170 likes | 185 Views
Learn about D-Latch, D Flip Flop, Sequential Circuit Modeling, FSM, Load Register, Shift Register, Up-Down Counter in Verilog. Understand modeling and testing using test benches.
E N D
COE 202Introduction to Verilog Computer Engineering Department College of Computer Sciences and Engineering King Fahd University of Petroleum and Minerals
Outline • D Latch • D Flip Flop • Structural Modeling of a Sequential Circuit • FSM Modeling • Parallel Load Register • Shift Register • Up-Down Counter
D Latch moduledlatch (output q, input data, enable); assign q = enable ? data: q; endmodule module dlatch2 (output reg q, input data, enable); always @(enable, data) if (enable) q <= data; //Notice the use of non-blocking endmodule// assignment—This is the case with // sequential circuits
D Flip Flop – Synchronous Set/Reset moduledff (output reg q, output q_bar, input data, set, reset, clk); assign q_bar = ~q; always @(posedgeclk) // Synchronous set/reset if (reset) q <= 0; // Again non-blocking assignments else if (set) q <=1; else q <= data; endmodule
D Flip Flop–Asynchronous Set/Reset module dff2 (output reg q, output q_bar, input data, set, reset, clk); assign q_bar = !q; always @(posedgeclk, posedgeset, posedgereset) // Asynchronous set/reset if (reset == 1'b1) q <= 0; else if (set == 1'b1) q <=1; else q <= data; endmodule
Structural Modeling of a Sequential Circuit module SeqStruct(output Y, input X, Reset, CLK); dff2 F0 (B, Bb, DB, 1'b0, Reset, CLK); dff2 F1 (A, Ab, DA, 1'b0, Reset, CLK); and (DB, Ab, X); and (w1, A, X); and (w2, B, X); or (DA, w1, w2); or (w3, A, B); not (w4, X); and (Y, w3, w4); endmodule
FSM Modeling • Moore Sequence Detector: Detection sequence is 110 IF 110 found on x Then Z gets ‘1’ Else z gets ‘0’ End x z clk 1 1 1 0 0 Reset /0 got1 /0 got11 /0 got110 /1 0 1
FSM Modeling module moore_110_detector(output reg z, input x, clk, rst ); localparam reset = 2'b00, got1=2'b01, got11=2'b10, got110=2'b11; reg [1:0] state, next_state; always @(posedgeclk) //synch reset if (rst) state <= reset; else state <= next_state; // the state transition always @(state, x) begin//comb. Logic z = 0; //Default value of z case (state) //Note the use of blocking assignments with combinational logic reset: if (x) next_state=got1; else next_state=reset; got1: if (x) next_state=got11; else next_state=reset; got11: if (x) next_state=got11; else next_state=got110; got110: begin z=1; if (x) next_state=got1; else next_state=reset; end endcase// When we have more than one statement inside a case end// branch, we use begin..endendmodule
FSM Modeling: Test benches • To test an FSM (i.e. sequential circuit), the test bench must supply an input sequence that exercise all state transitions and output combinations module moore_110_detector_TB ; //No ports for test benches regclk, rst, x ; // Inputs declarations – have to reg type since we are going to assign // them inside a procedural block wire z ;// output declaration – Must be a wire since it is connected to the output of the // instantiated module moore_110_detectorM1 (z, x, clk, rst) ; // instantiating the module under test initial begin // The reset and clock sequence rst = 1 ; clk = 0 ; #10 clk=1; #10 clk=0; rst = 0 ; forever #10 clk = ~ clk ; end initial begin//Input sequence – apply inputs with negative edge of clock @(negedgeclk) x=0; @(negedgeclk) x=1; @(negedgeclk) x=0; @(negedgeclk) x=1; @(negedgeclk) x = 1; @(negedgeclk) x = 1; @(negedgeclk) x = 0; @(negedgeclk) x = 1; @(negedgeclk) x = 1; @(negedgeclk) x = 0; @(negedgeclk) x = 0; end endmodule
Parallel Load Register module Par_load_reg4 #(parameter word_size=4) ( output reg [word_size-1:0] Data_out, input [word_size-1:0] Data_in, input load, clock, reset); always @(posedgeclock, posedgereset) if (reset) Data_out <= 0; else if (load) Data_out <= Data_in; endmodule
Shift Register (No shift control) module Shift_reg4 #(parameter word_size=4) ( output Data_out, input Data_in, clock, reset); // Serial-in, serial-out reg [word_size-1:0] Data_reg; assign Data_out = Data_reg[0]; always @(posedgeclock, negedgereset) if (!reset) Data_reg <= 0; else Data_reg <= {Data_in, Data_reg [word_size-1:1]} ; endmodule
Shift Register (with shift control) module Shift_reg4 #(parameter word_size=4) //Serial-in, Parallel-out ( output reg [word_size-1:0] Data_out, input Data_in, shift, clock, reset); always @(posedgeclock, negedgereset) if (!reset) Data_out<= 0; else if (shift) Data_out<= {Data_in, Data_ou t[word_size -1:1]} ; //Shifts to endmodule // the right
MultiFunction Register module MFRegister #(parameter n=3) (output reg [n-1:0] Q, input [n-1:0] Din, input s1, s0, clk, reset, SiL,, SiR); always @(posedge clk) begin if (reset) Q <= 0; // synchronous reset else case ({s1,s0}) 2'b00: Q <=Q ; // no change 2'b01: Q <= Din ; // parallel load – Read Din into register 2'b10: Q <= {Q [n-2:0], SiR} ; // shift left, SiR (Sin from the right) is shifted in 2'b11: Q <= {SiL, Q [n-1:1]} ; //shift right, SiL (Sin from the left) is shifted in endcase end endmodule
Up-Down Counter module Up_Down_Counter2 (output reg [2:0] count, input load, count_up, counter_on, clock, reset, input [2:0] Data_in); always @(negedgeclock, posedgereset) // counter is –ve edge triggered if (reset) count <= 0 ; // If counter_on is 0, the counter does nothing else if (counter_on) if (load) count <= Data_in; else if (count_up) count<=count+1; else count<=count-1; endmodule
Up-Down Counter: Testbench moduleTB_Counter ; reg[2:0] Data_in ; regload, count_up, counter_on, clock, reset ; wire [2:0] Q ; //output Up_Down_Counter2 (Q, load, count_up, counter_on, clock, reset, Data_in); initial begin // The reset and clock sequence reset = 1 ; clk = 0 ; #10 ; reset = 0 ; forever #10 clk = ~ clk ; end initial begin counter_on=0; load=0; count_up=0 ; Data_in=5; // initialize inputs @(posedgeclk) counter_on =1 ; load=1; // load with 5 @(posedgeclk) count_up=1 ; load=0; // count up to 6 @(posedgeclk) ; // count up to 7 @(posedgeclk) count_up=0 ; // count down to 6 @(posedgeclk) ; // count down to 5 end endmodule
Modulo-n Counter moduleModulo_n_Counter # (Parameter M=3, N=7) (output reg[M-1:0] count, input count_en, clock, reset); always @(posedgeclock, posedgereset) if (reset) count <= 0 ; //If count_en is 0, the counter does nothing else if (count_en) if (count == N-1) count <= 0 ; else count<=count+1; endmodule
A clock frequency divider • Whenever we divide by 2 or powers of 2 (using counters), the output is symmetrical; i.e. the high and low durations are equal • Division by other numbers will give non-symmetrical Output moduleCLK_Divider # (Parameter M=4, N=10) // N is the division ratio (output wire clk_out, input clk_in, reset); reg[M-1:0] count ; //2**M-1 must be larger than N assign clk_out = (count == N - 1) ; always @(posedgeclock, posedgereset) if (reset) count <= 0 ; else if (clk_out) count <= 0 ; else count<=count+1; endmodule