CSE 370
Autumn 1996

Homework #7

Mystery logic

q1 is a postive edge trigged flip flop
q2 is a postive clocked latch

There are a whole bunch of clever and interesting ways that you can drive the d12 pin to determine what sort of sequential logic element is behind q1 and q2. Most everyone caught on to the basic ideas: assert d12 near a rising edge, look for a response; assert d12 near a falling edge, watch what happens; pulse d12 high during the positive or negative cycle of the clock, watch the result. The waveform below shows many of these situations.

[Waveform of Mystery logic circuit]

Marked in the waveform are four points where we can deduce information about the logic elements:

a Are we driving a positive clocked latch? If so, then the latch should follow d12 at this edge. q2 does, so we guess that it's a positive clocked latch.

b Is either element a negative edge trigged flip-flop? If so, then at this falling clock edge, with d12 asserted, the flip-flop should change from 0 to 1. q1 doesn't change, so it's not a negative edge triggered device.

c What about positive edge triggered devices? d12 is asserted, and here is a positive edge. In fact, q1 does go high when this edge comes along, so q1 is probably a positive edge triggered device.

d Do we have a negative clocked latch? If we had such a device, it would reflect changes in d12 when the clock was low. d12 changes here, but nothing happens on our devices, so they aren't negative clocked latches.

Simple Flip Flop analysis

The simple device is a postive edge triggered 1's catching device with asynchronous clear.

The device has an asynchronous clear which resets the output to 0 whenever clr is 1. The output remains 0 until the input is high at a positive edge of the clock. Thereafter, the output will remain high, regardless of what the input does. The 1 on the input has been "caught".

[Waveform of simple sequential device]

4-bit Universal Shift Register

There were two parts to the assignment: building a single shift register cell, and building the 4 bit shifter from 4 cells.

Shift register cell

There's not much special about the shift cell. The specification didn't call for a clear input to the cell, but many of you included one anyway. That was okay.

MODULE shift1

  interface (di, sr, sl, s0, s1, clk -> z);

TITLE 'One-bit shift register'

  di, sr, sl, s0, s1	pin;
  clk			pin;

  z			pin istype 'reg, buffer';



  z.clk = clk;

       WHEN ( s1 &  s0) THEN z := di;
  ELSE WHEN ( s1 & !s0) THEN z := sr;
  ELSE WHEN (!s1 &  s0) THEN z := sl;
  ELSE WHEN (!s1 & !s0) THEN z := z.fb;


Four bit shifter from 1 bit cells

There were two distinct strategies that one could have taken on this design: use an ABEL file to connect the shift cells together, or use a schematic to glue everything together. Both methods allow for elegant solutions, and of course, both have their disadvantages.

ABEL solution

The ABEL solution allows for a very elegant method to build the shifter from the 4 shift cells. Below is a good example of this.

MODULE shift4

  interface (clk, i3..i0, s2..s0 -> q3..q0);

TITLE 'Universal 4-bit shift register'

clk, i3..i0, s2..s0       pin;
q3..q0                    pin istype 'com';

shift1 interface (di, sr, sl, s0, s1, clk -> z);
sh3..sh0 functional_block shift1;


  [sh3..sh0].clk = clk;
  [q3..q0] = [sh3..sh0].z;
  [sh3..sh0].di = [i3..i0];
  sh3.sr = (sh3.z & s2) # (sh0.z & !s2 & !s1);
  sh2.sr = sh3.z;
  sh1.sr = sh2.z;
  sh0.sr = sh1.z;
  sh3.sl = sh2.z;
  sh2.sl = sh1.z;
  sh1.sl = sh0.z;
  sh0.sl = !s2 & sh3.z;
  [sh3..sh0].s1 = s0;
  [sh3..sh0].s0 = (s2 & s1) # ((s2 $ s1) & !s0);

Unfortunately, ABEL also lets you have very cumbersome code. Many of you had in your EQUATIONS block a big WHEN THEN ELSE ... block that switched on the shift control signals s2..s0. Certainly, this strategy is not wrong, but probably not ideal. In particular, it is easy to make mistakes with this approach; there are scores of lines of code, anyone of which you might mistype. Further, it is difficult for someone to look over the code and discern that the blocks are, in fact, closely related (i.e., logical shift left and arithmetic shift left both shift left).

