Reputation: 6587
In VHDL, How to implement two tristates driving the same pin with a pullup? I tried to do the same thing in Verilog and it synthesizes without any problem:
`timescale 1ns/10ps
module driver(
input wire oe,
input wire di,
output tri1 do
);
assign do = oe ? di : 1'bz;
endmodule
`timescale 1ns/10ps
module top(
input wire oe1,
input wire di1,
input wire oe2,
input wire di2,
output tri1 do
);
driver driver1(
.oe (oe1),
.di (di1),
.do (do)
);
driver driver2(
.oe (oe2),
.di (di2),
.do (do)
);
endmodule
When I try to write this in VHDL, I get a little bit stuck because VHDL I'm not sure how to map Verilog's tri1 "pullup" into VHDL.
library ieee;
use ieee.std_logic_1164.all;
entity driver is
port(
oe :in std_logic;
di :in std_logic;
do :out std_logic
);
end entity;
architecture rtl of driver is
begin
do <= di when (oe = '1') else 'Z';
end architecture;
library ieee;
use ieee.std_logic_1164.all;
entity top is
port(
oe1 :in std_logic;
di1 :in std_logic;
oe2 :in std_logic;
di2 :in std_logic;
do :out std_logic
);
end entity;
architecture rtl of top is
begin
driver1: entity work.driver
port map(
oe => oe1,
di => di1,
do => do
);
driver2: entity work.driver
port map(
oe => oe2,
di => di2,
do => do
);
-- QUESTION: signal 'do' doesn't pull up to 'H'
---when oe1='0' and oe2='0'..
-- How to fix it in VHDL to do this so that pulls up
-- like 'tri1' signal in the Verilog version of this code.
end architecture;
I tried change the 'Z' in driver to 'H'... this cause synthesis to fail with a warning of multiple drivers to signal 'do'.
I tried add the line "do <= 'H';" to the top level architecture as suggested in another stackoverflow post on VHDL pullups. Also doesn't work, synthesis fails with a warning of multiple drivers to signal 'do'.
My question is: how to get the functionality of "tri1" pullup in VHDL code to pull up signal 'do' to 'H' when its not driven and both drivers have 'Z' output.
Upvotes: 1
Views: 1410
Reputation: 6587
-- implementing a pullup...
-- this appears to synthesize in vivado without multiple driver error...
-------------------------------------
-- module: pullup
-------------------------------------
library ieee;
use ieee.std_logic_1164.all;
-- pullup
entity pullup is
port(
di: in std_logic;
dz: out std_logic
);
end entity;
architecture rtl of pullup is
begin
dz <= 'H' when (di = 'Z') else di;
end architecture;
-------------------------------------
-- module: driver
-------------------------------------
library ieee;
use ieee.std_logic_1164.all;
entity driver is
port(
oe :in std_logic;
di :in std_logic;
do :out std_logic
);
end entity;
architecture rtl of driver is
begin
process(oe, di)
begin
if (oe = '1') then
do <= di;
else
do <= 'Z';
end if;
end process;
end architecture;
-------------------------------------
-- module: top
-------------------------------------
library ieee;
use ieee.std_logic_1164.all;
entity top is
port(
oe1 :in std_logic;
di1 :in std_logic;
oe2 :in std_logic;
di2 :in std_logic;
do :out std_logic
);
end entity;
architecture rtl of top is
signal doz: std_logic;
begin
driver1: entity work.driver
port map(
oe => oe1,
di => di1,
do => doz
);
driver2: entity work.driver
port map(
oe => oe2,
di => di2,
do => doz
);
pullup: entity work.pullup
port map(
di => doz,
dz => do
);
--do <= 'H' when (doz = 'Z') else doz;
end architecture;
Upvotes: 0
Reputation: 816
What about adding this line in the top architecture:
do <= 'Z' when (oe1 = '1') or (oe2 = '1') else 'H';
Upvotes: 1