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 186 and 187

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

Rev 186 Rev 187
Line 150... Line 150...
-- Seth Henry      07/27/11 Optimized logic for timing, merged blocks into
-- Seth Henry      07/27/11 Optimized logic for timing, merged blocks into
--                           single entity.
--                           single entity.
-- Seth Henry      09/20/11 Added BRK_Implements_WAI option, allowing the
-- Seth Henry      09/20/11 Added BRK_Implements_WAI option, allowing the
--                           processor to wait for an interrupt instead of the
--                           processor to wait for an interrupt instead of the
--                           normal BRK behavior.
--                           normal BRK behavior.
-- Seth Henry      12/20/11 Modified core to allow WAIT_FOR_INT state to idle
-- Seth Henry      12/20/11 Modified core to allow WAI_Cx state to idle
--                           the bus entirely (Rd_Enable is low)
--                           the bus entirely (Rd_Enable is low)
-- Seth Henry      02/03/12 Replaced complex interrupt controller with simpler,
-- Seth Henry      02/03/12 Replaced complex interrupt controller with simpler,
--                           faster logic that simply does priority encoding.
--                           faster logic that simply does priority encoding.
-- Seth Henry      08/06/13 Removed HALT functionality
-- Seth Henry      08/06/13 Removed HALT functionality
-- Seth Henry      10/29/15 Fixed inverted carry logic in CMP and SBC instrs
-- Seth Henry      10/29/15 Fixed inverted carry logic in CMP and SBC instrs
Line 174... Line 174...
--                           original modes as fixed offset values.
--                           original modes as fixed offset values.
--                          Modified the ALU section with a new ALU operation
--                          Modified the ALU section with a new ALU operation
--                           for GMSK. This allowed the .data field to be
--                           for GMSK. This allowed the .data field to be
--                           removed and Operand1 used in its place, which
--                           removed and Operand1 used in its place, which
--                           simplified the logic a great deal.
--                           simplified the logic a great deal.
 
-- Seth Henry      03/16/20 Added CPU_Halt input back, only now as an input to
 
--                           the instruction decode state, where it acts as a
 
--                           modified form of the BRK instruction that holds
 
--                           state until CPU_Halt is deasserted. This has a
 
--                           much smaller impact on Fmax/complexity than the
 
--                           original clock enable, but imposes a mild impact
 
