Assigning initial value to VHDL vector - vhdl

I am just learning the syntax of VHDL
I'd like to assign an initial value of '1' to Qout(0) and the rest '0'.
I cannot find the reference that shows me the correct syntax.
This gave me an error:
signal Qout: Std_Logic_Vector (4 downto 0) :='1';

As user1155120 says, in VHDL the width of the right hand side has to match the width of the left hand side of an assignment operator (<= or :=).
So, you could use the literal that corresponds to a std_logic_vector, which is a string:
signal Qout: Std_Logic_Vector (4 downto 0) := "00001";
(a string literal in VHDL is enclosed within double quotes). Or (and this is what a more experience VHDL user would do) use an aggregate:
signal Qout: Std_Logic_Vector (4 downto 0) := (0 => '1', others => '0');
The construct on the right hand side is an aggregate. An aggregate is a construct for representing composite data types such as arrays (which is what a std_logic_vector is) and record types (like a struct in C). The above example is saying "make element 0 equal to '1' and make all the other elements equal to '0'. Element 0 is the right hand side, because the array was declared (4 downto 0) (not (0 to 4)).
Using an aggregate might be considered a better way of doing it because, whilst not to clear to a beginner, the code is more maintainable: if the width of the signal were to change, you would not have to modify the aggregate.
You might want to seriously consider why you want to initialise this signal at all. If you are using an FPGA, it may be the case that that the corresponding flip-flops will be initialised as you wish. (I assume this signal Qout will become 5 flip-flops because of the name you have chosen.) On a chip this would never ever be the case - your initialisation would be ignored. You might want to consider whether providing a reset to your flip-flops would be a better solution than initialising a signal, eg an active-high synchronous reset:
process (Clock)
begin
if Reset = '1' then
Qout <= (0 => '1', others => '0');
elsif rising_edge(Clock) then
...

Related

Loop for lines and for position of lines

