CDL Modules
|
JTAG tap client to APB master module. More...
JTAG tap client to APB master module.
Copyright (C) 2018, Gavin J Stark. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
CDL implementation of a module that, with jtag_tap, forms an APB bus master that is driven by a JTAG interface.
It is based on the RISC-V DTM JTAG interface module, in that it supports a 5-bit IR (that is specified in the build of jtag_tap) and an IDCODE register accessed with IR=1; a control/status register accessed with IR=0x10, and an access register accessed with IR=0x11.
The IDCODE register is 32-bits long (as required by the JTAG standard) and must have the bottom bit set; it is defined as a constant, so a build of this module can override that to provide the desired IDCODE value for the JTAG TAP.
The 32-bit CONTROL register (at IR=0x10) returns, on reads, an op_status in bits [2;10], an abits of 16 in 6;4 and a version of 1 in [4;0] The op_status is a sticky status; it is sticky at 2 if an APB access is attempted while a previous access is being performed. This can be cleared with a write of 0x10000 to the CONTROL register.
Currently the CONTROL register does not support a hard reset of the DTM; it is not clear that this makes sense in an APB access.
The 50-bit ACCESS register (at IR=0x11) is used to perform APB read and writes; it is a 50-bit register (16-bit address, 32-bit data, 2-bit access type) register.
If the access type is 0 then no access is requested; this is used when a JTAG readback is to be used to return a previous APB read's data.
If the access type is 1 then a read access is requested; the top 16 bits of the JTAG data shifted in are the address to be accessed; the next 32 bits are ignored; the access is 1. An APB read access is requested through synchronization registers between the JTAG clock and the APB clock. The APB transaction completes and the data returned is captured and stored ready to be returned in future 'capture's of the ACCESS register.
If the access type is 2 then a write access is requested; the top 16 bits of the JTAG data shifted in are the address to be accessed; the next 32 bits are used as the write data; the access is 2. An APB write access is requested through synchronization registers between the JTAG clock and the APB clock.
If the ACCESS register is read then the bottom 2 bits returned are the op_status - this is 3 if any previous APB access was interrupted and therefore did not complete (read or write) successfully, otherwise it is 0; the next 32 bits are the last APB data read, and the top 16 bits are the last APB address accessed.
The normal usage for writes is to JTAG-shift in address(16)/data(32)/2(2) to the ACCESS register. The APB access will complete before any other JTAG operation can cause problems, so these writes can be performed back-to-back.
The normal usage for reads is to JTAG-shift in address(16)/data(32)/1(2) to the ACCESS register; then a further JTAG-shift of the ACCESS register permits the APB read data to be captured and shifted out. The APB access will take time to complete, and it is possible (with a fast JTAG TCK compared to APB clock) to JTAG-shift to CAPTURE the ACCESS register complete before the APB access returns its data; if this happens then the CAPTURE (read) of the ACCESS register will have an op_status of 3 (and this is sticky - it needs a write of 0x10000 to CONTROL to clear it). So the correct modus operandi is to start the APB read, hang in idle for a few cycles, then capture the APB response. The request and data have to be cacptured, and there are 2 registers for synchonization in each direction, and there are three clock crossings in each direction for an APB read, hence at least 7 cycles are required between Update and Capture, and it is wise to therefore stay in JTAG IDLE for 7 ticks.
Data Structures | |
struct | jtag_apb::t_jtag_state |
struct | jtag_apb::t_apb_state |
Namespaces | |
jtag_apb | |
Typedefs | |
typedef bit[3] | jtag_apb::t_sync |
Enumerations | |
enum | jtag_apb::t_update_action { jtag_apb::action_none, jtag_apb::action_reset, jtag_apb::action_start_read, jtag_apb::action_start_write } |
enum | jtag_apb::t_jtag_addr { jtag_apb::jtag_addr_idcode = 1, jtag_apb::jtag_addr_apb_control = 0x10, jtag_apb::jtag_addr_apb_access = 0x11 } |
Variables | |
constant bit[32] | jtag_apb::jtag_idcode =0xabcde6e3 |