gowin: Himbaechel. Use pin functions info

Use information about pin functions in the clock router.

Signed-off-by: YRabbit <rabbit@yrabbit.cyou>
This commit is contained in:
YRabbit 2023-07-20 12:09:14 +10:00 committed by myrtle
parent b2ec06dfe8
commit 6eeac1cabf
6 changed files with 77 additions and 11 deletions

View File

@ -29,14 +29,16 @@
#include "globals.h"
#include "gowin.h"
#include "gowin_utils.h"
NEXTPNR_NAMESPACE_BEGIN
struct GowinGlobalRouter
{
Context *ctx;
GowinUtils gwu;
GowinGlobalRouter(Context *ctx) : ctx(ctx){};
GowinGlobalRouter(Context *ctx) : ctx(ctx) { gwu.init(ctx); };
// allow io->global, global->global and global->tile clock
bool global_pip_filter(PipId pip) const
@ -157,8 +159,18 @@ struct GowinGlobalRouter
bool driver_is_clksrc(const PortRef &driver)
{
// XXX dedicated pins
return driver.port == id_O;
// dedicated pins
if (CellTypePort(driver) == CellTypePort(id_IBUF, id_O)) {
NPNR_ASSERT(driver.cell->bel != BelId());
IdStringList pin_func = gwu.get_pin_funcs(driver.cell->bel);
for (size_t i = 0; i < pin_func.size(); ++i) {
if (pin_func[i].str(ctx).rfind("GCLKT", 0) == 0) {
return true;
}
}
}
return false;
}
void run(void)

View File

@ -12,6 +12,7 @@
#include "cst.h"
#include "globals.h"
#include "gowin.h"
#include "gowin_utils.h"
#include "pack.h"
NEXTPNR_NAMESPACE_BEGIN
@ -38,6 +39,7 @@ struct GowinImpl : HimbaechelAPI
private:
HimbaechelHelpers h;
GowinUtils gwu;
IdString chip;
IdString partno;
@ -70,6 +72,8 @@ void GowinImpl::init(Context *ctx)
h.init(ctx);
HimbaechelAPI::init(ctx);
gwu.init(ctx);
const ArchArgs &args = ctx->getArchArgs();
// These fields go in the header of the output JSON file and can help
// gowin_pack support different architectures

View File

@ -348,6 +348,7 @@ def create_ssram_tiletype(chip: Chip, db: chipdb, x: int, y: int, ttyp: int):
tt.add_bel_pin(ff, f"WRE", "LSR2", PinType.INPUT)
return (ttyp, tt)
# pinouts, packages...
_tbrlre = re.compile(r"IO([TBRL])(\d+)(\w)")
def create_packages(chip: Chip, db: chipdb):
def ioloc_to_tile_bel(ioloc):

View File

@ -0,0 +1,25 @@
#include "gowin_utils.h"
#include "log.h"
#include "nextpnr.h"
#include "util.h"
NEXTPNR_NAMESPACE_BEGIN
// pin functions: GCLKT_4, SSPI_CS, READY etc
IdStringList GowinUtils::get_pin_funcs(BelId bel)
{
IdStringList bel_name = ctx->getBelName(bel);
const PadInfoPOD *pins = ctx->package_info->pads.get();
size_t len = ctx->package_info->pads.ssize();
for (size_t i = 0; i < len; i++) {
const PadInfoPOD *pin = &pins[i];
if (IdString(pin->tile) == bel_name[0] && IdString(pin->bel) == bel_name[1]) {
return IdStringList::parse(ctx, IdString(pin->pad_function).str(ctx));
}
}
return IdStringList();
}
NEXTPNR_NAMESPACE_END

View File

@ -0,0 +1,24 @@
#ifndef GOWIN_UTILS_H
#define GOWIN_UTILS_H
#include "idstringlist.h"
#include "nextpnr_namespaces.h"
#include "nextpnr_types.h"
NEXTPNR_NAMESPACE_BEGIN
struct GowinUtils
{
Context *ctx;
GowinUtils() {}
void init(Context *ctx) { this->ctx = ctx; }
// pin functions: GCLKT_4, SSPI_CS, READY etc
IdStringList get_pin_funcs(BelId bel);
};
NEXTPNR_NAMESPACE_END
#endif

View File

@ -305,8 +305,8 @@ struct GowinPacker
// create ALU chain
void pack_alus(void)
{
static CellTypePort cell_alu_cout = CellTypePort(id_ALU, id_COUT);
static CellTypePort cell_alu_cin = CellTypePort(id_ALU, id_CIN);
const CellTypePort cell_alu_cout = CellTypePort(id_ALU, id_COUT);
const CellTypePort cell_alu_cin = CellTypePort(id_ALU, id_CIN);
std::vector<std::unique_ptr<CellInfo>> new_cells;
log_info("Pack ALUs...\n");
@ -409,12 +409,12 @@ struct GowinPacker
void constrain_lutffs(void)
{
// Constrain directly connected LUTs and FFs together to use dedicated resources
auto lut_outs = pool<CellTypePort>{{id_LUT1, id_F}, {id_LUT2, id_F}, {id_LUT3, id_F}, {id_LUT4, id_F}};
auto dff_ins = pool<CellTypePort>{{id_DFF, id_D}, {id_DFFE, id_D}, {id_DFFN, id_D}, {id_DFFNE, id_D},
{id_DFFS, id_D}, {id_DFFSE, id_D}, {id_DFFNS, id_D}, {id_DFFNSE, id_D},
{id_DFFR, id_D}, {id_DFFRE, id_D}, {id_DFFNR, id_D}, {id_DFFNRE, id_D},
{id_DFFP, id_D}, {id_DFFPE, id_D}, {id_DFFNP, id_D}, {id_DFFNPE, id_D},
{id_DFFC, id_D}, {id_DFFCE, id_D}, {id_DFFNC, id_D}, {id_DFFNCE, id_D}};
const pool<CellTypePort> lut_outs{{id_LUT1, id_F}, {id_LUT2, id_F}, {id_LUT3, id_F}, {id_LUT4, id_F}};
const pool<CellTypePort> dff_ins{{id_DFF, id_D}, {id_DFFE, id_D}, {id_DFFN, id_D}, {id_DFFNE, id_D},
{id_DFFS, id_D}, {id_DFFSE, id_D}, {id_DFFNS, id_D}, {id_DFFNSE, id_D},
{id_DFFR, id_D}, {id_DFFRE, id_D}, {id_DFFNR, id_D}, {id_DFFNRE, id_D},
{id_DFFP, id_D}, {id_DFFPE, id_D}, {id_DFFNP, id_D}, {id_DFFNPE, id_D},
{id_DFFC, id_D}, {id_DFFCE, id_D}, {id_DFFNC, id_D}, {id_DFFNCE, id_D}};
int lutffs = h.constrain_cell_pairs(lut_outs, dff_ins, 1);
log_info("Constrained %d LUTFF pairs.\n", lutffs);