Sigasi logo

Table Of Contents

Previous topic

Making code clearer

Support

Improving the design structure

Add Port

Motivation

Adding a new port to and entity is a common structural refactoring in preparation of adding new functionality.

Adding a port to an entity requires changes to the corresponding component declarations and instantiations in order to keep the design consistent. The Add Port refactoring does this automatically.

Example

Suppose you have an entity like this:

entity calc is
    port(... start: in boolean; ...)
end calc;

Within the design it may be declared and instantiated as follows:

component calc is
    port(... start: in boolean; ...)
end calc;
...
calc_inst: calc
    port map(... start => start, ...);

Now suppose you need to add an output port ready to the calc entity. You can do this by applying the Add Port refactoring to the entity. You will need to specify the name, type, and direction of the port. The refactored result will be as follows:

entity calc is
    port(... start: in boolean; ready: out boolean; ...)
end calc;
...
component calc is
    port(... start: in boolean; ready: out boolean; ...)
end calc;
...
calc_inst: calc
    port map(... start => start, ready => open, ...);

Note that the ready port is stubbed to an open connection of the instance, presumably before it will be connected to other instances.

Connect Instance

Motivation

Adding new connections to instances is a common design requirement. This requires changes on various places in the design hierarchy. The Connect Instance refactoring does this automatically.

Example

Suppose you have a design as follows:

entity calc is
    port(... start: in boolean; ready: out boolean; ...)
end calc;

entity ctrl is
    port(... start: out boolean; ...)
end ctrl;

...
signal start: boolean;
...
calc_inst: calc
    port map(... start => start, ready => open, ...);
...
ctrl_inst: ctrl
    port map(... start => start, ...);

Note

To keep this example short, component declarations are not shown, If they are present, they will be kept up to date by the refactoring.

Note that ready is an unconnected port of the calc_inst instance. Suppose you want to connect to the ctrl_inst instance. You can do by applying the Connect Instance refactoring on ctrl_inst. The refactoring tool will present a number of possible signals and ports you can connect to. Select the ready port, and the refactored design will look as follows:

entity calc is
    port(... start: in boolean; ready: out boolean; ...)
end calc;

entity ctrl is
    port(... start: out boolean; ready: in boolean; ...)
end ctrl;

...
signal start: boolean;
signal ready: boolean;
...
calc_inst: calc
    port map(... start => start, ready => open ready, ...);
...
ctrl_inst: ctrl
    port map(... start => start, ready => ready, ...);

The refactoring infers the type and direction of a new port of the ctrl entity. It updates the entity interface and its component declaration if applicable. It also declares a new ready signal, and updates the port maps of the instantiations.

Remove Port

Disconnect Instance

Add Generic

Remove Generic

Encapsulate Concurrent Statements

Motivation

At some point in the design process, it may be desirable to modify the design hierarchy. For example, adding a new level of hierarchy may make the design clearer and create a new module that can be reused.

Creating a new level of hierarchy manually implies typically a lot of cumbersome work. The Encapsulate Concurrent Statements refactoring does all the work automatically.

Example

As an example, we use the architecture of clock generator module. It contains a process for a clock driver:

architecture BEH of clock_generator is

constant PERIOD: time := 50 ns;

begin

CLOCK_DRIVER: process is
begin
   clock <= '0';
   wait for PERIOD/2;
   clock <= '1';
   wait for PERIOD/2;
end process CLOCK_DRIVER;

end architecture BEH;

Suppose we need to add more output clocks to the clock generator module. Instead of duplicating the clock driver process, a better idea is to make it reusable. We can do that by encapsulating it in its own module. This can be accomplished automatically by applying the Encapsulate Concurrent Statements refactoring to the clock driver process.

After refactoring the clock generator architecture is modified as follows:

architecture BEH of clock_generator is

constant PERIOD: time := 50 ns;

begin

CLOCK_DRIVER: process is
begin
   clock <= '0';
   wait for PERIOD/2;
   clock <= '1';
   wait for PERIOD/2;
end process CLOCK_DRIVER;

clock_driver_inst: entity work.clock_driver(RTL)
    generic map (
        PERIOD => PERIOD
        )
    port map (
        clock => clock
        );

end architecture BEH;

Moreover, a new clock driver module has been created:

entity clock_driver is
    generic (PERIOD: time);
    port (clock: out std_logic);
end entity clock_driver;

architecture RTL of clock_driver is
begin
    CLOCK_DRIVER: process is
    begin
       clock <= '0';
       wait for PERIOD/2;
       clock <= '1';
       wait for PERIOD/2;
    end process CLOCK_DRIVER;
end architecture RTL;

Note that the refactoring understands how to map signals to ports with the correct directions, and how to map constants to generics.

Quite a lot of code changes were made, even though this was a “simple” example, with only one concurrent statement being encapsulated. In general, the Encapsulate Concurrent Statements refactoring can encapsulate an arbitrary number of concurrent statements.

Copyright © 2008-2011 Sigasi nv - "Sigasi" is a registered trademark of Sigasi nv