Skip to content

Commit

Permalink
Gowin. Add the ability to place registers in IOB (#1403)
Browse files Browse the repository at this point in the history
* Gowin. Add the ability to place registers in IOB

IO blocks have registers: for input, for output and for OutputEnable
signal - IREG, OREG and TREG respectively.

Each of the registers has one implicit non-switched wire, which one
depends on the type of register (IREG has a Q wire, OREG has a D wire).
Although the registers can be activated independently of each other they
share the CLK, ClockEnable and LocalSetReset wires and this places
restrictions on the possible combinations of register types in a single
IO.

Register placement in IO blocks is enabled by specifying the command
line keys --vopt ireg_in_iob, --vopt oreg_in_iob, or --vopt ioreg_in_iob.

It should be noted that specifying these keys leads to attempts to place
registers in IO blocks, but no errors are generated in case of failure.

Signed-off-by: YRabbit <[email protected]>

* Gowin. Registers in IO

Check for unconnected ports.

Signed-off-by: YRabbit <[email protected]>

* Gowin. IO regs. Verbose warnings.

If an attempt to place an FF in an IO block fails, issue a warning
detailing the reason for the failure, whether it is a register type
conflict, a network requirement violation, or a control signal conflict.

Signed-off-by: YRabbit <[email protected]>

* Gowin. BUGFIX. Fix FFs compatibility.

Flipflops with a fixed ClockEnable input cannot coexist with flipflops
with a variable one.

Signed-off-by: YRabbit <[email protected]>

* Gowin. FFs in IO.  Changing diagnostic messages.

Placement modes are still specified by the command line keys
ireg_in_iob/oreg_in_iob/ioreg_in_iob, but also introduces more granular
control in the form of attributes at I/O ports:

  (* NOIOBFF *) - registers are never placed in this IO,

  (* IOBFF *) - registers must be placed in this IO, in case of failure
  a warning (not an error) with the reason for nonplacement is issued,

  _attribute_absence_ - no diagnostics will be issued: managed to place - good, failed - not bad either.

Signed-off-by: YRabbit <[email protected]>

* Gowin. Registers in IO.

Change the logic for handling command line keys and attributes -
attributes allow routines to be placed in IO regardless of global mode.

Signed-off-by: YRabbit <[email protected]>

* Gowin. Registers in IO. Fix style.

Signed-off-by: YRabbit <[email protected]>

---------

Signed-off-by: YRabbit <[email protected]>
  • Loading branch information
yrabbit authored Jan 1, 2025
1 parent 0345b6e commit c565e36
Show file tree
Hide file tree
Showing 4 changed files with 393 additions and 10 deletions.
21 changes: 21 additions & 0 deletions himbaechel/uarch/gowin/constids.inc
Original file line number Diff line number Diff line change
Expand Up @@ -1312,3 +1312,24 @@ X(LSREN)

// EMCU
X(EMCU)

// Register placement options
X(IREG_IN_IOB)
X(OREG_IN_IOB)
X(IOREG_IN_IOB)
X(HAS_REG)
X(IREG_TYPE)
X(OREG_TYPE)
X(TREG_TYPE)
X(IREG_CLK_NET)
X(IREG_CE_NET)
X(IREG_LSR_NET)
X(OREG_CLK_NET)
X(OREG_CE_NET)
X(OREG_LSR_NET)
X(TREG_CLK_NET)
X(TREG_CE_NET)
X(TREG_LSR_NET)
X(NOIOBFF)
X(IOBFF)

15 changes: 14 additions & 1 deletion himbaechel/uarch/gowin/gowin.cc
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,17 @@ void GowinImpl::init(Context *ctx)
if (args.options.count("cst")) {
ctx->settings[ctx->id("cst.filename")] = args.options.at("cst");
}

// place registers in IO blocks
if (args.options.count("ireg_in_iob")) {
ctx->settings[id_IREG_IN_IOB] = Property(1);
}
if (args.options.count("oreg_in_iob")) {
ctx->settings[id_OREG_IN_IOB] = Property(1);
}
if (args.options.count("ioreg_in_iob")) {
ctx->settings[id_IOREG_IN_IOB] = Property(1);
}
}

// We do not allow the use of global wires that bypass a special router.
Expand Down Expand Up @@ -811,7 +822,9 @@ inline bool incompatible_ffs(const CellInfo *ff, const CellInfo *adj_ff)
(ff->type == id_DFFNRE && adj_ff->type != id_DFFNSE) ||
(ff->type == id_DFFNP && adj_ff->type != id_DFFNC) || (ff->type == id_DFFNC && adj_ff->type != id_DFFNP) ||
(ff->type == id_DFFNPE && adj_ff->type != id_DFFNCE) ||
(ff->type == id_DFFNCE && adj_ff->type != id_DFFNPE));
(ff->type == id_DFFNCE && adj_ff->type != id_DFFNPE) || (ff->type == id_DFF && adj_ff->type != id_DFF) ||
(ff->type == id_DFFE && adj_ff->type != id_DFFE) || (ff->type == id_DFFN && adj_ff->type != id_DFFN) ||
(ff->type == id_DFFNE && adj_ff->type != id_DFFNE));
}

// placement validation
Expand Down
4 changes: 4 additions & 0 deletions himbaechel/uarch/gowin/gowin.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ inline bool is_dff(const CellInfo *cell) { return type_is_dff(cell->type); }
inline bool type_is_alu(IdString cell_type) { return cell_type == id_ALU; }
inline bool is_alu(const CellInfo *cell) { return type_is_alu(cell->type); }

// io
inline bool type_is_io(IdString cell_type) { return cell_type.in(id_IBUF, id_OBUF, id_IOBUF, id_TBUF); }
inline bool is_io(const CellInfo *cell) { return type_is_io(cell->type); }

inline bool type_is_diffio(IdString cell_type)
{
return cell_type.in(id_ELVDS_IOBUF, id_ELVDS_IBUF, id_ELVDS_TBUF, id_ELVDS_OBUF, id_TLVDS_IOBUF, id_TLVDS_IBUF,
Expand Down
Loading

0 comments on commit c565e36

Please sign in to comment.