Verilog 2 - Design Examples: Modified by Michael Taylor From Arvind's MIT 6.375 Slides
Verilog 2 - Design Examples: Modified by Michael Taylor From Arvind's MIT 6.375 Slides
Register Transfer Level automatic tools to synthesize a low-level gate-level model Gate Level
L03-2
" ! Use continuous assignments (assign) " ! Use always_comb blocks with blocking assignments (=)
always_comb begin out = 2d0; if (in1 == 1) out = 2d1; else if (in2 == 1) out = 2d2; end
always blocks allow more expressive control structures, though not all will synthesize
default value
L03-3
" ! Use only positive-edge triggered flip-flops for state " ! Do not assign the same variable from more than one
always_ff block. Race condition in behavioral simulation; synthesizes incorrectly.
only use non-blocking assignments (<=) for sequential logic. only use block assignments (=) for combinational logic.
module hierarchy that corresponds to logical boundaries in the design. Also, separate datapath and control (more later). L03-4
+1
+1
Readable, combinational and sequential logic are separated. Standard naming: A_r is the output of the register and A_next (or A_n) is the input.
L03-5
+1
+1
L03-6
Alternate implementation?
wire A_next, B_next, C_next; reg A_r, B_r, C_r; always_ff @( posedge clk ) begin A_r <= A_next; B_r <= B_next; C_r <= C_next; assign B_next = A_r + 1; assign C_next = B_r + 1; end
+1
+1
Syntactically Incorrect.
L03-7
+1
+1
Is (B_r == A_next+1) ? Nope - Why? A_r <= A_next creates a register between A_next and A_r, not a wire.
L03-8
+1
+1
Does it have the same functionality? Yes. But why? It generates the same underlying circuit.
L03-9
+1
+1
Will this synthesize? " Maybe Is it correct? " No; Do not use blocking assignments in @posedge clk blocks. It is forbidden in this class.
L03-10
wire B_in, C_in; reg A_r; wire sel; always @( posedge clk ) begin A_r <= 1b0; A_r <= B_in; if (sel) A_r <= C_in; end
L03-11
wire B_in, C_in; reg A_r; wire sel; always @( posedge clk ) begin A_r <= 1b0; // redundant! A_r <= B_in; if (sel) A_r <= C_in; end
wire A_n, B_in, C_in; reg A_r; wire sel; always_comb begin A_n = A_r; // default; // rdt. but safe A_n = B_in; if (sel) A_n = C_in; end
wire A_n, B_in, C_in; reg A_r; wire choose; always_comb begin A_n = A_r; // default A_n = B_in; if (choose) A_n = C_in; end
B_in C_in
!0 !1
A_n
choose
A_n
A_r
L03-13
This is way faster than finding the same bugs in the waveform viewer!
L03-14
typedef struct packed { logic [17-1:0] instr; logic [10-1:0] addr; } instr_packet_s; instr_packet_s ip_n, ip_A_r, ip_B_r, ip_C_r; assign ip_n = {addr: addr_i , instr: instr_i}; assign { addr_o, instr_o } = { ip_C_r.addr, ip_C_r.instr };
always_ff @( posedge clk ) begin { ip_A_r, ip_B_r, ip_C_r } <= { ip_n, ip_A_r, ip_B_r }; end
L03-15