mirror of
https://github.com/stnolting/neorv32.git
synced 2025-04-24 22:27:21 -04:00
[rtl] minor GPTMR code reworks (#529)
This commit is contained in:
commit
747fcd5577
5 changed files with 39 additions and 49 deletions
|
@ -31,7 +31,8 @@ mimpid = 0x01040312 => Version 01.04.03.12 => v1.4.3.12
|
|||
|
||||
| Date (*dd.mm.yyyy*) | Version | Comment |
|
||||
|:-------------------:|:-------:|:--------|
|
||||
| 02.03.2023 | 1.8.1.4 | :bug: fix timeout bug in **FPU** (conversion and add/sub instructions); #528 |
|
||||
| 02.03.2023 | 1.8.1.5 | minor general purpose timer (GPTMR) code edits; [#529](https://github.com/stnolting/neorv32/pull/529) |
|
||||
| 02.03.2023 | 1.8.1.4 | :bug: fix timeout bug in **FPU** (conversion and add/sub instructions); [#528](https://github.com/stnolting/neorv32/pull/528) |
|
||||
| 25.02.2023 | 1.8.1.3 | :sparkles: add new processor module: **Serial Data Interface (SDI)** - a SPI _device-class_ interface; [#505](https://github.com/stnolting/neorv32/pull/505) |
|
||||
| 24.02.2023 | 1.8.1.2 | :warning: rename top interface signals of **XIP** and **SIP** modules; [#504](https://github.com/stnolting/neorv32/pull/504) |
|
||||
| 23.02.2023 | 1.8.1.1 | CFS: add another 32 interface register (now having 64 memory-mapped registers for custom usage); [#503](https://github.com/stnolting/neorv32/pull/503) |
|
||||
|
|
|
@ -46,8 +46,8 @@ writing zero to it.
|
|||
|
||||
**Timer Interrupt**
|
||||
|
||||
The timer interrupt is triggered when the timer is enabled and `COUNT` matches `THRES`. The interrupt
|
||||
remains pending until explicitly cleared by writing zero to the according <<_mip>> CSR bit.
|
||||
The GPTMR interrupt is triggered when the timer is enabled and `COUNT` matches `THRES`. The interrupt
|
||||
remains pending inside the CPU until it explicitly cleared by writing zero to the according <<_mip>> CSR bit.
|
||||
|
||||
|
||||
**Register Map**
|
||||
|
|
|
@ -84,34 +84,22 @@ architecture neorv32_gptmr_rtl of neorv32_gptmr is
|
|||
signal wren : std_ulogic; -- word write enable
|
||||
signal rden : std_ulogic; -- read enable
|
||||
|
||||
-- clock generator --
|
||||
signal gptmr_clk_en : std_ulogic;
|
||||
|
||||
-- timer core --
|
||||
type timer_t is record
|
||||
count : std_ulogic_vector(31 downto 0); -- counter register
|
||||
thres : std_ulogic_vector(31 downto 0); -- threshold value
|
||||
tick : std_ulogic; -- clock generator tick
|
||||
match : std_ulogic; -- count == thres
|
||||
cnt_we : std_ulogic; -- write access to count
|
||||
end record;
|
||||
signal timer : timer_t;
|
||||
|
||||
-- interrupt detector --
|
||||
signal irq_detect : std_ulogic_vector(1 downto 0);
|
||||
|
||||
begin
|
||||
|
||||
-- Access Control -------------------------------------------------------------------------
|
||||
-- Host Access ----------------------------------------------------------------------------
|
||||
-- -------------------------------------------------------------------------------------------
|
||||
acc_en <= '1' when (addr_i(hi_abb_c downto lo_abb_c) = gptmr_base_c(hi_abb_c downto lo_abb_c)) else '0';
|
||||
addr <= gptmr_base_c(31 downto lo_abb_c) & addr_i(lo_abb_c-1 downto 2) & "00"; -- word aligned
|
||||
wren <= acc_en and wren_i;
|
||||
rden <= acc_en and rden_i;
|
||||
|
||||
|
||||
-- Write Access ---------------------------------------------------------------------------
|
||||
-- -------------------------------------------------------------------------------------------
|
||||
write_access: process(rstn_i, clk_i)
|
||||
-- write access --
|
||||
process(rstn_i, clk_i)
|
||||
begin
|
||||
if (rstn_i = '0') then
|
||||
timer.cnt_we <= '0';
|
||||
|
@ -135,18 +123,10 @@ begin
|
|||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process write_access;
|
||||
end process;
|
||||
|
||||
-- clock generator enable --
|
||||
clkgen_en_o <= ctrl(ctrl_en_c);
|
||||
|
||||
-- clock select --
|
||||
gptmr_clk_en <= clkgen_i(to_integer(unsigned(ctrl(ctrl_prsc2_c downto ctrl_prsc0_c))));
|
||||
|
||||
|
||||
-- Read Access ----------------------------------------------------------------------------
|
||||
-- -------------------------------------------------------------------------------------------
|
||||
read_access: process(clk_i)
|
||||
-- read access --
|
||||
process(clk_i)
|
||||
begin
|
||||
if rising_edge(clk_i) then
|
||||
ack_o <= rden or wren; -- bus access acknowledge
|
||||
|
@ -166,19 +146,25 @@ begin
|
|||
end case;
|
||||
end if;
|
||||
end if;
|
||||
end process read_access;
|
||||
end process;
|
||||
|
||||
-- access control --
|
||||
acc_en <= '1' when (addr_i(hi_abb_c downto lo_abb_c) = gptmr_base_c(hi_abb_c downto lo_abb_c)) else '0';
|
||||
addr <= gptmr_base_c(31 downto lo_abb_c) & addr_i(lo_abb_c-1 downto 2) & "00"; -- word aligned
|
||||
wren <= acc_en and wren_i;
|
||||
rden <= acc_en and rden_i;
|
||||
|
||||
|
||||
-- Timer Core -----------------------------------------------------------------------------
|
||||
-- -------------------------------------------------------------------------------------------
|
||||
timer_core: process(rstn_i, clk_i)
|
||||
process(rstn_i, clk_i)
|
||||
begin
|
||||
if (rstn_i = '0') then
|
||||
timer.count <= (others => '0');
|
||||
elsif rising_edge(clk_i) then
|
||||
if (timer.cnt_we = '1') then -- write access
|
||||
timer.count <= data_i; -- data_i will stay unchanged for min. 1 cycle after WREN has returned to low again
|
||||
elsif (ctrl(ctrl_en_c) = '1') and (gptmr_clk_en = '1') then -- enabled and clock tick
|
||||
elsif (ctrl(ctrl_en_c) = '1') and (timer.tick = '1') then -- enabled and clock tick
|
||||
if (timer.match = '1') then
|
||||
if (ctrl(ctrl_mode_c) = '1') then -- reset counter if continuous mode
|
||||
timer.count <= (others => '0');
|
||||
|
@ -188,27 +174,29 @@ begin
|
|||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process timer_core;
|
||||
end process;
|
||||
|
||||
-- counter = threshold? --
|
||||
timer.match <= '1' when (timer.count = timer.thres) else '0';
|
||||
|
||||
-- clock generator enable --
|
||||
clkgen_en_o <= ctrl(ctrl_en_c);
|
||||
|
||||
-- Interrupt Generator --------------------------------------------------------------------
|
||||
-- -------------------------------------------------------------------------------------------
|
||||
irq_generator: process(clk_i)
|
||||
-- clock select --
|
||||
process(clk_i)
|
||||
begin
|
||||
if rising_edge(clk_i) then
|
||||
if (ctrl(ctrl_en_c) = '0') then
|
||||
irq_detect <= "00";
|
||||
else
|
||||
irq_detect <= irq_detect(0) & timer.match;
|
||||
end if;
|
||||
timer.tick <= clkgen_i(to_integer(unsigned(ctrl(ctrl_prsc2_c downto ctrl_prsc0_c))));
|
||||
end if;
|
||||
end process irq_generator;
|
||||
end process;
|
||||
|
||||
-- IRQ request to CPU --
|
||||
irq_o <= '1' when (irq_detect = "01") else '0';
|
||||
-- interrupt --
|
||||
process(clk_i)
|
||||
begin
|
||||
if rising_edge(clk_i) then
|
||||
irq_o <= ctrl(ctrl_en_c) and timer.match;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
|
||||
end neorv32_gptmr_rtl;
|
||||
|
|
|
@ -65,7 +65,7 @@ package neorv32_package is
|
|||
|
||||
-- Architecture Constants (do not modify!) ------------------------------------------------
|
||||
-- -------------------------------------------------------------------------------------------
|
||||
constant hw_version_c : std_ulogic_vector(31 downto 0) := x"01080104"; -- NEORV32 version
|
||||
constant hw_version_c : std_ulogic_vector(31 downto 0) := x"01080105"; -- NEORV32 version
|
||||
constant archid_c : natural := 19; -- official RISC-V architecture ID
|
||||
|
||||
-- Check if we're inside the Matrix -------------------------------------------------------
|
||||
|
|
|
@ -64,10 +64,10 @@ void gptmr_firq_handler(void);
|
|||
**************************************************************************/
|
||||
int main() {
|
||||
|
||||
// capture all exceptions and give debug info via UART
|
||||
// setup NEORV32 runtime environment (for trap handling)
|
||||
neorv32_rte_setup();
|
||||
|
||||
// init UART at default baud rate, no parity bits, no HW flow control
|
||||
// setup UART at default baud rate, no parity bits, no HW flow control
|
||||
neorv32_uart0_setup(BAUD_RATE, PARITY_NONE, FLOW_CONTROL_NONE);
|
||||
|
||||
|
||||
|
@ -93,7 +93,8 @@ int main() {
|
|||
neorv32_gptmr_setup(CLK_PRSC_8, 1, NEORV32_SYSINFO->CLK / (8 * 2));
|
||||
|
||||
// enable interrupt
|
||||
neorv32_cpu_csr_set(CSR_MIE, 1 << GPTMR_FIRQ_ENABLE); // enable GPTMR FIRQ channel
|
||||
neorv32_cpu_csr_clr(CSR_MIP, 1 << GPTMR_FIRQ_PENDING); // make sure there is no GPTMR IRQ pending already
|
||||
neorv32_cpu_csr_set(CSR_MIE, 1 << GPTMR_FIRQ_ENABLE); // enable GPTMR FIRQ channel
|
||||
neorv32_cpu_csr_set(CSR_MSTATUS, 1 << CSR_MSTATUS_MIE); // enable machine-mode interrupts
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue