VHDL Error "Expecting constant slice on LHS" - vhdl

I wrote a code. This should insert a "1" at a position, which is determined by the binary part of a signal E_reg_sig. The bits left to the "1" should be filled up by the fractional bits of a signal E_reg_sig.
There are some special cases:
The position is higher than the Output signals range: then all bits are set to high
There are more bits left right to the "1" than E_reg_sig has fractional bits: In this case the output should be filled up with the bits from E_reg_sig's fractional part, the rest should be "0"s
There is less space than E_reg_sig's bits widh: In this case the code should be filled up with the Bits from E_reg_sig from MSB to LSB till there are no bits from the output to fill up anymore
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.fixed_pkg.all;
use work.parameters.all;
entity log_mvm is
port (
CLK: IN std_logic;
E_reg: IN: ufixed(counter_log_mvm_WIDTH downto -(DATA_WIDTH_IN-2));
F_reg: OUT: unsigned(DATA_WIDTH_IN-2 downto 0);
);
end log_mvm;
architecture Behavioral of log_mvm is
begin
process(clk)
variable insert_position : NATURAL;
if rising_edge(CLK) then
insert_position:= to_integer(E_reg(E_reg'high downto 0));
if insert_position > F_reg'high then
F_reg<= (others=>'1');
else
F_reg(insert_position)<='1';
if insert_position>-1 then
If insert_position>=(-E_reg'low) then
F_reg(insert_position-1 downto insert_position+E_reg'low)<=unsigned(E_reg(-1 downto E_reg'low));
else
F_reg(insert_position-1 downto 0)<=unsigned(E_reg(-1 downto -insert_position));
END if;
END IF;
end if;
END IF;
END IF;
end process;
end Behavioral;
DATA_WIDTH_IN is defined as natural with the value 8
This codes works in simulation fine, but for synthezise, there is the error "[Synth 8-7138] Expecting constant slice on LHS" on part F_reg(insert_position-1 downto 0)<=unsigned(E_reg(-1 downto -insert_position));
How to avoid this
I am using VHDL 2008 with Vivad0 2021

You have to work with a loop:
for i in F_reg'range loop
if i<=insert_position-1 then
F_reg(i) <= E_reg(i-insert_position);
end if;
end loop;

Related

How do I extract a single bit out of a std_logic_vector and convert it to an integer?

I am struggling with type conversion in vhdl. I am pretty new to vhdl and apologize, if this is a really stupid question.
But what i want to do is, i want to go through the input vector and add all bits together to form an integer.
For example "11001010" shall result in 4 (or "100"). And "11101010" would result for example in 6 (or "110"). How can i achieve that?
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity xyz is
port(
input: in std_logic_vector(7 downto 0);
output: out std_logic_vector(7 downto 0)
);
end entity;
architecture behaviour of xyz is
signal temp : integer := 0;
begin
evaluate_input :process is
begin
for i in input'left downto input'right loop
temp <= temp + to_integer(unsigned(input(i)));
end loop;
wait;
end process;
stop_simulation :process is
begin
wait for 100 ns; --run the simulation for this duration
assert false
report "simulation ended"
severity failure;
end process;
end xyz;
Don't think to complicated. You want to calculate the hamming weight.
for i in input'range loop
temp <= temp + (1 when (input(i) = '1') else 0);
end loop;
Or with your proposed way:
for i in input'range loop
temp <= temp + to_integer(unsigned(input(i downto i)));
end loop;
unsigned(...) needs an array of std_logic_vector. By using just i, you get a single std_logic. Whereas, i downto i creates another std_logic_vector of length 1, which can be used in unsigned.

signal statement must use <= to assign value to signal

I've got this error in the expression "individuos(x):=cout" of the following code. What I'm trying to do is assign to each array of individuos a different random "cout" input sequentially. If I change the expression to "individuos <= cout", it'll asign the same "cout" to all "individuos", the same will happen if i trie to build a sequential statement with the assert function. How do I fix this?
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_TEXTIO.ALL;
use ieee.numeric_std.all;
--package genetica_type is
--type genetica is array(0 to 49) of unsigned(7 downto 0);
--type fitness is array(0 to 49) of unsigned (2 downto 0);
--end package genetica_type;
use work.genetica_type.all;
entity conexao is
Port (
clk : in bit;
cout: in unsigned (7 downto 0);
individuos: out genetica
);
end entity;
architecture Behavioral of conexao is
--type genetica is array (0 to 49) of std_logic_vector (7 downto 0);
--signal s_individuos : genetica;
--signal i: genetica;
begin
process (clk)
begin
If (clk 'event and clk = '1') then
for x in 0 to 49 loop
individuos(x) := cout;
end loop;
end if ;
end process;
end Behavioral;
I've got this error in the expression "individuos(x):=cout" of the following code.
That is a syntax error. Use <= exactly as the compiler says.
What I'm trying to do is assign to each array of individuos a different random "cout" input sequentially. If I change the expression to "individuos <= cout", it'll asign the same "cout" to all "individuos"
That is exactly what you ask it to do :
If (clk 'event and clk = '1') then
for x in 0 to 49 loop
individuos(x) <= cout;
end loop;
end if ;
On every rising clock edge, loop 50x performing 50 assignments, each of the same data, to all 50 addresses.
What I think you want to do, is, on every clock, perform ONE assignment, and increment the address to point to the next location.
signal x : natural range 0 to individuos'high;
...
if rising_edge(clk) then
individuos(x) <= cout;
x <= x + 1 mod individuos'length;
end if;
This code has several other differences from yours:
It uses the simpler rising_edge(clk) function
It will still work when you change the size of the input array.
It still has a bug : if you change the array lower bound to something other than 0, it will fail... for example:
type genetica is array(3 to 49) of ...
Easy to catch this with an assert:
Assert individuos'low = 0 report "Array Individuos bound error" severity failure;
It also runs continuously. If you want to start and stop it, or reset the address counter, or stop when it reaches 50, that takes additional logic.

RAM to read/write in VHDL

I'm trying to use RAM in order to read/write. My address is an integer value and it should be a memory of integers. This is my code below but i keep getting an error.
This is from my data path where the address selection is from a register of integers.
Code:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
entity Mem is
generic( width: integer:=4;
depth: integer:=4;
addr: integer:=2);
port( Clock: in std_logic;
Enable: in std_logic;
Read: in std_logic;
Write: in std_logic;
Read_Addr: in integer;
Write_Addr: in integer;
Data_in: in integer;
Data_out: out integer
);
end Mem;
--------------------------------------------------------------
architecture behav of Mem is
type ram_type is array (0 to 31) of
integer;
signal tmp_ram: ram_type;
begin
-- Read Functional Section
process(Clock, Read)
begin
if (Clock'event and Clock='1') then
if Enable='1' then
if Read='1' then
-- buildin function conv_integer change the type
-- from std_logic_vector to integer
Data_out <= tmp_ram(conv_integer(Read_Addr));
else
Data_out <= (Data_out'range => 'Z');
end if;
end if;
end if;
end process;
-- Write Functional Section
process(Clock, Write)
begin
if (Clock'event and Clock='1') then
if Enable='1' then
if Write='1' then
tmp_ram(conv_integer(Write_Addr)) <= Data_in;
end if;
end if;
end if;
end process;
end behav;
----------------------------------------------------------------
Error:
Error (10514): VHDL aggregate error at Mem.vhd(41): can't determine type of aggregate -- found 0 possible types
Your faulty code is:
if Read='1' then
-- buildin function conv_integer change the type
-- from std_logic_vector to integer
Data_out <= tmp_ram(conv_integer(Read_Addr));
else
Data_out <= (Data_out'range => 'Z'); -- Faulty line
end if;
Data_out is an integer, not a std_logic_vector or derived type. Thus, it doesn't have a range (only arrays do, std_logic_vector beeing defined as an array of std_logic). Furthermore, it can't take the value of 'Z' since it is not an std_logic; integers can only be assigned integer values.
If you need Data_out to become high-impedance when enable is '1' and read is '0' as you described, you will need your memory output to use std_logic_vector or signed/unsigned.
Also, I should advise you against using integers without range if your target is synthesis. By VHDL standard, integers are 32 bits. Synthesis tool may optimized the netlist and use less bits, but you shouldn't count on it. Either constrain the range of your integers (signal x: integer range -4 to 3) or use signed/unsigned.

How do I flip the bits in a vector in VHDL

I have a problem with VHDL, I want to rotate the signal Checked1 and save it in itself:
Checked1<=to_stdlogicvector(to_bitvector(Checked1) ROR 1);
and I get all zeros, instead of 0100->0010
I know I can't use the same signal, but I have to change Checked1 in a loop.
How can i used it?
The whole code is here:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_arith.ALL;
use IEEE.numeric_std.all;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity Stall_control is
Port ( EP : in STD_LOGIC_VECTOR (7 downto 0);
SP : in STD_LOGIC_VECTOR (7 downto 0);
Comp : in STD_LOGIC_VECTOR (7 downto 0);
Position : out STD_LOGIC_VECTOR (7 downto 0));
end Stall_control;
architecture Behavioral of Stall_control is
type state is (LOOP_STATE, END_STATE);
signal FSM_state: state;
signal Check: STD_LOGIC_VECTOR (7 downto 0);
signal Checked: STD_LOGIC_VECTOR (7 downto 0);
signal Checked1: STD_LOGIC_VECTOR (7 downto 0):="00000000";
signal flag: STD_LOGIC:='0';
begin
Checked<= EP;
process(EP, SP, Comp, Check, CheckED, CheckED1, FLAG)
begin
Position<= "11111111";
case FSM_state is
when LOOP_STATE=>
if((Checked AND Comp)="00000000") OR ((Checked1 AND Comp)="00000000") then
Checked1<=to_stdlogicvector(to_bitvector(Checked1) ROR 1);
--Checked<=Checked1;
--Checked1(7 downto 0)<=Checked1(0)&Checked1(7 downto 1);
flag<='0';
if(CheckED1/= SP) then
FSM_state<=LOOP_STATE;
else
FSM_state<=END_STATE;
end if;
else
flag<='1';
FSM_state<=END_STATE;
end if;
when END_STATE=>
if flag='1' then
Position<= Checked1;
else
--Position<= Checked1;
Position<= "11111111";
end if;
end case;
end process;
end Behavioral;
You are never assigning anything but all '0's to checked1.
case fsm_state is
when loop_state =>
if (checked and comp) = "00000000" or
(checked1 and comp) = "00000000" then
checked1 <= to_stdlogicvector(to_bitvector(checked1) ror 1);
flag<='0';
if checked /= sp then
fsm_state<=loop_state;
else
fsm_state<=end_state;
end if;
else
flag<='1';
fsm_state<=end_state;
end if;
checked1 has a default value of (others => '0') (all zeros) and is only rotated by 1. Of course it's going to be all zeros.
-- The ror operator returns a value that is L rotated right by R index positions. That is, if R is 0 or if L is a null array, the return
value is L. Otherwise, a basic rotate operation replaces L with a
value that is the result of a concatenation whose right argument is
the leftmost (L'Length - 1) elements of L and whose left argument is
L(L'Right). If R is positive, this basic rotate operation is repeated
R times to form the result. If R is negative, then the return value is
the value of the expression L rol -R.
It sounds like you want a different default value for checked1.
You don't need the ROR operator, you can use concatenation:
checked1 <= checked1(0) & checked1 (7 downto 1);
(Because your ROR operator R value is a constant and within the length of checked1).
And none of these now commented out packages are needed in your context clause:
library ieee;
use ieee.std_logic_1164.all;
-- use ieee.std_logic_arith.all;
-- use ieee.numeric_std.all;
-- use ieee.std_logic_unsigned.all;
Not a one of the three, and there can be potential conflicts from the combination.
And the way the process sensitivity list is populated, you've created an oscillation, any signal assigned in the process that is also in the sensitivity list will cause the process to resume the next simulation cycle. Put a '1' somewhere in the default value for checked1 and rotating it will cause an event (a change of value) on checkd1 causing the process to be invoked successively.

vhdl "parse error, unexpected FOR"

I try to write programm on vhdl in ise 14.4 for crc16 calculation but dont understand why get "parse error, unexpected FOR" in it. Tried to put it into process but it dont works too.
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity crc16 is port(
clk : in STD_LOGIC:='0');
end crc16;
architecture Behavioral of crc16 is
signal data:std_logic_vector(15 downto 0):="1010101010101010";
signal ext_data:std_logic_vector(31 downto 0);
signal crc16_original:std_logic_vector(15 downto 0):="1100000000000010";
signal crc16:std_logic_vector(15 downto 0);
signal position:std_logic_vector(5 downto 0);
signal crc_out:std_logic_vector(14 downto 0);
signal i:std_logic_vector(5 downto 0);
begin
for i in 1 to 15 loop
ext_data(i+16)<=data(i);
end loop;
for i in 1 to 15 loop
ext_data(i)<='0';
end loop;
while ext_data > "111111111111111" loop
for i in 0 to 31 loop
if ext_data(i)="1" position=i;
end loop;
crc16<= crc16_original srl 31-position;
ext_data<=ext_data xor crc16;
end loop;
for i in 0 to 14 loop
crc_out(i)<=ext_data(i);
end loop;
end Behavioral;
There are several issues to point out:
The for-loop must be in a process, so that is likely to cause the “parse error, unexpected FOR” that you see.
The relation compare with > may give unexpected result for std_logic_vector, so you may take a look at the numeric_std package for casting as for example unsigned(std_logic_vector) before comparison is made.
Compare ext_data(i) = "1" is illegal, since "1" is taken as std_logic_vector, where as ext_data(i) is std_logic; instead ext_data(i) = '1' will compile.
Illegal construction around if ext_data(i) = "1" position=i;, since no then etc.
There is an signal with identifier i, which i is also used as loop variable, with the result that position <= i is taken as an integer assign to std_logic_vector; use different names for signals and loop variables.
Assign to signal is not position = i but position <= i, like elsewhere.
Expression 31-position mixes integer and std_logic_vector, which can't be done with the selected packages. Use casting with unsigned.
The ext_data<=ext_data xor crc16 uses different size arguments, since ext_data is 32 bits and crc16 is 16 bits; this does probably not yield the expected result.
srl is not defined for std_logic_vector (VHDL-2002), so consider casting with unsigned for well-defined behavior.
Assuming that that your code is "sandbox" code, since it has no outputs.
Based on the above, you may consider doing some initial experiments with smaller designs, in order to get familiar with the different VHDL constructions, and learn how this simulates and maps to hardware; remember VHDL is a "Hardware Description Language" and not a programming language.
Below is some code that compiles in ModelSim, but is unlikely to give the expected result:
library ieee;
use ieee.std_logic_1164.all;
entity crc16 is port(
clk : in std_logic := '0');
end crc16;
library ieee;
use ieee.numeric_std.all;
architecture Behavioral of crc16 is
signal data : std_logic_vector(15 downto 0) := "1010101010101010";
signal ext_data : std_logic_vector(31 downto 0);
signal crc16_original : std_logic_vector(15 downto 0) := "1100000000000010";
signal crc16 : std_logic_vector(15 downto 0);
signal position : std_logic_vector(5 downto 0);
signal crc_out : std_logic_vector(14 downto 0);
signal i_sig : std_logic_vector(5 downto 0);
begin
process (clk) is
begin
if rising_edge(clk) then
for i in 1 to 15 loop
ext_data(i+16) <= data(i);
end loop;
for i in 1 to 15 loop
ext_data(i) <= '0';
end loop;
while ext_data > "111111111111111" loop
for i in 0 to 31 loop
if ext_data(i) = '1' then
position <= i_sig; -- TBD[Probably not right code, but compiles]
end if;
end loop;
crc16 <= std_logic_vector(unsigned(crc16_original) srl (31 - to_integer(unsigned(position))));
ext_data <= ext_data xor crc16;
end loop;
for i in 0 to 14 loop
crc_out(i) <= ext_data(i);
end loop;
end if;
end process;
end Behavioral;

Resources