Many of you who opted for the ABEL approach built separate modules for flip-flops. Again, this strategy was not incorrect, but probably excessive. To create a flip-flop in an ABEL module, you need only declare a pin to be a reg:

   q3..q0   pin istype 'reg, buffer';

Schematic solution

It might have been easier to build the shifter using a schematic at the highest level of abstraction. The schematic that was used to generate the waveforms is shown below. The schematic is also improved by editing the shift submodule's symbol so that the sl and sr blocks are on opposite sides.

[Shift register schematic]

This schematic uses an additional ABEL block to generate the miscellaneous control signals:

MODULE control

  interface (s2..s0 -> c1..c0, m0_0, m3_0, m3_1);

TITLE 'Shifter control'

  s2..s0		pin;

  c1..c0		pin istype 'com';	" Shift cell control
  m0_0			pin istype 'com';	" Control for bit 0 mux
  m3_0, m3_1		pin istype 'com';	" Control for bit 3 mux

  s = [s2..s0];
  c = [c1..c0];
  m3 = [m3_1..m3_0];
  hold = 0;
  shiftLeft = 1;
  shiftRight = 2;
  load = 3;

       WHEN (s == 0) THEN c = hold;		"Hold
  ELSE WHEN (s == 1) THEN c = shiftRight;	"Circular shift right
  ELSE WHEN (s == 2) THEN c = shiftLeft;	"Circular shift left
  ELSE WHEN (s == 3) THEN c = shiftRight;	"Logical shift right
  ELSE WHEN (s == 4) THEN c = shiftLeft;	"Logical shift left
  ELSE WHEN (s == 5) THEN c = shiftRight;	"Arithmetic shift right
  ELSE WHEN (s == 6) THEN c = shiftLeft;	"Arithmetic shift left
  ELSE WHEN (s == 7) THEN c = load;		"Parallel load

       WHEN (s == 2) THEN m0_0 = 1;		"Use out3
  ELSE               m0_0 = 0;			"Use 0

       WHEN (s == 1) THEN m3 = 0;		"Use out0
  ELSE WHEN (s == 5) THEN m3 = 1;		"Use out3
  ELSE                    m3 = 2;		"Use 0

Regardless of the approach you took, the waveforms for the solution should resemble those shown below:

[Shift register waveforms]

(For more information about using buses in Synario, see Tip #4 on the Synario Tips page).

Gray code counter

The most common implementation of the Gray code counter was one whose ABEL file looked like:

MODULE graycntr

  interface(clk, reset, en -> c2..c0);

TITLE 'Gray code counter'

  clk, reset, en	pin;

  c2..c0		pin istype 'reg, buffer';

  c = [c2..c0];


  c.clk = clk;

  WHEN (en) THEN {
           WHEN (reset) THEN      c := ^b110;
      ELSE WHEN (c == ^b000) THEN c := ^b001;
      ELSE WHEN (c == ^b001) THEN c := ^b011;
      ELSE WHEN (c == ^b011) THEN c := ^b010;
      ELSE WHEN (c == ^b010) THEN c := ^b110;
      ELSE WHEN (c == ^b110) THEN c := ^b111;
      ELSE WHEN (c == ^b111) THEN c := ^b101;
      ELSE WHEN (c == ^b101) THEN c := ^b100;
      ELSE WHEN (c == ^b100) THEN c := ^b000;
    c := c;

The notation ^b001 is an alternate notation for a binary value.

Several solutions were presented where the equations for each c2, c1, and c0 were simply equations from the previous values of c. This certainly is a valid approach, but probably not the best one. In particular, if you have used a K-map to derive these equations by hand, then you are not using the tools to their full capacity. The motivation to a Hardware Description Language such as ABEL is to allow the designer to state his or her intentions at a high level and let the tools translate these intentions into equations.

A sample waveform for the Gray code counter is:

Besides writing ABEL for the Gray code counter, you were also asked to draw a state machine for the device, and show how the counter would be mapped onto an EO320. A state machine for the counter is:

The most common mistakes on the state machine were forgetting to label the transitions, or forgetting to show the transitions for when en was low.

Finally, we have the EO320 fuse map. If you peeked inside the .jed file that Synario created, you could see exactly which fuses were made or blown. However, you could also have gotten the gist of the story from looking at the equations that Synario produced. One thing to watch out for on the Fuse Map is that the top minterm on each output pin is not part of the pin's value. Instead, this minterm controls the tristate buffer associated with the pin.

(See following page)