Simulation of VHDL code for a vending machine

G

glallenjr

Guest
Currently I am studying the "Circuit Design with VHDL" by Volnei A.
Pedroni. On page 207 the run a simulation but do not provide the test
bench. I would like to run the same simulation but I am not familiar with
how to write a testbench. If possible please provide a testbench to mimic
the simulation shown on page 207. If you are unfamiliar with this book or
the simulation run, I would also appreciate ANY KIND of testbench which
could simulate it's funcionality. Also if there are any errors with the
code, please let me know! Your help is much appreciated! thank you!

Here is the code we are trying to implement:

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity vending_machine is
Port ( clk, rst : IN STD_LOGIC;
nickel_in, dime_in, quarter_in : IN BOOLEAN;
candy_out, nickel_out, dime_out, quarter_out: OUT STD_LOGIC);
end vending_machine;

architecture fsm of vending_machine IS
TYPE state IS (st0, st5, st10, st15, st20, st25, st30, st35, st40, st45);
SIGNAL present_state, next_state: STATE;

begin
PROCESS(rst, clk)
BEGIN
IF(rst='1') THEN
present_state <=st0;
ELSIF(clk' EVENT AND clk ='1') THEN
present_state <= next_state;
END IF;
END PROCESS;

PROCESS(present_state, nickel_in, dime_in, quarter_in)
BEGIN
CASE present_state IS
WHEN st0 =>
candy_out <= '0';
nickel_out <='0';
dime_out <= '0';
IF (nickel_in) THEN next_state <= st5;
ELSIF (dime_in) THEN next_state <= st10;
ELSIF (quarter_in) THEN next_state <= st25;
ELSE next_state <=st0;
END IF;
WHEN st5 =>
candy_out <= '0';
nickel_out <='0';
dime_out <= '0';
IF (nickel_in) THEN next_state <= st10;
ELSIF (dime_in) THEN next_state <= st15;
ELSIF (quarter_in) THEN next_state <= st30;
ELSE next_state <=st5;
END IF;
WHEN st10 =>
candy_out <= '0';
nickel_out <='0';
dime_out <= '0';
IF (nickel_in) THEN next_state <= st15;
ELSIF (dime_in) THEN next_state <= st20;
ELSIF (quarter_in) THEN next_state <= st35;
ELSE next_state <=st10;
END IF;
WHEN st15 =>
candy_out <= '0';
nickel_out <='0';
dime_out <= '0';
IF (nickel_in) THEN next_state <= st20;
ELSIF (dime_in) THEN next_state <= st25;
ELSIF (quarter_in) THEN next_state <= st40;
ELSE next_state <=st15;
END IF;
WHEN st20 =>
candy_out <= '0';
nickel_out <='0';
dime_out <= '0';
IF (nickel_in) THEN next_state <= st25;
ELSIF (dime_in) THEN next_state <= st30;
ELSIF (quarter_in) THEN next_state <= st45;
ELSE next_state <=st20;
END IF;
WHEN st25 =>
candy_out <= '1';
nickel_out <='0';
dime_out <= '0';
next_state <= st0;
WHEN st30 =>
candy_out <= '1';
nickel_out <='1';
dime_out <= '0';
next_state <= st0;
WHEN st35 =>
candy_out <= '1';
nickel_out <='0';
dime_out <= '1';
next_state <= st35;
WHEN st45 =>
candy_out <= '0';
nickel_out <='0';
dime_out <= '1';
next_state <= st35;
END CASE;
END PROCESS;

END fsm;




---------------------------------------
This message was sent using the comp.arch.fpga web interface on
http://www.FPGARelated.com
 
On Dec 1 2009, 11:53 am, "glallenjr" <glalle...@gmail.com> wrote:
Currently I am studying the "Circuit Design with VHDL" by Volnei A.
Pedroni. On page 207 the run a simulation but do not provide the test
bench. I would like to run the same simulation but I am not familiar with
how to write a testbench. If possible please provide a testbench to mimic
the simulation shown on page 207. If you are unfamiliar with this book or
the simulation run, I would also appreciate ANY KIND of testbench which
could simulate it's funcionality. Also if there are any errors with the
code, please let me know! Your help is much appreciated! thank you!

Here is the code we are trying to implement:

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity vending_machine is
    Port ( clk, rst : IN  STD_LOGIC;
           nickel_in, dime_in, quarter_in : IN  BOOLEAN;
           candy_out, nickel_out, dime_out, quarter_out: OUT STD_LOGIC);
end vending_machine;

architecture fsm of vending_machine IS
        TYPE state IS (st0, st5, st10, st15, st20, st25, st30, st35, st40, st45);
        SIGNAL present_state, next_state: STATE;

begin
        PROCESS(rst, clk)
        BEGIN
                IF(rst='1') THEN
                        present_state <=st0;
                ELSIF(clk' EVENT AND clk ='1') THEN
                        present_state <= next_state;
                END IF;
        END PROCESS;

        PROCESS(present_state, nickel_in, dime_in, quarter_in)
        BEGIN
                CASE present_state IS
                        WHEN st0 =
                                candy_out <= '0';
                                nickel_out <='0';
                                dime_out <= '0';
                                IF (nickel_in) THEN next_state <= st5;
                                ELSIF (dime_in) THEN next_state <= st10;
                                ELSIF (quarter_in) THEN next_state <= st25;
                                ELSE next_state <=st0;
                                END IF;
                        WHEN st5 =
                                candy_out <= '0';
                                nickel_out <='0';
                                dime_out <= '0';
                                IF (nickel_in) THEN next_state <= st10;
                                ELSIF (dime_in) THEN next_state <= st15;
                                ELSIF (quarter_in) THEN next_state <= st30;
                                ELSE next_state <=st5;
                                END IF;
                        WHEN st10 =
                                candy_out <= '0';
                                nickel_out <='0';
                                dime_out <= '0';
                                IF (nickel_in) THEN next_state <= st15;
                                ELSIF (dime_in) THEN next_state <= st20;
                                ELSIF (quarter_in) THEN next_state <= st35;
                                ELSE next_state <=st10;
                                END IF;
                        WHEN st15 =
                                candy_out <= '0';
                                nickel_out <='0';
                                dime_out <= '0';
                                IF (nickel_in) THEN next_state <= st20;
                                ELSIF (dime_in) THEN next_state <= st25;
                                ELSIF (quarter_in) THEN next_state <= st40;
                                ELSE next_state <=st15;
                                END IF;
                        WHEN st20 =
                                candy_out <= '0';
                                nickel_out <='0';
                                dime_out <= '0';
                                IF (nickel_in) THEN next_state <= st25;
                                ELSIF (dime_in) THEN next_state <= st30;
                                ELSIF (quarter_in) THEN next_state <= st45;
                                ELSE next_state <=st20;
                                END IF;
                        WHEN st25 =
                                candy_out <= '1';
                                nickel_out <='0';
                                dime_out <= '0';
                                next_state <= st0;
                        WHEN st30 =
                                candy_out <= '1';
                                nickel_out <='1';
                                dime_out <= '0';
                                next_state <= st0;
                        WHEN st35 =
                                candy_out <= '1';
                                nickel_out <='0';
                                dime_out <= '1';
                                next_state <= st35;
                        WHEN st45 =
                                candy_out <= '0';
                                nickel_out <='0';
                                dime_out <= '1';
                                next_state <= st35;
                END CASE;
                END PROCESS;

                END fsm;

---------------------------------------        
This message was sent using the comp.arch.fpga web interface onhttp://www..FPGARelated.com


Hi,

I recommend you change your BOOLEANs to STD_LOGIC. Also, assuming this
is targeting real hardware, remember that the insertion of coins is
asynchronous and this is a synchronous design. You'll need some logic
for metastability and to create a one clock-wide pulse to your state
machine.

You can do something like this for a testbench:

====================
library ieee;
use ieee.std_logic_1164.all;

-- Add your library and packages declaration here ...

entity vending_machine_tb is
end vending_machine_tb;

architecture TB_ARCHITECTURE of vending_machine_tb is
-- Component declaration of the tested unit
component vending_machine
port
(
clk : in std_logic;
rst : in std_logic;
nickel_in : in std_logic;
dime_in : in std_logic;
quarter_in : in std_logic;
candy_out : out std_logic;
nickel_out : out std_logic;
dime_out : out std_logic;
quarter_out : out std_logic
);
end component;

-- Stimulus signals - signals mapped to the input and inout ports of
tested entity
signal clk : std_logic := '0';
signal rst : std_logic := '0';
signal nickel_in : std_logic := '0';
signal dime_in : std_logic := '0';
signal quarter_in : std_logic := '0';
-- Observed signals - signals mapped to the output ports of tested
entity
signal candy_out : std_logic;
signal nickel_out : std_logic;
signal dime_out : std_logic;
signal quarter_out : std_logic;

-- Add your code here ...

begin

-- Unit Under Test port map
UUT : vending_machine
port map
(
clk => clk,
rst => rst,
nickel_in => nickel_in,
dime_in => dime_in,
quarter_in => quarter_in,
candy_out => candy_out,
nickel_out => nickel_out,
dime_out => dime_out,
quarter_out => quarter_out
);

-- Add your stimulus here ...
clk <= not clk after 50ns;

Stimulus: process

begin

wait for 200 ns;

rst <='1';

wait for 200 ns;

rst <='0';

wait for 200 ns;

nickel_in <='1';

wait for 1 us;

nickel_in <='0';

wait for 1 us;

dime_in <='1';

wait for 1 us;

dime_in <='0';

wait for 1 us;

quarter_in <='1';

wait for 1 us;

quarter_in <='0';

-- add more...

wait;

end process;

end TB_ARCHITECTURE;

configuration TESTBENCH_FOR_vending_machine of vending_machine_tb is
for TB_ARCHITECTURE
for UUT : vending_machine
use entity work.vending_machine(fsm);
end for;
end for;
end TESTBENCH_FOR_vending_machine;

=================
I didn't simulate your design to check its operation. This TB is
simple but it will get you started.

KMS
 
On Jan 16, 12:59 pm, KMS <kms34...@gmail.com> wrote:
Hi,

I recommend you change your BOOLEANs to STD_LOGIC.
If you change the booleans to std_logic, you'll need
to change all the if statements to have a comparison
operator like
if (nickel_in) then . . .
becomes
if (nickel_in = '1') then . . .

If you're not trying to synthesize this logic, I'm not really
clear why you shouldn't use booleans, but then I would
normally have used Verilog.

On the other hand, if you make the code synthesizable,
you can use the Xilinx webpack to generate a testbench
template automatically. That often saves the headache
of writing the signal declarations, instantiations and
initialization logic.

Regards,
Gabor
 
On Jan 16, 10:23 pm, Gabor <ga...@alacron.com> wrote:
to generate a testbench
template automatically.  That often saves the headache
of writing the signal declarations, instantiations and
initialization logic.
I never caught on to how this was ever much of a headache and why it
gets touted by the tool vendors as something important. Copy/paste
the entity that you create to make two copies.

The first copy you add the word 'signal' at the begining of the line
and then delete the 'in', 'out' and 'inout' modes from each line and
'presto' you have the signal definitions for the testbench.

The second copy you edit the 'entity' line to make it an
instantiation, change 'generic' and 'port' to 'generic map' and 'port
map' and then use a macro to change all of the lines of the entity
from this...

xyz: in std_logic;

....to this...

xyz => xyz,

Touch it up a bit if you want and you're done...depends on your
preferred editor, but it never takes more than a minute or so.

Not much of a time saver in my opinion. Now something to generate the
actual stimulus and generate the assertion checking would be nice and
would be a real timesaver...

KJ
 
On Jan 17, 1:28 pm, KJ <kkjenni...@sbcglobal.net> wrote:
On Jan 16, 10:23 pm, Gabor <ga...@alacron.com> wrote:
to generate a testbench
template automatically.  That often saves the headache
of writing the signal declarations, instantiations and
initialization logic.

I never caught on to how this was ever much of a headache and why it
gets touted by the tool vendors as something important.  Copy/paste
the entity that you create to make two copies.

The first copy you add the word 'signal' at the begining of the line
and then delete the 'in', 'out' and 'inout' modes from each line and
'presto' you have the signal definitions for the testbench.

The second copy you edit the 'entity' line to make it an
instantiation, change 'generic' and 'port' to 'generic map' and 'port
map' and then use a macro to change all of the lines of the entity
from this...

   xyz:  in std_logic;

...to this...

   xyz => xyz,

Touch it up a bit if you want and you're done...depends on your
preferred editor, but it never takes more than a minute or so.

Not much of a time saver in my opinion.  Now something to generate the
actual stimulus and generate the assertion checking would be nice and
would be a real timesaver...

KJ
Well just your description is significanly longer than the buttons
to generate the testbench in ISE. It's actually more of a
timesaver if you use Verilog, where the instantiation and
wires / regs don't resemble the source code like in VHDL.
It's also great if you wanted to quickly make a Verilog
testbench for your VHDL entity or vice versa. This goes
doubly for a beginner, who may not know the basics
required to start the testbench.

Just my 2 cents,
Gabor
 
On Jan 16, 10:23 pm, Gabor <ga...@alacron.com> wrote:
On Jan 16, 12:59 pm, KMS <kms34...@gmail.com> wrote:

Hi,

I recommend you change your BOOLEANs to STD_LOGIC.

If you change the booleans to std_logic, you'll need
to change all the if statements to have a comparison
operator like
if (nickel_in) then . . .
becomes
if (nickel_in = '1') then . . .

If you're not trying to synthesize this logic, I'm not really
clear why you shouldn't use booleans, but then I would
normally have used Verilog.
I'll second that. There is nothing about Booleans that are evil. The
two times I will replace a Boolean with a std_logic is when I know
this is a signal that will be important in simulation or when it is at
the top level of a synthesized design. I don't recall the exact issue
having other than std_logic or slv at the top level, but it is not a
big deal to work with that restriction. I replace a Boolean with
std_logic for simulation only because a std_logic signal produces a
wiggly line with levels that are easy to see while a Boolean has a
state which must be read in the waveform viewer which can be difficult
with small text. I like Booleans because they can be less typing when
used in an IF statement or in the result of a comparison. In the end,
it more a matter of preference than anything. If you like the format
of your code using Booleans, go ahead. There are no real roadblocks
to using them.

On the other hand, if you make the code synthesizable,
you can use the Xilinx webpack to generate a testbench
template automatically. That often saves the headache
of writing the signal declarations, instantiations and
initialization logic.
I'll second that as well. But the template is only the signal
declarations and the component instantiations. You still have to
write the code to drive all the inputs to the UUT. Once you go a
couple of simple test benches you will see how easy they are. When
you need to test more complex code, you will find that your test bench
needs to get a little more complex, but the same concepts apply. The
main thing is to keep it simple and look at other coder's test benches
to get ideas. There are a lot of good designers out there and it is
always good to learn what you can from them. But don't be afraid to
think for yourself too.

Rick
 
On Sun, 17 Jan 2010 12:43:20 -0800 (PST), rickman <gnuarm@gmail.com> wrote:

On Jan 16, 10:23 pm, Gabor <ga...@alacron.com> wrote:
On Jan 16, 12:59 pm, KMS <kms34...@gmail.com> wrote:

Hi,

I recommend you change your BOOLEANs to STD_LOGIC.

If you're not trying to synthesize this logic, I'm not really
clear why you shouldn't use booleans, but then I would
normally have used Verilog.

I'll second that. There is nothing about Booleans that are evil. The
two times I will replace a Boolean with a std_logic is when I know
this is a signal that will be important in simulation or when it is at
the top level of a synthesized design. I don't recall the exact issue
having other than std_logic or slv at the top level, but it is not a
big deal to work with that restriction.
I'll third that.

The issue I see with std_logic[_vector] ports at the top level is that whatever
you use at the top level will be translated to std_logic[_vector] by synthesis
and/or the post-PAR netlist generator.

Therefore if you ever need to run a timing simulation, the easiest thing is to
use these types from the start. Then your testbench will work with either
behavioural or netlist versions.

Of course you could use other port types, and generate a wrapper to convert port
types for the netlist, but that's more work.

If the tools were actually designed to support VHDL users who want to design at
the most appropriate level of abstraction, they would auto-generate such a
wrapper; it would be trivial, and allow you to use any synthesisable type for
your ports - even records.

But they aren't...

- Brian
 
Well just your description is significanly longer than the buttons
to generate the testbench in ISE.  
OK, so I ramble on a bit...

It's actually more of a
timesaver if you use Verilog, where the instantiation and
wires / regs don't resemble the source code like in VHDL.
Yeah, VHDL is better than Verilog any day of the week ;)

This goes
doubly for a beginner, who may not know the basics
required to start the testbench.
Not sure the beginer learns much just by clicking on a button though.

Just my 2 cents,
I'll see your 2 cents, and raise you a penny

KJ
 
In the end,
it more a matter of preference than anything.  If you like the format
of your code using Booleans, go ahead.  There are no real roadblocks
to using them.
In the end, the main advantage of std_logic is with unknowns.
Booleans will initialize themselves to 'False', std_logic to 'U'.
Proving that your design does not depend on a lucky initialization
value happens when you use std_logic not booleans.

Kevin Jennings
 
On Jan 17, 7:49 pm, KJ <kkjenni...@sbcglobal.net> wrote:
In the end,
it more a matter of preference than anything.  If you like the format
of your code using Booleans, go ahead.  There are no real roadblocks
to using them.

In the end, the main advantage of std_logic is with unknowns.
Booleans will initialize themselves to 'False', std_logic to 'U'.
Proving that your design does not depend on a lucky initialization
value happens when you use std_logic not booleans.

Kevin Jennings
Interestingly enough, for FPGA synthesis, the boolean will
more closely resemble the final hardware. "Uninitialized"
logic in an FPGA generally defaults to zero, at least for
Xilinx XST. There may be some architectures that don't
initialize every register and memory bit in the configuration
bitstream, but I haven't run across them yet.

Regards,
Gabor
 
On Jan 18, 8:49 am, Gabor <ga...@alacron.com> wrote:
On Jan 17, 7:49 pm, KJ <kkjenni...@sbcglobal.net> wrote:

In the end,
it more a matter of preference than anything.  If you like the format
of your code using Booleans, go ahead.  There are no real roadblocks
to using them.

In the end, the main advantage of std_logic is with unknowns.
Booleans will initialize themselves to 'False', std_logic to 'U'.
Proving that your design does not depend on a lucky initialization
value happens when you use std_logic not booleans.

Kevin Jennings

Interestingly enough, for FPGA synthesis, the boolean will
more closely resemble the final hardware.  "Uninitialized"
logic in an FPGA generally defaults to zero
And when that first clock cycle comes along right after configuration
that nicely initialized value of zero is overwritten...and that first
clock edge happens to violate the setup time of the flop(s)...and you
use that flop in a feedback path (like a state machine) and you
neglected to add a reset term...well, you might well appreciate the
value of an 'X' in simulation after all

While it's true that boolean more closely models reality in that real
digital logic only has two values, the reality is that the tools and
data types are abstractions to help one engineer a robust design.
Things that assist in finding design errors earlier are a good thing.

Kevin Jennings
 
On Jan 18, 8:49 am, Gabor <ga...@alacron.com> wrote:
On Jan 17, 7:49 pm, KJ <kkjenni...@sbcglobal.net> wrote:

In the end,
it more a matter of preference than anything.  If you like the format
of your code using Booleans, go ahead.  There are no real roadblocks
to using them.

In the end, the main advantage of std_logic is with unknowns.
Booleans will initialize themselves to 'False', std_logic to 'U'.
Proving that your design does not depend on a lucky initialization
value happens when you use std_logic not booleans.

Kevin Jennings

Interestingly enough, for FPGA synthesis, the boolean will
more closely resemble the final hardware.  "Uninitialized"
logic in an FPGA generally defaults to zero, at least for
Xilinx XST.  There may be some architectures that don't
initialize every register and memory bit in the configuration
bitstream, but I haven't run across them yet.
This is an interesting issue. I deal with this by always initializing
registers which should be good enough to control a simulation and
should match what happened inside the FPGA.

As to Booleans, do they ever get implemented as False = High? Some
parts I have worked with do not have inverters in some spots which
then require that the signal sense be flipped to eliminate a LUT used
as an inverter. I would think the hardware default of the Boolean
would then not be a False. Oh, maybe this is moot. On further
reflection, the case where the signal is inverted is when the initial
state of the FF is High and the part has no set capability! So that
wouldn't be an issue in this case. But are there other times when a
Boolean would be inverted?

Rick
 
Hi,

Gabor wrote:
On Jan 17, 7:49 pm, KJ <kkjenni...@sbcglobal.net> wrote:
In the end,
it more a matter of preference than anything. If you like the format
of your code using Booleans, go ahead. There are no real roadblocks
to using them.
In the end, the main advantage of std_logic is with unknowns.
Booleans will initialize themselves to 'False', std_logic to 'U'.
Proving that your design does not depend on a lucky initialization
value happens when you use std_logic not booleans.

Kevin Jennings

Interestingly enough, for FPGA synthesis, the boolean will
more closely resemble the final hardware. "Uninitialized"
logic in an FPGA generally defaults to zero, at least for
Xilinx XST. There may be some architectures that don't
initialize every register and memory bit in the configuration
bitstream, but I haven't run across them yet.
But if we assume that the registers are correctly initialised
by a correct Reset signal, and the design is verified with std_logic,
a higher-level simulation (that deals more with using already
tested sub-functions), then we could swap the std_logic
with "bit"-based types to increase simulation speed ?

I'm diving into GHDL which is not as fast as, say... ncsim,
but has much more potential for me, so simulation time matters.
Not much yet but if I can cut the simulation time by one half,
simply by defining my signals differently, I take it :)
I'm considering writing a couple of similar VHDL packages
that define local types for the wires, one that uses bits
and the other std_logic : I'm curious to see the simulation
speed difference.

