Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[rtl] minor cleanups and optimizations #764

Merged
merged 11 commits into from
Jan 15, 2024
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ mimpid = 0x01040312 -> Version 01.04.03.12 -> v1.4.3.12

| Date | Version | Comment | Link |
|:----:|:-------:|:--------|:----:|
| 14.01.2024 | 1.9.3.1 | minor rtl cleanups and optimizations | [#764](https://github.com/stnolting/neorv32/pull/764) |
| 11.01.2024 | [**:rocket:1.9.3**](https://github.com/stnolting/neorv32/releases/tag/v1.9.3) | **New release** | |
| 10.01.2024 | 1.9.2.11 | minor HDL fix (introduced in v1.9.2.9) | [#763](https://github.com/stnolting/neorv32/pull/763) |
| 10.01.2024 | 1.9.2.10 | re-add MTIME system time output to processor top (`mtime_time_o`) | [#762](https://github.com/stnolting/neorv32/pull/762) |
Expand Down
12 changes: 6 additions & 6 deletions rtl/core/neorv32_cfs.vhd
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
-- # ********************************************************************************************* #
-- # BSD 3-Clause License #
-- # #
-- # Copyright (c) 2023, Stephan Nolting. All rights reserved. #
-- # Copyright (c) 2024, Stephan Nolting. All rights reserved. #
-- # #
-- # Redistribution and use in source and binary forms, with or without modification, are #
-- # permitted provided that the following conditions are met: #
Expand Down Expand Up @@ -55,13 +55,13 @@ entity neorv32_cfs is
port (
clk_i : in std_ulogic; -- global clock line
rstn_i : in std_ulogic; -- global reset line, low-active, use as async
bus_req_i : in bus_req_t; -- bus request
bus_rsp_o : out bus_rsp_t; -- bus response
clkgen_en_o : out std_ulogic; -- enable clock generator
bus_req_i : in bus_req_t; -- bus request
bus_rsp_o : out bus_rsp_t := rsp_terminate_c; -- bus response
clkgen_en_o : out std_ulogic := '0'; -- enable clock generator
clkgen_i : in std_ulogic_vector(7 downto 0); -- "clock" inputs
irq_o : out std_ulogic; -- interrupt request
irq_o : out std_ulogic := '0'; -- interrupt request
cfs_in_i : in std_ulogic_vector(CFS_IN_SIZE-1 downto 0); -- custom inputs
cfs_out_o : out std_ulogic_vector(CFS_OUT_SIZE-1 downto 0) -- custom outputs
cfs_out_o : out std_ulogic_vector(CFS_OUT_SIZE-1 downto 0) := (others => '0') -- custom outputs
);
end neorv32_cfs;

Expand Down
71 changes: 43 additions & 28 deletions rtl/core/neorv32_cpu_alu.vhd
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,11 @@ architecture neorv32_cpu_cpu_rtl of neorv32_cpu_alu is
signal cp_valid : std_ulogic_vector(5 downto 0); -- co-processor done
signal cp_shamt : std_ulogic_vector(index_size_f(XLEN)-1 downto 0); -- shift amount

-- CSR proxy --
signal fpu_csr_en, cfu_csr_en : std_ulogic;
signal fpu_csr_we, cfu_csr_we : std_ulogic;
signal fpu_csr_rd, cfu_csr_rd : std_ulogic_vector(XLEN-1 downto 0);

-- CSR read-backs --
signal csr_rdata_fpu, csr_rdata_cfu : std_ulogic_vector(XLEN-1 downto 0);

Expand Down Expand Up @@ -268,24 +273,29 @@ begin
neorv32_cpu_cp_fpu_inst: entity neorv32.neorv32_cpu_cp_fpu
port map (
-- global control --
clk_i => clk_i, -- global clock, rising edge
rstn_i => rstn_i, -- global reset, low-active, async
ctrl_i => ctrl_i, -- main control bus
start_i => cp_start(3), -- trigger operation
clk_i => clk_i, -- global clock, rising edge
rstn_i => rstn_i, -- global reset, low-active, async
ctrl_i => ctrl_i, -- main control bus
start_i => cp_start(3), -- trigger operation
-- CSR interface --
csr_we_i => csr_we_i, -- global write enable
csr_addr_i => csr_addr_i, -- address
csr_wdata_i => csr_wdata_i, -- write data
csr_rdata_o => csr_rdata_fpu, -- read data
csr_we_i => fpu_csr_we, -- write enable
csr_addr_i => csr_addr_i(1 downto 0), -- address
csr_wdata_i => csr_wdata_i, -- write data
csr_rdata_o => fpu_csr_rd, -- read data
-- data input --
cmp_i => cmp, -- comparator status
rs1_i => rs1_i, -- rf source 1
rs2_i => rs2_i, -- rf source 2
rs3_i => rs3_i, -- rf source 3
cmp_i => cmp, -- comparator status
rs1_i => rs1_i, -- rf source 1
rs2_i => rs2_i, -- rf source 2
rs3_i => rs3_i, -- rf source 3
-- result and status --
res_o => cp_result(3), -- operation result
valid_o => cp_valid(3) -- data output valid
res_o => cp_result(3), -- operation result
valid_o => cp_valid(3) -- data output valid
);

-- CSR proxy --
fpu_csr_en <= '1' when (csr_addr_i(11 downto 2) = csr_fflags_c(11 downto 2)) else '0';
fpu_csr_we <= fpu_csr_en and csr_we_i;
csr_rdata_fpu <= fpu_csr_rd when (fpu_csr_en = '1') else (others => '0');
end generate;

neorv32_cpu_cp_fpu_inst_false:
Expand All @@ -303,24 +313,29 @@ begin
neorv32_cpu_cp_cfu_inst: entity neorv32.neorv32_cpu_cp_cfu
port map (
-- global control --
clk_i => clk_i, -- global clock, rising edge
rstn_i => rstn_i, -- global reset, low-active, async
ctrl_i => ctrl_i, -- main control bus
start_i => cp_start(4), -- trigger operation
clk_i => clk_i, -- global clock, rising edge
rstn_i => rstn_i, -- global reset, low-active, async
ctrl_i => ctrl_i, -- main control bus
start_i => cp_start(4), -- trigger operation
-- CSR interface --
csr_we_i => csr_we_i, -- global write enable
csr_addr_i => csr_addr_i, -- address
csr_wdata_i => csr_wdata_i, -- write data
csr_rdata_o => csr_rdata_cfu, -- read data
csr_we_i => cfu_csr_we, -- write enable
csr_addr_i => csr_addr_i(1 downto 0), -- address
csr_wdata_i => csr_wdata_i, -- write data
csr_rdata_o => cfu_csr_rd, -- read data
-- data input --
rs1_i => rs1_i, -- rf source 1
rs2_i => rs2_i, -- rf source 2
rs3_i => rs3_i, -- rf source 3
rs4_i => rs4_i, -- rf source 4
rs1_i => rs1_i, -- rf source 1
rs2_i => rs2_i, -- rf source 2
rs3_i => rs3_i, -- rf source 3
rs4_i => rs4_i, -- rf source 4
-- result and status --
res_o => cp_result(4), -- operation result
valid_o => cp_valid(4) -- data output valid
res_o => cp_result(4), -- operation result
valid_o => cp_valid(4) -- data output valid
);

-- CSR proxy --
cfu_csr_en <= '1' when (csr_addr_i(11 downto 2) = csr_cfureg0_c(11 downto 2)) else '0';
cfu_csr_we <= cfu_csr_en and csr_we_i;
csr_rdata_cfu <= cfu_csr_rd when (cfu_csr_en = '1') else (others => '0');
end generate;

neorv32_cpu_cp_cfu_inst_false:
Expand Down
31 changes: 12 additions & 19 deletions rtl/core/neorv32_cpu_control.vhd
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
-- # ********************************************************************************************* #
-- # BSD 3-Clause License #
-- # #
-- # Copyright (c) 2023, Stephan Nolting. All rights reserved. #
-- # Copyright (c) 2024, Stephan Nolting. All rights reserved. #
-- # #
-- # Redistribution and use in source and binary forms, with or without modification, are #
-- # permitted provided that the following conditions are met: #
Expand Down Expand Up @@ -137,7 +137,6 @@ architecture neorv32_cpu_control_rtl of neorv32_cpu_control is
state : fetch_engine_state_t;
state_prev : fetch_engine_state_t;
restart : std_ulogic; -- buffered restart request (after branch)
unaligned : std_ulogic; -- fetching from non-32-bit address
pc : std_ulogic_vector(XLEN-1 downto 0);
reset : std_ulogic; -- restart request (after branch)
resp : std_ulogic; -- bus response
Expand Down Expand Up @@ -362,7 +361,6 @@ begin
fetch_engine.state <= IF_RESTART;
fetch_engine.state_prev <= IF_RESTART;
fetch_engine.restart <= '1'; -- set to reset IPB
fetch_engine.unaligned <= '0';
fetch_engine.pc <= CPU_BOOT_ADDR(XLEN-1 downto 2) & "00"; -- 32-bit aligned boot address
elsif rising_edge(clk_i) then
-- previous state (for HPMs only) --
Expand All @@ -378,13 +376,7 @@ begin
-- fsm --
case fetch_engine.state is

when IF_RESTART => -- set new fetch start address
-- ------------------------------------------------------------
fetch_engine.pc <= execute_engine.next_pc(XLEN-1 downto 2) & "00"; -- initialize with logical PC, word aligned
fetch_engine.unaligned <= execute_engine.next_pc(1);
fetch_engine.state <= IF_REQUEST;

when IF_REQUEST => -- request new 32-bit-aligned instruction word
when IF_REQUEST => -- request next 32-bit-aligned instruction word
-- ------------------------------------------------------------
if (ipb.free = "11") then -- wait for free IPB space
fetch_engine.state <= IF_PENDING;
Expand All @@ -395,32 +387,33 @@ begin
when IF_PENDING => -- wait for bus response and write instruction data to prefetch buffer
-- ------------------------------------------------------------
if (fetch_engine.resp = '1') then -- wait for bus response
fetch_engine.pc <= std_ulogic_vector(unsigned(fetch_engine.pc) + 4); -- next word
fetch_engine.unaligned <= '0';
if (fetch_engine.restart = '1') or (fetch_engine.reset = '1') then -- restart request (fast) due to branch
fetch_engine.pc <= std_ulogic_vector(unsigned(fetch_engine.pc) + 4); -- next word
fetch_engine.pc(1) <= '0'; -- (re-)align to 32-bit
if (fetch_engine.restart = '1') or (fetch_engine.reset = '1') then -- restart request due to branch
fetch_engine.state <= IF_RESTART;
else -- request next linear instruction word
fetch_engine.state <= IF_REQUEST;
end if;
end if;

when IF_PARKED => -- park position: instruction fetch is halted (CPU in sleep mode)
when IF_PARKED => -- park position: instruction fetch is halted for sleep mode
-- ------------------------------------------------------------
if (execute_engine.state /= SLEEP) then
fetch_engine.state <= IF_REQUEST;
end if;

when others => -- undefined
when others => -- IF_RESTART: set new start address
-- ------------------------------------------------------------
fetch_engine.state <= IF_RESTART;
fetch_engine.pc <= execute_engine.next_pc(XLEN-1 downto 1) & '0'; -- initialize from PC incl. 16-bit-alignment bit
fetch_engine.state <= IF_REQUEST;

end case;
end if;
end process fetch_engine_fsm;

-- PC output for instruction fetch --
bus_req_o.addr <= fetch_engine.pc; -- word aligned
fetch_pc_o <= fetch_engine.pc; -- word aligned
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

-- 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';
Expand All @@ -434,7 +427,7 @@ begin

-- IPB write enable --
ipb.we(0) <= '1' when (fetch_engine.state = IF_PENDING) and (fetch_engine.resp = '1') and
((fetch_engine.unaligned = '0') or (CPU_EXTENSION_RISCV_C = false)) else '0';
((fetch_engine.pc(1) = '0') or (CPU_EXTENSION_RISCV_C = false)) else '0';
ipb.we(1) <= '1' when (fetch_engine.state = IF_PENDING) and (fetch_engine.resp = '1') else '0';

-- bus access type --
Expand Down
Loading