Skip to content

Commit

Permalink
Merge pull request #174 from RapidSilicon/fifo_improv
Browse files Browse the repository at this point in the history
FIFO Generator updates and improvements
  • Loading branch information
bilalahmed-RS authored Sep 22, 2023
2 parents 022b280 + cbacf45 commit 2b7da41
Show file tree
Hide file tree
Showing 8 changed files with 1,680 additions and 550 deletions.
3 changes: 2 additions & 1 deletion rapidsilicon/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,14 @@ IP Catalog is an IP library for Raptor toolchain.
├── axis_ram_switch
├── axis_switch
├── axis_uart
├── axis_width_converter
├── boot_clock
├── dsp_generator
├── fifo_generator
├── i2c_master
├── i2c_slave
├── jtag_to_axi
├── on_chip_memory
├── pll
├── priority_encoder
├── reset_release
└── vexriscv_cpu
6 changes: 3 additions & 3 deletions rapidsilicon/ip/fifo_generator/v1_0/fifo_generator_gen.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,8 @@ def __init__(self, platform, data_width, synchronous, full_threshold, empty_thre
self.clock_domains.cd_rd = ClockDomain()

SYNCHRONOUS = {
True : "TRUE",
False : "FALSE"
True : "SYNCHRONOUS",
False : "ASYNCHRONOUS"
}

self.submodules.fifo = fifo = FIFO(data_width, SYNCHRONOUS[synchronous], full_threshold, empty_threshold, depth, first_word_fall_through, empty_value, full_value, BRAM)
Expand Down Expand Up @@ -232,4 +232,4 @@ def main():

if __name__ == "__main__":
main()


1,757 changes: 1,353 additions & 404 deletions rapidsilicon/ip/fifo_generator/v1_0/litex_wrapper/fifo_litex_generator.py

Large diffs are not rendered by default.

181 changes: 128 additions & 53 deletions rapidsilicon/ip/fifo_generator/v1_0/sim/FIFO.v
Original file line number Diff line number Diff line change
@@ -1,16 +1,21 @@
// Copyright (C) 2023 RapidSilicon
// --------------------------------------------------------------------------
// ---------------- Copyright (C) 2023 RapidSilicon -------------------------
// --------------------------------------------------------------------------
// ---------------------- FIFO Primitive ------------------------------------
// --------------------------------------------------------------------------

module FIFO #(
// Parameter Definition
parameter DATA_WIDTH = 36,
parameter SYNC_FIFO = "TRUE",
parameter PROG_FULL_THRESH = 12'b100000000000,
parameter PROG_EMPTY_THRESH = 12'b111111111100
parameter DATA_WRITE_WIDTH = 6'd36,
parameter DATA_READ_WIDTH = 6'd36,
parameter SYNC_FIFO = "SYNCHRONOUS",
parameter PROG_FULL_THRESH = 12'b111111111100,
parameter PROG_EMPTY_THRESH = 12'b000000000000
)
(
// Input/Output
input wire [DATA_WIDTH-1:0] WR_DATA,
output wire [DATA_WIDTH-1:0] RD_DATA,
input wire [DATA_WRITE_WIDTH-1:0] WR_DATA,
output wire [DATA_READ_WIDTH-1:0] RD_DATA,
output wire EMPTY,
output wire FULL,
output wire OVERFLOW,
Expand All @@ -27,140 +32,210 @@ module FIFO #(
);

// Signals
wire TEMP_CLK;
wire second_clk;

// Initial Block
initial
begin
if (!(SYNC_FIFO === "TRUE" || SYNC_FIFO === "FALSE")) begin
$error("Incorrect SYNC_FIFO Value: '%s'\nEnter valid SYNC_FIFO value: 'TRUE'/'FALSE'", SYNC_FIFO);
if (!(SYNC_FIFO === "SYNCHRONOUS" || SYNC_FIFO === "ASYNCHRONOUS")) begin
$error("Incorrect SYNC_FIFO Value: '%s'\nEnter valid SYNC_FIFO value: 'SYNCHRONOUS'/'ASYNCHRONOUS'", SYNC_FIFO);
$finish;
end
end

// Common Clock when Synchronous Selected
assign TEMP_CLK = (SYNC_FIFO == "TRUE") ? WRCLK : RDCLK;
assign second_clk = (SYNC_FIFO == "SYNCHRONOUS") ? WRCLK : RDCLK;

// Synchronous/Asynchronous FIFO
localparam SYNC_FIFO1 = (SYNC_FIFO == "TRUE") ? 1'b1 : 1'b0;
localparam sync_fifo = (SYNC_FIFO == "SYNCHRONOUS") ? 1'b1 : 1'b0;

// FIFO
generate
if (DATA_WIDTH == 36)
if (DATA_WRITE_WIDTH == 6'd36 && DATA_READ_WIDTH == 6'd36)
begin
RS_TDP36K #(
.MODE_BITS({SYNC_FIFO1, {4{3'b110}}, 1'b1, 1'b0, 1'b0, 1'b0, PROG_EMPTY_THRESH, PROG_FULL_THRESH, 39'd0, 1'b0})
.MODE_BITS({sync_fifo, {4{3'b110}}, 1'b1, 1'b0, 1'b0, 1'b0, PROG_EMPTY_THRESH, PROG_FULL_THRESH, 39'd0, 1'b0})
)
RS_TDP36K_inst1(
RS_TDP36K_W36_R36 (
.WEN_A1(WREN),
.REN_B1(RDEN),
.CLK_A1(WRCLK),
.CLK_B1(TEMP_CLK),
.CLK_B1(second_clk),
.WDATA_A1(WR_DATA[17:0]),
.WDATA_A2(WR_DATA[35:18]),
.RDATA_A1({EMPTY, ALMOST_EMPTY, PROG_EMPTY, UNDERFLOW, FULL, ALMOST_FULL, PROG_FULL, OVERFLOW}),
.RDATA_B1(RD_DATA[17:0]),
.RDATA_B2(RD_DATA[35:18]),
.FLUSH1(RESET),
.CLK_A2(WRCLK),
.CLK_B2(TEMP_CLK)
.CLK_B2(second_clk)
);
end

else if (DATA_WIDTH == 18)
else if (DATA_WRITE_WIDTH == 5'd18 && DATA_READ_WIDTH == 5'd18)
begin
RS_TDP36K #(
.MODE_BITS({SYNC_FIFO1, {4{3'b010}}, 1'b1, 1'b0, 1'b0, 1'b0, PROG_EMPTY_THRESH, PROG_FULL_THRESH, 39'd0, 1'b1})
// ----------------------------------------------------------Appending 12th bit as dont care bit
.MODE_BITS({sync_fifo, {4{3'b010}}, 1'b1, 1'b0, 1'b0, 1'b0, 1'b0, PROG_EMPTY_THRESH[10:0], 1'b0, PROG_FULL_THRESH[10:0], 39'd0, 1'b1})
)
RS_TDP36K_inst1(
RS_TDP36K_W18_R18 (
.WEN_A1(WREN),
.REN_B1(RDEN),
.CLK_A1(WRCLK),
.CLK_B1(TEMP_CLK),
.CLK_B1(second_clk),
.WDATA_A1(WR_DATA[17:0]),
.RDATA_A1({EMPTY, ALMOST_EMPTY, PROG_EMPTY, UNDERFLOW, FULL, ALMOST_FULL, PROG_FULL, OVERFLOW}),
.RDATA_B1(RD_DATA[17:0]),
.FLUSH1(RESET),
.CLK_A2(WRCLK),
.CLK_B2(TEMP_CLK)
.CLK_B2(second_clk)
);
end

else if (DATA_WIDTH == 9)
else if (DATA_WRITE_WIDTH == 4'd9 && DATA_READ_WIDTH == 4'd9)
begin
wire [17:0] rd_data;
assign RD_DATA = {rd_data[16], rd_data[7:0]};
RS_TDP36K #(
.MODE_BITS({SYNC_FIFO1, {4{3'b100}}, 1'b1, 1'b0, 1'b0, 1'b0, PROG_EMPTY_THRESH, PROG_FULL_THRESH, 39'd0, 1'b1})
// ----------------------------------------------------------Appending 12th bit as dont care bit
.MODE_BITS({sync_fifo, {4{3'b100}}, 1'b1, 1'b0, 1'b0, 1'b0, 1'b0, PROG_EMPTY_THRESH[10:0], 1'b0, PROG_FULL_THRESH[10:0], 39'd0, 1'b1})
)
RS_TDP36K_inst1(
RS_TDP36K_W9_R9 (
.WEN_A1(WREN),
.REN_B1(RDEN),
.CLK_A1(WRCLK),
.CLK_B1(TEMP_CLK),
.WDATA_A1(WR_DATA[8:0]),
.CLK_B1(second_clk),
.WDATA_A1({1'dx, WR_DATA[8], {8{1'dx}}, WR_DATA[7:0]}),
.RDATA_A1({EMPTY, ALMOST_EMPTY, PROG_EMPTY, UNDERFLOW, FULL, ALMOST_FULL, PROG_FULL, OVERFLOW}),
.RDATA_B1(RD_DATA[8:0]),
.RDATA_B1(rd_data),
.FLUSH1(RESET),
.CLK_A2(WRCLK),
.CLK_B2(TEMP_CLK)
.CLK_B2(second_clk)
);
end

else if (DATA_WIDTH == 4)
else if (DATA_WRITE_WIDTH == 6'd36 && DATA_READ_WIDTH == 5'd18)
begin
RS_TDP36K #(
.MODE_BITS({SYNC_FIFO1, {4{3'b001}}, 1'b1, 1'b0, 1'b0, 1'b0, PROG_EMPTY_THRESH, PROG_FULL_THRESH, 39'd0, 1'b1})
.MODE_BITS({sync_fifo, {2{3'b010}}, {2{3'b110}}, 1'b1, 1'b0, 1'b0, 1'b0, PROG_EMPTY_THRESH, PROG_FULL_THRESH, 39'd0, 1'b0})
)
RS_TDP36K_inst1(
RS_TDP36K_W36_R18 (
.WEN_A1(WREN),
.REN_B1(RDEN),
.CLK_A1(WRCLK),
.CLK_B1(TEMP_CLK),
.WDATA_A1(WR_DATA[3:0]),
.CLK_B1(second_clk),
.WDATA_A1(WR_DATA[17:0]),
.WDATA_A2(WR_DATA[35:18]),
.RDATA_A1({EMPTY, ALMOST_EMPTY, PROG_EMPTY, UNDERFLOW, FULL, ALMOST_FULL, PROG_FULL, OVERFLOW}),
.RDATA_B1(RD_DATA[3:0]),
.RDATA_B1(RD_DATA[17:0]),
.FLUSH1(RESET),
.CLK_A2(WRCLK),
.CLK_B2(TEMP_CLK)
.CLK_B2(second_clk)
);
end

else if (DATA_WIDTH == 2)
else if (DATA_WRITE_WIDTH == 6'd36 && DATA_READ_WIDTH == 4'd9)
begin
wire [17:0] rd_data;
assign RD_DATA = {rd_data[16], rd_data[7:0]};
RS_TDP36K #(
.MODE_BITS({SYNC_FIFO1, {4{3'b011}}, 1'b1, 1'b0, 1'b0, 1'b0, PROG_EMPTY_THRESH, PROG_FULL_THRESH, 39'd0, 1'b1})
.MODE_BITS({sync_fifo, {2{3'b100}}, {2{3'b110}}, 1'b1, 1'b0, 1'b0, 1'b0, PROG_EMPTY_THRESH, PROG_FULL_THRESH, 39'd0, 1'b0})
)
RS_TDP36K_inst1(
RS_TDP36K_W36_R9 (
.WEN_A1(WREN),
.REN_B1(RDEN),
.CLK_A1(WRCLK),
.CLK_B1(TEMP_CLK),
.WDATA_A1(WR_DATA[1:0]),
.CLK_B1(second_clk),
.WDATA_A1({WR_DATA[17], WR_DATA[8], WR_DATA[16:9], WR_DATA[7:0]}),
.WDATA_A2({WR_DATA[35], WR_DATA[26], WR_DATA[34:27], WR_DATA[25:18]}),
.RDATA_A1({EMPTY, ALMOST_EMPTY, PROG_EMPTY, UNDERFLOW, FULL, ALMOST_FULL, PROG_FULL, OVERFLOW}),
.RDATA_B1(RD_DATA[1:0]),
.RDATA_B1(rd_data),
.FLUSH1(RESET),
.CLK_A2(WRCLK),
.CLK_B2(TEMP_CLK)
.CLK_B2(second_clk)
);
end

else
else if (DATA_WRITE_WIDTH == 5'd18 && DATA_READ_WIDTH == 4'd9)
begin
wire [17:0] rd_data;
assign RD_DATA = {rd_data[16], rd_data[7:0]};
// ----------------------------------------------------------Appending 12th bit as dont care bit
RS_TDP36K #(
.MODE_BITS({sync_fifo, {2{3'b100}}, {2{3'b010}}, 1'b1, 1'b0, 1'b0, 1'b0, 1'b0, PROG_EMPTY_THRESH[10:0], 1'b0, PROG_FULL_THRESH[10:0], 39'd0, 1'b1})
)
RS_TDP36K_W18_R9 (
.WEN_A1(WREN),
.REN_B1(RDEN),
.CLK_A1(WRCLK),
.CLK_B1(second_clk),
.WDATA_A1({WR_DATA[17], WR_DATA[8], WR_DATA[16:9], WR_DATA[7:0]}),
.RDATA_A1({EMPTY, ALMOST_EMPTY, PROG_EMPTY, UNDERFLOW, FULL, ALMOST_FULL, PROG_FULL, OVERFLOW}),
.RDATA_B1(rd_data),
.FLUSH1(RESET),
.CLK_A2(WRCLK),
.CLK_B2(second_clk)
);
end
else if (DATA_WRITE_WIDTH == 4'd9 && DATA_READ_WIDTH == 5'd18)
begin
wire [17:0] rd_data;
assign RD_DATA = {rd_data[17], rd_data[15:8], rd_data[16], rd_data[7:0]};
RS_TDP36K #(
.MODE_BITS({SYNC_FIFO1, {4{3'b101}}, 1'b1, 1'b0, 1'b0, 1'b0, PROG_EMPTY_THRESH, PROG_FULL_THRESH, 39'd0, 1'b1})
// ----------------------------------------------------------Appending 12th bit as dont care bit
.MODE_BITS({sync_fifo, {2{3'b010}}, {2{3'b100}}, 1'b1, 1'b0, 1'b0, 1'b0, 1'b0, PROG_EMPTY_THRESH[10:0], 1'b0, PROG_FULL_THRESH[10:0], 39'd0, 1'b1})
)
RS_TDP36K_inst1(
RS_TDP36K_W9_R18 (
.WEN_A1(WREN),
.REN_B1(RDEN),
.CLK_A1(WRCLK),
.CLK_B1(TEMP_CLK),
.WDATA_A1(WR_DATA[0:0]),
.CLK_B1(second_clk),
.WDATA_A1({1'hx, WR_DATA[8], {8{1'hx}}, WR_DATA[7:0]}),
.RDATA_A1({EMPTY, ALMOST_EMPTY, PROG_EMPTY, UNDERFLOW, FULL, ALMOST_FULL, PROG_FULL, OVERFLOW}),
.RDATA_B1(RD_DATA[0:0]),
.RDATA_B1(rd_data),
.FLUSH1(RESET),
.CLK_A2(WRCLK),
.CLK_B2(TEMP_CLK)
.CLK_B2(second_clk)
);
end
else if (DATA_WRITE_WIDTH == 5'd18 && DATA_READ_WIDTH == 6'd36)
begin
RS_TDP36K #(
.MODE_BITS({sync_fifo, {2{3'b110}}, {2{3'b010}}, 1'b1, 1'b0, 1'b0, 1'b0, PROG_EMPTY_THRESH, PROG_FULL_THRESH, 39'd0, 1'b0})
)
RS_TDP36K_W18_R36 (
.WEN_A1(WREN),
.REN_B1(RDEN),
.CLK_A1(WRCLK),
.CLK_B1(second_clk),
.WDATA_A1(WR_DATA[17:0]),
.RDATA_A1({EMPTY, ALMOST_EMPTY, PROG_EMPTY, UNDERFLOW, FULL, ALMOST_FULL, PROG_FULL, OVERFLOW}),
.RDATA_B1(RD_DATA[17:0]),
.RDATA_B2(RD_DATA[35:18]),
.FLUSH1(RESET),
.CLK_A2(WRCLK),
.CLK_B2(second_clk)
);
end
else
begin
wire [35:0] rd_data;
assign RD_DATA = {rd_data[35], rd_data[33:26], rd_data[34], rd_data[25:18], rd_data[17], rd_data[15:8] ,rd_data[16], rd_data[7:0]};
RS_TDP36K #(
.MODE_BITS({sync_fifo, {2{3'b110}}, {2{3'b100}}, 1'b1, 1'b0, 1'b0, 1'b0, PROG_EMPTY_THRESH, PROG_FULL_THRESH, 39'd0, 1'b0})
)
RS_TDP36K_W9_R36 (
.WEN_A1(WREN),
.REN_B1(RDEN),
.CLK_A1(WRCLK),
.CLK_B1(second_clk),
.WDATA_A1({1'hx, WR_DATA[8], {8{1'hx}}, WR_DATA[7:0]}),
.RDATA_A1({EMPTY, ALMOST_EMPTY, PROG_EMPTY, UNDERFLOW, FULL, ALMOST_FULL, PROG_FULL, OVERFLOW}),
.RDATA_B1(rd_data[17:0]),
.RDATA_B2(rd_data[35:18]),
.FLUSH1(RESET),
.CLK_A2(WRCLK),
.CLK_B2(second_clk)
);
end

endgenerate

endmodule
63 changes: 0 additions & 63 deletions rapidsilicon/ip/fifo_generator/v1_0/sim/FIFO18K.v

This file was deleted.

Loading

0 comments on commit 2b7da41

Please sign in to comment.