Skip to content

Commit 924ffde

Browse files
Fixed instructions and CSRs in #291 (CRDs list things like instructions, CSRs, and traps that aren't in the configuration). Still need to fix traps and interrupts.
1 parent d990076 commit 924ffde

File tree

8 files changed

+89
-48
lines changed

8 files changed

+89
-48
lines changed

lib/arch_obj_models/csr.rb

Lines changed: 13 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ def defined_in_base64? = @data["base"].nil? || @data["base"] == 64
4646
# @return [Boolean] true if this CSR is defined regardless of the effective XLEN
4747
def defined_in_all_bases? = @data["base"].nil?
4848

49-
# @param design [Design] A configuration
49+
# @param design [Design] The design
5050
# @return [Boolean] Whether or not the format of this CSR changes when the effective XLEN changes in some mode
5151
def format_changes_with_xlen?(design)
5252
dynamic_length?(design) ||
@@ -55,7 +55,7 @@ def format_changes_with_xlen?(design)
5555
end
5656
end
5757

58-
# @param design [Design] A configuration
58+
# @param design [Design] The design
5959
# @return [Array<Idl::FunctionDefAst>] List of functions reachable from this CSR's sw_read or a field's sw_write function
6060
def reachable_functions(design)
6161
return @reachable_functions unless @reachable_functions.nil?
@@ -104,7 +104,7 @@ def reachable_functions_unevaluated(design)
104104
@reachable_functions_unevaluated = fns.uniq
105105
end
106106

107-
# @param design [Design] A configuration
107+
# @param design [Design] The design
108108
# @return [Boolean] Whether or not the length of the CSR depends on a runtime value
109109
# (e.g., mstatus.SXL)
110110
def dynamic_length?(design)
@@ -142,7 +142,7 @@ def min_length(design)
142142
end
143143
end
144144

145-
# @param design [Design] A configuration (can be nil if the lenth is not dependent on a config parameter)
145+
# @param design [Design] The design (can be nil if the length is not dependent on a config parameter)
146146
# @param effective_xlen [Integer] The effective xlen, needed since some fields change location with XLEN. If the field location is not determined by XLEN, then this parameter can be nil
147147
# @return [Integer] Length, in bits, of the CSR, given effective_xlen
148148
# @return [nil] if the length cannot be determined from the design (e.g., because SXLEN is unknown and +effective_xlen+ was not provided)
@@ -254,7 +254,7 @@ def length_cond64
254254
end
255255
end
256256

257-
# @param design [Design] A configuration
257+
# @param design [Design] The design
258258
# @return [String] Pretty-printed length string
259259
def length_pretty(design, effective_xlen=nil)
260260
if dynamic_length?(design)
@@ -306,7 +306,7 @@ def description_html
306306
Asciidoctor.convert description
307307
end
308308

309-
# @param design [Design] A configuration
309+
# @param design [Design] The design
310310
# @return [Array<CsrField>] All implemented fields for this CSR at the given effective XLEN, sorted by location (smallest location first)
311311
# Excluded any fields that are defined by unimplemented extensions or a base that is not effective_xlen
312312
def implemented_fields_for(design, effective_xlen)
@@ -321,7 +321,7 @@ def implemented_fields_for(design, effective_xlen)
321321
end
322322
end
323323

324-
# @param design [Design] A configuration
324+
# @param design [Design] The design
325325
# @return [Array<CsrField>] All implemented fields for this CSR
326326
# Excluded any fields that are defined by unimplemented extensions
327327
def implemented_fields(design)
@@ -377,7 +377,7 @@ def field(field_name)
377377
field_hash[field_name.to_s]
378378
end
379379

380-
# @param design [Design] A configuration
380+
# @param design [Design] The design
381381
# @param effective_xlen [Integer] The effective XLEN to apply, needed when field locations change with XLEN in some mode
382382
# @return [Idl::BitfieldType] A bitfield type that can represent all fields of the CSR
383383
def bitfield_type(design, effective_xlen = nil)
@@ -425,7 +425,7 @@ def type_checked_sw_read_ast(symtab)
425425
end
426426

