VHDL Synthesizable Vector Compare - vector

I am currently programming an ALU in VHDL and I am using a Cyclone II board. I need to compare two std_logic_vectors to see if one is greater than another. I used the greater than (>) in the condition but I don't know if the FPGA can synthesize that operator. Is there a workaround to compare two vectors without using ">" and synthesize it?

An MCVE would be helpful. However, what you are trying to do is both possible in simulation and in synthesis. What isn't clear from your question is what the format of the vectors are. Are they signed? Unsigned? Two's complement? Floating point? Sign magnitude?
However, assume the two vectors are signed, 2's complement numbers. One example:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity foo is
port
(
a : in std_logic_vector(31 downto 0);
b : in std_logic_vector(31 downto 0);
y : out std_logic
);
end entity foo;
architecture rtl of foo is
signal a_signed : signed(a'range);
signal b_signed : signed(b'range);
begin
a_signed <= signed(a);
b_signed <= signed(b);
y <= '1' when (a_signed > b_signed) else '0';
end architecture rtl;
And there are other solutions as well. And other implementations for different formats.

The datatype std_logic_vector is just a set of bits (with 9 values ...), but it doesn't define any arithmetic behavior.
To use arithmetic operations like addition, multiplication or comparisons like your intended "greater than", you need another datatype for example UNSIGNED or SIGNED. These types define additional arithmetic operations. So when you declare your signals as (UN)SIGNED, VHDL will know the additional operators and a synthesizer will infer the correct hardware.
-- declare the signals in a declarative region
signal mySignal1 : UNSIGNED(7 downto 0);
signal mySignal2 : UNSIGNED(7 downto 0);
signal greater : BOOLEAN;
-- now compare them
greater <= mySignal1 > mySignal2;

Related

How to know if vector is undefined

What I have
I've a signal of std_logic_vector. I need to give it values from a ROM, what I already do.
The problem
At the beginning of the simulation or use, there's an initialization process which makes it to need some time before ROM returns it first value (about 2 clk period).
Until then, ROM output vector is "UUUU" (since it's 4 bits of width). Let's call this signal ROM_coef_inf, so in simulation, this appears with "UUUU" value, so its colour is orange.
I need
I need to know how can I compare this output in order to know if it's an "undefined vector", in order to give another value (i.e. "0000") to my vector until the first ROM value is ready.
There are several possible solutions:
You could initialize all registers between your ROM and your destination (at least in simulation) with a different value to "UUUU".
A standard compare can test for all 9 STD_LOGIC values:
if (mySignal == 'U') then
You can test signals for special values with is_x(...).
Is is defined like this:
FUNCTION Is_X ( s : std_ulogic) RETURN BOOLEAN IS
BEGIN
CASE s IS
WHEN 'U' | 'X' | 'Z' | 'W' | '-' => RETURN TRUE;
WHEN OTHERS => NULL;
END CASE;
RETURN FALSE;
END;
There are overload for vectors, too.
I assume this is for FPGA use, in which case all registers will have a predictable value after programming, which is zeros unless you specify something else. If all you need is for ROM_coef_inf to have zeros instead of U's for the first clock cycles in simulation, you can simply specify an initial value when declaring the signal:
signal ROM_coef_inf : std_logic_vector(3 downto 0) := "0000";
In ASICs registers will have an unknown value after power is applied. In this case you need to use a reset signal to clear all the registers in your design. It is often a good idea to use a reset signal in an FPGA as well, for example to prevent your circuit from doing anything until the clock is stable.
The answer provided by #Paebbels works only in simulation. In the real world the signals tend to be either an 1 or a 0 (or a transition between them, but that is not discussed here). Number 1 will work, but you need to set it to a value that will never occur in your ROM if you want to check for uninitialized. The simpler option is to count clock cycles. The ROM will always behave the same. So if it takes three cycles to get the first data out, it will always take three cycles. So if you count three cycles you are ok.

Change bit state in Julia

In Julia language how can one set, clear and reverse a single bit? I hope you won't consider this question out of scope or too broad; if so, please comment it instead of downvote it.
Having this paragraph from Julia-Lang doc:
Currently, only sizes that are multiples of 8 bits are supported.
Therefore, boolean values, although they really need just a single
bit, cannot be declared to be any smaller than eight bits.
First it's possible to take a look at the binary representation of a variable like this:
julia> bits(Int(10))
"00000000000000000000000000001010"
and secondly, one can create byte value directly using its binary form:
julia> val=0b100
0x04
julia> typeof(val)
UInt8
and lastly, the best way to change value of a bit is performing right binary operation on its byte value:
julia> val | 0b10 # set 2nd bit
0x06
julia> bits(ans)
"00000110"
julia> val & 0b11111011 # clear 3nd bit
0x00
I assume you are wanting to clear, set and check the states of specific bits in a byte.
Where:
N represents the integer in question and;
n is the number of the bit in question (i.e: the n-th bit) and;
the LSB is 1-th bit
set the n-th bit: N |= 2^(n-1)
clear the n-th bit: N &= ~(2^(n-1))
check the state of a bit by copying and shifting: (N >> (n-1)) & 1 != 0
check the state of a bit using a bit-mask: mask = 2^(n-1); N & mask != mask
reverse/toggle/invert the n-th bit, using XOR: N ⊻= 2^(n-1). The xor function may also be used.

How can I increment an access type as if it were a C pointer?

How to increment an address of access type like a pointer in C? I am new to Ada...
procedure main is
type myarr is array(1..5)of integer; --creating array of 5 integer.
myarr_var:aliased myarr:=(2,5,7,9,0); --setting 5 values
type my_access is access all myarr; --creating access type (pointer)
var:my_access:=myarr_var'access; --holding address of 5 integer
begin;
-- since var holds the address of myarr_var now i want to increment
-- the address by adding 1 to print next value (5) as we do in c?
put((var+1).all); --???
-- i know this is bad but how to increment its base address of
-- var(pointer) so that it will point to next element 5?
end main;
Instantiate Interfaces.C.Pointers to do C-style pointer arithmetic in Ada.
Best explained by example:
with Ada.Text_IO; use Ada.Text_IO;
with Interfaces.C.Pointers;
procedure Access_Pointer_Arithmetic is
type Myarr_Indices is range 1 .. 5;
type Myarr is array (Myarr_Indices range <>) of aliased Integer;
Myarr_Terminator : constant Integer := 0;
package Myarr_Pointer_Arithmetic is new Interfaces.C.Pointers
(Myarr_Indices, Integer, Myarr, Myarr_Terminator);
use Myarr_Pointer_Arithmetic;
Myarr_Var : aliased Myarr := (2, 5, 7, 9, 0);
Var : Myarr_Pointer_Arithmetic.Pointer :=
Myarr_Var(Myarr_Var'First)'access;
begin
Put_Line(Integer'Image(Var.all));
Increment(Var);
Put_Line(Integer'Image(Var.all));
Increment(Var);
Put_Line(Integer'Image(Var.all));
Increment(Var);
Put_Line(Integer'Image(Var.all));
Var := Var - 2;
Put_Line(Integer'Image(Var.all));
end Access_Pointer_Arithmetic;
Running it:
C:\Ada\Sandbox\access_pointer_arithmetic
2
5
7
9
5
This package provides single increment/decrement, addition and subtraction of ptrdiff_t, and both terminator-specified and fixed length element array retrieval.
(Mind running off the end of the array... :-)
UPDATE : I just found out that there's a standard package Interfaces.C.Pointers that directly supports C-style pointer arithmetic, and now I see that Marc C.'s accepted answer covers its usage. You can probably ignore my answer, which discusses how you might do pointer arithmetic in Ada if Interfaces.C.Pointers didn't exist (which, in earlier versions of the language, it doesn't).
If you really want to do C-style pointer arithmetic on Ada access types, you can use the generic package System.Address_To_Access_Conversions to convert an object pointer type to System.Address, and the System.Storage_Elements package to perform C-like arithmetic on System.Address values.
Note that the target object type is a parameter to the System.Address_To_Access_Conversions generic package. The package itself defines the access type. You can't define your own access type and use it (at least not directly).
Keep in mind that C pointer arithmetic is defined in units of the size of the pointed-to object. So given:
int arr[10];
int *ptr = &arr[0];
the pointer value ptr + 3 points to arr[3], which is three int-sized chunks of memory past the location to which ptr points not necessarily three bytes. The "+" and "-" operators in System.Storage_Elements work with offsets in storage elements (which are very likely equivalent to C's "bytes").
So if you have an Ada pointer, um, I mean access value, that refers to an element of an array of Integers, then advancing to the next element of that array requires:
Using System.Address_To_Access_Conversions to convert the access type to System.Address;
Using the overloaded "+" operator in System.Storage_Elements to add the size of an Integer in bytes (Integer'Max_Size_In_Storage_Elements) to the System.Address value; and
Using System.Address_To_Access_Conversions again to convert the System.Address value back to your access type.
An alternative might be to write C code to do whatever pointer arithmetic you need, and use Interfaces.C to call that code from your Ada program.
But it's very likely that you don't need to do pointer arithmetic in Ada. C has pointer arithmetic in the core language; it even defines array indexing in terms of pointer arithmetic. Ada does not. There's rarely a good reason to perform pointer arithmetic in Ada. Just let arrays be arrays, and let the compiler figure out how to generate the best code to access their elements. (That code will likely involve pointer arithmetic on the CPU instruction level.)

Ada "constant" keyword memory usage

Consider the following code :
My_Constant : constant := 2;
Is "My_Constant" a variable or a C language macro-like, so does it have a storage in memory ?
Note that constant just means that you cannot modify the object. It doesn't necessarily mean that the value of the constant is known at compile time. So there are three cases to consider:
(1) A constant with a type, whose value is known at compile time:
My_Constant : constant Integer := 3;
In this case, there's no reason for the compiler to allocate memory for the constant; it can use the value 3 whenever it sees My_Constant (and is likely to use 3 as the immediate operand of instructions, where possible; if it sees something like My_Constant * 2 then it can use the value 6 as an immediate operand). The compiler is allowed to allocate memory for the constant, but I don't think any decent compiler would do so, in a simple case like this with a small number. If it were a really large number that wouldn't fit into an immediate operand, it might make more sense to allocate space for the number somewhere (if it can do so in a way that saves on code space).
In a more complex case:
My_Record_Constant : constant Rec := (Field_1 => 100, Field_2 => 201, Field_3 => 44);
Here, a good compiler can decide whether or not to store the constant in memory based on how it's used. If the only uses are accesses of individual fields (My_Record_Constant.Field_1), the compiler could replace those with the integer values, as if they were integer constants, and there would be no need to store the entire record in memory.
However, using aliased will cause any constant to be forced into memory:
My_Constant : aliased constant Integer := 3;
Now memory has to be allocated because the program could say My_Constant'Access (the access type has to be access constant Integer).
(2) A constant whose value is not known at compile time:
My_Constant : constant Integer := Some_Function_Call (Parameter_1);
The function is called once, when the integer's declaration is elaborated. Since it is not a macro expansion, uses of My_Constant do not generate calls to the function. Example:
procedure Some_Procedure is
My_Constant : constant Integer := Some_Function_Call (Parameter_1);
begin
Put_Line (Integer'Image (My_Constant));
Put_Line (Integer'Image (My_Constant));
end Some_Procedure;
Some_Function_Call is called each time Some_Procedure is called, but it is called once, not two or three times.
Most likely, this requires the value to be stored in memory to hold the function result, so space will be allocated for My_Constant. (This still isn't a requirement. If a good optimizing compiler can somehow figure out that Some_Function_Call will return a known value, it can use that information.)
(3) A named number. This is the example you have, where there is no type:
My_Constant : constant := 2;
The language rules say the value must be known at compile time. This is the equivalent of using that number every time My_Constant is seen, so it's the closest thing to a C macro you're going to get in Ada. But the effect is basically the same as in (1) [except with fewer restrictions on type compatibility]. The compiler probably will not allocate space for it, but it might do so for a larger value. Note that this syntax is allowed only for numeric values (integer or real).
Another variation on option (1) above is for a constant array.
primes : constant array(integer range <>) of integer := (1, 3, 5, 7, 11, 13, 17, 19, 23);
If the compiler can see it being accessed by an index, it will have to store the array.
I doubt the compiler writers would try and special case any other obscure corner condition to save some memory - they have enough other special corner cases to worry about in Ada!

The use of mod operators in ada

Can anyone please tell me the usage of the following declarations shown below.I am a beginner in ada language.I had tried the internet but that was not clear enough.
type Unsigned_4 is mod 2 ** 4;
for Unsigned_4'Size use 4;
Unsigned_4 is a "modular type" taking the values 0, 1, .. 14, 15, and wrapping round.
U : Unsigned_4;
begin
U := Unsigned_4'Last; -- 15
U := U + 1; -- 0
You only need 4 bits to implement the type, so it's OK to specify that as its Size (I think this may be simply a confirming spec, since the compiler clearly knows that already; if you were hoping to fit it into 3 bits and said for Unsigned_4'Size use 3; the compiler would tell you that you were wrong).
Most compilers will want to store values of the type in at least a byte, for efficient access. The minimum size comes into its own when you use the type in a packed record (pragma Pack).
The "is mod" is Ada's way of saying that this is a modular type. Modular types work a bit like unsigned types in C: They don't have negative values, and once you reach the largest representable value, if you add one you will get 0.
If you were to try the same with a normal (non-modular) integer in Ada, you'd get constraint_error

Resources