zoukankan      html  css  js  c++  java
  • FIFO的设计与仿真

    本设计参照齐威王大哥的设计,采用模块化的设计方法,每个模块简单易懂,并进行了每个模块的仿真。最后进行顶层设计,编写了测试激励在modisim上仿真正确,

    下面给出代码和测试激励,附上一篇比较好的英文文献。

    复制代码
     1 module yibu_fifo(wclk,wreset,wdata,wena,rclk,rena,rdata,rreset,full,empty);
     2 parameter DSIZE = 8,    
     3           ASIZE = 4;
     4 input wclk,wreset,rclk,rreset;
     5 input wena,rena; //写控制信号  读控制信号
     6 input [DSIZE-1:0] wdata;  //写数据
     7 output[DSIZE-1:0] rdata;  //读数据
     8 output full,empty ;//写满 读空
     9 wire  [ASIZE:0] wzz, wzz_syn,rzz,rzz_syn;   //特别注意
    10 wire  [ASIZE-1:0] raddr,waddr;              //特别注意
    11 fifomem   U1(rdata, wdata, waddr, raddr, wena,full, wclk);
    12 w_full    U2(full, waddr, wzz, rzz_syn, wena, wclk, wreset);
    13 r_empty   U3(empty, raddr, rzz, wzz_syn, rena, rclk, rreset);
    14 syn_w2r   U4(wzz,rclk,rreset,wzz_syn);
    15 syn_r2w   U5(wclk,wreset,rzz,rzz_syn);
    16 endmodule 
    复制代码
    复制代码
    module fifomem (rdata, wdata, waddr, raddr, wena,full, wclk);
    parameter DSIZE = 8,  
              ASIZE = 4;
    input wclk;
    input [DSIZE-1:0] wdata;
    input wena,full;
    output [DSIZE-1:0] rdata;
    input [ASIZE-1:0] waddr;
    input [ASIZE-1:0] raddr;
    reg [DSIZE-1:0] mem[0:(1<<ASIZE)-1];  //register  
    assign rdata=mem[raddr];                 //read
    always @(posedge wclk)                //write
    if (wena && !full)  
        mem[waddr] <= wdata;   
    endmodule 
    复制代码
    复制代码
    module r_empty(empty, raddr, rzz, wzz_syn, rena, rclk, rreset);
    parameter DSIZE = 8,  
              ASIZE = 4;  //
    input rclk, rreset,rena;
    input [ASIZE:0] wzz_syn;
    output [ASIZE:0] rzz;
    output [ASIZE-1:0] raddr;
    output empty;
    reg empty;
    reg [ASIZE:0] rzz;
    reg [ASIZE:0] rbin;
    wire [ASIZE:0] rgraynext,rbinnext;
    //-------------empty产生与raddr产生-------------------  
    always @(posedge rclk or negedge rreset) // GRAYSTYLE2 pointer  
    begin 
        if (!rreset)  
            {rbin, rzz} <= 0;  
        else 
            {rbin, rzz} <= {rbinnext, rgraynext};  
    end   
    // Memory read-address pointer (okay to use binary to address memory)  
    assign raddr = rbin[ASIZE-1:0];  
    assign rbinnext = rbin + (rena & ~empty);  
    assign rgraynext = (rbinnext>>1) ^ rbinnext;  
      
    // FIFO empty when the next rptr == synchronized wptr or on reset  
    assign rempty_val = (rgraynext == wzz_syn);  
    always @(posedge rclk or negedge rreset)  
    begin 
        if (!rreset)  
            empty <= 1'b1;  
        else 
            empty <= rempty_val;  
    end 
    endmodule 
    复制代码
    复制代码
    module w_full(full, waddr, wzz, rzz_syn, wena, wclk, wreset);
    parameter DSIZE = 8,  
              ASIZE = 4;
    input wclk,wreset;
    input wena;
    input [ASIZE:0] rzz_syn;
    output [ASIZE:0] wzz;
    output full;
    output [ASIZE-1:0] waddr;
    reg full;
    reg  [ASIZE:0] wzz;
    reg [ASIZE:0] wbin;
    wire [ASIZE:0] wgraynext,wbinnext;
    //---------------full产生与waddr产生--------------------
    always @(posedge wclk or negedge wreset)  
        if (!wreset)  
            {wbin, wzz} <= 0;  
        else 
            {wbin, wzz} <= {wbinnext, wgraynext};  
    // Memory write-address pointer (okay to use binary to address memory)  
    assign waddr = wbin[ASIZE-1:0];  
    assign wbinnext = wbin + (wena & ~full); 
     
    assign wgraynext = (wbinnext>>1) ^ wbinnext; //bin to g 
    assign wfull_val = (wgraynext=={~rzz_syn[ASIZE:ASIZE-1], rzz_syn[ASIZE-2:0]}); //  full   
      
    always @(posedge wclk or negedge wreset)  
        if (!wreset)  
            full <= 1'b0;  
        else 
            full <= wfull_val;       
    endmodule 
    复制代码
    复制代码
    module syn_r2w(wclk,wreset,rzz,rzz_syn);
     parameter DSIZE = 8,  
              ASIZE = 4;
    input wclk,wreset;
    input [ASIZE:0] rzz;
    output [ASIZE:0] rzz_syn;
    reg [ASIZE:0] rzz_syn;
    reg [ASIZE:0]  rzz_syn_1;   //两级同步
    always @(posedge wclk or negedge wreset)
    if(!wreset)
    {rzz_syn,rzz_syn_1} <= 0;
    else 
    {rzz_syn,rzz_syn_1} <= {rzz_syn_1,rzz};
    endmodule 
     
    复制代码
    复制代码
    module syn_w2r (wzz,rclk,rreset,wzz_syn);
    parameter DSIZE = 8,  
              ASIZE = 4;
    input rclk,rreset;
    input [ASIZE:0] wzz;
    output [ASIZE:0] wzz_syn;
    reg  [ASIZE:0] wzz_syn;
    reg [ASIZE:0] wzz_syn_1;    //两级同步
    always @(posedge rclk or negedge rreset)  
        if (!rreset)  
            {wzz_syn,wzz_syn_1} <= 0;  
        else 
            {wzz_syn,wzz_syn_1} <= {wzz_syn_1,wzz};         
    endmodule 
    复制代码
    复制代码
    module testbench;
    reg wclk,wreset;
    reg rclk,rreset;
    reg rena;
    reg wena;
    wire full;
    wire empty;
    reg [7:0] wdata;
    wire [7:0] rdata;
    reg [7:0]    value;
    yibu_fifo    FIFO(wclk,wreset,wdata,wena,rclk,rena,rdata,rreset,full,empty);
    // read
    task read_word;
    begin
       @(negedge rclk);
       rena = 1;
       @(posedge rclk)
       #5;
       rena = 0;
    end
    endtask
    //write
    task write_word;
    input [7:0]    value;
    begin
       @(negedge wclk);
       wdata = value;
       wena = 1;
       @(posedge wclk);
       #5;
       wdata = 8'hzz;
       wena = 0;
    end
    endtask
    //write clock
    initial begin
       wclk = 0;
       forever begin
          #5 wclk = 1;
          #5 wclk = 0;
       end
    end
    //read clock
    initial begin
       rclk = 0;
       forever begin
          #10 rclk = 1;
          #10 rclk = 0;
       end
    end
    // process
    initial 
    begin
      test1; 
    end
    task test1;
    begin
       wdata = 8'hzz;
       wena = 0;
       rena = 0;
       wreset = 0;
       rreset= 0;
       #10 wreset = 1;rreset=1;
       #50;
        //写入10个数据
       write_word (8'h01);
       write_word (8'h02);   //正常
       write_word (8'h03);   
       write_word (8'h04); 
       write_word (8'h05); 
       write_word (8'h06); 
       write_word (8'h07); 
       write_word (8'h08); 
       write_word (8'h09); 
       write_word (8'h0A); 
       repeat (10) 
       begin
          read_word;   // read 10
       end
    write_word (8'h01);
    write_word (8'h02);
    write_word (8'h03);
    write_word (8'h04);
    write_word (8'h05);
    write_word (8'h06);
    write_word (8'h07);
    write_word (8'h08);
    write_word (8'h09);
    write_word (8'h0A);
    write_word (8'h0B);
    write_word (8'h0C);
    write_word (8'h0D);
    write_word (8'h0E);
    write_word (8'h0F);
    write_word (8'h10);
    write_word (8'h11);
    write_word (8'h12);
    write_word (8'h13); //    写满溢出
       repeat (16) 
       begin
          read_word;   // 读空  
       end
    end 
    endtask
    endmodule 
    复制代码

    2013-03-24

    英文文献http://www.sunburst-design.com/papers/

  • 相关阅读:
    Java 多态
    Java 继承与抽象类
    Java 接口
    关于Oracle数据库故障诊断基础架构
    监控性能
    监视错误和警报
    内存管理参考
    使用自动内存管理
    内存架构概述
    关于内存管理
  • 原文地址:https://www.cnblogs.com/lueguo/p/3357499.html
Copyright © 2011-2022 走看看