Synthesis wrapper

H

hssig

Hi,

for synthesis we often face the situation that we have to write a
wrapper with input and output registers to see what the performance
etc. of the module looks like.

For example:


entity test_module is
port( Clk : in std_logic;
i_Data : in std_logic_vector(7 downto 0);
o_Data : out std_logic_vector(7 downto 0)
);
end test_module;

architecture rtl of test_module is
....
end rtl;

------------------------------------------------------------------------

The wrapper:

entity wrap_test_module is
port( Clk : in std_logic;
i_Data : in std_logic_vector(7 downto 0);
o_Data: out std_logic_vector(7 downto 0)
);
end wrap_test_module;

architecture wrapper of wrap_test_module is

component test_module ...


signal l_data_in, l_i_test_Data : std_logic_vector(7 downto 0);

begin

process(Clk)
begin
wait until rising_edge(Clk);
l_data_in <= i_Data;
o_Data <= l_i_test_Data;
end process;


i_test : test_module
port map ( Clk => Clk,
i_Data => l_data_in,
o_Data => l_i_test_Data
);

end wrapper;


Is there some possibility to introduce some automatism to create those
kind of wrappers ?
Has someone done that kind of job, for example with TCL ?

Cheers,
hssig
 
A

Andy

Not really automated, but simpler:

Why not just create another architecture of test_module that wraps the
rtl architecture?

architecture wrapped of test_module is

