ARM project: Week 1
Electronic dice in Verilog

ARM project home | Tasks (weeks): 1 | 2 | 3 | 4

Setting up the project

First create a new directory for the first part of this workshop in your filespace for the project, perhaps called w1/tlights/. Into this, download the files tlights.v and tlights.acf. Sometimes (for some reason best known to itself), Internet Explorer adds "(1)" to the end of file names when you download them—make sure you don't save them with this. The files are, respectively, a verilog hardware description file, and a file containing many settings for the project, including the mapping between pins and signal names.

For your reference, this circuit simulates a set of traffic lights that cycle through a sequence of Red, Red+Amber, Green, Amber, as illustrated in the first example of Simon Moore's ECAD lecture notes.

Editing the verilog source

You should now open the MAX+plus II program from the Start menu (it's in Teaching Packages | Computer Laboratory and called Altera 96 on the PWF) and, from the File | Open dialogue box, or from the shortcut button, which looks like this:, open tlights.v.

Open dialog box

This will open an editor window in which you can view (and edit!) the verilog file.

Pin and device assignments and the .acf file

There is a little more to be done before the project can be compiled.
  1. First of all the software needs to be told which is the top-level design file for the project and where its configuration file is located; in this case the top-level file is tlights.v, and, provided it is still the current file, this is indicated by choosing File | Project | Set Project to Current File, or with its shortcut, which looks like this: *.
  2. We must also designate a type of chip for the project; this is done from Assign | Device... This should be correct already, but it is as well to check. We will be using an EPF10K20RC240-4. The dialogue box should look like this:

    Device dialog box

    If it doesn't, check that the title bar of the MAX+Plus window indicates the right project name—it should be the same as the path to tlights.v, without the .v extension—for example z:\arm\w1\tlights\tlights. If it isn't, you didn't do step 1 above right.

    Otherwise, you may not have downloaded the tlights.acf file, which is where the assignments should come from. Close the Assign | Device... dialogue box and start again.

  3. Finally, while we're here, take a look at the Assign | Pin/Location/Chip... dialogue box. Again, this should already be correct but note that each of the ports of the top-level module has been assigned a pin number, to correspond with the pins which are actually connected to things on the board. The dialogue box will look like this:

    Pin/Location/Chip dialog box

    When you assign pins in the future, you'll need to make sure you've assigned the right sort of device beforehand.

These assignments are saved in the tlights.acf file. You may wish to open it and have a look. For a large number of pin assignments, it is much easier to edit this file than to use the dialogue box.

Compiling the project

We can now compile the project. Open the Compiler by choosing MAX+Plus II | Compiler, or clicking on the shortcut button, which looks like this: *. Switch off the slightly unstable Quartus Fitter by selecting Processing | Fitter Settings and unchecking Use Quartus Fitter for FLEX 10K and ACEX 1K Devices. Then click on Start.

Once the Quartus Fitter option has been set for a project it does not need to be set again. A quicker way to start a compilation is to choose File | Project | Save & Compile, or click on its shortcut button, which looks like this: *.

The software should now compile the design. It may bring up a messages window to complain about the fact we have made pin assignments. You can ignore this.

In compiling, it will generate many files, of which some are useful, and some aren't! At present we are interested in tlights.sof, which is the object file used to program the FLEX chip.

Introduction to the hardware

Picture of the hardware

In the case there are three boards. The one on the left is the Altera board, which we are using for this week's task; the one on the right is the ARM board, and the board underneath links them together and provides a power supply.

The Altera board has two Programmable Logic Devices; the rearmost one is the one we shall be using, and is called the FLEX; its programmable element is an SRAM, meaning it must be reprogrammed whenever it is first turned on.

The frontmost device is the much less powerful MAX. Its programmable element is an EEPROM, meaning it retains its configuration even when powered off. It has been programmed to protect the ARM when both boards are being used, since it would otherwise be possible to short out the ARM's pins. All signals between the FLEX and the ARM pass first through a resistor, and then the MAX. If the MAX detects that a short has occurred, it turns off all its outputs and displays "Er" (for error) in the LED segments. There is also a switch to separate the two boards: it is the very first switch, on the right of the board. It should be switched up for this lab, to separate the boards. Check this is the case.

The board is programmed via an interface called JTAG. This is very flexible, but we shall only be using it to program the FLEX chip. Check that the jumpers are set correctly for this: from the back, they should be to the left, left, right and right.

The data for the JTAG interface comes down the ribbon cable going to the connector on the back of the box. This short bit of cable is called the ByteBlaster, and it converts parallel data from the computer into the JTAG format. Of course, both the parallel cable and the power cable have to be connected to your computer before anything will work!

Programming the Altera FLEX chip

At last we can program the chip. This is done as follows:

  1. Open the Programmer, by choosing MAX+plus II | Programmer, or by clicking on the shortcut button, which looks like this:
  2. Ensure that JTAG | Multi-Device JTAG chain is switched off..
  3. In the Programmer window, click on Configure. This should download the .sof file to the board, instantiating the circuit, and the LEDs should display a traffic light sequence.

Having done this, play around a little on your own. Ensure that you can connect up the pushbuttons and displays in any way you desire, and that you know how to display numerical values on the LEDs. Build a counter, maybe a backwards counter, whatever. Above all, enjoy the fun!—that's the most effective way to learn at a deep level.

Using the simulator

Next, we'll investigate the use of the simulator, and some of the difficulties associated with using it.

First open the Waveform Editor, using MAX+plus II | Waveform Editor. This produces a blank .scf (simulator control file), which is where we enter the waveforms for the inputs to the simulation, and specify the outputs we wish to monitor.

First of all you need a clock input. To create this, select Node | Enter Nodes from SNF... (the SNF is a file created during compilation - it stands for Simulator Netlist File). Ensure that Inputs is ticked (since we wish to find an input), and that Node/Group contains "*". Click on List. This will produce a list of nodes and groups of the given types and matching the given name ("*" matches anything). We want "ck", so select this from the list and click => to transfer it to the list of nodes to be added to the .scf. The dialogue box should now look like this:

[SNF Node dialog box]

Finally, click on OK. This will add a waveform for the clock input, but it is assigned a logic zero by default. Reselect the waveform by clicking on it in the Name or Value columns. The blue icons on the toolbar on the far left allow you to assign a value to the selected bit of waveform. We want the clock button, which looks like this: .

In the resulting dialogue box, enter a Clock period of 40ns and a multiplier of 1, before clicking OK. If the period field is greyed out, turn off Options | Snap to Grid

Go back to the Enter Nodes from SNF dialogue box (note that you can also open this from the menu produced by right-clicking in the Waveform Editor Window); in a similar way to before, add "|clockdiv:clockdivA|counter", "leds10", "leds13" and "leds16" to the SCF (some of these are outputs, and some groups, so you must turn on these options in the dialogue box to find them). The waveform window should now look similar to this (except for the fact that we say leds1 instead of ledsA):

[Waveform Editor window]

Now save the Waveform file as tlights.scf. Open the simulator by clicking this button: [Simulator button]. Click on Start to start the simulation - this will update the waveform window to show what has happened. Note that the counter counts correctly, but the LED outputs are stuck at 1.

Note that you can click on the waveforms - this should give a vertical blue bar (if you get a small black section, the editor thought you were dragging to make a selection - try again, being careful to click quickly and keep the mouse still.) The Value column gives the values of the signals at the blue bar. You can move the bar between events using the arrow keys or the arrows next to the Ref box.

You will notice that the LED outputs are stuck at 1 in the simulation. Why is that? How can you modify the Verilog so that you can exercise the traffic light sequencer?

Question 1

W1-Q1: Why were the LEDs stuck at 1 in the simulation, and what was your fix?

Having done that, note that the supplied code is not synchronous: it derives a 'slow clock' signal and (yecchhh) uses it to clock the flip-flops of the traffic lights state machine. You know this is wrong. Fix it.

Question 2

W1-Q2: What did you do to turn the traffic lights into a synchronous circuit?

Electronic Dice

Now we'll take the Verilog one stage further. In this project, you should end up with dual working electronic dice; however, it is up to you exactly what form the system will take.

You should aim for a working project that produces two random numbers, each between 1 and 6, each time a button is pressed. You may want to blank the display while the button is being pressed, but that is not necessary. The usual approach to this is to implement a counter which is clocked faster than the eye can see. While the button is pressed, the counter counts, and when the button is released, the current value of the counter is frozen, and appears on the display. As long as the counter is clocked at a sufficiently high speed, the effect should be that of randomness.

Starting a new project

[New File dialog box]

Before we begin, we need to set up the FLEX chip. Download the file dice.acf - this contains many useful settings, like pin assignments. Make a new directory called "w1/dice/", and place this file inside.

To start a new project, load the Max+PLUS II software, and select the menu option File | New. In the dialog box, select Text Editor File. You should be presented with an empty editor window. Use and edit this template for any Verilog file you write. Enter the following skeleton for the top level module (the inputs and outputs mirror the definitions in the .acf file):

module dice(ck, button1, led1, led0);

    input ck;
    input button1;
    output [7:0] led1, led0;


You will also need the hextoleds.v file. Download this into your project directory. It provides a module with the following signature:

module hexToLeds(byte, led1, led0);
where 'byte' is an 8-bit input, and led1 and led0 are the bottom 7 bits of the outputs to the digit displays.

The project code

Undoubtedly, you will want to write a module that counts from 1 to 6. It should take two inputs: the clock, and an input telling it whether to advance or not. Combining these into one input is generally not safe practice: it is not a good idea to gate a clock, as it causes problems with propagation. The module should output a binary value on a three or four-bit data bus. (As a module designer, why would you choose one over the other? Can you see the merits of both choices?)

You can output this counter to bits 0-2 or 0-3 of the hextoleds. You can assign the remaining bits of the hextoleds input to zero.

Save all your code in a file called "dice.v" in the new w1/dice/ directory. Your top-level module must have the same name as the filename (without the ".v"). Compile, download, and run the program.

Useful debugging tips

To obtain additional debugging from the synthesis tool turn on the Design Doctor by opening a compiler window and then use Processing | Design Doctor. Under Processing | Design Doctor Settings... select the FLEX Rules option.

Remember that this Verilog compiler is rather lax: just because something compiled, it doesn't mean that it is bug-free. In some cases you would expect a compiler warning if you do something silly by mistake (e.g. connecting a bus of the wrong width into a module), but you probably won't get any. So it pays to be extra careful.

Remember also that the location at which the compilation stops with an error message may not be the real location of the error. Try checking for syntax errors in the lines above.

Once you've finished

How good a random-number generator do you think this is?

Question 3

W1-Q3: Is there any need to debounce the push button switches in your design? Why? Can you describe a design in which the opposite answer would be more appropriate?

Weekly mini-report

Submit your mini-report before the end of the last timetabled session of this week according to the usual rules.

You must supply a full source listing for the electronic dice, but not for the traffic lights, hextoleds or anything else.

Be sure to include the answers to the three questions in a comment at the end of your source.

Please don't leave submission to the last moment: expect queues for the demonstrators' attention during the last hour. If you haven't submitted by the end of the Thursday session, your next chance is on Monday, but with a penalty of 3 marks per weekday (i.e. 6 marks). Worth avoiding.