outputs are in conflict most of the time

Discussion in 'VHDL' started by Martijn van Pottelberghe, Sep 27, 2006.

  1. Hello everybody,

    I'm trying to make a vhdl implementation of an 74162 (bcd counter with load)
    Defined an entity and architecture, and entered a behavioural description
    that I think should be ok overall.

    After this definition, I made a testbench vhdl-file in order to simulate the
    thing using modelsim.

    Because i'm not even sure if the conflict appears within the testbench, or
    in the component description, I'll insert both heir vhdl files below.
    In order not to bother you too much I commented extensively so at least my
    reasonings should be easy to follow.

    Also I have a nice small png file of simulated signals, but the news server
    won't let me post those 13kb..

    Thanks for your attention so far..
    Help would be greatly appreciated.

    Regards,
    Martijn

    Here comes the 74162:
    =====================================================
    library ieee;
    use ieee.std_logic_1164.all;
    use ieee.numeric_std.all;

    entity sn_74162 is
    port (
    clr : in std_logic;
    load : in std_logic;
    ent : in std_logic;
    enp : in std_logic;
    clk : in std_logic;
    a : in std_logic;
    b : in std_logic;
    c : in std_logic;
    d : in std_logic;
    oa : out std_logic;
    ob : out std_logic;
    oc : out std_logic;
    od : out std_logic;
    rco : out std_logic;

    reset : in std_logic -- not an 74162's pin, though useful for testing
    purposes
    );
    end sn_74162;

    architecture gedrag of sn_74162 is
    signal num_out: std_logic_vector(3 downto 0);
    signal rco_on: std_logic; -- when i want to change rco, in fact i write to
    rco_on
    -- i do this in order to have a readable version of rco

    begin
    oa <= num_out(0);
    ob <= num_out(1); -- map num_out vector to right outputs
    oc <= num_out(2);
    od <= num_out(3);

    rco <= rco_on when rco_on'event;

    process(reset) begin
    if reset = '1' then
    num_out <= "0000";
    rco_on <= '0';
    end if;
    end process;

    process(clk)
    begin
    if clk'event and clk='1' then -- clear, load all synchronous in the 162

    -- if ripple carry has been set, now is the time to set it back to 0
    -- (ripple carry is held high for 1 full clock cycle in this manner)
    if rco_on = '1' then
    rco_on <= '0';
    end if;

    if clr = '0' then -- logical diagram points out that clear has
    presedence over load
    num_out <= "0000";
    elsif load = '0' then -- load has presedence over counting (loaded values
    don'tget incremented)
    num_out <= (a,b,c,d);
    elsif enp = '0' and ent = '0' then -- increment
    if num_out = "1001" then --is it 9, then back to 0 (because it's a bcd
    counter)
    num_out <= "0000";
    rco_on <= '1'; -- clock to next counter in cascade
    else num_out <= std_logic_vector(unsigned(num_out)+1);
    end if;
    end if;

    end if; -- clk'event

    end process;

    end gedrag;

    Here the testbench:
    =======================================================================
    library ieee;
    use ieee.std_logic_1164.all;


    entity testbench is
    end testbench;

    architecture tb_sn_74162 of testbench is
    component sn_74162 port (
    clr : in std_logic;
    load : in std_logic;
    ent : in std_logic;
    enp : in std_logic;
    clk : in std_logic;
    a : in std_logic;
    b : in std_logic;
    c : in std_logic;
    d : in std_logic;
    oa : out std_logic;
    ob : out std_logic;
    oc : out std_logic;
    od : out std_logic;
    rco : out std_logic;
    reset : in std_logic
    ); end component;

    for uut : sn_74162 use entity work.sn_74162(gedrag);

    signal clr : std_logic;
    signal load : std_logic;
    signal ent : std_logic;
    signal enp : std_logic;
    signal clk : std_logic := '0';
    signal a : std_logic;
    signal b : std_logic;
    signal c : std_logic;
    signal d : std_logic;
    signal oa : std_logic;
    signal ob : std_logic;
    signal oc : std_logic;
    signal od : std_logic;
    signal rco : std_logic;
    signal reset : std_logic;

    constant HALF_CLOCK_PERIOD : time := 10 ns;
    constant RESET_PERIOD : time := 2 ns;

    --
    -- place your own declarations here
    --

    begin --testbench

    uut : sn_74162 port map (
    clr => clr,
    load => load,
    ent => ent,
    enp => enp,
    clk => clk,
    a => a,
    b => b,
    c => c,
    d => d,
    oa => oa,
    ob => ob,
    oc => oc,
    od => od,
    rco => rco,
    reset => reset
    );


    clk <= not clk after HALF_CLOCK_PERIOD;
    reset <= '1', '0' after RESET_PERIOD;


    process
    begin
    -- test loading:
    clr <= '1';
    load <= '0';
    ent <='0'; --load should have presedence; clock enable should'nt matter
    enp <='0';
    -- zeroes only
    a <= '0';
    b <= '0';
    c <= '0';
    d <= '0';
    wait for 6*HALF_CLOCK_PERIOD;
    -- ones only
    a <= '1';
    b <= '1';
    c <= '1';
    d <= '1';
    wait for 6*HALF_CLOCK_PERIOD;
    -- mixed
    a <= '1';
    b <= '0';
    c <= '1';
    d <= '0';
    wait for 6*HALF_CLOCK_PERIOD;


    -- value now 5
    -- now test counting. enable is still active

    load <='1'; -- load off; counting starts
    wait for 24*HALF_CLOCK_PERIOD;

    -- expected value now 5 + 16/2 (mod 10) = 4
    -- (check if a pulse has been given to rco)

    -- test inhibit:
    ent <= '1'; -- one inhibit actief
    wait for 6*HALF_CLOCK_PERIOD;

    enp <= '1'; -- two inhibit actief
    wait for 6*HALF_CLOCK_PERIOD;


    -- test if load en clr still work (as they should)
    a <= '1';
    b <= '0';
    c <= '1';
    d <= '0';
    wait for 6*HALF_CLOCK_PERIOD;


    clr <= '0';
    wait for 6*HALF_CLOCK_PERIOD;

    wait;
    end process;

    end tb_sn_74162;
    Martijn van Pottelberghe, Sep 27, 2006
    #1
    1. Advertising

  2. Martijn van Pottelberghe wrote:

    > Hello everybody,
    >
    > I'm trying to make a vhdl implementation of an 74162 (bcd counter
    > with load) Defined an entity and architecture, and entered a
    > behavioural description that I think should be ok overall.
    >
    > After this definition, I made a testbench vhdl-file in order to
    > simulate the thing using modelsim.
    >
    > Because i'm not even sure if the conflict appears within the
    > testbench, or in the component description, I'll insert both heir
    > vhdl files below. In order not to bother you too much I commented
    > extensively so at least my reasonings should be easy to follow.


    You have two processes (in sn_74162) that both are driving signals
    num_out and rco_on. That is your conflict: multiple drivers.

    To solve that, put the reset part in the second process and scrap the
    first process. Or better yet: just remove input reset. You already
    have the clr input.

    Also replace:

    rco <= rco_on when rco_on'event;

    by:

    rco <= rco_on;

    A concurrent signal assignment is triggered automatically when an
    event occurs on a signal in the right hand side.

    > Also I have a nice small png file of simulated signals, but the news
    > server won't let me post those 13kb..


    Even if it would, this is not a binary newsgroup, so don't do that.
    Include a URL if you want to refer to a png file.

    Paul.


    > Thanks for your attention so far..
    > Help would be greatly appreciated.
    >
    > Regards,
    > Martijn
    >
    > Here comes the 74162:
    > =====================================================
    > library ieee;
    > use ieee.std_logic_1164.all;
    > use ieee.numeric_std.all;
    >
    > entity sn_74162 is
    > port (
    > clr : in std_logic;
    > load : in std_logic;
    > ent : in std_logic;
    > enp : in std_logic;
    > clk : in std_logic;
    > a : in std_logic;
    > b : in std_logic;
    > c : in std_logic;
    > d : in std_logic;
    > oa : out std_logic;
    > ob : out std_logic;
    > oc : out std_logic;
    > od : out std_logic;
    > rco : out std_logic;
    >
    > reset : in std_logic -- not an 74162's pin, though useful for
    > testing
    > purposes
    > );
    > end sn_74162;
    >
    > architecture gedrag of sn_74162 is
    > signal num_out: std_logic_vector(3 downto 0);
    > signal rco_on: std_logic; -- when i want to change rco, in fact i
    > write to
    > rco_on
    > -- i do this in order to have a readable version of rco
    >
    > begin
    > oa <= num_out(0);
    > ob <= num_out(1); -- map num_out vector to right outputs
    > oc <= num_out(2);
    > od <= num_out(3);
    >
    > rco <= rco_on when rco_on'event;
    >
    > process(reset) begin
    > if reset = '1' then
    > num_out <= "0000";
    > rco_on <= '0';
    > end if;
    > end process;
    >
    > process(clk)
    > begin
    > if clk'event and clk='1' then -- clear, load all synchronous in
    > the 162
    >
    > -- if ripple carry has been set, now is the time to set it back to
    > 0 -- (ripple carry is held high for 1 full clock cycle in this
    > manner)
    > if rco_on = '1' then
    > rco_on <= '0';
    > end if;
    >
    > if clr = '0' then -- logical diagram points out that clear has
    > presedence over load
    > num_out <= "0000";
    > elsif load = '0' then -- load has presedence over counting
    > (loaded values
    > don'tget incremented)
    > num_out <= (a,b,c,d);
    > elsif enp = '0' and ent = '0' then -- increment
    > if num_out = "1001" then --is it 9, then back to 0 (because it's
    > a bcd
    > counter)
    > num_out <= "0000";
    > rco_on <= '1'; -- clock to next counter in cascade
    > else num_out <= std_logic_vector(unsigned(num_out)+1);
    > end if;
    > end if;
    >
    > end if; -- clk'event
    >
    > end process;
    >
    > end gedrag;
    Paul Uiterlinden, Sep 27, 2006
    #2
    1. Advertising

  3. Martijn van Pottelberghe

    KJ Guest

    "Martijn van Pottelberghe" <> wrote in message
    news:451ae816$1$20420$...
    > Hello everybody,
    >
    > I'm trying to make a vhdl implementation of an 74162 (bcd counter with
    > load)
    > Defined an entity and architecture, and entered a behavioural description
    > that I think should be ok overall.
    >
    > After this definition, I made a testbench vhdl-file in order to simulate
    > the
    > thing using modelsim.
    >
    > Because i'm not even sure if the conflict appears within the testbench, or
    > in the component description, I'll insert both heir vhdl files below.
    > In order not to bother you too much I commented extensively so at least my
    > reasonings should be easy to follow.


    In addition to Paul's post I would suggest changing all std_logic to
    std_ulogic. Then the compiler will flag for you where you have two outputs
    driving the same signal...without ever starting up the simulation. It's
    much quicker. The only time std_logic is really needed is when you really
    do need to have two outputs driving a common signal at the same time. This
    occurs typically on data busses and will always involve tri-state control of
    every driver (i.e. setting each process that drives a signal to 'Z').

    I'm guessing that you're relatively new to VHDL and that whoever/whatever
    you learned VHDL from always used std_logic as the basic type for
    everything. Most people do learn this way, most people even continue to do
    it this way....and it's a mistake (in my opinion). Most signals in any
    design are never going to be intentionally driven by multiple sources so
    std_logic is just the wrong choice.

    Now most people (I would estimate it at 100%), as they write code ARE going
    to UNintentionally drive a signal from two places at some point in their
    career. And for each time they do this, if they use std_logic, they will
    have to debug to find the problem or ask for outside help as you have. Each
    person that used std_ulogic on the other hand will get the problem pointed
    out to them clearly either when they compile the file or as soon as they
    invoke the simulator (this occurs when the multiple drivers are physically
    in separate files or entities and compiling alone is not enough to 'know'
    that there are multiple drivers). The choice is yours to make.

    One caveat to using std_ulogic is you may find yourself interfacing to
    existing code that uses std_logic and you will have to either cave in and
    change your signal or add some type conversions. But again, the compiler
    flags those cases for you. In general, it is usually worth it I
    think...others may think otherwise....when they're not busy using the
    simulator to find multiple drivers.

    KJ
    KJ, Sep 28, 2006
    #3
  4. KJ wrote:

    > In addition to Paul's post I would suggest changing all std_logic to
    > std_ulogic. Then the compiler will flag for you where you have two
    > outputs
    > driving the same signal...without ever starting up the simulation.
    > It's
    > much quicker. The only time std_logic is really needed is when you
    > really
    > do need to have two outputs driving a common signal at the same
    > time. This occurs typically on data busses and will always involve
    > tri-state control of every driver (i.e. setting each process that
    > drives a signal to 'Z').


    You're absolutely right. That is exactly what I do.

    In addition, I always try to use types and constructs that gives an
    error message at the earliest possibility. Use types with the
    smallest possible range: delay_length in stead of time, natural
    instead of integer. Also I avoid using the WHEN OTHERS choice in case
    statements, especially in combination with enumerated types. If I
    later extend the enumeration type, it gets automatically flagged
    during analysis if I forget to add the choice to the case statement.
    This however holds only for behavioral code (testbenches and models).
    For synthesis the WHEN OTHERS is needed for other reasons than
    strictly VHDL.

    > I'm guessing that you're relatively new to VHDL and that
    > whoever/whatever you learned VHDL from always used std_logic as the
    > basic type for
    > everything. Most people do learn this way, most people even
    > continue to do
    > it this way....and it's a mistake (in my opinion). Most signals in
    > any design are never going to be intentionally driven by multiple
    > sources so std_logic is just the wrong choice.
    >
    > Now most people (I would estimate it at 100%), as they write code
    > ARE going to UNintentionally drive a signal from two places at some
    > point in their
    > career. And for each time they do this, if they use std_logic, they
    > will
    > have to debug to find the problem or ask for outside help as you
    > have. Each person that used std_ulogic on the other hand will get
    > the problem pointed out to them clearly either when they compile the
    > file or as soon as they invoke the simulator (this occurs when the
    > multiple drivers are physically in separate files or entities and
    > compiling alone is not enough to 'know'
    > that there are multiple drivers). The choice is yours to make.
    >
    > One caveat to using std_ulogic is you may find yourself interfacing
    > to existing code that uses std_logic and you will have to either
    > cave in and
    > change your signal or add some type conversions.


    If you're talking about std_logic/std_ulogic this is not true.
    std_logic is a subtype of std_ulogic, so they "talk" to each other
    without the need of any conversion.

    If you're talking about std_logic_vector/std_ulogic_vector, then
    you're right. That's why I only use std_logic_vector, not
    std_ulogic_vector. I know I miss occasions to check for multiple
    drivers that way. But then again, I always use mode buffer instead of
    out. That also gives a check on multiple drivers, regardless of the
    type involved. And you also do not need those pesky intermediate
    signals if you want to read the output port signal internally.

    --
    Paul.
    Paul Uiterlinden, Sep 28, 2006
    #4
  5. Martijn van Pottelberghe

    KJ Guest

    "Martijn van Pottelberghe" <> wrote in message
    news:451ae816$1$20420$...
    > Hello everybody,
    >
    > I'm trying to make a vhdl implementation of an 74162 (bcd counter with
    > load)
    > Defined an entity and architecture, and entered a behavioural description
    > that I think should be ok overall.
    >
    > After this definition, I made a testbench vhdl-file in order to simulate
    > the
    > thing using modelsim.
    >
    > Because i'm not even sure if the conflict appears within the testbench, or
    > in the component description, I'll insert both heir vhdl files below.
    > In order not to bother you too much I commented extensively so at least my
    > reasonings should be easy to follow.


    In addition to Paul's post I would suggest changing all std_logic to
    std_ulogic. Then the compiler will flag for you where you have two outputs
    driving the same signal...without ever starting up the simulation. It's
    much quicker. The only time std_logic is really needed is when you really
    do need to have two outputs driving a common signal at the same time. This
    occurs typically on data busses and will always involve tri-state control of
    every driver (i.e. setting each process that drives a signal to 'Z').

    I'm guessing that you're relatively new to VHDL and that whoever/whatever
    you learned VHDL from always used std_logic as the basic type for
    everything. Most people do learn this way, most people even continue to do
    it this way....and it's a mistake (in my opinion). Most signals in any
    design are never going to be intentionally driven by multiple sources so
    std_logic is just the wrong choice.

    Now most people (I would estimate it at 100%), as they write code ARE going
    to UNintentionally drive a signal from two places at some point in their
    career. And for each time they do this, if they use std_logic, they will
    have to debug to find the problem or ask for outside help as you have. Each
    person that used std_ulogic on the other hand will get the problem pointed
    out to them clearly either when they compile the file or as soon as they
    invoke the simulator (this occurs when the multiple drivers are physically
    in separate files or entities and compiling alone is not enough to 'know'
    that there are multiple drivers). The choice is yours to make.

    One caveat to using std_ulogic is you may find yourself interfacing to
    existing code that uses std_logic and you will have to either cave in and
    change your signal or add some type conversions. But again, the compiler
    flags those cases for you. In general, it is usually worth it I
    think...others may think otherwise....when they're not busy using the
    simulator to find multiple drivers.

    KJ
    KJ, Sep 30, 2006
    #5
  6. Paul Uiterlinden wrote:

    > If you're talking about std_logic/std_ulogic this is not true.
    > std_logic is a subtype of std_ulogic, so they "talk" to each other
    > without the need of any conversion.


    Yes, and std_ulogic is an excellent choice for a default bit type.

    The vector type std_ulogic_vector clashes with
    numeric_std functions so I can't suggest
    an obvious "best" default vector type.

    I avoid multiple drivers by using
    single process design entities.


    -- Mike Treseler
    Mike Treseler, Oct 2, 2006
    #6
  7. Martijn van Pottelberghe

    KJ Guest

    Mike Treseler wrote:

    > Yes, and std_ulogic is an excellent choice for a default bit type.
    >
    > The vector type std_ulogic_vector clashes with
    > numeric_std functions so I can't suggest
    > an obvious "best" default vector type.


    The type clashes though can be easily resolved with the appropriate
    type conversions

    A_std_ulogic_vector_signal <=
    std_ulogic_vector(std_logic_vector(An_Unsigned_Signal));

    where 'A_std_ulogic_vector_signal is a std_ulogic_vector and
    An_Unsigned_Signal is an unsigned.

    For the 'write it only once' guys this could be put into a function

    function Unsigned_To_Std_ULogic_Vector(L: unsigned) return
    std_ulogic_vector is
    begin
    return (std_ulogic_vector(std_logic_vector(L)));
    end function Unsigned_To_Std_ULogic_Vector;

    and then packaged with other handy 'always need these types of things
    whenever I do a VHDL design' package of VHDL things and used like...

    A_std_ulogic_vector_signal <=
    Unsigned_To_Std_ULogic_Vector(An_Unsigned_Signal);

    >
    > I avoid multiple drivers by using
    > single process design entities.
    >

    But that doesn't help resolve unintended multiple drivers between
    entities whereas std_ulogic would immediately flag it as soon as you
    start sim without having to debug down to that error....either that or
    run it through synthesis and let it find the multiple driver error.

    Like I mentioned earlier in the thread, there can be other places where
    type conversions are needed when interfacing with std_logic_vector and
    where making use of std_ulogic_vector a bit annoying at times....but
    I've found that it's generally not too bad. The amount of annoyance is
    probably directly related to how much existing code there is that you
    can't touch at all for whatever reason.

    KJ
    KJ, Oct 3, 2006
    #7
  8. KJ wrote:

    > But that doesn't help resolve unintended multiple drivers between
    > entities


    Port directions cover me there for all internal entities.

    > whereas std_ulogic would immediately flag it as soon as you
    > start sim


    as soon as I compile, actually

    > without having to debug down to that error....either that or
    > run it through synthesis and let it find the multiple driver error.


    Just to clarify, I agree with you on std_ulogic type for bits.

    > Like I mentioned earlier in the thread, there can be other places where
    > type conversions are needed when interfacing with std_logic_vector and
    > where making use of std_ulogic_vector a bit annoying at times....but
    > I've found that it's generally not too bad. The amount of annoyance is
    > probably directly related to how much existing code there is that you
    > can't touch at all for whatever reason.


    default vector type annoyance
    ------------------- ---------
    1. std_logic_vector mild: cast (un)signed for numerics
    2. std_ulogic_vector mild: some users complain
    3. unsigned moderate: implies numerics

    So, it depends.
    I see no clear default.

    -- Mike Treseler
    Mike Treseler, Oct 3, 2006
    #8
  9. Martijn van Pottelberghe

    KJ Guest

    Mike Treseler wrote:
    > KJ wrote:
    >
    > > But that doesn't help resolve unintended multiple drivers between
    > > entities

    >
    > Port directions cover me there for all internal entities.
    >
    > > whereas std_ulogic would immediately flag it as soon as you
    > > start sim

    >
    > as soon as I compile, actually


    Yes...almost always. I know I've run across cases where every file
    compiled without error and still when vsim was invoked it choked about
    two std_ulogics (or vectors) being driven from multiple sources. I
    don't quite recall the circumstances though and just fixed the
    unintended multiple drivers. In any event whether the compiler catches
    it (as it generally does) or at worst it gets caught when invoking
    'vsim' at least I didn't have to debug down to the error to find
    it....as I did in my younger days....back when my memory was better.

    KJ
    KJ, Oct 3, 2006
    #9
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. H.MuthuKumaraRajan
    Replies:
    3
    Views:
    415
    H.MuthuKumaraRajan
    Feb 4, 2004
  2. flamesrock
    Replies:
    8
    Views:
    430
    Hendrik van Rooyen
    Nov 24, 2006
  3. xkenneth
    Replies:
    8
    Views:
    327
    Bruno Desthuilliers
    Feb 6, 2008
  4. RRamsey118

    Need to time outputs

    RRamsey118, Dec 1, 2008, in forum: VHDL
    Replies:
    3
    Views:
    640
    jeppe
    Dec 2, 2008
  5. charles cashion

    css conflict (or html conflict)

    charles cashion, Feb 18, 2009, in forum: HTML
    Replies:
    2
    Views:
    770
    charles cashion
    Feb 18, 2009
Loading...

Share This Page