该程序包含两个源文件:8bit_PU.vhd(实体bit_PU)和8bit_Tb.vhd。程序的最终版本应该读取一些(在这个测试平台中时钟频率为100Hz)3位操作代码到
operation
,解码它们,将其应用到8位std_logic_vectorsoperand1
和operand2
(它们也会随时间变化)并将结果写入 8 位 std_logic_vector result
。我现在的代码只描述了一个加法操作,所以 operation
向量现在没用。
这是8bit_PU.vhd代码:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity bit_PU is
port(operation : in std_logic_vector (2 downto 0);
Clk : in std_logic;
operand1 : in std_logic_vector (7 downto 0);
operand2 : in std_logic_vector (7 downto 0);
result : out std_logic_vector(7 downto 0)
);
end bit_PU;
architecture proc of bit_PU is
function Add (op1 : std_logic_vector (7 downto 0);
op2 : std_logic_vector (7 downto 0)) return std_logic_vector is
variable res: std_logic_vector (7 downto 0);
begin
res := std_logic_vector((unsigned(op1)+unsigned(op2)) mod 256);
return res;
end function;
begin
process(Clk) is
begin
if rising_edge(Clk) then
result <= Add(operand1, operand2);
end if;
end process;
end architecture;
这是8bit_Tb.vhd代码:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity bit_Tb is
end bit_Tb;
architecture proc of bit_Tb is
component bit_PU is
port(operation : in std_logic_vector (2 downto 0);
Clk : in std_logic;
operand1 : in std_logic_vector (7 downto 0);
operand2 : in std_logic_vector (7 downto 0);
result : out std_logic_vector(7 downto 0)
);
end component bit_PU;
signal Clk : std_logic := '0';
constant Freq : integer := 100;
constant PeriodTime : time := 1000 ms / Freq;
signal operation : std_logic_vector (2 downto 0) := "000";
signal result : std_logic_vector (7 downto 0);
signal operand1 : std_logic_vector (7 downto 0) := (others => '0');
signal operand2 : std_logic_vector (7 downto 0) := (others => '0');
begin
i_bit_PU: component bit_PU
port map(Clk => Clk,
operation => operation,
operand1 => operand1,
operand2 => operand2,
result => result);
Clk <= not Clk after PeriodTime / 2;
process (Clk) is
begin
if rising_edge(Clk) then
if unsigned(operand1) < unsigned(operand2) or (operand1 = x"FF" and operand2 = x"00") then
operand1 <= std_logic_vector((unsigned(operand1)+1) mod 256);
else
operand2 <= std_logic_vector((unsigned(operand2)+1) mod 256);
end if;
end if;
end process;
end architecture;
分析编译过程:
$ ghdl -s 8bit_PU.vhd
$ ghdl -s 8bit_Tb.vhd
$ ghdl -a 8bit_PU.vhd
$ ghdl -a 8bit_Tb.vhd
$ ghdl -e bit_PU
$ ghdl -r bit_PU --vcd=2nd_circuit.vcd
执行:
$ gtkwave 2nd_circuit.vcd
GTKWave Analyzer v3.3.118 (w)1999-2023 BSI
[0] start time.
[0] end time.
如您所见,程序的运行时间为 0 秒。
我分别测试了这两个文件(8bit_PU.vhd 文件中的测试台模拟;仅测试台运行)并且它们工作正常,所以我认为,我在测试台中导入 PU 端口的方式存在一些问题。然后我尝试使用
work
库导入 PU 的端口:
---
architecture proc of bit_Tb is
signal Clk : std_logic := '0';
constant Freq : integer := 100;
constant PeriodTime : time := 1000 ms / Freq;
signal operation : std_logic_vector (2 downto 0) := "000";
signal result : std_logic_vector (7 downto 0);
signal operand1 : std_logic_vector (7 downto 0) := (others => '0');
signal operand2 : std_logic_vector (7 downto 0) := (others => '0');
begin
i_bit_PU: entity work.bit_PU(proc) --here
port map(Clk => Clk,
operation => operation,
operand1 => operand1,
operand2 => operand2,
result => result);
---
但这也没有帮助。
您的测试平台进程当前正在永久生成波形。更具算法性的测试用例生成器会为您提供更好的服务。如:
process
begin
for i in 1 to 512 loop
if i mod 2 = 1 then
operand2 <= std_logic_vector((unsigned(operand2)+1) mod 256);
else
operand1 <= std_logic_vector((unsigned(operand1)+1) mod 256);
end if ;
wait until rising_edge(clk) ;
end loop ;
-- stop your test case
std.env.stop ;
end process ;
如果您这样做,则不需要 GHDL 的
--stoptime
,因为它只会运行直到停止。
在您的测试平台中,如果您正在 std_logic_vector 上进行数学运算,我建议您使用
numeric_std_unsigned
而不是所有类型转换体操。另外,正如 @user16145658 提到的,您不需要 mod 256,因为 numeric_std 系列的包结果始终与最大参数的大小相同。这会将您的代码减少到:
process
begin
for i in 1 to 512 loop
if i mod 2 = 1 then
operand2 <= operand2 + 1;
else
operand1 <= operand1 + 1 ;
end if ;
wait until rising_edge(clk) ;
end loop ;
-- stop your test case
std.env.stop ;
end process ;
这种思考会让你开始思考如何编写测试用例。