E203 bypass buffer


如果fifo中没有数据,且有输入,则是bypass fifo,同周期内直接把输入数据转到输出数据。如果fifo中有数据,则读取fifo,成为普通的同步fifo。

复制代码
module sirv_gnrl_bypbuf # (
  parameter DP = 8,
  parameter DW = 32
) (
  input           i_vld,
  output          i_rdy,
  input  [DW-1:0] i_dat,

  output          o_vld,
  input           o_rdy,
  output [DW-1:0] o_dat,

  input           clk,
  input           rst_n
);


  wire          fifo_i_vld;
  wire          fifo_i_rdy;
  wire [DW-1:0] fifo_i_dat;

  wire          fifo_o_vld;
  wire          fifo_o_rdy;
  wire [DW-1:0] fifo_o_dat;

  sirv_gnrl_fifo # (
       .DP(DP),
       .DW(DW),
       .CUT_READY(1)
  ) u_bypbuf_fifo(
    .i_vld   (fifo_i_vld),
    .i_rdy   (fifo_i_rdy),
    .i_dat   (fifo_i_dat),
    .o_vld   (fifo_o_vld),
    .o_rdy   (fifo_o_rdy),
    .o_dat   (fifo_o_dat),
    .clk     (clk  ),
    .rst_n   (rst_n)
  );

   // This module is a super-weapon for timing fix,
   // but it is tricky, think it harder when you are reading, or contact Bob Hu

  assign i_rdy = fifo_i_rdy;

  // The FIFO is bypassed when:
  //   * fifo is empty, and o_rdy is high
  wire byp = i_vld & o_rdy & (~fifo_o_vld);

  // FIFO o-ready just use the o_rdy
  assign fifo_o_rdy = o_rdy;

  // The output is valid if FIFO or input have valid
  assign o_vld = fifo_o_vld | i_vld;

  // The output data select the FIFO as high priority
  assign o_dat = fifo_o_vld ? fifo_o_dat : i_dat;

  assign fifo_i_dat  = i_dat;

  // Only pass to FIFO i-valid if FIFO is not bypassed
  assign fifo_i_vld = i_vld & (~byp);


endmodule
复制代码
复制代码
module sirv_gnrl_dffs_tb;

   reg  clk=0,rst_n;
   reg  i_vld, o_rdy;
   reg  [31:0] i_dat;

   wire i_rdy, o_vld;
   wire [31:0] o_dat;

   sirv_gnrl_bypbuf  #(.CUT_READY(1),.DP(4),.DW(32)) mybuf(.i_vld(i_vld),.i_rdy(i_rdy),.i_dat(i_dat),.o_vld(o_vld),.o_rdy(o_rdy),.o_dat(o_dat),.clk(clk),.rst_n(rst_n));

   always #10 clk=~clk;

   initial
   begin
	rst_n=1'b1;
	i_vld = 1'b0;
        o_rdy = 1'b0;
	i_dat = 32'h12345678;
	#20
	rst_n=1'b0;
	#80
	rst_n=1'b1;
	#80
	i_vld = 1'b1;
        o_rdy = 1'b1;
	i_dat = 32'h8;
	#20
	i_vld = 1'b1;
        o_rdy = 1'b1;
	i_dat = 32'h12;
	#20
	i_vld = 1'b1;
        o_rdy = 1'b1;
	i_dat = 32'h2;
	#20
	i_vld = 1'b1;
        o_rdy = 1'b1;
	i_dat = 32'h11;
	#20
	i_vld = 1'b1;
        o_rdy = 1'b1;
	i_dat = 32'h13;
	#20
	i_vld = 1'b1;
        o_rdy = 1'b1;
	i_dat = 32'h6;
	#20
	i_vld = 1'b1;
        o_rdy = 1'b1;
	i_dat = 32'h22;
	#20
	i_vld = 1'b1;
        o_rdy = 1'b1;
	i_dat = 32'h99;
	#20
	i_vld = 1'b1;
        o_rdy = 1'b1;
	i_dat = 32'h33;
	#20
	i_vld = 1'b0;
        o_rdy = 1'b1;
	i_dat = 32'h17;
	#20
	i_vld = 1'b1;
        o_rdy = 1'b1;
	i_dat = 32'h3;
        #500 $finish;
   end

   initial
	   $monitor($time,,,"clk=%b,rst_n=%b,i_vld=%b,o_rdy=%b, i_rdy=%b, o_vld=%b,",clk,rst_n,i_vld,o_rdy,i_rdy,o_vld);
   initial
   begin
   	//$dumpfile("dump.vcd");
   	//$dumpvars;
   	$fsdbDumpfile("dump.fsdb");
	$fsdbDumpvars("+all");
   end



   endmodule
复制代码

用上面的testbench,可以看到是bypass buffer,fifo_o_vld总为0

image

复制代码
module sirv_gnrl_dffs_tb;

   reg  clk=0,rst_n;
   reg  i_vld, o_rdy;
   reg  [31:0] i_dat;

   wire i_rdy, o_vld;
   wire [31:0] o_dat;

   sirv_gnrl_bypbuf  #(.CUT_READY(1),.DP(4),.DW(32)) mybuf(.i_vld(i_vld),.i_rdy(i_rdy),.i_dat(i_dat),.o_vld(o_vld),.o_rdy(o_rdy),.o_dat(o_dat),.clk(clk),.rst_n(rst_n));

   always #10 clk=~clk;

   initial
   begin
	rst_n=1'b1;
	i_vld = 1'b0;
        o_rdy = 1'b0;
	i_dat = 32'h12345678;
	#20
	rst_n=1'b0;
	#80
	rst_n=1'b1;
	#80
	i_vld = 1'b1;
        o_rdy = 1'b0;
	i_dat = 32'h8;
	#20
	i_vld = 1'b1;
        o_rdy = 1'b0;
	i_dat = 32'h12;
	#20
	i_vld = 1'b1;
        o_rdy = 1'b1;
	i_dat = 32'h2;
	#20
	i_vld = 1'b1;
        o_rdy = 1'b1;
	i_dat = 32'h11;
	#20
	i_vld = 1'b1;
        o_rdy = 1'b1;
	i_dat = 32'h13;
	#20
	i_vld = 1'b1;
        o_rdy = 1'b1;
	i_dat = 32'h6;
	#20
	i_vld = 1'b1;
        o_rdy = 1'b1;
	i_dat = 32'h22;
	#20
	i_vld = 1'b1;
        o_rdy = 1'b1;
	i_dat = 32'h99;
	#20
	i_vld = 1'b1;
        o_rdy = 1'b1;
	i_dat = 32'h33;
	#20
	i_vld = 1'b0;
        o_rdy = 1'b1;
	i_dat = 32'h17;
	#20
	i_vld = 1'b1;
        o_rdy = 1'b1;
	i_dat = 32'h3;
        #500 $finish;
   end

   initial
	   $monitor($time,,,"clk=%b,rst_n=%b,i_vld=%b,o_rdy=%b, i_rdy=%b, o_vld=%b,",clk,rst_n,i_vld,o_rdy,i_rdy,o_vld);
   initial
   begin
   	//$dumpfile("dump.vcd");
   	//$dumpvars;
   	$fsdbDumpfile("dump.fsdb");
	$fsdbDumpvars("+all");
   end



   endmodule
View Code
复制代码

如果用上面的testbench,则变成普通的buffer,没有bypass


image

posted on   迈克老狼2012  阅读(1451)  评论(1编辑  收藏  举报

编辑推荐:
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· Vue3状态管理终极指南:Pinia保姆级教程

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5
点击右上角即可分享
微信分享提示