Мне нужно генерировать форму волны, как показано на рисунке.в коде verilog - PullRequest
0 голосов
/ 27 января 2019

Мне нужно сгенерировать форму волны, как показано на рисунке.Но с моим кодом я не получил ожидаемую форму волны

. В проекте часть получила последние и действительные значения в случайный период из испытательного стенда.Моя проблема заключается в том, почему значение I, увеличенное до действительного, не равно единице

Код проектирования:

module design_d(clk,valid,last,data);

   input clk,valid,last;
   output reg [7:0] data;

     reg [7:0] i; 
     initial
       begin
       data=0;
       i=0;
      end

always @(posedge clk,valid)
    begin

   if (valid)
   begin
     data<=i;
     i=i+1;
     $display("i=%d data=%d ",i,data);
   end
   else 
     begin
       data <=8'bz; 
     end
    end
endmodule    

Код испытательного стенда:

module test;

  reg clk,valid,last;
  wire [7:0] data;

  parameter clk_period=2;

  design_d dut(clk,valid,last,data);

  initial
  begin
    clk=1;
    valid=1;
    last=0;
  end

  always #(clk_period/2) clk=~clk;

  always @(posedge clk)
  begin 
    last=0;
    #4 last=1;
    #clk_period last=0;
    #8 last=1;
    #clk_period last=0;
    #10 last=1;
    #clk_period last=0;
    #16last=1;
    #clk_period last=0;  

    #20 last=1;
    #clk_period last=0;
  end

  always @(posedge clk or last)
  begin
     valid<=1;
     wait(last==1)
     #clk_period;
     valid<=0;
     #clk_period;
     valid<=1;
  end

  initial
  begin 
     $dumpfile("dump.vcd");
     $dumpvars(1);
     #24 $finish;
  end
endmodule

enter image description here

1 Ответ

0 голосов
/ 27 января 2019

Кажется, у вас проблемы с английским языком, который не является вашей ошибкой, но из-за этого я могу неправильно истолковать ваш вопрос.

У вас есть форма волны того, что вам нужно достичь.Для меня это говорит о том, что это школьное задание, и поэтому я буду относиться к нему таким образом.Это означает, что я ** не * дам вам полный ответ, но дам вам подсказки о том, где вы идете не так.(Это все должно быть в комментарии, но теперь есть способ, которым это будет соответствовать).

... получил последние и действительные значения в случайный период из тестового стенда.

Первое, что нужно понять, это написание тестового стенда так же сложно, если не сложнее, чем написание самого кода RTL.

В вашем тестовом стенде вы используете always @(posedge clk), но внутри этогораздел вы используете #... заявления.Это само по себе не так.Опасно, да, но не обязательно неправильно.

Но
Ваши часы имеют период времени 2 (parameter clk_period=2;), и внутри ваших часовых часов вы используете задержки, которые равно или больше , чем период времени.Как вы уже выяснили, это часто приводит к катастрофе.
Узнайте о том, как работает Verilog, особенно когда используется список чувствительности always @...: он не срабатывает, пока не будут рассмотрены все утверждения в разделе.В вашем случае это означает, что потребуется несколько фронтов тактовой частоты, пока снова не будет запущен блок Always.

Test Bench
Я не знаю, каково было назначение, поэтому я 'Я буду использовать форму волны, которую вы дали.Поскольку last и valid являются входами для вашего модуля, я дам вам указания, как их сделать.

valid имеет высокий уровень для 4 тактов, а затем низкий для одного такта, после чегоэто повторяется.Это означает, что вам нужен шаблон, который повторяется каждые 5 тактов, и, следовательно, вам нужно создать счетчик, который считает 0,1,2,3,4,0,1,2,3,4, ...

Вы должны не сделать это с помощью #..... операторов.Вы должны использовать часы на испытательном стенде и создать счетчик, который будет считать!
Создание счетчика, который считает, как описано выше, это первое, что вам нужно изучить в HDL!Вы обнаружите, что вам нужно делать это снова и снова, снова и снова. В каждом фрагменте кода RTL и на каждом тестовом стенде.

Счетчик по модулю 5.

Я предпочитаю, чтобы все мои модули и мои испытательные стенды имели сброс.Если только это позволяет мне начать новый тест из известного состояния.

reg [2:0] counter;

always @(posedge clk or negedge reset_n)
begin
   if (reset_n)
      counter <= ...
   else // clocked section
   begin
      if (..)
        counter <= ...
      else       
        counter <= ...
   end
end

Запустите заново и запустите приведенный выше код первым.Обратите внимание, что счетчик действительно работает 0,1 2, 3, 4, 0, ... прежде чем продолжить.

Производные сигналы.
Далее научитесь извлекать сигналы из этого.
Основное правило: в тактовой секции, если вам нужен сигнал со значением счетчика X, вы должны генерировать его в цикле X-1.

Таким образом, чтобы сделать последний максимум, когда счетчик равен 3, вы должныустановите его, когда счетчик равен 2:

always @(posedge clk...
...
   if (counter==3'h2)
      last <= 1'b1;
   else
      last <= 1'b0;

Я оставляю для вас действительное значение.

После того, как вы запустили тестовый стенд, начните работать над модулем design_d.

Несколько советов:

  • Используйте всегда неблокирующие назначения <= в своем временном разделе.**

  • НЕ используйте период времени 2, используйте 100 или 1000. В свое время вы узнаете, почему это лучше.

  • Не используйте always @(posedge clk or [one or more signals] ), если не в соответствии с моим примером.**

  • Позаботьтесь о своем отступе.Я должен был отредактировать мэра в вашем коде.

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

Я мог бы написать действительный код за десятую часть времени, которое понадобилось мне, чтобы написать все это, поэтому я надеюсь, что вы не удалите вопрос, поскольку другие могут извлечь из этого пользуэто.

...