427427
# @return [FunctionBodyAst] The abstract syntax tree of the sw_read() function
428-
# @param design [Design] A configuration
428+
# @param design [Design] The design
429429
def sw_read_ast(symtab)
430430
raise ArgumentError, "Argument should be a symtab" unless symtab.is_a?(Idl::SymbolTable)
431431

@@ -493,7 +493,7 @@ def pruned_sw_read_ast(design)
493493
# {bits: 12, name: 'imm12', attr: [''], type: 6}
494494
# ]}
495495
#
496-
# @param design [Design] A configuration
496+
# @param design [Design] The design
497497
# @param effective_xlen [Integer,nil] Effective XLEN to use when CSR length is dynamic
498498
# @param exclude_unimplemented [Boolean] If true, do not create include unimplemented fields in the figure
499499
# @param optional_type [Integer] Wavedrom type (Fill color) for fields that are optional (not mandatory) in a partially-specified design
@@ -543,10 +543,10 @@ def wavedrom_desc(design, effective_xlen, exclude_unimplemented: false, optional
543543
def exists_in_design?(design)
544544
if design.fully_configured?
545545
(@data["base"].nil? || (design.possible_xlens.include? @data["base"])) &&
546-
design.transitive_implemented_ext_vers.any? { |e| defined_by?(e) }
546+
design.transitive_implemented_ext_vers.any? { |ext_ver| defined_by?(ext_ver) }
547547
else
548548
(@data["base"].nil? || (design.possible_xlens.include? @data["base"])) &&
549-
design.prohibited_ext_reqs.none? { |ext_req| ext_req.satisfying_versions.any? { |e| defined_by?(e) } }
549+
design.prohibited_ext_reqs.none? { |ext_req| ext_req.satisfying_versions.any? { |ext_ver| defined_by?(ext_ver) } }
550550
end
551551
end
552552

@@ -556,10 +556,6 @@ def optional_in_design?(design)
556556
raise "optional_in_design? should only be used by a partially-specified arch def" unless design.partially_configured?
557557

558558
exists_in_design?(design) &&
559-
design.mandatory_ext_reqs.all? do |ext_req|
560-
ext_req.satisfying_versions.none? do |ext_ver|
561-
defined_by?(ext_ver)
562-
end
563-
end
559+
design.mandatory_ext_reqs.all? { |ext_req| ext_req.satisfying_versions.none? { |ext_ver| defined_by?(ext_ver) } }
564560
end
565561
end

lib/arch_obj_models/csr_field.rb

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,8 @@ def initialize(parent_csr, field_name, field_data)
2828
@type_cache = {}
2929
end
3030

31-
# @param possible_xlens [Array<Integer>] List of xlens that be used in any implemented mode
32-
# @param extensions [Array<ExtensionVersion>] List of extensions implemented
33-
# @return [Boolean] whether or not the instruction is implemented given the supplies config options
31+
# @param design [Design] The design
32+
# @return [Boolean] whether or not the instruction is implemented given the supplied design
3433
def exists_in_design?(design)
3534
if design.fully_configured?
3635
parent.exists_in_design?(design) &&
@@ -54,11 +53,7 @@ def optional_in_design?(design)
5453
if data["definedBy"].nil?
5554
parent.optional_in_design?(design)
5655
else
57-
design.mandatory_ext_reqs.all? do |ext_req|
58-
ext_req.satisfying_versions.none? do |ext_ver|
59-
defined_by?(ext_ver)
60-
end
61-
end
56+
design.mandatory_ext_reqs.all? { |ext_req| ext_req.satisfying_versions.none? { |ext_ver| defined_by?(ext_ver) } }
6257
end
6358
)
6459
end
@@ -146,7 +141,7 @@ def pruned_type_ast(symtab)
146141
@pruned_type_asts[symtab_hash] = ast
147142
end
148143

149-
# returns the definitive type for a design
144+
# Returns the definitive type for the design part of the symbol table.
150145
#
151146
# @param symtab [SymbolTable] Symbol table
152147
# @return [String]
@@ -250,9 +245,9 @@ def alias
250245
@alias
251246
end
252247

253-
# @return [Array<Idl::FunctionDefAst>] List of functions called thorugh this field
254248
# @param design [Design] The design
255249
# @Param effective_xlen [Integer] 32 or 64; needed because fields can change in different XLENs
250+
# @return [Array<Idl::FunctionDefAst>] List of functions called thorough this field
256251
def reachable_functions(design, effective_xlen)
257252
return @reachable_functions unless @reachable_functions.nil?
258253

lib/arch_obj_models/database_obj.rb

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -206,13 +206,23 @@ def keys = @data.keys
206206
# @return (see Hash#key?)
207207
def key?(k) = @data.key?(k)
208208

209+
# @param ext_ver [ExtensionVersion] Version of the extension
210+
# @param design [Design] The backend design
211+
# @return [Boolean] Whether or not the object is defined-by the given ExtensionVersion in the given Design.
212+
def in_scope?(ext_ver, design)
213+
raise ArgumentError, "Require an ExtensionVersion object but got a #{ext_ver.class} object" unless ext_ver.is_a?(ExtensionVersion)
214+
raise ArgumentError, "Require a Design object but got a #{design.class} object" unless design.is_a?(Design)
215+
216+
defined_by?(ext_ver)
217+
end
218+
209219
# @overload defined_by?(ext_name, ext_version)
210220
# @param ext_name [#to_s] An extension name
211221
# @param ext_version [#to_s] A specific extension version
212-
# @return [Boolean] Whether or not the instruction is defined by extension `ext`, version `version`
222+
# @return [Boolean] Whether or not the object is defined by extension `ext`, version `version`
213223
# @overload defined_by?(ext_version)
214224
# @param ext_version [ExtensionVersion] An extension version
215-
# @return [Boolean] Whether or not the instruction is defined by ext_version
225+
# @return [Boolean] Whether or not the object is defined by ext_version
216226
def defined_by?(*args)
217227
ext_ver =
218228
if args.size == 1
@@ -228,7 +238,7 @@ def defined_by?(*args)
228238
raise ArgumentError, "Unsupported number of arguments (#{args.size})"
229239
end
230240

231-
defined_by_condition.satisfied_by? { |req| req.satisfied_by?(ext_ver) }
241+
defined_by_condition.satisfied_by? { |ext_req| ext_req.satisfied_by?(ext_ver) }
232242
end
233243

234244
# because of multiple ("allOf") conditions, we generally can't return a list of extension versions here....
@@ -564,7 +574,6 @@ def to_rb_helper(hsh)
564574
# return a string that can be eval'd to determine if the objects in +ary_name+
565575
# meet the Condition
566576
#
567-
# @param ary_name [String] Name of a ruby string in the eval binding
568577
# @return [Boolean] If the condition is met
569578
def to_rb
570579
to_rb_helper(@hsh)
@@ -592,7 +601,10 @@ def satisfied_by?(&block)
592601

593602
raise ArgumentError, "Expecting one argument to block" unless block.arity == 1
594603

595-
eval to_rb
604+
# Written to allow debug breakpoints on individual lines.
605+
to_rb_expr = to_rb
606+
ret = eval to_rb_expr
607+
ret
596608
end
597609

598610
def satisfying_ext_versions

