Line 73... |
Line 73... |
IO_SPI_USE : boolean := true; -- implement serial peripheral interface (SPI)?
|
IO_SPI_USE : boolean := true; -- implement serial peripheral interface (SPI)?
|
IO_TWI_USE : boolean := true; -- implement two-wire interface (TWI)?
|
IO_TWI_USE : boolean := true; -- implement two-wire interface (TWI)?
|
IO_PWM_USE : boolean := true; -- implement pulse-width modulation unit (PWM)?
|
IO_PWM_USE : boolean := true; -- implement pulse-width modulation unit (PWM)?
|
IO_WDT_USE : boolean := true; -- implement watch dog timer (WDT)?
|
IO_WDT_USE : boolean := true; -- implement watch dog timer (WDT)?
|
IO_CLIC_USE : boolean := true; -- implement core local interrupt controller (CLIC)?
|
IO_CLIC_USE : boolean := true; -- implement core local interrupt controller (CLIC)?
|
IO_TRNG_USE : boolean := true -- implement true random number generator (TRNG)?
|
IO_TRNG_USE : boolean := true; -- implement true random number generator (TRNG)?
|
|
IO_DEVNULL_USE : boolean := true -- implement dummy device (DEVNULL)?
|
);
|
);
|
port (
|
port (
|
-- global control --
|
-- global control --
|
clk_i : in std_ulogic; -- global clock, rising edge
|
clk_i : in std_ulogic; -- global clock, rising edge
|
rstn_i : in std_ulogic; -- global reset, low-active, async
|
rstn_i : in std_ulogic; -- global reset, low-active, async
|
Line 386... |
Line 387... |
when funct3_sltu_c => alu_operation_v := alu_cmd_slt_c; -- SLTU(I)
|
when funct3_sltu_c => alu_operation_v := alu_cmd_slt_c; -- SLTU(I)
|
when funct3_xor_c => alu_operation_v := alu_cmd_xor_c; -- XOR(I)
|
when funct3_xor_c => alu_operation_v := alu_cmd_xor_c; -- XOR(I)
|
when funct3_sr_c => alu_operation_v := alu_cmd_shift_c; -- SRL(I) / SRA(I)
|
when funct3_sr_c => alu_operation_v := alu_cmd_shift_c; -- SRL(I) / SRA(I)
|
when funct3_or_c => alu_operation_v := alu_cmd_or_c; -- OR(I)
|
when funct3_or_c => alu_operation_v := alu_cmd_or_c; -- OR(I)
|
when funct3_and_c => alu_operation_v := alu_cmd_and_c; -- AND(I)
|
when funct3_and_c => alu_operation_v := alu_cmd_and_c; -- AND(I)
|
when others => alu_operation_v := (others => '-'); -- undefined
|
when others => alu_operation_v := (others => '0'); -- undefined
|
end case;
|
end case;
|
|
|
-- is rs1 = r0? --
|
-- is rs1 = r0? --
|
rs1_is_r0_v := '0';
|
rs1_is_r0_v := '0';
|
if (i_reg(instr_rs1_msb_c downto instr_rs1_lsb_c) = "00000") then
|
if (i_reg(instr_rs1_msb_c downto instr_rs1_lsb_c) = "00000") then
|
Line 901... |
Line 902... |
if (rstn_i = '0') then
|
if (rstn_i = '0') then
|
exc_buf <= (others => '0');
|
exc_buf <= (others => '0');
|
irq_buf <= (others => '0');
|
irq_buf <= (others => '0');
|
exc_ack <= (others => '0');
|
exc_ack <= (others => '0');
|
irq_ack <= (others => '0');
|
irq_ack <= (others => '0');
|
exc_src <= (others => '-');
|
exc_src <= (others => '0');
|
exc_cpu_start <= '0';
|
exc_cpu_start <= '0';
|
exc_cause <= (others => '0');
|
exc_cause <= (others => '0');
|
mtinst <= (others => '-');
|
mtinst <= (others => '0');
|
elsif rising_edge(clk_i) then
|
elsif rising_edge(clk_i) then
|
if (CPU_EXTENSION_RISCV_Zicsr = true) then
|
if (CPU_EXTENSION_RISCV_Zicsr = true) then
|
-- exception buffer: misaligned load/store/instruction address
|
-- exception buffer: misaligned load/store/instruction address
|
exc_buf(exception_lalign_c) <= (exc_buf(exception_lalign_c) or ma_load_i) and (not exc_ack(exception_lalign_c));
|
exc_buf(exception_lalign_c) <= (exc_buf(exception_lalign_c) or ma_load_i) and (not exc_ack(exception_lalign_c));
|
exc_buf(exception_salign_c) <= (exc_buf(exception_salign_c) or ma_store_i) and (not exc_ack(exception_salign_c));
|
exc_buf(exception_salign_c) <= (exc_buf(exception_salign_c) or ma_store_i) and (not exc_ack(exception_salign_c));
|
Line 1090... |
Line 1091... |
mstatus_mie <= '0';
|
mstatus_mie <= '0';
|
mstatus_mpie <= '0';
|
mstatus_mpie <= '0';
|
mie_msie <= '0';
|
mie_msie <= '0';
|
mie_meie <= '0';
|
mie_meie <= '0';
|
mie_mtie <= '0';
|
mie_mtie <= '0';
|
mtvec <= (others => '-');
|
mtvec <= (others => '0');
|
mtval <= (others => '-');
|
mtval <= (others => '0');
|
mepc <= (others => '-');
|
mepc <= (others => '0');
|
mip_msip <= '-';
|
mip_msip <= '0';
|
elsif rising_edge(clk_i) then
|
elsif rising_edge(clk_i) then
|
if (CPU_EXTENSION_RISCV_Zicsr = true) then
|
if (CPU_EXTENSION_RISCV_Zicsr = true) then
|
mip_msip <= '0';
|
mip_msip <= '0';
|
-- register that can be modified by user --
|
-- register that can be modified by user --
|
if (ctrl(ctrl_csr_we_c) = '1') then -- manual update
|
if (ctrl(ctrl_csr_we_c) = '1') then -- manual update
|
Line 1132... |
Line 1133... |
else -- automatic update by hardware
|
else -- automatic update by hardware
|
-- machine exception PC & exception value register --
|
-- machine exception PC & exception value register --
|
if (exc_cpu_ack = '1') then -- exception start?
|
if (exc_cpu_ack = '1') then -- exception start?
|
if (exc_cause(exc_cause_nxt'left) = '1') then -- for INTERRUPTs: mepc = address of next (unclompeted) instruction
|
if (exc_cause(exc_cause_nxt'left) = '1') then -- for INTERRUPTs: mepc = address of next (unclompeted) instruction
|
mepc <= pc_reg;
|
mepc <= pc_reg;
|
mtval <= (others => '-'); -- not specified
|
mtval <= (others => '0'); -- not specified
|
else -- for EXCEPTIONs: mepc = address of next (unclompeted) instruction
|
else -- for EXCEPTIONs: mepc = address of next (unclompeted) instruction
|
mepc <= pc_backup2_reg;
|
mepc <= pc_backup2_reg;
|
if ((exc_src(exception_iaccess_c) or exc_src(exception_ialign_c)) = '1') then -- instruction access error OR misaligned instruction
|
if ((exc_src(exception_iaccess_c) or exc_src(exception_ialign_c)) = '1') then -- instruction access error OR misaligned instruction
|
mtval <= pc_backup_reg;
|
mtval <= pc_backup_reg;
|
elsif (exc_src(exception_iillegal_c) = '1') then -- illegal instruction
|
elsif (exc_src(exception_iillegal_c) = '1') then -- illegal instruction
|
Line 1250... |
Line 1251... |
csr_rdata_o(20) <= bool_to_ulogic_f(IO_TWI_USE); -- implement two-wire interface (TWI)?
|
csr_rdata_o(20) <= bool_to_ulogic_f(IO_TWI_USE); -- implement two-wire interface (TWI)?
|
csr_rdata_o(21) <= bool_to_ulogic_f(IO_PWM_USE); -- implement pulse-width modulation unit (PWM)?
|
csr_rdata_o(21) <= bool_to_ulogic_f(IO_PWM_USE); -- implement pulse-width modulation unit (PWM)?
|
csr_rdata_o(22) <= bool_to_ulogic_f(IO_WDT_USE); -- implement watch dog timer (WDT)?
|
csr_rdata_o(22) <= bool_to_ulogic_f(IO_WDT_USE); -- implement watch dog timer (WDT)?
|
csr_rdata_o(23) <= bool_to_ulogic_f(IO_CLIC_USE); -- implement core local interrupt controller (CLIC)?
|
csr_rdata_o(23) <= bool_to_ulogic_f(IO_CLIC_USE); -- implement core local interrupt controller (CLIC)?
|
csr_rdata_o(24) <= bool_to_ulogic_f(IO_TRNG_USE); -- implement true random number generator (TRNG)?
|
csr_rdata_o(24) <= bool_to_ulogic_f(IO_TRNG_USE); -- implement true random number generator (TRNG)?
|
|
csr_rdata_o(25) <= bool_to_ulogic_f(IO_DEVNULL_USE); -- implement dummy device (DEVNULL)?
|
when x"fc1" => -- R/-: mclock - processor clock speed
|
when x"fc1" => -- R/-: mclock - processor clock speed
|
csr_rdata_o <= std_ulogic_vector(to_unsigned(CLOCK_FREQUENCY, 32));
|
csr_rdata_o <= std_ulogic_vector(to_unsigned(CLOCK_FREQUENCY, 32));
|
when x"fc4" => -- R/-: mispacebase - Base address of instruction memory space
|
when x"fc4" => -- R/-: mispacebase - Base address of instruction memory space
|
csr_rdata_o <= MEM_ISPACE_BASE;
|
csr_rdata_o <= MEM_ISPACE_BASE;
|
when x"fc5" => -- R/-: mdspacebase - Base address of data memory space
|
when x"fc5" => -- R/-: mdspacebase - Base address of data memory space
|