How to 'assign' a value to an output reg in Verilog?

后端 未结 4 1968
生来不讨喜
生来不讨喜 2020-12-15 02:09

( insert really basic question disclaimer here )

More specifically, I have the following declaration:

output reg icache_ram_rw

And

相关标签:
4条回答
  • 2020-12-15 02:35

    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

    0 讨论(0)
  • 2020-12-15 02:41

    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
    
    0 讨论(0)
  • 2020-12-15 02: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).

    0 讨论(0)
  • 2020-12-15 02:49
    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 .
    0 讨论(0)
提交回复
热议问题