lib/arch_obj_models/extension.rb

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -517,6 +517,34 @@ def implemented_instructions
517517
inst.defined_by?(self)
518518
end
519519
end
520+
521+
# @param design [Design] The design
522+
# @return [Array<Csr>] List of CSRs in-scope for this design for this extension version (may be empty)
523+
# Factors in effect of design's xlen in the appropriate mode for the CSR.
524+
def in_scope_csrs(design)
525+
raise ArgumentError, "Require a Design object but got a #{design.class} object" unless design.is_a?(Design)
526+
527+
return @in_scope_csrs unless @in_scope_csrs.nil?
528+
529+
@in_scope_csrs = @arch.csrs.select do |csr|
530+
csr.defined_by?(self) &&
531+
(csr.base.nil? || (design.possible_xlens.include?(csr.base)))
532+
end
533+
end
534+
535+
# @param design [Design] The design
536+
# @return [Array<Instruction>] List of instructions in-scope for this design for this extension version (may be empty)
537+
# Factors in effect of design's xlen in the appropriate mode for the instruction.
538+
def in_scope_instructions(design)
539+
raise ArgumentError, "Require a Design object but got a #{design.class} object" unless design.is_a?(Design)
540+
541+
return @in_scope_instructions unless @in_scope_instructions.nil?
542+
543+
@in_scope_instructions = @arch.instructions.select do |inst|
544+
inst.defined_by?(self) &&
545+
(inst.base.nil? || (design.possible_xlens.include?(inst.base)))
546+
end
547+
end
520548
end
521549

522550
# Is the extension mandatory, optional, various kinds of optional, etc.

lib/arch_obj_models/instruction.rb

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -743,8 +743,7 @@ def excluded_by?(*args)
743743
#
744744
# TODO: Does this function actually work for a partially configured design?
745745
# It is calling DatabaseObject.defined_by? with ExtensionRequirement objects
746-
# returned from Design.prohibited_ext_reqs() and Design.mandatory_ext_reqs()
747-
# but only accepts an ExtensionVersion object.
746+
# returned from Design.mandatory_ext_reqs() but only accepts an ExtensionVersion object.
748747
def exists_in_design?(design)
749748
if design.fully_configured?
750749
(@data["base"].nil? || (design.possible_xlens.include?(@data["base"]))) &&
@@ -754,7 +753,7 @@ def exists_in_design?(design)
754753
raise "unexpected design type" unless design.partially_configured?
755754

756755
(@data["base"].nil? || (design.possible_xlens.include?(@data["base"]))) &&
757-
design.prohibited_ext_reqs.none? { |ext_req| defined_by?(ext_req) } &&
756+
design.prohibited_ext_reqs.none? { |ext_req| ext_req.satisfying_versions.any? { |ext_ver| defined_by?(ext_ver) } }
758757
design.mandatory_ext_reqs.none? { |ext_req| excluded_by?(ext_req) }
759758
end
760759
end

lib/arch_obj_models/portfolio.rb

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -127,30 +127,36 @@ def in_scope_extensions
127127

128128
end
129129

130+
# @param design [Design] The design
130131
# @return [Array<Instruction>] Sorted list of all instructions associated with extensions listed as
131132
# mandatory or optional in portfolio. Uses instructions provided by the
132133
# minimum version of the extension that meets the extension requirement.
133-
def in_scope_instructions
134+
def in_scope_instructions(design)
135+
raise ArgumentError, "Require a Design object but got a #{design.class} object" unless design.is_a?(Design)
136+
134137
return @in_scope_instructions unless @in_scope_instructions.nil?
135138

136139
@in_scope_instructions = []
137140
portfolios.each do |portfolio|
138-
@in_scope_instructions += portfolio.in_scope_instructions
141+
@in_scope_instructions += portfolio.in_scope_instructions(design)
139142
end
140143

141144
@in_scope_instructions =
142145
@in_scope_instructions.uniq(&:name).sort_by(&:name)
143146
end
144147

148+
# @param design [Design] The design
145149
# @return [Array<Csr>] Unsorted list of all CSRs associated with extensions listed as
146150
# mandatory or optional in portfolio. Uses CSRs provided by the
147151
# minimum version of the extension that meets the extension requirement.
148-
def in_scope_csrs
152+
def in_scope_csrs(design)
153+
raise ArgumentError, "Require a Design object but got a #{design.class} object" unless design.is_a?(Design)
154+
149155
return @in_scope_csrs unless @in_scope_csrs.nil?
150156

