Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Incorrect inferrence of 3-state inout buffer #1530

Closed
mkurc-ant opened this issue Nov 26, 2019 · 3 comments
Closed

Incorrect inferrence of 3-state inout buffer #1530

mkurc-ant opened this issue Nov 26, 2019 · 3 comments
Assignees

Comments

@mkurc-ant
Copy link
Contributor

When inferring a 3-state inout buffer that is controlled directly by other inputs/outputs, the output of the inferred buffer cell gets disconnected.

Happens on Yosys @0466c485 and earlier.

Consider the following design:

module top
(
input  wire [1:0] in,
output wire [0:0] out,
inout  wire my_inout
);

// IOBUF
wire iob_i;
wire iob_o;
wire iob_t;

// Implement the 3-state buffer using assigns.
assign iob_o    = my_inout;
assign my_inout = (iob_t == 1'b0) ? iob_i : 1'bz;

// Controll the 3-state buffer from other IOs
assign iob_i = in[0];
assign iob_t = in[1];

assign out[0] = iob_o;

endmodule

Processed by the following Yosys script:

read_verilog iopadmap_test.v
tribuf
synth_xilinx -vpr -flatten -abc9 -nosrl -noclkbuf -nodsp
iopadmap -bits -outpad OBUF I:O -inpad IBUF O:I -toutpad OBUFT T:I:O -tinoutpad IOBUF T:O:I:IO A:top
write_verilog out_synth.v
show

After synthesis I got the IOBUF with the output port O disconnected and the 3-state input is taken directly from the inout port which is incorrect.

Expected behavior

After synthesis the my_inout port is connected directly to the IOBUF.IO port and nothing else. The 3-state "input" path is connected to the IOBUF.O port while the "output" path is connected to IOBUF.I and IOBUF.T ports.

Actual behavior

After synthesis the IOBUF.O port is disconnected, the my_input inout port is connected directly to IOBUF.IO but the 3-state "input" is taken directly from my_input instead of the IOBUF.O port.

The diagram produced by show indicates the problem:
image

The verilog produced by the write_verilog command also shows the incorrect connection:

(* top =  1  *)
(* src = "iopadmap_test.v:3" *)
module top(in, out, my_inout);
  wire _0_;
  wire _1_;
  wire [1:0] _2_;
  wire _3_;
  (* src = "iopadmap_test.v:5" *)
  input [1:0] in;
  (* src = "iopadmap_test.v:12" *)
  wire iob_i;
  (* src = "iopadmap_test.v:13" *)
  wire iob_o;
  (* src = "iopadmap_test.v:14" *)
  wire iob_t;
  (* src = "iopadmap_test.v:8" *)
  inout my_inout;
  (* src = "iopadmap_test.v:6" *)
  output out;
  (* module_not_derived = 32'd1 *)
  INV _4_ (
    .I(_2_[1]),
    .O(_0_)
  );
  (* keep = 32'd1 *)
  IOBUF _5_ (
    .I(_2_[0]),
    .IO(my_inout),
    .O(_1_),
    .T(_0_)
  );
  (* keep = 32'd1 *)
  IBUF _6_ (
    .I(in[0]),
    .O(_2_[0])
  );
  (* keep = 32'd1 *)
  IBUF _7_ (
    .I(in[1]),
    .O(_2_[1])
  );
  (* keep = 32'd1 *)
  OBUF _8_ (
    .I(_3_),
    .O(out)
  );
  assign iob_i = _2_[0];
  assign iob_o = my_inout;
  assign iob_t = _2_[1];
  assign _3_ = my_inout;
endmodule
@mwkmwkmwk
Copy link
Member

Use #1527 and #1528.

@mwkmwkmwk mwkmwkmwk self-assigned this Nov 26, 2019
@mkurc-ant
Copy link
Contributor Author

@mwkmwkmwk Thanks, that solves my problems. I hope that will get merged soon.

@mwkmwkmwk
Copy link
Member

Fixed by #1527

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants