Using the Pattern Generator
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 and Digital Discovery's 32 digital channels, you have multiple options for generating whatever digital pattern you choose, from a single signal to a full 16-bit or 32-bit bus.
- Analog Discovery 2 or Digital Discovery
- You may also use the Analog Discovery legacy or the Electronics Explorer Board with WaveForms. There are some slight differences in functionality between the Analog Discovery Legacy, Analog Discovery 2, Digital Discovery, and the Electronics Explorer Board, but nothing that will prevent you from following along if you have one of the other tools.
- If you haven't already installed WaveForms, you can follow the video installation guides.
- A computer with USB port to run the software
- 4-digit, common anode, 7-segment LED numerical display. We will be using a KW4-561 series.
- 4x 100-470Ω resistors
- 2x momentary NO push-buttons or slide switches
- An LED
- A small solderless breadboard
Step 1: Digital Pattern Generator
There isn't much to cover as far as background material for a Pattern Generator, so let's just get started. If you need help getting your Analog Discovery 2 set up and calibrated, Digital Discovery set up, or installing WaveForms, check out the links to get started.
Before we start, note that the Discovery'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 Discovery 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 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 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.
The “Run” button will start the wool. While running, this button converts to the “Stop” button.
For the trigger settings, the drop-down menu displayed in Fig. 9 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 the Manual Trigger button in the bottom left corner of the window.
The wait drop-down menu, displayed in Fig. 11 below, 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 oyu can select “none” to not wait at all.
The run drop-down menu, displayed in Fig. 12, 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 hrs 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.
The repeat drop-down menu, displayed in Fig. 13, 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 “Repeat Trigger”, 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 looks at the signal controls first, as there are several ways to configure them.
Click on the green plus button, displayed below in Fig. 16, 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 Fig. 19 below.
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 on the green plus button to add them to the window on the right.
Highlighting any channel in the right-hand window allows you to remove it by clicking the green subtract button, or you can change its relative location in the bus by clicking the green up or down arrows, displayed in Figs. 23 & 24 below.
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 the 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 position), 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 Fig. 27 below.
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 “Name” box.
The frequency drop-down menu, displayed in FIg. 30 below, 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 the green plus button to add channels.
The red subtract button lets you delete the selected channel, while the up and down arrows let you move the channels up and down in the window.
Click on the green plus button and add DIO 8 and DIO 9 as Inputs.
Add DIO 11 as an Output. Don't click “Add” yet because we have to define the truth table.
If you want to rename the DIO channels, double click on the “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 Fig. 36 below.
Now let's set up the truth table. Click on the “Truth Table” 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'll need to add 4 lines. Click on the green plus button to do that. As we've seen before, the red subtract button will delete the selected line, while the green up and down arrows will move the selected line up or down. In column A, enter the values 0, 0, 1, and 1, top to bottom. In column 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 Fig. 39 below.
Once everything is filled in, click on the “Add” button to add the ROM Logic channels to the grid. The grid should now look like Fig. 40 below.
Before we look at the individual channel settings, let's go over the remaining channel controls at the top.
The red subtract button with the drop-down menu allows you to 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.
The Edit drop-down button, displyed in Fig. 42, lets you edit 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 buses, and the truth table tab for ROM Logic. You can also access the properties window for each channel by clicking the icon displayed in Fig. 43 in the grid next to each channel name. Clicking on Fig. 44 will open the parameters window.
The Show drop-down menu 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.
“Auto” lets you choose between auto or manual scaling of the plot time base.
With manual selected, the “show” drop-down lets you adjust the time scale, while “From” lets you set the start time for the window.
Next is the grid itself. We've alluded to a few of the parts already, so let's look at the channel parameter columns.
Step 4: Defining Channels
The first channel 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. (Our testing with the Analog Discovery 2 shows Z at just a few miliivolts, but not a true 0 nor 1 value. The Digital Discovery is similar) 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 Discovery 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.
The “Start” with the drop-down menu is the initial state of the signal when the tool starts running.
“Low” sets the number of counts the signal will stay low.
“High” 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.
“Counter Init” 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.
“Divider” divides the 100 MHz system clock on the FPGA chip inside the Discovery. This divided clock value is then used as the clock signal to start counting.
“Divider Init” 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 is 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.
“Samples” 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 teach sample individually, which will then be reflected in the plot at the bottom.
“Import” 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 “Close” to close the custom editor.
Step 5: Defining Channel, Part 2
Buses 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). “Length” 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 Fig. 69 below.
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 the vertical dotted section, displayed in Fig. 70 below, 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” (ob11111101) to set segment B. Row 2 is set to “251” (0b11111011) to set segment C. The next 5 rows are set to “255” (ob11111111) to keep all segments off. Row 8 is set to “127” (ob01111111) 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. We've included two images to show the full table below with both decimal and binary values.
Connect the digital output pins on the Discovery header to the 7-segment display according to the manufacturer specs. For the KW4-561 series of displays, we have ours connected as shown below in Fig. 73 & 74.
Click “Run” 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 lor, C outputs as a low signal.
Let's set up a quick circuit to show this in action. Connect the circuit as shown in Fig. 76 below.
And a short gif of the circuit in action.
Step 6: That's It!
As you can see, the Pattern Generator on the Discovery is a powerful tool for helping test and analyze high speed digital circuits.