JTAG的工作原理及相关的代码

什么是JTAG

JTAG是如何工作的?

通过你的PC控制JTAG

并口

#define lpt_addr 0x378
#define TCK 0x01
 
void toggle_TCK()
{
	outport(lpt_addr, 0);
	outport(lpt_addr, TCK);
	outport(lpt_addr, 0);
}

通过JTAG TAP控制器

	// first sync everybody to the test-logic-reset state
	for(i=0; i<5; i++) JTAG_clock(TMS);
 
	// now that everybody is in a known and identical state, we can move together to another state
	// let's go to Shift-IR
	JTAG_clock(0);
	JTAG_clock(TMS);
	JTAG_clock(TMS);
	JTAG_clock(0);
	JTAG_clock(0);
	// Because the bits are shifted through in a chain, we must start sending the data for the device that is at the end of the chain
	// so we send the 10 FPGA IR bits first
	JTAG_clock(0);
	JTAG_clock(1);
	JTAG_clock(0);
	JTAG_clock(0);
	JTAG_clock(0);
	JTAG_clock(0);
	JTAG_clock(0);
	JTAG_clock(0);
	JTAG_clock(0);
	JTAG_clock(0);
 
	// then send the 5 CPU IR bits
	JTAG_clock(0);
	JTAG_clock(0);
	JTAG_clock(1);
	JTAG_clock(0);
	JTAG_clock(0 | TMS);	// last bit needs to have TMS active (to exit shift-IR)
查询JTAG链

统计JTAG链条上的设备数量

  // go to reset state
  for(i=0; i<5; i++) JTAG_clock(TMS);
 
  // go to Shift-IR
  JTAG_clock(0);
  JTAG_clock(TMS);
  JTAG_clock(TMS);
  JTAG_clock(0);
  JTAG_clock(0);
 
  // Send plenty of ones into the IR registers
  // That makes sure all devices are in BYPASS!
  for(i=0; i<999; i++) JTAG_clock(1);
  JTAG_clock(1 | TMS);  // last bit needs to have TMS active, to exit shift-IR
 
  // we are in Exit1-IR, go to Shift-DR
  JTAG_clock(TMS);
  JTAG_clock(TMS);
  JTAG_clock(0);
  JTAG_clock(0);
 
  // Send plenty of zeros into the DR registers to flush them
  for(i=0; i<1000; i++) JTAG_clock(0);
 
  // now send ones until we receive one back
  for(i=0; i<1000; i++) if(JTAG_clock(1)) break;
 
  nbDevices = i;
  printf("There are %d device(s) in the JTAG chain\n", nbDevices);
 
获取JTAG链条上的设备的ID
  // go to reset state (that loads IDCODE into IR of all the devices)
  for(i=0; i<5; i++) JTAG_clock(TMS);
 
  // go to Shift-DR
  JTAG_clock(0);
  JTAG_clock(TMS);
  JTAG_clock(0);
  JTAG_clock(0);
 
  // and read the IDCODES
  for(i=0; i < nbDevices; i++)
  {
    printf("IDCODE for device %d is %08X\n", i+1, JTAG_read(32));
  }
 

执行边界扫描

attribute INSTRUCTION_LENGTH of EP1C3T100 : entity is 10;
 
attribute INSTRUCTION_OPCODE of EP1C3T100 : entity is
  "BYPASS            (1111111111), "&
  "EXTEST            (0000000000), "&
  "SAMPLE            (0000000101), "&
  "IDCODE            (0000000110), "&
  "USERCODE          (0000000111), "&
  "CLAMP             (0000001010), "&
  "HIGHZ             (0000001011), "&
  "CONFIG_IO            (0000001101)";
 
attribute INSTRUCTION_CAPTURE of EP1C3T100 : entity is "0101010101";
 
attribute IDCODE_REGISTER of EP1C3T100 : entity is
  "0000"&               --4-bit Version
  "0010000010000001"&   --16-bit Part Number (hex 2081)
  "00001101110"&        --11-bit Manufacturer's Identity
  "1";                  --Mandatory LSB
 
attribute BOUNDARY_LENGTH of EP1C3T100 : entity is 339;
attribute BOUNDARY_REGISTER of EP1C3T100 : entity is
  --BSC group 0 for I/O pin 100
  "0   (BC_1, IO100, input, X)," &
  "1   (BC_1, *, control, 1)," &
  "2   (BC_1, IO100, output3, X, 1, 1, Z)," &
 
  --BSC group 1 for I/O pin 99
  "3   (BC_1, IO99, input, X)," &
  "4   (BC_1, *, control, 1)," &
  "5   (BC_1, IO99, output3, X, 4, 1, Z)," &
 
  ...
  ...
  ...
 
  --BSC group 112 for I/O pin 1
  "336 (BC_1, IO1, input, X)," &
  "337 (BC_1, *, control, 1)," &
  "338 (BC_1, IO1, output3, X, 337, 1, Z)" ;

<ode verilog>

// go to reset state
for(i=0; i<5; i++) JTAG_clock(TMS);
// go to Shift-IR
JTAG_clock(0);
JTAG_clock(TMS);
JTAG_clock(TMS);
JTAG_clock(0);
JTAG_clock(0);
// Assuming that IR is 10 bits long,
// that there is only one device in the chain,
// and that SAMPLE code = 0000000101b
JTAG_clock(1);
JTAG_clock(0);
JTAG_clock(1);
JTAG_clock(0);
JTAG_clock(0);
JTAG_clock(0);
JTAG_clock(0);
JTAG_clock(0);
JTAG_clock(0);
JTAG_clock(0 or TMS);  // last bit needs to have TMS active, to exit shift-IR
// we are in Exit1-IR, go to Shift-DR
JTAG_clock(TMS);
JTAG_clock(TMS);
JTAG_clock(0);
JTAG_clock(0);
// read the boundary-scan chain bits in an array called BSB
JTAG_read(BSB, 339);
printf("Status of pin 99 = %d\n, BSB[3]);

</code>