What does don't cares and null do in VHDL? - vhdl

What does setting a value to don't cares actually mean and do in VHDL? Also what's the difference between setting the values to don't care vs setting it to null?
Here's a snippet from the lab I'm doing:
with selector select
mux_data_selected <= Channel_1_registered_data when '0';
Channel_2_registered_data when '1';
(others => '-') when others;

The type of the elements of mux_data_selected is probably std_ulogic or one of the like. To answer your last question, there is no null value in these types, so you cannot assign (others => null).
null is a void instruction that does nothing and that is sometimes used to indicate that there is nothing to be done in a branch of the control flow and that it is intentional.
It is also a pointer value (access types). Finally we sometimes talk about null arrays but it means that the array has an empty range, like 1 to 0, for instance. If your vector has a non-null range you cannot assign it a null array value, this would cause an error.
The - don't care value is one of the 9 values of the std_ulogic enumerated type. As its name says it is for cases where you do not care about the value. Either because you know this situation will never happen in real life or because when the situation happens you do not use the signal.
A smart enough logic synthesizer can use this indication to implement any actual '0' or '1' value that improves one metric (speed, area, power...) While if you code, e.g., '0' the synthesizer is forced to obey, which could lead to a speed, area or power waste.
As noted by #user16145658 the '-' value is also treated as a match anything wildcard by VHDL2008 STD_MATCH functions and predefined matching relational operators (?=, ?/=, ?<, ?<=, ?>, and ?>=). So you can use it also for soft comparisons.

Related

VHDL create enumerated "bit" values for std_ulogic_vector

I have a group of 19 bits with each bit having a specific meaning ( a group of flags ). I would like to label each of these bits so they are identified within the simulator with their label.
These bits are read over a communications interface, and when I get them, they are in std_logic_vector value something like this:
signal myflags : std_ulogic_vector(18 downto 0);
I am new to VHDL, but I think the proper procedure for this is to create an enumerated type, but I am not exactly sure how to do this. I have created enumerated types for state machine signals, but the enumeration of each state "label" is just the next numeric value (0,1,2,3, etc). This is not what I want to do. Instead, I want each bit specifically enumerated (or at least a label assigned to each bit).
Really, this would not even come up as an issue if ModelSim would allow me to change the displayed value for a bit. The example below shows my desire to change the Display Name from (31), bit 31 in a std_ulogic_vector value, to "power_good". Any advice would be appreciated.

How to create boolean data type to standard logic in VHDL

Is there an existing function within the regular std.logic library to convert a boolean data type to std logic in vhdl?
The answer in short: no.
As #Harry pointed out, it isn't possible to map 2 values from boolean to 9 values from std_logic.
The std_logic-type is used, among other things, to detect problems in your code whilst simulating and to have a better representation how the hardware will act later on.
So I would recommend you to not write a function which converts true to '1' and false to '0', because then you'll lose the advantage of the std_logic-type.
It is noted, that converting from std_logic to boolean is allowed and even implemented since the VHDL 2008 standard.

Updating VHDL generic map values in execution

Probably an easy one, but has been a while since I've dabbled in VHDL, but I'm trying to figure out how to properly change generic values of a sub-component after instantiation, when an event happens. Some pseudo code is below that jumps to the point:
U1: PARITY
generic map (N => 8)
port map (A => DATA_BYTE,
ODD => PARITY_BYTE);
....
process(Some_button_click)
begin
// Change generic map value for N (integer) in PARITY to 10 //
end process;
I'm not in front of the code, but I've tried using 'shared variables' to no avail.... any help is greatly appreciated as this has been strangely hard to google.
I understand what you want to do, but as far as I understand generics are mean to be used only to make components reusable and flexible. It does not make sense to change a constant value at run time. My suggestion is that if you need to change the value you better use a signal port

VHDL - Why does using the length attribute directly on a function produce a warning?

I have a VHDL function that returns a std_logic_vector representation of a record and I want the length of that std_logic_vector. I am able to use the length attribute directly on the function. Why does this produce a warning in ModelSim? Am I inviting subtle problems? Googling the warning text did not turn up anything I understood to be helpful.
my_function_returns_slv(my_record)'length;
** Warning: ../src/my.vhd(line#): (vcom-1515) Prefix of predefined attribute "length" is function
call "my_function_returns_slv"
I've written the function to assemble the output by concatenating std_logic_vector representations of the record elements. The length of the record is fixed at compile time, but I do not want to hard code the length. I need the length to create signals for using the function output. So I can't just call 'length on the output of the function (ex: call 'length on a signal holding the function output) because it is not possible to declare an unconstrained signal to hold the output. I could write a similar function to calculate the length of the std_logic_vector, but that would add some significant code, especially for the number of records I have. Should I accept the ModelSim warning and carry on? Should I deal with the extra code from writing functions to assemble the bit width of my records? Is there a better solution altogether?
Helpful record pack/unpack subprograms I am making use of:
http://www.eda-twiki.org/twiki/pub/P1076/RecordReflectionToSlv/standard_functions.vhd
Thanks!
Using the 'length attribute directly on a function can be seen as just taking another part of the function result than the primary output, thus from a conceptual point of view there should be nothing wrong with that.
So I would accept the ModelSim warning, but also take it as an indication that the tool is worried about the construction, so I would check that my other tools, e.g. synthesis tools and code checkers, accept this use of an attribute directly on a function call.
Appears that you can avoid the ModelSim warning by making a function like:
function len(slv : std_logic_vector) return natural is
begin
return slv'length;
end function;
and then this won't result in a ModelSim warning:
signal MY_LEN : natural := len(slv_not(CONST));
So being able to avoid the warning using such encapsulation confirms that the warning is a little flaky in the first place.
"I need the length to create signals for using the function output. So I can't just call 'length on the output of the function (ex: call 'length on a signal holding the function output) because it is not possible to declare an unconstrained signal to hold the output."
A fun work around for sizing signals is:
constant MY_CONST : std_logic_vector := my_function_returns_slv(my_record) ;
signal MySig : std_logic_vector(MY_CONST'range) := MY_CONST ;
We have an LCS for VHDL-2017 that allows signals to be unconstrained and get their constraints from the initialization.

VHDL: Mapping a slice of an output to a signal

I want to map the lower bit (bit0) of a 32 bit output port to a signal and leave the upper bits unconnected (OPEN). Is there a way to treat this mapping as an aggregate?
I've tried the following to no avail:
port map (
some_output => ( 0 => sig_1, others => OPEN)
);
The below is not a valid answer, since it does not adhere to the VHDL standard. This "answer" is however kept here, and not deleted, since it shows what construction to avoid for tool compliance, since some tools apparently accept this non-standard compliant VHDL code.
Example of port mapping without association of all scalar subelement, which is accepted by Altera Quartus II and Mentor ModelSim in some cases, but is also likely to result in warning or error:
port map(
some_output(0) => sig_1,
-- some_output others are simply not included in port mapping
So, as David Koontzs point out in the comment, the VHDL standard (IEEE Std 1076-2008) section "6.5.7 Association lists" describes:
... every scalar subelement of the explicitly declared interface object shall be associated exactly once with an actual (or subelement thereof) in the same association list, and all such associations shall appear in a contiguous sequence within that association list. Each association element that associates a slice or subelement (or slice thereof) of an interface object shall identify the formal with a locally static name.
So it is not valid to only associate some of the scalar subelements, since the standard says "every scalar subelement", and open can't be used for the remaining scalar subelements, since the standard says "Each association element that associates a slice ... of an interface object shall identify the formal with a locally static name.".
Another solution is this:
signal my_vector : STD_LOGIC_VECTOR(3 downto 0);
signal my_vector_float : STD_LOGIC_VECTOR(3 downto 0);
port map (
[...]
some_output(3 downto 0) => my_vector,
some_output(7 downto 4) => my_vector_float,
[...]
);
You can now setup some report filter rules to silence all warning concerning *_float signals.

Resources