Note that, with a nice simple testbench with clean signals and edges,
dirty setup conditions with /RESET don't usually happen,
so I don't expect Us or Xs to propagate through the whole design ;-)

Has anyone already explored this path ?

Regards,
_o/
Gabor
yg

--
http://ygdes.com / http://yasep.org
 
On Mon, 18 Jan 2010 17:36:07 +0100, whygee wrote:

Note that, with a nice simple testbench with clean signals and edges,
dirty setup conditions with /RESET don't usually happen,
so I don't expect Us or Xs to propagate through the whole design ;-)

Has anyone already explored this path ?
I haven't, but it has been thoroughly explored in the
verification literature. That's one of the reasons why
SystemVerilog added 2-state variables (int, bit) to the
language; VHDL has had 2-state integer, bit and boolean
from the outset, of course.

There is some strong evidence to suggest that X-simulation
is not only inconvenient because spurious Xs tend to
chase around the design when in reality it's OK, but also
they can give rise to unjustified optimism because of
the way certain RTL control constructs handle X inputs.
For example, in Verilog...

if (mode2)
do_mode2_stuff;
else
do_mode1_stuff;

If (mode2) is 1'bx in RTL simulation, the if() statement
will take its else-branch and the simulation will act
exactly as if (mode2) was zero.

