Skip to content

Commit

Permalink
⚠️ remove Wishbone tag signal (#845)
Browse files Browse the repository at this point in the history
  • Loading branch information
stnolting committed Mar 11, 2024
2 parents 46baf5a + 5a90534 commit e893ddb
Show file tree
Hide file tree
Showing 16 changed files with 120 additions and 177 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 |
|:----:|:-------:|:--------|:----:|
| 11.03.2024 | 1.9.6.3 | :warning: remove Wishbone tag signal; minor rtl edits and optimizations | [#845](https://github.com/stnolting/neorv32/pull/845) |
| 10.03.2024 | 1.9.6.2 | minor rtl clean-ups, optimizations and fixes | [#843](https://github.com/stnolting/neorv32/pull/843) |
| 09.03.2024 | 1.9.6.1 | add generic cache module (not used yet) | [#842](https://github.com/stnolting/neorv32/pull/842) |
| 01.03.2024 | [**:rocket:1.9.6**](https://github.com/stnolting/neorv32/releases/tag/v1.9.6) | **New release** | |
Expand Down
2 changes: 0 additions & 2 deletions docs/datasheet/soc.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,6 @@ bits/channels are hardwired to zero.
[NOTE]
Some interfaces (like the TWI and the 1-Wire bus) require tri-state drivers in the designs top module.


.NEORV32 Processor Signal List
[cols="<3,^1,^1,^1,<8"]
[options="header",grid="rows"]
Expand All @@ -87,7 +86,6 @@ Some interfaces (like the TWI and the 1-Wire bus) require tri-state drivers in t
| `jtag_tdo_o` | 1 | out | - | serial data output
| `jtag_tms_i` | 1 | in | `'L'` | mode select
5+^| **<<_processor_external_memory_interface_wishbone>>**
| `wb_tag_o` | 3 | out | - | tag (access type identifier)
| `wb_adr_o` | 32 | out | - | destination address
| `wb_dat_i` | 32 | in | `'L'` | write data
| `wb_dat_o` | 32 | out | - | read data
Expand Down
16 changes: 2 additions & 14 deletions docs/datasheet/soc_wishbone.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@
|=======================
| Hardware source file(s): | neorv32_wishbone.vhd |
| Software driver file(s): | none | _implicitly used_
| Top entity port: | `wb_tag_o` | request tag output (3-bit)
| | `wb_adr_o` | address output (32-bit)
| Top entity port: | `wb_adr_o` | address output (32-bit)
| | `wb_dat_i` | data input (32-bit)
| | `wb_dat_o` | data output (32-bit)
| | `wb_we_o` | write enable (1-bit)
Expand All @@ -17,14 +16,12 @@
| | `wb_cyc_o` | valid cycle (1-bit)
| | `wb_ack_i` | acknowledge (1-bit)
| | `wb_err_i` | bus error (1-bit)
| | `fence_o` | an executed `fence` instruction
| | `fencei_o` | an executed `fence.i` instruction
| Configuration generics: | `MEM_EXT_EN` | enable external memory interface when `true`
| | `MEM_EXT_TIMEOUT` | number of clock cycles after which an unacknowledged external bus access will auto-terminate (0 = disabled)
| | `MEM_EXT_PIPE_MODE` | when `false` (default): classic/standard Wishbone protocol; when `true`: pipelined Wishbone protocol
| | `MEM_EXT_BIG_ENDIAN` | byte-order (Endianness) of external memory interface; `true`=BIG, `false`=little (default)
| | `MEM_EXT_ASYNC_RX` | use registered RX path when `false` (default); use async/direct RX path when `true`
| | `MEM_EXT_ASYNC_TX_` | use registered TX path when `false` (default); use async/direct TX path when `true`
| | `MEM_EXT_ASYNC_TX` | use registered TX path when `false` (default); use async/direct TX path when `true`
| CPU interrupts: | none |
|=======================

Expand Down Expand Up @@ -85,15 +82,6 @@ or terminate (via `wb_err_i`) the transfer within `MEM_EXT_TIMEOUT` clock cycles
setting `wb_cyc_o` low again and a CPU load/store/instruction fetch bus access fault exception is raised.


**Wishbone Tag**

The 3-bit wishbone `wb_tag_o` signal provides additional information regarding the access type:

* `wb_tag_o(0)`: `1` = privileged access (CPU is in machine mode); `0` = unprivileged access (CPU is not in machine mode)
* `wb_tag_o(1)`: always zero
* `wb_tag_o(2)`: `1` = instruction fetch access, `0` = data access
**Endianness**

The NEORV32 CPU and the Processor setup are *little-endian* architectures. To allow direct connection
Expand Down
Binary file modified docs/figures/wishbone_classic_read.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/figures/wishbone_pipelined_write.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 0 additions & 2 deletions docs/sources/wishbone_classic_read.json
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
{signal: [
{name: 'clk', wave: 'p....|...'},
{name: 'wb_tag_o', wave: 'x3...|.x.', data: ['Tag']},
{name: 'wb_adr_o', wave: 'x3...|.x.', data: ['Address']},
{name: 'wb_dat_i', wave: 'x....|3x.', data: ['rdata']},
{name: 'wb_dat_o', wave: 'x....|.x.', data: ['Wdata']},
{name: 'wb_we_o', wave: 'x0...|.x.'},
{name: 'wb_sel_o', wave: 'x....|.x.', data: ['Byte_enable']},
{name: 'wb_stb_o', wave: '01...|.0.'},
{name: 'wb_cyc_o', wave: '01...|.0.'},
{name: 'wb_lock_o', wave: '0....|...'},
{name: 'wb_ack_i', wave: '0....|10.'},
{name: 'wb_err_i', wave: '0....|...'},
]}
2 changes: 0 additions & 2 deletions docs/sources/wishbone_pipelined_write.json
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
{signal: [
{name: 'clk', wave: 'p....|...'},
{name: 'wb_tag_o', wave: 'x3...|.x.', data: ['Tag']},
{name: 'wb_adr_o', wave: 'x3...|.x.', data: ['Address']},
{name: 'wb_dat_i', wave: 'x....|.x.'},
{name: 'wb_dat_o', wave: 'x3...|.x.', data: ['Wdata']},
{name: 'wb_we_o', wave: 'x1...|.x.'},
{name: 'wb_sel_o', wave: 'x3...|.x.', data: ['Byte_enable']},
{name: 'wb_stb_o', wave: '010..|...'},
{name: 'wb_cyc_o', wave: '01...|.0.'},
{name: 'wb_lock_o', wave: '0....|...'},
{name: 'wb_ack_i', wave: '0....|10.'},
{name: 'wb_err_i', wave: '0....|...'},
]}
56 changes: 26 additions & 30 deletions rtl/core/neorv32_cache.vhd
Original file line number Diff line number Diff line change
Expand Up @@ -830,18 +830,16 @@ architecture neorv32_cache_bus_rtl of neorv32_cache_bus is
constant index_size_c : natural := index_size_f(NUM_BLOCKS);
constant tag_size_c : natural := 32 - (offset_size_c + index_size_c + 2);

-- host request buffer --
signal hreq : bus_req_t;

-- control fsm --
type state_t is (S_IDLE, S_CHECK, S_DOWNLOAD_REQ, S_DOWNLOAD_RSP, S_UPLOAD_GET, S_UPLOAD_REQ, S_UPLOAD_RSP, S_FLUSH_START, S_FLUSH_READ, S_FLUSH_CHECK);
type state_t is (S_IDLE, S_CHECK, S_DOWNLOAD_REQ, S_DOWNLOAD_RSP, S_UPLOAD_GET,
S_UPLOAD_REQ, S_UPLOAD_RSP, S_FLUSH_START, S_FLUSH_READ, S_FLUSH_CHECK);
signal state, upret, state_nxt, upret_nxt: state_t;

-- address generator --
type addr_t is record
tag : std_ulogic_vector(tag_size_c-1 downto 0);
ind : std_ulogic_vector(index_size_c-1 downto 0);
off : std_ulogic_vector(offset_size_c-1 downto 0); -- WORD offset!
idx : std_ulogic_vector(index_size_c-1 downto 0);
ofs : std_ulogic_vector(offset_size_c-1 downto 0); -- WORD offset!
end record;
signal haddr, baddr, addr, addr_nxt : addr_t;

Expand All @@ -851,13 +849,13 @@ begin
-- -------------------------------------------------------------------------------------------
-- base address of original host access --
haddr.tag <= host_req_i.addr(31 downto (32-tag_size_c));
haddr.ind <= host_req_i.addr((offset_size_c+2+index_size_c)-1 downto offset_size_c+2);
haddr.off <= (others => '0'); -- unused
haddr.idx <= (others => '0'); -- unused
haddr.ofs <= (others => '0'); -- unused

-- base address of indexed cache block --
baddr.tag <= base_i(31 downto (32-tag_size_c));
baddr.ind <= base_i((offset_size_c+2+index_size_c)-1 downto offset_size_c+2);
baddr.off <= (others => '0'); -- unused
baddr.idx <= base_i((offset_size_c+2+index_size_c)-1 downto offset_size_c+2);
baddr.ofs <= (others => '0'); -- unused


-- Control Engine FSM Sync ----------------------------------------------------------------
Expand All @@ -868,29 +866,27 @@ begin
state <= S_IDLE;
upret <= S_IDLE;
addr.tag <= (others => '0');
addr.ind <= (others => '0');
addr.off <= (others => '0');
hreq <= req_terminate_c;
addr.idx <= (others => '0');
addr.ofs <= (others => '0');
elsif rising_edge(clk_i) then
state <= state_nxt;
upret <= upret_nxt;
addr <= addr_nxt;
hreq <= host_req_i;
end if;
end process ctrl_engine_sync;


-- Control Engine FSM Comb ----------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
ctrl_engine_comb: process(state, upret, addr, hreq, haddr, baddr, bus_rsp_i, cmd_sync_i, cmd_miss_i, rdata_i, dirty_i)
ctrl_engine_comb: process(state, upret, addr, haddr, baddr, bus_rsp_i, cmd_sync_i, cmd_miss_i, rdata_i, dirty_i)
begin
-- control engine defaults --
state_nxt <= state;
upret_nxt <= upret;
addr_nxt <= addr;

-- cache defaults --
addr_o <= addr.tag & addr.ind & addr.off & "00"; -- always word-aligned
addr_o <= addr.tag & addr.idx & addr.ofs & "00"; -- always word-aligned
we_o <= (others => '0');
swe_o <= '0';
wdata_o <= bus_rsp_i.data;
Expand All @@ -902,17 +898,18 @@ begin

-- bus interface defaults --
bus_req_o <= req_terminate_c; -- all-zero
bus_req_o.addr <= addr.tag & addr.ind & addr.off & "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.ben <= (others => '1'); -- full-word writes only
bus_req_o.priv <= hreq.priv; -- keep original privilege level
bus_req_o.src <= '0'; -- cache accesses are always "data" accesses
bus_req_o.priv <= '0'; -- cache accesses are always "unprivileged" accesses

-- fsm --
case state is

when S_IDLE => -- wait for request
-- ------------------------------------------------------------
addr_nxt.off <= (others => '0'); -- align block base address for upload/download (and flush)
addr_nxt.ofs <= (others => '0'); -- align block base address for upload/download (and flush)
if (cmd_sync_i = '1') then -- cache sync
state_nxt <= S_FLUSH_START;
elsif (cmd_miss_i = '1') then -- cache miss
Expand All @@ -921,14 +918,13 @@ begin

when S_CHECK => -- check if accessed block is dirty (cache address is still applied by host controller!)
-- ------------------------------------------------------------
upret_nxt <= S_DOWNLOAD_REQ; -- go straight to S_DOWNLOAD_REQ when S_UPLOAD_GET has completed (if executed)
upret_nxt <= S_DOWNLOAD_REQ; -- go straight to S_DOWNLOAD_REQ when S_UPLOAD_GET has completed (if executed)
addr_nxt.idx <= baddr.idx; -- index of reference cache block
if (dirty_i = '1') then -- block is dirty, upload first
addr_nxt.tag <= baddr.tag; -- base address (tag + index) of accessed block
addr_nxt.ind <= baddr.ind;
state_nxt <= S_UPLOAD_GET;
else -- block is clean, download new block and override
else -- block is clean, download new block
addr_nxt.tag <= haddr.tag; -- base address (tag + index) of requested block
addr_nxt.ind <= haddr.ind;
state_nxt <= S_DOWNLOAD_REQ;
end if;

Expand All @@ -946,8 +942,8 @@ begin
swe_o <= '1'; -- cache: write status bit (bus error response)
new_o <= '1'; -- set new block (set tag, make valid, make clean)
if (bus_rsp_i.ack = '1') or (bus_rsp_i.err = '1') then -- wait for response
addr_nxt.off <= std_ulogic_vector(unsigned(addr.off) + 1);
if (and_reduce_f(addr.off) = '1') then -- block completed? offset will be all-zero again after block completion
addr_nxt.ofs <= std_ulogic_vector(unsigned(addr.ofs) + 1);
if (and_reduce_f(addr.ofs) = '1') then -- block completed? offset will be all-zero again after block completion
state_nxt <= S_IDLE;
else -- get next word
state_nxt <= S_DOWNLOAD_REQ;
Expand All @@ -971,8 +967,8 @@ begin
bus_req_o.rw <= '1'; -- write access
new_o <= '1'; -- set new block (set tag, make valid, make clean)
if (bus_rsp_i.ack = '1') or (bus_rsp_i.err = '1') then -- wait for response
addr_nxt.off <= std_ulogic_vector(unsigned(addr.off) + 1);
if (and_reduce_f(addr.off) = '1') then -- block completed? offset will be all-zero again after block completion
addr_nxt.ofs <= std_ulogic_vector(unsigned(addr.ofs) + 1);
if (and_reduce_f(addr.ofs) = '1') then -- block completed? offset will be all-zero again after block completion
state_nxt <= upret; -- go back to "upload-done return state"
else -- get next word
state_nxt <= S_UPLOAD_GET;
Expand All @@ -982,7 +978,7 @@ begin

when S_FLUSH_START => -- start checking for dirty blocks
-- ------------------------------------------------------------
addr_nxt.ind <= (others => '0'); -- start with index 0
addr_nxt.idx <= (others => '0'); -- start with index 0
upret_nxt <= S_FLUSH_CHECK; -- come back to S_FLUSH_CHECK after block upload
state_nxt <= S_FLUSH_READ;

Expand All @@ -997,8 +993,8 @@ begin
if (dirty_i = '1') then -- block dirty?
state_nxt <= S_UPLOAD_GET;
else -- move on to next block
addr_nxt.ind <= std_ulogic_vector(unsigned(addr.ind) + 1);
if (and_reduce_f(addr.ind) = '1') then -- all blocks done?
addr_nxt.idx <= std_ulogic_vector(unsigned(addr.idx) + 1);
if (and_reduce_f(addr.idx) = '1') then -- all blocks done?
bus_req_o.fence <= '1'; -- forward fence request to downstream memories
state_nxt <= S_IDLE;
else -- go to next block
Expand Down
3 changes: 1 addition & 2 deletions rtl/core/neorv32_package.vhd
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ package neorv32_package is

-- Architecture Constants -----------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
constant hw_version_c : std_ulogic_vector(31 downto 0) := x"01090602"; -- hardware version
constant hw_version_c : std_ulogic_vector(31 downto 0) := x"01090603"; -- hardware version
constant archid_c : natural := 19; -- official RISC-V architecture ID
constant XLEN : natural := 32; -- native data path width

Expand Down Expand Up @@ -843,7 +843,6 @@ package neorv32_package is
jtag_tdo_o : out std_ulogic;
jtag_tms_i : in std_ulogic := 'L';
-- Wishbone bus interface (available if MEM_EXT_EN = true) --
wb_tag_o : out std_ulogic_vector(02 downto 0);
wb_adr_o : out std_ulogic_vector(31 downto 0);
wb_dat_i : in std_ulogic_vector(31 downto 0) := (others => 'L');
wb_dat_o : out std_ulogic_vector(31 downto 0);
Expand Down
Loading

0 comments on commit e893ddb

Please sign in to comment.