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 162 and 164

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

Rev 162 Rev 164
Line 67... Line 67...
--            :  respectively. DBNZ decrements the specified register, and will
--            :  respectively. DBNZ decrements the specified register, and will
--            :  branch if the result is non-zero (Zero flag is not set). MUL
--            :  branch if the result is non-zero (Zero flag is not set). MUL
--            :  places the result of R0 * Rn into R1:R0, and executes in two
--            :  places the result of R0 * Rn into R1:R0, and executes in two
--            :  cycles. (R1:R0 = R0 * Rn)
--            :  cycles. (R1:R0 = R0 * Rn)
--            :
--            :
 
--            : BRK_Implements_WAI modifies the BRK instruction such that it
 
--            :  triggers the wait for interrupt state, but without triggering
 
--            :  a soft interrupt in lieu of its normal behavior, which is to
 
--            :  insert several dead clock cycles - essentially a long NOP
-- Revision History
-- Revision History
-- Author          Date     Change
-- Author          Date     Change
------------------ -------- ---------------------------------------------------
------------------ -------- ---------------------------------------------------
-- Seth Henry      07/19/06 Design Start
-- Seth Henry      07/19/06 Design Start
-- Seth Henry      01/18/11 Fixed BTT instruction to match V8
-- Seth Henry      01/18/11 Fixed BTT instruction to match V8
Line 81... Line 85...
-- 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
 
--                           the bus entirely (Rd_Enable is low)
 
 
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 201... Line 207...
  type SP_CTRL_TYPE is record
  type SP_CTRL_TYPE is record
    Oper                     : SP_MODES;
    Oper                     : SP_MODES;
    Addr                     : ADDRESS_TYPE;
    Addr                     : ADDRESS_TYPE;
  end record;
  end record;
 
 
  type DP_MODES is ( DATA_IDLE, DATA_REG, DATA_FLAG, DATA_PC );
  type DP_MODES is ( DATA_BUS_IDLE, DATA_RD_MEM,
 
                     DATA_WR_REG, DATA_WR_FLAG, DATA_WR_PC );
 
 
  type DATA_CTRL_TYPE is record
  type DATA_CTRL_TYPE is record
    Src                      : DP_MODES;
    Src                      : DP_MODES;
    Reg                      : SUBOP_TYPE;
    Reg                      : SUBOP_TYPE;
  end record;
  end record;
Line 352... Line 359...
    --
    --
    SP_Ctrl.Oper             <= SP_IDLE;
    SP_Ctrl.Oper             <= SP_IDLE;
    --
    --
    Address                  <= Program_Ctr;
    Address                  <= Program_Ctr;
    --
    --
    DP_Ctrl.Src              <= DATA_IDLE;
    DP_Ctrl.Src              <= DATA_RD_MEM;
    DP_Ctrl.Reg              <= ACCUM;
    DP_Ctrl.Reg              <= ACCUM;
    --
    --
    INT_Ctrl.Mask_Set        <= '0';
    INT_Ctrl.Mask_Set        <= '0';
    INT_Ctrl.Soft_Ints       <= x"00";
    INT_Ctrl.Soft_Ints       <= x"00";
    INT_Ctrl.Incr_ISR        <= '0';
    INT_Ctrl.Incr_ISR        <= '0';
Line 394... Line 401...
        case Opcode is
        case Opcode is
          when OP_PSH =>
          when OP_PSH =>
            CPU_Next_State   <= PSH_C1;
            CPU_Next_State   <= PSH_C1;
            Cache_Ctrl       <= CACHE_PREFETCH;
            Cache_Ctrl       <= CACHE_PREFETCH;
            PC_Ctrl.Oper     <= PC_REV1;
            PC_Ctrl.Oper     <= PC_REV1;
            DP_Ctrl.Src      <= DATA_REG;
            DP_Ctrl.Src      <= DATA_WR_REG;
            DP_Ctrl.Reg      <= SubOp;
            DP_Ctrl.Reg      <= SubOp;
 
 
          when OP_POP =>
          when OP_POP =>
            CPU_Next_State   <= POP_C1;
            CPU_Next_State   <= POP_C1;
            Cache_Ctrl       <= CACHE_PREFETCH;
            Cache_Ctrl       <= CACHE_PREFETCH;
Line 417... Line 424...
            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.Oper     <= PC_INCR;
            PC_Ctrl.Oper     <= PC_INCR;
 
            -- Make sure the requested interrupt is actually enabled first
            if( Int_Mask(Reg) = '1' )then
            if( Int_Mask(Reg) = '1' )then
              CPU_Next_State <= WAIT_FOR_INT;
              CPU_Next_State <= WAIT_FOR_INT;
              INT_Ctrl.Soft_Ints(Reg) <= '1';
              INT_Ctrl.Soft_Ints(Reg) <= '1';
            end if;
            end if;
 
 
