深度为1的异步FIFO设计

其实绝大多数的异步FIFO不会设计成深度为1的FIFO,但是我看很多题都是说到了这个,既然是FIFO那就是控数据流的,设计成深度为1岂不是效率很低?

我寻思这就涉及到了一个最小深度的问题,就是对于写满读快或者读写频率相同但是相位不同的FIFO,我看很多FIFO深度专题都是说之为1,那岂不是每次写FIFO的中间间隔很长?那还可以当成FIFO来用吗?

这里留给大家思考,如果连续的读写异步的FIFO深度多少合适呢?~~

回到题目里面深度为1的异步FIFO,设计起来思路很简单,写的时候FULL拉高,然后读出去的时候FULL再拉低,同理读的时候EMPTY拉高,写进来的时候EMPTY再拉低

也就是对读写的信号做个脉冲同步就行

然后读写数据的时候 满的时候不能写,空的时候不能读。

代码如下:

`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// BRAD
// Create Date: 2022/07/02 10:28:03
// Design Name: 
// Module Name: sync_fifo_onebit
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//

//外面的逻辑数据写的时候如果FULL为高就不要写了
//外面的逻辑数据读的时候如果EMPTY为高就不要读了
module sync_fifo_onebit#(
parameter WIDTH = 32
)(
input clka,
input clkb,
input rstn,
input write_en,
input read_en,
input [WIDTH-1:0] push_data,
output [WIDTH-1:0] pop_data,
output reg full,
output reg empty
    );
 reg [WIDTH-1:0] pop_data_r;
 reg [WIDTH-1:0] mem_reg;
 reg toggle_a;
 reg toggle_a_br0;
 reg toggle_a_br1;
 reg toggle_a_br2;
 reg toggle_b;
 reg toggle_b_ar0;
 reg toggle_b_ar1;
 reg toggle_b_ar2;
 assign pop_data = pop_data_r;
 always@(posedge clka or negedge rstn)begin
 if(~rstn)
    mem_reg <= {WIDTH{1'b0}};
 else if(write_en)
    mem_reg <= push_data;
 end
 always@(posedge clka or negedge rstn)begin
 if(~rstn)
 toggle_a <= 1'b0;
 else if(write_en)
 toggle_a <= ~toggle_a;
 end
 always@(posedge clka or negedge rstn)begin
 if(~rstn)
 begin
    toggle_b_ar0 <= 1'b0;
    toggle_b_ar1 <= 1'b0;
    toggle_b_ar2 <= 1'b0;
 end
 else
 begin
    toggle_b_ar0 <= toggle_b;
    toggle_b_ar1 <= toggle_b_ar0;
    toggle_b_ar2 <= toggle_b_ar1;
 end
 end
 
 always@(posedge clkb or negedge rstn)begin
 if(~rstn)
    pop_data_r <= {WIDTH{1'b0}};
 else if(read_en)
    pop_data_r <= mem_reg;
 end
 always@(posedge clkb or negedge rstn)begin
 if(~rstn)
 toggle_b <= 1'b0;
 else if(read_en)
 toggle_b <= ~toggle_b;
 end
 always@(posedge clkb or negedge rstn)begin
 if(~rstn)
 begin
    toggle_a_br0 <= 1'b0;
    toggle_a_br1 <= 1'b0;
    toggle_a_br2 <= 1'b0;
 end
 else
 begin
    toggle_a_br0 <= toggle_a;
    toggle_a_br1 <= toggle_a_br0;
    toggle_a_br2 <= toggle_a_br1;
 end
 end
 
 always@(*)begin
    if(~rstn)
    full  = 1'b0;
    else if(write_en)
    full  = 1'b1;
    else if(toggle_b_ar2 ^ toggle_b_ar1)
    full  = 1'b0;
    else
    full  = full;
    end
 always@(*)begin
    if(~rstn)
    empty  = 1'b1;
    else if(read_en)
    empty  = 1'b1;
    else if(toggle_a_br2 ^ toggle_a_br1)
    empty  = 1'b0;
    else
    empty  = empty;
    end
endmodule

对应的TB如下所示

`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// BRAD
// Create Date: 2022/07/02 11:28:49
// Design Name: 
// Module Name: tb_sync_fifo_onebit
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//


module tb_sync_fifo_onebit(

    );
reg clka = 0;
reg clkb = 0;
reg rstn = 0;
reg write_en = 0;
reg read_en = 0;
reg [31:0] push_data =32'b0;
wire [31:0] pop_data;
wire full;
wire empty;

parameter period_a = 4;
parameter period_b = 6;

initial begin
forever #(period_a/2) clka <= ~clka;
end
initial begin
forever #(period_b/2) clkb <= ~clkb;
end

initial begin
#(period_a*2) rstn <= 1'b1;
end

always@(posedge clka or negedge rstn)begin
if(~rstn)begin
    push_data <= 32'b0;
    write_en <= 1'b0;
    end
else if(~full)
begin
    push_data <= push_data + 1'b1;
    write_en <= 1'b1;
end
else if(full)
begin
    push_data <= push_data;
    write_en <= 1'b0;
end
end
always@(posedge clkb or negedge rstn)begin
if(~rstn)
    read_en <= 1'b0;
else if(~empty)
    read_en <= 1'b1;
else if(empty)
    read_en <= 1'b0;
end

sync_fifo_onebit DUT(
    .clka       (clka     ),
    .clkb       (clkb     ),
    .rstn       (rstn     ),
    .write_en   (write_en ),
    .read_en    (read_en  ),
    .push_data  (push_data),
    .pop_data   (pop_data ),
    .full       (full     ),
    .empty      (empty    )
        );

endmodule

读写数据还算正常 

  • 5
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值