我有以下代码。在这里,我试图根据索引对数组的值进行冒泡排序。
在第一组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位于进程的敏感性列表中,因此在评估每个clk后,sorted_array应该获得新的值。
过程中有2个for循环。如果我删除2nd for循环并将var_array分配给sorted_array(输出),则sorted_array将根据新的bit_array数据进行评估,并在每个时钟周期更新,这是正确的。但如果我同时包含两个for循环,那就不会发生同样的情况。
我是VHDL的新手,需要对此提出建议。
答案 0 :(得分:1)
...我正在使用第二组for循环来获取在数组中冒泡排序的值的原始值。
(请更新您的问题以反映这一点。)
现在您已经澄清了第二组循环的目的,可以通过其他方法引入功能。
使用后两个循环的内容可寻址方法无法访问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;
您可以想象地将索引列表和已排序内容输出到两个不同的排序数组中。
以上可以通过注释掉一个输出或另一个输出来完成。
如果检查输出波形:
根据输入数组值,您发现它是正确的。