1
0
mirror of https://github.com/YosysHQ/nextpnr.git synced 2026-01-11 23:53:21 +00:00
YRabbit 900573c778
Gowin. Implemenet special ADC IO. (#1598)
The TLVDS_IBUF_ADC IO primitives have been implemented, which provide a
signal for ADC bus 2. These differential IO primitives also have an
additional input that allows them to be disabled, thereby providing
dynamic switching of the signal source for the ADC.

Signed-off-by: YRabbit <rabbit@yrabbit.cyou>
2025-11-18 12:44:15 +01:00

325 lines
9.5 KiB
C++

#ifndef GOWIN_H
#define GOWIN_H
#include "nextpnr.h"
NEXTPNR_NAMESPACE_BEGIN
namespace {
// Return true if a cell is a LUT
inline bool type_is_lut(IdString cell_type) { return cell_type.in(id_LUT1, id_LUT2, id_LUT3, id_LUT4); }
inline bool is_lut(const CellInfo *cell) { return type_is_lut(cell->type); }
// Return true if a cell is a DFF
inline bool type_is_dff(IdString cell_type)
{
return cell_type.in(id_DFF, id_DFFE, id_DFFN, id_DFFNE, id_DFFS, id_DFFSE, id_DFFNS, id_DFFNSE, id_DFFR, id_DFFRE,
id_DFFNR, id_DFFNRE, id_DFFP, id_DFFPE, id_DFFNP, id_DFFNPE, id_DFFC, id_DFFCE, id_DFFNC,
id_DFFNCE);
}
inline bool is_dff(const CellInfo *cell) { return type_is_dff(cell->type); }
// Return true if a cell is a ALU
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,
id_TLVDS_TBUF, id_TLVDS_OBUF, id_TLVDS_IBUF_ADC);
}
inline bool is_diffio(const CellInfo *cell) { return type_is_diffio(cell->type); }
// MIPI
inline bool type_is_mipi(IdString cell_type) { return cell_type.in(id_MIPI_OBUF, id_MIPI_OBUF_A, id_MIPI_IBUF); }
inline bool is_mipi(const CellInfo *cell) { return type_is_mipi(cell->type); }
// I3C
inline bool type_is_i3c(IdString cell_type) { return cell_type.in(id_I3C_IOBUF); }
inline bool is_i3c(const CellInfo *cell) { return type_is_i3c(cell->type); }
// IOLOGIC input and output separately
inline bool type_is_iologico(IdString cell_type)
{
return cell_type.in(id_ODDR, id_ODDRC, id_OSER4, id_OSER8, id_OSER10, id_OVIDEO, id_IOLOGICO_EMPTY);
}
inline bool is_iologico(const CellInfo *cell) { return type_is_iologico(cell->type); }
inline bool type_is_iologici(IdString cell_type)
{
return cell_type.in(id_IDDR, id_IDDRC, id_IDES4, id_IDES8, id_IDES10, id_IVIDEO, id_IOLOGICI_EMPTY);
}
inline bool is_iologici(const CellInfo *cell) { return type_is_iologici(cell->type); }
// Return true if a cell is a SSRAM
inline bool type_is_ssram(IdString cell_type)
{
return cell_type.in(id_RAM16SDP1, id_RAM16SDP2, id_RAM16SDP4, id_ROM16);
}
inline bool is_ssram(const CellInfo *cell) { return type_is_ssram(cell->type); }
// Return true if a cell is a BSRAM
inline bool type_is_bsram(IdString cell_type)
{
return cell_type.in(id_SP, id_SPX9, id_pROM, id_pROMX9, id_ROM, id_SDP, id_SDPB, id_SDPX9B, id_DP, id_DPB,
id_DPX9B);
}
inline bool is_bsram(const CellInfo *cell) { return type_is_bsram(cell->type); }
// Return true if a cell is a DSP
inline bool type_is_dsp(IdString cell_type)
{
return cell_type.in(id_PADD9, id_PADD18, id_MULT9X9, id_MULT18X18, id_MULT36X36, id_ALU54D, id_MULTALU18X18,
id_MULTALU36X18, id_MULTADDALU18X18);
}
inline bool is_dsp(const CellInfo *cell) { return type_is_dsp(cell->type); }
// Return true if a cell is CLKDIV
inline bool type_is_clkdiv(IdString cell_type) { return cell_type == id_CLKDIV; }
inline bool is_clkdiv(const CellInfo *cell) { return type_is_clkdiv(cell->type); }
// Return true if a cell is CLKDIV2
inline bool type_is_clkdiv2(IdString cell_type) { return cell_type == id_CLKDIV2; }
inline bool is_clkdiv2(const CellInfo *cell) { return type_is_clkdiv2(cell->type); }
// Return true for HCLK Cells
inline bool is_hclk(const CellInfo *cell) { return type_is_clkdiv2(cell->type) || type_is_clkdiv(cell->type); }
// Return true if a cell is a UserFlash
inline bool type_is_userflash(IdString cell_type)
{
return cell_type.in(id_FLASH96K, id_FLASH256K, id_FLASH608K, id_FLASH128K, id_FLASH64K, id_FLASH64K, id_FLASH64KZ,
id_FLASH96KA);
}
inline bool is_userflash(const CellInfo *cell) { return type_is_userflash(cell->type); }
// Return true if a cell is a PLL
inline bool type_is_pll(IdString cell_type) { return cell_type.in(id_rPLL, id_PLLVR); }
inline bool is_pll(const CellInfo *cell) { return type_is_pll(cell->type); }
// Return true if a cell is a ADC
inline bool type_is_adc(IdString cell_type) { return cell_type.in(id_ADC); }
inline bool is_adc(const CellInfo *cell) { return type_is_adc(cell->type); }
// Return true if a cell is a EMCU
inline bool type_is_emcu(IdString cell_type) { return cell_type == id_EMCU; }
inline bool is_emcu(const CellInfo *cell) { return type_is_emcu(cell->type); }
// ==========================================
// extra data in the chip db
// ==========================================
NPNR_PACKED_STRUCT(struct Pad_extra_data_POD {
int32_t pll_tile;
int32_t pll_bel;
int32_t pll_type;
});
NPNR_PACKED_STRUCT(struct Tile_extra_data_POD {
int32_t class_id;
int16_t io16_x_off;
int16_t io16_y_off;
int32_t tile_flags;
// tile flags
static constexpr int32_t TILE_I3C_CAPABLE_IO = 1;
});
NPNR_PACKED_STRUCT(struct Bottom_io_cnd_POD {
int32_t wire_a_net;
int32_t wire_b_net;
});
NPNR_PACKED_STRUCT(struct Bottom_io_POD {
// simple OBUF
static constexpr int8_t NORMAL = 0;
// DDR
static constexpr int8_t DDR = 1;
RelSlice<Bottom_io_cnd_POD> conditions;
});
NPNR_PACKED_STRUCT(struct Spine_bel_POD {
int32_t spine;
int32_t bel_x;
int32_t bel_y;
int32_t bel_z;
});
NPNR_PACKED_STRUCT(struct Io_dlldly_bel_POD {
int32_t io;
int32_t dlldly;
});
NPNR_PACKED_STRUCT(struct Wire_bel_POD {
int32_t pip_xy;
int32_t pip_dst;
int32_t pip_src;
int32_t bel_x;
int32_t bel_y;
int32_t bel_z;
int32_t side;
});
NPNR_PACKED_STRUCT(struct Segment_POD {
int16_t x;
int16_t seg_idx;
int16_t min_x;
int16_t min_y;
int16_t max_x;
int16_t max_y;
int16_t top_row;
int16_t bottom_row;
uint32_t top_wire;
uint32_t bottom_wire;
RelSlice<uint32_t> top_gate_wire;
RelSlice<uint32_t> bottom_gate_wire;
});
NPNR_PACKED_STRUCT(struct Constraint_POD {
int32_t net;
int32_t row;
int32_t col;
int32_t bel;
int32_t iostd;
});
NPNR_PACKED_STRUCT(struct Extra_package_data_POD { RelSlice<Constraint_POD> cst; });
NPNR_PACKED_STRUCT(struct Extra_chip_data_POD {
int32_t chip_flags;
int32_t dcs_prefix;
Bottom_io_POD bottom_io;
RelSlice<IdString> diff_io_types;
RelSlice<Spine_bel_POD> dqce_bels;
RelSlice<Spine_bel_POD> dcs_bels;
RelSlice<Wire_bel_POD> dhcen_bels;
RelSlice<Io_dlldly_bel_POD> io_dlldly_bels;
RelSlice<Segment_POD> segments;
// chip flags
static constexpr int32_t HAS_SP32 = 1;
static constexpr int32_t NEED_SP_FIX = 2;
static constexpr int32_t NEED_BSRAM_OUTREG_FIX = 4;
static constexpr int32_t NEED_BLKSEL_FIX = 8;
static constexpr int32_t HAS_BANDGAP = 16;
static constexpr int32_t HAS_PLL_HCLK = 32;
static constexpr int32_t HAS_CLKDIV_HCLK = 64;
static constexpr int32_t HAS_PINCFG = 128;
static constexpr int32_t HAS_DFF67 = 256;
static constexpr int32_t HAS_CIN_MUX = 512;
static constexpr int32_t NEED_BSRAM_RESET_FIX = 1024;
static constexpr int32_t NEED_SDP_FIX = 2048;
});
} // namespace
// 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,
IDES16_Z = 74,
OSER16_Z = 75,
BUFG_Z = 76, // : 81 reserve just in case
BSRAM_Z = 100,
OSC_Z = 274,
PLL_Z = 275,
GSR_Z = 276,
VCC_Z = 277,
VSS_Z = 278,
BANDGAP_Z = 279,
DQCE_Z = 280, // : 286 reserve for 6 DQCEs
DCS_Z = 286, // : 288 reserve for 2 DCSs
DHCEN_Z = 288, // : 298
USERFLASH_Z = 298,
EMCU_Z = 300,
MIPIOBUF_Z = 301,
MIPIIBUF_Z = 302,
DLLDLY_Z = 303, // : 305 reserve for 2 DLLDLYs
PINCFG_Z = 400,
ADC_Z = 401,
// The two least significant bits encode Z for 9-bit adders and
// multipliers, if they are equal to 0, then we get Z of their common
// 18-bit equivalent.
DSP_Z = 509, // DSP
DSP_0_Z = 511, // DSP macro 0
PADD18_0_0_Z = 512,
PADD9_0_0_Z = 512 + 1,
PADD9_0_1_Z = 512 + 2,
PADD18_0_1_Z = 516,
PADD9_0_2_Z = 516 + 1,
PADD9_0_3_Z = 516 + 2,
MULT18X18_0_0_Z = 520,
MULT9X9_0_0_Z = 520 + 1,
MULT9X9_0_1_Z = 520 + 2,
MULT18X18_0_1_Z = 524,
MULT9X9_0_2_Z = 524 + 1,
MULT9X9_0_3_Z = 524 + 2,
ALU54D_0_Z = 524 + 3,
MULTALU18X18_0_Z = 528,
MULTALU36X18_0_Z = 528 + 1,
MULTADDALU18X18_0_Z = 528 + 2,
MULT36X36_Z = 528 + 3,
DSP_1_Z = 543, // DSP macro 1
PADD18_1_0_Z = 544,
PADD9_1_0_Z = 544 + 1,
PADD9_1_1_Z = 544 + 2,
PADD18_1_1_Z = 548,
PADD9_1_2_Z = 548 + 1,
PADD9_1_3_Z = 548 + 2,
MULT18X18_1_0_Z = 552,
MULT9X9_1_0_Z = 552 + 1,
MULT9X9_1_1_Z = 552 + 2,
MULT18X18_1_1_Z = 556,
MULT9X9_1_2_Z = 556 + 1,
MULT9X9_1_3_Z = 556 + 2,
ALU54D_1_Z = 556 + 3,
MULTALU18X18_1_Z = 560,
MULTALU36X18_1_Z = 560 + 1,
MULTADDALU18X18_1_Z = 560 + 2,
// HCLK Bels
CLKDIV2_0_Z = 610,
CLKDIV2_1_Z = 611,
CLKDIV2_2_Z = 612,
CLKDIV2_3_Z = 613,
CLKDIV_0_Z = 620,
CLKDIV_1_Z = 621,
CLKDIV_2_Z = 622,
CLKDIV_3_Z = 623
};
}
NEXTPNR_NAMESPACE_END
#endif