0%

day0-HDLbits

record of solving HDLbits problem.

Vector1

$display("This is a test number: %b.", num); // 印出結果 
$write("This is a test");
$write("number: %b", num); // 不會換行
$strobe("$strobe excuting result: %d.", a); // 在其他語句結束完成後,才執行顯示任務
$monitor("Counter change to value %d at the time %t.", cnt, $time); // 只要其中變數有更動就會列印出來

Unpacked vs. Packed Arrays

reg [7:0] mem [255:0]; // 256 unpacked elements, each of which is a 8-bit packed vector of reg.
reg mem2 [28:0]; // 29 unpacked elements, each of which is a 1-bit reg.

Gatesv100

短版 #bit操作
given a 100-bit input vector in[99:0],

  • out_both: out_both[98] = in[98] & in[99]
  • out_any: out_any[2] = in[1] | in[0]
  • out_different: out_different[98] = in[98] ^ in[99], but wrapping around.
    module top_module( 
    input [99:0] in,
    output [98:0] out_both,
    output [99:1] out_any,
    output [99:0] out_different );
    assign out_both = in[98:0] & in[99:1];
    assign out_any = in[99:1] | in[98:0];
    assign out_different = in[99:0] ^ {in[0],in[99:1]};
    endmodule

    Mux9to1v

    case 要寫在 always 裡面

Mux256to1

變動index居然可行

module top_module( 
input [255:0] in,
input [7:0] sel,
output out );
assign out = in[sel];
endmodule

Mux256to1v

謝謝你Verilog-2001, 6.4 Vector Bit Selects and Part Selects

module top_module( 
input [1023:0] in,
input [7:0] sel,
output [3:0] out );
assign out = in[sel*4 +: 4];
endmodule

Exams/m2014 q4j

果然有詐, 寫太多加法器思維被困住.
如果使用位连接符 {x+y},那么结果就会被限制为 4 bit 数。

module top_module (
input [3:0] x,
input [3:0] y,
output [4:0] sum);
assign sum = x + y ;
endmodule

Exams/ece241 2014 q1c

很酷的溢為位, 負數最高bit為0
一是正正相加,产生正溢出;另一种情况是负负相减,产生负溢出。

module top_module (
input [7:0] a,
input [7:0] b,
output [7:0] s,
output overflow
);
assign s = a + b;
// 正數2補數MSB為1, 若正數+正數且s[7]不為0, 正溢出. 反之
assign overflow = (~a[7] & ~b[7] & s[7]) | (a[7] & b[7] & ~s[7]); // 正數 | 負數
endmodule

assign out = ~a&b&~c&~d

Kmap4

很過分的一題, 用卡諾圖反而難解.

module top_module(
input a,
input b,
input c,
input d,
output out );
function result;
input [3:0] abcd;
begin
case(abcd)
4'b0100: result = 1;
4'b0001: result = 1;
4'b1000: result = 1;
4'b1101: result = 1;
4'b0111: result = 1;
4'b0010: result = 1;
4'b1011: result = 1;
4'b1110: result = 1;
default: result = 0;
endcase
end
endfunction
assign out = result({a,b,c,d});
endmodule

Exams/ece241 2014 q3

題目有點令人費解, 簡單來說, top_module 只與 cd有關
而mux_in[0]則是00時c與d的sop, 也就是卡諾圖的第一直排.

module top_module (
input c,
input d,
output [3:0] mux_in
);
assign mux_in[0] = c | d;
assign mux_in[1] = 0;
assign mux_in[2] = ~d;
assign mux_in[3] = c & d;
endmodule

Dff8p

16進位簡寫是可以的

always @(negedge clk) q <= reset ? 'h34 : d;

Exams/2014 q4a

巢狀結構if簡寫是可以的

always @(posedge clk) Q <= L ? R : (E ? w : Q); 

Edgecapture

犯蠢了, 不小心在always裡面重新定義了輸出

if  out_tmp <= 0;
out_tmp <= ~in & in_dly | out_tmp;

應該要這樣寫

out_tmp <= (reset) ? 0 : ~in & in_dly | out_tmp;

Dualedge

在 posedge 對上一個時間 negedge 跟 d xor 立 開始 flag (不論1或0),
在 negedge 對上一個時間 posedge 跟 d xor 立 結束 flag (不論1或0),
q 就是 開始flag 跟結束 flag 的 xor

module top_module (
input clk,
input d,
output q
);
reg q_d1;
reg q_d2;
always @(posedge clk) q_d1 <= d ^ q_d2;
always @(negedge clk) q_d2 <= d ^ q_d1;
assign q = q_d1 ^ q_d2;
endmodule

Lfsr32

部分映射, 部分xor

module top_module(
input clk,
input reset, // Active-high synchronous reset to 32'h1
output [31:0] q
);
always @(posedge clk) begin
if (reset) q <= 32'h1;
else q <= {q[0]^0, q[31:23],q[22]^q[0],q[21:3], q[2]^q[0], q[1]^q[0]};
end
endmodule

Exams/ece241 2013 q12

直接concatenate居然可以當index!

module top_module (
input clk,
input enable,
input S,
input A, B, C,
output Z );
reg [0:7] Q;
always@(posedge clk) begin
if(enable) Q <= {S, Q[0:6]};
end
assign Z = Q[{A,B,C}];
endmodule

Fsm3onehot

居然oneHot是可以平坦化解釋的transition.
支援多條件判斷.

module top_module(
input in,
input [3:0] state,
output [3:0] next_state,
output out); //

parameter A=0, B=1, C=2, D=3;

// State transition logic: Derive an equation for each state flip-flop.
assign next_state[A] = state[0]&(~in) | state[2]&(~in);
assign next_state[B] = state[0]&(in) | state[1]&(in) | state[3]&(in);
assign next_state[C] = state[1]&(~in) | state[3]&(~in);
assign next_state[D] = state[2]&(in);

// Output logic:
assign out = state[3]==1;

endmodule

Exams/ece241 2013 q4

思路, 照表格輸出fr1~fr3,
dfr特例輸出, 有兩個特性
一是要在clk判斷, 做輸出變化
再來,是要跟舊的state做判斷
因此獨立出來

module top_module (
input clk,
input reset,
input [3:1] s,
output fr3,
output fr2,
output fr1,
output dfr
);
reg [3:1] s_prev;
reg dfr_temp;
always @(posedge clk) begin
if (reset) begin
s_prev = 3'b000;
dfr_temp = 1;
{fr3,fr2,fr1,dfr} = 4'b1111;
end
else begin

// 用block寫法, 不然會多一個clock
if ( s != s_prev ) begin
dfr_temp = s < s_prev;
s_prev = s;
end
else dfr_temp = dfr_temp;
case (s) // 判斷完的直接送出
3'b000: {fr3,fr2,fr1,dfr} = {3'b111,dfr_temp};
3'b001: {fr3,fr2,fr1,dfr} = {3'b011,dfr_temp};
3'b011: {fr3,fr2,fr1,dfr} = {3'b001,dfr_temp};
3'b111: {fr3,fr2,fr1,dfr} = {3'b000,dfr_temp};
endcase
end
end
endmodule

Lemmings2

多兩個state, FALL_L, FALL_R
比較簡潔, 比起多一個reg來的方便快速.
用state描述狀態, 減少判斷.

Lemmings4

小時候很喜歡的旅鼠遊戲最終章
對於死亡的判定(20 or 21 clk)弄了蠻久的.
依舊是個很漂亮的FSM

module top_module(
input clk,
input areset, // Freshly brainwashed Lemmings walk left.
input bump_left,
input bump_right,
input ground,
input dig,
output walk_left,
output walk_right,
output aaah,
output digging );

parameter LEFT=3'd0, RIGHT=3'd1, FALL_L=3'd2, FALL_R=3'd3,
DIG_L=3'd4, DIG_R=3'd5, DIE = 3'd6;
reg [2:0] state, next_state;
reg [4:0] fall_count = 5'd0;

always @(*) begin
case (state)
LEFT: next_state <= !ground ? FALL_L : (dig ? DIG_L : (bump_left ? RIGHT : LEFT));
RIGHT: next_state <= !ground ? FALL_R : (dig ? DIG_R : (bump_right ? LEFT : RIGHT));
FALL_L: next_state <= fall_count > 5'd20 && ground ? DIE : (!ground ? FALL_L : LEFT);
FALL_R: next_state <= fall_count > 5'd20 && ground ? DIE : (!ground ? FALL_R : RIGHT);
DIG_L: next_state <= !ground ? FALL_L : DIG_L;
DIG_R: next_state <= !ground ? FALL_R : DIG_R;
DIE: next_state <= DIE;
endcase
end

always @(posedge clk, posedge areset) begin
if(areset) state <= LEFT;
else begin
state <= next_state;
if(!ground && fall_count < 5'd31) fall_count <= fall_count + 5'd1;
else if (!ground && fall_count == 5'd31) fall_count <= fall_count;
else fall_count <= 5'd0;
end
end

// Output logic
always @(*) begin
case (state)
LEFT: {walk_left,walk_right,aaah,digging} <= 'b1000;
RIGHT: {walk_left,walk_right,aaah,digging} <= 'b0100;
FALL_L: {walk_left,walk_right,aaah,digging} <= 'b0010;
FALL_R: {walk_left,walk_right,aaah,digging} <= 'b0010;
DIG_L: {walk_left,walk_right,aaah,digging} <= 'b0001;
DIG_R: {walk_left,walk_right,aaah,digging} <= 'b0001;
DIE: {walk_left,walk_right,aaah,digging} <= 'b0000;
endcase
end

endmodule