Line 461... Line 469...
                ALU_Ctrl.Data<= Int_Mask;
                ALU_Ctrl.Data<= Int_Mask;
 
 
              when SOP_JSR =>
              when SOP_JSR =>
                CPU_Next_State <= JSR_C1;
                CPU_Next_State <= JSR_C1;
                Cache_Ctrl   <= CACHE_OPER1;
                Cache_Ctrl   <= CACHE_OPER1;
                DP_Ctrl.Src  <= DATA_PC;
                DP_Ctrl.Src  <= DATA_WR_PC;
                DP_Ctrl.Reg  <= ACCUM+1;
                DP_Ctrl.Reg  <= ACCUM+1;
 
 
              when others => null;
              when others => null;
            end case;
            end case;
 
 
Line 529... Line 537...
 
 
          when OP_STO =>
          when OP_STO =>
            CPU_Next_State   <= STO_C1;
            CPU_Next_State   <= STO_C1;
            Cache_Ctrl       <= CACHE_OPER1;
            Cache_Ctrl       <= CACHE_OPER1;
            PC_Ctrl.Oper     <= PC_REV2;
            PC_Ctrl.Oper     <= PC_REV2;
            DP_Ctrl.Src      <= DATA_REG;
            DP_Ctrl.Src      <= DATA_WR_REG;
            DP_Ctrl.Reg      <= ACCUM;
            DP_Ctrl.Reg      <= ACCUM;
 
 
          when OP_STX =>
          when OP_STX =>
            CPU_Next_State   <= STX_C1;
            CPU_Next_State   <= STX_C1;
            Cache_Ctrl       <= CACHE_PREFETCH;
            Cache_Ctrl       <= CACHE_PREFETCH;
            PC_Ctrl.Oper     <= PC_REV2;
            PC_Ctrl.Oper     <= PC_REV2;
            DP_Ctrl.Src      <= DATA_REG;
            DP_Ctrl.Src      <= DATA_WR_REG;
            DP_Ctrl.Reg      <= ACCUM;
            DP_Ctrl.Reg      <= ACCUM;
 
 
          when others =>
          when others =>
            PC_Ctrl.Oper     <= PC_INCR;
            PC_Ctrl.Oper     <= PC_INCR;
            ALU_Ctrl.Oper    <= Opcode;
            ALU_Ctrl.Oper    <= Opcode;
Line 646... Line 654...
-- Data Storage - Store to memory (STA, STO, STX)
-- Data Storage - Store to memory (STA, STO, STX)
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
      when STA_C1 =>
      when STA_C1 =>
        CPU_Next_State       <= STA_C2;
        CPU_Next_State       <= STA_C2;
        Cache_Ctrl           <= CACHE_OPER2;
        Cache_Ctrl           <= CACHE_OPER2;
        DP_Ctrl.Src          <= DATA_REG;
        DP_Ctrl.Src          <= DATA_WR_REG;
        DP_Ctrl.Reg          <= SubOp;
        DP_Ctrl.Reg          <= SubOp;
 
 
      when STA_C2 =>
      when STA_C2 =>
        CPU_Next_State       <= STA_C3;
        CPU_Next_State       <= STA_C3;
        Address              <= Operand2 & Operand1;
        Address              <= Operand2 & Operand1;
Line 762... Line 770...
 
 
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
-- Subroutines & Interrupts (RTS, JSR)
-- Subroutines & Interrupts (RTS, JSR)
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
      when WAIT_FOR_INT => -- For soft interrupts only, halt the Program_Ctr
      when WAIT_FOR_INT => -- For soft interrupts only, halt the Program_Ctr
 
        DP_Ctrl.Src          <= DATA_BUS_IDLE;
        CPU_Next_State       <= WAIT_FOR_INT;
        CPU_Next_State       <= WAIT_FOR_INT;
 
 
      when ISR_C1 =>
      when ISR_C1 =>
        CPU_Next_State       <= ISR_C2;
        CPU_Next_State       <= ISR_C2;
        Address              <= ISR_Addr;
        Address              <= ISR_Addr;
        INT_Ctrl.Incr_ISR    <= '1';
        INT_Ctrl.Incr_ISR    <= '1';
 
 
      when ISR_C2 =>
      when ISR_C2 =>
        CPU_Next_State       <= ISR_C3;
        CPU_Next_State       <= ISR_C3;
        Address              <= ISR_Addr;
        Address              <= ISR_Addr;
        DP_Ctrl.Src          <= DATA_FLAG;
        DP_Ctrl.Src          <= DATA_WR_FLAG;
 
 
      when ISR_C3 =>
      when ISR_C3 =>
        CPU_Next_State       <= JSR_C1;
        CPU_Next_State       <= JSR_C1;
        Cache_Ctrl           <= CACHE_OPER1;
        Cache_Ctrl           <= CACHE_OPER1;
        Address              <= Stack_Ptr;
        Address              <= Stack_Ptr;
        SP_Ctrl.Oper         <= SP_PUSH;
        SP_Ctrl.Oper         <= SP_PUSH;
        DP_Ctrl.Src          <= DATA_PC;
        DP_Ctrl.Src          <= DATA_WR_PC;
        DP_Ctrl.Reg          <= ACCUM+1;
        DP_Ctrl.Reg          <= ACCUM+1;
        ALU_Ctrl.Oper        <= ALU_STP;
        ALU_Ctrl.Oper        <= ALU_STP;
        ALU_Ctrl.Reg         <= INT_FLAG;
        ALU_Ctrl.Reg         <= INT_FLAG;
        Ack_D                <= '1';
        Ack_D                <= '1';
 
 
      when JSR_C1 =>
      when JSR_C1 =>
        CPU_Next_State       <= JSR_C2;
        CPU_Next_State       <= JSR_C2;
        Cache_Ctrl           <= CACHE_OPER2;
        Cache_Ctrl           <= CACHE_OPER2;
        Address              <= Stack_Ptr;
        Address              <= Stack_Ptr;
        SP_Ctrl.Oper         <= SP_PUSH;
        SP_Ctrl.Oper         <= SP_PUSH;
        DP_Ctrl.Src          <= DATA_PC;
        DP_Ctrl.Src          <= DATA_WR_PC;
        DP_Ctrl.Reg          <= ACCUM;
        DP_Ctrl.Reg          <= ACCUM;
 
 
      when JSR_C2 =>
      when JSR_C2 =>
        CPU_Next_State       <= PIPE_FILL_0;
        CPU_Next_State       <= PIPE_FILL_0;
        Address              <= Stack_Ptr;
        Address              <= Stack_Ptr;
