2016-11-28 100 views
0

我完全不熟悉Verilog编程,我不明白在哪里初始化变量regVerilog注册分配?

让我们来看看下面的代码片段: 编辑: Warning at synthesize

module test (
     output LED0 
     ); 
reg led = 1'b1; 
assign LED0 = led; 
endmodule 

module test (
     output LED0 
     ); 

reg led; 
initial begin 
    reg led <= 1'b1; 
end 

assign LED0 = led; 
endmodule 

给我:使用的领导,因为这是从来没有在该行指定的初始值: reg led = 1'b1;

reg类型只在always @ block中被赋值吗?

又如:

module fourBitCounter 
     (input clk, 
     output [3:0]counter 
     ); 

wire clk; 
initial begin 
reg[3:0] counter = 4'b1; 
end 

[email protected] (posedge clk) begin 

     if(counter > 15) 
       counter <= 0; 
     else 
       counter <= counter + 1; 
     end endmodule 

这里REG具有的初始值为0,但之前我将它设置为1 ...怎么了?谢谢!

+0

你可能不希望使用内部和'initial'块'reg'关键字。 – toolic

+0

你说得对。但是,同样的结果... –

回答

1

是否只在always @ block中分配reg类型?

没有,reg类型可以always块和initial块分配(加taskfunction但我会跳过他们在这个问题的范围)

为了您fourBitCounter,在宣布reg[3:0] counterinitial块创建一个局部变量,也称为counter,它只能在其创建块的范围内访问。您需要删除初始块中的reg[3:0],以便赋值应用于预期的counter。但它仍然不起作用,因为您宣称counter为推断的导线类型,并且always/initial块不能分配导线。

counter被声明为4位推断导线的输出(output [3:0] counteroutput wire [3:0] counter的同义词)。由于counter分配在always块和initial块中,因此它需要是reg类型。因此应该声明为output reg [3:0] counter

此外,您声明clk在输入和作为本地电线,它不能同时。端口可以​​在本地访问,没有理由将其重新声明为本地网络。对于一个4位的值,15 + 1等于0,因为没有什么可以存储MSB。

module fourBitCounter (
    input clk, 
    output reg [3:0] counter // 'output reg', not 'output' 
); 

//wire clk; // do not do this, clk is an input 
initial begin 
    counter = 4'b1; // no 'reg' here 
end 

always @(posedge clk) begin 
    if(counter > 15) // this will never evaluate as true with counter declared as 4-bit 
    counter <= 0; 
    else 
    counter <= counter + 1; 
end 
endmodule

对于Verilog,assign语句只能净类型(例如wire)来施加。这是合法的:

module test (output LED0); // LED0 is an inferred wire 
assign LED0 = 1'b1; 
endmodule 

这是非法的:

module test (output reg LED0); // Explicit reg 
assign LED0 = 1'b1; // illegal, assign on a reg 
endmodule 
+0

谢谢你的回答!它帮助我纠正错误,但我还有一个问题:为什么在程序块内使用了非赋值?为什么不呢:counter <= 4'b1。附:计数器在开始时仍然为0,也许初始块不可综合? –

+0

在最初的块中,我使用了一个阻塞赋值('=')。在always块中,我使用了一个非阻塞赋值('<='),它应该用于在always块中分配预期的触发器/锁存器。我可以在最初的块中使用非阻塞,但我通常不会使用我的编码风格。非阻塞延迟调度器中的更新,这在时钟边缘有用,但不在零时间 – Greg

+0

现在除了以下内容之外,现在都可以使用了:我可以像第一个例子中那样为电线分配一个区段吗?那里有什么问题?即使我确实分配了LED内部的初始块,我仍然会得到:使用led的初始值,因为它从来没有分配过 –

0

从你的第一个代码示例:

reg led;    // <-- This declares one register called "led" 
initial begin 
    reg led <= 1'b1; // <-- This declares a *separate* register called "led" 
end     //  which is only valid in the initial block 

你的第二个样品中也存在同样的问题;你在initial块中声明了一个单独的寄存器。如果您只是想分配一个值,请不要使用关键字regwire

+0

是的,的确,我犯了一个错误。但即使没有变量名称前的reg或wire也不能使其工作。我的第一个例子呢? –