【问题标题】:compare and sort in VHDL在 VHDL 中进行比较和排序
【发布时间】:2015-12-24 20:26:50
【问题描述】:

这是在 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;

所有这三个代码都是顺序代码,但我们知道比较和排序不需要“时钟”,我同时编写了另一个带有“WHEN”的代码......所有这些代码都在模拟正确和我的时钟中工作Xilinx 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;

现在我不知道为什么我不能将并发排序与“何时”一起使用,而所有这些代码在模拟中运行良好,并且可以运行最大 59 Mhz 并且我有 30 Mhz 时钟?

“我为调试代码提供了随机默认值”

【问题讨论】:

  • 您向我们倾倒了大量代码,没有具体问题,也没有明确说明什么不起作用或证明它是如何失败的。我不会试图从这个问题中猜测你想要什么。
  • 排序结果不正确,先生,当您在图片的像素中计算和使用这种排序时。
  • 如果你不想回答我,为什么你说我的问题没有用?
  • 首先你还没有说这些类型中的哪一个有不正确的结果。他们都是?只是你没有给我们看的那个?那么你没有给我们任何关于“不正确”结果的细节。输出可能与输入相同。或全部 XXXX。或将带符号的数字视为无符号的。我不知道。当我反应不够快时,考虑到你的任性态度,我不再关心。
  • 没有。在模拟中它工作正常,当我在 fpga 上运行 3 或 4 次时。但有时它给了我不安全的答案,但我使用的顺序排序(使用 9 个时钟)总是正确的!

标签: sorting compare vhdl


【解决方案1】:

问题在于大同小异

(>=)

或小于等于

(


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

【讨论】:

    【解决方案2】:

    要对硬件中的 4 个元素进行排序,您可以考虑使用排序网络,wiki 文章:

    http://en.wikipedia.org/wiki/Sorting_network

    本例中,5个if/swap序列:

        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]); }
    

    【讨论】:

    • "if" 和 "swaping" 需要时钟,对吗?但是“排序”或“比较”不需要时钟。当我可以编写“Cencurrent 代码”时,为什么我应该编写“Sequential 代码”?!
    • @Prof.Hell - {a[0], a[2} 和 {a[1], a[3]} 操作可以在第一个周期并行完成。 {a[0], a[1} 和 {a[2], a[3]} 操作可以在第二个周期并行完成。这将 {a[1], a[2} 留给第三个循环。所以时间明智,它是 3 个周期。维基文章解释了这一点。
    • 感谢您的回答,但是:Q1 = A2 AND A1 >= A3 AND A1 >= A4) ELSE A2 WHEN (A2 >= A3 AND A2 >= A4 AND A2 > = A1) 否则 A3 何时(A3 >= A2 和 A3 >= A4 和 A3 >= A1)否则 A4;这是 Cencurrent 代码的一部分,可以用简单的门来制作。当您的输入发生变化时,您的输出会在门延迟后发生变化。不需要周期或时钟
    • 对于 Q2、Q3 和 Q4,你可以这样写。(将“if”转换为“when”)
    • @Prof.Hell - 有很多比较,还有四个最终作业(Q1 到 Q4),但它们都是并行的,所以虽然需要更多门,但速度更快,你只需要传播延迟。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-03
    • 1970-01-01
    相关资源
    最近更新 更多