Flattening a design?

R

Ron

Guest
I just recently completed my first sizable Verilog design, and following
the advice of the Verilog books I have, made everything nicely
modularized and hierarchical, etc., so that it was very easy to read and
understand. Now I realize that my modular hierarchical design created
multiple instances of the lower level modules (multiply, divide, etc)
even though they are invoked sequentially rather than running in
parallel. I had sort of expected this to happen, but figured there would
be enough LUTs that it wouldn't matter - ha!

Now I'm in the process of "flattening" out my design so that it will
consist of a single huge top level module with only one layer of
hierarchy (ie; no module nesting except for the top level and one level
beneath that), and it's turning out to be just a messy as I expected.


I have two questions:

1. Is there any type of design methodology that addresses this problem
of duplicated modules? Should I toss my books out and do my next design
from the bottom-up and use only one level of hierarchy, or is there a
better approach?

2. Any advice or suggested books, articles, etc., on how best to flatten
my design without going crazy in the process from the complexity of it?
Its about 2000 lines of Verilog code.

Thanks,

Ron
 
Ron wrote:


1. Is there any type of design methodology that addresses this problem
of duplicated modules? Should I toss my books out and do my next design
from the bottom-up and use only one level of hierarchy, or is there a
better approach?
I prefer using a single synchronous block for each module
while minimizing the number of modules. This gives me
a single threaded description with structure handled
by synthesis.

2. Any advice or suggested books, articles, etc., on how best to flatten
my design without going crazy in the process from the complexity of it?
Its about 2000 lines of Verilog code.
There is little written about this style in verilog.
Most distrust variable style regs. But it does work.
It has popped up and been beaten down several times on this group.
http://groups.google.com/groups/search?q=verilog+single_block

Good luck.

-- Mike Treseler
 
On Wed, 19 Apr 2006 01:49:24 -0700, Ron <News5@spamex.com> wrote:

I just recently completed my first sizable Verilog design, and following
the advice of the Verilog books I have, made everything nicely
modularized and hierarchical, etc., so that it was very easy to read and
understand. Now I realize that my modular hierarchical design created
multiple instances of the lower level modules (multiply, divide, etc)
even though they are invoked sequentially rather than running in
parallel. I had sort of expected this to happen, but figured there would
be enough LUTs that it wouldn't matter - ha!

Now I'm in the process of "flattening" out my design so that it will
consist of a single huge top level module with only one layer of
hierarchy (ie; no module nesting except for the top level and one level
beneath that), and it's turning out to be just a messy as I expected.


I have two questions:

1. Is there any type of design methodology that addresses this problem
of duplicated modules? Should I toss my books out and do my next design
from the bottom-up and use only one level of hierarchy, or is there a
better approach?
I don't think this has anything to do with hierarchy. If I understand
your description correctly you want to time-multiplex your resources
(multipliers/dividers etc). You can do this and still keep the
hierarchy, actually it would be easier if you did. What you need is to
instantiate a ie multiplier only once and then write a state machine
at a higher level module which can multiplex the inputs of the
mutliplier to select different inputs at different times. Then you can
have different resource requesters and resources at lower levels and a
top level controller which manages them. Putting all of these at a
single hierarchy makes it more difficult to manage.
 
Mike Treseler wrote:
I prefer using a single synchronous block for each module
while minimizing the number of modules.
Yes, but the problem is that (for example) my multiplier is invoked
(instantiated) from several different modules at different hierarchical
levels. It's my understanding that there is no way for these seperate
multiplier modules to communicate with each other(?).
 
mk wrote:
I don't think this has anything to do with hierarchy. If I understand
your description correctly you want to time-multiplex your resources
(multipliers/dividers etc).
Yes, that's exactly right.

What you need is to
instantiate a ie multiplier only once and then write a state machine
at a higher level module which can multiplex the inputs of the
mutliplier to select different inputs at different times. Then you can
have different resource requesters and resources at lower levels and a
top level controller which manages them.
I think you may have touched on some key point that I have failed to
understand about Verilog. Lets say that I have a multiplier module
called MULT that is instantiated in different modules at different
hierarchical levels as mult1, mult2, and mult3. Now lets say I design a
controller for MULT called MULT_MUX and instantiate it as mult_mux1 in
the top level module of my design.

Question: How do I pass multiplication parameters to MULT_MUX
(mult_mux1) from the modules at lower levels of hierarchy and retrieve
the results?

What's confusing me is that If I instantiate MULT_MUX in each of the
lower level modules, I'll get three separate copies of it, which is of
course not what I want. I guess the broader question is: is it possible
for a low level module to communicate with a higher level module than
it's immediate "parent" without passing everything as I/O parameters up
and down through possibly several nesting levels of modules?

