For context, please look at my attached diagram to see what I am trying to accomplish.
Essentially, I want to swap inout wires using a contained hierarchy that will allow me to have more modular RTL in my design.
The problem is that it is difficult to do swapping of inout wires in SystemVerilog and the only way I found that was able to accomplish this led to a non-synthesizable error, despite it being the same functional behavior of doing it in a different, less modular way.
Adding minimum reproducible code below as requested - The code below does the expected swapping but using the alias command. I would like to accomplish similar behavior but without the alias command. Thank you.
mod_a.sv
module mod_a (
inout bit0,
inout bit1,
input signal_a,
input [1:0] bus_a
);
wire mod_b_bit0;
wire mod_b_bit1;
mod_b u_mod_b (
.bit0(mod_b_bit0),
.bit1(mod_b_bit1),
.signal_a(signal_a),
.bus_a(bus_a)
);
mapper u_mapper (
.mod_b_bit0(mod_b_bit0),
.mod_b_bit1(mod_b_bit1),
.bit0(bit0),
.bit1(bit1)
);
endmodule
mod_b.sv
module mod_b (
inout bit0,
inout bit1,
input signal_a,
input [1:0] bus_a
);
assign bit0 = signal_a ? 1'bZ : bus_a[0];
assign bit1 = signal_a ? 1'bZ : bus_a[1];
endmodule
mapper.sv
module mapper (
inout mod_b_bit0,
inout mod_b_bit1,
inout bit0,
inout bit1
);
alias bit0 = mod_b_bit1; //swap
alias bit1 = mod_b_bit0; //swap
endmodule
tb.sv
module testbench_top;
wire bit0;
wire bit1;
logic signal_a;
logic [1:0] bus_a;
logic dq0_driver;
logic dq1_driver;
assign bit0 = signal_a ? dq0_driver : 1'bZ;
assign bit1 = signal_a ? dq1_driver : 1'bZ;
initial begin
signal_a = 0;
dq0_driver = 0;
dq1_driver = 0;
bus_a = $random();
#20
signal_a = 1;
dq0_driver = 1;
dq1_driver = 0;
#20
signal_a = 0;
bus_a = $random();
#20
signal_a = 1;
dq0_driver = 0;
dq1_driver = 1;
#20
signal_a = 0;
bus_a = $random();
#20
signal_a = 1;
dq0_driver = 1;
dq1_driver = 1;
#20
signal_a = 0;
bus_a = $random();
#20
signal_a = 1;
dq0_driver = 0;
dq1_driver = 0;
#20
signal_a = 1;
dq0_driver = 1;
dq1_driver = 0;
#1000 $stop;
end
mod_a u_mod_a ( //mod A
.bit0(bit0),
.bit1(bit1),
.signal_a(signal_a),
.bus_a(bus_a)
);
endmodule
The resolution for this was shared by Greg in the comment of my post.
2 potential solutions -
Solution #1: Two implicitly named ports connected to same internal net (non-ANSI style module header)
module submapper(
bit0,
bit0,
bit1,
bit1
);
inout bit0;
inout bit1;
endmodule
module mapper (
inout mod_b_bit0,
inout mod_b_bit1,
inout bit0,
inout bit1
);
submapper u_submapper(
bit0,
mod_b_bit1, //swap happens here
bit1,
mod_b_bit0 //swap happens here
);
endmodule
Solution #2 (CLEANER): Two ports with different names connected to same internal net (non-ANSI style module header)
module submapper2(
.bit0(bit0), .mod_b_bit0(bit1), //swap happens here
.bit1(bit1), .mod_b_bit1(bit0) //swap happens here
);
inout bit0;
inout bit1;
endmodule
module mapper (
inout mod_b_bit0,
inout mod_b_bit1,
inout bit0,
inout bit1
);
submapper2 u_submapper2 (.*);
endmodule
I have tested both and they can compile, elaborate, and synthesize without any errors. Thanks Greg.