Bimo
Bimo

Reputation: 6587

In VHDL, How to implement two tristate buffers driving the same pin with a PULLUP?

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

Answers (2)

Bimo
Bimo

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

Giampietro Seu
Giampietro Seu

Reputation: 816

What about adding this line in the top architecture:

do <= 'Z' when (oe1 = '1') or (oe2 = '1') else 'H';

Upvotes: 1

Related Questions