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

Subversion Repositories risc5x

[/] [risc5x/] [trunk/] [cpu.vhd] - Rev 5

Go to most recent revision | Compare with Previous | Blame | View Log

--
-- Risc5x
-- www.OpenCores.Org - November 2001
--
--
-- This library is free software; you can distribute it and/or modify it
-- under the terms of the GNU Lesser General Public License as published
-- by the Free Software Foundation; either version 2.1 of the License, or
-- (at your option) any later version.
--
-- This library is distributed in the hope that it will be useful, but
-- WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-- See the GNU Lesser General Public License for more details.
--
-- A RISC CPU core.
--
-- (c) Mike Johnson 2001. All Rights Reserved.
-- mikej@opencores.org for support or any other issues.
--
-- Revision list
--
-- version 1.1 bug fix: Used wrong bank select bits in direct addressing mode
--                      INDF register returns 0 when indirectly read
--                      FSR bit 8 always set
-- version 1.0 initial opencores release
--
 
use work.pkg_risc5x.all;
use work.pkg_prims.all;
library ieee;
  use ieee.std_logic_1164.all;
  use ieee.std_logic_arith.all;
  use ieee.std_logic_unsigned.all;
 
entity CPU is
  port (
    PADDR           : out std_logic_vector(10 downto 0);
    PDATA           : in  std_logic_vector(11 downto 0);
 
    PORTA_IN        : in    std_logic_vector(7 downto 0);
    PORTA_OUT       : out   std_logic_vector(7 downto 0);
    PORTA_OE_L      : out   std_logic_vector(7 downto 0);
 
    PORTB_IN        : in    std_logic_vector(7 downto 0);
    PORTB_OUT       : out   std_logic_vector(7 downto 0);
    PORTB_OE_L      : out   std_logic_vector(7 downto 0);
 
    PORTC_IN        : in    std_logic_vector(7 downto 0);
    PORTC_OUT       : out   std_logic_vector(7 downto 0);
    PORTC_OE_L      : out   std_logic_vector(7 downto 0);
 
    DEBUG_W         : out std_logic_vector(7 downto 0);
    DEBUG_PC        : out std_logic_vector(10 downto 0);
    DEBUG_INST      : out std_logic_vector(11 downto 0);
    DEBUG_STATUS    : out std_logic_vector(7 downto 0);
 
    RESET           : in  std_logic;
    CLK             : in  std_logic
    );
end;
 
architecture RTL of CPU is
 
-- component definitions
 
component IDEC is
  port (
    INST                : in  std_logic_vector(11 downto 0);
 
    ALU_ASEL            : out std_logic_vector(1 downto 0);
    ALU_BSEL            : out std_logic_vector(1 downto 0);
    ALU_ADDSUB          : out std_logic_vector(1 downto 0);
    ALU_BIT             : out std_logic_vector(1 downto 0);
    ALU_SEL             : out std_logic_vector(1 downto 0);
 
    WWE_OP              : out std_logic;
    FWE_OP              : out std_logic;
 
    ZWE                 : out std_logic;
    DCWE                : out std_logic;
    CWE                 : out std_logic;
    BDPOL               : out std_logic;
    OPTION              : out std_logic;
    TRIS                : out std_logic
    );
end component;
 
component ALU is
  port (
    ADDSUB          : in  std_logic_vector(1 downto 0);
    BIT             : in  std_logic_vector(1 downto 0);
    SEL             : in  std_logic_vector(1 downto 0);
 
    A               : in  std_logic_vector(7 downto 0);
    B               : in  std_logic_vector(7 downto 0);
    Y               : out std_logic_vector(7 downto 0);
    CIN             : in  std_logic;
    COUT            : out std_logic;
    DCOUT           : out std_logic;
    ZOUT            : out std_logic
    );
end component;
 
component REGS is
  port (
    WE              : in  std_logic;
    RE              : in  std_logic;
    BANK            : in  std_logic_vector(1 downto 0);
    LOCATION        : in  std_logic_vector(4 downto 0);
    DIN             : in  std_logic_vector(7 downto 0);
    DOUT            : out std_logic_vector(7 downto 0);
    RESET           : in  std_logic;
    CLK             : in  std_logic
    );
end component;
 
