Skip to content

Instantly share code, notes, and snippets.

@pervognsen
Last active June 25, 2017 17:43
Show Gist options
  • Save pervognsen/a3d13d4d30168d0a6bd9c49bfb275120 to your computer and use it in GitHub Desktop.
Save pervognsen/a3d13d4d30168d0a6bd9c49bfb275120 to your computer and use it in GitHub Desktop.
// Single process, registered outputs.
// Version 1 uses a blocking assignment to a flip-flop in a clocked block. This goes against almost all
// best-practices guidelines, even among single-process folks, but it's interesting that it directly expresses
// the intention of the design. Not an endorsement, mind you, but I'm definitely finding that with single-process
// registered-output designs, this kind of thing is tempting...
module srl_fifo#(
parameter DATA_WIDTH = 32,
parameter DEPTH = 16
)(
input clk,
input enq_enable,
input [DATA_WIDTH-1:0] enq_data,
output reg enq_ready,
input deq_enable,
output reg deq_ready,
output reg [DATA_WIDTH-1:0] deq_data
);
localparam ADDR_WIDTH = $clog2(DEPTH);
localparam FULL = DEPTH-1;
localparam EMPTY = -1;
integer i;
reg [DATA_WIDTH-1:0] array[0:DEPTH-1];
reg [ADDR_WIDTH:0] read_pos = EMPTY;
always @(posedge clk) begin
deq_data <= array[read_pos[ADDR_WIDTH-1:0]];
if (deq_enable && deq_ready)
read_pos = read_pos - 1;
if (enq_enable && enq_ready) begin
read_pos = read_pos + 1;
array[0] <= enq_data;
for (i = 1; i < DEPTH; i = i+1)
array[i] <= array[i-1];
end
deq_ready <= read_pos != EMPTY;
enq_ready <= read_pos != FULL;
end
endmodule
// Version 2
module srl_fifo#(
parameter DATA_WIDTH = 32,
parameter DEPTH = 16
)(
input clk,
input enq_enable,
input [DATA_WIDTH-1:0] enq_data,
output reg enq_ready,
input deq_enable,
output reg deq_ready,
output reg [DATA_WIDTH-1:0] deq_data
);
localparam ADDR_WIDTH = $clog2(DEPTH);
localparam FULL = DEPTH-1;
localparam EMPTY = -1;
integer i;
reg [DATA_WIDTH-1:0] array[0:DEPTH-1];
reg [ADDR_WIDTH:0] read_pos = EMPTY;
always @(posedge clk) begin : tick
reg [ADDR_WIDTH:0] next_read_pos;
next_read_pos = read_pos;
deq_data <= array[read_pos[ADDR_WIDTH-1:0]];
if (deq_enable && deq_ready)
next_read_pos = next_read_pos - 1;
if (enq_enable && enq_ready) begin
next_read_pos = next_read_pos + 1;
array[0] <= enq_data;
for (i = 1; i < DEPTH; i = i+1)
array[i] <= array[i-1];
end
deq_ready <= next_read_pos != EMPTY;
enq_ready <= next_read_pos != FULL;
read_pos <= next_read_pos;
end
endmodule
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment