ice40: Add IO config to bitstream
Signed-off-by: David Shah <davey1576@gmail.com>
This commit is contained in:
parent
d0bd657551
commit
30e672313d
@ -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++) {
|
||||
|
15
ice40/chip.h
15
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;
|
||||
}
|
||||
}
|
||||
|
@ -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)))
|
||||
|
Loading…
Reference in New Issue
Block a user