mirror of
https://github.com/openhwgroup/cvw
synced 2025-02-11 06:05:49 +00:00
uncore: Add fifo
This commit is contained in:
parent
b05893647f
commit
dec30b4d99
43
src/uncore/fifo/fifo.sv
Normal file
43
src/uncore/fifo/fifo.sv
Normal file
@ -0,0 +1,43 @@
|
||||
module fifo #(parameter DSIZE = 8,
|
||||
parameter ASIZE = 4)
|
||||
(rdata, wfull, rempty, wdata,
|
||||
winc, wclk, wrst_n, rinc, rclk, rrst_n);
|
||||
|
||||
input logic [DSIZE-1:0] wdata;
|
||||
input logic winc;
|
||||
input logic wclk;
|
||||
input logic wrst_n;
|
||||
input logic rinc;
|
||||
input logic rclk;
|
||||
input logic rrst_n;
|
||||
|
||||
output logic [DSIZE-1:0] rdata;
|
||||
output logic wfull;
|
||||
output logic rempty;
|
||||
|
||||
logic [ASIZE-1:0] waddr, raddr;
|
||||
logic [ASIZE:0] wptr, rptr, wq2_rptr, rq2_wptr;
|
||||
|
||||
sync_r2w sync_r2w (.wq2_rptr(wq2_rptr), .rptr(rptr),
|
||||
.wclk(wclk), .wrst_n(wrst_n));
|
||||
sync_w2r sync_w2r (.rq2_wptr(rq2_wptr), .wptr(wptr),
|
||||
.rclk(rclk), .rrst_n(rrst_n));
|
||||
|
||||
fifomem #(DSIZE, ASIZE) fifomem (.rdata(rdata), .wdata(wdata),
|
||||
.waddr(waddr), .raddr(raddr),
|
||||
.wclken(winc), .wfull(wfull),
|
||||
.wclk(wclk));
|
||||
rptr_empty #(ASIZE) rptr_empty (.rempty(rempty), .raddr(raddr),
|
||||
.rptr(rptr), .rq2_wptr(rq2_wptr),
|
||||
.rinc(rinc), .rclk(rclk),
|
||||
.rrst_n(rrst_n));
|
||||
wptr_full #(ASIZE) wptr_full (.wfull(wfull), .waddr(waddr),
|
||||
.wptr(wptr), .wq2_rptr(wq2_rptr),
|
||||
.winc(winc), .wclk(wclk),
|
||||
.wrst_n(wrst_n));
|
||||
|
||||
endmodule // fifo1
|
||||
|
||||
|
||||
|
||||
|
24
src/uncore/fifo/fifomem.sv
Normal file
24
src/uncore/fifo/fifomem.sv
Normal file
@ -0,0 +1,24 @@
|
||||
|
||||
// DATASIZE = Memory data word width
|
||||
// ADDRSIZE = Number of mem address bits
|
||||
module fifomem #(parameter DATASIZE = 8,
|
||||
parameter ADDRSIZE = 4)
|
||||
(rdata, wdata, waddr, raddr, wclken, wfull, wclk);
|
||||
|
||||
input logic [DATASIZE-1:0] wdata;
|
||||
input logic [ADDRSIZE-1:0] waddr;
|
||||
input logic [ADDRSIZE-1:0] raddr;
|
||||
input logic wclken;
|
||||
input logic wfull;
|
||||
input logic wclk;
|
||||
output logic [DATASIZE-1:0] rdata;
|
||||
|
||||
// RTL Verilog memory model
|
||||
localparam DEPTH = 1 << ADDRSIZE;
|
||||
logic [DATASIZE-1:0] mem [0:DEPTH-1];
|
||||
|
||||
assign rdata = mem[raddr];
|
||||
always @(posedge wclk)
|
||||
if (wclken && !wfull) mem[waddr] <= wdata;
|
||||
|
||||
endmodule // fifomem
|
37
src/uncore/fifo/rptr_empty.sv
Normal file
37
src/uncore/fifo/rptr_empty.sv
Normal file
@ -0,0 +1,37 @@
|
||||
module rptr_empty #(parameter ADDRSIZE = 4)
|
||||
(rempty, raddr, rptr, rq2_wptr, rinc, rclk, rrst_n);
|
||||
|
||||
input logic [ADDRSIZE:0] rq2_wptr;
|
||||
input logic rinc;
|
||||
input logic rclk;
|
||||
input logic rrst_n;
|
||||
output logic rempty;
|
||||
output logic [ADDRSIZE-1:0] raddr;
|
||||
output logic [ADDRSIZE :0] rptr;
|
||||
|
||||
logic [ADDRSIZE:0] rbin;
|
||||
logic [ADDRSIZE:0] rgraynext;
|
||||
logic [ADDRSIZE:0] rbinnext;
|
||||
|
||||
//-------------------
|
||||
// GRAYSTYLE2 pointer
|
||||
//-------------------
|
||||
always @(posedge rclk or negedge rrst_n)
|
||||
if (!rrst_n) {rbin, rptr} <= 0;
|
||||
else {rbin, rptr} <= {rbinnext, rgraynext};
|
||||
|
||||
// Memory read-address pointer (okay to use binary to address memory)
|
||||
assign raddr = rbin[ADDRSIZE-1:0];
|
||||
assign rbinnext = rbin + (rinc & ~rempty);
|
||||
assign rgraynext = (rbinnext>>1) ^ rbinnext;
|
||||
|
||||
//---------------------------------------------------------------
|
||||
// FIFO empty when the next rptr == synchronized wptr or on reset
|
||||
//---------------------------------------------------------------
|
||||
assign rempty_val = (rgraynext == rq2_wptr);
|
||||
|
||||
always @(posedge rclk or negedge rrst_n)
|
||||
if (!rrst_n) rempty <= 1'b1;
|
||||
else rempty <= rempty_val;
|
||||
|
||||
endmodule // rptr_empty
|
16
src/uncore/fifo/sync_r2w.sv
Normal file
16
src/uncore/fifo/sync_r2w.sv
Normal file
@ -0,0 +1,16 @@
|
||||
module sync_r2w #(parameter ADDRSIZE = 4)
|
||||
(wq2_rptr, rptr, wclk, wrst_n);
|
||||
|
||||
input logic [ADDRSIZE:0] rptr;
|
||||
input logic wclk;
|
||||
input logic wrst_n;
|
||||
|
||||
output logic [ADDRSIZE:0] wq2_rptr;
|
||||
|
||||
logic [ADDRSIZE:0] wq1_rptr;
|
||||
|
||||
always @(posedge wclk or negedge wrst_n)
|
||||
if (!wrst_n) {wq2_rptr,wq1_rptr} <= 0;
|
||||
else {wq2_rptr,wq1_rptr} <= {wq1_rptr,rptr};
|
||||
|
||||
endmodule // sync_r2w
|
16
src/uncore/fifo/sync_w2r.sv
Normal file
16
src/uncore/fifo/sync_w2r.sv
Normal file
@ -0,0 +1,16 @@
|
||||
module sync_w2r #(parameter ADDRSIZE = 4)
|
||||
(rq2_wptr, wptr, rclk, rrst_n);
|
||||
|
||||
input logic [ADDRSIZE:0] wptr;
|
||||
input logic rclk;
|
||||
input logic rrst_n;
|
||||
|
||||
output logic [ADDRSIZE:0] rq2_wptr;
|
||||
|
||||
logic [ADDRSIZE:0] rq1_wptr;
|
||||
|
||||
always @(posedge rclk or negedge rrst_n)
|
||||
if (!rrst_n) {rq2_wptr,rq1_wptr} <= 0;
|
||||
else {rq2_wptr,rq1_wptr} <= {rq1_wptr,wptr};
|
||||
|
||||
endmodule // sync_w2r
|
44
src/uncore/fifo/wptr_full.sv
Normal file
44
src/uncore/fifo/wptr_full.sv
Normal file
@ -0,0 +1,44 @@
|
||||
module wptr_full #(parameter ADDRSIZE = 4)
|
||||
(wfull, waddr, wptr, wq2_rptr, winc, wclk, wrst_n);
|
||||
|
||||
input logic [ADDRSIZE :0] wq2_rptr;
|
||||
input logic winc;
|
||||
input logic wclk;
|
||||
input logic wrst_n;
|
||||
|
||||
output logic wfull;
|
||||
output logic [ADDRSIZE-1:0] waddr;
|
||||
output logic [ADDRSIZE:0] wptr;
|
||||
|
||||
logic [ADDRSIZE:0] wbin;
|
||||
logic [ADDRSIZE:0] wgraynext;
|
||||
logic [ADDRSIZE:0] wbinnext;
|
||||
|
||||
// GRAYSTYLE2 pointer
|
||||
always @(posedge wclk or negedge wrst_n)
|
||||
if (!wrst_n) {wbin, wptr} <= 0;
|
||||
else {wbin, wptr} <= {wbinnext, wgraynext};
|
||||
|
||||
// Memory write-address pointer (okay to use binary to address memory)
|
||||
assign waddr = wbin[ADDRSIZE-1:0];
|
||||
assign wbinnext = wbin + (winc & ~wfull);
|
||||
assign wgraynext = (wbinnext>>1) ^ wbinnext;
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// Simplified version of the three necessary full-tests:
|
||||
// assign wfull_val=((wgnext[ADDRSIZE] !=wq2_rptr[ADDRSIZE] ) &&
|
||||
// (wgnext[ADDRSIZE-1] !=wq2_rptr[ADDRSIZE-1]) &&
|
||||
// (wgnext[ADDRSIZE-2:0]==wq2_rptr[ADDRSIZE-2:0]));
|
||||
//------------------------------------------------------------------
|
||||
assign wfull_val = (wgraynext=={~wq2_rptr[ADDRSIZE:ADDRSIZE-1],
|
||||
wq2_rptr[ADDRSIZE-2:0]});
|
||||
|
||||
always @(posedge wclk or negedge wrst_n)
|
||||
if (!wrst_n)
|
||||
wfull <= 1'b0;
|
||||
else
|
||||
wfull <= wfull_val;
|
||||
|
||||
endmodule // wptr_full
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user