udb 0.1.9 → 0.1.14

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 (414) hide show
  1. checksums.yaml +4 -4
  2. data/.data/cfgs/example_rv64_with_overlay.yaml +20 -20
  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 +8 -1
  16. data/.data/cfgs/rv32-riscv-tests.yaml +6 -2
  17. data/.data/cfgs/rv32-vector.yaml +6 -2
  18. data/.data/cfgs/rv64-riscv-tests.yaml +6 -2
  19. data/.data/cfgs/rv64-vector.yaml +6 -2
  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 +290 -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 +136 -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 +134 -0
  31. data/.data/spec/schemas/config_schema.json +220 -27
  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/mmr_schema.json +3 -3
  36. data/.data/spec/schemas/profile_release_schema.json +1 -1
  37. data/.data/spec/schemas/profile_schema.json +0 -3
  38. data/.data/spec/schemas/register_file_schema.json +8 -3
  39. data/.data/spec/schemas/schema_defs.json +13 -27
  40. data/.data/spec/std/isa/csr/H/henvcfg.yaml +25 -0
  41. data/.data/spec/std/isa/csr/I/pmpaddr0.yaml +6 -4
  42. data/.data/spec/std/isa/csr/I/pmpaddr1.yaml +6 -4
  43. data/.data/spec/std/isa/csr/I/pmpaddr10.yaml +6 -4
  44. data/.data/spec/std/isa/csr/I/pmpaddr11.yaml +6 -4
  45. data/.data/spec/std/isa/csr/I/pmpaddr12.yaml +6 -4
  46. data/.data/spec/std/isa/csr/I/pmpaddr13.yaml +6 -4
  47. data/.data/spec/std/isa/csr/I/pmpaddr14.yaml +6 -4
  48. data/.data/spec/std/isa/csr/I/pmpaddr15.yaml +6 -4
  49. data/.data/spec/std/isa/csr/I/pmpaddr16.yaml +6 -4
  50. data/.data/spec/std/isa/csr/I/pmpaddr17.yaml +6 -4
  51. data/.data/spec/std/isa/csr/I/pmpaddr18.yaml +6 -4
  52. data/.data/spec/std/isa/csr/I/pmpaddr19.yaml +6 -4
  53. data/.data/spec/std/isa/csr/I/pmpaddr2.yaml +6 -4
  54. data/.data/spec/std/isa/csr/I/pmpaddr20.yaml +6 -4
  55. data/.data/spec/std/isa/csr/I/pmpaddr21.yaml +6 -4
  56. data/.data/spec/std/isa/csr/I/pmpaddr22.yaml +6 -4
  57. data/.data/spec/std/isa/csr/I/pmpaddr23.yaml +6 -4
  58. data/.data/spec/std/isa/csr/I/pmpaddr24.yaml +6 -4
  59. data/.data/spec/std/isa/csr/I/pmpaddr25.yaml +6 -4
  60. data/.data/spec/std/isa/csr/I/pmpaddr26.yaml +6 -4
  61. data/.data/spec/std/isa/csr/I/pmpaddr27.yaml +6 -4
  62. data/.data/spec/std/isa/csr/I/pmpaddr28.yaml +6 -4
  63. data/.data/spec/std/isa/csr/I/pmpaddr29.yaml +6 -4
  64. data/.data/spec/std/isa/csr/I/pmpaddr3.yaml +6 -4
  65. data/.data/spec/std/isa/csr/I/pmpaddr30.yaml +6 -4
  66. data/.data/spec/std/isa/csr/I/pmpaddr31.yaml +6 -4
  67. data/.data/spec/std/isa/csr/I/pmpaddr32.yaml +6 -4
  68. data/.data/spec/std/isa/csr/I/pmpaddr33.yaml +6 -4
  69. data/.data/spec/std/isa/csr/I/pmpaddr34.yaml +6 -4
  70. data/.data/spec/std/isa/csr/I/pmpaddr35.yaml +6 -4
  71. data/.data/spec/std/isa/csr/I/pmpaddr36.yaml +6 -4
  72. data/.data/spec/std/isa/csr/I/pmpaddr37.yaml +6 -4
  73. data/.data/spec/std/isa/csr/I/pmpaddr38.yaml +6 -4
  74. data/.data/spec/std/isa/csr/I/pmpaddr39.yaml +6 -4
  75. data/.data/spec/std/isa/csr/I/pmpaddr4.yaml +6 -4
  76. data/.data/spec/std/isa/csr/I/pmpaddr40.yaml +6 -4
  77. data/.data/spec/std/isa/csr/I/pmpaddr41.yaml +6 -4
  78. data/.data/spec/std/isa/csr/I/pmpaddr42.yaml +6 -4
  79. data/.data/spec/std/isa/csr/I/pmpaddr43.yaml +6 -4
  80. data/.data/spec/std/isa/csr/I/pmpaddr44.yaml +6 -4
  81. data/.data/spec/std/isa/csr/I/pmpaddr45.yaml +6 -4
  82. data/.data/spec/std/isa/csr/I/pmpaddr46.yaml +6 -4
  83. data/.data/spec/std/isa/csr/I/pmpaddr47.yaml +6 -4
  84. data/.data/spec/std/isa/csr/I/pmpaddr48.yaml +6 -4
  85. data/.data/spec/std/isa/csr/I/pmpaddr49.yaml +6 -4
  86. data/.data/spec/std/isa/csr/I/pmpaddr5.yaml +6 -4
  87. data/.data/spec/std/isa/csr/I/pmpaddr50.yaml +6 -4
  88. data/.data/spec/std/isa/csr/I/pmpaddr51.yaml +6 -4
  89. data/.data/spec/std/isa/csr/I/pmpaddr52.yaml +6 -4
  90. data/.data/spec/std/isa/csr/I/pmpaddr53.yaml +6 -4
  91. data/.data/spec/std/isa/csr/I/pmpaddr54.yaml +6 -4
  92. data/.data/spec/std/isa/csr/I/pmpaddr55.yaml +6 -4
  93. data/.data/spec/std/isa/csr/I/pmpaddr56.yaml +6 -4
  94. data/.data/spec/std/isa/csr/I/pmpaddr57.yaml +6 -4
  95. data/.data/spec/std/isa/csr/I/pmpaddr58.yaml +6 -4
  96. data/.data/spec/std/isa/csr/I/pmpaddr59.yaml +6 -4
  97. data/.data/spec/std/isa/csr/I/pmpaddr6.yaml +6 -4
  98. data/.data/spec/std/isa/csr/I/pmpaddr60.yaml +6 -4
  99. data/.data/spec/std/isa/csr/I/pmpaddr61.yaml +6 -4
  100. data/.data/spec/std/isa/csr/I/pmpaddr62.yaml +6 -4
  101. data/.data/spec/std/isa/csr/I/pmpaddr63.yaml +6 -4
  102. data/.data/spec/std/isa/csr/I/pmpaddr7.yaml +6 -4
  103. data/.data/spec/std/isa/csr/I/pmpaddr8.yaml +6 -4
  104. data/.data/spec/std/isa/csr/I/pmpaddr9.yaml +6 -4
  105. data/.data/spec/std/isa/csr/I/pmpaddrN.layout +6 -4
  106. data/.data/spec/std/isa/csr/I/pmpcfg0.yaml +128 -152
  107. data/.data/spec/std/isa/csr/I/pmpcfg1.yaml +64 -76
  108. data/.data/spec/std/isa/csr/I/pmpcfg10.yaml +128 -152
  109. data/.data/spec/std/isa/csr/I/pmpcfg11.yaml +64 -76
  110. data/.data/spec/std/isa/csr/I/pmpcfg12.yaml +128 -152
  111. data/.data/spec/std/isa/csr/I/pmpcfg13.yaml +64 -76
  112. data/.data/spec/std/isa/csr/I/pmpcfg14.yaml +128 -152
  113. data/.data/spec/std/isa/csr/I/pmpcfg15.yaml +64 -76
  114. data/.data/spec/std/isa/csr/I/pmpcfg2.yaml +128 -152
  115. data/.data/spec/std/isa/csr/I/pmpcfg3.yaml +64 -76
  116. data/.data/spec/std/isa/csr/I/pmpcfg4.yaml +128 -152
  117. data/.data/spec/std/isa/csr/I/pmpcfg5.yaml +64 -76
  118. data/.data/spec/std/isa/csr/I/pmpcfg6.yaml +128 -152
  119. data/.data/spec/std/isa/csr/I/pmpcfg7.yaml +64 -76
  120. data/.data/spec/std/isa/csr/I/pmpcfg8.yaml +128 -152
  121. data/.data/spec/std/isa/csr/I/pmpcfg9.yaml +64 -76
  122. data/.data/spec/std/isa/csr/I/pmpcfgN.layout +16 -19
  123. data/.data/spec/std/isa/csr/Zicntr/mcountinhibit.layout +6 -2
  124. data/.data/spec/std/isa/csr/Zicntr/mcountinhibit.yaml +6 -2
  125. data/.data/spec/std/isa/csr/hstatus.yaml +16 -0
  126. data/.data/spec/std/isa/csr/jvt.yaml +1 -0
  127. data/.data/spec/std/isa/csr/mcycleh.yaml +1 -1
  128. data/.data/spec/std/isa/csr/menvcfg.yaml +20 -0
  129. data/.data/spec/std/isa/csr/misa.yaml +0 -12
  130. data/.data/spec/std/isa/csr/mstatus.yaml +46 -6
  131. data/.data/spec/std/isa/csr/mstatush.yaml +17 -15
  132. data/.data/spec/std/isa/csr/senvcfg.yaml +42 -0
  133. data/.data/spec/std/isa/csr/sstatus.yaml +12 -0
  134. data/.data/spec/std/isa/csr/vsstatus.yaml +24 -0
  135. data/.data/spec/std/isa/ext/A.yaml +5 -7
  136. data/.data/spec/std/isa/ext/S.yaml +12 -0
  137. data/.data/spec/std/isa/ext/Smpmpmt.yaml +52 -0
  138. data/.data/spec/std/isa/ext/Sv32.yaml +7 -19
  139. data/.data/spec/std/isa/ext/Sv39.yaml +7 -19
  140. data/.data/spec/std/isa/ext/Sv48.yaml +4 -20
  141. data/.data/spec/std/isa/ext/Sv57.yaml +4 -20
  142. data/.data/spec/std/isa/ext/Svukte.yaml +71 -0
  143. data/.data/spec/std/isa/ext/Zawrs.yaml +1 -1
  144. data/.data/spec/std/isa/ext/Zihpm.yaml +0 -12
  145. data/.data/spec/std/isa/inst/B/andn.yaml +10 -12
  146. data/.data/spec/std/isa/inst/B/clmul.yaml +9 -11
  147. data/.data/spec/std/isa/inst/B/clmulh.yaml +9 -11
  148. data/.data/spec/std/isa/inst/B/orn.yaml +9 -11
  149. data/.data/spec/std/isa/inst/B/rev8.yaml +1 -1
  150. data/.data/spec/std/isa/inst/B/rol.yaml +9 -11
  151. data/.data/spec/std/isa/inst/B/rolw.yaml +9 -11
  152. data/.data/spec/std/isa/inst/B/ror.yaml +9 -11
  153. data/.data/spec/std/isa/inst/B/rorw.yaml +9 -11
  154. data/.data/spec/std/isa/inst/B/xnor.yaml +9 -11
  155. data/.data/spec/std/isa/inst/C/c.addi.yaml +1 -0
  156. data/.data/spec/std/isa/inst/C/c.addi16sp.yaml +1 -0
  157. data/.data/spec/std/isa/inst/C/c.addiw.yaml +1 -0
  158. data/.data/spec/std/isa/inst/C/c.andi.yaml +1 -0
  159. data/.data/spec/std/isa/inst/C/c.ldsp.yaml +4 -4
  160. data/.data/spec/std/isa/inst/C/c.li.yaml +1 -0
  161. data/.data/spec/std/isa/inst/C/c.lui.yaml +1 -0
  162. data/.data/spec/std/isa/inst/C/c.mv.yaml +1 -1
  163. data/.data/spec/std/isa/inst/C/c.sdsp.yaml +1 -1
  164. data/.data/spec/std/isa/inst/D/fsgnj.d.yaml +3 -0
  165. data/.data/spec/std/isa/inst/D/fsgnjn.d.yaml +3 -0
  166. data/.data/spec/std/isa/inst/D/fsgnjx.d.yaml +3 -0
  167. data/.data/spec/std/isa/inst/F/fadd.s.yaml +5 -5
  168. data/.data/spec/std/isa/inst/F/fclass.s.yaml +2 -2
  169. data/.data/spec/std/isa/inst/F/fcvt.l.s.yaml +1 -1
  170. data/.data/spec/std/isa/inst/F/fcvt.lu.s.yaml +1 -1
  171. data/.data/spec/std/isa/inst/F/fcvt.s.l.yaml +1 -1
  172. data/.data/spec/std/isa/inst/F/fcvt.s.lu.yaml +1 -1
  173. data/.data/spec/std/isa/inst/F/fcvt.s.w.yaml +1 -1
  174. data/.data/spec/std/isa/inst/F/fcvt.s.wu.yaml +1 -1
  175. data/.data/spec/std/isa/inst/F/fcvt.w.s.yaml +1 -1
  176. data/.data/spec/std/isa/inst/F/fcvt.wu.s.yaml +1 -1
  177. data/.data/spec/std/isa/inst/F/fdiv.s.yaml +1 -1
  178. data/.data/spec/std/isa/inst/F/feq.s.yaml +2 -2
  179. data/.data/spec/std/isa/inst/F/fle.s.yaml +2 -2
  180. data/.data/spec/std/isa/inst/F/fleq.s.yaml +2 -2
  181. data/.data/spec/std/isa/inst/F/flt.s.yaml +2 -2
  182. data/.data/spec/std/isa/inst/F/fltq.s.yaml +2 -2
  183. data/.data/spec/std/isa/inst/F/flw.yaml +2 -2
  184. data/.data/spec/std/isa/inst/F/fmadd.s.yaml +1 -1
  185. data/.data/spec/std/isa/inst/F/fmax.s.yaml +6 -6
  186. data/.data/spec/std/isa/inst/F/fmin.s.yaml +6 -6
  187. data/.data/spec/std/isa/inst/F/fmsub.s.yaml +1 -1
  188. data/.data/spec/std/isa/inst/F/fmul.s.yaml +1 -1
  189. data/.data/spec/std/isa/inst/F/fmv.w.x.yaml +2 -2
  190. data/.data/spec/std/isa/inst/F/fmv.x.w.yaml +1 -1
  191. data/.data/spec/std/isa/inst/F/fnmadd.s.yaml +2 -2
  192. data/.data/spec/std/isa/inst/F/fnmsub.s.yaml +1 -1
  193. data/.data/spec/std/isa/inst/F/fsgnj.s.yaml +4 -4
  194. data/.data/spec/std/isa/inst/F/fsgnjn.s.yaml +3 -3
  195. data/.data/spec/std/isa/inst/F/fsgnjx.s.yaml +4 -4
  196. data/.data/spec/std/isa/inst/F/fsqrt.s.yaml +1 -1
  197. data/.data/spec/std/isa/inst/F/fsub.s.yaml +1 -1
  198. data/.data/spec/std/isa/inst/F/fsw.yaml +1 -1
  199. data/.data/spec/std/isa/inst/I/addi.yaml +2 -1
  200. data/.data/spec/std/isa/inst/I/addiw.yaml +2 -1
  201. data/.data/spec/std/isa/inst/I/andi.yaml +2 -1
  202. data/.data/spec/std/isa/inst/I/auipc.yaml +1 -0
  203. data/.data/spec/std/isa/inst/I/beq.yaml +1 -1
  204. data/.data/spec/std/isa/inst/I/bge.yaml +4 -2
  205. data/.data/spec/std/isa/inst/I/bgeu.yaml +3 -0
  206. data/.data/spec/std/isa/inst/I/blt.yaml +4 -2
  207. data/.data/spec/std/isa/inst/I/bltu.yaml +3 -0
  208. data/.data/spec/std/isa/inst/I/bne.yaml +1 -1
  209. data/.data/spec/std/isa/inst/I/lb.yaml +1 -0
  210. data/.data/spec/std/isa/inst/I/lbu.yaml +1 -0
  211. data/.data/spec/std/isa/inst/I/ld.yaml +2 -0
  212. data/.data/spec/std/isa/inst/I/lh.yaml +1 -0
  213. data/.data/spec/std/isa/inst/I/lhu.yaml +1 -0
  214. data/.data/spec/std/isa/inst/I/lui.yaml +1 -0
  215. data/.data/spec/std/isa/inst/I/lw.yaml +1 -0
  216. data/.data/spec/std/isa/inst/I/lwu.yaml +1 -0
  217. data/.data/spec/std/isa/inst/I/ori.yaml +1 -0
  218. data/.data/spec/std/isa/inst/I/sb.yaml +1 -0
  219. data/.data/spec/std/isa/inst/I/sd.yaml +1 -0
  220. data/.data/spec/std/isa/inst/I/sh.yaml +1 -0
  221. data/.data/spec/std/isa/inst/I/slt.yaml +2 -2
  222. data/.data/spec/std/isa/inst/I/slti.yaml +1 -0
  223. data/.data/spec/std/isa/inst/I/sltiu.yaml +2 -1
  224. data/.data/spec/std/isa/inst/I/sltu.yaml +1 -1
  225. data/.data/spec/std/isa/inst/I/sub.yaml +1 -1
  226. data/.data/spec/std/isa/inst/I/subw.yaml +1 -1
  227. data/.data/spec/std/isa/inst/I/sw.yaml +1 -0
  228. data/.data/spec/std/isa/inst/I/xori.yaml +2 -1
  229. data/.data/spec/std/isa/inst/M/mul.yaml +0 -19
  230. data/.data/spec/std/isa/inst/Q/fsgnj.q.yaml +1 -1
  231. data/.data/spec/std/isa/inst/S/sret.yaml +3 -1
  232. data/.data/spec/std/isa/inst/V/vadc.vim.yaml +1 -0
  233. data/.data/spec/std/isa/inst/V/vadd.vi.yaml +1 -0
  234. data/.data/spec/std/isa/inst/V/vadd.vv.yaml +1 -5
  235. data/.data/spec/std/isa/inst/V/vand.vi.yaml +1 -0
  236. data/.data/spec/std/isa/inst/V/vfsgnjn.vv.yaml +3 -0
  237. data/.data/spec/std/isa/inst/V/vfsgnjx.vv.yaml +3 -0
  238. data/.data/spec/std/isa/inst/V/vl1re8.v.yaml +3 -0
  239. data/.data/spec/std/isa/inst/V/vl2re8.v.yaml +3 -0
  240. data/.data/spec/std/isa/inst/V/vl4re8.v.yaml +3 -0
  241. data/.data/spec/std/isa/inst/V/vl8re8.v.yaml +3 -0
  242. data/.data/spec/std/isa/inst/V/vle8.v.yaml +4 -8
  243. data/.data/spec/std/isa/inst/V/vmadc.vi.yaml +1 -0
  244. data/.data/spec/std/isa/inst/V/vmadc.vim.yaml +1 -0
  245. data/.data/spec/std/isa/inst/V/vmand.mm.yaml +3 -0
  246. data/.data/spec/std/isa/inst/V/vmerge.vim.yaml +1 -0
  247. data/.data/spec/std/isa/inst/V/vmfle.vv.yaml +3 -0
  248. data/.data/spec/std/isa/inst/V/vmflt.vv.yaml +3 -0
  249. data/.data/spec/std/isa/inst/V/vmnand.mm.yaml +3 -0
  250. data/.data/spec/std/isa/inst/V/vmseq.vi.yaml +1 -0
  251. data/.data/spec/std/isa/inst/V/vmsgt.vi.yaml +4 -0
  252. data/.data/spec/std/isa/inst/V/vmsgtu.vi.yaml +4 -0
  253. data/.data/spec/std/isa/inst/V/vmsle.vi.yaml +4 -0
  254. data/.data/spec/std/isa/inst/V/vmsle.vv.yaml +3 -0
  255. data/.data/spec/std/isa/inst/V/vmsleu.vi.yaml +4 -0
  256. data/.data/spec/std/isa/inst/V/vmsleu.vv.yaml +3 -0
  257. data/.data/spec/std/isa/inst/V/vmslt.vv.yaml +3 -0
  258. data/.data/spec/std/isa/inst/V/vmsltu.vv.yaml +3 -0
  259. data/.data/spec/std/isa/inst/V/vmsne.vi.yaml +1 -0
  260. data/.data/spec/std/isa/inst/V/vmv.v.i.yaml +2 -13
  261. data/.data/spec/std/isa/inst/V/vmv.x.s.yaml +1 -1
  262. data/.data/spec/std/isa/inst/V/vmxnor.mm.yaml +3 -0
  263. data/.data/spec/std/isa/inst/V/vmxor.mm.yaml +3 -0
  264. data/.data/spec/std/isa/inst/V/vnsrl.wx.yaml +3 -0
  265. data/.data/spec/std/isa/inst/V/vor.vi.yaml +1 -0
  266. data/.data/spec/std/isa/inst/V/vrsub.vi.yaml +1 -0
  267. data/.data/spec/std/isa/inst/V/vrsub.vx.yaml +3 -0
  268. data/.data/spec/std/isa/inst/V/vsadd.vi.yaml +1 -0
  269. data/.data/spec/std/isa/inst/V/vsaddu.vi.yaml +1 -0
  270. data/.data/spec/std/isa/inst/V/vse8.v.yaml +4 -4
  271. data/.data/spec/std/isa/inst/V/vwadd.vx.yaml +3 -0
  272. data/.data/spec/std/isa/inst/V/vwaddu.vx.yaml +3 -0
  273. data/.data/spec/std/isa/inst/V/vxor.vi.yaml +4 -0
  274. data/.data/spec/std/isa/inst/Zalasr/lSIZE.AQRL.layout +40 -5
  275. data/.data/spec/std/isa/inst/Zalasr/lb.aq.yaml +17 -1
  276. data/.data/spec/std/isa/inst/Zalasr/lb.aqrl.yaml +17 -1
  277. data/.data/spec/std/isa/inst/Zalasr/ld.aq.yaml +17 -1
  278. data/.data/spec/std/isa/inst/Zalasr/ld.aqrl.yaml +17 -1
  279. data/.data/spec/std/isa/inst/Zalasr/lh.aq.yaml +17 -1
  280. data/.data/spec/std/isa/inst/Zalasr/lh.aqrl.yaml +17 -1
  281. data/.data/spec/std/isa/inst/Zalasr/lw.aq.yaml +17 -1
  282. data/.data/spec/std/isa/inst/Zalasr/lw.aqrl.yaml +17 -1
  283. data/.data/spec/std/isa/inst/Zalasr/sSIZE.AQRL.layout +46 -5
  284. data/.data/spec/std/isa/inst/Zalasr/sb.aqrl.yaml +16 -1
  285. data/.data/spec/std/isa/inst/Zalasr/sb.rl.yaml +16 -1
  286. data/.data/spec/std/isa/inst/Zalasr/sd.aqrl.yaml +16 -1
  287. data/.data/spec/std/isa/inst/Zalasr/sd.rl.yaml +16 -1
  288. data/.data/spec/std/isa/inst/Zalasr/sh.aqrl.yaml +16 -1
  289. data/.data/spec/std/isa/inst/Zalasr/sh.rl.yaml +16 -1
  290. data/.data/spec/std/isa/inst/Zalasr/sw.aqrl.yaml +16 -1
  291. data/.data/spec/std/isa/inst/Zalasr/sw.rl.yaml +16 -1
  292. data/.data/spec/std/isa/inst/Zawrs/wrs.nto.yaml +4 -2
  293. data/.data/spec/std/isa/inst/Zba/add.uw.yaml +9 -11
  294. data/.data/spec/std/isa/inst/Zbb/orc.b.yaml +1 -1
  295. data/.data/spec/std/isa/inst/Zbkb/brev8.yaml +3 -3
  296. data/.data/spec/std/isa/inst/Zbkb/packw.yaml +1 -1
  297. data/.data/spec/std/isa/inst/Zbkb/unzip.yaml +2 -2
  298. data/.data/spec/std/isa/inst/Zbkb/zip.yaml +2 -2
  299. data/.data/spec/std/isa/inst/Zbkx/xperm4.yaml +2 -2
  300. data/.data/spec/std/isa/inst/Zbkx/xperm8.yaml +2 -2
  301. data/.data/spec/std/isa/inst/Zcd/c.fld.yaml +1 -1
  302. data/.data/spec/std/isa/inst/Zcd/c.fldsp.yaml +1 -1
  303. data/.data/spec/std/isa/inst/Zcd/c.fsdsp.yaml +1 -1
  304. data/.data/spec/std/isa/inst/Zcf/c.flwsp.yaml +1 -1
  305. data/.data/spec/std/isa/inst/Zcf/c.fswsp.yaml +1 -1
  306. data/.data/spec/std/isa/inst/Zcmp/cm.pop.yaml +1 -1
  307. data/.data/spec/std/isa/inst/Zcmp/cm.popret.yaml +1 -1
  308. data/.data/spec/std/isa/inst/Zcmp/cm.popretz.yaml +1 -1
  309. data/.data/spec/std/isa/inst/Zcmp/cm.push.yaml +2 -3
  310. data/.data/spec/std/isa/inst/Zfa/fround.s.yaml +1 -1
  311. data/.data/spec/std/isa/inst/Zfh/fcvt.h.s.yaml +6 -6
  312. data/.data/spec/std/isa/inst/Zfh/fcvt.s.h.yaml +5 -5
  313. data/.data/spec/std/isa/inst/Zfh/flh.yaml +1 -1
  314. data/.data/spec/std/isa/inst/Zfh/fmv.h.x.yaml +1 -1
  315. data/.data/spec/std/isa/inst/Zfh/fmv.x.h.yaml +1 -1
  316. data/.data/spec/std/isa/inst/Zfh/fsh.yaml +1 -1
  317. data/.data/spec/std/isa/inst/Zicbop/prefetch.i.yaml +2 -0
  318. data/.data/spec/std/isa/inst/Zicbop/prefetch.r.yaml +2 -0
  319. data/.data/spec/std/isa/inst/Zicbop/prefetch.w.yaml +2 -0
  320. data/.data/spec/std/isa/inst/Zicsr/csrrc.yaml +1 -1
  321. data/.data/spec/std/isa/inst/Zicsr/csrrci.yaml +1 -1
  322. data/.data/spec/std/isa/inst/Zicsr/csrrs.yaml +2 -2
  323. data/.data/spec/std/isa/inst/Zicsr/csrrsi.yaml +1 -1
  324. data/.data/spec/std/isa/inst/Zicsr/csrrw.yaml +1 -1
  325. data/.data/spec/std/isa/inst/Zicsr/csrrwi.yaml +1 -1
  326. data/.data/spec/std/isa/inst/Zks/sm3p0.yaml +1 -1
  327. data/.data/spec/std/isa/inst/Zks/sm3p1.yaml +1 -1
  328. data/.data/spec/std/isa/inst/Zks/sm4ed.yaml +1 -1
  329. data/.data/spec/std/isa/inst/Zks/sm4ks.yaml +1 -1
  330. data/.data/spec/std/isa/isa/builtin_functions.idl +18 -0
  331. data/.data/spec/std/isa/isa/fp.idl +1 -5
  332. data/.data/spec/std/isa/isa/globals.isa +72 -21
  333. data/.data/spec/std/isa/isa/interrupts.idl +1 -0
  334. data/.data/spec/std/isa/isa/vec.idl +1 -2
  335. data/.data/spec/std/isa/manual_version/isa/20240411/isa_20240411.yaml +5 -5
  336. data/.data/spec/std/isa/param/COUNTINHIBIT_EN.yaml +8 -2
  337. data/.data/spec/std/isa/param/HSTATEEN_CONTEXT_TYPE.yaml +1 -0
  338. data/.data/spec/std/isa/param/JVT_BASE_MASK.yaml +1 -1
  339. data/.data/spec/std/isa/param/MCOUNTINHIBIT_IMPLEMENTED.yaml +25 -0
  340. data/.data/spec/std/isa/param/MSTATEEN_CONTEXT_TYPE.yaml +1 -0
  341. data/.data/spec/std/isa/param/MTVEC_BASE_ALIGNMENT_DIRECT.yaml +1 -0
  342. data/.data/spec/std/isa/param/MTVEC_BASE_ALIGNMENT_VECTORED.yaml +1 -0
  343. data/.data/spec/std/isa/param/MTVEC_MODES.yaml +10 -3
  344. data/.data/spec/std/isa/param/NUM_PMP_ENTRIES.yaml +11 -22
  345. data/.data/spec/std/isa/param/NUM_USABLE_PMP_ENTRIES.yaml +35 -0
  346. data/.data/spec/std/isa/param/PMP_NA4_SUPPORTED.yaml +23 -0
  347. data/.data/spec/std/isa/param/PMP_NAPOT_SUPPORTED.yaml +19 -0
  348. data/.data/spec/std/isa/param/{MSTATUS_TVM_IMPLEMENTED.yaml → PMP_TOR_SUPPORTED.yaml} +6 -6
  349. data/.data/spec/std/isa/param/PRECISE_SYNCHRONOUS_EXCEPTIONS.yaml +1 -0
  350. data/.data/spec/std/isa/param/TRAP_ON_EBREAK.yaml +1 -0
  351. data/.data/spec/std/isa/param/TRAP_ON_ECALL_FROM_M.yaml +1 -0
  352. data/.data/spec/std/isa/param/TRAP_ON_SFENCE_VMA_WHEN_SATP_MODE_IS_READ_ONLY.yaml +1 -0
  353. data/.data/spec/std/isa/param/VLEN.yaml +2 -0
  354. data/.data/spec/std/isa/param/ZAWRS_NTO_IS_NOP.yaml +19 -0
  355. data/.data/spec/std/isa/profile/RVA20S64.yaml +11 -4
  356. data/.data/spec/std/isa/profile/RVA20U64.yaml +14 -5
  357. data/.data/spec/std/isa/profile/RVA22S64.yaml +14 -3
  358. data/.data/spec/std/isa/profile/RVA22U64.yaml +8 -1
  359. data/.data/spec/std/isa/profile/RVA23S64.yaml +13 -0
  360. data/.data/spec/std/isa/profile/RVA23U64.yaml +15 -1
  361. data/.data/spec/std/isa/profile/RVB23S64.yaml +15 -3
  362. data/.data/spec/std/isa/profile/RVB23U64.yaml +8 -1
  363. data/.data/spec/std/isa/profile/RVI20U32.yaml +8 -1
  364. data/.data/spec/std/isa/profile/RVI20U64.yaml +7 -0
  365. data/.data/spec/std/isa/register_file/F.yaml +3 -2
  366. data/.data/spec/std/isa/register_file/V.yaml +2 -2
  367. data/.data/spec/std/isa/register_file/X.yaml +2 -1
  368. data/lib/udb/ESPRESSO_VERSION +1 -1
  369. data/lib/udb/architecture.rb +4 -25
  370. data/lib/udb/cfg_arch.rb +171 -59
  371. data/lib/udb/cli.rb +10 -1
  372. data/lib/udb/condition.rb +38 -37
  373. data/lib/udb/config.rb +86 -8
  374. data/lib/udb/doc_link.rb +3 -4
  375. data/lib/udb/logic.rb +29 -56
  376. data/lib/udb/obj/csr.rb +23 -5
  377. data/lib/udb/obj/csr_field.rb +36 -21
  378. data/lib/udb/obj/database_obj.rb +2 -5
  379. data/lib/udb/obj/extension.rb +0 -3
  380. data/lib/udb/obj/instruction.rb +2 -5
  381. data/lib/udb/obj/non_isa_specification.rb +22 -100
  382. data/lib/udb/obj/portfolio.rb +75 -20
  383. data/lib/udb/obj/profile.rb +0 -4
  384. data/lib/udb/obj/register_file.rb +63 -2
  385. data/lib/udb/portfolio_design.rb +3 -6
  386. data/lib/udb/resolver.rb +84 -23
  387. data/lib/udb/version.rb +1 -1
  388. data/lib/udb/version_spec.rb +8 -0
  389. data/lib/udb/z3.rb +25 -2
  390. data/lib/udb.rb +0 -3
  391. metadata +30 -38
  392. data/.data/cfgs/profile/RVA23M64.yaml +0 -159
  393. data/.data/cfgs/profile/RVB23M64.yaml +0 -149
  394. data/.data/spec/schemas/proc_cert_class_schema.json +0 -35
  395. data/.data/spec/schemas/proc_cert_model_schema.json +0 -336
  396. data/.data/spec/std/isa/proc_cert_class/AC.yaml +0 -13
  397. data/.data/spec/std/isa/proc_cert_class/MC.yaml +0 -13
  398. data/.data/spec/std/isa/proc_cert_class/RVI.yaml +0 -16
  399. data/.data/spec/std/isa/proc_cert_model/AC100.yaml +0 -72
  400. data/.data/spec/std/isa/proc_cert_model/AC200.yaml +0 -58
  401. data/.data/spec/std/isa/proc_cert_model/MC100-32.yaml +0 -155
  402. data/.data/spec/std/isa/proc_cert_model/MC100-64.yaml +0 -21
  403. data/.data/spec/std/isa/proc_cert_model/MC200-32.yaml +0 -60
  404. data/.data/spec/std/isa/proc_cert_model/MC200-64.yaml +0 -21
  405. data/.data/spec/std/isa/proc_cert_model/MC300-32.yaml +0 -40
  406. data/.data/spec/std/isa/proc_cert_model/MC300-64.yaml +0 -21
  407. data/.data/spec/std/isa/proc_cert_model/RVI20-32.yaml +0 -39
  408. data/.data/spec/std/isa/proc_cert_model/RVI20-64.yaml +0 -19
  409. data/.data/spec/std/isa/profile/RVA23M64.yaml +0 -24
  410. data/.data/spec/std/isa/profile/RVB23M64.yaml +0 -86
  411. data/lib/udb/cert_normative_rule.rb +0 -41
  412. data/lib/udb/obj/certifiable_obj.rb +0 -21
  413. data/lib/udb/obj/certificate.rb +0 -230
  414. data/lib/udb/proc_cert_design.rb +0 -77
@@ -143,72 +143,19 @@ class NonIsaSpecification
143
143
  )
144
144
  end
145
145
 
146
- # Validation methods
147
- sig { returns(T::Array[String]) }
148
- # Validate all prose statement IDs and conventions for this spec.
149
- def validate_prose_ids
150
- return [] unless valid?
151
-
152
- issues = []
153
- statements = extract_prose_statements
154
- statements.each do |stmt|
155
- next unless stmt['id']
156
- id = stmt['id']
157
- source = stmt[:source] || 'unknown'
158
-
159
- # Check ID format according to prose-schema conventions
160
- unless valid_id_format?(id)
161
- issues << "Invalid ID format '#{id}' in #{source}: must be lowercase with underscores/hyphens only"
162
- end
163
-
164
- # Check for non-ISA specification naming convention
165
- unless valid_id_naming?(id)
166
- issues << "ID '#{id}' in #{source} should start with '#{name.downcase}-' for non-ISA specifications"
167
- end
168
- end
169
-
170
- # Check for duplicate IDs
171
- issues.concat(find_duplicate_ids(statements))
172
- issues
173
- end
174
-
175
- sig { params(include_sections: T::Boolean).returns(T::Array[T::Hash[T.any(String, Symbol), T.untyped]]) }
176
- # Extract all prose statements from description and sections, tagging their source.
177
- def extract_prose_statements(include_sections: true)
178
- statements = []
179
- # Extract from description
180
- if spec_description.is_a?(Array)
181
- spec_description.each_with_index { |stmt, i| statements << stmt.merge(source: "description[#{i}]") if stmt.is_a?(Hash) }
182
- end
183
- # Extract from sections
184
- if include_sections
185
- sections.each_with_index do |section, section_idx|
186
- next unless section['content'].is_a?(Array)
187
- section['content'].each_with_index do |stmt, stmt_idx|
188
- statements << stmt.merge(source: "sections[#{section_idx}].content[#{stmt_idx}]") if stmt.is_a?(Hash)
189
- end
190
- end
191
- end
192
- statements
193
- end
194
-
195
146
  # Rendering methods
196
147
  sig do
197
148
  params(
198
149
  cfg_arch: T.untyped,
199
150
  base_level: Integer,
200
- normative: T::Boolean,
201
- non_normative: T::Boolean
202
151
  ).returns(String)
203
152
  end
204
153
  # Configuration-aware rendering
205
- def render_for_cfg(cfg_arch, base_level: 3, normative: true, non_normative: true)
154
+ def render_for_cfg(cfg_arch, base_level: 3)
206
155
  return "" unless exists_in_cfg?(cfg_arch)
207
156
 
208
157
  to_asciidoc(
209
158
  base_level: base_level,
210
- normative: normative,
211
- non_normative: non_normative,
212
159
  when_callback: create_when_callback(cfg_arch)
213
160
  )
214
161
  end
@@ -216,24 +163,22 @@ class NonIsaSpecification
216
163
  sig do
217
164
  params(
218
165
  base_level: Integer,
219
- normative: T::Boolean,
220
- non_normative: T::Boolean,
221
166
  when_callback: T.nilable(T.proc.params(arg0: T.untyped, arg1: T.untyped).returns(T::Boolean))
222
167
  ).returns(String)
223
168
  end
224
169
  # Render the full specification as AsciiDoc, including description, sections, and references.
225
- def to_asciidoc(base_level: 3, normative: true, non_normative: true, when_callback: nil)
170
+ def to_asciidoc(base_level: 3, when_callback: nil)
226
171
  return create_fallback_content(base_level) unless valid?
