Evaluate Assert First when Simulating - vhdl

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!

Related

VHDL type conversion - found 4 possible definitions

I am trying convert two std_logic bits to an integer as follows
LIBRARY IEEE;
USE IEEE.std_logic_1164.ALL;
USE IEEE.numeric_std.ALL;
ENTITY TEST IS
PORT (sw1, sw0 : IN std_logic;
x : OUT integer RANGE 3 DOWNTO 0);
END ENTITY TEST;
ARCHITECTURE dflow OF TEST IS
SIGNAL mes_sel : integer RANGE 3 DOWNTO 0;
BEGIN
mes_sel <= to_integer(unsigned(std_logic_vector(SW1 & SW0)));
x <= mes_sel;
END ARCHITECTURE dflow;
but the compiler does not like the mes_sel assignment. I get the following compiler error message:
Error (10327): VHDL error at Q4.vhd(92): can't determine definition of operator ""&"" -- found 4 possible definitions
Can I not concatenate 2 bit of std_logic to a vector and then convert? Or is it something else?
regards
D
The error message tells you roughly what's wrong, and it's not a problem with the assignment.
GHDL gives a better diagnosis:
ghdl -a test.vhd
test.vhd:13:57: can't resolve overload for operator "&"
test.vhd:13:57: possible interpretations are:
../../src/ieee/numeric_std.v93:66:18: array type "signed"
../../src/ieee/numeric_std.v93:65:20: array type "unsigned"
../../src/ieee/std_logic_1164.v93:69:30: array type "std_logic_vector"
../../src/ieee/std_logic_1164.v93:54:31: array type "std_ulogic_vector"
ghdl: compilation error
VHDL allows overloaded operators, distinguishable by the types of their arguments (in this case, std_logic) and their return types, (in this case ... well... what?)
There are apparently 4 types which have a std_logic_vector() type conversion function declared on them, as well as a & operator taking two std_logic arguments; and ghdl (unlike whatever tool you're using) helpfully lists them.
In such cases, VHDL (unlike some other languages) insists that you pick one, rather than arbitrarily making a hidden (and possibly wrong) choice for you.
You can do this with a type mark. As you actually want an unsigned, the obvious choice is unsigned'() (note the "'" symbol, also used for attributes).
mes_sel <= to_integer(unsigned'(SW1 & SW0));
Note that if VHDL allowed anything simpler, like to_integer(SW1 & SW0) it would be positively dangerous as there is nothing to distinguish between signed and unsigned conversions, making the conversion at least non-obvious, and quite possibly wrong.

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.

Vhdl code simulation

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.

Can I access a constant inside a instantiated entity from outside?

I have a VHDL entity with a generic parameter list. The architecture to this entity calculates several constants, which are needed to create the intended functionality.
Is it possible to access one of these constants from outside?
Example 1:
Let's say there is a FIFO that decides based on DEPTH and OUTREG what the best implementation is (register based, SRL based or BlockRAM based). Depending on this the minimum delay through the FIFO can vary from 1 to 2 cycles.
Example 2:
Consider the same FIFO to be cross clock compatible. Now the min delay depends also on the choosen sync circuits and the frequency difference.
Example 3:
A division entity needs N cycles to calculate a div b. N depends on BITS, RADIX, OUTREG, IS_SIGNED, ...
Further let's say each entity has a MIN_DELAY constant of type NATURAL which is of interest for other instances.
E.g. the instantiating entity needs to know how long it must at least wait for a result.
I can think of 2 solutions, but I think neither is a nice one.
Solution 1:
I could store the algorithmn for the computation in a package so it's globally accessable. But this is against the encapsulation principle :). The outside world only needs to know the delay value not the algorithmn.
Solution 2:
I could use a valid bit. That's always a good solution in dynamic, adaptive or pipelined systems, but this bit can not be used at synthesis time for further choices or optimizations.
Possible solution 3:
VHDL has the ability to define new attributes, but can they be accessed?
Example entity: alu_div:
constant MIN_DELAY : NATURAL := BITS / log2(RADIX) + 2;
attribute DELAY : NATURAL;
attribute DELAY of alu_div : entity is MIN_DELAY;
Example top:
mydiv : entity work.alu_div
generic map (....)
port map (....);
blk : block
constant my : NATURAL := mydiv'delay;
begin
....
end block;
NEW: Possible solution 4:
I found this SE question, where Jim Lewis noted that hierarchical references should also work with constants.
alias MY_DELAY is <<constant mydiv.DELAY : NATURAL >>;
Get internal signals of vhdl design in ncvhdl (alternative to modelsim's signal spy)
This is a modification of Morten's first entity declaration, in which for the 'module' instantiating alu_div I expect there's a component declaration which provides the declaration for the name alu_div.
There is no attribute decorating that declaration so the instantiation found at label alu_div_0 has no attribute DELAY.
If you were to use direct entity instantiation it might work:
entity alu_div is
constant MIN_DELAY : NATURAL := 42;
attribute DELAY : NATURAL;
attribute DELAY of alu_div : entity is MIN_DELAY;
end entity;
architecture foo of alu_div is
begin
end architecture;
entity test is
end entity;
architecture foo of test is
begin
alu_div_0:
entity work.alu_div ;
MONITOR:
process
begin
wait for 1 ns;
report "alu_div'DELAY = " & natural'image(work.alu_div'DELAY);
wait;
end process;
end architecture;
Which gives:
ghdl -a alu_div.vhdl
ghdl -e test
ghdl -r test
alu_div.vhdl:25:9:#1ns:(report note): alu_div'DELAY = 42
>
The idea is that if you use a direct entity instantiation with a selected name (an expanded name) you're using the declaration in the library noted by the prefix (in this case WORK).
The following demonstrates accessing the value of alu_div'DELAY can be done at elaboration:
entity alu_div is
generic (pickone: natural := 1);
constant MIN_DELAY : NATURAL := 42;
constant TARG_DELAY: natural := MIN_DELAY + pickone;
attribute DELAY : NATURAL;
attribute DELAY of alu_div: entity is MIN_DELAY;
-- attribute DELAY of alu_div : entity is TARG_DELAY;
end entity;
architecture foo of alu_div is
begin
end architecture;
entity test is
end entity;
architecture fie of test is
constant fumble: natural := work.alu_div'DELAY;
component alu_div is
generic (pickone: natural := 1);
end component;
begin
alu_div_0:
alu_div
generic map(1);
MONITOR:
process
begin
report "constant fumble = " & natural'image(fumble);
report "alu_div'DELAY = " & natural'image(work.alu_div'DELAY);
wait;
end process;
end architecture;
And that works:
ghdl -a alu_div.vhdl
david_koontz#Macbook: ghdl -e test
david_koontz#Macbook: ghdl -r test
alu_div.vhdl:60:9:#0ms:(report note): constant fumble = 42
alu_div.vhdl:61:9:#0ms:(report note): alu_div'DELAY = 42
Also following Jonathan's comment that the question was attempting to loop information through the instantiated component supplied by generics I tried switching the entity attribute to depend on a generic (commenting out the one with MIN_DELAY, uncommenting the one with TARG_DELAY) and that results in a different error than Morten supplied:
ghdl -a alu_div.vhdl
alu_div.vhdl:36:13: attribute expression for entity must be locally static
ghdl: compilation error
And that error is singularly helpful and easy to find in the 2008 LRM and is quite specific:
7.2 Attribute specification (paragraph 8):
The expression specifies the value of this attribute for each of the named entities inheriting the attribute as a result of this attribute specification. The type of the expression in the attribute specification shall be the same as (or implicitly convertible to) the type mark in the corresponding attribute declaration. If the entity name list denotes an entity declaration, architecture body, configuration declaration, or an uninstantiated package that is declared as a design unit, then the expression is required to be locally static (see 9.4.1)....
This requirement was introduced in the '93 LRM (5.1 Attribute specification). And researching that we find there was a proposal for out-mode generics in the -1992 standardization effort (approved in -1993).
Also in the '87 Issue Report 40 (IR00040.txt) following the first ISAC rationale report of a discussion of the problem as relates to setting the attribute from within an architecture:
Such a capability would greatly (and negatively) affect at least some
implementations. A straightforward approach to the implementation of
specifications is to decorate the named entity with the information
contained in the specification. However, when the entity appears in
one design unit and the applicable specification appears in another,
many problems result. One cannot analyze the specification without
modifying the library unit containing the entity, which can lead to
potential circular chains of dependence. Moreover, multiple
architectures corresponding to a given entity interface cannot each
supply a different value to the attribute of some interface-resident
entity. Finally, there is no LRM requirement that, if one architecture
attributes some interface-resident entity, then all must, which seems
desirable.
You could note the undesired circular dependencies are also possible with an attribute dependent on a generic. Or similarly with out-mode generics the issue moves from circular dependencies in analysis order (locally static expressions in attribute declarations) to elaboration order (evaluating globally static expressions) which is likely quite a bit harder. out-mode generics show sporadic mention in available records, the last time on the vhdl-200x-mp (Modeling and Productivity) email reflector.
It's not likely the status of either of these will change without someone defining how to deal with late binding (linking loader time) order dependencies.
In the mean time as Brian says the accepted method is to use a package commonly shared, which uses locally static constant declarations (and are declaration order dependent). You could also manage the issue with configuration.
Good question. I have sometimes felt the need for "OUT mode generics" too, whose actual value is computed within the architecture, again to allow the higher levels in a hierarchy to know (and adjust to) the pipeline depth of a processing unit.
It might be worth writing a proposal to allow something of the sort in VHDL-201x and submit it to the standards group but meanwhile we have to live with what we have.
My normal solution is to use a package associated with the unit, holding both the initial constant (instead of a generic) and the dependent quantities. This limits the "encapsulation breakage" to those compilation units that use the package, making them at least readily identifiable.
Within the package the constants are deferred where possible, or parameterless (impure) functions, which amount to the same thing.
A possible approach I haven't explored is that an entity declaration, after the PORT list, also allows zero or more entity_delarative_items. If these may include function declarations, then we could potentially return such information that way.
EDIT : David points out an LRM rule (8.3) that prevents this approach with current VHDL versions : a limited relaxation of that rule might be an alternative to "OUT mode generics".
An entity declaration may also include begin and some passive constructs - such as asserts that a set of generics and port widths are consistent. That way you would have to input all the required values, but at least the build would fail reporting errors if e.g. width and depth were inconsistent.
Agree that it is sometimes very useful with information about implementation
details from the entity, even though it breaks the encapsulation principle, but
for white box verification it can be a great help.
Tried to use entity attribute based on entity like:
entity alu_div is
generic(
BITS : positive;
RADIX : positive);
port(
...);
constant MIN_DELAY : NATURAL := BITS / log2(RADIX) + 2;
attribute DELAY : NATURAL;
attribute DELAY of alu_div : entity is MIN_DELAY;
end entity;
But the module where the alu_div is instantiated is not able to access it
using e.g. alu_div_0'DELAY, since ModelSim gives error:
No attribute specification with designator "DELAY" decorates label "alu_div_0".
One method that is useful for white box verification, where the verification
depends on the implementation, is to make an output port with information from
the implementation, like:
entity alu_div is
...
port(
...
DELAY_O : out natural);
...
end entity;
architecture syn of alu_div is
begin
DELAY_O <= MIN_DELAY;
...
It won't be a true constant, since for simulation it will need a delta cycle
before getting the value, but it may be a sufficient solution in many cases.
Another approach I have used is to live with the restriction that all "generic" information flows into a module by specifying as another generic, the result I want from the derived parameter.
For example,
entity alu_div is
generic(
BITS : positive;
RADIX : positive;
DELAY : positive);
port(
...);
Within the architecture, an ACTUAL_DELAY constant is derived from the other generics (plus port bus-widths, etc) and compared with the given DELAY generic.
If the requested DELAY and ACTUAL_DELAY are identical, all is well.
If the requested DELAY exceeds ACTUAL_DELAY, the architecture can insert pipeline stages to meet the request. The overall design will function as intended, though it may consume more registers than strictly necessary.
Otherwise the requested delay cannot be met, and the architecture asserts with severity FAILURE.

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