architecture Behavioral of DataTypesExample is | architecture Behavioral of DataTypesExample is | ||||
-- constant/signal Deklarationen | -- constant/signal Deklarationen | ||||
--Legen Sie ein Konstante DataWidth als integer mit Wert 8 an | |||||
--Legen Sie ein Konstante eight als integer mit Wert 8 an | |||||
--Legen Sie ein Konstante on als std_logic mit 1 an | |||||
--Legen Sie ein Konstante one als std_logic mit 1 an | |||||
--Legen Sie ein Konstante mask als std_logic_vector mit 5Ah an | --Legen Sie ein Konstante mask als std_logic_vector mit 5Ah an | ||||
--Legen Sie ein signal internal_int als integer mit Wertebreich -128 to 127 an | |||||
--Legen Sie ein signal internal_int als integer mit Wertebreich -128 to 127 an, initsialiseren Sie es mit 0 | |||||
--Legen Sie ein signal internal_int als integer mit Wertebreich -128 to 127 an | |||||
--Legen Sie ein signal internal_int2 als integer mit Wertebreich -128 to 127 an, initsialiseren Sie es mit 0 | |||||
--Legen Sie ein signal internal_slv als std_logic_vector mit Laenge 8 an | |||||
--Legen Sie ein signal internal_slv als std_logic_vector mit Laenge 8 an, initsialiseren Sie es mit 0 | |||||
--Legen Sie ein signal internal_s als signed mit Laenge 8 an | --Legen Sie ein signal internal_s als signed mit Laenge 8 an | ||||
-- Maskieren (UND) Sie den Eingang input_slv mit der Maske mask und weisen Sie den Wert dem Ausgang output_slv_mask zu | -- Maskieren (UND) Sie den Eingang input_slv mit der Maske mask und weisen Sie den Wert dem Ausgang output_slv_mask zu | ||||
-- Der Wert des Ausgangs output_slv_set soll dem Eingang input_slv entsprechen wobei immer das 5 Bit (von 8 Bit) per Bitverkettung gesetzt sein soll | |||||
-- Der Wert des Ausgangs output_slv_set soll dem Eingang input_slv entsprechen wobei immer das 5 Bit (6 Stelle von 8 Bit) per Bitverkettung gesetzt sein soll | |||||
-- Koonstante one kann verwendet werden | -- Koonstante one kann verwendet werden | ||||
-- Weisen Sie dem signal internal_slv dein Eingang input_slv zu | -- Weisen Sie dem signal internal_slv dein Eingang input_slv zu | ||||
-- Rechnen Sie die Subtraktion internal_int - der Konstante eight und weisen Sie das Ergebnis internal_int2 zu | -- Rechnen Sie die Subtraktion internal_int - der Konstante eight und weisen Sie das Ergebnis internal_int2 zu | ||||
-- Weisen Sie dem signal das Signal internal_int2 zu (Datentypen beachten Konvetierung noetig) | |||||
-- Weisen Sie dem Signal internal_s das Signal internal_int2 zu (Datentypen beachten Konvetierung noetig) | |||||
-- Weisen Sie dem Ausgang output_slv_calc das signal internal_s zu (Datentypen beachten Konvetierung noetig) | -- Weisen Sie dem Ausgang output_slv_calc das signal internal_s zu (Datentypen beachten Konvetierung noetig) | ||||
end Behavioral; | end Behavioral; | ||||
vhdl_srcs = down_counter_int.vhd \ | |||||
top_entity.vhd \ | |||||
test_top_entity.vhd \ | |||||
vhdl_srcs = ../scripts/test_utility.vhd \ | |||||
alu.vhd \ | |||||
test_alu.vhd \ | |||||
main = test_top_entity | |||||
main = test_alu | |||||
CHECK_RESULTS = true | CHECK_RESULTS = true | ||||
architecture Behavioral of SimpleALU is | 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 | -- 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 | -- 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 | -- 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 | -- 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 | -- 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 | -- 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 | -- 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 | begin | ||||
-- Ansonsten soll bei einer steigenden Flanke von clk der entsprechnde Eingang (entity) gespeichert werden | -- Ansonsten soll bei einer steigenden Flanke von clk der entsprechnde Eingang (entity) gespeichert werden | ||||
input_register : process(reset,clk) | input_register : process(reset,clk) | ||||
begin | 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; | end process input_register; | ||||
alu_process: process(all) | alu_process: process(all) | ||||
begin | begin | ||||
-- Anweisung fuer die Initialisierung fuer flag_zero mit dem Wert 0 | -- Anweisung fuer die Initialisierung fuer flag_zero mit dem Wert 0 | ||||
flag_zero <= '0'; | |||||
-- Entscheide basierend auf dem Opcode, welche Operation durchgefuehrt wird | -- Entscheide basierend auf dem Opcode, welche Operation durchgefuehrt wird | ||||
-- Wenn reg_opcode: | -- Wenn reg_opcode: | ||||
-- 11 -> result = reg_a or reg_b | -- 11 -> result = reg_a or reg_b | ||||
-- Fuer diese Realisierung soll die case-Anweisung verwendet werden | -- 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) | -- 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) | -- 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 | -- Fuer diese Realisierung soll die if-Anweisung verwendet werden | ||||
if result = "0000" then | |||||
flag_zero <= '1'; | |||||
end if; | |||||
end process alu_process; | end process alu_process; | ||||
-- Prozess fuer die Ausgangssregister reg_result, reg_flag_zero | -- Prozess fuer die Ausgangssregister reg_result, reg_flag_zero | ||||
-- Bei einem Reset sollen die Register den Wert 0 haben | -- 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 | -- 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 | -- 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 | -- 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 | -- 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 | -- 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 | -- 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; | |||||
end Behavioral; |
library std; | library std; | ||||
use std.env.all; | use std.env.all; | ||||
use std.textio.all; | |||||
entity test_top_entity is | |||||
generic( CHECK_RESULTS : boolean ); | |||||
end entity test_top_entity; | |||||
library work; | |||||
use work.test_utility.all; | |||||
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); | |||||
entity test_alu is | |||||
generic( GUI_MODE : boolean; CHECK_RESULTS : boolean ); | |||||
end entity test_alu; | |||||
architecture test of test_alu is | |||||
signal clk : std_logic := '0'; | |||||
signal reset : std_logic := '1'; | |||||
signal operand_a : std_logic_vector(3 downto 0); | |||||
signal operand_b : std_logic_vector(3 downto 0); | |||||
signal opcode : std_logic_vector(1 downto 0); | |||||
signal result_out : std_logic_vector(3 downto 0); | |||||
signal flag_zero_out : std_logic; | |||||
signal flag_or_out : std_logic; | |||||
begin | begin | ||||
u_top_entity : entity work.top_entity | |||||
u_alu : entity work.SimpleALU | |||||
port map ( | port map ( | ||||
CLK => CLK, | |||||
RESET => RESET, | |||||
CNT => CNT | |||||
clk => clk, | |||||
reset => reset, | |||||
operand_a => operand_a, | |||||
operand_b => operand_b, | |||||
opcode => opcode, | |||||
result_out => result_out, | |||||
flag_zero_out => flag_zero_out, | |||||
flag_or_out => flag_or_out | |||||
); | ); | ||||
CLK <= not CLK after 10 ns; | |||||
clk <= not clk after 10 ns; | |||||
p_reset : process( CLK ) | |||||
p_reset : process( clk ) | |||||
begin | begin | ||||
if falling_edge( CLK ) then | |||||
RESET <= '0'; | |||||
if falling_edge( clk ) then | |||||
reset <= '0'; | |||||
end if; | end if; | ||||
end process p_reset; | end process p_reset; | ||||
p_run : process | p_run : process | ||||
begin | 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; | |||||
wait until falling_edge( reset ); | |||||
-- Addition | |||||
write( output, "Test Addition ... " ); | |||||
opcode <= "00"; | |||||
operand_a <= x"a"; | |||||
operand_b <= x"5"; | |||||
wait until falling_edge( clk ); | |||||
wait until falling_edge( clk ); | |||||
assert_eq( result_out, x"f" ); | |||||
assert_eq( flag_zero_out, '0' ); | |||||
assert_eq( flag_or_out, '0' ); | |||||
write( output, "done" & LF ); | |||||
-- Subtraktion auf Null | |||||
write( output, "Test Subtraktion ... " ); | |||||
opcode <= "01"; | |||||
operand_a <= x"a"; | |||||
operand_b <= x"a"; | |||||
wait until falling_edge( clk ); | |||||
wait until falling_edge( clk ); | |||||
assert_eq( result_out, x"0" ); | |||||
assert_eq( flag_zero_out, '1' ); | |||||
assert_eq( flag_or_out, '0' ); | |||||
write( output, "done" & LF ); | |||||
-- UND-Operation | |||||
write( output, "Test UND-Operation ... " ); | |||||
opcode <= "10"; | |||||
operand_a <= x"a"; | |||||
operand_b <= x"3"; | |||||
wait until falling_edge( clk ); | |||||
wait until falling_edge( clk ); | |||||
assert_eq( result_out, x"2" ); | |||||
assert_eq( flag_zero_out, '0' ); | |||||
assert_eq( flag_or_out, '0' ); | |||||
write( output, "done" & LF ); | |||||
-- ODER-Operation | |||||
write( output, "Test ODER-Operation ... " ); | |||||
opcode <= "11"; | |||||
operand_a <= x"a"; | |||||
operand_b <= x"3"; | |||||
wait until falling_edge( clk ); | |||||
wait until falling_edge( clk ); | |||||
assert_eq( result_out, x"b" ); | |||||
assert_eq( flag_zero_out, '0' ); | |||||
assert_eq( flag_or_out, '1' ); | |||||
write( output, "done" & LF ); | |||||
wait until falling_edge( clk ); | |||||
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; |
$ version 1.1 | |||||
/test_DataTypesExample/u_DataTypesExample/* |
onerror {resume} | onerror {resume} | ||||
quietly WaveActivateNextPane {} 0 | quietly WaveActivateNextPane {} 0 | ||||
add wave -noupdate /test_top_entity/u_top_entity/* | |||||
add wave -noupdate /test_alu/u_alu/* |