6. Recommended HDL Coding Styles

Similar documents
Internal Memory (RAM and ROM) User Guide

Quartus II Software Design Series : Foundation. Digitale Signalverarbeitung mit FPGA. Digitale Signalverarbeitung mit FPGA (DSF) Quartus II 1

Internal Memory (RAM and ROM) User Guide

Introduction to the Quartus II Software. Version 10.0

Quartus II Introduction for VHDL Users

Altera Error Message Register Unloader IP Core User Guide

Download the Design Files

ModelSim-Altera Software Simulation User Guide

LAB #3 VHDL RECOGNITION AND GAL IC PROGRAMMING USING ALL-11 UNIVERSAL PROGRAMMER

Qsys and IP Core Integration

VHDL GUIDELINES FOR SYNTHESIS

Using Xilinx ISE for VHDL Based Design

Internal Memory (RAM and ROM) User Guide

VHDL Test Bench Tutorial

Arria 10 Core Fabric and General Purpose I/Os Handbook

Arria V Device Handbook

Cyclone V Device Handbook

The 104 Duke_ACC Machine

ECE 3401 Lecture 7. Concurrent Statements & Sequential Statements (Process)

Modeling Sequential Elements with Verilog. Prof. Chien-Nan Liu TEL: ext: Sequential Circuit

Digital Systems Design. VGA Video Display Generation

Digital Design with VHDL

Coding Guidelines for Datapath Synthesis

3. Memory Blocks in Arria II Devices

ECE232: Hardware Organization and Design. Part 3: Verilog Tutorial. Basic Verilog

9/14/ :38

Using Altera MAX Series as Microcontroller I/O Expanders

Step : Create Dependency Graph for Data Path Step b: 8-way Addition? So, the data operations are: 8 multiplications one 8-way addition Balanced binary

Digitale Signalverarbeitung mit FPGA (DSF) Soft Core Prozessor NIOS II Stand Mai Jens Onno Krah

if-then else : 2-1 mux mux: process (A, B, Select) begin if (select= 1 ) then Z <= A; else Z <= B; end if; end process;

Quartus II Handbook Volume 3: Verification

Integer Arithmetic IP Cores User Guide

Implementation of Web-Server Using Altera DE2-70 FPGA Development Kit

Lab 1: Introduction to Xilinx ISE Tutorial

Quartus Prime Standard Edition Handbook Volume 3: Verification

A New Paradigm for Synchronous State Machine Design in Verilog

Modeling Registers and Counters

Using the Altera Serial Flash Loader Megafunction with the Quartus II Software

A Verilog HDL Test Bench Primer Application Note

Asynchronous & Synchronous Reset Design Techniques - Part Deux

PCB Project (*.PrjPcb)

Engineering Change Order (ECO) Support in Programmable Logic Design

Chapter 13: Verification

Altera Advanced SEU Detection IP Core User Guide

Qsys System Design Tutorial

Modeling Latches and Flip-flops

8B10B Encoder/Decoder MegaCore Function User Guide

Life Cycle of a Memory Request. Ring Example: 2 requests for lock 17

An Open Source Circuit Library with Benchmarking Facilities

Quartus II Introduction Using VHDL Design

Hardware Implementation of the Stone Metamorphic Cipher

Finite State Machine Design and VHDL Coding Techniques

Introduction to the Altera Qsys System Integration Tool. 1 Introduction. For Quartus II 12.0

SystemVerilog Is Getting Even Better!

Prototyping ARM Cortex -A Processors using FPGA platforms

RAPID PROTOTYPING OF DIGITAL SYSTEMS Second Edition

White Paper Understanding Metastability in FPGAs

Introduction. Jim Duckworth ECE Department, WPI. VHDL Short Course - Module 1

Introduction to Programmable Logic Devices. John Coughlan RAL Technology Department Detector & Electronics Division

CNC FOR EDM MACHINE TOOL HARDWARE STRUCTURE. Ioan Lemeni

12. A B C A B C A B C 1 A B C A B C A B C JK-FF NETr

Using Nios II Floating-Point Custom Instructions Tutorial

Example-driven Interconnect Synthesis for Heterogeneous Coarse-Grain Reconfigurable Logic

Vivado Design Suite Tutorial

Enhancing High-Speed Telecommunications Networks with FEC

15. Introduction to ALTMEMPHY IP

Physics 226 FPGA Lab #1 SP Wakely. Terasic DE0 Board. Getting Started

FPGAs for High-Performance DSP Applications

Nios II Development Kit Version 5.1 SP1 Release Notes

Digital Circuit Design Using Xilinx ISE Tools

FINITE STATE MACHINE: PRINCIPLE AND PRACTICE

SDLC Controller. Documentation. Design File Formats. Verification

A Platform for Visualizing Digital Circuit Synthesis with VHDL

7a. System-on-chip design and prototyping platforms

ISE In-Depth Tutorial. UG695 (v14.1) April 24, 2012

Start Active-HDL by double clicking on the Active-HDL Icon (windows).

ECE 451 Verilog Exercises. Sept 14, James Barnes

Video and Image Processing Suite

HDL Simulation Framework

Digital Systems Design! Lecture 1 - Introduction!!

Multiplexers Two Types + Verilog

MAX II ISP Update with I/O Control & Register Data Retention

MAX+PLUS II. Introduction. Programmable Logic Development System & Software

High-Level Synthesis for FPGA Designs

From UML to HDL: a Model Driven Architectural Approach to Hardware-Software Co-Design

Testing of Digital System-on- Chip (SoC)

ESP-CV Custom Design Formal Equivalence Checking Based on Symbolic Simulation

The Advanced JTAG Bridge. Nathan Yawn 05/12/09

Agenda. Michele Taliercio, Il circuito Integrato, Novembre 2001

Xilinx Answer Data2Mem Usage and Debugging Guide

Design of a High Speed Communications Link Using Field Programmable Gate Arrays

DDS. 16-bit Direct Digital Synthesizer / Periodic waveform generator Rev Key Design Features. Block Diagram. Generic Parameters.

MasterBlaster Serial/USB Communications Cable User Guide

Building an Embedded Processor System on a Xilinx Zync FPGA (Profiling): A Tutorial

ECE410 Design Project Spring 2008 Design and Characterization of a CMOS 8-bit Microprocessor Data Path

Combinational-Circuit Building Blocks

ISE In-Depth Tutorial 10.1

The Designer's Guide to VHDL

USB-Blaster Download Cable User Guide

8. Hardware Acceleration and Coprocessing

Transcription:

6. Recommed HDL Coding Styles QII51007-9.0.0 Introduction f HDL coding styles can have a significant effect on the quality of results that you achieve for programmable logic designs. Synthesis tools optimize HDL code for both logic utilization and performance. However, sometimes the best optimizations require human understanding of the design, and synthesis tools have no information about the purpose or intent of the design. You are often in the best position to improve your quality of results. This chapter addresses HDL coding style recommations to ensure optimal synthesis results when targeting Altera devices, including the following sections: Quartus II Language Templates on page 6 1 Using Altera Megafunctions on page 6 2 Instantiating Altera Megafunctions in HDL Code on page 6 3 Inferring Multiplier and DSP Functions from HDL Code on page 6 6 Inferring Memory Functions from HDL Code on page 6 12 Coding Guidelines for Registers and Latches on page 6 36 General Coding Guidelines on page 6 46 Designing with Low-Level Primitives on page 6 71 For additional guidelines about structuring your design, refer to the Design Recommations for Altera Devices and the Quartus II Design Assistant chapter in volume 1 of the Quartus II Handbook. For additional hand-crafted techniques, you can use to optimize design blocks for the adaptive logic modules (ALMs) in many Altera devices, including a collection of circuit building blocks and related discussions, refer to the Advanced Synthesis Cookbook: A Design Guide for Stratix II, Stratix III, and Stratix IV Devices. Altera s website also provides design examples for other types of functions and to target specific applications. Refer to the Design Examples page and the Reference Designs page. For style recommations, options, or HDL attributes specific to your synthesis tool (including Quartus II integrated synthesis and other EDA tools), refer to the tool vor s documentation or the appropriate chapter in the Synthesis section in volume 1 of the Quartus II Handbook. Quartus II Language Templates The Quartus II software provides Verilog HDL, VHDL, AHDL, Tcl script, and megafunction language templates that can help you with your design. March 2009 Altera Corporation Quartus II Handbook Version 9.0 Volume 1: Design and Synthesis

6 2 Chapter 6: Recommed HDL Coding Styles Using Altera Megafunctions Figure 6 1. Insert Template Dialog Box Many of the Verilog HDL and VHDL examples in this document correspond with examples in the templates. You can easily insert examples from this document into your HDL source code using the Insert Template dialog box in the Quartus II user interface, shown in Figure 6 1. To open the Insert Template dialog box when you have a file open in the Quartus II Text Editor, on the Edit menu, click Insert Template. Alternatively, you can right-click in the Text Editor window and choose Insert Template. Using Altera Megafunctions Altera provides parameterizable megafunctions that are optimized for Altera device architectures. Using megafunctions instead of coding your own logic saves valuable design time. Additionally, the Altera-provided megafunctions may offer more efficient logic synthesis and device implementation. You can scale the megafunction s size and set various options by setting parameters. Megafunctions include the library of parameterized modules (LPM) and Altera device-specific megafunctions. To use megafunctions in your HDL code, you can instantiate them as described in Instantiating Altera Megafunctions in HDL Code on page 6 3. Quartus II Handbook Version 9.0 Volume 1: Design and Synthesis March 2009 Altera Corporation

Chapter 6: Recommed HDL Coding Styles 6 3 Instantiating Altera Megafunctions in HDL Code Sometimes it is preferable to make your code indepent of device family or vor. In this case, you might not want to instantiate megafunctions directly. For some types of logic functions, such as memories and DSP functions, you can infer a megafunction instead of instantiating it. Synthesis tools, including Quartus II integrated synthesis, recognize certain types of HDL code and automatically infer the appropriate megafunction. The synthesis tool uses the Altera megafunction code when compiling your design even when you do not specifically instantiate the megafunction. Synthesis tools infer megafunctions to take advantage of logic that is optimized for Altera devices or to target dedicated architectural blocks. In cases where you prefer to use generic HDL code instead of instantiating a megafunction, follow the guidelines and coding examples in Inferring Multiplier and DSP Functions from HDL Code on page 6 6 and Inferring Memory Functions from HDL Code on page 6 12 to ensure your HDL code infers the appropriate Altera megafunction. 1 You must use megafunctions to access some Altera device-specific architecture features. You can infer or instantiate megafunctions to target some features such as memory and DSP blocks. You must instantiate megafunctions to target certain device and high-speed features such as LVDS drivers, phase-locked loops (PLLs), transceivers, and double-data rate input/output (DDIO) circuitry. For some designs, generic HDL code can provide better results than instantiating a megafunction. Refer to the following general guidelines and examples that describe when to use standard HDL code and when to use megafunctions: For simple addition or subtraction functions, use the + or symbol instead of an LPM function. Instantiating an LPM function for simple arithmetic operations can result in a less efficient result because the function is hard coded and the synthesis algorithms cannot take advantage of basic logic optimizations. For simple multiplexers and decoders, use array notation (such as out = data[sel]) instead of an LPM function. Array notation works very well and has simple syntax. You can use the lpm_mux function to take advantage of architectural features such as cascade chains in APEX series devices, but use the LPM function only if you understand the device architecture in detail and want to force a specific implementation. Avoid division operations where possible. Division is an inherently slow operation. Many designers use multiplication creatively to produce division results. Instantiating Altera Megafunctions in HDL Code The following sections describe how to use megafunctions by instantiating them in your HDL code with the following methods: Instantiating Megafunctions Using the MegaWizard Plug-In Manager You can use the MegaWizard Plug-In Manager to parameterize the function and create a wrapper file. Creating a Netlist File for Other Synthesis Tools You can optionally create a netlist file instead of a wrapper file. March 2009 Altera Corporation Quartus II Handbook Version 9.0 Volume 1: Design and Synthesis

6 4 Chapter 6: Recommed HDL Coding Styles Instantiating Altera Megafunctions in HDL Code Instantiating Megafunctions Using the Port and Parameter Definition You can instantiate the function directly in your HDL code. Instantiating Megafunctions Using the MegaWizard Plug-In Manager Use the MegaWizard Plug-In Manager as described in this section to create megafunctions in the Quartus II GUI that you can instantiate in your HDL code. The MegaWizard Plug-In Manager provides a GUI to customize and parameterize megafunctions, and ensures that you set all megafunction parameters properly. When you finish setting parameters, you can specify which files you want generated. Deping on which language you choose, the MegaWizard Plug-In Manager instantiates the megafunction with the correct parameters and generates a megafunction variation file (wrapper file) in Verilog HDL (.v), VHDL (.vhd), or AHDL (.tdf), along with other supporting files. The MegaWizard Plug-In Manager provides options to create the following files: A sample instantiation template for the language of the variation file (_inst.v vhd tdf). Component Declaration File (.cmp) that can be used in VHDL Design Files ADHL Include File (.inc) that can be used in Text Design Files (.tdf) Quartus II Block Symbol File (.bsf) for schematic designs Verilog HDL module declaration file that can be used when instantiating the megafunction as a black box in a third-party synthesis tool (_bb.v). If you enable the option to generate a synthesis area and timing estimation netlist, the MegaWizard Plug-In Manager generates an additional synthesis netlist file (_syn.v). Refer to Creating a Netlist File for Other Synthesis Tools on page 6 5 for details. Table 6 1 lists and describes the files generated by the MegaWizard Plug-In Manager. Table 6 1. MegaWizard Plug-In Manager Generated Files (Part 1 of 2) File <output file>.v (1) <output file>.vhd (1) <output file>.tdf (1) <output file>.inc <output file>.cmp <output file>.bsf <output file>_inst.v <output file>_inst.vhd <output file>_inst.tdf Description Verilog HDL Variation Wrapper File Megafunction wrapper file for instantiation in a Verilog HDL design. VHDL Variation Wrapper File Megafunction wrapper file for instantiation in a VHDL design. AHDL Variation Wrapper File Megafunction wrapper file for instantiation in an AHDL design. ADHL Include File Used in AHDL designs. Component Declaration File Used in VHDL designs. Block Symbol File Used in Quartus II Block Design Files (.bdf). Verilog HDL Instantiation Template Sample Verilog HDL instantiation of the module in the megafunction wrapper file. VHDL Instantiation Template Sample VHDL instantiation of the entity in the megafunction wrapper file. Text Design File Instantiation Template Sample AHDL instantiation of the subdesign in the megafunction wrapper file. Quartus II Handbook Version 9.0 Volume 1: Design and Synthesis March 2009 Altera Corporation

Chapter 6: Recommed HDL Coding Styles 6 5 Instantiating Altera Megafunctions in HDL Code Table 6 1. MegaWizard Plug-In Manager Generated Files (Part 2 of 2) File <output file>_bb.v <output file>_syn.v (2) Creating a Netlist File for Other Synthesis Tools Description Black box Verilog HDL Module Declaration Hollow-body module declaration that can be used in Verilog HDL designs to specify port directions when creating black boxes in third-party synthesis tools. Synthesis area and timing estimation netlist Megafunction netlist may be used by third-party synthesis tools to improve area and timing estimations. Notes to Table 6 1: (1) The MegaWizard Plug-In Manager generates either the.v,.vhd, or.edf ile, deping on the language you select for the output file on the megafunction-selection page of the wizard. (2) The MegaWizard Plug-In Manager generates this file only if you turn on the Generate netlist option under Timing and resource estimation on the EDA page of the wizard. When you use certain megafunctions with third-party EDA synthesis tools (that is, tools other than Quartus II integrated synthesis), you can optionally create a netlist for area and timing estimation instead of a wrapper file. The netlist file is a representation of the customized logic used in the Quartus II software. The file provides the connectivity of architectural elements in the megafunction but may not represent true functionality. This information enables certain third-party synthesis tools to better report area and timing estimates. In addition, synthesis tools can use the timing information to focus timing-driven optimizations and improve the quality of results. To generate the netlist, turn on Generate a synthesis area and timing estimation netlist on the EDA page of the MegaWizard Plug-In Manager. The netlist file is called <output file>_syn.v. If you use this netlist for synthesis, you must include the megafunction wrapper file <output file>.v vhd in your Quartus II project for placement and routing. Your synthesis tool may call the Quartus II software in the background to generate this netlist, so you might not be required to perform the extra step of turning on this option. f For information about support for area and timing estimation netlists in your synthesis tool, refer to the tool vor s documentation or the appropriate chapter in the Synthesis section in volume 1 of the Quartus II Handbook. Instantiating Megafunctions Using the Port and Parameter Definition You can instantiate the megafunction directly in your Verilog HDL, VHDL, or AHDL code by calling the megafunction and setting its parameters as you would any other module, component, or subdesign. f Refer to the specific megafunction in the Quartus II Help for a list of the megafunction ports and parameters. The Quartus II Help also provides a sample VHDL component declaration and AHDL function prototype for each megafunction. March 2009 Altera Corporation Quartus II Handbook Version 9.0 Volume 1: Design and Synthesis

6 6 Chapter 6: Recommed HDL Coding Styles Inferring Multiplier and DSP Functions from HDL Code 1 Altera strongly recomms that you use the MegaWizard Plug-In Manager for complex megafunctions such as PLLs, transceivers, and LVDS drivers. For details about using the MegaWizard Plug-In Manager, refer to Instantiating Megafunctions Using the MegaWizard Plug-In Manager on page 6 4. Inferring Multiplier and DSP Functions from HDL Code The following sections describe how to infer multiplier and DSP functions from generic HDL code, and, if applicable, how to target the dedicated DSP block architecture in Altera devices: Multipliers Inferring the LPM_MULT Megafunction from HDL Code Multiply-Accumulators and Multiply-Adders Inferring ALTMULT_ACCUM and ALTMULT_ADD Megafunctions from HDL Code on page 6 8 f f For synthesis tool features and options, refer to your synthesis tool documentation or the appropriate chapter in the Synthesis section in volume 1 of the Quartus II Handbook. For more design examples involving advanced multiply functions and complex DSP functions, refer to the DSP Design Examples page on Altera s website. Multipliers Inferring the LPM_MULT Megafunction from HDL Code To infer multiplier functions, synthesis tools look for multipliers and convert them to LPM_MULT or ALTMULT_ADD megafunctions, or may map them directly to device atoms. For devices with DSP blocks, the software can implement the function in a DSP block instead of logic, deping on device utilization. The Quartus II Fitter can also place input and output registers in DSP blocks (that is, perform register packing) to improve performance and area utilization. f For additional information about the DSP block and the supported functions, refer to the appropriate Altera device family handbook and Altera s DSP Solutions Center website. Example 6 1 and Example 6 2 show Verilog HDL code examples, and Example 6 3 and Example 6 4 show VHDL code examples, for unsigned and signed multipliers that synthesis tools can infer as an LPM_MULT or ALTMULT_ADD megafunction. Each example fits into one DSP block 9-bit element. In addition, when register packing occurs, no extra logic cells for registers are required. 1 The signed declaration in Verilog HDL is a feature of the Verilog 2001 Standard. Example 6 1. Verilog HDL Unsigned Multiplier module unsigned_mult (out, a, b); output [15:0] out; input [7:0] a; input [7:0] b; assign out = a * b; module Quartus II Handbook Version 9.0 Volume 1: Design and Synthesis March 2009 Altera Corporation

Chapter 6: Recommed HDL Coding Styles 6 7 Inferring Multiplier and DSP Functions from HDL Code Example 6 2. Verilog HDL Signed Multiplier with Input and Output Registers (Pipelining = 2) module signed_mult (out, clk, a, b); output [15:0] out; input clk; input signed [7:0] a; input signed [7:0] b; reg signed [7:0] a_reg; reg signed [7:0] b_reg; reg signed [15:0] out; wire signed [15:0] mult_out; assign mult_out = a_reg * b_reg; always @ (posedge clk) begin a_reg <= a; b_reg <= b; out <= mult_out; module Example 6 3. VHDL Unsigned Multiplier with Input and Output Registers (Pipelining = 2) LIBRARY ieee; USE ieee.std_logic_1164.all; USE ieee.numeric_std.all; ENTITY unsigned_mult IS PORT ( a: IN UNSIGNED (7 DOWNTO 0); b: IN UNSIGNED (7 DOWNTO 0); clk: IN STD_LOGIC; aclr: IN STD_LOGIC; result: OUT UNSIGNED (15 DOWNTO 0) ); END unsigned_mult; ARCHITECTURE rtl OF unsigned_mult IS SIGNAL a_reg, b_reg: UNSIGNED (7 DOWNTO 0); BEGIN PROCESS (clk, aclr) BEGIN IF (aclr ='1') THEN a_reg <= (OTHERS => '0'); b_reg <= (OTHERS => '0'); result <= (OTHERS => '0'); ELSIF (clk'event AND clk = '1') THEN a_reg <= a; b_reg <= b; result <= a_reg * b_reg; END IF; END PROCESS; END rtl; March 2009 Altera Corporation Quartus II Handbook Version 9.0 Volume 1: Design and Synthesis

6 8 Chapter 6: Recommed HDL Coding Styles Inferring Multiplier and DSP Functions from HDL Code Example 6 4. VHDL Signed Multiplier LIBRARY ieee; USE ieee.std_logic_1164.all; USE ieee.numeric_std.all; ENTITY signed_mult IS PORT ( a: IN SIGNED (7 DOWNTO 0); b: IN SIGNED (7 DOWNTO 0); result: OUT SIGNED (15 DOWNTO 0) ); END signed_mult; BEGIN result <= a * b; END rtl; Multiply-Accumulators and Multiply-Adders Inferring ALTMULT_ACCUM and ALTMULT_ADD Megafunctions from HDL Code Synthesis tools detect multiply-accumulators or multiply-adders and convert them to ALTMULT_ACCUM or ALTMULT_ADD megafunctions, respectively, or may map them directly to device atoms. The Quartus II software then places these functions in DSP blocks during placement and routing. 1 Synthesis tools infer multiply-accumulator and multiply-adder functions only if the Altera device family has dedicated DSP blocks that support these functions. A simple multiply-accumulator consists of a multiplier feeding an addition operator. The addition operator feeds a set of registers that then feeds the second input to the addition operator. A simple multiply-adder consists of two to four multipliers feeding one or two levels of addition, subtraction, or addition/subtraction operators. Addition is always the second-level operator, if it is used. In addition to the multiply-accumulator and multiply-adder, the Quartus II Fitter also places input and output registers into the DSP blocks to pack registers and improve performance and area utilization. Some device families offer additional advanced multiply-add and accumulate functions, such as complex multiplication, input shift register, or larger multiplications. f For details about advanced DSP block features, refer to the appropriate device handbook. For more design examples involving DSP functions and inferring advanced features in the multiply-add and multiply-accumulate circuitry, refer to the DSP Design Examples page on Altera s website. The Verilog HDL and VHDL code samples shown in Example 6 5 through Example 6 8 infer multiply-accumulators and multiply-adders with input, output, and pipeline registers as well as an optional asynchronous clear signal. Using the three sets of registers provides the best performance through the function, with a latency of 3. You can remove the registers in your design to reduce the latency. Quartus II Handbook Version 9.0 Volume 1: Design and Synthesis March 2009 Altera Corporation

Chapter 6: Recommed HDL Coding Styles 6 9 Inferring Multiplier and DSP Functions from HDL Code Example 6 5. Verilog HDL Unsigned Multiply-Accumulator module unsig_altmult_accum (dataout, dataa, datab, clk, aclr, clken); input [7:0] dataa; input [7:0] datab; input clk; input aclr; input clken; output [31:0] dataout; reg [31:0] dataout; reg [7:0] dataa_reg; reg [7:0] datab_reg; reg [15:0] multa_reg; wire [15:0] multa; wire [31:0] adder_out; assign multa = dataa_reg * datab_reg; assign adder_out = multa_reg + dataout; always @ (posedge clk or posedge aclr) begin if (aclr) begin dataa_reg <= 8'b0; datab_reg <= 8'b0; multa_reg <= 16'b0; dataout <= 32'b0; else if (clken) begin dataa_reg <= dataa; datab_reg <= datab; multa_reg <= multa; dataout <= adder_out; module March 2009 Altera Corporation Quartus II Handbook Version 9.0 Volume 1: Design and Synthesis

6 10 Chapter 6: Recommed HDL Coding Styles Inferring Multiplier and DSP Functions from HDL Code Example 6 6. Verilog HDL Signed Multiply-Adder module sig_altmult_add (dataa, datab, datac, datad, clock, aclr, result); input signed [15:0] dataa, datab, datac, datad; input clock, aclr; output reg signed [32:0] result; reg signed [15:0] dataa_reg, datab_reg, datac_reg, datad_reg; reg signed [31:0] mult0_result, mult1_result; always @ (posedge clock or posedge aclr) begin if (aclr) begin dataa_reg <= 16'b0; datab_reg <= 16'b0; datac_reg <= 16'b0; datad_reg <= 16'b0; mult0_result <= 32'b0; mult0_result <= 32'b0; result <= 33'b0; else begin dataa_reg <= dataa; datab_reg <= datab; datac_reg <= datac; datad_reg <= datad; mult0_result <= dataa_reg * datab_reg; mult1_result <= datac_reg * datad_reg; result <= mult0_result + mult1_result; module Quartus II Handbook Version 9.0 Volume 1: Design and Synthesis March 2009 Altera Corporation

Chapter 6: Recommed HDL Coding Styles 6 11 Inferring Multiplier and DSP Functions from HDL Code Example 6 7. VHDL Signed Multiply-Accumulator LIBRARY ieee; USE ieee.std_logic_1164.all; USE ieee.numeric_std.all; ENTITY sig_altmult_accum IS PORT ( a: IN SIGNED(7 DOWNTO 0); b: IN SIGNED (7 DOWNTO 0); clk: IN STD_LOGIC; aclr: IN STD_LOGIC; accum_out: OUT SIGNED (15 DOWNTO 0) ) ; END sig_altmult_accum; ARCHITECTURE rtl OF sig_altmult_accum IS SIGNAL a_reg, b_reg: SIGNED (7 DOWNTO 0); SIGNAL pdt_reg: SIGNED (15 DOWNTO 0); SIGNAL adder_out: SIGNED (15 DOWNTO 0); BEGIN PROCESS (clk, aclr) BEGIN IF (aclr = '1') then a_reg <= (others => '0'); b_reg <= (others => '0'); pdt_reg <= (others => '0'); adder_out <= (others => '0'); ELSIF (clk'event and clk = '1') THEN a_reg <= (a); b_reg <= (b); pdt_reg <= a_reg * b_reg; adder_out <= adder_out + pdt_reg; END IF; END process; accum_out <= adder_out; END rtl; March 2009 Altera Corporation Quartus II Handbook Version 9.0 Volume 1: Design and Synthesis

6 12 Chapter 6: Recommed HDL Coding Styles Inferring Memory Functions from HDL Code Example 6 8. VHDL Unsigned Multiply-Adder LIBRARY ieee; USE ieee.std_logic_1164.all; USE ieee.numeric_std.all; ENTITY unsignedmult_add IS PORT ( a: IN UNSIGNED (7 DOWNTO 0); b: IN UNSIGNED (7 DOWNTO 0); c: IN UNSIGNED (7 DOWNTO 0); d: IN UNSIGNED (7 DOWNTO 0); clk: IN STD_LOGIC; aclr: IN STD_LOGIC; result: OUT UNSIGNED (15 DOWNTO 0) ); END unsignedmult_add; ARCHITECTURE rtl OF unsignedmult_add IS SIGNAL a_reg, b_reg, c_reg, d_reg: UNSIGNED (7 DOWNTO 0); SIGNAL pdt_reg, pdt2_reg: UNSIGNED (15 DOWNTO 0); SIGNAL result_reg: UNSIGNED (15 DOWNTO 0); BEGIN PROCESS (clk, aclr) BEGIN IF (aclr = '1') THEN a_reg <= (OTHERS => '0'); b_reg <= (OTHERS => '0'); c_reg <= (OTHERS => '0'); d_reg <= (OTHERS => '0'); pdt_reg <= (OTHERS => '0'); pdt2_reg <= (OTHERS => '0'); ELSIF (clk'event AND clk = '1') THEN a_reg <= a; b_reg <= b; c_reg <= c; d_reg <= d; pdt_reg <= a_reg * b_reg; pdt2_reg <= c_reg * d_reg; result_reg <= pdt_reg + pdt2_reg; END IF; END PROCESS; result <= result_reg; END rtl; Inferring Memory Functions from HDL Code The following sections describe how to infer memory functions from generic HDL code and, if applicable, to target the dedicated memory architecture in Altera devices: RAM Functions Inferring ALTSYNCRAM and ALTDPRAM Megafunctions from HDL Code on page 6 13 ROM Functions Inferring ALTSYNCRAM and LPM_ROM Megafunctions from HDL Code on page 6 29 Shift Registers Inferring the ALTSHIFT_TAPS Megafunction from HDL Code on page 6 32 Quartus II Handbook Version 9.0 Volume 1: Design and Synthesis March 2009 Altera Corporation

Chapter 6: Recommed HDL Coding Styles 6 13 Inferring Memory Functions from HDL Code f For synthesis tool features and options, refer to your synthesis tool documentation or the appropriate chapter in the Synthesis section in volume 1 of the Quartus II Handbook. Altera s dedicated memory architecture offers a number of advanced features that can be easily targeted using the MegaWizard Plug-In Manager, as described in Instantiating Altera Megafunctions in HDL Code on page 6 3. The coding recommations in the following sections provide portable examples of generic HDL code that infer the appropriate megafunction. However, if you want to use some of the advanced memory features in Altera devices, consider using the megafunction directly so that you can control the ports and parameters more easily. RAM Functions Inferring ALTSYNCRAM and ALTDPRAM Megafunctions from HDL Code To infer RAM functions, synthesis tools detect sets of registers and logic that can be replaced with the ALTSYNCRAM or ALTDPRAM megafunctions for device families that have dedicated RAM blocks, or may map them directly to device memory atoms. Tools typically consider all signals and variables that have a two-dimensional array type and then create a RAM block, if applicable, based on the way the signals, variables, or both are assigned, referenced, or both in the HDL source description. This section provides examples demonstrating the coding styles that are inferred to create a memory block. Standard synthesis tools recognize single-port and simple dual-port (one read port and one write port) RAM blocks. Some tools (such as the Quartus II software) also recognize true dual-port RAM blocks that map to the memory blocks in certain Altera devices. Tools usually do not infer small RAM blocks because small RAM blocks typically can be implemented more efficiently using the registers in regular logic. If you are using Quartus II integrated synthesis, you can direct the software to infer ROM blocks for all sizes with the Allow Any RAM Size for Recognition option under More Settings on the Analysis & Synthesis Settings page of the Settings dialog box. 1 If your design contains a RAM block that your synthesis tool does not recognize and infer, the design might require a large amount of system memory that can potentially cause compilation problems. Some synthesis tools provide options to control the implementation of inferred RAM blocks for Altera devices with TriMatrix memory blocks. For example, Quartus II integrated synthesis provides the ramstyle synthesis attribute to specify the type of memory block or to specify the use of regular logic instead of a dedicated memory block. Quartus II integrated synthesis does not map inferred memory into Stratix III MLABs unless the HDL code specifies the appropriate ramstyle attribute, although the Fitter may map some memories to MLABs. f For details about using the ramstyle attribute, refer to the Quartus II Integrated Synthesis chapter in volume 1 of the Quartus II Handbook. For information about synthesis attributes in other synthesis tools, refer to the appropriate chapter in the Synthesis section in volume 1 of the Quartus II Handbook. March 2009 Altera Corporation Quartus II Handbook Version 9.0 Volume 1: Design and Synthesis

6 14 Chapter 6: Recommed HDL Coding Styles Inferring Memory Functions from HDL Code When you use a formal verification flow, Altera recomms that you create RAM blocks in separate entities or modules that contain only the RAM logic. In certain formal verification flows, for example, when using Quartus II integrated synthesis, the entity or module containing the inferred RAM is put into a black box automatically because formal verification tools do not support RAM blocks. The Quartus II software issues a warning message when this occurs. If the entity or module contains any additional logic outside the RAM block, this logic also must be treated as a black box for formal verification and therefore cannot be verified. The following subsections present several guidelines for inferring RAM functions that match the dedicated memory architecture in Altera devices, and then provide recommed HDL code for different types of memory logic. Use Synchronous Memory Blocks Altera recomms using synchronous memory blocks for Altera designs. The TriMatrix memory blocks in Altera s newest devices are synchronous, so RAM designs that are targeted towards architectures that contain these dedicated memory blocks must be synchronous to be mapped directly into the device architecture. For these devices, asynchronous memory logic is implemented in regular logic cells. Synchronous memories are supported in all Altera device families. A memory block is considered synchronous if it uses one of the following read behaviors: Memory read occurs in a Verilog always block with a clock signal or a VHDL clocked process. Memory read occurs outside a clocked block, but there is a synchronous read address (that is, the address used in the read statement is registered). This type of logic is not always inferred as a memory block, deping on the target device architecture. 1 The synchronous memory structures in Altera devices differ from the structures in other vors devices. Match your design to the target device architecture to achieve the best results. Later subsections provide coding recommations for various memory types. All of these examples are synchronous to ensure that they can be directly mapped into the dedicated memory architecture available in Altera FPGAs. f For additional information about the dedicated memory blocks in your specific device, refer to the appropriate Altera device family data sheet on the Altera website at www.altera.com. Avoid Unsupported Reset and Control Conditions To ensure that your HDL code can be implemented in the target device architecture, avoid unsupported reset conditions or other control logic that does not exist in the device architecture. Quartus II Handbook Version 9.0 Volume 1: Design and Synthesis March 2009 Altera Corporation

Chapter 6: Recommed HDL Coding Styles 6 15 Inferring Memory Functions from HDL Code The RAM contents of Altera memory blocks cannot be cleared with a reset signal during device operation. If your HDL code describes a RAM with a reset signal for the RAM contents, the logic is implemented in regular logic cells instead of a memory block. As a general rule, avoid putting RAM read or write operations in an always block or process block with a reset signal. If you want to specify memory contents, initialize the memory as described in Specifying Initial Memory Contents at Power-Up on page 6 27 or write the data to the RAM during device operation. Example 6 9 shows an example of undesirable code where there is a reset signal that clears part of the RAM contents. Avoid this coding style because it is not supported in Altera memories. Example 6 9. Verilog RAM with Reset Signal that Clears RAM Contents: Not Supported in Device Architecture module clear_ram ( input clock, input reset, input we, input [7:0] data_in, input [4:0] address, output reg [7:0] data_out ); reg [7:0] mem [0:31]; integer i; always @ (posedge clock or posedge reset) begin if (reset == 1'b1) mem[address] <= 0; else if (we == 1'b1) mem[address] <= data_in; data_out <= mem[address]; module Example 6 10 shows an example of undesirable code where the reset signal affects the RAM, although the effect may not be inted. Avoid this coding style because it is not supported in Altera memories. March 2009 Altera Corporation Quartus II Handbook Version 9.0 Volume 1: Design and Synthesis

6 16 Chapter 6: Recommed HDL Coding Styles Inferring Memory Functions from HDL Code Example 6 10. Verilog RAM with Reset Signal that Affects RAM: Not Supported in Device Architecture module bad_reset ( input clock, input reset, input we, input [7:0] data_in, input [4:0] address, output reg [7:0] data_out, input d, output reg q ); reg [7:0] mem [0:31]; integer i; always @ (posedge clock or posedge reset) begin if (reset == 1'b1) q <= 0; else begin if (we == 1'b1) mem[address] <= data_in; data_out <= mem[address]; q <= d; module In addition to reset signals, other control logic can prevent memory logic from being inferred as a memory block. For example, you cannot use a clock enable on the read address registers in Stratix devices, because doing so affects the output latch of the RAM, and therefore the synthesized result in the device RAM architecture would not match the HDL description. In Stratix II, Cyclone II, Arria GX, and other newer devices, however, you can use the address stall feature as a read address clock enable, so there is no such limitation. Check the documentation on your device architecture to ensure that your code matches the hardware available in the device. Check Read-During-Write Behavior It is important to check the read-during-write behavior of the memory block described in your HDL design as compared to the behavior in your target device architecture. Your HDL source code specifies the memory behavior when you read and write from the same memory address in the same clock cycle. The code specifies that the read returns either the old data at the address, or the new data being written to the address. This is referred to as the read-during-write behavior of the memory block. Altera memory blocks have different read-during-write behavior deping on the target device family, memory mode, and block type. Synthesis tools map an HDL design into the target device architecture, with the goal of maintaining the functionality described in your source code. Therefore, if your source code specifies unsupported read-during-write behavior for the device RAM blocks, the software must implement the logic outside the RAM hardware in regular logic cells. Quartus II Handbook Version 9.0 Volume 1: Design and Synthesis March 2009 Altera Corporation

Chapter 6: Recommed HDL Coding Styles 6 17 Inferring Memory Functions from HDL Code One common problem occurs when there is a continuous read in the HDL code, as shown in the following samples. You should avoid using these coding styles: //Verilog HDL concurrent signal assignment assign q = ram[raddr_reg]; -- VHDL concurrent signal assignment q <= ram(raddr_reg); When a write operation occurs, this type of HDL implies that the read should immediately reflect the new data at the address, indepent of the read clock. However, that is not the behavior of TriMatrix memory blocks. In the device architecture, the new data is not available until the next edge of the read clock. Therefore, if the synthesis tool mapped the logic directly to a TriMatrix memory block, the device functionality and gate-level simulation results would not match the HDL description or function simulation results. If the write clock and read clock are the same, the synthesis tool can infer memory blocks and add extra bypass logic so that the device behavior does match the HDL behavior. If the write and read clocks are different, the synthesis tool cannot reliably add bypass logic, so the logic is implemented in regular logic cells instead of dedicated RAM blocks. The examples in the following sections discuss some of these differences for read-during-write conditions. In addition, the MLAB feature in Stratix III logic array blocks (LABs) does not easily support old data or new data behavior for a read during write in the dedicated device architecture. Implementing the extra logic to support this behavior significantly reduces timing performance through the memory. 1 For best performance in MLAB memories, your design should not dep on the read data during a write operation. In many synthesis tools, you can specify that the read-during-write behavior is not important to your design; for example, if you never read from the same address to which you write in the same clock cycle. For Quartus II integrated synthesis, add the synthesis attribute ramstyle="no_rw_check" to allow the software to choose the read-during-write behavior of a RAM, rather than use the behavior specified by your HDL code. Using this type of attribute prevents the synthesis tool from using extra logic to implement the memory block, and in some cases, can allow memory inference when it would otherwise be impossible. f For more information about attribute syntax, the no_rw_check attribute value, or specific options for your synthesis tool, refer to your synthesis tool documentation or the appropriate chapter in the Synthesis section in volume 1 of the Quartus II Handbook. The following subsections provide coding recommations for various memory types. Each example describes the read-during-write behavior and addresses the support for the memory type in Altera devices. Single-Clock Synchronous RAM with Old Data Read-During-Write Behavior The code examples in this section show Verilog HDL and VHDL code that infers simple dual-port, single-clock synchronous RAM. Single-port RAM blocks use a similar coding style. March 2009 Altera Corporation Quartus II Handbook Version 9.0 Volume 1: Design and Synthesis

6 18 Chapter 6: Recommed HDL Coding Styles Inferring Memory Functions from HDL Code The read-during-write behavior in these examples is to read the old data at the memory address. Refer to Check Read-During-Write Behavior on page 6 16 for details. Altera recomms that you use this coding style for most RAM blocks as long as your design does not require that a simultaneous read and write to the same RAM location read the new value that is currently being written to that RAM location. For best performance in MLAB memories, use the appropriate attribute so that your design does not dep on the read data during a write operation. If you require that the read-during-write results in new data, refer to Single-Clock Synchronous RAM with New Data Read-During-Write Behavior on page 6 19. The simple dual-port RAM code samples shown in Example 6 11 and Example 6 12 map directly into Altera TriMatrix memory. Single-port versions of memory blocks (that is, using the same read address and write address signals) can allow better RAM utilization than dual-port memory blocks, deping on the device family. Example 6 11. Verilog HDL Single-Clock Simple Dual-Port Synchronous RAM with Old Data Read-During-Write Behavior module single_clk_ram( output reg [7:0] q, input [7:0] d, input [6:0] write_address, read_address, input we, clk ); reg [7:0] mem [127:0]; always @ (posedge clk) begin if (we) mem[write_address] <= d; q <= mem[read_address]; // q doesn't get d in this clock cycle module Quartus II Handbook Version 9.0 Volume 1: Design and Synthesis March 2009 Altera Corporation

Chapter 6: Recommed HDL Coding Styles 6 19 Inferring Memory Functions from HDL Code Example 6 12. VHDL Single-Clock Simple Dual-Port Synchronous RAM with Old Data Read-During-Write Behavior LIBRARY ieee; USE ieee.std_logic_1164.all; ENTITY single_clock_ram IS PORT ( clock: IN STD_LOGIC; data: IN STD_LOGIC_VECTOR (2 DOWNTO 0); write_address: IN INTEGER RANGE 0 to 31; read_address: IN INTEGER RANGE 0 to 31; we: IN STD_LOGIC; q: OUT STD_LOGIC_VECTOR (2 DOWNTO 0) ); END single_clock_ram; ARCHITECTURE rtl OF single_clock_ram IS TYPE MEM IS ARRAY(0 TO 31) OF STD_LOGIC_VECTOR(2 DOWNTO 0); SIGNAL ram_block: MEM; BEGIN PROCESS (clock) BEGIN IF (clock'event AND clock = '1') THEN IF (we = '1') THEN ram_block(write_address) <= data; END IF; q <= ram_block(read_address); -- VHDL semantics imply that q doesn't get data -- in this clock cycle END IF; END PROCESS; END rtl; Single-Clock Synchronous RAM with New Data Read-During-Write Behavior The examples in this section describe RAM blocks in which a simultaneous read and write to the same location reads the new value that is currently being written to that RAM location. To implement this behavior in the target device, synthesis software adds bypass logic around the RAM block. This bypass logic increases the area utilization of the design and decreases the performance if the RAM block is part of the design s critical path. Refer to Check Read-During-Write Behavior on page 6 16 for details. If this behavior is not required for your design, use the examples from Single-Clock Synchronous RAM with Old Data Read-During-Write Behavior on page 6 17. The simple dual-port RAM shown in Example 6 13 and Example 6 14 require the software to create bypass logic around the RAM block. Single-port versions of the Verilog memory block (that is, using the same read address and write address signals) do not require any logic cells to create bypass logic in the Arria GX, Stratix, and Cyclone series of devices, because the device memory supports new data read-during-write behavior when in single-port mode (same clock, same read, and write address). March 2009 Altera Corporation Quartus II Handbook Version 9.0 Volume 1: Design and Synthesis

6 20 Chapter 6: Recommed HDL Coding Styles Inferring Memory Functions from HDL Code Example 6 13. Verilog HDL Single-Clock Simple Dual-Port Synchronous RAM with New Data Read-During-Write Behavior module single_clock_wr_ram( output reg [7:0] q, input [7:0] d, input [6:0] write_address, read_address, input we, clk ); reg [7:0] mem [127:0]; always @ (posedge clk) begin if (we) mem[write_address] = d; q = mem[read_address]; // q does get d in this clock cycle if we is high module 1 Example 6 13 is similar to Example 6 11, but Example 6 13 uses a blocking assignment for the write so that the data is assigned immediately. An alternative way to create a single-clock RAM is to use an assign statement to read the address of mem to create the output q, as shown in the following coding style. By itself, the code describes new data read-during-write behavior. However, if the RAM output feeds a register in another hierarchy, then a read-during-write would result in the old data. Synthesis tools may not infer a RAM block if the tool cannot determine which behavior is described, such as when the memory feeds a hard hierarchical partition boundary. For this reason, avoid using this alternate type of coding style: reg [7:0] mem [127:0]; reg [6:0] read_address_reg; always @ (posedge clk) begin if (we) mem[write_address] <= d; read_address_reg <= read_address; assign q = mem[read_address_reg]; Quartus II Handbook Version 9.0 Volume 1: Design and Synthesis March 2009 Altera Corporation

Chapter 6: Recommed HDL Coding Styles 6 21 Inferring Memory Functions from HDL Code The VHDL sample in Example 6 14 uses a concurrent signal assignment to read from the RAM. By itself, this example describes new data read-during-write behavior. However, if the RAM output feeds a register in another hierarchy, a read-during-write results in the old data. Synthesis tools may not infer a RAM block if the tool cannot determine which behavior is described, such as when the memory feeds a hard hierarchical partition boundary. Example 6 14. VHDL Single-Clock Simple Dual-Port Synchronous RAM with New Data Read-During-Write Behavior LIBRARY ieee; USE ieee.std_logic_1164.all; ENTITY single_clock_rw_ram IS PORT ( clock: IN STD_LOGIC; data: IN STD_LOGIC_VECTOR (2 DOWNTO 0); write_address: IN INTEGER RANGE 0 to 31; read_address: IN INTEGER RANGE 0 to 31; we: IN STD_LOGIC; q: OUT STD_LOGIC_VECTOR (2 DOWNTO 0) ); END single_clock_rw_ram; ARCHITECTURE rtl OF single_clock_rw_ram IS TYPE MEM IS ARRAY(0 TO 31) OF STD_LOGIC_VECTOR(2 DOWNTO 0); SIGNAL ram_block: MEM; SIGNAL read_address_reg: INTEGER RANGE 0 to 31; BEGIN PROCESS (clock) BEGIN IF (clock'event AND clock = '1') THEN IF (we = '1') THEN ram_block(write_address) <= data; END IF; read_address_reg <= read_address; END IF; END PROCESS; q <= ram_block(read_address_reg); END rtl; Example 6 14 does not infer a RAM block for the APEX series of devices, ACEX, or the FLEX series of devices by default because the read-during-write behavior deps on surrounding logic. For Quartus II integrated synthesis, if you do not require the read-through-write capability, add the synthesis attribute ramstyle="no_rw_check" to allow the software to choose the read-during-write behavior of a RAM, rather than use the behavior specified by your HDL code. Simple Dual-Port, Dual-Clock Synchronous RAM In dual clock designs, synthesis tools cannot accurately infer the read-during-write behavior because it deps on the timing of the two clocks within the target device. Therefore, the read-during-write behavior of the synthesized design is undefined and may differ from your original HDL code. Refer to Check Read-During-Write Behavior on page 6 16 for details. March 2009 Altera Corporation Quartus II Handbook Version 9.0 Volume 1: Design and Synthesis

6 22 Chapter 6: Recommed HDL Coding Styles Inferring Memory Functions from HDL Code When Quartus II integrated synthesis infers this type of RAM, it issues a warning because of the undefined read-during-write behavior. If this functionality is acceptable in your design, you can avoid the warning by adding the synthesis attribute ramstyle="no_rw_check" to allow the software to choose the read-during-write behavior of a RAM. The code samples shown in Example 6 15 and Example 6 16 show Verilog HDL and VHDL code that infers dual-clock synchronous RAM. The exact behavior deps on the relationship between the clocks. Example 6 15. Verilog HDL Simple Dual-Port, Dual-Clock Synchronous RAM module dual_clock_ram( output reg [7:0] q, input [7:0] d, input [6:0] write_address, read_address, input we, clk1, clk2 ); reg [6:0] read_address_reg; reg [7:0] mem [127:0]; always @ (posedge clk1) begin if (we) mem[write_address] <= d; always @ (posedge clk2) begin q <= mem[read_address_reg]; read_address_reg <= read_address; module Quartus II Handbook Version 9.0 Volume 1: Design and Synthesis March 2009 Altera Corporation

Chapter 6: Recommed HDL Coding Styles 6 23 Inferring Memory Functions from HDL Code Example 6 16. VHDL Simple Dual-Port, Dual-Clock Synchronous RAM LIBRARY ieee; USE ieee.std_logic_1164.all; ENTITY dual_clock_ram IS PORT ( clock1, clock2: IN STD_LOGIC; data: IN STD_LOGIC_VECTOR (3 DOWNTO 0); write_address: IN INTEGER RANGE 0 to 31; read_address: IN INTEGER RANGE 0 to 31; we: IN STD_LOGIC; q: OUT STD_LOGIC_VECTOR (3 DOWNTO 0) ); END dual_clock_ram; ARCHITECTURE rtl OF dual_clock_ram IS TYPE MEM IS ARRAY(0 TO 31) OF STD_LOGIC_VECTOR(3 DOWNTO 0); SIGNAL ram_block: MEM; SIGNAL read_address_reg : INTEGER RANGE 0 to 31; BEGIN PROCESS (clock1) BEGIN IF (clock1'event AND clock1 = '1') THEN IF (we = '1') THEN ram_block(write_address) <= data; END IF; END IF; END PROCESS; PROCESS (clock2) BEGIN IF (clock2'event AND clock2 = '1') THEN q <= ram_block(read_address_reg); read_address_reg <= read_address; END IF; END PROCESS; END rtl; True Dual-Port Synchronous RAM The code examples in this section show Verilog HDL and VHDL code that infers true dual-port synchronous RAM. Different synthesis tools may differ in their support for these types of memories. This section describes the inference rules for Quartus II integrated synthesis. This type of RAM inference is supported only for the Arria GX, Stratix, and Cyclone series of devices. Altera TriMatrix memory blocks have two indepent address ports, allowing for operations on two unique addresses simultaneously. A read operation and a write operation can share the same port if they share the same address. The Quartus II software infers true dual-port RAMs in Verilog HDL and VHDL with any combination of indepent read or write operations in the same clock cycle, with at most two unique port addresses, performing two reads and one write, two writes and one read, or two writes and two reads in one clock cycle with one or two unique addresses. March 2009 Altera Corporation Quartus II Handbook Version 9.0 Volume 1: Design and Synthesis

6 24 Chapter 6: Recommed HDL Coding Styles Inferring Memory Functions from HDL Code In the TriMatrix RAM block architecture, there is no priority between the two ports. Therefore, if you write to the same location on both ports at the same time, the result is indeterminate in the device architecture. You must ensure your HDL code does not imply priority for writes to the memory block, if you want the design to be implemented in a dedicated hardware memory block. For example, if both ports are defined in the same process block, the code is synthesized and simulated sequentially so there would be a priority between the two ports. If your code does imply a priority, the logic cannot be implemented in the device RAM blocks and is implemented in regular logic cells. You must also consider the read-during-write behavior of the RAM block, to ensure that it can be mapped directly to the device RAM architecture. Refer to Check Read-During-Write Behavior on page 6 16 for details. When a read and write operation occur on the same port for the same address, the read operation may behave as follows: Read new data This mode matches the behavior of TriMatrix memory blocks. Read old data This mode is supported only by Stratix IV, Arria II GX, Stratix III, and Cyclone III TriMatrix memory blocks. This behavior is not possible in TriMatrix memory blocks of other families. When a read and write operation occur on different ports for the same address (also known as mixed port), the read operation may behave as follows: Read new data Quartus II integrated synthesis supports this mode by creating bypass logic around the TriMatrix memory block. Read old data This behavior is supported by TriMatrix memory blocks. The Verilog HDL single-clock code sample shown in Example 6 17 maps directly into Altera TriMatrix memory. When a read and write operation occur on the same port for the same address, the new data being written to the memory is read. When a read and write operation occur on different ports for the same address, the old data in the memory is read. Simultaneous writes to the same location on both ports results in indeterminate behavior. A dual-clock version of this design describes the same behavior, but the memory in the target device will have undefined mixed port read-during-write behavior because it deps on the relationship between the clocks. Quartus II Handbook Version 9.0 Volume 1: Design and Synthesis March 2009 Altera Corporation

Chapter 6: Recommed HDL Coding Styles 6 25 Inferring Memory Functions from HDL Code Example 6 17. Verilog HDL True Dual-Port RAM with Single Clock module true_dual_port_ram_single_clock ( input [(DATA_WIDTH-1):0] data_a, data_b, input [(ADDR_WIDTH-1):0] addr_a, addr_b, input we_a, we_b, clk, output reg [(DATA_WIDTH-1):0] q_a, q_b ); parameter DATA_WIDTH = 8; parameter ADDR_WIDTH = 6; // Declare the RAM variable reg [DATA_WIDTH-1:0] ram[2**addr_width-1:0]; always @ (posedge clk) begin // Port A if (we_a) begin ram[addr_a] <= data_a; q_a <= data_a; else q_a <= ram[addr_a]; always @ (posedge clk) begin // Port b if (we_b) begin ram[addr_b] <= data_b; q_b <= data_b; else q_b <= ram[addr_b]; module If you use the following Verilog HDL read statements instead of the if-else statements in Example 6 17, the HDL code specifies that the read results in old data when a read and write operation occur at the same time for the same address on the same port or mixed ports. (This behavior is supported only in the TriMatrix memories of Stratix IV, Arria II GX, Stratix III and Cyclone III devices, and is not inferred as memory for other device families): always @ (posedge clk) begin // Port A if (we_a) ram[addr_a] <= data_a; q_a <= ram[addr_a]; always @ (posedge clk) begin // Port B if (we_b) ram[addr_b] <= data_b; q_b <= ram[addr_b]; March 2009 Altera Corporation Quartus II Handbook Version 9.0 Volume 1: Design and Synthesis