udb 0.1.8 → 0.1.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (275) hide show
  1. checksums.yaml +4 -4
  2. data/.data/cfgs/example_rv64_with_overlay.yaml +5 -2
  3. data/.data/cfgs/mc100-32-full-example.yaml +1 -0
  4. data/.data/cfgs/profile/README.adoc +10 -0
  5. data/.data/cfgs/profile/RVA20S64.yaml +26 -6
  6. data/.data/cfgs/profile/RVA20U64.yaml +18 -4
  7. data/.data/cfgs/profile/RVA22S64.yaml +27 -7
  8. data/.data/cfgs/profile/RVA22U64.yaml +18 -4
  9. data/.data/cfgs/profile/RVA23S64.yaml +61 -7
  10. data/.data/cfgs/profile/RVA23U64.yaml +36 -4
  11. data/.data/cfgs/profile/RVB23S64.yaml +27 -7
  12. data/.data/cfgs/profile/RVB23U64.yaml +18 -4
  13. data/.data/cfgs/profile/RVI20U32.yaml +10 -4
  14. data/.data/cfgs/profile/RVI20U64.yaml +10 -4
  15. data/.data/cfgs/qc_iu.yaml +4 -1
  16. data/.data/cfgs/rv32-riscv-tests.yaml +2 -1
  17. data/.data/cfgs/rv32-vector.yaml +2 -1
  18. data/.data/cfgs/rv64-riscv-tests.yaml +2 -1
  19. data/.data/cfgs/rv64-vector.yaml +2 -1
  20. data/.data/spec/custom/isa/qc_iu/csr/Smrnmi/mnepc.yaml +17 -0
  21. data/.data/spec/custom/isa/qc_iu/csr/Xqccmi/qc.itba.yaml +45 -0
  22. data/.data/spec/custom/isa/qc_iu/csr/Xqccmi/qc.itdec.yaml +39 -0
  23. data/.data/spec/custom/isa/qc_iu/csr/jvt.yaml +11 -0
  24. data/.data/spec/custom/isa/qc_iu/csr/mepc.yaml +16 -0
  25. data/.data/spec/custom/isa/qc_iu/ext/Xqccmi.yaml +219 -0
  26. data/.data/spec/custom/isa/qc_iu/ext/Xqccmt.yaml +127 -0
  27. data/.data/spec/custom/isa/qc_iu/inst/Xqccmi/qc.cm.ilut.yaml +153 -0
  28. data/.data/spec/custom/isa/qc_iu/inst/Xqccmt/qc.cm.jalt.yaml +84 -0
  29. data/.data/spec/custom/isa/qc_iu/inst/Xqccmt/qc.cm.jt.yaml +60 -0
  30. data/.data/spec/custom/isa/qc_iu/isa/globals.isa +112 -0
  31. data/.data/spec/schemas/config_schema.json +219 -26
  32. data/.data/spec/schemas/csr_schema.json +0 -6
  33. data/.data/spec/schemas/ext_schema.json +80 -24
  34. data/.data/spec/schemas/inst_schema.json +0 -3
  35. data/.data/spec/schemas/profile_release_schema.json +1 -1
  36. data/.data/spec/schemas/profile_schema.json +0 -3
  37. data/.data/spec/schemas/register_file_schema.json +8 -3
  38. data/.data/spec/schemas/schema_defs.json +8 -27
  39. data/.data/spec/std/isa/csr/I/pmpcfg0.yaml +8 -8
  40. data/.data/spec/std/isa/csr/I/pmpcfg1.yaml +4 -4
  41. data/.data/spec/std/isa/csr/I/pmpcfg10.yaml +8 -8
  42. data/.data/spec/std/isa/csr/I/pmpcfg11.yaml +4 -4
  43. data/.data/spec/std/isa/csr/I/pmpcfg12.yaml +8 -8
  44. data/.data/spec/std/isa/csr/I/pmpcfg13.yaml +4 -4
  45. data/.data/spec/std/isa/csr/I/pmpcfg14.yaml +8 -8
  46. data/.data/spec/std/isa/csr/I/pmpcfg15.yaml +4 -4
  47. data/.data/spec/std/isa/csr/I/pmpcfg2.yaml +8 -8
  48. data/.data/spec/std/isa/csr/I/pmpcfg3.yaml +4 -4
  49. data/.data/spec/std/isa/csr/I/pmpcfg4.yaml +8 -8
  50. data/.data/spec/std/isa/csr/I/pmpcfg5.yaml +4 -4
  51. data/.data/spec/std/isa/csr/I/pmpcfg6.yaml +8 -8
  52. data/.data/spec/std/isa/csr/I/pmpcfg7.yaml +4 -4
  53. data/.data/spec/std/isa/csr/I/pmpcfg8.yaml +8 -8
  54. data/.data/spec/std/isa/csr/I/pmpcfg9.yaml +4 -4
  55. data/.data/spec/std/isa/csr/I/pmpcfgN.layout +1 -1
  56. data/.data/spec/std/isa/csr/Zicntr/mcountinhibit.layout +6 -2
  57. data/.data/spec/std/isa/csr/Zicntr/mcountinhibit.yaml +6 -2
  58. data/.data/spec/std/isa/csr/hstatus.yaml +16 -0
  59. data/.data/spec/std/isa/csr/mcycleh.yaml +1 -1
  60. data/.data/spec/std/isa/csr/misa.yaml +0 -12
  61. data/.data/spec/std/isa/csr/mstatus.yaml +38 -0
  62. data/.data/spec/std/isa/csr/mstatush.yaml +17 -15
  63. data/.data/spec/std/isa/csr/senvcfg.yaml +16 -0
  64. data/.data/spec/std/isa/csr/sstatus.yaml +12 -0
  65. data/.data/spec/std/isa/csr/vsstatus.yaml +24 -0
  66. data/.data/spec/std/isa/ext/A.yaml +5 -7
  67. data/.data/spec/std/isa/ext/S.yaml +12 -0
  68. data/.data/spec/std/isa/ext/Smpmpmt.yaml +52 -0
  69. data/.data/spec/std/isa/ext/Sv32.yaml +7 -19
  70. data/.data/spec/std/isa/ext/Sv39.yaml +7 -19
  71. data/.data/spec/std/isa/ext/Sv48.yaml +4 -20
  72. data/.data/spec/std/isa/ext/Sv57.yaml +4 -20
  73. data/.data/spec/std/isa/ext/Svukte.yaml +71 -0
  74. data/.data/spec/std/isa/ext/Zawrs.yaml +1 -1
  75. data/.data/spec/std/isa/ext/Zihpm.yaml +0 -12
  76. data/.data/spec/std/isa/inst/C/c.addi.yaml +1 -0
  77. data/.data/spec/std/isa/inst/C/c.addi16sp.yaml +1 -0
  78. data/.data/spec/std/isa/inst/C/c.addiw.yaml +1 -0
  79. data/.data/spec/std/isa/inst/C/c.andi.yaml +1 -0
  80. data/.data/spec/std/isa/inst/C/c.ldsp.yaml +1 -1
  81. data/.data/spec/std/isa/inst/C/c.li.yaml +1 -0
  82. data/.data/spec/std/isa/inst/C/c.lui.yaml +1 -0
  83. data/.data/spec/std/isa/inst/C/c.mv.yaml +1 -1
  84. data/.data/spec/std/isa/inst/C/c.sdsp.yaml +1 -1
  85. data/.data/spec/std/isa/inst/D/fsgnj.d.yaml +3 -0
  86. data/.data/spec/std/isa/inst/D/fsgnjn.d.yaml +3 -0
  87. data/.data/spec/std/isa/inst/D/fsgnjx.d.yaml +3 -0
  88. data/.data/spec/std/isa/inst/F/fadd.s.yaml +5 -5
  89. data/.data/spec/std/isa/inst/F/fclass.s.yaml +2 -2
  90. data/.data/spec/std/isa/inst/F/fcvt.l.s.yaml +1 -1
  91. data/.data/spec/std/isa/inst/F/fcvt.lu.s.yaml +1 -1
  92. data/.data/spec/std/isa/inst/F/fcvt.s.l.yaml +1 -1
  93. data/.data/spec/std/isa/inst/F/fcvt.s.lu.yaml +1 -1
  94. data/.data/spec/std/isa/inst/F/fcvt.s.w.yaml +1 -1
  95. data/.data/spec/std/isa/inst/F/fcvt.s.wu.yaml +1 -1
  96. data/.data/spec/std/isa/inst/F/fcvt.w.s.yaml +1 -1
  97. data/.data/spec/std/isa/inst/F/fcvt.wu.s.yaml +1 -1
  98. data/.data/spec/std/isa/inst/F/fdiv.s.yaml +1 -1
  99. data/.data/spec/std/isa/inst/F/feq.s.yaml +2 -2
  100. data/.data/spec/std/isa/inst/F/fle.s.yaml +2 -2
  101. data/.data/spec/std/isa/inst/F/fleq.s.yaml +2 -2
  102. data/.data/spec/std/isa/inst/F/flt.s.yaml +2 -2
  103. data/.data/spec/std/isa/inst/F/fltq.s.yaml +2 -2
  104. data/.data/spec/std/isa/inst/F/flw.yaml +2 -2
  105. data/.data/spec/std/isa/inst/F/fmadd.s.yaml +1 -1
  106. data/.data/spec/std/isa/inst/F/fmax.s.yaml +6 -6
  107. data/.data/spec/std/isa/inst/F/fmin.s.yaml +6 -6
  108. data/.data/spec/std/isa/inst/F/fmsub.s.yaml +1 -1
  109. data/.data/spec/std/isa/inst/F/fmul.s.yaml +1 -1
  110. data/.data/spec/std/isa/inst/F/fmv.w.x.yaml +2 -2
  111. data/.data/spec/std/isa/inst/F/fmv.x.w.yaml +1 -1
  112. data/.data/spec/std/isa/inst/F/fnmadd.s.yaml +2 -2
  113. data/.data/spec/std/isa/inst/F/fnmsub.s.yaml +1 -1
  114. data/.data/spec/std/isa/inst/F/fsgnj.s.yaml +4 -4
  115. data/.data/spec/std/isa/inst/F/fsgnjn.s.yaml +3 -3
  116. data/.data/spec/std/isa/inst/F/fsgnjx.s.yaml +4 -4
  117. data/.data/spec/std/isa/inst/F/fsqrt.s.yaml +1 -1
  118. data/.data/spec/std/isa/inst/F/fsub.s.yaml +1 -1
  119. data/.data/spec/std/isa/inst/F/fsw.yaml +1 -1
  120. data/.data/spec/std/isa/inst/I/addi.yaml +1 -1
  121. data/.data/spec/std/isa/inst/I/addiw.yaml +1 -1
  122. data/.data/spec/std/isa/inst/I/andi.yaml +1 -1
  123. data/.data/spec/std/isa/inst/I/beq.yaml +1 -1
  124. data/.data/spec/std/isa/inst/I/bge.yaml +4 -2
  125. data/.data/spec/std/isa/inst/I/bgeu.yaml +3 -0
  126. data/.data/spec/std/isa/inst/I/blt.yaml +4 -2
  127. data/.data/spec/std/isa/inst/I/bltu.yaml +3 -0
  128. data/.data/spec/std/isa/inst/I/bne.yaml +1 -1
  129. data/.data/spec/std/isa/inst/I/slt.yaml +2 -2
  130. data/.data/spec/std/isa/inst/I/sltiu.yaml +1 -1
  131. data/.data/spec/std/isa/inst/I/sltu.yaml +1 -1
  132. data/.data/spec/std/isa/inst/I/sub.yaml +1 -1
  133. data/.data/spec/std/isa/inst/I/subw.yaml +1 -1
  134. data/.data/spec/std/isa/inst/I/xori.yaml +1 -1
  135. data/.data/spec/std/isa/inst/M/mul.yaml +0 -19
  136. data/.data/spec/std/isa/inst/Q/fsgnj.q.yaml +1 -1
  137. data/.data/spec/std/isa/inst/S/sret.yaml +3 -1
  138. data/.data/spec/std/isa/inst/V/vadd.vv.yaml +1 -5
  139. data/.data/spec/std/isa/inst/V/vfsgnjn.vv.yaml +3 -0
  140. data/.data/spec/std/isa/inst/V/vfsgnjx.vv.yaml +3 -0
  141. data/.data/spec/std/isa/inst/V/vl1re8.v.yaml +3 -0
  142. data/.data/spec/std/isa/inst/V/vl2re8.v.yaml +3 -0
  143. data/.data/spec/std/isa/inst/V/vl4re8.v.yaml +3 -0
  144. data/.data/spec/std/isa/inst/V/vl8re8.v.yaml +3 -0
  145. data/.data/spec/std/isa/inst/V/vle8.v.yaml +3 -8
  146. data/.data/spec/std/isa/inst/V/vmand.mm.yaml +3 -0
  147. data/.data/spec/std/isa/inst/V/vmfle.vv.yaml +3 -0
  148. data/.data/spec/std/isa/inst/V/vmflt.vv.yaml +3 -0
  149. data/.data/spec/std/isa/inst/V/vmnand.mm.yaml +3 -0
  150. data/.data/spec/std/isa/inst/V/vmsgt.vi.yaml +3 -0
  151. data/.data/spec/std/isa/inst/V/vmsgtu.vi.yaml +3 -0
  152. data/.data/spec/std/isa/inst/V/vmsle.vi.yaml +3 -0
  153. data/.data/spec/std/isa/inst/V/vmsle.vv.yaml +3 -0
  154. data/.data/spec/std/isa/inst/V/vmsleu.vi.yaml +3 -0
  155. data/.data/spec/std/isa/inst/V/vmsleu.vv.yaml +3 -0
  156. data/.data/spec/std/isa/inst/V/vmslt.vv.yaml +3 -0
  157. data/.data/spec/std/isa/inst/V/vmsltu.vv.yaml +3 -0
  158. data/.data/spec/std/isa/inst/V/vmv.v.i.yaml +2 -13
  159. data/.data/spec/std/isa/inst/V/vmv.x.s.yaml +1 -1
  160. data/.data/spec/std/isa/inst/V/vmxnor.mm.yaml +3 -0
  161. data/.data/spec/std/isa/inst/V/vmxor.mm.yaml +3 -0
  162. data/.data/spec/std/isa/inst/V/vnsrl.wx.yaml +3 -0
  163. data/.data/spec/std/isa/inst/V/vrsub.vx.yaml +3 -0
  164. data/.data/spec/std/isa/inst/V/vse8.v.yaml +3 -4
  165. data/.data/spec/std/isa/inst/V/vwadd.vx.yaml +3 -0
  166. data/.data/spec/std/isa/inst/V/vwaddu.vx.yaml +3 -0
  167. data/.data/spec/std/isa/inst/V/vxor.vi.yaml +4 -0
  168. data/.data/spec/std/isa/inst/Zalasr/lSIZE.AQRL.layout +40 -5
  169. data/.data/spec/std/isa/inst/Zalasr/lb.aq.yaml +17 -1
  170. data/.data/spec/std/isa/inst/Zalasr/lb.aqrl.yaml +17 -1
  171. data/.data/spec/std/isa/inst/Zalasr/ld.aq.yaml +17 -1
  172. data/.data/spec/std/isa/inst/Zalasr/ld.aqrl.yaml +17 -1
  173. data/.data/spec/std/isa/inst/Zalasr/lh.aq.yaml +17 -1
  174. data/.data/spec/std/isa/inst/Zalasr/lh.aqrl.yaml +17 -1
  175. data/.data/spec/std/isa/inst/Zalasr/lw.aq.yaml +17 -1
  176. data/.data/spec/std/isa/inst/Zalasr/lw.aqrl.yaml +17 -1
  177. data/.data/spec/std/isa/inst/Zalasr/sSIZE.AQRL.layout +46 -5
  178. data/.data/spec/std/isa/inst/Zalasr/sb.aqrl.yaml +16 -1
  179. data/.data/spec/std/isa/inst/Zalasr/sb.rl.yaml +16 -1
  180. data/.data/spec/std/isa/inst/Zalasr/sd.aqrl.yaml +16 -1
  181. data/.data/spec/std/isa/inst/Zalasr/sd.rl.yaml +16 -1
  182. data/.data/spec/std/isa/inst/Zalasr/sh.aqrl.yaml +16 -1
  183. data/.data/spec/std/isa/inst/Zalasr/sh.rl.yaml +16 -1
  184. data/.data/spec/std/isa/inst/Zalasr/sw.aqrl.yaml +16 -1
  185. data/.data/spec/std/isa/inst/Zalasr/sw.rl.yaml +16 -1
  186. data/.data/spec/std/isa/inst/Zbkb/packw.yaml +1 -1
  187. data/.data/spec/std/isa/inst/Zcd/c.fld.yaml +1 -1
  188. data/.data/spec/std/isa/inst/Zcd/c.fldsp.yaml +1 -1
  189. data/.data/spec/std/isa/inst/Zcd/c.fsdsp.yaml +1 -1
  190. data/.data/spec/std/isa/inst/Zcf/c.flwsp.yaml +1 -1
  191. data/.data/spec/std/isa/inst/Zcf/c.fswsp.yaml +1 -1
  192. data/.data/spec/std/isa/inst/Zcmp/cm.pop.yaml +1 -1
  193. data/.data/spec/std/isa/inst/Zcmp/cm.popret.yaml +1 -1
  194. data/.data/spec/std/isa/inst/Zcmp/cm.popretz.yaml +1 -1
  195. data/.data/spec/std/isa/inst/Zcmp/cm.push.yaml +2 -3
  196. data/.data/spec/std/isa/inst/Zfa/fround.s.yaml +1 -1
  197. data/.data/spec/std/isa/inst/Zfh/fcvt.h.s.yaml +6 -6
  198. data/.data/spec/std/isa/inst/Zfh/fcvt.s.h.yaml +5 -5
  199. data/.data/spec/std/isa/inst/Zfh/flh.yaml +1 -1
  200. data/.data/spec/std/isa/inst/Zfh/fmv.h.x.yaml +1 -1
  201. data/.data/spec/std/isa/inst/Zfh/fmv.x.h.yaml +1 -1
  202. data/.data/spec/std/isa/inst/Zfh/fsh.yaml +1 -1
  203. data/.data/spec/std/isa/inst/Zicsr/csrrc.yaml +1 -1
  204. data/.data/spec/std/isa/inst/Zicsr/csrrci.yaml +1 -1
  205. data/.data/spec/std/isa/inst/Zicsr/csrrs.yaml +2 -2
  206. data/.data/spec/std/isa/inst/Zicsr/csrrsi.yaml +1 -1
  207. data/.data/spec/std/isa/inst/Zicsr/csrrw.yaml +1 -1
  208. data/.data/spec/std/isa/inst/Zicsr/csrrwi.yaml +1 -1
  209. data/.data/spec/std/isa/isa/builtin_functions.idl +17 -0
  210. data/.data/spec/std/isa/isa/fp.idl +1 -5
  211. data/.data/spec/std/isa/isa/globals.isa +45 -14
  212. data/.data/spec/std/isa/isa/vec.idl +1 -2
  213. data/.data/spec/std/isa/manual_version/isa/20240411/isa_20240411.yaml +5 -5
  214. data/.data/spec/std/isa/param/COUNTINHIBIT_EN.yaml +8 -2
  215. data/.data/spec/std/isa/param/JVT_BASE_MASK.yaml +1 -1
  216. data/.data/spec/std/isa/param/MCOUNTINHIBIT_IMPLEMENTED.yaml +25 -0
  217. data/.data/spec/std/isa/param/MTVEC_MODES.yaml +10 -3
  218. data/.data/spec/std/isa/param/VLEN.yaml +2 -0
  219. data/.data/spec/std/isa/profile/RVA20S64.yaml +11 -4
  220. data/.data/spec/std/isa/profile/RVA20U64.yaml +14 -5
  221. data/.data/spec/std/isa/profile/RVA22S64.yaml +14 -3
  222. data/.data/spec/std/isa/profile/RVA22U64.yaml +8 -1
  223. data/.data/spec/std/isa/profile/RVA23S64.yaml +13 -0
  224. data/.data/spec/std/isa/profile/RVA23U64.yaml +15 -1
  225. data/.data/spec/std/isa/profile/RVB23S64.yaml +15 -3
  226. data/.data/spec/std/isa/profile/RVB23U64.yaml +8 -1
  227. data/.data/spec/std/isa/profile/RVI20U32.yaml +8 -1
  228. data/.data/spec/std/isa/profile/RVI20U64.yaml +7 -0
  229. data/.data/spec/std/isa/register_file/F.yaml +3 -2
  230. data/.data/spec/std/isa/register_file/V.yaml +2 -2
  231. data/.data/spec/std/isa/register_file/X.yaml +2 -1
  232. data/lib/udb/architecture.rb +4 -25
  233. data/lib/udb/cfg_arch.rb +171 -59
  234. data/lib/udb/cli.rb +10 -1
  235. data/lib/udb/condition.rb +38 -37
  236. data/lib/udb/config.rb +72 -6
  237. data/lib/udb/logic.rb +47 -66
  238. data/lib/udb/obj/csr.rb +23 -5
  239. data/lib/udb/obj/csr_field.rb +36 -21
  240. data/lib/udb/obj/database_obj.rb +2 -5
  241. data/lib/udb/obj/extension.rb +0 -3
  242. data/lib/udb/obj/instruction.rb +1 -4
  243. data/lib/udb/obj/portfolio.rb +75 -20
  244. data/lib/udb/obj/profile.rb +0 -4
  245. data/lib/udb/obj/register_file.rb +63 -2
  246. data/lib/udb/portfolio_design.rb +3 -6
  247. data/lib/udb/resolver.rb +84 -23
  248. data/lib/udb/version.rb +1 -1
  249. data/lib/udb/version_spec.rb +8 -0
  250. data/lib/udb/z3.rb +23 -0
  251. data/lib/udb.rb +0 -3
  252. metadata +25 -37
  253. data/.data/cfgs/profile/RVA23M64.yaml +0 -159
  254. data/.data/cfgs/profile/RVB23M64.yaml +0 -149
  255. data/.data/spec/schemas/proc_cert_class_schema.json +0 -35
  256. data/.data/spec/schemas/proc_cert_model_schema.json +0 -336
  257. data/.data/spec/std/isa/proc_cert_class/AC.yaml +0 -13
  258. data/.data/spec/std/isa/proc_cert_class/MC.yaml +0 -13
  259. data/.data/spec/std/isa/proc_cert_class/RVI.yaml +0 -16
  260. data/.data/spec/std/isa/proc_cert_model/AC100.yaml +0 -72
  261. data/.data/spec/std/isa/proc_cert_model/AC200.yaml +0 -58
  262. data/.data/spec/std/isa/proc_cert_model/MC100-32.yaml +0 -155
  263. data/.data/spec/std/isa/proc_cert_model/MC100-64.yaml +0 -21
  264. data/.data/spec/std/isa/proc_cert_model/MC200-32.yaml +0 -60
  265. data/.data/spec/std/isa/proc_cert_model/MC200-64.yaml +0 -21
  266. data/.data/spec/std/isa/proc_cert_model/MC300-32.yaml +0 -40
  267. data/.data/spec/std/isa/proc_cert_model/MC300-64.yaml +0 -21
  268. data/.data/spec/std/isa/proc_cert_model/RVI20-32.yaml +0 -39
  269. data/.data/spec/std/isa/proc_cert_model/RVI20-64.yaml +0 -19
  270. data/.data/spec/std/isa/profile/RVA23M64.yaml +0 -24
  271. data/.data/spec/std/isa/profile/RVB23M64.yaml +0 -86
  272. data/lib/udb/cert_normative_rule.rb +0 -41
  273. data/lib/udb/obj/certifiable_obj.rb +0 -21
  274. data/lib/udb/obj/certificate.rb +0 -230
  275. data/lib/udb/proc_cert_design.rb +0 -77
