OpenCores
URL https://opencores.org/ocsvn/pdp8/pdp8/trunk

Subversion Repositories pdp8

[/] [pdp8/] [trunk/] [pdp8/] [cpu/] [alu.vhd] - Rev 2

Compare with Previous | Blame | View Log

------------------------------------------------------------------
--!
--! PDP-8 Processor
--!
--! \brief
--!      CPU Arithmetic Logic Unit (ALU) Register
--!
--! \details
--!      The ALU 'owns' the Link Register (L) and Accumulator
--!      Register (AC).  This device performs every operation
--!      that manipules either the Link Register or Accumulator.
--!
--!      This code operates on the Link Register and Accumulator
--!      as if it were a single 13-bit wide register.  The Link
--!      Register is LAC(0) while the Accumlator is LAC(1 to 12).
--!
--! \todo
--!      Although the CPU is knitted together with a 'rats nest'
--!      of interconnections, this file is 'rattier' than most.
--!      It could stand a good cleanup.   Any cleanup should also
--!      address EAE and how that fits with the ALU.
--!
--! \file
--!      alu.vhd
--!
--! \author
--!      Rob Doyle - doyle (at) cox (dot) net
--!
--------------------------------------------------------------------
--
--  Copyright (C) 2009, 2010, 2011, 2012 Rob Doyle
--
-- This source file may be used and distributed without
-- restriction provided that this copyright statement is not
-- removed from the file and that any derivative work contains
-- the original copyright notice and the associated disclaimer.
--
-- This source file is free software; you can redistribute it
-- and/or modify it under the terms of the GNU Lesser General
-- Public License as published by the Free Software Foundation;
-- version 2.1 of the License.
--
-- This source is distributed in the hope that it will be
-- useful, but WITHOUT ANY WARRANTY; without even the implied
-- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
-- PURPOSE. See the GNU Lesser General Public License for more
-- details.
--
-- You should have received a copy of the GNU Lesser General
-- Public License along with this source; if not, download it
-- from http://www.gnu.org/licenses/lgpl.txt
--
--------------------------------------------------------------------
--
-- Comments are formatted for doxygen
--
 
library ieee;                                   --! IEEE Library
use ieee.std_logic_1164.all;                    --! IEEE 1164
use ieee.numeric_std.all;                       --! IEEE Numeric Standard
use work.cpu_types.all;                         --! Types
 
--
--! CPU Arithmetic Logic Unit (ALU) Register Entity
--
 
entity eALU is port (
    sys    : in  sys_t;                         --! Clock/Reset
    acOP   : in  acOP_t;                        --! AC Operation
    BTSTRP : in  std_logic;                     --! Bootstrap Flag
    GTF    : in  std_logic;                     --! Greater Than Flag
    HLTTRP : in  std_logic;                     --! Hlttrp Flag
    IE     : in  std_logic;                     --! Interrupt Enable Flip-Flop
    IRQ    : in  std_logic;                     --! Interrupt Request flag
    PNLTRP : in  std_logic;                     --! Panel Trap Flag
    PWRTRP : in  std_logic;                     --! Power-on Trap Flag
    DF     : in  field_t;                       --! DF Input
    EAE    : in  eae_t;                         --! EAE Input
    INF    : in  field_t;                       --! INF Input
    IR     : in  data_t;                        --! IR Input
    MA     : in  addr_t;                        --! MA Input
    MD     : in  data_t;                        --! MB Input
    MQ     : in  data_t;                        --! MQ Input
    PC     : in  addr_t;                        --! PC Input
    SC     : in  sc_t;                          --! SC Input
    SF     : in  sf_t;                          --! SF Input
    SP1    : in  addr_t;                        --! SP1 Input
    SP2    : in  addr_t;                        --! SP2 Input
    SR     : in  data_t;                        --! SR Input
    UF     : in  std_logic;                     --! UF Input
    LAC    : out ldata_t                        --! ALU Output
);
end eALU;
 
--
--! CPU Arithmetic Logic Unit (ALU) Register RTL
--
 
