object is not declared in verlog

2019-03-02 17:05发布

问题:

Here's my code, and as far as I can tell, LEDs in defined

module sevenseg (LEDs,in);
output reg [6:0] LEDs;
input [3:0] in;

always@(in) begin 
    case(in)
        0 : LEDs = 7'b1000000;
        1 : LEDs = 7'b1111001;
        2 : LEDs = 7'b0100100;
        3 : LEDs = 7'b0110000;
        4 : LEDs = 7'b0011001;
        5 : LEDs = 7'b0001010;
        6 : LEDs = 7'b0000010;
        7 : LEDs = 7'b1111000;
        8 : LEDs = 7'b0000000;
        9 : LEDs = 7'b00010000;
        default : LEDs = 7'b1111111;
    endcase
end 
endmodule 

here's the compilation error

Error (10161): Verilog HDL error at sevenseg2.v(39): object "LEDs" is not declared

Error: Quartus II 64-Bit Analysis & Synthesis was unsuccessful. 1 error, 1 warning

Error (293001): Quartus II Full Compilation was unsuccessful. 3 errors, 1 warning

回答1:

You are mixing ANSI and non-ANSI header styles. This is illegal syntax. Some simulator/synthesizer is allowing it, but it is bad practice.

You should use ANSI: IEEE Std 1800-2012 § 23.2.2.2 ANSI style list of port declarations

module sevenseg (
output reg [6:0] LEDs,
input [3:0] in );

or non-ANSI: IEEE Std 1800-2012 § 23.2.2.1 Non-ANSI style port declarations

module sevenseg (LEDs,in);
output [6:0] LEDs; // only an output here
input [3:0] in;
reg [6:0] LEDs; // declare as reg after all inputs/outputs/inouts

Non-ANSI is required for IEEE Std 1364-1995. Support for ANSI existed since IEEE Std 1364-2001.



回答2:

The accepted answer is incorrect - this is not illegal, in either Verilog (2001/2005) or SystemVerilog. If your compiler thinks that it is, then it is either buggy or is assuming Verilog-1995 (which no sane commercial compiler does).

For Verilog (1364-2005), 12.3.3 states:

Each port_identifier in a port_expression in the list of ports for the module declaration shall also be declared in the body of the module as one of the following port declarations: input, output, or inout (bidirectional). This is in addition to any other data type declaration for a particular port— for example, a reg or wire. The syntax for port declarations is given in Syntax 12-4.

12-4 defines an output_declaration as

output_declaration ::=
    output [ net_type ] [ signed ] [ range ] list_of_port_identifiers
 | output reg [ signed ] [ range ] list_of_variable_port_identifiers
 | output output_variable_type list_of_variable_port_identifiers

So output reg is valid when you have a plain list of port identifiers. The text below 12-4 states

If a port declaration does not include a net or variable type, then the port can be again declared in a net or variable declaration.

So the change suggested by Greg is allowed, rather than required (reg is of course a 'variable type'). In other words, if you don't have output reg x, then you are allowed to split this over two statements - output x and reg x.

SystemVerilog (1800-2012) is essentially identical - note that reg is an integer_vector_type, which is a data_type.

Note also that the word ANSI is not used in 1364, and SystemVerilog uses it incorrectly. Task/function/port declarations do not look like ANSI-C, because you can't specify lists of objects in C or C++. You can't declare or define a function like myfunc(int a, b), for example; it has to be (int a, int b).



回答3:

I think the problem is you are trying to push a non-ANSI style output from an always block.

you can either
1. move to ANSI style (which is more convenient anyway) or
2. add a wire, push the case outcome to it and 'assign' the output with the wire, 3. remove the 'always' block and write:
assign LEDs = (in == 0) ? 7'b1000000 : (in == 1) ? .....



标签: verilog