Skip to content

Commit

Permalink
Unpack a DFFs with separated inputs from LUTs.
Browse files Browse the repository at this point in the history
Use SELx wires instead of direct LUT->FF conenction.

Signed-off-by: YRabbit <[email protected]>
  • Loading branch information
yrabbit committed Feb 17, 2025
1 parent 10e384c commit 35e5aa7
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 5 deletions.
17 changes: 13 additions & 4 deletions apycula/gowin_unpack.py
Original file line number Diff line number Diff line change
Expand Up @@ -395,7 +395,7 @@ def parse_tile_(db, row, col, tile, default=True, noalias=False, noiostd = True)
if name.startswith("IOLOGIC"):
idx = name[-1]
attrvals = parse_attrvals(tile, db.logicinfo['IOLOGIC'], db.shortval[tiledata.ttyp][f'IOLOGIC{idx}'], attrids.iologic_attrids)
print(attrvals)
#print(attrvals)
if not attrvals:
continue
# additional IOLOGIC components
Expand Down Expand Up @@ -436,18 +436,20 @@ def parse_tile_(db, row, col, tile, default=True, noalias=False, noiostd = True)
if name.startswith("DFF"):
idx = int(name[3])
attrvals = parse_attrvals(tile, db.logicinfo['SLICE'], db.shortval[tiledata.ttyp][f'CLS{idx // 2}'], attrids.cls_attrids)
#print(row, col, attrvals)
#print('parse', row, col, attrvals)
# skip ALU and unsupported modes
if attrvals.get('MODE') == attrids.cls_attrvals['SSRAM']:
continue
dff_type = get_dff_type(idx, attrvals)
if dff_type:
bels[f'{name}'] = {dff_type}
if f'REG{idx % 2}_SD' in attrvals:
bels[f'{name}'].update({'SD'})
continue
if name.startswith("IOB"):
idx = name[-1]
attrvals = parse_attrvals(tile, db.logicinfo['IOB'], db.longval[tiledata.ttyp][f'IOB{idx}'], attrids.iob_attrids)
print(row, col, attrvals)
#print(row, col, attrvals)
try: # we can ask for invalid pin here because the IOBs share some stuff
bank = chipdb.loc2bank(db, row, col)
except KeyError:
Expand Down Expand Up @@ -1046,14 +1048,21 @@ def tile2verilog(dbrow, dbcol, bels, pips, clock_pips, mod, cst, db):
mod.primitives[name] = osc
elif typ == "DFF":
#print(flags)
sd = False
if 'SD' in flags:
sd = True
flags.remove('SD')
kind, = flags # DFF only have one flag
if kind == "RAM": continue
idx = int(idx)
port = dffmap[kind]
name = f"R{row}C{col}_{typ}E_{idx}"
dff = codegen.Primitive(kind+"E", name)
dff.portmap['CLK'] = f"R{row}C{col}_CLK{idx//2}"
dff.portmap['D'] = f"R{row}C{col}_F{idx}"
if sd:
dff.portmap['D'] = f"R{row}C{col}_SEL{idx}"
else:
dff.portmap['D'] = f"R{row}C{col}_F{idx}"
dff.portmap['Q'] = f"R{row}C{col}_Q{idx}"
dff.portmap['CE'] = f"R{row}C{col}_CE{idx//2}"
if port:
Expand Down
2 changes: 1 addition & 1 deletion doc/architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ Gowin FPGAs have a LUT4 architecture common to many smaller FPGA architectures.

Each Configurable logic unit consists of 8 LUT4s grouped in 4 slices, of which 3 have data flip-flops. Each slice shares certain resources such as clock inputs and reset lines.

Each LUT4 has 4 inputs and one output that is directly connected to the data flip-flop input. The LUT output can be used independently, but the flip-flop is always used through the LUT. Each pair of flip flops has data in and out, clock, clock enable, and set/reset. Each pair of flip-flops can be configured for rising edge or falling edge sensitivity, and asynchronous or synchronous set or clear.
Each LUT4 has 4 inputs and one output that is directly connected to the data flip-flop input. The LUT output can be used independently, as well as flipflop input D (although we do not generate such images at the moment, but we can unpack them correctly - in this case the SELx wire is the flipflop input). Each pair of flip flops has data in and out, clock, clock enable, and set/reset. Each pair of flip-flops can be configured for rising edge or falling edge sensitivity, and asynchronous or synchronous set or clear.

These tiles are connected with various multiplexers to adjacent tiles as well as global clock lines. Each tile has 8 tile-local wires, 4 one-hop wires of which 2 are shared between north/south and east/west, 8 two-hop wires with one-hop taps, and 4 eight-hop wires with four-hop taps. An overview of all wires can be seen below.

Expand Down

0 comments on commit 35e5aa7

Please sign in to comment.