-- type/constant definitions
  constant STATUS_RESET_VALUE : std_logic_vector(7 downto 0) := x"18";
  constant OPTION_RESET_VALUE : std_logic_vector(7 downto 0) := x"3F";
  constant INDF_ADDR     : std_logic_vector(2 downto 0) := "000";
  constant TMR0_ADDR     : std_logic_vector(2 downto 0) := "001";
  constant PCL_ADDR      : std_logic_vector(2 downto 0) := "010";
  constant STATUS_ADDR   : std_logic_vector(2 downto 0) := "011";
  constant FSR_ADDR      : std_logic_vector(2 downto 0) := "100";
  constant PORTA_ADDR    : std_logic_vector(2 downto 0) := "101";
  constant PORTB_ADDR    : std_logic_vector(2 downto 0) := "110";
  constant PORTC_ADDR    : std_logic_vector(2 downto 0) := "111";
 
-- signal definitions
  signal inst                           : std_logic_vector(11 downto 0);
 
  signal inst_k                         : std_logic_vector(7 downto 0);
  signal inst_fsel                      : std_logic_vector(4 downto 0);
  signal inst_d                         : std_logic;
  signal inst_b                         : std_logic_vector(2 downto 0);
 
  signal pc,next_pc                     : std_logic_vector(10 downto 0);
  signal pc_load_stack                  : std_logic_vector(10 downto 0);
  signal pc_write                       : std_logic_vector(10 downto 0);
  signal pc_call                        : std_logic_vector(10 downto 0);
  signal pc_goto                        : std_logic_vector(10 downto 0);
  signal pc_load                        : std_logic_vector(10 downto 0);
  signal pc_load_sel                    : std_logic_vector(1 downto 0);
  signal pc_inc                         : std_logic;
 
  signal stacklevel                     : std_logic_vector(1 downto 0);
  signal stack1,stack2                  : std_logic_vector(10 downto 0);
  signal w_reg,status,fsr,tmr0          : std_logic_vector(7 downto 0);
  signal prescaler,option               : std_logic_vector(7 downto 0);
  signal trisa,trisb,trisc              : std_logic_vector(7 downto 0);
 
  signal porta_dout                     : std_logic_vector(7 downto 0);
  signal portb_dout                     : std_logic_vector(7 downto 0);
  signal portc_dout                     : std_logic_vector(7 downto 0);
 
  signal porta_din                      : std_logic_vector(7 downto 0);
  signal portb_din                      : std_logic_vector(7 downto 0);
  signal portc_din                      : std_logic_vector(7 downto 0);
 
  signal dbus,sbus                      : std_logic_vector(7 downto 0);
  signal sbus_swap                      : std_logic_vector(7 downto 0);
  signal sbus_mux_out                   : std_logic_vector(7 downto 0);
 
  -- inst decode
  signal regfile_sel,special_sel        : std_logic;
  signal fileaddr_indirect              : std_logic;
  signal fileaddr_mux1                  : std_logic_vector(6 downto 0);
  signal fileaddr_mux0                  : std_logic_vector(6 downto 0);
 
  signal istris,isoption                : std_logic;
  signal fwe,wwe,zwe,dcwe,cwe           : std_logic;
  signal bdpol                          : std_logic;
  signal bd                             : std_logic_vector(7 downto 0);
  signal skip                           : std_logic;
 
  -- alu
  signal alu_asel,alu_bsel              : std_logic_vector(1 downto 0) := (others => '0');
  signal alu_addsub                     : std_logic_vector(1 downto 0) := (others => '0');
  signal alu_bit                        : std_logic_vector(1 downto 0) := (others => '0');
  signal alu_sel                        : std_logic_vector(1 downto 0) := (others => '0');
 
  signal alu_z,alu_dcout,alu_cout       : std_logic := '0';
  signal alu_a,alu_b                    : std_logic_vector(7 downto 0) := (others => '0');
  signal alu_out                        : std_logic_vector(7 downto 0);
 
  signal regfile_we,regfile_re          : std_logic;
  signal regfile_in,regfile_out         : std_logic_vector(7 downto 0);
  signal fileaddr                       : std_logic_vector(6 downto 0);
 