227
172
 
228
173
  content = []
229
174
 
230
175
  # Add main description prose
231
- desc_content = render_structured_prose(spec_description, normative: normative, non_normative: non_normative, when_callback: when_callback)
176
+ desc_content = render_structured_prose(spec_description, when_callback: when_callback)
232
177
  content << desc_content if desc_content && !desc_content.empty?
233
178
  content << ""
234
179
 
235
180
  # Process all sections
236
- content.concat(render_sections(base_level, normative, non_normative, when_callback))
181
+ content.concat(render_sections(base_level, when_callback))
237
182
 
238
183
  # Add references section if present
239
184
  content.concat(render_references(base_level)) unless references.empty?
@@ -243,50 +188,22 @@ class NonIsaSpecification
243
188
 
244
189
  private
245
190
 
246
- # Validation helper methods
247
- sig { params(id: String).returns(T::Boolean) }
248
- # IDs must be lowercase, start with a letter, and use only underscores/hyphens.
249
- def valid_id_format?(id)
250
- id.match?(/^[a-z][a-z0-9_-]*$/)
251
- end
252
-
253
- sig { params(id: String).returns(T::Boolean) }
254
- # IDs should start with spec name or allowed prefixes for non-ISA specs.
255
- def valid_id_naming?(id)
256
- id.start_with?(name.downcase) || id.match?(/^(ext|inst|csr)-/)
257
- end
258
-
259
- sig { params(statements: T::Array[T::Hash[T.any(String, Symbol), T.untyped]]).returns(T::Array[String]) }
260
- # Find duplicate IDs in the statements array.
261
- def find_duplicate_ids(statements)
262
- issues = []
263
- id_counts = Hash.new(0)
264
- statements.each { |stmt| id_counts[stmt['id']] += 1 if stmt['id'] }
265
- id_counts.each do |id, count|
266
- next if count == 1
267
- issues << "Duplicate ID '#{id}' appears #{count} times"
268
- end
269
- issues
270
- end
271
-
272
191
  # Rendering helper methods
