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

High impedance assignment translates to 1'x #170

Open
DanielG opened this issue Jul 20, 2022 · 6 comments
Open

High impedance assignment translates to 1'x #170

DanielG opened this issue Jul 20, 2022 · 6 comments

Comments

@DanielG
Copy link
Contributor

DanielG commented Jul 20, 2022

When trying to assign a pin to HiZ I get a hard low drive instead. Reproducer below. I dub this bug "resisting high impedance" :)

ent.vhdl:

library ieee;
use ieee.std_logic_1164.all;

entity ent is
  port (p : out std_ulogic);
end entity;

architecture a of ent is
begin
  p <= 'Z';
end architecture;

GHDL synth keeps the 'Z':

$ ghdl synth -e ent.vhdl
library ieee;
use ieee.std_logic_1164.all;
entity ent is
  port (
    p: out std_ulogic
  );
end entity;

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

architecture rtl of ent is
  signal wrap_p: std_logic;
  constant n1_o : std_logic := 'Z';  --- <-- Hi-Z still here
begin
  p <= wrap_p;
  wrap_p <= n1_o;
end rtl;

but ghdl-yosys-plugin seems to translate it to 1'x:

$ ghdl import ent.vhdl && ghdl make ent && yosys -m ghdl -p 'ghdl ent; write_rtlil'
[...]
# Generated by Yosys 0.12 (git sha1 2156e20)
autoidx 1
module \ent
  wire output 1 \p
  connect \p 1'x
end

Versions (all using my Debian packaging):

ghdl-yosys-plugin 0.0~git20211127.09a32cd-2~bpo11+1
ghdl 2.0.0+dfsg-1~bpo11+1
yosys 0.12-1~bpo11+1

@tgingold
Copy link
Member

tgingold commented Jul 20, 2022 via email

@DanielG
Copy link
Contributor Author

DanielG commented Jul 21, 2022

I managed to work around this using 'X' when false else 'Z' instead. This generates a $tribuf which seems to work. Perhaps the ghdl plugin should also use this pattern? I'd be happy to report a yosys bug too though.

@DanielG
Copy link
Contributor Author

DanielG commented Jul 21, 2022

Looks like there's an open yosys bug for this: YosysHQ/yosys#511

@DanielG
Copy link
Contributor Author

DanielG commented Jul 21, 2022

Here's a gdb session log for the yosys reproducer above. Looks like internally the constant does have the Sz value but the rtlil backend dumps it as 'x' in this code because is_fully_undef returns true:

void RTLIL_BACKEND::dump_const(...)
        [...]
	if (data.is_fully_undef()) {
		f << "x";
	} else {
		for (int i = offset+width-1; i >= offset; i--) {
			log_assert(i < (int)data.bits.size());
			switch (data.bits[i]) {
			case State::S0: f << stringf("0"); break;
			case State::S1: f << stringf("1"); break;
			case RTLIL::Sx: f << stringf("x"); break;
			case RTLIL::Sz: f << stringf("z"); break;
			case RTLIL::Sa: f << stringf("-"); break;
			case RTLIL::Sm: f << stringf("m"); break;
			}
		}
	}
2. Executing RTLIL backend.
Output filename: <stdout>
# Generated by Yosys 0.12 (git sha1 2156e20)
autoidx 1
attribute \cells_not_processed 1
attribute \src "/home/dxld/share/elec/nppd/fpga/repro/resisting-high-impedance/ent.v:1.1-3.10"
module \ent
  attribute \src "/home/dxld/share/elec/nppd/fpga/repro/resisting-high-impedance/ent.v:1.20-1.21"
  wire output 1 \v

Breakpoint 4, Yosys::RTLIL_BACKEND::dump_const (f=..., data=..., width=1, 
    offset=0, autoint=true) at backends/rtlil/rtlil_backend.cc:34
34	{
(gdb) tbreak RTLIL::Const::is_fully_undef
Temporary breakpoint 5 at 0x5555556ad9c4: file kernel/rtlil.cc, line 372.
(gdb) c
Continuing.

Temporary breakpoint 5, Yosys::RTLIL::Const::is_fully_undef (
    this=this@entry=0x7fffffffd648) at kernel/rtlil.cc:372
warning: Source file is more recent than executable.
372		cover("kernel.rtlil.const.is_fully_undef");
(gdb) p bits
$4 = std::vector of length 1, capacity 1 = {Sz}
(gdb) n
374		for (const auto &bit : bits)
(gdb) 
375			if (bit != RTLIL::State::Sx && bit != RTLIL::State::Sz)
(gdb) p bit
$5 = (const State &) @0x555555ebd7c0: Sz

@DanielG
Copy link
Contributor Author

DanielG commented Jul 21, 2022

Indeed the write_verilog output looks correct. I'm pretty sure something in the toolchain is miscompiling this as I can observe the bus conflicts on my Oscilloscope :)

@tgingold
Copy link
Member

tgingold commented Jul 21, 2022 via email

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