Skip to content

Commit

Permalink
[rtl] minor cleanups and optimizations (#764)
Browse files Browse the repository at this point in the history
  • Loading branch information
stnolting committed Jan 15, 2024
2 parents 0ab5863 + cdbf8ed commit 5da9d52
Show file tree
Hide file tree
Showing 12 changed files with 162 additions and 156 deletions.
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

0 comments on commit 5da9d52

Please sign in to comment.