So an alternative, which has been reported as giving
good results, is to use 2-state simulation **but to
randomize the values of all register variables at
startup**. If you use different seeds for the
randomization, you can simulate the design with a
wide range of startup values and therefore can see
whether it will reliably come out of reset. This
works nicely for ASIC designs where flip-flops
may power-up in an unknown state but the design
is nevertheless well-behaved. Consider, for example,
a simple clock divide-by-2 that has no reset - it
shoudl be OK in practice, but will be stuck at X
in a 4-state traditional simulation.

I believe that some simulators offer this startup
randomization as an option.

For a nice discussion of the drawbacks of 4-state
simulation, see Mike Turpin's survey at
http://www.arm.com/pdfs/Verilog_X_Bugs.pdf
The paper discusses Verilog, but many of the same
ideas map on to VHDL (although a lot of the details
are different).
--
Jonathan Bromley
 
An interesting thread is probably coming,
should we Xpost to comp.lang.vhdl ?

Kolja Sulimma wrote:
Note that a lot of the simulation time is take up by resolution functions.
STD_ULOGIC should be a lot faster than STD_LOGIC.
As there are no tristates in FPGAs anyway nowadays there is hardly
any reason to use STD_LOGIC at all.
That's what I thought. But recently (this summer)
I have been told to use STD_LOGIC anyway,
I don't remember why. There is hardly any
modification to my existing code because
I don't rely on resolution functions
or multiple-driver behaviour.
It was a pain (as anything VHDL-related)
to change all the declarations and interfaces
(both in the designs and the testbenches)
but it simply worked.

But this was only for synthesis.
I am wondering now what to do for high-level
simulations, when all the std_logic-ness
does not play any role anymore.
And with GHDL, for which integer directly maps
to the same C idiom, there are certainly
a lot of things to win (space, time)...

Kolja Sulimma
yg

--
http://ygdes.com / http://yasep.org
 
On 18 Jan., 17:36, whygee <y...@yg.yg> wrote:

I'm diving into GHDL which is not as fast as, say... ncsim,
but has much more potential for me, so simulation time matters.
Not much yet but if I can cut the simulation time by one half,
simply by defining my signals differently, I take it :)
I'm considering writing a couple of similar VHDL packages
that define local types for the wires, one that uses bits
and the other std_logic : I'm curious to see the simulation
speed difference.
Note that a lot of the simulation time is take up by resolution
functions.
STD_ULOGIC should be a lot faster than STD_LOGIC.
As there are no tristates in FPGAs anyway nowadays there is hardly
any reason to use STD_LOGIC at all.

Kolja Sulimma
 
Jonathan Bromley wrote:
On Mon, 18 Jan 2010 17:36:07 +0100, whygee wrote:
Has anyone already explored this path ?

I haven't, but it has been thoroughly explored in the
verification literature.
Can you point me to any online paper or website about this subject ?