273
192
  sig do
274
193
  params(
275
194
  base_level: Integer,
276
- normative: T::Boolean,
277
- non_normative: T::Boolean,
278
195
  when_callback: T.nilable(T.proc.params(arg0: T.untyped, arg1: T.untyped).returns(T::Boolean))
279
196
  ).returns(T::Array[String])
280
197
  end
281
198
  # Render all sections, adjusting heading levels and filtering by callback.
282
- def render_sections(base_level, normative, non_normative, when_callback)
199
+ def render_sections(base_level, when_callback)
283
200
  content = []
284
201
  sections.each do |section|
285
202
  next unless should_include_section?(section, when_callback)
286
203
  level = section['level'] || (base_level + 1)
287
204
  content << "#{'=' * level} #{section['title']}"
288
205
  content << ""
289
- section_content = render_structured_prose(section['content'], normative: normative, non_normative: non_normative, when_callback: when_callback)
206
+ section_content = render_structured_prose(section['content'], when_callback: when_callback)
290
207
  content << section_content if section_content && !section_content.empty?
291
208
  content << ""
292
209
  end
@@ -311,29 +228,34 @@ class NonIsaSpecification
311
228
  sig do
312
229
  params(
313
230
  prose_content: T.untyped,
314
- normative: T::Boolean,
315
- non_normative: T::Boolean,
316
231
  when_callback: T.nilable(T.proc.params(arg0: T.untyped, arg1: T.untyped).returns(T::Boolean))
317
232
  ).returns(T.nilable(String))
318
233
  end
319
- # Render an array of prose statements as AsciiDoc, filtering by normative and conditional status.
320
- def render_structured_prose(prose_content, normative: true, non_normative: true, when_callback: nil)
234
+ # Render an array of prose statements as AsciiDoc.
235
+ def render_structured_prose(prose_content, when_callback: nil)
321
236
  return nil if prose_content.nil?
237
+
238
+ # Handle simple string (Asciidoc source)
239
+ return prose_content if prose_content.is_a?(String)
240
+
322
241
  return "" unless prose_content.is_a?(Array)
323
242
 
324
243
  rendered_statements = []
325
244
  prose_content.each do |statement|
326
- next unless statement.is_a?(Hash) && statement['id'] && statement['text']
245
+ text = nil
246
+ condition = nil
247
+
248
+ next unless statement.is_a?(Hash)
249
+
250
+ text = statement['text']
251
+ condition = statement['when()']
327
252
 
328
- # Filter by normative status
329
- stmt_normative = statement['normative']
330
- next if stmt_normative == true && !normative
331
- next if stmt_normative == false && !non_normative
253
+ next unless text
332
254
 
333
255
  # Filter by when condition
334
- next if when_callback && !when_callback.call(statement['when()'], statement)
256
+ next if when_callback && !when_callback.call(condition, statement)
335
257
 
336
- rendered_statements << statement['text']
258
+ rendered_statements << text
337
259
  end
338
260
  rendered_statements.join("\n\n")
339
261
  end
@@ -23,6 +23,7 @@ module Udb
23
23
  class PortfolioExtensionRequirement
24
24
  extend T::Sig
25
25
  extend Forwardable
26
+ include Comparable
26
27
 
27
28
  def_delegators :@ext_req,
28
29
  :name,
@@ -41,12 +42,22 @@ module Udb
41
42
  presence: T.nilable(Presence)
42
43
  ).void
43
44
  }
44
- def initialize(name, requirements, arch:, note:, req_id:, presence:)
45
+ def initialize(name, requirements, arch:, note: nil, req_id: nil, presence: nil)
45
46
  @ext_req = arch.extension_requirement(name, requirements)
46
47
  @note = note
47
48
  @req_id = req_id
48
49
  @presence = presence
49
50
  end
51
+
52
+ sig { params(other: T.any(PortfolioExtensionRequirement, ExtensionRequirement)).returns(T.nilable(Integer)) }
53
+ def <=>(other)
54
+ case other
55
+ when PortfolioExtensionRequirement
56
+ @ext_req <=> other.ext_req
57
+ when ExtensionRequirement
58
+ @ext_req <=> other
59
+ end
60
+ end
50
61
  end
51
62
 
52
63
  ##################
@@ -440,22 +451,22 @@ module Udb
440
451
  end
441
452
  end
442
453
 
