Skip to content

Commit

Permalink
Merge pull request #261 from yrabbit/dhcen-ctl
Browse files Browse the repository at this point in the history
Add DHCEN primitive.
  • Loading branch information
yrabbit authored Sep 12, 2024
2 parents b2a84bd + af2975e commit 4f87247
Show file tree
Hide file tree
Showing 6 changed files with 251 additions and 7 deletions.
2 changes: 1 addition & 1 deletion apycula/attrids.py
Original file line number Diff line number Diff line change
Expand Up @@ -1210,7 +1210,7 @@
'DIVCIBRST2': 1,
'DIVCIBRST3': 2,
'DIV2': 3,
'DIVCIBRST0': 4,
'DIVCIBRST0': 4,
'DIVCIBRST1': 5,
'DIVCIBRST4': 6,
'DIVCIBRST5': 7,
Expand Down
91 changes: 91 additions & 0 deletions apycula/chipdb.py
Original file line number Diff line number Diff line change
Expand Up @@ -1186,12 +1186,19 @@ def fse_create_hclk_nodes(dev, device, fse, dat: Datfile):
row, col = hclk_loc
ttyp = fse['header']['grid'][61][row][col]
dev.hclk_pips[(row, col)] = fse_pips(fse, ttyp, table = 48, wn = hclknames)
for dst in dev.hclk_pips[(row, col)].keys():
# from HCLK to interbank MUX
if dst in {'HCLK_BANK_OUT0', 'HCLK_BANK_OUT1'}:
add_node(dev, f'HCLK{"TBLR".index(side)}_BANK_OUT{dst[-1]}', "GLOBAL_CLK", row, col, dst)
# connect local wires like PCLKT0 etc to the global nodes
for srcs in dev.hclk_pips[(row, col)].values():
for src in srcs.keys():
for pfx in _global_wire_prefixes:
if src.startswith(pfx):
add_node(dev, src, "HCLK", row, col, src)
# from interbank MUX to HCLK
if src in {'HCLK_BANK_IN0', 'HCLK_BANK_IN1'}:
add_node(dev, f'HCLKMUX{src[-1]}', "GLOBAL_CLK", row, col, src)
# strange GW1N-9C input-input aliases
for i in {0, 2}:
dev.nodes.setdefault(f'X{col}Y{row}/HCLK9-{i}', ('HCLK', {(row, col, f'HCLK_IN{i}')}))[1].add((row, col, f'HCLK_9IN{i}'))
Expand Down Expand Up @@ -1236,6 +1243,80 @@ def fse_create_hclk_nodes(dev, device, fse, dat: Datfile):
if src.startswith('HCLK'):
hclks[src].add((row, col, src))

