Copyright: Copyright ® 1996-1999 Synopsys, Inc.


Application Notes

These application notes describe how to use FPGA Express in your design flow:

Mixing HDL and Netlist Input

How to Specify Finite State Machines

Operator Sharing in FPGA Express

Simplifying an HDL Design with FPGA Express Built-in Module Generation

Using the FPGA Express Time Tracker

How to Define Timing Constraints in FPGA Express

How to Define Multicycle Timing Constraints

For Altera devices, see these application notes:

Design Flow Targeting Altera FLEX and MAX Devices

How To Use Memory Elements with Altera Devices

Using Altera MegaWizard Components in FPGA Compiler II and FPGA Express


Mixing HDL and Netlist Input

To mix HDL and netlist inputs in FPGA Express:

1.	Create the appropriate netlist format.

If your design contains schematics, you must export them to EDIF format in your schematic editor.

2.	Instantiate the netlist and HDL modules.

Case 1: HDL module instantiating netlist modules

The netlist modules must be instantiated in the HDL code as black boxes.

In VHDL: Declare the corresponding components and instantiate them. Do not declare any architecture block for these modules—the description is derived from the netlist.

In Verilog: Instantiate the corresponding modules. Also include empty modules to provide port direction information.

Case 2: Netlist module instantiating HDL modules

The HDL modules must appear in the netlist as black boxes. Their functionality will be derived from synthesis.

3.	Synthesize your design.

a.	Add all the netlist and HDL files to your project in FPGA Express.

b.	Select the top-level design and create an implementation.


How to Specify Finite State Machines

This application note contains VHDL and Verilog templates for finite state machines (FSMs). You can create any FSM using these templates, which give optimal synthesis results with FPGA Express.

VHDL Template

In VHDL, you can enumerate states symbolically or you can assign values to states with the ENUM_ENCODING attribute.

FPGA Express supports automatic FSM encoding for enumerated types in VHDL. If you want to take advantage of automatic encoding:

Use the VHDL template without the ENUM_ENCODING attribute.

From Synthesis > Options > Project, choose One Hot,  Binary, or Zero One Hot encoding. The default is One Hot.

Use the ENUM_ENCODING attribute when you want to control the state encoding.

This example of a very simple counter shows the VHDL template using an enumerated type for states (shown in bold text).

Note that the WHEN OTHERS statement is not needed for this template, though it can be used if required.

library IEEE;
use IEEE.std_logic_1164.all;

entity shift_enum is
   port (CLK,RST : in bit;
 O : out std_logic_vector (2 downto 0));
end shift_enum;

architecture beh of shift_enum is

type state_type is (S0, S1, S2);
-- Do not use the following 2 lines for automatic FSM extraction:
attribute ENUM_ENCODING: STRING;
attribute ENUM_ENCODING of state_type: type is "001 010 100";

signal machine : state_type;

begin
   process (CLK,RST)
   begin
      if RST= '1' then
         machine <= S0;
      elsif CLK= '1' and CLK'event then
case machine is
when S0 => machine <= S1;
when S1 => machine <= S2;
when S2 => machine <= S0;
end case;
      end if;
 end process;

with machine select
0 <= "001" when S0,
     "010" when S1,
     "100" when S2;
end;

Verilog Template

Verilog does not support the enumerated type. However, you can use the Verilog template to design a finite state machine and fully control the state encoding.

In Verilog, state values are defined with the parameter statement. These are the conventions for this Verilog template:

Use the parameter statement to define state values.

Use a CASE statement and the Synopsys directive //synopsys parallel_case full_case to describe the state machine. parallel_case indicates that all states are mutually exclusive and full_case indicates that all possible states are specified.

This example of the same simple counter described in the VHDL template shows the Verilog template using the parameter statement for state values.

module shift (clk, rst, out);
input clk, rst;
output [2:0] out;
parameter [2:0]
    S0 = 3'd1,
    S1 = 3'd2,
    S2 = 3'd4;

reg [2:0]
    state, next_state ;

always @ (state)
begin
case (state) // synopsys parallel_case full_case
S0: next_state = S1;
S1: next_state = S2;
S2: next_state = S0;
endcase
end

always @ (posedge clk or posedge rst)
begin
  if (rst) state <= S0;
  else state <= next_state;
end

assign out = state;
endmodule

FPGA Express provides the most flexible implementations of FSMs. FSMs can be implemented as either safest, to recover from invalid state transitions, or fastest and smallest when recovery is not required. Here are some tips on how to describe an FSM in VHDL for FPGA Express to achieve the best Quality of Results (QoR).

1.	Use an enumerated type for states. This guarantees that the state vector can be extracted and reencoded by FPGA Express. Here's an example:

TYPE state_type IS (start, sa, sb, sc, sd, se, sf, sg);

2.	Use a CASE statement to describe the logic of the next state and outputs. Here's an example:

process (clk, rst)
    begin
        IF rst='1' THEN
            current_state <= start;
            outputs <= x;
        ELSIF clk = '1' AND clk'event THEN
            CASE current_state IS
                WHEN start =>
                    <Describe next state and outputs>
                WHEN sa =>
                    <Describe next state and outputs>
            .
            .
            .
            END CASE;
        END IF;
END PROCESS;

3.	Choose One Hot, Binary, or Zero One Hot encoding style from the Synthesis->Options->Project dialog box. For one-hot encoding, you can achieve better QoR by omitting when others in the VHDL source code if recovery is not required.

The statement

when others =>
next_state <= start;

in the next state logic description covers all states that aren't specified including invalid states. For example, any state with more than one bit of the state vector at logic one is invalid in a one-hot implementation. If a transition to an invalid state occurs, the FSM will revert to state start on the following clock cycle. FPGA Express generates next state logic to ensure that the implementation is an exact match to the VHDL description and the FSM is able to recover from invalid state transitions.

However, if guaranteed recovery from invalid state transitions is not required, a smaller and faster implementation of the one-hot FSM can be generated by eliminating when others in the VHDL source code. Enumerated states that are not specified in the next state logic description must either be specified or removed from the enumerated type definition. The selection logic for all of the invalid states from when others is eliminated resulting in a smaller and faster one-hot FSM.


Simplifying an HDL Design with FPGA Express Built-in Module Generation

FPGA Express automatically generates and implements common arithmetic functions such as multiplication and addition using built-in module generation. These modules are logic circuits that have optimal performance and area based on the target architecture.

Designs that are synthesized using built-in module generation consistently obtain the best results compared to other implementations. FPGA Express built-in module generation supports the Altera architectures.

For details, see Benefits of Built-in Module Generation.

Available Functions

The FPGA Express built-in module generator infers the following functions from HDL source code and implements them as architecture-specific, optimized modules based on the width of the operands:

Multiplier (* operator)

Adder, subtractor, and adder/subtractor (+ and - operators)

Incrementer, decrementer, and incrementer/decrementer (+ and - operators)

Two's complementer (unary - operator)

Comparator (relational operators <, <=, >, >=, =, /=, ==, !=)

Multiplexer (selection statements or VHDL select operator)

HDL Examples

Built-in module generation is triggered in two ways. Arithmetic and relational modules are generated using operators in HDL code. Multiplexers are generated from either selection statements or the select operator, which is unique to VHDL.

For examples in VHDL and Verilog, see these topics:

Arithmetic and Relational Module Inference Examples

Multiplexer Inference Examples


Benefits of Built-in Module Generation

Built-in module generation provides advantages in circuit performance, software performance, and design methodology.

Optimal Circuit Performance

FPGA Express can optimize generated modules with logic outside their boundaries, unlike modules that are instantiated as black boxes. The resultant logic is smaller and faster than a black box implementation. This is especially true in the case of modules with constant inputs, as the constant values can be propagated throughout the module during optimization.

Inferred operators can be automatically shared, which can further optimize circuits. For more information about operator sharing, see Operator Sharing and Operator Sharing in FPGA Compiler II Altera Edition.

Faster Runtimes

Module generation is substantially faster than conventional synthesis because much of the module logic is immediately mapped to architecture-specific features.

Because FPGA Express modules are mapped directly to PLD primitives, they do not require additional synthesis and optimization by vendor tools. FPGA Express

Flexible Design Methodology

HDL source files are portable to other PLD architectures because they contain no architecture-specific components. Instantiations of functions into HDL source code as black boxes originating from FPGA vendors' module generators or macro libraries can become nonsynthesizable if you change the target architecture. Instead, FPGA Express generates logic that uses architecture-specific features that allow designers to remain at the higher level of abstraction of register transfer level (RTL) HDL.

Because technology-specific module generation algorithms are included for each supported FPGA family, the performance and area of the modules are optimized specifically for each architecture. The performance and area characteristics equal or exceed those of other sources.

The built-in module generator simplifies design entry. Built-in module generation is invoked from HDL statements instead of HDL functions, making the source code more intuitive. For example, if A, B, and C are 16-bit vectors, the statement:

C <= A + B;

is more intuitive and easier to code than:

C <= add_unsigned(A, B);


Arithmetic and Relational Module Inference Examples

VHDL Examples

The following are some examples of arithmetic and releational module inference in VHDL. Currently, it is not possible to infer both signed and unsigned operators in the same entity-architecture pair.

-- all unsigned arithmetic
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;

entity unsigned_modgen is
  generic(
width : positive := 16
);
  port(
a, b : in std_logic_vector(width - 1 downto 0);
product : out std_logic_vector(2 * width - 1 downto 0);
a_minus_b : out std_logic_vector(width - 1 downto 0);
a_plus_b : out std_logic_vector(width - 1 downto 0);
a_eq_b : out std_logic;
a_ne_b : out std_logic;
a_gt_b : out std_logic;
a_ge_b : out std_logic;
a_lt_b : out std_logic;
a_le_b : out std_logic;
rst, clk : in std_logic;
updown : in std_logic;  -- 1 - up / 0 - down
counter : buffer std_logic_vector(width - 1 downto 0)
);
end unsigned_modgen;

architecture rtl of unsigned_modgen is

begin  --  rtl

  product <= a * b;
  a_minus_b <= a - b;
  a_plus_b <= a + b;

  a_eq_b <= '1' when a = b else '0';

  a_ne_b <= '1' when a /= b else '0';

  a_gt_b <= '1' when a > b else '0';

  a_ge_b <= '1' when a >= b else '0';

  a_lt_b <= '1' when a < b else '0';

  a_le_b <= '1' when a <= b else '0';

  process(clk, rst)
  begin
    if (rst = '1') then
      counter <= (others => '0');
    elsif (clk = '1' and clk'event) then
      if (updown = '1') then  -- infer an incrementer/decrementer
        counter <= counter + 1;
      else
        counter <= counter - 1;
      end if;
    end if;
  end process;

end rtl;

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

-- all signed arithmetic
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_signed.all;

entity signed_modgen is
  generic(
width : positive := 16
);
  port(
a, b : in std_logic_vector(width - 1 downto 0);
product : out std_logic_vector(2 * width - 1 downto 0);
a_ne_b : out std_logic;
a_gt_b : out std_logic;
minus_b : out std_logic_vector(width - 1 downto 0);
rst, clk : in std_logic;
updown : in std_logic;  -- 1 - up / 0 - down
counter : buffer std_logic_vector(width - 1 downto 0)
);
end signed_modgen;

architecture rtl of signed_modgen is

begin  --  rtl

  product <= a * b;
  minus_b <= - b;

  a_ne_b <= '1' when a /= b else '0';

  a_gt_b <= '1' when a > b else '0';

  process(clk, rst)
  begin
if (rst = '1') then
  counter <= (others => '0');
elsif (clk = '1' and clk'event) then
  if (updown = '1') then  -- infer an incrementer/decrementer
    counter <= counter + 1;
  else
    counter <= counter - 1;
  end if;
end if;
  end process;

end rtl;

Verilog Examples

The following are some examples of arithmetic module inference in Verilog. In Verilog, all arithmetic and relational operations are assumed to be unsigned, except for the unary negation (-) operation. Currently, it is not possible to infer signed modules in Verilog.

module modgen(a, b, product, a_minus_b, a_plus_b, a_eq_b, a_ne_b, a_gt_b, a_ge_b, a_lt_b, a_le_b, minus_b, rst, clk, updown, counter);

parameter width = 16;
input [width-1:0] a, b;
output [2*width-1:0] product;
output [width-1:0] a_minus_b, a_plus_b, minus_b, counter;
reg [width-1:0] counter;
input rst, clk, updown;
output a_eq_b, a_ne_b, a_gt_b, a_ge_b, a_lt_b, a_le_b;

assign product = a * b;
assign a_minus_b = a - b;
assign a_plus_b = a + b;
assign a_eq_b = a == b;
assign a_ne_b = a != b;
assign a_gt_b = a > b;
assign a_ge_b = a >= b;
assign a_lt_b = a < b;
assign a_le_b = a <= b;
assign minus_b = - b;

always @(posedge clk or posedge rst)
  if (rst)
    counter = 0;
  else if (updown)  // infer an incrementer/decrementer
    counter = counter + 1;
  else
    counter = counter - 1;

endmodule


Multiplexer Inference Examples

VHDL Examples

These are some examples of multiplexer inference in VHDL.

--   a few examples of multiplexers
library ieee;
use ieee.std_logic_1164.all;

entity vhdlmux is
  generic(
width : positive := 24
);
  port(
sel : in std_logic_vector(1 downto 0);
s0, s1, s2, s3 : in std_logic;
i0, i1, i2, i3 : in std_logic_vector(width - 1 downto 0);
o0, o1, o2, o4 : out std_logic_vector(width - 1 downto 0);
o3 : buffer std_logic_vector(width - 1 downto 0)
);
end vhdlmux;

architecture rtl of vhdlmux is

begin  --  rtl

-- 4:1 mux, 2 select lines
  mux1 : process(i0, i1, i2, i3, sel)
  begin
    case sel is
      when "00" => o0 <= i0;
      when "01" => o0 <= i1;
      when "10" => o0 <= i2;
      when others => o0 <= i3;
    end case;                            --  sel
  end process;

-- mux2, 4:1 mux, 2 select lines with sel select
  o1 <= i0 when "00",
    i1 when "01",
    i2 when "10",
    i3 when others;

-- mux3, 4:1 mux, 2 select lines
  o2 <= i0 when sel = "00" else
    i1 when sel = "01" else
    i2 when sel = "10" else
    i3;

-- 4:1 mux, 4 select lines
  mux4 : process(s0, s1, s2, s3, i0, i1, i2, i3)

  variable seltemp : std_logic_vector(3 downto 0);

  begin
    seltemp := (s3 & s2 & s1 & s0);
    case seltemp is
      when "0001" => o3 <= i0;
      when "0010" => o3 <= i1;
      when "0100" => o3 <= i2;
      when "1000" => o3 <= i3;
-- use don't care condition to minimize logic
      when others => o3 <= (others => '-');
    end case;                            --  seltemp
  end process;

-- 2:1 mux, 1 select line
  mux5 : process(s0, i0, i1)
  begin
    if (s0 = '1') then
      o4 <= i1;
    else
      o4 <= i0;
    end if;
  end process;

end rtl;

Verilog Examples

These are some examples of multiplexer inference in Verilog.

module vlogmux(sel, s0, s1, s2, s3, i0, i1, i2, i3,
  o0, o1, o2, o3);

parameter width = 24;

input [1:0] sel;
input s0, s1, s2, s3;
input [width-1:0] i0, i1, i2, i3;
output [width-1:0] o0, o1, o2, o3;
reg [width-1:0] o0, o2;

// mux1, 4:1 mux, 2 select lines

always @(i0 or i1 or i2 or i3 or sel)
  case (sel)
    0: o0 = i0;
    1: o0 = i1;
    2: o0 = i2;
    default: o0 = i3;
  endcase

// mux2, 2:1 mux, 1 select line

assign o1 = s0 ? i1 : i0;

// mux3, 4:1 mux, 4 select lines

always @(i0 or i1 or i2 or i3 or s0 or s1 or s2 or s3)
  case (1)
    s0: o2 = i0;
    s1: o2 = i1;
    s2: o2 = i2;
    default: o2 = i3;
  endcase

// mux4, 4:1 mux, 2 select lines

assign o3 = s1 ? (s0 ? i3 : i2) : (s0 ? i1 : i0);

endmodule


Operator Sharing in FPGA Express

With operator sharing, FPGA Express can rearrange operators to optimize logic. The following example shows how FPGA Express can share operators in HDL code in a common VHDL process or Verilog always block.

In VHDL:

process(a, b, c, sel)
begin
  if (sel = '1') then
 z <= a + c;
  else
 	 z <= a + b;
  end if;
end process;

In Verilog:

always @ (a or b or c or sel)
  if (sel)
 z = a + c;
  else
 z = a + b;

a, b, c, and z are 16 bits wide. This logic requires one 16-bit multiplexer and two 16-bit adders. By rearranging operators, you can implement this logic using one 16-bit multiplexer and only one 16-bit adder. The resultant logic is the same as if the HDL code is rewritten as shown below.

In VHDL:

process(a, b, c, sel)
variable mux1 : std_logic_vector(15 downto 0);
begin
  if (sel = '1') then
 mux1 := c;
  else
 mux1 := b;
  end if;
  z <= a + mux1;
end process;

In Verilog:

always @ (a or b or c or sel)
  z = c + (sel ? a : b);

In this particular case, FPGA Express can save sixteen 4-input lookup tables (LUTs) when targeting an APEX20K family device.

This is another example showing the advantages of operator sharing.

In VHDL:

process (clk, rst)
begin
  if (rst = '1') then
 ctr <= (others => '0');
  elsif (clk = '1' and clk'event) then
    if (updown = '1') then
  	   ctr <= ctr + 1;
    else
      ctr <= ctr - 1;
    end if;
  end if;
end process;

In Verilog:

always @(posedge rst or posedge clk)
  if (rst)
    ctr = 0;
  else
    if (updown)
      ctr = ctr + 1;
    else
      ctr = ctr - 1;

In this case, using an incrementer/decrementer function instead of an adder, subtractor, and multiplexer results in a savings of 18 LUTs for a 16-bit counter when targeting an APEX20K family device.

You can control operator sharing using a setting in the Operator Sharing column of the Modules constraint table. The default value of operator sharing is on, but it can be turned off for individual modules or turned off globally in the <default> row.

FPGA Express calculates the cost of sharing operators in terms of FPGA resources. FPGA Express does not perform sharing if the resulting implementation is equal to or larger than the original logic. For example, because sharing operators in the following circuit yields no advantage, FPGA Express does not share oprerators.

process(a, b, c, d, sel)
begin
  if (sel = '1') then
    z <= a + b;
  else
    z <= c + d;
  end if;
end process;


How to Define Timing Constraints in FPGA Express

You can define these timing constraints in FPGA Express:

Clock waveforms

Path group constraints

I/O constraints

FPGA Express converts these constraints to the specific format ACF for Altera.

Specifying Clock Constraints

1.	Open the Clocks constraint table in the Chips window by selecting the elaborated chip, clicking on the right mouse button, and selecting Edit Constraints.

2.	Specify the waveforms of periodic signals in the design. To specify a waveform, click the Clock column cell and then the expand arrow appearing in the cell. Select Define. The Define Clock dialog box appears, where you can enter the period, rise time, and fall time of the signal.

Specifying Path Group Constraints

Use the Paths constraint table in the Chips window to specify timing constraints for path groups. This table contains the list of path groups automatically constructed during the Create Implementation step. For each path group, FPGA Express displays the starting timing group (From column), the ending timing group (To column), and the maximum delay of the path (Req. Delay column).

A timing group is a set of sequential cells or ports in the design that share the same timing behavior. For example, all flip-flops clocked by a common clock signal are grouped in one timing group. A path group is the set of all combinatorial paths between two timing groups. You can use path groups to describe the timing behavior of the design in the Paths constraint table.

To specify constraints for arbitrary timing paths, create subpaths to a specified timing group. See Timing Subpaths .

Specifying I/O Constraints

Enter port-specific constraints in the Ports constraint table in the Chips window. Each row in the table shows the constraints for a port. These are the timing constraints you can enter in this table:

Input Delay

The input delay of an input or inout port is the maximum delay from that port to a timing group. To define an input delay, click the Input Delay cell for a port, and select Define. In the Define Delay dialog box, define the input delay.

Output Delay

The output delay of an output or inout port is the maximum delay from a timing group to that port. To define an output delay, click the Output Delay cell for a port and select Define. In the Define Delay dialog box, define the output delay.

Slew Rate

You can specify a fast or slow rate for an output or bidirectional port.

I/O Register

You can specify that I/O register pads be used on a port where applicable.

Pad Location

You can specify the location of pads for a port. You cannot specify pad locations for a design that has the Do Not Insert I/O Pads option selected.


Using the FPGA Express TimeTracker

The FPGA Express TimeTracker speeds the design cycle by allowing you to identify and repair critical portions of your design without having to run Quartus or MAX+plus II to perform place and route. TimeTracker is integrated into the existing design flow and runs when you view the results of an optimized chip. It allows you to compare estimated delay values to entered constraints.

Timing Analysis also provides details of particular paths and a detailed listing of critical paths.

After you read the HDL source code into FPGA Express and enter timing requirements, synthesize the design for the target PLD architecture. Then, instead of using Quartus or MAX+plus II (noted as "FPGA vendor tools" in the figure below) to place and route the design, view the results of the optimized chip. See Optimizing a Design Implementation for more information about View Results.

The following figure shows where timing analysis fits into the design flow. Using TimeTracker for timing verification allows you to not have to place and route your design until after the timing is verified. This feature minimizes the need for multiple place and route interations.

These are the advantages of using the FPGA ExpressTimeTracker:

It gives feedback about how you meet your timing requirements without your having to run the vendor's place and route tool and timing analyzer.

It presents timing analysis results and timing requirements in a table, making the results easy to interpret.


Timing Analysis

This is how you can perform timing analysis with FPGA Express.

After optimization, right-click the optimized chip and select View Results to run the FPGA Express TimeTracker. TimeTracker calculates the delay.

Timing analysis follows the same top-down paradigm (from global to specific) as timing constraint entry (see Entering Timing Constraints ):

In the Clocks constraint table

The Clocks constraint table contains a new column showing the estimated clock frequency for each clock in your design next to the desired frequency derived from your timing constraints. If a particular clock fails to meet its constraint, it is highlighted in red. To see greater detail, proceed to the Paths constraint table.

In the Paths constraint table

The Paths constraint table shows the paths that are in violation of a timing constraint and a detailed list of each path’s structure.

The table contains an additional column displaying path delay with violations in red. It shows which groups of paths fail to meet constraints. Selecting any particular group lists all paths in that group with their start-points, end-points, and delays. At another level of detail, it shows exactly which paths are in violation. Selecting any particular path displays a listing of the composition of the entire path from start-point to end-point, including each instance in the path, the type of component, the cumulative delay through each instance, and the fanout of that particular pin of the instance.

These tables should provide the information needed for making design improvements without running Quartus or MAX+plus II.

Timing analysis fits into the present FPGA Expressdesign flow and gives you detailed information about the timing behavior of your design. With timing analysis, you can see the estimated delay values presented next to the desired delay values. For any path, the TimeTracker provides a detailed listing of the path composition to help you debug critical paths. FPGA Express timing analysis shortens the design cycle by eliminating the need to run vendor tools to get timing information.


Entering Timing Constraints

This is how you enter the timing specification for your design in FPGA Express.

After elaboration but before optimization, right-click the elaborated chip and select Edit Constraints to enter timing constraints.

FPGA Express lets you enter timing constraints for common types of paths including pad-to-pad, pad-to-setup, register-to-register, and clock-to-output paths. FPGA Express compares these timing constraints to the values calculated by its built-in TimeTracker.

You enter timing constraints in a top-down method: starting with global constraints (such as clock periods), then proceeding to the more specific (such as group path timing), to the most specific (input and output delay):

1.	Using the Clocks constraint table

In the Clocks constraint table, you can enter the default clock waveform for each clock in your design, including the clock period and rise and fall times. All path constraints are given default values based on the clock periods.

2.	Using the Paths constraint table

When there are more restrictive timing requirements than the defaults, you can override a default path constraint with a more specific constraint by entering path constraints in the Paths constraint table. Here you apply timing constraints to groups of paths, the set of all clock-to-output paths, for example. The input and output delays for the I/O ports are given default values based on the path constraints.

3.	Using the Ports constraint table

Sometimes a single value applied to many paths is not sufficient for a particular port. In the example of clock-to-output paths, there may be a particular output port that has a more restrictive clock-to-output requirement. To override a path constraint with an even more specific constraint, proceed to the Ports constraint table, where you can set input and output delays for individual ports.

After entering timing constraints, optimize the design.


How to Define Multicycle Timing Constraints

FPGA Express can generate timing groups and path groups for logic that uses clock enable signals. This is useful when portions of a design run at a slower speed than the rest, with the slower flip-flops controlled by the enable signal. The use of enable signals with a fundamental clock eliminates clock skew, which can be introduced by additional clock signals. You can set multicycle timing constraints for specified paths, making the slower logic easier to place and route using the vendor place and route tool. Multicycle timing constraints can be applied to subpath groups that you create.

This is an example of a situation in which a multicycle timing constraint is appropriate. An PLD contains some high-speed interface logic that must run at 40 MHz and some low-speed interface and core logic that has to run at 10 MHz. The FPGA has a 40-MHz system clock and uses it to generate a 10-MHz enable signal for internal distribution. The following figure shows how the 10-MHz enable might align with the system clock when the rising edge of the 40-MHz system clock is the active edge. The 40-MHz clock is distributed to the clock input of each FPGA flip-flop, while the enable signal is distributed to each FPGA flip-flop clock enable input. In this case, the primary clock period is 25 ns, but the 10-MHz enabled logic needs to satisfy a period of only 100 ns.

40 MHz clock    _|-|_|-|_|-|_|-|_|-|_|-|_|-|_|-|_|-|_

10 MHz enable   ______|--|____________|--|___________

A simple shift register circuit shown in the following logic diagram illustrates how the multicycle timing constraint is assigned in FPGA Express.

Register reg1 is a 4-bit serial-input parallel-output register. Register reg2 is a holding register that is loaded with the clock enable ena. The paths from the output of reg1 to the input of reg2 (net q) are multicycle paths because the data bits have 4 clock cycles to reach their destinations. The register-to-register timing constraint is 25 ns (1 / 40 MHz), but the multicycle timing constraint is 100 ns (4 x 25 ns).

In the Paths constraint table, to create a subpath group of the register-to-register paths, click the right mouse button on the register-to-register path groups and select New Sub path.

The Create / Edit Timing Sub Path window appears. Use this window to construct your own path group by selecting specific start-points and end-points. The newly created path group is called a subpath because it is a subset of another path group, in this case, the register-to-register paths in the design.

In this example, the outputs of reg1 are the start-points and the inputs of reg2 are the end-point for the subpath. A delay of 100 ns is assigned to the subpath. For more information about using the subpath editor, see the FPGA Express online help.

After you create a subpath and apply the multicycle timing constraint, the subpath appears in the Paths constraint table.

Note that an enabled flip-flop can be included in two different path groups—those that include clock-to-clock paths and those that include clock-to-enabled-clock paths. This implies that there are two overlapping constraints. The constraint for clock-to-clock timing, 25 ns in this case, conflicts with the constraint for clock-to-enabled-clock timing, which is 100 ns. Most vendor place and route tools assign different priorities to these two constraints, placing a higher priority on the more specific one. Because the subpath constraint is more specific than the clock-to-clock constraint, it takes precedence and the corresponding paths can be optimized for the slower speed.


ACF Example

This is an example of a typical Assignments and Constraints File (ACF) from FPGA Express.

CHIP my_chip
DEVICE = EPF10K100GC503-3 {synopsys};

“|_CONFIG” : PIN = P40 {synopsys};
“|_STATUS” : PIN = P41 {synopsys};

GLOBAL_PROJECT_SYNTHESIS_ASSIGNMENT_OPTIONS
DEVICE_FAMILY = FLEX10K {synopsys};
STYLE = WYSIWYG {synopsys};
OPTIMIZE_FOR_SPEED = 5 {synopsys};
AUTO_GLOBAL_CLOCK = ON {synopsys};

LOGIC_OPTIONS
“|TX_FIFOA_D6” : IO_CELL_REGISTER = ON {synopsys};
“|DEST_RAM_D6” : SLOW_SLEW_RATE = ON {synopsys};
“|DEST_RAM_D5” : SLOW_SLEW_RATE = OFF {synopsys};

COMPILER_INTERFACES_CONFIGURATION
EDIF_INPUT_VCC = VDD {synopsys};
EDIF_INPUT_GND = GND {synopsys};
EDIF_INPUT_USE_LMF1 = ON {synopsys};
EDIF_INPUT_LMF1 = “my_chip.lmf” {synopsys};

TIMING_POINT
FREQUENCY = 50MHz {synopsys};
“CLK80” : FREQUENCY = 80MHz {synopsys};
“G” : FREQUENCY = 25MHz {synopsys};
TPD = 10ns {synopsys};
“inp1” : TSU = 20ns {synopsys};
“out1” : TCO = 15ns {synopsys};


How To Use Memory Elements with Altera Devices

This is the recommended procedure for using FPGA Express to synthesize designs with RAM or ROM elements:

1.	Generate the type of memory you want using the Genmem utility, Altera’s memory generator.

2.	For Verilog designs

a.	Use the <memfile>.v for port information for the memory instance. Instantiate a memory instance in your Verilog source code.

b.	Include the simulation model <memfile>.v in your FPGA Compiler II / FPGA Express project.

c.	Create an implementation.

d.	In the Modules constraint table for the implementation, choose Preserve in the Hierarchy column for each memory instance.

3.	For VHDL designs

a.	Include the <memfile>.cmp component declaration in your VHDL source code.

b.	Instantiate a VHDL memory instance in your VHDL source code. You do not need to preserve the instance in FPGA Express when using VHDL.

Verilog RAM Example

This is an example of an asynchronous RAM instance in Verilog. For a 16x8 RAM, Genmem creates the asyn_ram_16x8.v file. The file contains port information.

module asyn_ram_16x8 (Q, Data, WE, Address);
parameter LPM_FILE = “UNUSED”;
parameter Width = 8;
parameter WidthAd = 4;
parameter NumWords = 16;

input [WidthAd-1:0] Address;
input [Width-1:0] Data;
input WE;
output [Width-1:0] Q;

input [3:0] Address;
input [7:0] Data;
input WE;
output [7:0] Q;

asyn_ram_16x8 u1(
.Address(Address),
.WE(WE),
.Data(Data),
.Q(Q)
);

Then you choose Preserve in the Hierarchy column for the instance u1.

VHDL RAM Example

This is an example of an asynchronous RAM instance in VHDL. For a 16x8 RAM, Genmem creates the asyn_ram_16x8.cmp file. This is placed in the VHDL source code along with the instance.

component asyn_ram_16x8
pragma translate_off
generic ( LPM_FILE : string );
pragma translate_on
port ( Data    : in std_logic_vector(7 downto 0);
Address : in std_logic_vector(3 downto 0);
WE : in std_logic;
Q : out std_logic_vector(7 downto 0)
     );
end component;
begin  --  rtl
u1 : asyn_ram_16x8 port map(
Data => d,
Address => a,
WE => w,
Q => qu
  );

end rtl;

No Preserve in the Hierarchy column for the instance u1 is necessary when using VHDL.


How to Use Altera LPM Components in FPGA Express

FPGA Express supports the following LPM (library of parameterized macros) components:

LPM_ABS  LPM_ADD_SUB LPM_BIPAD LPM_BUSTRI LPM_CLSHIFT LPM_COMPARE LPM_CONSTANT LPM_COUNTER LPM_DECODE LPM_DFF	LPM_FF LPM_INV LPM_LATCH LPM_MULT LPM_RAM_DQ LPM_RAM_IO LPM_ROM LPM_SHIFTREG LPM_TFF
You can find the definitions of these components in:

<drive>:\synopsys\fpga_express\lib\packages\lpm\lpm_components.vhd

For a list of Altera MAX+PLUS II software megafunctions and LPMs, see Megafunctions/LPM.

Example in VHDL

In this example of instantiating an LPM_RAM_DQ component in VHDL, note the inclusion of these two statements:

library lpm;

use lpm.lpm_components.all;

Design containing an LPM_RAM_DQ instance:

library ieee;
use ieee.std_logic_1164.all;
library lpm;
use lpm.lpm_components.all;

entity design is
   port(
      din : in std_logic_vector(15 downto 0);
      we : in std_logic;
      clk : in std_logic;
      addr : in std_logic_vector(3 downto 0);
      dat : out std_logic_vector(15 downto 0)
   );
end design;

architecture struct of design is
   signal vcc : std_logic;

begin  --  struct
   vcc <= ‘1’;
   u1 : lpm_ram_dq
      generic map(
         LPM_WIDTH => 16,
         LPM_WIDTHAD => 4,
         LPM_INDATA => UNREGISTERED,
         LPM_OUTDATA => UNREGISTERED
      )
      port map(
         data => din,
         address => addr,
         we => we,
         q => dat,
         inclock => vcc,
         outclock => clk
      );

end struct;

Using named association for the generics and parameters of LPM instances is highly recommended.  Note that the inclock input must be tied to logic 1 according to the definition in lpm_components.vhd:

component LPM_RAM_DQ
   generic (
      LPM_WIDTH: positive;
      LPM_TYPE: string := L_RAM_DQ;
      LPM_WIDTHAD: positive;
      LPM_NUMWORDS: string := UNUSED;
      LPM_FILE: string := UNUSED;
      LPM_INDATA: string := REGISTERED;
      LPM_ADDRESS_CONTROL: string := REGISTERED;
      LPM_OUTDATA: string := REGISTERED
   );
port (
      DATA: in STD_LOGIC_VECTOR(LPM_WIDTH-1 downto 0);
      ADDRESS: in STD_LOGIC_VECTOR(LPM_WIDTHAD-1 downto 0);
      WE: in STD_LOGIC; -- := ‘1’;
      INCLOCK: in STD_LOGIC; -- := ‘1’;
      OUTCLOCK: in STD_LOGIC; -- := ‘1’;
      Q: out STD_LOGIC_VECTOR(LPM_WIDTH-1 downto 0)
   );
end component;

Because FPGA Express does not support initial values of logic 1 on component declarations, the inclock input pin must be manually tied to logic 1. However, FPGA Express does support initial values of logic 0 on component declarations.

Example in Verilog

In this example of an LPM_RAM_DQ instance in Verilog, note that you must associate all parameters and only positional association is allowed.

// RAM design

module design(din, we, clk, addr, dat);

input [15:0] din;
input we, clk;
input [3:0] addr;
output [15:0] dat;

supply1 vcc;

lpm_ram_dq #(
   16,	// LPM_WIDTH
   “LPM_RAM_DQ”,	// LPM_TYPE
   4,	// LPM_WIDTHAD
   “16”,	// LPM_NUMWORDS
   “UNUSED”,	// LPM_FILE
   “UNREGISTERED”,	// LPM_INDATA
   “UNREGISTERED”, 	// LPM_ADDRESS_CONTROL
   “UNREGISTERED” 	// LPM_OUTDATA
)
u1(
   .data(din),
   .address(addr),
   .we(we),
   .q(dat),
   .inclock(vcc),
   .outclock(clk)
);

endmodule


Using Altera MegaWizard Components in FPGA Compiler II Altera Edition and FPGA Express

Introduction

The advancement in capacity of Programmable Logic Devices PLDs has made design reuse an integral part in high-density PLD designs.  In order to meet time-to-market requirements, designers are turning to predesigned, verified, and synthesizable functions ranging from adders, multipliers, shifters, to larger and more complex functions such as FIFOs.

Altera’s MegaWizard Plug-In Manager, or MegaWizard for short, helps designers create or modify predesigned and verified components that contain custom megafunction variations.  These custom megafunction variations are based on Altera-provided megafunctions, such as Library of Parameterized Modules (LPMs), which are optimized for Altera architecture.  The MegaWizard is a utility that helps designers easily specify options for the custom megafunction variations.  The utility asks questions about optional ports and the values designers want to set for parameters.  The results are “plug-and-play” components that can improve the quality of the designs in less time.

This document describes how MegaWizard-generated components can be used in the Synopsys’ FPGA Compiler II Altera Edition/FPGA Express(FCIIAE/FE) environment.  FCIIAE/FE includes architecture-specific PLD synthesis technology and FCIIAE is the only solution for million-gate designs with the addition of several advanced features as well as Synopsys design flow compatibility.  The FCIIAE/FE technology provides superior results in both area and speed performance and is further enhanced with the support for MegaWizard components.

A MegaWizard component for RAM, LPM_RAM_DQ, will be used as an example throughout this document.  The new megafunctions for APEX20KE devices, namely ALTCLKLOCK, ALTLVDS, and ALTCAM, will be just briefly mentioned due to their similarities to LPMs.  In all cases, examples in both Verilog and VHDL will be given.  It is assumed that the readers have basic knowledge of creating a component using MegaWizard and synthesizing a simple design in FCIIAE/FE.

The Process at a Glance

Using MegaWizard-generated components in FCIIAE/FE consists of the following steps:

Creating the MegaWizard component in Verilog or VHDL

Instantiating the MegaWizard “wrapper”

Synthesizing the design, without the actual MegaWizard component, in FCIIAE/FE

Exporting the netlist in FCIIAE/FE

Placement-and-routing of the entire design

Let us discuss each of these steps in detail.

Creating the MegaWizard Component in Verilog or VHDL

In Quartus, selecting Tools in the menu and then MegaWizard Plug-In Manager will launch the utility.  In MAX+plus II, the same can be accomplished by selecting File and then MegaWizard Plug-In Manager.  What MegaWizard typically does is create a top level design, or “wrapper”, in which an LPM with the functionality that best fits the designer’s requirements is instantiated.  Throughout this document a MegaWizard-generated RAM component will be used to illustrate the design flow.  Since LPM_RAM_DQ will be the underlying LPM used, the “wrapper” will be named use_lpm_ram_dq.  Figure 1 shows that use_lpm_ram_dq can be written in AHDL, Verilog, or VHDL.  Only components created in Verilog or VHDL will be discussed in this document.

Figure 1  Creating a RAM in MegaWizard Plug-In Manager

Instantiating the MegaWizard “Wrapper”

After the MegaWizard component has been created, the next step is to instantiate it in the design.  In Verilog, the process involves direct instantiation of the “wrapper” and an empty module to provide the port direction information.  Figure 2 shows a sample Verilog design.  Note that the empty module is required in FCIIAE/FE and it should be included at the end of the design file in which the “wrapper” is instantiated.

Figure 2  Sample Verilog Design

The process is very similar in VHDL, which involves direct instantiation of the “wrapper” and a component declaration to provide the port direction information.  Figure 3 shows the equivalent design in VHDL.

Figure 3  Sample VHDL Design

In either case, the port names for correct instantiation can be obtained from viewing the “wrapper”.

Synthesizing the Design, without the Actual MegaWizard Component, in FCII/FE

Create a project in FCIIAE/FE and add the design to the project.  It is important that the MegaWizard-generated components, such as use_lpm_ram_dq.v or use_lpm_ram_dq.vhd, are NOT added to the project.  Doing so leads FCIIAE/FE to treat the instantiated MegaWizard component as a black-box during elaboration.  If the design is written in VHDL, FPGA Compiler II Altera Edition will generate the following warning messages:

Warning: Cannot link cell 'vhdl_design/u1' to its reference design 'use_lpm_ram_dq'.  (FPGA-LINK-2)

Warning: The cell '/vhdl_design/u1' is not linked to any design.  (FPGA-CHECK-4)

The above messages will not appear if the design is written in Verilog because of the presence of the empty module.

The next step for FCIIAE/FE is to optimize the elaborated design for the target technology.  Please refer to the FPGA Compiler II Altera Edition Getting Started or the FPGA Express Getting Started for more information on elaboration and optimization.

Exporting the Netlist in FCIIAE/FE

Once the design has been elaborated and optimized, a netlist can be exported for place-and-route.  This can be done by right-clicking on the optimized chip in the Chips window of the FCIIAE/FE Graphical User Interface (GUI) and selecting Export Netlist.  Figure 4 shows the Export Netlist dialog box.

Figure 4  Exporting Netlists in FCII/FE

Placement-and-Routing of the Entire Design

The MegaWizard-generated components, such as use_lpm_ram_dq.v or use_lpm_ram_dq.vhd, should be placed in the same directory specified by Export Directory in the Export Netlist dialog box (Figure 4).  This directory should be used as the project directory of Quartus or MAX+plus II.  It is important that the top level design file, for example, verilog_design.v or vhdl_design.vhd, is specified as such in the place-and-route tools.  Quartus or MAX+plus II will then be able to link the MegaWizard-generated components and proceed to place-and-route the entire design.

Instantiating LPMs Directly in the Design

While the MegaWizard Plug-In Manager is an excellent utility to create or modify custom megafunction variations, designers also enjoy the flexibility of instantiating LPMs and passing parameters to them in Verilog or VHDL.  There is a file named lpm_components.vhd, located in < FCIIAE/FE directory>\lib\packages\Lpm, which contains port name and parameter information of all the LPMs supported by FCIIAE/FE.  Figure 5 shows the section for LPM_RAM_DQ in lpm_components.vhd.

Figure 5  LPM_RAM_DQ Component Declaration

In Verilog, FCIIAE/FE requires all LPM parameters to be specified using the #() construct.  They are also required to be listed in the same order as they appear in lpm_components.vhd.  In Figure 6, the order in which the LPM parameters are passed matches precisely with what is shown in Figure 5.  Note that although the parameter LPM_HINT is not used its value “UNUSED” is still required inside the #() construct.  As mentioned previously, an empty module is needed to provide port direction information.

Figure 6  Instantiating LPMs in Verilog

When instantiating LPMs in VHDL, FCIIAE/FE does not require all LPM parameters to be listed as long as the names of the ones being used in the GENERIC MAP section match with their counterpart in lpm_components.vhd.  Furthermore, a component declaration is not needed when the following statements are included in the design:

LIBRARY lpm;

USE lpm.lpm_components.all;

Figure 7 illustrates an example.  Note that the unused parameters LPM_FILE and LPM_HINT are not listed in the GENERIC MAP section.

Figure 7  Instantiating LPMs in VHDL

It is important to understand that when LPMs are directly instantiated in a design, only the ones with names that have the prefix LPM_ are supported in FCIIAE/FE.  This also holds true for LPM parameters.

New Altera Megafunctions for APEX20KE Devices

FCIIAE/FE version 3.3.1 supports the new megafunctions for Altera’s APEX20KE devices, namely ALTCLKLOCK, ALTLVDS, and ALTCAM.  The recommended black-boxing methodology for LPMs remains the preferred design flow for these megafunctions.  It is therefore not repeated here.

In situations where these megafunctions are instantiated in the design the same precaution as discussed for LPMs applies.  The only part that requires special attention is Export Netlist.  The current default bus style in FCIIAE/FE is EXPAND.  It has to be changed to %s[%d:%d] for Altera’s Quartus to place-and-route the FCIIAE/FE-generated netlist successfully.  Figure 8 shows the modified Bus Style field.

Figure 8  Bus Style Requirement of Altera’s Quartus

Note that this procedure is only needed when ALTCLKLOCK, ALTLVDS, or ALTCAM are instantiated.  The black-boxing methodology does not require the bus style to be changed and therefore it is the recommended design flow.

Additional Information

This document is intended to focus specifically on using MegaWizard-generated components in FCII/FE.  Please refer to the FPGA Compiler II Altera Edition Getting Started, FPGA Express Getting Started, or the on-line help for additional information on how to use other features of FCIAEI/FE.

Summary

The goal of this article is to describe how Synopsys’ FCIAEI/FE can help designers improve productivity by taking advantage of Altera’s MegaWizard components in FPGA designs.  The MegaWizard is a utility that helps designers easily specify options for custom megafunction variations.  These parameterizable and synthesizable components are proven to reduce designers’ time-to-market.

Whether the design is written in Verilog or VHDL, the recommended methodology is instantiate the MegaWizard-generated components as black-boxes.  FCIAEI/FE is then used to synthesize the design and generate a netlist.  Altera’s Quartus or MAX+plus II will link the netlist and the MegaWizard-generated components during the place-and-route process.

LPMs can also be directly instantiated in a design.  Both Verilog and VHDL examples are discussed.

FCIAEI/FE supports the megafunctions for Altera’s APEX20KE devices.  The recommended black-boxing methodology certainly applies well to ALTCLKLOCK, ALTLVDS, and ALTCAM.  In situations where these megafunctions are instantiated in the design the same precaution as discussed for LPMs applies.  However, special attention needs to be paid to the bus style when exporting netlists.  The default EXPAND has to be changed to %s[%d:%d] for Altera’s Quartus to successfully place-and-route the FCIAEI/FE-generated netlists.


Design Flow Targeting Altera FLX and MAX Devices
Design Flow Targeting Altera FLEX and MAX Devices

This is a typical design flow for targeting Altera FLEX and MAX devices using FPGA Express:

1.	Create your design.

Use HDL or a schematic capture tool to capture your design and output the schematics to an EDIF netlist.

2.	(Optional) Verify the function of your design.

Simulate the functionality of the design using HDL and/or gate-level simulators.

3.	Synthesize your design using FPGA Express.

a.	Create a new project.

b.	Add and analyze all the EDIF and HDL design source files.

c.	Identify the top-level design of the project.

d.	Select a target Altera family. FPGA Express provides the choice of AUTO for device and FASTEST for speed grade, which allows MAX+plus II to choose the smallest and fastest part.

e.	Enter the design constraints.

f.	Optimize your design.

g.	Review the results of timing analysis for feedback on timing and area performance, and make design changes if necessary.

h.	Export the optimized EDIF netlist, the ACF (Assignments and Constraints File) containing the design constraints, and the LMF (Library Mapping File) describing the cells used in the EDIF file. All three files must be placed in the MAX+plus II project directory.

About the ACF

When you export a netlist FPGA Express appends additional information such as the synthesis style to a built-in ACF provided by Altera. Lines modified by FPGA Express are marked with a {synopsys} comment at the end.

If a modified ACF points to the wrong LMF, MAX+plus II might fail and you would receive the error message “Can’t find design file X” (where X is a cell in the EDIF netlist). To correct this in MAX+plus II, select the following when the Compiler is opened:

Interfaces->EDIF Netlist Reader Settings->Customize

Then select the correct LMF from FPGA Express (<design_name>.lmf).

The MAX+plus II logic synthesis style is placed in the ACF. FPGA Express provides two settings: WYSIWYG and FAST. The FAST setting, which is the default, allows MAX+plus II to restructure logic in logic cells (LCELLs) for a possibly faster implementation. The WYSIWYG setting attaches LCELL buffers to logic cells to guarantee that the LCELL logic structure is preserved, which may help to achieve a smaller design. The logic synthesis style must be set before optimization.

The following information entered in FPGA Express constraint tables is passed to MAX+plus II in the ACF:

Clock frequencies (from the Clocks constraint table in the Chips window in FPGA Express)

Path group constraints (from the Paths constraint table in the Chips window)

Pin locations, slew rates, use of I/O registers, input to setup and clock to output delays (from the Ports constraint table in the Chips window)

For MAX Device Fitting

If MAX+plus II cannot fit your design targeting MAX devices, set the following MAX+plus II switches and try again:

Assign->Global Project Logic Synthesis->Multi-Level Synthesis for MAX  3000/5000/7000 Devices

Assign->Global Project Logic Synthesis->Multi-Level Synthesis for MAX  9000 Devices

If the design still does not fit, set this MAX+plus II switch and try again:

Processing->Fitter Settings->Advanced Try Harder/Longer Compilation Fitting

If the design still does not fit, try the customized fitting:

1.	Select Processing->Fitter Settings->Custom Fitting

2.	Select Processing->Fitter Settings->Customized, and then reduce the percentage for Fan-In per Logic Cell or for the other fields displayed in the Other Options window, as explained in the MAX+plus II online help.