Line 859... Line 868...
        -- 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;
        Cache_Ctrl           <= CACHE_IDLE;
        Cache_Ctrl           <= CACHE_IDLE;
        SP_Ctrl.Oper         <= SP_IDLE;
        SP_Ctrl.Oper         <= SP_IDLE;
        DP_Ctrl.Src          <= DATA_IDLE; -- JSH 7/20
        DP_Ctrl.Src          <= DATA_RD_MEM; -- JSH 7/20
        INT_Ctrl.Soft_Ints   <= (others => '0'); -- JSH 7/22
        INT_Ctrl.Soft_Ints   <= (others => '0'); -- JSH 7/22
        -- Rewind the PC by 3 to compensate for the pipeline registers
        -- Rewind the PC by 3 to compensate for the pipeline registers
        PC_Ctrl.Oper         <= PC_INCR;
        PC_Ctrl.Oper         <= PC_INCR;
        PC_Ctrl.Offset       <= x"FF";
        PC_Ctrl.Offset       <= x"FF";
        CPU_Next_State       <= ISR_C1;
        CPU_Next_State       <= ISR_C1;
Line 930... Line 939...
      end loop;
      end loop;
      Flags                  <= x"00";
      Flags                  <= x"00";
 
 
    elsif( rising_edge(Clock) )then
    elsif( rising_edge(Clock) )then
      Wr_Enable              <= '0';
      Wr_Enable              <= '0';
 
      Wr_Data                <= x"00";
      Rd_Enable              <= '0';
      Rd_Enable              <= '0';
 
 
      if( Halt = '0' )then
      if( Halt = '0' )then
        Rd_Enable            <= '1';
 
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
-- Instruction/Operand caching for pipelined memory access
-- Instruction/Operand caching for pipelined memory access
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
        CPU_State            <= CPU_Next_State;
        CPU_State            <= CPU_Next_State;
        case Cache_Ctrl is
        case Cache_Ctrl is
Line 994... Line 1003...
 
 
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
-- (Write) Data Path
-- (Write) Data Path
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
        case DP_Ctrl.Src is
        case DP_Ctrl.Src is
          when DATA_IDLE =>
          when DATA_BUS_IDLE =>
            null;
            null;
 
 
          when DATA_REG =>
          when DATA_RD_MEM =>
 
            Rd_Enable        <= '1';
 
 
 
          when DATA_WR_REG =>
            Wr_Enable        <= '1';
            Wr_Enable        <= '1';
            Rd_Enable        <= '0';
 
            Wr_Data          <= Regfile(conv_integer(DP_Ctrl.Reg));
            Wr_Data          <= Regfile(conv_integer(DP_Ctrl.Reg));
 
 
          when DATA_FLAG =>
          when DATA_WR_FLAG =>
            Wr_Enable        <= '1';
            Wr_Enable        <= '1';
            Rd_Enable        <= '0';
 
            Wr_Data          <= Flags;
            Wr_Data          <= Flags;
 
 
          when DATA_PC =>
          when DATA_WR_PC =>
            Wr_Enable        <= '1';
            Wr_Enable        <= '1';
            Rd_Enable        <= '0';
 
            Wr_Data          <= Program_Ctr(15 downto 8);
            Wr_Data          <= Program_Ctr(15 downto 8);
            if( DP_Ctrl.Reg = ACCUM )then
            if( DP_Ctrl.Reg = ACCUM )then
              Wr_Data        <= Program_Ctr(7 downto 0);
              Wr_Data        <= Program_Ctr(7 downto 0);
            end if;
            end if;
 
 

powered by: WebSVN 2.1.0

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