@@ -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; |
@@ -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 | |||
@@ -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; |
@@ -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; |
@@ -0,0 +1,2 @@ | |||
$ version 1.1 | |||
/test_DataTypesExample/u_DataTypesExample/* |
@@ -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 |
@@ -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; | |||