initial commit for open source NoC IP
This commit is contained in:
148
rtl/util/freelist.sv
Executable file
148
rtl/util/freelist.sv
Executable file
@@ -0,0 +1,148 @@
|
||||
`ifndef __FREELIST_SV__
|
||||
`define __FREELIST_SV__
|
||||
|
||||
module freelist
|
||||
#(
|
||||
parameter int unsigned ENTRY_COUNT = 4,
|
||||
localparam int unsigned ENTRY_TAG_WIDTH = $clog2(ENTRY_COUNT),
|
||||
localparam int unsigned IS_LOG2 = (2 ** ENTRY_TAG_WIDTH) == ENTRY_COUNT
|
||||
)
|
||||
(
|
||||
// Enqueue
|
||||
input logic enq_vld_i,
|
||||
input logic[ENTRY_TAG_WIDTH-1:0] enq_tag_i,
|
||||
// Dequeue
|
||||
input logic deq_vld_i,
|
||||
output logic[ENTRY_TAG_WIDTH-1:0] deq_tag_o,
|
||||
output logic deq_rdy_o,
|
||||
// Flush
|
||||
input logic flush_i,
|
||||
|
||||
input clk,
|
||||
input rst
|
||||
);
|
||||
|
||||
logic [ENTRY_COUNT-1:0][ENTRY_TAG_WIDTH-1:0] ram_r,ram_n;
|
||||
logic [ENTRY_COUNT-1:0] ram_clk_en;
|
||||
|
||||
logic [ENTRY_TAG_WIDTH-1:0] head_r,head_n;
|
||||
logic head_flag_r,head_flag_n;
|
||||
logic head_clk_en;
|
||||
|
||||
logic [ENTRY_TAG_WIDTH-1:0] tail_r,tail_n;
|
||||
logic tail_flag_r,tail_flag_n;
|
||||
logic tail_clk_en;
|
||||
|
||||
logic enq_fire;
|
||||
logic deq_fire;
|
||||
|
||||
logic full,empty;
|
||||
logic flag_equal,tag_equal;
|
||||
|
||||
assign enq_fire = enq_vld_i;
|
||||
assign deq_fire = deq_rdy_o & deq_vld_i;
|
||||
|
||||
assign flag_equal = tail_flag_r == head_flag_r;
|
||||
assign tag_equal = tail_r == head_r;
|
||||
|
||||
assign full = ~flag_equal & tag_equal;
|
||||
assign empty = flag_equal & tag_equal;
|
||||
|
||||
// Output
|
||||
assign deq_tag_o = ram_r[head_r];
|
||||
|
||||
always_comb begin : ram_update
|
||||
ram_n = ram_r;
|
||||
ram_n[tail_r] = enq_tag_i;
|
||||
if(flush_i) begin
|
||||
for(int i = 0 ; i < ENTRY_COUNT; i++) begin
|
||||
ram_n[i] = i[ENTRY_TAG_WIDTH-1:0];
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
always_comb begin : ram_clk_en_gen
|
||||
for(int i = 0 ; i < ENTRY_COUNT; i++) begin
|
||||
ram_clk_en[i] = (enq_fire & (i == tail_r)) | flush_i;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
always_comb begin : head_update
|
||||
if(IS_LOG2) begin
|
||||
{head_flag_n,head_n} = {head_flag_r,head_r} + 1'b1;
|
||||
end else begin
|
||||
if(head_r == ENTRY_COUNT-1) begin
|
||||
head_n = {ENTRY_COUNT{1'b0}};
|
||||
head_flag_n = ~head_flag_r;
|
||||
end else begin
|
||||
head_n = head_r + 1'b1;
|
||||
head_flag_n = head_flag_r;
|
||||
end
|
||||
end
|
||||
if(flush_i) begin
|
||||
{head_flag_n,head_n} = {head_flag_r,head_r};
|
||||
end
|
||||
end
|
||||
|
||||
assign tail_clk_en = enq_fire | flush_i;
|
||||
assign deq_rdy_o = ~empty;
|
||||
|
||||
always_comb begin : tail_update
|
||||
if(IS_LOG2) begin
|
||||
{tail_flag_n,tail_n} = {tail_flag_r,tail_r} + 1'b1;
|
||||
end else begin
|
||||
if(tail_r == ENTRY_COUNT-1) begin
|
||||
tail_n = {ENTRY_TAG_WIDTH{1'b0}};
|
||||
tail_flag_n = ~tail_flag_r;
|
||||
end else begin
|
||||
tail_n = tail_r + 1'b1;
|
||||
tail_flag_n = tail_flag_r;
|
||||
end
|
||||
end
|
||||
if(flush_i) begin
|
||||
{tail_flag_n,tail_n} = {~head_flag_r,head_r};
|
||||
end
|
||||
end
|
||||
|
||||
assign head_clk_en = deq_fire | flush_i;
|
||||
|
||||
always_ff@(posedge clk) begin : head_dff
|
||||
if(rst) begin
|
||||
{head_flag_r,head_r} <= {(ENTRY_TAG_WIDTH+1){1'b0}};
|
||||
end else begin
|
||||
if(head_clk_en) begin
|
||||
{head_flag_r,head_r} <= {head_flag_n,head_n};
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
always_ff@(posedge clk) begin : tail_dff
|
||||
if(rst) begin
|
||||
{tail_flag_r,tail_r} <= {1'b1,{(ENTRY_TAG_WIDTH){1'b0}}};
|
||||
end else begin
|
||||
if(tail_clk_en) begin
|
||||
{tail_flag_r,tail_r} <= {tail_flag_n,tail_n};
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
always_ff@(posedge clk) begin : ram_dff
|
||||
if(rst) begin
|
||||
for(int i = 0 ; i < ENTRY_COUNT; i++) begin
|
||||
ram_r[i] <= i[ENTRY_TAG_WIDTH-1:0];
|
||||
end
|
||||
end else begin
|
||||
for(int i = 0 ; i < ENTRY_COUNT; i++) begin
|
||||
if(ram_clk_en[i]) begin
|
||||
ram_r[i] <= ram_n[i];
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
endmodule : freelist
|
||||
|
||||
`endif
|
||||
Reference in New Issue
Block a user