我无法得知哪两个分配驱动器相互冲突

问题描述 投票:0回答:1

我试图制作一款可以计算时间的手表,因为时钟周期是一分钟。 但是,我很难找到哪两个作业发生冲突。 (找了两天没找到)

首先我在 EDA 游乐场中尝试了这些代码。

//code for "design.sv"

module clock(
  input clk, rstn,
  output reg[6:0] minute,      //line 1
  output reg[5:0] hour         //line 2
);

  
  always @ (posedge clk, negedge rstn) begin
    if(!rstn) begin
        minute <= 0; hour = 0;
        end
    else begin
        minute = minute + 1;
        end
  end
  
  always @ (posedge clk) begin
    if((minute%60==0)&&(minute != 0)) begin
        minute <= 0;
        hour = hour + 1;
        end
    
    if((hour%24==0)&&(hour !=0)) hour <= 0;
  end
  
  
endmodule

//code for "testbench.sv"
module test;
  reg clk, rstn;
  reg [6:0] minute;
  reg [5:0] hour;
  
  initial begin
    clk = 0;
    forever #5 clk = ~clk;
  end
  
  initial begin
    rstn = 1; minute = 0; hour = 0;    //line 3
    #30 rstn = 0;
    #1 rstn = 1;
    #600 $finish;
  end
  
  clock clock_inst(clk, rstn, minute, hour);
  
  initial begin
    $dumpfiles("wave.vcd");
    $dumpvars(0, test);
  end
  
endmodule

我模拟了这些第一个代码并得到了以下错误。

“变量“分钟””不能同时由过程赋值语句和连续赋值语句驱动。 “变量“hour”不能由过程赋值语句和连续赋值语句驱动。

我的第一个结论: 我的结论是,

line 1
line 2
上的作业与
line 3
上的作业发生冲突。 我认为
output reg minute
中的
output reg hour
clock_inst
是隐式连续赋值。 因此
line 1
line 2
minute
hour
(放置在
line 3
中)的分配发生冲突,导致一个变量出现多驱动程序问题。

但是,为了检查我的结论,我修改了代码,如下所示。

//revised code for "design.sv"

module clock(
  input clk, rstn,
  output reg[6:0] minute, 
  output reg[5:0] hour
);

  
  initial begin        // newly added block
    minute = 0; hour = 0;
  end
  
  always @ (posedge clk, negedge rstn) begin
    if(!rstn) begin
        minute <= 0; hour = 0;
        end 
    else begin
        minute = minute + 1;
        end
  end
  
  always @ (posedge clk) begin
    if((minute%60==0)&&(minute != 0)) begin
        minute <= 0;
        hour = hour + 1;
        end
    
    if((hour%24==0)&&(hour !=0)) hour <= 0;
  end
  
  
endmodule

//revised code for "testbench.sv"

module test;
  reg clk, rstn;
  reg [6:0] minute;
  reg [5:0] hour;
  
  initial begin
    clk = 0;
    forever #5 clk = ~clk;
  end
  
  initial begin
    rstn = 1;          //revised line
    #30 rstn = 0;
    #1 rstn = 1;
    #600 $finish;
  end
  
  clock clock_inst(clk, rstn, minute, hour);
  
  initial begin
    $dumpfiles("wave.vcd");
    $dumpvars(0, test);
  end
  
endmodule

我认为这些代码会给我带来错误,因为对

newly added block
的赋值会与
output reg[6:0] minute
output reg[5:0] hour
赋值发生冲突。

但是效果真的很好

VSIM:仿真已完成。没有更多的测试向量可以模拟。

VSIM:仿真已完成。

现在,我在我的第一个代码中找不到哪些行导致了多重驱动错误。

verilog system-verilog
1个回答
0
投票

在原始代码中,变量

minute
是由多个
always
块驱动的。

那是多个驱动,不会合成。

将所有驱动程序放入一个always块中的变量中。
像这样:

  always @ (posedge clk, negedge rstn) begin
    if(!rstn) begin
       minute <= 0;
       hour   <= 0;
    end
    else begin

        if((minute < 60) begin
          minute <= minute + 1;
        eles
          minute   <= 0;
        end

        if((minute < 24) begin
          hour <= hour + 1;
        else
          hour <= 0;
        end
  end

模数运算符不会很好地综合,除非您使用的是 2^N 的幂的模,例如:2,4,8,16.32...

还要注意在同步始终阻塞中始终使用非阻塞赋值

<=~
,而不是阻塞赋值
=
。在同步always块中使用阻塞分配可能会导致模拟/综合行为不匹配。

© www.soinside.com 2019 - 2024. All rights reserved.