------------------------------------------------------------ -- Copyright Mentor Graphic Corporation 1991. -- All rights reserved. ------------------------------------------------------------ -- -- Model Title: Execution Unit for Microprocessor "EX-1" -- Date Created: 95/10/25 (WED) -- Author: T. Ohtsuka -- ------------------------------------------------------------ -- Model Description: -- ----------------------------------------------------------- -- LIBRARY IEEE,ARITHMETIC ; LIBRARY work ; USE IEEE.STD_LOGIC_1164.ALL ; USE ARITHMETIC.STD_LOGIC_ARITH.ALL ; ENTITY eu IS PORT ( clk1 : IN STD_LOGIC ; -- phase I clock -- clk2 : IN STD_LOGIC ; -- phase II clock a : IN STD_LOGIC_VECTOR(7 DOWNTO 0); -- A port of the ALU input b : IN STD_LOGIC_VECTOR(7 DOWNTO 0) ; -- B port of the ALU input c_ctl : IN STD_LOGIC_VECTOR(2 DOWNTO 0) ; -- CARRY control acc_msb : IN STD_LOGIC ; -- MSB of ACC acc_lsb : IN STD_LOGIC ; -- LSB of ACC add_with_carry : IN STD_LOGIC ; -- add with carry control sub_with_borrow : IN STD_LOGIC ; -- substraction with borrow control alu_f_ctl : IN STD_LOGIC_VECTOR(4 DOWNTO 0) ; -- function control fo ALU zfc_acc_on : IN STD_LOGIC ; -- ZERO flag control for ACC value zfc_alu_on : IN STD_LOGIC ; -- ZERO flag control for ALU value zfc_acc : IN STD_LOGIC ; -- ZERO flag control for the result of shift/rotate in ACC alu : OUT STD_LOGIC_VECTOR(7 DOWNTO 0) ; -- the output of ALU carry : OUT STD_LOGIC ; -- output of CARRY flag register zero : OUT STD_LOGIC -- output of ZERO flag register ) ; END eu ; ARCHITECTURE behave OF eu IS SIGNAL c0,c1 : STD_LOGIC ; -- c0 is output of carry flag reg. -- c1 is the carry output of ALU, which is a combinational circuit. SIGNAL z_alu : STD_LOGIC ; -- z_alu is zero flag of the result of ALU. SIGNAL alu_ctl : STD_LOGIC_VECTOR(6 DOWNTO 0) ; -- Input port of ALU with the overflow bits SIGNAL a9, b9, result : STD_LOGIC_VECTOR(8 DOWNTO 0) ; -- a9 is the A port of ALU with overflow bit ( a9(8) ) -- b9 is the B port of ALU with overflow bit ( b9(8) ) -- result is the output of ALU with carry output ( result(8) ) BEGIN -- select the ALU functional alu_ctl <= alu_f_ctl & add_with_carry & sub_with_borrow ; a9 <= "0" & a ; -- insert the overflow bit b9 <= "0" & b ; -- insert overflow bit WITH alu_ctl SELECT -- transfer the A port data to the result. result <= a9 AFTER 100 ns WHEN "0000000" , -- increment the A port data. a9 + "000000001" AFTER 100 ns WHEN "0000011" , -- decrement the A port data. a9 - "000000001" AFTER 100 ns WHEN "1111111" , -- transfer the A port data to the result. b9 AFTER 100 ns WHEN "1101000" , -- add A port data and B port data witouth carry. a9 + b9 AFTER 100 ns WHEN "0100100" , -- add A port data and B port data with carry; a9 + b9 + ("0000000" & c0) AFTER 100 ns WHEN "0100110" , -- substract B port data from B port data without borrow. a9 - b9 AFTER 100 ns WHEN "0011000" , -- substract B port data from B port data with borrow. a9 - b9 + NOT ("0000000" & c0) AFTER 100 ns WHEN "0011001" , -- AND a9 AND b9 AFTER 100 ns WHEN "1101100" , -- OR a9 OR b9 AFTER 100 ns WHEN "1111000" , -- XOR a9 XOR b9 AFTER 100 ns WHEN "1011000" , -- clear "XXXXXXXXX" AFTER 100 ns WHEN OTHERS ; WITH alu_ctl SELECT c1 <= result(8) AFTER 100 ns WHEN "0000011", result(8) AFTER 100 ns WHEN "1111111", result(8) AFTER 100 ns WHEN "1101000", result(8) AFTER 100 ns WHEN "0100100", result(8) AFTER 100 ns WHEN "0100110", result(8) AFTER 100 ns WHEN "0011000", result(8) AFTER 100 ns WHEN "0011001", 'X' AFTER 100 ns WHEN OTHERS ; alu <= result(7 DOWNTO 0) ; -- to wait until the data become available through the bus -- that is expected to be implemented by 74LS541. z_alu <= result(0) OR result(1) OR result(2) OR result(3) OR result(4) OR result(5) OR result(6) OR result(7) ; carry_flag_reg : PROCESS(clk1) -- the process of the CARRY flag register BEGIN IF ((clk1 = '1') AND (clk1'LAST_VALUE = '0') AND clk1'EVENT) THEN -- edge triggered -- carry flag control CASE c_ctl IS WHEN "011" => c0 <= '0' ; -- clear carry WHEN "100" => c0 <= '1' ; -- set carry WHEN "101" => c0 <= acc_lsb ; -- shift/rotate right WHEN "110" => c0 <= acc_msb ; -- shift/rotate left WHEN "000" => c0 <= c0 ; WHEN "001" => c0 <= c1 ; WHEN OTHERS => c0 <= c0 ; END CASE ; END IF ; END PROCESS carry_flag_reg ; carry <= c0 ; zero_flag_reg : PROCESS(clk1) VARIABLE zfc : STD_LOGIC_VECTOR(3 DOWNTO 0) ; -- ZERO flag control for values of ACC and ALU BEGIN IF ((clk1 = '1') AND (clk1'LAST_VALUE = '0') AND clk1'EVENT) THEN zfc := zfc_acc_on & zfc_alu_on & z_alu & zfc_acc ; -- zero flag control CASE zfc IS -- ALU zero flag mode WHEN "0100" => zero <= '1' ; WHEN "0101" => zero <= '1' ; WHEN "0110" => zero <= '0' ; WHEN "0111" => zero <= '0' ; -- ACC zero flag mode WHEN "1001" => zero <= '1' ; WHEN "1011" => zero <= '1' ; WHEN "1000" => zero <= '0' ; WHEN "1010" => zero <= '0' ; -- etc. WHEN OTHERS => NULL ; END CASE ; END IF ; END PROCESS zero_flag_reg ; END behave ;