简体   繁体   中英

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

I have the following code. Here I am trying to bubble sort the values of an array acoording to their index .

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

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;

and the test bench is as below:

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;

波

Here the problem is , the output sorted_array is not getting evaluated and updated every clock cycle as input bit_array changes. bit_array changes every clk cycle and clk is in sensitivity list of process, so sorted_array should get new values after evaluation each clk.

There are 2 for loops in the process. If i remove 2nd for loop and assign var_array to sorted_array(output), then sorted_array is evaluated according to new bit_array data and is updated every clock cycle which is correct. But the same is not happening if i include both the for loops.

I am new to VHDL , Need suggestion on this.

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

(Please update your question to reflect this).

Now that you're comment has clarified the purpose of the second set of loops the functionality can be introduce by another method.

Your contents addressable method with the second two loops is missing access to the original index of bit_array in the var_array.

The easiest way to to do this create a new array type that carries the original index along with the context of an array element using a record element type. (The idea shows up in CAM memory, the index is part of the data):

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;

You could conceivably output both the index list and the sorted contents in two different sorted arrays.

The above can do either by commenting out one output or the other.

And if you check the output waveform:

sorted_tb_index.png

Against the input array values you'd find it's correct.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM