diff --git a/rapidsilicon/README.md b/rapidsilicon/README.md index 21eb209d..98c1f00a 100644 --- a/rapidsilicon/README.md +++ b/rapidsilicon/README.md @@ -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 diff --git a/rapidsilicon/ip/fifo_generator/v1_0/fifo_generator_gen.py b/rapidsilicon/ip/fifo_generator/v1_0/fifo_generator_gen.py index 8104f761..5a8ea80c 100755 --- a/rapidsilicon/ip/fifo_generator/v1_0/fifo_generator_gen.py +++ b/rapidsilicon/ip/fifo_generator/v1_0/fifo_generator_gen.py @@ -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) @@ -232,4 +232,4 @@ def main(): if __name__ == "__main__": main() - + \ No newline at end of file diff --git a/rapidsilicon/ip/fifo_generator/v1_0/litex_wrapper/fifo_litex_generator.py b/rapidsilicon/ip/fifo_generator/v1_0/litex_wrapper/fifo_litex_generator.py index 08964f74..b6ab28d8 100644 --- a/rapidsilicon/ip/fifo_generator/v1_0/litex_wrapper/fifo_litex_generator.py +++ b/rapidsilicon/ip/fifo_generator/v1_0/litex_wrapper/fifo_litex_generator.py @@ -6,7 +6,6 @@ # SPDX-License-Identifier: MIT # -import os import datetime import logging import math @@ -15,13 +14,15 @@ from litex.soc.interconnect.axi import * +logging.basicConfig(level=logging.INFO) + # logging.basicConfig(level=logging.INFO) logging.basicConfig(filename="IP.log",filemode="w", level=logging.INFO, format='%(levelname)s: %(message)s\n') timestamp = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S') logging.info(f'Log started at {timestamp}') -def divide_n_bit_number(number): +def divide_n_bit_number(number, depth): # Convert the number to a binary string binary_string = '0' * number buses = [] @@ -29,41 +30,66 @@ def divide_n_bit_number(number): for i in range(0, len(binary_string), 36): bus = binary_string[i:i+36] buses.append(bus) + if (len(buses[-1]) < 36 and len(buses[-1]) > 18 and depth > 1024): + for i in range(len(binary_string) - len(buses[-1]), len(binary_string), 18): + bus = binary_string[i:i+18] + buses.append(bus) + buses.pop(-3) return buses + # FIFO Generator --------------------------------------------------------------------------------------- class FIFO(Module): def __init__(self, data_width, synchronous, full_threshold, empty_threshold, depth, first_word_fall_through, empty_value, full_value, BRAM): + SYNCHRONOUS = { + "SYNCHRONOUS" : True, + "ASYNCHRONOUS" : False + } self.logger = logging.getLogger("FIFO") self.logger.propagate = True - self.logger.info(f"=================== PARAMETERS ====================") # Data Width self.logger.info(f"DATA_WIDTH : {data_width}") - - # User Width - self.logger.info(f"SYNCHRONOUS : {synchronous}") - - self.logger.info(f"FULL THRESHOLD : {full_value}") - - # Destination Width - - self.logger.info(f"EMPTY THRESHOLD : {empty_value}") - + # Synchronous / Asynchronous + self.logger.info(f"SYNCHRONOUS : {SYNCHRONOUS[synchronous]}") + # Full and Empty Thresholds + self.logger.info(f"FULL THRESHOLD : {full_value}") + self.logger.info(f"EMPTY THRESHOLD : {empty_value}") + # Depth + self.logger.info(f"DEPTH : {depth}") self.logger.info(f"===================================================") - - SYNCHRONOUS = { - "TRUE" : True, - "FALSE" : False - } - buses = divide_n_bit_number(data_width) + buses = divide_n_bit_number(data_width, depth) size_bram = 36864 - maximum = max(buses, key=len) - memory = math.ceil(size_bram / len(maximum)) - + data_36 = sum(1 for item in buses if ((len(item) >= 18 and depth < 1024) or (len(item) == 36 and depth >= 1024))) + total_mem = math.ceil((data_width * depth) / size_bram) + remaining_memory = 0 + depth_mem = 18432 + num_9K = 0 + num_18K = 0 + num_36K = 0 + while remaining_memory < data_width * depth: + for i, bus in enumerate(buses): + # if (remaining_memory < data_width * depth): + if (len(bus) <= 9): + data = 9 + memory = 1024 + remaining_memory = remaining_memory + (len(bus) * memory) + num_9K = num_9K + 1 + elif (len(bus) <= 18): + data = 18 + memory = 1024 + num_18K = num_18K + 1 + remaining_memory = remaining_memory + (len(bus) * memory) + elif (len(bus) <= 36): + data = 36 + memory = 1024 + num_36K = num_36K + 1 + remaining_memory = remaining_memory + (len(bus) * memory) + total_mem = num_36K + math.ceil(num_18K/2) + math.ceil(num_9K/4) + memory = 1024 instances = math.ceil(depth / memory) if(SYNCHRONOUS[synchronous]): self.counter = Signal(math.ceil(math.log2(depth)) + 1, reset=0) @@ -109,24 +135,34 @@ def __init__(self, data_width, synchronous, full_threshold, empty_threshold, dep self.prog_empty = Signal() self.almost_full = Signal() self.almost_empty = Signal() - + # Using Block RAM if (BRAM): - self.rden_int = Array(Signal() for _ in range(instances)) - self.wren_int = Array(Signal() for _ in range(instances)) - self.empty_int = Array(Signal() for _ in range(instances)) - self.full_int = Array(Signal() for _ in range(instances)) - self.almost_empty_int = Array(Signal() for _ in range(instances)) - self.almost_full_int = Array(Signal() for _ in range(instances)) - self.prog_full_int = Array(Signal() for _ in range(instances)) - self.prog_empty_int = Array(Signal() for _ in range(instances)) - self.dout_int = Array(Signal() for _ in range(instances)) - self.underflow_int = Array(Signal() for _ in range(instances)) - self.overflow_int = Array(Signal() for _ in range(instances)) - - for k in range(instances): - j = 0 - + self.rden_int = Array(Signal() for _ in range(total_mem * 2)) + self.wren_int = Array(Signal() for _ in range(total_mem * 2)) + self.empty_int = Array(Signal() for _ in range(total_mem * 2)) + self.full_int = Array(Signal() for _ in range(total_mem * 2)) + self.almost_empty_int = Array(Signal() for _ in range(total_mem * 2)) + self.almost_full_int = Array(Signal() for _ in range(total_mem * 2)) + self.prog_full_int = Array(Signal() for _ in range(total_mem * 2)) + self.prog_empty_int = Array(Signal() for _ in range(total_mem * 2)) + self.dout_int = Array(Signal() for _ in range(total_mem * 2)) + self.underflow_int = Array(Signal() for _ in range(total_mem * 2)) + self.overflow_int = Array(Signal() for _ in range(total_mem * 2)) + count = 0 + mem = 0 + k36_flag = 0 + index_array = [] + k_loop = 0 + count18K = 0 + old_count18K = 0 + old_count9K = 0 + two_block = 0 + count9K = 0 + count_36K = 0 + k9_flag = 0 + k18_flag = 0 + for k in range(total_mem * 2): self.rden_int[k] = Signal(name=f"rden_int_{k}") self.wren_int[k] = Signal(name=f"wren_int_{k}") self.empty_int[k] = Signal(name=f"empty_int_{k}") @@ -135,417 +171,1330 @@ def __init__(self, data_width, synchronous, full_threshold, empty_threshold, dep self.prog_empty_int[k] = Signal(name=f"prog_empty_int_{k}") self.almost_empty_int[k] = Signal(name=f"almost_empty_int_{k}") self.almost_full_int[k] = Signal(name=f"almost_full_int_{k}") - self.dout_int[k] = Signal(data_width, name=f"dout_int_{k}") + self.dout_int[k] = Signal(36, name=f"dout_int_{k}") self.underflow_int[k] = Signal(name=f"underflow_int_{k}") self.overflow_int[k] = Signal(name=f"overflow_int_{k}") + for k in range(total_mem): + j = 0 for i, bus in enumerate(buses): - if (len(bus) <= 2): - data = len(bus) - elif (len(bus) <= 4): - data = 4 - elif (len(bus) <= 9): + if (len(bus) <= 9): data = 9 + memory = 2048 + k9_flag = 1 elif (len(bus) <= 18): data = 18 + memory = 1024 + k18_flag = 1 elif (len(bus) <= 36): data = 36 - + memory = 1024 + k36_flag = 1 + if (data <= 18): - instance = "FIFO18K" + instance = "FIFO18KX2" else: instance = "FIFO36K" # Module Instance. # ---------------- if(SYNCHRONOUS[synchronous]): - if (instances == 1): - self.specials += Instance(instance, - # Parameters. - # ----------- - # Global. - p_DATA_WIDTH = C(data), - p_SYNC_FIFO = synchronous, - p_PROG_FULL_THRESH = C(depth - full_value, 12), - p_PROG_EMPTY_THRESH = C(empty_value, 12), + if (total_mem == 1): + if (instance == "FIFO36K"): + self.specials += Instance(instance, + # Parameters. + # ----------- + # Global. + p_DATA_WRITE_WIDTH = C(data), + p_DATA_READ_WIDTH = C(data), + p_FIFO_TYPE = synchronous, + p_PROG_FULL_THRESH = C(depth - full_value, 12), + p_PROG_EMPTY_THRESH = C(empty_value, 12), - # Clk / Rst. - # ---------- - i_RDCLK = ClockSignal(), - i_WRCLK = ClockSignal(), - i_RESET = ResetSignal(), + # Clk / Rst. + # ---------- + i_RD_CLK = ClockSignal(), + i_WR_CLK = ClockSignal(), + i_RESET = ResetSignal(), - # AXI Input - # ----------------- - i_WR_DATA = self.din[j:data + j], - i_RDEN = self.rden_int[k], - i_WREN = self.wren_int[k], + # Input + # ----------------- + i_WR_DATA = self.din[j:data + j], + i_RD_EN = self.rden_int[count], + i_WR_EN = self.wren_int[count], - # AXI Output - o_RD_DATA = self.dout[j:data + j], - o_EMPTY = self.empty[k], - o_FULL = self.full[k], - o_UNDERFLOW = self.underflow_int[k], - o_OVERFLOW = self.overflow_int[k], - o_ALMOST_EMPTY = self.almost_empty[k], - o_ALMOST_FULL = self.almost_full[k], - o_PROG_FULL = self.prog_full[k], - o_PROG_EMPTY = self.prog_empty[k] - ) + # Output + o_RD_DATA = self.dout_int[count][j:data + j], + o_EMPTY = self.empty_int[count], + o_FULL = self.full_int[count], + o_UNDERFLOW = self.underflow_int[count], + o_OVERFLOW = self.overflow_int[count], + o_ALMOST_EMPTY = self.almost_empty[count], + o_ALMOST_FULL = self.almost_full[count], + o_PROG_FULL = self.prog_full[count], + o_PROG_EMPTY = self.prog_empty[count] + ) + count = count + 1 + else: + self.specials += Instance(instance, + # Parameters. + # ----------- + # Global. + p_DATA_WRITE_WIDTH1 = C(data), + p_DATA_READ_WIDTH1 = C(data), + p_FIFO_TYPE1 = synchronous, + p_PROG_FULL_THRESH1 = C(depth - full_value, 12), + p_PROG_EMPTY_THRESH1 = C(empty_value, 12), + p_DATA_WRITE_WIDTH2 = C(data), + p_DATA_READ_WIDTH2 = C(data), + p_FIFO_TYPE2 = synchronous, + p_PROG_FULL_THRESH2 = C(depth - full_value, 11), + p_PROG_EMPTY_THRESH2 = C(empty_value, 11), + # Clk / Rst. + # ---------- + i_RD_CLK1 = ClockSignal(), + i_WR_CLK1 = ClockSignal(), + i_RESET1 = ResetSignal(), + # Input + # ----------------- # ----------------- + i_WR_DATA1 = self.din[j:data + j], + i_RD_EN1 = self.rden_int[count], + i_WR_EN1 = self.wren_int[count], + # Output + o_RD_DATA1 = self.dout_int[count][j:data + j], + o_EMPTY1 = self.empty_int[count], + o_FULL1 = self.full_int[count], + o_UNDERFLOW1 = self.underflow_int[count], + o_OVERFLOW1 = self.overflow_int[count], + o_ALMOST_EMPTY1 = self.almost_empty_int[count], + o_ALMOST_FULL1 = self.almost_full_int[count], + o_PROG_FULL1 = self.prog_full_int[count], + o_PROG_EMPTY1 = self.prog_empty_int[count], + # Clk / Rst. + # ---------- + i_RD_CLK2 = ClockSignal(), + i_WR_CLK2 = ClockSignal(), + i_RESET2 = ResetSignal(), + # Input + # ----------------- + i_WR_DATA2 = self.din[j:data + j], + i_RD_EN2 = self.rden_int[count + 1], + i_WR_EN2 = self.wren_int[count + 1], + # Output + o_RD_DATA2 = self.dout_int[count + 1][j:data + j], + o_EMPTY2 = self.empty_int[count + 1], + o_FULL2 = self.full_int[count + 1], + o_UNDERFLOW2 = self.underflow_int[count + 1], + o_OVERFLOW2 = self.overflow_int[count + 1], + o_ALMOST_EMPTY2 = self.almost_empty_int[count + 1], + o_ALMOST_FULL2 = self.almost_full_int[count + 1], + o_PROG_FULL2 = self.prog_full_int[count + 1], + o_PROG_EMPTY2 = self.prog_empty_int[count + 1] + ) + for l in range (2): + if (count + l < num_36K + (num_18K/2)*2 + (num_9K/4)*2): + self.comb += [ + If(self.wren, + If(~self.overflow, + If(~self.full_int[count + l], + If(self.wrt_ptr <= (count + l + 1)*memory, + If(self.wrt_ptr > (count + l)*memory, + self.wren_int[count + l].eq(1) + ) + ) + ) + ) + ) + ] + self.comb += [ + If(self.rden, + If(~self.underflow, + If(self.rd_ptr <= (count + l + 1)*memory, + If(self.rd_ptr > (count + l)*memory, + self.rden_int[count + l].eq(1), + self.dout[j:data + j].eq(self.dout_int[count + l] + ) + ) + ) + ) + ) + ] + if (first_word_fall_through): + self.comb += [ + If(~self.rden, + If(~self.underflow, + If(self.rd_ptr <= (count + l + 1)*memory, + If(self.rd_ptr >= (count + l)*memory, + self.dout[j:data + j].eq(self.dout_int[count + l] + ) + ) + ) + ) + ) + ] + count = count + 2 else: - self.specials += Instance(instance, - # Parameters. - # ----------- - # Global. - p_DATA_WIDTH = C(data), - p_SYNC_FIFO = synchronous, - p_PROG_FULL_THRESH = C(4095, 12), - p_PROG_EMPTY_THRESH = C(0, 12), + if (instance == "FIFO36K" and count_36K < num_36K): + self.specials += Instance(instance, + # Parameters. + # ----------- + # Global. + p_DATA_WRITE_WIDTH = C(data), + p_DATA_READ_WIDTH = C(data), + p_FIFO_TYPE = synchronous, + p_PROG_FULL_THRESH = C(4095, 12), + p_PROG_EMPTY_THRESH = C(0, 12), - # Clk / Rst. - # ---------- - i_RDCLK = ClockSignal(), - i_WRCLK = ClockSignal(), - i_RESET = ResetSignal(), + # Clk / Rst. + # ---------- + i_RD_CLK = ClockSignal(), + i_WR_CLK = ClockSignal(), + i_RESET = ResetSignal(), - # AXI Input - # ----------------- - i_WR_DATA = self.din[j:data + j], - i_RDEN = self.rden_int[k], - i_WREN = self.wren_int[k], + # Input + # ----------------- + i_WR_DATA = self.din[j:data + j], + i_RD_EN = self.rden_int[count], + i_WR_EN = self.wren_int[count], - # AXI Output - o_RD_DATA = self.dout_int[k][j:data + j], - o_EMPTY = self.empty_int[k], - o_FULL = self.full_int[k], - o_UNDERFLOW = self.underflow_int[k], - o_OVERFLOW = self.overflow_int[k], - o_ALMOST_EMPTY = self.almost_empty_int[k], - o_ALMOST_FULL = self.almost_full_int[k], - o_PROG_FULL = self.prog_full_int[k], - o_PROG_EMPTY = self.prog_empty_int[k] - ) + # Output + o_RD_DATA = self.dout_int[count], + o_EMPTY = self.empty_int[count], + o_FULL = self.full_int[count], + o_UNDERFLOW = self.underflow_int[count], + o_OVERFLOW = self.overflow_int[count], + o_ALMOST_EMPTY = self.almost_empty_int[count], + o_ALMOST_FULL = self.almost_full_int[count], + o_PROG_FULL = self.prog_full_int[count], + o_PROG_EMPTY = self.prog_empty_int[count] + ) + count_36K = count_36K + 1 + count = count + 1 + mem = mem + 1 + elif(instance == "FIFO18KX2" and mem < total_mem and ((((k % (instances/(instances/2)) == 1 and data == 18 and count18K < (num_18K/2)) or (k + 2 == total_mem) or (k % (instances/(instances/4)) == 1 and data == 9 and count9K < (num_9K/4)) or (not k36_flag and data == 9 and count9K < num_9K/4) or (not k36_flag and data == 18 and count18K < num_18K/2))))): + index_array.append(count) + index_array.append(count + 1) + self.specials += Instance(instance, + # Parameters. + # ----------- + # Global. + p_DATA_WRITE_WIDTH1 = C(data), + p_DATA_READ_WIDTH1 = C(data), + p_FIFO_TYPE1 = synchronous, + p_PROG_FULL_THRESH1 = C(full_value, 12), + p_PROG_EMPTY_THRESH1 = C(empty_value, 12), + p_DATA_WRITE_WIDTH2 = C(data), + p_DATA_READ_WIDTH2 = C(data), + p_FIFO_TYPE2 = synchronous, + p_PROG_FULL_THRESH2 = C(full_value, 11), + p_PROG_EMPTY_THRESH2 = C(empty_value, 11), + # Clk / Rst. + # ---------- + i_RD_CLK1 = ClockSignal(), + i_WR_CLK1 = ClockSignal(), + i_RESET1 = ResetSignal(), + # Input + # ----------------- + i_WR_DATA1 = self.din[j:data + j], + i_RD_EN1 = self.rden_int[count], + i_WR_EN1 = self.wren_int[count], + # Output + # ----------------- + o_RD_DATA1 = self.dout_int[count], + o_EMPTY1 = self.empty_int[count], + o_FULL1 = self.full_int[count], + o_UNDERFLOW1 = self.underflow_int[count], + o_OVERFLOW1 = self.overflow_int[count], + o_ALMOST_EMPTY1 = self.almost_empty_int[count], + o_ALMOST_FULL1 = self.almost_full_int[count], + o_PROG_FULL1 = self.prog_full_int[count], + o_PROG_EMPTY1 = self.prog_empty_int[count], + # Clk / Rst. + # ---------- + i_RD_CLK2 = ClockSignal(), + i_WR_CLK2 = ClockSignal(), + i_RESET2 = ResetSignal(), + # Input + # ----------------- + i_WR_DATA2 = self.din[j:data + j], + i_RD_EN2 = self.rden_int[count + 1], + i_WR_EN2 = self.wren_int[count + 1], + # Output + # ----------------- + o_RD_DATA2 = self.dout_int[count + 1], + o_EMPTY2 = self.empty_int[count + 1], + o_FULL2 = self.full_int[count + 1], + o_UNDERFLOW2 = self.underflow_int[count + 1], + o_OVERFLOW2 = self.overflow_int[count + 1], + o_ALMOST_EMPTY2 = self.almost_empty_int[count + 1], + o_ALMOST_FULL2 = self.almost_full_int[count + 1], + o_PROG_FULL2 = self.prog_full_int[count + 1], + o_PROG_EMPTY2 = self.prog_empty_int[count + 1] + ) + for l in range (2): + if (count + l < num_36K + (num_18K/2)*2 + (num_9K/4)*2): + if (data == 9): + if (k18_flag): + self.comb += [ + If(self.wren, + If(~self.overflow, + If(~self.full_int[count + l], + If(self.wrt_ptr <= (k_loop + 1 + l + two_block )*memory, + If(self.wrt_ptr > (k_loop + l + two_block)*memory, + self.wren_int[count + l].eq(1) + ) + ) + ) + ) + ) + ] + else: + self.comb += [ + If(self.wren, + If(~self.overflow, + If(~self.full_int[count + l], + If(self.wrt_ptr <= (k_loop + 1 + l + two_block + count9K)*memory, + If(self.wrt_ptr > (k_loop + l + two_block + count9K)*memory, + self.wren_int[count + l].eq(1) + ) + ) + ) + ) + ) + ] + else: + if (k9_flag): + self.comb += [ + If(self.wren, + If(~self.overflow, + If(~self.full_int[count + l], + If(self.wrt_ptr <= (k_loop + 1 + l + count18K + count9K)*memory, + If(self.wrt_ptr > (k_loop + l + count18K + count9K)*memory, + self.wren_int[count + l].eq(1) + ) + ) + ) + ) + ) + ] + else: + self.comb += [ + If(self.wren, + If(~self.overflow, + If(~self.full_int[count + l], + If(self.wrt_ptr <= (k_loop + 1 + l + count18K)*memory, + If(self.wrt_ptr > (k_loop + l + count18K)*memory, + self.wren_int[count + l].eq(1) + ) + ) + ) + ) + ) + ] + if (data == 9): + if (k18_flag): + self.comb += [ + If(self.rden, + If(~self.underflow, + If(self.rd_ptr <= (k_loop + 1 + l + two_block)*memory, + If(self.rd_ptr > (k_loop + l + two_block)*memory, + self.rden_int[count + l].eq(1), + self.dout[j:data + j].eq(self.dout_int[count + l] + ) + ) + ) + ) + ) + ] + else: + self.comb += [ + If(self.rden, + If(~self.underflow, + If(self.rd_ptr <= (k_loop + 1 + l + two_block + count9K)*memory, + If(self.rd_ptr > (k_loop + l + two_block + count9K)*memory, + self.rden_int[count + l].eq(1), + self.dout[j:data + j].eq(self.dout_int[count + l] + ) + ) + ) + ) + ) + ] + else: + if (k9_flag): + self.comb += [ + If(self.rden, + If(~self.underflow, + If(self.rd_ptr <= (k_loop + 1 + l + count18K + count9K)*memory, + If(self.rd_ptr > (k_loop + l + count18K + count9K)*memory, + self.rden_int[count + l].eq(1), + self.dout[j:data + j].eq(self.dout_int[count + l] + ) + ) + ) + ) + ) + ] + else: + self.comb += [ + If(self.rden, + If(~self.underflow, + If(self.rd_ptr <= (k_loop + 1 + l + count18K)*memory, + If(self.rd_ptr > (k_loop + l + count18K)*memory, + self.rden_int[count + l].eq(1), + self.dout[j:data + j].eq(self.dout_int[count + l] + ) + ) + ) + ) + ) + ] + if (first_word_fall_through): + if (data == 9): + if (k18_flag): + self.comb += [ + If(~self.rden, + If(~self.underflow, + If(self.rd_ptr <= (k_loop + 1 + l + two_block)*memory, + If(self.rd_ptr >= (k_loop + l + two_block)*memory, + self.dout[j:data + j].eq(self.dout_int[count + l] + ) + ) + ) + ) + ) + ] + else: + self.comb += [ + If(~self.rden, + If(~self.underflow, + If(self.rd_ptr <= (k_loop + 1 + l + two_block + count9K)*memory, + If(self.rd_ptr >= (k_loop + l + two_block + count9K)*memory, + self.dout[j:data + j].eq(self.dout_int[count + l] + ) + ) + ) + ) + ) + ] + else: + if (k9_flag): + self.comb += [ + If(~self.rden, + If(~self.underflow, + If(self.rd_ptr <= (k_loop + 1 + l + count18K + count9K)*memory, + If(self.rd_ptr >= (k_loop + l + count18K + count9K)*memory, + self.dout[j:data + j].eq(self.dout_int[count + l] + ) + ) + ) + ) + ) + ] + else: + self.comb += [ + If(~self.rden, + If(~self.underflow, + If(self.rd_ptr <= (k_loop + 1 + l + count18K)*memory, + If(self.rd_ptr >= (k_loop + l + count18K)*memory, + self.dout[j:data + j].eq(self.dout_int[count + l] + ) + ) + ) + ) + ) + ] + count = count + 2 + mem = mem + 1 + if (data == 18): + count18K = count18K + 1 + elif (data == 9): + count9K = count9K + 1 + if (count18K != old_count18K): + if (not k9_flag): + k_loop = k_loop + 1 + elif (k9_flag or k36_flag): + if (count18K % 2 == 0 and count18K != 0): + k_loop = k_loop + 1 + else: + k_loop = k_loop + 1 + if (count9K != old_count9K): + if (k18_flag or k36_flag): + if (count9K % 1 == 0 and count9K != 0): + two_block = two_block + 1 + else: + two_block = two_block + 1 + old_count18K = count18K + old_count9K = count9K else: - if (instances == 1): - self.specials += Instance(instance, - # Parameters. - # ----------- - # Global. - p_DATA_WIDTH = C(data), - p_SYNC_FIFO = synchronous, - p_PROG_FULL_THRESH = C(depth - full_value, 12), - p_PROG_EMPTY_THRESH = C(empty_value, 12), + if (total_mem == 1): + if (instance == "FIFO36K"): + self.specials += Instance(instance, + # Parameters. + # ----------- + # Global. + p_DATA_WRITE_WIDTH = C(data), + p_DATA_READ_WIDTH = C(data), + p_FIFO_TYPE = synchronous, + p_PROG_FULL_THRESH = C(depth - full_value, 12), + p_PROG_EMPTY_THRESH = C(empty_value, 12), - # Clk / Rst. - # ---------- - i_RDCLK = ClockSignal("rd"), - i_WRCLK = ClockSignal("wrt"), - i_RESET = ResetSignal(), + # Clk / Rst. + # ---------- + i_RD_CLK = ClockSignal("rd"), + i_WR_CLK = ClockSignal("wrt"), + i_RESET = ResetSignal(), - # AXI Input - # ----------------- - i_WR_DATA = self.din[j:data + j], - i_RDEN = self.rden_int[k], - i_WREN = self.wren_int[k], + # Input + # ----------------- + i_WR_DATA = self.din[j:data + j], + i_RD_EN = self.rden_int[count], + i_WR_EN = self.wren_int[count], - # AXI Output - o_RD_DATA = self.dout[j:data + j], - o_EMPTY = self.empty[k], - o_FULL = self.full[k], - o_UNDERFLOW = self.underflow_int[k], - o_OVERFLOW = self.overflow_int[k], - o_ALMOST_EMPTY = self.almost_empty[k], - o_ALMOST_FULL = self.almost_full[k], - o_PROG_FULL = self.prog_full[k], - o_PROG_EMPTY = self.prog_empty[k] - ) + # Output + o_RD_DATA = self.dout_int[count][j:data + j], + o_EMPTY = self.empty_int[count], + o_FULL = self.full_int[count], + o_UNDERFLOW = self.underflow_int[count], + o_OVERFLOW = self.overflow_int[count], + o_ALMOST_EMPTY = self.almost_empty[count], + o_ALMOST_FULL = self.almost_full[count], + o_PROG_FULL = self.prog_full[count], + o_PROG_EMPTY = self.prog_empty[count] + ) + count = count + 1 + else: + self.specials += Instance(instance, + # Parameters. + # ----------- + # Global. + p_DATA_WRITE_WIDTH1 = C(data), + p_DATA_READ_WIDTH1 = C(data), + p_FIFO_TYPE1 = synchronous, + p_PROG_FULL_THRESH1 = C(full_value, 12), + p_PROG_EMPTY_THRESH1 = C(empty_value, 12), + p_DATA_WRITE_WIDTH2 = C(data), + p_DATA_READ_WIDTH2 = C(data), + p_FIFO_TYPE2 = synchronous, + p_PROG_FULL_THRESH2 = C(empty_value, 11), + p_PROG_EMPTY_THRESH2 = C(empty_value, 11), + # Clk / Rst. + # ---------- + i_RD_CLK1 = ClockSignal("rd"), + i_WR_CLK1 = ClockSignal("wrt"), + i_RESET1 = ResetSignal(), + # Input + # ----------------- + i_WR_DATA1 = self.din[j:data + j], + i_RD_EN1 = self.rden_int[count], + i_WR_EN1 = self.wren_int[count], + # Output + # ---------------- + o_RD_DATA1 = self.dout_int[count][j:data + j], + o_EMPTY1 = self.empty_int[count], + o_FULL1 = self.full_int[count], + o_UNDERFLOW1 = self.underflow_int[count], + o_OVERFLOW1 = self.overflow_int[count], + o_ALMOST_EMPTY1 = self.almost_empty_int[count], + o_ALMOST_FULL1 = self.almost_full_int[count], + o_PROG_FULL1 = self.prog_full_int[count], + o_PROG_EMPTY1 = self.prog_empty_int[count], + # Clk / Rst. + # ---------- + i_RD_CLK2 = ClockSignal("rd"), + i_WR_CLK2 = ClockSignal("wrt"), + i_RESET2 = ResetSignal(), + # Input + # ----------------- + i_WR_DATA2 = self.din[j:data + j], + i_RD_EN2 = self.rden_int[count + 1], + i_WR_EN2 = self.wren_int[count + 1], + # Output + # ----------------- + o_RD_DATA2 = self.dout_int[count + 1][j:data + j], + o_EMPTY2 = self.empty_int[count + 1], + o_FULL2 = self.full_int[count + 1], + o_UNDERFLOW2 = self.underflow_int[count + 1], + o_OVERFLOW2 = self.overflow_int[count + 1], + o_ALMOST_EMPTY2 = self.almost_empty_int[count + 1], + o_ALMOST_FULL2 = self.almost_full_int[count + 1], + o_PROG_FULL2 = self.prog_full_int[count + 1], + o_PROG_EMPTY2 = self.prog_empty_int[count + 1] + ) + for l in range (2): + if (count + l < num_36K + (num_18K/2)*2 + (num_9K/4)*2): + self.sync.wrt += [ + If(self.wren, + If(~self.full, + If(self.wrt_ptr[0:math.ceil(math.log2(depth)) + 1] < ((count + 1 + l)*memory) + int(starting), + If(self.wrt_ptr[0:math.ceil(math.log2(depth)) + 1] >= ((count + l)*memory) + int(starting), + self.wren_int[count + l].eq(1) + ) + .Else( + self.wren_int[count + l].eq(0) + ) + ) + .Else( + self.wren_int[count + l].eq(0) + ) + ) + .Else( + self.wren_int[count + l].eq(0) + ) + ) + .Else( + self.wren_int[count + l].eq(0) + ) + ] + if (count + l == 0): + self.sync.rd += [ + If(self.rden, + If(~self.empty, + If(self.rd_ptr[0:math.ceil(math.log2(depth)) + 1] < ((count + 1 + l)*memory) + int(starting) - 1, + If(self.rd_ptr[0:math.ceil(math.log2(depth)) + 1] >= ((count + l)*memory) + int(starting), + self.rden_int[count + l].eq(1) + ).Else(self.rden_int[count + l].eq(0)) + ).Elif(self.rd_ptr[0:math.ceil(math.log2(depth)) + 1] == int(ending), + self.rden_int[count + l].eq(1) + ).Else(self.rden_int[count + l].eq(0)) + ).Else(self.rden_int[count + l].eq(0)) + ).Else(self.rden_int[count + l].eq(0)) + ] + else: + self.sync.rd += [ + If(self.rden, + If(~self.empty, + If(self.rd_ptr[0:math.ceil(math.log2(depth)) + 1] < ((count + 1 + l)*memory) + int(starting) - 1, + If(self.rd_ptr[0:math.ceil(math.log2(depth)) + 1] >= ((count + l)*memory) + int(starting) - 1, + self.rden_int[count + l].eq(1) + ).Else(self.rden_int[count + l].eq(0)) + ).Else(self.rden_int[count + l].eq(0)) + ).Else(self.rden_int[count + l].eq(0)) + ).Else(self.rden_int[count + l].eq(0)) + ] + self.sync.rd += [ + If(self.rd_en_flop1, + If(~self.underflow, + If(self.rd_ptr[0:math.ceil(math.log2(depth)) + 1] < ((count + 1 + l)*memory) + int(starting), + If(self.rd_ptr[0:math.ceil(math.log2(depth)) + 1] >= ((count + l)*memory) + int(starting), + self.dout[j:data + j].eq(self.dout_int[count + l]) + ) + ) + ) + ) + ] + if (first_word_fall_through): + self.sync.rd += [ + If(~self.rden, + If(~self.underflow, + If(self.rd_ptr[0:math.ceil(math.log2(depth)) + 1] <= ((count + 1 + l)*memory) + int(starting), + If(self.rd_ptr[0:math.ceil(math.log2(depth)) + 1] >= ((count + l)*memory) + int(starting), + self.dout[j:data + j].eq(self.dout_int[count + l] + ) + ) + ) + ) + ) + ] + count = count + 2 else: - self.specials += Instance(instance, - # Parameters. - # ----------- - # Global. - p_DATA_WIDTH = C(data), - p_SYNC_FIFO = synchronous, - p_PROG_FULL_THRESH = C(4095, 12), - p_PROG_EMPTY_THRESH = C(0, 12), + if (instance == "FIFO36K" and count_36K < num_36K): + self.specials += Instance(instance, + # Parameters. + # ----------- + # Global. + p_DATA_WRITE_WIDTH = C(data), + p_DATA_READ_WIDTH = C(data), + p_FIFO_TYPE = synchronous, + p_PROG_FULL_THRESH = C(4095, 12), + p_PROG_EMPTY_THRESH = C(0, 12), - # Clk / Rst. - # ---------- - i_RDCLK = ClockSignal("rd"), - i_WRCLK = ClockSignal("wrt"), - i_RESET = ResetSignal(), + # Clk / Rst. + # ---------- + i_RD_CLK = ClockSignal("rd"), + i_WR_CLK = ClockSignal("wrt"), + i_RESET = ResetSignal(), - # AXI Input - # ----------------- - i_WR_DATA = self.din[j:data + j], - i_RDEN = self.rden_int[k], - i_WREN = self.wren_int[k], + # Input + # ----------------- + i_WR_DATA = self.din[j:data + j], + i_RD_EN = self.rden_int[count], + i_WR_EN = self.wren_int[count], - # AXI Output - o_RD_DATA = self.dout_int[k][j:data + j], - o_EMPTY = self.empty_int[k], - o_FULL = self.full_int[k], - o_UNDERFLOW = self.underflow_int[k], - o_OVERFLOW = self.overflow_int[k], - o_ALMOST_EMPTY = self.almost_empty_int[k], - o_ALMOST_FULL = self.almost_full_int[k], - o_PROG_FULL = self.prog_full_int[k], - o_PROG_EMPTY = self.prog_empty_int[k] - ) + # Output + o_RD_DATA = self.dout_int[count], + o_EMPTY = self.empty_int[count], + o_FULL = self.full_int[count], + o_UNDERFLOW = self.underflow_int[count], + o_OVERFLOW = self.overflow_int[count], + o_ALMOST_EMPTY = self.almost_empty_int[count], + o_ALMOST_FULL = self.almost_full_int[count], + o_PROG_FULL = self.prog_full_int[count], + o_PROG_EMPTY = self.prog_empty_int[count] + ) + count = count + 1 + mem = mem + 1 + count_36K = count_36K + 1 + elif(instance == "FIFO18KX2" and mem < total_mem and ((((k % (instances/(instances/2)) == 1 and data == 18 and count18K < (num_18K/2)) or (k + 2 == total_mem) or (k % (instances/(instances/4)) == 1 and data == 9 and count9K < (num_9K/4)) or (not k36_flag and data == 9 and count9K < num_9K/4) or (not k36_flag and data == 18 and count18K < num_18K/2))))): + index_array.append(count) + index_array.append(count + 1) + self.specials += Instance(instance, + # Parameters. + # ----------- + # Global. + p_DATA_WRITE_WIDTH1 = C(data), + p_DATA_READ_WIDTH1 = C(data), + p_FIFO_TYPE1 = synchronous, + p_PROG_FULL_THRESH1 = C(4095, 12), + p_PROG_EMPTY_THRESH1 = C(0, 12), + p_DATA_WRITE_WIDTH2 = C(data), + p_DATA_READ_WIDTH2 = C(data), + p_FIFO_TYPE2 = synchronous, + p_PROG_FULL_THRESH2 = C(2000, 11), + p_PROG_EMPTY_THRESH2 = C(0, 11), + # Clk / Rst. + # ---------- + i_RD_CLK1 = ClockSignal("rd"), + i_WR_CLK1 = ClockSignal("wrt"), + i_RESET1 = ResetSignal(), + # Input + # ----------------- + i_WR_DATA1 = self.din[j:data + j], + i_RD_EN1 = self.rden_int[count], + i_WR_EN1 = self.wren_int[count], + # Output + # ----------------- + o_RD_DATA1 = self.dout_int[count], + o_EMPTY1 = self.empty_int[count], + o_FULL1 = self.full_int[count], + o_UNDERFLOW1 = self.underflow_int[count], + o_OVERFLOW1 = self.overflow_int[count], + o_ALMOST_EMPTY1 = self.almost_empty_int[count], + o_ALMOST_FULL1 = self.almost_full_int[count], + o_PROG_FULL1 = self.prog_full_int[count], + o_PROG_EMPTY1 = self.prog_empty_int[count], + # Clk / Rst. + # ---------- + i_RD_CLK2 = ClockSignal("rd"), + i_WR_CLK2 = ClockSignal("wrt"), + i_RESET2 = ResetSignal(), + # Input + # ----------------- + i_WR_DATA2 = self.din[j:data + j], + i_RD_EN2 = self.rden_int[count + 1], + i_WR_EN2 = self.wren_int[count + 1], + # Output + o_RD_DATA2 = self.dout_int[count + 1], + o_EMPTY2 = self.empty_int[count + 1], + o_FULL2 = self.full_int[count + 1], + o_UNDERFLOW2 = self.underflow_int[count + 1], + o_OVERFLOW2 = self.overflow_int[count + 1], + o_ALMOST_EMPTY2 = self.almost_empty_int[count + 1], + o_ALMOST_FULL2 = self.almost_full_int[count + 1], + o_PROG_FULL2 = self.prog_full_int[count + 1], + o_PROG_EMPTY2 = self.prog_empty_int[count + 1] + ) + for l in range (2): + if (count + l < num_36K + (num_18K/2)*2 + (num_9K/4)*2): + if (data == 9): + if (k18_flag): + self.sync.wrt += [ + If(self.wren, + If(~self.full, + If(self.wrt_ptr[0:math.ceil(math.log2(depth)) + 1] < ((k_loop + 1 + l + two_block)*memory) + int(starting), + If(self.wrt_ptr[0:math.ceil(math.log2(depth)) + 1] >= ((k_loop + l + two_block)*memory) + int(starting), + self.wren_int[count + l].eq(1) + ) + .Else( + self.wren_int[count + l].eq(0) + ) + ) + .Else( + self.wren_int[count + l].eq(0) + ) + ) + .Else( + self.wren_int[count + l].eq(0) + ) + ) + .Else( + self.wren_int[count + l].eq(0) + ) + ] + else: + self.sync.wrt += [ + If(self.wren, + If(~self.full, + If(self.wrt_ptr[0:math.ceil(math.log2(depth)) + 1] < ((k_loop + 1 + l + two_block + count9K)*memory) + int(starting), + If(self.wrt_ptr[0:math.ceil(math.log2(depth)) + 1] >= ((k_loop + l + two_block + count9K)*memory) + int(starting), + self.wren_int[count + l].eq(1) + ) + .Else( + self.wren_int[count + l].eq(0) + ) + ) + .Else( + self.wren_int[count + l].eq(0) + ) + ) + .Else( + self.wren_int[count + l].eq(0) + ) + ) + .Else( + self.wren_int[count + l].eq(0) + ) + ] + else: + if (k9_flag): + self.sync.wrt += [ + If(self.wren, + If(~self.full, + If(self.wrt_ptr[0:math.ceil(math.log2(depth)) + 1] < ((k_loop + 1 + l + count18K + count9K)*memory) + int(starting), + If(self.wrt_ptr[0:math.ceil(math.log2(depth)) + 1] >= ((k_loop + l + count18K + count9K)*memory) + int(starting), + self.wren_int[count + l].eq(1) + ) + .Else( + self.wren_int[count + l].eq(0) + ) + ) + .Else( + self.wren_int[count + l].eq(0) + ) + ) + .Else( + self.wren_int[count + l].eq(0) + ) + ) + .Else( + self.wren_int[count + l].eq(0) + ) + ] + else: + self.sync.wrt += [ + If(self.wren, + If(~self.full, + If(self.wrt_ptr[0:math.ceil(math.log2(depth)) + 1] < ((k_loop + 1 + l + count18K)*memory) + int(starting), + If(self.wrt_ptr[0:math.ceil(math.log2(depth)) + 1] >= ((k_loop + l + count18K)*memory) + int(starting), + self.wren_int[count + l].eq(1) + ) + .Else( + self.wren_int[count + l].eq(0) + ) + ) + .Else( + self.wren_int[count + l].eq(0) + ) + ) + .Else( + self.wren_int[count + l].eq(0) + ) + ) + .Else( + self.wren_int[count + l].eq(0) + ) + ] + if (data == 9): + if (k18_flag): + if ((count + l + count_36K == 0) or (count_36K > 0 and l == 0 and (count9K == 0))): + self.sync.rd += [ + If(self.rden, + If(~self.empty, + If(self.rd_ptr[0:math.ceil(math.log2(depth)) + 1] < ((k_loop + 1 + l + two_block)*memory) + int(starting) - 1, + If(self.rd_ptr[0:math.ceil(math.log2(depth)) + 1] >= ((k_loop + l + two_block)*memory) + int(starting), + self.rden_int[count + l].eq(1) + ).Else(self.rden_int[count + l].eq(0)) + ).Elif(self.rd_ptr[0:math.ceil(math.log2(depth)) + 1] == int(ending), + self.rden_int[count + l].eq(1) + ).Else(self.rden_int[count + l].eq(0)) + ).Else(self.rden_int[count + l].eq(0)) + ).Else(self.rden_int[count + l].eq(0)) + ] + else: + self.sync.rd += [ + If(self.rden, + If(~self.empty, + If(self.rd_ptr[0:math.ceil(math.log2(depth)) + 1] < ((k_loop + 1 + l + two_block)*memory) + int(starting) - 1, + If(self.rd_ptr[0:math.ceil(math.log2(depth)) + 1] >= ((k_loop + l + two_block)*memory) + int(starting) - 1, + self.rden_int[count + l].eq(1) + ).Else(self.rden_int[count + l].eq(0)) + ).Else(self.rden_int[count + l].eq(0)) + ).Else(self.rden_int[count + l].eq(0)) + ).Else(self.rden_int[count + l].eq(0)) + ] + self.sync.rd += [ + If(self.rd_en_flop1, + If(~self.underflow, + If(self.rd_ptr[0:math.ceil(math.log2(depth)) + 1] < ((k_loop + 1 + l + two_block)*memory) + int(starting), + If(self.rd_ptr[0:math.ceil(math.log2(depth)) + 1] >= ((k_loop + l + two_block)*memory) + int(starting), + self.dout[j:data + j].eq(self.dout_int[count + l]) + ) + ) + ) + ) + ] + else: + if ((count + l + count_36K == 0) or (count_36K > 0 and l == 0 and (count18K + count9K == 0))): + self.sync.rd += [ + If(self.rden, + If(~self.empty, + If(self.rd_ptr[0:math.ceil(math.log2(depth)) + 1] < ((k_loop + 1 + l + two_block + count9K)*memory) + int(starting) - 1, + If(self.rd_ptr[0:math.ceil(math.log2(depth)) + 1] >= ((k_loop + l + two_block + count9K)*memory) + int(starting), + self.rden_int[count + l].eq(1) + ).Else(self.rden_int[count + l].eq(0)) + ).Elif(self.rd_ptr[0:math.ceil(math.log2(depth)) + 1] == int(ending), + self.rden_int[count + l].eq(1) + ).Else(self.rden_int[count + l].eq(0)) + ).Else(self.rden_int[count + l].eq(0)) + ).Else(self.rden_int[count + l].eq(0)) + ] + else: + self.sync.rd += [ + If(self.rden, + If(~self.empty, + If(self.rd_ptr[0:math.ceil(math.log2(depth)) + 1] < ((k_loop + 1 + l + two_block + count9K)*memory) + int(starting) - 1, + If(self.rd_ptr[0:math.ceil(math.log2(depth)) + 1] >= ((k_loop + l + two_block + count9K)*memory) + int(starting) - 1, + self.rden_int[count + l].eq(1) + ).Else(self.rden_int[count + l].eq(0)) + ).Else(self.rden_int[count + l].eq(0)) + ).Else(self.rden_int[count + l].eq(0)) + ).Else(self.rden_int[count + l].eq(0)) + ] + self.sync.rd += [ + If(self.rd_en_flop1, + If(~self.underflow, + If(self.rd_ptr[0:math.ceil(math.log2(depth)) + 1] < ((k_loop + 1 + l + two_block + count9K)*memory) + int(starting), + If(self.rd_ptr[0:math.ceil(math.log2(depth)) + 1] >= ((k_loop + l + two_block + count9K)*memory) + int(starting), + self.dout[j:data + j].eq(self.dout_int[count + l]) + ) + ) + ) + ) + ] + else: + if (k9_flag): + if ((count + l + count_36K == 0) or (count_36K > 0 and l == 0 and (count18K == 0))): + self.sync.rd += [ + If(self.rden, + If(~self.empty, + If(self.rd_ptr[0:math.ceil(math.log2(depth)) + 1] < ((k_loop + 1 + l + count18K + count9K)*memory) + int(starting) - 1, + If(self.rd_ptr[0:math.ceil(math.log2(depth)) + 1] >= ((k_loop + l + count18K + count9K)*memory) + int(starting), + self.rden_int[count + l].eq(1) + ).Else(self.rden_int[count + l].eq(0)) + ).Elif(self.rd_ptr[0:math.ceil(math.log2(depth)) + 1] == int(ending), + self.rden_int[count + l].eq(1) + ).Else(self.rden_int[count + l].eq(0)) + ).Else(self.rden_int[count + l].eq(0)) + ).Else(self.rden_int[count + l].eq(0)) + ] + else: + self.sync.rd += [ + If(self.rden, + If(~self.empty, + If(self.rd_ptr[0:math.ceil(math.log2(depth)) + 1] < ((k_loop + 1 + l + count18K + count9K)*memory) + int(starting) - 1, + If(self.rd_ptr[0:math.ceil(math.log2(depth)) + 1] >= ((k_loop + l + count18K + count9K)*memory) + int(starting) - 1, + self.rden_int[count + l].eq(1) + ).Else(self.rden_int[count + l].eq(0)) + ).Else(self.rden_int[count + l].eq(0)) + ).Else(self.rden_int[count + l].eq(0)) + ).Else(self.rden_int[count + l].eq(0)) + ] + self.sync.rd += [ + If(self.rd_en_flop1, + If(~self.underflow, + If(self.rd_ptr[0:math.ceil(math.log2(depth)) + 1] < ((k_loop + 1 + l + count18K + count9K)*memory) + int(starting), + If(self.rd_ptr[0:math.ceil(math.log2(depth)) + 1] >= ((k_loop + l + count18K + count9K)*memory) + int(starting), + self.dout[j:data + j].eq(self.dout_int[count + l]) + ) + ) + ) + ) + ] + else: + if ((count + l + count_36K == 0) or (count_36K > 0 and l == 0 and (count18K + count9K == 0))): + self.sync.rd += [ + If(self.rden, + If(~self.empty, + If(self.rd_ptr[0:math.ceil(math.log2(depth)) + 1] < ((k_loop + 1 + l + count18K)*memory) + int(starting) - 1, + If(self.rd_ptr[0:math.ceil(math.log2(depth)) + 1] >= ((k_loop + l + count18K)*memory) + int(starting), + self.rden_int[count + l].eq(1) + ).Else(self.rden_int[count + l].eq(0)) + ).Elif(self.rd_ptr[0:math.ceil(math.log2(depth)) + 1] == int(ending), + self.rden_int[count + l].eq(1) + ).Else(self.rden_int[count + l].eq(0)) + ).Else(self.rden_int[count + l].eq(0)) + ).Else(self.rden_int[count + l].eq(0)) + ] + else: + self.sync.rd += [ + If(self.rden, + If(~self.empty, + If(self.rd_ptr[0:math.ceil(math.log2(depth)) + 1] < ((k_loop + 1 + l + count18K)*memory) + int(starting) - 1, + If(self.rd_ptr[0:math.ceil(math.log2(depth)) + 1] >= ((k_loop + l + count18K)*memory) + int(starting)- 1, + self.rden_int[count + l].eq(1) + ).Else(self.rden_int[count + l].eq(0)) + ).Else(self.rden_int[count + l].eq(0)) + ).Else(self.rden_int[count + l].eq(0)) + ).Else(self.rden_int[count + l].eq(0)) + ] + self.sync.rd += [ + If(self.rd_en_flop1, + If(~self.underflow, + If(self.rd_ptr[0:math.ceil(math.log2(depth)) + 1] <= ((k_loop + 1 + l + count18K)*memory) + int(starting), + If(self.rd_ptr[0:math.ceil(math.log2(depth)) + 1] >= ((k_loop + l + count18K)*memory) + int(starting), + self.dout[j:data + j].eq(self.dout_int[count + l]) + ) + ) + ) + ) + ] + if (first_word_fall_through): + if (data == 9): + if (k18_flag): + self.sync.rd += [ + If(~self.rden, + If(~self.underflow, + If(self.rd_ptr[0:math.ceil(math.log2(depth)) + 1] <= ((k_loop + 1 + l + two_block)*memory) + int(starting), + If(self.rd_ptr[0:math.ceil(math.log2(depth)) + 1] >= ((k_loop + l + two_block)*memory) + int(starting), + self.dout[j:data + j].eq(self.dout_int[count + l] + ) + ) + ) + ) + ) + ] + else: + self.sync.rd += [ + If(~self.rden, + If(~self.underflow, + If(self.rd_ptr[0:math.ceil(math.log2(depth)) + 1] <= ((k_loop + 1 + l + two_block + count9K)*memory) + int(starting), + If(self.rd_ptr[0:math.ceil(math.log2(depth)) + 1] >= ((k_loop + l + two_block + count9K)*memory) + int(starting), + self.dout[j:data + j].eq(self.dout_int[count + l] + ) + ) + ) + ) + ) + ] + else: + if (k9_flag): + self.sync.rd += [ + If(~self.rden, + If(~self.underflow, + If(self.rd_ptr[0:math.ceil(math.log2(depth)) + 1] <= ((k_loop + 1 + l + count18K + count9K)*memory) + int(starting), + If(self.rd_ptr[0:math.ceil(math.log2(depth)) + 1] >= ((k_loop + l + count18K + count9K)*memory) + int(starting), + self.dout[j:data + j].eq(self.dout_int[count + l] + ) + ) + ) + ) + ) + ] + else: + self.sync.rd += [ + If(~self.rden, + If(~self.underflow, + If(self.rd_ptr[0:math.ceil(math.log2(depth)) + 1] <= ((k_loop + 1 + l + count18K)*memory) + int(starting), + If(self.rd_ptr[0:math.ceil(math.log2(depth)) + 1] >= ((k_loop + l + count18K)*memory) + int(starting), + self.dout[j:data + j].eq(self.dout_int[count + l] + ) + ) + ) + ) + ) + ] + count = count + 2 + mem = mem + 1 + if (data == 18): + count18K = count18K + 1 + elif (data == 9): + count9K = count9K + 1 + if (count18K != old_count18K): + if (not k9_flag): + k_loop = k_loop + 1 + elif (k9_flag or k36_flag): + if (count18K % 2 == 0 and count18K != 0): + k_loop = k_loop + 1 + else: + k_loop = k_loop + 1 + if (count9K != old_count9K): + if (k18_flag or k36_flag): + if (count9K % 1 == 0 and count9K != 0): + two_block = two_block + 1 + else: + two_block = two_block + 1 + old_count18K = count18K + old_count9K = count9K j = data + j - if (instances > 1): - # Writing and Reading to FIFOs - if(SYNCHRONOUS[synchronous]): - self.comb += [ - If(self.wren, - If(~self.overflow, - If(~self.full_int[k], - If(self.wrt_ptr <= (k + 1)*memory, - If(self.wrt_ptr > (k)*memory, - self.wren_int[k].eq(1) - ) + memory = 1024 + j_loop = 0 + l = 0 + count_loop = 0 + if (k36_flag): + for k in range (0, int(mem + (count18K/2)) * math.ceil(data_width/36) + 1, math.ceil(data_width/36)): + # if (total_mem > 1): + for i in range (k, k + math.ceil(data_width/36)): + if (i not in index_array and i < count): + count_loop = count_loop + 1 + # Writing and Reading to FIFOs + if(SYNCHRONOUS[synchronous]): + self.comb += [ + If(self.wren, + If(~self.overflow, + If(~self.full_int[i], + If(self.wrt_ptr <= (j_loop + 1)*memory, + If(self.wrt_ptr > (j_loop)*memory, + self.wren_int[i].eq(1) + ) + ) + ) + ) ) - ) - ) - ) - ] - - self.comb += [ - If(self.rden, - If(~self.underflow, - If(self.rd_ptr <= (k + 1)*memory, - If(self.rd_ptr > (k)*memory, - self.rden_int[k].eq(1), - self.dout.eq(self.dout_int[k] + ] + self.comb += [ + If(self.rden, + If(~self.underflow, + If(self.rd_ptr <= (j_loop + 1)*memory, + If(self.rd_ptr > (j_loop)*memory, + self.rden_int[i].eq(1), + self.dout[(36*l):36 + (36*l)].eq(self.dout_int[i]) + ) + ) + ) ) - ) - ) - ) - ) - ] - - # First Word Fall Through Implmentation - if (first_word_fall_through): - if (k == 0): - self.comb += [ - If(~self.rden, - If(~self.underflow, - If(self.rd_ptr <= (k + 1)*memory, - If(self.rd_ptr >= (k)*memory, - self.dout.eq(self.dout_int[k]) + ] + + # First Word Fall Through Implmentation + if (first_word_fall_through): + if (j_loop == 0): + self.comb += [ + If(~self.rden, + If(~self.underflow, + If(self.rd_ptr <= (j_loop + 1)*memory, + If(self.rd_ptr >= (j_loop)*memory, + self.dout[(36*l):36 + (36*l)].eq(self.dout_int[i]) + ) + ) + ) + ) + ] + else: + self.comb += [ + If(~self.rden, + If(~self.underflow, + If(self.rd_ptr <= (j_loop + 1)*memory, + If(self.rd_ptr > (j_loop)*memory, + self.dout[(36*l):36 + (36*l)].eq(self.dout_int[i]) + ) + ) + ) + ) + ] + else: + if (j_loop == total_mem - 1): + if (j_loop == 0): + self.sync.rd += [ + If(self.rden, + If(~self.empty, + If(self.rd_ptr[0:math.ceil(math.log2(depth)) + 1] < ((j_loop + 1)*memory) + int(starting) - 1, + If(self.rd_ptr[0:math.ceil(math.log2(depth)) + 1] >= ((j_loop)*memory) + int(starting), + self.rden_int[i].eq(1) + ) + .Else( + self.rden_int[i].eq(0)) + ) + .Else( + self.rden_int[i].eq(0) + ) + ) + .Else( + self.rden_int[i].eq(0) + ) ) - ) - ) - ) - ] - else: - self.comb += [ - If(~self.rden, - If(~self.underflow, - If(self.rd_ptr <= (k + 1)*memory, - If(self.rd_ptr > (k)*memory, - self.dout.eq(self.dout_int[k]) + .Else( + self.rden_int[i].eq(0) ) - ) - ) - ) - ] - else: - if (k == instances - 1): - if (k == 0): - self.sync.rd += [ - If(self.rden, - If(~self.empty, - If(self.rd_ptr[0:math.ceil(math.log2(depth)) + 1] < ((k + 1)*memory) + int(starting - 1), - If(self.rd_ptr[0:math.ceil(math.log2(depth)) + 1] >= ((k)*memory) + int(starting), - self.rden_int[k].eq(1) - ) - .Else( - self.rden_int[k].eq(0)) - ) - .Else( - self.rden_int[k].eq(0) - ) - ) - .Else( - self.rden_int[k].eq(0) - ) - ) - .Else( - self.rden_int[k].eq(0) - ) - ] - else: - self.sync.rd += [ - If(self.rden, - If(~self.empty, - If(self.rd_ptr[0:math.ceil(math.log2(depth)) + 1] < ((k + 1)*memory) + int(starting - 1), - If(self.rd_ptr[0:math.ceil(math.log2(depth)) + 1] >= ((k)*memory) + int(starting - 1), - self.rden_int[k].eq(1) - ) - .Else( - self.rden_int[k].eq(0)) - ) - .Else( - self.rden_int[k].eq(0) - ) - ) - .Else( - self.rden_int[k].eq(0) - ) - ) - .Else( - self.rden_int[k].eq(0) - ) - ] - self.sync.rd += [ - If(self.rd_en_flop1, - If(~self.underflow, - If(self.rd_ptr[0:math.ceil(math.log2(depth)) + 1] <= ((k + 1)*memory) + int(starting), - If(self.rd_ptr[0:math.ceil(math.log2(depth)) + 1] >= ((k)*memory) + int(starting), - self.dout.eq(self.dout_int[k]) - ) - ) - ) - ) - ] - - self.sync.wrt += [ - If(self.wren, - If(~self.full, - If(self.wrt_ptr[0:math.ceil(math.log2(depth)) + 1] < ((k + 1)*memory) + int(starting), - If(self.wrt_ptr[0:math.ceil(math.log2(depth)) + 1] >= ((k)*memory) + int(starting), - self.wren_int[k].eq(1) + ] + else: + self.sync.rd += [ + If(self.rden, + If(~self.empty, + If(self.rd_ptr[0:math.ceil(math.log2(depth)) + 1] < ((j_loop + 1)*memory) + int(starting) - 1, + If(self.rd_ptr[0:math.ceil(math.log2(depth)) + 1] >= ((j_loop)*memory) + int(starting) - 1, + self.rden_int[i].eq(1) + ) + .Else( + self.rden_int[i].eq(0)) + ) + .Else( + self.rden_int[i].eq(0) + ) + ) + .Else( + self.rden_int[i].eq(0) + ) ) .Else( - self.wren_int[k].eq(0) + self.rden_int[i].eq(0) + ) + ] + self.sync.rd += [ + If(self.rd_en_flop1, + If(~self.underflow, + If(self.rd_ptr[0:math.ceil(math.log2(depth)) + 1] <= ((j_loop + 1)*memory) + int(starting), + If(self.rd_ptr[0:math.ceil(math.log2(depth)) + 1] >= ((j_loop)*memory) + int(starting), + self.dout[(36*l):36 + (36*l)].eq(self.dout_int[i]) + ) + ) + ) ) - ) - .Else( - self.wren_int[k].eq(0) - ) - ) - .Else( - self.wren_int[k].eq(0) - ) - ) - .Else( - self.wren_int[k].eq(0) - ) - ] - else: - self.sync.wrt += [ - If(self.wren, - If(~self.full, - If(self.wrt_ptr[0:math.ceil(math.log2(depth)) + 1] < ((k + 1)*memory) + int(starting), - If(self.wrt_ptr[0:math.ceil(math.log2(depth)) + 1] >= ((k)*memory) + int(starting), - self.wren_int[k].eq(1) - ) - .Else( - self.wren_int[k].eq(0) - ) - ) - .Else( - self.wren_int[k].eq(0) - ) - ) - .Else( - self.wren_int[k].eq(0) - ) - ) - .Else( - self.wren_int[k].eq(0) - ) - ] - if (k == 0): - self.sync.rd += [ - If(self.rden, - If(~self.empty, - If(self.rd_ptr[0:math.ceil(math.log2(depth)) + 1] < ((k + 1)*memory) + int(starting - 1), - If(self.rd_ptr[0:math.ceil(math.log2(depth)) + 1] >= ((k)*memory) + int(starting), - self.rden_int[k].eq(1) + ] + self.sync.wrt += [ + If(self.wren, + If(~self.full, + If(self.wrt_ptr[0:math.ceil(math.log2(depth)) + 1] < ((j_loop + 1)*memory) + int(starting), + If(self.wrt_ptr[0:math.ceil(math.log2(depth)) + 1] >= ((j_loop)*memory) + int(starting), + self.wren_int[i].eq(1) + ) + .Else( + self.wren_int[i].eq(0) + ) + ) + .Else( + self.wren_int[i].eq(0) + ) + ) + .Else( + self.wren_int[i].eq(0) + ) ) .Else( - self.rden_int[k].eq(0)) - ) - .Elif(self.rd_ptr[0:math.ceil(math.log2(depth)) + 1] == int(ending), - self.rden_int[k].eq(1) - ) - .Else( - self.rden_int[k].eq(0) + self.wren_int[i].eq(0) + ) + ] + else: + self.sync.wrt += [ + If(self.wren, + If(~self.full, + If(self.wrt_ptr[0:math.ceil(math.log2(depth)) + 1] < ((j_loop + 1)*memory) + int(starting), + If(self.wrt_ptr[0:math.ceil(math.log2(depth)) + 1] >= ((j_loop)*memory) + int(starting), + self.wren_int[i].eq(1) + ) + .Else( + self.wren_int[i].eq(0) + ) + ) + .Else( + self.wren_int[i].eq(0) + ) + ) + .Else( + self.wren_int[i].eq(0) ) - ) - .Else( - self.rden_int[k].eq(0) - ) - ) - .Else( - self.rden_int[k].eq(0) - ) - ] - else: - self.sync.rd += [ - If(self.rden, - If(~self.empty, - If(self.rd_ptr[0:math.ceil(math.log2(depth)) + 1] < ((k + 1)*memory) + int(starting - 1), - If(self.rd_ptr[0:math.ceil(math.log2(depth)) + 1] >= ((k)*memory) + int(starting - 1), - self.rden_int[k].eq(1) ) .Else( - self.rden_int[k].eq(0) - ) - ) - .Else( - self.rden_int[k].eq(0) - ) - ) - .Else( - self.rden_int[k].eq(0) - ) - ) - .Else( - self.rden_int[k].eq(0) - ) - ] - self.sync.rd += [ - If(self.rd_en_flop1, - If(~self.underflow, - If(self.rd_ptr[0:math.ceil(math.log2(depth)) + 1] < ((k + 1)*memory) + int(starting), - If(self.rd_ptr[0:math.ceil(math.log2(depth)) + 1] >= ((k)*memory) + int(starting), - self.dout.eq(self.dout_int[k]) + self.wren_int[i].eq(0) ) - ) - ) - ) - ] - - - # First Word Fall Through Implmentation - if (first_word_fall_through): - if (k == instances - 1): - self.sync.rd += [ - If(~self.rd_en_flop1, - If(~self.underflow, - If(self.rd_ptr[0:math.ceil(math.log2(depth)) + 1] <= ((k + 1)*memory) + int(starting), - If(self.rd_ptr[0:math.ceil(math.log2(depth)) + 1] >= ((k)*memory) + int(starting), - self.dout.eq(self.dout_int[k]) + ] + if (j_loop == 0): + self.sync.rd += [ + If(self.rden, + If(~self.empty, + If(self.rd_ptr[0:math.ceil(math.log2(depth)) + 1] < ((j_loop + 1)*memory) + int(starting) - 1, + If(self.rd_ptr[0:math.ceil(math.log2(depth)) + 1] >= ((j_loop)*memory) + int(starting), + self.rden_int[i].eq(1) + ) + .Else( + self.rden_int[i].eq(0)) + ) + .Elif(self.rd_ptr[0:math.ceil(math.log2(depth)) + 1] == int(ending), + self.rden_int[i].eq(1) + ) + .Else( + self.rden_int[i].eq(0) + ) + ) + .Else( + self.rden_int[i].eq(0) + ) + ) + .Else( + self.rden_int[i].eq(0) + ) + ] + else: + self.sync.rd += [ + If(self.rden, + If(~self.empty, + If(self.rd_ptr[0:math.ceil(math.log2(depth)) + 1] < ((j_loop + 1)*memory) + int(starting) - 1, + If(self.rd_ptr[0:math.ceil(math.log2(depth)) + 1] >= ((j_loop)*memory) + int(starting) - 1, + self.rden_int[i].eq(1) + ) + .Else( + self.rden_int[i].eq(0) + ) + ) + .Else( + self.rden_int[i].eq(0) + ) + ) + .Else( + self.rden_int[i].eq(0) + ) ) - ) - ) - ) - ] - else: - self.sync.rd += [ - If(~self.rd_en_flop1, - If(~self.underflow, - If(self.rd_ptr[0:math.ceil(math.log2(depth)) + 1] < ((k + 1)*memory) + int(starting), - If(self.rd_ptr[0:math.ceil(math.log2(depth)) + 1] >= ((k)*memory) + int(starting), - self.dout.eq(self.dout_int[k]) + .Else( + self.rden_int[i].eq(0) + ) + ] + self.sync.rd += [ + If(self.rd_en_flop1, + If(~self.underflow, + If(self.rd_ptr[0:math.ceil(math.log2(depth)) + 1] < ((j_loop + 1)*memory) + int(starting), + If(self.rd_ptr[0:math.ceil(math.log2(depth)) + 1] >= ((j_loop)*memory) + int(starting), + self.dout[(36*l):36 + (36*l)].eq(self.dout_int[i]) + ) + ) + ) ) - ) - ) - ) - ] - if (instances > 1): + ] + # First Word Fall Through Implmentation + if (first_word_fall_through): + if (j_loop == total_mem - 1): + self.sync.rd += [ + If(~self.rd_en_flop1, + If(~self.underflow, + If(self.rd_ptr[0:math.ceil(math.log2(depth)) + 1] <= ((j_loop + 1)*memory) + int(starting), + If(self.rd_ptr[0:math.ceil(math.log2(depth)) + 1] >= ((j_loop)*memory) + int(starting), + self.dout[(36*l):36 + (36*l)].eq(self.dout_int[i]) + ) + ) + ) + ) + ] + else: + self.sync.rd += [ + If(~self.rd_en_flop1, + If(~self.underflow, + If(self.rd_ptr[0:math.ceil(math.log2(depth)) + 1] < ((j_loop + 1)*memory) + int(starting), + If(self.rd_ptr[0:math.ceil(math.log2(depth)) + 1] >= ((j_loop)*memory) + int(starting), + self.dout[(36*l):36 + (36*l)].eq(self.dout_int[i]) + ) + ) + ) + ) + ] + l = l + 1 + if (data_width >= 36): + if (count_loop == data_36): + j_loop = j_loop + 1 + l = 0 + count_loop = 0 + else: + j_loop = j_loop + 1 + l = 0 + count_loop = 0 + + + if ((total_mem >= 1 and instance == "FIFO36K") or (total_mem >= 1 and instance == "FIFO18KX2")): if (not SYNCHRONOUS[synchronous]): self.sync.rd += self.rd_en_flop.eq(self.rden) self.sync.rd += [ @@ -1115,4 +2064,4 @@ def __init__(self, data_width, synchronous, full_threshold, empty_threshold, dep ).Else( self.overflow.eq(0) ) - ] \ No newline at end of file + ] diff --git a/rapidsilicon/ip/fifo_generator/v1_0/sim/FIFO.v b/rapidsilicon/ip/fifo_generator/v1_0/sim/FIFO.v index b22d0ba0..26894bf5 100644 --- a/rapidsilicon/ip/fifo_generator/v1_0/sim/FIFO.v +++ b/rapidsilicon/ip/fifo_generator/v1_0/sim/FIFO.v @@ -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, @@ -27,35 +32,35 @@ 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}), @@ -63,104 +68,174 @@ if (DATA_WIDTH == 36) .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 \ No newline at end of file diff --git a/rapidsilicon/ip/fifo_generator/v1_0/sim/FIFO18K.v b/rapidsilicon/ip/fifo_generator/v1_0/sim/FIFO18K.v deleted file mode 100644 index 3543f715..00000000 --- a/rapidsilicon/ip/fifo_generator/v1_0/sim/FIFO18K.v +++ /dev/null @@ -1,63 +0,0 @@ -// -------------------------------------------------------------------------- -// ---------------- Copyright (C) 2023 RapidSilicon ------------------------- -// -------------------------------------------------------------------------- -// ---------------------- FIFO18K Primitive --------------------------------- -// -------------------------------------------------------------------------- - -module FIFO18K #( - parameter DATA_WIDTH = 18, // Data Width of FIFO from 1, 2, 4, 9, 18 - parameter SYNC_FIFO = "TRUE", // Synchronous or Asynchronous FIFO "TRUE"/"FALSE" - parameter PROG_FULL_THRESH = 12'b100000000000, // Threshold indicating that the FIFO buffer is considered Full - parameter PROG_EMPTY_THRESH = 12'b111111111100 // Threshold indicating that the FIFO buffer is considered Empty -) -( - input wire [DATA_WIDTH-1:0] WR_DATA, // 18-bits Data coming inside FIFO - output wire [DATA_WIDTH-1:0] RD_DATA, // 18-bits Data coming out from FIFO - output wire EMPTY, // 1-bit output: Empty Flag - output wire FULL, // 1-bit output: Full Flag - output wire OVERFLOW, // 1-bit output: Overflow Flag - output wire UNDERFLOW, // 1-bit output: Underflow Flag - input wire RDEN, // 1-bit input: Read Enable - input wire WREN, // 1-bit input: Write Enable - output wire ALMOST_EMPTY, // 1-bit output: This Flag is asserted when FIFO contains EMPTY plus one data words. - output wire ALMOST_FULL, // 1-bit output: This Flag is asserted when FIFO contains FULL minus one data words. - output wire PROG_EMPTY, // 1-bit output: Empty Watermark Flag - output wire PROG_FULL, // 1-bit output: Full Watermark Flag - input wire WRCLK, // 1-bit input: Write Clock - input wire RDCLK, // 1-bit input: Read Clock - input wire RESET // 1-bit input: Active Low Synchronous Reset -); - -initial -begin - if (!(DATA_WIDTH == 1 || DATA_WIDTH == 2 || DATA_WIDTH == 4 || DATA_WIDTH == 9 || DATA_WIDTH == 18)) - begin - $error("Incorrect DATA_WIDTH: %0d\nEnter valid DATA_WIDTH: 1, 2, 4, 8, 9, 18", DATA_WIDTH); - $finish; - end -end - -FIFO #( - .DATA_WIDTH(DATA_WIDTH), - .SYNC_FIFO(SYNC_FIFO), - .PROG_FULL_THRESH(PROG_FULL_THRESH), - .PROG_EMPTY_THRESH(PROG_EMPTY_THRESH) -) -FIFO_insta_1( - .WR_DATA(WR_DATA), - .RD_DATA(RD_DATA), - .EMPTY(EMPTY), - .FULL(FULL), - .ALMOST_EMPTY(ALMOST_EMPTY), - .ALMOST_FULL(ALMOST_FULL), - .PROG_EMPTY(PROG_EMPTY), - .PROG_FULL(PROG_FULL), - .OVERFLOW(OVERFLOW), - .UNDERFLOW(UNDERFLOW), - .RDEN(RDEN), - .WREN(WREN), - .WRCLK(WRCLK), - .RDCLK(RDCLK), - .RESET(RESET) -); -endmodule \ No newline at end of file diff --git a/rapidsilicon/ip/fifo_generator/v1_0/sim/FIFO18KX2.v b/rapidsilicon/ip/fifo_generator/v1_0/sim/FIFO18KX2.v new file mode 100644 index 00000000..10bec9d6 --- /dev/null +++ b/rapidsilicon/ip/fifo_generator/v1_0/sim/FIFO18KX2.v @@ -0,0 +1,147 @@ +// -------------------------------------------------------------------------- +// ---------------- Copyright (C) 2023 RapidSilicon ------------------------- +// -------------------------------------------------------------------------- +// ---------------------- FIFO18KX2 Primitive ------------------------------- +// -------------------------------------------------------------------------- + +module FIFO18KX2 #( + parameter DATA_WRITE_WIDTH1 = 5'd18, // Write Data Width of FIFO1 from 1, 2, 4, 9, 18 + parameter DATA_READ_WIDTH1 = 5'd18, // Read Data Width of FIFO1 from 1, 2, 4, 9, 18 + parameter FIFO_TYPE1 = "SYNCHRONOUS", // Synchronous or Asynchronous FIFO1 + parameter PROG_EMPTY_THRESH1 = 12'h004, // Threshold indicating that the FIFO1 buffer is considered Empty + parameter PROG_FULL_THRESH1 = 12'h8fa, // Threshold indicating that the FIFO1 buffer is considered Full + + parameter DATA_WRITE_WIDTH2 = 5'd18, // Write Data Width of FIFO2 from 1, 2, 4, 9, 18 + parameter DATA_READ_WIDTH2 = 5'd18, // Read Data Width of FIFO1 from 1, 2, 4, 9, 18 + parameter FIFO_TYPE2 = "SYNCHRONOUS", // Synchronous or Asynchronous FIFO2 + parameter PROG_EMPTY_THRESH2 = 11'h004, // Threshold indicating that the FIFO2 buffer is considered Empty + parameter PROG_FULL_THRESH2 = 11'h4fa // Threshold indicating that the FIFO2 buffer is considered Full +) +( + // -------------Ports for FIFO 1----------------- + input wire RESET1, // 1-bit input: Active Low Synchronous Reset + input wire WR_CLK1, // 1-bit input: Write Clock + input wire RD_CLK1, // 1-bit input: Read Clock + input wire RD_EN1, // 1-bit input: Read Enable + input wire WR_EN1, // 1-bit input: Write Enable + input wire [DATA_WRITE_WIDTH1-1:0] WR_DATA1,// DATA_WIDTH1-bits Data coming inside FIFO + output wire [DATA_READ_WIDTH1-1:0] RD_DATA1,// DATA_WIDTH1-bits Data coming out from FIFO + output wire EMPTY1, // 1-bit output: Empty Flag + output wire FULL1, // 1-bit output: Full Flag + output wire ALMOST_EMPTY1, // 1-bit output: This Flag is asserted when FIFO contains EMPTY plus one data words + output wire ALMOST_FULL1, // 1-bit output: This Flag is asserted when FIFO contains FULL minus one data words + output wire PROG_EMPTY1, // 1-bit output: Empty Watermark Flag + output wire PROG_FULL1, // 1-bit output: Full Watermark Flag + output wire OVERFLOW1, // 1-bit output: Overflow Flag + output wire UNDERFLOW1, // 1-bit output: Underflow Flag + + // -------------Ports for FIFO 2----------------- + input wire RESET2, // 1-bit input: Active Low Synchronous Reset + input wire WR_CLK2, // 1-bit input: Write Clock + input wire RD_CLK2, // 1-bit input: Read Clock + input wire RD_EN2, // 1-bit input: Read Enable + input wire WR_EN2, // 1-bit input: Write Enable + input wire [DATA_WRITE_WIDTH2-1:0] WR_DATA2,// DATA_WIDTH2-bits Data coming inside FIFO + output wire [DATA_READ_WIDTH2-1:0] RD_DATA2,// DATA_WIDTH2-bits Data coming out from FIFO + output wire EMPTY2, // 1-bit output: Empty Flag + output wire FULL2, // 1-bit output: Full Flag + output wire ALMOST_EMPTY2, // 1-bit output: This Flag is asserted when FIFO contains EMPTY plus one data words + output wire ALMOST_FULL2, // 1-bit output: This Flag is asserted when FIFO contains FULL minus one data words + output wire PROG_EMPTY2, // 1-bit output: Empty Watermark Flag + output wire PROG_FULL2, // 1-bit output: Full Watermark Flag + output wire OVERFLOW2, // 1-bit output: Overflow Flag + output wire UNDERFLOW2 // 1-bit output: Underflow Flag +); + +localparam data_width_write1 = (DATA_WRITE_WIDTH1 > 4'd9) ? 5'd18 : DATA_WRITE_WIDTH1; +localparam data_width_write2 = (DATA_WRITE_WIDTH2 > 4'd9) ? 5'd18 : DATA_WRITE_WIDTH2; +localparam data_width_read1 = (DATA_READ_WIDTH1 > 4'd9) ? 5'd18 : DATA_READ_WIDTH1; +localparam data_width_read2 = (DATA_READ_WIDTH2 > 4'd9) ? 5'd18 : DATA_READ_WIDTH2; + +initial begin + if ((DATA_WRITE_WIDTH1 < 1'd1) || (DATA_WRITE_WIDTH1 > 5'd18)) begin + $display("FIFO18KX2 instance %m DATA_WRITE_WIDTH1 set to incorrect value, %d. Values must be between 1 and 18.", DATA_WRITE_WIDTH1); + #1 $stop; + end + if ((DATA_READ_WIDTH1 < 1'd1) || (DATA_READ_WIDTH1 > 5'd18)) begin + $display("FIFO18KX2 instance %m DATA_READ_WIDTH1 set to incorrect value, %d. Values must be between 1 and 18.", DATA_READ_WIDTH1); + #1 $stop; + end + case(FIFO_TYPE1) + "SYNCHRONOUS" , + "ASYNCHRONOUS": begin end + default: begin + $display("\nError: FIFO18KX2 instance %m has parameter FIFO_TYPE1 set to %s. Valid values are SYNCHRONOUS, ASYNCHRONOUS\n", FIFO_TYPE1); + #1 $stop ; + end + endcase + + if ((DATA_WRITE_WIDTH2 < 1'd1) || (DATA_WRITE_WIDTH2 > 5'd18)) begin + $display("FIFO18KX2 instance %m DATA_WRITE_WIDTH2 set to incorrect value, %d. Values must be between 1 and 18.", DATA_WRITE_WIDTH2); + #1 $stop; + end + if ((DATA_READ_WIDTH2 < 1'd1) || (DATA_READ_WIDTH2 > 5'd18)) begin + $display("FIFO18KX2 instance %m DATA_READ_WIDTH2 set to incorrect value, %d. Values must be between 1 and 18.", DATA_READ_WIDTH2); + #1 $stop; + end + case(FIFO_TYPE2) + "SYNCHRONOUS" , + "ASYNCHRONOUS": begin end + default: begin + $display("\nError: FIFO18KX2 instance %m has parameter FIFO_TYPE2 set to %s. Valid values are SYNCHRONOUS, ASYNCHRONOUS\n", FIFO_TYPE2); + #1 $stop ; + end + endcase +end + +FIFO #( + .DATA_WRITE_WIDTH(data_width_write1), + .DATA_READ_WIDTH(data_width_read1), + .SYNC_FIFO(FIFO_TYPE1), + .PROG_FULL_THRESH(PROG_FULL_THRESH1), + .PROG_EMPTY_THRESH(PROG_EMPTY_THRESH1) +) +FIFO18K_1 ( + .WR_DATA(WR_DATA1), + .RD_DATA(RD_DATA1), + .EMPTY(EMPTY1), + .FULL(FULL1), + .OVERFLOW(OVERFLOW1), + .UNDERFLOW(UNDERFLOW1), + .RDEN(RD_EN1), + .WREN(WR_EN1), + .ALMOST_EMPTY(ALMOST_EMPTY1), + .ALMOST_FULL(ALMOST_FULL1), + .PROG_EMPTY(PROG_EMPTY1), + .PROG_FULL(PROG_FULL1), + .WRCLK(WR_CLK1), + .RDCLK(RD_CLK1), + .RESET(RESET1) +); + +FIFO #( + .DATA_WRITE_WIDTH(data_width_write2), + .DATA_READ_WIDTH(data_width_read2), + .SYNC_FIFO(FIFO_TYPE2), + .PROG_FULL_THRESH(PROG_FULL_THRESH2), + .PROG_EMPTY_THRESH(PROG_EMPTY_THRESH2) +) +FIFO18K_2 ( + .WR_DATA(WR_DATA2), + .RD_DATA(RD_DATA2), + .EMPTY(EMPTY2), + .FULL(FULL2), + .OVERFLOW(OVERFLOW2), + .UNDERFLOW(UNDERFLOW2), + .RDEN(RD_EN2), + .WREN(WR_EN2), + .ALMOST_EMPTY(ALMOST_EMPTY2), + .ALMOST_FULL(ALMOST_FULL2), + .PROG_EMPTY(PROG_EMPTY2), + .PROG_FULL(PROG_FULL2), + .WRCLK(WR_CLK2), + .RDCLK(RD_CLK2), + .RESET(RESET2) +); + +endmodule diff --git a/rapidsilicon/ip/fifo_generator/v1_0/sim/FIFO36K.v b/rapidsilicon/ip/fifo_generator/v1_0/sim/FIFO36K.v index d3daa5a8..9f1abccf 100644 --- a/rapidsilicon/ip/fifo_generator/v1_0/sim/FIFO36K.v +++ b/rapidsilicon/ip/fifo_generator/v1_0/sim/FIFO36K.v @@ -5,45 +5,66 @@ // -------------------------------------------------------------------------- module FIFO36K #( - parameter DATA_WIDTH = 36, // Supported Data Width 1, 2, 4, 9, 18, 36 - parameter SYNC_FIFO = "TRUE", // Synchronous or Asynchronous FIFO "TRUE"/"FALSE" - parameter PROG_FULL_THRESH = 12'b100000000000, // Threshold indicating that the FIFO buffer is considered Full - parameter PROG_EMPTY_THRESH = 12'b111111111100 // Threshold indicating that the FIFO buffer is considered Empty + parameter DATA_WRITE_WIDTH = 6'd36, // Supported Data Width 1 - 36 + parameter DATA_READ_WIDTH = 6'd36, // Supported Data Width 1 - 36 + parameter FIFO_TYPE = "SYNCHRONOUS", // Synchronous or Asynchronous + parameter PROG_FULL_THRESH = 12'hffa, // Threshold indicating that the FIFO buffer is considered Full + parameter PROG_EMPTY_THRESH = 12'h004 // Threshold indicating that the FIFO buffer is considered Empty ) ( - input wire [DATA_WIDTH-1:0] WR_DATA, // 36-bits Data coming inside FIFO - output wire [DATA_WIDTH-1:0] RD_DATA, // 36-bits Data coming out from FIFO + input wire [DATA_WRITE_WIDTH-1:0] WR_DATA, // 36-bits Data coming inside FIFO + output wire [DATA_READ_WIDTH-1:0] RD_DATA, // 36-bits Data coming out from FIFO output wire EMPTY, // 1-bit output: Empty Flag output wire FULL, // 1-bit output: Full Flag output wire OVERFLOW, // 1-bit output: Overflow Flag output wire UNDERFLOW, // 1-bit output: Underflow Flag - input wire RDEN, // 1-bit input: Read Enable - input wire WREN, // 1-bit input: Write Enable + input wire RD_EN, // 1-bit input: Read Enable + input wire WR_EN, // 1-bit input: Write Enable output wire ALMOST_EMPTY, // 1-bit output: This Flag is asserted when FIFO contains EMPTY plus one data words. output wire ALMOST_FULL, // 1-bit output: This Flag is asserted when FIFO contains FULL minus one data words. output wire PROG_EMPTY, // 1-bit output: Empty Watermark Flag output wire PROG_FULL, // 1-bit output: Full Watermark Flag - input wire WRCLK, // 1-bit input: Write Clock - input wire RDCLK, // 1-bit input: Read Clock + input wire WR_CLK, // 1-bit input: Write Clock + input wire RD_CLK, // 1-bit input: Read Clock input wire RESET // 1-bit input: Active Low Synchronous Reset ); -initial -begin - if (!(DATA_WIDTH == 1 || DATA_WIDTH == 2 || DATA_WIDTH == 4 || DATA_WIDTH == 9 || DATA_WIDTH == 18 || DATA_WIDTH == 36)) - begin - $error("Incorrect DATA_WIDTH: %0d\nEnter valid DATA_WIDTH: 1, 2, 4, 8, 9, 18, 36", DATA_WIDTH); - $finish; - end +localparam data_width_width = + (DATA_WRITE_WIDTH > 5'd18) ? 6'd36 : + (DATA_WRITE_WIDTH > 4'd9) ? 5'd18 : + DATA_WRITE_WIDTH; +localparam data_width_read = + (DATA_READ_WIDTH > 5'd18) ? 6'd36 : + (DATA_READ_WIDTH > 4'd9) ? 5'd18 : + DATA_READ_WIDTH; + +initial begin + if ((DATA_WRITE_WIDTH < 1'd1) || (DATA_WRITE_WIDTH > 6'd36)) begin + $display("FIFO36K instance %m DATA_WRITE_WIDTH set to incorrect value, %d. Values must be between 1 and 36.", DATA_WRITE_WIDTH); + #1 $stop; + end + if ((DATA_READ_WIDTH < 1'd1) || (DATA_READ_WIDTH > 6'd36)) begin + $display("FIFO36K instance %m DATA_READ_WIDTH set to incorrect value, %d. Values must be between 1 and 36.", DATA_READ_WIDTH); + #1 $stop; + end + case(FIFO_TYPE) + "SYNCHRONOUS" , + "ASYNCHRONOUS": begin end + default: begin + $display("\nError: FIFO36K instance %m has parameter FIFO_TYPE set to %s. Valid values are SYNCHRONOUS, ASYNCHRONOUS\n", FIFO_TYPE); + #1 $stop ; + end + endcase end FIFO #( - .DATA_WIDTH(DATA_WIDTH), - .SYNC_FIFO(SYNC_FIFO), + .DATA_WRITE_WIDTH(data_width_width), + .DATA_READ_WIDTH(data_width_read), + .SYNC_FIFO(FIFO_TYPE), .PROG_FULL_THRESH(PROG_FULL_THRESH), .PROG_EMPTY_THRESH(PROG_EMPTY_THRESH) ) -FIFO_insta_1( +FIFO ( .WR_DATA(WR_DATA), .RD_DATA(RD_DATA), .EMPTY(EMPTY), @@ -54,10 +75,10 @@ FIFO_insta_1( .PROG_FULL(PROG_FULL), .OVERFLOW(OVERFLOW), .UNDERFLOW(UNDERFLOW), - .RDEN(RDEN), - .WREN(WREN), - .WRCLK(WRCLK), - .RDCLK(RDCLK), + .RDEN(RD_EN), + .WREN(WR_EN), + .WRCLK(WR_CLK), + .RDCLK(RD_CLK), .RESET(RESET) ); endmodule \ No newline at end of file diff --git a/rapidsilicon/ip/fifo_generator/v1_0/sim/testbench.v b/rapidsilicon/ip/fifo_generator/v1_0/sim/testbench.v index 031551bb..2b77d983 100644 --- a/rapidsilicon/ip/fifo_generator/v1_0/sim/testbench.v +++ b/rapidsilicon/ip/fifo_generator/v1_0/sim/testbench.v @@ -52,12 +52,12 @@ initial begin $display("\n**** All Comparison Matched ****\n**** Simulation Passed ****"); else $display("%0d comparison(s) mismatched\nERROR: SIM: Simulation Failed", mismatch); + + $finish; end initial begin $dumpfile("fifo.vcd"); $dumpvars; - #600000; - $finish; end endmodule \ No newline at end of file