【问题标题】:Sorting network in VHDLVHDL中的排序网络
【发布时间】:2015-03-31 21:14:00
【问题描述】:

我正在编写一个基本程序来实现这个链接Network for N=5, using Bose-Nelson Algorithm中的排序算法。

我使用comb.vhd组件比较两个数字,我的程序的顶部实体在下面的代码中。

我用Quartus编译没有问题,但是用modelsim模拟RTL,不管输入是什么,输出总是0000。

我认为我误解了信号的使用,但我不知道哪里出错了。

以下是我程序的主要部分,我使用的信号是:

SIGNAL out0_temp, out1_temp, out3_temp, out4_temp               : bit_vector (3 downto 0); --comp1(0,1),comp2(3,4)
    SIGNAL out2_temp, out4_1_temp                                           : bit_vector (3 downto 0);  --comp3(2,4)
    SIGNAL out2_1_temp, out3_1_temp, out1_1_temp, out4_2_temp   : bit_vector (3 downto 0); --comp4(2,3),comp5(1,4)
    SIGNAL out0_1_temp, out3_2_temp                                     : bit_vector (3 downto 0); --comp6(0,3)
    SIGNAL out0_2_temp, out2_2_temp, out1_2_temp, out3_3_temp   : bit_vector (3 downto 0); --comp7(0,2),comp8(1,3)
    SIGNAL out1_3_temp, out2_3_temp                                     : bit_vector (3 downto 0); --comp9(1,2)

如算法所示,我使用 9 个比较来对输入从最大到最小进行排序,如下所示:

    BEGIN
comp1:comp -- (0,1)
PORT MAP (clk,reset, in0, in1, out0_temp, out1_temp);
comp2:comp -- (3,4)
PORT MAP (clk,reset, in3, in4, out3_temp, out4_temp);
comp3:comp -- (2,4)
PORT MAP (clk,reset, in2, out4_temp, out2_temp, out4_1_temp);
comp4:comp -- (2,3)
PORT MAP (clk,reset, out2_temp, out3_temp, out2_1_temp, out3_1_temp);
comp5:comp -- (1,4)
PORT MAP (clk,reset, out1_temp, out4_1_temp, out1_1_temp, out4_2_temp);
comp6:comp -- (0,3)
PORT MAP (clk,reset, out0_temp, out3_1_temp, out0_1_temp, out3_2_temp);
comp7:comp -- (0,2)
PORT MAP ( clk,reset, out0_1_temp, out2_1_temp, out0_2_temp, out2_2_temp);
comp8:comp -- (1,3)
PORT MAP ( clk,reset, out1_1_temp, out3_2_temp, out1_2_temp, out3_3_temp);
comp9:comp -- (1,2)
PORT MAP ( clk,reset, out1_2_temp, out2_2_temp, out1_3_temp, out2_3_temp);

out0 <= out0_2_temp;
out1 <= out1_3_temp;
out2 <= out2_3_temp;
out3 <= out3_3_temp;
out4 <= out4_2_temp;



END ARCHITECTURE behav;  

 Comp.vhd module

--Comp.vhd 模块用于比较两个数字,如果有则切换它们

LIBRARY ieee; 
USE     ieee.std_logic_1164.ALL; 
USE     ieee.std_logic_arith.ALL; 
USE     ieee.std_logic_unsigned.ALL;

ENTITY comp IS 
    PORT ( 
        clk         : IN std_logic;  
        reset       : IN bit; 

          num0_in     : IN bit_vector (3 DOWNTO 0); 
        num1_in     : IN bit_vector (3 DOWNTO 0); 

          num0_out    : OUT bit_vector (3 DOWNTO 0); 
        num1_out    : OUT bit_vector (3 DOWNTO 0)  
    ); 
END ENTITY comp;

ARCHITECTURE compare OF comp IS 
BEGIN 
    PROCESS (clk, reset) 
    BEGIN

        -- reset everything to '0' when reset is asserted 
        IF (reset = '1') THEN 
           -- num0_out <=  (OTHERS => '0'); 
            --num1_out <=  (OTHERS => '0'); 

        ELSIF (rising_edge (clk)) THEN 

                -- num0_in is smaller than num1_in, so switch them 
                IF (num0_in < num1_in) THEN 
                    num0_out <= num1_in; 
                    num1_out <= num0_in; 
                -- num0_in and num1_in are in order 
                ELSE 
                    num0_out <= num0_in; 
                    num1_out <= num1_in; 
                END IF;

        END IF; 
     END PROCESS; 
