Introduction: Using the Pattern Generator With the Analog Discovery 2
A pattern generator is used to generate a user defined pattern of digital logic high/low signals or pulses. With the Analog Discovery 2's 16 digital channels, you have multiple options for generating whatever digital pattern you choose, from a single signal to a full 16-bit bus.
For this Instructable you will need:
- 4-digit, common anode, 7-segment LED numerical display. I'm using a KW4-561 series.
- 4X 100-470Ω resistors
- 2X momentary NO pushbuttons or slide switches
- an LED
- small solderless breadboard
-Waveforms 2015 software
- a computer with USB port to run the software
*You may also use the original Analog Discovery or the Electronics Explorer Board with Waveforms 2015. There are some slight differences in functionality between the AD1, AD2, and EEBoard, but nothing that will prevent you from following along if you have one of the other tools.
Step 1: Digital Pattern Generator
There isn't much to cover as far as background for a Pattern Generator, so let's just get started. If you want some help getting your AD2 set up and calibrated, or installing Waveforms 2015, check out this quick start I'ble collection.
Before we start, note that the AD2's digital channels are not meant to be used as sources for large loads. Don't connect much more than a single LED and resistor directly to the channel. If you need to drive larger loads, the channels can be used to trigger high current drivers such as MOSFETs, H-bridges, etc. but are not to be used as primary sources.
Once you have your AD2 and Waveforms all set up, open the Pattern Generator by clicking on the "Patterns" button.
The Pattern Generator window will open.
There are three main tool bars along the top, the first with "File", "Control", and "Window" options.
Under "File" you'll see several options.
"New Patterns" lets you open a new instance of the Pattern Generator.
You can open a new, empty instance, or you can clone all of the current settings into a new instance. Only one instance can be used at one time. The other instances will be on standby when one is in use.
You can "Save" the current pattern generator settings, or "Open" a previously saved project.
"Export" lets you save the current pattern generator preview plot data, either as an image of the window in most common formats, e.g. *.bmp, *.jpg, *.tif, etc., or as a data file with the plot window information in either *.csv, *.txt, or *.tdms formats.
"Close Patterns" will close the pattern generator window. This will not clear the current settings as long as you don't close Waveforms 2015 completely. Just click on the "Patterns" button again and the window will pop back open with all of the same settings.
Under "Control", you have access to the tool's Run and Stop commands.
"Window" lets you switch between any tool windows currently open, the Waveforms 2015 welcome window, or the Help window.
Step 2: Run/Stop and Trigger Options
The next tool bar is for running/stopping the tool, as well as setting the trigger.
will start the tool. While running, this button converts to to stop the tool.
For the trigger settings, lets you determine what type of trigger source you want. You can select "none", or use some external signal, or even one of the other Waveforms tools, like the Oscilloscope. You can also trigger the signal manually by setting the trigger to "manual" and then clicking on in the bottom left corner of the window.
lets you set a wait time. Once the trigger condition has been met, the signal will enter the idle condition, outputting the idle value for that amount of time. Once that time has expired, the pattern generator begins running. Any time from 20 ns to 24 hr is valid, or you can select "none" to not wait at all.
lets you set how long the pattern will run once the Pattern Generator has been triggered and any wait time has expired. Any time from 20 ns to 24 hr can be selected, or you can choose "continuous" to not have the pattern ever reset. Be aware that choosing "continuous" can introduce an accumulated rounding error to the pattern output over time, resulting in a phase shift. Setting your run time to some integer multiple of your pattern time base (e.g. for a 1 kHz signal, enter a 1 ms run time) will regularly reset the pattern output and any accumulated error will continuously be reset to 0.
lets you set how many times you want the set pattern to repeat before returning the outputs to idle state. You can set this to any value between 1 and 30,000 cycles, or choose infinite.
If you check , the Pattern Generator will have to be triggered for the number of cycles you entered in the "Repeat" box. For example, if you have "manual" selected, enter "5" in the repeat box, and check "repeat trigger", you will have to click the manual trigger button at the bottom five times. The Pattern Generator outputs will idle and arm between triggers, and then idle and reset to ready state after 5 triggers. By un-checking the box, the Pattern Generator will automatically output the defined pattern for the set number of cycles without the need of additional trigger instances.
Step 3: Signal Control Settings
Below the trigger settings, are the signal controls, as well as the plot window settings. Let's look at the signal controls first, as there are several ways to configure them.
Click to add a single signal, a bus, or ROM logic.
Clicking "Signal" opens a small window that lets you pick which channels you want to add as single signals. Any channel can be added in any order. You can add several channels at once by holding either the "Shift" or "Ctrl" buttons on your keyboard and clicking on additional channels to highlight them. For our example, let's add 4 single signals, channels 15-12.
Click "Add" to add the selected channels to the list. It should look like this.
When the new channels appear in the grid, you'll see various options to further define the channel. Don't worry about these options just yet. We'll get to defining each channel in the next step.
Now let's look at adding a bus. Clicking "Bus" opens the bus configuration window.
At the top of the window you can edit the name of your bus in the "Name" box. Below that in the left hand window, select which channels you want to add to your bus. Any channel not already in use can be chosen. You can add several channels at once by holding either the "Shift" or "Ctrl" buttons on your keyboard and clicking on additional channels to highlight them. Once you have your channels selected, click to add them to the window on the right. Highlighting any channel in the right hand window allows you to remove it by clicking , or you can change its relative location in the bus by clicking or .
Using the "Format" box, you can change the way you numerically enter and display the bus data. There are a number of options. More on that in a bit.
The "Endianness" box lets you choose between Most Significant Bit (MSB) or Least Significant Bit (LSB). Selecting "MSB" will assign the most significant bit to the top channel displayed in the window on the right. Conversely, selecting "LSB" assigns the least significant bit to the top channel displayed in the window on the right. More on that in a bit as well.
The MSB and LSB boxes let you determine the indices used for the bus values. If you are familiar with writing computer code binary manipulation, it's similar to bit-shifting a value. Additional place-holder bits will be added to fill in. For example, you choose a 4-bit bus, but set the MSB box to 7 (the LSB box will auto adjust to 4). The numerical representation of that bus in the plot window will be 8 bits (b00000000 → 4 0's added to the number in the LSB postion), not 4 bits (b0000), even though you are only putting a signal on 4 I/O channels. MSB can have a value as high as 31, while LSB can be as low as -32.
For now, let's add an 8-bit bus, with decimal format and MSB endianness. The MSB and LSB boxes will default to "7" and "0" respectively, which is fine for our example. Let's name the bus "ABCDEFGp", since this will be the segment selection bus for our 7-segment display.
Click "OK" to add the bus to the grid. Your grid should look like this.
The last signal option is ROM Logic, which can be used to visualize truth tables and test state machine logic. Select "ROM Logic" to open the configuration window.
At the top you can rename the ROM Logic channel in the box.
lets you determine the sample frequency of the inputs. If the change of state on the input happens faster than the sample frequency, the output will likely not register the correct value. Be sure to set your sample frequency higher than your expected input frequency.
On the left you have the "Inputs" window, while on the right you have the "Outputs" window. For both windows, click on to add channels. lets you delete the selected channel, while and let you move channels up and down in the window.
Click and add DIO 8 and DIO 9 as Inputs.
Add DIO 11 as an Output. Don't click yet because we have to define the truth table.
If you want to rename the DIO channels, double click on "DIO x" under the "Name" column, where x is the DIO number. For our example, let's assign "A" to DIO 9, "B" to DIO 8, and "C" to DIO 11. Once done, the ROM Logic configuration window should look like this.
Now let's set up the truth table. Click on the tab to open the truth table editor.
Let's do a simple AND truth table. With two inputs, there are 4 possible combinations, so we well need to add 4 lines. Click to do that. As we've seen before, will delete the selected line, while and let you move the selected line up or down. In column A, enter the values 0, 0, 1, and 1, top to bottom. In colmun B, enter 0, 1, 0, and 1, top to bottom. Lastly, in column C enter 0, 0, 0, and 1, top to bottom. The table should look like this.
Once everything is filled in, click on to add the ROM Logic channels to the grid. The grid should now look like this.
Before we look at the individual channel settings, let's go over the remaining channel controls at the top.
lets you delete the selected channel, or you can clear the entire grid. With a channel highlighted, you can also press "Delete" on your keyboard to remove that channel.
lets you edit either the Properties or the Parameters of the selected signal. Clicking "Properties" will open A) the name and channel select for a signal; B) the name, channel select, format, endianness, etc. for a bus; C) the properties tab for ROM Logic. Clicking "Parameters" will open the signal type editor window (we'll cover this next) for both signals and busses, and the truth table tab for ROM Logic. You can also access the properties window for each channel by clicking in the grid next to each channel name. Clicking will open the parameters window.
lets you determine which data you want to show in the grid columns. Not all columns will be used for all signals, but some will use all of them.
On the right side of the Patterns window is the plot window showing the defined patterns. At the top of that window, there are three options for editing the window. lets you choose between auto or manual scaling of the plot time base. With manual selected, lets you adjust the time scale, while lets you set the start time for the window.
Next is the grid itself. I've alluded to a few of the parts already, so let's look at the channel parameter columns.
Step 4: Defining Channels
The first column is "Output". Depending on the type you have selected in the type column, there will be up to four options in this drop down menu. "PP" stands for push/pull, which is a full swing 1/0 signal. Next is "OD", which means open drain. The signal will swing between 0 and Z, which is an undetermined value by definition. (My testing with my AD2 shows Z at just a few millivolts, but not a true 0 nor 1 value.) Next we have "OS", which stands for open source. The signal swings between 1 and Z. Last is "TS" which is three-state. The signal can be either 1, Z ,or 0.
The next column is "Idle". You can set the value that the AD2 will output on the DIO pin while the tool is not running. This setting is independent of the other settings, i.e. you can output a 1 while idling even though you have the channel set to open drain, so be aware of how this is set to avoid shorting. The possible settings are "Initial", 0, 1, or Z.
Next is the "Type" column, followed by up to three Parameter columns. Here you can set what type of signal you want to output, along with its possible parameters. Single channel signals can be set to:
- constant, where the signal is set to 1, Z, or 0 and holds that value indefinitely.
- clock, which will output a square wave according to the set frequency and the output type selected. Duty cycle and phase can also be selected.
- pulse, which changes the output state of the channel based on the system clock division and the counters set. This works just like the clock signal type, but gives you much more control and customization over the signal.
is the initial state of the signal when the tool starts running. sets the number of counts the signal will stay low. sets the number of counts the signal will stay high. Dividing "high" by the sum of "low" and "high" will determine your duty cycle. Adding the "low" and "high" time values will determine your total period. is the counter's initial value and is just a programmable delay, which can be seen in seconds to the right. When the initial counter value is reached, the signal will output the "start" state and begin counting the high/low state values. divides the 100 Mhz system clock on the FPGA chip inside the AD2. This divided clock value is then used as the clock signal to start counting. sets the number of system clock cycles will be waited before the divider starts and the low/high values are counted. It works like a system delay instead of a counter delay. Each setting has a time value associated with it, as well as min and max settings, all of which are displayed to the right of the setting box.
- random, which is just what it sounds like. The computer generates a random bit string. You can adjust the frequency at which the bits change state.
- custom, which lets you define your own signal as you want it.
determines the sample frequency for the signal. sets the number of samples your signal can have. Once you determine how many samples you want to use, you can click on the small plot window below to set each sample, but with many samples, that can be difficult. The data table on the right side of the window will allow you to set each sample individually, which will then be reflected in the plot at the bottom. lets you import a saved custom Patterns file, or you can export the custom data as a *.csv, *.txt, or *.tdms file, or as an image of the custom editor window in most common image file formats. Click to close the custom editor.
Step 5: Defining Channel, Part 2
Busses have the same type options as single signals, but with some additional counter options that can only be accomplished with a synchronized bus signal. The counter options are:
- Binary counter, which is a simple binary counter, or Gray counter, which counts up/down by only allowing one bit to change at a time between sequential numbers. Click here for more on Gray code/counters. Both Binary and Gray counters have the same settings options. You can set the frequency, which is the rate at which the LSB will toggle high/low, the initial value where the counter will start for the first count cycle, and whether it counts up or down. The counter can count up to or down from 2n, where n is the number of channels assigned to the bus. Once the max value (up) or 0 (down) is reached, the counter will start over from the beginning, ignoring the defined initial value from then on.
- Johnson counter, also known as a ring counter and is a variation of gray code, which adds one channel at a time, starting with either the LSB (left direction) or MSB (right direction), until all channels are on. Each channel is then turned off one at a time, again starting with either the LSB or MSB, until all channels are off. The cycle then repeats. There are a total of 2n possible combinations for a Johnson counter, where n is the number of channels assigned to the bus. Click here for more on Johnson counters.
- walking 0/1 counters, which "walk" the respective counter value sequentially through all of the bits, one at a time. The frequency determines the rate at which the bits change state. You can set the walk to start with either the LSB (left direction) or MSB (right direction). lets you set how many counts the 0/1 will last, from 0 up to n, where n is the number of channels assigned to the bus.
Now that we've gone through all of that, let's get back to our example. Using the "parameters" window for each channel, set DIO 15-12 to "PP" output, "0" Idle, "Custom" type, "200 Hz" frequency, and "4" samples. For DIO 12, set sample 1 to "1" and leave the other samples to "0".
The remaining 3 channels are set similarly. For DIO 13, set sample 2 to "1". DIO 14, set sample 3 to "1", and for DIO 15 set sample 4 to "1". These will be tied to each of the four digits. It may help to rename them to identify their respective digit, with DIO 12 tied to digit 1, DIO 13 to digit 2, DIO 14 to digit 3, and DIO 15 to digit 4. Once all set, the four single channels should look like this.
For the bus "ABCDEFGp", open the "Parameters" window for the bus. Set the bus to "Custom" type, "PP" output, "1" idle, 1.6 kHz frequency and "32" samples. The easiest way to set this bus is to use the data table. Click and drag it to the left to extend the data table. Starting with row 1 under column "ABCDEFGp", you can enter the bus value for that sample. How you enter this value is determined in the bus "properties" window. We selected "decimal" format before. You can also set each bus channel individually if you choose.
If you're not familiar with multiplexing LEDs, the idea is to turn only one segment on at a time, but cycle through all of them so fast that you can't see them flashing. The first digit will display the number "1" and the decimal point. To make a "1" on a 7-segment, we need to light segments B and C. Row 1 is set to "253" (0b11111101) to set segment B. Row 2 is set to "251" (0b11111011) to set segment C. The next 5 rows are set to "255" (0b11111111) to keep all segments off. Row 8 is set to "127" (0b01111111) to turn on the decimal point. Since there are a total of 8 LEDs, row 9-16 are the segment assignments for digit 2. Rows 17-24 are for digit 3, and rows 25-32 are for digit 4. I've included two images to show the full table below with both decimal and binary values.
Connect the digital pins on the AD2 header to the 7-segment display according to the manufacturer specs. For the KW4-561 series of displays, I have mine connected as shown.
Click to run the display. You should see the following.
If you have a common cathode display, make all of the same connections and signal definitions, but reverse ALL of the bit assignments for all 4 signals and the entire bus table.
Try to make the 4 separate signals used for the digits into one 4-bit bus.
Now let's take a quick look at the ROM Logic channel we defined earlier. We set the truth table to match the output of a simple AND logic gate, where if both channels A and B register a high value, then C will output a high value. If either A or B or both are low, C outputs a low signal.
Let's set up a quick circuit to show this in action. Connect the circuit as shown below.
And a short gif of the circuit in action.
Step 6: That's It!
As you can see, the Pattern Generator on the Analog Discovery 2 is a powerful tool for helping test and analyze high speed digital circuits.
As always, thanks for reading. If you have questions, please ask them in the comments below, though PMs are always welcome as well. You just never know when someone else has the same question and that way we can all learn and help each other get better. Have fun building!
Also, please check out the Digilent blog where I contribute from time to time.