Skip to content

Commit

Permalink
HCLK. Add interbank wires
Browse files Browse the repository at this point in the history
An interesting mechanism for transmitting signals between HCLK banks (or
otherwise parties) has been discovered.

We have two points, each of which can receive a signal from any HCLK and
transmit it to any other HCLK.

No complex signals can be transmitted here - the input lines are limited
by HCLK_INx, and we also need to see which components can use the output
from these two points, but so far the tests are encouraging: it is
possible to transmit a signal from the clock pin from one side of the
chip to the opposite and feed CLKDIV2 there using just a couple wires!

Signed-off-by: YRabbit <[email protected]>
  • Loading branch information
yrabbit committed Jul 25, 2024
1 parent 90aaf55 commit 6889998
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 39 deletions.
90 changes: 55 additions & 35 deletions apycula/chipdb.py
Original file line number Diff line number Diff line change
Expand Up @@ -1023,12 +1023,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 @@ -1069,53 +1076,54 @@ def fse_create_hclk_nodes(dev, device, fse, dat: Datfile):
# 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 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 on each side of the chip (sides: Right Bottom Left Top).
# There are 4 multiplexers and interbank inputs on each side of the chip
# (sides: Right Bottom Left Top).
_dhcen_ce = {
'GW1N-1':
{'B' : [( 0, 19, 'D5'), ( 0, 19, 'D3'), ( 0, 19, 'D4'), ( 0, 19, 'D2')]},
{'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')],
'T' : [(10, 19, 'A2'), (10, 19, 'A4'), (10, 19, 'A3'), (10, 19, 'A5')]},
{'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')],
'B' : [(11, 19, 'A4'), (11, 19, 'A6'), (11, 19, 'A5'), (11, 19, 'A7')],
'L' : [( 9, 0, 'A0'), ( 9, 0, 'A2'), ( 9, 0, 'A1'), ( 9, 0, 'A3')],
'T' : [( 0, 19, 'D5'), ( 0, 19, 'D3'), ( 0, 19, 'D4'), ( 0, 19, 'D2')]},
{'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')],
'B' : [(19, 37, 'A2'), (19, 37, 'A4'), (19, 37, 'A3'), (19, 37, 'A5')],
'L' : [(18, 0, 'C6'), (18, 0, 'D7'), (18, 0, 'C7'), (18, 0, 'D6')]},
{'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')],
'B' : [(19, 37, 'A2'), (19, 37, 'A4'), (19, 37, 'A3'), (19, 37, 'A5')],
'T' : [( 1, 0, 'B6'), ( 1, 0, 'A0'), ( 1, 0, 'B7'), ( 1, 0, 'A1')]},
{'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')],
'B' : [(28, 46, 'A2'), (28, 46, 'A4'), (28, 46, 'A3'), (28, 46, 'A5')],
'L' : [(18, 0, 'C6'), (18, 0, 'D7'), (18, 0, 'C7'), (18, 0, 'D6')],
'T' : [( 9, 0, 'C6'), ( 9, 0, 'D7'), ( 9, 0, 'C7'), ( 9, 0, 'D6')]},
'GW1N-9C':
{'R' : [(18, 46, 'C6'), (18, 46, 'D7'), (18, 46, 'C7'), (18, 46, 'D6')],
'B' : [(28, 46, 'A2'), (28, 46, 'A4'), (28, 46, 'A3'), (28, 46, 'A5')],
'L' : [(18, 0, 'C6'), (18, 0, 'D7'), (18, 0, 'C7'), (18, 0, 'D6')],
'T' : [( 9, 0, 'C6'), ( 9, 0, 'D7'), ( 9, 0, 'C7'), ( 9, 0, 'D6')]},
{'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')],
'B' : [(54, 27, 'A2'), (54, 27, 'A3'), (54, 27, 'D2'), (54, 27, 'D3')],
'L' : [(27, 0, 'A2'), (27, 0, 'A3'), (27, 0, 'D2'), (27, 0, 'D3')],
'T' : [( 0, 27, 'A2'), ( 0, 27, 'A3'), ( 0, 27, 'D2'), ( 0, 27, 'D3')]},
{'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')],
'B' : [(54, 27, 'A2'), (54, 27, 'A3'), (54, 27, 'D2'), (54, 27, 'D3')],
'L' : [(27, 0, 'A2'), (27, 0, 'A3'), (27, 0, 'D2'), (27, 0, 'D3')],
'T' : [( 0, 27, 'A2'), ( 0, 27, 'A3'), ( 0, 27, 'D2'), ( 0, 27, 'D3')]},
{'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:
Expand All @@ -1128,8 +1136,13 @@ def fse_create_dhcen(dev, device, fse, dat: Datfile):
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 f'HCLK_IN{idx}' in dev.hclk_pips[hclk_loc]:
hclkin = {'hclkin' : [f'X{hclk_loc[1]}Y{hclk_loc[0]}', f'HCLK_IN{idx}', side]}
if idx < 4:
if f'HCLK_IN{idx}' in dev.hclk_pips[hclk_loc]:
hclkin = {'wire' : [f'X{hclk_loc[1]}Y{hclk_loc[0]}', f'HCLK_IN{idx}', side]}
else:
if f'HCLK_BANK_OUT{idx - 4}' in dev.hclk_pips[hclk_loc]:
hclkin = {'wire' : [f'X{hclk_loc[1]}Y{hclk_loc[0]}', f'HCLK_BANK_OUT{idx - 4}', side]}

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

Expand Down Expand Up @@ -1386,16 +1399,23 @@ 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)}
for row, rd in enumerate(dev.grid):
for col, rc in enumerate(rd):
for dest, srcs in rc.pure_clock_pips.items():
for src in srcs.keys():
if src in spines and not dest.startswith('GT'):
add_node(dev, src, "GLOBAL_CLK", row, col, src)
if dest in spines:
if dest in spines or dest in dcs_inputs:
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
18 changes: 16 additions & 2 deletions apycula/gowin_pack.py
Original file line number Diff line number Diff line change
Expand Up @@ -1973,6 +1973,8 @@ def set_osc_attrs(db, typ, params):
'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()
Expand Down Expand Up @@ -2467,12 +2469,12 @@ def place(db, tilemap, bels, cst, args):
for r, c in bits:
cfg_tile[r][c] = 1
elif typ == "DHCEN":
if 'DHCEN_SIDE' not in attrs:
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)]['hclkin']
_, wire, side = db.extra_func[row - 1, col -1]['dhcen'][int(num)]['wire']
hclk_attrs = find_and_set_dhcen_hclk_fuses(db, tilemap, wire, side)
else:
print("unknown type", typ)
Expand Down Expand Up @@ -2635,6 +2637,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 @@ -2646,6 +2659,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 @@ -106,19 +106,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'
})

# outputs
hclknames.update({
10: 'HCLK_OUT0', 11: 'HCLK_OUT1', 12: 'HCLK_OUT2', 13: 'HCLK_OUT3'
6: 'HCLK_BANK_OUT0', 7: 'HCLK_BANK_OUT1', 10: 'HCLK0_SECT0_IN', 11: 'HCLK0_SECT1_IN', 12: 'HCLK1_SECT0_IN', 13: 'HCLK1_SECT1_IN'
})
# these work as inputs in GW1N-9c
hclknames.update({
Expand Down

0 comments on commit 6889998

Please sign in to comment.