Adds checks to tests
This commit is contained in:
parent
b4e75e651c
commit
0fff028d26
11
.gitignore
vendored
Normal file
11
.gitignore
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
U1_Datentypen/.libwork
|
||||
U1_Datentypen/modelsim.ini
|
||||
U1_Datentypen/transcript
|
||||
U1_Datentypen/vish_stacktrace.vstf
|
||||
U1_Datentypen/vsim.wlf
|
||||
U1_Datentypen/work/
|
||||
U2_Entity_Component/.libwork
|
||||
U2_Entity_Component/modelsim.ini
|
||||
U2_Entity_Component/transcript
|
||||
U2_Entity_Component/vsim.wlf
|
||||
U2_Entity_Component/work/
|
@ -1,6 +1,7 @@
|
||||
|
||||
vhdl_srcs = DataTypesExample.vhd \
|
||||
test_DataTypesExample.vhd \
|
||||
../scripts/test_utility.vhd \
|
||||
test_DataTypesExample.vhd \
|
||||
|
||||
main = test_DataTypesExample
|
||||
|
||||
|
@ -4,8 +4,11 @@ library ieee;
|
||||
library std;
|
||||
use std.env.all;
|
||||
|
||||
library work;
|
||||
use work.test_utility.all;
|
||||
|
||||
entity test_DataTypesExample is
|
||||
generic( CHECK_RESULTS : boolean );
|
||||
generic( GUI_MODE : boolean; CHECK_RESULTS : boolean );
|
||||
end entity test_DataTypesExample;
|
||||
|
||||
architecture test of test_DataTypesExample is
|
||||
@ -27,7 +30,15 @@ begin
|
||||
delay : process
|
||||
begin
|
||||
wait for 100 ns;
|
||||
stop;
|
||||
assert_eq( output_slv_calc, x"52" );
|
||||
assert_eq( output_slv_mask, x"5a" );
|
||||
assert_eq( output_slv_set, x"7a" );
|
||||
|
||||
if ( GUI_MODE ) then
|
||||
std.env.stop;
|
||||
else
|
||||
std.env.finish;
|
||||
end if;
|
||||
end process delay;
|
||||
|
||||
end architecture test;
|
||||
|
@ -1,5 +1,6 @@
|
||||
|
||||
vhdl_srcs = down_counter_int.vhd \
|
||||
../scripts/test_utility.vhd \
|
||||
top_entity.vhd \
|
||||
test_top_entity.vhd \
|
||||
|
||||
|
@ -4,8 +4,11 @@ library ieee;
|
||||
library std;
|
||||
use std.env.all;
|
||||
|
||||
library work;
|
||||
use work.test_utility.all;
|
||||
|
||||
entity test_top_entity is
|
||||
generic( CHECK_RESULTS : boolean );
|
||||
generic( GUI_MODE : boolean; CHECK_RESULTS : boolean );
|
||||
end entity test_top_entity;
|
||||
|
||||
architecture test of test_top_entity is
|
||||
@ -31,12 +34,19 @@ begin
|
||||
|
||||
p_run : process
|
||||
begin
|
||||
wait until falling_edge( RESET );
|
||||
wait until falling_edge( RESET );
|
||||
for i in 0 to 128 loop
|
||||
wait until rising_edge( CLK );
|
||||
wait until rising_edge( CLK );
|
||||
end loop;
|
||||
wait until rising_edge( CLK );
|
||||
stop;
|
||||
|
||||
assert_eq( CNT, "0111000" );
|
||||
|
||||
if ( GUI_MODE ) then
|
||||
std.env.stop;
|
||||
else
|
||||
std.env.finish;
|
||||
end if;
|
||||
end process p_run;
|
||||
|
||||
end architecture test;
|
||||
|
11
U3_Anweisungen/Makefile
Normal file
11
U3_Anweisungen/Makefile
Normal file
@ -0,0 +1,11 @@
|
||||
|
||||
vhdl_srcs = down_counter_int.vhd \
|
||||
top_entity.vhd \
|
||||
test_top_entity.vhd \
|
||||
|
||||
main = test_top_entity
|
||||
|
||||
CHECK_RESULTS = true
|
||||
|
||||
include ../scripts/vhdl.mk
|
||||
|
125
U3_Anweisungen/alu.vhd
Normal file
125
U3_Anweisungen/alu.vhd
Normal file
@ -0,0 +1,125 @@
|
||||
-- Importiere die notwendigen Bibliotheken
|
||||
library IEEE;
|
||||
use IEEE.STD_LOGIC_1164.ALL;
|
||||
use IEEE.NUMERIC_STD.ALL;
|
||||
|
||||
-- Definiere eine ALU-Entity mit zwei Operanden, einem Opcode und einem Ergebnisausgang
|
||||
entity SimpleALU is
|
||||
Port (
|
||||
clk : in STD_LOGIC; -- Takt
|
||||
reset : in STD_LOGIC; -- Reset
|
||||
operand_a : in STD_LOGIC_VECTOR(3 downto 0); -- Erster Operand
|
||||
operand_b : in STD_LOGIC_VECTOR(3 downto 0); -- Zweiter Operand
|
||||
opcode : in STD_LOGIC_VECTOR(1 downto 0); -- Opcode, der die Operation bestimmt
|
||||
result_out : out STD_LOGIC_VECTOR(3 downto 0); -- Ergebnis der Operation
|
||||
flag_zero_out : out STD_LOGIC; -- Flag, das anzeigt, ob das Ergebnis null ist
|
||||
flag_or_out : out STD_LOGIC -- Flag, das anzeigt, ob eine Oder Operation bei den Operanden stattgefunden hat
|
||||
);
|
||||
end SimpleALU;
|
||||
|
||||
-- Architekturdefinition der ALU
|
||||
architecture Behavioral of SimpleALU is
|
||||
|
||||
-- Legen Sie das Signal STD_LOGIC_VECTOR reg_a an, in diesem soll spaeter der Eingang operand_a gespeichert werden
|
||||
signal reg_a : STD_LOGIC_VECTOR(3 downto 0);
|
||||
|
||||
-- Legen Sie das Signal STD_LOGIC_VECTOR reg_b an, in diesem soll spaeter der Eingang operand_b gespeichert werden
|
||||
signal reg_b : STD_LOGIC_VECTOR(3 downto 0);
|
||||
|
||||
-- Legen Sie das Signal STD_LOGIC_VECTOR reg_opcode an, in diesem soll spaeter der Eingang opcode gespeichert werden
|
||||
signal reg_opcode : STD_LOGIC_VECTOR(1 downto 0);
|
||||
|
||||
-- Legen Sie ein Signal flag_zero als STD_LOGIC an
|
||||
signal flag_zero : STD_LOGIC;
|
||||
|
||||
-- Legen Sie ein Signal result als STD_LOGIC_VECTOR der Laenge 4 an
|
||||
signal result : STD_LOGIC_VECTOR(3 downto 0);
|
||||
|
||||
-- Legen Sie ein Signal reg_flag_zero als STD_LOGIC
|
||||
signal reg_flag_zero : STD_LOGIC;
|
||||
|
||||
-- Legen Sie ein Signal reg_result als STD_LOGIC_VECTOR der Laenge von result an
|
||||
signal reg_result : STD_LOGIC_VECTOR(3 downto 0);
|
||||
|
||||
begin
|
||||
|
||||
-- Prozess fuer die Eingangsregister reg_a, reg_b, reg_c
|
||||
-- Bei einem Reset sollen die Register den Wert 0 haben
|
||||
-- Ansonsten soll bei einer steigenden Flanke von clk der entsprechnde Eingang (entity) gespeichert werden
|
||||
input_register : process(reset,clk)
|
||||
begin
|
||||
if reset = '1' then
|
||||
reg_a <= (others => '0');
|
||||
reg_b <= (others => '0');
|
||||
reg_opcode <= (others => '0');
|
||||
elsif rising_edge(clk) then
|
||||
reg_a <= operand_a;
|
||||
reg_b <= operand_b;
|
||||
reg_opcode <= opcode;
|
||||
end if;
|
||||
end process input_register;
|
||||
|
||||
|
||||
-- Prozess, der die ALU-Operationen durchfuehrt
|
||||
alu_process: process(all)
|
||||
begin
|
||||
-- Anweisung fuer die Initialisierung fuer flag_zero mit dem Wert 0
|
||||
flag_zero <= '0';
|
||||
|
||||
-- Entscheide basierend auf dem Opcode, welche Operation durchgefuehrt wird
|
||||
-- Wenn reg_opcode:
|
||||
-- 00 -> result = reg_a + reg_b
|
||||
-- 01 -> result = reg_a - reg_b
|
||||
-- 10 -> result = reg_a and reg_b
|
||||
-- 11 -> result = reg_a or reg_b
|
||||
-- Fuer diese Realisierung soll die case-Anweisung verwendet werden
|
||||
-- Anm. Bei Berechnungen Datentypen beachten (std_logic_vector kann nicht direkt verwendet werden sondern es muss erst gecastet werden - signed verwenden)
|
||||
case reg_opcode is
|
||||
when "00" => -- Im Fall von "00" fuehre eine Addition durch
|
||||
result <= std_logic_vector(signed(reg_a) + signed(reg_b));
|
||||
when "01" => -- Im Fall von "01" fuehre eine Subtraktion durch
|
||||
result <= std_logic_vector(signed(reg_a) - signed(reg_b));
|
||||
when "10" => -- Im Fall von "10" fuehre eine bitweise AND-Operation durch
|
||||
result <= reg_a and reg_b;
|
||||
when "11" => -- Im Fall von "11" fuehre eine bitweise OR-Operation durch
|
||||
result <= reg_a or reg_b;
|
||||
when others => -- In allen anderen Faellen setze ein undefiniertes Verhalten
|
||||
result <= (others => 'X');
|
||||
end case;
|
||||
|
||||
-- ueberpruefe, ob das Ergebnis result null ist, und setze das flag_zero entsprechend (result = 0 dann 1 ansonsten 0)
|
||||
-- Fuer diese Realisierung soll die if-Anweisung verwendet werden
|
||||
if result = "0000" then
|
||||
flag_zero <= '1';
|
||||
end if;
|
||||
|
||||
end process alu_process;
|
||||
|
||||
-- Prozess fuer die Ausgangssregister reg_result, reg_flag_zero
|
||||
-- Bei einem Reset sollen die Register den Wert 0 haben
|
||||
-- Ansonsten soll bei einer steigenden Flanke von clk das entsprechnde Signal aus dem alu_process zugewiesen werden
|
||||
output_register : process(reset,clk)
|
||||
begin
|
||||
if reset = '1' then
|
||||
reg_result <= (others => '0');
|
||||
reg_flag_zero <= '0';
|
||||
elsif rising_edge(clk) then
|
||||
reg_result <= result;
|
||||
reg_flag_zero <= flag_zero;
|
||||
end if;
|
||||
end process output_register;
|
||||
|
||||
-- Anweisung um das Signal reg_result dem Ausgang result_out zu zuweisen
|
||||
result_out <= reg_result;
|
||||
|
||||
-- Anweisung um das Signal reg_flag_zero dem Ausgang flag_zero_out zu zuweisen
|
||||
flag_zero_out <= reg_flag_zero;
|
||||
|
||||
-- Bedingte Signalzuweisung fuer 'flag_or_out' außerhalb des Prozesses
|
||||
-- Es soll anhand des Entity Eingang opcode mit einer With .. Select Anweisung der Ausgang flag_or_out gesetzt werden
|
||||
-- opcode von or Operation dann 1 ansonsten 0
|
||||
with opcode select
|
||||
flag_or_out <= '1' when "11", -- Setze 'flag_or_out' auf '1', wenn 'opcode' "11" ist
|
||||
'0' when others; -- Ansonsten 0
|
||||
|
||||
end Behavioral;
|
42
U3_Anweisungen/test_alu.vhd
Normal file
42
U3_Anweisungen/test_alu.vhd
Normal file
@ -0,0 +1,42 @@
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
|
||||
library std;
|
||||
use std.env.all;
|
||||
|
||||
entity test_top_entity is
|
||||
generic( CHECK_RESULTS : boolean );
|
||||
end entity test_top_entity;
|
||||
|
||||
architecture test of test_top_entity is
|
||||
signal CLK : std_logic := '0';
|
||||
signal RESET : std_logic := '1';
|
||||
signal CNT : std_logic_vector(6 downto 0);
|
||||
begin
|
||||
u_top_entity : entity work.top_entity
|
||||
port map (
|
||||
CLK => CLK,
|
||||
RESET => RESET,
|
||||
CNT => CNT
|
||||
);
|
||||
|
||||
CLK <= not CLK after 10 ns;
|
||||
|
||||
p_reset : process( CLK )
|
||||
begin
|
||||
if falling_edge( CLK ) then
|
||||
RESET <= '0';
|
||||
end if;
|
||||
end process p_reset;
|
||||
|
||||
p_run : process
|
||||
begin
|
||||
wait until falling_edge( RESET );
|
||||
for i in 0 to 128 loop
|
||||
wait until rising_edge( CLK );
|
||||
end loop;
|
||||
wait until rising_edge( CLK );
|
||||
stop;
|
||||
end process p_run;
|
||||
|
||||
end architecture test;
|
2
U3_Anweisungen/test_top_entity.wave
Normal file
2
U3_Anweisungen/test_top_entity.wave
Normal file
@ -0,0 +1,2 @@
|
||||
$ version 1.1
|
||||
/test_DataTypesExample/u_DataTypesExample/*
|
3
U3_Anweisungen/vsim.wave
Normal file
3
U3_Anweisungen/vsim.wave
Normal file
@ -0,0 +1,3 @@
|
||||
onerror {resume}
|
||||
quietly WaveActivateNextPane {} 0
|
||||
add wave -noupdate /test_top_entity/u_top_entity/*
|
@ -23,11 +23,13 @@ assert_level := error
|
||||
|
||||
gui: ${verilog_objs} ${vhdl_objs}
|
||||
@vsim \
|
||||
-gGUI_MODE=true \
|
||||
-gCHECK_RESULTS=$(CHECK_RESULTS) \
|
||||
-voptargs=+acc work.${main} -do "do vsim.wave; run -all"
|
||||
|
||||
sim: ${verilog_objs} ${vhdl_objs}
|
||||
@vsim \
|
||||
-gGUI_MODE=false \
|
||||
-gCHECK_RESULTS=$(CHECK_RESULTS) \
|
||||
-voptargs=+acc -c work.${main} -do "run -all" \
|
||||
| ../scripts/highlight_test_results.sh
|
||||
|
71
scripts/test_utility.vhd
Normal file
71
scripts/test_utility.vhd
Normal file
@ -0,0 +1,71 @@
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
use ieee.float_pkg.all;
|
||||
|
||||
library std;
|
||||
use std.textio.all;
|
||||
|
||||
package test_utility is
|
||||
constant TEST_FAIL : string := "[ FAIL ]";
|
||||
constant TEST_OK : string := "[ OK ]" & LF;
|
||||
|
||||
type real_array is array ( natural range <> ) of real;
|
||||
|
||||
procedure assert_eq( a : in std_logic_vector; b : in std_logic_vector );
|
||||
|
||||
procedure assert_near( variable a : in real;
|
||||
variable b : in real;
|
||||
variable abs_err : in real );
|
||||
|
||||
procedure assert_element_near( variable a : in real;
|
||||
variable b : in real;
|
||||
variable abs_err : in real;
|
||||
variable index : in integer );
|
||||
|
||||
end package test_utility;
|
||||
|
||||
package body test_utility is
|
||||
|
||||
procedure assert_eq( a : in std_logic_vector; b : in std_logic_vector ) is
|
||||
begin
|
||||
|
||||
assert( a = b )
|
||||
report TEST_FAIL & "assert_eq" & LF &
|
||||
" a: " & to_string( a ) & LF &
|
||||
" b: " & to_string( b ) & LF
|
||||
severity error;
|
||||
end procedure assert_eq;
|
||||
|
||||
procedure assert_near( variable a : in real;
|
||||
variable b : in real;
|
||||
variable abs_err : in real ) is
|
||||
variable abs_diff : real;
|
||||
begin
|
||||
abs_diff := abs( a - b );
|
||||
assert( abs_diff <= abs_err )
|
||||
report TEST_FAIL & "assert_near" & LF &
|
||||
" a: " & to_string( a ) & LF &
|
||||
" b: " & to_string( b ) & LF &
|
||||
" " & to_string( abs_diff ) & " > " & to_string( abs_err ) & LF
|
||||
severity error;
|
||||
end procedure assert_near;
|
||||
|
||||
procedure assert_element_near( variable a : in real;
|
||||
variable b : in real;
|
||||
variable abs_err : in real;
|
||||
variable index : in integer ) is
|
||||
variable abs_diff : real;
|
||||
begin
|
||||
abs_diff := abs( a - b );
|
||||
assert( abs_diff <= abs_err )
|
||||
report TEST_FAIL & "assert_element_near" & LF &
|
||||
" element: " & integer'image( index ) & LF &
|
||||
" a: " & to_string( a ) & LF &
|
||||
" b: " & to_string( b ) & LF &
|
||||
" " & to_string( abs_diff ) & " > " & to_string( abs_err ) & LF
|
||||
severity error;
|
||||
end procedure assert_element_near;
|
||||
|
||||
end package body test_utility;
|
||||
|
Loading…
x
Reference in New Issue
Block a user