//****************************************************************************** // * // Copyright (C) 2010 Regents of the University of California. * // * // The information contained herein is the exclusive property of the VCL * // group but may be used and/or modified for non-comercial purposes if the * // author is acknowledged. For all other uses, permission must be attained * // by the VLSI Computation Lab. * // * // This work has been developed by members of the VLSI Computation Lab * // (VCL) in the Department of Electrical and Computer Engineering at * // the University of California at Davis. Contact: bbaas@ece.ucdavis.edu * //****************************************************************************** // // tb.vt // // Testbench for FIFO // // This module will rigorously test the FIFO module. // // Written by Aaron Stillmaker // 8/13/10 // Define FIFO Address width minus 1 and Data word width minus 1 `define ADDR_WIDTH_M1 6 `define DATA_WIDTH_M1 15 `timescale 10ps/1ps `define IN_COUNT 200 module tb(); reg clkP, // write clock clkC, // read clock reset, // reset wr_valid, nap, rd_request, last_request, request, emp, last_empty, wr_en; reg [`DATA_WIDTH_M1:0] data_in, last_data; reg [1:0] delay_sel; // delay select reg [2:0] wr_sync_cntrl, // write sysch control rd_sync_cntrl; // read sync control reg [`ADDR_WIDTH_M1:0] reserve; // reserve wire wr_request, empty; wire [`DATA_WIDTH_M1:0] data_out; integer fh_output, // output file handle r, // random seed iterationP, // count of itteration for clock for producer iterationC, // count of itteration for clock for consumer speedP, // count of speed for clock for producer speedC, // count of speed for clock for consumer symcount, // count of how many runs are done iterationRD, rd_interval, iterationWR, wr_interval; // Initialization for data capture initial begin //$recordfile("tb"); //$recordvars(tb); fh_output = $fopen("output.m"); r = 123; // initialize random seed end // Initialize testbench initial begin clkP=0; clkC=0; reset = 1; rd_request = 0; data_in=7'b0000000; symcount = 1; wr_valid = 0; iterationRD = 0; rd_interval = 10; iterationWR = 0; wr_interval = 10; wr_en = 0; // Delay Select, set how much delay you want in the FIFO delay_sel = 2'b00; // Write and Read number of registers in the asynchronous communication beween the two frequencies wr_sync_cntrl = 3'b000; rd_sync_cntrl = 3'b000; // Reserve space constant reserve = 7'b0000000; // No Increment Read pointer signal nap = 0; // Initialize the speed and interation numbers speedP = 500; speedC = 400; iterationP = 0; iterationC = 0; #50; clkP=1; clkC=1; #50; reset = 0; end // Producer Clock always begin if (iterationP == speedP/2) begin #1 clkP = ~clkP; // alternate the clock iterationP = iterationP + 1; end else if (iterationP == speedP) begin #1 clkP = ~clkP; // alternate the clock iterationP = 0; // reset the counter speedP = 2 * (500 - ($random(r) % 250)); // make a new random number from 500-1500 end else begin #1 iterationP = iterationP + 1; end end // Consumer Clock always begin if (iterationC == speedC/2) begin #1 clkC = ~clkC; // alternate the clock iterationC = iterationC + 1; end else if (iterationC == speedC) begin #1 clkC = ~clkC; // alternate the clock iterationC = 0; // reset the counter speedC = 2 * (500 - ($random(r) % 250)); // make a new random number from 500-1500 if (speedC == (speedP - iterationP)) begin speedC = speedC +4; //make sure the clock pulses do not line up to stop a verilog error end end else begin #1 iterationC = iterationC + 1; end end // Create WR and RD enable signals always @(posedge clkC) begin if (iterationRD == rd_interval) begin #1 rd_request = ~rd_request; // alternate the rd_request iterationRD = 0; // reset the counter rd_interval = (1001 - ($random(r) % 1000)); // make a new random number from 1-2001 end else begin #1 iterationRD = iterationRD + 1; end end always @(posedge clkP) begin if (iterationWR == wr_interval) begin #1 wr_en = ~wr_en; // alternate the wr_en iterationWR = 0; // reset the counter wr_interval = (1001 - ($random(r) % 1000)); // make a new random number from 1-2001 end else begin #1 iterationWR = iterationWR + 1; end end // Generate Producer Input always @(posedge clkP) begin if (wr_request == 1 & wr_en == 1) begin // Inc when the FIFO is ready for a write and the pos edge of the clock wr_valid = 1; data_in = data_in + 1; // The data //$fwrite(fh_output,"In = %h;\n", data_in); #2 wr_valid = 0; // Data is no longer valid end end // Save Output from Consumer always @(posedge clkC) begin // Save output whenever the FIFO is ready to output and the //positive edge of the clock if (last_request == 1 & last_empty != 1) begin last_request = rd_request; last_empty = empty; #1 //$fwrite(fh_output, "Out = %h;\n", data_out); if (last_data + 1 != data_out) begin $display("ERROR last_data = %h while data_out= %h!!!!!!rd_request = %b, last_request = %b, and request = %b\n", last_data, data_out, rd_request, last_request, request); $fwrite(fh_output, "ERROR last_data = %h while data_out= %h!!!!!!rd_request = %b, last_request = %b, and request = %b\n", last_data, data_out, rd_request, last_request, request); end last_data = data_out; end //symcount = symcount + 1; if (symcount == 0 ) begin $display("FINISHED!!!!"); $finish; $fclose(fh_output); end end // Submodule FIFO FIFO ( .reserve (reserve), .wr_sync_cntrl (wr_sync_cntrl), .clk_wr (clkP), .data_in (data_in), .wr_valid (wr_valid), .delay_sel (delay_sel), .wr_request (wr_request), .async_empty (async_empty), .reset (reset), .clk_rd (clkC), .data_out (data_out), .empty (empty), .rd_request (rd_request), .async_full (async_full), .rd_sync_cntrl (rd_sync_cntrl), .nap (nap), .fifo_util (fifo_util) ); endmodule