Steps to reproduce the issue
When I've compiled i4004 block from http://www.opencores.org/cores/mcs-4/
I've encountered a problem with IO buffer insertion for inout port.
The problem is, that z-state for this port is hidden in the second layer of conditional operator.
assign data_pad = poc ? 4'b0000 : (n0700 ? 4'bzzzz : data_out);
In this case tri-buf isn't on the same level, as the assignment, so IO insertion logic failed.
To test this assumption I've used 32-bit mxe-build Yosys of commit dadaf7e in Windows 7 OS.
The first design was:
module bidirtest (A, COND, DATA, EO, Q, BI);
inout BI;
output Q;
input A, COND, DATA, EO;
assign BI = COND ? 1'b0 : (A ? 1'bz : DATA);
assign Q = BI;
endmodule
The synthesis script was:
read_verilog bidirtest.v
tribuf -logic
synth -top bidirtest
iopadmap -bits -inpad IBUF O:PAD -outpad OBUF I:PAD -tinoutpad IOBUF ENA:O:I:PAD bidirtest
write_verilog -noattr proj_iotemp.v
As expected, Yosys didn't detect z-state buffer, It didn't even isert any IO cell for the BI port:
/* Generated by Yosys 0.9+932 (git sha1 dadaf7ed, i686-w64-mingw32.static-g++ 5.5.0 -Os) */
module bidirtest(A, COND, DATA, EO, Q, BI);
wire _00_;
wire _01_;
wire _02_;
wire _03_;
wire _04_;
input A;
inout BI;
input COND;
input DATA;
input EO;
output Q;
assign BI = _02_ & ~(_03_);
IBUF _06_ (
.O(_04_),
.PAD(A)
);
IBUF _07_ (
.O(_03_),
.PAD(COND)
);
IBUF _08_ (
.O(_02_),
.PAD(DATA)
);
IBUF _09_ (
.O(_01_),
.PAD(EO)
);
OBUF _10_ (
.I(_00_),
.PAD(Q)
);
assign _00_ = BI;
endmodule
Expected behavior
When the same expression is changed to have z-state on the upper-most level, then everything will work well.
RTL Verilog:
module bidirtest (A, COND, DATA, EO, Q, BI);
inout BI;
output Q;
input A, COND, DATA, EO;
assign BI = !COND && A ? 1'bz : (COND ? 1'b0 : DATA);
assign Q = BI;
endmodule
The output netlist:
/* Generated by Yosys 0.9+932 (git sha1 dadaf7ed, i686-w64-mingw32.static-g++ 5.5.0 -Os) */
module bidirtest(A, COND, DATA, EO, Q, BI);
wire _00_;
wire _01_;
wire _02_;
wire _03_;
wire _04_;
wire _05_;
wire _06_;
wire _07_;
input A;
inout BI;
input COND;
input DATA;
input EO;
output Q;
assign _01_ = _04_ & ~(_05_);
assign _00_ = _05_ | ~(_06_);
IOBUF _10_ (
.ENA(_00_),
.I(_01_),
.O(_07_),
.PAD(BI)
);
IBUF _11_ (
.O(_06_),
.PAD(A)
);
IBUF _12_ (
.O(_05_),
.PAD(COND)
);
IBUF _13_ (
.O(_04_),
.PAD(DATA)
);
IBUF _14_ (
.O(_03_),
.PAD(EO)
);
OBUF _15_ (
.I(_02_),
.PAD(Q)
);
assign _02_ = _07_;
endmodule
Actual behavior
It didn't insert IO cell and didn't detect tribuf.
Steps to reproduce the issue
When I've compiled i4004 block from http://www.opencores.org/cores/mcs-4/
I've encountered a problem with IO buffer insertion for inout port.
The problem is, that z-state for this port is hidden in the second layer of conditional operator.
In this case tri-buf isn't on the same level, as the assignment, so IO insertion logic failed.
To test this assumption I've used 32-bit mxe-build Yosys of commit dadaf7e in Windows 7 OS.
The first design was:
The synthesis script was:
As expected, Yosys didn't detect z-state buffer, It didn't even isert any IO cell for the BI port:
Expected behavior
When the same expression is changed to have z-state on the upper-most level, then everything will work well.
RTL Verilog:
The output netlist:
Actual behavior
It didn't insert IO cell and didn't detect tribuf.