我在这个VHDL程序中写了一个ALU及其正在运行的测试平台:
ALU-代码:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity ALU_CLK is
port( Clk : in std_logic; --clock signal
InRegA,InRegB : in signed(31 downto 0); --input operands
InOp : in unsigned(2 downto 0); --Operation to be performed
OutReg : out signed(31 downto 0); --output of ALU
OutZero : out std_logic
);
end ALU_CLK;
architecture Behavioral of ALU_CLK is
signal Reg1,Reg2,Reg3 : signed(31 downto 0) := (others => '0');
begin
Reg1 <= INregA;
Reg2 <= InRegB;
OutReg <= Reg3;
process(Clk)
variable temp: signed(31 downto 0);
begin
if(rising_edge(Clk)) then
case InOp is
when "010" =>
temp := Reg1 + Reg2; --addition
when "000" =>
temp := Reg1 and Reg2; --AND gate
when "001" =>
temp := Reg1 or Reg2; --OR gate
when others =>
NULL;
end case;
if temp = (31 downto 0=>'0') then
OutZero <= '1';
else
OutZero <= '0';
end if;
Reg3 <= temp;
end if;
end process;
end Behavioral;
测试台代码:
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.numeric_std.ALL;
ENTITY tb IS
END tb;
ARCHITECTURE ALU_CLK OF tb IS
signal Clk : std_logic := '0';
signal A,B,R : signed(31 downto 0) := (others => '0');
signal Op : unsigned(2 downto 0) := (others => '0');
signal zero : std_logic :='0';
constant Clk_period : time := 10 ns;
BEGIN
uut: entity work.ALU_CLK PORT MAP (
Clk => Clk,
InRegA => A,
InRegB => B,
InOp => Op,
OutReg => R,
OutZero => zero
);
Clk_process :process
begin
Clk <= '0';
wait for Clk_period/2;
Clk <= '1';
wait for Clk_period/2;
end process;
-- Stimulus process
stim_proc: process
begin
wait for Clk_period*1;
--test normal operations
A <= "00000000000000000000000000010011"; --19 in decimal
B <= "00000000000000000000000000001100"; --12 in decimal
Op <= "000"; wait for Clk_period; --Bitwise and A and B
Op <= "001"; wait for Clk_period; --Bitwise or B from A.
Op <= "010"; wait for Clk_period; --addition A nad B
wait;
end process;
END;
为了缩短代码清单,我没有发布ALU所做的所有操作。 我可以管理它以将ALU更改为没有clk的ALU但是如何使用测试平台进行测试?
答案 0 :(得分:2)
即使在没有时钟的模块的测试台上,也可能是个好主意 一个时钟,可以计时测试事件,并使测试更容易 波形的进展。
因此,在从ALU移除时钟之后,测试台过程可以控制 刺激并做检查,如:
-- Combined stimuli and check process
process is
begin
...
-- === 2 + 2 test ===
-- Stimuli control
wait until rising_edge(clk);
InRegA <= to_signed(2, InRegA'length);
InRegB <= to_signed(2, InRegA'length);
InOp <= "010"; -- Add
-- Output check
wait until falling_edge(clk);
assert OutReg = InRegA + InRegB;
assert (OutZero = '1') = (OutReg = 0);
...
end process;
为了简化检查部分,可以将其移至单独的流程和检查 可以根据以下操作制作:
-- Check process
process (clk) is
begin
if falling_edge(clk) then
if check then
-- OutReg check
case InOp is
when "010" => assert OutReg = InRegA + InRegB; -- Add
when "000" => assert OutReg = (InRegA and InRegB); -- And
when "001" => assert OutReg = (InRegA or InRegB); -- Or
when others => report "Unsupported operation" severity ERROR;
end case;
-- OutZero check
assert (OutZero = '1') = (OutReg = 0);
end if;
end if;
end process;
check
信号由刺激过程控制,以保护时间
要进行检查,以避免启动或其他错误
特殊条件。
答案 1 :(得分:1)
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity alu32bit is
port(en:in STD_LOGIC;
opc:in STD_LOGIC_VECTOR(3 downto 0);
a_in,b_in:in STD_LOGIC_VECTOR(31 downto 0);
y_op:out STD_LOGIC_VECTOR(31 downto 0));
end alu32 bit;
architecture Behavioral of alu32 bit is
begin
Process(en,a_in,b_in,opc)
begin
if(en='1')then
when "0001"=>y_op<=a_in+b_in;
when "0010"=>y_op<=a_in-b_in;
when "0011"=>y_op<=not a_in;
when "0100"=>y_op<=a_in and b_in;
when "0101"=>y_op<=a_in or b_in;
when "0110"=>y_op<=a_in nand b_in;
when "0111"=>y_op<=a_in xor b_in;
when others=>null;
end case;
else
y_op<="ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ";
end if;
end process;
end Behavioral;
答案 2 :(得分:0)
最后我得到了这个:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity ALU_32 is
port(
InRegA,InRegB : in signed(31 downto 0); --input operands
InOp : in unsigned(2 downto 0); --Operation to be performed
OutReg : out signed(31 downto 0); --output of ALU
OutZero : out std_logic
);
end ALU_32;
architecture Behavioral of ALU_32 is
--temporary signal declaration.
signal Reg1,Reg2,Reg3 : signed(31 downto 0) := (others => '0');
begin
Reg1 <= InRegA;
Reg2 <= InRegB;
OutReg <= Reg3;
process(InOp, InRegA, inRegB)
variable temp: signed(31 downto 0);
begin
case InOp is
when "010" =>
temp := Reg1 + Reg2; --addition
when "110" =>
temp := Reg1 - Reg2; --subtraction
when "000" =>
temp := Reg1 and Reg2; --AND gate
when "001" =>
temp := Reg1 or Reg2; --OR gate
when "100" =>
temp := Reg1 nor Reg2; --NOR gate
when "011" =>
temp := Reg1 xor Reg2; --XOR gate
when "101" =>
temp := not Reg1; --NOT gate
when "111" =>
if Reg1 < Reg2 then --SLT (set on less than) gate
temp := (others => '1');
else
temp := (others => '0');
end if;
when others =>
NULL;
end case;
if temp = (31 downto 0=>'0') then
OutZero <= '1';
else
OutZero <= '0';
end if;
Reg3 <= temp;
end process;
end Behavioral;
工作测试平台是:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
ENTITY tb2 IS
END tb2;
ARCHITECTURE ALU_32 OF tb2 IS
COMPONENT ALU_32
PORT(
InRegA : IN signed(31 downto 0);
InRegB : IN signed(31 downto 0);
InOp : IN unsigned(2 downto 0);
OutReg : OUT signed(31 downto 0);
OutZero : OUT std_logic
);
END COMPONENT;
--Inputs
signal InRegA : signed(31 downto 0) := (others => '0');
signal InRegB : signed(31 downto 0) := (others => '0');
signal InOp : unsigned(2 downto 0) := (others => '0');
--Outputs
signal OutReg : signed(31 downto 0);
signal OutZero : std_logic;
-- No clocks detected in port list. Replace <clock> below with
-- appropriate port name
--constant <InOp>_period : time := 10 ns;
BEGIN
-- Instantiate the Unit Under Test (UUT)
uut: ALU_32 PORT MAP (
InRegA => InRegA,
InRegB => InRegB,
InOp => InOp,
OutReg => OutReg,
OutZero => OutZero
);
-- Stimulus process
stim_proc: process
begin
-- hold reset state for 100 ns.
wait for 100 ns;
-- insert stimulus here
--test normal operations
InRegA <= "00000000000000000000000000010011"; --19 in decimal
InRegB <= "00000000000000000000000000001100"; --12 in decimal
InOp <= "000"; wait for 100 ns; --Bitwise and A and B
InOp <= "001"; wait for 100 ns; --Bitwise or B from A.
InOp <= "010"; wait for 100 ns; --addition A nad B
InOp <= "100"; wait for 100 ns; --Bitwise NOR of A and B
InOp <= "011"; wait for 100 ns; --Bitwise XOR of A and B
InOp <= "110"; wait for 100 ns; --substract A and B
InOp <= "101"; wait for 100 ns; --Bitwise NOT of A
InOp <= "111"; wait for 100 ns; --Bitwise SLT of A and B
-- test SLT the other way around
InRegB <= "00000000000000000000000000010011"; --19 in decimal
InRegA <= "00000000000000000000000000001100"; --12 in decimal
InOp <= "111"; wait for 100 ns; --Bitwise SLT of A and B
-- test Branch equal that substraction is 0 and zero is 1
InRegA <= "00000000000000000000000000001011"; --11 in decimal
InRegB <= "00000000000000000000000000001011"; --11 in decimal
InOp <= "110"; wait for 100 ns; --substract A and B
wait;
end process;
END;
以下是模拟的结果: