小武学fpgastep7

1.创建ip核。在ipcatlog那里搜索fifo,选择fifo generator

 2.首先还是选择标准的接口类型,AXI4还不知道怎么用,下面注意配置成异步时钟(common clock block ram是同步的,independent clocks的是异步),异步的才可以使读跟写是不同的时钟。否则就只能是一个时钟。失去了跨时钟域传递数据的意义。

 3.第一个是标准fifo第二个是第一个字在开始。这两个就相差一个周期输出数据(目前是这样的理解,biaozhunfifo会延迟一个时钟周期)/ 位宽是一位的长度,深度能存多少个数据。8位的位宽最大存的数是255.10位最大是1023。深度是能存多少个这样的数。读是根据写来推断的。读和写的位宽最好一致,不然读出来的数据会出问题。其他的暂时还没用到

 4.快空快满的信号勾上,提前一个时钟周期来判断防止出现亚稳态。

 5.计数,计算fifo里面还有多少个数,。如果前面读跟写设置的同时钟这里两个数应该是一样的。如果时钟不一样就不一样了(我这里读时钟是写时钟的两倍所以读的变得块),后面的summary就是fifo的设置总结了。

 6.配置完FIFOip核之后就开始写代码,分为读跟写两个部分。写的时候判断快空的信号,快空的时候,将使能拉高开始写。快满的时候开始停止写数据将使能拉低。注意当复位的时候要将写使能拉高一下不然数据清空的时候就快空的信号就无法跳高了因为已经空了。

module fifo_write(
    input                  clk,
    input                  rst_n,
    input                  almost_empty     ,
    input                  almost_full      ,
    output  reg            fifo_wr_en       ,
    output  reg   [9:0]    fifo_wr_data
    );
      
    reg alemp_do;
    reg alemp_d1;
    wire alemp_flag;
    assign alemp_flag=alemp_do&!alemp_d1;
    always@(posedge clk or negedge rst_n)begin//判断是否为快空
        if(!rst_n)begin
            alemp_do<=1'b0;
            alemp_d1<=1'b0;
        end
        else begin
            alemp_do<=almost_empty;
            alemp_d1<=alemp_do;
        end  
    end
    reg [3:0]cnt_dly;
    reg [1:0]state;
    always@(posedge clk or negedge rst_n)begin//开始赋值
        if(!rst_n)begin
            fifo_wr_en<=1'b1;
            fifo_wr_data<=1'b0;
            cnt_dly<=1'b0;
            state<=1'b0;
        end
        else begin
            case(state)
                2'd0:begin
                    if(alemp_flag)
                        state<=2'd1;
                     else
                        state<=state;   
                end
                2'd1:begin
                    if(cnt_dly==4'd10)begin
                        state<=2'd2;
                        cnt_dly<=1'b0; 
                    end 
                    else
                        cnt_dly<=cnt_dly+1'b1;      
                end
                2'd2:begin
                    if(almost_full)begin
                       fifo_wr_en<=1'b0;
                       fifo_wr_data<=1'b0;
                       state<=2'd0;
                    end
                    else begin
                    	fifo_wr_en<=1'b1;
                    	fifo_wr_data<=fifo_wr_data+1'b1;  
                    end          
                end
                default: state<=2'd0;
                endcase
        end
    end 
endmodule

 7.读跟写刚好相反,判断快满的信号,快满的时候,将使能拉高开始读。快空的时候延时一段时间停止读数据,并将使能拉低。

module fifo_read(
    input                  clk,
    input                  rst_n,
    input                  almost_empty     ,
    input                  almost_full      ,
    output  reg            fifo_rd_en       ,
     input  [9:0]           fifo_rd_data
    );
    
    reg alful_do;
    reg alful_d1;
    wire alful_flag;
    reg [3:0]cnt_dly;
    reg [1:0]state;
    assign alful_flag=alful_do&!alful_d1;
    always@(posedge clk or negedge rst_n)begin//判断满了
        if(!rst_n)begin
            alful_do<=1'b0;
            alful_d1<=1'b0;
        end
        else begin
            alful_do<=almost_full;
            alful_d1<=alful_do;
        end  
    end

    always@(posedge clk or negedge rst_n)begin//开始赋值
        if(!rst_n)begin
            fifo_rd_en<=1'b0;
            cnt_dly<=1'b0;
            state<=1'b0;
        end
        else begin
            case(state)
                2'd0:begin
                    if(alful_flag)
                        state<=2'd1;
                     else
                        state<=state;   
                end
                2'd1:begin
                    if(cnt_dly==4'd10)begin
                        state<=2'd2;
                        cnt_dly<=1'b0; 
                    end 
                    else
                        cnt_dly<=cnt_dly+1'b1;      
                end
                2'd2:begin
                    if(almost_empty)begin
                       fifo_rd_en<=1'b0;
                       state<=2'd0;
                    end
                    else begin
                    	fifo_rd_en<=1'b1;
                    	
                    end          
                end
                default: state<=2'd0;
                endcase
        end
    end 
endmodule

8.最后在顶层调用就行了,注意数据的位宽。定义一个时钟ip核来产生两个不同频率的时钟。


module fifo_top(
input clk,
input rst_n

    );
    
    wire [9:0] write_data;
    wire [9:0] read_data;
    wire [9:0]  rd_data_count;
    wire [9:0]  wr_data_count;
    wire write_en;
    wire almem;
    wire almful;
    wire empty;
    wire full;
    wire read_en;
    wire clk100hz;
    wire clk50hz;
 fifo_write fifo_write_u(
    .   clk         (clk100hz)   ,
    .   rst_n       (rst_n)   ,
    .   almost_empty(almem)   ,
    .   almost_full (almful)   ,
    .   fifo_wr_en  (write_en)   ,
    .   fifo_wr_data(write_data)
    );   
 fifo_read fifo_read_u(
    .     clk           (clk50hz) ,
    .     rst_n         (rst_n)  ,
    .     almost_empty  (almem)  ,
    .     almost_full   (almful)  ,
    .     fifo_rd_en    (read_en)  ,
    .      fifo_rd_data (read_data)
    );
  clk_wiz_0 clk_u(
    // Clock out ports
    .clk_out1(clk50hz),     // output clk_out1
    .clk_out2(clk100hz),     // output clk_out2
    // Status and control signals
    .resetn(rst_n), // input resetn
   // Clock in ports
    .clk_in1(clk));      // input clk_in1


   
fifo_generator_0 your_instance_name (
  .wr_clk(clk100hz),                // input wire wr_clk
  .rd_clk(clk50hz),                // input wire rd_clk
  .din(write_data),                      // input wire [7 : 0] din
  .wr_en(write_en),                  // input wire wr_en
  .rd_en(read_en),                  // input wire rd_en
  .dout(read_data),                    // output wire [7 : 0] dout
  .full(full),                    // output wire full
  .almost_full(almful),      // output wire almost_full
  .empty(empty),                  // output wire empty
  
  .almost_empty(almem),    // output wire almost_empty
  .rd_data_count(rd_data_count),  // output wire [7 : 0] rd_data_count
  .wr_data_count(wr_data_count)  // output wire [7 : 0] wr_data_count
); 

    
ila_0 ila_u (
	.clk(clk), // input wire clk
	.probe0(write_en), // input wire [0:0]  probe0  
	.probe1(read_en),        // input wire [0:0]  probe1 
	.probe2(almful),        // input wire [0:0]  probe2 
	.probe3(full),          // input wire [0:0]  probe3 
	.probe4(almem),         // input wire [0:0]  probe4 
	.probe5(empty),         // input wire [0:0]  probe5 
	.probe6(write_data),    // input wire [9:0]  probe6 
	.probe7(read_data),     // input wire [9:0]  probe7 
	.probe8(clk100hz), // input wire [0:0]  probe8 
	.probe9(clk50hz) // input wire [0:0]  probe9
);    
    
    
endmodule

可以看到读确实比写要快一倍

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值