I have a array of integers range 0 to 23 which stores value of range 0 to 2 like ex:
type t_slave_24symbol is array (0 to 23) of integer range 0 to 2;
signal slave_24symbol : t_slave_24symbol;
type nibble_array is array (0 to 7) of STD_LOGIC_VECTOR(3 downto 0);
signal nibble : nibble_array;
signal nibble_full : STD_LOGIC_VECTOR(31 downto 0) := "00000000000000000000000000000000";
now I want to split this string into sequences of 3 and compare like
nibble(0) <= "0000" when slave_24symbol(012) = 120 else--
"0001" when slave_24symbol(012)= 200 else
"0010" when slave_24symbol(012)= 020 else
"1111";
but later
nibble(3) <= "0000" when slave_24symbol(91011) = 012 else
. . .
and at the end
nibble_full <= nibble(0) & nibble(1) & nibble(2) & nibble(3) & nibble(4)
& nibble(5) & nibble(6) & nibble(7);
how do I do? because I want to assign char 9 10 and 11 and so on.
The question shows python syntax thinking.
There's an array of constrained integers being converted to binary representation in a std_logic_vector array.
First a working Minimal, Complete, and Verifiable example for assigning one element of nibble:
library ieee;
use ieee.std_logic_1164.all;
entity depython is
end entity;
architecture foo of depython is
type t_slave_24symbol is array (natural range <>) of integer range 0 to 2;
signal slave_24symbol: t_slave_24symbol (0 to 23);
type nibble_array is array (0 to 7) of std_logic_vector(3 downto 0);
signal nibble: nibble_array;
signal nibble_full: std_logic_vector(31 downto 0) := (others => '0');
subtype nyyblet is t_slave_24symbol (0 to 2);
begin
-- nibble(0) <= "0000" when slave_24symbol(012) = 120 else--
-- "0001" when slave_24symbol(012)= 200 else
-- "0010" when slave_24symbol(012)= 020 else
-- "1111";
-- BECOMES:
nibble(0) <= "0000" when slave_24symbol(0 to 2) = nyyblet'(1, 2, 0) else
"0001" when slave_24symbol(0 to 2) = nyyblet'(2, 0, 0) else
"0010" when slave_24symbol(0 to 2) = nyyblet'(0, 2, 0) else
"1111";
end architecture;
The type t_slave_24symbol
has been changed to an unconstrained array definition with the declaration of signal slave_24symbol
providing the subtype. (This is called an unbounded array definition in -2008).
The index range of a slice of slave_24symbol
is changed to VHDL syntax. The value range of the expression evaluated in each condition has been changed to VHDL syntax using an aggregate whose type is provided by qualified expression requiring the subtype definition. The subtype declaration requires the unconstrained/unbounded array definition.
The qualified expression is required to specify the subtype because the predefined equality operator for an array type operates on unconstrained operands - you can test equality of two different length arrays and they will always be unequal. (Comes in handy when dealing with null arrays).
Note that the type of a string literal (e.g. "0010") is determined by context and element values ('0', '1') must be compatible with the element type (here std_ulogic) of the array type (here std_logic_vector).
This analyzes, elaborates and simulates (using the default value (0, 0, 0) for each element of slave_24symbol, each process will execute once during initialization, a concurrent assignment statement is elaborated into an equivalent sequential assignment statement contained in a process statement).
Now we address how to convert all the elements of nibble
in a new architecture:
architecture sequential of depython is
type t_slave_24symbol is array (natural range <>) of integer range 0 to 2;
signal slave_24symbol: t_slave_24symbol (0 to 23);
type nibble_array is array (0 to 7) of std_logic_vector(3 downto 0);
signal nibble: nibble_array;
signal nibble_full: std_logic_vector(31 downto 0) := (others => '0');
subtype nyyblet is t_slave_24symbol (0 to 2);
function nybble (nyb: nyyblet) return std_logic_vector is
-- retv: std_logic_vector(3 downto 0);
begin
if nyb = nyyblet'(1, 2, 0) then
return "0000";
elsif nyb = nyyblet'(2, 0, 0) then
return "0001";
elsif nyb = nyyblet'(0, 2, 0) then
return "0010";
else
return "1111";
end if;
end function;
begin
-- nibble(0) <= "0000" when slave_24symbol(0 to 2) = nyyblet'(1,2,0) else
-- "0001" when slave_24symbol(0 to 2) = nyyblet'(2,0,0) else
-- "0010" when slave_24symbol(0 to 2) = nyyblet'(0,2,0) else
-- "1111";
-- but later
--
-- nibble(3) <= "0000" when slave_24symbol(91011) = 012 else
--
-- . . .
--
-- and at the end
--
-- nibble_full <= nibble(0) & nibble(1) & nibble(2) & nibble(3) & nibble(4)
-- & nibble(5) & nibble(6) & nibble(7);
process (slave_24symbol)
begin
for i in nibble'range loop
nibble(i) <= nybble(slave_24symbol(3 * i to 2 + i * 3));
end loop;
end process;
end architecture;
Here a function call is used to hide some of the complexity. The sequential assignment statement in a loop statement (a sequential statement itself) uses offset arithmetic to address all eight slices of three constrained integers of of slave_24symbol
being evaluated.
And because the question showed a nibble element being assigned in a conditional signal assignment (here a concurrent signal assignment), a concurrent assignment version using a generate statement:
architecture concurrent of depython is
type t_slave_24symbol is array (natural range <>) of integer range 0 to 2;
signal slave_24symbol: t_slave_24symbol (0 to 23);
type nibble_array is array (0 to 7) of std_logic_vector(3 downto 0);
signal nibble: nibble_array;
signal nibble_full: std_logic_vector(31 downto 0) := (others => '0');
subtype nyyblet is t_slave_24symbol (0 to 2);
function nybble (nyb: nyyblet) return std_logic_vector is
-- retv: std_logic_vector(3 downto 0);
begin
if nyb = nyyblet'(1, 2, 0) then
return "0000";
elsif nyb = nyyblet'(2, 0, 0) then
return "0001";
elsif nyb = nyyblet'(0, 2, 0) then
return "0010";
else
return "1111";
end if;
end function;
begin
-- process (slave_24symbol)
-- begin
-- for i in nibble'range loop
-- nibble(i) <= nybble(slave_24symbol(3 * i to 2 + i * 3));
-- end loop;
-- end process;
NIBBLE_IT:
for i in nibble'range generate
nibble(i) <= nybble(slave_24symbol(3 * i to 2 + i * 3));
end generate;
end architecture;
All the shown architectures analyze, elaborate and simulate demonstrating all the indexes and slices fall within subtype bounds.
Note you could also pour the loop statement into a function with a parameter type of t_slave_24symbol
and perform one assignment either concurrently or sequentially. This would also allow detection of a parameter value that isn't comprised of a multiple of 3 integers (because type t_slave_24symbol
is declared unconstrained/unbounded). It's possible to avoid any parameter value detection by declaring a new type and making t_slave_24symbol
and nyyblet
subtypes of the new type:
architecture all_in_one_function of depython is
type c_integer_array is array (natural range <>) of integer range 0 to 2;
subtype t_slave_24symbol is c_integer_array (0 to 23);
signal slave_24symbol: t_slave_24symbol := (
1,2,0, 2,0,0, 0,2,0, 0,0,0, 0,0,1, 0,0,2, 0,1,0, 0,1,1);
signal nibble_full: std_logic_vector (31 downto 0);
function nybble (slave: t_slave_24symbol) return std_logic_vector is
type nibble_array is array (0 to 7) of std_logic_vector(3 downto 0);
variable nib: nibble_array;
subtype nyyblet is c_integer_array (0 to 2);
begin
for i in nib'range loop
if slave(3 * i to 2 + i * 3) = nyyblet'(1, 2, 0) then
nib(i) := "0000";
elsif slave(3 * i to 2 + i * 3) = nyyblet'(2, 0, 0) then
nib(i) := "0001";
elsif slave(3 * i to 2 + i * 3) = nyyblet'(0, 2, 0) then
nib(i) := "0010";
else
nib(i) := "1111";
end if;
end loop;
return nib(0) & nib(1) & nib(2) & nib(3) &
nib(4) & nib(5) & nib(5) & nib(7);
end function;
function to_string (inp: std_logic_vector) return string is
variable image_str: string (1 to inp'length);
alias input_str: std_logic_vector (1 to inp'length) is inp;
begin
for i in input_str'range loop
image_str(i) := character'VALUE(std_ulogic'IMAGE(input_str(i)));
end loop;
return image_str;
end function;
begin
NIBBLE_IT:
nibble_full <= nybble(slave_24symbol);
process
begin
wait for 0 ns;
report "nibble_full = " & to_string (nibble_full);
wait;
end process;
end architecture;
The to_string function is added for compatibility with VHDL revisions earlier than -2008. The signal _slave_24symbol
is initialized to demonstrate the conversion is successful:
/usr/local/bin/ghdl -a depython1.vhdl
/usr/local/bin/ghdl -e depython
/usr/local/bin/ghdl -r depython
depython1.vhdl:79:9:@0ms:(report note): nibble_full = 00000001001011111111111111111111