Class: OrigenARM::Cores::CortexM::BaseController
- Inherits:
-
BaseController
- Object
- BaseController
- OrigenARM::Cores::CortexM::BaseController
- Includes:
- Origen::Controller
- Defined in:
- lib/origen_arm/cores/cortexm/base_cortexm/cortexm_controller.rb
Direct Known Subclasses
Instance Method Summary collapse
-
#core_reg_to_dcrdr(reg, options) ⇒ Object
Reads the core register and places its contents in the DCRDR, but does not invoke and tester-level compares.
-
#enter_debug_mode_delay! ⇒ Object
Delays for the core to to enter debug mode.
-
#exit_debug_mode_delay! ⇒ Object
Delays for the core to to exit debug mode.
-
#in_debug_mode(with_core_halted: false) ⇒ Object
(also: #with_debug_mode, #with_debug_enabled)
Runs the given block in debug mode, exiting debug mode upon completion.
-
#initialize(options = {}) ⇒ BaseController
constructor
A new instance of BaseController.
-
#read_register(reg, options = {}) ⇒ Object
Certain registers within the core must be written in certain ways.
-
#reg_wrapped_by_dcrsr?(reg) ⇒ Boolean
Checks if the register given is either a
general_purpose_register
,special_purpose_register
, or afloating_point_register
. -
#write_register(reg, options = {}) ⇒ Object
Certain registers within the core must be written in certain ways.
Constructor Details
#initialize(options = {}) ⇒ BaseController
Returns a new instance of BaseController
7 8 9 |
# File 'lib/origen_arm/cores/cortexm/base_cortexm/cortexm_controller.rb', line 7 def initialize(={}) super end |
Instance Method Details
#core_reg_to_dcrdr(reg, options) ⇒ Object
Implement Raise
condition.
This is a shortcut to a reg.read!
call that masks all the
bits.
See the implementation of #write_register for additional details on the internals.
All core registers are 32-bits. Any contents in the DCRDR will be overwritten.
Reads the core register and places its contents in the DCRDR, but does not invoke and tester-level compares.
120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 |
# File 'lib/origen_arm/cores/cortexm/base_cortexm/cortexm_controller.rb', line 120 def core_reg_to_dcrdr(reg, ) if reg_wrapped_by_dcrsr?(reg) pp("Copying Core Register to DCRDR: DCRDR <- #{reg.name}.data") do reg(:dcrsr).bits(:regwnr).write(0) reg(:dcrsr).bits(:reg_sel).write(reg.address) reg(:dcrsr).write! tester.cycle(repeat: read_debug_register_delay) end else Origen.app.fail!( message: "Method #core_reg_to_dcrdr can only be run with the core debug registers. " + \ "Given register #{reg.is_a?(Register) ? reg.name : reg.to_s} is not classified as a core register.", exception: OrigenARM::CoreRegisterError ) end end |
#enter_debug_mode_delay! ⇒ Object
The delay (in cycles) can be set by initializing the core subblock
parameter :enter_debug_mode_delay_cycles
.
If the DUT
provides the same method, that method will be used
in place of this one.
Delays for the core to to enter debug mode.
16 17 18 19 20 21 22 23 24 |
# File 'lib/origen_arm/cores/cortexm/base_cortexm/cortexm_controller.rb', line 16 def enter_debug_mode_delay! if dut.respond_to?('enter_debug_mode_delay!'.to_sym) cc 'Using DUT-defined #enter_debug_mode_delay! for core to enter debug mode' dut.enter_debug_mode_delay! else cc "Delaying #{enter_debug_mode_delay_cycles} cycles for core to enter debug mode" tester.cycle(repeat: enter_debug_mode_delay_cycles) end end |
#exit_debug_mode_delay! ⇒ Object
The delay (in cycles) can be set by initializing the core subblock
parameter :exit_debug_mode_delay_cycles
.
If the DUT
provides the same method, that method will be used
in place of this one.
Delays for the core to to exit debug mode.
31 32 33 34 35 36 37 38 39 |
# File 'lib/origen_arm/cores/cortexm/base_cortexm/cortexm_controller.rb', line 31 def exit_debug_mode_delay! if dut.respond_to?('exit_debug_mode_delay!'.to_sym) cc 'Using DUT-defined #exit_debug_mode_delay! for core to exit debug mode' dut.exit_debug_mode_delay! else cc "Delaying #{exit_debug_mode_delay_cycles} cycles for core to exit debug mode" tester.cycle(repeat: exit_debug_mode_delay_cycles) end end |
#in_debug_mode(with_core_halted: false) ⇒ Object Also known as: with_debug_mode, with_debug_enabled
This is equivalent to:
-> enter_debug_mode(halt_core:
with_core_halted)
-> ...
->
exit_debug_mode(release_core: with_core_halted)
Runs the given block in debug mode, exiting debug mode upon completion.
53 54 55 56 57 |
# File 'lib/origen_arm/cores/cortexm/base_cortexm/cortexm_controller.rb', line 53 def in_debug_mode(with_core_halted: false) enter_debug_mode(halt_core: with_core_halted) yield exit_debug_mode(release_core: with_core_halted) end |
#read_register(reg, options = {}) ⇒ Object
This doesn't protect from the user copying the register to a different namepace, nor from using the address directly.
This method will use the toplevel's reg.read!
. This is
just wraps the write process for certain registers.
Certain registers within the core must be written in certain ways. Override
the reg.read!
and reg.write!
methods to have
Origen handle this.
101 102 103 104 105 106 107 108 109 110 111 |
# File 'lib/origen_arm/cores/cortexm/base_cortexm/cortexm_controller.rb', line 101 def read_register(reg, ={}) if reg_wrapped_by_dcrsr?(reg) pp("Reading and Comparing Core Register: DCRDR <- #{reg.name}.data (expecting #{reg.data}") do core_reg_to_dcrdr(reg, ) reg(:dcrdr).read!(reg.data) end else # Nothing special about this registers. Write it as normal. parent.read_register(reg, ) end end |
#reg_wrapped_by_dcrsr?(reg) ⇒ Boolean
Register type indication is done per regster, when adding registers. This method just checks that field.
Checks if the register given is either a
general_purpose_register
,
special_purpose_register
, or a
floating_point_register
.
Read and writes to these
regsters are wrapped around the DHRCR
and DHRSR
registers.
142 143 144 145 146 147 148 |
# File 'lib/origen_arm/cores/cortexm/base_cortexm/cortexm_controller.rb', line 142 def reg_wrapped_by_dcrsr?(reg) # If reg isn't an Origen register, convert it to one. r = reg.is_a?(Origen::Registers::Reg) ? reg : self.reg(reg) # The register type is a custom field stored in the registers metadata. r.[:general_purpose_register] || r.[:special_purpose_register] || r.[:floating_point_register] end |
#write_register(reg, options = {}) ⇒ Object
This doesn't protect from the user copying the register to a different namepace, nor from using the address directly.
This method will use the toplevel's reg.write!
. This is
just wraps the write process for certain registers.
Certain registers within the core must be written in certain ways. Override
the reg.read!
and reg.write!
methods to have
Origen handle this.
68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 |
# File 'lib/origen_arm/cores/cortexm/base_cortexm/cortexm_controller.rb', line 68 def write_register(reg, ={}) if reg_wrapped_by_dcrsr?(reg) # This register write requires a few steps: # 1. Write the dcrdr register with the data. # # 2a. Write the dcrsr[:regwnr] bit to 1 (indicate a write) # 2b. Write the regsel bits with the desired register. # (The above two take place in a single transaction) # # Writing the dcrsr will trigger the write to occur. Very important # the write to the dcrdr occurs first. # # This requires a reg_sel lookup. pp("Writing Debug Register: #{reg.name} <- #{reg.data.to_hex}") do reg(:dcrdr).write!(reg.data) reg(:dcrsr).bits(:regwnr).write(1) reg(:dcrsr).bits(:reg_sel).write(reg.address) #resolve_regsel(reg)) reg(:dcrsr).write! tester.cycle(repeat: write_debug_register_delay) end else # Nothing special about this registers. Write it as normal. parent.write_register(reg, ) end end |