aboutsummaryrefslogtreecommitdiffstats
path: root/ice40/arch.cc
diff options
context:
space:
mode:
Diffstat (limited to 'ice40/arch.cc')
-rw-r--r--ice40/arch.cc231
1 files changed, 58 insertions, 173 deletions
diff --git a/ice40/arch.cc b/ice40/arch.cc
index 5e56ea10..7e2dd7f7 100644
--- a/ice40/arch.cc
+++ b/ice40/arch.cc
@@ -32,102 +32,13 @@ NEXTPNR_NAMESPACE_BEGIN
// -----------------------------------------------------------------------
-IdString Arch::belTypeToId(BelType type) const
-{
- if (type == TYPE_ICESTORM_LC)
- return id("ICESTORM_LC");
- if (type == TYPE_ICESTORM_RAM)
- return id("ICESTORM_RAM");
- if (type == TYPE_SB_IO)
- return id("SB_IO");
- if (type == TYPE_SB_GB)
- return id("SB_GB");
- if (type == TYPE_ICESTORM_PLL)
- return id("ICESTORM_PLL");
- if (type == TYPE_SB_WARMBOOT)
- return id("SB_WARMBOOT");
- if (type == TYPE_ICESTORM_DSP)
- return id("ICESTORM_DSP");
- if (type == TYPE_ICESTORM_HFOSC)
- return id("ICESTORM_HFOSC");
- if (type == TYPE_ICESTORM_LFOSC)
- return id("ICESTORM_LFOSC");
- if (type == TYPE_SB_I2C)
- return id("SB_I2C");
- if (type == TYPE_SB_SPI)
- return id("SB_SPI");
- if (type == TYPE_IO_I3C)
- return id("IO_I3C");
- if (type == TYPE_SB_LEDDA_IP)
- return id("SB_LEDDA_IP");
- if (type == TYPE_SB_RGBA_DRV)
- return id("SB_RGBA_DRV");
- if (type == TYPE_ICESTORM_SPRAM)
- return id("ICESTORM_SPRAM");
- return IdString();
-}
-
-BelType Arch::belTypeFromId(IdString type) const
-{
- if (type == id("ICESTORM_LC"))
- return TYPE_ICESTORM_LC;
- if (type == id("ICESTORM_RAM"))
- return TYPE_ICESTORM_RAM;
- if (type == id("SB_IO"))
- return TYPE_SB_IO;
- if (type == id("SB_GB"))
- return TYPE_SB_GB;
- if (type == id("ICESTORM_PLL"))
- return TYPE_ICESTORM_PLL;
- if (type == id("SB_WARMBOOT"))
- return TYPE_SB_WARMBOOT;
- if (type == id("ICESTORM_DSP"))
- return TYPE_ICESTORM_DSP;
- if (type == id("ICESTORM_HFOSC"))
- return TYPE_ICESTORM_HFOSC;
- if (type == id("ICESTORM_LFOSC"))
- return TYPE_ICESTORM_LFOSC;
- if (type == id("SB_I2C"))
- return TYPE_SB_I2C;
- if (type == id("SB_SPI"))
- return TYPE_SB_SPI;
- if (type == id("IO_I3C"))
- return TYPE_IO_I3C;
- if (type == id("SB_LEDDA_IP"))
- return TYPE_SB_LEDDA_IP;
- if (type == id("SB_RGBA_DRV"))
- return TYPE_SB_RGBA_DRV;
- if (type == id("ICESTORM_SPRAM"))
- return TYPE_ICESTORM_SPRAM;
- return TYPE_NONE;
-}
-
-// -----------------------------------------------------------------------
-
void IdString::initialize_arch(const BaseCtx *ctx)
{
-#define X(t) initialize_add(ctx, #t, PIN_##t);
-
-#include "portpins.inc"
-
+#define X(t) initialize_add(ctx, #t, ID_##t);
+#include "constids.inc"
#undef X
}
-IdString Arch::portPinToId(PortPin type) const
-{
- IdString ret;
- if (type > 0 && type < PIN_MAXIDX)
- ret.index = type;
- return ret;
-}
-
-PortPin Arch::portPinFromId(IdString type) const
-{
- if (type.index > 0 && type.index < PIN_MAXIDX)
- return PortPin(type.index);
- return PIN_NONE;
-}
-
// -----------------------------------------------------------------------
static const ChipInfoPOD *get_chip_info(const RelPtr<ChipInfoPOD> *ptr) { return ptr->get(); }
@@ -182,29 +93,6 @@ Arch::Arch(ArchArgs args) : args(args)
wire_to_net.resize(chip_info->num_wires);
pip_to_net.resize(chip_info->num_pips);
switches_locked.resize(chip_info->num_switches);
-
- // Initialise regularly used IDStrings for performance
- id_glb_buf_out = id("GLOBAL_BUFFER_OUTPUT");
- id_icestorm_lc = id("ICESTORM_LC");
- id_sb_io = id("SB_IO");
- id_sb_gb = id("SB_GB");
- id_cen = id("CEN");
- id_clk = id("CLK");
- id_sr = id("SR");
- id_i0 = id("I0");
- id_i1 = id("I1");
- id_i2 = id("I2");
- id_i3 = id("I3");
- id_dff_en = id("DFF_ENABLE");
- id_carry_en = id("CARRY_ENABLE");
- id_neg_clk = id("NEG_CLK");
- id_cin = id("CIN");
- id_cout = id("COUT");
- id_o = id("O");
- id_lo = id("LO");
- id_icestorm_ram = id("ICESTORM_RAM");
- id_rclk = id("RCLK");
- id_wclk = id("WCLK");
}
// -----------------------------------------------------------------------
@@ -310,7 +198,7 @@ BelRange Arch::getBelsByTile(int x, int y) const
return br;
}
-PortType Arch::getBelPinType(BelId bel, PortPin pin) const
+PortType Arch::getBelPinType(BelId bel, IdString pin) const
{
NPNR_ASSERT(bel != BelId());
@@ -319,16 +207,16 @@ PortType Arch::getBelPinType(BelId bel, PortPin pin) const
if (num_bel_wires < 7) {
for (int i = 0; i < num_bel_wires; i++) {
- if (bel_wires[i].port == pin)
+ if (bel_wires[i].port == pin.index)
return PortType(bel_wires[i].type);
}
} else {
int b = 0, e = num_bel_wires - 1;
while (b <= e) {
int i = (b + e) / 2;
- if (bel_wires[i].port == pin)
+ if (bel_wires[i].port == pin.index)
return PortType(bel_wires[i].type);
- if (bel_wires[i].port > pin)
+ if (bel_wires[i].port > pin.index)
e = i - 1;
else
b = i + 1;
@@ -338,7 +226,7 @@ PortType Arch::getBelPinType(BelId bel, PortPin pin) const
return PORT_INOUT;
}
-WireId Arch::getBelPinWire(BelId bel, PortPin pin) const
+WireId Arch::getBelPinWire(BelId bel, IdString pin) const
{
WireId ret;
@@ -349,7 +237,7 @@ WireId Arch::getBelPinWire(BelId bel, PortPin pin) const
if (num_bel_wires < 7) {
for (int i = 0; i < num_bel_wires; i++) {
- if (bel_wires[i].port == pin) {
+ if (bel_wires[i].port == pin.index) {
ret.index = bel_wires[i].wire_index;
break;
}
@@ -358,11 +246,11 @@ WireId Arch::getBelPinWire(BelId bel, PortPin pin) const
int b = 0, e = num_bel_wires - 1;
while (b <= e) {
int i = (b + e) / 2;
- if (bel_wires[i].port == pin) {
+ if (bel_wires[i].port == pin.index) {
ret.index = bel_wires[i].wire_index;
break;
}
- if (bel_wires[i].port > pin)
+ if (bel_wires[i].port > pin.index)
e = i - 1;
else
b = i + 1;
@@ -372,9 +260,9 @@ WireId Arch::getBelPinWire(BelId bel, PortPin pin) const
return ret;
}
-std::vector<PortPin> Arch::getBelPins(BelId bel) const
+std::vector<IdString> Arch::getBelPins(BelId bel) const
{
- std::vector<PortPin> ret;
+ std::vector<IdString> ret;
NPNR_ASSERT(bel != BelId());
@@ -382,7 +270,7 @@ std::vector<PortPin> Arch::getBelPins(BelId bel) const
const BelWirePOD *bel_wires = chip_info->bel_data[bel.index].bel_wires.get();
for (int i = 0; i < num_bel_wires; i++)
- ret.push_back(bel_wires[i].port);
+ ret.push_back(IdString(bel_wires[i].port));
return ret;
}
@@ -644,7 +532,7 @@ std::vector<GroupId> Arch::getGroupGroups(GroupId group) const
bool Arch::getBudgetOverride(const NetInfo *net_info, const PortRef &sink, delay_t &budget) const
{
const auto &driver = net_info->driver;
- if (driver.port == id_cout && sink.port == id_cin) {
+ if (driver.port == id_COUT && sink.port == id_CIN) {
auto driver_loc = getBelLocation(driver.cell->bel);
auto sink_loc = getBelLocation(sink.cell->bel);
if (driver_loc.y == sink_loc.y)
@@ -822,7 +710,7 @@ std::vector<GraphicElement> Arch::getDecalGraphics(DecalId decal) const
auto bel_type = getBelType(bel);
- if (bel_type == TYPE_ICESTORM_LC) {
+ if (bel_type == id_ICESTORM_LC) {
GraphicElement el;
el.type = GraphicElement::TYPE_BOX;
el.style = decal.active ? GraphicElement::STYLE_ACTIVE : GraphicElement::STYLE_INACTIVE;
@@ -835,7 +723,7 @@ std::vector<GraphicElement> Arch::getDecalGraphics(DecalId decal) const
ret.push_back(el);
}
- if (bel_type == TYPE_SB_IO) {
+ if (bel_type == id_SB_IO) {
GraphicElement el;
el.type = GraphicElement::TYPE_BOX;
el.style = decal.active ? GraphicElement::STYLE_ACTIVE : GraphicElement::STYLE_INACTIVE;
@@ -848,7 +736,7 @@ std::vector<GraphicElement> Arch::getDecalGraphics(DecalId decal) const
ret.push_back(el);
}
- if (bel_type == TYPE_ICESTORM_RAM) {
+ if (bel_type == id_ICESTORM_RAM) {
for (int i = 0; i < 2; i++) {
GraphicElement el;
el.type = GraphicElement::TYPE_BOX;
@@ -869,15 +757,12 @@ std::vector<GraphicElement> Arch::getDecalGraphics(DecalId decal) const
bool Arch::getCellDelay(const CellInfo *cell, IdString fromPort, IdString toPort, DelayInfo &delay) const
{
- BelType type = belTypeFromId(cell->type);
for (int i = 0; i < chip_info->num_timing_cells; i++) {
const auto &tc = chip_info->cell_timing[i];
- if (tc.type == type) {
- PortPin fromPin = portPinFromId(fromPort);
- PortPin toPin = portPinFromId(toPort);
+ if (tc.type == cell->type.index) {
for (int j = 0; j < tc.num_paths; j++) {
const auto &path = tc.path_delays[j];
- if (path.from_port == fromPin && path.to_port == toPin) {
+ if (path.from_port == fromPort.index && path.to_port == toPort.index) {
if (fast_part)
delay.delay = path.fast_delay;
else
@@ -894,70 +779,70 @@ bool Arch::getCellDelay(const CellInfo *cell, IdString fromPort, IdString toPort
// Get the port class, also setting clockPort to associated clock if applicable
TimingPortClass Arch::getPortTimingClass(const CellInfo *cell, IdString port, IdString &clockPort) const
{
- if (cell->type == id_icestorm_lc) {
- if (port == id_clk)
+ if (cell->type == id_ICESTORM_LC) {
+ if (port == id_CLK)
return TMG_CLOCK_INPUT;
- if (port == id_cin)
+ if (port == id_CIN)
return TMG_COMB_INPUT;
- if (port == id_cout || port == id_lo)
+ if (port == id_COUT || port == id_LO)
return TMG_COMB_OUTPUT;
if (cell->lcInfo.dffEnable) {
- clockPort = id_clk;
- if (port == id_o)
+ clockPort = id_CLK;
+ if (port == id_O)
return TMG_REGISTER_OUTPUT;
else
return TMG_REGISTER_INPUT;
} else {
- if (port == id_o)
+ if (port == id_O)
return TMG_COMB_OUTPUT;
else
return TMG_COMB_INPUT;
}
- } else if (cell->type == id_icestorm_ram) {
+ } else if (cell->type == id_ICESTORM_RAM) {
- if (port == id_rclk || port == id_wclk)
+ if (port == id_RCLK || port == id_WCLK)
return TMG_CLOCK_INPUT;
if (port.str(this)[0] == 'R')
- clockPort = id_rclk;
+ clockPort = id_RCLK;
else
- clockPort = id_wclk;
+ clockPort = id_WCLK;
if (cell->ports.at(port).type == PORT_OUT)
return TMG_REGISTER_OUTPUT;
else
return TMG_REGISTER_INPUT;
- } else if (cell->type == id("ICESTORM_DSP") || cell->type == id("ICESTORM_SPRAM")) {
- clockPort = id_clk;
- if (port == id_clk)
+ } else if (cell->type == id_ICESTORM_DSP || cell->type == id_ICESTORM_SPRAM) {
+ clockPort = id_CLK;
+ if (port == id_CLK)
return TMG_CLOCK_INPUT;
else if (cell->ports.at(port).type == PORT_OUT)
return TMG_REGISTER_OUTPUT;
else
return TMG_REGISTER_INPUT;
- } else if (cell->type == id_sb_io) {
- if (port == id("D_IN_0") || port == id("D_IN_1"))
+ } else if (cell->type == id_SB_IO) {
+ if (port == id_D_IN_0 || port == id_D_IN_1)
return TMG_STARTPOINT;
- if (port == id("D_OUT_0") || port == id("D_OUT_1") || port == id("OUTPUT_ENABLE"))
+ if (port == id_D_OUT_0 || port == id_D_OUT_1 || port == id_OUTPUT_ENABLE)
return TMG_ENDPOINT;
return TMG_IGNORE;
- } else if (cell->type == id("ICESTORM_PLL")) {
- if (port == id("PLLOUT_A") || port == id("PLLOUT_B"))
+ } else if (cell->type == id_ICESTORM_PLL) {
+ if (port == id_PLLOUT_A || port == id_PLLOUT_B)
return TMG_GEN_CLOCK;
return TMG_IGNORE;
- } else if (cell->type == id("ICESTORM_LFOSC")) {
- if (port == id("CLKLF"))
+ } else if (cell->type == id_ICESTORM_LFOSC) {
+ if (port == id_CLKLF)
return TMG_GEN_CLOCK;
return TMG_IGNORE;
- } else if (cell->type == id("ICESTORM_HFOSC")) {
- if (port == id("CLKHF"))
+ } else if (cell->type == id_ICESTORM_HFOSC) {
+ if (port == id_CLKHF)
return TMG_GEN_CLOCK;
return TMG_IGNORE;
- } else if (cell->type == id_sb_gb) {
- if (port == id_glb_buf_out)
+ } else if (cell->type == id_SB_GB) {
+ if (port == id_GLOBAL_BUFFER_OUTPUT)
return TMG_COMB_OUTPUT;
return TMG_COMB_INPUT;
- } else if (cell->type == id("SB_WARMBOOT")) {
+ } else if (cell->type == id_SB_WARMBOOT) {
return TMG_ENDPOINT;
}
log_error("no timing info for port '%s' of cell type '%s'\n", port.c_str(this), cell->type.c_str(this));
@@ -967,7 +852,7 @@ bool Arch::isGlobalNet(const NetInfo *net) const
{
if (net == nullptr)
return false;
- return net->driver.cell != nullptr && net->driver.port == id_glb_buf_out;
+ return net->driver.cell != nullptr && net->driver.port == id_GLOBAL_BUFFER_OUTPUT;
}
// Assign arch arg info
@@ -994,22 +879,22 @@ void Arch::assignArchInfo()
void Arch::assignCellInfo(CellInfo *cell)
{
- cell->belType = belTypeFromId(cell->type);
- if (cell->type == id_icestorm_lc) {
- cell->lcInfo.dffEnable = bool_or_default(cell->params, id_dff_en);
- cell->lcInfo.carryEnable = bool_or_default(cell->params, id_carry_en);
- cell->lcInfo.negClk = bool_or_default(cell->params, id_neg_clk);
- cell->lcInfo.clk = get_net_or_empty(cell, id_clk);
- cell->lcInfo.cen = get_net_or_empty(cell, id_cen);
- cell->lcInfo.sr = get_net_or_empty(cell, id_sr);
+ cell->belType = cell->type;
+ if (cell->type == id_ICESTORM_LC) {
+ cell->lcInfo.dffEnable = bool_or_default(cell->params, id_DFF_ENABLE);
+ cell->lcInfo.carryEnable = bool_or_default(cell->params, id_CARRY_ENABLE);
+ cell->lcInfo.negClk = bool_or_default(cell->params, id_NEG_CLK);
+ cell->lcInfo.clk = get_net_or_empty(cell, id_CLK);
+ cell->lcInfo.cen = get_net_or_empty(cell, id_CEN);
+ cell->lcInfo.sr = get_net_or_empty(cell, id_SR);
cell->lcInfo.inputCount = 0;
- if (get_net_or_empty(cell, id_i0))
+ if (get_net_or_empty(cell, id_I0))
cell->lcInfo.inputCount++;
- if (get_net_or_empty(cell, id_i1))
+ if (get_net_or_empty(cell, id_I1))
cell->lcInfo.inputCount++;
- if (get_net_or_empty(cell, id_i2))
+ if (get_net_or_empty(cell, id_I2))
cell->lcInfo.inputCount++;
- if (get_net_or_empty(cell, id_i3))
+ if (get_net_or_empty(cell, id_I3))
cell->lcInfo.inputCount++;
}
}