jsonwrite: Fix bus cell ports
Signed-off-by: David Shah <dave@ds0.me>
This commit is contained in:
parent
2b3dda7535
commit
6562edc98e
@ -73,14 +73,17 @@ struct PortGroup
|
|||||||
PortType dir;
|
PortType dir;
|
||||||
};
|
};
|
||||||
|
|
||||||
std::vector<PortGroup> group_ports(Context *ctx)
|
std::vector<PortGroup> group_ports(Context *ctx, const std::unordered_map<IdString, PortInfo> &ports,
|
||||||
|
bool is_cell = false)
|
||||||
{
|
{
|
||||||
std::vector<PortGroup> groups;
|
std::vector<PortGroup> groups;
|
||||||
std::unordered_map<std::string, size_t> base_to_group;
|
std::unordered_map<std::string, size_t> base_to_group;
|
||||||
for (auto &pair : ctx->ports) {
|
for (auto &pair : ports) {
|
||||||
std::string name = pair.second.name.str(ctx);
|
std::string name = pair.second.name.str(ctx);
|
||||||
if ((name.back() != ']') || (name.find('[') == std::string::npos)) {
|
if ((name.back() != ']') || (name.find('[') == std::string::npos)) {
|
||||||
groups.push_back({name, {pair.first.index}, pair.second.type});
|
groups.push_back({name,
|
||||||
|
{is_cell ? (pair.second.net ? pair.second.net->name.index : -1) : pair.first.index},
|
||||||
|
pair.second.type});
|
||||||
} else {
|
} else {
|
||||||
int off1 = int(name.find_last_of('['));
|
int off1 = int(name.find_last_of('['));
|
||||||
std::string basename = name.substr(0, off1);
|
std::string basename = name.substr(0, off1);
|
||||||
@ -95,22 +98,23 @@ std::vector<PortGroup> group_ports(Context *ctx)
|
|||||||
if (int(grp.bits.size()) <= index)
|
if (int(grp.bits.size()) <= index)
|
||||||
grp.bits.resize(index + 1, -1);
|
grp.bits.resize(index + 1, -1);
|
||||||
NPNR_ASSERT(grp.bits.at(index) == -1);
|
NPNR_ASSERT(grp.bits.at(index) == -1);
|
||||||
grp.bits.at(index) = pair.second.net ? pair.second.net->name.index : pair.first.index;
|
grp.bits.at(index) = pair.second.net ? pair.second.net->name.index : (is_cell ? -1 : pair.first.index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return groups;
|
return groups;
|
||||||
};
|
}
|
||||||
|
|
||||||
std::string format_port_bits(const PortGroup &port)
|
std::string format_port_bits(const PortGroup &port, int &dummy_idx)
|
||||||
{
|
{
|
||||||
std::stringstream s;
|
std::stringstream s;
|
||||||
s << "[ ";
|
s << "[ ";
|
||||||
bool first = true;
|
bool first = true;
|
||||||
|
if (port.bits.size() != 1 || port.bits.at(0) != -1) // skip single disconnected ports
|
||||||
for (auto bit : port.bits) {
|
for (auto bit : port.bits) {
|
||||||
if (!first)
|
if (!first)
|
||||||
s << ", ";
|
s << ", ";
|
||||||
if (bit == -1)
|
if (bit == -1)
|
||||||
s << "\"x\"";
|
s << (++dummy_idx);
|
||||||
else
|
else
|
||||||
s << bit;
|
s << bit;
|
||||||
first = false;
|
first = false;
|
||||||
@ -122,6 +126,7 @@ std::string format_port_bits(const PortGroup &port)
|
|||||||
void write_module(std::ostream &f, Context *ctx)
|
void write_module(std::ostream &f, Context *ctx)
|
||||||
{
|
{
|
||||||
auto val = ctx->attrs.find(ctx->id("module"));
|
auto val = ctx->attrs.find(ctx->id("module"));
|
||||||
|
int dummy_idx = int(ctx->idstring_idx_to_str->size()) + 1000;
|
||||||
if (val != ctx->attrs.end())
|
if (val != ctx->attrs.end())
|
||||||
f << stringf(" %s: {\n", get_string(val->second.as_string()).c_str());
|
f << stringf(" %s: {\n", get_string(val->second.as_string()).c_str());
|
||||||
else
|
else
|
||||||
@ -134,14 +139,14 @@ void write_module(std::ostream &f, Context *ctx)
|
|||||||
f << stringf("\n },\n");
|
f << stringf("\n },\n");
|
||||||
f << stringf(" \"ports\": {");
|
f << stringf(" \"ports\": {");
|
||||||
|
|
||||||
auto ports = group_ports(ctx);
|
auto ports = group_ports(ctx, ctx->ports);
|
||||||
bool first = true;
|
bool first = true;
|
||||||
for (auto &port : ports) {
|
for (auto &port : ports) {
|
||||||
f << stringf("%s\n", first ? "" : ",");
|
f << stringf("%s\n", first ? "" : ",");
|
||||||
f << stringf(" %s: {\n", get_string(port.name).c_str());
|
f << stringf(" %s: {\n", get_string(port.name).c_str());
|
||||||
f << stringf(" \"direction\": \"%s\",\n",
|
f << stringf(" \"direction\": \"%s\",\n",
|
||||||
port.dir == PORT_IN ? "input" : port.dir == PORT_INOUT ? "inout" : "output");
|
port.dir == PORT_IN ? "input" : port.dir == PORT_INOUT ? "inout" : "output");
|
||||||
f << stringf(" \"bits\": %s\n", format_port_bits(port).c_str());
|
f << stringf(" \"bits\": %s\n", format_port_bits(port, dummy_idx).c_str());
|
||||||
f << stringf(" }");
|
f << stringf(" }");
|
||||||
first = false;
|
first = false;
|
||||||
}
|
}
|
||||||
@ -151,6 +156,7 @@ void write_module(std::ostream &f, Context *ctx)
|
|||||||
first = true;
|
first = true;
|
||||||
for (auto &pair : ctx->cells) {
|
for (auto &pair : ctx->cells) {
|
||||||
auto &c = pair.second;
|
auto &c = pair.second;
|
||||||
|
auto cell_ports = group_ports(ctx, c->ports, true);
|
||||||
f << stringf("%s\n", first ? "" : ",");
|
f << stringf("%s\n", first ? "" : ",");
|
||||||
f << stringf(" %s: {\n", get_name(c->name, ctx).c_str());
|
f << stringf(" %s: {\n", get_name(c->name, ctx).c_str());
|
||||||
f << stringf(" \"hide_name\": %s,\n", c->name.c_str(ctx)[0] == '$' ? "1" : "0");
|
f << stringf(" \"hide_name\": %s,\n", c->name.c_str(ctx)[0] == '$' ? "1" : "0");
|
||||||
@ -163,24 +169,18 @@ void write_module(std::ostream &f, Context *ctx)
|
|||||||
f << stringf("\n },\n");
|
f << stringf("\n },\n");
|
||||||
f << stringf(" \"port_directions\": {");
|
f << stringf(" \"port_directions\": {");
|
||||||
bool first2 = true;
|
bool first2 = true;
|
||||||
for (auto &conn : c->ports) {
|
for (auto &pg : cell_ports) {
|
||||||
auto &p = conn.second;
|
std::string direction = (pg.dir == PORT_IN) ? "input" : (pg.dir == PORT_OUT) ? "output" : "inout";
|
||||||
std::string direction = (p.type == PORT_IN) ? "input" : (p.type == PORT_OUT) ? "output" : "inout";
|
|
||||||
f << stringf("%s\n", first2 ? "" : ",");
|
f << stringf("%s\n", first2 ? "" : ",");
|
||||||
f << stringf(" %s: \"%s\"", get_name(conn.first, ctx).c_str(), direction.c_str());
|
f << stringf(" %s: \"%s\"", get_string(pg.name).c_str(), direction.c_str());
|
||||||
first2 = false;
|
first2 = false;
|
||||||
}
|
}
|
||||||
f << stringf("\n },\n");
|
f << stringf("\n },\n");
|
||||||
f << stringf(" \"connections\": {");
|
f << stringf(" \"connections\": {");
|
||||||
first2 = true;
|
first2 = true;
|
||||||
for (auto &conn : c->ports) {
|
for (auto &pg : cell_ports) {
|
||||||
auto &p = conn.second;
|
|
||||||
f << stringf("%s\n", first2 ? "" : ",");
|
f << stringf("%s\n", first2 ? "" : ",");
|
||||||
if (p.net)
|
f << stringf(" %s: %s", get_string(pg.name).c_str(), format_port_bits(pg, dummy_idx).c_str());
|
||||||
f << stringf(" %s: [ %d ]", get_name(conn.first, ctx).c_str(), p.net->name.index);
|
|
||||||
else
|
|
||||||
f << stringf(" %s: [ ]", get_name(conn.first, ctx).c_str());
|
|
||||||
|
|
||||||
first2 = false;
|
first2 = false;
|
||||||
}
|
}
|
||||||
f << stringf("\n }\n");
|
f << stringf("\n }\n");
|
||||||
|
Loading…
Reference in New Issue
Block a user