3
0
Fork 0
mirror of https://github.com/YosysHQ/yosys synced 2025-04-22 08:35:32 +00:00

Merge pull request #53 from alaindargelas/main

Splitnets new options for top only and port only
This commit is contained in:
Akash Levy 2025-02-19 10:12:34 -08:00 committed by GitHub
commit 87e730a01b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 104 additions and 5 deletions

View file

@ -112,6 +112,12 @@ struct SplitnetsPass : public Pass {
log(" -ports\n");
log(" also split module ports. per default only internal signals are split.\n");
log("\n");
log(" -ports_only\n");
log(" split module ports, but not the internal signals.\n");
log("\n");
log(" -top_only\n");
log(" split module ports/nets, only at the top level of hierarchy.\n");
log("\n");
log(" -driver\n");
log(" don't blindly split nets in individual bits. instead look at the driver\n");
log(" and split nets so that no driver drives only part of a net.\n");
@ -121,6 +127,8 @@ struct SplitnetsPass : public Pass {
{
bool flag_ports = false;
bool flag_driver = false;
bool flag_ports_only = false;
bool flag_top_only = false;
std::string format = "[]:";
log_header(design, "Executing SPLITNETS pass (splitting up multi-bit signals).\n");
@ -136,6 +144,14 @@ struct SplitnetsPass : public Pass {
flag_ports = true;
continue;
}
if (args[argidx] == "-ports_only") {
flag_ports_only = true;
continue;
}
if (args[argidx] == "-top_only") {
flag_top_only = true;
continue;
}
if (args[argidx] == "-driver") {
flag_driver = true;
continue;
@ -151,10 +167,12 @@ struct SplitnetsPass : public Pass {
{
if (module->has_processes_warn())
continue;
if (flag_top_only && (design->top_module() != module))
continue;
SplitnetsWorker worker;
if (flag_ports)
if (flag_ports || flag_ports_only)
{
int normalized_port_factor = 0;
@ -186,7 +204,8 @@ struct SplitnetsPass : public Pass {
for (auto &chunk : sig.chunks()) {
if (chunk.wire == NULL)
continue;
if (chunk.wire->port_id == 0 || flag_ports) {
if ((flag_ports_only && (chunk.wire->port_id != 0) ||
(!flag_ports_only && (chunk.wire->port_id == 0 || flag_ports))) {
if (chunk.offset != 0)
split_wires_at[chunk.wire].insert(chunk.offset);
if (chunk.offset + chunk.width < chunk.wire->width)
@ -207,7 +226,10 @@ struct SplitnetsPass : public Pass {
else
{
for (auto wire : module->wires()) {
if (wire->width > 1 && (wire->port_id == 0 || flag_ports) && design->selected(module, wire))
if (flag_ports_only)
if (wire->width > 1 && (wire->port_id != 0) && design->selected(module, wire))
worker.splitmap[wire] = std::vector<RTLIL::SigBit>();
else if (wire->width > 1 && (wire->port_id == 0 || flag_ports) && design->selected(module, wire))
worker.splitmap[wire] = std::vector<RTLIL::SigBit>();
}
@ -218,7 +240,7 @@ struct SplitnetsPass : public Pass {
module->rewrite_sigspecs(worker);
if (flag_ports)
if (flag_ports || flag_ports_only)
{
for (auto wire : module->wires())
{
@ -243,7 +265,7 @@ struct SplitnetsPass : public Pass {
delete_wires.insert(it.first);
module->remove(delete_wires);
if (flag_ports)
if (flag_ports || flag_ports_only)
module->fixup_ports();
}

View file

@ -0,0 +1,63 @@
yosys -import
proc read_stats { file } {
set fid [open $file]
set result [read $fid]
close $fid
set ports 0
set nets 0
foreach line [split $result "\n"] {
if [regexp {Number of wires:[ \t]+([0-9]+)} $line tmp n] {
set nets [expr $nets + $n]
}
if [regexp {Number of ports:[ \t]+([0-9]+)} $line tmp n] {
set ports [expr $ports + $n]
}
}
return [list $nets $ports]
}
proc assert_count { type actual expected } {
if {$actual != $expected} {
puts "Error, $type count: $actual vs $expected expected"
exit 1
}
}
read_verilog test_splitnets.v
hierarchy -auto-top
procs
design -save "pre"
splitnets -ports_only -top_only
write_verilog -noexpr "ports_only_in_top.v"
tee -o "ports_only_in_top.txt" stat
foreach {nets ports} [read_stats "ports_only_in_top.txt"] {}
assert_count "nets" $nets 26
assert_count "ports" $ports 16
design -load "pre"
splitnets -ports_only
write_verilog -noexpr "ports_only_in_all.v"
tee -o "ports_only_in_all.txt" stat
foreach {nets ports} [read_stats "ports_only_in_all.txt"] {}
assert_count "nets" $nets 30
assert_count "ports" $ports 20
design -load "pre"
splitnets -ports -top_only
write_verilog -noexpr "ports_nets_in_top.v"
tee -o "ports_nets_in_top.txt" stat
foreach {nets ports} [read_stats "ports_nets_in_top.txt"] {}
assert_count "nets" $nets 30
assert_count "ports" $ports 16
design -load "pre"
splitnets -ports
write_verilog -noexpr "ports_nets_in_all.v"
tee -o "ports_nets_in_all.txt" stat
foreach {nets ports} [read_stats "ports_nets_in_all.txt"] {}
assert_count "nets" $nets 40
assert_count "ports" $ports 20
exit 0

View file

@ -0,0 +1,13 @@
module bottom(input clk, input wire [1:0] i, output reg [1:0] q);
reg [1:0] q1;
always @(posedge clk) begin
q1 <= i;
q <= q1;
end
endmodule
module top(input clk, input wire [1:0] i, output reg [1:0] q);
reg [1:0] q1;
bottom u1 (.clk(clk), .i(i), .q(q1));
not u2 (q, q1);
endmodule

View file

@ -0,0 +1 @@
tcl test_splitnets.tcl