data/lib/udb/config.rb CHANGED
@@ -63,6 +63,9 @@ module Udb
63
63
  sig { returns(String) }
64
64
  def description = @data["description"]
65
65
 
66
+ sig { returns(T.nilable(T.any(String, T::Array[String]))) }
67
+ def compatible = @data["compatible"]
68
+
66
69
  sig { abstract.returns(T.nilable(Integer)) }
67
70
  def mxlen; end
68
71
 
@@ -103,6 +106,8 @@ module Udb
103
106
 
104
107
  sig { params(obj: T.untyped).returns(T.untyped) }
105
108
  def self.freeze_data(obj)
109
+ return obj if obj.frozen?
110
+
106
111
  if obj.is_a?(Hash)
107
112
  obj.each do |k, v|
108
113
  obj[k] = freeze_data(v)
@@ -156,13 +161,29 @@ module Udb
156
161
  }
157
162
  end
158
163
  }
159
- data.fetch("params")["MXLEN"] = portfolio_grp.max_base
160
164
  freeze_data(data)
161
165
  PartialConfig.send(:new, data, info)
162
166
  else
163
167
  T.absurd(cfg_file_path_or_portfolio_grp)
164
168
  end
165
169
  end
170
+
171
+ # Create an AbstractConfig directly from a config data hash, bypassing file I/O.
172
+ # Used when the config is already in memory (e.g., portfolio-derived temp configs).
173
+ sig { params(data: T::Hash[String, T.untyped], info: Resolver::ConfigInfo).returns(AbstractConfig) }
174
+ def self.create_from_data(data, info)
175
+ freeze_data(data)
176
+ case data["type"]
177
+ when "fully configured"
178
+ FullConfig.send(:new, data, info)
179
+ when "partially configured"
180
+ PartialConfig.send(:new, data, info)
181
+ when "unconfigured"
182
+ UnConfig.send(:new, data, info)
183
+ else
184
+ raise "Unexpected type (#{data['type']}) in config"
185
+ end
186
+ end
166
187
  end
