Skip to content

Commit bf6309b

Browse files
authored
Merge pull request #316 from yrabbit/clkdiv-clkdiv2
Implement CLKDIV2 and CLKDIV for all boards.
2 parents b760177 + f019771 commit bf6309b

File tree

6 files changed

+155
-22
lines changed

6 files changed

+155
-22
lines changed

apycula/chipdb.py

+97-9
Original file line numberDiff line numberDiff line change
@@ -177,16 +177,26 @@ def bank_tiles(self):
177177
# If suddenly a command is given to assign an already used wire to another
178178
# node, then all the contents of this node are combined with the existing one,
179179
# and the node itself is destroyed.
180+
# To prevent further attempts to add wires to the destroyed node, we return the
181+
# name of the node to which the connection was made
180182
wire2node = {}
181183
def add_node(dev, node_name, wire_type, row, col, wire):
182184
if (row, col, wire) not in wire2node:
183185
wire2node[row, col, wire] = node_name
184186
dev.nodes.setdefault(node_name, (wire_type, set()))[1].add((row, col, wire))
187+
return node_name
185188
else:
186-
if node_name != wire2node[row, col, wire] and node_name in dev.nodes:
187-
#print(f'{node_name} -> {wire2node[row, col, wire]} share ({row}, {col}, {wire})')
188-
dev.nodes[wire2node[row, col, wire]][1].update(dev.nodes[node_name][1])
189-
del dev.nodes[node_name]
189+
old_node_name = wire2node[row, col, wire]
190+
if node_name != old_node_name:
191+
if node_name in dev.nodes:
192+
#print(f'#0 {node_name} -> {wire2node[row, col, wire]} share ({row}, {col}, {wire})')
193+
dev.nodes[old_node_name][1].update(dev.nodes[node_name][1])
194+
del dev.nodes[node_name]
195+
else:
196+
#print(f'#1 {node_name} -> {wire2node[row, col, wire]} share ({row}, {col}, {wire})')
197+
dev.nodes[old_node_name][1].add((row, col, wire))
198+
return old_node_name
199+
return node_name
190200

191201
# create bels for entry potints to the global clock nets
192202
def add_buf_bel(dev, row, col, wire, buf_type = 'BUFG'):
@@ -1036,6 +1046,24 @@ def fse_create_hclk_aliases(db, device, dat: Datfile):
10361046
1: HCLK_PINS((27,0), [("CALIB",27,0,"C5"), ("RESETN",27,0,"B5") ], [("RESETN",27,0,"A1") ], [("RESETN",27,0,"C1")])
10371047
}
10381048
},
1049+
"GW1N-9": {
1050+
"TOPSIDE":{
1051+
0: HCLK_PINS((0,0), [("CALIB",9,0,"A2"), ("RESETN",9,0,"B0")], [("RESETN",9,0,"B2")], [("RESETN",9,0,"B4")]),
1052+
1: HCLK_PINS((0,46), [("CALIB",9,0,"A3"), ("RESETN",9,0,"B1")], [("RESETN",9,0,"B3")], [("RESETN",9,0,"B5")])
1053+
},
1054+
"RIGHTSIDE":{
1055+
0: HCLK_PINS((18,46), [("CALIB",18,46,"A2"), ("RESETN",18,46,"B0")], [("RESETN",18,46,"B2")], [("RESETN",18,46,"B4")]),
1056+
1: HCLK_PINS((18,46), [("CALIB",18,46,"A3"), ("RESETN",18,46,"B1")], [("RESETN",18,46,"B3")], [("RESETN",18,46,"B5")])
1057+
},
1058+
"BOTTOMSIDE":{
1059+
0: HCLK_PINS((28,0), [("CALIB",28,0,"D0"), ("RESETN",28,0,"D2")], [("RESETN",28,0,"D4")], [("RESETN",28,0,"C0")]),
1060+
1: HCLK_PINS((28,46), [("CALIB",28,0,"D1"), ("RESETN",28,0,"D3")], [("RESETN",28,0,"D5")], [("RESETN",28,0,"C1")])
1061+
},
1062+
"LEFTSIDE":{
1063+
0: HCLK_PINS((18,0), [("CALIB",18,0,"A2"), ("RESETN",18,0,"B0") ], [("RESETN",18,0,"B2") ], [("RESETN",18,0,"B4") ]),
1064+
1: HCLK_PINS((18,0), [("CALIB",18,0,"A3"), ("RESETN",18,0,"B1") ], [("RESETN",18,0,"B3") ], [("RESETN",18,0,"B5") ])
1065+
}
1066+
},
10391067
"GW1N-9C": {
10401068
"TOPSIDE":{
10411069
0: HCLK_PINS((0,0), [("CALIB",9,0,"A2"), ("RESETN",9,0,"B0")], [("RESETN",9,0,"B2")], [("RESETN",9,0,"B4")]),
@@ -1053,7 +1081,51 @@ def fse_create_hclk_aliases(db, device, dat: Datfile):
10531081
0: HCLK_PINS((18,0), [("CALIB",18,0,"A2"), ("RESETN",18,0,"B0") ], [("RESETN",18,0,"B2") ], [("RESETN",18,0,"B4") ]),
10541082
1: HCLK_PINS((18,0), [("CALIB",18,0,"A3"), ("RESETN",18,0,"B1") ], [("RESETN",18,0,"B3") ], [("RESETN",18,0,"B5") ])
10551083
}
1056-
}
1084+
},
1085+
"GW1N-1": {
1086+
"BOTTOMSIDE":{
1087+
0: HCLK_PINS((10, 0), [("CALIB", 10, 0, "D2"), ("RESETN", 10, 0, "D0")], [("RESETN", 10, 0, "D4")], [("RESETN", 10, 0, "D6")]),
1088+
1: HCLK_PINS((10, 19), [("CALIB", 10, 0, "D3"), ("RESETN", 10, 0, "D1")], [("RESETN", 10, 0, "D5")], [("RESETN", 10, 0, "D7")])
1089+
},
1090+
},
1091+
"GW1NZ-1": {
1092+
"TOPSIDE":{
1093+
0: HCLK_PINS((0, 5), [("CALIB", 0, 19, "D3"), ("RESETN", 0, 19, "D1")], [("RESETN", 0, 18, "C2")], [("RESETN", 0, 18, "C4")]),
1094+
1: HCLK_PINS((0, 5), [("CALIB", 0, 19, "D2"), ("RESETN", 0, 19, "D0")], [("RESETN", 0, 18, "C3")], [("RESETN", 0, 18, "C5")])
1095+
},
1096+
"RIGHTSIDE":{
1097+
0: HCLK_PINS((5, 19), [("CALIB", 10, 19, "D3"), ("RESETN", 10, 19, "D1")], [("RESETN", 10, 18, "C2")], [("RESETN", 10, 18, "C4")]),
1098+
1: HCLK_PINS((5, 19), [("CALIB", 10, 19, "D2"), ("RESETN", 10, 19, "D1")], [("RESETN", 10, 18, "C3")], [("RESETN", 10, 18, "C5")])
1099+
},
1100+
},
1101+
"GW1NS-4": {
1102+
"TOPSIDE":{
1103+
0: HCLK_PINS((0, 18), [("CALIB", 1, 0, "C0"), ("RESETN", 0, 0, "C5")], [("RESETN", 0, 0, "B1")], [("RESETN", 1, 0, "C6")]),
1104+
1: HCLK_PINS((0, 18), [("CALIB", 1, 0, "D7"), ("RESETN", 0, 0, "B0")], [("RESETN", 1, 0, "C7")], [("RESETN", 1, 0, "C5")])
1105+
},
1106+
"RIGHTSIDE":{
1107+
0: HCLK_PINS((9, 37), [("CALIB", 0, 37, "D7"), ("RESETN", 0, 37, "D5")], [("RESETN", 0, 37, "C3")], [("RESETN", 0, 37, "C1")]),
1108+
1: HCLK_PINS((9, 37), [("CALIB", 0, 37, "D6"), ("RESETN", 0, 37, "D6")], [("RESETN", 0, 37, "C2")], [("RESETN", 0, 37, "C0")])
1109+
},
1110+
"BOTTOMSIDE":{
1111+
0: HCLK_PINS((19, 16), [("CALIB", 19, 0, "D0"), ("RESETN", 19, 0, "D2")], [("RESETN", 19, 0, "D4")], [("RESETN", 19, 0, "C0")]),
1112+
1: HCLK_PINS((19, 17), [("CALIB", 19, 0, "D1"), ("RESETN", 19, 0, "D3")], [("RESETN", 19, 0, "D5")], [("RESETN", 19, 0, "C1")])
1113+
},
1114+
},
1115+
"GW1N-4": {
1116+
"LEFTSIDE":{
1117+
0: HCLK_PINS((9, 0), [("CALIB", 19, 0,"B4"), ("RESETN", 19, 0, "B6") ], [("RESETN", 19, 0, "A0")], [("RESETN", 19, 0, "A2")]),
1118+
1: HCLK_PINS((9 ,0), [("CALIB", 19, 0,"B5"), ("RESETN", 19, 0, "B7") ], [("RESETN", 19, 0, "A1")], [("RESETN", 19, 0, "A3")])
1119+
},
1120+
"RIGHTSIDE":{
1121+
0: HCLK_PINS((9, 37), [("CALIB", 0, 37, "B7"), ("RESETN", 0, 37, "B5")], [("RESETN", 0, 37, "C3")], [("RESETN", 0, 37, "C1")]),
1122+
1: HCLK_PINS((9, 37), [("CALIB", 0, 37, "B6"), ("RESETN", 0, 37, "B6")], [("RESETN", 0, 37, "C2")], [("RESETN", 0, 37, "C0")])
1123+
},
1124+
"BOTTOMSIDE":{
1125+
0: HCLK_PINS((19, 0), [("CALIB", 19, 0, "D0"), ("RESETN", 19, 0, "D2")], [("RESETN", 19, 0, "D4")], [("RESETN", 19, 0, "C0")]),
1126+
1: HCLK_PINS((19, 37), [("CALIB", 19, 0, "D1"), ("RESETN", 19, 0, "D3")], [("RESETN", 19, 0, "D5")], [("RESETN", 19, 0, "C1")])
1127+
},
1128+
},
10571129
}
10581130

10591131

@@ -1075,7 +1147,7 @@ def _iter_edge_coords(dev):
10751147

10761148
def add_hclk_bels(dat, dev, device):
10771149
#Stub for parts that don't have HCLK bel support yet
1078-
if device not in ("GW2A-18", "GW2A-18C", "GW1N-9C"):
1150+
if device not in ("GW2A-18", "GW2A-18C", "GW1N-9", "GW1N-9C", "GW1N-1", "GW1NZ-1", "GW1NS-4", "GW1N-4"):
10791151
to_connect = ['HCLK0_SECT0_IN', 'HCLK0_SECT1_IN', 'HCLK1_SECT0_IN', 'HCLK1_SECT1_IN']
10801152
for x in range(dev.cols):
10811153
for y in range(dev.rows):
@@ -1092,6 +1164,22 @@ def add_hclk_bels(dat, dev, device):
10921164
device = "GW2A-18"
10931165
device_hclk_pins = _device_hclk_pin_dict[device]
10941166

1167+
if device == 'GW1NS-4':
1168+
node_name = 'X16Y19/HCLK0_SECT0_IN'
1169+
node_name = add_node(dev, node_name, 'HCLK', 19, 16, 'HCLK0_SECT0_IN')
1170+
node_name = add_node(dev, node_name, 'HCLK', 19, 17, 'HCLK0_SECT0_IN')
1171+
node_name = 'X17Y19/HCLK1_SECT0_IN'
1172+
node_name = add_node(dev, node_name, 'HCLK', 19, 17, 'HCLK1_SECT0_IN')
1173+
node_name = add_node(dev, node_name, 'HCLK', 19, 20, 'HCLK1_SECT0_IN')
1174+
node_name = 'X17Y19/HCLK1_SECT1_IN'
1175+
node_name = add_node(dev, node_name, 'HCLK', 19, 17, 'HCLK1_SECT1_IN')
1176+
node_name = add_node(dev, node_name, 'HCLK', 19, 20, 'HCLK1_SECT1_IN')
1177+
node_name = 'X17Y19/HCLK_IN2'
1178+
node_name = add_node(dev, node_name, 'HCLK', 19, 17, 'HCLK_IN2')
1179+
node_name = add_node(dev, node_name, 'HCLK', 19, 20, 'HCLK_IN2')
1180+
node_name = 'X17Y19/HCLK_IN3'
1181+
node_name = add_node(dev, node_name, 'HCLK', 19, 17, 'HCLK_IN3')
1182+
add_node(dev, node_name, 'HCLK', 19, 20, 'HCLK_IN3')
10951183

10961184
#There is a sleight of hand going on here - there is likely only one physical CLKDIV bel per HCLK
10971185
#However because of how they are connected, and how I suspect that the muxes that utilize them are,
@@ -1132,7 +1220,7 @@ def add_hclk_bels(dat, dev, device):
11321220
dev.grid[tile_row][tile_col].bels[clkdiv2_name] = clkdiv2
11331221
dev.grid[tile_row][tile_col].bels[clkdiv_name] = clkdiv #We still create this so as not to break the PnR logic
11341222

1135-
if device in ("GW1N-9C, GW1NR-9C"):
1223+
if device == "GW1N-9C":
11361224
clkdiv2_in = f"HCLK{idx}_SECT{section}_IN" if section==0 else f"HCLK_IN{idx*2+section}"
11371225
dev.hclk_pips[tile_row,tile_col][clkdiv2.portmap["HCLKIN"]] = {clkdiv2_in:set()}
11381226
sect_div2_mux = f"HCLK{idx}_SECT{section}_MUX_DIV2"
@@ -1150,7 +1238,6 @@ def add_hclk_bels(dat, dev, device):
11501238

11511239
else:
11521240
dev.hclk_pips[tile_row,tile_col][clkdiv2.portmap["HCLKIN"]] = {f"HCLK{idx}_SECT{section}_IN":set()}
1153-
# sect_div2_mux = f"HCLK{idx}_SECT{section}_MUX_DIV2"
11541241
sect_div2_mux = f"HCLK{idx}_SECT{section}_MUX2"
11551242
dev.hclk_pips[tile_row,tile_col][sect_div2_mux] = {f"HCLK{idx}_SECT{section}_IN":set(), clkdiv2.portmap["CLKOUT"]:set()}
11561243
dev.hclk_pips[tile_row,tile_col][clkdiv.portmap["HCLKIN"]] = ({sect_div2_mux:set()})
@@ -1204,7 +1291,8 @@ def fse_create_hclk_nodes(dev, device, fse, dat: Datfile):
12041291
add_node(dev, f'HCLKMUX{src[-1]}', "GLOBAL_CLK", row, col, src)
12051292
# strange GW1N-9C input-input aliases
12061293
for i in {0, 2}:
1207-
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}'))
1294+
add_node(dev, f'X{col}Y{row}/HCLK9-{i}', 'HCLK', row, col, f'HCLK_IN{i}')
1295+
add_node(dev, f'X{col}Y{row}/HCLK9-{i}', 'HCLK', row, col, f'HCLK_9IN{i}')
12081296
# GW1N-9C clock pin aliases
12091297
if side != 'B': # it’s still unclear on this side, but the
12101298
# Tangnano9k external clock is not connected here, so we

apycula/gowin_pack.py

+17-4
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,17 @@ def extra_pll_bels(cell, row, col, num, cellname):
8181
yield ('RPLLB', int(row), int(col) + offx * off, num,
8282
cell['parameters'], cell['attributes'], sanitize_name(cellname) + f'B{off}', cell)
8383

