mirror of
https://github.com/YosysHQ/nextpnr.git
synced 2026-01-11 23:53:21 +00:00
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>
This commit is contained in:
parent
69facd7c9a
commit
900573c778
@ -997,6 +997,7 @@ X(IBUF)
|
||||
X(OBUF)
|
||||
X(IOBUF)
|
||||
X(TBUF)
|
||||
X(TLVDS_IBUF_ADC)
|
||||
X(TLVDS_OBUF)
|
||||
X(TLVDS_TBUF)
|
||||
X(TLVDS_IBUF)
|
||||
@ -1040,6 +1041,7 @@ X(PLLA)
|
||||
|
||||
// ADC
|
||||
X(ADC)
|
||||
X(ADC_IO)
|
||||
|
||||
// primitive attributes
|
||||
X(INIT)
|
||||
@ -1067,6 +1069,7 @@ X(I0)
|
||||
X(I1)
|
||||
X(I2)
|
||||
X(I3)
|
||||
X(ADCEN)
|
||||
X(OEN)
|
||||
X(S0)
|
||||
X(SEL)
|
||||
|
||||
@ -160,7 +160,7 @@ struct GowinCstReader
|
||||
row = col;
|
||||
col = 1;
|
||||
}
|
||||
adc_ios.insert(ctx->idf("%d/X%dY%d", std::stoi(match[1]), row - 1, col - 1));
|
||||
adc_ios.insert(ctx->idf("%d/X%dY%d", std::stoi(match[1]), col - 1, row - 1));
|
||||
} break;
|
||||
case clock: { // CLOCK name BUFG|S=#
|
||||
std::string which_clock = match[2];
|
||||
|
||||
@ -28,7 +28,7 @@ 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_TBUF, id_TLVDS_OBUF, id_TLVDS_IBUF_ADC);
|
||||
}
|
||||
inline bool is_diffio(const CellInfo *cell) { return type_is_diffio(cell->type); }
|
||||
|
||||
|
||||
@ -925,6 +925,10 @@ def create_io_tiletype(chip: Chip, db: chipdb, x: int, y: int, ttyp: int, tdesc:
|
||||
tt.add_bel_pin(io, "I", portmap['I'], PinType.INPUT)
|
||||
tt.add_bel_pin(io, "OEN", portmap['OE'], PinType.INPUT)
|
||||
tt.add_bel_pin(io, "O", portmap['O'], PinType.OUTPUT)
|
||||
if 'ADCEN' in portmap:
|
||||
tt.create_wire(portmap['ADCEN'], "IO_ADCEN")
|
||||
tt.add_bel_pin(io, "ADCEN", portmap['ADCEN'], PinType.INPUT)
|
||||
|
||||
# bottom io
|
||||
if 'BOTTOM_IO_PORT_A' in portmap and portmap['BOTTOM_IO_PORT_A']:
|
||||
if not tt.has_wire(portmap['BOTTOM_IO_PORT_A']):
|
||||
|
||||
@ -232,7 +232,8 @@ struct GowinPacker
|
||||
p = net_only_drives(ctx, ci.ports.at(id_O).net, is_iob, id_I, true);
|
||||
n = net_only_drives(ctx, ci.ports.at(id_OB).net, is_iob, id_I, true);
|
||||
break;
|
||||
case ID_ELVDS_IBUF: /* fall-through */
|
||||
case ID_TLVDS_IBUF_ADC: /* fall-through */
|
||||
case ID_ELVDS_IBUF: /* fall-through */
|
||||
case ID_TLVDS_IBUF:
|
||||
p = net_driven_by(ctx, ci.ports.at(id_I).net, is_iob, id_O);
|
||||
n = net_driven_by(ctx, ci.ports.at(id_IB).net, is_iob, id_O);
|
||||
@ -254,6 +255,10 @@ struct GowinPacker
|
||||
pn_cells.first->setParam(id_DIFF_TYPE, ci.type.str(ctx));
|
||||
pn_cells.second->setParam(id_DIFF, std::string("N"));
|
||||
pn_cells.second->setParam(id_DIFF_TYPE, ci.type.str(ctx));
|
||||
if (ci.params.count(id_ADC_IO)) {
|
||||
pn_cells.first->setParam(id_ADC_IO, ci.params.at(id_ADC_IO));
|
||||
pn_cells.second->setParam(id_ADC_IO, ci.params.at(id_ADC_IO));
|
||||
}
|
||||
}
|
||||
|
||||
void switch_diff_ports(CellInfo &ci, std::pair<CellInfo *, CellInfo *> &pn_cells,
|
||||
@ -318,6 +323,17 @@ struct GowinPacker
|
||||
ci.movePortTo(id_O, iob_p, id_O);
|
||||
return;
|
||||
}
|
||||
if (ci.type.in(id_TLVDS_IBUF_ADC)) {
|
||||
nets_to_remove.push_back(ci.getPort(id_I)->name);
|
||||
ci.disconnectPort(id_I);
|
||||
nets_to_remove.push_back(ci.getPort(id_IB)->name);
|
||||
ci.disconnectPort(id_IB);
|
||||
iob_p->disconnectPort(id_O);
|
||||
iob_n->disconnectPort(id_O);
|
||||
|
||||
ci.movePortTo(id_ADCEN, iob_p, id_ADCEN);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// ===================================
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user