180 likes | 380 Vues
This guide covers the two main types of procedural blocks in Verilog: initial and always. The initial block executes once at time zero, useful for setting initial states, while the always block continuously executes based on defined conditions, modeling cyclic behavior. Learn how procedural assignments are applied within these constructs and discover their applications in sequential and combinational logic design. Numerous code examples are provided, including the implementation of D, T, and JK flip-flops, as well as the use of control constructs for selection and repetition.
E N D
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 : Initial begin clock = 1'b0; repeat (30) #10 clock = ~clock; end The initial block is executed at time 0. Initial block just execute all the statements within begin and end statements.
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 flip-flop • // 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 flip-flop • // 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
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