Verilog Intro: Part 2 Procedural Blocks • There are two types of procedural blocks in Verilog. – initial for single-pass behavior : initial blocks execute only once at time zero (start execution at time zero). – always for cyclic behavior: always blocks loop to execute over and over again, in other words as name means, it executes always. • Procedural assignment may only appear in initial and always constructs. • The initial and always constructs are used to model sequential logic. • Continuous statement is used to model combinational logic. Initial Block • General Form initial begin //Procedural assignment statements end • Example : The initial block is executed at time 0. Initial Initial block just execute all the statements begin within begin and end statements. clock = 1'b0; repeat (30) #10 clock = ~clock; end Example: Always Block • General Form: always @ (event control expression) begin //Procedural assignment statements that execute //when the condition is met end • Example: always @ (A or B or C) always @(posedge clock or negedge reset) //Verilog 1995 always @(posedge clock, negedge reset) //Verilog 2001, 2005 Control Constructs • Control Constructs – Can be used in the procedural sections of code. • Selection – if statement: if (A == 4) begin B = 2; end else begin B = 4; end – case statements: case (<expression>) <value1>: <statement> <value2>: <statement> default: <statement> endcase Example: Case Statement case (select) 2’b00: q = d[0]; 2’b01: q = d[1]; 2’b10: q = d[2]; 2’b11: q = d[3]; endcase Repetition • // for loop for(i = 0; i < 10; i = i + 1) begin $display(“i = %d", i); end • • //while loop i = 0; while(i < 10) begin $display(“i = %d", i); i = i + 1; end // repeat loop repeat (5) //repeats the block 5 times, begin $display(“i = %d", i); i = i + 1; end Blocking and Non-blocking Procedural Assignments • The blocking assignment statement (= operator) acts much like in traditional programming languages. Blocking statement must complete execute before the next statement in the behavior can execute. • The non-blocking (<= operator) evaluates all the right-hand sides for the current time unit and assigns the left-hand sides at the end of the time unit. Non-blocking assignment statements execute concurrently rather than sequentially. D-Flip Flops • // D flip-flop without reset module D-FF (Q, D, Clk); output Q; input D, Clk; reg Q; always @ (posedge Clk) Q <= D; endmodule • // D flipflop with asynchronous reset (V2001, V2005) module DFF (output reg Q, Q_b, input D, Clk, rst); always @ (posedge Clk, negedge rst) if(~rst) // Same as: if (rst == 0) begin Q <= 1'b0; Q_b <=1'b1; end else begin Q <= D; Q_b <=~D; end endmodule T flip-flop using D flip-flop • //T flip-flop from D flip-flop and gates module TFF (Q, Q_b, T, Clk, rst); output Q, Q_b; input T, Clk, rst; wire DT; assign DT=Q^T; // Instantiate the D flip-flop DFF TF1 (Q, Q_b,DT, Clk, rst); endmodule JK flip-flop using D flip-flop • // JK flip-flop from D flip-flop and gates module JKFF (output Q, Q_b, input J, K, clk, rst); wire JK; assign JK = (J & ~Q) | (~ K & Q); // Instantiate D flip-flop DFF JK1 (Q, Q_b, JK, clk, rst); endmodule Behavioral Description of JK flipflop • // Functional description of JK flip-flop module JK_FF (input J, K, Clk, output reg Q, output Q_b); assign Q_b = ~Q ; always @ (posedge Clk) case ({J,K}) 2'b00: Q <= Q; 2'b01: Q <= 1'b0; 2'b10: Q <= 1'b1; 2'b11: Q <= ~Q; endcase endmodule Behavioral Description of JK flipflop • // Functional description of JK flip-flop module JK_FF (input J, K, Clk, output reg Q, output Q_b); assign Q_b = ~Q ; initial Q = 0; always @ (posedge Clk) case ({J,K}) 2'b00: Q <= Q; 2'b01: Q <= 1'b0; 2'b10: Q <= 1'b1; 2'b11: Q <= ~Q; endcase endmodule Example: Fig 5_20 Using Behavioral Description module Moore_Model_Fig_5_20 ( output y_out, input x_in, clock, reset ); reg [1:0] state; parameter S0=2'b00, S1=2'b01, S2=2'b10,S3=2'b11; always @ (posedge clock, negedge reset) if (reset == 0) state <= S0; // Initialize to state SO else case (state) S0: if(x_in) state <= S1;else state <=S0; S1: if(x_in) state <= S2;else state <=S1; S2: if(x_in) state <= S3;else state <=S2; S3: if(x_in) state <= S0;else state <=S3; endcase assign y_out = (state == S3); // Output of flip-flops endmodule Structural Description module Moore_Model_STR_Fig_5_20 (output y_out, A, B, input x_in, clock, reset); wire TA, TB; assign TA = x_in & B; // Flip-flop input equations assign TB = x_in; assign y_out = A & B; // Output equation Toggle_flip_flop M_A (A, TA, clock, reset); // Instantiate Toggle flip-flops Toggle_flip_flop M_B (B, TB, clock, reset); // Instantiate Toggle flip-flops endmodule module Toggle_flip_flop (Q, T, CLK, RST_b); output Q; input T, CLK, RST_b; reg Q; always @ (posedge CLK, negedge RST_b) if (RST_b == 0) Q <= 1'b0; else if (T) Q <= ~Q; endmodule Test Bench module t_Moore_Fig_5_20; wire t_y_out_2, t_y_out_1 ; reg t_x_in, t_clock, t_reset; Moore_Model_Fig_5_20 M1(t_y_out_1, t_x_in, t_clock, t_reset); Moore_Model_STR_Fig_5_20 M2(t_y_out_2, A, B, t_x_in, t_clock, t_reset); initial #200 $finish; initial begin t_reset= 0; t_clock = 0; #5 t_reset = 1; repeat (16) #5 t_clock = ~t_clock; end initial begin t_x_in = 0; #15 t_x_in = 1 ; repeat (8) #10 t_x_in = ~t_x_in; end endmodule Example: Sequence Detector