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 154 and 155

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

Rev 154 Rev 155
Line 72... Line 72...
-- 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
 
-- Seth Henry      07/22/11 Fixed interrupt transition logic to avoid data
 
--                           corruption issues.
 
-- Seth Henry      07/26/11 Optimized logic in ALU, stack pointer, and data path
 
--                           sections.
 
 
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 222... Line 226...
Halt_Enabled_fn: if( Enable_CPU_Halt )generate
Halt_Enabled_fn: if( Enable_CPU_Halt )generate
  Halt                       <= CPU_Halt;
  Halt                       <= CPU_Halt;
end generate;
end generate;
 
 
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
-- ALU (Arithmetic / Logic Unit
-- ALU (Arithmetic / Logic Unit)
-- Notes:
-- Notes:
-- 1) Infers a multiplier in Xilinx/Altera parts - should be checked in others
-- 1) Infers a multiplier in Xilinx/Altera parts - should be checked in others
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
 
 
Open8_ALU : block is
Open8_ALU : block is
 
 
  -- Preinitialization is for simulation only - check actual reset conditions
  -- Preinitialization is for simulation only - check actual reset conditions
  signal Regfile_D, Regfile  : REGFILE_TYPE := (others => (others => '0') );
  signal Regfile             : REGFILE_TYPE := (others => (others => '0') );
  signal Flags_D, Flags      : FLAG_TYPE    := (others => '0');
  signal Flags               : FLAG_TYPE    := (others => '0');
  signal Mult                : ADDRESS_TYPE := (others => '0');
  signal Mult                : ADDRESS_TYPE := (others => '0');
 
 
  signal Sum                 : std_logic_vector(8 downto 0) := (others => '0');
 
  signal Addend_A, Addend_B  : DATA_TYPE    := (others => '0');
 
  signal Carry               : std_logic    := '0';
 
 
 
