Красная питая FPGA-плата в качестве счетчика импульсов

Я хочу познакомиться с разработкой ПЛИС и поэтому попытался реализовать в качестве первого проекта счетчик импульсов на основе ПЛИС, который просто подсчитывает все входящие импульсы (например, только нарастающие фронты) и делает их доступными через интерфейс GPIO/AXI как 32- Бит целое число

Я попытался объединить следующие два примера:

Я использовал проект секундомера в качестве основы и адаптировал его так, чтобы двоичный счетчик не подавался на тактовые импульсы ПЛИС 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

Вот дизайн блока:

Может кто-нибудь, пожалуйста, помогите мне, как я могу заставить это работать?

0 ответов

Другие вопросы по тегам