450 likes | 795 Views
Verilog HDL. HDLs. Hardware Description Languages Widely used in logic design Verilog and VHDL Describe hardware using code Document logic functions Simulate logic before building Synthesize code into gates and layout Requires a library of standard cells. Module name. Module ports.
E N D
HDLs • Hardware Description Languages • Widely used in logic design • Verilog and VHDL • Describe hardware using code • Document logic functions • Simulate logic before building • Synthesize code into gates and layout • Requires a library of standard cells
Module name Module ports Declaration of port modes Declaration of internal signal Instantiation of primitive gates Verilog keywords Taste of Verilog module Add_half ( sum, c_out, a, b ); input a, b; output sum, c_out; wire c_out_bar; xor (sum, a, b); nand (c_out_bar, a, b); not (c_out, c_out_bar); endmodule a sum b c_out_bar c_out
a sum Add_half b c_out Behavioral Description module Add_half ( sum, c_out, a, b ); input a, b; output sum, c_out; reg sum, c_out; always @ ( a or b ) begin sum = a ^ b; // Exclusive or c_out = a & b; // And end endmodule
rst data_in q clk Declaration of synchronous behavior Procedural statement Example of Flip-flop module Flip_flop ( q, data_in, clk, rst ); input data_in, clk, rst; output q; reg q; always @ ( posedge clk ) begin if ( rst == 1) q = 0; else q = data_in; end endmodule
Gate Delay • and (yout, x1, x2); // default, zero gate delay • and #3 (yout, x1, x2); // 3 units delay for all transitions • and #(2,3) G1(yout, x1, x2); // rising, falling delay • and #(2,3) G1(yout, x1, x2), G2(yout2, x3, x4); // Multiple instances • a_buffer #(3,5,2) (yout, x); // UDP, rise, fall, turnoff • bufif1 #(3:4:5, 6:7:9, 5:7:8) (yout, xin, enable); // min:typ:max / rise, fall, turnoff • Simulators simulate with only one of min, typ and max delay values • Selection is made through compiler directives or user interfaces • Default delay is typ delay
Time Scales • Time scale directive: ‘ timescale <time_unit>/<time_precision> • time_unit -> physical unit of measure, time scale of delay • time_precision -> time resolution/minimum step size during simulation • time_unit time_precision
2 2 2 2 2 4 4 4 4 4 6 6 6 6 6 8 8 8 8 8 10 10 10 10 10 Net Delay … … wire #2 y_tran; and #3 (y_tran, x1, x2); buf #1 (buf_out, y_tran); and #3 (y_inertial, x1, x2); … … x1 x2 y_inertial x1 y_tran buf_out y_tran x2 y_inertial buf_out
Structural vs. Behavioral Descriptions module my_module(…); … assign …; // continuous assignment and (…); // instantiation of primitive adder_16 M(…); // instantiation of module always @(…) begin … end initial begin … end endmodule Structural, no order Behavior, in order in each procedure
initial | always single_statement; | begin block_of_statements; end initial Activated from tsim = 0 Executed once Initialize a simulation always Activated from tsim = 0 Executed cyclically Continue till simulation terminates Behavioral Statements
Example of Behavioral Statement module clock1 ( clk ); parameter half_cycle = 50; parameter max_time = 1000; output clk; reg clk; initial clk = 0; always begin #half_cycle clk = ~clk; end initial #max_time $finish; endmodule clk 50 100 150 200 tsim
Assignment • Continuous assignment • Values are assigned to net variables due to some input variable changes • “assign …=… “ • Procedural assignment • Values are assigned to register variables when certain statement is executed in a behavioral description • Procedural assignment, “=“ • Procedural continuous assignment, “assign …=… [deassign] “ • Non-blocking assignment, “<=“
Procedural Continuous Assignment • Continuous assignment establishes static binding for net variables • Procedural continuous assignment (PCA) establishes dynamic binding for variables • “assign … deassign” for register variables only
Binding takes effect when PCA statement is executed Can be overridden by another PCA statement “deassign” is optional “assign” takes control, “deassign” release control module flop ( q, qbar, preset, clear, clock, data ); … assign qbar = ~q; initial q = 0; always @ ( negedge clk ) q = data; always @ ( clear or preset ) begin if ( !preset ) assign q = 1; else if ( !clear ) assign q = 0; elsedeassign q; end endmodule “assign … deassign” PCA
Example of assign module mux4_PCA(a, b, c, d, select, y_out); input a, b, c, d; input [1:0] select; output y_out; reg y_out; always @(select) begin if (select == 0) assign y_out=a; else if (select == 1) assign y_out=b; else if (select == 2) assign y_out=c; else if (select == 3) assign y_out=d; elseassign y_out=1’bx; end endmodule y_out changes with a;
Alternative module mux4_PCA(a, b, c, d, select, y_out); input a, b, c, d; input [1:0] select; output y_out; reg y_out; always @(select or a or b or c or d) begin if (select == 0) y_out=a; else if (select == 1) y_out=b; else if (select == 2) y_out=c; else if (select == 3) y_out=d; else y_out=1’bx; end endmodule Value of ‘a’ is assigned to y_out at this time
initial begin a = 1; b = 0; a = b; // a = 0; b = a; // b = 0; end initial begin a = 1; b = 0; a <= b; // a = 0; b <= a; // b = 1; end Blocking assignment “=“ Statement order matters A statement has to be executed before next statement Non-blocking assignment “<=“ Concurrent assignment If there are multiple non-blocking assignments to same variable in same behavior, latter overwrites previous Blocking and Non-blocking Assignment
Delay Control Operator (#) initial begin #0 in1 = 0; in2 = 1; #10 in3 = 1; #40 in4 = 0; in5 = 1; #60 in3 = 0; end
… @ ( eventA or eventB ) begin … @ ( eventC ) begin … end end Event -> identifier or expression When “@” is reached Activity flow is suspended The event is monitored Other processes keep going posedge: 0->1, 0->x, x->1 negedge: 1->0, 1->x, x->0 Event Control Operator (@)
module modA (…); … always begin … wait ( enable ) ra = rb; … end endmodule Activity flow is suspended if expression is false It resumes when the expression is true Other processes keep going The “wait” Construct
// B = 0 at time 0 // B = 1 at time 4 … #5 A = B; // A = 1 C = D; … A = #5 B; // A = 0 C = D; … A = @(enable) B; C = D; … A = @(named_event) B; C= D; … If timing control operator(#,@) on LHS Blocking delay RHS evaluated at (#,@) Assignment at (#,@) If timing control operator(#,@) on RHS Intra-assignment delay RHS evaluated immediately Assignment at (#,@) Intra-assignment Delay: Blocking Assignment
module multi_assign(); reg a, b, c, d; initial begin #5 a = 1; b = 0; end always @ ( posedge a ) begin c = a; end always @ ( posedge a ) begin c = b; end always @ ( posedge a ) begin d = b; end always @ ( posedge a ) begin d = a; end endmodule Multiple assignments are made to same variable in different behaviors Value depends on code order or vendor specifications Similar to race-conditions in hardware Indeterminate Assignment
if ( A == B ) P = d; if ( B < C ); if ( a >= b ) begin … end if ( A < B ) P = d; else P = k; if ( A > B ) P = d; else if ( A < B ) P = k; else P = Q; Syntax: if ( expression ) statement [ else statement ] Value of expression 0, x or z => false Non-zero number => true Activity Flow Control ( if … else )
Conditional Operator ( ? … : ) always @ ( posedge clock ) yout = ( sel ) ? a + b : a – b; • Conditional operator can be applied in • either continuous assignments • or behavioral descriptions
module mux4 ( a, b, c, d, select, yout ); input a, b, c, d; input [1:0] select; output yout; reg yout; always @( a or b or c or d or select ) begin case ( select ) 0: yout = a; 1: yout = b; 2: yout = c; 3: yout = d; default yout = 1`bx; endcase endmodule Case items are examined in order Exact match between case expression and case item casez – treats “z” as don’t cares casex – treats both “x” and “z” as don’t cares The case Statement
The repeat Loop … word_address = 0; repeat ( memory_size ) begin memory [word_address] = 0; word_address = word_address + 1; end …
The for Loop reg [15:0] regA; integer k; … for ( k = 4; k; k = k – 1 ) begin regA [ k+10 ] = 0; regA [ k+2 ] = 1; end … Loop variables have to be either integer or reg
begin cnt1s reg [7:0] tmp; cnt = 0; tmp = regA; while ( tmp ) begin cnt = cnt + tmp[0]; tmp = tmp >> 1; end end module sth ( externalSig ); input externalSig; always begin while ( externalSig ); end endmodule The while Loop Loop activities suspend external activities
The disable Statement begin k = 0; for ( k = 0; k <= 15; k = k + 1 ) if ( word[ k ] == 1 ) disable ; end Terminate prematurely in a block of procedural statements
The forever Loop parameter half_cycle = 50; initial begin : clock_loop clock = 0; forever begin #half_cycle clock = 1; #half_cycle clock = 0; end end initial #350 disable clock_loop;
Task module bit_counter (data, count); input [7:0] data; output [3:0] count; reg [3:0] count; always @(data) t(data, count); task t; input [7:0] a; output [3:0] c; reg [3:0] c; reg [7:0] tmp; begin c = 0; tmp = a; while (tmp) begin c = c + tmp[0]; tmp = tmp >> 1; end end endtask endmodule
Function module word_aligner (w_in, w_out); input [7:0] w_in; output [7:0] w_out; assign w_out = align (w_in); function [7:0] align; input [7:0] word; begin align = word; if (align != 0) while (align[7] == 0) align = align << 1; end endfunction endmodule
Switch Level NAND Gate module nand_2 ( Y, A, B ); output Y; input A, B; supply0 GND; supply1 PWR; wire w; pmos ( Y, PWR, A ); pmos ( Y, PWR, B ); nmos ( Y, w, A ); nmos ( w, GND, B ); endmodule Vdd B A Y A B
nand ( pull1, strong0 ) G1( Y, A, B ); wire ( pull0, weak1 ) A_wire = net1 || net2; assign ( pull1, weak0 ) A_net = reg_b; Drive strength is specified through an unordered pair one value from { supply0, strong0, pull0, weak0 , highz0 } the other from { supply1, strong1, pull1, weak1, highz1 } Only scalar nets may receive strength assignment Assign Drive Strengths
Latch Resulted from Unspecified Input State module myMux( y, selA, selB, a, b ); input selA, selB, a, b; output y; reg y; always @ ( selA or selB or a or b ) case ( {selA, selB} ) 2’b10: y = a; 2’b01: y = b; endcase endmodule b selA’ en selB y selA latch selB’ a
Synthesis of Loops • repeat, for, while, forever • Depends on • Venders • Timing control • Data dependencies • A loop is static or data-independent if the number of iterations can by determined by the complier before simulation
Static Loops without Internal Timing Controls –> Combinational Logic module count1sA ( bit_cnt, data, clk, rst ); parameter data_width = 4; parameter cnt_width = 3; output [cnt_width-1:0] bit_cnt; input [data_width-1:0] data; input clk, rst; reg [cnt_width-1:0] cnt, bit_cnt, i; reg [data_width-1:0] tmp; always @ ( posedge clk ) if ( rst ) begin cnt = 0; bit_cnt = 0; end else begin cnt = 0; tmp = data; for ( i = 0; i < data_width; i = i + 1 ) begin if ( tmp[0] ) cnt = cnt + 1; tmp = tmp >> 1; end bit_cnt = cnt; end endmodule
Static Loops with Internal Timing Controls –> Sequential Logic module count1sB ( bit_cnt, data, clk, rst ); parameter data_width = 4; parameter cnt_width = 3; output [cnt_width-1:0] bit_cnt; input [data_width-1:0] data; input clk, rst; reg [cnt_width-1:0] cnt, bit_cnt, i; reg [data_width-1:0] tmp; always @ ( posedge clk ) if ( rst ) begin cnt = 0; bit_cnt = 0; end else begin cnt = 0; tmp = data; for ( i = 0; i < data_width; i = i + 1 ) @ ( posedge clk ) begin if ( tmp[0] ) cnt = cnt + 1; tmp = tmp >> 1; end bit_cnt = cnt; end endmodule
Non-Static Loops without Internal Timing Controls –> Not Synthesizable module count1sC ( bit_cnt, data, clk, rst ); parameter data_width = 4; parameter cnt_width = 3; output [cnt_width-1:0] bit_cnt; input [data_width-1:0] data; input clk, rst; reg [cnt_width-1:0] cnt, bit_cnt, i; reg [data_width-1:0] tmp; always @ ( posedge clk ) if ( rst ) begin cnt = 0; bit_cnt = 0; end else begin cnt = 0; tmp = data; for ( i = 0; tmp; i = i + 1 ) begin if ( tmp[0] ) cnt = cnt + 1; tmp = tmp >> 1; end bit_cnt = cnt; end endmodule
Non-Static Loops with Internal Timing Controls –> Sequential Logic module count1sD ( bit_cnt, data, clk, rst ); parameter data_width = 4; parameter cnt_width = 3; output [cnt_width-1:0] bit_cnt; input [data_width-1:0] data; input clk, rst; reg [cnt_width-1:0] cnt, bit_cnt, i; reg [data_width-1:0] tmp; always @ ( posedge clk ) if ( rst ) begin cnt = 0; bit_cnt = 0; end else begin: bit_counter cnt = 0; tmp = data; while ( tmp ) @ ( posedge clk ) begin if ( rst ) begin cnt = 0; disable bit_counter; end else begin cnt = cnt + tmp[0]; tmp = tmp >> 1; end bit_cnt = cnt; end end endmodule