High speed serial trigger using Spartan-6

The serial trigger includes a shift register and a comparator. When the content of the register matches the expected pattern, the trigger output is set to high.

First, how to create a simple 8-bit shift register in verilog?

Implementation of a simple 8-bit shift register

module shift_reg(
        clk,            // clock
        clear,          // clear register (0=no clear, 1=clear)
        shift_in,       // bit to shift in the register
        d_out           // current content of the register
        );

input                   clk;
input                   clear;
input                   shift_in;
output [7:0]    d_out;
reg    [7:0]    d_out;

always @(posedge clk) begin
        if(clear)       d_out <= 0;
        else            d_out <= {d_out[6:0], shift_in};
end

endmodule

Note about Xilinx ISE: this verilog implementation is converted into schematic symbol using the "Create Schematic Symbol" item from the "Processes" window (on the left).

The complete component is very simple:

Note about Xilinx ISE: pin assignment for inputs (clock, clear, shift_in), and output (trigger) is done via PlanAhead. Just be careful to select a dedicated clock input pin for "clock". See [UG382] (v1.9) at p.15-16 for a list of pins optimized to clock input.

The "Schematic" tab shows the way the verilog description was implemented: using a chain of eight FDR (D Flip-Flop with Synchronous Reset and Set and Clock Enable) for the 8-bit shift register, and two LUTs for the comparison with the pattern. The pattern itself is stored in the LUTs. Hence, not only a fixed pattern (e.g., 0b11110000) can be matched, but also any combination of patterns (e.g., 0b11110000 or 0b11110001).

To make partial reconfiguration easier, the LUTs of the "pattern_match" sub-component can be constrained to a fixed location in PlanAhead. To do so, (in "Device" tab) add a BEL constraint to each LUT you want to fix.

PlanAhead will generate plain-text constraint in the constraints file (.ucf) of the project:

# PlanAhead Generated physical constraints
INST "pattern_trigger_1/trigger<7>" BEL = C6LUT;
INST "pattern_trigger_1/trigger<7>" LOC = SLICE_X12Y61;
INST "pattern_trigger_1/trigger<7>_SW0" BEL = B6LUT;
INST "pattern_trigger_1/trigger<7>_SW0" LOC = SLICE_X12Y61;

You can refer to previous post for a method to find the LUT equation in the bitstream (i.e., row, major, minor, idx "coordinates"). Then, the live reconfiguration server can be used to update the pattern of the trigger comparison while running the FPGA.

About reset

Should the "clear" input be synchronous or asynchronous? I have discovered that this question is an old debate in FPGA design. There are many documents about it such as [1] and [WP272] .

Practical usage

The synthesis software of the Xilinx design chain rates this design at more than 800MHz. I have no way to actually measure the maximum triggering speed.

There is an usage issue with this simple design. Let us say that we would like to match the pattern 0b11111111 on a 8-bit SPI bus. Since there is no information about the current "load level" of the shift register, the current design will also trigger any sequences of 8 following bits at one, no matter their alignment on transmission bytes. Example: this sequence 0b00000111 followed by 0b11111000 will trigger as well.

See next post for an improvement of this serial trigger addressing this issue.

[1]Synchronous Resets? Asynchronous Resets? I am so confused! How will I ever know which to use? http://www.sunburst-design.com/papers/CummingsSNUG2002SJ_Resets.pdf
[UG382]Spartan-6 FPGA Clocking Resources http://www.xilinx.com/support/documentation/user_guides/ug382.pdf
[WP272]Get Smart About Reset: Think Local, Not Global http://www.xilinx.com/support/documentation/white_papers/wp272.pdf
[WP309]Targeting and Retargeting Guide for Spartan-6 FPGAs http://www.xilinx.com/support/documentation/white_papers/wp309.pdf