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