FPGA Central - World's 1st FPGA / CPLD Portal

FPGA Central

World's 1st FPGA Portal

 

Go Back   FPGA Groups > NewsGroup > VHDL

VHDL comp.lang.vhdl newsgroup / Usenet

Reply
 
LinkBack Thread Tools Display Modes
  #1 (permalink)  
Old 09-27-2006, 11:07 PM
Martijn van Pottelberghe
Guest
 
Posts: n/a
Default outputs are in conflict most of the time

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;



Reply With Quote
  #2 (permalink)  
Old 09-27-2006, 11:59 PM
Paul Uiterlinden
Guest
 
Posts: n/a
Default Re: outputs are in conflict most of the time

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;


Reply With Quote
  #3 (permalink)  
Old 09-28-2006, 05:03 AM
KJ
Guest
 
Posts: n/a
Default Re: outputs are in conflict most of the time

"Martijn van Pottelberghe" <[email protected]> wrote in message
news:[email protected] net.nl...
> 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


Reply With Quote
  #4 (permalink)  
Old 09-28-2006, 10:16 PM
Paul Uiterlinden
Guest
 
Posts: n/a
Default Re: outputs are in conflict most of the time

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.

Reply With Quote
  #5 (permalink)  
Old 09-30-2006, 03:14 AM
KJ
Guest
 
Posts: n/a
Default Re: outputs are in conflict most of the time

"Martijn van Pottelberghe" <[email protected]> wrote in message
news:[email protected] net.nl...
> 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



Reply With Quote
  #6 (permalink)  
Old 10-02-2006, 09:06 PM
Mike Treseler
Guest
 
Posts: n/a
Default Re: outputs are in conflict most of the time

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
Reply With Quote
  #7 (permalink)  
Old 10-03-2006, 07:53 PM
KJ
Guest
 
Posts: n/a
Default Re: outputs are in conflict most of the time

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_Sig nal));

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

Reply With Quote
  #8 (permalink)  
Old 10-03-2006, 08:33 PM
Mike Treseler
Guest
 
Posts: n/a
Default Re: outputs are in conflict most of the time

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






Reply With Quote
  #9 (permalink)  
Old 10-03-2006, 08:58 PM
KJ
Guest
 
Posts: n/a
Default Re: outputs are in conflict most of the time


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

Reply With Quote
Reply

Bookmarks

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On


Similar Threads
Thread Thread Starter Forum Replies Last Post
hard_temac : mdio conflict Paul FPGA 9 08-02-2007 02:45 PM
How to debug suspected driver conflict? Andrew FPGA VHDL 0 06-01-2006 08:16 AM
Compiler can't resolve name conflict Michael Eichler VHDL 1 11-08-2005 12:03 AM
EDK6.3i Memory conflict..... vasudev FPGA 1 02-26-2005 01:09 AM


All times are GMT +1. The time now is 04:22 AM.


Powered by vBulletin® Version 3.8.0
Copyright ©2000 - 2020, Jelsoft Enterprises Ltd.
Search Engine Friendly URLs by vBSEO 3.2.0
Copyright 2008 @ FPGA Central. All rights reserved