udb 0.1.4 → 0.1.6

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 (36) hide show
  1. checksums.yaml +4 -4
  2. data/.data/cfgs/mc100-32-full-example.yaml +0 -35
  3. data/.data/cfgs/qc_iu.yaml +0 -33
  4. data/.data/cfgs/rv32-riscv-tests.yaml +5 -1
  5. data/.data/cfgs/rv64-riscv-tests.yaml +4 -1
  6. data/.data/spec/std/isa/inst/F/fadd.s.yaml +16 -1
  7. data/.data/spec/std/isa/inst/F/fclass.s.yaml +7 -0
  8. data/.data/spec/std/isa/inst/F/fcvt.l.s.yaml +3 -0
  9. data/.data/spec/std/isa/inst/F/fcvt.lu.s.yaml +3 -0
  10. data/.data/spec/std/isa/inst/F/fcvt.s.l.yaml +4 -0
  11. data/.data/spec/std/isa/inst/F/fcvt.s.lu.yaml +4 -0
  12. data/.data/spec/std/isa/inst/F/fcvt.w.s.yaml +1 -1
  13. data/.data/spec/std/isa/inst/F/fcvt.wu.s.yaml +1 -1
  14. data/.data/spec/std/isa/inst/F/fdiv.s.yaml +4 -0
  15. data/.data/spec/std/isa/inst/F/feq.s.yaml +1 -1
  16. data/.data/spec/std/isa/inst/F/fle.s.yaml +14 -7
  17. data/.data/spec/std/isa/inst/F/fleq.s.yaml +30 -0
  18. data/.data/spec/std/isa/inst/F/flt.s.yaml +13 -8
  19. data/.data/spec/std/isa/inst/F/fltq.s.yaml +21 -0
  20. data/.data/spec/std/isa/inst/F/fmadd.s.yaml +4 -0
  21. data/.data/spec/std/isa/inst/F/fmax.s.yaml +30 -0
  22. data/.data/spec/std/isa/inst/F/fmin.s.yaml +30 -0
  23. data/.data/spec/std/isa/inst/F/fmsub.s.yaml +4 -0
  24. data/.data/spec/std/isa/inst/F/fmul.s.yaml +4 -0
  25. data/.data/spec/std/isa/inst/F/fnmadd.s.yaml +7 -0
  26. data/.data/spec/std/isa/inst/F/fnmsub.s.yaml +4 -0
  27. data/.data/spec/std/isa/inst/F/fsqrt.s.yaml +4 -0
  28. data/.data/spec/std/isa/isa/fp.idl +911 -101
  29. data/.data/spec/std/isa/isa/globals.isa +2 -0
  30. data/.data/spec/std/isa/isa/util.idl +22 -0
  31. data/.data/spec/std/isa/param/SCOUNTENABLE_EN.yaml +1 -1
  32. data/lib/udb/cfg_arch.rb +42 -6
  33. data/lib/udb/condition.rb +66 -2
  34. data/lib/udb/logic.rb +27 -1
  35. data/lib/udb/version.rb +1 -1
  36. metadata +2 -2
@@ -936,6 +936,8 @@ function xlen {
936
936
  } else {
937
937
  unreachable();
938
938
  }
939
+ } else {
940
+ unreachable();
939
941
  }
940
942
  }
941
943
  }
@@ -147,6 +147,28 @@ function count_leading_zeros {
147
147
  }
148
148
  }
149
149
 
150
+ function count_leading_zeros_64 {
151
+ returns
152
+ XReg # Number of leading zeros in +value+
153
+ arguments
154
+ U32 N, # bit width
155
+ Bits<64> value # value to count zero in
156
+ description {
157
+ Returns the number of leading 0 bits before the most-significant 1 bit of +value+,
158
+ or N if value is zero.
159
+ }
160
+ body {
161
+ for (U32 i=0; i < N; i++) {
162
+ if (value[N - 1 - i] == 1) {
163
+ return i;
164
+ }
165
+ }
166
+
167
+ # fall-through; value must be zero
168
+ return N;
169
+ }
170
+ }
171
+
150
172
  function sext {
151
173
  returns XReg
152
174
  arguments XReg value, XReg first_extended_bit
@@ -39,4 +39,4 @@ requirements:
39
39
  When mhpmcounter[i] does not exist, it cannot be enabled.
40
40
  definedBy:
41
41
  extension:
42
- name: Sm
42
+ name: S
data/lib/udb/cfg_arch.rb CHANGED
@@ -287,7 +287,12 @@ module Udb
287
287
 
288
288
  explicitly_implemented_extension_versions.each do |ext_ver|
289
289
  unless ext_ver.requirements_condition.satisfied_by_cfg_arch?(self) == SatisfiedResult::Yes
290
- reasons << "Extension requirement is unmet: #{ext_ver}. Needs: #{ext_ver.requirements_condition.minimize(expand: true).to_s_with_value(self, expand: false)}"
290
+ failing = ext_ver.requirements_condition.failing_conjuncts(self, expand: false)
291
+ reasons << "Extension requirement is unmet: #{ext_ver}. " + if failing.empty?
292
+ "Condition not yet determined: #{ext_ver.requirements_condition.to_s_with_value(self, expand: false)}"
293
+ else
294
+ "Failing condition(s):\n" + failing.map { |f| " - #{f}" }.join("\n")
295
+ end
291
296
  end
292
297
  end
293
298
 
@@ -295,15 +300,25 @@ module Udb
295
300
  config.param_values.each do |param_name, param_value|
296
301
  p = T.must(param(param_name))
297
302
  unless p.defined_by_condition.satisfied_by_cfg_arch?(self) == SatisfiedResult::Yes
303
+ failing = p.defined_by_condition.failing_conjuncts(self, expand: false)
298
304
  reasons << [
299
305
  "Parameter is not defined by this config: '#{param_name}'.",
300
- "Needs: #{p.defined_by_condition.minimize(expand: true).to_s_with_value(self, expand: false)}"
306
+ if failing.empty?
307
+ "Condition not yet determined: #{p.defined_by_condition.to_s_with_value(self, expand: false)}"
308
+ else
309
+ "Failing condition(s):\n" + failing.map { |f| " - #{f}" }.join("\n")
310
+ end
301
311
  ].join("\n")
302
312
  end
303
313
  unless p.requirements_condition.satisfied_by_cfg_arch?(self) == SatisfiedResult::Yes
314
+ failing = p.requirements_condition.failing_conjuncts(self, expand: false)
304
315
  reasons << [
305
316
  "Parameter requirements not met: '#{param_name}'.",
306
- "Needs: #{p.requirements_condition.minimize(expand: true).to_s_with_value(self, expand: false)}"
317
+ if failing.empty?
318
+ "Condition not yet determined: #{p.requirements_condition.to_s_with_value(self, expand: false)}"
319
+ else
320
+ "Failing condition(s):\n" + failing.map { |f| " - #{f}" }.join("\n")
321
+ end
307
322
  ].join("\n")
308
323
  end
309
324
  end
@@ -357,7 +372,12 @@ module Udb
357
372
  reasons = []
358
373
  mandatory_extension_reqs.each do |ext_req|
359
374
  if ext_req.requirements_condition.satisfied_by_cfg_arch?(self) != SatisfiedResult::Yes
360
- reasons << "Requirement of #{ext_req} are not met: #{ext_req.requirements_condition.to_s_with_value(self, expand: false)}"
375
+ failing = ext_req.requirements_condition.failing_conjuncts(self, expand: false)
376
+ reasons << "Requirement of #{ext_req} are not met:\n" + if failing.empty?
377
+ " Condition not yet determined: #{ext_req.requirements_condition.to_s_with_value(self, expand: false)}"
378
+ else
379
+ failing.map { |f| " - #{f}" }.join("\n")
380
+ end
361
381
  end
362
382
  end
363
383
 
@@ -414,11 +434,27 @@ module Udb
414
434
  # check that parameter is defined by the partial config (e.g., is defined by a mandatory
415
435
  # extension and/or other param value).
416
436
  unless p.defined_by_condition.satisfied_by_cfg_arch?(self) == SatisfiedResult::Yes
417
- reasons << "Parameter is not defined by this config: '#{param_name}'. Needs #{p.defined_by_condition}"
437
+ failing = p.defined_by_condition.failing_conjuncts(self, expand: false)
438
+ reasons << [
439
+ "Parameter is not defined by this config: '#{param_name}'.",
440
+ if failing.empty?
441
+ "Condition not yet determined: #{p.defined_by_condition.to_s_with_value(self, expand: false)}"
442
+ else
443
+ "Failing condition(s):\n" + failing.map { |f| " - #{f}" }.join("\n")
444
+ end
445
+ ].join("\n")
418
446
  end
419
447
 
420
448
  if p.requirements_condition.satisfied_by_cfg_arch?(self) == SatisfiedResult::No
421
- reasons << "Parameter requirements cannot be met: '#{param_name}'. Needs: #{p.requirements_condition}"
449
+ failing = p.requirements_condition.failing_conjuncts(self, expand: false)
450
+ reasons << [
451
+ "Parameter requirements cannot be met: '#{param_name}'.",
452
+ if failing.empty?
453
+ "Condition not yet determined: #{p.requirements_condition.to_s_with_value(self, expand: false)}"
454
+ else
455
+ "Failing condition(s):\n" + failing.map { |f| " - #{f}" }.join("\n")
456
+ end
457
+ ].join("\n")
422
458
  end
423
459
  end
424
460
 
data/lib/udb/condition.rb CHANGED
@@ -333,6 +333,10 @@ module Udb
333
333
  sig { abstract.params(cfg_arch: ConfiguredArchitecture, expand: T::Boolean).returns(String) }
334
334
  def to_s_with_value(cfg_arch, expand:); end
335
335
 
336
+ # returns the failing conjuncts (clauses that are false) for the given cfg_arch
337
+ sig { abstract.params(cfg_arch: ConfiguredArchitecture, expand: T::Boolean).returns(T::Array[String]) }
338
+ def failing_conjuncts(cfg_arch, expand:); end
339
+
336
340
  # string representation of condition in Asciidoc
337
341
  sig { abstract.returns(String) }
338
342
  def to_asciidoc; end
@@ -1151,7 +1155,7 @@ module Udb
1151
1155
  elsif cfg_arch.partially_configured?
1152
1156
  cb = make_cb_proc do |term|
1153
1157
  if term.is_a?(ExtensionTerm)
1154
- if cfg_arch.mandatory_extension_reqs.any? { |cfg_ext_req| cfg_ext_req.satisfied_by?(term.to_ext_req(cfg_arch)) }
1158
+ if cfg_arch.mandatory_extension_reqs.any? { |cfg_ext_req| term.to_ext_req(cfg_arch).satisfied_by?(cfg_ext_req) }
1155
1159
  SatisfiedResult::Yes
1156
1160
  elsif cfg_arch.possible_extension_versions.any? { |cfg_ext_ver| term.to_ext_req(cfg_arch).satisfied_by?(cfg_ext_ver) }
1157
1161
  SatisfiedResult::Maybe
@@ -1273,7 +1277,7 @@ module Udb
1273
1277
  SatisfiedResult::Yes
1274
1278
  end
1275
1279
  elsif cfg_arch.partially_configured?
1276
- if cfg_arch.mandatory_extension_reqs.any? { |cfg_ext_req| cfg_ext_req.satisfied_by?(term.to_ext_req(cfg_arch)) }
1280
+ if cfg_arch.mandatory_extension_reqs.any? { |cfg_ext_req| term.to_ext_req(cfg_arch).satisfied_by?(cfg_ext_req) }
1277
1281
  SatisfiedResult::Yes
1278
1282
  elsif cfg_arch.possible_extension_versions.any? { |cfg_ext_ver| term.to_ext_req(cfg_arch).satisfied_by?(cfg_ext_ver) }
1279
1283
  SatisfiedResult::Maybe
@@ -1312,6 +1316,60 @@ module Udb
1312
1316
  to_logic_tree(expand:).to_s_with_value(cb, format: LogicNode::LogicSymbolFormat::C)
1313
1317
  end
1314
1318
 
1319
+ sig { override.params(cfg_arch: ConfiguredArchitecture, expand: T::Boolean).returns(T::Array[String]) }
1320
+ def failing_conjuncts(cfg_arch, expand: false)
1321
+ cb = LogicNode.make_eval_cb do |term|
1322
+ case term
1323
+ when ExtensionTerm
1324
+ if cfg_arch.fully_configured?
1325
+ ext_ver = cfg_arch.implemented_extension_version(term.name)
1326
+ if ext_ver.nil? || !term.to_ext_req(cfg_arch).satisfied_by?(ext_ver)
1327
+ SatisfiedResult::No
1328
+ else
1329
+ SatisfiedResult::Yes
1330
+ end
1331
+ elsif cfg_arch.partially_configured?
1332
+ if cfg_arch.mandatory_extension_reqs.any? { |cfg_ext_req| term.to_ext_req(cfg_arch).satisfied_by?(cfg_ext_req) }
1333
+ SatisfiedResult::Yes
1334
+ elsif cfg_arch.possible_extension_versions.any? { |cfg_ext_ver| term.to_ext_req(cfg_arch).satisfied_by?(cfg_ext_ver) }
1335
+ SatisfiedResult::Maybe
1336
+ else
1337
+ SatisfiedResult::No
1338
+ end
1339
+ else
1340
+ SatisfiedResult::Maybe
1341
+ end
1342
+ when ParameterTerm
1343
+ if cfg_arch.fully_configured?
1344
+ if cfg_arch.param_values.key?(term.name)
1345
+ term.eval(cfg_arch)
1346
+ else
1347
+ SatisfiedResult::No
1348
+ end
1349
+ elsif cfg_arch.partially_configured?
1350
+ term.eval(cfg_arch)
1351
+ else
1352
+ SatisfiedResult::Maybe
1353
+ end
1354
+ when XlenTerm
1355
+ if cfg_arch.possible_xlens.include?(term.xlen)
1356
+ if cfg_arch.possible_xlens.size == 1
1357
+ SatisfiedResult::Yes
1358
+ else
1359
+ SatisfiedResult::Maybe
1360
+ end
1361
+ else
1362
+ SatisfiedResult::No
1363
+ end
1364
+ else
1365
+ raise "unexpected term type #{term.class.name}"
1366
+ end
1367
+ end
1368
+ to_logic_tree(expand:).failing_conjuncts(cb).map do |node|
1369
+ node.to_s_with_value(cb, format: LogicNode::LogicSymbolFormat::C)
1370
+ end
1371
+ end
1372
+
1315
1373
  sig { override.returns(String) }
1316
1374
  def to_asciidoc
1317
1375
  to_logic_tree(expand: false).to_asciidoc(include_versions: false)
@@ -1690,6 +1748,9 @@ module Udb
1690
1748
  sig { override.params(cfg_arch: ConfiguredArchitecture, expand: T::Boolean).returns(String) }
1691
1749
  def to_s_with_value(cfg_arch, expand: false) = "true"
1692
1750
 
1751
+ sig { override.params(cfg_arch: ConfiguredArchitecture, expand: T::Boolean).returns(T::Array[String]) }
1752
+ def failing_conjuncts(cfg_arch, expand: false) = []
1753
+
1693
1754
  sig { override.returns(String) }
1694
1755
  def to_asciidoc = "true"
1695
1756
 
@@ -1803,6 +1864,9 @@ module Udb
1803
1864
  sig { override.params(cfg_arch: ConfiguredArchitecture, expand: T::Boolean).returns(String) }
1804
1865
  def to_s_with_value(cfg_arch, expand: false) = "false"
1805
1866
 
1867
+ sig { override.params(cfg_arch: ConfiguredArchitecture, expand: T::Boolean).returns(T::Array[String]) }
1868
+ def failing_conjuncts(cfg_arch, expand: false) = ["false"]
1869
+
1806
1870
  sig { override.returns(String) }
1807
1871
  def to_asciidoc = "false"
1808
1872
 
data/lib/udb/logic.rb CHANGED
@@ -1058,8 +1058,10 @@ module Udb
1058
1058
  cv <=> T.cast(other_param.comparison_value, String)
1059
1059
  elsif cv.is_a?(Array)
1060
1060
  cv <=> T.cast(other_param.comparison_value, T::Array[T.any(String, T::Boolean, Integer)])
1061
- else
1061
+ elsif cv.is_a?(Integer)
1062
1062
  T.cast(comparison_value, Integer) <=> T.cast(other_param.comparison_value, Integer)
1063
+ else
1064
+ T.cast(comparison_value, T::Boolean) <=> T.cast(other_param.comparison_value, T::Boolean)
1063
1065
  end
1064
1066
  else
1065
1067
  # these are the same (ignoring reason)
@@ -1689,6 +1691,27 @@ module Udb
1689
1691
  end
1690
1692
  end
1691
1693
 
1694
+ sig { params(eval_cb: EvalCallbackType).returns(T::Array[LogicNode]) }
1695
+ def failing_conjuncts(eval_cb)
1696
+ if @type == LogicNodeType::And
1697
+ # Evaluate each original child independently to find failing conjuncts
1698
+ child_replace_cb = LogicNode.make_replace_cb do |tn|
1699
+ r = eval_cb.call(T.cast(tn.children.fetch(0), TermType))
1700
+ case r
1701
+ when SatisfiedResult::Yes then LogicNode::True
1702
+ when SatisfiedResult::No then LogicNode::False
1703
+ when SatisfiedResult::Maybe then tn
1704
+ else T.absurd(r)
1705
+ end
1706
+ end
1707
+ node_children.select do |child|
1708
+ child.replace_terms(child_replace_cb).reduce.type == LogicNodeType::False
1709
+ end
1710
+ else
1711
+ [self]
1712
+ end
1713
+ end
1714
+
1692
1715
  sig { params(callback: EvalCallbackType).returns(SatisfiedResult) }
1693
1716
  def eval_cb(callback)
1694
1717
  case @type
@@ -2696,6 +2719,9 @@ module Udb
2696
2719
  if xor_with_self
2697
2720
  # xor with self if always false
2698
2721
  False
2722
+ elsif reduced.node_children.all? { |c| c.type == LogicNodeType::True || c.type == LogicNodeType::False }
2723
+ # all children are literals: xor is true iff exactly one child is true
2724
+ reduced.node_children.count { |c| c.type == LogicNodeType::True } == 1 ? True : False
2699
2725
  else
2700
2726
  reduced
2701
2727
  end
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.4"
8
+ def self.version = "0.1.6"
9
9
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: udb
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.4
4
+ version: 0.1.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Derek Hower
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2026-03-26 00:00:00.000000000 Z
12
+ date: 2026-03-31 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activesupport