To help clarify things, I've posted a JPG image of the Xilinx Project
File window that shows the problematic hierarchy graphically at:
Ron.Dotson.org/temp/Ecm.jpg
 
If you want to time-multiplex the multiplier, then you wouldn't instantiate it multiple times at
lower levels. You'd have to just instantiate it once and have some sort of control over which
inputs it's using. You'd also need control over which module would receive the results, so that the
one's receiving results destined for another module ignore the values currently on the multiplier
output bus.


Ron wrote:
mk wrote:

I don't think this has anything to do with hierarchy. If I understand
your description correctly you want to time-multiplex your resources
(multipliers/dividers etc).


Yes, that's exactly right.

What you need is to
instantiate a ie multiplier only once and then write a state machine
at a higher level module which can multiplex the inputs of the
mutliplier to select different inputs at different times. Then you can
have different resource requesters and resources at lower levels and a
top level controller which manages them.


I think you may have touched on some key point that I have failed to
understand about Verilog. Lets say that I have a multiplier module
called MULT that is instantiated in different modules at different
hierarchical levels as mult1, mult2, and mult3. Now lets say I design a
controller for MULT called MULT_MUX and instantiate it as mult_mux1 in
the top level module of my design.

Question: How do I pass multiplication parameters to MULT_MUX
(mult_mux1) from the modules at lower levels of hierarchy and retrieve
the results?

What's confusing me is that If I instantiate MULT_MUX in each of the
lower level modules, I'll get three separate copies of it, which is of
course not what I want. I guess the broader question is: is it possible
for a low level module to communicate with a higher level module than
it's immediate "parent" without passing everything as I/O parameters up
and down through possibly several nesting levels of modules?

To help clarify things, I've posted a JPG image of the Xilinx Project
File window that shows the problematic hierarchy graphically at:
Ron.Dotson.org/temp/Ecm.jpg
 
Ron <News5@spamex.com> writes:

Question: How do I pass multiplication parameters to MULT_MUX
(mult_mux1) from the modules at lower levels of hierarchy and retrieve
the results?

What's confusing me is that If I instantiate MULT_MUX in each of the
lower level modules, I'll get three separate copies of it, which is of
course not what I want. I guess the broader question is: is it
possible for a low level module to communicate with a higher level
module than it's immediate "parent" without passing everything as I/O
parameters up and down through possibly several nesting levels of
modules?
Yes, you can communicate without explicit pins using hierarchical
references, e.g. top.mult.mutiplier and top.mult.multiplicand.
However, it is actually better generally to use explicit
parameters.

You are actually at the point where "design" is key. A design with
one multiplier that is time-multiplexed is significantly different
than a design with separate multipliers. The design with one
multiplier is significantly more complex (although generally taking
far less area and power) than one with multiple multipliers. the
reason it is more complex is that you have to make explicit all the
machinery which makes certain you are using that serializes
(arbitrates, multiplexes, controls) the access to the multiplier
circuitry so that only one multiplication is done at a time. To do so,
you need to create cotrol logic, muxes, registers, perhaps a FSM that
implements the serialization machinery. With multiple multipliers,
you don't have that, because each multiplier is dedicated to its one
use and when it is needed, it just performs its task.

I have recently became aware of tools by Celoxica and Forte that
attempt to solve this problem, or so I understand. You feed them a
high-level "algorithmic" model of your circuit and some criteria that
describe the timing constraints (bandwidth and latency) and they lay
down circuitry that instantiates the low-level resources and the
control mechanism to synchronize the uses. Depending on your
constraints they may share resources or instantiate them multiple
times. Some people suggest that this is "the next wave" of synthesis.
You might want to see if they are useful for solving your problem.

Hope this helps,
-Chris

*****************************************************************************
Chris Clark Internet : compres@world.std.com
Compiler Resources, Inc. Web Site : http://world.std.com/~compres
23 Bailey Rd voice : (508) 435-5016
Berlin, MA 01503 USA fax : (978) 838-0263 (24 hours)
------------------------------------------------------------------------------
 
Very well then. Thank you Chris and the others who replied to my question.

I shall set about adding some top level multiplexers and stringing wires
between them and the lower level modules that need the mux'd resource
(multiplier, divider, modulo, etc) forthwith. I just hope all that extra
routing doesn't cost more real estate than I gain by adding the
multiplexers in the first place.

Regards to all,

Ron
 

Welcome to EDABoard.com

Sponsor

Back
Top