ice40: SB_LFOSC support, fabric routing only
Signed-off-by: David Shah <davey1576@gmail.com>
This commit is contained in:
parent
6a783ef94f
commit
8850f86a8a
@ -692,11 +692,6 @@ struct Arch : BaseCtx
|
|||||||
bool checkPipAvail(PipId pip) const
|
bool checkPipAvail(PipId pip) const
|
||||||
{
|
{
|
||||||
assert(pip != PipId());
|
assert(pip != PipId());
|
||||||
if (args.type == ArchArgs::UP5K) {
|
|
||||||
int x = chip_info->pip_data[pip.index].x;
|
|
||||||
if (x == 0 || x == (chip_info->width - 1))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return switches_locked[chip_info->pip_data[pip.index].switch_index] ==
|
return switches_locked[chip_info->pip_data[pip.index].switch_index] ==
|
||||||
IdString();
|
IdString();
|
||||||
}
|
}
|
||||||
|
@ -267,7 +267,8 @@ void write_asc(const Context *ctx, std::ostream &out)
|
|||||||
read_mode & 0x1);
|
read_mode & 0x1);
|
||||||
set_config(ti_ramt, config.at(y + 1).at(x), "RamConfig.CBIT_3",
|
set_config(ti_ramt, config.at(y + 1).at(x), "RamConfig.CBIT_3",
|
||||||
read_mode & 0x2);
|
read_mode & 0x2);
|
||||||
} else if (cell.second->type == ctx->id("SB_WARMBOOT")) {
|
} else if (cell.second->type == ctx->id("SB_WARMBOOT") ||
|
||||||
|
cell.second->type == ctx->id("ICESTORM_LFOSC")) {
|
||||||
// No config needed
|
// No config needed
|
||||||
} else {
|
} else {
|
||||||
assert(false);
|
assert(false);
|
||||||
@ -323,13 +324,8 @@ void write_asc(const Context *ctx, std::ostream &out)
|
|||||||
ctx->args.type == ArchArgs::HX8K) {
|
ctx->args.type == ArchArgs::HX8K) {
|
||||||
setColBufCtrl = (y == 8 || y == 9 || y == 24 || y == 25);
|
setColBufCtrl = (y == 8 || y == 9 || y == 24 || y == 25);
|
||||||
} else if (ctx->args.type == ArchArgs::UP5K) {
|
} else if (ctx->args.type == ArchArgs::UP5K) {
|
||||||
if (tile == TILE_LOGIC || tile == TILE_RAMB ||
|
|
||||||
tile == TILE_RAMT) {
|
|
||||||
setColBufCtrl = (y == 4 || y == 5 || y == 14 || y == 15 ||
|
setColBufCtrl = (y == 4 || y == 5 || y == 14 || y == 15 ||
|
||||||
y == 26 || y == 27);
|
y == 26 || y == 27);
|
||||||
} else {
|
|
||||||
setColBufCtrl = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (setColBufCtrl) {
|
if (setColBufCtrl) {
|
||||||
set_config(ti, config.at(y).at(x), "ColBufCtrl.glb_netwk_0",
|
set_config(ti, config.at(y).at(x), "ColBufCtrl.glb_netwk_0",
|
||||||
@ -349,6 +345,35 @@ void write_asc(const Context *ctx, std::ostream &out)
|
|||||||
set_config(ti, config.at(y).at(x), "ColBufCtrl.glb_netwk_7",
|
set_config(ti, config.at(y).at(x), "ColBufCtrl.glb_netwk_7",
|
||||||
true);
|
true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Weird UltraPlus bits
|
||||||
|
if (tile == TILE_DSP0 || tile == TILE_DSP1 || tile == TILE_DSP2 ||
|
||||||
|
tile == TILE_IPCON) {
|
||||||
|
for (int lc_idx = 0; lc_idx < 8; lc_idx++) {
|
||||||
|
static const std::vector<int> ip_dsp_lut_perm = {
|
||||||
|
4, 14, 15, 5, 6, 16, 17, 7,
|
||||||
|
3, 13, 12, 2, 1, 11, 10, 0,
|
||||||
|
};
|
||||||
|
for (int i = 0; i < 16; i++)
|
||||||
|
set_config(ti, config.at(y).at(x),
|
||||||
|
"LC_" + std::to_string(lc_idx),
|
||||||
|
((i % 8) >= 4), ip_dsp_lut_perm.at(i));
|
||||||
|
if (tile == TILE_IPCON)
|
||||||
|
set_config(ti, config.at(y).at(x),
|
||||||
|
"Cascade.IPCON_LC0" +
|
||||||
|
std::to_string(lc_idx) +
|
||||||
|
"_inmux02_5",
|
||||||
|
true);
|
||||||
|
else
|
||||||
|
set_config(
|
||||||
|
ti, config.at(y).at(x),
|
||||||
|
"Cascade.MULT" +
|
||||||
|
std::to_string(int(tile - TILE_DSP0)) +
|
||||||
|
"_LC0" + std::to_string(lc_idx) +
|
||||||
|
"_inmux02_5",
|
||||||
|
true);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -106,11 +106,26 @@ CellInfo *create_ice_cell(Context *ctx, IdString type, std::string name)
|
|||||||
add_port(ctx, new_cell, "RADDR_" + std::to_string(i), PORT_IN);
|
add_port(ctx, new_cell, "RADDR_" + std::to_string(i), PORT_IN);
|
||||||
add_port(ctx, new_cell, "WADDR_" + std::to_string(i), PORT_IN);
|
add_port(ctx, new_cell, "WADDR_" + std::to_string(i), PORT_IN);
|
||||||
}
|
}
|
||||||
|
} else if (type == ctx->id("ICESTORM_LFOSC")) {
|
||||||
|
add_port(ctx, new_cell, "CLKLFEN", PORT_IN);
|
||||||
|
add_port(ctx, new_cell, "CLKLFPU", PORT_IN);
|
||||||
|
add_port(ctx, new_cell, "CLKLF", PORT_OUT);
|
||||||
|
add_port(ctx, new_cell, "CLKLF_FABRIC", PORT_OUT);
|
||||||
|
} else if (type == ctx->id("ICESTORM_HFOSC")) {
|
||||||
|
new_cell->params[ctx->id("CLKHF_DIV")] = "0";
|
||||||
|
new_cell->params[ctx->id("TRIM_EN")] = "0";
|
||||||
|
|
||||||
|
add_port(ctx, new_cell, "CLKHFEN", PORT_IN);
|
||||||
|
add_port(ctx, new_cell, "CLKHFPU", PORT_IN);
|
||||||
|
add_port(ctx, new_cell, "CLKHF", PORT_OUT);
|
||||||
|
add_port(ctx, new_cell, "CLKHF_FABRIC", PORT_OUT);
|
||||||
|
for (int i = 0; i < 10; i++)
|
||||||
|
add_port(ctx, new_cell, "TRIM" + std::to_string(i), PORT_IN);
|
||||||
} else if (type == ctx->id("SB_GB")) {
|
} else if (type == ctx->id("SB_GB")) {
|
||||||
add_port(ctx, new_cell, "USER_SIGNAL_TO_GLOBAL_BUFFER", PORT_IN);
|
add_port(ctx, new_cell, "USER_SIGNAL_TO_GLOBAL_BUFFER", PORT_IN);
|
||||||
add_port(ctx, new_cell, "GLOBAL_BUFFER_OUTPUT", PORT_OUT);
|
add_port(ctx, new_cell, "GLOBAL_BUFFER_OUTPUT", PORT_OUT);
|
||||||
} else {
|
} else {
|
||||||
log_error("unable to create iCE40 cell of type %s", type.c_str());
|
log_error("unable to create iCE40 cell of type %s", type.c_str(ctx));
|
||||||
}
|
}
|
||||||
return new_cell;
|
return new_cell;
|
||||||
}
|
}
|
||||||
@ -124,7 +139,7 @@ void lut_to_lc(const Context *ctx, CellInfo *lut, CellInfo *lc, bool no_dff)
|
|||||||
replace_port(lut, "I3", lc, "I3");
|
replace_port(lut, "I3", lc, "I3");
|
||||||
if (no_dff) {
|
if (no_dff) {
|
||||||
replace_port(lut, "O", lc, "O");
|
replace_port(lut, "O", lc, "O");
|
||||||
lc->params["DFF_ENABLE"] = "0";
|
lc->params[ctx->id("DFF_ENABLE")] = "0";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -91,6 +91,16 @@ inline bool is_ram(const Context *ctx, const CellInfo *cell)
|
|||||||
cell->type == ctx->id("SB_RAM40_4KNRNW");
|
cell->type == ctx->id("SB_RAM40_4KNRNW");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline bool is_sb_lfosc(const Context *ctx, const CellInfo *cell)
|
||||||
|
{
|
||||||
|
return cell->type == ctx->id("SB_LFOSC");
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool is_sb_hfosc(const Context *ctx, const CellInfo *cell)
|
||||||
|
{
|
||||||
|
return cell->type == ctx->id("SB_HFOSC");
|
||||||
|
}
|
||||||
|
|
||||||
// Convert a SB_LUT primitive to (part of) an ICESTORM_LC, swapping ports
|
// Convert a SB_LUT primitive to (part of) an ICESTORM_LC, swapping ports
|
||||||
// as needed. Set no_dff if a DFF is not being used, so that the output
|
// as needed. Set no_dff if a DFF is not being used, so that the output
|
||||||
// can be reconnected
|
// can be reconnected
|
||||||
|
@ -485,6 +485,39 @@ static void promote_globals(Context *ctx)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Pack internal oscillators
|
||||||
|
static void pack_intosc(Context *ctx)
|
||||||
|
{
|
||||||
|
log_info("Packing oscillators..\n");
|
||||||
|
|
||||||
|
std::unordered_set<IdString> packed_cells;
|
||||||
|
std::vector<CellInfo *> new_cells;
|
||||||
|
|
||||||
|
for (auto cell : sorted(ctx->cells)) {
|
||||||
|
CellInfo *ci = cell.second;
|
||||||
|
if (is_sb_lfosc(ctx, ci)) {
|
||||||
|
CellInfo *packed = create_ice_cell(ctx, "ICESTORM_LFOSC",
|
||||||
|
ci->name.str(ctx) + "_OSC");
|
||||||
|
packed_cells.insert(ci->name);
|
||||||
|
new_cells.push_back(packed);
|
||||||
|
replace_port(ci, "CLKLFEN", packed, "CLKLFEN");
|
||||||
|
replace_port(ci, "CLKLFPU", packed, "CLKLFPU");
|
||||||
|
if (bool_or_default(ci->attrs, "ROUTE_THROUGH_FABRIC")) {
|
||||||
|
replace_port(ci, "CLKLF", packed, "CLKLF_FABRIC");
|
||||||
|
} else {
|
||||||
|
replace_port(ci, "CLKLF", packed, "CLKLF");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto pcell : packed_cells) {
|
||||||
|
ctx->cells.erase(pcell);
|
||||||
|
}
|
||||||
|
for (auto ncell : new_cells) {
|
||||||
|
ctx->cells[ncell->name] = ncell;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Main pack function
|
// Main pack function
|
||||||
bool pack_design(Context *ctx)
|
bool pack_design(Context *ctx)
|
||||||
{
|
{
|
||||||
@ -496,6 +529,7 @@ bool pack_design(Context *ctx)
|
|||||||
pack_lut_lutffs(ctx);
|
pack_lut_lutffs(ctx);
|
||||||
pack_nonlut_ffs(ctx);
|
pack_nonlut_ffs(ctx);
|
||||||
pack_ram(ctx);
|
pack_ram(ctx);
|
||||||
|
pack_intosc(ctx);
|
||||||
log_info("Checksum: 0x%08x\n", ctx->checksum());
|
log_info("Checksum: 0x%08x\n", ctx->checksum());
|
||||||
return true;
|
return true;
|
||||||
} catch (log_execution_error_exception) {
|
} catch (log_execution_error_exception) {
|
||||||
|
Loading…
Reference in New Issue
Block a user