/// LSU EE 4755 -- Fall 2019 -- Digital Design / HDL // /// Verilog Notes -- Synthesis of Sequential Logic Examples // /// This file is a supplement to the lecture slides /// Visit https://www.ece.lsu.edu/v/2019/lsli-syn-seq.pdf /// Under Construction /// Contents // /// References // :SV12: IEEE 1800-2012 -- The SystemVerilog Standard // :SV17: IEEE 1800-2017 -- The SystemVerilog Standard // https://ieeexplore.ieee.org/document/8299595/ // This is for those already familiar with Verilog. // // :BV3: Brown & Vranesic, Fundamentals of Digital Logic with Verilog, 3rd Ed. // The text used in LSU EE 2740. /// Preview of Blocking and Non-Block Assignments /// // // :SV12: Section 9.4.5 module verilog_stuff(input uwire a); logic [7:0] b, c, d, e; initial begin b = 0; c1 = b; #1; // Nonblocking assignment. lhs <= some_expression + some_other_expression; b <= 1; c2 = b; #2; c3 = b; end initial b = 0; always @( posedge a ) begin c <= b; b <= 1; end always @( posedge a ) begin e <= b; b <= 2; end endmodule /// First Examples of Inferred Registers /// module testc; logic clk; counter myc(count, r, clk); initial clk = 0; always #10 clk = !clk; always @( count ) $write("The counter is now %0d\n", count); endmodule module counter #( int w = 16 ) ( output logic [w-1:0] count, input uwire reset, clk ); always_ff @( posedge clk ) begin count = count + 1; end endmodule module counter #( int w = 16 ) (output logic [w-1:0] count, input uwire reset, clk ); always @( posedge clk ) begin if ( reset ) count = 0; else count++; end endmodule module counter #( int w = 16 ) (output logic [w-1:0] c, input uwire reset, clk ); always_ff @( posedge clk ) begin c = c + 1; if ( reset ) c = 0; end endmodule /// Examples of Describing Common Register Types /// // Behavioral description of d flip-flop. // module d_ff(output logic q, input uwire d, clk); always_ff @( posedge clk ) q <= d; endmodule // d_ff module register #( int width = 16 ) ( output logic [width-1:0] val, input uwire [width-1:0] data, input uwire clk ); always_ff @( posedge clk ) val <= data; endmodule module register_en #( int width = 16 ) ( output logic [width-1:0] val, input uwire enable, input uwire [width-1:0] data, input uwire clk ); always_ff @( posedge clk iff enable ) val <= data; endmodule module register_en #( int width = 16 ) ( output logic [width-1:0] val, input uwire enable, input uwire [width-1:0] data, input uwire clk ); always_ff @( posedge clk ) begin if ( a ) begin if ( enable ) val = data; val = val + 3; if ( e2 ) val = val * 5; end x = val + val2; end always_ff @( posedge clk ) begin x = val + val2; end endmodule module register_sync_reset #( int width = 16 ) ( output logic [width-1:0] val, input uwire reset, input uwire [width-1:0] data, input uwire clk ); always_ff @( posedge clk ) if ( reset ) val <= 0; else val <= data; endmodule module register_async_reset #( int width = 16 ) ( output logic [width-1:0] val, input uwire reset, input uwire [width-1:0] data, input uwire clk ); always_ff @( posedge clk or posedge reset ) if ( reset ) val <= 0; else val <= data; endmodule /// Examples of Counters /// module count #( int bits = 16 ) ( output logic [bits-1:0] c, input uwire clk ); initial c = 0; always @( posedge clk ) c++; endmodule module count_reset #( int bits = 16 ) ( output logic [bits-1:0] c, input uwire reset, input uwire clk ); always_ff @( posedge clk ) if ( reset ) c <= 0; else c <= c + 1; endmodule module count_thd #( int bits = 16 ) ( output logic [bits-1:0] c, output logic over_th, input uwire [bits-1:0] threshold, input uwire clk ); always_ff @( posedge clk ) begin c++; over_th = c > threshold; end endmodule module count_thd_alt2 #( int bits = 16 ) ( output logic [bits-1:0] c, output logic over_th, input uwire [bits-1:0] threshold, input uwire clk ); always_ff @( posedge clk ) begin over_th = c > threshold; c++; end // No delay constraints. // over_th_reg/CLK setup 0 +277 4272 R // count_thd_alt2 92 15928 0 15928 (D) // 100 ps delay target // c_reg[12]/CLK setup 0 +276 1355 R // count_thd_alt2 191 24492 0 24492 (D) endmodule module count_thd_alt #( int bits = 16 ) ( output logic [bits-1:0] c, output logic over_th, input uwire [bits-1:0] threshold, input uwire clk ); always_ff @( posedge clk ) c++; always_comb over_th = c > threshold; // No delay constraints. // over_th out port +0 3973 F // count_thd_alt 91 15544 0 15544 (D) // 100 ps delay target // c_reg[15]/CLK setup 0 +276 1340 R // count_thd_alt 189 23160 0 23160 (D) endmodule module count_limit #( int max_val = 9, int bits = $clog2(max_val) ) ( output logic [bits-1:0] c, input uwire reset, input uwire clk ); always_ff @( posedge clk ) begin if ( reset || c == max_val ) c = 0; else c++; end endmodule `ifdef classroom_live module bcd_count #( int num_digits = 4 ) ( output uwire [num_digits-1:0][3:0] count, input uwire clk ); count_limit_en #(9) cl0( count[0], 1'b1, clk ); assign en1 = count[0] == 9; count_limit_en #(9) cl1( count[1], en1, clk ); assign en2 = count[1] == 9 && en1; count_limit_en #(9) cl2( count[2], en2, clk ); endmodule `endif module count_limit_en #( int max_val = 9, int bits = $clog2(max_val) ) ( output logic [bits-1:0] c, input uwire reset, input uwire enable, input uwire clk ); always_ff @( posedge clk ) if ( reset ) c = 0; else if ( enable ) begin if ( c == max_val ) c = 0; else c++; end endmodule module bcd_count #( int num_digits = 4 ) ( output uwire [num_digits-1:0][3:0] count, input uwire reset, input uwire clk ); uwire nines[num_digits:-1]; assign nines[-1] = 1; for ( genvar d=0; d