Übungen der VHDL-Einführung
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

alu.vhd 5.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. -- Importiere die notwendigen Bibliotheken
  2. library IEEE;
  3. use IEEE.STD_LOGIC_1164.ALL;
  4. use IEEE.NUMERIC_STD.ALL;
  5. -- Definiere eine ALU-Entity mit zwei Operanden, einem Opcode und einem Ergebnisausgang
  6. entity SimpleALU is
  7. Port (
  8. clk : in STD_LOGIC; -- Takt
  9. reset : in STD_LOGIC; -- Reset
  10. operand_a : in STD_LOGIC_VECTOR(3 downto 0); -- Erster Operand
  11. operand_b : in STD_LOGIC_VECTOR(3 downto 0); -- Zweiter Operand
  12. opcode : in STD_LOGIC_VECTOR(1 downto 0); -- Opcode, der die Operation bestimmt
  13. result_out : out STD_LOGIC_VECTOR(3 downto 0); -- Ergebnis der Operation
  14. flag_zero_out : out STD_LOGIC; -- Flag, das anzeigt, ob das Ergebnis null ist
  15. flag_or_out : out STD_LOGIC -- Flag, das anzeigt, ob eine Oder Operation bei den Operanden stattgefunden hat
  16. );
  17. end SimpleALU;
  18. -- Architekturdefinition der ALU
  19. architecture Behavioral of SimpleALU is
  20. -- Legen Sie das Signal STD_LOGIC_VECTOR reg_a an, in diesem soll spaeter der Eingang operand_a gespeichert werden
  21. signal reg_a : STD_LOGIC_VECTOR(3 downto 0);
  22. -- Legen Sie das Signal STD_LOGIC_VECTOR reg_b an, in diesem soll spaeter der Eingang operand_b gespeichert werden
  23. signal reg_b : STD_LOGIC_VECTOR(3 downto 0);
  24. -- Legen Sie das Signal STD_LOGIC_VECTOR reg_opcode an, in diesem soll spaeter der Eingang opcode gespeichert werden
  25. signal reg_opcode : STD_LOGIC_VECTOR(1 downto 0);
  26. -- Legen Sie ein Signal flag_zero als STD_LOGIC an
  27. signal flag_zero : STD_LOGIC;
  28. -- Legen Sie ein Signal result als STD_LOGIC_VECTOR der Laenge 4 an
  29. signal result : STD_LOGIC_VECTOR(3 downto 0);
  30. -- Legen Sie ein Signal reg_flag_zero als STD_LOGIC
  31. signal reg_flag_zero : STD_LOGIC;
  32. -- Legen Sie ein Signal reg_result als STD_LOGIC_VECTOR der Laenge von result an
  33. signal reg_result : STD_LOGIC_VECTOR(3 downto 0);
  34. begin
  35. -- Prozess fuer die Eingangsregister reg_a, reg_b, reg_c
  36. -- Bei einem Reset sollen die Register den Wert 0 haben
  37. -- Ansonsten soll bei einer steigenden Flanke von clk der entsprechnde Eingang (entity) gespeichert werden
  38. input_register : process(reset,clk)
  39. begin
  40. if reset = '1' then
  41. reg_a <= (others => '0');
  42. reg_b <= (others => '0');
  43. reg_opcode <= (others => '0');
  44. elsif rising_edge(clk) then
  45. reg_a <= operand_a;
  46. reg_b <= operand_b;
  47. reg_opcode <= opcode;
  48. end if;
  49. end process input_register;
  50. -- Prozess, der die ALU-Operationen durchfuehrt
  51. alu_process: process(all)
  52. begin
  53. -- Anweisung fuer die Initialisierung fuer flag_zero mit dem Wert 0
  54. flag_zero <= '0';
  55. -- Entscheide basierend auf dem Opcode, welche Operation durchgefuehrt wird
  56. -- Wenn reg_opcode:
  57. -- 00 -> result = reg_a + reg_b
  58. -- 01 -> result = reg_a - reg_b
  59. -- 10 -> result = reg_a and reg_b
  60. -- 11 -> result = reg_a or reg_b
  61. -- Fuer diese Realisierung soll die case-Anweisung verwendet werden
  62. -- Anm. Bei Berechnungen Datentypen beachten (std_logic_vector kann nicht direkt verwendet werden sondern es muss erst gecastet werden - signed verwenden)
  63. case reg_opcode is
  64. when "00" => -- Im Fall von "00" fuehre eine Addition durch
  65. result <= std_logic_vector(signed(reg_a) + signed(reg_b));
  66. when "01" => -- Im Fall von "01" fuehre eine Subtraktion durch
  67. result <= std_logic_vector(signed(reg_a) - signed(reg_b));
  68. when "10" => -- Im Fall von "10" fuehre eine bitweise AND-Operation durch
  69. result <= reg_a and reg_b;
  70. when "11" => -- Im Fall von "11" fuehre eine bitweise OR-Operation durch
  71. result <= reg_a or reg_b;
  72. when others => -- In allen anderen Faellen setze ein undefiniertes Verhalten
  73. result <= (others => 'X');
  74. end case;
  75. -- ueberpruefe, ob das Ergebnis result null ist, und setze das flag_zero entsprechend (result = 0 dann 1 ansonsten 0)
  76. -- Fuer diese Realisierung soll die if-Anweisung verwendet werden
  77. if result = "0000" then
  78. flag_zero <= '1';
  79. end if;
  80. end process alu_process;
  81. -- Prozess fuer die Ausgangssregister reg_result, reg_flag_zero
  82. -- Bei einem Reset sollen die Register den Wert 0 haben
  83. -- Ansonsten soll bei einer steigenden Flanke von clk das entsprechnde Signal aus dem alu_process zugewiesen werden
  84. output_register : process(reset,clk)
  85. begin
  86. if reset = '1' then
  87. reg_result <= (others => '0');
  88. reg_flag_zero <= '0';
  89. elsif rising_edge(clk) then
  90. reg_result <= result;
  91. reg_flag_zero <= flag_zero;
  92. end if;
  93. end process output_register;
  94. -- Anweisung um das Signal reg_result dem Ausgang result_out zu zuweisen
  95. result_out <= reg_result;
  96. -- Anweisung um das Signal reg_flag_zero dem Ausgang flag_zero_out zu zuweisen
  97. flag_zero_out <= reg_flag_zero;
  98. -- Bedingte Signalzuweisung fuer 'flag_or_out' außerhalb des Prozesses
  99. -- Es soll anhand des Entity Eingang opcode mit einer With .. Select Anweisung der Ausgang flag_or_out gesetzt werden
  100. -- opcode von or Operation dann 1 ansonsten 0
  101. with opcode select
  102. flag_or_out <= '1' when "11", -- Setze 'flag_or_out' auf '1', wenn 'opcode' "11" ist
  103. '0' when others; -- Ansonsten 0
  104. end Behavioral;