Vhdl 进程语句未因时钟变化而更新(敏感度列表)

Vhdl process statements not getting updated for change in clock(sensitivity list)

我有以下代码。在这里,我试图根据索引对数组的值进行冒泡排序。

在第一组 for 循环中进行冒泡排序后,我正在使用第二组 for 循环来获取数组中冒泡排序的值的原始索引。

library ieee;
use ieee.std_logic_1164.all;

package array_type is
    constant len: integer := 4;
    type sorted is array (0 to 15) of std_logic_vector(len-1 downto 0); 
end package;

library ieee;
use ieee.std_logic_1164.all;
use work.array_type.all;

entity sort is
port (
     clk:             in  std_logic;
     bit_array:        in  sorted;
     sorted_array:    out sorted 
);
end entity;

architecture behaviour of sort is
    use ieee.numeric_std.all;
begin

BSORT:
process (clk)
    variable temp:      std_logic_vector (len-1 downto 0);
    variable var_array:     sorted; 
    variable temp_array:     sorted;           
begin
    var_array := bit_array;
    if rising_edge(clk) then
        for j in sorted'LEFT to sorted'RIGHT - 1 loop 
            for i in sorted'LEFT to sorted'RIGHT - 1 - j loop 
                if unsigned(var_array(i)) < unsigned(var_array(i + 1)) then
                    temp := var_array(i);
                    var_array(i) := var_array(i + 1);
                    var_array(i + 1) := temp;
                end if;
            end loop;
        end loop;

        for i in sorted'LEFT to sorted'RIGHT loop 
            j_loop:for j in sorted'LEFT to sorted'RIGHT loop 
                if ( (var_array(i)) = (bit_array(j)) ) then
                    if not( (temp_array(0)= std_logic_vector(to_unsigned(j, len))) or
                            (temp_array(1)= std_logic_vector(to_unsigned(j, len))) or
                            (temp_array(2)= std_logic_vector(to_unsigned(j, len))) or
                            (temp_array(3)= std_logic_vector(to_unsigned(j, len))) or
                            (temp_array(4)= std_logic_vector(to_unsigned(j, len))) or
                            (temp_array(5)= std_logic_vector(to_unsigned(j, len))) or
                            (temp_array(6)= std_logic_vector(to_unsigned(j, len))) or
                            (temp_array(7)= std_logic_vector(to_unsigned(j, len))) or
                            (temp_array(8)= std_logic_vector(to_unsigned(j, len))) or
                            (temp_array(9)= std_logic_vector(to_unsigned(j, len))) or
                            (temp_array(10)= std_logic_vector(to_unsigned(j, len))) or
                            (temp_array(11)= std_logic_vector(to_unsigned(j, len))) or
                            (temp_array(12)= std_logic_vector(to_unsigned(j, len))) or
                            (temp_array(13)= std_logic_vector(to_unsigned(j, len))) or
                            (temp_array(14)= std_logic_vector(to_unsigned(j, len))) or
                            (temp_array(15)= std_logic_vector(to_unsigned(j, len))) ) then 
                        temp_array(i) := std_logic_vector(to_unsigned(j, len)); --conv_std_logic_vector(j,4);
                        exit j_loop;
                    end if;
                end if;
            end loop;
        end loop;
    sorted_array <= temp_array;
    end if;
end process;
end architecture behaviour;

测试台如下:

library ieee;
use ieee.std_logic_1164.all;
use work.array_type.all;

entity sort_tb is
end entity;

architecture behav of sort_tb is
    use work.array_type.all;
    signal clk:             std_logic := '0';
    signal bit_array:        sorted;
    signal sorted_array:   sorted ;

    -- Clock period definitions
    constant clk_period : time := 10 ns; 

