Add LUT route-through pips to iCE40 architecture database

Signed-off-by: Clifford Wolf <clifford@clifford.at>
This commit is contained in:
Clifford Wolf 2018-08-02 16:28:47 +02:00
parent 0208897aa3
commit 36009645ce
3 changed files with 71 additions and 6 deletions

View File

@ -141,6 +141,7 @@ static const int max_switch_bits = 5;
NPNR_PACKED_STRUCT(struct SwitchInfoPOD {
int32_t num_bits;
int32_t bel;
int8_t x, y;
ConfigBitPOD cbits[max_switch_bits];
});
@ -598,7 +599,16 @@ struct Arch : BaseCtx
bool checkPipAvail(PipId pip) const
{
NPNR_ASSERT(pip != PipId());
return switches_locked[chip_info->pip_data[pip.index].switch_index] == IdString();
int switch_idx = chip_info->pip_data[pip.index].switch_index;
if (switches_locked[switch_idx] != IdString())
return false;
int bel_idx = chip_info->bits_info->switches[switch_idx].bel;
if (bel_idx >= 0 && bel_to_cell[bel_idx] != IdString())
return false;
return true;
}
IdString getBoundPipNet(PipId pip) const

View File

@ -271,6 +271,16 @@ def pipdelay(src_idx, dst_idx, db):
if re.match(r"ram/(MASK|RADDR|WADDR|WDATA)_", dst[2]):
return db["InMux.I.O"]
if re.match(r"lutff_\d+/out", dst[2]):
if re.match(r"lutff_\d+/in_0", src[2]):
return db["LogicCell40.in0.lcout"]
if re.match(r"lutff_\d+/in_1", src[2]):
return db["LogicCell40.in1.lcout"]
if re.match(r"lutff_\d+/in_2", src[2]):
return db["LogicCell40.in2.lcout"]
if re.match(r"lutff_\d+/in_3", src[2]):
return db["LogicCell40.in3.lcout"]
print(src, dst, src_idx, dst_idx, src_type, dst_type, file=sys.stderr)
assert 0
@ -316,12 +326,12 @@ with open(args.filename, "r") as f:
if line[0] == ".buffer":
mode = ("buffer", int(line[3]), int(line[1]), int(line[2]))
switches.append((line[3], int(line[1]), int(line[2]), line[4:]))
switches.append((int(line[1]), int(line[2]), line[4:], -1))
continue
if line[0] == ".routing":
mode = ("routing", int(line[3]), int(line[1]), int(line[2]))
switches.append((line[3], int(line[1]), int(line[2]), line[4:]))
switches.append((int(line[1]), int(line[2]), line[4:], -1))
continue
if line[0] == ".io_tile":
@ -499,6 +509,22 @@ def add_wire(x, y, name):
wire_names_r[wire_idx] = wname
wire_segments[wire_idx] = dict()
def add_switch(x, y, bel=-1):
switches.append((x, y, [], bel))
def add_pip(src, dst):
x, y, _, _ = switches[-1]
if src not in wire_downhill:
wire_downhill[src] = set()
wire_downhill[src].add(dst)
if dst not in wire_uphill:
wire_uphill[dst] = set()
wire_uphill[dst].add(src)
pip_xy[(src, dst)] = (x, y, 0, len(switches) - 1)
# Add virtual padin wires
for i in range(8):
add_wire(0, 0, "padin_%d" % i)
@ -555,6 +581,13 @@ def add_bel_lc(x, y, z):
if wire_lout is not None:
add_bel_output(bel, wire_lout, "LO")
# route-through LUTs
add_switch(x, y, bel)
add_pip(wire_in_0, wire_out)
add_pip(wire_in_1, wire_out)
add_pip(wire_in_2, wire_out)
add_pip(wire_in_3, wire_out)
def add_bel_io(x, y, z):
bel = len(bel_name)
bel_name.append("X%d/Y%d/io%d" % (x, y, z))
@ -996,7 +1029,7 @@ for info in pipinfo:
switchinfo = []
for switch in switches:
dst, x, y, bits = switch
x, y, bits, bel = switch
bitlist = []
for b in bits:
m = cbit_re.match(b)
@ -1006,11 +1039,13 @@ for switch in switches:
si["x"] = x
si["y"] = y
si["bits"] = bitlist
si["bel"] = bel
switchinfo.append(si)
bba.l("switch_data_%s" % dev_name, "SwitchInfoPOD")
for info in switchinfo:
bba.u32(len(info["bits"]), "num_bits")
bba.u32(info["bel"], "bel")
bba.u8(info["x"], "x")
bba.u8(info["y"], "y")
for i in range(5):

View File

@ -696,11 +696,30 @@ void gfxTilePip(std::vector<GraphicElement> &g, int x, int y, GfxTileWireId src,
{
float x1, y1, x2, y2;
if (getWireXY_main(src, x1, y1) && getWireXY_main(dst, x2, y2))
if (getWireXY_main(src, x1, y1) && getWireXY_main(dst, x2, y2)) {
pipGfx(g, x, y, x1, y1, x2, y2, main_swbox_x1, main_swbox_y1, main_swbox_x2, main_swbox_y2, style);
return;
}
if (getWireXY_local(src, x1, y1) && getWireXY_local(dst, x2, y2))
if (getWireXY_local(src, x1, y1) && getWireXY_local(dst, x2, y2)) {
pipGfx(g, x, y, x1, y1, x2, y2, local_swbox_x1, local_swbox_y1, local_swbox_x2, local_swbox_y2, style);
return;
}
if (TILE_WIRE_LUTFF_0_IN_0 <= src && src <= TILE_WIRE_LUTFF_7_IN_3 && TILE_WIRE_LUTFF_0_OUT <= dst && dst <= TILE_WIRE_LUTFF_7_OUT) {
int lut_idx = (src - TILE_WIRE_LUTFF_0_IN_0) / 4;
int in_idx = (src - TILE_WIRE_LUTFF_0_IN_0) % 4;
GraphicElement el;
el.type = GraphicElement::TYPE_ARROW;
el.style = style;
el.x1 = x + logic_cell_x1;
el.x2 = x + logic_cell_x2;
el.y1 = y + (logic_cell_y1 + logic_cell_y2) / 2 - 0.0075 + (0.005 * in_idx) + lut_idx * logic_cell_pitch;
el.y2 = y + (logic_cell_y1 + logic_cell_y2) / 2 + lut_idx * logic_cell_pitch;
g.push_back(el);
return;
}
if (src == TILE_WIRE_CARRY_IN && dst == TILE_WIRE_CARRY_IN_MUX) {
GraphicElement el;
@ -711,6 +730,7 @@ void gfxTilePip(std::vector<GraphicElement> &g, int x, int y, GfxTileWireId src,
el.y1 = y + 0.01;
el.y2 = y + 0.02;
g.push_back(el);
return;
}
}