Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pll updates #176

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 24 additions & 44 deletions rapidsilicon/ip/axi_async_fifo/v1_0/axi_async_fifo_gen.py
Original file line number Diff line number Diff line change
Expand Up @@ -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 *
Expand Down Expand Up @@ -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.")
Expand All @@ -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,
Expand All @@ -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()
18 changes: 16 additions & 2 deletions rapidsilicon/ip/boot_clock/v1_0/boot_clock_gen.py
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand Down Expand Up @@ -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")
Expand Down
2 changes: 1 addition & 1 deletion rapidsilicon/ip/boot_clock/v1_0/src/BOOT_CLOCK.v
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
59 changes: 31 additions & 28 deletions rapidsilicon/ip/pll/v1_0/litex_wrapper/pll_litex_wrapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -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}")
Expand All @@ -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):
Expand Down
56 changes: 42 additions & 14 deletions rapidsilicon/ip/pll/v1_0/pll_gen.py
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -94,29 +95,27 @@ 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")
core_fix_param_group.add_argument("--clk_out3_div", type=int, default=2, choices=[2,3,4,5,6,7,8,10,12,16,20.24,32,40,48,64], help="CLK_OUT3 divider value")

# 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="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")

# 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")
Expand All @@ -125,25 +124,54 @@ 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 = {
"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)
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,
clk_out3_div=args.clk_out3_div)

a
# Build Project --------------------------------------------------------------------------------
if args.build:
rs_builder.prepare(
Expand Down
8 changes: 4 additions & 4 deletions rapidsilicon/ip/pll/v1_0/src/PLL.v
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Loading
Loading