Component Author Guide PDF
Component Author Guide PDF
Cypress Semiconductor
198 Champion Court
San Jose, CA 95134-1709
http://www.cypress.com
© Cypress Semiconductor Corporation, 2007-2017.
This document is the property of Cypress Semiconductor Corporation and its subsidiaries, including Spansion LLC
("Cypress"). This document, including any software or firmware included or referenced in this document ("Software"), is
owned by Cypress under the intellectual property laws and treaties of the United States and other countries worldwide.
Cypress reserves all rights under such laws and treaties and does not, except as specifically stated in this paragraph, grant
any license under its patents, copyrights, trademarks, or other intellectual property rights. If the Software is not accompanied
by a license agreement and you do not otherwise have a written agreement with Cypress governing the use of the Software,
then Cypress hereby grants you a personal, non-exclusive, nontransferable license (without the right to sublicense) (1) under
its copyright rights in the Software (a) for Software provided in source code form, to modify and reproduce the Software solely
for use with Cypress hardware products, only internally within your organization, and (b) to distribute the Software in binary
code form externally to end users (either directly or indirectly through resellers and distributors), solely for use on Cypress
hardware product units, and (2) under those claims of Cypress's patents that are infringed by the Software (as provided by
Cypress, unmodified) to make, use, distribute, and import the Software solely for use with Cypress hardware products. Any
other use, reproduction, modification, translation, or compilation of the Software is prohibited.
TO THE EXTENT PERMITTED BY APPLICABLE LAW, CYPRESS MAKES NO WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, WITH REGARD TO THIS DOCUMENT OR ANY SOFTWARE OR ACCOMPANYING HARDWARE, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. To the extent permitted by applicable law, Cypress reserves the right to make changes to this document without
further notice. Cypress does not assume any liability arising out of the application or use of any product or circuit described in
this document. Any information provided in this document, including any sample design information or programming code, is
provided only for reference purposes. It is the responsibility of the user of this document to properly design, program, and test
the functionality and safety of any application made of this information and any resulting product. Cypress products are not
designed, intended, or authorized for use as critical Components in systems designed or intended for the operation of
weapons, weapons systems, nuclear installations, life-support devices or systems, other medical devices or systems
(including resuscitation equipment and surgical implants), pollution control or hazardous substances management, or other
uses where the failure of the device or system could cause personal injury, death, or property damage ("Unintended Uses").
A critical Component is any Component of a device or system whose failure to perform can be reasonably expected to cause
the failure of the device or system, or to affect its safety or effectiveness. Cypress is not liable, in whole or in part, and you
shall and hereby do release Cypress from any claim, damage, or other liability arising from or related to all Unintended Uses
of Cypress products. You shall indemnify and hold Cypress harmless from and against all claims, costs, damages, and other
liabilities, including claims for personal injury or death, arising from or related to any Unintended Uses of Cypress products.
Cypress, the Cypress logo, Spansion, the Spansion logo, and combinations thereof, WICED, PSoC, CapSense, EZ-USB, F-
RAM, and Traveo are trademarks or registered trademarks of Cypress in the United States and other countries. For a more
complete list of Cypress trademarks, visit cypress.com. Other names and brands may be claimed as property of their
respective owners.
1. Introduction 9
1.1 What is a PSoC Creator Component?......................................................................................9
1.2 Component Interaction ...........................................................................................................10
1.3 Component Creation Process Overview.................................................................................11
1.4 Cypress Component Requirements........................................................................................11
1.4.1 File Names ..................................................................................................................11
1.4.2 Name Considerations..................................................................................................11
1.4.3 File Name Length Limitations......................................................................................11
1.4.4 Component Versioning................................................................................................12
1.5 Component Parameter Overview ...........................................................................................13
1.5.1 Formal versus Local Parameters ................................................................................13
1.5.2 Built-In Parameters .....................................................................................................15
1.5.2.1 Formals:.......................................................................................................15
1.5.2.2 Locals: .........................................................................................................16
1.5.3 Expression Functions..................................................................................................18
1.5.3.1 Device Information Functions ......................................................................18
1.5.3.2 Component Information Functions ..............................................................19
1.5.3.3 Misc. / Utility Functions................................................................................20
1.5.3.4 Deprecated Functions .................................................................................21
1.5.4 User-Defined Types ....................................................................................................22
1.6 References .............................................................................................................................22
1.7 Conventions Used in this Guide .............................................................................................22
1.8 Revision History......................................................................................................................23
4. Adding an Implementation 45
4.1 Implement with a Schematic...................................................................................................47
4.1.1 Add a Schematic.........................................................................................................47
4.1.2 Complete the Schematic.............................................................................................48
4.1.2.1 Design-Wide Resources (DWR) Settings....................................................48
4.2 Create a Schematic Macro .....................................................................................................48
4.2.1 Add a Schematic Macro Document ............................................................................49
4.2.2 Define the Macro ........................................................................................................49
4.2.3 Versioning ...................................................................................................................50
4.2.4 Component Update Tool .............................................................................................50
4.2.5 Macro File Naming Conventions.................................................................................51
4.2.5.1 Macro and Symbol with Same Name ..........................................................51
4.2.6 Document Properties ..................................................................................................51
4.2.6.1 Component Catalog Placement ..................................................................51
4.2.6.2 Summary Text .............................................................................................51
4.2.6.3 Hidden Property ..........................................................................................51
4.2.7 Macro Datasheets.......................................................................................................51
4.2.8 Post-Processing of the Macro.....................................................................................51
4.2.9 Example ......................................................................................................................52
4.3 Implement a UDB Component................................................................................................52
4.3.1 Introduction to UDB Hardware ....................................................................................52
4.3.1.1 UDB Overview.............................................................................................53
4.3.1.2 Datapath Operation .....................................................................................54
4.3.2 Implement with UDB Editor.........................................................................................57
4.3.3 Implement with Verilog................................................................................................57
4.3.3.1 Verilog File Requirements ...........................................................................57
4.3.3.2 Add a Verilog File ........................................................................................58
4.3.3.3 Complete the Verilog file .............................................................................59
4.3.4 UDB Elements ............................................................................................................59
4.3.4.1 Clock/Enable Specification..........................................................................59
4.3.4.2 Datapath(s)..................................................................................................60
4.3.4.3 Control Register ..........................................................................................65
4.3.4.4 Status Register............................................................................................66
4.3.4.5 Count7.........................................................................................................68
4.3.5 Fixed Blocks ...............................................................................................................69
4.3.6 Design-Wide Resources .............................................................................................69
4.3.7 When to use Cypress Provided Primitives instead of Logic .......................................69
4.3.8 Warp Features for Component Creation.....................................................................69
4.3.8.1 Generate Statements ..................................................................................69
4.4 Implement with Software ........................................................................................................71
4.5 Exclude a Component ............................................................................................................72
This guide provides instructions and information that will help you create Components for PSoC
Creator. Some of this guide is intended for advanced users to create sophisticated Components that
other users employ to interact with PSoC Creator. However, there are some basic principles in this
guide that will also benefit novice users who may wish to create their own Components.
The most common files that make up a Component include the following:
Symbol – A symbol contains the basic definition of a Component. It contains the top-level picture
shown in the PSoC Creator Component Catalog, as well as the parameter definitions. There can
be only one symbol in a Component.
Optional hardware implementation – This is typically either a schematic or a Verilog file or a
UDB editor file. Some Components have a <project>.cyprimitive file -- this is just a sentinel that
says the backend tools inherently know about it and there is no explicit implementation.
Schematic – A schematic defines how a Component has been implemented visually. A
schematic can be generic for any PSoC device, or it can be specific to a Family, Series and/or
Device.
Verilog – Verilog can be used to define the functionality of a Component implemented in
Verilog. There will only be one Verilog file in any given level of a Component. Verilog files
found at different levels of the Component, such as at a Family, Series and/or Device, may not
refer to each other.
Optional firmware – This is typically made of a C header, source files, or static libraries.
Assembly is also supported, but rarely used. The C header and source files are templates. They
can't be compiled directly by C compiler. They get processed by PSoC Creator and turned into
the generated source you see when building a design.
API – Application Programming Interface. APIs define how to interact with a Component using C
code. They can be generic for any PSoC device, or they can be specific to a Family, Series and/
or Device.
Optional C# customizer (.cs and .resx files) – There is help documentation available from the
Help menu that details the APIs the tool exposes to Components. It's effectively a plug-in
interface that lets Components customize certain default behaviors of the tool (like appearance,
how it netlists to Verilog, generating APIs on-the-fly, etc.).
Control File – The control file contains directives to the code generation module. For information
on how to add a control file, see Add Control File on page 84. For more information about control
files in general, refer to the Control File and Directives topics in the PSoC Creator Help.
Documentation – The documentation of the Component is generally its datasheet.
Note These chapters provide a logical grouping of related information and they present one, but not
the only, possible workflow process for creating Components. Refer also to Chapter 11 for various
best practices to follow when creating Components.
PSoC Creator supports Component versioning and patching. A version of the Component (major
and minor) is fully self-contained. Patching may be used rarely and only when it does not change
any actual content (perhaps just a document change).
Major version: major changes (e.g. API changes, Component symbol interface changes,
functionality changes etc.) that may break the compatibility
Minor version: No API changes. Bug fixes, additional features that do not break the compatibility
Patch: No API changes. Documentation, bug fixes to the existing functionality of the Component
that do not break the compatibility. Note that since patches are an aspect of the Component,
when the user installs an updated Component, they automatically get these changes.
The version number will be carried as part of the Component name by appending
"_v<major_num>_<minor_num>" to the Component name, where <major_num> and <minor_num>
are integers that specify the major and minor versions respectively. For example,
CyCounter8_v1_20 is version 1.20 of the CyCounter8 Component. Major and minor numbers are
each integers on their own and do not make up a "real number." For example, v1_1 is not the same
as v1_10 and v1_2 comes before v1_10.
The patch level will be an aspect of the Component (carried on the symbol) and hence is not
reflected in the Component name. Incorporating the version number as part of the Component name
will protect existing designs when there is a major change in the Component. Note that it is under the
control of the Component author to name the major and minor versions.
In a symbol, formal parameters have constant default values and local parameters may have
expressions with identifiers that refer to other parameters. The identifiers in the local parameter
expressions come from the combined set of formal and local parameters. In effect, the parameter set
is an evaluation context (for the local parameters).
Schematic documents have a parameter set. When open in the editor, the schematic has a
parameter set that is a direct copy of its symbol parameter set. This copy is made at run time and is
guaranteed to always stay in sync with the symbol. These parameters are not directly visible in
PSoC Creator, except by editing the symbol. If a schematic does not have a symbol, then it does not
have a parameter set.
An instance of a Component holds formal parameters from the Component’s symbol. The instance
creates a copy of its formal symbol parameters when it is dropped in a schematic. Users can change
the values of the formal parameters to expressions. Formal parameters on an instance may refer to
any parameters that exist on the schematic on which it was dropped. Formal parameters on an
instance may not refer to any of its other parameters. Formal parameters are the means by which
the user’s configuration values get propagated through the design hierarchy by Component
developers.
End users cannot change values of local parameters. The instance local parameters are evaluated
in the context of the instance. That means they can refer to any other parameter on the instance, but
may not refer to any parameters from the schematic on which it was dropped. See the Expression
Evaluator appendix on page 167 for more information on evaluation contexts and their use.
Instance parameters match-by-name with symbol parameters; type does not matter. An in-memory
instance has both an active parameter set and an orphan parameter. The active set are those
parameters contained in the symbol's parameter set. The orphan set are those parameters that had
been created for the instance, but the symbol changed, and those parameters are no longer valid
parameters. For example, this allows end users to change their library search path, switch to an
alternate implementation or version of a Component, and switch back to their original search path
without losing any data.
Orphan parameters are transient. Orphan parameters will become active if the associated symbol is
refreshed and now has formal parameters of those names. The elaborated schematic parameters
are just a direct copy of the instance parameters from the parent instance.
1.5.2.1 Formals:
Name Description
This is a special parameter. In the editor, it has the short name for the instance.
This is what the user edits when they want to rename an instance. In the
elaborated design, it provides access to the "full" or "hierarchical" instance
name. This is the name that should be used (via `$INSTANCE_NAME`) in API
files to ensure that there aren't any collisions). In other words, this name is
INSTANCE_NAME nearly always the one Component authors should refer to, and it will have an
appropriate value.
Note The INSTANCE_NAME parameter returns a different value when used in
the expression evaluator versus API and HDL generation. For the expression
evaluator, it returns the leaf name of the instance; when used for API and HDL
generation, it returns the path name of the instance.
CY_CONST_CONFIG Controls whether the configuration structure is stored in flash (const, true) or
SRAM (not const, false). Only visible for devices that support driver style APIs
(Config Data in Flash) (for example, FMx).
This parameter is a flag to the elaborator, which tells it to remove the instance
CY_REMOVE from the netlist. It works in conjunction with the live mux to allow Component
authors to dynamically switch between two different implementations of a
(Disable) Component in a single schematic. The default value is false (that is, keep the
instance around).
CY_SUPPRESS_API_GEN This parameter can be used to indicate that a particular instance should not
have an API generated for it (even though the Component has an API). The
(Suppress API Generation) default value is false.
Instance-specific comments. Component authors should include the comment
in generated source (.c file) as follows:
CY_COMMENT
/*
(User Comments)
`$CY_COMMENT`
*/
1.5.2.2 Locals:
Name Description
This parameter is used during the build process to check for the
existence of the cyapicallbacks.h file on disk in the project
directory.
CY_API_CALLBACK_HEADER_INCLUDE If the file exists, this parameter will expand to #include
"cyapicallbacks.h".
If the file does not exist, this parameter expands to an empty
string.
This parameter contains the file system path to the
Component's base directory (the directory where the symbol
CY_COMPONENT_NAME
exists). It is only valid after elaboration. Before elaboration this
parameter contains the value " UNELABORATED ".
This parameter allows Component authors to specify an
CY_CONFIG_TITLE alternate Component name to be displayed to the end-user in
the Component's Configure dialog title bar.
This parameter is used to specify a control file for the
Component instance. This is used internally to define fixed
placement characteristics for specific Components. The default
value (<:default:>) refers to the control file at the generic level
(that is,
CY_CONTROL_FILE
<ComponentName>.ctl), if one is used. This value should not
be changed.
For information about how to create and use a control file in a
design, refer to the “Control File” topic in the PSoC Creator
Help. See also Add Control File on page 84.
This parameter is used to specify all documentation files for the
Component instance. This includes the datasheet and all
supporting documents for a Component. The default value
(<:default:>) refers to the datasheet file (that is,
<ComponentName>.pdf). If there are multiple files associated
CY_DATASHEET_FILE with the Component, a list of documents can also be provided
using a semicolon separated string of filenames. For example:
<ComponentName>.pdf;document1.pdf;document2.html
Note The first document in the string ALWAYS must be the
datasheet. The file system paths for all documents are relative
to the Component’s base directory.
CY_FITTER_NAME Hierarchical name in fitter format.
If for some reason a Component author needs the short form of
the instance name even in the elaborated design, it can be
CY__INSTANCE_SHORT_NAME accessed via this parameter. End- users should NEVER see
this. It isn't editable. Its value is automatically updated whenever
the user modifies the INSTANCE_NAME parameter.
Name of the PDL driver that this Component generates code
CY_PDL_DRIVER_NAME
(e.g., initialization structures) for.
Required version of the driver this Component is compatible
with in the form Major.Minor.Patch. Major version number must
CY_PDL_DRIVER_REQ_VERSION
be an exact match for the PDL driver. Minor and Patch are
minimum versions within a major version.
Optional subgroup of the driver name. Corresponds to Pack
CY_PDL_DRIVER_SUBGROUP
cSub.
Name Description
Optional special variant of the driver name. Corresponds to
CY_PDL_DRIVER_VARIANT
Pack cVariant
This parameter displays version and build information for PSoC
CY_VERSION
Creator.
CY_MAJOR_VERSION This parameter contains the major version number for the
(Component Major Version) instance.
CY_MINOR_VERSION This parameter contains the minor version number for the
(Component Minor Version) instance.
You can make an expression that contains a function call. In order to use one of the functions in a
text label, use the format `=IsError()` for example. If you want to set a parameter value to the
result of one of these functions then just set the value to the function. Similarly, these functions can
be used in a validator expression. See also Add Parameter Validators on page 37.
1.6 References
This guide is one of a set of documents pertaining to PSoC Creator Component creation. Refer to
the following as needed:
PSoC Creator Help (Library Component Project and Basic Hierarchical Design topics, as well as
the Symbol Editor topics)
Cypress.com
KBA86338, Creating a Verilog-based Component
PSoC Creator Tutorial: Component Creation - Creating a Symbol
PSoC Creator Tutorial: Component Creation - Implementing with Verilog
Cypress Community Component Forum
PSoC Creator Universal Digital Block (UDB) Editor Guide
PSoC Creator Customization API Reference Guide
PSoC Creator Tuner API Reference Guide
PSoC Creator System Reference Guide
Device-specific Technical Reference Manual (TRM)
Warp™ Verilog Reference Guide
Convention Usage
Displays file locations and source code:
Courier New
C:\ …cd\icc\, user entered text
Displays file names and reference documentation:
Italics
sourcefile.hex
Displays keyboard commands in procedures:
[bracketed, bold]
[Enter] or [Ctrl] [C]
Represents menu paths:
File > New Project
File > New Project > Clone
Displays commands, menu paths and selections, and icon names in procedures:
Bold
Click the Debugger icon, and then click Next.
This chapter covers the basic steps to create a library project and add symbols using PSoC Creator.
To use the Components, add the project in which they are contained as a dependency in PSoC
Creator. See Add Dependency on page 109 for more information.
1. Click File > New > Project to open the New Project wizard.
3. Select one or more processors for which the library project will be built.
Note You cannot select the DP8051 processor and any of the Cortex processors, because they
are not compatible. An error will display.
4. If a workspace is already open, select Add to current workspace or Create new workspace.
Also, as desired, enter a Workspace Name and Project Name, and click the ellipsis (...) button
to specify the Location to store the project.
5. Click Finish.
The project displays in the Workspace Explorer under the Source tab.
This section will focus on creating a symbol as the first Component item. There are two methods to
create a symbol: an empty symbol and the symbol wizard.
Note You may also auto-generate a symbol from a schematic or Verilog, but this section will not
cover that process. Refer instead to the PSoC Creator Help for instructions.
The symbol displays in the Workspace Explorer tree, with a symbol file (.cysym) listed as the only
node.
The Symbol Editor also opens the <project_name>.cysym file, and you can draw or import a pic-
ture that represents the Component.
7. Draw basic shapes and terminals to define the symbol using the Symbol Editor. Refer to the
PSoC Creator Help for more information.
Note The plus sign (or cross-hairs) in the middle of the Symbol Editor canvas depicts the origin of
your symbol drawing.
8. Click File > Save All to save changes to your project and symbol file.
1. Follow the instructions for creating a Component as described in Create an Empty Symbol on
page 29.
2. Instead of choosing the Empty Symbol icon described in Step 4 on 30, choose the Symbol
Wizard icon.
After clicking Create New on the Add Component Item dialog, the Symbol Creation Wizard
displays.
3. Under Add New Terminals, enter the Name, and Type for the terminals you wish to place on the
symbol.
The Symbol Preview section will show a preview of how your symbol will appear on the Symbol
Editor canvas.
4. Use the Delete, Up, and Down buttons to move and delete terminals, as needed.
5. Optionally, choose a Title color and specify a Symbol label.
6. Click OK to close the Symbol Creation Wizard.
As with creating an empty symbol, the new Component displays in the Workspace Explorer tree,
with a symbol file (.cysym) listed as the only node. However, your Symbol Editor will display the
symbol created by the wizard, and it will be centered on the cross-hairs.
7. Make changes to your symbol drawing, as needed.
8. Click File > Save All to save changes to your project and symbol file.
This chapter covers the process to define various symbol information, such as parameters,
validators, and properties. For detailed information about symbol parameters, refer to Component
Parameter Overview on page 13.
2. Right-click on the canvas and select Symbol Parameters... to open the Parameters
Definition dialog.
3. To create one or more parameters for each symbol, click the Add button to open the Create
Parameter Definition dialog.
– Formal – These are how users configure a Component. They are inputs to the
Component from the user. They serve the same purpose as arguments to a C function.
Formals are normally visible and editable. They can be temporarily hidden and/or made
read only.
– Local – These are additional information required by the Component. They are
calculated from formals. They serve the same purpose as stack variables in a C function.
Locals are normally hidden, and are always read only. They can be made visible to show
useful derived information (e.g., like a baud rate).
Expr type – This is the expression type. Select the appropriate type from the pull-down menu.
Tab name – This is the name of the tab where the parameter will be located. Select a name
from the pull-down menu, if available, or type a name for a new tab.
Category – This is the category name under which this symbol displays in the Parameter
Editor dialog. This is a way to group parameters together.
When finished entering this information, click OK to close the Create Parameter Definition dialog.
4. Back on the Parameters Definition dialog, type a default Value for the parameter. If needed, click
on the Expression Editor button to open the Expression Editor to type more complicated
expressions.
Note The default parameter value only defines the value used when a Component is first
instantiated. The value is a snapshot at that time. If the default value for the Component is
subsequently changed, that value does not get propagated down to any previously instantiated
Component.
5. On the right side of the Parameters Definition dialog, define the following properties:
Category – This is the same as on the Create Parameter Definition dialog from Step 3. You
can change the category here, if needed.
Description – The description that displays to the end-user for this parameter in the instance
Configure dialog.
Display Name – The name to display for the parameter in the instance Configure dialog and
the instance tooltip. If not set, the parameter name will be used instead. This name should use
title-style capitalization. Use it to display a user-friendly name (instead of a legal identifier
name) to the user.
Display On Hover – An expression that specifies if the parameter value displays while
hovering the mouse over the instance in the Schematic Editor.
Read Only – An expression that specifies whether or not the parameter can be changed by
the end user.
– This will always be true for Locals.
– If a parameter is visible and there is nothing the user can do to make the value editable, a
Local should be used instead of a Formal.
– Only display (set Visible to true) a Formal if the user is expected to edit the value at some
point.
Scope – Specifies the scope in which the parameter is accessible (Formal or Local).
Sort Index – Overrides the default alphabetical ordering of the parameters. This will also
control the tab and category ordering. The tab/category containing the smallest sort index will
be presented first. Any parameter without a sort index specified will be sorted alphabetically
within their category after all parameters that do have an index provided.
Tab – Specifies the tab under which the parameter should be displayed on in the instance
Configure dialog.
Visible – An expression that specifies if the parameter should be visible in the instance
Configure dialog.
Hardware – If true, the parameter is included in the Verilog netlist generated during the
netlisting phase of the build process.
Check Range – When true, this will check that the parameter’s value after each evaluation is
in the range for the associated type. If out of range, PSoC Creator generates an expression
evaluation error. Valid ranges are as follows:
Validators – One or more validation expressions for the parameter. See Add Parameter
Validators on page 37 for how to use this field; see Expression Evaluator appendix on
page 167 for more information about CyExpressions.
6. When you are finished adding parameters, click OK to close the Parameters Definition dialog.
Note You can copy one or more parameter definitions by using the Copy/Paste buttons from the
toolbar. Also, multiple parameter properties can be changed at once by having multiple
parameters selected when changing the property.
2. In the Type file, select Error, Warning, or Info as the expression type.
3. In the Expression field, type in the validation check expression. You can reference parameter
names using the $ symbol. For example:
$param1 > 1 && $param < 16
($param1 == 8) || ($param1 == 16) || ($param1 == 24)
See Expression Evaluator appendix on page 167 for more information.
4. In the Message field, type in the message to display if the validation check is not met.
5. To add another validator, click in any field for an empty row marked with >*, and type in the fields
as appropriate.
6. To delete an expression, click the > symbol in the first column of the row to delete, and press the
[Delete] key.
7. To close the dialog, click OK.
2. Type a name in the bottom row of the Enum Set table (where it says 'Enter type name…').
3. In the Enum Item Name table (on the right), click in the empty row and type a name for the 1st
name/value pair of the enumerated type; type a value under Value or accept the default.
4. Optionally, enter a string in Display Name that will display in the Component's Configure dialog
pull down menu for that parameter.
5. Enter as many enum sets as needed and click OK to close the Enumeration Types dialog.
You can specify the following document properties for each Component, as applicable:
Symbol Properties
Doc.APIPrefix – Specifies a prefix that will be stripped on all API files in the Component
before generating the final user-visible file name during code generation.
For example, if you enter “Counter” as shown above for a counter Component, the generated
header file for a Component with instance name “Counter_1” will be Counter_1.h. If you enter
nothing in this property, the generated file would be Counter_1_Counter.h.
Note The APIPrefix is only applied to API files that are part of a project on disk. It is not
applied to API files generated by the API customizer.
Doc.CatalogPlacement – Defines how the Component will display in the Component
Catalog. See Define Catalog Placement on page 40.
Doc.CatalogVisibilityExpression – Used to enter an expression to show the symbol in the
Component Catalog. If this expression evaluates to 'false' and the "Show Hidden
Components" option (Tools > Options > Design Entry > Component Catalog) is not enabled,
the symbol (or schematic macro) will not be displayed in the Component Catalog.
Doc.CustomContextMenuItems – Used to add additional context menu items to open files,
such as an API Reference. See Add Custom Context Menu on page 41.
Doc.DefaultInstanceName – Defines the default instance name for Components. If left
blank, the instance name defaults to the Component name.
Doc.ExternalComponent – Specifies whether the symbol is an external Component: true or
false. See Create External Component on page 40. Note The label reads as “Annotation” due
to legacy issues.
Doc.SymbolSummary – Used to enter a brief description shown in the Component Catalog.
Doc.SymbolVisibleInCatalog – Specifies whether the Component displays in the
Component Catalog: true or false.
Doc.URL – Used to enter a complete web address or a file location on disk. If you enter a
valid value in this field, then various menu items become activated to allow a user to navigate
to the applicable web page, or open the specified file.
2. Then use an External terminal from the Design Elements Palette (DEP) to define the symbol
connections to off-chip resources.
An external Component will generate a DRC if it contains non-external content. The DRC will warn
that the content will not be implemented. Likewise, the use of digital or analog terminals in an
external Component will also generate a DRC. This DRC will warn that the terminal does not
connect to anything functional.
If you do not define catalog placement information, the symbol will display by default under Default >
Components.
1. Open the dialog by clicking the ellipsis button in the Doc.CatalogPlacement field in the
Properties dialog.
2. On the left side of the dialog, enter placement definition in the first row of the table, using the
following syntax:
t/x/x/x/x/d
t – The tab name. The tab order displayed in the Symbol Catalog is alphabetical and case
insensitive.
x – A node in the tree. You must have at least one node.
d – The display name for the symbol (optional). If you do not specify the display name, the
symbol name will be used instead; however, you must use the syntax: t/x/.
For example, in the default Component Catalog for the Component named “PGA,” the tab name
(t) is Cypress, the first node (x) is Analog, the second node (x) is Amplifiers, and the display
name (d) is PGA: Cypress/Analog/Amplifiers/PGA.
3. On the right side of the dialog, under Default Parameter Values, enter default parameter values
for this particular catalog placement definition, as needed.
Note The default parameter value only defines the value used when a Component is first
instantiated. The value is a snap shot at that time. If the default value for the Component is
subsequently changed, that value does not get propagated down to any previously instantiated
Component.
4. If desired, add more rows in the left side table to enter more than one catalog placement
definition; set the same or different default parameter values for each additional row.
5. Click OK to close the dialog.
2. Click the ellipsis button in the Doc.CustomContextMenuItems field to open the Custom Context
Menu Items dialog.
Arguments – Optional. Specifies arguments to use when the 'Open' path is executed.
Supports the following macro substitution: ${CyPdlPath}, ${CyPrjDirPath}.
Image – Optional. Specifies the image file path to be shown on the left side of the context
menu item.
You must place an image file in the same directory as the <project>.cysym file to enable the
drop-down list. Otherwise, you cannot specify an image file.
Visible – Expression to determine whether this context menu item will be shown or not.
Enabled – Expression to determine whether this context menu item will be enabled or not.
5. Click OK to close the Custom Context Menu Items dialog, and then click OK to close the
Properties dialog.
6. Place the Component in a design project schematic and right-click on the Component instance.
Note that the menu item is shown as specified.
To open this dialog, select one or more shapes and click the Format Shape button.
PSoC Creator allows you to create a Component using several design strategies for your specific
needs. Depending on the design goal of your particular application, the design strategy may vary
greatly between different implementation options. There are schematic implementations, schematic
macros, hardware implementations using the universal digital block (UDB) Editor, hardware
implementations using Verilog, and software implementations.
Schematic
The easiest and the most straight forward strategy to implement your Component is to use a
schematic (see Implement with a Schematic on page 47). A schematic allows you to place existing
Components on the design canvas much like any design. The design is then encapsulated into a
Component with its own input and output terminals with a unique function that can be used in other
designs. Use this method if you are using existing blocks to perform the new function.
This method does not allow you to work directly with the UDB elements and therefore limits the full
potential available in UDBs, such as datapaths and advanced programmable logic device (PLD)
features. If a separate UDB-based Component is available, then it can be used in a schematic-
based Component like any other available in the Component Catalog.
Schematic Macro
Similar to the schematic implementation, it is possible to create a schematic macro that contains a
design with pre-configured parameters and settings with several Components already linked
together. The schematic macro then becomes available in the Component Catalog and allows you to
use the pre-configured settings without worrying about the specifics of Component configurations. A
schematic macro is usually created for Component implementations that have complex
configurations. It is not normally used as a template for large designs with many Components on the
schematic. See Create a Schematic Macro on page 48 for details on implementing a schematic
macro.
UDB-Based Designs
For UDB-based designs, use the UDB Editor, or use Verilog and the Datapath Configuration Tool.
Both methods allow access to UDB elements. However your preference may differ depending on the
circumstances.
The UDB Editor is used to graphically describe the digital functions in UDBs. It does not require
you to know Verilog or have knowledge of the Datapath Configuration Tool. Therefore, it may be
an easier option than the Verilog method. The UDB Editor takes care of many internal
configuration details simply by specifying the parameters of the UDB blocks on the design
canvas. These graphical configurations are then used to generate Verilog code in real time and
can be used to observe how the blocks translate into code. However, the trade-off in using the
UDB editor is that some advanced features of the UDB are not supported with this method. Also
for users who know Verilog, it may be faster for them to use the Verilog method when designing
state-machines. Refer to the separate UDB Editor Guide available from the PSoC Creator Help
menu.
Implementing a UDB Component with Verilog is the most versatile but also the most complex and
is not recommended for beginners. Verilog allows you to design state machines that are more
refined than the UDB Editor. It may also be easier for users who are familiar with digital logic and
Verilog to use this method. To gain access to the datapath, you will also need to use the Datapath
Configuration Tool, which allows full functionality of the datapath. With this you will be able to use
the full potential of UDBs to create efficient and complex logic. See Implement with Verilog on
page 57.
Software
Implementations can also be just software. Implementing a Component with software means that no
hardware is used or referenced in the design. For instance, this method is used in Components that
act as an interface to link several codes together. See Implement with Software on page 71 for more
details.
Exclude
If your Component is intended to support only certain PSoC families, series, or devices, then it is
also possible to explicitly state that this Component is supported only for those specific parts. See
Exclude a Component on page 72 for more information on excluding Components.
Implementation Priority
Note that for implementations using hardware such as schematic, UDB Editor or Verilog, PSoC
Creator will use only one of these to make the Component and will ignore the rest. The priority of
these implementations is as follows.
1. Verilog – Has the highest priority. Creator ignores UDB Editor or schematics in the Component
workspace.
2. UDB Editor – Has higher priority than a schematic, but will be ignored if there is a Verilog file in
the Component workspace.
3. Schematic – Has the lowest priority and will be ignored if either a Verilog or UDB Editor file is in
the workspace.
In the Workspace Explorer tree, the schematic file (<project>.cysch) is listed in the appropriate
directory, depending on the device option specified.
The Schematic Editor opens the <project>.cysch file, and you can draw a diagram that represents
the Component connectivity at this time.
If you create a Component with a DWR, you can rename it at will with no consequence. The internal
ID is used to maintain the association.
If you delete a DWR from your Component, the system will fall back on using the hierarchical
instance name. If you then add a new DWR Component, and give it a different name, the
<project>.cydwr file will lose any settings the end user had associated with their DWR Component.
Schematic macros are typically created to simplify usage of the Components. Typical use cases of
the Components in schematics will be prepared and made available as macros. The end user will
use macros instead of using bare symbols.
In the Workspace Explorer, the schematic macro file (<project>.cymacro) is listed in the appropriate
directory, depending on the device option specified.
The Schematic Macro Editor opens the <project>.cymacro file. You can add Components, define
predefined settings such as a default clock frequency, and override default settings of each
Component, etc. You can also use macros to predefine I/O pin configurations necessary for a
communication interface or an analog Component, etc.
5. Right click in the schematic macro somewhere and select Properties from the drop down.
Change the Component catalog placement and summary to the desired settings.
6. Open the Timer symbol file, right click somewhere in the empty space and select Properties from
the drop down. Make the setting to Hide the Component from the Component catalog.
In a design project you will see the following:
7. Once you place this in your design, experiment with how you can delete the logic low or change
the clock or timer settings, etc.
4.2.3 Versioning
Since macros belong to a Component (see above) they are implicitly versioned through the
versioning of the Component. The macro name will not include the version number of the macro or
Component.
However, a schematic macro itself is defined as a schematic. That schematic may contain instances
of other Components that can be updated via the Component Update Tool. The macro definition
schematic is visible to the Component Update Tool and all appropriate updates are available.
Schematic macros will be listed in the Component catalog similar to the way symbols are displayed
in the catalog. If a macro display name is repeated in another Component, the macro is displayed
with an index in parenthesis to denote that there are more than one instances of the macro with the
same display name.
For each instance, terminal, and wire in the macro, PSoC Creator must assign a non-conflicting
name before adding it to the model. Each instance, terminal, and wire is added to the schematic
making sure that the HDL name being used for the item is currently not used in the schematic
already. The base names of the items will be suffixed with numbers and incremented until a unique
HDL name is available.
4.2.9 Example
Assume there is a macro with one instance (named “i2c_master”), three terminals (named “sclk,”
“sdata,” and “clk”) and three wires (wires are not named; their effective names are sclk, sdata, and
clk, respectively). If the schematic is empty and a macro is dropped on the schematic, the names of
the instances, terminals, and wires will be as follows:
Instance: i2c_master
Terminals: sclk, sdata, and clk
Wires: sclk, sdata, and clk
If the names are already used, then the suffix is incremented until a valid name is available.
UDBs are driven with a user clock and the bus clock. The bus clock reads from and writes to the
registers in the datapath and the control/status registers. These data words travel through the PHUB
system bus. The user clock drives the blocks in the UDB. Signals in a UDB can be routed to form a
hardware output in a Component or can be used to drive the inputs of the structured blocks in a
UDB.
PLD – These are most often used to create logic to control the other structured resources
available in a UDB. PLD based designs are composed of both combinational logic and sequential
logic. The sequential logic is driven with the user clock. Although PLDs are the most flexible
element in a UDB, it is also resource intensive. Therefore it is recommended to use the other
structured blocks as much as possible when implementing large designs.
Datapath – A datapath is an 8-bit wide processor that can be used to perform simple arithmetic
and bitwise operations on data words. It can be chained to form 16-, 24-, and 32-bit wide
processors. It can have up to 8 user defined instructions that are often driven using the PLD
implemented state machine. Datapaths form the core of many UDB designs and should be used
in preference over PLD designs when 8-bit words or larger are used. For more information on
using the datapath, see Datapath Operation on page 54.
Control Register – A control register is used in a UDB to communicate with the CPU. Using a
control register, it is possible for the CPU to directly send commands to the UDB hardware. The
reading and writing of the control register from the CPU is performed at the bus clock, unless it is
in sync or pulse mode with the user defined clock.
Status Register – A status register is used to notify the CPU on the status of the hardware signal
states. The rate at which the status register is read by the CPU is controlled using the bus clock
whereas the register is written by the UDB at the user clock. Status registers also have the ability
to generate maskable interrupts. This is accomplished by using one pin for the interrupt output
and the other 7 bits as the maskable triggers for the interrupt.
Count7 Counter – UDBs contain a 7-bit counter that can be used instead of a counter
implementation using PLDs or a datapath. This can save resources if the required counter bits
are between 4 and 7 bits. The terminal count of the counter can then be used throughout your
design.
The datapath allows for many different configurations that are common in almost every Component
that will be designed. Many functions within a datapath that can be implemented with Verilog fit into
the PLDs. However, the PLDs will be used up very quickly, whereas the datapath is a fixed block.
There will always be a trade-off between the number of datapaths and PLDs available. It is up to the
designer to decide which of these is a more precious resource. Note that some functions, such as
FIFOs, cannot be implemented in the PLDs.
Datapath Instructions
The datapath is broken into the following sections:
ALU – An ALU is capable of the following operations on 8-bit data. When multiple datapaths are
tied together to form 16, 24, and 32 bits, then the operations act on the full datawidth.
Pass-Through
Increment (INC)
Decrement (DEC)
Add (ADD)
Subtract (SUB)
XOR
AND
OR
Shift – The output of the ALU is passed to the shift operator, which is capable of the following
operations. When multiple datapaths are tied together to form 16, 24, and 32 bits, then the
operations act on the full datawidth.
Pass-Through
Shift Left
Shift Right
Nibble Swap
Mask – The output of the shift operator is passed to a mask operator, which is capable of
masking off any of the 8 bits of the datapath.
Registers – The datapath has the following registers available to the hardware and to the CPU
with various configuration options defined in the static configuration registers.
Two Accumulator Registers: ACC0 and ACC1
Two Data Registers: DATA0 and DATA1
Two 4-byte deep FIFOs: FIFO0 and FIFO1 capable of multiple modes of operation
Comparison Operators
Zero Detection: Z0 and Z1 which compare ACC0 and ACC1 to zero respectively and output
the binary true/false to the interconnect logic for use by the hardware as necessary.
FF Detection: FF0 and FF1 which compare ACC0 and ACC1 to 0xFF respectively and output
the binary true/false to the interconnect logic for use by the hardware as necessary.
Compare 0:
Compare equal (ce0) – Compare (ACC0 & Cmask0) is equal to DATA0 and output the binary
true/false to the interconnect logic for use by the hardware as necessary. (Cmask0 is configu-
rable in the static configuration.)
Compare Less Than (cl0) – Compare (ACC0 & Cmask0) is less than DATA0 and output the
binary true/false to the interconnect logic for use by the hardware as necessary. (Cmask0 is
configurable in the static configuration.)
Compare 1:
Compare equal (ce1) – Compare ((ACC0 or ACC1) & Cmask1) is equal to (DATA1 or ACC0)
and output the binary true/false to the interconnect logic for use by the hardware as neces-
sary. (Cmask1 is configurable in the static configuration)
Compare Less Than (cl1) – Compare (ACC0 & Cmask0) is less than DATA0 and output the
binary true/false to the interconnect logic for use by the hardware as necessary. (Cmask1 is
configurable in the static configuration)
Overflow Detection: Indicates the msb has overflowed by driving ov_msb output as a binary
true/false to the interconnect logic for use by the hardware as necessary.
Note Overflow is defined as the XOR of the carry into the MSB and the carry out of the MSB.
The computation is done on the currently defined MSB as specified by the MSB_SEL bits.
This condition is not chainable; however, the computation is valid when done in the most sig-
nificant Datapath of a multi-precision function, as long as the carry is chained between blocks.
ov_msb works fine in all cases except when DPATH_CFG3.MSB_SEL=0 (and MSB_EN=1);
that is, except when there is only 1 data bit being used in this datapath. What is supposed to
happen in that case is CI should be selected as "Carry(msb-1)”. However, PSoC 6 MCUs
instead roll under the "MSB-1" selection and end up grabbing the ALU's carry-out bit 7
(alu_co[7]).
A possible software workaround would be to avoid performing ov_msb on values that are of
size (N*8)+1 and instead simply allow the value to be 1 bit larger: (N*8)+2. If, however, the
overflow must be performed on (N*8)+1 bits worth of data, then another possibility is to multi-
ply the (N*8)+1 value by 2 (by shifting a zero in from the right) to create a temporary value that
is now 10 bits, which can then be used to safely check the ov_msb.
Datapath Registers
Each datapath contains 6 registers - A0, A1, D0, D1, F0 and F1. These serve different functions with
certain restrictions, and can be used in a variety of ways to form your design.
Accumulator registers A0 and A1 are often used like RAM to hold temporary values entering and
coming out of the ALU. These are the most versatile registers and are also the most accessed.
Data registers D0 and D1 are not as versatile as the accumulator registers. They can be written
by the datapath only from the FIFO and by consuming an extra d0_load or d1_load input signal.
For this reason it is often used like ROM in the design.
4-word deep FIFOs F0 and F1 are often used as the input and output buffers for the datapath.
These cannot directly source the ALU and the value in the FIFO must be loaded in to the
accumulator register before it can be used by the ALU. See FIFO Modes on page 56 for more
details on the FIFO configurations.
Datapath Inputs/Output
A datapath, regardless of data width can contain up to 6 input bits. Of the 6 input bits, up to 3 bits can
be used to control the datapath instructions for that clock cycle. Therefore 8 unique datapath
instructions can be used in the design. Each of these instructions can perform multiple operations in
the same clock cycle, which can further optimize performance.
Similarly, a datapath can contain up to 6 outputs regardless of the data width. These outputs are
used to send status signals from the datapath to either a status register or to other blocks in the
design such as the state machine or the count7 counter. These status signals are generated from
comparisons and internal logic in the datapath and do not include data bits directly from the registers
or the ALU. It is possible however to access this information by using the shifter to serially shift out
the bits in the ALU.
FIFO Modes
The 4-word deep FIFOs in datapaths can be configured to several modes using an auxiliary control
register. This register is used by the CPU/DMA to dynamically control the interrupt, counter, and
FIFO operations. Refer to the TRM for more information about the auxiliary control register.
The data transfers to and from the FIFO are often controlled using the FIFO bus and block status
signals. These are FIFO 0/1 block status (f0_block_stat, f1_block_stat), and FIFO 0/1 bus status
(f0_bus_stat, f1_bus_stat) signals. The behaviors of these are dependent on the input/output mode
and the auxiliary control register settings. The following table shows the possible configurations.
Note This is for illustrative purposes only. For more detail descriptions on the FIFO configuration,
refer to the TRM.
Level mode can be configured by setting the FIFO level mode of the auxiliary control register to
either NORMAL or MID.
NORMAL FIFO level - A NORMAL FIFO level allows the bus status signal to assert whenever
there is at least 1 word that is ready to be read or written (depending on the FIFO direction).
MID FIFO level - A MID FIFO level allows the bus status signal to assert whenever there are at
least 2 words that are ready to be read or written (depending on the FIFO direction).
Note Any primitive embedded in Verilog will not have an API automatically generated for it. The
appropriate #define values will be created, but for example a cy_psoc3_control embedded in Verilog
will not cause APIs to be generated that are normally produced when a Control Register symbol is
placed on a schematic.
The name of the Component created with a symbol in PSoC Creator must match exactly the name
of the module defined in the Verilog file. PSoC Creator also creates the Verilog file with the same
name as the Component. As a designer you are required to use this same name as your module
name.
For example, a “ModuleName” Component created in PSoC Creator will generate a ModuleName.v
file for you to develop the digital content. The top module in that file must be a “ModuleName” (case
sensitive) for it to be built correctly in PSoC Creator.
In the following example, the text entered in the Component name text box (“ModuleName”) must
match the module name used in the Verilog file [“module ModuleName(….)”].
You must think of the naming convention you want to follow when you create the symbol to start off
the process as shown in the example above.
A file has been provided by Cypress that contains all of the constants expected in a Component
Verilog file. These constants are available in the cypress.v file. This file is contained in the search
path for all Verilog compilations in PSoC Creator. All Verilog files will use the cypress.v file and
therefore must have this line before the module declaration:
`include “cypress.v”
New File
If you do not have an existing Verilog file, you can use the Generate Verilog tool , which will
create a basic Verilog file with the appropriate file name, ‘include “cypress.v”, and basic
module information based on how you have defined the symbol.
Existing File
If you have an existing Verilog file, you can add it as a Component item.
1. Right click on the Component and select Add Component Item.
The Add Component Item dialog displays.
2. Select the Verilog icon.
Note The Verilog file will inherit the Component name. See Verilog File Requirements on
page 57.
3. If necessary, toggle the Create New button to Add Existing.
4. Click the ellipsis button [...], navigate to the location of the file, and click Open.
5. Click Add Existing.
The Verilog file is added to the Workspace Explorer with the appropriate file name.
Note The Verilog implementation's module name must match its Component name; it is case
sensitive.
For UDB-based PSoC devices, the Verilog implementation allows for Verilog2005 design and will
compile into the PLDs available in the architecture. However. there are several other modules
available which are optimized functions to prevent usage of the precious PLD resources. These
modules and their use are listed in the next few sections.
Note Many references in this guide and in the Component names specify “psoc3.” These references
apply to all UDB-based PSoC devices, including PSoC 3 and PSoC 5LP.
cy_psoc3_udb_clock_enable_v1_0
This primitive allows for the specification of the clock characteristics for the UDB Components being
driven by its output. The output from the element can only drive UDB elements. Any other
Component will result in a DRC error in the fitter. The element has one parameter:
sync_mode : A boolean parameter that designates whether the resulting clock should be
synchronous (true) or asynchronous (false). The default is synchronous.
If the signal source is a combinational macrocell, PSoC Creator will follow each of the macrocell's
input signals using the same rules. If the inputs have the same clock source, that signal will be used.
Otherwise, the search is inconclusive.
If the search finds a clock that is not identical to the original clock signal, PSoC Creator will replace
the clock with the source signal and use the original clock signal as a clock enable. Otherwise, the
original signal will be used as the clock.
4.3.4.2 Datapath(s)
To Instantiate a datapath or multiple consecutive datapaths in your design, use one of the following
module instantiations within your Verilog module.
cy_psoc3_dp
This is the base datapath element available. There are several other elements which build on this
base element and they should be used before this element is chosen, because all I/Os available on
this element are listed in the instantiation. However, there are several limitations because of the
architecture of UDBs in UDB-based PSoC devices, such that many of these signals have a limited
number of wires in your design to which they can connect. It would be wise to always use the
cy_psoc3_dp8 module when a single datapath is necessary.
Each datapath has several parameters that can be passed as named parameters to the module
itself. The Datapath Configuration Tool should be the method used to implement the parameters in
the Verilog file for all datapaths. This tool will read a Verilog file, display all of the datapaths, and save
the correct information back to the Verilog file for use by the compiler (Warp).
cy_psoc3_dp8
This is a single 8-bit wide datapath element.
This element has the same parameters for each datapath as the base datapath element. All
parameters are appended with “_a” to indicate the LSB datapath (X=a for LSB datapath in the
following list).
cy_dpconfig_X,: the configuration for the datapath which includes the dynamic and static
configurations. Default value is {128’h0,32’hFF00FFFF, 48’h0}
cy_psoc3_dp16
This is two 8-bit wide datapath elements set up to be two consecutive datapaths for a 16-bit wide
module. ALU, Shift, and Mask operations operate on the full 16-bit width of the data by having direct
connections of the carry, shift-in, shift-out, and feedback signals between the individual datapaths.
This element has the same parameters for each datapath as the base datapath element. All
parameters are appended with “_a” to indicate the LSB datapath and “_b” to indicate the MSB of the
two datapaths (X=a for LSB datapath and X=b for MSB datapath in the following list).
cy_dpconfig_X,: the configuration for the datapath which includes the dynamic and static
configurations. Default value is {128’h0,32’hFF00FFFF, 48’h0}
d0_init_X: Initialization value for DATA0 Registers. Default value is 8’b0
d1_init_X: Initialization value for DATA1 Registers. Default value is 8’b0
a0_init_X: Initialization value for ACC0 Registers. Default value is 8’b0
a1_init_X: Initialization value for ACC1 Registers. Default value is 8’b0
cy_psoc3_dp24
This is three 8-bit wide datapath elements set up to be three consecutive datapaths for a 24-bit wide
module. ALU, Shift, and Mask operations operate on the full 24-bit width of the data by having direct
connections of the carry, shift-in, shift-out, and feedback signals between the individual datapaths.
This element has the same parameters for each datapath as the base datapath element. All
parameters are appended with “_a” to indicate the LSB datapath, “_b” to indicate the middle
datapath, and “_c” to indicate the MSB datapath of the three datapaths (X=a for LSB datapath, X=b
for the middle datapath, and X=c for MSB datapath in the following list).
cy_dpconfig_X,: the configuration for the datapath which includes the dynamic and static
configurations. Default value is {128’h0,32’hFF00FFFF, 48’h0}
d0_init_X: Initialization value for DATA0 Registers. Default value is 8’b0
d1_init_X: Initialization value for DATA1 Registers. Default value is 8’b0
a0_init_X: Initialization value for ACC0 Registers. Default value is 8’b0
a1_init_X: Initialization value for ACC1 Registers. Default value is 8’b0
cy_psoc3_dp32
This element is four 8-bit wide datapath elements set up to be four consecutive datapaths for a 32-bit
wide module. ALU, Shift, and Mask operations operate on the full 32-bit width of the data by having
direct connections of the carry, shift-in, shift-out, and feedback signals between the individual
datapaths.
This element has the same parameters for each datapath as the base datapath element. All
parameters are appended with “_a” to indicate the LSB datapath, “_b” to indicate the lower middle
datapath, “_c” to indicate the upper middle datapath, and “_d” to indicate the MSB datapath of the
four datapaths (X=a for LSB datapath, X=b for the lower middle datapath, X=c for the upper middle
datapath, and X=d for MSB datapath in the following list).
cy_dpconfig_X,: the configuration for the datapath which includes the dynamic and static
configurations. Default value is {128’h0,32’hFF00FFFF, 48’h0}
d0_init_X: Initialization value for DATA0 Registers. Default value is 8’b0
d1_init_X: Initialization value for DATA1 Registers. Default value is 8’b0
a0_init_X: Initialization value for ACC0 Registers. Default value is 8’b0
a1_init_X: Initialization value for ACC1 Registers. Default value is 8’b0
To instantiate a control register in your design, use the following element instantiation within your
Verilog code.
cy_psoc3_control
This 8-bit control register has the following available parameters, as follows:
cy_force_order: A Boolean used by the compiler to improve ability of the router if order of the bits
within the register is not required. The default value is False. Typically the order is important and
this should be set to TRUE.
cy_init_value: The initial value for the register to be loaded during chip configuration.
cy_ctrl_mode_1, cy_ctrl_mode_0 (PSoC 3 ES3 Only): These two parameters are optional.
Together they control which of the three modes of operation are to be used for each bit of the
control register. Refer to the TRM for details about each of the modes:
To instantiate a status register in your design, use one of the following module instantiations within
your Verilog code.
cy_psoc3_status
This is an 8-bit status register. The element has the following available parameters. These should be
passed as named parameters as shown in the example instantiation:
cy_force_order: A Boolean used by the compiler to improve ability of the router if order of the bits
within the register is not required. The default value is False. Typically the order is important and
this should be set to TRUE.
cy_md_select: A mode definition for each of the bits in the register. The bits represent transparent
or sticky. The default value is transparent for each bit.
cy_psoc3_statusi
This module is a 7-bit status register with an interrupt output based on those 7 status bits.
For the statusi register, there is a hardware enable and a software enable. Both enables must be
enabled to generate an interrupt. The software enable is in the Aux Control register. Note that
multiple bits in the Aux Control register can be for different Components, so an interrupt safe
implementation should be done using Critical Region APIs. See the following for an example
#define MYSTATUSI_AUX_CTL (* (reg8 *) MyInstance__STATUS_AUX_CTL_REG)
uint8 interruptState;
The module has the following parameters which should be passed as named parameters as shown
in the example instantiation:
cy_force_order: A Boolean used by the compiler to improve ability of the router if order of the bits
within the register is not required. The default value is False. Typically the order is important and
this should be set to TRUE.
cy_md_select: A mode definition for each of the bits in the register. The bits represent transparent
or sticky. The default value is transparent for each bit.
cy_int_mask: A mask register to select which bits are included in the generation of any of the 7
bits of the register. The default value is 0, which disables all 7 bits as interrupt generators.
4.3.4.5 Count7
A simple 7-bit counter is available to avoid using up a whole 8-bit datapath or multiple PLDs to
implement the same. This element uses other resources within the architecture to avoid using up the
more precious PLD and datapaths. If your counter is between 3 and 7 bits then this module will save
PLD or datapath resources. An example of where this counter is useful is as a bit counter for
communication interfaces where you need a 4-bit counter which would tie up one whole datapath or
one whole 4-macrocell PLD.
For the count7 counter, there is a hardware enable and a software enable. Both enables must be
enabled to get the count7 counter to count. The software enable is in the Aux Control register. Note
that multiple bits in the Aux Control register can be for different Components, so an interrupt safe
implementation should be done using Critical Region APIs. See the following for an example:
#define MYCOUNT7_AUX_CTL (* (reg8 *) MyInstance__CONTROL_AUX_CTL_REG)
uint8 interruptState;
cy_psoc3_count7
This element has the following available parameters which should be passed as named parameters
as shown in the example instantiation:
cy_period: A 7-bit period value. Default value is 7’b1111111.
cy_route_ld: A Boolean to enable a routed signal as a load signal to the counter. If false terminal
count reloads the counter with the period value passed as a parameter, if true either terminal
count or the load signal will load the counter. Default is `FALSE.
cy_route_en: A Boolean to enable a routed signal as an enable to the counter. If false then the
counter is always enabled, if true then the counter is only enabled while the enable input is high.
Default is `FALSE.
Where reg_name is the name of a register in the block as listed in the TRM, such as the CR1
register of the DSM. The value after the = is expected to be the hexadecimal value to be assigned to
the register (the leading 0x is optional, but the value is always interpreted as hexadecimal). In the
case where a register listed is one that is also configured by the fitter, the value listed in the
parameter will take precedence.
Note It is important to remember scope when trying to define nets inside of a generate statement.
Note Generate statements add a layer to the naming convention passed to the API (in the generated
cyfitter.h file) from the datapaths and control and status registers. If you use a generate statement
with a “begin : GenerateSlice” statement then the Components are now pushed down one level in
their naming. For example a datapath named “DatapathName” that is not inside of a generate
statement will have the following variables defined in the cyfitter.h file.
#define ‘$INSTANCE_NAME_DatapathName_u0_A0_REG 0
#define ‘$INSTANCE_NAME_DatapathName_u0_A1_REG 0
#define ‘$INSTANCE_NAME_DatapathName_u0_D0_REG 0
#define ‘$INSTANCE_NAME_DatapathName_u0_D1_REG 0
But if that same datapath is inside of the “GenerateSlice” generate statement the same variables will
be defined in cyfitter.h as
#define ‘$INSTANCE_NAME_GenerateSlice_DatapathName_u0_A0_REG 0
#define ‘$INSTANCE_NAME_GenerateSlice_DatapathName_u0_A1_REG 0
#define ‘$INSTANCE_NAME_GenerateSlice_DatapathName_u0_D0_REG 0
#define ‘$INSTANCE_NAME_GenerateSlice_DatapathName_u0_D1_REG 0
Parameter Usage
Parameters are allowed in the right hand side of a parameter assignment. This is critical for
Component development particularly when assigning the datapath configuration information. For
example, the SPI Component requires the ability to set the number of data-bits dynamically at build
time. The MSB value bit-field of the datapath’s configuration requires a different value based on the
data-width of the SPI transfer. A parameter called MSBVal can be defined which is assigned based
on the existing parameter NumBits which defines the transfer size of the block. The method to do
this is provided in the datapath configuration tool. For datapath configuration you should not be
hand-editing the parameters passed to a datapath. But you may use this method in any other
parameter definitions at your discretion.
Defparam usage is very error prone so Warp has added the support of named parameter passing.
This is used extensively as shown in the standard modules defined in previous sections. Named
parameters are passed at the instance declaration time within the #(…) block as shown in the
following example:
cy_psoc3_status #(.cy_force_order(`TRUE)) StatusReg (
. . . status register isntantiation
You can and should also protect your parameters with local parameters as much as possible. In the
example above for SPI, MSBVal should be defined as a local parameter because it is set based on
the parameter NumBits. It cannot be set by the user at a higher level. The code for this example
would look like the following:
module SPI(...)
parameter NumBits = 5'd8;
localparam MSBVal = (NumBits == 8 || NumBits == 16) ? 5'd8 :
(NumBits == 7 || NumBits == 15) ? 5'd7 :
(NumBits == 6 || NumBits == 14) ? 5'd6 :
(NumBits == 5 || NumBits == 13) ? 5'd5 :
(NumBits == 4 || NumBits == 12) ? 5'd4 :
(NumBits == 3 || NumBits == 11) ? 5'd3 :
(NumBits == 2 || NumBits == 10) ? 5'd2 :
(NumBits == 9) ? 5'd1;
endmodule
One example of a software only Component might be an interface that links the code of several
Components.
Note A specific implementation will override the exclude file. For example, if you exclude an entire
family, but create an implementation for a specific series or device, the Component will be available
for that family or device.
2. Scroll down to the Misc section and select the Exclude File icon.
3. De-select the Target generic device to specify the Family, Series, and/or Device using the drop
down menus, or leave the check box selected to allow the Component to apply to all devices.
4. Click Create New.
In the Workspace Explorer, the exclude is listed in the appropriate directory, depending on the
Target option specified.
When you finish this Component and try to use it in a design, select the appropriate family, series,
and/or device for which you added the exclude file, and verify that the Component is not available.
Cypress provides functional simulation models with PSoC Creator for Component developers to
simulate and debug their designs. This chapter provides a how-to-guide to help you understand how
CPU accesses (reads and writes) to various elements should be done.
The lpm.v file is used to define certain values for the parameters used by the Library of
Parameterized Modules (LPM) in the library. The rtl.v file is used to define various primitives used by
the synthesis engine to map to the internal architecture of the targeted devices.
Also included in this directory is the cypress.v file, which links the design to the appropriate PSoC
models. When using these models for synthesis, the following lines must be present in the user’s
source design:
‘include “cypress.v” //to use the PSoC-specific modules
‘include “lpm.v” //to use the LPM modules
‘include “rtl.v” //to use the RTL modules in the user’s design
or
+incdir+$CYPRESS_DIR/lib/sim/presynth/vlg
The latter example is valid since the Verilog source files are also mirrored at $CYPRESS_DIR/lib/
sim/presynth/vlg for convenience and compatibility with the Verilog pre-synthesis file structure.
Typically, the invocation of a Verilog simulator that utilizes these collections of modules would be:
vlog +incdir+$CYPRESS_DIR/lib/common <test bench>.v <testfile>.v
You must use the appropriate ‘include clause to access the desired modules.
The device model contains elements that must be clocked, written, and/or read. Provisions were
made in the device models to help with the manipulation of the elements by providing internal signals
(CPU clock) and tasks (read/write) associated with the various elements. The following sections
discuss this functionality and provide several examples.
If a design contains more than one control register, status register, or datapath, the clock generator
block should contain several assignment statements (such as the following examples).
ela.matcher.pattern_matcher.cpu_clock = CPUClock;
ela.compress.compressor.cpu_clock = CPUClock;
ela.trigger.PosEdgeReg.cpu_clock = CPUClock;
ela.trigger.NegEdgeReg.cpu_clock = CPUClock;
ela.ELAControl.cpu_clock = CPUClock;
These tasks are used to read and write the various registers in their respective Component models.
Each call to any one of these tasks involves a single argument.
For the write tasks, that argument is the 8-bit data that is to be written to the register.
For the read tasks, the 8-bit register data will be retuned and assigned to that argument.
initial
begin
ela.trigger.PosEdgeReg.control_write(POS_EDGE);
ela.trigger.NegEdgeReg.control_write(NEG_EDGE);
end
This chapter covers the process of adding application programming interface (API) files and code to
a Component, as well as different aspects such as API generation and template expansion.
If there is a top-level Counter Component called foo, then files foo_Counter.c, foo_Counter.h, and
foo_CounterINT.c are generated. If there is a lower-level Counter instance called bar_1_foo, then
files bar_1_foo_Counter.c, bar_1_foo_Counter.h, and bar_1_foo_CounterINT.c are generated.
Either syntax is valid, and both expand to provide the specified parameter value. For example:
void `$INSTANCE_NAME`_Start(void);
For a Counter instance named foo_1, this code snippet would expand to:
void foo_1_counter_Start(void);
Each of those directives results in a sequence of #define statements. For types local to the instance,
the expanded name takes the form:
<path_to_instance>_<keyname>
Note that the instance name is followed by a single underbar (as in the rest of the API), but the
Component name, if used, is followed by a DOUBLE UNDERBAR (as it is in the rest of the system).
This means that locally defined key values should not conflict with register names.
Example
Component: Fox
Type: Color (RED=1, WHITE=2, BLUE=3)
Also Uses: Rabbit__Species
Component: Rabbit
Type: Species (JACK=1, COTTON=2, JACKALOPE=3, WHITE=4)
A design contains a schematic that contains one instance of Fox named bob. In the API file for bob,
the following lines:
‘#declare_enum Color‘
‘#declare_enum Rabbit_Species‘
expand to:
#define path_to_bob_RED 1
#define path_to_bob_WHITE 2
#define path_to_bob_BLUE 3
#define path_to_bob_Rabbit__JACK 1
#define path_to_bob_Rabbit__COTTON 2
#define path_to_bob_Rabbit__JACKALOPE 3
#define path_to_bob_Rabbit__WHITE 4
expands to:
#define path_to_bob_RED 1
#define path_to_bob_WHITE 2
#define path_to_bob_BLUE 3
#define path_to_bob_Rabbit__JACK 1
#define path_to_bob_Rabbit__COTTON 2
#define path_to_bob_Rabbit__JACKALOPE 3
#define path_to_bob_Rabbit__WHITE 4
will be generated in cyfitter.h to allow the Component API to be conditionally compiled into the
design. In addition, any code that uses the APIs of the removed Component would need to be
constructed to take advantage of the #define so the removed Component would not be accessed.
To use the macro callback, it needs to be defined in a user-defined header file named
cyapiallbacks.h. This file will be included in all generated source files that offer callbacks through the
local built-in parameter named:
CY_API_CALLBACK_HEADER_INCLUDE
Components should not directly #include cyapicallbacks.h. Instead they should do the following:
`=GetApiCallbackHeaderInclude()`
This ensures backward compatibility with older PSoC Creator projects (that don't have
cyapicallbacks.h), and ensures the firmware still builds if the user chooses to remove the
cyapicallbacks.h header file.
To complete the example, the cyapiallbacks.h file would include this code:
#define SimpleComp_1_START_CALLBACK
void SimpleComp_1_Start_Callback( void );
In any other user file, the user would write the SimpleComp_1_Start_Callback() function.
6.1.6.3 Inlining
The function declaration could be added to the Component source, which would save the user from
having to write the prototype (one line per function). However, by reducing the Component code to
just the call, the user is free to modify the declaration. This is most obviously beneficial with inlining.
Different compilers implement inlining with different syntaxes but they all (that we support) do it on
the function declaration/implementation, and not the call. By extracting the declaration/
implementation from the content code the user has full control over inlining, regardless of the
compiler used.
Anything an end-user places in this region will be preserved in subsequent updates of the file. If a
subsequent version of the file does not contain the same named region, the entire region from the
previous file will be copied to the end of the file and placed in comments.
user edits the design-entry document for a family, only the primitives that are applicable for that
particular family are available for placement into a schematic.
An API exists but no schematic is provided
In this case, the Component does not re-use existing Components and presents an API for use.
This may occur for software-only Components that do not employ other Components.
Both a schematic and an API are provided.
This is a typical Component with an API and one or more primitives and/or other Components
included in the design. When the schematic includes other instantiated Components that have
their own APIs, the code generation process for a top-level design is somewhat complicated. For
example, consider construction of a Count32 Component from two Count16 Components, with
instance names u1 and u2 in the Count32 generic schematic. When the Count32 Component is
instantiated in a top-level design, the code generation mechanism must be aware of the hierarchy
when generating the APIs.
In this case, the creator of the Count32 Component would need to use u1’s API in the template
code as ‘$INSTANCE_NAME``[u1]`Init().
Note that if the Count16 Component was composed of Count8 Components, for example, with
identical substructure, then their instance names during code generation are hierarchical in
nature as well.
Neither a schematic nor an API is provided.
This is an invalid configuration except for Components of type “primitive.”
When the header is generated, there are a few naming conventions used. For working registers
(status, control, period, mask, etc.) the full instance name will be used (including any hierarchy) with
a specified string appended (as shown in the following table):
This chapter covers the various steps involved with finishing the Component, including:
Add/Create Datasheet
Add Control File
Add/Create Debug XML File
Add/Create DMA Capability File
Add/Create .cystate XML File
Add Static Library
Add Dependency
Build the project
2. Select the Document Files icon under the Misc category from the templates, and type the name
of the PDF file to add in Item name.
Note This process applies to any number of miscellaneous files you wish to add to the
Component. Click on a different template icon to add a different file type.
3. Click Create New to allow PSoC Creator to create a dummy file; select Add Existing from the
pull-down to select an existing file to add to the Component.
The item displays in the Workspace Explorer and opens outside of PSoC Creator.
4. If applicable, copy any updates over the file included with the project.
2. Select the Control File icon under the Misc category from the templates. The name will be the
same as the Component.
3. Click Create New to allow PSoC Creator to create an empty file; select Add Existing from the
pull-down to select an existing file to add to the Component.
The item displays in the Workspace Explorer and opens as tabbed document in the work area.
When the user enables the feature from the Component Configure dialog, the Component instance
will be forced into the specified resources. Multiple instances are not allowed to use this feature and
attempts to do so will generate an error.
3. Click Add Existing to select an existing file to add to the Component; select Create New to allow
PSoC Creator to create a dummy file.
The item displays in the Workspace Explorer and opens as a tabbed document in the PSoC Creator
Code Editor.
Like other files in the Component, debug XML files are able to use template expansion (see
Section 6.1.3) to evaluate parameters at build time. Additionally, addresses can be either the actual
address, or a #define from cydevice.h, cydevice_trm.h, or cyfitter.h.
Note The names of items in the XML documents cannot contain spaces.
Block
The <block> field is used to wrap related registers/memories in a single block. A block can be a
Component instance, a portion of the Component such as UDBs, sub-Components, or an abstract
collection of similar registers or memories. A block must always have a unique name within a
hierarchy. It can optionally provide a description and a block visibility expression.
Memory
The <memory> field represents a contiguous section of memory used by the Component. The
memory section needs a unique name, the starting address of the memory, and the size of that
memory. A <memory> must be placed within a <block>.
Register
The <register> field is used to represent a register used internally by the Component. A <register>
must be placed within a <block>.
Field
The <field> is used to define a portion of a register that has a specific meaning. It is a sub-item of
<register> and should not be used outside of it. The definition allows meaning to be placed for the
specific portions of the register when viewed from the Component debug window.
Value
The <value> is used to define a specific value that has meaning to a register field. It is a sub-item of
<field>. A value is an optional helper definition that shows up in the tool tip when a <register> with a
<field> and a <value> is opened in the Component debug window. The definition allows quick
viewing of what values of the specific field mean.
Note Addresses shown in this example are not actual addresses; they are used here only as a
demonstration.
<?xml version="1.0" encoding="us-ascii"?>
<deviceData version="1"
xmlns="http://cypress.com/xsd/cydevicedata"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://cypress.com/xsd/cydevicedata cydevicedata.xsd">
For additional examples, look at the Components shipped with PSoC Creator (e.g., I2C). These are
located in the following directory of your PSoC Creator installation:
<install location>\PSoC Creator\<Version#>\PSoC Creator\psoc\content
<deviceData version="1"
xmlns="http://cypress.com/xsd/cydevicedata"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://cypress.com/xsd/cydevicedata
cydevicedata.xsd">
<deviceData version="1"
xmlns="http://cypress.com/xsd/cydevicedata"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://cypress.com/xsd/cydevicedata cydevicedata.xsd">
</block>
</deviceData>
For the address field, the Component uses the Cypress template substitution mechanism to allow
this to work for any Component name, as well as the ability to look up any value defined in
cydevice_trm.h or cyfitter.h. In this case, it used a define from cyfitter.h which allows it to function
independent of where the tool ended up placing the timer.
…
<block name="`$INSTANCE_NAME`_CONTROL3" desc=""
visible="`$CONTROL3`">
<!-- UDB Parameter Specific Registers -->
<register name=""
address="`$INSTANCE_NAME`_TimerHW__CFG2" bitWidth="8"
desc="TMRx.CFG2">
<field name="TMR_CFG" from="1" to="0" access="RW"
desc="Timer configuration (MODE = 0): 000 = Continuous; 001 =
Pulsewidth; 010 = Period; 011 = Stop on IRQ">
<value name="Continuous" value="0" desc="Timer runs
while EN bit of CFG0 register is set to '1'." />
<value name="Pulsewidth" value="1" desc="Timer runs from
positive to negative edge of TIMEREN." />
<value name="Period" value="10" desc="Timer runs from
positive to positive edge of TIMEREN." />
<value name="Irq" value="11" desc="Timer runs until
IRQ." />
</field>
<field name="COD" from="2" to="2" access="RW" desc="Clear On
Disable (COD). Clears or gates outputs to zero.">
</field>
<field name="ROD" from="3" to="3" access="RW" desc="Reset On
Disable (ROD). Resets internal state of output logic">
</field>
<field name="CMP_CFG" from="6" to="4" access="RW"
desc="Comparator configurations">
<value name="Equal" value="0" desc="Compare Equal " />
<value name="Less than" value="1" desc="Compare Less
Than " />
<value name="Less than or equal" value="10"
desc="Compare Less Than or Equal ." />
<value name="Greater" value="11" desc="Compare Greater
Than ." />
<value name="Greater than or equal" value="100"
desc="Compare Greater Than or Equal " />
</field>
<field name="HW_EN" from="7" to="7" access="RW" desc="When
set Timer Enable controls counting.">
</field>
</register>
</block>
…
If you have registers that are part of the hardware, you can find generic register definitions in the
cyfitter.h file. These definitions will always be updated with the proper address regardless of where
your Component pieces are placed by PSoC Creator. To see what you have available, build a test
project with your Component in it, then open the generated cyfitter.h file. The following is an
example:
/* X_UDB_OffsetMix_1 */
#define X_UDB_OffsetMix_1_OffsetMixer_LSB__16BIT_DP_AUX_CTL_REG CYREG_B0_UDB10_11_ACTL
#define X_UDB_OffsetMix_1_OffsetMixer_LSB__16BIT_F0_REG CYREG_B0_UDB10_11_F0
#define X_UDB_OffsetMix_1_OffsetMixer_LSB__16BIT_F1_REG CYREG_B0_UDB10_11_F1
…
You can use the definition shown in red in your header file to redefine the abstract
X_UDB_OffsetMix_1_OffsetMixer_LSB__16BIT_F0_REG into something more human
friendly. For example:
Header File:
#define `$INSTANCE_NAME`_OUTPUT_PTR ((reg16 *) `$INSTANCE_NAME`_OffsetMixer_LSB
__16BIT_F0_REG)
#define `$INSTANCE_NAME`_OUTPUT_LOW_PTR ((reg8 *) `$INSTANCE_NAME`_OffsetMixer_LSB
__F0_REG)
#define `$INSTANCE_NAME`_OUTPUT_HIGH_PTR ((reg8 *) `$INSTANCE_NAME`_OffsetMixer_MSB
__F0_REG)
You now have a define `$INSTANCE_NAME_OUTPUT_PTR` to use anywhere; not only for the DMA
Wizard, but for API and Component usage in general.
Note Comments in the DMA Capability file are surrounded by ‘<!--‘ and ‘-->’. For example:
<!-- Text between brackets on one line
or more
will be commented out -->
The beginning of the DMA Capability file looks like the following:
<DMACapability>
<Category name=""
enabled=""
bytes_in_burst=”"
bytes_in_burst_is_strict=""
spoke_width=""
inc_addr=""
each_burst_req_request="">
<Location name="" enabled="true" direction=""/>
</Category>
</DMACapability>
The following sections describe how each field impacts the DMA Wizard:
If you have multiple categories, when your Component is selected in the source and destination,
another drop-down menu will appear listing the available categories.
<DMACapability>
<Category name="Catagory 1, 1 byte strict"
enabled="true"
bytes_in_burst="1"
bytes_in_burst_is_strict="true"
spoke_width="2"
inc_addr="false"
each_burst_req_request="true">
<Location name="`$INSTANCE_NAME`_location_1_cat_1" enabled="true"
direction="source"/>
</Category>
7.4.3.2 Enabled
The enable field can be set to “true” or “false”, or it can use a parameter passed from the customizer.
This can be used to enable or disable categories depending on features enabled or disabled in the
customizer. The syntax is such that you replace the content between the quotation marks with
`=$YourParameterName` [include the back ticks ( ` )].
<DMACapability>
<Category name="Catagory 1, 1 byte strict"
enabled="`=$EnableDMA`"
bytes_in_burst="1"
bytes_in_burst_is_strict="true"
spoke_width="2"
inc_addr="false"
each_burst_req_request="true">
<Location name="`$INSTANCE_NAME`_location_1_cat_1" enabled="true"
direction="source"/>
</Category>
</DMACapability>
Note Any field in the DMA Capability file can be replaced with a parameter using the same syntax.
You can also use Boolean expressions in these fields to produce more complex results. For
example:
enabled="`=$EnableExtraDest && $EnableExtraLocations`"
The user can override this setting by checking the Set Manually box. However, the tool will display
an error if the value is over the maximum or go outside the “Strict” value:
This setting can also be a parameter from a customizer. Use a type of “uint8” with the customizer
validator set to restrict the range from “0” to “127”.
bytes_in_burst="`=$Bytes`"
The user can always select Set Manually in the DMA wizard and override these settings, regardless
of the value of the strict setting. However, there will be a warning.
<DMACapability>
<Category name="Catagory 1, 1 byte strict"
enabled="true"
bytes_in_burst="31"
bytes_in_burst_is_strict="true"
spoke_width="2"
inc_addr="false"
each_burst_req_request="true">
<Location name="`$INSTANCE_NAME`_location_1_cat_1" enabled="true"
direction="source"/>
</Category>
</DMACapability>
<DMACapability>
<Category name="Catagory 1, 1 byte strict"
enabled="true"
bytes_in_burst="`=$Bytes`"
bytes_in_burst_is_strict="false"
spoke_width="2"
inc_addr="false"
each_burst_req_request="true">
<Location name="`$INSTANCE_NAME`_location_1_cat_1" enabled="true"
direction="source"/>
</Category>
</DMACapability>
If the “direction” field of the location entry (see Location Name on page 100) is set to “destination”
then when the “inc_addr” field is set to true, the Destination Inc check box will be checked instead
of the Source Inc check box.
As with other fields, the user can check the Set Manually check box to override the initial setting,
regardless of the value of the “each_burst_requires_a_request” field.
Note The syntax for the register name is slightly different than for a parameter.
If you only have one location in a category, then this location will automatically be populated in
the appropriate source/destination location in the TD configuration window.
<DMACapability>
<Category name="Catagory 1, 1 byte strict"
enabled="true"
bytes_in_burst="1"
bytes_in_burst_is_strict="true"
spoke_width="2"
inc_addr="true"
each_burst_req_request="true">
<Location name="`$INSTANCE_NAME`_location_1_cat_1" enabled="true"
direction="source"/>
</Category>
</DMACapability>
If you have multiple locations in the category, you will be given a choice from a drop down box
containing all the listed locations.
<DMACapability>
<Category name="Catagory 1, 1 byte strict"
enabled="true"
bytes_in_burst="1"
bytes_in_burst_is_strict="true"
spoke_width="2"
inc_addr="true"
each_burst_req_request="true">
<Location name="`$INSTANCE_NAME`_AWESOME_DATA_PTR" enabled="true"
direction="source"/>
<Location name="`$INSTANCE_NAME`_WOOT_PTR" enabled="true" direction="source"/>
<Location name="`$INSTANCE_NAME`_FOOBAR_PTR" enabled="true" direction="source"/>
</Category>
</DMACapability>
Enabled
If the location is enabled by setting this field to “true”, then the entry will appear in the TD
configuration window. If the location is set to “false” then the location will not show up in the list of
options. This can be used to selectively enable / disable options based on parameters set in the
customizer. The syntax is the same for the other fields:
enabled="`=$EnableLocationAwesome`"
Direction
The “direction” field sets the location as “source”, “destination” or “both”. This setting impacts where
the category will appear in the DMA wizard, as well as where the location and increment address will
go.
<DMACapability>
<Category name="Catagory 1, 1 byte strict"
enabled="true"
bytes_in_burst="1"
bytes_in_burst_is_strict="true"
spoke_width="2"
inc_addr="true"
each_burst_req_request="true">
<Location name="`$INSTANCE_NAME`_AWESOME_DATA_PTR" enabled="true"
direction="destination"/>
<Location name="`$INSTANCE_NAME`_WOOT_PTR" enabled="true" direction="destination"/>
<Location name="`$INSTANCE_NAME`_FOOBAR_PTR" enabled="true" direction="destination"/
>
</Category>
Note Any changes you make to the .cystate file won't take effect until PSoC Creator has been
restarted.
7.5.2 States
In general, Components can be in one of three states: obsolete, production, or prototype.
Obsolete defines a Component as not recommended for use.
Production defines a Component as fully-tested and warranted for use in production designs.
Prototype refers to everything else. There are two common uses: beta releases and example
content.
<xs:complexType name="ComponentStateRulesType">
<xs:sequence>
<xs:element name="Rule" type="RuleType" minOccurs="1" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="Version" type="xs:int" use="required"/>
</xs:complexType>
<xs:complexType name="RuleType">
<xs:sequence>
<xs:element name="Pattern" type="PatternType" minOccurs="1" maxOccurs="1"/>
<xs:element name="State" type="StateType" minOccurs="1" maxOccurs="1"/>
<xs:element name="Severity" type="SeverityType" minOccurs="1" maxOccurs="1"/>
<xs:element name="Message" type="xs:string" maxOccurs="1"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="PatternType">
<xs:sequence>
<xs:element name="Architecture" type="xs:string"/>
<xs:element name="Family" type="xs:string"/>
<xs:element name="Revision" type="xs:string"/>
<xs:element name="Device" type="xs:string"/>
</xs:sequence>
</xs:complexType>
<xs:simpleType name="StateType">
<xs:restriction base="xs:string">
<xs:enumeration value="Prototype"/>
<xs:enumeration value="Production"/>
<xs:enumeration value="Obsolete"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="SeverityType">
<xs:restriction base="xs:string">
<xs:enumeration value="None"/>
<xs:enumeration value="Note"/>
<xs:enumeration value="Warning"/>
<xs:enumeration value="Error"/>
</xs:restriction>
</xs:simpleType>
</xs:schema>
ComponentStateRules
ComponentStateRules is the root element that contains one or more rules for the Component. This
element has a required attribute named “Version” and the only legal value is 1. It has one element,
named Rule.
Rule
The Rule element defines a rule for the Component. Rules are listed in order of precedent. Once a
rule is matched, the result is returned. Each Rule supports one set of the following elements:
Pattern – This is the name of the pattern to match. The value for this element is specified by
PatternType. It can be any of family, series, device, and/or revision. The pattern is not
hierarchical, and it can be blank to search for everything.
State – This is the name of the state. The value for this element is specified by StateType. It can
be one of Production, Prototype, or Obsolete.
Severity – This is the type of message given by the Component for this particular rule. The value
for this element is specified by SeverityType. It can be one of:
2. Select the appropriate library file type for the desired toolchain under the Library category from
the templates. The Item name will default to something appropriate for the type selected; it can
be changed as needed. See Best Practices on page 109.
3. When a Library item is selected, the Configuration field becomes active to select the desired
configuration, as follows:
Debug
Release
Both
4. Click Create New to allow PSoC Creator to create the file, or select Add Existing from the pull-
down to select an existing file.
The item is added in the Workspace Explorer in the “Library” directory.
Best practices for using static libraries in a Component is to create a Component that will have only
the static library(ies) and add that Component to the schematic of Components using the static
library. This will allow Component authors to update the top level Component without having to
update the static library or vice versa. Additionally, Component authors should insure that all static
libraries they add to a Component are added at the Family level. This insures that the Component
author is adding CM-0 code to CM-0 based devices, CM-3 to CM-3, etc.
If during library creation, the Component author selects the wrong template (say GCC instead of
MDK), the Component author can go to their Component, select the library with the wrong template
and right-click, from there the author selects the properties item from the context menu. In the
Properties window, use the File Type property to select the appropriate template for the library.
3. On the Dependencies dialog, under User Dependencies, click the New Entry button.
4. On the Open dialog, navigate to the location of the project, select it, and click Open to close the
dialog.
5. On the Dependencies dialog, notice that the project you selected is listed under User
Dependencies. Click OK to close the Dependencies dialog.
6. On the Component Catalog, notice that there may be one or more new tabs and categories of
Components, depending on how the Components were configured.
2. On the dialog, expand the Project Management category and select Default Dependencies,
then click the New Entry button.
3. On the Open dialog, navigate to the location of the library project, select it, and click Open to
close the dialog.
4. On the Options dialog, notice that the project you selected is listed under Default
Dependencies. Click OK to close the Options dialog.
6. On the Component Catalog, notice that there may be one or more new tabs and categories of
Components, depending on how the Components were configured.
7. If you open the Dependencies dialog, notice that the project is already included under User
Dependencies.
When a Component project is built, all portions of it are built, including the family-specific portions.
After a build, the build directory will contain all aspects of the Component that the Component author
has specified via the project manager.
Customizing Components refers to the mechanism of allowing custom code (C#) to augment or
replace the default behavior of an instantiated Component within PSoC Creator. The code is
sometimes referred to as “customizers,” which may:
customize the Configure dialog
customize symbol shapes / display based on parameter values
customize symbol terminal names, counts, or configuration based on parameters
generate custom Verilog code
generate custom C/assembly code
interact with the clocking system (for clock and PWM Components)
3. The Component author explicitly asks PSoC Creator to build a new customizer DLL.
You will be able to specify whether to build the customizer DLL in "Debug" or "Release" mode, as
well as specify command line options to the compiler.
If there are any errors/warnings during the above build procedure, the errors/warnings are displayed
in the Notice List window. Since the DLL is built on the fly, there is no need to keep any of the built
customizer DLLs in source control.
The Component item displays in the Workspace Explorer tree, in a sub-directory named “Custom.”
The Text Editor opens the .cs file, and you can edit the file at this time.
To specify .NET references and other user references, browse to the directory where the assembly
resides and select it. In the case of .NET references you will have to browse to:
%windir%\Microsoft.NET\Framework\v2.0.50727
You can also specify relative paths in the assembly references dialog. You can add assembly
references relative to the project top level directory (.cydsn). You will have to type in the relative path.
Similarly if the DLL is compiled during a build (within cydsfit), the directory will be located at:
Documents and Settings/user_name/Local Settings/Application Data/
Cypress Semiconductor/cydsfit/<Release_Dir>/customizer_cache/
By design, Component customizers are rebuilt when necessary. Checking to see if the Component
customizers are up to date requires inspecting all of the constituent files, and it can take some time
to load those files from disk and inspect them.
To bypass loading and inspecting those files and to define the Component customizer assembly to
use, it is possible to precompile the Component customizers for a library. This will build the
Component customizer assembly, copy it into the library directory structure, and associate it with the
library. The precompiled Component customizer is named _project_.dll and is visible in the
Workspace Explorer at the top level of the project.
Note The existence of a precompiled Component customizer will bypass the source files. If the
source files change, the Component customizer used will be silently out-of-date. In addition, a
precompiled customizer is opened automatically, which will prevent the project from being renamed
or the customizer from being updated. For these reasons, only use this feature if performance
requires it, and only if you are sure that the Component customizers are unlikely to change.
To reduce confusion, PSoC Creator will refuse to build a new customizer assembly if a precompiled
customizer assembly for a project already exists, since the precompiled customizer assembly will
always be used.
When a Component is renamed or imported, all instances of the namespace within the customizer
source are replaced.
To avoid unintended substitutions in the source code, and to allow shared source (where one
Component can use common utility routines defined in another Component in the same library), all
the Components in a library should have a common distinct prefix, for example:
Some.Company.Name.
8.5 Interfaces
The customization support defines two sets of interfaces:
Customization interfaces implemented by Components
System interfaces used by customization interfaces
The interfaces are named with the version number concatenated to the end of the name. This allows
for upgrades to the interface without breaking existing customizers.
For in depth documentation, refer to the PSoC Creator Customization API Reference Guide
(customizer_api.chm file, located in the same directory as this Component Author Guide).
8.5.1.1 ICyTerminalQuery_v1
Has two methods called GetClockData. One takes two parameters (a terminal name, and an index)
and returns the frequencies of the clock that drives the terminal. The second takes an "instance
path", a terminal name, and an index and returns the clock frequency of buried clocks.
8.5.1.2 ICyClockDataProvider_v1
Components that generate or manipulate clocks can provide their frequency information to PSoC
Creator and it will automatically be accessible to the GetClockData methods.
Tuning support is a highly advanced feature that is used for a few limited Components, such as
CapSense®, that require the ability for the user to tune the Component while it is in the design.
Tuning requires communication between the firmware Component and the host application. The
firmware sends scan values to the GUI and the GUI sends updated tuning parameters down to the
firmware. This is an iterative process in order to get the best possible results out of the device.
PSoC Creator supports this requirement by providing a flexible API that Component authors can use
to implement tuning for their Component.
Communication to the device is done using an I2C, EZ I2C, SPI, or UART Component in the end
user’s design.
Tuning is typically done with a GUI that displays scan values on the various inputs and allows the
user to set new tuning parameter values. The effects of the parameter changes are visible in real-
time as they are applied.
The tuning application runs on a PC that is running PSoC Creator and it displays values as they
come from a PSoC device. Parameter values are written from the PC down to the chip at the user’s
request.
It is the responsibility of the user to set up this two-way communication channel using a
communication protocol that both the tuning framework and the tunable Component support. It is not
possible for PSoC Creator to automatically set up a communication channel for the user’s design
because it is not safe to make assumptions about what communication is available or how the user
is using the communication Components for additional purposes.
9.2 Architecture
The following diagram shows the PSoC Creator tuning framework. PSoC Creator launches tuning
for a Component using the TunerLaunch API. The Component’s tuner uses the TuningComm API to
read and write to the device. PSoC Creator interacts with the PSoC device using I2C, SPI, or UART
and the MiniProg3.
TunerLaunch API
PSoC Component
Creator TunerComm API
MP3
PSoC
The following sections list and summarize the various tuning interfaces. For in depth documentation,
refer to the PSoC Creator Tuning API Reference Guide (tuner_api.chm file, located in the same
directory as this Component Author Guide).
PSoC Creator launches the tuner as a non-modal window so that the user can do other things (such
as debugging) while the tuner is running.
The TunerComm API is implemented by PSoC Creator and is used by a tuner to communicate with
the PSoC device using a supported tuning communication channel.
The TunerComm API implements a data communication channel between the tuner GUI and the
Component firmware on the chip. The contents of the data being communication are opaque to
PSoC Creator. It is up to the Component tuner to make sure that the GUI and firmware agree on the
contents of the data being passed.
Note You cannot add more than one tuner DLL file to a Component.
PSoC Creator does not support source-based tuners. Therefore, the tuner must be compiled outside
of the tool and supplied as a DLL.
Refer to the PSoC Creator Tuning API Reference Guide (tuner_api.chm file, located in the same
directory as this Component Author Guide).
struct tuning_data {
// this data is opaque to PSoC Creator but known to the Component
} tuning_data;
for (;;) {
// If there the data from the last push has been consumed
// by the PC then go ahead and fill the buffer again.
This main function relies on a way to synchronize the reads and writes between the chip and the
host PC. This will likely be implemented by using a byte of data in the buffer for read and write
enables.
the Component. The firmware that is built when in tuning mode will be aware of this structure so that
it can process parameters correctly.
In this code, the tuner creates a custom GUI (MyForm) and then calls show dialog on this. Since this
tuner is being run its own thread, it is safe for it to call the blocking call, ShowDialog(), without fear of
hanging PSoC Creator.
PSoC Creator will call the LaunchTuner method and then wait for it to return. Once the method call
returns, PSoC Creator will call GetParameters() to get the new parameter values which it will then
store on the Component instance.
This chapter describes how to provide bootloader support for a Component. For more information
about the PSoC Creator bootloader system, refer to the PSoC Creator System Reference Guide.
To provide bootloader support in a Component, there are two general areas to modify:
Firmware
Customizer Bootloader Interface
10.1 Firmware
For a Component to support bootloading, it must implement five functions described in
Section 10.1.2. These functions are used by the bootloader for setting up the communications
interface and relaying packets back and forth with the host.
For more information about source code and implementing functions, see the Adding API
Files chapter on page 77.
10.1.1 Guarding
Because there can be multiple bootloader supporting Components in the design at once, each with
implementations of the necessary bootloader functions, all must be guarded for conditional
preprocessor inclusion. This guard is:
#if defined(CYDEV_BOOTLOADER_IO_COMP) &&
(CYDEV_BOOTLOADER_IO_COMP == CyBtldr_`@INSTANCE_NAME`)
//Bootloader code
#endif
10.1.2 Functions
The following functions need to be implemented in the Component to support bootloading:
CyBtldrCommStart
CyBtldrCommStop
CyBtldrCommReset
CyBtldrCommWrite
CyBtldrCommRead
10.1.2.4 cystatus CyBtldrCommWrite(uint8 *data, uint16 size, uint16 *count, uint8 timeOut)
Requests that the provided size number of bytes are written from the input data buffer to the
host device. Once the write is done count is updated with the number of bytes written. The
Description: timeOut parameter is used to provide an upper bound on the time that the function is allowed
to operate. If the write completes early it should return a success code as soon as possible.
If the write was not successful before the allotted time has expired it should return an error.
Parameters: uint8 *data – pointer to the buffer containing data to be written
uint16 size – the number of bytes from the data buffer to write
uint16 *count – pointer to where the comm. Component will write the count of the number of
bytes actually written
uint8 timeOut – amount of time (in units of 10 milliseconds) the comm. Component should
wait before indicating communications timed out
CYRET_SUCCESS if one or more bytes were successfully written. CYRET_TIMEOUT if the
Return Value:
host controller did not respond to the write in 10 milliseconds * timeOut milliseconds.
Side Effects: None
10.1.2.5 cystatus CyBtldrCommRead(uint8 *data, uint16 size, uint16 *count, uint8 timeOut)
Requests that the provided size number of bytes are read from the host device and stored in
the provided data buffer. Once the write is done count is updated with the number of bytes
written. The timeOut parameter is used to provide an upper bound on the time that the
Description:
function is allowed to operate. If the read completes early it should return a success code as
soon as possible. If the read was not successful before the allotted time has expired it should
return an error.
Parameters: uint8 *data – pointer to the buffer to store data from the host controller
uint16 size – the number of bytes to read into the data buffer
uint16 *count – pointer to where the comm. Component will write the count of the number of
bytes actually read
uint8 timeOut – amount of time (in units of 10 milliseconds) the comm. Component should
wait before indicating communications timed out
CYRET_SUCCESS if one or more bytes were successfully read. CYRET_TIMEOUT if the
Return Value:
host controller did not respond to the read in 10 milliseconds * timeOut milliseconds.
Side Effects: None
This interface is described in the the PSoC Creator Customization API Reference Guide
(customizer_api.chm file, located in the same directory as this Component Author Guide), under
“Common Interfaces.” It contains a single method that is used by the bootloader to determine
whether the current configuration of the Component is bootloader compatible.
public interface ICyBootLoaderSupport
{
CyCustErr IsBootloaderReady(ICyInstQuery_v1 inst);
}
When the Component is bootloader ready, any instance placed in the design will be shown as an
option for the bootloader IO Component in the Design-Wide Resources System Editor. The
implementation of the single method within the customizer only needs to validate the current
configuration of the Component to make sure the settings are compatable with bi-directional
communication.
For more information about customizers, see the Customizing Components (Advanced) chapter on
page 115.
This chapter covers general best practices to consider when creating Components, including:
Clocking
Interrupts
DMA
Low Power Support
Component Encapulation
Verilog
11.1 Clocking
When using the clocking resources internal to the PSoC device, there are several things to keep in
mind. As with any digital system, clocking architectures must be completely understood and
designed with the limitations and device characteristics firmly in mind.
Many of the digital resources available in the PSoC device can be clocked using the internal clocks
of the device. However, this is not universally true. There are many other resources that can and will
be contrived using clock sources other than those internally available in the chip. It is both of these
cases that have to be considered when designing Components for use in the PSoC device.
The second class of clock domain is controlled by a “user” clock. This clock may have its origin
entirely outside the PSoC internal clocking structure. This clock is the main clock for the
implemented function. For PSoC 4 devices, the (internal) clock is driven via a HFCLK and its
frequency must be below that of the SYSCLK to allow bus accesses by the CPU. The frequency
restriction also applies to external clocks. PSoC 3 and 5LP devices do not have these restrictions.
To avoid metastable conditions in the UDB, synchronization flip-flops may be necessary whenever a
signal crosses either clock domain boundary. There are a couple of ways that this can be
accomplished with resources internal to the UDB. The first way is to use the PLD macrocells as
synchronizers. The second way is to allocate the status register as a 4-bit synchronizer. The status
register can be configured to allow its 8 internal flip-flops to become 4 dual flip-flop synchronizers. As
expected, however, using the status register in this manner removes it from the pool of resources
inside the UDB.
The timing analysis of signals crossing clock domain boundaries is necessary in all circumstances.
Additionally, even for signals that are synchronous to the internal clocks, it may be necessary to
validate their phase relationships to the region that they enter. A synchronous signal that is shifted by
some amount may not satisfy the requirements for the timing in the destination circuitry.
The GPIO registers have access only to BUS_CLK (PSoC 3/PSoC 5LP) or HFCLK (PSoC 4) and
are not clock aligned with any external clock that a function may be using. Because of this limitation,
any PSoC 3/PSoC 5LP output registers that are not clocked by BUS_CLK must use UDB resources
before being sent to the output. This results in a very long clock to out path.
Any signal can be used by the UDB as an external clock signal. However, these external clocks do
not come directly via the clock tree. They are routed through long paths before they can enter the
clock tree. This makes the I/O timing problem more complex by creating long clock arrival times
resulting in long set-up times.
Metastability can be defined as a period of time when the output of a flip-flop is unpredictable or is in
an unstable (or metastable) state. Eventually, after some time, this state will resolve to a stable state
of either a ‘1’ or a ‘0’. However, that resolution may not be quick enough for circuitry that is
dependent upon the output to correctly evaluate the final result.
In combinatorial circuits, those outputs may cause glitches in the circuits that it drives. In sequential
circuits, those glitches result in hazard conditions that could affect the storing of data in registers and
the decision processes for state machines. It is therefore imperative that metastable states be
avoided.
There are several conditions that can result in metastable conditions, these conditions include:
Signals that cross a clock domain boundary.
Long combinatorial paths between flip-flops in a single clock domain.
Clock skew between flip-flops in a single clock domain
Any one of these (or other) situations may cause a metastable condition. In general if the set-up time
(Tsu) or hold time (Th) of the flip-flop is violated, a metastable state is possible if not probable.
For PSoC 3/PSoC 5LP, this clock source can be selected from several places:
1. CPU BUS_CLK,
2. global clock (SrcClk), which can be any internal clock, such as IMO, ILO, and master clock, or
3. external clock (ExtClk).
For PSoC 4 devices, the clock selection is restricted to (2) clocks derived from High Frequency clock
(HFLCLK) and (3) external clock (ExtClk).
If the ClkIn is the BUS_CLK/HFCLK, we can be assured that we have a single clock domain and
worries about clock domain crossing can be eliminated. However, there may still remain situations
where excessive skew is possible or long combinatorial paths exist.
Tco represents the clock to out time of the driving flip-flop. Tcomb is the combinatorial delay of the
intervening circuitry. Tsu is the set-up time of the next flip-flop stage.
If these long paths are contained completely within a Component, they are more easily handled.
Therefore, signals leaving a Component should be driven by a flip-flop to avoid problems. If this is
not possible or desirable, a complete understanding of the timing from clock to output of the
Component must be understood and communicated.
To best avoid metastability problems, signals that are interfaced to the CPU should be synchronized
with the BUS_CLK/HFCLK signal. If they are already a derivative of that clock, then the task for a
designer is to ensure that there are no long combinatorial path problems or problematic skews
(discussed earlier).
If signals need to be interfaced to the MPU but are controlled by clocks that are asynchronous to
BUS_CLK/HFCLK, they may need to be synchronized before being presented to that interface.
There are some primitive Components that are available in PSoC Creator that can help with that task
and are detailed in the following sections.
The cy_psoc3_udb_clock_enable has inputs for an enable (enable) and clock (clock_in), a clock
output (clock_out) that will drive the UDB Components, and a parameter to specify the intended
synchronization behavior for the clock result (sync_mode).
These can be either a global clock or a local clock and can be either synchronous or asynchronous
to BUS_CLK/HFCLK. The enable signal can also be either synchronous or asynchronous to
BUS_CLK/HFCLK. These two signals are then connected to the primitive and the user selects either
synchronous or asynchronous mode.
Once these have been done, the fitter in PSoC Creator will determine the implementation necessary
to obtain the requested clock behavior for the UDB elements and attach the appropriate signals to
the mapped UDB results. The rule set used when mapping the clock/enable to the UDB is listed in
the following table:
The Sync() function indicates that a double flip-flop has been used to synchronize the signal with
clock_out. These double registers are taken from a status cell configured in sync mode. The Enable
mode relates to the mode in which the internal logic chooses the clock signal in the Clock Select/
Enable control logic. This will be Edge type when the sync_mode is on and clock_in is a routed
clock.
A typical instantiation of the cy_psoc3_udb_clock_enable primitive might look something like this:
cy_psoc3_udb_clock_enable_v1_0 #(.sync_mode (‘TRUE)) My_Clock_Enable (
.clock_in (my_clock_input),
.enable (my_clock_enable),
.clock_out (my_clock_out));
A typical instantiation of the cy_psoc3_sync primitive might look something like this:
cy_psoc3_sync My_Sync (
.clock (my_clock_input),
.sc_in (my_raw_signal_in),
.sc_out (my_synced_signal_out));
Mixing positive edge triggering and negative edge triggering commonly restricts the length of time a
signal has to transverse it path. If, for instance, a flip-flop is clocked with the positive edge and the
resulting output is sent through some logic to another flip-flop that is clocked with a negative edge,
the Tcycle is effectively cut in half. If there is a need to trigger on both edges of a clock, a double
rate clock should be implemented and alternate positive edges should be used for triggering.
11.2 Interrupts
The main role of interrupts is to interact with CPU firmware or a DMA channel. Any data signal in the
UDB array routing can be used to generate an interrupt or DMA request. The status register and
FIFO status registers are considered the primary means of generating these interrupts. When small
amounts of data and frequent interaction with the CPU is required, the status register is the logical
choice for generating interrupts.
The generation of interrupts or DMA request is specific to the design. For example an interrupt that is
targeted for the CPU may be designed to be sticky (clear on read) but that same request for DMA
would not be appropriate because the design of the transaction descriptors would have to
incorporate a separate descriptor to clear the request in addition to the transaction descriptors to
process the data.
The status register is read-only and it allows internal UDB state to be read out onto the system bus
directly from internal routing. This allows firmware to monitor the state of UDB processing. Each bit
of these registers has programmable connections to the routing matrix.
A status interrupt example would be a case where a PLD or datapath block generated a condition,
such as a “compare true” condition, that is captured by the status register and then read (and
cleared) by CPU firmware.
The status mode register (CFGx) provides mode selection for each bit of the status register.
Transparent read is a mode in which a CPU read of the status register returns the state of the routing
input signal. Sticky mode, which is a clear on read, is a mode which the input status is sampled and
when the input goes high, the register bit is set and stays set regardless of the subsequent state of
the input. The register bit is cleared on a subsequent read by the CPU. The selected clock for this
block determines the sample rate. The rate should be greater than or equal to the rate at which the
status input signals are being generated.
When large amounts of data are being streamed or rapid burst are being transmitted or received,
DMA transactions are the most reasonable method of transport. In these cases, interrupts to control
data flow should be performed using FIFO status registers. The following diagram shows a high-
level view of the datapath module. These FIFOs generate status that can be routed to interact with
sequencers, interrupts, or DMA requests.
The “bus” status is primarily intended for the system bus control for DMA interaction (when the
system should read or write bytes).
When implementing a buffer for transactions, a decision should be made with regard to how much
RAM will be used to store the data. If the size of the buffer is less than or equal to 4 bytes, the buffer
should be implemented with the FIFO hardware.
The buffering provided in the receive and transmit FIFOs allows the processing order of user
application logic to be independent of the order of data transfer on the bus. The receive FIFO also
absorbs the usually observed bursty nature of data on the interface. This FIFO could also decouple
the operating frequency of the user application logic from the frequency of the specific bus. Consider
both buffer overflow and underflow in the implementation.
To solve the overflow problem, designers must employ a look-ahead indication of the FIFO status.
Thus, any port FIFO would indicate a satisfied status when the data path latency + status path
latency + maximum burst transfer is less than being full. This implies that the high watermark for a
FIFO must be set equal to data path latency + status path latency + maximum burst. Effectively, an
additional mandatory space after satisfied indication has to be provided in the port FIFO to avoid
buffer overflows.
The time elapsed between the FIFO status indicating starving or hungry to get the data for that
particular port is the total path latency, which is the sum of status update latency + status path
latency + data scheduler latency and finally the data path latency. The first two numbers reflect the
amount of time required in getting the burst information built up at the transmitter. The last two
numbers define the amount of time required to get the data moved across the interface from transmit
FIFO to the receive FIFO over the particular link.
The buffer underflow depends on the maximum read rate of the port FIFO by the application logic. To
prevent underflow, software should program low watermark for each port FIFO, judiciously (that is,
large enough).
11.3 DMA
The Peripheral HUB (PHUB) is a programmable and configurable central hub within a PSoC 3 and
PSoC 5 device that ties the various on-chip system elements together utilizing standard Advanced
Microcontroller Bus Architecture (AMBA) high-performance bus (AHB). The PHUB essentially
utilizes a multi-layer AHB architecture allowing for simultaneous AMBA-lite style mastering. The
PHUB contains a DMA controller (DMAC) that can be programmed to transfer data between system
elements without burdening the CPU. PHUB contains logic that performs arbitration between DMAC
and the CPU for access to PHUB’s downstream spokes.
The diagram below illustrates the general connectivity between the CPU, PHUB, SYSMEM, TD/
CFGMEM and the downstream spokes.
CPU
CPU
INTERFACE
PHUB CHn
CSRs
CHn
CSRs
CHn
CSRs
DMAREQ[N:0]
CH ARB
SPK0
(AHB)
TD/ LOCMEM
DMAC SYSMEM
CFGMEM ARB
LOCAL SPOKE /
PHUB CSR
SPOKE ARBITRATION
SPOKES to
Peripherals
The details with regard to the register map are contained in the PSoC® 3, PSoC® 5 Architecture
Technical Reference Manual (TRM). The points of concern here are that the DMA controller offloads
the CPU, it is a separate bus master, and that the DMAC arbitrates between multiple DMA channels.
The DMA handler and associated APIs are outlined in DMA Component datasheet.
The main points of this section is to consider how to construct a Component to use DMA, methods of
data transfer utilizing DMA, how to signal a transfer and what methods are best for transferring either
large amounts of data or small packets that may only consist of single byte. To reduce the complexity
of configuration a DMA wizard is provided for the end user. As part of the Component development
the capabilities of the Component with regard to DMA may be provided in an XML file.
Each datapath module has six 8-bit working registers. All registers are CPU and DMA readable and
writable.
Each datapath contains two 4-byte FIFOs, which can be individually configured for direction as an
input buffer or an output buffer. These FIFOs generate status that can be routed to interact with
sequencers, interrupts, or DMA requests. For an input buffer, thesystem bus writes to the FIFO, and
datapath internals read the FIFO. For an output buffer, datapath internals write to the FIFO, and the
system bus reads from the FIFO.
For small transfers, the accumulator should be used especially when a single packet of data will be
transmitted or received and where computation on the data is necessary before another packet is
sent.
For large data transfers that require continuous streams of data, FIFOs are particularly useful. Along
with the FIFO status logic, continuous data streams can be maintained without the loss of data.
There are two status bits generated from each FIFO block that are available to be driven into the
UDB routing through the datapath output multiplexer. The “bus” status is primarily intended for the
system bus control for CPU/DMA interaction (when the system should read or write bytes). The
“block” status is primarily intended for local control to provide FIFO state to the internal UDB state
machines. The meaning of the status depends on the configured direction (Fx_INSEL[1:0]) and the
FIFO level bits.
FIFO level bits (Fx_LVL) are set in the auxiliary control register in working register space. Options
are shown in the following table.
Fx_INSEL
Fx_LVL Signal Status Description
[1:0]
This status is asserted when there is room for at least 1 byte
Input 0 fx_bus_stat Not Full in the FIFO. This status can be used to assert a system
interrupt or DMA request to write more bytes into the FIFO.
At Least This status is asserted when there is room for at least 2
Input 1 fx_bus_stat
Half Empty bytes in the FIFO.
This status is asserted when there are no bytes left in the
FIFO. When not empty, the Datapath function may consume
Input N/A fx_blk_stat Empty
bytes. When empty the control logic may idle or generate
underrun status.
The following table defines the peripherals associated with a spoke and the width of the spoke.
The source spoke and destination spoke can be different sizes. The burst engine will use the FIFO
within the DMA controller as a funneling mechanism between the two spokes.
Note In the dynamic FIFO control mode, d0_load and d1_load are not available for their normal use
in loading the D0/D1 registers from F0/F1.
In a given usage scenario, the dynamic control (dx_load) can be controlled with PLD logic or any
other routed signal, including constants. For example, starting with external access (dx_load == 1),
the CPU or DMA can write one or more bytes of data to the FIFO. Then toggling to internal access
(dx_load == 0), the datapath can perform operations on the data. Then toggling back to external
access, the CPU or DMA can read the result of the computation.
There are three types of interfaces: the PLD, the configuration latches, and the DP configuration
RAM. All configurations are writable as 16 bits to support DMA or as 16-bit processor operations.
They are also separately writable as upper (odd addresses) and lower (even addresses) bytes. The
PLD has unique read signals which implement RAM read and write timing. The CFG registers and
DP CFG RAM share the same read and write control signals.
Note that UDBs can be accessed as 8- or 16-bit objects and each of these access methods has a
different address space.
On the left, the 8-bit address scheme is shown, where the register number is in the upper nibble and
the UDB number is in the lower nibble. With this scheme, the working registers for 16 UDBs can be
accessed with an 8-bit address.
On the right is the 16-bit address, which is always even aligned. The UDB number is 5 bits instead of
4 due to the even address alignment. The upper 4 bits is still the register number. A total of 9
address bits are required to access 16 UDBs in 16-bit data access mode. Working registers are
organized into banks of 16 UDBs.
A0 A0 A0
A1 A1 A1
Only one byte at a time can be accessed in this mode and the PHUB will naturally align the valid odd
(upper) or even (lower) byte back to the processor or DMA.
As shown in the following figure, the default mode accesses a given register in UDB ‘i’ in the lower
byte and the same register in UDB ‘i+1’ in the upper byte. This makes 16-bit data handling efficient in
neighboring UDBs (address order) that are configured as a 16-bit function.
UDB 2 UDB 1 UDB 0
A0 A0 A0
A1 A1 A1
Low byte High byte Low byte High byte Low byte
16-bits at 16-bits at 16-bits at
UDB 2 UDB 1 UDB 0
The following figure shows the concat mode, where the registers of a single UDB are concatenated
to form 16-bit registers. In this mode, the 16-bit UDB array data bus has access to pairs of registers
in the UDB. For example, an access at A0, returns A0 in the low byte and A1 in the high byte.
UDB i
A1 A0
D1 D0
F1 F0
CTL/CNT ST
ACTL MSK/PER
00h MC
16-bits at
High byte UDB i Low byte
When the DMA transfers 16 bits to address 0, the lower and upper bytes are written to UDB0 and
UDB1, respectively. On the next 16-bit DMA transfer at address 2, you will overwrite the value in
UDB1 with the lower byte of that transfer. To avoid having to provide redundant data organization in
memory buffers to support this addressing, it is recommended that 8-bit DMA transfers in 8-bit
working space be used for functions over 16 bits.
The overhead of processing a channel is generally hidden in the background of data bursting. The
arbitrating, fetching, or updating for a channel can occur in the background of the data bursting of
another channel. Additionally, the data bursts of one channel can overlap with the data bursts of
another channel, provided there is no spoke contention or contention for the source (SRC) or
destination (DST) engines of the DMA controller.
Intra-spoke DMA requires the entire SRC burst to first be buffered in the DMA controller FIFO before
the data is then written back out to the same spoke. In that case there are two of these N+1 length
bursts that occur, and thus the general formula for an ideal intra-spoke burst is 2N+2.
Inter-spoke DMA allows the SRC and DST bursts to overlap. As data is being read from the SRC
spoke and written into the DMA controller FIFO, the DST engine can write available FIFO data to the
DST spoke. As a result of this overlapping, inter-spoke DMA is more efficient. The net result is that
there are three overhead cycles to move a single piece of data from one spoke to the other. The
initial control cycle on each spoke plus one “redundant” data cycle (it takes one data cycle on each
spoke to move each piece of data). Thus the general formula for an ideal inter-spoke DMA burst is
N+3 to move N pieces of data.
The following table shows the cycle times for some example ideal bursts:
Note You cannot add more than one DMA Capability file to a Component.
uint8 enableState;
} `$INSTANCE_NAME`_BACKUP_STRUCT;
Restore non-retention register values from the static data structure. Restore only the specific
Component register values.
`$INSTANCE_NAME`_RestoreConfig()
{
/* Restore non-retention register values from backup data structure. */
}
Save the enable state of the Component. Use this state to determine whether to start the
Component on wake-up. Stop the Component and save the configuration.
`$INSTANCE_NAME`_Sleep()
{
/* Save Component’s enable state – enabled/disabled. */
if(/* Component’s block is enabled */)
{
backup.enableState = 1u;
}
else /* Component’s block is disabled */
{
backup.enableState = 0u;
}
`$INSTANCE_NAME`_Stop();
`$INSTANCE_NAME`_SaveConfig();
}
Restore the Component configuration and determine if the Component should be enabled.
`$INSTANCE_NAME`_Wakeup()
{
`$INSTANCE_NAME`_RestoreConfig();
/* Restore Component’s block enable state */
if(0u != backup.enableState)
{
/* Component’s block was enabled */
`$INSTANCE_NAME`_Enable();
} /* Do nothing if Component’s block was disabled */
}
To make it easy to reuse a design with PSoC Creator, it should be encapsulated as a PSoC Creator
Component. A design can be considered for encapsulation and reuse if it meets one or more of the
following criteria:
Implements a specific function. The general rule is that it should “do just one thing and do it well.”
Has a limited and relatively small set of inputs and outputs, in the form of either hardware
terminals or API calls. The general rule is the fewer the better, but not so few that essential
functionality is reduced.
In one of the simpler examples of when to encapsulate IP as a Component, consider what you might
do if you are required to have a window comparator in your design. A window comparator activates
when an input voltage is between two compare voltages. With PSoC Creator you would most likely
design it as follows:
This design is a good candidate for encapsulation as a Component. It implements just one specific
function: a window comparator. Plus, it has a limited and small set of inputs and outputs. It would
also have a small API to start the comparators. So the basic, essential functionality of the design can
be encapsulated into a Component, with a symbol, as follows:
When encapsulating a design, an important decision is what to leave out of the Component. In the
above example, the VDACs could have been brought into the Component. However, they really are
not part of the essential design functionality, which is simply comparing a voltage to two reference
voltages. The reference voltages could be provided by VDACs or by some other source. So in this
case it is better practice to leave the VDACs out.
The following the mag card reader example is more complex. In this design, there is a central ADC
and reference section along with multiple copies of circuitry for reading a single channel:
The basic design functionality in this case is converting the analog inputs from the channel into a
form that is readable by a digital system. Again, because it is a well-defined and limited function it is
a good candidate for encapsulation:
Again, you need to look at what to leave out of the Component. The original design uses two SIO
pins with different thresholds. These could have been brought into the Component but it is better
practice to keep pins at the top-level design. Also, the basic design requires only the digital signals
CH_hi and CH_lo, and not necessarily their sources.
Also, since PSoC 3/5 opamps are closely associated with specific device pins, it may actually be
better to keep the opamp out of the Component.
Finally, the design makes use of limited analog resources and routing, and multiple instances may
not fit in some smaller PSoC 3/5 devices. This fact, along with possible voltage, temperature, or
speed limitations should be communicated to the user. For example, what frequency should PeakClk
be? It is known at the top level of the original design, but perhaps not known when the Component
is reused.
This brings up an interesting issue: when NOT to encapsulate a design. If a design meets one or
more of the criteria listed below, it may not be good practice to encapsulate it. If it is encapsulated
then the relevant issues and limitations should be communicated such that the user becomes aware
of the issues as soon as an attempt is made to reuse the Component.
Incorporates critical resources in the PSoC 3/5, thereby making those resources unavailable in
the higher-level design. Specific topics include:
usage of single-instance fixed-function blocks such as ADC_DelSig, CAN, USB, and I2C
too much usage of more abundant resources such as UDBs, comparators, DACs, opamps,
timers, DMA channels, interrupts, pins, clocks, etc.
too much usage of less obvious resources such as analog or DSI routing, flash, SRAM or
CPU cycles
Operates only under certain conditions, for example: CPU or bus_clk speed, or Vdd levels, or
only with certain parts such as the PSoC 5 family.
Multiple instances of the IP cannot be implemented.
11.5.2 Parameterization
In PSoC Creator, Components can be parameterized. That is, the behavior of an instance of a
Component can be set at build time (typically by using a dialog box). Both hardware and software
behavior can be set up by parameterization. Parameterization should be used in cases where:
Different instances of the IP behave slightly differently but the overall functionality is unchanged.
For example, an alert output on a fan controller may be set to be active high or active low.
The differences in behavior are not expected to change at run-time.
If parameterization causes large changes to the functionality of different instances, then you should
consider encapsulating the design in multiple Components. PSoC Creator allows multiple
Components to be packaged in a single library project, so different versions of the Component can
be kept together. For example, a single fan controller Component might have a parameter for
number of fans to be controlled. Fan controllers with two different interfaces, like SPI and I2C, might
be two separate Components in the “Fan Control” library project.
Clock Components may or may not be encapsulated in a Component. The advantage of not
embedding a clock is that multiple Components can be connected to the same clock, thereby
conserving clock resources. A Component can include a parameterization option to make a clock
internal or external.
Interrupts and DMA channels may or may not be encapsulated in a Component. A Component may
generate a “have data” signal that could be connected to either an IRQ or a DRQ, in which case the
interrupt and DMA should not be embedded in the Component.
Components can contain several different file types: symbol (.cysym), schematic (.cysch), Verilog
(.v), firmware source code (.c, .h, .a51, etc.), and documentation (.pdf, .txt). Components can also
reference other Components, thus enabling hierarchical design techniques.
Components developed under this specification should have as a minimum a symbol file and a
datasheet file. All other file types are optional depending on the function of the Component. For
example, a hardware-only Component could have just a schematic or Verilog file, whereas a
firmware-only Component could have just a .h and .c file for an API.
Component datasheet
To properly document your Component, a datasheet should be included. The datasheet should
include the design considerations mentioned above. For information about how to add a datasheet,
see Add/Create Datasheet on page 83.
Component Versioning
The Component name can include version information, which is done by appending the following to
the Component name:
“_v<major_num>_<minor_num>_<patch_level>”
Both <major_num> and <minor_num> are integers that specify the major and minor version
numbers respectively. <patch_level> is a single, lower case, alpha character. Components should be
versioned. For information about versioning, see Component Versioning on page 12.
The reference Component should be included with each of its parameters set to as many different
settings as possible. Note that in order to do this either multiple instances of the Component may
need to be used or multiple test / demo projects may need to be created. All functions in the
Component’s API should be called at least once. All macros should be used at least once.
As much as possible, the test projects should support both PSoC 3 and PSoC 5, in various
configurations. For example, standard and bootloadable, debug and release, different PSoC 5
compilers, and different compiler optimization settings.
11.6 Verilog
Many digital Components use Verilog to define the implementation of the Component. For more
information, see Implement with Verilog on page 57.
This Verilog must be written in the synthesizable subset of Verilog. In addition to conforming to the
Verilog subset, there are additional guidelines that should be followed when creating a Verilog-based
Component. Many of these guidelines are practices accepted as best practices for any synthesis
tool. Additional guidelines are specific recommendations related to the development of a PSoC
Creator Component.
The specific synthesizable subset of Verilog supported by PSoC Creator is specified in the Warp
Verilog Reference Guide. This synthesizable subset is similar to the subset implemented in other
Verilog synthesis tools. Refer to the guide for a detailed description of the Verilog constructs
supported.
The synthesizable portion of the Verilog design will be synthesized into PLD logic. The remaining
UDB resources can be instantiated into a Verilog design, but they are never inferred by the synthesis
process.
nextstate state
clk
Y
C
Do not mix blocking and non-blocking assignments in the same always block
This rule implies that combinatorial logic that requires more than a single assignment to implement
should be described in a block separate from a sequential always block. This combinatorial logic can
be implemented in a separate combinatorial block or in a continuous assignment statement.
Do not make assignments to the same variable in more than one always block
The synthesis engine in PSoC Creator will enforce this rule and generate an error if this rule is
violated.
this rule to continue to be satisfied when case-items are changed later in the development of the
code. If a case-item is removed or the width of the case is changed, then the default statement is
already present.
This rule is particularly important within a combinatorial always block. Including a default condition
where the combinatorial result is assigned prevents the synthesis of latches in the design.
When a parameter is passed to a Verilog module the parameter setting will be applied before
synthesis is performed. The result is that the specific instance will be synthesized based on the
parameter settings. This method is appropriate for settings that can be made at build time, but can’t
be used for settings that will need to be determined at run time. Settings that can be changed at run
time will need to be controlled by software through the datapath or control registers. Determining
which parameters should be static and which need to be dynamic (run time changeable) will
influence the complexity and resource requirements of the Component.
A Verilog based Component that has a Hardware parameter will get access to that parameter value
with a parameter statement. This parameter statement will automatically be created in the Verilog
template that can be created automatically from the symbol. The initial value will always be
overridden with the value set for the specific instance of the Component.
parameter Interrupt = 0;
Generate statements
Often the value of a parameter will result in the need for significantly different Verilog code based on
that value. This functionality can be implemented using a Verilog generate statement. For example if
a Component can have either an 8-bit or 16-bit implementation, that will result in the need to
instantiate either an 8-bit or 16-bit datapath Component. The only method to implement that
functionality is a generate statement.
parameter [7:0] Resolution = WIDTH_8_BIT;
generate
if (Resolution == 8) begin : dp8
// Code for 8-bit
end
else begin : dp16
// Code for 16-bit
end
endgenerate
There are two ways that parameters can be passed in Verilog. The original method is the defparam
statement. In the other method, from the Verilog-2001 specification, parameters can be passed
using named parameters. The parameter names and values are included after a “#” in the module
instance. It is recommended that parameters always be passed using named parameters.
cy_psoc3_statusi #(.cy_force_order(1),
.cy_md_select(7’h07), .cy_int_mask(7’h07))
stsreg(
.clock(clock),
.status(status),
.interrupt(interrupt)
);
multiple configuration parameters. Duplicating the same information is prone to error and difficult to
maintain, so a parameter value can be used so that the configuration data is only present in one
place.
parameter config0 = {
`CS_ALU_OP_PASS,
// Remainder of the value not shown here
};
11.6.2.4 Latches
Latches should be avoided in a PSoC design. Some programmable logic devices have latches built
into their architecture. That is not the case for PSoC devices. Each macrocell can be combinatorial
or registered on a clock edge. If a latch is created in a PSoC design, the latch will be implemented
using cross coupled logic. The use of latches limits the capability to do timing analysis due to the
loop construct that is created. The combinatorial latch based implementation can also have timing
issues since the length of the feedback paths is not controlled.
It is often the case that when a latch is present in a design, that a latch was not the intended
functionality. A latch will be inferred during synthesis for any output from a combinatorial always
block where there is at least one path through the block where the output is not assigned a value.
This can be avoided by assigning to each output in every if-else clause and including a final else
clause in an if-else chain. Alternatively this can be avoided by assigning a default value for each
output at the top of the always block.
Asynchronous reset and set can not be used for the same register
The hardware implementation for the PLD macrocells uses a single signal for asynchronous reset
and set. A selection is made to use this signal as a reset, a set or not use the signal. The option of
having both an asynchronous reset and set is not available in the hardware.
11.6.3 Optimization
11.6.3.1 Designing for Performance
The performance of a typical digital Component is determined by the longest combinatorial path
between two registers. The time taken by that combinatorial path is determined by the mapping of
the Verilog design to the available hardware.
Registering outputs
Depending on the typical usage model for a Component, it can be beneficial to register the outputs
of the Component. If there is more than one output and they are sent to pins, then registering these
outputs will result in more predictable timing relationship between the output signals. If the outputs
from the Component are used to feed another Component, then the performance of the system will
be dependent on the output timing from this Component and the input timing of the destination
Component. If the outputs are registered, the output portion of that path will be minimized.
To determine the number of inputs that are needed to calculate a specific output all the inputs that
are used in if statements, case statements and in the assignment statement for a particular output
need to be counted.
building logic for the PLD, the specific architecture of the PSoC PLD must be taken into
consideration.
The first step is to build the Component and observe the average statistics for the packed PLDs from
the report file.
If the average number of macrocells is significantly below 4.0 and the number of inputs is
approaching 12.0, then the number of inputs required is the limiting factor in your design. To improve
the packing, the number of inputs required will need to be reduced.
In some cases this can be done by restructuring the equations to consolidate a group of inputs to a
single input. For example, if a multi-bit comparison is an input, then that can be replaced by a single
result input. If this value is used to calculate multiple outputs (a multi-bit register), then forcing a
specific partition of the logic can result in significant size reduction. To force a signal to be the output
of a macrocell, use the cy_buf Component. The output of a cy_buf will always be a macrocell output.
wire cmp = (count == 10’h3FB);
cy_buf cmpBuf (.x(cmp), .y(cmpOut));
logic will be placed in PLDs. Datapath implementation must be done by including a datapath
instance in the Verilog design.
11.6.4.1 Datapath
The datapath resource has many times the equivalent logic gate capability as the PLD resource, so
if applicable to the application the datapath resource should be the first choice.
The PSoC Creator expression evaluator is used to evaluate expressions in PSoC Creator (except
those in the debugger). This includes parameter values, expressions in strings, and code generation
templates. The expression evaluation language is similar to the Perl 5 language. It borrows most of
its operators, including their precedence, but adds a different type system, which is better suited to
PSoC Creator application requirements.
The evaluation of local and formal parameters was discussed in Formal versus Local Parameters on
page 13. Annotations can have embedded expressions. Most annotations are evaluated in the
document context. Annotations associated with instances are evaluated in the instance context.
A.2.1 Bool
Legal values include true and false.
A.2.2 Error
Values of the error type may be created automatically by the system, or by end users. This provides
a standard means by which evaluation expressions can generate custom errors.
A.2.3 Float
64-bit double precision IEEE floating point. Written as [+-] [0-9] [.[0-9]*]? [eE [+-]? [0-9]+]
Illegal: .2, e5
A.2.4 Integers
Sized, signed, and unsigned integers. Integers may be expressed in any of the following three
bases:
hexadecimal – starts with 0x
octal – starts with 0
decimal – all other sequences of digits
The following table shows the valid values for each specific type.
A.2.5 String
Sequences of characters, enclosed in double quotes (“). Stored as .NET strings internally (UTF-16
encoded Unicode). Currently, only ASCII characters are recognized by the parser. \\ and \” are the
only supported escape sequences in strings.
The one exception to the conversion rule is the error type. All data types may be converted to the
error type, but the error type may not be converted to any other type.
A.3.1 Bool
A.3.2 Error
A.3.3 Float
A.3.4 Int
A.3.5 String
Strings are a special case. There are 4 sub-types of strings. These include:
bool-ish strings have the value “true” or “false”.
float-ish strings have a floating point value as their first non whitespace characters. Trailing
characters that are not a part of the float are ignored.
int-ish strings have an integer value as their first non-whitespace characters. Trailing characters
that are not a part of the float are ignored.
other
A.4 Operators
The expression evaluator supports the follow operators (in order of precedence from high to low).
casts
! unary+ unary-
*/%
+-.
< > <= >= lt gt le ge
== != eq ne
&&
||
?:
All operators force their arguments to a well defined type and yield a result in a well defined type.
If both operands are integers and at least one is unsigned then the operation is performed as an
unsigned operation.
Arithmetic operators always yield an error value or a number of the same type as the operands after
the operands have been converted using the rules defined above.
A.4.2 Numeric Compare Operators (==, !=, <, >, <=, >=)
Numeric comparison operators force their arguments to a number using the exact same rules as the
arithmetic operators. Numeric compare operators always yield a bool value.
If both operands are integers and at least one is unsigned then the operation is performed as an
unsigned operation.
A.4.3 String Compare Operators (eq, ne, lt, gt, le, ge)
String compare operators force their arguments to strings, unless either operand is an error. If either
operand is an error, the left-most error is the result of the operation. String compare operators always
yield an error value or a string.
Note If the concatenation operator is directly preceded or followed by a digit, then it will be
interpreted as a float (e.g., 1. = float; 1 . = string concatenation).
A.4.6 Casts
Casts (lowercase: cast) are of the form: cast(type, expr)
Casts evaluate the expression and convert the result of expr to the named type.
The `= marks the beginning of the expression. The = sign is not interpreted as part of the expression.
Since the next ` found ends the expression it is not possible to nest `= blocks inside other `= blocks.
Multiple expressions, provided they aren’t nested, may be embedded in the same string and they will
all be evaluated and interpolated. There is only one evaluation pass over the embedded expression.
If the resutling string is a legal expression it will not be evaluated as an additional step.
The portion of the string from the starting ` to the ending ` is replaced with the result of the
expression between the ` and `.