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 253 and 254

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

Rev 253 Rev 254
Line 284... Line 284...
  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;
 
 
  constant INT_VECTOR_0      : ADDRESS_TYPE := ISR_Start_Addr;
 
  constant INT_VECTOR_1      : ADDRESS_TYPE := ISR_Start_Addr+2;
 
  constant INT_VECTOR_2      : ADDRESS_TYPE := ISR_Start_Addr+4;
 
  constant INT_VECTOR_3      : ADDRESS_TYPE := ISR_Start_Addr+6;
 
  constant INT_VECTOR_4      : ADDRESS_TYPE := ISR_Start_Addr+8;
 
  constant INT_VECTOR_5      : ADDRESS_TYPE := ISR_Start_Addr+10;
 
  constant INT_VECTOR_6      : ADDRESS_TYPE := ISR_Start_Addr+12;
 
  constant INT_VECTOR_7      : ADDRESS_TYPE := ISR_Start_Addr+14;
 
 
 
  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 327... Line 318...
  signal INT_Ctrl            : INT_CTRL_TYPE;
  signal INT_Ctrl            : INT_CTRL_TYPE;
  signal Ack_D, Ack_Q, Ack_Q1: std_logic   := '0';
  signal Ack_D, Ack_Q, Ack_Q1: std_logic   := '0';
  signal Int_Req, Int_Ack    : std_logic   := '0';
  signal Int_Req, Int_Ack    : std_logic   := '0';
  signal Set_Mask            : std_logic   := '0';
  signal Set_Mask            : std_logic   := '0';
  signal Int_Mask            : DATA_TYPE   := x"00";
  signal Int_Mask            : DATA_TYPE   := x"00";
  signal ISR_Addr            : ADDRESS_TYPE := x"0000";
 
  signal i_Ints              : INTERRUPT_BUNDLE := x"00";
  signal i_Ints              : INTERRUPT_BUNDLE := x"00";
  signal Pending             : INTERRUPT_BUNDLE := x"00";
  signal Pending             : INTERRUPT_BUNDLE := x"00";
  signal Wait_for_FSM        : std_logic := '0';
  signal Wait_for_FSM        : std_logic := '0';
  signal Wait_for_ISR        : std_logic := '0';
  signal Wait_for_ISR        : std_logic := '0';
 
 
 
  alias  ISR_Addr_Base       is ISR_Start_Addr(15 downto 4);
 
  signal ISR_Addr_Offset     : std_logic_vector(3 downto 0) := x"0";
 
 
 
  constant INT_VECTOR_0      : std_logic_vector(3 downto 0) := x"0";
 
  constant INT_VECTOR_1      : std_logic_vector(3 downto 0) := x"2";
 
  constant INT_VECTOR_2      : std_logic_vector(3 downto 0) := x"4";
 
  constant INT_VECTOR_3      : std_logic_vector(3 downto 0) := x"6";
 
  constant INT_VECTOR_4      : std_logic_vector(3 downto 0) := x"8";
 
  constant INT_VECTOR_5      : std_logic_vector(3 downto 0) := x"A";
 
  constant INT_VECTOR_6      : std_logic_vector(3 downto 0) := x"C";
 
  constant INT_VECTOR_7      : std_logic_vector(3 downto 0) := x"E";
 
 
  signal IDX_Offset          : ADDRESS_TYPE := x"0000";
  signal IDX_Offset          : ADDRESS_TYPE := x"0000";
 
 
  signal IDX_Reg_l           : integer := 0;
  signal IDX_Reg_l           : integer := 0;
  signal IDX_Reg_h           : integer := 0;
  signal IDX_Reg_h           : integer := 0;
 
 
Line 380... Line 382...
 
 
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
-- Address bus selection/generation logic
-- Address bus selection/generation logic
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
 
 
 
  -- Address selection logic based on current CPU state. This is combinatorial,
 
  --  as adding pipeline registration would add a clock cycle to every instr,
 
  --  without really adding the Fmax to compensate.
 
  Address_Logic: process(CPU_State, Operand1, Operand2, IDX_NoOffset_Calc,
 
                         IDX_Offset_Calc, ISR_Addr_Offset, Stack_Ptr, Program_Ctr )
 
  begin
 
    case( CPU_State )is
 
 
 
      when LDA_C2 | STA_C2 =>
 
        Open8_Bus.Address    <= Operand2 & Operand1;
 
 
 
      when LDX_C1 | STX_C1 =>
 
        Open8_Bus.Address    <= IDX_NoOffset_Calc;
 
 
 
      when LDO_C2 | STO_C2 =>
 
        Open8_Bus.Address    <= IDX_Offset_Calc;
 
 
 
      when ISR_C1 | ISR_C2 =>
 
        Open8_Bus.Address    <= ISR_Addr_Base & ISR_Addr_Offset;
 
 
 
      when PSH_C1 | POP_C1 | ISR_C3 | JSR_C1 | JSR_C2 | RTS_C1 | RTS_C2 | RTS_C3 =>
 
        Open8_Bus.Address    <= Stack_Ptr;
 
 
 
      when others =>
 
        Open8_Bus.Address    <= Program_Ctr;
 
 
 
    end case;
 
  end process;
 
 
  -- The original model treated the offset to LDO/STO as a signed value
  -- The original model treated the offset to LDO/STO as a signed value
  --  allowing access to locations -128 to +127 from [Rn+1:Rn]. This isn't
  --  allowing access to locations -128 to +127 from [Rn+1:Rn]. This isn't
  --  always helpful, so the generic allows the CPU to use unsigned math
  --  always helpful, so the generic allows the CPU to use unsigned math
  --  for the offsets. This makes the range 0 to +255 instead.
  --  for the offsets. This makes the range 0 to +255 instead.
 
 
Line 423... Line 454...
      IDX_Offset_Calc        <= (Regfile(IDX_Reg_h) & Regfile(IDX_Reg_l)) +
      IDX_Offset_Calc        <= (Regfile(IDX_Reg_h) & Regfile(IDX_Reg_l)) +
                                IDX_Offset;
                                IDX_Offset;
    end if;
    end if;
  end process;
  end process;
 
 
  -- Address selection logic based on current CPU state. This is combinatorial,
 
  --  as adding pipeline registration would add a clock cycle to every instr,
 
  --  without really adding the Fmax to compensate.
 
  Address_Logic: process(CPU_State, Operand1, Operand2, IDX_NoOffset_Calc,
 
                         IDX_Offset_Calc, ISR_Addr, Stack_Ptr, Program_Ctr )
 
  begin
 
    case( CPU_State )is
 
 
 
      when LDA_C2 | STA_C2 =>
 
        Open8_Bus.Address    <= Operand2 & Operand1;
 
 
 
      when LDX_C1 | STX_C1 =>
 
        Open8_Bus.Address    <= IDX_NoOffset_Calc;
 
 
 
      when LDO_C2 | STO_C2 =>
 
        Open8_Bus.Address    <= IDX_Offset_Calc;
 
 
 
      when ISR_C1 | ISR_C2 =>
 
        Open8_Bus.Address    <= ISR_Addr;
 
 
 
      when PSH_C1 | POP_C1 | ISR_C3 | JSR_C1 | JSR_C2 | RTS_C1 | RTS_C2 | RTS_C3 =>
 
        Open8_Bus.Address    <= Stack_Ptr;
 
 
 
      when others =>
 
        Open8_Bus.Address    <= Program_Ctr;
 
 
 
    end case;
 
  end process;
 
 
 
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
-- Combinatorial portion of CPU finite state machine
-- Combinatorial portion of CPU finite state machine
-- State Logic / Instruction Decoding & Execution
-- State Logic / Instruction Decoding & Execution
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
 
 
Line 1049... Line 1051...
      if( Enable_NMI )then
      if( Enable_NMI )then
        Int_Mask             <= Default_Interrupt_Mask(7 downto 1) & '1';
        Int_Mask             <= Default_Interrupt_Mask(7 downto 1) & '1';
      else
      else
        Int_Mask             <= Default_Interrupt_Mask;
        Int_Mask             <= Default_Interrupt_Mask;
      end if;
      end if;
      ISR_Addr               <= INT_VECTOR_0;
      ISR_Addr_Offset        <= INT_VECTOR_0;
 
 
      for i in 0 to 7 loop
      for i in 0 to 7 loop
        Regfile(i)           <= x"00";
        Regfile(i)           <= x"00";
      end loop;
      end loop;
      Flags                  <= x"00";
      Flags                  <= x"00";
