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:
Colin Riley 2018-11-12 00:17:16 +00:00
parent 12f77e85c5
commit cc388e3a90
5 changed files with 420 additions and 43 deletions

View file

@ -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

View file

@ -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

View file

@ -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
View 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;

View file

@ -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;