What are labels used for in VHDL? - vhdl

A lot of VHDL structures has the option for an optional_label before the declaration, but what is this label used for?
Here is a process declaration example from vdlande showing the option for a label:
optional_label: process (optional sensitivity list)
-- declarations
begin
-- sequential statements
end process optional_label;

Labels are used for identification.
IEEE1076-2008 for instance says
7.3.1 General
A configuration specification associates binding information with component labels representing instances of a given component declaration.
consider the next piece of code:
entity e is end entity;
architecture a of e is begin
process is begin wait; end process;
foo: process is begin wait; end process;
end architecture;
In simulation (with modelsim) this will show as
I.e. label foo is fixed, while the other process is just assigned some reference, in this case the line number. Is you are using attributes, configurations, aliases, etc, you often need to refer to specific objects and their location. You need fixed names for that.
If you look at the IEEE1076-2008 standard, you can see that about every statement can have a label: if, case, loop, etc.

You can use labels to identify things in a simulator as JHBonarius says, but there are other uses for labels, too:
i) Identifying the end of a long block of code, eg
my_if : if A = B then
-- lots of lines of code
end if my_if;
ii) keeping track of complicated code, eg
my_if_1 : if A = B then
my_if_2 : if A = B then
my_if_3 : if A = B then
my_if_4 : if A = B then
my_if_5 : if A = B then
my_if_6 : if A = B then
-- blah blah blah
end if my_if_6;
end if my_if_5;
end if my_if_4;
end if my_if_3;
end if my_if_2;
end if my_if_1;
iii) It is usually a good idea to label assertions so that they can be easily identified in an EDA tool, eg :
enable_check : assert enable = '1';
iv) If you label something, then you can decorate it with an attribute (ie attach some metadata for some other EDA tool), eg something like this might stop a synthesiser optimising something away:
attribute KEEP : boolean;
attribute KEEP of g0:label is TRUE;
...
g0 : CLK_EN port map ( ...
(The exact names will depend on the synthesiser.)

Related

VHDL - Why is it bad practice to not include an else-condition in a "process" block?

I'm watching a beginner tutorial on VHDL. The lecturer says that it's bad practice to not include an else-condition inside a "process" block because it will create a latch and is bad for timing in advance circuits. He said that including an else-condition will create a mux instead and is better to use in most case.
Why is that?
snippet from lecture video
Why is a latch design bad for timing and what makes the mux design better?
The point is to make VHDL code that results in the design you want, and the risk is that you will inadvertently create a latch.
There are several basic constructions in VHDL, that can illustrate this.
Mux by process with if-then-else, can be made with this code:
process (all) is -- Mux
begin
if sel = '0' then
z <= a;
else
z <= b;
end if;
end process;
Mux by process with if-then and default assign, can be made with this derived code:
process (all) is -- Mux
begin
z <= b; -- Default b, thus for sel = '1', since no overwrite
if sel = '0' then
z <= a;
end if;
end process;
However, if you want to make a mux, then a better coding style is by continuous assign with this code:
z <= a when (sel = '0') else b;
Finally, what can lead to a latch with a process, is if the resulting output is not assigned in all branches of the code. That can occur, if the if-then does neither have an else, nor a default assign to the output, like this code:
process (all) is -- Latch
begin
if en = '1' then
q <= d;
end if;
end process;
So a good rule when designing combinatorial logic using a process, is to have an initial line that makes a default assignment to the resulting output, for example just assing undefined 'X'. A latch is thereby avoided, and functional verification should catch the undefined 'X', if this is a bug.
Also, remember to check the syntheis report for warnings about created latches, since that is most likely a bug in the design.

Signal in Top Module of a design being driven by two drivers (from different components)

In my design I have several modules. the code snippet of the top module is coming as follows.
There's one problem which confuses me. let's assume the below scenario:
Step1:
The Calc1_module works from t1 to t2 and it should send it's output to the input of the memory module to be stored there. (Calc1_out is mapped to Aggregation_Signal)
Step2:
The Calc2_module works from t3 to t4 and it should send it's output to the input of the memory module to be stored there. (Calc2_out is mapped to Aggregation_Signal).
The Memory_Moduel_in is mapped to Aggregation_Signal.
Since there are multiple drivers for one signal, it has all the time an unknown value.
It's worth mentioning that all controls occur within FSM to decide when it goes after Calc1 and when Calc2.
How I can selectively interleave different data from different sources on one wire (signal) on at a time -in the top module of the design- without pushing that wire into an unknown state?
In other words, how is it possible to aggregate:
value1 for signal1 (e.g. coming from Calc2 in t1 to t2)
value2 from signal2 (e.g. coming from Calc1 in t2 to t3)
all in one Aggregation_Signal without driving it into unknown state.
entity TOP is
port (...);
end entity;
architecture Behav_TOP of TOP is
component FSM is
port(...);
end component;
component Calc1_Module is
port
( ...
Calc1_Module_out
... );
end component;
component Calc2_Module is
port
( ...
Calc2_Module_out
... );
end component;
component Memory_Module is
port
( ...
Memory_Module_in
... );
end component;
Signal Aggregation_Signal;
begin
U_FSM : FSM
port map(...);
U_Calc1_Module : Calc1_Module
port map
( ...
Calc1_Module_out => Aggregation_Signal,
... );
U_Calc2_Module : Calc2_Module
port map
( ...
Calc2_Module_out => Aggregation_Signal,
... );
U_Memory_Module : Memory_Module
port map
( ...
Memory_Module_in => Aggregation_Signal,
... );
end Behav_TOP;
The clue is in your term "selectively interleave".
How do you make that selection? Presumably you know when you want to see Calc1, when you want to see Calc2, etc. So encode that information onto a signal, let's call it Selector.
Then bring each unit's output onto its own signal, Calc1_output etc and use Selector to select between them onto Aggregation_Signal.
Aggregation_Signal <= Calc1_output when Selector = Calc1
else Calc2_output when Selector = Calc2
else (others => '0';
The Selector signal can be an enumeration with one value per Calc unit, or a Natural or a std_logic_vector with constants named Calc1, Calc2 etc.
Since you say the calculation is driven by a state machine, it is logical for the state machine to drive Selector with the correct value whenever you need a value on Aggregation_Signal.

VHDL - Conditional attribute declaration depending on a generic

How do I write a code segment which would evaluate a generic and create (or not create) an attribute accordingly?
Example :
if G_MY_GENERIC then
attribute my_attribute_typ : string;
attribute my_attribute_typ of signal_having_an_attr : signal is "value";
else
--nothing is created
end if;
It is perfectly possible to write something similar to that, but the attribute will only be visible in the scope of the generate statement.
g_something: if test_condition generate
attribute my_attribute_typ : string;
attribute an_attribute of my_attribute_typ: signal is "value";
begin
-- attribute is visible in this scope
p_my_process: process(clk)
begin
-- attribute is also visible here
end process;
end generate;
-- but not here
Instead you have to use something like the following to conditionally set an attribute (cumbersome, but achieves the result):
signal asvRam : svRam_at(0 to gc_nFifoDepth-1) := (others => (others => '0'));
type svStr_at is array(boolean) of string(0 to 10);
constant c_svRamStyle : svStr_at := (false => " ", true => "distributed");
attribute ram_style : string;
attribute ram_style of asvRam : signal is c_svRamStyle(gc_bDistributedRam);
We talked more generalized conditional compilation in the IEEE VHDL Working Group. The debate was heated. Some wanted a compile time approach (similar to 'C') and some an elaboration time approach. Compile time approach works well in C because constants are also compile time objects, however, in VHDL, a compile time approach will not understand things in the VHDL environment, and hence, using a generic is not an option. OTOH, the compile time option would probably give you vendor name, tool type (simulator, synthesis, ...), ...
I have added your code as a requirement to the proposal page. It is at: http://www.eda.org/twiki/bin/view.cgi/P1076/ConditionalCompilation
If you are willing to share additional insight on your application, I would like to add that to the proposal also.
Basically: this is exactly how VHDL does not work. In VHDL you declare your intent to use specific bits of hardware, and then the synthesizer attempts to connect those bits of hardware. Any semblance of dynamically creating hardware like for ... generate loops are essentially just a semblance: syntactic sugar to take the pain away.
What you can do is conditionally assign to signals/variables:
process (sig1, sig2, enable) is
begin
if enable = '1'
then
out <= sig1;
else
out <= sig2;
end if;
end process;

Define "enum"-type depending on generics

I am writing a statemachine, which has a generic parameter, and some states existence depends on this. Since I have my states defined in something like an enum (don't know the vhdl term for it), I wonder if I can define this enum depending on the generic somewhat like so:
generic(x: bool); -- in the entity
....
architecture ...
if x then generate
type states_t is (State1, State2, State3ifX)
else
type states_t is (State1, State2)
end generate;
variable state : states_t;
begin
case state is
....
if x then generate
when State3ifX =>
...
end if;
end case
end architecture;
Do I have to carry the dead weight (logic for state3, danger to drop into it (does not matter in my case since I do not expect radiation), additional bit since ceil(ld(3))=2 > ld(2)=1), or is there a possibility to strip unnecessary state(s)?
(In my case there are several states that could be stripped, however seperate architectures are not worth while the effort)
you can define the "states"-type in a process that is optionally generated using a generic. see a reference example below:
entity blabla is
generic(sel: std_logic := '0');
port(
...
architecture Behavioral of blabla is
begin
q1: if sel='0' generate
p: process(clk)
type t_state is (s1, s2, s3);
variable state: t_state;
begin
if rising_edge(clk) then
...
end if;
end process;
end generate;
q2: if sel='1' generate
p: process(clk)
type t_state is (s1, s2);
variable state: t_state;
begin
if rising_edge(clk) then
...
end if;
end process;
end generate;
I can't think of a way to achieve what you need.
On the upside, your concern about having to "carry the dead weight (logic for state3, danger to drop into it)" is not something you need to worry about - the synthesizer will optimise the logic away, so the state register will only be as big as it needs to be for the states you can actually reach.
I know its an old tread but still a hit on google so Im adding how Im doing it
label: if x generate
declarations <- put types, signals & attribures here !!!!
begin
ur code
end generate label;
You might want to consider second architecture or even simpler just a different entity - just another vhd file with slightly different name (like _x1, then _x2)
I find "genercis system" not really practical in more advanced cases (to much bloat-code to write), and then u might use different synthezisers so two archoitecture with one entity might not work, generate with decalrations inside might not work.... I would create different vhd for that - it will work in all the cases)
Cheers

Avoid duplicating code in VHDL

I have a code listing that is full of code like the following, but larger chunks.
if (m = '00000') then
done <= '1';
else
done <= '0';
end if;
Is there any way of making this like a function of a c like #define so that I don't have to write the same code all over the place?
This code is not VHDL in the first place, so you have other things to worry about. (It's a bit more VHDL-like after the edit)
Thankfully VHDL has nothing like C's #define. Instead it has tools for proper abstractions such as packages (very roughly, C++ namespaces but done right), functions and procedures.
This allows you to write
done <= test_zero(m);
assuming done is a signal ( or done := test_zero(m); if it's a variable)
test_zero is then a function, something like
function test_zero ( word : in std_logic_vector) return std_logic is
begin
if word = (word'range => '0') then
return '1';
else
return '0';
end if;
end test_zero;
which (because it uses the "range" attribute) will work with different sizes of "m".
You will end up with a collection of useful functions : keep them in a package and use them throughout the project.
A package usually appears as two parts : the package specification (a bit like a C header file done right)
package my_tools is
function test_zero ( word : in std_logic_vector) return std_logic;
end my_tools;
and a package body containing the implementations
package body my_tools is
function test_zero ( word : in std_logic_vector) return std_logic is
...
end test_zero;
end my_tools;
To use it, it is compiled into a library (we'll use the default library "work" which is already declared by an implicit library work; in every VHDL file). Then you can choose either to make everything in the package visible in your code:
use work.my_tools.all;
Or make only one function visible:
use work.my_tools.test_zero;
Or make it obvious to anyone reading the code where the mysterious "test_zero" function came from:
done <= my_tools.test_zero(m);
If you have used C++ namespaces you will recognise these different strategies.
What makes the VHDL equivalent "namespaces done right" is that the VHDL compiler uses these declarations to track dependencies automatically and compile the right bits, instead of needing additional #includes and external tools like makefiles which must be kept in sync with the actual code by hand.

Resources