1
\$\begingroup\$

I'm working on designing an 8 bit home brewed CPU and in this process I'm using Octal D Flip Flops as registers to store data. One of the issues that I've ran into is the need to execute multiple functions in a single main clock cycle.

In order to do this, I'm fetching data from memory, placing it on the data bus, then clocking it into a register all in a single operation. I'm worried that the rising edge of the main clock will happen at the register before the data is fetched from memory.... a sort of propagation delay / race condition.

The only way I though to counter act this is to AND the flip flop's clock input with a clock that is faster than the main clock... that way data will be guaranteed to be clocked in at the end of that cycle. This does bring up a problem with data being clocked in over and over again, but I'm not sure if this is an issue. Any recommendations? Do I need to provide schematics?

EDIT:

Here's a small schematic for a register. I have three buses in the picture: data, control, and state. Depending on the OP code on the control bus, and the state, the flip flop will be clocked in. Note that I am ANDing with MC which is a clock that I set up running twice as fast as the universal clock. This is described above.

enter image description here

\$\endgroup\$
  • \$\begingroup\$ schematics? yes please. I have the impression that a somewhat higher block schematic will do start off. \$\endgroup\$ – jippie Dec 22 '12 at 23:39
  • \$\begingroup\$ I dug up something easily available to me... hopefully this helps a bit. \$\endgroup\$ – Dave C Dec 22 '12 at 23:52
2
\$\begingroup\$

The only way I though to counter act this is to AND the flip flop's clock input with a clock that is faster than the main clock... that way data will be guaranteed to be clocked in at the end of that cycle.

This sounds to me like an architecture choice that will eventually limit the performance (maximum clock speed) you can achieve with your design. If your registers are able to function at the faster clock speed, you'll eventually want to try to get the whole system running as close to that clock speed as you can, but then you won't be able to have a "slow" clock and a "fast" clock to do this with.

In order to do this, I'm fetching data from memory, placing it on the data bus, then clocking it into a register all in a single operation. I'm worried that the rising edge of the main clock will happen at the register before the data is fetched from memory.... a sort of propagation delay / race condition.

First solution

One way that leaps to mind to solve this is to clock data out of the memory on the rising edge of the clock, and clock it in to the register on the falling edge. Since your register doesn't have a configuration bit for which edge it responds to (like it would if you were designing in an FPGA), you would have to generate the appropriate signal by using an inverter (NOT gate) between the "main" clock signal and the register.

More generally, it's possible to distribute several phases of your clock (e.g., 0, 90, 180, and 270 degrees) instead of just clock and inverted clock. And use these different phases to execute different actions at different times. Of course you have to do a fairly careful analysis of each interface where data is transferred from one phase to another to be sure setup and hold times are met.

To the best of my understanding (possibly out-of-date) multiphase clock designs were fairly common in the discrete logic design era, and were also common (and may still be common) in ASICs and custom chip designs. But they are fairly uncommon in FPGA design due to the complexity of the timing analysis.

Second solution

Another option is to create a controller state machine that enables and disables different elements on different clock cycles as needed. For example, you'd enable the memory output on cycle 1 and enable the register to latch in the data on cycle 2. Since your register apparently doesn't have a clock enable input, you might need to do this by ANDing a state machine output with the clock input to the register.

This type of design was fairly common in the era of discrete logic CPUs, and its what was taught in undergraduate digital logic courses in the early 90's. An elaborate version of this scheme is called a microcoded architecture.

Of course this architecture means that you need more than one clock cycle to complete each instruction. But it would be multiple cycles of your fast clock, not your original "slow" clock that would be used, and you are already using more than one cycle of the fast clock per instruction in your design.

\$\endgroup\$
  • \$\begingroup\$ Thanks for the well constructed answer, I appreciate the time put into it. I have a very similar architecture to the second solution. I've been thinking a lot about using the falling edge but I'm not quite sure. I understand that my hack with the secondary clock w/ AND gate is a poor choice. \$\endgroup\$ – Dave C Dec 23 '12 at 17:27
2
\$\begingroup\$

Adding clocks or using the falling edge are poor choices, and slowing the clock won't help when you have setup or hold time problems. What you really need is a timing analysis.

First, find the required data hold time for the register chip and add that to the maximum delay through the AND gate for the clock signal. The result is the length of time that the DataBus must remain valid after the MC edge.

Second, determine how long the data outputs of the RAM will remain valid after the MC edge. There should be a spec for this on your RAM, and to that you can add the minimum propagation delay through any buffers on the data outputs as well as the minimum delay from the MC signal to the RAM.

If the RAM outputs are guaranteed to be valid (after the clock edge) for a longer time than the minimum time required for the register then everything should work. If not, you have a hold time violation.

\$\endgroup\$
  • \$\begingroup\$ Hey Joe, this is a good idea; however, how do I alter the propagation delays of the input chips? Is it just a matter of searching tons of datasheets to find a good match? Thanks very much for the response, I am learning a lot from people on here! \$\endgroup\$ – Dave C Dec 23 '12 at 17:29
  • \$\begingroup\$ @DaveC, for large adjustments, adding a buffer stage is the simple solution. For small adjustments, a resistor in series with the driver output will form an RC filter with the load capacitance and create a delay. However this is a very "fragile" design and likely to break when you change the load. \$\endgroup\$ – The Photon Dec 23 '12 at 17:53
  • \$\begingroup\$ @JoeHass, Good point. The timing analysis is how you figure out if you really have a problem. My answer addressed more what to do once that's already established. \$\endgroup\$ – The Photon Dec 23 '12 at 17:54
  • \$\begingroup\$ @DaveC, Photon's comment is correct, by adding a buffer to the output of the RAM you can increase the length of time that the RAM data is valid after a clock edge. The down side of this is that you also increase the delay from the clock edge until new data becomes valid, which can limit the maximum clock frequency. \$\endgroup\$ – Joe Hass Dec 25 '12 at 15:27

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.