Bit Bang JTAG Programming of Xilinx CPLD using FT232 – Homebrew SVF Player

A couple of important states:

0) TEST-LOGIC-RESET (aka RESET).  The all-important reset state.  You have to know how to get back here in case you get lost, or come upon a logic device with a TAP controller in an unknown state.  All programming begins with the RESET state, and a failsafe way to get here is to hold TMS=1 while you clock the device at least 5 times.  This will ensure that you exit out of any state you’re in, as well as that you’ll be trapped in RESET by the TMS=1 loopback.  So clock it 5 times or 5,000 – you’ll be in RESET.

4) SHIFT-DR (aka SHIFTDR).  The state used to load serial data to the device’s data register.  All our programming data goes in here, and all our verification/readback data comes out here.

B) SHIFT-IR (aka SHIFTIR).  The state used to load serial data to the device’s instruction register.  All our commands (erase, program, chip ID) go in here.  Then we go over to SHIFTDR to send or get data.

Well OK!  We’ve got a state diagram, and a somewhat tenuous grasp on how to get from one place to another.  How the hell do we write software to wander around this maze? It’s not too difficult actually.  You will want to implement two arrays:

1) The first is a 16 x 2 array that describes the next state given any present state and whether TMS=1 or 0.  This helps us keep track of where we are, and where we’re going as we go jumping around.

2) The second is a 16 x 16 array that describes what our TMS decision should be given any state, and any desired state.  This one is kind of like that table at the beginning of a road atlas that tells you if you’re in Raleigh NC and need to get to San Fransisco CA, you’ve got 2488 grueling miles ahead of you.  But our table only gives one decision at a time – from Raleigh, turn left.  Check back when you get to Knoxville, TN.  In Knoxville, turn right.  And so on until City = DesiredCity and then stop driving.  Dry and mechanical, but it works quite well in practice.

We’ve named these two arrays nextstate() and route().  Nextstate was generated in-house, but route was cribbed from a very elegant work by Freescale Semiconductor on just this subject.  No freakin clue how they get away without a nextstate array, but more power to them if they can – it’s certainly not described in their article.  Read the very nice document from Freescale describing a pre-determined “shortest path” routine for software wanting to traverse the TAP.  Without further ado, here are the arrays:


nextstate(16,2) – Tell us the TAP’s next state if we know our present state, and what TMS we’re about to give to the machine.

 State  Name            TMS=0   TMS=1
    0x0: Test-logic-reset  1       0
    0x1: Run-test/Idle     1       2
    0x2: Select-DR-scan    3       9
    0x3: Capture-DR        4       5
    0x4: Shift-DR          4       5
    0x5: Exit1-DR          6       8
    0x6: Pause-DR          6       7
    0x7: Exit2-DR          4       8
    0x8: Update-DR         1       2
    0x9: Select-IR-scan    A       0
    0xA: Capture-IR        B       C
    0xB: Shift-IR          B       C
    0xC: Exit1-IR          D       F
    0xD: Pause-IR          D       E
    0xE: Exit2-IR          B       F
    0xF: Update-IR         1       2

route(16, 16) – Given our present and desired state, give us the TMS value that leads us in the shortest path to where we want to be.

----   0 1 2 3  4 5 6 7  8 9 A B  C D E F
       0 1 0 0 0  0 0 0 0  0 0 0 0  0 0 0 0
       1 1 0 1 1  1 1 1 1  1 1 1 1  1 1 1 1
       2 1 1 x 0  0 0 0 0  0 1 1 1  1 1 1 1
       3 1 1 1 x  0 1 1 1  1 1 1 1  1 1 1 1
       4 1 1 1 1  0 1 1 1  1 1 1 1  1 1 1 1
       5 1 1 1 1  0 x 0 0  1 1 1 1  1 1 1 1
       6 1 1 1 1  1 1 0 1  1 1 1 1  1 1 1 1
       7 1 1 1 1  0 0 0 x  1 1 1 1  1 1 1 1
       8 1 0 1 1  1 1 1 1  x 1 1 1  1 1 1 1
       9 1 1 1 1  1 1 1 1  1 x 0 0  0 0 0 0
       A 1 1 1 1  1 1 1 1  1 1 x 0  1 1 1 1
       B 1 1 1 1  1 1 1 1  1 1 1 0  1 1 1 1
       C 1 1 1 1  1 1 1 1  1 1 1 0  x 0 0 1
       D 1 1 1 1  1 1 1 1  1 1 1 1  1 0 1 1
       E 1 1 1 1  1 1 1 1  1 1 1 0  0 0 x 1
       F 1 0 1 1  1 1 1 1  1 1 1 1  1 1 1 x



If you think about it, traversing from one side of the machine to the other may take 5, 6, 7 or more steps and it’s easy to get confused if you try to take them all at once.  The use of the two arrays greatly simplifies it to a very simple routine that consists of one simple step at a time.

while(ourState != desiredState)

{

nextTMS = route(ourState, desiredState);

ClockJTAG(nextTMS);

ourState = nextstate(ourState, nextTMS);

}

Keep looping in this routine, and you are certain to end up in your desired state in the bare minimum number of steps required.  Natch!  Our job, halfway done.  All’s left is to read through the SVF file and dig out the instructions.  For this part you’ll definitely want a copy of the SVF file format white paper from Xilinx to read along with.



This entry was posted in Projects and tagged , , , , , . Bookmark the permalink.

26 Responses to "Bit Bang JTAG Programming of Xilinx CPLD using FT232 – Homebrew SVF Player"

Leave a reply