📄 cpu.vhd
字号:
--
-- 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 + -