Skip to content

Digital Pattern Generator DPG1 Guide

sfifteen edited this page Jan 6, 2020 · 1 revision

Welcome to the Digital_Pattern_Generator_DPG1 wiki!

Table of Contents

Firmware

The firmware emulates a virtual serial device, and understands currently (as of svn-4) the following commands:

 CONFIG <value>
 STATUS?
 WRITEW <v1> <v2>....
 *IDN?

This interface is not very nice yet, but it allows to program the table with text-based code or scripts.

 CONFIG? queries the last configuration value
 NIMOUT <value>
         selects mode for NIMOUT output 0: outline[24], 1: delayed outline[24], 2: masterclock, 3: refclk
 NIMOUT? queries setting of NIMOUT
 HOOKS <value>
         sets the value of the two hook bits (value ranges from 0...3)
 HOOKS?  queries last value set for hooks
 PARAM <v0> <v1>....
         write 16 bit parameters in parameter registers, starting from register 0
 TTL     sets the input sensitivity to TTL level (positive polarity)
 NIM     sets the input sensitivity to NIM level (negative polarity)
 LEVEL?  queries the input polarity (0: NIM, 1: TTL)
 TSTAT?  extracts the readback pattern in outline[31:28] from the status word
 INSTAT? extracts the status of the input lines from the status word
 HOLDADR forces the row address pointer to the startaddress value (0 by default)
 RUN     releases the table address pointer and enables the sequencer
 RAMPROG swiches to ram programming mode (as opposed to parameter writing)

Use the Python based library for a quick start to the device. Otherwise, refer to the guide below to write a series of WRITEW four-word command to program the sequence of I/O. There are four 16-bit words per WRITEW command, each with their own function.

Before writing the WRITEW words, one can first set the state and running parameters of the device, with CONFIG and PARAM command. They are described below.

CONFIG (Configuration) register

This register determines the overall behavior of the device. Its bits have the following meaning:

Bits what interpretation
9:8 tablehooks these two bits can be used in conditional jumps in the table entry to redirect the sequence to different branches
7:6 clockselect these two bits determine the master clock selection for the table sequencer according as shown below:
value clock source
00 100 MHz, with automatic reference clock selection (internal, or external reference if its freqency is between 9 and 11 MHz)
01 100 MHz, always use external 10 MHz reference clock
10 100MHz, always use internal reference clock
11 use external clock directly as table master clock
5:4 auxlineselect Determines the NIM output line on the main board according to the following selection:
value NIM output
00 value of bit 24 of a table entry
01 value of bit 24 of a table entry, delayed by half a table master clock cycle
10 main table clock
11 reference clock input
3 parameterwrite if set to 1, data is written to parameter register bank. When 0, data is written to the pattern RAM
2 addressreset when set, the table address is loaded with the startaddress register content. Otherwise, the next address is generated from the table entry (direct or conditional jumps
1 level input line discipline. 0: input are NIM levels, 1: inputs are TTL level
0 tablereset RAM register reset; not clear if this is needed in conjunction with addressreset

STATUS? (Status) register

This 16 bit wide register reflects the status of the pattern generator; it can be read out at any time, with the following interpretation of the bits:

bits What Interpretation
10 level reflects the setting of the level bit (NIM:0 or TTL:1)
9 PLL_lock internal PLL lock status (i.e., when set, it gives good 100 MHz )
8 CLK_OK external clock status. Is set if external frequency is between 9 and 11 MHz
7:4 inlines reflects the status of the four input lines, corrected for the respective discipline (TTL or NIM); 1 means line is active
3:0 patternstatus reflects the pattern status lines stored in each table entry

PARAM (Parameter) registers

There are 8 words of 16 bit wide parameter registers which can be set when the PARAM line if the status register is set. The parameters are written consecutively to the write address, which is reset to 0 at a write to the configuration register, and incremented by 1 after each 16 bit word write. The following parameters are currently implemented:

Write address Register Comment
0 tablestart Start address of the RAM. When the addressreset bit in the configuration register is set, the value of this register is loaded in the read address pointer of the lookup table.
1...4 extcntload Reload value for the four counters that get decremented through external events
5..8 intcntload Reload value for the four internal counters that get decremented through a special command. This can be used to set up loops

WORDW (Pattern) RAM

This is an internal RAM bank, organized in 512x64 bits for the table replay, and in 2048x16 entries for writing data to it. The content is written consecutively to a write address, which is reset to 0 at a write to the configuration register, and incremented by 1 after each 16 bit word write. The table gets replayed by the internal sequencer. Write address 0...3 correspsond to table row 0, write address 4...7 to row address 1, write address 8..11 to row address 3 and so on. The bits have the following meaning:

Write addr What Interpretation
row*4+0 outlines[15:0] determines the output pattern for two of the 8-bit outputs. Port 0 represents outlines[7:0], and Port 1 represents outlines[15:8]
row*4+1 outlines[31:16] outlines[23:16] determine the Port 2 output lines. outlines[24] can be connected to the NIM output on the main board, depending on the setting auxlinesel in the configuration register.
row*4+2 timelines Determines the wait cycles before the sequencer jumps to the next address. A value of 0 means that the next table row is played after 1 master clock cycle, or 10ns for the standard 100 MHz clock. For example, an entry of 9999 corresponds to a switch to the next table row after (9999+1)*10ns = 100μsec for a 100 MHz clock. Note that the largest value is 65535, corresponding to 655.36μs duration for a table row (for a 100MHz master clock).
row*4+3 addresslines Determines the next row for the table sequencer, or executes a special command (in which case, the row address following the current one is chosen as next row).

Address line interpretation: The choice of the next table entry, and some special events, are determined by the 16 bit wide addressline register in each table row. The bit pattern is interpreted as shown below:

Action bits 15:12 bits 11:8 bits 7:4 bits 3:0
unconditional jump 0 next row address
special command 1 decrement internal counter 3:0 load internal counter 3:0 load external counter 3:0
conditional jump on hook 0 2 address of next row entry if tablehook[0] is set (otherwise, the next address is chosen)
conditional jump on hook 1 3 address of next row entry if tablehook[1] is set (otherwise, the next address is chosen)
conditional jump on input line 1 4 address of next row entry if inline 1 is set (otherwise, the next address is chosen)
conditional jump on input line 2 5 address of next row entry if inline 2 is set (otherwise, the next address is chosen)
conditional jump on input line 3 6 address of next row entry if inline 3 is set (otherwise, the next address is chosen)
conditional jump on input line 4 7 address of next row entry if inline 4 is set (otherwise, the next address is chosen)
conditional jump on external counter 1 8 address of next row entry if extcounter 1 is nonzero (otherwise, the next address is chosen)
conditional jump on external counter 2 9 address of next row entry if extcounter 2 is nonzero (otherwise, the next address is chosen)
conditional jump on external counter 3 10 address of next row entry if extcounter 3 is nonzero (otherwise, the next address is chosen)
conditional jump on external counter 4 11 address of next row entry if extcounter 4 is nonzero (otherwise, the next address is chosen)
conditional jump on internal counter 1 12 address of next row entry if internal counter 1 is nonzero (otherwise, the next address is chosen)
conditional jump on internal counter 2 13 address of next row entry if internal counter 2 is nonzero (otherwise, the next address is chosen)
conditional jump on internal counter 3 14 address of next row entry if internal counter 3 is nonzero (otherwise, the next address is chosen)
conditional jump on internal counter 4 15 address of next row entry if internal counter 4 is nonzero (otherwise, the next address is chosen)

Sample WORDW Script

Simple repetitive sequence

Desired pattern (time axis is not to scale):

Code to send to card, assuming a standard clock frequency of 100MHz:

 # Set device to programming mode: reset table, reset RAM, program params
 config 13
 writew 0; # basic address is 0
 config 5; # switch to RAM write
 
 # This is the RAM sequence
 writew 1,256,9,1; # channel 1 pulse, sync pulse, 100nsec
 writew 0,0,989,2; # off for 9.9usec
 writew 2,0,9,3, 0,0,89,4, 2,0,9,5; # 2 pulses, total len 1.1usec
 writew 0,0,889,6; # pause for 8.9 usec
 writew 4,0,9,7, 0,0,89,8, 4,0,9,9, 0,0,89,10, 4,0,9,11; # 3 pulses, 2.1us
 writew 0,0,7789,0; # wait 77.9 usec, go back to 0 
 
 # start pattern
 config 0

Switching between different tables through external lines

Code to send to the card, assuming a 100MHz internal clock:

 config 15; # parameter write
 writew 0; # reset address to 0
 
 config 7; # write to RAM, set addr counter to 0
 writew 1,256,9,1;   # row 0: 100nsec, unconditional jump to row 1
 writew 0,0,9,16384; # row 1: 100nsec, conditional jump to row 0
 writew 1,256,49,3;  # row 2: 500nsec, uncond jump to row 3 
 writew 0,0,9,16384; # row 3: 100nsec, conditional jump to 0
 writew 0,0,39,2;    # row 4: 400nsec, unconditional jump to 2
 
 config 2; # run the sequence

Use of internal variables for a loop

The following code uses two parameter registers: One to implement a burst pulse counter, the other one to have an extended delay in multiples of 1ms:

 config 13
 writew 0, 0,0,0,0, 10,2; # startrow 0, no external regs, 10 pulse burst, 2x 1ms wait 
 
 config 5
 
 writew 0,0,0,4144;      # row 0: load burst counter, load wait counter: 0x1030
 writew 1,256,9,4352;    # row 1: 100 nsec on, decrement burst cnt (0x1100)
 writew 2,0,9,49153;     # row 2: 100 nsec off, cond jump to row 1 on nonzero cnt
 writew 4,0,49999,4608;  # row 3: 500 usec, decrement cnt2 (0x1200)
 writew 8,0,49999,53251; # row 4: 500 usec,  jump to row 3 on nonzero (0xd003)
 writew 16,0,0,0;        # row 5: uncond jump to row 0
 
 config 0; # start sequence

In this demo code, the pulse burst ends up on the NIMOUT connection, and outputs 0..4 reflect the position in different rows.

Branching between tables, depending on count rate

The following code measures the number of events in a 10ms wide time interval; if the number exceeds a value of 100, it switches on the NIMOUT line, and sets the table status to 1 (can be tested with TSTAT?). The code implements two such loops, and its output status reflects the finding of the last 10ms test periode. Take note that the example below uses PARAM commands and the like, instead of config commands. This works properly only as of firmware svn-9.

 param  0,100,0,0,0,10;    # startrow 0, 100 into ext cnt, 10 into int cnt 
 
 holdadr; ramprog;         # for programming pattern
 # Stay in this loop if counts were low (NIMOUT=0)
 writew 0,0,0,4113;        # row 0: load int and ext counters (0x1011) 
 writew 1,0,49999,4352;    # row 1: 500 usec, decrement int cnt1 (0x1100)
 writew 2,0,49999,49153;   # row 2: 500usec, jmp to 1 on nonzer int cnt (0xc001)
 writew 4,0,0,32768;       # row 3: 10nsec, jump to 0 on nonzero ext cnt (0x8000)
 
 # Stay in this loop if counts were high (NIMOUT=1, tablestat=1)
 writew 8,4352,0,4113;      # row 4: load int and ext counters (0x1011) 
 writew 16,4352,49999,4352; # row 5: 500 usec, decrement int cnt1 (0x1100)
 writew 32,4352,49999,49157;# row 6: 500usec, jmp to 5 on nonzer int cnt (0xc005)
 writew 64,4352,0,32768;    # row 7: 10nsec, jump to 0 on nonzero ext cnt (0x8000)
 
 writew 64,256,0,4;         # row 8: 10ns, unconditional jump to row 4 
 
 run;                       # start sequence