mirror of
https://github.com/Domipheus/RPU.git
synced 2025-04-18 19:15:13 -04:00
Start of CSR and interrupt support for machine-mode level operations. No testbenches and the CSR operations are not fixed up yet. Some basic read values are included but as the register write logic is not edited to take values from the CSR unit rather than ALU any reads will result in the incorrect data being stored into rD.
This commit is contained in:
parent
12f77e85c5
commit
cc388e3a90
5 changed files with 420 additions and 43 deletions
|
@ -2,7 +2,6 @@
|
|||
-- Project Name: RISC-V CPU
|
||||
-- Description: Constants for instruction forms, opcodes, conditional flags, etc.
|
||||
--
|
||||
-- Revision: 1
|
||||
----------------------------------------------------------------------------------
|
||||
-- Copyright 2016 Colin Riley
|
||||
--
|
||||
|
@ -164,6 +163,101 @@ constant F3_SYSTEM_CSRRWI: std_logic_vector(2 downto 0) := "101";
|
|||
constant F3_SYSTEM_CSRRSI: std_logic_vector(2 downto 0) := "110";
|
||||
constant F3_SYSTEM_CSRRCI: std_logic_vector(2 downto 0) := "111";
|
||||
|
||||
|
||||
constant F3_PRIVOP: std_logic_vector(2 downto 0) := "000";
|
||||
|
||||
constant F7_PRIVOP_URET: std_logic_vector(6 downto 0) := "0000000";
|
||||
constant F7_PRIVOP_SRET_WFI: std_logic_vector(6 downto 0) := "0001000";
|
||||
constant F7_PRIVOP_MRET: std_logic_vector(6 downto 0) := "0011000";
|
||||
constant F7_PRIVOP_SFENCE_VMA: std_logic_vector(6 downto 0) := "0001001";
|
||||
|
||||
constant RD_PRIVOP: std_logic_vector(4 downto 0) := "00000";
|
||||
|
||||
constant R2_PRIV_RET: std_logic_vector(4 downto 0) := "00010";
|
||||
constant R2_PRIV_WFI: std_logic_vector(4 downto 0) := "00101";
|
||||
|
||||
|
||||
constant EXCEPTION_INT_USER_SOFTWARE: std_logic_vector(XLEN32M1 downto 0):= X"80000000";
|
||||
constant EXCEPTION_INT_SUPERVISOR_SOFTWARE: std_logic_vector(XLEN32M1 downto 0):= X"80000001";
|
||||
--constant EXCEPTION_INT_RESERVED: std_logic_vector(XLEN32M1 downto 0):= X"80000002";
|
||||
constant EXCEPTION_INT_MACHINE_SOFTWARE: std_logic_vector(XLEN32M1 downto 0):= X"80000003";
|
||||
constant EXCEPTION_INT_USER_TIMER: std_logic_vector(XLEN32M1 downto 0):= X"80000004";
|
||||
constant EXCEPTION_INT_SUPERVISOR_TIMER: std_logic_vector(XLEN32M1 downto 0):= X"80000005";
|
||||
--constant EXCEPTION_INT_RESERVED: std_logic_vector(XLEN32M1 downto 0):= X"80000006";
|
||||
constant EXCEPTION_INT_MACHINE_TIMER: std_logic_vector(XLEN32M1 downto 0):= X"80000007";
|
||||
constant EXCEPTION_INT_USER_EXTERNAL: std_logic_vector(XLEN32M1 downto 0):= X"80000008";
|
||||
constant EXCEPTION_INT_SUPERVISOR_EXTERNAL: std_logic_vector(XLEN32M1 downto 0):= X"80000009";
|
||||
--constant EXCEPTION_INT_RESERVED: std_logic_vector(XLEN32M1 downto 0):= X"8000000a";
|
||||
constant EXCEPTION_INT_MACHINE_EXTERNAL: std_logic_vector(XLEN32M1 downto 0):= X"8000000b";
|
||||
|
||||
constant EXCEPTION_INSTRUCTION_ADDR_MISALIGNED: std_logic_vector(XLEN32M1 downto 0):= X"00000000";
|
||||
constant EXCEPTION_INSTRUCTION_ACCESS_FAULT: std_logic_vector(XLEN32M1 downto 0):= X"00000001";
|
||||
constant EXCEPTION_INSTRUCTION_ILLEGAL: std_logic_vector(XLEN32M1 downto 0):= X"00000002";
|
||||
constant EXCEPTION_BREAKPOINT: std_logic_vector(XLEN32M1 downto 0):= X"00000003";
|
||||
constant EXCEPTION_LOAD_ADDRESS_MISALIGNED: std_logic_vector(XLEN32M1 downto 0):= X"00000004";
|
||||
constant EXCEPTION_LOAD_ACCESS_FAULT: std_logic_vector(XLEN32M1 downto 0):= X"00000005";
|
||||
constant EXCEPTION_STORE_AMO_ADDRESS_MISALIGNED:std_logic_vector(XLEN32M1 downto 0):= X"00000006";
|
||||
constant EXCEPTION_STORE_AMO_ACCESS_FAULT: std_logic_vector(XLEN32M1 downto 0):= X"00000007";
|
||||
constant EXCEPTION_ENVIRONMENT_CALL_FROM_UMODE: std_logic_vector(XLEN32M1 downto 0):= X"00000008";
|
||||
constant EXCEPTION_ENVIRONMENT_CALL_FROM_SMODE: std_logic_vector(XLEN32M1 downto 0):= X"00000009";
|
||||
--constant EXCEPTION_RESERVED: std_logic_vector(XLEN32M1 downto 0):= X"0000000a";
|
||||
constant EXCEPTION_ENVIRONMENT_CALL_FROM_MMODE: std_logic_vector(XLEN32M1 downto 0):= X"0000000b";
|
||||
constant EXCEPTION_INSTRUCTION_PAGE_FAULT: std_logic_vector(XLEN32M1 downto 0):= X"0000000c";
|
||||
constant EXCEPTION_LOAD_PAGE_FAULT: std_logic_vector(XLEN32M1 downto 0):= X"0000000d";
|
||||
--constant EXCEPTION_RESERVED: std_logic_vector(XLEN32M1 downto 0):= X"0000000e";
|
||||
constant EXCEPTION_STORE_AMO_PAGE_FAULT: std_logic_vector(XLEN32M1 downto 0):= X"0000000f";
|
||||
|
||||
constant CSR_ADDR_PRIVILEGE_BIT_START: integer := 9;
|
||||
constant CSR_ADDR_PRIVILEGE_BIT_END: integer := 8;
|
||||
constant CSR_ADDR_PRIVILEGE_USER: std_logic_vector(1 downto 0):= "00";
|
||||
constant CSR_ADDR_PRIVILEGE_SUPERVISOR: std_logic_vector(1 downto 0):= "01";
|
||||
constant CSR_ADDR_PRIVILEGE_RESERVED: std_logic_vector(1 downto 0):= "10";
|
||||
constant CSR_ADDR_PRIVILEGE_MACHINE: std_logic_vector(1 downto 0):= "11";
|
||||
|
||||
constant CSR_ADDR_ACCESS_BIT_START: integer := 11;
|
||||
constant CSR_ADDR_ACCESS_BIT_END: integer := 10;
|
||||
constant CSR_ADDR_ACCESS_READONLY: std_logic_vector(1 downto 0):= "11";
|
||||
|
||||
|
||||
-- CSR Opcodes:
|
||||
-- 0 - CSR Written
|
||||
-- 1 - CSR Read
|
||||
-- 2..3 0 operation
|
||||
-- 01 - read or write whole XLEN
|
||||
-- 10 - Set bits
|
||||
-- 11 - clear bits
|
||||
-- 4 - immediate or register
|
||||
|
||||
constant CSR_OP_BITS_WRITTEN: integer := 0;
|
||||
constant CSR_OP_BITS_READ: integer := 1;
|
||||
constant CSR_OP_BITS_OPA: integer := 2;
|
||||
constant CSR_OP_BITS_OPB: integer := 3;
|
||||
constant CSR_OP_BITS_IMM: integer := 4;
|
||||
|
||||
constant CSR_OP_WR: std_logic_vector(4 downto 0) := "00100";
|
||||
constant CSR_OP_W: std_logic_vector(4 downto 0) := "00101";
|
||||
constant CSR_OP_R: std_logic_vector(4 downto 0) := "00110";
|
||||
|
||||
constant CSR_OP_SET_WR: std_logic_vector(4 downto 0) := "01000";
|
||||
constant CSR_OP_SET_W: std_logic_vector(4 downto 0) := "01001";
|
||||
constant CSR_OP_SET_R: std_logic_vector(4 downto 0) := "01010";
|
||||
|
||||
constant CSR_OP_CLEAR_WR: std_logic_vector(4 downto 0) := "01100";
|
||||
constant CSR_OP_CLEAR_W: std_logic_vector(4 downto 0) := "01101";
|
||||
constant CSR_OP_CLEAR_R: std_logic_vector(4 downto 0) := "01110";
|
||||
|
||||
constant CSR_OP_IMM_WR: std_logic_vector(4 downto 0) := "10100";
|
||||
constant CSR_OP_IMM_W: std_logic_vector(4 downto 0) := "10101";
|
||||
constant CSR_OP_IMM_R: std_logic_vector(4 downto 0) := "10110";
|
||||
|
||||
constant CSR_OP_IMM_SET_WR: std_logic_vector(4 downto 0) := "11000";
|
||||
constant CSR_OP_IMM_SET_W: std_logic_vector(4 downto 0) := "11001";
|
||||
constant CSR_OP_IMM_SET_R: std_logic_vector(4 downto 0) := "11010";
|
||||
|
||||
constant CSR_OP_IMM_CLEAR_WR: std_logic_vector(4 downto 0) := "11100";
|
||||
constant CSR_OP_IMM_CLEAR_W: std_logic_vector(4 downto 0) := "11101";
|
||||
constant CSR_OP_IMM_CLEAR_R: std_logic_vector(4 downto 0) := "11110";
|
||||
|
||||
end constants;
|
||||
|
||||
package body constants is
|
||||
|
|
|
@ -38,6 +38,7 @@ entity control_unit is
|
|||
O_set_idata:out STD_LOGIC;
|
||||
O_set_ipc: out STD_LOGIC;
|
||||
O_set_irpc: out STD_LOGIC;
|
||||
O_instTick: out STD_LOGIC;
|
||||
|
||||
-- mem controller state and control
|
||||
I_ready: in STD_LOGIC;
|
||||
|
@ -64,7 +65,7 @@ architecture Behavioral of control_unit is
|
|||
signal interrupt_was_inactive: STD_LOGIC := '1';
|
||||
signal set_idata: STD_LOGIC := '0';
|
||||
signal set_ipc: STD_LOGIC := '0';
|
||||
|
||||
signal instTick: STD_LOGIC := '0';
|
||||
begin
|
||||
|
||||
O_execute <= mem_execute;
|
||||
|
@ -74,6 +75,7 @@ begin
|
|||
O_set_idata <= set_idata;
|
||||
O_set_irpc <= set_idata;
|
||||
O_set_ipc <= set_ipc;
|
||||
O_instTick <= instTick;
|
||||
|
||||
process(I_clk)
|
||||
begin
|
||||
|
@ -89,12 +91,14 @@ begin
|
|||
set_ipc <= '0';
|
||||
O_idata <= X"00000000";
|
||||
set_idata <= '0';
|
||||
instTick <= '0';
|
||||
else
|
||||
if I_int = '0' then
|
||||
interrupt_was_inactive <= '1';
|
||||
end if;
|
||||
case s_state is
|
||||
when "0000001" => -- fetch
|
||||
instTick <= '0';
|
||||
if mem_cycles = 0 and mem_ready = '1' then
|
||||
mem_execute <= '1';
|
||||
mem_cycles <= 1;
|
||||
|
@ -133,7 +137,7 @@ begin
|
|||
-- if it's a write, go through
|
||||
if I_aluop(6 downto 2) = OPCODE_STORE then
|
||||
mem_cycles <= 0;
|
||||
s_state <= "0100001";-- "0100000"; -- WB
|
||||
s_state <= "0100001";-- "0100000"; -- WB ----- *** fixme: Stores skip the int check?
|
||||
elsif mem_dataReady = '1' then
|
||||
-- if read, wait for data
|
||||
mem_cycles <= 0;
|
||||
|
@ -151,8 +155,9 @@ begin
|
|||
else
|
||||
s_state <= "0000001"; --F
|
||||
end if;
|
||||
|
||||
instTick <= '1';
|
||||
when "1000000" => -- stalls
|
||||
instTick <= '0';
|
||||
-- interrupt stall
|
||||
if interrupt_state = "001" then
|
||||
-- give a cycle of latency
|
||||
|
|
116
vhdl/core.vhd
116
vhdl/core.vhd
|
@ -32,7 +32,8 @@ entity core is
|
|||
I_reset : in STD_LOGIC;
|
||||
I_halt : in STD_LOGIC;
|
||||
|
||||
-- unused interrupt interface, relic from TPU implementation
|
||||
-- External Interrupt interface
|
||||
I_int_data: in STD_LOGIC_VECTOR(31 downto 0);
|
||||
I_int: in STD_LOGIC;
|
||||
O_int_ack: out STD_LOGIC;
|
||||
|
||||
|
@ -80,6 +81,7 @@ architecture Behavioral of core is
|
|||
O_set_idata:out STD_LOGIC;
|
||||
O_set_ipc: out STD_LOGIC;
|
||||
O_set_irpc: out STD_LOGIC;
|
||||
O_instTick: out STD_LOGIC;
|
||||
|
||||
I_ready: in STD_LOGIC;
|
||||
O_execute: out STD_LOGIC;
|
||||
|
@ -99,8 +101,11 @@ architecture Behavioral of core is
|
|||
O_dataIMM : OUT std_logic_vector(31 downto 0);
|
||||
O_regDwe : OUT std_logic;
|
||||
O_aluOp : OUT std_logic_vector(6 downto 0);
|
||||
O_aluFunc : OUT std_logic_vector(15 downto 0); -- ALU function
|
||||
O_memOp : out STD_LOGIC_VECTOR(4 downto 0)
|
||||
O_aluFunc : OUT std_logic_vector(15 downto 0);
|
||||
O_memOp : out STD_LOGIC_VECTOR(4 downto 0);
|
||||
|
||||
O_csrOP : out STD_LOGIC_VECTOR(4 downto 0);
|
||||
O_csrAddr : out STD_LOGIC_VECTOR(11 downto 0)
|
||||
);
|
||||
END COMPONENT;
|
||||
|
||||
|
@ -137,7 +142,26 @@ architecture Behavioral of core is
|
|||
);
|
||||
END COMPONENT;
|
||||
|
||||
|
||||
COMPONENT csr_unit
|
||||
PORT (
|
||||
I_clk : in STD_LOGIC;
|
||||
I_en : in STD_LOGIC;
|
||||
|
||||
I_dataIn : in STD_LOGIC_VECTOR(XLENM1 downto 0);
|
||||
O_dataOut : out STD_LOGIC_VECTOR(XLENM1 downto 0);
|
||||
|
||||
I_csrOp : in STD_LOGIC_VECTOR (4 downto 0);
|
||||
I_csrAddr : in STD_LOGIC_VECTOR (11 downto 0);
|
||||
|
||||
-- This unit can raise exceptions
|
||||
O_int : out STD_LOGIC;
|
||||
O_int_data : out STD_LOGIC_VECTOR (31 downto 0);
|
||||
|
||||
I_instRetTick : in STD_LOGIC;
|
||||
O_csr_status : out STD_LOGIC_VECTOR(XLENM1 downto 0);
|
||||
O_csr_tvec : out STD_LOGIC_VECTOR(XLENM1 downto 0)
|
||||
);
|
||||
END COMPONENT;
|
||||
|
||||
COMPONENT mem_controller
|
||||
PORT(
|
||||
|
@ -198,6 +222,7 @@ architecture Behavioral of core is
|
|||
signal en_fetch : std_logic := '0';
|
||||
signal en_decode : std_logic := '0';
|
||||
signal en_alu : std_logic := '0';
|
||||
signal en_csru : std_logic := '0';
|
||||
signal en_memory : std_logic := '0';
|
||||
signal en_regwrite : std_logic := '0';
|
||||
signal en_stall : std_logic := '0';
|
||||
|
@ -222,6 +247,21 @@ architecture Behavioral of core is
|
|||
signal int_enabled: std_logic;
|
||||
signal int_set_irpc: STD_LOGIC;
|
||||
|
||||
signal csru_int: STD_LOGIC;
|
||||
signal csru_int_data: STD_LOGIC_VECTOR(XLENM1 downto 0);
|
||||
|
||||
signal csru_dataIn : STD_LOGIC_VECTOR(XLENM1 downto 0);
|
||||
signal csru_dataOut : STD_LOGIC_VECTOR(XLENM1 downto 0);
|
||||
|
||||
signal csru_csrOp : STD_LOGIC_VECTOR (4 downto 0);
|
||||
signal csru_csrAddr : STD_LOGIC_VECTOR (11 downto 0);
|
||||
|
||||
signal csru_instRetTick : STD_LOGIC;
|
||||
|
||||
-- Some CSRs are needed in various places easily, so they are distributed
|
||||
signal csr_status : STD_LOGIC_VECTOR(XLENM1 downto 0);
|
||||
signal csr_tvec : STD_LOGIC_VECTOR(XLENM1 downto 0);
|
||||
|
||||
signal core_clock:STD_LOGIC := '0';
|
||||
|
||||
begin
|
||||
|
@ -258,28 +298,26 @@ begin
|
|||
O_PC => PC
|
||||
);
|
||||
|
||||
control: control_unit PORT MAP (
|
||||
I_clk => core_clock,
|
||||
I_reset => I_reset,
|
||||
I_aluop => aluop,
|
||||
|
||||
I_int => I_int,
|
||||
O_int_ack => O_int_ack,
|
||||
|
||||
I_int_enabled => int_enabled,
|
||||
I_int_mem_data=>MEM_I_data,
|
||||
O_idata=> int_idata,
|
||||
O_set_idata=> int_set_idata,
|
||||
O_set_ipc=> PCintVec,
|
||||
O_set_irpc => int_set_irpc,
|
||||
I_ready => memctl_ready,
|
||||
O_execute => memctl_execute,
|
||||
I_dataReady => memctl_dataReady,
|
||||
|
||||
O_state => state
|
||||
);
|
||||
control: control_unit PORT MAP (
|
||||
I_clk => core_clock,
|
||||
I_reset => I_reset,
|
||||
I_aluop => aluop,
|
||||
|
||||
I_int => I_int,
|
||||
O_int_ack => O_int_ack,
|
||||
I_int_enabled => int_enabled,
|
||||
I_int_mem_data=>MEM_I_data,
|
||||
O_idata=> int_idata,
|
||||
O_set_idata=> int_set_idata,
|
||||
O_set_ipc=> PCintVec,
|
||||
O_set_irpc => int_set_irpc,
|
||||
O_instTick => csru_instRetTick,
|
||||
I_ready => memctl_ready,
|
||||
O_execute => memctl_execute,
|
||||
I_dataReady => memctl_dataReady,
|
||||
O_state => state
|
||||
);
|
||||
|
||||
|
||||
decoder: decoder_RV32 PORT MAP (
|
||||
I_clk => core_clock,
|
||||
I_en => en_decode,
|
||||
|
@ -291,7 +329,9 @@ begin
|
|||
O_regDwe => dataDwe,
|
||||
O_aluOp => aluOp,
|
||||
O_aluFunc => aluFunc,
|
||||
O_memOp => memOp
|
||||
O_memOp => memOp,
|
||||
O_csrOp => csru_csrOp,
|
||||
O_csrAddr => csru_csrAddr
|
||||
);
|
||||
|
||||
alu: alu_RV32I PORT MAP (
|
||||
|
@ -321,6 +361,27 @@ begin
|
|||
I_selD => selD,
|
||||
I_we => reg_we
|
||||
);
|
||||
|
||||
csru: csr_unit PORT MAP (
|
||||
|
||||
I_clk => core_clock,
|
||||
I_en => en_csru,
|
||||
|
||||
I_dataIn => csru_dataIn,
|
||||
O_dataOut => csru_dataOut,
|
||||
|
||||
I_csrOp => csru_csrOp,
|
||||
I_csrAddr => csru_csrAddr,
|
||||
|
||||
-- This unit can raise exceptions
|
||||
O_int => csru_int,
|
||||
O_int_data => csru_int_data,
|
||||
|
||||
I_instRetTick => csru_instRetTick,
|
||||
O_csr_status => csr_status,
|
||||
O_csr_tvec => csr_tvec
|
||||
);
|
||||
|
||||
|
||||
-- Register file controls
|
||||
reg_en <= en_decode or en_regwrite;
|
||||
|
@ -329,7 +390,8 @@ begin
|
|||
-- These are the pipeline stage enable bits
|
||||
en_fetch <= state(0);
|
||||
en_decode <= state(1);
|
||||
en_alu <= state(3);
|
||||
en_alu <= '0' when aluop = OPCODE_SYSTEM else state(3);
|
||||
en_csru <= state(3) when aluop = OPCODE_SYSTEM else '0';
|
||||
en_memory <= state(4);
|
||||
en_regwrite <= state(5);
|
||||
en_stall <= state(6);
|
||||
|
|
164
vhdl/csr_unit.vhd
Normal file
164
vhdl/csr_unit.vhd
Normal file
|
@ -0,0 +1,164 @@
|
|||
----------------------------------------------------------------------------------
|
||||
-- Project Name: RISC-V CPU
|
||||
-- Description: CSR unit RV32I
|
||||
--
|
||||
----------------------------------------------------------------------------------
|
||||
-- Copyright 2016 Colin Riley
|
||||
--
|
||||
-- Licensed under the Apache License, Version 2.0 (the "License");
|
||||
-- you may not use this file except in compliance with the License.
|
||||
-- You may obtain a copy of the License at
|
||||
--
|
||||
-- http://www.apache.org/licenses/LICENSE-2.0
|
||||
--
|
||||
-- Unless required by applicable law or agreed to in writing, software
|
||||
-- distributed under the License is distributed on an "AS IS" BASIS,
|
||||
-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
-- See the License for the specific language governing permissions and
|
||||
-- limitations under the License.
|
||||
----------------------------------------------------------------------------------
|
||||
library IEEE;
|
||||
use IEEE.STD_LOGIC_1164.ALL;
|
||||
use IEEE.NUMERIC_STD.ALL;
|
||||
|
||||
library work;
|
||||
use work.constants.all;
|
||||
|
||||
entity csr_unit is
|
||||
Port ( I_clk : in STD_LOGIC;
|
||||
I_en : in STD_LOGIC;
|
||||
I_dataIn : in STD_LOGIC_VECTOR (XLENM1 downto 0);
|
||||
O_dataOut : out STD_LOGIC_VECTOR (XLENM1 downto 0);
|
||||
I_csrOp : in STD_LOGIC_VECTOR (4 downto 0);
|
||||
I_csrAddr : in STD_LOGIC_VECTOR (11 downto 0);
|
||||
O_int : out STD_LOGIC;
|
||||
O_int_data : out STD_LOGIC_VECTOR (31 downto 0);
|
||||
I_instRetTick : in STD_LOGIC;
|
||||
O_csr_status : out STD_LOGIC_VECTOR (XLENM1 downto 0);
|
||||
O_csr_tvec : out STD_LOGIC_VECTOR (XLENM1 downto 0)
|
||||
);
|
||||
end csr_unit;
|
||||
|
||||
architecture Behavioral of csr_unit is
|
||||
|
||||
constant CSR_ADDR_USTATUS: STD_LOGIC_VECTOR (11 downto 0) := X"000";
|
||||
constant CSR_ADDR_UIE: STD_LOGIC_VECTOR (11 downto 0) := X"004";
|
||||
constant CSR_ADDR_UTVEC: STD_LOGIC_VECTOR (11 downto 0) := X"005";
|
||||
|
||||
constant CSR_ADDR_USCRATCH: STD_LOGIC_VECTOR (11 downto 0) := X"040";
|
||||
constant CSR_ADDR_UEPC: STD_LOGIC_VECTOR (11 downto 0) := X"041";
|
||||
constant CSR_ADDR_UCAUSE: STD_LOGIC_VECTOR (11 downto 0) := X"042";
|
||||
constant CSR_ADDR_UTVAL: STD_LOGIC_VECTOR (11 downto 0) := X"043";
|
||||
constant CSR_ADDR_UIP: STD_LOGIC_VECTOR (11 downto 0) := X"044";
|
||||
|
||||
constant CSR_ADDR_CYCLE: STD_LOGIC_VECTOR (11 downto 0) := X"C00";
|
||||
constant CSR_ADDR_TIME: STD_LOGIC_VECTOR (11 downto 0) := X"C01";
|
||||
constant CSR_ADDR_INSTRET: STD_LOGIC_VECTOR (11 downto 0) := X"C02";
|
||||
|
||||
constant CSR_ADDR_CYCLEH: STD_LOGIC_VECTOR (11 downto 0) := X"C80";
|
||||
constant CSR_ADDR_TIMEH: STD_LOGIC_VECTOR (11 downto 0) := X"C81";
|
||||
constant CSR_ADDR_INSTRETH: STD_LOGIC_VECTOR (11 downto 0) := X"C82";
|
||||
|
||||
constant CSR_ADDR_MSTATUS: STD_LOGIC_VECTOR (11 downto 0) := X"300";
|
||||
constant CSR_ADDR_MISA: STD_LOGIC_VECTOR (11 downto 0) := X"301";
|
||||
constant CSR_ADDR_MEDELEG: STD_LOGIC_VECTOR (11 downto 0) := X"302";
|
||||
constant CSR_ADDR_MIDELEG: STD_LOGIC_VECTOR (11 downto 0) := X"303";
|
||||
constant CSR_ADDR_MIE: STD_LOGIC_VECTOR (11 downto 0) := X"304";
|
||||
constant CSR_ADDR_MTVEC: STD_LOGIC_VECTOR (11 downto 0) := X"305";
|
||||
constant CSR_ADDR_MCOUNTEREN: STD_LOGIC_VECTOR (11 downto 0) := X"306";
|
||||
|
||||
constant CSR_ADDR_MSCRATCH: STD_LOGIC_VECTOR (11 downto 0) := X"340";
|
||||
constant CSR_ADDR_MEPC: STD_LOGIC_VECTOR (11 downto 0) := X"341";
|
||||
constant CSR_ADDR_MCAUSE: STD_LOGIC_VECTOR (11 downto 0) := X"342";
|
||||
constant CSR_ADDR_MTVAL: STD_LOGIC_VECTOR (11 downto 0) := X"343";
|
||||
constant CSR_ADDR_MIP: STD_LOGIC_VECTOR (11 downto 0) := X"344";
|
||||
|
||||
constant CSR_ADDR_MCYCLE: STD_LOGIC_VECTOR (11 downto 0) := X"B00";
|
||||
constant CSR_ADDR_MINSTRET: STD_LOGIC_VECTOR (11 downto 0) := X"B02";
|
||||
|
||||
constant CSR_ADDR_MCYCLEH: STD_LOGIC_VECTOR (11 downto 0) := X"B80";
|
||||
constant CSR_ADDR_MINSTRETH: STD_LOGIC_VECTOR (11 downto 0) := X"B82";
|
||||
|
||||
constant CSR_ADDR_MVENDORID: STD_LOGIC_VECTOR (11 downto 0) := X"F11";
|
||||
constant CSR_ADDR_MARCHID: STD_LOGIC_VECTOR (11 downto 0) := X"F12";
|
||||
constant CSR_ADDR_MIMPID: STD_LOGIC_VECTOR (11 downto 0) := X"F13";
|
||||
constant CSR_ADDR_MHARDID: STD_LOGIC_VECTOR (11 downto 0) := X"F14";
|
||||
|
||||
signal csr_cycles: STD_LOGIC_VECTOR(63 downto 0) := (others => '0');
|
||||
signal csr_instret: STD_LOGIC_VECTOR(63 downto 0) := (others => '0');
|
||||
|
||||
|
||||
signal csr_status : STD_LOGIC_VECTOR (XLENM1 downto 0) := (others => '0');
|
||||
signal csr_tvec : STD_LOGIC_VECTOR (XLENM1 downto 0) := (others => '0');
|
||||
|
||||
begin
|
||||
|
||||
O_csr_status <= csr_status;
|
||||
O_csr_tvec <= csr_tvec;
|
||||
|
||||
cycles: process (I_clk)
|
||||
begin
|
||||
if rising_edge(I_clk) then
|
||||
csr_cycles <= std_logic_vector(unsigned(csr_cycles) + 1);
|
||||
end if;
|
||||
end process;
|
||||
|
||||
instret: process (I_clk)
|
||||
begin
|
||||
if rising_edge(I_clk) and I_instRetTick='1' then
|
||||
csr_instret <= std_logic_vector(unsigned(csr_instret) + 1);
|
||||
end if;
|
||||
end process;
|
||||
|
||||
protection: process (I_clk, I_en)
|
||||
begin
|
||||
if rising_edge(I_clk) and I_en = '1' then
|
||||
if (I_csrAddr(CSR_ADDR_ACCESS_BIT_START downto CSR_ADDR_ACCESS_BIT_END) = CSR_ADDR_ACCESS_READONLY) and
|
||||
(I_csrOp(CSR_OP_BITS_WRITTEN) = '1') then
|
||||
--todo: raise exception
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
datamain: process (I_clk, I_en)
|
||||
begin
|
||||
if rising_edge(I_clk) and I_en = '1' then
|
||||
case I_csrAddr is
|
||||
when CSR_ADDR_MVENDORID =>
|
||||
O_dataOut <= X"00000000"; -- JEDEC non-commercial
|
||||
when CSR_ADDR_MARCHID =>
|
||||
O_dataOut <= X"00000000";
|
||||
when CSR_ADDR_MIMPID =>
|
||||
O_dataOut <= X"52505530"; -- "RPU0"
|
||||
when CSR_ADDR_MHARDID =>
|
||||
O_dataOut <= X"00000000";
|
||||
|
||||
when CSR_ADDR_MISA =>
|
||||
O_dataOut <= X"40000080"; -- XLEN 32, RV32I
|
||||
|
||||
|
||||
when CSR_ADDR_CYCLE =>
|
||||
O_dataOut <= csr_cycles(31 downto 0);
|
||||
when CSR_ADDR_CYCLEH =>
|
||||
O_dataOut <= csr_cycles(63 downto 32);
|
||||
|
||||
when CSR_ADDR_INSTRET =>
|
||||
O_dataOut <= csr_cycles(31 downto 0);
|
||||
when CSR_ADDR_INSTRETH =>
|
||||
O_dataOut <= csr_cycles(63 downto 32);
|
||||
|
||||
when CSR_ADDR_MCYCLE =>
|
||||
O_dataOut <= csr_cycles(31 downto 0);
|
||||
when CSR_ADDR_MCYCLEH =>
|
||||
O_dataOut <= csr_cycles(63 downto 32);
|
||||
|
||||
when CSR_ADDR_MINSTRET =>
|
||||
O_dataOut <= csr_cycles(31 downto 0);
|
||||
when CSR_ADDR_MINSTRETH =>
|
||||
O_dataOut <= csr_cycles(63 downto 32);
|
||||
when others =>
|
||||
end case;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
end Behavioral;
|
|
@ -36,7 +36,9 @@ entity decoder_RV32 is
|
|||
O_regDwe : out STD_LOGIC; -- RegD wrtite enable
|
||||
O_aluOp : out STD_LOGIC_VECTOR (6 downto 0); -- ALU opcode
|
||||
O_aluFunc : out STD_LOGIC_VECTOR (15 downto 0); -- ALU function
|
||||
O_memOp : out STD_LOGIC_VECTOR(4 downto 0) -- Memory operation
|
||||
O_memOp : out STD_LOGIC_VECTOR(4 downto 0); -- Memory operation
|
||||
O_csrOP : out STD_LOGIC_VECTOR(4 downto 0); -- CSR operations
|
||||
O_csrAddr : out STD_LOGIC_VECTOR(11 downto 0) -- CSR address
|
||||
);
|
||||
end decoder_RV32;
|
||||
|
||||
|
@ -50,12 +52,12 @@ begin
|
|||
begin
|
||||
if rising_edge(I_clk) and I_en = '1' then
|
||||
|
||||
O_selD <= I_dataInst(RD_START downto RD_END);
|
||||
|
||||
O_aluOp <= I_dataInst(OPCODE_START downto OPCODE_END);
|
||||
O_selD <= I_dataInst(RD_START downto RD_END);
|
||||
|
||||
O_aluFunc <= "000000" & I_dataInst(FUNCT7_START downto FUNCT7_END)
|
||||
& I_dataInst(FUNCT3_START downto FUNCT3_END);
|
||||
O_aluOp <= I_dataInst(OPCODE_START downto OPCODE_END);
|
||||
|
||||
O_aluFunc <= "000000" & I_dataInst(FUNCT7_START downto FUNCT7_END)
|
||||
& I_dataInst(FUNCT3_START downto FUNCT3_END);
|
||||
|
||||
case I_dataInst(OPCODE_START downto OPCODE_END_2) is
|
||||
when OPCODE_LUI =>
|
||||
|
@ -124,15 +126,65 @@ begin
|
|||
else
|
||||
O_dataIMM <= X"0000" & "0000" & I_dataInst(7) & I_dataInst(30 downto 25) & I_dataInst(11 downto 8) & '0';
|
||||
end if;
|
||||
when OPCODE_MISCMEM =>
|
||||
when OPCODE_MISCMEM =>
|
||||
O_regDwe <= '0';
|
||||
O_memOp <= "01000";
|
||||
O_dataIMM <= I_dataInst;
|
||||
when others =>
|
||||
O_memOp <= "00000";
|
||||
O_regDwe <= '1';
|
||||
O_dataIMM <= I_dataInst(IMM_I_START downto IMM_S_B_END)
|
||||
& "0000000";
|
||||
when OPCODE_SYSTEM =>
|
||||
O_memOp <= "00000";
|
||||
if I_dataInst(FUNCT3_START downto FUNCT3_END) = "000" then
|
||||
-- ECALL or EBREAK
|
||||
|
||||
else
|
||||
-- CSR
|
||||
-- The immediate output is the zero-extended R1 value for Imm-form CSR ops
|
||||
O_dataIMM <= X"000000" & "000" & I_dataInst(R1_START downto R1_END);
|
||||
|
||||
-- The 12bit immediate in the instruction forms the csr address.
|
||||
O_csrAddr <= I_dataInst(IMM_I_START downto IMM_I_END);
|
||||
|
||||
-- is there a destination? if not, CSR is not read
|
||||
if I_dataInst(RD_START downto RD_END) = "00000" then
|
||||
O_csrOP(0) <= '0';
|
||||
else
|
||||
O_csrOP(0) <= '1';
|
||||
end if;
|
||||
|
||||
-- is there source data? if not, CSR value is not written
|
||||
if I_dataInst(R1_START downto R1_END) = "00000" then
|
||||
O_csrOP(1) <= '0';
|
||||
else
|
||||
O_csrOP(1) <= '1';
|
||||
end if;
|
||||
|
||||
O_csrOp(4 downto 2) <= I_dataInst(FUNCT3_START downto FUNCT3_END);
|
||||
|
||||
-- -- operation
|
||||
-- case '0' & I_dataInst((FUNCT3_START+1) downto FUNCT3_END) is
|
||||
-- when F3_SYSTEM_CSRRW =>
|
||||
-- O_csrOP(3 downto 2) <= "00";
|
||||
--
|
||||
-- when F3_SYSTEM_CSRRS =>
|
||||
-- O_csrOP(3 downto 2) <= "10";
|
||||
--
|
||||
-- when F3_SYSTEM_CSRRC=>
|
||||
-- O_csrOP(3 downto 2) <= "11";
|
||||
--
|
||||
-- when others =>
|
||||
-- end case;
|
||||
--
|
||||
-- -- immediate or reg source
|
||||
-- if I_dataInst(FUNCT3_START) = '1' then
|
||||
-- O_csrOP(4) <= '1';
|
||||
-- else
|
||||
-- O_csrOP(4) <= '0';
|
||||
-- end if;
|
||||
end if;
|
||||
when others =>
|
||||
O_memOp <= "00000";
|
||||
O_regDwe <= '1';
|
||||
O_dataIMM <= I_dataInst(IMM_I_START downto IMM_S_B_END)
|
||||
& "0000000";
|
||||
end case;
|
||||
end if;
|
||||
end process;
|
||||
|
|
Loading…
Add table
Reference in a new issue