What's new

JTAG

Fluffy

Champion
Joined
Dec 15, 2018
Messages
1,037
Reaction score
1,974
Location
Germany
I want to use ATF150x CPLDs to make progress on a handful of projects. They seem to be the last 5V compatible CPLD available, and they are available in PLCC packaging that works with through-hole sockets.
The official dev board costs a silly amount of money ( https://eu.mouser.com/ProductDetail/Microchip-Technology/ATF15XX-DK3-U?qs=AcLemrdGTbJem%2BPKCCMKBg== ) though there are a few good options on GitHub:
https://github.com/whitequark/ATF15xx-EVB
https://github.com/adrienkohlbecker/atf1504_plcc44_breakout
https://github.com/roscopeco/ATF150x-Programming-Board

I ordered the last option and assembled it so far that I can try out JTAG programming. The first experiments with one of those cheap Altera USB-Blaster adapters were disappointing. I tried Urjtag and the Programmer included in Quartus Web Edition. Quartus was reporting an unknown device with a wrong ID code, urjtag was detecting nothing. Using the "idcode" command showed that the whole value was off by one bit shifted to the left...
Based on buffi's recommendation I ordered a Tigard board which seems to work fine in urjtag.

Next steps are to generate SVF files from CUPL and Quartus and see if I can program them. (And maybe reverse-engineer the command stream in the SVF file so I can generate it directly instead of going through ATMISP..) Also, now that I know that the programming board works I'll have to see if I can get pico-DirtyJTAG to work to bring the costs down if I release something that people want to build.


Edit:
UsbBlaster (Bad):
Code:
jtag> detect
jtag> idcode
Reading 0 bytes of idcode
Read 01111111(0x7f) 01000000(0x40) 10100000(0xa0) 00000001(0x01) 00000000(0x00) 00000000(0x00) 00000000(0x00) 00000000(0x00)
Tigard (Good):
Code:
jtag> detect
IR length: 10
Chain length: 1
Device Id: 00000001010100000010000000111111 (0x0150203F)
  Filename:     e:/fpga/bsdl/1502AS_A44.bsd
jtag> idcode
Reading 0 bytes of idcode
Read 00111111(0x3f) 00100000(0x20) 01010000(0x50) 00000001(0x01) 00000000(0x00) 00000000(0x00) 00000000(0x00) 00000000(0x00)
 
Last edited:
I used ATF1504's in my https://github.com/jwestfall69/neogeo-diag-mvs-cha project as a replacement for the NEO-ZMC. If you scroll 2/3 the way down the page there are details/example on how I programmed them. I had some of same issues with costs originally, but eventually found using a cheap FT232H + openocd + SVF file worked well. One additional benefit with this method is the FT232H can power the ATF150x chip while programming. I also used this same setup for programming the FPGA's on the neogeo 161in1 boards.
 
That is a similar reason why I plan to use pico-JTAG. While it is somewhat overkill just to use for JTAG, it can then be used to test the design, and it provides +5V from USB.
 
These type of things is why I ended up getting a fancy device programmer...
I've programmed other CPLDs (EPM7032) with same packages as ATF150x and my Elnec Beeprog 2C support them natively (... with the expensive adapter)

It's possible to get cheap setups going for programming stuff like this, but having something that feels professional and just works reliably without any hassle is extremely fucking nice.
 
USB Blaster can not power the CPLD/FPGA that's being programmed - this is why it fails for many people that try to use it. I own a real Altera USB Blaster and a clone and the only difference I found was the real blaster is able to validate some devices, while clone can not after programming (e.g. OSSC)

In recent years, I switched to using a Raspberry Pi with OpenOCD for most of my programming. The only gotcha is that you'll need to build the programming software from source. What ships with distro most times is broken on the Pi (xc3sprog is also broken from distro)
 
Neither the UsbBlaster or the Tigard adapter power the board, and the breakout board doesn't have power on the JTAG connector. It does have a power connection "VTGT" that goes from the board to the adapter, and is used as reference voltage for the level shifter. I.e. if a board runs at 3.3V then JTAG does as well.
I guess it depends on the design of your board if it can safely be powered through JTAG, or if you want to power it from its main power connector. If you want to program just the chip in a breakout board it makes sense to provide power from the adapter, if you have it already in a fully populated board you may want to make sure everything is powered on correctly.

By the way, one of the arcade replacement part shops had some spring-loaded pin headers you could snap into a board without soldering them in, so you can remove and reuse them when you're finished with something. I don't remember which store it was, though... Does anyone know what this could've been?
 
Last edited:
My first test is with WinCUPL, with a trivial test program:
Code:
Name     Test ;
PartNo   00 ;
Date     10.09.2024 ;
Revision 01 ;
Designer Engineer ;
Company  Nothing ;
Assembly None ;
Location  ;
Device   f1502ispplcc44;

/* *************** INPUT PINS *********************/
PIN    8 = A; /*                                 */
PIN    9 = B; /*                                 */
PIN    39 = O; /*                                 */

O = A $ B; /* A xor B */
Note: Device is f1502ispplcc44, this leaves the JTAG pins enabled after programming. f1502plcc44 (without isp) gives you access to the extra pins, but you need to put 12V to the Vpp pin to re-enable JTAG access.

WinCUPL produces a .jed file which contains the fuse map. The next step is to configure the JTAG chain that describes which devices are connected to the JTAG port and in which order:
1728072515581.png

This is a trivial chain of just one device, but you could program multiple (different) devices as well, including running some tests to make sure your board is working correctly. With a supported cable ATIMSP could program the connected devices directly, but I have to add an extra step to write a "SVF" file. This is a text file containing the operations that a JTAG adapter has to send. This file is written when pressing the "RUN" button.

To successfully program the ATF1502 I needed to download the "BSDL" file - nothing kinky, just a VHDL file describing the JTAG interface of the device. They are available on Microchips website.

With my Tigard adapter connected and the test board powered I can play back the generated SVF file with UrJTAG:
Code:
jtag> cable ft2232 vid=0x403 pid=0x6010 interface=1
Connected to libftd2xx driver.
jtag> frequency 100000
Setting TCK frequency to 100000 Hz
jtag> bsdl path e:/FPGA/bsdl
jtag> detect
IR length: 10
Chain length: 1
Device Id: 00000001010100000010000000111111 (0x0150203F)
  Filename:     e:/FPGA/bsdl/1502AS_A44.bsd

jtag> svf test_atmisp.svf progress
warning: unimplemented mode 'ABSENT' for TRST
detail: Parsing   3660/3668 ( 99%)detail:
detail: Scanned device output matched expected TDO values.

PXL_20241004_210947903.MP.jpg

Well, you have to take my word for it that it works...

Interesting notes:
- even though the Tigard board is not supported by ATMISP it still broke SVF writing, writing 0 length files. So I had to disconnect the Tigard board to write updated SVF files.
- setting the clock speed is important, I forgot this in one experiment and got mismatches with the expected return values.

"Doh!" note:
- notice how the black line on the breadboard goes from left to right, while the red line is interrupted in the middle? Yeah, took my a while to figure out why the buttons didn't seem to do anything...

Anyway, onward to Quartus tomorrow.
 
Last edited:
Second Test with VHDL, I am using "Intel® Quartus® II Web Edition Design Software Version 13.0sp1 for Windows". which is the last version supporting the MAX7000 devices (which are similar to the ATF150x devices):

Quartus supports VHDL, Verilog and a schematic editor. I used Pascal for a long time so VHDL looked most appealing to me. I expect the synthesis/fitting back-end is the same for all three options, so it depends only on someone's preference what to use.

This implements a simple latch that can be set and reset with the two buttons:
Code:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity ATF1502_Test_Vhdl is

    port
    (
        a : in std_logic;
        b : in std_logic;
        o : out std_logic
    );

end entity;

architecture rtl of ATF1502_Test_Vhdl is
    signal latch : std_logic;
begin

    process(a, b)
    begin
        if (a = '0') then
            latch <= '1';
        elsif (b = '0') then
            latch <= '0';
        end if;
    end process;
  
    o <= latch;
  
end rtl;
Target device is EPM7032SLC44-10, which is an equivalent to the ATF1502 I've got in the test jig. Quartus produces a "pof" file, which is similar to a "jed" file, just binary.
Microchip produces a tool called POF2JED, which converts a pof into a jed, and massages the differences between devices:

1729790122966.png


The "jed" file can be used to produce an "svf" with ATMISP, similar to what I do above (remembering to disconnect the tigard adapter...) and programmed with UrJTAG. Works fine.

(I could embed the same image as above, it would look the same...)

The last option is ProChip designer, but I evaluated that a few years ago with a trial license, and didn't think the quality/functionality justified the licensing cost. Especially since I'd at most do 1-2 designs a year.
 
Last edited:
Unfortunately no parallel port on anything I have set up right now... I'll see if I can automate the pof and svf steps, because UrJTAG works fine otherwise.
 
oh man, I would love a friendly "newish" replacement for WinCUPL... constant crashes and all kinds or randomness that software has.. jeez been giving me grey hairs!
 
The biggest problem I can see is that the internals for ATF150x are not documented, so a lot of work would have to be spent decoding the fusemap. The datasheet gives some indication what functional units are there, and I guess once you've got 1502 you can expand that to 1504 and 1508. But then you'd have to write a fitter.
Though I think the fitter included in WinCUPL and ProChip has a relatively simple input format, so that would be an option...
 
hmm I think I also have Protel 99 SE installed on some old laptop.. maybe I should dig up that one.. but yeah, thats also old :(
 
Last edited:
Some more tricks:
You can put the instruction to initialise the cable into a file, for example "cable.jtag", and include that file:
Code:
cable ft2232 vid=0x403 pid=0x6010 interface=1
frequency 100000
bsdl path e:/FPGA/bsdl_plcc
detect
Then:
Code:
$ jtag

UrJTAG 2021.03 #d9a2943f
Copyright (C) 2002, 2003 ETC s.r.o.
Copyright (C) 2007, 2008, 2009 Kolja Waschk and the respective authors

UrJTAG is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
There is absolutely no warranty for UrJTAG.

warning: UrJTAG may damage your hardware!
Type "quit" to exit, "help" for help.

jtag> include e:/fpga/cable.jtag
Connected to libftd2xx driver.
Setting TCK frequency to 100000 Hz
IR length: 10
Chain length: 1
Device Id: 00000001010100000010000000111111 (0x0150203F)
  Filename:     e:/FPGA/bsdl_plcc/1502AS_J44.bsd
Note that I created a separate directory for the "PLCC" packaged version of the chips. UrJTAG uses the first BSDL file with a matching device ID, which is e:/FPGA/bsdl/1502AS_A44.bsd for me, which is the TQFP packaged version. It doesn't matter much for programming, but is interesting for sampling individual pins:
Code:
jtag> instruction sample/preload
jtag> shift ir
jtag> shift dr
jtag> get signal io8
io8 = 1
jtag> get signal io9
io9 = 1
jtag> shift dr
jtag> get signal io9
io9 = 0
jtag> get signal io8
io8 = 1
jtag> shift dr
jtag> get signal io8
io8 = 0
jtag> get signal io9
io9 = 1
This is with push buttons connected to pin 8 and pin 9.

Or to test the device output:
Code:
jtag> instruction extest
jtag> shift ir
jtag> set signal io39 out 0
jtag> shift dr
jtag> set signal io39 out 1
jtag> shift dr
The LED is connected to pin 39.
 
Last edited:
Small update, I was able to erase a atf1502 with disabled jtag using the instructions from https://www.hackup.net/2020/01/erasing-and-programming-the-atf1504-cpld/
1741201983343.png


This uses a 12V boost converter to create the programming voltage, and I used a 1k resistor I had laying around to limit the current.

Edit: Slight update, You are supposed to:
- provide 5V power
- provide 12V programming voltage to pin 44/84
- program
- remove 12V programming voltage
- (remove 5V power)

I initially used the small push-button for 12V, but that didn't work properly. I assume the button is slightly bouncy. What worked was to directly plug in the wire at 12V after powering up. So if you design a PCB for this it may be better to use a jumper than a button. (Typing the programming instructions one-handed while holding the button is not ideal, either.)
 
Last edited:
Great thread!
I was just considering using the ATF1502 for a project and imagine my surprise when I was looking for info on it and AP came up near the top of the search results.

anyone use the ATDH1150USB programmers: https://www.digikey.com/en/products/detail/microchip-technology/ATDH1150USB/2050869
seems like a nice solution. on my project I'm not looking to power in-circuit just using a pogo-pin JTAG header to reflash in-circuit.
 
So far I have the best results with the Tigard board, but one of those days I want to try https://github.com/phdussud/pico-dirtyJtag as well.

Depending on the design of your board and your programmer you may need power to go from your board to your programmer to drive the output drivers to the right voltage (5v, 3.3v, 1.6v). (Sometimes this is fixed, sometimes this can be adjusted with jumpers or switches, sometimes this depends on the board, etc.)
 
Last edited:
I like the Tigard due to the simple voltage level selector and support for UrJTAG.
 
Back
Top