CPLD Clock

  1. 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.

  2. jcsd
  3. berkeman

    Staff: Mentor

    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)?
  4. 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?
  5. berkeman

    Staff: Mentor

    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....
  6. 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.

  7. berkeman

    Staff: Mentor

    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.
  8. 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?
  9. berkeman

    Staff: Mentor

    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.
  10. 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?
  11. berkeman

    Staff: Mentor

    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?
  12. 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?
  13. berkeman

    Staff: Mentor

    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.
  14. berkeman

    Staff: Mentor

    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: Jan 26, 2007
  15. berkeman

    Staff: Mentor

    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.
  16. 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.

  17. berkeman

    Staff: Mentor

    Did this suggestion not work out?

  18. 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?
Know someone interested in this topic? Share a link to this question via email, Google+, Twitter, or Facebook