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