如何修改Verilog代码避免多驱动?

How to modify the Verilog code to avoid multiple drivers?

Quartus 11.0 说:

Error (10028): Can't resolve multiple constant drivers for net "n[9]"

对于以下代码:

module make_counter(h, clk, P);

input wire h;
input wire clk; 
output wire P;
reg r=1'b1;
reg[9:0] n=10'b0000000000;

always @(posedge h)
begin
    n<=0;
end

always @(negedge clk)
begin
if(n<600) 
    n<=n+1'b1;

if(n==106)  
    r<=1'b0;
else if(n==517)  
    r<=1'b1;
else;
end
assign P=r;

endmodule

########### image is here ###########


我要的就是这张图。 flag1开始时设置n=0,并计数clk; 当计数到flag2时,设置P=0;数到红色箭头时,设P=1;

正如警告所说,n[9] 有多个驱动程序,实际上 nr 都有,因为 nr 是在 initialalways 中都被驱动,并且在综合设计时,一个 reg 只能有一个驱动程序。并且 n 在多个 always 块中驱动。

对于综合,一个 reg 应该只从一个 always 块中驱动。

对于驱动n的多个always块,将它们合并为一个,并且只使用一个时钟,例如clk.

如果目的是为 nr 分配默认值,则在声明中进行,并删除 initial,如:

reg r = 1'b1;
reg[9:0] n = 0;

但是,如果可能,请考虑添加一个复位信号,然后使用此复位信号将复位值同步或异步地分配给寄存器。

假设 hclk 同步,只需对 h 进行采样并找出何时采样值较低而当前值较高(例如 h rose ).这样 n 在一个 always 块中分配(这是综合所必需的)并且所有内容都是相同的时钟域。

always @(negedge clk) begin
  past_h <= h;
  if(!past_h && h) begin // detect 0->1
    n <= 10'h000;
  end
  else begin
    n <= n + 1'b1;
  end
end

如果 h 是异步的,那么保持信号干净的事情就会变得更加复杂。在这种情况下,我建议阅读 Cliff Cummings

Clock Domain Crossing (CDC) Design & Verification Techniques

我想它会对你有所帮助。我已经在xilinx 14.5 synthesis done中编译了这个。

    module make_counter(h, clk, P);
    input wire h;
    input wire clk; 

output wire P;
reg r=1'b1;
reg[9:0] n=10'b0000000000;


task cpu_write;
   begin
      @ (posedge h);
    n <= 0;
      @ (posedge clk);
      if(n<600) 
    n<=n+1'b1;
    if(n==106)  
        r<=1'b0;
    else if(n==517)  
        r<=1'b1;
    else;
    end
  endtask
assign P=r;

endmodule

您可以尝试将posedge h 移动到与negedge clock 相同的always 块中,并根据输入逻辑对h 和clk 进行采样。如果 h 在 clk 的否定之前变低,那么这样的事情可能会起作用。

module make_counter(h, clk, P);

input wire h;
input wire clk; 
output wire P;
reg r=1'b1;
reg[9:0] n=10'b0000000000;



always @(negedge clk, posedge h)
begin
if(h==1'b1)
    n<=0;
if(n<600) 
    n<=n+1'b1;

if(n==106)  
    r<=1'b0;
else if(n==517)  
    r<=1'b1;
else;
end
assign P=r;

endmodule