begin
begin
 
 
  ALU_Regs                   <= Regfile;
  ALU_Regs                   <= Regfile;
  ALU_Flags                  <= Flags;
  ALU_Flags                  <= Flags;
 
 
  ALU_proc: process( ALU_Ctrl, Regfile, Flags, Mult, Sum )
  -- We need to infer a hardware multipler, so we create a special clocked
 
  --  process with no reset or clock enable
 
  Multiplier: process( Clock )
 
  begin
 
    if( rising_edge(Clock) )then
 
      Mult                   <= Regfile(0) *
 
                                Regfile(conv_integer(ALU_Ctrl.Reg));
 
    end if;
 
  end process;
 
 
 
  ALU: process( Reset, Clock )
 
    variable Sum               : std_logic_vector(8 downto 0) := "000000000";
    variable Index             : integer range 0 to 7 := 0;
    variable Index             : integer range 0 to 7 := 0;
    variable Temp              : std_logic_vector(8 downto 0);
    variable Temp              : std_logic_vector(8 downto 0);
  begin
  begin
    Regfile_D                <= Regfile;
    if( Reset = Reset_Level )then
    Flags_D                  <= Flags;
      for i in 0 to 7 loop
    Addend_A                 <= x"00";
        Regfile(i)           <= (others => '0');
    Addend_B                 <= x"00";
      end loop;
    Carry                    <= '0';
      Flags                  <= x"00";
 
    elsif( rising_edge(Clock) )then
    Temp                     := (others => '0');
    Temp                     := (others => '0');
    Index                    := conv_integer(ALU_Ctrl.Reg);
    Index                    := conv_integer(ALU_Ctrl.Reg);
 
      if( Halt = '0' )then
    case ALU_Ctrl.Oper is
    case ALU_Ctrl.Oper is
      when ALU_INC | ALU_UPP => -- Rn = Rn + 1 : Flags N,C,Z
      when ALU_INC | ALU_UPP => -- Rn = Rn + 1 : Flags N,C,Z
        Addend_A             <= x"01";
            Sum              := ("0" & x"01") +
        Addend_B             <= Regfile(Index);
                                ("0" & Regfile(Index));
        Flags_D(FL_CARRY)    <= Sum(8);
            Flags(FL_CARRY)  <= Sum(8);
        Regfile_D(Index)     <= Sum(7 downto 0);
            Regfile(Index)   <= Sum(7 downto 0);
        -- ALU_INC and ALU_UPP are essentially the same, except that ALU_UPP
        -- ALU_INC and ALU_UPP are essentially the same, except that ALU_UPP
        --  doesn't set the N or Z flags. Note that the MSB can be used to
        --  doesn't set the N or Z flags. Note that the MSB can be used to
        --  distinguish between the two ALU modes.
        --  distinguish between the two ALU modes.
        if( ALU_Ctrl.Oper(4) = '0' )then
        if( ALU_Ctrl.Oper(4) = '0' )then
          Flags_D(FL_ZERO)   <= '0';
             Flags(FL_ZERO)  <= '0';
          if( Sum(7 downto 0) = 0 )then
          if( Sum(7 downto 0) = 0 )then
            Flags_D(FL_ZERO) <= '1';
               Flags(FL_ZERO)<= '1';
          end if;
          end if;
          Flags_D(FL_NEG)    <= Sum(7);
             Flags(FL_NEG)   <= Sum(7);
        end if;
        end if;
 
 
      when ALU_UPP2 => -- Rn = Rn + C
      when ALU_UPP2 => -- Rn = Rn + C
        Addend_A             <= x"00";
            Sum              := ("0" & x"00") +
        Addend_B             <= Regfile(Index);
                                ("0" & Regfile(Index)) +
        Carry                <= Flags(FL_CARRY);
                                Flags(FL_CARRY);
        Flags_D(FL_CARRY)    <= Sum(8);
            Flags(FL_CARRY)  <= Sum(8);
        Regfile_D(Index)     <= Sum(7 downto 0);
            Regfile(Index)   <= Sum(7 downto 0);
 
 
      when ALU_ADC => -- R0 = R0 + Rn + C : Flags N,C,Z
      when ALU_ADC => -- R0 = R0 + Rn + C : Flags N,C,Z
        Addend_A             <= Regfile(0);
            Sum              := ("0" & Regfile(0)) +
        Addend_B             <= Regfile(Index);
                                ("0" & Regfile(Index)) +
        Carry                <= Flags(FL_CARRY);
                                Flags(FL_CARRY);
        Flags_D(FL_ZERO)     <= '0';
            Flags(FL_ZERO)   <= '0';
        if( Sum(7 downto 0) = 0 )then
        if( Sum(7 downto 0) = 0 )then
          Flags_D(FL_ZERO)   <= '1';
              Flags(FL_ZERO) <= '1';
        end if;
        end if;
        Flags_D(FL_CARRY)    <= Sum(8);
            Flags(FL_CARRY)  <= Sum(8);
        Flags_D(FL_NEG)      <= Sum(7);
            Flags(FL_NEG)    <= Sum(7);
        Regfile_D(0)         <= Sum(7 downto 0);
            Regfile(0)       <= Sum(7 downto 0);
 
 
      when ALU_TX0 => -- R0 = Rn : Flags N,Z
      when ALU_TX0 => -- R0 = Rn : Flags N,Z
        Temp                 := "0" & Regfile(Index);
        Temp                 := "0" & Regfile(Index);
        Flags_D(FL_ZERO)     <= '0';
            Flags(FL_ZERO)   <= '0';
        if( Temp(7 downto 0) = 0 )then
        if( Temp(7 downto 0) = 0 )then
          Flags_D(FL_ZERO)   <= '1';
              Flags(FL_ZERO) <= '1';
        end if;
        end if;
        Flags_D(FL_NEG)      <= Temp(7);
            Flags(FL_NEG)    <= Temp(7);
        Regfile_D(0)         <= Temp(7 downto 0);
            Regfile(0)       <= Temp(7 downto 0);
 
 
      when ALU_OR  => -- R0 = R0 | Rn : Flags N,Z
      when ALU_OR  => -- R0 = R0 | Rn : Flags N,Z
        Temp(7 downto 0)     := Regfile(0) or Regfile(Index);
        Temp(7 downto 0)     := Regfile(0) or Regfile(Index);
        Flags_D(FL_ZERO)     <= '0';
            Flags(FL_ZERO)   <= '0';
        if( Temp(7 downto 0) = 0 )then
        if( Temp(7 downto 0) = 0 )then
          Flags_D(FL_ZERO)   <= '1';
              Flags(FL_ZERO) <= '1';
        end if;
        end if;
        Flags_D(FL_NEG)      <= Temp(7);
            Flags(FL_NEG)    <= Temp(7);
        Regfile_D(0)         <= Temp(7 downto 0);
            Regfile(0)       <= Temp(7 downto 0);
 
 
      when ALU_AND => -- R0 = R0 & Rn : Flags N,Z
      when ALU_AND => -- R0 = R0 & Rn : Flags N,Z
        Temp(7 downto 0)     := Regfile(0) and Regfile(Index);
        Temp(7 downto 0)     := Regfile(0) and Regfile(Index);
        Flags_D(FL_ZERO)     <= '0';
            Flags(FL_ZERO)   <= '0';
        if( Temp(7 downto 0) = 0 )then
        if( Temp(7 downto 0) = 0 )then
          Flags_D(FL_ZERO)   <= '1';
              Flags(FL_ZERO) <= '1';
        end if;
        end if;
        Flags_D(FL_NEG)      <= Temp(7);
            Flags(FL_NEG)    <= Temp(7);
        Regfile_D(0)         <= Temp(7 downto 0);
            Regfile(0)       <= Temp(7 downto 0);
 
 
      when ALU_XOR => -- R0 = R0 ^ Rn : Flags N,Z
      when ALU_XOR => -- R0 = R0 ^ Rn : Flags N,Z
        Temp(7 downto 0)     := Regfile(0) xor Regfile(Index);
        Temp(7 downto 0)     := Regfile(0) xor Regfile(Index);
        Flags_D(FL_ZERO)     <= '0';
            Flags(FL_ZERO)   <= '0';
        if( Temp(7 downto 0) = 0 )then
        if( Temp(7 downto 0) = 0 )then
          Flags_D(FL_ZERO)   <= '1';
              Flags(FL_ZERO) <= '1';
        end if;
        end if;
        Flags_D(FL_NEG)      <= Temp(7);
            Flags(FL_NEG)    <= Temp(7);
        Regfile_D(0)         <= Temp(7 downto 0);
            Regfile(0)       <= Temp(7 downto 0);
 
 
      when ALU_ROL => -- Rn = Rn<<1,C : Flags N,C,Z
      when ALU_ROL => -- Rn = Rn<<1,C : Flags N,C,Z
        Temp                 := Regfile(Index) & Flags(FL_CARRY);
        Temp                 := Regfile(Index) & Flags(FL_CARRY);
        Flags_D(FL_ZERO)     <= '0';
            Flags(FL_ZERO)   <= '0';
        if( Temp(7 downto 0) = 0 )then
        if( Temp(7 downto 0) = 0 )then
          Flags_D(FL_ZERO)   <= '1';
              Flags(FL_ZERO) <= '1';
        end if;
        end if;
        Flags_D(FL_CARRY)    <= Temp(8);
            Flags(FL_CARRY)  <= Temp(8);
        Flags_D(FL_NEG)      <= Temp(7);
            Flags(FL_NEG)    <= Temp(7);
        Regfile_D(Index)     <= Temp(7 downto 0);
            Regfile(Index)   <= Temp(7 downto 0);
 
 
      when ALU_ROR => -- Rn = C,Rn>>1 : Flags N,C,Z
      when ALU_ROR => -- Rn = C,Rn>>1 : Flags N,C,Z
        Temp                 := Regfile(Index)(0) & Flags(FL_CARRY) &
        Temp                 := Regfile(Index)(0) & Flags(FL_CARRY) &
                                Regfile(Index)(7 downto 1);
                                Regfile(Index)(7 downto 1);
        Flags_D(FL_ZERO)     <= '0';
            Flags(FL_ZERO)   <= '0';
        if( Temp(7 downto 0) = 0 )then
        if( Temp(7 downto 0) = 0 )then
          Flags_D(FL_ZERO)   <= '1';
              Flags(FL_ZERO) <= '1';
        end if;
        end if;
        Flags_D(FL_CARRY)    <= Temp(8);
            Flags(FL_CARRY)  <= Temp(8);
        Flags_D(FL_NEG)      <= Temp(7);
            Flags(FL_NEG)    <= Temp(7);
        Regfile_D(Index)     <= Temp(7 downto 0);
            Regfile(Index)   <= Temp(7 downto 0);
 
 
      when ALU_DEC => -- Rn = Rn - 1 : Flags N,C,Z
      when ALU_DEC => -- Rn = Rn - 1 : Flags N,C,Z
        Addend_A             <= Regfile(Index);
            Sum              := ("0" & Regfile(Index)) +
        Addend_B             <= x"FF";
                                ("0" & x"FF");
        Flags_D(FL_ZERO)     <= '0';
            Flags(FL_ZERO)   <= '0';
        if( Sum(7 downto 0) = 0 )then
        if( Sum(7 downto 0) = 0 )then
          Flags_D(FL_ZERO)   <= '1';
              Flags(FL_ZERO) <= '1';
        end if;
        end if;
        Flags_D(FL_CARRY)    <= Sum(8);
            Flags(FL_CARRY)  <= Sum(8);
        Flags_D(FL_NEG)      <= Sum(7);
            Flags(FL_NEG)    <= Sum(7);
        Regfile_D(Index)     <= Sum(7 downto 0);
            Regfile(Index)   <= Sum(7 downto 0);
 
 
      when ALU_SBC => -- Rn = R0 - Rn - C : Flags N,C,Z
      when ALU_SBC => -- Rn = R0 - Rn - C : Flags N,C,Z
        Addend_A             <= Regfile(0);
            Sum              := ("0" & Regfile(0)) +
        Addend_B             <= not Regfile(Index);
                                ("0" & (not Regfile(Index))) +
        Carry                <= Flags(FL_CARRY);
                                Flags(FL_CARRY);
        Flags_D(FL_ZERO)     <= '0';
            Flags(FL_ZERO)   <= '0';
        if( Sum(7 downto 0) = 0 )then
        if( Sum(7 downto 0) = 0 )then
          Flags_D(FL_ZERO)   <= '1';
              Flags(FL_ZERO) <= '1';
        end if;
        end if;
        Flags_D(FL_CARRY)    <= Sum(8);
            Flags(FL_CARRY)  <= Sum(8);
        Flags_D(FL_NEG)      <= Sum(7);
            Flags(FL_NEG)    <= Sum(7);
        Regfile_D(0)         <= Sum(7 downto 0);
            Regfile(0)       <= Sum(7 downto 0);
 
 
      when ALU_ADD => -- R0 = R0 + Rn : Flags N,C,Z
      when ALU_ADD => -- R0 = R0 + Rn : Flags N,C,Z
        Addend_A             <= Regfile(0);
            Sum              := ("0" & Regfile(0)) +
        Addend_B             <= Regfile(Index);
                                ("0" & Regfile(Index));
        Flags_D(FL_CARRY)    <= Sum(8);
            Flags(FL_CARRY)  <= Sum(8);
        Regfile_D(0)         <= Sum(7 downto 0);
            Regfile(0)       <= Sum(7 downto 0);
        Flags_D(FL_ZERO)     <= '0';
            Flags(FL_ZERO)   <= '0';
        if( Sum(7 downto 0) = 0 )then
        if( Sum(7 downto 0) = 0 )then
          Flags_D(FL_ZERO)   <= '1';
              Flags(FL_ZERO) <= '1';
        end if;
        end if;
        Flags_D(FL_NEG)      <= Sum(7);
            Flags(FL_NEG)    <= Sum(7);
 
 
      when ALU_STP => -- Sets bit(n) in the Flags register
      when ALU_STP => -- Sets bit(n) in the Flags register
        Flags_D(Index)       <= '1';
            Flags(Index)     <= '1';
 
 
      when ALU_BTT => -- Z = !R0(N), N = R0(7)
      when ALU_BTT => -- Z = !R0(N), N = R0(7)
        Flags_D(FL_ZERO)     <= not Regfile(0)(Index);
            Flags(FL_ZERO)   <= not Regfile(0)(Index);
        Flags_D(FL_NEG)      <= Regfile(0)(7);
            Flags(FL_NEG)    <= Regfile(0)(7);
