compare and sort in VHDL - sorting

this is a code for sorting 4 element in VHDL:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity COMPARE_2 is
PORT(
clock :in STD_LOGIC:='0';
En :in STD_LOGIC:='0';
AA1 :buffer STD_LOGIC_VECTOR(7 DOWNTO 0);
AA2 :buffer STD_LOGIC_VECTOR(7 DOWNTO 0);
AA3 :buffer STD_LOGIC_VECTOR(7 DOWNTO 0);
AA4 :buffer STD_LOGIC_VECTOR(7 DOWNTO 0);
Q1 :OUT STD_LOGIC_VECTOR(7 DOWNTO 0);
Q2 :OUT STD_LOGIC_VECTOR(7 DOWNTO 0);
Q3 :OUT STD_LOGIC_VECTOR(7 DOWNTO 0);
Q4 :OUT STD_LOGIC_VECTOR(7 DOWNTO 0)
);
end COMPARE_2;
architecture Behavioral of COMPARE_2 is
signal A1 : STD_LOGIC_VECTOR(7 DOWNTO 0):=x"09";
signal A2 : STD_LOGIC_VECTOR(7 DOWNTO 0):=x"09";
signal A3 : STD_LOGIC_VECTOR(7 DOWNTO 0):=x"09";
signal A4 : STD_LOGIC_VECTOR(7 DOWNTO 0):=x"09";
begin
A1<=AA1;
A2<=AA2;
A3<=AA3;
A4<=AA4;
process(clock)
begin
if(clock'event and clock ='1') then
if( En='1') then
if (A1 >= A2 AND A1 >= A3 AND A1 >= A4) then Q1 <= A1;
elsif (A2 >= A3 AND A2 >= A4 AND A2 >= A1) then Q1 <= A2;
elsif( A3 >= A2 AND A3 >= A4 AND A3 >= A1) then Q1 <= A3;
elsif( A4 >= A3 AND A4 >= A2 AND A4 >= A1) then Q1 <= A4;
end if;
if ((A1 <= A2 AND A1 >= A3 AND A1 >= A4 ) OR (A1 >= A2 AND A1 <= A3 AND A1 >= A4) OR (A1 >= A2 AND A1 >= A3 AND A1 <= A4) ) then Q2 <= A1;
elsif ((A2 <= A1 AND A2 >= A3 AND A2 >= A4 ) OR (A2 >= A1 AND A2 <= A3 AND A2 >= A4) OR (A2 >= A1 AND A2 >= A3 AND A2 <= A4)) then Q2 <= A2;
elsif ((A3 <= A1 AND A3 >= A2 AND A3 >= A4 ) OR (A3 >= A1 AND A3 <= A2 AND A3 >= A4) OR (A3 >= A1 AND A3 >= A2 AND A3 <= A4)) then Q2 <= A3;
elsif ((A4 <= A1 AND A4 >= A2 AND A4 >= A3 ) OR (A4 >= A1 AND A4 <= A2 AND A4 >= A3) OR (A4 >= A1 AND A4 >= A2 AND A4 <= A3)) then Q2 <= A4;
end if;
if ((A1 <= A2 AND A1 <= A3 AND A1 >= A4 ) OR (A1 >= A2 AND A1 <= A3 AND A1 <= A4) OR (A1 <= A2 AND A1 >= A3 AND A1 <= A4)) then Q3 <= A1;
elsif ((A2 <= A1 AND A2 <= A3 AND A2 >= A4 ) OR (A2 >= A1 AND A2 <= A3 AND A2 <= A4) OR (A2 <= A1 AND A2 >= A3 AND A2 <= A4)) then Q3 <= A2;
elsif ((A3 <= A1 AND A3 <= A2 AND A3 >= A4 ) OR (A3 >= A1 AND A3 <= A2 AND A3 <= A4) OR (A3 <= A1 AND A3 >= A2 AND A3 <= A4)) then Q3 <= A3;
elsif ((A4 <= A1 AND A4 <= A2 AND A4 >= A3 ) OR (A4 >= A1 AND A4 <= A2 AND A4 <= A3) OR (A4 <= A1 AND A4 >= A2 AND A4 <= A3)) then Q3 <= A4;
end if;
if (A1 <= A2 AND A1 <= A3 AND A1 <= A4 )then Q4 <= A1;
elsif ( A2 <= A3 AND A2 <= A4 AND A2 <= A1) then Q4 <= A2;
elsif( A3 <= A4 AND A3 <= A2 AND A3 <= A1 )then Q4 <= A3;
elsif( A4 <= A3 AND A4 <= A2 AND A4 <= A1 )then Q4 <= A4;
end if;
end if;
end if;
end process;
end Behavioral;
and this is another code:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity COMPARE_2 is
PORT(
clock :in STD_LOGIC;
En :in STD_LOGIC:='0';
A1 :in STD_LOGIC_VECTOR(7 DOWNTO 0):=x"FF";
A2 :in STD_LOGIC_VECTOR(7 DOWNTO 0):=x"FF";
A3 :in STD_LOGIC_VECTOR(7 DOWNTO 0):=x"FF";
A4 :in STD_LOGIC_VECTOR(7 DOWNTO 0):=x"FF";
Q1 :OUT STD_LOGIC_VECTOR(7 DOWNTO 0):=x"FF";
Q2 :OUT STD_LOGIC_VECTOR(7 DOWNTO 0):=x"FF";
Q3 :OUT STD_LOGIC_VECTOR(7 DOWNTO 0):=x"FF";
Q4 :OUT STD_LOGIC_VECTOR(7 DOWNTO 0):=x"FF";
done :OUT STD_LOGIC:='0'
);
end COMPARE_2;
architecture Behavioral of COMPARE_2 is
type Com2StateMachine is (C2_start,C2_sort1,C2_sort2,C2_sort3,C2_sort4,C2_done);
signal Com2State : Com2StateMachine:=C2_start;
begin
process(clock)
begin
if(clock'event and clock ='1') then
c2case: case Com2State is
when C2_start =>
if( En='1') then
Com2State <= C2_sort1;
end if;
when C2_sort1 =>
if (A1 >= A2 AND A1 >= A3 AND A1 >= A4) then Q1 <= A1;
elsif (A2 >= A3 AND A2 >= A4 AND A2 >= A1) then Q1 <= A2;
elsif( A3 >= A2 AND A3 >= A4 AND A3 >= A1) then Q1 <= A3;
elsif( A4 >= A3 AND A4 >= A2 AND A4 >= A1) then Q1 <= A4;
end if;
Com2State <= C2_sort2;
when C2_sort2 =>
if ((A1 <= A2 AND A1 >= A3 AND A1 >= A4 ) OR (A1 >= A2 AND A1 <= A3 AND A1 >= A4) OR (A1 >= A2 AND A1 >= A3 AND A1 <= A4) ) then Q2 <= A1;
elsif ((A2 <= A1 AND A2 >= A3 AND A2 >= A4 ) OR (A2 >= A1 AND A2 <= A3 AND A2 >= A4) OR (A2 >= A1 AND A2 >= A3 AND A2 <= A4)) then Q2 <= A2;
elsif ((A3 <= A1 AND A3 >= A2 AND A3 >= A4 ) OR (A3 >= A1 AND A3 <= A2 AND A3 >= A4) OR (A3 >= A1 AND A3 >= A2 AND A3 <= A4)) then Q2 <= A3;
elsif ((A4 <= A1 AND A4 >= A2 AND A4 >= A3 ) OR (A4 >= A1 AND A4 <= A2 AND A4 >= A3) OR (A4 >= A1 AND A4 >= A2 AND A4 <= A3)) then Q2 <= A4;
end if;
Com2State <= C2_sort3;
when C2_sort3 =>
if ((A1 <= A2 AND A1 <= A3 AND A1 >= A4 ) OR (A1 >= A2 AND A1 <= A3 AND A1 <= A4) OR (A1 <= A2 AND A1 >= A3 AND A1 <= A4)) then Q3 <= A1;
elsif ((A2 <= A1 AND A2 <= A3 AND A2 >= A4 ) OR (A2 >= A1 AND A2 <= A3 AND A2 <= A4) OR (A2 <= A1 AND A2 >= A3 AND A2 <= A4)) then Q3 <= A2;
elsif ((A3 <= A1 AND A3 <= A2 AND A3 >= A4 ) OR (A3 >= A1 AND A3 <= A2 AND A3 <= A4) OR (A3 <= A1 AND A3 >= A2 AND A3 <= A4)) then Q3 <= A3;
elsif ((A4 <= A1 AND A4 <= A2 AND A4 >= A3 ) OR (A4 >= A1 AND A4 <= A2 AND A4 <= A3) OR (A4 <= A1 AND A4 >= A2 AND A4 <= A3)) then Q3 <= A4;
end if;
Com2State <= C2_sort4;
when C2_sort4 =>
if (A1 <= A2 AND A1 <= A3 AND A1 <= A4 )then Q4 <= A1;
elsif ( A2 <= A3 AND A2 <= A4 AND A2 <= A1) then Q4 <= A2;
elsif( A3 <= A4 AND A3 <= A2 AND A3 <= A1 )then Q4 <= A3;
elsif( A4 <= A3 AND A4 <= A2 AND A4 <= A1 )then Q4 <= A4;
end if;
Com2State <= C2_done;
when C2_done =>
done<='1';
if (En='0') then
Com2State <= C2_start;
end if;
end case c2case;
end if;
end process;
end Behavioral;
and this is another code:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity COMPARE_2 is
PORT(
clock :in STD_LOGIC;
En :in STD_LOGIC:='0';
A1 :in STD_LOGIC_VECTOR(7 DOWNTO 0):=x"FF";
A2 :in STD_LOGIC_VECTOR(7 DOWNTO 0):=x"FF";
A3 :in STD_LOGIC_VECTOR(7 DOWNTO 0):=x"FF";
A4 :in STD_LOGIC_VECTOR(7 DOWNTO 0):=x"FF";
Q1 :OUT STD_LOGIC_VECTOR(7 DOWNTO 0):=x"FF";
Q2 :OUT STD_LOGIC_VECTOR(7 DOWNTO 0):=x"FF";
Q3 :OUT STD_LOGIC_VECTOR(7 DOWNTO 0):=x"FF";
Q4 :OUT STD_LOGIC_VECTOR(7 DOWNTO 0):=x"FF";
done :OUT STD_LOGIC:='0'
);
end COMPARE_2;
architecture Behavioral of COMPARE_2 is
type ArrVec4 is array (0 to 3) of std_logic_vector(7 downto 0);
function sort(data : ArrVec4) return ArrVec4 is
variable tmp: ArrVec4;
variable tmp2: std_logic_vector(7 downto 0);
begin
l0: for k in 0 to 3 loop
tmp(k):=data(k);
end loop l0;
l1: for i in 0 to 2 loop
l2: for j in i+1 to 3 loop
if(tmp(i) >= tmp(j)) then
tmp2 := tmp(j);
tmp(j) := tmp(i);
tmp(i) := tmp2;
end if;
end loop l2;
end loop l1;
return tmp;
end sort;
--SIGNALS:
signal i: ArrVec4;
signal oVec : ArrVec4;
type Com2StateMachine is (C2_start,C2_sort1,C2_sort2,C2_sort3,C2_done);
signal Com2State : Com2StateMachine:=C2_start;
begin
process(clock)
begin
if(clock'event and clock ='1') then
c2case: case Com2State is
when C2_start =>
if( En='1') then
Com2State <= C2_sort1;
end if;
when C2_sort1 =>
i(0) <= A1;
i(1) <= A2;
i(2) <= A3;
i(3) <= A4;
Com2State <= C2_sort2;
when C2_sort2 =>
oVec <= sort(i);
Com2State <= C2_sort3;
when C2_sort3 =>
Q4 <= oVec(3);
Q3 <= oVec(2);
Q2 <= oVec(1);
Q1 <= oVec(0);
Com2State <= C2_done;
when C2_done =>
done<='1';
if (En='0') then
Com2State <= C2_start;
end if;
end case c2case;
end if;
end process;
end Behavioral;
all of these three codes is sequential code but we know compare and sort doesn't need "clock" , I wrote another code with "WHEN" in concurrence... and all of this code work in simulation right and my clock speed in Xillinx Spartan3 is 30 MHz and ISE say that I can have 59 Mhz Clock speed for this code. it works even when I wrote a test component with using UART, but when I use this codes in my simple component about Median Filter and in large number of calculation. it doesn't work but when I use a sort code that do Sorting in 8 clock, I give answer.
I need to mention that I instance this component in this code for use 2 , 4 byte sort for calculating median of 8 element:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity COMPARE_8 is
PORT(
clock :IN std_logic:='0';
en :IN std_logic:='0';
A1 :IN STD_LOGIC_VECTOR(7 DOWNTO 0);
A2 :IN STD_LOGIC_VECTOR(7 DOWNTO 0);
A3 :IN STD_LOGIC_VECTOR(7 DOWNTO 0);
A4 :IN STD_LOGIC_VECTOR(7 DOWNTO 0);
A5 :IN STD_LOGIC_VECTOR(7 DOWNTO 0);
A6 :IN STD_LOGIC_VECTOR(7 DOWNTO 0);
A7 :IN STD_LOGIC_VECTOR(7 DOWNTO 0);
A8 :IN STD_LOGIC_VECTOR(7 DOWNTO 0);
Q4 :OUT STD_LOGIC_VECTOR(7 DOWNTO 0);
Q5 :OUT STD_LOGIC_VECTOR(7 DOWNTO 0);
done :OUT std_logic:='0'
);
end COMPARE_8;
architecture Behavioral of COMPARE_8 is
COMPONENT COMPARE_2
PORT(
clock : IN std_logic;
En : IN std_logic:='0';
A1 : in std_logic_vector(7 downto 0);
A2 : in std_logic_vector(7 downto 0);
A3 : in std_logic_vector(7 downto 0);
A4 : in std_logic_vector(7 downto 0);
Q1 : OUT std_logic_vector(7 downto 0);
Q2 : OUT std_logic_vector(7 downto 0);
Q3 : OUT std_logic_vector(7 downto 0);
Q4 : OUT std_logic_vector(7 downto 0);
done :OUT STD_LOGIC:='0'
);
END COMPONENT;
for All: COMPARE_2 use entity WORK.COMPARE_2(Behavioral);
type ComStateMachine is (C_start,C_sort,C_wait,C_done);
signal ComState : ComStateMachine:=C_start;
--SIGNALS:
SIGNAL i1:STD_LOGIC_VECTOR(7 DOWNTO 0):=x"05";
SIGNAL i2:STD_LOGIC_VECTOR(7 DOWNTO 0):=x"05";
SIGNAL i3:STD_LOGIC_VECTOR(7 DOWNTO 0):=x"05";
SIGNAL i4:STD_LOGIC_VECTOR(7 DOWNTO 0):=x"05";
SIGNAL i5:STD_LOGIC_VECTOR(7 DOWNTO 0):=x"05";
SIGNAL i6:STD_LOGIC_VECTOR(7 DOWNTO 0):=x"05";
SIGNAL i7:STD_LOGIC_VECTOR(7 DOWNTO 0):=x"05";
SIGNAL i8:STD_LOGIC_VECTOR(7 DOWNTO 0):=x"05";
SIGNAL O1:STD_LOGIC_VECTOR(7 DOWNTO 0):=x"07";
SIGNAL O2:STD_LOGIC_VECTOR(7 DOWNTO 0):=x"07";
SIGNAL O3:STD_LOGIC_VECTOR(7 DOWNTO 0):=x"06";
SIGNAL O4:STD_LOGIC_VECTOR(7 DOWNTO 0):=x"06";
SIGNAL O5:STD_LOGIC_VECTOR(7 DOWNTO 0):=x"06";
SIGNAL O6:STD_LOGIC_VECTOR(7 DOWNTO 0):=x"06";
SIGNAL O7:STD_LOGIC_VECTOR(7 DOWNTO 0):=x"06";
SIGNAL O8:STD_LOGIC_VECTOR(7 DOWNTO 0):=x"06";
signal enSort:STD_LOGIC:='0';
signal doSort1:STD_LOGIC:='0';
signal doSort2:STD_LOGIC:='0';
signal clk:STD_LOGIC:='0';
begin
Inst1_COMPARE_2: COMPARE_2 PORT MAP(
clock => clk,
En => enSort,
A1 => i1,
A2 => i2,
A3 => i3,
A4 => i4,
Q1 => O1,
Q2 => O2,
Q3 => O3,
Q4 => O4,
done => doSort1
);
Inst2_COMPARE_2: COMPARE_2 PORT MAP(
clock => clk,
En => enSort,
A1 => i5,
A2 => i6,
A3 => i7,
A4 => i8,
Q1 => O5,
Q2 => O6,
Q3 => O7,
Q4 => O8,
done => doSort2
);
clk<= clock;
process(clock)
begin
if( clock'event and clock='1' ) then
c0Case: case ComState is
when C_start =>
done<='0';
if(En = '1') then
i1<=A1;
i2<=A2;
i3<=A3;
i4<=A4;
i5<=A5;
i6<=A6;
i7<=A7;
i8<=A8;
-- i1<=x"09";
-- i2<=x"02";
-- i3<=x"03";
-- i4<=x"06";
-- i5<=x"2b";
-- i6<=x"1a";
-- i7<=x"0c";
-- i8<=x"01";
ComState <= C_sort;
end if;
when C_sort =>
enSort<='1';
ComState <= C_wait;
when C_wait =>
if(doSort1='1' and doSort2='1') then
enSort<='0';
if( O5 <= O4 ) then
Q4 <= O4;
Q5 <= O5;
end if;
if( O6 <= O3 AND O6 >= O4 ) then
Q5 <= O6;
end if;
if( O7 <= O2 AND O7 >= O3) then
Q5 <= O7;
end if;
if( O8 <= O1 AND O8 >= O2)then
Q5 <=O8;
end if;
if(O1 <= O8 )then
Q5 <= O1;
end if;
if( O2 <= O7 AND O2 >= O8)then
Q5 <=O2;
end if;
if( O3 <= O6 AND O3 >= O7)then
Q5 <=O3;
end if;
if(O4 <= O5 AND O4 >= O6)then
Q5 <=O4 ;
end if;
if( O5 <= O3 AND O5 >= O4) then
Q4 <= O5;
end if;
if( O6 <= O2 AND O6 >= O3)then
Q4 <= O6;
end if;
if(O7 <= O1 AND O7 >= O2 )then
Q4 <= O7;
end if;
if( O8 >= O1) then
Q4 <= O8;
end if;
if( O1 <= O7 AND O1 >= O8 )then
Q4 <= O1;
end if;
if( O2 <= O6 AND O2 >= O7) then
Q4 <= O2;
end if;
if(O3 <= O5 AND O3 >= O6)then
Q4 <= O3;
end if;
-- if(O3 <= O7 AND O3 >= O8)then
-- Q4 <= O4;
-- end if;
ComState <= C_done;
end if;
when C_done =>
done<='1';
if(En='0')then
ComState <= C_start;
end if;
end case c0Case;
end if;
end process;
end Behavioral;
now I don't know why I can't use concurrence sorting with "when" and all of this codes run fine in simulation and can run maximum 59 Mhz and I have 30 Mhz clock?
"I gave that random default values for debugging my code"

The problem is inside of great equal
(>=)
or less equal
(<=)
just change the operators' conditions to > or <
and just use >= or <= once for each statement.

To sort 4 elements in hardware, you might consider using a sorting network, wiki article:
http://en.wikipedia.org/wiki/Sorting_network
In this case, 5 if / swap sequence:
if (a[0] > a[2]) { swap(a[0], a[2]); }
if (a[1] > a[3]) { swap(a[1], a[3]); }
if (a[0] > a[1]) { swap(a[0], a[1]); }
if (a[2] > a[3]) { swap(a[2], a[3]); }
if (a[1] > a[2]) { swap(a[1], a[2]); }

Related

7 4 Hamming decoder in xilinx (Shows warning "temp should be on the sensitivity list of process")

This is what I am implementing.
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity sammy_2018314405 is
Port ( codeword : in STD_LOGIC_VECTOR (6 downto 0);
syndrome : out STD_LOGIC_VECTOR (2 downto 0);
dataword : out STD_LOGIC_VECTOR (3 downto 0));
end sammy_2018314405;
architecture Behavioral of sammy_2018314405 is
signal s : std_logic_vector(2 downto 0);
signal b3, b2, b1, b0, q2, q1, q0 : std_logic;
signal temp : std_logic_vector(6 downto 0);
begin
b3 <= codeword(6);
b2 <= codeword(5);
b1 <= codeword(4);
b0 <= codeword(3);
q2 <= codeword(2);
q1 <= codeword(1);
q0 <= codeword(0);
s(0) <= b0 xor b1 xor b2 xor q0;
s(1) <= b1 xor b2 xor b3 xor q1;
s(2) <= b0 xor b1 xor b3 xor q2;
temp <= (b3,b2,b1,b0,q2,q1,q0);
process(s)
begin
case s is
when "001" => temp(0) <= not temp(0);
when "010" => temp(1) <= not temp(1);
when "011" => temp(5) <= not temp(5);
when "100" => temp(2) <= not temp(2);
when "101" => temp(3) <= not temp(3);
when "110" => temp(6) <= not temp(6);
when "111" => temp(4) <= not temp(4);
when others => null;
end case;
end process;
syndrome(2 downto 0) <= s(2 downto 0);
dataword(3 downto 0) <= temp(6 downto 3);
end Behavioral;
--I get warnings that show temp should be on the sensitivity list of process. I do not understand what does this means. I should get a result something like the picture below.
Result for the implementation

Error in Xilinx for case statement (case-when)

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity sammy_2018314405 is
Port ( codeword : in STD_LOGIC_VECTOR (6 downto 0);
syndrome : out STD_LOGIC_VECTOR (2 downto 0);
dataword : out STD_LOGIC_VECTOR (3 downto 0));
end sammy_2018314405;
architecture Behavioral of sammy_2018314405 is
signal s : std_logic_vector(2 downto 0);
signal b3, b2, b1, b0, q2, q1, q0 : std_logic;
signal temp : std_logic_vector(6 downto 0);
begin
b3 <= codeword(6);
b2 <= codeword(5);
b1 <= codeword(4);
b0 <= codeword(3);
q2 <= codeword(2);
q1 <= codeword(1);
q0 <= codeword(0);
s(0) <= b0 xor b1 xor b2 xor q0;
s(1) <= b1 xor b2 xor b3 xor q1;
s(2) <= b0 xor b1 xor b3 xor q2;
temp <= (b3,b2,b1,b0,q2,q1,q0);
--this part show error, can I put case in the middle of the code?
process(s)
begin
case s is
when "001" => temp(0) <= not temp(0);
when "010" => temp(1) <= not temp(1);
when "011" => temp(5) <= not temp(5);
when "100" => temp(2) <= not temp(2);
when "101" => temp(3) <= not temp(3);
when "110" => temp(6) <= not temp(6);
when "111" => temp(4) <= not temp(4);
when others => null;
end case;
end process;
syndrome(2 downto 0) <= s(2 downto 0);
dataword(3 downto 0) <= temp(6 downto 3);
end Behavioral;
Line 51: Net <temp[6]> is already driven by input port <codeword[6]>.
Net <temp[5]> is already driven by input port <codeword[5]>.
(This is code for 7 4 Hamming decoder.)
What should I do?

why does not compile a VHDL program

i tried to compile the following VHDL code but i got an error message:
LIBRARY ieee ;
USE ieee.std_logic_1164.all;
ENTITY testdoublemux IS
END testdoublemux;
ARCHITECTURE test_doublemux OF testdoublemux IS
SIGNAL A1,B1,D1 : std_logic_vector(2 downto 0); S1 : std_logic;
COMPONENT mux_double_2to1 port ( a,b: in std_logic_vector(2 downto 0); s : in std_logic; d : out std_logic_vector(2 downto 0) );
END COMPONENT;
BEGIN
M1: mux_double_2to1 PORT MAP ( a => A1 , b => B1 , s => S1 , d => D1 );
PROCESS
BEGIN
A1 <= '001'; B1 <= '010'; S1 <= '0'; wait for 20ps;
A1 <= '010'; B1 <= '100'; S1 <= '0'; wait for 20ps;
A1 <= '111'; B1 <= '011'; S1 <= '0'; wait for 20ps;
A1 <= '101'; B1 <= '111'; S1 <= '0'; wait for 20ps;
A1 <= '010'; B1 <= '001'; S1 <= '1'; wait for 20ps;
A1 <= '000'; B1 <= '101'; S1 <= '1'; wait for 20ps;
A1 <= '101'; B1 <= '010'; S1 <= '1'; wait for 20ps;
A1 <= '111'; B1 <= '101'; S1 <= '1'; wait for 20ps;
END PROCESS;
END test_doublemux;
The error message is:
** Error: D:\apps\modelsim starter edition\modelsim workspace\mux_doubletb.vhd(8): near "S1": (vcom-1576) expecting BEGIN.
The entity code is:
LIBRARY ieee ;
USE ieee.std_logic_1164.all;
ENTITY mux_double_2to1 is
PORT
(a, b: in std_logic_vector(2 downto 0);
s: in std_logic;
d: out std_logic_vector(2 downto 0)
);
END mux_double_2to1;
ARCHITECTURE dataflow3 OF mux_double_2to1 IS
BEGIN
d <= a WHEN s='0' ELSE b;
END dataflow3;

Why do I get "Found '0' definitions of operator "+"" when adding bit_vectors? Are Delta Delays a factor?

I'm in the process of coding a 3-bit ALU. The problem I'm running into is in the multiplier, when Opcode = "001". I'm trying to add 3 bit_vectors(5 downto 0), and it's throwing the error "Found '0' definitions of operator "+"". I've looked around and found some links found '0' definitions of operator "+" in VHDL, but adding any packages doesn't seem to fix the error for me.
Also, I read somewhere that since you're coding hardware in VHDL, it's wise to keep in mind delta delays. Since i'm assigning values to a signal in a process, will it actually work to output the final product? Or will the delta delays cause the signals to not be updated until the process is suspended.
The error occurs on line 67, "Z <= t4 + t5 + t6", in the block where Opcode = "001". Thank you to anyone who can give a little advice.
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity ALU is
PORT(
X,Y : IN BIT_VECTOR(2 downto 0);
Opcode : IN BIT_VECTOR(2 downto 0);
Z : OUT BIT_VECTOR(5 downto 0);
CLK : IN BIT
);
end ALU;
architecture Behavioral of ALU is
COMPONENT adder3 is
PORT (
A1 ,A2, A3, B1, B2, B3, Cin : IN BIT ;
Sum1 ,Sum2, Sum3, Cout : OUT BIT );
END COMPONENT;
SIGNAL adder_output: BIT_VECTOR(3 downto 0);
SIGNAL temp: BIT_VECTOR(2 downto 0);
SIGNAL t1,t2,t3: BIT_VECTOR(2 downto 0);
SIGNAL t4,t5,t6: BIT_VECTOR(5 downto 0);
begin
ADD3: adder3 PORT MAP(
A1 => X(0),
B1 => Y(0),
A2 => X(1),
B2 => Y(1),
A3 => X(2),
B3 => Y(2),
Cin => '0',
Sum1 => adder_output(0),
Sum2 => adder_output(1),
Sum3 => adder_output(2),
Cout => adder_output(3)
);
PROCESS(X, Y, CLK, Opcode)
BEGIN
IF(CLK'EVENT AND CLK='1')THEN
IF Opcode = "000" THEN
Z <= adder_output;
ELSIF Opcode = "001" THEN
IF Y(0) = '1' THEN
t1 <= X;
ELSE
t1 <= "000";
END IF;
IF Y(1) = '1' THEN
t2 <= X;
ELSE
t2 <= "000";
END IF;
IF Y(2) = '1' THEN
t3 <= X;
ELSE
t3 <= "000";
END IF;
t4 <= "000"&t1;
t5 <= "00"&t2&"0";
t6 <= "0"&t3&"00";
Z <= t4+t5+t6;
ELSIF Opcode = "010" THEN
Z <= X AND Y;
ELSIF Opcode = "011" THEN
Z <= X OR Y;
ELSIF Opcode = "100" THEN
Z <= X XOR Y;
ELSIF Opcode = "101" THEN
temp <= NOT X;
Z <= "000"&temp;
ELSIF Opcode = "110" THEN
IF Y = "000" THEN
Z <= "000"&X(2 downto 0);
ELSIF Y = "001" THEN
Z <= "00"&X(2 downto 0)&"0";
ELSIF Y = "010" THEN
Z <= "0"&X(2 downto 0)&"00";
ELSIF Y = "011" THEN
Z <= X(2 downto 0)&"000";
ELSIF Y = "100" THEN
Z <= X(1 downto 0)&"0000";
ELSIF Y = "101" THEN
Z <= X(0)&"00000";
ELSE
Z <= "000000";
END IF;
ELSE
IF Y = "000" THEN
Z <= "000"&X(2 downto 0);
ELSIF Y = "001" THEN
Z <= "0000"&X(2 downto 1);
ELSIF Y = "010" THEN
Z <= "00000"&X(2);
ELSE
Z <= "000000";
END IF;
END IF;
END IF;
END PROCESS;
end Behavioral;
If you want to do unsigned arithmetic with bit_vector, you need to use the numeric_bit_unsigned library that is part of the VHDL 2008 spec. For signed arithmetic, you need to use unsigned or signed types from either numeric_std or numeric_bit (the only difference is the base type).

VHDL Loops - Program seem to use previous value

LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.NUMERIC_STD.ALL;
ENTITY WeightsUpdate IS
GENERIC ( n: INTEGER := 1;
m: INTEGER := 3;
b: INTEGER := 8);
PORT ( w0 : in SIGNED (b-1 DOWNTO 0);
w1 : in SIGNED (b-1 DOWNTO 0);
w2 : in SIGNED (b-1 DOWNTO 0);
y : in STD_LOGIC_VECTOR (b-1 DOWNTO 0);
x1 : in STD_LOGIC;
x2 : in STD_LOGIC;
d : in STD_LOGIC_VECTOR (b-1 DOWNTO 0);
up_w0 : out SIGNED (b-1 DOWNTO 0);
up_w1 : out SIGNED (b-1 DOWNTO 0);
up_w2 : out SIGNED (b-1 DOWNTO 0));
END WeightsUpdate;
ARCHITECTURE Behavioral OF WeightsUpdate IS
TYPE weights IS ARRAY (1 TO n*m) OF SIGNED(b-1 DOWNTO 0);
TYPE new_weights IS ARRAY (1 TO n*m) OF SIGNED(b-1 DOWNTO 0);
TYPE inputs IS ARRAY (1 TO m) OF SIGNED(b-1 DOWNTO 0);
TYPE outputs IS ARRAY (1 TO n) OF SIGNED(b-1 DOWNTO 0);
SIGNAL exp, act : SIGNED(b-1 DOWNTO 0);
BEGIN
PROCESS(w0, w1, w2, y, x1, x2, d)
VARIABLE weight: weights;
VARIABLE new_weight: new_weights;
VARIABLE input: inputs;
VARIABLE output: outputs;
VARIABLE error: SIGNED(b-1 DOWNTO 0);
VARIABLE delta_weight: SIGNED(2*b-1 DOWNTO 0);
BEGIN
input(1) := "0000000" & x1;
input(2) := "0000000" & x2;
input(3) := "11111111";
weight(1) := w1;
weight(2) := w2;
weight(3) := w0;
exp <= SIGNED(d);
act <= SIGNED(y);
error := exp - act;
L1: FOR i IN 1 TO m LOOP
delta_weight := input(i) * error;
new_weight(i) := weight(i) + delta_weight(b-1 DOWNTO 0);
END LOOP L1;
up_w0 <= new_weight(3);
up_w1 <= new_weight(1);
up_w2 <= new_weight(2);
END PROCESS;
END Behavioral;
Hi. Today I'm encountering a problem with above VHDL Code. It's a part of my NN and this module is responsible for updating the weights. It's done like:
d - expected_result
y - actual_result
error = expected_result - actual_result
new_weight = old_weight + (input * error)
Error is calculated once. I have 3 inputs to the neuron (one is bias so I set him for -1) and 3 weights (w0, w1, w2 - old_weights), one for every input so I'm doing the update in loop with 3 iterations. Below is the testbench:
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE IEEE.NUMERIC_STD.ALL;
ENTITY WeightsUpdateTB IS
END WeightsUpdateTB;
ARCHITECTURE behavior OF WeightsUpdateTB IS
-- Component Declaration for the Unit Under Test (UUT)
COMPONENT WeightsUpdate
PORT(
w0 : IN SIGNED(7 downto 0);
w1 : IN SIGNED(7 downto 0);
w2 : IN SIGNED(7 downto 0);
y : IN std_logic_vector(7 downto 0);
x1 : IN std_logic;
x2 : IN std_logic;
d : IN std_logic_vector(7 downto 0);
up_w0 : OUT SIGNED(7 downto 0);
up_w1 : OUT SIGNED(7 downto 0);
up_w2 : OUT SIGNED(7 downto 0)
);
END COMPONENT;
--Inputs
signal w0 : SIGNED(7 downto 0) := (others => '0');
signal w1 : SIGNED(7 downto 0) := (others => '0');
signal w2 : SIGNED(7 downto 0) := (others => '0');
signal y : std_logic_vector(7 downto 0) := (others => '0');
signal x1 : std_logic := '0';
signal x2 : std_logic := '0';
signal d : std_logic_vector(7 downto 0) := (others => '0');
--Outputs
signal up_w0 : SIGNED(7 downto 0);
signal up_w1 : SIGNED(7 downto 0);
signal up_w2 : SIGNED(7 downto 0);
BEGIN
-- Instantiate the Unit Under Test (UUT)
uut: WeightsUpdate PORT MAP (
w0 => w0,
w1 => w1,
w2 => w2,
y => y,
x1 => x1,
x2 => x2,
d => d,
up_w0 => up_w0,
up_w1 => up_w1,
up_w2 => up_w2
);
-- Stimulus process
stim_proc: process
begin
w0 <= "00000000";
w1 <= "00110000";
w2 <= "00110000";
y <= "00011111";
x1 <= '1';
x2 <= '1';
d <= "00100000";
wait for 100 ns;
w0 <= "00000000";
w1 <= "00110000";
w2 <= "00110000";
y <= "00011111";
x1 <= '0';
x2 <= '1';
d <= "00000000";
wait for 100 ns;
w0 <= "00000000";
w1 <= "00110000";
w2 <= "00110000";
y <= "00011111";
x1 <= '1';
x2 <= '0';
d <= "00000000";
wait for 100 ns;
w0 <= "00000000";
w1 <= "00110000";
w2 <= "00110000";
y <= "00011111";
x1 <= '1';
x2 <= '1';
d <= "00100000";
wait;
end process;
END;
And simulation:
Simulation
And the problem is that it seems like the error is calculated wrong. During the first set of inputs in simulation the error is 0 when it should be 1 and then in second set it's 1 when it should be equal to -31 and so on - looks like it takes value from previous set? The weights in first set should look like:
up_w0 = -1
up_w1 = 49
up_w2 = 49
And second set:
up_w0 = 31
up_w1 = 48
up_w2 = 17
Third:
up_w0 = 31
up_w1 = 17
up_w2 = 48
Fourth:
up_w0 = -1
up_w1 = 49
up_w2 = 49

Resources