151157
@in_scope_csrs = []
152158
portfolios.each do |portfolio|
153-
@in_scope_csrs += portfolio.in_scope_csrs
159+
@in_scope_csrs += portfolio.in_scope_csrs(design)
154160
end
155161

156162
@in_scope_csrs.uniq(&:name)
@@ -349,24 +355,30 @@ def in_scope_min_satisfying_extension_versions
349355
@in_scope_min_satisfying_extension_versions
350356
end
351357

358+
# @param design [Design] The design
352359
# @return [Array<Instruction>] Sorted list of all instructions associated with extensions listed as
353360
# mandatory or optional in portfolio. Uses instructions provided by the
354361
# minimum version of the extension that meets the extension requirement.
355-
def in_scope_instructions
362+
def in_scope_instructions(design)
363+
raise ArgumentError, "Require a Design object but got a #{design.class} object" unless design.is_a?(Design)
364+
356365
return @in_scope_instructions unless @in_scope_instructions.nil?
357366

358367
@in_scope_instructions =
359-
in_scope_min_satisfying_extension_versions.map {|ext_ver| ext_ver.implemented_instructions }.flatten.uniq.sort
368+
in_scope_min_satisfying_extension_versions.map {|ext_ver| ext_ver.in_scope_instructions(design) }.flatten.uniq.sort
360369
end
361370

371+
# @param design [Design] The design
362372
# @return [Array<Csr>] Unsorted list of all CSRs associated with extensions listed as
363373
# mandatory or optional in portfolio. Uses CSRs provided by the
364374
# minimum version of the extension that meets the extension requirement.
365-
def in_scope_csrs
375+
def in_scope_csrs(design)
376+
raise ArgumentError, "Require a Design object but got a #{design.class} object" unless design.is_a?(Design)
377+
366378
return @in_scope_csrs unless @in_scope_csrs.nil?
367379

368380
@in_scope_csrs =
369-
in_scope_min_satisfying_extension_versions.map {|ext_ver| ext_ver.implemented_csrs }.flatten.uniq
381+
in_scope_min_satisfying_extension_versions.map {|ext_ver| ext_ver.in_scope_csrs(design) }.flatten.uniq
370382
end
371383

372384
# @return [Boolean] Does the profile differentiate between different types of optional.

lib/config.rb

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,4 @@ def implemented_extensions
178178

179179
def mandatory_extensions = raise "mandatory_extensions is only available for a PartialConfig"
180180
def prohibited_extensions = raise "prohibited_extensions is only available for a PartialConfig"
181-
182-
# def prohibited_ext?(ext_name, cfg_arch) = !ext?(ext_name, cfg_arch)
183-
# def ext?(ext_name, cfg_arch) = implemented_extensions(cfg_arch).any? { |e| e.name == ext_name.to_s }
184181
end

lib/portfolio_design.rb

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -179,12 +179,14 @@ def in_scope_ext_reqs = @portfolio_grp.in_scope_ext_reqs
179179
# @return [Array<Instruction>] Sorted list of all instructions associated with extensions listed as
180180
# mandatory or optional in portfolio. Uses instructions provided by the
181181
# minimum version of the extension that meets the extension requirement.
182-
def in_scope_instructions = @portfolio_grp.in_scope_instructions
182+
# Factors in things like XLEN in design.
183+
def in_scope_instructions = @portfolio_grp.in_scope_instructions(self)
183184

184185
# @return [Array<Csr>] Unsorted list of all CSRs associated with extensions listed as
185186
# mandatory or optional in portfolio. Uses CSRs provided by the
186187
# minimum version of the extension that meets the extension requirement.
187-
def in_scope_csrs = @portfolio_grp.in_scope_csrs
188+
# Factors in things like XLEN in design.
189+
def in_scope_csrs = @portfolio_grp.in_scope_csrs(self)
188190

189191
# @return [String] Given an extension +ext_name+, return the presence as a string.
190192
# Returns the greatest presence string across all portfolios in this design.

0 commit comments

Comments
 (0)