begin
DUT:
    entity work.sort(behaviour)
        port map (clk => clk,
            bit_array => bit_array,
            sorted_array => sorted_array
        );

    -- Clock process definitions( clock with 50% duty cycle is generated    here.
    clk_process :process
    begin
        clk <= '1';
        wait for clk_period/2;  --for 5 ns signal is '1'.
        clk <= '0';
        wait for clk_period/2;  --for next 5 ns signal is '0'.
    end process;

    process 
    begin
        bit_array <= (x"0", x"0", x"0", x"0", x"0", x"0", x"0", x"0", x"0", x"0", x"0", x"0", x"0", x"0", x"0", x"0") ;
        wait for 10 ns;
        bit_array <= (x"0", x"0", x"0", x"4", x"0", x"0", x"0", x"3", x"2", x"2", x"0", x"0", x"0", x"5", x"0", x"0") ;
        wait for 10 ns;
        bit_array <= (x"0", x"0", x"9", x"4", x"0", x"4", x"0", x"3", x"2", x"2", x"0", x"8", x"0", x"5", x"0", x"0") ;
        wait;
    end process;
end architecture;

这里的问题是,随着输入 bit_array 的变化,输出 sorted_array 没有在每个时钟周期得到评估和更新。 bit_array 更改每个 clk 周期并且 clk 在进程的敏感列表中,因此 sorted_array 应该在每个 clk 评估后获得新值。

进程中有2个for循环。如果我删除第二个 for 循环并将 var_array 分配给 sorted_array(输出),则 sorted_array 会根据新的 bit_array 数据进行评估,并在每个正确的时钟周期进行更新。但是如果我同时包含两个 for 循环,则不会发生同样的情况。

我是 VHDL 的新手,需要这方面的建议。

... i am using second set of for loops to get the original indeces of the values which are bubble sorted in an array.

(请更新您的问题以反映这一点)。

现在您的评论已经阐明了第二组循环的目的,可以通过另一种方法引入功能。

您的后两个循环的内容可寻址方法无法访问 var_array 中 bit_array 的原始索引。

执行此操作的最简单方法是创建一个新数组类型,该数组类型携带原始索引以及使用记录元素类型的数组元素的上下文。 (想法出现在CAM内存中,索引是数据的一部分):

library ieee;
use ieee.std_logic_1164.all;

package array_type is
  constant len:         natural := 4;
  constant indx_size:    natural := len;
  type sorted is array (0 to 15) of std_logic_vector (len - 1 downto 0);
  type cam is record 
      contents: std_logic_vector (len - 1 downto 0);
      index:    std_logic_vector (indx_size - 1  downto 0);
  end record;
  type rsorted is array (0 to 15) of cam;
end package;

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.array_type.all;

entity sort is
    port (
        clk:             in  std_logic;
        bit_array:       in  sorted;
        sorted_array:    out sorted
    );
end entity;

architecture behaviour of sort is
begin
BSORT:
    process (clk)
        variable temp:          cam;
        variable var_array:     rsorted;
        variable temp_array:    rsorted;
    begin
        -- var_array := bit_array;
        for i in bit_array'range loop
            var_array(i).contents := bit_array(i);
            var_array(i).index    := std_logic_vector(to_unsigned(i,indx_size));
        end loop;

        if rising_edge(clk) then
            for j in rsorted'LEFT to rsorted'RIGHT - 1 loop
                for i in rsorted'LEFT to rsorted'RIGHT - 1 - j loop
                    if var_array(i).contents < var_array(i + 1).contents then
                        temp := var_array(i);
                        var_array(i) := var_array(i + 1);
                        var_array(i + 1) := temp;
                    end if;
                end loop;
            end loop;
            -- for i in sorted'range loop            -- the sorted contents
            --     sorted_array(i) <= var_array(i).contents;
            -- end loop;
            -- or
            for i in sorted'range loop            -- the original indexes
                sorted_array(i) <= var_array(i).index;
            end loop;
        end if;
    end process;
end architecture behaviour;

library ieee;
use ieee.std_logic_1164.all;
use work.array_type.all;

entity sort_tb is
end entity;

architecture behav of sort_tb is
    use work.array_type.all;
    signal clk:            std_logic := '0';
    signal bit_array:      sorted;
    signal sorted_array:   sorted;
  -- Clock period definitions
    constant clk_period:   time := 10 ns;
begin
DUT:
    entity work.sort (behaviour)
        port map (
            clk          => clk,
            bit_array    => bit_array,
            sorted_array => sorted_array
        );
clk_process:
    process
    begin
        clk <= '1';
        wait for clk_period/2;
        clk <= '0';
        wait for clk_period/2;
    end process;

    process 
    begin
        bit_array <= ( x"0", x"0", x"0", x"0", x"0", x"0", x"0", x"0",
                       x"0", x"0", x"0", x"0", x"0", x"0", x"0", x"0" );
        wait for 10 ns;
        bit_array <= ( x"0", x"0", x"0", x"4", x"0", x"0", x"0", x"3",
                       x"2", x"2", x"0", x"0", x"0", x"5", x"0", x"0" );
        wait for 10 ns;
        bit_array <= ( x"0", x"0", x"9", x"4", x"0", x"4", x"0", x"3",
                       x"2", x"2", x"0", x"8", x"0", x"5", x"0", x"0" );
    wait;
    end process;
 end architecture;

您可以想象在两个不同的排序数组中同时输出索引列表和排序后的内容。

以上可以通过注释掉一个输出或另一个输出来完成。

如果检查输出波形:

根据输入的数组值,您会发现它是正确的。