Compare commits
3 Commits
master
...
lofty/mist
Author | SHA1 | Date | |
---|---|---|---|
![]() |
83ad4a9f17 | ||
![]() |
1f8e8948ea | ||
![]() |
5b99b99859 |
@ -43,10 +43,10 @@ void IdString::initialize_arch(const BaseCtx *ctx)
|
||||
#undef X
|
||||
}
|
||||
|
||||
CycloneV::rnode_t Arch::find_rnode(CycloneV::block_type_t bt, int x, int y, CycloneV::port_type_t port, int bi,
|
||||
CycloneV::rnode_coords Arch::find_rnode(CycloneV::block_type_t bt, int x, int y, CycloneV::port_type_t port, int bi,
|
||||
int pi) const
|
||||
{
|
||||
auto pn1 = CycloneV::pnode(bt, x, y, port, bi, pi);
|
||||
auto pn1 = CycloneV::pnode_coords{bt, x, y, port, bi, pi};
|
||||
auto rn1 = cyclonev->pnode_to_rnode(pn1);
|
||||
if (rn1)
|
||||
return rn1;
|
||||
@ -63,7 +63,7 @@ CycloneV::rnode_t Arch::find_rnode(CycloneV::block_type_t bt, int x, int y, Cycl
|
||||
return rn2;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return CycloneV::rnode_coords{};
|
||||
}
|
||||
|
||||
WireId Arch::get_port(CycloneV::block_type_t bt, int x, int y, int bi, CycloneV::port_type_t port, int pi) const
|
||||
@ -72,7 +72,7 @@ WireId Arch::get_port(CycloneV::block_type_t bt, int x, int y, int bi, CycloneV:
|
||||
if (rn)
|
||||
return WireId(rn);
|
||||
|
||||
log_error("Trying to connect unknown node %s\n", CycloneV::pn2s(CycloneV::pnode(bt, x, y, port, bi, pi)).c_str());
|
||||
log_error("Trying to connect unknown node %s\n", CycloneV::pnode_coords{bt, x, y, port, bi, pi}.to_string().c_str());
|
||||
}
|
||||
|
||||
bool Arch::has_port(CycloneV::block_type_t bt, int x, int y, int bi, CycloneV::port_type_t port, int pi) const
|
||||
@ -103,33 +103,33 @@ Arch::Arch(ArchArgs args)
|
||||
bels_by_tile.resize(cyclonev->get_tile_sx() * cyclonev->get_tile_sy());
|
||||
|
||||
for (auto lab_pos : cyclonev->lab_get_pos())
|
||||
create_lab(CycloneV::pos2x(lab_pos), CycloneV::pos2y(lab_pos), /*is_mlab=*/false);
|
||||
create_lab(lab_pos.x(), lab_pos.y(), /*is_mlab=*/false);
|
||||
|
||||
for (auto mlab_pos : cyclonev->mlab_get_pos())
|
||||
create_lab(CycloneV::pos2x(mlab_pos), CycloneV::pos2y(mlab_pos), /*is_mlab=*/true);
|
||||
create_lab(mlab_pos.x(), mlab_pos.y(), /*is_mlab=*/true);
|
||||
|
||||
for (auto gpio_pos : cyclonev->gpio_get_pos())
|
||||
create_gpio(CycloneV::pos2x(gpio_pos), CycloneV::pos2y(gpio_pos));
|
||||
create_gpio(gpio_pos.x(), gpio_pos.y());
|
||||
|
||||
for (auto cmuxh_pos : cyclonev->cmuxh_get_pos())
|
||||
create_clkbuf(CycloneV::pos2x(cmuxh_pos), CycloneV::pos2y(cmuxh_pos));
|
||||
create_clkbuf(cmuxh_pos.x(), cmuxh_pos.y());
|
||||
|
||||
create_control(CycloneV::pos2x(cyclonev->ctrl_get_pos()[0]), CycloneV::pos2y(cyclonev->ctrl_get_pos()[0]));
|
||||
create_control(cyclonev->ctrl_get_pos()[0].x(), cyclonev->ctrl_get_pos()[0].y());
|
||||
|
||||
auto hps_pos = cyclonev->hps_get_pos();
|
||||
if (!hps_pos.empty()) {
|
||||
create_hps_mpu_general_purpose(CycloneV::pos2x(hps_pos[CycloneV::I_HPS_MPU_GENERAL_PURPOSE]),
|
||||
CycloneV::pos2y(hps_pos[CycloneV::I_HPS_MPU_GENERAL_PURPOSE]));
|
||||
create_hps_mpu_general_purpose(hps_pos[CycloneV::I_HPS_MPU_GENERAL_PURPOSE].x(),
|
||||
hps_pos[CycloneV::I_HPS_MPU_GENERAL_PURPOSE].y());
|
||||
}
|
||||
|
||||
for (auto m10k_pos : cyclonev->m10k_get_pos())
|
||||
create_m10k(CycloneV::pos2x(m10k_pos), CycloneV::pos2y(m10k_pos));
|
||||
create_m10k(m10k_pos.x(), m10k_pos.y());
|
||||
|
||||
// This import takes about 5s, perhaps long term we can speed it up, e.g. defer to Mistral more...
|
||||
log_info("Initialising routing graph...\n");
|
||||
int pip_count = 0;
|
||||
for (const auto &rnode : cyclonev->rnodes()) {
|
||||
WireId dst_wire(rnode.id());
|
||||
WireId dst_wire(rnode.rc());
|
||||
for (const auto &src : rnode.sources()) {
|
||||
WireId src_wire(src);
|
||||
wires[dst_wire].wires_uphill.push_back(src_wire);
|
||||
@ -158,7 +158,7 @@ BelId Arch::getBelByName(IdStringList name) const
|
||||
int y = id2int.at(name[2]);
|
||||
int z = id2int.at(name[3]);
|
||||
|
||||
bel.pos = CycloneV::xy2pos(x, y);
|
||||
bel.pos = CycloneV::xycoords{x, y};
|
||||
bel.z = z;
|
||||
|
||||
NPNR_ASSERT(name[0] == getBelType(bel));
|
||||
@ -168,8 +168,8 @@ BelId Arch::getBelByName(IdStringList name) const
|
||||
|
||||
IdStringList Arch::getBelName(BelId bel) const
|
||||
{
|
||||
int x = CycloneV::pos2x(bel.pos);
|
||||
int y = CycloneV::pos2y(bel.pos);
|
||||
int x = bel.pos.x();
|
||||
int y = bel.pos.y();
|
||||
int z = bel.z & 0xFF;
|
||||
|
||||
std::array<IdString, 4> ids{
|
||||
@ -215,7 +215,7 @@ WireId Arch::getWireByName(IdStringList name) const
|
||||
int x = id2int.at(name[1]);
|
||||
int y = id2int.at(name[2]);
|
||||
int z = id2int.at(name[3]);
|
||||
return WireId(CycloneV::rnode(ty, x, y, z));
|
||||
return WireId(CycloneV::rnode_coords{ty, x, y, z});
|
||||
}
|
||||
|
||||
IdStringList Arch::getWireName(WireId wire) const
|
||||
@ -224,17 +224,17 @@ IdStringList Arch::getWireName(WireId wire) const
|
||||
// non-mistral wires
|
||||
std::array<IdString, 4> ids{
|
||||
id_WIRE,
|
||||
int2id.at(CycloneV::rn2x(wire.node)),
|
||||
int2id.at(CycloneV::rn2y(wire.node)),
|
||||
int2id.at(wire.node.x()),
|
||||
int2id.at(wire.node.y()),
|
||||
wires.at(wire).name_override,
|
||||
};
|
||||
return IdStringList(ids);
|
||||
} else {
|
||||
std::array<IdString, 4> ids{
|
||||
rn_t2id.at(CycloneV::rn2t(wire.node)),
|
||||
int2id.at(CycloneV::rn2x(wire.node)),
|
||||
int2id.at(CycloneV::rn2y(wire.node)),
|
||||
int2id.at(CycloneV::rn2z(wire.node)),
|
||||
rn_t2id.at(wire.node.t()),
|
||||
int2id.at(wire.node.x()),
|
||||
int2id.at(wire.node.y()),
|
||||
int2id.at(wire.node.z()),
|
||||
};
|
||||
return IdStringList(ids);
|
||||
}
|
||||
@ -260,7 +260,7 @@ std::vector<BelId> Arch::getBelsByTile(int x, int y) const
|
||||
std::vector<BelId> bels;
|
||||
if (x >= 0 && x < cyclonev->get_tile_sx() && y >= 0 && y < cyclonev->get_tile_sy()) {
|
||||
for (size_t i = 0; i < bels_by_tile.at(pos2idx(x, y)).size(); i++)
|
||||
bels.push_back(BelId(CycloneV::xy2pos(x, y), i));
|
||||
bels.push_back(BelId(CycloneV::xycoords{x, y}, i));
|
||||
}
|
||||
|
||||
return bels;
|
||||
@ -320,7 +320,7 @@ BelId Arch::bel_by_block_idx(int x, int y, IdString type, int block_index) const
|
||||
for (size_t i = 0; i < bels.size(); i++) {
|
||||
auto &bel_data = bels.at(i);
|
||||
if (bel_data.type == type && bel_data.block_index == block_index)
|
||||
return BelId(CycloneV::xy2pos(x, y), i);
|
||||
return BelId(CycloneV::xycoords{x, y}, i);
|
||||
}
|
||||
return BelId();
|
||||
}
|
||||
@ -328,7 +328,7 @@ BelId Arch::bel_by_block_idx(int x, int y, IdString type, int block_index) const
|
||||
BelId Arch::add_bel(int x, int y, IdString name, IdString type)
|
||||
{
|
||||
auto &bels = bels_by_tile.at(pos2idx(x, y));
|
||||
BelId id = BelId(CycloneV::xy2pos(x, y), bels.size());
|
||||
BelId id = BelId(CycloneV::xycoords{x, y}, bels.size());
|
||||
all_bels.push_back(id);
|
||||
bels.emplace_back();
|
||||
auto &bel = bels.back();
|
||||
@ -356,7 +356,7 @@ WireId Arch::add_wire(int x, int y, IdString name, uint64_t flags)
|
||||
// Determine a unique ID for the wire
|
||||
int z = 0;
|
||||
WireId id;
|
||||
while (wires.count(id = WireId(CycloneV::rnode(CycloneV::rnode_type_t((z >> 10) + 128), x, y, (z & 0x3FF)))))
|
||||
while (wires.count(id = WireId(CycloneV::rnode_coords{CycloneV::rnode_type_t((z >> 10) + 128), x, y, (z & 0x3FF)})))
|
||||
z++;
|
||||
wires[id].name_override = name;
|
||||
wires[id].flags = flags;
|
||||
@ -438,10 +438,10 @@ void Arch::assignArchInfo()
|
||||
BoundingBox Arch::getRouteBoundingBox(WireId src, WireId dst) const
|
||||
{
|
||||
BoundingBox bounds;
|
||||
int src_x = CycloneV::rn2x(src.node);
|
||||
int src_y = CycloneV::rn2y(src.node);
|
||||
int dst_x = CycloneV::rn2x(dst.node);
|
||||
int dst_y = CycloneV::rn2y(dst.node);
|
||||
int src_x = src.node.x();
|
||||
int src_y = src.node.y();
|
||||
int dst_x = dst.node.x();
|
||||
int dst_y = dst.node.y();
|
||||
bounds.x0 = std::min(src_x, dst_x);
|
||||
bounds.y0 = std::min(src_y, dst_y);
|
||||
bounds.x1 = std::max(src_x, dst_x);
|
||||
|
@ -311,7 +311,7 @@ struct Arch : BaseArch<ArchRanges>
|
||||
std::vector<BelId> getBelsByTile(int x, int y) const override;
|
||||
Loc getBelLocation(BelId bel) const override
|
||||
{
|
||||
return Loc(CycloneV::pos2x(bel.pos), CycloneV::pos2y(bel.pos), bel.z);
|
||||
return Loc(bel.pos.x(), bel.pos.y(), bel.z);
|
||||
}
|
||||
BelId getBelByLocation(Loc loc) const override
|
||||
{
|
||||
@ -322,7 +322,7 @@ struct Arch : BaseArch<ArchRanges>
|
||||
auto &bels = bels_by_tile.at(pos2idx(loc.x, loc.y));
|
||||
if (loc.z < 0 || loc.z >= int(bels.size()))
|
||||
return BelId();
|
||||
return BelId(CycloneV::xy2pos(loc.x, loc.y), loc.z);
|
||||
return BelId(CycloneV::xycoords(loc.x, loc.y), loc.z);
|
||||
}
|
||||
IdString getBelType(BelId bel) const override; // arch.cc
|
||||
WireId getBelPinWire(BelId bel, IdString pin) const override
|
||||
@ -380,7 +380,7 @@ struct Arch : BaseArch<ArchRanges>
|
||||
|
||||
PipId getPipByName(IdStringList name) const override;
|
||||
AllPipRange getPips() const override { return AllPipRange(wires); }
|
||||
Loc getPipLocation(PipId pip) const override { return Loc(CycloneV::rn2x(pip.dst), CycloneV::rn2y(pip.dst), 0); }
|
||||
Loc getPipLocation(PipId pip) const override { return Loc(pip.dst.x(), pip.dst.y(), 0); }
|
||||
IdStringList getPipName(PipId pip) const override;
|
||||
WireId getPipSrcWire(PipId pip) const override { return WireId(pip.src); };
|
||||
WireId getPipDstWire(PipId pip) const override { return WireId(pip.dst); };
|
||||
@ -466,7 +466,7 @@ struct Arch : BaseArch<ArchRanges>
|
||||
|
||||
void add_bel_pin(BelId bel, IdString pin, PortType dir, WireId wire);
|
||||
|
||||
CycloneV::rnode_t find_rnode(CycloneV::block_type_t bt, int x, int y, CycloneV::port_type_t port, int bi = -1,
|
||||
CycloneV::rnode_coords find_rnode(CycloneV::block_type_t bt, int x, int y, CycloneV::port_type_t port, int bi = -1,
|
||||
int pi = -1) const;
|
||||
WireId get_port(CycloneV::block_type_t bt, int x, int y, int bi, CycloneV::port_type_t port, int pi = -1) const;
|
||||
bool has_port(CycloneV::block_type_t bt, int x, int y, int bi, CycloneV::port_type_t port, int pi = -1) const;
|
||||
@ -545,7 +545,7 @@ struct Arch : BaseArch<ArchRanges>
|
||||
return y * cyclonev->get_tile_sx() + x;
|
||||
}
|
||||
|
||||
size_t pos2idx(CycloneV::pos_t pos) const { return pos2idx(CycloneV::pos2x(pos), CycloneV::pos2y(pos)); }
|
||||
size_t pos2idx(CycloneV::xycoords pos) const { return pos2idx(pos.x(), pos.y()); }
|
||||
|
||||
BelInfo &bel_data(BelId bel) { return bels_by_tile.at(pos2idx(bel.pos)).at(bel.z); }
|
||||
const BelInfo &bel_data(BelId bel) const { return bels_by_tile.at(pos2idx(bel.pos)).at(bel.z); }
|
||||
|
@ -76,44 +76,44 @@ struct DelayInfo
|
||||
struct BelId
|
||||
{
|
||||
BelId() = default;
|
||||
BelId(CycloneV::pos_t _pos, uint16_t _z) : pos{_pos}, z{_z} {}
|
||||
BelId(CycloneV::xycoords _pos, uint16_t _z) : pos{_pos}, z{_z} {}
|
||||
|
||||
// pos_t is used for X/Y, nextpnr-cyclonev uses its own Z coordinate system.
|
||||
CycloneV::pos_t pos = 0;
|
||||
// xycoords is used for X/Y, nextpnr-cyclonev uses its own Z coordinate system.
|
||||
CycloneV::xycoords pos{};
|
||||
uint16_t z = 0;
|
||||
|
||||
bool operator==(const BelId &other) const { return pos == other.pos && z == other.z; }
|
||||
bool operator!=(const BelId &other) const { return pos != other.pos || z != other.z; }
|
||||
bool operator<(const BelId &other) const { return pos < other.pos || (pos == other.pos && z < other.z); }
|
||||
unsigned int hash() const { return mkhash(pos, z); }
|
||||
unsigned int hash() const { return mkhash(pos.v, z); }
|
||||
};
|
||||
|
||||
static constexpr auto invalid_rnode = std::numeric_limits<CycloneV::rnode_t>::max();
|
||||
static constexpr auto invalid_rnode = CycloneV::rnode_coords{};
|
||||
|
||||
struct WireId
|
||||
{
|
||||
WireId() = default;
|
||||
explicit WireId(CycloneV::rnode_t node) : node(node){};
|
||||
CycloneV::rnode_t node = invalid_rnode;
|
||||
explicit WireId(CycloneV::rnode_coords node) : node(node){};
|
||||
CycloneV::rnode_coords node = invalid_rnode;
|
||||
|
||||
// Wires created by nextpnr have rnode type >= 128
|
||||
bool is_nextpnr_created() const
|
||||
{
|
||||
NPNR_ASSERT(node != invalid_rnode);
|
||||
return unsigned(CycloneV::rn2t(node)) >= 128;
|
||||
return unsigned(node.t()) >= 128;
|
||||
}
|
||||
|
||||
bool operator==(const WireId &other) const { return node == other.node; }
|
||||
bool operator!=(const WireId &other) const { return node != other.node; }
|
||||
bool operator<(const WireId &other) const { return node < other.node; }
|
||||
unsigned int hash() const { return unsigned(node); }
|
||||
unsigned int hash() const { return node.v; }
|
||||
};
|
||||
|
||||
struct PipId
|
||||
{
|
||||
PipId() = default;
|
||||
PipId(CycloneV::rnode_t src, CycloneV::rnode_t dst) : src(src), dst(dst){};
|
||||
CycloneV::rnode_t src = invalid_rnode, dst = invalid_rnode;
|
||||
PipId(CycloneV::rnode_coords src, CycloneV::rnode_coords dst) : src(src), dst(dst){};
|
||||
CycloneV::rnode_coords src = invalid_rnode, dst = invalid_rnode;
|
||||
|
||||
bool operator==(const PipId &other) const { return src == other.src && dst == other.dst; }
|
||||
bool operator!=(const PipId &other) const { return src != other.src || dst != other.dst; }
|
||||
|
@ -30,15 +30,15 @@ struct MistralBitgen
|
||||
Context *ctx;
|
||||
CycloneV *cv;
|
||||
|
||||
using rnode_t = CycloneV::rnode_t;
|
||||
using pnode_t = CycloneV::pnode_t;
|
||||
using pos_t = CycloneV::pos_t;
|
||||
using rnode_coords = CycloneV::rnode_coords;
|
||||
using pnode_coords = CycloneV::pnode_coords;
|
||||
using xycoords = CycloneV::xycoords;
|
||||
using block_type_t = CycloneV::block_type_t;
|
||||
using port_type_t = CycloneV::port_type_t;
|
||||
|
||||
rnode_t find_rnode(block_type_t bt, pos_t pos, port_type_t port, int bi = -1, int pi = -1) const
|
||||
rnode_coords find_rnode(block_type_t bt, xycoords pos, port_type_t port, int bi = -1, int pi = -1) const
|
||||
{
|
||||
auto pn1 = CycloneV::pnode(bt, pos, port, bi, pi);
|
||||
auto pn1 = CycloneV::pnode_coords{bt, pos, port, bi, pi};
|
||||
auto rn1 = cv->pnode_to_rnode(pn1);
|
||||
if (rn1)
|
||||
return rn1;
|
||||
@ -55,7 +55,7 @@ struct MistralBitgen
|
||||
return rn2;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return CycloneV::rnode_coords{};
|
||||
}
|
||||
|
||||
void options()
|
||||
@ -88,7 +88,7 @@ struct MistralBitgen
|
||||
void write_io_cell(CellInfo *ci, int x, int y, int bi)
|
||||
{
|
||||
bool is_output = (ci->type == id_MISTRAL_OB || (ci->type == id_MISTRAL_IO && ci->getPort(id_OE) != nullptr));
|
||||
auto pos = CycloneV::xy2pos(x, y);
|
||||
auto pos = CycloneV::xycoords{x, y};
|
||||
// TODO: configurable pull, IO standard, etc
|
||||
cv->bmux_b_set(CycloneV::GPIO, pos, CycloneV::USE_WEAK_PULLUP, bi, false);
|
||||
if (is_output) {
|
||||
@ -96,12 +96,12 @@ struct MistralBitgen
|
||||
cv->bmux_m_set(CycloneV::GPIO, pos, CycloneV::IOCSR_STD, bi, CycloneV::DIS);
|
||||
|
||||
// Output gpios must also bypass things in the associated dqs
|
||||
auto dqs = cv->p2p_to(CycloneV::pnode(CycloneV::GPIO, pos, CycloneV::PNONE, bi, -1));
|
||||
auto dqs = cv->p2p_to(CycloneV::pnode_coords{CycloneV::GPIO, pos, CycloneV::PNONE, bi, -1});
|
||||
if (dqs) {
|
||||
cv->bmux_m_set(CycloneV::DQS16, CycloneV::pn2p(dqs), CycloneV::INPUT_REG4_SEL, CycloneV::pn2bi(dqs),
|
||||
cv->bmux_m_set(CycloneV::DQS16, dqs.p(), CycloneV::INPUT_REG4_SEL, dqs.bi(),
|
||||
CycloneV::SEL_LOCKED_DPA);
|
||||
cv->bmux_r_set(CycloneV::DQS16, CycloneV::pn2p(dqs), CycloneV::RB_T9_SEL_EREG_CFF_DELAY,
|
||||
CycloneV::pn2bi(dqs), 0x1f);
|
||||
cv->bmux_r_set(CycloneV::DQS16, dqs.p(), CycloneV::RB_T9_SEL_EREG_CFF_DELAY,
|
||||
dqs.bi(), 0x1f);
|
||||
}
|
||||
}
|
||||
// There seem to be two mirrored OEIN inversion bits for constant OE for inputs/outputs. This might be to
|
||||
@ -114,14 +114,14 @@ struct MistralBitgen
|
||||
void write_clkbuf_cell(CellInfo *ci, int x, int y, int bi)
|
||||
{
|
||||
(void)ci; // currently unused
|
||||
auto pos = CycloneV::xy2pos(x, y);
|
||||
auto pos = CycloneV::xycoords{x, y};
|
||||
cv->bmux_r_set(CycloneV::CMUXHG, pos, CycloneV::INPUT_SEL, bi, 0x1b); // hardcode to general routing
|
||||
cv->bmux_m_set(CycloneV::CMUXHG, pos, CycloneV::TESTSYN_ENOUT_SELECT, bi, CycloneV::PRE_SYNENB);
|
||||
}
|
||||
|
||||
void write_m10k_cell(CellInfo *ci, int x, int y, int bi)
|
||||
{
|
||||
auto pos = CycloneV::xy2pos(x, y);
|
||||
auto pos = CycloneV::xycoords{x, y};
|
||||
|
||||
// Notes:
|
||||
// DATA_FLOW_THRU is probably transparent reads.
|
||||
@ -240,8 +240,8 @@ struct MistralBitgen
|
||||
const std::array<CycloneV::port_type_t, 6> mux_port{CycloneV::FFT0, CycloneV::FFT1, CycloneV::FFT1L,
|
||||
CycloneV::FFB0, CycloneV::FFB1, CycloneV::FFB1L};
|
||||
for (int i = 0; i < 6; i++) {
|
||||
if (ctx->wires_connected(alm_data.comb_out[i / 3], ctx->get_port(block_type, CycloneV::pos2x(pos),
|
||||
CycloneV::pos2y(pos), alm, mux_port[i])))
|
||||
if (ctx->wires_connected(alm_data.comb_out[i / 3], ctx->get_port(block_type, pos.x(),
|
||||
pos.y(), alm, mux_port[i])))
|
||||
cv->bmux_m_set(block_type, pos, mux_settings[i], alm, CycloneV::NLUT);
|
||||
}
|
||||
|
||||
@ -358,7 +358,7 @@ struct MistralBitgen
|
||||
for (int i = 0; i < 3; i++) {
|
||||
// Check for fabric->clock routing
|
||||
if (ctx->wires_connected(
|
||||
ctx->get_port(block_type, CycloneV::pos2x(pos), CycloneV::pos2y(pos), -1, CycloneV::DATAIN, 0),
|
||||
ctx->get_port(block_type, pos.x(), pos.y(), -1, CycloneV::DATAIN, 0),
|
||||
lab_data.clk_wires[i]))
|
||||
cv->bmux_m_set(block_type, pos, CycloneV::CLKA_SEL, 0, CycloneV::DIN0);
|
||||
}
|
||||
|
@ -251,7 +251,7 @@ DelayQuad Arch::getPipDelay(PipId pip) const
|
||||
return DelayQuad{20};
|
||||
|
||||
// This is guesswork based on average of (interconnect delay / number of pips)
|
||||
auto src_type = CycloneV::rn2t(src.node);
|
||||
auto src_type = src.node.t();
|
||||
|
||||
switch (src_type) {
|
||||
case CycloneV::rnode_type_t::SCLK:
|
||||
@ -303,7 +303,7 @@ bool Arch::getArcDelayOverride(const NetInfo *net_info, const PortRef &sink, Del
|
||||
mistral::AnalogSim::wave input_wave[2], output_wave[2];
|
||||
mistral::AnalogSim::time_interval output_delays[2];
|
||||
mistral::AnalogSim::time_interval output_delay_sum[2];
|
||||
std::vector<std::pair<mistral::CycloneV::rnode_t, int>> outputs;
|
||||
std::vector<std::pair<mistral::CycloneV::rnode_coords, int>> outputs;
|
||||
auto temp = mistral::CycloneV::T_100;
|
||||
auto est = mistral::CycloneV::EST_SLOW;
|
||||
|
||||
@ -342,7 +342,7 @@ bool Arch::getArcDelayOverride(const NetInfo *net_info, const PortRef &sink, Del
|
||||
continue;
|
||||
|
||||
if (dst.is_nextpnr_created())
|
||||
dst.node = 0;
|
||||
dst.node = CycloneV::rnode_coords{};
|
||||
|
||||
auto mode = cyclonev->rnode_timing_get_mode(src.node);
|
||||
NPNR_ASSERT(mode != mistral::CycloneV::RTM_UNSUPPORTED);
|
||||
@ -378,13 +378,13 @@ bool Arch::getArcDelayOverride(const NetInfo *net_info, const PortRef &sink, Del
|
||||
: mistral::CycloneV::RF_RISE;
|
||||
mistral::AnalogSim sim;
|
||||
int input = -1;
|
||||
std::vector<std::pair<mistral::CycloneV::rnode_t, int>> outputs;
|
||||
std::vector<std::pair<mistral::CycloneV::rnode_coords, int>> outputs;
|
||||
cyclonev->rnode_timing_build_circuit(src.node, temp, CycloneV::DELAY_MAX, actual_edge, sim, input, outputs);
|
||||
|
||||
sim.set_input_wave(input, input_wave[edge]);
|
||||
auto o = std::find_if(
|
||||
outputs.begin(), outputs.end(),
|
||||
[&](std::pair<mistral::CycloneV::rnode_t, int> output) { return output.first == dst.node; });
|
||||
[&](std::pair<mistral::CycloneV::rnode_coords, int> output) { return output.first == dst.node; });
|
||||
NPNR_ASSERT(o != outputs.end());
|
||||
|
||||
output_wave[edge].clear();
|
||||
@ -419,10 +419,10 @@ delay_t Arch::predictDelay(BelId src_bel, IdString src_pin, BelId dst_bel, IdStr
|
||||
|
||||
delay_t Arch::estimateDelay(WireId src, WireId dst) const
|
||||
{
|
||||
int x0 = CycloneV::rn2x(src.node);
|
||||
int y0 = CycloneV::rn2y(src.node);
|
||||
int x1 = CycloneV::rn2x(dst.node);
|
||||
int y1 = CycloneV::rn2y(dst.node);
|
||||
int x0 = src.node.x();
|
||||
int y0 = src.node.y();
|
||||
int x1 = dst.node.x();
|
||||
int y1 = dst.node.y();
|
||||
int x_diff = std::abs(x1 - x0);
|
||||
int y_diff = std::abs(y1 - y0);
|
||||
return 75 * x_diff + 200 * y_diff;
|
||||
|
@ -71,7 +71,7 @@ struct MistralGlobalRouter
|
||||
// When routing globals; we allow global->local for some tricky cases but never local->local
|
||||
bool global_pip_filter(PipId pip) const
|
||||
{
|
||||
auto src_type = CycloneV::rn2t(pip.src);
|
||||
auto src_type = pip.src.t();
|
||||
return src_type != CycloneV::H14 && src_type != CycloneV::H6 && src_type != CycloneV::H3 &&
|
||||
src_type != CycloneV::V12 && src_type != CycloneV::V2 && src_type != CycloneV::V4 &&
|
||||
src_type != CycloneV::WM;
|
||||
|
@ -56,8 +56,8 @@ bool Arch::is_io_cell(IdString cell_type) const
|
||||
BelId Arch::get_io_pin_bel(const CycloneV::pin_info_t *pin) const
|
||||
{
|
||||
auto pad = pin->pad;
|
||||
CycloneV::pos_t pos = (pad & 0x3FFF);
|
||||
return bel_by_block_idx(CycloneV::pos2x(pos), CycloneV::pos2y(pos), id_MISTRAL_IO, (pad >> 14));
|
||||
CycloneV::xycoords pos = CycloneV::xycoords{pad & 0x3FFF};
|
||||
return bel_by_block_idx(pos.x(), pos.y(), id_MISTRAL_IO, (pad >> 14));
|
||||
}
|
||||
|
||||
NEXTPNR_NAMESPACE_END
|
||||
|
@ -1081,7 +1081,7 @@ uint64_t Arch::compute_lut_mask(uint32_t lab, uint8_t alm)
|
||||
#if 1
|
||||
if (getCtx()->debug) {
|
||||
auto pos = alm_data.lut_bels[0].pos;
|
||||
log("ALM %03d.%03d.%d\n", CycloneV::pos2x(pos), CycloneV::pos2y(pos), alm);
|
||||
log("ALM %03d.%03d.%d\n", pos.x(), pos.y(), alm);
|
||||
for (int i = 0; i < 2; i++) {
|
||||
log(" LUT%d: ", i);
|
||||
if (luts[i]) {
|
||||
|
Loading…
Reference in New Issue
Block a user