在 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 里面

(>=)

或小于等于

(<=)


只需将运算符的条件更改为 >< 每个语句只需使用 >=<= 一次。