⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cpu.vhd

📁 risc5x源代码。介绍了一般微处理器核的设计原理、基本概念和方法.
💻 VHD
📖 第 1 页 / 共 2 页
字号:
--
-- 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;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -