Variable std_logic_vector or array entry in vhdl - aes

I'm currently working on AES encryption using keys of three different sizes (128,192, and 256 bit).
I was wondering if I can declare / use a std_logic_vector of a variable size? For example, can I just have one input port and I get to know wether it's 128,192, or 256 bit based on the user input?
Or else if I choose the max key length, which is 256 bit, can I assign a 128 or 192 bit key to that std_logic_vector? Or will an error message appear?

If the size of key changes at run-time, you will have to declare
the corresponding objects (signals, constants, variables) with the
maximum possible size. The actual key length will then be defined by another
signal or variable. The maximum size may be defined as below.
If you declare an object of type std_logic_vector with the maximum possible size, then assigning a shorter std_logic_vector will result in an error. You will have to extend the right-hand aside of the assignment to the size of the target object first, e.g. using the following resize function from the PoC Library where I'm one of the authors:
function resize(vec : std_logic_vector; length : natural; fill : std_logic := '0') return std_logic_vector is
constant high2b : natural := vec'low+length-1;
constant highcp : natural := imin(vec'high, high2b);
variable res_up : std_logic_vector(vec'low to high2b);
variable res_dn : std_logic_vector(high2b downto vec'low);
begin
if vec'ascending then
res_up := (others => fill);
res_up(vec'low to highcp) := vec(vec'low to highcp);
return res_up;
else
res_dn := (others => fill);
res_dn(highcp downto vec'low) := vec(highcp downto vec'low);
return res_dn;
end if;
end function;
For example, given a 128-bit std_logic_vector named source, this can be re-sized to 256 bit with:
resize(source, 256) -- returns a 256-bit std_logic_vector
The function works like the resize function on unsigned and signed from package numeric_std.
If the key size is known at compile (elaboraton) time, then you will
have two options. A usual approach is to define the key size by a
constant and passing the key size via generics to sub-components.
The following entity test has a generic SIZE specifying the key
size. The length of ports as well as other objects, can now be defined
depending on this generic.
library ieee;
use ieee.std_logic_1164.all;
entity test is
generic (
SIZE : positive := 128); -- the default value can be omitted
port (
x : in std_logic_vector(SIZE-1 downto 0);
y : out std_logic_vector(SIZE-1 downto 0));
end entity test;
architecture rtl of test is
begin -- architecture rtl
y <= not x;
end architecture rtl;
The generic can now be bound during the instantiation of this entity,
for example:
library ieee;
use ieee.std_logic_1164.all;
entity test_tb is
end entity test_tb;
architecture rtl of test_tb is
constant SIZE : positive := 192;
signal x : std_logic_vector(SIZE-1 downto 0) := (others => '0');
signal y : std_logic_vector(SIZE-1 downto 0);
begin -- architecture rtl
dut: entity work.test
generic map (
SIZE => SIZE)
port map (
x => x,
y => y);
end architecture rtl;
Of course, the length of the actuals (right side in port map) must
match the length of the formals (left side in port map). This approach
is supported by all (major) VHDL synthesis tools. If default values
for the generics are present, then test can be directly synthesized as
top-level module.
The second option, for a fixed key-size during elaboration, would be
to use unconstrained arrays (std_logic_vector) in the port
declaration of the entity. The actual size of the array can be
determined with the length atribute, and the actual range with the
range attribute, for example:
library ieee;
use ieee.std_logic_1164.all;
entity test2 is
port (
x : in std_logic_vector;
y : out std_logic_vector);
end entity test2;
architecture rtl of test2 is
signal z : std_logic_vector(x'range);
begin -- architecture rtl
z <= x;
y <= not z;
assert false report "x'length=" & integer'image(x'length) severity note;
end architecture rtl;
The range (and length) of the port signals will then be
constrained by the associated actual in the component instantiation.
library ieee;
use ieee.std_logic_1164.all;
entity test2_tb is
end entity test2_tb;
architecture rtl of test2_tb is
constant SIZE : positive := 192;
signal x : std_logic_vector(SIZE-1 downto 0) := (others => '0');
signal y : std_logic_vector(SIZE-1 downto 0);
begin -- architecture rtl
dut: entity work.test2
port map (
x => x,
y => y);
end architecture rtl;
This works in simulation. But, I'm not sure whether it is supported by
the (major) VHDL synthesis tools. Of course, for synthesis of test2
another top-level entity is required which instantiates test2 to
constraint the array ranges.

Related

"operator symbol not allowed for generic subprogram" from Ada

I want to make subprogram for adding array's elements with Ada.
subprogram "Add_Data" have 3 parameters-
first parameter = generic type array (array of INTEGER or array of REAL)
second parameter = INTEGER (size of array)
third parameter = generic type sum (array of INTEGER -> sum will be INTEGER, array of REAL -> sum will be REAL)
I programmed it from ideone.com.
(I want to see just result by array of INTEGER. After that, I will test by array of REAL)
With Ada.Text_IO; Use Ada.Text_IO;
With Ada.Integer_Text_IO; Use Ada.Integer_Text_IO;
procedure test is
generic
type T is private;
type Tarr is array (INTEGER range <>) of T;
--function "+" (A,B : T) return T;
--function "+" (A, B : T) return T is
--begin
-- return (A+B);
--end "+";
procedure Add_Data(X : in Tarr; Y : in INTEGER; Z : in out T);
procedure Add_Data(X : in Tarr; Y : in INTEGER; Z : in out T) is
temp : T;
count : INTEGER;
begin
count := 1;
loop
temp :=temp+ X(count); //<-This is problem.
count := count + 1;
if count > Y then
exit;
end if;
end loop;
Z:=temp;
end Add_Data;
type intArray is array (INTEGER range <>) of INTEGER;
intArr : intArray := (1=>2, 2=>10, 3=>20, 4=>30, 5=>8);
sum : INTEGER;
procedure intAdd is new Add_Data(Tarr=>intArray, T=>INTEGER);
begin
sum := 0;
intAdd(intArr, 5, sum);
put (sum);
end test;
when I don't overload operator "+", It makes error.
"There is no applicable operator "+" for private type "T" defined."
What can I do for this?
If a generic’s formal type is private, then nothing in the generic can assume anything about the type except that it can be assigned (:=) and that it can be compared for equality (=) and inequality (/=). In particular, no other operators (e.g. +) are available in the generic unless you provide them.
The way to do that is
generic
type T is private;
with function "+" (L, R : T) return T is <>;
This tells the compiler that (a) there is a function "+" which takes two T’s and returns a T; and (b) if the actual T has an operator "+" which matches that profile, to allow it as the default.
So, you could say
procedure intAdd is new Add_Data (T => Integer, ...
or, if you didn’t feel like using the default,
procedure intAdd is new Add_Data (T => Integer, "+" => "+", ...
In addition to not knowing how to declare a generic formal subprogram (Wright has shown how to do this for functions), your code has a number of other issues that, if addressed, might help you move from someone who thinks in another language and translates it into Ada into someone who actually uses Ada. Presuming that you want to become such a person, I will point some of these out.
You declare your array types using Integer range <>. It's more common in Ada to use Positive range <>, because people usually refer to positions starting from 1: 1st, 2nd, 3rd, ...
Generics are used for code reuse, and in real life, such code is often used by people other than the original author. It is good practice not to make unstated assumptions about the values clients will pass to your operations. You assume that, for Y > 0, for all I in 1 .. Y => I in X'range and for Y < 1, 1 in X'range. While this is true for the values you use, it's unlikely to be true for all uses of the procedure. For example, when an array is used as a sequence, as it is here, the indices are immaterial, so it's more natural to write your array aggreate as (2, 10, 20, 30, 8). If I do that, Intarr'First = Integer'First and Intarr'Last = Integer'First + 4, both of which are negative. Attempting to index this with 1 will raise Constraint_Error.
Y is declared as Integer, which means that zero and negative values are acceptable. What does it mean to pass -12 to Y? Ada's subtypes help here; if you declare Y as Positive, trying to pass non-positive values to it will fail.
Z is declared mode in out, but the input value is not referenced. This would be better as mode out.
Y is not needed. Ada has real arrays; they carry their bounds around with them as X'First, X'Last, and X'Length. Trying to index an array outside its bounds is an error (no buffer overflow vulnerabilities are possible). The usual way to iterate over an array is with the 'range attribute:
for I in X'range loop
This ensures that I is always a valid index into X.
Temp is not initialized, so it will normally be initialized to "stack junk". You should expect to get different results for different calls with the same inputs.
Instead of
if count > Y then
exit;
end if;
it's more usual to write exit when Count > Y;
Since your procedure produces a single, scalar output, it would be more natural for it to be a function:
generic -- Sum
type T is private;
Zero : T;
type T_List is array (Positive range <>) of T;
with function "+" (Left : T; Right : T) return T is <>;
function Sum (X : T_List) return T;
function Sum (X : T_List) return T is
Result : T := Zero;
begin -- Sum
Add_All : for I in X'range loop
Result := Result + X (I);
end loop Add_All;
return Result;
end Sum;
HTH

Average value of input Data in Mitsubishi GX Works 2

I need to obtain an average value of my input signals from mitsubishi input module Q64AD. I'm working in GX Works 2 in structured text.
This is how i used to obtain average value in Codesys:
timer_sr(IN:= NOT timer_sr.Q , PT:= T#5s );
SUM1:= SUM1 + napr1;
Nsum:=Nsum + 1;
IF timer_sr.Q THEN
timer_sr(IN:= NOT timer_sr.Q , PT:= T#5s);
outsr := SUM1 /Nsum;
Nsum := 0;
SUM1 := 0;
END_IF;
napr1 - is value from module
This piece of code is not working in GX Works 2, and i think because SUM1 is not an INT data type, but just a Word[signed] type.
Is there a way to make SUM1 an INT type or may be there is another logic to that solution?
In other platforms it should work but the compiler gives a warning so I guess it will still compile? Of course, if the value is negative there will be problems.
You can convert a WORD to INT by the IEC function WORD_TO_INT. I'm not sure how well your system follows the standard but if it does, try the following:
WORD_TO_INT(SUM1). If the SUM1 > 65535 then there will be problems as the upper bound of INTis 32767.
If this doesn't help, could you provide more details? How is it not workin?
Ps. The WORD is unsigned data type, not signed as you wrote.

How to customize the output of the Postgres Pseudo Encrypt function?

I would like to use the pseudo_encrypt function mentioned a few times on StackOverflow to make my IDs look more random: https://wiki.postgresql.org/wiki/Pseudo_encrypt
How can I customize this to output unique "random" numbers for just me. I read somewhere that you can just change the 1366.0 constant, but I don't want to take any risks with my IDs as any potential ID duplicates would cause major issues.
I really have no idea what each constant actually does, so I don't want to mess around with it unless I get some direction. Does anyone know which constants I can safely change?
Here it is:
CREATE OR REPLACE FUNCTION "pseudo_encrypt"("VALUE" int) RETURNS int IMMUTABLE STRICT AS $function_pseudo_encrypt$
DECLARE
l1 int;
l2 int;
r1 int;
r2 int;
i int:=0;
BEGIN
l1:= ("VALUE" >> 16) & 65535;
r1:= "VALUE" & 65535;
WHILE i < 3 LOOP
l2 := r1;
r2 := l1 # ((((1366.0 * r1 + 150889) % 714025) / 714025.0) * 32767)::int;
r1 := l2;
l1 := r2;
i := i + 1;
END LOOP;
RETURN ((l1::int << 16) + r1);
END;
$function_pseudo_encrypt$ LANGUAGE plpgsql;
for bigint's
CREATE OR REPLACE FUNCTION "pseudo_encrypt"("VALUE" bigint) RETURNS bigint IMMUTABLE STRICT AS $function_pseudo_encrypt$
DECLARE
l1 bigint;
l2 bigint;
r1 bigint;
r2 bigint;
i int:=0;
BEGIN
l1:= ("VALUE" >> 32) & 4294967295::bigint;
r1:= "VALUE" & 4294967295;
WHILE i < 3 LOOP
l2 := r1;
r2 := l1 # ((((1366.0 * r1 + 150889) % 714025) / 714025.0) * 32767*32767)::bigint;
r1 := l2;
l1 := r2;
i := i + 1;
END LOOP;
RETURN ((l1::bigint << 32) + r1);
END;
$function_pseudo_encrypt$ LANGUAGE plpgsql;
Alternative solution: use different ciphers
Other cipher functions are now available on postgres wiki. They're going to be significantly slower, but aside from that, they're better candidates for generating customized random-looking series of unique numbers.
For 32 bit outputs, Skip32 in plpgsql will encrypt its input with a 10 bytes wide key, so you just have to choose your own secret key to have your own specific permutation (the particular order in which the 2^32 unique values will come out).
For 64 bit outputs, XTEA in plpgsql will do similarly, but using a 16 bytes wide key.
Otherwise, to just customize pseudo_encrypt, see below:
Explanations about pseudo_encrypt's implementation:
This function has 3 properties
global unicity of the output values
reversability
pseudo-random effect
The first and second property come from the Feistel Network, and as already explained in #CodesInChaos's answer, they don't depend on the choice of these constants: 1366 and also 150889 and 714025.
Make sure when changing f(r1) that it stays a function in the mathematical sense, that is x=y implies f(x)=f(y), or in other words the same input must always produce the same output. Breaking this would break the unicity.
The purpose of these constants and this formula for f(r1) is to produce a reasonably good pseudo-random effect. Using postgres built-in random() or similar method is not possible because it's not a mathematical function as described above.
Why these arbitrary constants? In this part of the function:
r2 := l1 # ((((1366.0 * r1 + 150889) % 714025) / 714025.0) * 32767)::int;
The formula and the values 1366, 150889 and 714025 come from Numerical recipes in C (1992, by William H.Press, 2nd ed.), chapter 7: random numbers, specifically p.284 and 285.
The book is not directly indexable on the web but readable through an interface here: http://apps.nrbook.com/c/index.html .It's also cited as a reference in various source code implementing PRNGs.
Among the algorithms discussed in this chapter, the one used above is very simple and relatively effective. The formula to get a new random number from a previous one (jran) is:
jran = (jran * ia + ic) % im;
ran = (float) jran / (float) im; /* normalize into the 0..1 range */
where jran is the current random integer.
This generator will necessarily loop over itself after a certain number of values (the "period"), so the constants ia, ic and im have to be chosen carefully for that period to be as large as possible. The book provides a table p.285 where constants are suggested for various lengths of the period.
ia=1366, ic=150889 and im=714025 is one of the entries for a period of
229 bits, which is way more than needed.
Finally the multiplication by 32767 or 215-1 is not part of the PRNG but meant to produce a positive half-integer from the 0..1 pseudo-random float value. Don't change that part, unless to widen the blocksize of the algorithm.
This function looks like a blockcipher based on a Feistel network - but it's lacking a key.
The Feistel construction is bijective, i.e. it guarantees that there are no collisions. The interesting part is: r2 := l1 # f(r1). As long as f(r1) only depends on r1 the pseudo_encrypt will be bijective, no matter what the function does.
The lack of key means that anybody who knows the source code can recover the sequential ID. So you're relying on security-though-obscurity.
The alternative is using a block cipher which takes a key. For 32 bit blocks there are relatively few choices, I know of Skip32 and ipcrypt. For 64 bit blocks there are many ciphers to choose from, including 3DES, Blowfish and XTEA.

VHDL writing std_logic_vector as a signed integer in file

I wonder how to write a std_logic_vector as a signed integer in VHDL testbench?
Using numeric_std:
signal test_in : std_logic_vector(2 downto 0);
signal test_out : integer range -4 to 3;
test_out <= to_integer(signed(test_in));
You need to convert to an integer (using the use ieee.numeric_std.all;, which means you need to know if your std_logic_vector is representing a signed or unsigned number. Ideally, you'd use the relevant type rather than the bag-of-bits that std-logic_vector is.
Converting to an integer is as straightforward as:
int_variable := to_integer(some_vector);
If you must stick to a std_logic_vector you'll have to tell the compiler whether it is unsigned or signed like this:
int_variable := to_integer(unsigned(some_vector));
or this:
int_variable := to_integer(signed(some_vector));
Then you can write you integer to the file as you normally would.

Variable number of "in" ports in an entity?

I am trying to simulate a destination control lift controller with n floors and m lifts. So from every floor, the user can enter a destination floor to go and gets a lift number in return. So to simulate this kind of lift controller, I need to have variable in ports (which would be equal to the number of floors), each of type integer. I tried searching on google but could not find anything useful. Can someone suggest me how we can do the above ?
Thanks in advance.
In VHDL you can use unconstrained arrays as ports:
entity myDevice is
port ( floors : in std_logic_vector;
lifts : in std_logic_vector
);
end entity myDevice;
The size of the port is the determined during elaboration by the size of the connected signal. If you need to know the size of the port in your architecture, you simply use the 'length, 'range or any other appropriate attribute:
architecture RTL of myDevice is
begin
pr_control : process(all) is
begin
-- Code, code, code...
for n in lifts'range loop
process_lift(n);
end loop;
-- More code ...
end process pr_controll;
end architecture RTL;
You can always do something like this:
entity controller is generic (
N : integer;
M : integer
); port (
Floors : in std_logic_vector(N-1 downto 0);
Lifts : in std_logic_vector(M-1 downto 0)
);
end controller;
You can find some more examples of this here.
Or perhaps:
package foo is
type integer_array is array (integer range <>) of integer;
end package;
entity controller is generic (
N : integer;
M : integer
); port (
Floors : in foo.integer_array(N-1 downto 0);
Lifts : in foo.integer_array(M-1 downto 0)
);
end controller;