ice40: UltraPlus SPRAM working
Signed-off-by: David Shah <davey1576@gmail.com>
This commit is contained in:
parent
27e7bc3b4b
commit
302ccc14cf
@ -39,8 +39,8 @@
|
|||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "place_common.h"
|
#include "place_common.h"
|
||||||
#include "place_legaliser.h"
|
#include "place_legaliser.h"
|
||||||
#include "util.h"
|
|
||||||
#include "timing.h"
|
#include "timing.h"
|
||||||
|
#include "util.h"
|
||||||
NEXTPNR_NAMESPACE_BEGIN
|
NEXTPNR_NAMESPACE_BEGIN
|
||||||
|
|
||||||
class SAPlacer
|
class SAPlacer
|
||||||
|
@ -21,8 +21,6 @@
|
|||||||
|
|
||||||
NEXTPNR_NAMESPACE_BEGIN
|
NEXTPNR_NAMESPACE_BEGIN
|
||||||
|
|
||||||
bool legalise_design(Context *ctx) {
|
bool legalise_design(Context *ctx) { return true; }
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
NEXTPNR_NAMESPACE_END
|
NEXTPNR_NAMESPACE_END
|
||||||
|
@ -56,8 +56,8 @@ IdString Arch::belTypeToId(BelType type) const
|
|||||||
return id("SB_LEDDA_IP");
|
return id("SB_LEDDA_IP");
|
||||||
if (type == TYPE_SB_RGBA_DRV)
|
if (type == TYPE_SB_RGBA_DRV)
|
||||||
return id("SB_RGBA_DRV");
|
return id("SB_RGBA_DRV");
|
||||||
if (type == TYPE_SB_SPRAM256KA)
|
if (type == TYPE_ICESTORM_SPRAM)
|
||||||
return id("SB_SPRAM256KA");
|
return id("ICESTORM_SPRAM");
|
||||||
return IdString();
|
return IdString();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -91,8 +91,8 @@ BelType Arch::belTypeFromId(IdString type) const
|
|||||||
return TYPE_SB_LEDDA_IP;
|
return TYPE_SB_LEDDA_IP;
|
||||||
if (type == id("SB_RGBA_DRV"))
|
if (type == id("SB_RGBA_DRV"))
|
||||||
return TYPE_SB_RGBA_DRV;
|
return TYPE_SB_RGBA_DRV;
|
||||||
if (type == id("SB_SPRAM256KA"))
|
if (type == id("ICESTORM_SPRAM"))
|
||||||
return TYPE_SB_SPRAM256KA;
|
return TYPE_ICESTORM_SPRAM;
|
||||||
return TYPE_NONE;
|
return TYPE_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,7 +62,7 @@ enum BelType : int32_t
|
|||||||
TYPE_IO_I3C,
|
TYPE_IO_I3C,
|
||||||
TYPE_SB_LEDDA_IP,
|
TYPE_SB_LEDDA_IP,
|
||||||
TYPE_SB_RGBA_DRV,
|
TYPE_SB_RGBA_DRV,
|
||||||
TYPE_SB_SPRAM256KA,
|
TYPE_ICESTORM_SPRAM,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum PortPin : int32_t
|
enum PortPin : int32_t
|
||||||
|
@ -241,6 +241,29 @@ void write_asc(const Context *ctx, std::ostream &out)
|
|||||||
set_config(ti_ramt, config.at(y + 1).at(x), "RamConfig.CBIT_3", read_mode & 0x2);
|
set_config(ti_ramt, config.at(y + 1).at(x), "RamConfig.CBIT_3", read_mode & 0x2);
|
||||||
} else if (cell.second->type == ctx->id("SB_WARMBOOT") || cell.second->type == ctx->id("ICESTORM_LFOSC")) {
|
} else if (cell.second->type == ctx->id("SB_WARMBOOT") || cell.second->type == ctx->id("ICESTORM_LFOSC")) {
|
||||||
// No config needed
|
// No config needed
|
||||||
|
} else if (cell.second->type == ctx->id("ICESTORM_SPRAM")) {
|
||||||
|
const BelInfoPOD &beli = ci.bel_data[bel.index];
|
||||||
|
int x = beli.x, y = beli.y, z = beli.z;
|
||||||
|
assert(ctx->args.type == ArchArgs::UP5K);
|
||||||
|
if (x == 0 && y == 0) {
|
||||||
|
const TileInfoPOD &ti_ipcon = bi.tiles_nonrouting[TILE_IPCON];
|
||||||
|
if (z == 1) {
|
||||||
|
set_config(ti_ipcon, config.at(1).at(0), "IpConfig.CBIT_0", true);
|
||||||
|
} else if (z == 2) {
|
||||||
|
set_config(ti_ipcon, config.at(1).at(0), "IpConfig.CBIT_1", true);
|
||||||
|
} else {
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
} else if (x == 25 && y == 0) {
|
||||||
|
const TileInfoPOD &ti_ipcon = bi.tiles_nonrouting[TILE_IPCON];
|
||||||
|
if (z == 3) {
|
||||||
|
set_config(ti_ipcon, config.at(1).at(25), "IpConfig.CBIT_0", true);
|
||||||
|
} else if (z == 4) {
|
||||||
|
set_config(ti_ipcon, config.at(1).at(25), "IpConfig.CBIT_1", true);
|
||||||
|
} else {
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
assert(false);
|
assert(false);
|
||||||
}
|
}
|
||||||
|
@ -124,6 +124,24 @@ std::unique_ptr<CellInfo> create_ice_cell(Context *ctx, IdString type, std::stri
|
|||||||
} else if (type == ctx->id("SB_GB")) {
|
} else if (type == ctx->id("SB_GB")) {
|
||||||
add_port(ctx, new_cell.get(), "USER_SIGNAL_TO_GLOBAL_BUFFER", PORT_IN);
|
add_port(ctx, new_cell.get(), "USER_SIGNAL_TO_GLOBAL_BUFFER", PORT_IN);
|
||||||
add_port(ctx, new_cell.get(), "GLOBAL_BUFFER_OUTPUT", PORT_OUT);
|
add_port(ctx, new_cell.get(), "GLOBAL_BUFFER_OUTPUT", PORT_OUT);
|
||||||
|
} else if (type == ctx->id("ICESTORM_SPRAM")) {
|
||||||
|
add_port(ctx, new_cell.get(), "WREN", PORT_IN);
|
||||||
|
add_port(ctx, new_cell.get(), "CHIPSELECT", PORT_IN);
|
||||||
|
add_port(ctx, new_cell.get(), "CLOCK", PORT_IN);
|
||||||
|
add_port(ctx, new_cell.get(), "STANDBY", PORT_IN);
|
||||||
|
add_port(ctx, new_cell.get(), "SLEEP", PORT_IN);
|
||||||
|
add_port(ctx, new_cell.get(), "POWEROFF", PORT_IN);
|
||||||
|
|
||||||
|
for (int i = 0; i < 16; i++) {
|
||||||
|
add_port(ctx, new_cell.get(), "DATAIN_" + std::to_string(i), PORT_IN);
|
||||||
|
add_port(ctx, new_cell.get(), "DATAOUT_" + std::to_string(i), PORT_OUT);
|
||||||
|
}
|
||||||
|
for (int i = 0; i < 14; i++) {
|
||||||
|
add_port(ctx, new_cell.get(), "ADDRESS_" + std::to_string(i), PORT_IN);
|
||||||
|
}
|
||||||
|
for (int i = 0; i < 4; i++) {
|
||||||
|
add_port(ctx, new_cell.get(), "MASKWREN_" + std::to_string(i), PORT_IN);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
log_error("unable to create iCE40 cell of type %s", type.c_str(ctx));
|
log_error("unable to create iCE40 cell of type %s", type.c_str(ctx));
|
||||||
}
|
}
|
||||||
|
@ -67,6 +67,8 @@ inline bool is_sb_lfosc(const BaseCtx *ctx, const CellInfo *cell) { return cell-
|
|||||||
|
|
||||||
inline bool is_sb_hfosc(const BaseCtx *ctx, const CellInfo *cell) { return cell->type == ctx->id("SB_HFOSC"); }
|
inline bool is_sb_hfosc(const BaseCtx *ctx, const CellInfo *cell) { return cell->type == ctx->id("SB_HFOSC"); }
|
||||||
|
|
||||||
|
inline bool is_sb_spram(const BaseCtx *ctx, const CellInfo *cell) { return cell->type == ctx->id("SB_SPRAM256KA"); }
|
||||||
|
|
||||||
// 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
|
||||||
|
@ -528,10 +528,10 @@ static void promote_globals(Context *ctx)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pack internal oscillators
|
// Pack special functions
|
||||||
static void pack_intosc(Context *ctx)
|
static void pack_special(Context *ctx)
|
||||||
{
|
{
|
||||||
log_info("Packing oscillators..\n");
|
log_info("Packing special functions..\n");
|
||||||
|
|
||||||
std::unordered_set<IdString> packed_cells;
|
std::unordered_set<IdString> packed_cells;
|
||||||
std::vector<std::unique_ptr<CellInfo>> new_cells;
|
std::vector<std::unique_ptr<CellInfo>> new_cells;
|
||||||
@ -550,6 +550,20 @@ static void pack_intosc(Context *ctx)
|
|||||||
replace_port(ci, ctx->id("CLKLF"), packed.get(), ctx->id("CLKLF"));
|
replace_port(ci, ctx->id("CLKLF"), packed.get(), ctx->id("CLKLF"));
|
||||||
}
|
}
|
||||||
new_cells.push_back(std::move(packed));
|
new_cells.push_back(std::move(packed));
|
||||||
|
} else if (is_sb_spram(ctx, ci)) {
|
||||||
|
std::unique_ptr<CellInfo> packed =
|
||||||
|
create_ice_cell(ctx, ctx->id("ICESTORM_SPRAM"), ci->name.str(ctx) + "_RAM");
|
||||||
|
packed_cells.insert(ci->name);
|
||||||
|
for (auto port : ci->ports) {
|
||||||
|
PortInfo &pi = port.second;
|
||||||
|
std::string newname = pi.name.str(ctx);
|
||||||
|
size_t bpos = newname.find('[');
|
||||||
|
if (bpos != std::string::npos) {
|
||||||
|
newname = newname.substr(0, bpos) + "_" + newname.substr(bpos + 1, (newname.size() - bpos) - 2);
|
||||||
|
}
|
||||||
|
replace_port(ci, ctx->id(pi.name.c_str(ctx)), packed.get(), ctx->id(newname));
|
||||||
|
}
|
||||||
|
new_cells.push_back(std::move(packed));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -573,7 +587,7 @@ bool pack_design(Context *ctx)
|
|||||||
pack_nonlut_ffs(ctx);
|
pack_nonlut_ffs(ctx);
|
||||||
pack_carries(ctx);
|
pack_carries(ctx);
|
||||||
pack_ram(ctx);
|
pack_ram(ctx);
|
||||||
pack_intosc(ctx);
|
pack_special(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