0
\$\begingroup\$

I have written a testbench in Verilog which creates 3 copies of a module and passes data back and forth with my main module test as anticipated:

test Sen1(A,B,C,D,E,F,CLK);
test Sen2(A,B,C,D,E,F,CLK);
test Sen3(A,B,C,D,E,F,CLK);

Is module instantiation only valid for simulating behavioral/functional models? I'm wondering what I need to do to create a synthesizeable version of this. On the one hand it seems that my module called test could aggregate all of the ports like this:

test (A1,A2,A3,B1,B2,B3,....CLK)

but then I'll have single modules with a lot of ports which would clutter my code (CLK would need to be shared between instantiations BTW). I'd like to know your thoughts on the correct approach for reorganizing/reformulating my module instantiations into a code structure that I can synthesize and assign pins to.

\$\endgroup\$
1
\$\begingroup\$

At the top of your hierarchy you MUST have one module which contains all the logic.

but then I'll have single modules with a lot of ports which would clutter my code

There is no simple solution to 'unclutter' your code. The only way is to use sensible port and signal names.
It is not unusual for digital designs to have lots of signals at the top level. That is why you find FPGAs with 400+ I/O ports. Inside a design the port connections are an order of magnitude bigger.

I'd like to know your thoughts on the correct approach for reorganizing/reformulating my module instantiations into a code structure that I can synthesize and assign pins to.

That is not possible unless we know a lot more what your code does and all the ports you have. The phrase "Cleanliness is next to godliness" comes to mind here. The names in your example above are the quintessence of how not to name ports.

\$\endgroup\$
  • \$\begingroup\$ Each test module is tied to an external communications node and has its own 6-state FSM with 6 states port names representing communication lines to/from the node. Also, the three module instances don't communicate with each other however they will share a common clock. A separate module will aggregate the data from each node. You've given me a lot to think about. At one level it sounds like an explicit FSM needs to be defined for each module. Please comment on on whether or not module instantiation as shown in my OP is possible with synthesis code. Thanks for the feedback. \$\endgroup\$ – reacher33 Jul 29 '18 at 20:22
1
\$\begingroup\$

You can only have one instance of the "Top-Level Module" in a design, it is this single module instance that will be your hardware. The same in fact goes for simulation - you have a single test-bench module that your simulation tool uses to build the hierarchy.

If you think about it, how would the synthesis tools know which port is which if you were able to request multiple instances. You would have several ports call A, several called B, and so on. If these are not connected to the same pin, you would need some way to differentiate them.

If you want multiple instances of your module to form the top level, you will need to create a wrapper which instantiates the number of instances you require. The simplest way to do this if you want to be able to change the number of instantiations easily and don't want to redeclare lots of ports, is to use generate loops:

test Sen1(A,B,C,D,E,F,CLK);
test Sen2(A,B,C,D,E,F,CLK);
test Sen3(A,B,C,D,E,F,CLK);

could become:

module #(
    parameter instances = 3 //Change this value to set number of instances
) SenTop (
   ... [instances-1:0] A,
   ... [instances-1:0] B,
   ...
   ... [instances-1:0] F,
   input CLK,
);
    genvar i;
    generate for (i = 0; i < instances; i=i+1) begin : inst_loop
        test Sen(A[i],B[i],C[i],D[i],E[i],F[i],CLK);
    end endgenerate
end

You could also connect the same input or inout pin to multiple instances if required (e.g. CLK could be single bit and connect to all instances).

If any of the pins in the module instance are multi-bit, you would have to have some unpacking in your loop. For example if say A was a 2-bit bus in the submodule, you could have something like:

module #(
    parameter instances = 3 //Change this value to set number of instances
) SenTop (
   ... [instances*2-1:0] A,
   ... [instances  -1:0] B,
   ...
   input CLK,
);
    genvar i;
    generate for (i = 0; i < instances; i=i+1) begin : inst_loop
        localparam j = 2 * i;
        test Sen(A[j+:2],B[i], ... ,CLK);
    end endgenerate
end
\$\endgroup\$

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.