--                           due to the need to reset the instruction pipeline
 
 
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 199... Line 206...
    Default_Interrupt_Mask   : DATA_TYPE    := x"FF";   -- Enable all Ints
    Default_Interrupt_Mask   : DATA_TYPE    := x"FF";   -- Enable all Ints
    Reset_Level              : std_logic    := '0' );   -- Active reset level
    Reset_Level              : std_logic    := '0' );   -- Active reset level
  port(
  port(
    Clock                    : in  std_logic;
    Clock                    : in  std_logic;
    Reset                    : in  std_logic;
    Reset                    : in  std_logic;
    Interrupts               : in  INTERRUPT_BUNDLE;
    CPU_Halt                 : in  std_logic := '0';
 
    Interrupts               : in  INTERRUPT_BUNDLE := x"00";
    --
    --
    Address                  : out ADDRESS_TYPE;
    Address                  : out ADDRESS_TYPE;
    Rd_Data                  : in  DATA_TYPE;
    Rd_Data                  : in  DATA_TYPE;
    Rd_Enable                : out std_logic;
    Rd_Enable                : out std_logic;
    Wr_Data                  : out DATA_TYPE;
    Wr_Data                  : out DATA_TYPE;
Line 219... Line 227...
  constant INT_VECTOR_4      : ADDRESS_TYPE := ISR_Start_Addr+8;
  constant INT_VECTOR_4      : ADDRESS_TYPE := ISR_Start_Addr+8;
  constant INT_VECTOR_5      : ADDRESS_TYPE := ISR_Start_Addr+10;
  constant INT_VECTOR_5      : ADDRESS_TYPE := ISR_Start_Addr+10;
  constant INT_VECTOR_6      : ADDRESS_TYPE := ISR_Start_Addr+12;
  constant INT_VECTOR_6      : ADDRESS_TYPE := ISR_Start_Addr+12;
  constant INT_VECTOR_7      : ADDRESS_TYPE := ISR_Start_Addr+14;
  constant INT_VECTOR_7      : ADDRESS_TYPE := ISR_Start_Addr+14;
 
 
  signal CPU_Next_State      : CPU_STATES := PIPE_FILL_0;
  signal CPU_Next_State      : CPU_STATES := IPF_C0;
  signal CPU_State           : CPU_STATES := PIPE_FILL_0;
  signal CPU_State           : CPU_STATES := IPF_C0;
 
 
 
  signal CPU_Halt_Req        : std_logic;
 
 
  signal Cache_Ctrl          : CACHE_MODES := CACHE_IDLE;
  signal Cache_Ctrl          : CACHE_MODES := CACHE_IDLE;
 
 
  signal Opcode              : OPCODE_TYPE := (others => '0');
  signal Opcode              : OPCODE_TYPE := (others => '0');
  signal SubOp, SubOp_p1     : SUBOP_TYPE  := (others => '0');
  signal SubOp, SubOp_p1     : SUBOP_TYPE  := (others => '0');
Line 307... Line 317...
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
-- Combinatorial portion of CPU finite state machine
-- Combinatorial portion of CPU finite state machine
-- State Logic / Instruction Decoding & Execution
-- State Logic / Instruction Decoding & Execution
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
 
 
  State_Logic: process(CPU_State, Flags, Int_Mask, Opcode,
  State_Logic: process(CPU_State, Flags, Int_Mask, CPU_Halt_Req, Opcode,
                       SubOp , SubOp_p1, Operand1, Operand2, Int_Req )
                       SubOp , SubOp_p1, Operand1, Operand2, Int_Req )
    variable Reg             : integer range 0 to 7 := 0;
    variable Reg             : integer range 0 to 7 := 0;
  begin
  begin
    CPU_Next_State           <= CPU_State;
    CPU_Next_State           <= CPU_State;
    Cache_Ctrl               <= CACHE_IDLE;
    Cache_Ctrl               <= CACHE_IDLE;
Line 336... Line 346...
 
 
    case CPU_State is
    case CPU_State is
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
-- Initial Instruction fetch & decode
-- Initial Instruction fetch & decode
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
      when PIPE_FILL_0 =>
      when IPF_C0 =>
        CPU_Next_State       <= PIPE_FILL_1;
        CPU_Next_State       <= IPF_C1;
        PC_Ctrl.Offset       <= PC_NEXT;
        PC_Ctrl.Offset       <= PC_NEXT;
 
 
      when PIPE_FILL_1 =>
      when IPF_C1 =>
        CPU_Next_State       <= PIPE_FILL_2;
        CPU_Next_State       <= IPF_C2;
        PC_Ctrl.Offset       <= PC_NEXT;
        PC_Ctrl.Offset       <= PC_NEXT;
 
 
      when PIPE_FILL_2 =>
      when IPF_C2 =>
        CPU_Next_State       <= INSTR_DECODE;
        CPU_Next_State       <= IDC_C0;
        Cache_Ctrl           <= CACHE_INSTR;
        Cache_Ctrl           <= CACHE_INSTR;
        PC_Ctrl.Offset       <= PC_NEXT;
        PC_Ctrl.Offset       <= PC_NEXT;
 
 
      when INSTR_DECODE =>
      when IDC_C0 =>
        CPU_Next_State       <= INSTR_DECODE;
        CPU_Next_State       <= IDC_C0;
        Cache_Ctrl           <= CACHE_INSTR;
        Cache_Ctrl           <= CACHE_INSTR;
 
 
        case Opcode is
        case Opcode is
          when OP_PSH =>
          when OP_PSH =>
            CPU_Next_State   <= PSH_C1;
            CPU_Next_State   <= PSH_C1;
Line 382... Line 392...
            ALU_Ctrl.Oper    <= ALU_DEC;
            ALU_Ctrl.Oper    <= ALU_DEC;
            ALU_Ctrl.Reg     <= SubOp;
            ALU_Ctrl.Reg     <= SubOp;
 
 
          when OP_INT =>
          when OP_INT =>
            PC_Ctrl.Offset   <= PC_NEXT;
            PC_Ctrl.Offset   <= PC_NEXT;
            -- Make sure the requested interrupt is actually enabled first
            -- Make sure the requested interrupt is actually enabled first.
 
            --  Also, unlike CPU_Halt, the INT instruction is actually being
 
            --  executed, so go ahead and increment the program counter before
 
            --  pausing so the CPU restarts on the next instruction.
            if( Int_Mask(Reg) = '1' )then
            if( Int_Mask(Reg) = '1' )then
              CPU_Next_State <= WAIT_FOR_INT;
              CPU_Next_State <= WAI_Cx;
              INT_Ctrl.Soft_Ints(Reg) <= '1';
              INT_Ctrl.Soft_Ints(Reg) <= '1';
            end if;
            end if;
 
 
          when OP_STK =>
          when OP_STK =>
            case SubOp is
            case SubOp is
              when SOP_RSP  =>
              when SOP_RSP  =>
                PC_Ctrl.Offset <= PC_NEXT;
                PC_Ctrl.Offset <= PC_NEXT;
                if( not Allow_Stack_Address_Move )then
                if( not Allow_Stack_Address_Move )then
 
                  -- The default behavior for this instruction is to simply
 
                  --  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 Flags(Stack_Xfer_Flag) = '1' )then
                if( Allow_Stack_Address_Move and
 
                    Flags(Stack_Xfer_Flag) = '1' )then
 
                  -- If RSP is set to allow SP moves, and the specified flag
 
                  --  is true, then signal the stack pointer logic to load
 
                  --  from R1:R0
                  SP_Ctrl.Oper    <= SP_SET;
                  SP_Ctrl.Oper    <= SP_SET;
                end if;
                end if;
                if( Allow_Stack_Address_Move and Flags(Stack_Xfer_Flag) = '0')then
                if( Allow_Stack_Address_Move and
 
                    Flags(Stack_Xfer_Flag) = '0')then
 
                  -- If RSP is set to allow SP moves, and the specified flag
 
                  --  is false, then signal the ALU to copy the stack pointer
 
                  --  to R1:R0
                  ALU_Ctrl.Oper   <= ALU_RSP;
                  ALU_Ctrl.Oper   <= ALU_RSP;
                end if;
                end if;
 
 
              when SOP_RTS | SOP_RTI =>
              when SOP_RTS | SOP_RTI =>
                CPU_Next_State    <= RTS_C1;
                CPU_Next_State    <= RTS_C1;
                SP_Ctrl.Oper      <= SP_POP;
                SP_Ctrl.Oper      <= SP_POP;
 
 
              when SOP_BRK  =>
              when SOP_BRK  =>
                CPU_Next_State    <= BRK_C1;
 
                PC_Ctrl.Offset    <= PC_REV2;
 
                -- If Break implements Wait for Interrupt, replace the normal
 
                --  flow with a modified version of the INT instruction
 
                if( BRK_Implements_WAI )then
                if( BRK_Implements_WAI )then
                  CPU_Next_State  <= WAIT_FOR_INT;
                  -- If BRK_Implements_WAI, then jump to the WAI_Cx and
 
                  --  increment the PC similar to an ISR flow.
 
                  CPU_Next_State  <= WAI_Cx;
                  PC_Ctrl.Offset  <= PC_NEXT;
                  PC_Ctrl.Offset  <= PC_NEXT;
 
                else
 
                -- If Break is implemented normally, back the PC up by
 
                --  2 and return through IPF_C0 in order to execute a 5
 
                --  clock cycle delay
 
                  CPU_Next_State  <= BRK_C1;
 
                  PC_Ctrl.Offset  <= PC_REV2;
                end if;
                end if;
 
 
              when SOP_JMP  =>
              when SOP_JMP  =>
                CPU_Next_State    <= JMP_C1;
                CPU_Next_State    <= JMP_C1;
                Cache_Ctrl        <= CACHE_OPER1;
                Cache_Ctrl        <= CACHE_OPER1;
Line 468... Line 495...
          when OP_LDI =>
          when OP_LDI =>
            CPU_Next_State   <= LDI_C1;
            CPU_Next_State   <= LDI_C1;
            Cache_Ctrl       <= CACHE_OPER1;
            Cache_Ctrl       <= CACHE_OPER1;
            PC_Ctrl.Offset   <= PC_NEXT;
            PC_Ctrl.Offset   <= PC_NEXT;
 
 
 
 
          when OP_LDO =>
          when OP_LDO =>
            CPU_Next_State   <= LDO_C1;
            CPU_Next_State   <= LDO_C1;
            Cache_Ctrl       <= CACHE_OPER1;
            Cache_Ctrl       <= CACHE_OPER1;
            PC_Ctrl.Offset   <= PC_REV2;
            PC_Ctrl.Offset   <= PC_REV2;
 
 
Line 506... Line 532...
 
 
        end case;
        end case;
 
 
        if( Int_Req = '1' )then
        if( Int_Req = '1' )then
          CPU_Next_State     <= ISR_C1;
          CPU_Next_State     <= ISR_C1;
 
        end if;
 
 
 
        if( CPU_Halt_Req = '1' )then
 
          CPU_Next_State     <= WAH_Cx;
 
        end if;
 
 
 
        -- If either of these override conditions are true, the decoder needs
 
        --  to undo everything it just setup, since even "single-cycle"
 
        --  instructions will be executed again upon return.
 
        if( Int_Req = '1' or CPU_Halt_Req = '1' )then
 
          -- In either case, we want to skip loading the cache, as the cache
 
          --  will be invalid by the time we get back.
          Cache_Ctrl         <= CACHE_IDLE;
          Cache_Ctrl         <= CACHE_IDLE;
          -- Rewind the PC by 3 to compensate for the pipeline registers
          -- Rewind the PC by 3 to put the PC back to the current instruction,
 
          -- compensating for the pipeline registers.
          PC_Ctrl.Offset     <= PC_REV3;
          PC_Ctrl.Offset     <= PC_REV3;
          -- Reset all of the sub-block controls to IDLE, to avoid unintended
          -- Reset all of the sub-block controls to IDLE, to avoid unintended
          --  operation due to the current instruction
          --  operation due to the current instruction.
          ALU_Ctrl.Oper      <= ALU_IDLE;
          ALU_Ctrl.Oper      <= ALU_IDLE;
          SP_Ctrl.Oper       <= SP_IDLE;
          SP_Ctrl.Oper       <= SP_IDLE;
 
          -- Interrupt logic outside of the state machine needs this to be set
 
          --  to DATA_RD_MEM, while CPU_Halt considers this a "don't care".
          DP_Ctrl.Src        <= DATA_RD_MEM;
          DP_Ctrl.Src        <= DATA_RD_MEM;
          INT_Ctrl.Soft_Ints <= (others => '0');
          -- If an INT/SMSK instruction was going to be executed, it will get
 
          --  executed again when normal processing resumes, so axe their
 
          --  requests for now.
 
          INT_Ctrl.Mask_Set       <= '0';
 
          INT_Ctrl.Soft_Ints(Reg) <= '0';
        end if;
        end if;
 
 
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
-- Program Control (BR0_C1, BR1_C1, DBNZ_C1, JMP )
-- Program Control (BR0_C1, BR1_C1, DBNZ_C1, JMP )
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
 
 
      when BRN_C1 =>
      when BRN_C1 =>
        CPU_Next_State       <= INSTR_DECODE;
        CPU_Next_State       <= IDC_C0;
        Cache_Ctrl           <= CACHE_INSTR;
        Cache_Ctrl           <= CACHE_INSTR;
        PC_Ctrl.Offset       <= PC_NEXT;
        PC_Ctrl.Offset       <= PC_NEXT;
        if( Flags(Reg) = Opcode(0) )then
        if( Flags(Reg) = Opcode(0) )then
          CPU_Next_State     <= PIPE_FILL_0;
          CPU_Next_State     <= IPF_C0;
          Cache_Ctrl         <= CACHE_IDLE;
          Cache_Ctrl         <= CACHE_IDLE;
          PC_Ctrl.Offset     <= Operand1;
          PC_Ctrl.Offset     <= Operand1;
        end if;
        end if;
 
 
      when DBNZ_C1 =>
      when DBNZ_C1 =>
        CPU_Next_State       <= INSTR_DECODE;
        CPU_Next_State       <= IDC_C0;
        Cache_Ctrl           <= CACHE_INSTR;
        Cache_Ctrl           <= CACHE_INSTR;
        PC_Ctrl.Offset       <= PC_NEXT;
        PC_Ctrl.Offset       <= PC_NEXT;
        if( Flags(PSR_Z) = '0' )then
        if( Flags(PSR_Z) = '0' )then
          CPU_Next_State     <= PIPE_FILL_0;
          CPU_Next_State     <= IPF_C0;
          Cache_Ctrl         <= CACHE_IDLE;
          Cache_Ctrl         <= CACHE_IDLE;
          PC_Ctrl.Offset     <= Operand1;
          PC_Ctrl.Offset     <= Operand1;
        end if;
        end if;
 
 
      when JMP_C1 =>
      when JMP_C1 =>
        CPU_Next_State       <= JMP_C2;
        CPU_Next_State       <= JMP_C2;
        Cache_Ctrl           <= CACHE_OPER2;
        Cache_Ctrl           <= CACHE_OPER2;
 
 
      when JMP_C2 =>
      when JMP_C2 =>
        CPU_Next_State       <= PIPE_FILL_0;
        CPU_Next_State       <= IPF_C0;
        PC_Ctrl.Oper         <= PC_LOAD;
        PC_Ctrl.Oper         <= PC_LOAD;
 
 
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
-- Data Storage - Load from memory (LDA, LDI, LDO, LDX)
-- Data Storage - Load from memory (LDA, LDI, LDO, LDX)
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
Line 570... Line 615...
        CPU_Next_State       <= LDI_C1;
        CPU_Next_State       <= LDI_C1;
        Cache_Ctrl           <= CACHE_OPER1;
        Cache_Ctrl           <= CACHE_OPER1;
        PC_Ctrl.Offset       <= PC_NEXT;
        PC_Ctrl.Offset       <= PC_NEXT;
 
 
      when LDI_C1 =>
      when LDI_C1 =>
        CPU_Next_State       <= INSTR_DECODE;
        CPU_Next_State       <= IDC_C0;
        Cache_Ctrl           <= CACHE_INSTR;
        Cache_Ctrl           <= CACHE_INSTR;
        PC_Ctrl.Offset       <= PC_NEXT;
        PC_Ctrl.Offset       <= PC_NEXT;
        ALU_Ctrl.Oper        <= ALU_LDI;
        ALU_Ctrl.Oper        <= ALU_LDI;
        ALU_Ctrl.Reg         <= SubOp;
        ALU_Ctrl.Reg         <= SubOp;
 
 
Line 601... Line 646...
        CPU_Next_State       <= LDX_C4;
        CPU_Next_State       <= LDX_C4;
        Cache_Ctrl           <= CACHE_OPER1;
        Cache_Ctrl           <= CACHE_OPER1;
        PC_Ctrl.Offset       <= PC_NEXT;
        PC_Ctrl.Offset       <= PC_NEXT;
 
 
      when LDX_C4 =>
      when LDX_C4 =>
        CPU_Next_State       <= INSTR_DECODE;
        CPU_Next_State       <= IDC_C0;
        Cache_Ctrl           <= CACHE_INSTR;
        Cache_Ctrl           <= CACHE_INSTR;
        PC_Ctrl.Offset       <= PC_NEXT;
        PC_Ctrl.Offset       <= PC_NEXT;
        ALU_Ctrl.Oper        <= ALU_LDI;
        ALU_Ctrl.Oper        <= ALU_LDI;
        ALU_Ctrl.Reg         <= ACCUM;
        ALU_Ctrl.Reg         <= ACCUM;
 
 
Line 621... Line 666...
      when STA_C2 =>
      when STA_C2 =>
        CPU_Next_State       <= STA_C3;
        CPU_Next_State       <= STA_C3;
        PC_Ctrl.Offset       <= PC_NEXT;
        PC_Ctrl.Offset       <= PC_NEXT;
 
 
      when STA_C3 =>
      when STA_C3 =>
        CPU_Next_State       <= PIPE_FILL_2;
        CPU_Next_State       <= IPF_C2;
        Cache_Ctrl           <= CACHE_PREFETCH;
        Cache_Ctrl           <= CACHE_PREFETCH;
        PC_Ctrl.Offset       <= PC_NEXT;
        PC_Ctrl.Offset       <= PC_NEXT;
 
 
      when STO_C1 =>
      when STO_C1 =>
        CPU_Next_State       <= PIPE_FILL_0;
        CPU_Next_State       <= IPF_C0;
        Cache_Ctrl           <= CACHE_PREFETCH;
        Cache_Ctrl           <= CACHE_PREFETCH;
        PC_Ctrl.Offset       <= PC_NEXT;
        PC_Ctrl.Offset       <= PC_NEXT;
        if( Enable_Auto_Increment and SubOp(0) = '1' )then
        if( Enable_Auto_Increment and SubOp(0) = '1' )then
          CPU_Next_State     <= STO_C2;
          CPU_Next_State     <= STO_C2;
          ALU_Ctrl.Oper      <= ALU_UPP;
          ALU_Ctrl.Oper      <= ALU_UPP;
          ALU_Ctrl.Reg       <= SubOp(2 downto 1) & '0';
          ALU_Ctrl.Reg       <= SubOp(2 downto 1) & '0';
        end if;
        end if;
 
 
      when STO_C2 =>
      when STO_C2 =>
        CPU_Next_State       <= PIPE_FILL_1;
        CPU_Next_State       <= IPF_C1;
        PC_Ctrl.Offset       <= PC_NEXT;
        PC_Ctrl.Offset       <= PC_NEXT;
        ALU_Ctrl.Oper        <= ALU_UPP2;
        ALU_Ctrl.Oper        <= ALU_UPP2;
        ALU_Ctrl.Reg         <= SubOp(2 downto 1) & '1';
        ALU_Ctrl.Reg         <= SubOp(2 downto 1) & '1';
 
 
      when STX_C1 =>
      when STX_C1 =>
        CPU_Next_State       <= PIPE_FILL_1;
        CPU_Next_State       <= IPF_C1;
        PC_Ctrl.Offset       <= PC_NEXT;
        PC_Ctrl.Offset       <= PC_NEXT;
        if( Enable_Auto_Increment and SubOp(0) = '1' )then
        if( Enable_Auto_Increment and SubOp(0) = '1' )then
          CPU_Next_State     <= STX_C2;
          CPU_Next_State     <= STX_C2;
          ALU_Ctrl.Oper      <= ALU_UPP;
          ALU_Ctrl.Oper      <= ALU_UPP;
          ALU_Ctrl.Reg       <= SubOp(2 downto 1) & '0';
          ALU_Ctrl.Reg       <= SubOp(2 downto 1) & '0';
        end if;
        end if;
 
 
      when STX_C2 =>
      when STX_C2 =>
        CPU_Next_State       <= PIPE_FILL_2;
        CPU_Next_State       <= IPF_C2;
        PC_Ctrl.Offset       <= PC_NEXT;
        PC_Ctrl.Offset       <= PC_NEXT;
        ALU_Ctrl.Oper        <= ALU_UPP2;
        ALU_Ctrl.Oper        <= ALU_UPP2;
        ALU_Ctrl.Reg         <= SubOp(2 downto 1) & '1';
        ALU_Ctrl.Reg         <= SubOp(2 downto 1) & '1';
 
 
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
Line 665... Line 710...
      -- Because we have to backup the pipeline by 1 to refetch the 2nd
      -- Because we have to backup the pipeline by 1 to refetch the 2nd
      --  instruction/first operand, we have to return through PF2. Also, we
      --  instruction/first operand, we have to return through PF2. Also, we
      --  need to tell the ALU to store the results to R1:R0 here. Note that
      --  need to tell the ALU to store the results to R1:R0 here. Note that
      --  there is no ALU_Ctrl.Reg, as this is implied in the ALU instruction
      --  there is no ALU_Ctrl.Reg, as this is implied in the ALU instruction
      when MUL_C1 =>
      when MUL_C1 =>
        CPU_Next_State       <= PIPE_FILL_2;
        CPU_Next_State       <= IPF_C2;
        PC_Ctrl.Offset       <= PC_NEXT;
        PC_Ctrl.Offset       <= PC_NEXT;
        ALU_Ctrl.Oper        <= ALU_MUL;
        ALU_Ctrl.Oper        <= ALU_MUL;
 
 
      when UPP_C1 =>
      when UPP_C1 =>
        CPU_Next_State       <= PIPE_FILL_2;
        CPU_Next_State       <= IPF_C2;
        PC_Ctrl.Offset       <= PC_NEXT;
        PC_Ctrl.Offset       <= PC_NEXT;
        ALU_Ctrl.Oper        <= ALU_UPP2;
        ALU_Ctrl.Oper        <= ALU_UPP2;
        ALU_Ctrl.Reg         <= SubOp_p1;
        ALU_Ctrl.Reg         <= SubOp_p1;
 
 
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
-- Basic Stack Manipulation (PSH, POP, RSP)
-- Basic Stack Manipulation (PSH, POP, RSP)
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
      when PSH_C1 =>
      when PSH_C1 =>
        CPU_Next_State       <= PIPE_FILL_1;
        CPU_Next_State       <= IPF_C1;
        SP_Ctrl.Oper         <= SP_PUSH;
        SP_Ctrl.Oper         <= SP_PUSH;
 
 
      when POP_C1 =>
      when POP_C1 =>
        CPU_Next_State       <= POP_C2;
        CPU_Next_State       <= POP_C2;
 
 
Line 695... Line 740...
        CPU_Next_State       <= POP_C4;
        CPU_Next_State       <= POP_C4;
        Cache_Ctrl           <= CACHE_OPER1;
        Cache_Ctrl           <= CACHE_OPER1;
        PC_Ctrl.Offset       <= PC_NEXT;
        PC_Ctrl.Offset       <= PC_NEXT;
 
 
      when POP_C4 =>
      when POP_C4 =>
        CPU_Next_State       <= INSTR_DECODE;
        CPU_Next_State       <= IDC_C0;
        Cache_Ctrl           <= CACHE_INSTR;
        Cache_Ctrl           <= CACHE_INSTR;
        PC_Ctrl.Offset       <= PC_NEXT;
        PC_Ctrl.Offset       <= PC_NEXT;
        ALU_Ctrl.Oper        <= ALU_POP;
        ALU_Ctrl.Oper        <= ALU_POP;
        ALU_Ctrl.Reg         <= SubOp;
        ALU_Ctrl.Reg         <= SubOp;
 
 
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
-- Subroutines & Interrupts (RTS, JSR)
-- Subroutines & Interrupts (RTS, JSR)
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
      when WAIT_FOR_INT => -- For soft interrupts only, halt the Program_Ctr
      when WAI_Cx => -- For soft interrupts only, halt the Program_Ctr
        DP_Ctrl.Src          <= DATA_BUS_IDLE;
        DP_Ctrl.Src          <= DATA_BUS_IDLE;
        if( Int_Req = '1' )then
        if( Int_Req = '1' )then
          CPU_Next_State     <= ISR_C1;
          CPU_Next_State     <= ISR_C1;
          -- Rewind the PC by 3 to compensate for the pipeline registers
          -- Rewind the PC by 3 to put the PC back to would have been the next
 
          --  instruction, compensating for the pipeline registers.
          PC_Ctrl.Offset     <= PC_REV3;
          PC_Ctrl.Offset     <= PC_REV3;
          -- Reset all of the sub-block controls to IDLE, to avoid unintended
          -- Reset all of the sub-block controls to IDLE, to avoid unintended
          --  operation due to the current instruction
          --  operation due to the current instruction
          DP_Ctrl.Src        <= DATA_RD_MEM;
          DP_Ctrl.Src        <= DATA_RD_MEM;
        end if;
        end if;
 
 
 
      when WAH_Cx => -- Holds until CPU_Halt_Req is deasserted.
 
        DP_Ctrl.Src          <= DATA_BUS_IDLE;
 
        if( CPU_Halt_Req = '0' )then
 
          CPU_Next_State     <= IPF_C0;
 
          DP_Ctrl.Src        <= DATA_RD_MEM;
 
        end if;
 
 
 
      when BRK_C1 => -- Debugging (BRK) Performs a 5-clock NOP.
 
        CPU_Next_State       <= IPF_C0;
 
 
      when ISR_C1 =>
      when ISR_C1 =>
        CPU_Next_State       <= ISR_C2;
        CPU_Next_State       <= ISR_C2;
        INT_Ctrl.Incr_ISR    <= '1';
        INT_Ctrl.Incr_ISR    <= '1';
 
 
      when ISR_C2 =>
      when ISR_C2 =>
Line 741... Line 797...
        SP_Ctrl.Oper         <= SP_PUSH;
        SP_Ctrl.Oper         <= SP_PUSH;
        DP_Ctrl.Src          <= DATA_WR_PC;
        DP_Ctrl.Src          <= DATA_WR_PC;
        DP_Ctrl.Reg          <= PC_LSB;
        DP_Ctrl.Reg          <= PC_LSB;
 
 
      when JSR_C2 =>
      when JSR_C2 =>
        CPU_Next_State       <= PIPE_FILL_0;
        CPU_Next_State       <= IPF_C0;
        PC_Ctrl.Oper         <= PC_LOAD;
        PC_Ctrl.Oper         <= PC_LOAD;
        SP_Ctrl.Oper         <= SP_PUSH;
        SP_Ctrl.Oper         <= SP_PUSH;
 
 
      when RTS_C1 =>
      when RTS_C1 =>
        CPU_Next_State       <= RTS_C2;
        CPU_Next_State       <= RTS_C2;
Line 765... Line 821...
      when RTS_C4 =>
      when RTS_C4 =>
        CPU_Next_State       <= RTS_C5;
        CPU_Next_State       <= RTS_C5;
        Cache_Ctrl           <= CACHE_OPER2;
        Cache_Ctrl           <= CACHE_OPER2;
 
 
      when RTS_C5 =>
      when RTS_C5 =>
        CPU_Next_State       <= PIPE_FILL_0;
        CPU_Next_State       <= IPF_C0;
        PC_Ctrl.Oper         <= PC_LOAD;
        PC_Ctrl.Oper         <= PC_LOAD;
        -- if this is an RTI, then we need to clear the I bit
        -- if this is an RTI, then we need to clear the I bit
        if( SubOp = SOP_RTI )then
        if( SubOp = SOP_RTI )then
          CPU_Next_State     <= RTI_C6;
          CPU_Next_State     <= RTI_C6;
          Cache_Ctrl         <= CACHE_OPER1;
          Cache_Ctrl         <= CACHE_OPER1;
          ALU_Ctrl.Oper      <= ALU_CLP;
          ALU_Ctrl.Oper      <= ALU_CLP;
          ALU_Ctrl.Reg       <= conv_std_logic_vector(PSR_I,3);
          ALU_Ctrl.Reg       <= conv_std_logic_vector(PSR_I,3);
        end if;
        end if;
 
 
      when RTI_C6 =>
      when RTI_C6 =>
        CPU_Next_State       <= PIPE_FILL_1;
        CPU_Next_State       <= IPF_C1;
        PC_Ctrl.Offset       <= PC_NEXT;
        PC_Ctrl.Offset       <= PC_NEXT;
        ALU_Ctrl.Oper        <= ALU_RFLG;
        ALU_Ctrl.Oper        <= ALU_RFLG;
 
 
-------------------------------------------------------------------------------
 
-- Debugging (BRK) Performs a 5-clock NOP
 
-------------------------------------------------------------------------------
 
      when BRK_C1 =>
 
        CPU_Next_State       <= PIPE_FILL_0;
 
 
 
      when others =>
      when others =>
        null;
        null;
    end case;
    end case;
 
 
  end process;
  end process;
Line 804... Line 854...
    variable Index           : integer range 0 to 7         := 0;
    variable Index           : integer range 0 to 7         := 0;
    variable Sum             : std_logic_vector(8 downto 0) := "000000000";
    variable Sum             : std_logic_vector(8 downto 0) := "000000000";
    variable Temp            : std_logic_vector(8 downto 0) := "000000000";
    variable Temp            : std_logic_vector(8 downto 0) := "000000000";
  begin
  begin
    if( Reset = Reset_Level )then
    if( Reset = Reset_Level )then
      CPU_State              <= PIPE_FILL_0;
      CPU_State              <= IPF_C0;
      Opcode                 <= OP_INC;
      Opcode                 <= OP_INC;
      SubOp                  <= ACCUM;
      SubOp                  <= ACCUM;
      SubOp_p1               <= ACCUM;
      SubOp_p1               <= ACCUM;
      Operand1               <= x"00";
      Operand1               <= x"00";
      Operand2               <= x"00";
      Operand2               <= x"00";
      Instr_Prefetch         <= '0';
      Instr_Prefetch         <= '0';
      Prefetch               <= x"00";
      Prefetch               <= x"00";
 
 
 
      CPU_Halt_Req           <= '0';
 
 
      Wr_Data                <= (others => '0');
      Wr_Data                <= (others => '0');
      Wr_Enable              <= '0';
      Wr_Enable              <= '0';
      Rd_Enable              <= '1';
      Rd_Enable              <= '1';
 
 
      Program_Ctr            <= Program_Start_Addr;
      Program_Ctr            <= Program_Start_Addr;
Line 840... Line 892...
        Regfile(i)           <= (others => '0');
        Regfile(i)           <= (others => '0');
      end loop;
      end loop;
      Flags                  <= x"00";
      Flags                  <= x"00";
 
 
    elsif( rising_edge(Clock) )then
    elsif( rising_edge(Clock) )then
 
 
 
      CPU_Halt_Req           <= CPU_Halt;
 
 
      Wr_Enable              <= '0';
      Wr_Enable              <= '0';
      Wr_Data                <= x"00";
      Wr_Data                <= x"00";
      Rd_Enable              <= '0';
      Rd_Enable              <= '0';
 
 
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------

powered by: WebSVN 2.1.0

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