123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182 |
- //
- // 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 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;
- reg [width-1:0] rdata_q;
- assign rdata = rdata_q;
- always @(posedge rclk)
- begin
- raddr_q <= raddr;
- rdata_q <= mem[raddr_q];
- end
- 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 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] rnused = r_wcaddr - (rtaddr + rstb_w);
- 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
- if (rabort_w)
- rtaddr <= rcaddr_w;
- else
- begin
- rtaddr <= rtaddr + rstb_w;
- if (rcommit_w)
- rcaddr <= rtaddr + rstb_w;
- end // else: !if(rabort_w)
- rnavail <= rnused;
- rempty <= ~|rnused;
- rlast <= rnused < 2;
- rfull <= &rnused;
- 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),
- .rdata (rdata)
- );
- endmodule // dcpktfifo
|