-- 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;