我需要生成如图所示的波形。在verilog代码中

我需要生成如图所示的波形。在verilog代码中,verilog,Verilog,我需要生成一个波形,如图所示。但用我的代码,我并没有得到预期的波形 在设计中,该部分从试验台上随机获得最后的有效值。 我的问题是,为什么在valid处递增的I值不等于1 设计规范: 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

我需要生成一个波形,如图所示。但用我的代码,我并没有得到预期的波形

在设计中,该部分从试验台上随机获得最后的有效值。 我的问题是,为什么在valid处递增的I值不等于1

设计规范:

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    
模块设计(时钟、有效、最后、数据);
输入时钟,有效,最后一次;
输出reg[7:0]数据;
reg[7:0]i;
最初的
开始
数据=0;
i=0;
终止
始终@(posedge clk,有效)
开始
如果(有效)
开始

数据看来你的英语有困难,这不是你的错,但正因为如此,我可能会错误地解释你的问题

你有一个你需要实现的波形。这对我来说意味着这是一项学校作业,因此我会这样对待它。这意味着我将**不*给你一个完整的答案,而是给你指出你的错误所在。(这些都应该放在评论中,但现在有了合适的方式)

…从测试台随机获得最后一个有效值

首先要认识到的是,编写一个测试平台同样困难,如果不是比编写RTL代码本身更困难的话

在测试台中,您使用的是
始终@(posedge clk)
,但在该部分中,您使用的是
#……
语句。这本身并没有错。危险,是的,但不一定是错的

但是
您的时钟的时间周期为2(
参数clk_period=2;
),在posedge时钟内,您使用的延迟小于等于或大于时钟周期。正如您所发现的,这通常会导致灾难。
阅读Verilog的工作原理,尤其是当使用敏感度列表
始终@…
时:在处理完本节中的所有语句之前,不会触发它。在您的情况下,这意味着在always块再次启动之前需要几个时钟边缘

试验台
我不知道任务是什么,所以我将使用你给出的波形。 由于
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
reg[2:0]计数器;
始终@(posedge clk或negedge重置)
开始
如果(重置)
柜台
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
always @(posedge clk...
...
   if (counter==3'h2)
      last <= 1'b1;
   else
      last <= 1'b0;