皋陶 发表于 2021-3-6 14:42:57

E203 bypass buffer

本帖最后由 皋陶 于 2021-3-6 14:42 编辑

如果fifo中没有数据,且有输入,则是bypass fifo,同周期内直接把输入数据转到输出数据。如果fifo中有数据,则读取fifo,成为普通的同步fifo。
module sirv_gnrl_bypbuf # (
parameter DP = 8,
parameter DW = 32
) (
input         i_vld,
output          i_rdy,
input i_dat,

output          o_vld,
input         o_rdy,
output o_dat,

input         clk,
input         rst_n
);


wire          fifo_i_vld;
wire          fifo_i_rdy;
wire fifo_i_dat;

wire          fifo_o_vld;
wire          fifo_o_rdy;
wire 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);


endmodulemodule sirv_gnrl_dffs_tb;

   regclk=0,rst_n;
   regi_vld, o_rdy;
   reg i_dat;

   wire i_rdy, o_vld;
   wire 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


module sirv_gnrl_dffs_tb;

   regclk=0,rst_n;
   regi_vld, o_rdy;
   reg i_dat;

   wire i_rdy, o_vld;
   wire 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
如果用上面的testbench,则变成普通的buffer,没有bypass



页: [1]
查看完整版本: E203 bypass buffer