mirror of
https://github.com/stnolting/neorv32.git
synced 2025-04-24 14:17:51 -04:00
Add "out-of-band" signals to internal bus interface (#1131)
This commit is contained in:
commit
a4935d249f
17 changed files with 219 additions and 141 deletions
|
@ -29,6 +29,7 @@ mimpid = 0x01040312 -> Version 01.04.03.12 -> v1.4.3.12
|
||||||
|
|
||||||
| Date | Version | Comment | Ticket |
|
| Date | Version | Comment | Ticket |
|
||||||
|:----:|:-------:|:--------|:------:|
|
|:----:|:-------:|:--------|:------:|
|
||||||
|
| 27.12.2024 | 1.10.8.2 | add out-of-band signals to internal request bus | [#1131](https://github.com/stnolting/neorv32/pull/1131) |
|
||||||
| 27.12.2024 | 1.10.8.1 | :warning: replace MTIME by CLINT; :warning: remove `HART_ID` generic | [#1130](https://github.com/stnolting/neorv32/pull/1130) |
|
| 27.12.2024 | 1.10.8.1 | :warning: replace MTIME by CLINT; :warning: remove `HART_ID` generic | [#1130](https://github.com/stnolting/neorv32/pull/1130) |
|
||||||
| 26.12.2024 | [**:rocket:1.10.8**](https://github.com/stnolting/neorv32/releases/tag/v1.10.8) | **New release** | |
|
| 26.12.2024 | [**:rocket:1.10.8**](https://github.com/stnolting/neorv32/releases/tag/v1.10.8) | **New release** | |
|
||||||
| 23.12.2024 | 1.10.7.9 | :warning: rework IO/peripheral address space; :sparkles: increase device size from 256 bytes to 64kB | [#1126](https://github.com/stnolting/neorv32/pull/1126) |
|
| 23.12.2024 | 1.10.7.9 | :warning: rework IO/peripheral address space; :sparkles: increase device size from 256 bytes to 64kB | [#1126](https://github.com/stnolting/neorv32/pull/1126) |
|
||||||
|
|
|
@ -68,8 +68,6 @@ direction as seen from the CPU.
|
||||||
4+^| **Global Signals**
|
4+^| **Global Signals**
|
||||||
| `clk_i` | 1 | in | Global clock line, all registers triggering on rising edge.
|
| `clk_i` | 1 | in | Global clock line, all registers triggering on rising edge.
|
||||||
| `rstn_i` | 1 | in | Global reset, low-active.
|
| `rstn_i` | 1 | in | Global reset, low-active.
|
||||||
| `sleep_o` | 1 | out | CPU is in <<_sleep_mode>> when set.
|
|
||||||
| `debug_o` | 1 | out | CPU is in <<_cpu_debug_mode,debug mode>> when set.
|
|
||||||
4+^| **Interrupts (<<_traps_exceptions_and_interrupts>>)**
|
4+^| **Interrupts (<<_traps_exceptions_and_interrupts>>)**
|
||||||
| `msi_i` | 1 | in | RISC-V machine software interrupt.
|
| `msi_i` | 1 | in | RISC-V machine software interrupt.
|
||||||
| `mei_i` | 1 | in | RISC-V machine external interrupt.
|
| `mei_i` | 1 | in | RISC-V machine external interrupt.
|
||||||
|
@ -342,7 +340,7 @@ The `wfi` instruction will raise an illegal instruction exception when executed
|
||||||
if `TW` in <<_mstatus>> is set. When executed in debug-mode or during single-stepping `wfi` will behave as
|
if `TW` in <<_mstatus>> is set. When executed in debug-mode or during single-stepping `wfi` will behave as
|
||||||
simple `nop` without entering sleep mode.
|
simple `nop` without entering sleep mode.
|
||||||
|
|
||||||
After executing the `wfi` instruction the CPU's `sleep_o` signal (<<_cpu_top_entity_signals>>) will become set
|
After executing the `wfi` instruction the `sleep` signal of the CPU's request buses (<<_bus_interface>> will become set
|
||||||
as soon as the CPU has fully halted:
|
as soon as the CPU has fully halted:
|
||||||
|
|
||||||
[start=1]
|
[start=1]
|
||||||
|
@ -393,15 +391,22 @@ the instruction fetch interface (`i_bus_*` signals) is used for fetching instruc
|
||||||
(`d_bus_*` signals) is used to access data via load and store operations. Each of these interfaces can access an address
|
(`d_bus_*` signals) is used to access data via load and store operations. Each of these interfaces can access an address
|
||||||
space of up to 2^32^ bytes (4GB).
|
space of up to 2^32^ bytes (4GB).
|
||||||
|
|
||||||
The bus interface uses two custom interface types: `bus_req_t` is used to propagate the bus access **requests**. These
|
The bus interface uses two custom interface types: `bus_req_t` is used to propagate the bus access requests downstream
|
||||||
signals are driven by the _accessing_ device (i.e. the CPU core). `bus_rsp_t` is used to return the bus **response** and
|
from a host to a device. These signals are driven by the request-issuing device (i.e. the CPU core). Vice versa, `bus_rsp_t`
|
||||||
is driven by the _accessed_ device or bus system (i.e. a processor-internal memory or IO device).
|
is used to return the bus response upstream from a device back to the host and is driven by the accessed device or bus system
|
||||||
|
(i.e. a processor-internal memory or IO device).
|
||||||
|
|
||||||
|
The signals of the request bus are split in to two categories: _in-band_ signals and _out-of-band_ signals. In-band
|
||||||
|
signals always belong to a certain bus transaction and are only valid between `stb` being set and the according response
|
||||||
|
(`err` or `ack`). being set. In contrast, the out-of-band signals are not associated with any bus transaction and are
|
||||||
|
always valid when set.
|
||||||
|
|
||||||
.Bus Interface - Request Bus (`bus_req_t`)
|
.Bus Interface - Request Bus (`bus_req_t`)
|
||||||
[cols="^1,^1,<6"]
|
[cols="^1,^1,<6"]
|
||||||
[options="header",grid="rows"]
|
[options="header",grid="rows"]
|
||||||
|=======================
|
|=======================
|
||||||
| Signal | Width | Description
|
| Signal | Width | Description
|
||||||
|
3+^| **In-Band Signals**
|
||||||
| `addr` | 32 | Access address (byte addressing)
|
| `addr` | 32 | Access address (byte addressing)
|
||||||
| `data` | 32 | Write data
|
| `data` | 32 | Write data
|
||||||
| `ben` | 4 | Byte-enable for each byte in `data`
|
| `ben` | 4 | Byte-enable for each byte in `data`
|
||||||
|
@ -410,7 +415,10 @@ is driven by the _accessed_ device or bus system (i.e. a processor-internal memo
|
||||||
| `src` | 1 | Access source (`0` = instruction fetch, `1` = load/store)
|
| `src` | 1 | Access source (`0` = instruction fetch, `1` = load/store)
|
||||||
| `priv` | 1 | Set if privileged (M-mode) access
|
| `priv` | 1 | Set if privileged (M-mode) access
|
||||||
| `rvso` | 1 | Set if current access is a reservation-set operation (`lr` or `sc` instruction, <<_zalrsc_isa_extension>>)
|
| `rvso` | 1 | Set if current access is a reservation-set operation (`lr` or `sc` instruction, <<_zalrsc_isa_extension>>)
|
||||||
| `fence` | 1 | Data/instruction fence operation; valid without `stb` being set
|
3+^| **Out-Of-Band Signals**
|
||||||
|
| `fence` | 1 | Data/instruction fence request; single-shot
|
||||||
|
| `sleep` | 1 | Set if ALL upstream devices are in <<_sleep_mode>>
|
||||||
|
| `debug` | 1 | Set if the upstream device is in debug-mode
|
||||||
|=======================
|
|=======================
|
||||||
|
|
||||||
.Bus Interface - Response Bus (`bus_rsp_t`)
|
.Bus Interface - Response Bus (`bus_rsp_t`)
|
||||||
|
@ -444,7 +452,7 @@ The figure below shows three exemplary bus accesses:
|
||||||
. A write access to address `B_addr` writing `wdata` (fastest response; `ACK` arrives right in the next cycle).
|
. A write access to address `B_addr` writing `wdata` (fastest response; `ACK` arrives right in the next cycle).
|
||||||
. A failing read access to address `C_addr` (slow response; `ERR` arrives after several cycles).
|
. A failing read access to address `C_addr` (slow response; `ERR` arrives after several cycles).
|
||||||
|
|
||||||
.Three Exemplary Bus Transactions
|
.Three Exemplary Bus Transactions (showing only in-band signals)
|
||||||
image::bus_interface.png[700]
|
image::bus_interface.png[700]
|
||||||
|
|
||||||
.Adding Register Stages
|
.Adding Register Stages
|
||||||
|
@ -478,7 +486,7 @@ and also registers a reservation for the address `addr` (`rvs_valid` becomes set
|
||||||
invalidated (`rvs_valid` is `0`) the store access fails, so `wdata2` is **not** written to address `addr` at all. The failed
|
invalidated (`rvs_valid` is `0`) the store access fails, so `wdata2` is **not** written to address `addr` at all. The failed
|
||||||
operation is indicated by a **1** being returned via `rsp.data` together with `ack`.
|
operation is indicated by a **1** being returned via `rsp.data` together with `ack`.
|
||||||
|
|
||||||
.Three Exemplary LR/SC Bus Transactions
|
.Three Exemplary LR/SC Bus Transactions (showing only in-band signals)
|
||||||
image::bus_interface_atomic.png[700]
|
image::bus_interface_atomic.png[700]
|
||||||
|
|
||||||
.Store-Conditional Status
|
.Store-Conditional Status
|
||||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 53 KiB After Width: | Height: | Size: 52 KiB |
Binary file not shown.
Before Width: | Height: | Size: 56 KiB After Width: | Height: | Size: 57 KiB |
|
@ -10,7 +10,6 @@
|
||||||
{name: 'src', wave: 'x0.|.x0.x..|..'},
|
{name: 'src', wave: 'x0.|.x0.x..|..'},
|
||||||
{name: 'priv', wave: 'x0.|.x0.x..|..'},
|
{name: 'priv', wave: 'x0.|.x0.x..|..'},
|
||||||
{name: 'rvso', wave: 'x0.|.x0.x..|..'},
|
{name: 'rvso', wave: 'x0.|.x0.x..|..'},
|
||||||
{name: 'fence', wave: '0....|.....|..'},
|
|
||||||
],
|
],
|
||||||
{},
|
{},
|
||||||
[
|
[
|
||||||
|
|
|
@ -10,7 +10,6 @@
|
||||||
{name: 'src', wave: '0....|.....|.....'},
|
{name: 'src', wave: '0....|.....|.....'},
|
||||||
{name: 'priv', wave: '0....|.....|.....'},
|
{name: 'priv', wave: '0....|.....|.....'},
|
||||||
{name: 'rvso', wave: '01..0|.1..0|.1..0', node: '.b.......e....'},
|
{name: 'rvso', wave: '01..0|.1..0|.1..0', node: '.b.......e....'},
|
||||||
{name: 'fence', wave: '0....|.....|.....'},
|
|
||||||
],
|
],
|
||||||
{},
|
{},
|
||||||
[
|
[
|
||||||
|
|
|
@ -19,14 +19,15 @@ use neorv32.neorv32_package.all;
|
||||||
|
|
||||||
entity neorv32_bus_switch is
|
entity neorv32_bus_switch is
|
||||||
generic (
|
generic (
|
||||||
PORT_A_READ_ONLY : boolean; -- set if port A is read-only
|
ROUND_ROBIN_EN : boolean := false; -- enable round-robing scheduling
|
||||||
PORT_B_READ_ONLY : boolean -- set if port B is read-only
|
PORT_A_READ_ONLY : boolean := false; -- set if port A is read-only
|
||||||
|
PORT_B_READ_ONLY : boolean := false -- set if port B is read-only
|
||||||
);
|
);
|
||||||
port (
|
port (
|
||||||
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
|
||||||
a_lock_i : in std_ulogic; -- exclusive access for port A while set
|
a_lock_i : in std_ulogic; -- exclusive access for port A while set
|
||||||
a_req_i : in bus_req_t; -- host port A request bus (PRIORITIZED)
|
a_req_i : in bus_req_t; -- host port A request bus
|
||||||
a_rsp_o : out bus_rsp_t; -- host port A response bus
|
a_rsp_o : out bus_rsp_t; -- host port A response bus
|
||||||
b_req_i : in bus_req_t; -- host port B request bus
|
b_req_i : in bus_req_t; -- host port B request bus
|
||||||
b_rsp_o : out bus_rsp_t; -- host port B response bus
|
b_rsp_o : out bus_rsp_t; -- host port B response bus
|
||||||
|
@ -38,17 +39,10 @@ end neorv32_bus_switch;
|
||||||
architecture neorv32_bus_switch_rtl of neorv32_bus_switch is
|
architecture neorv32_bus_switch_rtl of neorv32_bus_switch is
|
||||||
|
|
||||||
-- access arbiter --
|
-- access arbiter --
|
||||||
type arbiter_t is record
|
type state_t is (S_CHECK_A, S_BUSY_A, S_CHECK_B, S_BUSY_B);
|
||||||
state, state_nxt : std_ulogic_vector(1 downto 0);
|
signal state, state_nxt : state_t;
|
||||||
a_req, b_req : std_ulogic;
|
signal a_req, b_req : std_ulogic;
|
||||||
sel, stb : std_ulogic;
|
signal sel, stb : std_ulogic;
|
||||||
end record;
|
|
||||||
signal arbiter : arbiter_t;
|
|
||||||
|
|
||||||
-- FSM states --
|
|
||||||
constant IDLE : std_ulogic_vector(1 downto 0) := "00";
|
|
||||||
constant BUSY_A : std_ulogic_vector(1 downto 0) := "01";
|
|
||||||
constant BUSY_B : std_ulogic_vector(1 downto 0) := "10";
|
|
||||||
|
|
||||||
begin
|
begin
|
||||||
|
|
||||||
|
@ -57,86 +51,158 @@ begin
|
||||||
arbiter_sync: process(rstn_i, clk_i)
|
arbiter_sync: process(rstn_i, clk_i)
|
||||||
begin
|
begin
|
||||||
if (rstn_i = '0') then
|
if (rstn_i = '0') then
|
||||||
arbiter.state <= IDLE;
|
state <= S_CHECK_A;
|
||||||
arbiter.a_req <= '0';
|
a_req <= '0';
|
||||||
arbiter.b_req <= '0';
|
b_req <= '0';
|
||||||
elsif rising_edge(clk_i) then
|
elsif rising_edge(clk_i) then
|
||||||
arbiter.state <= arbiter.state_nxt;
|
state <= state_nxt;
|
||||||
arbiter.a_req <= (arbiter.a_req or a_req_i.stb) and (not arbiter.state(0)); -- clear STB buffer in BUSY_A
|
if (state = S_BUSY_A) then -- clear request
|
||||||
arbiter.b_req <= (arbiter.b_req or b_req_i.stb) and (not arbiter.state(1)); -- clear STB buffer in BUSY_B
|
a_req <= '0';
|
||||||
|
else -- buffer request
|
||||||
|
a_req <= a_req or a_req_i.stb;
|
||||||
|
end if;
|
||||||
|
if (state = S_BUSY_B) then -- clear request
|
||||||
|
b_req <= '0';
|
||||||
|
else -- buffer request
|
||||||
|
b_req <= b_req or b_req_i.stb;
|
||||||
|
end if;
|
||||||
end if;
|
end if;
|
||||||
end process arbiter_sync;
|
end process arbiter_sync;
|
||||||
|
|
||||||
-- fsm --
|
|
||||||
arbiter_comb: process(arbiter, a_lock_i, a_req_i, b_req_i, x_rsp_i)
|
|
||||||
begin
|
|
||||||
-- defaults --
|
|
||||||
arbiter.state_nxt <= arbiter.state;
|
|
||||||
arbiter.sel <= '0';
|
|
||||||
arbiter.stb <= '0';
|
|
||||||
|
|
||||||
-- state machine --
|
-- Prioritizing Bus Switch ----------------------------------------------------------------
|
||||||
case arbiter.state is
|
-- -------------------------------------------------------------------------------------------
|
||||||
|
arbiter_prioritized:
|
||||||
|
if not ROUND_ROBIN_EN generate
|
||||||
|
arbiter_fsm: process(state, a_req, b_req, a_lock_i, a_req_i, b_req_i, x_rsp_i)
|
||||||
|
begin
|
||||||
|
-- defaults --
|
||||||
|
state_nxt <= state;
|
||||||
|
sel <= '0';
|
||||||
|
stb <= '0';
|
||||||
|
|
||||||
when BUSY_A => -- port A access in progress
|
-- state machine --
|
||||||
-- ------------------------------------------------------------
|
case state is
|
||||||
arbiter.sel <= '0';
|
|
||||||
if (x_rsp_i.err = '1') or (x_rsp_i.ack = '1') then
|
|
||||||
arbiter.state_nxt <= IDLE;
|
|
||||||
end if;
|
|
||||||
|
|
||||||
when BUSY_B => -- port B access in progress
|
when S_BUSY_A => -- port A access in progress
|
||||||
-- ------------------------------------------------------------
|
-- ------------------------------------------------------------
|
||||||
arbiter.sel <= '1';
|
sel <= '0';
|
||||||
if (x_rsp_i.err = '1') or (x_rsp_i.ack = '1') then
|
if (x_rsp_i.err = '1') or (x_rsp_i.ack = '1') then
|
||||||
arbiter.state_nxt <= IDLE;
|
state_nxt <= S_CHECK_A;
|
||||||
end if;
|
end if;
|
||||||
|
|
||||||
when others => -- IDLE: wait for requests
|
when S_BUSY_B => -- port B access in progress
|
||||||
-- ------------------------------------------------------------
|
-- ------------------------------------------------------------
|
||||||
if (a_req_i.stb = '1') or (arbiter.a_req = '1') then -- request from port A (prioritized)?
|
sel <= '1';
|
||||||
arbiter.sel <= '0';
|
if (x_rsp_i.err = '1') or (x_rsp_i.ack = '1') then
|
||||||
arbiter.stb <= '1';
|
state_nxt <= S_CHECK_A;
|
||||||
arbiter.state_nxt <= BUSY_A;
|
end if;
|
||||||
elsif ((b_req_i.stb = '1') or (arbiter.b_req = '1')) and (a_lock_i = '0') then -- request from port B?
|
|
||||||
arbiter.sel <= '1';
|
|
||||||
arbiter.stb <= '1';
|
|
||||||
arbiter.state_nxt <= BUSY_B;
|
|
||||||
end if;
|
|
||||||
|
|
||||||
end case;
|
when others => -- wait for requests
|
||||||
end process arbiter_comb;
|
-- ------------------------------------------------------------
|
||||||
|
if (a_req_i.stb = '1') or (a_req = '1') then -- request from port A (prioritized)?
|
||||||
|
sel <= '0';
|
||||||
|
stb <= '1';
|
||||||
|
state_nxt <= S_BUSY_A;
|
||||||
|
elsif ((b_req_i.stb = '1') or (b_req = '1')) and (a_lock_i = '0') then -- request from port B?
|
||||||
|
sel <= '1';
|
||||||
|
stb <= '1';
|
||||||
|
state_nxt <= S_BUSY_B;
|
||||||
|
end if;
|
||||||
|
|
||||||
|
end case;
|
||||||
|
end process arbiter_fsm;
|
||||||
|
end generate;
|
||||||
|
|
||||||
|
|
||||||
|
-- Round-Robin Arbiter --------------------------------------------------------------------
|
||||||
|
-- -------------------------------------------------------------------------------------------
|
||||||
|
arbiter_round_robin:
|
||||||
|
if ROUND_ROBIN_EN generate
|
||||||
|
arbiter_fsm: process(state, a_req, b_req, a_req_i, b_req_i, x_rsp_i)
|
||||||
|
begin
|
||||||
|
-- defaults --
|
||||||
|
state_nxt <= state;
|
||||||
|
sel <= '0';
|
||||||
|
stb <= '0';
|
||||||
|
|
||||||
|
-- state machine --
|
||||||
|
case state is
|
||||||
|
|
||||||
|
when S_CHECK_A => -- check if access from port A
|
||||||
|
-- ------------------------------------------------------------
|
||||||
|
sel <= '0';
|
||||||
|
if (a_req_i.stb = '1') or (a_req = '1') then
|
||||||
|
stb <= '1';
|
||||||
|
state_nxt <= S_BUSY_A;
|
||||||
|
else
|
||||||
|
state_nxt <= S_CHECK_B;
|
||||||
|
end if;
|
||||||
|
|
||||||
|
when S_BUSY_A => -- port B access in progress
|
||||||
|
-- ------------------------------------------------------------
|
||||||
|
sel <= '0';
|
||||||
|
if (x_rsp_i.err = '1') or (x_rsp_i.ack = '1') then
|
||||||
|
state_nxt <= S_CHECK_B;
|
||||||
|
end if;
|
||||||
|
|
||||||
|
when S_CHECK_B => -- check if access from port B
|
||||||
|
-- ------------------------------------------------------------
|
||||||
|
sel <= '1';
|
||||||
|
if (b_req_i.stb = '1') or (b_req = '1') then
|
||||||
|
stb <= '1';
|
||||||
|
state_nxt <= S_BUSY_B;
|
||||||
|
else
|
||||||
|
state_nxt <= S_CHECK_A;
|
||||||
|
end if;
|
||||||
|
|
||||||
|
when S_BUSY_B => -- port B access in progress
|
||||||
|
-- ------------------------------------------------------------
|
||||||
|
sel <= '1';
|
||||||
|
if (x_rsp_i.err = '1') or (x_rsp_i.ack = '1') then
|
||||||
|
state_nxt <= S_CHECK_A;
|
||||||
|
end if;
|
||||||
|
|
||||||
|
when others => -- undefined
|
||||||
|
-- ------------------------------------------------------------
|
||||||
|
state_nxt <= S_CHECK_A;
|
||||||
|
|
||||||
|
end case;
|
||||||
|
end process arbiter_fsm;
|
||||||
|
end generate;
|
||||||
|
|
||||||
|
|
||||||
-- Request Switch -------------------------------------------------------------------------
|
-- Request Switch -------------------------------------------------------------------------
|
||||||
-- -------------------------------------------------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
||||||
x_req_o.addr <= a_req_i.addr when (arbiter.sel = '0') else b_req_i.addr;
|
x_req_o.addr <= a_req_i.addr when (sel = '0') else b_req_i.addr;
|
||||||
x_req_o.rvso <= a_req_i.rvso when (arbiter.sel = '0') else b_req_i.rvso;
|
x_req_o.rvso <= a_req_i.rvso when (sel = '0') else b_req_i.rvso;
|
||||||
x_req_o.priv <= a_req_i.priv when (arbiter.sel = '0') else b_req_i.priv;
|
x_req_o.priv <= a_req_i.priv when (sel = '0') else b_req_i.priv;
|
||||||
x_req_o.src <= a_req_i.src when (arbiter.sel = '0') else b_req_i.src;
|
x_req_o.src <= a_req_i.src when (sel = '0') else b_req_i.src;
|
||||||
x_req_o.rw <= a_req_i.rw when (arbiter.sel = '0') else b_req_i.rw;
|
x_req_o.rw <= a_req_i.rw when (sel = '0') else b_req_i.rw;
|
||||||
x_req_o.fence <= a_req_i.fence or b_req_i.fence; -- propagate any fence operations
|
x_req_o.fence <= a_req_i.fence or b_req_i.fence; -- propagate any fence request
|
||||||
|
x_req_o.sleep <= a_req_i.sleep and b_req_i.sleep; -- set if ALL upstream devices are in sleep mode
|
||||||
|
x_req_o.debug <= a_req_i.debug when (sel = '0') else b_req_i.debug;
|
||||||
|
|
||||||
x_req_o.data <= b_req_i.data when PORT_A_READ_ONLY else
|
x_req_o.data <= b_req_i.data when PORT_A_READ_ONLY else
|
||||||
a_req_i.data when PORT_B_READ_ONLY else
|
a_req_i.data when PORT_B_READ_ONLY else
|
||||||
a_req_i.data when (arbiter.sel = '0') else b_req_i.data;
|
a_req_i.data when (sel = '0') else b_req_i.data;
|
||||||
|
|
||||||
x_req_o.ben <= b_req_i.ben when PORT_A_READ_ONLY else
|
x_req_o.ben <= b_req_i.ben when PORT_A_READ_ONLY else
|
||||||
a_req_i.ben when PORT_B_READ_ONLY else
|
a_req_i.ben when PORT_B_READ_ONLY else
|
||||||
a_req_i.ben when (arbiter.sel = '0') else b_req_i.ben;
|
a_req_i.ben when (sel = '0') else b_req_i.ben;
|
||||||
|
|
||||||
x_req_o.stb <= arbiter.stb;
|
x_req_o.stb <= stb;
|
||||||
|
|
||||||
|
|
||||||
-- Response Switch ------------------------------------------------------------------------
|
-- Response Switch ------------------------------------------------------------------------
|
||||||
-- -------------------------------------------------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
||||||
a_rsp_o.data <= x_rsp_i.data;
|
a_rsp_o.data <= x_rsp_i.data;
|
||||||
a_rsp_o.ack <= x_rsp_i.ack when (arbiter.sel = '0') else '0';
|
a_rsp_o.ack <= x_rsp_i.ack when (sel = '0') else '0';
|
||||||
a_rsp_o.err <= x_rsp_i.err when (arbiter.sel = '0') else '0';
|
a_rsp_o.err <= x_rsp_i.err when (sel = '0') else '0';
|
||||||
|
|
||||||
b_rsp_o.data <= x_rsp_i.data;
|
b_rsp_o.data <= x_rsp_i.data;
|
||||||
b_rsp_o.ack <= x_rsp_i.ack when (arbiter.sel = '1') else '0';
|
b_rsp_o.ack <= x_rsp_i.ack when (sel = '1') else '0';
|
||||||
b_rsp_o.err <= x_rsp_i.err when (arbiter.sel = '1') else '0';
|
b_rsp_o.err <= x_rsp_i.err when (sel = '1') else '0';
|
||||||
|
|
||||||
|
|
||||||
end neorv32_bus_switch_rtl;
|
end neorv32_bus_switch_rtl;
|
||||||
|
@ -703,10 +769,10 @@ entity neorv32_bus_reservation_set is
|
||||||
rvs_addr_o : out std_ulogic_vector(31 downto 0);
|
rvs_addr_o : out std_ulogic_vector(31 downto 0);
|
||||||
rvs_valid_o : out std_ulogic;
|
rvs_valid_o : out std_ulogic;
|
||||||
rvs_clear_i : in std_ulogic;
|
rvs_clear_i : in std_ulogic;
|
||||||
-- core/cpu port --
|
-- core port --
|
||||||
core_req_i : in bus_req_t;
|
core_req_i : in bus_req_t;
|
||||||
core_rsp_o : out bus_rsp_t;
|
core_rsp_o : out bus_rsp_t;
|
||||||
-- system ports --
|
-- system port --
|
||||||
sys_req_o : out bus_req_t;
|
sys_req_o : out bus_req_t;
|
||||||
sys_rsp_i : in bus_rsp_t
|
sys_rsp_i : in bus_rsp_t
|
||||||
);
|
);
|
||||||
|
|
|
@ -183,7 +183,7 @@ begin
|
||||||
-- request splitter: cached or direct access --
|
-- request splitter: cached or direct access --
|
||||||
req_splitter: process(host_req_i, dir_acc_d)
|
req_splitter: process(host_req_i, dir_acc_d)
|
||||||
begin
|
begin
|
||||||
-- default: pass-through of all bus signals --
|
-- default: pass-through all bus signals --
|
||||||
cache_req <= host_req_i;
|
cache_req <= host_req_i;
|
||||||
dir_req_d <= host_req_i;
|
dir_req_d <= host_req_i;
|
||||||
-- direct access --
|
-- direct access --
|
||||||
|
@ -826,7 +826,7 @@ begin
|
||||||
|
|
||||||
-- Control Engine FSM Comb ----------------------------------------------------------------
|
-- Control Engine FSM Comb ----------------------------------------------------------------
|
||||||
-- -------------------------------------------------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
||||||
ctrl_engine_comb: process(state, upret, addr, haddr, baddr, bus_rsp_i, cmd_sync_i, cmd_miss_i, rdata_i, dirty_i)
|
ctrl_engine_comb: process(state, upret, addr, haddr, baddr, host_req_i, bus_rsp_i, cmd_sync_i, cmd_miss_i, rdata_i, dirty_i)
|
||||||
begin
|
begin
|
||||||
-- control engine defaults --
|
-- control engine defaults --
|
||||||
state_nxt <= state;
|
state_nxt <= state;
|
||||||
|
@ -845,13 +845,19 @@ begin
|
||||||
new_o <= '0';
|
new_o <= '0';
|
||||||
|
|
||||||
-- bus interface defaults --
|
-- bus interface defaults --
|
||||||
bus_req_o <= req_terminate_c; -- all-zero
|
bus_req_o <= req_terminate_c; -- all-zero
|
||||||
bus_req_o.addr <= addr.tag & addr.idx & addr.ofs & "00"; -- always word-aligned
|
bus_req_o.addr <= addr.tag & addr.idx & addr.ofs & "00"; -- always word-aligned
|
||||||
bus_req_o.data <= rdata_i;
|
bus_req_o.data <= rdata_i;
|
||||||
bus_req_o.ben <= (others => '1'); -- full-word writes only
|
bus_req_o.ben <= (others => '1'); -- full-word writes only
|
||||||
bus_req_o.src <= '0'; -- cache accesses are always "data" accesses
|
bus_req_o.src <= '0'; -- cache accesses are always data accesses
|
||||||
bus_req_o.priv <= '0'; -- cache accesses are always "unprivileged" accesses
|
bus_req_o.priv <= '0'; -- cache accesses are always "unprivileged" accesses
|
||||||
bus_req_o.rvso <= '0'; -- cache accesses can never be a reservation set operation
|
bus_req_o.rvso <= '0'; -- cache accesses can never be a reservation set operation
|
||||||
|
bus_req_o.debug <= host_req_i.debug;
|
||||||
|
if (state = S_IDLE) then
|
||||||
|
bus_req_o.sleep <= host_req_i.sleep;
|
||||||
|
else
|
||||||
|
bus_req_o.sleep <= '0';
|
||||||
|
end if;
|
||||||
|
|
||||||
-- fsm --
|
-- fsm --
|
||||||
case state is
|
case state is
|
||||||
|
|
|
@ -71,8 +71,6 @@ entity neorv32_cpu is
|
||||||
-- global control --
|
-- global control --
|
||||||
clk_i : in std_ulogic; -- switchable global clock, rising edge
|
clk_i : in std_ulogic; -- switchable global clock, rising edge
|
||||||
rstn_i : in std_ulogic; -- global reset, low-active, async
|
rstn_i : in std_ulogic; -- global reset, low-active, async
|
||||||
sleep_o : out std_ulogic; -- cpu is in sleep mode when set
|
|
||||||
debug_o : out std_ulogic; -- cpu is in debug mode when set
|
|
||||||
-- interrupts --
|
-- interrupts --
|
||||||
msi_i : in std_ulogic; -- risc-v machine software interrupt
|
msi_i : in std_ulogic; -- risc-v machine software interrupt
|
||||||
mei_i : in std_ulogic; -- risc-v machine external interrupt
|
mei_i : in std_ulogic; -- risc-v machine external interrupt
|
||||||
|
@ -290,10 +288,6 @@ begin
|
||||||
-- external CSR read-back --
|
-- external CSR read-back --
|
||||||
xcsr_rdata_res <= xcsr_rdata_pmp or xcsr_rdata_alu;
|
xcsr_rdata_res <= xcsr_rdata_pmp or xcsr_rdata_alu;
|
||||||
|
|
||||||
-- CPU state --
|
|
||||||
sleep_o <= ctrl.cpu_sleep;
|
|
||||||
debug_o <= ctrl.cpu_debug;
|
|
||||||
|
|
||||||
|
|
||||||
-- Register File --------------------------------------------------------------------------
|
-- Register File --------------------------------------------------------------------------
|
||||||
-- -------------------------------------------------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
||||||
|
|
|
@ -362,7 +362,7 @@ begin
|
||||||
((fetch_engine.pc(1) = '0') or (not RISCV_ISA_C)) else '0';
|
((fetch_engine.pc(1) = '0') or (not RISCV_ISA_C)) else '0';
|
||||||
ipb.we(1) <= '1' when (fetch_engine.state = IF_PENDING) and (fetch_engine.resp = '1') else '0';
|
ipb.we(1) <= '1' when (fetch_engine.state = IF_PENDING) and (fetch_engine.resp = '1') else '0';
|
||||||
|
|
||||||
-- bus access type --
|
-- bus access meta data --
|
||||||
ibus_req_o.priv <= fetch_engine.priv; -- current effective privilege level
|
ibus_req_o.priv <= fetch_engine.priv; -- current effective privilege level
|
||||||
ibus_req_o.data <= (others => '0'); -- read-only
|
ibus_req_o.data <= (others => '0'); -- read-only
|
||||||
ibus_req_o.ben <= (others => '0'); -- read-only
|
ibus_req_o.ben <= (others => '0'); -- read-only
|
||||||
|
@ -370,6 +370,8 @@ begin
|
||||||
ibus_req_o.src <= '1'; -- source = instruction fetch
|
ibus_req_o.src <= '1'; -- source = instruction fetch
|
||||||
ibus_req_o.rvso <= '0'; -- cannot be a reservation set operation
|
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
|
ibus_req_o.fence <= ctrl.lsu_fence; -- fence operation, valid without STB being set
|
||||||
|
ibus_req_o.sleep <= sleep_mode; -- sleep mode, valid without STB being set
|
||||||
|
ibus_req_o.debug <= debug_ctrl.run; -- debug mode, valid without STB being set
|
||||||
|
|
||||||
|
|
||||||
-- Instruction Prefetch Buffer (FIFO) -----------------------------------------------------
|
-- Instruction Prefetch Buffer (FIFO) -----------------------------------------------------
|
||||||
|
|
|
@ -106,7 +106,9 @@ begin
|
||||||
end process mem_do_reg;
|
end process mem_do_reg;
|
||||||
|
|
||||||
dbus_req_o.src <= '0'; -- 0 = data access
|
dbus_req_o.src <= '0'; -- 0 = data access
|
||||||
dbus_req_o.fence <= ctrl_i.lsu_fence; -- this is valid without STB being set
|
dbus_req_o.fence <= ctrl_i.lsu_fence; -- out-of-band: this is valid without STB being set
|
||||||
|
dbus_req_o.sleep <= ctrl_i.cpu_sleep; -- out-of-band: this is valid without STB being set
|
||||||
|
dbus_req_o.debug <= ctrl_i.cpu_debug; -- out-of-band: this is valid without STB being set
|
||||||
|
|
||||||
|
|
||||||
-- Data Input: Alignment and Sign-Extension -----------------------------------------------
|
-- Data Input: Alignment and Sign-Extension -----------------------------------------------
|
||||||
|
|
|
@ -25,7 +25,6 @@ entity neorv32_debug_dm is
|
||||||
-- global control --
|
-- global control --
|
||||||
clk_i : in std_ulogic; -- global clock line
|
clk_i : in std_ulogic; -- global clock line
|
||||||
rstn_i : in std_ulogic; -- global reset line, low-active
|
rstn_i : in std_ulogic; -- global reset line, low-active
|
||||||
cpu_debug_i : in std_ulogic; -- CPU is in debug mode
|
|
||||||
-- debug module interface (DMI) --
|
-- debug module interface (DMI) --
|
||||||
dmi_req_i : in dmi_req_t; -- request
|
dmi_req_i : in dmi_req_t; -- request
|
||||||
dmi_rsp_o : out dmi_rsp_t; -- response
|
dmi_rsp_o : out dmi_rsp_t; -- response
|
||||||
|
@ -69,6 +68,7 @@ architecture neorv32_debug_dm_rtl of neorv32_debug_dm is
|
||||||
constant addr_progbuf1_c : std_ulogic_vector(6 downto 0) := "0100001";
|
constant addr_progbuf1_c : std_ulogic_vector(6 downto 0) := "0100001";
|
||||||
constant addr_authdata_c : std_ulogic_vector(6 downto 0) := "0110000";
|
constant addr_authdata_c : std_ulogic_vector(6 downto 0) := "0110000";
|
||||||
--constant addr_sbcs_c : std_ulogic_vector(6 downto 0) := "0111000"; -- hardwired to zero
|
--constant addr_sbcs_c : std_ulogic_vector(6 downto 0) := "0111000"; -- hardwired to zero
|
||||||
|
constant addr_haltsum0_c : std_ulogic_vector(6 downto 0) := "1000000";
|
||||||
|
|
||||||
-- DMI access --
|
-- DMI access --
|
||||||
signal dmi_wren, dmi_wren_auth, dmi_rden, dmi_rden_auth : std_ulogic;
|
signal dmi_wren, dmi_wren_auth, dmi_rden, dmi_rden_auth : std_ulogic;
|
||||||
|
@ -666,7 +666,7 @@ begin
|
||||||
end process bus_access;
|
end process bus_access;
|
||||||
|
|
||||||
-- access helpers --
|
-- access helpers --
|
||||||
accen <= cpu_debug_i and bus_req_i.stb; -- allow access only when in debug-mode
|
accen <= bus_req_i.debug and bus_req_i.stb; -- allow access only when in debug-mode
|
||||||
rden <= accen and (not bus_req_i.rw);
|
rden <= accen and (not bus_req_i.rw);
|
||||||
wren <= accen and ( bus_req_i.rw);
|
wren <= accen and ( bus_req_i.rw);
|
||||||
|
|
||||||
|
|
|
@ -310,6 +310,8 @@ begin
|
||||||
dma_req_o.addr <= engine.src_addr when (engine.state = S_READ) else engine.dst_addr;
|
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
|
dma_req_o.rvso <= '0'; -- no reservation set operation possible
|
||||||
dma_req_o.fence <= cfg.enable and cfg.fence and engine.done; -- issue FENCE operation when transfer is done
|
dma_req_o.fence <= cfg.enable and cfg.fence and engine.done; -- issue FENCE operation when transfer is done
|
||||||
|
dma_req_o.sleep <= '1' when (engine.state = S_IDLE) else '0'; -- idle = sleep mode
|
||||||
|
dma_req_o.debug <= '0'; -- can never ever be in debug mode
|
||||||
|
|
||||||
-- address increment --
|
-- address increment --
|
||||||
address_inc: process(cfg.qsel)
|
address_inc: process(cfg.qsel)
|
||||||
|
|
|
@ -29,7 +29,7 @@ package neorv32_package is
|
||||||
|
|
||||||
-- Architecture Constants -----------------------------------------------------------------
|
-- Architecture Constants -----------------------------------------------------------------
|
||||||
-- -------------------------------------------------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
||||||
constant hw_version_c : std_ulogic_vector(31 downto 0) := x"01100801"; -- hardware version
|
constant hw_version_c : std_ulogic_vector(31 downto 0) := x"01100802"; -- hardware version
|
||||||
constant archid_c : natural := 19; -- official RISC-V architecture ID
|
constant archid_c : natural := 19; -- official RISC-V architecture ID
|
||||||
constant XLEN : natural := 32; -- native data path width
|
constant XLEN : natural := 32; -- native data path width
|
||||||
|
|
||||||
|
@ -129,7 +129,10 @@ package neorv32_package is
|
||||||
src : std_ulogic; -- access source (1=instruction fetch, 0=data access)
|
src : std_ulogic; -- access source (1=instruction fetch, 0=data access)
|
||||||
priv : std_ulogic; -- set if privileged (machine-mode) access
|
priv : std_ulogic; -- set if privileged (machine-mode) access
|
||||||
rvso : std_ulogic; -- set if reservation set operation (atomic LR/SC)
|
rvso : std_ulogic; -- set if reservation set operation (atomic LR/SC)
|
||||||
fence : std_ulogic; -- set if fence(.i) operation, single-shot (out-of-band)
|
-- out-of-band signals --
|
||||||
|
fence : std_ulogic; -- set if fence(.i) request by upstream device, single-shot
|
||||||
|
sleep : std_ulogic; -- set if ALL upstream sources are in sleep mode
|
||||||
|
debug : std_ulogic; -- set if upstream device is in debug mode
|
||||||
end record;
|
end record;
|
||||||
|
|
||||||
-- bus response --
|
-- bus response --
|
||||||
|
@ -149,7 +152,9 @@ package neorv32_package is
|
||||||
src => '0',
|
src => '0',
|
||||||
priv => '0',
|
priv => '0',
|
||||||
rvso => '0',
|
rvso => '0',
|
||||||
fence => '0'
|
fence => '0',
|
||||||
|
sleep => '1',
|
||||||
|
debug => '0'
|
||||||
);
|
);
|
||||||
|
|
||||||
-- endpoint (response) termination --
|
-- endpoint (response) termination --
|
||||||
|
|
|
@ -103,7 +103,7 @@ begin
|
||||||
end if;
|
end if;
|
||||||
end process sysinfo_0_write;
|
end process sysinfo_0_write;
|
||||||
|
|
||||||
-- SYSINFO(1): Internal Memory Configuration (sizes)
|
-- SYSINFO(1): Misc --
|
||||||
sysinfo(1)(7 downto 0) <= std_ulogic_vector(to_unsigned(index_size_f(MEM_INT_IMEM_SIZE), 8)); -- log2(IMEM size)
|
sysinfo(1)(7 downto 0) <= std_ulogic_vector(to_unsigned(index_size_f(MEM_INT_IMEM_SIZE), 8)); -- log2(IMEM size)
|
||||||
sysinfo(1)(15 downto 8) <= std_ulogic_vector(to_unsigned(index_size_f(MEM_INT_DMEM_SIZE), 8)); -- log2(DMEM size)
|
sysinfo(1)(15 downto 8) <= std_ulogic_vector(to_unsigned(index_size_f(MEM_INT_DMEM_SIZE), 8)); -- log2(DMEM size)
|
||||||
sysinfo(1)(23 downto 16) <= (others => '0'); -- reserved
|
sysinfo(1)(23 downto 16) <= (others => '0'); -- reserved
|
||||||
|
|
|
@ -298,9 +298,6 @@ architecture neorv32_top_rtl of neorv32_top is
|
||||||
signal clk_gen_en : clk_gen_en_t;
|
signal clk_gen_en : clk_gen_en_t;
|
||||||
signal clk_gen_en2 : std_ulogic_vector(11 downto 0);
|
signal clk_gen_en2 : std_ulogic_vector(11 downto 0);
|
||||||
|
|
||||||
-- CPU status --
|
|
||||||
signal cpu_debug, cpu_sleep : std_ulogic;
|
|
||||||
|
|
||||||
-- debug module interface (DMI) --
|
-- debug module interface (DMI) --
|
||||||
signal dmi_req : dmi_req_t;
|
signal dmi_req : dmi_req_t;
|
||||||
signal dmi_rsp : dmi_rsp_t;
|
signal dmi_rsp : dmi_rsp_t;
|
||||||
|
@ -459,6 +456,26 @@ begin
|
||||||
-- **************************************************************************************************************************
|
-- **************************************************************************************************************************
|
||||||
-- Core Complex
|
-- Core Complex
|
||||||
-- **************************************************************************************************************************
|
-- **************************************************************************************************************************
|
||||||
|
|
||||||
|
-- fast interrupt requests (FIRQs) --
|
||||||
|
cpu_firq(0) <= firq(FIRQ_TWD);
|
||||||
|
cpu_firq(1) <= firq(FIRQ_CFS);
|
||||||
|
cpu_firq(2) <= firq(FIRQ_UART0_RX);
|
||||||
|
cpu_firq(3) <= firq(FIRQ_UART0_TX);
|
||||||
|
cpu_firq(4) <= firq(FIRQ_UART1_RX);
|
||||||
|
cpu_firq(5) <= firq(FIRQ_UART1_TX);
|
||||||
|
cpu_firq(6) <= firq(FIRQ_SPI);
|
||||||
|
cpu_firq(7) <= firq(FIRQ_TWI);
|
||||||
|
cpu_firq(8) <= firq(FIRQ_XIRQ);
|
||||||
|
cpu_firq(9) <= firq(FIRQ_NEOLED);
|
||||||
|
cpu_firq(10) <= firq(FIRQ_DMA);
|
||||||
|
cpu_firq(11) <= firq(FIRQ_SDI);
|
||||||
|
cpu_firq(12) <= firq(FIRQ_GPTMR);
|
||||||
|
cpu_firq(13) <= firq(FIRQ_ONEWIRE);
|
||||||
|
cpu_firq(14) <= firq(FIRQ_SLINK_RX);
|
||||||
|
cpu_firq(15) <= firq(FIRQ_SLINK_TX);
|
||||||
|
|
||||||
|
-- CPU core + optional L1 caches --
|
||||||
core_complex:
|
core_complex:
|
||||||
if true generate
|
if true generate
|
||||||
|
|
||||||
|
@ -516,8 +533,6 @@ begin
|
||||||
-- global control --
|
-- global control --
|
||||||
clk_i => clk_i,
|
clk_i => clk_i,
|
||||||
rstn_i => rstn_sys,
|
rstn_i => rstn_sys,
|
||||||
sleep_o => cpu_sleep,
|
|
||||||
debug_o => cpu_debug,
|
|
||||||
-- interrupts --
|
-- interrupts --
|
||||||
msi_i => msw_irq,
|
msi_i => msw_irq,
|
||||||
mei_i => mext_irq_i,
|
mei_i => mext_irq_i,
|
||||||
|
@ -532,26 +547,8 @@ begin
|
||||||
dbus_rsp_i => cpu_d_rsp
|
dbus_rsp_i => cpu_d_rsp
|
||||||
);
|
);
|
||||||
|
|
||||||
-- fast interrupt requests (FIRQs) --
|
|
||||||
cpu_firq(0) <= firq(FIRQ_TWD);
|
|
||||||
cpu_firq(1) <= firq(FIRQ_CFS);
|
|
||||||
cpu_firq(2) <= firq(FIRQ_UART0_RX);
|
|
||||||
cpu_firq(3) <= firq(FIRQ_UART0_TX);
|
|
||||||
cpu_firq(4) <= firq(FIRQ_UART1_RX);
|
|
||||||
cpu_firq(5) <= firq(FIRQ_UART1_TX);
|
|
||||||
cpu_firq(6) <= firq(FIRQ_SPI);
|
|
||||||
cpu_firq(7) <= firq(FIRQ_TWI);
|
|
||||||
cpu_firq(8) <= firq(FIRQ_XIRQ);
|
|
||||||
cpu_firq(9) <= firq(FIRQ_NEOLED);
|
|
||||||
cpu_firq(10) <= firq(FIRQ_DMA);
|
|
||||||
cpu_firq(11) <= firq(FIRQ_SDI);
|
|
||||||
cpu_firq(12) <= firq(FIRQ_GPTMR);
|
|
||||||
cpu_firq(13) <= firq(FIRQ_ONEWIRE);
|
|
||||||
cpu_firq(14) <= firq(FIRQ_SLINK_RX);
|
|
||||||
cpu_firq(15) <= firq(FIRQ_SLINK_TX);
|
|
||||||
|
|
||||||
|
-- CPU L1 Instruction Cache (I-Cache) -----------------------------------------------------
|
||||||
-- CPU Instruction Cache (I-Cache) --------------------------------------------------------
|
|
||||||
-- -------------------------------------------------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
||||||
neorv32_icache_inst_true:
|
neorv32_icache_inst_true:
|
||||||
if ICACHE_EN generate
|
if ICACHE_EN generate
|
||||||
|
@ -580,7 +577,7 @@ begin
|
||||||
end generate;
|
end generate;
|
||||||
|
|
||||||
|
|
||||||
-- CPU Data Cache (D-Cache) ---------------------------------------------------------------
|
-- CPU L1 Data Cache (D-Cache) ------------------------------------------------------------
|
||||||
-- -------------------------------------------------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
||||||
neorv32_dcache_inst_true:
|
neorv32_dcache_inst_true:
|
||||||
if DCACHE_EN generate
|
if DCACHE_EN generate
|
||||||
|
@ -613,13 +610,14 @@ begin
|
||||||
-- -------------------------------------------------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
||||||
neorv32_core_bus_switch_inst: entity neorv32.neorv32_bus_switch
|
neorv32_core_bus_switch_inst: entity neorv32.neorv32_bus_switch
|
||||||
generic map (
|
generic map (
|
||||||
|
ROUND_ROBIN_EN => false, -- use prioritizing arbitration
|
||||||
PORT_A_READ_ONLY => false,
|
PORT_A_READ_ONLY => false,
|
||||||
PORT_B_READ_ONLY => true -- i-fetch is read-only
|
PORT_B_READ_ONLY => true -- i-fetch is read-only
|
||||||
)
|
)
|
||||||
port map (
|
port map (
|
||||||
clk_i => clk_i,
|
clk_i => clk_i,
|
||||||
rstn_i => rstn_sys,
|
rstn_i => rstn_sys,
|
||||||
a_lock_i => '0', -- no exclusive accesses for port A
|
a_lock_i => '0', -- no exclusive accesses
|
||||||
a_req_i => dcache_req, -- prioritized
|
a_req_i => dcache_req, -- prioritized
|
||||||
a_rsp_o => dcache_rsp,
|
a_rsp_o => dcache_rsp,
|
||||||
b_req_i => icache_req,
|
b_req_i => icache_req,
|
||||||
|
@ -656,13 +654,14 @@ begin
|
||||||
-- -------------------------------------------------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
||||||
neorv32_dma_bus_switch_inst: entity neorv32.neorv32_bus_switch
|
neorv32_dma_bus_switch_inst: entity neorv32.neorv32_bus_switch
|
||||||
generic map (
|
generic map (
|
||||||
|
ROUND_ROBIN_EN => false, -- use prioritizing arbitration
|
||||||
PORT_A_READ_ONLY => false,
|
PORT_A_READ_ONLY => false,
|
||||||
PORT_B_READ_ONLY => false
|
PORT_B_READ_ONLY => false
|
||||||
)
|
)
|
||||||
port map (
|
port map (
|
||||||
clk_i => clk_i,
|
clk_i => clk_i,
|
||||||
rstn_i => rstn_sys,
|
rstn_i => rstn_sys,
|
||||||
a_lock_i => '0', -- no exclusive accesses for port A
|
a_lock_i => '0', -- no exclusive accesses
|
||||||
a_req_i => core_req, -- prioritized
|
a_req_i => core_req, -- prioritized
|
||||||
a_rsp_o => core_rsp,
|
a_rsp_o => core_rsp,
|
||||||
b_req_i => dma_req,
|
b_req_i => dma_req,
|
||||||
|
@ -1151,8 +1150,6 @@ begin
|
||||||
rstn_sys_i => rstn_sys,
|
rstn_sys_i => rstn_sys,
|
||||||
bus_req_i => iodev_req(IODEV_WDT),
|
bus_req_i => iodev_req(IODEV_WDT),
|
||||||
bus_rsp_o => iodev_rsp(IODEV_WDT),
|
bus_rsp_o => iodev_rsp(IODEV_WDT),
|
||||||
cpu_debug_i => cpu_debug,
|
|
||||||
cpu_sleep_i => cpu_sleep,
|
|
||||||
clkgen_en_o => clk_gen_en(CG_WDT),
|
clkgen_en_o => clk_gen_en(CG_WDT),
|
||||||
clkgen_i => clk_gen,
|
clkgen_i => clk_gen,
|
||||||
rstn_o => rstn_wdt
|
rstn_o => rstn_wdt
|
||||||
|
@ -1690,7 +1687,6 @@ begin
|
||||||
port map (
|
port map (
|
||||||
clk_i => clk_i,
|
clk_i => clk_i,
|
||||||
rstn_i => rstn_ext,
|
rstn_i => rstn_ext,
|
||||||
cpu_debug_i => cpu_debug,
|
|
||||||
dmi_req_i => dmi_req,
|
dmi_req_i => dmi_req,
|
||||||
dmi_rsp_o => dmi_rsp,
|
dmi_rsp_o => dmi_rsp,
|
||||||
bus_req_i => iodev_req(IODEV_OCD),
|
bus_req_i => iodev_req(IODEV_OCD),
|
||||||
|
|
|
@ -23,8 +23,6 @@ entity neorv32_wdt is
|
||||||
rstn_sys_i : in std_ulogic; -- system reset, low-active
|
rstn_sys_i : in std_ulogic; -- system reset, low-active
|
||||||
bus_req_i : in bus_req_t; -- bus request
|
bus_req_i : in bus_req_t; -- bus request
|
||||||
bus_rsp_o : out bus_rsp_t; -- bus response
|
bus_rsp_o : out bus_rsp_t; -- bus response
|
||||||
cpu_debug_i : in std_ulogic; -- CPU is in debug mode
|
|
||||||
cpu_sleep_i : in std_ulogic; -- CPU is in sleep mode
|
|
||||||
clkgen_en_o : out std_ulogic; -- enable clock generator
|
clkgen_en_o : out std_ulogic; -- enable clock generator
|
||||||
clkgen_i : in std_ulogic_vector(7 downto 0);
|
clkgen_i : in std_ulogic_vector(7 downto 0);
|
||||||
rstn_o : out std_ulogic -- timeout reset, low_active, sync
|
rstn_o : out std_ulogic -- timeout reset, low_active, sync
|
||||||
|
@ -155,8 +153,8 @@ begin
|
||||||
|
|
||||||
-- valid counter increment? --
|
-- valid counter increment? --
|
||||||
cnt_inc <= '1' when ((prsc_tick = '1') and (cnt_started = '1')) and -- clock tick and started
|
cnt_inc <= '1' when ((prsc_tick = '1') and (cnt_started = '1')) and -- clock tick and started
|
||||||
((cpu_debug_i = '0') or (ctrl.dben = '1')) and -- not in debug mode or allowed to run in debug mode
|
((bus_req_i.debug = '0') or (ctrl.dben = '1')) and -- not in debug mode or allowed to run in debug mode
|
||||||
((cpu_sleep_i = '0') or (ctrl.sen = '1')) else '0'; -- not in sleep mode or allowed to run in sleep mode
|
((bus_req_i.sleep = '0') or (ctrl.sen = '1')) else '0'; -- not in sleep mode or allowed to run in sleep mode
|
||||||
|
|
||||||
-- timeout detector --
|
-- timeout detector --
|
||||||
cnt_timeout <= '1' when (cnt_started = '1') and (cnt = ctrl.timeout) else '0';
|
cnt_timeout <= '1' when (cnt_started = '1') and (cnt = ctrl.timeout) else '0';
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue