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


浙公网安备 33010602011771号