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

Subversion Repositories open8_urisc

[/] [open8_urisc/] [trunk/] [VHDL/] [o8_cpu.vhd] - Diff between revs 269 and 270

Go to most recent revision | Show entire file | Details | Blame | View Log

Rev 269 Rev 270
Line 39... Line 39...
--            :   Allow_Stack_Address_Move is false.
--            :   Allow_Stack_Address_Move is false.
--            :
--            :
--            :  Allow_Stack_Address_Move, when set true, allows the RSP to be
--            :  Allow_Stack_Address_Move, when set true, allows the RSP to be
--            :   programmed via thet RSP instruction. If enabled, the
--            :   programmed via thet RSP instruction. If enabled, the
--            :   instruction changes into TSX or TXS based on the flag
--            :   instruction changes into TSX or TXS based on the flag
--            :   specified by Stack_Xfer_Flag. If the flag is '0', RSP will
--            :   specified by STACK_XFER_FLAG. If the flag is '0', RSP will
--            :   copy the current stack pointer to R1:R0 (TSX). If the flag
--            :   copy the current stack pointer to R1:R0 (TSX). If the flag
--            :   is '1', RSP will copy R1:R0 to the stack pointer (TXS). This
--            :   is '1', RSP will copy R1:R0 to the stack pointer (TXS). This
--            :   allows the processor to backup and restore stack pointers
--            :   allows the processor to backup and restore stack pointers
--            :   in a multi-process environment. Note that no flags are
--            :   in a multi-process environment. Note that no flags are
--            :   modified by either form of this instruction.
--            :   modified by either form of this instruction.
--            :
--            :
--            :  Stack_Xfer_Flag instructs the core to use the specified ALU
--            :  STACK_XFER_FLAG instructs the core to use the specified ALU
--            :   flag to alter the behavior of the RSP instruction when
--            :   flag to alter the behavior of the RSP instruction when
--            :   Allow_Stack_Address_Move is set TRUE, otherwise it's ignored.
--            :   Allow_Stack_Address_Move is set TRUE, otherwise it's ignored.
--            :   While technically any of the status bits may be used, the
--            :   While technically any of the status bits may be used, the
--            :   intent was to use FL_GP[1,2,3,4], as these are not modified
--            :   intent was to use FL_GP[1,2,3,4], as these are not modified
--            :   by ordinary ALU operations.
--            :   by ordinary ALU operations.
Line 259... Line 259...
--                           pair wasn't being incremented properly due to a
--                           pair wasn't being incremented properly due to a
--                           missing UPP2 signal to the ALU.
--                           missing UPP2 signal to the ALU.
-- Seth Henry      10/21/20 Modified the write data path to use separate
-- Seth Henry      10/21/20 Modified the write data path to use separate
--                           enumerated states rather than reuse the .reg field
--                           enumerated states rather than reuse the .reg field
--                           to improve performance.
--                           to improve performance.
 
-- Seth Henry      10/23/20 Moved CPU internal constants to o8_cpu.vhd. Also
 
--                           removed Stack_Xfer_Flag, which specified the CPU
 
--                           flag used to alter the RSP instruction, making it
 
--                           a constant instead (PSR_GP4). This eliminated the
 
--                           need to expose an internal constant externally
 
 
library ieee;
library ieee;
  use ieee.std_logic_1164.all;
  use ieee.std_logic_1164.all;
  use ieee.std_logic_unsigned.all;
  use ieee.std_logic_unsigned.all;
  use ieee.std_logic_arith.all;
  use ieee.std_logic_arith.all;
Line 275... Line 280...
  generic(
  generic(
    Program_Start_Addr       : ADDRESS_TYPE := x"0000"; -- Initial PC location
    Program_Start_Addr       : ADDRESS_TYPE := x"0000"; -- Initial PC location
    ISR_Start_Addr           : ADDRESS_TYPE := x"FFF0"; -- Bottom of ISR vec's
    ISR_Start_Addr           : ADDRESS_TYPE := x"FFF0"; -- Bottom of ISR vec's
    Stack_Start_Addr         : ADDRESS_TYPE := x"03FF"; -- Top of Stack
    Stack_Start_Addr         : ADDRESS_TYPE := x"03FF"; -- Top of Stack
    Allow_Stack_Address_Move : boolean      := false;   -- Use Normal v8 RSP
    Allow_Stack_Address_Move : boolean      := false;   -- Use Normal v8 RSP
    Stack_Xfer_Flag          : integer      := PSR_GP4; -- GP4 modifies RSP
 
    Enable_Auto_Increment    : boolean      := false;   -- Modify indexed instr
    Enable_Auto_Increment    : boolean      := false;   -- Modify indexed instr
    BRK_Implements_WAI       : boolean      := false;   -- BRK -> Wait for Int
    BRK_Implements_WAI       : boolean      := false;   -- BRK -> Wait for Int
    Enable_NMI               : boolean      := true;    -- Force INTR0 enabled
    Enable_NMI               : boolean      := true;    -- Force INTR0 enabled
    Sequential_Interrupts    : boolean      := false;   -- Interruptable ISRs
    Sequential_Interrupts    : boolean      := false;   -- Interruptable ISRs
    RTI_Ignores_GP_Flags     : boolean      := false;   -- RTI sets all flags
    RTI_Ignores_GP_Flags     : boolean      := false;   -- RTI sets all flags
Line 311... Line 315...
  constant USEC_DLY          : std_logic_vector :=
  constant USEC_DLY          : std_logic_vector :=
                                conv_std_logic_vector(USEC_VAL - 1, USEC_WDT);
                                conv_std_logic_vector(USEC_VAL - 1, USEC_WDT);
  signal uSec_Cntr           : std_logic_vector( USEC_WDT - 1 downto 0 );
  signal uSec_Cntr           : std_logic_vector( USEC_WDT - 1 downto 0 );
  signal uSec_Tick           : std_logic;
  signal uSec_Tick           : std_logic;
 
 
 
  -- CPU Instruction Set Definitions
 
  subtype OPCODE_TYPE  is std_logic_vector(4 downto 0);
 
  subtype SUBOP_TYPE   is std_logic_vector(2 downto 0);
 
 
 
  -- All opcodes should be identical to the opcode used by the assembler
 
  -- In this case, they match the original V8/ARC uRISC ISA
 
  constant OP_INC            : OPCODE_TYPE := "00000";
 
  constant OP_ADC            : OPCODE_TYPE := "00001";
 
  constant OP_TX0            : OPCODE_TYPE := "00010";
 
  constant OP_OR             : OPCODE_TYPE := "00011";
 
  constant OP_AND            : OPCODE_TYPE := "00100";
 
  constant OP_XOR            : OPCODE_TYPE := "00101";
 
  constant OP_ROL            : OPCODE_TYPE := "00110";
 
  constant OP_ROR            : OPCODE_TYPE := "00111";
 
  constant OP_DEC            : OPCODE_TYPE := "01000";
 
  constant OP_SBC            : OPCODE_TYPE := "01001";
 
  constant OP_ADD            : OPCODE_TYPE := "01010";
 
  constant OP_STP            : OPCODE_TYPE := "01011";
 
  constant OP_BTT            : OPCODE_TYPE := "01100";
 
  constant OP_CLP            : OPCODE_TYPE := "01101";
 
  constant OP_T0X            : OPCODE_TYPE := "01110";
 
  constant OP_CMP            : OPCODE_TYPE := "01111";
 
  constant OP_PSH            : OPCODE_TYPE := "10000";
 
  constant OP_POP            : OPCODE_TYPE := "10001";
 
  constant OP_BR0            : OPCODE_TYPE := "10010";
 
  constant OP_BR1            : OPCODE_TYPE := "10011";
 
  constant OP_DBNZ           : OPCODE_TYPE := "10100"; -- USR
 
  constant OP_INT            : OPCODE_TYPE := "10101";
 
  constant OP_MUL            : OPCODE_TYPE := "10110"; -- USR2
 
  constant OP_STK            : OPCODE_TYPE := "10111";
 
  constant OP_UPP            : OPCODE_TYPE := "11000";
 
  constant OP_STA            : OPCODE_TYPE := "11001";
 
  constant OP_STX            : OPCODE_TYPE := "11010";
 
  constant OP_STO            : OPCODE_TYPE := "11011";
 
  constant OP_LDI            : OPCODE_TYPE := "11100";
 
  constant OP_LDA            : OPCODE_TYPE := "11101";
 
  constant OP_LDX            : OPCODE_TYPE := "11110";
 
  constant OP_LDO            : OPCODE_TYPE := "11111";
 
 
 
  -- OP_STK uses the lower 3 bits to further refine the instruction by
 
  --  repurposing the source register field. These "sub opcodes" take
 
  --  the place of the register select for the OP_STK opcode
 
  constant SOP_RSP           : SUBOP_TYPE := "000";
 
  constant SOP_RTS           : SUBOP_TYPE := "001";
 
  constant SOP_RTI           : SUBOP_TYPE := "010";
 
  constant SOP_BRK           : SUBOP_TYPE := "011";
 
  constant SOP_JMP           : SUBOP_TYPE := "100";
 
  constant SOP_SMSK          : SUBOP_TYPE := "101";
 
  constant SOP_GMSK          : SUBOP_TYPE := "110";
 
  constant SOP_JSR           : SUBOP_TYPE := "111";
 
 
 
  -- These should match the assembler's definitions for the flags
 
  constant PSR_Z             : integer := 0;
 
  constant PSR_C             : integer := 1;
 
  constant PSR_N             : integer := 2;
 
  constant PSR_I             : integer := 3;
 
  constant PSR_GP4           : integer := 4;
 
  constant PSR_GP5           : integer := 5;
 
  constant PSR_GP6           : integer := 6;
 
  constant PSR_GP7           : integer := 7;
 
 
 
  -- Internal CPU Signals & Constants
 
 
 
  type CPU_STATES is (
 
      -- Instruction fetch & Decode
 
    IPF_C0, IPF_C1, IPF_C2, IDC_C0,
 
    -- Branching
 
    BRN_C1, DBNZ_C1, JMP_C1, JMP_C2,
 
    -- Loads
 
    LDA_C1, LDA_C2, LDA_C3, LDA_C4, LDI_C1,
 
    LDO_C1, LDO_C2, LDX_C1, LDX_C2, LDX_C3, LDX_C4,
 
    -- Stores
 
    STA_C1, STA_C2, STA_C3, STO_C1, STO_C2, STO_C3, STX_C1, STX_C2,
 
    -- 2-cycle math
 
    MUL_C1, UPP_C1,
 
    -- Stack
 
    PSH_C1, POP_C1, POP_C2, POP_C3, POP_C4,
 
    -- Subroutines & Interrupts
 
    WAI_Cx, WAH_Cx, BRK_C1,
 
    ISR_C1, ISR_C2, ISR_C3, JSR_C1, JSR_C2,
 
    RTS_C1, RTS_C2, RTS_C3, RTS_C4, RTS_C5, RTI_C6
 
     );
 
 
 
  type CACHE_MODES is (CACHE_IDLE, CACHE_INSTR, CACHE_OPER1, CACHE_OPER2,
 
                       CACHE_PREFETCH );
 
 
 
  type PC_MODES is ( PC_INCR, PC_LOAD );
 
 
 
  type PC_CTRL_TYPE is record
 
    Oper                     : PC_MODES;
 
    Offset                   : DATA_TYPE;
 
  end record;
 
 
 
  -- These are fixed constant offsets to the program counter logic, which is
 
  --  always either incrementing or loading.
 
  constant PC_NEXT           : DATA_TYPE := x"03";
 
  constant PC_IDLE           : DATA_TYPE := x"02";
 
  constant PC_REV1           : DATA_TYPE := x"01";
 
  constant PC_REV2           : DATA_TYPE := x"00";
 
  constant PC_REV3           : DATA_TYPE := x"FF";
 
 
 
  type SP_MODES is ( SP_IDLE, SP_CLR, SP_SET, SP_POP, SP_PUSH );
 
 
 
  type SP_CTRL_TYPE is record
 
    Oper                     : SP_MODES;
 
  end record;
 
 
 
  -- This constant determines which CPU flag is used to switch the
 
  --  direction of the modified RSP instruction
 
  constant STACK_XFER_FLAG   : integer := PSR_GP4; -- GP4 modifies RSP
 
 
 
  type DP_MODES is ( DATA_BUS_IDLE, DATA_RD_MEM,
 
                     DATA_WR_REG, DATA_WR_FLAG,
 
                     DATA_WR_PC_L, DATA_WR_PC_H );
 
 
 
  type DATA_CTRL_TYPE is record
 
    Src                      : DP_MODES;
 
    Reg                      : SUBOP_TYPE;
 
  end record;
 
 
 
  type INT_CTRL_TYPE is record
 
    Mask_Set                 : std_logic;
 
    Soft_Ints                : INTERRUPT_BUNDLE;
 
    Incr_ISR                 : std_logic;
 
  end record;
 
 
 
  -- Most of the ALU instructions are the same as their Opcode equivalents,
 
  --  with exceptions for IDLE, UPP2, RFLG, RSP, and GMSK, which perform
 
  --  internal operations not otherwise exposed by the instruction set.
 
  constant ALU_INC           : OPCODE_TYPE := "00000"; -- x"00"
 
  constant ALU_ADC           : OPCODE_TYPE := "00001"; -- x"01"
 
  constant ALU_TX0           : OPCODE_TYPE := "00010"; -- x"02"
 
  constant ALU_OR            : OPCODE_TYPE := "00011"; -- x"03"
 
  constant ALU_AND           : OPCODE_TYPE := "00100"; -- x"04"
 
  constant ALU_XOR           : OPCODE_TYPE := "00101"; -- x"05"
 
  constant ALU_ROL           : OPCODE_TYPE := "00110"; -- x"06"
 
  constant ALU_ROR           : OPCODE_TYPE := "00111"; -- x"07"
 
  constant ALU_DEC           : OPCODE_TYPE := "01000"; -- x"08"
 
  constant ALU_SBC           : OPCODE_TYPE := "01001"; -- x"09"
 
  constant ALU_ADD           : OPCODE_TYPE := "01010"; -- x"0A"
 
  constant ALU_STP           : OPCODE_TYPE := "01011"; -- x"0B"
 
  constant ALU_BTT           : OPCODE_TYPE := "01100"; -- x"0C"
 
  constant ALU_CLP           : OPCODE_TYPE := "01101"; -- x"0D"
 
  constant ALU_T0X           : OPCODE_TYPE := "01110"; -- x"0E"
 
  constant ALU_CMP           : OPCODE_TYPE := "01111"; -- x"0F"
 
  constant ALU_POP           : OPCODE_TYPE := "10001"; -- x"11"
 
  constant ALU_MUL           : OPCODE_TYPE := "10110"; -- x"16"
 
  constant ALU_UPP           : OPCODE_TYPE := "11000"; -- x"18"
 
  constant ALU_LDI           : OPCODE_TYPE := "11100"; -- x"1C"
 
 
 
  constant ALU_IDLE          : OPCODE_TYPE := "10000"; -- x"10"
 
  constant ALU_UPP2          : OPCODE_TYPE := "10010"; -- x"12"
 
  constant ALU_RFLG          : OPCODE_TYPE := "10011"; -- x"13"
 
  constant ALU_RSP           : OPCODE_TYPE := "10111"; -- x"17"
 
  constant ALU_GMSK          : OPCODE_TYPE := "11111"; -- x"1F"
 
 
 
  type ALU_CTRL_TYPE is record
 
    Oper                     : OPCODE_TYPE;
 
    Reg                      : SUBOP_TYPE;
 
  end record;
 
 
 
  constant ACCUM             : SUBOP_TYPE := "000";
 
 
 
  type REGFILE_TYPE is array (0 to 7) of DATA_TYPE;
 
 
 
  subtype FLAG_TYPE is DATA_TYPE;
 
 
  signal CPU_Next_State      : CPU_STATES := IPF_C0;
  signal CPU_Next_State      : CPU_STATES := IPF_C0;
  signal CPU_State           : CPU_STATES := IPF_C0;
  signal CPU_State           : CPU_STATES := IPF_C0;
 
 
  signal CPU_Halt_Req        : std_logic := '0';
  signal CPU_Halt_Req        : std_logic := '0';
  signal CPU_Halt_Ack        : std_logic := '0';
  signal CPU_Halt_Ack        : std_logic := '0';
Line 555... Line 726...
          when OP_BR0 | OP_BR1 =>
          when OP_BR0 | OP_BR1 =>
            CPU_Next_State   <= BRN_C1;
            CPU_Next_State   <= BRN_C1;
            Cache_Ctrl       <= CACHE_OPER1;
            Cache_Ctrl       <= CACHE_OPER1;
            PC_Ctrl.Offset   <= PC_NEXT;
            PC_Ctrl.Offset   <= PC_NEXT;
 
 
 
 
          when OP_DBNZ =>
          when OP_DBNZ =>
            CPU_Next_State   <= DBNZ_C1;
            CPU_Next_State   <= DBNZ_C1;
            Cache_Ctrl       <= CACHE_OPER1;
            Cache_Ctrl       <= CACHE_OPER1;
            PC_Ctrl.Offset   <= PC_NEXT;
            PC_Ctrl.Offset   <= PC_NEXT;
            ALU_Ctrl.Oper    <= ALU_DEC;
            ALU_Ctrl.Oper    <= ALU_DEC;
Line 584... Line 754...
                  -- The default behavior for this instruction is to simply
                  -- The default behavior for this instruction is to simply
                  --  repoint the SP to the HDL default
                  --  repoint the SP to the HDL default
                  SP_Ctrl.Oper    <= SP_CLR;
                  SP_Ctrl.Oper    <= SP_CLR;
                end if;
                end if;
                if( Allow_Stack_Address_Move and
                if( Allow_Stack_Address_Move and
                    Flags(Stack_Xfer_Flag) = '1' )then
                    Flags(STACK_XFER_FLAG) = '1' )then
                  -- If RSP is set to allow SP moves, and the specified flag
                  -- If RSP is set to allow SP moves, and the specified flag
                  --  is true, then signal the stack pointer logic to load
                  --  is true, then signal the stack pointer logic to load
                  --  from R1:R0
                  --  from R1:R0
                  SP_Ctrl.Oper    <= SP_SET;
                  SP_Ctrl.Oper    <= SP_SET;
                end if;
                end if;
                if( Allow_Stack_Address_Move and
                if( Allow_Stack_Address_Move and
                    Flags(Stack_Xfer_Flag) = '0')then
                    Flags(STACK_XFER_FLAG) = '0')then
                  -- If RSP is set to allow SP moves, and the specified flag
                  -- If RSP is set to allow SP moves, and the specified flag
                  --  is false, then signal the ALU to copy the stack pointer
                  --  is false, then signal the ALU to copy the stack pointer
                  --  to R1:R0
                  --  to R1:R0
                  ALU_Ctrl.Oper   <= ALU_RSP;
                  ALU_Ctrl.Oper   <= ALU_RSP;
                end if;
                end if;
Line 746... Line 916...
          INT_Ctrl.Mask_Set       <= '0';
          INT_Ctrl.Mask_Set       <= '0';
          INT_Ctrl.Soft_Ints(Reg) <= '0';
          INT_Ctrl.Soft_Ints(Reg) <= '0';
        end if;
        end if;
 
 
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
-- Program Control (BR0_C1, BR1_C1, DBNZ_C1, JMP )
-- Program Control (BRx, BNx, DBNZ, JMP )
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
 
 
      when BRN_C1 =>
      when BRN_C1 =>
        CPU_Next_State       <= IDC_C0;
        CPU_Next_State       <= IDC_C0;
        Cache_Ctrl           <= CACHE_INSTR;
        Cache_Ctrl           <= CACHE_INSTR;

powered by: WebSVN 2.1.0

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