Using Altera Max II CPLD with a General Purpose Bus

  • Thread starter Thread starter j777
  • Start date Start date
  • Tags Tags
    Bus General Max
Click For Summary

Discussion Overview

The discussion revolves around interfacing an Altera Max II CPLD with a general purpose bus, focusing on clock requirements, data synchronization, and control signal management. Participants explore design considerations for reading and writing data, including the use of flip-flops, tri-state drivers, and timing constraints related to bus operations.

Discussion Character

  • Technical explanation
  • Debate/contested
  • Mathematical reasoning

Main Points Raised

  • One participant inquires whether the CPLD clock is typically sourced externally or generated internally, noting a 14.7456MHz clock and questioning if a faster clock is needed.
  • Another participant asserts that the clock must be supplied externally and can only be divided down within the CPLD, not multiplied.
  • Discussion includes the need for control signals from the bus, with one participant mentioning the use of a finite state machine to generate signals synchronized with the CPLD clock.
  • Concerns are raised about synchronizing input and output data with the bus, particularly regarding metastability and timing issues during read operations.
  • One participant proposes using tri-state drivers and flip-flops to store port values, suggesting that there is sufficient time for the registers to settle before the bus read signal goes high.
  • Another participant questions the proposed design, emphasizing the importance of adhering to setup and hold timing requirements for the bus operations.
  • Participants discuss the synchronization of read registers and the potential need to adjust clocking based on control signals from the bus.
  • There is a suggestion to use a synchronized version of the ALE signal instead of a combination of ALE and RD~ for controlling the read register clock.

Areas of Agreement / Disagreement

Participants express differing views on the timing and synchronization strategies for interfacing with the bus, with no consensus reached on the optimal design approach. The discussion remains unresolved regarding the adequacy of proposed solutions and timing constraints.

Contextual Notes

Participants highlight potential timing issues related to the 55ns window for bus read operations and the synchronization of control signals with the CPLD clock. The discussion reflects the complexity of ensuring stable data during bus interactions.

j777
Messages
148
Reaction score
0
Hello,

I'm using an Altera Max II CPLD to interface with a general purpose bus with 60ns bus cycles. This is my first time using programmable logic so go easy on me. Is the required clock for the CPLD usually provided from an external source or can it be generated internally? Is a clock provided externally and then divided or multiplied internally to the desired frequency? I have a 14.7456Mhz clock being fed into the CPLD but I think I need something faster to interface with the bus. Any information related to these questions is appreciated.

Thanks
 
Engineering news on Phys.org
You need to supply the clock externally, and you would only be able to divide it down inside the CPLD, not multiply it up.

The bus you are interfacing to should have some control signals associated with it. Those are the signals that you will use to interface with the bus. If you have an asynchronous clock coming in from some other source, you will need to consider using synchronizer stages to avoid metastability. Are you transfering data from one clock domain (yours) to another clock domain (the bus)?
 
The bus provides an ALE and a read and write strobe signal. I'm still working on that digital io problem that we talked about before where I need the following io ports: 2 8bit output, 2 8bit input, and 2 8bit configurable io. As I mentioned the CPLD is fed a 14.7456Mhz clock. I understand how to write to these ports but the reading of them is still causing me some trouble. If I use the 14.7456Mhz clock and 2 flipflops to synchronize the inputs how do I then synchronize the output of the 2nd flipflop with the bus?

I've struggled with the overall design and have gone from a design that is completely driven by the bus's control signals to my latest version that uses a finite state machine to generate secondary ALE and RD/WR strobe signals (that are synchronized with the 14.7456Mhz clock). Since my overall goal here is relatively simple is there any problem with the design driven by the bus control signals? Would this be how it is typically done?
 
What is the relationship between the 14.7456Mhz clock and the IOs? Are the IOs synchronous with this clock? Can you post what the bus timing spec diagrams look like? You will need to figure out a way to hold off changing the bus-side registers too close to a bus read operation...
 
There doesn't have to be a relationship between the IOs and the 14.7456Mhz clock; it's just a clock that is available for use. I was going to use it for the 2 stage synchronizers on the inputs.

The last section in the text file (link below) shows the timing specs for the bus I am interfacing with.

http://www.embeddedarm.com/Manuals/ts-7400-info.txt"
 
Last edited by a moderator:
Okay, sounds like you can do what you want, but I'd also have the clocking of the final IOin Read register(s) get held off when ALE is low. That way you will be holding the most recent values, and not have them changing when the RD~ signal is rising. Or use some other method to avoid contention for the Read register when the uC is reading the values.
 
I actually just used a tri-state driver for each port for reads and I was thinking I'd use flip-flops to store the port values when the RD~ signal goes low. That way they would have 55ns before the RD~ signal goes high to settle to a stable state. Does this sound like a good solution?
 
I'm not sure I understand what you are proposing. Any chance you could attach a sketch? You need to be a good citizen on the ALE bus, which means not violating any setup or hold timing that the uC requires for reads. You need to guarantee that the data which you offer to the bus does not change around the rising edge of RD~ (where the data is latched into the uC, I believe). To do that, the data has to have been synchronized and latched into your read register(s) before the setup time to RD~ rising begins.
 
Ok, say I have two 8-bit input ports on the CPLD that I would like to read from the uC over the GPBUS (as documented in ts-7400-info.txt). Presently I have it working with pure combinational logic using a tristate driver for each input port. The driver is enabled when the correct address is decoded from the multiplexed GPBUS and RD~ goes low (it will go high again 55ns after it goes low). Now as you have mentioned I should synchronize the input ports and have the port's value in a read register prior to RD~ going high to make sure the value on the data bus doesn't change when the uC tries to latch it. So I'm wondering if a register between each input port and it's tristate driver would be sufficient if the register stored the value of the port when RD~ goes low. Since there is 55ns before RD~ goes high and the uC latches the data there should be enough time for the register to settle to a stable state...correct? Or is this a bad solution?
 
  • #10
