Обнаружение пика Verilog - PullRequest
0 голосов
/ 20 мая 2018

Я новичок в Verilog.Я пытаюсь определить пиковое напряжение входного сигнала для АЦП на ПЛИС.До этого я хотел протестировать простой, но похожий код, который находит минимум и максимум набора из 4-битных параллельных входов.

Первоначально я назначил pk_low и pk_high в качестве первого входа, в зависимости от предстоящих входовpk_low и pk_high должны измениться или остаться прежними.Но в симуляциях я вижу, что значение pk_low всегда равно 0. pk_high и pp_voltage (пиковое напряжение) неизвестны (X).

В чем проблема?

module peak_voltage (clk, parallel_in, pk_high, pk_low, pp_voltage);

input clk;
input wire [3:0] parallel_in;
output reg [3:0] pk_high;
output reg [3:0] pk_low;
output wire [3:0] pp_voltage;

reg state;

parameter st0 = 'd0;
parameter st1 = 'd1;
parameter st2 = 'd2;

initial begin
    state = st0;
    pk_high <= parallel_in;
    pk_low <= parallel_in;
end


always @ (posedge clk) begin

    if (parallel_in > pk_high)begin
        state = st1;
    end else if (parallel_in < pk_low) begin
        state = st2;
    end else begin
        state = st0;
    end

end

always @(*) begin

    case (state)

        st0: begin
            pk_low <= pk_low;
            pk_high <= pk_high;
        end

        st1: begin
            pk_low <= pk_low;
            pk_high <= parallel_in;
        end

        st2: begin
            pk_low <= parallel_in;
            pk_high <= pk_high;     
        end
    endcase
end

assign pp_voltage = pk_high - pk_low;

endmodule

1 Ответ

0 голосов
/ 21 мая 2018

Вы закодировали это как конечный автомат, где вместо этого у вас должно быть постоянное назначение для вашего селектора дел.Присвойте 3 бита, чтобы получить вектор с одним горячим вектором.

У вас есть неблокирующие назначения в этой логике - вам нужно использовать блокировку для комбинаторной логики.

Вам не хватает явного хранилищадля пиковых высоких / низких значений.Возможно, вы могли бы вывести некоторые защелки в этом стиле, но не совсем понятно, что вы имели в виду.

Определите некоторые флопы, синхронизированные с помощью clk, с неблокирующими назначениями.Сохраняйте обновленные результаты в каждом цикле.

Помните, что verilog выполняет все операторы параллельно, вам не следует думать о порядке выполнения.Вместо этого подумайте о явном захвате ваших результатов и вычислении «следующих» значений для этих результатов.

Вы можете просмотреть свой код следующим образом:

  1. Проверить обновление максимума или минимума
  2. Рассчитать новые значения
  3. Записать новые значения

Вы сделали (1) неправильно и пропустили (3) в целом.Возможно, имеет смысл кодировать (1) и (2) вместе, но это зависит от того, как вы хотите выразить функции.

assign new_level = (in > level) ? in : level;
...