如何在 VHDL 中的测试台中初始化数组?
How to initialize an array in test bench in VHDL?
在下面的代码中,主要问题是数组没有被测试台初始化。
我的主要目的是设计下面的读地址输出指令的单元。主要输入 "INSTRUCTION_ADRESS" 是一个包含地址及其内容的数组。
我们将非常重视任何意见。
library IEEE;
use IEEE.std_logic_1164.all;
PACKAGE MIPS_PACKAGE is
type INSTRUCTION_ARRAY is array (0 to 31) of std_logic_vector(31 downto 0);
end PACKAGE MIPS_PACKAGE;
-- INSTRUCTION MEMORY --
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.numeric_std.all;
use IEEE.std_logic_unsigned."+";
use work.MIPS_PACKAGE.all;
entity INSTRUCTION_MEMORY is
port(
PCSrc : in STD_LOGIC;
PC_EXT : in STD_LOGIC_VECTOR (31 downto 0);
INSTRUCTION_ADDRESS : in INSTRUCTION_ARRAY;
INSTRUCTION : out STD_LOGIC_VECTOR (31 downto 0)
);
end INSTRUCTION_MEMORY;
architecture INST_MEM of INSTRUCTION_MEMORY is
Signal PC: std_logic_vector (31 downto 0):="00000000000000000000000000000100";
Signal PC_ADD4: std_logic_vector (31 downto 0):=X"00000000";
begin
INSTRUCTION <= INSTRUCTION_ADDRESS(to_integer(unsigned(PC))); -- INSTRUCTION MEMORY
PC_ADD4 <= PC + X"4"; -- ADD 4
MUX_PC: process(PCSrc)
begin
if( PCSrc = '0') then
PC <= PC_ADD4;
else
PC <= PC_EXT;
end if;
end process MUX_PC;
end INST_MEM;
----------
--TESTBENCH
library IEEE;
use IEEE.Std_logic_1164.all;
use IEEE.Numeric_Std.all;
use work.MIPS_PACKAGE.all;
entity INSTRUCTION_MEMORY_tb is
end;
architecture bench of INSTRUCTION_MEMORY_tb is
component INSTRUCTION_MEMORY
port(
PCSrc : in STD_LOGIC;
PC_EXT : in STD_LOGIC_VECTOR (31 downto 0);
INSTRUCTION_ADDRESS : in INSTRUCTION_ARRAY;
INSTRUCTION : out STD_LOGIC_VECTOR (31 downto 0)
);
end component;
signal PCSrc: STD_LOGIC;
signal PC_EXT: STD_LOGIC_VECTOR (31 downto 0);
signal TestMemory: INSTRUCTION_ARRAY;
signal INSTRUCTION: STD_LOGIC_VECTOR (31 downto 0) ;
begin
uut: INSTRUCTION_MEMORY port map ( PCSrc => PCSrc,
PC_EXT => PC_EXT,
INSTRUCTION_ADDRESS => TestMemory,
INSTRUCTION => INSTRUCTION );
stimulus: process
begin
-- Put initialisation code here
PCSrc <= '0';
PC_EXT <= "00000000000000000000000000000000";
TestMemory(0) <= "10001100000000010000000000000000";
wait for 1 ns;
PCSrc <= '0';
PC_EXT <= "00000000000000000000000000000000";
TestMemory(4) <= "10001100000000100000000000000001";
wait for 1 ns;
PCSrc <= '0';
PC_EXT <= "00000000000000000000000000000000";
TestMemory(8) <= "00000000001000101000000000100000";
PCSrc <= '0';
PC_EXT <= "00000000000000000000000000000000";
TestMemory(12) <= "00000010000000011000100000100000";
wait for 1 ns;
PCSrc <= '0';
PC_EXT <= "00000000000000000000000000000000";
TestMemory( 16 ) <= "10101100000100000000000000000011";
wait for 5 ns;
-- Put test bench stimulus code here
wait;
end process;
end;
所以我只是通过 Vivado 运行 你的代码,在这个模拟器中,数组确实按照它应该的方式进行了初始化:
注意 TestMemory 波形每纳秒变化一次,正如预期的那样。由于您从未初始化整个数组,因此其他值当然保持 'U'
。
现在,您可以看到指令仅在2ns 后发生变化,但这与未初始化数组无关。这是因为 MUX_PC: process(PCSrc)
在其敏感列表中只有 PCSrc
,这意味着该过程只会执行一次 PCSrc
实际更改。这很可能不是预期的行为(这意味着您的 PC
只能在 PCSrc
更改时增加)。为了解决这个问题,在你的设计中加入一个时钟,设计一个同步过程。
在下面的代码中,主要问题是数组没有被测试台初始化。
我的主要目的是设计下面的读地址输出指令的单元。主要输入 "INSTRUCTION_ADRESS" 是一个包含地址及其内容的数组。
我们将非常重视任何意见。
library IEEE;
use IEEE.std_logic_1164.all;
PACKAGE MIPS_PACKAGE is
type INSTRUCTION_ARRAY is array (0 to 31) of std_logic_vector(31 downto 0);
end PACKAGE MIPS_PACKAGE;
-- INSTRUCTION MEMORY --
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.numeric_std.all;
use IEEE.std_logic_unsigned."+";
use work.MIPS_PACKAGE.all;
entity INSTRUCTION_MEMORY is
port(
PCSrc : in STD_LOGIC;
PC_EXT : in STD_LOGIC_VECTOR (31 downto 0);
INSTRUCTION_ADDRESS : in INSTRUCTION_ARRAY;
INSTRUCTION : out STD_LOGIC_VECTOR (31 downto 0)
);
end INSTRUCTION_MEMORY;
architecture INST_MEM of INSTRUCTION_MEMORY is
Signal PC: std_logic_vector (31 downto 0):="00000000000000000000000000000100";
Signal PC_ADD4: std_logic_vector (31 downto 0):=X"00000000";
begin
INSTRUCTION <= INSTRUCTION_ADDRESS(to_integer(unsigned(PC))); -- INSTRUCTION MEMORY
PC_ADD4 <= PC + X"4"; -- ADD 4
MUX_PC: process(PCSrc)
begin
if( PCSrc = '0') then
PC <= PC_ADD4;
else
PC <= PC_EXT;
end if;
end process MUX_PC;
end INST_MEM;
----------
--TESTBENCH
library IEEE;
use IEEE.Std_logic_1164.all;
use IEEE.Numeric_Std.all;
use work.MIPS_PACKAGE.all;
entity INSTRUCTION_MEMORY_tb is
end;
architecture bench of INSTRUCTION_MEMORY_tb is
component INSTRUCTION_MEMORY
port(
PCSrc : in STD_LOGIC;
PC_EXT : in STD_LOGIC_VECTOR (31 downto 0);
INSTRUCTION_ADDRESS : in INSTRUCTION_ARRAY;
INSTRUCTION : out STD_LOGIC_VECTOR (31 downto 0)
);
end component;
signal PCSrc: STD_LOGIC;
signal PC_EXT: STD_LOGIC_VECTOR (31 downto 0);
signal TestMemory: INSTRUCTION_ARRAY;
signal INSTRUCTION: STD_LOGIC_VECTOR (31 downto 0) ;
begin
uut: INSTRUCTION_MEMORY port map ( PCSrc => PCSrc,
PC_EXT => PC_EXT,
INSTRUCTION_ADDRESS => TestMemory,
INSTRUCTION => INSTRUCTION );
stimulus: process
begin
-- Put initialisation code here
PCSrc <= '0';
PC_EXT <= "00000000000000000000000000000000";
TestMemory(0) <= "10001100000000010000000000000000";
wait for 1 ns;
PCSrc <= '0';
PC_EXT <= "00000000000000000000000000000000";
TestMemory(4) <= "10001100000000100000000000000001";
wait for 1 ns;
PCSrc <= '0';
PC_EXT <= "00000000000000000000000000000000";
TestMemory(8) <= "00000000001000101000000000100000";
PCSrc <= '0';
PC_EXT <= "00000000000000000000000000000000";
TestMemory(12) <= "00000010000000011000100000100000";
wait for 1 ns;
PCSrc <= '0';
PC_EXT <= "00000000000000000000000000000000";
TestMemory( 16 ) <= "10101100000100000000000000000011";
wait for 5 ns;
-- Put test bench stimulus code here
wait;
end process;
end;
所以我只是通过 Vivado 运行 你的代码,在这个模拟器中,数组确实按照它应该的方式进行了初始化:
注意 TestMemory 波形每纳秒变化一次,正如预期的那样。由于您从未初始化整个数组,因此其他值当然保持 'U'
。
现在,您可以看到指令仅在2ns 后发生变化,但这与未初始化数组无关。这是因为 MUX_PC: process(PCSrc)
在其敏感列表中只有 PCSrc
,这意味着该过程只会执行一次 PCSrc
实际更改。这很可能不是预期的行为(这意味着您的 PC
只能在 PCSrc
更改时增加)。为了解决这个问题,在你的设计中加入一个时钟,设计一个同步过程。