当前位置: 首页 > ai >正文

集成电路流片随笔17:jtag子模块1

JTAG 驱动模块(jtag_driver),它用于实现 JTAG 接口协议,控制 JTAG 状态机的操作,并处理与调试模块(DM)的交互。通过该模块,JTAG 接口可以完成数据传输、调试和控制等任务。

模块输入输出

输入信号:
  • rst_n:复位信号,低电平有效。用于将模块恢复到初始状态。
  • jtag_TCK:JTAG 时钟信号。用于同步 JTAG 数据传输。
  • jtag_TDI:JTAG 数据输入信号,数据从外部传入设备。
  • jtag_TMS:JTAG 模式选择信号,控制 JTAG 状态机的状态转移。
  • dm_resp_i:来自调试模块(DM)的响应信号。表示调试模块已经发送了数据。
  • dm_resp_data_i:来自 DM 的响应数据。
  • dm_ack_i:来自 DM 的确认信号,表示 DM 已经准备好响应数据。
输出信号:
  • jtag_TDO:JTAG 数据输出信号,设备将数据发送到外部调试设备。
  • dtm_ack_o:调试传输模块(DTM)的确认信号。表示从设备接收到数据请求并已准备好响应。
  • dtm_req_valid_o:DTM 请求信号,表示是否有有效的请求需要处理。
  • dtm_req_data_o:DTM 请求的数据。包含目标寄存器、数据或操作等信息。
  • reg_we_o:寄存器写使能信号,表示是否进行寄存器写操作。
  • reg_addr_o:寄存器地址,指示要访问的寄存器。
  • reg_wdata_o:写入寄存器的数据。
  • mem_we_o:内存写使能信号,表示是否进行内存写操作。
  • mem_addr_o:内存地址,指示要访问的内存位置。
  • mem_wdata_o:写入内存的数据。
  • op_req_o:操作请求信号,表示设备要求执行操作。

JTAG 状态机(JTAG State Machine)

JTAG 使用状态机(State Machine)来控制数据的传输和命令的执行。状态机的状态由 TMS(Test Mode Select) 信号控制。

主要状态:
parameter TEST_LOGIC_RESET  = 4'h0;
parameter RUN_TEST_IDLE     = 4'h1;
parameter SELECT_DR         = 4'h2;
parameter CAPTURE_DR        = 4'h3;
parameter SHIFT_DR          = 4'h4;
parameter EXIT1_DR          = 4'h5;
parameter PAUSE_DR          = 4'h6;
parameter EXIT2_DR          = 4'h7;
parameter UPDATE_DR         = 4'h8;
parameter SELECT_IR         = 4'h9;
parameter CAPTURE_IR        = 4'hA;
parameter SHIFT_IR          = 4'hB;
parameter EXIT1_IR          = 4'hC;
parameter PAUSE_IR          = 4'hD;
parameter EXIT2_IR          = 4'hE;
parameter UPDATE_IR         = 4'hF;

这段代码定义了 JTAG 状态机的所有状态。TMS 信号用于在不同的状态之间进行切换。常见的状态有:

  • TEST_LOGIC_RESET:设备复位状态。
  • RUN_TEST_IDLE:空闲状态。
  • SELECT_DR:选择数据寄存器进行数据传输。
  • CAPTURE_DR:捕获数据寄存器的内容。
  • SHIFT_DR:移位操作,将数据移入数据寄存器或输出。
  • UPDATE_DR:更新数据寄存器的状态。

这些状态通过 TMS 信号的变化来控制,确保 JTAG 操作按照协议顺序进行。


数据传输和寄存器操作

CAPTURE_DRSHIFT_DR 状态下,JTAG 会根据 TDI(Test Data Input)TDO(Test Data Output) 信号来完成数据的传输。

这段代码实现了 JTAG 接口中的 IR(Instruction Register)DR(Data Register) 的移位操作。JTAG 设备通过 TDI(Test Data Input)TDO(Test Data Output) 进行数据传输,其中,IR 用于传输指令,而 DR 用于传输数据。

代码解析

代码基于 JTAG 状态机 的状态变化,通过移位寄存器(shift_reg)来执行 IR 和 DR 的数据移位。移位过程发生在 JTAG 时钟信号 TCK 的上升沿。

1. IR 移位 (CAPTURE_IRSHIFT_IR 状态)
// IR
CAPTURE_IR: shift_reg <= {{(SHIFT_REG_BITS - 1){1'b0}}, 1'b1}; // JTAG spec says it must be b01
SHIFT_IR  : shift_reg <= {{(SHIFT_REG_BITS - IR_BITS){1'b0}}, jtag_TDI, shift_reg[IR_BITS - 1:1]}; // right shift 1 bit
  • CAPTURE_IR
    CAPTURE_IR 状态下,JTAG 会捕获指令寄存器(IR)的数据,并将其存入移位寄存器 shift_reg 中。根据 JTAG 协议,IR 的初始值应为 1'b1,并且其它位应填充为 0,所以使用 { {(SHIFT_REG_BITS - 1){1'b0}}, 1'b1 }

  • SHIFT_IR
    SHIFT_IR 状态下,JTAG 从 TDI 信号中读取数据并将其右移一个位置,保留原有的 shift_reg 内容。shift_reg 中的数据会从最低位(TDI)开始移位,直到完成传输。这时 TDI 输入的数据会填充 shift_reg 的最低位,剩下的数据将向右移动。

2. DR 移位 (CAPTURE_DRSHIFT_DR 状态)
// DR
CAPTURE_DR: case (ir_reg) REG_BYPASS     : shift_reg <= {(SHIFT_REG_BITS){1'b0}}; // No dataREG_IDCODE     : shift_reg <= {{(SHIFT_REG_BITS - DMI_DATA_BITS){1'b0}}, idcode}; // ID codeREG_DTMCS      : shift_reg <= {{(SHIFT_REG_BITS - DMI_DATA_BITS){1'b0}}, dtmcs}; // DTM control and statusREG_DMI        : shift_reg <=  is_busy ? busy_response : none_busy_response; // DMI datadefault:shift_reg <= {(SHIFT_REG_BITS){1'b0}}; // Default caseendcase
SHIFT_DR  : case (ir_reg) REG_BYPASS     : shift_reg <= {{(SHIFT_REG_BITS - 1){1'b0}}, jtag_TDI}; // Bypass, just pass dataREG_IDCODE     : shift_reg <= {{(SHIFT_REG_BITS - DMI_DATA_BITS){1'b0}}, jtag_TDI, shift_reg[31:1]}; // right shift 1 bitREG_DTMCS      : shift_reg <= {{(SHIFT_REG_BITS - DMI_DATA_BITS){1'b0}}, jtag_TDI, shift_reg[31:1]}; // right shift 1 bitREG_DMI        : shift_reg <= {jtag_TDI, shift_reg[SHIFT_REG_BITS - 1:1]}; // right shift 1 bitdefault:shift_reg <= {{(SHIFT_REG_BITS - 1){1'b0}} , jtag_TDI}; // Default caseendcase 
  • CAPTURE_DR
    CAPTURE_DR 状态下,根据指令寄存器(ir_reg)的值选择不同的操作:

    • REG_BYPASS:不进行任何数据传输,移位寄存器 shift_reg 直接置零。
    • REG_IDCODE:将 ID 代码加载到移位寄存器 shift_reg 中。ID 代码是设备的唯一标识。
    • REG_DTMCS:加载调试传输模块(DTM)控制和状态信息。
    • REG_DMI:加载 DMI 数据,具体取决于是否忙碌(is_busy)。如果忙碌,则加载忙碌响应 busy_response,否则加载正常响应 none_busy_response
  • SHIFT_DR
    SHIFT_DR 状态下,移位寄存器中的数据向右移动,并根据指令寄存器(ir_reg)的值执行相应的操作:

    • REG_BYPASS:直接将 TDI 数据传递到 shift_reg 中,不改变其它数据。
    • REG_IDCODEREG_DTMCSREG_DMI:将 TDI 数据移入寄存器并右移一位,保留其余部分的值。

通过这种方式,JTAG 可以通过 TDITDO 在目标设备与调试主机之间传递数据。移位操作通过 TCK(JTAG 时钟)同步进行,以确保数据按顺序传输。


DTM 请求和响应

DTM Debug Transport Module 是 JTAG 调试协议中的一个模块,负责数据传输和调试操作。它通常包含在 JTAG 控制器中,允许通过 JTAG 接口进行调试和设备控制。

  • 功能:DTM 的主要作用是向调试目标设备(如 CPU)发送命令,并接收目标设备的响应。它负责处理与设备间的数据传输和调试命令的交互。

  • 如何工作

    • 请求:调试主机通过 JTAG 向 DTM 发送请求,要求执行某个操作或读取某个寄存器的数据。
    • 响应:DTM 处理请求并返回响应数据。如果操作失败或 DTM 无法处理请求,它会返回一个错误响应。

代码解释

涉及到的几个主要部分有 DTM 请求DTM 重置接收 DM 响应数据TX 忙碌状态

1. 开始访问 DM 模块 (start access DM module)

always @(posedge jtag_TCK or negedge rst_n) beginif (!rst_n) begindtm_req_valid <= `DTM_REQ_INVALID;dtm_req_data <= {DTM_REQ_BITS{1'b0}};end else beginif (jtag_state == UPDATE_DR) beginif (ir_reg == REG_DMI) begin// if DM can be accessedif (!is_busy & tx_idle) begindtm_req_valid <= `DTM_REQ_VALID;dtm_req_data <= shift_reg;endendend else begindtm_req_valid <= `DTM_REQ_INVALID;endend
end
  • DTM 请求有效信号 (dtm_req_valid):该信号表明 DTM 请求是否有效。如果为 1,表示可以发送请求。
  • DTM 请求数据 (dtm_req_data):该信号保存发送给 DM 模块的数据。

工作原理

  • 这个过程在每个时钟周期检查是否可以发送 DTM 请求。在 UPDATE_DR 状态下,如果当前指令寄存器(ir_reg)为 REG_DMI(表示数据模块接口),且当前 DTM 模块未忙碌 (!is_busy),并且传输空闲 (tx_idle),则会将请求设置为有效,并将移位寄存器中的数据(shift_reg)作为请求数据。
  • 如果当前不符合条件,则将 dtm_req_valid 设置为无效 (DTM_REQ_INVALID)。

2. DTM 重置 (DTM reset)

always @(posedge jtag_TCK or negedge rst_n) beginif (!rst_n) beginsticky_busy <= 1'b0;end else beginif (jtag_state == UPDATE_DR) beginif (ir_reg == REG_DTMCS & dtm_reset) beginsticky_busy <= 1'b0;endend else if (jtag_state == CAPTURE_DR) beginif (ir_reg == REG_DMI) beginsticky_busy <= is_busy;endendend
end
  • sticky_busy:这个寄存器用于存储 DTM 的忙碌状态。

工作原理

  • UPDATE_DR 状态下,如果当前指令寄存器是 REG_DTMCS(表示 DTM 控制和状态寄存器)并且要求重置(dtm_reset)时,将 sticky_busy 设置为 0,表示重置 DTM 的忙碌状态。
  • CAPTURE_DR 状态下,如果当前指令寄存器是 REG_DMI(数据模块接口寄存器),则将 sticky_busy 设置为当前 DTM 的忙碌状态(is_busy)。is_busy 表示 DTM 是否正在忙碌。

3. 接收 DM 响应数据 (receive DM response data)

always @(posedge jtag_TCK or negedge rst_n) beginif (!rst_n) begindm_resp_data <= {DM_RESP_BITS{1'b0}};end else beginif (rx_valid) begindm_resp_data <= rx_data;endend
end
  • dm_resp_data:该寄存器用于存储从 DM 模块接收到的数据。

工作原理

  • 每次接收到有效的 rx_valid 信号时,就会将接收到的数据 rx_data 存入 dm_resp_data

4. TX 忙碌状态 (TX busy)

always @(posedge jtag_TCK or negedge rst_n) beginif (!rst_n) begindm_is_busy <= 1'b0;end else beginif (dtm_req_valid) begindm_is_busy <= 1'b1;end else if (rx_valid) begindm_is_busy <= 1'b0;endend
end
  • dm_is_busy:该寄存器用于指示 DTM 是否处于忙碌状态。

工作原理

  • dtm_req_valid 为有效时,表示正在向 DTM 模块发送请求,所以将 dm_is_busy 设置为 1,表示 DTM 正在忙碌。
  • 如果 rx_valid 为有效(接收到响应数据),则表示 DTM 的请求已处理完毕,设置 dm_is_busy0,表示 DTM 不再忙碌。

TAP(Test Access Port)复位、TDO 输出、以及数据的全双工传输(通过 full_handshake_txfull_handshake_rx 模块)

1. TAP reset

always @(negedge jtag_TCK) beginif (jtag_state == TEST_LOGIC_RESET) beginir_reg <= REG_IDCODE;end else if (jtag_state == UPDATE_IR) beginir_reg <= shift_reg[IR_BITS - 1:0];end
end
  • jtag_TCK:JTAG 时钟信号。
  • ir_reg:指令寄存器(Instruction Register),它用于保存当前指令的状态。

工作原理

  • 在 JTAG 时钟的负边沿(negedge jtag_TCK)时,这段代码会根据当前状态 (jtag_state) 来更新指令寄存器 ir_reg
    • 如果当前状态是 TEST_LOGIC_RESET,表示 JTAG 正在复位,此时将 ir_reg 设置为 REG_IDCODE,表示指令寄存器指向 IDCODE 寄存器。
    • 如果当前状态是 UPDATE_IR,表示要更新指令寄存器的内容,此时将 ir_reg 设置为移位寄存器 shift_reg 的低位(shift_reg[IR_BITS - 1:0])。这将移位寄存器的当前值加载到指令寄存器中。

2. TDO output

always @(negedge jtag_TCK) beginif (jtag_state == SHIFT_IR) beginjtag_TDO <= shift_reg[0];end else if (jtag_state == SHIFT_DR) beginjtag_TDO <= shift_reg[0];end else beginjtag_TDO <= 1'b0;end
end
  • jtag_TDO:JTAG 数据输出信号(Test Data Out)。

工作原理

  • 在 JTAG 时钟的负边沿(negedge jtag_TCK)时,这段代码根据当前的 JTAG 状态来设置输出信号 jtag_TDO
    • 如果当前状态是 SHIFT_IR,表示正在移位指令寄存器(IR),此时将 jtag_TDO 设置为移位寄存器 shift_reg 的最低位 shift_reg[0]
    • 如果当前状态是 SHIFT_DR,表示正在移位数据寄存器(DR),同样将 jtag_TDO 设置为移位寄存器 shift_reg 的最低位。
    • 否则,即不在移位状态下,jtag_TDO 设置为 0

3. 全双工传输模块 (full_handshake_tx)

full_handshake_tx #(.DW(DTM_REQ_BITS)
) tx(.clk(jtag_TCK),.rst_n(rst_n),.ack_i(dm_ack_i),.req_i(tx_valid),.req_data_i(tx_data),.idle_o(tx_idle),.req_o(dtm_req_valid_o),.req_data_o(dtm_req_data_o)
);
  • full_handshake_tx:这是一个全双工传输模块,用于发送数据(请求)到 DM(调试模块)。
  • tx_valid:发送请求有效信号,表示数据请求是否有效。
  • tx_data:发送的数据。
  • dtm_req_valid_o:DTM 请求有效信号,表示是否可以发送请求。
  • dtm_req_data_o:DTM 请求数据,将 tx_data 转发给 DTM 模块。

工作原理

  • full_handshake_tx 模块通过握手信号完成数据的发送。
    • 通过 ack_i(DM 模块的应答信号)来判断是否可以发送新的数据。
    • tx_valid1 时,表示可以发送数据,tx_data 存储需要发送的数据。
    • full_handshake_tx 模块中,dtm_req_valid_odtm_req_data_o 表示将数据发送到 DTM 模块。

4. 全双工接收模块 (full_handshake_rx)

full_handshake_rx #(.DW(DM_RESP_BITS)
) rx(.clk(jtag_TCK),.rst_n(rst_n),.req_i(dm_resp_i),.req_data_i(dm_resp_data_i),.ack_o(dtm_ack_o),.recv_data_o(rx_data),.recv_rdy_o(rx_valid)
);
  • full_handshake_rx:这是一个全双工接收模块,用于从 DM 模块接收响应数据。
  • dm_resp_i:DM 响应请求输入信号,表示 DM 是否发送了响应。
  • dm_resp_data_i:从 DM 模块接收的数据。
  • dtm_ack_o:DTM 应答信号,表示是否接受数据。
  • rx_data:接收到的数据。
  • rx_valid:接收数据有效信号,表示接收到有效数据。

工作原理

  • full_handshake_rx 模块通过握手信号来接收数据。
    • 通过 dm_resp_i(DM 模块的响应信号)来判断是否可以接收数据。
    • dm_resp_data_i 保存接收到的 DM 响应数据,并通过 rx_valid 告知数据是否有效。

http://www.xdnf.cn/news/966.html

相关文章:

  • 朴素贝叶斯(Naive Bayes)
  • 创建kaggle实现微调(kaggle创建)
  • 系分论文《论数据中台建设的分析和应用》
  • 每天五分钟机器学习:凸优化
  • 【MQ篇】初识MQ!
  • 使用Cloudflare加速网站的具体操作步骤
  • 进程和线程(1)
  • HyperDefect-YOLO:基于超图计算的工业缺陷检测算法解析
  • 关于综合能源服务认证证书的全解析专业认证团队
  • 小迪安全-112-yii反序列化链,某达oa,某商场,影响分析
  • MMIO、IOMAP 和 IOMMU 总结
  • 【Easylive】使用Seata解决分布式事务问题
  • Android 中实现 GIF 图片动画
  • three.js中的instancedMesh类优化渲染多个同网格材质的模型
  • 《AI大模型应知应会100篇》第31篇:大模型重塑教育:从智能助教到学习革命的实践探索
  • 【大数据、数据开发与数据分析面试题汇总(含答案)】
  • langchain +ollama +chroma+embedding模型实现RAG入门级Demo(python版)
  • 量化交易 - RSRS(阻力支撑相对强度)- 正确用法 - 年均收益18%
  • EMQX安装使用和客户端认证
  • Kubernetes 节点摘除指南
  • LintCode第107题-单词拆分
  • 全排列问题cpp
  • Discuz论坛网站忘记管理员密码进不去管理中心怎么办?怎么改管理员密码?
  • stc32单片机实现串口2M波特率满带宽传输
  • C#接口开发异常:System.Web.HttpRequestValidationException
  • Linux421用户、组
  • qt画一朵花
  • ​001-内网穿透工具
  • 20250421在荣品的PRO-RK3566开发板的Android13下使用io命令控制GPIO
  • ArcGIS、ArcMap查看.shp文件时属性表中文乱码