ATF1500 CPLD based "SPI/shift register peripheral"

333 views
Skip to first unread message

Tom Storey

unread,
Sep 3, 2019, 9:52:58 AM9/3/19
to retro-comp
Hi everyone.

Some time ago I hinted that I was trying to implement a SPI like peripheral in a CPLD, namely for use in a project that I am working on, and also just because I felt like doing something with a CPLD.

I finally managed to find some time to have a real crack at it, and I think Ive managed to do it. My initial goal was only to implement "write and shift" functionality, since that was what I had implemented as a purely discrete logic solution for my project, and since I am only shifting data out to drive some displays, but it looks like I have also managed to implement read functionality as well.

Ive written it in CUPL, since WinCUPL comes with WinSIM which meant I was able to simulate the design and test it. I'd give it a go in some kind of HDL if I could find a good set of simulation tools and if I could work out whether VHDL or Verilog is what I want to learn. Ive been doing a bit of poking around that kind of stuff lately, but yet to find *the* setup that will work for me.

Anyhow, attached is a screenshot of the output from WinSIM, with a few notes:

* Vector 5 I start to initiate a "write and shift" operation, but it isnt really until vector 6 that this operation begins, as the internal state machine is clocked by the system clock
* At vector 8 you can see that the storage register sr is loaded from the value presented on the data bus
* When the chip select signal is released at vector 11 you can see that the state machine transitions to the next state at vector 12, this is the beginning of the shift operation now that the write operation has completed. The ser_out signal simply follows the value of sr7 which you can see also started to present a value at vector 8 when the storage register was loaded.
* From vector 13 onwards, the chip outputs an inverted version of the system clock, this is used to clock the slave device so that it loads each bit into its own storage register. sr0 will have its input value clocked by the system clock, and this only takes effect as long as the state machine is in the shifting state which it is from vector 12 (but only actually takes effect from vector 14).
* Vector 14-27 are a bit of a jumble, but you'll see if you look very carefully that the value of sr7..0 is being shifted out, and the value of the ser_in signal is being shifted in place.
* When ctr3 goes high, this indicates that 8 bits have been shifted and will terminate the shift opeation and return the state machine to its idle state where it waits for the next operation. That concludes a write/shift operation.

* From vector 33 Im playing around with setting up a read operation, which is successfully initiated at vector 35 once both the !cs and !rd signals are asserted. This will cause the state machine to transition to the reading state, although really this has no actual effect or impact on the operation - the tri-state function of the databus latches is a simple combinatorial function of those two signals. So you'll see at vector 35, even though this is a falling edge period of the system clock, the data bus is driven with the value that was in the storage register. The storage register is transferred to the data bus latches each clock cycle.
* At vector 40 you can see the state machine transitioning back to its idle state once the !cs and !rd signals are no longer in a valid state and we encounter a positive edge of the system clock. And that concludes a read operation.

* At vector 43 you can see that if I assert the !clr signal then all counters, registers etc are reset.
* At vector 47 I try another read operation just to make sure the device is outputting all 0's since a reset has occurred. Reset is asynchronous as you can see by it occurring within a falling edge of the system clock.

I think that about covers it...

Have popped the source and simulation files up on github (https://github.com/tomstorey/CPLD-Projects/tree/master/z80_sr). If you have the inclination to look over it, I'd like to hear if Ive really goofed anything up - although the simulation results fill me with a sense of confidence. One of my design goals was to operate it at full system clock frequency, so that ideally you could use instructions like OUTI et al to sit in a tight loop moving data from memory to the peripheral, and without needing to fiddle the WAIT line.

Also, chip select for slave devices should be implemented externally.

Im yet to program an actual device to try it out while being driven from an actual Z80 CPU, I'll hopefully get to that in the next month (or at this rate, two). Would be good to put my dev kit to use. :-)

Tom
Screenshot 2019-09-03 at 08.13.32.png

Mark T

unread,
Sep 3, 2019, 11:45:26 AM9/3/19
to retro-comp
Hi Tom

I made a discrete shift register spi interface for micro SD card:-

And then a variant on this to interface to a featherwing wiznet:-

Note these use two separate shift registers for input and output data. I had considered trying to use a single shift register, which I think is what you are using in your CPLD design. The problem I saw with this is that the shifting data out on the rising edge of clock and shifting data in on the falling edge, for SPI Mode 0.

It might have been possible to fix this with a 74x74 for receive data to clock input data on the falling edge but this would not reduce the package count.

Two separate shift registers also has the advantage that on completion of a transfer the transmit register contains 0xFF, so when reading a sequence of bytes from the slave the data output to the slave is a sequence of 0xFF, without the need to reload the transmit register.

I included two options to read the receive register, Read and initiate a new transfer and read without initiating a new transfer. When implementing this in RomWBW for micro SD cards, I found that I only needed the read and initiate new transfer.

It would probably be quite easy to implement separate shift registers in the CPLD. I have a version using EPM7128S in process, but using schematic entry to implement the same logic as my discrete version. I may try and include SPI modes 1, 2 and 3 later as this would increase the range of PMOD modules that could be used.

Mark

Tom Storey

unread,
Sep 3, 2019, 3:20:21 PM9/3/19
to retro-comp


On Tuesday, September 3, 2019 at 4:45:26 PM UTC+1, Mark T wrote:
Hi Tom

I made a discrete shift register spi interface for micro SD card:-


Hey Mark,

Yep, I recall you sent me something similar when I posted about my discrete version, probably over on the rc2014 list at the time.

It is very much designed to do what I wanted it to do - I guess thats what most CPLD designs are for. :)

