Commit 9d19b097 authored by Tomasz Wlostowski's avatar Tomasz Wlostowski

Initial wbgen2 uploaded.

parent 2d957fc1
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
This is the initial version of wbgen2. Requires Lua 5.1.4+. Enjoy it :)
There is still some stuff to do:
- add RAMs and FIFOs
- add C code generator
- add documentation generator
- CONSTANT registers
\ No newline at end of file
These examples show various uses of wbgen2.
Run "run.do" in Modelsim to start the simulation.
\ No newline at end of file
; Copyright 2006 Mentor Graphics Corporation
;
; All Rights Reserved.
;
; THIS WORK CONTAINS TRADE SECRET AND PROPRIETARY INFORMATION WHICH IS THE PROPERTY OF
; MENTOR GRAPHICS CORPORATION OR ITS LICENSORS AND IS SUBJECT TO LICENSE TERMS.
;
[Library]
std = $MODEL_TECH/../std
ieee = $MODEL_TECH/../ieee
verilog = $MODEL_TECH/../verilog
vital2000 = $MODEL_TECH/../vital2000/vhdl
std_developerskit = $MODEL_TECH/../std_developerskit
synopsys = $MODEL_TECH/../synopsys
modelsim_lib = $MODEL_TECH/../modelsim_lib
sv_std = $MODEL_TECH/../sv_std
UNISIMS_VER = /opt/Xilinx/10.1/ISE/verilog/mti_se/unisims_ver
UNI9000_VER = /opt/ISE8/verilog/mti_se/uni9000_ver
SIMPRIMS_VER = /opt/Xilinx/10.1/ISE/verilog/mti_se/simprims_ver
XILINXCORELIB_VER = /opt/Xilinx/10.1/ISE/verilog/mti_se/XilinxCoreLib_ver
AIM_VER = /opt/ISE8/verilog/mti_se/abel_ver/aim_ver
CPLD_VER = /opt/ISE8/verilog/mti_se/cpld_ver
UNIMACRO_VER = /opt/Xilinx/10.1/ISE/verilog/mti_se/unimacro_ver
SECUREIP = /opt/Xilinx/10.1/ISE/vhdl/mti_se/secureip
UNISIM = /opt/Xilinx/10.1/ISE/vhdl/mti_se/unisim
UNIMACRO = /opt/Xilinx/10.1/ISE/vhdl/mti_se/unimacro
XILINXCORELIB = /opt/Xilinx/10.1/ISE/vhdl/mti_se/XilinxCoreLib
SIMPRIM = /opt/Xilinx/10.1/ISE/vhdl/mti_se/simprim
altera_mf = $MODEL_TECH/../altera/vhdl/altera_mf
altera_primitives = $MODEL_TECH/../altera/vhdl/altera_primitives
lpm = $MODEL_TECH/../altera/vhdl/lpm
sgate = $MODEL_TECH/../altera/vhdl/sgate
cycloneiii = $MODEL_TECH/../altera/vhdl/cycloneiii
work = work
[vcom]
; VHDL93 variable selects language version as the default.
; Default is VHDL-2002.
; Value of 0 or 1987 for VHDL-1987.
; Value of 1 or 1993 for VHDL-1993.
; Default or value of 2 or 2002 for VHDL-2002.
VHDL93 = 2002
; Show source line containing error. Default is off.
; Show_source = 1
; Turn off unbound-component warnings. Default is on.
; Show_Warning1 = 0
; Turn off process-without-a-wait-statement warnings. Default is on.
; Show_Warning2 = 0
; Turn off null-range warnings. Default is on.
; Show_Warning3 = 0
; Turn off no-space-in-time-literal warnings. Default is on.
; Show_Warning4 = 0
; Turn off multiple-drivers-on-unresolved-signal warnings. Default is on.
; Show_Warning5 = 0
; Turn off optimization for IEEE std_logic_1164 package. Default is on.
; Optimize_1164 = 0
; Turn on resolving of ambiguous function overloading in favor of the
; "explicit" function declaration (not the one automatically created by
; the compiler for each type declaration). Default is off.
; The .ini file has Explicit enabled so that std_logic_signed/unsigned
; will match the behavior of synthesis tools.
Explicit = 1
; Turn off acceleration of the VITAL packages. Default is to accelerate.
; NoVital = 1
; Turn off VITAL compliance checking. Default is checking on.
; NoVitalCheck = 1
; Ignore VITAL compliance checking errors. Default is to not ignore.
; IgnoreVitalErrors = 1
; Turn off VITAL compliance checking warnings. Default is to show warnings.
; Show_VitalChecksWarnings = 0
; Turn off PSL assertion warning messages. Default is to show warnings.
; Show_PslChecksWarnings = 0
; Enable parsing of embedded PSL assertions. Default is enabled.
; EmbeddedPsl = 0
; Keep silent about case statement static warnings.
; Default is to give a warning.
; NoCaseStaticError = 1
; Keep silent about warnings caused by aggregates that are not locally static.
; Default is to give a warning.
; NoOthersStaticError = 1
; Treat as errors:
; case statement static warnings
; warnings caused by aggregates that are not locally static
; Overrides NoCaseStaticError, NoOthersStaticError settings.
; PedanticErrors = 1
; Turn off inclusion of debugging info within design units.
; Default is to include debugging info.
; NoDebug = 1
; Turn off "Loading..." messages. Default is messages on.
; Quiet = 1
; Turn on some limited synthesis rule compliance checking. Checks only:
; -- signals used (read) by a process must be in the sensitivity list
; CheckSynthesis = 1
; Activate optimizations on expressions that do not involve signals,
; waits, or function/procedure/task invocations. Default is off.
; ScalarOpts = 1
; Turns on lint-style checking.
; Show_Lint = 1
; Require the user to specify a configuration for all bindings,
; and do not generate a compile time default binding for the
; component. This will result in an elaboration error of
; 'component not bound' if the user fails to do so. Avoids the rare
; issue of a false dependency upon the unused default binding.
; RequireConfigForAllDefaultBinding = 1
; Perform default binding at compile time.
; Default is to do default binding at load time.
; BindAtCompile=1;
; Inhibit range checking on subscripts of arrays. Range checking on
; scalars defined with subtypes is inhibited by default.
; NoIndexCheck = 1
; Inhibit range checks on all (implicit and explicit) assignments to
; scalar objects defined with subtypes.
; NoRangeCheck = 1
; Run the 0in tools from within the simulator.
; Default value set to 0. Please set it to 1 to invoke 0in.
; VcomZeroIn = 1
; Set the options to be passed to the 0in tools.
; Default value set to "". Please set it to appropriate options needed.
; VcomZeroInOptions = ""
; Turn off code coverage in VHDL subprograms. Default is on.
; CoverageNoSub = 0
; Automatically exclude VHDL case statement default branches.
; Default is to not exclude.
; CoverExcludeDefault = 1
; Turn on code coverage in VHDL generate blocks. Default is off.
; CoverGenerate = 1
; Use this directory for compiler temporary files instead of "work/_temp"
; CompilerTempDir = /tmp
[vlog]
; Turn off inclusion of debugging info within design units.
; Default is to include debugging info.
; NoDebug = 1
; Turn on `protect compiler directive processing.
; Default is to ignore `protect directives.
; Protect = 1
; Turn off "Loading..." messages. Default is messages on.
; Quiet = 1
; Turn on Verilog hazard checking (order-dependent accessing of global vars).
; Default is off.
; Hazard = 1
; Turn on converting regular Verilog identifiers to uppercase. Allows case
; insensitivity for module names. Default is no conversion.
; UpCase = 1
; Activate optimizations on expressions that do not involve signals,
; waits, or function/procedure/task invocations. Default is off.
; ScalarOpts = 1
; Turns on lint-style checking.
; Show_Lint = 1
; Show source line containing error. Default is off.
; Show_source = 1
; Turn on bad option warning. Default is off.
; Show_BadOptionWarning = 1
; Revert back to IEEE 1364-1995 syntax, default is 0 (off).
vlog95compat = 0
; Turn off PSL warning messages. Default is to show warnings.
; Show_PslChecksWarnings = 0
; Enable parsing of embedded PSL assertions. Default is enabled.
; EmbeddedPsl = 0
; Set the threshold for automatically identifying sparse Verilog memories.
; A memory with depth equal to or more than the sparse memory threshold gets
; marked as sparse automatically, unless specified otherwise in source code.
; The default is 0 (i.e. no memory is automatically given sparse status)
; SparseMemThreshold = 1048576
; Set the maximum number of iterations permitted for a generate loop.
; Restricting this permits the implementation to recognize infinite
; generate loops.
; GenerateLoopIterationMax = 100000
; Set the maximum depth permitted for a recursive generate instantiation.
; Restricting this permits the implementation to recognize infinite
; recursions.
; GenerateRecursionDepthMax = 200
; Run the 0in tools from within the simulator.
; Default value set to 0. Please set it to 1 to invoke 0in.
; VlogZeroIn = 1
; Set the options to be passed to the 0in tools.
; Default value set to "". Please set it to appropriate options needed.
; VlogZeroInOptions = ""
; Run the 0in tools from within the simulator.
; Default value set to 0. Please set it to 1 to invoke 0in.
; VoptZeroIn = 1
; Set the options to be passed to the 0in tools.
; Default value set to "". Please set it to appropriate options needed.
; VoptZeroInOptions = ""
; Set the option to treat all files specified in a vlog invocation as a
; single compilation unit. The default value is set to 0 which will treat
; each file as a separate compilation unit as specified in the P1800 draft standard.
; MultiFileCompilationUnit = 1
; Automatically exclude Verilog case statement default branches.
; Default is to not exclude.
; CoverExcludeDefault = 1
; Turn on code coverage in VLOG generate blocks. Default is off.
; CoverGenerate = 1
[sccom]
; Enable use of SCV include files and library. Default is off.
; UseScv = 1
; Add C++ compiler options to the sccom command line by using this variable.
; CppOptions = -g
; Use custom C++ compiler located at this path rather than the default path.
; The path should point directly at a compiler executable.
; CppPath = /usr/bin/g++
; Enable verbose messages from sccom. Default is off.
; SccomVerbose = 1
; sccom logfile. Default is no logfile.
; SccomLogfile = sccom.log
; Enable use of SC_MS include files and library. Default is off.
; UseScMs = 1
[vsim]
; vopt flow
; Set to turn on automatic optimization of a design.
; Default is on
VoptFlow = 1
; vopt automatic SDF
; If automatic design optimization is on, enables automatic compilation
; of SDF files.
; Default is on, uncomment to turn off.
; VoptAutoSDFCompile = 0
; Simulator resolution
; Set to fs, ps, ns, us, ms, or sec with optional prefix of 1, 10, or 100.
resolution = 1ps
; User time unit for run commands
; Set to default, fs, ps, ns, us, ms, or sec. The default is to use the
; unit specified for Resolution. For example, if Resolution is 100ps,
; then UserTimeUnit defaults to ps.
; Should generally be set to default.
UserTimeUnit = default
; Default run length
RunLength = 100 ps
; Maximum iterations that can be run without advancing simulation time
IterationLimit = 5000
; Control PSL and Verilog Assume directives during simulation
; Set SimulateAssumeDirectives = 0 to disable assume being simulated as asserts
; Set SimulateAssumeDirectives = 1 to enable assume simulation as asserts
; SimulateAssumeDirectives = 1
; Control the simulation of PSL and SVA
; These switches can be overridden by the vsim command line switches:
; -psl, -nopsl, -sva, -nosva.
; Set SimulatePSL = 0 to disable PSL simulation
; Set SimulatePSL = 1 to enable PSL simulation (default)
; SimulatePSL = 1
; Set SimulateSVA = 0 to disable SVA simulation
; Set SimulateSVA = 1 to enable concurrent SVA simulation (default)
; SimulateSVA = 1
; Directives to license manager can be set either as single value or as
; space separated multi-values:
; vhdl Immediately reserve a VHDL license
; vlog Immediately reserve a Verilog license
; plus Immediately reserve a VHDL and Verilog license
; nomgc Do not look for Mentor Graphics Licenses
; nomti Do not look for Model Technology Licenses
; noqueue Do not wait in the license queue when a license is not available
; viewsim Try for viewer license but accept simulator license(s) instead
; of queuing for viewer license (PE ONLY)
; noviewer Disable checkout of msimviewer and vsim-viewer license
; features (PE ONLY)
; noslvhdl Disable checkout of qhsimvh and vsim license features
; noslvlog Disable checkout of qhsimvl and vsimvlog license features
; nomix Disable checkout of msimhdlmix and hdlmix license features
; nolnl Disable checkout of msimhdlsim and hdlsim license features
; mixedonly Disable checkout of qhsimvh,qhsimvl,vsim,vsimvlog license
; features
; lnlonly Disable checkout of qhsimvh,qhsimvl,vsim,vsimvlog,msimhdlmix,
; hdlmix license features
; Single value:
; License = plus
; Multi-value:
; License = noqueue plus
; Stop the simulator after a VHDL/Verilog immediate assertion message
; 0 = Note 1 = Warning 2 = Error 3 = Failure 4 = Fatal
BreakOnAssertion = 3
; VHDL assertion Message Format
; %S - Severity Level
; %R - Report Message
; %T - Time of assertion
; %D - Delta
; %I - Instance or Region pathname (if available)
; %i - Instance pathname with process
; %O - Process name
; %K - Kind of object path is to return: Instance, Signal, Process or Unknown
; %P - Instance or Region path without leaf process
; %F - File
; %L - Line number of assertion or, if assertion is in a subprogram, line
; from which the call is made
; %% - Print '%' character
; If specific format for assertion level is defined, use its format.
; If specific format is not defined for assertion level:
; - and if failure occurs during elaboration, use AssertionFormatBreakLine;
; - and if assertion triggers a breakpoint (controlled by BreakOnAssertion
; level), use AssertionFormatBreak;
; - otherwise, use AssertionFormat.
; AssertionFormatBreakLine = "** %S: %R\n Time: %T Iteration: %D %K: %i File: %F Line: %L\n"
; AssertionFormatBreak = "** %S: %R\n Time: %T Iteration: %D %K: %i File: %F\n"
; AssertionFormat = "** %S: %R\n Time: %T Iteration: %D%I\n"
; AssertionFormatNote = "** %S: %R\n Time: %T Iteration: %D%I\n"
; AssertionFormatWarning = "** %S: %R\n Time: %T Iteration: %D%I\n"
; AssertionFormatError = "** %S: %R\n Time: %T Iteration: %D %K: %i File: %F\n"
; AssertionFormatFail = "** %S: %R\n Time: %T Iteration: %D %K: %i File: %F\n"
; AssertionFormatFatal = "** %S: %R\n Time: %T Iteration: %D %K: %i File: %F\n"
; Assertion File - alternate file for storing VHDL/PSL/Verilog assertion messages
; AssertFile = assert.log
; Simulation Breakpoint messages
; This flag controls the display of function names when reporting the location
; where the simulator stops do to a breakpoint or fatal error.
; Example w/function name: # Break in Process ctr at counter.vhd line 44
; Example wo/function name: # Break at counter.vhd line 44
ShowFunctions = 1
; Default radix for all windows and commands.
; Set to symbolic, ascii, binary, octal, decimal, hex, unsigned
DefaultRadix = hexadecimal
; VSIM Startup command
; Startup = do startup.do
; File for saving command transcript
TranscriptFile = transcript
; File for saving command history
; CommandHistory = cmdhist.log
; Specify whether paths in simulator commands should be described
; in VHDL or Verilog format.
; For VHDL, PathSeparator = /
; For Verilog, PathSeparator = .
; Must not be the same character as DatasetSeparator.
; PathSeparator = /
; Specify the dataset separator for fully rooted contexts.
; The default is ':'. For example: sim:/top
; Must not be the same character as PathSeparator.
DatasetSeparator = :
; Specify a unique path separator for the Signal Spy set of functions.
; The default will be to use the PathSeparator variable.
; Must not be the same character as DatasetSeparator.
; SignalSpyPathSeparator = /
; Disable VHDL assertion messages
; IgnoreNote = 1
; IgnoreWarning = 1
; IgnoreError = 1
; IgnoreFailure = 1
; Disable System Verilog assertion messages
; Info and Warning are disabled by default
; IgnoreSVAInfo = 0
; IgnoreSVAWarning = 0
; IgnoreSVAError = 1
; IgnoreSVAFatal = 1
; Default force kind. May be freeze, drive, deposit, or default
; or in other terms, fixed, wired, or charged.
; A value of "default" will use the signal kind to determine the
; force kind, drive for resolved signals, freeze for unresolved signals
; DefaultForceKind = freeze
; If zero, open files when elaborated; otherwise, open files on
; first read or write. Default is 0.
; DelayFileOpen = 1
; Control VHDL files opened for write.
; 0 = Buffered, 1 = Unbuffered
UnbufferedOutput = 0
; Control the number of VHDL files open concurrently.
; This number should always be less than the current ulimit
; setting for max file descriptors.
; 0 = unlimited
ConcurrentFileLimit = 40
; Control the number of hierarchical regions displayed as
; part of a signal name shown in the Wave window.
; A value of zero tells VSIM to display the full name.
; The default is 0.
; WaveSignalNameWidth = 0
; Turn off warnings when changing VHDL constants and generics
; Default is 1 to generate warning messages
; WarnConstantChange = 0
; Turn off warnings from the std_logic_arith, std_logic_unsigned
; and std_logic_signed packages.
; StdArithNoWarnings = 1
; Turn off warnings from the IEEE numeric_std and numeric_bit packages.
; NumericStdNoWarnings = 1
; Control the format of the (VHDL) FOR generate statement label
; for each iteration. Do not quote it.
; The format string here must contain the conversion codes %s and %d,
; in that order, and no other conversion codes. The %s represents
; the generate_label; the %d represents the generate parameter value
; at a particular generate iteration (this is the position number if
; the generate parameter is of an enumeration type). Embedded whitespace
; is allowed (but discouraged); leading and trailing whitespace is ignored.
; Application of the format must result in a unique scope name over all
; such names in the design so that name lookup can function properly.
; GenerateFormat = %s__%d
; Specify whether checkpoint files should be compressed.
; The default is 1 (compressed).
; CheckpointCompressMode = 0
; Specify whether to enable SystemVerilog DPI out-of-the-blue call.
; Out-of-the-blue call refers to a SystemVerilog export function call
; directly from a C function that don't have the proper context setup
; as done in DPI-C import C functions. When this is enabled, one can
; call a DPI export function (but not task) from any C code.
; The default is 0 (disabled).
; DpiOutOfTheBlue = 1
; List of dynamically loaded objects for Verilog PLI applications
; Veriuser = veriuser.sl
Veriuser = $MODEL_TECH/libswiftpli.sl;;$DENALI/mtipli.so
; Specify default options for the restart command. Options can be one
; or more of: -force -nobreakpoint -nolist -nolog -nowave -noassertions
; DefaultRestartOptions = -force
; HP-UX 10.20 ONLY - Enable memory locking to speed up large designs
; (> 500 megabyte memory footprint). Default is disabled.
; Specify number of megabytes to lock.
; LockedMemory = 1000
; HP-UX 11.00 ONLY - Use /usr/lib/libCsup_v2.sl for shared object loading.
; This is necessary when C++ files have been compiled with aCC's -AA option.
; The default behavior is to use /usr/lib/libCsup.sl.
; UseCsupV2 = 1
; Turn on (1) or off (0) WLF file compression.
; The default is 1 (compress WLF file).
; WLFCompress = 0
; Specify whether to save all design hierarchy (1) in the WLF file
; or only regions containing logged signals (0).
; The default is 0 (save only regions with logged signals).
; WLFSaveAllRegions = 1
; WLF file time limit. Limit WLF file by time, as closely as possible,
; to the specified amount of simulation time. When the limit is exceeded
; the earliest times get truncated from the file.
; If both time and size limits are specified the most restrictive is used.
; UserTimeUnits are used if time units are not specified.
; The default is 0 (no limit). Example: WLFTimeLimit = {100 ms}
; WLFTimeLimit = 0
; WLF file size limit. Limit WLF file size, as closely as possible,
; to the specified number of megabytes. If both time and size limits
; are specified then the most restrictive is used.
; The default is 0 (no limit).
; WLFSizeLimit = 1000
; Specify whether or not a WLF file should be deleted when the
; simulation ends. A value of 1 will cause the WLF file to be deleted.
; The default is 0 (do not delete WLF file when simulation ends).
; WLFDeleteOnQuit = 1
; Specify whether or not a WLF file should be optimized during
; simulation. If set to 0, the WLF file will not be optimized.
; The default is 1, optimize the WLF file.
; WLFOptimize = 0
; Specify the name of the WLF file.
; The default is vsim.wlf
; WLFFilename = vsim.wlf
; WLF reader cache size limit. Specifies the internal WLF file cache size,
; in megabytes, for EACH open WLF file. A value of 0 turns off the
; WLF cache.
; The default setting is enabled to 256M per open WLF file.
; WLFCacheSize = 1000
; Specify the WLF file event collapse mode.
; 0 = Preserve all events and event order. (same as -wlfnocollapse)
; 1 = Only record values of logged objects at the end of a simulator iteration.
; (same as -wlfcollapsedelta)
; 2 = Only record values of logged objects at the end of a simulator time step.
; (same as -wlfcollapsetime)
; The default is 1.
; WLFCollapseMode = 0
; Turn on/off undebuggable SystemC type warnings. Default is on.
; ShowUndebuggableScTypeWarning = 0
; Turn on/off unassociated SystemC name warnings. Default is off.
; ShowUnassociatedScNameWarning = 1
; Set SystemC default time unit.
; Set to fs, ps, ns, us, ms, or sec with optional
; prefix of 1, 10, or 100. The default is 1 ns.
; The ScTimeUnit value is honored if it is coarser than Resolution.
; If ScTimeUnit is finer than Resolution, it is set to the value
; is 10 ns and ScTimeUnit is ns, then the default time unit will be 10 ns.
ScTimeUnit = ns
; Set the SCV relationship name that will be used to identify phase
; relations. If the name given to a transactor relation matches this
; name, the transactions involved will be treated as phase transactions
ScvPhaseRelationName = mti_phase
; Do not exit when executing sc_stop().
; If this is enabled, the control will be returned to the user before exiting
; the simulation. This can make some cleanup tasks easier before kernel exits.
; The default is off.
; NoExitOnScStop = 1
; Run simulator in assertion debug mode. Default is off.
; AssertionDebug = 1
; Turn on/off PSL/SVA concurrent assertion pass enable. Default is on.
; AssertionPassEnable = 0
; Turn on/off PSL/SVA concurrent assertion fail enable. Default is on.
; AssertionFailEnable = 0
; Set PSL/SVA concurrent assertion pass limit. Default is -1.
; Any positive integer, -1 for infinity.
; AssertionPassLimit = 1
; Set PSL/SVA concurrent assertion fail limit. Default is -1.
; Any positive integer, -1 for infinity.
; AssertionFailLimit = 1
; Turn on/off PSL concurrent assertion pass log. Default is off.
; The flag does not affect SVA
; AssertionPassLog = 1
; Turn on/off PSL concurrent assertion fail log. Default is on.
; The flag does not affect SVA
; AssertionFailLog = 0
; Set action type for PSL/SVA concurrent assertion fail action. Default is continue.
; 0 = Continue 1 = Break 2 = Exit
; AssertionFailAction = 1
; Turn on/off code coverage
; CodeCoverage = 0
; Count all code coverage condition and expression truth table rows that match.
; CoverCountAll = 1
; Turn on/off all PSL/SVA cover directive enables. Default is on.
; CoverEnable = 0
; Turn on/off PSL/SVA cover log. Default is off.
; CoverLog = 1
; Set "at_least" value for all PSL/SVA cover directives. Default is 1.
; CoverAtLeast = 2
; Set "limit" value for all PSL/SVA cover directives. Default is -1.
; Any positive integer, -1 for infinity.
; CoverLimit = 1
; Specify the coverage database filename. Default is "" (i.e. database is NOT automatically saved on close).
; UCDBFilename = vsim.ucdb
; Set weight for all PSL/SVA cover directives. Default is 1.
; CoverWeight = 2
; Check vsim plusargs. Default is 0 (off).
; 0 = Don't check plusargs
; 1 = Warning on unrecognized plusarg
; 2 = Error and exit on unrecognized plusarg
; CheckPlusargs = 1
; Load the specified shared objects with the RTLD_GLOBAL flag.
; This gives global visibility to all symbols in the shared objects,
; meaning that subsequently loaded shared objects can bind to symbols
; in the global shared objects. The list of shared objects should
; be whitespace delimited. This option is not supported on the
; Windows or AIX platforms.
; GlobalSharedObjectList = example1.so example2.so example3.so
; Run the 0in tools from within the simulator.
; Default value set to 0. Please set it to 1 to invoke 0in.
; VsimZeroIn = 1
; Set the options to be passed to the 0in tools.
; Default value set to "". Please set it to appropriate options needed.
; VsimZeroInOptions = ""
; Initial seed for the Random Number Generator (RNG) of the root thread (SystemVerilog).
; Sv_Seed = 0
; Maximum size of dynamic arrays that are resized during randomize().
; The default is 1000. A value of 0 indicates no limit.
; SolveArrayResizeMax = 1000
; Error message severity when randomize() failure is detected (SystemVerilog).
; The default is 0 (no error).
; 0 = No error 1 = Warning 2 = Error 3 = Failure 4 = Fatal
; SolveFailSeverity = 0
; Enable/disable debug information for randomize() failures (SystemVerilog).
; The default is 0 (disabled). Set to 1 to enable.
; SolveFailDebug = 0
; When SolveFailDebug is enabled, this value specifies the maximum number of
; constraint subsets that will be tested for conflicts.
; The default is 0 (no limit).
; SolveFailDebugLimit = 0
; When SolveFailDebug is eanbled, this value specifies the maximum size of
; constraint subsets that will be tested for conflicts.
; The default value is 0 (no limit).
; SolveFailDebugMaxSet = 0
; Specify random sequence compatiblity with a prior letter release. This
; option is used to get the same random sequences during simulation as
; as a prior letter release. Only prior letter releases (of the current
; number release) are allowed.
; Note: To achieve the same random sequences, solver optimizations and/or
; bug fixes introduced since the specified release may be disabled -
; yielding the performance / behavior of the prior release.
; Default value set to "" (random compatibility not required).
; SolveRev = ""
; Environment variable expansion of command line arguments has been depricated
; in favor shell level expansion. Universal environment variable expansion
; inside -f files is support and continued support for MGC Location Maps provide
; alternative methods for handling flexible pathnames.
; The following line may be uncommented and the value set to 1 to re-enable this
; deprecated behavior. The default value is 0.
; DeprecatedEnvironmentVariableExpansion = 0
; Retroactive Recording uses a limited number of private data channels in the WLF
; file. Too many channels degrade WLF performance. If the limit is reached,
; simulation ends with a fatal error. You may change this limit as needed, but be
; aware of the implications of too many channels. The value must be an integer
; greater than or equal to zero, where zero disables all retroactive recording.
; RetroChannelLimit = 20
; Options to give vopt when code coverage is turned on.
; Default is "+acc=lprnb -opt=-merge -opt=-suppressAlways"
; VoptCoverageOptions = +acc=lprnb -opt=-merge -opt=-suppressAlways
[lmc]
; The simulator's interface to Logic Modeling's SmartModel SWIFT software
libsm = $MODEL_TECH/libsm.sl
; The simulator's interface to Logic Modeling's SmartModel SWIFT software (Windows NT)
; libsm = $MODEL_TECH/libsm.dll
; Logic Modeling's SmartModel SWIFT software (HP 9000 Series 700)
; libswift = $LMC_HOME/lib/hp700.lib/libswift.sl
; Logic Modeling's SmartModel SWIFT software (IBM RISC System/6000)
; libswift = $LMC_HOME/lib/ibmrs.lib/swift.o
; Logic Modeling's SmartModel SWIFT software (Sun4 Solaris)
; libswift = $LMC_HOME/lib/sun4Solaris.lib/libswift.so
; Logic Modeling's SmartModel SWIFT software (Windows NT)
; libswift = $LMC_HOME/lib/pcnt.lib/libswift.dll
; Logic Modeling's SmartModel SWIFT software (Linux)
libswift = $LMC_HOME/lib/x86_linux.lib/libswift.so
; The simulator's interface to Logic Modeling's hardware modeler SFI software
libhm = $MODEL_TECH/libhm.sl
; The simulator's interface to Logic Modeling's hardware modeler SFI software (Windows NT)
; libhm = $MODEL_TECH/libhm.dll
; Logic Modeling's hardware modeler SFI software (HP 9000 Series 700)
; libsfi = <sfi_dir>/lib/hp700/libsfi.sl
; Logic Modeling's hardware modeler SFI software (IBM RISC System/6000)
; libsfi = <sfi_dir>/lib/rs6000/libsfi.a
; Logic Modeling's hardware modeler SFI software (Sun4 Solaris)
; libsfi = <sfi_dir>/lib/sun4.solaris/libsfi.so
; Logic Modeling's hardware modeler SFI software (Windows NT)
; libsfi = <sfi_dir>/lib/pcnt/lm_sfi.dll
; Logic Modeling's hardware modeler SFI software (Linux)
; libsfi = <sfi_dir>/lib/linux/libsfi.so
[msg_system]
; Change a message severity or suppress a message.
; The format is: <msg directive> = <msg number>[,<msg number>...]
; Examples:
; note = 3009
; warning = 3033
; error = 3010,3016
; fatal = 3016,3033
; suppress = 3009,3016,3043
; The command verror <msg number> can be used to get the complete
; description of a message.
; Control transcripting of elaboration/runtime messages.
; The default is to have messages appear in the transcript and
; recorded in the wlf file (messages that are recorded in the
; wlf file can be viewed in the MsgViewer). The other settings
; are to send messages only to the transcript or only to the
; wlf file. The valid values are
; both {default}
; tran {transcript only}
; wlf {wlf file only}
; msgmode = both
[Project]
Project_Version = 6
Project_DefaultLib = work
Project_SortMethod = unused
Project_Files_Count = 0
Project_Sim_Count = 0
Project_Folder_Count = 0
Echo_Compile_Output = 0
Save_Compile_Report = 1
Project_Opt_Count = 0
ForceSoftPaths = 0
ReOpenSourceFiles = 1
VERILOG_DoubleClick = Edit
VERILOG_CustomDoubleClick =
VHDL_DoubleClick = Edit
VHDL_CustomDoubleClick =
PSL_DoubleClick = Edit
PSL_CustomDoubleClick =
TEXT_DoubleClick = Edit
TEXT_CustomDoubleClick =
SYSTEMC_DoubleClick = Edit
SYSTEMC_CustomDoubleClick =
TCL_DoubleClick = Edit
TCL_CustomDoubleClick =
MACRO_DoubleClick = Edit
MACRO_CustomDoubleClick =
VCD_DoubleClick = Edit
VCD_CustomDoubleClick =
SDF_DoubleClick = Edit
SDF_CustomDoubleClick =
XML_DoubleClick = Edit
XML_CustomDoubleClick =
LOGFILE_DoubleClick = Edit
LOGFILE_CustomDoubleClick =
EditorState = {tabbed horizontal 1}
Project_Major_Version = 6
Project_Minor_Version = 2
-------------------------------------------------------------------------------
-- Title : A sample GPIO port (wbgen2 example)
-- Project :
-------------------------------------------------------------------------------
-- File : gpio_port.vhdl
-- Author : T.W.
-- Company :
-- Created : 2010-02-22
-- Last update: 2010-02-22
-- Platform :
-- Standard : VHDL'87
-------------------------------------------------------------------------------
-- Description:
-------------------------------------------------------------------------------
-- Copyright (c) 2010 T.W.
-------------------------------------------------------------------------------
-- Revisions :
-- Date Version Author Description
-- 2010-02-22 1.0 slayer Created
-------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
library work;
entity gpio_port is
port (
rst_n_i : in std_logic;
wb_clk_i : in std_logic;
wb_addr_i : in std_logic_vector(2 downto 0);
wb_data_i : in std_logic_vector(31 downto 0);
wb_data_o : out std_logic_vector(31 downto 0);
wb_cyc_i : in std_logic;
wb_sel_i : in std_logic;
wb_stb_i : in std_logic;
wb_we_i : in std_logic;
wb_ack_o : out std_logic;
-- our port :)
gpio_pins_b : inout std_logic_vector(31 downto 0)
);
end gpio_port;
architecture syn of gpio_port is
component wb_slave_gpio_port
port (
rst_n_i : in std_logic;
wb_clk_i : in std_logic;
wb_addr_i : in std_logic_vector(2 downto 0);
wb_data_i : in std_logic_vector(31 downto 0);
wb_data_o : out std_logic_vector(31 downto 0);
wb_cyc_i : in std_logic;
wb_sel_i : in std_logic;
wb_stb_i : in std_logic;
wb_we_i : in std_logic;
wb_ack_o : out std_logic;
gpio_ddr_o : out std_logic_vector(31 downto 0);
gpio_psr_i : in std_logic_vector(31 downto 0);
gpio_pdr_o : out std_logic_vector(31 downto 0);
gpio_pdr_wr_o : out std_logic;
gpio_sopr_o : out std_logic_vector(31 downto 0);
gpio_sopr_wr_o : out std_logic;
gpio_copr_o : out std_logic_vector(31 downto 0);
gpio_copr_wr_o : out std_logic);
end component;
signal gpio_ddr : std_logic_vector(31 downto 0);
signal gpio_psr : std_logic_vector(31 downto 0);
signal gpio_pdr : std_logic_vector(31 downto 0);
signal gpio_pdr_wr : std_logic;
signal gpio_sopr : std_logic_vector(31 downto 0);
signal gpio_sopr_wr : std_logic;
signal gpio_copr : std_logic_vector(31 downto 0);
signal gpio_copr_wr : std_logic;
-- regsiter containing current output state
signal gpio_reg : std_logic_vector(31 downto 0);
-- registers for synchronization of input pins
signal gpio_pins_sync1 : std_logic_vector(31 downto 0);
signal gpio_pins_sync0 : std_logic_vector(31 downto 0);
begin -- syn
wb_slave : wb_slave_gpio_port
port map (
rst_n_i => rst_n_i,
wb_clk_i => wb_clk_i,
wb_addr_i => wb_addr_i,
wb_data_i => wb_data_i,
wb_data_o => wb_data_o,
wb_cyc_i => wb_cyc_i,
wb_sel_i => wb_sel_i,
wb_stb_i => wb_stb_i,
wb_we_i => wb_we_i,
wb_ack_o => wb_ack_o,
gpio_ddr_o => gpio_ddr,
gpio_psr_i => gpio_pins_sync1,
gpio_pdr_o => gpio_pdr,
gpio_pdr_wr_o => gpio_pdr_wr,
gpio_sopr_o => gpio_sopr,
gpio_sopr_wr_o => gpio_sopr_wr,
gpio_copr_o => gpio_copr,
gpio_copr_wr_o => gpio_copr_wr);
process (wb_clk_i, rst_n_i)
begin -- process
if(rst_n_i = '0') then
gpio_reg <= (others => '0');
elsif rising_edge(wb_clk_i) then
if(gpio_pdr_wr = '1') then -- write operation to "PDR" register -
-- set the new values of GPIO outputs
gpio_reg <= gpio_pdr;
end if;
if(gpio_sopr_wr = '1') then -- write to "SOPR" reg - set ones
for i in 0 to 31 loop
if(gpio_sopr(i) = '1') then
gpio_reg(i) <= '1';
end if;
end loop;
end if;
if(gpio_copr_wr = '1') then -- write to "COPR" reg - set zeros
for i in 0 to 31 loop
if(gpio_copr(i) = '1') then
gpio_reg(i) <= '0';
end if;
end loop;
end if;
end if;
end process;
-- synchronizing process for input pins
synchronize_input_pins : process (wb_clk_i, rst_n_i)
begin -- process
if(rst_n_i = '0') then
gpio_pins_sync0 <= (others => '0');
gpio_pins_sync1 <= (others => '0');
elsif rising_edge(wb_clk_i) then
gpio_pins_sync0 <= gpio_pins_b;
gpio_pins_sync1 <= gpio_pins_sync0;
end if;
end process;
-- generate the tristate buffers for I/O pins
gen_tristates : for i in 0 to 31 generate
gpio_pins_b(i) <= gpio_reg(i) when gpio_ddr(i) = '1' else 'Z';
end generate gen_tristates;
end syn;
-- here comes our peripheral definition
peripheral {
-- short (human-readable) name for the peripheral.
name = "GPIO Port";
-- a longer description, if you want
description = "A sample 32-bit general-purpose bidirectional I/O port, explaining how to use SLV and PASS-THROUGH registers.";
-- name of the target VHDL entity to be generated
hdl_entity = "wb_slave_gpio_port";
-- prefix for all the generated ports belonging to our peripheral
prefix = "gpio";
-- Pin direction register. Readable and writable from the bus, readable from the device.
reg {
name = "Pin direction register";
description = "A register defining the direction of the GPIO potr pins.";
prefix = "ddr";
-- a single, anonymous field (no prefix) of type SLV.
field {
name = "Pin directions";
description = "Each bit in this register defines the direction of corresponding pin of the GPIO port. 1 means the pin is an OUTPUT, 0 means the pin is an INPUT";
-- there is (deliberately) no prefix defined for this field. Since we have only one field in the register "ddr", we can omit the prefix - wbgen2 will produce signal names
-- containing only prefixes of the peripheral and the parent register.
-- type of our field - std_logic_vector
type = SLV;
-- size - we want 32-bits wide port :)
size = 32;
-- the field will be readable/writable from the Wishbone bus
access_bus = READ_WRITE;
-- .. and readable from the peripheral
access_dev = READ_ONLY;
};
};
-- Pin input state register. Readable the bus, writable from the device.
reg {
name = "Pin input state register";
description = "A register containing the current state of input pins.";
prefix = "psr";
-- a single, anonymous field (no prefix) of type SLV.
field {
name = "Pin input state";
description = "Each bit in this register reflects the state of corresponding GPIO port pin.";
-- no prefix here as well (see above)
-- type of our field - std_logic_vector
type = SLV;
-- size - we want 32-bits wide port :)
size = 32;
-- the field will be readable from the Wishbone bus
access_bus = READ_ONLY;
-- .. and writable from the peripheral
access_dev = WRITE_ONLY;
};
};
-- Port output register. Shows how to use PASS-THROUGH regs
reg {
name = "Port output register";
description = "Register containing the output pin state.";
prefix = "pdr";
-- a single, anonymous field (no prefix) of type PASS-THROUGH.
field {
name = "Port output value";
-- the description isn't really necessary here :)
-- description = "Writing '1' sets the corresponding GPIO pin to '1'";
-- type of our field - PASS_THROUGH. In this mode, the slave core is not storing the register value. Instead it provides the raw value
-- (taken from the wishbone data input) and a strobe signal, asserted for single clock cycle upon write operation to the register.
-- The wishbone data input will be fed directly to gpio_pdr_o and each write operation to this register will generate a single-cycle positive
-- pulse on gpio_pdr_wr_o signal.
type = PASS_THROUGH;
size = 32;
-- access flags don't apply for the PASS-THROUGH regsiters, so we can omit them.
};
};
-- Set output register. Shows how to use PASS-THROUGH regs
reg {
name = "Set output pin register";
description = "Writing '1' sets the corresponding GPIO pin to '1'";
prefix = "sopr";
-- Our driver developer would want these two (SOPR and COPR) registers' addresses to be aligned to multiple of 4 :)
align = 4;
field {
name = "Set output pin register";
type = PASS_THROUGH;
size = 32;
};
};
-- Clear output register. Designed identically as the previous reg.
reg {
name = "Clear output pin register";
description = "Writing '1' clears the corresponding GPIO pin";
prefix = "copr";
field {
name = "Clear output pin register";
type = PASS_THROUGH;
size = 32;
};
};
};
`define ADDR_GPIO_DDR 3'h0
`define ADDR_GPIO_PSR 3'h1
`define ADDR_GPIO_PDR 3'h2
`define ADDR_GPIO_SOPR 3'h4
`define ADDR_GPIO_COPR 3'h5
vlib work
../../wbgen2.lua gpio_port.wb -vo ./output/wb_slave_gpio_port.vhdl --gen-vlog-constants ./output/vlog_constants.v
vcom ./output/wb_slave_gpio_port.vhdl
vcom ./gpio_port.vhdl
vlog ./testbench.v
vsim work.main
radix -hexadecimal
do wave.do
run 15us
wave zoomfull
`timescale 1ns/1ps
`define wbclk_period 100
`include "output/vlog_constants.v"
module main;
reg clk=1;
reg rst=0;
always #(`wbclk_period/2) clk <= ~clk;
initial #1000 rst <= 1;
`include "wishbone_stuff.v"
wire [31:0] gpio_pins_b;
reg [31:0] gpio_reg = 32'bz;
gpio_port dut(
.rst_n_i (rst),
.wb_clk_i (clk),
.wb_addr_i (wb_addr[2:0]),
.wb_data_i (wb_data_o),
.wb_data_o (wb_data_i),
.wb_cyc_i (wb_cyc),
.wb_sel_i (wb_sel),
.wb_stb_i (wb_stb),
.wb_we_i (wb_we),
.wb_ack_o (wb_ack),
.gpio_pins_b (gpio_pins_b)
);
assign gpio_pins_b = gpio_reg;
reg[31:0] data;
integer i;
initial begin
#2001; // wait until the DUT is reset
$display("Set half of the pins to outputs, other half to inputs");
wb_write(`ADDR_GPIO_DDR, 32'hffff0000);
$display("Pins state: %b (%x)", gpio_pins_b, gpio_pins_b);
$display("Set every even byte to '1'");
wb_write(`ADDR_GPIO_SOPR, 32'hff00ff00);
$display("Pins state: %b (%x)", gpio_pins_b, gpio_pins_b);
$display("Clear every even bit");
wb_write(`ADDR_GPIO_COPR, 32'h55555555);
$display("Pins state: %b (%x)", gpio_pins_b, gpio_pins_b);
$display("Write an arbitrary value");
wb_write(`ADDR_GPIO_PDR, 32'hdeadbeef);
$display("Pins state: %b (%x)", gpio_pins_b, gpio_pins_b);
$display("Force something tasty on the GPIO input pins");
gpio_reg[15:0] = 16'hcafe;
delay_cycles(1);
$display("Pins state: %b (%x)", gpio_pins_b, gpio_pins_b);
delay_cycles(10); // wait for a while for the sync logic
wb_read(`ADDR_GPIO_PSR, data);
$display("Time for %x!", data[15:0]);
end
endmodule
onerror {resume}
quietly WaveActivateNextPane {} 0
add wave -noupdate -format Logic /main/dut/rst_n_i
add wave -noupdate -format Logic /main/dut/wb_clk_i
add wave -noupdate -format Literal /main/dut/wb_addr_i
add wave -noupdate -format Literal /main/dut/wb_data_i
add wave -noupdate -format Literal /main/dut/wb_data_o
add wave -noupdate -format Logic /main/dut/wb_cyc_i
add wave -noupdate -format Logic /main/dut/wb_sel_i
add wave -noupdate -format Logic /main/dut/wb_stb_i
add wave -noupdate -format Logic /main/dut/wb_we_i
add wave -noupdate -format Logic /main/dut/wb_ack_o
add wave -noupdate -format Literal /main/dut/gpio_pins_b
add wave -noupdate -format Literal /main/dut/gpio_ddr
add wave -noupdate -format Literal /main/dut/gpio_psr
add wave -noupdate -format Literal /main/dut/gpio_pdr
add wave -noupdate -format Logic /main/dut/gpio_pdr_wr
add wave -noupdate -format Literal /main/dut/gpio_sopr
add wave -noupdate -format Logic /main/dut/gpio_sopr_wr
add wave -noupdate -format Literal /main/dut/gpio_copr
add wave -noupdate -format Logic /main/dut/gpio_copr_wr
add wave -noupdate -format Literal /main/dut/gpio_reg
add wave -noupdate -format Literal /main/dut/gpio_pins_sync1
add wave -noupdate -format Literal /main/dut/gpio_pins_sync0
add wave -noupdate -format Logic /main/dut/wb_slave/rst_n_i
add wave -noupdate -format Logic /main/dut/wb_slave/wb_clk_i
add wave -noupdate -format Literal /main/dut/wb_slave/wb_addr_i
add wave -noupdate -format Literal /main/dut/wb_slave/wb_data_i
add wave -noupdate -format Literal /main/dut/wb_slave/wb_data_o
add wave -noupdate -format Logic /main/dut/wb_slave/wb_cyc_i
add wave -noupdate -format Logic /main/dut/wb_slave/wb_sel_i
add wave -noupdate -format Logic /main/dut/wb_slave/wb_stb_i
add wave -noupdate -format Logic /main/dut/wb_slave/wb_we_i
add wave -noupdate -format Logic /main/dut/wb_slave/wb_ack_o
add wave -noupdate -format Logic /main/dut/wb_slave/gpio_async_clk_i
add wave -noupdate -format Literal /main/dut/wb_slave/gpio_ddr_o
add wave -noupdate -format Literal /main/dut/wb_slave/gpio_psr_i
add wave -noupdate -format Literal /main/dut/wb_slave/gpio_pdr_o
add wave -noupdate -format Logic /main/dut/wb_slave/gpio_pdr_wr_o
add wave -noupdate -format Literal /main/dut/wb_slave/gpio_sopr_o
add wave -noupdate -format Logic /main/dut/wb_slave/gpio_sopr_wr_o
add wave -noupdate -format Literal /main/dut/wb_slave/gpio_copr_o
add wave -noupdate -format Logic /main/dut/wb_slave/gpio_copr_wr_o
add wave -noupdate -format Literal /main/dut/wb_slave/gpio_ddr_int
add wave -noupdate -format Logic /main/dut/wb_slave/gpio_ddr_swb
add wave -noupdate -format Logic /main/dut/wb_slave/gpio_ddr_swb_delay
add wave -noupdate -format Logic /main/dut/wb_slave/gpio_ddr_swb_s0
add wave -noupdate -format Logic /main/dut/wb_slave/gpio_ddr_swb_s1
add wave -noupdate -format Logic /main/dut/wb_slave/gpio_ddr_swb_s2
add wave -noupdate -format Literal /main/dut/wb_slave/gpio_psr_int
add wave -noupdate -format Logic /main/dut/wb_slave/gpio_psr_lwb
add wave -noupdate -format Logic /main/dut/wb_slave/gpio_psr_lwb_delay
add wave -noupdate -format Logic /main/dut/wb_slave/gpio_psr_lwb_in_progress
add wave -noupdate -format Logic /main/dut/wb_slave/gpio_psr_lwb_s0
add wave -noupdate -format Logic /main/dut/wb_slave/gpio_psr_lwb_s1
add wave -noupdate -format Logic /main/dut/wb_slave/gpio_psr_lwb_s2
add wave -noupdate -format Logic /main/dut/wb_slave/gpio_pdr_wr_int
add wave -noupdate -format Logic /main/dut/wb_slave/gpio_pdr_wr_int_delay
add wave -noupdate -format Logic /main/dut/wb_slave/gpio_pdr_wr_sync0
add wave -noupdate -format Logic /main/dut/wb_slave/gpio_pdr_wr_sync1
add wave -noupdate -format Logic /main/dut/wb_slave/gpio_pdr_wr_sync2
add wave -noupdate -format Logic /main/dut/wb_slave/gpio_sopr_wr_int
add wave -noupdate -format Logic /main/dut/wb_slave/gpio_sopr_wr_int_delay
add wave -noupdate -format Logic /main/dut/wb_slave/gpio_sopr_wr_sync0
add wave -noupdate -format Logic /main/dut/wb_slave/gpio_sopr_wr_sync1
add wave -noupdate -format Logic /main/dut/wb_slave/gpio_sopr_wr_sync2
add wave -noupdate -format Logic /main/dut/wb_slave/gpio_copr_wr_int
add wave -noupdate -format Logic /main/dut/wb_slave/gpio_copr_wr_int_delay
add wave -noupdate -format Logic /main/dut/wb_slave/gpio_copr_wr_sync0
add wave -noupdate -format Logic /main/dut/wb_slave/gpio_copr_wr_sync1
add wave -noupdate -format Logic /main/dut/wb_slave/gpio_copr_wr_sync2
add wave -noupdate -format Logic /main/dut/wb_slave/wb_ack_regbank
add wave -noupdate -format Literal /main/dut/wb_slave/ack_cntr
add wave -noupdate -format Logic /main/dut/wb_slave/ack_in_progress
add wave -noupdate -format Logic /main/dut/wb_slave/tmpbit
add wave -noupdate -format Literal /main/dut/wb_slave/wb_data_out_int
TreeUpdate [SetDefaultTree]
WaveRestoreCursors {{Cursor 1} {0 ps} 0}
configure wave -namecolwidth 333
configure wave -valuecolwidth 100
configure wave -justifyvalue left
configure wave -signalnamewidth 0
configure wave -snapdistance 10
configure wave -datasetprefix 0
configure wave -rowmargin 4
configure wave -childrowmargin 2
configure wave -gridoffset 0
configure wave -gridperiod 1
configure wave -griddelta 40
configure wave -timeline 0
update
WaveRestoreZoom {0 ps} {15750 ns}
reg [31:0] wb_addr, wb_data_o, tmp;
wire [31:0] wb_data_i;
wire wb_ack;
reg wb_sel =0, wb_cyc=0, wb_stb=0, wb_we= 0;
task delay_cycles;
input [31:0] n;
begin
#(n * `wbclk_period);
end
endtask // delay_cycles
task wb_write;
input[31:0] addr;
input [31:0] data;
begin
$display("WB write: addr %x, data %x", addr, data);
wb_sel=1;
wb_stb=1;
wb_cyc=1;
wb_addr = addr;
wb_data_o=data;
wb_we = 1;
delay_cycles(1);
while(wb_ack == 0)
delay_cycles(1);
delay_cycles(1);
wb_cyc = 0;
wb_sel=0;
wb_we=0;
wb_stb=0;
end
endtask // wb_write
task wb_read;
input[31:0] addr;
output [31:0] data;
begin
wb_sel=1;
wb_stb=1;
wb_cyc=1;
wb_addr = addr;
wb_data_o=data;
wb_we = 0;
delay_cycles(1);
while(wb_ack == 0)
delay_cycles(1);
data = wb_data_i;
delay_cycles(1);
wb_cyc = 0;
wb_sel=0;
wb_we=0;
wb_stb=0;
end
endtask // wb_read
; Copyright 2006 Mentor Graphics Corporation
;
; All Rights Reserved.
;
; THIS WORK CONTAINS TRADE SECRET AND PROPRIETARY INFORMATION WHICH IS THE PROPERTY OF
; MENTOR GRAPHICS CORPORATION OR ITS LICENSORS AND IS SUBJECT TO LICENSE TERMS.
;
[Library]
std = $MODEL_TECH/../std
ieee = $MODEL_TECH/../ieee
verilog = $MODEL_TECH/../verilog
vital2000 = $MODEL_TECH/../vital2000/vhdl
std_developerskit = $MODEL_TECH/../std_developerskit
synopsys = $MODEL_TECH/../synopsys
modelsim_lib = $MODEL_TECH/../modelsim_lib
sv_std = $MODEL_TECH/../sv_std
UNISIMS_VER = /opt/Xilinx/10.1/ISE/verilog/mti_se/unisims_ver
UNI9000_VER = /opt/ISE8/verilog/mti_se/uni9000_ver
SIMPRIMS_VER = /opt/Xilinx/10.1/ISE/verilog/mti_se/simprims_ver
XILINXCORELIB_VER = /opt/Xilinx/10.1/ISE/verilog/mti_se/XilinxCoreLib_ver
AIM_VER = /opt/ISE8/verilog/mti_se/abel_ver/aim_ver
CPLD_VER = /opt/ISE8/verilog/mti_se/cpld_ver
UNIMACRO_VER = /opt/Xilinx/10.1/ISE/verilog/mti_se/unimacro_ver
SECUREIP = /opt/Xilinx/10.1/ISE/vhdl/mti_se/secureip
UNISIM = /opt/Xilinx/10.1/ISE/vhdl/mti_se/unisim
UNIMACRO = /opt/Xilinx/10.1/ISE/vhdl/mti_se/unimacro
XILINXCORELIB = /opt/Xilinx/10.1/ISE/vhdl/mti_se/XilinxCoreLib
SIMPRIM = /opt/Xilinx/10.1/ISE/vhdl/mti_se/simprim
altera_mf = $MODEL_TECH/../altera/vhdl/altera_mf
altera_primitives = $MODEL_TECH/../altera/vhdl/altera_primitives
lpm = $MODEL_TECH/../altera/vhdl/lpm
sgate = $MODEL_TECH/../altera/vhdl/sgate
cycloneiii = $MODEL_TECH/../altera/vhdl/cycloneiii
work = work
[vcom]
; VHDL93 variable selects language version as the default.
; Default is VHDL-2002.
; Value of 0 or 1987 for VHDL-1987.
; Value of 1 or 1993 for VHDL-1993.
; Default or value of 2 or 2002 for VHDL-2002.
VHDL93 = 2002
; Show source line containing error. Default is off.
; Show_source = 1
; Turn off unbound-component warnings. Default is on.
; Show_Warning1 = 0
; Turn off process-without-a-wait-statement warnings. Default is on.
; Show_Warning2 = 0
; Turn off null-range warnings. Default is on.
; Show_Warning3 = 0
; Turn off no-space-in-time-literal warnings. Default is on.
; Show_Warning4 = 0
; Turn off multiple-drivers-on-unresolved-signal warnings. Default is on.
; Show_Warning5 = 0
; Turn off optimization for IEEE std_logic_1164 package. Default is on.
; Optimize_1164 = 0
; Turn on resolving of ambiguous function overloading in favor of the
; "explicit" function declaration (not the one automatically created by
; the compiler for each type declaration). Default is off.
; The .ini file has Explicit enabled so that std_logic_signed/unsigned
; will match the behavior of synthesis tools.
Explicit = 1
; Turn off acceleration of the VITAL packages. Default is to accelerate.
; NoVital = 1
; Turn off VITAL compliance checking. Default is checking on.
; NoVitalCheck = 1
; Ignore VITAL compliance checking errors. Default is to not ignore.
; IgnoreVitalErrors = 1
; Turn off VITAL compliance checking warnings. Default is to show warnings.
; Show_VitalChecksWarnings = 0
; Turn off PSL assertion warning messages. Default is to show warnings.
; Show_PslChecksWarnings = 0
; Enable parsing of embedded PSL assertions. Default is enabled.
; EmbeddedPsl = 0
; Keep silent about case statement static warnings.
; Default is to give a warning.
; NoCaseStaticError = 1
; Keep silent about warnings caused by aggregates that are not locally static.
; Default is to give a warning.
; NoOthersStaticError = 1
; Treat as errors:
; case statement static warnings
; warnings caused by aggregates that are not locally static
; Overrides NoCaseStaticError, NoOthersStaticError settings.
; PedanticErrors = 1
; Turn off inclusion of debugging info within design units.
; Default is to include debugging info.
; NoDebug = 1
; Turn off "Loading..." messages. Default is messages on.
; Quiet = 1
; Turn on some limited synthesis rule compliance checking. Checks only:
; -- signals used (read) by a process must be in the sensitivity list
; CheckSynthesis = 1
; Activate optimizations on expressions that do not involve signals,
; waits, or function/procedure/task invocations. Default is off.
; ScalarOpts = 1
; Turns on lint-style checking.
; Show_Lint = 1
; Require the user to specify a configuration for all bindings,
; and do not generate a compile time default binding for the
; component. This will result in an elaboration error of
; 'component not bound' if the user fails to do so. Avoids the rare
; issue of a false dependency upon the unused default binding.
; RequireConfigForAllDefaultBinding = 1
; Perform default binding at compile time.
; Default is to do default binding at load time.
; BindAtCompile=1;
; Inhibit range checking on subscripts of arrays. Range checking on
; scalars defined with subtypes is inhibited by default.
; NoIndexCheck = 1
; Inhibit range checks on all (implicit and explicit) assignments to
; scalar objects defined with subtypes.
; NoRangeCheck = 1
; Run the 0in tools from within the simulator.
; Default value set to 0. Please set it to 1 to invoke 0in.
; VcomZeroIn = 1
; Set the options to be passed to the 0in tools.
; Default value set to "". Please set it to appropriate options needed.
; VcomZeroInOptions = ""
; Turn off code coverage in VHDL subprograms. Default is on.
; CoverageNoSub = 0
; Automatically exclude VHDL case statement default branches.
; Default is to not exclude.
; CoverExcludeDefault = 1
; Turn on code coverage in VHDL generate blocks. Default is off.
; CoverGenerate = 1
; Use this directory for compiler temporary files instead of "work/_temp"
; CompilerTempDir = /tmp
[vlog]
; Turn off inclusion of debugging info within design units.
; Default is to include debugging info.
; NoDebug = 1
; Turn on `protect compiler directive processing.
; Default is to ignore `protect directives.
; Protect = 1
; Turn off "Loading..." messages. Default is messages on.
; Quiet = 1
; Turn on Verilog hazard checking (order-dependent accessing of global vars).
; Default is off.
; Hazard = 1
; Turn on converting regular Verilog identifiers to uppercase. Allows case
; insensitivity for module names. Default is no conversion.
; UpCase = 1
; Activate optimizations on expressions that do not involve signals,
; waits, or function/procedure/task invocations. Default is off.
; ScalarOpts = 1
; Turns on lint-style checking.
; Show_Lint = 1
; Show source line containing error. Default is off.
; Show_source = 1
; Turn on bad option warning. Default is off.
; Show_BadOptionWarning = 1
; Revert back to IEEE 1364-1995 syntax, default is 0 (off).
vlog95compat = 0
; Turn off PSL warning messages. Default is to show warnings.
; Show_PslChecksWarnings = 0
; Enable parsing of embedded PSL assertions. Default is enabled.
; EmbeddedPsl = 0
; Set the threshold for automatically identifying sparse Verilog memories.
; A memory with depth equal to or more than the sparse memory threshold gets
; marked as sparse automatically, unless specified otherwise in source code.
; The default is 0 (i.e. no memory is automatically given sparse status)
; SparseMemThreshold = 1048576
; Set the maximum number of iterations permitted for a generate loop.
; Restricting this permits the implementation to recognize infinite
; generate loops.
; GenerateLoopIterationMax = 100000
; Set the maximum depth permitted for a recursive generate instantiation.
; Restricting this permits the implementation to recognize infinite
; recursions.
; GenerateRecursionDepthMax = 200
; Run the 0in tools from within the simulator.
; Default value set to 0. Please set it to 1 to invoke 0in.
; VlogZeroIn = 1
; Set the options to be passed to the 0in tools.
; Default value set to "". Please set it to appropriate options needed.
; VlogZeroInOptions = ""
; Run the 0in tools from within the simulator.
; Default value set to 0. Please set it to 1 to invoke 0in.
; VoptZeroIn = 1
; Set the options to be passed to the 0in tools.
; Default value set to "". Please set it to appropriate options needed.
; VoptZeroInOptions = ""
; Set the option to treat all files specified in a vlog invocation as a
; single compilation unit. The default value is set to 0 which will treat
; each file as a separate compilation unit as specified in the P1800 draft standard.
; MultiFileCompilationUnit = 1
; Automatically exclude Verilog case statement default branches.
; Default is to not exclude.
; CoverExcludeDefault = 1
; Turn on code coverage in VLOG generate blocks. Default is off.
; CoverGenerate = 1
[sccom]
; Enable use of SCV include files and library. Default is off.
; UseScv = 1
; Add C++ compiler options to the sccom command line by using this variable.
; CppOptions = -g
; Use custom C++ compiler located at this path rather than the default path.
; The path should point directly at a compiler executable.
; CppPath = /usr/bin/g++
; Enable verbose messages from sccom. Default is off.
; SccomVerbose = 1
; sccom logfile. Default is no logfile.
; SccomLogfile = sccom.log
; Enable use of SC_MS include files and library. Default is off.
; UseScMs = 1
[vsim]
; vopt flow
; Set to turn on automatic optimization of a design.
; Default is on
VoptFlow = 1
; vopt automatic SDF
; If automatic design optimization is on, enables automatic compilation
; of SDF files.
; Default is on, uncomment to turn off.
; VoptAutoSDFCompile = 0
; Simulator resolution
; Set to fs, ps, ns, us, ms, or sec with optional prefix of 1, 10, or 100.
resolution = 1ps
; User time unit for run commands
; Set to default, fs, ps, ns, us, ms, or sec. The default is to use the
; unit specified for Resolution. For example, if Resolution is 100ps,
; then UserTimeUnit defaults to ps.
; Should generally be set to default.
UserTimeUnit = default
; Default run length
RunLength = 100 ps
; Maximum iterations that can be run without advancing simulation time
IterationLimit = 5000
; Control PSL and Verilog Assume directives during simulation
; Set SimulateAssumeDirectives = 0 to disable assume being simulated as asserts
; Set SimulateAssumeDirectives = 1 to enable assume simulation as asserts
; SimulateAssumeDirectives = 1
; Control the simulation of PSL and SVA
; These switches can be overridden by the vsim command line switches:
; -psl, -nopsl, -sva, -nosva.
; Set SimulatePSL = 0 to disable PSL simulation
; Set SimulatePSL = 1 to enable PSL simulation (default)
; SimulatePSL = 1
; Set SimulateSVA = 0 to disable SVA simulation
; Set SimulateSVA = 1 to enable concurrent SVA simulation (default)
; SimulateSVA = 1
; Directives to license manager can be set either as single value or as
; space separated multi-values:
; vhdl Immediately reserve a VHDL license
; vlog Immediately reserve a Verilog license
; plus Immediately reserve a VHDL and Verilog license
; nomgc Do not look for Mentor Graphics Licenses
; nomti Do not look for Model Technology Licenses
; noqueue Do not wait in the license queue when a license is not available
; viewsim Try for viewer license but accept simulator license(s) instead
; of queuing for viewer license (PE ONLY)
; noviewer Disable checkout of msimviewer and vsim-viewer license
; features (PE ONLY)
; noslvhdl Disable checkout of qhsimvh and vsim license features
; noslvlog Disable checkout of qhsimvl and vsimvlog license features
; nomix Disable checkout of msimhdlmix and hdlmix license features
; nolnl Disable checkout of msimhdlsim and hdlsim license features
; mixedonly Disable checkout of qhsimvh,qhsimvl,vsim,vsimvlog license
; features
; lnlonly Disable checkout of qhsimvh,qhsimvl,vsim,vsimvlog,msimhdlmix,
; hdlmix license features
; Single value:
; License = plus
; Multi-value:
; License = noqueue plus
; Stop the simulator after a VHDL/Verilog immediate assertion message
; 0 = Note 1 = Warning 2 = Error 3 = Failure 4 = Fatal
BreakOnAssertion = 3
; VHDL assertion Message Format
; %S - Severity Level
; %R - Report Message
; %T - Time of assertion
; %D - Delta
; %I - Instance or Region pathname (if available)
; %i - Instance pathname with process
; %O - Process name
; %K - Kind of object path is to return: Instance, Signal, Process or Unknown
; %P - Instance or Region path without leaf process
; %F - File
; %L - Line number of assertion or, if assertion is in a subprogram, line
; from which the call is made
; %% - Print '%' character
; If specific format for assertion level is defined, use its format.
; If specific format is not defined for assertion level:
; - and if failure occurs during elaboration, use AssertionFormatBreakLine;
; - and if assertion triggers a breakpoint (controlled by BreakOnAssertion
; level), use AssertionFormatBreak;
; - otherwise, use AssertionFormat.
; AssertionFormatBreakLine = "** %S: %R\n Time: %T Iteration: %D %K: %i File: %F Line: %L\n"
; AssertionFormatBreak = "** %S: %R\n Time: %T Iteration: %D %K: %i File: %F\n"
; AssertionFormat = "** %S: %R\n Time: %T Iteration: %D%I\n"
; AssertionFormatNote = "** %S: %R\n Time: %T Iteration: %D%I\n"
; AssertionFormatWarning = "** %S: %R\n Time: %T Iteration: %D%I\n"
; AssertionFormatError = "** %S: %R\n Time: %T Iteration: %D %K: %i File: %F\n"
; AssertionFormatFail = "** %S: %R\n Time: %T Iteration: %D %K: %i File: %F\n"
; AssertionFormatFatal = "** %S: %R\n Time: %T Iteration: %D %K: %i File: %F\n"
; Assertion File - alternate file for storing VHDL/PSL/Verilog assertion messages
; AssertFile = assert.log
; Simulation Breakpoint messages
; This flag controls the display of function names when reporting the location
; where the simulator stops do to a breakpoint or fatal error.
; Example w/function name: # Break in Process ctr at counter.vhd line 44
; Example wo/function name: # Break at counter.vhd line 44
ShowFunctions = 1
; Default radix for all windows and commands.
; Set to symbolic, ascii, binary, octal, decimal, hex, unsigned
DefaultRadix = hexadecimal
; VSIM Startup command
; Startup = do startup.do
; File for saving command transcript
TranscriptFile = transcript
; File for saving command history
; CommandHistory = cmdhist.log
; Specify whether paths in simulator commands should be described
; in VHDL or Verilog format.
; For VHDL, PathSeparator = /
; For Verilog, PathSeparator = .
; Must not be the same character as DatasetSeparator.
; PathSeparator = /
; Specify the dataset separator for fully rooted contexts.
; The default is ':'. For example: sim:/top
; Must not be the same character as PathSeparator.
DatasetSeparator = :
; Specify a unique path separator for the Signal Spy set of functions.
; The default will be to use the PathSeparator variable.
; Must not be the same character as DatasetSeparator.
; SignalSpyPathSeparator = /
; Disable VHDL assertion messages
; IgnoreNote = 1
; IgnoreWarning = 1
; IgnoreError = 1
; IgnoreFailure = 1
; Disable System Verilog assertion messages
; Info and Warning are disabled by default
; IgnoreSVAInfo = 0
; IgnoreSVAWarning = 0
; IgnoreSVAError = 1
; IgnoreSVAFatal = 1
; Default force kind. May be freeze, drive, deposit, or default
; or in other terms, fixed, wired, or charged.
; A value of "default" will use the signal kind to determine the
; force kind, drive for resolved signals, freeze for unresolved signals
; DefaultForceKind = freeze
; If zero, open files when elaborated; otherwise, open files on
; first read or write. Default is 0.
; DelayFileOpen = 1
; Control VHDL files opened for write.
; 0 = Buffered, 1 = Unbuffered
UnbufferedOutput = 0
; Control the number of VHDL files open concurrently.
; This number should always be less than the current ulimit
; setting for max file descriptors.
; 0 = unlimited
ConcurrentFileLimit = 40
; Control the number of hierarchical regions displayed as
; part of a signal name shown in the Wave window.
; A value of zero tells VSIM to display the full name.
; The default is 0.
; WaveSignalNameWidth = 0
; Turn off warnings when changing VHDL constants and generics
; Default is 1 to generate warning messages
; WarnConstantChange = 0
; Turn off warnings from the std_logic_arith, std_logic_unsigned
; and std_logic_signed packages.
; StdArithNoWarnings = 1
; Turn off warnings from the IEEE numeric_std and numeric_bit packages.
; NumericStdNoWarnings = 1
; Control the format of the (VHDL) FOR generate statement label
; for each iteration. Do not quote it.
; The format string here must contain the conversion codes %s and %d,
; in that order, and no other conversion codes. The %s represents
; the generate_label; the %d represents the generate parameter value
; at a particular generate iteration (this is the position number if
; the generate parameter is of an enumeration type). Embedded whitespace
; is allowed (but discouraged); leading and trailing whitespace is ignored.
; Application of the format must result in a unique scope name over all
; such names in the design so that name lookup can function properly.
; GenerateFormat = %s__%d
; Specify whether checkpoint files should be compressed.
; The default is 1 (compressed).
; CheckpointCompressMode = 0
; Specify whether to enable SystemVerilog DPI out-of-the-blue call.
; Out-of-the-blue call refers to a SystemVerilog export function call
; directly from a C function that don't have the proper context setup
; as done in DPI-C import C functions. When this is enabled, one can
; call a DPI export function (but not task) from any C code.
; The default is 0 (disabled).
; DpiOutOfTheBlue = 1
; List of dynamically loaded objects for Verilog PLI applications
; Veriuser = veriuser.sl
Veriuser = $MODEL_TECH/libswiftpli.sl;;$DENALI/mtipli.so
; Specify default options for the restart command. Options can be one
; or more of: -force -nobreakpoint -nolist -nolog -nowave -noassertions
; DefaultRestartOptions = -force
; HP-UX 10.20 ONLY - Enable memory locking to speed up large designs
; (> 500 megabyte memory footprint). Default is disabled.
; Specify number of megabytes to lock.
; LockedMemory = 1000
; HP-UX 11.00 ONLY - Use /usr/lib/libCsup_v2.sl for shared object loading.
; This is necessary when C++ files have been compiled with aCC's -AA option.
; The default behavior is to use /usr/lib/libCsup.sl.
; UseCsupV2 = 1
; Turn on (1) or off (0) WLF file compression.
; The default is 1 (compress WLF file).
; WLFCompress = 0
; Specify whether to save all design hierarchy (1) in the WLF file
; or only regions containing logged signals (0).
; The default is 0 (save only regions with logged signals).
; WLFSaveAllRegions = 1
; WLF file time limit. Limit WLF file by time, as closely as possible,
; to the specified amount of simulation time. When the limit is exceeded
; the earliest times get truncated from the file.
; If both time and size limits are specified the most restrictive is used.
; UserTimeUnits are used if time units are not specified.
; The default is 0 (no limit). Example: WLFTimeLimit = {100 ms}
; WLFTimeLimit = 0
; WLF file size limit. Limit WLF file size, as closely as possible,
; to the specified number of megabytes. If both time and size limits
; are specified then the most restrictive is used.
; The default is 0 (no limit).
; WLFSizeLimit = 1000
; Specify whether or not a WLF file should be deleted when the
; simulation ends. A value of 1 will cause the WLF file to be deleted.
; The default is 0 (do not delete WLF file when simulation ends).
; WLFDeleteOnQuit = 1
; Specify whether or not a WLF file should be optimized during
; simulation. If set to 0, the WLF file will not be optimized.
; The default is 1, optimize the WLF file.
; WLFOptimize = 0
; Specify the name of the WLF file.
; The default is vsim.wlf
; WLFFilename = vsim.wlf
; WLF reader cache size limit. Specifies the internal WLF file cache size,
; in megabytes, for EACH open WLF file. A value of 0 turns off the
; WLF cache.
; The default setting is enabled to 256M per open WLF file.
; WLFCacheSize = 1000
; Specify the WLF file event collapse mode.
; 0 = Preserve all events and event order. (same as -wlfnocollapse)
; 1 = Only record values of logged objects at the end of a simulator iteration.
; (same as -wlfcollapsedelta)
; 2 = Only record values of logged objects at the end of a simulator time step.
; (same as -wlfcollapsetime)
; The default is 1.
; WLFCollapseMode = 0
; Turn on/off undebuggable SystemC type warnings. Default is on.
; ShowUndebuggableScTypeWarning = 0
; Turn on/off unassociated SystemC name warnings. Default is off.
; ShowUnassociatedScNameWarning = 1
; Set SystemC default time unit.
; Set to fs, ps, ns, us, ms, or sec with optional
; prefix of 1, 10, or 100. The default is 1 ns.
; The ScTimeUnit value is honored if it is coarser than Resolution.
; If ScTimeUnit is finer than Resolution, it is set to the value
; is 10 ns and ScTimeUnit is ns, then the default time unit will be 10 ns.
ScTimeUnit = ns
; Set the SCV relationship name that will be used to identify phase
; relations. If the name given to a transactor relation matches this
; name, the transactions involved will be treated as phase transactions
ScvPhaseRelationName = mti_phase
; Do not exit when executing sc_stop().
; If this is enabled, the control will be returned to the user before exiting
; the simulation. This can make some cleanup tasks easier before kernel exits.
; The default is off.
; NoExitOnScStop = 1
; Run simulator in assertion debug mode. Default is off.
; AssertionDebug = 1
; Turn on/off PSL/SVA concurrent assertion pass enable. Default is on.
; AssertionPassEnable = 0
; Turn on/off PSL/SVA concurrent assertion fail enable. Default is on.
; AssertionFailEnable = 0
; Set PSL/SVA concurrent assertion pass limit. Default is -1.
; Any positive integer, -1 for infinity.
; AssertionPassLimit = 1
; Set PSL/SVA concurrent assertion fail limit. Default is -1.
; Any positive integer, -1 for infinity.
; AssertionFailLimit = 1
; Turn on/off PSL concurrent assertion pass log. Default is off.
; The flag does not affect SVA
; AssertionPassLog = 1
; Turn on/off PSL concurrent assertion fail log. Default is on.
; The flag does not affect SVA
; AssertionFailLog = 0
; Set action type for PSL/SVA concurrent assertion fail action. Default is continue.
; 0 = Continue 1 = Break 2 = Exit
; AssertionFailAction = 1
; Turn on/off code coverage
; CodeCoverage = 0
; Count all code coverage condition and expression truth table rows that match.
; CoverCountAll = 1
; Turn on/off all PSL/SVA cover directive enables. Default is on.
; CoverEnable = 0
; Turn on/off PSL/SVA cover log. Default is off.
; CoverLog = 1
; Set "at_least" value for all PSL/SVA cover directives. Default is 1.
; CoverAtLeast = 2
; Set "limit" value for all PSL/SVA cover directives. Default is -1.
; Any positive integer, -1 for infinity.
; CoverLimit = 1
; Specify the coverage database filename. Default is "" (i.e. database is NOT automatically saved on close).
; UCDBFilename = vsim.ucdb
; Set weight for all PSL/SVA cover directives. Default is 1.
; CoverWeight = 2
; Check vsim plusargs. Default is 0 (off).
; 0 = Don't check plusargs
; 1 = Warning on unrecognized plusarg
; 2 = Error and exit on unrecognized plusarg
; CheckPlusargs = 1
; Load the specified shared objects with the RTLD_GLOBAL flag.
; This gives global visibility to all symbols in the shared objects,
; meaning that subsequently loaded shared objects can bind to symbols
; in the global shared objects. The list of shared objects should
; be whitespace delimited. This option is not supported on the
; Windows or AIX platforms.
; GlobalSharedObjectList = example1.so example2.so example3.so
; Run the 0in tools from within the simulator.
; Default value set to 0. Please set it to 1 to invoke 0in.
; VsimZeroIn = 1
; Set the options to be passed to the 0in tools.
; Default value set to "". Please set it to appropriate options needed.
; VsimZeroInOptions = ""
; Initial seed for the Random Number Generator (RNG) of the root thread (SystemVerilog).
; Sv_Seed = 0
; Maximum size of dynamic arrays that are resized during randomize().
; The default is 1000. A value of 0 indicates no limit.
; SolveArrayResizeMax = 1000
; Error message severity when randomize() failure is detected (SystemVerilog).
; The default is 0 (no error).
; 0 = No error 1 = Warning 2 = Error 3 = Failure 4 = Fatal
; SolveFailSeverity = 0
; Enable/disable debug information for randomize() failures (SystemVerilog).
; The default is 0 (disabled). Set to 1 to enable.
; SolveFailDebug = 0
; When SolveFailDebug is enabled, this value specifies the maximum number of
; constraint subsets that will be tested for conflicts.
; The default is 0 (no limit).
; SolveFailDebugLimit = 0
; When SolveFailDebug is eanbled, this value specifies the maximum size of
; constraint subsets that will be tested for conflicts.
; The default value is 0 (no limit).
; SolveFailDebugMaxSet = 0
; Specify random sequence compatiblity with a prior letter release. This
; option is used to get the same random sequences during simulation as
; as a prior letter release. Only prior letter releases (of the current
; number release) are allowed.
; Note: To achieve the same random sequences, solver optimizations and/or
; bug fixes introduced since the specified release may be disabled -
; yielding the performance / behavior of the prior release.
; Default value set to "" (random compatibility not required).
; SolveRev = ""
; Environment variable expansion of command line arguments has been depricated
; in favor shell level expansion. Universal environment variable expansion
; inside -f files is support and continued support for MGC Location Maps provide
; alternative methods for handling flexible pathnames.
; The following line may be uncommented and the value set to 1 to re-enable this
; deprecated behavior. The default value is 0.
; DeprecatedEnvironmentVariableExpansion = 0
; Retroactive Recording uses a limited number of private data channels in the WLF
; file. Too many channels degrade WLF performance. If the limit is reached,
; simulation ends with a fatal error. You may change this limit as needed, but be
; aware of the implications of too many channels. The value must be an integer
; greater than or equal to zero, where zero disables all retroactive recording.
; RetroChannelLimit = 20
; Options to give vopt when code coverage is turned on.
; Default is "+acc=lprnb -opt=-merge -opt=-suppressAlways"
; VoptCoverageOptions = +acc=lprnb -opt=-merge -opt=-suppressAlways
[lmc]
; The simulator's interface to Logic Modeling's SmartModel SWIFT software
libsm = $MODEL_TECH/libsm.sl
; The simulator's interface to Logic Modeling's SmartModel SWIFT software (Windows NT)
; libsm = $MODEL_TECH/libsm.dll
; Logic Modeling's SmartModel SWIFT software (HP 9000 Series 700)
; libswift = $LMC_HOME/lib/hp700.lib/libswift.sl
; Logic Modeling's SmartModel SWIFT software (IBM RISC System/6000)
; libswift = $LMC_HOME/lib/ibmrs.lib/swift.o
; Logic Modeling's SmartModel SWIFT software (Sun4 Solaris)
; libswift = $LMC_HOME/lib/sun4Solaris.lib/libswift.so
; Logic Modeling's SmartModel SWIFT software (Windows NT)
; libswift = $LMC_HOME/lib/pcnt.lib/libswift.dll
; Logic Modeling's SmartModel SWIFT software (Linux)
libswift = $LMC_HOME/lib/x86_linux.lib/libswift.so
; The simulator's interface to Logic Modeling's hardware modeler SFI software
libhm = $MODEL_TECH/libhm.sl
; The simulator's interface to Logic Modeling's hardware modeler SFI software (Windows NT)
; libhm = $MODEL_TECH/libhm.dll
; Logic Modeling's hardware modeler SFI software (HP 9000 Series 700)
; libsfi = <sfi_dir>/lib/hp700/libsfi.sl
; Logic Modeling's hardware modeler SFI software (IBM RISC System/6000)
; libsfi = <sfi_dir>/lib/rs6000/libsfi.a
; Logic Modeling's hardware modeler SFI software (Sun4 Solaris)
; libsfi = <sfi_dir>/lib/sun4.solaris/libsfi.so
; Logic Modeling's hardware modeler SFI software (Windows NT)
; libsfi = <sfi_dir>/lib/pcnt/lm_sfi.dll
; Logic Modeling's hardware modeler SFI software (Linux)
; libsfi = <sfi_dir>/lib/linux/libsfi.so
[msg_system]
; Change a message severity or suppress a message.
; The format is: <msg directive> = <msg number>[,<msg number>...]
; Examples:
; note = 3009
; warning = 3033
; error = 3010,3016
; fatal = 3016,3033
; suppress = 3009,3016,3043
; The command verror <msg number> can be used to get the complete
; description of a message.
; Control transcripting of elaboration/runtime messages.
; The default is to have messages appear in the transcript and
; recorded in the wlf file (messages that are recorded in the
; wlf file can be viewed in the MsgViewer). The other settings
; are to send messages only to the transcript or only to the
; wlf file. The valid values are
; both {default}
; tran {transcript only}
; wlf {wlf file only}
; msgmode = both
[Project]
Project_Version = 6
Project_DefaultLib = work
Project_SortMethod = unused
Project_Files_Count = 0
Project_Sim_Count = 0
Project_Folder_Count = 0
Echo_Compile_Output = 0
Save_Compile_Report = 1
Project_Opt_Count = 0
ForceSoftPaths = 0
ReOpenSourceFiles = 1
VERILOG_DoubleClick = Edit
VERILOG_CustomDoubleClick =
VHDL_DoubleClick = Edit
VHDL_CustomDoubleClick =
PSL_DoubleClick = Edit
PSL_CustomDoubleClick =
TEXT_DoubleClick = Edit
TEXT_CustomDoubleClick =
SYSTEMC_DoubleClick = Edit
SYSTEMC_CustomDoubleClick =
TCL_DoubleClick = Edit
TCL_CustomDoubleClick =
MACRO_DoubleClick = Edit
MACRO_CustomDoubleClick =
VCD_DoubleClick = Edit
VCD_CustomDoubleClick =
SDF_DoubleClick = Edit
SDF_CustomDoubleClick =
XML_DoubleClick = Edit
XML_CustomDoubleClick =
LOGFILE_DoubleClick = Edit
LOGFILE_CustomDoubleClick =
EditorState = {tabbed horizontal 1}
Project_Major_Version = 6
Project_Minor_Version = 2
-------------------------------------------------------------------------------
-- Title : A sample GPIO port with asynchronous clock (wbgen2 example)
-- Project :
-------------------------------------------------------------------------------
-- File : gpio_port_async.vhdl
-- Author : T.W.
-- Company :
-- Created : 2010-02-22
-- Last update: 2010-02-22
-- Platform :
-- Standard : VHDL'87
-------------------------------------------------------------------------------
-- Description:
-------------------------------------------------------------------------------
-- Copyright (c) 2010 T.W.
-------------------------------------------------------------------------------
-- Revisions :
-- Date Version Author Description
-- 2010-02-22 1.0 slayer Created
-------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
library work;
entity gpio_port_async is
port (
rst_n_i : in std_logic;
wb_clk_i : in std_logic;
wb_addr_i : in std_logic_vector(2 downto 0);
wb_data_i : in std_logic_vector(31 downto 0);
wb_data_o : out std_logic_vector(31 downto 0);
wb_cyc_i : in std_logic;
wb_sel_i : in std_logic;
wb_stb_i : in std_logic;
wb_we_i : in std_logic;
wb_ack_o : out std_logic;
-- our port :)
gpio_clk_i: in std_logic; -- asynchronous clock for the GPIO port
gpio_pins_b : inout std_logic_vector(31 downto 0)
);
end gpio_port_async;
architecture syn of gpio_port_async is
component wb_slave_gpio_port_async
port (
rst_n_i : in std_logic;
wb_clk_i : in std_logic;
wb_addr_i : in std_logic_vector(2 downto 0);
wb_data_i : in std_logic_vector(31 downto 0);
wb_data_o : out std_logic_vector(31 downto 0);
wb_cyc_i : in std_logic;
wb_sel_i : in std_logic;
wb_stb_i : in std_logic;
wb_we_i : in std_logic;
wb_ack_o : out std_logic;
gpio_async_clk_i : in std_logic;
gpio_ddr_o : out std_logic_vector(31 downto 0);
gpio_psr_i : in std_logic_vector(31 downto 0);
gpio_pdr_o : out std_logic_vector(31 downto 0);
gpio_pdr_wr_o : out std_logic;
gpio_sopr_o : out std_logic_vector(31 downto 0);
gpio_sopr_wr_o : out std_logic;
gpio_copr_o : out std_logic_vector(31 downto 0);
gpio_copr_wr_o : out std_logic);
end component;
signal gpio_ddr : std_logic_vector(31 downto 0);
signal gpio_psr : std_logic_vector(31 downto 0);
signal gpio_pdr : std_logic_vector(31 downto 0);
signal gpio_pdr_wr : std_logic;
signal gpio_sopr : std_logic_vector(31 downto 0);
signal gpio_sopr_wr : std_logic;
signal gpio_copr : std_logic_vector(31 downto 0);
signal gpio_copr_wr : std_logic;
-- regsiter containing current output state
signal gpio_reg : std_logic_vector(31 downto 0);
-- registers for synchronization of input pins
signal gpio_pins_sync1 : std_logic_vector(31 downto 0);
signal gpio_pins_sync0 : std_logic_vector(31 downto 0);
begin -- syn
wb_slave : wb_slave_gpio_port_async
port map (
rst_n_i => rst_n_i,
wb_clk_i => wb_clk_i,
wb_addr_i => wb_addr_i,
wb_data_i => wb_data_i,
wb_data_o => wb_data_o,
wb_cyc_i => wb_cyc_i,
wb_sel_i => wb_sel_i,
wb_stb_i => wb_stb_i,
wb_we_i => wb_we_i,
wb_ack_o => wb_ack_o,
gpio_async_clk_i => gpio_clk_i,
gpio_ddr_o => gpio_ddr,
gpio_psr_i => gpio_pins_sync1,
gpio_pdr_o => gpio_pdr,
gpio_pdr_wr_o => gpio_pdr_wr,
gpio_sopr_o => gpio_sopr,
gpio_sopr_wr_o => gpio_sopr_wr,
gpio_copr_o => gpio_copr,
gpio_copr_wr_o => gpio_copr_wr);
process (gpio_clk_i, rst_n_i)
begin -- process
if(rst_n_i = '0') then
gpio_reg <= (others => '0');
elsif rising_edge(gpio_clk_i) then
if(gpio_pdr_wr = '1') then -- write operation to "PDR" register -
-- set the new values of GPIO outputs
gpio_reg <= gpio_pdr;
end if;
if(gpio_sopr_wr = '1') then -- write to "SOPR" reg - set ones
for i in 0 to 31 loop
if(gpio_sopr(i) = '1') then
gpio_reg(i) <= '1';
end if;
end loop;
end if;
if(gpio_copr_wr = '1') then -- write to "COPR" reg - set zeros
for i in 0 to 31 loop
if(gpio_copr(i) = '1') then
gpio_reg(i) <= '0';
end if;
end loop;
end if;
end if;
end process;
-- synchronizing process for input pins
synchronize_input_pins : process (gpio_clk_i, rst_n_i)
begin -- process
if(rst_n_i = '0') then
gpio_pins_sync0 <= (others => '0');
gpio_pins_sync1 <= (others => '0');
elsif rising_edge(gpio_clk_i) then
gpio_pins_sync0 <= gpio_pins_b;
gpio_pins_sync1 <= gpio_pins_sync0;
end if;
end process;
-- generate the tristate buffers for I/O pins
gen_tristates : for i in 0 to 31 generate
gpio_pins_b(i) <= gpio_reg(i) when gpio_ddr(i) = '1' else 'Z';
end generate gen_tristates;
end syn;
-- this is no different from "gpio_port" example, except all the registers use gpio_async_clk_i clock input.
-- here comes our peripheral definition
peripheral {
-- short (human-readable) name for the peripheral.
name = "GPIO Port";
-- a longer description, if you want
description = "A sample 32-bit general-purpose bidirectional I/O port, explaining how to use SLV and PASS-THROUGH registers. This time in asynchronous mode!";
-- name of the target VHDL entity to be generated
hdl_entity = "wb_slave_gpio_port_async";
-- prefix for all the generated ports belonging to our peripheral
prefix = "gpio";
-- Pin direction register. Readable and writable from the bus, readable from the device.
reg {
name = "Pin direction register";
description = "A register defining the direction of the GPIO potr pins.";
prefix = "ddr";
-- a single, anonymous field (no prefix) of type SLV.
field {
name = "Pin directions";
description = "Each bit in this register defines the direction of corresponding pin of the GPIO port. 1 means the pin is an OUTPUT, 0 means the pin is an INPUT";
-- there is (deliberately) no prefix defined for this field. Since we have only one field in the register "ddr", we can omit the prefix - wbgen2 will produce signal names
-- containing only prefixes of the peripheral and the parent register.
-- type of our field - std_logic_vector
type = SLV;
-- size - we want 32-bits wide port :)
size = 32;
-- the field will be readable/writable from the Wishbone bus
access_bus = READ_WRITE;
-- .. and readable from the peripheral
access_dev = READ_ONLY;
-- our asynchronous clock :)
clock = "gpio_async_clk_i";
};
};
-- Pin input state register. Readable the bus, writable from the device.
reg {
name = "Pin input state register";
description = "A register containing the current state of input pins.";
prefix = "psr";
-- a single, anonymous field (no prefix) of type SLV.
field {
name = "Pin input state";
description = "Each bit in this register reflects the state of corresponding GPIO port pin.";
-- no prefix here as well (see above)
-- type of our field - std_logic_vector
type = SLV;
-- size - we want 32-bits wide port :)
size = 32;
-- the field will be readable from the Wishbone bus
access_bus = READ_ONLY;
-- .. and writable from the peripheral
access_dev = WRITE_ONLY;
clock = "gpio_async_clk_i";
};
};
-- Port output register. Shows how to use PASS-THROUGH regs
reg {
name = "Port output register";
description = "Register containing the output pin state.";
prefix = "pdr";
-- a single, anonymous field (no prefix) of type PASS-THROUGH.
field {
name = "Port output value";
-- the description isn't really necessary here :)
-- description = "Writing '1' sets the corresponding GPIO pin to '1'";
-- type of our field - PASS_THROUGH. In this mode, the slave core is not storing the register value. Instead it provides the raw value
-- (taken from the wishbone data input) and a strobe signal, asserted for single clock cycle upon write operation to the register.
-- The wishbone data input will be fed directly to gpio_pdr_o and each write operation to this register will generate a single-cycle positive
-- pulse on gpio_pdr_wr_o signal.
type = PASS_THROUGH;
size = 32;
-- access flags don't apply for the PASS-THROUGH regsiters, so we can omit them.
clock = "gpio_async_clk_i";
};
};
-- Set output register. Shows how to use PASS-THROUGH regs
reg {
name = "Set output pin register";
description = "Writing '1' sets the corresponding GPIO pin to '1'";
prefix = "sopr";
-- Our driver developer would want these two (SOPR and COPR) registers' addresses to be aligned to multiple of 4 :)
align = 4;
field {
name = "Set output pin register";
type = PASS_THROUGH;
size = 32;
clock = "gpio_async_clk_i";
};
};
-- Clear output register. Designed identically as the previous reg.
reg {
name = "Clear output pin register";
description = "Writing '1' clears the corresponding GPIO pin";
prefix = "copr";
field {
name = "Clear output pin register";
type = PASS_THROUGH;
size = 32;
clock = "gpio_async_clk_i";
};
};
};
`define ADDR_GPIO_DDR 3'h0
`define ADDR_GPIO_PSR 3'h1
`define ADDR_GPIO_PDR 3'h2
`define ADDR_GPIO_SOPR 3'h4
`define ADDR_GPIO_COPR 3'h5
vlib work
../../wbgen2.lua gpio_port_async.wb -vo ./output/wb_slave_gpio_port_async.vhdl --gen-vlog-constants ./output/vlog_constants.v
vcom ./output/wb_slave_gpio_port_async.vhdl
vcom ./gpio_port_async.vhdl
vlog ./testbench.v
vsim work.main
radix -hexadecimal
do wave.do
run 15us
wave zoomfull
`timescale 1ns/1ps
`define wbclk_period 100
`define clk_async_period 71
`include "output/vlog_constants.v"
module main;
reg clk=1;
reg clk_async = 1;
reg rst=0;
always #(`wbclk_period) clk<=~clk;
always #(`clk_async_period/2) clk_async <= ~clk_async;
initial #1000 rst <= 1;
`include "wishbone_stuff.v"
wire [31:0] gpio_pins_b;
reg [31:0] gpio_reg = 32'bz;
gpio_port_async dut(
.rst_n_i (rst),
.wb_clk_i (clk),
.wb_addr_i (wb_addr[2:0]),
.wb_data_i (wb_data_o),
.wb_data_o (wb_data_i),
.wb_cyc_i (wb_cyc),
.wb_sel_i (wb_sel),
.wb_stb_i (wb_stb),
.wb_we_i (wb_we),
.wb_ack_o (wb_ack),
.gpio_clk_i (clk_async),
.gpio_pins_b (gpio_pins_b)
);
assign gpio_pins_b = gpio_reg;
reg[31:0] data;
integer i;
initial begin
#2001; // wait until the DUT is reset
$display("Set half of the pins to outputs, other half to inputs");
wb_write(`ADDR_GPIO_DDR, 32'hffff0000);
$display("Pins state: %b (%x)", gpio_pins_b, gpio_pins_b);
$display("Set every even byte to '1'");
wb_write(`ADDR_GPIO_SOPR, 32'hff00ff00);
$display("Pins state: %b (%x)", gpio_pins_b, gpio_pins_b);
$display("Clear every even bit");
wb_write(`ADDR_GPIO_COPR, 32'h55555555);
$display("Pins state: %b (%x)", gpio_pins_b, gpio_pins_b);
$display("Write an arbitrary value");
wb_write(`ADDR_GPIO_PDR, 32'hdeadbeef);
$display("Pins state: %b (%x)", gpio_pins_b, gpio_pins_b);
$display("Force something tasty on the GPIO input pins");
gpio_reg[15:0] = 16'hcafe;
delay_cycles(1);
$display("Pins state: %b (%x)", gpio_pins_b, gpio_pins_b);
delay_cycles(10); // wait for a while for the sync logic
wb_read(`ADDR_GPIO_PSR, data);
$display("Time for %x!", data[15:0]);
end
endmodule
onerror {resume}
quietly WaveActivateNextPane {} 0
add wave -noupdate -format Logic /main/dut/rst_n_i
add wave -noupdate -format Logic /main/dut/wb_clk_i
add wave -noupdate -format Literal /main/dut/wb_addr_i
add wave -noupdate -format Literal /main/dut/wb_data_i
add wave -noupdate -format Literal /main/dut/wb_data_o
add wave -noupdate -format Logic /main/dut/wb_cyc_i
add wave -noupdate -format Logic /main/dut/wb_sel_i
add wave -noupdate -format Logic /main/dut/wb_stb_i
add wave -noupdate -format Logic /main/dut/wb_we_i
add wave -noupdate -format Logic /main/dut/wb_ack_o
add wave -noupdate -format Literal /main/dut/gpio_pins_b
add wave -noupdate -format Literal /main/dut/gpio_ddr
add wave -noupdate -format Literal /main/dut/gpio_psr
add wave -noupdate -format Literal /main/dut/gpio_pdr
add wave -noupdate -format Logic /main/dut/gpio_pdr_wr
add wave -noupdate -format Literal /main/dut/gpio_sopr
add wave -noupdate -format Logic /main/dut/gpio_sopr_wr
add wave -noupdate -format Literal /main/dut/gpio_copr
add wave -noupdate -format Logic /main/dut/gpio_copr_wr
add wave -noupdate -format Literal /main/dut/gpio_reg
add wave -noupdate -format Literal /main/dut/gpio_pins_sync1
add wave -noupdate -format Literal /main/dut/gpio_pins_sync0
add wave -noupdate -format Logic /main/dut/wb_slave/rst_n_i
add wave -noupdate -format Logic /main/dut/wb_slave/wb_clk_i
add wave -noupdate -format Literal /main/dut/wb_slave/wb_addr_i
add wave -noupdate -format Literal /main/dut/wb_slave/wb_data_i
add wave -noupdate -format Literal /main/dut/wb_slave/wb_data_o
add wave -noupdate -format Logic /main/dut/wb_slave/wb_cyc_i
add wave -noupdate -format Logic /main/dut/wb_slave/wb_sel_i
add wave -noupdate -format Logic /main/dut/wb_slave/wb_stb_i
add wave -noupdate -format Logic /main/dut/wb_slave/wb_we_i
add wave -noupdate -format Logic /main/dut/wb_slave/wb_ack_o
add wave -noupdate -format Logic /main/dut/wb_slave/gpio_async_clk_i
add wave -noupdate -format Literal /main/dut/wb_slave/gpio_ddr_o
add wave -noupdate -format Literal /main/dut/wb_slave/gpio_psr_i
add wave -noupdate -format Literal /main/dut/wb_slave/gpio_pdr_o
add wave -noupdate -format Logic /main/dut/wb_slave/gpio_pdr_wr_o
add wave -noupdate -format Literal /main/dut/wb_slave/gpio_sopr_o
add wave -noupdate -format Logic /main/dut/wb_slave/gpio_sopr_wr_o
add wave -noupdate -format Literal /main/dut/wb_slave/gpio_copr_o
add wave -noupdate -format Logic /main/dut/wb_slave/gpio_copr_wr_o
add wave -noupdate -format Literal /main/dut/wb_slave/gpio_ddr_int
add wave -noupdate -format Logic /main/dut/wb_slave/gpio_ddr_swb
add wave -noupdate -format Logic /main/dut/wb_slave/gpio_ddr_swb_delay
add wave -noupdate -format Logic /main/dut/wb_slave/gpio_ddr_swb_s0
add wave -noupdate -format Logic /main/dut/wb_slave/gpio_ddr_swb_s1
add wave -noupdate -format Logic /main/dut/wb_slave/gpio_ddr_swb_s2
add wave -noupdate -format Literal /main/dut/wb_slave/gpio_psr_int
add wave -noupdate -format Logic /main/dut/wb_slave/gpio_psr_lwb
add wave -noupdate -format Logic /main/dut/wb_slave/gpio_psr_lwb_delay
add wave -noupdate -format Logic /main/dut/wb_slave/gpio_psr_lwb_in_progress
add wave -noupdate -format Logic /main/dut/wb_slave/gpio_psr_lwb_s0
add wave -noupdate -format Logic /main/dut/wb_slave/gpio_psr_lwb_s1
add wave -noupdate -format Logic /main/dut/wb_slave/gpio_psr_lwb_s2
add wave -noupdate -format Logic /main/dut/wb_slave/gpio_pdr_wr_int
add wave -noupdate -format Logic /main/dut/wb_slave/gpio_pdr_wr_int_delay
add wave -noupdate -format Logic /main/dut/wb_slave/gpio_pdr_wr_sync0
add wave -noupdate -format Logic /main/dut/wb_slave/gpio_pdr_wr_sync1
add wave -noupdate -format Logic /main/dut/wb_slave/gpio_pdr_wr_sync2
add wave -noupdate -format Logic /main/dut/wb_slave/gpio_sopr_wr_int
add wave -noupdate -format Logic /main/dut/wb_slave/gpio_sopr_wr_int_delay
add wave -noupdate -format Logic /main/dut/wb_slave/gpio_sopr_wr_sync0
add wave -noupdate -format Logic /main/dut/wb_slave/gpio_sopr_wr_sync1
add wave -noupdate -format Logic /main/dut/wb_slave/gpio_sopr_wr_sync2
add wave -noupdate -format Logic /main/dut/wb_slave/gpio_copr_wr_int
add wave -noupdate -format Logic /main/dut/wb_slave/gpio_copr_wr_int_delay
add wave -noupdate -format Logic /main/dut/wb_slave/gpio_copr_wr_sync0
add wave -noupdate -format Logic /main/dut/wb_slave/gpio_copr_wr_sync1
add wave -noupdate -format Logic /main/dut/wb_slave/gpio_copr_wr_sync2
add wave -noupdate -format Logic /main/dut/wb_slave/wb_ack_regbank
add wave -noupdate -format Literal /main/dut/wb_slave/ack_cntr
add wave -noupdate -format Logic /main/dut/wb_slave/ack_in_progress
add wave -noupdate -format Logic /main/dut/wb_slave/tmpbit
add wave -noupdate -format Literal /main/dut/wb_slave/wb_data_out_int
TreeUpdate [SetDefaultTree]
WaveRestoreCursors {{Cursor 1} {0 ps} 0}
configure wave -namecolwidth 333
configure wave -valuecolwidth 100
configure wave -justifyvalue left
configure wave -signalnamewidth 0
configure wave -snapdistance 10
configure wave -datasetprefix 0
configure wave -rowmargin 4
configure wave -childrowmargin 2
configure wave -gridoffset 0
configure wave -gridperiod 1
configure wave -griddelta 40
configure wave -timeline 0
update
WaveRestoreZoom {0 ps} {46187117 ps}
reg [31:0] wb_addr, wb_data_o, tmp;
wire [31:0] wb_data_i;
wire wb_ack;
reg wb_sel =0, wb_cyc=0, wb_stb=0, wb_we= 0;
task delay_cycles;
input [31:0] n;
begin
#(n * `wbclk_period);
end
endtask // delay_cycles
task wb_write;
input[31:0] addr;
input [31:0] data;
begin
$display("WB write: addr %x, data %x", addr, data);
wb_sel=1;
wb_stb=1;
wb_cyc=1;
wb_addr = addr;
wb_data_o=data;
wb_we = 1;
delay_cycles(1);
while(wb_ack == 0)
delay_cycles(1);
delay_cycles(1);
wb_cyc = 0;
wb_sel=0;
wb_we=0;
wb_stb=0;
end
endtask // wb_write
task wb_read;
input[31:0] addr;
output [31:0] data;
begin
wb_sel=1;
wb_stb=1;
wb_cyc=1;
wb_addr = addr;
wb_data_o=data;
wb_we = 0;
delay_cycles(1);
while(wb_ack == 0)
delay_cycles(1);
data = wb_data_i;
delay_cycles(1);
wb_cyc = 0;
wb_sel=0;
wb_we=0;
wb_stb=0;
end
endtask // wb_read
#!/usr/bin/lua
wbgen2_version="0.3"
wbgen2_libdir="/home/slayer/wbgen2-dev"
device_family="altera_cyclone3";
dofile(wbgen2_libdir.."/wbgen_common.lua");
dofile(wbgen2_libdir.."/wbgen_vhdl.lua");
dofile(wbgen2_libdir.."/wbgen_regbank.lua");
dofile(wbgen2_libdir.."/wbgen_rams.lua");
function chk_nil(p,s)
if(p == nil) then
die(s.." expected.");
end
return p;
end
function parse_args(arg)
local n=1;
if(arg[1] == nil) then
print("wbgen2 version "..wbgen2_version);
print("(c) Tomasz Wlostowski/CERN BE-Co-HT 2010");
print("");
print("usage: "..arg[0].." input_file.wb -t target -vo output.vhdl -co output.c -do output.html [additional options]");
print("where target is the target FPGA architecture [altera/xilinx]");
print("");
print("Additional options: ");
print("--gen-reg-constants - generates VHDL constants containing addresses of all registers. Useful for writing testbenches.");
print("--gen-vlog-constants file.v - generates Verilog constants containing addresses of all registers and writes them to file.v. Useful for writing testbenches.");
print("");
os.exit(0);
end
input_wb_file = arg[1];
vhdl_gen_reg_constants = false;
vlog_gen_reg_constants = false;
n=2;
while(arg[n] ~= nil) do
local sw = arg[n];
if(sw == "-vo") then
output_vhdl_file = chk_nil(arg[n+1], "VHDL output filename expected");
n=n+2;
elseif(sw == "-co") then
output_c_file = chk_nil(arg[n+1], "C header output filename expected");
n=n+2;
elseif(sw == "--gen-reg-constants") then
vhdl_gen_reg_constants = true;
n=n+1;
elseif(sw == "--gen-vlog-constants") then
output_vlog_constants_file = chk_nil(arg[n+1],"Verilog constants filename expected");
vlog_gen_reg_constants = true;
n=n+2;
else
n=n+1;
end
end
end
parse_args(arg);
dofile(input_wb_file);
if(periph == nil) then die ("missing peripheral declaration"); end
foreach_reg(
function(reg)
reg.total_size=0;
reg.current_offset=0;
end
);
foreach_field( fix_prefix );
foreach_field( fix_access );
foreach_reg( fix_prefix );
periph = fix_prefix(periph);
foreach_field(calc_size);
foreach_reg(check_max_size);
foreach_field(calc_field_offsets);
--foreach_field(function(reg, field) print
foreach_reg(calc_address_sizes);
assign_addresses();
--foreach_reg(gen_vhdl_signals);
--foreach_reg(gen_vhdl_constants);
gen_vhdl_code(output_vhdl_file);
if(vlog_gen_reg_constants) then
gen_vlog_constants(output_vlog_constants_file);
end
#!/usr/bin/lua
-- bus properties
DATA_BUS_WIDTH = 32;
SYNC_CHAIN_LENGTH = 3;
-- constant definitions (block types)
TYPE_PERIPH = 1;
TYPE_REG = 2;
TYPE_FIELD = 3;
TYPE_FIFO = 4;
TYPE_ENUM = 5;
TYPE_RAM = 6;
-- FIFO register flags
FIFO_FULL = 0x1;
FIFO_EMPTY = 0x2;
FIFO_ALMOST_FULL = 0x4;
FIFO_ALMOST_EMPTY = 0x8;
FIFO_CLEAR = 0x10;
FIFO_COUNT = 0x20;
-- field access flags
READ_ONLY = 0x1;
READ_WRITE = 0x2;
WRITE_ONLY = 0x4;
SET_ON_WRITE = 0x8;
RESET_ON_WRITE = 0x10;
-- field types
MONOSTABLE = 0x1;
BIT = 0x2;
SLV = 0x4;
SIGNED = 0x8;
UNSIGNED = 0x10;
ENUM = 0x20;
PASS_THROUGH = 0x40;
LOAD_INT = 1;
LOAD_EXT = 2;
ACC_RO_WO = 1;
ACC_WO_RO = 2;
ACC_RW_RW = 3;
ACC_RW_RO = 4;
FROM_WB = 1;
TO_WB = 2;
function peripheral(x) x['__type']=TYPE_PERIPH; periph = x; return x; end
function reg(x) x['__type']=TYPE_REG; return x; end
function field(x) x['__type']=TYPE_FIELD; return x; end
function fifo_reg(x) x['__type']=TYPE_FIFO; return x; end
function ram(x) x['__type']=TYPE_RAM; return x; end
function enum(x) x['__type']=TYPE_ENUM; return x; end
function range2bits(range)
local min = range[1];
local max = range[2];
local msize;
if(math.abs(min) > math.abs(max)) then
msize = math.abs(min);
else
msize = math.abs(max);
end
local logsize = math.ceil(math.log(msize) / math.log(2));
if(min < 0) then
logsize = logsize + 1;
end
return logsize;
end
function calc_size(field, reg)
if(field.type == MONOSTABLE or field.type == BIT) then
-- print('got bit');
field.size = 1;
elseif (field.type == SLV) then
-- print('got slv');
if(field.size == nil) then
die("no size declared for SLV-type field '".. field.name.."'");
end
elseif (field.type == SIGNED or field.type == UNSIGNED) then
-- print("got signed/USIGNED");
if(field.range == nil and field.size == nil) then
die("no range nor size declared for SIGNED/UNSIGNED-type field '".. field.name.."'");
end
if(field.size == nil) then
local nbits = range2bits(field.range);
if(nbits == nil) then
die("misdeclared range for SIGNED/UNSIGNED-type field '".. field.name.."'");
end
field.size = nbits;
end
elseif(field.type == ENUM) then
die("ENUM-type fields are not yet supported. Sorry :(");
end
reg.total_size = reg.total_size + field.size;
end
function foreach_field(func)
for i,v in pairs(periph) do
if(type(v) == 'table') then
if(v.__type ~= nil and (v.__type == TYPE_REG or v.__type == TYPE_FIFO or v.__type == TYPE_RAM)) then
for j,field in pairs(v) do
if (type(field) == 'table' and field.__type == TYPE_FIELD) then
func(field, v, periph);
end
end
end
end
end
end
function foreach_subfield(reg, func)
for j,field in pairs(reg) do
if (type(field) == 'table' and field.__type == TYPE_FIELD) then
func(field, reg);
end
end
end
function foreach_reg(func)
for i,v in pairs(periph) do
if(type(v) == 'table') then
if(v.__type ~= nil and (v.__type == TYPE_REG or v.__type == TYPE_FIFO or v.__type == TYPE_RAM)) then
func(v);
end
end
end
end
function align(field, offset)
local a;
if(field.align == nil) then
a=1;
else
a=field.align;
end
local newofs = a * math.floor((offset + a - 1) / a);
return newofs;
end
function calc_field_offsets(field, reg)
local ofs = reg.current_offset;
ofs = align(field, ofs);
-- print ("field "..field.name.." offset: "..ofs);
reg.current_offset = ofs + field.size;
field.offset = ofs;
if( reg.__type == TYPE_REG and reg.current_offset > DATA_BUS_WIDTH ) then
die ("Total size of register '"..reg.name.."' ("..reg.current_offset..") exceeds data bus width ("..DATA_BUS_WIDTH..")");
end
-- print ("field ", field.name, "align: ", align);
end
function die(s)
print ("Error: "..s);
os.exit(-1);
end
function match(var, values)
local i,v;
for i,v in pairs(values) do
if(var==v) then return true; end
end
return false;
end
function csel(cond, tr, fl)
if(cond) then
return tr;
else
return fl;
end
end
function flag_set(where, flag)
local i,v;
for i,v in pairs(where)do
if(v == flag) then return true; end
end
return false;
end
function fix_prefix(obj)
if(obj.c_prefix == nil or obj.hdl_prefix==nil) then
if(obj.prefix == nil and obj.__type ~= TYPE_FIELD) then
die ("No C/HDL prefix nor default prefix defined for field/reg/peripheral '"..obj.name.."'");
end
obj.c_prefix = obj.prefix;
obj.hdl_prefix = obj.prefix;
return obj;
end
return obj;
end
function default_access(field, mytype, acc_bus, acc_dev)
if(field.type == mytype) then
if(field.access_bus == nil) then
field.access_bus = acc_bus;
end
if(field.access_dev == nil) then
field.access_dev = acc_dev;
end
end
end
function fix_access(field, reg)
if(reg.__type == TYPE_REG) then
default_access(field, BIT, READ_WRITE, READ_ONLY);
default_access(field, SLV, READ_WRITE, READ_ONLY);
default_access(field, SIGNED, READ_WRITE, READ_ONLY);
default_access(field, UNSIGNED, READ_WRITE, READ_ONLY);
default_access(field, MONOSTABLE, WRITE_ONLY, READ_ONLY);
default_access(field, ENUM, READ_WRITE, READ_ONLY);
default_access(field, PASS_THROUGH, WRITE_ONLY, READ_ONLY);
if(field.access ~= nil) then
return;
end
if(field.access_bus == READ_ONLY and field.access_dev == WRITE_ONLY) then
field.access = ACC_RO_WO;
elseif (field.access_bus == WRITE_ONLY and field.access_dev == READ_ONLY) then
field.access = ACC_WO_RO;
elseif (field.access_bus == READ_WRITE and field.access_dev == READ_WRITE) then
field.access = ACC_RW_RW;
elseif (field.access_bus == READ_WRITE and field.access_dev == READ_ONLY) then
field.access = ACC_RW_RO;
else
die ("Illegal access flags combination for field '"..field.name.."' in register '"..reg.name.."'");
end
end
end
function check_max_size(reg)
if(reg.total_size > DATA_BUS_WIDTH and reg.__type == TYPE_REG) then
die ("register ", reg.name, " size exceeds data bus witdh (", DATA_BUS_WIDTH, " bits)");
end
end
all_regs_size = 0;
max_ram_addr_bits = 0;
block_bits = 0;
num_rams = 0;
function log2 (x)
return math.floor(math.log(x) / math.log(2));
end
function log2up (x)
return math.ceil(math.log(x) / math.log(2));
end
function is_power_of_2(x)
for i=1,24 do
if(x == math.pow(2, i)) then return true; end
end
return false;
end
function calc_address_sizes(reg)
if(reg.__type == TYPE_REG) then
-- for ordinary registers - just count them
all_regs_size = align(reg, all_regs_size) + 1;
elseif (reg.__type == TYPE_FIFO) then
-- for FIFOS:
-- size of all FIFO fields (rounded up to multiple of 32 bits) + 1 extra FIFO control register
fifo_size = math.floor((reg.total_size + DATA_BUS_WIDTH - 1) / DATA_BUS_WIDTH) + 1;
all_regs_size = all_regs_size + fifo_size;
reg.num_fifo_regs = fifo_size;
else
-- for rams:
if(not is_power_of_2(reg.size)) then die ("RAM '"..reg.name.."': memory size must be a power of 2"); end
print("RAM: "..reg.size.." entries");
if (reg.wrap_bits == nil) then
reg.wrap_bits = 0;
end
reg.addr_bits = log2(reg.size * math.pow(2, reg.wrap_bits));
print("RAM: address size "..reg.addr_bits);
if(max_ram_addr_bits < reg.addr_bits) then
max_ram_addr_bits = reg.addr_bits;
end
if(reg.width > DATA_BUS_WIDTH) then
die("RAM '"..reg.name.."' data width exceeds WB data bus width");
end
reg.select_bits = num_rams + 1;
num_rams = num_rams + 1;
end
regbank_address_bits = log2up (all_regs_size);
-- print("all_regs: "..all_regs_size);
end
function assign_addresses()
local block_bits = math.max(max_ram_addr_bits, log2up(all_regs_size));
local num_blocks = num_rams;
local i = 0;
if(all_regs_size > 0) then
num_blocks = num_blocks + 1;
end
local select_bits = log2up (num_blocks);
print("Total bits per block: "..block_bits..", select bits: "..select_bits);
foreach_reg(function(reg)
if(reg.__type==TYPE_REG) then
reg.base = align(reg, i);
i=reg.base+1;
print("base "..reg.name.." = "..reg.base);
elseif(reg.__type == TYPE_FIFO) then
reg.base = i;
i=i+reg.num_fifo_regs;
print("fifo base "..reg.name.." = "..reg.base);
end
end );
address_bus_width = block_bits + select_bits;
address_bus_select_bits = select_bits;
end
function find_max(table, field)
local mval = 0;
local i,v;
for i,v in pairs(table) do if(type(v) == 'table' and v[field]~=nil and v[field] > mval) then mval = v[field]; end end
return mval;
end
function table_join(table_out, table_in)
local i,v;
if(table_in == nil) then return; end
for i,v in pairs(table_in) do
table.insert(table_out, v);
end
end
function tree_2_table(entry)
local tab = {};
foreach_reg(function(reg)
if(reg[entry] ~= nil) then
if(type(reg[entry]) == 'table') then
table_join(tab, reg[entry]);
else
table.insert(tab, reg[entry]);
end
end
foreach_subfield(reg, function(field, reg)
if(field[entry] ~= nil) then
if(type(field[entry]) == 'table') then
table_join(tab, field[entry]);
else
table.insert(tab, field[entry]);
end
end
end);
end);
return tab;
end
function remove_duplicates(t)
local i=1,v,j;
while(t[i] ~= nil) do
for j=1,i-1 do if(t[j]==t[i]) then table.remove(t, i); i=i-1; end end
i=i+1;
end
end
\ No newline at end of file
#!/usr/bin/lua
function gen_vhdl_ramcode(ram)
local prefix = string.lower(periph.hdl_prefix.."_"..ram.hdl_prefix);
-- generate the RAM-related ports
ram.ports = { port (SLV, ram.addr_bits - ram.wrap_bits, "in", prefix.."_addr_i", "Ports for RAM: "..ram.name ) };
if(match(ram.access_dev, {READ_ONLY, READ_WRITE})) then
table_join(ram.ports, { port(SLV, ram.width, "out", prefix.."_data_o") });
end
if(match(ram.access_dev, {WRITE_ONLY, READ_WRITE})) then
table_join(ram.ports, { port(SLV, ram.width, "in", prefix.."_data_i"),
port(BIT, 0, "in", prefix.."_we_i") });
end
local raminst = vhdl_new_instance();
end
function gen_vhdl_rams()
foreach_reg(function(reg) if(reg.__type == TYPE_RAM) then gen_vhdl_ramcode(reg); end end);
end
\ No newline at end of file
-- -*- Mode: LUA; tab-width: 2 -*-
-- wbgen2 - a simple Wishbone slave generator
-- (c) 2010 Tomasz Wlostowski
-- CERN BE-Co-HT
-- LICENSED UNDER GPL v2
function gen_vhdl_field_prefix(field, reg)
local field_count;
if(reg.hdl_prefix == nil) then
die("no prefix specified for reg: "..reg.name);
end
field_count = 0;
foreach_subfield(reg, function(field, reg) field_count = field_count+1; end );
if(field.count == 0) then
die("empty reg: "..reg.name);
end
if(field.prefix == nil) then
if(field_count >1 ) then die("multiple anonymous-prefix fields declared for reg: "..reg.name); end
return string.lower(periph.hdl_prefix.."_"..reg.hdl_prefix);
end
return string.lower(periph.hdl_prefix.."_"..reg.hdl_prefix.."_"..field.hdl_prefix);
end
-- generates VHDL for monostable-type field (both same-clock and other-clock)
function gen_vhdl_code_monostable(field, reg)
local prefix = gen_vhdl_field_prefix(field, reg);
-- field.prefix = prefix;
-- monostable type field using WB bus clock
if(field.clock == nil) then
-- WB-synchronous monostable port (bus write-only)
field.signals = { signal(BIT, 0, prefix.."_dly0"),
signal(BIT, 0, prefix.."_int") };
field.ports = { port(BIT, 0, "out", prefix.."_o", "Port for MONOSTABLE field: '"..field.name.."' in reg: '"..reg.name.."'" ) };
field.acklen = 3;
field.extra_code = {"process (wb_clk_i, rst_n_i)",
"begin",
"if(rst_n_i = '0') then",
prefix.."_dly0 <= '0';",
prefix.."_o <= '0';",
"elsif rising_edge(wb_clk_i) then",
prefix.."_dly0 <= "..prefix.."_int;",
prefix.."_o <= "..prefix.."_int and (not "..prefix.."_dly0);",
"end if;",
"end process;" };
field.reset_code_main = { prefix.."_int <= '0';" };
field.write_code = { prefix.."_int <= wb_data_i("..field.offset..");" };
field.read_code = { "" };
field.ackgen_code = { prefix.."_int <= '0';" };
else
-- WB-asynchronous monostable port (bus write-only)
field.signals = { signal(BIT, 0, prefix.."_int"),
signal(BIT, 0, prefix.."_int_delay"),
signal(BIT, 0, prefix.."_sync0"),
signal(BIT, 0, prefix.."_sync1"),
signal(BIT, 0, prefix.."_sync2") };
field.ports = { port(BIT, 0, "out", prefix.."_o", "Port for asynchronous (clock: "..field.clock..") MONOSTABLE field: '"..field.name.."' in reg: '"..reg.name.."'") };
field.acklen = 5;
field.extra_code = { "process ("..field.clock..", rst_n_i)",
"begin",
"if(rst_n_i = '0') then",
prefix.."_o <= '0';",
prefix.."_sync0 <= '0';",
prefix.."_sync1 <= '0';",
prefix.."_sync2 <= '0';",
"elsif rising_edge("..field.clock..") then",
prefix.."_sync0 <= "..prefix.."_int;",
prefix.."_sync1 <= "..prefix.."_sync0;",
prefix.."_sync2 <= "..prefix.."_sync1;",
prefix.."_o <= "..prefix.."_sync2 and (not "..prefix.."_sync1);",
"end if;",
"end process;" };
field.reset_code_main = { prefix.."_int <= '0';",
prefix.."_int_delay <= '0';" };
field.write_code = { prefix.."_int <= wb_data_i("..field.offset..");",
prefix.."_int_delay <= wb_data_i("..field.offset..");" };
field.read_code = { "" };
field.ackgen_code_pre = { prefix.."_int <= "..prefix.."_int_delay;",
prefix.."_int_delay <= '0';" };
end
end
-- generates code for BIT-type field
function gen_vhdl_code_bit(field, reg)
local prefix = gen_vhdl_field_prefix(field, reg);
field.prefix = prefix;
-- BIT-type field using WB bus clock
if(field.clock == nil) then
if(field.access == ACC_RW_RO) then
-- bus(read-write), dev(read-only) bitfield
field.ports = { port(BIT, 0, "out", prefix.."_o", "Port for BIT field: '"..field.name.."' in reg: '"..reg.name.."'" ) };
field.signals = { signal(BIT, 0, prefix.."_int") };
field.acklen = 1;
field.write_code = { prefix.."_int <= wb_data_i("..field.offset..");" };
field.read_code = { "wb_data_out_int("..field.offset..") <= "..prefix.."_int;" };
field.reset_code_main = { prefix.."_int <= '0';" };
field.extra_code = { prefix.."_o <= "..prefix.."_int; "};
elseif (field.access == ACC_RO_WO) then
-- bus(read-only), dev(read-only) bitfield
field.ports = { port(BIT, 0, "in", prefix.."_i", "Port for BIT field: '"..field.name.."' in reg: '"..reg.name.."'") };
field.signals = { };
field.acklen = 1;
field.write_code = { };
field.read_code = { "wb_data_out_int("..field.offset..") <= "..prefix.."_i;" };
field.reset_code_main = { };
field.extra_code = { };
elseif (field.access == ACC_WO_RO) then
-- bus(write-only), dev(read-only) bitfield - unsupported yet (use RW/RO type instead)
die("WO-RO type unsupported yet ("..field.name..")");
elseif (field.access == ACC_RW_RW) then
-- dual-write bitfield (both from the bus and the device)
if(field.load == LOAD_EXT) then
-- external load type (e.g. the register itself is placed outside the WB slave, which only outputs new value and asserts the "load" signal for single clock cycle upon bus write.
field.ports = { port(BIT, 0, "out", prefix.."_o", "Ports for BIT field: '"..field.name.."' in reg: '"..reg.name.."'"),
port(BIT, 0, "in", prefix.."_i"),
port(BIT, 0, "out", prefix.."_load_o") };
field.acklen = 1;
field.read_code = { "wb_data_out_int("..field.offset..") <= "..prefix.."_i;" };
field.write_code = { prefix.."_load_o <= '1';" };
field.extra_code = { prefix.."_o <= wb_data_i("..field.offset..");" };
field.ackgen_code_pre = { prefix.."_load_o <= '0';" };
field.ackgen_code = { prefix.."_load_o <= '0';" };
field.reset_code_main = { prefix.."_load_o <= '0';" };
else
die("internal RW/RW register storage unsupported yet ("..field.name..")");
end
end
else
-- asynchronous bit-type register
if(field.access == ACC_RW_RO) then
-- bus(read-write), dev(read-only) bitfield, asynchronous
field.ports = { port(BIT, 0, "out", prefix.."_o", "Port for asynchronous (clock: "..field.clock..") BIT field: '"..field.name.."' in reg: '"..reg.name.."'") };
field.signals = { signal(BIT, 0, prefix.."_int"),
signal(BIT, 0, prefix.."_sync0"),
signal(BIT, 0, prefix.."_sync1") };
field.acklen = 4;
field.write_code = { prefix.."_int <= wb_data_i("..field.offset..");" };
field.read_code = { "wb_data_out_int("..field.offset..") <= "..prefix.."_int;" };
field.reset_code_main = { prefix.."_int <= '0';" };
field.extra_code = { "-- synchronizer chain for field : "..field.name.." (type RW/RO, wb_clk_i <-> "..field.clock..")",
"process ("..field.clock..", rst_n_i)",
"begin",
"if(rst_n_i = '0') then",
prefix.."_o <= '0';",
prefix.."_sync0 <= '0';",
prefix.."_sync1 <= '0';",
"elsif rising_edge("..field.clock..") then",
prefix.."_sync0 <= "..prefix.."_int;",
prefix.."_sync1 <= "..prefix.."_sync0;",
prefix.."_o <= "..prefix.."_sync1;",
"end if;",
"end process;" };
elseif (field.access == ACC_RO_WO) then
-- bus(read-only), dev(write-only) bitfield, asynchronous
field.ports = { port(BIT, 0, "in", prefix.."_i", "Port for asynchronous (clock: "..field.clock..") BIT field: '"..field.name.."' in reg: '"..reg.name.."'") };
field.signals = { signal(BIT, 0, prefix.."_sync0"),
signal(BIT, 0, prefix.."_sync1") };
field.acklen = 1;
field.write_code = { };
field.read_code = { "wb_data_out_int("..field.offset..") <= "..prefix.."_sync1;" };
field.reset_code_main = { };
field.extra_code = { "-- synchronizer chain for field : "..field.name.." (type RO/WO, "..field.clock.." -> wb_clk_i)",
"process (wb_clk_i, rst_n_i)",
"begin",
"if(rst_n_i = '0') then",
prefix.."_sync0 <= '0';",
prefix.."_sync1 <= '0';",
"elsif rising_edge(wb_clk_i) then",
prefix.."_sync0 <= "..prefix.."_i;",
prefix.."_sync1 <= "..prefix.."_sync0;",
"end if;",
"end process;" };
elseif (field.access == ACC_RW_RW) then
-- asynchronous dual-write bitfield. Tough shit :/
if(field.load ~= LOAD_EXT) then
die("Only external load is supported for RW/RW bit fields");
end
local comment = "Ports for asynchronous (clock: "..field.clock..") RW/RW BIT field: '"..field.name.."' in reg: '"..reg.name.."'";
field.ports = { port(BIT, 0, "out", prefix.."_o", comment),
port(BIT, 0, "in", prefix.."_i"),
port(BIT, 0, "out", prefix.."_load_o") };
field.signals = { signal(BIT, 0, prefix.."_int_read"),
signal(BIT, 0, prefix.."_int_write"),
signal(BIT, 0, prefix.."_lw"),
signal(BIT, 0, prefix.."_lw_delay"),
signal(BIT, 0, prefix.."_lw_read_in_progress"),
signal(BIT, 0, prefix.."_lw_s0"),
signal(BIT, 0, prefix.."_lw_s1"),
signal(BIT, 0, prefix.."_lw_s2"),
signal(BIT, 0, prefix.."_rwsel") };
field.acklen = 6;
field.write_code = { prefix.."_int_write <= wb_data_i("..field.offset..");",
prefix.."_lw <= '1';",
prefix.."_lw_delay <= '1';",
prefix.."_lw_read_in_progress <= '0';",
prefix.."_rwsel <= '1'; " };
field.read_code = { prefix.."_lw <= '1';",
prefix.."_lw_delay <= '1';",
prefix.."_lw_read_in_progress <= '1';",
prefix.."_rwsel <= '0'; " };
field.reset_code_main = { prefix.."_lw <= '0';",
prefix.."_lw_delay <= '0';",
prefix.."_lw_read_in_progress <= '0';",
prefix.."_rwsel <= '0';",
prefix.."_int_write <= '0';"
};
field.ackgen_code_pre = { prefix.."_lw <= "..prefix.."_lw_delay; ",
prefix.."_lw_delay <= '0'; ",
"if ((ack_cntr = "..gen_vhdl_bin_literal(1,4)..") and ("..prefix.."_lw_read_in_progress = '1')) then",
"wb_data_out_int("..field.offset..") <= "..prefix.."_int_read;",
prefix.."_lw_read_in_progress <= '0';",
"end if;" };
field.extra_code = { "-- asynchronous BIT register : "..field.name.." (type RW/WO, "..field.clock.." <-> wb_clk_i)",
"process ("..field.clock..", rst_n_i)",
"begin",
"if(rst_n_i = '0') then",
prefix.."_lw_s0 <= '0';",
prefix.."_lw_s1 <= '0';",
prefix.."_lw_s2 <= '0';",
prefix.."_int_read <= '0';",
prefix.."_load_o <= '0';",
prefix.."_o <= '0';",
"elsif rising_edge("..field.clock..") then",
prefix.."_lw_s0 <= "..prefix.."_lw;",
prefix.."_lw_s1 <= "..prefix.."_lw_s0;",
prefix.."_lw_s2 <= "..prefix.."_lw_s1;",
"if("..prefix.."_lw_s2 = '0' and "..prefix.."_lw_s1 = '1') then",
"if("..prefix.."_rwsel = '1') then",
prefix.."_o <= "..prefix.."_int_write;",
prefix.."_load_o <= '1';",
"else",
prefix.."_load_o <= '0';",
prefix.."_int_read <= "..prefix.."_i;",
"end if;",
"else",
prefix.."_load_o <= '0';",
"end if;",
"end if;",
"end process;" };
elseif (field.access == ACC_WO_RO) then
die("WO-RO type unsupported yet ("..field.name..")");
end
end
end
-- generates the bit-range for accessing a certain register field from WB-bus
function gen_vhdl_subrange(field)
local s;
s="("..(field.offset+field.size-1).." downto "..(field.offset)..")";
return s;
end
-- converts field of type (slv) to type (type)
function convert_from_slv(type, prefix)
if(type == UNSIGNED) then
return "unsigned("..prefix..")";
elseif (type == SIGNED) then
return "signed("..prefix..")";
else return prefix; end
end
-- ... and vice versa
function convert_to_slv(type, prefix)
if(type == UNSIGNED) then
return "std_logic_vector("..prefix..")";
elseif (type == SIGNED) then
return "std_logic_vector("..prefix..")";
else return prefix; end
end
-- generates code for slv, signed or unsigned fields
function gen_vhdl_code_slv(field, reg)
local prefix = gen_vhdl_field_prefix(field, reg);
local is_slv = (field.type == SLV);
local name_slv_i = csel(is_slv , prefix.."_i", prefix.."_i_slv");
local name_slv_o = csel(is_slv , prefix.."_o", prefix.."_o_slv");
field.prefix = prefix;
-- synchronous signed/unsigned/slv field
if(field.clock == nil) then
if(field.access == ACC_RW_RO) then
-- bus(read-write), dev(read-only) slv
field.ports = { port(field.type, field.size, "out", prefix.."_o", "Port for "..fieldtype_2_vhdl[field.type].." field: '"..field.name.."' in reg: '"..reg.name.."'") };
field.signals = { signal(SLV, field.size, prefix.."_int") };
field.acklen = 1;
field.write_code = { prefix.."_int <= wb_data_i"..gen_vhdl_subrange(field)..";" };
field.read_code = { "wb_data_out_int"..gen_vhdl_subrange(field).." <= "..prefix.."_int;" };
field.reset_code_main = { prefix.."_int <= (others => '0');" };
field.extra_code = { prefix.."_o <= "..convert_from_slv(field.type, prefix.."_int")..";"};
elseif (field.access == ACC_RO_WO) then
-- bus(read-only), dev(write-only) slv
field.ports = { port(field.type, field.size, "in", prefix.."_i", "Port for "..fieldtype_2_vhdl[field.type].." field: '"..field.name.."' in reg: '"..reg.name.."'") };
field.signals = { };
field.acklen = 1;
field.write_code = { };
field.read_code = { "wb_data_out_int"..gen_vhdl_subrange(field).." <= "..convert_to_slv(field.type, prefix.."_i")..";" };
field.reset_code_main = { };
field.extra_code = { };
elseif (field.access == ACC_RW_RW) then
-- bus(read-write), dev(read-write) slv
if(field.load ~= LOAD_EXT) then
die("Only external load is supported for RW/RW slv/signed/unsigned fields");
end
field.ports = { port(field.type, field.size, "out", prefix.."_o", "Port for "..fieldtype_2_vhdl[field.type].." field: '"..field.name.."' in reg: '"..reg.name.."'"),
port(field.type, field.size, "in", prefix.."_i"),
port(BIT, 0, "out", prefix.."_load_o") };
field.acklen = 1;
field.read_code = { "wb_data_out_int"..gen_vhdl_subrange(field).." <= "..convert_to_slv(field.type, prefix.."_i")..";" };
field.write_code = { prefix.."_load_o <= '1';" };
field.extra_code = { prefix.."_o <= "..convert_from_slv(field.type, "wb_data_i"..gen_vhdl_subrange(field))..";" };
field.ackgen_code_pre = { prefix.."_load_o <= '0';" };
field.ackgen_code = { prefix.."_load_o <= '0';" };
field.reset_code_main = { prefix.."_load_o <= '0';" };
end
else
-- asynchronous register. Even tougher shit :(
if(field.access == ACC_RW_RO) then
-- bus(read-write), dev(read-only) slv/signed/unsigned
local comment = "Port for asynchronous (clock: "..field.clock..") "..fieldtype_2_vhdl[field.type].." field: '"..field.name.."' in reg: '"..reg.name.."'";
field.ports = { port(field.type, field.size, "out", prefix.."_o", comment) };
field.signals = { signal(SLV, field.size, prefix.."_int"),
signal(BIT, 0, prefix.."_swb"),
signal(BIT, 0, prefix.."_swb_delay"),
signal(BIT, 0, prefix.."_swb_s0"),
signal(BIT, 0, prefix.."_swb_s1"),
signal(BIT, 0, prefix.."_swb_s2") };
field.acklen = 4;
field.write_code = { prefix.."_int <= wb_data_i"..gen_vhdl_subrange(field)..";",
prefix.."_swb <= '1';",
prefix.."_swb_delay <= '1';" };
field.read_code = { "wb_data_out_int"..gen_vhdl_subrange(field).." <= "..prefix.."_int;" };
field.reset_code_main = { prefix.."_int <= (others => '0');",
prefix.."_swb <= '0'; ",
prefix.."_swb_delay <= '0';" };
field.ackgen_code_pre = { prefix.."_swb <= "..prefix.."_swb_delay; ",
prefix.."_swb_delay <= '0';" };
field.extra_code = { "-- asynchronous "..fieldtype_2_vhdl[field.type].." register : "..field.name.." (type RW/RO, "..field.clock.." <-> wb_clk_i)",
"process ("..field.clock..", rst_n_i)",
"begin",
"if(rst_n_i = '0') then",
prefix.."_swb_s0 <= '0';",
prefix.."_swb_s1 <= '0';",
prefix.."_swb_s2 <= '0';",
prefix.."_o <= (others => '0');",
"elsif rising_edge("..field.clock..") then",
prefix.."_swb_s0 <= "..prefix.."_swb;",
prefix.."_swb_s1 <= "..prefix.."_swb_s0;",
prefix.."_swb_s2 <= "..prefix.."_swb_s1;",
"if("..prefix.."_swb_s2 = '0' and "..prefix.."_swb_s1 = '1') then",
prefix.."_o <= "..convert_from_slv(field.type, prefix.."_int")..";",
"end if;",
"end if;",
"end process;" };
elseif(field.access == ACC_RO_WO) then
-- bus(read-write), dev(read-only) slv
local comment = "Port for asynchronous (clock: "..field.clock..") "..fieldtype_2_vhdl[field.type].." field: '"..field.name.."' in reg: '"..reg.name.."'";
field.ports = { port(field.type, field.size, "in", prefix.."_i", comment) };
field.signals = { signal(SLV, field.size, prefix.."_int"),
signal(BIT, 0, prefix.."_lwb"),
signal(BIT, 0, prefix.."_lwb_delay"),
signal(BIT, 0, prefix.."_lwb_in_progress"),
signal(BIT, 0, prefix.."_lwb_s0"),
signal(BIT, 0, prefix.."_lwb_s1"),
signal(BIT, 0, prefix.."_lwb_s2") };
field.acklen = 6;
field.write_code = { };
field.read_code = { prefix.."_lwb <= '1';",
prefix.."_lwb_delay <= '1';",
prefix.."_lwb_in_progress <= '1';" };
field.reset_code_main = { prefix.."_lwb <= '0';",
prefix.."_lwb_delay <= '0';",
prefix.."_lwb_in_progress <= '0';" };
field.ackgen_code_pre = { prefix.."_lwb <= "..prefix.."_lwb_delay; ",
prefix.."_lwb_delay <= '0'; ",
"if ((ack_cntr = "..gen_vhdl_bin_literal(1,4)..") and ("..prefix.."_lwb_in_progress = '1')) then",
"wb_data_out_int"..gen_vhdl_subrange(field).." <= "..prefix.."_int;",
prefix.."_lwb_in_progress <= '0';",
"end if;", };
field.extra_code = { "-- asynchronous "..fieldtype_2_vhdl[field.type].." register : "..field.name.." (type RO/WO, "..field.clock.." <-> wb_clk_i)",
"process ("..field.clock..", rst_n_i)",
"begin",
"if(rst_n_i = '0') then",
prefix.."_lwb_s0 <= '0';",
prefix.."_lwb_s1 <= '0';",
prefix.."_lwb_s2 <= '0';",
prefix.."_int <= (others => '0');",
"elsif rising_edge("..field.clock..") then",
prefix.."_lwb_s0 <= "..prefix.."_lwb;",
prefix.."_lwb_s1 <= "..prefix.."_lwb_s0;",
prefix.."_lwb_s2 <= "..prefix.."_lwb_s1;",
"if("..prefix.."_lwb_s1 = '1' and "..prefix.."_lwb_s2 = '0') then",
prefix.."_int <= "..convert_to_slv(field.type, prefix.."_i")..";",
"end if;",
"end if;",
"end process;" };
elseif(field.access == ACC_RW_RW) then
-- async bus(read-write), dev(read-write) slv. gooosh...
if(field.load ~= LOAD_EXT) then
die("Only external load is supported for RW/RW slv/signed/unsigned fields");
end
local comment = "Ports for asynchronous (clock: "..field.clock..") "..fieldtype_2_vhdl[field.type].." field: '"..field.name.."' in reg: '"..reg.name.."'";
field.ports = { port(field.type, field.size, "out", prefix.."_o", comment),
port(field.type, field.size, "in", prefix.."_i"),
port(BIT, 0, "out", prefix.."_load_o") };
field.signals = { signal(SLV, field.size, prefix.."_int_read"),
signal(SLV, field.size, prefix.."_int_write"),
signal(BIT, 0, prefix.."_lw"),
signal(BIT, 0, prefix.."_lw_delay"),
signal(BIT, 0, prefix.."_lw_read_in_progress"),
signal(BIT, 0, prefix.."_lw_s0"),
signal(BIT, 0, prefix.."_lw_s1"),
signal(BIT, 0, prefix.."_lw_s2"),
signal(BIT, 0, prefix.."_rwsel") };
field.acklen = 6;
field.write_code = { prefix.."_int_write <= wb_data_i"..gen_vhdl_subrange(field)..";",
prefix.."_lw <= '1';",
prefix.."_lw_delay <= '1';",
prefix.."_lw_read_in_progress <= '0';",
prefix.."_rwsel <= '1'; " };
field.read_code = { prefix.."_lw <= '1';",
prefix.."_lw_delay <= '1';",
prefix.."_lw_read_in_progress <= '1';",
prefix.."_rwsel <= '0'; " };
field.reset_code_main = { prefix.."_lw <= '0';",
prefix.."_lw_delay <= '0';",
prefix.."_lw_read_in_progress <= '0';",
prefix.."_rwsel <= '0';",
prefix.."_int_write <= (others => '0');"
};
field.ackgen_code_pre = { prefix.."_lw <= "..prefix.."_lw_delay; ",
prefix.."_lw_delay <= '0'; ",
"if ((ack_cntr = "..gen_vhdl_bin_literal(1,4)..") and ("..prefix.."_lw_read_in_progress = '1')) then",
"wb_data_out_int"..gen_vhdl_subrange(field).." <= "..prefix.."_int_read;",
prefix.."_lw_read_in_progress <= '0';",
"end if;", };
field.extra_code = { "-- asynchronous "..fieldtype_2_vhdl[field.type].." register : "..field.name.." (type RW/WO, "..field.clock.." <-> wb_clk_i)",
"process ("..field.clock..", rst_n_i)",
"begin",
"if(rst_n_i = '0') then",
prefix.."_lw_s0 <= '0';",
prefix.."_lw_s1 <= '0';",
prefix.."_lw_s2 <= '0';",
prefix.."_o <= (others => '0');",
prefix.."_load_o <= '0';",
prefix.."_int_read <= (others => '0');",
"elsif rising_edge("..field.clock..") then",
prefix.."_lw_s0 <= "..prefix.."_lw;",
prefix.."_lw_s1 <= "..prefix.."_lw_s0;",
prefix.."_lw_s2 <= "..prefix.."_lw_s1;",
"if("..prefix.."_lw_s2 = '0' and "..prefix.."_lw_s1 = '1') then",
"if("..prefix.."_rwsel = '1') then",
prefix.."_o <= "..convert_from_slv(field.type, prefix.."_int_write")..";",
prefix.."_load_o <= '1';",
"else",
prefix.."_load_o <= '0';",
prefix.."_int_read <= "..convert_to_slv(field.type, prefix.."_i")..";",
"end if;",
"else",
prefix.."_load_o <= '0';",
"end if;",
"end if;",
"end process;" };
end
end
end
function gen_vhdl_code_passthrough(field, reg)
local prefix = gen_vhdl_field_prefix(field, reg);
if(field.clock == nil) then
-- sync pass-through
local comment = "Ports for PASS_THROUGH field: '"..field.name.."' in reg: '"..reg.name.."'";
field.ports = { port(SLV, field.size, "out", prefix.."_o", comment),
port(BIT, 0, "out", prefix.."_wr_o") };
field.acklen = 1;
field.reset_code_main = { prefix.."_wr_o <= '0';" };
field.read_code = {};
field.write_code = { prefix.."_wr_o <= '1';" };
field.ackgen_code_pre = { prefix.."_wr_o <= '0';" };
field.ackgen_code = { prefix.."_wr_o <= '0';" };
field.extra_code = { "-- pass-through field: "..field.name.." in register: "..reg.name,
prefix.."_o <= wb_data_i"..gen_vhdl_subrange(field)..";" }
else
local comment = "Ports for asynchronous (clock: "..field.clock..") PASS_THROUGH field: '"..field.name.."' in reg: '"..reg.name.."'";
field.ports = { port(SLV, field.size, "out", prefix.."_o", comment),
port(BIT, 0, "out", prefix.."_wr_o") };
field.signals = { signal(BIT, 0, prefix.."_wr_int"),
signal(BIT, 0, prefix.."_wr_int_delay"),
signal(BIT, 0, prefix.."_wr_sync0"),
signal(BIT, 0, prefix.."_wr_sync1"),
signal(BIT, 0, prefix.."_wr_sync2") };
field.acklen = 4;
field.reset_code_main = { prefix.."_wr_int <= '0';",
prefix.."_wr_int_delay <= '0';" };
field.read_code = {};
field.write_code = { prefix.."_wr_int <= '1';",
prefix.."_wr_int_delay <= '1';" };
field.ackgen_code_pre = { prefix.."_wr_int <= "..prefix.."_wr_int_delay;",
prefix.."_wr_int_delay <= '0';" };
field.extra_code = { "-- pass-through field: "..field.name.." in register: "..reg.name,
prefix.."_o <= wb_data_i"..gen_vhdl_subrange(field)..";",
"process ("..field.clock..", rst_n_i )",
"begin",
"if(rst_n_i = '0') then",
prefix.."_wr_sync0 <= '0';",
prefix.."_wr_sync1 <= '0';",
prefix.."_wr_sync2 <= '0';",
"elsif rising_edge("..field.clock..") then",
prefix.."_wr_sync0 <= "..prefix.."_wr_int;",
prefix.."_wr_sync1 <= "..prefix.."_wr_sync0;",
prefix.."_wr_sync2 <= "..prefix.."_wr_sync1;",
prefix.."_wr_o <= "..prefix.."_wr_sync1 and (not "..prefix.."_wr_sync2);",
"end if;",
"end process;" };
end
end
-- generates VHDL code for single register field
function gen_vhdl_code_reg_field(field, reg)
if(field.type == MONOSTABLE) then
gen_vhdl_code_monostable(field, reg);
elseif(field.type == BIT) then
gen_vhdl_code_bit(field, reg);
elseif(field.type == SIGNED or field.type == UNSIGNED or field.type == SLV) then
gen_vhdl_code_slv(field, reg);
elseif(field.type == PASS_THROUGH) then
gen_vhdl_code_passthrough(field, reg);
end
end
-- generates VHDL for single register
function gen_vhdl_code_reg(reg)
foreach_subfield(reg, function(field, reg) gen_vhdl_code_reg_field(field, reg); end );
end
function gen_vhdl_block_select_bits()
return "wb_addr_i("..(address_bus_width-1).." downto "..(address_bus_width - address_bus_select_bits)..")";
end
-- generates the entire VHDL register-bank access stuff
function gen_vhdl_regbank()
local s;
local ramcount = 0;
vhdl_new_code();
foreach_reg(function(reg)
if(reg.__type == TYPE_REG) then
gen_vhdl_code_reg(reg);
end
end );
vhdl ("");
vhdl ("begin");
vhdl ("-- MAIN REGISTER BANK PROCESS --");
vhdl ("process (wb_clk_i, rst_n_i)");
vhdl ("begin");
-- generate reset code for the main process
vhdl ("if(rst_n_i = '0') then");
vhdl ("-- Resetting the signals --");
vhdl ("");
foreach_field(function(field, reg)
if (field.reset_code_main ~= nil) then
vhdl_paste_code (field.reset_code_main);
end
end );
vhdl ("wb_ack_regbank <= '0';");
vhdl ("ack_in_progress <= '0';");
vhdl ("ack_cntr <= "..gen_vhdl_bin_literal(0,4)..";");
vhdl ("wb_data_out_int <= (others => '0');");
vhdl ("");
vhdl ("elsif rising_edge(wb_clk_i) then");
vhdl ("-- ACK signal generator --");
vhdl ("if ack_in_progress = '1' then");
vhdl ("if(ack_cntr = "..gen_vhdl_bin_literal(0,4)..") then");
foreach_reg(function(reg)
if(reg.__type == TYPE_REG) then
foreach_subfield(reg, function(field, reg)
vhdl_paste_code(field.ackgen_code);
end );
end
end );
vhdl ("ack_in_progress <= '0';");
vhdl ("wb_ack_regbank <= '0';");
vhdl ("else");
foreach_reg(function(reg)
if(reg.__type == TYPE_REG) then
foreach_subfield(reg, function(field, reg)
vhdl_paste_code(field.ackgen_code_pre);
end );
end
end );
vhdl ("ack_cntr <= ack_cntr - 1;");
vhdl ("if (ack_cntr = "..gen_vhdl_bin_literal(1,4)..") then");
vhdl ("wb_ack_regbank <= '1';");
vhdl ("else");
vhdl ("wb_ack_regbank <= '0';");
vhdl ("end if;");
vhdl ("end if;");
vhdl ("else");
-- count the RAMs in the design
foreach_reg(function(reg)
if(reg.__type == TYPE_RAM) then
ramcount = ramcount + 1;
end
end
);
if(ramcount > 0) then
vhdl ("case "..gen_vhdl_block_select_bits().." is ");
foreach_reg(function(reg)
if (reg.__type == TYPE_RAM) then
vhdl ("when "..gen_vhdl_bin_literal(reg.select_bits, address_bus_select_bits).." => ");
vhdl ("wb_ack_regbank <= '1'; ack_in_progress <= '1'; ack_cntr <= "..gen_vhdl_bin_literal(0,4).."; ");
end
end );
vhdl ("when "..gen_vhdl_bin_literal(0, address_bus_select_bits).." => ");
end
vhdl ("if ( wb_sel_i = '1' and wb_cyc_i = '1' and wb_stb_i = '1' ) then");
if(regbank_address_bits > 0) then
vhdl ("case (wb_addr_i("..(regbank_address_bits -1 ).." downto 0)) is");
end
foreach_reg(function(reg)
if(reg.__type == TYPE_REG) then
local acklen = find_max(reg, "acklen");
if(regbank_address_bits > 0) then
vhdl ("when "..gen_vhdl_bin_literal(reg.base, regbank_address_bits).." => \t-- "..reg.name.."");
end
vhdl ("if(wb_we_i = '1') then -- write access");
foreach_subfield(reg, function(field, reg) vhdl_paste_code(field.write_code); end );
vhdl ("else -- read access");
foreach_subfield(reg, function(field, reg) vhdl_paste_code(field.read_code); end );
vhdl ("end if; ");
-- emit the ACK generation code. Special case for 1-cycle ACK
-- if(acklen == 1) then
-- vhdl("ack_in_progress <= '0'; ");
--else
vhdl("wb_ack_regbank <= "..csel((acklen==1),"'1'","'0'")..";");
vhdl("ack_cntr <= "..gen_vhdl_bin_literal(math.max(acklen-1, 0),4)..";");
vhdl("ack_in_progress <= '1'; ");
end
end );
if(regbank_address_bits > 0) then
vhdl("when others => ");
vhdl("ack_in_progress <= '0'; ack_cntr <= "..gen_vhdl_bin_literal(0,4).."; wb_ack_regbank <= '0';");
vhdl ("end case;");
end
vhdl ("else");
vhdl ("wb_ack_regbank <= '0';");
vhdl ("end if;");
if(ramcount > 0) then
vhdl("when others => ack_in_progress <= '0'; ack_cntr <= "..gen_vhdl_bin_literal(0,4).."; ");
-- vhdl_indent_left();
-- vhdl_indent_left();
vhdl("end case; ");
end
vhdl ("end if;")
vhdl ("end if;")
vhdl ("end process;");
vhdl("");
-- vhdl_indent_right();
foreach_reg(function(reg)
if(reg.extra_code ~= nil) then
vhdl("-- extra code for reg/fifo/mem: "..reg.name);
vhdl_paste_code(reg.extra_code);
vhdl("");
end
foreach_subfield(reg, function(field, reg) vhdl_paste_code(field.extra_code); vhdl("");end );
end);
return code_vhdl;
end
#!/usr/bin/lua
-- wbgen2, (c) 2010 Tomasz Wlostowski
-- CERN BE-Co-HT
-- LICENSED UNDER GPL v2
fieldtype_2_vhdl={};
fieldtype_2_vhdl[BIT]="std_logic";
fieldtype_2_vhdl[MONOSTABLE]="std_logic";
fieldtype_2_vhdl[SIGNED] = "signed";
fieldtype_2_vhdl[UNSIGNED] = "unsigned";
fieldtype_2_vhdl[ENUM] = "std_logic_vector";
fieldtype_2_vhdl[SLV] = "std_logic_vector";
cvtfunc_hdl = {};
cvtfunc_hdl[SLV] = "";
cvtfunc_hdl[SIGNED] = "signed";
cvtfunc_hdl[UNSIGNED] = "unsigned";
-------------------------------
-- GENERAL-PURPOSE FUNCTIONS --
-------------------------------
-- variable containing the current snippet of VHDL code
code_vhdl = {};
-- function emits a line of VHDL code.
function vhdl(s)
table.insert(code_vhdl, s);
end
-- function forces single-tab left indentation
function vhdl_indent_left()
table.insert(code_vhdl,"--@il");
end
-- function forces single-tab left indentation
function vhdl_indent_right()
table.insert(code_vhdl,"--@ir");
end
-- function creates an empty snippet of VHDL code. The previous snippet is destroyed.
function vhdl_new_code()
code_vhdl = {};
end
-- function pastes code into current snippet from another snippet.
function vhdl_paste_code(code)
local i,v;
if(code == nil) then return; end
for i,v in pairs(code) do
table.insert(code_vhdl, v);
end
end
-- generates new VHDL component instance
function vhdl_new_instance()
local inst = {};
inst.component = "";
inst.name = "";
inst.pmaps= {};
inst.gmaps = {};
return inst;
end
-------------------------------
-- VHDL CODE GENERATOR --
-------------------------------
function gen_vhdl_signals_ram(reg)
local prefix = string.lower(periph.hdl_prefix.."_"..reg.hdl_prefix);
local port = {};
if(reg.__type ~= TYPE_RAM) then
return;
end
table.insert(hdl_ports, { name = prefix.."_addr_i"; length = reg.addr_bits - reg.wrap_bits; type = SLV; dir = "in"; });
if(match(reg.access_dev, {READ_ONLY, READ_WRITE})) then
table.insert(hdl_ports, { name = prefix.."_data_o"; length = reg.width; type = SLV; dir = "out"; });
end
if(match(reg.access_dev, {WRITE_ONLY, READ_WRITE})) then
table.insert(hdl_ports, { name = prefix.."_data_i"; length = reg.width; type = SLV; dir = "in"; });
table.insert(hdl_ports, { name = prefix.."_wr_i"; length = 1; type = BIT; dir = "in"; });
end
end
function gen_vhdl_signals_fifo(field, reg)
local prefix = string.lower(periph.hdl_prefix.."_"..reg.hdl_prefix.."_"..field.hdl_prefix);
if(reg.__type == TYPE_FIFO) then
local suffix = csel(reg.direction == FROM_WB, "_o" , "_i");
local mdir = csel(reg.direction == FROM_WB, "out" , "in");
table.insert(hdl_ports, { name = prefix..suffix; length = field.size; type = field.type; dir = mdir; });
end
end
function gen_vhdl_controls_fifo(reg)
local prefix = string.lower(periph.hdl_prefix.."_"..reg.hdl_prefix);
if(reg.__type == TYPE_FIFO) then
if flag_set(reg.fifo_flags_dev, FIFO_FULL) then table.insert(hdl_ports, { name = prefix.."_ctl_full_o"; length = 1; type = BIT; dir = "out"; } ); end
if flag_set(reg.fifo_flags_dev, FIFO_EMPTY) then table.insert(hdl_ports, { name = prefix.."_ctl_empty_o"; length = 1; type = BIT; dir = "out"; } ); end
if flag_set(reg.fifo_flags_dev, FIFO_ALMOST_FULL) then table.insert(hdl_ports, { name = prefix.."_ctl_almostfull_o"; length = 1; type = BIT; dir = "out"; } ); end
if flag_set(reg.fifo_flags_dev, FIFO_ALMOST_EMPTY) then table.insert(hdl_ports, { name = prefix.."_ctl_almostempty_o"; length = 1; type = BIT; dir = "out"; } ); end
if flag_set(reg.fifo_flags_dev, FIFO_CLEAR) then table.insert(hdl_ports, { name = prefix.."_ctl_clear_i"; length = 1; type = BIT; dir = "in"; } ); end
end
end
-- generates nice VHDL file header
function gen_vhdl_header(file)
vhdl_new_code();
vhdl ("---------------------------------------------------------------------------------------");
vhdl ("-- Title : Wishbone slave core for "..periph.name);
vhdl ("---------------------------------------------------------------------------------------");
vhdl ("-- File : "..output_vhdl_file);
vhdl ("-- Author : auto-generated by wbgen2 from "..input_wb_file);
vhdl ("-- Created : "..os.date());
vhdl ("-- Standard : VHDL'87");
vhdl ("---------------------------------------------------------------------------------------");
vhdl ("-- THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE "..input_wb_file);
vhdl ("-- DO NOT HAND-EDIT UNLESS IT'S ABSOLUTELY NECESSARY!");
vhdl ("---------------------------------------------------------------------------------------");
vhdl ("");
vhdl ("");
vhdl ("library ieee;");
vhdl ("use ieee.std_logic_1164.all;");
vhdl ("use ieee.numeric_std.all;");
vhdl ("");
-- vhdl ("library wbgen2;");
-- vhdl ("use wbgen2.wbgen2_components.all;");
vhdl ("");
vhdl ("library work;");
vhdl ("");
return code_vhdl;
end
-- generates a string containing VHDL-compatible binary numeric value of size numbits
function gen_vhdl_bin_literal(value, numbits)
local str ='\"';
local i,n,d,r;
n=value;
r=math.pow(2, numbits-1);
for i=1,numbits do
d=math.floor(n/r);
str=str..csel(d>0,"1","0");
n=n%r;
r=r/2;
end
return str..'\"';
end
function gen_vhdl_block_address_decoder()
local s = {};
s= "\n\n-- BLOCK ADDRESS DECODER --\n";
s=s.."address_decode_1: process (wb_addr_i) begin\n";
s=s.."\treg_blk_sel <= '1' when (wb_addr_i("..(address_bus_width-1).." downto "..(address_bus_width - address_bus_select_bits)..") = "..gen_vhdl_bin_literal(0, address_bus_select_bits)..") else '0';\n";
foreach_reg(function(reg)
if(reg.__type == TYPE_RAM) then
s=s.."\t"..reg.hdl_prefix.."_blk_sel <= '1' when (wb_addr_i("..(address_bus_width-1).." downto "..(address_bus_width - address_bus_select_bits)..") = "..gen_vhdl_bin_literal(reg.select_bits, address_bus_select_bits)..") else '0';\n";
end
end );
s=s.."end process;\n";
return s;
end
-- constructor for a VHDL signal
function signal(type, nbits, name, comment)
local t = {}
t.comment = comment;
t.type = type;
t.range= nbits;
t.name = name;
return t;
end
-- constructor for a VHDL port
function port(type, nbits, dir, name, comment)
local t = {}
t.comment = comment;
t.type = type;
t.range= nbits;
t.name = name;
t.dir = dir;
return t;
end
function vhdl_portmap(instance, port, sig, range_port, range_sig)
local map = {};
map.type = "portmap";
map.port = port;
map.signal = sig;
map.range_port = range_port;
map.range_sig = range_sig;
table_join(instance.pmaps, map);
end
function vhdl_generic(instance, gname, gvalue)
local gen = {};
gen.type = "genmap";
gen.name = gname;
gen.value = gvalue;
table_join(instance.gmaps, gen);
end
function gen_vhdl_type(field)
local s = fieldtype_2_vhdl[field.type];
if(field.type == SLV or field.type == UNSIGNED or field.type == SIGNED) then
s=s.."("..(field.size-1).." downto 0)";
end
return s;
end
function write_vhdl_code(code, filename)
local cur_indent = 0;
local file = io.open(filename, "w");
local i,v,j;
--local in_case;
for i,v in pairs(code) do
if(v == "--@il") then
cur_indent = cur_indent - 1;
elseif ( v == "--@ir") then
cur_indent = cur_indent + 1;
else
if(
string.find(v, "^else") ~= nil or
string.find(v, "^elsif") ~= nil or
string.find(v, "^end if;") ~= nil or
--- string.find(v, "^else") ~= nil or
string.find(v, "^end case;") ~= nil or
string.find(v, "^end process;") ~= nil or
string.find(v, "^end;") ~= nil or
string.find(v, "^when") ~= nil or
string.find(v, "^end ") ~= nil) then
cur_indent = cur_indent -1;
end
if(string.find(v,"^%-%-") == nil) then
for j=1,cur_indent do file.write(file, " "); end
end
-- print (i,v);
file.write(file, v.."\n");
if(
string.find(v, "^begin") ~= nil or
string.find(v, "^elsif") ~= nil or
string.find(v, "^else") ~= nil or
-- string.find(v, "^process") ~= nil or
string.find(v, "^case") ~= nil or
string.find(v, "^when") ~= nil or
string.find(v, "^if") ~= nil or
string.find(v, "^entity") ~= nil or
string.find(v, "^architecture") ~= nil or
string.find(v, "^port") ~= nil or
string.find(v, "^generic") ~= nil
) then
cur_indent = cur_indent + 1;
end
end
end
io.close(file);
end
function gen_vhdl_wishbone_ports()
local ports = {
port(BIT, 0, "in", "rst_n_i"),
port(BIT, 0, "in", "wb_clk_i"),
};
if(address_bus_width > 0 ) then
table_join(ports, { port(SLV, address_bus_width, "in", "wb_addr_i") });
end
table_join(ports, {
port(SLV, DATA_BUS_WIDTH, "in", "wb_data_i"),
port(SLV, DATA_BUS_WIDTH, "out", "wb_data_o"),
port(BIT, 0, "in", "wb_cyc_i"),
port(BIT, 0, "in", "wb_sel_i"),
port(BIT, 0, "in", "wb_stb_i"),
port(BIT, 0, "in", "wb_we_i"),
port(BIT, 0, "out", "wb_ack_o")
});
return ports;
end
function vhdl_build_clock_list()
local allclocks = tree_2_table("clock");
local i,v;
local clockports = {};
remove_duplicates(allclocks);
for i,v in pairs(allclocks) do
table.insert(clockports, port(BIT, 0, "in", v));
end
return clockports;
end
function gen_vhdl_entity()
local portlist = {};
local i, last;
vhdl_new_code();
vhdl ("entity "..periph.hdl_entity.." is");
vhdl ("port (");
-- generate a global port table by joining port tables for all fields/registers
table_join(portlist, gen_vhdl_wishbone_ports());
table_join(portlist, vhdl_build_clock_list());
table_join(portlist, tree_2_table("ports"));
vhdl_build_clock_list();
-- output the lines into file
for i=1,table.getn(portlist) do
local port = portlist[i];
if(i == table.getn(portlist)) then
last = true;
else
last = false;
end
if(port.comment ~= nil) then
vhdl("-- "..port.comment);
end
local line = string.format("%-40s : %-6s %s", port.name, port.dir, fieldtype_2_vhdl[port.type]);
if(port.range > 0) then
line = line.."("..(port.range-1).." downto 0)";
end
line=line..csel(last, "", ";");
vhdl(line);
end
vhdl_indent_left();
vhdl(");");
vhdl_indent_left();
vhdl("end "..periph.hdl_entity..";");
vhdl("");
vhdl("");
vhdl("architecture behavioral of "..periph.hdl_entity.." is ");
return code_vhdl;
end
function gen_vhdl_signals()
local siglist = {};
local i,v;
local s;
siglist = tree_2_table("signals");
wb_sigs = { signal(BIT, 0, "wb_ack_regbank"),
signal(UNSIGNED, 4, "ack_cntr"),
signal(BIT,0, "ack_in_progress"),
signal(BIT,0, "tmpbit"),
signal(SLV, DATA_BUS_WIDTH, "wb_data_out_int") };
table_join(siglist, wb_sigs);
vhdl_new_code();
for i,v in pairs (siglist) do
-- print (fieldtype_2_vhdl[v.type].." "..v.name);
-- print (v.type);
s=string.format("signal %-40s : %-15s", v.name, fieldtype_2_vhdl[v.type]);
if(v.range > 0) then
s=s..string.format("(%d downto 0)", v.range-1);
end
s=s..";";
vhdl(s);
end
return code_vhdl;
end
function vhdl_generate_constants()
vhdl_new_code();
foreach_reg(function(reg)
if(reg.__type == TYPE_REG) then
vhdl(string.format("constant %-30s : std_logic_vector(%d downto 0) := %-10s;", "ADDR_"..string.upper(periph.hdl_prefix.."_"..reg.hdl_prefix), address_bus_width-1, gen_vhdl_bin_literal(reg.base, address_bus_width)));
end
end
);
vhdl("");
return code_vhdl;
end
function gen_vhdl_code(filename)
local code_header = gen_vhdl_header();
local code_regbank = gen_vhdl_regbank();
local code_rams = gen_vhdl_rams();
local code_signals = gen_vhdl_signals();
local code_entity = gen_vhdl_entity();
local code = {};
table_join(code, code_header);
table_join(code, code_entity);
if(vhdl_gen_reg_constants == true) then
table_join(code, vhdl_generate_constants());
end
table_join(code, code_signals);
table_join(code, code_regbank);
table_join(code, code_rams);
vhdl_new_code();
vhdl ("wb_data_o <= wb_data_out_int;");
vhdl ("wb_ack_o <= wb_ack_regbank;");
vhdl ("end behavioral;");
table_join(code, code_vhdl);
write_vhdl_code(code, filename);
end
function gen_vlog_constants(filename)
print("genvlog: "..filename);
local file = io.open(filename, "w");
if(file == nil) then
die("can't open "..filename.." for writing.");
end
foreach_reg(function(reg)
if(reg.__type == TYPE_REG) then
file.write(file, string.format("`define %-30s %d'h%x\n", "ADDR_"..string.upper(periph.hdl_prefix.."_"..reg.hdl_prefix), address_bus_width, reg.base));
end
end
);
io.close(file);
end
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment