Finishes placement now
This commit is contained in:
parent
32f5346378
commit
57c273898c
95
xc7/arch.cc
95
xc7/arch.cc
@ -173,6 +173,9 @@ WireId Arch::getBelPinWire(BelId bel, IdString pin) const
|
|||||||
{
|
{
|
||||||
WireId ret;
|
WireId ret;
|
||||||
|
|
||||||
|
const auto& site = ddbSites->getSite(bel.index);
|
||||||
|
ret.index = site.getPinTilewire(pin.str(this));
|
||||||
|
|
||||||
// NPNR_ASSERT(bel != BelId());
|
// NPNR_ASSERT(bel != BelId());
|
||||||
//
|
//
|
||||||
// int num_bel_wires = chip_info->bel_data[bel.index].num_bel_wires;
|
// int num_bel_wires = chip_info->bel_data[bel.index].num_bel_wires;
|
||||||
@ -229,9 +232,9 @@ WireId Arch::getWireByName(IdString name) const
|
|||||||
wire_by_name[id(chip_info->wire_data[i].name.get())] = i;
|
wire_by_name[id(chip_info->wire_data[i].name.get())] = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto it = wire_by_name.find(name);
|
//auto it = wire_by_name.find(name);
|
||||||
if (it != wire_by_name.end())
|
//if (it != wire_by_name.end())
|
||||||
ret.index = it->second;
|
// ret.index = it->second;
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -239,38 +242,38 @@ WireId Arch::getWireByName(IdString name) const
|
|||||||
IdString Arch::getWireType(WireId wire) const
|
IdString Arch::getWireType(WireId wire) const
|
||||||
{
|
{
|
||||||
NPNR_ASSERT(wire != WireId());
|
NPNR_ASSERT(wire != WireId());
|
||||||
switch (chip_info->wire_data[wire.index].type) {
|
// switch (chip_info->wire_data[wire.index].type) {
|
||||||
case WireInfoPOD::WIRE_TYPE_NONE:
|
// case WireInfoPOD::WIRE_TYPE_NONE:
|
||||||
return IdString();
|
// return IdString();
|
||||||
case WireInfoPOD::WIRE_TYPE_GLB2LOCAL:
|
// case WireInfoPOD::WIRE_TYPE_GLB2LOCAL:
|
||||||
return id("GLB2LOCAL");
|
// return id("GLB2LOCAL");
|
||||||
case WireInfoPOD::WIRE_TYPE_GLB_NETWK:
|
// case WireInfoPOD::WIRE_TYPE_GLB_NETWK:
|
||||||
return id("GLB_NETWK");
|
// return id("GLB_NETWK");
|
||||||
case WireInfoPOD::WIRE_TYPE_LOCAL:
|
// case WireInfoPOD::WIRE_TYPE_LOCAL:
|
||||||
return id("LOCAL");
|
// return id("LOCAL");
|
||||||
case WireInfoPOD::WIRE_TYPE_LUTFF_IN:
|
// case WireInfoPOD::WIRE_TYPE_LUTFF_IN:
|
||||||
return id("LUTFF_IN");
|
// return id("LUTFF_IN");
|
||||||
case WireInfoPOD::WIRE_TYPE_LUTFF_IN_LUT:
|
// case WireInfoPOD::WIRE_TYPE_LUTFF_IN_LUT:
|
||||||
return id("LUTFF_IN_LUT");
|
// return id("LUTFF_IN_LUT");
|
||||||
case WireInfoPOD::WIRE_TYPE_LUTFF_LOUT:
|
// case WireInfoPOD::WIRE_TYPE_LUTFF_LOUT:
|
||||||
return id("LUTFF_LOUT");
|
// return id("LUTFF_LOUT");
|
||||||
case WireInfoPOD::WIRE_TYPE_LUTFF_OUT:
|
// case WireInfoPOD::WIRE_TYPE_LUTFF_OUT:
|
||||||
return id("LUTFF_OUT");
|
// return id("LUTFF_OUT");
|
||||||
case WireInfoPOD::WIRE_TYPE_LUTFF_COUT:
|
// case WireInfoPOD::WIRE_TYPE_LUTFF_COUT:
|
||||||
return id("LUTFF_COUT");
|
// return id("LUTFF_COUT");
|
||||||
case WireInfoPOD::WIRE_TYPE_LUTFF_GLOBAL:
|
// case WireInfoPOD::WIRE_TYPE_LUTFF_GLOBAL:
|
||||||
return id("LUTFF_GLOBAL");
|
// return id("LUTFF_GLOBAL");
|
||||||
case WireInfoPOD::WIRE_TYPE_CARRY_IN_MUX:
|
// case WireInfoPOD::WIRE_TYPE_CARRY_IN_MUX:
|
||||||
return id("CARRY_IN_MUX");
|
// return id("CARRY_IN_MUX");
|
||||||
case WireInfoPOD::WIRE_TYPE_SP4_V:
|
// case WireInfoPOD::WIRE_TYPE_SP4_V:
|
||||||
return id("SP4_V");
|
// return id("SP4_V");
|
||||||
case WireInfoPOD::WIRE_TYPE_SP4_H:
|
// case WireInfoPOD::WIRE_TYPE_SP4_H:
|
||||||
return id("SP4_H");
|
// return id("SP4_H");
|
||||||
case WireInfoPOD::WIRE_TYPE_SP12_V:
|
// case WireInfoPOD::WIRE_TYPE_SP12_V:
|
||||||
return id("SP12_V");
|
// return id("SP12_V");
|
||||||
case WireInfoPOD::WIRE_TYPE_SP12_H:
|
// case WireInfoPOD::WIRE_TYPE_SP12_H:
|
||||||
return id("SP12_H");
|
// return id("SP12_H");
|
||||||
}
|
// }
|
||||||
return IdString();
|
return IdString();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -507,8 +510,8 @@ DecalXY Arch::getWireDecal(WireId wire) const
|
|||||||
{
|
{
|
||||||
DecalXY decalxy;
|
DecalXY decalxy;
|
||||||
decalxy.decal.type = DecalId::TYPE_WIRE;
|
decalxy.decal.type = DecalId::TYPE_WIRE;
|
||||||
decalxy.decal.index = wire.index;
|
//decalxy.decal.index = wire.index;
|
||||||
decalxy.decal.active = wire_to_net.at(wire.index) != nullptr;
|
//decalxy.decal.active = wire_to_net.at(wire.index) != nullptr;
|
||||||
return decalxy;
|
return decalxy;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -671,6 +674,15 @@ std::vector<GraphicElement> Arch::getDecalGraphics(DecalId decal) const
|
|||||||
|
|
||||||
bool Arch::getCellDelay(const CellInfo *cell, IdString fromPort, IdString toPort, DelayInfo &delay) const
|
bool Arch::getCellDelay(const CellInfo *cell, IdString fromPort, IdString toPort, DelayInfo &delay) const
|
||||||
{
|
{
|
||||||
|
if (cell->type == id_SLICEL)
|
||||||
|
{
|
||||||
|
if (fromPort.index >= id_A1.index && fromPort.index <= id_A6.index)
|
||||||
|
return toPort == id_A || toPort == id_AQ;
|
||||||
|
}
|
||||||
|
else if (cell->type == id_BUFGCTRL)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -682,19 +694,16 @@ TimingPortClass Arch::getPortTimingClass(const CellInfo *cell, IdString port, Id
|
|||||||
return TMG_CLOCK_INPUT;
|
return TMG_CLOCK_INPUT;
|
||||||
if (port == id_CIN)
|
if (port == id_CIN)
|
||||||
return TMG_COMB_INPUT;
|
return TMG_COMB_INPUT;
|
||||||
if (port == id_COUT || port == id_O)
|
if (port == id_COUT || port == id_A)
|
||||||
return TMG_COMB_OUTPUT;
|
return TMG_COMB_OUTPUT;
|
||||||
if (cell->lcInfo.dffEnable) {
|
if (cell->lcInfo.dffEnable) {
|
||||||
clockPort = id_CLK;
|
clockPort = id_CLK;
|
||||||
if (port == id_OQ)
|
if (port == id_AQ)
|
||||||
return TMG_REGISTER_OUTPUT;
|
return TMG_REGISTER_OUTPUT;
|
||||||
else
|
else
|
||||||
return TMG_REGISTER_INPUT;
|
return TMG_REGISTER_INPUT;
|
||||||
} else {
|
} else {
|
||||||
if (port == id_O)
|
return TMG_COMB_INPUT;
|
||||||
return TMG_COMB_OUTPUT;
|
|
||||||
else
|
|
||||||
return TMG_COMB_INPUT;
|
|
||||||
}
|
}
|
||||||
// TODO
|
// TODO
|
||||||
//if (port == id_OMUX)
|
//if (port == id_OMUX)
|
||||||
|
95
xc7/arch.h
95
xc7/arch.h
@ -305,10 +305,11 @@ struct BelPinRange
|
|||||||
|
|
||||||
struct WireIterator
|
struct WireIterator
|
||||||
{
|
{
|
||||||
int cursor = -1;
|
Tilewire cursor;
|
||||||
|
|
||||||
void operator++() { cursor++; }
|
// TODO
|
||||||
bool operator!=(const WireIterator &other) const { return cursor != other.cursor; }
|
void operator++() { /*cursor++;*/ }
|
||||||
|
bool operator!=(const WireIterator &other) const { return !(cursor == other.cursor); }
|
||||||
|
|
||||||
WireId operator*() const
|
WireId operator*() const
|
||||||
{
|
{
|
||||||
@ -511,18 +512,19 @@ struct Arch : BaseCtx
|
|||||||
IdString getWireName(WireId wire) const
|
IdString getWireName(WireId wire) const
|
||||||
{
|
{
|
||||||
NPNR_ASSERT(wire != WireId());
|
NPNR_ASSERT(wire != WireId());
|
||||||
return id(chip_info->wire_data[wire.index].name.get());
|
//return id(chip_info->wire_data[wire.index].name.get());
|
||||||
|
return IdString();
|
||||||
}
|
}
|
||||||
|
|
||||||
IdString getWireType(WireId wire) const;
|
IdString getWireType(WireId wire) const;
|
||||||
|
|
||||||
uint32_t getWireChecksum(WireId wire) const { return wire.index; }
|
uint32_t getWireChecksum(WireId wire) const { return hash_value(wire.index); }
|
||||||
|
|
||||||
void bindWire(WireId wire, NetInfo *net, PlaceStrength strength)
|
void bindWire(WireId wire, NetInfo *net, PlaceStrength strength)
|
||||||
{
|
{
|
||||||
NPNR_ASSERT(wire != WireId());
|
NPNR_ASSERT(wire != WireId());
|
||||||
NPNR_ASSERT(wire_to_net[wire.index] == nullptr);
|
//NPNR_ASSERT(wire_to_net[wire.index] == nullptr);
|
||||||
wire_to_net[wire.index] = net;
|
//wire_to_net[wire.index] = net;
|
||||||
net->wires[wire].pip = PipId();
|
net->wires[wire].pip = PipId();
|
||||||
net->wires[wire].strength = strength;
|
net->wires[wire].strength = strength;
|
||||||
refreshUiWire(wire);
|
refreshUiWire(wire);
|
||||||
@ -531,49 +533,52 @@ struct Arch : BaseCtx
|
|||||||
void unbindWire(WireId wire)
|
void unbindWire(WireId wire)
|
||||||
{
|
{
|
||||||
NPNR_ASSERT(wire != WireId());
|
NPNR_ASSERT(wire != WireId());
|
||||||
NPNR_ASSERT(wire_to_net[wire.index] != nullptr);
|
//NPNR_ASSERT(wire_to_net[wire.index] != nullptr);
|
||||||
|
|
||||||
auto &net_wires = wire_to_net[wire.index]->wires;
|
//auto &net_wires = wire_to_net[wire.index]->wires;
|
||||||
auto it = net_wires.find(wire);
|
//auto it = net_wires.find(wire);
|
||||||
NPNR_ASSERT(it != net_wires.end());
|
//NPNR_ASSERT(it != net_wires.end());
|
||||||
|
|
||||||
auto pip = it->second.pip;
|
//auto pip = it->second.pip;
|
||||||
if (pip != PipId()) {
|
//if (pip != PipId()) {
|
||||||
pip_to_net[pip.index] = nullptr;
|
// pip_to_net[pip.index] = nullptr;
|
||||||
switches_locked[chip_info->pip_data[pip.index].switch_index] = nullptr;
|
// switches_locked[chip_info->pip_data[pip.index].switch_index] = nullptr;
|
||||||
}
|
//}
|
||||||
|
|
||||||
net_wires.erase(it);
|
//net_wires.erase(it);
|
||||||
wire_to_net[wire.index] = nullptr;
|
//wire_to_net[wire.index] = nullptr;
|
||||||
refreshUiWire(wire);
|
refreshUiWire(wire);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool checkWireAvail(WireId wire) const
|
bool checkWireAvail(WireId wire) const
|
||||||
{
|
{
|
||||||
NPNR_ASSERT(wire != WireId());
|
//NPNR_ASSERT(wire != WireId());
|
||||||
return wire_to_net[wire.index] == nullptr;
|
//return wire_to_net[wire.index] == nullptr;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
NetInfo *getBoundWireNet(WireId wire) const
|
NetInfo *getBoundWireNet(WireId wire) const
|
||||||
{
|
{
|
||||||
NPNR_ASSERT(wire != WireId());
|
//NPNR_ASSERT(wire != WireId());
|
||||||
return wire_to_net[wire.index];
|
//return wire_to_net[wire.index];
|
||||||
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
NetInfo *getConflictingWireNet(WireId wire) const
|
NetInfo *getConflictingWireNet(WireId wire) const
|
||||||
{
|
{
|
||||||
NPNR_ASSERT(wire != WireId());
|
//NPNR_ASSERT(wire != WireId());
|
||||||
return wire_to_net[wire.index];
|
//return wire_to_net[wire.index];
|
||||||
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
DelayInfo getWireDelay(WireId wire) const
|
DelayInfo getWireDelay(WireId wire) const
|
||||||
{
|
{
|
||||||
DelayInfo delay;
|
DelayInfo delay;
|
||||||
NPNR_ASSERT(wire != WireId());
|
//NPNR_ASSERT(wire != WireId());
|
||||||
if (fast_part)
|
//if (fast_part)
|
||||||
delay.delay = chip_info->wire_data[wire.index].fast_delay;
|
// delay.delay = chip_info->wire_data[wire.index].fast_delay;
|
||||||
else
|
//else
|
||||||
delay.delay = chip_info->wire_data[wire.index].slow_delay;
|
// delay.delay = chip_info->wire_data[wire.index].slow_delay;
|
||||||
return delay;
|
return delay;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -589,8 +594,8 @@ struct Arch : BaseCtx
|
|||||||
WireRange getWires() const
|
WireRange getWires() const
|
||||||
{
|
{
|
||||||
WireRange range;
|
WireRange range;
|
||||||
range.b.cursor = 0;
|
//range.b.cursor = 0;
|
||||||
range.e.cursor = 0; //chip_info->num_wires;
|
//range.e.cursor = chip_info->num_wires;
|
||||||
return range;
|
return range;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -608,11 +613,11 @@ struct Arch : BaseCtx
|
|||||||
switches_locked[chip_info->pip_data[pip.index].switch_index] = net;
|
switches_locked[chip_info->pip_data[pip.index].switch_index] = net;
|
||||||
|
|
||||||
WireId dst;
|
WireId dst;
|
||||||
dst.index = chip_info->pip_data[pip.index].dst;
|
//dst.index = chip_info->pip_data[pip.index].dst;
|
||||||
NPNR_ASSERT(wire_to_net[dst.index] == nullptr);
|
//NPNR_ASSERT(wire_to_net[dst.index] == nullptr);
|
||||||
wire_to_net[dst.index] = net;
|
//wire_to_net[dst.index] = net;
|
||||||
net->wires[dst].pip = pip;
|
//net->wires[dst].pip = pip;
|
||||||
net->wires[dst].strength = strength;
|
//net->wires[dst].strength = strength;
|
||||||
refreshUiPip(pip);
|
refreshUiPip(pip);
|
||||||
refreshUiWire(dst);
|
refreshUiWire(dst);
|
||||||
}
|
}
|
||||||
@ -624,9 +629,9 @@ struct Arch : BaseCtx
|
|||||||
NPNR_ASSERT(switches_locked[chip_info->pip_data[pip.index].switch_index] != nullptr);
|
NPNR_ASSERT(switches_locked[chip_info->pip_data[pip.index].switch_index] != nullptr);
|
||||||
|
|
||||||
WireId dst;
|
WireId dst;
|
||||||
dst.index = chip_info->pip_data[pip.index].dst;
|
//dst.index = chip_info->pip_data[pip.index].dst;
|
||||||
NPNR_ASSERT(wire_to_net[dst.index] != nullptr);
|
//NPNR_ASSERT(wire_to_net[dst.index] != nullptr);
|
||||||
wire_to_net[dst.index] = nullptr;
|
//wire_to_net[dst.index] = nullptr;
|
||||||
pip_to_net[pip.index]->wires.erase(dst);
|
pip_to_net[pip.index]->wires.erase(dst);
|
||||||
|
|
||||||
pip_to_net[pip.index] = nullptr;
|
pip_to_net[pip.index] = nullptr;
|
||||||
@ -698,7 +703,7 @@ struct Arch : BaseCtx
|
|||||||
{
|
{
|
||||||
WireId wire;
|
WireId wire;
|
||||||
NPNR_ASSERT(pip != PipId());
|
NPNR_ASSERT(pip != PipId());
|
||||||
wire.index = chip_info->pip_data[pip.index].src;
|
//wire.index = chip_info->pip_data[pip.index].src;
|
||||||
return wire;
|
return wire;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -706,7 +711,7 @@ struct Arch : BaseCtx
|
|||||||
{
|
{
|
||||||
WireId wire;
|
WireId wire;
|
||||||
NPNR_ASSERT(pip != PipId());
|
NPNR_ASSERT(pip != PipId());
|
||||||
wire.index = chip_info->pip_data[pip.index].dst;
|
//wire.index = chip_info->pip_data[pip.index].dst;
|
||||||
return wire;
|
return wire;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -725,8 +730,8 @@ struct Arch : BaseCtx
|
|||||||
{
|
{
|
||||||
PipRange range;
|
PipRange range;
|
||||||
NPNR_ASSERT(wire != WireId());
|
NPNR_ASSERT(wire != WireId());
|
||||||
range.b.cursor = chip_info->wire_data[wire.index].pips_downhill.get();
|
//range.b.cursor = chip_info->wire_data[wire.index].pips_downhill.get();
|
||||||
range.e.cursor = range.b.cursor + chip_info->wire_data[wire.index].num_downhill;
|
//range.e.cursor = range.b.cursor + chip_info->wire_data[wire.index].num_downhill;
|
||||||
return range;
|
return range;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -734,8 +739,8 @@ struct Arch : BaseCtx
|
|||||||
{
|
{
|
||||||
PipRange range;
|
PipRange range;
|
||||||
NPNR_ASSERT(wire != WireId());
|
NPNR_ASSERT(wire != WireId());
|
||||||
range.b.cursor = chip_info->wire_data[wire.index].pips_uphill.get();
|
//range.b.cursor = chip_info->wire_data[wire.index].pips_uphill.get();
|
||||||
range.e.cursor = range.b.cursor + chip_info->wire_data[wire.index].num_uphill;
|
//range.e.cursor = range.b.cursor + chip_info->wire_data[wire.index].num_uphill;
|
||||||
return range;
|
return range;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "torc/Architecture.hpp"
|
#include "torc/Architecture.hpp"
|
||||||
|
using namespace torc::architecture;
|
||||||
using namespace torc::architecture::xilinx;
|
using namespace torc::architecture::xilinx;
|
||||||
|
|
||||||
NEXTPNR_NAMESPACE_BEGIN
|
NEXTPNR_NAMESPACE_BEGIN
|
||||||
@ -73,10 +74,10 @@ struct BelId
|
|||||||
|
|
||||||
struct WireId
|
struct WireId
|
||||||
{
|
{
|
||||||
int32_t index = -1;
|
Tilewire index;
|
||||||
|
|
||||||
bool operator==(const WireId &other) const { return index == other.index; }
|
bool operator==(const WireId &other) const { return index == other.index; }
|
||||||
bool operator!=(const WireId &other) const { return index != other.index; }
|
bool operator!=(const WireId &other) const { return !(index == other.index); }
|
||||||
};
|
};
|
||||||
|
|
||||||
struct PipId
|
struct PipId
|
||||||
@ -163,7 +164,7 @@ template <> struct hash<NEXTPNR_NAMESPACE_PREFIX WireId>
|
|||||||
{
|
{
|
||||||
std::size_t operator()(const NEXTPNR_NAMESPACE_PREFIX WireId &wire) const noexcept
|
std::size_t operator()(const NEXTPNR_NAMESPACE_PREFIX WireId &wire) const noexcept
|
||||||
{
|
{
|
||||||
return hash<int>()(wire.index);
|
return hash_value(wire.index);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
36
xc7/cells.cc
36
xc7/cells.cc
@ -53,21 +53,21 @@ std::unique_ptr<CellInfo> create_ice_cell(Context *ctx, IdString type, std::stri
|
|||||||
new_cell->params[ctx->id("CIN_CONST")] = "0";
|
new_cell->params[ctx->id("CIN_CONST")] = "0";
|
||||||
new_cell->params[ctx->id("CIN_SET")] = "0";
|
new_cell->params[ctx->id("CIN_SET")] = "0";
|
||||||
|
|
||||||
add_port(ctx, new_cell.get(), "I0", PORT_IN);
|
add_port(ctx, new_cell.get(), "A1", PORT_IN);
|
||||||
add_port(ctx, new_cell.get(), "I1", PORT_IN);
|
add_port(ctx, new_cell.get(), "A2", PORT_IN);
|
||||||
add_port(ctx, new_cell.get(), "I2", PORT_IN);
|
add_port(ctx, new_cell.get(), "A3", PORT_IN);
|
||||||
add_port(ctx, new_cell.get(), "I3", PORT_IN);
|
add_port(ctx, new_cell.get(), "A4", PORT_IN);
|
||||||
add_port(ctx, new_cell.get(), "I4", PORT_IN);
|
add_port(ctx, new_cell.get(), "A5", PORT_IN);
|
||||||
add_port(ctx, new_cell.get(), "I5", PORT_IN);
|
add_port(ctx, new_cell.get(), "A6", PORT_IN);
|
||||||
add_port(ctx, new_cell.get(), "CIN", PORT_IN);
|
add_port(ctx, new_cell.get(), "CIN", PORT_IN);
|
||||||
|
|
||||||
add_port(ctx, new_cell.get(), "CLK", PORT_IN);
|
add_port(ctx, new_cell.get(), "CLK", PORT_IN);
|
||||||
add_port(ctx, new_cell.get(), "CE", PORT_IN);
|
add_port(ctx, new_cell.get(), "CE", PORT_IN);
|
||||||
add_port(ctx, new_cell.get(), "SR", PORT_IN);
|
add_port(ctx, new_cell.get(), "SR", PORT_IN);
|
||||||
|
|
||||||
add_port(ctx, new_cell.get(), "O", PORT_OUT);
|
add_port(ctx, new_cell.get(), "A", PORT_OUT);
|
||||||
add_port(ctx, new_cell.get(), "OMUX", PORT_OUT);
|
add_port(ctx, new_cell.get(), "AQ", PORT_OUT);
|
||||||
add_port(ctx, new_cell.get(), "OQ", PORT_OUT);
|
add_port(ctx, new_cell.get(), "AMUX", PORT_OUT);
|
||||||
add_port(ctx, new_cell.get(), "COUT", PORT_OUT);
|
add_port(ctx, new_cell.get(), "COUT", PORT_OUT);
|
||||||
} else if (type == ctx->id("IOBUF")) {
|
} else if (type == ctx->id("IOBUF")) {
|
||||||
new_cell->type = id_IOB33S;
|
new_cell->type = id_IOB33S;
|
||||||
@ -259,19 +259,19 @@ std::unique_ptr<CellInfo> create_ice_cell(Context *ctx, IdString type, std::stri
|
|||||||
void lut_to_lc(const Context *ctx, CellInfo *lut, CellInfo *lc, bool no_dff)
|
void lut_to_lc(const Context *ctx, CellInfo *lut, CellInfo *lc, bool no_dff)
|
||||||
{
|
{
|
||||||
lc->params[ctx->id("LUT_INIT")] = lut->params[ctx->id("LUT_INIT")];
|
lc->params[ctx->id("LUT_INIT")] = lut->params[ctx->id("LUT_INIT")];
|
||||||
replace_port(lut, ctx->id("I0"), lc, ctx->id("I0"));
|
replace_port(lut, ctx->id("I0"), lc, ctx->id("A1"));
|
||||||
if (get_net_or_empty(lut, ctx->id("I1")))
|
if (get_net_or_empty(lut, ctx->id("I1")))
|
||||||
replace_port(lut, ctx->id("I1"), lc, ctx->id("I1"));
|
replace_port(lut, ctx->id("I1"), lc, ctx->id("A2"));
|
||||||
if (get_net_or_empty(lut, ctx->id("I2")))
|
if (get_net_or_empty(lut, ctx->id("I2")))
|
||||||
replace_port(lut, ctx->id("I2"), lc, ctx->id("I2"));
|
replace_port(lut, ctx->id("I2"), lc, ctx->id("A3"));
|
||||||
if (get_net_or_empty(lut, ctx->id("I3")))
|
if (get_net_or_empty(lut, ctx->id("I3")))
|
||||||
replace_port(lut, ctx->id("I3"), lc, ctx->id("I3"));
|
replace_port(lut, ctx->id("I3"), lc, ctx->id("A4"));
|
||||||
if (get_net_or_empty(lut, ctx->id("I4")))
|
if (get_net_or_empty(lut, ctx->id("I4")))
|
||||||
replace_port(lut, ctx->id("I4"), lc, ctx->id("I3"));
|
replace_port(lut, ctx->id("I4"), lc, ctx->id("A5"));
|
||||||
if (get_net_or_empty(lut, ctx->id("I5")))
|
if (get_net_or_empty(lut, ctx->id("I5")))
|
||||||
replace_port(lut, ctx->id("I5"), lc, ctx->id("I3"));
|
replace_port(lut, ctx->id("I5"), lc, ctx->id("A6"));
|
||||||
if (no_dff) {
|
if (no_dff) {
|
||||||
replace_port(lut, ctx->id("O"), lc, ctx->id("O"));
|
replace_port(lut, ctx->id("O"), lc, ctx->id("A"));
|
||||||
lc->params[ctx->id("DFF_ENABLE")] = "0";
|
lc->params[ctx->id("DFF_ENABLE")] = "0";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -318,10 +318,10 @@ void dff_to_lc(const Context *ctx, CellInfo *dff, CellInfo *lc, bool pass_thru_l
|
|||||||
|
|
||||||
if (pass_thru_lut) {
|
if (pass_thru_lut) {
|
||||||
lc->params[ctx->id("LUT_INIT")] = "2";
|
lc->params[ctx->id("LUT_INIT")] = "2";
|
||||||
replace_port(dff, ctx->id("D"), lc, ctx->id("I0"));
|
replace_port(dff, ctx->id("D"), lc, ctx->id("A1"));
|
||||||
}
|
}
|
||||||
|
|
||||||
replace_port(dff, ctx->id("Q"), lc, ctx->id("OQ"));
|
replace_port(dff, ctx->id("Q"), lc, ctx->id("AQ"));
|
||||||
}
|
}
|
||||||
|
|
||||||
void nxio_to_sb(Context *ctx, CellInfo *nxio, CellInfo *sbio)
|
void nxio_to_sb(Context *ctx, CellInfo *nxio, CellInfo *sbio)
|
||||||
|
@ -441,6 +441,16 @@ X(NEG_CLK)
|
|||||||
|
|
||||||
X(I)
|
X(I)
|
||||||
|
|
||||||
|
X(A1)
|
||||||
|
X(A2)
|
||||||
|
X(A3)
|
||||||
|
X(A4)
|
||||||
|
X(A5)
|
||||||
|
X(A6)
|
||||||
|
X(A)
|
||||||
|
X(AQ)
|
||||||
|
X(AMUX)
|
||||||
|
|
||||||
X(LUT1)
|
X(LUT1)
|
||||||
X(LUT2)
|
X(LUT2)
|
||||||
X(LUT3)
|
X(LUT3)
|
||||||
|
138
xc7/delay.cc
138
xc7/delay.cc
@ -27,75 +27,75 @@ NEXTPNR_NAMESPACE_BEGIN
|
|||||||
|
|
||||||
void ice40DelayFuzzerMain(Context *ctx)
|
void ice40DelayFuzzerMain(Context *ctx)
|
||||||
{
|
{
|
||||||
std::vector<WireId> srcWires, dstWires;
|
// std::vector<WireId> srcWires, dstWires;
|
||||||
|
//
|
||||||
for (int i = 0; i < ctx->chip_info->num_wires; i++) {
|
// for (int i = 0; i < ctx->chip_info->num_wires; i++) {
|
||||||
WireId wire;
|
// WireId wire;
|
||||||
wire.index = i;
|
// wire.index = i;
|
||||||
|
//
|
||||||
switch (ctx->chip_info->wire_data[i].type) {
|
// switch (ctx->chip_info->wire_data[i].type) {
|
||||||
case WireInfoPOD::WIRE_TYPE_LUTFF_OUT:
|
// case WireInfoPOD::WIRE_TYPE_LUTFF_OUT:
|
||||||
srcWires.push_back(wire);
|
// srcWires.push_back(wire);
|
||||||
break;
|
// break;
|
||||||
|
//
|
||||||
case WireInfoPOD::WIRE_TYPE_LUTFF_IN_LUT:
|
// case WireInfoPOD::WIRE_TYPE_LUTFF_IN_LUT:
|
||||||
dstWires.push_back(wire);
|
// dstWires.push_back(wire);
|
||||||
break;
|
// break;
|
||||||
|
//
|
||||||
default:
|
// default:
|
||||||
break;
|
// break;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
ctx->shuffle(srcWires);
|
// ctx->shuffle(srcWires);
|
||||||
ctx->shuffle(dstWires);
|
// ctx->shuffle(dstWires);
|
||||||
|
//
|
||||||
int index = 0;
|
// int index = 0;
|
||||||
int cnt = 0;
|
// int cnt = 0;
|
||||||
|
//
|
||||||
while (cnt < NUM_FUZZ_ROUTES) {
|
// while (cnt < NUM_FUZZ_ROUTES) {
|
||||||
if (index >= int(srcWires.size()) || index >= int(dstWires.size())) {
|
// if (index >= int(srcWires.size()) || index >= int(dstWires.size())) {
|
||||||
index = 0;
|
// index = 0;
|
||||||
ctx->shuffle(srcWires);
|
// ctx->shuffle(srcWires);
|
||||||
ctx->shuffle(dstWires);
|
// ctx->shuffle(dstWires);
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
WireId src = srcWires[index];
|
// WireId src = srcWires[index];
|
||||||
WireId dst = dstWires[index++];
|
// WireId dst = dstWires[index++];
|
||||||
std::unordered_map<WireId, PipId> route;
|
// std::unordered_map<WireId, PipId> route;
|
||||||
|
//
|
||||||
#if NUM_FUZZ_ROUTES <= 1000
|
//#if NUM_FUZZ_ROUTES <= 1000
|
||||||
if (!ctx->getActualRouteDelay(src, dst, nullptr, &route, false))
|
// if (!ctx->getActualRouteDelay(src, dst, nullptr, &route, false))
|
||||||
continue;
|
// continue;
|
||||||
#else
|
//#else
|
||||||
if (!ctx->getActualRouteDelay(src, dst, nullptr, &route, true))
|
// if (!ctx->getActualRouteDelay(src, dst, nullptr, &route, true))
|
||||||
continue;
|
// continue;
|
||||||
#endif
|
//#endif
|
||||||
|
//
|
||||||
WireId cursor = dst;
|
// WireId cursor = dst;
|
||||||
delay_t delay = 0;
|
// delay_t delay = 0;
|
||||||
|
//
|
||||||
while (1) {
|
// while (1) {
|
||||||
delay += ctx->getWireDelay(cursor).maxDelay();
|
// delay += ctx->getWireDelay(cursor).maxDelay();
|
||||||
|
//
|
||||||
printf("%s %d %d %s %s %d %d\n", cursor == dst ? "dst" : "src",
|
// printf("%s %d %d %s %s %d %d\n", cursor == dst ? "dst" : "src",
|
||||||
int(ctx->chip_info->wire_data[cursor.index].x), int(ctx->chip_info->wire_data[cursor.index].y),
|
// int(ctx->chip_info->wire_data[cursor.index].x), int(ctx->chip_info->wire_data[cursor.index].y),
|
||||||
ctx->getWireType(cursor).c_str(ctx), ctx->getWireName(cursor).c_str(ctx), int(delay),
|
// ctx->getWireType(cursor).c_str(ctx), ctx->getWireName(cursor).c_str(ctx), int(delay),
|
||||||
int(ctx->estimateDelay(cursor, dst)));
|
// int(ctx->estimateDelay(cursor, dst)));
|
||||||
|
//
|
||||||
if (cursor == src)
|
// if (cursor == src)
|
||||||
break;
|
// break;
|
||||||
|
//
|
||||||
PipId pip = route.at(cursor);
|
// PipId pip = route.at(cursor);
|
||||||
delay += ctx->getPipDelay(pip).maxDelay();
|
// delay += ctx->getPipDelay(pip).maxDelay();
|
||||||
cursor = ctx->getPipSrcWire(pip);
|
// cursor = ctx->getPipSrcWire(pip);
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
cnt++;
|
// cnt++;
|
||||||
|
//
|
||||||
if (cnt % 100 == 0)
|
// if (cnt % 100 == 0)
|
||||||
fprintf(stderr, "Fuzzed %d arcs.\n", cnt);
|
// fprintf(stderr, "Fuzzed %d arcs.\n", cnt);
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
delay_t Arch::estimateDelay(WireId src, WireId dst) const
|
delay_t Arch::estimateDelay(WireId src, WireId dst) const
|
||||||
|
42
xc7/pack.cc
42
xc7/pack.cc
@ -336,16 +336,16 @@ static void pack_constants(Context *ctx)
|
|||||||
std::unique_ptr<NetInfo> gnd_net = std::unique_ptr<NetInfo>(new NetInfo);
|
std::unique_ptr<NetInfo> gnd_net = std::unique_ptr<NetInfo>(new NetInfo);
|
||||||
gnd_net->name = ctx->id("$PACKER_GND_NET");
|
gnd_net->name = ctx->id("$PACKER_GND_NET");
|
||||||
gnd_net->driver.cell = gnd_cell.get();
|
gnd_net->driver.cell = gnd_cell.get();
|
||||||
gnd_net->driver.port = ctx->id("O");
|
gnd_net->driver.port = ctx->id("A");
|
||||||
gnd_cell->ports.at(ctx->id("O")).net = gnd_net.get();
|
gnd_cell->ports.at(ctx->id("A")).net = gnd_net.get();
|
||||||
|
|
||||||
std::unique_ptr<CellInfo> vcc_cell = create_ice_cell(ctx, ctx->id("XC7_LC"), "$PACKER_VCC");
|
std::unique_ptr<CellInfo> vcc_cell = create_ice_cell(ctx, ctx->id("XC7_LC"), "$PACKER_VCC");
|
||||||
vcc_cell->params[ctx->id("LUT_INIT")] = "1";
|
vcc_cell->params[ctx->id("LUT_INIT")] = "1";
|
||||||
std::unique_ptr<NetInfo> vcc_net = std::unique_ptr<NetInfo>(new NetInfo);
|
std::unique_ptr<NetInfo> vcc_net = std::unique_ptr<NetInfo>(new NetInfo);
|
||||||
vcc_net->name = ctx->id("$PACKER_VCC_NET");
|
vcc_net->name = ctx->id("$PACKER_VCC_NET");
|
||||||
vcc_net->driver.cell = vcc_cell.get();
|
vcc_net->driver.cell = vcc_cell.get();
|
||||||
vcc_net->driver.port = ctx->id("O");
|
vcc_net->driver.port = ctx->id("A");
|
||||||
vcc_cell->ports.at(ctx->id("O")).net = vcc_net.get();
|
vcc_cell->ports.at(ctx->id("A")).net = vcc_net.get();
|
||||||
|
|
||||||
std::vector<IdString> dead_nets;
|
std::vector<IdString> dead_nets;
|
||||||
|
|
||||||
@ -451,6 +451,7 @@ static bool is_logic_port(BaseCtx *ctx, const PortRef &port)
|
|||||||
|
|
||||||
static void insert_global(Context *ctx, NetInfo *net, bool is_reset, bool is_cen, bool is_logic)
|
static void insert_global(Context *ctx, NetInfo *net, bool is_reset, bool is_cen, bool is_logic)
|
||||||
{
|
{
|
||||||
|
asm("int3");
|
||||||
std::string glb_name = net->name.str(ctx) + std::string("_$glb_") + (is_reset ? "sr" : (is_cen ? "ce" : "clk"));
|
std::string glb_name = net->name.str(ctx) + std::string("_$glb_") + (is_reset ? "sr" : (is_cen ? "ce" : "clk"));
|
||||||
std::unique_ptr<CellInfo> gb = create_ice_cell(ctx, id_BUFGCTRL, "$bufg_" + glb_name);
|
std::unique_ptr<CellInfo> gb = create_ice_cell(ctx, id_BUFGCTRL, "$bufg_" + glb_name);
|
||||||
gb->ports[ctx->id("I0")].net = net;
|
gb->ports[ctx->id("I0")].net = net;
|
||||||
@ -847,25 +848,25 @@ static void pack_special(Context *ctx)
|
|||||||
|
|
||||||
// Find wire that will be driven by this port.
|
// Find wire that will be driven by this port.
|
||||||
const auto pll_out_wire = ctx->getBelPinWire(pll_bel, port.name);
|
const auto pll_out_wire = ctx->getBelPinWire(pll_bel, port.name);
|
||||||
NPNR_ASSERT(pll_out_wire.index != -1);
|
NPNR_ASSERT(pll_out_wire != WireId());
|
||||||
|
|
||||||
// Now, constrain all LUTs on the output of the signal to be at
|
// Now, constrain all LUTs on the output of the signal to be at
|
||||||
// the correct Bel relative to the PLL Bel.
|
// the correct Bel relative to the PLL Bel.
|
||||||
int x = ctx->chip_info->wire_data[pll_out_wire.index].x;
|
//int x = ctx->chip_info->wire_data[pll_out_wire.index].x;
|
||||||
int y = ctx->chip_info->wire_data[pll_out_wire.index].y;
|
//int y = ctx->chip_info->wire_data[pll_out_wire.index].y;
|
||||||
int z = 0;
|
//int z = 0;
|
||||||
for (const auto &user : port.net->users) {
|
//for (const auto &user : port.net->users) {
|
||||||
NPNR_ASSERT(user.cell != nullptr);
|
// NPNR_ASSERT(user.cell != nullptr);
|
||||||
NPNR_ASSERT(user.cell->type == ctx->id("XC7_LC"));
|
// NPNR_ASSERT(user.cell->type == ctx->id("XC7_LC"));
|
||||||
|
|
||||||
// TODO(q3k): handle when the Bel might be already the
|
// // TODO(q3k): handle when the Bel might be already the
|
||||||
// target of another constraint.
|
// // target of another constraint.
|
||||||
NPNR_ASSERT(z < 8);
|
// NPNR_ASSERT(z < 8);
|
||||||
auto target_bel = ctx->getBelByLocation(Loc(x, y, z++));
|
// auto target_bel = ctx->getBelByLocation(Loc(x, y, z++));
|
||||||
auto target_bel_name = ctx->getBelName(target_bel).str(ctx);
|
// auto target_bel_name = ctx->getBelName(target_bel).str(ctx);
|
||||||
user.cell->attrs[ctx->id("BEL")] = target_bel_name;
|
// user.cell->attrs[ctx->id("BEL")] = target_bel_name;
|
||||||
log_info(" constrained '%s' to %s\n", user.cell->name.c_str(ctx), target_bel_name.c_str());
|
// log_info(" constrained '%s' to %s\n", user.cell->name.c_str(ctx), target_bel_name.c_str());
|
||||||
}
|
//}
|
||||||
}
|
}
|
||||||
|
|
||||||
new_cells.push_back(std::move(packed));
|
new_cells.push_back(std::move(packed));
|
||||||
@ -887,7 +888,8 @@ bool Arch::pack()
|
|||||||
try {
|
try {
|
||||||
log_break();
|
log_break();
|
||||||
pack_constants(ctx);
|
pack_constants(ctx);
|
||||||
promote_globals(ctx);
|
// TODO
|
||||||
|
//promote_globals(ctx);
|
||||||
pack_io(ctx);
|
pack_io(ctx);
|
||||||
pack_lut_lutffs(ctx);
|
pack_lut_lutffs(ctx);
|
||||||
pack_nonlut_ffs(ctx);
|
pack_nonlut_ffs(ctx);
|
||||||
|
Loading…
Reference in New Issue
Block a user