如何在Verilog中为输出reg'赋值?

时间:2009-11-27 16:52:53

标签: verilog

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

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

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 )

我怎么办呢?!

4 个答案:

答案 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,那么您必须在过程(alwaysinitial块中)为其提供值。最佳做法是仅在同一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

您应该阅读的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

答案 2 :(得分:3)

请注意,您可以在声明时为reg分配初始值,如下所示:

output reg icache_ram_rw = 1'b0;

这将确保它在模拟中以零值开始。对于综合,您的结果将取决于综合工具和目标技术(对于FPGA,您通常可以为硬件分配初始值;对于ASIC,情况并非如此)。

答案 3 :(得分:1)

  1. 问题是sythesized时的assign语句会创建端口/引脚,这就是为什么它需要一根导线作为输出。
  2. 你创建了一个名为icache_ram_rw的注册表,现在寄存器与引脚权限不同....
  3. 所以要指定一个注册表,你需要使用正确格式的verilog
  4. verilog通过使用always语句允许相同,创建DFF并且该DFF的输入引脚将是您的icache_ram_rw,该格式已由其他人提供。