Continue to Site

# ATF1508 - output as open collector with WinCUPL

#### jamesportman

##### Newbie level 6
Hi,

I would like to have an ATF1508 output pin act as open collector.
If I output 0, it is pulled down to ground/outputs 0, if I output 1 then the pin should float.

I have searched and found almost useful information but specifically for VHDL e.g.

Is is possible to do this in WinCUPL?
If not I did download Quantus II, so I could just start to learn VHDL and use that instead if it just works?

I have also seen some optocouplers and inverters with open-collector outputs but I was hoping to just use the PLD if it can do this.
Also can probably do all this with transistors but it will be messy.

Thanks for any help!

Longer version for background info:
So far I have got some code together in WinCUPL for a project, it is doing address decoding, control signals to a ROM chip and needs to cope with IO pin read/write from an old CPU.
The CPU IO ports 3&4 are shared with the data/address bus for the ROM, and on top of that the bus is multiplexed so 16 bit address and 16 bit data on the same 16 pins.
IO reads and writes are presented as bus cycles but with a specific address (0x1FFE), they need to be output on some totally separate CPLD pins which I can wire off somewhere.
I am latching the address with ALE and storing that, then checking for either a ROM address or IO address 0x1FFE.
For the ROM access I can enable ROM CE/OE when the RD read or WR write pins are active for a ROM address.
The CPU IO ports are bi-directional open-collectors.
* When the CPU does an IO write then I need to latch the bus data into the PLD then constantly output it on some output pins - as open collectors.
* If the CPU does an IO read then I need to read from the PLD output pins and write that onto the bus, but all other times the PLD bus pins must be floating/used inputs to read addresses and data.

For now I just at least want to get one PLD output pin working as open collector.

Code so if anyone is interested, at the moment only works for IO writes from CPU and outputs solid 1/0 (not open collector);

Code:
/******************** pin_ definitions *******************/

pin [51..52,54..58,60,61,63..65,67..70] = [ecu_io_pin_15..0]; // ECU side only I/O pins

PIN 27 = ROMOE;
PIN 80 = ROMWE;
PIN 28 = RD;
PIN 79 = WR; // (L)
// PIN 78 = WRH; // not sure needed, it will always do 16 bit writes for IO and sets WRL and WRH when it does
PIN 77 = ALE;
PIN 76 = ROMCE;

$repeat i = [0..15] pinnode = address_latch{i};$repend

// set up the full cpu address latches
cpuaddr.LE = !ALE; // latch on ALE low (or does it need to be high?)

// based on the above, decide whether the address was I/O ports or ROM
cpu_rom_access = cpuaddr:[2000..9FFF]; // TODO [2000..9FFF]

/**************** latch IO data output from CPU to ECU IO *****************/

$repeat i = [0..15] pinnode = io_data_output_latch{i};$repend

field io_data_output = [io_data_output_latch15..0];

io_data_output.L = [ad15..0]; // data to latch (direct data bus pins)
io_data_output.LE = cpu_io_access & WR; // latch on CPU IO access and write

/**************** allow I/O access *****************/
// how do we know what is an input or output? can it change depending on how the CPU accesses?
// should we just always latch the outputs?
// check CPU code to see if it reads or writes?
// this is setting up output only from CPU to ECU IO
field ecu_io = [ecu_io_pin_15..0];
ecu_io = io_data_output;

/**************** set ROM control pins *****************/
!ROMCE = cpu_rom_access;
!ROMOE = !RD & WR & cpu_rom_access; // read from ROM if reading and not writing and it is a ROM address on the CPU side
// write has complicated timings, double check
!ROMWE = !WR & RD & cpu_rom_access; // write to the ROM if writing and not reading and it is a ROM address on the CPU side

/**************** fix the ROM address (-0x2000) *****************/
// I think this actually immediately sets the outputs
// this could be kept as-is just to operate on the highest nibble of the address
// the rest can be piped directly through
'd'0 => 'd'14; // -2 but wrap around, can't cope with negatives
'd'1 => 'd'15; // -2 but wrap around, can't cope with negatives
// the repeat just fills the rest in as -2 each
$repeat i = [2..15] 'd'{i} => 'd'{i-2};$repend
}
// the lower 12 bits can pass straight through
romaddr_lower = cpuaddr_lower;

Last edited:

#### FvM

##### Super Moderator
Staff member
ATF15xx series can implement open collector and tristate buffer, as most complex CPLD. I would expect that WinCUPL can translate a VHDL description to ATF programming file. However WinCUPL is rather old software with Windows 3 look and feel. It has no native VHDL support, just a VHDL to boolean converter. Thus I'm not sure if it performs well. There should be up-to-date tool options.

#### jamesportman

##### Newbie level 6
ATF15xx series can implement open collector and tristate buffer, as most complex CPLD. I would expect that WinCUPL can translate a VHDL description to ATF programming file. However WinCUPL is rather old software with Windows 3 look and feel. It has no native VHDL support, just a VHDL to boolean converter. Thus I'm not sure if it performs well. There should be up-to-date tool options.

There is a program from Atmel to convert compiled verilog (POF files maybe) so they can be programmed to my chip.
And I did download Quartus by Intel which can build VHDL for the exact equivalent Altera chip to mine, so maybe that is the way to go.

And yes WinCupl is absolutely awful to deal with in the short time I have used it.
It sometimes just completely closes if you have a slight code issue.
There are command line tools for it that make things better but still not ideal

#### FvM

##### Super Moderator
Staff member
Last Quartus version supporting MAX7000S series is 13.0SP1. Did you already get this old version? I know that compatibility with ATF15xx has been stated using an Atmel pof2jed tool.

#### jamesportman

##### Newbie level 6
Yes I had to go back to version 13.0SP1 as you say, which was annoying, I did get the latest version first.
It's a shame things are so awkward with these because I do specifically need 5v IO levels, most of the FPGAs and other new chips are 3.3v.

And yes that's the one thanks, pof2jed.
I think the original atmel tool for programming will work after that.

Just waiting for breakout board then I will see if my JTAG programmer works with it or not.

#### KlausST

##### Super Moderator
Staff member
Hi,
I do specifically need 5v IO levels, most of the FPGAs and other new chips are 3.3v.
You want "open collector" thus it's not the IC that determines the output voltage level.
It may give limits, but often these devices are 5V tolerant, even powered with 3.3V.

Alternatives:
* you may use external transistors
* you may use external drivers, like HC1G125

If you want to build an "open collector" from a 3-state driver: (D_in, OE_in, Q_out)
* connect D_in to GND
* connect OE_in to your data signal
* Q_out acts like an "open collector"
This is true for external drivers as well as for PLD internal drivers.

Klaus

#### jamesportman

##### Newbie level 6
Hi Klaus,

Didn't realise some of the FPGAs were 5v tolerant for signals.

I do still need 5v IO level for talking to the ROM chip, plus the CPU bus address and data will be 0-5v incoming, so it just seemed better with a 5v chip.

I did think about transistors but it might be messy, there will be 16 outputs.

Thanks for the bus driver idea, I did wonder about some latch or similar.
Makes sense as you say to either enable a low output or just disable for high output with OE so the pin floats, that is great.
Again though, this would need 16 of them since the OE is really the output per pin, even an 8 input/output version would not be helpful.

And thanks for the point that this also works for PLDs, I'll have another look in case I can already do it in WinCupl, but I probably better learn VHDL with Quartus..

Thanks