That's one of the reasons why
SystemVerilog added 2-state variables (int, bit) to the
language; VHDL has had 2-state integer, bit and boolean
from the outset, of course.
yes, the ADA legacy has some good advantages :)

There is some strong evidence to suggest that X-simulation
is not only inconvenient because spurious Xs tend to
chase around the design when in reality it's OK,
I've seen this too, the false positives are quite annoying :-/

but also
they can give rise to unjustified optimism because of
the way certain RTL control constructs handle X inputs.
For example, in Verilog...

if (mode2)
do_mode2_stuff;
else
do_mode1_stuff;

If (mode2) is 1'bx in RTL simulation, the if() statement
will take its else-branch and the simulation will act
exactly as if (mode2) was zero.
heh, good point !

So an alternative, which has been reported as giving
good results, is to use 2-state simulation **but to
randomize the values of all register variables at
startup**. If you use different seeds for the
randomization, you can simulate the design with a
wide range of startup values and therefore can see
whether it will reliably come out of reset. This
works nicely for ASIC designs where flip-flops
may power-up in an unknown state but the design
is nevertheless well-behaved. Consider, for example,
a simple clock divide-by-2 that has no reset - it
shoudl be OK in practice, but will be stuck at X
in a 4-state traditional simulation.

I believe that some simulators offer this startup
randomization as an option.
I've explored this around 2001 :)
and I have then run into file read issues
from VHDL and compatibility issues with
different simulators. But it worked quite
well on a few platforms.


For a nice discussion of the drawbacks of 4-state
simulation, see Mike Turpin's survey at
http://www.arm.com/pdfs/Verilog_X_Bugs.pdf
The paper discusses Verilog, but many of the same
ideas map on to VHDL (although a lot of the details
are different).
i'll check that, thanks !

yg
--
http://ygdes.com / http://yasep.org
 
Mike Treseler wrote:
whygee wrote:
But recently (this summer)
I have been told to use STD_LOGIC anyway,
I don't remember why.

That is the common default for bits.
?

The *only* advantage is it covers tristate signals.
sure. But I don't have/need tristates.

Otherwise std_ulogic can detect multiple drivers
at compile time and has no downside
as it is 100% compatible with std_logic.
I still don't remember how/why I was convinced to drop ulogic
but I switched anyway.
It was probably something about externally provided
(or proprietary/manufacturer-specific) code interface...

Vectors are a more complicated story.
I don't see what could go wrong...

well, except this whole mess with
integer/signed/unsigned/bit_vector/std_logic_vector/std_ulogic_vector
translations/type casts :-/

-- Mike Treseler
yg

--
http://ygdes.com / http://yasep.org
 
whygee wrote:

Kolja Sulimma wrote:
Note that a lot of the simulation time is take up by resolution
functions.
STD_ULOGIC should be a lot faster than STD_LOGIC.
As there are no tristates in FPGAs anyway nowadays there is hardly
any reason to use STD_LOGIC at all.

