Open tmichalak opened 4 years ago
Recently, I encountered the same error and created some tests to investigate the problem. It turned out that the OBUFT inference in submodules works in some cases. The tests below use the synth_xilinx
command for synthesis (I split the synth_xilinx
command into few parts, to obtain the diagrams before the iopadmap
call)
$_TBUF_
in a top-level module:sources:
module top (
input wire sw_oe,
input wire btn_iout,
output wire led
);
assign led = sw_oe ? btn_iout : 1'bz;
endmodule
- before `iopadmap`:
![tbuf_case1_before_iopadmap](https://user-images.githubusercontent.com/52699314/94288200-70ec6680-ff57-11ea-8620-ac3b2a529821.png)
- after `iopadmap`:
![tbuf_case1_after_iopadmap](https://user-images.githubusercontent.com/52699314/94288036-41d5f500-ff57-11ea-8c7e-521aed2bdd7e.png)
- comment:
This case is correctly resolved
### Test Case 2: OBUFT inference in place of `$_TBUF_` in a submodule:
- sources:
module top ( input wire sw_oe, input wire btn_iout, output wire led );
pad_wrapper wrap1 (sw_oe, btn_iout, led);
endmodule
module pad_wrapper ( input wire i_oe, input wire i_out, output wire o_out );
assign o_out = i_oe ? i_out : 1'bz;
endmodule
- before `iopadmap`:
![tbuf_case2_before_iopadmap](https://user-images.githubusercontent.com/52699314/94288451-b5780200-ff57-11ea-8524-fcd134c93619.png)
- after `iopadmap`:
![tbuf_case2_after_iopadmap](https://user-images.githubusercontent.com/52699314/94288475-ba3cb600-ff57-11ea-9558-3b76a7cd0567.png)
- comment:
This case is correctly resolved
### Test Case 3: Mixed case
- sources:
module top ( input wire [1:0] sw_en, input wire [1:0] btn_led, output wire [1:0] leds );
assign leds[0] = sw_en[0] ? btn_led[0] : 1'bz;
pad_wrapper wrap1 (sw_en[1], btn_led[1], leds[1]);
endmodule
module pad_wrapper ( input wire i_oe, input wire i_out, output wire o_out );
assign o_out = i_oe ? i_out : 1'bz;
endmodule
- before `iopadmap`:
![tbuf_case3_before_iopadmap](https://user-images.githubusercontent.com/52699314/94288681-fa9c3400-ff57-11ea-9d33-fbf91e766d69.png)
- after `iopadmap`:
![tbuf_case3_after_iopadmap](https://user-images.githubusercontent.com/52699314/94288700-012aab80-ff58-11ea-9956-68fd288f074a.png)
- comment:
It seems that the mixed case of the two previous scenarios causes problems. I noticed that the top-level module output is not directly connected to the `$_TBUF_` output in the last case.
Maybe this is a source of the problems.
Here are all the tests with synthesis scripts:
[yosys_obuft.zip](https://github.com/YosysHQ/yosys/files/5283918/yosys_obuft.zip)
@mwkmwkmwk Do you have any thoughts, how this issue might be resolved?
Steps to reproduce the issue
Testcase: obuft_inference_bug.zip
make top.edif
to generate the invalid EDIF.Expected behavior
The final EDIF should contain OBUFT primitives instead of TBUF.
Actual behavior
When there is
assign IO_UTX = (cio_uart_tx_en_d2p ? cio_uart_tx_d2p : 1'bz);
in the top module theOBUFT
is correctly inferred. However if I have the statement inside a submodule I end up with_TBUF_
cells which are obviously not recognized in Vivado.