origen_arm 0.1.0

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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: aac2a9ad38cd6455af8072078ce1323050ffa8ccd807a309aa162f7a495a1d04
4
+ data.tar.gz: 40fcc38125de73c08bccb499ffda8e60815ccb46b44b0e96abe50e4e5f8dc2d5
5
+ SHA512:
6
+ metadata.gz: d558d399e03bd7da9209cf3872801c3d975424682982bdeb5744649ad06a916bacc2e203c9a816c06b9c3d25c57bb3d34d647f196f9799e07789f037c03fdb4d
7
+ data.tar.gz: 5271ac914b8d3df3e8e5fd9f0c0a2f9c2fec65166e5c235c66f73187ecb14bf85b6aa17c248f25c5ab8fd34a3c4611c5319eb7e782a2ffa25df08ecb0d74a371
@@ -0,0 +1,103 @@
1
+ require 'origen'
2
+ class OrigenARMApplication < Origen::Application
3
+
4
+ # See http://origen-sdk.org/origen/api/Origen/Application/Configuration.html
5
+ # for a full list of the configuration options available
6
+
7
+ # These attributes should never be changed, the duplication here will be resolved in future
8
+ # by condensing these attributes that do similar things
9
+ self.name = "origen_arm"
10
+ self.namespace = "OrigenARM"
11
+ config.name = "origen_arm"
12
+ config.initials = "OrigenARM"
13
+ config.rc_url = "git@github.com:Origen-SDK/origen_arm.git"
14
+ config.release_externally = true
15
+ config.gem_name = "origen_arm"
16
+
17
+ # To enable deployment of your documentation to a web server (via the 'origen web'
18
+ # command) fill in these attributes.
19
+ config.web_directory = "git@github.com:Origen-SDK/Origen-SDK.github.io.git/arm"
20
+ config.web_domain = "http://origen-sdk.org/arm"
21
+
22
+ # When false Origen will be less strict about checking for some common coding errors,
23
+ # it is recommended that you leave this to true for better feedback and easier debug.
24
+ # This will be the default setting in Origen v3.
25
+ config.strict_errors = true
26
+
27
+ # See: http://origen-sdk.org/origen/latest/guides/utilities/lint/
28
+ config.lint_test = {
29
+ # Require the lint tests to pass before allowing a release to proceed
30
+ run_on_tag: true,
31
+ # Auto correct violations where possible whenever 'origen lint' is run
32
+ auto_correct: true,
33
+ # Limit the testing for large legacy applications
34
+ #level: :easy,
35
+ # Run on these directories/files by default
36
+ #files: ["lib", "config/application.rb"],
37
+ }
38
+
39
+ config.semantically_version = true
40
+
41
+ # An example of how to set application specific LSF parameters
42
+ #config.lsf.project = "msg.te"
43
+
44
+ # An example of how to specify a prefix to add to all generated patterns
45
+ #config.pattern_prefix = "nvm"
46
+
47
+ # An example of how to add header comments to all generated patterns
48
+ #config.pattern_header do
49
+ # cc "This is a pattern created by the example origen application"
50
+ #end
51
+
52
+ # By default all generated output will end up in ./output.
53
+ # Here you can specify an alternative directory entirely, or make it dynamic such that
54
+ # the output ends up in a setup specific directory.
55
+ #config.output_directory do
56
+ # "#{Origen.root}/output/#{$dut.class}"
57
+ #end
58
+
59
+ # Similarly for the reference files, generally you want to setup the reference directory
60
+ # structure to mirror that of your output directory structure.
61
+ #config.reference_directory do
62
+ # "#{Origen.root}/.ref/#{$dut.class}"
63
+ #end
64
+
65
+ # This will automatically deploy your documentation after every tag
66
+ #def after_release_email(tag, note, type, selector, options)
67
+ # command = "origen web compile --remote --api"
68
+ # Dir.chdir Origen.root do
69
+ # system command
70
+ # end
71
+ #end
72
+
73
+ # Ensure that all tests pass before allowing a release to continue
74
+ #def validate_release
75
+ # if !system("origen specs") || !system("origen examples")
76
+ # puts "Sorry but you can't release with failing tests, please fix them and try again."
77
+ # exit 1
78
+ # else
79
+ # puts "All tests passing, proceeding with release process!"
80
+ # end
81
+ #end
82
+
83
+ # To enabled source-less pattern generation create a class (for example PatternDispatcher)
84
+ # to generate the pattern. This should return false if the requested pattern has been
85
+ # dispatched, otherwise Origen will proceed with looking up a pattern source as normal.
86
+ #def before_pattern_lookup(requested_pattern)
87
+ # PatternDispatcher.new.dispatch_or_return(requested_pattern)
88
+ #end
89
+
90
+ # If you use pattern iterators you may come across the case where you request a pattern
91
+ # like this:
92
+ # origen g example_pat_b0.atp
93
+ #
94
+ # However it cannot be found by Origen since the pattern name is actually example_pat_bx.atp
95
+ # In the case where the pattern cannot be found Origen will pass the name to this translator
96
+ # if it exists, and here you can make any substitutions to help Origen find the file you
97
+ # want. In this example any instances of _b\d, where \d means a number, are replaced by
98
+ # _bx.
99
+ #config.pattern_name_translator do |name|
100
+ # name.gsub(/_b\d/, "_bx")
101
+ #end
102
+
103
+ end
@@ -0,0 +1,24 @@
1
+ # This file is used to boot your plugin when it is running in standalone mode
2
+ # from its own workspace - i.e. when the plugin is being developed.
3
+ #
4
+ # It will not be loaded when the plugin is imported by a 3rd party app - in that
5
+ # case only lib/origen_arm.rb is loaded.
6
+ #
7
+ # Therefore this file can be used to load anything extra that you need to boot
8
+ # the development environment for this app. For example, this is typically used
9
+ # to load some additional test classes to use your plugin APIs so that they can
10
+ # be tested and/or interacted with in the console.
11
+ require "origen_arm"
12
+
13
+ module OrigenARMDev
14
+ # Example of how to explicitly require a file
15
+ # require "origen_arm_dev/my_file"
16
+
17
+ # Load all files in the lib/origen_arm_dev directory.
18
+ # Note that there is no problem from requiring a file twice (Ruby will ignore
19
+ # the second require), so if you have a file that must be required first, then
20
+ # explicitly require it up above and then let this take care of the rest.
21
+ Dir.glob("#{File.dirname(__FILE__)}/../lib/origen_arm_dev/**/*.rb").sort.each do |file|
22
+ require file
23
+ end
24
+ end
@@ -0,0 +1,79 @@
1
+ # This file should be used to extend the origen with application specific commands
2
+
3
+ # Map any command aliases here, for example to allow 'origen ex' to refer to a
4
+ # command called execute you would add a reference as shown below:
5
+ aliases ={
6
+ # "ex" => "execute",
7
+ }
8
+
9
+ # The requested command is passed in here as @command, this checks it against
10
+ # the above alias table and should not be removed.
11
+ @command = aliases[@command] || @command
12
+
13
+ # Now branch to the specific task code
14
+ case @command
15
+
16
+ # (Working) example of how to create an application specific comment, here to generate
17
+ # a tags file for you application to enable method definition lookup and similar within
18
+ # editors/IDEs
19
+ when "tags"
20
+ # Here the logic is just written in-line, alternatively it could be written in a
21
+ # dedicated file and required here, e.g.
22
+ #require "origen_arm/commands/my_command" # Would load file lib/origen_arm/commands/my_command.rb
23
+ Dir.chdir Origen.root do
24
+ system("ripper-tags -R")
25
+ end
26
+ # You must always exit upon successfully capturing and executing a command to prevent
27
+ # control flowing back to Origen
28
+ exit 0
29
+
30
+ ## Example of how to make a command to run unit tests, this simply invokes RSpec on
31
+ ## the spec directory
32
+ #when "specs"
33
+ # require "rspec"
34
+ # exit RSpec::Core::Runner.run(['spec'])
35
+
36
+ ## Example of how to make a command to run diff-based tests
37
+ #when "examples", "test"
38
+ # Origen.load_application
39
+ # status = 0
40
+ #
41
+ # # Compiler tests
42
+ # ARGV = %w(templates/example.txt.erb -t debug -r approved)
43
+ # load "origen/commands/compile.rb"
44
+ # # Pattern generator tests
45
+ # #ARGV = %w(some_pattern -t debug -r approved)
46
+ # #load "#{Origen.top}/lib/origen/commands/generate.rb"
47
+ #
48
+ # if Origen.app.stats.changed_files == 0 &&
49
+ # Origen.app.stats.new_files == 0 &&
50
+ # Origen.app.stats.changed_patterns == 0 &&
51
+ # Origen.app.stats.new_patterns == 0
52
+ #
53
+ # Origen.app.stats.report_pass
54
+ # else
55
+ # Origen.app.stats.report_fail
56
+ # status = 1
57
+ # end
58
+ # puts
59
+ # if @command == "test"
60
+ # Origen.app.unload_target!
61
+ # require "rspec"
62
+ # result = RSpec::Core::Runner.run(['spec'])
63
+ # status = status == 1 ? 1 : result
64
+ # end
65
+ # exit status # Exit with a 1 on the event of a failure per std unix result codes
66
+
67
+ # Always leave an else clause to allow control to fall back through to the
68
+ # Origen command handler.
69
+ else
70
+ # You probably want to also add the your commands to the help shown via
71
+ # origen -h, you can do this by assigning the required text to @application_commands
72
+ # before handing control back to Origen.
73
+ @application_commands = <<-EOT
74
+ tags Build a tags file for this app
75
+ EOT
76
+ # specs Run the specs (tests), -c will enable coverage
77
+ # examples Run the examples (tests), -c will enable coverage
78
+ # test Run both specs and examples, -c will enable coverage
79
+ end
@@ -0,0 +1,8 @@
1
+ module OrigenARM
2
+ MAJOR = 0
3
+ MINOR = 1
4
+ BUGFIX = 0
5
+ DEV = nil
6
+
7
+ VERSION = [MAJOR, MINOR, BUGFIX].join(".") + (DEV ? ".pre#{DEV}" : '')
8
+ end
@@ -0,0 +1,19 @@
1
+ require 'origen_testers'
2
+ require 'origen'
3
+ require_relative '../config/application.rb'
4
+ module OrigenARM
5
+ # THIS FILE SHOULD ONLY BE USED TO LOAD RUNTIME DEPENDENCIES
6
+ # If this plugin has any development dependencies (e.g. dummy DUT or other models that are only used
7
+ # for testing), then these should be loaded from config/boot.rb
8
+
9
+ # Example of how to explicitly require a file
10
+ # require "origen_arm/my_file"
11
+
12
+ # Load all files in the lib/origen_arm directory.
13
+ # Note that there is no problem from requiring a file twice (Ruby will ignore
14
+ # the second require), so if you have a file that must be required first, then
15
+ # explicitly require it up above and then let this take care of the rest.
16
+ Dir.glob("#{File.dirname(__FILE__)}/origen_arm/**/*.rb").sort.each do |file|
17
+ require file
18
+ end
19
+ end
@@ -0,0 +1,8 @@
1
+ module OrigenARM
2
+ module Cores
3
+ class Base
4
+ def initialize(options = {})
5
+ end
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,8 @@
1
+ module OrigenARM
2
+ module Cores
3
+ class BaseController
4
+ def initialize(options = {})
5
+ end
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,8 @@
1
+ module OrigenARM
2
+ module Cores
3
+ class Base
4
+ module Registers
5
+ end
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,51 @@
1
+ module OrigenARM
2
+ module Cores
3
+ module CortexM
4
+ class Base < OrigenARM::Cores::Base
5
+ require_relative 'cortexm_registers'
6
+
7
+ include Origen::Model
8
+ include Registers
9
+
10
+ attr_reader :enter_debug_mode_delay_cycles
11
+ attr_reader :exit_debug_mode_delay_cycles
12
+ attr_reader :write_debug_register_delay
13
+ attr_reader :read_debug_register_delay
14
+
15
+ # Initialize the CortexM base.
16
+ # @param [Hash] options CortexM Base options.
17
+ # @option options [True, False] :no_init_common_registers Skip initializing common registers entirely.
18
+ # @option options [Fixnum] :enter_debug_mode_delay_cycles
19
+ # Customize the delay (in cycles) to wait for the device to enter debug mode.
20
+ # @option options [Fixnum] :exit_debug_mode_delay_cycles
21
+ # Customize the delay (in cycles) to wait for the device to exit debug mode.
22
+ # @note For the most part, enter/exit debug mode delay cycles should be the same,
23
+ # so the same override will affect both. For these to be truely different,
24
+ # both options must be given.
25
+ def initialize(options = {})
26
+ # Initialize any common registers followed by the core's own registers.
27
+ # Note that the core's #initialize_registers could re-configure or
28
+ # remove any common registers that aren't actually common to that core.
29
+ OrigenARM::Cores::CortexM::Base::Registers.instantiate_registers(self, options) unless options[:no_init_common_registers]
30
+ instantiate_registers(options) if respond_to?(:instantiate_registers)
31
+
32
+ @enter_debug_mode_delay_cycles = options[:enter_debug_mode_delay_cycles] || options[:exit_debug_mode_delay_cycles] || 50
33
+ @exit_debug_mode_delay_cycles = options[:exit_debug_mode_delay_cycles] || options[:enter_debug_mode_delay_cycles] || 50
34
+
35
+ @write_debug_register_delay = options[:write_debug_register_delay] || 1000
36
+ @read_debug_register_delay = options[:read_debug_register_delay] || 1000
37
+
38
+ super
39
+ end
40
+
41
+ # Returns the location of the <code>Registers</code> module.
42
+ # @return [Module]
43
+ # @example Retrieve the register scope of the CM33 core model.
44
+ # dut.cm33_core._registers_scope #=> OrigenARM::Cores::CortexM::CM33::Registers
45
+ def _registers_scope
46
+ eval("#{self.class}::Registers")
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,152 @@
1
+ module OrigenARM
2
+ module Cores
3
+ module CortexM
4
+ class BaseController < OrigenARM::Cores::BaseController
5
+ include Origen::Controller
6
+
7
+ def initialize(options = {})
8
+ super
9
+ end
10
+
11
+ # Delays for the core to to enter debug mode.
12
+ # @note The delay (in cycles) can be set by initializing the core
13
+ # subblock parameter <code>:enter_debug_mode_delay_cycles</code>.
14
+ # @note If the <code>DUT</code> provides the same method, that method
15
+ # will be used in place of this one.
16
+ def enter_debug_mode_delay!
17
+ if dut.respond_to?('enter_debug_mode_delay!'.to_sym)
18
+ cc 'Using DUT-defined #enter_debug_mode_delay! for core to enter debug mode'
19
+ dut.enter_debug_mode_delay!
20
+ else
21
+ cc "Delaying #{enter_debug_mode_delay_cycles} cycles for core to enter debug mode"
22
+ tester.cycle(repeat: enter_debug_mode_delay_cycles)
23
+ end
24
+ end
25
+
26
+ # Delays for the core to to exit debug mode.
27
+ # @note The delay (in cycles) can be set by initializing the core
28
+ # subblock parameter <code>:exit_debug_mode_delay_cycles</code>.
29
+ # @note If the <code>DUT</code> provides the same method, that method
30
+ # will be used in place of this one.
31
+ def exit_debug_mode_delay!
32
+ if dut.respond_to?('exit_debug_mode_delay!'.to_sym)
33
+ cc 'Using DUT-defined #exit_debug_mode_delay! for core to exit debug mode'
34
+ dut.exit_debug_mode_delay!
35
+ else
36
+ cc "Delaying #{exit_debug_mode_delay_cycles} cycles for core to exit debug mode"
37
+ tester.cycle(repeat: exit_debug_mode_delay_cycles)
38
+ end
39
+ end
40
+
41
+ # Runs the given block in debug mode, exiting debug mode upon completion.
42
+ # @param with_core_halted [true, false] Indicates if the core should be halted while executing the given blocck.
43
+ # If true, the core will be released upon debug mode exit.
44
+ # @note This is equivalent to: <br>
45
+ # -> <code>enter_debug_mode(halt_core: with_core_halted)</code> <br>
46
+ # -> <code>...</code> <br>
47
+ # -> <code>exit_debug_mode(release_core: with_core_halted)</code>
48
+ # @example Perform a write/read-expect operation on <code>dut.core(:reg1)</code>
49
+ # dut.core.in_debug_mode do
50
+ # dut.core.reg(:reg7).write!(0x7)
51
+ # dut.core.reg(:reg7).read!(0x7)
52
+ # end
53
+ def in_debug_mode(with_core_halted: false)
54
+ enter_debug_mode(halt_core: with_core_halted)
55
+ yield
56
+ exit_debug_mode(release_core: with_core_halted)
57
+ end
58
+ alias_method :with_debug_mode, :in_debug_mode
59
+ alias_method :with_debug_enabled, :in_debug_mode
60
+
61
+ # Certain registers within the core must be written in certain ways.
62
+ # Override the <code>reg.read!</code> and <code>reg.write!</code> methods to have Origen handle this.
63
+ # @note This doesn't protect from the user copying the register to a different namepace,
64
+ # nor from using the address directly.
65
+ # @note This method will use the toplevel's <code>reg.write!</code>.
66
+ # This is just wraps the write process for certain registers.
67
+ # @see Link: <a href='https://origen-sdk.org/origen/guides/pattern/registers/#Basic_Concept'>Registers Docs</a>
68
+ def write_register(reg, options = {})
69
+ if reg_wrapped_by_dcrsr?(reg)
70
+ # This register write requires a few steps:
71
+ # 1. Write the dcrdr register with the data.
72
+ #
73
+ # 2a. Write the dcrsr[:regwnr] bit to 1 (indicate a write)
74
+ # 2b. Write the regsel bits with the desired register.
75
+ # (The above two take place in a single transaction)
76
+ #
77
+ # Writing the dcrsr will trigger the write to occur. Very important
78
+ # the write to the dcrdr occurs first.
79
+ #
80
+ # This requires a reg_sel lookup.
81
+ pp("Writing Debug Register: #{reg.name} <- #{reg.data.to_hex}") do
82
+ reg(:dcrdr).write!(reg.data)
83
+ reg(:dcrsr).bits(:regwnr).write(1)
84
+ reg(:dcrsr).bits(:reg_sel).write(reg.address)
85
+ reg(:dcrsr).write!
86
+ tester.cycle(repeat: write_debug_register_delay)
87
+ end
88
+ else
89
+ # Nothing special about this registers. Write it as normal.
90
+ parent.write_register(reg, options)
91
+ end
92
+ end
93
+
94
+ # Certain registers within the core must be written in certain ways.
95
+ # Override the <code>reg.read!</code> and <code>reg.write!</code> methods to have Origen handle this.
96
+ # @note This doesn't protect from the user copying the register to a different namepace,
97
+ # nor from using the address directly.
98
+ # @note This method will use the toplevel's <code>reg.read!</code>.
99
+ # This is just wraps the write process for certain registers.
100
+ # @see Link: <a href='https://origen-sdk.org/origen/guides/pattern/registers/#Basic_Concept'>Registers Docs</a>
101
+ def read_register(reg, options = {})
102
+ if reg_wrapped_by_dcrsr?(reg)
103
+ pp("Reading and Comparing Core Register: DCRDR <- #{reg.name}.data (expecting #{reg.data}") do
104
+ core_reg_to_dcrdr(reg, options)
105
+ reg(:dcrdr).read!(reg.data)
106
+ end
107
+ else
108
+ # Nothing special about this registers. Write it as normal.
109
+ parent.read_register(reg, options)
110
+ end
111
+ end
112
+
113
+ # Reads the core register and places its contents in the DCRDR, but does
114
+ # not invoke and tester-level compares.
115
+ # @note This is a shortcut to a <code>reg.read!</code> call that masks all the bits.
116
+ # @todo Implement <code>Raise</code> condition.
117
+ # @raise [OrigenARM::CoreRegisterError] If <code>reg</code> is not a core register.
118
+ # @note See the implementation of #write_register for additional details on the internals.
119
+ # @note All core registers are 32-bits. Any contents in the DCRDR will be overwritten.
120
+ def core_reg_to_dcrdr(reg, options)
121
+ if reg_wrapped_by_dcrsr?(reg)
122
+ pp("Copying Core Register to DCRDR: DCRDR <- #{reg.name}.data") do
123
+ reg(:dcrsr).bits(:regwnr).write(0)
124
+ reg(:dcrsr).bits(:reg_sel).write(reg.address)
125
+ reg(:dcrsr).write!
126
+ tester.cycle(repeat: read_debug_register_delay)
127
+ end
128
+ else
129
+ Origen.app.fail!(
130
+ message: 'Method #core_reg_to_dcrdr can only be run with the core debug registers. ' \
131
+ "Given register #{reg.is_a?(Register) ? reg.name : reg.to_s} is not classified as a core register.",
132
+ exception: OrigenARM::CoreRegisterError
133
+ )
134
+ end
135
+ end
136
+
137
+ # Checks if the register given is either a <code>general_purpose_register</code>, <code>special_purpose_register</code>,
138
+ # or a <code>floating_point_register</code>. <br> <br> Read and writes to these regsters are wrapped around the
139
+ # <code>DHRCR</code> and <code>DHRSR</code> registers.
140
+ # @raise NoRegisterError If <code>reg</code> could not be converted to a register within the selected core.
141
+ # @note Register type indication is done per regster, when adding registers. This method just checks that field.
142
+ def reg_wrapped_by_dcrsr?(reg)
143
+ # If reg isn't an Origen register, convert it to one.
144
+ r = reg.is_a?(Origen::Registers::Reg) ? reg : self.reg(reg)
145
+
146
+ # The register type is a custom field stored in the registers metadata.
147
+ r.meta[:general_purpose_register] || r.meta[:special_purpose_register] || r.meta[:floating_point_register]
148
+ end
149
+ end
150
+ end
151
+ end
152
+ end