VHDL multiple constant drivers - vhdl

I'm trying to modify a source code for do a sum (for example) and other maths function using switch and hex display.
This is the main code:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.seven_segment_pkg.all;
entity Switch7Segment is
port (
SW : in std_logic_vector(9 downto 0);
HEX0 : out std_logic_vector(6 downto 0);
HEX1 : out std_logic_vector(6 downto 0);
HEX2 : out std_logic_vector(6 downto 0);
HEX3 : out std_logic_vector(6 downto 0);
KEY : in std_logic_vector(3 downto 0);
CLOCK_50 : in std_logic
);
end entity Switch7Segment;
architecture behavior of Switch7Segment is
signal segments1 : std_logic_vector(13 downto 0);
signal segments2 : std_logic_vector(13 downto 0);
signal segmentsR : std_logic_vector(13 downto 0); -- Range changed from 27 downto 0 to allow compile
signal input1 : integer;
signal input2 : integer;
signal result : unsigned(31 downto 0); -- Range added to allow compile
signal temp : integer;
begin
input1 <= to_integer(unsigned(SW(4 downto 0)));
input2 <= to_integer(unsigned(SW(9 downto 5)));
segments1 <= unsigned_to_seven_segment(value => unsigned(SW(4 downto 0)), number_of_digits => 2, value_is_bcd => false);
segments2 <= unsigned_to_seven_segment(value => unsigned(SW(9 downto 5)), number_of_digits => 2, value_is_bcd => false);
HEX1 <= segments1(13 downto 7);
HEX0 <= segments1(6 downto 0);
HEX3 <= segments2(13 downto 7);
HEX2 <= segments2(6 downto 0);
process(CLOCK_50)
begin
if (CLOCK_50' EVENT and CLOCK_50 = '1' AND KEY(0) = '1') then
temp <= input1+input2;
result <= to_unsigned(integer(temp), result'length);
segmentsR <= unsigned_to_seven_segment(value => unsigned(result), number_of_digits => 2, value_is_bcd => false);
HEX1 <= segmentsR(13 downto 7);
HEX0 <= segmentsR(6 downto 0);
end if;
end process;
end architecture;
And then there is the package:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
package seven_segment_pkg is
-- Return a std_logic_vector ready for driving a number of 7-segment displays.
function unsigned_to_seven_segment(value : unsigned; number_of_digits : integer; value_is_bcd : boolean)
return std_logic_vector;
end;
package body seven_segment_pkg is
function seven_seg_from_bcd_digit(bcd_digit : std_logic_vector(3 downto 0)) return std_logic_vector is
begin
case bcd_digit is
-- abcdefg
when x"0" => return "1000000";
when x"1" => return "1111001";
when x"2" => return "0100100";
when x"3" => return "0110000";
when x"4" => return "0011001";
when x"5" => return "0010010";
when x"6" => return "0000010";
when x"7" => return "1111000";
when x"8" => return "0000000";
when x"9" => return "0010000";
when x"a" => return "0001000";
when x"b" => return "0000011";
when x"c" => return "1000110";
when x"d" => return "0100001";
when x"e" => return "0000110";
when x"f" => return "1110001";
when others => return "0000000";
end case;
end function;
-- Return a vector ready for driving a series of 7-segment displays.
function unsigned_to_seven_segment(
value : unsigned;
-- Number of 7-segment displays (determines output vector width: W = 7*N)
number_of_digits : integer;
-- When true, treat the input value as a BCD number where every 4 bits hold one
-- digit from 0 to A. When false, treat the input number as an unsigned integer.
value_is_bcd : boolean
) return std_logic_vector is
variable segments : std_logic_vector(number_of_digits*7-1 downto 0);
variable bcd_quotient : unsigned(value'range);
variable bcd_remainder : unsigned(3 downto 0);
begin
if value_is_bcd then
for i in 0 to number_of_digits-1 loop
segments(i*7+6 downto i*7) := seven_seg_from_bcd_digit(
std_logic_vector(value(i*4+3 downto i*4))
);
end loop;
else
bcd_quotient := value;
for i in 0 to number_of_digits-1 loop
bcd_remainder := resize(bcd_quotient mod 10, 4);
bcd_quotient := bcd_quotient / 10;
segments(i*7+6 downto i*7) := seven_seg_from_bcd_digit(
std_logic_vector(bcd_remainder)
);
end loop;
end if;
return segments;
end function;
end package body;
I think that there is an error that at the moment i never signed here that is the length of the result. if we compile this VHDL code Quartus will tell us that the function is for 13 element and not for 27. But i don't see an obstacle to resolve it....my problem is about outputs (HEX0.....HEX3)
If i modify the code and i insert
signal segmentsR: std_logic_vector(13 downto 0);
I resolve the problem of the length but i will see error 10028 (multiple constant drivers).
If i understood correct, i can't assign two times at the same vector two different value or something similar is correct? maybe i always think like a C++ / C programmer. I think that if i use CLOCK the problem will be resolve but is not true...

The problem is that there are drivers for HEX0 and HEX1 both before the process and in the process, but any signal/port should only be driven from one place in typical synthesized code.
If the HEX0 and HEX1 are driven from the process, then remove the drivers before the process.

Conceptually, a multiple drivers error means that your behavioral code (remember: VHDL describes how a circuit works) isn't able to be synthesized. Or, if you have really special synthesizing code, it will give you unexpected results.
In my experience, this error results when I write code with undefined behavior -- for example, if in two processes I modify the same variable (say, X) based on some condition, then the hardware could run into an undefined state where both conditions are met -- how should the variable be modified? If you are familiar to race conditions or mutual exclusion, this should look familiar. Hardware languages don't have easy support for mutex and the like, so they warn you and won't let you do the bad thing.
In your case, I think you could clarify your code and simplify things by assigning default values to your top-level ports, like so:
entity Switch7Segment is
port (
SW : in std_logic_vector(9 downto 0);
HEX0 : out std_logic_vector(6 downto 0);
HEX1 : out std_logic_vector(6 downto 0) := (others => '0');
HEX2 : out std_logic_vector(6 downto 0) := (others => '0');
HEX3 : out std_logic_vector(6 downto 0);
KEY : in std_logic_vector(3 downto 0);
CLOCK_50 : in std_logic
);
end entity Switch7Segment;
This provides a default value for an entity. Whatever creates the entity can provide a different value than the default. Read more here: http://vhdl.renerta.com/mobile/source/vhd00051.htm
It looks like your default value is more complicated (based on the inputs of the function). In this case, I would either (1) change my interface so that the caller provides the information or (2) write a function and a constant in a package and use the function/constant as the default value.
Another possible solution is using generics and default value. This would let you use the bits of the SW field in you default values. (ie: something like HEX2 : out std_logic_vector(6 downto 0) := (SW(xx downto yy), where SW is defined in the generics port)

Related

Can't normally see result in wave (Modesim)

I have code designed for Vivid software. How I can translate this code into ModelSIM? In vivado, I should get the following values, but in modelsim I get completely different ones.
This is noise generator. Successful in adding pseudorandom noise sequence to our sine wave, but now we are trying to add Gaussian noise. The code and the simulation results for ADDITION OF PSEUDORANDOM NOISE SEQUENCE TO SINE WAVE IS GIVEN BELOW:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL; --try to use this library as much as possible.
entity sine_wave is
generic ( width : integer := 4 );
port (clk :in std_logic;
random_num : out std_logic_vector (width-1 downto 0);
data_out : out STD_LOGIC_VECTOR(7 downto 0)
);
end sine_wave;
architecture Behavioral of sine_wave is
signal data_out1,rand_temp1,noisy_signal : integer;
signal noisy_signal1 : STD_LOGIC_VECTOR(7 downto 0);
signal i : integer range 0 to 29:=0;
--type memory_type is array (0 to 29) of integer;
type memory_type is array (0 to 29) of std_logic_vector(7 downto 0);
--ROM for storing the sine values generated by MATLAB.
signal sine : memory_type := ("01001101","01011101","01101100","01111010","10000111","10010000","10010111","10011010","10011010");
--hi
begin
process(clk)
variable rand_temp : std_logic_vector(width-1 downto 0):=(width-1 => '1',others => '0');
variable temp : std_logic := '0';
begin
--to check the rising edge of the clock signal
if(rising_edge(clk)) then
temp := rand_temp(width-1) xor rand_temp(width-2);
rand_temp(width-1 downto 1) := rand_temp(width-2 downto 0);
rand_temp(0) := temp;
--data_out <= sine(i);
i <= i+ 1;
if(i = 29) then
i <= 0;
end if;
end if;
data_out <= sine(i);
data_out1<=to_integer(unsigned(sine(i)));
random_num <= rand_temp;
rand_temp1<=to_integer(unsigned(rand_temp));
noisy_signal<=data_out1+rand_temp1;
noisy_signal1<= std_logic_vector(to_signed(noisy_signal,8));
end process;
end Behavioral;
Vivado
ModelSIM

VHDL-can't add numbers?

Hello I want to build a clock on my ALTERA DE2 that I can adjust the length of by pressing keys.
Now the problem is that when I convert from STD_LOGIC_VECTOR to UNSIGNED the code does not work:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
--use ieee.std_logic_unsigned.all; Do not use with numeric_std
entity Adjust_Clock_4_buttens is
port(
clk,clk1 : in STD_LOGIC;
minutes_plus, minutes_minus,houres_plus,houres_minus : in STD_LOGIC;
minutes : IN STD_LOGIC_VECTOR(5 downto 0);
houres : IN STD_LOGIC_VECTOR(4 downto 0);
output_minutes : out STD_LOGIC_VECTOR(5 downto 0);
output_houres : out STD_LOGIC_VECTOR(4 downto 0);
LED_0 : OUT STD_LOGIC;
LED_1 : OUT STD_LOGIC;
LED_2 : OUT STD_LOGIC;
LED_3 : OUT STD_LOGIC
);
end entity Adjust_Clock_4_buttens ;
architecture behavioral of Adjust_Clock_4_buttens is
signal button1_r : std_logic_vector(2 downto 0);
signal button2_r : std_logic_vector(2 downto 0);
signal button3_r : std_logic_vector(2 downto 0);
signal button4_r : std_logic_vector(2 downto 0);
-- signal minutes_total : unsigned(5 downto 0) := (others => '0');
-- signal houres_total : unsigned(4 downto 0) := (others => '0');
signal minutes_total : unsigned(5 downto 0);
signal houres_total : unsigned(4 downto 0);
begin
process(clk)
begin
if (rising_edge(clk) )then
minutes_total<=unsigned(minutes);
houres_total<=unsigned(houres);
-- Shift the value of button in button_r
-- The LSB is unused and is there solely for metastability
button1_r <= button1_r(button1_r'left-1 downto 0) & minutes_plus;
button2_r <= button2_r(button2_r'left-1 downto 0) & minutes_minus;
button3_r <= button3_r(button3_r'left-1 downto 0) & houres_plus;
button4_r <= button4_r(button4_r'left-1 downto 0) & houres_minus;
if button1_r(button1_r'left downto button1_r'left-1) = "01" then -- Button1 rising --button1_r[2:1]
minutes_total <= (minutes_total + 1);
LED_0<='1';LED_1<='0';LED_2<='0';LED_3<='0';
elsif button2_r(button2_r'left downto button2_r'left-1) = "01" then -- Button2 rising --button1_r[2:1]
minutes_total <= (minutes_total-1 );
LED_0<='0';LED_1<='1';LED_2<='0';LED_3<='0';
end if;
if button3_r(button3_r'left downto button3_r'left-1) = "01" then -- Button1 rising --button1_r[2:1]
houres_total <= (houres_total + 1);
LED_0<='0';LED_1<='0';LED_2<='1';LED_3<='0';
elsif button4_r(button4_r'left downto button4_r'left-1) = "01" then -- Button2 rising --button1_r[2:1]
houres_total<= (houres_total-1 );
LED_0<='0';LED_1<='0';LED_2<='0';LED_3<='1';
end if;
end if;
end process;
output_minutes <= std_logic_vector(minutes_total);
output_houres <= std_logic_vector(houres_total);
end architecture behavioral ;
So in this code I get the time from another block the problem start when I try to add minutes and hours and for some reason it does not react to pressing of the keys. Could anyone explain maybe why is that?
The problem might be that you only have the clock in the sensitivity list of your process. Try adding the buttons in the sensitivity list, since they drive your if conditions. (Not sure if that's the problem but I guess it's worth a try)
minutes_total<=unsigned(minutes);
is on 2 lines, inside and outside of the process, which generates multiple line drivers, and will not work, ever!
(didn't read the rest of the code, there may be other problems, like hours not taking an e)
Now that it's inside the process, you need to rename minutes_total as minute_source, else you're incrementing the value only for the one clock cycle when you have a button edge!

VHDL - Index out range even If I made concurrent checking using when-else

I'm implementing a register file where I wanna read asynchronously and write on the rising edge.
I made concurrent checks on the addresses and the writing occurs inside a process.
However, it always cause me a fatal error and I don't know why!
Here's my code if anyone could help and tell me how can I read asynchronously and write on rising edge
Thank you!
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity RegFile is
port(
outData1 : out std_logic_vector(15 downto 0);
outData2 : out std_logic_vector(15 downto 0);
inData : in std_logic_vector(15 downto 0);
writeEn : in std_logic;
reg1Sel : in std_logic_vector(2 downto 0);
reg2Sel : in std_logic_vector(2 downto 0);
writeRegSel : in std_logic_vector(2 downto 0);
clk : in std_logic
);
end RegFile;
architecture Register_File of RegFile is
type registerFile is array(0 to 5) of std_logic_vector(15 downto 0);
signal registers : registerFile;
signal reg1Address,reg2Address : integer;
signal reg1FinalAddressing,reg2FinalAddressing : std_logic_vector(2 downto 0);
begin
--Conversion of logic vector to unsigned integer
reg1Address <= to_integer(unsigned(reg1Sel));
reg2Address <= to_integer(unsigned(reg2Sel));
reg1FinalAddressing <= reg1Sel when (reg1Address<6 ) else
(others => '0');
reg2FinalAddressing <= reg2Sel when (reg2Address<6 ) else
(others => '0');
outData1 <= registers(to_integer(unsigned(reg1FinalAddressing)));
outData2 <= registers(to_integer(unsigned(reg2FinalAddressing)));
process (clk) is
begin
-- Reading from Registers 1 and 2
if rising_edge(clk) then
-- Writing to Register file Case Enabled
if writeEn = '1' then
registers(to_integer(unsigned(writeRegSel))) <= inData;
-- Case a value being written to register file, it will be out simultaneously if
-- the register was already selected. (The updated values are being released instantly).
if reg1Sel = writeRegSel then
outData1 <= inData;
end if;
if reg2Sel = writeRegSel then
outData2 <= inData;
end if;
end if;
end if;
end process;
end Register_File;

Bundle statements in VHDL

How can I combine/bundle statements for further use and better handling? For example some assignments like this which would be used many times more in future calls of the routine.
ADDR_PC <= "0000000000";
ADDR_OP_A <= "00000";
ADDR_OP_B <= "00000";
OP_CODE <= OP_NOP;
OP_IMMED <= IMMED_NULL;
WE_SREG <= "00000"; -- S V N C Z
Into something like this.
NOP = {ADDR_PC <= "00000000", ADDR_OP_A <= "00000", ...}
I don't know if there are any possibilities to do that in VHDL. Any tip would be helpful.
Records and/or aggregates:
library ieee;
use ieee.std_logic_1164.all;
entity op_decoded is
end entity;
architecture foo of op_decoded is
-- These declarations probably want to be in a package
constant IMMED_NULL: std_logic_vector (8 downto 0) := (others => '0');
constant OP_NOP: std_logic_vector (5 downto 0) := (others => '0');
type decode_op is
record
PC: std_logic_vector (7 downto 0);
OP_A: std_logic_vector (4 downto 0);
OP_B: std_logic_vector (4 downto 0);
OP_CODE: std_logic_vector (5 downto 0);
OP_IMMED: std_logic_vector (8 downto 0);
WE_SREG: std_logic_vector (4 downto 0); -- S V N C Z
end record;
constant NOP: decode_op := (
PC => "00000000",
OP_A => "00000",
OP_B => "00000",
OP_CODE => OP_NOP,
OP_IMMED => IMMED_NULL,
WE_SREG => "00000"
);
-- actual signals
signal ADDR_PC: std_logic_vector (7 downto 0);
signal ADDR_OP_A: std_logic_vector (4 downto 0);
signal ADDR_OP_B: std_logic_vector (4 downto 0);
signal OP_CODE: std_logic_vector (5 downto 0);
signal OP_IMMED: std_logic_vector (8 downto 0);
signal WE_SREG: std_logic_vector (4 downto 0);
signal pipe1: decode_op;
signal pipe_disc: decode_op;
begin
(ADDR_PC, ADDR_OP_A, ADDR_OP_B, OP_CODE, OP_IMMED, WE_SREG) <= NOP;
pipe1 <= NOP;
pipe_disc <= (pipe1.PC, pipe1.OP_A, pipe1.OP_B, pipe1.OP_CODE,
pipe1.OP_IMMED, pipe1.WE_SREG);
end architecture;
This analyzes, elaborates and simulates (showing it's syntactically and semantically correct).
There's also an aggregate target with an aggregate right hand side (with the type provided):
(ADDR_PC, ADDR_OP_A, ADDR_OP_B, OP_CODE, OP_IMMED, WE_SREG) <=
decode_op'(pipe1.PC, pipe1.OP_A, pipe1.OP_B, pipe1.OP_CODE,
pipe1.OP_IMMED, pipe1.WE_SREG);
VHDL has records (C calls it struct).
Declaration example:
type T_MY_RECORD is record
Member1 : STD_LOGIC;
Member2 : STD_LOGIC_VECTOR(15 downto 0);
end record;
signal mySignal1 : T_MY_RECORD;
signal mySignal2 : T_MY_RECORD;
Usage examples:
mySignal1 <= (
Member1 => '1',
Member2 => x"12FC"
);
mySignal2.Member1 <= '0';
Records can be nested, e.g. for the flags.
Records and/or aggregates are one possibility, but and alternative is to declare a procedure in the process where the signals are driven, and then call the procedure, like:
process (clk_i) is
procedure NOP is
begin
ADDR_PC <= "0000000000";
ADDR_OP_A <= "00000";
ADDR_OP_B <= "00000";
OP_CODE <= OP_NOP;
OP_IMMED <= IMMED_NULL;
WE_SREG <= "00000"; -- S V N C Z
end procedure;
begin
if rising_edge(clk_i) then
...
NOP;
...
end if;
end process;
This work both for simulation and synthesizable code.

Adding Even Parity bit and 2 stop bits to a 8 bits std_logic_vector

Here is the code: In this the calculation for the parity bit is not done. Parity bit can be calculated using the for loop but is there any other short or better way to calculate the even parity bit in this context.
Is it somehow possible to use arrays instead of 8 TxDataReg std_logic_vector considering that after making arrays I wish to access bit by bit the array of 8 signals of 8 bits, bit by bit for sending the data in the uart_tx port?
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
use IEEE.STD_LOGIC_SIGNED.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.NUMERIC_STD.ALL;
entity Uart_tx is
Port (
tx_clk_in : in STD_LOGIC;
reset : in STD_LOGIC;
tx : out STD_LOGIC;
Rx_Data_in : in STD_LOGIC_VECTOR(63 downto 0)
);
end Uart_tx;
architecture Behavioral of Uart_tx is
signal Tx_Data : STD_LOGIC_VECTOR(63 downto 0) := "00000000";
signal DataByteArray1 : std_logic_vector(7 downto 0) := (others => "00000000");
signal DataByteArray2 : std_logic_vector(7 downto 0) := (others => "00000000");
signal DataByteArray3 : std_logic_vector(7 downto 0) := (others => "00000000");
signal DataByteArray4 : std_logic_vector(7 downto 0) := (others => "00000000");
signal DataByteArray5 : std_logic_vector(7 downto 0) := (others => "00000000");
signal DataByteArray6 : std_logic_vector(7 downto 0) := (others => "00000000");
signal DataByteArray7 : std_logic_vector(7 downto 0) := (others => "00000000");
signal DataByteArray8 : std_logic_vector(7 downto 0) := (others => "00000000");
signal TxDataReg1 : std_logic_vector(10 downto 0) := (others => "00000000");
signal TxDataReg2 : std_logic_vector(10 downto 0) := (others => "00000000");
signal TxDataReg3 : std_logic_vector(10 downto 0) := (others => "00000000");
signal TxDataReg4 : std_logic_vector(10 downto 0) := (others => "00000000");
signal TxDataReg5 : std_logic_vector(10 downto 0) := (others => "00000000");
signal TxDataReg6 : std_logic_vector(10 downto 0) := (others => "00000000");
signal TxDataReg7 : std_logic_vector(10 downto 0) := (others => "00000000");
signal TxDataReg8 : std_logic_vector(10 downto 0) := (others => "00000000");
signal count : unsigned(2 downto 0) := (others => '0');
signal one_bit : std_logic := '0';
begin
Tx_Data <= Rx_Data_in;
DataByteArray1 <= Rx_Data_in(7 downto 0);
DataByteArray2 <= Rx_Data_in(15 downto 8);
DataByteArray3 <= Rx_Data_in(23 downto 16);
DataByteArray4 <= Rx_Data_in(31 downto 24);
DataByteArray5 <= Rx_Data_in(39 downto 32);
DataByteArray6 <= Rx_Data_in(47 downto 40);
DataByteArray7 <= Rx_Data_in(55 downto 48);
DataByteArray8 <= Rx_Data_in(63 downto 56);
Process (tx_clk_in)
begin
-- Calculate the parity bit
for i in 0 to 7 loop
one_bit = DataByteArray1(i);
if one_bit = '1' then
count = count + 1;
end if;
end loop;
-- For all the registers,one even parity & two stop bits I am trying to add in the end
if count mod 2 = 0 then
TxDataReg1 <= DataByteArray1&'0'&'11'; -- I am not so sure that this works or not
count <= "000";
else
TxDataReg1 <= DataByteArray1&'1'&'11';
count <= "000";
end if;
-- Send the uart data from TxDataReg1,TxDataReg2 ...
-- etc.
end process;
end behavioral;
This UART would be much easier to understand if you created a State Machine. State Machines give your code an organized flow. The flow just makes more sense. In VHDL you can create enumerated states which means that you can give them names. I recommend this approach.
It's much harder to keep counters throughout your design to know exactly when to insert the parity bit or when to insert the 2 stop bits in your UART design. If you have a nice state machine it will make much more sense to you I believe. This is especially recommended for anyone new at FPGAs.
When you calculate your parity, just keep a running parity bit that gets an XOR with the outgoing serial data. Create a state to insert your parity bit at the correct time, then insert your two stop bits.
For an example of this, look at this UART VHDL Code
I would second the suggestion to reorganize this to use an FSM that works on just a byte at a time. Then you will have a general purpose async. TX entity that another controller can send bytes to as needed.
As to managing your data. It would be simpler if you created an array of byte arrays:
subtype byte is std_logic_Vector(7 downto 0);
type byte_array is array(natural range <>) of byte;
signal data_byte_array : byte_array(1 to 8);
signal byte_index : unsigned(2 downto 0);
...
-- Select the current byte
cur_byte <= data_byte_array(to_integer(byte_index));
The subtype isn't strictly necessary but it is a good habit to use for common data types to save you from littering your code with so many hard-coded array bounds.
For calculating parity you need to adopt the hardware mindset of implementing logic gates rather than the software approach of counting set bits. Parity calculation boils down to an XOR-reduce operation applied to all the bits in your vector. For even parity, you XOR all bits. For odd parity, you XOR all bits and invert the result. Because XOR is equivalent to a controlled inversion you can select the parity type by setting an initial state and performing one extra XOR to get the optional inversion based on your desire for odd or even.
-- Any VHDL:
variable parity : std_logic;
parity := '0'; -- Set to '1' to get odd parity
for i in cur_byte'range loop
parity := parity xor cur_byte(i);
end loop;
-- VHDL-2002
use ieee.reduce_pack.xor_reduce;
parity := xor_reduce(cur_byte);
-- VHDL-2008
parity := xor cur_byte;
In synthesis these approaches all boil down to the same logic so any of them is fine for all practical purposes. This is an explicitly parallel operation and you don't have to step through the byte bitwise with the unneeded overhead of a counter.
You have committed a cardinal sin of mixing the non-standard Synopsys libraries std_logic_unsigned, _signed, and _arith with the true standard numeric library numeric_std. Never mix them in the same file and, better yet, never use the Synopsys libraries at all. They are a historical aberration best forgotten.

Resources