2
\$\begingroup\$

I created a simple 8-3 encoder module (called encoder8to3) to replace a few repeated instances of Verilog code. I then tried to use the module in levers2.v. I get the following error when I run a Verilog test file:

ERROR:HDLCompiler:69 - "C:/Documents and Settings/me/xilinx projects/wQCBG/levers2.v" Line 132: is not declared.

I see all sorts of examples of how to create modules, but not many on how to use the ones that are created. All I find are snippets of the use and not the declaration.

Will someone tell me how to properly declare encoder8to3 in levers2 please?

EDIT - codez, levers2, pared down.

module levers2(
     input [7:0] LL,
     input [7:0] RL,
    output reg [10:0] DIVISOR,
     output reg TD_ANY_MARK,
     output reg TD_NUMBERS,
     output reg TD_ONE_MARK,
     output reg TD_DONT_DISENGAGE,
    output reg FAULT
    );

(snip)

reg [7:0] x;

always @(LL, RL) begin
(snip)
        FAULT <= 0;
        /*
        encoder8to3(LL, x, FAULT);
(snip)

The encoder module itself is:

module encoder8to3(
    input [7:0] A,
    output reg [2:0] B,
    output reg F
    );

    always @(A) begin
        F <= 0;
        if (A[0]) B <= 0;
        else if (A[1]) B <= 1;
        else if (A[2]) B <= 2;
        else if (A[3]) B <= 3;
        else if (A[4]) B <= 4;
        else if (A[5]) B <= 5;
        else if (A[6]) B <= 6;
        else if (A[7]) B <= 7;
        else F <= 1;
    end

endmodule

I'm learning, and I'm just having some trouble with Verilog syntax. So somehow, I need to tell levers2 (the first piece of code) where to find encoder8to3 or perhaps, like c, just warn the compiler that the module will eventually be used.

\$\endgroup\$
  • \$\begingroup\$ Show us your code for both modules. \$\endgroup\$ – Dave Tweed Sep 14 '12 at 12:07
  • 1
    \$\begingroup\$ Which line is line 132? \$\endgroup\$ – Martin Thompson Sep 14 '12 at 13:21
  • \$\begingroup\$ @MartinThompson probably the encoder8to3 line - I'm at work now and can't check for sure. \$\endgroup\$ – Tony Ennis Sep 14 '12 at 14:08
4
\$\begingroup\$

You need to give the instance a name (see below)

It also looks like you may be trying to declare it in an always block, this won't work. Declare it outside any blocks (e.g. at the top of the module)

Also, using the "connection by name" (or named association) method of instantiation rather than "connection by order" (or positional association) is less prone to accidental errors from getting the order wrong, especially with modules with many ports.

So the instantiation for connection by name would be

encoder8to3 enc_instance (.A(LL), .B(x), .F(FAULT));

With this method it could be written like this and still be correctly connected:

encoder8to3 enc_instance (.A(LL), .F(FAULT), .B(x));

Whereas using:

encoder8to3 enc_instance (LL, FAULT, x);

would connect B to FAULT and F to x.

Here's a reasonable pdf on modules and instantiating them. I agree good Verilog tutorials are quite thin on the ground (compared to something like C) so starting out can be a bit bewildering.
If you can find a copy at a reasonable price, I do highly recommend the Pong Chu book "FPGA Prototyping with Verilog Examples" I mentioned in my answer to your other question, as well as the focus on synthesis I mentioned, it goes through everything you need to start writing decent code, and is very clear and concise.
There is also a google mailing list for Verilog you might find of use, and fpga4fun has some good tutorials and a forum. And of course there is here :-)

EDIT - about where to declare the module:

The instantiation only connects the ports together, so where you declare it (outside a block) doesn't matter.
If you want to do something with this module inside the always block use some intermediate logic. Create a couple of registers, use the always block to manipulate them as desired, then tie these to the instantiated module ports (in the instantiation).

The way you have it at the moment, the instantiated module can be seen as in parallel with your module rather than inside it, as it just connects directly to the inputs and output of the module. Have a look at the RTL schematic to see what is being generated by the code (under synthesis in the design tab)

\$\endgroup\$
  • \$\begingroup\$ There is a decent Verilog tutorial at asic-world.com/verilog/veritut.html \$\endgroup\$ – dwikle Sep 14 '12 at 13:42
  • \$\begingroup\$ @dwikle and Oli, thanks, I have found those sites. They're very good. I'll look for that book. Currently I don't always know enough to search effectively. \$\endgroup\$ – Tony Ennis Sep 14 '12 at 14:32
  • \$\begingroup\$ So what I missed is the instance name for the new circuit - enc_instance above. If I were using the ISE schematic tool, I'd see a new 'chip' on the schematic called enc_instance. \$\endgroup\$ – Tony Ennis Sep 14 '12 at 14:47
  • \$\begingroup\$ Yes, you need the name of the instance (just like instantiating a variable or class in C, C++, Java, etc - you can't just put int = 0;, or Button = new Button(); you need to put something like int i = 0; or Button but = new Button();) When you use the schematic tool and place an instance of something, you will see the underlying HDL update to add the instantiation code with the name of the symbol (whatever you have called it) \$\endgroup\$ – Oli Glaser Sep 14 '12 at 16:18
  • \$\begingroup\$ As I think about it, this isn't really a module in the software sense - this is like a "c" macro substitution. That is, if there are 3 uses of encoder8to3, the Verilog compiler will produce three independent sets of gates that perform encoder8to3. \$\endgroup\$ – Tony Ennis Sep 14 '12 at 18:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.