From 0763d2cb5f5d93ef24eb0fe14bf79ff2a3cb2fe1 Mon Sep 17 00:00:00 2001 From: bilalahmed-RS Date: Fri, 22 Sep 2023 17:30:19 +0500 Subject: [PATCH 1/8] Summary and details added for Boot clock --- .../ip/boot_clock/v1_0/boot_clock_gen.py | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/rapidsilicon/ip/boot_clock/v1_0/boot_clock_gen.py b/rapidsilicon/ip/boot_clock/v1_0/boot_clock_gen.py index 438a6c73..accc783a 100755 --- a/rapidsilicon/ip/boot_clock/v1_0/boot_clock_gen.py +++ b/rapidsilicon/ip/boot_clock/v1_0/boot_clock_gen.py @@ -56,7 +56,7 @@ def main(): # Parameter Dependency dictionary # Ports : Dependency - dep_dict = {} + dep_dict = {'period' : 'True'} # IP Builder. rs_builder = IP_Builder(device="gemini", ip_name="boot_clock", language="verilog") @@ -84,13 +84,27 @@ def main(): args = parser.parse_args() + + details = {"IP details": { + 'Name' : 'Boot Clock', + 'Version' : 'V1_0', + 'Interface' : 'Native', + 'Description' : 'This is an oscillator IP.'}} + + + summary = { + "Frequency in MHz =": 40, + } + + # Import JSON (Optional) ----------------------------------------------------------------------- if args.json: args = rs_builder.import_args_from_json(parser=parser, json_filename=args.json) # Export JSON Template (Optional) -------------------------------------------------------------- if args.json_template: - rs_builder.export_json_template(parser=parser, dep_dict=dep_dict) + rs_builder.export_json_template(parser=parser, dep_dict=dep_dict , summary=summary) + rs_builder.import_ip_details_json(json_filename=args.json, build_dir=args.build_dir ,details=details) # Create Wrapper ------------------------------------------------------------------------------- platform = OSFPGAPlatform(io=[], toolchain="raptor", device="gemini") From 6865a5f37a4228a9bff6cac23fbde60a1fac17bf Mon Sep 17 00:00:00 2001 From: bilalahmed-RS Date: Mon, 2 Oct 2023 14:16:50 +0500 Subject: [PATCH 2/8] PLL generator updates with backend support --- .../ip/boot_clock/v1_0/boot_clock_gen.py | 2 +- .../ip/boot_clock/v1_0/src/BOOT_CLOCK.v | 2 +- .../v1_0/litex_wrapper/pll_litex_wrapper.py | 59 ++++++++++--------- rapidsilicon/ip/pll/v1_0/pll_gen.py | 52 ++++++++++++---- rapidsilicon/ip/pll/v1_0/src/PLL.v | 8 +-- rapidsilicon/lib/common.py | 17 +++++- 6 files changed, 91 insertions(+), 49 deletions(-) diff --git a/rapidsilicon/ip/boot_clock/v1_0/boot_clock_gen.py b/rapidsilicon/ip/boot_clock/v1_0/boot_clock_gen.py index accc783a..a90729cc 100755 --- a/rapidsilicon/ip/boot_clock/v1_0/boot_clock_gen.py +++ b/rapidsilicon/ip/boot_clock/v1_0/boot_clock_gen.py @@ -93,7 +93,7 @@ def main(): summary = { - "Frequency in MHz =": 40, + "Frequency in MHz " : 40, } diff --git a/rapidsilicon/ip/boot_clock/v1_0/src/BOOT_CLOCK.v b/rapidsilicon/ip/boot_clock/v1_0/src/BOOT_CLOCK.v index de276cbe..1df1c975 100644 --- a/rapidsilicon/ip/boot_clock/v1_0/src/BOOT_CLOCK.v +++ b/rapidsilicon/ip/boot_clock/v1_0/src/BOOT_CLOCK.v @@ -7,7 +7,7 @@ // Copyright (c) 2023 Rapid Silicon, Inc. All rights reserved. // -module BOOT_CLOCK #( +module BOOT_CLOCK #( parameter PERIOD = 25.0 // Clock period for simulation purposes (nS) ) ( output reg O = 1'b0 // Clock output diff --git a/rapidsilicon/ip/pll/v1_0/litex_wrapper/pll_litex_wrapper.py b/rapidsilicon/ip/pll/v1_0/litex_wrapper/pll_litex_wrapper.py index 0b6a79b8..d07fa53d 100644 --- a/rapidsilicon/ip/pll/v1_0/litex_wrapper/pll_litex_wrapper.py +++ b/rapidsilicon/ip/pll/v1_0/litex_wrapper/pll_litex_wrapper.py @@ -38,7 +38,7 @@ def colorer(s, color="bright"): # PLL Wrapper ------------------------------------------------------------------------------------ class PLL(Module): - def __init__(self, platform, divide_clk_in_by_2, pll_mult, pll_div, clk_out0_div, clk_out1_div, clk_out2_div, clk_out3_div, **kwargs): + def __init__(self, platform, divided_clks, divide_clk_in_by_2, fast_clk_freq, ref_clk_freq, clk_out0_div, clk_out1_div, clk_out2_div, clk_out3_div, **kwargs): self.logger = logging.getLogger("PLL") self.logger.propagate = True @@ -51,8 +51,8 @@ def __init__(self, platform, divide_clk_in_by_2, pll_mult, pll_div, clk_out0_div self.logger.info(f"=================== PARAMETERS ====================") self.logger.info(f"DIVIDE_CLK_IN_BY_2 : {divide_clk_in_by_2}") - self.logger.info(f"PLL_MULT : {pll_mult}") - self.logger.info(f"PLL_DIV : {pll_div}") +# self.logger.info(f"PLL_MULT : {pll_mult}") +# self.logger.info(f"PLL_DIV : {pll_div}") self.logger.info(f"CLK_OUT0_DIV : {clk_out0_div}") self.logger.info(f"CLK_OUT1_DIV : {clk_out1_div}") self.logger.info(f"CLK_OUT2_DIV : {clk_out2_div}") @@ -73,32 +73,35 @@ def __init__(self, platform, divide_clk_in_by_2, pll_mult, pll_div, clk_out0_div self.GEARBOX_FAST_CLK = Signal() self.LOCK = Signal() - self.specials += Instance("PLL", - **kwargs, - p_DIVIDE_CLK_IN_BY_2 = Instance.PreformattedParam(divide_clk_in_by_2), - p_PLL_MULT = Instance.PreformattedParam(pll_mult), - p_PLL_DIV = Instance.PreformattedParam(pll_div), - p_CLK_OUT0_DIV = Instance.PreformattedParam(clk_out0_div), - p_CLK_OUT1_DIV = Instance.PreformattedParam(clk_out1_div), - p_CLK_OUT2_DIV = Instance.PreformattedParam(clk_out2_div), - p_CLK_OUT3_DIV = Instance.PreformattedParam(clk_out3_div), - - i_PLL_EN = self.PLL_EN, - i_CLK_IN = self.CLK_IN, - i_CLK_OUT0_EN = self.CLK_OUT0_EN, - i_CLK_OUT1_EN = self.CLK_OUT1_EN, - i_CLK_OUT2_EN = self.CLK_OUT2_EN, - i_CLK_OUT3_EN = self.CLK_OUT3_EN, - o_CLK_OUT0 = self.CLK_OUT0, - o_CLK_OUT1 = self.CLK_OUT1, - o_CLK_OUT2 = self.CLK_OUT2, - o_CLK_OUT3 = self.CLK_OUT3, - o_GEARBOX_FAST_CLK = self.GEARBOX_FAST_CLK, - o_LOCK = self.LOCK - ) - - self.add_sources(platform) + if divided_clks == 3: + self.specials += Instance("PLL", + **kwargs, + + p_DIVIDED_CLKS = Instance.PreformattedParam(divided_clks), + P_DIVIDE_CLK_IN_BY_2 = Instance.PreformattedParam(divide_clk_in_by_2), + p_FAST_CLK_FREQ = Instance.PreformattedParam(fast_clk_freq), + p_REF_CLK_FREQ = Instance.PreformattedParam(ref_clk_freq), + p_CLK_OUT0_DIV = Instance.PreformattedParam(clk_out0_div), + p_CLK_OUT1_DIV = Instance.PreformattedParam(clk_out1_div), + p_CLK_OUT2_DIV = Instance.PreformattedParam(clk_out2_div), + p_CLK_OUT3_DIV = Instance.PreformattedParam(clk_out3_div), + + i_PLL_EN = 1, + i_CLK_IN = self.CLK_IN, + i_CLK_OUT0_EN = self.CLK_OUT0_EN, + i_CLK_OUT1_EN = 0, + i_CLK_OUT2_EN = 0, + i_CLK_OUT3_EN = 0, + o_CLK_OUT0 = self.CLK_OUT0, + o_CLK_OUT1 = self.CLK_OUT1, + o_CLK_OUT2 = self.CLK_OUT2, + o_CLK_OUT3 = self.CLK_OUT3, + o_GEARBOX_FAST_CLK = self.GEARBOX_FAST_CLK, + o_LOCK = self.LOCK + ) + + self.add_sources(platform) @staticmethod def add_sources(platform): diff --git a/rapidsilicon/ip/pll/v1_0/pll_gen.py b/rapidsilicon/ip/pll/v1_0/pll_gen.py index aa1b99b3..f29943ca 100755 --- a/rapidsilicon/ip/pll/v1_0/pll_gen.py +++ b/rapidsilicon/ip/pll/v1_0/pll_gen.py @@ -39,15 +39,16 @@ def get_clkin_ios(): # AXI RAM Wrapper ---------------------------------------------------------------------------------- class PLLWrapper(Module): - def __init__(self, platform, divide_clk_in_by_2, pll_mult, pll_div, clk_out0_div, clk_out1_div, clk_out2_div, clk_out3_div): + def __init__(self, platform, divided_clks, divide_clk_in_by_2, fast_clk_freq, ref_clk_freq, clk_out0_div, clk_out1_div, clk_out2_div, clk_out3_div): self.clock_domains.cd_sys = ClockDomain() # AXI-RAM ---------------------------------------------------------------------------------- self.submodules.pll = pll = PLL(platform, + divided_clks = divided_clks, divide_clk_in_by_2 = divide_clk_in_by_2, - pll_mult = pll_mult, - pll_div = pll_div, + fast_clk_freq = fast_clk_freq, + ref_clk_freq = ref_clk_freq, clk_out0_div = clk_out0_div, clk_out1_div = clk_out1_div, clk_out2_div = clk_out2_div, @@ -94,6 +95,7 @@ def main(): # Core fix value parameters. core_fix_param_group = parser.add_argument_group(title="Core fix parameters") + core_fix_param_group.add_argument("--divided_clks", type=int, default=4, choices=[1,2,3,4], help="Divided clocks to be generated from fast clock") core_fix_param_group.add_argument("--clk_out0_div", type=int, default=2, choices=[2,3,4,5,6,7,8,10,12,16,20.24,32,40,48,64], help="CLK_OUT0 divider value") core_fix_param_group.add_argument("--clk_out1_div", type=int, default=2, choices=[2,3,4,5,6,7,8,10,12,16,20.24,32,40,48,64], help="CLK_OUT1 divider value") core_fix_param_group.add_argument("--clk_out2_div", type=int, default=2, choices=[2,3,4,5,6,7,8,10,12,16,20.24,32,40,48,64], help="CLK_OUT2 divider value") @@ -101,22 +103,19 @@ def main(): # Core range value parameters. core_range_param_group = parser.add_argument_group(title="Core range parameters") - core_range_param_group.add_argument("--pll_mult", type=int, default=16, choices=range(16,1000), help="RAM Address Width") - core_range_param_group.add_argument("--pll_div", type=int, default=1, choices=range(1, 63), help="RAM ID Width") + core_range_param_group.add_argument("--fast_clk_freq", type=int, default=1600, choices=range(800,3201), help="Freq in MHz") + core_range_param_group.add_argument("--ref_clk_freq", type=int, default=5, choices=range(5, 1201), help="RAM ID Width") # Core bool value parameters. core_bool_param_group = parser.add_argument_group(title="Core bool parameters") core_bool_param_group.add_argument("--divide_clk_in_by_2", type=bool, default=False, help="RAM Pipelined Output") - # Core file path parameters. - # core_file_path_group = parser.add_argument_group(title="Core file path parameters") - # core_file_path_group.add_argument("--file_path", type=argparse.FileType('r'), help="File Path for memory initialization file") # Build Parameters. build_group = parser.add_argument_group(title="Build parameters") build_group.add_argument("--build", action="store_true", help="Build Core") build_group.add_argument("--build-dir", default="./", help="Build Directory") - build_group.add_argument("--build-name", default="pll_wrapper", help="Build Folder Name, Build RTL File Name and Module Name") + build_group.add_argument("--build-name", default="pll_wrapper", help="Build Folder Name, Build RTL File Name and Module Name") # JSON Import/Template json_group = parser.add_argument_group(title="JSON Parameters") @@ -125,20 +124,49 @@ def main(): args = parser.parse_args() + if (args.divided_clks == 1): + option_strings_to_remove = ['--clk_out1_div', '--clk_out2_div' , '--clk_out3_div'] + parser._actions = [action for action in parser._actions if action.option_strings and action.option_strings[0] not in option_strings_to_remove] + +# parser._actions = [action for argument_name in option_strings_to_remove: +# for action in parser._actions: +# if action.option_strings and argument_name in action.option_strings: +# parser._remove_action(action)] + elif(args.divided_clks == 2): + option_strings_to_remove = ['--clk_out2_div' , '--clk_out3_div'] + parser._actions = [action for action in parser._actions if action.option_strings and action.option_strings[0] not in option_strings_to_remove] + elif(args.divided_clks == 3): + option_strings_to_remove = ['--clk_out3_div'] + parser._actions = [action for action in parser._actions if action.option_strings and action.option_strings[0] not in option_strings_to_remove] + + details = {"IP details": { + 'Name' : 'PLL', + 'Version' : 'V1_0', + 'Interface' : 'Native', + 'Description' : "PLL IP core is a key component in chip design, used to generate stable clock signals from an input reference clock. Its essential for precise synchronization and clock management in modern integrated circuits, ensuring reliable performance across various applications."}} + + + summary = { + "Frequency in MHz =": 40, + } + # Import JSON (Optional) ----------------------------------------------------------------------- if args.json: args = rs_builder.import_args_from_json(parser=parser, json_filename=args.json) + rs_builder.import_ip_details_json(build_dir=args.build_dir ,details=details , build_name = args.build_name, version = "v1_0") # Export JSON Template (Optional) -------------------------------------------------------------- if args.json_template: - rs_builder.export_json_template(parser=parser, dep_dict=dep_dict) + rs_builder.export_json_template(parser=parser, dep_dict=dep_dict , summary=summary) + # Create Wrapper ------------------------------------------------------------------------------- platform = OSFPGAPlatform(io=[], toolchain="raptor", device="gemini") module = PLLWrapper(platform, divide_clk_in_by_2=args.divide_clk_in_by_2, - pll_mult=args.pll_mult, - pll_div=args.pll_div, + divided_clks=args.divided_clks, + fast_clk_freq=args.fast_clk_freq, + ref_clk_freq=args.ref_clk_freq, clk_out0_div=args.clk_out0_div, clk_out1_div=args.clk_out1_div, clk_out2_div=args.clk_out2_div, diff --git a/rapidsilicon/ip/pll/v1_0/src/PLL.v b/rapidsilicon/ip/pll/v1_0/src/PLL.v index 27ec23ed..ca504a69 100644 --- a/rapidsilicon/ip/pll/v1_0/src/PLL.v +++ b/rapidsilicon/ip/pll/v1_0/src/PLL.v @@ -81,10 +81,10 @@ module PLL #( parameter DIVIDE_CLK_IN_BY_2 = "FALSE", // Enable input divider (TRUE/FALSE) parameter PLL_MULT = 16, // Clock multiplier value (16-1000) parameter PLL_DIV = 1, // Clock divider value (1-63) - parameter CLK_OUT0_DIV = 2, // CLK_OUT0 divider value (2,3,4,5,6,7,8,10,12,16,20.24.32.40,48,64) - parameter CLK_OUT1_DIV = 2, // CLK_OUT1 divider value (2,3,4,5,6,7,8,10,12,16,20.24.32.40,48,64) - parameter CLK_OUT2_DIV = 2, // CLK_OUT2 divider value (2,3,4,5,6,7,8,10,12,16,20.24.32.40,48,64) - parameter CLK_OUT3_DIV = 2 // CLK_OUT3 divider value (2,3,4,5,6,7,8,10,12,16,20.24.32.40,48,64) + parameter CLK_OUT0_DIV = 2, // CLK_OUT0 divider value (2,3,4,5,6,7,8,10,12,16,20.24.32.40,48,64) () + parameter CLK_OUT1_DIV = 2, // CLK_OUT1 divider value (2,3,4,5,6,7,8,10,12,16,20.24.32.40,48,64) () + parameter CLK_OUT2_DIV = 2, // CLK_OUT2 divider value (2,3,4,5,6,7,8,10,12,16,20.24.32.40,48,64) () + parameter CLK_OUT3_DIV = 2 // CLK_OUT3 divider value (2,3,4,5,6,7,8,10,12,16,20.24.32.40,48,64) () ) ( input PLL_EN, // PLL Enable input CLK_IN, // Clock input diff --git a/rapidsilicon/lib/common.py b/rapidsilicon/lib/common.py index c3f6cad7..4d91ca8b 100644 --- a/rapidsilicon/lib/common.py +++ b/rapidsilicon/lib/common.py @@ -41,7 +41,7 @@ def add_wrapper_header(self, filename): # JSON template for GUI parsing - def export_json_template(self, parser, dep_dict): + def export_json_template(self, parser, dep_dict, summary): # Get "core_fix_param_group" group. core_fix_param_group = None @@ -171,6 +171,11 @@ def export_json_template(self, parser, dep_dict): param_json["parameters"][i].update(disable = dep_dict[param_json["parameters"][i]['parameter']]) + #Append summary in JSON + summary_temp = {"Summary": summary} + param_json.update(summary_temp) + + # Append Build and Json params to final json for i in range(len(build_param_list)): @@ -186,7 +191,13 @@ def import_args_from_json(self, parser, json_filename): t_args.__dict__.update(json.load(f)) args = parser.parse_args(namespace=t_args) return args - + + def import_ip_details_json(self, build_dir,details, build_name, version ): + self.build_name = build_name + self.build_path = os.path.join(build_dir, "rapidsilicon", "ip", self.ip_name, version, build_name) + new_json_filename = os.path.join(self.build_path, "details.json") + with open(new_json_filename, "w") as f: + json.dump(details, f, indent=4, default=None,) def prepare(self, build_dir, build_name, version): @@ -296,7 +307,7 @@ def generate_tcl(self): def generate_wrapper(self, platform, module): assert self.prepared - build_path = self.build_path + "build_dir" + build_path = "litex_build" build_filename = os.path.join(build_path, self.build_name) + ".v" # Build LiteX module. From 88a3b6299eed150388017383cba2ab534c337da4 Mon Sep 17 00:00:00 2001 From: bilalahmed-RS Date: Mon, 2 Oct 2023 14:22:27 +0500 Subject: [PATCH 3/8] axi_async fifo changes --- .../axi_async_fifo/v1_0/axi_async_fifo_gen.py | 68 +++++++------------ 1 file changed, 24 insertions(+), 44 deletions(-) diff --git a/rapidsilicon/ip/axi_async_fifo/v1_0/axi_async_fifo_gen.py b/rapidsilicon/ip/axi_async_fifo/v1_0/axi_async_fifo_gen.py index 5f6f0c6b..82975c00 100755 --- a/rapidsilicon/ip/axi_async_fifo/v1_0/axi_async_fifo_gen.py +++ b/rapidsilicon/ip/axi_async_fifo/v1_0/axi_async_fifo_gen.py @@ -7,12 +7,9 @@ import os import sys import json -import logging import argparse import math -from datetime import datetime - from litex_wrapper.axi_async_fifo_litex_wrapper import AXIASYNCFIFO from migen import * @@ -91,10 +88,6 @@ def main(): # IP Builder. rs_builder = IP_Builder(device="gemini", ip_name="axi_async_fifo", language="verilog") - logging.info("===================================================") - logging.info("IP : %s", rs_builder.ip_name.upper()) - logging.info(("===================================================")) - # Core fix value parameters. core_fix_param_group = parser.add_argument_group(title="Core fix parameters") core_fix_param_group.add_argument("--fifo_depth", type=int, default=4096, choices=[8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192,16384,32768], help="FIFO Depth.") @@ -119,17 +112,31 @@ def main(): args = parser.parse_args() + + details = { "IP details": { + 'Name' : 'axi_asynchronus_fifo', + 'Version' : 'V1_0', + 'Interface' : 'AXI', + 'Description' : 'The AXI Async FIFO is an AXI full compliant customize-able asynchronous FIFO. It can be used to store and retrieve ordered data at different clock domains, while using optimal resources.'}} + + + summary = { + "AXI Data width programmed": args.data_width, + "AXI ID width programmed": args.id_width, + "Memory Type selected": "Single Dual Port", + } + + + # Import JSON (Optional) ----------------------------------------------------------------------- if args.json: args = rs_builder.import_args_from_json(parser=parser, json_filename=args.json) + rs_builder.import_ip_details_json(build_dir=args.build_dir ,details=details , build_name = args.build_name, version = "v1_0") # Export JSON Template (Optional) -------------------------------------------------------------- - if args.json_template: - rs_builder.export_json_template(parser=parser, dep_dict=dep_dict) - - # Create Wrapper ------------------------------------------------------------------------------- + platform = OSFPGAPlatform(io=[], toolchain="raptor", device="gemini") module = AXIASYNCFIFOWrapper(platform, data_width = args.data_width, @@ -152,39 +159,12 @@ def main(): platform = platform, module = module, ) - - # IP_ID Parameter - now = datetime.now() - my_year = now.year - 2022 - year = (bin(my_year)[2:]).zfill(7) # 7-bits # Removing '0b' prefix = [2:] - month = (bin(now.month)[2:]).zfill(4) # 4-bits - day = (bin(now.day)[2:]).zfill(5) # 5-bits - mod_hour = now.hour % 12 # 12 hours Format - hour = (bin(mod_hour)[2:]).zfill(4) # 4-bits - minute = (bin(now.minute)[2:]).zfill(6) # 6-bits - second = (bin(now.second)[2:]).zfill(6) # 6-bits - - # Concatenation for IP_ID Parameter - ip_id = ("{}{}{}{}{}{}").format(year, day, month, hour, minute, second) - ip_id = ("32'h{}").format(hex(int(ip_id,2))[2:]) - - # IP_VERSION parameter - # Base _ Major _ Minor - ip_version = "00000000_00000000_0000000000000001" - ip_version = ("32'h{}").format(hex(int(ip_version, 2))[2:]) - - wrapper = os.path.join(args.build_dir, "rapidsilicon", "ip", "axi_async_fifo", "v1_0", args.build_name, "src",args.build_name+".v") - new_lines = [] - with open (wrapper, "r") as file: - lines = file.readlines() - for i, line in enumerate(lines): - if ("module {}".format(args.build_name)) in line: - new_lines.append("module {} #(\n\tparameter IP_TYPE \t\t= \"ASYNCFFO\",\n\tparameter IP_VERSION \t= {}, \n\tparameter IP_ID \t\t= {}\n)\n(".format(args.build_name, ip_version, ip_id)) - else: - new_lines.append(line) - - with open(os.path.join(wrapper), "w") as file: - file.writelines(new_lines) + + if args.json_template: + rs_builder.export_json_template(parser=parser, dep_dict=dep_dict , summary=summary) + #Exporting Details.json + + if __name__ == "__main__": main() From 2b43a83c1fbcc333426486df35874e16b846219c Mon Sep 17 00:00:00 2001 From: bilalahmed-RS Date: Mon, 2 Oct 2023 17:09:51 +0500 Subject: [PATCH 4/8] updating common.py into main --- rapidsilicon/ip/pll/v1_0/pll_gen.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/rapidsilicon/ip/pll/v1_0/pll_gen.py b/rapidsilicon/ip/pll/v1_0/pll_gen.py index f29943ca..fc989164 100755 --- a/rapidsilicon/ip/pll/v1_0/pll_gen.py +++ b/rapidsilicon/ip/pll/v1_0/pll_gen.py @@ -95,7 +95,7 @@ def main(): # Core fix value parameters. core_fix_param_group = parser.add_argument_group(title="Core fix parameters") - core_fix_param_group.add_argument("--divided_clks", type=int, default=4, choices=[1,2,3,4], help="Divided clocks to be generated from fast clock") + core_fix_param_group.add_argument("--divided_clks", type=int, default=4, choices=[1,2,3,4], help="Divided clocks to be generated from fast clock") core_fix_param_group.add_argument("--clk_out0_div", type=int, default=2, choices=[2,3,4,5,6,7,8,10,12,16,20.24,32,40,48,64], help="CLK_OUT0 divider value") core_fix_param_group.add_argument("--clk_out1_div", type=int, default=2, choices=[2,3,4,5,6,7,8,10,12,16,20.24,32,40,48,64], help="CLK_OUT1 divider value") core_fix_param_group.add_argument("--clk_out2_div", type=int, default=2, choices=[2,3,4,5,6,7,8,10,12,16,20.24,32,40,48,64], help="CLK_OUT2 divider value") @@ -104,11 +104,11 @@ def main(): # Core range value parameters. core_range_param_group = parser.add_argument_group(title="Core range parameters") core_range_param_group.add_argument("--fast_clk_freq", type=int, default=1600, choices=range(800,3201), help="Freq in MHz") - core_range_param_group.add_argument("--ref_clk_freq", type=int, default=5, choices=range(5, 1201), help="RAM ID Width") + core_range_param_group.add_argument("--ref_clk_freq", type=int, default=5, choices=range(5, 1201), help="Freq in MHz") # Core bool value parameters. core_bool_param_group = parser.add_argument_group(title="Core bool parameters") - core_bool_param_group.add_argument("--divide_clk_in_by_2", type=bool, default=False, help="RAM Pipelined Output") + core_bool_param_group.add_argument("--divide_clk_in_by_2", type=bool, default=False, help="Divide input clock by 2") # Build Parameters. @@ -145,11 +145,11 @@ def main(): 'Interface' : 'Native', 'Description' : "PLL IP core is a key component in chip design, used to generate stable clock signals from an input reference clock. Its essential for precise synchronization and clock management in modern integrated circuits, ensuring reliable performance across various applications."}} - summary = { - "Frequency in MHz =": 40, + "Number of divided clocks ": args.divided_clks, + "Fast clock frequency selected": args.fast_clk_freq, + "Input reference clock frequency": args.ref_clk_freq, } - # Import JSON (Optional) ----------------------------------------------------------------------- if args.json: args = rs_builder.import_args_from_json(parser=parser, json_filename=args.json) @@ -171,7 +171,7 @@ def main(): clk_out1_div=args.clk_out1_div, clk_out2_div=args.clk_out2_div, clk_out3_div=args.clk_out3_div) - +a # Build Project -------------------------------------------------------------------------------- if args.build: rs_builder.prepare( From dac2456477efd55044571aea02d3ca03ba18d7f7 Mon Sep 17 00:00:00 2001 From: bilalahmed-RS Date: Wed, 4 Oct 2023 10:38:12 +0500 Subject: [PATCH 5/8] PLL generator parameters updated --- .../v1_0/litex_wrapper/pll_litex_wrapper.py | 155 +++++++++++++++--- rapidsilicon/ip/pll/v1_0/pll_gen.py | 2 +- 2 files changed, 129 insertions(+), 28 deletions(-) diff --git a/rapidsilicon/ip/pll/v1_0/litex_wrapper/pll_litex_wrapper.py b/rapidsilicon/ip/pll/v1_0/litex_wrapper/pll_litex_wrapper.py index d07fa53d..c2d1eda9 100644 --- a/rapidsilicon/ip/pll/v1_0/litex_wrapper/pll_litex_wrapper.py +++ b/rapidsilicon/ip/pll/v1_0/litex_wrapper/pll_litex_wrapper.py @@ -22,6 +22,32 @@ logging.info(f'Log started at {timestamp}') # Helpers ------------------------------------------------------------------------------------------ + +def freq_calc(self, fast_clk_freq, ref_clk_freq, c_range, d_range): + self.product = Signal() + self.ready = Signal() + a = fast_clk_freq + b = ref_clk_freq + c_range = 1000 + d_range = 63 + # Nested loop for iterating over c and d + for c in range(c_range): + for d in range(d_range): + # Calculate 2 * (a / b) + product_candidate = 2 * (a/ b) + print("product_candidate",product_candidate) + print(f" values found - C: {c}, D: {d}") + # Check if the candidate product matches the formula with c and d + print("candidate match", ((c+1) / (d+1))) + if product_candidate == ((c+1) / (d+1)): + # If a match is found, assign c, d, and the product to the respective signals + print(f"Matching values found - C: {c}, D: {d}") + pll_mult = c + 1 + pll_div = d + 1 + return pll_mult, pll_div + #break + + class Open(Signal): pass def colorer(s, color="bright"): @@ -73,35 +99,110 @@ def __init__(self, platform, divided_clks, divide_clk_in_by_2, fast_clk_freq, re self.GEARBOX_FAST_CLK = Signal() self.LOCK = Signal() + pll_mult, pll_div = freq_calc(self, fast_clk_freq, ref_clk_freq, c_range=63, d_range=1000) + print("pll_mult", pll_mult , "pll_div", pll_div) - if divided_clks == 3: + if divided_clks == 4: self.specials += Instance("PLL", - **kwargs, - - p_DIVIDED_CLKS = Instance.PreformattedParam(divided_clks), - P_DIVIDE_CLK_IN_BY_2 = Instance.PreformattedParam(divide_clk_in_by_2), - p_FAST_CLK_FREQ = Instance.PreformattedParam(fast_clk_freq), - p_REF_CLK_FREQ = Instance.PreformattedParam(ref_clk_freq), - p_CLK_OUT0_DIV = Instance.PreformattedParam(clk_out0_div), - p_CLK_OUT1_DIV = Instance.PreformattedParam(clk_out1_div), - p_CLK_OUT2_DIV = Instance.PreformattedParam(clk_out2_div), - p_CLK_OUT3_DIV = Instance.PreformattedParam(clk_out3_div), - - i_PLL_EN = 1, - i_CLK_IN = self.CLK_IN, - i_CLK_OUT0_EN = self.CLK_OUT0_EN, - i_CLK_OUT1_EN = 0, - i_CLK_OUT2_EN = 0, - i_CLK_OUT3_EN = 0, - o_CLK_OUT0 = self.CLK_OUT0, - o_CLK_OUT1 = self.CLK_OUT1, - o_CLK_OUT2 = self.CLK_OUT2, - o_CLK_OUT3 = self.CLK_OUT3, - o_GEARBOX_FAST_CLK = self.GEARBOX_FAST_CLK, - o_LOCK = self.LOCK - ) - - self.add_sources(platform) + **kwargs, + p_DIVIDE_CLK_IN_BY_2 = Instance.PreformattedParam(divide_clk_in_by_2), + p_PLL_MULT = Instance.PreformattedParam(pll_mult), + p_PLL_DIV = Instance.PreformattedParam(pll_div), + p_CLK_OUT0_DIV = Instance.PreformattedParam(clk_out0_div), + p_CLK_OUT1_DIV = Instance.PreformattedParam(clk_out1_div), + p_CLK_OUT2_DIV = Instance.PreformattedParam(clk_out2_div), + p_CLK_OUT3_DIV = Instance.PreformattedParam(clk_out3_div), + + i_PLL_EN = 1, + i_CLK_IN = self.CLK_IN, + i_CLK_OUT0_EN = 1, + i_CLK_OUT1_EN = 1, + i_CLK_OUT2_EN = 1, + i_CLK_OUT3_EN = 1, + o_CLK_OUT0 = self.CLK_OUT0, + o_CLK_OUT1 = self.CLK_OUT1, + o_CLK_OUT2 = self.CLK_OUT2, + o_CLK_OUT3 = self.CLK_OUT3, + o_GEARBOX_FAST_CLK = self.GEARBOX_FAST_CLK, + o_LOCK = self.LOCK + ) + elif divided_clks == 3: + self.specials += Instance("PLL", + **kwargs, + p_DIVIDE_CLK_IN_BY_2 = Instance.PreformattedParam(divide_clk_in_by_2), + p_PLL_MULT = Instance.PreformattedParam(pll_mult), + p_PLL_DIV = Instance.PreformattedParam(pll_div), + p_CLK_OUT0_DIV = Instance.PreformattedParam(clk_out0_div), + p_CLK_OUT1_DIV = Instance.PreformattedParam(clk_out1_div), + p_CLK_OUT2_DIV = Instance.PreformattedParam(clk_out2_div), + p_CLK_OUT3_DIV = Instance.PreformattedParam(clk_out3_div), + + i_PLL_EN = 1, + i_CLK_IN = self.CLK_IN, + i_CLK_OUT0_EN = 1, + i_CLK_OUT1_EN = 1, + i_CLK_OUT2_EN = 1, + i_CLK_OUT3_EN = 0, + o_CLK_OUT0 = self.CLK_OUT0, + o_CLK_OUT1 = self.CLK_OUT1, + o_CLK_OUT2 = self.CLK_OUT2, +# o_CLK_OUT3 = self.CLK_OUT3, + o_GEARBOX_FAST_CLK = self.GEARBOX_FAST_CLK, + o_LOCK = self.LOCK + ) + + elif divided_clks == 2: + self.specials += Instance("PLL", + **kwargs, + p_DIVIDE_CLK_IN_BY_2 = Instance.PreformattedParam(divide_clk_in_by_2), + p_PLL_MULT = Instance.PreformattedParam(pll_mult), + p_PLL_DIV = Instance.PreformattedParam(pll_div), + p_CLK_OUT0_DIV = Instance.PreformattedParam(clk_out0_div), + p_CLK_OUT1_DIV = Instance.PreformattedParam(clk_out1_div), + p_CLK_OUT2_DIV = Instance.PreformattedParam(clk_out2_div), + p_CLK_OUT3_DIV = Instance.PreformattedParam(clk_out3_div), + + i_PLL_EN = 1, + i_CLK_IN = self.CLK_IN, + i_CLK_OUT0_EN = 1, + i_CLK_OUT1_EN = 1, + i_CLK_OUT2_EN = 0, + i_CLK_OUT3_EN = 0, + o_CLK_OUT0 = self.CLK_OUT0, + o_CLK_OUT1 = self.CLK_OUT1, +# o_CLK_OUT2 = self.CLK_OUT2, +# o_CLK_OUT3 = self.CLK_OUT3, + o_GEARBOX_FAST_CLK = self.GEARBOX_FAST_CLK, + o_LOCK = self.LOCK + ) + + elif divided_clks == 1: + self.specials += Instance("PLL", + **kwargs, + p_DIVIDE_CLK_IN_BY_2 = Instance.PreformattedParam(divide_clk_in_by_2), + p_PLL_MULT = Instance.PreformattedParam(pll_mult), + p_PLL_DIV = Instance.PreformattedParam(pll_div), + p_CLK_OUT0_DIV = Instance.PreformattedParam(clk_out0_div), + p_CLK_OUT1_DIV = Instance.PreformattedParam(clk_out1_div), + p_CLK_OUT2_DIV = Instance.PreformattedParam(clk_out2_div), + p_CLK_OUT3_DIV = Instance.PreformattedParam(clk_out3_div), + + i_PLL_EN = 1, + i_CLK_IN = self.CLK_IN, + i_CLK_OUT0_EN = 1, + i_CLK_OUT1_EN = 0, + i_CLK_OUT2_EN = 0, + i_CLK_OUT3_EN = 0, + o_CLK_OUT0 = self.CLK_OUT0, +# o_CLK_OUT1 = self.CLK_OUT1, +# o_CLK_OUT2 = self.CLK_OUT2, +# o_CLK_OUT3 = self.CLK_OUT3, + o_GEARBOX_FAST_CLK = self.GEARBOX_FAST_CLK, + o_LOCK = self.LOCK + ) + + + self.add_sources(platform) @staticmethod def add_sources(platform): diff --git a/rapidsilicon/ip/pll/v1_0/pll_gen.py b/rapidsilicon/ip/pll/v1_0/pll_gen.py index fc989164..a97b1dbe 100755 --- a/rapidsilicon/ip/pll/v1_0/pll_gen.py +++ b/rapidsilicon/ip/pll/v1_0/pll_gen.py @@ -171,7 +171,7 @@ def main(): clk_out1_div=args.clk_out1_div, clk_out2_div=args.clk_out2_div, clk_out3_div=args.clk_out3_div) -a + # Build Project -------------------------------------------------------------------------------- if args.build: rs_builder.prepare( From 493a6398d4daea0715d45091ae8994c4d0df611f Mon Sep 17 00:00:00 2001 From: bilalahmed-RS Date: Wed, 4 Oct 2023 14:47:15 +0500 Subject: [PATCH 6/8] Revert "axi_async fifo changes" This reverts commit 88a3b6299eed150388017383cba2ab534c337da4. --- .../axi_async_fifo/v1_0/axi_async_fifo_gen.py | 68 ++++++++++++------- 1 file changed, 44 insertions(+), 24 deletions(-) diff --git a/rapidsilicon/ip/axi_async_fifo/v1_0/axi_async_fifo_gen.py b/rapidsilicon/ip/axi_async_fifo/v1_0/axi_async_fifo_gen.py index 82975c00..5f6f0c6b 100755 --- a/rapidsilicon/ip/axi_async_fifo/v1_0/axi_async_fifo_gen.py +++ b/rapidsilicon/ip/axi_async_fifo/v1_0/axi_async_fifo_gen.py @@ -7,9 +7,12 @@ import os import sys import json +import logging import argparse import math +from datetime import datetime + from litex_wrapper.axi_async_fifo_litex_wrapper import AXIASYNCFIFO from migen import * @@ -88,6 +91,10 @@ def main(): # IP Builder. rs_builder = IP_Builder(device="gemini", ip_name="axi_async_fifo", language="verilog") + logging.info("===================================================") + logging.info("IP : %s", rs_builder.ip_name.upper()) + logging.info(("===================================================")) + # Core fix value parameters. core_fix_param_group = parser.add_argument_group(title="Core fix parameters") core_fix_param_group.add_argument("--fifo_depth", type=int, default=4096, choices=[8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192,16384,32768], help="FIFO Depth.") @@ -112,31 +119,17 @@ def main(): args = parser.parse_args() - - details = { "IP details": { - 'Name' : 'axi_asynchronus_fifo', - 'Version' : 'V1_0', - 'Interface' : 'AXI', - 'Description' : 'The AXI Async FIFO is an AXI full compliant customize-able asynchronous FIFO. It can be used to store and retrieve ordered data at different clock domains, while using optimal resources.'}} - - - summary = { - "AXI Data width programmed": args.data_width, - "AXI ID width programmed": args.id_width, - "Memory Type selected": "Single Dual Port", - } - - - # Import JSON (Optional) ----------------------------------------------------------------------- if args.json: args = rs_builder.import_args_from_json(parser=parser, json_filename=args.json) - rs_builder.import_ip_details_json(build_dir=args.build_dir ,details=details , build_name = args.build_name, version = "v1_0") # Export JSON Template (Optional) -------------------------------------------------------------- + if args.json_template: + rs_builder.export_json_template(parser=parser, dep_dict=dep_dict) + - # Create Wrapper ------------------------------------------------------------------------------- + # Create Wrapper ------------------------------------------------------------------------------- platform = OSFPGAPlatform(io=[], toolchain="raptor", device="gemini") module = AXIASYNCFIFOWrapper(platform, data_width = args.data_width, @@ -159,12 +152,39 @@ def main(): platform = platform, module = module, ) - - if args.json_template: - rs_builder.export_json_template(parser=parser, dep_dict=dep_dict , summary=summary) - #Exporting Details.json - - + + # IP_ID Parameter + now = datetime.now() + my_year = now.year - 2022 + year = (bin(my_year)[2:]).zfill(7) # 7-bits # Removing '0b' prefix = [2:] + month = (bin(now.month)[2:]).zfill(4) # 4-bits + day = (bin(now.day)[2:]).zfill(5) # 5-bits + mod_hour = now.hour % 12 # 12 hours Format + hour = (bin(mod_hour)[2:]).zfill(4) # 4-bits + minute = (bin(now.minute)[2:]).zfill(6) # 6-bits + second = (bin(now.second)[2:]).zfill(6) # 6-bits + + # Concatenation for IP_ID Parameter + ip_id = ("{}{}{}{}{}{}").format(year, day, month, hour, minute, second) + ip_id = ("32'h{}").format(hex(int(ip_id,2))[2:]) + + # IP_VERSION parameter + # Base _ Major _ Minor + ip_version = "00000000_00000000_0000000000000001" + ip_version = ("32'h{}").format(hex(int(ip_version, 2))[2:]) + + wrapper = os.path.join(args.build_dir, "rapidsilicon", "ip", "axi_async_fifo", "v1_0", args.build_name, "src",args.build_name+".v") + new_lines = [] + with open (wrapper, "r") as file: + lines = file.readlines() + for i, line in enumerate(lines): + if ("module {}".format(args.build_name)) in line: + new_lines.append("module {} #(\n\tparameter IP_TYPE \t\t= \"ASYNCFFO\",\n\tparameter IP_VERSION \t= {}, \n\tparameter IP_ID \t\t= {}\n)\n(".format(args.build_name, ip_version, ip_id)) + else: + new_lines.append(line) + + with open(os.path.join(wrapper), "w") as file: + file.writelines(new_lines) if __name__ == "__main__": main() From 23667cf7b54a487faa157108fc97f069fdd19fbd Mon Sep 17 00:00:00 2001 From: bilalahmed-RS Date: Wed, 4 Oct 2023 14:50:19 +0500 Subject: [PATCH 7/8] Axi async fifo updated wih details and summary --- .../ip/axi_async_fifo/v1_0/axi_async_fifo_gen.py | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/rapidsilicon/ip/axi_async_fifo/v1_0/axi_async_fifo_gen.py b/rapidsilicon/ip/axi_async_fifo/v1_0/axi_async_fifo_gen.py index 5f6f0c6b..4897f930 100755 --- a/rapidsilicon/ip/axi_async_fifo/v1_0/axi_async_fifo_gen.py +++ b/rapidsilicon/ip/axi_async_fifo/v1_0/axi_async_fifo_gen.py @@ -119,10 +119,23 @@ def main(): args = parser.parse_args() + + details = { "IP details": { + 'Name' : 'axi_asynchronus_fifo', + 'Version' : 'V1_0', + 'Interface' : 'AXI', + 'Description' : 'The AXI Async FIFO is an AXI full compliant customize-able asynchronous FIFO. It can be used to store and retrieve ordered data at different clock domains, while using optimal resources.'}} + + + summary = { + "AXI Data width programmed": args.data_width, + "AXI ID width programmed": args.id_width, + "Memory Type selected": "Single Dual Port", + } # Import JSON (Optional) ----------------------------------------------------------------------- if args.json: args = rs_builder.import_args_from_json(parser=parser, json_filename=args.json) - + rs_builder.import_ip_details_json(build_dir=args.build_dir ,details=details , build_name = args.build_name, version = "v1_0") # Export JSON Template (Optional) -------------------------------------------------------------- if args.json_template: rs_builder.export_json_template(parser=parser, dep_dict=dep_dict) From 10e6eec549dd16a3f3cb78b7044fe199dc36791b Mon Sep 17 00:00:00 2001 From: bilalahmed-RS Date: Wed, 4 Oct 2023 15:52:18 +0500 Subject: [PATCH 8/8] COmments improved --- rapidsilicon/ip/pll/v1_0/src/PLL.v | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/rapidsilicon/ip/pll/v1_0/src/PLL.v b/rapidsilicon/ip/pll/v1_0/src/PLL.v index ca504a69..36e2d6e7 100644 --- a/rapidsilicon/ip/pll/v1_0/src/PLL.v +++ b/rapidsilicon/ip/pll/v1_0/src/PLL.v @@ -81,10 +81,10 @@ module PLL #( parameter DIVIDE_CLK_IN_BY_2 = "FALSE", // Enable input divider (TRUE/FALSE) parameter PLL_MULT = 16, // Clock multiplier value (16-1000) parameter PLL_DIV = 1, // Clock divider value (1-63) - parameter CLK_OUT0_DIV = 2, // CLK_OUT0 divider value (2,3,4,5,6,7,8,10,12,16,20.24.32.40,48,64) () - parameter CLK_OUT1_DIV = 2, // CLK_OUT1 divider value (2,3,4,5,6,7,8,10,12,16,20.24.32.40,48,64) () - parameter CLK_OUT2_DIV = 2, // CLK_OUT2 divider value (2,3,4,5,6,7,8,10,12,16,20.24.32.40,48,64) () - parameter CLK_OUT3_DIV = 2 // CLK_OUT3 divider value (2,3,4,5,6,7,8,10,12,16,20.24.32.40,48,64) () + parameter CLK_OUT0_DIV = 2, // CLK_OUT0 divider value (2,3,4,5,6,7,8,10,12,16,20.24.32.40,48,64) + parameter CLK_OUT1_DIV = 2, // CLK_OUT1 divider value (2,3,4,5,6,7,8,10,12,16,20.24.32.40,48,64) + parameter CLK_OUT2_DIV = 2, // CLK_OUT2 divider value (2,3,4,5,6,7,8,10,12,16,20.24.32.40,48,64) + parameter CLK_OUT3_DIV = 2 // CLK_OUT3 divider value (2,3,4,5,6,7,8,10,12,16,20.24.32.40,48,64) ) ( input PLL_EN, // PLL Enable input CLK_IN, // Clock input