--        Temp                 := "0" & Regfile(Index);
 
--        Flags_D(FL_ZERO)     <= '0';
 
--        if( Temp(7 downto 0) = 0 )then
 
--          Flags_D(FL_ZERO)   <= '1';
 
--        end if;
 
--        Flags_D(FL_NEG)      <= Temp(7);
 
 
 
      when ALU_CLP => -- Clears bit(n) in the Flags register
      when ALU_CLP => -- Clears bit(n) in the Flags register
        Flags_D(Index)         <= '0';
            Flags(Index)     <= '0';
 
 
      when ALU_T0X => -- Rn = R0 : Flags N,Z
      when ALU_T0X => -- Rn = R0 : Flags N,Z
        Temp                 := "0" & Regfile(0);
        Temp                 := "0" & Regfile(0);
        Flags_D(FL_ZERO)     <= '0';
            Flags(FL_ZERO)   <= '0';
        if( Temp(7 downto 0) = 0 )then
        if( Temp(7 downto 0) = 0 )then
          Flags_D(FL_ZERO)   <= '1';
              Flags(FL_ZERO) <= '1';
        end if;
        end if;
        Flags_D(FL_NEG)      <= Temp(7);
            Flags(FL_NEG)    <= Temp(7);
        Regfile_D(Index)     <= Temp(7 downto 0);
            Regfile(Index)   <= Temp(7 downto 0);
 
 
      when ALU_CMP => -- Sets Flags on R0 - Rn : Flags N,C,Z
      when ALU_CMP => -- Sets Flags on R0 - Rn : Flags N,C,Z
        Addend_A             <= Regfile(0);
            Sum              := ("0" & Regfile(0)) +
        Addend_B             <= not Regfile(Index);
                                ("0" & (not Regfile(Index))) +
        Carry                <= '1';
                                '1';
        Flags_D(FL_ZERO)     <= '0';
            Flags(FL_ZERO)   <= '0';
        if( Sum(7 downto 0) = 0 )then
        if( Sum(7 downto 0) = 0 )then
          Flags_D(FL_ZERO)   <= '1';
              Flags(FL_ZERO) <= '1';
        end if;
        end if;
        Flags_D(FL_CARRY)    <= Sum(8);
            Flags(FL_CARRY)  <= Sum(8);
        Flags_D(FL_NEG)      <= Sum(7);
            Flags(FL_NEG)    <= Sum(7);
 
 
      when ALU_MUL => -- Stage 1 of 2 {R1:R0} = R0 * Rn : Flags Z
      when ALU_MUL => -- Stage 1 of 2 {R1:R0} = R0 * Rn : Flags Z
        Regfile_D(0)         <= Mult(7 downto 0);
            Regfile(0)       <= Mult(7 downto 0);
        Regfile_D(1)         <= Mult(15 downto 8);
            Regfile(1)       <= Mult(15 downto 8);
        Flags_D(FL_ZERO)     <= '0';
            Flags(FL_ZERO)   <= '0';
        if( Mult = 0 )then
        if( Mult = 0 )then
          Flags_D(FL_ZERO)   <= '1';
              Flags(FL_ZERO) <= '1';
        end if;
        end if;
 
 
      when ALU_LDI | ALU_POP => -- Rn <= Data : Flags N,Z
      when ALU_LDI | ALU_POP => -- Rn <= Data : Flags N,Z
        -- The POP instruction doesn't alter the flags, so we need to check
        -- The POP instruction doesn't alter the flags, so we need to check
        if( ALU_Ctrl.Oper = ALU_LDI )then
        if( ALU_Ctrl.Oper = ALU_LDI )then
          Flags_D(FL_ZERO)   <= '0';
              Flags(FL_ZERO) <= '0';
          if( ALU_Ctrl.Data = 0 )then
          if( ALU_Ctrl.Data = 0 )then
            Flags_D(FL_ZERO) <= '1';
                Flags(FL_ZERO) <= '1';
          end if;
          end if;
          Flags_D(FL_NEG)    <= ALU_Ctrl.Data(7);
              Flags(FL_NEG)  <= ALU_Ctrl.Data(7);
        end if;
        end if;
        Regfile_D(Index)     <= ALU_Ctrl.Data;
            Regfile(Index)   <= ALU_Ctrl.Data;
 
 
      when ALU_LDX => -- R0 <= Data : Flags N,Z
      when ALU_LDX => -- R0 <= Data : Flags N,Z
        Flags_D(FL_ZERO)     <= '0';
            Flags(FL_ZERO)   <= '0';
        if( ALU_Ctrl.Data = 0 )then
        if( ALU_Ctrl.Data = 0 )then
          Flags_D(FL_ZERO)   <= '1';
              Flags(FL_ZERO) <= '1';
        end if;
        end if;
        Flags_D(FL_NEG)      <= ALU_Ctrl.Data(7);
            Flags(FL_NEG)    <= ALU_Ctrl.Data(7);
        Regfile_D(0)         <= ALU_Ctrl.Data;
            Regfile(0)       <= ALU_Ctrl.Data;
 
 
      when ALU_RFLG =>
      when ALU_RFLG =>
        Flags_D              <= ALU_Ctrl.Data;
            Flags            <= ALU_Ctrl.Data;
 
 
      when others => null;
      when others => null;
    end case;
    end case;
  end process;
 
 
 
  -- 8-bit Adder with carry
 
  Sum                        <= ("0" & Addend_A) + ("0" & Addend_B) + Carry;
 
 
 
  -- We need to infer a hardware multipler, so we create a special clocked
 
  --  process with no reset or clock enable
 
  M_Reg: process( Clock )
 
  begin
 
    if( rising_edge(Clock) )then
 
      Mult                   <= Regfile(0) *
 
                                Regfile(conv_integer(ALU_Ctrl.Reg));
 
    end if;
 
  end process;
 
 
 
  S_Regs: process( Reset, Clock )
 
  begin
 
    if( Reset = Reset_Level )then
 
      for i in 0 to 7 loop
 
        Regfile(i)           <= (others => '0');
 
      end loop;
 
      Flags                  <= x"00";
 
    elsif( rising_edge(Clock) )then
 
      if( Halt = '0' )then
 
        Regfile              <= Regfile_D;
 
        Flags                <= Flags_D;
 
      end if;
      end if;
    end if;
    end if;
  end process;
  end process;
 
 
end block;
end block;
Line 490... Line 467...
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
 
 
Open8_PC : block is
Open8_PC : block is
  -- Preinitialization is for simulation only - check actual reset conditions
  -- Preinitialization is for simulation only - check actual reset conditions
  signal PC_Q                : ADDRESS_TYPE := (others => '0');
  signal PC_Q                : ADDRESS_TYPE := (others => '0');
  signal Rewind_1_2n         : std_logic    := '0';
 
begin
begin
 
 
  PC                         <= PC_Q;
  PC                         <= PC_Q;
 
 
  -- This sets the carry input on the "rewind" adder. If the rewind command is
  Program_Counter: process( Reset, Clock )
  --  PC_REV2, then we clear the carry. Otherwise, we leave it high.
 
  Rewind_PC_Calc: process( PC_Ctrl )
 
  begin
 
    Rewind_1_2n              <= '1';
 
    if( PC_Ctrl.Oper = PC_REV2 )then
 
      Rewind_1_2n            <= '0';
 
    end if;
 
  end process;
 
 
 
  Program_Counter: process( Reset, Clock, Halt, PC_Ctrl, PC_Q, Rewind_1_2n )
 
    variable PC_Offset_SX    : ADDRESS_TYPE := x"0000";
    variable PC_Offset_SX    : ADDRESS_TYPE := x"0000";
  begin
  begin
    PC_Offset_SX(15 downto 8):= (others => PC_Ctrl.Offset(7));
 
    PC_Offset_SX(7 downto 0) := PC_Ctrl.Offset;
 
    if( Reset = Reset_Level )then
    if( Reset = Reset_Level )then
      PC_Q                   <= Program_Start_Addr;
      PC_Q                   <= Program_Start_Addr;
    elsif( rising_edge(Clock) )then
    elsif( rising_edge(Clock) )then
 
      PC_Offset_SX(15 downto 8):= (others => PC_Ctrl.Offset(7));
 
      PC_Offset_SX(7 downto 0) := PC_Ctrl.Offset;
      if( Halt = '0' )then
      if( Halt = '0' )then
        case PC_Ctrl.Oper is
        case PC_Ctrl.Oper is
          when PC_IDLE =>
          when PC_IDLE =>
            null;
            null;
          when PC_REV1 | PC_REV2 =>
          when PC_REV1 =>
            PC_Q             <= PC_Q - 2 + Rewind_1_2n;
            PC_Q             <= PC_Q - 1;
 
          when PC_REV2 =>
 
            PC_Q             <= PC_Q - 2;
          when PC_INCR =>
          when PC_INCR =>
            PC_Q             <= PC_Q + PC_Offset_SX - 2;
            PC_Q             <= PC_Q + PC_Offset_SX - 2;
          when PC_LOAD =>
          when PC_LOAD =>
            PC_Q             <= PC_Ctrl.Addr;
            PC_Q             <= PC_Ctrl.Addr;
        end case;
        end case;
Line 560... Line 528...
  end process;
  end process;
 
 
end block;
end block;
 
 
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
 
-- Address Source Mux
 
-------------------------------------------------------------------------------
 
 
 
Open8_AS : block is
 
begin
 
 
 
  Address_Select: process( AS_Ctrl, PC, SP, IMM, ISR )
 
  begin
 
    Address                  <= (others => '0');
 
    case AS_Ctrl.Src is
 
      when ADDR_PC =>
 
        Address              <= PC;
 
      when ADDR_SP =>
 
        Address              <= SP;
 
      when ADDR_IMM =>
 
        Address              <= IMM;
 
      when ADDR_ISR =>
 
        Address              <= ISR;
 
    end case;
 
  end process;
 
 
 
end block;
 
 
 
-------------------------------------------------------------------------------
 
-- (Write) Data Path
 
-------------------------------------------------------------------------------
 
 
 
Open8_DP : block is
 
begin
 
 
 
  Data_Path: process( Reset, Clock )
 
  begin
 
    if( Reset = Reset_Level )then
 
      Wr_Data                <= (others => '0');
 
      Wr_Enable              <= '0';
 
      Rd_Enable              <= '1';
 
    elsif( rising_edge(Clock) )then
 
      if( Halt = '0' )then
 
        Wr_Enable            <= '0';
 
        Rd_Enable            <= '1';
 
        case DP_Ctrl.Src is
 
          when DATA_IDLE =>
 
            null;
 
          when DATA_REG =>
 
            Wr_Enable        <= '1';
 
            Rd_Enable        <= '0';
 
            Wr_Data          <= ALU_Regs(conv_integer(DP_Ctrl.Reg));
 
          when DATA_FLAG =>
 
            Wr_Enable        <= '1';
 
            Rd_Enable        <= '0';
 
            Wr_Data          <= ALU_Flags;
 
          when DATA_PC =>
 
            Wr_Enable        <= '1';
 
            Rd_Enable        <= '0';
 
            Wr_Data          <= PC(15 downto 8);
 
            if( DP_Ctrl.Reg = ACCUM )then
 
              Wr_Data        <= PC(7 downto 0);
 
            end if;
 
          when others => null;
 
        end case;
 
      end if;
 
    end if;
 
  end process;
 
 
 
end block;
 
 
 
-------------------------------------------------------------------------------
-- Interrupt Controller
-- Interrupt Controller
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
 
 
Open8_INT : block is
Open8_INT : block is
 
 
Line 1331... Line 1366...
        --  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_IDLE; -- JSH 7/20
 
        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 1415... Line 1451...
  SP_Ctrl.Addr               <= Stack_Start_Addr;
  SP_Ctrl.Addr               <= Stack_Start_Addr;
end generate;
end generate;
 
 
end block;
end block;
 
 
-------------------------------------------------------------------------------
 
-- Address Source Mux
 
-------------------------------------------------------------------------------
 
 
 
Open8_AS : block is
 
begin
 
 
 
  Address_Select: process( AS_Ctrl, PC, SP, IMM, ISR )
 
    variable PC_Mux, SP_Mux  : ADDRESS_TYPE;
 
    variable IMM_Mux, ISR_Mux: ADDRESS_TYPE;
 
  begin
 
    PC_Mux                   := (others => '0');
 
    SP_Mux                   := (others => '0');
 
    IMM_Mux                  := (others => '0');
 
    ISR_Mux                  := (others => '0');
 
 
 
    case AS_Ctrl.Src is
 
      when ADDR_PC =>
 
        PC_Mux               := PC;
 
      when ADDR_SP =>
 
        SP_Mux               := SP;
 
      when ADDR_IMM =>
 
        IMM_Mux              := IMM;
 
      when ADDR_ISR =>
 
        ISR_Mux              := ISR;
 
    end case;
 
 
 
    for i in 0 to 15 loop
 
      Address(i)             <= PC_Mux(i) or SP_Mux(i) or IMM_Mux(i) or
 
                                ISR_Mux(i);
 
    end loop;
 
  end process;
 
 
 
end block;
 
 
 
-------------------------------------------------------------------------------
 
-- (Write) Data Path
 
-------------------------------------------------------------------------------
 
 
 
Open8_DP : block is
 
  signal Wr_Data_D           : DATA_TYPE := (others => '0');
 
  signal Wr_Enable_D         : std_logic := '0';
 
begin
 
 
 
  Data_Select: process( DP_Ctrl, ALU_Regs, ALU_Flags, PC )
 
    variable Reg_Mux, PC_Mux : DATA_TYPE;
 
    variable Flag_Mux        : DATA_TYPE;
 
  begin
 
    Reg_Mux                  := (others => '0');
 
    Flag_Mux                 := (others => '0');
 
    PC_Mux                   := (others => '0');
 
    Wr_Enable_D              <= '0';
 
 
 
    case DP_Ctrl.Src is
 
      when DATA_IDLE =>
 
        null;
 
      when DATA_REG =>
 
        Reg_Mux              := ALU_Regs(conv_integer(DP_Ctrl.Reg));
 
        Wr_Enable_D          <= '1';
 
      when DATA_FLAG =>
 
        Flag_Mux             := ALU_Flags;
 
        Wr_Enable_D          <= '1';
 
      when DATA_PC =>
 
        Wr_Enable_D          <= '1';
 
        if( DP_Ctrl.Reg = ACCUM )then
 
          PC_Mux             := PC(7 downto 0);
 
        else
 
          PC_Mux             := PC(15 downto 8);
 
        end if;
 
    end case;
 
 
 
    for i in 0 to 7 loop
 
      Wr_Data_D(i)           <= Reg_Mux(i) or Flag_Mux(i) or PC_Mux(i);
 
    end loop;
 
  end process;
 
 
 
  S_Regs: process( Reset, Clock )
 
  begin
 
    if( Reset = Reset_Level )then
 
      Wr_Data                <= (others => '0');
 
      Wr_Enable              <= '0';
 
      Rd_Enable              <= '1';
 
    elsif( rising_edge(Clock) )then
 
      if( Halt = '0' )then
 
        Wr_Data              <= Wr_Data_D;
 
        Wr_Enable            <= Wr_Enable_D;
 
        Rd_Enable            <= not Wr_Enable_D;
 
      end if;
 
    end if;
 
  end process;
 
 
 
end block;
 
 
 
end rtl;
end rtl;
 
 
 No newline at end of file
 No newline at end of file

powered by: WebSVN 2.1.0

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