END ARCHITECTURE compare;

【问题讨论】:

  • 我认为答案可以提供的任何见解都需要您的更多代码,特别是对您的实例化comp的可见性。
  • 这是我的comp模块,它工作正常,我用modelsim模拟它,它给出了预期的结果:

标签: vhdl sorting-network


【解决方案1】:

好吧,看这里是问题所在。我使用了您的声明并创建了缺失的位,并在您发布 COMP.vhd 之前开始:

entity comp is
    port (
        clk:    in  bit;
        reset:  in  bit;
        in0:    in  bit_vector (3 downto 0);
        in1:    in  bit_vector (3 downto 0);  
        out0:   out bit_vector (3 downto 0);
        out1:   out bit_vector (3 downto 0)
    );
end entity;

architecture foo of comp is

begin
comparison:
    process (clk, reset)
        variable GT: bit;
    begin
        if in0 > in1 then
            GT := '1';
        else 
            GT := '0';
        end if;
        if reset = '1' then
            out0 <= (others => '0');
            out1 <= (others => '0');
        elsif clk'event and clk = '1' then
            if GT = '1' then
                out0 <= in0;
                out1 <= in1;
            else
                out0 <= in1;
                out1 <= in0;
            end if;
        end if;
    end process;
end architecture;


entity bose is
    port (
        clk:    in  bit;
        reset:  in  bit;
        in0:    in  bit_vector (3 downto 0);
        in1:    in  bit_vector (3 downto 0);
        in2:    in  bit_vector (3 downto 0);
        in3:    in  bit_vector (3 downto 0);
        in4:    in  bit_vector (3 downto 0);
        out0:   out bit_vector (3 downto 0);
        out1:   out bit_vector (3 downto 0);
        out2:   out bit_vector (3 downto 0);
        out3:   out bit_vector (3 downto 0);
        out4:   out bit_vector (3 downto 0)
    );
end entity;

architecture foo of bose is
    signal out0_temp, out1_temp, out3_temp, out4_temp: 
                    bit_vector (3 downto 0); --comp1(0,1),comp2(3,4)
    signal out2_temp, out4_1_temp: 
                    bit_vector (3 downto 0);  --comp3(2,4)
    signal out2_1_temp, out3_1_temp, out1_1_temp, out4_2_temp: 
                    bit_vector (3 downto 0); --comp4(2,3),comp5(1,4)
    signal out0_1_temp, out3_2_temp: 
                    bit_vector (3 downto 0); --comp6(0,3)
    signal out0_2_temp, out2_2_temp, out1_2_temp, out3_3_temp:
                    bit_vector (3 downto 0); --comp7(0,2),comp8(1,3)
    signal out1_3_temp, out2_3_temp:
                     bit_vector (3 downto 0); --comp9(1,2)
    component comp is
        port (
            clk:    in  bit;
            reset:  in  bit;
            in0:    in  bit_vector (3 downto 0);
            in1:    in  bit_vector (3 downto 0);  
            out0:   out bit_vector (3 downto 0);
            out1:   out bit_vector (3 downto 0)
        );
     end component;
begin
comp1:
    comp -- (0,1)
        port map (clk,reset, in0, in1, out0_temp, out1_temp);
comp2:
    comp -- (3,4)
        port map (clk,reset, in3, in4, out3_temp, out4_temp);
comp3:
    comp -- (2,4)
        port map (clk,reset, in2, out4_temp, out2_temp, out4_1_temp);
comp4:
    comp -- (2,3)
        port map (clk,reset, out2_temp, out3_temp, out2_1_temp, out3_1_temp);
comp5:
    comp -- (1,4)
        port map (clk,reset, out1_temp, out4_1_temp, out1_1_temp, out4_2_temp);
comp6:
    comp -- (0,3)
        port map (clk,reset, out0_temp, out3_1_temp, out0_1_temp, out3_2_temp);
comp7:
    comp -- (0,2)
        port map ( clk,reset, out0_1_temp, out2_1_temp, out0_2_temp, out2_2_temp);
comp8:
    comp -- (1,3)
        port map ( clk,reset, out1_1_temp, out3_2_temp, out1_2_temp, out3_3_temp);
comp9:
    comp -- (1,2)
        port map ( clk,reset, out1_2_temp, out2_2_temp, out1_3_temp, out2_3_temp);

    out0 <= out0_2_temp;
    out1 <= out1_3_temp;
    out2 <= out2_3_temp;
    out3 <= out3_3_temp;
    out4 <= out4_2_temp;
end architecture;

entity bose_tb is
end entity;

architecture foo of bose_tb is
    signal clk:    bit := '0';
    signal reset:  bit := '0';
    signal in0:    bit_vector (3 downto 0) := x"A";
    signal in1:    bit_vector (3 downto 0) := x"5";
    signal in2:    bit_vector (3 downto 0) := x"9";
    signal in3:    bit_vector (3 downto 0) := x"4";
    signal in4:    bit_vector (3 downto 0) := x"7";
    signal out0:   bit_vector (3 downto 0);
    signal out1:   bit_vector (3 downto 0);
    signal out2:   bit_vector (3 downto 0);
    signal out3:   bit_vector (3 downto 0);
    signal out4:   bit_vector (3 downto 0);
begin
DUT:
    entity work.bose
        port map (
            clk => clk,
            reset => reset,
            in0 => in0,
            in1 => in1,
            in2 => in2,
            in3 => in3,
            in4 => in4,
            out0 => out0,
            out1 => out1,
            out2 => out2,
            out3 => out3,
            out4 => out4
        );
CLOCK:
    process 
    begin
        wait for 5 ns;
        clk <= not clk;
        if Now > 120 ns then
            wait;
        end if;
    end process;
STIMULIS:
    process
    begin
        reset <= '1';
        wait for 11 ns;
        reset <= not reset;
        wait;
    end process;
end architecture;

-- Network for N=5, using Bose-Nelson Algorithm.
--
-- o--^--------^--^-----------o
--    |        |  |
-- o--v--------|--|--^--^--^--o
--             |  |  |  |  |
-- o-----^--^--|--v--|--|--v--o
--       |  |  |     |  |
-- o--^--|--v--v-----|--v-----o
--    |  |           |
-- o--v--v-----------v--------o
--
-- There are 9 comparators in this network,
-- grouped into 6 parallel operations.
--
-- [[0,1],[3,4]]
-- [[2,4]]
-- [[2,3],[1,4]]
-- [[0,3]]
-- [[0,2],[1,3]]
-- [[1,2]]
--
-- This is graphed in 8 columns.

最终得到了一个有效的模拟:

(可点击)

我发现你可以得到所有'0'的唯一方法是comp中的错误或测试台中的错误。

请注意,我选择了您使用的相同比较顺序,尽管使用了“>”和相反的比较顺序。

我虽然重置没有意义,但实际上使用它。而且它没有意义的原因是,在保证正确答案出现之前,您必须等待这 5 个时钟。

这是使用 ghdl 和 gtkwave 完成的。

