diff options
author | David Shah <davey1576@gmail.com> | 2018-06-10 13:24:48 +0200 |
---|---|---|
committer | David Shah <davey1576@gmail.com> | 2018-06-10 13:24:48 +0200 |
commit | 30e672313dc1dd1223b1641583ea509417ae9b61 (patch) | |
tree | 809b11dcd8709dfad82f4142e02f4531840703d6 /ice40 | |
parent | d0bd657551e449aa14a3fcc04401cbd9efb9fb96 (diff) | |
download | nextpnr-30e672313dc1dd1223b1641583ea509417ae9b61.tar.gz nextpnr-30e672313dc1dd1223b1641583ea509417ae9b61.tar.bz2 nextpnr-30e672313dc1dd1223b1641583ea509417ae9b61.zip |
ice40: Add IO config to bitstream
Signed-off-by: David Shah <davey1576@gmail.com>
Diffstat (limited to 'ice40')
-rw-r--r-- | ice40/bitstream.cc | 76 | ||||
-rw-r--r-- | ice40/chip.h | 15 | ||||
-rw-r--r-- | ice40/chipdb.py | 19 |
3 files changed, 93 insertions, 17 deletions
diff --git a/ice40/bitstream.cc b/ice40/bitstream.cc index 6ed6279d..524a8fee 100644 --- a/ice40/bitstream.cc +++ b/ice40/bitstream.cc @@ -25,7 +25,9 @@ inline TileType tile_at(const Chip &chip, int x, int y) return chip.chip_info.tile_grid[y * chip.chip_info.width + x]; } -const ConfigEntryPOD &find_config(const TileInfoPOD &tile, const std::string &name) { +const ConfigEntryPOD &find_config(const TileInfoPOD &tile, + const std::string &name) +{ for (int i = 0; i < tile.num_config_entries; i++) { if (std::string(tile.entries[i].name) == name) { return tile.entries[i]; @@ -34,7 +36,22 @@ const ConfigEntryPOD &find_config(const TileInfoPOD &tile, const std::string &na assert(false); } -void set_config(const TileInfoPOD &ti, vector<vector<int8_t>> &tile_cfg, const std::string &name, bool value, int index = -1) { +std::tuple<int8_t, int8_t, int8_t> get_ieren(const BitstreamInfoPOD &bi, + int8_t x, int8_t y, int8_t z) +{ + for (int i = 0; i < bi.num_ierens; i++) { + auto ie = bi.ierens[i]; + if (ie.iox == x && ie.ioy == y && ie.ioz == z) { + return std::make_tuple(ie.ierx, ie.iery, ie.ierz); + } + } + // No pin at this location + return std::make_tuple(-1, -1, -1); +}; + +void set_config(const TileInfoPOD &ti, vector<vector<int8_t>> &tile_cfg, + const std::string &name, bool value, int index = -1) +{ const ConfigEntryPOD &cfg = find_config(ti, name); if (index == -1) { for (int i = 0; i < cfg.num_bits; i++) { @@ -90,8 +107,12 @@ void write_asc(const Design &design, std::ostream &out) const PipInfoPOD &pi = ci.pip_data[pip.index]; const SwitchInfoPOD &swi = bi.switches[pi.switch_index]; for (int i = 0; i < swi.num_bits; i++) { - bool val = (pi.switch_mask & (1 << ((swi.num_bits - 1) - i))) != 0; - int8_t &cbit = config.at(swi.y).at(swi.x).at(swi.cbits[i].row).at(swi.cbits[i].col); + bool val = + (pi.switch_mask & (1 << ((swi.num_bits - 1) - i))) != 0; + int8_t &cbit = config.at(swi.y) + .at(swi.x) + .at(swi.cbits[i].row) + .at(swi.cbits[i].col); if (bool(cbit) != 0) assert(false); cbit = val; @@ -101,13 +122,15 @@ void write_asc(const Design &design, std::ostream &out) // Set logic cell config for (auto cell : design.cells) { BelId bel = cell.second->bel; - if (bel == BelId()) - std::cout << "Found unplaced cell " << cell.first << " while generating bitstream!" << std::endl; + if (bel == BelId()) { + std::cout << "Found unplaced cell " << cell.first + << " while generating bitstream!" << std::endl; + continue; + } + const BelInfoPOD &beli = ci.bel_data[bel.index]; + int x = beli.x, y = beli.y, z = beli.z; if (cell.second->type == "ICESTORM_LC") { - const BelInfoPOD &beli = ci.bel_data[bel.index]; - int x = beli.x, y = beli.y, z = beli.z; TileInfoPOD &ti = bi.tiles_nonrouting[TILE_LOGIC]; - unsigned lut_init = std::stoi(cell.second->params["LUT_INIT"]); bool neg_clk = std::stoi(cell.second->params["NEG_CLK"]); bool dff_enable = std::stoi(cell.second->params["DFF_ENABLE"]); @@ -129,15 +152,44 @@ void write_asc(const Design &design, std::ostream &out) lc.at(19) = async_sr; for (int i = 0; i < 20; i++) - set_config(ti, config.at(y).at(x), "LC_" + std::to_string(z), lc.at(i), i); + set_config(ti, config.at(y).at(x), "LC_" + std::to_string(z), + lc.at(i), i); set_config(ti, config.at(y).at(x), "NegClk", neg_clk); } else if (cell.second->type == "SB_IO") { - // TODO + TileInfoPOD &ti = bi.tiles_nonrouting[TILE_IO]; + unsigned pin_type = std::stoi(cell.second->params["PIN_TYPE"]); + bool neg_trigger = std::stoi(cell.second->params["NEG_TRIGGER"]); + bool pullup = std::stoi(cell.second->params["PULLUP"]); + for (int i = 0; i < 6; i++) { + bool val = (pin_type >> i) & 0x01; + set_config(ti, config.at(y).at(x), + "IOB_" + std::to_string(z) + ".PINTYPE_" + + std::to_string(i), + val); + } + + auto ieren = get_ieren(bi, x, y, z); + int iex, iey, iez; + std::tie(iex, iey, iez) = ieren; + assert(iez != -1); + + bool input_en = false; + if ((chip.wire_to_net[chip.getWireBelPin(bel, PIN_D_IN_0).index] != + IdString()) || + (chip.wire_to_net[chip.getWireBelPin(bel, PIN_D_IN_1).index] != + IdString())) { + input_en = true; + } + set_config(ti, config.at(iey).at(iex), + "IoCtrl.IE_" + std::to_string(iez), !input_en); + set_config(ti, config.at(iey).at(iex), + "IoCtrl.REN_" + std::to_string(iez), !pullup); } else { assert(false); } } - // Set other config bits - currently just disable RAM to stop icebox_vlog crashing + // Set other config bits - currently just disable RAM to stop icebox_vlog + // crashing // TODO: ColBufCtrl , unused IO for (int y = 0; y < ci.height; y++) { for (int x = 0; x < ci.width; x++) { diff --git a/ice40/chip.h b/ice40/chip.h index 1a978fcd..84b2196a 100644 --- a/ice40/chip.h +++ b/ice40/chip.h @@ -144,11 +144,18 @@ struct SwitchInfoPOD ConfigBitPOD cbits[max_switch_bits]; }; +struct IerenInfoPOD +{ + int8_t iox, ioy, ioz; + int8_t ierx, iery, ierz; +}; + struct BitstreamInfoPOD { - int num_switches; + int num_switches, num_ierens; TileInfoPOD *tiles_nonrouting; SwitchInfoPOD *switches; + IerenInfoPOD *ierens; }; struct ChipInfoPOD @@ -563,7 +570,8 @@ struct Chip pip_to_net[pip.index] = net; // Optimise? for (int i = 0; i < chip_info.num_pips; i++) { - if (chip_info.pip_data[i].switch_index == chip_info.pip_data[pip.index].switch_index) + if (chip_info.pip_data[i].switch_index == + chip_info.pip_data[pip.index].switch_index) pips_locked[i] = true; } } @@ -575,7 +583,8 @@ struct Chip pip_to_net[pip.index] = IdString(); // Optimise? for (int i = 0; i < chip_info.num_pips; i++) { - if (chip_info.pip_data[i].switch_index == chip_info.pip_data[pip.index].switch_index) + if (chip_info.pip_data[i].switch_index == + chip_info.pip_data[pip.index].switch_index) pips_locked[i] = false; } } diff --git a/ice40/chipdb.py b/ice40/chipdb.py index a543298c..a92704eb 100644 --- a/ice40/chipdb.py +++ b/ice40/chipdb.py @@ -21,6 +21,8 @@ bel_wires = list() switches = list() +ierens = list() + wire_uphill_belport = dict() wire_downhill_belports = dict() @@ -117,6 +119,10 @@ with open(sys.argv[1], "r") as f: tile_sizes[4] = (int(line[1]), int(line[2])) continue + if line[0] == ".ieren": + mode = ("ieren",) + continue + if (line[0][0] == ".") or (mode is None): mode = None continue @@ -173,6 +179,8 @@ with open(sys.argv[1], "r") as f: bits.append((int(m.group(1)), int(m.group(2)))) tile_bits[mode[1]].append((name, bits)) + if mode[0] == "ieren": + ierens.append(tuple([int(_) for _ in line])) def add_bel_input(bel, wire, port): if wire not in wire_downhill_belports: wire_downhill_belports[wire] = set() @@ -409,7 +417,9 @@ for switch in switches: switchinfo.append("{%d, %d, %d, {%s}}" % (x, y, len(bits), cbits)) switchid += 1 - +iereninfo = [] +for ieren in ierens: + iereninfo.append("{%d, %d, %d, %d, %d, %d}" % ieren) print("static WireInfoPOD wire_data_%s[%d] = {" % (dev_name, num_wires)) print(",\n".join(wireinfo)) @@ -427,8 +437,13 @@ print("static TileInfoPOD tile_data_%s[%d] = {" % (dev_name, num_tile_types)) print(",\n".join(tileinfo)) print("};") +print("static IerenInfoPOD ieren_data_%s[%d] = {" % (dev_name, len(iereninfo))) +print(",\n".join(iereninfo)) +print("};") + + print("static BitstreamInfoPOD bits_info_%s = {" % dev_name) -print("%d, tile_data_%s, switch_data_%s" % (len(switchinfo), dev_name, dev_name)) +print("%d, %d, tile_data_%s, switch_data_%s, ieren_data_%s" % (len(switchinfo), len(iereninfo), dev_name, dev_name, dev_name)) print("};") print("static TileType tile_grid_%s[%d] = {" % (dev_name, len(tilegrid))) |