From c2fd823a59b25a962a9431ad04b799ad32f9d0ce Mon Sep 17 00:00:00 2001 From: stnolting Date: Fri, 20 Sep 2024 16:05:38 +0200 Subject: [PATCH 1/7] [dma] minor comment edit --- rtl/core/neorv32_dma.vhd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rtl/core/neorv32_dma.vhd b/rtl/core/neorv32_dma.vhd index 2300de073..7f0799ee8 100644 --- a/rtl/core/neorv32_dma.vhd +++ b/rtl/core/neorv32_dma.vhd @@ -305,7 +305,7 @@ begin engine.busy <= '0' when (engine.state = S_IDLE) else '1'; -- bus output -- - dma_req_o.priv <= priv_mode_m_c; -- privileged access + dma_req_o.priv <= priv_mode_m_c; -- DMA accesses are always privileged dma_req_o.src <= '0'; -- source = data access dma_req_o.addr <= engine.src_addr when (engine.state = S_READ) else engine.dst_addr; dma_req_o.rvso <= '0'; -- no reservation set operation possible From 6b5cd911241d330df0ac4c5582032f3983063724 Mon Sep 17 00:00:00 2001 From: stnolting Date: Fri, 20 Sep 2024 16:06:51 +0200 Subject: [PATCH 2/7] [xirq] rework priorization mux chain to prevent Quartus from issuing warnings --- rtl/core/neorv32_xirq.vhd | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/rtl/core/neorv32_xirq.vhd b/rtl/core/neorv32_xirq.vhd index c5cf52ff4..5ed5b45e5 100644 --- a/rtl/core/neorv32_xirq.vhd +++ b/rtl/core/neorv32_xirq.vhd @@ -152,12 +152,18 @@ begin -- anyone firing? -- irq_fire <= or_reduce_f(irq_raw); - -- encode highest-priority source (structural code) -- + -- encode highest-priority source (structural code: mux-chain) -- priority_encoder_gen: - for i in 0 to XIRQ_NUM_CH-2 generate -- start with highest priority - prio_enc(i) <= std_ulogic_vector(to_unsigned(i, 5)) when (irq_raw(i) = '1') else prio_enc(i+1); + for i in 0 to XIRQ_NUM_CH-1 generate -- start with highest priority + priority_encoder_gen_chain: -- inside chain + if i < XIRQ_NUM_CH-1 generate + prio_enc(i) <= std_ulogic_vector(to_unsigned(i, 5)) when (irq_raw(i) = '1') else prio_enc(i+1); + end generate; + priority_encoder_gen_last: -- end of chain + if i = XIRQ_NUM_CH-1 generate + prio_enc(XIRQ_NUM_CH-1) <= std_ulogic_vector(to_unsigned(XIRQ_NUM_CH-1, 5)); -- lowest priority + end generate; end generate; - prio_enc(XIRQ_NUM_CH-1) <= std_ulogic_vector(to_unsigned(XIRQ_NUM_CH-1, 5)); -- lowest priority -- IRQ Arbiter -------------------------------------------------------------- From 1bc829f13e1ed73b7ed0f78b5b93732216b4968f Mon Sep 17 00:00:00 2001 From: stnolting Date: Fri, 20 Sep 2024 16:07:31 +0200 Subject: [PATCH 3/7] [lsu] signal renamings plus some minor code cleanups --- rtl/core/neorv32_cpu_lsu.vhd | 108 ++++++++++++++--------------------- 1 file changed, 44 insertions(+), 64 deletions(-) diff --git a/rtl/core/neorv32_cpu_lsu.vhd b/rtl/core/neorv32_cpu_lsu.vhd index e9fdb18f3..39ece0b5d 100644 --- a/rtl/core/neorv32_cpu_lsu.vhd +++ b/rtl/core/neorv32_cpu_lsu.vhd @@ -29,14 +29,11 @@ entity neorv32_cpu_lsu is rdata_o : out std_ulogic_vector(XLEN-1 downto 0); -- read data mar_o : out std_ulogic_vector(XLEN-1 downto 0); -- current memory address register wait_o : out std_ulogic; -- wait for access to complete - ma_load_o : out std_ulogic; -- misaligned load data address - ma_store_o : out std_ulogic; -- misaligned store data address - be_load_o : out std_ulogic; -- bus error on load data access - be_store_o : out std_ulogic; -- bus error on store data access + err_o : out std_ulogic_vector(3 downto 0); -- alignment/access errors pmp_fault_i : in std_ulogic; -- PMP read/write access fault -- data bus -- - bus_req_o : out bus_req_t; -- request - bus_rsp_i : in bus_rsp_t -- response + dbus_req_o : out bus_req_t; -- request + dbus_rsp_i : in bus_rsp_t -- response ); end neorv32_cpu_lsu; @@ -68,67 +65,50 @@ begin end if; end process mem_addr_reg; - bus_req_o.addr <= mar; -- bus address - mar_o <= mar; -- for MTVAL CSR + dbus_req_o.addr <= mar; -- bus address + mar_o <= mar; -- for MTVAL CSR - -- Access Type ---------------------------------------------------------------------------- - -- ------------------------------------------------------------------------------------------- - mem_type_reg: process(rstn_i, clk_i) - begin - if (rstn_i = '0') then - bus_req_o.rw <= '0'; - bus_req_o.priv <= '0'; - bus_req_o.rvso <= '0'; - elsif rising_edge(clk_i) then - if (ctrl_i.lsu_mo_we = '1') then - -- read/write -- - bus_req_o.rw <= ctrl_i.lsu_rw; - -- privilege level -- - bus_req_o.priv <= ctrl_i.lsu_priv; - -- reservation set operation -- - if AMO_LRSC_ENABLE and (ctrl_i.ir_opcode(2) = opcode_amo_c(2)) then - bus_req_o.rvso <= '1'; - else - bus_req_o.rvso <= '0'; - end if; - end if; - end if; - end process mem_type_reg; - - bus_req_o.src <= '0'; -- 0 = data access - bus_req_o.fence <= ctrl_i.lsu_fence; -- this is valid without STB being set - - - -- Data Output - Alignment and Byte Enable ------------------------------------------------ + -- Data Output: Alignment, Byte Enable and Type Identifiers ------------------------------- -- ------------------------------------------------------------------------------------------- mem_do_reg: process(rstn_i, clk_i) begin if (rstn_i = '0') then - bus_req_o.data <= (others => '0'); - bus_req_o.ben <= (others => '0'); + dbus_req_o.rw <= '0'; + dbus_req_o.priv <= '0'; + dbus_req_o.rvso <= '0'; + dbus_req_o.data <= (others => '0'); + dbus_req_o.ben <= (others => '0'); elsif rising_edge(clk_i) then if (ctrl_i.lsu_mo_we = '1') then + -- type identifiers -- + dbus_req_o.rw <= ctrl_i.lsu_rw; -- read/write + dbus_req_o.priv <= ctrl_i.lsu_priv; -- privilege level + dbus_req_o.rvso <= bool_to_ulogic_f(AMO_LRSC_ENABLE) and ctrl_i.ir_opcode(2); -- reservation set operation + -- data alignment + byte-enable -- case ctrl_i.ir_funct3(1 downto 0) is when "00" => -- byte - bus_req_o.data <= wdata_i(7 downto 0) & wdata_i(7 downto 0) & wdata_i(7 downto 0) & wdata_i(7 downto 0); - bus_req_o.ben(0) <= (not addr_i(1)) and (not addr_i(0)); - bus_req_o.ben(1) <= (not addr_i(1)) and ( addr_i(0)); - bus_req_o.ben(2) <= ( addr_i(1)) and (not addr_i(0)); - bus_req_o.ben(3) <= ( addr_i(1)) and ( addr_i(0)); + dbus_req_o.data <= wdata_i(7 downto 0) & wdata_i(7 downto 0) & wdata_i(7 downto 0) & wdata_i(7 downto 0); + dbus_req_o.ben(0) <= (not addr_i(1)) and (not addr_i(0)); + dbus_req_o.ben(1) <= (not addr_i(1)) and ( addr_i(0)); + dbus_req_o.ben(2) <= ( addr_i(1)) and (not addr_i(0)); + dbus_req_o.ben(3) <= ( addr_i(1)) and ( addr_i(0)); when "01" => -- half-word - bus_req_o.data <= wdata_i(15 downto 0) & wdata_i(15 downto 0); - bus_req_o.ben <= addr_i(1) & addr_i(1) & (not addr_i(1)) & (not addr_i(1)); + dbus_req_o.data <= wdata_i(15 downto 0) & wdata_i(15 downto 0); + dbus_req_o.ben <= addr_i(1) & addr_i(1) & (not addr_i(1)) & (not addr_i(1)); when others => -- word - bus_req_o.data <= wdata_i; - bus_req_o.ben <= (others => '1'); + dbus_req_o.data <= wdata_i; + dbus_req_o.ben <= (others => '1'); end case; end if; end if; end process mem_do_reg; + dbus_req_o.src <= '0'; -- 0 = data access + dbus_req_o.fence <= ctrl_i.lsu_fence; -- this is valid without STB being set + - -- Data Input - Alignment and Sign-Extension ---------------------------------------------- + -- Data Input Alignment and Sign-Extension ------------------------------------------------ -- ------------------------------------------------------------------------------------------- mem_di_reg: process(rstn_i, clk_i) begin @@ -141,22 +121,22 @@ begin when "00" => -- byte case mar(1 downto 0) is when "00" => -- byte 0 - rdata_o <= replicate_f((not ctrl_i.ir_funct3(2)) and bus_rsp_i.data(7), 24) & bus_rsp_i.data(7 downto 0); + rdata_o <= replicate_f((not ctrl_i.ir_funct3(2)) and dbus_rsp_i.data(7), 24) & dbus_rsp_i.data(7 downto 0); when "01" => -- byte 1 - rdata_o <= replicate_f((not ctrl_i.ir_funct3(2)) and bus_rsp_i.data(15), 24) & bus_rsp_i.data(15 downto 8); + rdata_o <= replicate_f((not ctrl_i.ir_funct3(2)) and dbus_rsp_i.data(15), 24) & dbus_rsp_i.data(15 downto 8); when "10" => -- byte 2 - rdata_o <= replicate_f((not ctrl_i.ir_funct3(2)) and bus_rsp_i.data(23), 24) & bus_rsp_i.data(23 downto 16); + rdata_o <= replicate_f((not ctrl_i.ir_funct3(2)) and dbus_rsp_i.data(23), 24) & dbus_rsp_i.data(23 downto 16); when others => -- byte 3 - rdata_o <= replicate_f((not ctrl_i.ir_funct3(2)) and bus_rsp_i.data(31), 24) & bus_rsp_i.data(31 downto 24); + rdata_o <= replicate_f((not ctrl_i.ir_funct3(2)) and dbus_rsp_i.data(31), 24) & dbus_rsp_i.data(31 downto 24); end case; when "01" => -- half-word if (mar(1) = '0') then -- low half-word - rdata_o <= replicate_f((not ctrl_i.ir_funct3(2)) and bus_rsp_i.data(15), 16) & bus_rsp_i.data(15 downto 0); + rdata_o <= replicate_f((not ctrl_i.ir_funct3(2)) and dbus_rsp_i.data(15), 16) & dbus_rsp_i.data(15 downto 0); else -- high half-word - rdata_o <= replicate_f((not ctrl_i.ir_funct3(2)) and bus_rsp_i.data(31), 16) & bus_rsp_i.data(31 downto 16); + rdata_o <= replicate_f((not ctrl_i.ir_funct3(2)) and dbus_rsp_i.data(31), 16) & dbus_rsp_i.data(31 downto 16); end if; when others => -- word - rdata_o <= bus_rsp_i.data; + rdata_o <= dbus_rsp_i.data; end case; end if; end if; @@ -171,26 +151,26 @@ begin arbiter_err <= '0'; arbiter_req <= '0'; elsif rising_edge(clk_i) then - arbiter_err <= bus_rsp_i.err or pmp_fault_i; -- buffer stage + arbiter_err <= dbus_rsp_i.err or pmp_fault_i; -- buffer stage if (arbiter_req = '0') then -- idle arbiter_req <= ctrl_i.lsu_req; - elsif (bus_rsp_i.ack = '1') or (ctrl_i.cpu_trap = '1') then -- normal termination or start of trap handling + elsif (dbus_rsp_i.ack = '1') or (ctrl_i.cpu_trap = '1') then -- normal termination or start of trap handling arbiter_req <= '0'; end if; end if; end process access_arbiter; -- wait for bus response -- - wait_o <= not bus_rsp_i.ack; + wait_o <= not dbus_rsp_i.ack; -- output access/alignment errors to control unit -- - ma_load_o <= arbiter_req and (not ctrl_i.lsu_rw) and misaligned; -- misaligned load - be_load_o <= arbiter_req and (not ctrl_i.lsu_rw) and arbiter_err; -- load bus error - ma_store_o <= arbiter_req and ( ctrl_i.lsu_rw) and misaligned; -- misaligned store - be_store_o <= arbiter_req and ( ctrl_i.lsu_rw) and arbiter_err; -- store bus error + err_o(0) <= arbiter_req and (not ctrl_i.lsu_rw) and misaligned; -- misaligned load + err_o(1) <= arbiter_req and (not ctrl_i.lsu_rw) and arbiter_err; -- load bus error + err_o(2) <= arbiter_req and ( ctrl_i.lsu_rw) and misaligned; -- misaligned store + err_o(3) <= arbiter_req and ( ctrl_i.lsu_rw) and arbiter_err; -- store bus error -- access request (all source signals are driven by registers) -- - bus_req_o.stb <= ctrl_i.lsu_req and (not misaligned) and (not pmp_fault_i); + dbus_req_o.stb <= ctrl_i.lsu_req and (not misaligned) and (not pmp_fault_i); end neorv32_cpu_lsu_rtl; From 1756ceacc723791281c444e19f94f623c4a68840 Mon Sep 17 00:00:00 2001 From: stnolting Date: Fri, 20 Sep 2024 16:07:53 +0200 Subject: [PATCH 4/7] [cpu] signal renamings to make the code more readable --- rtl/core/neorv32_cpu.vhd | 91 +++++++++++++++++++--------------------- 1 file changed, 42 insertions(+), 49 deletions(-) diff --git a/rtl/core/neorv32_cpu.vhd b/rtl/core/neorv32_cpu.vhd index e169a91b4..6fcc18eb9 100644 --- a/rtl/core/neorv32_cpu.vhd +++ b/rtl/core/neorv32_cpu.vhd @@ -81,9 +81,9 @@ end neorv32_cpu; architecture neorv32_cpu_rtl of neorv32_cpu is -- auto-configuration -- - constant regfile_rs3_en_c : boolean := CPU_EXTENSION_RISCV_Zxcfu or CPU_EXTENSION_RISCV_Zfinx; -- 3rd register file read port (rs3) + constant regfile_rs3_en_c : boolean := CPU_EXTENSION_RISCV_Zxcfu or CPU_EXTENSION_RISCV_Zfinx; -- 3rd register file read port - -- control-unit-external CSR interface -- + -- external CSR interface -- signal xcsr_we : std_ulogic; signal xcsr_addr : std_ulogic_vector(11 downto 0); signal xcsr_wdata : std_ulogic_vector(XLEN-1 downto 0); @@ -93,26 +93,24 @@ architecture neorv32_cpu_rtl of neorv32_cpu is -- local signals -- signal ctrl : ctrl_bus_t; -- main control bus - signal imm : std_ulogic_vector(XLEN-1 downto 0); -- immediate + signal alu_imm : std_ulogic_vector(XLEN-1 downto 0); -- immediate signal rf_wdata : std_ulogic_vector(XLEN-1 downto 0); -- register file write data signal rs1, rs2, rs3 : std_ulogic_vector(XLEN-1 downto 0); -- source registers signal alu_res : std_ulogic_vector(XLEN-1 downto 0); -- alu result signal alu_add : std_ulogic_vector(XLEN-1 downto 0); -- alu address result signal alu_cmp : std_ulogic_vector(1 downto 0); -- comparator result - signal mem_rdata : std_ulogic_vector(XLEN-1 downto 0); -- memory read data - signal cp_done : std_ulogic; -- ALU co-processor operation done + signal lsu_rdata : std_ulogic_vector(XLEN-1 downto 0); -- lsu memory read data + signal alu_cp_done : std_ulogic; -- alu co-processor operation done signal lsu_wait : std_ulogic; -- wait for current data bus access signal csr_rdata : std_ulogic_vector(XLEN-1 downto 0); -- csr read data - signal mar : std_ulogic_vector(XLEN-1 downto 0); -- memory address register - signal ma_load : std_ulogic; -- misaligned load data address - signal ma_store : std_ulogic; -- misaligned store data address - signal be_load : std_ulogic; -- bus error on load data access - signal be_store : std_ulogic; -- bus error on store data access - signal fetch_pc : std_ulogic_vector(XLEN-1 downto 0); -- pc for instruction fetch - signal curr_pc : std_ulogic_vector(XLEN-1 downto 0); -- current pc (for currently executed instruction) - signal link_pc : std_ulogic_vector(XLEN-1 downto 0); -- link pc (return address) - signal pmp_ex_fault : std_ulogic; -- PMP instruction fetch fault - signal pmp_rw_fault : std_ulogic; -- PMP read/write access fault + signal lsu_mar : std_ulogic_vector(XLEN-1 downto 0); -- lsu memory address register + signal lsu_err : std_ulogic_vector(3 downto 0); -- lsu alignment/access errors + signal pc_fetch : std_ulogic_vector(XLEN-1 downto 0); -- pc for instruction fetch + signal pc_curr : std_ulogic_vector(XLEN-1 downto 0); -- current pc (for currently executed instruction) + signal pc_next : std_ulogic_vector(XLEN-1 downto 0); -- next pc (return address) + signal pmp_ex_fault : std_ulogic; -- pmp instruction fetch fault + signal pmp_rw_fault : std_ulogic; -- pmp read/write access fault + signal irq_machine : std_ulogic_vector(2 downto 0); -- risc-v standard machine-level interrupts begin @@ -192,18 +190,18 @@ begin rstn_i => rstn_i, -- global reset, low-active, async ctrl_o => ctrl, -- main control bus -- instruction fetch interface -- - i_pmp_fault_i => pmp_ex_fault, -- instruction fetch pmp fault - bus_req_o => ibus_req_o, -- request - bus_rsp_i => ibus_rsp_i, -- response + ibus_pmperr_i => pmp_ex_fault, -- instruction fetch pmp fault + ibus_req_o => ibus_req_o, -- request + ibus_rsp_i => ibus_rsp_i, -- response -- data path interface -- - alu_cp_done_i => cp_done, -- ALU iterative operation done - cmp_i => alu_cmp, -- comparator status + alu_cp_done_i => alu_cp_done, -- ALU iterative operation done + alu_cmp_i => alu_cmp, -- comparator status alu_add_i => alu_add, -- ALU address result - rs1_i => rs1, -- rf source 1 - imm_o => imm, -- immediate - fetch_pc_o => fetch_pc, -- instruction fetch address - curr_pc_o => curr_pc, -- current PC (corresponding to current instruction) - link_pc_o => link_pc, -- link PC (return address) + alu_imm_o => alu_imm, -- immediate + rf_rs1_i => rs1, -- rf source 1 + pc_fetch_o => pc_fetch, -- instruction fetch address + pc_curr_o => pc_curr, -- current PC (corresponding to current instruction) + pc_next_o => pc_next, -- next PC (return address) csr_rdata_o => csr_rdata, -- CSR read data -- external CSR interface -- xcsr_we_o => xcsr_we, -- global write enable @@ -211,20 +209,18 @@ begin xcsr_wdata_o => xcsr_wdata, -- write data xcsr_rdata_i => xcsr_rdata_res, -- read data -- interrupts -- - db_halt_req_i => dbi_i, -- debug mode (halt) request - msi_i => msi_i, -- machine software interrupt - mei_i => mei_i, -- machine external interrupt - mti_i => mti_i, -- machine timer interrupt - firq_i => firq_i, -- fast interrupts - -- data access interface -- + irq_dbg_i => dbi_i, -- debug mode (halt) request + irq_machine_i => irq_machine, -- risc-v mti, mei, msi + irq_fast_i => firq_i, -- fast interrupts + -- load/store unit interface -- lsu_wait_i => lsu_wait, -- wait for data bus - mar_i => mar, -- memory address register - ma_load_i => ma_load, -- misaligned load data address - ma_store_i => ma_store, -- misaligned store data address - be_load_i => be_load, -- bus error on load data access - be_store_i => be_store -- bus error on store data access + lsu_mar_i => lsu_mar, -- memory address register + lsu_err_i => lsu_err -- alignment/access errors ); + -- RISC-V machine interrupts -- + irq_machine <= mti_i & mei_i & msi_i; + -- external CSR read-back -- xcsr_rdata_res <= xcsr_rdata_pmp or xcsr_rdata_alu; @@ -254,7 +250,7 @@ begin ); -- all buses are zero unless there is an according operation -- - rf_wdata <= alu_res or mem_rdata or csr_rdata or link_pc; + rf_wdata <= alu_res or lsu_rdata or csr_rdata or pc_next; -- ALU (Arithmetic/Logic Unit) and ALU Co-Processors -------------------------------------- @@ -286,14 +282,14 @@ begin rs1_i => rs1, -- rf source 1 rs2_i => rs2, -- rf source 2 rs3_i => rs3, -- rf source 3 - pc_i => curr_pc, -- current PC - imm_i => imm, -- immediate + pc_i => pc_curr, -- current PC + imm_i => alu_imm, -- immediate -- data output -- cmp_o => alu_cmp, -- comparator status res_o => alu_res, -- ALU result add_o => alu_add, -- address computation result -- status -- - cp_done_o => cp_done -- iterative processing units done? + cp_done_o => alu_cp_done -- iterative processing units done? ); @@ -311,17 +307,14 @@ begin -- cpu data access interface -- addr_i => alu_add, -- access address wdata_i => rs2, -- write data - rdata_o => mem_rdata, -- read data - mar_o => mar, -- memory address register + rdata_o => lsu_rdata, -- read data + mar_o => lsu_mar, -- memory address register wait_o => lsu_wait, -- wait for access to complete - ma_load_o => ma_load, -- misaligned load data address - ma_store_o => ma_store, -- misaligned store data address - be_load_o => be_load, -- bus error on load data access - be_store_o => be_store, -- bus error on store data access + err_o => lsu_err, -- alignment/access errors pmp_fault_i => pmp_rw_fault, -- PMP read/write access fault -- data bus -- - bus_req_o => dbus_req_o, -- request - bus_rsp_i => dbus_rsp_i -- response + dbus_req_o => dbus_req_o, -- request + dbus_rsp_i => dbus_rsp_i -- response ); @@ -347,7 +340,7 @@ begin csr_wdata_i => xcsr_wdata, -- write data csr_rdata_o => xcsr_rdata_pmp, -- read data -- address input -- - addr_if_i => fetch_pc, -- instruction fetch address + addr_if_i => pc_fetch, -- instruction fetch address addr_ls_i => alu_add, -- load/store address -- faults -- fault_ex_o => pmp_ex_fault, -- instruction fetch fault From be5eeaadbdafb8a40de69be54733e16c33f79bbf Mon Sep 17 00:00:00 2001 From: stnolting Date: Fri, 20 Sep 2024 16:08:44 +0200 Subject: [PATCH 5/7] [control] signal renamings to make the code more readable; minor code optimizations --- rtl/core/neorv32_cpu_control.vhd | 193 +++++++++++++++---------------- 1 file changed, 91 insertions(+), 102 deletions(-) diff --git a/rtl/core/neorv32_cpu_control.vhd b/rtl/core/neorv32_cpu_control.vhd index 09a66224f..43a3b8132 100644 --- a/rtl/core/neorv32_cpu_control.vhd +++ b/rtl/core/neorv32_cpu_control.vhd @@ -65,18 +65,18 @@ entity neorv32_cpu_control is rstn_i : in std_ulogic; -- global reset, low-active, async ctrl_o : out ctrl_bus_t; -- main control bus -- instruction fetch interface -- - i_pmp_fault_i : in std_ulogic; -- instruction fetch pmp fault - bus_req_o : out bus_req_t; -- request - bus_rsp_i : in bus_rsp_t; -- response + ibus_pmperr_i : in std_ulogic; -- instruction fetch pmp fault + ibus_req_o : out bus_req_t; -- request + ibus_rsp_i : in bus_rsp_t; -- response -- data path interface -- alu_cp_done_i : in std_ulogic; -- ALU iterative operation done - cmp_i : in std_ulogic_vector(1 downto 0); -- comparator status + alu_cmp_i : in std_ulogic_vector(1 downto 0); -- comparator status alu_add_i : in std_ulogic_vector(XLEN-1 downto 0); -- ALU address result - rs1_i : in std_ulogic_vector(XLEN-1 downto 0); -- rf source 1 - imm_o : out std_ulogic_vector(XLEN-1 downto 0); -- immediate - fetch_pc_o : out std_ulogic_vector(XLEN-1 downto 0); -- instruction fetch address - curr_pc_o : out std_ulogic_vector(XLEN-1 downto 0); -- current PC (corresponding to current instruction) - link_pc_o : out std_ulogic_vector(XLEN-1 downto 0); -- link PC (return address) + alu_imm_o : out std_ulogic_vector(XLEN-1 downto 0); -- immediate + rf_rs1_i : in std_ulogic_vector(XLEN-1 downto 0); -- rf source 1 + pc_fetch_o : out std_ulogic_vector(XLEN-1 downto 0); -- instruction fetch address + pc_curr_o : out std_ulogic_vector(XLEN-1 downto 0); -- current PC (corresponding to current instruction) + pc_next_o : out std_ulogic_vector(XLEN-1 downto 0); -- next PC (return address) csr_rdata_o : out std_ulogic_vector(XLEN-1 downto 0); -- CSR read data -- external CSR interface -- xcsr_we_o : out std_ulogic; -- global write enable @@ -84,18 +84,13 @@ entity neorv32_cpu_control is xcsr_wdata_o : out std_ulogic_vector(XLEN-1 downto 0); -- write data xcsr_rdata_i : in std_ulogic_vector(XLEN-1 downto 0); -- read data -- interrupts -- - db_halt_req_i : in std_ulogic; -- debug mode (halt) request - msi_i : in std_ulogic; -- machine software interrupt - mei_i : in std_ulogic; -- machine external interrupt - mti_i : in std_ulogic; -- machine timer interrupt - firq_i : in std_ulogic_vector(15 downto 0); -- fast interrupts - -- data access interface -- + irq_dbg_i : in std_ulogic; -- debug mode (halt) request + irq_machine_i : in std_ulogic_vector(2 downto 0); -- risc-v mti, mei, msi + irq_fast_i : in std_ulogic_vector(15 downto 0); -- fast interrupts + -- load/store unit interface -- lsu_wait_i : in std_ulogic; -- wait for data bus - mar_i : in std_ulogic_vector(XLEN-1 downto 0); -- memory address register - ma_load_i : in std_ulogic; -- misaligned load data address - ma_store_i : in std_ulogic; -- misaligned store data address - be_load_i : in std_ulogic; -- bus error on load data access - be_store_i : in std_ulogic -- bus error on store data access + lsu_mar_i : in std_ulogic_vector(XLEN-1 downto 0); -- memory address register + lsu_err_i : in std_ulogic_vector(3 downto 0) -- alignment/access errors ); end neorv32_cpu_control; @@ -163,7 +158,6 @@ architecture neorv32_cpu_control_rtl of neorv32_cpu_control is pc : std_ulogic_vector(XLEN-1 downto 0); -- actual PC, corresponding to current executed instruction pc_we : std_ulogic; -- PC update enable next_pc : std_ulogic_vector(XLEN-1 downto 0); -- next PC, corresponding to next instruction to be executed - link_pc : std_ulogic_vector(XLEN-1 downto 0); -- next PC for linking (return address) end record; signal execute_engine : execute_engine_t; @@ -282,11 +276,7 @@ architecture neorv32_cpu_control_rtl of neorv32_cpu_control is -- debug-mode controller -- type debug_ctrl_t is record - running : std_ulogic; -- CPU is in debug mode - trig_hw : std_ulogic; -- hardware trigger - trig_break : std_ulogic; -- ebreak instruction trigger - trig_halt : std_ulogic; -- external request trigger - trig_step : std_ulogic; -- single-stepping mode trigger + running, trig_hw, trig_break, trig_halt, trig_step : std_ulogic; -- single-stepping mode trigger end record; signal debug_ctrl : debug_ctrl_t; @@ -301,9 +291,9 @@ architecture neorv32_cpu_control_rtl of neorv32_cpu_control is begin --- **************************************************************************************************************************** --- Instruction Fetch (always fetch 32-bit-aligned 32-bit chunks of data) --- **************************************************************************************************************************** + -- **************************************************************************************************************************** + -- Instruction Fetch (always fetch 32-bit-aligned 32-bit chunks of data) + -- **************************************************************************************************************************** -- Fetch Engine FSM ----------------------------------------------------------------------- -- ------------------------------------------------------------------------------------------- @@ -356,18 +346,18 @@ begin end process fetch_engine_fsm; -- PC output for instruction fetch -- - bus_req_o.addr <= fetch_engine.pc(XLEN-1 downto 2) & "00"; -- word aligned - fetch_pc_o <= fetch_engine.pc(XLEN-1 downto 2) & "00"; -- word aligned + ibus_req_o.addr <= fetch_engine.pc(XLEN-1 downto 2) & "00"; -- word aligned + pc_fetch_o <= fetch_engine.pc(XLEN-1 downto 2) & "00"; -- word aligned -- instruction fetch (read) request if IPB not full -- - bus_req_o.stb <= '1' when (fetch_engine.state = IF_REQUEST) and (ipb.free = "11") else '0'; + ibus_req_o.stb <= '1' when (fetch_engine.state = IF_REQUEST) and (ipb.free = "11") else '0'; -- instruction bus response -- - fetch_engine.resp <= bus_rsp_i.ack or bus_rsp_i.err; + fetch_engine.resp <= ibus_rsp_i.ack or ibus_rsp_i.err; -- IPB instruction data and status -- - ipb.wdata(0) <= (bus_rsp_i.err or i_pmp_fault_i) & bus_rsp_i.data(15 downto 0); - ipb.wdata(1) <= (bus_rsp_i.err or i_pmp_fault_i) & bus_rsp_i.data(31 downto 16); + ipb.wdata(0) <= (ibus_rsp_i.err or ibus_pmperr_i) & ibus_rsp_i.data(15 downto 0); + ipb.wdata(1) <= (ibus_rsp_i.err or ibus_pmperr_i) & ibus_rsp_i.data(31 downto 16); -- IPB write enable -- ipb.we(0) <= '1' when (fetch_engine.state = IF_PENDING) and (fetch_engine.resp = '1') and @@ -375,13 +365,13 @@ begin ipb.we(1) <= '1' when (fetch_engine.state = IF_PENDING) and (fetch_engine.resp = '1') else '0'; -- bus access type -- - bus_req_o.priv <= fetch_engine.priv; -- current effective privilege level - bus_req_o.data <= (others => '0'); -- read-only - bus_req_o.ben <= (others => '0'); -- read-only - bus_req_o.rw <= '0'; -- read-only - bus_req_o.src <= '1'; -- source = instruction fetch - bus_req_o.rvso <= '0'; -- cannot be a reservation set operation - bus_req_o.fence <= ctrl.lsu_fence; -- fence operation, valid without STB being set + ibus_req_o.priv <= fetch_engine.priv; -- current effective privilege level + ibus_req_o.data <= (others => '0'); -- read-only + ibus_req_o.ben <= (others => '0'); -- read-only + ibus_req_o.rw <= '0'; -- read-only + ibus_req_o.src <= '1'; -- source = instruction fetch + ibus_req_o.rvso <= '0'; -- cannot be a reservation set operation + ibus_req_o.fence <= ctrl.lsu_fence; -- fence operation, valid without STB being set -- Instruction Prefetch Buffer (FIFO) ----------------------------------------------------- @@ -414,9 +404,9 @@ begin end generate; --- **************************************************************************************************************************** --- Instruction Issue (decompress 16-bit instructions and assemble a 32-bit instruction word) --- **************************************************************************************************************************** + -- **************************************************************************************************************************** + -- Instruction Issue (decompress 16-bit instructions and assemble a 32-bit instruction word) + -- **************************************************************************************************************************** issue_engine_enabled: if CPU_EXTENSION_RISCV_C generate @@ -497,37 +487,37 @@ begin ipb.re(1) <= issue_engine.valid(1) and issue_engine.ack; --- **************************************************************************************************************************** --- Instruction Execution --- **************************************************************************************************************************** + -- **************************************************************************************************************************** + -- Instruction Execution + -- **************************************************************************************************************************** -- Immediate Generator -------------------------------------------------------------------- -- ------------------------------------------------------------------------------------------- imm_gen: process(rstn_i, clk_i) begin if (rstn_i = '0') then - imm_o <= (others => '0'); + alu_imm_o <= (others => '0'); elsif rising_edge(clk_i) then if (execute_engine.state = DISPATCH) then -- prepare update of next_pc (using ALU's PC + IMM in EXECUTE state) - imm_o <= (others => '0'); + alu_imm_o <= (others => '0'); if CPU_EXTENSION_RISCV_C and (issue_engine.data(33) = '1') then -- is de-compressed C instruction? - imm_o(3 downto 0) <= x"2"; + alu_imm_o(3 downto 0) <= x"2"; else - imm_o(3 downto 0) <= x"4"; + alu_imm_o(3 downto 0) <= x"4"; end if; else - imm_o <= replicate_f(execute_engine.ir(31), 21) & execute_engine.ir(30 downto 21) & execute_engine.ir(20); -- default: I-immediate + alu_imm_o <= replicate_f(execute_engine.ir(31), 21) & execute_engine.ir(30 downto 21) & execute_engine.ir(20); -- default: I-immediate case decode_aux.opcode is when opcode_store_c => -- S-immediate - imm_o <= replicate_f(execute_engine.ir(31), 21) & execute_engine.ir(30 downto 25) & execute_engine.ir(11 downto 7); + alu_imm_o <= replicate_f(execute_engine.ir(31), 21) & execute_engine.ir(30 downto 25) & execute_engine.ir(11 downto 7); when opcode_branch_c => -- B-immediate - imm_o <= replicate_f(execute_engine.ir(31), 20) & execute_engine.ir(7) & execute_engine.ir(30 downto 25) & execute_engine.ir(11 downto 8) & '0'; + alu_imm_o <= replicate_f(execute_engine.ir(31), 20) & execute_engine.ir(7) & execute_engine.ir(30 downto 25) & execute_engine.ir(11 downto 8) & '0'; when opcode_lui_c | opcode_auipc_c => -- U-immediate - imm_o <= execute_engine.ir(31 downto 12) & x"000"; + alu_imm_o <= execute_engine.ir(31 downto 12) & x"000"; when opcode_jal_c => -- J-immediate - imm_o <= replicate_f(execute_engine.ir(31), 12) & execute_engine.ir(19 downto 12) & execute_engine.ir(20) & execute_engine.ir(30 downto 21) & '0'; + alu_imm_o <= replicate_f(execute_engine.ir(31), 12) & execute_engine.ir(19 downto 12) & execute_engine.ir(20) & execute_engine.ir(30 downto 21) & '0'; when opcode_amo_c => -- atomic memory access - if CPU_EXTENSION_RISCV_A then imm_o <= (others => '0'); end if; + if CPU_EXTENSION_RISCV_A then alu_imm_o <= (others => '0'); end if; when others => NULL; -- use default end case; @@ -538,13 +528,13 @@ begin -- Branch Condition Check ----------------------------------------------------------------- -- ------------------------------------------------------------------------------------------- - branch_check: process(execute_engine.ir, cmp_i) + branch_check: process(execute_engine.ir, alu_cmp_i) begin if (execute_engine.ir(instr_opcode_lsb_c+2) = '0') then -- conditional branch if (execute_engine.ir(instr_funct3_msb_c) = '0') then -- beq / bne - execute_engine.branch_taken <= cmp_i(cmp_equal_c) xor execute_engine.ir(instr_funct3_lsb_c); + execute_engine.branch_taken <= alu_cmp_i(cmp_equal_c) xor execute_engine.ir(instr_funct3_lsb_c); else -- blt(u) / bge(u) - execute_engine.branch_taken <= cmp_i(cmp_less_c) xor execute_engine.ir(instr_funct3_lsb_c); + execute_engine.branch_taken <= alu_cmp_i(cmp_less_c) xor execute_engine.ir(instr_funct3_lsb_c); end if; else -- unconditional branch execute_engine.branch_taken <= '1'; @@ -563,7 +553,7 @@ begin execute_engine.is_ci <= '0'; execute_engine.pc <= CPU_BOOT_ADDR(XLEN-1 downto 2) & "00"; -- 32-bit-aligned boot address execute_engine.next_pc <= CPU_BOOT_ADDR(XLEN-1 downto 2) & "00"; -- 32-bit-aligned boot address - execute_engine.link_pc <= (others => '0'); + pc_next_o <= (others => '0'); elsif rising_edge(clk_i) then -- control bus -- ctrl <= ctrl_nxt; @@ -578,17 +568,12 @@ begin execute_engine.pc <= execute_engine.next_pc(XLEN-1 downto 1) & '0'; end if; - -- link PC: return address -- - if (execute_engine.state = BRANCH) then - execute_engine.link_pc <= execute_engine.next_pc(XLEN-1 downto 1) & '0'; - else -- output zero if not a branch instruction - execute_engine.link_pc <= (others => '0'); - end if; - -- next PC: address of next instruction -- + pc_next_o <= (others => '0'); -- output zero if not a branch instruction case execute_engine.state is when TRAP_ENTER => -- starting trap environment + -- ------------------------------------------------------------ if (trap_ctrl.cause(5) = '1') and CPU_EXTENSION_RISCV_Sdext then -- debug mode (re-)entry execute_engine.next_pc <= CPU_DEBUG_PARK_ADDR(XLEN-1 downto 2) & "00"; -- debug mode enter; start at "parking loop" elsif (debug_ctrl.running = '1') and CPU_EXTENSION_RISCV_Sdext then -- any other trap INSIDE debug mode @@ -602,6 +587,7 @@ begin end if; when TRAP_EXIT => -- leaving trap environment + -- ------------------------------------------------------------ if (debug_ctrl.running = '1') and CPU_EXTENSION_RISCV_Sdext then -- debug mode exit execute_engine.next_pc <= csr.dpc(XLEN-1 downto 1) & '0'; else -- normal end of trap @@ -609,14 +595,18 @@ begin end if; when BRANCH => -- branch instruction + -- ------------------------------------------------------------ + pc_next_o <= execute_engine.next_pc(XLEN-1 downto 1) & '0'; -- output as link/return address if (trap_ctrl.exc_buf(exc_illegal_c) = '0') and (execute_engine.branch_taken = '1') then -- valid taken branch execute_engine.next_pc <= alu_add_i(XLEN-1 downto 1) & '0'; end if; when EXECUTE => -- linear increment (use ALU's adder to compute next_pc = current_pc + imm (2/4)) + -- ------------------------------------------------------------ execute_engine.next_pc <= alu_add_i(XLEN-1 downto 1) & '0'; when others => -- no update + -- ------------------------------------------------------------ NULL; end case; @@ -628,9 +618,8 @@ begin (execute_engine.branch_taken = '1') and -- branch is taken (alu_add_i(1) = '1') and (not CPU_EXTENSION_RISCV_C) else '0'; -- misaligned destination - -- PC output -- - curr_pc_o <= execute_engine.pc(XLEN-1 downto 1) & '0'; -- current PC - link_pc_o <= execute_engine.link_pc(XLEN-1 downto 1) & '0'; -- jump-and-link return address + -- current PC output -- + pc_curr_o <= execute_engine.pc(XLEN-1 downto 1) & '0'; -- Decoding Helper Logic ------------------------------------------------------------------ @@ -985,9 +974,9 @@ begin ctrl_o.cpu_debug <= debug_ctrl.running; --- **************************************************************************************************************************** --- Illegal Instruction Detection --- **************************************************************************************************************************** + -- **************************************************************************************************************************** + -- Illegal Instruction Detection + -- **************************************************************************************************************************** -- Instruction Execution Monitor (trap if multi-cycle instruction does not complete) ------ -- ------------------------------------------------------------------------------------------- @@ -1226,9 +1215,9 @@ begin (execute_engine.ir(instr_opcode_lsb_c+1 downto instr_opcode_lsb_c) /= "11")) else '0'; -- illegal opcode LSBs? --- **************************************************************************************************************************** --- Trap Controller --- **************************************************************************************************************************** + -- **************************************************************************************************************************** + -- Trap Controller + -- **************************************************************************************************************************** -- Exception Buffer ----------------------------------------------------------------------- -- ------------------------------------------------------------------------------------------- @@ -1246,13 +1235,13 @@ begin -- ---------------------------------------------------------------------- -- misaligned load/store/instruction address -- - trap_ctrl.exc_buf(exc_lalign_c) <= (trap_ctrl.exc_buf(exc_lalign_c) or ma_load_i) and (not trap_ctrl.env_enter); - trap_ctrl.exc_buf(exc_salign_c) <= (trap_ctrl.exc_buf(exc_salign_c) or ma_store_i) and (not trap_ctrl.env_enter); + trap_ctrl.exc_buf(exc_lalign_c) <= (trap_ctrl.exc_buf(exc_lalign_c) or lsu_err_i(0)) and (not trap_ctrl.env_enter); + trap_ctrl.exc_buf(exc_salign_c) <= (trap_ctrl.exc_buf(exc_salign_c) or lsu_err_i(2)) and (not trap_ctrl.env_enter); trap_ctrl.exc_buf(exc_ialign_c) <= (trap_ctrl.exc_buf(exc_ialign_c) or trap_ctrl.instr_ma) and (not trap_ctrl.env_enter); -- load/store/instruction access fault -- - trap_ctrl.exc_buf(exc_laccess_c) <= (trap_ctrl.exc_buf(exc_laccess_c) or be_load_i) and (not trap_ctrl.env_enter); - trap_ctrl.exc_buf(exc_saccess_c) <= (trap_ctrl.exc_buf(exc_saccess_c) or be_store_i) and (not trap_ctrl.env_enter); + trap_ctrl.exc_buf(exc_laccess_c) <= (trap_ctrl.exc_buf(exc_laccess_c) or lsu_err_i(1)) and (not trap_ctrl.env_enter); + trap_ctrl.exc_buf(exc_saccess_c) <= (trap_ctrl.exc_buf(exc_saccess_c) or lsu_err_i(3)) and (not trap_ctrl.env_enter); trap_ctrl.exc_buf(exc_iaccess_c) <= (trap_ctrl.exc_buf(exc_iaccess_c) or trap_ctrl.instr_be) and (not trap_ctrl.env_enter); -- illegal instruction & environment call -- @@ -1291,12 +1280,12 @@ begin -- ---------------------------------------------------------------------- -- RISC-V machine interrupts -- - trap_ctrl.irq_pnd(irq_msi_irq_c) <= msi_i; - trap_ctrl.irq_pnd(irq_mei_irq_c) <= mei_i; - trap_ctrl.irq_pnd(irq_mti_irq_c) <= mti_i; + trap_ctrl.irq_pnd(irq_msi_irq_c) <= irq_machine_i(0); + trap_ctrl.irq_pnd(irq_mei_irq_c) <= irq_machine_i(1); + trap_ctrl.irq_pnd(irq_mti_irq_c) <= irq_machine_i(2); -- NEORV32-specific fast interrupts -- - trap_ctrl.irq_pnd(irq_firq_15_c downto irq_firq_0_c) <= firq_i(15 downto 0); + trap_ctrl.irq_pnd(irq_firq_15_c downto irq_firq_0_c) <= irq_fast_i(15 downto 0); -- debug-mode entry -- trap_ctrl.irq_pnd(irq_db_halt_c) <= '0'; -- unused @@ -1450,9 +1439,9 @@ begin trap_ctrl.wakeup <= or_reduce_f(trap_ctrl.irq_buf) or debug_ctrl.running or csr.dcsr_step; --- **************************************************************************************************************************** --- Control and Status Registers (CSRs) --- **************************************************************************************************************************** + -- **************************************************************************************************************************** + -- Control and Status Registers (CSRs) + -- **************************************************************************************************************************** -- CSR Address Register ------------------------------------------------------------------- -- ------------------------------------------------------------------------------------------- @@ -1473,7 +1462,7 @@ begin -- CSR Write-Data ALU --------------------------------------------------------------------- -- ------------------------------------------------------------------------------------------- - csr_write_data: process(execute_engine.ir, csr.rdata, rs1_i) + csr_write_data: process(execute_engine.ir, csr.rdata, rf_rs1_i) variable tmp_v : std_ulogic_vector(XLEN-1 downto 0); begin -- immediate/register operand -- @@ -1481,7 +1470,7 @@ begin tmp_v := (others => '0'); tmp_v(4 downto 0) := execute_engine.ir(19 downto 15); -- uimm5 else - tmp_v := rs1_i; + tmp_v := rf_rs1_i; end if; -- tiny ALU to compute CSR write data -- case execute_engine.ir(instr_funct3_msb_c-1 downto instr_funct3_lsb_c) is @@ -1665,7 +1654,7 @@ begin csr.mepc <= trap_ctrl.epc(XLEN-1 downto 1) & '0'; -- trap PC -- trap value -- if (trap_ctrl.cause(6) = '0') and (trap_ctrl.cause(2) = '1') then -- load/store misaligned/access faults [hacky!] - csr.mtval <= mar_i; -- faulting data access address + csr.mtval <= lsu_mar_i; -- faulting data access address else -- everything else including all interrupts csr.mtval <= (others => '0'); end if; @@ -2020,9 +2009,9 @@ begin csr_rdata_o <= csr.rdata; --- **************************************************************************************************************************** --- CPU Counters (Base Counters and Hardware Performance Monitors) --- **************************************************************************************************************************** + -- **************************************************************************************************************************** + -- CPU Counters (Base Counters and Hardware Performance Monitors) + -- **************************************************************************************************************************** -- Counter CSRs --------------------------------------------------------------------------- -- ------------------------------------------------------------------------------------------- @@ -2187,9 +2176,9 @@ begin cnt_event(hpmcnt_event_trap_c) <= '1' when (trap_ctrl.env_enter = '1') else '0'; -- entered trap --- **************************************************************************************************************************** --- CPU Debug Mode (Part of the On-Chip Debugger) --- **************************************************************************************************************************** + -- **************************************************************************************************************************** + -- CPU Debug Mode (Part of the On-Chip Debugger) + -- **************************************************************************************************************************** -- Debug Control -------------------------------------------------------------------------- -- ------------------------------------------------------------------------------------------- @@ -2218,7 +2207,7 @@ begin debug_ctrl.trig_break <= trap_ctrl.ebreak and (debug_ctrl.running or -- re-enter debug mode (( csr.privilege) and csr.dcsr_ebreakm) or -- enabled goto-debug-mode in machine mode on "ebreak" ((not csr.privilege) and csr.dcsr_ebreaku)); -- enabled goto-debug-mode in user mode on "ebreak" - debug_ctrl.trig_halt <= db_halt_req_i and (not debug_ctrl.running); -- external halt request (if not halted already) + debug_ctrl.trig_halt <= irq_dbg_i and (not debug_ctrl.running); -- external halt request (if not halted already) debug_ctrl.trig_step <= csr.dcsr_step and (not debug_ctrl.running); -- single-step mode (trigger when NOT CURRENTLY in debug mode) end generate; @@ -2253,9 +2242,9 @@ begin csr.dcsr_rd(1 downto 0) <= (others => csr.dcsr_prv); -- prv: privilege mode when debug mode was entered --- **************************************************************************************************************************** --- Hardware Trigger Module --- **************************************************************************************************************************** + -- **************************************************************************************************************************** + -- Hardware Trigger Module + -- **************************************************************************************************************************** trigger_module_enable: if CPU_EXTENSION_RISCV_Sdtrig generate From e29e053dcc334544b49a265d83b9f0c883cb5275 Mon Sep 17 00:00:00 2001 From: stnolting Date: Fri, 20 Sep 2024 16:08:57 +0200 Subject: [PATCH 6/7] [package] update version ID --- rtl/core/neorv32_package.vhd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rtl/core/neorv32_package.vhd b/rtl/core/neorv32_package.vhd index e86ecd7e6..01814c8a1 100644 --- a/rtl/core/neorv32_package.vhd +++ b/rtl/core/neorv32_package.vhd @@ -29,7 +29,7 @@ package neorv32_package is -- Architecture Constants ----------------------------------------------------------------- -- ------------------------------------------------------------------------------------------- - constant hw_version_c : std_ulogic_vector(31 downto 0) := x"01100400"; -- hardware version + constant hw_version_c : std_ulogic_vector(31 downto 0) := x"01100401"; -- hardware version constant archid_c : natural := 19; -- official RISC-V architecture ID constant XLEN : natural := 32; -- native data path width From bba1652ef771a5b391a791a2650ccd052c8f2380 Mon Sep 17 00:00:00 2001 From: stnolting Date: Fri, 20 Sep 2024 16:17:39 +0200 Subject: [PATCH 7/7] [changelog] add v1.10.4.1 --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 69caba676..1c5051d11 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -29,6 +29,7 @@ mimpid = 0x01040312 -> Version 01.04.03.12 -> v1.4.3.12 | Date | Version | Comment | Ticket | |:----:|:-------:|:--------|:------:| +| 20.09.2024 | 1.10.4.1 | rtl signal renamings to make the code more readable | [#1026](https://github.com/stnolting/neorv32/pull/1026) | | 16.09.2024 | [**:rocket:1.10.4**](https://github.com/stnolting/neorv32/releases/tag/v1.10.4) | **New release** | | | 15.09.2024 | 1.10.3.10 | :bug: SW: fix stack-alignment (has to be 128-bit-aligned) before entering the very first procedure (`main`) | [#1021](https://github.com/stnolting/neorv32/pull/1021) | | 14.09.2024 | 1.10.3.9 | massive rtl code cleanup | [#1019](https://github.com/stnolting/neorv32/pull/1019) |