Skip to content

Commit

Permalink
Gowin. Taking into account the features of ROM
Browse files Browse the repository at this point in the history
For pROM(X9) primitives in images generated by Gowin IDE, there is an
interesting recommunication of inputs depending on the data bit depth.
For example, in some cases, a high logical level may be applied to the
Write Enable input, which, let’s say, is not entirely usual for Read
Only memory.

Here we will do similar manipulations.

In addition, several minor bug fixes are included:

 - Fixed bit numbering for non-X9 series primitives.
 - Fixed decoder generation for BLKSEL - do not assume unused inputs are
   connected to GND.
 - Use default values for BSRAM parameters - don't assume their
   mandatory presence.

Signed-off-by: YRabbit <[email protected]>
  • Loading branch information
yrabbit authored and gatecat committed Jul 9, 2024
1 parent cecd6b3 commit 1871afe
Showing 1 changed file with 45 additions and 11 deletions.
56 changes: 45 additions & 11 deletions himbaechel/uarch/gowin/pack.cc
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include "design_utils.h"
#include "log.h"
#include "nextpnr.h"
#include "util.h"

#define HIMBAECHEL_CONSTIDS "uarch/gowin/constids.inc"
#include "himbaechel_constids.h"
Expand Down Expand Up @@ -1324,7 +1325,7 @@ struct GowinPacker
{
int num = (bit_width == 9 || bit_width == 18 || bit_width == 36) ? 36 : 32;
for (int i = 0, j = offset; i < num; ++i, ++j) {
if (((i + 1) % 9) == 0 && (bit_width == 16 || bit_width == 32)) {
if (((j + 1) % 9) == 0 && (bit_width == 16 || bit_width == 32)) {
++j;
}
ci->renamePort(ctx->idf(from, i), ctx->idf(to, offset ? j % 36 : j));
Expand Down Expand Up @@ -1390,6 +1391,15 @@ struct GowinPacker
}
++idx;
}
switch (idx) {
case 1:
init |= init << 2; /* fallthrough */
case 2:
init |= init << 4;
break;
default:
break;
}
lut->setParam(id_INIT, init);

new_cells.push_back(std::move(lut_cell));
Expand All @@ -1406,7 +1416,7 @@ struct GowinPacker
if (bit_width == 32 || bit_width == 36) {
return;
}
int read_mode = ci->params.at(id_READ_MODE).as_int64();
int read_mode = int_or_default(ci->params, id_READ_MODE, 0);
if (read_mode == 0) {
return;
}
Expand Down Expand Up @@ -1511,7 +1521,7 @@ struct GowinPacker
CellInfo *new_ce_net_src = ce_pre_dff;

// add delay register in pipeline mode
int read_mode = ci->params.at(id_READ_MODE).as_int64();
int read_mode = int_or_default(ci->params, id_READ_MODE, 0);
if (read_mode) {
auto ce_pipe_dff_cell = gwu.create_cell(create_aux_name(ci->name, 0, "_ce_pipe_dff$"), id_DFF);
new_cells.push_back(std::move(ce_pipe_dff_cell));
Expand Down Expand Up @@ -1587,10 +1597,7 @@ struct GowinPacker
ci->connectPort(port, vcc_net);
}

ci->addInput(id_WRE);
ci->connectPort(id_WRE, vss_net);
ci->addInput(id_WREB);
ci->connectPort(id_WREB, vss_net);

if (!ci->params.count(id_BIT_WIDTH)) {
ci->setParam(id_BIT_WIDTH, Property(default_bw, 32));
Expand All @@ -1602,10 +1609,19 @@ struct GowinPacker
ci->copyPortTo(id_CE, ci, id_CEB);
ci->copyPortTo(id_OCE, ci, id_OCEB);
ci->copyPortTo(id_RESET, ci, id_RESETB);
ci->connectPort(id_WREB, vcc_net);

for (int i = 0; i < 14; ++i) {
ci->renamePort(ctx->idf("AD[%d]", i), ctx->idf("ADA%d", i));
ci->copyPortTo(ctx->idf("ADA%d", i), ci, ctx->idf("ADB%d", i));
// disconnect lower address bits for ROM
static int rom_ignore_bits[] = {2, 4, 8, 16, 32};
static int romx9_ignore_bits[] = {9, 9, 9, 18, 36};
for (unsigned int i = 0; i < 14; ++i) {
if (i < sizeof(rom_ignore_bits) && ((ci->type == id_pROM && bit_width >= rom_ignore_bits[i]) ||
(ci->type == id_pROMX9 && bit_width >= romx9_ignore_bits[i]))) {
ci->disconnectPort(ctx->idf("AD[%d]", i));
} else {
ci->renamePort(ctx->idf("AD[%d]", i), ctx->idf("ADA%d", i));
ci->copyPortTo(ctx->idf("ADA%d", i), ci, ctx->idf("ADB%d", i));
}
}
bsram_rename_ports(ci, bit_width, "DO[%d]", "DO%d");
} else {
Expand All @@ -1614,9 +1630,18 @@ struct GowinPacker
ci->renamePort(id_OCE, id_OCEB);
ci->renamePort(id_CE, id_CEB);
ci->renamePort(id_RESET, id_RESETB);
ci->connectPort(id_WREB, vss_net);

ci->addInput(id_CE);
ci->connectPort(id_CE, vcc_net);
ci->disconnectPort(id_OCEB);

ci->addInput(id_CEA);
ci->connectPort(id_CEA, vss_net);
int read_mode = int_or_default(ci->params, id_READ_MODE, 0);
if (read_mode) {
ci->connectPort(id_OCEB, vcc_net);
} else {
ci->copyPortTo(id_CEB, ci, id_OCEB);
}
for (int i = 0; i < 14; ++i) {
ci->renamePort(ctx->idf("AD[%d]", i), ctx->idf("ADB%d", i));
}
Expand Down Expand Up @@ -1798,6 +1823,15 @@ struct GowinPacker
bsram_fix_blksel(ci, new_cells);
}

// XXX
NetInfo *oce_net = ci->getPort(id_OCE);
if (oce_net == nullptr || oce_net->name == ctx->id("$PACKER_VCC") || oce_net->name == ctx->id("$PACKER_GND")) {
if (oce_net != nullptr) {
ci->disconnectPort(id_OCE);
ci->copyPortTo(id_CE, ci, id_OCE);
}
}

// XXX UG285-1.3.6_E Gowin BSRAM & SSRAM User Guide:
// For GW1N-9/GW1NR-9/GW1NS-4 series, 32/36-bit SP/SPX9 is divided into two
// SP/SPX9s, which occupy two BSRAMs.
Expand Down

0 comments on commit 1871afe

Please sign in to comment.