I want to have a loop that runs the all lines of my code and also that runs every position of all lines.
My problem is in selecting the line that the loop will run, and I want to have simple way to do it without making to write every single line one-by-one, cause the final code will have 66 lines to scan.
Hope you can help me.
Entity of this code will have 66 lines, but I'm just testing it this 10 lines right now:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity lshift is
port( RED_Buffer1 : in std_logic_vector(6 downto 0);
RED_Buffer2 : in std_logic_vector(6 downto 0);
RED_Buffer3 : in std_logic_vector(6 downto 0);
RED_Buffer4 : in std_logic_vector(6 downto 0);
RED_Buffer5 : in std_logic_vector(6 downto 0);
IR_Buffer1 : in std_logic_vector(6 downto 0);
IR_Buffer2 : in std_logic_vector(6 downto 0);
IR_Buffer3 : in std_logic_vector(6 downto 0);
IR_Buffer4 : in std_logic_vector(6 downto 0);
IR_Buffer5 : in std_logic_vector(6 downto 0);
output : out bit_vector(1 downto 0));
end lshift;
What I have done so far but with no success:
ARCHITECTURE main OF lshift IS
SIGNAL condition1: boolean;
signal valor : std_ulogic;
BEGIN
PROCESS(IR_Buffer5)
BEGIN
FOR I IN 1 TO 5 LOOP
FOR J IN 1 TO 5 LOOP
CONSTANT linha_cond : string(1 to 12) := string(("RED_Buffer") && I);
IF (linha_cond(J) = '1') THEN
output <= "01";
END IF;
END LOOP;
END LOOP;
END PROCESS;
END main;
The purpose of this answer is to demonstrate indexing the subelement values of RED_Buffer1 through RED_Buffer5. Without the purpose of the code being revealed this could easily prove to be an XY Problem question.
While it is possible to organize RED_Buffer1 through RED_Buffer5 into a value that can be indexed as shown below, there are other issues as well.
library ieee;
use ieee.std_logic_1164.all;
entity lshift is
port (
red_buffer1: in std_logic_vector (6 downto 0);
red_buffer2: in std_logic_vector (6 downto 0);
red_buffer3: in std_logic_vector (6 downto 0);
red_buffer4: in std_logic_vector (6 downto 0);
red_buffer5: in std_logic_vector (6 downto 0);
ir_buffer1: in std_logic_vector (6 downto 0);
ir_buffer2: in std_logic_vector (6 downto 0);
ir_buffer3: in std_logic_vector (6 downto 0);
ir_buffer4: in std_logic_vector (6 downto 0);
ir_buffer5: in std_logic_vector (6 downto 0);
output: out bit_vector (1 downto 0)
);
end entity lshift;
architecture indexed_array of lshift is
signal condition1: boolean;
signal valor: std_ulogic;
type lbuffer is array (1 to 5) of std_logic_vector (6 downto 0);
signal red_buffer: lbuffer;
begin
red_buffer <= (red_buffer1, red_buffer2, red_buffer3, red_buffer4,
red_buffer5);
process (red_buffer)
begin
for i in 1 to 5 loop
for j in red_buffer'range loop
if red_buffer(i)(j) = '1' then
output <= "01";
end if;
end loop;
end loop;
end process;
end architecture indexed_array;
How the indexing is implemented here
A composite type (lbuffer) having the requisite number of elements with required element subtype is declared. This is possible because the declarations for ports RED_Buffer1 through RED_Buffer5 share a common subtype indication. Assignment to elements of an object of the type lbuffer would be compatible, having matching elements between the target and right hand expression.
A signal red_buffer with a type mark of lbuffer is declared.
A concurrent assignment was made to the signal in a concurrent signal assignment statement in the architecture statement part from an aggregate. The association in the aggregate is positional. It could as easily use named association:
-- red_buffer <= (red_buffer1, red_buffer2, red_buffer3, red_buffer4,
-- red_buffer5);
red_buffer <= (1 => red_buffer1, 2 => red_buffer2, 3 => red_buffer3,
4 => red_buffer4, 5 => red_buffer5);
The type of the aggregate is taken from context, here the assignment statement where red_buffer has the subtype lbuffer.
A selected element of the composite red_buffer is selected by an index name (red_buffer(i)). A subelement of red_buffer(i) is selected by use of an indexed name where the name red_buffer(i) where 'iis a constant using 'j from the inner loop - red_buffer(i)(j).
Note the range of the j parameter doesn't match the index range of subtype of the lbuffer element subtype here identical to the subtype of RED_Buffer1 through RED_Buffer5. This signifies a further potential semantic issue with the original code, whose purpose isn't made clear here. The only hint present in the original code comes from linha_cond where linha means line in Portuguese or Catalan indicating j is used to index within a 'line'.
The original code fails for two reasons
First an object can't be declared inline in VHDL. The for loop parameter is dynamically elaborated from an implicit declaration, the loop parameter is only visible within the loop statement's sequence of statements. The syntax doesn't allow for additional object declarations.
Second a name for a object declaration is conveyed in an identifier list consisting of one or more identifiers which are lexical elements (lexemes) that cannot be manipulated programmatically.
Other semantic issues with the question's code
The assignment to output without the passage of time doesn't appear useful.
A process statement is an independently executing concurrent statement wherein the loop statement containing an assignment to the same signal output will overwrite the projected output waveform for elements of output without any intervening passage of time.
There's only one entry in a projected output waveform queue for any particular simulation time. A simulation cycle consists of signal updates followed by the resumption and subsequent suspension of any processes sensitive to signal updates. The purpose is to emulate parallelism in hardware while describing behavior with sequential statements.
Here that would mean output would be updated to the value "01" if any of the if statement conditions in the unrolled loops evaluate to TRUE. That's likely not the intended behavior (without more information from the original poster).
Also note there is no output assignment to a different value and no default or otherwise assigned value. For synthesis this would represent a hold over delay on output until a '1' is first found.
In both cases this refers to an implicit latch for output.
This issue with the sample code can't be addressed without knowing how it is supposed to work and the only hint that has been shown here on Stackoverflow to date is by a question deleted by the user requiring 10K+ reputation to access (others will see aPage not found message, see revision 1).
Also concepts conveyed from programming or scripting languages don't generally port to Hardware Description Languages which are generally formal notations defined self-referentially (here in IEEE Std 1076, the VHDL Language Reference Manual) requiring inculcation or persistent effort to learn. HDLs generally describe hardware behaviorally and structurally not by programmatic equivalence.

VHDL, how does concatenate work?

I have some code in VHDL. I don't understand how concatenation works.
A : IN STD_LOGIC_VECTOR(3 DOWNTO 0);
B : IN IN STD_LOGIC;
A <= "1111";
B <= '0';
A <= A(2 DOWNTO 0) & B;
Is A "0111" or "1110"?
As far as the concatenation itself is concerned, you seem to be doing that right, but apart from the other errors (you're assigning to an input, as BrianDrummond noted, and you've not got compilable syntax), you'll have a problem because VHDL signal assignments outside of a process are concurrent (i.e. they are evaluated continuously and in parallel).
So if you do:
A <= "1111";
A <= A(2 DOWNTO 0) & B;
You'll be assigning every bit of A with two drivers - a '1', and the bit on the left of it except for the least significant bit which gets assigned 'B'. Imagine constructing this with actual copper wires. You are tying all bits of A together - AND tying them to the positive voltage source.
If B is '1' this should resolve to all '1', but if B is '0' you will effectively connect the positive and negative voltage terminals, like a short circuit. Your simulator will tell you the result is 'X' - unknown.

VHDL - custom shifter - concatenation input (in defined range) and remaining zeros

I am trying to write my own shifter. It all doesn't matter about the shifter, so please don't recommend me to do shifter by different way. The shifter is here only for demonstration my problem that I've reached.
Here is a piece of shifter description:
1: with operand_b select result <=
2: operand_a when "0000",
3: operand_a(14 downto 0) & '0' when "0001",
4: operand_a(13 downto 0) & "00" when "0010",
5: operand_a(12 downto 0) & "000" when "0011",
6: operand_a(11 downto 0) & "0000" when "0100",
7: operand_a(10 downto 0) & "00000" when "0101",
8: operand_a(9 downto 0) & "000000" when "0110",
9: operand_a(8 downto 0) & "0000000" when "0111",
10: operand_a(7 downto 0) & "00000000" when "1000",
11: operand_a(6 downto 0) & "000000000" when "1001",
12: operand_a(5 downto 0) & "0000000000" when "1010",
13: operand_a(4 downto 0) & "00000000000" when "1011",
14: operand_a(3 downto 0) & "000000000000" when "1100",
15: operand_a(2 downto 0) & "0000000000000" when "1101",
16: operand_a(1 downto 0) & "00000000000000" when "1110",
17: operand_a(0) & "000000000000000" when others;
Where operand_b is value used to be shifted by, result is output of the shifter.
As you can see, it is quite bottlenecking. What will happen when we have for instance 64 bit shifter - a lot of useless zeros. I was finding a lot on web how to write that more rationally, but every solution that I tried, like operand_a(13 downto 0) & (others => '0') when "0010" or (15 downto 2 => operand_a(13 downto 0), others => '0') when "0010" or (operand_a(13 downto 0), others => '0') when "0010" doesn't work. Everytime I got a report with some error.
Any solutions, please?
Sorry for my English.
EDIT:
When I replace operand_a(13 downto 0) & "00" when "0010", on the 4th line with:
operand_a(13 downto 0) & (others => '0') when "0010", it returns
Can not determine the "others" values in aggregate. (<= also for line 17)
Size of concat operation is different than size of the target.
(15 downto 2 => operand_a(13 downto 0), others => '0') when "0010", it returns
The type of the element in aggregate does not correspond to any array type.
(operand_a(13 downto 0), others => '0') when "0010", it returns
No array or record type can be found that has elements of types matching the aggregate.
operand_a(13 downto 0) & (1 downto 0 => '0') when "0010",
This one is working, but isn't here any way to use others?
Value expressions such as (operand_a(13 downto 0), others => '0') should work in IEEE Std 1076-2008.
Compare 9.3.3.3 Array aggregates, para 1 and 2:
For an aggregate of a one-dimensional array type, each choice shall specify values of the index type, and the expression of each element association shall be of either the element type or the type of the aggregate. If the type of the expression of an element association is the type of the aggregate, then either the element association shall be positional or the choice shall be a discrete range.
For an element association with a choice that is a discrete range and an expression of the element type of the aggregate, the value of the expression is the element at each index value in the range.
to IEEE Std 1076-1993 Array aggregates para 1:
For an aggregate of a one-dimensional array type, each choice must specify values of the index type, and the expression of each element association must be of the element type. An aggregate of an n-dimensional array type, where n is greater than 1, is written as a one-dimensional aggregate in which the index subtype of the aggregate is given by the first index position of the array type, and the expression specified for each element association is an (n-1)-dimensional array or array aggregate, which is called a subaggregate. A string or bit string literal is allowed as a subaggregate in the place of any aggregate of a one-dimensional array of a character type.
In -2008 we are allowed to have association elements that are the type of the aggregate (a one-dimensional array type). This allows association of slice names of the same type.
At the same time -2008 9.3.3.3 para 7 allows the use of the others choice:
e) As a value expression in an assignment statement, where the target is a declared object (or member thereof), and either the subtype of the target is a fully constrained array subtype or the target is a slice name
(And the target being a slice name has been added from previous revisions.) The rules for where you can use the others choice require you have context that supplies a subtype constraint.
So it tells us the VHDL implementation you are using is not -2008 compatible (or is not being used as -2008 compatible).
This feature is one of generally low priority for implementation in upgrading to -2008 compatibility.
Should you find your VHDL tool lacking support there are other ways to express your shifter such as:
SHIFTER:
process (operand_b, operand_a)
variable b: integer range 0 to operand_a'HIGH;
begin
result <= (others => '0');
if not is_x(operand_b) then -- culling meta-values
b := to_integer(unsigned(operand_b));
for i in result'range loop
if i = b then
result(result'high downto i) <=
operand_a (operand_a'high - i downto 0);
end if;
end loop;
end if;
end process;
This process is synthesis eligible, because the slice ranges depend on static values including the loop constant, loops are unrolled or parallelized for synthesis. There is an assignment statement for each binary value of operand_b and you rely on optimization in synthesis (which does amazingly well for things like multiplexers and shifters).
This method works by writing all of result as '0's then writing the portions of operand_a desired to result. It depends on sequential assignment inside the same process (and can be used with a sequential conditional signal assignment in a -2008 compatible implementation) and with if statement or a case statement. (But not a selected signal assignment which depends on same left hand side target).
The two assignment statements being executed in one process depends on there being a single driver and is supported by synthesis. The last written array element values overwrite earlier array element value writes, there is only one time slot for any particular simulation time in a projected output waveform.

synthesis of dynamic mux on std_logic_vector bytes

I have a FIFO who's size is determined according to a parameter in the package:
signal fifo : std_logic_vector(FIFO_SIZE*8 -1 downto 0);
I also have a 4 bit vector (numOfBytes) saying how many bytes are in the FIFO at any given time (up to 8).
I want the data out (a single byte) from the FIFO to be determined according the numOfBytes signal:
Do <= fifo(to_integer(unsigned(numOfBytes)*8 -1 downto to_integer(unsigned(numOfBytes)*8 -8) when numOfBytes /= x"0" else (others => '0');
when simulating, this works well, however when I try to synthesis it (using Synopsys DC) I get an elaboration error upon linking the design saying "Constant value required (ELAB-922)".
The ELAB code means "This error message occurs because an expression in the indicated line of your RTL description does not evaluate to a constant value, as required by the language."
How else can I make the output mux so it will undergo synthesis?
if not for the parameter i'd change the Do line to a regular mux, but it can't work with the parameters. (I can't call fifo(63 downto 54) when fifo is 4 byte...)
p.s.
I tried working with conv_integer in the beginning, but changed to to_integer(unsigned())due to answers found on the web.
Signal indexes used to construct a range have to be compile-time constants for synthesis to accept them.
There are two ways to solve this problem:
1) Change your FIFO to use an array. This is the standard way of declaring any form of memory, such as a FIFO.
type fifo_type is array(0 to FIFO_SIZE-1) of std_logic_vector(8-1 downto 0);
signal fifo : fifo_type;
...
Do <= fifo(to_integer(unsigned(numOfBytes))-1) when(numOfBytes/=0) else (others=>'0');
2) Use a loop to convert the variable into a constant. This is a common way to code a generic mux.
Do <= (others=>'0');
for i in 0 to FIFO_SIZE-1 loop
if(numOfBytes=i+1) then
Do <= fifo((i+1)*8-1 downto i*8);
end if;
end loop;
I would recommend the first approach for larger, memory-based FIFOs, and the second for smaller, register-based ones.
If the FIFO created with a number of bytes, instead of combining it into the same std_logic_vector then Synopsys DC may be able to handle it. Code could look like:
library ieee;
use ieee.numeric_std.all;
architecture syn of mdl is
... Declaration of FIFO_SIZE natural constant
type fifo_t is array(natural range <>) of std_logic_vector(7 downto 0);
signal fifo : fifo_t(FIFO_SIZE - 1 downto 0);
begin
... Handling FIFO insert and remove
Do <= fifo(to_integer(unsigned(numOfBytes))) when numOfBytes /= x"0" else (others => '0');
end architecture;
If you don't need a runtime-dynamic size to the FIFO, use a generic on your entity.
If you truly need a dynamic sized FIFO, you'll have to use a loop in a process as someone else said. But be very careful how you use such a FIFO, as if you change the size of it while someone is reading or writing, bad things may happen!

Vhdl vector boundry check

type dmemSpace is array(0 to 1023) of std_logic_vector(31 downto 0);
signal dataMem : dmemSpace := (
400 => X"00000000",
404 => X"00001000",
408 => X"FFFFEFFF",
others => X"00000000"
);
signal dAddr : std_logic_vector(31 downto 0);
signal check : integer;
dAddr(31 downto 0) <= Addr(31 downto 2) & "00";
check <= to_integer(unsigned(dAddr));
DataOut <= dataMem(to_integer(unsigned(dAddr))) when (check > 0);
Its me again.... In working on a single cycle cpu and everything else works fine but this particular line in the memory.
DataOut <= dataMem(to_integer(unsigned(dAddr))) when (check > 0);
I want to prevent an index out of bounds error for DataOut but this doesn't work. Any ideas?
Check > 0 prevents all data from coming out.
Check >= 0 lets the error through... when the index that causes the exception is -4.
If you have it in a process, you need "dAddr" and "check" to be variables, or else you are taking two clock cycles based on whether or not the previous address was valid, not the one you are using.
If your memory has 1024 locations, your address should be 10 bits, not the 32 bits you have now. If your address is unsigned(9 downto 0), all of its values are legal input for your memory array.
Note you put data at address 400, 404, 408. You are leaving three blank spaces in between each data element! Even though your data is 4 bytes wide, every address takes up an entire 4 byte data word.
A few other problems with this attempt and the provided answers:
You could not have applied index of -4. Your dAddr is type std_logic_vector cast to UNSIGNED. So it is always a positive or ZERO.
Using VARIABLES is a solution if you are just SIMULATING. For SYNTHESIS they still need to be SIGNALS if you want to know what the implementation is doing.
Your memory is Read only. If you want to have read/write memory you will want to have this in a clocked process so you generate REGISTERS instead of LATCHES.
I dont know WHAT you're doing with the array partial assignment in the declaration. Yes it is syntatically correct, but assignment at declaration DOES NOT APPLY TO SYNTHESIZED logic. This really only works for CONSTANTS (in all fairness, that is what your dataMem signal is.... a constant.)
To initialize the memory you need it in the RESET block of your clocked process, use a for loop to set all to x"00", followed by the 3 assignments for 400, 404, 408 using [dataMem(404) <= x"08";]
Assign DataOut EVERY clock
if (check < 1024) then
DataOut <= dataMem(check);
else
DataOut <= (others => "0"); -- maybe? or just retain old value?
end if;

Resources