Merge pull request #382 from YosysHQ/ecp5-psuedodiff

ecp5: Add support for top pseudo diff outputs
This commit is contained in:
David Shah 2020-01-16 09:38:00 +00:00 committed by GitHub
commit 54c1bc1538
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 42 additions and 13 deletions

View File

@ -256,6 +256,18 @@ static std::string get_pic_tile(Context *ctx, BelId bel)
} }
} }
// Get the complement PIC and PIO tiles for a pseudo differential IO
static std::string get_comp_pio_tile(Context *ctx, BelId bel)
{
NPNR_ASSERT(bel.location.y == 0);
return ctx->getTileByTypeAndLocation(0, bel.location.x + 1, "PIOT1");
}
static std::string get_comp_pic_tile(Context *ctx, BelId bel)
{
NPNR_ASSERT(bel.location.y == 0);
return ctx->getTileByTypeAndLocation(1, bel.location.x + 1, "PICT1");
}
// Get the list of tiles corresponding to a blockram // Get the list of tiles corresponding to a blockram
std::vector<std::string> get_bram_tiles(Context *ctx, BelId bel) std::vector<std::string> get_bram_tiles(Context *ctx, BelId bel)
{ {
@ -829,18 +841,29 @@ void write_bitstream(Context *ctx, std::string base_config_file, std::string tex
cc.tiles[pio_tile].add_enum(pio + ".BASE_TYPE", dir + "_" + iotype); cc.tiles[pio_tile].add_enum(pio + ".BASE_TYPE", dir + "_" + iotype);
cc.tiles[pic_tile].add_enum(pio + ".BASE_TYPE", dir + "_" + iotype); cc.tiles[pic_tile].add_enum(pio + ".BASE_TYPE", dir + "_" + iotype);
if (is_differential(ioType_from_str(iotype))) { if (is_differential(ioType_from_str(iotype))) {
// Explicitly disable other pair if (bel.location.y == 0) {
std::string other; // Pseudo differential top IO
if (pio == "PIOA") NPNR_ASSERT(dir == "OUTPUT");
other = "PIOB"; NPNR_ASSERT(pio == "PIOA");
else if (pio == "PIOC") std::string cpio_tile = get_comp_pio_tile(ctx, bel);
other = "PIOD"; std::string cpic_tile = get_comp_pic_tile(ctx, bel);
else cc.tiles[cpio_tile].add_enum(pio + ".BASE_TYPE", dir + "_" + iotype);
log_error("cannot place differential IO at location %s\n", pio.c_str()); cc.tiles[cpic_tile].add_enum(pio + ".BASE_TYPE", dir + "_" + iotype);
// cc.tiles[pio_tile].add_enum(other + ".BASE_TYPE", "_NONE_"); } else {
// cc.tiles[pic_tile].add_enum(other + ".BASE_TYPE", "_NONE_"); // Explicitly disable other pair
cc.tiles[pio_tile].add_enum(other + ".PULLMODE", "NONE"); std::string other;
cc.tiles[pio_tile].add_enum(pio + ".PULLMODE", "NONE"); if (pio == "PIOA")
other = "PIOB";
else if (pio == "PIOC")
other = "PIOD";
else
log_error("cannot place differential IO at location %s\n", pio.c_str());
// cc.tiles[pio_tile].add_enum(other + ".BASE_TYPE", "_NONE_");
// cc.tiles[pic_tile].add_enum(other + ".BASE_TYPE", "_NONE_");
cc.tiles[pio_tile].add_enum(other + ".PULLMODE", "NONE");
cc.tiles[pio_tile].add_enum(pio + ".PULLMODE", "NONE");
}
} else if (is_referenced(ioType_from_str(iotype))) { } else if (is_referenced(ioType_from_str(iotype))) {
cc.tiles[pio_tile].add_enum(pio + ".PULLMODE", "NONE"); cc.tiles[pio_tile].add_enum(pio + ".PULLMODE", "NONE");
} }

View File

@ -22,6 +22,8 @@ X(SSTL15D_II)
X(HSUL12D) X(HSUL12D)
X(LVCMOS33D) X(LVCMOS33D)
X(LVCMOS25D) X(LVCMOS25D)
X(LVCMOS15D)
X(LVCMOS12D)
X(LVDS) X(LVDS)
X(BLVDS25) X(BLVDS25)

View File

@ -109,6 +109,7 @@ IOVoltage get_vccio(IOType type)
case IOType::SSTL18D_II: case IOType::SSTL18D_II:
return IOVoltage::VCC_1V8; return IOVoltage::VCC_1V8;
case IOType::LVCMOS15: case IOType::LVCMOS15:
case IOType::LVCMOS15D:
case IOType::SSTL15_I: case IOType::SSTL15_I:
case IOType::SSTL15_II: case IOType::SSTL15_II:
case IOType::SSTL15D_I: case IOType::SSTL15D_I:
@ -120,6 +121,7 @@ IOVoltage get_vccio(IOType type)
case IOType::SSTL135D_II: case IOType::SSTL135D_II:
return IOVoltage::VCC_1V35; return IOVoltage::VCC_1V35;
case IOType::LVCMOS12: case IOType::LVCMOS12:
case IOType::LVCMOS12D:
case IOType::HSUL12: case IOType::HSUL12:
case IOType::HSUL12D: case IOType::HSUL12D:
return IOVoltage::VCC_1V2; return IOVoltage::VCC_1V2;
@ -159,6 +161,8 @@ bool is_differential(IOType type)
switch (type) { switch (type) {
case IOType::LVCMOS33D: case IOType::LVCMOS33D:
case IOType::LVCMOS25D: case IOType::LVCMOS25D:
case IOType::LVCMOS15D:
case IOType::LVCMOS12D:
case IOType::LVPECL33: case IOType::LVPECL33:
case IOType::LVDS: case IOType::LVDS:
case IOType::MLVDS25: case IOType::MLVDS25:
@ -207,7 +211,7 @@ bool valid_loc_for_io(IOType type, PortType dir, IOSide side, int z)
bool is_lr = side == IOSide::LEFT || side == IOSide::RIGHT; bool is_lr = side == IOSide::LEFT || side == IOSide::RIGHT;
if (is_referenced(type) && !is_lr) if (is_referenced(type) && !is_lr)
return false; return false;
if (is_differential(type) && (!is_lr || ((z % 2) == 1))) if (is_differential(type) && ((!is_lr && dir != PORT_OUT) || ((z % 2) == 1)))
return false; return false;
if ((type == IOType::LVCMOS18D || type == IOType::LVDS) && (dir == PORT_OUT || dir == PORT_INOUT) && z != 0) if ((type == IOType::LVCMOS18D || type == IOType::LVDS) && (dir == PORT_OUT || dir == PORT_INOUT) && z != 0)
return false; return false;