signal l_data_in, l_i_test_Data : std_logic_vector(i_data'range);

begin

-- register ins and outs
l_data_in <= i_data when rising_edge(clk);
o_data <= l_i_test_data when rising_edge(clk);

-- instantiate entity/arch for uut
entity work.test_module(rtl)
port map (
clk => clk,
i_data => l_data_in,
o_data => l_i_test_data
);

end wrapped;


Then synthesize the wrapped architecture of test_module.

Andy
 
B

backhus

Hi,

for synthesis we often face the situation that we have to write a
wrapper with input and output registers to see what the performance
etc. of the module looks like.

For example:

entity test_module is
port( Clk : in std_logic;
        i_Data : in  std_logic_vector(7 downto 0);
       o_Data : out std_logic_vector(7 downto 0)
      );
end test_module;

architecture rtl of test_module is
...
end rtl;

------------------------------------------------------------------------

The wrapper:

entity wrap_test_module is
port( Clk : in  std_logic;
        i_Data : in  std_logic_vector(7 downto 0);
       o_Data: out std_logic_vector(7 downto 0)
     );
end wrap_test_module;

architecture wrapper of wrap_test_module is

component test_module ...

signal l_data_in, l_i_test_Data : std_logic_vector(7 downto 0);

begin

process(Clk)
begin
     wait until rising_edge(Clk);
     l_data_in <= i_Data;
    o_Data     <= l_i_test_Data;
end process;

i_test : test_module
port map ( Clk => Clk,
                 i_Data => l_data_in,
                 o_Data => l_i_test_Data
               );

end wrapper;

Is there some possibility to introduce some automatism to create those
kind of wrappers ?
Has someone done that kind of job, for example with TCL ?

Cheers,
hssig

Hi,
why do you add output registers anyway, when your design is clocked.
In that case it should have registers on all outputs anyway.

And for the Inputs, it should also be obsolete, since your test design
should have registers at the outputs that connect to the DUTs inputs.

So this extra one clock latency at input and output of your DUT makes
no real sense.

Also, what kind of performance analysis are you doing?
Don't you trust the static timing analysis?
Or do you want to sqeeze out a little more than calculated?

Have a nice synthesis
Eilert
 
H

hssig

Hi backhus,
And for the Inputs, it should also be obsolete, since your test design
should have registers at the outputs that connect to the DUTs inputs.

yes, you are right. But when synthesizing modules stand-alone there
are not always given
input registers in the description of the module, so at least one
input register stage should
be inserted for test synthesis.
Don't you trust the static timing analysis?
Yes, I trust it. BUT without input registers the module is not
synthesized like it would be synthesized when being placed in the
"middle" of a design.

@ Andy: Good idea, thank you.

Cheers,
hssig
 
H

hssig

Hi Andy,

one question regarding your suggestion:

How do you handle both architectures that is does the architecture
"wrapped" have some entity (even the same entity?) ?


Cheers,
hssig
 
M

Mike Treseler

hssig said:
How do you handle both architectures that is does the architecture
"wrapped" have some entity (even the same entity?) ?

I would probably make entity_plain and entity_wrapped
to keep things simple.

-- Mike Treseler
 
F

Fredxx

Is there some possibility to introduce some automatism to create those
kind of wrappers ?
Has someone done that kind of job, for example with TCL ?

The closest you're going to get is to use ISE or other software to make a
test-bench from the desired file. All the components and signals will be
there, and all you'll need to do is modify a few lines.

Hope that idea helps.
 
A

Andy

Hi Andy,

one question regarding your suggestion:

How do you handle both architectures that is does the architecture
"wrapped" have some entity (even the same entity?) ?

Cheers,
hssig

Both architectures are for the same entity.

The entity and both architectures can be defined in the same or
different files. If the same file, most tools will require the wrapped
architecture to appear after the rtl architecture, which would appear
after the entity. In practice, it would be rather simple to just add
the wrapped architecture to the bottom of the same file with the
entity and rtl architecture. Or you could create a second file with
just the wrapped arch, and only include it in your test synthesis
runs.

When instantiating them, use configurations (and component
declarations) to specify which architecture you want, or skip all that
and just use direct entity instantiation. If this is a synthesis
wrapper, it is doubtful that any vhdl code would ever instantiate the
wrapped version; I wouldn't bother simulating the wrapped version. I
use components and configurations extremely rarely; direct entity (and
architecture) instantiation is just much easier. Just beware that
direct entity/architecture instantiation requires both the entity and
the architecture to have been previously compiled. If your tool has
that cool automatic compilation-reordering option, then you can just
throw the units and files in any order at it and the tool will figure
it out.

To instantiate the rtl version:
uut: entity work.test_module(rtl)
port map ...

To instantiate the wrapped version:
uut: entity work.test_module(wrapped)
port map ...

What is simpler about "entity work.entity_plain" compared to "entity
work.entity(rtl)"?

Andy
 
H

hssig

Hi,

it is not clear to me yet.

Concerning the configuration, is the following approach correct ?:

1. file "test_module.vhd" with entity "test_module" and architectures
"rtl", "wrapped"
2. file "test_module_TOP.vhd" for configuration:

The second file:

library ieee;
use ieee.std_logic_1164.all;

entity test_module_TOP is
port( Clk : in std_logic;
i_Data : in std_logic_vector(7 downto 0);
o_Data : out std_logic_vector(7 downto 0)
);
end test_module_TOP;

architecture TOP of test_module_TOP is
begin

uut: entity work.test_module(wrapped)
port map ( Clk => Clk,
i_Data => i_Data,
o_Data => o_Data
);
end TOP;



When importing both files in Lattice-ispLEVER 7.2 I get the warning
"Circular hierarchy reference found" but nevertheless I am able to
synthesize it with different architectures.

Is that the way you suggested or did I get something wrong?


When regarding the motivation of my post to have a quick way of
building a synthesis wrapper for a given module, I have to assert that
now I have to write two additional modules (architecture "wrapped",
module "test_module_TOP"). Is that easier than my first
proposal "wrap_test_module"? I think not.


Cheers,
hssig
 
M

moogyd

Hi,

it is not clear to me yet.

Concerning the configuration, is the following approach correct ?:

1. file "test_module.vhd" with entity "test_module" and architectures
"rtl", "wrapped"
2. file "test_module_TOP.vhd" for configuration:

The second file:

library ieee;
use ieee.std_logic_1164.all;

entity test_module_TOP is
port( Clk : in std_logic;
      i_Data : in  std_logic_vector(7 downto 0);
      o_Data : out std_logic_vector(7 downto 0)
      );
end test_module_TOP;

architecture TOP of test_module_TOP is
begin

uut: entity work.test_module(wrapped)
port map ( Clk    => Clk,
           i_Data => i_Data,
           o_Data => o_Data
         );
end TOP;

When importing both files in Lattice-ispLEVER 7.2 I get the warning
"Circular hierarchy reference found" but nevertheless I am able to
synthesize it with different architectures.

Is that the way you suggested or did I get something wrong?

When regarding the motivation of my post to have a quick way of
building a synthesis wrapper for a given module, I have to assert that
now I have to write two additional modules (architecture "wrapped",
module "test_module_TOP"). Is that easier than my first
proposal "wrap_test_module"? I think not.

Cheers,
hssig

Hi,

Maybe I have misunderstood here...

Why don't you add timing constraints to the inputs and outputs?

e.g. set_input_timing -clock sys_clk ck_q_delay_plus_margin
[all_inputs] ?

where ck_q_delay_plus_margin reflects the register delay plus some
margin (routing, clock skew etc)

(Obviously, I don't know what synthesis tool you are using, but if
it's a real one, this should be possible)

Steven
 
H

hssig

Hi,

Maybe I have misunderstood here...

Why don't you add timing constraints to the inputs and outputs?

Hi,

as Brian stated before, input registers are typically a long way from
the logic, using
input setup constraints do not make it better.

Cheers,
hssig
 
M

moogyd

Hi,

as Brian stated before, input registers are typically a long way from
the logic, using
input setup constraints do not make it better.

Cheers,
hssig

Hi,

But you can still include this in the constraints. i.e. The
input_delay is increased to take into account this additional routing
delay.

If you cannot specify this input delay (or at least make a reasonable
estimate), then you have problems anyway.

Steven

p.s. If I was to use the currently suggested method of adding
registers for synthesis only, I would use a generic and a generate to
include/exclude I/O registers.
 
A

Andy

Hi,

it is not clear to me yet.

Concerning the configuration, is the following approach correct ?:

1. file "test_module.vhd" with entity "test_module" and architectures
"rtl", "wrapped"
2. file "test_module_TOP.vhd" for configuration:

The second file:

library ieee;
use ieee.std_logic_1164.all;

entity test_module_TOP is
port( Clk : in std_logic;
      i_Data : in  std_logic_vector(7 downto 0);
      o_Data : out std_logic_vector(7 downto 0)
      );
end test_module_TOP;

architecture TOP of test_module_TOP is
begin

uut: entity work.test_module(wrapped)
port map ( Clk    => Clk,
           i_Data => i_Data,
           o_Data => o_Data
         );
end TOP;

When importing both files in Lattice-ispLEVER 7.2 I get the warning
"Circular hierarchy reference found" but nevertheless I am able to
synthesize it with different architectures.

Is that the way you suggested or did I get something wrong?

When regarding the motivation of my post to have a quick way of
building a synthesis wrapper for a given module, I have to assert that
now I have to write two additional modules (architecture "wrapped",
module "test_module_TOP"). Is that easier than my first
proposal "wrap_test_module"? I think not.

Cheers,
hssig

I'm not familiar with isplever, but you should be able to specify the
entity and architecture for your top level synthesis unit. If so, you
do not need test_module_top at all. Just synthesize the wrapped
architecture of test_module, and you're done.

You do not need configurations for this, because the wrapped
architecture directly instantiates the entity (and architecture) not a
component. If the RTL architecture of test_module includes components,
then you will either need a configuration (you can invoke the
configuration from the wrapped architecture) or you will have to
modify it to use entity instantiations.

Andy
 
M

Mike Treseler

moogyd said:
But you can still include this in the constraints. i.e. The
input_delay is increased to take into account this additional routing
delay.

True, but since the module does not go out to pins
in the real world, figuring out that constraint
might more trouble than using the wrapper.
If you cannot specify this input delay (or at least make a reasonable
estimate), then you have problems anyway.

True for the top entity, inside Fmax is the thing.

-- Mike Treseler
 
H

hssig

Hi Andy,

I'm not familiar with isplever, but you should be able to specify the
entity and architecture for your top level synthesis unit. If so, you
do not need test_module_top at all. Just synthesize the wrapped
architecture of test_module, and you're done.

Are you working with Altera Quartus ? I have installed it (web edition
8.1) so that
I can crosscheck with it.

My first steps in Quartus:
Import "test_module.vhd" with "test_module" as entity and "rtl" as
architecture,
import "wrapped.vhd" with "wrapped" as architecture.

If I mark an imported file I can choose (right mouse click) "Set as
Top-Level Entity", but I
cannot choose the synthesis architecture. Is there a possibility to
select the architecture
for synthesis ?

Cheers,
hssig
 
A

Andy

Hi Andy,


Are you working with Altera Quartus ? I have installed it (web edition
8.1) so that
I can crosscheck with it.

My first steps in Quartus:
Import "test_module.vhd" with "test_module" as entity and "rtl" as
architecture,
import "wrapped.vhd" with "wrapped" as architecture.

If I mark an imported file I can choose (right mouse click) "Set as
Top-Level Entity", but I
cannot choose the synthesis architecture. Is there a possibility to
select the architecture
for synthesis ?

Cheers,
hssig

I use simplify for synthesis, I'm not sure how to do it in Quartus,
maybe Treseler knows?

Andy
 
M

Mike Treseler

Andy said:
I use simplify for synthesis, I'm not sure how to do it in Quartus,
maybe Treseler knows?

Quartus supports configurations,
so Andy's configuration example should work.
I think using two entity names is less confusing for synthesis.

Otherwise, quartus insists on a single top entity:
"Note: The Quartus II software cannot process VHDL designs with two or
more entities of the same name even if the entities are compiled into
separate custom libraries."

-- Mike Treseler
 
M

moogyd

True, but since the module does not go out to pins
in the real world, figuring out that constraint
might more trouble than using the wrapper.


True for the top entity, inside Fmax is the thing.

    -- Mike Treseler

Hi,

Maybe I am over-complicating the issue.

If every module considered "internal" Fmax only, and assumed that
registers where added elsewhere, then you are storing up a lot of
trouble during top level synthesis.

The module designer needs to know the environment the block is used in
i.e. whether I/Os are registered elsewhere or not.

Steven
 
K

KJ

If every module considered "internal" Fmax only, and assumed that
registers where added elsewhere, then you are storing up a lot of
trouble during top level synthesis.

The module designer needs to know the environment the block is used in
i.e. whether I/Os are registered elsewhere or not.

You're missing the point. The reason for adding the surrounding flops
is to be able to get a rough measure of the timing performance (i.e.
Fmax) of a module that is intended to be internally with no direct
connections to any I/O pins.

If the module is intended to interact directly with I/O pins, you
would not add flops to those I/O. Typically though the set of all
module I/O that make up an entire FPGA design will have a fair number
of I/O that are primarily intended to be connected with other internal
FPGA signals.

Adding the flops changes (and likely breaks) the intended
functionality of the module. Adding the flops does not necessarily
mimic exactly how the module actually will be used in a design. But
adding the flops does give a method to roughly mimic the usage and get
approximate timing performance. Connecting the I/O for a module
directly to I/O pins of an FPGA does not mimic this nearly as well.

Kevin Jennings
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,768
Messages
2,569,575
Members
45,053
Latest member
billing-software

Latest Threads

Top