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/ |
vhdl_srcs = DataTypesExample.vhd \ | vhdl_srcs = DataTypesExample.vhd \ | ||||
test_DataTypesExample.vhd \ | |||||
../scripts/test_utility.vhd \ | |||||
test_DataTypesExample.vhd \ | |||||
main = test_DataTypesExample | main = test_DataTypesExample | ||||
library std; | library std; | ||||
use std.env.all; | use std.env.all; | ||||
library work; | |||||
use work.test_utility.all; | |||||
entity test_DataTypesExample is | entity test_DataTypesExample is | ||||
generic( CHECK_RESULTS : boolean ); | |||||
generic( GUI_MODE : boolean; CHECK_RESULTS : boolean ); | |||||
end entity test_DataTypesExample; | end entity test_DataTypesExample; | ||||
architecture test of test_DataTypesExample is | architecture test of test_DataTypesExample is | ||||
delay : process | delay : process | ||||
begin | begin | ||||
wait for 100 ns; | 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 process delay; | ||||
end architecture test; | end architecture test; |
vhdl_srcs = down_counter_int.vhd \ | vhdl_srcs = down_counter_int.vhd \ | ||||
../scripts/test_utility.vhd \ | |||||
top_entity.vhd \ | top_entity.vhd \ | ||||
test_top_entity.vhd \ | test_top_entity.vhd \ | ||||
library std; | library std; | ||||
use std.env.all; | use std.env.all; | ||||
library work; | |||||
use work.test_utility.all; | |||||
entity test_top_entity is | entity test_top_entity is | ||||
generic( CHECK_RESULTS : boolean ); | |||||
generic( GUI_MODE : boolean; CHECK_RESULTS : boolean ); | |||||
end entity test_top_entity; | end entity test_top_entity; | ||||
architecture test of test_top_entity is | architecture test of test_top_entity is | ||||
p_run : process | p_run : process | ||||
begin | begin | ||||
wait until falling_edge( RESET ); | |||||
wait until falling_edge( RESET ); | |||||
for i in 0 to 128 loop | for i in 0 to 128 loop | ||||
wait until rising_edge( CLK ); | |||||
wait until rising_edge( CLK ); | |||||
end loop; | end loop; | ||||
wait until rising_edge( CLK ); | 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 process p_run; | ||||
end architecture test; | end architecture test; |
vhdl_srcs = down_counter_int.vhd \ | |||||
top_entity.vhd \ | |||||
test_top_entity.vhd \ | |||||
main = test_top_entity | |||||
CHECK_RESULTS = true | |||||
include ../scripts/vhdl.mk | |||||
-- 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; |
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; |
$ version 1.1 | |||||
/test_DataTypesExample/u_DataTypesExample/* |
onerror {resume} | |||||
quietly WaveActivateNextPane {} 0 | |||||
add wave -noupdate /test_top_entity/u_top_entity/* |
gui: ${verilog_objs} ${vhdl_objs} | gui: ${verilog_objs} ${vhdl_objs} | ||||
@vsim \ | @vsim \ | ||||
-gGUI_MODE=true \ | |||||
-gCHECK_RESULTS=$(CHECK_RESULTS) \ | -gCHECK_RESULTS=$(CHECK_RESULTS) \ | ||||
-voptargs=+acc work.${main} -do "do vsim.wave; run -all" | -voptargs=+acc work.${main} -do "do vsim.wave; run -all" | ||||
sim: ${verilog_objs} ${vhdl_objs} | sim: ${verilog_objs} ${vhdl_objs} | ||||
@vsim \ | @vsim \ | ||||
-gGUI_MODE=false \ | |||||
-gCHECK_RESULTS=$(CHECK_RESULTS) \ | -gCHECK_RESULTS=$(CHECK_RESULTS) \ | ||||
-voptargs=+acc -c work.${main} -do "run -all" \ | -voptargs=+acc -c work.${main} -do "run -all" \ | ||||
| ../scripts/highlight_test_results.sh | | ../scripts/highlight_test_results.sh |
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; | |||||