Skip to content

Tribuf hierarchy on bidirectional IO buffer insertion #1595

Description

@Gl237man

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.

Metadata

Metadata

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions