CPEN 230: Introduction to Digital LogicA Verilog example showing how to code FSMsRTL code implementing an edge detectoredgedetector.v
// Edge Detector - Claudio Talarico module edgedetector (Clk, Rst, Din, Pulse); input Clk, Rst, Din; output Pulse; reg pulse_d, Pulse; parameter zero=0, pedge=1, nedge=2, one=3; reg [1:0] state, nextstate; // Combinational logic always @ (state or Din) begin case (state) zero : begin if (Din == 0) begin nextstate = zero; pulse_d = 0; end else begin nextstate = pedge; pulse_d = 1; end end one : begin if (Din) begin nextstate = one; pulse_d = 0; end else begin nextstate = nedge; pulse_d = 1; end end pedge : begin if (Din) begin nextstate = one; pulse_d = 0; end else begin nextstate = nedge; pulse_d = 1; end end nedge : begin if (Din) begin nextstate = pedge; pulse_d = 1; end else begin nextstate = zero; pulse_d = 0; end end default : begin nextstate = zero; pulse_d = 0; end endcase end //sequential logic always @ (posedge Rst or posedge Clk) //active high async. reset begin if (Rst) begin state <= zero; Pulse <= 0; end else begin state <= nextstate; Pulse <= pulse_d; end end endmodule Test vectors (stimuli & expected outputs) read in by testbench:test.vec
11 10 10 10 10 01 11 10 10 10 Testbench:edgedetector_tb.v
// Edge Detector TestBench - Claudio Talarico `timescale 1ns/1ns module edgedetector_tb; parameter ClkPeriod=20, NVect=10, ClkOffset=2, ProbeDel = 2, NField = 2; integer j, fc; //fc=failcount integer Log_File; reg [NField : 1] Vmem [1 : NVect]; reg Pulse_exp; reg Clk_tb; // inputs to RTL hardware model (Device Under Test) reg Clk, Rst, Din; //outputs from DUT wire Pulse; //instantiate the DUT edgedetector edge_detector_inst(Clk, Rst, Din, Pulse); initial begin $dumpfile("edgedetector.vcd"); $dumpvars(0); end // initialiaze inputs initial begin Rst=0; Din=0; Clk=0; end // initialize testbench initial begin Clk_tb = 0; fc = 0; end //setup a free running virtual clock always begin #(ClkPeriod/2) Clk_tb = ~Clk_tb; end //setup a free running system clock initial begin #ClkOffset; //initial offset between the clocks forever #(ClkPeriod/2) Clk = ~Clk; end // Perform System Reset initial begin #2; #1 Rst = 1; #4 Rst = 0; end // main test initial begin Log_File = $fopen("logfile"); $readmemb("test.vec", Vmem); for(j=1;j<=NVect;j=j+1) begin @ (posedge Clk_tb); begin {Din,Pulse_exp} = Vmem[j]; #(ClkOffset + ProbeDel); // let value settle if (Pulse !== Pulse_exp) begin $fdisplay(Log_File, "Time=%t ::", $time," ***** Mismatch on Vector %d *****", j); fc = fc + 1; end else begin $fdisplay(Log_File, "Time=%t ::", $time, "vector %d successfull", j); end end end if(!fc) $fdisplay(Log_File, "Simulation finished successfully"); else $fdisplay(Log_File, "***** Simulation finished unsuccessfully *****"); $fclose(Log_File); $finish; end initial begin $monitor("Time=%t :: ", $time, "Clk_tb=%b, Clk=%b, Din=%b, Pulse=%b", Clk_tb, Clk, Din, Pulse); end endmodule |