That's what I thought. But recently (this summer)
I have been told to use STD_LOGIC anyway,
I don't remember why.
That is the common default for bits.
The *only* advantage is it covers tristate signals.
Otherwise std_ulogic can detect multiple drivers
at compile time and has no downside
as it is 100% compatible with std_logic.
Vectors are a more complicated story.

-- Mike Treseler
 
On Jan 18, 2:51 pm, whygee <y...@yg.yg> wrote:
Mike Treseler wrote:
whygee wrote:
But recently (this summer)
I have been told to use STD_LOGIC anyway,
I don't remember why.

That is the common default for bits.

?

The *only* advantage is it covers tristate signals.

sure. But I don't have/need tristates.

Otherwise std_ulogic can detect multiple drivers
at compile time and has no downside
as it is 100% compatible with std_logic.

I still don't remember how/why I was convinced to drop ulogic
but I switched anyway.
It was probably something about externally provided
(or proprietary/manufacturer-specific) code interface...

Vectors are a more complicated story.

I don't see what could go wrong...

well, except this whole mess with
integer/signed/unsigned/bit_vector/std_logic_vector/std_ulogic_vector
translations/type casts :-/

     -- Mike Treseler

yg

--http://ygdes.com/http://yasep.org
After struggling with VHDL type casting for some time, I finally
settled on using signed/unsigned for the majority of the vectors I
use. I seldom use integers other than perhaps memory where it
simulates much faster with a lot less memory. But nothing is
absolute. I just try to be consistent within a given design. I have
never used bit types, but the discussion here about the advantages of
ulogic over logic is interesting. I certainly like to speed up my
simulations. But it is such a PITA to get away from std_logic. I
don't recall if ieee.numeric_std converts between ulogic and the
signed/unsigned types. It is so verbose to use multiple conversions
in one assignment.

Rick
 

Welcome to EDABoard.com

Sponsor

Back
Top