如何“分配” Verilog 中输出寄存器的值?

发布于 2024-08-12 21:48:46 字数 381 浏览 6 评论 0原文

(在这里插入真正基本的问题免责声明)

更具体地说,我有以下声明:

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

心碎的声音 2024-08-19 21:48:46

从输出声明中删除“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

绮筵 2024-08-19 21:48:46

assign 语句用于驱动wire

如果您将某些内容声明为 reg,那么您必须在过程( alwaysinitial 块)内为其赋予值。最佳实践是仅在同一 always 块中设置 reg 的值。例如:

always @( * ) begin // combo logic block
   if( some_condition ) begin
      icache_ram_rw = 1'b0;
   end else begin
      icache_ram_rw = something_else;
 end

regwire 之间存在重要差异,您应该仔细阅读。

我有一种感觉,如果你驱动 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

The assign statement is used for driving wires.

If you've somethings declared as a reg, then you have to give it values inside a procedure ( always or initial blocks ). It's best practice to only set values of regs in the same always block. eg:

always @( * ) begin // combo logic block
   if( some_condition ) begin
      icache_ram_rw = 1'b0;
   end else begin
      icache_ram_rw = something_else;
 end

There are important differences between regs and wires 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:

// 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
诗化ㄋ丶相逢 2024-08-19 21:48:46

请注意,您还可以在声明时为 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).

梦醒灬来后我 2024-08-19 21:48:46
  1. 问题是,综合时的分配语句将创建端口/引脚,这就是为什么它需要一根电线作为输出。
  2. 您创建的名为 icache_ram_rw 的寄存器现在是一个寄存器,与引脚不同,
  3. 因此要分配一个寄存器,您需要使用正确的 verilog 格式。verilog
  4. 允许使用always语句进行相同的操作,创建一个 DFF 并输入该引脚DFF就是你的icache_ram_rw,该格式已经由其他人提供了。
  1. The issue is that the assign statement when synthesized will create the port/pin thats why its need a wire as output .
  2. The reg named icache_ram_rw created by you is now a register and is not same as pin
  3. so to assign an register you need to use a proper format of verilog
  4. verilog allows the same by using always statement , a DFF is created and the input pin of that DFF would be your icache_ram_rw , the format is already been provided by others .
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文