[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)