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