84+
def extra_clkdiv_bels(cell, row, col, num, cellname):
85+
if device in {'GW1NS-4'}:
86+
if int(col) == 18:
87+
bel_type = f'{cell["type"]}_AUX'
88+
yield (bel_type, int(row), int(col) + 3, num,
89+
cell['parameters'], cell['attributes'], sanitize_name(cellname) + 'AUX', cell)
90+
if int(col) == 17:
91+
bel_type = f'{cell["type"]}_AUX'
92+
yield (bel_type, int(row), int(col) + 1, num,
93+
cell['parameters'], cell['attributes'], sanitize_name(cellname) + 'AUX', cell)
94+
8495
def extra_mipi_bels(cell, row, col, num, cellname):
8596
yield ('MIPI_IBUF_AUX', int(row), int(col) + 1, num,
8697
cell['parameters'], cell['attributes'], sanitize_name(cellname) + 'AUX', cell)
@@ -184,6 +195,7 @@ def get_bits(init_data):
184195
x0 += 1
185196
y += 1
186197

198+
_clkdiv_cell_types = {'CLKDIV', 'CLKDIV2'}
187199
_bsram_cell_types = {'DP', 'SDP', 'SP', 'ROM'}
188200
_dsp_cell_types = {'ALU54D', 'MULT36X36', 'MULTALU36X18', 'MULTADDALU18X18', 'MULTALU18X18', 'MULT18X18', 'MULT9X9', 'PADD18', 'PADD9'}
189201
def get_bels(data):
@@ -220,6 +232,8 @@ def get_bels(data):
220232
if cell_type == 'rPLL':
221233
cell_type = 'RPLLA'
222234
yield from extra_pll_bels(cell, row, col, num, cellname)
235+
if cell_type in _clkdiv_cell_types:
236+
yield from extra_clkdiv_bels(cell, row, col, num, cellname)
223237
if cell_type in _bsram_cell_types:
224238
yield from extra_bsram_bels(cell, row, col, num, cellname)
225239
if cell_type in _dsp_cell_types:
@@ -2063,10 +2077,9 @@ def set_hclk_attrs(db, params, num, typ, cell_name):
20632077
raise Exception(f"Invalid DIV_MODE {bin_match or params['DIV_MODE']} for CLKDIV {cell_name} on device {device}")
20642078
params["DIV_MODE"] = str(bin_match[0])
20652079

2066-
2067-
if (typ == "CLKDIV2"):
2080+
if typ.startswith("CLKDIV2"):
20682081
attrs[f"BK{section_idx}MUX{hclk_idx}_OUTSEL"] = "DIV2"
2069-
elif (typ == "CLKDIV"):
2082+
elif typ.startswith("CLKDIV"):
20702083
attrs[f"HCLKDIV{hclk_idx}_DIV"] = params["DIV_MODE"]
20712084
if (section_idx == '1'):
20722085
attrs[f"HCLKDCS{hclk_idx}_SEL"] = f"HCLKBK{section_idx}{hclk_idx}"
@@ -2608,7 +2621,7 @@ def place(db, tilemap, bels, cst, args):
26082621
# for the corresponding HCLK and set its fuses.
26092622
_, wire, _, side = db.extra_func[row - 1, col -1]['dhcen'][int(num)]['pip']
26102623
hclk_attrs = find_and_set_dhcen_hclk_fuses(db, tilemap, wire, side)
2611-
elif typ in ["CLKDIV", "CLKDIV2"]:
2624+
elif typ.startswith("CLKDIV"):
26122625
hclk_attrs = set_hclk_attrs(db, parms, num, typ, cellname)
26132626
bits = get_shortval_fuses(db, tiledata.ttyp, hclk_attrs, "HCLK")
26142627
for r, c in bits:

apycula/gowin_unpack.py

+5
Original file line numberDiff line numberDiff line change
@@ -333,6 +333,11 @@ def parse_tile_(db, row, col, tile, default=True, noalias=False, noiostd = True)
333333
skip_bels = set()
334334
#print((row, col))
335335
tiledata = db.grid[row][col]
336+
#if 'HCLK' in db.shortval[tiledata.ttyp].keys():
337+
# attrvals =parse_attrvals(tile, db.logicinfo['HCLK'], db.shortval[tiledata.ttyp]['HCLK'], attrids.hclk_attrids)
338+
# if attrvals:
339+
# print(row, col, attrvals)
340+
336341
clock_pips = {}
337342
bels = {}
338343
for name, bel in tiledata.bels.items():

0 commit comments

Comments
 (0)