Line 1212... Line 1214...
        Wait_for_ISR         <= '0';
        Wait_for_ISR         <= '0';
      end if;
      end if;
 
 
      if( Wait_for_FSM = '0' and Wait_for_ISR = '0' )then
      if( Wait_for_FSM = '0' and Wait_for_ISR = '0' )then
        if(    Pending(0) = '1' )then
        if(    Pending(0) = '1' )then
          ISR_Addr           <= INT_VECTOR_0;
          ISR_Addr_Offset    <= INT_VECTOR_0;
          Pending(0)         <= '0';
          Pending(0)         <= '0';
        elsif( Pending(1) = '1' )then
        elsif( Pending(1) = '1' )then
          ISR_Addr           <= INT_VECTOR_1;
          ISR_Addr_Offset    <= INT_VECTOR_1;
          Pending(1)         <= '0';
          Pending(1)         <= '0';
        elsif( Pending(2) = '1' )then
        elsif( Pending(2) = '1' )then
          ISR_Addr           <= INT_VECTOR_2;
          ISR_Addr_Offset    <= INT_VECTOR_2;
          Pending(2)         <= '0';
          Pending(2)         <= '0';
        elsif( Pending(3) = '1' )then
        elsif( Pending(3) = '1' )then
          ISR_Addr           <= INT_VECTOR_3;
          ISR_Addr_Offset    <= INT_VECTOR_3;
          Pending(3)         <= '0';
          Pending(3)         <= '0';
        elsif( Pending(4) = '1' )then
        elsif( Pending(4) = '1' )then
          ISR_Addr           <= INT_VECTOR_4;
          ISR_Addr_Offset    <= INT_VECTOR_4;
          Pending(4)         <= '0';
          Pending(4)         <= '0';
        elsif( Pending(5) = '1' )then
        elsif( Pending(5) = '1' )then
          ISR_Addr           <= INT_VECTOR_5;
          ISR_Addr_Offset    <= INT_VECTOR_5;
          Pending(5)         <= '0';
          Pending(5)         <= '0';
        elsif( Pending(6) = '1' )then
        elsif( Pending(6) = '1' )then
          ISR_Addr           <= INT_VECTOR_6;
          ISR_Addr_Offset    <= INT_VECTOR_6;
          Pending(6)         <= '0';
          Pending(6)         <= '0';
        elsif( Pending(7) = '1' )then
        elsif( Pending(7) = '1' )then
          ISR_Addr           <= INT_VECTOR_7;
          ISR_Addr_Offset    <= INT_VECTOR_7;
          Pending(7)         <= '0';
          Pending(7)         <= '0';
        end if;
        end if;
        Wait_for_FSM         <= or_reduce(Pending);
        Wait_for_FSM         <= or_reduce(Pending);
      end if;
      end if;
 
 
Line 1252... Line 1254...
      Int_Req                <= Wait_for_FSM and (not Int_Ack);
      Int_Req                <= Wait_for_FSM and (not Int_Ack);
 
 
      -- Incr_ISR allows the CPU Core to advance the vector address to pop the
      -- Incr_ISR allows the CPU Core to advance the vector address to pop the
      --  lower half of the address.
      --  lower half of the address.
      if( INT_Ctrl.Incr_ISR = '1' )then
      if( INT_Ctrl.Incr_ISR = '1' )then
        ISR_Addr             <= ISR_Addr + 1;
        ISR_Addr_Offset             <= ISR_Addr_Offset + 1;
      end if;
      end if;
 
 
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
-- ALU (Arithmetic / Logic Unit)
-- ALU (Arithmetic / Logic Unit)
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------

powered by: WebSVN 2.1.0

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