It's hard to work this through without drawing some stuff on paper together, but what I would describe in words would be something like this:

For each input register, you will need two registers in series, in order to synchronize the input data into the final register that you will read out onto the bus via the tri-state drivers. The two series input registers for each Register are clocked with the same 14MHz local clock that you have. So data is continuously being clocked into each of the final Read registers while there is no uC bus activity.

But when ALE and RD~ are asserted, I would stop clocking the final Read registers, to be sure that the data is stable when RD~ goes high to clock the data up into the uC. You need to be careful how you static the Read register clock, since ALE and RD~ are asynchronous to your 14MHz clock domain. You basically need to synchronize the ALE ^ RD~ signal with your 14MHz clock (so use two FFs in series, right?). Then use that synchronized signal to disable the clock into the final Read registers. And when ALE ^ RD~ de-asserts, the synchronized version of that makes it through and re-enables the clock into the final Read registers.

Does that make sense?
 
  • #11
Thanks for the good explanation. I understand what you're saying but I don't think there is enough time for the synchronized version of ALE ^ RD~ to static the read register clock before ALE ^ RD~ de-asserts and the uC latches the data on the bus. There is only 55ns between RD~ asserted and RD~ de-asserted (see http://www.embeddedarm.com/Manuals/ts-7400-info.txt" ). If I'm not mistaken wouldn't 140ns pass before ALE ^ RD~ is synchronized and stops the read register clock?
 
Last edited by a moderator:
  • #12
j777 said:
Thanks for the good explanation. I understand what you're saying but I don't think there is enough time for the synchronized version of ALE ^ RD~ to static the read register clock before ALE ^ RD~ de-asserts and the uC latches the data on the bus. There is only 55ns between RD~ asserted and RD~ de-asserted (see http://www.embeddedarm.com/Manuals/ts-7400-info.txt" ). If I'm not mistaken wouldn't 140ns pass before ALE ^ RD~ is synchronized and stops the read register clock?

Great stuff J777, that's the way to be thinking. I didn't do any numbers in my thinking about the interface, since that's your job, and you're doing it! Just like in the real world, this is the way stuff works. We toss around design ideas, but it's the person actually doing the circuit design who is responsible for doing the detailed, careful checks.

Now (again without me doing the detailed checks -- that's up to you), the next step back would be to just use a synchronized (to the 14MHz clock domain) version of ALE instead. You would be holding the Read register on Writes, but in the system context, that may not matter (that would depend on the overall system architecture constraints). So if you get enough time for the synchronizations to work with backing off of ALE ^ RD~ to just ALE, then you may be good to go. If that's not enough still, then you need to spend some time thinking about the two clock domains more, and how you can guarantee no metastability in IO --> uC transfers.

You're doing great. I'm looking forward to what you come up with next.
 
Last edited by a moderator:
  • #13
BTW, also in the real world, the way that we capture design considerations, constraints and features like this is in our Functional Specification documents about the circuits or products. These documents are checked into Source Control (like CVS or VisualSourceSafe), and revisions are tracked via those systems. It's an important part of real-world of PDP systems (I forget what that stands for, "Process something something") that you have written documentation for what you are technically trying to do, and to track changes in the requirements and targeted performance through the stages of a project.

So I'd recommend that as practice, you jot down your requirements and some notes about your circuit design (and how your design meets the requirements). The subject matter that you are getting into with this project is basically identical to real-world work that I do and other engineers do, so it would be good to add in a little practice for the other supporting work that you do. (Plus, despite the hassle of having to do more paperwork, efficiently writing and maintaining specs of your work is a big lever in keeping all the technical and Marketing team members synchronized.)
 
Last edited:
  • #14
Like, if you wrote that the Read register had to hold off for the full ALE period, but that caused some Marketing problem, there are ways to fix that (which involve more cost in your circuit design). Those kind of tradeoffs happen all the time, and getting good/comfortable/practiced at putting that kind of thing down on paper (well, on your local server) is an important skill.
 
  • #15
Well I've been thinking about this and I've come up with two ideas/solutions.

1. I do nothing as far as synchronizing the inputs. Since the input values are stored in the read register when RD~ is de-asserted and at that point there is at least 40ns to resolve any metastable state (before RD~ is asserted) everything will be OK. <-- this is just a thought I had...let me know if this is way off or not

2. I slow down the uC's bus cycles to allow enough time for ALE ^ RD~ to be synchronized with the 14Mhz clock. This signal is then used to static the read register clock when RD~ is de-asserted.

Please give me your thoughts on these two solutions.

Thanks
 
  • #16
Did this suggestion not work out?

berkeman said:
Now (again without me doing the detailed checks -- that's up to you), the next step back would be to just use a synchronized (to the 14MHz clock domain) version of ALE instead. You would be holding the Read register on Writes, but in the system context, that may not matter (that would depend on the overall system architecture constraints). So if you get enough time for the synchronizations to work with backing off of ALE ^ RD~ to just ALE, then you may be good to go.
 
  • #17
Sorry for jumping ahead :)

If I am correct, backing off to just ALE only gives an additional 13ns which results in 68ns for the read registers to be staticed and read. Since it may take 70ns for the synchronized version of ALE to get through this solution is still inadequate. Is there something else that I'm missing in my thought process?
 

Similar threads

Replies
29
Views
6K
  • · Replies 1 ·
Replies
1
Views
5K
Replies
4
Views
4K
  • · Replies 9 ·
Replies
9
Views
4K