origen_arm 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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