blob: 159cbf59b79f396bf88202475b3e8e6c0f697eae [file] [log] [blame]
module openFifo8_flopped_2w2r(/*AUTOARG*/
// Outputs
outData0, outData1, fifo_full, fifo_1left_to_full, fifo_empty,
fifo_1left_to_empty, d0, d1, d2, d3, d4, d5, d6, d7, dPtr, dValid,
// Inputs
clk, rst_n, push0, inData0, push1, inData1, pop0, pop1
);
parameter DWIDTH = 32;
// global signal
input clk;
input rst_n;
// write
input logic push0;
input logic [DWIDTH-1:0] inData0;
input logic push1;
input logic [DWIDTH-1:0] inData1;
// read
input logic pop0;
output logic [DWIDTH-1:0] outData0;
input logic pop1;
output logic [DWIDTH-1:0] outData1;
// fifo status
output logic fifo_full;
output logic fifo_1left_to_full;
output logic fifo_empty;
output logic fifo_1left_to_empty;
// open data
output logic [DWIDTH-1:0] d0;
output logic [DWIDTH-1:0] d1;
output logic [DWIDTH-1:0] d2;
output logic [DWIDTH-1:0] d3;
output logic [DWIDTH-1:0] d4;
output logic [DWIDTH-1:0] d5;
output logic [DWIDTH-1:0] d6;
output logic [DWIDTH-1:0] d7;
output logic [2:0] dPtr;
output logic [7:0] dValid;
// Wires & Regs
wire push0_int;
wire [DWIDTH-1:0] inData0_int;
wire push1_int;
wire [DWIDTH-1:0] inData1_int;
wire pop0_int;
wire [DWIDTH-1:0] outData0_int;
wire pop1_int;
wire [DWIDTH-1:0] outData1_int;
wire full0_int;
wire full1_int;
wire empty0_int;
wire empty1_int;
wire [DWIDTH-1:0] d0_0_int;
wire [DWIDTH-1:0] d1_0_int;
wire [DWIDTH-1:0] d2_0_int;
wire [DWIDTH-1:0] d3_0_int;
wire [1:0] nxtRdPtr0_int;
wire [3:0] dValid0_int;
wire [DWIDTH-1:0] d0_1_int;
wire [DWIDTH-1:0] d1_1_int;
wire [DWIDTH-1:0] d2_1_int;
wire [DWIDTH-1:0] d3_1_int;
wire [1:0] nxtRdPtr1_int;
wire [3:0] dValid1_int;
//Push arbitration
wire pushSwapFlag;
wire pushSwapFlag_nxt;
wire single_push = push0 && !push1;
assign pushSwapFlag_nxt = single_push ? !pushSwapFlag : pushSwapFlag;
edff #(1) pushSwapFlagReg (.q(pushSwapFlag), .clk(clk), .rst_n(rst_n), .d(pushSwapFlag_nxt), .en(push0||push1) `ifdef TB_SUPPORT , .init_data('0)`endif);
assign {push1_int,push0_int} = pushSwapFlag ? {push0,push1} : {push1,push0};
assign {inData1_int,inData0_int} = pushSwapFlag ? {inData0,inData1} : {inData1,inData0};
//Pop arbitration
wire popSwapFlag;
wire popSwapFlag_nxt;
wire single_pop = pop0 && !pop1;
assign popSwapFlag_nxt = single_pop ? !popSwapFlag : popSwapFlag;
edff #(1) popSwapReg (.q(popSwapFlag), .clk(clk), .rst_n(rst_n), .d(popSwapFlag_nxt), .en(pop0||pop1) `ifdef TB_SUPPORT , .init_data('0)`endif);
assign {pop1_int,pop0_int} = popSwapFlag ? {pop0,pop1} : {pop1,pop0};
assign {outData1,outData0} = popSwapFlag ? {outData0_int,outData1_int} : {outData1_int,outData0_int};
// Full flag
assign fifo_full = full0_int && full1_int;
assign fifo_1left_to_full = (full0_int && !full1_int) || (!full0_int && full1_int);
// Empty flag
assign fifo_empty = empty1_int && empty0_int;
assign fifo_1left_to_empty = (empty0_int && !empty1_int) || (!empty0_int && empty1_int);
// Open data pack
assign d0 = d0_0_int;
assign d1 = d0_1_int;
assign d2 = d1_0_int;
assign d3 = d1_1_int;
assign d4 = d2_0_int;
assign d5 = d2_1_int;
assign d6 = d3_0_int;
assign d7 = d3_1_int;
wire [3:0] dPtr_even_pre = nxtRdPtr0_int*2;
wire [3:0] dPtr_odd_pre = nxtRdPtr1_int*2 + 1'd1;
assign dPtr = popSwapFlag ? dPtr_odd_pre : dPtr_even_pre;
assign dValid = {dValid1_int[3],dValid0_int[3],
dValid1_int[2],dValid0_int[2],
dValid1_int[1],dValid0_int[1],
dValid1_int[0],dValid0_int[0]};
// Fifo inst even
// Entry 0, 2, 4, 6, 8, ...
openFifo4_flopped_ptr #(DWIDTH) fifo_even (
//Outputs
.fifo_outData(outData0_int),
.fifo_full(full0_int),
.fifo_empty(empty0_int),
.d0(d0_0_int),
.d1(d1_0_int),
.d2(d2_0_int),
.d3(d3_0_int),
.dPtr(nxtRdPtr0_int),
.dValid(dValid0_int),
//Inputs
.clk(clk),
.rst_n(rst_n),
.fifo_inData(inData0_int),
.single_push(push0_int),
.single_pop(pop0_int));
// Fifo inst odd
// Entry 1, 3, 5, 7, 9, ...
openFifo4_flopped_ptr #(DWIDTH) fifo_odd (
//Outputs
.fifo_outData(outData1_int),
.fifo_full(full1_int),
.fifo_empty(empty1_int),
.d0(d0_1_int),
.d1(d1_1_int),
.d2(d2_1_int),
.d3(d3_1_int),
.dPtr(nxtRdPtr1_int),
.dValid(dValid1_int),
//Inputs
.clk(clk),
.rst_n(rst_n),
.fifo_inData(inData1_int),
.single_push(push1_int),
.single_pop(pop1_int));
`ifdef ASSERT_ON
`rvv_expect(({push1,push0}) inside {2'b11, 2'b01, 2'b00})
else $error("ERROR: Push 2w2r fifo out-of-order: %2b \n", $sampled({push1,push0}));
`rvv_expect(({pop1,pop0}) inside {2'b11, 2'b01, 2'b00})
else $error("ERROR: Pop 2w2r fifo out-of-order: %2b \n", $sampled({pop1,pop0}));
`endif
endmodule