module OrigenARMDebug class MemAPController < APController def write_register(reg_or_val, options = {}) if reg_or_val.try(:owner) == model log "Write MEM-AP (#{model.name}) register #{reg_or_val.name.to_s.upcase}: #{reg_or_val.data.to_hex}" do parent.dp.write_register(reg_or_val, options) apreg_access_wait.cycles end else addr = extract_address(reg_or_val, options) data = extract_data(reg_or_val, options) ovl = options.delete(:overlay) unless ovl.nil? Origen.log.warn '[ARM Debug] Overlays only supported through register model' end log "Write MEM-AP (#{model.name}) address #{addr.to_hex}: #{data.to_hex}" do csw.bits(:size).write!(0b010) if csw.bits(:size).data != 0b010 tar.write!(addr) unless tar.data == addr drw.reset drw.overlay(nil) drw.copy_all(reg_or_val) drw.write!(options) latency.cycles end increment_addr end end def read_register(reg_or_val, options = {}) if reg_or_val.try(:owner) == model apacc_wait_states = reg_or_val.name == :drw ? (apmem_access_wait + apreg_access_wait) : apreg_access_wait log "Read MEM-AP (#{model.name}) register #{reg_or_val.name.to_s.upcase}: #{Origen::Utility.read_hex(reg_or_val)}" do parent.dp.read_register(reg_or_val, options.merge(apacc_wait_states: apacc_wait_states)) end else addr = extract_address(reg_or_val, options) log "Read MEM-AP (#{model.name}) address #{addr.to_hex}: #{Origen::Utility.read_hex(reg_or_val)}" do csw.bits(:size).write!(0b010) if csw.bits(:size).data != 0b010 unless tar.data == addr tar.write!(addr) end drw.reset drw.overlay(nil) drw.copy_all(reg_or_val) parent.dp.read_register(drw, options.merge(apacc_wait_states: (apmem_access_wait + apreg_access_wait))) end increment_addr end reg_or_val.clear_flags if reg_or_val.respond_to?(:clear_flags) end def address_increment_enabled? d = csw.addr_inc.data d == 1 || d == 2 end private # Update the model if the address is auto-incrementing on chip def increment_addr if address_increment_enabled? case csw.bits(:size).data when 0 then tar.data += 1 # Increment single when 1 then tar.data += 2 # Increment single when 2 then tar.data += 4 # Increment single end elsif csw.addr_inc.data == 2 tar.data += 4 # Increment packed end # Reset tar if just crossed a 1kB boundary if address_increment_enabled? && (tar[9..0].data == 0) tar.write(0) end end end end