Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

VHDL simulation of open drain pull ups

Status
Not open for further replies.

shaiko

Advanced Member level 5
Joined
Aug 20, 2011
Messages
2,644
Helped
303
Reputation
608
Reaction score
297
Trophy points
1,363
Activity points
18,302
Hello,

I'd like to simulate open drain pulled up ports in my testbench.
For example: I2C clock and data inout ports are outputed as high 'Z' an then pulled up to a '1' by a pull up resistor to achieve a "wired and".

In my simulation, I want the outputs that get <= 'Z' to be resolved as a logic '1'.
I know that the correct way to do it is write a resolution function. But I don't know how and where to write it...please help me with the VHDL code.

---------- Post added at 11:07 ---------- Previous post was at 10:52 ----------

------------------------------------------
function resolve_logic (drivers : in logic_array) return logic_level;
begin
for index in drivers'range loop
if drivers(index) = L then
return L;
end if;
end loop;
return H;
end resolve_logic;
------------------------------------------
I found the function above but I don't know where to put it so it would work and pull the 'Z' to '1' and resolve '0' and 'Z' to '0'
 

Why not use the existing resolution function for std_logic?

Add this line somewhere:

my_inout_signal <= 'H';

'H' is a weak '1'.
When all other drivers drive the signal to 'Z',
the 'H' will "win" the resolution.
When another driver drives this signal to '1' or '0',
the 'H' will have no effect.

I have not tested this, but I think it should work.
 

Hi std_match,

I want to be able to do this without changing the RTL code. Hence, the signal must be resolved from the the testbench side...
 

It should not matter where you drive the signal to 'H',
so it should be OK to have it in the test bench.
 

Please elaborate.

in my RTL component: some_inout_signal <= 'Z';
How do I write the testbench code with 'H' so that "some_inout_signal" is pulled up to '1' ?
 

You add a driver to the test bench signal (std_logic) that is connected to "some_inout_signal".

test_bench_signal_connected_to_dut_open_drain <= 'H';

As I said, I have not tested this, but I can't see why it shouldn't work.
 

Tried it, not good.
I need my RTL to "see" (register back) a '1' when it itself drives the output to 'Z' and no other signal on the bus pulls it to '0'.

For examle:

-- we drive an inout port to 'Z' somewhere in our RTL code
inout_port <= 'Z'

-- we register back the inout_port in a synchronous process to see its value
registered_inout_port <= inout_port;

I want to see the "registered_inout_port" in the waveform as '1' when no other signal pulls it down to '0'.
but with what you suggested - it shows 'H' instead of '1'...

Resolution function...anyone?
 

if you write a resolution function, you will have to change all your logic to the 2nd type, which wont be supported by the synthesisor properly.

I still dont understand what you are trying to do in your testbench. It's as if you're trying to see something in the testbench that has nothing to do with the UUT. I also dont understand what you mean by "registered" inout port. This is not possible. Registers only go in 1 direction, with the output connected to a tri-state buffer.
 

Tried it, not good.
I need my RTL to "see" (register back) a '1' when it itself drives the output to 'Z' and no other signal on the bus pulls it to '0'.

For examle:

-- we drive an inout port to 'Z' somewhere in our RTL code
inout_port <= 'Z'

-- we register back the inout_port in a synchronous process to see its value
registered_inout_port <= inout_port;

I want to see the "registered_inout_port" in the waveform as '1' when no other signal pulls it down to '0'.
but with what you suggested - it shows 'H' instead of '1'...

Resolution function...anyone?

The 'H' should have the same effect as '1' in your simulation. It will be seen as '1' when you use it in any logic function,
but you can also do it explicitly like this:

registered_inout_port <= To_X01(inout_port);

That should have no effect for synthesis, but the simulation will convert 'H' to '1'.
 

'H' doesn't have the same effect as '1'.
inout_signal = 'H' isn't the same as inout_signal = '1'
what if I don't have access to the RTL .vhd ?
 
Last edited:

then why not just connect the inout_signal to '1'? if its driving 'Z' intenerally then the read logic will be able to see '1'. You should also have access to the enable signal so that you know when to switch to 'Z'
 

'H' doesn't have the same effect as '1'.
inout_signal = 'H' isn't the same as inout_signal = '1'
what if I don't have access to the RTL .vhd ?

Ok, 'H' can break the simulation. All functions in std_logic_1164 will work, but code like " if inout_signal = '1' " will fail.

One more thing to try in the test bench (I have not tested it):

Code:
pull_up: process(test_bench_signal_connected_to_dut_open_drain)
begin
  -- The output from this process will be latched to '1' or 'Z'
  if test_bench_signal_connected_to_dut_open_drain = 'Z' then
    test_bench_signal_connected_to_dut_open_drain <= '1';
  else if test_bench_signal_connected_to_dut_open_drain = 'X' then
    test_bench_signal_connected_to_dut_open_drain <= 'Z';
  end if;
end process pull_up;
 
  • Like
Reactions: shaiko

    shaiko

    Points: 2
    Helpful Answer Positive Rating
then why not just connect the inout_signal to '1'?'

That's an inout port...the tesbench side also drives the signal. Think of the following on an I2C bus:
A master sends the address and waits for the slave to acknowledge by pulling the bus to '0'.
No one drives the bus to '1'...a '1' level is achieved by the pull up resistors.

I need a simple resolution function that converts the 'Z's to '1'...
 

A '1' and a 'Z' driven together will give '1'.

The DUT and the test bench must also be able to drive the signal to '0'. If the testbench drives it to '1', it can never be '0', only '1' and 'X'.

We have two or more drivers, they drive '0' or 'Z'.
We want the signal to be '0' if any driver drives '0', otherwise we want '1'.
 

exactly...in the "real world" it's done on the PCB or by an internal pull up on the IC.
I'd like to do the same on the testbench
 

One more thing to try in the test bench (I have not tested it):

If you get 'U' in the simulation, change so that 'X' or 'U' will activate the 'Z' driver:

Code:
pull_up: process(test_bench_signal_connected_to_dut_open_drain)
begin
  -- The output from this process will be latched to '1' or 'Z'
  if test_bench_signal_connected_to_dut_open_drain = 'Z' then
    test_bench_signal_connected_to_dut_open_drain <= '1';
  else if test_bench_signal_connected_to_dut_open_drain = 'X'
    or test_bench_signal_connected_to_dut_open_drain = 'U'  then
    test_bench_signal_connected_to_dut_open_drain <= 'Z';
  end if;
end process pull_up;

I still haven't tested this.
 
  • Like
Reactions: shaiko

    shaiko

    Points: 2
    Helpful Answer Positive Rating
Seems to do the job...however the signals are "very colorfull".
On the rising edge of the pulled up signal it's blue (supposedly 'Z') for an Infinitesimal amount of time and on the falling edge it's red (supposedly 'X'). Otherwise when the signal is stable it's green (at '1' or '0' as it's supposed to be).
Some kind of a race condition on the edges...
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top