• 异步FIFO的编程


    对于异步FIFO。最基本的两个方面是地址控制和空、满标志位的产生。首先地址控制分别为读地址和写地址,每次读写时能读写地址应该加1.计数次数为ram深度的2倍。当读写地址相等时则空标志位有效,当读写地址最高位互补其余位相等时则满标志位有效。

    存储部分採用双口RAM实现。


    以下是详细的Verilog代码:

    module afifo(r_clk,w_clk,rst_n,data_in,data_out,we,re,empty,full);
    input r_clk,w_clk,rst_n,re,we;
    output empty,full;
    input [7:0] data_in;
    output[7:0] data_out;
    wire[4:0] waddr,raddr;
    wire [4:0] g_waddr,g_raddr;
    // empty full
    assign empty=(raddr==waddr);
    assign full=((raddr[3:0]==waddr[3:0])&&(raddr[4]==(~waddr[4])));


    wire wenable=we&&(~full);
    wire renable=re&&(~empty);


    afifo_control afifo_control1(
    .r_clk(r_clk),
    .w_clk(w_clk),
    .rst_n(rst_n),
    .we(wenable),
    .re(renable),
    .raddr(raddr),
    .waddr(waddr)
    );


    dualram dualram_inst (
    .data ( data_in ),
    .rdaddress ( raddr[3:0] ),
    .rdclock ( r_clk ),
    .wraddress ( waddr[3:0] ),
    .wrclock ( w_clk ),
    .wren ( wenable ),
    .q ( data_out )
    );


    endmodule 


    module afifo_control(r_clk,w_clk,rst_n,we,re,raddr,waddr);
    input r_clk,w_clk,rst_n,we,re;
    output reg[4:0] raddr,waddr;


    always @(posedge r_clk or negedge rst_n)
    if(!rst_n) begin
    raddr<=3'd0;
    end
    else if(re) begin
    raddr<=raddr+1'b1;
    end
    always @(posedge w_clk or negedge rst_n)
    if(!rst_n) begin
    waddr<=3'd0;
    end
    else if(we) begin
    waddr<=waddr+1'b1;
    end
    endmodule 


    testbench例如以下:

    `timescale 1 ns/ 1 ps
    module afifo_vlg_tst();
    // constants                                           
    // general purpose registers
    //reg eachvec;
    // test vector input registers
    reg [7:0] data_in;
    reg r_clk;
    reg re;
    reg rst_n;
    reg w_clk;
    reg we;
    // wires                                               
    wire [7:0]  data_out;
    wire empty;
    wire full;


    // assign statements (if any)                          
    afifo i1 (
    // port map - connection between master ports and signals/registers   
    .data_in(data_in),
    .data_out(data_out),
    .empty(empty),
    .full(full),
    .r_clk(r_clk),
    .re(re),
    .rst_n(rst_n),
    .w_clk(w_clk),
    .we(we)
    );
    initial                                                
    begin                                                  
    #0; rst_n=1;data_in=100;re=0;we=0;
    #50;rst_n=0; 
    #50;rst_n=1;  
    #20;re=1;
    #20;re=0; 
    #20;we=1;
    #60;data_in=180;
    #2000;we=0;re=1;
    #3000;re=0;
    #100;$stop();
                       
    end                                                    
    always                                                 
    // optional sensitivity list                           
    // @(event1 or event2 or .... eventn)                  
    begin                                                  
    // code executes for every event on sensitivity list   
    // insert code here --> begin                          
       #10 r_clk=1; w_clk=0;
       #10 r_clk=0; w_clk=1;
    //@eachvec;                                              
    // --> end                                             
    end                                                    
    endmodule

  • 相关阅读:
    NYOJ 35
    TOJ 3072
    HDU 1075
    POJ 1028
    TOJ 1153
    TOJ 1036
    POJ 1521
    POJ 3253
    NYOJ 467
    HDU 1671
  • 原文地址:https://www.cnblogs.com/llguanli/p/6914373.html
Copyright © 2020-2023  润新知