begin -- architecture
 
  u_idec : IDEC
    port map (
      INST                => inst,
 
      ALU_ASEL            => alu_asel,
      ALU_BSEL            => alu_bsel,
      ALU_ADDSUB          => alu_addsub,
      ALU_BIT             => alu_bit,
      ALU_SEL             => alu_sel,
 
      WWE_OP              => wwe,
      FWE_OP              => fwe,
 
      ZWE                 => zwe,
      DCWE                => dcwe,
      CWE                 => cwe,
      BDPOL               => bdpol,
      OPTION              => isoption,
      TRIS                => istris
      );
 
  u_alu : ALU
    port map (
      ADDSUB          => alu_addsub,
      BIT             => alu_bit,
      SEL             => alu_sel,
 
      A               => alu_a,
      B               => alu_b,
      Y               => alu_out,
      CIN             => status(0),
      COUT            => alu_cout,
      DCOUT           => alu_dcout,
      ZOUT            => alu_z
      );
 
  u_regs : REGS
    port map (
      WE              => regfile_we,
      RE              => regfile_re,
      BANK            => fileaddr(6 downto 5),
      LOCATION        => fileaddr(4 downto 0),
      DIN             => regfile_in,
      DOUT            => regfile_out,
      RESET           => RESET,
      CLK             => CLK
      );
 
  DEBUG_W <= w_reg;
  DEBUG_PC <= pc(10 downto 0);
  DEBUG_INST <= inst;
  DEBUG_STATUS <= status;
 
  -- *********** REGISTER FILE Addressing ****************
  p_addr_dec_comb : process(inst_fsel,fsr)
  begin
    if (inst_fsel = ("00" & INDF_ADDR)) then
      fileaddr_indirect <= '1';
    else
      fileaddr_indirect <= '0';
    end if;
 
    fileaddr_mux1 <= fsr(6 downto 0);
    fileaddr_mux0 <= (fsr(6 downto 5) & inst_fsel);
  end process;
 
  fileaddr_mux : MUX2
    generic map (
      WIDTH         => 7,
      SLICE         => 1,
      OP_REG        => FALSE
      )
    port map (
      DIN1          => fileaddr_mux1,
      DIN0          => fileaddr_mux0,
 
      SEL           => fileaddr_indirect,
      ENA           => '0', -- not used
      CLK           => '0', -- not used
 
      DOUT          => fileaddr
      );
 
  p_regfile_we_comb : process(regfile_sel,fwe,alu_asel,alu_bsel)
  begin
    regfile_we <= regfile_sel and fwe;
    regfile_re <= '1'; -- not used
  end process;
 
  p_fileaddr_dec_comb : process(fileaddr,isoption,istris)
  begin
    regfile_sel <= '1'; -- everything else;
    special_sel <= '0';
    if (fileaddr(4 downto 3) = "00") and (isoption = '0') and (istris = '0') then
      special_sel <= '1';  -- lower 8 addresses in ALL BANKS 1 lut
    end if;
  end process;
 
  sbus_muxa : MUX8
    generic map (
      WIDTH         => 8,
      OP_REG        => FALSE
      )
    port map (
      DIN7          => portc_din,
      DIN6          => portb_din,
      DIN5          => porta_din,
      DIN4          => fsr,
      DIN3          => status,
      DIN2          => pc(7 downto 0),
      DIN1          => tmr0,
      DIN0          => x"00", -- INDF returns 0
 
      SEL           => inst_fsel(2 downto 0),
      ENA           => '0',
      CLK           => '0',
 
      DOUT          => sbus_mux_out
      );
 
  sbus_muxb : MUX2
    generic map (
      WIDTH         => 8,
      SLICE         => 1,
      OP_REG        => FALSE
      )
    port map (
      DIN1          => sbus_mux_out,
      DIN0          => regfile_out,
 
      SEL           => special_sel,
      ENA           => '0',
      CLK           => '0',
 
      DOUT          => sbus
      );
 
  p_dbus_comb : process(alu_out)
  begin
    dbus <= alu_out;
    regfile_in <= alu_out;
  end process;
 
  p_paddr_comb : process(next_pc)
  begin
     PADDR <= next_pc(10 downto 0);
  end process;
 
  p_inst_assign_comb : process(inst)
  begin
    inst_k    <= inst(7 downto 0);
    inst_fsel <= inst(4 downto 0);
    inst_d    <= inst(5);
    inst_b    <= inst(7 downto 5);
  end process;
 
  p_bdec_assign_comb : process(inst_b,bdpol)
  variable bdec : std_logic_vector(7 downto 0);
  begin
    -- 1 lut
    bdec := "00000001";
    case inst_b is
      when "000" => bdec := "00000001";
      when "001" => bdec := "00000010";
      when "010" => bdec := "00000100";
      when "011" => bdec := "00001000";
      when "100" => bdec := "00010000";
      when "101" => bdec := "00100000";
      when "110" => bdec := "01000000";
      when "111" => bdec := "10000000";
      when others => null;
    end case;
    if (bdpol = '1') then
      bd <= not bdec;
    else
      bd <=     bdec;
    end if;
  end process;
 
  p_inst : process(CLK,RESET)
  begin
    if (RESET = '1') then
      inst <= x"000";
    elsif CLK'event and (CLK = '1') then
      if (skip = '1')  then
        inst <= x"000"; -- force NOP
      else
        inst <= PDATA;
      end if;
    end if;
  end process;
 
  p_skip_comb : process(inst,alu_z,fwe,special_sel,fileaddr)
  begin
    -- SKIP signal.
    -- We want to insert the NOP instruction for the following conditions:
    --    we have modified PCL
    --    GOTO,CALL and RETLW instructions
    --    BTFSS instruction when aluz is HI
    --    BTFSC instruction when aluz is LO
   skip <= '0';
 
    if (fwe = '1') and (special_sel = '1') and (fileaddr(2 downto 0) = PCL_ADDR) then skip <= '1'; end if;
    if (inst(11 downto 10) = "10") then skip <= '1'; end if;
    if (inst(11 downto  8) = "0110") and (alu_z = '1') then skip <= '1'; end if; -- BTFSC
    if (inst(11 downto  8) = "0111") and (alu_z = '0') then skip <= '1'; end if; -- BTFSS
    if (inst(11 downto  6) = "001011") and (alu_z = '1') then skip <= '1'; end if; -- DECFSZ
    if (inst(11 downto  6) = "001111") and (alu_z = '1') then skip <= '1'; end if; -- INCFSZ
  end process;
 
  sbus_swap <= sbus(3 downto 0) & sbus(7 downto 4);
 
  alua_mux : MUX4
    generic map (
      WIDTH         => 8,
      SLICE         => 1,
      OP_REG        => FALSE
      )
    port map (
      DIN3          => sbus_swap,
      DIN2          => inst_k,
      DIN1          => sbus,
      DIN0          => w_reg,
 
      SEL           => alu_asel,
      ENA           => '0',
      CLK           => '0',
 
      DOUT          => alu_a
      );
 
  alub_mux : MUX4
    generic map (
      WIDTH         => 8,
      SLICE         => 0,
      OP_REG        => FALSE
      )
    port map (
      DIN3          => x"01",
      DIN2          => bd,
      DIN1          => sbus,
      DIN0          => w_reg,
 
      SEL           => alu_bsel,
      ENA           => '0',
      CLK           => '0',
 
      DOUT          => alu_b
      );
 
  p_w_reg : process(CLK,RESET)
  begin
    if (RESET = '1') then
      w_reg <= x"00";
    elsif CLK'event and (CLK = '1') then
      if (wwe = '1')  then
        w_reg <= dbus;
      end if;
    end if;
  end process;
 
  p_tmr0 : process(CLK,RESET)
    variable mask : std_logic_vector(7 downto 0);
  begin
    if (RESET = '1') then
      tmr0 <= x"00";
    elsif CLK'event and (CLK = '1') then
      -- See if the timer register is actually being written to
      if (fwe = '1') and (special_sel = '1') and (fileaddr(2 downto 0) = TMR0_ADDR) then
        tmr0 <= dbus;
      else
        mask := "00000001";
        case option(2 downto 0) is
          when "000" => mask := "00000001";
          when "001" => mask := "00000011";
          when "010" => mask := "00000111";
          when "011" => mask := "00001111";
          when "100" => mask := "00011111";
          when "101" => mask := "00111111";
          when "110" => mask := "01111111";
          when "111" => mask := "11111111";
          when others => null;
        end case;
        if ((prescaler and mask) = "00000000") or (option(3) = '1') then
          tmr0 <= tmr0 + "1";
        end if;
      end if;
    end if;
  end process;
 
  p_prescaler : process(CLK,RESET)
  begin
    if (RESET = '1') then
      prescaler <= x"00";
    elsif CLK'event and (CLK = '1') then
      if not (option(5) = '1') then
        prescaler <= prescaler + "1";
      end if;
    end if;
  end process;
 
  p_status_reg : process(CLK,RESET)
    variable new_z,new_dc,new_c : std_logic;
  begin
    if (RESET = '1') then
      status <= STATUS_RESET_VALUE;
    elsif CLK'event and (CLK = '1') then
      -- See if the status register is actually being written to
      -- this is not accurate, bits 4 & 3 should be read only
      -- additionally, zwe,cwe and dcwe should override fwe
 
      if (fwe = '1') and (special_sel = '1') and (fileaddr(2 downto 0) = STATUS_ADDR) then
        status <= dbus;
      else
      -- For the carry and zero flags, each instruction has its own rule as
      -- to whether to update this flag or not.  The instruction decoder is
      -- providing us with an enable for C and Z.  Use this to decide whether
      -- to retain the existing value, or update with the new alu status output.
         if (zwe = '1') then new_z := alu_z; else new_z := status(2); end if;
         if (dcwe = '1') then new_dc := alu_dcout; else new_dc := status(1); end if;
         if (cwe = '1') then new_c := alu_cout; else new_c := status(0); end if;
         status <= (
              status(7) &                  -- BIT 7: Undefined.. (maybe use for debugging)
              status(6) &                  -- BIT 6: Program Page, HI bit
              status(5) &                  -- BIT 5: Program Page, LO bit
              status(4) &                  -- BIT 4: Time Out bit (not implemented at this time)
              status(3) &                  -- BIT 3: Power Down bit (not implemented at this time)
              new_z     &                  -- BIT 2: Z
              new_dc    &                  -- BIT 1: DC
              new_c);                      -- BIT 0: C
       end if;
    end if;
  end process;
 
  p_fsr_reg : process(CLK,RESET)
  begin
    if (RESET = '1') then
      fsr <= x"80";
    elsif CLK'event and (CLK = '1') then
      if (fwe = '1') and (special_sel = '1') and (fileaddr(2 downto 0) = FSR_ADDR) then
        fsr <= dbus;
      end if;
      fsr(7) <= '1'; --always set in real chip
    end if;
  end process;
 
  p_option_reg : process(CLK,RESET)
  begin
    if (RESET = '1') then
      option <= OPTION_RESET_VALUE;
    elsif CLK'event and (CLK = '1') then
      if (isoption = '1') then
        option <= dbus;
      end if;
    end if;
  end process;
 
  p_drive_ports_comb : process(porta_dout,trisa,portb_dout,trisb,portc_dout,trisc)
  begin
      PORTA_OE_L <= trisa;
      PORTB_OE_L <= trisb;
      PORTC_OE_L <= trisc;
 
      PORTA_OUT <= porta_dout;
      PORTB_OUT <= portb_dout;
      PORTC_OUT <= portc_dout;
 
  end process;
 
  port_in : process(CLK,RESET,PORTA_IN,PORTB_IN,PORTC_IN)
    begin
    -- the input registers don't exist in the real device,
    -- so if you read an output we have introduced a clock delay.
      if (RESET = '1') then
        porta_din <= (others => '0');
        portb_din <= (others => '0');
        portc_din <= (others => '0');
      elsif CLK'event and (CLK = '1') then -- comment this out for combinatorial ip
      --else                               -- or comment this for registered ip
        porta_din <= PORTA_IN;
        portb_din <= PORTB_IN;
        portc_din <= PORTC_IN;
      end if;
  end process;
 
  p_port_reg : process(CLK,RESET)
  begin
    if (RESET = '1') then
      trisa <= x"FF"; -- default tristate
      trisb <= x"FF"; -- default tristate
      trisc <= x"FF"; -- default tristate
      porta_dout <= x"00";
      portb_dout <= x"00";
      portc_dout <= x"00";
    elsif CLK'event and (CLK = '1') then
 
      if (fwe = '1') and (fileaddr(2 downto 0) = PORTA_ADDR) then
        if (istris = '0') and (special_sel = '1') then
          porta_dout <= dbus;
        elsif (istris = '1') then
          trisa <= dbus;
        end if;
      end if;
 
      if (fwe = '1') and (fileaddr(2 downto 0) = PORTB_ADDR) then
        if (istris = '0') and (special_sel = '1') then
          portb_dout <= dbus;
        elsif (istris = '1') then
          trisb <= dbus;
        end if;
      end if;
 
      if (fwe = '1') and (fileaddr(2 downto 0) = PORTC_ADDR) then
        if (istris = '0') and (special_sel = '1') then
          portc_dout <= dbus;
        elsif (istris = '1') then
          trisc <= dbus;
        end if;
      end if;
    end if;
  end process;
 
  -- ********** PC AND STACK *************************
 
  p_next_pc_comb : process(pc,inst,status,stacklevel,stack1,stack2,dbus,fileaddr,special_sel,fwe)
  begin
 
    pc_goto  <= ( status(6 downto 5) &       inst(8 downto 0));
    pc_call  <= ( status(6 downto 5) & '0' & inst(7 downto 0));
    pc_write <= (pc(10) & '0' & pc(8) & dbus);          -- set bit 9 to zero
 
    pc_inc <= '1'; -- default
 
    pc_load_sel <= "00"; -- pc write
    if (fwe = '1') and (special_sel = '1') and (fileaddr(2 downto 0) = PCL_ADDR) then
      --pc_load_sel <= "00";  default
      pc_inc <= '0';  -- as we have modified next_pc, must skip next instruction
    end if;
 
    if (inst(11 downto 9) = "101")  then pc_load_sel <= "01"; pc_inc <= '0'; end if; -- goto
    if (inst(11 downto 8) = "1001") then pc_load_sel <= "10"; pc_inc <= '0'; end if; -- call
    if (inst(11 downto 8) = "1000") then pc_load_sel <= "11"; pc_inc <= '0'; end if; -- ret
 
  end process;
 
  pc_load_mux : MUX4
    generic map (
      WIDTH         => 11,
      SLICE         => 0,
      OP_REG        => FALSE
      )
    port map (
      DIN3          => pc_load_stack,
      DIN2          => pc_call,
      DIN1          => pc_goto,
      DIN0          => pc_write,
 
      SEL           => pc_load_sel,
      ENA           => '0',
      CLK           => '0',
 
      DOUT          => pc_load
      );
 
  pc_mux2_add_reg : MUX2_ADD_REG
    generic map (
      WIDTH         => 11
      )
    port map (
      ADD_VAL       => "00000000001",  -- pc = pc + 1
      LOAD_VAL      => pc_load, -- branch
 
      ADD           => pc_inc,
 
      PRESET        => RESET,
      ENA           => '1',
      CLK           => CLK,
 
      DOUT          => next_pc,
      REG_DOUT      => pc
      );
 
  p_stack_comb : process(stacklevel,stack1,stack2)
  begin
    pc_load_stack <= stack1; -- default
    case stacklevel is
      when "00" => pc_load_stack <= stack1;
      when "01" => pc_load_stack <= stack1;
      when "10" => pc_load_stack <= stack2;
      when "11" => pc_load_stack <= stack2;
      when others => null;
    end case;
  end process;
 
  p_stack_reg : process(CLK,RESET)
  begin
    if (RESET = '1') then
      stack1 <= (others => '0');
      stack2 <= (others => '0');
    elsif CLK'event and (CLK = '1') then
      if (inst(11 downto 8) = "1001") then
        case stacklevel is
          when "00" => stack1 <= pc(10 downto 0);
          when "01" => stack2 <= pc(10 downto 0);
          when "10" => assert false report "Too many CALLs !" severity failure;
          when "11" => assert false report "Too many CALLs !" severity failure;
          when others => null;
        end case;
      end if;
    end if;
  end process;
 
  p_stack_level : process(CLK,RESET)
  begin
    if (RESET = '1') then
      stacklevel <= "00";
    elsif CLK'event and (CLK = '1') then
      stacklevel <= stacklevel;
      if (inst(11 downto 8) = "1001") then
        case stacklevel is
          when "00" => stacklevel <="01"; -- 1st call
          when "01" => stacklevel <="10"; -- 2nd call
          when "10" => stacklevel <="10"; -- already 2, ignore
          when "11" => stacklevel <="00"; -- broke
          when others => null;
        end case;
      elsif (inst(11 downto 8) = "1000") then
        case stacklevel is
          when "00" => stacklevel <="00"; -- broke
          when "01" => stacklevel <="00"; -- go back to no call
          when "10" => stacklevel <="01"; -- go back to 1 call
          when "11" => stacklevel <="10"; -- broke
          when others => null;
        end case;
      end if;
    end if;
  end process;
end rtl;
 
 

Go to most recent revision | Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

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