почему мой выходной сигнал имеет задержку в 2 такта? - PullRequest
0 голосов
/ 19 марта 2020

Для каждого бита в 32-битном векторе, захват при изменении входного сигнала от 1 в одном такте до 0 в следующем. «Захват» означает, что выход останется равным 1, пока регистр не будет сброшен (синхронный сброс). Каждый выходной бит ведет себя как триггер SR: Выходной бит должен быть установлен (равным 1) в цикле после перехода от 1 к 0. Выходной бит должен быть сброшен (на 0) на положительном фронте тактового сигнала, когда сброс высокий. Если оба вышеупомянутых события происходят одновременно, сброс имеет приоритет. В последних 4 циклах приведенного ниже примера формы волны событие «reset» происходит на один цикл раньше, чем событие «set», поэтому здесь нет конфликта. В приведенном ниже примере формы сигнала для ясности снова показаны сброс в 1 и 1 .

enter image description here

мой код:

module top_module (
  input clk,
  input reset,
  input [31:0] in,
  output [31:0] out );
  integer i;
  reg [31:0] in_del;
  reg [31:0] out_del;
  always @ (posedge clk)
      begin
          in_del<=in;
          out_del<=~in & in_del;
          if (reset)
              out=0;
          else
              begin
                  for (i=0; i<32;i=i+1) begin
                      if (out_del[i])
                          out[i]=out_del[i];
                  end

              end
      end
endmodule

мой вывод

enter image description here

1 Ответ

1 голос
/ 20 марта 2020

Сначала о вашем коде.

  1. он не может быть скомпилирован. out должно быть reg, чтобы его можно было назначить в блоке always.

  2. с использованием неблокирующего назначения в out_del <= in & in_del вызовет задержку в один цикл для сравнения if (out_del). Неблокирующие назначения планируют назначение lhs после оценки блока. Основное правило - всегда использовать блокирующие назначения для промежуточных сигналов в последовательном блоке.

  3. из-за вышеизложенного и из-за in & in_del это не может быть синтезировано или, по крайней мере, не может быть правильно синтезировано.

  4. Вы нарушаете отраслевые практики, используя присвоение blocking в сигнале out. Основное правило: всегда использовать неблокирующие назначения для выходов последовательных блоков.

  5. код просто не работает : - (

Если я правильно понял ваше требование, то следующий код сделает это:

module top_module (
  input clk,
  input reset,
  input [31:0] in,
  output reg [31:0] out );
  reg lock;
  always @ (posedge clk)
      begin
        if (reset) begin
              lock <= 0;
              out <= 0;
          end
          else if (lock == 0)
              begin
                out <= in;
                lock <= 1;
              end
      end
endmodule

Просто используйте сигнал lock, чтобы разрешить обновление. И да, Вот простой тестовый стенд, чтобы проверить это:

module real_top();

    reg clk, reset;
    reg [31:0] in;
    reg [31:0] out;

    top_module tm(clk, reset, in, out);

    initial begin
        clk = 0;
        forever #5 clk = ~clk;
    end

    integer i;
    initial begin 
      in = 0;
      reset = 1;
      #7 reset = 0;
      for (i = 1; i < 5; i++) begin
        #10 in = i;
        #10 reset = 1;
        #10 reset = 0;
      end
      $finish;
    end

    initial 
      $monitor(clk, reset, in, out);
endmodule
...