在 VHDL 中进行比较和排序
compare and sort in VHDL
这是在 VHDL 中对 4 元素进行排序的代码:
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;
这是另一个代码:
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;
这是另一个代码:
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;
所有这三个代码都是顺序代码,但我们知道比较和排序不需要 "clock" ,我同时写了另一个代码 "WHEN" ...并且所有这些代码都有效在模拟中,我在 Xillinx Spartan3 中的时钟速度是 30 MHz,ISE 说我可以为这段代码提供 59 Mhz 的时钟速度。它甚至在我使用 UART 编写测试组件时也能正常工作,但是当我在我的关于中值滤波器的简单组件中使用此代码并进行大量计算时。它不起作用但是当我使用在 8 时钟进行排序的排序代码时,我给出了答案。
我需要提到的是,我在这段代码中实例化了这个组件,用于使用 2、4 字节排序来计算 8 个元素的中值:
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;
现在我不知道为什么我不能使用 "when" 的并发排序,所有这些代码 运行 在模拟中都很好并且可以 运行 最大 59 Mhz 和我有 30 Mhz 时钟吗?
"I gave that random default values for debugging my code"
要在硬件中对 4 个元素进行排序,您可以考虑使用排序网络,wiki 文章:
http://en.wikipedia.org/wiki/Sorting_network
在这种情况下,5 if / 交换序列:
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]); }
问题出在 great equal 里面
(>=)
或小于等于
(<=)
只需将运算符的条件更改为 > 或 <
每个语句只需使用 >= 或 <= 一次。
这是在 VHDL 中对 4 元素进行排序的代码:
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;
这是另一个代码:
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;
这是另一个代码:
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;
所有这三个代码都是顺序代码,但我们知道比较和排序不需要 "clock" ,我同时写了另一个代码 "WHEN" ...并且所有这些代码都有效在模拟中,我在 Xillinx Spartan3 中的时钟速度是 30 MHz,ISE 说我可以为这段代码提供 59 Mhz 的时钟速度。它甚至在我使用 UART 编写测试组件时也能正常工作,但是当我在我的关于中值滤波器的简单组件中使用此代码并进行大量计算时。它不起作用但是当我使用在 8 时钟进行排序的排序代码时,我给出了答案。 我需要提到的是,我在这段代码中实例化了这个组件,用于使用 2、4 字节排序来计算 8 个元素的中值:
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;
现在我不知道为什么我不能使用 "when" 的并发排序,所有这些代码 运行 在模拟中都很好并且可以 运行 最大 59 Mhz 和我有 30 Mhz 时钟吗?
"I gave that random default values for debugging my code"
要在硬件中对 4 个元素进行排序,您可以考虑使用排序网络,wiki 文章:
http://en.wikipedia.org/wiki/Sorting_network
在这种情况下,5 if / 交换序列:
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]); }
问题出在 great equal 里面
(>=)
或小于等于
(<=)
只需将运算符的条件更改为 > 或 < 每个语句只需使用 >= 或 <= 一次。