gowin: Himbaechel. Add OSER8
Signed-off-by: YRabbit <rabbit@yrabbit.cyou>
This commit is contained in:
parent
5e9a96d358
commit
dfb701b5ab
@ -1062,6 +1062,7 @@ X(GOWIN_VCC)
|
|||||||
X(PLL)
|
X(PLL)
|
||||||
X(BOTTOM_IO_PORT_A)
|
X(BOTTOM_IO_PORT_A)
|
||||||
X(BOTTOM_IO_PORT_B)
|
X(BOTTOM_IO_PORT_B)
|
||||||
|
X(IOLOGIC_DUMMY)
|
||||||
|
|
||||||
// wire types
|
// wire types
|
||||||
X(GLOBAL_CLK)
|
X(GLOBAL_CLK)
|
||||||
|
@ -185,7 +185,7 @@ void GowinImpl::postRoute()
|
|||||||
ci->setAttr(id_IOLOGIC_FCLK, Property("UNKNOWN"));
|
ci->setAttr(id_IOLOGIC_FCLK, Property("UNKNOWN"));
|
||||||
const NetInfo *h_net = ci->getPort(id_FCLK);
|
const NetInfo *h_net = ci->getPort(id_FCLK);
|
||||||
if (h_net) {
|
if (h_net) {
|
||||||
for (auto const &user : h_net->users) {
|
for (auto &user : h_net->users) {
|
||||||
if (user.port != id_FCLK) {
|
if (user.port != id_FCLK) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -195,7 +195,7 @@ void GowinImpl::postRoute()
|
|||||||
PipId up_pip = h_net->wires.at(ctx->getNetinfoSinkWire(h_net, user, 0)).pip;
|
PipId up_pip = h_net->wires.at(ctx->getNetinfoSinkWire(h_net, user, 0)).pip;
|
||||||
IdString up_wire_name = ctx->getWireName(ctx->getPipSrcWire(up_pip))[1];
|
IdString up_wire_name = ctx->getWireName(ctx->getPipSrcWire(up_pip))[1];
|
||||||
if (up_wire_name.in(id_HCLK_OUT0, id_HCLK_OUT1, id_HCLK_OUT2, id_HCLK_OUT3)) {
|
if (up_wire_name.in(id_HCLK_OUT0, id_HCLK_OUT1, id_HCLK_OUT2, id_HCLK_OUT3)) {
|
||||||
ci->setAttr(id_IOLOGIC_FCLK, Property(up_wire_name.str(ctx)));
|
user.cell->setAttr(id_IOLOGIC_FCLK, Property(up_wire_name.str(ctx)));
|
||||||
}
|
}
|
||||||
if (ctx->debug) {
|
if (ctx->debug) {
|
||||||
log_info("HCLK user cell:%s, port:%s, wire:%s, pip:%s, up wire:%s\n",
|
log_info("HCLK user cell:%s, port:%s, wire:%s, pip:%s, up wire:%s\n",
|
||||||
@ -402,8 +402,7 @@ void GowinImpl::notifyBelChange(BelId bel, CellInfo *cell)
|
|||||||
// OSER8 took both IOLOGIC bels in the tile
|
// OSER8 took both IOLOGIC bels in the tile
|
||||||
if (cell->type == id_OSER8) {
|
if (cell->type == id_OSER8) {
|
||||||
Loc loc = ctx->getBelLocation(bel);
|
Loc loc = ctx->getBelLocation(bel);
|
||||||
loc.z = BelZ::IOLOGICA_Z + (1 - (loc.z - BelZ::IOLOGICA_Z));
|
inactive_bels.insert(ctx->getBelByLocation(get_pair_iologic_bel(loc)));
|
||||||
inactive_bels.insert(ctx->getBelByLocation(loc));
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// the unbind is about to happen
|
// the unbind is about to happen
|
||||||
@ -411,8 +410,7 @@ void GowinImpl::notifyBelChange(BelId bel, CellInfo *cell)
|
|||||||
// OSER8 took both IOLOGIC bels in the tile
|
// OSER8 took both IOLOGIC bels in the tile
|
||||||
if (ci->type == id_OSER8) {
|
if (ci->type == id_OSER8) {
|
||||||
Loc loc = ctx->getBelLocation(bel);
|
Loc loc = ctx->getBelLocation(bel);
|
||||||
loc.z = BelZ::IOLOGICA_Z + (1 - (loc.z - BelZ::IOLOGICA_Z));
|
inactive_bels.erase(ctx->getBelByLocation(get_pair_iologic_bel(loc)));
|
||||||
inactive_bels.erase(ctx->getBelByLocation(loc));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,31 @@
|
|||||||
|
|
||||||
NEXTPNR_NAMESPACE_BEGIN
|
NEXTPNR_NAMESPACE_BEGIN
|
||||||
|
|
||||||
|
// Bels Z ranges. It is desirable that these numbers be synchronized with the chipdb generator
|
||||||
|
namespace BelZ {
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
LUT0_Z = 0,
|
||||||
|
LUT7_Z = 14,
|
||||||
|
MUX20_Z = 16,
|
||||||
|
MUX21_Z = 18,
|
||||||
|
MUX23_Z = 22,
|
||||||
|
MUX27_Z = 29,
|
||||||
|
ALU0_Z = 30, // :35, 6 ALU
|
||||||
|
RAMW_Z = 36, // RAM16SDP4
|
||||||
|
|
||||||
|
IOBA_Z = 50,
|
||||||
|
IOBB_Z = 51, // +IOBC...IOBL
|
||||||
|
|
||||||
|
IOLOGICA_Z = 70,
|
||||||
|
|
||||||
|
PLL_Z = 275,
|
||||||
|
GSR_Z = 276,
|
||||||
|
VCC_Z = 277,
|
||||||
|
VSS_Z = 278
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
namespace BelFlags {
|
namespace BelFlags {
|
||||||
static constexpr uint32_t FLAG_SIMPLE_IO = 0x100;
|
static constexpr uint32_t FLAG_SIMPLE_IO = 0x100;
|
||||||
}
|
}
|
||||||
@ -93,32 +118,13 @@ inline bool is_simple_io_bel(const ChipInfoPOD *chip, BelId bel)
|
|||||||
return chip_bel_info(chip, bel).flags & BelFlags::FLAG_SIMPLE_IO;
|
return chip_bel_info(chip, bel).flags & BelFlags::FLAG_SIMPLE_IO;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
inline Loc get_pair_iologic_bel(Loc loc)
|
||||||
|
|
||||||
// Bels Z ranges. It is desirable that these numbers be synchronized with the chipdb generator
|
|
||||||
namespace BelZ {
|
|
||||||
enum
|
|
||||||
{
|
{
|
||||||
LUT0_Z = 0,
|
loc.z = BelZ::IOLOGICA_Z + (1 - (loc.z - BelZ::IOLOGICA_Z));
|
||||||
LUT7_Z = 14,
|
return loc;
|
||||||
MUX20_Z = 16,
|
|
||||||
MUX21_Z = 18,
|
|
||||||
MUX23_Z = 22,
|
|
||||||
MUX27_Z = 29,
|
|
||||||
ALU0_Z = 30, // :35, 6 ALU
|
|
||||||
RAMW_Z = 36, // RAM16SDP4
|
|
||||||
|
|
||||||
IOBA_Z = 50,
|
|
||||||
IOBB_Z = 51, // +IOBC...IOBL
|
|
||||||
|
|
||||||
IOLOGICA_Z = 70,
|
|
||||||
|
|
||||||
PLL_Z = 275,
|
|
||||||
GSR_Z = 276,
|
|
||||||
VCC_Z = 277,
|
|
||||||
VSS_Z = 278
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
NEXTPNR_NAMESPACE_END
|
NEXTPNR_NAMESPACE_END
|
||||||
#endif
|
#endif
|
||||||
|
@ -82,7 +82,6 @@ struct GowinPacker
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
log_info("cnd:%d\n", cnd);
|
|
||||||
IdString wire_a_net = get_bottom_io_wire_a_net(ctx->chip_info, cnd);
|
IdString wire_a_net = get_bottom_io_wire_a_net(ctx->chip_info, cnd);
|
||||||
connect_io_wire(id_BOTTOM_IO_PORT_A, wire_a_net);
|
connect_io_wire(id_BOTTOM_IO_PORT_A, wire_a_net);
|
||||||
|
|
||||||
@ -381,6 +380,40 @@ struct GowinPacker
|
|||||||
make_iob_nets(*out_iob);
|
make_iob_nets(*out_iob);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
IdString create_aux_iologic_name(IdString main_name, int idx = 0)
|
||||||
|
{
|
||||||
|
std::string sfx("");
|
||||||
|
if (idx) {
|
||||||
|
sfx = std::to_string(idx);
|
||||||
|
}
|
||||||
|
return ctx->id(main_name.str(ctx) + std::string("_aux") + sfx);
|
||||||
|
}
|
||||||
|
|
||||||
|
BelId get_aux_iologic_bel(const CellInfo &ci)
|
||||||
|
{
|
||||||
|
return ctx->getBelByLocation(get_pair_iologic_bel(ctx->getBelLocation(ci.bel)));
|
||||||
|
}
|
||||||
|
|
||||||
|
void create_aux_iologic_cells(CellInfo &ci)
|
||||||
|
{
|
||||||
|
if (ci.type.in(id_ODDR, id_ODDRC, id_OSER4)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
IdString aux_name = create_aux_iologic_name(ci.name);
|
||||||
|
BelId bel = get_aux_iologic_bel(ci);
|
||||||
|
ctx->createCell(aux_name, id_IOLOGIC_DUMMY);
|
||||||
|
CellInfo *aux = ctx->cells[aux_name].get();
|
||||||
|
aux->addInput(id_PCLK);
|
||||||
|
ci.copyPortTo(id_PCLK, ctx->cells.at(aux_name).get(), id_PCLK);
|
||||||
|
aux->addInput(id_FCLK);
|
||||||
|
ci.copyPortTo(id_FCLK, ctx->cells.at(aux_name).get(), id_FCLK);
|
||||||
|
aux->addInput(id_RESET);
|
||||||
|
ci.copyPortTo(id_RESET, ctx->cells.at(aux_name).get(), id_RESET);
|
||||||
|
ctx->cells.at(aux_name)->setParam(ctx->id("OUTMODE"), Property("DDRENABLE"));
|
||||||
|
ctx->cells.at(aux_name)->setAttr(ctx->id("IOLOGIC_TYPE"), Property("DUMMY"));
|
||||||
|
ctx->bindBel(bel, aux, PlaceStrength::STRENGTH_LOCKED);
|
||||||
|
}
|
||||||
|
|
||||||
void pack_iologic()
|
void pack_iologic()
|
||||||
{
|
{
|
||||||
log_info("Pack IO logic...\n");
|
log_info("Pack IO logic...\n");
|
||||||
@ -396,6 +429,7 @@ struct GowinPacker
|
|||||||
}
|
}
|
||||||
if (ci.type.in(id_ODDR, id_ODDRC, id_OSER4, id_OSER8)) {
|
if (ci.type.in(id_ODDR, id_ODDRC, id_OSER4, id_OSER8)) {
|
||||||
pack_bi_output_iol(ci, cells_to_remove, nets_to_remove);
|
pack_bi_output_iol(ci, cells_to_remove, nets_to_remove);
|
||||||
|
create_aux_iologic_cells(ci);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -407,7 +441,6 @@ struct GowinPacker
|
|||||||
ctx->nets.erase(net);
|
ctx->nets.erase(net);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ===================================
|
// ===================================
|
||||||
// Constant nets
|
// Constant nets
|
||||||
// ===================================
|
// ===================================
|
||||||
|
Loading…
Reference in New Issue
Block a user