Красная питая FPGA-плата в качестве счетчика импульсов
Я хочу познакомиться с разработкой ПЛИС и поэтому попытался реализовать в качестве первого проекта счетчик импульсов на основе ПЛИС, который просто подсчитывает все входящие импульсы (например, только нарастающие фронты) и делает их доступными через интерфейс GPIO/AXI как 32- Бит целое число
Я попытался объединить следующие два примера:
Секундомер: http://antonpotocnik.com/?p=489265
Счетчик частоты: http://antonpotocnik.com/?p=519284
Я использовал проект секундомера в качестве основы и адаптировал его так, чтобы двоичный счетчик не подавался на тактовые импульсы ПЛИС 125 МГц, а вместо этого на входящие импульсы (эта часть взята из проекта частотного счетчика). Я также изменил код Verilog Frequency Counter, так как он просто создает 1-битный сигнал High/Low, чтобы он мог управлять двоичным счетчиком:
module frequency_counter #
(
parameter ADC_WIDTH = 14,
parameter AXIS_TDATA_WIDTH = 32,
parameter COUNT_WIDTH = 32,
parameter HIGH_THRESHOLD = -100,
parameter LOW_THRESHOLD = -150
)
(
(* X_INTERFACE_PARAMETER = "FREQ_HZ 125000000" *)
input [AXIS_TDATA_WIDTH-1:0] S_AXIS_IN_tdata,
input S_AXIS_IN_tvalid,
input clk,
input rst,
input [COUNT_WIDTH-1:0] Ncycles,
output [AXIS_TDATA_WIDTH-1:0] M_AXIS_OUT_tdata,
output M_AXIS_OUT_tvalid,
output [0:0] counter_output
);
wire signed [ADC_WIDTH-1:0] data;
reg state, state_next;
reg [COUNT_WIDTH-1:0] counter=0, counter_next=0;
reg [COUNT_WIDTH-1:0] counter_output_next=0;
reg [0:0] counter_output=0;
reg [COUNT_WIDTH-1:0] cycle=0, cycle_next=0;
// Wire AXIS IN to AXIS OUT
assign M_AXIS_OUT_tdata[ADC_WIDTH-1:0] = S_AXIS_IN_tdata[ADC_WIDTH-1:0];
assign M_AXIS_OUT_tvalid = S_AXIS_IN_tvalid;
// Extract only the 14-bits of ADC data
assign data = S_AXIS_IN_tdata[ADC_WIDTH-1:0];
// Handling of the state buffer for finding signal transition at the threshold
always @(posedge clk)
begin
if (~rst)
state <= 1'b0;
else
state <= state_next;
end
always @* // logic for state buffer
begin
if (data > HIGH_THRESHOLD)
counter_output = 1;
else if (data < LOW_THRESHOLD)
counter_output = 0;
else
state_next = state;
end
endmodule
Это работает как-то, но не правильно:
Если я посылаю импульсы на вход IN1, значение счетчика (0x48000008) увеличивается, но слишком быстро (я использую сигнал 1 Гц, и счетчик увеличивается примерно в 1000 раз быстрее):
// read counter value
root@rp-f0184d:~# monitor 0x42000008
0x00000000
// start counting pulses (by default stopped)
root@rp-f0184d:~# monitor 0x42000000 1
// read counter values
root@rp-f0184d:~# monitor 0x42000008
0x00000db5
root@rp-f0184d:~# monitor 0x42000008
0x00001404
root@rp-f0184d:~# monitor 0x42000008
0x000017ca
root@rp-f0184d:~# monitor 0x42000008
0x00001b86
root@rp-f0184d:~# monitor 0x42000008
Вот дизайн блока:
Может кто-нибудь, пожалуйста, помогите мне, как я могу заставить это работать?