(在这里插入真正基本的问题免责声明)
更具体地说,我有以下声明:
output reg icache_ram_rw
在代码的某些方面,我需要将零值放在此reg中。这是我尝试过的结果和结果:
assign icache_ram_rw = 1'b0;
( declarative lvalue or port sink reg icache_ram_rw must be a wire )
icache_ram_rw <= 1'b0;
( instance gate/name for type "icache_ram_rw" expected - <= read )
我怎么办呢?!
答案 0 :(得分:27)
从输出声明中删除“reg”,代码应该有效(默认为线路输出类型)。
在Verilog中,大多数自学成才或教学不足的工程师都有两件事情难以理解:(1)阻止-vs-非阻塞作业(参见我关于这个主题的论文:http://www.sunburst-design.com/papers/CummingsSNUG2000SJ_NBA.pdf)和(2) reg -vs-wire。让我们现在澄清后一个话题。
左手边的任何东西(LHS)或程序分配(总是,初始,任务,功能)必须声明为变量类型(通常是reg)。语言中的其他所有内容都是网络(通常是电线)。没有例外。这真的很简单。我不知道任何Verilog书那么简单。
这是怎么发生的?我问过Verilog语的好朋友和发明家Phil Moorby,“为什么要注册?”菲尔告诉我,当他发明了Verilog时,没有任何综合工具,他认为从一个总是块出来的一切都将成为一个注册。他错了,现在我们坚持使用这个“reg”关键字。
我已经尝试在Veirlog和SystemVerilog委员会上改变了十多年。我想将所有内容声明为有线并且首次使用将确定“线”是否表现为reg(从程序块中的第一次赋值和最后一次赋值获胜)或行为类似于线(第一次赋值来自驱动源,例如a模块输出或连续分配和多个驱动程序在今天的Verilog中得到解决)并且对同一信号进行程序分配和驱动程序分配是非法的。唉,我对委员会没有足够的票数来成功通过这项提案。
这是我在自己的代码中经常犯的错误。只是习惯于错误消息,例如“非法LHS分配”或“非法分配到电线”。它们都意味着同样的事情,你忘了宣布你的注册。
问候 - Cliff Cummings - Verilog&amp; SystemVerilog Guru
答案 1 :(得分:15)
assign
语句用于驱动wire
s。
如果您将某些事情声明为reg
,那么您必须在过程(always
或initial
块中)为其提供值。最佳做法是仅在同一reg
块中设置always
s的值。例如:
always @( * ) begin // combo logic block
if( some_condition ) begin
icache_ram_rw = 1'b0;
end else begin
icache_ram_rw = something_else;
end
您应该阅读的reg
和wire
之间存在重大差异。
我有一种感觉,如果你正在驱动RAM信号,你需要一些时钟逻辑。在这种情况下,您需要看起来像这样的代码:
// some parameter definitions to make logic 'read' clearer.
localparam READ = 1'b0;
localparam WRITE = 1'b1;
// standard clocked logic 'template' that synthesis tools recognise.
always @( posedge clk or negedge resetb )
if( !resetb ) begin // asynchronous active low reset
icache_ram_rw <= READ;
end else if( some_enable_condition ) begin
icache_ram_rw <= WRITE;
end else begin
icache_ram_rw <= READ;
end
答案 2 :(得分:3)
请注意,您可以在声明时为reg分配初始值,如下所示:
output reg icache_ram_rw = 1'b0;
这将确保它在模拟中以零值开始。对于综合,您的结果将取决于综合工具和目标技术(对于FPGA,您通常可以为硬件分配初始值;对于ASIC,情况并非如此)。
答案 3 :(得分:1)