如何“分配” Verilog 中输出寄存器的值?
(在这里插入真正基本的问题免责声明)
更具体地说,我有以下声明:
output reg icache_ram_rw
在代码的某些点上,我需要将零值放入此注册表中。这是我尝试过的方法和结果:
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 )
我到底该怎么做?
( insert really basic question disclaimer here )
More specifically, I have the following declaration:
output reg icache_ram_rw
And in some point of the code I need to put the zero value in this reg. Here's what I've tried and the outcomes:
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 )
How do I do it after all?!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
从输出声明中删除“reg”,代码应该可以工作(默认为连线输出类型)。
大多数自学成才或学识较差的工程师在 Verilog 中发现有两件事难以理解:(1) 阻塞分配与非阻塞分配(请参阅我关于此主题的论文:http://www.sunburst-design.com/papers/CummingsSNUG2000SJ_NBA.pdf)和(2)reg-vs-wire。现在让我们澄清后一个话题。
左侧 (LHS) 或过程赋值(始终、初始、任务、函数)上的任何内容都必须声明为变量类型(通常是 reg)。该语言中的其他一切都是网络(通常是电线)。没有例外。真的就是这么简单。我不知道有哪一本 Verilog 书能这么简单地阐述这一点。
这是怎么发生的?我问 Phil Moorby(Verilog 语言的发明者和好朋友)“为什么要使用 reg?” Phil 告诉我,当他发明 Verilog 时,还没有综合工具,他认为来自always 块的所有内容都将成为寄存器。他错了,现在我们被这个“reg”关键字困住了。
十多年来,我一直试图在 Veirlog 和 SystemVerilog 委员会上改变这一点。我想将所有内容声明为电线,并且第一次使用将确定“电线”的行为是否像一个reg(来自程序块的第一个分配和最后一个分配获胜)或像一个电线(第一个分配来自驱动源,例如模块输出或连续分配和多个驱动程序的解决方式与今天的 Verilog 一样),并且对同一信号进行程序分配和驱动程序分配是非法的。唉,我在委员会中没有获得足够的票数来成功通过这项提案。
这是我在自己的代码中最常犯的错误。只需习惯“非法 LHS 分配”或“非法连线分配”等错误消息即可。它们的意思是一样的,你忘了声明你的规则。
问候 - Cliff Cummings - Verilog &系统Verilog大师
Remove "reg" from the output declaration and the code should work (defaults to wire output type).
There are two things that most self-taught or poorly-taught engineers find difficult to understand in Verilog: (1) blocking -vs- nonblocking assignments (see my paper on this topic: http://www.sunburst-design.com/papers/CummingsSNUG2000SJ_NBA.pdf) and (2) reg -vs- wire. Let's clear up the latter topic right now.
Anything on the Left-Hand-Side (LHS) or a procedural assignment (always, initial, task, function) must be declared as a variable type (typically a reg). Everything else in the language is a net (typically a wire). No exceptions. It's really that simple. I don't know of any Verilog book that says it that simply.
How did this happen? I asked Phil Moorby, good friend and inventor of the Verilog language, "why reg??" Phil told me that when he invented Verilog, there were no synthesis tools and he thought everything coming out of an always block was going to be a register. He was wrong, and now we are stuck with this "reg" keyword.
I have tried to get this changed on the Veirlog and SystemVerilog committees for more than a decade. I would like to declare everything as wire and first usage would determine if the "wire" behaves like a reg (first assignment from a procedural block and last assignment wins) or behaves like a wire (first assignment is from a driving source such as a module output or continuous assignment and multiple drivers are resolved as in Verilog today) and it would be illegal to make both procedural assignments and driver assignments to the same signal. Alas, I have not had enough votes on the committee to succeed in passing this proposal.
This is the mistake I make most often in my own code. Just get used to error messages like, "illegal LHS assignment" or "illegal assignment to wire." They both mean the same thing, you forgot to declare your regs.
Regards - Cliff Cummings - Verilog & SystemVerilog Guru
assign
语句用于驱动wire
。如果您将某些内容声明为
reg
,那么您必须在过程(always
或initial
块)内为其赋予值。最佳实践是仅在同一always
块中设置reg
的值。例如:reg
和wire
之间存在重要差异,您应该仔细阅读。我有一种感觉,如果你驱动 RAM 信号,你将需要一些时钟逻辑。在这种情况下,您将需要如下所示的代码:
The
assign
statement is used for drivingwire
s.If you've somethings declared as a
reg
, then you have to give it values inside a procedure (always
orinitial
blocks ). It's best practice to only set values ofreg
s in the samealways
block. eg:There are important differences between
reg
s andwire
s that you should read up on.I've a feeling though that you'll need some clocked logic if you're driving RAM signals. In this case, you'll need code that looks something like this:
请注意,您还可以在声明时为 reg 分配一个初始值,如下所示:
output reg icache_ram_rw = 1'b0;
这将确保它在模拟中以零值开始。对于综合,您的结果将取决于综合工具和目标技术(对于 FPGA,您通常可以为硬件分配一个初始值;对于 ASIC,情况并非如此)。
Note that you can also assign an initial value to a reg when you declare it, like this:
output reg icache_ram_rw = 1'b0;
This will ensure it starts with the zero value in simulation. For synthesis, your results will depend on the synthesis tool and target technology (for FPGAs, you can generally assign an initial value for hardware; for ASIC, that's not the case).