architecture rtl of eALU is
 
    signal   lacREG         : ldata_t;          --! Link and Accumulator Register
    signal   lacMUX         : ldata_t;          --! Link and Accumulator Multiplexer
 
    --!
    --! ALU Operations
    --!
 
    signal   opIAC          : ldata_t;          --! Increment accumulator
    signal   opBSW          : ldata_t;          --! Byte swap
    signal   opRAL          : ldata_t;          --! 
    signal   opRTL          : ldata_t;          --! 
    signal   opR3L          : ldata_t;          --! 
    signal   opRAR          : ldata_t;          --! 
    signal   opRTR          : ldata_t;          --! 
    signal   opSHL0         : ldata_t;          --! 
    signal   opSHL1         : ldata_t;          --! 
    signal   opLSR          : ldata_t;          --! 
    signal   opASR          : ldata_t;          --!
    signal   opUNDEF1       : ldata_t;          --! Undefined Operation #1
    signal   opUNDEF2       : ldata_t;          --! Undefined Operation #2
    signal   opPC           : ldata_t;          --! Undefined Operation #1,2
    signal   opCML          : ldata_t;          --! 
    signal   opCMA          : ldata_t;          --! 
    signal   opCMACML       : ldata_t;          --! 
    signal   opCLL          : ldata_t;          --! 
    signal   opCLLCML       : ldata_t;          --! 
    signal   opCLLCMA       : ldata_t;          --! 
    signal   opCLLCMACML    : ldata_t;          --! 
    signal   opCLA          : ldata_t;          --! 
    signal   opCLACML       : ldata_t;          --! 
    signal   opCLACMA       : ldata_t;          --! 
    signal   opCLACMACML    : ldata_t;          --! 
    signal   opCLACLL       : ldata_t;          --! 
    signal   opCLACLLCML    : ldata_t;          --! 
    signal   opCLACLLCMA    : ldata_t;          --! 
    signal   opCLACLLCMACML : ldata_t;          --! 
 
    --!
    --! KM8E
    --!
 
    signal   opRDF0         : ldata_t;          --! RDF0 (HD6120)
    signal   opRIF0         : ldata_t;          --! RIF0 (HD6120)
    signal   opRIB0         : ldata_t;          --! RIB0 (HD6120)
    signal   opRDF1         : ldata_t;          --! RDF1 (PDP8)
    signal   opRIF1         : ldata_t;          --! RIF1 (PDP8)
    signal   opRIB1         : ldata_t;          --! RIB1 (PDP8)
 
    --!
    --! EAE
    --!
 
    signal   opEAELAC       : ldata_t;          --! LAC <- EAE(0 to 12)
    signal   opEAEZAC       : ldata_t;          --! LAC <- '0' & EAE(1 to 12)
 
    --!
    --! Flags
    --!
 
    signal   opPRS          : ldata_t;          --!
    signal   opGTF1         : ldata_t;          --!
    signal   opGTF2         : ldata_t;          --!
    signal   opGCF          : ldata_t;          --!
 
    --!
    --! MD operations
    --!
 
    signal   opSUBMD        : ldata_t;          --! LAC <- LAC - MD
    signal   opADDMD        : ldata_t;          --! LAC <- LAC + MD
    signal   opADDMDP1      : ldata_t;          --! LAC <- LAC + MD + 1
    signal   opANDMD        : ldata_t;          --! LAC <- L & (AC and MD)
    signal   opORMD         : ldata_t;          --! LAC <- L & (AC or  MD)
 
    --!
    --! MQ Operations
    --!
 
    signal   opMQSUB        : ldata_t;          --! LAC <- MQ - AC
    signal   opMQ           : ldata_t;          --! LAC <- L & MQ
    signal   opZMQ          : ldata_t;          --! LAC <- '0' & MQ
    signal   opMQP1         : ldata_t;          --! LAC <-  MQ + 1
    signal   opNEGMQ        : ldata_t;          --! LAC <- -MQ
    signal   opNOTMQ        : ldata_t;          --! LAC <- not(MQ)
    signal   opORMQ         : ldata_t;          --! LAC <- L & (AC or MQ)
 
    --!
    --! SC Operations
    --!
 
    signal   opSCA          : ldata_t;          --! LAC <- L & (AC or  SC)
 
    --!
    --! SP Operations
    --!
 
    signal   opSP1          : ldata_t;          --! LAC <- '0' & SP1
    signal   opSP2          : ldata_t;          --! LAC <- '0' & SP2
 
    --!
    --! SR Operations
    --!
 
    signal   opOSR          : ldata_t;          --! LAC <- L & (AC or SR)
    signal   opLAS          : ldata_t;          --! LAC <- L & SR
 