167
188
 
168
189
  #################################################################
@@ -220,12 +241,25 @@ module Udb
220
241
  @param_values = @data.key?("params") ? @data["params"] : [].freeze
221
242
 
222
243
  @mxlen = @data.dig("params", "MXLEN")
244
+
223
245
  if @mxlen.nil?
224
- Udb.logger.error "Must set MXLEN for a configured config"
225
- raise InvalidConfigError
246
+ # Infer MXLEN from subordinate mode XLENs: if any of UXLEN/SXLEN/VSXLEN/VUXLEN
247
+ # can be 64, then MXLEN must be 64 (lower modes cannot exceed machine-mode width).
248
+ MODE_XLEN_PARAMS.each do |param|
249
+ val = @data.dig("params", param)
250
+ if val == 64 || (val.is_a?(Array) && val.include?(64))
251
+ @mxlen = 64
252
+ break
253
+ end
254
+ end
255
+
256
+ if @mxlen.nil?
257
+ param_req = @data.dig("requirements", "param")
258
+ @mxlen = 64 if !param_req.nil? && param_req_implies_64?(param_req)
259
+ end
226
260
  end
227
261
 
228
- @mxlen.freeze
262
+ @mxlen.freeze unless @mxlen.nil?
229
263
  end
230
264
 
