0

I want to implement open collector protocol. When I try to set inout type port to 'Z' value, which is pulled up, it just continue to hold its previous value. To elucidate, I have just written the following VHDL code which first set o_sample_trig to 0 then set to to 'z' ( high impedance) state, since the o_sample_trig pin is pulled up it should immediately go to '1' state, but instead continue sending '0'! please advise me.

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
--********************************************
entity TopLvl is
port(
    clk,reset : in std_logic;
    max_tick: out std_logic;
    o_sample_trig: inout std_logic
    );
 end TopLvl;
 --***************************************************
architecture Behavioral of TopLvl is
signal timer1_reg,timer1_next : integer range 0 to 23999999:=0;
 attribute PULLUP: string;
 attribute PULLUP of o_sample_trig : signal is "TRUE";

begin

process ( clk ,reset)
begin
        if(reset ='1') then
            timer1_reg <= 0;
        elsif ( clk'event and clk='1' ) then 
             timer1_reg <= timer1_next;
        end if;
end process;

 --**************************************************       
  process ( clk ,timer1_reg)
  begin

            Timer1_next <= timer1_reg+1;


        if (timer1_reg >= 100 and timer1_reg < 150)  or (timer1_reg >= 200 and timer1_reg < 225) or (timer1_reg = 300) then 
            o_sample_trig<='0';
        elsif (timer1_reg >= 150 and timer1_reg < 200) or (timer1_reg >= 225 and timer1_reg < 300) or (timer1_reg >= 400) then
            o_sample_trig<='Z';
        end if;         
        if (timer1_reg >= 151 and timer1_reg < 199 and o_sample_trig = '1') then
            max_tick<= '1';
        end if;

end process;


end Behavioral;
Reflection
  • 399
  • 2
  • 11

3 Answers3

1

You need to model the pull-up resistor. In your test bench, assign 'H' (driving a weak one) to your tri-state signal:

o_sample_trig <= 'H';

You also probably need to fix your second process and add a conditional for the clock signal. What you have might simulate, but it likely won't synthesize into hardware.

Charles Steinkuehler
  • 3,335
  • 18
  • 12
  • according to pedroni's book, 'H' will be synthesized as '1'. It did not work. – Reflection Feb 04 '19 at 14:55
  • I think Charles's suggestion is that if you have a open-collector, then there must be a pull-up somewhere - such as the board, the IO cell, or the testbench. None the less, this must be modeled to be able to simulate. Hence, as Charles suggested, perhaps you need to have it in your testbench? Since the testbench is not synthesized, this will be fine, but also see below as this is only half of the solution – Jim Lewis Feb 04 '19 at 17:42
  • I do not attempt to design circuit for simulation at all. what I want is that I want to know why inout port not receiving input in the real world! and yes surly I tried to use physical pull up. besides 'H' state is defined to be used in simulation only. – Reflection Feb 06 '19 at 09:13
  • I already answered this question my self, the problem was the way I configure tristate buffer – Reflection Feb 06 '19 at 10:51
  • If max tick is not part of your concern, then post a minimal complete example for review here that does not include it. – Jim Lewis Feb 07 '19 at 18:30
1

First re-read the post about pull-ups. It is half of your solution.

Second, your logic about max_tick is wrong. You need to handle 'H' as well as 1 and have an assignment for 0.

    if (timer1_reg >= 151 and timer1_reg < 199 and to_x01(o_sample_trig) = '1') then
        max_tick <= '1';
    else
        max_tick <= '0';
    end if;
Jim Lewis
  • 3,601
  • 10
  • 20
  • it is not what I wanted to do, I want to send 0 through o_sample_trig port during timer1_reg >= 100 and timer1_reg < 150 interval, then receive input from the same port during timer1_reg >= 150 and timer1_reg < 200 interval. I do not want to trigger max_tick . I just mentioned max_tick in order to synthesis tool not omit this port. and I have read pull up that is what I conceive from it please advise. – Reflection Feb 06 '19 at 09:08
  • I already answered this question myself, the problem was the way I configure tristate buffer – Reflection Feb 06 '19 at 10:51
  • If you leave your max_tick logic as it is, it starts at 'X' (which in some technologies can be a 1) and then later is assigned to a 1. It is never 0. Hence, it is not the sort of hardware most of us would ever expect to use or allow in a review. – Jim Lewis Feb 07 '19 at 18:25
0

according to Pedroni's book you cannot use a in/out port in that way and you should configure Tristate buffer in the following way:

1 ------------------------------
2 LIBRARY ieee;
3 USE ieee.std_logic_1164.all;
4 ------------------------------
5 ENTITY bidir IS
6 PORT (a, b: IN STD_LOGIC;
7 c: INOUT STD_LOGIC;
8 d: OUT STD_LOGIC);
9 END ENTITY;
10 ------------------------------
11 ARCHITECTURE arch1 OF bidir IS
12 BEGIN
13 c <= a WHEN b='1' ELSE 'Z';
14 d <= c;
15 END ARCHITECTURE;
16 ------------------------------
17 ARCHITECTURE arch2 OF bidir IS
18 BEGIN
19 PROCESS (a, b)
20 BEGIN
21 d <= c;
22 IF (b='1') THEN c <= a;
23 ELSE c <= 'Z';
24 END IF;
25 END PROCESS;
26 END ARCHITECTURE;
27 ------------------------------

using above code I managed to actually synthesize a tristate buffer.

Reflection
  • 399
  • 2
  • 11