udb 0.1.9 → 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 +29 -56
  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
@@ -321,8 +324,12 @@ module Udb
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
 
@@ -1083,7 +1090,7 @@ module Udb
1083
1090
  .returns(Integer)
1084
1091
  .checked(:never)
1085
1092
  }
1086
- def hash = @hash ||= @yaml.reject { |k, _| k == "reason" }.hash
1093
+ def hash = @hash ||= @yaml_no_reason.hash
1087
1094
 
1088
1095
  sig {
1089
1096
  override
@@ -1093,8 +1100,9 @@ module Udb
1093
1100
  }
1094
1101
  def eql?(other)
1095
1102
  return false unless other.is_a?(ParameterTerm)
1103
+ return false unless hash == other.hash
1096
1104
 
1097
- (self <=> other) == 0
1105
+ @yaml_no_reason == other.yaml_no_reason
1098
1106
  end
1099
1107
  end
1100
1108
 
@@ -1226,37 +1234,8 @@ module Udb
1226
1234
  # object to hold results of expensive calculations
1227
1235
  # LogicNode type and children are frozen at construction so
1228
1236
  # we can safely remember and return these values
1229
- class MemoizedState < T::Struct
1230
- # when true, the formula is known to be in CNF form
1231
- # when false, the formula is known to not be in CNF form
1232
- prop :is_cnf, T.nilable(T::Boolean)
1233
-
1234
- # when not nil, an equisatisfiable representation of self in CNF form
1235
- prop :cnf_form, T.nilable(LogicNode)
1236
-
1237
- # when true, a flattened version of the formula would be CNF
1238
- # when false, a flattened version of the formula would not be CNF
1239
- prop :is_nested_cnf, T.nilable(T::Boolean)
1240
-
1241
- # when true, the formula would be unaltered by calling reduce
1242
- # when false, the formula would be reduced further by calling reduce
1243
- prop :is_reduced, T.nilable(T::Boolean)
1244
-
1245
- # list of terms in the formula
1246
- prop :terms, T.nilable(T::Array[TermType])
1247
-
1248
- # list of literals in the formula
1249
- prop :literals, T.nilable(T::Array[TermType])
1250
-
1251
- # when true, formula is known to be satisfiable
1252
- # when false, formula is known to be unsatisfiable
1253
- prop :is_satisfiable, T.nilable(T::Boolean)
1254
-
1255
- # result of #equisat_cnf
1256
- prop :equisat_cnf, T.nilable(LogicNode)
1257
-
1258
- # result of #equisat_cnf
1259
- 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
1260
1239
  end
1261
1240
 
1262
1241
  attr_accessor :memo
@@ -1288,16 +1267,7 @@ module Udb
1288
1267
  @type.freeze
1289
1268
 
1290
1269
  # used for memoization in transformation routines
1291
- @memo = MemoizedState.new(
1292
- is_cnf: nil,
1293
- is_nested_cnf: nil,
1294
- is_reduced: nil,
1295
- terms: nil,
1296
- literals: nil,
1297
- is_satisfiable: nil,
1298
- equisat_cnf: nil,
1299
- equiv_cnf: nil
1300
- )
1270
+ @memo = MemoizedState.new
1301
1271
  end
1302
1272
 
1303
1273
  # @api private
@@ -1360,21 +1330,24 @@ module Udb
1360
1330
  # @return The unique terms (leafs) of this tree, exculding antecendents of an IF
1361
1331
  sig { returns(T::Array[TermType]).checked(:never) }
1362
1332
  def terms_no_antecendents
1363
- if @type == LogicNodeType::If
1364
- node_children.fetch(1).terms_no_antecendents
1365
- elsif @type == LogicNodeType::Term
1366
- [T.cast(@children.fetch(0), TermType)]
1367
- else
1368
- seen = {}
1369
- node_children.each_with_object([]) do |child, result|
1370
- child.terms_no_antecendents.each do |t|
1371
- unless seen.key?(t)
1372
- seen[t] = true
1373
- 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
1374
1348
  end
1375
1349
  end
1376
1350
  end
1377
- end
1378
1351
  end
1379
1352
 
1380
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