Line 154... |
Line 154... |
buf : std_ulogic_vector(2+15 downto 0);
|
buf : std_ulogic_vector(2+15 downto 0);
|
buf_nxt : std_ulogic_vector(2+15 downto 0);
|
buf_nxt : std_ulogic_vector(2+15 downto 0);
|
end record;
|
end record;
|
signal issue_engine : issue_engine_t;
|
signal issue_engine : issue_engine_t;
|
|
|
-- instruction buffer ("FIFO" with just one entry) --
|
-- instruction issue interface --
|
type i_buf_t is record
|
type cmd_issue_t is record
|
wdata : std_ulogic_vector(35 downto 0); -- 4-bit status + 32-bit instruction
|
data : std_ulogic_vector(35 downto 0); -- 4-bit status + 32-bit instruction
|
rdata : std_ulogic_vector(35 downto 0); -- 4-bit status + 32-bit instruction
|
valid : std_ulogic; -- data word is valid when set
|
status : std_ulogic;
|
|
clear : std_ulogic;
|
|
we : std_ulogic;
|
|
re : std_ulogic;
|
|
free : std_ulogic;
|
|
avail : std_ulogic;
|
|
end record;
|
end record;
|
signal i_buf : i_buf_t;
|
signal cmd_issue : cmd_issue_t;
|
|
|
-- instruction execution engine --
|
-- instruction execution engine --
|
type execute_engine_state_t is (SYS_WAIT, DISPATCH, TRAP, EXECUTE, ALU_WAIT, BRANCH, LOADSTORE_0, LOADSTORE_1, LOADSTORE_2, CSR_ACCESS);
|
type execute_engine_state_t is (SYS_WAIT, DISPATCH, TRAP, EXECUTE, ALU_WAIT, BRANCH, LOADSTORE_0, LOADSTORE_1, LOADSTORE_2, CSR_ACCESS);
|
type execute_engine_t is record
|
type execute_engine_t is record
|
state : execute_engine_state_t;
|
state : execute_engine_state_t;
|
Line 195... |
Line 189... |
if_rst : std_ulogic; -- instruction fetch was reset
|
if_rst : std_ulogic; -- instruction fetch was reset
|
if_rst_nxt : std_ulogic; -- instruction fetch was reset
|
if_rst_nxt : std_ulogic; -- instruction fetch was reset
|
end record;
|
end record;
|
signal execute_engine : execute_engine_t;
|
signal execute_engine : execute_engine_t;
|
|
|
signal next_pc_tmp : std_ulogic_vector(data_width_c-1 downto 0);
|
|
|
|
-- trap controller --
|
-- trap controller --
|
type trap_ctrl_t is record
|
type trap_ctrl_t is record
|
exc_buf : std_ulogic_vector(exception_width_c-1 downto 0);
|
exc_buf : std_ulogic_vector(exception_width_c-1 downto 0);
|
exc_fire : std_ulogic; -- set if there is a valid source in the exception buffer
|
exc_fire : std_ulogic; -- set if there is a valid source in the exception buffer
|
irq_buf : std_ulogic_vector(interrupt_width_c-1 downto 0);
|
irq_buf : std_ulogic_vector(interrupt_width_c-1 downto 0);
|
Line 367... |
Line 359... |
if (ipb.clear = '1') then
|
if (ipb.clear = '1') then
|
ipb.w_pnt <= (others => '0');
|
ipb.w_pnt <= (others => '0');
|
elsif (ipb.we = '1') then
|
elsif (ipb.we = '1') then
|
ipb.w_pnt <= std_ulogic_vector(unsigned(ipb.w_pnt) + 1);
|
ipb.w_pnt <= std_ulogic_vector(unsigned(ipb.w_pnt) + 1);
|
end if;
|
end if;
|
if (ipb.we = '1') then -- write port
|
if (ipb.we = '1') then -- write data
|
ipb.data(to_integer(unsigned(ipb.w_pnt(ipb.w_pnt'left-1 downto 0)))) <= ipb.wdata;
|
ipb.data(to_integer(unsigned(ipb.w_pnt(ipb.w_pnt'left-1 downto 0)))) <= ipb.wdata;
|
end if;
|
end if;
|
-- read port --
|
-- read port --
|
if (ipb.clear = '1') then
|
if (ipb.clear = '1') then
|
ipb.r_pnt <= (others => '0');
|
ipb.r_pnt <= (others => '0');
|
Line 428... |
Line 420... |
end process issue_engine_fsm_sync;
|
end process issue_engine_fsm_sync;
|
|
|
|
|
-- Issue Engine FSM Comb ------------------------------------------------------------------
|
-- Issue Engine FSM Comb ------------------------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
issue_engine_fsm_comb: process(issue_engine, ipb, i_buf, execute_engine, ci_illegal, ci_instr32)
|
issue_engine_fsm_comb: process(issue_engine, ipb, execute_engine, ci_illegal, ci_instr32)
|
begin
|
begin
|
-- arbiter defaults --
|
-- arbiter defaults --
|
issue_engine.state_nxt <= issue_engine.state;
|
issue_engine.state_nxt <= issue_engine.state;
|
issue_engine.align_nxt <= issue_engine.align;
|
issue_engine.align_nxt <= issue_engine.align;
|
issue_engine.buf_nxt <= issue_engine.buf;
|
issue_engine.buf_nxt <= issue_engine.buf;
|
|
|
-- instruction prefetch buffer interface defaults --
|
-- instruction prefetch buffer interface defaults --
|
ipb.re <= '0';
|
ipb.re <= '0';
|
|
|
-- instruction buffer interface defaults --
|
-- instruction issue interface defaults --
|
i_buf.we <= '0';
|
-- cmd_issue.data = <illegal_compressed_instruction> & <bus_error & alignment_error> & <is_compressed_instrucion> & <32-bit_instruction_word>
|
-- i_buf = <illegal_compressed_instruction> & <bus_error & alignment_error> & <is_compressed_instrucion> & <32-bit_instruction_word>
|
cmd_issue.data <= '0' & ipb.rdata(33 downto 32) & '0' & ipb.rdata(31 downto 0);
|
i_buf.wdata <= '0' & ipb.rdata(33 downto 32) & '0' & ipb.rdata(31 downto 0);
|
cmd_issue.valid <= '0';
|
|
|
-- state machine --
|
-- state machine --
|
case issue_engine.state is
|
case issue_engine.state is
|
|
|
when ISSUE_ACTIVE => -- issue instruction if available
|
when ISSUE_ACTIVE => -- issue instruction if available
|
-- ------------------------------------------------------------
|
-- ------------------------------------------------------------
|
if (ipb.avail = '1') then -- instructions available?
|
if (ipb.avail = '1') then -- instructions available?
|
|
|
if (issue_engine.align = '0') or (CPU_EXTENSION_RISCV_C = false) then -- begin check in LOW instruction half-word
|
if (issue_engine.align = '0') or (CPU_EXTENSION_RISCV_C = false) then -- begin check in LOW instruction half-word
|
if (i_buf.free = '1') then
|
if (execute_engine.state = DISPATCH) then
|
i_buf.we <= '1';
|
cmd_issue.valid <= '1';
|
issue_engine.buf_nxt <= ipb.rdata(33 downto 32) & ipb.rdata(31 downto 16); -- store high half-word - we might need it for an unaligned uncompressed instruction
|
issue_engine.buf_nxt <= ipb.rdata(33 downto 32) & ipb.rdata(31 downto 16); -- store high half-word - we might need it for an unaligned uncompressed instruction
|
if (ipb.rdata(1 downto 0) = "11") or (CPU_EXTENSION_RISCV_C = false) then -- uncompressed and "aligned"
|
if (ipb.rdata(1 downto 0) = "11") or (CPU_EXTENSION_RISCV_C = false) then -- uncompressed and "aligned"
|
ipb.re <= '1';
|
ipb.re <= '1';
|
i_buf.wdata <= '0' & ipb.rdata(33 downto 32) & '0' & ipb.rdata(31 downto 0);
|
cmd_issue.data <= '0' & ipb.rdata(33 downto 32) & '0' & ipb.rdata(31 downto 0);
|
else -- compressed
|
else -- compressed
|
ipb.re <= '1';
|
ipb.re <= '1';
|
i_buf.wdata <= ci_illegal & ipb.rdata(33 downto 32) & '1' & ci_instr32;
|
cmd_issue.data <= ci_illegal & ipb.rdata(33 downto 32) & '1' & ci_instr32;
|
issue_engine.align_nxt <= '1';
|
issue_engine.align_nxt <= '1';
|
end if;
|
end if;
|
end if;
|
end if;
|
|
|
else -- begin check in HIGH instruction half-word
|
else -- begin check in HIGH instruction half-word
|
if (i_buf.free = '1') then
|
if (execute_engine.state = DISPATCH) then
|
i_buf.we <= '1';
|
cmd_issue.valid <= '1';
|
issue_engine.buf_nxt <= ipb.rdata(33 downto 32) & ipb.rdata(31 downto 16); -- store high half-word - we might need it for an unaligned uncompressed instruction
|
issue_engine.buf_nxt <= ipb.rdata(33 downto 32) & ipb.rdata(31 downto 16); -- store high half-word - we might need it for an unaligned uncompressed instruction
|
if (issue_engine.buf(1 downto 0) = "11") then -- uncompressed and "unaligned"
|
if (issue_engine.buf(1 downto 0) = "11") then -- uncompressed and "unaligned"
|
ipb.re <= '1';
|
ipb.re <= '1';
|
i_buf.wdata <= '0' & issue_engine.buf(17 downto 16) & '0' & (ipb.rdata(15 downto 0) & issue_engine.buf(15 downto 0));
|
cmd_issue.data <= '0' & issue_engine.buf(17 downto 16) & '0' & (ipb.rdata(15 downto 0) & issue_engine.buf(15 downto 0));
|
else -- compressed
|
else -- compressed
|
-- do not read from ipb here!
|
-- do not read from ipb here!
|
i_buf.wdata <= ci_illegal & ipb.rdata(33 downto 32) & '1' & ci_instr32;
|
cmd_issue.data <= ci_illegal & ipb.rdata(33 downto 32) & '1' & ci_instr32;
|
issue_engine.align_nxt <= '0';
|
issue_engine.align_nxt <= '0';
|
end if;
|
end if;
|
end if;
|
end if;
|
end if;
|
end if;
|
end if;
|
end if;
|
Line 520... |
Line 512... |
ci_instr32 <= (others => '0');
|
ci_instr32 <= (others => '0');
|
ci_illegal <= '0';
|
ci_illegal <= '0';
|
end generate;
|
end generate;
|
|
|
|
|
-- Instruction Buffer ---------------------------------------------------------------------
|
|
-- -------------------------------------------------------------------------------------------
|
|
instruction_buffer: process(clk_i)
|
|
begin
|
|
if rising_edge(clk_i) then
|
|
if (i_buf.clear = '1') then
|
|
i_buf.status <= '0';
|
|
elsif (i_buf.we = '1') then
|
|
i_buf.status <= '1';
|
|
elsif (i_buf.re = '1') then
|
|
i_buf.status <= '0';
|
|
end if;
|
|
if (i_buf.we = '1') then
|
|
i_buf.rdata <= i_buf.wdata;
|
|
end if;
|
|
end if;
|
|
end process instruction_buffer;
|
|
|
|
-- status --
|
|
i_buf.free <= not i_buf.status;
|
|
i_buf.avail <= i_buf.status;
|
|
|
|
-- clear i_buf when clearing ipb --
|
|
i_buf.clear <= ipb.clear;
|
|
|
|
|
|
-- ****************************************************************************************************************************
|
-- ****************************************************************************************************************************
|
-- Instruction Execution
|
-- Instruction Execution
|
-- ****************************************************************************************************************************
|
-- ****************************************************************************************************************************
|
|
|
|
|
-- Immediate Generator --------------------------------------------------------------------
|
-- Immediate Generator --------------------------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
imm_gen: process(clk_i)
|
imm_gen: process(clk_i)
|
|
variable opcode_v : std_ulogic_vector(6 downto 0);
|
begin
|
begin
|
if rising_edge(clk_i) then
|
if rising_edge(clk_i) then
|
case execute_engine.i_reg(instr_opcode_msb_c downto instr_opcode_lsb_c) is
|
opcode_v := execute_engine.i_reg(instr_opcode_msb_c downto instr_opcode_lsb_c+2) & "11";
|
|
case opcode_v is -- save some bits here, LSBs are always 11 for rv32
|
when opcode_store_c => -- S-immediate
|
when opcode_store_c => -- S-immediate
|
imm_o(31 downto 11) <= (others => execute_engine.i_reg(31)); -- sign extension
|
imm_o(31 downto 11) <= (others => execute_engine.i_reg(31)); -- sign extension
|
imm_o(10 downto 05) <= execute_engine.i_reg(30 downto 25);
|
imm_o(10 downto 05) <= execute_engine.i_reg(30 downto 25);
|
imm_o(04 downto 01) <= execute_engine.i_reg(11 downto 08);
|
imm_o(04 downto 01) <= execute_engine.i_reg(11 downto 08);
|
imm_o(00) <= execute_engine.i_reg(07);
|
imm_o(00) <= execute_engine.i_reg(07);
|
Line 642... |
Line 610... |
execute_engine.is_cp_op <= execute_engine.is_cp_op_nxt;
|
execute_engine.is_cp_op <= execute_engine.is_cp_op_nxt;
|
--
|
--
|
if (execute_engine.state = EXECUTE) then
|
if (execute_engine.state = EXECUTE) then
|
execute_engine.i_reg_last <= execute_engine.i_reg;
|
execute_engine.i_reg_last <= execute_engine.i_reg;
|
end if;
|
end if;
|
|
-- next PC --
|
|
if (execute_engine.is_ci = '1') then -- compressed instruction?
|
|
execute_engine.next_pc <= std_ulogic_vector(unsigned(execute_engine.pc) + 2);
|
|
else
|
|
execute_engine.next_pc <= std_ulogic_vector(unsigned(execute_engine.pc) + 4);
|
|
end if;
|
--
|
--
|
ctrl <= ctrl_nxt;
|
ctrl <= ctrl_nxt;
|
end if;
|
end if;
|
end process execute_engine_fsm_sync;
|
end process execute_engine_fsm_sync;
|
|
|
-- next PC --
|
|
next_pc_tmp <= std_ulogic_vector(unsigned(execute_engine.pc) + 2) when (execute_engine.is_ci = '1') else std_ulogic_vector(unsigned(execute_engine.pc) + 4);
|
|
execute_engine.next_pc <= next_pc_tmp(data_width_c-1 downto 1) & '0';
|
|
|
|
-- PC output --
|
-- PC output --
|
curr_pc_o <= execute_engine.pc(data_width_c-1 downto 1) & '0';
|
curr_pc_o <= execute_engine.pc(data_width_c-1 downto 1) & '0';
|
next_pc_o <= next_pc_tmp(data_width_c-1 downto 1) & '0';
|
next_pc_o <= execute_engine.next_pc(data_width_c-1 downto 1) & '0';
|
|
|
|
|
-- CPU Control Bus Output -----------------------------------------------------------------
|
-- CPU Control Bus Output -----------------------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
ctrl_output: process(ctrl, fetch_engine, trap_ctrl, bus_fast_ir, execute_engine, csr.privilege)
|
ctrl_output: process(ctrl, fetch_engine, trap_ctrl, bus_fast_ir, execute_engine, csr.privilege)
|
Line 681... |
Line 651... |
end process ctrl_output;
|
end process ctrl_output;
|
|
|
|
|
-- Execute Engine FSM Comb ----------------------------------------------------------------
|
-- Execute Engine FSM Comb ----------------------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
execute_engine_fsm_comb: process(execute_engine, fetch_engine, i_buf, trap_ctrl, csr, ctrl, csr_acc_valid,
|
execute_engine_fsm_comb: process(execute_engine, fetch_engine, cmd_issue, trap_ctrl, csr, ctrl, csr_acc_valid,
|
alu_add_i, alu_wait_i, bus_d_wait_i, ma_load_i, be_load_i, ma_store_i, be_store_i)
|
alu_add_i, alu_wait_i, bus_d_wait_i, ma_load_i, be_load_i, ma_store_i, be_store_i)
|
variable alu_immediate_v : std_ulogic;
|
variable alu_immediate_v : std_ulogic;
|
variable rs1_is_r0_v : std_ulogic;
|
variable rs1_is_r0_v : std_ulogic;
|
variable opcode_v : std_ulogic_vector(6 downto 0);
|
variable opcode_v : std_ulogic_vector(6 downto 0);
|
begin
|
begin
|
Line 700... |
Line 670... |
execute_engine.sleep_nxt <= execute_engine.sleep;
|
execute_engine.sleep_nxt <= execute_engine.sleep;
|
execute_engine.if_rst_nxt <= execute_engine.if_rst;
|
execute_engine.if_rst_nxt <= execute_engine.if_rst;
|
|
|
-- instruction dispatch --
|
-- instruction dispatch --
|
fetch_engine.reset <= '0';
|
fetch_engine.reset <= '0';
|
i_buf.re <= '0';
|
|
|
|
-- trap environment control --
|
-- trap environment control --
|
trap_ctrl.env_start_ack <= '0';
|
trap_ctrl.env_start_ack <= '0';
|
trap_ctrl.env_end <= '0';
|
trap_ctrl.env_end <= '0';
|
|
|
Line 745... |
Line 714... |
|
|
when SYS_WAIT => -- System delay cycle (used to wait for side effects to kick in) ((and to init r0 with zero if it is a physical register))
|
when SYS_WAIT => -- System delay cycle (used to wait for side effects to kick in) ((and to init r0 with zero if it is a physical register))
|
-- ------------------------------------------------------------
|
-- ------------------------------------------------------------
|
-- set reg_file's r0 to zero --
|
-- set reg_file's r0 to zero --
|
if (rf_r0_is_reg_c = true) then -- is r0 implemented as physical register, which has to be set to zero?
|
if (rf_r0_is_reg_c = true) then -- is r0 implemented as physical register, which has to be set to zero?
|
ctrl_nxt(ctrl_rf_in_mux_msb_c downto ctrl_rf_in_mux_lsb_c) <= "11"; -- RF input = CSR output (hacky! results zero since there is no valid CSR_read request)
|
ctrl_nxt(ctrl_rf_in_mux_msb_c downto ctrl_rf_in_mux_lsb_c) <= "11"; -- RF input = CSR output (hacky! results zero since there is no valid CSR_read)
|
ctrl_nxt(ctrl_rf_r0_we_c) <= '1'; -- force RF write access and force rd=r0
|
ctrl_nxt(ctrl_rf_r0_we_c) <= '1'; -- force RF write access and force rd=r0
|
end if;
|
end if;
|
--
|
--
|
execute_engine.state_nxt <= DISPATCH;
|
execute_engine.state_nxt <= DISPATCH;
|
|
|
when DISPATCH => -- Get new command from instruction buffer (i_buf)
|
when DISPATCH => -- Get new command from instruction issue engine
|
-- ------------------------------------------------------------
|
-- ------------------------------------------------------------
|
if (i_buf.avail = '1') then -- instruction available?
|
if (cmd_issue.valid = '1') then -- instruction available?
|
i_buf.re <= '1';
|
-- IR update --
|
--
|
execute_engine.is_ci_nxt <= cmd_issue.data(32); -- flag to indicate this is a de-compressed instruction beeing executed
|
execute_engine.is_ci_nxt <= i_buf.rdata(32); -- flag to indicate this is a de-compressed instruction beeing executed
|
execute_engine.i_reg_nxt <= cmd_issue.data(31 downto 0);
|
execute_engine.i_reg_nxt <= i_buf.rdata(31 downto 0);
|
trap_ctrl.instr_ma <= cmd_issue.data(33); -- misaligned instruction fetch address
|
trap_ctrl.instr_ma <= i_buf.rdata(33); -- misaligned instruction fetch address
|
trap_ctrl.instr_be <= cmd_issue.data(34); -- bus access fault during instrucion fetch
|
trap_ctrl.instr_be <= i_buf.rdata(34); -- bus access fault during instrucion fetch
|
illegal_compressed <= cmd_issue.data(35); -- invalid decompressed instruction
|
illegal_compressed <= i_buf.rdata(35); -- invalid decompressed instruction
|
-- PC update --
|
--
|
|
execute_engine.if_rst_nxt <= '0';
|
execute_engine.if_rst_nxt <= '0';
|
if (execute_engine.if_rst = '0') then -- if there was NO non-linear PC modification
|
if (execute_engine.if_rst = '0') then -- if there was NO non-linear PC modification
|
execute_engine.pc_nxt <= execute_engine.next_pc;
|
execute_engine.pc_nxt <= execute_engine.next_pc(data_width_c-1 downto 1) & '0';
|
end if;
|
end if;
|
--
|
-- any reason to go to trap state FAST? --
|
-- any reason to go FAST to trap state? --
|
if (execute_engine.sleep = '1') or (trap_ctrl.env_start = '1') or (trap_ctrl.exc_fire = '1') or ((cmd_issue.data(33) or cmd_issue.data(34)) = '1') then
|
if (execute_engine.sleep = '1') or (trap_ctrl.env_start = '1') or (trap_ctrl.exc_fire = '1') or ((i_buf.rdata(33) or i_buf.rdata(34)) = '1') then
|
|
execute_engine.state_nxt <= TRAP;
|
execute_engine.state_nxt <= TRAP;
|
else
|
else
|
execute_engine.state_nxt <= EXECUTE;
|
execute_engine.state_nxt <= EXECUTE;
|
end if;
|
end if;
|
end if;
|
end if;
|
Line 883... |
Line 850... |
-- ------------------------------------------------------------
|
-- ------------------------------------------------------------
|
execute_engine.state_nxt <= SYS_WAIT;
|
execute_engine.state_nxt <= SYS_WAIT;
|
-- for simplicity: internally, fence and fence.i perform the same operations (clear and reload instruction prefetch buffer)
|
-- for simplicity: internally, fence and fence.i perform the same operations (clear and reload instruction prefetch buffer)
|
-- FENCE.I --
|
-- FENCE.I --
|
if (CPU_EXTENSION_RISCV_Zifencei = true) then
|
if (CPU_EXTENSION_RISCV_Zifencei = true) then
|
execute_engine.pc_nxt <= execute_engine.next_pc; -- "refetch" next instruction
|
execute_engine.pc_nxt <= execute_engine.next_pc(data_width_c-1 downto 1) & '0'; -- "refetch" next instruction
|
execute_engine.if_rst_nxt <= '1'; -- this is a non-linear PC modification
|
execute_engine.if_rst_nxt <= '1'; -- this is a non-linear PC modification
|
fetch_engine.reset <= '1';
|
fetch_engine.reset <= '1';
|
if (execute_engine.i_reg(instr_funct3_lsb_c) = funct3_fencei_c(0)) then
|
if (execute_engine.i_reg(instr_funct3_lsb_c) = funct3_fencei_c(0)) then
|
ctrl_nxt(ctrl_bus_fencei_c) <= '1';
|
ctrl_nxt(ctrl_bus_fencei_c) <= '1';
|
end if;
|
end if;
|
Line 985... |
Line 952... |
|
|
when LOADSTORE_2 => -- wait for bus transaction to finish
|
when LOADSTORE_2 => -- wait for bus transaction to finish
|
-- ------------------------------------------------------------
|
-- ------------------------------------------------------------
|
ctrl_nxt(ctrl_bus_mdi_we_c) <= '1'; -- keep writing input data to MDI (only relevant for LOAD)
|
ctrl_nxt(ctrl_bus_mdi_we_c) <= '1'; -- keep writing input data to MDI (only relevant for LOAD)
|
ctrl_nxt(ctrl_rf_in_mux_msb_c downto ctrl_rf_in_mux_lsb_c) <= "01"; -- RF input = memory input (only relevant for LOAD)
|
ctrl_nxt(ctrl_rf_in_mux_msb_c downto ctrl_rf_in_mux_lsb_c) <= "01"; -- RF input = memory input (only relevant for LOAD)
|
if (ma_load_i = '1') or (be_load_i = '1') or (ma_store_i = '1') or (be_store_i = '1') then -- abort if exception
|
if ((ma_load_i or be_load_i or ma_store_i or be_store_i) = '1') then -- abort if exception
|
execute_engine.state_nxt <= SYS_WAIT;
|
execute_engine.state_nxt <= DISPATCH;
|
elsif (bus_d_wait_i = '0') then -- wait for bus to finish transaction
|
elsif (bus_d_wait_i = '0') then -- wait for bus to finish transaction
|
if (execute_engine.i_reg(instr_opcode_msb_c-1) = '0') then -- LOAD
|
if (execute_engine.i_reg(instr_opcode_msb_c-1) = '0') then -- LOAD
|
ctrl_nxt(ctrl_rf_wb_en_c) <= '1'; -- valid RF write-back (keep writing back all the time)
|
ctrl_nxt(ctrl_rf_wb_en_c) <= '1'; -- valid RF write-back (keep writing back all the time)
|
end if;
|
end if;
|
execute_engine.state_nxt <= DISPATCH;
|
execute_engine.state_nxt <= DISPATCH;
|
Line 1749... |
Line 1716... |
csr.rdata(16) <= trap_ctrl.irq_buf(interrupt_firq_0_c);
|
csr.rdata(16) <= trap_ctrl.irq_buf(interrupt_firq_0_c);
|
csr.rdata(17) <= trap_ctrl.irq_buf(interrupt_firq_1_c);
|
csr.rdata(17) <= trap_ctrl.irq_buf(interrupt_firq_1_c);
|
csr.rdata(18) <= trap_ctrl.irq_buf(interrupt_firq_2_c);
|
csr.rdata(18) <= trap_ctrl.irq_buf(interrupt_firq_2_c);
|
csr.rdata(19) <= trap_ctrl.irq_buf(interrupt_firq_3_c);
|
csr.rdata(19) <= trap_ctrl.irq_buf(interrupt_firq_3_c);
|
|
|
-- physical memory protection --
|
-- physical memory protection - configuration --
|
when csr_pmpcfg0_c => -- R/W: pmpcfg0 - physical memory protection configuration register 0
|
when csr_pmpcfg0_c => -- R/W: pmpcfg0 - physical memory protection configuration register 0
|
if (PMP_USE = true) then
|
if (PMP_USE = true) then
|
if (PMP_NUM_REGIONS >= 1) then
|
if (PMP_NUM_REGIONS >= 1) then
|
csr.rdata(07 downto 00) <= csr.pmpcfg(0);
|
csr.rdata(07 downto 00) <= csr.pmpcfg(0);
|
end if;
|
end if;
|
Line 1781... |
Line 1748... |
if (PMP_NUM_REGIONS >= 8) then
|
if (PMP_NUM_REGIONS >= 8) then
|
csr.rdata(31 downto 24) <= csr.pmpcfg(7);
|
csr.rdata(31 downto 24) <= csr.pmpcfg(7);
|
end if;
|
end if;
|
end if;
|
end if;
|
|
|
|
-- physical memory protection - addresses --
|
when csr_pmpaddr0_c => -- R/W: pmpaddr0 - physical memory protection address register 0
|
when csr_pmpaddr0_c => -- R/W: pmpaddr0 - physical memory protection address register 0
|
if (PMP_USE = true) and (PMP_NUM_REGIONS >= 1) then
|
if (PMP_USE = true) and (PMP_NUM_REGIONS >= 1) then
|
csr.rdata <= csr.pmpaddr(0);
|
csr.rdata <= csr.pmpaddr(0);
|
if (csr.pmpcfg(0)(4 downto 3) = "00") then -- mode = off
|
if (csr.pmpcfg(0)(4 downto 3) = "00") then -- mode = off
|
csr.rdata(PMP_GRANULARITY-1 downto 0) <= (others => '0'); -- required for granularity check by SW
|
csr.rdata(PMP_GRANULARITY-1 downto 0) <= (others => '0'); -- required for granularity check by SW
|