|
| 1 | +/*=======================================================================================*/ |
| 2 | +/* This Sail RISC-V architecture model, comprising all files and */ |
| 3 | +/* directories except where otherwise noted is subject the BSD */ |
| 4 | +/* two-clause license in the LICENSE file. */ |
| 5 | +/* */ |
| 6 | +/* SPDX-License-Identifier: BSD-2-Clause */ |
| 7 | +/*=======================================================================================*/ |
| 8 | + |
| 9 | +/* Support CTR depths - if bit n is set then CTR depth 2^n is supported */ |
| 10 | +val sys_valid_ctr_depth = {c: "sys_valid_ctr_depth", ocaml: "Platform.valid_ctr_depth", _: "sys_valid_ctr_depth"} : unit -> bits(64) |
| 11 | + |
| 12 | +/* Architectural state for the Ssctr and Smctr standard extension. */ |
| 13 | +bitfield Mctrctl : bits(64) = { |
| 14 | + DIRLJMPINH : 47, |
| 15 | + INDLJMPINH : 46, |
| 16 | + RETINH : 45, |
| 17 | + CORSWAPINH : 44, |
| 18 | + DIRJMPINH : 43, |
| 19 | + INDJMPINH : 42, |
| 20 | + DIRCALLINH : 41, |
| 21 | + INDCALLINH : 40, |
| 22 | + TKBRINH : 37, |
| 23 | + NTBREN : 36, |
| 24 | + TRETINH : 35, |
| 25 | + INTRINH : 34, |
| 26 | + EXCINH : 33, |
| 27 | + |
| 28 | + LCOFIFRZ : 12, |
| 29 | + BPFRZ : 11, |
| 30 | + |
| 31 | + MTE : 9, |
| 32 | + STE : 8, |
| 33 | + |
| 34 | + RASEMU : 7, |
| 35 | + |
| 36 | + M : 2, |
| 37 | + S : 1, |
| 38 | + U : 0 |
| 39 | +} |
| 40 | +bitfield Sctrctl : bits(64) = { |
| 41 | + DIRLJMPINH : 47, |
| 42 | + INDLJMPINH : 46, |
| 43 | + RETINH : 45, |
| 44 | + CORSWAPINH : 44, |
| 45 | + DIRJMPINH : 43, |
| 46 | + INDJMPINH : 42, |
| 47 | + DIRCALLINH : 41, |
| 48 | + INDCALLINH : 40, |
| 49 | + TKBRINH : 37, |
| 50 | + NTBREN : 36, |
| 51 | + TRETINH : 35, |
| 52 | + INTRINH : 34, |
| 53 | + EXCINH : 33, |
| 54 | + |
| 55 | + LCOFIFRZ : 12, |
| 56 | + BPFRZ : 11, |
| 57 | + |
| 58 | + STE : 8, |
| 59 | + |
| 60 | + RASEMU : 7, |
| 61 | + |
| 62 | + S : 1, |
| 63 | + U : 0 |
| 64 | +} |
| 65 | +bitfield Sctrdepth : bits(32) = { |
| 66 | + DEPTH : 2 .. 0 |
| 67 | +} |
| 68 | +bitfield Sctrstatus : bits(32) = { |
| 69 | + FROZEN : 31, |
| 70 | + WRPTR : 7 .. 0 |
| 71 | +} |
| 72 | +bitfield Ctrsource : xlenbits = { |
| 73 | + PC : xlen - 1 .. 1, |
| 74 | + V : 0 |
| 75 | +} |
| 76 | +bitfield Ctrtarget : xlenbits = { |
| 77 | + PC : xlen - 1 .. 1, |
| 78 | + MISP : 0 |
| 79 | +} |
| 80 | +bitfield Ctrdata : bits(64) = { |
| 81 | + CCE : 31 .. 28, |
| 82 | + CCM : 27 .. 16, |
| 83 | + CCV : 15, |
| 84 | + TYPE : 3 .. 0 |
| 85 | +} |
| 86 | + |
| 87 | +register sctrstatus : Sctrstatus |
| 88 | +register sctrdepth : Sctrdepth |
| 89 | +register mctrctl : Mctrctl |
| 90 | +register ctrsource : vector(256, dec, Ctrsource) |
| 91 | +register ctrtarget : vector(256, dec, Ctrtarget) |
| 92 | +register ctrdata : vector(256, dec, Ctrdata) |
| 93 | +/* Should parameterize the cycle counter to support wider counters */ |
| 94 | +register ctr_cycle_counter : bits(13) |
| 95 | +register ctr_cycle_counter_valid : bool |
| 96 | + |
| 97 | +function legalize_mctrctl(o : Mctrctl, v : xlenbits) -> Mctrctl = { |
| 98 | + let m : Mctrctl = Mk_Mctrctl(zero_extend(v)); |
| 99 | + m |
| 100 | +} |
| 101 | + |
| 102 | +function lower_sctrctl(m : Mctrctl) -> Sctrctl = { |
| 103 | + let s = Mk_Sctrctl(m.bits); |
| 104 | + s |
| 105 | +} |
| 106 | + |
| 107 | +function legalize_sctrctl(m : Mctrctl, v : xlenbits) -> Mctrctl = { |
| 108 | + let o = Mk_Mctrctl(zero_extend(v)); |
| 109 | + let o = [o with M = m[M], MTE = m[MTE]]; |
| 110 | + o |
| 111 | +} |
| 112 | + |
| 113 | + |
| 114 | +function get_wrptr_mask(d : Sctrdepth) -> bits(8) = |
| 115 | + match(d[DEPTH]) { |
| 116 | + 0b000 => 0b00001111, |
| 117 | + 0b001 => 0b00011111, |
| 118 | + 0b010 => 0b00111111, |
| 119 | + 0b011 => 0b01111111, |
| 120 | + 0b100 => 0b11111111, |
| 121 | + _ => internal_error(__FILE__, __LINE__, "Unexpected DEPTH encoding") |
| 122 | + } |
| 123 | + |
| 124 | +function legalize_sctrdepth(s : Sctrdepth, v : xlenbits) -> Sctrdepth = { |
| 125 | + let valid_ctr_depth : bits(64) = sys_valid_ctr_depth(); |
| 126 | + let depth : bits(3) = match(v[2 .. 0]) { |
| 127 | + 0b000 => if bit_to_bool(valid_ctr_depth[0]) then v[2 .. 0] else s[DEPTH], |
| 128 | + 0b001 => if bit_to_bool(valid_ctr_depth[1]) then v[2 .. 0] else s[DEPTH], |
| 129 | + 0b010 => if bit_to_bool(valid_ctr_depth[2]) then v[2 .. 0] else s[DEPTH], |
| 130 | + 0b011 => if bit_to_bool(valid_ctr_depth[3]) then v[2 .. 0] else s[DEPTH], |
| 131 | + 0b100 => if bit_to_bool(valid_ctr_depth[4]) then v[2 .. 0] else s[DEPTH], |
| 132 | + _ => s[DEPTH] |
| 133 | + }; |
| 134 | + let o = Mk_Sctrdepth(zero_extend(depth)); |
| 135 | + |
| 136 | + /* On depth change WRPTR assumes an unspecified but legal value */ |
| 137 | + sctrstatus[WRPTR] = sctrstatus[WRPTR] & get_wrptr_mask(o); |
| 138 | + |
| 139 | + o |
| 140 | +} |
| 141 | +function legalize_sctrstatus(s : Sctrstatus, v : xlenbits) -> Sctrstatus = { |
| 142 | + let wrptr_mask : bits(8) = get_wrptr_mask(sctrdepth); |
| 143 | + let o = Mk_Sctrstatus(zeros()); |
| 144 | + let o = [o with WRPTR = (v[7 .. 0] & wrptr_mask), FROZEN = v[31 .. 31]]; |
| 145 | + o |
| 146 | +} |
| 147 | +function number_of_ctr() -> int = { |
| 148 | + let valid_ctr_depth : bits(64) = sys_valid_ctr_depth(); |
| 149 | + let num = if bit_to_bool(valid_ctr_depth[0]) then 16 else 0; |
| 150 | + let num = if bit_to_bool(valid_ctr_depth[1]) then 32 else num; |
| 151 | + let num = if bit_to_bool(valid_ctr_depth[2]) then 64 else num; |
| 152 | + let num = if bit_to_bool(valid_ctr_depth[3]) then 128 else num; |
| 153 | + let num = if bit_to_bool(valid_ctr_depth[4]) then 256 else num; |
| 154 | + num |
| 155 | +} |
| 156 | +function isValidCtrMiselect() -> bool = { |
| 157 | + let ctr_select = miselect.bits[7 .. 0]; |
| 158 | + haveSmctr() & (unsigned(ctr_select) < number_of_ctr()) |
| 159 | +} |
| 160 | +function isValidCtrSiselect() -> bool = { |
| 161 | + let ctr_select = siselect.bits[7 .. 0]; |
| 162 | + haveSsctr() & (unsigned(ctr_select) < number_of_ctr()) |
| 163 | +} |
| 164 | +/* Logical entry N, selected by *iselect value of (0x200 | N), is |
| 165 | + * physically at ((WRPTR - N - 1) % depth) where depth = 2^(DEPTH+4) |
| 166 | + */ |
| 167 | +function get_ctr_idx(iselect : SMiselect) -> bits(8) = { |
| 168 | + let ctr_idx = sctrstatus[WRPTR] - iselect.bits[7 .. 0] - 1; |
| 169 | + ctr_idx & get_wrptr_mask(sctrdepth); |
| 170 | +} |
| 171 | + |
| 172 | +function get_ctr_mireg() -> xlenbits = |
| 173 | + ctrsource[unsigned(get_ctr_idx(miselect))].bits |
| 174 | + |
| 175 | +function get_ctr_mireg2() -> xlenbits = |
| 176 | + ctrtarget[unsigned(get_ctr_idx(miselect))].bits |
| 177 | + |
| 178 | +function get_ctr_mireg3() -> xlenbits = |
| 179 | + ctrdata[unsigned(get_ctr_idx(miselect))].bits |
| 180 | + |
| 181 | +function set_ctr_mireg(v: xlenbits) -> unit = |
| 182 | + ctrsource[unsigned(get_ctr_idx(miselect))] = Mk_Ctrsource(v) |
| 183 | + |
| 184 | +function set_ctr_mireg2(v: xlenbits) -> unit = |
| 185 | + ctrtarget[unsigned(get_ctr_idx(miselect))] = Mk_Ctrtarget(v) |
| 186 | + |
| 187 | +function set_ctr_mireg3(v: xlenbits) -> unit = |
| 188 | + ctrdata[unsigned(get_ctr_idx(miselect))] = Mk_Ctrdata(v) |
| 189 | + |
| 190 | + |
| 191 | +function get_ctr_sireg() -> xlenbits = |
| 192 | + ctrsource[unsigned(get_ctr_idx(siselect))].bits |
| 193 | + |
| 194 | +function get_ctr_sireg2() -> xlenbits = |
| 195 | + ctrsource[unsigned(get_ctr_idx(siselect))].bits |
| 196 | + |
| 197 | +function get_ctr_sireg3() -> xlenbits = |
| 198 | + ctrsource[unsigned(get_ctr_idx(siselect))].bits |
| 199 | + |
| 200 | +function set_ctr_sireg(v: xlenbits) -> unit = |
| 201 | + ctrsource[unsigned(get_ctr_idx(siselect))] = Mk_Ctrsource(v) |
| 202 | + |
| 203 | +function set_ctr_sireg2(v: xlenbits) -> unit = |
| 204 | + ctrtarget[unsigned(get_ctr_idx(siselect))] = Mk_Ctrtarget(v) |
| 205 | + |
| 206 | +function set_ctr_sireg3(v: xlenbits) -> unit = |
| 207 | + ctrdata[unsigned(get_ctr_idx(siselect))] = Mk_Ctrdata(v) |
0 commit comments