231
265
  ###############################
@@ -235,7 +269,7 @@ module Udb
235
269
  sig { override.returns(T::Hash[String, ParamValueType]) }
236
270
  def param_values = @param_values
237
271
 
238
- sig { override.returns(Integer) }
272
+ sig { override.returns(T.nilable(Integer)) }
239
273
  def mxlen = @mxlen
240
274
 
241
275
  sig { override.returns(T::Boolean) }
@@ -301,6 +335,37 @@ module Udb
301
335
 
302
336
  sig { returns(T.nilable(T::Hash[String, T.untyped])) }
303
337
  def requirements = @data["requirements"]
338
+
339
+ private
340
+
341
+ MODE_XLEN_PARAMS = %w[UXLEN SXLEN VSXLEN VUXLEN].freeze
342
+
343
+ # Returns true if the param requirements condition guarantees that at least one
344
+ # subordinate-mode XLEN param must be 64, which implies MXLEN = 64.
345
+ #
346
+ # Entailment rules:
347
+ # allOf: any child entailing 64 is sufficient (all must hold)
348
+ # anyOf: all children must entail 64 (only one needs to hold, so we can't
349
+ # conclude 64 unless every branch requires it)
350
+ # noneOf/not/if/oneOf: too complex to reason about without a solver → false
351
+ # leaf with a MODE_XLEN_PARAMS name and equal/includes 64 → true
352
+ # anything else (extension, xlen, idl, other params) → false
353
+ sig { params(yaml: T.untyped).returns(T::Boolean) }
354
+ def param_req_implies_64?(yaml)
355
+ return false unless yaml.is_a?(Hash)
356
+
357
+ if yaml.key?("allOf")
358
+ yaml["allOf"].any? { |child| param_req_implies_64?(child) }
359
+ elsif yaml.key?("anyOf")
360
+ yaml["anyOf"].all? { |child| param_req_implies_64?(child) }
361
+ elsif yaml.key?("param")
362
+ param_req_implies_64?(yaml["param"])
363
+ elsif yaml.key?("name") && MODE_XLEN_PARAMS.include?(yaml["name"])
364
+ yaml["equal"] == 64 || yaml["includes"] == 64
365
+ else
366
+ false
367
+ end
368
+ end
304
369
  end
