不同通道的发散和跳跃计数
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' 可以说这会导致意外行为。
要解决此问题,您可以将输入翻转两次(称为双列同步器),然后再将它们输入您的其余逻辑。通常多位同步需要更仔细的处理,但在您的情况下,每个位都可以独立处理。
我正在尝试实现一个计数模块。我的基本设置: FPGA(Digilent 的 Arty 和 Xilinx Artix-35T)有两条 BNC 电缆连接到连接到信号发生器的 IO 端口,并通过 USB/UART 连接到 PC 以进行读取。我的信号发生器产生 1 Hz 的一些 TTL 信号。
我现在想计算通道 1、通道 2 中的事件数量以及通道 1 和通道 2 的重合度。虽然基本原理有效,但我看到通道 1 和通道 2 是分开的,即使它们具有相同的输入(通过 BNC-T 连接器)。此外,有时其中一个输出通道会跳跃 - 在任一方向上,见图。
我的顺序计数代码看起来像
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' 可以说这会导致意外行为。
要解决此问题,您可以将输入翻转两次(称为双列同步器),然后再将它们输入您的其余逻辑。通常多位同步需要更仔细的处理,但在您的情况下,每个位都可以独立处理。