Vhdl code simulation - vhdl

I'm trying to simulate the following code :
entity schal is port ( SW : in bit_vector(7 downto 0);
LED : out bit_vector(7 downto 0));
end schal;
architecture BEHAVIOUR of schal is
begin
INOUT_PROS : process (SW)
begin
LED <= SW;
end process INOUT_PROS;
end BEHAVIOUR;
I wrote this do file
vsim work.schal
restart
view wave
radix hex
add wave -height 25 -radix default sim:/schal/*
force SW 01000001
run 20ns
force SW 01000000
run 20ns
here is what I get :
as you can see the simulation affect only the first bit but not the whole vector ?
any idea how should I adjust the do file to get the right simulation ?

I think your force command is not using the correct syntax. You are trying to force a binary value, but the correct way to do this would be force SW 2#01000001, with the 2# specifying a binary value.
In ModelSim, go to Help > Documentation > PDF Bookcase, then open the 'Command Reference Manual'. This contains documentation on all commands, including force.

This is a Read-The-Fine-Manual moment. See the <value> argument description under the force command Arguments section in the Command Reference Manual.
A one-dimensional array of character enumeration can be forced as a sequence of character literals or as a based number with a radix of 2, 8, 10 or 16. For example, the following values are equivalent for a signal of type bit_vector (0 to 3):
You could note that IEEE Std 1076-2008 15.5.3 Based literals tells us:
A based literal is an abstract literal expressed in a form that specifies the base explicitly. The base shall be at least two and at most sixteen.
There are VHDL standard compliant based literals that can't be expressed with the force command.
Also notice the question's use of
force SW 01000001
is compatible with the sequence of character literals example in the Command Reference Manual. See the following NOTE:
For based numbers in VHDL, ModelSim translates each 1 or 0 to the appropriate value for the number’s enumerated type. The translation is controlled by the translation table in the pref.tcl file. If ModelSim cannot find a translation for 0 or 1, it uses the left bound of the signal type (type’left) for that value.
Also note from the question's value and waveform that the right most position of SWs enumeration translates properly. This suggests that the behavior doesn't match the force command &LT;value> description.
In VHDL terms you're being force to use a bit string literal as demonstrated in scary_jeff's answer and not a string literal for providing the value. (Both sans quotation marks).
The character literal sequence is correct according to the example but does not translate correctly. You could wonder if quotation marks would help - how would otherwise force a string type object's value containing a leading space?
As an early MTI Modelsim user the simulator originally only supported VHDL. The problem is either the simulator or the example.
And of course there's the use of a VHDL test bench instead of embedding simulation sequence in a do file.
This method would be portable between VHDL simulators:
entity schal_tb is
end entity;
architecture foo of schal_tb is
signal SW: bit_vector(7 downto 0);
signal LED: bit_vector(7 downto 0);
begin
DUT:
entity work.schal
port map (
SW => SW,
LED => LED
);
STIMULUS:
process
begin
SW <= "01000001";
wait for 20 ns;
SW <= "01000000";
wait for 20 ns;
wait for 60 ns; -- to show 100 ns on waveform
wait; -- suspends process permenently
end process;
end architecture;
And gives:
There are also online VHDL Testbench outline generators such as the Doulos VHDL Testbench generator or this Online VHDL Testbench Template Generator.

Related

Evaluate Assert First when Simulating

I have an assert in my VHDL code that validates generics passed through the entity of my component. The severity of the assert is set to FAILURE, because I want to quit the simulation if the generics are misused. When simulating with Active-HDL (really any version, but I've specifically used versions 12-14a), the assert is hit when the generics are misused and the simulation exits before doing anything else. When simulating with ModelSim DE (I've only tried 10.6c, 32-bit), however, the assert is not the first thing to be evaluated, and a different error appears for a signal assignment of different array lengths, related to the values of the generics (which is why the assert exists). Here is my MCVE:
example.vhd:
library ieee;
use ieee.std_logic_1164.all;
entity example is
generic
(
INPUT_LEN : integer := 4;
OUTPUT_LEN : integer := 5
);
port
(
my_input : in std_logic_vector(INPUT_LEN-1 downto 0);
my_output : out std_logic_vector(OUTPUT_LEN-1 downto 0)
);
end entity example;
architecture rtl of example is
begin
-- We want this evaluated first.
assert (INPUT_LEN = OUTPUT_LEN)
report "INPUT_LEN and OUTPUT_LEN must be equal!"
severity FAILURE;
-- This is actually what is evaluated first.
my_output <= my_input;
end architecture rtl;
As you can see, my_output and my_input are affected by the values of the generics, and I want the assert to happen first so that a helpful error message will be printed to the console, instead of the current Fatal: (vsim-3420) Array lengths do not match. Left is 32 (31 downto 0). Right is 8 (7 downto 0)..
I compile and simulate using the following two ModelSim commands:
vcom -work work example.vhd
vsim -c -lib work example
My question is, is there a directive for vsim that forces ModelSim to evaluate asserts first? Or more broadly, a command that will look for and evaluate asserts before doing anything else? It seems Active-HDL does it by default, but ModelSim doesn't... I've looked through the documentation for vsim and I've tried the -immedassert flag but that didn't change anything.
I'm also working with very old code that gets used in a lot of different places (and is obviously way more complex than my MCVE), so the best solution would not be to modify the source code.
Thanks for any help.
All concurrent statements are elaborated in process statements or process statements and block statements. The two concurrent statements, the signal assignment and assertion have no guaranteed execution order. Counting on implementation defined apparent ordering results in a non-portable design description.
The assertion can still be ordered. It's possible to get assertions during elaboration.
This can be demonstrated by adding (in this case) a function that returns a boolean as an initial value for an object that never happens to get used (and would be eliminated during synthesis):
library ieee;
use ieee.std_logic_1164.all;
entity example is
generic
(
INPUT_LEN : integer := 4;
OUTPUT_LEN : integer := 5
);
port
(
my_input : in std_logic_vector(INPUT_LEN-1 downto 0);
my_output : out std_logic_vector(OUTPUT_LEN-1 downto 0)
);
end entity example;
architecture rtl of example is
function is_it_safe return boolean is
begin
assert (INPUT_LEN = OUTPUT_LEN)
report "INPUT_LEN and OUTPUT_LEN must be equal!"
severity FAILURE;
return TRUE;
end function;
constant safe: boolean := is_it_safe;
begin
-- We want this evaluated first
assert (INPUT_LEN = OUTPUT_LEN)
report " ORIGINAL INPUT_LEN and OUTPUT_LEN must be equal!"
severity FAILURE;
-- This is actually what is evaluated first.
my_output <= my_input;
end architecture rtl;
The added default values for the generics allow the code to analyzed, elaborated and simulated stand alone (as a Minimal, Complete and Verifiable example).
The report message in the original assertion has been changed for easy identification in case any implementation doesn't include line numbers.
Because the two generics have different default values it's is guaranteed to cause an assertion:
ghdl -a example.vhdl
ghdl -e example
ghdl -r example
example.vhdl:20:9:#0ms:(assertion failure): INPUT_LEN and OUTPUT_LEN must be equal!
./example:error: assertion failed
./example:error: error during elaboration
Line 20 is in the function is_it_safe.
The ordering will hold for Modelsim because objects are elaborated before simulation initialization (where one error or the other occurs now). See IEEE Std 1076-2008 14.4 Elaboration of a declaration, 14.4.2.5 Object declarations and 14.7 Execution of a model, 14.7.5.2 Initialization.
The idea here is to establish an ordered single execution of an assertion that was originally a concurrent statement (which is elaborated into a process with no sensitivity list and a final wait statement with no clauses, See 11.5 Concurrent assertion statements).
Note no answer so far answers the narrow question on how to affect process execution order in Modelsim.
It should not be possible to order concurrent statement execution. The order of the list of all processes executed until they suspend at the beginning of simulation (14.7.5.2) would be implementation defined and non-portable. That's already been demonstrated by the Original Poster.
Moving the assertion or providing a new copy in a function used during elaboration can guaranteed the assertion statement is executed before any assignment statement during initialization.
Also note the idea of an assertion testing the equality of the values of two constants of the same type could be viewed as an anti-pattern somewhat as JHBonarius commented. A fix adopted from programming which has little to do with hardware description and only serves to produce a particular message in the face of a lack of standardized error messages.
VHDL will already catch the error in the original code albeit requiring VHDL or tool implementation familiarity.
With the assertion in a function providing an object value the concurrent assertion statement can be eliminated.
VHDL is a strongly typed language. I am not sure about the construct of Modelsim that let you run the assertions first.
All you can try is type cast the my_output <= my_input as my_output <= std_logic_vector(my_input) this will let Modelsim simulate your design but as soon as you try to RUN your design, it will throw an Error.
Without the type-casting, it won't let you even simulate your design.
You can realize sequential processing by putting it in a process. Example:
library ieee;
use ieee.std_logic_1164.all;
entity example is
generic (
INPUT_LEN : integer := 5;
OUTPUT_LEN : integer := 6);
port (
my_input : in std_logic_vector(INPUT_LEN-1 downto 0);
my_output : out std_logic_vector(OUTPUT_LEN-1 downto 0));
end entity;
architecture rtl of example is
begin
assign_my_output: process(my_input) begin
assert (INPUT_LEN = OUTPUT_LEN)
report "INPUT_LEN and OUTPUT_LEN must be equal!"
severity FAILURE;
my_output <= my_input;
end process;
end architecture rtl;
vcom -work work example.vhd
vsim work.example
run 1 ns
# ** Failure: INPUT_LEN and OUTPUT_LEN must be equal!

VHDL assignment when ... else renders syntax error

Simply, what would be wrong with this line?
zero <= '1' when alu_out = "00000000" else '0';
It is within a process. zero is std_logic and alu_out is std_logic_vector(7 downto 0). Both are defined in the entity and the assignment is made in the architecture. The error is:
Error (10500): VHDL syntax error at alu.vhd(27) near text "when"; expecting ";"
Sounds like using VHDL-2002 revision, where the concurrent conditional signal assign format can't be used as a statement in a process.
Try to enable VHDL-2008 revision support if the tool allows, otherwise use an if statement or write your own ternary function.
Also see this question and answer.
For Altera Quartus Prime ver. 15.1 the VHDL input version selection is shown in the figure below.

found '0' definitions of operator "+" in VHDL

At first I wanna point out that this is my first attempt with VHDL so be kind. I want to read the X1 ... X4 inputs and produce the sum of the ones at the output. This my code
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity counter_of_aces is
Generic(N: integer := 3);
port( X1, X2, X3, X4 : IN BIT;
count: out std_logic_vector(N-1 downto 0));
end counter_of_aces;
architecture behavioral of counter_of_aces is
signal counter : std_logic_vector(Ν-1 downto 0);
begin
process (X1, X2, X3, X4)
begin
counter <= "0";
if(X1='1' OR X2='1' OR X3='1' OR X4='1')then
counter <= counter + "1"; --O counter λειτουργεί ως στοιχείο μνήμης
else
counter <= counter;
end if;
end process;
end behavioral;
and I get the following errors
ERROR:HDLCompiler:69 - Line 11: <í> is not declared.
ERROR:HDLCompiler:1731 - Line 17: found '0' definitions of operator "+", cannot determine exact overloaded matching definition for "+"
ERROR:HDLCompiler:854 - Line 10: Unit <behavioral> ignored due to previous errors.
Which "i" is it referring to and what about the others? Thanks in advance.
Start your VHDL with
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.std_logic_unsigned.all;
These are observations based analyzing the example code a simulator.
ERROR:HDLCompiler:69 - Line 11: <í> is not declared.
This is caused by a non ISO 8859-1 character. I replaced the N with a new N and got past that point. My analyzer pointed at line 11, character 36 and examination showed a two byte character there (X"CE9D").
A VHDL analyzer constructs lexical elements out of specific subsets of the ISO 8859-1 character. Comments can contain any characters in VHDL -2008, while previous revisions of the standard required comments to be comprised of the graphic character subset.
ERROR:HDLCompiler:1731 - Line 17: found '0' definitions of operator "+", cannot determine exact overloaded matching definition for "+"
The context of overload resolution for operator overload functions depends on signatures - the types and number of parameters and type of the return value. A VHDL analyzer will only look where it's directed to other than for an implicit context clause available to every design unit:
library STD, WORK; use STD.STANDARD.all;
This is why we add the likes of:
library ieee;
use ieee.std_logic_1164.all;
to make all the declarations in library ieee package std_logic_1164 visible so they can be used in a design specification.
Without adding the right use and library clauses the analyzer can't find a "+" function with a signature of [std_logic_vector string return std_logic_vector].
to provide the overload function for the "+" operator on line 17:
counter <= counter + "1"; --O counter λειτουργεί ως στοιχείο μνήμης
The string literal "1" would have it's type determined from context (here the entire assignment.
There are two candidate packages for providing an operator overload function: std_logic_unsigned from Synopsys and numeric_std_unsigned a -2008 IEEE package. Neither are made visible currently by a use clause.
Because non- ISO 8859-1 characters are found in the comment it seems you have a IEEE Std 1076-2008 compliant analyzer.
For older VHDL implementations you can stick with the Synopsys package, write your own "+" function, or use type conversions with package numeric_std:
counter <= std_logic_vector(unsigned(counter) + "1");
There's are additional issues
An enable for a latch shouldn't be combinatorial derived. There can be different routing delays or timing causing glitches.
counter(N - 1 downto 0) depends on synthesis (mapping) for implementation behavior to match simulation. If implemented as a latch with an increment there's a feedback path (counter <= counter + "1";) that will produce gated oscillation on the counter outputs. An increment is guaranteed to invert at least one input. Output frequencies would be dependent on routing delays, latch and increment delays.
There are historical synthesis attributes used to direct the else assignment of counter to itself be implemented in logic. Otherwise a synthesis tool would ignore them (as do simulators mostly, an assignment without a change in effective value doesn't cause an event). The attributes likely have been useful for Earle latches in CPLDs while FPGA vendors typically manage all aspects of implementing latches.
In Vivado itself, it is written to add this LAST line mentioned below:
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
use IEEE.NUMERIC_STD.ALL
try this,
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;

VHDL alias syntax "<< ... >>"

I'd like to understand the syntax used in the line of code below where an alternate name is created using an ALIAS declaration. Specifically, I'd like to know what the << and >> imply. An example alias statement is,
alias x2_dac_data is
<< signal server.x2_dac_data : std_logic_vector(23 downto 0) >>;
where server is an instantiated component and x2_dac_data is a signal with the component, but not listed in the port declaration.
I've reviewed Pedroni's text and a course guide, neither of which reference the << ... >> syntax as it relates to alias.
Thanks
The double Less-Thans and double Greater characters (<<, >>) enclose an External Name, which is a path name to a object (e.g. signal, constant, variable) through a design model's hierarchy. The intended use is for design verification, allowing a testbench to reach objects not visible at the top level of a design.
See Peter Ashenden and Jim Lewis The Designer's Guide to VHDL (3rd Ed.), Section 18.1 External Names and Doulos VHDL-2008: Easier to use, Hierarchical Names, or IEEE Std 1076-2008, 8.7 External names.
There's an example on Page 561 of The Designer's Guide to VHDL:
alias duv_data_bus is
<<signal .tb.duv_rtl.data_bus : std_ulogic_vector(0 to 15)>>;
The syntax is described on Page 560. Pages 559-562 are visible in the Google Book preview. The example found in The Designer's Guide to VHDL dealing with external names is also found in Chapter 2, Section 2.1 External Names of VHDL 2008 Just the New Stuff by the same authors and while without the EBNF syntax description goes further into the philosophy behind external names. Unfortunately the book's Google Book preview doesn't reach Section 2.1. Jim Lewis is organizing the P1076 Study Group of the IEEE VHDL Analysis and Standardization Group (VASG) responsible for developing the next revision of IEEE Std 1076-201X. Peter Ashenden is a long time contributor to the VHDL standardization effort as well.
A better solution than aliases to hierarchical signal references in packages: using a package to share signals between bfm-procedures and testbench toplevel. Example:
library ieee;
use ieee.std_logic_1164.all;
--VHDL 2008 with questasim
package bfm is
signal tb_ii_a : std_logic;
signal tb_ii_b : std_logic;
signal tb_oo_c : std_logic;
procedure wiggle;
end package;
package body bfm is
procedure wiggle;
begin
tb_oo_c <= force in '1';
wait for 10 ns;
tb_oo_c <= force in '0';
wait for 10 ns;
tb_oo_c <= force in tb_ii_a and tb_ii_b;
end procedure;
end package body;
library ieee;
use ieee.std_logic_1164.all;
use std.textio.all;
use std.env.all;
library work;
use work.bfm.all;
entity tb;
end tb;
architecture tb_dut1 of tb is
begin
dut : entity work.dut port map(
oo_a => tb_ii_a, -- output of dut input of tb bfm
oo_b => tb_ii_b, -- output of dut input of tb bfm
ii_c => tb_oo_c -- input of dut output of tb bfm
);
testcase : process
begin
wiggle;
wait for 100 ns;
std.env.stop(0);
end process;
end architecture;

VHDL syntax for arrays of clocks (accepted by synthesis but not Active-HDL simulator)

I've a problem with some VHDL syntax in some old code that I want to reuse. It is accepted by the synthesis tool (Synplify) but the simulator (Aldec Active-HDL 8.3) gives the following error. (Note: This construction was accepted by a previous version of this simulator).
#Error: COMP96_0228: buffered_data.vhdl : (19, 28): The actual must be denoted by a static signal name, if the actual is associated with a signal parameter of any mode.
I get that the error doesn't like the (i) in the signal clk(i) but I don't want to unroll the loop to (0),(1),etc because it's used in several different configurations for different port sizes and I'm sure there must be a way to describe this.
My solution so far is to encapsulate one instance in it's own entity/arch hierarchy and use a "generate" to instantiate once for each port but I don't like it. Any better ideas?
Very simplified example showing exactly my issue. (The intent is to ensure that data is first clocked into the FPGA using its own associated clock before anything else)
library IEEE;
use IEEE.STD_LOGIC_1164.all;
entity input_buffer is
port(
clk : in std_logic_vector;
data_in : in std_logic_vector;
data_out : out std_logic_vector
);
end input_buffer;
architecture rtl of input_buffer is
constant c_NumOfPorts : integer := 3;
begin
p_process: process(clk)
begin
for i in 0 to c_NumOfPorts-1 loop
if rising_edge(clk(i)) then -- error here
data_out(i) <= data_in(i);
end if;
end loop;
end process;
end rtl;
If you change the loop inside the process into a generate statement outside the process, it works fine in ModelSim (I don't have Aldec available), and IMHO seems cleaner than a single process with a bunch of clocks. I would also typically use a generic to define the port widths, rather than pulling them in as a constant inside the architecture, but I figure you've got some reason for doing it that way:
library IEEE;
use IEEE.STD_LOGIC_1164.all;
entity input_buffer is
port(
clk : in std_logic_vector;
data_in : in std_logic_vector;
data_out : out std_logic_vector
);
end input_buffer;
architecture rtl of input_buffer is
constant c_NumOfPorts : integer := 3;
begin
gen : for i in 0 to c_NumOfPorts-1 generate
begin
p_process: process(clk(i))
begin
if rising_edge(clk(i)) then -- error here
data_out(i) <= data_in(i);
end if;
end process;
end generate;
end rtl;
FWIW, I get the same with Modelsim:
Model Technology ModelSim PE vcom 10.0a Compiler 2011.02 Feb 20 2011
-- Loading package STANDARD
-- Loading package TEXTIO
-- Loading package std_logic_1164
-- Compiling entity input_buffer
-- Compiling architecture rtl of input_buffer
** Error: clk.vhd(19): (vcom-1450) Actual (indexed name) for formal "s" is not a static signal name.
** Error: clk.vhd(25): VHDL Compiler exiting
As an aside - is there a reason for your use of the constant and not just doing this?
for i in clk'range loop
But no actual answer has occurred to me yet, sorry!

Resources