305
370
 
306
371
  ################################################################################################################
@@ -320,7 +385,7 @@ module Udb
320
385
 
321
386
  @mxlen = @data.dig("params", "MXLEN").freeze
322
387
  if @mxlen.nil?
323
- Udb.logger.error "Must set MXLEN for a configured config"
388
+ Udb.logger.error "Must set MXLEN for a full config"
324
389
  raise InvalidConfigError
325
390
  end
326
391
  end
@@ -359,5 +424,6 @@ module Udb
359
424
  end
360
425
  end
361
426
  end
427
+
362
428
  end
363
429
  end
data/lib/udb/logic.rb CHANGED
@@ -293,7 +293,10 @@ module Udb
293
293
  .checked(:never)
294
294
  }
295
295
  def eql?(other)
296
- (self <=> other) == 0
296
+ return false unless other.is_a?(ExtensionTerm)
297
+ return false unless hash == other.hash
298
+
299
+ to_s == other.to_s
297
300
  end
298
301
 
299
302
  end
@@ -316,13 +319,17 @@ module Udb
316
319
  end
317
320
  end
318
321
 
319
- ValueType = T.type_alias { T.any(Integer, String, T::Boolean, T::Array[T.any(Integer, String)]) }
322
+ ValueType = T.type_alias { T.any(Integer, String, T::Boolean, T::Array[T.any(Integer, String, T::Boolean)]) }
320
323
 
321
324
  sig { params(yaml: T::Hash[String, T.untyped]).void }
322
325
  def initialize(yaml)
323
326
  @yaml = yaml
327
+ @yaml_no_reason = yaml.key?("reason") ? yaml.reject { |k, _| k == "reason" }.freeze : yaml
324
328
  end
325
329
 
330
+ sig { returns(T::Hash[String, T.untyped]) }
331
+ def yaml_no_reason = @yaml_no_reason
332
+
326
333
  sig { returns(String) }
327
334
  def name = @yaml.fetch("name")
328
335
 
@@ -1034,9 +1041,11 @@ module Udb
1034
1041
  elsif !@yaml.key?("includes") && other_param.to_h.key?("includes")
1035
1042
  -1
1036
1043
  end
1037
- elsif @yaml.key?("oneOf") || other_param.to_h.key?("oneOf")
1038
- if @yaml.key?("oneOf") && other_param.to_h.key?("oneOf")
1039
- @yaml.fetch("oneOf") <=> other_param.to_h.fetch("oneOf")
1044
+ elsif @yaml.key?("oneOf") || other_param.comparison_type == ParameterComparisonType::OneOf
1045
+ if @yaml.key?("oneOf") && other_param.comparison_type == ParameterComparisonType::OneOf
1046
+ one_of = @yaml.fetch("oneOf")
1047
+ other_one_of = T.cast(other_param.comparison_value, T::Array[T.untyped])
1048
+ one_of.map { |e| [e.class.name, e.to_s] } <=> other_one_of.map { |e| [e.class.name, e.to_s] }
1040
1049
  elsif @yaml.key?("oneOf")
1041
1050
  1
1042
1051
  else
@@ -1054,14 +1063,20 @@ module Udb
1054
1063
  comparison_type <=> other_param.comparison_type
1055
1064
  elsif comparison_value != other_param.comparison_value
1056
1065
  cv = comparison_value
1057
- if cv.is_a?(String)
1058
- cv <=> T.cast(other_param.comparison_value, String)
1066
+ ocv = other_param.comparison_value
1067
+ if cv.class != ocv.class
1068
+ cv.class.name <=> ocv.class.name
1069
+ elsif cv.is_a?(String)
1070
+ cv <=> T.cast(ocv, String)
1059
1071
  elsif cv.is_a?(Array)
1060
- cv <=> T.cast(other_param.comparison_value, T::Array[T.any(String, T::Boolean, Integer)])
1061
- elsif cv.is_a?(Integer)
1062
- T.cast(comparison_value, Integer) <=> T.cast(other_param.comparison_value, Integer)
1072
+ ocv_arr = T.cast(ocv, T::Array[T.any(String, T::Boolean, Integer)])
1073
+ cv.map { |e| [e.class.name, e.to_s] } <=> ocv_arr.map { |e| [e.class.name, e.to_s] }
1063
1074
  else
