I have two 2D arrays:
type array1x1D is array (0 to 10) of std_logic_vector(0 to 10); -- Array of arrays
type array2D is array (0 to 10, 0 to 10) of std_logic; -- Real 2D array
How do I access the range of the std_logic_vectors in the former and the range in the latter? I could of course use a variable to keep track of their size but I would prefer to avoid that. I am trying to loop over the arrays using GENERATE statements.
array1x1D:
VHDL-2002: A subtype is required for the std_logic_vector(0 downto 10) if you
want to get the range of this part, thus splitting the type into:
subtype array1x1D_element is std_logic_vector(0 to 10);
type array1x1D is array (0 to 10) of array1x1D_element; -- Array of arrays
Then you can do array1x1D_element'range.
VHDL-2008: Use the added 'element attribute (probably for that purpose :-),
and write array1x1D'element'range.
array2D:
Access the different dimensions through an index to 'range, thus
with array2D'range(1) and array2D'range(2).
entity test1 is
end entity;
library ieee;
use ieee.std_logic_1164.all;
architecture a1 of test1 is
type array1x1D is array (0 to 10) of std_logic_vector(0 to 10); -- Array of arrays
type array2D is array (0 to 10, 0 to 5) of std_logic; -- Real 2D array
signal s1 : array1x1D;
begin
name : process is
begin
report "array1x1D(0)'length:" & integer'image(s1(0)'length);
report "array2D'length(1):" & integer'image(array2D'length(1));
report "array2D'length(2):" & integer'image(array2D'length(2));
wait;
end process name;
end architecture a1;
produces:
# run -all
# ** Note: array1x1D(0)'length:11
# Time: 0 ns Iteration: 0 Instance: /test1
# ** Note: array2D'length(1):11
# Time: 0 ns Iteration: 0 Instance: /test1
# ** Note: array2D'length(2):6
# Time: 0 ns Iteration: 0 Instance: /test1
#
I can't immediately see a way to figure out the length of the vector elements of the 1d array without an intermediate signal/constant/variable of that type...
Related
I have a array of Nodes:
type NodeArray is array (Positive range 1 .. 5) of XNode;
The node has some data and an integer ID but thats not important right now.
The way I undestand it is that array'First (excuse the abuse of notation) always points or references the first item in a range or array, not the integer of the range type.
My question is why I always get 1 instead of the first entry in my array.
If you need to see more code I can provide it, I just thought I'd keep my example simple and short.
Your
type NodeArray is array (Positive range 1 .. 5) of XNode;
defines a constrained array type (ALRM 3.6(5)), whose first index will always be 1.
If you want to use one type to create array objects with different index ranges, you need an unconstrained array type (ALRM 3.6(3)) with bounds like Positive range <> (note 1, once you’ve created such an object, its bounds are fixed; note 2, instead of Positive you can use any scalar appropriate to the problem).
with Ada.Text_IO; use Ada.Text_IO;
procedure Zython is
type Unconstrained_Node_Array is array (Positive range <>) of Float;
subtype Constrained_Node_Array is Unconstrained_Node_Array (1 .. 5);
U : Unconstrained_Node_Array (42 .. 44); -- must include the index range
C : Constrained_Node_Array; -- the index range is 1 .. 5
begin
for J in U'Range loop
U (J) := Float (J) * 2.0;
end loop;
Put_Line ("U'First: "
& Positive'Image (U'First)
& ", U (U'First): "
& Float'Image (U (U'First)));
for J in C'Range loop
C (J) := Float (J) * 2.0;
end loop;
Put_Line ("C'First: "
& Positive'Image (C'First)
& ", C (C'First): "
& Float'Image (C (C'First)));
end Zython;
I have the following problem:
My code has this constant value
constant source_vector : std_logic_vector(7 downto 0) := "1011000";
This value needs to be fed into a signal of type std_logic_vector, bit by bit. The problem is that the destination vector has a size defined in a constant. For the test, I am using size 1.
constant k : integer := 1;
dest_vector : in std_logic_vector(k-1 downto 0);
When I try to assign the first bit:
dest_vector <= std_logic_vector(to_unsigned(source_vector(0), k));
I got this error:
ERROR: [VRFC 10-925] indexed name is not a natural
I have tried several things, but no luck. Perhaps I am missing something... Any advice here?
Answer from user1155120 Jul 16 '17 at 19:47
Use dest_vector <= source_vector(0 downto 0); which uses a slice name or dest_vector(0) <= source_vector(0); which uses indexed names for both target and right hand side. There's also dest_vector <= "" & source_vector(0); which derives the type of the concatenation result from context while concatenating a null array to a value of the element type. See IEEE Std 1076-2008 8.4 Indexed names, 8.5 Slice names, 9.2.5 Adding operators ("&") and 12.5 The context of overload resolution (which "&").
type kelvin_Array is array(0 to 3, 0 to 1) of integer
signal array_int1 :kelvin_Array;
signal array_int2 :kelvin_Array;
begin
array_int1 (0,0) <= 5; --using 2 indexes
what I wanted is
array_int1(0) <= (5,3);
Please let me know how can I achieve this.
Regards,
Kelvin
It looks like you want a single dimensional array of a single dimensional array of two integers, eg:
type matthew_Array is array(0 to 1) of integer;
type matthew_Array_Array is array(0 to 9) of matthew_Array;
signal array_int1 : matthew_Array_Array;
begin
array_int1(0) <= (5,3);
https://www.edaplayground.com/x/5Lz8
I'm trying to use the concept of recursion but using for do loop. However my program cannot do it. For example if I want the output for 4! the answer should be 24 but my output is 12. Can somebody please help me?
program pastYear;
var
n,i:integer;
function calculateFactorial ( A:integer):real;
begin
if A=0 then
calculateFactorial := 1.0
else
for i:= A downto 1 do
begin
j:= A-1;
calculateFactorial:= A*j;
end;
end;
begin
writeln( ' Please enter a number ');
readln ( n);
writeln ( calculateFactorial(n):2:2);
readln;
end.
There are several problems in your code.
First of all it doesn't compile because you are accessing the undefined variable j.
Calculating the factorial using a loop is the iterative way of doing it. You are looking for the recursive way.
What is a recursion? A recursive function calls itself. So in your case calculateFactorial needs a call to itself.
How is the factorial function declared?
In words:
The factorial of n is declared as
1 when n equals 0
the factorial of n-1 multiplied with n when n is greater than 0
So you see the definition of the factorial function is already recursive since it's referring to itself when n is greater than 0.
This can be adopted to Pascal code:
function Factorial(n: integer): integer;
begin
if n = 0 then
Result := 1
else if n > 0 then
Result := Factorial(n - 1) * n;
end;
No we can do a few optimizations:
The factorial function doesn't work with negative numbers. So we change the datatype from integer (which can represent negative numbers) to longword (which can represent only positive numbers).
The largest value that a longword can store is 4294967295 which is twice as big as a longint can store.
Now as we don't need to care about negative numbers we can reduce one if statement.
The result looks like this:
function Factorial(n: longword): longword;
begin
if n = 0 then
Result := 1
else
Result := Factorial(n - 1) * n;
end;
If I have an unsigned(MAX downto 0) containing the value 2**MAX - 1, do the VHDL (87|93|200X) standards define what happens when I increment it by one? (Or, similarly, when I decrement it by one from zero?)
Short answer:
There is no overflow handling, the overflow carry is simply lost. Thus the result is simply the integer result of your operation modulo 2^MAX.
Longer answer:
The numeric_std package is a standard package but it is not is the Core the VHDL standards (87,93,200X).
For reference : numeric_std.vhd
The + operator in the end calls the ADD_UNSIGNED (L, R : unsigned; C : std_logic) function (with C = '0'). Note that any integer/natural operand is first converted into an unsigned.
The function's definition is:
function ADD_UNSIGNED (L, R : unsigned; C : std_logic) return unsigned is
constant L_left : integer := L'length-1;
alias XL : unsigned(L_left downto 0) is L;
alias XR : unsigned(L_left downto 0) is R;
variable RESULT : unsigned(L_left downto 0);
variable CBIT : std_logic := C;
begin
for i in 0 to L_left loop
RESULT(i) := CBIT xor XL(i) xor XR(i);
CBIT := (CBIT and XL(i)) or (CBIT and XR(i)) or (XL(i) and XR(i));
end loop;
return RESULT;
end ADD_UNSIGNED;
As you can see an "overflow" occurs if CBIT='1' (carry bit) for i = L_left. The result bit RESULT(i) is calculated normally and the last carry bot value is ignored.
I've had the problem with wanting an unsigned to overflow/underflow as in C or in Verilog and here is what I came up with (result and delta are unsigned):
result <= unsigned(std_logic_vector(resize(('1' & result) - delta, result'length))); -- proper underflow
result <= unsigned(std_logic_vector(resize(('0' & result) + delta, result'length))); -- proper overflow
For overflow '0' & result makes an unsigned which is 1 bit larger to be able to correctly accommodate the value of the addition. The MSB is then removed by the resize command which yields the correct overflow value. Same for underflow.
For a value of MAX equal to 7 adding 1 to 2**7 - 1 (127) will result in the value 2**7 (128).
The maximum unsigned value is determined by the length of an unsigned array type:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity foo is
end entity;
architecture faa of foo is
constant MAX: natural := 7;
signal somename: unsigned (MAX downto 0) := (others => '1');
begin
UNLABELED:
process
begin
report "somename'length = " & integer'image(somename'length);
report "somename maximum value = " &integer'image(to_integer(somename));
wait;
end process;
end architecture;
The aggregate (others => '1') represents a '1' in each element of somename which is an unsigned array type and represents the maximum binary value possible.
This gives:
foo.vhdl:15:9:#0ms:(report note): somename'length = 8
foo.vhdl:16:9:#0ms:(report note): somename maximum value = 255
The length is 8 and the numerical value range representable by the unsigned array type is from 0 to 2**8 - 1 (255), the maximum possible value is greater than 2**7 (128) and there is no overflow.
This was noticed in a newer question VHDL modulo 2^32 addition. In the context of your accepted answer it assumes you meant length instead of the leftmost value.
The decrement from zero case does result in a value of 2**8 - 1 (255) (MAX = 7). An underflow or an overflow depending on your math religion.
Hat tip to Jonathan Drolet for pointing this out in the linked newer question.