MCU通过APB总线与FPGA 数据交互(实现JATG 模块的控制)
问题出发点:
通过MCU 的APB 将数据发送到fpga 端;fpga 端实现 jtag 模块功能,支持状态机TAP的移动主要是:从IDLE 移动到 shirft-IR 发送指令数据然后再回到 IDLE ,从 IDLE 移动到shirft-DR 发送用户数据再回到IDLE;从而可以 通过 mcu端实现jtag 协议控制。
为了实现 MCU 通过 APB 总线将数据发送到 FPGA,并由 FPGA 实现 JTAG 模块功能,我们需要设计一个完整的系统来确保数据的正确传输和 JTAG 协议的正确控制。以下是详细的设计方案:
系统架构
MCU (Microcontroller Unit)
通过 APB 总线与 FPGA 进行数据通信。
负责将数据发送到 FPGA 的缓冲区。
控制 JTAG 协议的状态机移动。
FPGA (Field-Programmable Gate Array)
包含一个 APB 接口,用于接收来自 MCU 的数据和控制信号。
包含一个 JTAG 模块,用于实现 JTAG 协议的状态机控制和数据传输。
包含一个 FIFO 缓冲区,用于暂存从 MCU 接收到的数据。
设计步骤
1. MCU 端设计
APB 总线配置
配置 APB 总线的时钟和复位信号。
初始化 APB 总线的控制信号(如 PSEL, PENABLE, PWRITE 等)。
设置 APB 总线的地址映射,确保 MCU 能够正确访问 FPGA 的寄存器。
数据发送
将数据通过 APB 总线写入 FPGA 的 FIFO 缓冲区。
发送控制信号,指示 FPGA 进行 JTAG 状态机的移动。
2. FPGA 端设计
a. APB 接口模块
APB 控制逻辑
实现 APB 总线协议,处理来自 MCU 的读写请求。
解析 APB 总线的地址信号,确定目标寄存器。
管理数据的读写操作,确保数据正确传输到 FIFO 缓冲区。
接收控制信号,控制 JTAG 状态机的移动。
b. FIFO 缓冲区模块
FIFO 结构
使用双端口 RAM 实现 FIFO 缓冲区。
包含读指针和写指针,管理数据的入队和出队操作。
提供状态信号(如空、满、半满等),用于指示 FIFO 的当前状态。
c. JTAG 模块
JTAG 控制逻辑
实现 JTAG 协议的状态机控制。
管理 TCK(Test Clock)、TMS(Test Mode Select)、TDI(Test Data In)、TDO(Test Data Out)信号。
根据控制信号,从 IDLE 状态移动到 SHIFT-IR 或 SHIFT-DR 状态,发送指令或用户数据,再回到 IDLE 状态。
d. 数据流控制
数据传输流程
MCU 通过 APB 总线将数据写入 FPGA 的 FIFO 缓冲区。
MCU 发送控制信号,指示 FPGA 进行 JTAG 状态机的移动。
FPGA 的 JTAG 控制逻辑从 FIFO 缓冲区读取数据,并通过 JTAG 接口发送出去。
使用中断或轮询方式监控 FIFO 的状态,确保数据的及时传输。
详细代码示例
MCU 端代码示例(伪代码)
void send_jtag_command(uint8_t *command, int length) {
// 写入指令数据
for (int i = 0; i < length; i++) {
apb_set_address(FPGA_JTAG_CMD_BASE_ADDRESS);
apb_write_data(command[i]);
// 等待 FIFO 不满
while (apb_read_status() & FIFO_FULL_FLAG);
}
// 发送控制信号,移动到 SHIFT-IR 状态
apb_set_address(FPGA_JTAG_CTRL_BASE_ADDRESS);
apb_write_data(JTAG_CMD_SHIFT_IR);
// 等待 JTAG 状态机移动完成
while (apb_read_status() & JTAG_BUSY_FLAG);
}
void send_jtag_data(uint8_t *data, int length) {
// 写入用户数据
for (int i = 0; i < length; i++) {
apb_set_