mirror of
https://github.com/Domipheus/RPU.git
synced 2025-04-18 19:15:13 -04:00
CSR Unit implemented with all CSR operational modify operations (write, set, clear). Not all CSRs are supported as yet, but cycles, instret and some of the machine identifiers are. Also two R/W locations at 0x400 and 0x401 for testing.
This commit is contained in:
parent
cc388e3a90
commit
25411fd194
4 changed files with 114 additions and 66 deletions
|
@ -228,12 +228,16 @@ constant CSR_ADDR_ACCESS_READONLY: std_logic_vector(1 downto 0):= "11";
|
|||
-- 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_READ: integer := 0;
|
||||
constant CSR_OP_BITS_WRITTEN: 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_MAINOP_WR: std_logic_vector(1 downto 0) := "01";
|
||||
constant CSR_MAINOP_SET: std_logic_vector(1 downto 0) := "10";
|
||||
constant CSR_MAINOP_CLEAR: std_logic_vector(1 downto 0) := "11";
|
||||
|
||||
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";
|
||||
|
|
|
@ -218,6 +218,7 @@ architecture Behavioral of core is
|
|||
signal reg_we: std_logic := '0';
|
||||
|
||||
signal registerWriteData : std_logic_vector(XLENM1 downto 0) := (others=>'0');
|
||||
signal alu_or_csr_output : std_logic_vector(XLENM1 downto 0) := (others=>'0');
|
||||
|
||||
signal en_fetch : std_logic := '0';
|
||||
signal en_decode : std_logic := '0';
|
||||
|
@ -390,8 +391,8 @@ begin
|
|||
-- These are the pipeline stage enable bits
|
||||
en_fetch <= state(0);
|
||||
en_decode <= state(1);
|
||||
en_alu <= '0' when aluop = OPCODE_SYSTEM else state(3);
|
||||
en_csru <= state(3) when aluop = OPCODE_SYSTEM else '0';
|
||||
en_alu <= '0' when aluop(6 downto 2) = OPCODE_SYSTEM else state(3);
|
||||
en_csru <= state(3) when aluop(6 downto 2) = OPCODE_SYSTEM else '0';
|
||||
en_memory <= state(4);
|
||||
en_regwrite <= state(5);
|
||||
en_stall <= state(6);
|
||||
|
@ -405,8 +406,11 @@ begin
|
|||
-- The input PC is just always the branch target output from ALU
|
||||
in_pc <= branchTarget;
|
||||
|
||||
-- input data from the register file, or use immediate if the OP specifies it
|
||||
csru_dataIn <= dataIMM when csru_csrOp(CSR_OP_BITS_IMM) = '1' else dataA;
|
||||
|
||||
-- The debug output just allows some internal state to be visible outside the core black box
|
||||
O_DBG <= "000" & memctl_dataReady & "000" & MEM_I_dataReady & "0" & state & registerWriteData(15 downto 0);
|
||||
--O_DBG <= "000" & memctl_dataReady & "000" & MEM_I_dataReady & X"0000"&"0" & state;-- & registerWriteData(15 downto 0);
|
||||
|
||||
-- Below statements are for memory interface use.
|
||||
memctl_address <= dataResult when en_memory = '1' else PC;
|
||||
|
@ -417,8 +421,8 @@ begin
|
|||
memctl_size <= memOp(1 downto 0);
|
||||
memctl_signExtend <= memOp(2);
|
||||
|
||||
-- This chooses to write registers with memory data or ALU data
|
||||
registerWriteData <= memctl_out_data when memOp(4 downto 3) = "10" else dataResult;
|
||||
-- This chooses to write registers with memory data or ALU/csr data
|
||||
registerWriteData <= memctl_out_data when memOp(4 downto 3) = "10" else csru_dataOut when aluop(6 downto 2) = OPCODE_SYSTEM else dataResult;
|
||||
|
||||
-- The instructions are delivered from memctl
|
||||
instruction <= memctl_out_data;
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
-- Description: CSR unit RV32I
|
||||
--
|
||||
----------------------------------------------------------------------------------
|
||||
-- Copyright 2016 Colin Riley
|
||||
-- Copyright 2018 Colin Riley
|
||||
--
|
||||
-- Licensed under the Apache License, Version 2.0 (the "License");
|
||||
-- you may not use this file except in compliance with the License.
|
||||
|
@ -59,6 +59,10 @@ 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_TEST_400: STD_LOGIC_VECTOR (11 downto 0) := X"400";
|
||||
constant CSR_ADDR_TEST_401: STD_LOGIC_VECTOR (11 downto 0) := X"401";
|
||||
|
||||
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";
|
||||
|
@ -91,10 +95,20 @@ 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');
|
||||
|
||||
signal curr_csr_value: STD_LOGIC_VECTOR(XLENM1 downto 0) := (others=> '0');
|
||||
signal next_csr_value: STD_LOGIC_VECTOR(XLENM1 downto 0) := (others=> '0');
|
||||
|
||||
signal test0_CSR: STD_LOGIC_VECTOR(XLENM1 downto 0) := X"FEFbbEF0";
|
||||
signal test1_CSR: STD_LOGIC_VECTOR(XLENM1 downto 0) := X"FEFbbEF1";
|
||||
|
||||
signal csr_op: STD_LOGIC_VECTOR(4 downto 0) := (others=>'0');
|
||||
signal opState: integer := 0;
|
||||
begin
|
||||
|
||||
O_csr_status <= csr_status;
|
||||
O_csr_tvec <= csr_tvec;
|
||||
|
||||
O_dataOut <= curr_csr_value;
|
||||
|
||||
cycles: process (I_clk)
|
||||
begin
|
||||
|
@ -120,45 +134,89 @@ begin
|
|||
end if;
|
||||
end process;
|
||||
|
||||
-- Read data is available next cycle, with an additional cycle before another op can be processed
|
||||
-- Write to CSR occurs 3 cycles later.
|
||||
-- cycle 1: read of existing csr available
|
||||
-- cycle 2: update value calculates (whole write, set/clear bit read-modify-write)
|
||||
-- cycle 3: actual write to csr occurs.
|
||||
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;
|
||||
if rising_edge(I_clk) then
|
||||
if I_en = '1' and opState = 0 then
|
||||
csr_op <= I_csrOp;
|
||||
case I_csrAddr is
|
||||
when CSR_ADDR_MVENDORID =>
|
||||
curr_csr_value <= X"00000000"; -- JEDEC non-commercial
|
||||
when CSR_ADDR_MARCHID =>
|
||||
curr_csr_value <= X"00000000";
|
||||
when CSR_ADDR_MIMPID =>
|
||||
curr_csr_value <= X"52505530"; -- "RPU0"
|
||||
when CSR_ADDR_MHARDID =>
|
||||
curr_csr_value <= X"00000000";
|
||||
when CSR_ADDR_MISA =>
|
||||
curr_csr_value <= X"40000080"; -- XLEN 32, RV32I
|
||||
|
||||
when CSR_ADDR_CYCLE =>
|
||||
curr_csr_value <= csr_cycles(31 downto 0);
|
||||
when CSR_ADDR_CYCLEH =>
|
||||
curr_csr_value <= csr_cycles(63 downto 32);
|
||||
|
||||
when CSR_ADDR_INSTRET =>
|
||||
curr_csr_value <= csr_instret(31 downto 0);
|
||||
when CSR_ADDR_INSTRETH =>
|
||||
curr_csr_value <= csr_instret(63 downto 32);
|
||||
|
||||
when CSR_ADDR_MCYCLE =>
|
||||
curr_csr_value <= csr_cycles(31 downto 0);
|
||||
when CSR_ADDR_MCYCLEH =>
|
||||
curr_csr_value <= csr_cycles(63 downto 32);
|
||||
|
||||
when CSR_ADDR_MINSTRET =>
|
||||
curr_csr_value <= csr_instret(31 downto 0);
|
||||
when CSR_ADDR_MINSTRETH =>
|
||||
curr_csr_value <= csr_instret(63 downto 32);
|
||||
|
||||
when CSR_ADDR_TEST_400 =>
|
||||
curr_csr_value <= test0_CSR;
|
||||
when CSR_ADDR_TEST_401 =>
|
||||
curr_csr_value <= test1_CSR;
|
||||
|
||||
when others =>
|
||||
-- raise exception for unsupported CSR
|
||||
end case;
|
||||
opState <= 1;
|
||||
|
||||
elsif opState = 1 then
|
||||
-- update stage for sets, clears and writes
|
||||
case csr_op(3 downto 2) is
|
||||
when CSR_MAINOP_WR =>
|
||||
next_csr_value <= I_dataIn;
|
||||
when CSR_MAINOP_SET =>
|
||||
next_csr_value <= curr_csr_value or I_dataIn;
|
||||
when CSR_MAINOP_CLEAR =>
|
||||
next_csr_value <= curr_csr_value and (not I_dataIn);
|
||||
when others =>
|
||||
end case;
|
||||
|
||||
if I_csrOp(CSR_OP_BITS_WRITTEN) = '1' then
|
||||
opState <= 2;
|
||||
else
|
||||
opState <= 0;
|
||||
end if;
|
||||
|
||||
elsif opState = 2 then
|
||||
-- write stage
|
||||
opState <= 0;
|
||||
case I_csrAddr is
|
||||
when CSR_ADDR_TEST_400 =>
|
||||
test0_CSR <= next_csr_value;
|
||||
when CSR_ADDR_TEST_401 =>
|
||||
test1_CSR <= next_csr_value;
|
||||
when others =>
|
||||
end case;
|
||||
end if;
|
||||
end if;
|
||||
|
||||
end process;
|
||||
|
||||
end Behavioral;
|
||||
|
|
|
@ -146,7 +146,9 @@ begin
|
|||
-- is there a destination? if not, CSR is not read
|
||||
if I_dataInst(RD_START downto RD_END) = "00000" then
|
||||
O_csrOP(0) <= '0';
|
||||
O_regDwe <= '0';
|
||||
else
|
||||
O_regDwe <= '1';
|
||||
O_csrOP(0) <= '1';
|
||||
end if;
|
||||
|
||||
|
@ -158,27 +160,7 @@ begin
|
|||
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";
|
||||
|
|
Loading…
Add table
Reference in a new issue