【讨论】:

    【解决方案2】:

    由于您没有提供用于模拟的代码的完整示例,因此我使用您提供的 comp 实体创建了自己的测试平台。看看是不是和自己的相似:

    library ieee;
    use ieee.std_logic_1164.all;
    
    entity vhdl_tb is
    end vhdl_tb;
    architecture testbench of vhdl_tb is
      constant PERIOD         : time := 100 ps;
      constant TOTAL_CYCLES   : natural := 400;
      signal clk              : std_logic := '1';
      signal cycle            : natural := 0 ;
    
      signal done             : boolean := false;
      signal reset            : std_logic := '1';
      signal simclk           : std_logic := '0';
    
      SIGNAL out0_temp, out1_temp, out3_temp, out4_temp               : bit_vector (3 downto 0); --comp1(0,1),comp2(3,4)
      SIGNAL out2_temp, out4_1_temp                                           : bit_vector (3 downto 0);  --comp3(2,4)
      SIGNAL out2_1_temp, out3_1_temp, out1_1_temp, out4_2_temp   : bit_vector (3 downto 0); --comp4(2,3),comp5(1,4)
      SIGNAL out0_1_temp, out3_2_temp                                     : bit_vector (3 downto 0); --comp6(0,3)
      SIGNAL out0_2_temp, out2_2_temp, out1_2_temp, out3_3_temp   : bit_vector (3 downto 0); --comp7(0,2),comp8(1,3)
      SIGNAL out1_3_temp, out2_3_temp                                     : bit_vector (3 downto 0); --comp9(1,2)
    
      signal in0 : bit_vector(3 downto 0) := "0001";
      signal in1 : bit_vector(3 downto 0) := "0010";
      signal in2 : bit_vector(3 downto 0) := "0011";
      signal in3 : bit_vector(3 downto 0) := "0100";
      signal in4 : bit_vector(3 downto 0) := "0101";
    
      signal out0 : bit_vector(3 downto 0);
      signal out1 : bit_vector(3 downto 0);
      signal out2 : bit_vector(3 downto 0);
      signal out3 : bit_vector(3 downto 0);
      signal out4 : bit_vector(3 downto 0);
    
      signal reset_bit : bit;
    
      component comp is
        port ( 
          clk         : IN std_logic;  
          reset       : IN bit; 
          num0_in     : IN bit_vector (3 DOWNTO 0); 
          num1_in     : IN bit_vector (3 DOWNTO 0); 
          num0_out    : OUT bit_vector (3 DOWNTO 0); 
          num1_out    : OUT bit_vector (3 DOWNTO 0)  
        ); 
      end component comp;
    
    begin
    
      -- The following is a process which generates a clock
      -- while the unit is still under test
      ClkProcess: process(done,simclk)
      begin
        if (not done) then
          if (clk = '1') then
              cycle <= cycle + 1 ;
          end if ;
          simclk <= not simclk after PERIOD / 2 ;
        end if;
      end process;
    
    
      DoneProcess: process
      begin
        wait until (clk = '0');
          wait for PERIOD * 3;
          reset <= '0';
          wait for PERIOD * TOTAL_CYCLES;  -- Numder of cycles to execute
          done <= true;              -- Force the clock process to shutdown
        wait;                        -- This waits forever
      end process ;
    
      clk <= not simclk;
    
    
      -----------------------------------------------------------------
      -- Test section
      -----------------------------------------------------------------
      reset_bit <= to_bit(reset);
    
      comp1:comp -- (0,1)
      PORT MAP (clk,reset_bit, in0, in1, out0_temp, out1_temp);
      comp2:comp -- (3,4)
      PORT MAP (clk,reset_bit, in3, in4, out3_temp, out4_temp);
      comp3:comp -- (2,4)
      PORT MAP (clk,reset_bit, in2, out4_temp, out2_temp, out4_1_temp);
      comp4:comp -- (2,3)
      PORT MAP (clk,reset_bit, out2_temp, out3_temp, out2_1_temp, out3_1_temp);
      comp5:comp -- (1,4)
      PORT MAP (clk,reset_bit, out1_temp, out4_1_temp, out1_1_temp, out4_2_temp);
      comp6:comp -- (0,3)
      PORT MAP (clk,reset_bit, out0_temp, out3_1_temp, out0_1_temp, out3_2_temp);
      comp7:comp -- (0,2)
      PORT MAP ( clk,reset_bit, out0_1_temp, out2_1_temp, out0_2_temp, out2_2_temp);
      comp8:comp -- (1,3)
      PORT MAP ( clk,reset_bit, out1_1_temp, out3_2_temp, out1_2_temp, out3_3_temp);
      comp9:comp -- (1,2)
      PORT MAP ( clk,reset_bit, out1_2_temp, out2_2_temp, out1_3_temp, out2_3_temp);
    
      out0 <= out0_2_temp;
      out1 <= out1_3_temp;
      out2 <= out2_3_temp;
      out3 <= out3_3_temp;
      out4 <= out4_2_temp;
    
    
    end testbench;
    

    这些是我使用 modelsim 得到的结果:

    您提供的代码似乎有效。所以我会得出结论,你的问题出在你的模拟测试台上。

    注意事项:

    • 确保clk 已在您的测试平台中定义,并且它实际上会转换...duh。
    • 确保您的输入 (in0 - in4) 已定义,而不是全部为 0。
    • 确保您的reset 信号进入您的comp 块已定义。如果不是,您的 comp 块的输出将保持未定义。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-12-01
      • 2017-06-30
      • 2015-10-01
      • 2021-03-26
      • 2014-10-17
      • 2014-07-11
      • 1970-01-01
      • 2017-02-15
      相关资源
      最近更新 更多