1064
- T.cast(comparison_value, T::Boolean) <=> T.cast(other_param.comparison_value, T::Boolean)
1075
+ # cv and ocv have the same class (not String, not Array).
1076
+ # Given the type constraints (String, Boolean, Integer), this is Integer.
1077
+ # Two booleans with the same value are equal (cv != ocv is false), so
1078
+ # TrueClass or FalseClass values never reach here.
1079
+ T.cast(cv, Integer) <=> T.cast(ocv, Integer)
1065
1080
  end
1066
1081
  else
1067
1082
  # these are the same (ignoring reason)
@@ -1075,7 +1090,7 @@ module Udb
1075
1090
  .returns(Integer)
1076
1091
  .checked(:never)
1077
1092
  }
1078
- def hash = @hash ||= @yaml.reject { |k, _| k == "reason" }.hash
1093
+ def hash = @hash ||= @yaml_no_reason.hash
1079
1094
 
1080
1095
  sig {
1081
1096
  override
@@ -1085,8 +1100,9 @@ module Udb
1085
1100
  }
1086
1101
  def eql?(other)
1087
1102
  return false unless other.is_a?(ParameterTerm)
1103
+ return false unless hash == other.hash
1088
1104
 
1089
- (self <=> other) == 0
1105
+ @yaml_no_reason == other.yaml_no_reason
1090
1106
  end
1091
1107
  end
1092
1108
 
@@ -1218,37 +1234,8 @@ module Udb
1218
1234
  # object to hold results of expensive calculations
1219
1235
  # LogicNode type and children are frozen at construction so
1220
1236
  # we can safely remember and return these values
1221
- class MemoizedState < T::Struct
1222
- # when true, the formula is known to be in CNF form
1223
- # when false, the formula is known to not be in CNF form
1224
- prop :is_cnf, T.nilable(T::Boolean)
1225
-
1226
- # when not nil, an equisatisfiable representation of self in CNF form
1227
- prop :cnf_form, T.nilable(LogicNode)
1228
-
1229
- # when true, a flattened version of the formula would be CNF
1230
- # when false, a flattened version of the formula would not be CNF
1231
- prop :is_nested_cnf, T.nilable(T::Boolean)
1232
-
1233
- # when true, the formula would be unaltered by calling reduce
1234
- # when false, the formula would be reduced further by calling reduce
1235
- prop :is_reduced, T.nilable(T::Boolean)
1236
-
1237
- # list of terms in the formula
1238
- prop :terms, T.nilable(T::Array[TermType])
1239
-
1240
- # list of literals in the formula
1241
- prop :literals, T.nilable(T::Array[TermType])
1242
-
1243
- # when true, formula is known to be satisfiable
1244
- # when false, formula is known to be unsatisfiable
1245
- prop :is_satisfiable, T.nilable(T::Boolean)
1246
-
1247
- # result of #equisat_cnf
1248
- prop :equisat_cnf, T.nilable(LogicNode)
1249
-
1250
- # result of #equisat_cnf
1251
- prop :equiv_cnf, T.nilable(LogicNode)
1237
+ class MemoizedState
1238
+ attr_accessor :is_cnf, :cnf_form, :is_nested_cnf, :is_reduced, :terms, :literals, :is_satisfiable, :equisat_cnf, :equiv_cnf, :terms_no_antecendents
1252
1239
  end
1253
1240
 
1254
1241
  attr_accessor :memo
@@ -1280,16 +1267,7 @@ module Udb
1280
1267
  @type.freeze
1281
1268
 
1282
1269
  # used for memoization in transformation routines
1283
- @memo = MemoizedState.new(
1284
- is_cnf: nil,
1285
- is_nested_cnf: nil,
1286
- is_reduced: nil,
1287
- terms: nil,
1288
- literals: nil,
1289
- is_satisfiable: nil,
1290
- equisat_cnf: nil,
1291
- equiv_cnf: nil
1292
- )
1270
+ @memo = MemoizedState.new
1293
1271
  end
1294
1272
 
1295
1273
  # @api private
@@ -1352,21 +1330,24 @@ module Udb
1352
1330
  # @return The unique terms (leafs) of this tree, exculding antecendents of an IF
1353
1331
  sig { returns(T::Array[TermType]).checked(:never) }
1354
1332
  def terms_no_antecendents
1355
- if @type == LogicNodeType::If
1356
- node_children.fetch(1).terms_no_antecendents
1357
- elsif @type == LogicNodeType::Term
1358
- [T.cast(@children.fetch(0), TermType)]
1359
- else
1360
- seen = {}
1361
- node_children.each_with_object([]) do |child, result|
1362
- child.terms_no_antecendents.each do |t|
1363
- unless seen.key?(t)
1364
- seen[t] = true
1365
- result << t
1333
+ return @memo.terms_no_antecendents unless @memo.terms_no_antecendents.nil?
1334
+
1335
+ @memo.terms_no_antecendents =
1336
+ if @type == LogicNodeType::If
1337
+ node_children.fetch(1).terms_no_antecendents
1338
+ elsif @type == LogicNodeType::Term
1339
+ [T.cast(@children.fetch(0), TermType)]
1340
+ else
1341
+ seen = {}
1342
+ node_children.each_with_object([]) do |child, result|
1343
+ child.terms_no_antecendents.each do |t|
1344
+ unless seen.key?(t)
1345
+ seen[t] = true
1346
+ result << t
1347
+ end
1366
1348
  end
1367
1349
  end
1368
1350
  end
1369
- end
1370
1351
  end
1371
1352
 
1372
1353
  # @return all unique literals (leafs) in the tree
data/lib/udb/obj/csr.rb CHANGED
@@ -9,7 +9,6 @@ require "idlc/interfaces"
9
9
  require "idlc/passes/reachable_functions"
10
10
 
11
11
  require_relative "database_obj"
12
- require_relative "certifiable_obj"
13
12
  require_relative "has_fields"
14
13
 
15
14
  module Udb
@@ -22,7 +21,6 @@ module Udb
22
21
  BITS128_TYPE = Idl::Type.new(:bits, width: 128).freeze
23
22
  ENCODING_SIZE_VAR = Idl::Var.new("__instruction_encoding_size", BITS6_TYPE, 32).freeze
24
23
  # Add all methods in this module to this type of database object.
25
- include CertifiableObject
26
24
  include HasFields
27
25
 
28
26
  include Idl::Csr
@@ -520,8 +518,8 @@ module Udb
520
518
  def sw_read_ast(symtab)
521
519
  raise ArgumentError, "Argument should be a symtab" unless symtab.is_a?(Idl::SymbolTable)
522
520
 
523
- return @sw_read_ast unless @sw_read_ast.nil?
524
- return nil if @data["sw_read()"].nil?
521
+ return @sw_read_ast if instance_variable_defined?(:@sw_read_ast)
522
+ return (@sw_read_ast = nil) if @data["sw_read()"].nil?
525
523
 
526
524
  # now, parse the function
527
525
  @sw_read_ast = @cfg_arch.idl_compiler.compile_func_body(
@@ -568,6 +566,7 @@ module Udb
568
566
  end
569
567
 
570
568
  # @param effective_xlen [Integer or nil] 32 or 64 for fixed xlen, nil for dynamic
569
+ # @return [FunctionBodyAst] Pruned (but not re-type-checked) AST for sw_read()
571
570
  def pruned_sw_read_ast(effective_xlen)
572
571
  raise ArgumentError, "effective_xlen is non-nil and is a #{effective_xlen.class} but must be an Integer" unless effective_xlen.nil? || effective_xlen.is_a?(Integer)
573
572
  @pruned_sw_read_ast ||= {}
@@ -580,6 +579,25 @@ module Udb
580
579
  ast = ast.prune(symtab)
581
580
  ast.freeze_tree(@cfg_arch.symtab)
582
581
 
582
+ symtab.pop
583
+ symtab.release
584
+
585
+ @pruned_sw_read_ast[effective_xlen] = ast
586
+ end
587
+
588
+ # @param effective_xlen [Integer or nil] 32 or 64 for fixed xlen, nil for dynamic
589
+ # @return [FunctionBodyAst] Pruned and re-type-checked AST for sw_read()
590
+ # Use this when you need the AST to be fully type-checked (e.g., for the type_check pass).
591
+ # For reachable_functions, use pruned_sw_read_ast directly.
592
+ def type_checked_pruned_sw_read_ast(effective_xlen)
593
+ raise ArgumentError, "effective_xlen is non-nil and is a #{effective_xlen.class} but must be an Integer" unless effective_xlen.nil? || effective_xlen.is_a?(Integer)
594
+ @type_checked_pruned_sw_read_ast ||= {}
595
+ return @type_checked_pruned_sw_read_ast[effective_xlen] if @type_checked_pruned_sw_read_ast.key?(effective_xlen)
596
+
597
+ ast = pruned_sw_read_ast(effective_xlen)
598
+
599
+ symtab = fill_symtab(type_checked_sw_read_ast(effective_xlen), effective_xlen)
600
+
583
601
  @cfg_arch.idl_compiler.type_check(
584
602
  ast,
585
603
  symtab,
@@ -589,7 +607,7 @@ module Udb
589
607
  symtab.pop
590
608
  symtab.release
591
609
 
592
- @pruned_sw_read_ast[effective_xlen] = ast
610
+ @type_checked_pruned_sw_read_ast[effective_xlen] = ast
593
611
  end
594
612
 
595
613
  # @param cfg_arch [ConfiguredArchitecture] Architecture def
@@ -8,7 +8,6 @@ require "sorbet-runtime"
8
8
  require "idlc/passes/gen_option_adoc"
9
9
 
10
10
  require_relative "database_obj"
11
- require_relative "certifiable_obj"
12
11
 
13
12
  module Udb
14
13
 
@@ -16,9 +15,6 @@ module Udb
16
15
  class CsrField < DatabaseObject
17
16
  extend T::Sig
18
17
 
19
- # Add all methods in this module to this type of database object.
20
- include CertifiableObject
21
-
22
18
  include Idl::CsrField
23
19
 
24
20
  # @return [Csr, Mmr] The Csr or Mmr that defines this field
@@ -60,6 +56,19 @@ module Udb
60
56
  @memo = MemoizedState.new(reachable_functions: {})
61
57
  end
62
58
 
59
+ # When a field has no definedBy of its own, it inherits the parent CSR's condition.
60
+ # Returning the parent's condition object directly lets us reuse its memoized
61
+ # satisfied_by_cfg_arch? result instead of re-evaluating an equivalent condition.
62
+ sig { override.returns(AbstractCondition) }
63
+ def defined_by_condition
64
+ @defined_by_condition ||=
65
+ if @data.key?("definedBy")
66
+ Condition.new(@data["definedBy"], @cfg_arch)
67
+ else
68
+ @parent.defined_by_condition
69
+ end
70
+ end
71
+
63
72
  # CSR fields are defined in their parent CSR YAML file
64
73
  def __source = @parent.__source
65
74
 
@@ -75,6 +84,11 @@ module Udb
75
84
  # @return [Boolean] True if this field might exist in a config
76
85
  sig { params(cfg_arch: ConfiguredArchitecture).returns(T::Boolean) }
77
86
  def exists_in_cfg?(cfg_arch)
87
+ # When the field has no definedBy of its own, its existence is identical to the parent's.
88
+ # base is also nil in this case (no xlen restriction from the condition), so we can
89
+ # skip the condition evaluation entirely and just delegate to the parent.
90
+ return parent.exists_in_cfg?(cfg_arch) unless @data.key?("definedBy")
91
+
78
92
  if cfg_arch.fully_configured?
79
93
  parent.exists_in_cfg?(cfg_arch) &&
80
94
  (base.nil? || cfg_arch.possible_xlens.include?(base)) &&
@@ -116,8 +130,8 @@ module Udb
116
130
  # @return [nil] if the type property is not a function
117
131
  sig { returns(T.nilable(Idl::FunctionBodyAst)) }
118
132
  def type_ast
119
- return @type_ast unless @type_ast.nil?
120
- return nil if @data["type()"].nil?
133
+ return @type_ast if instance_variable_defined?(:@type_ast)
134
+ return (@type_ast = nil) if @data["type()"].nil?
121
135
 
122
136
  idl_code = T.must(@data["type()"])
123
137
 
@@ -370,8 +384,8 @@ module Udb
370
384
  # @return [nil] If the reset_value is not a function
371
385
  sig { returns(T.nilable(Idl::FunctionBodyAst)) }
372
386
  def reset_value_ast
373
- return @reset_value_ast unless @reset_value_ast.nil?
374
- return nil unless @data.key?("reset_value()")
387
+ return @reset_value_ast if instance_variable_defined?(:@reset_value_ast)
388
+ return (@reset_value_ast = nil) unless @data.key?("reset_value()")
375
389
 
376
390
  @reset_value_ast = cfg_arch.idl_compiler.compile_func_body(
377
391
  @data["reset_value()"],
@@ -388,9 +402,9 @@ module Udb
388
402
  # @return [nil] If the reset_value is not a function
389
403
  sig { returns(T.nilable(Idl::FunctionBodyAst)) }
390
404
  def type_checked_reset_value_ast
391
- return @type_checked_reset_value_ast unless @type_checked_reset_value_ast.nil?
405
+ return @type_checked_reset_value_ast if instance_variable_defined?(:@type_checked_reset_value_ast)
392
406
 
393
- return nil unless @data.key?("reset_value()")
407
+ return (@type_checked_reset_value_ast = nil) unless @data.key?("reset_value()")
394
408
 
395
409
  ast = reset_value_ast
396
410
 
@@ -409,9 +423,9 @@ module Udb
409
423
  # @return [nil] If the reset_value is not a function
410
424
  sig { returns(T.nilable(Idl::FunctionBodyAst)) }
411
425
  def pruned_reset_value_ast
412
- return @pruned_reset_value_ast unless @pruned_reset_value_ast.nil?
426
+ return @pruned_reset_value_ast if instance_variable_defined?(:@pruned_reset_value_ast)
413
427
 
414
- return nil unless @data.key?("reset_value()")
428
+ return (@pruned_reset_value_ast = nil) unless @data.key?("reset_value()")
415
429
 
416
430
  ast = T.must(type_checked_reset_value_ast)
417
431
 
@@ -517,8 +531,8 @@ module Udb
517
531
  # @param symtab [Idl::SymbolTable] Symbols
518
532
  sig { params(symtab: Idl::SymbolTable).returns(T.nilable(Idl::FunctionBodyAst)) }
519
533
  def sw_write_ast(symtab)
520
- return @sw_write_ast unless @sw_write_ast.nil?
521
- return nil if @data["sw_write(csr_value)"].nil?
534
+ return @sw_write_ast if instance_variable_defined?(:@sw_write_ast)
535
+ return (@sw_write_ast = nil) if @data["sw_write(csr_value)"].nil?
522
536
 
523
537
  # now, parse the function
524
538
  @sw_write_ast = @cfg_arch.idl_compiler.compile_func_body(
@@ -610,13 +624,14 @@ module Udb
610
624
  # @param effective_xlen [Integer] effective xlen, needed because fields can change in different bases
611
625
  sig { params(effective_xlen: T.nilable(Integer)).returns(T.nilable(Idl::AstNode)) }
612
626
  def pruned_sw_write_ast(effective_xlen)
613
- return @pruned_sw_write_ast unless @pruned_sw_write_ast.nil?
627
+ @pruned_sw_write_ast ||= {}
628
+ return @pruned_sw_write_ast[effective_xlen] if @pruned_sw_write_ast.key?(effective_xlen)
614
629
 
615
- return nil unless @data.key?("sw_write(csr_value)")
630
+ return (@pruned_sw_write_ast[effective_xlen] = nil) unless @data.key?("sw_write(csr_value)")
616
631
 
617
632
  ast = T.must(type_checked_sw_write_ast(cfg_arch.symtab, effective_xlen))
618
633
 
619
- return ast if cfg_arch.unconfigured?
634
+ return (@pruned_sw_write_ast[effective_xlen] = ast) if cfg_arch.unconfigured?
620
635
 
621
636
  symtab = fill_symtab_for_sw_write(effective_xlen, ast)
622
637
 
@@ -634,7 +649,7 @@ module Udb
634
649
  symtab.pop
635
650
  symtab.release
636
651
 
637
- @pruned_sw_write_ast = ast
652
+ @pruned_sw_write_ast[effective_xlen] = ast
638
653
  end
639
654
 
640
655
  # @param cfg_arch [ConfiguredArchitecture] A config. May be nil if the location is not configturation-dependent
@@ -751,7 +766,7 @@ module Udb
751
766
  sig { returns(String) }
752
767
  def location_cond32
753
768
  case csr.priv_mode
754
- when "M"
769
+ when "M", "D"
755
770
  "CSR[misa].MXL == 0"
756
771
  when "S"
757
772
  "CSR[mstatus].SXL == 0"
@@ -767,7 +782,7 @@ module Udb
767
782
  sig { returns(String) }
768
783
  def location_cond64
769
784
  case csr.priv_mode
770
- when "M"
785
+ when "M", "D"
771
786
  "CSR[misa].MXL == 1"
772
787
  when "S"
773
788
  "CSR[mstatus].SXL == 1"
@@ -793,7 +808,7 @@ module Udb
793
808
  if dynamic_location?
794
809
  condition =
795
810
  case csr.priv_mode
796
- when "M"
811
+ when "M", "D"
797
812
  "CSR[misa].MXL == %%"
798
813
  when "S"
799
814
  "CSR[mstatus].SXL == %%"
@@ -33,8 +33,6 @@ module Udb
33
33
  InterruptCode = new("interrupt_code")
34
34
  Manual = new("manual")
35
35
  ManualVersion = new("manual version")
36
- ProcessorCertificateClass = new("processor certificate class")
37
- ProcessorCertificateModel = new("processor certificate model")
38
36
  Profile = new("profile")
39
37
  ProfileFamily = new("profile family")
40
38
  ProfileRelease = new("profile release")
@@ -136,10 +134,9 @@ module Udb
136
134
  # defer the calculation of 'blk' until later, then memoize the result
137
135
  sig { params(fn_name: Symbol, _block: T.proc.void).returns(T.untyped) }
138
136
  def defer(fn_name, &_block)
139
- cache_value = @cache[fn_name]
140
- return cache_value unless cache_value.nil?
137
+ return @cache[fn_name] if @cache.key?(fn_name)
141
138
 
142
- @cache[fn_name] ||= yield
139
+ @cache[fn_name] = yield
143
140
  end
144
141
 
145
142
  # @return Condition for when the object exists
@@ -5,7 +5,6 @@
5
5
  # frozen_string_literal: true
6
6
 
7
7
  require_relative "database_obj"
8
- require_relative "certifiable_obj"
9
8
  require_relative "parameter"
10
9
  require_relative "../schema"
11
10
  require_relative "../condition"
@@ -16,8 +15,6 @@ module Udb
16
15
 
17
16
  # Extension definition
18
17
  class Extension < TopLevelDatabaseObject
19
- # Add all methods in this module to this type of database object.
20
- include CertifiableObject
21
18
  include Comparable
22
19
 
23
20
  # @return Long name of the extension
@@ -7,7 +7,6 @@
7
7
  # require 'ruby-prof-flamegraph'
8
8
 
9
9
  require_relative "database_obj"
10
- require_relative "certifiable_obj"
11
10
  require_relative "../presence"
12
11
  require "udb_helpers/backend_helpers"
13
12
  require "awesome_print"
@@ -110,8 +109,6 @@ module Udb
110
109
 
111
110
  # model of a specific instruction in a specific base (RV32/RV64)
112
111
  class Instruction < TopLevelDatabaseObject
113
- # Add all methods in this module to this type of database object.
114
- include CertifiableObject
115
112
  include Helpers::WavedromUtil
116
113
 
117
114
  class MemoizedState < T::Struct
@@ -1104,7 +1101,7 @@ module Udb
1104
1101
  # @return [FunctionBodyAst] A type-checked abstract syntax tree of the operation
1105
1102
  # @param effective_xlen [Integer] 32 or 64, the effective xlen to type check against
1106
1103
  def type_checked_operation_ast(effective_xlen)
1107
- defer :type_checked_operation_ast do
1104
+ defer :"type_checked_operation_ast_#{effective_xlen}" do
1108
1105
  return nil unless @data.key?("operation()")
1109
1106
 
1110
1107
  ast = operation_ast