# DHCEN (as I imagine) is an additional control input of the HCLK input
# multiplexer. We have four input multiplexers - HCLK_IN0, HCLK_IN1, HCLK_IN2,
# HCLK_IN3 (GW1N-9C with its additional four multiplexers stands separately,
# but we will deal with it later) and two interbank inputs.
# Creating images using IDE where we use the maximum allowable number of DHCEN,
# the CE port of which is connected to the IO ports, then we trace the route
# from IO to the final wire, which will be the CE port of the DHCEN primitive.
# We are not interested in the CLKIN and CLKOUT ports because we are supposed
# to simply disable/enable one of the input multiplexers.
# Let's summarize the experimental data in a table.
# There are 4 multiplexers and interbank inputs on each side of the chip
# (sides: Right Bottom Left Top).
_dhcen_ce = {
'GW1N-1':
{'B' : [(10, 19, 'D5'), (10, 19, 'D3'), (10, 19, 'D4'), (10, 19, 'D2'), (10, 0, 'C0'), (10, 0, 'C1')]},
'GW1NZ-1':
{'R' : [( 0, 19, 'A2'), ( 0, 19, 'A4'), ( 0, 19, 'A3'), ( 0, 19, 'A5'), ( 0, 18, 'C6'), ( 0, 18, 'C7')],
'T' : [(10, 19, 'A2'), (10, 19, 'A4'), (10, 19, 'A3'), (10, 19, 'A5'), (10, 19, 'C6'), (10, 19, 'C7')]},
'GW1NS-2':
{'R' : [(10, 19, 'A4'), (10, 19, 'A6'), (10, 19, 'A5'), (10, 19, 'A7'), (10, 19, 'C4'), (10, 19, 'C5')],
'B' : [(11, 19, 'A4'), (11, 19, 'A6'), (11, 19, 'A5'), (11, 19, 'A7'), (11, 19, 'C4'), (11, 19, 'C5')],
'L' : [( 9, 0, 'A0'), ( 9, 0, 'A2'), ( 9, 0, 'A1'), ( 9, 0, 'A3'), ( 9, 0, 'C0'), ( 9, 0, 'C1')],
'T' : [( 0, 19, 'D5'), ( 0, 19, 'D3'), ( 0, 19, 'D4'), ( 0, 19, 'D2'), ( 0, 0, 'B1'), ( 0, 0, 'B0')]},
'GW1N-4':
{'R' : [(18, 37, 'C6'), (18, 37, 'D7'), (18, 37, 'C7'), (18, 37, 'D6'), ( 0, 37, 'D7'), ( 0, 37, 'D6')],
'B' : [(19, 37, 'A2'), (19, 37, 'A4'), (19, 37, 'A3'), (19, 37, 'A5'), (19, 0, 'B2'), (19, 0, 'B3')],
'L' : [(18, 0, 'C6'), (18, 0, 'D7'), (18, 0, 'C7'), (18, 0, 'D6'), (19, 0, 'A4'), ( 0, 0, 'B1')]},
'GW1NS-4':
{'R' : [(18, 37, 'C6'), (18, 37, 'D7'), (18, 37, 'C7'), (18, 37, 'D6'), ( 0, 37, 'D7'), ( 0, 37, 'D6')],
'B' : [(19, 37, 'A2'), (19, 37, 'A4'), (19, 37, 'A3'), (19, 37, 'A5'), (19, 0, 'B2'), (19, 0, 'B3')],
'T' : [( 1, 0, 'B6'), ( 1, 0, 'A0'), ( 1, 0, 'B7'), ( 1, 0, 'A1'), ( 1, 0, 'C4'), ( 1, 0, 'C3')]},
'GW1N-9':
{'R' : [(18, 46, 'C6'), (18, 46, 'D7'), (18, 46, 'C7'), (18, 46, 'D6'), (18, 46, 'B6'), (18, 46, 'B7')],
'B' : [(28, 46, 'A2'), (28, 46, 'A4'), (28, 46, 'A3'), (28, 46, 'A5'), (28, 0, 'B2'), (28, 0, 'B3')],
'L' : [(18, 0, 'C6'), (18, 0, 'D7'), (18, 0, 'C7'), (18, 0, 'D6'), (18, 0, 'B6'), (18, 0, 'B7')],
'T' : [( 9, 0, 'C6'), ( 9, 0, 'D7'), ( 9, 0, 'C7'), ( 9, 0, 'D6'), ( 9, 0, 'B6'), ( 9, 0, 'B7')]},
'GW1N-9C':
{'R' : [(18, 46, 'C6'), (18, 46, 'D7'), (18, 46, 'C7'), (18, 46, 'D6'), (18, 46, 'B6'), (18, 46, 'B7')],
'B' : [(28, 46, 'A2'), (28, 46, 'A4'), (28, 46, 'A3'), (28, 46, 'A5'), (28, 0, 'B2'), (28, 0, 'B3')],
'L' : [(18, 0, 'C6'), (18, 0, 'D7'), (18, 0, 'C7'), (18, 0, 'D6'), (18, 0, 'B6'), (18, 0, 'B7')],
'T' : [( 9, 0, 'C6'), ( 9, 0, 'D7'), ( 9, 0, 'C7'), ( 9, 0, 'D6'), ( 9, 0, 'B6'), ( 9, 0, 'B7')]},
'GW2A-18':
{'R' : [(27, 55, 'A2'), (27, 55, 'A3'), (27, 55, 'D2'), (27, 55, 'D3'), (27, 55, 'D0'), (27, 55, 'D1')],
'B' : [(54, 27, 'A2'), (54, 27, 'A3'), (54, 27, 'D2'), (54, 27, 'D3'), (54, 27, 'D0'), (54, 27, 'D1')],
'L' : [(27, 0, 'A2'), (27, 0, 'A3'), (27, 0, 'D2'), (27, 0, 'D3'), (27, 0, 'D0'), (27, 0, 'D1')],
'T' : [( 0, 27, 'A2'), ( 0, 27, 'A3'), ( 0, 27, 'D2'), ( 0, 27, 'D3'), ( 0,27, 'D0'), ( 0, 27, 'D1')]},
'GW2A-18C':
{'R' : [(27, 55, 'A2'), (27, 55, 'A3'), (27, 55, 'D2'), (27, 55, 'D3'), (27, 55, 'D0'), (27, 55, 'D1')],
'B' : [(54, 27, 'A2'), (54, 27, 'A3'), (54, 27, 'D2'), (54, 27, 'D3'), (54, 27, 'D0'), (54, 27, 'D1')],
'L' : [(27, 0, 'A2'), (27, 0, 'A3'), (27, 0, 'D2'), (27, 0, 'D3'), (27, 0, 'D0'), (27, 0, 'D1')],
'T' : [( 0, 27, 'A2'), ( 0, 27, 'A3'), ( 0, 27, 'D2'), ( 0, 27, 'D3'), ( 0,27, 'D0'), ( 0, 27, 'D1')]},
}
def fse_create_dhcen(dev, device, fse, dat: Datfile):
if device not in _dhcen_ce:
print(f'No DHCEN for {device} for now.')
return
for side, ces in _dhcen_ce[device].items():
for idx, ce_wire in enumerate(ces):
row, col, wire = ce_wire
extra = dev.extra_func.setdefault((row, col), {})
dhcen = extra.setdefault('dhcen', [])
# use db.hclk_pips in order to find HCLK_IN cells
for hclk_loc in _hclk_to_fclk[device][side]['hclk']:
if idx < 4:
hclk_name = f'HCLK_IN{idx}'
else:
hclk_name = f'HCLK_BANK_OUT{idx - 4}'
if hclk_name in dev.hclk_pips[hclk_loc]:
hclkin = {'pip' : [f'X{hclk_loc[1]}Y{hclk_loc[0]}', hclk_name, next(iter(dev.hclk_pips[hclk_loc][hclk_name].keys())), side]}

hclkin.update({ 'ce' : wire})
dhcen.append(hclkin)


_pll_loc = {
'GW1N-1':
{'TRPLL0CLK0': (0, 17, 'F4'), 'TRPLL0CLK1': (0, 17, 'F5'),
Expand Down Expand Up @@ -1488,6 +1569,7 @@ def fse_create_clocks(dev, device, dat: Datfile, fse):


spines = {f'SPINE{i}' for i in range(32)}
hclk_srcs = {f'HCLK{i}_BANK_OUT{j}' for i in range(4) for j in range(2)}
dcs_inputs = {f'P{i}{j}{k}' for i in range(1, 5) for j in range(6, 8) for k in "ABCD"}
for row, rd in enumerate(dev.grid):
for col, rc in enumerate(rd):
Expand All @@ -1499,6 +1581,12 @@ def fse_create_clocks(dev, device, dat: Datfile, fse):
add_node(dev, dest, "GLOBAL_CLK", row, col, dest)
for src in { wire for wire in srcs.keys() if wire not in {'VCC', 'VSS'}}:
add_node(dev, src, "GLOBAL_CLK", row, col, src)
elif dest in {'HCLKMUX0', 'HCLKMUX1'}:
# this interbank communication between HCLKs
add_node(dev, dest, "GLOBAL_CLK", row, col, dest)
for src in {wire for wire in srcs.keys() if wire in hclk_srcs}:
add_node(dev, src, "GLOBAL_CLK", row, col, src)

# GBx0 <- GBOx
for spine_pair in range(4): # GB00/GB40, GB10/GB50, GB20/GB60, GB30/GB70
tap_start = _clock_data[device]['tap_start'][0]
Expand Down Expand Up @@ -2088,6 +2176,7 @@ def from_fse(device, fse, dat: Datfile):
fse_create_bandgap(dev, device)
fse_create_userflash(dev, device, dat)
fse_create_logic2clk(dev, device, dat)
fse_create_dhcen(dev, device, fse, dat)
disable_plls(dev, device)
sync_extra_func(dev)
set_chip_flags(dev, device);
Expand Down Expand Up @@ -3487,6 +3576,8 @@ def fse_wire_delays(db):
db.wire_delay[clknames[i]] = "CENT_SPINE_PCLK"
for i in range(129, 153): # clock inputs (logic->clock)
db.wire_delay[clknames[i]] = "CENT_SPINE_PCLK"
for i in range(1000, 1010): # HCLK
db.wire_delay[clknames[i]] = "X0" # XXX

# assign pads with plls
# for now use static table and store the bel name although it is always PLL without a number
Expand Down
62 changes: 60 additions & 2 deletions apycula/gowin_pack.py
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ def get_bits(init_data):
def get_bels(data):
later = []
if is_himbaechel:
belre = re.compile(r"X(\d+)Y(\d+)/(?:GSR|LUT|DFF|IOB|MUX|ALU|ODDR|OSC[ZFHWO]?|BUF[GS]|RAM16SDP4|RAM16SDP2|RAM16SDP1|PLL|IOLOGIC|CLKDIV2|CLKDIV|BSRAM|ALU|MULTALU18X18|MULTALU36X18|MULTADDALU18X18|MULT36X36|MULT18X18|MULT9X9|PADD18|PADD9|BANDGAP|DQCE|DCS|USERFLASH)(\w*)")
belre = re.compile(r"X(\d+)Y(\d+)/(?:GSR|LUT|DFF|IOB|MUX|ALU|ODDR|OSC[ZFHWO]?|BUF[GS]|RAM16SDP4|RAM16SDP2|RAM16SDP1|PLL|IOLOGIC|CLKDIV2|CLKDIV|BSRAM|ALU|MULTALU18X18|MULTALU36X18|MULTADDALU18X18|MULT36X36|MULT18X18|MULT9X9|PADD18|PADD9|BANDGAP|DQCE|DCS|USERFLASH|DHCEN)(\w*)")
else:
belre = re.compile(r"R(\d+)C(\d+)_(?:GSR|SLICE|IOB|MUX2_LUT5|MUX2_LUT6|MUX2_LUT7|MUX2_LUT8|ODDR|OSC[ZFHWO]?|BUFS|RAMW|rPLL|PLLVR|IOLOGIC)(\w*)")

Expand Down Expand Up @@ -1989,6 +1989,43 @@ def set_osc_attrs(db, typ, params):
add_attr_val(db, 'OSC', fin_attrs, attrids.osc_attrids[attr], val)
return fin_attrs

_wire2attr_val = {
'HCLK_IN0': ('HSB0MUX0_HSTOP', 'HCLKCIBSTOP0'),
'HCLK_IN1': ('HSB1MUX0_HSTOP', 'HCLKCIBSTOP2'),
'HCLK_IN2': ('HSB0MUX1_HSTOP', 'HCLKCIBSTOP1'),
'HCLK_IN3': ('HSB1MUX1_HSTOP', 'HCLKCIBSTOP3'),
'HCLK_BANK_OUT0': ('BRGMUX0_BRGSTOP', 'BRGCIBSTOP0'),
'HCLK_BANK_OUT1': ('BRGMUX1_BRGSTOP', 'BRGCIBSTOP1'),
}
def find_and_set_dhcen_hclk_fuses(db, tilemap, wire, side):
fin_attrs = set()
attr, attr_val = _wire2attr_val[wire]
val = attrids.hclk_attrvals[attr_val]
add_attr_val(db, 'HCLK', fin_attrs, attrids.hclk_attrids[attr], val)

def set_fuse():
ttyp = db.grid[row][col].ttyp
if 'HCLK' in db.shortval[ttyp]:
bits = get_shortval_fuses(db, ttyp, fin_attrs, "HCLK")
tile = tilemap[row, col]
for r, c in bits:
tile[r][c] = 1

if side in "TB":
if side == 'T':
row = 0
else:
row = db.rows - 1
for col in range(db.cols):
set_fuse()
else:
if side == 'L':
col = 0
else:
col = db.cols - 1
for row in range(db.rows):
set_fuse()

def bin_str_to_dec(str_val):
bin_pattern = r'^[0,1]+'
bin_str = re.findall(bin_pattern, str_val)
Expand Down Expand Up @@ -2035,7 +2072,6 @@ def set_hclk_attrs(db, params, num, typ, cell_name):
add_attr_val(db, 'HCLK', fin_attrs, attrids.hclk_attrids[attr], val)
return fin_attrs


_iologic_default_attrs = {
'DUMMY': {},
'IOLOGIC': {},
Expand Down Expand Up @@ -2502,9 +2538,19 @@ def place(db, tilemap, bels, cst, args):
cfg_tile = tilemap[(0, 37)]
for r, c in bits:
cfg_tile[r][c] = 1
elif typ == "DHCEN":
if 'DHCEN_USED' not in attrs:
continue
# DHCEN as such is just a control wire and does not have a fuse
# itself, but HCLK has fuses that allow this control. Here we look
# for the corresponding HCLK and set its fuses.
_, wire, _, side = db.extra_func[row - 1, col -1]['dhcen'][int(num)]['pip']
hclk_attrs = find_and_set_dhcen_hclk_fuses(db, tilemap, wire, side)
elif typ in ["CLKDIV", "CLKDIV2"]:
hclk_attrs = set_hclk_attrs(db, parms, num, typ, cellname)
bits = get_shortval_fuses(db, tiledata.ttyp, hclk_attrs, "HCLK")
for r, c in bits:
tile[r][c] = 1
elif typ == 'DQCE':
# Himbaechel only
pipre = re.compile(r"X(\d+)Y(\d+)/([\w_]+)/([\w_]+)")
Expand Down Expand Up @@ -2693,6 +2739,17 @@ def secure_long_wires(db, tilemap, row, col, src, dest):
for row, col in bits:
tile[row][col] = 1

# hclk interbank requires to set some non-route fuses
def do_hclk_banks(db, row, col, src, dest):
res = set()
if dest in {'HCLK_BANK_OUT0', 'HCLK_BANK_OUT1'}:
fin_attrs = set()
add_attr_val(db, 'HCLK', fin_attrs, attrids.hclk_attrids[f'BRGMUX{dest[-1]}_BRGOUT'], attrids.hclk_attrvals['ENABLE'])

ttyp = db.grid[row][col].ttyp
if 'HCLK' in db.shortval[ttyp]:
res = get_shortval_fuses(db, ttyp, fin_attrs, "HCLK")
return res

def route(db, tilemap, pips):
for row, col, src, dest in pips:
Expand All @@ -2704,6 +2761,7 @@ def route(db, tilemap, pips):
bits = tiledata.clock_pips[dest][src]
elif is_himbaechel and (row - 1, col - 1) in db.hclk_pips and dest in db.hclk_pips[row - 1, col - 1]:
bits = db.hclk_pips[row - 1, col - 1][dest][src]
bits.update(do_hclk_banks(db, row - 1, col - 1, src, dest))
else:
bits = tiledata.pips[dest][src]
except KeyError:
Expand Down
16 changes: 14 additions & 2 deletions apycula/wirenames.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,19 +119,31 @@
})

clknames.update({n: f"UNK{n}" for n in range(210, 261)})

# HCLK->clock network
# Each HCLK can connect to other HCLKs through two MUXes in the clock system.
# Here we assign numbers to these MUXes and their inputs - two per HCLK
clknames.update({
1000: 'HCLKMUX0', 1001: 'HCLKMUX1',
1002: 'HCLK0_BANK_OUT0', 1003: 'HCLK0_BANK_OUT1',
1004: 'HCLK1_BANK_OUT0', 1005: 'HCLK1_BANK_OUT1',
1006: 'HCLK2_BANK_OUT0', 1007: 'HCLK2_BANK_OUT1',
1008: 'HCLK3_BANK_OUT0', 1009: 'HCLK3_BANK_OUT1',
})

clknumbers = {v: k for k, v in clknames.items()}

# hclk
hclknames = clknames.copy()
hclknames.update({n: f"HCLK_UNK{n}" for n in range(26)})
# inputs
hclknames.update({
2: 'HCLK_IN0', 3: 'HCLK_IN1', 4: 'HCLK_IN2', 5: 'HCLK_IN3'
2: 'HCLK_IN0', 3: 'HCLK_IN1', 4: 'HCLK_IN2', 5: 'HCLK_IN3', 8: 'HCLK_BANK_IN0', 9: 'HCLK_BANK_IN1'
})

# HCLK section inputs
hclknames.update({
10: 'HCLK0_SECT0_IN', 11: 'HCLK0_SECT1_IN', 12: 'HCLK1_SECT0_IN', 13: 'HCLK1_SECT1_IN'
6: 'HCLK_BANK_OUT0', 7: 'HCLK_BANK_OUT1', 10: 'HCLK0_SECT0_IN', 11: 'HCLK0_SECT1_IN', 12: 'HCLK1_SECT0_IN', 13: 'HCLK1_SECT1_IN'
})

# Bypass connections from HCLK_IN to HCLK_OUT
Expand Down
4 changes: 2 additions & 2 deletions examples/himbaechel/Makefile.himbaechel
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ NEXTPNR ?= nextpnr-himbaechel
all: \
blinky-tangnano20k.fs shift-tangnano20k.fs blinky-tbuf-tangnano20k.fs blinky-oddr-tangnano20k.fs \
blinky-osc-tangnano20k.fs tlvds-tangnano20k.fs elvds-tangnano20k.fs oddr-tlvds-tangnano20k.fs \
blinky-clkdiv-tangnano20k.fs dvi-example-tangnano20k.fs\
blinky-clkdiv-tangnano20k.fs dvi-example-tangnano20k.fs blinky-clkdiv-dhcen-tangnano20k.fs \
oddr-elvds-tangnano20k.fs pll-nanolcd-tangnano20k.fs attosoc-tangnano20k.fs \
oser4-tangnano20k.fs ovideo-tangnano20k.fs oser8-tangnano20k.fs oser10-tangnano20k.fs \
ides4-tangnano20k.fs ivideo-tangnano20k.fs ides8-tangnano20k.fs ides10-tangnano20k.fs \
Expand All @@ -21,7 +21,7 @@ all: \
\
blinky-primer20k.fs shift-primer20k.fs blinky-tbuf-primer20k.fs blinky-oddr-primer20k.fs \
blinky-osc-primer20k.fs tlvds-primer20k.fs elvds-primer20k.fs oddr-tlvds-primer20k.fs \
blinky-clkdiv-primer20k.fs dvi-example-primer20k.fs\
blinky-clkdiv-primer20k.fs dvi-example-primer20k.fs blinky-clkdiv-dhcen-primer20k.fs \
oddr-elvds-primer20k.fs pll-nanolcd-primer20k.fs attosoc-primer20k.fs \
oser4-primer20k.fs ovideo-primer20k.fs oser8-primer20k.fs oser10-primer20k.fs \
ides4-primer20k.fs ivideo-primer20k.fs ides8-primer20k.fs ides10-primer20k.fs \
Expand Down
83 changes: 83 additions & 0 deletions examples/himbaechel/blinky-clkdiv-dhcen.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
module top (
input clk,
input key_i,
output [`LEDS_NR-1:0] led
);

/* Expected Result:
- 1 or 2 LEDs blinking, depending on your board.
- The `faster` LED is associated with the input clock.
- The `slower` LED is associated with a divided clock.
- On boards with multiple CLKDIVs, the slower LED's blink rate changes as it cycles through CLKDIVs
configured with different DIV_MODES.
- If your board has only one LED, it should blink with the divided clock.
- Holding the appropriate button should stop the blinking.
*/

localparam /*string*/ DIV_MODE_2 = "2";
localparam /*string*/ DIV_MODE_35 = "3.5";
localparam /*string*/ DIV_MODE_4 = "4";
localparam /*string*/ DIV_MODE_5 = "5";


wire key = key_i ^ `INV_BTN;

reg [25:0] ctr_q;
wire [25:0] ctr_d;
// localparam NUM_HCLKi=NUM_HCLK;

wire [`NUM_HCLK-1:0] hclk_counts;
reg [$clog2(`NUM_HCLK)-1:0] curr_hclk_idx;
wire curr_hclk;
reg [30:0] sup_count;


wire managed_clk;
DHCEN dhcen(
.CLKIN(clk),
.CE(key),
.CLKOUT(managed_clk)
);

genvar i;
generate
for (i=0; i < `NUM_HCLK; i=i+1) begin:hcount
localparam /*string*/ div_mode =(i % 4 == 0) ? DIV_MODE_5 :
(i % 4 == 1) ? DIV_MODE_4 :
(i % 4 == 2) ? DIV_MODE_35 :
DIV_MODE_2;

wire div2_out;
wire o_clk;

CLKDIV2 my_div2 (
.RESETN(1'b1),
.HCLKIN(managed_clk),
.CLKOUT(div2_out)
);

CLKDIV #(.DIV_MODE(div_mode)) my_div (
.RESETN(1'b1),
.HCLKIN(div2_out),
.CLKOUT(o_clk)
);

reg [23:0] count;
always @(posedge o_clk)begin
count <= count + 1'b1;
end
assign hclk_counts[i] = count[23];
end
endgenerate

always @(posedge clk) begin
sup_count <= sup_count + 1'b1;
curr_hclk_idx <= curr_hclk_idx + sup_count[29];
if (curr_hclk_idx == `NUM_HCLK-1)
curr_hclk_idx <= 0;
end

assign curr_hclk = hclk_counts[curr_hclk_idx];
assign led = {curr_hclk, sup_count[23]};

endmodule

0 comments on commit 4f87247

Please sign in to comment.