443
- sig { returns(T::Hash[String, T.untyped]) }
444
- def to_config
445
- {
454
+ sig { params(mandatory: T::Array[PortfolioExtensionRequirement]).returns(T::Hash[String, T.untyped]) }
455
+ def to_config(mandatory: mandatory_ext_reqs)
456
+ c = {
446
457
  "$schema" => "config_schema.json#",
447
458
  "kind" => "architecture configuration",
448
459
  "type" => "partially configured",
449
460
  "name" => name,
450
461
  "description" => description,
451
- "params" => all_in_scope_params.map do |p|
462
+ "params" => all_in_scope_params.sort.map do |p|
452
463
  if p.single_value?
453
464
  [p.name, p.value]
454
465
  else
455
466
  nil
456
467
  end
457
468
  end.compact.to_h,
458
- "mandatory_extensions" => mandatory_ext_reqs.map do |ext_req|
469
+ "mandatory_extensions" => mandatory.sort.map do |ext_req|
459
470
  {
460
471
  "name" => ext_req.name,
461
472
  "version" => \
@@ -466,7 +477,7 @@ module Udb
466
477
  end
467
478
  }
468
479
  end,
469
- "non_mandatory_extensions" => optional_ext_reqs.map do |ext_req|
480
+ "non_mandatory_extensions" => optional_ext_reqs.sort.map do |ext_req|
470
481
  {
471
482
  "name" => ext_req.name,
472
483
  "version" => \
@@ -479,19 +490,41 @@ module Udb
479
490
  end,
480
491
  "additional_extensions" => true
481
492
  }
493
+ c["requirements"] = requirements_condition.to_h unless requirements_condition.empty?
494
+ c
482
495
  end
483
496
 
484
- # returns a config arch that treats the Portfolio like a partial config
485
- sig { returns(ConfiguredArchitecture) }
486
- def to_cfg_arch
487
- @cfg_arch_for_mandatory ||= begin
488
- Tempfile.create do |f|
489
- f.write YAML.dump(to_config)
490
- f.fsync
497
+ # @return portfolio in config form, with requirements of mandatory extensions expanded
498
+ sig { returns(T::Hash[String, T.untyped]) }
499
+ def to_strict_config
500
+ strict_mandatory_ext_reqs = mandatory_ext_reqs
501
+ mandatory_ext_req_names = strict_mandatory_ext_reqs.map(&:name).to_set
502
+ cfg_arch_obj = to_cfg_arch
503
+
504
+ cfg_arch_obj.extensions.each do |ext|
505
+ next if mandatory_ext_req_names.include?(ext.name)
506
+
507
+ if (-ext.to_ext_req.to_condition & cfg_arch_obj.to_condition).unsatisfiable_by_cfg_arch?(cfg_arch_obj)
508
+ # what's the minimum?
509
+ min_ext_ver = ext.versions.find do |ext_ver|
510
+ compat_with_ext_ver = Condition.new({ "extension" => { "name" => ext.name, "version" => "= #{ext_ver.version_str}" } }, cfg_arch_obj)
511
+ c = (compat_with_ext_ver & cfg_arch_obj.to_condition)
512
+ c.satisfiable_by_cfg_arch?(cfg_arch_obj)
513
+ end
514
+ raise "condition problem: ext is required but none of the versions are" if min_ext_ver.nil?
491
515
 
492
- @cfg_arch.config.info.resolver.cfg_arch_for(Pathname.new f.path)
516
+ strict_mandatory_ext_reqs << PortfolioExtensionRequirement.new(ext.name, "~> #{min_ext_ver.version_str}", arch: cfg_arch_obj)
517
+ mandatory_ext_req_names.add(ext.name)
493
518
  end
494
519
  end
520
+
521
+ to_config(mandatory: strict_mandatory_ext_reqs)
522
+ end
523
+
524
+ # returns a config arch that treats the Portfolio like a partial config
525
+ sig { returns(ConfiguredArchitecture) }
526
+ def to_cfg_arch
527
+ @cfg_arch_for_mandatory ||= cfg_arch_for_config_data(to_config)
495
528
  end
496
529
 
497
530
  # returns a config arch that treats the *optional* extensions in Portfolio like a partial config
@@ -525,15 +558,38 @@ module Udb
525
558
  end,
526
559
  "additional_extensions" => true
527
560
  }
561
+ contents["requirements"] = requirements_condition.to_h unless requirements_condition.empty?
562
+ cfg_arch_for_config_data(contents)
563
+ end
564
+ end
565
+
566
+ # Build a ConfiguredArchitecture from an in-memory config data hash.
567
+ # Uses the fast path (no disk round-trip) when the parent has no overlay;
568
+ # falls back to the full pipeline when the parent's resolved spec differs.
569
+ sig { params(config_data: T::Hash[String, T.untyped]).returns(ConfiguredArchitecture) }
570
+ def cfg_arch_for_config_data(config_data)
571
+ resolver = @cfg_arch.config.info.resolver
572
+ if @cfg_arch.config.info.overlay_path.nil?
573
+ resolver.cfg_arch_for_data(config_data)
574
+ else
528
575
  Tempfile.create do |f|
529
- f.write YAML.dump(contents)
576
+ f.write YAML.dump(config_data)
530
577
  f.fsync
531
-
532
- @cfg_arch.config.info.resolver.cfg_arch_for(Pathname.new f.path)
578
+ resolver.cfg_arch_for(Pathname.new f.path)
533
579
  end
534
580
  end
535
581
  end
536
582
 
583
+ sig { returns(AbstractCondition) }
584
+ def requirements_condition
585
+ @requirements_condition ||=
586
+ if @data.key?("requirements")
587
+ Condition.new(@data.fetch("requirements"), cfg_arch)
588
+ else
589
+ AlwaysTrueCondition.new(cfg_arch)
590
+ end
591
+ end
592
+
537
593
  # @return [String] Given an instruction +inst_name+, return the presence as a string.
538
594
  # If the instruction name isn't found in the portfolio, return "-".
539
595
  sig { params(inst_name: String).returns(T.nilable(Presence)) }
@@ -739,8 +795,7 @@ module Udb
739
795
 
740
796
  return @in_scope_csrs unless @in_scope_csrs.nil?
741
797
 
742
- @in_scope_csrs =
743
- in_scope_min_satisfying_extension_versions.map { |ext_ver| ext_ver.in_scope_csrs(design.possible_xlens) }.flatten.uniq
798
+ @in_scope_csrs = to_cfg_arch.in_scope_csrs()
744
799
  end
745
800
 
746
801
  # @param design [Design] The design
@@ -196,10 +196,6 @@ module Udb
196
196
  @data["base"]
197
197
  end
198
198
 
199
- def all_in_scope_params
200
- [Portfolio::InScopeParameter.new(@cfg_arch.param("MXLEN"), { "const" => @data["base"] }, "")]
201
- end
202
-
203
199
  # Too complicated to put in profile ERB template.
204
200
  # @param presence_type [String]
205
201
  # @param heading_level [Integer]
@@ -49,6 +49,12 @@ class RegisterFile < TopLevelDatabaseObject
49
49
  sig { returns(T::Array[String]) }
50
50
  def abi_mnemonics = @data.fetch("abi_mnemonics", [])
51
51
 
52
+ sig { returns(T.nilable(String)) }
53
+ def reset_value = @data["reset_value"]
54
+
55
+ sig { returns(RegisterFile) }
56
+ def register_file = @file
57
+
52
58
  sig { returns(T.any(Integer, String)) }
53
59
  def index = @index
54
60
 
@@ -97,8 +103,63 @@ class RegisterFile < TopLevelDatabaseObject
97
103
  end
98
104
  end
99
105
 
100
- sig { returns(T.any(Integer, String)) }
101
- def register_length = @data.fetch("register_length")
106
+ # Returns the IDL function body string for the register_length() field.
107
+ # e.g. "return MXLEN;" or "return implemented?(ExtensionName::D) ? 64 : 32;"
108
+ sig { returns(String) }
109
+ def register_length = @data.fetch("register_length()")
110
+
111
+ # Returns the stripped IDL expression (no 'return' keyword or trailing semicolon).
112
+ sig { returns(String) }
113
+ def register_length_expr
114
+ register_length.strip.sub(/\Areturn\s+/, "").sub(/;\z/, "").strip
115
+ end
116
+
117
+ # Evaluate the register_length() IDL body against the given cfg_arch parameter context.
118
+ # Returns an Integer if the width is statically determined, or a String param name
119
+ # if the width depends on a runtime parameter (e.g. "VLEN").
120
+ sig { params(cfg_arch: ConfiguredArchitecture).returns(T.any(Integer, String)) }
121
+ def eval_register_length(cfg_arch)
122
+ expr = register_length_expr
123
+
124
+ # Literal integer
125
+ return Integer(expr) if expr =~ /\A\d+\z/
126
+
127
+ # Simple MXLEN reference
128
+ if expr == "MXLEN"
129
+ mxlen = cfg_arch.mxlen
130
+ return mxlen || "MXLEN" # Return String "MXLEN" for dynamic-XLEN configs
131
+ end
132
+
133
+ # Check for a fixed parameter
134
+ fixed = cfg_arch.params_with_value.find { |p| p.name == expr }
135
+ return T.cast(fixed.value, Integer).to_i if fixed
136
+
137
+ # Check if it's a free parameter name
138
+ free = cfg_arch.params_without_value.find { |p| p.name == expr }
139
+ return expr if free
140
+
141
+ # Complex expression — fall back to the architectural maximum.
142
+ max_register_length
143
+ end
144
+
145
+ # Maximum value register_length() can return across all valid configurations.
146
+ # Derived by compiling the register_length() expression against the full symtab
147
+ # and calling max_value — unknown conditions (e.g. implemented?) cause the ternary
148
+ # to return the max of both branches.
149
+ sig { returns(Integer) }
150
+ def max_register_length
151
+ @max_register_length ||= _compute_max_register_length
152
+ end
153
+
154
+ private def _compute_max_register_length
155
+ node = cfg_arch.idl_compiler.compile_expression(
156
+ register_length_expr, cfg_arch.symtab, pass_error: true
157
+ )
158
+ max = node.max_value(cfg_arch.symtab)
159
+ raise "Cannot determine max_register_length for register file '#{name}' " \
160
+ "(register_length() expression: '#{register_length_expr}')" if max == :unknown
161
+ Integer(max)
162
+ end
102
163
 
103
164
  sig { returns(T.nilable(String)) }
104
165
  def summary = @data["summary"]
@@ -4,13 +4,12 @@
4
4
 
5
5
  # frozen_string_literal: true
6
6
 
7
- # Combines knowledge of the architecture database with one or more portfolios (profile or certificate).
7
+ # Combines knowledge of the architecture database with one or more portfolios (profile).
8
8
  #
9
9
  # Used in portfolio-based ERB templates to gather information about the "portfolio_design".
10
10
  # The "portfolio_design" corresponds to the file being created by the ERB template and facilitates
11
11
  # sharing ERB template fragments between different kinds of portfolios (mostly in the appendices).
12
- # For example, a processor certificate model has one portfolio but a profile release has multiple portfolios
13
- # but they both have just one PortfolioDesign object.
12
+ # For example, a profile release has multiple portfolios but just one PortfolioDesign object.
14
13
 
15
14
  require "forwardable"
16
15
 
@@ -66,9 +65,7 @@ module Udb
66
65
 
67
66
  # Class methods
68
67
  def self.profile_release_type = "Profile Release"
69
- def self.proc_crd_type = "Certification Requirements Document"
70
- def self.proc_ctp_type = "Certification Test Plan"
71
- def self.portfolio_design_types = [profile_release_type, proc_crd_type, proc_ctp_type]
68
+ def self.portfolio_design_types = [profile_release_type]
72
69
 
73
70
  # @param name [#to_s] The name of the portfolio design (i.e., backend filename without a suffix)
74
71
  # @param cfg_arch [ConfiguredArchitecture] The database of RISC-V standards for a particular configuration
data/lib/udb/resolver.rb CHANGED
@@ -15,6 +15,9 @@ require_relative "yaml/yaml_resolver"
15
15
  module Udb
16
16
  # resolves the specification in the context of a config, and writes to a generation folder
17
17
  #
18
+ # Raised by Resolver#cfg_info when a config name or path cannot be found.
19
+ class ConfigNotFoundError < StandardError; end
20
+
18
21
  # The primary interface for users will be #cfg_arch_for
19
22
  class Resolver
20
23
  extend T::Sig
@@ -186,15 +189,20 @@ module Udb
186
189
  end
187
190
  raise "custom directory '#{overlay_path}' does not exist" if !overlay_path.nil? && !overlay_path.directory?
188
191
 
189
- if any_newer?(merged_spec_path(config_name) / ".stamp", deps)
190
- # Use Ruby YAML resolver instead of Python
191
- yaml_resolver = Udb::Yaml::Resolver.new(quiet: @quiet, compile_idl: @compile_idl)
192
- yaml_resolver.merge_files(
193
- std_path.to_s,
194
- overlay_path&.to_s,
195
- merged_spec_path(config_name).to_s
196
- )
197
- FileUtils.touch(merged_spec_path(config_name) / ".stamp")
192
+ FileUtils.mkdir_p(@gen_path / "spec")
193
+ merge_lock_name = merged_spec_path(config_name).basename
194
+ File.open(@gen_path / "spec" / ".#{merge_lock_name}.lock", File::CREAT | File::RDWR) do |f|
195
+ f.flock(File::LOCK_EX)
196
+ if any_newer?(merged_spec_path(config_name) / ".stamp", deps)
197
+ # Use Ruby YAML resolver instead of Python
198
+ yaml_resolver = Udb::Yaml::Resolver.new(quiet: @quiet, compile_idl: @compile_idl)
199
+ yaml_resolver.merge_files(
200
+ std_path.to_s,
201
+ overlay_path&.to_s,
202
+ merged_spec_path(config_name).to_s
203
+ )
204
+ FileUtils.touch(merged_spec_path(config_name) / ".stamp")
205
+ end
198
206
  end
199
207
  end
200
208
  end
@@ -205,19 +213,24 @@ module Udb
205
213
  @mutex.synchronize do
206
214
  config_name = config_yaml["name"]
207
215
 
208
- deps = Dir[merged_spec_path(config_name) / "**" / "*.yaml"].map { |p| Pathname.new(p) }
209
- if any_newer?(resolved_spec_path(config_name) / ".stamp", deps)
210
- # Use Ruby YAML resolver instead of Python
211
- yaml_resolver = Udb::Yaml::Resolver.new(quiet: @quiet, compile_idl: @compile_idl)
212
- yaml_resolver.resolve_files(
213
- merged_spec_path(config_name).to_s,
214
- resolved_spec_path(config_name).to_s,
215
- no_checks: false
216
- )
217
- FileUtils.touch(resolved_spec_path(config_name) / ".stamp")
218
- end
216
+ FileUtils.mkdir_p(@gen_path / "resolved_spec")
217
+ resolve_lock_name = resolved_spec_path(config_name).basename
218
+ File.open(@gen_path / "resolved_spec" / ".#{resolve_lock_name}.lock", File::CREAT | File::RDWR) do |f|
219
+ f.flock(File::LOCK_EX)
220
+ deps = Dir[merged_spec_path(config_name) / "**" / "*.yaml"].map { |p| Pathname.new(p) }
221
+ if any_newer?(resolved_spec_path(config_name) / ".stamp", deps)
222
+ # Use Ruby YAML resolver instead of Python
223
+ yaml_resolver = Udb::Yaml::Resolver.new(quiet: @quiet, compile_idl: @compile_idl)
224
+ yaml_resolver.resolve_files(
225
+ merged_spec_path(config_name).to_s,
226
+ resolved_spec_path(config_name).to_s,
227
+ no_checks: false
228
+ )
229
+ FileUtils.touch(resolved_spec_path(config_name) / ".stamp")
230
+ end
219
231
 
220
- FileUtils.cp_r(std_path / "isa", resolved_spec_path(config_name))
232
+ FileUtils.cp_r(std_path / "isa", resolved_spec_path(config_name))
233
+ end
221
234
  end
222
235
  end
223
236
 
@@ -240,8 +253,7 @@ module Udb
240
253
  if (@cfgs_path / "#{config_path_or_name}.yaml").file?
241
254
  (@cfgs_path / "#{config_path_or_name}.yaml").realpath
242
255
  else
243
- Udb.logger.error "Could not find config: #{config_path_or_name}"
244
- exit 1
256
+ raise ConfigNotFoundError, "Could not find config: #{config_path_or_name}"
245
257
  end
246
258
  else
247
259
  T.absurd(config_path_or_name)
@@ -291,6 +303,33 @@ module Udb
291
303
  end
292
304
  end
293
305
 
306
+ # Resolve a config pointer (name or file path) to a ConfiguredArchitecture.
307
+ # Resolution order:
308
+ # 1. If <cfgs_path>/<pointer>.yaml exists on disk, treat as a repo config name
309
+ # (handles names that contain '/', e.g. "profile/RVA23U64").
310
+ # 2. If the pointer ends in .yaml/.yml, is absolute, or starts with ./ or ../,
311
+ # treat as a file path resolved relative to +relative_dir+.
312
+ # 3. Otherwise raise ArgumentError — the pointer is neither a known config name
313
+ # nor a recognisable file path.
314
+ sig { params(pointer: String, relative_dir: Pathname).returns(Udb::ConfiguredArchitecture) }
315
+ def cfg_arch_for_pointer(pointer, relative_dir:)
316
+ if (@cfgs_path / "#{pointer}.yaml").file?
317
+ # Repo config name — may contain '/' for nested configs (e.g. "profile/RVA23U64").
318
+ cfg_arch_for(pointer)
319
+ elsif pointer.end_with?(".yaml", ".yml") ||
320
+ Pathname.new(pointer).absolute? ||
321
+ pointer.start_with?("./", "../")
322
+ # Explicit file path — resolve relative to the caller's directory.
323
+ path = Pathname.new(pointer)
324
+ cfg_arch_for(path.absolute? ? path : (relative_dir / path).cleanpath)
325
+ else
326
+ raise ArgumentError,
327
+ "Cannot resolve config pointer '#{pointer}': not a known config name " \
328
+ "under '#{@cfgs_path}' and not a recognisable file path " \
329
+ "(.yaml/.yml extension, absolute, or starting with ./ or ../)"
330
+ end
331
+ end
332
+
294
333
  # resolve the specification for a config, and return a ConfiguredArchitecture
295
334
  sig { params(config_path_or_name: T.any(Pathname, String)).returns(Udb::ConfiguredArchitecture) }
296
335
  def cfg_arch_for(config_path_or_name)
@@ -312,6 +351,28 @@ module Udb
312
351
  end
313
352
  end
314
353
 
354
+ # Create a ConfiguredArchitecture directly from an in-memory config data hash,
355
+ # bypassing resolve_config and resolve_arch entirely. Only valid when the config
356
+ # has no arch_overlay (i.e., it uses the standard spec at gen/resolved_spec/_).
357
+ # Callers must ensure this precondition holds before calling this method.
358
+ sig { params(config_data: T::Hash[String, T.untyped]).returns(Udb::ConfiguredArchitecture) }
359
+ def cfg_arch_for_data(config_data)
360
+ info = ConfigInfo.new(
361
+ name: config_data["name"],
362
+ path: Pathname.new("portfolio/#{config_data["name"]}"),
363
+ overlay_path: nil,
364
+ unresolved_yaml: config_data,
365
+ spec_path: std_path,
366
+ merged_spec_path: @gen_path / "spec" / "_",
367
+ resolved_spec_path: @gen_path / "resolved_spec" / "_",
368
+ resolver: self
369
+ )
370
+ Udb::ConfiguredArchitecture.new(
371
+ config_data["name"],
372
+ Udb::AbstractConfig.create_from_data(config_data, info)
373
+ )
374
+ end
375
+
315
376
  SCHEMAS_BASE_URL = "https://riscv.github.io/riscv-unified-db/schemas"
316
377
 
317
378
  # Resolve schema files by rewriting their $id to the full published URL and
data/lib/udb/version.rb CHANGED
@@ -5,5 +5,5 @@
5
5
  # frozen_string_literal: true
6
6
 
7
7
  module Udb
8
- def self.version = "0.1.9"
8
+ def self.version = "0.1.14"
9
9
  end
@@ -192,6 +192,14 @@ module Udb
192
192
  REQUIREMENT_OP_REGEX = /((?:>=)|(?:>)|(?:~>)|(?:<)|(?:<=)|(?:!=)|(?:=))/
193
193
  REQUIREMENT_REGEX = /#{REQUIREMENT_OP_REGEX}\s*(#{VersionSpec::VERSION_REGEX})/
194
194
 
195
+ # Intern cache: RequirementSpec.new with the same string returns the same object.
196
+ @intern_cache = T.let({}, T::Hash[String, RequirementSpec])
197
+
198
+ sig { params(requirement: String).returns(RequirementSpec) }
199
+ def self.new(requirement)
200
+ @intern_cache[requirement] ||= super
201
+ end
202
+
195
203
  sig { returns(String) }
196
204
  attr_reader :op
197
205