2

I'm trying to test if a wire(s) is on or not to signify if there is an error/overflow in my alu code. Given this code:

output reg[3:0]x;                       // line 149
output wire error;
output wire overflow;

always @* begin
    if(error || overflow) begin         
        assign x = 4'b1111;             // line 155
        assign error = ~error;
        assign overflow = ~overflow;
    end else begin
        assign x = opcode;
    end
end

I get following error messages:

Errors

uut is my instantiation unit in my testbench called main

sharvil111
  • 4,301
  • 1
  • 14
  • 29
SasaS
  • 23
  • 1
  • 1
  • 3

2 Answers2

3

The code in the example has several issues.

1) you tried to use 'procedural assignments' which is an advanced verilog topic. In other words assign statement inside of an always block. This is not synthesizable, can only be used on reg types, and is there in verilog for very special cases. Do not use it.

You error messages coming from the fact that error and overflow are declared as wire.

2) you are trying to assign inverted version of a value to itself in a non-clocked logic. It will not behave the way you expect. Depending on usage it can either not toggle or will cause an infinite zero-delay loop, or in your case it could just generate a glitch.

So, potentially, your code should look something like the following:

input wire clk; // << you need clock
output reg[3:0]x;                       // line 149
output wire error;
output wire overflow;

reg error_reg, overflow_reg; 

 always @(posedge clk) begin
    if(error || overflow) begin         
        x <= 4'b1111;             // line 155
        error_reg <= ~error;
        overflow_reg <= ~overflow;
    end else begin
        x <= opcode;
    end
 assign error = error_reg;
 assign overflow = overflow_reg;
end
Serge
  • 11,616
  • 3
  • 18
  • 28
  • What is the point of creating a `reg` only to assign it to an `output wire` when you can use `output reg`? – Greg Nov 15 '17 at 18:20
  • 1
    @Greg In this case I did not want to change the original port definitions. Yes, you can declare them as regs, but you risk to propagate reg-related behavior to the other modules and can have tough time debugging races and multiple driver issues. It is always a good methodology to stick to 'nets' only in module ports. – Serge Nov 15 '17 at 18:38
  • It fixed up everything! Thanks for the advice! Didn't realize wires couldn't be assigned in always blocks – SasaS Nov 15 '17 at 23:45
  • @Serge my experience been different and I follow the opposite. Using Verilog-2005's `uwire` a level up or SytemVerilog style coding catches unintended multiple driver issues. Race conditions are usually from poor coding which I normally spot in code review. Lint checks can also catch most of these issue. Creating the intermediate is very prone to typos resulting in connectivity issues can be hard catch on large designs. As long as your strategy works for you; to each their own. – Greg Nov 16 '17 at 01:29
0

Your using the assign incorrectly. That can be used outside of a always process, but not inside of one.
Also, the type wire, is required for an assign

wire [3:0] x;
assign x = 4'b1111;

Inside the always process, remove the assign statement and just say

reg [3:0] x;  // Note that this is assigned as a reg now
 always @* begin
    if(blah) begin 
       x = 4'b1111;
    end else begin
       x = opcode;
    end
 end
Rich Maes
  • 1,204
  • 1
  • 12
  • 29