begin
 
    -- group1 sequence 4 operations
    opIAC           <= std_logic_vector(unsigned(lacREG) + "1");
    opBSW           <= lacREG(0) & lacREG(7 to 12) & lacREG(1 to 6);
    -- rotate lefts
    opRAL           <= lacREG( 1 to 12) & lacREG(0);
    opRTL           <= lacREG( 2 to 12) & lacREG(0 to 1);
    opR3L           <= lacREG( 3 to 12) & lacREG(0 to 2);
    -- rotate rights
    opRAR           <= lacREG(12)       & lacREG(0 to 11);
    opRTR           <= lacREG(11 to 12) & lacREG(0 to 10);
    -- shift lefts
    opSHL0          <= lacREG( 1 to 12) & '0';
    opSHL1          <= lacREG( 1 to 12) & '1';
    -- shift rights
    opLSR           <= '0' & lacREG(0 to 11);
    opASR           <= lacREG(1) & lacREG(1) & lacREG(1 to 11);
    -- undefs
    opUNDEF1        <= lacREG(0) & (lacREG(1 to 12) and IR);
    opUNDEF2        <= lacREG(0) & MA(0 to 4) & IR(5 to 11);
    opPC            <= lacREG(0) & PC;
    -- group 1 operations
    opCML           <= not(lacREG(0)) &     lacREG(1 to 12);
    opCMA           <=     lacREG(0)  & not(lacREG(1 to 12));
    opCMACML        <= not(lacREG(0)) & not(lacREG(1 to 12));
    opCLL           <= '0'            &     lacREG(1 to 12);
    opCLLCML        <= '1'            &     lacREG(1 to 12);
    opCLLCMA        <= '0'            & not(lacREG(1 to 12));
    opCLLCMACML     <= '1'            & not(lacREG(1 to 12));
    opCLA           <=     lacREG(0)  & o"0000";
    opCLACML        <= not(lacREG(0)) & o"0000";
    opCLACMA        <=     lacREG(0)  & o"7777";
    opCLACMACML     <= not(lacREG(0)) & o"7777";
    opCLACLL        <= '0'            & o"0000";
    opCLACLLCML     <= '1'            & o"0000";
    opCLACLLCMA     <= '0'            & o"7777";
    opCLACLLCMACML  <= '1'            & o"7777";
    -- KM8E ops
    opRDF0          <= lacREG(0 to  6) & DF  & lacREG(10 to 12);
    opRIF0          <= lacREG(0 to  6) & INF & lacREG(10 to 12);
    opRIB0          <= lacREG(0 to  5) & SF;
    opRDF1          <= lacREG(0 to 12) or ("0000000" & DF  & "000");
    opRIF1          <= lacREG(0 to 12) or ("0000000" & INF & "000");
    opRIB1          <= lacREG(0 to 12) or ("000000"  & SF);
    -- Flags
    opPRS           <= lacREG(0) & BTSTRP    & PNLTRP & IRQ & PWRTRP & HLTTRP & '0'   & "000"      & "000";
    opGTF1          <= lacREG(0) & lacREG(0) & GTF    & IRQ & PWRTRP & '1'    & '0'   & SF(1 to 3) & SF(4 to 6);
    opGTF2          <= lacREG(0) & lacREG(0) & GTF    & IRQ &  '0'   & IE     & SF(0) & SF(1 to 3) & SF(4 to 6);
    opGCF           <= lacREG(0) & lacREG(0) & GTF    & IRQ & PWRTRP & IE     & '0'   & INF        & DF;
    -- EAE
    opEAELAC        <= EAE(0 to 12);
    opEAEZAC        <= '0' & EAE(1 to 12);
    -- MD
    opADDMD         <= std_logic_vector(unsigned(lacREG(0 to 12)) + unsigned('0' & MD));
    opADDMDP1       <= std_logic_vector(unsigned(lacREG(0 to 12)) + unsigned('0' & MD) + "1");
    opSUBMD         <= std_logic_vector(unsigned(lacREG(0 to 12)) - unsigned('0' & MD));
    opANDMD         <= lacREG(0) & (lacREG(1 to 12) and MD);
    opORMD          <= lacREG(0) & (lacREG(1 to 12) or  MD);
    -- MQ
    opMQSUB         <= std_logic_vector(unsigned('0' & MQ) + unsigned('0' & not(lacREG(1 to 12))) + "1");
    opMQ            <= lacREG(0) & MQ;
    opZMQ           <= '0' & MQ;
    opMQP1          <= std_logic_vector(unsigned('0' & MQ) + "1");
    opNEGMQ         <= std_logic_vector(unsigned('0' & not(MQ)) + "1");
    opNOTMQ         <= '0' & not(MQ);
    opORMQ          <= lacREG(0) & (lacREG(1 to 12) or MQ);
    -- SC
    opSCA           <= lacREG(0 to 7) & (lacREG(8 to 12) or SC);
    -- SP
    opSP1           <= lacREG(0) & SP1;
    opSP2           <= lacREG(0) & SP2;
    -- SR
    opLAS           <= lacREG(0) & SR;
    opOSR           <= lacREG(0) & (lacREG(1 to 12) or SR);
 
    --
    -- Adder input #2 mux.
    --
 
    with acOP select
        lacMUX <= lacREG          when acopNOP,         -- LAC <- LAC
                  opIAC           when acopIAC,         -- LAC <- LAC + 1
                  opBSW           when acopBSW,         -- LAC <- L & AC(6:12) & AC(0:5);
                  opRAL           when acopRAL,         -- LAC <- AC(0:11) & L
                  opRTL           when acopRTL,         -- LAC <- AC(1:11) & L & AC(0)
                  opR3L           when acopR3L,         -- LAC <- AC(2:11) & L & AC(0:1)
                  opRAR           when acopRAR,         -- LAC <- AC(11) & L & & AC(0:10);
                  opRTR           when acopRTR,         -- LAC <- AC(10:11) & L & & AC(0:9);
                  opSHL0          when acopSHL0,        -- LAC <- (LAC << 1) & '0'
                  opSHL1          when acopSHL1,        -- LAC <- (LAC << 1) & '1'
                  opLSR           when acopLSR,         -- LAC <- '0' & (LAC >> 1)
                  opASR           when acopASR,         -- LAC <-  L  & (LAC >> 1)
                  opUNDEF1        when acopUNDEF1,      -- LAC <-  L  & (AC and IR);
                  opUNDEF2        when acopUNDEF2,      -- LAC <-  L  & MA(0:4) & IR(5:11)
                  opPC            when acopPC,          -- LAC <- PC
                  opCML           when acopCML,         -- LAC <-  0   0   0  CML
                  opCMA           when acopCMA,         -- LAC <-  0   0  CMA  0
                  opCMACML        when acopCMACML,      -- LAC <-  0   0  CMA CML
                  opCLL           when acopCLL,         -- LAC <-  0  CLL  0   0
                  opCLLCML        when acopCLLCML,      -- LAC <-  0  CLL  0  CML
                  opCLLCMA        when acopCLLCMA,      -- LAC <-  0  CLL CMA  0
                  opCLLCMACML     when acopCLLCMACML,   -- LAC <-  0  CLL CMA CML
                  opCLA           when acopCLA,         -- LAC <- CLA  0   0   0
                  opCLACML        when acopCLACML,      -- LAC <- CLA  0   0  CML 
                  opCLACMA        when acopCLACMA,      -- LAC <- CLA  0  CMA  0
                  opCLACMACML     when acopCLACMACML,   -- LAC <- CLA  0  CMA CML
                  opCLACLL        when acopCLACLL,      -- LAC <- CLA CLL  0   0
                  opCLACLLCML     when acopCLACLLCML,   -- LAC <- CLA CLL  0  CML
                  opCLACLLCMA     when acopCLACLLCMA,   -- LAC <- CLA CLL CMA  0
                  opCLACLLCMACML  when acopCLACLLCMACML,-- LAC <- CLA CLL CMA CML
                  opRDF0          when acopRDF0,        -- LAC <- LAC(0 to  6) & DF  & LAC(10 to 12)
                  opRIF0          when acopRIF0,        -- LAC <- LAC(0 to  6) & INF & LAC(10 to 12);
                  opRIB0          when acopRIB0,        -- LAC <- LAC(0 to  5) & SF
                  opRDF1          when acopRDF1,        -- LAC <- LAC(0 to 12) or ("0000000" & DF  & "000");
                  opRIF1          when acopRIF1,        -- LAC <- LAC(0 to 12) or ("0000000" & INF & "000")
                  opRIB1          when acopRIB1,        -- LAC <- LAC(0 to 12) or ("000000"  & SF);
                  opPRS           when acopPRS,         -- LAC <- LAC(0) & BTSTRP    & PNLTRP & IRQ & PWRTRP & HLTTRP & '0'   & "000"      & "000";
                  opGTF1          when acopGTF1,        -- HD6120 GTF
                  opGTF2          when acopGTF2,        -- PDP8 GTF
                  opGCF           when acopGCF,         -- LAC <- LAC(0) & LAC(0) & GTF    & IRQ & PWRTRP & IE     & '0'   & INF        & DF;
                  opEAELAC        when acopEAELAC,      -- LAC <- EAE(0 to 12)
                  opEAEZAC        when acopEAEZAC,      -- LAC <- '0' & EAE(1 to 12);
                  opSUBMD         when acopSUBMD,       -- LAC <- LAC - MD <- LAC + NOT(MD) + 1
                  opADDMD         when acopADDMD,       -- LAC <- LAC + MD
                  opADDMDP1       when acopADDMDP1,     -- LAC <- LAC + MD + 1
                  opANDMD         when acopANDMD,       -- LAC <- L & (AC and MD)
                  opORMD          when acopORMD,        -- LAC <- L & (AC or MD)
                  opMQSUB         when acopMQSUB,       -- LAC <- MQ - AC <- MQ + NOT(AC) + 1
                  opMQ            when acopMQ,          -- LAC <- L & MQ
                  opZMQ           when acopZMQ,         -- LAC <- 0 & MQ
                  opMQP1          when acopMQP1,        -- LAC <- MQ + 1
                  opNEGMQ         when acopNEGMQ,       -- LAC <- -MQ <- NOT(MQ) + 1
                  opNOTMQ         when acopNOTMQ,       -- LAC <- NOT(MQ)
                  opORMQ          when acopORMQ,        -- LAC <- L & (AC or MQ)
                  opSCA           when acopSCA,         -- LAC <- LAC(0 to 7) & (LAC(8 to 12) or SC)
                  opSP1           when acopSP1,         -- LAC <- LAC(0) & SP1
                  opSP2           when acopSP2,         -- LAC <- LAC(0) & SP2
                  opLAS           when acopLAS,         -- LAC <- SR
                  opOSR           when acopOSR,         -- LAC <- LAC(0) & (LAC(1 to 12) or SR)
                  (others => '0') when others;          -- 
 
    --
    --! ALU Register
    --
 
    REG_ALU : process(sys)
    begin
        if sys.rst = '1' then
            lacREG <= (others => '0');
        elsif rising_edge(sys.clk) then
            lacREG <= lacMUX;
        end if;
    end process REG_ALU;
 
    LAC <= lacREG;
 
end rtl;
 

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.