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

⚠️ remove Wishbone tag signal #845

Merged
merged 6 commits into from
Mar 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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