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);
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 [4..6,8..11,15..18,20..22,24,25] = [ad15..0]; // CPU address/data/port bus pins
pin [29..31,33..37,39..41,44,46,48..50] = [ROMADDR15..0]; // ROM only address pins
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;
/******************** address bus things *******************/
field romaddr_top = [ROMADDR15..12]; // top 4 ROM address pins
field romaddr_lower = [ROMADDR11..0]; // lower 12 ROM address pins
$repeat i = [0..15]
pinnode = address_latch{i};
$repend
field cpuaddr = [address_latch15..0]; // full cpu address, can check whether accessing I/O port or ROM
field cpuaddr_top = [address_latch15..12]; // selecting top 4 CPU address bits
field cpuaddr_lower = [address_latch11..0]; // selecting lower 12 CPU address bits
// set up the full cpu address latches
cpuaddr.L = [ad15..0]; // data to latch (direct data bus pins)
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_io_access = cpuaddr:1FFE;
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) *****************/
// romaddr = cpuaddr - 2
// 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
Table cpuaddr_top=>romaddr_top {
'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: