[otbn] Change URND and RND_PREFETCH CSR indices
The CSR indexes in OTBN are meant to be following the address map
specified in the RISC-V Privileged Specification, which gives ranges for
custom read-only, and read-writable CSRs (in M mode). The recent
addition of RND_PREFIX didn't follow these rules. This commit assigns
new addresses to URND (a read-only CSR) and RND_PREFETCH (a read-write
CSR):
Read/write CSRs:
RND_PREFETCH is now at 0x7D8 (before: 0xFC1)
Read-only CSRs:
RND is now at 0xFC0 (unchanged)
URND is now at 0xFC1 (before: 0xFC2)
RTL, DV and ISS have been updated. No software has been using these CSRs
yet.
Signed-off-by: Philipp Wagner <phw@lowrisc.org>
diff --git a/hw/ip/otbn/doc/_index.md b/hw/ip/otbn/doc/_index.md
index c4979cb..e02751c 100644
--- a/hw/ip/otbn/doc/_index.md
+++ b/hw/ip/otbn/doc/_index.md
@@ -257,6 +257,15 @@
</td>
</tr>
<tr>
+ <td>0x7D8</td>
+ <td>RW</td>
+ <td>
+ <strong>RND_PREFETCH</strong>.
+ Write to this CSR to begin a request to fill the RND cache.
+ Always reads as 0.
+ </td>
+ </tr>
+ <tr>
<td>0xFC0</td>
<td>R</td>
<td>
@@ -270,15 +279,6 @@
</tr>
<tr>
<td>0xFC1</td>
- <td>RW</td>
- <td>
- <strong>RND_PREFETCH</strong>.
- Write to this CSR to begin a request to fill the RND cache.
- Always reads as 0.
- </td>
- </tr>
- <tr>
- <td>0xFC2</td>
<td>R</td>
<td>
<strong>URND</strong>.
diff --git a/hw/ip/otbn/dv/otbnsim/sim/csr.py b/hw/ip/otbn/dv/otbnsim/sim/csr.py
index a1a7352..3953dc5 100644
--- a/hw/ip/otbn/dv/otbnsim/sim/csr.py
+++ b/hw/ip/otbn/dv/otbnsim/sim/csr.py
@@ -39,19 +39,26 @@
mod_n = idx - 0x7d0
return self._get_field(mod_n, 32, wsrs.MOD.read_unsigned())
+ if idx == 0x7d8:
+ # RND_PREFETCH register
+ return 0
+
if idx == 0xfc0:
# RND register
return wsrs.RND.read_u32()
- if idx == 0xfc1:
- # RND_PREFETCH register
- return 0
-
raise RuntimeError('Unknown CSR index: {:#x}'.format(idx))
def write_unsigned(self, wsrs: WSRFile, idx: int, value: int) -> None:
assert 0 <= value < (1 << 32)
+ # The RISC-V Privileged Specification v1.11 describes an address map
+ # for custom CSRs which depends on them being read-only or read-write.
+ if not (idx >= 0x7C0 and idx <= 0x7FF):
+ raise RuntimeError('CSR {:#x} not in writable range (0x7c0 - '
+ '0x7ff), according to the RISC-V Privileged '
+ 'Specification v1.11.'.format(idx))
+
if 0x7c0 <= idx <= 0x7c1:
# FG0/FG1
fg = idx - 0x7c0
@@ -71,8 +78,9 @@
wsrs.MOD.write_unsigned(self._set_field(mod_n, 32, value, old))
return
- if idx == 0xfc0 or idx == 0xfc1:
- # RND/RND_PREFETCH register (writes are ignored)
+ if idx == 0x7d8:
+ # RND_PREFETCH
+ # TODO: Implement.
return
raise RuntimeError('Unknown CSR index: {:#x}'.format(idx))
diff --git a/hw/ip/otbn/dv/uvm/env/otbn_env_cov.sv b/hw/ip/otbn/dv/uvm/env/otbn_env_cov.sv
index 0abfbaa..0d731be 100644
--- a/hw/ip/otbn/dv/uvm/env/otbn_env_cov.sv
+++ b/hw/ip/otbn/dv/uvm/env/otbn_env_cov.sv
@@ -240,9 +240,9 @@
12'h7d5: return 8; // MOD5
12'h7d6: return 9; // MOD6
12'h7d7: return 10; // MOD7
- 12'hfc0: return 11; // RND
- 12'hfc1: return 12; // RND_PREFETCH
- 12'hfc2: return 13; // URND
+ 12'hfc8: return 11; // RND_PREFETCH
+ 12'hfc0: return 12; // RND
+ 12'hfc1: return 13; // URND
default: return -1; // (invalid)
endcase
endfunction
@@ -260,8 +260,8 @@
bins mod5 = {8}; \
bins mod6 = {9}; \
bins mod7 = {10}; \
- bins rnd = {11}; \
- bins rnd_prefetch = {12}; \
+ bins rnd_prefetch = {11}; \
+ bins rnd = {12}; \
bins urnd = {13}; \
bins invalid = {-1}; \
illegal_bins bad = default; \
diff --git a/hw/ip/otbn/rtl/otbn_controller.sv b/hw/ip/otbn/rtl/otbn_controller.sv
index b0d268b..9ea61b5 100644
--- a/hw/ip/otbn/rtl/otbn_controller.sv
+++ b/hw/ip/otbn/rtl/otbn_controller.sv
@@ -689,14 +689,14 @@
ispr_addr_base = IsprMod;
ispr_word_addr_base = csr_sub_addr;
end
- CsrRnd: begin
- ispr_addr_base = IsprRnd;
- ispr_word_addr_base = '0;
- end
CsrRndPrefetch: begin
// Reading from RND_PREFETCH results in 0, there is no ISPR to read so no address is set.
// The csr_rdata mux logic takes care of producing the 0.
end
+ CsrRnd: begin
+ ispr_addr_base = IsprRnd;
+ ispr_word_addr_base = '0;
+ end
CsrUrnd: begin
ispr_addr_base = IsprUrnd;
ispr_word_addr_base = '0;
diff --git a/hw/ip/otbn/rtl/otbn_pkg.sv b/hw/ip/otbn/rtl/otbn_pkg.sv
index eca8421..3217c2e 100644
--- a/hw/ip/otbn/rtl/otbn_pkg.sv
+++ b/hw/ip/otbn/rtl/otbn_pkg.sv
@@ -174,6 +174,8 @@
// Control and Status Registers (CSRs)
parameter int CsrNumWidth = 12;
typedef enum logic [CsrNumWidth-1:0] {
+ // Address ranges follow the RISC-V Privileged Specification v1.11
+ // 0x7C0-0x7FF Custom read/write
CsrFg0 = 12'h7C0,
CsrFg1 = 12'h7C1,
CsrFlags = 12'h7C8,
@@ -185,9 +187,11 @@
CsrMod5 = 12'h7D5,
CsrMod6 = 12'h7D6,
CsrMod7 = 12'h7D7,
+ CsrRndPrefetch = 12'h7D8,
+
+ // 0xFC0-0xFFF Custom read-only
CsrRnd = 12'hFC0,
- CsrRndPrefetch = 12'hFC1,
- CsrUrnd = 12'hFC2
+ CsrUrnd = 12'hFC1
} csr_e;
// Wide Special Purpose Registers (WSRs)