Reputation: 638
I have need to write a process that implement this correlation table :
E -> S
0 -> 2
1 -> 4
2 -> 8
3 -> 16
4 -> 32
5 -> 64
and so forth.
You can see clearly that the output can be easily calculated :
S = 1^(E+1)
However I'm not sure if it is possible to do this in VHDL with left shift. What bothers me is that we don't know in advance the size of (E+1) so we don't know how many 0 needs to be added so both sides of the equations have the same size.
Is there a smart way to do this in VHDL (smarter than to do a MUX) ?
Upvotes: 1
Views: 3082
Reputation: 408
There are few different ways to achieve this (for the purpose of synthesis); I'm sure there are more than those listed here. If E
is an input generic to your module (which it doesn't sound like it is, otherwise you would know what E+1
is in advance), no "additional" logic is required.
If E
is an input to the module, but you have an upper bound on E, you could simply use a ROM as a lookup (This isn't an efficient use of memory, but will work). Alternatively, you could use a function that takes E
as an input and returns a vector that represents the result, S
(Note that this also requires E
being bounded, which bounds the size of the result).
constant MAX_WID : natural := 64;
...
-- You can use unsigned in place of slv, if that is more suitable
function calc_s(e : integer) return std_logic_vector is
-- MAX_WID is effectively your maximum value of E
variable ret : std_logic_vector(MAX_WID+1 downto 0) := (others => '0');
begin
ret(e+1) := '1';
return ret;
end calc_s;
Upvotes: 1
Reputation: 11281
This is possible in many ways. E.g. To start:
use ieee.math_real.all;
constant E : natural := 0; -- any value >= 0
constant S : integer := natural(2 ** real(E+1));
Or
use ieee.numeric_std.all;
....
constant E : natural := 0;
constant S : unsigned((E+1) downto 0):= (
(E+1) => '1',
others => '0');
Or
use ieee.math_real.all;
use ieee.numeric_std.all;
....
constant E : natural := 0;
constant S : unsigned((E+1) downto 0) :=
to_unsigned(integer(2 ** real(E+1)), E+2));
Or
use ieee.numeric_std.all;
....
constant E : natural := 0;
signal S : unsigned((E+1) downto 0);
....
S <= left_shift(to_unsigned(1, (E+2)), E+1);
Etc, etc.
I mean, what would you like to achieve?
Upvotes: 0