不同通道的发散和跳跃计数

Counting of different channels diverge and jumps

我正在尝试实现一个计数模块。我的基本设置: FPGA(Digilent 的 Arty 和 Xilinx Artix-35T)有两条 BNC 电缆连接到连接到信号发生器的 IO 端口,并通过 USB/UART 连接到 PC 以进行读取。我的信号发生器产生 1 Hz 的一些 TTL 信号。

我现在想计算通道 1、通道 2 中的事件数量以及通道 1 和通道 2 的重合度。虽然基本原理有效,但我看到通道 1 和通道 2 是分开的,即使它们具有相同的输入(通过 BNC-T 连接器)。此外,有时其中一个输出通道会跳跃 - 在任一方向上,见图。 紫色通道 ("Channel 1") 的斜率与绿色 ("Channel 2") 不同。巧合也使这里有两个小的有损跳跃。

我的顺序计数代码看起来像

reg [15:0] coinciInt [(numCoincidences -1):0]; // internally store events
always @(posedge clk or posedge reset)    // every time the clock rises...
begin
    signalDelay <= signal;                // delayed signal for not counting the same event twice

    if(reset)                             // reset
    begin
        for(i=0;i<numCoincidences;i=i+1) 
            coinciInt[i] <= 16'b0;
    end
    else                                  // No reset
    begin
        for(i=1;i<numCoincidences;i=i+1)   // loop through all coincidence possibilities:
        begin 
            if( ((signal & i) == i) && ((signalDelay & i) != i) )   // only if signal give coincidence, but did not give before, it's a coincidence
            begin                         // "(signal & i) == i" means that "signal" is checked if bitmask of "i" is contained: 
                                          // ((0011 & 0010) == 0010) is true, since 0011 & 0010 = 0010 == 0010  
                coinciInt[i] <= coinciInt[i] + 1'b1;    // the i-th coincidence triggered, store it
            end
        end
    end
end // end of always

assign coinci = coinciInt;  // the output variable is called coinci, so assign to this one

请注意,所有事件都在寄存器 coinci - 巧合以及 'single events' 中。理想情况下,coinci[1] 应该存储通道 1 的事件,coinci[2] 存储通道 2 的事件以及 coinci[3] 1 和 2 之间的巧合,因为通道被标记为 1,2,4,8,...,2 ^n 和巧合分别相加。 coinci[0] 用于某种校验和,但现在是 off-topic。

对于缺失的计数有什么想法吗?对于不同的斜坡?

非常感谢

编辑 1

@Brian Magnuson 指出了元稳定性问题。使用 multi-buffered 输入解决了发散通道的问题。这很好用。虽然我不完全明白其中的原因,但到目前为止我也没有在巧合通道中看到任何跳跃。你可能为我节省了很多时间,谢谢!

我怀疑是元稳定性问题。您在 ch1/ch2 上的输入脉冲可能与您使用的系统时钟不同步。 See here.

正因为如此,您有时可能会捕获计数器更新 'mid-stride' 可以说这会导致意外行为。

要解决此问题,您可以将输入翻转两次(称为双列同步器),然后再将它们输入您的其余逻辑。通常多位同步需要更仔细的处理,但在您的情况下,每个位都可以独立处理。