Почему мои выходные регистры Verilog выводят только "x"? - PullRequest
0 голосов
/ 20 марта 2019

Я написал следующий модуль для приема 12-битного потока ввода и запуска его по формуле Экспоненциальное скользящее среднее (EMA) . При моделировании программы создается впечатление, что мой вывод представляет собой 12-битный поток "все равно". Независимо от того, что мой ввод, он не реализован регистром вывода.

Я новичок в Verilog, так что я уверен, что здесь есть масса проблем, но я ожидал, по крайней мере, получить какой-то вывод. Почему происходит такое поведение и как я могу предотвратить его появление в будущем? В нижней части этого поста я привел скриншот моих результатов осциллограмм.

Мой модуль verilog:

`timescale 1ns / 1ps
module EMATesting (     input signed [11:0] signal_in,
                        output reg signed [11:0] signal_out,
                        input clock_in,
                        input reset,
                        input enable,
                        output reg [11:0] newEMA);

reg [11:0] prevEMA;
reg [11:0] y;
reg [11:0] temp;
integer count = 0;
integer t = 1;
integer one = 1;
integer alpha = 0.5;

always @(posedge clock_in) begin

    if (reset) begin
        count = 0;
        end

    else if (count < 64) begin
         count = count + 1;
        end

//set the output equal to the first value received
    if (count == 1) begin
        newEMA = signal_in;
        end

//if not the first value, run through the formula
    else begin
        temp = newEMA;
        prevEMA = temp;
        newEMA = alpha * signal_in + (one-alpha) * prevEMA;
        count = count + 1;
        end
    end
endmodule

Мой тестовый стенд:

`timescale 10ns / 1ns
module testbench_EMA;

reg signal_in;
reg clock_in, reset, enable;
wire [11:0] signal_out;
wire [11:0] newEMA;

initial begin
    signal_in = 0; reset = 0; enable = 0;
    clock_in = 0;
end

EMATesting DUT(signal_in, signal_out, clock_in, reset, enable, newEMA);

initial
begin
//test some values with timing intervals here 
#100;
reset = 1;
#100;
reset = 0;
enable = 1;
#100;
//set signal_in to "1" repeating 12 times
signal_in = { 12 { 1'b1}};
#100;
reset = 1;
#100; //buffer to end simulation
$finish;
end


always
    #5 clock_in = !clock_in;

endmodule

Результаты осциллограммы моего тестового стенда . Обратите внимание, что оба выходных регистра не дают значений.

1 Ответ

2 голосов
/ 20 марта 2019

В вашем коде много ошибок.@Мистер.Снруб перечислил некоторые из них.Вы можете исправить ошибки, перечисленные в комментариях, и, отредактировав свой код, можете заставить его работать так, как вы хотите, , но есть более важные фундаментальные проблемы .Вы должны решить их, прежде чем делать дальнейшие и трудные для устранения ошибок в будущем, это также дает преимущество лучшего понимания концепций HDL.

  • Прежде всего, вам необходимо понять разницу между программированиемязыки и языки описания оборудования.Вы должны провести дальнейшие исследования для этого, ошибки, которые вы сделали, обычно делают разработчики, которые полагают, что HDL похож на языки программирования.Проверьте эту ссылку для получения дополнительной информации.
  • Вам необходимо больше понять, как синтезируются коды Verilog HDL (или любые другие HDL) и почему они используются.
  • Необходимо знать, когда и как использовать блокировку = илиНеблокирующие <= назначения и как они работают.Проверьте эту ссылку.

Когда вы изучите перечисленные темы, вы поймете, что в чувствительном к фронту (синхронном или последовательном) блоке always плохая идея использовать блокирующее присвоение =.

Когда вы используете назначение блокировки, назначения выполняются последовательно, как в обычных языках программирования.В случае чувствительного к фронту блока always у вас очень ограниченное время для выполнения всех необходимых назначений внутри блока always.

В вашем случае, поскольку все назначения внутри чувствительного к фронту блока всегда блокируются (при условии отсутствия условия сброса):

  • Сначала проверяется, меньше ли count 64и завершает присваивание, если это так.Все остальные назначения ожидают завершения этого назначения.
  • К тому времени, когда будет выполнено первое назначение, блок always с чувствительностью posedge clock_in мог закончить выполнение и ожидать следующего фронта часов.Таким образом, другие назначения не выполняются.
  • Поскольку вы не инициализировали свои выходные регистры, они изначально были заполнены «пофиг», и новое значение больше никогда не назначается, поэтому в результате вы получилиэтот вывод (заполненный «пофиг»).
  • Даже когда count становится больше или равен 64, у вас есть другие блокирующие назначения, прежде чем присваивать значение newEMA.
...