123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190 |
- //
- // dcpktfifo.sv
- //
- // Dual-clock RAM-based FIFO with transaction support (commit/abort)
- //
- // Parametric synchronous RAM module, dual clock,
- // one read and one write port; output data not
- // registered
- module dcqram
- #(
- parameter wbits, // log2(size in words)
- parameter width = 8
- )
- (
- input wclk,
- input wstb,
- input [wbits-1:0] waddr,
- input [width-1:0] wdata,
- input rclk,
- input [wbits-1:0] raddr,
- output [width-1:0] rdata
- );
- `ifdef ALTERA_RESERVED_QIS
- (* ramstyle = "no_rw_check" *)
- `endif
- reg [width-1:0] mem[0:(1 << wbits)-1];
- always @(posedge wclk)
- if (wstb)
- mem[waddr] <= wdata;
- reg [wbits-1:0] raddr_q;
- assign rdata = mem[raddr_q];
- always @(posedge rclk)
- raddr_q <= raddr;
- endmodule // dcqram
- module dcpktfifo
- #(
- parameter wbits = 10,
- parameter width = 8,
- parameter [0:0] wtrans = 1'b1, // Support transactions on write side
- parameter [0:0] rtrans = 1'b1 // Support transactions on read side
- )
- (
- input rst_n,
- input wclk,
- input wstb,
- input wcommit,
- input wabort,
- input [width-1:0] wdata,
- output reg [wbits-1:0] wnfree,
- output reg wempty,
- output reg wfull,
- input rclk,
- input rstb,
- input rcommit,
- input rabort,
- output [width-1:0] rdata,
- output reg [wbits-1:0] rnavail,
- output reg rempty,
- output reg rlast,
- output reg remptyh, // Cleared only on abort/commit
- output reg rlasth, // Cleared only on abort/commit
- output reg rfull
- );
- reg [wbits-1:0] wtaddr; // Transient write address
- reg [wbits-1:0] wcaddr; // Committed write address
- wire [wbits-1:0] w_rcaddr; // rcaddr latched in the wclk domain
- wire wcommit_w = wtrans ? wcommit : 1'b1;
- wire wabort_w = wtrans ? wabort : 1'b0;
- wire [wbits-1:0] wcaddr_w = wtrans ? wcaddr : wtaddr;
- wire wstb_w = wstb & ~wfull;
- wire [wbits-1:0] wnused = wtaddr + wstb_w - w_rcaddr;
- always @(negedge rst_n or posedge wclk)
- if (~rst_n)
- begin
- wtaddr <= 'b0;
- wcaddr <= 'b0;
- wempty <= 1'b1;
- wfull <= 1'b0;
- end
- else
- begin
- if (wabort_w)
- wtaddr <= wcaddr_w;
- else
- begin
- wtaddr <= wtaddr + wstb_w;
- if (wcommit_w)
- wcaddr <= wtaddr + wstb_w;
- end
- wnfree <= ~wnused;
- wempty <= ~|wnused;
- wfull <= &wnused;
- end // else: !if(~rst_n)
- reg [wbits-1:0] rtaddr; // Transient read address
- reg [wbits-1:0] rcaddr; // Committed read address
- wire [wbits-1:0] r_wcaddr; // wcaddr latched in the rclk domain
- wire rcommit_w = rtrans ? rcommit : 1'b1;
- wire rabort_w = rtrans ? rabort : 1'b0;
- wire [wbits-1:0] rcaddr_w = rtrans ? rcaddr : rtaddr;
- wire rstb_w = rstb & ~rempty;
- wire [wbits-1:0] rtaddr_next = (rabort_w & ~rcommit_w)
- ? rcaddr : rtaddr + rstb_w;
- wire [wbits-1:0] rnused_w = r_wcaddr - rtaddr_next;
- always @(negedge rst_n or posedge rclk)
- if (~rst_n)
- begin
- rtaddr <= 'b0;
- rcaddr <= 'b0;
- rnavail <= 'b0;
- rempty <= 1'b1;
- rlast <= 1'b1;
- rfull <= 1'b0;
- end
- else
- begin
- rtaddr <= rtaddr_next;
- if (rcommit_w)
- rcaddr <= rtaddr_next;
- rnavail <= rnused_w;
- rempty <= ~|rnused_w;
- remptyh <= ~|rnused_w | (remptyh & ~(rcommit_w|rabort_w));
- rlast <= ~|rnused_w[wbits-1:1];
- rlasth <= ~|rnused_w[wbits-1:1] | (rlasth & ~(rcommit_w|rabort_w));
- rfull <= &rnused_w;
- end // else: !if(~rst_n)
- // Address pointer synchronizers.
- synchronizer #(.width(wbits))
- syncrcaddr (
- .rst_n (rst_n),
- .clk (wclk),
- .d (rcaddr_w),
- .q (w_rcaddr)
- );
- synchronizer #(.width(wbits))
- syncwcaddr (
- .rst_n (rst_n),
- .clk (rclk),
- .d (wcaddr_w),
- .q (r_wcaddr)
- );
- //
- // Memory array
- //
- dcqram #(.wbits(wbits), .width(width))
- ram (
- .wclk (wclk),
- .wstb (wstb),
- .waddr (wtaddr),
- .wdata (wdata),
- .rclk (rclk),
- .raddr (rtaddr_next),
- .rdata (rdata)
- );
- // For debugging
- (* preserve, noprune *) reg wflag;
- always @(posedge wclk)
- wflag <= (wflag | wstb_w) & ~(wcommit|wabort);
- (* preserve, noprune *) reg rflag;
- always @(posedge rclk)
- rflag <= (rflag | rstb) & ~(rcommit|rabort);
- endmodule // dcpktfifo
|