clangformat
This commit is contained in:
parent
858ff546d8
commit
96b073c001
@ -44,7 +44,7 @@ struct BitstreamJsonBackend
|
|||||||
std::ostream &out;
|
std::ostream &out;
|
||||||
bool first_instance;
|
bool first_instance;
|
||||||
|
|
||||||
BitstreamJsonBackend(Context *ctx, NgUltraImpl *uarch, std::ostream &out) : ctx(ctx), uarch(uarch), out(out){};
|
BitstreamJsonBackend(Context *ctx, NgUltraImpl *uarch, std::ostream &out) : ctx(ctx), uarch(uarch), out(out) {};
|
||||||
|
|
||||||
std::string get_string(std::string str)
|
std::string get_string(std::string str)
|
||||||
{
|
{
|
||||||
@ -59,40 +59,39 @@ struct BitstreamJsonBackend
|
|||||||
|
|
||||||
std::string update_name(std::string tile, std::string name)
|
std::string update_name(std::string tile, std::string name)
|
||||||
{
|
{
|
||||||
if (boost::starts_with(tile,"FENCE[")) {
|
if (boost::starts_with(tile, "FENCE[")) {
|
||||||
char last = tile[tile.size()-2];
|
char last = tile[tile.size() - 2];
|
||||||
switch(last)
|
switch (last) {
|
||||||
{
|
|
||||||
case 'T':
|
case 'T':
|
||||||
case 'B':
|
case 'B':
|
||||||
case 'U':
|
case 'U':
|
||||||
case 'L':
|
case 'L':
|
||||||
std::string loc = tile.substr(tile.find("[")+1, tile.find("x")-tile.find("["));
|
std::string loc = tile.substr(tile.find("[") + 1, tile.find("x") - tile.find("["));
|
||||||
boost::replace_all(name, "1x", loc);
|
boost::replace_all(name, "1x", loc);
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (boost::starts_with(tile,"TILE[") && boost::algorithm::contains(name,".FE")) {
|
if (boost::starts_with(tile, "TILE[") && boost::algorithm::contains(name, ".FE")) {
|
||||||
std::string last = name.substr(name.rfind('.') + 1);
|
std::string last = name.substr(name.rfind('.') + 1);
|
||||||
if (last[0]=='D') {
|
if (last[0] == 'D') {
|
||||||
boost::replace_all(name, ".D", ".");
|
boost::replace_all(name, ".D", ".");
|
||||||
boost::replace_all(name, ".FE", ".DFF");
|
boost::replace_all(name, ".FE", ".DFF");
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
if (last=="L" || last=="R") {
|
if (last == "L" || last == "R") {
|
||||||
boost::replace_all(name, ".FE", ".DFF");
|
boost::replace_all(name, ".FE", ".DFF");
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
if (last=="CK") {
|
if (last == "CK") {
|
||||||
boost::replace_all(name, ".FE", ".DFF");
|
boost::replace_all(name, ".FE", ".DFF");
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
if (last[0]=='L') {
|
if (last[0] == 'L') {
|
||||||
boost::replace_all(name, ".L", ".");
|
boost::replace_all(name, ".L", ".");
|
||||||
boost::replace_all(name, ".FE", ".LUT");
|
boost::replace_all(name, ".FE", ".LUT");
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
if (last[0]=='P') {
|
if (last[0] == 'P') {
|
||||||
boost::replace_all(name, ".PI", ".I");
|
boost::replace_all(name, ".PI", ".I");
|
||||||
boost::replace_all(name, ".FE", ".LUT");
|
boost::replace_all(name, ".FE", ".LUT");
|
||||||
return name;
|
return name;
|
||||||
@ -101,10 +100,13 @@ struct BitstreamJsonBackend
|
|||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
void add_net(std::set<std::string> &nets, std::string src_tile, std::string src_name, std::string dst_tile, std::string dst_name, IdString src_type, IdString dst_type)
|
void add_net(std::set<std::string> &nets, std::string src_tile, std::string src_name, std::string dst_tile,
|
||||||
|
std::string dst_name, IdString src_type, IdString dst_type)
|
||||||
{
|
{
|
||||||
if (src_type.in(ctx->id("LUT_PERMUTATION_WIRE"), ctx->id("MUX_WIRE"), ctx->id("INTERCONNECT_INPUT"))) return;
|
if (src_type.in(ctx->id("LUT_PERMUTATION_WIRE"), ctx->id("MUX_WIRE"), ctx->id("INTERCONNECT_INPUT")))
|
||||||
if (boost::starts_with(src_type.c_str(ctx),"CROSSBAR_") && boost::ends_with(src_type.c_str(ctx),"INPUT_WIRE")) return;
|
return;
|
||||||
|
if (boost::starts_with(src_type.c_str(ctx), "CROSSBAR_") && boost::ends_with(src_type.c_str(ctx), "INPUT_WIRE"))
|
||||||
|
return;
|
||||||
if (dst_type == ctx->id("MUX_WIRE"))
|
if (dst_type == ctx->id("MUX_WIRE"))
|
||||||
dst_name = dst_name.substr(0, dst_name.rfind('.'));
|
dst_name = dst_name.substr(0, dst_name.rfind('.'));
|
||||||
src_name = update_name(src_tile, src_name);
|
src_name = update_name(src_tile, src_name);
|
||||||
@ -125,8 +127,10 @@ struct BitstreamJsonBackend
|
|||||||
bool first_net = true;
|
bool first_net = true;
|
||||||
for (auto &net : ctx->nets) {
|
for (auto &net : ctx->nets) {
|
||||||
NetInfo *ni = net.second.get();
|
NetInfo *ni = net.second.get();
|
||||||
if (ni->wires.empty()) continue;
|
if (ni->wires.empty())
|
||||||
out << (first_net ? "" : ",\n"); first_net = false;
|
continue;
|
||||||
|
out << (first_net ? "" : ",\n");
|
||||||
|
first_net = false;
|
||||||
out << stringf("\t\t%s: [\n", get_string(cleanup_name(ni->name.c_str(ctx))).c_str());
|
out << stringf("\t\t%s: [\n", get_string(cleanup_name(ni->name.c_str(ctx))).c_str());
|
||||||
std::set<std::string> nets;
|
std::set<std::string> nets;
|
||||||
for (auto &w : ni->wires) {
|
for (auto &w : ni->wires) {
|
||||||
@ -139,7 +143,8 @@ struct BitstreamJsonBackend
|
|||||||
IdString src_type = ctx->getWireType(swire);
|
IdString src_type = ctx->getWireType(swire);
|
||||||
|
|
||||||
IdString src_orig = IdString(chip_tile_info(ctx->chip_info, pip.tile).wires[pd.src_wire].name);
|
IdString src_orig = IdString(chip_tile_info(ctx->chip_info, pip.tile).wires[pd.src_wire].name);
|
||||||
IdString src_orig_type = IdString(chip_tile_info(ctx->chip_info, pip.tile).wires[pd.src_wire].wire_type);
|
IdString src_orig_type =
|
||||||
|
IdString(chip_tile_info(ctx->chip_info, pip.tile).wires[pd.src_wire].wire_type);
|
||||||
|
|
||||||
WireId dwire = ctx->getPipDstWire(pip);
|
WireId dwire = ctx->getPipDstWire(pip);
|
||||||
IdString dst = ctx->getWireName(dwire)[1];
|
IdString dst = ctx->getWireName(dwire)[1];
|
||||||
@ -148,25 +153,30 @@ struct BitstreamJsonBackend
|
|||||||
std::string s_tile_name = uarch->tile_name(swire.tile);
|
std::string s_tile_name = uarch->tile_name(swire.tile);
|
||||||
std::string tile_name = uarch->tile_name(pip.tile);
|
std::string tile_name = uarch->tile_name(pip.tile);
|
||||||
|
|
||||||
if (src_orig!=src)
|
if (src_orig != src)
|
||||||
add_net(nets, s_tile_name, src.c_str(ctx), tile_name, src_orig.c_str(ctx), src_type, src_orig_type);
|
add_net(nets, s_tile_name, src.c_str(ctx), tile_name, src_orig.c_str(ctx), src_type,
|
||||||
if (!extra_data.name || (extra_data.type != PipExtra::PIP_EXTRA_BYPASS && extra_data.type != PipExtra::PIP_EXTRA_VIRTUAL && extra_data.type != PipExtra::PIP_EXTRA_MUX))
|
src_orig_type);
|
||||||
add_net(nets, tile_name, src_orig.c_str(ctx), tile_name, dst.c_str(ctx), src_orig_type, dst_type);
|
if (!extra_data.name ||
|
||||||
} else if (ni->wires.size()==1) {
|
(extra_data.type != PipExtra::PIP_EXTRA_BYPASS &&
|
||||||
|
extra_data.type != PipExtra::PIP_EXTRA_VIRTUAL && extra_data.type != PipExtra::PIP_EXTRA_MUX))
|
||||||
|
add_net(nets, tile_name, src_orig.c_str(ctx), tile_name, dst.c_str(ctx), src_orig_type,
|
||||||
|
dst_type);
|
||||||
|
} else if (ni->wires.size() == 1) {
|
||||||
IdString src = ctx->getWireName(w.first)[1];
|
IdString src = ctx->getWireName(w.first)[1];
|
||||||
IdString src_type = ctx->getWireType(w.first);
|
IdString src_type = ctx->getWireType(w.first);
|
||||||
std::string s_tile_name = uarch->tile_name(w.first.tile);
|
std::string s_tile_name = uarch->tile_name(w.first.tile);
|
||||||
for (auto &u : ni->users){
|
for (auto &u : ni->users) {
|
||||||
std::string tile_name = uarch->tile_name(u.cell->bel.tile);
|
std::string tile_name = uarch->tile_name(u.cell->bel.tile);
|
||||||
IdString bel_name = ctx->getBelName(u.cell->bel)[1];
|
IdString bel_name = ctx->getBelName(u.cell->bel)[1];
|
||||||
add_net(nets, s_tile_name, src.c_str(ctx), tile_name, stringf("%s.%s", bel_name.c_str(ctx), u.port.c_str(ctx)), src_type, src_type);
|
add_net(nets, s_tile_name, src.c_str(ctx), tile_name,
|
||||||
|
stringf("%s.%s", bel_name.c_str(ctx), u.port.c_str(ctx)), src_type, src_type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
bool first = true;
|
bool first = true;
|
||||||
for (auto &str : nets) {
|
for (auto &str : nets) {
|
||||||
out << (first ? "" : ",\n");
|
out << (first ? "" : ",\n");
|
||||||
out << stringf("\t\t\t%s",get_string(str).c_str());
|
out << stringf("\t\t\t%s", get_string(str).c_str());
|
||||||
first = false;
|
first = false;
|
||||||
}
|
}
|
||||||
out << "\n\t\t]";
|
out << "\n\t\t]";
|
||||||
@ -206,7 +216,8 @@ struct BitstreamJsonBackend
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename KeyType> std::string extract_bits_or_default(const dict<KeyType, Property> &ct, const KeyType &key, int bits, int def = 0)
|
template <typename KeyType>
|
||||||
|
std::string extract_bits_or_default(const dict<KeyType, Property> &ct, const KeyType &key, int bits, int def = 0)
|
||||||
{
|
{
|
||||||
Property extr = get_or_default(ct, key, Property()).extract(0, bits);
|
Property extr = get_or_default(ct, key, Property()).extract(0, bits);
|
||||||
std::string str = extr.str;
|
std::string str = extr.str;
|
||||||
@ -218,27 +229,30 @@ struct BitstreamJsonBackend
|
|||||||
|
|
||||||
void open_instance(CellInfo *cell, std::string rename = "")
|
void open_instance(CellInfo *cell, std::string rename = "")
|
||||||
{
|
{
|
||||||
out << stringf("%s", first_instance ? "" : ",\n"); first_instance = false;
|
out << stringf("%s", first_instance ? "" : ",\n");
|
||||||
out << stringf("\t\t%s: {\n", get_string(cleanup_name(rename.empty() ? cell->name.c_str(ctx) : rename.c_str())).c_str());
|
first_instance = false;
|
||||||
|
out << stringf("\t\t%s: {\n",
|
||||||
|
get_string(cleanup_name(rename.empty() ? cell->name.c_str(ctx) : rename.c_str())).c_str());
|
||||||
std::string tile_name = uarch->tile_name(cell->bel.tile);
|
std::string tile_name = uarch->tile_name(cell->bel.tile);
|
||||||
IdString idx = ctx->getBelName(cell->bel)[1];
|
IdString idx = ctx->getBelName(cell->bel)[1];
|
||||||
std::string belname = idx.c_str(ctx);
|
std::string belname = idx.c_str(ctx);
|
||||||
config.clear();
|
config.clear();
|
||||||
out << stringf("\t\t\t\"location\": %s,\n",get_string(tile_name + ":" + belname).c_str());
|
out << stringf("\t\t\t\"location\": %s,\n", get_string(tile_name + ":" + belname).c_str());
|
||||||
out << stringf("\t\t\t\"type\": %s",get_string(cell->type.c_str(ctx)).c_str());
|
out << stringf("\t\t\t\"type\": %s", get_string(cell->type.c_str(ctx)).c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
void open_instance_fe(CellInfo *cell, std::string type, std::string replace, std::string postfix = "")
|
void open_instance_fe(CellInfo *cell, std::string type, std::string replace, std::string postfix = "")
|
||||||
{
|
{
|
||||||
out << stringf("%s", first_instance ? "" : ",\n"); first_instance = false;
|
out << stringf("%s", first_instance ? "" : ",\n");
|
||||||
|
first_instance = false;
|
||||||
out << stringf("\t\t%s: {\n", get_string(cleanup_name(cell->name.c_str(ctx)) + postfix).c_str());
|
out << stringf("\t\t%s: {\n", get_string(cleanup_name(cell->name.c_str(ctx)) + postfix).c_str());
|
||||||
std::string tile_name = uarch->tile_name(cell->bel.tile);
|
std::string tile_name = uarch->tile_name(cell->bel.tile);
|
||||||
IdString idx = ctx->getBelName(cell->bel)[1];
|
IdString idx = ctx->getBelName(cell->bel)[1];
|
||||||
std::string belname = idx.c_str(ctx);
|
std::string belname = idx.c_str(ctx);
|
||||||
boost::replace_all(belname, ".FE", replace);
|
boost::replace_all(belname, ".FE", replace);
|
||||||
config.clear();
|
config.clear();
|
||||||
out << stringf("\t\t\t\"location\": %s,\n",get_string(tile_name + ":" + belname).c_str());
|
out << stringf("\t\t\t\"location\": %s,\n", get_string(tile_name + ":" + belname).c_str());
|
||||||
out << stringf("\t\t\t\"type\": %s",get_string(type).c_str());
|
out << stringf("\t\t\t\"type\": %s", get_string(type).c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void add_config(std::string name, int val)
|
inline void add_config(std::string name, int val)
|
||||||
@ -256,20 +270,24 @@ struct BitstreamJsonBackend
|
|||||||
config.push_back(stringf("\t\t\t\t%s:%s", get_string(name).c_str(), get_string(val).c_str()));
|
config.push_back(stringf("\t\t\t\t%s:%s", get_string(name).c_str(), get_string(val).c_str()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void close_instance() {
|
void close_instance()
|
||||||
|
{
|
||||||
bool first = true;
|
bool first = true;
|
||||||
if (!config.empty()) out << ",\n\t\t\t\"config\": {\n";
|
if (!config.empty())
|
||||||
|
out << ",\n\t\t\t\"config\": {\n";
|
||||||
for (auto &str : config) {
|
for (auto &str : config) {
|
||||||
out << (first ? "" : ",\n");
|
out << (first ? "" : ",\n");
|
||||||
out << str.c_str();
|
out << str.c_str();
|
||||||
first = false;
|
first = false;
|
||||||
}
|
}
|
||||||
if (!config.empty()) out << "\n\t\t\t}";
|
if (!config.empty())
|
||||||
|
out << "\n\t\t\t}";
|
||||||
out << "\n\t\t}";
|
out << "\n\t\t}";
|
||||||
config.clear();
|
config.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void write_iop(CellInfo *cell) {
|
void write_iop(CellInfo *cell)
|
||||||
|
{
|
||||||
open_instance(cell, str_or_default(cell->params, id_iobname, ""));
|
open_instance(cell, str_or_default(cell->params, id_iobname, ""));
|
||||||
add_config("location", str_or_default(cell->params, id_location, ""));
|
add_config("location", str_or_default(cell->params, id_location, ""));
|
||||||
add_config("differential", str_or_n_value_lower(cell->params, id_differential, "false"));
|
add_config("differential", str_or_n_value_lower(cell->params, id_differential, "false"));
|
||||||
@ -294,15 +312,16 @@ struct BitstreamJsonBackend
|
|||||||
close_instance();
|
close_instance();
|
||||||
std::string tile_name = uarch->tile_name(cell->bel.tile);
|
std::string tile_name = uarch->tile_name(cell->bel.tile);
|
||||||
std::string bank = tile_name.substr(0, tile_name.rfind(':'));
|
std::string bank = tile_name.substr(0, tile_name.rfind(':'));
|
||||||
if (uarch->bank_voltage.count(bank)==0) {
|
if (uarch->bank_voltage.count(bank) == 0) {
|
||||||
if (bank=="IOB0" || bank=="IOB1" || bank=="IOB6" || bank=="IOB7")
|
if (bank == "IOB0" || bank == "IOB1" || bank == "IOB6" || bank == "IOB7")
|
||||||
uarch->bank_voltage[bank] = "3.3V";
|
uarch->bank_voltage[bank] = "3.3V";
|
||||||
else
|
else
|
||||||
uarch->bank_voltage[bank] = "1.8V";
|
uarch->bank_voltage[bank] = "1.8V";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void write_ddfr(CellInfo *cell) {
|
void write_ddfr(CellInfo *cell)
|
||||||
|
{
|
||||||
open_instance(cell);
|
open_instance(cell);
|
||||||
add_config("dff_load", bool_or_default(cell->params, id_dff_load, false));
|
add_config("dff_load", bool_or_default(cell->params, id_dff_load, false));
|
||||||
add_config("dff_sync", bool_or_default(cell->params, id_dff_sync, false));
|
add_config("dff_sync", bool_or_default(cell->params, id_dff_sync, false));
|
||||||
@ -312,7 +331,8 @@ struct BitstreamJsonBackend
|
|||||||
close_instance();
|
close_instance();
|
||||||
}
|
}
|
||||||
|
|
||||||
void write_dfr(CellInfo *cell) {
|
void write_dfr(CellInfo *cell)
|
||||||
|
{
|
||||||
open_instance(cell);
|
open_instance(cell);
|
||||||
add_config("data_inv", bool_or_default(cell->params, id_data_inv, false));
|
add_config("data_inv", bool_or_default(cell->params, id_data_inv, false));
|
||||||
add_config("dff_edge", bool_or_default(cell->params, id_dff_edge, false));
|
add_config("dff_edge", bool_or_default(cell->params, id_dff_edge, false));
|
||||||
@ -325,7 +345,8 @@ struct BitstreamJsonBackend
|
|||||||
close_instance();
|
close_instance();
|
||||||
}
|
}
|
||||||
|
|
||||||
void write_bfr(CellInfo *cell) {
|
void write_bfr(CellInfo *cell)
|
||||||
|
{
|
||||||
open_instance(cell);
|
open_instance(cell);
|
||||||
add_config("mode", int_or_default(cell->params, id_mode, 2));
|
add_config("mode", int_or_default(cell->params, id_mode, 2));
|
||||||
add_config("iobname", str_or_default(cell->params, id_iobname, ""));
|
add_config("iobname", str_or_default(cell->params, id_iobname, ""));
|
||||||
@ -335,14 +356,16 @@ struct BitstreamJsonBackend
|
|||||||
close_instance();
|
close_instance();
|
||||||
}
|
}
|
||||||
|
|
||||||
void write_cy(CellInfo *cell) {
|
void write_cy(CellInfo *cell)
|
||||||
|
{
|
||||||
open_instance(cell);
|
open_instance(cell);
|
||||||
add_config("add_carry", int_or_default(cell->params, id_add_carry, 0));
|
add_config("add_carry", int_or_default(cell->params, id_add_carry, 0));
|
||||||
add_config("shifter", bool_or_default(cell->params, id_shifter, false));
|
add_config("shifter", bool_or_default(cell->params, id_shifter, false));
|
||||||
close_instance();
|
close_instance();
|
||||||
}
|
}
|
||||||
|
|
||||||
void write_fe(CellInfo *cell) {
|
void write_fe(CellInfo *cell)
|
||||||
|
{
|
||||||
if (bool_or_default(cell->params, id_lut_used)) {
|
if (bool_or_default(cell->params, id_lut_used)) {
|
||||||
open_instance_fe(cell, "LUT", ".LUT");
|
open_instance_fe(cell, "LUT", ".LUT");
|
||||||
add_config("lut_table", extract_bits_or_default(cell->params, id_lut_table, 16));
|
add_config("lut_table", extract_bits_or_default(cell->params, id_lut_table, 16));
|
||||||
@ -351,7 +374,7 @@ struct BitstreamJsonBackend
|
|||||||
if (bool_or_default(cell->params, id_dff_used)) {
|
if (bool_or_default(cell->params, id_dff_used)) {
|
||||||
std::string subtype = str_or_default(cell->params, id_type, "DFF");
|
std::string subtype = str_or_default(cell->params, id_type, "DFF");
|
||||||
open_instance_fe(cell, subtype, ".DFF", "_D");
|
open_instance_fe(cell, subtype, ".DFF", "_D");
|
||||||
if (subtype =="DFF") {
|
if (subtype == "DFF") {
|
||||||
add_config("dff_ctxt", std::to_string(int_or_default(cell->params, id_dff_ctxt, 0)));
|
add_config("dff_ctxt", std::to_string(int_or_default(cell->params, id_dff_ctxt, 0)));
|
||||||
add_config("dff_edge", bool_or_default(cell->params, id_dff_edge, false));
|
add_config("dff_edge", bool_or_default(cell->params, id_dff_edge, false));
|
||||||
add_config("dff_init", bool_or_default(cell->params, id_dff_init, false));
|
add_config("dff_init", bool_or_default(cell->params, id_dff_init, false));
|
||||||
@ -363,19 +386,22 @@ struct BitstreamJsonBackend
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void write_xlut(CellInfo *cell) {
|
void write_xlut(CellInfo *cell)
|
||||||
|
{
|
||||||
open_instance(cell);
|
open_instance(cell);
|
||||||
add_config("lut_table", extract_bits_or_default(cell->params, id_lut_table, 16));
|
add_config("lut_table", extract_bits_or_default(cell->params, id_lut_table, 16));
|
||||||
close_instance();
|
close_instance();
|
||||||
}
|
}
|
||||||
|
|
||||||
void write_iom(CellInfo *cell) {
|
void write_iom(CellInfo *cell)
|
||||||
|
{
|
||||||
open_instance(cell);
|
open_instance(cell);
|
||||||
add_config("pads_path", str_or_default(cell->params, id_pads_path, ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"));
|
add_config("pads_path", str_or_default(cell->params, id_pads_path, ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"));
|
||||||
close_instance();
|
close_instance();
|
||||||
}
|
}
|
||||||
|
|
||||||
void write_gck(CellInfo *cell) {
|
void write_gck(CellInfo *cell)
|
||||||
|
{
|
||||||
open_instance(cell);
|
open_instance(cell);
|
||||||
add_config("inv_in", bool_or_default(cell->params, id_inv_in, false));
|
add_config("inv_in", bool_or_default(cell->params, id_inv_in, false));
|
||||||
add_config("inv_out", bool_or_default(cell->params, id_inv_out, false));
|
add_config("inv_out", bool_or_default(cell->params, id_inv_out, false));
|
||||||
@ -383,7 +409,8 @@ struct BitstreamJsonBackend
|
|||||||
close_instance();
|
close_instance();
|
||||||
}
|
}
|
||||||
|
|
||||||
void write_wfb(CellInfo *cell) {
|
void write_wfb(CellInfo *cell)
|
||||||
|
{
|
||||||
open_instance(cell);
|
open_instance(cell);
|
||||||
add_config("delay_on", bool_or_default(cell->params, id_delay_on, false));
|
add_config("delay_on", bool_or_default(cell->params, id_delay_on, false));
|
||||||
add_config("delay", int_or_default(cell->params, id_delay, 0));
|
add_config("delay", int_or_default(cell->params, id_delay, 0));
|
||||||
@ -391,7 +418,8 @@ struct BitstreamJsonBackend
|
|||||||
close_instance();
|
close_instance();
|
||||||
}
|
}
|
||||||
|
|
||||||
void write_wfg(CellInfo *cell) {
|
void write_wfg(CellInfo *cell)
|
||||||
|
{
|
||||||
open_instance(cell);
|
open_instance(cell);
|
||||||
add_config("mode", int_or_default(cell->params, id_mode, 0));
|
add_config("mode", int_or_default(cell->params, id_mode, 0));
|
||||||
add_config("delay_on", bool_or_default(cell->params, id_delay_on, false));
|
add_config("delay_on", bool_or_default(cell->params, id_delay_on, false));
|
||||||
@ -407,7 +435,8 @@ struct BitstreamJsonBackend
|
|||||||
close_instance();
|
close_instance();
|
||||||
}
|
}
|
||||||
|
|
||||||
void write_pll(CellInfo *cell) {
|
void write_pll(CellInfo *cell)
|
||||||
|
{
|
||||||
open_instance(cell);
|
open_instance(cell);
|
||||||
add_config("clk_outdiv1", extract_bits_or_default(cell->params, id_clk_outdiv1, 3));
|
add_config("clk_outdiv1", extract_bits_or_default(cell->params, id_clk_outdiv1, 3));
|
||||||
add_config("clk_outdiv2", extract_bits_or_default(cell->params, id_clk_outdiv2, 3));
|
add_config("clk_outdiv2", extract_bits_or_default(cell->params, id_clk_outdiv2, 3));
|
||||||
@ -437,15 +466,18 @@ struct BitstreamJsonBackend
|
|||||||
close_instance();
|
close_instance();
|
||||||
}
|
}
|
||||||
|
|
||||||
void write_rfb(CellInfo *cell) {
|
void write_rfb(CellInfo *cell)
|
||||||
|
{
|
||||||
open_instance(cell);
|
open_instance(cell);
|
||||||
std::string context = str_or_default(cell->params, id_mem_ctxt, "");
|
std::string context = str_or_default(cell->params, id_mem_ctxt, "");
|
||||||
if (!context.empty()) add_config("mem_ctxt", context);
|
if (!context.empty())
|
||||||
|
add_config("mem_ctxt", context);
|
||||||
add_config("wck_edge", bool_or_default(cell->params, id_wck_edge, false));
|
add_config("wck_edge", bool_or_default(cell->params, id_wck_edge, false));
|
||||||
close_instance();
|
close_instance();
|
||||||
}
|
}
|
||||||
|
|
||||||
void write_ram(CellInfo *cell) {
|
void write_ram(CellInfo *cell)
|
||||||
|
{
|
||||||
open_instance(cell);
|
open_instance(cell);
|
||||||
add_config("mcka_edge", bool_or_default(cell->params, id_mcka_edge, false));
|
add_config("mcka_edge", bool_or_default(cell->params, id_mcka_edge, false));
|
||||||
add_config("mckb_edge", bool_or_default(cell->params, id_mckb_edge, false));
|
add_config("mckb_edge", bool_or_default(cell->params, id_mckb_edge, false));
|
||||||
@ -454,11 +486,13 @@ struct BitstreamJsonBackend
|
|||||||
add_config("raw_config0", extract_bits_or_default(cell->params, id_raw_config0, 4));
|
add_config("raw_config0", extract_bits_or_default(cell->params, id_raw_config0, 4));
|
||||||
add_config("raw_config1", extract_bits_or_default(cell->params, id_raw_config1, 16));
|
add_config("raw_config1", extract_bits_or_default(cell->params, id_raw_config1, 16));
|
||||||
std::string context = str_or_default(cell->params, id_mem_ctxt, "");
|
std::string context = str_or_default(cell->params, id_mem_ctxt, "");
|
||||||
if (!context.empty()) add_config("mem_ctxt", context);
|
if (!context.empty())
|
||||||
|
add_config("mem_ctxt", context);
|
||||||
close_instance();
|
close_instance();
|
||||||
}
|
}
|
||||||
|
|
||||||
void write_dsp(CellInfo *cell) {
|
void write_dsp(CellInfo *cell)
|
||||||
|
{
|
||||||
open_instance(cell);
|
open_instance(cell);
|
||||||
add_config("raw_config0", extract_bits_or_default(cell->params, id_raw_config0, 27));
|
add_config("raw_config0", extract_bits_or_default(cell->params, id_raw_config0, 27));
|
||||||
add_config("raw_config1", extract_bits_or_default(cell->params, id_raw_config1, 24));
|
add_config("raw_config1", extract_bits_or_default(cell->params, id_raw_config1, 24));
|
||||||
@ -467,7 +501,8 @@ struct BitstreamJsonBackend
|
|||||||
close_instance();
|
close_instance();
|
||||||
}
|
}
|
||||||
|
|
||||||
void write_cdc(CellInfo *cell) {
|
void write_cdc(CellInfo *cell)
|
||||||
|
{
|
||||||
open_instance(cell);
|
open_instance(cell);
|
||||||
if (cell->type.in(id_DDE, id_TDE, id_CDC, id_XCDC)) {
|
if (cell->type.in(id_DDE, id_TDE, id_CDC, id_XCDC)) {
|
||||||
add_config("ck0_edge", bool_or_default(cell->params, id_ck0_edge, false));
|
add_config("ck0_edge", bool_or_default(cell->params, id_ck0_edge, false));
|
||||||
@ -495,7 +530,8 @@ struct BitstreamJsonBackend
|
|||||||
close_instance();
|
close_instance();
|
||||||
}
|
}
|
||||||
|
|
||||||
void write_fifo(CellInfo *cell) {
|
void write_fifo(CellInfo *cell)
|
||||||
|
{
|
||||||
open_instance(cell);
|
open_instance(cell);
|
||||||
add_config("rck_edge", bool_or_default(cell->params, id_rck_edge, false));
|
add_config("rck_edge", bool_or_default(cell->params, id_rck_edge, false));
|
||||||
add_config("wck_edge", bool_or_default(cell->params, id_wck_edge, false));
|
add_config("wck_edge", bool_or_default(cell->params, id_wck_edge, false));
|
||||||
@ -511,13 +547,15 @@ struct BitstreamJsonBackend
|
|||||||
{
|
{
|
||||||
for (auto &net : ctx->nets) {
|
for (auto &net : ctx->nets) {
|
||||||
NetInfo *ni = net.second.get();
|
NetInfo *ni = net.second.get();
|
||||||
if (ni->wires.size()==0) continue;
|
if (ni->wires.size() == 0)
|
||||||
|
continue;
|
||||||
std::vector<std::string> nets;
|
std::vector<std::string> nets;
|
||||||
for (auto &w : ni->wires) {
|
for (auto &w : ni->wires) {
|
||||||
if (w.second.pip != PipId()) {
|
if (w.second.pip != PipId()) {
|
||||||
PipId pip = w.second.pip;
|
PipId pip = w.second.pip;
|
||||||
const auto &extra_data = *uarch->pip_extra_data(w.second.pip);
|
const auto &extra_data = *uarch->pip_extra_data(w.second.pip);
|
||||||
if (!extra_data.name || extra_data.type != PipExtra::PIP_EXTRA_INTERCONNECT) continue;
|
if (!extra_data.name || extra_data.type != PipExtra::PIP_EXTRA_INTERCONNECT)
|
||||||
|
continue;
|
||||||
auto &pd = chip_pip_info(ctx->chip_info, pip);
|
auto &pd = chip_pip_info(ctx->chip_info, pip);
|
||||||
IdString src = IdString(chip_tile_info(ctx->chip_info, pip.tile).wires[pd.src_wire].name);
|
IdString src = IdString(chip_tile_info(ctx->chip_info, pip.tile).wires[pd.src_wire].name);
|
||||||
std::string tile_name = uarch->tile_name(pip.tile);
|
std::string tile_name = uarch->tile_name(pip.tile);
|
||||||
@ -525,15 +563,17 @@ struct BitstreamJsonBackend
|
|||||||
std::string type = "OTC";
|
std::string type = "OTC";
|
||||||
if (src_name.find("UI1x") != std::string::npos)
|
if (src_name.find("UI1x") != std::string::npos)
|
||||||
type = "ITC";
|
type = "ITC";
|
||||||
if (boost::starts_with(src_name,"SO1.")) type = "OTS";
|
if (boost::starts_with(src_name, "SO1."))
|
||||||
if (boost::starts_with(src_name,"SI1.")) type = "ITS";
|
type = "OTS";
|
||||||
|
if (boost::starts_with(src_name, "SI1."))
|
||||||
|
type = "ITS";
|
||||||
src_name = update_name(tile_name, src_name);
|
src_name = update_name(tile_name, src_name);
|
||||||
src_name = src_name.substr(0, src_name.size() - 2);
|
src_name = src_name.substr(0, src_name.size() - 2);
|
||||||
|
|
||||||
std::string name = cleanup_name(std::string(ni->name.c_str(ctx))+ "_" + src_name.substr(4));
|
std::string name = cleanup_name(std::string(ni->name.c_str(ctx)) + "_" + src_name.substr(4));
|
||||||
out << stringf(",\n\t\t%s: {\n", get_string(name).c_str());
|
out << stringf(",\n\t\t%s: {\n", get_string(name).c_str());
|
||||||
out << stringf("\t\t\t\"location\": %s,\n",get_string(tile_name + ":" + src_name).c_str());
|
out << stringf("\t\t\t\"location\": %s,\n", get_string(tile_name + ":" + src_name).c_str());
|
||||||
out << stringf("\t\t\t\"type\": %s\n\t\t}",get_string(type).c_str());
|
out << stringf("\t\t\t\"type\": %s\n\t\t}", get_string(type).c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -545,46 +585,81 @@ struct BitstreamJsonBackend
|
|||||||
first_instance = true;
|
first_instance = true;
|
||||||
for (auto &cell : ctx->cells) {
|
for (auto &cell : ctx->cells) {
|
||||||
switch (cell.second->type.index) {
|
switch (cell.second->type.index) {
|
||||||
case id_BEYOND_FE.index: write_fe(cell.second.get()); break;
|
case id_BEYOND_FE.index:
|
||||||
|
write_fe(cell.second.get());
|
||||||
|
break;
|
||||||
case id_IOP.index:
|
case id_IOP.index:
|
||||||
case id_IP.index:
|
case id_IP.index:
|
||||||
case id_OP.index:
|
case id_OP.index:
|
||||||
case id_IOTP.index:
|
case id_IOTP.index:
|
||||||
case id_ITP.index:
|
case id_ITP.index:
|
||||||
case id_OTP.index: write_iop(cell.second.get()); break;
|
case id_OTP.index:
|
||||||
case id_CY.index: write_cy(cell.second.get()); break;
|
write_iop(cell.second.get());
|
||||||
case id_WFB.index: write_wfb(cell.second.get()); break;
|
break;
|
||||||
case id_WFG.index: write_wfg(cell.second.get()); break;
|
case id_CY.index:
|
||||||
case id_GCK.index: write_gck(cell.second.get()); break;
|
write_cy(cell.second.get());
|
||||||
case id_IOM.index: write_iom(cell.second.get()); break;
|
break;
|
||||||
case id_BFR.index: write_bfr(cell.second.get()); break;
|
case id_WFB.index:
|
||||||
case id_DDFR.index: write_ddfr(cell.second.get()); break;
|
write_wfb(cell.second.get());
|
||||||
case id_DFR.index: write_dfr(cell.second.get()); break;
|
break;
|
||||||
case id_RAM.index: write_ram(cell.second.get()); break;
|
case id_WFG.index:
|
||||||
|
write_wfg(cell.second.get());
|
||||||
|
break;
|
||||||
|
case id_GCK.index:
|
||||||
|
write_gck(cell.second.get());
|
||||||
|
break;
|
||||||
|
case id_IOM.index:
|
||||||
|
write_iom(cell.second.get());
|
||||||
|
break;
|
||||||
|
case id_BFR.index:
|
||||||
|
write_bfr(cell.second.get());
|
||||||
|
break;
|
||||||
|
case id_DDFR.index:
|
||||||
|
write_ddfr(cell.second.get());
|
||||||
|
break;
|
||||||
|
case id_DFR.index:
|
||||||
|
write_dfr(cell.second.get());
|
||||||
|
break;
|
||||||
|
case id_RAM.index:
|
||||||
|
write_ram(cell.second.get());
|
||||||
|
break;
|
||||||
case id_RF.index:
|
case id_RF.index:
|
||||||
case id_RFSP.index:
|
case id_RFSP.index:
|
||||||
case id_XHRF.index:
|
case id_XHRF.index:
|
||||||
case id_XWRF.index:
|
case id_XWRF.index:
|
||||||
case id_XPRF.index: write_rfb(cell.second.get()); break;
|
case id_XPRF.index:
|
||||||
case id_XLUT.index: write_xlut(cell.second.get()); break;
|
write_rfb(cell.second.get());
|
||||||
|
break;
|
||||||
|
case id_XLUT.index:
|
||||||
|
write_xlut(cell.second.get());
|
||||||
|
break;
|
||||||
case id_FIFO.index: // mode 0
|
case id_FIFO.index: // mode 0
|
||||||
case id_XHFIFO.index: // mode 1
|
case id_XHFIFO.index: // mode 1
|
||||||
case id_XWFIFO.index: write_fifo(cell.second.get()); break; // mode 2
|
case id_XWFIFO.index:
|
||||||
|
write_fifo(cell.second.get());
|
||||||
|
break; // mode 2
|
||||||
case id_DDE.index: // mode 0
|
case id_DDE.index: // mode 0
|
||||||
case id_TDE.index: // mode 1
|
case id_TDE.index: // mode 1
|
||||||
case id_CDC.index: // mode 2
|
case id_CDC.index: // mode 2
|
||||||
case id_BGC.index: // mode 3
|
case id_BGC.index: // mode 3
|
||||||
case id_GBC.index: // mode 4
|
case id_GBC.index: // mode 4
|
||||||
case id_XCDC.index: write_cdc(cell.second.get()); break; // mode 5
|
case id_XCDC.index:
|
||||||
case id_DSP.index: write_dsp(cell.second.get()); break;
|
write_cdc(cell.second.get());
|
||||||
case id_PLL.index: write_pll(cell.second.get()); break;
|
break; // mode 5
|
||||||
//case id_CRX.index:
|
case id_DSP.index:
|
||||||
//case id_CTX.index:
|
write_dsp(cell.second.get());
|
||||||
//case id_PMA.index:
|
break;
|
||||||
//case id_Service.index:
|
case id_PLL.index:
|
||||||
//case id_SOCIF.index:
|
write_pll(cell.second.get());
|
||||||
|
break;
|
||||||
|
// case id_CRX.index:
|
||||||
|
// case id_CTX.index:
|
||||||
|
// case id_PMA.index:
|
||||||
|
// case id_Service.index:
|
||||||
|
// case id_SOCIF.index:
|
||||||
default:
|
default:
|
||||||
log_error("Unhandled cell %s of type %s\n", cell.second.get()->name.c_str(ctx), cell.second->type.c_str(ctx));
|
log_error("Unhandled cell %s of type %s\n", cell.second.get()->name.c_str(ctx),
|
||||||
|
cell.second->type.c_str(ctx));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
write_interconnections();
|
write_interconnections();
|
||||||
@ -599,7 +674,7 @@ struct BitstreamJsonBackend
|
|||||||
bool first = true;
|
bool first = true;
|
||||||
for (auto &bank : uarch->bank_voltage) {
|
for (auto &bank : uarch->bank_voltage) {
|
||||||
out << (first ? "" : ",\n");
|
out << (first ? "" : ",\n");
|
||||||
out << stringf("\t\t\t%s:%s",get_string(bank.first).c_str(),get_string(bank.second).c_str());
|
out << stringf("\t\t\t%s:%s", get_string(bank.first).c_str(), get_string(bank.second).c_str());
|
||||||
first = false;
|
first = false;
|
||||||
}
|
}
|
||||||
out << "\n\t\t}\n\t}\n";
|
out << "\n\t\t}\n\t}\n";
|
||||||
|
@ -82,14 +82,13 @@ void NgUltraImpl::parse_csv(const std::string &filename)
|
|||||||
boost::split(arguments, line, boost::is_any_of(","));
|
boost::split(arguments, line, boost::is_any_of(","));
|
||||||
if (arguments.empty())
|
if (arguments.empty())
|
||||||
continue;
|
continue;
|
||||||
switch(line_type) {
|
switch (line_type) {
|
||||||
case IO_PADS:
|
case IO_PADS: {
|
||||||
{
|
if (arguments.size() == 1 && arguments[0][0] == '!') {
|
||||||
if (arguments.size()==1 && arguments[0][0]=='!') {
|
|
||||||
line_type = IO_BANKS;
|
line_type = IO_BANKS;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (arguments.size()!=15)
|
if (arguments.size() != 15)
|
||||||
log_error("number of parameters in line %d must be 15\n", lineno);
|
log_error("number of parameters in line %d must be 15\n", lineno);
|
||||||
|
|
||||||
std::string arg_iobname = arguments.at(0);
|
std::string arg_iobname = arguments.at(0);
|
||||||
@ -109,8 +108,8 @@ void NgUltraImpl::parse_csv(const std::string &filename)
|
|||||||
std::string arg_registered = arguments.at(14);
|
std::string arg_registered = arguments.at(14);
|
||||||
|
|
||||||
// TODO: Remove this block
|
// TODO: Remove this block
|
||||||
const std::vector<std::string> weak_values_check = { "None", "PullDown", "PullUp", "Keeper" };
|
const std::vector<std::string> weak_values_check = {"None", "PullDown", "PullUp", "Keeper"};
|
||||||
auto it2 = std::find(std::begin(weak_values_check),std::end(weak_values_check), arguments.at(4));
|
auto it2 = std::find(std::begin(weak_values_check), std::end(weak_values_check), arguments.at(4));
|
||||||
if (it2 != std::end(weak_values_check)) {
|
if (it2 != std::end(weak_values_check)) {
|
||||||
if (!old_format) {
|
if (!old_format) {
|
||||||
log_warning("Old CSV format detected. Please update file.\n");
|
log_warning("Old CSV format detected. Please update file.\n");
|
||||||
@ -125,21 +124,23 @@ void NgUltraImpl::parse_csv(const std::string &filename)
|
|||||||
}
|
}
|
||||||
// End of block
|
// End of block
|
||||||
|
|
||||||
if (!(boost::starts_with(arg_location, "IOB") && boost::contains(arg_location,"_D")))
|
if (!(boost::starts_with(arg_location, "IOB") && boost::contains(arg_location, "_D")))
|
||||||
log_error("invalid location name '%s' must start with 'IOB' in line %d\n", arg_location.c_str(), lineno);
|
log_error("invalid location name '%s' must start with 'IOB' in line %d\n", arg_location.c_str(),
|
||||||
|
lineno);
|
||||||
|
|
||||||
const std::vector<std::string> standard_values = { "LVDS", "LVCMOS", "SSTL", "HSTL" }; // , "POD"
|
const std::vector<std::string> standard_values = {"LVDS", "LVCMOS", "SSTL", "HSTL"}; // , "POD"
|
||||||
auto it = std::find(std::begin(standard_values),std::end(standard_values), arg_standard);
|
auto it = std::find(std::begin(standard_values), std::end(standard_values), arg_standard);
|
||||||
if (it == std::end(standard_values))
|
if (it == std::end(standard_values))
|
||||||
log_error("unknown standard value '%s' in line %d\n", arg_standard.c_str(), lineno);
|
log_error("unknown standard value '%s' in line %d\n", arg_standard.c_str(), lineno);
|
||||||
|
|
||||||
const std::vector<std::string> drive_values = { "2mA", "4mA", "8mA", "16mA", "CatI", "CatII", "Undefined" }; // "6mA", "12mA",
|
const std::vector<std::string> drive_values = {"2mA", "4mA", "8mA", "16mA",
|
||||||
it = std::find(std::begin(drive_values),std::end(drive_values), arg_drive);
|
"CatI", "CatII", "Undefined"}; // "6mA", "12mA",
|
||||||
|
it = std::find(std::begin(drive_values), std::end(drive_values), arg_drive);
|
||||||
if (it == std::end(drive_values))
|
if (it == std::end(drive_values))
|
||||||
log_error("unknown drive value '%s' in line %d\n", arg_drive.c_str(), lineno);
|
log_error("unknown drive value '%s' in line %d\n", arg_drive.c_str(), lineno);
|
||||||
|
|
||||||
const std::vector<std::string> slew_values = { "Slow", "Medium", "Fast" };
|
const std::vector<std::string> slew_values = {"Slow", "Medium", "Fast"};
|
||||||
it = std::find(std::begin(slew_values),std::end(slew_values), arg_slewRate);
|
it = std::find(std::begin(slew_values), std::end(slew_values), arg_slewRate);
|
||||||
if (it == std::end(slew_values))
|
if (it == std::end(slew_values))
|
||||||
log_error("unknown weak termination value '%s' in line %d\n", arg_slewRate.c_str(), lineno);
|
log_error("unknown weak termination value '%s' in line %d\n", arg_slewRate.c_str(), lineno);
|
||||||
|
|
||||||
@ -147,39 +148,41 @@ void NgUltraImpl::parse_csv(const std::string &filename)
|
|||||||
log_error("input delay must be number, value '%s' in line %d\n", arg_inputDelayLine.c_str(), lineno);
|
log_error("input delay must be number, value '%s' in line %d\n", arg_inputDelayLine.c_str(), lineno);
|
||||||
} else {
|
} else {
|
||||||
int delay = std::stoi(arg_inputDelayLine);
|
int delay = std::stoi(arg_inputDelayLine);
|
||||||
if (delay<0 || delay >63)
|
if (delay < 0 || delay > 63)
|
||||||
log_error("input delay value must be in range from 0 to 63 in line %d\n", lineno);
|
log_error("input delay value must be in range from 0 to 63 in line %d\n", lineno);
|
||||||
}
|
}
|
||||||
if (!is_number(arg_outputDelayLine)) {
|
if (!is_number(arg_outputDelayLine)) {
|
||||||
log_error("output delay must be number, value '%s' in line %d\n", arg_outputDelayLine.c_str(), lineno);
|
log_error("output delay must be number, value '%s' in line %d\n", arg_outputDelayLine.c_str(), lineno);
|
||||||
} else {
|
} else {
|
||||||
int delay = std::stoi(arg_outputDelayLine);
|
int delay = std::stoi(arg_outputDelayLine);
|
||||||
if (delay<0 || delay >63)
|
if (delay < 0 || delay > 63)
|
||||||
log_error("output delay value must be in range from 0 to 63 in line %d\n", lineno);
|
log_error("output delay value must be in range from 0 to 63 in line %d\n", lineno);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!arg_differential.empty() && arg_differential != "True" && arg_differential != "False")
|
if (!arg_differential.empty() && arg_differential != "True" && arg_differential != "False")
|
||||||
log_error("differential must be boolean, value '%s' in line %d\n", arg_differential.c_str(), lineno);
|
log_error("differential must be boolean, value '%s' in line %d\n", arg_differential.c_str(), lineno);
|
||||||
|
|
||||||
const std::vector<std::string> weak_values = { "None", "PullDown", "PullUp", "Keeper" };
|
const std::vector<std::string> weak_values = {"None", "PullDown", "PullUp", "Keeper"};
|
||||||
it = std::find(std::begin(weak_values),std::end(weak_values), arg_weakTermination);
|
it = std::find(std::begin(weak_values), std::end(weak_values), arg_weakTermination);
|
||||||
if (it == std::end(weak_values))
|
if (it == std::end(weak_values))
|
||||||
log_error("unknown weak termination value '%s' in line %d\n", arg_weakTermination.c_str(), lineno);
|
log_error("unknown weak termination value '%s' in line %d\n", arg_weakTermination.c_str(), lineno);
|
||||||
|
|
||||||
if (!arg_termination.empty()) {
|
if (!arg_termination.empty()) {
|
||||||
if (!is_number(arg_termination)) {
|
if (!is_number(arg_termination)) {
|
||||||
log_error("termination must be string containing int, value '%s' in line %d\n", arg_termination.c_str(), lineno);
|
log_error("termination must be string containing int, value '%s' in line %d\n",
|
||||||
|
arg_termination.c_str(), lineno);
|
||||||
} else {
|
} else {
|
||||||
int termination = std::stoi(arg_termination);
|
int termination = std::stoi(arg_termination);
|
||||||
if (termination<30 || termination >80)
|
if (termination < 30 || termination > 80)
|
||||||
log_error("termination value must be in range from 30 to 80 in line %d\n", lineno);
|
log_error("termination value must be in range from 30 to 80 in line %d\n", lineno);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::vector<std::string> termref_values = { "Floating", "VT" };
|
const std::vector<std::string> termref_values = {"Floating", "VT"};
|
||||||
it = std::find(std::begin(termref_values),std::end(termref_values), arg_terminationReference);
|
it = std::find(std::begin(termref_values), std::end(termref_values), arg_terminationReference);
|
||||||
if (it == std::end(termref_values))
|
if (it == std::end(termref_values))
|
||||||
log_error("unknown termination reference value '%s' in line %d\n", arg_terminationReference.c_str(), lineno);
|
log_error("unknown termination reference value '%s' in line %d\n", arg_terminationReference.c_str(),
|
||||||
|
lineno);
|
||||||
|
|
||||||
if (!arg_turbo.empty() && arg_turbo != "True" && arg_turbo != "False")
|
if (!arg_turbo.empty() && arg_turbo != "True" && arg_turbo != "False")
|
||||||
log_error("turbo must be boolean, value '%s' in line %d\n", arg_turbo.c_str(), lineno);
|
log_error("turbo must be boolean, value '%s' in line %d\n", arg_turbo.c_str(), lineno);
|
||||||
@ -187,24 +190,28 @@ void NgUltraImpl::parse_csv(const std::string &filename)
|
|||||||
if (!arg_inputSignalSlope.empty() && !is_number(arg_inputSignalSlope))
|
if (!arg_inputSignalSlope.empty() && !is_number(arg_inputSignalSlope))
|
||||||
log_error("signal slope must be number, value '%s' in line %d\n", arg_inputSignalSlope.c_str(), lineno);
|
log_error("signal slope must be number, value '%s' in line %d\n", arg_inputSignalSlope.c_str(), lineno);
|
||||||
if (!arg_outputCapacity.empty() && !is_number(arg_outputCapacity))
|
if (!arg_outputCapacity.empty() && !is_number(arg_outputCapacity))
|
||||||
log_error("output capacity must be number, value '%s' in line %d\n", arg_outputCapacity.c_str(), lineno);
|
log_error("output capacity must be number, value '%s' in line %d\n", arg_outputCapacity.c_str(),
|
||||||
|
lineno);
|
||||||
|
|
||||||
const std::vector<std::string> registered_values = { "Auto", "I", "IC", "O", "OC", "IO", "IOC" };
|
const std::vector<std::string> registered_values = {"Auto", "I", "IC", "O", "OC", "IO", "IOC"};
|
||||||
it = std::find(std::begin(registered_values),std::end(registered_values), arg_registered);
|
it = std::find(std::begin(registered_values), std::end(registered_values), arg_registered);
|
||||||
if (it == std::end(registered_values))
|
if (it == std::end(registered_values))
|
||||||
log_error("unknown registered value '%s' in line %d\n", arg_registered.c_str(), lineno);
|
log_error("unknown registered value '%s' in line %d\n", arg_registered.c_str(), lineno);
|
||||||
|
|
||||||
if (arg_standard=="LVDS" && arg_drive!="Undefined")
|
if (arg_standard == "LVDS" && arg_drive != "Undefined")
|
||||||
log_error("for port in line %d when standard is 'LVDS' drive must be 'Undefined'\n", lineno);
|
log_error("for port in line %d when standard is 'LVDS' drive must be 'Undefined'\n", lineno);
|
||||||
if (arg_standard=="LVCMOS" && !boost::ends_with(arg_drive,"mA"))
|
if (arg_standard == "LVCMOS" && !boost::ends_with(arg_drive, "mA"))
|
||||||
log_error("for port in line %d when standard is 'LVCMOS' drive current must be in mA\n", lineno);
|
log_error("for port in line %d when standard is 'LVCMOS' drive current must be in mA\n", lineno);
|
||||||
if ((arg_standard=="SSTL" || arg_standard=="HSTL") && !boost::starts_with(arg_drive,"Cat"))
|
if ((arg_standard == "SSTL" || arg_standard == "HSTL") && !boost::starts_with(arg_drive, "Cat"))
|
||||||
log_error("for port in line %d when standard is 'SSTL' or 'HSTL' drive current must be in 'CatI' or 'CatII'\n", lineno);
|
log_error("for port in line %d when standard is 'SSTL' or 'HSTL' drive current must be in 'CatI' or "
|
||||||
|
"'CatII'\n",
|
||||||
|
lineno);
|
||||||
|
|
||||||
|
if (arg_terminationReference == "Floating") {
|
||||||
if (arg_terminationReference=="Floating") {
|
|
||||||
if (!(arg_differential == "True" && arg_weakTermination == "None")) {
|
if (!(arg_differential == "True" && arg_weakTermination == "None")) {
|
||||||
log_error("for floating termination, differential myst be 'True' and weakTermination must be 'None' in line %d\n", lineno);
|
log_error("for floating termination, differential myst be 'True' and weakTermination must be "
|
||||||
|
"'None' in line %d\n",
|
||||||
|
lineno);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
std::vector<CellInfo *> dest = get_cells(arg_iobname);
|
std::vector<CellInfo *> dest = get_cells(arg_iobname);
|
||||||
@ -216,8 +223,8 @@ void NgUltraImpl::parse_csv(const std::string &filename)
|
|||||||
c->params[id_slewRate] = arg_slewRate;
|
c->params[id_slewRate] = arg_slewRate;
|
||||||
c->params[id_inputDelayLine] = arg_inputDelayLine;
|
c->params[id_inputDelayLine] = arg_inputDelayLine;
|
||||||
c->params[id_outputDelayLine] = arg_outputDelayLine;
|
c->params[id_outputDelayLine] = arg_outputDelayLine;
|
||||||
c->params[id_inputDelayOn] = std::string((std::stoi(arg_inputDelayLine)!=0) ? "True" : "False");
|
c->params[id_inputDelayOn] = std::string((std::stoi(arg_inputDelayLine) != 0) ? "True" : "False");
|
||||||
c->params[id_outputDelayOn] = std::string((std::stoi(arg_outputDelayLine)!=0) ? "True" : "False");
|
c->params[id_outputDelayOn] = std::string((std::stoi(arg_outputDelayLine) != 0) ? "True" : "False");
|
||||||
c->params[id_differential] = arg_differential;
|
c->params[id_differential] = arg_differential;
|
||||||
c->params[id_weakTermination] = arg_weakTermination;
|
c->params[id_weakTermination] = arg_weakTermination;
|
||||||
if (!arg_termination.empty()) {
|
if (!arg_termination.empty()) {
|
||||||
@ -229,70 +236,65 @@ void NgUltraImpl::parse_csv(const std::string &filename)
|
|||||||
c->params[id_outputCapacity] = arg_outputCapacity;
|
c->params[id_outputCapacity] = arg_outputCapacity;
|
||||||
c->params[id_registered] = arg_registered;
|
c->params[id_registered] = arg_registered;
|
||||||
}
|
}
|
||||||
if (dest.size()==0)
|
if (dest.size() == 0)
|
||||||
log_warning("Pad with name '%s' not found in netlist.\n", arg_iobname.c_str());
|
log_warning("Pad with name '%s' not found in netlist.\n", arg_iobname.c_str());
|
||||||
|
|
||||||
std::string bank_name = arg_location.substr(0,arg_location.find_first_of('_'));
|
std::string bank_name = arg_location.substr(0, arg_location.find_first_of('_'));
|
||||||
banks_used.emplace(bank_name);
|
banks_used.emplace(bank_name);
|
||||||
}
|
} break;
|
||||||
break;
|
case IO_BANKS: {
|
||||||
case IO_BANKS:
|
if (arguments.size() == 1 && arguments[0][0] == '!') {
|
||||||
{
|
|
||||||
if (arguments.size()==1 && arguments[0][0]=='!') {
|
|
||||||
line_type = IO_GCKS;
|
line_type = IO_GCKS;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (arguments.size()!=3)
|
if (arguments.size() != 3)
|
||||||
log_error("number of parameters in line %d must be 3\n", lineno);
|
log_error("number of parameters in line %d must be 3\n", lineno);
|
||||||
|
|
||||||
if (!boost::starts_with(arguments.at(0), "IOB"))
|
if (!boost::starts_with(arguments.at(0), "IOB"))
|
||||||
log_error("wrong bank name '%s' in line %d\n", arguments.at(0).c_str(), lineno);
|
log_error("wrong bank name '%s' in line %d\n", arguments.at(0).c_str(), lineno);
|
||||||
|
|
||||||
const char* voltages[] = { "1.2V", "1.5V", "1.8V", "2.5V", "3.3V" };
|
const char *voltages[] = {"1.2V", "1.5V", "1.8V", "2.5V", "3.3V"};
|
||||||
auto it = std::find(std::begin(voltages),std::end(voltages), arguments.at(1));
|
auto it = std::find(std::begin(voltages), std::end(voltages), arguments.at(1));
|
||||||
if (it == std::end(voltages))
|
if (it == std::end(voltages))
|
||||||
log_error("unknown voltage level '%s' in line %d\n", arguments.at(1).c_str(), lineno);
|
log_error("unknown voltage level '%s' in line %d\n", arguments.at(1).c_str(), lineno);
|
||||||
|
|
||||||
const char * direct_io_voltages[] = { "1.8V", "2.5V", "3.3V" };
|
const char *direct_io_voltages[] = {"1.8V", "2.5V", "3.3V"};
|
||||||
const char * complex_io_voltages[] = { "1.2V", "1.5V", "1.8V" };
|
const char *complex_io_voltages[] = {"1.2V", "1.5V", "1.8V"};
|
||||||
|
|
||||||
int bank = std::stoi(arguments.at(0).substr(3));
|
int bank = std::stoi(arguments.at(0).substr(3));
|
||||||
switch(bank) {
|
switch (bank) {
|
||||||
// direct
|
// direct
|
||||||
case 0:
|
case 0:
|
||||||
case 1:
|
case 1:
|
||||||
case 6:
|
case 6:
|
||||||
case 7:
|
case 7: {
|
||||||
{
|
auto it = std::find(std::begin(direct_io_voltages), std::end(direct_io_voltages), arguments.at(1));
|
||||||
auto it = std::find(std::begin(direct_io_voltages),std::end(direct_io_voltages), arguments.at(1));
|
|
||||||
if (it == std::end(direct_io_voltages))
|
if (it == std::end(direct_io_voltages))
|
||||||
log_error("unsupported voltage level '%s' for bank '%s'\n", arguments.at(1).c_str(), arguments.at(0).c_str());
|
log_error("unsupported voltage level '%s' for bank '%s'\n", arguments.at(1).c_str(),
|
||||||
}
|
arguments.at(0).c_str());
|
||||||
break;
|
} break;
|
||||||
// complex
|
// complex
|
||||||
default:
|
default:
|
||||||
auto it = std::find(std::begin(complex_io_voltages),std::end(complex_io_voltages), arguments.at(1));
|
auto it = std::find(std::begin(complex_io_voltages), std::end(complex_io_voltages), arguments.at(1));
|
||||||
if (it == std::end(complex_io_voltages))
|
if (it == std::end(complex_io_voltages))
|
||||||
log_error("unsupported voltage level '%s' for bank '%s'\n", arguments.at(1).c_str(), arguments.at(0).c_str());
|
log_error("unsupported voltage level '%s' for bank '%s'\n", arguments.at(1).c_str(),
|
||||||
|
arguments.at(0).c_str());
|
||||||
}
|
}
|
||||||
bank_voltage[arguments.at(0)] = arguments.at(1);
|
bank_voltage[arguments.at(0)] = arguments.at(1);
|
||||||
}
|
} break;
|
||||||
break;
|
case IO_GCKS: {
|
||||||
case IO_GCKS:
|
if (arguments.size() == 1 && arguments[0][0] == '!') {
|
||||||
{
|
|
||||||
if (arguments.size()==1 && arguments[0][0]=='!') {
|
|
||||||
line_type = IO_ERROR;
|
line_type = IO_ERROR;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (arguments.size()!=2)
|
if (arguments.size() != 2)
|
||||||
log_error("number of parameters in line %d must be 2\n", lineno);
|
log_error("number of parameters in line %d must be 2\n", lineno);
|
||||||
}
|
} break;
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
log_error("switching to unknown block of data in line %d\n", lineno);
|
log_error("switching to unknown block of data in line %d\n", lineno);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for(auto& bank_name : banks_used) {
|
for (auto &bank_name : banks_used) {
|
||||||
if (bank_voltage.count(bank_name) == 0) {
|
if (bank_voltage.count(bank_name) == 0) {
|
||||||
log_error("IO for bank '%s' defined, but no bank configuration.\n", bank_name.c_str());
|
log_error("IO for bank '%s' defined, but no bank configuration.\n", bank_name.c_str());
|
||||||
}
|
}
|
||||||
|
@ -40,8 +40,15 @@ NPNR_PACKED_STRUCT(struct NGUltraPipExtraDataPOD {
|
|||||||
|
|
||||||
NPNR_PACKED_STRUCT(struct NGUltraBelExtraDataPOD { int32_t flags; });
|
NPNR_PACKED_STRUCT(struct NGUltraBelExtraDataPOD { int32_t flags; });
|
||||||
|
|
||||||
struct GckConfig {
|
struct GckConfig
|
||||||
explicit GckConfig(BelId belid) { bel = belid; si1 = IdString(); si2 = IdString(); used = false; }
|
{
|
||||||
|
explicit GckConfig(BelId belid)
|
||||||
|
{
|
||||||
|
bel = belid;
|
||||||
|
si1 = IdString();
|
||||||
|
si2 = IdString();
|
||||||
|
used = false;
|
||||||
|
}
|
||||||
BelId bel;
|
BelId bel;
|
||||||
IdString si1;
|
IdString si1;
|
||||||
IdString si2;
|
IdString si2;
|
||||||
|
@ -24,17 +24,17 @@ NEXTPNR_NAMESPACE_BEGIN
|
|||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
const Loc ng_ultra_place_cy_map[24] = {
|
const Loc ng_ultra_place_cy_map[24] = {
|
||||||
{ 0, 1, 0 }, // S1 0 -> S2 0 CY24->CY1
|
{0, 1, 0}, // S1 0 -> S2 0 CY24->CY1
|
||||||
{ 0, 0, -1 }, // S1 1 -> S1 0 CY23->CY24
|
{0, 0, -1}, // S1 1 -> S1 0 CY23->CY24
|
||||||
{ 0, 0, -1 }, // S1 2 -> S1 1 CY22->CY23
|
{0, 0, -1}, // S1 2 -> S1 1 CY22->CY23
|
||||||
{ 0, 0, -1 }, // S1 3 -> S1 2 CY21->CY22
|
{0, 0, -1}, // S1 3 -> S1 2 CY21->CY22
|
||||||
|
|
||||||
{-1, 0,+3}, // S5 0 -> S1 1 CY20->CY21
|
{-1, 0, +3}, // S5 0 -> S1 1 CY20->CY21
|
||||||
{0, 0, -1}, // S5 1 -> S5 0 CY19->CY20
|
{0, 0, -1}, // S5 1 -> S5 0 CY19->CY20
|
||||||
{0, 0, -1}, // S5 2 -> S5 1 CY18->CY19
|
{0, 0, -1}, // S5 2 -> S5 1 CY18->CY19
|
||||||
{0, 0, -1}, // S5 3 -> S5 2 CY17->CY18
|
{0, 0, -1}, // S5 3 -> S5 2 CY17->CY18
|
||||||
|
|
||||||
{-1, 0,+3}, // S9 0 -> S5 1 CY16->CY17
|
{-1, 0, +3}, // S9 0 -> S5 1 CY16->CY17
|
||||||
{0, 0, -1}, // S9 1 -> S9 0 CY15->CY16
|
{0, 0, -1}, // S9 1 -> S9 0 CY15->CY16
|
||||||
{0, 0, -1}, // S9 2 -> S9 1 CY14->CY15
|
{0, 0, -1}, // S9 2 -> S9 1 CY14->CY15
|
||||||
{0, 0, -1}, // S9 3 -> S9 2 CY13->CY14
|
{0, 0, -1}, // S9 3 -> S9 2 CY13->CY14
|
||||||
@ -52,226 +52,221 @@ const Loc ng_ultra_place_cy_map[24] = {
|
|||||||
{0, 0, +1}, // S10 0 -> S10 1 CY9->CY10
|
{0, 0, +1}, // S10 0 -> S10 1 CY9->CY10
|
||||||
{0, 0, +1}, // S10 1 -> S10 2 CY10->CY11
|
{0, 0, +1}, // S10 1 -> S10 2 CY10->CY11
|
||||||
{0, 0, +1}, // S10 2 -> S10 3 CY11->CY12
|
{0, 0, +1}, // S10 2 -> S10 3 CY11->CY12
|
||||||
{0,-1, 0}, // S10 3 -> S9 3 CY12->CY13
|
{0, -1, 0}, // S10 3 -> S9 3 CY12->CY13
|
||||||
};
|
};
|
||||||
|
|
||||||
const Loc ng_ultra_place_xrf[] =
|
const Loc ng_ultra_place_xrf[] = {
|
||||||
{
|
|
||||||
{-1, 0, 1},// I/O1
|
|
||||||
{-1, 0, 2},// I/O2
|
|
||||||
{-1, 0, 5},// I/O3
|
|
||||||
{-1, 0, 6},// I/O4
|
|
||||||
{-1, 0, 7},// I/O5
|
|
||||||
{-1, 0, 9},// I/O6
|
|
||||||
{-1, 0, 10},// I/O7
|
|
||||||
{-1, 0, 13},// I/O8
|
|
||||||
{-1, 0, 14},// I/O9
|
|
||||||
{-1, 0, 15},// I/O10
|
|
||||||
{-1, 0, 16},// I/O11
|
|
||||||
{-1, 0, 17},// I/O12
|
|
||||||
{-1, 0, 18},// I/O13
|
|
||||||
{-1, 0, 21},// I/O14
|
|
||||||
{-1, 0, 24},// I/O15
|
|
||||||
{-1, 0, 25},// I/O16
|
|
||||||
{-1, 0, 26},// I/O17
|
|
||||||
{-1, 0, 29},// I/O18
|
|
||||||
|
|
||||||
{+1, 0, 1},// I/O19
|
|
||||||
{+1, 0, 2},// I/O20
|
|
||||||
{+1, 0, 5},// I/O21
|
|
||||||
{+1, 0, 6},// I/O22
|
|
||||||
{+1, 0, 7},// I/O23
|
|
||||||
{+1, 0, 9},// I/O24
|
|
||||||
{+1, 0, 10},// I/O25
|
|
||||||
{+1, 0, 13},// I/O26
|
|
||||||
{+1, 0, 14},// I/O27
|
|
||||||
{+1, 0, 15},// I/O28
|
|
||||||
{+1, 0, 16},// I/O29
|
|
||||||
{+1, 0, 17},// I/O30
|
|
||||||
{+1, 0, 18},// I/O31
|
|
||||||
{+1, 0, 21},// I/O32
|
|
||||||
{+1, 0, 24},// I/O33
|
|
||||||
{+1, 0, 25},// I/O34
|
|
||||||
{+1, 0, 26},// I/O35
|
|
||||||
{+1, 0, 29},// I/O36
|
|
||||||
|
|
||||||
{-1, 0, 4},// RA1
|
|
||||||
{-1, 0, 12},// RA2
|
|
||||||
{-1, 0, 20},// RA3
|
|
||||||
{-1, 0, 27},// RA4
|
|
||||||
{-1, 0, 31},// RA5
|
|
||||||
|
|
||||||
{+1, 0, 4},// RA6
|
|
||||||
{+1, 0, 12},// RA7
|
|
||||||
{+1, 0, 20},// RA8
|
|
||||||
{+1, 0, 27},// RA9
|
|
||||||
{+1, 0, 31},// RA10
|
|
||||||
|
|
||||||
{-1, 0, 3},// WA1
|
|
||||||
{-1, 0, 11},// WA2
|
|
||||||
{-1, 0, 19},// WA3
|
|
||||||
{-1, 0, 23},// WA4
|
|
||||||
{-1, 0, 28},// WA5
|
|
||||||
|
|
||||||
{+1, 0, 3},// WA6
|
|
||||||
|
|
||||||
{-1, 0, 0},// WE
|
|
||||||
{-1, 0, 8},// WEA
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
const Loc ng_ultra_place_cdc1[] =
|
|
||||||
{
|
|
||||||
{+1, 0, 1}, // AI1
|
|
||||||
{+1, 0, 2}, // AI2
|
|
||||||
{+1, 0, 9}, // AI3
|
|
||||||
{+1, 0, 17},// AI4
|
|
||||||
{+1, 0, 18},// AI5
|
|
||||||
{+1, 0, 25},// AI6
|
|
||||||
|
|
||||||
{+1, 0, 3}, // BI1
|
|
||||||
{+1, 0, 10},// BI2
|
|
||||||
{+1, 0, 11},// BI3
|
|
||||||
{+1, 0, 19},// BI4
|
|
||||||
{+1, 0, 26},// BI5
|
|
||||||
{+1, 0, 27},// BI6
|
|
||||||
|
|
||||||
{ 0, 0, 22},// ASRSTI
|
|
||||||
{ 0, 0, 30},// ADRSTI
|
|
||||||
{+1, 0, 24},// BSRSTI
|
|
||||||
{+1, 0, 8}, // BDRSTI
|
|
||||||
};
|
|
||||||
|
|
||||||
const Loc ng_ultra_place_cdc2[] =
|
|
||||||
{
|
|
||||||
{-1, 0, 4}, // AI1
|
|
||||||
{-1, 0, 5}, // AI2
|
|
||||||
{-1, 0, 12},// AI3
|
|
||||||
{-1, 0, 20},// AI4
|
|
||||||
{-1, 0, 21},// AI5
|
|
||||||
{-1, 0, 28},// AI6
|
|
||||||
|
|
||||||
{-1, 0, 6}, // BI1
|
|
||||||
{-1, 0, 13},// BI2
|
|
||||||
{-1, 0, 14},// BI3
|
|
||||||
{-1, 0, 22},// BI4
|
|
||||||
{-1, 0, 29},// BI5
|
|
||||||
{-1, 0, 30},// BI6
|
|
||||||
|
|
||||||
{ 0, 0, 22},// ASRSTI
|
|
||||||
{ 0, 0, 30},// ADRSTI
|
|
||||||
{-1, 0, 23},// BSRSTI
|
|
||||||
{-1, 0, 7}, // BDRSTI
|
|
||||||
};
|
|
||||||
|
|
||||||
const Loc ng_ultra_place_xcdc[] =
|
|
||||||
{
|
|
||||||
{ 0, 0, 1}, // AI1
|
|
||||||
{ 0, 0, 2}, // AI2
|
|
||||||
{ 0, 0, 9}, // AI3
|
|
||||||
{ 0, 0, 17},// AI4
|
|
||||||
{ 0, 0, 18},// AI5
|
|
||||||
{ 0, 0, 25},// AI6
|
|
||||||
|
|
||||||
{ 0, 0, 4}, // BI1
|
|
||||||
{ 0, 0, 5}, // BI2
|
|
||||||
{ 0, 0, 12},// BI3
|
|
||||||
{ 0, 0, 20},// BI4
|
|
||||||
{ 0, 0, 21},// BI5
|
|
||||||
{ 0, 0, 28},// BI6
|
|
||||||
|
|
||||||
{-1, 0, 22},// ASRSTI
|
|
||||||
{-1, 0, 30},// ADRSTI
|
|
||||||
{+1, 0, 22},// BSRSTI
|
|
||||||
{+1, 0, 30},// BDRSTI
|
|
||||||
|
|
||||||
{ 0, 0, 3}, // CI1
|
|
||||||
{ 0, 0, 10},// CI2
|
|
||||||
{ 0, 0, 11},// CI3
|
|
||||||
{ 0, 0, 19},// CI4
|
|
||||||
{ 0, 0, 26},// CI5
|
|
||||||
{ 0, 0, 27},// CI6
|
|
||||||
|
|
||||||
{ 0, 0, 6}, // DI1
|
|
||||||
{ 0, 0, 13},// DI2
|
|
||||||
{ 0, 0, 14},// DI3
|
|
||||||
{ 0, 0, 22},// DI4
|
|
||||||
{ 0, 0, 29},// DI5
|
|
||||||
{ 0, 0, 30},// DI6
|
|
||||||
|
|
||||||
{ 0, 0, 24},// CSRSTI
|
|
||||||
{ 0, 0, 8}, // CDRSTI
|
|
||||||
{ 0, 0, 23},// DSRSTI
|
|
||||||
{ 0, 0, 7}, // DDRSTI
|
|
||||||
};
|
|
||||||
|
|
||||||
const Loc ng_ultra_place_fifo1[] =
|
|
||||||
{
|
|
||||||
{-1, 0, 1}, // I/O1
|
{-1, 0, 1}, // I/O1
|
||||||
{-1, 0, 2}, // I/O2
|
{-1, 0, 2}, // I/O2
|
||||||
{-1, 0, 5}, // I/O3
|
{-1, 0, 5}, // I/O3
|
||||||
{-1, 0, 6}, // I/O4
|
{-1, 0, 6}, // I/O4
|
||||||
{-1, 0, 7}, // I/O5
|
{-1, 0, 7}, // I/O5
|
||||||
{-1, 0, 9}, // I/O6
|
{-1, 0, 9}, // I/O6
|
||||||
{-1, 0, 10},// I/O7
|
{-1, 0, 10}, // I/O7
|
||||||
{-1, 0, 13},// I/O8
|
{-1, 0, 13}, // I/O8
|
||||||
{-1, 0, 14},// I/O9
|
{-1, 0, 14}, // I/O9
|
||||||
{-1, 0, 15},// I/O10
|
{-1, 0, 15}, // I/O10
|
||||||
{-1, 0, 16},// I/O11
|
{-1, 0, 16}, // I/O11
|
||||||
{-1, 0, 17},// I/O12
|
{-1, 0, 17}, // I/O12
|
||||||
{-1, 0, 18},// I/O13
|
{-1, 0, 18}, // I/O13
|
||||||
{-1, 0, 21},// I/O14
|
{-1, 0, 21}, // I/O14
|
||||||
{-1, 0, 24},// I/O15
|
{-1, 0, 24}, // I/O15
|
||||||
{-1, 0, 25},// I/O16
|
{-1, 0, 25}, // I/O16
|
||||||
{-1, 0, 26},// I/O17
|
{-1, 0, 26}, // I/O17
|
||||||
{-1, 0, 29},// I/O18
|
{-1, 0, 29}, // I/O18
|
||||||
|
|
||||||
{ 0, 0, 0},// I/O19
|
{+1, 0, 1}, // I/O19
|
||||||
{ 0, 0, 0},// I/O20
|
{+1, 0, 2}, // I/O20
|
||||||
{ 0, 0, 0},// I/O21
|
{+1, 0, 5}, // I/O21
|
||||||
{ 0, 0, 0},// I/O22
|
{+1, 0, 6}, // I/O22
|
||||||
{ 0, 0, 0},// I/O23
|
{+1, 0, 7}, // I/O23
|
||||||
{ 0, 0, 0},// I/O24
|
{+1, 0, 9}, // I/O24
|
||||||
{ 0, 0, 0},// I/O25
|
{+1, 0, 10}, // I/O25
|
||||||
{ 0, 0, 0},// I/O26
|
{+1, 0, 13}, // I/O26
|
||||||
{ 0, 0, 0},// I/O27
|
{+1, 0, 14}, // I/O27
|
||||||
{ 0, 0, 0},// I/O28
|
{+1, 0, 15}, // I/O28
|
||||||
{ 0, 0, 0},// I/O29
|
{+1, 0, 16}, // I/O29
|
||||||
{ 0, 0, 0},// I/O30
|
{+1, 0, 17}, // I/O30
|
||||||
{ 0, 0, 0},// I/O31
|
{+1, 0, 18}, // I/O31
|
||||||
{ 0, 0, 0},// I/O32
|
{+1, 0, 21}, // I/O32
|
||||||
{ 0, 0, 0},// I/O33
|
{+1, 0, 24}, // I/O33
|
||||||
{ 0, 0, 0},// I/O34
|
{+1, 0, 25}, // I/O34
|
||||||
{ 0, 0, 0},// I/O35
|
{+1, 0, 26}, // I/O35
|
||||||
{ 0, 0, 0},// I/O36
|
{+1, 0, 29}, // I/O36
|
||||||
|
|
||||||
{ 0, 0, 3}, // RAI1/RAO1
|
{-1, 0, 4}, // RA1
|
||||||
{ 0, 0, 10},// RAI2/RAO2
|
{-1, 0, 12}, // RA2
|
||||||
{ 0, 0, 11},// RAI3/RAO3
|
{-1, 0, 20}, // RA3
|
||||||
{ 0, 0, 19},// RAI4/RAO4
|
{-1, 0, 27}, // RA4
|
||||||
{ 0, 0, 26},// RAI5/RAO5
|
{-1, 0, 31}, // RA5
|
||||||
{ 0, 0, 27},// RAI6/RAO6
|
|
||||||
{ 0, 0, 0},// RAI7/RAO7
|
|
||||||
|
|
||||||
{ 0, 0, 1}, // WAI1/WAO1
|
{+1, 0, 4}, // RA6
|
||||||
{ 0, 0, 2}, // WAI2/WAO2
|
{+1, 0, 12}, // RA7
|
||||||
{ 0, 0, 9}, // WAI3/WAO3
|
{+1, 0, 20}, // RA8
|
||||||
{ 0, 0, 17},// WAI4/WAO4
|
{+1, 0, 27}, // RA9
|
||||||
{ 0, 0, 18},// WAI5/WAO5
|
{+1, 0, 31}, // RA10
|
||||||
{ 0, 0, 25},// WAI6/WAO6
|
|
||||||
{ 0, 0, 0},// WAI7/WAO7
|
{-1, 0, 3}, // WA1
|
||||||
|
{-1, 0, 11}, // WA2
|
||||||
|
{-1, 0, 19}, // WA3
|
||||||
|
{-1, 0, 23}, // WA4
|
||||||
|
{-1, 0, 28}, // WA5
|
||||||
|
|
||||||
|
{+1, 0, 3}, // WA6
|
||||||
|
|
||||||
{-1, 0, 0}, // WE
|
{-1, 0, 0}, // WE
|
||||||
{-1, 0, 8}, // WEA
|
{-1, 0, 8}, // WEA
|
||||||
|
|
||||||
{-1, 0, 22},// WRSTI1/WRSTO
|
};
|
||||||
{-1, 0, 30},// RRSTI1/RRSTO
|
|
||||||
{ 0, 0, 8}, // WRSTI2
|
const Loc ng_ultra_place_cdc1[] = {
|
||||||
{ 0, 0, 24},// RRSTI2
|
{+1, 0, 1}, // AI1
|
||||||
{ 0, 0, 0}, // WRSTI3/WRSTO
|
{+1, 0, 2}, // AI2
|
||||||
{ 0, 0, 0}, // RRSTI3/RRSTO
|
{+1, 0, 9}, // AI3
|
||||||
{ 0, 0, 0}, // WRSTI4
|
{+1, 0, 17}, // AI4
|
||||||
{ 0, 0, 0}, // RRSTI4
|
{+1, 0, 18}, // AI5
|
||||||
|
{+1, 0, 25}, // AI6
|
||||||
|
|
||||||
|
{+1, 0, 3}, // BI1
|
||||||
|
{+1, 0, 10}, // BI2
|
||||||
|
{+1, 0, 11}, // BI3
|
||||||
|
{+1, 0, 19}, // BI4
|
||||||
|
{+1, 0, 26}, // BI5
|
||||||
|
{+1, 0, 27}, // BI6
|
||||||
|
|
||||||
|
{0, 0, 22}, // ASRSTI
|
||||||
|
{0, 0, 30}, // ADRSTI
|
||||||
|
{+1, 0, 24}, // BSRSTI
|
||||||
|
{+1, 0, 8}, // BDRSTI
|
||||||
|
};
|
||||||
|
|
||||||
|
const Loc ng_ultra_place_cdc2[] = {
|
||||||
|
{-1, 0, 4}, // AI1
|
||||||
|
{-1, 0, 5}, // AI2
|
||||||
|
{-1, 0, 12}, // AI3
|
||||||
|
{-1, 0, 20}, // AI4
|
||||||
|
{-1, 0, 21}, // AI5
|
||||||
|
{-1, 0, 28}, // AI6
|
||||||
|
|
||||||
|
{-1, 0, 6}, // BI1
|
||||||
|
{-1, 0, 13}, // BI2
|
||||||
|
{-1, 0, 14}, // BI3
|
||||||
|
{-1, 0, 22}, // BI4
|
||||||
|
{-1, 0, 29}, // BI5
|
||||||
|
{-1, 0, 30}, // BI6
|
||||||
|
|
||||||
|
{0, 0, 22}, // ASRSTI
|
||||||
|
{0, 0, 30}, // ADRSTI
|
||||||
|
{-1, 0, 23}, // BSRSTI
|
||||||
|
{-1, 0, 7}, // BDRSTI
|
||||||
|
};
|
||||||
|
|
||||||
|
const Loc ng_ultra_place_xcdc[] = {
|
||||||
|
{0, 0, 1}, // AI1
|
||||||
|
{0, 0, 2}, // AI2
|
||||||
|
{0, 0, 9}, // AI3
|
||||||
|
{0, 0, 17}, // AI4
|
||||||
|
{0, 0, 18}, // AI5
|
||||||
|
{0, 0, 25}, // AI6
|
||||||
|
|
||||||
|
{0, 0, 4}, // BI1
|
||||||
|
{0, 0, 5}, // BI2
|
||||||
|
{0, 0, 12}, // BI3
|
||||||
|
{0, 0, 20}, // BI4
|
||||||
|
{0, 0, 21}, // BI5
|
||||||
|
{0, 0, 28}, // BI6
|
||||||
|
|
||||||
|
{-1, 0, 22}, // ASRSTI
|
||||||
|
{-1, 0, 30}, // ADRSTI
|
||||||
|
{+1, 0, 22}, // BSRSTI
|
||||||
|
{+1, 0, 30}, // BDRSTI
|
||||||
|
|
||||||
|
{0, 0, 3}, // CI1
|
||||||
|
{0, 0, 10}, // CI2
|
||||||
|
{0, 0, 11}, // CI3
|
||||||
|
{0, 0, 19}, // CI4
|
||||||
|
{0, 0, 26}, // CI5
|
||||||
|
{0, 0, 27}, // CI6
|
||||||
|
|
||||||
|
{0, 0, 6}, // DI1
|
||||||
|
{0, 0, 13}, // DI2
|
||||||
|
{0, 0, 14}, // DI3
|
||||||
|
{0, 0, 22}, // DI4
|
||||||
|
{0, 0, 29}, // DI5
|
||||||
|
{0, 0, 30}, // DI6
|
||||||
|
|
||||||
|
{0, 0, 24}, // CSRSTI
|
||||||
|
{0, 0, 8}, // CDRSTI
|
||||||
|
{0, 0, 23}, // DSRSTI
|
||||||
|
{0, 0, 7}, // DDRSTI
|
||||||
|
};
|
||||||
|
|
||||||
|
const Loc ng_ultra_place_fifo1[] = {
|
||||||
|
{-1, 0, 1}, // I/O1
|
||||||
|
{-1, 0, 2}, // I/O2
|
||||||
|
{-1, 0, 5}, // I/O3
|
||||||
|
{-1, 0, 6}, // I/O4
|
||||||
|
{-1, 0, 7}, // I/O5
|
||||||
|
{-1, 0, 9}, // I/O6
|
||||||
|
{-1, 0, 10}, // I/O7
|
||||||
|
{-1, 0, 13}, // I/O8
|
||||||
|
{-1, 0, 14}, // I/O9
|
||||||
|
{-1, 0, 15}, // I/O10
|
||||||
|
{-1, 0, 16}, // I/O11
|
||||||
|
{-1, 0, 17}, // I/O12
|
||||||
|
{-1, 0, 18}, // I/O13
|
||||||
|
{-1, 0, 21}, // I/O14
|
||||||
|
{-1, 0, 24}, // I/O15
|
||||||
|
{-1, 0, 25}, // I/O16
|
||||||
|
{-1, 0, 26}, // I/O17
|
||||||
|
{-1, 0, 29}, // I/O18
|
||||||
|
|
||||||
|
{0, 0, 0}, // I/O19
|
||||||
|
{0, 0, 0}, // I/O20
|
||||||
|
{0, 0, 0}, // I/O21
|
||||||
|
{0, 0, 0}, // I/O22
|
||||||
|
{0, 0, 0}, // I/O23
|
||||||
|
{0, 0, 0}, // I/O24
|
||||||
|
{0, 0, 0}, // I/O25
|
||||||
|
{0, 0, 0}, // I/O26
|
||||||
|
{0, 0, 0}, // I/O27
|
||||||
|
{0, 0, 0}, // I/O28
|
||||||
|
{0, 0, 0}, // I/O29
|
||||||
|
{0, 0, 0}, // I/O30
|
||||||
|
{0, 0, 0}, // I/O31
|
||||||
|
{0, 0, 0}, // I/O32
|
||||||
|
{0, 0, 0}, // I/O33
|
||||||
|
{0, 0, 0}, // I/O34
|
||||||
|
{0, 0, 0}, // I/O35
|
||||||
|
{0, 0, 0}, // I/O36
|
||||||
|
|
||||||
|
{0, 0, 3}, // RAI1/RAO1
|
||||||
|
{0, 0, 10}, // RAI2/RAO2
|
||||||
|
{0, 0, 11}, // RAI3/RAO3
|
||||||
|
{0, 0, 19}, // RAI4/RAO4
|
||||||
|
{0, 0, 26}, // RAI5/RAO5
|
||||||
|
{0, 0, 27}, // RAI6/RAO6
|
||||||
|
{0, 0, 0}, // RAI7/RAO7
|
||||||
|
|
||||||
|
{0, 0, 1}, // WAI1/WAO1
|
||||||
|
{0, 0, 2}, // WAI2/WAO2
|
||||||
|
{0, 0, 9}, // WAI3/WAO3
|
||||||
|
{0, 0, 17}, // WAI4/WAO4
|
||||||
|
{0, 0, 18}, // WAI5/WAO5
|
||||||
|
{0, 0, 25}, // WAI6/WAO6
|
||||||
|
{0, 0, 0}, // WAI7/WAO7
|
||||||
|
|
||||||
|
{-1, 0, 0}, // WE
|
||||||
|
{-1, 0, 8}, // WEA
|
||||||
|
|
||||||
|
{-1, 0, 22}, // WRSTI1/WRSTO
|
||||||
|
{-1, 0, 30}, // RRSTI1/RRSTO
|
||||||
|
{0, 0, 8}, // WRSTI2
|
||||||
|
{0, 0, 24}, // RRSTI2
|
||||||
|
{0, 0, 0}, // WRSTI3/WRSTO
|
||||||
|
{0, 0, 0}, // RRSTI3/RRSTO
|
||||||
|
{0, 0, 0}, // WRSTI4
|
||||||
|
{0, 0, 0}, // RRSTI4
|
||||||
|
|
||||||
{-1, 0, 3}, // WEQ
|
{-1, 0, 3}, // WEQ
|
||||||
{-1, 0, 4}, // REQ
|
{-1, 0, 4}, // REQ
|
||||||
@ -281,77 +276,76 @@ const Loc ng_ultra_place_fifo1[] =
|
|||||||
// {-1, 0, 20}, REQ
|
// {-1, 0, 20}, REQ
|
||||||
// {-1, 0, 27}, WEQ
|
// {-1, 0, 27}, WEQ
|
||||||
// {-1, 0, 28}, REQ
|
// {-1, 0, 28}, REQ
|
||||||
{ 0, 0, 0}, // WEQ2
|
{0, 0, 0}, // WEQ2
|
||||||
{ 0, 0, 0}, // REQ2
|
{0, 0, 0}, // REQ2
|
||||||
};
|
};
|
||||||
|
|
||||||
const Loc ng_ultra_place_fifo2[] =
|
const Loc ng_ultra_place_fifo2[] = {
|
||||||
{
|
|
||||||
{+1, 0, 1}, // I/O1
|
{+1, 0, 1}, // I/O1
|
||||||
{+1, 0, 2}, // I/O2
|
{+1, 0, 2}, // I/O2
|
||||||
{+1, 0, 5}, // I/O3
|
{+1, 0, 5}, // I/O3
|
||||||
{+1, 0, 6}, // I/O4
|
{+1, 0, 6}, // I/O4
|
||||||
{+1, 0, 7}, // I/O5
|
{+1, 0, 7}, // I/O5
|
||||||
{+1, 0, 9}, // I/O6
|
{+1, 0, 9}, // I/O6
|
||||||
{+1, 0, 10},// I/O7
|
{+1, 0, 10}, // I/O7
|
||||||
{+1, 0, 13},// I/O8
|
{+1, 0, 13}, // I/O8
|
||||||
{+1, 0, 14},// I/O9
|
{+1, 0, 14}, // I/O9
|
||||||
{+1, 0, 15},// I/O10
|
{+1, 0, 15}, // I/O10
|
||||||
{+1, 0, 16},// I/O11
|
{+1, 0, 16}, // I/O11
|
||||||
{+1, 0, 17},// I/O12
|
{+1, 0, 17}, // I/O12
|
||||||
{+1, 0, 18},// I/O13
|
{+1, 0, 18}, // I/O13
|
||||||
{+1, 0, 21},// I/O14
|
{+1, 0, 21}, // I/O14
|
||||||
{+1, 0, 24},// I/O15
|
{+1, 0, 24}, // I/O15
|
||||||
{+1, 0, 25},// I/O16
|
{+1, 0, 25}, // I/O16
|
||||||
{+1, 0, 26},// I/O17
|
{+1, 0, 26}, // I/O17
|
||||||
{+1, 0, 29},// I/O18
|
{+1, 0, 29}, // I/O18
|
||||||
|
|
||||||
{ 0, 0, 0},// I/O19
|
{0, 0, 0}, // I/O19
|
||||||
{ 0, 0, 0},// I/O20
|
{0, 0, 0}, // I/O20
|
||||||
{ 0, 0, 0},// I/O21
|
{0, 0, 0}, // I/O21
|
||||||
{ 0, 0, 0},// I/O22
|
{0, 0, 0}, // I/O22
|
||||||
{ 0, 0, 0},// I/O23
|
{0, 0, 0}, // I/O23
|
||||||
{ 0, 0, 0},// I/O24
|
{0, 0, 0}, // I/O24
|
||||||
{ 0, 0, 0},// I/O25
|
{0, 0, 0}, // I/O25
|
||||||
{ 0, 0, 0},// I/O26
|
{0, 0, 0}, // I/O26
|
||||||
{ 0, 0, 0},// I/O27
|
{0, 0, 0}, // I/O27
|
||||||
{ 0, 0, 0},// I/O28
|
{0, 0, 0}, // I/O28
|
||||||
{ 0, 0, 0},// I/O29
|
{0, 0, 0}, // I/O29
|
||||||
{ 0, 0, 0},// I/O30
|
{0, 0, 0}, // I/O30
|
||||||
{ 0, 0, 0},// I/O31
|
{0, 0, 0}, // I/O31
|
||||||
{ 0, 0, 0},// I/O32
|
{0, 0, 0}, // I/O32
|
||||||
{ 0, 0, 0},// I/O33
|
{0, 0, 0}, // I/O33
|
||||||
{ 0, 0, 0},// I/O34
|
{0, 0, 0}, // I/O34
|
||||||
{ 0, 0, 0},// I/O35
|
{0, 0, 0}, // I/O35
|
||||||
{ 0, 0, 0},// I/O36
|
{0, 0, 0}, // I/O36
|
||||||
|
|
||||||
{ 0, 0, 6}, // RAI1/RAO1
|
{0, 0, 6}, // RAI1/RAO1
|
||||||
{ 0, 0, 13},// RAI2/RAO2
|
{0, 0, 13}, // RAI2/RAO2
|
||||||
{ 0, 0, 14},// RAI3/RAO3
|
{0, 0, 14}, // RAI3/RAO3
|
||||||
{ 0, 0, 22},// RAI4/RAO4
|
{0, 0, 22}, // RAI4/RAO4
|
||||||
{ 0, 0, 29},// RAI5/RAO5
|
{0, 0, 29}, // RAI5/RAO5
|
||||||
{ 0, 0, 30},// RAI6/RAO6
|
{0, 0, 30}, // RAI6/RAO6
|
||||||
{ 0, 0, 0},// RAI7/RAO7
|
{0, 0, 0}, // RAI7/RAO7
|
||||||
|
|
||||||
{ 0, 0, 4}, // WAI1/WAO1
|
{0, 0, 4}, // WAI1/WAO1
|
||||||
{ 0, 0, 5}, // WAI2/WAO2
|
{0, 0, 5}, // WAI2/WAO2
|
||||||
{ 0, 0, 12},// WAI3/WAO3
|
{0, 0, 12}, // WAI3/WAO3
|
||||||
{ 0, 0, 20},// WAI4/WAO4
|
{0, 0, 20}, // WAI4/WAO4
|
||||||
{ 0, 0, 21},// WAI5/WAO5
|
{0, 0, 21}, // WAI5/WAO5
|
||||||
{ 0, 0, 28},// WAI6/WAO6
|
{0, 0, 28}, // WAI6/WAO6
|
||||||
{ 0, 0, 0},// WAI7/WAO7
|
{0, 0, 0}, // WAI7/WAO7
|
||||||
|
|
||||||
{+1, 0, 0}, // WE
|
{+1, 0, 0}, // WE
|
||||||
{+1, 0, 8}, // WEA
|
{+1, 0, 8}, // WEA
|
||||||
|
|
||||||
{+1, 0, 22},// WRSTI1/WRSTO
|
{+1, 0, 22}, // WRSTI1/WRSTO
|
||||||
{+1, 0, 30},// RRSTI1/RRSTO
|
{+1, 0, 30}, // RRSTI1/RRSTO
|
||||||
{ 0, 0, 7}, // WRSTI2
|
{0, 0, 7}, // WRSTI2
|
||||||
{ 0, 0, 23},// RRSTI2
|
{0, 0, 23}, // RRSTI2
|
||||||
{ 0, 0, 0}, // WRSTI3/WRSTO
|
{0, 0, 0}, // WRSTI3/WRSTO
|
||||||
{ 0, 0, 0}, // RRSTI3/RRSTO
|
{0, 0, 0}, // RRSTI3/RRSTO
|
||||||
{ 0, 0, 0}, // WRSTI4
|
{0, 0, 0}, // WRSTI4
|
||||||
{ 0, 0, 0}, // RRSTI4
|
{0, 0, 0}, // RRSTI4
|
||||||
|
|
||||||
{+1, 0, 3}, // WEQ
|
{+1, 0, 3}, // WEQ
|
||||||
{+1, 0, 4}, // REQ
|
{+1, 0, 4}, // REQ
|
||||||
@ -361,76 +355,75 @@ const Loc ng_ultra_place_fifo2[] =
|
|||||||
// {+1, 0, 20}, REQ
|
// {+1, 0, 20}, REQ
|
||||||
// {+1, 0, 27}, WEQ
|
// {+1, 0, 27}, WEQ
|
||||||
// {+1, 0, 28}, REQ
|
// {+1, 0, 28}, REQ
|
||||||
{ 0, 0, 0}, // WEQ2
|
{0, 0, 0}, // WEQ2
|
||||||
{ 0, 0, 0}, // REQ2
|
{0, 0, 0}, // REQ2
|
||||||
};
|
};
|
||||||
|
|
||||||
const Loc ng_ultra_place_xfifo[] =
|
const Loc ng_ultra_place_xfifo[] = {
|
||||||
{
|
|
||||||
{-1, 0, 1}, // I/O1
|
{-1, 0, 1}, // I/O1
|
||||||
{-1, 0, 2}, // I/O2
|
{-1, 0, 2}, // I/O2
|
||||||
{-1, 0, 5}, // I/O3
|
{-1, 0, 5}, // I/O3
|
||||||
{-1, 0, 6}, // I/O4
|
{-1, 0, 6}, // I/O4
|
||||||
{-1, 0, 7}, // I/O5
|
{-1, 0, 7}, // I/O5
|
||||||
{-1, 0, 9}, // I/O6
|
{-1, 0, 9}, // I/O6
|
||||||
{-1, 0, 10},// I/O7
|
{-1, 0, 10}, // I/O7
|
||||||
{-1, 0, 13},// I/O8
|
{-1, 0, 13}, // I/O8
|
||||||
{-1, 0, 14},// I/O9
|
{-1, 0, 14}, // I/O9
|
||||||
{-1, 0, 15},// I/O10
|
{-1, 0, 15}, // I/O10
|
||||||
{-1, 0, 16},// I/O11
|
{-1, 0, 16}, // I/O11
|
||||||
{-1, 0, 17},// I/O12
|
{-1, 0, 17}, // I/O12
|
||||||
{-1, 0, 18},// I/O13
|
{-1, 0, 18}, // I/O13
|
||||||
{-1, 0, 21},// I/O14
|
{-1, 0, 21}, // I/O14
|
||||||
{-1, 0, 24},// I/O15
|
{-1, 0, 24}, // I/O15
|
||||||
{-1, 0, 25},// I/O16
|
{-1, 0, 25}, // I/O16
|
||||||
{-1, 0, 26},// I/O17
|
{-1, 0, 26}, // I/O17
|
||||||
{-1, 0, 29},// I/O18
|
{-1, 0, 29}, // I/O18
|
||||||
{+1, 0, 1}, // I/O19
|
{+1, 0, 1}, // I/O19
|
||||||
{+1, 0, 2}, // I/O20
|
{+1, 0, 2}, // I/O20
|
||||||
{+1, 0, 5}, // I/O21
|
{+1, 0, 5}, // I/O21
|
||||||
{+1, 0, 6}, // I/O22
|
{+1, 0, 6}, // I/O22
|
||||||
{+1, 0, 7}, // I/O23
|
{+1, 0, 7}, // I/O23
|
||||||
{+1, 0, 9}, // I/O24
|
{+1, 0, 9}, // I/O24
|
||||||
{+1, 0, 10},// I/O25
|
{+1, 0, 10}, // I/O25
|
||||||
{+1, 0, 13},// I/O26
|
{+1, 0, 13}, // I/O26
|
||||||
{+1, 0, 14},// I/O27
|
{+1, 0, 14}, // I/O27
|
||||||
{+1, 0, 15},// I/O28
|
{+1, 0, 15}, // I/O28
|
||||||
{+1, 0, 16},// I/O29
|
{+1, 0, 16}, // I/O29
|
||||||
{+1, 0, 17},// I/O30
|
{+1, 0, 17}, // I/O30
|
||||||
{+1, 0, 18},// I/O31
|
{+1, 0, 18}, // I/O31
|
||||||
{+1, 0, 21},// I/O32
|
{+1, 0, 21}, // I/O32
|
||||||
{+1, 0, 24},// I/O33
|
{+1, 0, 24}, // I/O33
|
||||||
{+1, 0, 25},// I/O34
|
{+1, 0, 25}, // I/O34
|
||||||
{+1, 0, 26},// I/O35
|
{+1, 0, 26}, // I/O35
|
||||||
{+1, 0, 29},// I/O36
|
{+1, 0, 29}, // I/O36
|
||||||
|
|
||||||
{ 0, 0, 3}, // RAI1/RAO1
|
{0, 0, 3}, // RAI1/RAO1
|
||||||
{ 0, 0, 10},// RAI2/RAO2
|
{0, 0, 10}, // RAI2/RAO2
|
||||||
{ 0, 0, 11},// RAI3/RAO3
|
{0, 0, 11}, // RAI3/RAO3
|
||||||
{ 0, 0, 19},// RAI4/RAO4
|
{0, 0, 19}, // RAI4/RAO4
|
||||||
{ 0, 0, 26},// RAI5/RAO5
|
{0, 0, 26}, // RAI5/RAO5
|
||||||
{ 0, 0, 27},// RAI6/RAO6
|
{0, 0, 27}, // RAI6/RAO6
|
||||||
{ 0, 0, 6}, // RAI7/RAO7
|
{0, 0, 6}, // RAI7/RAO7
|
||||||
|
|
||||||
{ 0, 0, 1}, // WAI1/WAO1
|
{0, 0, 1}, // WAI1/WAO1
|
||||||
{ 0, 0, 2}, // WAI2/WAO2
|
{0, 0, 2}, // WAI2/WAO2
|
||||||
{ 0, 0, 9}, // WAI3/WAO3
|
{0, 0, 9}, // WAI3/WAO3
|
||||||
{ 0, 0, 17},// WAI4/WAO4
|
{0, 0, 17}, // WAI4/WAO4
|
||||||
{ 0, 0, 18},// WAI5/WAO5
|
{0, 0, 18}, // WAI5/WAO5
|
||||||
{ 0, 0, 25},// WAI6/WAO6
|
{0, 0, 25}, // WAI6/WAO6
|
||||||
{ 0, 0, 4}, // WAI7/WAO7
|
{0, 0, 4}, // WAI7/WAO7
|
||||||
|
|
||||||
{-1, 0, 0}, // WE
|
{-1, 0, 0}, // WE
|
||||||
{-1, 0, 8}, // WEA
|
{-1, 0, 8}, // WEA
|
||||||
|
|
||||||
{-1, 0, 22},// WRSTI1/WRSTO
|
{-1, 0, 22}, // WRSTI1/WRSTO
|
||||||
{-1, 0, 30},// RRSTI1/RRSTO
|
{-1, 0, 30}, // RRSTI1/RRSTO
|
||||||
{ 0, 0, 8}, // WRSTI2
|
{0, 0, 8}, // WRSTI2
|
||||||
{ 0, 0, 24},// RRSTI2
|
{0, 0, 24}, // RRSTI2
|
||||||
{+1, 0, 22},// WRSTI3/WRSTO
|
{+1, 0, 22}, // WRSTI3/WRSTO
|
||||||
{+1, 0, 30},// RRSTI3/RRSTO
|
{+1, 0, 30}, // RRSTI3/RRSTO
|
||||||
{ 0, 0, 7}, // WRSTI4
|
{0, 0, 7}, // WRSTI4
|
||||||
{ 0, 0, 23},// RRSTI4
|
{0, 0, 23}, // RRSTI4
|
||||||
|
|
||||||
{-1, 0, 3}, // WEQ1
|
{-1, 0, 3}, // WEQ1
|
||||||
{-1, 0, 4}, // REQ1
|
{-1, 0, 4}, // REQ1
|
||||||
@ -450,14 +443,14 @@ const Loc ng_ultra_place_xfifo[] =
|
|||||||
// {+1, 0, 28}, REQ2
|
// {+1, 0, 28}, REQ2
|
||||||
};
|
};
|
||||||
|
|
||||||
};
|
}; // namespace
|
||||||
|
|
||||||
namespace ng_ultra {
|
namespace ng_ultra {
|
||||||
|
|
||||||
Loc getNextLocInDSPChain(const NgUltraImpl *impl, Loc loc)
|
Loc getNextLocInDSPChain(const NgUltraImpl *impl, Loc loc)
|
||||||
{
|
{
|
||||||
BelId bel = impl->ctx->getBelByLocation(loc);
|
BelId bel = impl->ctx->getBelByLocation(loc);
|
||||||
if (impl->dsp_cascade.count(bel)==0) {
|
if (impl->dsp_cascade.count(bel) == 0) {
|
||||||
loc.z = -1; // End of chain
|
loc.z = -1; // End of chain
|
||||||
return loc;
|
return loc;
|
||||||
}
|
}
|
||||||
@ -497,14 +490,15 @@ Loc getNextLocInDFFChain(Loc loc)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
int z = loc.z + 8;
|
int z = loc.z + 8;
|
||||||
if (z>31) z++;
|
if (z > 31)
|
||||||
|
z++;
|
||||||
result.z = z % 32; // BEL_LUT_Z is 0
|
result.z = z % 32; // BEL_LUT_Z is 0
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
Loc getCYFE(Loc root, int pos)
|
Loc getCYFE(Loc root, int pos)
|
||||||
{
|
{
|
||||||
int p[] = { 2-1, 25-1, 10-1, 17-1 };
|
int p[] = {2 - 1, 25 - 1, 10 - 1, 17 - 1};
|
||||||
int cy = root.z - BEL_CY_Z;
|
int cy = root.z - BEL_CY_Z;
|
||||||
Loc result;
|
Loc result;
|
||||||
result.x = root.x;
|
result.x = root.x;
|
||||||
@ -541,7 +535,7 @@ Loc getCDCFE(Loc root, int pos)
|
|||||||
Loc result;
|
Loc result;
|
||||||
if (root.z == BEL_CDC_Z) {
|
if (root.z == BEL_CDC_Z) {
|
||||||
result = ng_ultra_place_cdc1[pos];
|
result = ng_ultra_place_cdc1[pos];
|
||||||
} else if (root.z == BEL_CDC_Z+1) {
|
} else if (root.z == BEL_CDC_Z + 1) {
|
||||||
result = ng_ultra_place_cdc2[pos];
|
result = ng_ultra_place_cdc2[pos];
|
||||||
} else if (root.z == BEL_XCDC_Z) {
|
} else if (root.z == BEL_XCDC_Z) {
|
||||||
result = ng_ultra_place_xcdc[pos];
|
result = ng_ultra_place_xcdc[pos];
|
||||||
@ -558,7 +552,7 @@ Loc getFIFOFE(Loc root, int pos)
|
|||||||
Loc result;
|
Loc result;
|
||||||
if (root.z == BEL_FIFO_Z) {
|
if (root.z == BEL_FIFO_Z) {
|
||||||
result = ng_ultra_place_fifo1[pos];
|
result = ng_ultra_place_fifo1[pos];
|
||||||
} else if (root.z == BEL_FIFO_Z+1) {
|
} else if (root.z == BEL_FIFO_Z + 1) {
|
||||||
result = ng_ultra_place_fifo2[pos];
|
result = ng_ultra_place_fifo2[pos];
|
||||||
} else if (root.z == BEL_XFIFO_Z) {
|
} else if (root.z == BEL_XFIFO_Z) {
|
||||||
result = ng_ultra_place_xfifo[pos];
|
result = ng_ultra_place_xfifo[pos];
|
||||||
@ -570,5 +564,5 @@ Loc getFIFOFE(Loc root, int pos)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
}; // namespace ng_ultra
|
||||||
NEXTPNR_NAMESPACE_END
|
NEXTPNR_NAMESPACE_END
|
||||||
|
@ -37,7 +37,7 @@ Loc getXRFFE(Loc root, int pos);
|
|||||||
Loc getCDCFE(Loc root, int pos);
|
Loc getCDCFE(Loc root, int pos);
|
||||||
Loc getFIFOFE(Loc root, int pos);
|
Loc getFIFOFE(Loc root, int pos);
|
||||||
|
|
||||||
};
|
}; // namespace ng_ultra
|
||||||
|
|
||||||
NEXTPNR_NAMESPACE_END
|
NEXTPNR_NAMESPACE_END
|
||||||
#endif
|
#endif
|
||||||
|
@ -21,18 +21,18 @@
|
|||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <queue>
|
#include <queue>
|
||||||
|
|
||||||
#include "himbaechel_api.h"
|
|
||||||
#include "design_utils.h"
|
#include "design_utils.h"
|
||||||
|
#include "extra_data.h"
|
||||||
|
#include "himbaechel_api.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "nextpnr.h"
|
#include "nextpnr.h"
|
||||||
#include "util.h"
|
|
||||||
#include "extra_data.h"
|
|
||||||
#include "placer_heap.h"
|
#include "placer_heap.h"
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
#include "himbaechel_helpers.h"
|
#include "himbaechel_helpers.h"
|
||||||
|
|
||||||
#include "ng_ultra.h"
|
|
||||||
#include "location_map.h"
|
#include "location_map.h"
|
||||||
|
#include "ng_ultra.h"
|
||||||
|
|
||||||
#define GEN_INIT_CONSTIDS
|
#define GEN_INIT_CONSTIDS
|
||||||
#define HIMBAECHEL_CONSTIDS "uarch/ng-ultra/constids.inc"
|
#define HIMBAECHEL_CONSTIDS "uarch/ng-ultra/constids.inc"
|
||||||
@ -41,7 +41,7 @@ using namespace NEXTPNR_NAMESPACE_PREFIX ng_ultra;
|
|||||||
|
|
||||||
NEXTPNR_NAMESPACE_BEGIN
|
NEXTPNR_NAMESPACE_BEGIN
|
||||||
|
|
||||||
NgUltraImpl::~NgUltraImpl(){};
|
NgUltraImpl::~NgUltraImpl() {};
|
||||||
|
|
||||||
void NgUltraImpl::init_database(Arch *arch)
|
void NgUltraImpl::init_database(Arch *arch)
|
||||||
{
|
{
|
||||||
@ -54,56 +54,56 @@ void NgUltraImpl::init_database(Arch *arch)
|
|||||||
void NgUltraImpl::init(Context *ctx)
|
void NgUltraImpl::init(Context *ctx)
|
||||||
{
|
{
|
||||||
HimbaechelAPI::init(ctx);
|
HimbaechelAPI::init(ctx);
|
||||||
for (int i=1;i<=8;i++)
|
for (int i = 1; i <= 8; i++)
|
||||||
for (int j=0;j<20;j++)
|
for (int j = 0; j < 20; j++)
|
||||||
gck_per_lobe[i].push_back(GckConfig(BelId()));
|
gck_per_lobe[i].push_back(GckConfig(BelId()));
|
||||||
for (auto bel : ctx->getBels()) {
|
for (auto bel : ctx->getBels()) {
|
||||||
if (ctx->getBelType(bel) == id_IOM) {
|
if (ctx->getBelType(bel) == id_IOM) {
|
||||||
std::set<IdString> ckg;
|
std::set<IdString> ckg;
|
||||||
IdString bank = tile_name_id(bel.tile);
|
IdString bank = tile_name_id(bel.tile);
|
||||||
iom_bels.emplace(bank,bel);
|
iom_bels.emplace(bank, bel);
|
||||||
WireId belpin = ctx->getBelPinWire(bel,id_CKO1);
|
WireId belpin = ctx->getBelPinWire(bel, id_CKO1);
|
||||||
for (auto dh : ctx->getPipsDownhill(belpin)) {
|
for (auto dh : ctx->getPipsDownhill(belpin)) {
|
||||||
WireId pip_dst = ctx->getPipDstWire(dh);
|
WireId pip_dst = ctx->getPipDstWire(dh);
|
||||||
for (const auto &item : ctx->getWireBelPins(pip_dst)) {
|
for (const auto &item : ctx->getWireBelPins(pip_dst)) {
|
||||||
if (boost::contains(ctx->nameOfBel(item.bel),"WFG_C")) {
|
if (boost::contains(ctx->nameOfBel(item.bel), "WFG_C")) {
|
||||||
unused_wfg[item.bel] = tile_name_id(item.bel.tile);
|
unused_wfg[item.bel] = tile_name_id(item.bel.tile);
|
||||||
}
|
} else if (boost::contains(ctx->nameOfBel(item.bel), "PLL")) {
|
||||||
else if (boost::contains(ctx->nameOfBel(item.bel),"PLL")) {
|
|
||||||
ckg.emplace(tile_name_id(item.bel.tile));
|
ckg.emplace(tile_name_id(item.bel.tile));
|
||||||
unused_pll[item.bel] = tile_name_id(item.bel.tile);
|
unused_pll[item.bel] = tile_name_id(item.bel.tile);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
std::pair<IdString,IdString> p;
|
std::pair<IdString, IdString> p;
|
||||||
p.first = *ckg.begin();
|
p.first = *ckg.begin();
|
||||||
if (ckg.size()==2) p.second = *(ckg.begin()++);
|
if (ckg.size() == 2)
|
||||||
|
p.second = *(ckg.begin()++);
|
||||||
bank_to_ckg[bank] = p;
|
bank_to_ckg[bank] = p;
|
||||||
} else if (ctx->getBelType(bel) == id_IOTP) {
|
} else if (ctx->getBelType(bel) == id_IOTP) {
|
||||||
if (ctx->getBelName(bel)[1] == ctx->id("D08P_CLK.IOTP")) {
|
if (ctx->getBelName(bel)[1] == ctx->id("D08P_CLK.IOTP")) {
|
||||||
global_capable_bels.emplace(bel,id_P17RI);
|
global_capable_bels.emplace(bel, id_P17RI);
|
||||||
} else if (ctx->getBelName(bel)[1] == ctx->id("D09P_CLK.IOTP")) {
|
} else if (ctx->getBelName(bel)[1] == ctx->id("D09P_CLK.IOTP")) {
|
||||||
global_capable_bels.emplace(bel,id_P19RI);
|
global_capable_bels.emplace(bel, id_P19RI);
|
||||||
}
|
}
|
||||||
} else if (ctx->getBelType(bel) == id_GCK) {
|
} else if (ctx->getBelType(bel) == id_GCK) {
|
||||||
std::string name = ctx->getBelName(bel)[1].c_str(ctx);
|
std::string name = ctx->getBelName(bel)[1].c_str(ctx);
|
||||||
int lobe = std::stoi(name.substr(1,1));
|
int lobe = std::stoi(name.substr(1, 1));
|
||||||
int num = std::stoi(name.substr(4,2).c_str());
|
int num = std::stoi(name.substr(4, 2).c_str());
|
||||||
gck_per_lobe[lobe][num-1] = GckConfig(bel);
|
gck_per_lobe[lobe][num - 1] = GckConfig(bel);
|
||||||
}
|
}
|
||||||
locations.emplace(stringf("%s:%s",tile_name(bel.tile).c_str(), ctx->getBelName(bel)[1].c_str(ctx)),bel);
|
locations.emplace(stringf("%s:%s", tile_name(bel.tile).c_str(), ctx->getBelName(bel)[1].c_str(ctx)), bel);
|
||||||
Loc loc = ctx->getBelLocation(bel);
|
Loc loc = ctx->getBelLocation(bel);
|
||||||
tile_locations.emplace(tile_name(bel.tile).c_str(),Loc(loc.x & 0xfffe, loc.y & 0xfffe, 0));
|
tile_locations.emplace(tile_name(bel.tile).c_str(), Loc(loc.x & 0xfffe, loc.y & 0xfffe, 0));
|
||||||
}
|
}
|
||||||
for (auto bel : ctx->getBels()) {
|
for (auto bel : ctx->getBels()) {
|
||||||
if (ctx->getBelType(bel) == id_DSP) {
|
if (ctx->getBelType(bel) == id_DSP) {
|
||||||
WireId cco = ctx->getBelPinWire(bel,id_CCO);
|
WireId cco = ctx->getBelPinWire(bel, id_CCO);
|
||||||
WireId cci;
|
WireId cci;
|
||||||
for (auto dh : ctx->getPipsDownhill(cco)) {
|
for (auto dh : ctx->getPipsDownhill(cco)) {
|
||||||
cci = ctx->getPipDstWire(dh);
|
cci = ctx->getPipDstWire(dh);
|
||||||
}
|
}
|
||||||
if (cci!=WireId()) {
|
if (cci != WireId()) {
|
||||||
std::string loc = stringf("%s:%s",tile_name(cci.tile).c_str(), ctx->getWireName(cci)[1].c_str(ctx));
|
std::string loc = stringf("%s:%s", tile_name(cci.tile).c_str(), ctx->getWireName(cci)[1].c_str(ctx));
|
||||||
loc.erase(loc.find(".CCI"));
|
loc.erase(loc.find(".CCI"));
|
||||||
BelId dsp_bel = locations[loc];
|
BelId dsp_bel = locations[loc];
|
||||||
dsp_cascade.emplace(dsp_bel, bel);
|
dsp_cascade.emplace(dsp_bel, bel);
|
||||||
@ -115,75 +115,72 @@ void NgUltraImpl::init(Context *ctx)
|
|||||||
namespace {
|
namespace {
|
||||||
// Note: These are per Cell type not Bel type
|
// Note: These are per Cell type not Bel type
|
||||||
// Sinks
|
// Sinks
|
||||||
const dict<IdString,pool<IdString>> fabric_lowskew_sinks = {
|
const dict<IdString, pool<IdString>> fabric_lowskew_sinks = {
|
||||||
// TILE - DFF
|
// TILE - DFF
|
||||||
{ id_BEYOND_FE, { id_CK, id_L, id_R }},
|
{id_BEYOND_FE, {id_CK, id_L, id_R}},
|
||||||
// { id_DFF, { id_CK }}, // This is part of BEYOND_FE
|
// { id_DFF, { id_CK }}, // This is part of BEYOND_FE
|
||||||
// TILE - Register file
|
// TILE - Register file
|
||||||
{ id_RF, { id_WCK }},
|
{id_RF, {id_WCK}},
|
||||||
{ id_RFSP, { id_WCK }},
|
{id_RFSP, {id_WCK}},
|
||||||
{ id_XHRF, { id_WCK1, id_WCK2 }},
|
{id_XHRF, {id_WCK1, id_WCK2}},
|
||||||
{ id_XWRF, { id_WCK1, id_WCK2 }},
|
{id_XWRF, {id_WCK1, id_WCK2}},
|
||||||
{ id_XPRF, { id_WCK1, id_WCK2 }},
|
{id_XPRF, {id_WCK1, id_WCK2}},
|
||||||
// TILE - CDC
|
// TILE - CDC
|
||||||
{ id_CDC, { id_CK1, id_CK2 }},
|
{id_CDC, {id_CK1, id_CK2}},
|
||||||
{ id_DDE, { id_CK1, id_CK2 }},
|
{id_DDE, {id_CK1, id_CK2}},
|
||||||
{ id_TDE, { id_CK1, id_CK2 }},
|
{id_TDE, {id_CK1, id_CK2}},
|
||||||
{ id_XCDC, { id_CK1, id_CK2 }},
|
{id_XCDC, {id_CK1, id_CK2}},
|
||||||
// TILE - FIFO
|
// TILE - FIFO
|
||||||
{ id_FIFO, { id_RCK, id_WCK }},
|
{id_FIFO, {id_RCK, id_WCK}},
|
||||||
{ id_XHFIFO, { id_RCK1, id_RCK2, id_WCK1, id_WCK2 }},
|
{id_XHFIFO, {id_RCK1, id_RCK2, id_WCK1, id_WCK2}},
|
||||||
{ id_XWFIFO, { id_RCK1, id_RCK2, id_WCK1, id_WCK2 }},
|
{id_XWFIFO, {id_RCK1, id_RCK2, id_WCK1, id_WCK2}},
|
||||||
// CGB - RAM
|
// CGB - RAM
|
||||||
{ id_RAM, { id_ACK, id_BCK }},
|
{id_RAM, {id_ACK, id_BCK}},
|
||||||
// CGB - DSP
|
// CGB - DSP
|
||||||
{ id_DSP, {id_CK }},
|
{id_DSP, {id_CK}},
|
||||||
};
|
};
|
||||||
|
|
||||||
const dict<IdString,pool<IdString>> ring_clock_sinks = {
|
const dict<IdString, pool<IdString>> ring_clock_sinks = {
|
||||||
// CKG
|
// CKG
|
||||||
{ id_PLL, { id_CLK_CAL, id_FBK, id_REF }},
|
{id_PLL, {id_CLK_CAL, id_FBK, id_REF}},
|
||||||
{ id_WFB, { id_ZI }},
|
{id_WFB, {id_ZI}},
|
||||||
{ id_WFG, { id_ZI }}
|
{id_WFG, {id_ZI}}};
|
||||||
};
|
|
||||||
|
|
||||||
const dict<IdString,pool<IdString>> ring_over_tile_clock_sinks = {
|
const dict<IdString, pool<IdString>> ring_over_tile_clock_sinks = {
|
||||||
// IOB
|
// IOB
|
||||||
{ id_DFR, { id_CK }},
|
{id_DFR, {id_CK}},
|
||||||
{ id_DDFR, { id_CK, id_CKF }},
|
{id_DDFR, {id_CK, id_CKF}},
|
||||||
};
|
};
|
||||||
// IOB
|
// IOB
|
||||||
// { id_IOM, { id_ALCK1, id_ALCK2, id_ALCK3, id_CCK, id_FCK1, id_FCK2, id_FDCK,
|
// { id_IOM, { id_ALCK1, id_ALCK2, id_ALCK3, id_CCK, id_FCK1, id_FCK2, id_FDCK,
|
||||||
// id_LDSCK1, id_LDSCK2, id_LDSCK3, id_SWRX1CK, id_SWRX2CK }},
|
// id_LDSCK1, id_LDSCK2, id_LDSCK3, id_SWRX1CK, id_SWRX2CK }},
|
||||||
|
|
||||||
// HSSL
|
// HSSL
|
||||||
// { id_CRX, { id_LINK }},
|
// { id_CRX, { id_LINK }},
|
||||||
// { id_CTX, { id_LINK }},
|
// { id_CTX, { id_LINK }},
|
||||||
// { id_PMA, { id_hssl_clock_i1, id_hssl_clock_i2, id_hssl_clock_i3, id_hssl_clock_i4 },
|
// { id_PMA, { id_hssl_clock_i1, id_hssl_clock_i2, id_hssl_clock_i3, id_hssl_clock_i4 },
|
||||||
|
|
||||||
const dict<IdString,pool<IdString>> tube_clock_sinks = {
|
const dict<IdString, pool<IdString>> tube_clock_sinks = {
|
||||||
// TUBE
|
// TUBE
|
||||||
{ id_GCK, { id_SI1, id_SI2 }},
|
{id_GCK, {id_SI1, id_SI2}},
|
||||||
};
|
};
|
||||||
// Sources
|
// Sources
|
||||||
// CKG
|
// CKG
|
||||||
const dict<IdString,pool<IdString>> ring_clock_source = {
|
const dict<IdString, pool<IdString>> ring_clock_source = {
|
||||||
{ id_IOM, { id_CKO1, id_CKO2 }},
|
{id_IOM, {id_CKO1, id_CKO2}},
|
||||||
{ id_WFB, { id_ZO }},
|
{id_WFB, {id_ZO}},
|
||||||
{ id_WFG, { id_ZO }},
|
{id_WFG, {id_ZO}},
|
||||||
{ id_PLL, { id_OSC, id_VCO, id_REFO, id_LDFO,
|
{id_PLL,
|
||||||
id_CLK_DIV1, id_CLK_DIV2, id_CLK_DIV3, id_CLK_DIV4,
|
{id_OSC, id_VCO, id_REFO, id_LDFO, id_CLK_DIV1, id_CLK_DIV2, id_CLK_DIV3, id_CLK_DIV4, id_CLK_DIVD1,
|
||||||
id_CLK_DIVD1, id_CLK_DIVD2, id_CLK_DIVD3, id_CLK_DIVD4, id_CLK_DIVD5,
|
id_CLK_DIVD2, id_CLK_DIVD3, id_CLK_DIVD4, id_CLK_DIVD5, id_CLK_CAL_DIV}}};
|
||||||
id_CLK_CAL_DIV }}
|
// TUBE
|
||||||
};
|
const dict<IdString, pool<IdString>> tube_clock_source = {
|
||||||
// TUBE
|
{id_GCK, {id_SO}},
|
||||||
const dict<IdString,pool<IdString>> tube_clock_source = {
|
|
||||||
{ id_GCK, { id_SO }},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
};
|
}; // namespace
|
||||||
|
|
||||||
const dict<IdString,pool<IdString>>& NgUltraImpl::get_fabric_lowskew_sinks() { return fabric_lowskew_sinks; }
|
const dict<IdString, pool<IdString>> &NgUltraImpl::get_fabric_lowskew_sinks() { return fabric_lowskew_sinks; }
|
||||||
|
|
||||||
bool NgUltraImpl::is_fabric_lowskew_sink(const PortRef &ref)
|
bool NgUltraImpl::is_fabric_lowskew_sink(const PortRef &ref)
|
||||||
{
|
{
|
||||||
@ -197,7 +194,8 @@ bool NgUltraImpl::is_ring_clock_sink(const PortRef &ref)
|
|||||||
|
|
||||||
bool NgUltraImpl::is_ring_over_tile_clock_sink(const PortRef &ref)
|
bool NgUltraImpl::is_ring_over_tile_clock_sink(const PortRef &ref)
|
||||||
{
|
{
|
||||||
return ring_over_tile_clock_sinks.count(ref.cell->type) && ring_over_tile_clock_sinks.at(ref.cell->type).count(ref.port);
|
return ring_over_tile_clock_sinks.count(ref.cell->type) &&
|
||||||
|
ring_over_tile_clock_sinks.at(ref.cell->type).count(ref.port);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NgUltraImpl::is_tube_clock_sink(const PortRef &ref)
|
bool NgUltraImpl::is_tube_clock_sink(const PortRef &ref)
|
||||||
@ -236,10 +234,7 @@ IdString NgUltraImpl::tile_name_id(int tile) const
|
|||||||
return IdString(data.name);
|
return IdString(data.name);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string NgUltraImpl::tile_name(int tile) const
|
std::string NgUltraImpl::tile_name(int tile) const { return stringf("%s", tile_name_id(tile).c_str(ctx)); }
|
||||||
{
|
|
||||||
return stringf("%s", tile_name_id(tile).c_str(ctx));
|
|
||||||
}
|
|
||||||
|
|
||||||
int NgUltraImpl::tile_lobe(int tile) const
|
int NgUltraImpl::tile_lobe(int tile) const
|
||||||
{
|
{
|
||||||
@ -264,7 +259,8 @@ bool NgUltraImpl::get_mux_data(WireId wire, uint8_t *value)
|
|||||||
if (!ctx->getBoundPipNet(pip))
|
if (!ctx->getBoundPipNet(pip))
|
||||||
continue;
|
continue;
|
||||||
const auto &extra_data = *pip_extra_data(pip);
|
const auto &extra_data = *pip_extra_data(pip);
|
||||||
if (!extra_data.name) continue;
|
if (!extra_data.name)
|
||||||
|
continue;
|
||||||
if (extra_data.type == PipExtra::PIP_EXTRA_MUX) {
|
if (extra_data.type == PipExtra::PIP_EXTRA_MUX) {
|
||||||
*value = extra_data.input;
|
*value = extra_data.input;
|
||||||
return true;
|
return true;
|
||||||
@ -286,7 +282,7 @@ bool NgUltraImpl::update_bff_to_csc(CellInfo *cell, BelId bel, PipId dst_pip)
|
|||||||
if (!ctx->getBoundPipNet(pip2))
|
if (!ctx->getBoundPipNet(pip2))
|
||||||
continue;
|
continue;
|
||||||
IdString dst = ctx->getWireName(ctx->getPipDstWire(pip2))[1];
|
IdString dst = ctx->getWireName(ctx->getPipDstWire(pip2))[1];
|
||||||
if (boost::ends_with(dst.c_str(ctx),".DS")) {
|
if (boost::ends_with(dst.c_str(ctx), ".DS")) {
|
||||||
cell->setParam(id_type, Property("CSC"));
|
cell->setParam(id_type, Property("CSC"));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -309,7 +305,7 @@ bool NgUltraImpl::update_bff_to_scc(CellInfo *cell, BelId bel, PipId dst_pip)
|
|||||||
if (!ctx->getBoundPipNet(pip2))
|
if (!ctx->getBoundPipNet(pip2))
|
||||||
continue;
|
continue;
|
||||||
IdString dst = ctx->getWireName(ctx->getPipSrcWire(pip2))[1];
|
IdString dst = ctx->getWireName(ctx->getPipSrcWire(pip2))[1];
|
||||||
if (boost::starts_with(dst.c_str(ctx),"SYSTEM.ST1")) {
|
if (boost::starts_with(dst.c_str(ctx), "SYSTEM.ST1")) {
|
||||||
cell->setParam(id_type, Property("SCC"));
|
cell->setParam(id_type, Property("SCC"));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -330,44 +326,48 @@ void NgUltraImpl::postRoute()
|
|||||||
for (auto &w : ni->wires) {
|
for (auto &w : ni->wires) {
|
||||||
if (w.second.pip != PipId()) {
|
if (w.second.pip != PipId()) {
|
||||||
const auto &extra_data = *pip_extra_data(w.second.pip);
|
const auto &extra_data = *pip_extra_data(w.second.pip);
|
||||||
if (!extra_data.name) continue;
|
if (!extra_data.name)
|
||||||
|
continue;
|
||||||
if (extra_data.type == PipExtra::PIP_EXTRA_BYPASS) {
|
if (extra_data.type == PipExtra::PIP_EXTRA_BYPASS) {
|
||||||
IdStringList id = ctx->getPipName(w.second.pip);
|
IdStringList id = ctx->getPipName(w.second.pip);
|
||||||
BelId bel = ctx->getBelByName(IdStringList::concat(id[0], IdString(extra_data.name)));
|
BelId bel = ctx->getBelByName(IdStringList::concat(id[0], IdString(extra_data.name)));
|
||||||
IdString type = ctx->getBelType(bel);
|
IdString type = ctx->getBelType(bel);
|
||||||
if (!ctx->getBoundBelCell(bel)) {
|
if (!ctx->getBoundBelCell(bel)) {
|
||||||
CellInfo *cell = ctx->createCell(ctx->id(ctx->nameOfBel(bel)), type);
|
CellInfo *cell = ctx->createCell(ctx->id(ctx->nameOfBel(bel)), type);
|
||||||
ctx->bindBel(bel,cell,PlaceStrength::STRENGTH_FIXED);
|
ctx->bindBel(bel, cell, PlaceStrength::STRENGTH_FIXED);
|
||||||
if (type==id_BEYOND_FE) fe_new++;
|
if (type == id_BEYOND_FE)
|
||||||
|
fe_new++;
|
||||||
}
|
}
|
||||||
CellInfo *cell = ctx->getBoundBelCell(bel);
|
CellInfo *cell = ctx->getBoundBelCell(bel);
|
||||||
switch(type.index) {
|
switch (type.index) {
|
||||||
case id_BEYOND_FE.index :
|
case id_BEYOND_FE.index:
|
||||||
if (extra_data.input==0) {
|
if (extra_data.input == 0) {
|
||||||
// set bypass mode for DFF
|
// set bypass mode for DFF
|
||||||
cell->setParam(id_type, Property("BFF"));
|
cell->setParam(id_type, Property("BFF"));
|
||||||
cell->params[id_dff_used] = Property(1,1);
|
cell->params[id_dff_used] = Property(1, 1);
|
||||||
// Note: no conflict, CSC and SCC modes are never available on same position
|
// Note: no conflict, CSC and SCC modes are never available on same position
|
||||||
if (update_bff_to_csc(cell, bel, w.second.pip))
|
if (update_bff_to_csc(cell, bel, w.second.pip))
|
||||||
csc_count++;
|
csc_count++;
|
||||||
else if(update_bff_to_scc(cell, bel, w.second.pip))
|
else if (update_bff_to_scc(cell, bel, w.second.pip))
|
||||||
scc_count++;
|
scc_count++;
|
||||||
else
|
else
|
||||||
bff_count++;
|
bff_count++;
|
||||||
} else {
|
} else {
|
||||||
lut_bypass++;
|
lut_bypass++;
|
||||||
cell->params[id_lut_used] = Property(1,1);
|
cell->params[id_lut_used] = Property(1, 1);
|
||||||
cell->params[id_lut_table] = Property(0xaaaa, 16);
|
cell->params[id_lut_table] = Property(0xaaaa, 16);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case id_WFG.index : wfg_bypass++;
|
case id_WFG.index:
|
||||||
|
wfg_bypass++;
|
||||||
cell->type = id_WFB;
|
cell->type = id_WFB;
|
||||||
break;
|
break;
|
||||||
case id_GCK.index : gck_bypass++;
|
case id_GCK.index:
|
||||||
|
gck_bypass++;
|
||||||
cell->setParam(id_std_mode, extra_data.input == 0 ? Property("BYPASS") : Property("CSC"));
|
cell->setParam(id_std_mode, extra_data.input == 0 ? Property("BYPASS") : Property("CSC"));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
log_error("Unmaped bel type '%s' for routing\n",type.c_str(ctx));
|
log_error("Unmaped bel type '%s' for routing\n", type.c_str(ctx));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -379,7 +379,7 @@ void NgUltraImpl::postRoute()
|
|||||||
log_info(" %6d DFFs used as CSC\n", csc_count);
|
log_info(" %6d DFFs used as CSC\n", csc_count);
|
||||||
if (scc_count)
|
if (scc_count)
|
||||||
log_info(" %6d DFFs used as SCC\n", scc_count);
|
log_info(" %6d DFFs used as SCC\n", scc_count);
|
||||||
if(lut_bypass)
|
if (lut_bypass)
|
||||||
log_info(" %6d LUTs used in bypass mode\n", lut_bypass);
|
log_info(" %6d LUTs used in bypass mode\n", lut_bypass);
|
||||||
if (fe_new)
|
if (fe_new)
|
||||||
log_info(" %6d newly allocated FEs\n", fe_new);
|
log_info(" %6d newly allocated FEs\n", fe_new);
|
||||||
@ -402,7 +402,8 @@ void NgUltraImpl::postRoute()
|
|||||||
if (!ctx->getBoundPipNet(pip))
|
if (!ctx->getBoundPipNet(pip))
|
||||||
continue;
|
continue;
|
||||||
const auto &extra_data = *pip_extra_data(pip);
|
const auto &extra_data = *pip_extra_data(pip);
|
||||||
if (!extra_data.name) continue;
|
if (!extra_data.name)
|
||||||
|
continue;
|
||||||
if (extra_data.type == PipExtra::PIP_EXTRA_LUT_PERMUTATION) {
|
if (extra_data.type == PipExtra::PIP_EXTRA_LUT_PERMUTATION) {
|
||||||
NPNR_ASSERT(extra_data.output == i);
|
NPNR_ASSERT(extra_data.output == i);
|
||||||
phys_to_log[extra_data.input].push_back(i);
|
phys_to_log[extra_data.input].push_back(i);
|
||||||
@ -443,7 +444,7 @@ void NgUltraImpl::configurePlacerHeap(PlacerHeapCfg &cfg)
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
template <size_t N> bool check_assign_sig(std::array<const NetInfo*, N> &sig_set, const NetInfo *sig)
|
template <size_t N> bool check_assign_sig(std::array<const NetInfo *, N> &sig_set, const NetInfo *sig)
|
||||||
{
|
{
|
||||||
if (sig == nullptr)
|
if (sig == nullptr)
|
||||||
return true;
|
return true;
|
||||||
@ -464,11 +465,11 @@ struct SectionFEWorker
|
|||||||
std::array<const NetInfo *, 2> load{}; // from local system matrix
|
std::array<const NetInfo *, 2> load{}; // from local system matrix
|
||||||
std::array<const NetInfo *, 1> shared{}; // 1 from local system matrix
|
std::array<const NetInfo *, 1> shared{}; // 1 from local system matrix
|
||||||
// Additional R and L can be used from RI network
|
// Additional R and L can be used from RI network
|
||||||
bool run(const NgUltraImpl *impl,const Context *ctx, BelId bel, CellInfo *cell)
|
bool run(const NgUltraImpl *impl, const Context *ctx, BelId bel, CellInfo *cell)
|
||||||
{
|
{
|
||||||
Loc loc = ctx->getBelLocation(bel);
|
Loc loc = ctx->getBelLocation(bel);
|
||||||
for (uint8_t id = 0; id <= BEL_LUT_MAX_Z; id++) {
|
for (uint8_t id = 0; id <= BEL_LUT_MAX_Z; id++) {
|
||||||
const CellInfo *ff = ctx->getBoundBelCell(ctx->getBelByLocation(Loc(loc.x,loc.y,id)));
|
const CellInfo *ff = ctx->getBoundBelCell(ctx->getBelByLocation(Loc(loc.x, loc.y, id)));
|
||||||
if (ff == nullptr)
|
if (ff == nullptr)
|
||||||
continue;
|
continue;
|
||||||
if (!check_assign_sig(reset, ff->getPort(id_R))) {
|
if (!check_assign_sig(reset, ff->getPort(id_R))) {
|
||||||
@ -485,8 +486,10 @@ struct SectionFEWorker
|
|||||||
const auto &extra_data = *impl->bel_extra_data(bel);
|
const auto &extra_data = *impl->bel_extra_data(bel);
|
||||||
if (cell->params.count(id_type)) {
|
if (cell->params.count(id_type)) {
|
||||||
const std::string &type = cell->params[id_type].as_string();
|
const std::string &type = cell->params[id_type].as_string();
|
||||||
if (type=="CSC" && (extra_data.flags & BEL_EXTRA_FE_CSC) == 0) return false; // No CSC capability on FE
|
if (type == "CSC" && (extra_data.flags & BEL_EXTRA_FE_CSC) == 0)
|
||||||
if (type=="SCC" && (extra_data.flags & BEL_EXTRA_FE_SCC) == 0) return false; // No SCC capability on FE
|
return false; // No CSC capability on FE
|
||||||
|
if (type == "SCC" && (extra_data.flags & BEL_EXTRA_FE_SCC) == 0)
|
||||||
|
return false; // No SCC capability on FE
|
||||||
}
|
}
|
||||||
if (extra_data.flags & BEL_EXTRA_FE_CSC)
|
if (extra_data.flags & BEL_EXTRA_FE_CSC)
|
||||||
return false;
|
return false;
|
||||||
@ -505,83 +508,109 @@ bool NgUltraImpl::isBelLocationValid(BelId bel, bool explain_invalid) const
|
|||||||
if (ctx->getBelType(bel) == id_BEYOND_FE) {
|
if (ctx->getBelType(bel) == id_BEYOND_FE) {
|
||||||
SectionFEWorker worker;
|
SectionFEWorker worker;
|
||||||
return worker.run(this, ctx, bel, cell);
|
return worker.run(this, ctx, bel, cell);
|
||||||
}
|
} else if (ctx->getBelType(bel).in(id_RF, id_XRF)) {
|
||||||
else if (ctx->getBelType(bel).in(id_RF, id_XRF)) {
|
|
||||||
Loc loc = ctx->getBelLocation(bel);
|
Loc loc = ctx->getBelLocation(bel);
|
||||||
if (loc.z == BEL_XRF_Z) {
|
if (loc.z == BEL_XRF_Z) {
|
||||||
// If we used any of RFs we can not used XRF
|
// If we used any of RFs we can not used XRF
|
||||||
if (ctx->getBoundBelCell(ctx->getBelByLocation(Loc(loc.x,loc.y,BEL_RF_Z)))) return false;
|
if (ctx->getBoundBelCell(ctx->getBelByLocation(Loc(loc.x, loc.y, BEL_RF_Z))))
|
||||||
if (ctx->getBoundBelCell(ctx->getBelByLocation(Loc(loc.x,loc.y,BEL_RF_Z+1)))) return false;
|
return false;
|
||||||
|
if (ctx->getBoundBelCell(ctx->getBelByLocation(Loc(loc.x, loc.y, BEL_RF_Z + 1))))
|
||||||
|
return false;
|
||||||
// If we used any FIFO we can not use XRF
|
// If we used any FIFO we can not use XRF
|
||||||
if (ctx->getBoundBelCell(ctx->getBelByLocation(Loc(loc.x,loc.y,BEL_FIFO_Z)))) return false;
|
if (ctx->getBoundBelCell(ctx->getBelByLocation(Loc(loc.x, loc.y, BEL_FIFO_Z))))
|
||||||
if (ctx->getBoundBelCell(ctx->getBelByLocation(Loc(loc.x,loc.y,BEL_FIFO_Z+1)))) return false;
|
return false;
|
||||||
|
if (ctx->getBoundBelCell(ctx->getBelByLocation(Loc(loc.x, loc.y, BEL_FIFO_Z + 1))))
|
||||||
|
return false;
|
||||||
// If we used XFIFO we can not use XRF
|
// If we used XFIFO we can not use XRF
|
||||||
if (ctx->getBoundBelCell(ctx->getBelByLocation(Loc(loc.x,loc.y,BEL_XFIFO_Z)))) return false;
|
if (ctx->getBoundBelCell(ctx->getBelByLocation(Loc(loc.x, loc.y, BEL_XFIFO_Z))))
|
||||||
|
return false;
|
||||||
} else {
|
} else {
|
||||||
// If we used XRF we can not use individual RF
|
// If we used XRF we can not use individual RF
|
||||||
if (ctx->getBoundBelCell(ctx->getBelByLocation(Loc(loc.x,loc.y,BEL_XRF_Z)))) return false;
|
if (ctx->getBoundBelCell(ctx->getBelByLocation(Loc(loc.x, loc.y, BEL_XRF_Z))))
|
||||||
|
return false;
|
||||||
// If we used XFIFO we can not use RF
|
// If we used XFIFO we can not use RF
|
||||||
if (ctx->getBoundBelCell(ctx->getBelByLocation(Loc(loc.x,loc.y,BEL_XFIFO_Z)))) return false;
|
if (ctx->getBoundBelCell(ctx->getBelByLocation(Loc(loc.x, loc.y, BEL_XFIFO_Z))))
|
||||||
|
return false;
|
||||||
int index = loc.z - BEL_RF_Z;
|
int index = loc.z - BEL_RF_Z;
|
||||||
// If we used coresponding FIFO we can not use RF
|
// If we used coresponding FIFO we can not use RF
|
||||||
if (ctx->getBoundBelCell(ctx->getBelByLocation(Loc(loc.x,loc.y,BEL_FIFO_Z + index)))) return false;
|
if (ctx->getBoundBelCell(ctx->getBelByLocation(Loc(loc.x, loc.y, BEL_FIFO_Z + index))))
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
} else if (ctx->getBelType(bel).in(id_FIFO, id_XFIFO)) {
|
||||||
else if (ctx->getBelType(bel).in(id_FIFO, id_XFIFO)) {
|
|
||||||
Loc loc = ctx->getBelLocation(bel);
|
Loc loc = ctx->getBelLocation(bel);
|
||||||
if (loc.z == BEL_XFIFO_Z) {
|
if (loc.z == BEL_XFIFO_Z) {
|
||||||
// If we used any of RFs we can not used XFIFO
|
// If we used any of RFs we can not used XFIFO
|
||||||
if (ctx->getBoundBelCell(ctx->getBelByLocation(Loc(loc.x,loc.y,BEL_RF_Z)))) return false;
|
if (ctx->getBoundBelCell(ctx->getBelByLocation(Loc(loc.x, loc.y, BEL_RF_Z))))
|
||||||
if (ctx->getBoundBelCell(ctx->getBelByLocation(Loc(loc.x,loc.y,BEL_RF_Z+1)))) return false;
|
return false;
|
||||||
|
if (ctx->getBoundBelCell(ctx->getBelByLocation(Loc(loc.x, loc.y, BEL_RF_Z + 1))))
|
||||||
|
return false;
|
||||||
// If we used any FIFO we can not use XFIFO
|
// If we used any FIFO we can not use XFIFO
|
||||||
if (ctx->getBoundBelCell(ctx->getBelByLocation(Loc(loc.x,loc.y,BEL_FIFO_Z)))) return false;
|
if (ctx->getBoundBelCell(ctx->getBelByLocation(Loc(loc.x, loc.y, BEL_FIFO_Z))))
|
||||||
if (ctx->getBoundBelCell(ctx->getBelByLocation(Loc(loc.x,loc.y,BEL_FIFO_Z+1)))) return false;
|
return false;
|
||||||
|
if (ctx->getBoundBelCell(ctx->getBelByLocation(Loc(loc.x, loc.y, BEL_FIFO_Z + 1))))
|
||||||
|
return false;
|
||||||
// If we used XFIFO we can not use XFIFO
|
// If we used XFIFO we can not use XFIFO
|
||||||
if (ctx->getBoundBelCell(ctx->getBelByLocation(Loc(loc.x,loc.y,BEL_XFIFO_Z)))) return false;
|
if (ctx->getBoundBelCell(ctx->getBelByLocation(Loc(loc.x, loc.y, BEL_XFIFO_Z))))
|
||||||
|
return false;
|
||||||
// If we used any CDC we can not use XFIFO
|
// If we used any CDC we can not use XFIFO
|
||||||
// NOTE: CDC1 is in S4 and CDC2 is S12
|
// NOTE: CDC1 is in S4 and CDC2 is S12
|
||||||
if (ctx->getBoundBelCell(ctx->getBelByLocation(Loc(loc.x-1,loc.y,BEL_CDC_Z)))) return false;
|
if (ctx->getBoundBelCell(ctx->getBelByLocation(Loc(loc.x - 1, loc.y, BEL_CDC_Z))))
|
||||||
if (ctx->getBoundBelCell(ctx->getBelByLocation(Loc(loc.x+1,loc.y,BEL_CDC_Z+1)))) return false;
|
return false;
|
||||||
|
if (ctx->getBoundBelCell(ctx->getBelByLocation(Loc(loc.x + 1, loc.y, BEL_CDC_Z + 1))))
|
||||||
|
return false;
|
||||||
// If we used XCDC we can not use XFIFO
|
// If we used XCDC we can not use XFIFO
|
||||||
if (ctx->getBoundBelCell(ctx->getBelByLocation(Loc(loc.x,loc.y,BEL_XCDC_Z)))) return false;
|
if (ctx->getBoundBelCell(ctx->getBelByLocation(Loc(loc.x, loc.y, BEL_XCDC_Z))))
|
||||||
|
return false;
|
||||||
} else {
|
} else {
|
||||||
// If we used XFIFO we can not use individual FIFO
|
// If we used XFIFO we can not use individual FIFO
|
||||||
if (ctx->getBoundBelCell(ctx->getBelByLocation(Loc(loc.x,loc.y,BEL_XFIFO_Z)))) return false;
|
if (ctx->getBoundBelCell(ctx->getBelByLocation(Loc(loc.x, loc.y, BEL_XFIFO_Z))))
|
||||||
|
return false;
|
||||||
// If we used XRF we can not use FIFO
|
// If we used XRF we can not use FIFO
|
||||||
if (ctx->getBoundBelCell(ctx->getBelByLocation(Loc(loc.x,loc.y,BEL_XRF_Z)))) return false;
|
if (ctx->getBoundBelCell(ctx->getBelByLocation(Loc(loc.x, loc.y, BEL_XRF_Z))))
|
||||||
|
return false;
|
||||||
// If we used XCDC we can not use FIFO
|
// If we used XCDC we can not use FIFO
|
||||||
if (ctx->getBoundBelCell(ctx->getBelByLocation(Loc(loc.x,loc.y,BEL_XCDC_Z)))) return false;
|
if (ctx->getBoundBelCell(ctx->getBelByLocation(Loc(loc.x, loc.y, BEL_XCDC_Z))))
|
||||||
|
return false;
|
||||||
int index = loc.z - BEL_FIFO_Z;
|
int index = loc.z - BEL_FIFO_Z;
|
||||||
// If we used coresponding RF we can not use FIFO
|
// If we used coresponding RF we can not use FIFO
|
||||||
if (ctx->getBoundBelCell(ctx->getBelByLocation(Loc(loc.x,loc.y,BEL_RF_Z + index)))) return false;
|
if (ctx->getBoundBelCell(ctx->getBelByLocation(Loc(loc.x, loc.y, BEL_RF_Z + index))))
|
||||||
|
return false;
|
||||||
// If we used coresponding CDC we can not use FIFO
|
// If we used coresponding CDC we can not use FIFO
|
||||||
// NOTE: CDC1 is in S4 and CDC2 is S12
|
// NOTE: CDC1 is in S4 and CDC2 is S12
|
||||||
int rel = (index == 0) ? -1 : +1;
|
int rel = (index == 0) ? -1 : +1;
|
||||||
if (ctx->getBoundBelCell(ctx->getBelByLocation(Loc(loc.x + rel,loc.y,BEL_CDC_Z + index)))) return false;
|
if (ctx->getBoundBelCell(ctx->getBelByLocation(Loc(loc.x + rel, loc.y, BEL_CDC_Z + index))))
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
} else if (ctx->getBelType(bel).in(id_CDC, id_XCDC)) {
|
||||||
else if (ctx->getBelType(bel).in(id_CDC, id_XCDC)) {
|
|
||||||
Loc loc = ctx->getBelLocation(bel);
|
Loc loc = ctx->getBelLocation(bel);
|
||||||
if (loc.z == BEL_XCDC_Z) {
|
if (loc.z == BEL_XCDC_Z) {
|
||||||
// If we used any of CDCs we can not used XCDC
|
// If we used any of CDCs we can not used XCDC
|
||||||
// NOTE: CDC1 is in S4 and CDC2 is S12
|
// NOTE: CDC1 is in S4 and CDC2 is S12
|
||||||
if (ctx->getBoundBelCell(ctx->getBelByLocation(Loc(loc.x-1,loc.y,BEL_CDC_Z)))) return false;
|
if (ctx->getBoundBelCell(ctx->getBelByLocation(Loc(loc.x - 1, loc.y, BEL_CDC_Z))))
|
||||||
if (ctx->getBoundBelCell(ctx->getBelByLocation(Loc(loc.x+1,loc.y,BEL_CDC_Z+1)))) return false;
|
return false;
|
||||||
|
if (ctx->getBoundBelCell(ctx->getBelByLocation(Loc(loc.x + 1, loc.y, BEL_CDC_Z + 1))))
|
||||||
|
return false;
|
||||||
// If we used any FIFO we can not use XCDC
|
// If we used any FIFO we can not use XCDC
|
||||||
if (ctx->getBoundBelCell(ctx->getBelByLocation(Loc(loc.x,loc.y,BEL_FIFO_Z)))) return false;
|
if (ctx->getBoundBelCell(ctx->getBelByLocation(Loc(loc.x, loc.y, BEL_FIFO_Z))))
|
||||||
if (ctx->getBoundBelCell(ctx->getBelByLocation(Loc(loc.x,loc.y,BEL_FIFO_Z+1)))) return false;
|
return false;
|
||||||
|
if (ctx->getBoundBelCell(ctx->getBelByLocation(Loc(loc.x, loc.y, BEL_FIFO_Z + 1))))
|
||||||
|
return false;
|
||||||
// If we used XFIFO we can not use XCDC
|
// If we used XFIFO we can not use XCDC
|
||||||
if (ctx->getBoundBelCell(ctx->getBelByLocation(Loc(loc.x,loc.y,BEL_XFIFO_Z)))) return false;
|
if (ctx->getBoundBelCell(ctx->getBelByLocation(Loc(loc.x, loc.y, BEL_XFIFO_Z))))
|
||||||
|
return false;
|
||||||
} else {
|
} else {
|
||||||
// NOTE: CDC1 is in S4 and CDC2 is S12 so we move calculation relative to S8
|
// NOTE: CDC1 is in S4 and CDC2 is S12 so we move calculation relative to S8
|
||||||
int index = loc.z - BEL_CDC_Z;
|
int index = loc.z - BEL_CDC_Z;
|
||||||
int fix = (index == 0) ? +1 : -1;
|
int fix = (index == 0) ? +1 : -1;
|
||||||
// If we used XCDC we can not use individual CDC
|
// If we used XCDC we can not use individual CDC
|
||||||
if (ctx->getBoundBelCell(ctx->getBelByLocation(Loc(loc.x+fix,loc.y,BEL_XCDC_Z)))) return false;
|
if (ctx->getBoundBelCell(ctx->getBelByLocation(Loc(loc.x + fix, loc.y, BEL_XCDC_Z))))
|
||||||
|
return false;
|
||||||
// If we used XFIFO we can not use CDC
|
// If we used XFIFO we can not use CDC
|
||||||
if (ctx->getBoundBelCell(ctx->getBelByLocation(Loc(loc.x+fix,loc.y,BEL_XFIFO_Z)))) return false;
|
if (ctx->getBoundBelCell(ctx->getBelByLocation(Loc(loc.x + fix, loc.y, BEL_XFIFO_Z))))
|
||||||
|
return false;
|
||||||
// If we used coresponding FIFO we can not use CDC
|
// If we used coresponding FIFO we can not use CDC
|
||||||
if (ctx->getBoundBelCell(ctx->getBelByLocation(Loc(loc.x+fix,loc.y,BEL_FIFO_Z + index)))) return false;
|
if (ctx->getBoundBelCell(ctx->getBelByLocation(Loc(loc.x + fix, loc.y, BEL_FIFO_Z + index))))
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@ -590,7 +619,7 @@ bool NgUltraImpl::isBelLocationValid(BelId bel, bool explain_invalid) const
|
|||||||
// Bel bucket functions
|
// Bel bucket functions
|
||||||
IdString NgUltraImpl::getBelBucketForCellType(IdString cell_type) const
|
IdString NgUltraImpl::getBelBucketForCellType(IdString cell_type) const
|
||||||
{
|
{
|
||||||
if (cell_type.in(id_IOP,id_IP,id_OP,id_IOTP,id_ITP,id_OTP))
|
if (cell_type.in(id_IOP, id_IP, id_OP, id_IOTP, id_ITP, id_OTP))
|
||||||
return ctx->idf("IOP/IOTP");
|
return ctx->idf("IOP/IOTP");
|
||||||
else if (cell_type.in(id_BFR, id_DFR, id_DDFR))
|
else if (cell_type.in(id_BFR, id_DFR, id_DDFR))
|
||||||
return ctx->idf("DFR/DDFR");
|
return ctx->idf("DFR/DDFR");
|
||||||
@ -626,17 +655,17 @@ bool NgUltraImpl::isValidBelForCellType(IdString cell_type, BelId bel) const
|
|||||||
{
|
{
|
||||||
IdString bel_type = ctx->getBelType(bel);
|
IdString bel_type = ctx->getBelType(bel);
|
||||||
if (bel_type == id_IOTP)
|
if (bel_type == id_IOTP)
|
||||||
return cell_type.in(id_IOP,id_IP,id_OP,id_IOTP,id_ITP,id_OTP);
|
return cell_type.in(id_IOP, id_IP, id_OP, id_IOTP, id_ITP, id_OTP);
|
||||||
else if (bel_type == id_IOP)
|
else if (bel_type == id_IOP)
|
||||||
return cell_type.in(id_IOP,id_IP,id_OP);
|
return cell_type.in(id_IOP, id_IP, id_OP);
|
||||||
else if (bel_type == id_DDFR)
|
else if (bel_type == id_DDFR)
|
||||||
return cell_type.in(id_BFR,id_DFR,id_DDFR);
|
return cell_type.in(id_BFR, id_DFR, id_DDFR);
|
||||||
else if (bel_type == id_DFR)
|
else if (bel_type == id_DFR)
|
||||||
return cell_type.in(id_BFR,id_DFR);
|
return cell_type.in(id_BFR, id_DFR);
|
||||||
else if (bel_type == id_RF)
|
else if (bel_type == id_RF)
|
||||||
return cell_type.in(id_RF,id_RFSP);
|
return cell_type.in(id_RF, id_RFSP);
|
||||||
else if (bel_type == id_XRF)
|
else if (bel_type == id_XRF)
|
||||||
return cell_type.in(id_XHRF,id_XWRF,id_XPRF);
|
return cell_type.in(id_XHRF, id_XWRF, id_XPRF);
|
||||||
else if (bel_type == id_CDC)
|
else if (bel_type == id_CDC)
|
||||||
return cell_type.in(id_DDE, id_TDE, id_CDC, id_BGC, id_GBC);
|
return cell_type.in(id_DDE, id_TDE, id_CDC, id_BGC, id_GBC);
|
||||||
else if (bel_type == id_XCDC)
|
else if (bel_type == id_XCDC)
|
||||||
@ -646,7 +675,7 @@ bool NgUltraImpl::isValidBelForCellType(IdString cell_type, BelId bel) const
|
|||||||
else if (bel_type == id_XFIFO)
|
else if (bel_type == id_XFIFO)
|
||||||
return cell_type.in(id_XHFIFO, id_XWFIFO);
|
return cell_type.in(id_XHFIFO, id_XWFIFO);
|
||||||
else if (bel_type == id_WFG)
|
else if (bel_type == id_WFG)
|
||||||
return cell_type.in(id_WFB,id_WFG);
|
return cell_type.in(id_WFB, id_WFG);
|
||||||
else
|
else
|
||||||
return (bel_type == cell_type);
|
return (bel_type == cell_type);
|
||||||
}
|
}
|
||||||
@ -657,19 +686,38 @@ bool NgUltraImpl::getChildPlacement(const BaseClusterInfo *cluster, Loc root_loc
|
|||||||
Loc prev = root_loc;
|
Loc prev = root_loc;
|
||||||
for (auto child : cluster->constr_children) {
|
for (auto child : cluster->constr_children) {
|
||||||
Loc child_loc;
|
Loc child_loc;
|
||||||
switch(child->constr_z) {
|
switch (child->constr_z) {
|
||||||
case PLACE_CY_CHAIN :child_loc = getNextLocInCYChain(prev); prev = child_loc; break;
|
case PLACE_CY_CHAIN:
|
||||||
case PLACE_LUT_CHAIN : child_loc = getNextLocInLUTChain(prev); prev = child_loc; break;
|
child_loc = getNextLocInCYChain(prev);
|
||||||
case PLACE_DFF_CHAIN : child_loc = getNextLocInDFFChain(prev); prev = child_loc; break;
|
prev = child_loc;
|
||||||
case PLACE_CY_FE1 ... PLACE_CY_FE4: child_loc = getCYFE(root_loc, child->constr_z - PLACE_CY_FE1 ); break;
|
break;
|
||||||
case PLACE_XLUT_FE1 ... PLACE_XLUT_FE4: child_loc = getXLUTFE(root_loc, child->constr_z - PLACE_XLUT_FE1 );break;
|
case PLACE_LUT_CHAIN:
|
||||||
|
child_loc = getNextLocInLUTChain(prev);
|
||||||
|
prev = child_loc;
|
||||||
|
break;
|
||||||
|
case PLACE_DFF_CHAIN:
|
||||||
|
child_loc = getNextLocInDFFChain(prev);
|
||||||
|
prev = child_loc;
|
||||||
|
break;
|
||||||
|
case PLACE_CY_FE1 ... PLACE_CY_FE4:
|
||||||
|
child_loc = getCYFE(root_loc, child->constr_z - PLACE_CY_FE1);
|
||||||
|
break;
|
||||||
|
case PLACE_XLUT_FE1 ... PLACE_XLUT_FE4:
|
||||||
|
child_loc = getXLUTFE(root_loc, child->constr_z - PLACE_XLUT_FE1);
|
||||||
|
break;
|
||||||
case PLACE_XRF_I1 ... PLACE_XRF_WEA:
|
case PLACE_XRF_I1 ... PLACE_XRF_WEA:
|
||||||
child_loc = getXRFFE(root_loc, child->constr_z - PLACE_XRF_I1 ); break;
|
child_loc = getXRFFE(root_loc, child->constr_z - PLACE_XRF_I1);
|
||||||
|
break;
|
||||||
case PLACE_CDC_AI1 ... PLACE_CDC_DDRSTI:
|
case PLACE_CDC_AI1 ... PLACE_CDC_DDRSTI:
|
||||||
child_loc = getCDCFE(root_loc, child->constr_z - PLACE_CDC_AI1 ); break;
|
child_loc = getCDCFE(root_loc, child->constr_z - PLACE_CDC_AI1);
|
||||||
|
break;
|
||||||
case PLACE_FIFO_I1 ... PLACE_FIFO_REQ2:
|
case PLACE_FIFO_I1 ... PLACE_FIFO_REQ2:
|
||||||
child_loc = getFIFOFE(root_loc, child->constr_z - PLACE_FIFO_I1 ); break;
|
child_loc = getFIFOFE(root_loc, child->constr_z - PLACE_FIFO_I1);
|
||||||
case PLACE_DSP_CHAIN : child_loc = getNextLocInDSPChain(this, prev); prev = child_loc; break;
|
break;
|
||||||
|
case PLACE_DSP_CHAIN:
|
||||||
|
child_loc = getNextLocInDSPChain(this, prev);
|
||||||
|
prev = child_loc;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
child_loc.x = root_loc.x + child->constr_x;
|
child_loc.x = root_loc.x + child->constr_x;
|
||||||
child_loc.y = root_loc.y + child->constr_y;
|
child_loc.y = root_loc.y + child->constr_y;
|
||||||
@ -679,7 +727,8 @@ bool NgUltraImpl::getChildPlacement(const BaseClusterInfo *cluster, Loc root_loc
|
|||||||
if (child_bel == BelId() || !this->isValidBelForCellType(child->type, child_bel))
|
if (child_bel == BelId() || !this->isValidBelForCellType(child->type, child_bel))
|
||||||
return false;
|
return false;
|
||||||
placement.emplace_back(child, child_bel);
|
placement.emplace_back(child, child_bel);
|
||||||
if (!getChildPlacement(child, child_loc, placement)) return false;
|
if (!getChildPlacement(child, child_loc, placement))
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -704,8 +753,8 @@ bool NgUltraImpl::getClusterPlacement(ClusterId cluster, BelId root_bel,
|
|||||||
|
|
||||||
BoundingBox NgUltraImpl::getRouteBoundingBox(WireId src, WireId dst) const
|
BoundingBox NgUltraImpl::getRouteBoundingBox(WireId src, WireId dst) const
|
||||||
{
|
{
|
||||||
if ((tile_type(src.tile)!=TILE_EXTRA_FABRIC || tile_type(dst.tile)!=TILE_EXTRA_FABRIC)) {
|
if ((tile_type(src.tile) != TILE_EXTRA_FABRIC || tile_type(dst.tile) != TILE_EXTRA_FABRIC)) {
|
||||||
return { 0, 0, ctx->getGridDimX(), ctx->getGridDimY() };
|
return {0, 0, ctx->getGridDimX(), ctx->getGridDimY()};
|
||||||
}
|
}
|
||||||
int x0, y0, x1, y1;
|
int x0, y0, x1, y1;
|
||||||
auto expand = [&](int x, int y) {
|
auto expand = [&](int x, int y) {
|
||||||
@ -721,9 +770,9 @@ BoundingBox NgUltraImpl::getRouteBoundingBox(WireId src, WireId dst) const
|
|||||||
tile_xy(ctx->chip_info, dst.tile, dx, dy);
|
tile_xy(ctx->chip_info, dst.tile, dx, dy);
|
||||||
expand(dx, dy);
|
expand(dx, dy);
|
||||||
// Reach 7 MESH above and below (3 left and 3 right of TILE/CGB)
|
// Reach 7 MESH above and below (3 left and 3 right of TILE/CGB)
|
||||||
return {(x0 & 0xfffc) - 3*4, // 3 MESH on left
|
return {(x0 & 0xfffc) - 3 * 4, // 3 MESH on left
|
||||||
(y0 & 0xfffc) - 4, // row above
|
(y0 & 0xfffc) - 4, // row above
|
||||||
(x1 & 0xfffc) + 4*4, // MESH bellow and 3 right
|
(x1 & 0xfffc) + 4 * 4, // MESH bellow and 3 right
|
||||||
(y1 & 0xfffc) + 8}; // current and row bellow
|
(y1 & 0xfffc) + 8}; // current and row bellow
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -743,39 +792,38 @@ delay_t NgUltraImpl::estimateDelay(WireId src, WireId dst) const
|
|||||||
int sx, sy, dx, dy;
|
int sx, sy, dx, dy;
|
||||||
tile_xy(ctx->chip_info, src.tile, sx, sy);
|
tile_xy(ctx->chip_info, src.tile, sx, sy);
|
||||||
tile_xy(ctx->chip_info, dst.tile, dx, dy);
|
tile_xy(ctx->chip_info, dst.tile, dx, dy);
|
||||||
if (sx==dx && sy==dy) {
|
if (sx == dx && sy == dy) {
|
||||||
// Same sub tile
|
// Same sub tile
|
||||||
return 50;
|
return 50;
|
||||||
} else if (((sx & 0xfffc) == (dx & 0xfffc)) && ((sy & 0xfffc) == (dy & 0xfffc))) {
|
} else if (((sx & 0xfffc) == (dx & 0xfffc)) && ((sy & 0xfffc) == (dy & 0xfffc))) {
|
||||||
// Same "TILE"
|
// Same "TILE"
|
||||||
return 200;
|
return 200;
|
||||||
}
|
}
|
||||||
return 500 + 100 * (std::abs(dy - sy)/4 + std::abs(dx - sx)/4);
|
return 500 + 100 * (std::abs(dy - sy) / 4 + std::abs(dx - sx) / 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
delay_t NgUltraImpl::predictDelay(BelId src_bel, IdString src_pin, BelId dst_bel, IdString dst_pin) const
|
delay_t NgUltraImpl::predictDelay(BelId src_bel, IdString src_pin, BelId dst_bel, IdString dst_pin) const
|
||||||
{
|
{
|
||||||
Loc src_loc = ctx->getBelLocation(src_bel), dst_loc = ctx->getBelLocation(dst_bel);
|
Loc src_loc = ctx->getBelLocation(src_bel), dst_loc = ctx->getBelLocation(dst_bel);
|
||||||
if (src_loc.x==dst_loc.x && src_loc.y==dst_loc.y) {
|
if (src_loc.x == dst_loc.x && src_loc.y == dst_loc.y) {
|
||||||
// Same sub tile
|
// Same sub tile
|
||||||
return 50;
|
return 50;
|
||||||
} else if (((src_loc.x & 0xfffc) == (dst_loc.x & 0xfffc)) && ((src_loc.y & 0xfffc) == (dst_loc.y & 0xfffc))) {
|
} else if (((src_loc.x & 0xfffc) == (dst_loc.x & 0xfffc)) && ((src_loc.y & 0xfffc) == (dst_loc.y & 0xfffc))) {
|
||||||
// Same "TILE"
|
// Same "TILE"
|
||||||
return 200;
|
return 200;
|
||||||
}
|
}
|
||||||
return 500 + 100 * (std::abs(dst_loc.y - src_loc.y)/4 + std::abs(dst_loc.x - src_loc.x)/4);
|
return 500 + 100 * (std::abs(dst_loc.y - src_loc.y) / 4 + std::abs(dst_loc.x - src_loc.x) / 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
void NgUltraImpl::fixup_crossbars()
|
void NgUltraImpl::fixup_crossbars()
|
||||||
{
|
{
|
||||||
|
|
||||||
auto is_crossbar_pip = [&] (PipId pip) {
|
auto is_crossbar_pip = [&](PipId pip) {
|
||||||
const auto &extra_data = *pip_extra_data(pip);
|
const auto &extra_data = *pip_extra_data(pip);
|
||||||
return (extra_data.name && extra_data.type == PipExtra::PIP_EXTRA_CROSSBAR);
|
return (extra_data.name && extra_data.type == PipExtra::PIP_EXTRA_CROSSBAR);
|
||||||
};
|
};
|
||||||
|
|
||||||
auto crossbar_key = [&] (PipId pip) {
|
auto crossbar_key = [&](PipId pip) {
|
||||||
const auto &extra_data = *pip_extra_data(pip);
|
const auto &extra_data = *pip_extra_data(pip);
|
||||||
return std::make_pair(pip.tile, IdString(extra_data.name));
|
return std::make_pair(pip.tile, IdString(extra_data.name));
|
||||||
};
|
};
|
||||||
@ -823,7 +871,8 @@ void NgUltraImpl::fixup_crossbars()
|
|||||||
}
|
}
|
||||||
NPNR_ASSERT(found_pip != PipId());
|
NPNR_ASSERT(found_pip != PipId());
|
||||||
// rebind
|
// rebind
|
||||||
//log_info(" replacing crossbar pip %s with %s on %s\n", ctx->nameOfPip(pip), ctx->nameOfPip(found_pip), ctx->nameOf(ni));
|
// log_info(" replacing crossbar pip %s with %s on %s\n", ctx->nameOfPip(pip),
|
||||||
|
// ctx->nameOfPip(found_pip), ctx->nameOf(ni));
|
||||||
ctx->bindPip(found_pip, ni, STRENGTH_STRONG);
|
ctx->bindPip(found_pip, ni, STRENGTH_STRONG);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -842,75 +891,74 @@ void NgUltraImpl::drawBel(std::vector<GraphicElement> &g, GraphicElement::style_
|
|||||||
GraphicElement el;
|
GraphicElement el;
|
||||||
el.type = GraphicElement::TYPE_BOX;
|
el.type = GraphicElement::TYPE_BOX;
|
||||||
el.style = style;
|
el.style = style;
|
||||||
switch (bel_type.index)
|
switch (bel_type.index) {
|
||||||
{
|
case id_BEYOND_FE.index:
|
||||||
case id_BEYOND_FE.index :
|
|
||||||
el.x1 = loc.x + 0.15 + (loc.z % 8) * 0.1;
|
el.x1 = loc.x + 0.15 + (loc.z % 8) * 0.1;
|
||||||
el.x2 = el.x1 + 0.05;
|
el.x2 = el.x1 + 0.05;
|
||||||
el.y1 = loc.y + 0.9 - (loc.z / 8) * 0.15;
|
el.y1 = loc.y + 0.9 - (loc.z / 8) * 0.15;
|
||||||
el.y2 = el.y1 - 0.05;
|
el.y2 = el.y1 - 0.05;
|
||||||
g.push_back(el);
|
g.push_back(el);
|
||||||
break;
|
break;
|
||||||
case id_XLUT.index :
|
case id_XLUT.index:
|
||||||
el.x1 = loc.x + 0.15 + ((loc.z - BEL_XLUT_Z) % 8) * 0.1;
|
el.x1 = loc.x + 0.15 + ((loc.z - BEL_XLUT_Z) % 8) * 0.1;
|
||||||
el.x2 = el.x1 + 0.05;
|
el.x2 = el.x1 + 0.05;
|
||||||
el.y1 = loc.y + 0.9 - 4 * 0.15;
|
el.y1 = loc.y + 0.9 - 4 * 0.15;
|
||||||
el.y2 = el.y1 - 0.1;
|
el.y2 = el.y1 - 0.1;
|
||||||
g.push_back(el);
|
g.push_back(el);
|
||||||
break;
|
break;
|
||||||
case id_CY.index :
|
case id_CY.index:
|
||||||
el.x1 = loc.x + 0.15 + ((loc.z-BEL_CY_Z) % 4) * 0.2;
|
el.x1 = loc.x + 0.15 + ((loc.z - BEL_CY_Z) % 4) * 0.2;
|
||||||
el.x2 = el.x1 + 0.15;
|
el.x2 = el.x1 + 0.15;
|
||||||
el.y1 = loc.y + 0.9 - 4 * 0.15;
|
el.y1 = loc.y + 0.9 - 4 * 0.15;
|
||||||
el.y2 = el.y1 - 0.1;
|
el.y2 = el.y1 - 0.1;
|
||||||
g.push_back(el);
|
g.push_back(el);
|
||||||
break;
|
break;
|
||||||
case id_RF.index :
|
case id_RF.index:
|
||||||
el.x1 = loc.x + 0.15 + ((loc.z-BEL_RF_Z) % 2) * 0.6;
|
el.x1 = loc.x + 0.15 + ((loc.z - BEL_RF_Z) % 2) * 0.6;
|
||||||
el.x2 = el.x1 + 0.15;
|
el.x2 = el.x1 + 0.15;
|
||||||
el.y1 = loc.y + 0.9 - 4 * 0.15;
|
el.y1 = loc.y + 0.9 - 4 * 0.15;
|
||||||
el.y2 = el.y1 - 0.05;
|
el.y2 = el.y1 - 0.05;
|
||||||
g.push_back(el);
|
g.push_back(el);
|
||||||
break;
|
break;
|
||||||
case id_XRF.index :
|
case id_XRF.index:
|
||||||
el.x1 = loc.x + 0.15 + 0.2;
|
el.x1 = loc.x + 0.15 + 0.2;
|
||||||
el.x2 = el.x1 + 0.35;
|
el.x2 = el.x1 + 0.35;
|
||||||
el.y1 = loc.y + 0.9 - 4 * 0.15;
|
el.y1 = loc.y + 0.9 - 4 * 0.15;
|
||||||
el.y2 = el.y1 - 0.05;
|
el.y2 = el.y1 - 0.05;
|
||||||
g.push_back(el);
|
g.push_back(el);
|
||||||
break;
|
break;
|
||||||
case id_CDC.index :
|
case id_CDC.index:
|
||||||
el.x1 = loc.x + 0.15 + ((loc.z-BEL_CDC_Z) % 2) * 0.6;
|
el.x1 = loc.x + 0.15 + ((loc.z - BEL_CDC_Z) % 2) * 0.6;
|
||||||
el.x2 = el.x1 + 0.15;
|
el.x2 = el.x1 + 0.15;
|
||||||
el.y1 = loc.y + 0.9 - 4 * 0.15 - 0.1;
|
el.y1 = loc.y + 0.9 - 4 * 0.15 - 0.1;
|
||||||
el.y2 = el.y1 - 0.05;
|
el.y2 = el.y1 - 0.05;
|
||||||
g.push_back(el);
|
g.push_back(el);
|
||||||
break;
|
break;
|
||||||
case id_XCDC.index :
|
case id_XCDC.index:
|
||||||
el.x1 = loc.x + 0.15 + 0.2;
|
el.x1 = loc.x + 0.15 + 0.2;
|
||||||
el.x2 = el.x1 + 0.35;
|
el.x2 = el.x1 + 0.35;
|
||||||
el.y1 = loc.y + 0.9 - 4 * 0.15 - 0.1;
|
el.y1 = loc.y + 0.9 - 4 * 0.15 - 0.1;
|
||||||
el.y2 = el.y1 - 0.05;
|
el.y2 = el.y1 - 0.05;
|
||||||
g.push_back(el);
|
g.push_back(el);
|
||||||
break;
|
break;
|
||||||
case id_FIFO.index :
|
case id_FIFO.index:
|
||||||
el.x1 = loc.x + 0.15 + ((loc.z-BEL_FIFO_Z) % 2) * 0.6;
|
el.x1 = loc.x + 0.15 + ((loc.z - BEL_FIFO_Z) % 2) * 0.6;
|
||||||
el.x2 = el.x1 + 0.15;
|
el.x2 = el.x1 + 0.15;
|
||||||
el.y1 = loc.y + 0.9 - 4 * 0.15 - 0.2;
|
el.y1 = loc.y + 0.9 - 4 * 0.15 - 0.2;
|
||||||
el.y2 = el.y1 - 0.05;
|
el.y2 = el.y1 - 0.05;
|
||||||
g.push_back(el);
|
g.push_back(el);
|
||||||
break;
|
break;
|
||||||
case id_XFIFO.index :
|
case id_XFIFO.index:
|
||||||
el.x1 = loc.x + 0.15 + 0.2;
|
el.x1 = loc.x + 0.15 + 0.2;
|
||||||
el.x2 = el.x1 + 0.35;
|
el.x2 = el.x1 + 0.35;
|
||||||
el.y1 = loc.y + 0.9 - 4 * 0.15 - 0.2;
|
el.y1 = loc.y + 0.9 - 4 * 0.15 - 0.2;
|
||||||
el.y2 = el.y1 - 0.05;
|
el.y2 = el.y1 - 0.05;
|
||||||
g.push_back(el);
|
g.push_back(el);
|
||||||
break;
|
break;
|
||||||
case id_IOTP.index :
|
case id_IOTP.index:
|
||||||
el.x1 = loc.x + 0.15 + loc.z / 4 * 0.11;
|
el.x1 = loc.x + 0.15 + loc.z / 4 * 0.11;
|
||||||
el.x2 = el.x1 + 0.06;
|
el.x2 = el.x1 + 0.06;
|
||||||
if (loc.y==3) { // bottom
|
if (loc.y == 3) { // bottom
|
||||||
el.y1 = 0.1;
|
el.y1 = 0.1;
|
||||||
el.y2 = el.y1 + 0.2;
|
el.y2 = el.y1 + 0.2;
|
||||||
} else { // top
|
} else { // top
|
||||||
@ -919,10 +967,10 @@ void NgUltraImpl::drawBel(std::vector<GraphicElement> &g, GraphicElement::style_
|
|||||||
}
|
}
|
||||||
g.push_back(el);
|
g.push_back(el);
|
||||||
break;
|
break;
|
||||||
case id_IOM.index :
|
case id_IOM.index:
|
||||||
el.x1 = loc.x + 0.15;
|
el.x1 = loc.x + 0.15;
|
||||||
el.x2 = el.x1 + 33 * 0.11 + 0.06;
|
el.x2 = el.x1 + 33 * 0.11 + 0.06;
|
||||||
if (loc.y==3) { // bottom
|
if (loc.y == 3) { // bottom
|
||||||
el.y1 = 0.4;
|
el.y1 = 0.4;
|
||||||
el.y2 = el.y1 + 0.2;
|
el.y2 = el.y1 + 0.2;
|
||||||
} else { // top
|
} else { // top
|
||||||
@ -931,10 +979,10 @@ void NgUltraImpl::drawBel(std::vector<GraphicElement> &g, GraphicElement::style_
|
|||||||
}
|
}
|
||||||
g.push_back(el);
|
g.push_back(el);
|
||||||
break;
|
break;
|
||||||
case id_DDFR.index :
|
case id_DDFR.index:
|
||||||
el.x1 = loc.x + 0.15 + loc.z / 4 * 0.11 + (loc.z % 4 - 1) * 0.02;
|
el.x1 = loc.x + 0.15 + loc.z / 4 * 0.11 + (loc.z % 4 - 1) * 0.02;
|
||||||
el.x2 = el.x1 + 0.015;
|
el.x2 = el.x1 + 0.015;
|
||||||
if (loc.y==3) { // bottom
|
if (loc.y == 3) { // bottom
|
||||||
el.y1 = 0.7;
|
el.y1 = 0.7;
|
||||||
el.y2 = el.y1 + 0.1;
|
el.y2 = el.y1 + 0.1;
|
||||||
} else { // top
|
} else { // top
|
||||||
@ -943,8 +991,8 @@ void NgUltraImpl::drawBel(std::vector<GraphicElement> &g, GraphicElement::style_
|
|||||||
}
|
}
|
||||||
g.push_back(el);
|
g.push_back(el);
|
||||||
break;
|
break;
|
||||||
case id_IOP.index :
|
case id_IOP.index:
|
||||||
if (loc.x==ctx->getGridDimX()-4) { // right
|
if (loc.x == ctx->getGridDimX() - 4) { // right
|
||||||
el.x1 = ctx->getGridDimX() - 0.1;
|
el.x1 = ctx->getGridDimX() - 0.1;
|
||||||
el.x2 = el.x1 - 0.2;
|
el.x2 = el.x1 - 0.2;
|
||||||
} else { // left
|
} else { // left
|
||||||
@ -955,8 +1003,8 @@ void NgUltraImpl::drawBel(std::vector<GraphicElement> &g, GraphicElement::style_
|
|||||||
el.y2 = el.y1 - 0.06;
|
el.y2 = el.y1 - 0.06;
|
||||||
g.push_back(el);
|
g.push_back(el);
|
||||||
break;
|
break;
|
||||||
case id_DFR.index :
|
case id_DFR.index:
|
||||||
if (loc.x==ctx->getGridDimX()-4) { // right
|
if (loc.x == ctx->getGridDimX() - 4) { // right
|
||||||
el.x1 = ctx->getGridDimX() - 0.4;
|
el.x1 = ctx->getGridDimX() - 0.4;
|
||||||
el.x2 = el.x1 - 0.1;
|
el.x2 = el.x1 - 0.1;
|
||||||
} else { // left
|
} else { // left
|
||||||
@ -967,17 +1015,17 @@ void NgUltraImpl::drawBel(std::vector<GraphicElement> &g, GraphicElement::style_
|
|||||||
el.y2 = el.y1 + 0.015;
|
el.y2 = el.y1 + 0.015;
|
||||||
g.push_back(el);
|
g.push_back(el);
|
||||||
break;
|
break;
|
||||||
case id_PLL.index :
|
case id_PLL.index:
|
||||||
el.x1 = loc.x + 0.1;
|
el.x1 = loc.x + 0.1;
|
||||||
el.x2 = el.x1 + 0.8;
|
el.x2 = el.x1 + 0.8;
|
||||||
el.y1 = loc.y + 0.9;
|
el.y1 = loc.y + 0.9;
|
||||||
el.y2 = el.y1 - 0.8;
|
el.y2 = el.y1 - 0.8;
|
||||||
g.push_back(el);
|
g.push_back(el);
|
||||||
break;
|
break;
|
||||||
case id_WFG.index :
|
case id_WFG.index:
|
||||||
el.x1 = loc.x + 1.1;
|
el.x1 = loc.x + 1.1;
|
||||||
el.x2 = el.x1 + 0.8;
|
el.x2 = el.x1 + 0.8;
|
||||||
el.y1 = loc.y + 0.95 - (loc.z-1) * 0.25 + 3;
|
el.y1 = loc.y + 0.95 - (loc.z - 1) * 0.25 + 3;
|
||||||
el.y2 = el.y1 - 0.2;
|
el.y2 = el.y1 - 0.2;
|
||||||
g.push_back(el);
|
g.push_back(el);
|
||||||
break;
|
break;
|
||||||
@ -995,16 +1043,14 @@ void NgUltraImpl::drawBel(std::vector<GraphicElement> &g, GraphicElement::style_
|
|||||||
el.y2 = el.y1 - 1.6;
|
el.y2 = el.y1 - 1.6;
|
||||||
g.push_back(el);
|
g.push_back(el);
|
||||||
break;
|
break;
|
||||||
case id_GCK.index:
|
case id_GCK.index: {
|
||||||
{
|
|
||||||
int lobe = loc.z / 20;
|
int lobe = loc.z / 20;
|
||||||
el.x1 = (47 + (lobe % 2)*3) *4 + 0.1;
|
el.x1 = (47 + (lobe % 2) * 3) * 4 + 0.1;
|
||||||
el.x2 = el.x1 + 0.8;
|
el.x2 = el.x1 + 0.8;
|
||||||
el.y1 = (ctx->getGridDimY() - 1 - (7*4 + 12*4*(lobe>>1))) + 0.95 - (loc.z % 20) * 0.25;
|
el.y1 = (ctx->getGridDimY() - 1 - (7 * 4 + 12 * 4 * (lobe >> 1))) + 0.95 - (loc.z % 20) * 0.25;
|
||||||
el.y2 = el.y1 - 0.2;
|
el.y2 = el.y1 - 0.2;
|
||||||
g.push_back(el);
|
g.push_back(el);
|
||||||
}
|
} break;
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1012,7 +1058,7 @@ void NgUltraImpl::drawBel(std::vector<GraphicElement> &g, GraphicElement::style_
|
|||||||
|
|
||||||
struct NgUltraArch : HimbaechelArch
|
struct NgUltraArch : HimbaechelArch
|
||||||
{
|
{
|
||||||
NgUltraArch() : HimbaechelArch("ng-ultra"){};
|
NgUltraArch() : HimbaechelArch("ng-ultra") {};
|
||||||
bool match_device(const std::string &device) override { return device == "NG-ULTRA"; }
|
bool match_device(const std::string &device) override { return device == "NG-ULTRA"; }
|
||||||
std::unique_ptr<HimbaechelAPI> create(const std::string &device, const dict<std::string, std::string> &args)
|
std::unique_ptr<HimbaechelAPI> create(const std::string &device, const dict<std::string, std::string> &args)
|
||||||
{
|
{
|
||||||
|
@ -65,19 +65,20 @@ struct NgUltraImpl : HimbaechelAPI
|
|||||||
delay_t estimateDelay(WireId src, WireId dst) const override;
|
delay_t estimateDelay(WireId src, WireId dst) const override;
|
||||||
delay_t predictDelay(BelId src_bel, IdString src_pin, BelId dst_bel, IdString dst_pin) const override;
|
delay_t predictDelay(BelId src_bel, IdString src_pin, BelId dst_bel, IdString dst_pin) const override;
|
||||||
|
|
||||||
bool checkPipAvail(PipId pip) const override { return blocked_pips.count(pip)==0; }
|
bool checkPipAvail(PipId pip) const override { return blocked_pips.count(pip) == 0; }
|
||||||
bool checkPipAvailForNet(PipId pip, const NetInfo *net) const override { return checkPipAvail(pip); };
|
bool checkPipAvailForNet(PipId pip, const NetInfo *net) const override { return checkPipAvail(pip); };
|
||||||
|
|
||||||
void expandBoundingBox(BoundingBox &bb) const override;
|
void expandBoundingBox(BoundingBox &bb) const override;
|
||||||
|
|
||||||
void drawBel(std::vector<GraphicElement> &g, GraphicElement::style_t style, IdString bel_type, Loc loc) override;
|
void drawBel(std::vector<GraphicElement> &g, GraphicElement::style_t style, IdString bel_type, Loc loc) override;
|
||||||
public:
|
|
||||||
|
public:
|
||||||
int tile_lobe(int tile) const;
|
int tile_lobe(int tile) const;
|
||||||
TileTypeExtra tile_type(int tile) const;
|
TileTypeExtra tile_type(int tile) const;
|
||||||
IdString tile_name_id(int tile) const;
|
IdString tile_name_id(int tile) const;
|
||||||
std::string tile_name(int tile) const;
|
std::string tile_name(int tile) const;
|
||||||
|
|
||||||
const dict<IdString,pool<IdString>>& get_fabric_lowskew_sinks();
|
const dict<IdString, pool<IdString>> &get_fabric_lowskew_sinks();
|
||||||
bool is_fabric_lowskew_sink(const PortRef &ref);
|
bool is_fabric_lowskew_sink(const PortRef &ref);
|
||||||
bool is_ring_clock_sink(const PortRef &ref);
|
bool is_ring_clock_sink(const PortRef &ref);
|
||||||
bool is_ring_over_tile_clock_sink(const PortRef &ref);
|
bool is_ring_over_tile_clock_sink(const PortRef &ref);
|
||||||
@ -89,15 +90,15 @@ public:
|
|||||||
const NGUltraPipExtraDataPOD *pip_extra_data(PipId pip) const;
|
const NGUltraPipExtraDataPOD *pip_extra_data(PipId pip) const;
|
||||||
const NGUltraBelExtraDataPOD *bel_extra_data(BelId bel) const;
|
const NGUltraBelExtraDataPOD *bel_extra_data(BelId bel) const;
|
||||||
|
|
||||||
dict<IdString,BelId> iom_bels;
|
dict<IdString, BelId> iom_bels;
|
||||||
dict<std::string, std::string> bank_voltage;
|
dict<std::string, std::string> bank_voltage;
|
||||||
dict<BelId,IdString> global_capable_bels;
|
dict<BelId, IdString> global_capable_bels;
|
||||||
dict<std::string,BelId> locations;
|
dict<std::string, BelId> locations;
|
||||||
dict<std::string,Loc> tile_locations;
|
dict<std::string, Loc> tile_locations;
|
||||||
dict<int,std::vector<GckConfig>> gck_per_lobe;
|
dict<int, std::vector<GckConfig>> gck_per_lobe;
|
||||||
|
|
||||||
pool<PipId> blocked_pips;
|
pool<PipId> blocked_pips;
|
||||||
dict<IdString, std::pair<IdString,IdString>> bank_to_ckg;
|
dict<IdString, std::pair<IdString, IdString>> bank_to_ckg;
|
||||||
dict<BelId, IdString> unused_wfg;
|
dict<BelId, IdString> unused_wfg;
|
||||||
dict<BelId, IdString> unused_pll;
|
dict<BelId, IdString> unused_pll;
|
||||||
dict<BelId, BelId> dsp_cascade;
|
dict<BelId, BelId> dsp_cascade;
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -83,9 +83,11 @@ TESTABLE_PRIVATE:
|
|||||||
void ddfr_rewrite(CellInfo *cell);
|
void ddfr_rewrite(CellInfo *cell);
|
||||||
|
|
||||||
void exchange_if_constant(CellInfo *cell, IdString input1, IdString input2);
|
void exchange_if_constant(CellInfo *cell, IdString input1, IdString input2);
|
||||||
void pack_cy_input_and_output(CellInfo *cy, IdString cluster, IdString in_port, IdString out_port, int placer, int &lut_only, int &lut_and_ff, int &dff_only);
|
void pack_cy_input_and_output(CellInfo *cy, IdString cluster, IdString in_port, IdString out_port, int placer,
|
||||||
|
int &lut_only, int &lut_and_ff, int &dff_only);
|
||||||
|
|
||||||
void pack_xrf_input_and_output(CellInfo *cy, IdString cluster, IdString in_port, IdString out_port, ClusterPlacement placement, int &lut_only, int &lut_and_ff, int &dff_only);
|
void pack_xrf_input_and_output(CellInfo *cy, IdString cluster, IdString in_port, IdString out_port,
|
||||||
|
ClusterPlacement placement, int &lut_only, int &lut_and_ff, int &dff_only);
|
||||||
|
|
||||||
void connect_gnd_if_unconnected(CellInfo *cell, IdString input, bool warn);
|
void connect_gnd_if_unconnected(CellInfo *cell, IdString input, bool warn);
|
||||||
void disconnect_if_gnd(CellInfo *cell, IdString input);
|
void disconnect_if_gnd(CellInfo *cell, IdString input);
|
||||||
@ -107,10 +109,10 @@ TESTABLE_PRIVATE:
|
|||||||
int make_init_with_const_input(int init, int input, bool value);
|
int make_init_with_const_input(int init, int input, bool value);
|
||||||
|
|
||||||
int memory_width(int config, bool ecc);
|
int memory_width(int config, bool ecc);
|
||||||
int memory_addr_bits(int config,bool ecc);
|
int memory_addr_bits(int config, bool ecc);
|
||||||
|
|
||||||
void constrain_location(CellInfo *cell);
|
void constrain_location(CellInfo *cell);
|
||||||
void extract_lowskew_signals(CellInfo *cell, dict<IdString,dict<IdString,std::vector<PortRef>>> &lowskew_signals);
|
void extract_lowskew_signals(CellInfo *cell, dict<IdString, dict<IdString, std::vector<PortRef>>> &lowskew_signals);
|
||||||
// Cell creating
|
// Cell creating
|
||||||
CellInfo *create_cell_ptr(IdString type, IdString name);
|
CellInfo *create_cell_ptr(IdString type, IdString name);
|
||||||
|
|
||||||
|
@ -18,9 +18,9 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include "command.h"
|
||||||
#include "gtest/gtest.h"
|
#include "gtest/gtest.h"
|
||||||
#include "nextpnr.h"
|
#include "nextpnr.h"
|
||||||
#include "command.h"
|
|
||||||
#include "uarch/ng-ultra/ng_ultra.h"
|
#include "uarch/ng-ultra/ng_ultra.h"
|
||||||
#include "uarch/ng-ultra/pack.h"
|
#include "uarch/ng-ultra/pack.h"
|
||||||
#define HIMBAECHEL_CONSTIDS "uarch/ng-ultra/constids.inc"
|
#define HIMBAECHEL_CONSTIDS "uarch/ng-ultra/constids.inc"
|
||||||
@ -38,13 +38,13 @@ class NGUltraLutDffTest : public ::testing::Test
|
|||||||
ctx = new Context(chipArgs);
|
ctx = new Context(chipArgs);
|
||||||
ctx->uarch->init(ctx);
|
ctx->uarch->init(ctx);
|
||||||
ctx->late_init();
|
ctx->late_init();
|
||||||
impl = (NgUltraImpl*)(ctx->uarch.get());
|
impl = (NgUltraImpl *)(ctx->uarch.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void TearDown() { delete ctx; }
|
virtual void TearDown() { delete ctx; }
|
||||||
|
|
||||||
int const_autoidx = 0;
|
int const_autoidx = 0;
|
||||||
NetInfo* add_constant_driver(const char *name, char constval)
|
NetInfo *add_constant_driver(const char *name, char constval)
|
||||||
{
|
{
|
||||||
IdString cell_name = ctx->idf("%s%s%d", name, (constval == '1' ? "$VCC$" : "$GND$"), const_autoidx++);
|
IdString cell_name = ctx->idf("%s%s%d", name, (constval == '1' ? "$VCC$" : "$GND$"), const_autoidx++);
|
||||||
CellInfo *cc = ctx->createCell(cell_name, ctx->id(constval == '1' ? "VCC" : "GND"));
|
CellInfo *cc = ctx->createCell(cell_name, ctx->id(constval == '1' ? "VCC" : "GND"));
|
||||||
@ -99,19 +99,19 @@ TEST_F(NGUltraLutDffTest, remove_unused_gnd)
|
|||||||
add_port(cell, "I2", PORT_IN);
|
add_port(cell, "I2", PORT_IN);
|
||||||
add_port(cell, "I3", PORT_IN);
|
add_port(cell, "I3", PORT_IN);
|
||||||
add_port(cell, "I4", PORT_IN);
|
add_port(cell, "I4", PORT_IN);
|
||||||
cell->connectPort(id_I1, add_constant_driver("TEST",'1'));
|
cell->connectPort(id_I1, add_constant_driver("TEST", '1'));
|
||||||
cell->connectPort(id_I2, add_constant_driver("TEST",'1'));
|
cell->connectPort(id_I2, add_constant_driver("TEST", '1'));
|
||||||
cell->connectPort(id_I3, add_constant_driver("TEST",'1'));
|
cell->connectPort(id_I3, add_constant_driver("TEST", '1'));
|
||||||
|
|
||||||
ASSERT_EQ(ctx->cells.size(), 4LU);
|
ASSERT_EQ(ctx->cells.size(), 4LU);
|
||||||
packer.pack_constants();
|
packer.pack_constants();
|
||||||
ASSERT_EQ(ctx->cells.size(), 3LU);
|
ASSERT_EQ(ctx->cells.size(), 3LU);
|
||||||
impl->remove_constants();
|
impl->remove_constants();
|
||||||
ASSERT_EQ(ctx->cells.size(), 2LU);
|
ASSERT_EQ(ctx->cells.size(), 2LU);
|
||||||
ASSERT_EQ(ctx->cells.find(ctx->id("$PACKER_GND_DRV")),ctx->cells.end());
|
ASSERT_EQ(ctx->cells.find(ctx->id("$PACKER_GND_DRV")), ctx->cells.end());
|
||||||
ASSERT_NE(ctx->cells.find(ctx->id("$PACKER_VCC_DRV")),ctx->cells.end());
|
ASSERT_NE(ctx->cells.find(ctx->id("$PACKER_VCC_DRV")), ctx->cells.end());
|
||||||
ASSERT_EQ(ctx->nets.find(ctx->id("$PACKER_GND")),ctx->nets.end());
|
ASSERT_EQ(ctx->nets.find(ctx->id("$PACKER_GND")), ctx->nets.end());
|
||||||
ASSERT_NE(ctx->nets.find(ctx->id("$PACKER_VCC")),ctx->nets.end());
|
ASSERT_NE(ctx->nets.find(ctx->id("$PACKER_VCC")), ctx->nets.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(NGUltraLutDffTest, remove_unused_vcc)
|
TEST_F(NGUltraLutDffTest, remove_unused_vcc)
|
||||||
@ -122,26 +122,26 @@ TEST_F(NGUltraLutDffTest, remove_unused_vcc)
|
|||||||
add_port(cell, "I2", PORT_IN);
|
add_port(cell, "I2", PORT_IN);
|
||||||
add_port(cell, "I3", PORT_IN);
|
add_port(cell, "I3", PORT_IN);
|
||||||
add_port(cell, "I4", PORT_IN);
|
add_port(cell, "I4", PORT_IN);
|
||||||
cell->connectPort(id_I1, add_constant_driver("TEST",'0'));
|
cell->connectPort(id_I1, add_constant_driver("TEST", '0'));
|
||||||
cell->connectPort(id_I2, add_constant_driver("TEST",'0'));
|
cell->connectPort(id_I2, add_constant_driver("TEST", '0'));
|
||||||
cell->connectPort(id_I3, add_constant_driver("TEST",'0'));
|
cell->connectPort(id_I3, add_constant_driver("TEST", '0'));
|
||||||
|
|
||||||
ASSERT_EQ(ctx->cells.size(), 4LU);
|
ASSERT_EQ(ctx->cells.size(), 4LU);
|
||||||
packer.pack_constants();
|
packer.pack_constants();
|
||||||
ASSERT_EQ(ctx->cells.size(), 3LU);
|
ASSERT_EQ(ctx->cells.size(), 3LU);
|
||||||
impl->remove_constants();
|
impl->remove_constants();
|
||||||
ASSERT_EQ(ctx->cells.size(), 2LU);
|
ASSERT_EQ(ctx->cells.size(), 2LU);
|
||||||
ASSERT_NE(ctx->cells.find(ctx->id("$PACKER_GND_DRV")),ctx->cells.end());
|
ASSERT_NE(ctx->cells.find(ctx->id("$PACKER_GND_DRV")), ctx->cells.end());
|
||||||
ASSERT_EQ(ctx->cells.find(ctx->id("$PACKER_VCC_DRV")),ctx->cells.end());
|
ASSERT_EQ(ctx->cells.find(ctx->id("$PACKER_VCC_DRV")), ctx->cells.end());
|
||||||
ASSERT_NE(ctx->nets.find(ctx->id("$PACKER_GND")),ctx->nets.end());
|
ASSERT_NE(ctx->nets.find(ctx->id("$PACKER_GND")), ctx->nets.end());
|
||||||
ASSERT_EQ(ctx->nets.find(ctx->id("$PACKER_VCC")),ctx->nets.end());
|
ASSERT_EQ(ctx->nets.find(ctx->id("$PACKER_VCC")), ctx->nets.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(NGUltraLutDffTest, make_init_with_const_input)
|
TEST_F(NGUltraLutDffTest, make_init_with_const_input)
|
||||||
{
|
{
|
||||||
NgUltraPacker packer(ctx, impl);
|
NgUltraPacker packer(ctx, impl);
|
||||||
for (int lut_table=0;lut_table<0x10000;lut_table++) {
|
for (int lut_table = 0; lut_table < 0x10000; lut_table++) {
|
||||||
for(int lut=0;lut<16;lut++) {
|
for (int lut = 0; lut < 16; lut++) {
|
||||||
int I4 = (lut & 8) ? 1 : 0;
|
int I4 = (lut & 8) ? 1 : 0;
|
||||||
int I3 = (lut & 4) ? 1 : 0;
|
int I3 = (lut & 4) ? 1 : 0;
|
||||||
int I2 = (lut & 2) ? 1 : 0;
|
int I2 = (lut & 2) ? 1 : 0;
|
||||||
@ -152,10 +152,10 @@ TEST_F(NGUltraLutDffTest, make_init_with_const_input)
|
|||||||
int tab3 = packer.make_init_with_const_input(tab2, 2, I3);
|
int tab3 = packer.make_init_with_const_input(tab2, 2, I3);
|
||||||
int tab4 = packer.make_init_with_const_input(tab3, 3, I4);
|
int tab4 = packer.make_init_with_const_input(tab3, 3, I4);
|
||||||
|
|
||||||
ASSERT_EQ(evaluate_lut(I1,I2,I3,I4,lut_table),evaluate_lut(I1,I2,I3,I4,tab1));
|
ASSERT_EQ(evaluate_lut(I1, I2, I3, I4, lut_table), evaluate_lut(I1, I2, I3, I4, tab1));
|
||||||
ASSERT_EQ(evaluate_lut(I1,I2,I3,I4,lut_table),evaluate_lut(I1,I2,I3,I4,tab2));
|
ASSERT_EQ(evaluate_lut(I1, I2, I3, I4, lut_table), evaluate_lut(I1, I2, I3, I4, tab2));
|
||||||
ASSERT_EQ(evaluate_lut(I1,I2,I3,I4,lut_table),evaluate_lut(I1,I2,I3,I4,tab3));
|
ASSERT_EQ(evaluate_lut(I1, I2, I3, I4, lut_table), evaluate_lut(I1, I2, I3, I4, tab3));
|
||||||
ASSERT_EQ(evaluate_lut(I1,I2,I3,I4,lut_table),evaluate_lut(I1,I2,I3,I4,tab4));
|
ASSERT_EQ(evaluate_lut(I1, I2, I3, I4, lut_table), evaluate_lut(I1, I2, I3, I4, tab4));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,8 +18,8 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include "log.h"
|
|
||||||
#include "gtest/gtest.h"
|
#include "gtest/gtest.h"
|
||||||
|
#include "log.h"
|
||||||
|
|
||||||
USING_NEXTPNR_NAMESPACE
|
USING_NEXTPNR_NAMESPACE
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user