VHDL 2D Array Initialization using single Index - multidimensional-array

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

Related

Why is array'First always 1 in this example?

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;

Ada: Flatten Record to Byte array

I have a record made of smaller types, a total of 16 bits in size.
type Type_1 is (val1, val2, val3, val4, val5, val6, val7, val8);
for Type_1 use (val1 => 0, val2 = 1, val3 = 2, val4 => 3
val5 => 4, val6 => 5, val7 => 6, val8 => 7);
for Type_1'Size use 3;
type Type_2 is (val1, val2);
for Type_2 use (val1 => 0, val2 = 1);
for Type_2'Size use 1;
etc, etc
type The_Record is record
element_1 : Type_1;
element_2 : Type_2;
element_3 : Type_3;
element_4 : Type_4;
end record;
for the_Record use record
element_1 at 0 range 0 .. 2;
element_2 at 0 range 3 .. 4;
element_3 at 0 range 5 .. 12;
element_4 at 0 range 13 .. 15;
end record;
for The_Record'Size use 16;
How can I flatten 'The_Record' into an array of bytes or something similar?
Thank you!
You can always use Unchecked_conversion, however, this approach is unchecked and you are therefore telling the compiler (a) that you know what you're doing, and (b) that it cannot help you [otherwise it would be named checked_conversion].
Another way that you can do the conversion is with overlaying, this is my preferred approach (if it is not a simple type-renaming issue) as if things change then the conversion-function can be modified as needed.
-- Subtype-renaming.
Subtype Byte is Interfaces.Unsigned_8;
-- General type for conversion to a collection of bytes.
Type Byte_Array is Array (Positive Range <>) of Byte;
-- Speciffic collection of bytes from The_Record.
Subtype Record_Bytes is Byte_Array(1..The_Record'Size/Byte'Size);
-- Converting record to bytes...
Function Convert( Input : The_Record ) return Record_Bytes is
Result : Constant Record_Bytes;
For Result'Address use Input'Address;
Pragma Import( Convention => Ada, Entity => Result );
begin
Return Result;
end Convert;
-- Converting bytes to record... in Ada 2012!
Function Convert( Input : Record_Bytes ) return The_Record is
Result : The_Record with
Import, Convention => Ada, Address => Input'Address;
begin
Return Result;
end Convert;
Another, and probably better, way (if you are trying for serialization. as I suspect) of doing this would be to create read/write functions and override the default 'read and 'write attributes.
This in an example of how to use the Unchecked Conversion way:
with Ada.Unchecked_Conversion;
with Ada.Text_Io;
procedure Uc is
type The_Record is record
A : Integer;
B : Integer;
end record;
-- define a byte sized thing...
type U8 is mod 2**8;
for U8'Size use 8;
-- have your array defined according to
-- the size of the record it needs to hold
type U8_Record_Array is array (1 .. The_Record'Size / U8'Size) of U8;
-- instantiate Unchecked_Conversion
function To_Array is new Ada.Unchecked_Conversion (Source => The_Record,
Target => U8_Record_Array);
-- Declare a record and convert it to an array
R : constant The_Record := (A => 1, B => 2);
A : constant U8_Record_Array := To_Array (R);
begin
-- Print the Array As Bytes
for I in A'Range loop
Ada.Text_Io.Put (U8'Image (A(I)));
end loop;
end Uc;
Depending on Exactly what you are intending to do, Both the Overlay & Unchecked Conversion ways will have pros & cons associated with them :)

VHDL - determining the range of a 2d array

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...

Pascal. Recursive function to count amount of odd numbers in the sequence

I need to write recursive function to count amount of odd numbers in the sequence
Here my initial code:
program OddNumbers;
{$APPTYPE CONSOLE}
uses
SysUtils;
function GetOddNumbersAmount(const x: array of integer; count,i:integer):integer;
begin
if((x[i] <> 0) and (x[i] mod 2=0)) then
begin
count:= count + 1;
GetOddNumbersAmount:=count;
end;
i:=i+1;
GetOddNumbersAmount:=GetOddNumbersAmount(x, count, i);
end;
var X: array[1..10] of integer;
i,amount: integer;
begin
writeln('Enter your sequence:');
for i:=1 to 10 do
read(X[i]);
amount:= GetOddNumbersAmount(X, 0, 1);
writeln('Amount of odd numbers: ', amount);
readln;
readln;
end.
When i type the sequence and press "enter", program closed without any errors and i can't see the result.
Also, i think my function isn't correct.
Can someone help with that code?
UPD:
function GetOddNumbersAmount(const x: array of integer; count,i:integer):integer;
begin
if((x[i] <> 0) and (x[i] mod 2<>0)) then
count:= count + 1;
if(i = 10) then
GetOddNumbersAmount:=count
else
GetOddNumbersAmount:=GetOddNumbersAmount(x, count, i+1);
end;
You don't provide an end of recursion, i.e., you always call your function GetOddNumbersAmount again, and your program never terminates. Thus, you get an array index error (or a stack overflow) and your program crashes.
Please note, that every recursion need a case where it terminates, i.e. does not call itself. In your case, it should return if there are no elements in the array left.
In addition, you are counting the even numbers, not the odd ones.
You passed a static array to a dynamic so the index get confused:
Allocat the array with
SetLength(X,10)
allocates an array of 10 integers, indexed 0 to 9.
Dynamic arrays are always integer-indexed, always starting from 0!
SetLength(X,10)
for it:=0 to 9 do begin
X[it]:= random(100);
And second if you know the length a loop has more advantages:
function GetEvenNumbersAmount(const x: array of integer; count,i:integer):integer;
begin
for i:= 0 to length(X)-1 do
if((x[i] <> 0) and (x[i] mod 2=0)) then begin
inc(count);
//write(inttostr(X[i-1])+ ' ') :debug
end;
result:=count;
end;

Is overflow defined for VHDL numeric_std signed/unsigned

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.

Resources