tb_fifo

来源:互联网 发布:mac资源管理器快捷键 编辑:程序博客网 时间:2024/06/14 13:30
`timescale 1ns / 100ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date:    19:42:15 02/17/2009 
// Design Name: 
// Module Name:    tb_fifo 
// Project Name: 
// Target Devices: 
// Tool versions: 
// Description: 
//
// Dependencies: 
//
// Revision: 
// Revision 0.01 - File Created
// Additional Comments: 
//
//////////////////////////////////////////////////////////////////////////////////
module tb_fifo;


reg [15:0] din;
reg     rd_clk;
reg       rd_en;
reg       rst;
reg       wr_clk;
reg       wr_en;
wire     almost_empty;
wire     almost_full;
wire[15:0]  dout;
wire     empty;
wire     full;
wire     overflow;
wire[8:0] rd_data_count;
wire     underflow;
wire[8:0] wr_data_count;
integer   i;
integer   file1;
            reg[15:0] data2file;
            reg[15:0] mem[2000:1];
            reg       start;
            integer  wr_count;
            integer  rd_count;
/********************************************
                   ???
********************************************/
fifo_top  asyn_fifo (
          .din(din),
          .rd_clk(rd_clk),
          .rd_en(rd_en),
          .rst(rst),
          .wr_clk(wr_clk),
          .wr_en(wr_en),
          .almost_empty(almost_empty),
          .almost_full(almost_full),
          .dout(dout),
          .empty(empty),
          .full(full),
          .overflow(overflow),
          .rd_data_count(rd_data_count),
          .underflow(underflow),
          .wr_data_count(wr_data_count)
 );
 
/********************************************
               ??????
********************************************/
initial
     begin
    wr_clk = 0;
 forever #5 wr_clk = ~wr_clk;  // f=100 MHz
 end
 
initial
     begin
    rd_clk = 0;
 forever #10.4 rd_clk = ~rd_clk; // f= 48MHz
 end
/********************************************
                 ???
********************************************/


initial
     begin
    rst    = 0;
 wr_en  = 0;
 rd_en  = 0;
 din    = 0;
 start  = 0;
 #100;
 #20;
 reset;
 $display("reset case done!");
 case_underflow;
 $display("underflow case done!");
 case_singleRD_WR;
 $display("singleRD_WR case done!");
 case_overflow;
 $display("overflow case done!");
 reset;
 case_multiRD_WR;
 $display("multiRD_WR case done!");
 $finish;
 end
/********************************************
                  ????
********************************************/
task reset;
     begin
       rst   = 1;
@(posedge wr_clk);
rst   = 0;
@(posedge wr_clk);
 end
endtask


task case_singleRD_WR;
     begin
       @(negedge wr_clk);
   wr_en = 1;
   din   = 16'habcd;
       @(negedge wr_clk);
   wr_en = 0;
   @(negedge empty);   //?FIFO???????????fifo?????
   rd_en = 1;
   @(posedge rd_clk);
   if(dout!=16'habcd) $display("single write_read error!");
   @(negedge rd_clk);
   rd_en = 0;
   repeat(3) @(negedge rd_clk);
 end
endtask
/***************************
    ?fifo?????????
       ???fifo??
***************************/
task  case_underflow;
      begin
      @(negedge rd_clk);
    rd_en = 1;
    @(negedge rd_clk);
    rd_en = 0;
    repeat(3) @(negedge rd_clk);   
      end
endtask
/***************************
  ?fifo???????????
       ???fifo??
***************************/


task case_overflow;
      begin
         wr_en  =  1;
         for(i=0;i<515;i=i+1)
            begin
                @(posedge wr_clk);
                din  =  i;
                if(overflow) $display("fifo is overflow!!!");
            end
         @(posedge wr_clk);
         wr_en  =  0;
      end
endtask
/**************************
        fifo?????
**************************/




task  case_multiRD_WR;
      begin
         start = 0;
         wr_count = 0;
         rd_count = 0;
         file1 = $fopen("wr.dat");
         for(i=0;i<2000;i=i+1)
            begin
                data2file = {$random}%16'hffff;
                $fdisplayh(file1,data2file);
            end
         $readmemh("wr.dat",mem);
         start  = 1;
         #10000;
         start  = 0;
         $fclose(file1);
      end
endtask


always @(negedge wr_clk)
       begin:sender
           if(start)
             begin
                 if(!full)
                    begin
                      wr_en    <= 1;
                      din      <= mem[wr_count];
                      wr_count <= wr_count + 1;
                    end
                 else
                    begin
                      wr_en    <= 0;
                      wr_count <= wr_count;
                    end
              end
       end


always @ (negedge rd_clk)
       begin:reciever
           if(start)
              begin
                  if(!empty)
                    begin
                     rd_en    <= 1;
                     rd_count <= rd_count + 1;
                     @(posedge rd_clk);
                     if(dout!=mem[rd_count]) 
                         $display("read data error at %d ,rd=%d ,wr=%d",rd_count,dout,mem[rd_count]);
                     else
                         $display("read data correct at %d ,rd=%d ,wr=%d",rd_count,dout,mem[rd_count]);
                    end
                  else
                     begin
                      rd_en     <= 0;
                      rd_count  <= rd_count;
                     end
              end
       end
endmodule
0 0
原创粉丝点击