How to 'assign' a value to an output reg i

2019-01-23 22:07发布

( 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?!

标签: verilog
4条回答
时光不老,我们不散
2楼-- · 2019-01-23 22:32

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

查看更多
贪生不怕死
3楼-- · 2019-01-23 22:34

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
查看更多
beautiful°
4楼-- · 2019-01-23 22:44

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).

查看更多
劫难
5楼-- · 2019-01-23 22:44
  1. the issue is that the assign statement when sythesized will create the port/pin thats why its need a wire as output .
  2. you have created the reg named icache_ram_rw now a register is not same as pin right ....
  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 .
查看更多
登录 后发表回答