To do all 4 of the different modes I may need a bigger CPLD and quite some more logic. Probably not unachieveable, but definitely much more work.

Thinking a bit out loud... I pretty much already have a second shift registers worth of latches used within the current design - those used to interface with the data bus. On a read operation I simply enable the output drivers of those latches to put what ever value they have out on to the bus. When youre doing a write to it, I take the value present on the pins, but it doesnt have to be latched through the registers assigned to those pins. With a little work, the ser_in signal could be shifted into those latches instead of the storage register.

And on the subject of the function to "do another read" is pretty interesting if you are reading long strings of data from somewhere - I guess thats something I havent needed in my project since I am mostly shifting data out for a display. Perhaps that could even be taken care of by hooking A0 up to an input, and using that to select between simply reading what is in the data bus registers, and kicking off another operation which pulls the WAIT line low while another byte is read in.

Maybe a project for another time, certainly sounds like a challenge. :)

Alan Cox

unread,
Sep 3, 2019, 4:16:48 PM9/3/19
to retro-comp
And on the subject of the function to "do another read" is pretty interesting if you are reading long strings of data from somewhere - I guess thats something I havent needed in my project since I am mostly shifting data out for a display. Perhaps that could even be taken care of by hooking A0 up to an input, and using that to select between simply reading what is in the data bus registers, and kicking off another operation which pulls the WAIT line low while another byte is read in.

The ZX spectrum interfaces either do that, or they just run the SPI clock at a fraction of the CPU clock thereby guaranteeing that by the time your ini ini has done the second read you've got the data. As it's 16 clocks even at 8MHz you don't have to run the SPi that fast. (shade faster for Z180).

SocZ80 is open source and also has a VHDL SPI interface which works by CPU halting but it probably wouldn't fit a CPLD nicely.

(Usefully the ZXMMC actually works with RC2014 because it's really a Z80 CPU socket adapter and uses ports 1F/3F)

Alan

Mark T

unread,
Sep 3, 2019, 7:15:40 PM9/3/19
to retro-comp
I just wanted to make sure that you considered that the output data shifts on one clock edge and the input data on the opposite clock edge. It didnt look like your design was doing that. Of course its not a problem if you want output only.

Mark

Rick Policy

unread,
Sep 3, 2019, 9:51:52 PM9/3/19
to retro-comp
If you are looking for a quick start using VHDL, Digikey has an open core that is a SPI master. It is quite simple and has most of the bells and whistles (e.g. CPOL and CPHA control). It also supports multiple chip selects. All you need to add is the user/micro interface. Altera has a schematic capture that can be used for the micro interface instead of having to generate it in VHDL. The downside is the older parts are not supported by the free version (Intel Quartus Prime Light). The MAXII parts are supported and would be a good fit if you are not hung up with 3.3V logic I/O. The 74VLCxxxx parts can be used from RC2014 to the CPLD since they are 5V tolerant, but powered by 3.3V.

I’ve just recently used it on an EPM7160SL84 without much trouble. One thing to keep in mind is if you hold the ENABLE pin high after a SPI transfer is complete, then it will repeat the transfer using the same data. Therefore the RC2014 would need to strobe it quite quickly.

You can find it here:
https://www.digikey.com/eewiki/pages/viewpage.action?pageId=4096096

Bill Shen

unread,
Sep 3, 2019, 10:19:58 PM9/3/19
to retro-comp
I want to mention that MarkT's SPI schematic design fit easily in a 44-pin EPM7064S CPLD.  Only 61% of the 64 macrocells are utilized.  It may be possible to fit the design in EPM7032S, the smallest CPLD of the 7000 family.
  Bill

Mark T

unread,
Sep 4, 2019, 12:38:24 AM9/4/19
to retro-comp
Quartus 13.1 ia available as a free version and supports the Epm7xxx series.

74ahc can also be used with 3.3v supply and is 5 v tolerant. They may be easier to find in through hole DIL package.

The issue with long enable pulse causing multiple transfers is probably not difficult to fix in the vhdl code, but as there is no point running the spi clock faster than the cpu clock so its not likely to be an issue.

Mark

Greg Holdren

unread,
Sep 4, 2019, 1:59:27 AM9/4/19
to retro...@googlegroups.com


Also, One could send and receive on the same edge if so desired. :) Transfer a register to the MISO register on falling select if it needs to be loaded first and is not already mirrored.

Greg

Tom Storey

unread,
Sep 4, 2019, 2:50:12 AM9/4/19
to retro-comp


On Wednesday, September 4, 2019 at 12:15:40 AM UTC+1, Mark T wrote:
I just wanted to make sure that you considered that the output data shifts on one clock edge and the input data on the opposite clock edge. It didnt look like your design was doing that. Of course its not a problem if you want output only.

Mark


That is exactly what it is doing. 

Tom Storey

unread,
Sep 4, 2019, 5:11:31 AM9/4/19
to retro-comp


On Wednesday, September 4, 2019 at 2:51:52 AM UTC+1, Rick Policy wrote:
If you are looking for a quick start using VHDL, Digikey has an open core that is a SPI master. 

Im quite interested in the challenge of trying to implement something myself, rather than just copying/pasting. :-)

I could use it as inspiration and to learn from, however.  Thanks for the heads up!
Reply all
Reply to author
Forward
0 new messages