URL
https://opencores.org/ocsvn/neorv32/neorv32/trunk
Subversion Repositories neorv32
Compare Revisions
- This comparison shows the changes necessary to convert path
/neorv32/trunk
- from Rev 5 to Rev 6
- ↔ Reverse comparison
Rev 5 → Rev 6
/.ci/hw_check.sh
7,67 → 7,13
homedir="$( cd "$(dirname "$0")" >/dev/null 2>&1 ; pwd -P )" |
homedir=$homedir/.. |
|
# The directories of the hw source files |
srcdir_core=$homedir/rtl/core |
srcdir_top_templates=$homedir/rtl/top_templates |
srcdir_sim=$homedir/sim |
|
# Show GHDL version |
ghdl -v |
|
# List files |
echo "" |
echo "Simulation source files:" |
ls -al $srcdir_core |
ls -al $srcdir_top_templates |
ls -al $srcdir_sim |
|
# Analyse sources; libs and images at first! |
ghdl -a --work=neorv32 $srcdir_core/neorv32_package.vhd |
ghdl -a --work=neorv32 $srcdir_core/neorv32_application_image.vhd |
ghdl -a --work=neorv32 $srcdir_core/neorv32_bootloader_image.vhd |
# |
ghdl -a --work=neorv32 $srcdir_core/neorv32_boot_rom.vhd |
ghdl -a --work=neorv32 $srcdir_core/neorv32_clic.vhd |
ghdl -a --work=neorv32 $srcdir_core/neorv32_cpu.vhd |
ghdl -a --work=neorv32 $srcdir_core/neorv32_cpu_alu.vhd |
ghdl -a --work=neorv32 $srcdir_core/neorv32_cpu_bus.vhd |
ghdl -a --work=neorv32 $srcdir_core/neorv32_cpu_control.vhd |
ghdl -a --work=neorv32 $srcdir_core/neorv32_cpu_cp_muldiv.vhd |
ghdl -a --work=neorv32 $srcdir_core/neorv32_cpu_decompressor.vhd |
ghdl -a --work=neorv32 $srcdir_core/neorv32_cpu_regfile.vhd |
ghdl -a --work=neorv32 $srcdir_core/neorv32_devnull.vhd |
ghdl -a --work=neorv32 $srcdir_core/neorv32_dmem.vhd |
ghdl -a --work=neorv32 $srcdir_core/neorv32_gpio.vhd |
ghdl -a --work=neorv32 $srcdir_core/neorv32_imem.vhd |
ghdl -a --work=neorv32 $srcdir_core/neorv32_mtime.vhd |
ghdl -a --work=neorv32 $srcdir_core/neorv32_pwm.vhd |
ghdl -a --work=neorv32 $srcdir_core/neorv32_spi.vhd |
ghdl -a --work=neorv32 $srcdir_core/neorv32_top.vhd |
ghdl -a --work=neorv32 $srcdir_core/neorv32_trng.vhd |
ghdl -a --work=neorv32 $srcdir_core/neorv32_twi.vhd |
ghdl -a --work=neorv32 $srcdir_core/neorv32_uart.vhd |
ghdl -a --work=neorv32 $srcdir_core/neorv32_wdt.vhd |
ghdl -a --work=neorv32 $srcdir_core/neorv32_wishbone.vhd |
# |
ghdl -a --work=neorv32 $srcdir_top_templates/*.vhd |
# |
ghdl -a --work=neorv32 $srcdir_sim/*.vhd |
|
# Prepare simulation output files |
touch neorv32.testbench_uart.out |
chmod 777 neorv32.testbench_uart.out |
touch neorv32.devnull.out |
chmod 777 neorv32.devnull.out |
|
# Run simulation |
ghdl -e --work=neorv32 neorv32_tb |
ghdl -r --work=neorv32 neorv32_tb --stop-time=5ms --ieee-asserts=disable --assert-level=error |
sh $homedir/sim/ghdl/ghdl_sim.sh --stop-time=5ms |
|
# Check output |
echo "Checking NEORV32.DEVNULL output. Should contain:"; cat $homedir/check_reference.out |
echo "Checking NEORV32.DEVNULL text output. Should contain:"; cat $homedir/check_reference.out |
echo "" |
echo "Checking NEORV32.DEVNULL output. NEORV32.DEVNULL output is:" |
echo "Checking NEORV32.DEVNULL text output. NEORV32.DEVNULL text output is:" |
cat neorv32.devnull.out |
|
# Check if reference can be found in output |
/.ci/sw_check.sh
10,7 → 10,7
# The directories of the SW source files |
srcdir_examples=$homedir/sw/example |
srcdir_bootloader=$homedir/sw/bootloader |
test_app_dir=$homedir/sw/example/test_exceptions |
test_app_dir=$homedir/sw/example/cpu_test |
|
# List files |
ls -al $srcdir_examples |
/docs/figures/neorv32_overview.png
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/docs/NEORV32.pdf
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/docs/doxygen_makefile_sw
1,51 → 1,448
# Doxyfile 1.8.11 |
# Doxyfile 1.8.17 |
|
# This file describes the settings to be used by the documentation system |
# doxygen (www.doxygen.org) for a project. |
# |
# All text after a double hash (##) is considered a comment and is placed in |
# front of the TAG it is preceding. |
# |
# All text after a single hash (#) is considered a comment and will be ignored. |
# The format is: |
# TAG = value [value, ...] |
# For lists, items can also be appended using: |
# TAG += value [value, ...] |
# Values that contain spaces should be placed between quotes (\" \"). |
|
#--------------------------------------------------------------------------- |
# Project related configuration options |
#--------------------------------------------------------------------------- |
|
# This tag specifies the encoding used for all characters in the configuration |
# file that follow. The default is UTF-8 which is also the encoding used for all |
# text before the first occurrence of this tag. Doxygen uses libiconv (or the |
# iconv built into libc) for the transcoding. See |
# https://www.gnu.org/software/libiconv/ for the list of possible encodings. |
# The default value is: UTF-8. |
|
DOXYFILE_ENCODING = UTF-8 |
|
# The PROJECT_NAME tag is a single word (or a sequence of words surrounded by |
# double-quotes, unless you are using Doxywizard) that should identify the |
# project for which the documentation is generated. This name is used in the |
# title of most generated pages and in a few other places. |
# The default value is: My Project. |
|
PROJECT_NAME = "The NEORV32 Processor - Software Framework" |
|
# The PROJECT_NUMBER tag can be used to enter a project or revision number. This |
# could be handy for archiving the generated documentation or if some version |
# control system is used. |
|
PROJECT_NUMBER = 1.0 |
|
# Using the PROJECT_BRIEF tag one can provide an optional one line description |
# for a project that appears at the top of each page and should give viewer a |
# quick idea about the purpose of the project. Keep the description short. |
|
PROJECT_BRIEF = |
|
# With the PROJECT_LOGO tag one can specify a logo or an icon that is included |
# in the documentation. The maximum height of the logo should not exceed 55 |
# pixels and the maximum width should not exceed 200 pixels. Doxygen will copy |
# the logo to the output directory. |
|
PROJECT_LOGO = |
|
# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path |
# into which the generated documentation will be written. If a relative path is |
# entered, it will be relative to the location where doxygen was started. If |
# left blank the current directory will be used. |
|
OUTPUT_DIRECTORY = build |
|
# If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub- |
# directories (in 2 levels) under the output directory of each output format and |
# will distribute the generated files over these directories. Enabling this |
# option can be useful when feeding doxygen a huge amount of source files, where |
# putting all generated files in the same directory would otherwise causes |
# performance problems for the file system. |
# The default value is: NO. |
|
CREATE_SUBDIRS = NO |
|
# If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII |
# characters to appear in the names of generated files. If set to NO, non-ASCII |
# characters will be escaped, for example _xE3_x81_x84 will be used for Unicode |
# U+3044. |
# The default value is: NO. |
|
ALLOW_UNICODE_NAMES = NO |
|
# The OUTPUT_LANGUAGE tag is used to specify the language in which all |
# documentation generated by doxygen is written. Doxygen will use this |
# information to generate all constant output in the proper language. |
# Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Catalan, Chinese, |
# Chinese-Traditional, Croatian, Czech, Danish, Dutch, English (United States), |
# Esperanto, Farsi (Persian), Finnish, French, German, Greek, Hungarian, |
# Indonesian, Italian, Japanese, Japanese-en (Japanese with English messages), |
# Korean, Korean-en (Korean with English messages), Latvian, Lithuanian, |
# Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, Romanian, Russian, |
# Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, Swedish, Turkish, |
# Ukrainian and Vietnamese. |
# The default value is: English. |
|
OUTPUT_LANGUAGE = English |
|
# The OUTPUT_TEXT_DIRECTION tag is used to specify the direction in which all |
# documentation generated by doxygen is written. Doxygen will use this |
# information to generate all generated output in the proper direction. |
# Possible values are: None, LTR, RTL and Context. |
# The default value is: None. |
|
OUTPUT_TEXT_DIRECTION = None |
|
# If the BRIEF_MEMBER_DESC tag is set to YES, doxygen will include brief member |
# descriptions after the members that are listed in the file and class |
# documentation (similar to Javadoc). Set to NO to disable this. |
# The default value is: YES. |
|
BRIEF_MEMBER_DESC = YES |
|
# If the REPEAT_BRIEF tag is set to YES, doxygen will prepend the brief |
# description of a member or function before the detailed description |
# |
# Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the |
# brief descriptions will be completely suppressed. |
# The default value is: YES. |
|
REPEAT_BRIEF = YES |
|
# This tag implements a quasi-intelligent brief description abbreviator that is |
# used to form the text in various listings. Each string in this list, if found |
# as the leading text of the brief description, will be stripped from the text |
# and the result, after processing the whole list, is used as the annotated |
# text. Otherwise, the brief description is used as-is. If left blank, the |
# following values are used ($name is automatically replaced with the name of |
# the entity):The $name class, The $name widget, The $name file, is, provides, |
# specifies, contains, represents, a, an and the. |
|
ABBREVIATE_BRIEF = |
|
# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then |
# doxygen will generate a detailed section even if there is only a brief |
# description. |
# The default value is: NO. |
|
ALWAYS_DETAILED_SEC = NO |
|
# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all |
# inherited members of a class in the documentation of that class as if those |
# members were ordinary class members. Constructors, destructors and assignment |
# operators of the base classes will not be shown. |
# The default value is: NO. |
|
INLINE_INHERITED_MEMB = NO |
|
# If the FULL_PATH_NAMES tag is set to YES, doxygen will prepend the full path |
# before files name in the file list and in the header files. If set to NO the |
# shortest path that makes the file name unique will be used |
# The default value is: YES. |
|
FULL_PATH_NAMES = YES |
|
# The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path. |
# Stripping is only done if one of the specified strings matches the left-hand |
# part of the path. The tag can be used to show relative paths in the file list. |
# If left blank the directory from which doxygen is run is used as the path to |
# strip. |
# |
# Note that you can specify absolute paths here, but also relative paths, which |
# will be relative from the directory where doxygen is started. |
# This tag requires that the tag FULL_PATH_NAMES is set to YES. |
|
STRIP_FROM_PATH = |
|
# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the |
# path mentioned in the documentation of a class, which tells the reader which |
# header file to include in order to use a class. If left blank only the name of |
# the header file containing the class definition is used. Otherwise one should |
# specify the list of include paths that are normally passed to the compiler |
# using the -I flag. |
|
STRIP_FROM_INC_PATH = |
|
# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but |
# less readable) file names. This can be useful is your file systems doesn't |
# support long names like on DOS, Mac, or CD-ROM. |
# The default value is: NO. |
|
SHORT_NAMES = NO |
|
# If the JAVADOC_AUTOBRIEF tag is set to YES then doxygen will interpret the |
# first line (until the first dot) of a Javadoc-style comment as the brief |
# description. If set to NO, the Javadoc-style will behave just like regular Qt- |
# style comments (thus requiring an explicit @brief command for a brief |
# description.) |
# The default value is: NO. |
|
JAVADOC_AUTOBRIEF = NO |
|
# If the JAVADOC_BANNER tag is set to YES then doxygen will interpret a line |
# such as |
# /*************** |
# as being the beginning of a Javadoc-style comment "banner". If set to NO, the |
# Javadoc-style will behave just like regular comments and it will not be |
# interpreted by doxygen. |
# The default value is: NO. |
|
JAVADOC_BANNER = NO |
|
# If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first |
# line (until the first dot) of a Qt-style comment as the brief description. If |
# set to NO, the Qt-style will behave just like regular Qt-style comments (thus |
# requiring an explicit \brief command for a brief description.) |
# The default value is: NO. |
|
QT_AUTOBRIEF = NO |
|
# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make doxygen treat a |
# multi-line C++ special comment block (i.e. a block of //! or /// comments) as |
# a brief description. This used to be the default behavior. The new default is |
# to treat a multi-line C++ comment block as a detailed description. Set this |
# tag to YES if you prefer the old behavior instead. |
# |
# Note that setting this tag to YES also means that rational rose comments are |
# not recognized any more. |
# The default value is: NO. |
|
MULTILINE_CPP_IS_BRIEF = NO |
|
# If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the |
# documentation from any documented member that it re-implements. |
# The default value is: YES. |
|
INHERIT_DOCS = YES |
|
# If the SEPARATE_MEMBER_PAGES tag is set to YES then doxygen will produce a new |
# page for each member. If set to NO, the documentation of a member will be part |
# of the file/class/namespace that contains it. |
# The default value is: NO. |
|
SEPARATE_MEMBER_PAGES = NO |
|
# The TAB_SIZE tag can be used to set the number of spaces in a tab. Doxygen |
# uses this value to replace tabs by spaces in code fragments. |
# Minimum value: 1, maximum value: 16, default value: 4. |
|
TAB_SIZE = 4 |
|
# This tag can be used to specify a number of aliases that act as commands in |
# the documentation. An alias has the form: |
# name=value |
# For example adding |
# "sideeffect=@par Side Effects:\n" |
# will allow you to put the command \sideeffect (or @sideeffect) in the |
# documentation, which will result in a user-defined paragraph with heading |
# "Side Effects:". You can put \n's in the value part of an alias to insert |
# newlines (in the resulting output). You can put ^^ in the value part of an |
# alias to insert a newline as if a physical newline was in the original file. |
# When you need a literal { or } or , in the value part of an alias you have to |
# escape them by means of a backslash (\), this can lead to conflicts with the |
# commands \{ and \} for these it is advised to use the version @{ and @} or use |
# a double escape (\\{ and \\}) |
|
ALIASES = |
|
# This tag can be used to specify a number of word-keyword mappings (TCL only). |
# A mapping has the form "name=value". For example adding "class=itcl::class" |
# will allow you to use the command class in the itcl::class meaning. |
|
TCL_SUBST = |
|
# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources |
# only. Doxygen will then generate output that is more tailored for C. For |
# instance, some of the names that are used will be different. The list of all |
# members will be omitted, etc. |
# The default value is: NO. |
|
OPTIMIZE_OUTPUT_FOR_C = YES |
|
# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or |
# Python sources only. Doxygen will then generate output that is more tailored |
# for that language. For instance, namespaces will be presented as packages, |
# qualified scopes will look different, etc. |
# The default value is: NO. |
|
OPTIMIZE_OUTPUT_JAVA = NO |
|
# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran |
# sources. Doxygen will then generate output that is tailored for Fortran. |
# The default value is: NO. |
|
OPTIMIZE_FOR_FORTRAN = NO |
|
# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL |
# sources. Doxygen will then generate output that is tailored for VHDL. |
# The default value is: NO. |
|
OPTIMIZE_OUTPUT_VHDL = NO |
|
# Set the OPTIMIZE_OUTPUT_SLICE tag to YES if your project consists of Slice |
# sources only. Doxygen will then generate output that is more tailored for that |
# language. For instance, namespaces will be presented as modules, types will be |
# separated into more groups, etc. |
# The default value is: NO. |
|
OPTIMIZE_OUTPUT_SLICE = NO |
|
# Doxygen selects the parser to use depending on the extension of the files it |
# parses. With this tag you can assign which parser to use for a given |
# extension. Doxygen has a built-in mapping, but you can override or extend it |
# using this tag. The format is ext=language, where ext is a file extension, and |
# language is one of the parsers supported by doxygen: IDL, Java, JavaScript, |
# Csharp (C#), C, C++, D, PHP, md (Markdown), Objective-C, Python, Slice, |
# Fortran (fixed format Fortran: FortranFixed, free formatted Fortran: |
# FortranFree, unknown formatted Fortran: Fortran. In the later case the parser |
# tries to guess whether the code is fixed or free formatted code, this is the |
# default for Fortran type files), VHDL, tcl. For instance to make doxygen treat |
# .inc files as Fortran files (default is PHP), and .f files as C (default is |
# Fortran), use: inc=Fortran f=C. |
# |
# Note: For files without extension you can use no_extension as a placeholder. |
# |
# Note that for custom extensions you also need to set FILE_PATTERNS otherwise |
# the files are not read by doxygen. |
|
EXTENSION_MAPPING = |
|
# If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments |
# according to the Markdown format, which allows for more readable |
# documentation. See https://daringfireball.net/projects/markdown/ for details. |
# The output of markdown processing is further processed by doxygen, so you can |
# mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in |
# case of backward compatibilities issues. |
# The default value is: YES. |
|
MARKDOWN_SUPPORT = YES |
|
# When the TOC_INCLUDE_HEADINGS tag is set to a non-zero value, all headings up |
# to that level are automatically included in the table of contents, even if |
# they do not have an id attribute. |
# Note: This feature currently applies only to Markdown headings. |
# Minimum value: 0, maximum value: 99, default value: 5. |
# This tag requires that the tag MARKDOWN_SUPPORT is set to YES. |
|
TOC_INCLUDE_HEADINGS = 5 |
|
# When enabled doxygen tries to link words that correspond to documented |
# classes, or namespaces to their corresponding documentation. Such a link can |
# be prevented in individual cases by putting a % sign in front of the word or |
# globally by setting AUTOLINK_SUPPORT to NO. |
# The default value is: YES. |
|
AUTOLINK_SUPPORT = YES |
|
# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want |
# to include (a tag file for) the STL sources as input, then you should set this |
# tag to YES in order to let doxygen match functions declarations and |
# definitions whose arguments contain STL classes (e.g. func(std::string); |
# versus func(std::string) {}). This also make the inheritance and collaboration |
# diagrams that involve STL classes more complete and accurate. |
# The default value is: NO. |
|
BUILTIN_STL_SUPPORT = NO |
|
# If you use Microsoft's C++/CLI language, you should set this option to YES to |
# enable parsing support. |
# The default value is: NO. |
|
CPP_CLI_SUPPORT = NO |
|
# Set the SIP_SUPPORT tag to YES if your project consists of sip (see: |
# https://www.riverbankcomputing.com/software/sip/intro) sources only. Doxygen |
# will parse them like normal C++ but will assume all classes use public instead |
# of private inheritance when no explicit protection keyword is present. |
# The default value is: NO. |
|
SIP_SUPPORT = NO |
|
# For Microsoft's IDL there are propget and propput attributes to indicate |
# getter and setter methods for a property. Setting this option to YES will make |
# doxygen to replace the get and set methods by a property in the documentation. |
# This will only work if the methods are indeed getting or setting a simple |
# type. If this is not the case, or you want to show the methods anyway, you |
# should set this option to NO. |
# The default value is: YES. |
|
IDL_PROPERTY_SUPPORT = YES |
|
# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC |
# tag is set to YES then doxygen will reuse the documentation of the first |
# member in the group (if any) for the other members of the group. By default |
# all members of a group must be documented explicitly. |
# The default value is: NO. |
|
DISTRIBUTE_GROUP_DOC = YES |
|
# If one adds a struct or class to a group and this option is enabled, then also |
# any nested class or struct is added to the same group. By default this option |
# is disabled and one has to add nested compounds explicitly via \ingroup. |
# The default value is: NO. |
|
GROUP_NESTED_COMPOUNDS = NO |
|
# Set the SUBGROUPING tag to YES to allow class member groups of the same type |
# (for instance a group of public functions) to be put as a subgroup of that |
# type (e.g. under the Public Functions section). Set it to NO to prevent |
# subgrouping. Alternatively, this can be done per class using the |
# \nosubgrouping command. |
# The default value is: YES. |
|
SUBGROUPING = YES |
|
# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and unions |
# are shown inside the group in which they are included (e.g. using \ingroup) |
# instead of on a separate page (for HTML and Man pages) or section (for LaTeX |
# and RTF). |
# |
# Note that this feature does not work in combination with |
# SEPARATE_MEMBER_PAGES. |
# The default value is: NO. |
|
INLINE_GROUPED_CLASSES = NO |
|
# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and unions |
# with only public data fields or simple typedef fields will be shown inline in |
# the documentation of the scope in which they are defined (i.e. file, |
# namespace, or group documentation), provided this scope is documented. If set |
# to NO, structs, classes, and unions are shown on a separate page (for HTML and |
# Man pages) or section (for LaTeX and RTF). |
# The default value is: NO. |
|
INLINE_SIMPLE_STRUCTS = NO |
|
# When TYPEDEF_HIDES_STRUCT tag is enabled, a typedef of a struct, union, or |
# enum is documented as struct, union, or enum with the name of the typedef. So |
# typedef struct TypeS {} TypeT, will appear in the documentation as a struct |
# with name TypeT. When disabled the typedef will appear as a member of a file, |
# namespace, or class. And the struct will be named TypeS. This can typically be |
# useful for C code in case the coding convention dictates that all compound |
# types are typedef'ed and only the typedef is referenced, never the tag name. |
# The default value is: NO. |
|
TYPEDEF_HIDES_STRUCT = NO |
|
# The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This |
# cache is used to resolve symbols given their name and scope. Since this can be |
# an expensive process and often the same symbol appears multiple times in the |
# code, doxygen keeps a cache of pre-resolved symbols. If the cache is too small |
# doxygen will become slower. If the cache is too large, memory is wasted. The |
# cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range |
# is 0..9, the default is 0, corresponding to a cache size of 2^16=65536 |
# symbols. At the end of a run doxygen will report the cache usage and suggest |
# the optimal cache size from a speed point of view. |
# Minimum value: 0, maximum value: 9, default value: 0. |
|
LOOKUP_CACHE_SIZE = 0 |
|
#--------------------------------------------------------------------------- |
52,42 → 449,298
# Build related configuration options |
#--------------------------------------------------------------------------- |
|
# If the EXTRACT_ALL tag is set to YES, doxygen will assume all entities in |
# documentation are documented, even if no documentation was available. Private |
# class members and static file members will be hidden unless the |
# EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES. |
# Note: This will also disable the warnings about undocumented members that are |
# normally produced when WARNINGS is set to YES. |
# The default value is: NO. |
|
EXTRACT_ALL = NO |
|
# If the EXTRACT_PRIVATE tag is set to YES, all private members of a class will |
# be included in the documentation. |
# The default value is: NO. |
|
EXTRACT_PRIVATE = NO |
|
# If the EXTRACT_PRIV_VIRTUAL tag is set to YES, documented private virtual |
# methods of a class will be included in the documentation. |
# The default value is: NO. |
|
EXTRACT_PRIV_VIRTUAL = NO |
|
# If the EXTRACT_PACKAGE tag is set to YES, all members with package or internal |
# scope will be included in the documentation. |
# The default value is: NO. |
|
EXTRACT_PACKAGE = NO |
|
# If the EXTRACT_STATIC tag is set to YES, all static members of a file will be |
# included in the documentation. |
# The default value is: NO. |
|
EXTRACT_STATIC = YES |
|
# If the EXTRACT_LOCAL_CLASSES tag is set to YES, classes (and structs) defined |
# locally in source files will be included in the documentation. If set to NO, |
# only classes defined in header files are included. Does not have any effect |
# for Java sources. |
# The default value is: YES. |
|
EXTRACT_LOCAL_CLASSES = YES |
|
# This flag is only useful for Objective-C code. If set to YES, local methods, |
# which are defined in the implementation section but not in the interface are |
# included in the documentation. If set to NO, only methods in the interface are |
# included. |
# The default value is: NO. |
|
EXTRACT_LOCAL_METHODS = NO |
|
# If this flag is set to YES, the members of anonymous namespaces will be |
# extracted and appear in the documentation as a namespace called |
# 'anonymous_namespace{file}', where file will be replaced with the base name of |
# the file that contains the anonymous namespace. By default anonymous namespace |
# are hidden. |
# The default value is: NO. |
|
EXTRACT_ANON_NSPACES = NO |
|
# If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all |
# undocumented members inside documented classes or files. If set to NO these |
# members will be included in the various overviews, but no documentation |
# section is generated. This option has no effect if EXTRACT_ALL is enabled. |
# The default value is: NO. |
|
HIDE_UNDOC_MEMBERS = NO |
|
# If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all |
# undocumented classes that are normally visible in the class hierarchy. If set |
# to NO, these classes will be included in the various overviews. This option |
# has no effect if EXTRACT_ALL is enabled. |
# The default value is: NO. |
|
HIDE_UNDOC_CLASSES = NO |
|
# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend |
# declarations. If set to NO, these declarations will be included in the |
# documentation. |
# The default value is: NO. |
|
HIDE_FRIEND_COMPOUNDS = NO |
|
# If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any |
# documentation blocks found inside the body of a function. If set to NO, these |
# blocks will be appended to the function's detailed documentation block. |
# The default value is: NO. |
|
HIDE_IN_BODY_DOCS = NO |
|
# The INTERNAL_DOCS tag determines if documentation that is typed after a |
# \internal command is included. If the tag is set to NO then the documentation |
# will be excluded. Set it to YES to include the internal documentation. |
# The default value is: NO. |
|
INTERNAL_DOCS = NO |
|
# If the CASE_SENSE_NAMES tag is set to NO then doxygen will only generate file |
# names in lower-case letters. If set to YES, upper-case letters are also |
# allowed. This is useful if you have classes or files whose names only differ |
# in case and if your file system supports case sensitive file names. Windows |
# (including Cygwin) ands Mac users are advised to set this option to NO. |
# The default value is: system dependent. |
|
CASE_SENSE_NAMES = YES |
|
# If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with |
# their full class and namespace scopes in the documentation. If set to YES, the |
# scope will be hidden. |
# The default value is: NO. |
|
HIDE_SCOPE_NAMES = NO |
|
# If the HIDE_COMPOUND_REFERENCE tag is set to NO (default) then doxygen will |
# append additional text to a page's title, such as Class Reference. If set to |
# YES the compound reference will be hidden. |
# The default value is: NO. |
|
HIDE_COMPOUND_REFERENCE= NO |
|
# If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of |
# the files that are included by a file in the documentation of that file. |
# The default value is: YES. |
|
SHOW_INCLUDE_FILES = YES |
|
# If the SHOW_GROUPED_MEMB_INC tag is set to YES then Doxygen will add for each |
# grouped member an include statement to the documentation, telling the reader |
# which file to include in order to use the member. |
# The default value is: NO. |
|
SHOW_GROUPED_MEMB_INC = NO |
|
# If the FORCE_LOCAL_INCLUDES tag is set to YES then doxygen will list include |
# files with double quotes in the documentation rather than with sharp brackets. |
# The default value is: NO. |
|
FORCE_LOCAL_INCLUDES = NO |
|
# If the INLINE_INFO tag is set to YES then a tag [inline] is inserted in the |
# documentation for inline members. |
# The default value is: YES. |
|
INLINE_INFO = YES |
|
# If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the |
# (detailed) documentation of file and class members alphabetically by member |
# name. If set to NO, the members will appear in declaration order. |
# The default value is: YES. |
|
SORT_MEMBER_DOCS = YES |
|
# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief |
# descriptions of file, namespace and class members alphabetically by member |
# name. If set to NO, the members will appear in declaration order. Note that |
# this will also influence the order of the classes in the class list. |
# The default value is: NO. |
|
SORT_BRIEF_DOCS = NO |
|
# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the |
# (brief and detailed) documentation of class members so that constructors and |
# destructors are listed first. If set to NO the constructors will appear in the |
# respective orders defined by SORT_BRIEF_DOCS and SORT_MEMBER_DOCS. |
# Note: If SORT_BRIEF_DOCS is set to NO this option is ignored for sorting brief |
# member documentation. |
# Note: If SORT_MEMBER_DOCS is set to NO this option is ignored for sorting |
# detailed member documentation. |
# The default value is: NO. |
|
SORT_MEMBERS_CTORS_1ST = NO |
|
# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy |
# of group names into alphabetical order. If set to NO the group names will |
# appear in their defined order. |
# The default value is: NO. |
|
SORT_GROUP_NAMES = NO |
|
# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be sorted by |
# fully-qualified names, including namespaces. If set to NO, the class list will |
# be sorted only by class name, not including the namespace part. |
# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. |
# Note: This option applies only to the class list, not to the alphabetical |
# list. |
# The default value is: NO. |
|
SORT_BY_SCOPE_NAME = NO |
|
# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper |
# type resolution of all parameters of a function it will reject a match between |
# the prototype and the implementation of a member function even if there is |
# only one candidate or it is obvious which candidate to choose by doing a |
# simple string match. By disabling STRICT_PROTO_MATCHING doxygen will still |
# accept a match between prototype and implementation in such cases. |
# The default value is: NO. |
|
STRICT_PROTO_MATCHING = NO |
|
# The GENERATE_TODOLIST tag can be used to enable (YES) or disable (NO) the todo |
# list. This list is created by putting \todo commands in the documentation. |
# The default value is: YES. |
|
GENERATE_TODOLIST = YES |
|
# The GENERATE_TESTLIST tag can be used to enable (YES) or disable (NO) the test |
# list. This list is created by putting \test commands in the documentation. |
# The default value is: YES. |
|
GENERATE_TESTLIST = YES |
|
# The GENERATE_BUGLIST tag can be used to enable (YES) or disable (NO) the bug |
# list. This list is created by putting \bug commands in the documentation. |
# The default value is: YES. |
|
GENERATE_BUGLIST = YES |
|
# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or disable (NO) |
# the deprecated list. This list is created by putting \deprecated commands in |
# the documentation. |
# The default value is: YES. |
|
GENERATE_DEPRECATEDLIST= YES |
|
# The ENABLED_SECTIONS tag can be used to enable conditional documentation |
# sections, marked by \if <section_label> ... \endif and \cond <section_label> |
# ... \endcond blocks. |
|
ENABLED_SECTIONS = |
|
# The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the |
# initial value of a variable or macro / define can have for it to appear in the |
# documentation. If the initializer consists of more lines than specified here |
# it will be hidden. Use a value of 0 to hide initializers completely. The |
# appearance of the value of individual variables and macros / defines can be |
# controlled using \showinitializer or \hideinitializer command in the |
# documentation regardless of this setting. |
# Minimum value: 0, maximum value: 10000, default value: 30. |
|
MAX_INITIALIZER_LINES = 30 |
|
# Set the SHOW_USED_FILES tag to NO to disable the list of files generated at |
# the bottom of the documentation of classes and structs. If set to YES, the |
# list will mention the files that were used to generate the documentation. |
# The default value is: YES. |
|
SHOW_USED_FILES = YES |
|
# Set the SHOW_FILES tag to NO to disable the generation of the Files page. This |
# will remove the Files entry from the Quick Index and from the Folder Tree View |
# (if specified). |
# The default value is: YES. |
|
SHOW_FILES = YES |
|
# Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces |
# page. This will remove the Namespaces entry from the Quick Index and from the |
# Folder Tree View (if specified). |
# The default value is: YES. |
|
SHOW_NAMESPACES = YES |
|
# The FILE_VERSION_FILTER tag can be used to specify a program or script that |
# doxygen should invoke to get the current version for each file (typically from |
# the version control system). Doxygen will invoke the program by executing (via |
# popen()) the command command input-file, where command is the value of the |
# FILE_VERSION_FILTER tag, and input-file is the name of an input file provided |
# by doxygen. Whatever the program writes to standard output is used as the file |
# version. For an example see the documentation. |
|
FILE_VERSION_FILTER = |
|
# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed |
# by doxygen. The layout file controls the global structure of the generated |
# output files in an output format independent way. To create the layout file |
# that represents doxygen's defaults, run doxygen with the -l option. You can |
# optionally specify a file name after the option, if omitted DoxygenLayout.xml |
# will be used as the name of the layout file. |
# |
# Note that if you run doxygen from a directory containing a file called |
# DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE |
# tag is left empty. |
|
LAYOUT_FILE = |
|
# The CITE_BIB_FILES tag can be used to specify one or more bib files containing |
# the reference definitions. This must be a list of .bib files. The .bib |
# extension is automatically appended if omitted. This requires the bibtex tool |
# to be installed. See also https://en.wikipedia.org/wiki/BibTeX for more info. |
# For LaTeX the style of the bibliography can be controlled using |
# LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the |
# search path. See also \cite for info how to create references. |
|
CITE_BIB_FILES = |
|
#--------------------------------------------------------------------------- |
94,13 → 747,66
# Configuration options related to warning and progress messages |
#--------------------------------------------------------------------------- |
|
# The QUIET tag can be used to turn on/off the messages that are generated to |
# standard output by doxygen. If QUIET is set to YES this implies that the |
# messages are off. |
# The default value is: NO. |
|
QUIET = NO |
|
# The WARNINGS tag can be used to turn on/off the warning messages that are |
# generated to standard error (stderr) by doxygen. If WARNINGS is set to YES |
# this implies that the warnings are on. |
# |
# Tip: Turn warnings on while writing the documentation. |
# The default value is: YES. |
|
WARNINGS = YES |
|
# If the WARN_IF_UNDOCUMENTED tag is set to YES then doxygen will generate |
# warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag |
# will automatically be disabled. |
# The default value is: YES. |
|
WARN_IF_UNDOCUMENTED = YES |
|
# If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for |
# potential errors in the documentation, such as not documenting some parameters |
# in a documented function, or documenting parameters that don't exist or using |
# markup commands wrongly. |
# The default value is: YES. |
|
WARN_IF_DOC_ERROR = YES |
|
# This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that |
# are documented, but have no documentation for their parameters or return |
# value. If set to NO, doxygen will only warn about wrong or incomplete |
# parameter documentation, but not about the absence of documentation. If |
# EXTRACT_ALL is set to YES then this flag will automatically be disabled. |
# The default value is: NO. |
|
WARN_NO_PARAMDOC = NO |
|
# If the WARN_AS_ERROR tag is set to YES then doxygen will immediately stop when |
# a warning is encountered. |
# The default value is: NO. |
|
WARN_AS_ERROR = NO |
|
# The WARN_FORMAT tag determines the format of the warning messages that doxygen |
# can produce. The string should contain the $file, $line, and $text tags, which |
# will be replaced by the file and line number from which the warning originated |
# and the warning text. Optionally the format may contain $version, which will |
# be replaced by the version of the file (if it could be obtained via |
# FILE_VERSION_FILTER) |
# The default value is: $file:$line: $text. |
|
WARN_FORMAT = "$file:$line: $text" |
|
# The WARN_LOGFILE tag can be used to specify a file to which warning and error |
# messages should be written. If left blank the output is written to standard |
# error (stderr). |
|
WARN_LOGFILE = |
|
#--------------------------------------------------------------------------- |
107,22 → 813,169
# Configuration options related to the input files |
#--------------------------------------------------------------------------- |
|
INPUT = ../README.md ../sw/lib/source ../sw/lib/include ../sw/bootloader ../sw/example |
# The INPUT tag is used to specify the files and/or directories that contain |
# documented source files. You may enter file names like myfile.cpp or |
# directories like /usr/src/myproject. Separate the files or directories with |
# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING |
# Note: If this tag is empty the current directory is searched. |
|
INPUT = ../README.md \ |
../sw/lib/source \ |
../sw/lib/include \ |
../sw/bootloader \ |
../sw/example |
|
# This tag can be used to specify the character encoding of the source files |
# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses |
# libiconv (or the iconv built into libc) for the transcoding. See the libiconv |
# documentation (see: https://www.gnu.org/software/libiconv/) for the list of |
# possible encodings. |
# The default value is: UTF-8. |
|
INPUT_ENCODING = UTF-8 |
FILE_PATTERNS = *.c *.h |
|
# If the value of the INPUT tag contains directories, you can use the |
# FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and |
# *.h) to filter out the source-files in the directories. |
# |
# Note that for custom extensions or not directly supported extensions you also |
# need to set EXTENSION_MAPPING for the extension otherwise the files are not |
# read by doxygen. |
# |
# If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cpp, |
# *.c++, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h, |
# *.hh, *.hxx, *.hpp, *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc, |
# *.m, *.markdown, *.md, *.mm, *.dox (to be provided as doxygen C comment), |
# *.doc (to be provided as doxygen C comment), *.txt (to be provided as doxygen |
# C comment), *.py, *.pyw, *.f90, *.f95, *.f03, *.f08, *.f, *.for, *.tcl, *.vhd, |
# *.vhdl, *.ucf, *.qsf and *.ice. |
|
FILE_PATTERNS = *.c \ |
*.h |
|
# The RECURSIVE tag can be used to specify whether or not subdirectories should |
# be searched for input files as well. |
# The default value is: NO. |
|
RECURSIVE = YES |
|
# The EXCLUDE tag can be used to specify files and/or directories that should be |
# excluded from the INPUT source files. This way you can easily exclude a |
# subdirectory from a directory tree whose root is specified with the INPUT tag. |
# |
# Note that relative paths are relative to the directory from which doxygen is |
# run. |
|
EXCLUDE = |
|
# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or |
# directories that are symbolic links (a Unix file system feature) are excluded |
# from the input. |
# The default value is: NO. |
|
EXCLUDE_SYMLINKS = NO |
EXCLUDE_PATTERNS = ~* */example/coremark/* |
|
# If the value of the INPUT tag contains directories, you can use the |
# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude |
# certain files from those directories. |
# |
# Note that the wildcards are matched against the file with absolute path, so to |
# exclude all test directories for example use the pattern */test/* |
|
EXCLUDE_PATTERNS = ~* \ |
*/example/coremark/* |
|
# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names |
# (namespaces, classes, functions, etc.) that should be excluded from the |
# output. The symbol name can be a fully qualified name, a word, or if the |
# wildcard * is used, a substring. Examples: ANamespace, AClass, |
# AClass::ANamespace, ANamespace::*Test |
# |
# Note that the wildcards are matched against the file with absolute path, so to |
# exclude all test directories use the pattern */test/* |
|
EXCLUDE_SYMBOLS = |
|
# The EXAMPLE_PATH tag can be used to specify one or more files or directories |
# that contain example code fragments that are included (see the \include |
# command). |
|
EXAMPLE_PATH = |
|
# If the value of the EXAMPLE_PATH tag contains directories, you can use the |
# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and |
# *.h) to filter out the source-files in the directories. If left blank all |
# files are included. |
|
EXAMPLE_PATTERNS = |
|
# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be |
# searched for input files to be used with the \include or \dontinclude commands |
# irrespective of the value of the RECURSIVE tag. |
# The default value is: NO. |
|
EXAMPLE_RECURSIVE = NO |
|
# The IMAGE_PATH tag can be used to specify one or more files or directories |
# that contain images that are to be included in the documentation (see the |
# \image command). |
|
IMAGE_PATH = |
|
# The INPUT_FILTER tag can be used to specify a program that doxygen should |
# invoke to filter for each input file. Doxygen will invoke the filter program |
# by executing (via popen()) the command: |
# |
# <filter> <input-file> |
# |
# where <filter> is the value of the INPUT_FILTER tag, and <input-file> is the |
# name of an input file. Doxygen will then use the output that the filter |
# program writes to standard output. If FILTER_PATTERNS is specified, this tag |
# will be ignored. |
# |
# Note that the filter must not add or remove lines; it is applied before the |
# code is scanned, but not when the output code is generated. If lines are added |
# or removed, the anchors will not be placed correctly. |
# |
# Note that for custom extensions or not directly supported extensions you also |
# need to set EXTENSION_MAPPING for the extension otherwise the files are not |
# properly processed by doxygen. |
|
INPUT_FILTER = |
|
# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern |
# basis. Doxygen will compare the file name with each pattern and apply the |
# filter if there is a match. The filters are a list of the form: pattern=filter |
# (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how |
# filters are used. If the FILTER_PATTERNS tag is empty or if none of the |
# patterns match the file name, INPUT_FILTER is applied. |
# |
# Note that for custom extensions or not directly supported extensions you also |
# need to set EXTENSION_MAPPING for the extension otherwise the files are not |
# properly processed by doxygen. |
|
FILTER_PATTERNS = |
|
# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using |
# INPUT_FILTER) will also be used to filter the input files that are used for |
# producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES). |
# The default value is: NO. |
|
FILTER_SOURCE_FILES = NO |
|
# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file |
# pattern. A pattern will override the setting for FILTER_PATTERN (if any) and |
# it is also possible to disable source filtering for a specific pattern using |
# *.ext= (so without naming a filter). |
# This tag requires that the tag FILTER_SOURCE_FILES is set to YES. |
|
FILTER_SOURCE_PATTERNS = |
|
# If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that |
# is part of the input, its contents will be placed on the main page |
# (index.html). This can be useful if you have a project on for instance GitHub |
# and want to reuse the introduction page also for the doxygen output. |
|
USE_MDFILE_AS_MAINPAGE = ../README.md |
|
#--------------------------------------------------------------------------- |
129,24 → 982,141
# Configuration options related to source browsing |
#--------------------------------------------------------------------------- |
|
# If the SOURCE_BROWSER tag is set to YES then a list of source files will be |
# generated. Documented entities will be cross-referenced with these sources. |
# |
# Note: To get rid of all source code in the generated output, make sure that |
# also VERBATIM_HEADERS is set to NO. |
# The default value is: NO. |
|
SOURCE_BROWSER = NO |
|
# Setting the INLINE_SOURCES tag to YES will include the body of functions, |
# classes and enums directly into the documentation. |
# The default value is: NO. |
|
INLINE_SOURCES = NO |
|
# Setting the STRIP_CODE_COMMENTS tag to YES will instruct doxygen to hide any |
# special comment blocks from generated source code fragments. Normal C, C++ and |
# Fortran comments will always remain visible. |
# The default value is: YES. |
|
STRIP_CODE_COMMENTS = YES |
|
# If the REFERENCED_BY_RELATION tag is set to YES then for each documented |
# entity all documented functions referencing it will be listed. |
# The default value is: NO. |
|
REFERENCED_BY_RELATION = NO |
|
# If the REFERENCES_RELATION tag is set to YES then for each documented function |
# all documented entities called/used by that function will be listed. |
# The default value is: NO. |
|
REFERENCES_RELATION = NO |
|
# If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set |
# to YES then the hyperlinks from functions in REFERENCES_RELATION and |
# REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will |
# link to the documentation. |
# The default value is: YES. |
|
REFERENCES_LINK_SOURCE = YES |
|
# If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the |
# source code will show a tooltip with additional information such as prototype, |
# brief description and links to the definition and documentation. Since this |
# will make the HTML file larger and loading of large files a bit slower, you |
# can opt to disable this feature. |
# The default value is: YES. |
# This tag requires that the tag SOURCE_BROWSER is set to YES. |
|
SOURCE_TOOLTIPS = YES |
|
# If the USE_HTAGS tag is set to YES then the references to source code will |
# point to the HTML generated by the htags(1) tool instead of doxygen built-in |
# source browser. The htags tool is part of GNU's global source tagging system |
# (see https://www.gnu.org/software/global/global.html). You will need version |
# 4.8.6 or higher. |
# |
# To use it do the following: |
# - Install the latest version of global |
# - Enable SOURCE_BROWSER and USE_HTAGS in the configuration file |
# - Make sure the INPUT points to the root of the source tree |
# - Run doxygen as normal |
# |
# Doxygen will invoke htags (and that will in turn invoke gtags), so these |
# tools must be available from the command line (i.e. in the search path). |
# |
# The result: instead of the source browser generated by doxygen, the links to |
# source code will now point to the output of htags. |
# The default value is: NO. |
# This tag requires that the tag SOURCE_BROWSER is set to YES. |
|
USE_HTAGS = NO |
|
# If the VERBATIM_HEADERS tag is set the YES then doxygen will generate a |
# verbatim copy of the header file for each class for which an include is |
# specified. Set to NO to disable this. |
# See also: Section \class. |
# The default value is: YES. |
|
VERBATIM_HEADERS = YES |
|
# If the CLANG_ASSISTED_PARSING tag is set to YES then doxygen will use the |
# clang parser (see: http://clang.llvm.org/) for more accurate parsing at the |
# cost of reduced performance. This can be particularly helpful with template |
# rich C++ code for which doxygen's built-in parser lacks the necessary type |
# information. |
# Note: The availability of this option depends on whether or not doxygen was |
# generated with the -Duse_libclang=ON option for CMake. |
# The default value is: NO. |
|
CLANG_ASSISTED_PARSING = NO |
|
# If clang assisted parsing is enabled you can provide the compiler with command |
# line options that you would normally use when invoking the compiler. Note that |
# the include paths will already be set by doxygen for the files and directories |
# specified with INPUT and INCLUDE_PATH. |
# This tag requires that the tag CLANG_ASSISTED_PARSING is set to YES. |
|
CLANG_OPTIONS = |
|
# If clang assisted parsing is enabled you can provide the clang parser with the |
# path to the compilation database (see: |
# http://clang.llvm.org/docs/HowToSetupToolingForLLVM.html) used when the files |
# were built. This is equivalent to specifying the "-p" option to a clang tool, |
# such as clang-check. These options will then be passed to the parser. |
# Note: The availability of this option depends on whether or not doxygen was |
# generated with the -Duse_libclang=ON option for CMake. |
|
CLANG_DATABASE_PATH = |
|
#--------------------------------------------------------------------------- |
# Configuration options related to the alphabetical class index |
#--------------------------------------------------------------------------- |
|
# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index of all |
# compounds will be generated. Enable this if the project contains a lot of |
# classes, structs, unions or interfaces. |
# The default value is: YES. |
|
ALPHABETICAL_INDEX = YES |
|
# The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in |
# which the alphabetical index list will be split. |
# Minimum value: 1, maximum value: 20, default value: 5. |
# This tag requires that the tag ALPHABETICAL_INDEX is set to YES. |
|
COLS_IN_ALPHA_INDEX = 5 |
|
# In case all classes in a project start with a common prefix, all classes will |
# be put under the same header in the alphabetical index. The IGNORE_PREFIX tag |
# can be used to specify a prefix (or a list of prefixes) that should be ignored |
# while generating the index headers. |
# This tag requires that the tag ALPHABETICAL_INDEX is set to YES. |
|
IGNORE_PREFIX = |
|
#--------------------------------------------------------------------------- |
153,60 → 1123,561
# Configuration options related to the HTML output |
#--------------------------------------------------------------------------- |
|
# If the GENERATE_HTML tag is set to YES, doxygen will generate HTML output |
# The default value is: YES. |
|
GENERATE_HTML = YES |
|
# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a |
# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of |
# it. |
# The default directory is: html. |
# This tag requires that the tag GENERATE_HTML is set to YES. |
|
HTML_OUTPUT = html |
|
# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each |
# generated HTML page (for example: .htm, .php, .asp). |
# The default value is: .html. |
# This tag requires that the tag GENERATE_HTML is set to YES. |
|
HTML_FILE_EXTENSION = .html |
|
# The HTML_HEADER tag can be used to specify a user-defined HTML header file for |
# each generated HTML page. If the tag is left blank doxygen will generate a |
# standard header. |
# |
# To get valid HTML the header file that includes any scripts and style sheets |
# that doxygen needs, which is dependent on the configuration options used (e.g. |
# the setting GENERATE_TREEVIEW). It is highly recommended to start with a |
# default header using |
# doxygen -w html new_header.html new_footer.html new_stylesheet.css |
# YourConfigFile |
# and then modify the file new_header.html. See also section "Doxygen usage" |
# for information on how to generate the default header that doxygen normally |
# uses. |
# Note: The header is subject to change so you typically have to regenerate the |
# default header when upgrading to a newer version of doxygen. For a description |
# of the possible markers and block names see the documentation. |
# This tag requires that the tag GENERATE_HTML is set to YES. |
|
HTML_HEADER = |
|
# The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each |
# generated HTML page. If the tag is left blank doxygen will generate a standard |
# footer. See HTML_HEADER for more information on how to generate a default |
# footer and what special commands can be used inside the footer. See also |
# section "Doxygen usage" for information on how to generate the default footer |
# that doxygen normally uses. |
# This tag requires that the tag GENERATE_HTML is set to YES. |
|
HTML_FOOTER = |
|
# The HTML_STYLESHEET tag can be used to specify a user-defined cascading style |
# sheet that is used by each HTML page. It can be used to fine-tune the look of |
# the HTML output. If left blank doxygen will generate a default style sheet. |
# See also section "Doxygen usage" for information on how to generate the style |
# sheet that doxygen normally uses. |
# Note: It is recommended to use HTML_EXTRA_STYLESHEET instead of this tag, as |
# it is more robust and this tag (HTML_STYLESHEET) will in the future become |
# obsolete. |
# This tag requires that the tag GENERATE_HTML is set to YES. |
|
HTML_STYLESHEET = |
|
# The HTML_EXTRA_STYLESHEET tag can be used to specify additional user-defined |
# cascading style sheets that are included after the standard style sheets |
# created by doxygen. Using this option one can overrule certain style aspects. |
# This is preferred over using HTML_STYLESHEET since it does not replace the |
# standard style sheet and is therefore more robust against future updates. |
# Doxygen will copy the style sheet files to the output directory. |
# Note: The order of the extra style sheet files is of importance (e.g. the last |
# style sheet in the list overrules the setting of the previous ones in the |
# list). For an example see the documentation. |
# This tag requires that the tag GENERATE_HTML is set to YES. |
|
HTML_EXTRA_STYLESHEET = |
|
# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or |
# other source files which should be copied to the HTML output directory. Note |
# that these files will be copied to the base HTML output directory. Use the |
# $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these |
# files. In the HTML_STYLESHEET file, use the file name only. Also note that the |
# files will be copied as-is; there are no commands or markers available. |
# This tag requires that the tag GENERATE_HTML is set to YES. |
|
HTML_EXTRA_FILES = |
|
# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen |
# will adjust the colors in the style sheet and background images according to |
# this color. Hue is specified as an angle on a colorwheel, see |
# https://en.wikipedia.org/wiki/Hue for more information. For instance the value |
# 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300 |
# purple, and 360 is red again. |
# Minimum value: 0, maximum value: 359, default value: 220. |
# This tag requires that the tag GENERATE_HTML is set to YES. |
|
HTML_COLORSTYLE_HUE = 220 |
|
# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors |
# in the HTML output. For a value of 0 the output will use grayscales only. A |
# value of 255 will produce the most vivid colors. |
# Minimum value: 0, maximum value: 255, default value: 100. |
# This tag requires that the tag GENERATE_HTML is set to YES. |
|
HTML_COLORSTYLE_SAT = 100 |
|
# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to the |
# luminance component of the colors in the HTML output. Values below 100 |
# gradually make the output lighter, whereas values above 100 make the output |
# darker. The value divided by 100 is the actual gamma applied, so 80 represents |
# a gamma of 0.8, The value 220 represents a gamma of 2.2, and 100 does not |
# change the gamma. |
# Minimum value: 40, maximum value: 240, default value: 80. |
# This tag requires that the tag GENERATE_HTML is set to YES. |
|
HTML_COLORSTYLE_GAMMA = 80 |
|
# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML |
# page will contain the date and time when the page was generated. Setting this |
# to YES can help to show when doxygen was last run and thus if the |
# documentation is up to date. |
# The default value is: NO. |
# This tag requires that the tag GENERATE_HTML is set to YES. |
|
HTML_TIMESTAMP = NO |
|
# If the HTML_DYNAMIC_MENUS tag is set to YES then the generated HTML |
# documentation will contain a main index with vertical navigation menus that |
# are dynamically created via JavaScript. If disabled, the navigation index will |
# consists of multiple levels of tabs that are statically embedded in every HTML |
# page. Disable this option to support browsers that do not have JavaScript, |
# like the Qt help browser. |
# The default value is: YES. |
# This tag requires that the tag GENERATE_HTML is set to YES. |
|
HTML_DYNAMIC_MENUS = YES |
|
# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML |
# documentation will contain sections that can be hidden and shown after the |
# page has loaded. |
# The default value is: NO. |
# This tag requires that the tag GENERATE_HTML is set to YES. |
|
HTML_DYNAMIC_SECTIONS = NO |
|
# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries |
# shown in the various tree structured indices initially; the user can expand |
# and collapse entries dynamically later on. Doxygen will expand the tree to |
# such a level that at most the specified number of entries are visible (unless |
# a fully collapsed tree already exceeds this amount). So setting the number of |
# entries 1 will produce a full collapsed tree by default. 0 is a special value |
# representing an infinite number of entries and will result in a full expanded |
# tree by default. |
# Minimum value: 0, maximum value: 9999, default value: 100. |
# This tag requires that the tag GENERATE_HTML is set to YES. |
|
HTML_INDEX_NUM_ENTRIES = 100 |
|
# If the GENERATE_DOCSET tag is set to YES, additional index files will be |
# generated that can be used as input for Apple's Xcode 3 integrated development |
# environment (see: https://developer.apple.com/xcode/), introduced with OSX |
# 10.5 (Leopard). To create a documentation set, doxygen will generate a |
# Makefile in the HTML output directory. Running make will produce the docset in |
# that directory and running make install will install the docset in |
# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at |
# startup. See https://developer.apple.com/library/archive/featuredarticles/Doxy |
# genXcode/_index.html for more information. |
# The default value is: NO. |
# This tag requires that the tag GENERATE_HTML is set to YES. |
|
GENERATE_DOCSET = NO |
|
# This tag determines the name of the docset feed. A documentation feed provides |
# an umbrella under which multiple documentation sets from a single provider |
# (such as a company or product suite) can be grouped. |
# The default value is: Doxygen generated docs. |
# This tag requires that the tag GENERATE_DOCSET is set to YES. |
|
DOCSET_FEEDNAME = "Doxygen generated docs" |
|
# This tag specifies a string that should uniquely identify the documentation |
# set bundle. This should be a reverse domain-name style string, e.g. |
# com.mycompany.MyDocSet. Doxygen will append .docset to the name. |
# The default value is: org.doxygen.Project. |
# This tag requires that the tag GENERATE_DOCSET is set to YES. |
|
DOCSET_BUNDLE_ID = org.doxygen.Project |
|
# The DOCSET_PUBLISHER_ID tag specifies a string that should uniquely identify |
# the documentation publisher. This should be a reverse domain-name style |
# string, e.g. com.mycompany.MyDocSet.documentation. |
# The default value is: org.doxygen.Publisher. |
# This tag requires that the tag GENERATE_DOCSET is set to YES. |
|
DOCSET_PUBLISHER_ID = org.doxygen.Publisher |
|
# The DOCSET_PUBLISHER_NAME tag identifies the documentation publisher. |
# The default value is: Publisher. |
# This tag requires that the tag GENERATE_DOCSET is set to YES. |
|
DOCSET_PUBLISHER_NAME = Publisher |
|
# If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three |
# additional HTML index files: index.hhp, index.hhc, and index.hhk. The |
# index.hhp is a project file that can be read by Microsoft's HTML Help Workshop |
# (see: https://www.microsoft.com/en-us/download/details.aspx?id=21138) on |
# Windows. |
# |
# The HTML Help Workshop contains a compiler that can convert all HTML output |
# generated by doxygen into a single compiled HTML file (.chm). Compiled HTML |
# files are now used as the Windows 98 help format, and will replace the old |
# Windows help format (.hlp) on all Windows platforms in the future. Compressed |
# HTML files also contain an index, a table of contents, and you can search for |
# words in the documentation. The HTML workshop also contains a viewer for |
# compressed HTML files. |
# The default value is: NO. |
# This tag requires that the tag GENERATE_HTML is set to YES. |
|
GENERATE_HTMLHELP = NO |
|
# The CHM_FILE tag can be used to specify the file name of the resulting .chm |
# file. You can add a path in front of the file if the result should not be |
# written to the html output directory. |
# This tag requires that the tag GENERATE_HTMLHELP is set to YES. |
|
CHM_FILE = |
|
# The HHC_LOCATION tag can be used to specify the location (absolute path |
# including file name) of the HTML help compiler (hhc.exe). If non-empty, |
# doxygen will try to run the HTML help compiler on the generated index.hhp. |
# The file has to be specified with full path. |
# This tag requires that the tag GENERATE_HTMLHELP is set to YES. |
|
HHC_LOCATION = |
|
# The GENERATE_CHI flag controls if a separate .chi index file is generated |
# (YES) or that it should be included in the master .chm file (NO). |
# The default value is: NO. |
# This tag requires that the tag GENERATE_HTMLHELP is set to YES. |
|
GENERATE_CHI = NO |
|
# The CHM_INDEX_ENCODING is used to encode HtmlHelp index (hhk), content (hhc) |
# and project file content. |
# This tag requires that the tag GENERATE_HTMLHELP is set to YES. |
|
CHM_INDEX_ENCODING = |
|
# The BINARY_TOC flag controls whether a binary table of contents is generated |
# (YES) or a normal table of contents (NO) in the .chm file. Furthermore it |
# enables the Previous and Next buttons. |
# The default value is: NO. |
# This tag requires that the tag GENERATE_HTMLHELP is set to YES. |
|
BINARY_TOC = NO |
|
# The TOC_EXPAND flag can be set to YES to add extra items for group members to |
# the table of contents of the HTML help documentation and to the tree view. |
# The default value is: NO. |
# This tag requires that the tag GENERATE_HTMLHELP is set to YES. |
|
TOC_EXPAND = NO |
|
# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and |
# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that |
# can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help |
# (.qch) of the generated HTML documentation. |
# The default value is: NO. |
# This tag requires that the tag GENERATE_HTML is set to YES. |
|
GENERATE_QHP = NO |
|
# If the QHG_LOCATION tag is specified, the QCH_FILE tag can be used to specify |
# the file name of the resulting .qch file. The path specified is relative to |
# the HTML output folder. |
# This tag requires that the tag GENERATE_QHP is set to YES. |
|
QCH_FILE = |
|
# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help |
# Project output. For more information please see Qt Help Project / Namespace |
# (see: https://doc.qt.io/archives/qt-4.8/qthelpproject.html#namespace). |
# The default value is: org.doxygen.Project. |
# This tag requires that the tag GENERATE_QHP is set to YES. |
|
QHP_NAMESPACE = org.doxygen.Project |
|
# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt |
# Help Project output. For more information please see Qt Help Project / Virtual |
# Folders (see: https://doc.qt.io/archives/qt-4.8/qthelpproject.html#virtual- |
# folders). |
# The default value is: doc. |
# This tag requires that the tag GENERATE_QHP is set to YES. |
|
QHP_VIRTUAL_FOLDER = doc |
|
# If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom |
# filter to add. For more information please see Qt Help Project / Custom |
# Filters (see: https://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom- |
# filters). |
# This tag requires that the tag GENERATE_QHP is set to YES. |
|
QHP_CUST_FILTER_NAME = |
|
# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the |
# custom filter to add. For more information please see Qt Help Project / Custom |
# Filters (see: https://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom- |
# filters). |
# This tag requires that the tag GENERATE_QHP is set to YES. |
|
QHP_CUST_FILTER_ATTRS = |
|
# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this |
# project's filter section matches. Qt Help Project / Filter Attributes (see: |
# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#filter-attributes). |
# This tag requires that the tag GENERATE_QHP is set to YES. |
|
QHP_SECT_FILTER_ATTRS = |
|
# The QHG_LOCATION tag can be used to specify the location of Qt's |
# qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the |
# generated .qhp file. |
# This tag requires that the tag GENERATE_QHP is set to YES. |
|
QHG_LOCATION = |
|
# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be |
# generated, together with the HTML files, they form an Eclipse help plugin. To |
# install this plugin and make it available under the help contents menu in |
# Eclipse, the contents of the directory containing the HTML and XML files needs |
# to be copied into the plugins directory of eclipse. The name of the directory |
# within the plugins directory should be the same as the ECLIPSE_DOC_ID value. |
# After copying Eclipse needs to be restarted before the help appears. |
# The default value is: NO. |
# This tag requires that the tag GENERATE_HTML is set to YES. |
|
GENERATE_ECLIPSEHELP = NO |
|
# A unique identifier for the Eclipse help plugin. When installing the plugin |
# the directory name containing the HTML and XML files should also have this |
# name. Each documentation set should have its own identifier. |
# The default value is: org.doxygen.Project. |
# This tag requires that the tag GENERATE_ECLIPSEHELP is set to YES. |
|
ECLIPSE_DOC_ID = org.doxygen.Project |
|
# If you want full control over the layout of the generated HTML pages it might |
# be necessary to disable the index and replace it with your own. The |
# DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) at top |
# of each HTML page. A value of NO enables the index and the value YES disables |
# it. Since the tabs in the index contain the same information as the navigation |
# tree, you can set this option to YES if you also set GENERATE_TREEVIEW to YES. |
# The default value is: NO. |
# This tag requires that the tag GENERATE_HTML is set to YES. |
|
DISABLE_INDEX = NO |
|
# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index |
# structure should be generated to display hierarchical information. If the tag |
# value is set to YES, a side panel will be generated containing a tree-like |
# index structure (just like the one that is generated for HTML Help). For this |
# to work a browser that supports JavaScript, DHTML, CSS and frames is required |
# (i.e. any modern browser). Windows users are probably better off using the |
# HTML help feature. Via custom style sheets (see HTML_EXTRA_STYLESHEET) one can |
# further fine-tune the look of the index. As an example, the default style |
# sheet generated by doxygen has an example that shows how to put an image at |
# the root of the tree instead of the PROJECT_NAME. Since the tree basically has |
# the same information as the tab index, you could consider setting |
# DISABLE_INDEX to YES when enabling this option. |
# The default value is: NO. |
# This tag requires that the tag GENERATE_HTML is set to YES. |
|
GENERATE_TREEVIEW = NO |
|
# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that |
# doxygen will group on one line in the generated HTML documentation. |
# |
# Note that a value of 0 will completely suppress the enum values from appearing |
# in the overview section. |
# Minimum value: 0, maximum value: 20, default value: 4. |
# This tag requires that the tag GENERATE_HTML is set to YES. |
|
ENUM_VALUES_PER_LINE = 4 |
|
# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used |
# to set the initial width (in pixels) of the frame in which the tree is shown. |
# Minimum value: 0, maximum value: 1500, default value: 250. |
# This tag requires that the tag GENERATE_HTML is set to YES. |
|
TREEVIEW_WIDTH = 250 |
|
# If the EXT_LINKS_IN_WINDOW option is set to YES, doxygen will open links to |
# external symbols imported via tag files in a separate window. |
# The default value is: NO. |
# This tag requires that the tag GENERATE_HTML is set to YES. |
|
EXT_LINKS_IN_WINDOW = NO |
|
# Use this tag to change the font size of LaTeX formulas included as images in |
# the HTML documentation. When you change the font size after a successful |
# doxygen run you need to manually remove any form_*.png images from the HTML |
# output directory to force them to be regenerated. |
# Minimum value: 8, maximum value: 50, default value: 10. |
# This tag requires that the tag GENERATE_HTML is set to YES. |
|
FORMULA_FONTSIZE = 10 |
|
# Use the FORMULA_TRANSPARENT tag to determine whether or not the images |
# generated for formulas are transparent PNGs. Transparent PNGs are not |
# supported properly for IE 6.0, but are supported on all modern browsers. |
# |
# Note that when changing this option you need to delete any form_*.png files in |
# the HTML output directory before the changes have effect. |
# The default value is: YES. |
# This tag requires that the tag GENERATE_HTML is set to YES. |
|
FORMULA_TRANSPARENT = YES |
|
# The FORMULA_MACROFILE can contain LaTeX \newcommand and \renewcommand commands |
# to create new LaTeX commands to be used in formulas as building blocks. See |
# the section "Including formulas" for details. |
|
FORMULA_MACROFILE = |
|
# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see |
# https://www.mathjax.org) which uses client side JavaScript for the rendering |
# instead of using pre-rendered bitmaps. Use this if you do not have LaTeX |
# installed or if you want to formulas look prettier in the HTML output. When |
# enabled you may also need to install MathJax separately and configure the path |
# to it using the MATHJAX_RELPATH option. |
# The default value is: NO. |
# This tag requires that the tag GENERATE_HTML is set to YES. |
|
USE_MATHJAX = NO |
|
# When MathJax is enabled you can set the default output format to be used for |
# the MathJax output. See the MathJax site (see: |
# http://docs.mathjax.org/en/latest/output.html) for more details. |
# Possible values are: HTML-CSS (which is slower, but has the best |
# compatibility), NativeMML (i.e. MathML) and SVG. |
# The default value is: HTML-CSS. |
# This tag requires that the tag USE_MATHJAX is set to YES. |
|
MATHJAX_FORMAT = HTML-CSS |
|
# When MathJax is enabled you need to specify the location relative to the HTML |
# output directory using the MATHJAX_RELPATH option. The destination directory |
# should contain the MathJax.js script. For instance, if the mathjax directory |
# is located at the same level as the HTML output directory, then |
# MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax |
# Content Delivery Network so you can quickly see the result without installing |
# MathJax. However, it is strongly recommended to install a local copy of |
# MathJax from https://www.mathjax.org before deployment. |
# The default value is: https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/. |
# This tag requires that the tag USE_MATHJAX is set to YES. |
|
MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest |
|
# The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax |
# extension names that should be enabled during MathJax rendering. For example |
# MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols |
# This tag requires that the tag USE_MATHJAX is set to YES. |
|
MATHJAX_EXTENSIONS = |
|
# The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces |
# of code that will be used on startup of the MathJax code. See the MathJax site |
# (see: http://docs.mathjax.org/en/latest/output.html) for more details. For an |
# example see the documentation. |
# This tag requires that the tag USE_MATHJAX is set to YES. |
|
MATHJAX_CODEFILE = |
|
# When the SEARCHENGINE tag is enabled doxygen will generate a search box for |
# the HTML output. The underlying search engine uses javascript and DHTML and |
# should work on any modern browser. Note that when using HTML help |
# (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET) |
# there is already a search function so this one should typically be disabled. |
# For large projects the javascript based search engine can be slow, then |
# enabling SERVER_BASED_SEARCH may provide a better solution. It is possible to |
# search using the keyboard; to jump to the search box use <access key> + S |
# (what the <access key> is depends on the OS and browser, but it is typically |
# <CTRL>, <ALT>/<option>, or both). Inside the search box use the <cursor down |
# key> to jump into the search results window, the results can be navigated |
# using the <cursor keys>. Press <Enter> to select an item or <escape> to cancel |
# the search. The filter options can be selected when the cursor is inside the |
# search box by pressing <Shift>+<cursor down>. Also here use the <cursor keys> |
# to select a filter and <Enter> or <escape> to activate or cancel the filter |
# option. |
# The default value is: YES. |
# This tag requires that the tag GENERATE_HTML is set to YES. |
|
SEARCHENGINE = YES |
|
# When the SERVER_BASED_SEARCH tag is enabled the search engine will be |
# implemented using a web server instead of a web client using JavaScript. There |
# are two flavors of web server based searching depending on the EXTERNAL_SEARCH |
# setting. When disabled, doxygen will generate a PHP script for searching and |
# an index file used by the script. When EXTERNAL_SEARCH is enabled the indexing |
# and searching needs to be provided by external tools. See the section |
# "External Indexing and Searching" for details. |
# The default value is: NO. |
# This tag requires that the tag SEARCHENGINE is set to YES. |
|
SERVER_BASED_SEARCH = NO |
|
# When EXTERNAL_SEARCH tag is enabled doxygen will no longer generate the PHP |
# script for searching. Instead the search results are written to an XML file |
# which needs to be processed by an external indexer. Doxygen will invoke an |
# external search engine pointed to by the SEARCHENGINE_URL option to obtain the |
# search results. |
# |
# Doxygen ships with an example indexer (doxyindexer) and search engine |
# (doxysearch.cgi) which are based on the open source search engine library |
# Xapian (see: https://xapian.org/). |
# |
# See the section "External Indexing and Searching" for details. |
# The default value is: NO. |
# This tag requires that the tag SEARCHENGINE is set to YES. |
|
EXTERNAL_SEARCH = NO |
|
# The SEARCHENGINE_URL should point to a search engine hosted by a web server |
# which will return the search results when EXTERNAL_SEARCH is enabled. |
# |
# Doxygen ships with an example indexer (doxyindexer) and search engine |
# (doxysearch.cgi) which are based on the open source search engine library |
# Xapian (see: https://xapian.org/). See the section "External Indexing and |
# Searching" for details. |
# This tag requires that the tag SEARCHENGINE is set to YES. |
|
SEARCHENGINE_URL = |
|
# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the unindexed |
# search data is written to a file for indexing by an external tool. With the |
# SEARCHDATA_FILE tag the name of this file can be specified. |
# The default file is: searchdata.xml. |
# This tag requires that the tag SEARCHENGINE is set to YES. |
|
SEARCHDATA_FILE = searchdata.xml |
|
# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the |
# EXTERNAL_SEARCH_ID tag can be used as an identifier for the project. This is |
# useful in combination with EXTRA_SEARCH_MAPPINGS to search through multiple |
# projects and redirect the results back to the right project. |
# This tag requires that the tag SEARCHENGINE is set to YES. |
|
EXTERNAL_SEARCH_ID = |
|
# The EXTRA_SEARCH_MAPPINGS tag can be used to enable searching through doxygen |
# projects other than the one defined by this configuration file, but that are |
# all added to the same external search index. Each project needs to have a |
# unique id set via EXTERNAL_SEARCH_ID. The search mapping then maps the id of |
# to a relative location where the documentation can be found. The format is: |
# EXTRA_SEARCH_MAPPINGS = tagname1=loc1 tagname2=loc2 ... |
# This tag requires that the tag SEARCHENGINE is set to YES. |
|
EXTRA_SEARCH_MAPPINGS = |
|
#--------------------------------------------------------------------------- |
213,35 → 1684,257
# Configuration options related to the LaTeX output |
#--------------------------------------------------------------------------- |
|
# If the GENERATE_LATEX tag is set to YES, doxygen will generate LaTeX output. |
# The default value is: YES. |
|
GENERATE_LATEX = NO |
|
# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. If a |
# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of |
# it. |
# The default directory is: latex. |
# This tag requires that the tag GENERATE_LATEX is set to YES. |
|
LATEX_OUTPUT = latex |
|
# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be |
# invoked. |
# |
# Note that when not enabling USE_PDFLATEX the default is latex when enabling |
# USE_PDFLATEX the default is pdflatex and when in the later case latex is |
# chosen this is overwritten by pdflatex. For specific output languages the |
# default can have been set differently, this depends on the implementation of |
# the output language. |
# This tag requires that the tag GENERATE_LATEX is set to YES. |
|
LATEX_CMD_NAME = latex |
|
# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to generate |
# index for LaTeX. |
# Note: This tag is used in the Makefile / make.bat. |
# See also: LATEX_MAKEINDEX_CMD for the part in the generated output file |
# (.tex). |
# The default file is: makeindex. |
# This tag requires that the tag GENERATE_LATEX is set to YES. |
|
MAKEINDEX_CMD_NAME = makeindex |
|
# The LATEX_MAKEINDEX_CMD tag can be used to specify the command name to |
# generate index for LaTeX. In case there is no backslash (\) as first character |
# it will be automatically added in the LaTeX code. |
# Note: This tag is used in the generated output file (.tex). |
# See also: MAKEINDEX_CMD_NAME for the part in the Makefile / make.bat. |
# The default value is: makeindex. |
# This tag requires that the tag GENERATE_LATEX is set to YES. |
|
LATEX_MAKEINDEX_CMD = makeindex |
|
# If the COMPACT_LATEX tag is set to YES, doxygen generates more compact LaTeX |
# documents. This may be useful for small projects and may help to save some |
# trees in general. |
# The default value is: NO. |
# This tag requires that the tag GENERATE_LATEX is set to YES. |
|
COMPACT_LATEX = NO |
|
# The PAPER_TYPE tag can be used to set the paper type that is used by the |
# printer. |
# Possible values are: a4 (210 x 297 mm), letter (8.5 x 11 inches), legal (8.5 x |
# 14 inches) and executive (7.25 x 10.5 inches). |
# The default value is: a4. |
# This tag requires that the tag GENERATE_LATEX is set to YES. |
|
PAPER_TYPE = a4 |
|
# The EXTRA_PACKAGES tag can be used to specify one or more LaTeX package names |
# that should be included in the LaTeX output. The package can be specified just |
# by its name or with the correct syntax as to be used with the LaTeX |
# \usepackage command. To get the times font for instance you can specify : |
# EXTRA_PACKAGES=times or EXTRA_PACKAGES={times} |
# To use the option intlimits with the amsmath package you can specify: |
# EXTRA_PACKAGES=[intlimits]{amsmath} |
# If left blank no extra packages will be included. |
# This tag requires that the tag GENERATE_LATEX is set to YES. |
|
EXTRA_PACKAGES = |
|
# The LATEX_HEADER tag can be used to specify a personal LaTeX header for the |
# generated LaTeX document. The header should contain everything until the first |
# chapter. If it is left blank doxygen will generate a standard header. See |
# section "Doxygen usage" for information on how to let doxygen write the |
# default header to a separate file. |
# |
# Note: Only use a user-defined header if you know what you are doing! The |
# following commands have a special meaning inside the header: $title, |
# $datetime, $date, $doxygenversion, $projectname, $projectnumber, |
# $projectbrief, $projectlogo. Doxygen will replace $title with the empty |
# string, for the replacement values of the other commands the user is referred |
# to HTML_HEADER. |
# This tag requires that the tag GENERATE_LATEX is set to YES. |
|
LATEX_HEADER = |
|
# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for the |
# generated LaTeX document. The footer should contain everything after the last |
# chapter. If it is left blank doxygen will generate a standard footer. See |
# LATEX_HEADER for more information on how to generate a default footer and what |
# special commands can be used inside the footer. |
# |
# Note: Only use a user-defined footer if you know what you are doing! |
# This tag requires that the tag GENERATE_LATEX is set to YES. |
|
LATEX_FOOTER = |
|
# The LATEX_EXTRA_STYLESHEET tag can be used to specify additional user-defined |
# LaTeX style sheets that are included after the standard style sheets created |
# by doxygen. Using this option one can overrule certain style aspects. Doxygen |
# will copy the style sheet files to the output directory. |
# Note: The order of the extra style sheet files is of importance (e.g. the last |
# style sheet in the list overrules the setting of the previous ones in the |
# list). |
# This tag requires that the tag GENERATE_LATEX is set to YES. |
|
LATEX_EXTRA_STYLESHEET = |
|
# The LATEX_EXTRA_FILES tag can be used to specify one or more extra images or |
# other source files which should be copied to the LATEX_OUTPUT output |
# directory. Note that the files will be copied as-is; there are no commands or |
# markers available. |
# This tag requires that the tag GENERATE_LATEX is set to YES. |
|
LATEX_EXTRA_FILES = |
|
# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated is |
# prepared for conversion to PDF (using ps2pdf or pdflatex). The PDF file will |
# contain links (just like the HTML output) instead of page references. This |
# makes the output suitable for online browsing using a PDF viewer. |
# The default value is: YES. |
# This tag requires that the tag GENERATE_LATEX is set to YES. |
|
PDF_HYPERLINKS = YES |
|
# If the USE_PDFLATEX tag is set to YES, doxygen will use pdflatex to generate |
# the PDF file directly from the LaTeX files. Set this option to YES, to get a |
# higher quality PDF documentation. |
# The default value is: YES. |
# This tag requires that the tag GENERATE_LATEX is set to YES. |
|
USE_PDFLATEX = YES |
|
# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \batchmode |
# command to the generated LaTeX files. This will instruct LaTeX to keep running |
# if errors occur, instead of asking the user for help. This option is also used |
# when generating formulas in HTML. |
# The default value is: NO. |
# This tag requires that the tag GENERATE_LATEX is set to YES. |
|
LATEX_BATCHMODE = NO |
|
# If the LATEX_HIDE_INDICES tag is set to YES then doxygen will not include the |
# index chapters (such as File Index, Compound Index, etc.) in the output. |
# The default value is: NO. |
# This tag requires that the tag GENERATE_LATEX is set to YES. |
|
LATEX_HIDE_INDICES = NO |
|
# If the LATEX_SOURCE_CODE tag is set to YES then doxygen will include source |
# code with syntax highlighting in the LaTeX output. |
# |
# Note that which sources are shown also depends on other settings such as |
# SOURCE_BROWSER. |
# The default value is: NO. |
# This tag requires that the tag GENERATE_LATEX is set to YES. |
|
LATEX_SOURCE_CODE = NO |
|
# The LATEX_BIB_STYLE tag can be used to specify the style to use for the |
# bibliography, e.g. plainnat, or ieeetr. See |
# https://en.wikipedia.org/wiki/BibTeX and \cite for more info. |
# The default value is: plain. |
# This tag requires that the tag GENERATE_LATEX is set to YES. |
|
LATEX_BIB_STYLE = plain |
|
# If the LATEX_TIMESTAMP tag is set to YES then the footer of each generated |
# page will contain the date and time when the page was generated. Setting this |
# to NO can help when comparing the output of multiple runs. |
# The default value is: NO. |
# This tag requires that the tag GENERATE_LATEX is set to YES. |
|
LATEX_TIMESTAMP = NO |
|
# The LATEX_EMOJI_DIRECTORY tag is used to specify the (relative or absolute) |
# path from which the emoji images will be read. If a relative path is entered, |
# it will be relative to the LATEX_OUTPUT directory. If left blank the |
# LATEX_OUTPUT directory will be used. |
# This tag requires that the tag GENERATE_LATEX is set to YES. |
|
LATEX_EMOJI_DIRECTORY = |
|
#--------------------------------------------------------------------------- |
# Configuration options related to the RTF output |
#--------------------------------------------------------------------------- |
|
# If the GENERATE_RTF tag is set to YES, doxygen will generate RTF output. The |
# RTF output is optimized for Word 97 and may not look too pretty with other RTF |
# readers/editors. |
# The default value is: NO. |
|
GENERATE_RTF = NO |
|
# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. If a |
# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of |
# it. |
# The default directory is: rtf. |
# This tag requires that the tag GENERATE_RTF is set to YES. |
|
RTF_OUTPUT = rtf |
|
# If the COMPACT_RTF tag is set to YES, doxygen generates more compact RTF |
# documents. This may be useful for small projects and may help to save some |
# trees in general. |
# The default value is: NO. |
# This tag requires that the tag GENERATE_RTF is set to YES. |
|
COMPACT_RTF = NO |
|
# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated will |
# contain hyperlink fields. The RTF file will contain links (just like the HTML |
# output) instead of page references. This makes the output suitable for online |
# browsing using Word or some other Word compatible readers that support those |
# fields. |
# |
# Note: WordPad (write) and others do not support links. |
# The default value is: NO. |
# This tag requires that the tag GENERATE_RTF is set to YES. |
|
RTF_HYPERLINKS = NO |
|
# Load stylesheet definitions from file. Syntax is similar to doxygen's |
# configuration file, i.e. a series of assignments. You only have to provide |
# replacements, missing definitions are set to their default value. |
# |
# See also section "Doxygen usage" for information on how to generate the |
# default style sheet that doxygen normally uses. |
# This tag requires that the tag GENERATE_RTF is set to YES. |
|
RTF_STYLESHEET_FILE = |
|
# Set optional variables used in the generation of an RTF document. Syntax is |
# similar to doxygen's configuration file. A template extensions file can be |
# generated using doxygen -e rtf extensionFile. |
# This tag requires that the tag GENERATE_RTF is set to YES. |
|
RTF_EXTENSIONS_FILE = |
|
# If the RTF_SOURCE_CODE tag is set to YES then doxygen will include source code |
# with syntax highlighting in the RTF output. |
# |
# Note that which sources are shown also depends on other settings such as |
# SOURCE_BROWSER. |
# The default value is: NO. |
# This tag requires that the tag GENERATE_RTF is set to YES. |
|
RTF_SOURCE_CODE = NO |
|
#--------------------------------------------------------------------------- |
248,10 → 1941,44
# Configuration options related to the man page output |
#--------------------------------------------------------------------------- |
|
# If the GENERATE_MAN tag is set to YES, doxygen will generate man pages for |
# classes and files. |
# The default value is: NO. |
|
GENERATE_MAN = NO |
|
# The MAN_OUTPUT tag is used to specify where the man pages will be put. If a |
# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of |
# it. A directory man3 will be created inside the directory specified by |
# MAN_OUTPUT. |
# The default directory is: man. |
# This tag requires that the tag GENERATE_MAN is set to YES. |
|
MAN_OUTPUT = man |
|
# The MAN_EXTENSION tag determines the extension that is added to the generated |
# man pages. In case the manual section does not start with a number, the number |
# 3 is prepended. The dot (.) at the beginning of the MAN_EXTENSION tag is |
# optional. |
# The default value is: .3. |
# This tag requires that the tag GENERATE_MAN is set to YES. |
|
MAN_EXTENSION = .3 |
|
# The MAN_SUBDIR tag determines the name of the directory created within |
# MAN_OUTPUT in which the man pages are placed. If defaults to man followed by |
# MAN_EXTENSION with the initial . removed. |
# This tag requires that the tag GENERATE_MAN is set to YES. |
|
MAN_SUBDIR = |
|
# If the MAN_LINKS tag is set to YES and doxygen generates man output, then it |
# will generate one additional man file for each entity documented in the real |
# man page(s). These additional files only source the real man page, but without |
# them the man command would be unable to find the correct page. |
# The default value is: NO. |
# This tag requires that the tag GENERATE_MAN is set to YES. |
|
MAN_LINKS = NO |
|
#--------------------------------------------------------------------------- |
258,16 → 1985,61
# Configuration options related to the XML output |
#--------------------------------------------------------------------------- |
|
# If the GENERATE_XML tag is set to YES, doxygen will generate an XML file that |
# captures the structure of the code including all documentation. |
# The default value is: NO. |
|
GENERATE_XML = NO |
|
# The XML_OUTPUT tag is used to specify where the XML pages will be put. If a |
# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of |
# it. |
# The default directory is: xml. |
# This tag requires that the tag GENERATE_XML is set to YES. |
|
XML_OUTPUT = xml |
|
# If the XML_PROGRAMLISTING tag is set to YES, doxygen will dump the program |
# listings (including syntax highlighting and cross-referencing information) to |
# the XML output. Note that enabling this will significantly increase the size |
# of the XML output. |
# The default value is: YES. |
# This tag requires that the tag GENERATE_XML is set to YES. |
|
XML_PROGRAMLISTING = YES |
|
# If the XML_NS_MEMB_FILE_SCOPE tag is set to YES, doxygen will include |
# namespace members in file scope as well, matching the HTML output. |
# The default value is: NO. |
# This tag requires that the tag GENERATE_XML is set to YES. |
|
XML_NS_MEMB_FILE_SCOPE = NO |
|
#--------------------------------------------------------------------------- |
# Configuration options related to the DOCBOOK output |
#--------------------------------------------------------------------------- |
|
# If the GENERATE_DOCBOOK tag is set to YES, doxygen will generate Docbook files |
# that can be used to generate PDF. |
# The default value is: NO. |
|
GENERATE_DOCBOOK = NO |
|
# The DOCBOOK_OUTPUT tag is used to specify where the Docbook pages will be put. |
# If a relative path is entered the value of OUTPUT_DIRECTORY will be put in |
# front of it. |
# The default directory is: docbook. |
# This tag requires that the tag GENERATE_DOCBOOK is set to YES. |
|
DOCBOOK_OUTPUT = docbook |
|
# If the DOCBOOK_PROGRAMLISTING tag is set to YES, doxygen will include the |
# program listings (including syntax highlighting and cross-referencing |
# information) to the DOCBOOK output. Note that enabling this will significantly |
# increase the size of the DOCBOOK output. |
# The default value is: NO. |
# This tag requires that the tag GENERATE_DOCBOOK is set to YES. |
|
DOCBOOK_PROGRAMLISTING = NO |
|
#--------------------------------------------------------------------------- |
274,6 → 2046,12
# Configuration options for the AutoGen Definitions output |
#--------------------------------------------------------------------------- |
|
# If the GENERATE_AUTOGEN_DEF tag is set to YES, doxygen will generate an |
# AutoGen Definitions (see http://autogen.sourceforge.net/) file that captures |
# the structure of the code including all documentation. Note that this feature |
# is still experimental and incomplete at the moment. |
# The default value is: NO. |
|
GENERATE_AUTOGEN_DEF = NO |
|
#--------------------------------------------------------------------------- |
280,9 → 2058,38
# Configuration options related to the Perl module output |
#--------------------------------------------------------------------------- |
|
# If the GENERATE_PERLMOD tag is set to YES, doxygen will generate a Perl module |
# file that captures the structure of the code including all documentation. |
# |
# Note that this feature is still experimental and incomplete at the moment. |
# The default value is: NO. |
|
GENERATE_PERLMOD = NO |
|
# If the PERLMOD_LATEX tag is set to YES, doxygen will generate the necessary |
# Makefile rules, Perl scripts and LaTeX code to be able to generate PDF and DVI |
# output from the Perl module output. |
# The default value is: NO. |
# This tag requires that the tag GENERATE_PERLMOD is set to YES. |
|
PERLMOD_LATEX = NO |
|
# If the PERLMOD_PRETTY tag is set to YES, the Perl module output will be nicely |
# formatted so it can be parsed by a human reader. This is useful if you want to |
# understand what is going on. On the other hand, if this tag is set to NO, the |
# size of the Perl module output will be much smaller and Perl will parse it |
# just the same. |
# The default value is: YES. |
# This tag requires that the tag GENERATE_PERLMOD is set to YES. |
|
PERLMOD_PRETTY = YES |
|
# The names of the make variables in the generated doxyrules.make file are |
# prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. This is useful |
# so different doxyrules.make files included by the same Makefile don't |
# overwrite each other's variables. |
# This tag requires that the tag GENERATE_PERLMOD is set to YES. |
|
PERLMOD_MAKEVAR_PREFIX = |
|
#--------------------------------------------------------------------------- |
289,14 → 2096,78
# Configuration options related to the preprocessor |
#--------------------------------------------------------------------------- |
|
# If the ENABLE_PREPROCESSING tag is set to YES, doxygen will evaluate all |
# C-preprocessor directives found in the sources and include files. |
# The default value is: YES. |
|
ENABLE_PREPROCESSING = YES |
|
# If the MACRO_EXPANSION tag is set to YES, doxygen will expand all macro names |
# in the source code. If set to NO, only conditional compilation will be |
# performed. Macro expansion can be done in a controlled way by setting |
# EXPAND_ONLY_PREDEF to YES. |
# The default value is: NO. |
# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. |
|
MACRO_EXPANSION = YES |
|
# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES then |
# the macro expansion is limited to the macros specified with the PREDEFINED and |
# EXPAND_AS_DEFINED tags. |
# The default value is: NO. |
# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. |
|
EXPAND_ONLY_PREDEF = YES |
|
# If the SEARCH_INCLUDES tag is set to YES, the include files in the |
# INCLUDE_PATH will be searched if a #include is found. |
# The default value is: YES. |
# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. |
|
SEARCH_INCLUDES = YES |
|
# The INCLUDE_PATH tag can be used to specify one or more directories that |
# contain include files that are not input files but should be processed by the |
# preprocessor. |
# This tag requires that the tag SEARCH_INCLUDES is set to YES. |
|
INCLUDE_PATH = |
|
# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard |
# patterns (like *.h and *.hpp) to filter out the header-files in the |
# directories. If left blank, the patterns specified with FILE_PATTERNS will be |
# used. |
# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. |
|
INCLUDE_FILE_PATTERNS = |
|
# The PREDEFINED tag can be used to specify one or more macro names that are |
# defined before the preprocessor is started (similar to the -D option of e.g. |
# gcc). The argument of the tag is a list of macros of the form: name or |
# name=definition (no spaces). If the definition and the "=" are omitted, "=1" |
# is assumed. To prevent a macro definition from being undefined via #undef or |
# recursively expanded use the := operator instead of the = operator. |
# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. |
|
PREDEFINED = __attribute__((x))= |
|
# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this |
# tag can be used to specify a list of macro names that should be expanded. The |
# macro definition that is found in the sources will be used. Use the PREDEFINED |
# tag if you want to use a different macro definition that overrules the |
# definition found in the source code. |
# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. |
|
EXPAND_AS_DEFINED = |
|
# If the SKIP_FUNCTION_MACROS tag is set to YES then doxygen's preprocessor will |
# remove all references to function-like macros that are alone on a line, have |
# an all uppercase name, and do not end with a semicolon. Such function macros |
# are typically used for boiler-plate code, and will confuse the parser if not |
# removed. |
# The default value is: YES. |
# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. |
|
SKIP_FUNCTION_MACROS = YES |
|
#--------------------------------------------------------------------------- |
303,49 → 2174,356
# Configuration options related to external references |
#--------------------------------------------------------------------------- |
|
# The TAGFILES tag can be used to specify one or more tag files. For each tag |
# file the location of the external documentation should be added. The format of |
# a tag file without this location is as follows: |
# TAGFILES = file1 file2 ... |
# Adding location for the tag files is done as follows: |
# TAGFILES = file1=loc1 "file2 = loc2" ... |
# where loc1 and loc2 can be relative or absolute paths or URLs. See the |
# section "Linking to external documentation" for more information about the use |
# of tag files. |
# Note: Each tag file must have a unique name (where the name does NOT include |
# the path). If a tag file is not located in the directory in which doxygen is |
# run, you must also specify the path to the tagfile here. |
|
TAGFILES = |
|
# When a file name is specified after GENERATE_TAGFILE, doxygen will create a |
# tag file that is based on the input files it reads. See section "Linking to |
# external documentation" for more information about the usage of tag files. |
|
GENERATE_TAGFILE = |
|
# If the ALLEXTERNALS tag is set to YES, all external class will be listed in |
# the class index. If set to NO, only the inherited external classes will be |
# listed. |
# The default value is: NO. |
|
ALLEXTERNALS = NO |
|
# If the EXTERNAL_GROUPS tag is set to YES, all external groups will be listed |
# in the modules index. If set to NO, only the current project's groups will be |
# listed. |
# The default value is: YES. |
|
EXTERNAL_GROUPS = YES |
|
# If the EXTERNAL_PAGES tag is set to YES, all external pages will be listed in |
# the related pages index. If set to NO, only the current project's pages will |
# be listed. |
# The default value is: YES. |
|
EXTERNAL_PAGES = YES |
PERL_PATH = /usr/bin/perl |
|
#--------------------------------------------------------------------------- |
# Configuration options related to the dot tool |
#--------------------------------------------------------------------------- |
|
# If the CLASS_DIAGRAMS tag is set to YES, doxygen will generate a class diagram |
# (in HTML and LaTeX) for classes with base or super classes. Setting the tag to |
# NO turns the diagrams off. Note that this option also works with HAVE_DOT |
# disabled, but it is recommended to install and use dot, since it yields more |
# powerful graphs. |
# The default value is: YES. |
|
CLASS_DIAGRAMS = NO |
MSCGEN_PATH = |
|
# You can include diagrams made with dia in doxygen documentation. Doxygen will |
# then run dia to produce the diagram and insert it in the documentation. The |
# DIA_PATH tag allows you to specify the directory where the dia binary resides. |
# If left empty dia is assumed to be found in the default search path. |
|
DIA_PATH = |
|
# If set to YES the inheritance and collaboration graphs will hide inheritance |
# and usage relations if the target is undocumented or is not a class. |
# The default value is: YES. |
|
HIDE_UNDOC_RELATIONS = YES |
|
# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is |
# available from the path. This tool is part of Graphviz (see: |
# http://www.graphviz.org/), a graph visualization toolkit from AT&T and Lucent |
# Bell Labs. The other options in this section have no effect if this option is |
# set to NO |
# The default value is: YES. |
|
HAVE_DOT = NO |
|
# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is allowed |
# to run in parallel. When set to 0 doxygen will base this on the number of |
# processors available in the system. You can set it explicitly to a value |
# larger than 0 to get control over the balance between CPU load and processing |
# speed. |
# Minimum value: 0, maximum value: 32, default value: 0. |
# This tag requires that the tag HAVE_DOT is set to YES. |
|
DOT_NUM_THREADS = 0 |
|
# When you want a differently looking font in the dot files that doxygen |
# generates you can specify the font name using DOT_FONTNAME. You need to make |
# sure dot is able to find the font, which can be done by putting it in a |
# standard location or by setting the DOTFONTPATH environment variable or by |
# setting DOT_FONTPATH to the directory containing the font. |
# The default value is: Helvetica. |
# This tag requires that the tag HAVE_DOT is set to YES. |
|
DOT_FONTNAME = Helvetica |
|
# The DOT_FONTSIZE tag can be used to set the size (in points) of the font of |
# dot graphs. |
# Minimum value: 4, maximum value: 24, default value: 10. |
# This tag requires that the tag HAVE_DOT is set to YES. |
|
DOT_FONTSIZE = 10 |
|
# By default doxygen will tell dot to use the default font as specified with |
# DOT_FONTNAME. If you specify a different font using DOT_FONTNAME you can set |
# the path where dot can find it using this tag. |
# This tag requires that the tag HAVE_DOT is set to YES. |
|
DOT_FONTPATH = |
|
# If the CLASS_GRAPH tag is set to YES then doxygen will generate a graph for |
# each documented class showing the direct and indirect inheritance relations. |
# Setting this tag to YES will force the CLASS_DIAGRAMS tag to NO. |
# The default value is: YES. |
# This tag requires that the tag HAVE_DOT is set to YES. |
|
CLASS_GRAPH = YES |
|
# If the COLLABORATION_GRAPH tag is set to YES then doxygen will generate a |
# graph for each documented class showing the direct and indirect implementation |
# dependencies (inheritance, containment, and class references variables) of the |
# class with other documented classes. |
# The default value is: YES. |
# This tag requires that the tag HAVE_DOT is set to YES. |
|
COLLABORATION_GRAPH = YES |
|
# If the GROUP_GRAPHS tag is set to YES then doxygen will generate a graph for |
# groups, showing the direct groups dependencies. |
# The default value is: YES. |
# This tag requires that the tag HAVE_DOT is set to YES. |
|
GROUP_GRAPHS = YES |
|
# If the UML_LOOK tag is set to YES, doxygen will generate inheritance and |
# collaboration diagrams in a style similar to the OMG's Unified Modeling |
# Language. |
# The default value is: NO. |
# This tag requires that the tag HAVE_DOT is set to YES. |
|
UML_LOOK = NO |
|
# If the UML_LOOK tag is enabled, the fields and methods are shown inside the |
# class node. If there are many fields or methods and many nodes the graph may |
# become too big to be useful. The UML_LIMIT_NUM_FIELDS threshold limits the |
# number of items for each type to make the size more manageable. Set this to 0 |
# for no limit. Note that the threshold may be exceeded by 50% before the limit |
# is enforced. So when you set the threshold to 10, up to 15 fields may appear, |
# but if the number exceeds 15, the total amount of fields shown is limited to |
# 10. |
# Minimum value: 0, maximum value: 100, default value: 10. |
# This tag requires that the tag HAVE_DOT is set to YES. |
|
UML_LIMIT_NUM_FIELDS = 10 |
|
# If the TEMPLATE_RELATIONS tag is set to YES then the inheritance and |
# collaboration graphs will show the relations between templates and their |
# instances. |
# The default value is: NO. |
# This tag requires that the tag HAVE_DOT is set to YES. |
|
TEMPLATE_RELATIONS = NO |
|
# If the INCLUDE_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are set to |
# YES then doxygen will generate a graph for each documented file showing the |
# direct and indirect include dependencies of the file with other documented |
# files. |
# The default value is: YES. |
# This tag requires that the tag HAVE_DOT is set to YES. |
|
INCLUDE_GRAPH = YES |
|
# If the INCLUDED_BY_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are |
# set to YES then doxygen will generate a graph for each documented file showing |
# the direct and indirect include dependencies of the file with other documented |
# files. |
# The default value is: YES. |
# This tag requires that the tag HAVE_DOT is set to YES. |
|
INCLUDED_BY_GRAPH = YES |
|
# If the CALL_GRAPH tag is set to YES then doxygen will generate a call |
# dependency graph for every global function or class method. |
# |
# Note that enabling this option will significantly increase the time of a run. |
# So in most cases it will be better to enable call graphs for selected |
# functions only using the \callgraph command. Disabling a call graph can be |
# accomplished by means of the command \hidecallgraph. |
# The default value is: NO. |
# This tag requires that the tag HAVE_DOT is set to YES. |
|
CALL_GRAPH = NO |
|
# If the CALLER_GRAPH tag is set to YES then doxygen will generate a caller |
# dependency graph for every global function or class method. |
# |
# Note that enabling this option will significantly increase the time of a run. |
# So in most cases it will be better to enable caller graphs for selected |
# functions only using the \callergraph command. Disabling a caller graph can be |
# accomplished by means of the command \hidecallergraph. |
# The default value is: NO. |
# This tag requires that the tag HAVE_DOT is set to YES. |
|
CALLER_GRAPH = NO |
|
# If the GRAPHICAL_HIERARCHY tag is set to YES then doxygen will graphical |
# hierarchy of all classes instead of a textual one. |
# The default value is: YES. |
# This tag requires that the tag HAVE_DOT is set to YES. |
|
GRAPHICAL_HIERARCHY = YES |
|
# If the DIRECTORY_GRAPH tag is set to YES then doxygen will show the |
# dependencies a directory has on other directories in a graphical way. The |
# dependency relations are determined by the #include relations between the |
# files in the directories. |
# The default value is: YES. |
# This tag requires that the tag HAVE_DOT is set to YES. |
|
DIRECTORY_GRAPH = YES |
|
# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images |
# generated by dot. For an explanation of the image formats see the section |
# output formats in the documentation of the dot tool (Graphviz (see: |
# http://www.graphviz.org/)). |
# Note: If you choose svg you need to set HTML_FILE_EXTENSION to xhtml in order |
# to make the SVG files visible in IE 9+ (other browsers do not have this |
# requirement). |
# Possible values are: png, png:cairo, png:cairo:cairo, png:cairo:gd, png:gd, |
# png:gd:gd, jpg, jpg:cairo, jpg:cairo:gd, jpg:gd, jpg:gd:gd, gif, gif:cairo, |
# gif:cairo:gd, gif:gd, gif:gd:gd, svg, png:gd, png:gd:gd, png:cairo, |
# png:cairo:gd, png:cairo:cairo, png:cairo:gdiplus, png:gdiplus and |
# png:gdiplus:gdiplus. |
# The default value is: png. |
# This tag requires that the tag HAVE_DOT is set to YES. |
|
DOT_IMAGE_FORMAT = png |
|
# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to |
# enable generation of interactive SVG images that allow zooming and panning. |
# |
# Note that this requires a modern browser other than Internet Explorer. Tested |
# and working are Firefox, Chrome, Safari, and Opera. |
# Note: For IE 9+ you need to set HTML_FILE_EXTENSION to xhtml in order to make |
# the SVG files visible. Older versions of IE do not have SVG support. |
# The default value is: NO. |
# This tag requires that the tag HAVE_DOT is set to YES. |
|
INTERACTIVE_SVG = NO |
|
# The DOT_PATH tag can be used to specify the path where the dot tool can be |
# found. If left blank, it is assumed the dot tool can be found in the path. |
# This tag requires that the tag HAVE_DOT is set to YES. |
|
DOT_PATH = |
|
# The DOTFILE_DIRS tag can be used to specify one or more directories that |
# contain dot files that are included in the documentation (see the \dotfile |
# command). |
# This tag requires that the tag HAVE_DOT is set to YES. |
|
DOTFILE_DIRS = |
|
# The MSCFILE_DIRS tag can be used to specify one or more directories that |
# contain msc files that are included in the documentation (see the \mscfile |
# command). |
|
MSCFILE_DIRS = |
|
# The DIAFILE_DIRS tag can be used to specify one or more directories that |
# contain dia files that are included in the documentation (see the \diafile |
# command). |
|
DIAFILE_DIRS = |
|
# When using plantuml, the PLANTUML_JAR_PATH tag should be used to specify the |
# path where java can find the plantuml.jar file. If left blank, it is assumed |
# PlantUML is not used or called during a preprocessing step. Doxygen will |
# generate a warning when it encounters a \startuml command in this case and |
# will not generate output for the diagram. |
|
PLANTUML_JAR_PATH = |
|
# When using plantuml, the PLANTUML_CFG_FILE tag can be used to specify a |
# configuration file for plantuml. |
|
PLANTUML_CFG_FILE = |
|
# When using plantuml, the specified paths are searched for files specified by |
# the !include statement in a plantuml block. |
|
PLANTUML_INCLUDE_PATH = |
|
# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of nodes |
# that will be shown in the graph. If the number of nodes in a graph becomes |
# larger than this value, doxygen will truncate the graph, which is visualized |
# by representing a node as a red box. Note that doxygen if the number of direct |
# children of the root node in a graph is already larger than |
# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note that |
# the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. |
# Minimum value: 0, maximum value: 10000, default value: 50. |
# This tag requires that the tag HAVE_DOT is set to YES. |
|
DOT_GRAPH_MAX_NODES = 50 |
|
# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the graphs |
# generated by dot. A depth value of 3 means that only nodes reachable from the |
# root by following a path via at most 3 edges will be shown. Nodes that lay |
# further from the root node will be omitted. Note that setting this option to 1 |
# or 2 may greatly reduce the computation time needed for large code bases. Also |
# note that the size of a graph can be further restricted by |
# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. |
# Minimum value: 0, maximum value: 1000, default value: 0. |
# This tag requires that the tag HAVE_DOT is set to YES. |
|
MAX_DOT_GRAPH_DEPTH = 0 |
|
# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent |
# background. This is disabled by default, because dot on Windows does not seem |
# to support this out of the box. |
# |
# Warning: Depending on the platform used, enabling this option may lead to |
# badly anti-aliased labels on the edges of a graph (i.e. they become hard to |
# read). |
# The default value is: NO. |
# This tag requires that the tag HAVE_DOT is set to YES. |
|
DOT_TRANSPARENT = NO |
|
# Set the DOT_MULTI_TARGETS tag to YES to allow dot to generate multiple output |
# files in one run (i.e. multiple -o and -T options on the command line). This |
# makes dot run faster, but since only newer versions of dot (>1.8.10) support |
# this, this feature is disabled by default. |
# The default value is: NO. |
# This tag requires that the tag HAVE_DOT is set to YES. |
|
DOT_MULTI_TARGETS = NO |
|
# If the GENERATE_LEGEND tag is set to YES doxygen will generate a legend page |
# explaining the meaning of the various boxes and arrows in the dot generated |
# graphs. |
# The default value is: YES. |
# This tag requires that the tag HAVE_DOT is set to YES. |
|
GENERATE_LEGEND = YES |
|
# If the DOT_CLEANUP tag is set to YES, doxygen will remove the intermediate dot |
# files that are used to generate the various graphs. |
# The default value is: YES. |
# This tag requires that the tag HAVE_DOT is set to YES. |
|
DOT_CLEANUP = YES |
/rtl/core/neorv32_bootloader_image.vhd
51,13 → 51,13
00000040 => x"01612823", |
00000041 => x"01712623", |
00000042 => x"01812423", |
00000043 => x"4e9000ef", |
00000044 => x"4ad000ef", |
00000045 => x"415000ef", |
00000046 => x"285000ef", |
00000047 => x"4c5000ef", |
00000048 => x"26d000ef", |
00000049 => x"fc101473", |
00000043 => x"4fd000ef", |
00000044 => x"4c1000ef", |
00000045 => x"429000ef", |
00000046 => x"299000ef", |
00000047 => x"4d9000ef", |
00000048 => x"281000ef", |
00000049 => x"fc102473", |
00000050 => x"026267b7", |
00000051 => x"9ff78793", |
00000052 => x"00000713", |
67,954 → 67,961
00000056 => x"00200513", |
00000057 => x"0087f463", |
00000058 => x"00400513", |
00000059 => x"391000ef", |
00000059 => x"3a5000ef", |
00000060 => x"00005537", |
00000061 => x"00000613", |
00000062 => x"00000593", |
00000063 => x"b0050513", |
00000064 => x"279000ef", |
00000065 => x"251000ef", |
00000064 => x"28d000ef", |
00000065 => x"265000ef", |
00000066 => x"00245793", |
00000067 => x"00a78533", |
00000068 => x"00f537b3", |
00000069 => x"00b785b3", |
00000070 => x"249000ef", |
00000070 => x"25d000ef", |
00000071 => x"ffff07b7", |
00000072 => x"41478793", |
00000072 => x"42878793", |
00000073 => x"30579073", |
00000074 => x"08000793", |
00000075 => x"30479073", |
00000076 => x"441000ef", |
00000076 => x"455000ef", |
00000077 => x"00100513", |
00000078 => x"41d000ef", |
00000078 => x"431000ef", |
00000079 => x"00000793", |
00000080 => x"34079073", |
00000081 => x"ffff1537", |
00000082 => x"ed850513", |
00000083 => x"2d9000ef", |
00000084 => x"3bc000ef", |
00000082 => x"eec50513", |
00000083 => x"2ed000ef", |
00000084 => x"3d0000ef", |
00000085 => x"ffff1537", |
00000086 => x"f1050513", |
00000087 => x"2c9000ef", |
00000088 => x"fc101573", |
00000089 => x"240000ef", |
00000086 => x"f2450513", |
00000087 => x"2dd000ef", |
00000088 => x"fc102573", |
00000089 => x"254000ef", |
00000090 => x"ffff1537", |
00000091 => x"f1850513", |
00000092 => x"2b5000ef", |
00000093 => x"30101573", |
00000094 => x"22c000ef", |
00000091 => x"f2c50513", |
00000092 => x"2c9000ef", |
00000093 => x"f1402573", |
00000094 => x"240000ef", |
00000095 => x"ffff1537", |
00000096 => x"f2450513", |
00000097 => x"2a1000ef", |
00000098 => x"fc001573", |
00000099 => x"218000ef", |
00000096 => x"f3850513", |
00000097 => x"2b5000ef", |
00000098 => x"30102573", |
00000099 => x"22c000ef", |
00000100 => x"ffff1537", |
00000101 => x"f2c50513", |
00000102 => x"28d000ef", |
00000103 => x"fc601573", |
00000104 => x"ffff14b7", |
00000105 => x"200000ef", |
00000106 => x"f3448513", |
00000107 => x"279000ef", |
00000108 => x"fc401573", |
00000109 => x"1f0000ef", |
00000110 => x"ffff1537", |
00000111 => x"f4050513", |
00000112 => x"265000ef", |
00000113 => x"fc701573", |
00000114 => x"1dc000ef", |
00000115 => x"f3448513", |
00000116 => x"255000ef", |
00000117 => x"fc501573", |
00000118 => x"1cc000ef", |
00000119 => x"ffff1537", |
00000120 => x"f4850513", |
00000121 => x"241000ef", |
00000122 => x"00341413", |
00000123 => x"00000493", |
00000124 => x"ffff1937", |
00000125 => x"fa402783", |
00000126 => x"0607d063", |
00000127 => x"ffff1537", |
00000128 => x"f7850513", |
00000129 => x"221000ef", |
00000130 => x"ffff1937", |
00000131 => x"0f4000ef", |
00000132 => x"ffff19b7", |
00000133 => x"07200a13", |
00000134 => x"06800a93", |
00000135 => x"07500b13", |
00000136 => x"07300b93", |
00000137 => x"ffff14b7", |
00000138 => x"ffff1c37", |
00000139 => x"f8490513", |
00000140 => x"1f5000ef", |
00000141 => x"1e1000ef", |
00000142 => x"00050413", |
00000143 => x"1c9000ef", |
00000144 => x"f7498513", |
00000145 => x"1e1000ef", |
00000146 => x"09440263", |
00000147 => x"03541863", |
00000148 => x"0b0000ef", |
00000149 => x"fd9ff06f", |
00000150 => x"0fd000ef", |
00000151 => x"00b49463", |
00000152 => x"f8856ae3", |
00000153 => x"00100513", |
00000154 => x"508000ef", |
00000155 => x"f7490513", |
00000156 => x"1b5000ef", |
00000157 => x"098000ef", |
00000158 => x"f7dff06f", |
00000159 => x"00000513", |
00000160 => x"01640e63", |
00000161 => x"01741663", |
00000162 => x"72c000ef", |
00000163 => x"fa1ff06f", |
00000164 => x"06c00793", |
00000165 => x"00f41863", |
00000166 => x"00100513", |
00000167 => x"4d4000ef", |
00000168 => x"f8dff06f", |
00000169 => x"06500793", |
00000170 => x"00f41663", |
00000171 => x"060000ef", |
00000172 => x"f7dff06f", |
00000173 => x"03f00793", |
00000174 => x"f8cc0513", |
00000175 => x"00f40463", |
00000176 => x"fa048513", |
00000177 => x"161000ef", |
00000178 => x"f65ff06f", |
00000179 => x"02c12083", |
00000180 => x"02812403", |
00000181 => x"02412483", |
00000182 => x"02012903", |
00000183 => x"01c12983", |
00000184 => x"01812a03", |
00000185 => x"01412a83", |
00000186 => x"01012b03", |
00000187 => x"00c12b83", |
00000188 => x"00812c03", |
00000189 => x"00000513", |
00000190 => x"03010113", |
00000191 => x"00008067", |
00000192 => x"ffff1537", |
00000193 => x"da850513", |
00000194 => x"11d0006f", |
00000195 => x"340017f3", |
00000196 => x"00079863", |
00000101 => x"f4050513", |
00000102 => x"2a1000ef", |
00000103 => x"fc002573", |
00000104 => x"218000ef", |
00000105 => x"ffff1537", |
00000106 => x"f4850513", |
00000107 => x"28d000ef", |
00000108 => x"fc602573", |
00000109 => x"ffff14b7", |
00000110 => x"200000ef", |
00000111 => x"f5048513", |
00000112 => x"279000ef", |
00000113 => x"fc402573", |
00000114 => x"1f0000ef", |
00000115 => x"ffff1537", |
00000116 => x"f5c50513", |
00000117 => x"265000ef", |
00000118 => x"fc702573", |
00000119 => x"1dc000ef", |
00000120 => x"f5048513", |
00000121 => x"255000ef", |
00000122 => x"fc502573", |
00000123 => x"1cc000ef", |
00000124 => x"ffff1537", |
00000125 => x"f6450513", |
00000126 => x"241000ef", |
00000127 => x"00341413", |
00000128 => x"00000493", |
00000129 => x"ffff1937", |
00000130 => x"fa402783", |
00000131 => x"0607d063", |
00000132 => x"ffff1537", |
00000133 => x"f9450513", |
00000134 => x"221000ef", |
00000135 => x"ffff1937", |
00000136 => x"0f4000ef", |
00000137 => x"ffff19b7", |
00000138 => x"07200a13", |
00000139 => x"06800a93", |
00000140 => x"07500b13", |
00000141 => x"07300b93", |
00000142 => x"ffff14b7", |
00000143 => x"ffff1c37", |
00000144 => x"fa090513", |
00000145 => x"1f5000ef", |
00000146 => x"1e1000ef", |
00000147 => x"00050413", |
00000148 => x"1c9000ef", |
00000149 => x"f9098513", |
00000150 => x"1e1000ef", |
00000151 => x"09440263", |
00000152 => x"03541863", |
00000153 => x"0b0000ef", |
00000154 => x"fd9ff06f", |
00000155 => x"0fd000ef", |
00000156 => x"00b49463", |
00000157 => x"f8856ae3", |
00000158 => x"00100513", |
00000159 => x"508000ef", |
00000160 => x"f9090513", |
00000161 => x"1b5000ef", |
00000162 => x"098000ef", |
00000163 => x"f7dff06f", |
00000164 => x"00000513", |
00000165 => x"01640e63", |
00000166 => x"01741663", |
00000167 => x"72c000ef", |
00000168 => x"fa1ff06f", |
00000169 => x"06c00793", |
00000170 => x"00f41863", |
00000171 => x"00100513", |
00000172 => x"4d4000ef", |
00000173 => x"f8dff06f", |
00000174 => x"06500793", |
00000175 => x"00f41663", |
00000176 => x"060000ef", |
00000177 => x"f7dff06f", |
00000178 => x"03f00793", |
00000179 => x"fa8c0513", |
00000180 => x"00f40463", |
00000181 => x"fbc48513", |
00000182 => x"161000ef", |
00000183 => x"f65ff06f", |
00000184 => x"02c12083", |
00000185 => x"02812403", |
00000186 => x"02412483", |
00000187 => x"02012903", |
00000188 => x"01c12983", |
00000189 => x"01812a03", |
00000190 => x"01412a83", |
00000191 => x"01012b03", |
00000192 => x"00c12b83", |
00000193 => x"00812c03", |
00000194 => x"00000513", |
00000195 => x"03010113", |
00000196 => x"00008067", |
00000197 => x"ffff1537", |
00000198 => x"e0c50513", |
00000199 => x"1090006f", |
00000200 => x"ff010113", |
00000201 => x"00112623", |
00000202 => x"251000ef", |
00000203 => x"00000793", |
00000204 => x"30479073", |
00000205 => x"ffff1537", |
00000206 => x"e2850513", |
00000207 => x"0e9000ef", |
00000208 => x"fa002783", |
00000209 => x"fe07cee3", |
00000210 => x"fc4017f3", |
00000211 => x"00078067", |
00000212 => x"ff9ff06f", |
00000213 => x"ff010113", |
00000214 => x"00812423", |
00000215 => x"00050413", |
00000216 => x"ffff1537", |
00000217 => x"e3850513", |
00000218 => x"00112623", |
00000219 => x"0b9000ef", |
00000220 => x"00500793", |
00000221 => x"0287e063", |
00000222 => x"03040513", |
00000223 => x"0ff57513", |
00000224 => x"085000ef", |
00000225 => x"1f5000ef", |
00000226 => x"00100513", |
00000227 => x"1c9000ef", |
00000228 => x"0000006f", |
00000229 => x"ffff1537", |
00000230 => x"e4050513", |
00000231 => x"089000ef", |
00000232 => x"fe5ff06f", |
00000233 => x"fe010113", |
00000234 => x"01212823", |
00000235 => x"00050913", |
00000236 => x"ffff1537", |
00000237 => x"00912a23", |
00000238 => x"e4850513", |
00000239 => x"ffff14b7", |
00000240 => x"00812c23", |
00000241 => x"01312623", |
00000242 => x"00112e23", |
00000243 => x"01c00413", |
00000244 => x"055000ef", |
00000245 => x"fac48493", |
00000246 => x"ffc00993", |
00000247 => x"008957b3", |
00000248 => x"00f7f793", |
00000249 => x"00f487b3", |
00000250 => x"0007c503", |
00000251 => x"ffc40413", |
00000252 => x"015000ef", |
00000253 => x"ff3414e3", |
00000254 => x"01c12083", |
00000255 => x"01812403", |
00000256 => x"01412483", |
00000257 => x"01012903", |
00000258 => x"00c12983", |
00000259 => x"02010113", |
00000260 => x"00008067", |
00000261 => x"fb010113", |
00000262 => x"04112623", |
00000263 => x"04512423", |
00000264 => x"04612223", |
00000265 => x"04712023", |
00000266 => x"02812e23", |
00000267 => x"02a12c23", |
00000268 => x"02b12a23", |
00000269 => x"02c12823", |
00000270 => x"02d12623", |
00000271 => x"02e12423", |
00000272 => x"02f12223", |
00000273 => x"03012023", |
00000274 => x"01112e23", |
00000275 => x"01c12c23", |
00000276 => x"01d12a23", |
00000277 => x"01e12823", |
00000278 => x"01f12623", |
00000279 => x"34201473", |
00000280 => x"800007b7", |
00000281 => x"00778793", |
00000282 => x"02f40a63", |
00000283 => x"ffff1537", |
00000284 => x"e4c50513", |
00000285 => x"7b0000ef", |
00000286 => x"00040513", |
00000287 => x"f29ff0ef", |
00000198 => x"dbc50513", |
00000199 => x"11d0006f", |
00000200 => x"340027f3", |
00000201 => x"00079863", |
00000202 => x"ffff1537", |
00000203 => x"e2050513", |
00000204 => x"1090006f", |
00000205 => x"ff010113", |
00000206 => x"00112623", |
00000207 => x"251000ef", |
00000208 => x"00000793", |
00000209 => x"30479073", |
00000210 => x"ffff1537", |
00000211 => x"e3c50513", |
00000212 => x"0e9000ef", |
00000213 => x"fa002783", |
00000214 => x"fe07cee3", |
00000215 => x"fc4027f3", |
00000216 => x"00078067", |
00000217 => x"ff9ff06f", |
00000218 => x"ff010113", |
00000219 => x"00812423", |
00000220 => x"00050413", |
00000221 => x"ffff1537", |
00000222 => x"e4c50513", |
00000223 => x"00112623", |
00000224 => x"0b9000ef", |
00000225 => x"00500793", |
00000226 => x"0287e063", |
00000227 => x"03040513", |
00000228 => x"0ff57513", |
00000229 => x"085000ef", |
00000230 => x"1f5000ef", |
00000231 => x"00100513", |
00000232 => x"1c9000ef", |
00000233 => x"0000006f", |
00000234 => x"ffff1537", |
00000235 => x"e5450513", |
00000236 => x"089000ef", |
00000237 => x"fe5ff06f", |
00000238 => x"fe010113", |
00000239 => x"01212823", |
00000240 => x"00050913", |
00000241 => x"ffff1537", |
00000242 => x"00912a23", |
00000243 => x"e5c50513", |
00000244 => x"ffff14b7", |
00000245 => x"00812c23", |
00000246 => x"01312623", |
00000247 => x"00112e23", |
00000248 => x"01c00413", |
00000249 => x"055000ef", |
00000250 => x"fc848493", |
00000251 => x"ffc00993", |
00000252 => x"008957b3", |
00000253 => x"00f7f793", |
00000254 => x"00f487b3", |
00000255 => x"0007c503", |
00000256 => x"ffc40413", |
00000257 => x"015000ef", |
00000258 => x"ff3414e3", |
00000259 => x"01c12083", |
00000260 => x"01812403", |
00000261 => x"01412483", |
00000262 => x"01012903", |
00000263 => x"00c12983", |
00000264 => x"02010113", |
00000265 => x"00008067", |
00000266 => x"fb010113", |
00000267 => x"04112623", |
00000268 => x"04512423", |
00000269 => x"04612223", |
00000270 => x"04712023", |
00000271 => x"02812e23", |
00000272 => x"02a12c23", |
00000273 => x"02b12a23", |
00000274 => x"02c12823", |
00000275 => x"02d12623", |
00000276 => x"02e12423", |
00000277 => x"02f12223", |
00000278 => x"03012023", |
00000279 => x"01112e23", |
00000280 => x"01c12c23", |
00000281 => x"01d12a23", |
00000282 => x"01e12823", |
00000283 => x"01f12623", |
00000284 => x"34202473", |
00000285 => x"800007b7", |
00000286 => x"00778793", |
00000287 => x"02f40a63", |
00000288 => x"ffff1537", |
00000289 => x"e5c50513", |
00000290 => x"79c000ef", |
00000291 => x"34101573", |
00000292 => x"f15ff0ef", |
00000293 => x"00500513", |
00000294 => x"ebdff0ef", |
00000295 => x"00000513", |
00000296 => x"095000ef", |
00000297 => x"6b0000ef", |
00000298 => x"fc1017f3", |
00000299 => x"0027d793", |
00000300 => x"00a78533", |
00000301 => x"00f537b3", |
00000302 => x"00b785b3", |
00000303 => x"6a4000ef", |
00000304 => x"03c12403", |
00000305 => x"04c12083", |
00000306 => x"04812283", |
00000307 => x"04412303", |
00000308 => x"04012383", |
00000309 => x"03812503", |
00000310 => x"03412583", |
00000311 => x"03012603", |
00000312 => x"02c12683", |
00000313 => x"02812703", |
00000314 => x"02412783", |
00000315 => x"02012803", |
00000316 => x"01c12883", |
00000317 => x"01812e03", |
00000318 => x"01412e83", |
00000319 => x"01012f03", |
00000320 => x"00c12f83", |
00000321 => x"05010113", |
00000322 => x"30200073", |
00000323 => x"fe010113", |
00000324 => x"00112e23", |
00000325 => x"00812c23", |
00000326 => x"00912a23", |
00000327 => x"01212823", |
00000328 => x"01312623", |
00000329 => x"01412423", |
00000330 => x"01512223", |
00000331 => x"f1301973", |
00000332 => x"00000a93", |
00000333 => x"00900993", |
00000334 => x"00300a13", |
00000335 => x"00400493", |
00000336 => x"41500433", |
00000337 => x"00341413", |
00000338 => x"01840413", |
00000339 => x"00895433", |
00000340 => x"0ff47413", |
00000341 => x"00000513", |
00000342 => x"0489ec63", |
00000343 => x"00050863", |
00000344 => x"03050513", |
00000345 => x"0ff57513", |
00000346 => x"69c000ef", |
00000347 => x"03040513", |
00000348 => x"0ff57513", |
00000349 => x"690000ef", |
00000350 => x"014a8663", |
00000351 => x"02e00513", |
00000352 => x"684000ef", |
00000353 => x"001a8a93", |
00000354 => x"fa9a9ce3", |
00000355 => x"01c12083", |
00000356 => x"01812403", |
00000357 => x"01412483", |
00000358 => x"01012903", |
00000359 => x"00c12983", |
00000360 => x"00812a03", |
00000361 => x"00412a83", |
00000362 => x"02010113", |
00000363 => x"00008067", |
00000364 => x"ff640413", |
00000365 => x"00150513", |
00000366 => x"0ff47413", |
00000367 => x"0ff57513", |
00000368 => x"f99ff06f", |
00000369 => x"ff010113", |
00000370 => x"00000513", |
00000371 => x"00112623", |
00000372 => x"00812423", |
00000373 => x"708000ef", |
00000374 => x"00500513", |
00000375 => x"744000ef", |
00000376 => x"00000513", |
00000377 => x"73c000ef", |
00000378 => x"00050413", |
00000379 => x"00000513", |
00000380 => x"70c000ef", |
00000381 => x"00c12083", |
00000382 => x"0ff47513", |
00000383 => x"00812403", |
00000384 => x"01010113", |
00000385 => x"00008067", |
00000386 => x"ff010113", |
00000387 => x"00000513", |
00000388 => x"00112623", |
00000389 => x"00812423", |
00000390 => x"6c4000ef", |
00000391 => x"09e00513", |
00000392 => x"700000ef", |
00000393 => x"00000513", |
00000394 => x"6f8000ef", |
00000395 => x"00050413", |
00000396 => x"00000513", |
00000397 => x"6c8000ef", |
00000398 => x"00c12083", |
00000399 => x"0ff47513", |
00000400 => x"00812403", |
00000401 => x"01010113", |
00000402 => x"00008067", |
00000403 => x"ff010113", |
00000404 => x"00000513", |
00000405 => x"00112623", |
00000406 => x"684000ef", |
00000407 => x"00600513", |
00000408 => x"6c0000ef", |
00000409 => x"00c12083", |
00000410 => x"00000513", |
00000411 => x"01010113", |
00000412 => x"68c0006f", |
00000413 => x"ff010113", |
00000414 => x"00812423", |
00000415 => x"00050413", |
00000416 => x"01055513", |
00000417 => x"0ff57513", |
00000418 => x"00112623", |
00000419 => x"694000ef", |
00000420 => x"00845513", |
00000421 => x"0ff57513", |
00000422 => x"688000ef", |
00000423 => x"0ff47513", |
00000424 => x"00812403", |
00000425 => x"00c12083", |
00000426 => x"01010113", |
00000427 => x"6740006f", |
00000428 => x"ff010113", |
00000429 => x"00812423", |
00000430 => x"00050413", |
00000431 => x"00000513", |
00000432 => x"00112623", |
00000433 => x"618000ef", |
00000434 => x"00300513", |
00000435 => x"654000ef", |
00000436 => x"00040513", |
00000437 => x"fa1ff0ef", |
00000438 => x"00000513", |
00000439 => x"644000ef", |
00000440 => x"00050413", |
00000441 => x"00000513", |
00000442 => x"614000ef", |
00000443 => x"00c12083", |
00000444 => x"0ff47513", |
00000445 => x"00812403", |
00000446 => x"01010113", |
00000447 => x"00008067", |
00000448 => x"fd010113", |
00000449 => x"02812423", |
00000450 => x"02912223", |
00000451 => x"03212023", |
00000452 => x"01312e23", |
00000453 => x"02112623", |
00000454 => x"00050493", |
00000455 => x"00300413", |
00000456 => x"00358913", |
00000457 => x"fff00993", |
00000458 => x"02049e63", |
00000459 => x"4e8000ef", |
00000460 => x"00c10793", |
00000461 => x"008787b3", |
00000462 => x"00a78023", |
00000463 => x"fff40413", |
00000464 => x"ff3414e3", |
00000465 => x"02c12083", |
00000466 => x"02812403", |
00000467 => x"00c12503", |
00000468 => x"02412483", |
00000469 => x"02012903", |
00000470 => x"01c12983", |
00000471 => x"03010113", |
00000472 => x"00008067", |
00000473 => x"40890533", |
00000474 => x"f49ff0ef", |
00000475 => x"fc5ff06f", |
00000476 => x"fd010113", |
00000477 => x"02112623", |
00000478 => x"02812423", |
00000479 => x"02912223", |
00000480 => x"03212023", |
00000481 => x"01312e23", |
00000482 => x"01412c23", |
00000483 => x"01512a23", |
00000484 => x"01612823", |
00000485 => x"01712623", |
00000486 => x"fc001473", |
00000487 => x"00847413", |
00000488 => x"00040663", |
00000489 => x"00400513", |
00000490 => x"badff0ef", |
00000491 => x"00050493", |
00000492 => x"02051863", |
00000493 => x"ffff1537", |
00000494 => x"e6450513", |
00000495 => x"468000ef", |
00000496 => x"000405b7", |
00000497 => x"00048513", |
00000498 => x"f39ff0ef", |
00000499 => x"4788d7b7", |
00000500 => x"afe78793", |
00000501 => x"02f50463", |
00000502 => x"00000513", |
00000503 => x"fcdff06f", |
00000504 => x"ffff1537", |
00000505 => x"e8450513", |
00000506 => x"43c000ef", |
00000507 => x"e1dff0ef", |
00000508 => x"fc0518e3", |
00000509 => x"00300513", |
00000510 => x"fb1ff06f", |
00000511 => x"00040a37", |
00000512 => x"004a0593", |
00000513 => x"00048513", |
00000514 => x"ef9ff0ef", |
00000515 => x"00050913", |
00000516 => x"008a0593", |
00000517 => x"00048513", |
00000518 => x"ee9ff0ef", |
00000519 => x"00050a93", |
00000520 => x"fc6017f3", |
00000521 => x"00100513", |
00000522 => x"f927e0e3", |
00000523 => x"fc401bf3", |
00000524 => x"00000993", |
00000525 => x"ffc97b13", |
00000526 => x"00ca0a13", |
00000527 => x"014985b3", |
00000528 => x"053b1663", |
00000529 => x"01540433", |
00000530 => x"00200513", |
00000531 => x"f4041ee3", |
00000532 => x"ffff1537", |
00000533 => x"e9050513", |
00000534 => x"3cc000ef", |
00000535 => x"34091073", |
00000536 => x"02c12083", |
00000537 => x"02812403", |
00000538 => x"02412483", |
00000539 => x"02012903", |
00000540 => x"01c12983", |
00000541 => x"01812a03", |
00000542 => x"01412a83", |
00000543 => x"01012b03", |
00000544 => x"00c12b83", |
00000545 => x"03010113", |
00000546 => x"00008067", |
00000547 => x"00048513", |
00000548 => x"e71ff0ef", |
00000549 => x"017987b3", |
00000550 => x"00a40433", |
00000551 => x"00a7a023", |
00000552 => x"00498993", |
00000553 => x"f99ff06f", |
00000554 => x"ff010113", |
00000555 => x"00112623", |
00000556 => x"00812423", |
00000557 => x"00912223", |
00000558 => x"00058413", |
00000559 => x"00050493", |
00000560 => x"d8dff0ef", |
00000561 => x"00000513", |
00000562 => x"414000ef", |
00000563 => x"00200513", |
00000564 => x"450000ef", |
00000565 => x"00048513", |
00000566 => x"d9dff0ef", |
00000567 => x"00040513", |
00000568 => x"440000ef", |
00000569 => x"00000513", |
00000570 => x"414000ef", |
00000571 => x"cd9ff0ef", |
00000572 => x"00157513", |
00000573 => x"fe051ce3", |
00000574 => x"00c12083", |
00000575 => x"00812403", |
00000576 => x"00412483", |
00000577 => x"01010113", |
00000578 => x"00008067", |
00000579 => x"fe010113", |
00000580 => x"00812c23", |
00000581 => x"00912a23", |
00000582 => x"01212823", |
00000583 => x"00112e23", |
00000584 => x"00b12623", |
00000585 => x"00300413", |
00000586 => x"00350493", |
00000587 => x"fff00913", |
00000588 => x"00c10793", |
00000589 => x"008787b3", |
00000590 => x"0007c583", |
00000591 => x"40848533", |
00000592 => x"fff40413", |
00000593 => x"f65ff0ef", |
00000594 => x"ff2414e3", |
00000595 => x"01c12083", |
00000596 => x"01812403", |
00000597 => x"01412483", |
00000598 => x"01012903", |
00000599 => x"02010113", |
00000600 => x"00008067", |
00000601 => x"ff010113", |
00000602 => x"00112623", |
00000603 => x"00812423", |
00000604 => x"00050413", |
00000605 => x"cd9ff0ef", |
00000606 => x"00000513", |
00000607 => x"360000ef", |
00000608 => x"0d800513", |
00000609 => x"39c000ef", |
00000610 => x"00040513", |
00000611 => x"ce9ff0ef", |
00000612 => x"00000513", |
00000613 => x"368000ef", |
00000614 => x"c2dff0ef", |
00000615 => x"00157513", |
00000616 => x"fe051ce3", |
00000617 => x"00c12083", |
00000618 => x"00812403", |
00000619 => x"01010113", |
00000620 => x"00008067", |
00000621 => x"fe010113", |
00000622 => x"00112e23", |
00000623 => x"00812c23", |
00000624 => x"00912a23", |
00000625 => x"01212823", |
00000626 => x"01312623", |
00000627 => x"01412423", |
00000628 => x"01512223", |
00000629 => x"34001473", |
00000630 => x"02041863", |
00000631 => x"ffff1537", |
00000632 => x"e0c50513", |
00000633 => x"01812403", |
00000634 => x"01c12083", |
00000635 => x"01412483", |
00000636 => x"01012903", |
00000637 => x"00c12983", |
00000638 => x"00812a03", |
00000639 => x"00412a83", |
00000640 => x"02010113", |
00000641 => x"2200006f", |
00000642 => x"ffff1537", |
00000643 => x"e9450513", |
00000644 => x"214000ef", |
00000645 => x"00040513", |
00000646 => x"98dff0ef", |
00000289 => x"e6050513", |
00000290 => x"7b0000ef", |
00000291 => x"00040513", |
00000292 => x"f29ff0ef", |
00000293 => x"ffff1537", |
00000294 => x"e7050513", |
00000295 => x"79c000ef", |
00000296 => x"34102573", |
00000297 => x"f15ff0ef", |
00000298 => x"00500513", |
00000299 => x"ebdff0ef", |
00000300 => x"00000513", |
00000301 => x"095000ef", |
00000302 => x"6b0000ef", |
00000303 => x"fc1027f3", |
00000304 => x"0027d793", |
00000305 => x"00a78533", |
00000306 => x"00f537b3", |
00000307 => x"00b785b3", |
00000308 => x"6a4000ef", |
00000309 => x"03c12403", |
00000310 => x"04c12083", |
00000311 => x"04812283", |
00000312 => x"04412303", |
00000313 => x"04012383", |
00000314 => x"03812503", |
00000315 => x"03412583", |
00000316 => x"03012603", |
00000317 => x"02c12683", |
00000318 => x"02812703", |
00000319 => x"02412783", |
00000320 => x"02012803", |
00000321 => x"01c12883", |
00000322 => x"01812e03", |
00000323 => x"01412e83", |
00000324 => x"01012f03", |
00000325 => x"00c12f83", |
00000326 => x"05010113", |
00000327 => x"30200073", |
00000328 => x"fe010113", |
00000329 => x"00112e23", |
00000330 => x"00812c23", |
00000331 => x"00912a23", |
00000332 => x"01212823", |
00000333 => x"01312623", |
00000334 => x"01412423", |
00000335 => x"01512223", |
00000336 => x"f1302973", |
00000337 => x"00000a93", |
00000338 => x"00900993", |
00000339 => x"00300a13", |
00000340 => x"00400493", |
00000341 => x"41500433", |
00000342 => x"00341413", |
00000343 => x"01840413", |
00000344 => x"00895433", |
00000345 => x"0ff47413", |
00000346 => x"00000513", |
00000347 => x"0489ec63", |
00000348 => x"00050863", |
00000349 => x"03050513", |
00000350 => x"0ff57513", |
00000351 => x"69c000ef", |
00000352 => x"03040513", |
00000353 => x"0ff57513", |
00000354 => x"690000ef", |
00000355 => x"014a8663", |
00000356 => x"02e00513", |
00000357 => x"684000ef", |
00000358 => x"001a8a93", |
00000359 => x"fa9a9ce3", |
00000360 => x"01c12083", |
00000361 => x"01812403", |
00000362 => x"01412483", |
00000363 => x"01012903", |
00000364 => x"00c12983", |
00000365 => x"00812a03", |
00000366 => x"00412a83", |
00000367 => x"02010113", |
00000368 => x"00008067", |
00000369 => x"ff640413", |
00000370 => x"00150513", |
00000371 => x"0ff47413", |
00000372 => x"0ff57513", |
00000373 => x"f99ff06f", |
00000374 => x"ff010113", |
00000375 => x"00000513", |
00000376 => x"00112623", |
00000377 => x"00812423", |
00000378 => x"708000ef", |
00000379 => x"00500513", |
00000380 => x"744000ef", |
00000381 => x"00000513", |
00000382 => x"73c000ef", |
00000383 => x"00050413", |
00000384 => x"00000513", |
00000385 => x"70c000ef", |
00000386 => x"00c12083", |
00000387 => x"0ff47513", |
00000388 => x"00812403", |
00000389 => x"01010113", |
00000390 => x"00008067", |
00000391 => x"ff010113", |
00000392 => x"00000513", |
00000393 => x"00112623", |
00000394 => x"00812423", |
00000395 => x"6c4000ef", |
00000396 => x"09e00513", |
00000397 => x"700000ef", |
00000398 => x"00000513", |
00000399 => x"6f8000ef", |
00000400 => x"00050413", |
00000401 => x"00000513", |
00000402 => x"6c8000ef", |
00000403 => x"00c12083", |
00000404 => x"0ff47513", |
00000405 => x"00812403", |
00000406 => x"01010113", |
00000407 => x"00008067", |
00000408 => x"ff010113", |
00000409 => x"00000513", |
00000410 => x"00112623", |
00000411 => x"684000ef", |
00000412 => x"00600513", |
00000413 => x"6c0000ef", |
00000414 => x"00c12083", |
00000415 => x"00000513", |
00000416 => x"01010113", |
00000417 => x"68c0006f", |
00000418 => x"ff010113", |
00000419 => x"00812423", |
00000420 => x"00050413", |
00000421 => x"01055513", |
00000422 => x"0ff57513", |
00000423 => x"00112623", |
00000424 => x"694000ef", |
00000425 => x"00845513", |
00000426 => x"0ff57513", |
00000427 => x"688000ef", |
00000428 => x"0ff47513", |
00000429 => x"00812403", |
00000430 => x"00c12083", |
00000431 => x"01010113", |
00000432 => x"6740006f", |
00000433 => x"ff010113", |
00000434 => x"00812423", |
00000435 => x"00050413", |
00000436 => x"00000513", |
00000437 => x"00112623", |
00000438 => x"618000ef", |
00000439 => x"00300513", |
00000440 => x"654000ef", |
00000441 => x"00040513", |
00000442 => x"fa1ff0ef", |
00000443 => x"00000513", |
00000444 => x"644000ef", |
00000445 => x"00050413", |
00000446 => x"00000513", |
00000447 => x"614000ef", |
00000448 => x"00c12083", |
00000449 => x"0ff47513", |
00000450 => x"00812403", |
00000451 => x"01010113", |
00000452 => x"00008067", |
00000453 => x"fd010113", |
00000454 => x"02812423", |
00000455 => x"02912223", |
00000456 => x"03212023", |
00000457 => x"01312e23", |
00000458 => x"02112623", |
00000459 => x"00050493", |
00000460 => x"00300413", |
00000461 => x"00358913", |
00000462 => x"fff00993", |
00000463 => x"02049e63", |
00000464 => x"4e8000ef", |
00000465 => x"00c10793", |
00000466 => x"008787b3", |
00000467 => x"00a78023", |
00000468 => x"fff40413", |
00000469 => x"ff3414e3", |
00000470 => x"02c12083", |
00000471 => x"02812403", |
00000472 => x"00c12503", |
00000473 => x"02412483", |
00000474 => x"02012903", |
00000475 => x"01c12983", |
00000476 => x"03010113", |
00000477 => x"00008067", |
00000478 => x"40890533", |
00000479 => x"f49ff0ef", |
00000480 => x"fc5ff06f", |
00000481 => x"fd010113", |
00000482 => x"02112623", |
00000483 => x"02812423", |
00000484 => x"02912223", |
00000485 => x"03212023", |
00000486 => x"01312e23", |
00000487 => x"01412c23", |
00000488 => x"01512a23", |
00000489 => x"01612823", |
00000490 => x"01712623", |
00000491 => x"fc002473", |
00000492 => x"00847413", |
00000493 => x"00040663", |
00000494 => x"00400513", |
00000495 => x"badff0ef", |
00000496 => x"00050493", |
00000497 => x"02051863", |
00000498 => x"ffff1537", |
00000499 => x"e7850513", |
00000500 => x"468000ef", |
00000501 => x"000405b7", |
00000502 => x"00048513", |
00000503 => x"f39ff0ef", |
00000504 => x"4788d7b7", |
00000505 => x"afe78793", |
00000506 => x"02f50463", |
00000507 => x"00000513", |
00000508 => x"fcdff06f", |
00000509 => x"ffff1537", |
00000510 => x"e9850513", |
00000511 => x"43c000ef", |
00000512 => x"e1dff0ef", |
00000513 => x"fc0518e3", |
00000514 => x"00300513", |
00000515 => x"fb1ff06f", |
00000516 => x"00040a37", |
00000517 => x"004a0593", |
00000518 => x"00048513", |
00000519 => x"ef9ff0ef", |
00000520 => x"00050913", |
00000521 => x"008a0593", |
00000522 => x"00048513", |
00000523 => x"ee9ff0ef", |
00000524 => x"00050a93", |
00000525 => x"fc6027f3", |
00000526 => x"00100513", |
00000527 => x"f927e0e3", |
00000528 => x"fc402bf3", |
00000529 => x"00000993", |
00000530 => x"ffc97b13", |
00000531 => x"00ca0a13", |
00000532 => x"014985b3", |
00000533 => x"053b1663", |
00000534 => x"01540433", |
00000535 => x"00200513", |
00000536 => x"f4041ee3", |
00000537 => x"ffff1537", |
00000538 => x"ea450513", |
00000539 => x"3cc000ef", |
00000540 => x"34091073", |
00000541 => x"02c12083", |
00000542 => x"02812403", |
00000543 => x"02412483", |
00000544 => x"02012903", |
00000545 => x"01c12983", |
00000546 => x"01812a03", |
00000547 => x"01412a83", |
00000548 => x"01012b03", |
00000549 => x"00c12b83", |
00000550 => x"03010113", |
00000551 => x"00008067", |
00000552 => x"00048513", |
00000553 => x"e71ff0ef", |
00000554 => x"017987b3", |
00000555 => x"00a40433", |
00000556 => x"00a7a023", |
00000557 => x"00498993", |
00000558 => x"f99ff06f", |
00000559 => x"ff010113", |
00000560 => x"00112623", |
00000561 => x"00812423", |
00000562 => x"00912223", |
00000563 => x"00058413", |
00000564 => x"00050493", |
00000565 => x"d8dff0ef", |
00000566 => x"00000513", |
00000567 => x"414000ef", |
00000568 => x"00200513", |
00000569 => x"450000ef", |
00000570 => x"00048513", |
00000571 => x"d9dff0ef", |
00000572 => x"00040513", |
00000573 => x"440000ef", |
00000574 => x"00000513", |
00000575 => x"414000ef", |
00000576 => x"cd9ff0ef", |
00000577 => x"00157513", |
00000578 => x"fe051ce3", |
00000579 => x"00c12083", |
00000580 => x"00812403", |
00000581 => x"00412483", |
00000582 => x"01010113", |
00000583 => x"00008067", |
00000584 => x"fe010113", |
00000585 => x"00812c23", |
00000586 => x"00912a23", |
00000587 => x"01212823", |
00000588 => x"00112e23", |
00000589 => x"00b12623", |
00000590 => x"00300413", |
00000591 => x"00350493", |
00000592 => x"fff00913", |
00000593 => x"00c10793", |
00000594 => x"008787b3", |
00000595 => x"0007c583", |
00000596 => x"40848533", |
00000597 => x"fff40413", |
00000598 => x"f65ff0ef", |
00000599 => x"ff2414e3", |
00000600 => x"01c12083", |
00000601 => x"01812403", |
00000602 => x"01412483", |
00000603 => x"01012903", |
00000604 => x"02010113", |
00000605 => x"00008067", |
00000606 => x"ff010113", |
00000607 => x"00112623", |
00000608 => x"00812423", |
00000609 => x"00050413", |
00000610 => x"cd9ff0ef", |
00000611 => x"00000513", |
00000612 => x"360000ef", |
00000613 => x"0d800513", |
00000614 => x"39c000ef", |
00000615 => x"00040513", |
00000616 => x"ce9ff0ef", |
00000617 => x"00000513", |
00000618 => x"368000ef", |
00000619 => x"c2dff0ef", |
00000620 => x"00157513", |
00000621 => x"fe051ce3", |
00000622 => x"00c12083", |
00000623 => x"00812403", |
00000624 => x"01010113", |
00000625 => x"00008067", |
00000626 => x"fe010113", |
00000627 => x"00112e23", |
00000628 => x"00812c23", |
00000629 => x"00912a23", |
00000630 => x"01212823", |
00000631 => x"01312623", |
00000632 => x"01412423", |
00000633 => x"01512223", |
00000634 => x"34002473", |
00000635 => x"02041863", |
00000636 => x"ffff1537", |
00000637 => x"e2050513", |
00000638 => x"01812403", |
00000639 => x"01c12083", |
00000640 => x"01412483", |
00000641 => x"01012903", |
00000642 => x"00c12983", |
00000643 => x"00812a03", |
00000644 => x"00412a83", |
00000645 => x"02010113", |
00000646 => x"2200006f", |
00000647 => x"ffff1537", |
00000648 => x"ea050513", |
00000649 => x"200000ef", |
00000650 => x"00040537", |
00000651 => x"979ff0ef", |
00000648 => x"ea850513", |
00000649 => x"214000ef", |
00000650 => x"00040513", |
00000651 => x"98dff0ef", |
00000652 => x"ffff1537", |
00000653 => x"ebc50513", |
00000654 => x"1ec000ef", |
00000655 => x"1d8000ef", |
00000656 => x"00050493", |
00000657 => x"1c0000ef", |
00000658 => x"07900793", |
00000659 => x"0af49e63", |
00000660 => x"bb9ff0ef", |
00000661 => x"00051663", |
00000662 => x"00300513", |
00000663 => x"8f9ff0ef", |
00000664 => x"ffff1537", |
00000665 => x"ec850513", |
00000666 => x"01045493", |
00000667 => x"1b8000ef", |
00000668 => x"00148493", |
00000669 => x"00040937", |
00000670 => x"fff00993", |
00000671 => x"00010a37", |
00000672 => x"fff48493", |
00000673 => x"07349063", |
00000674 => x"4788d5b7", |
00000675 => x"afe58593", |
00000676 => x"00040537", |
00000677 => x"e79ff0ef", |
00000678 => x"00040537", |
00000679 => x"00040593", |
00000680 => x"00450513", |
00000681 => x"e69ff0ef", |
00000682 => x"fc401a73", |
00000683 => x"000409b7", |
00000684 => x"ffc47413", |
00000685 => x"00000493", |
00000686 => x"00000913", |
00000687 => x"00c98a93", |
00000688 => x"01548533", |
00000689 => x"014487b3", |
00000690 => x"02849663", |
00000691 => x"00898513", |
00000692 => x"412005b3", |
00000693 => x"e39ff0ef", |
00000694 => x"ffff1537", |
00000695 => x"e9050513", |
00000696 => x"f05ff06f", |
00000697 => x"00090513", |
00000698 => x"e7dff0ef", |
00000699 => x"01490933", |
00000700 => x"f91ff06f", |
00000701 => x"0007a583", |
00000702 => x"00448493", |
00000703 => x"00b90933", |
00000704 => x"e0dff0ef", |
00000705 => x"fbdff06f", |
00000706 => x"01c12083", |
00000707 => x"01812403", |
00000708 => x"01412483", |
00000709 => x"01012903", |
00000710 => x"00c12983", |
00000711 => x"00812a03", |
00000712 => x"00412a83", |
00000713 => x"02010113", |
00000714 => x"00008067", |
00000715 => x"000047b7", |
00000716 => x"70078793", |
00000717 => x"f8f02623", |
00000718 => x"00008067", |
00000719 => x"fc000713", |
00000720 => x"00072783", |
00000721 => x"00179793", |
00000722 => x"0017d793", |
00000723 => x"00f72023", |
00000724 => x"00008067", |
00000725 => x"f9002503", |
00000726 => x"f9402583", |
00000727 => x"00008067", |
00000728 => x"f9800693", |
00000729 => x"fff00613", |
00000730 => x"00c6a023", |
00000731 => x"00a6a023", |
00000732 => x"00b6a223", |
00000733 => x"00008067", |
00000734 => x"fa002023", |
00000735 => x"fc1016f3", |
00000736 => x"00000713", |
00000737 => x"00151513", |
00000738 => x"04a6f263", |
00000739 => x"000016b7", |
00000740 => x"00000793", |
00000741 => x"ffe68693", |
00000742 => x"04e6e463", |
00000743 => x"00167613", |
00000744 => x"0015f593", |
00000745 => x"01879793", |
00000746 => x"01e61613", |
00000747 => x"00c7e7b3", |
00000748 => x"01d59593", |
00000749 => x"00b7e7b3", |
00000750 => x"00e7e7b3", |
00000751 => x"10000737", |
00000752 => x"00e7e7b3", |
00000753 => x"faf02023", |
00000754 => x"00008067", |
00000755 => x"00170793", |
00000756 => x"01079713", |
00000757 => x"40a686b3", |
00000758 => x"01075713", |
00000759 => x"fadff06f", |
00000760 => x"ffe78513", |
00000761 => x"0fd57513", |
00000762 => x"00051a63", |
00000763 => x"00375713", |
00000764 => x"00178793", |
00000765 => x"0ff7f793", |
00000766 => x"fa1ff06f", |
00000767 => x"00175713", |
00000768 => x"ff1ff06f", |
00000769 => x"fa002783", |
00000770 => x"fe07cee3", |
00000771 => x"faa02223", |
00000772 => x"00008067", |
00000773 => x"fa402503", |
00000774 => x"fe055ee3", |
00000775 => x"0ff57513", |
00000776 => x"00008067", |
00000777 => x"ff010113", |
00000778 => x"00812423", |
00000779 => x"01212023", |
00000780 => x"00112623", |
00000781 => x"00912223", |
00000782 => x"00050413", |
00000783 => x"00a00913", |
00000784 => x"00044483", |
00000785 => x"00140413", |
00000786 => x"00049e63", |
00000787 => x"00c12083", |
00000788 => x"00812403", |
00000789 => x"00412483", |
00000790 => x"00012903", |
00000791 => x"01010113", |
00000792 => x"00008067", |
00000793 => x"01249663", |
00000794 => x"00d00513", |
00000795 => x"f99ff0ef", |
00000796 => x"00048513", |
00000797 => x"f91ff0ef", |
00000798 => x"fc9ff06f", |
00000799 => x"00757513", |
00000800 => x"00177793", |
00000801 => x"01079793", |
00000802 => x"0036f693", |
00000803 => x"00a51513", |
00000804 => x"00f56533", |
00000805 => x"00167613", |
00000806 => x"00e69793", |
00000807 => x"0015f593", |
00000808 => x"00f567b3", |
00000809 => x"00d61613", |
00000810 => x"00c7e7b3", |
00000811 => x"00959593", |
00000812 => x"fa800813", |
00000813 => x"00b7e7b3", |
00000814 => x"00082023", |
00000815 => x"1007e793", |
00000816 => x"00f82023", |
00000817 => x"00008067", |
00000818 => x"fa800713", |
00000819 => x"00072783", |
00000820 => x"eff7f793", |
00000821 => x"00f72023", |
00000653 => x"eb450513", |
00000654 => x"200000ef", |
00000655 => x"00040537", |
00000656 => x"979ff0ef", |
00000657 => x"ffff1537", |
00000658 => x"ed050513", |
00000659 => x"1ec000ef", |
00000660 => x"1d8000ef", |
00000661 => x"00050493", |
00000662 => x"1c0000ef", |
00000663 => x"07900793", |
00000664 => x"0af49e63", |
00000665 => x"bb9ff0ef", |
00000666 => x"00051663", |
00000667 => x"00300513", |
00000668 => x"8f9ff0ef", |
00000669 => x"ffff1537", |
00000670 => x"edc50513", |
00000671 => x"01045493", |
00000672 => x"1b8000ef", |
00000673 => x"00148493", |
00000674 => x"00040937", |
00000675 => x"fff00993", |
00000676 => x"00010a37", |
00000677 => x"fff48493", |
00000678 => x"07349063", |
00000679 => x"4788d5b7", |
00000680 => x"afe58593", |
00000681 => x"00040537", |
00000682 => x"e79ff0ef", |
00000683 => x"00040537", |
00000684 => x"00040593", |
00000685 => x"00450513", |
00000686 => x"e69ff0ef", |
00000687 => x"fc402a73", |
00000688 => x"000409b7", |
00000689 => x"ffc47413", |
00000690 => x"00000493", |
00000691 => x"00000913", |
00000692 => x"00c98a93", |
00000693 => x"01548533", |
00000694 => x"014487b3", |
00000695 => x"02849663", |
00000696 => x"00898513", |
00000697 => x"412005b3", |
00000698 => x"e39ff0ef", |
00000699 => x"ffff1537", |
00000700 => x"ea450513", |
00000701 => x"f05ff06f", |
00000702 => x"00090513", |
00000703 => x"e7dff0ef", |
00000704 => x"01490933", |
00000705 => x"f91ff06f", |
00000706 => x"0007a583", |
00000707 => x"00448493", |
00000708 => x"00b90933", |
00000709 => x"e0dff0ef", |
00000710 => x"fbdff06f", |
00000711 => x"01c12083", |
00000712 => x"01812403", |
00000713 => x"01412483", |
00000714 => x"01012903", |
00000715 => x"00c12983", |
00000716 => x"00812a03", |
00000717 => x"00412a83", |
00000718 => x"02010113", |
00000719 => x"00008067", |
00000720 => x"000047b7", |
00000721 => x"70078793", |
00000722 => x"f8f02623", |
00000723 => x"00008067", |
00000724 => x"fc000713", |
00000725 => x"00072783", |
00000726 => x"00179793", |
00000727 => x"0017d793", |
00000728 => x"00f72023", |
00000729 => x"00008067", |
00000730 => x"f9002503", |
00000731 => x"f9402583", |
00000732 => x"00008067", |
00000733 => x"f9800693", |
00000734 => x"fff00613", |
00000735 => x"00c6a023", |
00000736 => x"00a6a023", |
00000737 => x"00b6a223", |
00000738 => x"00008067", |
00000739 => x"fa002023", |
00000740 => x"fc1026f3", |
00000741 => x"00000713", |
00000742 => x"00151513", |
00000743 => x"04a6f263", |
00000744 => x"000016b7", |
00000745 => x"00000793", |
00000746 => x"ffe68693", |
00000747 => x"04e6e463", |
00000748 => x"00167613", |
00000749 => x"0015f593", |
00000750 => x"01879793", |
00000751 => x"01e61613", |
00000752 => x"00c7e7b3", |
00000753 => x"01d59593", |
00000754 => x"00b7e7b3", |
00000755 => x"00e7e7b3", |
00000756 => x"10000737", |
00000757 => x"00e7e7b3", |
00000758 => x"faf02023", |
00000759 => x"00008067", |
00000760 => x"00170793", |
00000761 => x"01079713", |
00000762 => x"40a686b3", |
00000763 => x"01075713", |
00000764 => x"fadff06f", |
00000765 => x"ffe78513", |
00000766 => x"0fd57513", |
00000767 => x"00051a63", |
00000768 => x"00375713", |
00000769 => x"00178793", |
00000770 => x"0ff7f793", |
00000771 => x"fa1ff06f", |
00000772 => x"00175713", |
00000773 => x"ff1ff06f", |
00000774 => x"fa002783", |
00000775 => x"fe07cee3", |
00000776 => x"faa02223", |
00000777 => x"00008067", |
00000778 => x"fa402503", |
00000779 => x"fe055ee3", |
00000780 => x"0ff57513", |
00000781 => x"00008067", |
00000782 => x"ff010113", |
00000783 => x"00812423", |
00000784 => x"01212023", |
00000785 => x"00112623", |
00000786 => x"00912223", |
00000787 => x"00050413", |
00000788 => x"00a00913", |
00000789 => x"00044483", |
00000790 => x"00140413", |
00000791 => x"00049e63", |
00000792 => x"00c12083", |
00000793 => x"00812403", |
00000794 => x"00412483", |
00000795 => x"00012903", |
00000796 => x"01010113", |
00000797 => x"00008067", |
00000798 => x"01249663", |
00000799 => x"00d00513", |
00000800 => x"f99ff0ef", |
00000801 => x"00048513", |
00000802 => x"f91ff0ef", |
00000803 => x"fc9ff06f", |
00000804 => x"00757513", |
00000805 => x"00177793", |
00000806 => x"01079793", |
00000807 => x"0036f693", |
00000808 => x"00a51513", |
00000809 => x"00f56533", |
00000810 => x"00167613", |
00000811 => x"00e69793", |
00000812 => x"0015f593", |
00000813 => x"00f567b3", |
00000814 => x"00d61613", |
00000815 => x"00c7e7b3", |
00000816 => x"00959593", |
00000817 => x"fa800813", |
00000818 => x"00b7e7b3", |
00000819 => x"00082023", |
00000820 => x"1007e793", |
00000821 => x"00f82023", |
00000822 => x"00008067", |
00000823 => x"fa800713", |
00000824 => x"00072683", |
00000825 => x"00757793", |
00000826 => x"00100513", |
00000827 => x"00f51533", |
00000828 => x"00d56533", |
00000829 => x"00a72023", |
00000830 => x"00008067", |
00000831 => x"fa800713", |
00000832 => x"00072683", |
00000833 => x"00757513", |
00000834 => x"00100793", |
00000835 => x"00a797b3", |
00000836 => x"fff7c793", |
00000837 => x"00d7f7b3", |
00000838 => x"00f72023", |
00000839 => x"00008067", |
00000840 => x"faa02623", |
00000841 => x"fa802783", |
00000842 => x"fe07cee3", |
00000843 => x"fac02503", |
00000824 => x"00072783", |
00000825 => x"eff7f793", |
00000826 => x"00f72023", |
00000827 => x"00008067", |
00000828 => x"fa800713", |
00000829 => x"00072683", |
00000830 => x"00757793", |
00000831 => x"00100513", |
00000832 => x"00f51533", |
00000833 => x"00d56533", |
00000834 => x"00a72023", |
00000835 => x"00008067", |
00000836 => x"fa800713", |
00000837 => x"00072683", |
00000838 => x"00757513", |
00000839 => x"00100793", |
00000840 => x"00a797b3", |
00000841 => x"fff7c793", |
00000842 => x"00d7f7b3", |
00000843 => x"00f72023", |
00000844 => x"00008067", |
00000845 => x"f8400713", |
00000846 => x"00072683", |
00000847 => x"00f57793", |
00000848 => x"00100513", |
00000849 => x"00f51533", |
00000850 => x"00d54533", |
00000851 => x"00a72023", |
00000852 => x"00008067", |
00000853 => x"f8a02223", |
00000854 => x"00008067", |
00000855 => x"fb800713", |
00000856 => x"00072783", |
00000857 => x"ffe7f793", |
00000858 => x"00f72023", |
00000845 => x"faa02623", |
00000846 => x"fa802783", |
00000847 => x"fe07cee3", |
00000848 => x"fac02503", |
00000849 => x"00008067", |
00000850 => x"f8400713", |
00000851 => x"00072683", |
00000852 => x"00f57793", |
00000853 => x"00100513", |
00000854 => x"00f51533", |
00000855 => x"00d54533", |
00000856 => x"00a72023", |
00000857 => x"00008067", |
00000858 => x"f8a02223", |
00000859 => x"00008067", |
00000860 => x"30046073", |
00000861 => x"00008067", |
00000862 => x"30047073", |
00000863 => x"00008067", |
00000864 => x"fb000713", |
00000865 => x"00072783", |
00000866 => x"ff77f793", |
00000867 => x"00f72023", |
00000860 => x"fb800713", |
00000861 => x"00072783", |
00000862 => x"ffe7f793", |
00000863 => x"00f72023", |
00000864 => x"00008067", |
00000865 => x"30046073", |
00000866 => x"00008067", |
00000867 => x"30047073", |
00000868 => x"00008067", |
00000869 => x"f8800713", |
00000869 => x"fb000713", |
00000870 => x"00072783", |
00000871 => x"fef7f793", |
00000871 => x"ff77f793", |
00000872 => x"00f72023", |
00000873 => x"00008067", |
00000874 => x"69617641", |
00000875 => x"6c62616c", |
00000876 => x"4d432065", |
00000877 => x"0a3a7344", |
00000878 => x"203a6820", |
00000879 => x"706c6548", |
00000880 => x"3a72200a", |
00000881 => x"73655220", |
00000882 => x"74726174", |
00000883 => x"3a75200a", |
00000884 => x"6c705520", |
00000885 => x"0a64616f", |
00000886 => x"203a7320", |
00000887 => x"726f7453", |
00000888 => x"6f742065", |
00000889 => x"616c6620", |
00000890 => x"200a6873", |
00000891 => x"4c203a6c", |
00000892 => x"2064616f", |
00000893 => x"6d6f7266", |
00000874 => x"f8800713", |
00000875 => x"00072783", |
00000876 => x"fef7f793", |
00000877 => x"00f72023", |
00000878 => x"00008067", |
00000879 => x"69617641", |
00000880 => x"6c62616c", |
00000881 => x"4d432065", |
00000882 => x"0a3a7344", |
00000883 => x"203a6820", |
00000884 => x"706c6548", |
00000885 => x"3a72200a", |
00000886 => x"73655220", |
00000887 => x"74726174", |
00000888 => x"3a75200a", |
00000889 => x"6c705520", |
00000890 => x"0a64616f", |
00000891 => x"203a7320", |
00000892 => x"726f7453", |
00000893 => x"6f742065", |
00000894 => x"616c6620", |
00000895 => x"200a6873", |
00000896 => x"45203a65", |
00000897 => x"75636578", |
00000898 => x"00006574", |
00000899 => x"65206f4e", |
00000900 => x"75636578", |
00000901 => x"6c626174", |
00000902 => x"76612065", |
00000903 => x"616c6961", |
00000904 => x"2e656c62", |
00000905 => x"00000000", |
00000906 => x"746f6f42", |
00000907 => x"2e676e69", |
00000908 => x"0a0a2e2e", |
00000909 => x"00000000", |
00000910 => x"52450a07", |
00000911 => x"00005f52", |
00000912 => x"6e6b6e75", |
00000913 => x"006e776f", |
00000914 => x"00007830", |
00000915 => x"58450a0a", |
00000916 => x"54504543", |
00000917 => x"3a4e4f49", |
00000918 => x"00000020", |
00000919 => x"30204020", |
00000920 => x"00000078", |
00000921 => x"69617741", |
00000922 => x"676e6974", |
00000923 => x"6f656e20", |
00000924 => x"32337672", |
00000925 => x"6578655f", |
00000926 => x"6e69622e", |
00000927 => x"202e2e2e", |
00000928 => x"00000000", |
00000929 => x"64616f4c", |
00000930 => x"2e676e69", |
00000931 => x"00202e2e", |
00000932 => x"00004b4f", |
00000933 => x"74697257", |
00000934 => x"78302065", |
00000935 => x"00000000", |
00000936 => x"74796220", |
00000937 => x"74207365", |
00000938 => x"5053206f", |
00000939 => x"6c662049", |
00000940 => x"20687361", |
00000941 => x"78302040", |
00000942 => x"00000000", |
00000943 => x"7928203f", |
00000944 => x"20296e2f", |
00000945 => x"00000000", |
00000946 => x"616c460a", |
00000947 => x"6e696873", |
00000948 => x"2e2e2e67", |
00000949 => x"00000020", |
00000950 => x"0a0a0a0a", |
00000951 => x"4e203c3c", |
00000952 => x"56524f45", |
00000953 => x"42203233", |
00000954 => x"6c746f6f", |
00000955 => x"6564616f", |
00000956 => x"3e3e2072", |
00000957 => x"4c420a0a", |
00000958 => x"203a5644", |
00000959 => x"206e754a", |
00000960 => x"32203732", |
00000961 => x"0a303230", |
00000962 => x"3a565748", |
00000963 => x"00002020", |
00000964 => x"4b4c430a", |
00000965 => x"0020203a", |
00000966 => x"0a7a4820", |
00000967 => x"4153494d", |
00000968 => x"0000203a", |
00000969 => x"4e4f430a", |
00000970 => x"00203a46", |
00000971 => x"454d490a", |
00000972 => x"00203a4d", |
00000973 => x"74796220", |
00000974 => x"40207365", |
00000975 => x"00000020", |
00000976 => x"454d440a", |
00000977 => x"00203a4d", |
00000978 => x"75410a0a", |
00000979 => x"6f626f74", |
00000980 => x"6920746f", |
00000981 => x"3828206e", |
00000982 => x"202e7329", |
00000983 => x"73657250", |
00000984 => x"656b2073", |
00000985 => x"6f742079", |
00000986 => x"6f626120", |
00000987 => x"0a2e7472", |
00000988 => x"00000000", |
00000989 => x"0000000a", |
00000990 => x"726f6241", |
00000991 => x"2e646574", |
00000992 => x"00000a0a", |
00000993 => x"444d430a", |
00000994 => x"00203e3a", |
00000995 => x"53207962", |
00000996 => x"68706574", |
00000997 => x"4e206e61", |
00000998 => x"69746c6f", |
00000999 => x"0000676e", |
00001000 => x"61766e49", |
00001001 => x"2064696c", |
00001002 => x"00444d43", |
00001003 => x"33323130", |
00001004 => x"37363534", |
00001005 => x"42413938", |
00001006 => x"46454443", |
00000896 => x"4c203a6c", |
00000897 => x"2064616f", |
00000898 => x"6d6f7266", |
00000899 => x"616c6620", |
00000900 => x"200a6873", |
00000901 => x"45203a65", |
00000902 => x"75636578", |
00000903 => x"00006574", |
00000904 => x"65206f4e", |
00000905 => x"75636578", |
00000906 => x"6c626174", |
00000907 => x"76612065", |
00000908 => x"616c6961", |
00000909 => x"2e656c62", |
00000910 => x"00000000", |
00000911 => x"746f6f42", |
00000912 => x"2e676e69", |
00000913 => x"0a0a2e2e", |
00000914 => x"00000000", |
00000915 => x"52450a07", |
00000916 => x"00005f52", |
00000917 => x"6e6b6e75", |
00000918 => x"006e776f", |
00000919 => x"00007830", |
00000920 => x"58450a0a", |
00000921 => x"54504543", |
00000922 => x"3a4e4f49", |
00000923 => x"00000020", |
00000924 => x"30204020", |
00000925 => x"00000078", |
00000926 => x"69617741", |
00000927 => x"676e6974", |
00000928 => x"6f656e20", |
00000929 => x"32337672", |
00000930 => x"6578655f", |
00000931 => x"6e69622e", |
00000932 => x"202e2e2e", |
00000933 => x"00000000", |
00000934 => x"64616f4c", |
00000935 => x"2e676e69", |
00000936 => x"00202e2e", |
00000937 => x"00004b4f", |
00000938 => x"74697257", |
00000939 => x"78302065", |
00000940 => x"00000000", |
00000941 => x"74796220", |
00000942 => x"74207365", |
00000943 => x"5053206f", |
00000944 => x"6c662049", |
00000945 => x"20687361", |
00000946 => x"78302040", |
00000947 => x"00000000", |
00000948 => x"7928203f", |
00000949 => x"20296e2f", |
00000950 => x"00000000", |
00000951 => x"616c460a", |
00000952 => x"6e696873", |
00000953 => x"2e2e2e67", |
00000954 => x"00000020", |
00000955 => x"0a0a0a0a", |
00000956 => x"4e203c3c", |
00000957 => x"56524f45", |
00000958 => x"42203233", |
00000959 => x"6c746f6f", |
00000960 => x"6564616f", |
00000961 => x"3e3e2072", |
00000962 => x"4c420a0a", |
00000963 => x"203a5644", |
00000964 => x"206c754a", |
00000965 => x"32203520", |
00000966 => x"0a303230", |
00000967 => x"3a565748", |
00000968 => x"00002020", |
00000969 => x"4b4c430a", |
00000970 => x"0020203a", |
00000971 => x"0a7a4820", |
00000972 => x"4449484d", |
00000973 => x"0000203a", |
00000974 => x"53494d0a", |
00000975 => x"00203a41", |
00000976 => x"4e4f430a", |
00000977 => x"00203a46", |
00000978 => x"454d490a", |
00000979 => x"00203a4d", |
00000980 => x"74796220", |
00000981 => x"40207365", |
00000982 => x"00000020", |
00000983 => x"454d440a", |
00000984 => x"00203a4d", |
00000985 => x"75410a0a", |
00000986 => x"6f626f74", |
00000987 => x"6920746f", |
00000988 => x"3828206e", |
00000989 => x"202e7329", |
00000990 => x"73657250", |
00000991 => x"656b2073", |
00000992 => x"6f742079", |
00000993 => x"6f626120", |
00000994 => x"0a2e7472", |
00000995 => x"00000000", |
00000996 => x"0000000a", |
00000997 => x"726f6241", |
00000998 => x"2e646574", |
00000999 => x"00000a0a", |
00001000 => x"444d430a", |
00001001 => x"00203e3a", |
00001002 => x"53207962", |
00001003 => x"68706574", |
00001004 => x"4e206e61", |
00001005 => x"69746c6f", |
00001006 => x"0000676e", |
00001007 => x"61766e49", |
00001008 => x"2064696c", |
00001009 => x"00444d43", |
00001010 => x"33323130", |
00001011 => x"37363534", |
00001012 => x"42413938", |
00001013 => x"46454443", |
others => x"00000000" |
); |
|
/rtl/core/neorv32_cpu.vhd
53,6 → 53,7
CLOCK_FREQUENCY : natural := 0; -- clock frequency of clk_i in Hz |
HART_ID : std_ulogic_vector(31 downto 0) := x"00000000"; -- custom hardware thread ID |
BOOTLOADER_USE : boolean := true; -- implement processor-internal bootloader? |
CSR_COUNTERS_USE : boolean := true; -- implement RISC-V perf. counters ([m]instret[h], [m]cycle[h], time[h])? |
-- RISC-V CPU Extensions -- |
CPU_EXTENSION_RISCV_C : boolean := false; -- implement compressed extension? |
CPU_EXTENSION_RISCV_E : boolean := false; -- implement embedded RF extension? |
109,8 → 110,6
signal ctrl : std_ulogic_vector(ctrl_width_c-1 downto 0); -- main control bus |
signal alu_cmp : std_ulogic_vector(1 downto 0); -- alu comparator result |
signal imm : std_ulogic_vector(data_width_c-1 downto 0); -- immediate |
signal pc : std_ulogic_vector(data_width_c-1 downto 0); -- current program counter |
signal pc_delayed : std_ulogic_vector(data_width_c-1 downto 0); -- delayed program counter |
signal instr : std_ulogic_vector(data_width_c-1 downto 0); -- new instruction |
signal rs1, rs2 : std_ulogic_vector(data_width_c-1 downto 0); -- source registers |
signal alu_res : std_ulogic_vector(data_width_c-1 downto 0); -- alu result |
127,6 → 126,10
signal be_load : std_ulogic; -- bus error on load data access |
signal be_store : std_ulogic; -- bus error on store data access |
signal bus_exc_ack : std_ulogic; -- bus exception error acknowledge |
signal bus_busy : std_ulogic; -- bus unit is busy |
signal fetch_pc : std_ulogic_vector(data_width_c-1 downto 0); -- pc for instruction fetch |
signal curr_pc : std_ulogic_vector(data_width_c-1 downto 0); -- current pc (for current executed instruction) |
signal next_pc : std_ulogic_vector(data_width_c-1 downto 0); -- next pc (for current executed instruction) |
|
-- co-processor interface -- |
signal cp0_data, cp1_data : std_ulogic_vector(data_width_c-1 downto 0); |
139,9 → 142,10
neorv32_cpu_control_inst: neorv32_cpu_control |
generic map ( |
-- General -- |
CLOCK_FREQUENCY => CLOCK_FREQUENCY, -- clock frequency of clk_i in Hz |
HART_ID => HART_ID, -- custom hardware thread ID |
BOOTLOADER_USE => BOOTLOADER_USE, -- implement processor-internal bootloader? |
CLOCK_FREQUENCY => CLOCK_FREQUENCY, -- clock frequency of clk_i in Hz |
HART_ID => HART_ID, -- custom hardware thread ID |
BOOTLOADER_USE => BOOTLOADER_USE, -- implement processor-internal bootloader? |
CSR_COUNTERS_USE => CSR_COUNTERS_USE, -- implement RISC-V perf. counters ([m]instret[h], [m]cycle[h], time[h])? |
-- RISC-V CPU Extensions -- |
CPU_EXTENSION_RISCV_C => CPU_EXTENSION_RISCV_C, -- implement compressed extension? |
CPU_EXTENSION_RISCV_E => CPU_EXTENSION_RISCV_E, -- implement embedded RF extension? |
186,8 → 190,9
alu_add_i => alu_add, -- ALU.add result |
-- data output -- |
imm_o => imm, -- immediate |
pc_o => pc, -- current PC |
alu_pc_o => pc_delayed, -- delayed PC for ALU |
fetch_pc_o => fetch_pc, -- PC for instruction fetch |
curr_pc_o => curr_pc, -- current PC (corresponding to current instruction) |
next_pc_o => next_pc, -- next PC (corresponding to current instruction) |
-- csr interface -- |
csr_wdata_i => alu_res, -- CSR write data |
csr_rdata_o => csr_rdata, -- CSR read data |
202,7 → 207,8
be_instr_i => be_instr, -- bus error on instruction access |
be_load_i => be_load, -- bus error on load data access |
be_store_i => be_store, -- bus error on store data access |
bus_exc_ack_o => bus_exc_ack -- bus exception error acknowledge |
bus_exc_ack_o => bus_exc_ack, -- bus exception error acknowledge |
bus_busy_i => bus_busy -- bus unit is busy |
); |
|
|
220,7 → 226,7
mem_i => rdata, -- memory read data |
alu_i => alu_res, -- ALU result |
csr_i => csr_rdata, -- CSR read data |
pc_i => pc, -- current pc |
pc_i => next_pc, -- next pc |
-- data output -- |
rs1_o => rs1, -- operand 1 |
rs2_o => rs2 -- operand 2 |
230,10 → 236,6
-- ALU ------------------------------------------------------------------------------------ |
-- ------------------------------------------------------------------------------------------- |
neorv32_cpu_alu_inst: neorv32_cpu_alu |
generic map ( |
CPU_EXTENSION_RISCV_C => CPU_EXTENSION_RISCV_C, -- implement compressed extension? |
CPU_EXTENSION_RISCV_M => CPU_EXTENSION_RISCV_M -- implement mul/div extension? |
) |
port map ( |
-- global control -- |
clk_i => clk_i, -- global clock, rising edge |
242,8 → 244,7
-- data input -- |
rs1_i => rs1, -- rf source 1 |
rs2_i => rs2, -- rf source 2 |
pc_i => pc, -- current PC |
pc2_i => pc_delayed, -- delayed PC |
pc2_i => curr_pc, -- delayed PC |
imm_i => imm, -- immediate |
csr_i => csr_rdata, -- csr read data |
-- data output -- |
296,8 → 297,7
-- ------------------------------------------------------------------------------------------- |
neorv32_cpu_bus_inst: neorv32_cpu_bus |
generic map ( |
CPU_EXTENSION_RISCV_C => CPU_EXTENSION_RISCV_C, -- implement compressed extension? |
MEM_EXT_TIMEOUT => MEM_EXT_TIMEOUT -- cycles after which a valid bus access will timeout |
MEM_EXT_TIMEOUT => MEM_EXT_TIMEOUT -- cycles after which a valid bus access will timeout |
) |
port map ( |
-- global control -- |
306,7 → 306,7
ctrl_i => ctrl, -- main control bus |
-- data input -- |
wdata_i => rs2, -- write data |
pc_i => pc, -- current PC |
pc_i => fetch_pc, -- current PC for instruction fetch |
alu_i => alu_res, -- ALU result |
-- data output -- |
instr_o => instr, -- instruction |
320,6 → 320,7
be_load_o => be_load, -- bus error on load data access |
be_store_o => be_store, -- bus error on store data access |
bus_wait_o => bus_wait, -- wait for bus operation to finish |
bus_busy_o => bus_busy, -- bus unit is busy |
exc_ack_i => bus_exc_ack, -- exception controller ACK |
-- bus system -- |
bus_addr_o => bus_addr_o, -- bus access address |
/rtl/core/neorv32_cpu_alu.vhd
42,10 → 42,6
use neorv32.neorv32_package.all; |
|
entity neorv32_cpu_alu is |
generic ( |
CPU_EXTENSION_RISCV_C : boolean := false; -- implement compressed extension? |
CPU_EXTENSION_RISCV_M : boolean := false -- implement mul/div extension? |
); |
port ( |
-- global control -- |
clk_i : in std_ulogic; -- global clock, rising edge |
54,7 → 50,6
-- data input -- |
rs1_i : in std_ulogic_vector(data_width_c-1 downto 0); -- rf source 1 |
rs2_i : in std_ulogic_vector(data_width_c-1 downto 0); -- rf source 2 |
pc_i : in std_ulogic_vector(data_width_c-1 downto 0); -- current PC |
pc2_i : in std_ulogic_vector(data_width_c-1 downto 0); -- delayed PC |
imm_i : in std_ulogic_vector(data_width_c-1 downto 0); -- immediate |
csr_i : in std_ulogic_vector(data_width_c-1 downto 0); -- csr read data |
75,7 → 70,7
architecture neorv32_cpu_cpu_rtl of neorv32_cpu_alu is |
|
-- operands -- |
signal opa, opb, opc, pc_inc : std_ulogic_vector(data_width_c-1 downto 0); |
signal opa, opb, opc : std_ulogic_vector(data_width_c-1 downto 0); |
|
-- results -- |
signal add_res : std_ulogic_vector(data_width_c-1 downto 0); |
109,22 → 104,28
|
-- Operand Mux ---------------------------------------------------------------------------- |
-- ------------------------------------------------------------------------------------------- |
input_op_mux: process(ctrl_i, csr_i, pc2_i, pc_i, rs1_i, rs2_i, imm_i, pc_inc) |
input_op_mux: process(ctrl_i, csr_i, pc2_i, rs1_i, rs2_i, imm_i) |
begin |
-- opa (first ALU input operand) -- |
case ctrl_i(ctrl_alu_opa_mux_msb_c downto ctrl_alu_opa_mux_lsb_c) is |
when "00" => opa <= rs1_i; |
when "01" => opa <= pc2_i; |
when "10" => opa <= csr_i; |
when others => opa <= pc_i; |
end case; |
if (ctrl_i(ctrl_alu_opa_mux_msb_c) = '0') then |
if (ctrl_i(ctrl_alu_opa_mux_lsb_c) = '0') then |
opa <= rs1_i; |
else |
opa <= pc2_i; |
end if; |
else |
opa <= csr_i; |
end if; |
-- opb (second ALU input operand) -- |
case ctrl_i(ctrl_alu_opb_mux_msb_c downto ctrl_alu_opb_mux_lsb_c) is |
when "00" => opb <= rs2_i; |
when "01" => opb <= imm_i; |
when "10" => opb <= rs1_i; |
when others => opb <= pc_inc; |
end case; |
if (ctrl_i(ctrl_alu_opb_mux_msb_c) = '0') then |
if (ctrl_i(ctrl_alu_opb_mux_lsb_c) = '0') then |
opb <= rs2_i; |
else |
opb <= imm_i; |
end if; |
else |
opb <= rs1_i; |
end if; |
-- opc (second operand for comparison (and SUB)) -- |
if (ctrl_i(ctrl_alu_opc_mux_c) = '0') then |
opc <= imm_i; |
133,10 → 134,7
end if; |
end process input_op_mux; |
|
-- PC increment -- |
pc_inc <= x"00000002" when (CPU_EXTENSION_RISCV_C = true) else x"00000004"; |
|
|
-- Comparator Unit ------------------------------------------------------------------------ |
-- ------------------------------------------------------------------------------------------- |
-- less than (x < y) -- |
202,7 → 200,7
cp_rb_ff0 <= '0'; |
cp_rb_ff1 <= '0'; |
elsif rising_edge(clk_i) then |
if (CPU_EXTENSION_RISCV_M = true) then |
if (ctrl_i(ctrl_sys_m_ext_en_c) = '1') then |
cp_cmd_ff <= ctrl_i(ctrl_cp_use_c); |
cp_rb_ff0 <= '0'; |
cp_rb_ff1 <= cp_rb_ff0; |
/rtl/core/neorv32_cpu_bus.vhd
43,8 → 43,7
|
entity neorv32_cpu_bus is |
generic ( |
CPU_EXTENSION_RISCV_C : boolean := false; -- implement compressed extension? |
MEM_EXT_TIMEOUT : natural := 15 -- cycles after which a valid bus access will timeout |
MEM_EXT_TIMEOUT : natural := 15 -- cycles after which a valid bus access will timeout |
); |
port ( |
-- global control -- |
67,6 → 66,7
be_load_o : out std_ulogic; -- bus error on load data access |
be_store_o : out std_ulogic; -- bus error on store data access |
bus_wait_o : out std_ulogic; -- wait for bus operation to finish |
bus_busy_o : out std_ulogic; -- bus unit is busy |
exc_ack_i : in std_ulogic; -- exception controller ACK |
-- bus system -- |
bus_addr_o : out std_ulogic_vector(data_width_c-1 downto 0); -- bus access address |
113,7 → 113,7
end process mem_adr_reg; |
|
-- address output -- |
bus_addr_o <= pc_i when (ctrl_i(ctrl_bus_if_c) = '1') else mar; -- is instruction fetch? |
bus_addr_o <= pc_i when ((bus_if_req or ctrl_i(ctrl_bus_if_c)) = '1') else mar; -- is instruction fetch? |
mar_o <= mar; |
|
-- write request output -- |
120,7 → 120,7
bus_we_o <= ctrl_i(ctrl_bus_wr_c) and (not misaligned_data); |
|
-- read request output (also used for instruction fetch) -- |
bus_re_o <= (ctrl_i(ctrl_bus_rd_c) and (not misaligned_data)) or (ctrl_i(ctrl_bus_if_c) and (not misaligned_instr)); |
bus_re_o <= (ctrl_i(ctrl_bus_rd_c) and (not misaligned_data)) or ((bus_if_req or ctrl_i(ctrl_bus_if_c)) and (not misaligned_instr)); |
|
|
-- Write Data ----------------------------------------------------------------------------- |
263,6 → 263,7
ma_store_o <= bus_wr_req and align_err; |
|
-- wait for bus -- |
bus_busy_o <= bus_busy; |
bus_wait_o <= bus_busy and (not bus_ack_i); -- FIXME: 'async' ack |
|
|
290,11 → 291,9
begin |
-- check instruction access -- |
misaligned_instr <= '0'; -- default |
if (CPU_EXTENSION_RISCV_C = true) then -- 16-bit instruction access only |
if (pc_i(0) /= '0') then |
misaligned_instr <= '1'; |
end if; |
else -- 32-bit instruction access only |
if (ctrl_i(ctrl_sys_c_ext_en_c) = '1') then -- 16-bit and 32-bit instruction accesses |
misaligned_instr <= '0'; |
else -- 32-bit instruction accesses only |
if (pc_i(1 downto 0) /= "00") then |
misaligned_instr <= '1'; |
end if; |
/rtl/core/neorv32_cpu_control.vhd
1,8 → 1,9
-- ################################################################################################# |
-- # << NEORV32 - CPU Control >> # |
-- # ********************************************************************************************* # |
-- # FSM to control CPU operations. This unit also includes the control and status registers (CSR) # |
-- # and the interrupt and exception controller. # |
-- # CPU operation is split into a fetch engine (responsible for fetching an decompressing instr- # |
-- # uctions), an execute engine (responsible for actually executing the instructions), an inter- # |
-- # rupt and exception handling controller and the RISC-V status and control registers (CSRs). # |
-- # ********************************************************************************************* # |
-- # BSD 3-Clause License # |
-- # # |
48,6 → 49,7
CLOCK_FREQUENCY : natural := 0; -- clock frequency of clk_i in Hz |
HART_ID : std_ulogic_vector(31 downto 0) := x"00000000"; -- custom hardware thread ID |
BOOTLOADER_USE : boolean := true; -- implement processor-internal bootloader? |
CSR_COUNTERS_USE : boolean := true; -- implement RISC-V perf. counters ([m]instret[h], [m]cycle[h], time[h])? |
-- RISC-V CPU Extensions -- |
CPU_EXTENSION_RISCV_C : boolean := false; -- implement compressed extension? |
CPU_EXTENSION_RISCV_E : boolean := false; -- implement embedded RF extension? |
92,8 → 94,9
alu_add_i : in std_ulogic_vector(data_width_c-1 downto 0); -- ALU.add result |
-- data output -- |
imm_o : out std_ulogic_vector(data_width_c-1 downto 0); -- immediate |
pc_o : out std_ulogic_vector(data_width_c-1 downto 0); -- current PC |
alu_pc_o : out std_ulogic_vector(data_width_c-1 downto 0); -- delayed PC for ALU |
fetch_pc_o : out std_ulogic_vector(data_width_c-1 downto 0); -- PC for instruction fetch |
curr_pc_o : out std_ulogic_vector(data_width_c-1 downto 0); -- current PC (corresponding to current instruction) |
next_pc_o : out std_ulogic_vector(data_width_c-1 downto 0); -- next PC (corresponding to current instruction) |
-- csr data interface -- |
csr_wdata_i : in std_ulogic_vector(data_width_c-1 downto 0); -- CSR write data |
csr_rdata_o : out std_ulogic_vector(data_width_c-1 downto 0); -- CSR read data |
108,90 → 111,151
be_instr_i : in std_ulogic; -- bus error on instruction access |
be_load_i : in std_ulogic; -- bus error on load data access |
be_store_i : in std_ulogic; -- bus error on store data access |
bus_exc_ack_o : out std_ulogic -- bus exception error acknowledge |
bus_exc_ack_o : out std_ulogic; -- bus exception error acknowledge |
bus_busy_i : in std_ulogic -- bus unit is busy |
); |
end neorv32_cpu_control; |
|
architecture neorv32_cpu_control_rtl of neorv32_cpu_control is |
|
-- state machine -- |
type state_t is (IFETCH_0, IFETCH_1, IFETCH_2, IFETCH_3, IFETCH_4, IFETCH_5, IFETCH_6, EXECUTE, |
ALU_WAIT, STORE_0, LOAD_0, LOADSTORE_0, LOADSTORE_1, CSR_ACCESS, SLEEP); |
signal state, state_nxt : state_t; |
signal ctrl_nxt, ctrl : std_ulogic_vector(ctrl_width_c-1 downto 0); |
signal hw_control : std_ulogic_vector(data_width_c-1 downto 0); |
-- instruction fetch enginge -- |
type fetch_engine_state_t is (IFETCH_RESET, IFETCH_0, IFETCH_1, IFETCH_2, IFETCH_3); |
type fetch_engine_t is record |
state : fetch_engine_state_t; |
state_nxt : fetch_engine_state_t; |
i_buf : std_ulogic_vector(33 downto 0); |
i_buf_nxt : std_ulogic_vector(33 downto 0); |
i_buf2 : std_ulogic_vector(33 downto 0); |
i_buf2_nxt : std_ulogic_vector(33 downto 0); |
ci_reg : std_ulogic_vector(17 downto 0); |
ci_reg_nxt : std_ulogic_vector(17 downto 0); |
i_buf_state : std_ulogic_vector(01 downto 0); |
i_buf_state_nxt : std_ulogic_vector(01 downto 0); |
pc_real : std_ulogic_vector(data_width_c-1 downto 0); |
pc_real_add : std_ulogic_vector(data_width_c-1 downto 0); |
pc_fetch : std_ulogic_vector(data_width_c-1 downto 0); |
pc_fetch_add : std_ulogic_vector(data_width_c-1 downto 0); |
ci_return : std_ulogic; |
ci_return_nxt : std_ulogic; |
reset : std_ulogic; |
bus_err_ack : std_ulogic; |
end record; |
signal fetch_engine : fetch_engine_t; |
|
-- pre-decoder -- |
signal ci_instr32 : std_ulogic_vector(31 downto 0); |
signal ci_valid : std_ulogic; |
signal ci_illegal : std_ulogic; |
|
-- instruction register -- |
signal i_reg, i_reg_nxt : std_ulogic_vector(31 downto 0); |
signal i_buf, i_buf_nxt : std_ulogic_vector(15 downto 0); |
signal ci_reg, ci_reg_nxt : std_ulogic_vector(15 downto 0); |
signal iavail, iavail_nxt : std_ulogic; |
signal is_ci, is_ci_nxt : std_ulogic; -- current instruction is COMPRESSED instruction flag |
-- instrucion prefetch buffer (IPB) -- |
type ipb_t is record |
wdata : std_ulogic_vector(34 downto 0); |
rdata : std_ulogic_vector(34 downto 0); |
waddr : std_ulogic_vector(31 downto 0); |
raddr : std_ulogic_vector(31 downto 0); |
status : std_ulogic; |
free : std_ulogic; |
avail : std_ulogic; |
we : std_ulogic; |
re : std_ulogic; |
clear : std_ulogic; |
end record; |
signal ipb : ipb_t; |
|
-- immediates -- |
signal imm_reg : std_ulogic_vector(data_width_c-1 downto 0); |
-- instruction execution engine -- |
type execute_engine_state_t is (IDLE, DISPATCH, TRAP, EXECUTE, ALU_WAIT, BRANCH, STORE, LOAD, LOADSTORE_0, LOADSTORE_1, CSR_ACCESS); |
type execute_engine_t is record |
state : execute_engine_state_t; |
state_nxt : execute_engine_state_t; |
state_prev : execute_engine_state_t; |
i_reg : std_ulogic_vector(31 downto 0); |
i_reg_nxt : std_ulogic_vector(31 downto 0); |
is_ci : std_ulogic; -- current instruction is de-compressed instruction |
is_ci_nxt : std_ulogic; |
is_jump : std_ulogic; -- current instruction is jump instruction |
is_jump_nxt : std_ulogic; |
branch_taken : std_ulogic; -- branch condition fullfilled |
pc : std_ulogic_vector(data_width_c-1 downto 0); -- actual PC, corresponding to current executed instruction |
pc_nxt : std_ulogic_vector(data_width_c-1 downto 0); |
next_pc : std_ulogic_vector(data_width_c-1 downto 0); -- next PC, corresponding to next instruction to be executed |
last_pc : std_ulogic_vector(data_width_c-1 downto 0); -- PC of last executed instruction |
end record; |
signal execute_engine : execute_engine_t; |
|
-- branch system -- |
signal is_branch : std_ulogic; |
signal is_branch_nxt : std_ulogic; |
signal branch_taken : std_ulogic; |
-- trap controller -- |
type trap_ctrl_t is record |
exc_buf : std_ulogic_vector(exception_width_c-1 downto 0); |
exc_fire : std_ulogic; -- set if there is a valid source in the exception buffer |
irq_buf : std_ulogic_vector(interrupt_width_c-1 downto 0); |
irq_fire : std_ulogic; -- set if there is a valid source in the interrupt buffer |
exc_ack : std_ulogic; -- acknowledge all exceptions |
irq_ack : std_ulogic_vector(interrupt_width_c-1 downto 0); -- acknowledge specific interrupt |
irq_ack_nxt : std_ulogic_vector(interrupt_width_c-1 downto 0); |
cause : std_ulogic_vector(data_width_c-1 downto 0); -- trap ID (for "mcause") |
cause_nxt : std_ulogic_vector(data_width_c-1 downto 0); |
instr : std_ulogic_vector(31 downto 0); -- faulting instruction |
exc_src : std_ulogic_vector(exception_width_c-1 downto 0); |
-- |
env_start : std_ulogic; -- start trap handler env |
env_start_ack : std_ulogic; -- start of trap handler acknowledged |
env_end : std_ulogic; -- end trap handler env |
-- |
instr_be : std_ulogic; -- instruction fetch bus error |
instr_ma : std_ulogic; -- instruction fetch misaligned address |
instr_il : std_ulogic; -- illegal instruction |
env_call : std_ulogic; |
break_point : std_ulogic; |
end record; |
signal trap_ctrl : trap_ctrl_t; |
|
-- CPU control signals -- |
signal ctrl_nxt, ctrl : std_ulogic_vector(ctrl_width_c-1 downto 0); |
|
-- program counter -- |
signal pc_reg : std_ulogic_vector(data_width_c-1 downto 0); -- actual PC |
signal pc_backup_reg : std_ulogic_vector(data_width_c-1 downto 0); -- delayed PC (for ALU operations) |
signal pc_backup2_reg : std_ulogic_vector(data_width_c-1 downto 0); -- delayed delayed PC (for exception handling) |
signal mepc : std_ulogic_vector(data_width_c-1 downto 0); -- exception PC |
-- fast bus access -- |
signal bus_fast_ir : std_ulogic; |
signal bus_fast_rd : std_ulogic; |
signal bus_fast_wr : std_ulogic; |
|
-- irq controller -- |
signal exc_buf : std_ulogic_vector(exception_width_c-1 downto 0); |
signal exc_ack : std_ulogic; |
signal exc_src : std_ulogic_vector(exception_width_c-1 downto 0); |
signal exc_fire : std_ulogic; |
signal irq_buf : std_ulogic_vector(interrupt_width_c-1 downto 0); |
signal irq_ack : std_ulogic_vector(interrupt_width_c-1 downto 0); |
signal irq_ack_nxt : std_ulogic_vector(interrupt_width_c-1 downto 0); |
signal irq_fire : std_ulogic; |
signal exc_cpu_start : std_ulogic; -- starting exception env |
signal exc_cpu_ack : std_ulogic; -- starting of exception env acknowledge |
signal exc_cpu_end : std_ulogic; -- exiting eception env |
signal exc_cause : std_ulogic_vector(data_width_c-1 downto 0); |
signal exc_cause_nxt : std_ulogic_vector(data_width_c-1 downto 0); |
-- RISC-V control and status registers (CSRs) -- |
type csr_t is record |
we : std_ulogic; -- write enable |
we_nxt : std_ulogic; |
re : std_ulogic; -- read enable |
re_nxt : std_ulogic; |
mstatus_mie : std_ulogic; -- mstatus.MIE: global IRQ enable (R/W) |
mstatus_mpie : std_ulogic; -- mstatus.MPIE: previous global IRQ enable (R/-) |
mip_msip : std_ulogic; -- mip.MSIP: machine software interrupt pending (R/W) |
mie_msie : std_ulogic; -- mie.MSIE: machine software interrupt enable (R/W) |
mie_meie : std_ulogic; -- mie.MEIE: machine external interrupt enable (R/W) |
mie_mtie : std_ulogic; -- mie.MEIE: machine timer interrupt enable (R/W) |
mepc : std_ulogic_vector(data_width_c-1 downto 0); -- mepc: machine exception pc (R/W) |
mcause : std_ulogic_vector(data_width_c-1 downto 0); -- mcause: machine trap cause (R/-) |
mtvec : std_ulogic_vector(data_width_c-1 downto 0); -- mtvec: machine trap-handler base address (R/W) |
mtval : std_ulogic_vector(data_width_c-1 downto 0); -- mtval: machine bad address or isntruction (R/-) |
mscratch : std_ulogic_vector(data_width_c-1 downto 0); -- mscratch: scratch register (R/W) |
mtinst : std_ulogic_vector(data_width_c-1 downto 0); -- mtinst: machine trap instruction (transformed) (R/-) |
cycle : std_ulogic_vector(32 downto 0); -- cycle, mtime (R/-), plus carry bit |
instret : std_ulogic_vector(32 downto 0); -- instret (R/-), plus carry bit |
cycleh : std_ulogic_vector(31 downto 0); -- cycleh, mtimeh (R/-) |
instreth : std_ulogic_vector(31 downto 0); -- instreth (R/-) |
misa_c_en : std_ulogic; -- misa: C extension enable bit (R/W) |
misa_m_en : std_ulogic; -- misa: M extension enable bit (R/W) |
end record; |
signal csr : csr_t; |
|
-- RISC-V CSRs -- |
signal mstatus_mie : std_ulogic; -- mstatus.MIE: global IRQ enable (R/W) |
signal mstatus_mpie : std_ulogic; -- mstatus.MPIE: previous global IRQ enable (R/-) |
signal mip_msip : std_ulogic; -- mip.MSIP: machine software interrupt pending (R/W) |
signal mie_msie : std_ulogic; -- mie.MSIE: machine software interrupt enable (R/W) |
signal mie_meie : std_ulogic; -- mie.MEIE: machine external interrupt enable (R/W) |
signal mie_mtie : std_ulogic; -- mie.MEIE: machine timer interrupt enable (R/W) |
signal mtvec : std_ulogic_vector(data_width_c-1 downto 0); -- mtvec: machine trap-handler base address (R/W) |
signal mtval : std_ulogic_vector(data_width_c-1 downto 0); -- mtval: machine bad address or isntruction (R/-) |
signal mscratch : std_ulogic_vector(data_width_c-1 downto 0); -- mscratch: scratch register (R/W) |
signal mtinst : std_ulogic_vector(data_width_c-1 downto 0); -- mtinst: machine trap instruction (transformed) (R/-) |
signal cycle_lo : std_ulogic_vector(32 downto 0); -- cycle, mtime (R/-) |
signal instret_lo : std_ulogic_vector(32 downto 0); -- instret (R/-) |
signal cycle_hi : std_ulogic_vector(15 downto 0); -- cycleh, mtimeh (R/-) - only 16-bit wide |
signal instret_hi : std_ulogic_vector(15 downto 0); -- instreth (R/-) - only 16-bit wide |
signal cycle_lo_msb : std_ulogic; |
signal instret_lo_msb : std_ulogic; |
signal cycle_msb : std_ulogic; |
signal instret_msb : std_ulogic; |
|
-- illegal instruction check .. |
-- illegal instruction check -- |
signal illegal_instruction : std_ulogic; |
signal illegal_register : std_ulogic; -- only for E-extension |
signal illegal_compressed : std_ulogic; -- only fir C-extension |
|
-- synchronous exceptions trigger -- |
signal illegal_instr_exc : std_ulogic; |
signal env_call : std_ulogic; |
signal break_point : std_ulogic; |
|
begin |
|
-- **************************************************************************************************************************** |
-- Instruction Fetch |
-- **************************************************************************************************************************** |
|
-- Compressed Instructions Recoding ------------------------------------------------------- |
-- ------------------------------------------------------------------------------------------- |
neorv32_cpu_decompressor_inst_true: |
199,9 → 263,8
neorv32_cpu_decompressor_inst: neorv32_cpu_decompressor |
port map ( |
-- instruction input -- |
ci_instr16_i => ci_reg, -- compressed instruction input |
ci_instr16_i => fetch_engine.ci_reg(15 downto 0), -- compressed instruction input |
-- instruction output -- |
ci_valid_o => ci_valid, -- is a compressed instruction |
ci_illegal_o => ci_illegal, -- is an illegal compressed instruction |
ci_instr32_o => ci_instr32 -- 32-bit decompressed instruction |
); |
209,290 → 272,460
|
neorv32_cpu_decompressor_inst_false: |
if (CPU_EXTENSION_RISCV_C = false) generate |
ci_instr32 <= instr_i; |
ci_valid <= '0'; |
ci_instr32 <= (others => '0'); |
ci_illegal <= '0'; |
end generate; |
|
|
-- Fetch Engine FSM Sync ------------------------------------------------------------------ |
-- ------------------------------------------------------------------------------------------- |
-- for registers that require a specific reset state -- |
fetch_engine_fsm_sync_rst: process(rstn_i, clk_i) |
begin |
if (rstn_i = '0') then |
fetch_engine.state <= IFETCH_RESET; |
elsif rising_edge(clk_i) then |
if (fetch_engine.reset = '1') then |
fetch_engine.state <= IFETCH_RESET; |
else |
fetch_engine.state <= fetch_engine.state_nxt; |
end if; |
end if; |
end process fetch_engine_fsm_sync_rst; |
|
|
-- for registers that DO NOT require a specific reset state -- |
fetch_engine_fsm_sync: process(clk_i) |
begin |
if rising_edge(clk_i) then |
if (fetch_engine.state = IFETCH_RESET) then |
fetch_engine.pc_fetch <= execute_engine.pc(data_width_c-1 downto 1) & '0'; -- initialize with "real" application PC |
fetch_engine.pc_real <= execute_engine.pc(data_width_c-1 downto 1) & '0'; -- initialize with "real" application PC |
else |
fetch_engine.pc_real <= std_ulogic_vector(unsigned(fetch_engine.pc_real(data_width_c-1 downto 1) & '0') + unsigned(fetch_engine.pc_real_add(data_width_c-1 downto 1) & '0')); |
fetch_engine.pc_fetch <= std_ulogic_vector(unsigned(fetch_engine.pc_fetch(data_width_c-1 downto 1) & '0') + unsigned(fetch_engine.pc_fetch_add(data_width_c-1 downto 1) & '0')); |
end if; |
-- |
fetch_engine.i_buf <= fetch_engine.i_buf_nxt; |
fetch_engine.i_buf2 <= fetch_engine.i_buf2_nxt; |
fetch_engine.i_buf_state <= fetch_engine.i_buf_state_nxt; |
-- |
fetch_engine.ci_reg <= fetch_engine.ci_reg_nxt; |
fetch_engine.ci_return <= fetch_engine.ci_return_nxt; |
end if; |
end process fetch_engine_fsm_sync; |
|
|
-- Fetch Engine FSM Comb ------------------------------------------------------------------ |
-- ------------------------------------------------------------------------------------------- |
fetch_engine_fsm_comb: process(fetch_engine, execute_engine, csr, ipb, instr_i, bus_wait_i, bus_busy_i, ci_instr32, be_instr_i, ma_instr_i) |
begin |
-- arbiter defaults -- |
fetch_engine.state_nxt <= fetch_engine.state; |
fetch_engine.pc_fetch_add <= (others => '0'); |
fetch_engine.pc_real_add <= (others => '0'); |
bus_fast_ir <= '0'; |
fetch_engine.i_buf_nxt <= fetch_engine.i_buf; |
fetch_engine.i_buf2_nxt <= fetch_engine.i_buf2; |
fetch_engine.i_buf_state_nxt <= fetch_engine.i_buf_state; |
fetch_engine.ci_reg_nxt <= fetch_engine.ci_reg; |
fetch_engine.ci_return_nxt <= fetch_engine.ci_return; |
fetch_engine.bus_err_ack <= '0'; |
|
-- instruction prefetch buffer interface -- |
ipb.we <= '0'; |
ipb.clear <= '0'; |
ipb.wdata <= fetch_engine.i_buf2(33 downto 32) & '0' & fetch_engine.i_buf2(31 downto 0); |
ipb.waddr <= fetch_engine.pc_real(data_width_c-1 downto 1) & '0'; |
|
-- state machine -- |
case fetch_engine.state is |
|
when IFETCH_RESET => -- reset engine, prefetch buffer, get PC |
-- ------------------------------------------------------------ |
fetch_engine.i_buf_state_nxt <= (others => '0'); |
fetch_engine.ci_return_nxt <= '0'; |
ipb.clear <= '1'; -- clear instruction prefetch buffer |
fetch_engine.bus_err_ack <= '1'; -- ack bus errors, the execute engine has to take care of them |
fetch_engine.state_nxt <= IFETCH_0; |
|
when IFETCH_0 => -- output current PC to bus system, request 32-bit word |
-- ------------------------------------------------------------ |
if (bus_busy_i = '0') and (execute_engine.state /= LOAD) and (execute_engine.state /= STORE) and |
(execute_engine.state /= LOADSTORE_0) and (execute_engine.state /= LOADSTORE_1) then -- wait if execute engine is using bus unit |
bus_fast_ir <= '1'; -- fast instruction fetch request (output PC to bus.address) |
fetch_engine.state_nxt <= IFETCH_1; |
end if; |
|
when IFETCH_1 => -- store data from memory to buffer(s) |
-- ------------------------------------------------------------ |
fetch_engine.i_buf_nxt <= be_instr_i & ma_instr_i & instr_i(31 downto 0); -- store data word and exception info |
if (bus_wait_i = '0') then -- wait for bus response |
fetch_engine.i_buf2_nxt <= fetch_engine.i_buf; |
fetch_engine.i_buf_state_nxt(1) <= fetch_engine.i_buf_state(0); |
fetch_engine.state_nxt <= IFETCH_2; |
end if; |
|
fetch_engine.i_buf_state_nxt(0) <= '1'; |
if (be_instr_i = '1') or (ma_instr_i = '1') then -- any fetch exception? |
fetch_engine.bus_err_ack <= '1'; -- ack bus errors, the execute engine has to take care of them |
end if; |
|
when IFETCH_2 => -- construct instruction and issue |
-- ------------------------------------------------------------ |
if (fetch_engine.i_buf_state(1) = '1') then |
if (fetch_engine.pc_fetch(1) = '0') or (CPU_EXTENSION_RISCV_C = false) or (csr.misa_c_en = '0') then -- 32-bit aligned |
fetch_engine.ci_reg_nxt <= fetch_engine.i_buf2(33 downto 32) & fetch_engine.i_buf2(15 downto 00); |
ipb.wdata <= fetch_engine.i_buf2(33 downto 32) & '0' & fetch_engine.i_buf2(31 downto 0); |
|
if (fetch_engine.i_buf2(01 downto 00) = "11") or (CPU_EXTENSION_RISCV_C = false) or (csr.misa_c_en = '0') then -- uncompressed |
if (ipb.free = '1') then -- free entry in buffer? |
ipb.we <= '1'; |
fetch_engine.pc_real_add <= std_ulogic_vector(to_unsigned(4, data_width_c)); |
fetch_engine.pc_fetch_add <= std_ulogic_vector(to_unsigned(4, data_width_c)); |
fetch_engine.state_nxt <= IFETCH_0; |
end if; |
|
else -- compressed |
fetch_engine.pc_fetch_add <= std_ulogic_vector(to_unsigned(2, data_width_c)); |
fetch_engine.ci_return_nxt <= '1'; -- come back here after issueing |
fetch_engine.state_nxt <= IFETCH_3; |
end if; |
|
else -- 16-bit aligned |
fetch_engine.ci_reg_nxt <= fetch_engine.i_buf2(33 downto 32) & fetch_engine.i_buf2(31 downto 16); |
ipb.wdata <= fetch_engine.i_buf(33 downto 32) & '0' & fetch_engine.i_buf(15 downto 00) & fetch_engine.i_buf2(31 downto 16); |
|
if (fetch_engine.i_buf2(17 downto 16) = "11") then -- uncompressed |
if (ipb.free = '1') then -- free entry in buffer? |
ipb.we <= '1'; |
fetch_engine.pc_real_add <= std_ulogic_vector(to_unsigned(4, data_width_c)); |
fetch_engine.pc_fetch_add <= std_ulogic_vector(to_unsigned(4, data_width_c)); |
fetch_engine.state_nxt <= IFETCH_0; |
end if; |
|
else -- compressed |
fetch_engine.pc_fetch_add <= std_ulogic_vector(to_unsigned(2, data_width_c)); |
fetch_engine.ci_return_nxt <= '0'; -- start next fetch after issueing |
fetch_engine.state_nxt <= IFETCH_3; |
end if; |
end if; |
else |
fetch_engine.pc_fetch_add <= std_ulogic_vector(to_unsigned(4, data_width_c)); |
fetch_engine.state_nxt <= IFETCH_0; |
end if; |
|
when IFETCH_3 => -- additional cycle for issueing decompressed instructions |
-- ------------------------------------------------------------ |
if (ipb.free = '1') then -- free entry in buffer? |
ipb.we <= '1'; |
ipb.wdata <= fetch_engine.ci_reg(17 downto 16) & '1' & ci_instr32; |
fetch_engine.pc_real_add <= std_ulogic_vector(to_unsigned(2, data_width_c)); |
if (fetch_engine.ci_return = '0') then |
fetch_engine.state_nxt <= IFETCH_0; |
else |
fetch_engine.state_nxt <= IFETCH_2; |
end if; |
end if; |
|
when others => -- undefined |
-- ------------------------------------------------------------ |
fetch_engine.state_nxt <= IFETCH_RESET; |
|
end case; |
end process fetch_engine_fsm_comb; |
|
|
-- **************************************************************************************************************************** |
-- Instruction Prefetch Buffer |
-- **************************************************************************************************************************** |
|
|
-- Instruction Prefetch Buffer Stage ------------------------------------------------------ |
-- ------------------------------------------------------------------------------------------- |
instr_prefetch_buffer: process(rstn_i, clk_i) |
begin |
if (rstn_i = '0') then |
ipb.status <= '0'; |
ipb.rdata <= (others => '0'); |
ipb.raddr <= (others => '0'); |
elsif rising_edge(clk_i) then |
if (ipb.clear = '1') then |
ipb.status <= '0'; |
elsif (ipb.we = '1') then |
ipb.status <= '1'; |
elsif (ipb.re = '1') then |
ipb.status <= '0'; |
end if; |
if (ipb.we = '1') then |
ipb.rdata <= ipb.wdata; |
ipb.raddr <= ipb.waddr; |
end if; |
end if; |
end process instr_prefetch_buffer; |
|
-- status -- |
ipb.free <= not ipb.status; |
ipb.avail <= ipb.status; |
|
|
-- **************************************************************************************************************************** |
-- Instruction Execution |
-- **************************************************************************************************************************** |
|
|
-- Immediate Generator -------------------------------------------------------------------- |
-- ------------------------------------------------------------------------------------------- |
imm_gen: process(clk_i) |
begin |
if rising_edge(clk_i) then |
-- default: I-immediate -- |
imm_reg(31 downto 11) <= (others => i_reg(31)); -- sign extension |
imm_reg(10 downto 05) <= i_reg(30 downto 25); |
imm_reg(04 downto 01) <= i_reg(24 downto 21); |
imm_reg(00) <= i_reg(20); |
case i_reg(instr_opcode_msb_c downto instr_opcode_lsb_c) is |
case execute_engine.i_reg(instr_opcode_msb_c downto instr_opcode_lsb_c) is |
when opcode_store_c => -- S-immediate |
imm_reg(31 downto 11) <= (others => i_reg(31)); -- sign extension |
imm_reg(10 downto 05) <= i_reg(30 downto 25); |
imm_reg(04 downto 01) <= i_reg(11 downto 08); |
imm_reg(00) <= i_reg(07); |
imm_o(31 downto 11) <= (others => execute_engine.i_reg(31)); -- sign extension |
imm_o(10 downto 05) <= execute_engine.i_reg(30 downto 25); |
imm_o(04 downto 01) <= execute_engine.i_reg(11 downto 08); |
imm_o(00) <= execute_engine.i_reg(07); |
when opcode_branch_c => -- B-immediate |
imm_reg(31 downto 12) <= (others => i_reg(31)); -- sign extension |
imm_reg(11) <= i_reg(07); |
imm_reg(10 downto 05) <= i_reg(30 downto 25); |
imm_reg(04 downto 01) <= i_reg(11 downto 08); |
imm_reg(00) <= '0'; |
imm_o(31 downto 12) <= (others => execute_engine.i_reg(31)); -- sign extension |
imm_o(11) <= execute_engine.i_reg(07); |
imm_o(10 downto 05) <= execute_engine.i_reg(30 downto 25); |
imm_o(04 downto 01) <= execute_engine.i_reg(11 downto 08); |
imm_o(00) <= '0'; |
when opcode_lui_c | opcode_auipc_c => -- U-immediate |
imm_reg(31 downto 20) <= i_reg(31 downto 20); |
imm_reg(19 downto 12) <= i_reg(19 downto 12); |
imm_reg(11 downto 00) <= (others => '0'); |
imm_o(31 downto 20) <= execute_engine.i_reg(31 downto 20); |
imm_o(19 downto 12) <= execute_engine.i_reg(19 downto 12); |
imm_o(11 downto 00) <= (others => '0'); |
when opcode_jal_c => -- J-immediate |
imm_reg(31 downto 20) <= (others => i_reg(31)); -- sign extension |
imm_reg(19 downto 12) <= i_reg(19 downto 12); |
imm_reg(11) <= i_reg(20); |
imm_reg(10 downto 05) <= i_reg(30 downto 25); |
imm_reg(04 downto 01) <= i_reg(24 downto 21); |
imm_reg(00) <= '0'; |
imm_o(31 downto 20) <= (others => execute_engine.i_reg(31)); -- sign extension |
imm_o(19 downto 12) <= execute_engine.i_reg(19 downto 12); |
imm_o(11) <= execute_engine.i_reg(20); |
imm_o(10 downto 05) <= execute_engine.i_reg(30 downto 25); |
imm_o(04 downto 01) <= execute_engine.i_reg(24 downto 21); |
imm_o(00) <= '0'; |
when opcode_syscsr_c => -- CSR-immediate |
imm_reg(31 downto 05) <= (others => '0'); |
imm_reg(04 downto 00) <= i_reg(19 downto 15); |
imm_o(31 downto 05) <= (others => '0'); |
imm_o(04 downto 00) <= execute_engine.i_reg(19 downto 15); |
when others => -- I-immediate |
imm_reg(31 downto 11) <= (others => i_reg(31)); -- sign extension |
imm_reg(10 downto 05) <= i_reg(30 downto 25); |
imm_reg(04 downto 01) <= i_reg(24 downto 21); |
imm_reg(00) <= i_reg(20); |
imm_o(31 downto 11) <= (others => execute_engine.i_reg(31)); -- sign extension |
imm_o(10 downto 05) <= execute_engine.i_reg(30 downto 25); |
imm_o(04 downto 01) <= execute_engine.i_reg(24 downto 21); |
imm_o(00) <= execute_engine.i_reg(20); |
end case; |
end if; |
end process imm_gen; |
|
-- output -- |
imm_o <= imm_reg; |
|
|
-- Branch Condition Check ----------------------------------------------------------------- |
-- ------------------------------------------------------------------------------------------- |
branch_check: process(i_reg, cmp_i) |
branch_check: process(execute_engine.i_reg, cmp_i) |
begin |
case i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) is |
case execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) is |
when funct3_beq_c => -- branch if equal |
branch_taken <= cmp_i(alu_cmp_equal_c); |
execute_engine.branch_taken <= cmp_i(alu_cmp_equal_c); |
when funct3_bne_c => -- branch if not equal |
branch_taken <= not cmp_i(alu_cmp_equal_c); |
execute_engine.branch_taken <= not cmp_i(alu_cmp_equal_c); |
when funct3_blt_c | funct3_bltu_c => -- branch if less (signed/unsigned) |
branch_taken <= cmp_i(alu_cmp_less_c); |
execute_engine.branch_taken <= cmp_i(alu_cmp_less_c); |
when funct3_bge_c | funct3_bgeu_c => -- branch if greater or equal (signed/unsigned) |
branch_taken <= not cmp_i(alu_cmp_less_c); |
execute_engine.branch_taken <= not cmp_i(alu_cmp_less_c); |
when others => -- undefined |
branch_taken <= '0'; |
execute_engine.branch_taken <= '0'; |
end case; |
end process branch_check; |
|
|
-- Arbiter State Machine Sync ------------------------------------------------------------- |
-- Execute Engine FSM Sync ---------------------------------------------------------------- |
-- ------------------------------------------------------------------------------------------- |
arbiter_sync_rst: process(rstn_i, clk_i) |
-- for registers that require a specific reset state -- |
execute_engine_fsm_sync_rst: process(rstn_i, clk_i) |
begin |
if (rstn_i = '0') then |
-- these registers REQUIRE a specific reset state |
state <= IFETCH_0; |
if (BOOTLOADER_USE = true) then -- boot from bootloader ROM |
execute_engine.pc <= boot_base_c(data_width_c-1 downto 1) & '0'; |
execute_engine.last_pc <= boot_base_c(data_width_c-1 downto 1) & '0'; |
else -- boot from IMEM |
execute_engine.pc <= MEM_ISPACE_BASE(data_width_c-1 downto 1) & '0'; |
execute_engine.last_pc <= MEM_ISPACE_BASE(data_width_c-1 downto 1) & '0'; |
end if; |
execute_engine.state <= IDLE; |
execute_engine.state_prev <= IDLE; |
elsif rising_edge(clk_i) then |
state <= state_nxt; |
execute_engine.pc <= execute_engine.pc_nxt(data_width_c-1 downto 1) & '0'; |
if (execute_engine.state = EXECUTE) then |
execute_engine.last_pc <= execute_engine.pc(data_width_c-1 downto 1) & '0'; |
end if; |
execute_engine.state <= execute_engine.state_nxt; |
execute_engine.state_prev <= execute_engine.state; |
end if; |
end process arbiter_sync_rst; |
end process execute_engine_fsm_sync_rst; |
|
arbiter_sync: process(clk_i) |
|
-- for registers that DO NOT require a specific reset state -- |
execute_engine_fsm_sync: process(clk_i) |
begin |
if rising_edge(clk_i) then |
-- these registers do not need a specific reset state |
ctrl <= ctrl_nxt; |
i_reg <= i_reg_nxt; |
i_buf <= i_buf_nxt; |
ci_reg <= ci_reg_nxt; |
iavail <= iavail_nxt; |
is_ci <= is_ci_nxt; |
is_branch <= is_branch_nxt; |
execute_engine.i_reg <= execute_engine.i_reg_nxt; |
execute_engine.is_ci <= execute_engine.is_ci_nxt; |
execute_engine.is_jump <= execute_engine.is_jump_nxt; |
-- control signals -- |
ctrl <= ctrl_nxt; |
end if; |
end process arbiter_sync; |
end process execute_engine_fsm_sync; |
|
-- control bus output -- |
ctrl_outpu: process(ctrl, i_reg) |
|
-- PC output -- |
execute_engine.next_pc <= std_ulogic_vector(unsigned(execute_engine.pc(data_width_c-1 downto 1) & '0') + 2) when (execute_engine.is_ci = '1') else |
std_ulogic_vector(unsigned(execute_engine.pc(data_width_c-1 downto 1) & '0') + 4); |
fetch_pc_o <= fetch_engine.pc_fetch(data_width_c-1 downto 1) & '0'; |
curr_pc_o <= execute_engine.pc(data_width_c-1 downto 1) & '0'; |
next_pc_o <= execute_engine.next_pc(data_width_c-1 downto 1) & '0'; |
|
|
-- CPU Control Bus Output ----------------------------------------------------------------- |
-- ------------------------------------------------------------------------------------------- |
ctrl_output: process(ctrl, execute_engine, csr, bus_fast_ir, bus_fast_rd, bus_fast_wr) |
begin |
ctrl_o <= ctrl; |
-- direct output of register addresses -- |
ctrl_o(ctrl_rf_rd_adr4_c downto ctrl_rf_rd_adr0_c) <= i_reg(instr_rd_msb_c downto instr_rd_lsb_c); |
ctrl_o(ctrl_rf_rs1_adr4_c downto ctrl_rf_rs1_adr0_c) <= i_reg(instr_rs1_msb_c downto instr_rs1_lsb_c); |
ctrl_o(ctrl_rf_rs2_adr4_c downto ctrl_rf_rs2_adr0_c) <= i_reg(instr_rs2_msb_c downto instr_rs2_lsb_c); |
end process ctrl_outpu; |
ctrl_o(ctrl_rf_rd_adr4_c downto ctrl_rf_rd_adr0_c) <= execute_engine.i_reg(instr_rd_msb_c downto instr_rd_lsb_c); |
ctrl_o(ctrl_rf_rs1_adr4_c downto ctrl_rf_rs1_adr0_c) <= execute_engine.i_reg(instr_rs1_msb_c downto instr_rs1_lsb_c); |
ctrl_o(ctrl_rf_rs2_adr4_c downto ctrl_rf_rs2_adr0_c) <= execute_engine.i_reg(instr_rs2_msb_c downto instr_rs2_lsb_c); |
-- bus access requests -- |
ctrl_o(ctrl_bus_if_c) <= ctrl(ctrl_bus_if_c) or bus_fast_ir; |
ctrl_o(ctrl_bus_rd_c) <= ctrl(ctrl_bus_rd_c) or bus_fast_rd; |
ctrl_o(ctrl_bus_wr_c) <= ctrl(ctrl_bus_wr_c) or bus_fast_wr; |
-- cpu extension control -- |
ctrl_o(ctrl_sys_c_ext_en_c) <= csr.misa_c_en; -- C extension enabled |
ctrl_o(ctrl_sys_m_ext_en_c) <= csr.misa_m_en; -- M extension enabled |
end process ctrl_output; |
|
|
-- Arbiter State Machine Comb ----------------------------------------------- |
-- ----------------------------------------------------------------------------- |
arbiter_comb: process(state, ctrl, i_reg, alu_wait_i, bus_wait_i, exc_cpu_start, ma_load_i, be_load_i, ma_store_i, be_store_i, |
ci_reg, i_buf, instr_i, is_ci, iavail, pc_backup_reg, ci_valid, ci_instr32) |
-- Execute Engine FSM Comb ---------------------------------------------------------------- |
-- ------------------------------------------------------------------------------------------- |
execute_engine_fsm_comb: process(execute_engine, fetch_engine, ipb, trap_ctrl, csr, ctrl, |
alu_add_i, alu_wait_i, bus_wait_i, ma_load_i, be_load_i, ma_store_i, be_store_i) |
variable alu_immediate_v : std_ulogic; |
variable alu_operation_v : std_ulogic_vector(2 downto 0); |
variable rd_is_r0_v : std_ulogic; |
variable rs1_is_r0_v : std_ulogic; |
begin |
-- arbiter defaults -- |
state_nxt <= state; |
is_branch_nxt <= '0'; |
exc_cpu_ack <= '0'; |
exc_cpu_end <= '0'; |
execute_engine.state_nxt <= execute_engine.state; |
execute_engine.i_reg_nxt <= execute_engine.i_reg; |
execute_engine.is_jump_nxt <= '0'; |
execute_engine.is_ci_nxt <= execute_engine.is_ci; |
execute_engine.pc_nxt <= execute_engine.pc(data_width_c-1 downto 1) & '0'; |
|
i_reg_nxt <= i_reg; |
i_buf_nxt <= i_buf; |
ci_reg_nxt <= ci_reg; |
iavail_nxt <= iavail; |
is_ci_nxt <= is_ci; |
-- instruction dispatch -- |
fetch_engine.reset <= '0'; |
ipb.re <= '0'; |
|
-- trap environment control -- |
trap_ctrl.env_start_ack <= '0'; |
trap_ctrl.env_end <= '0'; |
|
-- bus access (fast) -- |
bus_fast_rd <= '0'; |
bus_fast_wr <= '0'; |
|
-- exception trigger -- |
env_call <= '0'; |
break_point <= '0'; |
trap_ctrl.instr_be <= '0'; |
trap_ctrl.instr_ma <= '0'; |
trap_ctrl.env_call <= '0'; |
trap_ctrl.break_point <= '0'; |
|
-- CSR access -- |
csr.we_nxt <= '0'; |
csr.re_nxt <= '0'; |
|
-- control defaults -- |
ctrl_nxt <= (others => '0'); -- all off at first |
ctrl_nxt(ctrl_bus_unsigned_c) <= i_reg(instr_funct3_msb_c); -- unsigned LOAD (LBU, LHU) |
if (i_reg(instr_opcode_lsb_c+4) = '1') then -- ALU ops |
ctrl_nxt(ctrl_alu_unsigned_c) <= i_reg(instr_funct3_lsb_c+0); -- unsigned ALU operation (SLTIU, SLTU) |
ctrl_nxt(ctrl_bus_unsigned_c) <= execute_engine.i_reg(instr_funct3_msb_c); -- unsigned LOAD (LBU, LHU) |
if (execute_engine.i_reg(instr_opcode_lsb_c+4) = '1') then -- ALU ops |
ctrl_nxt(ctrl_alu_unsigned_c) <= execute_engine.i_reg(instr_funct3_lsb_c+0); -- unsigned ALU operation (SLTIU, SLTU) |
else -- branches |
ctrl_nxt(ctrl_alu_unsigned_c) <= i_reg(instr_funct3_lsb_c+1); -- unsigned branches (BLTU, BGEU) |
ctrl_nxt(ctrl_alu_unsigned_c) <= execute_engine.i_reg(instr_funct3_lsb_c+1); -- unsigned branches (BLTU, BGEU) |
end if; |
ctrl_nxt(ctrl_alu_shift_dir_c) <= i_reg(instr_funct3_msb_c); -- shift direction |
ctrl_nxt(ctrl_alu_shift_ar_c) <= i_reg(30); -- arithmetic shift |
ctrl_nxt(ctrl_bus_size_lsb_c) <= i_reg(instr_funct3_lsb_c+0); -- transfer size lsb (00=byte, 01=half-word) |
ctrl_nxt(ctrl_bus_size_msb_c) <= i_reg(instr_funct3_lsb_c+1); -- transfer size msb (10=word, 11=?) |
ctrl_nxt(ctrl_alu_shift_dir_c) <= execute_engine.i_reg(instr_funct3_msb_c); -- shift direction |
ctrl_nxt(ctrl_alu_shift_ar_c) <= execute_engine.i_reg(30); -- arithmetic shift |
ctrl_nxt(ctrl_bus_size_lsb_c) <= execute_engine.i_reg(instr_funct3_lsb_c+0); -- transfer size lsb (00=byte, 01=half-word) |
ctrl_nxt(ctrl_bus_size_msb_c) <= execute_engine.i_reg(instr_funct3_lsb_c+1); -- transfer size msb (10=word, 11=?) |
ctrl_nxt(ctrl_alu_cmd2_c downto ctrl_alu_cmd0_c) <= alu_cmd_add_c; -- actual ALU operation = add |
ctrl_nxt(ctrl_cp_cmd2_c downto ctrl_cp_cmd0_c) <= i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c); -- CP operation |
ctrl_nxt(ctrl_cp_cmd2_c downto ctrl_cp_cmd0_c) <= execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c); -- CP operation |
ctrl_nxt(ctrl_cp_id_msb_c downto ctrl_cp_id_lsb_c) <= cp_sel_muldiv_c; -- only CP0 implemented yet |
|
-- is immediate operation? -- |
alu_immediate_v := '0'; |
if (i_reg(instr_opcode_msb_c-1) = '0') then |
if (execute_engine.i_reg(instr_opcode_msb_c-1) = '0') then |
alu_immediate_v := '1'; |
end if; |
|
-- hardware branch operation control -- |
hw_control(31 downto 24) <= ('0' & funct3_bne_c) & ('1' & funct3_bne_c); |
hw_control(23 downto 16) <= funct3_xor_c & funct3_slt_c & "00"; |
hw_control(15 downto 08) <= funct3_beq_c & funct3_bne_c & "11"; |
hw_control(07 downto 00) <= funct3_beq_c & funct3_bne_c & "00"; |
|
-- alu operation -- |
case i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) is |
-- alu operation re-coding -- |
case execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) is |
when funct3_subadd_c => -- SUB / ADD(I) |
if (alu_immediate_v = '0') and (i_reg(instr_funct7_msb_c-1) = '1') then -- not immediate and funct7 = SUB |
if (alu_immediate_v = '0') and (execute_engine.i_reg(instr_funct7_msb_c-1) = '1') then -- not immediate and funct7 = SUB |
alu_operation_v := alu_cmd_sub_c; |
else |
alu_operation_v := alu_cmd_add_c; |
end if; |
when funct3_sll_c => alu_operation_v := alu_cmd_shift_c; -- SLL(I) |
when funct3_slt_c => alu_operation_v := alu_cmd_slt_c; -- SLT(I) |
when funct3_sltu_c => alu_operation_v := alu_cmd_slt_c; -- SLTU(I) |
when funct3_xor_c => alu_operation_v := alu_cmd_xor_c; -- XOR(I) |
when funct3_slt_c => alu_operation_v := alu_cmd_slt_c; -- SLT(I) |
when funct3_sltu_c => alu_operation_v := alu_cmd_slt_c; -- SLTU(I) |
when funct3_xor_c => alu_operation_v := alu_cmd_xor_c; -- XOR(I) |
when funct3_sr_c => alu_operation_v := alu_cmd_shift_c; -- SRL(I) / SRA(I) |
when funct3_or_c => alu_operation_v := alu_cmd_or_c; -- OR(I) |
when funct3_and_c => alu_operation_v := alu_cmd_and_c; -- AND(I) |
when funct3_or_c => alu_operation_v := alu_cmd_or_c; -- OR(I) |
when funct3_and_c => alu_operation_v := alu_cmd_and_c; -- AND(I) |
when others => alu_operation_v := (others => '0'); -- undefined |
end case; |
|
-- is rd = r0? -- |
rd_is_r0_v := '0'; |
if (execute_engine.i_reg(instr_rd_msb_c downto instr_rd_lsb_c) = "00000") then |
rd_is_r0_v := '1'; |
end if; |
|
-- is rs1 = r0? -- |
rs1_is_r0_v := '0'; |
if (i_reg(instr_rs1_msb_c downto instr_rs1_lsb_c) = "00000") then |
if (execute_engine.i_reg(instr_rs1_msb_c downto instr_rs1_lsb_c) = "00000") then |
rs1_is_r0_v := '1'; |
end if; |
|
-- state machine -- |
case execute_engine.state is |
|
-- state machine: instruction fetch and execution -- |
case state is |
|
when IFETCH_0 => -- output current PC to bus system |
when IDLE => -- Delay cycle (used to wait for side effects to kick in) |
-- ------------------------------------------------------------ |
ctrl_nxt(ctrl_bus_if_c) <= '1'; -- instruction fetch request (output PC to bus address) |
iavail_nxt <= '0'; -- absolutely no instruction available yet |
state_nxt <= IFETCH_1; |
execute_engine.state_nxt <= DISPATCH; |
|
when IFETCH_1 => -- memory latency, update PC |
-- ------------------------------------------------------------ |
ctrl_nxt(ctrl_alu_opa_mux_msb_c downto ctrl_alu_opa_mux_lsb_c) <= "11"; -- opa = current PC |
ctrl_nxt(ctrl_alu_opb_mux_msb_c downto ctrl_alu_opb_mux_lsb_c) <= "11"; -- opb = PC_increment |
ctrl_nxt(ctrl_alu_cmd2_c downto ctrl_alu_cmd0_c) <= alu_cmd_add_c; -- actual ALU operation = ADD |
ctrl_nxt(ctrl_csr_pc_we_c) <= '1'; -- update PC |
state_nxt <= IFETCH_2; |
when DISPATCH => -- Get new command from instruction prefetch buffer (IPB) |
-- ------------------------------------------------------------ |
if (ipb.avail = '1') then -- instruction available? |
ipb.re <= '1'; |
trap_ctrl.instr_ma <= ipb.rdata(33); |
trap_ctrl.instr_be <= ipb.rdata(34); |
if (trap_ctrl.env_start = '1') or (ipb.rdata(33) = '1') or (ipb.rdata(34) = '1') then -- exception/interrupt? |
execute_engine.state_nxt <= TRAP; |
else |
execute_engine.is_ci_nxt <= ipb.rdata(32); -- flag to indicate this is a compressed instruction beeing executed |
execute_engine.i_reg_nxt <= ipb.rdata(31 downto 0); |
execute_engine.pc_nxt <= ipb.raddr(data_width_c-1 downto 1) & '0'; -- the PC according to the current instruction |
execute_engine.state_nxt <= EXECUTE; |
end if; |
end if; |
|
when IFETCH_2 => -- update instruction buffers |
when TRAP => -- Start trap environment (also used as sleep state) |
-- ------------------------------------------------------------ |
if (exc_cpu_start = '1') then -- exception detected! |
exc_cpu_ack <= '1'; |
state_nxt <= IFETCH_0; -- start new instruction fetch |
else -- normal operation |
-- instruction register update -- |
if (CPU_EXTENSION_RISCV_C = true) then -- compressed AND uncompressed instructions possible |
if (pc_backup_reg(1) = '0') then |
i_buf_nxt <= instr_i(31 downto 16); |
ci_reg_nxt <= instr_i(15 downto 00); |
else |
i_buf_nxt <= instr_i(15 downto 00); |
ci_reg_nxt <= instr_i(31 downto 16); |
end if; |
else -- only uncompressed instructions |
i_reg_nxt <= instr_i(31 downto 0); |
end if; |
-- next state -- |
if (bus_wait_i = '0') then -- wait for bus response |
if (CPU_EXTENSION_RISCV_C = true) then -- compressed AND uncompressed instructions possible |
state_nxt <= IFETCH_3; |
else -- only uncompressed instructions |
state_nxt <= EXECUTE; |
end if; |
end if; |
if (trap_ctrl.env_start = '1') then |
trap_ctrl.env_start_ack <= '1'; |
execute_engine.pc_nxt <= csr.mtvec(data_width_c-1 downto 1) & '0'; |
fetch_engine.reset <= '1'; |
execute_engine.state_nxt <= IDLE; |
end if; |
|
|
when IFETCH_3 => -- check for exception, start instruction execution (only available for C-extension) |
when EXECUTE => -- Decode and execute instruction |
-- ------------------------------------------------------------ |
ctrl_nxt(ctrl_alu_opa_mux_msb_c downto ctrl_alu_opa_mux_lsb_c) <= "11"; -- opa = current PC |
ctrl_nxt(ctrl_alu_opb_mux_msb_c downto ctrl_alu_opb_mux_lsb_c) <= "11"; -- opb = PC_increment |
ctrl_nxt(ctrl_alu_cmd2_c downto ctrl_alu_cmd0_c) <= alu_cmd_add_c; -- actual ALU operation = ADD |
-- |
if (exc_cpu_start = '1') then -- exception detected! |
exc_cpu_ack <= '1'; |
state_nxt <= IFETCH_0; -- start new instruction fetch |
else -- normal operation |
if (ci_valid = '1') then -- directly execute decoded compressed instruction |
i_reg_nxt <= ci_instr32; |
state_nxt <= EXECUTE; |
elsif (pc_backup_reg(1) = '0') or (iavail = '1') then -- 32-bit aligned uncompressed instruction |
i_reg_nxt <= i_buf & ci_reg; |
state_nxt <= EXECUTE; |
ctrl_nxt(ctrl_csr_pc_we_c) <= not pc_backup_reg(1); -- update PC again when on 32b-aligned address |
else |
i_reg_nxt <= i_buf & ci_reg; |
state_nxt <= IFETCH_4; |
end if; |
end if; |
case execute_engine.i_reg(instr_opcode_msb_c downto instr_opcode_lsb_c) is |
|
when IFETCH_4 => -- get missing instruction parts: output current PC to bus system (only available for C-extension) |
-- ------------------------------------------------------------ |
ctrl_nxt(ctrl_bus_if_c) <= '1'; -- instruction fetch request (output PC to bus address) |
state_nxt <= IFETCH_5; |
|
when IFETCH_5 => -- memory latency, update PC (only available for C-extension) |
-- ------------------------------------------------------------ |
ctrl_nxt(ctrl_alu_opa_mux_msb_c downto ctrl_alu_opa_mux_lsb_c) <= "11"; -- opa = current PC |
ctrl_nxt(ctrl_alu_opb_mux_msb_c downto ctrl_alu_opb_mux_lsb_c) <= "11"; -- opb = PC_increment |
ctrl_nxt(ctrl_alu_cmd2_c downto ctrl_alu_cmd0_c) <= alu_cmd_add_c; -- actual ALU operation = ADD |
ctrl_nxt(ctrl_csr_pc_we_c) <= '1'; -- update PC |
state_nxt <= IFETCH_6; |
|
when IFETCH_6 => -- update missing instruction buffer parts (only available for C-extension) |
-- ------------------------------------------------------------ |
if (bus_wait_i = '0') then -- wait for bus response |
i_buf_nxt <= instr_i(15 downto 00); |
iavail_nxt <= '1'; |
state_nxt <= IFETCH_3; |
end if; |
|
|
when EXECUTE => -- decode and execute instruction |
-- ------------------------------------------------------------ |
is_ci_nxt <= ci_valid; -- flag to indicate this is a compressed instruction beeing executed (ci_valid is zero if not C-ext is not implemented) |
case i_reg(instr_opcode_msb_c downto instr_opcode_lsb_c) is |
|
when opcode_alu_c | opcode_alui_c => -- ALU operation |
-- ------------------------------------------------------------ |
ctrl_nxt(ctrl_alu_opa_mux_lsb_c) <= '0'; -- use RS1 as ALU.OPA |
500,31 → 733,31
ctrl_nxt(ctrl_alu_opc_mux_c) <= not alu_immediate_v; |
ctrl_nxt(ctrl_alu_cmd2_c downto ctrl_alu_cmd0_c) <= alu_operation_v; -- actual ALU operation |
ctrl_nxt(ctrl_rf_in_mux_msb_c downto ctrl_rf_in_mux_lsb_c) <= "00"; -- RF input = ALU result |
if (CPU_EXTENSION_RISCV_M = true) and (i_reg(instr_opcode_msb_c downto instr_opcode_lsb_c) = opcode_alu_c) and |
(i_reg(instr_funct7_msb_c downto instr_funct7_lsb_c) = "0000001") then -- MULDIV? |
if (CPU_EXTENSION_RISCV_M = true) and (execute_engine.i_reg(instr_opcode_msb_c downto instr_opcode_lsb_c) = opcode_alu_c) and |
(execute_engine.i_reg(instr_funct7_msb_c downto instr_funct7_lsb_c) = "0000001") then -- MULDIV? |
ctrl_nxt(ctrl_cp_use_c) <= '1'; -- use CP |
ctrl_nxt(ctrl_cp_id_msb_c downto ctrl_cp_id_lsb_c) <= cp_sel_muldiv_c; -- muldiv CP |
state_nxt <= ALU_WAIT; |
execute_engine.state_nxt <= ALU_WAIT; |
elsif (alu_operation_v = alu_cmd_shift_c) then -- multi-cycle shift operation? |
state_nxt <= ALU_WAIT; |
execute_engine.state_nxt <= ALU_WAIT; |
else |
ctrl_nxt(ctrl_rf_wb_en_c) <= '1'; -- valid RF write-back |
state_nxt <= IFETCH_0; |
execute_engine.state_nxt <= DISPATCH; |
end if; |
|
when opcode_lui_c | opcode_auipc_c => -- load upper immediate (add to PC) |
-- ------------------------------------------------------------ |
ctrl_nxt(ctrl_rf_clear_rs1_c) <= '1'; -- force RS1 = r0 |
if (i_reg(instr_opcode_msb_c downto instr_opcode_lsb_c) = opcode_auipc_c) then -- AUIPC |
if (execute_engine.i_reg(instr_opcode_msb_c downto instr_opcode_lsb_c) = opcode_auipc_c) then -- AUIPC |
ctrl_nxt(ctrl_alu_opa_mux_lsb_c) <= '1'; -- use PC as ALU.OPA |
else -- LUI |
ctrl_nxt(ctrl_alu_opa_mux_lsb_c) <= '0'; -- use RS1 as ALU.OPA |
end if; |
ctrl_nxt(ctrl_alu_opb_mux_lsb_c) <= '1'; -- use IMM as ALU.OPB |
ctrl_nxt(ctrl_alu_opb_mux_lsb_c) <= '1'; -- use IMM as ALU.OPB |
ctrl_nxt(ctrl_alu_cmd2_c downto ctrl_alu_cmd0_c) <= alu_cmd_add_c; -- actual ALU operation |
ctrl_nxt(ctrl_rf_in_mux_msb_c downto ctrl_rf_in_mux_lsb_c) <= "00"; -- RF input = ALU result |
ctrl_nxt(ctrl_rf_wb_en_c) <= '1'; -- valid RF write-back |
state_nxt <= IFETCH_0; |
execute_engine.state_nxt <= DISPATCH; |
|
when opcode_load_c | opcode_store_c => -- load/store |
-- ------------------------------------------------------------ |
531,12 → 764,14
ctrl_nxt(ctrl_alu_opa_mux_lsb_c) <= '0'; -- use RS1 as ALU.OPA |
ctrl_nxt(ctrl_alu_opb_mux_lsb_c) <= '1'; -- use IMM as ALU.OPB |
ctrl_nxt(ctrl_alu_cmd2_c downto ctrl_alu_cmd0_c) <= alu_cmd_add_c; -- actual ALU operation |
ctrl_nxt(ctrl_bus_mar_we_c) <= '1'; -- write to MAR |
ctrl_nxt(ctrl_bus_mdo_we_c) <= '1'; -- write to MDO (only relevant for stores) |
if (i_reg(instr_opcode_msb_c downto instr_opcode_lsb_c) = opcode_load_c) then -- LOAD |
state_nxt <= LOAD_0; |
else -- STORE |
state_nxt <= STORE_0; |
ctrl_nxt(ctrl_bus_mar_we_c) <= '1'; -- write to MAR |
ctrl_nxt(ctrl_bus_mdo_we_c) <= '1'; -- write to MDO (only relevant for stores) |
if (fetch_engine.state /= IFETCH_0) then |
if (execute_engine.i_reg(instr_opcode_msb_c downto instr_opcode_lsb_c) = opcode_load_c) then -- LOAD |
execute_engine.state_nxt <= LOAD; |
else -- STORE |
execute_engine.state_nxt <= STORE; |
end if; |
end if; |
|
when opcode_branch_c => -- branch instruction |
543,14 → 778,13
-- ------------------------------------------------------------ |
ctrl_nxt(ctrl_alu_opa_mux_lsb_c) <= '1'; -- use PC as ALU.OPA |
ctrl_nxt(ctrl_alu_opb_mux_lsb_c) <= '1'; -- use IMM as ALU.OPB |
ctrl_nxt(ctrl_alu_opc_mux_c) <= '1'; -- use RS2 as ALU.OPC |
is_branch_nxt <= '1'; |
state_nxt <= IFETCH_0; |
ctrl_nxt(ctrl_alu_opc_mux_c) <= '1'; -- use RS2 as ALU.OPC |
execute_engine.state_nxt <= BRANCH; |
|
when opcode_jal_c | opcode_jalr_c => -- jump and link (with register) |
-- ------------------------------------------------------------ |
-- compute target address -- |
if (i_reg(instr_opcode_msb_c downto instr_opcode_lsb_c) = opcode_jal_c) then -- JAL |
if (execute_engine.i_reg(instr_opcode_msb_c downto instr_opcode_lsb_c) = opcode_jal_c) then -- JAL |
ctrl_nxt(ctrl_alu_opa_mux_lsb_c) <= '1'; -- use PC as ALU.OPA |
else -- JALR |
ctrl_nxt(ctrl_alu_opa_mux_lsb_c) <= '0'; -- use RS1 as ALU.OPA |
559,70 → 793,49
-- save return address -- |
ctrl_nxt(ctrl_rf_in_mux_msb_c downto ctrl_rf_in_mux_lsb_c) <= "10"; -- RF input = current PC |
ctrl_nxt(ctrl_rf_wb_en_c) <= '1'; -- valid RF write-back |
-- update PC -- |
ctrl_nxt(ctrl_csr_pc_we_c) <= '1'; -- update PC |
state_nxt <= IFETCH_0; |
-- |
execute_engine.is_jump_nxt <= '1'; -- this is a jump operation |
execute_engine.state_nxt <= BRANCH; |
|
when opcode_syscsr_c => -- system/csr access |
-- ------------------------------------------------------------ |
ctrl_nxt(ctrl_csr_re_c) <= '1'; -- ALWAYS READ CSR!!! (OLD: valid CSR read if rd is not r0) |
if (i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_env_c) then -- system |
case i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) is |
when x"000" => env_call <= '1'; state_nxt <= IFETCH_0; -- ECALL |
when x"001" => break_point <= '1'; state_nxt <= IFETCH_0; -- EBREAK |
when x"302" => exc_cpu_end <= '1'; state_nxt <= IFETCH_0; -- MRET |
when x"105" => state_nxt <= SLEEP; -- WFI |
when others => NULL; -- undefined |
if (execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_csrrw_c) or |
(execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_csrrwi_c) then |
csr.re_nxt <= not rd_is_r0_v; -- only read CSR if not writing to zero_reg |
else |
csr.re_nxt <= '1'; -- always read CSR |
end if; |
-- |
if (execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_env_c) then -- system |
case execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) is |
when x"000" => -- ECALL |
trap_ctrl.env_call <= '1'; |
execute_engine.state_nxt <= IDLE; |
when x"001" => -- EBREAK |
trap_ctrl.break_point <= '1'; |
execute_engine.state_nxt <= IDLE; |
when x"302" => -- MRET |
trap_ctrl.env_end <= '1'; |
execute_engine.pc_nxt <= csr.mepc(data_width_c-1 downto 1) & '0'; |
fetch_engine.reset <= '1'; |
execute_engine.state_nxt <= IDLE; |
when x"105" => -- WFI |
execute_engine.state_nxt <= TRAP; |
when others => -- undefined |
NULL; |
end case; |
elsif (CPU_EXTENSION_RISCV_Zicsr = true) then -- CSR access |
state_nxt <= CSR_ACCESS; |
execute_engine.state_nxt <= CSR_ACCESS; |
else |
state_nxt <= IFETCH_0; |
execute_engine.state_nxt <= DISPATCH; |
end if; |
|
when others => -- undefined |
-- ------------------------------------------------------------ |
state_nxt <= IFETCH_0; |
execute_engine.state_nxt <= DISPATCH; |
|
end case; |
|
when ALU_WAIT => -- wait for multi-cycle ALU operation to finish |
-- ------------------------------------------------------------ |
ctrl_nxt(ctrl_alu_cmd2_c downto ctrl_alu_cmd0_c) <= alu_operation_v; -- actual ALU operation |
ctrl_nxt(ctrl_rf_in_mux_msb_c downto ctrl_rf_in_mux_lsb_c) <= "00"; -- RF input = ALU result |
ctrl_nxt(ctrl_rf_wb_en_c) <= '1'; -- valid RF write-back (write back all the time) |
if (alu_wait_i = '0') then |
state_nxt <= IFETCH_0; |
end if; |
|
when LOAD_0 => -- trigger memory read request |
-- ------------------------------------------------------------ |
ctrl_nxt(ctrl_bus_rd_c) <= '1'; -- read request |
state_nxt <= LOADSTORE_0; |
|
when STORE_0 => -- trigger memory write request |
-- ------------------------------------------------------------ |
ctrl_nxt(ctrl_bus_wr_c) <= '1'; -- write request |
state_nxt <= LOADSTORE_0; |
|
when LOADSTORE_0 => -- memory latency |
-- ------------------------------------------------------------ |
ctrl_nxt(ctrl_bus_mdi_we_c) <= '1'; -- write input data to MDI (only relevant for LOAD) |
state_nxt <= LOADSTORE_1; |
|
when LOADSTORE_1 => -- wait for bus transaction to finish |
-- ------------------------------------------------------------ |
ctrl_nxt(ctrl_bus_mdi_we_c) <= '1'; -- keep writing input data to MDI (only relevant for LOAD) |
ctrl_nxt(ctrl_rf_in_mux_msb_c downto ctrl_rf_in_mux_lsb_c) <= "01"; -- RF input = memory input (only relevant for LOAD) |
if (ma_load_i = '1') or (be_load_i = '1') or (ma_store_i = '1') or (be_store_i = '1') then -- abort if exception |
state_nxt <= IFETCH_0; |
elsif (bus_wait_i = '0') then -- wait here for bus to finish transaction |
if (i_reg(instr_opcode_msb_c downto instr_opcode_lsb_c) = opcode_load_c) then -- LOAD? |
ctrl_nxt(ctrl_rf_wb_en_c) <= '1'; -- valid RF write-back |
end if; |
state_nxt <= IFETCH_0; |
end if; |
|
when CSR_ACCESS => -- write CSR data to RF, write ALU.res to CSR |
-- ------------------------------------------------------------ |
ctrl_nxt(ctrl_alu_opa_mux_msb_c) <= '0'; -- default |
629,34 → 842,39
ctrl_nxt(ctrl_alu_opa_mux_lsb_c) <= '0'; -- default |
ctrl_nxt(ctrl_alu_opb_mux_msb_c) <= '0'; -- default |
ctrl_nxt(ctrl_alu_opb_mux_lsb_c) <= '0'; -- default |
ctrl_nxt(ctrl_csr_we_c) <= not rs1_is_r0_v; -- valid CSR write if rs1 is not r0 (or not imm5 = 0) |
case i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) is |
when funct3_csrrw_c => -- CSSRW |
case execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) is |
when funct3_csrrw_c => -- CSRRW |
ctrl_nxt(ctrl_alu_opa_mux_lsb_c) <= '0'; -- OPA = rs1 |
ctrl_nxt(ctrl_alu_opb_mux_lsb_c) <= '0'; -- OPB = rs2 |
ctrl_nxt(ctrl_rf_clear_rs2_c) <= '1'; -- rs2 = 0 |
ctrl_nxt(ctrl_alu_cmd2_c downto ctrl_alu_cmd0_c) <= alu_cmd_add_c; -- actual ALU operation = ADD |
when funct3_csrrs_c => -- CSSRS |
csr.we_nxt <= '1'; -- always write CSR |
when funct3_csrrs_c => -- CSRRS |
ctrl_nxt(ctrl_alu_opa_mux_msb_c) <= '1'; -- OPA = csr |
ctrl_nxt(ctrl_alu_opb_mux_msb_c) <= '1'; -- OPB = crs1 |
ctrl_nxt(ctrl_alu_cmd2_c downto ctrl_alu_cmd0_c) <= alu_cmd_or_c; -- actual ALU operation = OR |
when funct3_csrrc_c => -- CSSRC |
csr.we_nxt <= not rs1_is_r0_v; -- write CSR if rs1 is not zero_reg |
when funct3_csrrc_c => -- CSRRC |
ctrl_nxt(ctrl_alu_opa_mux_msb_c) <= '1'; -- OPA = csr |
ctrl_nxt(ctrl_alu_opb_mux_msb_c) <= '1'; -- OPB = rs1 |
ctrl_nxt(ctrl_alu_cmd2_c downto ctrl_alu_cmd0_c) <= alu_cmd_bitc_c; -- actual ALU operation = bit clear |
when funct3_csrrwi_c => -- CSSRWI |
csr.we_nxt <= not rs1_is_r0_v; -- write CSR if rs1 is not zero_reg |
when funct3_csrrwi_c => -- CSRRWI |
ctrl_nxt(ctrl_alu_opa_mux_lsb_c) <= '0'; -- OPA = rs1 |
ctrl_nxt(ctrl_rf_clear_rs1_c) <= '1'; -- rs1 = 0 |
ctrl_nxt(ctrl_alu_opb_mux_lsb_c) <= '1'; -- OPB = immediate |
ctrl_nxt(ctrl_alu_cmd2_c downto ctrl_alu_cmd0_c) <= alu_cmd_add_c; -- actual ALU operation = ADD |
when funct3_csrrsi_c => -- CSSRSI |
csr.we_nxt <= '1'; -- always write CSR |
when funct3_csrrsi_c => -- CSRRSI |
ctrl_nxt(ctrl_alu_opa_mux_msb_c) <= '1'; -- OPA = csr |
ctrl_nxt(ctrl_alu_opb_mux_lsb_c) <= '1'; -- OPB = immediate |
ctrl_nxt(ctrl_alu_cmd2_c downto ctrl_alu_cmd0_c) <= alu_cmd_or_c; -- actual ALU operation = OR |
when funct3_csrrci_c => -- CSSRCI |
csr.we_nxt <= not rs1_is_r0_v; -- write CSR if UIMM5 is not zero (bits from rs1 filed) |
when funct3_csrrci_c => -- CSRRCI |
ctrl_nxt(ctrl_alu_opa_mux_msb_c) <= '1'; -- OPA = csr |
ctrl_nxt(ctrl_alu_opb_mux_lsb_c) <= '1'; -- OPB = immediate |
ctrl_nxt(ctrl_alu_cmd2_c downto ctrl_alu_cmd0_c) <= alu_cmd_bitc_c; -- actual ALU operation = bit clear |
csr.we_nxt <= not rs1_is_r0_v; -- write CSR if UIMM5 is not zero (bits from rs1 filed) |
when others => -- undefined |
NULL; |
end case; |
663,28 → 881,66
-- RF write back -- |
ctrl_nxt(ctrl_rf_in_mux_msb_c downto ctrl_rf_in_mux_lsb_c) <= "11"; -- RF input = CSR output register |
ctrl_nxt(ctrl_rf_wb_en_c) <= '1'; -- valid RF write-back |
state_nxt <= IFETCH_0; |
execute_engine.state_nxt <= DISPATCH; |
|
when SLEEP => -- stall and wait for interrupt (WFI) |
when ALU_WAIT => -- wait for multi-cycle ALU operation to finish |
-- ------------------------------------------------------------ |
if (exc_cpu_start = '1') then -- exception detected! |
exc_cpu_ack <= '1'; |
state_nxt <= IFETCH_0; -- start new instruction fetch |
ctrl_nxt(ctrl_alu_cmd2_c downto ctrl_alu_cmd0_c) <= alu_operation_v; -- actual ALU operation |
ctrl_nxt(ctrl_rf_in_mux_msb_c downto ctrl_rf_in_mux_lsb_c) <= "00"; -- RF input = ALU result |
ctrl_nxt(ctrl_rf_wb_en_c) <= '1'; -- valid RF write-back (write back all the time) |
if (alu_wait_i = '0') then |
execute_engine.state_nxt <= DISPATCH; |
end if; |
|
when BRANCH => -- update PC for taken branches and jumps |
-- ------------------------------------------------------------ |
if (execute_engine.is_jump = '1') or (execute_engine.branch_taken = '1') then |
execute_engine.pc_nxt <= alu_add_i(data_width_c-1 downto 1) & '0'; |
fetch_engine.reset <= '1'; |
end if; |
execute_engine.state_nxt <= IDLE; |
|
when LOAD => -- trigger memory read request |
-- ------------------------------------------------------------ |
ctrl_nxt(ctrl_bus_rd_c) <= '1';--bus_fast_rd <= '1'; -- fast read request |
execute_engine.state_nxt <= LOADSTORE_0; |
|
when STORE => -- trigger memory write request |
-- ------------------------------------------------------------ |
ctrl_nxt(ctrl_bus_wr_c) <= '1';--bus_fast_wr <= '1'; -- fast write request |
execute_engine.state_nxt <= LOADSTORE_0; |
|
when LOADSTORE_0 => -- memory latency |
-- ------------------------------------------------------------ |
ctrl_nxt(ctrl_bus_mdi_we_c) <= '1'; -- write input data to MDI (only relevant for LOAD) |
execute_engine.state_nxt <= LOADSTORE_1; |
|
when LOADSTORE_1 => -- wait for bus transaction to finish |
-- ------------------------------------------------------------ |
ctrl_nxt(ctrl_bus_mdi_we_c) <= '1'; -- keep writing input data to MDI (only relevant for LOAD) |
ctrl_nxt(ctrl_rf_in_mux_msb_c downto ctrl_rf_in_mux_lsb_c) <= "01"; -- RF input = memory input (only relevant for LOAD) |
if (ma_load_i = '1') or (be_load_i = '1') or (ma_store_i = '1') or (be_store_i = '1') then -- abort if exception |
execute_engine.state_nxt <= IDLE; |
elsif (bus_wait_i = '0') then -- wait here for bus to finish transaction |
if (execute_engine.i_reg(instr_opcode_msb_c downto instr_opcode_lsb_c) = opcode_load_c) then -- LOAD? |
ctrl_nxt(ctrl_rf_wb_en_c) <= '1'; -- valid RF write-back |
end if; |
execute_engine.state_nxt <= DISPATCH; |
end if; |
|
when others => -- undefined |
-- ------------------------------------------------------------ |
state_nxt <= IFETCH_0; |
execute_engine.state_nxt <= IDLE; |
|
end case; |
end process arbiter_comb; |
end process execute_engine_fsm_comb; |
|
|
-- Illegal Instruction Check -------------------------------------------------------------- |
-- ------------------------------------------------------------------------------------------- |
illegal_instruction_check: process(i_reg, state, ctrl_nxt, ci_valid, ci_illegal) |
illegal_instruction_check: process(execute_engine, csr, ctrl_nxt, ci_illegal) |
begin |
if (state = EXECUTE) then |
if (execute_engine.state = EXECUTE) then |
-- defaults -- |
illegal_instruction <= '0'; |
illegal_register <= '0'; |
691,14 → 947,14
illegal_compressed <= '0'; |
|
-- check if using reg >= 16 for E-CPUs -- |
if (CPU_EXTENSION_RISCV_E = true) then |
illegal_register <= ctrl_nxt(ctrl_rf_rd_adr4_c) or ctrl_nxt(ctrl_rf_rs2_adr4_c) or ctrl_nxt(ctrl_rf_rs1_adr4_c); |
else |
illegal_register <= '0'; |
end if; |
--if (CPU_EXTENSION_RISCV_E = true) then |
-- illegal_register <= ctrl_nxt(ctrl_rf_rd_adr4_c) or ctrl_nxt(ctrl_rf_rs2_adr4_c) or ctrl_nxt(ctrl_rf_rs1_adr4_c); |
--else |
-- illegal_register <= '0'; |
--end if; |
|
-- check instructions -- |
case i_reg(instr_opcode_msb_c downto instr_opcode_lsb_c) is |
case execute_engine.i_reg(instr_opcode_msb_c downto instr_opcode_lsb_c) is |
|
-- OPCODE check sufficient: LUI, UIPC, JAL -- |
when opcode_lui_c | opcode_auipc_c | opcode_jal_c => |
705,11 → 961,11
illegal_instruction <= '0'; |
|
when opcode_alui_c => -- check ALUI funct7 |
if ((i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_sll_c) and |
(i_reg(instr_funct7_msb_c downto instr_funct7_lsb_c) /= "0000000")) or -- shift logical left |
((i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_sr_c) and |
((i_reg(instr_funct7_msb_c downto instr_funct7_lsb_c) /= "0000000") and |
(i_reg(instr_funct7_msb_c downto instr_funct7_lsb_c) /= "0100000"))) then -- shift right |
if ((execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_sll_c) and |
(execute_engine.i_reg(instr_funct7_msb_c downto instr_funct7_lsb_c) /= "0000000")) or -- shift logical left |
((execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_sr_c) and |
((execute_engine.i_reg(instr_funct7_msb_c downto instr_funct7_lsb_c) /= "0000000") and |
(execute_engine.i_reg(instr_funct7_msb_c downto instr_funct7_lsb_c) /= "0100000"))) then -- shift right |
illegal_instruction <= '1'; |
else |
illegal_instruction <= '0'; |
716,11 → 972,11
end if; |
|
when opcode_load_c => -- check LOAD funct3 |
if (i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_lb_c) or |
(i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_lh_c) or |
(i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_lw_c) or |
(i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_lbu_c) or |
(i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_lhu_c) then |
if (execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_lb_c) or |
(execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_lh_c) or |
(execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_lw_c) or |
(execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_lbu_c) or |
(execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_lhu_c) then |
illegal_instruction <= '0'; |
else |
illegal_instruction <= '1'; |
727,9 → 983,9
end if; |
|
when opcode_store_c => -- check STORE funct3 |
if (i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_sb_c) or |
(i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_sh_c) or |
(i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_sw_c) then |
if (execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_sb_c) or |
(execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_sh_c) or |
(execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_sw_c) then |
illegal_instruction <= '0'; |
else |
illegal_instruction <= '1'; |
736,12 → 992,12
end if; |
|
when opcode_branch_c => -- check BRANCH funct3 |
if (i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_beq_c) or |
(i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_bne_c) or |
(i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_blt_c) or |
(i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_bge_c) or |
(i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_bltu_c) or |
(i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_bgeu_c) then |
if (execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_beq_c) or |
(execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_bne_c) or |
(execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_blt_c) or |
(execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_bge_c) or |
(execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_bltu_c) or |
(execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_bgeu_c) then |
illegal_instruction <= '0'; |
else |
illegal_instruction <= '1'; |
748,7 → 1004,7
end if; |
|
when opcode_jalr_c => -- check JALR funct3 |
if (i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = "000") then |
if (execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = "000") then |
illegal_instruction <= '0'; |
else |
illegal_instruction <= '1'; |
755,14 → 1011,14
end if; |
|
when opcode_alu_c => -- check ALU funct3 & funct7 |
if (i_reg(instr_funct7_msb_c downto instr_funct7_lsb_c) = "0000001") then -- MULDIV |
if (CPU_EXTENSION_RISCV_M = false) then |
if (execute_engine.i_reg(instr_funct7_msb_c downto instr_funct7_lsb_c) = "0000001") then -- MULDIV |
if (CPU_EXTENSION_RISCV_M = false) or (csr.misa_m_en = '0') then -- not implemented or disabled |
illegal_instruction <= '1'; |
end if; |
elsif ((i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_subadd_c) or |
(i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_sr_c)) and -- ADD/SUB or SRA/SRL check |
((i_reg(instr_funct7_msb_c downto instr_funct7_lsb_c) /= "0000000") and |
(i_reg(instr_funct7_msb_c downto instr_funct7_lsb_c) /= "0100000")) then -- ADD/SUB or SRA/SRL select |
elsif ((execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_subadd_c) or |
(execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_sr_c)) and -- ADD/SUB or SRA/SRL check |
((execute_engine.i_reg(instr_funct7_msb_c downto instr_funct7_lsb_c) /= "0000000") and |
(execute_engine.i_reg(instr_funct7_msb_c downto instr_funct7_lsb_c) /= "0100000")) then -- ADD/SUB or SRA/SRL select |
illegal_instruction <= '1'; |
else |
illegal_instruction <= '0'; |
770,46 → 1026,45
|
when opcode_syscsr_c => -- check system instructions -- |
-- CSR access -- |
if (i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_csrrw_c) or |
(i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_csrrs_c) or |
(i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_csrrc_c) or |
(i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_csrrwi_c) or |
(i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_csrrsi_c) or |
(i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_csrrci_c) then |
if (execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_csrrw_c) or |
(execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_csrrs_c) or |
(execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_csrrc_c) or |
(execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_csrrwi_c) or |
(execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_csrrsi_c) or |
(execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_csrrci_c) then |
-- valid CSR? -- |
if (i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"300") or -- mstatus |
(i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"301") or -- misa |
(i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"304") or -- mie |
(i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"305") or -- mtvev |
(i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"340") or -- mscratch |
(i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"341") or -- mepc |
(i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"342") or -- mcause |
(i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"343") or -- mtval |
(i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"344") or -- mip |
(i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"34a") or -- mtinst |
if (execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"300") or -- mstatus |
(execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"301") or -- misa |
(execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"304") or -- mie |
(execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"305") or -- mtvev |
(execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"340") or -- mscratch |
(execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"341") or -- mepc |
(execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"342") or -- mcause |
(execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"343") or -- mtval |
(execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"344") or -- mip |
(execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"34a") or -- mtinst |
-- |
((i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"c00") and (CPU_EXTENSION_RISCV_E = false)) or -- cycle |
((i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"c01") and (CPU_EXTENSION_RISCV_E = false)) or -- time |
((i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"c02") and (CPU_EXTENSION_RISCV_E = false)) or -- instret |
((i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"c80") and (CPU_EXTENSION_RISCV_E = false)) or -- cycleh |
((i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"c81") and (CPU_EXTENSION_RISCV_E = false)) or -- timeh |
((i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"c82") and (CPU_EXTENSION_RISCV_E = false)) or -- instreth |
((execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"c00") and (CPU_EXTENSION_RISCV_E = false) and (CSR_COUNTERS_USE = true)) or -- cycle |
((execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"c01") and (CPU_EXTENSION_RISCV_E = false) and (CSR_COUNTERS_USE = true)) or -- time |
((execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"c02") and (CPU_EXTENSION_RISCV_E = false) and (CSR_COUNTERS_USE = true)) or -- instret |
((execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"c80") and (CPU_EXTENSION_RISCV_E = false) and (CSR_COUNTERS_USE = true)) or -- cycleh |
((execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"c81") and (CPU_EXTENSION_RISCV_E = false) and (CSR_COUNTERS_USE = true)) or -- timeh |
((execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"c82") and (CPU_EXTENSION_RISCV_E = false) and (CSR_COUNTERS_USE = true)) or -- instreth |
-- |
((i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"b00") and (CPU_EXTENSION_RISCV_E = false)) or -- mcycle |
((i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"b02") and (CPU_EXTENSION_RISCV_E = false)) or -- minstret |
((i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"b80") and (CPU_EXTENSION_RISCV_E = false)) or -- mcycleh |
((i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"b82") and (CPU_EXTENSION_RISCV_E = false)) or -- minstreth |
((execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"b00") and (CPU_EXTENSION_RISCV_E = false) and (CSR_COUNTERS_USE = true)) or -- mcycle |
((execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"b02") and (CPU_EXTENSION_RISCV_E = false) and (CSR_COUNTERS_USE = true)) or -- minstret |
((execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"b80") and (CPU_EXTENSION_RISCV_E = false) and (CSR_COUNTERS_USE = true)) or -- mcycleh |
((execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"b82") and (CPU_EXTENSION_RISCV_E = false) and (CSR_COUNTERS_USE = true)) or -- minstreth |
-- |
(i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"f13") or -- mimpid |
(i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"f14") or -- mhartid |
(i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"fff") or -- mhwctrl |
(execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"f13") or -- mimpid |
(execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"f14") or -- mhartid |
-- |
(i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"fc0") or -- mfeatures |
(i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"fc1") or -- mclock |
(i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"fc4") or -- mispacebase |
(i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"fc5") or -- mispacesize |
(i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"fc6") or -- mdspacebase |
(i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"fc7") then -- mdspacesize |
(execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"fc0") or -- mfeatures |
(execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"fc1") or -- mclock |
(execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"fc4") or -- mispacebase |
(execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"fc5") or -- mispacesize |
(execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"fc6") or -- mdspacebase |
(execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"fc7") then -- mdspacesize |
illegal_instruction <= '0'; |
else |
illegal_instruction <= '1'; |
816,12 → 1071,12
end if; |
|
-- ecall, ebreak, mret, wfi -- |
elsif (i_reg(instr_rd_msb_c downto instr_rd_lsb_c) = "00000") and |
(i_reg(instr_rs1_msb_c downto instr_rs1_lsb_c) = "00000") then |
if (i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = "000000000000") or -- ECALL |
(i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = "000000000001") or -- EBREAK |
(i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = "001100000010") or -- MRET |
(i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = "000100000101") then -- WFI |
elsif (execute_engine.i_reg(instr_rd_msb_c downto instr_rd_lsb_c) = "00000") and |
(execute_engine.i_reg(instr_rs1_msb_c downto instr_rs1_lsb_c) = "00000") then |
if (execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = "000000000000") or -- ECALL |
(execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = "000000000001") or -- EBREAK |
(execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = "001100000010") or -- MRET |
(execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = "000100000101") then -- WFI |
illegal_instruction <= '0'; |
else |
illegal_instruction <= '1'; |
831,10 → 1086,10
end if; |
|
when others => -- compressed instruction or undefined instruction |
if (i_reg(1 downto 0) = "11") then -- undefined/unimplemented opcode |
if (execute_engine.i_reg(1 downto 0) = "11") then -- undefined/unimplemented opcode |
illegal_instruction <= '1'; |
else -- compressed instruction |
illegal_compressed <= ci_valid and ci_illegal; |
else -- compressed instruction: illegal or disabled / not implemented |
illegal_compressed <= ci_illegal or (not csr.misa_c_en); |
end if; |
|
end case; |
846,142 → 1101,106
end process illegal_instruction_check; |
|
-- any illegal condition? -- |
illegal_instr_exc <= illegal_instruction or illegal_register or illegal_compressed; |
trap_ctrl.instr_il <= illegal_instruction or illegal_register or illegal_compressed; |
|
|
-- Program Counter ------------------------------------------------------------------------ |
-- ------------------------------------------------------------------------------------------- |
program_counter: process(rstn_i, clk_i) |
begin |
if (rstn_i = '0') then |
if (BOOTLOADER_USE = true) then -- boot from bootloader ROM |
pc_reg <= boot_base_c; |
pc_backup_reg <= boot_base_c; |
pc_backup2_reg <= boot_base_c; |
else -- boot from IMEM |
pc_reg <= MEM_ISPACE_BASE; |
pc_backup_reg <= MEM_ISPACE_BASE; |
pc_backup2_reg <= MEM_ISPACE_BASE; |
end if; |
elsif rising_edge(clk_i) then |
-- actual PC -- |
if (exc_cpu_ack = '1') then -- exception start? |
pc_reg <= mtvec; |
elsif (exc_cpu_end = '1') then -- return from exception |
pc_reg <= mepc; |
elsif (ctrl(ctrl_csr_pc_we_c) = '1') or ((is_branch and branch_taken) = '1') then -- manual update or taken branch |
pc_reg <= alu_add_i; |
end if; |
-- delayed PC -- |
if (state = IFETCH_1) then |
pc_backup_reg <= pc_reg; -- PC for ALU address computations |
end if; |
if (state = EXECUTE) then |
pc_backup2_reg <= pc_backup_reg; -- PC backup for exceptions |
end if; |
end if; |
end process program_counter; |
-- **************************************************************************************************************************** |
-- Exception and Interrupt Control |
-- **************************************************************************************************************************** |
|
-- output -- |
pc_o <= pc_reg; |
alu_pc_o <= pc_backup_reg; |
|
|
-- Exception Controller ------------------------------------------------------------------- |
-- Trap Controller ------------------------------------------------------------------------ |
-- ------------------------------------------------------------------------------------------- |
exception_controller: process(rstn_i, clk_i) |
trap_controller: process(rstn_i, clk_i) |
begin |
if (rstn_i = '0') then |
exc_buf <= (others => '0'); |
irq_buf <= (others => '0'); |
exc_ack <= '0'; |
irq_ack <= (others => '0'); |
exc_src <= (others => '0'); |
exc_cpu_start <= '0'; |
exc_cause <= (others => '0'); |
mtinst <= (others => '0'); |
trap_ctrl.exc_buf <= (others => '0'); |
trap_ctrl.irq_buf <= (others => '0'); |
trap_ctrl.exc_ack <= '0'; |
trap_ctrl.irq_ack <= (others => '0'); |
trap_ctrl.cause <= (others => '0'); |
trap_ctrl.instr <= (others => '0'); |
trap_ctrl.exc_src <= (others => '0'); |
trap_ctrl.env_start <= '0'; |
elsif rising_edge(clk_i) then |
if (CPU_EXTENSION_RISCV_Zicsr = true) then |
-- exception buffer: misaligned load/store/instruction address |
exc_buf(exception_lalign_c) <= (exc_buf(exception_lalign_c) or ma_load_i) and (not exc_ack); |
exc_buf(exception_salign_c) <= (exc_buf(exception_salign_c) or ma_store_i) and (not exc_ack); |
exc_buf(exception_ialign_c) <= (exc_buf(exception_ialign_c) or ma_instr_i) and (not exc_ack); |
trap_ctrl.exc_buf(exception_lalign_c) <= (trap_ctrl.exc_buf(exception_lalign_c) or ma_load_i) and (not trap_ctrl.exc_ack); |
trap_ctrl.exc_buf(exception_salign_c) <= (trap_ctrl.exc_buf(exception_salign_c) or ma_store_i) and (not trap_ctrl.exc_ack); |
trap_ctrl.exc_buf(exception_ialign_c) <= (trap_ctrl.exc_buf(exception_ialign_c) or trap_ctrl.instr_ma) and (not trap_ctrl.exc_ack); |
-- exception buffer: load/store/instruction bus access error |
exc_buf(exception_laccess_c) <= (exc_buf(exception_laccess_c) or be_load_i) and (not exc_ack); |
exc_buf(exception_saccess_c) <= (exc_buf(exception_saccess_c) or be_store_i) and (not exc_ack); |
exc_buf(exception_iaccess_c) <= (exc_buf(exception_iaccess_c) or be_instr_i) and (not exc_ack); |
trap_ctrl.exc_buf(exception_laccess_c) <= (trap_ctrl.exc_buf(exception_laccess_c) or be_load_i) and (not trap_ctrl.exc_ack); |
trap_ctrl.exc_buf(exception_saccess_c) <= (trap_ctrl.exc_buf(exception_saccess_c) or be_store_i) and (not trap_ctrl.exc_ack); |
trap_ctrl.exc_buf(exception_iaccess_c) <= (trap_ctrl.exc_buf(exception_iaccess_c) or trap_ctrl.instr_be) and (not trap_ctrl.exc_ack); |
-- exception buffer: illegal instruction / env call / break point |
exc_buf(exception_iillegal_c) <= (exc_buf(exception_iillegal_c) or illegal_instr_exc) and (not exc_ack); |
exc_buf(exception_m_envcall_c) <= (exc_buf(exception_m_envcall_c) or env_call) and (not exc_ack); |
exc_buf(exception_break_c) <= (exc_buf(exception_break_c) or break_point) and (not exc_ack); |
trap_ctrl.exc_buf(exception_m_envcall_c) <= (trap_ctrl.exc_buf(exception_m_envcall_c) or trap_ctrl.env_call) and (not trap_ctrl.exc_ack); |
trap_ctrl.exc_buf(exception_break_c) <= (trap_ctrl.exc_buf(exception_break_c) or trap_ctrl.break_point) and (not trap_ctrl.exc_ack); |
trap_ctrl.exc_buf(exception_iillegal_c) <= (trap_ctrl.exc_buf(exception_iillegal_c) or trap_ctrl.instr_il) and (not trap_ctrl.exc_ack); |
-- interrupt buffer: machine software/external/timer interrupt |
irq_buf(interrupt_msw_irq_c) <= mie_msie and (irq_buf(interrupt_msw_irq_c) or mip_msip) and (not irq_ack(interrupt_msw_irq_c)); |
irq_buf(interrupt_mext_irq_c) <= mie_meie and (irq_buf(interrupt_mext_irq_c) or clic_irq_i) and (not irq_ack(interrupt_mext_irq_c)); |
irq_buf(interrupt_mtime_irq_c) <= mie_mtie and (irq_buf(interrupt_mtime_irq_c) or mtime_irq_i) and (not irq_ack(interrupt_mtime_irq_c)); |
trap_ctrl.irq_buf(interrupt_msw_irq_c) <= csr.mie_msie and (trap_ctrl.irq_buf(interrupt_msw_irq_c) or csr.mip_msip) and (not trap_ctrl.irq_ack(interrupt_msw_irq_c)); |
trap_ctrl.irq_buf(interrupt_mext_irq_c) <= csr.mie_meie and (trap_ctrl.irq_buf(interrupt_mext_irq_c) or clic_irq_i) and (not trap_ctrl.irq_ack(interrupt_mext_irq_c)); |
trap_ctrl.irq_buf(interrupt_mtime_irq_c) <= csr.mie_mtie and (trap_ctrl.irq_buf(interrupt_mtime_irq_c) or mtime_irq_i) and (not trap_ctrl.irq_ack(interrupt_mtime_irq_c)); |
|
-- exception control -- |
if (exc_cpu_start = '0') then -- |
-- exception/interrupt triggered, waiting for IRQ in EXECUTE (make sure at least 1 instr. is executed even for a continous IRQ) |
if (exc_fire = '1') or ((irq_fire = '1') and ((state = EXECUTE) or (state = SLEEP))) then |
exc_cause <= exc_cause_nxt; -- capture source for program |
mtinst <= i_reg; -- MTINST NOT FOULLY IMPLEMENTED YET! FIXME |
mtinst(1) <= not is_ci; -- bit is set for uncompressed instruction |
exc_src <= exc_buf; -- capture source for hardware |
exc_ack <= '1'; -- clear execption |
irq_ack <= irq_ack_nxt; -- capture and clear with interrupt ACK mask |
exc_cpu_start <= '1'; |
-- trap control -- |
if (trap_ctrl.env_start = '0') then -- no started trap handler |
if (trap_ctrl.exc_fire = '1') or ((trap_ctrl.irq_fire = '1') and |
((execute_engine.state = EXECUTE) or (execute_engine.state = TRAP))) then -- exception/IRQ detected! |
trap_ctrl.cause <= trap_ctrl.cause_nxt; -- capture source ID for program |
trap_ctrl.instr <= execute_engine.i_reg; -- FIXME mtinst transformation not fully implemented yet! |
trap_ctrl.instr(1) <= not execute_engine.is_ci; -- bit is set for uncompressed instruction |
trap_ctrl.exc_src <= trap_ctrl.exc_buf; -- capture exception source for hardware |
trap_ctrl.exc_ack <= '1'; -- clear execption |
trap_ctrl.irq_ack <= trap_ctrl.irq_ack_nxt; -- capture and clear with interrupt ACK mask |
trap_ctrl.env_start <= '1'; -- now we want to start the trap handler |
end if; |
else -- waiting for exception handler to get started |
if (exc_cpu_ack = '1') then -- handler started? |
exc_ack <= '0'; |
irq_ack <= (others => '0'); |
exc_cpu_start <= '0'; |
else -- trap waiting to get started |
if (trap_ctrl.env_start_ack = '1') then -- start of trap handler acknowledged by execution engine |
trap_ctrl.exc_ack <= '0'; |
trap_ctrl.irq_ack <= (others => '0'); |
trap_ctrl.env_start <= '0'; |
end if; |
end if; |
else -- (CPU_EXTENSION_RISCV_Zicsr = false) |
exc_buf <= (others => '0'); |
irq_buf <= (others => '0'); |
exc_ack <= '0'; |
irq_ack <= (others => '0'); |
exc_src <= (others => '0'); |
exc_cpu_start <= '0'; |
exc_cause <= (others => '0'); |
mtinst <= (others => '0'); |
end if; |
end if; |
end process exception_controller; |
end process trap_controller; |
|
-- any exception/interrupt? -- |
exc_fire <= or_all_f(exc_buf); -- classic exceptions (faults/traps) cannot be masked |
irq_fire <= or_all_f(irq_buf) and mstatus_mie; -- classic interrupts can be enabled/disabled |
trap_ctrl.exc_fire <= or_all_f(trap_ctrl.exc_buf); -- classic exceptions (faults/traps) cannot be masked |
trap_ctrl.irq_fire <= or_all_f(trap_ctrl.irq_buf) and csr.mstatus_mie; -- classic interrupts can be enabled/disabled |
|
-- exception acknowledge for bus unit -- |
bus_exc_ack_o <= exc_cpu_ack; |
bus_exc_ack_o <= trap_ctrl.env_start_ack or fetch_engine.bus_err_ack; |
|
-- exception priority encoder -- |
exc_priority: process(exc_buf, irq_buf) |
-- exception/interrupt/status ID visible for program -- |
csr.mcause <= trap_ctrl.cause; |
csr.mtinst <= trap_ctrl.instr; |
|
|
-- Trap Priority Detector ----------------------------------------------------------------- |
-- ------------------------------------------------------------------------------------------- |
trap_priority: process(trap_ctrl) |
begin |
-- defaults -- |
exc_cause_nxt <= (others => '0'); |
irq_ack_nxt <= (others => '0'); |
trap_ctrl.cause_nxt <= (others => '0'); |
trap_ctrl.irq_ack_nxt <= (others => '0'); |
|
-- interrupt: 1.11 machine external interrupt -- |
if (irq_buf(interrupt_mext_irq_c) = '1') then |
exc_cause_nxt(exc_cause_nxt'left) <= '1'; |
exc_cause_nxt(3 downto 0) <= "1011"; |
irq_ack_nxt(interrupt_mext_irq_c) <= '1'; |
if (trap_ctrl.irq_buf(interrupt_mext_irq_c) = '1') then |
trap_ctrl.cause_nxt(data_width_c-1) <= '1'; |
trap_ctrl.cause_nxt(3 downto 0) <= "1011"; |
trap_ctrl.irq_ack_nxt(interrupt_mext_irq_c) <= '1'; |
|
-- interrupt: 1.7 machine timer interrupt -- |
elsif (irq_buf(interrupt_mtime_irq_c) = '1') then |
exc_cause_nxt(exc_cause_nxt'left) <= '1'; |
exc_cause_nxt(3 downto 0) <= "0111"; |
irq_ack_nxt(interrupt_mtime_irq_c) <= '1'; |
elsif (trap_ctrl.irq_buf(interrupt_mtime_irq_c) = '1') then |
trap_ctrl.cause_nxt(data_width_c-1) <= '1'; |
trap_ctrl.cause_nxt(3 downto 0) <= "0111"; |
trap_ctrl.irq_ack_nxt(interrupt_mtime_irq_c) <= '1'; |
|
-- interrupt: 1.3 machine SW interrupt -- |
elsif (irq_buf(interrupt_msw_irq_c) = '1') then |
exc_cause_nxt(exc_cause_nxt'left) <= '1'; |
exc_cause_nxt(3 downto 0) <= "0011"; |
irq_ack_nxt(interrupt_msw_irq_c) <= '1'; |
elsif (trap_ctrl.irq_buf(interrupt_msw_irq_c) = '1') then |
trap_ctrl.cause_nxt(data_width_c-1) <= '1'; |
trap_ctrl.cause_nxt(3 downto 0) <= "0011"; |
trap_ctrl.irq_ack_nxt(interrupt_msw_irq_c) <= '1'; |
|
|
-- the following traps are caused by synchronous exceptions |
988,150 → 1207,161
-- here we do not need an acknowledge mask since only one exception can trigger at the same time |
|
-- trap/fault: 0.0 instruction address misaligned -- |
elsif (exc_buf(exception_ialign_c) = '1') then |
exc_cause_nxt(exc_cause_nxt'left) <= '0'; |
exc_cause_nxt(3 downto 0) <= "0000"; |
elsif (trap_ctrl.exc_buf(exception_ialign_c) = '1') then |
trap_ctrl.cause_nxt(data_width_c-1) <= '0'; |
trap_ctrl.cause_nxt(3 downto 0) <= "0000"; |
|
-- trap/fault: 0.1 instruction access fault -- |
elsif (exc_buf(exception_iaccess_c) = '1') then |
exc_cause_nxt(exc_cause_nxt'left) <= '0'; |
exc_cause_nxt(3 downto 0) <= "0001"; |
elsif (trap_ctrl.exc_buf(exception_iaccess_c) = '1') then |
trap_ctrl.cause_nxt(data_width_c-1) <= '0'; |
trap_ctrl.cause_nxt(3 downto 0) <= "0001"; |
|
-- trap/fault: 0.2 illegal instruction -- |
elsif (exc_buf(exception_iillegal_c) = '1') then |
exc_cause_nxt(exc_cause_nxt'left) <= '0'; |
exc_cause_nxt(3 downto 0) <= "0010"; |
elsif (trap_ctrl.exc_buf(exception_iillegal_c) = '1') then |
trap_ctrl.cause_nxt(data_width_c-1) <= '0'; |
trap_ctrl.cause_nxt(3 downto 0) <= "0010"; |
|
|
-- trap/fault: 0.11 environment call from M-mode -- |
elsif (exc_buf(exception_m_envcall_c) = '1') then |
exc_cause_nxt(exc_cause_nxt'left) <= '0'; |
exc_cause_nxt(3 downto 0) <= "1011"; |
elsif (trap_ctrl.exc_buf(exception_m_envcall_c) = '1') then |
trap_ctrl.cause_nxt(data_width_c-1) <= '0'; |
trap_ctrl.cause_nxt(3 downto 0) <= "1011"; |
|
-- trap/fault: 0.3 breakpoint -- |
elsif (exc_buf(exception_break_c) = '1') then |
exc_cause_nxt(exc_cause_nxt'left) <= '0'; |
exc_cause_nxt(3 downto 0) <= "0011"; |
elsif (trap_ctrl.exc_buf(exception_break_c) = '1') then |
trap_ctrl.cause_nxt(data_width_c-1) <= '0'; |
trap_ctrl.cause_nxt(3 downto 0) <= "0011"; |
|
|
-- trap/fault: 0.6 store address misaligned - |
elsif (exc_buf(exception_salign_c) = '1') then |
exc_cause_nxt(exc_cause_nxt'left) <= '0'; |
exc_cause_nxt(3 downto 0) <= "0110"; |
elsif (trap_ctrl.exc_buf(exception_salign_c) = '1') then |
trap_ctrl.cause_nxt(data_width_c-1) <= '0'; |
trap_ctrl.cause_nxt(3 downto 0) <= "0110"; |
|
-- trap/fault: 0.4 load address misaligned -- |
elsif (exc_buf(exception_lalign_c) = '1') then |
exc_cause_nxt(exc_cause_nxt'left) <= '0'; |
exc_cause_nxt(3 downto 0) <= "0100"; |
elsif (trap_ctrl.exc_buf(exception_lalign_c) = '1') then |
trap_ctrl.cause_nxt(data_width_c-1) <= '0'; |
trap_ctrl.cause_nxt(3 downto 0) <= "0100"; |
|
-- trap/fault: 0.7 store access fault -- |
elsif (exc_buf(exception_saccess_c) = '1') then |
exc_cause_nxt(exc_cause_nxt'left) <= '0'; |
exc_cause_nxt(3 downto 0) <= "0111"; |
elsif (trap_ctrl.exc_buf(exception_saccess_c) = '1') then |
trap_ctrl.cause_nxt(data_width_c-1) <= '0'; |
trap_ctrl.cause_nxt(3 downto 0) <= "0111"; |
|
-- trap/fault: 0.5 load access fault -- |
elsif (exc_buf(exception_laccess_c) = '1') then |
exc_cause_nxt(exc_cause_nxt'left) <= '0'; |
exc_cause_nxt(3 downto 0) <= "0101"; |
elsif (trap_ctrl.exc_buf(exception_laccess_c) = '1') then |
trap_ctrl.cause_nxt(data_width_c-1) <= '0'; |
trap_ctrl.cause_nxt(3 downto 0) <= "0101"; |
|
-- undefined / not implemented -- |
else |
exc_cause_nxt <= (others => '0'); |
irq_ack_nxt <= (others => '0'); |
trap_ctrl.cause_nxt <= (others => '0'); |
trap_ctrl.irq_ack_nxt <= (others => '0'); |
end if; |
end process exc_priority; |
end process trap_priority; |
|
|
-- **************************************************************************************************************************** |
-- Control and Status Registers (CSRs) |
-- **************************************************************************************************************************** |
|
-- CSR CPU Access ------------------------------------------------------------------------- |
-- ------------------------------------------------------------------------------------------- |
csr_cpu_acc: process(clk_i) |
begin |
if rising_edge(clk_i) then |
csr.we <= csr.we_nxt; |
csr.re <= csr.re_nxt; |
end if; |
end process csr_cpu_acc; |
|
|
-- Control and Status Registers Write Access ---------------------------------------------- |
-- ------------------------------------------------------------------------------------------- |
csr_write_access: process(rstn_i, clk_i) |
begin |
if (rstn_i = '0') then |
mstatus_mie <= '0'; |
mstatus_mpie <= '0'; |
mie_msie <= '0'; |
mie_meie <= '0'; |
mie_mtie <= '0'; |
mtvec <= (others => '0'); |
mtval <= (others => '0'); |
mepc <= (others => '0'); |
mip_msip <= '0'; |
csr.mstatus_mie <= '0'; |
csr.mstatus_mpie <= '0'; |
csr.mie_msie <= '0'; |
csr.mie_meie <= '0'; |
csr.mie_mtie <= '0'; |
csr.mtvec <= (others => '0'); |
csr.mtval <= (others => '0'); |
csr.mepc <= (others => '0'); |
csr.mip_msip <= '0'; |
csr.misa_c_en <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_C); -- C CPU extension |
csr.misa_m_en <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_M); -- M CPU extension |
elsif rising_edge(clk_i) then |
if (CPU_EXTENSION_RISCV_Zicsr = true) then |
mip_msip <= '0'; |
csr.mip_msip <= '0'; |
|
-- register that can be modified by user -- |
if (ctrl(ctrl_csr_we_c) = '1') then -- manual update |
if (csr.we = '1') then -- manual update |
|
-- machine trap setup -- |
if (i_reg(31 downto 24) = x"30") then |
if (i_reg(23 downto 20) = x"0") then -- R/W: mstatus - machine status register |
mstatus_mie <= csr_wdata_i(03); |
mstatus_mpie <= csr_wdata_i(07); |
if (execute_engine.i_reg(31 downto 24) = x"30") then |
if (execute_engine.i_reg(23 downto 20) = x"0") then -- R/W: mstatus - machine status register |
csr.mstatus_mie <= csr_wdata_i(03); |
csr.mstatus_mpie <= csr_wdata_i(07); |
end if; |
if (i_reg(23 downto 20) = x"4") then -- R/W: mie - machine interrupt-enable register |
mie_msie <= csr_wdata_i(03); -- SW IRQ enable |
mie_mtie <= csr_wdata_i(07); -- TIMER IRQ enable |
mie_meie <= csr_wdata_i(11); -- EXT IRQ enable |
if (execute_engine.i_reg(23 downto 20) = x"1") then -- R/W: misa - machine instruction set extensions |
csr.misa_c_en <= csr_wdata_i(02); -- C extension enable/disable |
csr.misa_m_en <= csr_wdata_i(12); -- M extension enable/disable |
end if; |
if (i_reg(23 downto 20) = x"5") then -- R/W: mtvec - machine trap-handler base address (for ALL exceptions) |
mtvec <= csr_wdata_i; |
if (execute_engine.i_reg(23 downto 20) = x"4") then -- R/W: mie - machine interrupt-enable register |
csr.mie_msie <= csr_wdata_i(03); -- SW IRQ enable |
csr.mie_mtie <= csr_wdata_i(07); -- TIMER IRQ enable |
csr.mie_meie <= csr_wdata_i(11); -- EXT IRQ enable |
end if; |
if (execute_engine.i_reg(23 downto 20) = x"5") then -- R/W: mtvec - machine trap-handler base address (for ALL exceptions) |
csr.mtvec <= csr_wdata_i; |
end if; |
end if; |
|
-- machine trap handling -- |
if (i_reg(31 downto 24) = x"34") then |
if (i_reg(23 downto 20) = x"0") then -- R/W: mscratch - machine scratch register |
mscratch <= csr_wdata_i; |
if (execute_engine.i_reg(31 downto 24) = x"34") then |
if (execute_engine.i_reg(23 downto 20) = x"0") then -- R/W: mscratch - machine scratch register |
csr.mscratch <= csr_wdata_i; |
end if; |
if (i_reg(23 downto 20) = x"1") then-- R/W: mepc - machine exception program counter |
mepc <= csr_wdata_i; |
if (execute_engine.i_reg(23 downto 20) = x"1") then-- R/W: mepc - machine exception program counter |
csr.mepc <= csr_wdata_i; |
end if; |
if (i_reg(23 downto 20) = x"4") then -- R/W: mip - machine interrupt pending |
mip_msip <= csr_wdata_i(03); -- manual SW IRQ trigger |
if (execute_engine.i_reg(23 downto 20) = x"4") then -- R/W: mip - machine interrupt pending |
csr.mip_msip <= csr_wdata_i(03); -- manual SW IRQ trigger |
end if; |
end if; |
|
else -- automatic update by hardware |
-- machine exception PC & exception value register -- |
if (exc_cpu_ack = '1') then -- exception start? |
if (exc_cause(exc_cause_nxt'left) = '1') then -- for INTERRUPTs: mepc = address of next (unclompeted) instruction |
mepc <= pc_reg; |
mtval <= (others => '0'); -- not specified |
else -- for EXCEPTIONs: mepc = address of next (unclompeted) instruction |
mepc <= pc_backup2_reg; |
if ((exc_src(exception_iaccess_c) or exc_src(exception_ialign_c)) = '1') then -- instruction access error OR misaligned instruction |
mtval <= pc_backup_reg; |
elsif (exc_src(exception_iillegal_c) = '1') then -- illegal instruction |
mtval <= i_reg; |
elsif ((exc_src(exception_lalign_c) or exc_src(exception_salign_c) or |
exc_src(exception_laccess_c) or exc_src(exception_saccess_c)) = '1') then -- load/store misaligned / access error |
mtval <= mar_i; |
if (trap_ctrl.env_start_ack = '1') then -- trap handler started? |
if (csr.mcause(data_width_c-1) = '1') then -- for INTERRUPTS only (mtval not defined for interrupts) |
csr.mepc <= execute_engine.pc(data_width_c-1 downto 1) & '0'; -- this is the CURRENT pc = interrupted instruction |
csr.mtval <= (others => '0'); |
else -- for EXCEPTIONs |
csr.mepc <= execute_engine.last_pc(data_width_c-1 downto 1) & '0'; -- this is the LAST pc = last executed instruction |
if ((trap_ctrl.exc_src(exception_iaccess_c) or trap_ctrl.exc_src(exception_ialign_c)) = '1') then -- instruction access error OR misaligned instruction |
csr.mtval <= execute_engine.pc(data_width_c-1 downto 1) & '0'; |
elsif (trap_ctrl.exc_src(exception_iillegal_c) = '1') then -- illegal instruction |
csr.mtval <= execute_engine.i_reg; |
else -- everything else |
--elsif ((trap_ctrl.exc_src(exception_lalign_c) or trap_ctrl.exc_src(exception_salign_c) or |
-- trap_ctrl.exc_src(exception_laccess_c) or trap_ctrl.exc_src(exception_saccess_c)) = '1') then -- load/store misaligned / access error |
csr.mtval <= mar_i; |
end if; |
end if; |
end if; |
|
-- context switch in mstatus -- |
if (exc_cpu_ack = '1') then -- actually entering trap |
mstatus_mie <= '0'; |
if (mstatus_mpie = '0') then -- FIXME: prevent loosing the prev MIE state after several traps |
mstatus_mpie <= mstatus_mie; |
if (trap_ctrl.env_start_ack = '1') then -- actually entering trap |
csr.mstatus_mie <= '0'; |
if (csr.mstatus_mpie = '0') then -- FIXME: prevent loosing the prev MIE state after several traps |
csr.mstatus_mpie <= csr.mstatus_mie; |
end if; |
elsif (exc_cpu_end = '1') then -- return from exception |
mstatus_mie <= mstatus_mpie; |
elsif (trap_ctrl.env_end = '1') then -- return from exception |
csr.mstatus_mie <= csr.mstatus_mpie; |
end if; |
end if; |
|
else -- CPU_EXTENSION_RISCV_Zicsr = false |
mstatus_mie <= '0'; |
mstatus_mpie <= '0'; |
mie_msie <= '0'; |
mie_meie <= '0'; |
mie_mtie <= '0'; |
mtvec <= (others => '0'); |
mtval <= (others => '0'); |
mepc <= (others => '0'); |
mip_msip <= '0'; |
end if; |
end if; |
end process csr_write_access; |
1144,67 → 1374,66
if rising_edge(clk_i) then |
csr_rdata_o <= (others => '0'); -- default |
if (CPU_EXTENSION_RISCV_Zicsr = true) then -- implement CSR access at all? |
if (ctrl(ctrl_csr_re_c) = '1') then |
case i_reg(31 downto 20) is |
if (csr.re = '1') then |
case execute_engine.i_reg(31 downto 20) is |
-- machine trap setup -- |
when x"300" => -- R/W: mstatus - machine status register |
csr_rdata_o(03) <= mstatus_mie; -- MIE |
csr_rdata_o(07) <= mstatus_mpie; -- MPIE |
csr_rdata_o(03) <= csr.mstatus_mie; -- MIE |
csr_rdata_o(07) <= csr.mstatus_mpie; -- MPIE |
csr_rdata_o(11) <= '1'; -- MPP low |
csr_rdata_o(12) <= '1'; -- MPP high |
when x"301" => -- R/-: misa - ISA and extensions |
csr_rdata_o(02) <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_C); -- C CPU extension |
when x"301" => -- R/W: misa - ISA and extensions |
csr_rdata_o(02) <= csr.misa_c_en; -- C CPU extension |
csr_rdata_o(04) <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_E); -- E CPU extension |
csr_rdata_o(08) <= not bool_to_ulogic_f(CPU_EXTENSION_RISCV_E); -- I CPU extension (if not E) |
csr_rdata_o(12) <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_M); -- M CPU extension |
csr_rdata_o(12) <= csr.misa_m_en; -- M CPU extension |
csr_rdata_o(23) <= '1'; -- X CPU extension: non-standard extensions |
csr_rdata_o(25) <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_Zicsr); -- Z CPU extension |
csr_rdata_o(30) <= '1'; -- 32-bit architecture (MXL lo) |
csr_rdata_o(31) <= '0'; -- 32-bit architecture (MXL hi) |
when x"304" => -- R/W: mie - machine interrupt-enable register |
csr_rdata_o(03) <= mie_msie; -- software IRQ enable |
csr_rdata_o(07) <= mie_mtie; -- timer IRQ enable |
csr_rdata_o(11) <= mie_meie; -- external IRQ enable |
csr_rdata_o(03) <= csr.mie_msie; -- software IRQ enable |
csr_rdata_o(07) <= csr.mie_mtie; -- timer IRQ enable |
csr_rdata_o(11) <= csr.mie_meie; -- external IRQ enable |
when x"305" => -- R/W: mtvec - machine trap-handler base address (for ALL exceptions) |
csr_rdata_o <= mtvec; |
csr_rdata_o <= csr.mtvec; |
-- machine trap handling -- |
when x"340" => -- R/W: mscratch - machine scratch register |
csr_rdata_o <= mscratch; |
csr_rdata_o <= csr.mscratch; |
when x"341" => -- R/W: mepc - machine exception program counter |
csr_rdata_o <= mepc; |
csr_rdata_o <= csr.mepc; |
when x"342" => -- R/-: mcause - machine trap cause |
csr_rdata_o <= exc_cause; |
csr_rdata_o <= csr.mcause; |
when x"343" => -- R/-: mtval - machine bad address or instruction |
csr_rdata_o <= mtval; |
csr_rdata_o <= csr.mtval; |
when x"344" => -- R/W: mip - machine interrupt pending |
csr_rdata_o(03) <= irq_buf(interrupt_msw_irq_c); |
csr_rdata_o(07) <= irq_buf(interrupt_mtime_irq_c); |
csr_rdata_o(11) <= irq_buf(interrupt_mext_irq_c); |
csr_rdata_o(03) <= trap_ctrl.irq_buf(interrupt_msw_irq_c); |
csr_rdata_o(07) <= trap_ctrl.irq_buf(interrupt_mtime_irq_c); |
csr_rdata_o(11) <= trap_ctrl.irq_buf(interrupt_mext_irq_c); |
when x"34a" => -- R/-: mtinst - machine trap instruction (transformed) |
csr_rdata_o <= mtinst; |
csr_rdata_o <= csr.mtinst; |
-- counter and timers -- |
when x"c00" | x"c01" | x"b00" => -- R/-: cycle/time/mcycle: Cycle counter LOW / Timer LOW |
csr_rdata_o <= cycle_lo(31 downto 0); |
csr_rdata_o <= csr.cycle(31 downto 0); |
when x"c02" | x"b02" => -- R/-: instret/minstret: Instructions-retired counter LOW |
csr_rdata_o <= instret_lo(31 downto 0); |
csr_rdata_o <= csr.instret(31 downto 0); |
when x"c80" | x"c81" | x"b80" => -- R/-: cycleh/timeh/mcycleh: Cycle counter HIGH / Timer HIGH |
csr_rdata_o(15 downto 0) <= cycle_hi; -- counter is only 16-bit wide! |
csr_rdata_o <= csr.cycleh; |
when x"c82" | x"b82" => -- R/-: instreth/minstreth: Instructions-retired counter HIGH |
csr_rdata_o(15 downto 0) <= instret_hi; -- counter is only 16-bit wide! |
csr_rdata_o <= csr.instreth; |
-- machine information registers -- |
when x"f13" => -- R/-: mimpid - implementation ID / version |
csr_rdata_o <= hw_version_c; |
when x"f14" => -- R/-: mhartid - hardware thread ID |
csr_rdata_o <= HART_ID; |
when x"fff" => -- R/-: mhwctrl - hardware controller |
csr_rdata_o <= hw_control; |
-- CUSTOM read-only machine CSRs -- |
when x"fc0" => -- R/-: mfeatures - implemented processor devices/features |
csr_rdata_o(00) <= bool_to_ulogic_f(BOOTLOADER_USE); -- implement processor-internal bootloader? |
csr_rdata_o(01) <= bool_to_ulogic_f(MEM_EXT_USE); -- implement external memory bus interface? |
csr_rdata_o(02) <= bool_to_ulogic_f(MEM_INT_IMEM_USE); -- implement processor-internal instruction memory |
csr_rdata_o(03) <= bool_to_ulogic_f(MEM_INT_IMEM_ROM); -- implement processor-internal instruction memory as ROM |
csr_rdata_o(04) <= bool_to_ulogic_f(MEM_INT_DMEM_USE); -- implement processor-internal data memory |
csr_rdata_o(02) <= bool_to_ulogic_f(MEM_INT_IMEM_USE); -- implement processor-internal instruction memory? |
csr_rdata_o(03) <= bool_to_ulogic_f(MEM_INT_IMEM_ROM); -- implement processor-internal instruction memory as ROM? |
csr_rdata_o(04) <= bool_to_ulogic_f(MEM_INT_DMEM_USE); -- implement processor-internal data memory? |
csr_rdata_o(05) <= bool_to_ulogic_f(CSR_COUNTERS_USE); -- implement RISC-V (performance) counter? |
-- |
csr_rdata_o(16) <= bool_to_ulogic_f(IO_GPIO_USE); -- implement general purpose input/output port unit (GPIO)? |
csr_rdata_o(17) <= bool_to_ulogic_f(IO_MTIME_USE); -- implement machine system timer (MTIME)? |
1236,41 → 1465,34
end process csr_read_access; |
|
|
-- Optional RISC-V CSRs: Counters --------------------------------------------------------- |
-- RISC-V Counter CSRs -------------------------------------------------------------------- |
-- ------------------------------------------------------------------------------------------- |
csr_counters: process(rstn_i, clk_i) |
begin |
if rising_edge(clk_i) then |
if (rstn_i = '0') then |
cycle_lo <= (others => '0'); |
instret_lo <= (others => '0'); |
cycle_hi <= (others => '0'); |
instret_hi <= (others => '0'); |
cycle_lo_msb <= '0'; |
instret_lo_msb <= '0'; |
elsif (CPU_EXTENSION_RISCV_E = false) then |
if (rstn_i = '0') then |
csr.cycle <= (others => '0'); |
csr.instret <= (others => '0'); |
csr.cycleh <= (others => '0'); |
csr.instreth <= (others => '0'); |
cycle_msb <= '0'; |
instret_msb <= '0'; |
elsif rising_edge(clk_i) then |
if (CPU_EXTENSION_RISCV_E = false) and (CSR_COUNTERS_USE = true) then |
-- low word overflow buffers -- |
cycle_lo_msb <= cycle_lo(cycle_lo'left); |
instret_lo_msb <= instret_lo(instret_lo'left); |
cycle_msb <= csr.cycle(csr.cycle'left); |
instret_msb <= csr.instret(csr.instret'left); |
-- low word counters -- |
cycle_lo <= std_ulogic_vector(unsigned(cycle_lo) + 1); |
if (state = EXECUTE) then |
instret_lo <= std_ulogic_vector(unsigned(instret_lo) + 1); |
csr.cycle <= std_ulogic_vector(unsigned(csr.cycle) + 1); |
if (execute_engine.state_prev /= EXECUTE) and (execute_engine.state = EXECUTE) then |
csr.instret <= std_ulogic_vector(unsigned(csr.instret) + 1); |
end if; |
-- high word counters -- |
if ((cycle_lo_msb xor cycle_lo(cycle_lo'left)) = '1') then |
cycle_hi <= std_ulogic_vector(unsigned(cycle_hi) + 1); |
if ((cycle_msb xor csr.cycle(csr.cycle'left)) = '1') then |
csr.cycleh <= std_ulogic_vector(unsigned(csr.cycleh) + 1); |
end if; |
if ((instret_lo_msb xor instret_lo(instret_lo'left)) = '1') then |
instret_hi <= std_ulogic_vector(unsigned(instret_hi) + 1); |
if ((instret_msb xor csr.instret(csr.instret'left)) = '1') then |
csr.instreth <= std_ulogic_vector(unsigned(csr.instreth) + 1); |
end if; |
else -- counters are not available in embedded mode |
cycle_lo <= (others => '0'); |
instret_lo <= (others => '0'); |
cycle_hi <= (others => '0'); |
instret_hi <= (others => '0'); |
cycle_lo_msb <= '0'; |
instret_lo_msb <= '0'; |
end if; |
end if; |
end process csr_counters; |
/rtl/core/neorv32_cpu_cp_muldiv.vhd
2,8 → 2,8
-- # << NEORV32 - CPU Co-Processor: MULDIV unit >> # |
-- # ********************************************************************************************* # |
-- # Multiplier and Divider unit. Implements the RISC-V RV32-M CPU extension. # |
-- # Multiplier core (signed/unsigned) uses serial algorithm. -> 32+8 cycles latency # |
-- # Divider core (unsigned) uses serial algorithm. -> 32+8 cycles latency # |
-- # Multiplier core (signed/unsigned) uses serial algorithm. -> 32+4 cycles latency # |
-- # Divider core (unsigned) uses serial algorithm. -> 32+6 cycles latency # |
-- # ********************************************************************************************* # |
-- # BSD 3-Clause License # |
-- # # |
60,6 → 60,9
|
architecture neorv32_cpu_cp_muldiv_rtl of neorv32_cpu_cp_muldiv is |
|
-- constants -- |
constant all_zero_c : std_ulogic_vector(data_width_c-1 downto 0) := (others => '0'); |
|
-- controller -- |
type state_t is (IDLE, DECODE, INIT_OPX, INIT_OPY, PROCESSING, FINALIZE, COMPLETED); |
signal state : state_t; |
70,6 → 73,7
signal opx, opy : std_ulogic_vector(data_width_c-1 downto 0); -- input operands |
signal opx_is_signed : std_ulogic; |
signal opy_is_signed : std_ulogic; |
signal opy_is_zero : std_ulogic; |
signal div_res_corr : std_ulogic; |
|
-- divider core -- |
101,6 → 105,7
start <= '0'; |
valid_o <= '0'; |
div_res_corr <= '0'; |
opy_is_zero <= '0'; |
elsif rising_edge(clk_i) then |
-- defaults -- |
start <= '0'; |
118,11 → 123,19
|
when DECODE => |
cnt <= "11111"; |
if (cp_op = cp_op_div_c) or (cp_op = cp_op_rem_c) then -- result sign compensation for div? |
if (cp_op = cp_op_div_c) then -- result sign compensation for div? |
div_res_corr <= opx(opx'left) xor opy(opy'left); |
elsif (cp_op = cp_op_rem_c) then -- result sign compensation for rem? |
div_res_corr <= opx(opx'left); |
else |
div_res_corr <= '0'; |
end if; |
-- if (cp_op = cp_op_div_c) and (opy = all_zero_c) then -- *divide* by 0? |
if (opy = all_zero_c) then -- *divide* by 0? |
opy_is_zero <= '1'; |
else |
opy_is_zero <= '0'; |
end if; |
if (operation = '1') then -- division |
state <= INIT_OPX; |
else -- multiplication |
175,7 → 188,7
begin |
if rising_edge(clk_i) then |
if (start = '1') then -- start new multiplication |
mul_product(63 downto 32) <= (others => (opy(opy'left) and opy_is_signed)); -- sign extension |
mul_product(63 downto 32) <= (others => '0'); |
mul_product(31 downto 00) <= opy; |
elsif ((state = PROCESSING) or (state = FINALIZE)) and (operation = '0') then |
mul_product(63 downto 31) <= mul_do_add(32 downto 0); |
189,9 → 202,9
begin |
if (mul_product(0) = '1') then |
if (mul_sign_cycle = '1') then -- for signed operation only: take care of negative weighted MSB |
mul_do_add <= std_ulogic_vector(unsigned(mul_p_sext & mul_product(63 downto 32)) - unsigned((opx(opy'left) and opx_is_signed) & opx)); |
mul_do_add <= std_ulogic_vector(unsigned(mul_p_sext & mul_product(63 downto 32)) - unsigned((opx(opx'left) and opx_is_signed) & opx)); |
else |
mul_do_add <= std_ulogic_vector(unsigned(mul_p_sext & mul_product(63 downto 32)) + unsigned((opx(opy'left) and opx_is_signed) & opx)); |
mul_do_add <= std_ulogic_vector(unsigned(mul_p_sext & mul_product(63 downto 32)) + unsigned((opx(opx'left) and opx_is_signed) & opx)); |
end if; |
else |
mul_do_add <= mul_p_sext & mul_product(63 downto 32); |
232,7 → 245,7
div_sign_comp <= std_ulogic_vector(0 - unsigned(div_sign_comp_in)); |
|
-- result sign correction -- |
div_res <= div_sign_comp when (div_res_corr = '1') else div_sign_comp_in; |
div_res <= div_sign_comp when (div_res_corr = '1') and (opy_is_zero = '0') else div_sign_comp_in; |
|
|
-- Data Output ---------------------------------------------------------------------------- |
240,6 → 253,7
operation_result: process(clk_i) |
begin |
if rising_edge(clk_i) then |
res_o <= (others => '0'); -- default |
case cp_op is |
when cp_op_mul_c => |
res_o <= mul_product(31 downto 00); |
250,7 → 264,11
when cp_op_divu_c => |
res_o <= quotient; |
when cp_op_rem_c => |
res_o <= div_res; |
if (opy_is_zero = '0') then |
res_o <= div_res; |
else |
res_o <= opx; |
end if; |
when cp_op_remu_c => |
res_o <= remainder; |
when others => -- undefined |
/rtl/core/neorv32_cpu_decompressor.vhd
44,7 → 44,6
-- instruction input -- |
ci_instr16_i : in std_ulogic_vector(15 downto 0); -- compressed instruction input |
-- instruction output -- |
ci_valid_o : out std_ulogic; -- is a compressed instruction |
ci_illegal_o : out std_ulogic; -- is an illegal compressed instruction |
ci_instr32_o : out std_ulogic_vector(31 downto 0) -- 32-bit decompressed instruction |
); |
147,7 → 146,7
ci_instr32_o(24) <= ci_instr16_i(11); |
ci_instr32_o(25) <= ci_instr16_i(12); |
ci_instr32_o(26) <= ci_instr16_i(5); |
ci_instr32_o(31 downto 26) <= (others => '0'); |
ci_instr32_o(31 downto 27) <= (others => '0'); |
ci_instr32_o(instr_funct3_msb_c downto instr_funct3_lsb_c) <= funct3_lw_c; |
ci_instr32_o(instr_rs1_msb_c downto instr_rs1_lsb_c) <= "01" & ci_instr16_i(ci_rs1_3_msb_c downto ci_rs1_3_lsb_c); -- x8 - x15 |
ci_instr32_o(instr_rd_msb_c downto instr_rd_lsb_c) <= "01" & ci_instr16_i(ci_rd_3_msb_c downto ci_rd_3_lsb_c); -- x8 - x15 |
432,8 → 431,5
end case; |
end process decompressor; |
|
-- is compressed instruction at all? -- |
ci_valid_o <= '0' when (ci_instr16_i(ci_opcode_msb_c downto ci_opcode_lsb_c) = "11") else '1'; |
|
|
end neorv32_cpu_decompressor_rtl; |
/rtl/core/neorv32_devnull.vhd
3,6 → 3,7
-- # ********************************************************************************************* # |
-- # In simulation: This unit will output the lowest 8 bit of the written data as ASCII chars # |
-- # to the simulator console and to a text file ("neorv32.devnull.out"). # |
-- # The complete data 32-bit data word is dumped to "neorv32.devnull.data.out". # |
-- # In real hardware: This unit implements a "/dev/null" device. # |
-- # ********************************************************************************************* # |
-- # BSD 3-Clause License # |
61,7 → 62,8
architecture neorv32_devnull_rtl of neorv32_devnull is |
|
-- configuration -- |
constant sim_output_en_c : boolean := true; -- output lowest byte as char to simulator when enabled |
constant sim_text_output_en_c : boolean := true; -- output lowest byte as char to simulator and file when enabled |
constant sim_data_output_en_c : boolean := true; -- dump 32-word to file when enabled |
|
-- IO space: module base address -- |
constant hi_abb_c : natural := index_size_f(io_size_c)-1; -- high address boundary bit |
80,26 → 82,36
-- Read/Write Access ---------------------------------------------------------------------- |
-- ------------------------------------------------------------------------------------------- |
rw_access: process(clk_i) |
file file_devnull_out : text open write_mode is "neorv32.devnull.out"; |
file file_devnull_text_out : text open write_mode is "neorv32.devnull.out"; |
file file_devnull_data_out : text open write_mode is "neorv32.devnull.data.out"; |
variable i : integer; |
variable la, lb : line; -- we need to variables here since "writeline" seems to flush the source variable |
variable la, lb, lc : line; -- we need several variables here since "writeline" seems to flush the source variable |
begin |
if rising_edge(clk_i) then |
ack_o <= acc_en and (wren_i or rden_i); |
if ((acc_en and wren_i and ben_i(0)) = '1') and (sim_output_en_c = true) then |
-- print lowest byte as ASCII to console -- |
i := to_integer(unsigned(data_i(7 downto 0))); |
if (i >= 128) then -- out of range? |
i := 0; |
if (acc_en = '1') and (wren_i = '1') then |
if (sim_text_output_en_c = true) and (ben_i(0) = '1') then |
-- print lowest byte as ASCII to console -- |
i := to_integer(unsigned(data_i(7 downto 0))); |
if (i >= 128) then -- out of range? |
i := 0; |
end if; |
if (i /= 10) and (i /= 13) then -- skip line breaks - they are issued via "writeline" |
write(la, character'val(i)); |
write(lb, character'val(i)); |
end if; |
if (i = 10) then -- line break: write to screen and file |
writeline(output, la); |
writeline(file_devnull_text_out, lb); |
end if; |
end if; |
if (i /= 10) and (i /= 13) then -- skip line breaks - they are issued via "writeline" |
write(la, character'val(i)); |
write(lb, character'val(i)); |
if (sim_data_output_en_c = true) then |
-- dump raw data |
for x in 7 downto 0 loop |
write(lc, to_hexchar_f(data_i(3+x*4 downto 0+x*4))); -- write in hex form |
end loop; -- x |
writeline(file_devnull_data_out, lc); |
end if; |
if (i = 10) then -- line break: write to screen and file |
writeline(output, la); |
writeline(file_devnull_out, lb); |
end if; |
end if; |
end if; |
end process rw_access; |
/rtl/core/neorv32_mtime.vhd
108,6 → 108,7
else |
-- mtime low -- |
mtime_lo <= std_ulogic_vector(unsigned(mtime_lo) + 1); |
mtime_lo_msb_ff <= mtime_lo(mtime_lo'left); |
-- mtime high -- |
if ((mtime_lo_msb_ff xor mtime_lo(mtime_lo'left)) = '1') then -- mtime_lo carry? |
mtime_hi <= std_ulogic_vector(unsigned(mtime_hi) + 1); |
/rtl/core/neorv32_package.vhd
41,7 → 41,7
-- Architecture Constants ----------------------------------------------------------------- |
-- ------------------------------------------------------------------------------------------- |
constant data_width_c : natural := 32; -- data width - FIXED! |
constant hw_version_c : std_ulogic_vector(31 downto 0) := x"00000206"; -- no touchy! |
constant hw_version_c : std_ulogic_vector(31 downto 0) := x"01000000"; -- no touchy! |
|
-- Internal Functions --------------------------------------------------------------------- |
-- ------------------------------------------------------------------------------------------- |
53,6 → 53,7
function and_all_f( a : std_ulogic_vector) return std_ulogic; |
function xor_all_f( a : std_ulogic_vector) return std_ulogic; |
function xnor_all_f(a : std_ulogic_vector) return std_ulogic; |
function to_hexchar_f(input : std_ulogic_vector(3 downto 0)) return character; |
|
-- Processor-internal Address Space Layout ------------------------------------------------ |
-- ------------------------------------------------------------------------------------------- |
160,9 → 161,9
constant ctrl_alu_cmd1_c : natural := 21; -- ALU command bit 1 |
constant ctrl_alu_cmd2_c : natural := 22; -- ALU command bit 2 |
constant ctrl_alu_opa_mux_lsb_c : natural := 23; -- operand A select lsb (00=rs1, 01=PC) |
constant ctrl_alu_opa_mux_msb_c : natural := 24; -- operand A select msb (10=CSR, 11=CSR) |
constant ctrl_alu_opb_mux_lsb_c : natural := 25; -- operand B select lsb (00=rs2, 01=PC) |
constant ctrl_alu_opb_mux_msb_c : natural := 26; -- operand B select msb (10=rs1, 11=PC_increment(2/4)) |
constant ctrl_alu_opa_mux_msb_c : natural := 24; -- operand A select msb (10=CSR, 11=?) |
constant ctrl_alu_opb_mux_lsb_c : natural := 25; -- operand B select lsb (00=rs2, 01=IMM) |
constant ctrl_alu_opb_mux_msb_c : natural := 26; -- operand B select msb (10=rs1, 11=?) |
constant ctrl_alu_opc_mux_c : natural := 27; -- operand C select (0=IMM, 1=rs2) |
constant ctrl_alu_unsigned_c : natural := 28; -- is unsigned ALU operation |
constant ctrl_alu_shift_dir_c : natural := 29; -- shift direction (0=left, 1=right) |
177,24 → 178,23
constant ctrl_bus_mdo_we_c : natural := 37; -- memory data out register write enable |
constant ctrl_bus_mdi_we_c : natural := 38; -- memory data in register write enable |
constant ctrl_bus_unsigned_c : natural := 39; -- is unsigned load |
-- csr/system -- |
constant ctrl_csr_pc_we_c : natural := 40; -- PC write enable |
constant ctrl_csr_re_c : natural := 41; -- valid CSR read |
constant ctrl_csr_we_c : natural := 42; -- valid CSR write |
-- co-processor -- |
constant ctrl_cp_use_c : natural := 43; -- is cp operation |
constant ctrl_cp_id_lsb_c : natural := 44; -- cp select lsb |
constant ctrl_cp_id_msb_c : natural := 45; -- cp select msb |
constant ctrl_cp_cmd0_c : natural := 46; -- cp command bit 0 |
constant ctrl_cp_cmd1_c : natural := 47; -- cp command bit 1 |
constant ctrl_cp_cmd2_c : natural := 48; -- cp command bit 2 |
constant ctrl_cp_use_c : natural := 40; -- is cp operation |
constant ctrl_cp_id_lsb_c : natural := 41; -- cp select lsb |
constant ctrl_cp_id_msb_c : natural := 42; -- cp select msb |
constant ctrl_cp_cmd0_c : natural := 43; -- cp command bit 0 |
constant ctrl_cp_cmd1_c : natural := 44; -- cp command bit 1 |
constant ctrl_cp_cmd2_c : natural := 45; -- cp command bit 2 |
-- system -- |
constant ctrl_sys_c_ext_en_c : natural := 46; -- CPU C extension enabled |
constant ctrl_sys_m_ext_en_c : natural := 47; -- CPU M extension enabled |
-- control bus size -- |
constant ctrl_width_c : natural := 49; -- control bus size |
constant ctrl_width_c : natural := 48; -- control bus size |
|
-- ALU Comparator Bus --------------------------------------------------------------------- |
-- ------------------------------------------------------------------------------------------- |
constant alu_cmp_equal_c : natural := 0; |
constant alu_cmp_less_c : natural := 1; -- for signed and unsigned |
constant alu_cmp_less_c : natural := 1; -- for signed and unsigned comparisons |
|
-- RISC-V Opcode Layout ------------------------------------------------------------------- |
-- ------------------------------------------------------------------------------------------- |
279,14 → 279,14
-- cp ids -- |
constant cp_sel_muldiv_c : std_ulogic_vector(1 downto 0) := "00"; -- MULDIV CP |
-- muldiv cp -- |
constant cp_op_mul_c : std_ulogic_vector(2 downto 0) := "000"; -- mul |
constant cp_op_mulh_c : std_ulogic_vector(2 downto 0) := "001"; -- mulh |
constant cp_op_mulhsu_c : std_ulogic_vector(2 downto 0) := "010"; -- mulhsu |
constant cp_op_mulhu_c : std_ulogic_vector(2 downto 0) := "011"; -- mulhu |
constant cp_op_div_c : std_ulogic_vector(2 downto 0) := "100"; -- div |
constant cp_op_divu_c : std_ulogic_vector(2 downto 0) := "101"; -- divu |
constant cp_op_rem_c : std_ulogic_vector(2 downto 0) := "110"; -- rem |
constant cp_op_remu_c : std_ulogic_vector(2 downto 0) := "111"; -- remu |
constant cp_op_mul_c : std_ulogic_vector(2 downto 0) := "000"; -- mul |
constant cp_op_mulh_c : std_ulogic_vector(2 downto 0) := "001"; -- mulh |
constant cp_op_mulhsu_c : std_ulogic_vector(2 downto 0) := "010"; -- mulhsu |
constant cp_op_mulhu_c : std_ulogic_vector(2 downto 0) := "011"; -- mulhu |
constant cp_op_div_c : std_ulogic_vector(2 downto 0) := "100"; -- div |
constant cp_op_divu_c : std_ulogic_vector(2 downto 0) := "101"; -- divu |
constant cp_op_rem_c : std_ulogic_vector(2 downto 0) := "110"; -- rem |
constant cp_op_remu_c : std_ulogic_vector(2 downto 0) := "111"; -- remu |
|
-- ALU Function Codes --------------------------------------------------------------------- |
-- ------------------------------------------------------------------------------------------- |
337,6 → 337,7
CLOCK_FREQUENCY : natural := 0; -- clock frequency of clk_i in Hz |
HART_ID : std_ulogic_vector(31 downto 0) := x"00000000"; -- custom hardware thread ID |
BOOTLOADER_USE : boolean := true; -- implement processor-internal bootloader? |
CSR_COUNTERS_USE : boolean := true; -- implement RISC-V perf. counters ([m]instret[h], [m]cycle[h], time[h])? |
-- RISC-V CPU Extensions -- |
CPU_EXTENSION_RISCV_C : boolean := false; -- implement compressed extension? |
CPU_EXTENSION_RISCV_E : boolean := false; -- implement embedded RF extension? |
390,9 → 391,9
uart_txd_o : out std_ulogic; -- UART send data |
uart_rxd_i : in std_ulogic := '0'; -- UART receive data |
-- SPI -- |
spi_sclk_o : out std_ulogic; -- serial clock line |
spi_mosi_o : out std_ulogic; -- serial data line out |
spi_miso_i : in std_ulogic := '0'; -- serial data line in |
spi_sck_o : out std_ulogic; -- SPI serial clock |
spi_sdo_o : out std_ulogic; -- controller data out, peripheral data in |
spi_sdi_i : in std_ulogic; -- controller data in, peripheral data out |
spi_csn_o : out std_ulogic_vector(07 downto 0); -- SPI CS |
-- TWI -- |
twi_sda_io : inout std_logic := 'H'; -- twi serial data line |
413,6 → 414,7
CLOCK_FREQUENCY : natural := 0; -- clock frequency of clk_i in Hz |
HART_ID : std_ulogic_vector(31 downto 0) := x"00000000"; -- custom hardware thread ID |
BOOTLOADER_USE : boolean := true; -- implement processor-internal bootloader? |
CSR_COUNTERS_USE : boolean := true; -- implement RISC-V perf. counters ([m]instret[h], [m]cycle[h], time[h])? |
-- RISC-V CPU Extensions -- |
CPU_EXTENSION_RISCV_C : boolean := false; -- implement compressed extension? |
CPU_EXTENSION_RISCV_E : boolean := false; -- implement embedded RF extension? |
471,6 → 473,7
CLOCK_FREQUENCY : natural := 0; -- clock frequency of clk_i in Hz |
HART_ID : std_ulogic_vector(31 downto 0) := x"00000000"; -- custom hardware thread ID |
BOOTLOADER_USE : boolean := true; -- implement processor-internal bootloader? |
CSR_COUNTERS_USE : boolean := true; -- implement RISC-V perf. counters ([m]instret[h], [m]cycle[h], time[h])? |
-- RISC-V CPU Extensions -- |
CPU_EXTENSION_RISCV_C : boolean := false; -- implement compressed extension? |
CPU_EXTENSION_RISCV_E : boolean := false; -- implement embedded RF extension? |
515,8 → 518,9
alu_add_i : in std_ulogic_vector(data_width_c-1 downto 0); -- ALU.add result |
-- data output -- |
imm_o : out std_ulogic_vector(data_width_c-1 downto 0); -- immediate |
pc_o : out std_ulogic_vector(data_width_c-1 downto 0); -- current PC |
alu_pc_o : out std_ulogic_vector(data_width_c-1 downto 0); -- delayed PC for ALU |
fetch_pc_o : out std_ulogic_vector(data_width_c-1 downto 0); -- PC for instruction fetch |
curr_pc_o : out std_ulogic_vector(data_width_c-1 downto 0); -- current PC (corresponding to current instruction) |
next_pc_o : out std_ulogic_vector(data_width_c-1 downto 0); -- next PC (corresponding to current instruction) |
-- csr interface -- |
csr_wdata_i : in std_ulogic_vector(data_width_c-1 downto 0); -- CSR write data |
csr_rdata_o : out std_ulogic_vector(data_width_c-1 downto 0); -- CSR read data |
531,7 → 535,8
be_instr_i : in std_ulogic; -- bus error on instruction access |
be_load_i : in std_ulogic; -- bus error on load data access |
be_store_i : in std_ulogic; -- bus error on store data access |
bus_exc_ack_o : out std_ulogic -- bus exception error acknowledge |
bus_exc_ack_o : out std_ulogic; -- bus exception error acknowledge |
bus_busy_i : in std_ulogic -- bus unit is busy |
); |
end component; |
|
559,10 → 564,6
-- Component: CPU ALU --------------------------------------------------------------------- |
-- ------------------------------------------------------------------------------------------- |
component neorv32_cpu_alu |
generic ( |
CPU_EXTENSION_RISCV_C : boolean := false; -- implement compressed extension? |
CPU_EXTENSION_RISCV_M : boolean := false -- implement mul/div extension? |
); |
port ( |
-- global control -- |
clk_i : in std_ulogic; -- global clock, rising edge |
571,7 → 572,6
-- data input -- |
rs1_i : in std_ulogic_vector(data_width_c-1 downto 0); -- rf source 1 |
rs2_i : in std_ulogic_vector(data_width_c-1 downto 0); -- rf source 2 |
pc_i : in std_ulogic_vector(data_width_c-1 downto 0); -- current PC |
pc2_i : in std_ulogic_vector(data_width_c-1 downto 0); -- delayed PC |
imm_i : in std_ulogic_vector(data_width_c-1 downto 0); -- immediate |
csr_i : in std_ulogic_vector(data_width_c-1 downto 0); -- csr read data |
610,8 → 610,7
-- ------------------------------------------------------------------------------------------- |
component neorv32_cpu_bus |
generic ( |
CPU_EXTENSION_RISCV_C : boolean := false; -- implement compressed extension? |
MEM_EXT_TIMEOUT : natural := 15 -- cycles after which a valid bus access will timeout |
MEM_EXT_TIMEOUT : natural := 15 -- cycles after which a valid bus access will timeout |
); |
port ( |
-- global control -- |
634,6 → 633,7
be_load_o : out std_ulogic; -- bus error on load data access |
be_store_o : out std_ulogic; -- bus error on store data |
bus_wait_o : out std_ulogic; -- wait for bus operation to finish |
bus_busy_o : out std_ulogic; -- bus unit is busy |
exc_ack_i : in std_ulogic; -- exception controller ACK |
-- bus system -- |
bus_addr_o : out std_ulogic_vector(data_width_c-1 downto 0); -- bus access address |
654,7 → 654,6
-- instruction input -- |
ci_instr16_i : in std_ulogic_vector(15 downto 0); -- compressed instruction input |
-- instruction output -- |
ci_valid_o : out std_ulogic; -- is a compressed instruction |
ci_illegal_o : out std_ulogic; -- is an illegal compressed instruction |
ci_instr32_o : out std_ulogic_vector(31 downto 0) -- 32-bit decompressed instruction |
); |
838,9 → 837,9
clkgen_en_o : out std_ulogic; -- enable clock generator |
clkgen_i : in std_ulogic_vector(07 downto 0); |
-- com lines -- |
spi_sclk_o : out std_ulogic; -- SPI serial clock |
spi_mosi_o : out std_ulogic; -- SPI master out, slave in |
spi_miso_i : in std_ulogic; -- SPI master in, slave out |
spi_sck_o : out std_ulogic; -- SPI serial clock |
spi_sdo_o : out std_ulogic; -- controller data out, peripheral data in |
spi_sdi_i : in std_ulogic; -- controller data in, peripheral data out |
spi_csn_o : out std_ulogic_vector(07 downto 0); -- SPI CS |
-- interrupt -- |
spi_irq_o : out std_ulogic -- transmission done interrupt |
1063,4 → 1062,31
return tmp_v; |
end function xnor_all_f; |
|
-- Function: Convert to hex char ---------------------------------------------------------- |
-- ------------------------------------------------------------------------------------------- |
function to_hexchar_f(input : std_ulogic_vector(3 downto 0)) return character is |
variable output_v : character; |
begin |
case input is |
when x"0" => output_v := '0'; |
when x"1" => output_v := '1'; |
when x"2" => output_v := '2'; |
when x"3" => output_v := '3'; |
when x"4" => output_v := '4'; |
when x"5" => output_v := '5'; |
when x"6" => output_v := '6'; |
when x"7" => output_v := '7'; |
when x"8" => output_v := '8'; |
when x"9" => output_v := '9'; |
when x"a" => output_v := 'a'; |
when x"b" => output_v := 'b'; |
when x"c" => output_v := 'c'; |
when x"d" => output_v := 'd'; |
when x"e" => output_v := 'e'; |
when x"f" => output_v := 'f'; |
when others => output_v := '?'; |
end case; |
return output_v; |
end function to_hexchar_f; |
|
end neorv32_package; |
/rtl/core/neorv32_spi.vhd
1,5 → 1,5
-- ################################################################################################# |
-- # << NEORV32 - Serial Peripheral Interface Master (SPI) >> # |
-- # << NEORV32 - Serial Peripheral Interface Controller (SPI) >> # |
-- # ********************************************************************************************* # |
-- # Frame format: 8/16/24/32-bit RTX, MSB or LSB first, 2 clock modes, 8 clock speeds, # |
-- # 8 dedicated CS lines (low-active). Interrupt: SPI_transfer_done # |
57,9 → 57,9
clkgen_en_o : out std_ulogic; -- enable clock generator |
clkgen_i : in std_ulogic_vector(07 downto 0); |
-- com lines -- |
spi_sclk_o : out std_ulogic; -- SPI serial clock |
spi_mosi_o : out std_ulogic; -- SPI master out, slave in |
spi_miso_i : in std_ulogic; -- SPI master in, slave out |
spi_sck_o : out std_ulogic; -- SPI serial clock |
spi_sdo_o : out std_ulogic; -- controller data out, peripheral data in |
spi_sdi_i : in std_ulogic; -- controller data in, peripheral data out |
spi_csn_o : out std_ulogic_vector(07 downto 0); -- SPI CS |
-- interrupt -- |
spi_irq_o : out std_ulogic -- transmission done interrupt |
116,8 → 116,8
signal spi_rtx_sreg : std_ulogic_vector(31 downto 0); |
signal spi_rx_data : std_ulogic_vector(31 downto 0); |
signal spi_bitcnt : std_ulogic_vector(05 downto 0); |
signal spi_miso_ff0 : std_ulogic; |
signal spi_miso_ff1 : std_ulogic; |
signal spi_sdi_ff0 : std_ulogic; |
signal spi_sdi_ff1 : std_ulogic; |
|
begin |
|
217,9 → 217,9
spi_rtx_unit: process(clk_i) |
begin |
if rising_edge(clk_i) then |
-- input (MISO) synchronizer -- |
spi_miso_ff0 <= spi_miso_i; |
spi_miso_ff1 <= spi_miso_ff0; |
-- input (sdi) synchronizer -- |
spi_sdi_ff0 <= spi_sdi_i; |
spi_sdi_ff1 <= spi_sdi_ff0; |
|
-- serial engine -- |
spi_irq_o <= '0'; |
231,8 → 231,8
when others => spi_bitcnt <= "100000"; -- 32-bit mode |
end case; |
spi_state1 <= '0'; |
spi_mosi_o <= '0'; |
spi_sclk_o <= '0'; |
spi_sdo_o <= '0'; |
spi_sck_o <= '0'; |
if (ctrl(ctrl_spi_en_c) = '0') then -- disabled |
spi_busy <= '0'; |
elsif (spi_start = '1') then -- start new transmission |
249,19 → 249,19
else -- transmission in progress |
if (spi_state1 = '0') then -- first half of transmission |
|
spi_sclk_o <= ctrl(ctrl_spi_cpha_c); |
spi_sck_o <= ctrl(ctrl_spi_cpha_c); |
if (ctrl(ctrl_spi_dir_c) = '0') then |
spi_mosi_o <= spi_rtx_sreg(31); -- MSB first |
spi_sdo_o <= spi_rtx_sreg(31); -- MSB first |
else |
spi_mosi_o <= spi_rtx_sreg(0); -- LSB first |
spi_sdo_o <= spi_rtx_sreg(0); -- LSB first |
end if; |
if (spi_clk = '1') then |
spi_state1 <= '1'; |
if (ctrl(ctrl_spi_cpha_c) = '0') then |
if (ctrl(ctrl_spi_dir_c) = '0') then |
spi_rtx_sreg <= spi_rtx_sreg(30 downto 0) & spi_miso_ff1; -- MSB first |
spi_rtx_sreg <= spi_rtx_sreg(30 downto 0) & spi_sdi_ff1; -- MSB first |
else |
spi_rtx_sreg <= spi_miso_ff1 & spi_rtx_sreg(31 downto 1); -- LSB first |
spi_rtx_sreg <= spi_sdi_ff1 & spi_rtx_sreg(31 downto 1); -- LSB first |
end if; |
end if; |
spi_bitcnt <= std_ulogic_vector(unsigned(spi_bitcnt) - 1); |
268,14 → 268,14
end if; |
else -- second half of transmission |
|
spi_sclk_o <= not ctrl(ctrl_spi_cpha_c); |
spi_sck_o <= not ctrl(ctrl_spi_cpha_c); |
if (spi_clk = '1') then |
spi_state1 <= '0'; |
if (ctrl(ctrl_spi_cpha_c) = '1') then |
if (ctrl(ctrl_spi_dir_c) = '0') then |
spi_rtx_sreg <= spi_rtx_sreg(30 downto 0) & spi_miso_ff1; -- MSB first |
spi_rtx_sreg <= spi_rtx_sreg(30 downto 0) & spi_sdi_ff1; -- MSB first |
else |
spi_rtx_sreg <= spi_miso_ff1 & spi_rtx_sreg(31 downto 1); -- LSB first |
spi_rtx_sreg <= spi_sdi_ff1 & spi_rtx_sreg(31 downto 1); -- LSB first |
end if; |
end if; |
if (spi_bitcnt = "000000") then |
/rtl/core/neorv32_top.vhd
50,6 → 50,7
CLOCK_FREQUENCY : natural := 0; -- clock frequency of clk_i in Hz |
HART_ID : std_ulogic_vector(31 downto 0) := x"00000000"; -- custom hardware thread ID |
BOOTLOADER_USE : boolean := true; -- implement processor-internal bootloader? |
CSR_COUNTERS_USE : boolean := true; -- implement RISC-V perf. counters ([m]instret[h], [m]cycle[h], time[h])? |
-- RISC-V CPU Extensions -- |
CPU_EXTENSION_RISCV_C : boolean := false; -- implement compressed extension? |
CPU_EXTENSION_RISCV_E : boolean := false; -- implement embedded RF extension? |
103,9 → 104,9
uart_txd_o : out std_ulogic; -- UART send data |
uart_rxd_i : in std_ulogic := '0'; -- UART receive data |
-- SPI (available if IO_SPI_USE = true) -- |
spi_sclk_o : out std_ulogic; -- serial clock line |
spi_mosi_o : out std_ulogic; -- serial data line out |
spi_miso_i : in std_ulogic := '0'; -- serial data line in |
spi_sck_o : out std_ulogic; -- SPI serial clock |
spi_sdo_o : out std_ulogic; -- controller data out, peripheral data in |
spi_sdi_i : in std_ulogic; -- controller data in, peripheral data out |
spi_csn_o : out std_ulogic_vector(07 downto 0); -- SPI CS |
-- TWI (available if IO_TWI_USE = true) -- |
twi_sda_io : inout std_logic := 'H'; -- twi serial data line |
315,6 → 316,7
CLOCK_FREQUENCY => CLOCK_FREQUENCY, -- clock frequency of clk_i in Hz |
HART_ID => HART_ID, -- custom hardware thread ID |
BOOTLOADER_USE => BOOTLOADER_USE, -- implement processor-internal bootloader? |
CSR_COUNTERS_USE => CSR_COUNTERS_USE, -- implement RISC-V perf. counters ([m]instret[h], [m]cycle[h], time[h])? |
-- RISC-V CPU Extensions -- |
CPU_EXTENSION_RISCV_C => CPU_EXTENSION_RISCV_C, -- implement compressed extension? |
CPU_EXTENSION_RISCV_E => CPU_EXTENSION_RISCV_E, -- implement embedded RF extension? |
719,9 → 721,9
clkgen_en_o => spi_cg_en, -- enable clock generator |
clkgen_i => clk_gen, |
-- com lines -- |
spi_sclk_o => spi_sclk_o, -- SPI serial clock |
spi_mosi_o => spi_mosi_o, -- SPI master out, slave in |
spi_miso_i => spi_miso_i, -- SPI master in, slave out |
spi_sck_o => spi_sck_o, -- SPI serial clock |
spi_sdo_o => spi_sdo_o, -- controller data out, peripheral data in |
spi_sdi_i => spi_sdi_i, -- controller data in, peripheral data out |
spi_csn_o => spi_csn_o, -- SPI CS |
-- interrupt -- |
spi_irq_o => spi_irq -- transmission done interrupt |
732,8 → 734,8
if (IO_SPI_USE = false) generate |
spi_rdata <= (others => '0'); |
spi_ack <= '0'; |
spi_sclk_o <= '0'; |
spi_mosi_o <= '0'; |
spi_sck_o <= '0'; |
spi_sdo_o <= '0'; |
spi_csn_o <= (others => '1'); -- CSn lines are low-active |
spi_cg_en <= '0'; |
spi_irq <= '0'; |
/rtl/core/neorv32_twi.vhd
1,9 → 1,9
-- ################################################################################################# |
-- # << NEORV32 - Two-Wire Interface Master (TWI) >> # |
-- # << NEORV32 - Two-Wire Interface Controller (TWI) >> # |
-- # ********************************************************************************************* # |
-- # Supports START and STOP conditions, 8 bit data + ACK/NACK transfers and clock stretching. # |
-- # Supports ACKs by the master. No multi-master support and no slave mode support yet! # |
-- # Interrupt: TWI_transfer_done # |
-- # Supports ACKs by the constroller. No multi-controller support and no peripheral mode support # |
-- # yet. Interrupt: TWI_transfer_done # |
-- # ********************************************************************************************* # |
-- # BSD 3-Clause License # |
-- # # |
79,7 → 79,7
constant ctrl_twi_prsc0_c : natural := 4; -- r/w: CLK prsc bit 0 |
constant ctrl_twi_prsc1_c : natural := 5; -- r/w: CLK prsc bit 1 |
constant ctrl_twi_prsc2_c : natural := 6; -- r/w: CLK prsc bit 2 |
constant ctrl_twi_mack_c : natural := 7; -- r/w: generate ACK by master for transmission |
constant ctrl_twi_mack_c : natural := 7; -- r/w: generate ACK by controller for transmission |
-- |
constant ctrl_twi_ack_c : natural := 30; -- r/-: Set if ACK received |
constant ctrl_twi_busy_c : natural := 31; -- r/-: Set if TWI unit is busy |
201,7 → 201,7
-- TWI bus signals are set/sampled using 4 clock phases |
case arbiter is |
|
when "100" => -- IDLE: waiting for requests, bus might be still claimed by this master if no STOP condition was generated |
when "100" => -- IDLE: waiting for requests, bus might be still claimed by this controller if no STOP condition was generated |
twi_bitcnt <= (others => '0'); |
if (wr_en = '1') then |
if (addr = twi_ctrl_addr_c) then |
211,8 → 211,8
arbiter(1 downto 0) <= "10"; |
end if; |
elsif (addr = twi_rtx_addr_c) then -- start a data transmission |
-- one bit extra for ack, issued by master if ctrl_twi_mack_c is set, |
-- sampled from slave if ctrl_twi_mack_c is cleared |
-- one bit extra for ack, issued by controller if ctrl_twi_mack_c is set, |
-- sampled from peripheral if ctrl_twi_mack_c is cleared |
if (ben_i(0) = '1') then |
twi_rtx_sreg <= data_i(7 downto 0) & (not ctrl(ctrl_twi_mack_c)); |
arbiter(1 downto 0) <= "11"; |
279,10 → 279,10
-- ------------------------------------------------------------------------------------------- |
clock_stretching: process(arbiter, twi_scl_o, twi_scl_i_ff1) |
begin |
-- clock stretching by the slave can happen at "any time" |
-- clock stretching by the peripheral can happen at "any time" |
if (arbiter(2) = '1') and -- module enabled |
(twi_scl_o = '1') and -- master wants to pull scl high |
(twi_scl_i_ff1 = '0') then -- but scl is pulled low by slave |
(twi_scl_o = '1') and -- controller wants to pull scl high |
(twi_scl_i_ff1 = '0') then -- but scl is pulled low by peripheral |
twi_clk_halt <= '1'; |
else |
twi_clk_halt <= '0'; |
/rtl/top_templates/neorv32_test_setup.vhd
72,6 → 72,7
CLOCK_FREQUENCY => 100000000, -- clock frequency of clk_i in Hz |
HART_ID => x"00000000", -- custom hardware thread ID |
BOOTLOADER_USE => true, -- implement processor-internal bootloader? |
CSR_COUNTERS_USE => true, -- implement RISC-V perf. counters ([m]instret[h], [m]cycle[h], time[h])? |
-- RISC-V CPU Extensions -- |
CPU_EXTENSION_RISCV_C => false, -- implement compressed extension? |
CPU_EXTENSION_RISCV_E => false, -- implement embedded RF extension? |
125,9 → 126,9
uart_txd_o => uart_txd_o, -- UART send data |
uart_rxd_i => uart_rxd_i, -- UART receive data |
-- SPI -- |
spi_sclk_o => open, -- serial clock line |
spi_mosi_o => open, -- serial data line out |
spi_miso_i => '0', -- serial data line in |
spi_sck_o => open, -- SPI serial clock |
spi_sdo_o => open, -- controller data out, peripheral data in |
spi_sdi_i => '0', -- controller data in, peripheral data out |
spi_csn_o => open, -- SPI CS |
-- TWI -- |
twi_sda_io => open, -- twi serial data line |
/sim/ghdl/ghdl_sim.sh
3,6 → 3,9
# Abort if any command returns != 0 |
set -e |
|
# Simulation config |
SIM_CONFIG=--stop-time=5ms |
|
# Project home folder |
homedir="$( cd "$(dirname "$0")" >/dev/null 2>&1 ; pwd -P )" |
homedir=$homedir/../.. |
11,6 → 14,9
srcdir_core=$homedir/rtl/core |
srcdir_sim=$homedir/sim |
|
# Simulation time define by user? |
if [ -z ${1} ]; then echo "Using default simulation config: $SIM_CONFIG"; else SIM_CONFIG=$1; echo "Using user simulation config: $SIM_CONFIG"; fi |
|
# Show GHDL version |
ghdl -v |
|
21,7 → 27,7
|
# Just a hint |
echo "" |
echo "Compile application with USER_FLAGS+=-DDEVNULL_UART_OVERRIDE to have faster UART/console output." |
echo "Tip: Compile application with USER_FLAGS+=-DDEVNULL_UART_OVERRIDE to have faster UART/console output." |
echo "" |
|
# Analyse sources; libs and images at first! |
59,7 → 65,9
chmod 777 neorv32.testbench_uart.out |
touch neorv32.devnull.out |
chmod 777 neorv32.devnull.out |
touch neorv32.devnull.data.out |
chmod 777 neorv32.devnull.data.out |
|
# Run simulation |
ghdl -e --work=neorv32 neorv32_tb |
ghdl -r --work=neorv32 neorv32_tb --stop-time=4ms --ieee-asserts=disable --assert-level=error |
ghdl -r --work=neorv32 neorv32_tb --ieee-asserts=disable --assert-level=error $SIM_CONFIG |
/sim/vivado/neorv32_tb_behav.wcfg
0,0 → 1,791
<?xml version="1.0" encoding="UTF-8"?> |
<wave_config> |
<wave_state> |
</wave_state> |
<db_ref_list> |
<db_ref path="neorv32_tb_behav.wdb" id="1"> |
<top_modules> |
<top_module name="neorv32_application_image" /> |
<top_module name="neorv32_package" /> |
<top_module name="neorv32_tb" /> |
</top_modules> |
</db_ref> |
</db_ref_list> |
<zoom_setting> |
<ZoomStartTime time="1950430583fs"></ZoomStartTime> |
<ZoomEndTime time="1950447384fs"></ZoomEndTime> |
<Cursor1Time time="1950490183fs"></Cursor1Time> |
</zoom_setting> |
<column_width_setting> |
<NameColumnWidth column_width="178"></NameColumnWidth> |
<ValueColumnWidth column_width="131"></ValueColumnWidth> |
</column_width_setting> |
<WVObjectSize size="156" /> |
<wvobject type="divider" fp_name="divider273"> |
<obj_property name="label">CPU: Control.FETCH</obj_property> |
<obj_property name="DisplayName">label</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/clk_i" type="logic"> |
<obj_property name="ElementShortName">clk_i</obj_property> |
<obj_property name="ObjectShortName">clk_i</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/rstn_i" type="logic"> |
<obj_property name="ElementShortName">rstn_i</obj_property> |
<obj_property name="ObjectShortName">rstn_i</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/bus_wait_i" type="logic"> |
<obj_property name="ElementShortName">bus_wait_i</obj_property> |
<obj_property name="ObjectShortName">bus_wait_i</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/bus_fast_ir" type="logic"> |
<obj_property name="ElementShortName">bus_fast_ir</obj_property> |
<obj_property name="ObjectShortName">bus_fast_ir</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/ma_instr_i" type="logic"> |
<obj_property name="ElementShortName">ma_instr_i</obj_property> |
<obj_property name="ObjectShortName">ma_instr_i</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/be_instr_i" type="logic"> |
<obj_property name="ElementShortName">be_instr_i</obj_property> |
<obj_property name="ObjectShortName">be_instr_i</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/instr_i" type="array"> |
<obj_property name="ElementShortName">instr_i[31:0]</obj_property> |
<obj_property name="ObjectShortName">instr_i[31:0]</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/ci_instr32" type="array"> |
<obj_property name="ElementShortName">ci_instr32[31:0]</obj_property> |
<obj_property name="ObjectShortName">ci_instr32[31:0]</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/ci_illegal" type="logic"> |
<obj_property name="ElementShortName">ci_illegal</obj_property> |
<obj_property name="ObjectShortName">ci_illegal</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/fetch_engine" type="array"> |
<obj_property name="ElementShortName">fetch_engine</obj_property> |
<obj_property name="ObjectShortName">fetch_engine</obj_property> |
<obj_property name="isExpanded"></obj_property> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/fetch_engine.state" type="other"> |
<obj_property name="ElementShortName">.state</obj_property> |
<obj_property name="ObjectShortName">.state</obj_property> |
<obj_property name="CustomSignalColor">#FFD700</obj_property> |
<obj_property name="UseCustomSignalColor">true</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/fetch_engine.state_nxt" type="other"> |
<obj_property name="ElementShortName">.state_nxt</obj_property> |
<obj_property name="ObjectShortName">.state_nxt</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/fetch_engine.i_buf" type="array"> |
<obj_property name="ElementShortName">.i_buf[33:0]</obj_property> |
<obj_property name="ObjectShortName">.i_buf[33:0]</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/fetch_engine.i_buf_nxt" type="array"> |
<obj_property name="ElementShortName">.i_buf_nxt[33:0]</obj_property> |
<obj_property name="ObjectShortName">.i_buf_nxt[33:0]</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/fetch_engine.i_buf2" type="array"> |
<obj_property name="ElementShortName">.i_buf2[33:0]</obj_property> |
<obj_property name="ObjectShortName">.i_buf2[33:0]</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/fetch_engine.i_buf2_nxt" type="array"> |
<obj_property name="ElementShortName">.i_buf2_nxt[33:0]</obj_property> |
<obj_property name="ObjectShortName">.i_buf2_nxt[33:0]</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/fetch_engine.ci_reg" type="array"> |
<obj_property name="ElementShortName">.ci_reg[17:0]</obj_property> |
<obj_property name="ObjectShortName">.ci_reg[17:0]</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/fetch_engine.ci_reg_nxt" type="array"> |
<obj_property name="ElementShortName">.ci_reg_nxt[17:0]</obj_property> |
<obj_property name="ObjectShortName">.ci_reg_nxt[17:0]</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/fetch_engine.i_buf_state" type="array"> |
<obj_property name="ElementShortName">.i_buf_state[1:0]</obj_property> |
<obj_property name="ObjectShortName">.i_buf_state[1:0]</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/fetch_engine.i_buf_state_nxt" type="array"> |
<obj_property name="ElementShortName">.i_buf_state_nxt[1:0]</obj_property> |
<obj_property name="ObjectShortName">.i_buf_state_nxt[1:0]</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/fetch_engine.pc_real" type="array"> |
<obj_property name="ElementShortName">.pc_real[31:0]</obj_property> |
<obj_property name="ObjectShortName">.pc_real[31:0]</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/fetch_engine.pc_real_add" type="array"> |
<obj_property name="ElementShortName">.pc_real_add[31:0]</obj_property> |
<obj_property name="ObjectShortName">.pc_real_add[31:0]</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/fetch_engine.pc_fetch" type="array"> |
<obj_property name="ElementShortName">.pc_fetch[31:0]</obj_property> |
<obj_property name="ObjectShortName">.pc_fetch[31:0]</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/fetch_engine.pc_fetch_add" type="array"> |
<obj_property name="ElementShortName">.pc_fetch_add[31:0]</obj_property> |
<obj_property name="ObjectShortName">.pc_fetch_add[31:0]</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/fetch_engine.ci_return" type="logic"> |
<obj_property name="ElementShortName">.ci_return</obj_property> |
<obj_property name="ObjectShortName">.ci_return</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/fetch_engine.ci_return_nxt" type="logic"> |
<obj_property name="ElementShortName">.ci_return_nxt</obj_property> |
<obj_property name="ObjectShortName">.ci_return_nxt</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/fetch_engine.reset" type="logic"> |
<obj_property name="ElementShortName">.reset</obj_property> |
<obj_property name="ObjectShortName">.reset</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/fetch_engine.bus_err_ack" type="logic"> |
<obj_property name="ElementShortName">.bus_err_ack</obj_property> |
<obj_property name="ObjectShortName">.bus_err_ack</obj_property> |
</wvobject> |
</wvobject> |
<wvobject type="divider" fp_name="divider273"> |
<obj_property name="label">CPU: Control.IPB</obj_property> |
<obj_property name="DisplayName">label</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/ipb" type="array"> |
<obj_property name="ElementShortName">ipb</obj_property> |
<obj_property name="ObjectShortName">ipb</obj_property> |
</wvobject> |
<wvobject type="divider" fp_name="divider273"> |
<obj_property name="label">CPU: Control.EXE</obj_property> |
<obj_property name="DisplayName">label</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/alu_wait_i" type="logic"> |
<obj_property name="ElementShortName">alu_wait_i</obj_property> |
<obj_property name="ObjectShortName">alu_wait_i</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/bus_wait_i" type="logic"> |
<obj_property name="ElementShortName">bus_wait_i</obj_property> |
<obj_property name="ObjectShortName">bus_wait_i</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/instr_i" type="array"> |
<obj_property name="ElementShortName">instr_i[31:0]</obj_property> |
<obj_property name="ObjectShortName">instr_i[31:0]</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/cmp_i" type="array"> |
<obj_property name="ElementShortName">cmp_i[1:0]</obj_property> |
<obj_property name="ObjectShortName">cmp_i[1:0]</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/alu_add_i" type="array"> |
<obj_property name="ElementShortName">alu_add_i[31:0]</obj_property> |
<obj_property name="ObjectShortName">alu_add_i[31:0]</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/imm_o" type="array"> |
<obj_property name="ElementShortName">imm_o[31:0]</obj_property> |
<obj_property name="ObjectShortName">imm_o[31:0]</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/csr_wdata_i" type="array"> |
<obj_property name="ElementShortName">csr_wdata_i[31:0]</obj_property> |
<obj_property name="ObjectShortName">csr_wdata_i[31:0]</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/csr_rdata_o" type="array"> |
<obj_property name="ElementShortName">csr_rdata_o[31:0]</obj_property> |
<obj_property name="ObjectShortName">csr_rdata_o[31:0]</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/clic_irq_i" type="logic"> |
<obj_property name="ElementShortName">clic_irq_i</obj_property> |
<obj_property name="ObjectShortName">clic_irq_i</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/mtime_irq_i" type="logic"> |
<obj_property name="ElementShortName">mtime_irq_i</obj_property> |
<obj_property name="ObjectShortName">mtime_irq_i</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/mar_i" type="array"> |
<obj_property name="ElementShortName">mar_i[31:0]</obj_property> |
<obj_property name="ObjectShortName">mar_i[31:0]</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/ma_load_i" type="logic"> |
<obj_property name="ElementShortName">ma_load_i</obj_property> |
<obj_property name="ObjectShortName">ma_load_i</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/ma_store_i" type="logic"> |
<obj_property name="ElementShortName">ma_store_i</obj_property> |
<obj_property name="ObjectShortName">ma_store_i</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/be_load_i" type="logic"> |
<obj_property name="ElementShortName">be_load_i</obj_property> |
<obj_property name="ObjectShortName">be_load_i</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/be_store_i" type="logic"> |
<obj_property name="ElementShortName">be_store_i</obj_property> |
<obj_property name="ObjectShortName">be_store_i</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/bus_exc_ack_o" type="logic"> |
<obj_property name="ElementShortName">bus_exc_ack_o</obj_property> |
<obj_property name="ObjectShortName">bus_exc_ack_o</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/ctrl" type="array"> |
<obj_property name="ElementShortName">ctrl[47:0]</obj_property> |
<obj_property name="ObjectShortName">ctrl[47:0]</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/ctrl_o" type="array"> |
<obj_property name="ElementShortName">ctrl_o[47:0]</obj_property> |
<obj_property name="ObjectShortName">ctrl_o[47:0]</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/bus_fast_rd" type="logic"> |
<obj_property name="ElementShortName">bus_fast_rd</obj_property> |
<obj_property name="ObjectShortName">bus_fast_rd</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/bus_fast_wr" type="logic"> |
<obj_property name="ElementShortName">bus_fast_wr</obj_property> |
<obj_property name="ObjectShortName">bus_fast_wr</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/ci_instr32" type="array"> |
<obj_property name="ElementShortName">ci_instr32[31:0]</obj_property> |
<obj_property name="ObjectShortName">ci_instr32[31:0]</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/ci_illegal" type="logic"> |
<obj_property name="ElementShortName">ci_illegal</obj_property> |
<obj_property name="ObjectShortName">ci_illegal</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/fetch_pc_o" type="array"> |
<obj_property name="ElementShortName">fetch_pc_o[31:0]</obj_property> |
<obj_property name="ObjectShortName">fetch_pc_o[31:0]</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/curr_pc_o" type="array"> |
<obj_property name="ElementShortName">curr_pc_o[31:0]</obj_property> |
<obj_property name="ObjectShortName">curr_pc_o[31:0]</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/next_pc_o" type="array"> |
<obj_property name="ElementShortName">next_pc_o[31:0]</obj_property> |
<obj_property name="ObjectShortName">next_pc_o[31:0]</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/illegal_instruction" type="logic"> |
<obj_property name="ElementShortName">illegal_instruction</obj_property> |
<obj_property name="ObjectShortName">illegal_instruction</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/illegal_register" type="logic"> |
<obj_property name="ElementShortName">illegal_register</obj_property> |
<obj_property name="ObjectShortName">illegal_register</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/illegal_compressed" type="logic"> |
<obj_property name="ElementShortName">illegal_compressed</obj_property> |
<obj_property name="ObjectShortName">illegal_compressed</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/execute_engine" type="array"> |
<obj_property name="ElementShortName">execute_engine</obj_property> |
<obj_property name="ObjectShortName">execute_engine</obj_property> |
<obj_property name="isExpanded"></obj_property> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/execute_engine.state" type="other"> |
<obj_property name="ElementShortName">.state</obj_property> |
<obj_property name="ObjectShortName">.state</obj_property> |
<obj_property name="CustomSignalColor">#FFD700</obj_property> |
<obj_property name="UseCustomSignalColor">true</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/execute_engine.state_nxt" type="other"> |
<obj_property name="ElementShortName">.state_nxt</obj_property> |
<obj_property name="ObjectShortName">.state_nxt</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/execute_engine.state_prev" type="other"> |
<obj_property name="ElementShortName">.state_prev</obj_property> |
<obj_property name="ObjectShortName">.state_prev</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/execute_engine.i_reg" type="array"> |
<obj_property name="ElementShortName">.i_reg[31:0]</obj_property> |
<obj_property name="ObjectShortName">.i_reg[31:0]</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/execute_engine.i_reg_nxt" type="array"> |
<obj_property name="ElementShortName">.i_reg_nxt[31:0]</obj_property> |
<obj_property name="ObjectShortName">.i_reg_nxt[31:0]</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/execute_engine.is_ci" type="logic"> |
<obj_property name="ElementShortName">.is_ci</obj_property> |
<obj_property name="ObjectShortName">.is_ci</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/execute_engine.is_ci_nxt" type="logic"> |
<obj_property name="ElementShortName">.is_ci_nxt</obj_property> |
<obj_property name="ObjectShortName">.is_ci_nxt</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/execute_engine.is_jump" type="logic"> |
<obj_property name="ElementShortName">.is_jump</obj_property> |
<obj_property name="ObjectShortName">.is_jump</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/execute_engine.is_jump_nxt" type="logic"> |
<obj_property name="ElementShortName">.is_jump_nxt</obj_property> |
<obj_property name="ObjectShortName">.is_jump_nxt</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/execute_engine.branch_taken" type="logic"> |
<obj_property name="ElementShortName">.branch_taken</obj_property> |
<obj_property name="ObjectShortName">.branch_taken</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/execute_engine.pc" type="array"> |
<obj_property name="ElementShortName">.pc[31:0]</obj_property> |
<obj_property name="ObjectShortName">.pc[31:0]</obj_property> |
<obj_property name="CustomSignalColor">#FFFFFF</obj_property> |
<obj_property name="UseCustomSignalColor">true</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/execute_engine.pc_nxt" type="array"> |
<obj_property name="ElementShortName">.pc_nxt[31:0]</obj_property> |
<obj_property name="ObjectShortName">.pc_nxt[31:0]</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/execute_engine.next_pc" type="array"> |
<obj_property name="ElementShortName">.next_pc[31:0]</obj_property> |
<obj_property name="ObjectShortName">.next_pc[31:0]</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/execute_engine.last_pc" type="array"> |
<obj_property name="ElementShortName">.last_pc[31:0]</obj_property> |
<obj_property name="ObjectShortName">.last_pc[31:0]</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/execute_engine.pc_we" type="logic"> |
<obj_property name="ElementShortName">.pc_we</obj_property> |
<obj_property name="ObjectShortName">.pc_we</obj_property> |
</wvobject> |
</wvobject> |
<wvobject type="divider" fp_name="divider139"> |
<obj_property name="label">CPU: Control.TRAP</obj_property> |
<obj_property name="DisplayName">label</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/trap_ctrl" type="array"> |
<obj_property name="ElementShortName">trap_ctrl</obj_property> |
<obj_property name="ObjectShortName">trap_ctrl</obj_property> |
<obj_property name="isExpanded"></obj_property> |
</wvobject> |
<wvobject type="divider" fp_name="divider139"> |
<obj_property name="label">CPU: Control.CSR</obj_property> |
<obj_property name="DisplayName">label</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/csr" type="array"> |
<obj_property name="ElementShortName">csr</obj_property> |
<obj_property name="ObjectShortName">csr</obj_property> |
<obj_property name="isExpanded"></obj_property> |
</wvobject> |
<wvobject type="divider" fp_name="divider139"> |
<obj_property name="label">CPU: RegFile</obj_property> |
<obj_property name="DisplayName">label</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_regfile_inst/reg_file" type="array"> |
<obj_property name="ElementShortName">reg_file[31:0][31:0]</obj_property> |
<obj_property name="ObjectShortName">reg_file[31:0][31:0]</obj_property> |
</wvobject> |
<wvobject type="divider" fp_name="divider367"> |
<obj_property name="label">CPU: ALU</obj_property> |
<obj_property name="DisplayName">label</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_alu_inst/clk_i" type="logic"> |
<obj_property name="ElementShortName">clk_i</obj_property> |
<obj_property name="ObjectShortName">clk_i</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_alu_inst/rstn_i" type="logic"> |
<obj_property name="ElementShortName">rstn_i</obj_property> |
<obj_property name="ObjectShortName">rstn_i</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_alu_inst/ctrl_i" type="array"> |
<obj_property name="ElementShortName">ctrl_i[47:0]</obj_property> |
<obj_property name="ObjectShortName">ctrl_i[47:0]</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_alu_inst/rs1_i" type="array"> |
<obj_property name="ElementShortName">rs1_i[31:0]</obj_property> |
<obj_property name="ObjectShortName">rs1_i[31:0]</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_alu_inst/rs2_i" type="array"> |
<obj_property name="ElementShortName">rs2_i[31:0]</obj_property> |
<obj_property name="ObjectShortName">rs2_i[31:0]</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_alu_inst/pc2_i" type="array"> |
<obj_property name="ElementShortName">pc2_i[31:0]</obj_property> |
<obj_property name="ObjectShortName">pc2_i[31:0]</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_alu_inst/imm_i" type="array"> |
<obj_property name="ElementShortName">imm_i[31:0]</obj_property> |
<obj_property name="ObjectShortName">imm_i[31:0]</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_alu_inst/csr_i" type="array"> |
<obj_property name="ElementShortName">csr_i[31:0]</obj_property> |
<obj_property name="ObjectShortName">csr_i[31:0]</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_alu_inst/cmp_o" type="array"> |
<obj_property name="ElementShortName">cmp_o[1:0]</obj_property> |
<obj_property name="ObjectShortName">cmp_o[1:0]</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_alu_inst/add_o" type="array"> |
<obj_property name="ElementShortName">add_o[31:0]</obj_property> |
<obj_property name="ObjectShortName">add_o[31:0]</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_alu_inst/res_o" type="array"> |
<obj_property name="ElementShortName">res_o[31:0]</obj_property> |
<obj_property name="ObjectShortName">res_o[31:0]</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_alu_inst/cp0_data_i" type="array"> |
<obj_property name="ElementShortName">cp0_data_i[31:0]</obj_property> |
<obj_property name="ObjectShortName">cp0_data_i[31:0]</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_alu_inst/cp0_valid_i" type="logic"> |
<obj_property name="ElementShortName">cp0_valid_i</obj_property> |
<obj_property name="ObjectShortName">cp0_valid_i</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_alu_inst/cp1_data_i" type="array"> |
<obj_property name="ElementShortName">cp1_data_i[31:0]</obj_property> |
<obj_property name="ObjectShortName">cp1_data_i[31:0]</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_alu_inst/cp1_valid_i" type="logic"> |
<obj_property name="ElementShortName">cp1_valid_i</obj_property> |
<obj_property name="ObjectShortName">cp1_valid_i</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_alu_inst/wait_o" type="logic"> |
<obj_property name="ElementShortName">wait_o</obj_property> |
<obj_property name="ObjectShortName">wait_o</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_alu_inst/opa" type="array"> |
<obj_property name="ElementShortName">opa[31:0]</obj_property> |
<obj_property name="ObjectShortName">opa[31:0]</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_alu_inst/opb" type="array"> |
<obj_property name="ElementShortName">opb[31:0]</obj_property> |
<obj_property name="ObjectShortName">opb[31:0]</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_alu_inst/opc" type="array"> |
<obj_property name="ElementShortName">opc[31:0]</obj_property> |
<obj_property name="ObjectShortName">opc[31:0]</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_alu_inst/add_res" type="array"> |
<obj_property name="ElementShortName">add_res[31:0]</obj_property> |
<obj_property name="ObjectShortName">add_res[31:0]</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_alu_inst/alu_res" type="array"> |
<obj_property name="ElementShortName">alu_res[31:0]</obj_property> |
<obj_property name="ObjectShortName">alu_res[31:0]</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_alu_inst/cmp_opx" type="array"> |
<obj_property name="ElementShortName">cmp_opx[32:0]</obj_property> |
<obj_property name="ObjectShortName">cmp_opx[32:0]</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_alu_inst/cmp_opy" type="array"> |
<obj_property name="ElementShortName">cmp_opy[32:0]</obj_property> |
<obj_property name="ObjectShortName">cmp_opy[32:0]</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_alu_inst/cmp_sub" type="array"> |
<obj_property name="ElementShortName">cmp_sub[32:0]</obj_property> |
<obj_property name="ObjectShortName">cmp_sub[32:0]</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_alu_inst/sub_res" type="array"> |
<obj_property name="ElementShortName">sub_res[31:0]</obj_property> |
<obj_property name="ObjectShortName">sub_res[31:0]</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_alu_inst/cmp_equal" type="logic"> |
<obj_property name="ElementShortName">cmp_equal</obj_property> |
<obj_property name="ObjectShortName">cmp_equal</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_alu_inst/cmp_less" type="logic"> |
<obj_property name="ElementShortName">cmp_less</obj_property> |
<obj_property name="ObjectShortName">cmp_less</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_alu_inst/shift_cmd" type="logic"> |
<obj_property name="ElementShortName">shift_cmd</obj_property> |
<obj_property name="ObjectShortName">shift_cmd</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_alu_inst/shift_cmd_ff" type="logic"> |
<obj_property name="ElementShortName">shift_cmd_ff</obj_property> |
<obj_property name="ObjectShortName">shift_cmd_ff</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_alu_inst/shift_start" type="logic"> |
<obj_property name="ElementShortName">shift_start</obj_property> |
<obj_property name="ObjectShortName">shift_start</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_alu_inst/shift_run" type="logic"> |
<obj_property name="ElementShortName">shift_run</obj_property> |
<obj_property name="ObjectShortName">shift_run</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_alu_inst/shift_cnt" type="array"> |
<obj_property name="ElementShortName">shift_cnt[4:0]</obj_property> |
<obj_property name="ObjectShortName">shift_cnt[4:0]</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_alu_inst/shift_sreg" type="array"> |
<obj_property name="ElementShortName">shift_sreg[31:0]</obj_property> |
<obj_property name="ObjectShortName">shift_sreg[31:0]</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_alu_inst/cp_cmd_ff" type="logic"> |
<obj_property name="ElementShortName">cp_cmd_ff</obj_property> |
<obj_property name="ObjectShortName">cp_cmd_ff</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_alu_inst/cp_run" type="logic"> |
<obj_property name="ElementShortName">cp_run</obj_property> |
<obj_property name="ObjectShortName">cp_run</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_alu_inst/cp_start" type="logic"> |
<obj_property name="ElementShortName">cp_start</obj_property> |
<obj_property name="ObjectShortName">cp_start</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_alu_inst/cp_busy" type="logic"> |
<obj_property name="ElementShortName">cp_busy</obj_property> |
<obj_property name="ObjectShortName">cp_busy</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_alu_inst/cp_rb_ff0" type="logic"> |
<obj_property name="ElementShortName">cp_rb_ff0</obj_property> |
<obj_property name="ObjectShortName">cp_rb_ff0</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_alu_inst/cp_rb_ff1" type="logic"> |
<obj_property name="ElementShortName">cp_rb_ff1</obj_property> |
<obj_property name="ObjectShortName">cp_rb_ff1</obj_property> |
</wvobject> |
<wvobject type="divider" fp_name="divider367"> |
<obj_property name="label">CPU: BUS_UNIT</obj_property> |
<obj_property name="DisplayName">label</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_bus_inst/rstn_i" type="logic"> |
<obj_property name="ElementShortName">rstn_i</obj_property> |
<obj_property name="ObjectShortName">rstn_i</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_bus_inst/clk_i" type="logic"> |
<obj_property name="ElementShortName">clk_i</obj_property> |
<obj_property name="ObjectShortName">clk_i</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_bus_inst/ctrl_i" type="array"> |
<obj_property name="ElementShortName">ctrl_i[47:0]</obj_property> |
<obj_property name="ObjectShortName">ctrl_i[47:0]</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_bus_inst/wdata_i" type="array"> |
<obj_property name="ElementShortName">wdata_i[31:0]</obj_property> |
<obj_property name="ObjectShortName">wdata_i[31:0]</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_bus_inst/pc_i" type="array"> |
<obj_property name="ElementShortName">pc_i[31:0]</obj_property> |
<obj_property name="ObjectShortName">pc_i[31:0]</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_bus_inst/alu_i" type="array"> |
<obj_property name="ElementShortName">alu_i[31:0]</obj_property> |
<obj_property name="ObjectShortName">alu_i[31:0]</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_bus_inst/instr_o" type="array"> |
<obj_property name="ElementShortName">instr_o[31:0]</obj_property> |
<obj_property name="ObjectShortName">instr_o[31:0]</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_bus_inst/rdata_o" type="array"> |
<obj_property name="ElementShortName">rdata_o[31:0]</obj_property> |
<obj_property name="ObjectShortName">rdata_o[31:0]</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_bus_inst/mar_o" type="array"> |
<obj_property name="ElementShortName">mar_o[31:0]</obj_property> |
<obj_property name="ObjectShortName">mar_o[31:0]</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_bus_inst/ma_instr_o" type="logic"> |
<obj_property name="ElementShortName">ma_instr_o</obj_property> |
<obj_property name="ObjectShortName">ma_instr_o</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_bus_inst/ma_load_o" type="logic"> |
<obj_property name="ElementShortName">ma_load_o</obj_property> |
<obj_property name="ObjectShortName">ma_load_o</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_bus_inst/ma_store_o" type="logic"> |
<obj_property name="ElementShortName">ma_store_o</obj_property> |
<obj_property name="ObjectShortName">ma_store_o</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_bus_inst/be_instr_o" type="logic"> |
<obj_property name="ElementShortName">be_instr_o</obj_property> |
<obj_property name="ObjectShortName">be_instr_o</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_bus_inst/be_load_o" type="logic"> |
<obj_property name="ElementShortName">be_load_o</obj_property> |
<obj_property name="ObjectShortName">be_load_o</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_bus_inst/be_store_o" type="logic"> |
<obj_property name="ElementShortName">be_store_o</obj_property> |
<obj_property name="ObjectShortName">be_store_o</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_bus_inst/bus_wait_o" type="logic"> |
<obj_property name="ElementShortName">bus_wait_o</obj_property> |
<obj_property name="ObjectShortName">bus_wait_o</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_bus_inst/exc_ack_i" type="logic"> |
<obj_property name="ElementShortName">exc_ack_i</obj_property> |
<obj_property name="ObjectShortName">exc_ack_i</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_bus_inst/bus_addr_o" type="array"> |
<obj_property name="ElementShortName">bus_addr_o[31:0]</obj_property> |
<obj_property name="ObjectShortName">bus_addr_o[31:0]</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_bus_inst/bus_rdata_i" type="array"> |
<obj_property name="ElementShortName">bus_rdata_i[31:0]</obj_property> |
<obj_property name="ObjectShortName">bus_rdata_i[31:0]</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_bus_inst/bus_wdata_o" type="array"> |
<obj_property name="ElementShortName">bus_wdata_o[31:0]</obj_property> |
<obj_property name="ObjectShortName">bus_wdata_o[31:0]</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_bus_inst/bus_ben_o" type="array"> |
<obj_property name="ElementShortName">bus_ben_o[3:0]</obj_property> |
<obj_property name="ObjectShortName">bus_ben_o[3:0]</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_bus_inst/bus_we_o" type="logic"> |
<obj_property name="ElementShortName">bus_we_o</obj_property> |
<obj_property name="ObjectShortName">bus_we_o</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_bus_inst/bus_re_o" type="logic"> |
<obj_property name="ElementShortName">bus_re_o</obj_property> |
<obj_property name="ObjectShortName">bus_re_o</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_bus_inst/bus_ack_i" type="logic"> |
<obj_property name="ElementShortName">bus_ack_i</obj_property> |
<obj_property name="ObjectShortName">bus_ack_i</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_bus_inst/bus_err_i" type="logic"> |
<obj_property name="ElementShortName">bus_err_i</obj_property> |
<obj_property name="ObjectShortName">bus_err_i</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_bus_inst/mar" type="array"> |
<obj_property name="ElementShortName">mar[31:0]</obj_property> |
<obj_property name="ObjectShortName">mar[31:0]</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_bus_inst/mdo" type="array"> |
<obj_property name="ElementShortName">mdo[31:0]</obj_property> |
<obj_property name="ObjectShortName">mdo[31:0]</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_bus_inst/mdi" type="array"> |
<obj_property name="ElementShortName">mdi[31:0]</obj_property> |
<obj_property name="ObjectShortName">mdi[31:0]</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_bus_inst/bus_busy" type="logic"> |
<obj_property name="ElementShortName">bus_busy</obj_property> |
<obj_property name="ObjectShortName">bus_busy</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_bus_inst/bus_if_req" type="logic"> |
<obj_property name="ElementShortName">bus_if_req</obj_property> |
<obj_property name="ObjectShortName">bus_if_req</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_bus_inst/bus_rd_req" type="logic"> |
<obj_property name="ElementShortName">bus_rd_req</obj_property> |
<obj_property name="ObjectShortName">bus_rd_req</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_bus_inst/bus_wr_req" type="logic"> |
<obj_property name="ElementShortName">bus_wr_req</obj_property> |
<obj_property name="ObjectShortName">bus_wr_req</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_bus_inst/access_err" type="logic"> |
<obj_property name="ElementShortName">access_err</obj_property> |
<obj_property name="ObjectShortName">access_err</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_bus_inst/align_err" type="logic"> |
<obj_property name="ElementShortName">align_err</obj_property> |
<obj_property name="ObjectShortName">align_err</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_bus_inst/bus_timeout" type="array"> |
<obj_property name="ElementShortName">bus_timeout[3:0]</obj_property> |
<obj_property name="ObjectShortName">bus_timeout[3:0]</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_bus_inst/misaligned_data" type="logic"> |
<obj_property name="ElementShortName">misaligned_data</obj_property> |
<obj_property name="ObjectShortName">misaligned_data</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_bus_inst/misaligned_instr" type="logic"> |
<obj_property name="ElementShortName">misaligned_instr</obj_property> |
<obj_property name="ObjectShortName">misaligned_instr</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_bus_inst/MEM_EXT_TIMEOUT" type="other"> |
<obj_property name="ElementShortName">MEM_EXT_TIMEOUT</obj_property> |
<obj_property name="ObjectShortName">MEM_EXT_TIMEOUT</obj_property> |
</wvobject> |
<wvobject type="divider" fp_name="divider298"> |
<obj_property name="label">CPU: MULDIC CP</obj_property> |
<obj_property name="DisplayName">label</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_cp_muldiv_inst_true/neorv32_cpu_cp_muldiv_inst/clk_i" type="logic"> |
<obj_property name="ElementShortName">clk_i</obj_property> |
<obj_property name="ObjectShortName">clk_i</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_cp_muldiv_inst_true/neorv32_cpu_cp_muldiv_inst/rstn_i" type="logic"> |
<obj_property name="ElementShortName">rstn_i</obj_property> |
<obj_property name="ObjectShortName">rstn_i</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_cp_muldiv_inst_true/neorv32_cpu_cp_muldiv_inst/ctrl_i" type="array"> |
<obj_property name="ElementShortName">ctrl_i[47:0]</obj_property> |
<obj_property name="ObjectShortName">ctrl_i[47:0]</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_cp_muldiv_inst_true/neorv32_cpu_cp_muldiv_inst/rs1_i" type="array"> |
<obj_property name="ElementShortName">rs1_i[31:0]</obj_property> |
<obj_property name="ObjectShortName">rs1_i[31:0]</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_cp_muldiv_inst_true/neorv32_cpu_cp_muldiv_inst/rs2_i" type="array"> |
<obj_property name="ElementShortName">rs2_i[31:0]</obj_property> |
<obj_property name="ObjectShortName">rs2_i[31:0]</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_cp_muldiv_inst_true/neorv32_cpu_cp_muldiv_inst/res_o" type="array"> |
<obj_property name="ElementShortName">res_o[31:0]</obj_property> |
<obj_property name="ObjectShortName">res_o[31:0]</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_cp_muldiv_inst_true/neorv32_cpu_cp_muldiv_inst/valid_o" type="logic"> |
<obj_property name="ElementShortName">valid_o</obj_property> |
<obj_property name="ObjectShortName">valid_o</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_cp_muldiv_inst_true/neorv32_cpu_cp_muldiv_inst/state" type="other"> |
<obj_property name="ElementShortName">state</obj_property> |
<obj_property name="ObjectShortName">state</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_cp_muldiv_inst_true/neorv32_cpu_cp_muldiv_inst/cnt" type="array"> |
<obj_property name="ElementShortName">cnt[4:0]</obj_property> |
<obj_property name="ObjectShortName">cnt[4:0]</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_cp_muldiv_inst_true/neorv32_cpu_cp_muldiv_inst/cp_op" type="array"> |
<obj_property name="ElementShortName">cp_op[2:0]</obj_property> |
<obj_property name="ObjectShortName">cp_op[2:0]</obj_property> |
<obj_property name="Radix">BINARYRADIX</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_cp_muldiv_inst_true/neorv32_cpu_cp_muldiv_inst/start" type="logic"> |
<obj_property name="ElementShortName">start</obj_property> |
<obj_property name="ObjectShortName">start</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_cp_muldiv_inst_true/neorv32_cpu_cp_muldiv_inst/operation" type="logic"> |
<obj_property name="ElementShortName">operation</obj_property> |
<obj_property name="ObjectShortName">operation</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_cp_muldiv_inst_true/neorv32_cpu_cp_muldiv_inst/opx" type="array"> |
<obj_property name="ElementShortName">opx[31:0]</obj_property> |
<obj_property name="ObjectShortName">opx[31:0]</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_cp_muldiv_inst_true/neorv32_cpu_cp_muldiv_inst/opy" type="array"> |
<obj_property name="ElementShortName">opy[31:0]</obj_property> |
<obj_property name="ObjectShortName">opy[31:0]</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_cp_muldiv_inst_true/neorv32_cpu_cp_muldiv_inst/opx_is_signed" type="logic"> |
<obj_property name="ElementShortName">opx_is_signed</obj_property> |
<obj_property name="ObjectShortName">opx_is_signed</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_cp_muldiv_inst_true/neorv32_cpu_cp_muldiv_inst/opy_is_signed" type="logic"> |
<obj_property name="ElementShortName">opy_is_signed</obj_property> |
<obj_property name="ObjectShortName">opy_is_signed</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_cp_muldiv_inst_true/neorv32_cpu_cp_muldiv_inst/div_res_corr" type="logic"> |
<obj_property name="ElementShortName">div_res_corr</obj_property> |
<obj_property name="ObjectShortName">div_res_corr</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_cp_muldiv_inst_true/neorv32_cpu_cp_muldiv_inst/remainder" type="array"> |
<obj_property name="ElementShortName">remainder[31:0]</obj_property> |
<obj_property name="ObjectShortName">remainder[31:0]</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_cp_muldiv_inst_true/neorv32_cpu_cp_muldiv_inst/quotient" type="array"> |
<obj_property name="ElementShortName">quotient[31:0]</obj_property> |
<obj_property name="ObjectShortName">quotient[31:0]</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_cp_muldiv_inst_true/neorv32_cpu_cp_muldiv_inst/div_sub" type="array"> |
<obj_property name="ElementShortName">div_sub[32:0]</obj_property> |
<obj_property name="ObjectShortName">div_sub[32:0]</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_cp_muldiv_inst_true/neorv32_cpu_cp_muldiv_inst/div_sign_comp_in" type="array"> |
<obj_property name="ElementShortName">div_sign_comp_in[31:0]</obj_property> |
<obj_property name="ObjectShortName">div_sign_comp_in[31:0]</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_cp_muldiv_inst_true/neorv32_cpu_cp_muldiv_inst/div_sign_comp" type="array"> |
<obj_property name="ElementShortName">div_sign_comp[31:0]</obj_property> |
<obj_property name="ObjectShortName">div_sign_comp[31:0]</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_cp_muldiv_inst_true/neorv32_cpu_cp_muldiv_inst/div_res" type="array"> |
<obj_property name="ElementShortName">div_res[31:0]</obj_property> |
<obj_property name="ObjectShortName">div_res[31:0]</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_cp_muldiv_inst_true/neorv32_cpu_cp_muldiv_inst/mul_product" type="array"> |
<obj_property name="ElementShortName">mul_product[63:0]</obj_property> |
<obj_property name="ObjectShortName">mul_product[63:0]</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_cp_muldiv_inst_true/neorv32_cpu_cp_muldiv_inst/mul_do_add" type="array"> |
<obj_property name="ElementShortName">mul_do_add[32:0]</obj_property> |
<obj_property name="ObjectShortName">mul_do_add[32:0]</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_cp_muldiv_inst_true/neorv32_cpu_cp_muldiv_inst/mul_sign_cycle" type="logic"> |
<obj_property name="ElementShortName">mul_sign_cycle</obj_property> |
<obj_property name="ObjectShortName">mul_sign_cycle</obj_property> |
</wvobject> |
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_cp_muldiv_inst_true/neorv32_cpu_cp_muldiv_inst/mul_p_sext" type="logic"> |
<obj_property name="ElementShortName">mul_p_sext</obj_property> |
<obj_property name="ObjectShortName">mul_p_sext</obj_property> |
</wvobject> |
</wave_config> |
/sim/neorv32_tb.vhd
126,8 → 126,9
generic map ( |
-- General -- |
CLOCK_FREQUENCY => f_clock_nat_c, -- clock frequency of clk_i in Hz |
HART_ID => x"ABCD1234", -- custom hardware thread ID |
HART_ID => x"00000000", -- custom hardware thread ID |
BOOTLOADER_USE => false, -- implement processor-internal bootloader? |
CSR_COUNTERS_USE => true, -- implement RISC-V perf. counters ([m]instret[h], [m]cycle[h], time[h])? |
-- RISC-V CPU Extensions -- |
CPU_EXTENSION_RISCV_C => true, -- implement compressed extension? |
CPU_EXTENSION_RISCV_E => false, -- implement embedded RF extension? |
181,9 → 182,9
uart_txd_o => uart_txd, -- UART send data |
uart_rxd_i => uart_txd, -- UART receive data |
-- SPI -- |
spi_sclk_o => open, -- serial clock line |
spi_mosi_o => spi_data, -- serial data line out |
spi_miso_i => spi_data, -- serial data line in |
spi_sck_o => open, -- SPI serial clock |
spi_sdo_o => spi_data, -- controller data out, peripheral data in |
spi_sdi_i => spi_data, -- controller data in, peripheral data out |
spi_csn_o => open, -- SPI CS |
-- TWI -- |
twi_sda_io => twi_sda, -- twi serial data line |
/sw/bootloader/bootloader.c
218,7 → 218,9
print_proc_version(); |
neorv32_uart_print("\nCLK: "); |
print_hex_word(neorv32_cpu_csr_read(CSR_MCLOCK)); |
neorv32_uart_print(" Hz\nMISA: "); |
neorv32_uart_print(" Hz\nMHID: "); |
print_hex_word(neorv32_cpu_csr_read(CSR_MHARTID)); |
neorv32_uart_print("\nMISA: "); |
print_hex_word(neorv32_cpu_csr_read(CSR_MISA)); |
neorv32_uart_print("\nCONF: "); |
print_hex_word(neorv32_cpu_csr_read(CSR_MFEATURES)); |
/sw/common/crt0.S
1,7 → 1,7
/* ################################################################################################# */ |
/* # << NEORV32 - crt0.S - Application Start-Up Code >> # */ |
/* # << NEORV32 - crt0.S - Application Start-Up Code & Minimal Runtime Environment >> # */ |
/* # ********************************************************************************************* # */ |
/* # The start-up code provides a minimal runtime environment that catches all exceptions/ # */ |
/* # The start-up code provides a minimal runtime environment that catches all exceptions and # */ |
/* # interrupts and delegates them to the handler functions (installed by user via dedicated # */ |
/* # install function from the neorv32 runtime environment library). # */ |
/* # ********************************************************************************************* # */ |
117,8 → 117,8
// Setup stack pointer |
// ********************************************************* |
__crt0_stack_pointer_init: |
csrrw x11, CSR_MDSPACEBASE, zero // data memory space base address |
csrrw x12, CSR_MDSPACESIZE, zero // data memory space size |
csrr x11, CSR_MDSPACEBASE // data memory space base address |
csrr x12, CSR_MDSPACESIZE // data memory space size |
add sp, x11, x12 |
addi sp, sp, -4 // stack pointer = last entry |
addi fp, sp, 0 // frame pointer = stack pointer |
139,9 → 139,9
// ********************************************************* |
__crt0_neorv32_rte_init: |
la x11, __crt0_neorv32_rte |
csrrw zero, mtvec, x11 // set address of first-level exception handler |
csrw mtvec, x11 // set address of first-level exception handler |
|
csrrw x11, CSR_MDSPACEBASE, zero // data memory space base address |
csrr x11, CSR_MDSPACEBASE // data memory space base address |
la x12, __crt0_neorv32_rte_dummy_hanlder |
li x13, 2*16 // number of entries (16xEXC, 16xIRQ) |
|
278,14 → 278,14
// -------------------------------------------- |
// get cause and prepare jump into vector table |
// -------------------------------------------- |
csrrw t0, mcause, zero // get cause code |
csrr t0, mcause // get cause code |
|
andi t1, t0, 0x0f // isolate cause ID |
slli t1, t1, 2 // make address offset |
csrrw ra, CSR_MDSPACEBASE, zero // data memory space base address |
csrr ra, CSR_MDSPACEBASE // data memory space base address |
add t1, t1, ra // get vetor table entry address (EXC vectors) |
|
csrrw ra, mepc, zero // get return address |
csrr ra, mepc // get return address |
|
blt t0, zero, __crt0_neorv32_rte_is_irq // branch if this is an INTERRUPT |
|
296,11 → 296,11
__crt0_neorv32_rte_is_exc: |
|
// is faulting instruction compressed? |
csrrw t0, mtinst, zero |
andi t0, t0, 2 // get compression flag (bit #1): 0=compressed, 2=uncompressed |
csrr t0, mtinst |
andi t0, t0, 2 // get compression flag (bit #1): 0=compressed, 1=uncompressed |
|
addi ra, ra, +2 // only this for compressed instr |
add ra, ra, t0 // add another 2 (0+4) for uncompressed instr |
addi ra, ra, +2 // only this for compressed instructions |
add ra, ra, t0 // add another 2 (making +4) for uncompressed instructions |
j __crt0_neorv32_rte_execute |
|
|
320,7 → 320,6
// push ra |
addi sp, sp, -4 |
sw ra, 0(sp) |
csrrw zero, mscratch, ra |
|
jalr ra, t0 // call second-level handler |
|
328,7 → 327,7
lw ra, 0(sp) |
addi sp, sp, +4 |
|
csrrw zero, mepc, ra |
csrw mepc, ra |
|
|
// -------------------------------------------- |
/sw/example/blink_led/makefile
82,16 → 82,14
|
|
# ----------------------------------------------------------------------------- |
# Add NEORV32 sources to input SRCs |
# NEORV32 core sources |
# ----------------------------------------------------------------------------- |
APP_SRC += $(wildcard $(NEORV32_SRC_PATH)/*.c) |
CORE_SRC = $(wildcard $(NEORV32_SRC_PATH)/*.c) |
|
|
# ----------------------------------------------------------------------------- |
# Make defaults |
# ----------------------------------------------------------------------------- |
.SUFFIXES: |
.PHONY: all |
.DEFAULT_GOAL := help |
|
|
106,7 → 104,8
all: $(APP_ASM) $(APP_EXE) neorv32_application_image.vhd |
|
# define all object files |
OBJ = $(APP_SRC:.c=.o) |
OBJ = $(APP_SRC:.c=.o) |
OBJ += $(CORE_SRC:.c=.o) |
|
|
# ----------------------------------------------------------------------------- |
259,13 → 258,18
# ----------------------------------------------------------------------------- |
info: |
@echo "---------------- Info: Project ----------------" |
@echo "Project: $(shell basename $(CURDIR))" |
@echo "Project source files: $(APP_SRC)" |
@echo "Project include folders: $(NEORV32_INC_PATH) $(APP_INC)" |
@echo "Project object files: $(OBJ)" |
@echo "Project folder: $(shell basename $(CURDIR))" |
@echo "Source files: $(APP_SRC)" |
@echo "Include folder(s): $(APP_INC)" |
@echo "---------------- Info: NEORV32 ----------------" |
@echo "NEORV32 home folder (NEORV32_HOME): $(NEORV32_HOME)" |
@echo "IMAGE_GEN: $(IMAGE_GEN)" |
@echo "Core source files:" |
@echo "$(CORE_SRC)" |
@echo "Core include folder:" |
@echo "$(NEORV32_INC_PATH)" |
@echo "Project object files:" |
@echo "$(OBJ)" |
@echo "---------------- Info: RISC-V CPU ----------------" |
@echo "MARCH: $(MARCH)" |
@echo "MABI: $(MABI)" |
/sw/example/coremark/makefile
82,16 → 82,14
|
|
# ----------------------------------------------------------------------------- |
# Add NEORV32 sources to input SRCs |
# NEORV32 core sources |
# ----------------------------------------------------------------------------- |
APP_SRC += $(wildcard $(NEORV32_SRC_PATH)/*.c) |
CORE_SRC = $(wildcard $(NEORV32_SRC_PATH)/*.c) |
|
|
# ----------------------------------------------------------------------------- |
# Make defaults |
# ----------------------------------------------------------------------------- |
.SUFFIXES: |
.PHONY: all |
.DEFAULT_GOAL := help |
|
|
106,7 → 104,8
all: $(APP_ASM) $(APP_EXE) neorv32_application_image.vhd |
|
# define all object files |
OBJ = $(APP_SRC:.c=.o) |
OBJ = $(APP_SRC:.c=.o) |
OBJ += $(CORE_SRC:.c=.o) |
|
|
# ----------------------------------------------------------------------------- |
259,13 → 258,18
# ----------------------------------------------------------------------------- |
info: |
@echo "---------------- Info: Project ----------------" |
@echo "Project: $(shell basename $(CURDIR))" |
@echo "Project source files: $(APP_SRC)" |
@echo "Project include folders: $(NEORV32_INC_PATH) $(APP_INC)" |
@echo "Project object files: $(OBJ)" |
@echo "Project folder: $(shell basename $(CURDIR))" |
@echo "Source files: $(APP_SRC)" |
@echo "Include folder(s): $(APP_INC)" |
@echo "---------------- Info: NEORV32 ----------------" |
@echo "NEORV32 home folder (NEORV32_HOME): $(NEORV32_HOME)" |
@echo "IMAGE_GEN: $(IMAGE_GEN)" |
@echo "Core source files:" |
@echo "$(CORE_SRC)" |
@echo "Core include folder:" |
@echo "$(NEORV32_INC_PATH)" |
@echo "Project object files:" |
@echo "$(OBJ)" |
@echo "---------------- Info: RISC-V CPU ----------------" |
@echo "MARCH: $(MARCH)" |
@echo "MABI: $(MABI)" |
/sw/example/cpu_test/main.c
0,0 → 1,586
// ################################################################################################# |
// # << NEORV32 - CPU Test Program >> # |
// # ********************************************************************************************* # |
// # BSD 3-Clause License # |
// # # |
// # Copyright (c) 2020, Stephan Nolting. All rights reserved. # |
// # # |
// # Redistribution and use in source and binary forms, with or without modification, are # |
// # permitted provided that the following conditions are met: # |
// # # |
// # 1. Redistributions of source code must retain the above copyright notice, this list of # |
// # conditions and the following disclaimer. # |
// # # |
// # 2. Redistributions in binary form must reproduce the above copyright notice, this list of # |
// # conditions and the following disclaimer in the documentation and/or other materials # |
// # provided with the distribution. # |
// # # |
// # 3. Neither the name of the copyright holder nor the names of its contributors may be used to # |
// # endorse or promote products derived from this software without specific prior written # |
// # permission. # |
// # # |
// # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS # |
// # OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF # |
// # MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE # |
// # COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, # |
// # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE # |
// # GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED # |
// # AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING # |
// # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED # |
// # OF THE POSSIBILITY OF SUCH DAMAGE. # |
// # ********************************************************************************************* # |
// # The NEORV32 Processor - https://github.com/stnolting/neorv32 (c) Stephan Nolting # |
// ################################################################################################# |
|
|
/**********************************************************************//** |
* @file cpu_test/main.c |
* @author Stephan Nolting |
* @brief Simple CPU interrupts and exceptions test program. |
**************************************************************************/ |
|
#include <neorv32.h> |
|
|
/**********************************************************************//** |
* @name User configuration |
**************************************************************************/ |
/**@{*/ |
/** UART BAUD rate */ |
#define BAUD_RATE 19200 |
//** Set 1 for detailed exception debug information */ |
#define DETAILED_EXCEPTION_DEBUG 0 |
//** Reachable unaligned address */ |
#define ADDR_UNALIGNED 0x00000002 |
//** Unreachable aligned address */ |
#define ADDR_UNREACHABLE 0xFFFFFF00 |
/**@}*/ |
|
|
/**********************************************************************//** |
* @name Exception handler acknowledges |
**************************************************************************/ |
/**@{*/ |
/** Exception handler answers / identifiers */ |
enum EXC_HANDLER_ANSWERS { |
ANSWER_I_MISALIGN = 0x12345678, /**< Answer for misaligned instruction address excetion */ |
ANSWER_I_ACCESS = 0xAABB1133, /**< Answer for instruction access fault excetion */ |
ANSWER_I_ILLEGAL = 0x0199203B, /**< Answer for illegal instruction excetion */ |
ANSWER_BREAKPOINT = 0x12322330, /**< Answer for breakpoint excetion */ |
ANSWER_L_MISALIGN = 0xBABCCCCC, /**< Answer for misaligned load address excetion */ |
ANSWER_L_ACCESS = 0xDEF728AA, /**< Answer for load access fault excetion */ |
ANSWER_S_MISALIGN = 0xFF0927DD, /**< Answer for misaligned store address excetion */ |
ANSWER_S_ACCESS = 0x20091777, /**< Answer for store access fault excetion */ |
ANSWER_ENVCALL = 0x55662244, /**< Answer for environment call excetion */ |
ANSWER_MSI = 0xCDECDEA9, /**< Answer for machine software interrupt */ |
ANSWER_MTI = 0x0012FA53, /**< Answer for machine timer interrupt */ |
ANSWER_CLIC = 0xEEF33088 /**< Answer for machine external interrupt */ |
}; |
/** Gloabl volatile variable to store exception handler answer */ |
volatile uint32_t exception_handler_answer; |
/**@}*/ |
|
|
// Prototypes |
void exc_handler_i_misalign(void); |
void exc_handler_i_access(void); |
void exc_handler_i_illegal(void); |
void exc_handler_breakpoint(void); |
void exc_handler_l_misalign(void); |
void exc_handler_l_access(void); |
void exc_handler_s_misalign(void); |
void exc_handler_s_access(void); |
void exc_handler_envcall(void); |
void exc_handler_msi(void); |
void exc_handler_mti(void); |
void irq_handler_clic_ch0(); |
|
|
/**********************************************************************//** |
* Unreachable memory-mapped register that should be always available |
**************************************************************************/ |
#define MMR_UNREACHABLE (*(IO_REG32 (ADDR_UNREACHABLE))) |
|
|
/**********************************************************************//** |
* This program uses mostly synthetic case to trigger all implemented exceptions. |
* Each exception is captured and evaluated for correct detection. |
* |
* @note This program requires the UART, MTIME and CLIC to be synthesized. |
* |
* @return Irrelevant. |
**************************************************************************/ |
int main() { |
|
register uint32_t tmp_a; |
volatile uint32_t dummy_dst __attribute__((unused)); |
|
int cnt_fail = 0; |
int cnt_ok = 0; |
int cnt_test = 0; |
|
// check if UART unit is implemented at all |
if (neorv32_uart_available() == 0) { |
return 0; |
} |
|
// check if CLIC unit is implemented at all |
if (neorv32_clic_available() == 0) { |
return 0; |
} |
|
// check if MTIME unit is implemented at all |
if (neorv32_mtime_available() == 0) { |
return 0; |
} |
|
|
// init UART at default baud rate, no rx interrupt, no tx interrupt |
neorv32_uart_setup(BAUD_RATE, 0, 0); |
|
|
// set CMP of machine system timer MTIME to max to prevent an IRQ |
uint64_t mtime_cmp_max = 0xFFFFFFFFFFFFFFFFL; |
neorv32_mtime_set_timecmp(mtime_cmp_max); |
|
// intro |
neorv32_uart_printf("\n\n------ CPU TEST ------\n\n"); |
|
// show full HW config report |
neorv32_rte_print_hw_config(); |
|
// intro2 |
neorv32_uart_printf("\n\nNEORV32 exceptions and interrupts test program\n\n"); |
|
// install exception handler functions |
int install_err = 0; |
install_err += neorv32_rte_exception_install(EXCID_I_MISALIGNED, exc_handler_i_misalign); |
install_err += neorv32_rte_exception_install(EXCID_I_ACCESS, exc_handler_i_access); |
install_err += neorv32_rte_exception_install(EXCID_I_ILLEGAL, exc_handler_i_illegal); |
install_err += neorv32_rte_exception_install(EXCID_BREAKPOINT, exc_handler_breakpoint); |
install_err += neorv32_rte_exception_install(EXCID_L_MISALIGNED, exc_handler_l_misalign); |
install_err += neorv32_rte_exception_install(EXCID_L_ACCESS, exc_handler_l_access); |
install_err += neorv32_rte_exception_install(EXCID_S_MISALIGNED, exc_handler_s_misalign); |
install_err += neorv32_rte_exception_install(EXCID_S_ACCESS, exc_handler_s_access); |
install_err += neorv32_rte_exception_install(EXCID_MENV_CALL, exc_handler_envcall); |
install_err += neorv32_rte_exception_install(EXCID_MSI, exc_handler_msi); |
install_err += neorv32_rte_exception_install(EXCID_MTI, exc_handler_mti); |
//install_err += neorv32_rte_exception_install(EXCID_MEI, -); done by neorv32_clic_handler_install |
|
if (install_err) { |
neorv32_uart_printf("install error!\n"); |
return 0; |
} |
|
|
// install interrupt handler for clic WDT channel |
install_err += neorv32_clic_handler_install(CLIC_CH_WDT, irq_handler_clic_ch0); |
|
if (install_err) { |
neorv32_uart_printf("CLIC install error!\n"); |
return 0; |
} |
|
|
#if (DETAILED_EXCEPTION_DEBUG==1) |
// enable debug mode for uninitialized exception/interrupt vectors |
// and overwrite previous exception handler installations |
// -> any exception/interrupt will show a message from the neorv32 runtime environment |
neorv32_rte_enable_debug_mode(); |
#endif |
|
|
// enable global interrupts |
neorv32_cpu_eint(); |
|
exception_handler_answer = 0; |
|
|
// ---------------------------------------------------------- |
// Unaligned instruction address |
// ---------------------------------------------------------- |
neorv32_uart_printf("EXC I_ALIGN: "); |
cnt_test++; |
|
// skip if C-mode is not implemented |
if ((neorv32_cpu_csr_read(CSR_MISA) | (1<<CPU_MISA_C_EXT)) == 0) { |
|
// call unaligned address |
((void (*)(void))ADDR_UNALIGNED)(); |
|
#if (DETAILED_EXCEPTION_DEBUG==0) |
if (exception_handler_answer == ANSWER_I_MISALIGN) { |
neorv32_uart_printf("ok\n"); |
cnt_ok++; |
} |
else { |
neorv32_uart_printf("fail\n"); |
cnt_fail++; |
} |
exception_handler_answer = 0; |
#endif |
} |
else { |
neorv32_uart_printf("skipped (no EXC I_ALIGN possible in C-mode)\n"); |
} |
|
|
// ---------------------------------------------------------- |
// Instruction access fault |
// ---------------------------------------------------------- |
neorv32_uart_printf("EXC I_ACC: "); |
cnt_test++; |
|
// call unreachable aligned address |
((void (*)(void))ADDR_UNREACHABLE)(); |
|
#if (DETAILED_EXCEPTION_DEBUG==0) |
if (exception_handler_answer == ANSWER_I_ACCESS) { |
neorv32_uart_printf("ok\n"); |
cnt_ok++; |
} |
else { |
neorv32_uart_printf("fail\n"); |
cnt_fail++; |
} |
exception_handler_answer = 0; |
#endif |
|
|
// ---------------------------------------------------------- |
// Illegal instruction |
// ---------------------------------------------------------- |
neorv32_uart_printf("EXC I_ILLEG: "); |
cnt_test++; |
|
// create test program in RAM |
static const uint32_t dummy_sub_program[2] = { |
0xDEAD007F, // undefined 32-bit opcode -> illegal instruction exception |
0x00008067 // ret (32-bit) |
}; |
|
tmp_a = (uint32_t)&dummy_sub_program; // call the dummy sub program |
asm volatile ( "jalr ra, %0 " : "=r" (tmp_a) : "r" (tmp_a)); |
|
#if (DETAILED_EXCEPTION_DEBUG==0) |
if (exception_handler_answer == ANSWER_I_ILLEGAL) { |
neorv32_uart_printf("ok\n"); |
cnt_ok++; |
} |
else { |
neorv32_uart_printf("fail\n"); |
cnt_fail++; |
} |
exception_handler_answer = 0; |
#endif |
|
|
// ---------------------------------------------------------- |
// Breakpoint instruction |
// ---------------------------------------------------------- |
neorv32_uart_printf("EXC BREAK: "); |
cnt_test++; |
|
asm volatile("EBREAK"); |
|
#if (DETAILED_EXCEPTION_DEBUG==0) |
if (exception_handler_answer == ANSWER_BREAKPOINT) { |
neorv32_uart_printf("ok\n"); |
cnt_ok++; |
} |
else { |
neorv32_uart_printf("fail\n"); |
cnt_fail++; |
} |
exception_handler_answer = 0; |
#endif |
|
|
// ---------------------------------------------------------- |
// Unaligned load address |
// ---------------------------------------------------------- |
neorv32_uart_printf("EXC L_ALIGN: "); |
cnt_test++; |
|
// load from unaligned address |
asm volatile ("lw zero, %[input_i](zero)" : : [input_i] "i" (ADDR_UNALIGNED)); |
|
#if (DETAILED_EXCEPTION_DEBUG==0) |
if (exception_handler_answer == ANSWER_L_MISALIGN) { |
neorv32_uart_printf("ok\n"); |
cnt_ok++; |
} |
else { |
neorv32_uart_printf("fail\n"); |
cnt_fail++; |
} |
exception_handler_answer = 0; |
#endif |
|
|
// ---------------------------------------------------------- |
// Load access fault |
// ---------------------------------------------------------- |
neorv32_uart_printf("EXC L_ACC: "); |
cnt_test++; |
|
// load from unreachable aligned address |
dummy_dst = MMR_UNREACHABLE; |
|
#if (DETAILED_EXCEPTION_DEBUG==0) |
if (exception_handler_answer == ANSWER_L_ACCESS) { |
neorv32_uart_printf("ok\n"); |
cnt_ok++; |
} |
else { |
neorv32_uart_printf("fail\n"); |
cnt_fail++; |
} |
exception_handler_answer = 0; |
#endif |
|
|
// ---------------------------------------------------------- |
// Unaligned store address |
// ---------------------------------------------------------- |
neorv32_uart_printf("EXC S_ALIGN: "); |
cnt_test++; |
|
// store to unaligned address |
asm volatile ("sw zero, %[input_i](zero)" : : [input_i] "i" (ADDR_UNALIGNED)); |
|
#if (DETAILED_EXCEPTION_DEBUG==0) |
if (exception_handler_answer == ANSWER_S_MISALIGN) { |
neorv32_uart_printf("ok\n"); |
cnt_ok++; |
} |
else { |
neorv32_uart_printf("fail\n"); |
cnt_fail++; |
} |
exception_handler_answer = 0; |
#endif |
|
|
// ---------------------------------------------------------- |
// Store access fault |
// ---------------------------------------------------------- |
neorv32_uart_printf("EXC S_ACC: "); |
cnt_test++; |
|
// store to unreachable aligned address |
MMR_UNREACHABLE = 0; |
|
#if (DETAILED_EXCEPTION_DEBUG==0) |
if (exception_handler_answer == ANSWER_S_ACCESS) { |
neorv32_uart_printf("ok\n"); |
cnt_ok++; |
} |
else { |
neorv32_uart_printf("fail\n"); |
cnt_fail++; |
} |
exception_handler_answer = 0; |
#endif |
|
|
// ---------------------------------------------------------- |
// Environment call |
// ---------------------------------------------------------- |
neorv32_uart_printf("EXC ENVCALL: "); |
cnt_test++; |
|
asm volatile("ECALL"); |
|
#if (DETAILED_EXCEPTION_DEBUG==0) |
if (exception_handler_answer == ANSWER_ENVCALL) { |
neorv32_uart_printf("ok\n"); |
cnt_ok++; |
} |
else { |
neorv32_uart_printf("fail\n"); |
cnt_fail++; |
} |
exception_handler_answer = 0; |
#endif |
|
|
// ---------------------------------------------------------- |
// Machine software interrupt |
// ---------------------------------------------------------- |
neorv32_uart_printf("IRQ MSI: "); |
cnt_test++; |
|
// trigger machine software interrupt |
neorv32_cpu_sw_irq(); |
|
#if (DETAILED_EXCEPTION_DEBUG==0) |
if (exception_handler_answer == ANSWER_MSI) { |
neorv32_uart_printf("ok\n"); |
cnt_ok++; |
} |
else { |
neorv32_uart_printf("fail\n"); |
cnt_fail++; |
} |
exception_handler_answer = 0; |
#endif |
|
|
// ---------------------------------------------------------- |
// Machine timer interrupt (MTIME) |
// ---------------------------------------------------------- |
neorv32_uart_printf("IRQ MTI: "); |
cnt_test++; |
|
// force MTIME IRQ |
neorv32_mtime_set_timecmp(0); |
|
// wait some time for the IRQ to arrive the CPU |
asm volatile("nop"); |
asm volatile("nop"); |
asm volatile("nop"); |
asm volatile("nop"); |
|
#if (DETAILED_EXCEPTION_DEBUG==0) |
if (exception_handler_answer == ANSWER_MTI) { |
neorv32_uart_printf("ok\n"); |
cnt_ok++; |
} |
else { |
neorv32_uart_printf("fail\n"); |
cnt_fail++; |
} |
exception_handler_answer = 0; |
#endif |
|
|
// ---------------------------------------------------------- |
// Machine external interrupt (via CLIC) |
// ---------------------------------------------------------- |
neorv32_uart_printf("IRQ MEI: "); |
cnt_test++; |
|
// manually trigger CLIC channel (watchdog interrupt) |
neorv32_clic_trigger_irq(CLIC_CH_WDT); |
|
// wait some time for the IRQ to arrive the CPU |
asm volatile("nop"); |
asm volatile("nop"); |
asm volatile("nop"); |
asm volatile("nop"); |
|
#if (DETAILED_EXCEPTION_DEBUG==0) |
if (exception_handler_answer == ANSWER_CLIC) { |
neorv32_uart_printf("ok\n"); |
cnt_ok++; |
} |
else { |
neorv32_uart_printf("fail\n"); |
cnt_fail++; |
} |
exception_handler_answer = 0; |
#endif |
|
|
// error report |
neorv32_uart_printf("\n\nTests: %i\nOK: %i\nFAIL: %i\n\n", cnt_test, cnt_ok, cnt_fail); |
|
// final result |
if (cnt_fail == 0) { |
neorv32_uart_printf("TEST OK!\n"); |
} |
else { |
neorv32_uart_printf("TEST FAILED!\n"); |
} |
|
return 0; |
} |
|
|
/**********************************************************************//** |
* Misaligned instruction address exception handler. |
**************************************************************************/ |
void exc_handler_i_misalign(void) { |
exception_handler_answer = ANSWER_I_MISALIGN; |
} |
|
/**********************************************************************//** |
* Instruction access fault exception handler. |
**************************************************************************/ |
void exc_handler_i_access(void) { |
exception_handler_answer = ANSWER_I_ACCESS; |
} |
|
/**********************************************************************//** |
* Illegal instruction exception handler. |
**************************************************************************/ |
void exc_handler_i_illegal(void) { |
exception_handler_answer = ANSWER_I_ILLEGAL; |
} |
|
/**********************************************************************//** |
* Breakpoint exception handler. |
**************************************************************************/ |
void exc_handler_breakpoint(void) { |
exception_handler_answer = ANSWER_BREAKPOINT; |
} |
|
/**********************************************************************//** |
* Misaligned load address exception handler. |
**************************************************************************/ |
void exc_handler_l_misalign(void) { |
exception_handler_answer = ANSWER_L_MISALIGN; |
} |
|
/**********************************************************************//** |
* Load instruction access fault exception handler. |
**************************************************************************/ |
void exc_handler_l_access(void) { |
exception_handler_answer = ANSWER_L_ACCESS; |
} |
|
/**********************************************************************//** |
* Misaligned store address exception handler. |
**************************************************************************/ |
void exc_handler_s_misalign(void) { |
exception_handler_answer = ANSWER_S_MISALIGN; |
} |
|
/**********************************************************************//** |
* Store address access fault exception handler. |
**************************************************************************/ |
void exc_handler_s_access(void) { |
exception_handler_answer = ANSWER_S_ACCESS; |
} |
|
/**********************************************************************//** |
* Environment call exception handler. |
**************************************************************************/ |
void exc_handler_envcall(void) { |
exception_handler_answer = ANSWER_ENVCALL; |
} |
|
/**********************************************************************//** |
* Machine software interrupt exception handler. |
**************************************************************************/ |
void exc_handler_msi(void) { |
exception_handler_answer = ANSWER_MSI; |
} |
|
/**********************************************************************//** |
* Machine timer interrupt exception handler. |
**************************************************************************/ |
void exc_handler_mti(void) { |
exception_handler_answer = ANSWER_MTI; |
// set CMP of machine system timer MTIME to max to prevent an IRQ |
neorv32_mtime_set_timecmp(-1); |
} |
|
/**********************************************************************//** |
* CLIC interrupt handler for channel 0. |
**************************************************************************/ |
void irq_handler_clic_ch0(void) { |
exception_handler_answer = ANSWER_CLIC; |
} |
|
/sw/example/cpu_test/makefile
0,0 → 1,326
################################################################################################# |
# << NEORV32 - Application Makefile >> # |
# ********************************************************************************************* # |
# Make sure to add the riscv GCC compiler's bin folder to your PATH environment variable. # |
# ********************************************************************************************* # |
# BSD 3-Clause License # |
# # |
# Copyright (c) 2020, Stephan Nolting. All rights reserved. # |
# # |
# Redistribution and use in source and binary forms, with or without modification, are # |
# permitted provided that the following conditions are met: # |
# # |
# 1. Redistributions of source code must retain the above copyright notice, this list of # |
# conditions and the following disclaimer. # |
# # |
# 2. Redistributions in binary form must reproduce the above copyright notice, this list of # |
# conditions and the following disclaimer in the documentation and/or other materials # |
# provided with the distribution. # |
# # |
# 3. Neither the name of the copyright holder nor the names of its contributors may be used to # |
# endorse or promote products derived from this software without specific prior written # |
# permission. # |
# # |
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS # |
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF # |
# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE # |
# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, # |
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE # |
# GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED # |
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING # |
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED # |
# OF THE POSSIBILITY OF SUCH DAMAGE. # |
# ********************************************************************************************* # |
# The NEORV32 Processor - https://github.com/stnolting/neorv32 (c) Stephan Nolting # |
################################################################################################# |
|
|
# ***************************************************************************** |
# USER CONFIGURATION |
# ***************************************************************************** |
# Compiler effort |
EFFORT = -Os |
|
# User's application sources (add additional files here) |
APP_SRC = $(wildcard *.c) |
|
# User's application include folders (don't forget the '-I' before each entry) |
APP_INC = -I . |
|
# Compiler toolchain (use default if not set by user) |
RISCV_TOOLCHAIN ?= riscv32-unknown-elf |
|
# CPU architecture and ABI |
MARCH = -march=rv32i |
MABI = -mabi=ilp32 |
|
# Path to runtime c library (use default if not set by user) |
LIBC_PATH ?= $(dir $(shell which $(CC)))../$(RISCV_TOOLCHAIN)/lib/libc.a |
LIBGCC_PATH ?= $(dir $(shell which $(CC)))../lib/gcc/$(RISCV_TOOLCHAIN)/*/libgcc.a |
|
# Relative or absolute path to the NEORV32 home folder (use default if not set by user) |
NEORV32_HOME ?= ../../.. |
# ***************************************************************************** |
|
|
|
# ----------------------------------------------------------------------------- |
# NEORV32 framework |
# ----------------------------------------------------------------------------- |
# Path to NEORV32 linker script and startup file |
NEORV32_COM_PATH=$(NEORV32_HOME)/sw/common |
# Path to main NEORV32 library include files |
NEORV32_INC_PATH=$(NEORV32_HOME)/sw/lib/include |
# Path to main NEORV32 library source files |
NEORV32_SRC_PATH=$(NEORV32_HOME)/sw/lib/source |
# Path to NEORV32 executable generator |
NEORV32_EXG_PATH=$(NEORV32_HOME)/sw/image_gen |
# Path to NEORV32 core rtl folder |
NEORV32_RTL_PATH=$(NEORV32_HOME)/rtl/core |
# Marker file to verify NEORV32 home folder |
NEORV32_HOME_MARKER=$(NEORV32_INC_PATH)/neorv32.h |
|
|
# ----------------------------------------------------------------------------- |
# NEORV32 core sources |
# ----------------------------------------------------------------------------- |
CORE_SRC = $(wildcard $(NEORV32_SRC_PATH)/*.c) |
|
|
# ----------------------------------------------------------------------------- |
# Make defaults |
# ----------------------------------------------------------------------------- |
.DEFAULT_GOAL := help |
|
|
# ----------------------------------------------------------------------------- |
# Application output definitions |
# ----------------------------------------------------------------------------- |
APP_EXE = neorv32_exe.bin |
APP_ASM = main.s |
|
compile: $(APP_ASM) $(APP_EXE) |
install: $(APP_ASM) neorv32_application_image.vhd |
all: $(APP_ASM) $(APP_EXE) neorv32_application_image.vhd |
|
# define all object files |
OBJ = $(APP_SRC:.c=.o) |
OBJ += $(CORE_SRC:.c=.o) |
|
|
# ----------------------------------------------------------------------------- |
# Tools and flags |
# ----------------------------------------------------------------------------- |
# compiler tools |
CC = $(RISCV_TOOLCHAIN)-gcc |
LD = $(RISCV_TOOLCHAIN)-ld |
OBJDUMP = $(RISCV_TOOLCHAIN)-objdump |
OBJCOPY = $(RISCV_TOOLCHAIN)-objcopy |
SIZE = $(RISCV_TOOLCHAIN)-size |
|
# NEORV32 executable image generator |
IMAGE_GEN = $(NEORV32_EXG_PATH)/image_gen |
|
# Compiler flags |
CC_OPTS = $(MARCH) $(MABI) $(EFFORT) -Wall -ffunction-sections -fdata-sections -lm |
|
# Linker flags |
LD_OPTS = $(EFFORT) --gc-sections |
|
# User flags for additional config |
USER_FLAGS = |
CC_OPTS += $(USER_FLAGS) |
|
# Use embedded RISC-V CPU extension? |
ifeq (,$(findstring rv32e,$(MARCH))) |
CC_OPTS += |
else |
CC_OPTS += -D__RISCV_EMBEDDED_CPU__ |
endif |
|
# ----------------------------------------------------------------------------- |
# Host native compiler |
# ----------------------------------------------------------------------------- |
CC_X86 = gcc -Wall -O -g |
|
|
# ----------------------------------------------------------------------------- |
# Tool targets |
# ----------------------------------------------------------------------------- |
# install/compile tools |
$(IMAGE_GEN): $(NEORV32_EXG_PATH)/image_gen.cpp |
@echo Compiling $(IMAGE_GEN) |
@$(CC_X86) $< -o $(IMAGE_GEN) |
|
|
# ----------------------------------------------------------------------------- |
# Application targets: Assemble, compile, link, dump |
# ----------------------------------------------------------------------------- |
# Assemble startup code |
crt0.elf: $(NEORV32_COM_PATH)/crt0.S |
@$(CC) $(CC_OPTS) -c $< -o $@ |
|
# Compile app sources |
$(OBJ): %.o : %.c crt0.elf |
@$(CC) -c $(CC_OPTS) -I $(NEORV32_INC_PATH) $(APP_INC) $< -o $@ |
|
# Link object files and show memory utilization |
main.elf: $(OBJ) |
@$(LD) $(LD_OPTS) -I $(NEORV32_INC_PATH) $(APP_INC) -T $(NEORV32_COM_PATH)/neorv32.ld $(OBJ) $(LIBC_PATH) $(LIBGCC_PATH) -o $@ |
@echo "Memory utilization:" |
@$(SIZE) main.elf |
|
# Assembly listing file (for debugging) |
$(APP_ASM): main.elf |
@$(OBJDUMP) -D -S -z $< > $@ |
|
|
# ----------------------------------------------------------------------------- |
# Application targets: Generate binary executable, install (as VHDL file) |
# ----------------------------------------------------------------------------- |
# Generate final executable: text, rodata, data (in THIS order!) |
main.bin: main.elf |
@$(OBJCOPY) -I elf32-little $< -j .text -O binary text.bin |
@$(OBJCOPY) -I elf32-little $< -j .rodata -O binary rodata.bin |
@$(OBJCOPY) -I elf32-little $< -j .data -O binary data.bin |
@cat text.bin rodata.bin data.bin > $@ |
@rm -f text.bin rodata.bin data.bin |
|
# Generate NEORV32 executable image for bootloader update |
$(APP_EXE): main.bin $(IMAGE_GEN) |
@set -e |
@$(IMAGE_GEN) -app_bin $< $@ $(shell basename $(CURDIR)) |
@echo "Executable ($(APP_EXE)) size in bytes:" |
@wc -c < $(APP_EXE) |
|
# Generate NEORV32 executable VHDL boot image |
neorv32_application_image.vhd: main.bin $(IMAGE_GEN) |
@set -e |
@$(IMAGE_GEN) -app_img $< $@ $(shell basename $(CURDIR)) |
@echo "Installing application image to $(NEORV32_RTL_PATH)/neorv32_application_image.vhd" |
@cp neorv32_application_image.vhd $(NEORV32_RTL_PATH)/. |
@rm -f neorv32_application_image.vhd |
|
|
# ----------------------------------------------------------------------------- |
# Bootloader targets |
# ----------------------------------------------------------------------------- |
# Assemble startup code |
bootloader_crt0.elf: $(NEORV32_COM_PATH)/bootloader_crt0.S |
@$(CC) $(CC_OPTS) -c $< -o $@ |
|
# Compile and install bootloader |
bootloader: bootloader_crt0.elf $(OBJ) $(IMAGE_GEN) |
@set -e |
@$(LD) $(LD_OPTS) -I $(NEORV32_INC_PATH) $(APP_INC) -T $(NEORV32_COM_PATH)/bootloader_neorv32.ld $(OBJ) $(LIBC_PATH) $(LIBGCC_PATH) -o bootloader.elf |
@echo "Memory utilization:" |
@$(SIZE) bootloader.elf |
@$(OBJDUMP) -D -S -z bootloader.elf > bootloader.s |
@$(OBJCOPY) -I elf32-little bootloader.elf -j .text -O binary text.bin |
@$(OBJCOPY) -I elf32-little bootloader.elf -j .rodata -O binary rodata.bin |
@$(OBJCOPY) -I elf32-little bootloader.elf -j .data -O binary data.bin |
@cat text.bin rodata.bin data.bin > bootloader.bin |
@$(IMAGE_GEN) -bld_img bootloader.bin neorv32_bootloader_image.vhd $(shell basename $(CURDIR)) |
@echo "Installing bootloader image to $(NEORV32_RTL_PATH)/neorv32_bootloader_image.vhd" |
@cp neorv32_bootloader_image.vhd $(NEORV32_RTL_PATH)/. |
@rm -f neorv32_bootloader_image.vhd text.bin rodata.bin data.bin |
|
|
# ----------------------------------------------------------------------------- |
# Check toolchain |
# ----------------------------------------------------------------------------- |
check: $(IMAGE_GEN) |
@echo "---------------- Check: NEORV32_HOME folder ----------------" |
ifneq ($(shell [ -e $(NEORV32_HOME_MARKER) ] && echo 1 || echo 0 ), 1) |
$(error NEORV32_HOME folder not found!) |
endif |
@echo "NEORV32_HOME: $(NEORV32_HOME)" |
@echo "---------------- Check: $(CC) ----------------" |
@$(CC) -v |
@echo "---------------- Check: $(LD) ----------------" |
@$(LD) -V |
@echo "---------------- Check: $(OBJDUMP) ----------------" |
@$(OBJDUMP) -V |
@echo "---------------- Check: $(OBJCOPY) ----------------" |
@$(OBJCOPY) -V |
@echo "---------------- Check: $(SIZE) ----------------" |
@$(SIZE) -V |
@echo "---------------- Check: NEORV32 image_gen ----------------" |
@$(IMAGE_GEN) -help |
@echo "---------------- Check: native gcc ----------------" |
@$(CC_X86) -v |
@echo |
@echo "Toolchain check OK" |
|
|
# ----------------------------------------------------------------------------- |
# Show configuration |
# ----------------------------------------------------------------------------- |
info: |
@echo "---------------- Info: Project ----------------" |
@echo "Project folder: $(shell basename $(CURDIR))" |
@echo "Source files: $(APP_SRC)" |
@echo "Include folder(s): $(APP_INC)" |
@echo "---------------- Info: NEORV32 ----------------" |
@echo "NEORV32 home folder (NEORV32_HOME): $(NEORV32_HOME)" |
@echo "IMAGE_GEN: $(IMAGE_GEN)" |
@echo "Core source files:" |
@echo "$(CORE_SRC)" |
@echo "Core include folder:" |
@echo "$(NEORV32_INC_PATH)" |
@echo "Project object files:" |
@echo "$(OBJ)" |
@echo "---------------- Info: RISC-V CPU ----------------" |
@echo "MARCH: $(MARCH)" |
@echo "MABI: $(MABI)" |
@echo "---------------- Info: RISC-V Toolchain ----------------" |
@echo "Toolchain: $(RISCV_TOLLCHAIN)" |
@echo "CC: $(CC)" |
@echo "LD: $(LD)" |
@echo "OBJDUMP: $(OBJDUMP)" |
@echo "OBJCOPY: $(OBJCOPY)" |
@echo "SIZE: $(SIZE)" |
@echo "---------------- Info: C Lib ----------------" |
@echo "CLIB: $(LIBC_PATH)" |
@echo "GCCLIB: $(LIBGCC_PATH)" |
@echo "---------------- Info: Flags ----------------" |
@echo "CC_OPTS: $(CC_OPTS)" |
@echo "LD_OPTS: $(LD_OPTS)" |
@echo "---------------- Info: Host Native GCC ----------------" |
@echo "CC_X86: $(CC_X86)" |
|
|
# ----------------------------------------------------------------------------- |
# Show final ELF details (just for debugging) |
# ----------------------------------------------------------------------------- |
elf_info: main.elf |
@$(OBJDUMP) -x main.elf |
|
|
# ----------------------------------------------------------------------------- |
# Help |
# ----------------------------------------------------------------------------- |
help: |
@echo "<<< NEORV32 Application Makefile >>>" |
@echo "Make sure to add the bin folder of RISC-V GCC to your PATH variable." |
@echo "Targets:" |
@echo " help - show this text" |
@echo " check - check toolchain" |
@echo " info - show makefile/toolchain configuration" |
@echo " compile - compile and generate <neorv32_exe.bin> executable for upload via bootloader" |
@echo " install - compile, generate and install VHDL IMEM boot image" |
@echo " all - compile and generate <neorv32_exe.bin> executable for upload via bootloader and generate and install VHDL IMEM boot image" |
@echo " clean - clean up project" |
@echo " clean_all - clean up project, core libraries and image generator" |
@echo " bootloader - compile, generate and install VHDL BOOTROM bott image (for bootloader only!)" |
|
|
# ----------------------------------------------------------------------------- |
# Clean up |
# ----------------------------------------------------------------------------- |
clean: |
@rm -f *.elf *.o *.bin *.out *.s |
|
clean_all: clean |
@rm -f $(OBJ) $(IMAGE_GEN) |
|
/sw/example/demo_pwm/makefile
82,16 → 82,14
|
|
# ----------------------------------------------------------------------------- |
# Add NEORV32 sources to input SRCs |
# NEORV32 core sources |
# ----------------------------------------------------------------------------- |
APP_SRC += $(wildcard $(NEORV32_SRC_PATH)/*.c) |
CORE_SRC = $(wildcard $(NEORV32_SRC_PATH)/*.c) |
|
|
# ----------------------------------------------------------------------------- |
# Make defaults |
# ----------------------------------------------------------------------------- |
.SUFFIXES: |
.PHONY: all |
.DEFAULT_GOAL := help |
|
|
106,7 → 104,8
all: $(APP_ASM) $(APP_EXE) neorv32_application_image.vhd |
|
# define all object files |
OBJ = $(APP_SRC:.c=.o) |
OBJ = $(APP_SRC:.c=.o) |
OBJ += $(CORE_SRC:.c=.o) |
|
|
# ----------------------------------------------------------------------------- |
259,13 → 258,18
# ----------------------------------------------------------------------------- |
info: |
@echo "---------------- Info: Project ----------------" |
@echo "Project: $(shell basename $(CURDIR))" |
@echo "Project source files: $(APP_SRC)" |
@echo "Project include folders: $(NEORV32_INC_PATH) $(APP_INC)" |
@echo "Project object files: $(OBJ)" |
@echo "Project folder: $(shell basename $(CURDIR))" |
@echo "Source files: $(APP_SRC)" |
@echo "Include folder(s): $(APP_INC)" |
@echo "---------------- Info: NEORV32 ----------------" |
@echo "NEORV32 home folder (NEORV32_HOME): $(NEORV32_HOME)" |
@echo "IMAGE_GEN: $(IMAGE_GEN)" |
@echo "Core source files:" |
@echo "$(CORE_SRC)" |
@echo "Core include folder:" |
@echo "$(NEORV32_INC_PATH)" |
@echo "Project object files:" |
@echo "$(OBJ)" |
@echo "---------------- Info: RISC-V CPU ----------------" |
@echo "MARCH: $(MARCH)" |
@echo "MABI: $(MABI)" |
/sw/example/demo_trng/makefile
82,16 → 82,14
|
|
# ----------------------------------------------------------------------------- |
# Add NEORV32 sources to input SRCs |
# NEORV32 core sources |
# ----------------------------------------------------------------------------- |
APP_SRC += $(wildcard $(NEORV32_SRC_PATH)/*.c) |
CORE_SRC = $(wildcard $(NEORV32_SRC_PATH)/*.c) |
|
|
# ----------------------------------------------------------------------------- |
# Make defaults |
# ----------------------------------------------------------------------------- |
.SUFFIXES: |
.PHONY: all |
.DEFAULT_GOAL := help |
|
|
106,7 → 104,8
all: $(APP_ASM) $(APP_EXE) neorv32_application_image.vhd |
|
# define all object files |
OBJ = $(APP_SRC:.c=.o) |
OBJ = $(APP_SRC:.c=.o) |
OBJ += $(CORE_SRC:.c=.o) |
|
|
# ----------------------------------------------------------------------------- |
259,13 → 258,18
# ----------------------------------------------------------------------------- |
info: |
@echo "---------------- Info: Project ----------------" |
@echo "Project: $(shell basename $(CURDIR))" |
@echo "Project source files: $(APP_SRC)" |
@echo "Project include folders: $(NEORV32_INC_PATH) $(APP_INC)" |
@echo "Project object files: $(OBJ)" |
@echo "Project folder: $(shell basename $(CURDIR))" |
@echo "Source files: $(APP_SRC)" |
@echo "Include folder(s): $(APP_INC)" |
@echo "---------------- Info: NEORV32 ----------------" |
@echo "NEORV32 home folder (NEORV32_HOME): $(NEORV32_HOME)" |
@echo "IMAGE_GEN: $(IMAGE_GEN)" |
@echo "Core source files:" |
@echo "$(CORE_SRC)" |
@echo "Core include folder:" |
@echo "$(NEORV32_INC_PATH)" |
@echo "Project object files:" |
@echo "$(OBJ)" |
@echo "---------------- Info: RISC-V CPU ----------------" |
@echo "MARCH: $(MARCH)" |
@echo "MABI: $(MABI)" |
/sw/example/demo_twi/makefile
82,16 → 82,14
|
|
# ----------------------------------------------------------------------------- |
# Add NEORV32 sources to input SRCs |
# NEORV32 core sources |
# ----------------------------------------------------------------------------- |
APP_SRC += $(wildcard $(NEORV32_SRC_PATH)/*.c) |
CORE_SRC = $(wildcard $(NEORV32_SRC_PATH)/*.c) |
|
|
# ----------------------------------------------------------------------------- |
# Make defaults |
# ----------------------------------------------------------------------------- |
.SUFFIXES: |
.PHONY: all |
.DEFAULT_GOAL := help |
|
|
106,7 → 104,8
all: $(APP_ASM) $(APP_EXE) neorv32_application_image.vhd |
|
# define all object files |
OBJ = $(APP_SRC:.c=.o) |
OBJ = $(APP_SRC:.c=.o) |
OBJ += $(CORE_SRC:.c=.o) |
|
|
# ----------------------------------------------------------------------------- |
259,13 → 258,18
# ----------------------------------------------------------------------------- |
info: |
@echo "---------------- Info: Project ----------------" |
@echo "Project: $(shell basename $(CURDIR))" |
@echo "Project source files: $(APP_SRC)" |
@echo "Project include folders: $(NEORV32_INC_PATH) $(APP_INC)" |
@echo "Project object files: $(OBJ)" |
@echo "Project folder: $(shell basename $(CURDIR))" |
@echo "Source files: $(APP_SRC)" |
@echo "Include folder(s): $(APP_INC)" |
@echo "---------------- Info: NEORV32 ----------------" |
@echo "NEORV32 home folder (NEORV32_HOME): $(NEORV32_HOME)" |
@echo "IMAGE_GEN: $(IMAGE_GEN)" |
@echo "Core source files:" |
@echo "$(CORE_SRC)" |
@echo "Core include folder:" |
@echo "$(NEORV32_INC_PATH)" |
@echo "Project object files:" |
@echo "$(OBJ)" |
@echo "---------------- Info: RISC-V CPU ----------------" |
@echo "MARCH: $(MARCH)" |
@echo "MABI: $(MABI)" |
/sw/example/demo_wdt/makefile
82,16 → 82,14
|
|
# ----------------------------------------------------------------------------- |
# Add NEORV32 sources to input SRCs |
# NEORV32 core sources |
# ----------------------------------------------------------------------------- |
APP_SRC += $(wildcard $(NEORV32_SRC_PATH)/*.c) |
CORE_SRC = $(wildcard $(NEORV32_SRC_PATH)/*.c) |
|
|
# ----------------------------------------------------------------------------- |
# Make defaults |
# ----------------------------------------------------------------------------- |
.SUFFIXES: |
.PHONY: all |
.DEFAULT_GOAL := help |
|
|
106,7 → 104,8
all: $(APP_ASM) $(APP_EXE) neorv32_application_image.vhd |
|
# define all object files |
OBJ = $(APP_SRC:.c=.o) |
OBJ = $(APP_SRC:.c=.o) |
OBJ += $(CORE_SRC:.c=.o) |
|
|
# ----------------------------------------------------------------------------- |
259,13 → 258,18
# ----------------------------------------------------------------------------- |
info: |
@echo "---------------- Info: Project ----------------" |
@echo "Project: $(shell basename $(CURDIR))" |
@echo "Project source files: $(APP_SRC)" |
@echo "Project include folders: $(NEORV32_INC_PATH) $(APP_INC)" |
@echo "Project object files: $(OBJ)" |
@echo "Project folder: $(shell basename $(CURDIR))" |
@echo "Source files: $(APP_SRC)" |
@echo "Include folder(s): $(APP_INC)" |
@echo "---------------- Info: NEORV32 ----------------" |
@echo "NEORV32 home folder (NEORV32_HOME): $(NEORV32_HOME)" |
@echo "IMAGE_GEN: $(IMAGE_GEN)" |
@echo "Core source files:" |
@echo "$(CORE_SRC)" |
@echo "Core include folder:" |
@echo "$(NEORV32_INC_PATH)" |
@echo "Project object files:" |
@echo "$(OBJ)" |
@echo "---------------- Info: RISC-V CPU ----------------" |
@echo "MARCH: $(MARCH)" |
@echo "MABI: $(MABI)" |
/sw/example/game_of_life/makefile
82,16 → 82,14
|
|
# ----------------------------------------------------------------------------- |
# Add NEORV32 sources to input SRCs |
# NEORV32 core sources |
# ----------------------------------------------------------------------------- |
APP_SRC += $(wildcard $(NEORV32_SRC_PATH)/*.c) |
CORE_SRC = $(wildcard $(NEORV32_SRC_PATH)/*.c) |
|
|
# ----------------------------------------------------------------------------- |
# Make defaults |
# ----------------------------------------------------------------------------- |
.SUFFIXES: |
.PHONY: all |
.DEFAULT_GOAL := help |
|
|
106,7 → 104,8
all: $(APP_ASM) $(APP_EXE) neorv32_application_image.vhd |
|
# define all object files |
OBJ = $(APP_SRC:.c=.o) |
OBJ = $(APP_SRC:.c=.o) |
OBJ += $(CORE_SRC:.c=.o) |
|
|
# ----------------------------------------------------------------------------- |
259,13 → 258,18
# ----------------------------------------------------------------------------- |
info: |
@echo "---------------- Info: Project ----------------" |
@echo "Project: $(shell basename $(CURDIR))" |
@echo "Project source files: $(APP_SRC)" |
@echo "Project include folders: $(NEORV32_INC_PATH) $(APP_INC)" |
@echo "Project object files: $(OBJ)" |
@echo "Project folder: $(shell basename $(CURDIR))" |
@echo "Source files: $(APP_SRC)" |
@echo "Include folder(s): $(APP_INC)" |
@echo "---------------- Info: NEORV32 ----------------" |
@echo "NEORV32 home folder (NEORV32_HOME): $(NEORV32_HOME)" |
@echo "IMAGE_GEN: $(IMAGE_GEN)" |
@echo "Core source files:" |
@echo "$(CORE_SRC)" |
@echo "Core include folder:" |
@echo "$(NEORV32_INC_PATH)" |
@echo "Project object files:" |
@echo "$(OBJ)" |
@echo "---------------- Info: RISC-V CPU ----------------" |
@echo "MARCH: $(MARCH)" |
@echo "MABI: $(MABI)" |
/sw/lib/include/neorv32.h
60,10 → 60,10
* Available CPU Control and Status Registers (CSRs) |
**************************************************************************/ |
enum NEORV32_CPU_CSRS_enum { |
CSR_MSTATUS = 0x300, /**< 0x300 - mstatus (r/w): Machine status register */ |
CSR_MISA = 0x301, /**< 0x301 - misa (r/-): CPU ISA and extensions */ |
CSR_MIE = 0x304, /**< 0x304 - mie (r/w): Machine interrupt-enable register */ |
CSR_MTVEC = 0x305, /**< 0x305 - mtvec (r/w): Machine trap-handler base address (for ALL traps) */ |
CSR_MSTATUS = 0x300, /**< 0x300 - mstatus (r/w): Machine status register */ |
CSR_MISA = 0x301, /**< 0x301 - misa (r/-): CPU ISA and extensions */ |
CSR_MIE = 0x304, /**< 0x304 - mie (r/w): Machine interrupt-enable register */ |
CSR_MTVEC = 0x305, /**< 0x305 - mtvec (r/w): Machine trap-handler base address (for ALL traps) */ |
|
CSR_MSCRATCH = 0x340, /**< 0x340 - mscratch (r/w): Machine scratch register */ |
CSR_MEPC = 0x341, /**< 0x341 - mepc (r/w): Machine exception program counter */ |
127,6 → 127,21
|
|
/**********************************************************************//** |
* CPU <b>misa</b> CSR (r/w): Machine instruction set extensions (RISC-V spec.) |
**************************************************************************/ |
enum NEORV32_CPU_MISA_enum { |
CPU_MISA_C_EXT = 2, /**< CPU misa CSR (2): C: Compressed instructions CPU extension available (r/w), can be switched on/off */ |
CPU_MISA_E_EXT = 4, /**< CPU misa CSR (3): E: Embedded CPU extension available (r/-) */ |
CPU_MISA_I_EXT = 8, /**< CPU misa CSR (8): I: Base integer ISA CPU extension available (r/-) */ |
CPU_MISA_M_EXT = 12, /**< CPU misa CSR (12): M: Multiplier/divider CPU extension available (r/w), can be switched on/off */ |
CPU_MISA_X_EXT = 23, /**< CPU misa CSR (23): X: Non-standard CPU extension available (r/-) */ |
CPU_MISA_Z_EXT = 25, /**< CPU misa CSR (25): Z: Privileged architecture CPU extension available (r/-) */ |
CPU_MISA_MXL_LO_EXT = 30, /**< CPU misa CSR (30): MXL.lo: CPU data width (r/-) */ |
CPU_MISA_MXL_HI_EXT = 31 /**< CPU misa CSR (31): MXL.Hi: CPU data width (r/-) */ |
}; |
|
|
/**********************************************************************//** |
* CPU <b>mfeatures</b> CSR (r/-): Implemented processor devices/features (CUSTOM) |
**************************************************************************/ |
enum NEORV32_CPU_MFEATURES_enum { |
135,6 → 150,7
CPU_MFEATURES_MEM_INT_IMEM = 2, /**< CPU mfeatures CSR (2) (r/-): Processor-internal instruction memory implemented when 1 (via MEM_INT_IMEM_USE generic) */ |
CPU_MFEATURES_MEM_INT_IMEM_ROM = 3, /**< CPU mfeatures CSR (3) (r/-): Processor-internal instruction memory implemented as ROM when 1 (via MEM_INT_IMEM_ROM generic) */ |
CPU_MFEATURES_MEM_INT_DMEM = 4, /**< CPU mfeatures CSR (4) (r/-): Processor-internal data memory implemented when 1 (via MEM_INT_DMEM_USE generic) */ |
CPU_MFEATURES_CSR_COUNTERS = 5, /**< CPU mfeatures CSR (5) (r/-): RISC-V performance counters implemented when 1 (via CSR_COUNTERS_USE generic) */ |
|
CPU_MFEATURES_IO_GPIO = 16, /**< CPU mfeatures CSR (16) (r/-): General purpose input/output port unit implemented when 1 (via IO_GPIO_USE generic) */ |
CPU_MFEATURES_IO_MTIME = 17, /**< CPU mfeatures CSR (17) (r/-): Machine system timer implemented when 1 (via IO_MTIME_USE generic) */ |
211,13 → 227,13
**************************************************************************/ |
/**@{*/ |
/** instruction memory base address (r/w/x) */ |
#define INSTR_MEM_BASE_ADDR 0x00000000 |
// -> use value from MEM_ISPACE_BASE CSR |
/** data memory base address (r/w/x) */ |
#define DATA_MEM_BASE_ADDR 0x80000000 |
// -> use value from MEM_DSPACE_BASE CSR |
/** bootloader memory base address (r/-/x) */ |
#define BOOTLOADER_BASE_ADDRESS 0xFFFF0000 |
#define BOOTLOADER_BASE_ADDRESS (0xFFFF0000UL) |
/** peripheral/IO devices memory base address (r/w/x) */ |
#define IO_BASE_ADDRESS 0xFFFFFF80 |
#define IO_BASE_ADDRESS (0xFFFFFF80UL) |
/**@}*/ |
|
|
226,9 → 242,9
**************************************************************************/ |
/**@{*/ |
/** GPIO parallel input port (r/-) */ |
#define GPIO_INPUT (*(IO_ROM32 0xFFFFFF80)) |
#define GPIO_INPUT (*(IO_ROM32 0xFFFFFF80UL)) |
/** GPIO parallel output port (r/w) */ |
#define GPIO_OUTPUT (*(IO_REG32 0xFFFFFF84)) |
#define GPIO_OUTPUT (*(IO_REG32 0xFFFFFF84UL)) |
/**@}*/ |
|
|
237,7 → 253,7
**************************************************************************/ |
/**@{*/ |
/** CLIC control register (r/w) */ |
#define CLIC_CT (*(IO_REG32 0xFFFFFF88)) |
#define CLIC_CT (*(IO_REG32 0xFFFFFF88UL)) |
|
/** CLIC control register bits */ |
enum NEORV32_CLIC_CT_enum { |
284,7 → 300,7
**************************************************************************/ |
/**@{*/ |
/** Watchdog control register (r/w) */ |
#define WDT_CT (*(IO_REG32 0xFFFFFF8C)) |
#define WDT_CT (*(IO_REG32 0xFFFFFF8CUL)) |
|
/** WTD control register bits */ |
enum NEORV32_WDT_CT_enum { |
310,13 → 326,13
**************************************************************************/ |
/**@{*/ |
/** MTIME (time register) low word (r/-) */ |
#define MTIME_LO (*(IO_ROM32 0xFFFFFF90)) |
#define MTIME_LO (*(IO_ROM32 0xFFFFFF90UL)) |
/** MTIME (time register) high word (r/-) */ |
#define MTIME_HI (*(IO_ROM32 0xFFFFFF94)) |
#define MTIME_HI (*(IO_ROM32 0xFFFFFF94UL)) |
/** MTIMECMP (time compare register) low word (r/w) */ |
#define MTIMECMP_LO (*(IO_REG32 0xFFFFFF98)) |
#define MTIMECMP_LO (*(IO_REG32 0xFFFFFF98UL)) |
/** MTIMECMP (time register) high word (r/w) */ |
#define MTIMECMP_HI (*(IO_REG32 0xFFFFFF9C)) |
#define MTIMECMP_HI (*(IO_REG32 0xFFFFFF9CUL)) |
|
/** MTIME (time register) 64-bit access (r/-) */ |
#define MTIME (*(IO_ROM64 (&MTIME_LO))) |
330,9 → 346,9
**************************************************************************/ |
/**@{*/ |
/** UART control register (r/w) */ |
#define UART_CT (*(IO_REG32 0xFFFFFFA0)) |
#define UART_CT (*(IO_REG32 0xFFFFFFA0UL)) |
/** UART receive/transmit data register (r/w) */ |
#define UART_DATA (*(IO_REG32 0xFFFFFFA4)) |
#define UART_DATA (*(IO_REG32 0xFFFFFFA4UL)) |
|
/** UART control register bits */ |
enum NEORV32_UART_CT_enum { |
373,9 → 389,9
**************************************************************************/ |
/**@{*/ |
/** SPI control register (r/w) */ |
#define SPI_CT (*(IO_REG32 0xFFFFFFA8)) |
#define SPI_CT (*(IO_REG32 0xFFFFFFA8UL)) |
/** SPI receive/transmit data register (r/w) */ |
#define SPI_DATA (*(IO_REG32 0xFFFFFFAC)) |
#define SPI_DATA (*(IO_REG32 0xFFFFFFACUL)) |
|
/** SPI control register bits */ |
enum NEORV32_SPI_CT_enum { |
409,9 → 425,9
**************************************************************************/ |
/**@{*/ |
/** TWI control register (r/w) */ |
#define TWI_CT (*(IO_REG32 0xFFFFFFB0)) |
#define TWI_CT (*(IO_REG32 0xFFFFFFB0UL)) |
/** TWI receive/transmit data register (r/w) */ |
#define TWI_DATA (*(IO_REG32 0xFFFFFFB4)) |
#define TWI_DATA (*(IO_REG32 0xFFFFFFB4UL)) |
|
/** TWI control register bits */ |
enum NEORV32_TWI_CT_enum { |
441,9 → 457,9
**************************************************************************/ |
/**@{*/ |
/** PWM control register (r/w) */ |
#define PWM_CT (*(IO_REG32 0xFFFFFFB8)) // r/w: control register |
#define PWM_CT (*(IO_REG32 0xFFFFFFB8UL)) // r/w: control register |
/** PWM duty cycle register (4-channels) (r/w) */ |
#define PWM_DUTY (*(IO_REG32 0xFFFFFFBC)) // r/w: duty cycle channel 1 and 0 |
#define PWM_DUTY (*(IO_REG32 0xFFFFFFBCUL)) // r/w: duty cycle channel 1 and 0 |
|
/** PWM control register bits */ |
enum NEORV32_PWM_CT_enum { |
472,9 → 488,9
**************************************************************************/ |
/**@{*/ |
/** TRNG control register (r/w) */ |
#define TRNG_CT (*(IO_REG32 0xFFFFFFC0)) |
#define TRNG_CT (*(IO_REG32 0xFFFFFFC0UL)) |
/** TRNG data register (r/-) */ |
#define TRNG_DATA (*(IO_ROM32 0xFFFFFFC4)) |
#define TRNG_DATA (*(IO_ROM32 0xFFFFFFC4UL)) |
|
/** TRNG control register bits */ |
enum NEORV32_TRNG_CT_enum { |
496,8 → 512,8
* @name IO Device: Dummy Device (DEVNULL) |
**************************************************************************/ |
/**@{*/ |
/** TRNG data register (r/w) */ |
#define DEVNULL_DATA (*(IO_REG32 0xFFFFFFFC)) |
/** DEVNULL data register (r/w) */ |
#define DEVNULL_DATA (*(IO_REG32 0xFFFFFFFCUL)) |
/**@}*/ |
|
|
/sw/lib/include/neorv32_cpu.h
64,7 → 64,7
|
register uint32_t csr_data; |
|
asm volatile ("csrrw %[result], %[input_i], zero" : [result] "=r" (csr_data) : [input_i] "i" (csr_id)); |
asm volatile ("csrr %[result], %[input_i]" : [result] "=r" (csr_data) : [input_i] "i" (csr_id)); |
|
return csr_data; |
} |
80,7 → 80,7
|
register uint32_t csr_data = data; |
|
asm volatile ("csrrw zero, %[input_i], %[input_j]" : : [input_i] "i" (csr_id), [input_j] "r" (csr_data)); |
asm volatile ("csrw %[input_i], %[input_j]" : : [input_i] "i" (csr_id), [input_j] "r" (csr_data)); |
} |
|
#endif // neorv32_cpu_h |
/sw/lib/include/neorv32_rte.h
44,7 → 44,8
|
// prototypes |
void neorv32_rte_enable_debug_mode(void); |
int neorv32_rte_exception_install(uint8_t exc_id, void (*handler)(void)); |
int neorv32_rte_exception_uninstall(uint8_t exc_id); |
int neorv32_rte_exception_install(uint8_t exc_id, void (*handler)(void)); |
int neorv32_rte_exception_uninstall(uint8_t exc_id); |
void neorv32_rte_print_hw_config(void); |
|
#endif // neorv32_rte_h |
/sw/lib/source/neorv32_rte.c
43,8 → 43,10
#include "neorv32_rte.h" |
|
// Privates |
static void __neorv32_rte_dummy_exc_handler(void) __attribute__((unused)); |
static void __neorv32_rte_debug_exc_handler(void) __attribute__((unused)); |
static void __neorv32_rte_dummy_exc_handler(void) __attribute__((unused)); |
static void __neorv32_rte_debug_exc_handler(void) __attribute__((unused)); |
static void __neorv32_rte_print_true_false(int state) __attribute__((unused)); |
static void __neorv32_rte_print_hw_version(void) __attribute__((unused)); |
|
|
/**********************************************************************//** |
151,11 → 153,13
**************************************************************************/ |
static void __neorv32_rte_debug_exc_handler(void) { |
|
neorv32_uart_printf("\n\n\n<<< NEORV32 Runtime Environment >>>\n"); |
neorv32_uart_printf("\n\n<< NEORV32 Runtime Environment >>\n"); |
|
neorv32_uart_printf("System time: 0x%x_%x\n", neorv32_cpu_csr_read(CSR_TIMEH), neorv32_cpu_csr_read(CSR_TIME)); |
|
uint32_t exc_cause = neorv32_cpu_csr_read(CSR_MCAUSE); |
register uint32_t exc_cause = neorv32_cpu_csr_read(CSR_MCAUSE); |
register uint32_t return_addr = neorv32_cpu_csr_read(CSR_MEPC); |
register uint32_t trans_cmd = neorv32_cpu_csr_read(CSR_MTINST); |
|
if (exc_cause & 0x80000000) { |
neorv32_uart_printf("INTERRUPT"); |
162,8 → 166,14
} |
else { |
neorv32_uart_printf("EXCEPTION"); |
if ((trans_cmd & (1 << 1)) == 0) { |
return_addr -= 4; |
} |
else { |
return_addr -= 2; |
} |
} |
neorv32_uart_printf(" at instruction address: 0x%x\n", neorv32_cpu_csr_read(CSR_MEPC)); |
neorv32_uart_printf(" at instruction address: 0x%x\n", return_addr); |
|
neorv32_uart_printf("Cause: "); |
switch (exc_cause) { |
190,18 → 200,179
neorv32_uart_printf("\nFaulting address"); |
} |
neorv32_uart_printf(": 0x%x\n", neorv32_cpu_csr_read(CSR_MTVAL)); |
uint32_t trans_cmd = neorv32_cpu_csr_read(CSR_MTINST); |
neorv32_uart_printf("Transf. instruction: 0x%x ", trans_cmd); |
|
if (trans_cmd & (1 << 1)) { |
neorv32_uart_printf("(uncompr.)\n"); |
if ((trans_cmd & (1 << 1)) == 0) { |
neorv32_uart_printf("(decompressed)\n"); |
} |
|
neorv32_uart_printf("Trying to resume application @ 0x%x...", neorv32_cpu_csr_read(CSR_MEPC)); |
|
neorv32_uart_printf("\n<</NEORV32 Runtime Environment >>\n\n"); |
} |
|
|
/**********************************************************************//** |
* NEORV32 runtime environment: Print hardware configuration information via UART |
**************************************************************************/ |
void neorv32_rte_print_hw_config(void) { |
|
uint32_t tmp; |
int i; |
char c; |
|
neorv32_uart_printf("\n\n<< NEORV32 Hardware Configuration Overview >>\n"); |
|
// CPU configuration |
neorv32_uart_printf("\n-- Central Processing Unit --\n"); |
|
// Hart ID |
neorv32_uart_printf("Hart ID: 0x%x\n", neorv32_cpu_csr_read(CSR_MHARTID)); |
|
// HW version |
neorv32_uart_printf("Hardware version: "); |
__neorv32_rte_print_hw_version(); |
neorv32_uart_printf(" (0x%x)\n", neorv32_cpu_csr_read(CSR_MIMPID)); |
|
// CPU architecture |
neorv32_uart_printf("Architecture: "); |
tmp = neorv32_cpu_csr_read(CSR_MISA); |
tmp = (tmp >> 30) & 0x03; |
if (tmp == 0) { |
neorv32_uart_printf("unknown"); |
} |
if (tmp == 1) { |
neorv32_uart_printf("RV32"); |
} |
if (tmp == 2) { |
neorv32_uart_printf("RV64"); |
} |
if (tmp == 3) { |
neorv32_uart_printf("RV128"); |
} |
|
// CPU extensions |
neorv32_uart_printf("\nCPU extensions: "); |
tmp = neorv32_cpu_csr_read(CSR_MISA); |
for (i=0; i<26; i++) { |
if (tmp & (1 << i)) { |
c = (char)('A' + i); |
neorv32_uart_putc(c); |
neorv32_uart_putc(' '); |
} |
} |
neorv32_uart_printf("(0x%x)\n", tmp); |
|
// Performance counters |
neorv32_uart_printf("CNT & time CSRs: "); |
__neorv32_rte_print_true_false(neorv32_cpu_csr_read(CSR_MFEATURES) & (1 << CPU_MFEATURES_CSR_COUNTERS)); |
|
// Clock speed |
neorv32_uart_printf("Clock speed: %u Hz\n", neorv32_cpu_csr_read(CSR_MCLOCK)); |
|
// Memory configuration |
neorv32_uart_printf("\n-- Memory Configuration --\n"); |
|
uint32_t size = neorv32_cpu_csr_read(CSR_MISPACESIZE); |
uint32_t base = neorv32_cpu_csr_read(CSR_MISPACEBASE); |
neorv32_uart_printf("Instruction memory: %u bytes @ 0x%x\n", size, base); |
neorv32_uart_printf("Internal IMEM: "); |
__neorv32_rte_print_true_false(neorv32_cpu_csr_read(CSR_MFEATURES) & (1 << CPU_MFEATURES_MEM_INT_IMEM)); |
neorv32_uart_printf("Internal IMEM as ROM: "); |
__neorv32_rte_print_true_false(neorv32_cpu_csr_read(CSR_MFEATURES) & (1 << CPU_MFEATURES_MEM_INT_IMEM_ROM)); |
|
size = neorv32_cpu_csr_read(CSR_MDSPACESIZE); |
base = neorv32_cpu_csr_read(CSR_MDSPACEBASE); |
neorv32_uart_printf("Data memory: %u bytes @ 0x%x\n", size, base); |
neorv32_uart_printf("Internal DMEM: "); |
__neorv32_rte_print_true_false(neorv32_cpu_csr_read(CSR_MFEATURES) & (1 << CPU_MFEATURES_MEM_INT_DMEM)); |
|
neorv32_uart_printf("Bootloader: "); |
__neorv32_rte_print_true_false(neorv32_cpu_csr_read(CSR_MFEATURES) & (1 << CPU_MFEATURES_BOOTLOADER)); |
|
neorv32_uart_printf("External interface: "); |
__neorv32_rte_print_true_false(neorv32_cpu_csr_read(CSR_MFEATURES) & (1 << CPU_MFEATURES_MEM_EXT)); |
|
// peripherals |
neorv32_uart_printf("\n-- Peripherals --\n"); |
tmp = neorv32_cpu_csr_read(CSR_MFEATURES); |
|
neorv32_uart_printf("GPIO: "); |
__neorv32_rte_print_true_false(tmp & (1 << CPU_MFEATURES_IO_GPIO)); |
|
neorv32_uart_printf("MTIME: "); |
__neorv32_rte_print_true_false(tmp & (1 << CPU_MFEATURES_IO_MTIME)); |
|
neorv32_uart_printf("UART: "); |
__neorv32_rte_print_true_false(tmp & (1 << CPU_MFEATURES_IO_UART)); |
|
neorv32_uart_printf("SPI: "); |
__neorv32_rte_print_true_false(tmp & (1 << CPU_MFEATURES_IO_SPI)); |
|
neorv32_uart_printf("TWI: "); |
__neorv32_rte_print_true_false(tmp & (1 << CPU_MFEATURES_IO_TWI)); |
|
neorv32_uart_printf("PWM: "); |
__neorv32_rte_print_true_false(tmp & (1 << CPU_MFEATURES_IO_PWM)); |
|
neorv32_uart_printf("WDT: "); |
__neorv32_rte_print_true_false(tmp & (1 << CPU_MFEATURES_IO_WDT)); |
|
neorv32_uart_printf("CLIC: "); |
__neorv32_rte_print_true_false(tmp & (1 << CPU_MFEATURES_IO_CLIC)); |
|
neorv32_uart_printf("TRNG: "); |
__neorv32_rte_print_true_false(tmp & (1 << CPU_MFEATURES_IO_TRNG)); |
|
neorv32_uart_printf("DEVNULL: "); |
__neorv32_rte_print_true_false(tmp & (1 << CPU_MFEATURES_IO_DEVNULL)); |
} |
|
|
/**********************************************************************//** |
* NEORV32 runtime environment: Private function to print true or false. |
* @note This function is used by neorv32_rte_print_hw_config(void) only. |
* |
* @param[in] state Print TRUE when !=0, print FALSE when 0 |
**************************************************************************/ |
static void __neorv32_rte_print_true_false(int state) { |
|
if (state) { |
neorv32_uart_printf("True\n"); |
} |
else { |
neorv32_uart_printf("(compr.)\n"); |
neorv32_uart_printf("False\n"); |
} |
} |
|
neorv32_uart_printf("Trying to resume application @ 0x%x...", neorv32_cpu_csr_read(CSR_MSCRATCH)); |
|
neorv32_uart_printf("\n<<</NEORV32 Runtime Environment >>>\n\n\n"); |
/**********************************************************************//** |
* NEORV32 runtime environment: Private function to show the processor version in human-readable format. |
* @note This function is used by neorv32_rte_print_hw_config(void) only. |
**************************************************************************/ |
static void __neorv32_rte_print_hw_version(void) { |
|
uint32_t i; |
char tmp, cnt; |
uint32_t version = neorv32_cpu_csr_read(CSR_MIMPID); |
|
for (i=0; i<4; i++) { |
|
tmp = (char)(version >> (24 - 8*i)); |
|
// serial division |
cnt = 0; |
while (tmp >= 10) { |
tmp = tmp - 10; |
cnt++; |
} |
|
if (cnt) { |
neorv32_uart_putc('0' + cnt); |
} |
neorv32_uart_putc('0' + tmp); |
if (i < 3) { |
neorv32_uart_putc('.'); |
} |
} |
} |
|
/README.md
56,10 → 56,15
|
### Status |
|
![processor status](https://img.shields.io/badge/processor%20status-beta-orange) |
The processor is synthesizable (tested with Intel Quartus Prime, Xilinx Vivado and Lattice Radiant/LSE) and can successfully execute |
all the [provided example programs](https://github.com/stnolting/neorv32/tree/master/sw/example) including the CoreMark benchmark. |
|
The processor is synthesizable (tested with Intel Quartus Prime and Lattice Radiant/Synplify) and can successfully execute all the [provided example programs](https://github.com/stnolting/neorv32/tree/master/sw/example). |
The processor passes the `rv32i`, `rv32im`, `rv32imc` and `rv32Zicsr` *RISC-V compliance tests*. |
|
[RISC-V compliance test](https://github.com/stnolting/neorv32_compliance_test): |
[![Build Status](https://travis-ci.com/stnolting/neorv32_riscv_compliance.svg?branch=master)](https://travis-ci.com/stnolting/neorv32_riscv_compliance) |
|
|
## Features |
|
![neorv32 Overview](https://raw.githubusercontent.com/stnolting/neorv32/master/docs/figures/neorv32_overview.png) |
73,7 → 78,7
- Completely described in behavioral, platform-independent VHDL – no primitives, macros, etc. |
- Fully synchronous design, no latches, no gated clocks |
- Small hardware footprint and high operating frequency |
- Highly customizable processor configuration |
- Customizable processor configuration |
- Optional processor-internal data and instruction memories (DMEM/IMEM) |
- Optional internal bootloader with UART console and automatic SPI flash boot option |
- Optional machine system timer (MTIME), RISC-V-compliant |
135,8 → 140,8
* Machine external interrupt (via `CLIC` unit) |
|
**General**: |
* No hardware support of unaligned accesses (except for instructions in `C` extension that still have to be aligned on 16-bit boundaries) |
* Multi-cycle in-order instruction execution |
* No hardware support of unaligned accesses - they will trigger and exception |
* Two stages in-order pipeline (FETCH, EXECUTE); each stage uses a multi-cycle execution |
|
More information including a detailed list of the available CSRs can be found in |
the [![NEORV32 datasheet](https://raw.githubusercontent.com/stnolting/neorv32/master/docs/figures/PDF_32.png) NEORV32 datasheet](https://raw.githubusercontent.com/stnolting/neorv32/master/docs/NEORV32.pdf). |
144,11 → 149,11
|
### To-Do / Wish List |
|
- Testing, testing and even more testing |
- Port official [RISC-V compliance test](https://github.com/riscv/riscv-compliance) |
- No exception is triggered in `E`-mode when using reg >x15 yet |
- Port Dhrystone benchmark |
- Implement atomic extensions (`A` extension) |
- Implement co-processor for single-precision floating-point (`F` extension) |
- Implement atomic operations (`A` extension) |
- Implement `Zifence` extension |
- Implement co-processor for single-precision floating-point operations (`F` extension) |
- Implement user mode (`U` extension) |
- Make a 64-bit branch |
- Maybe port an RTOS (like [freeRTOS](https://www.freertos.org/) or [RIOT](https://www.riot-os.org/)) |
162,39 → 167,46
information is derived from the Timing Analyzer / Slow 1200mV 0C Model. If not otherwise specified, the default configuration |
of the processor's generics is assumed. No constraints were used. |
|
Results generated for hardware version: `0.0.2.3` |
Results generated for hardware version: `1.0.0.0` |
|
### CPU |
|
| CPU Configuration | LEs | FFs | Memory bits | DSPs | f_max | |
|:--------------------|:----------:|:--------:|:-----------:|:------:|:-------:| |
| `rv32i` | 852 (4%) | 326 (1%) | 2048 (>1%) | 0 (0%) | 111 MHz | |
| `rv32i` + `Zicsr` | 1488 (7%) | 694 (3%) | 2048 (>1%) | 0 (0%) | 107 MHz | |
| `rv32im` + `Zicsr` | 2057 (9%) | 941 (4%) | 2048 (>1%) | 0 (0%) | 102 MHz | |
| `rv32imc` + `Zicsr` | 2209 (10%) | 958 (4%) | 2048 (>1%) | 0 (0%) | 102 MHz | |
| `rv32e` | 848 (4%) | 326 (1%) | 1024 (>1%) | 0 (0%) | 111 MHz | |
| `rv32e` + `Zicsr` | 1316 (6%) | 594 (3%) | 1024 (>1%) | 0 (0%) | 106 MHz | |
| `rv32em` + `Zicsr` | 1879 (8%) | 841 (4%) | 1024 (>1%) | 0 (0%) | 101 MHz | |
| `rv32emc` + `Zicsr` | 2065 (9%) | 858 (4%) | 1024 (>1%) | 0 (0%) | 100 MHz | |
| `rv32i` | 1027 | 474 | 2048 | 0 (0%) | 111 MHz | |
| `rv32i` + `Zicsr` | 1721 | 868 | 2048 | 0 (0%) | 104 MHz | |
| `rv32im` + `Zicsr` | 2298 | 1115 | 2048 | 0 (0%) | 103 MHz | |
| `rv32imc` + `Zicsr` | 2557 | 1138 | 2048 | 0 (0%) | 103 MHz | |
| `rv32emc` + `Zicsr` | 2342 | 1005 | 1024 | 0 (0%) | 100 MHz | |
|
### Peripherals / Others |
### Processor-Internal Peripherals and Memories |
|
| Module | Description | LEs | FFs | Memory bits | DSPs | |
|:---------|:------------------------------------------------|:---:|:---:|:-----------:|:----:| |
| BOOT ROM | Bootloader ROM (4kB) | 3 | 1 | 32 768 | 0 | |
| DEVNULL | Dummy device | 2 | 1 | 0 | 0 | |
| DEVNULL | Dummy device | 3 | 1 | 0 | 0 | |
| DMEM | Processor-internal data memory (8kB) | 12 | 2 | 65 536 | 0 | |
| GPIO | General purpose input/output ports | 37 | 33 | 0 | 0 | |
| GPIO | General purpose input/output ports | 38 | 33 | 0 | 0 | |
| IMEM | Processor-internal instruction memory (16kb) | 7 | 2 | 131 072 | 0 | |
| MTIME | Machine system timer | 369 | 168 | 0 | 0 | |
| PWM | Pulse-width modulation controller | 77 | 69 | 0 | 0 | |
| SPI | Serial peripheral interface | 198 | 125 | 0 | 0 | |
| TRNG | True random number generator | 103 | 93 | 0 | 0 | |
| TWI | Two-wire interface | 76 | 44 | 0 | 0 | |
| UART | Universal asynchronous receiver/transmitter | 154 | 108 | 0 | 0 | |
| MTIME | Machine system timer | 270 | 167 | 0 | 0 | |
| PWM | Pulse-width modulation controller | 76 | 69 | 0 | 0 | |
| SPI | Serial peripheral interface | 206 | 125 | 0 | 0 | |
| TRNG | True random number generator | 104 | 93 | 0 | 0 | |
| TWI | Two-wire interface | 78 | 44 | 0 | 0 | |
| UART | Universal asynchronous receiver/transmitter | 151 | 108 | 0 | 0 | |
| WDT | Watchdog timer | 57 | 45 | 0 | 0 | |
|
### CPU + Peripheral |
|
The following table shows the implementation results for an _Intel Cyclone IV EP4CE22F17C6N_ FPGA. |
The design was synthesized using Intel Quartus Prime Lite 19.1 (“balanced implementation”). |
IMEM uses 16kB and DMEM uses 8kB memory space. |
|
| CPU Configuration | LEs | REGs | DSPs | Memory Bits | f_max | |
|:--------------------|:----------:|:---------:|:------:|:------------:|:-------:| |
| `rv32imc` + `Zicsr` | 3724 (17%) | 1899 (9%) | 0 (0%) | 231424 (38%) | 103 MHz | |
|
|
### Lattice iCE40 UltraPlus 5k |
|
The following table shows the hardware utilization for a [iCE40 UP5K](http://www.latticesemi.com/en/Products/FPGAandCPLD/iCE40UltraPlus) FPGA. |
205,13 → 217,11
Place & route reports generated with **Lattice Radiant 2.1** using Lattice LSE. The clock frequency |
is constrained and generated via the PLL from the internal HF oscillator running at 12 MHz. |
|
Results generated for hardware version: `0.0.2.5` |
| CPU Configuration | LUTs | REGs | DSPs | SPRAM | EBR | f | |
|:--------------------|:----------:|:----------:|:------:|:--------:|:--------:|:---------:| |
| `rv32imc` + `Zicsr` | 4985 (94%) | 1982 (38%) | 0 (0%) | 4 (100%) | 12 (40%) | 20.25 MHz | |
|
| CPU Configuration | Slices | LUT | REG | DSPs | SPRAM | EBR | f | |
|:--------------------|:----------:|:----------:|:----------:|:------:|:--------:|:--------:|:---------:| |
| `rv32imc` + `Zicsr` | 2405 (91%) | 4642 (87%) | 1810 (34%) | 0 (0%) | 4 (100%) | 12 (40%) | 20.25 MHz | |
|
|
## Performance |
|
### CoreMark Benchmark |
220,7 → 230,7
[sw/example/coremark](https://github.com/stnolting/neorv32/blob/master/sw/example/coremark) project folder. This benchmark |
tests the capabilities of a CPU itself rather than the functions provided by the whole system / SoC. |
|
Results generated for hardware version: `0.0.2.3` |
Results generated for hardware version: `1.0.0.0` |
|
~~~ |
**Configuration** |
232,12 → 242,12
|
| __Configuration__ | __Optimization__ | __Executable Size__ | __CoreMark Score__ | __CoreMarks/MHz__ | |
|:------------------|:----------------:|:-------------------:|:------------------:|:-----------------:| |
| `rv32i` | `-Os` | 17 944 bytes | 23.26 | 0.232 | |
| `rv32i` | `-O2` | 20 264 bytes | 25.64 | 0.256 | |
| `rv32im` | `-Os` | 16 880 bytes | 40.81 | 0.408 | |
| `rv32im` | `-O2` | 19 312 bytes | 47.62 | 0.476 | |
| `rv32imc` | `-Os` | 13 000 bytes | 32.78 | 0.327 | |
| `rv32imc` | `-O2` | 15 004 bytes | 37.04 | 0.370 | |
| `rv32i` | `-Os` | 18 044 bytes | 21.98 | 0.21 | |
| `rv32i` | `-O2` | 20 388 bytes | 25 | 0.25 | |
| `rv32im` | `-Os` | 16 980 bytes | 40 | 0.40 | |
| `rv32im` | `-O2` | 19 436 bytes | 51.28 | 0.51 | |
| `rv32imc` | `-Os` | 13 076 bytes | 39.22 | 0.39 | |
| `rv32imc` | `-O2` | 15 208 bytes | 50 | 0.50 | |
|
|
### Instruction Cycles |
250,7 → 260,7
Please note that the CPU-internal shifter (e.g. for the `SLL` instruction) as well as the multiplier and divider of the |
`M` extension use a bit-serial approach and require several cycles for completion. |
|
The following table shows the performance results for successfully (!) running 2000 CoreMark |
The following table shows the performance results for successfully running 2000 CoreMark |
iterations. The average CPI is computed by dividing the total number of required clock cycles (all of CoreMark |
– not only the timed core) by the number of executed instructions (`instret[h]` CSRs). The executables |
were generated using optimization `-O2`. |
257,27 → 267,12
|
| CPU / Toolchain Config. | Required Clock Cycles | Executed Instructions | Average CPI | |
|:------------------------|----------------------:|----------------------:|:-----------:| |
| `rv32i` | 10 385 023 697 | 1 949 310 506 | 5.3 | |
| `rv32im` | 6 276 943 488 | 995 011 883 | 6.3 | |
| `rv32imc` | 7 340 734 652 | 934 952 588 | 7.6 | |
| `rv32i` | 19 355 607 369 | 2 995 064 579 | 6.5 | |
| `rv32im` | 5 809 384 583 | 867 377 291 | 6.7 | |
| `rv32imc` | 5 560 220 723 | 825 898 407 | 6.7 | |
|
|
### Evaluation |
|
Based on the provided performance measurement and the hardware utilization for the |
different CPU configurations, the following configurations are suggested: |
|
|
| Design Goal | NEORV32 CPU Config. | |
|:-------------------------------|:--------------------| |
| Highest performance: | `rv32im` | |
| Lowest memory requirements: | `rv32imc` | |
| Lowest hardware requirements*: | `rv32ec` | |
|
*) Including on-chip memory hardware requirements. |
|
|
|
## Top Entity |
|
The top entity of the processor is [**neorv32_top.vhd**](https://github.com/stnolting/neorv32/blob/master/rtl/core/neorv32_top.vhd) (from the `rtl/core` folder). |
294,6 → 289,7
CLOCK_FREQUENCY : natural := 0; -- clock frequency of clk_i in Hz |
HART_ID : std_ulogic_vector(31 downto 0) := x"00000000"; -- custom hardware thread ID |
BOOTLOADER_USE : boolean := true; -- implement processor-internal bootloader? |
CSR_COUNTERS_USE : boolean := true; -- implement RISC-V perf. counters ([m]instret[h], [m]cycle[h], time[h])? |
-- RISC-V CPU Extensions -- |
CPU_EXTENSION_RISCV_C : boolean := false; -- implement compressed extension? |
CPU_EXTENSION_RISCV_E : boolean := false; -- implement embedded RF extension? |
347,9 → 343,9
uart_txd_o : out std_ulogic; -- UART send data |
uart_rxd_i : in std_ulogic := '0'; -- UART receive data |
-- SPI (available if IO_SPI_USE = true) -- |
spi_sclk_o : out std_ulogic; -- serial clock line |
spi_mosi_o : out std_ulogic; -- serial data line out |
spi_miso_i : in std_ulogic := '0'; -- serial data line in |
spi_sck_o : out std_ulogic; -- serial clock line |
spi_sdo_o : out std_ulogic; -- serial data line out |
spi_sdi_i : in std_ulogic := '0'; -- serial data line in |
spi_csn_o : out std_ulogic_vector(07 downto 0); -- SPI CS |
-- TWI (available if IO_TWI_USE = true) -- |
twi_sda_io : inout std_logic := 'H'; -- twi serial data line |
412,7 → 408,7
|
$ git clone https://github.com/stnolting/neorv32.git |
|
Create a new HW project with your FPGA synthesis tool of choice. Add all files from the [`rtl/core`](https://github.com/stnolting/neorv32/blob/master/rtl) |
Create a new HW project with your FPGA design tool of choice. Add all files from the [`rtl/core`](https://github.com/stnolting/neorv32/blob/master/rtl) |
folder to this project and add them to a **new library** called `neorv32`. |
|
You can either instantiate the [processor's top entity](https://github.com/stnolting/neorv32#top-entity) in you own project, or you |
464,30 → 460,6
|
Use the bootloader console to upload and execute your application image. |
|
``` |
<< NEORV32 Bootloader >> |
|
BLDV: Jun 22 2020 |
HWV: 0.0.2.3 |
CLK: 0x0134FD90 Hz |
MISA: 0x42801104 |
CONF: 0x01FF0015 |
IMEM: 0x00010000 bytes @ 0x00000000 |
DMEM: 0x00010000 bytes @ 0x80000000 |
|
Autoboot in 8s. Press key to abort. |
Aborted. |
|
Available commands: |
h: Help |
r: Restart |
u: Upload |
s: Store to flash |
l: Load from flash |
e: Execute |
CMD:> |
``` |
|
Going further: Take a look at the [![NEORV32 datasheet](https://raw.githubusercontent.com/stnolting/neorv32/master/docs/figures/PDF_32.png) NEORV32 datasheet](https://raw.githubusercontent.com/stnolting/neorv32/master/docs/NEORV32.pdf). |
|
|
512,6 → 484,7
## Legal |
|
This is a hobby project released under the BSD 3-Clause license. No copyright infringement intended. |
Other implied/used projects might have different licensing - see their documentation to get more information. |
|
**BSD 3-Clause License** |
|
561,4 → 534,4
This project is not affiliated with or endorsed by the Open Source Initiative (https://www.oshwa.org / https://opensource.org). |
|
|
Made with :heart: in Hannover, Germany. |
Made with :coffee: in Hannover, Germany. |