pax_global_header 0000666 0000000 0000000 00000000064 13460261316 0014514 g ustar 00root root 0000000 0000000 52 comment=53772dc3cd49421ea1fa6326a199b7a72dc04d18
wrtd-53772dc3cd49421ea1fa6326a199b7a72dc04d18/ 0000775 0000000 0000000 00000000000 13460261316 0017410 5 ustar 00root root 0000000 0000000 wrtd-53772dc3cd49421ea1fa6326a199b7a72dc04d18/.gitmodules 0000664 0000000 0000000 00000002344 13460261316 0021570 0 ustar 00root root 0000000 0000000 [submodule "dependencies/mock-turtle"]
path = dependencies/mock-turtle
url = https://ohwr.org/project/mock-turtle.git
[submodule "dependencies/fine-delay"]
path = dependencies/fmc-delay-1ns-8cha
url = https://ohwr.org/project/fmc-delay-1ns-8cha.git
[submodule "dependencies/fmc-tdc"]
path = dependencies/fmc-tdc-1ns-5cha-gw
url = https://ohwr.org/project/fmc-tdc-1ns-5cha-gw.git
[submodule "dependencies/vme64x-core"]
path = dependencies/vme64x-core
url = https://ohwr.org/project/vme64x-core.git
[submodule "dependencies/general-cores"]
path = dependencies/general-cores
url = https://ohwr.org/project/general-cores.git
[submodule "dependencies/wr-cores"]
path = dependencies/wr-cores
url = https://ohwr.org/project/wr-cores.git
[submodule "dependencies/urv-core"]
path = dependencies/urv-core
url = https://ohwr.org/project/urv-core.git
[submodule "dependencies/fmc-adc-100m14b4cha-gw"]
path = dependencies/fmc-adc-100m14b4cha-gw
url = https://ohwr.org/project/fmc-adc-100m14b4cha-gw.git
[submodule "dependencies/ddr3-sp6-core"]
path = dependencies/ddr3-sp6-core
url = https://ohwr.org/project/ddr3-sp6-core.git
[submodule "dependencies/gn4124-core"]
path = dependencies/gn4124-core
url = https://ohwr.org/project/gn4124-core.git
wrtd-53772dc3cd49421ea1fa6326a199b7a72dc04d18/CHANGELOG 0000664 0000000 0000000 00000000000 13460261316 0020610 0 ustar 00root root 0000000 0000000 wrtd-53772dc3cd49421ea1fa6326a199b7a72dc04d18/CONTRIBUTING.md 0000664 0000000 0000000 00000001303 13460261316 0021636 0 ustar 00root root 0000000 0000000 The project is based on the Mock Turtle infrastructure. On top of the
Mock Turtle we have the White Rabbit Trigger Distribution.
The project is made of:
- two real-time applications running on the Mock Turtle CPUs
- one library which provide the application's abstraction to communicate with
the real-time applications.
- a set of command line tools for the White Rabbit Trigger Distribution
configuration
RULES
=====
The master branch is protected so you need special permission to touch it.
Do you development on your own branch and push it.
In the project we are following the Linux kernel code style.
All the functions, defines, structures, enumeraters exported should use
the `wrtd_` prefix.
wrtd-53772dc3cd49421ea1fa6326a199b7a72dc04d18/LICENSE 0000664 0000000 0000000 00000077327 13460261316 0020435 0 ustar 00root root 0000000 0000000 GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc.
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The GNU General Public License is a free, copyleft license for
software and other kinds of works.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
the GNU General Public License is intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users. We, the Free Software Foundation, use the
GNU General Public License for most of our software; it applies also to
any other work released this way by its authors. You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
To protect your rights, we need to prevent others from denying you
these rights or asking you to surrender the rights. Therefore, you have
certain responsibilities if you distribute copies of the software, or if
you modify it: responsibilities to respect the freedom of others.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must pass on to the recipients the same
freedoms that you received. You must make sure that they, too, receive
or can get the source code. And you must show them these terms so they
know their rights.
Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
giving you legal permission to copy, distribute and/or modify it.
For the developers' and authors' protection, the GPL clearly explains
that there is no warranty for this free software. For both users' and
authors' sake, the GPL requires that modified versions be marked as
changed, so that their problems will not be attributed erroneously to
authors of previous versions.
Some devices are designed to deny users access to install or run
modified versions of the software inside them, although the manufacturer
can do so. This is fundamentally incompatible with the aim of
protecting users' freedom to change the software. The systematic
pattern of such abuse occurs in the area of products for individuals to
use, which is precisely where it is most unacceptable. Therefore, we
have designed this version of the GPL to prohibit the practice for those
products. If such problems arise substantially in other domains, we
stand ready to extend this provision to those domains in future versions
of the GPL, as needed to protect the freedom of users.
Finally, every program is threatened constantly by software patents.
States should not allow patents to restrict development and use of
software on general-purpose computers, but in those that do, we wish to
avoid the special danger that patents applied to a free program could
make it effectively proprietary. To prevent this, the GPL assures that
patents cannot be used to render the program non-free.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
13. Use with the GNU Affero General Public License.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU Affero General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the special requirements of the GNU Affero General Public License,
section 13, concerning interaction through a network will apply to the
combination as such.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the
Program specifies that a certain numbered version of the GNU General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU General Public License, you may choose any version ever published
by the Free Software Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS wrtd-53772dc3cd49421ea1fa6326a199b7a72dc04d18/README.md 0000664 0000000 0000000 00000000514 13460261316 0020667 0 ustar 00root root 0000000 0000000 # White Rabbit Trigger Distribution - WRTD
The aim of the project is to provide a system that is able to receive triggers
from some external source and distribute these triggers to remote nodes over
the White Rabbit network.
For more information, check out the project [Wiki](https://ohwr-gitlab.cern.ch/project/wrtd/wikis/Home).
wrtd-53772dc3cd49421ea1fa6326a199b7a72dc04d18/dependencies/ 0000775 0000000 0000000 00000000000 13460261316 0022036 5 ustar 00root root 0000000 0000000 wrtd-53772dc3cd49421ea1fa6326a199b7a72dc04d18/dependencies/ddr3-sp6-core/ 0000775 0000000 0000000 00000000000 13460261316 0024326 5 ustar 00root root 0000000 0000000 wrtd-53772dc3cd49421ea1fa6326a199b7a72dc04d18/dependencies/fmc-adc-100m14b4cha-gw/ 0000775 0000000 0000000 00000000000 13460261316 0025465 5 ustar 00root root 0000000 0000000 wrtd-53772dc3cd49421ea1fa6326a199b7a72dc04d18/dependencies/fmc-delay-1ns-8cha/ 0000775 0000000 0000000 00000000000 13460261316 0025217 5 ustar 00root root 0000000 0000000 wrtd-53772dc3cd49421ea1fa6326a199b7a72dc04d18/dependencies/fmc-tdc-1ns-5cha-gw/ 0000775 0000000 0000000 00000000000 13460261316 0025303 5 ustar 00root root 0000000 0000000 wrtd-53772dc3cd49421ea1fa6326a199b7a72dc04d18/dependencies/general-cores/ 0000775 0000000 0000000 00000000000 13460261316 0024564 5 ustar 00root root 0000000 0000000 wrtd-53772dc3cd49421ea1fa6326a199b7a72dc04d18/dependencies/gn4124-core/ 0000775 0000000 0000000 00000000000 13460261316 0023703 5 ustar 00root root 0000000 0000000 wrtd-53772dc3cd49421ea1fa6326a199b7a72dc04d18/dependencies/mock-turtle/ 0000775 0000000 0000000 00000000000 13460261316 0024304 5 ustar 00root root 0000000 0000000 wrtd-53772dc3cd49421ea1fa6326a199b7a72dc04d18/dependencies/urv-core/ 0000775 0000000 0000000 00000000000 13460261316 0023600 5 ustar 00root root 0000000 0000000 wrtd-53772dc3cd49421ea1fa6326a199b7a72dc04d18/dependencies/vme64x-core/ 0000775 0000000 0000000 00000000000 13460261316 0024115 5 ustar 00root root 0000000 0000000 wrtd-53772dc3cd49421ea1fa6326a199b7a72dc04d18/dependencies/wr-cores/ 0000775 0000000 0000000 00000000000 13460261316 0023577 5 ustar 00root root 0000000 0000000 wrtd-53772dc3cd49421ea1fa6326a199b7a72dc04d18/doc/ 0000775 0000000 0000000 00000000000 13460261316 0020155 5 ustar 00root root 0000000 0000000 wrtd-53772dc3cd49421ea1fa6326a199b7a72dc04d18/doc/.gitignore 0000664 0000000 0000000 00000000047 13460261316 0022146 0 ustar 00root root 0000000 0000000 doxygen-output/
*.log
_build
build_env
wrtd-53772dc3cd49421ea1fa6326a199b7a72dc04d18/doc/Makefile 0000664 0000000 0000000 00000002306 13460261316 0021616 0 ustar 00root root 0000000 0000000 # Minimal makefile for Sphinx documentation
#
# You can set these variables from the command line.
SPHINXOPTS =
SPHINXBUILD = sphinx-build
SPHINXPROJ = wrtd
SOURCEDIR = .
BUILDDIR = _build
# Put it first so that "make" without argument is like "make help".
help:
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
.PHONY: help Makefile doxygen doxygen-clean
# Catch-all target: route all unknown targets to Sphinx using the new
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
%: Makefile
$(MAKE) doxygen TARGET=$@
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
GIT_VERSION = $(shell cd $(src); git describe --dirty --long --tags)
DOXY_OUT ?= doxygen-output
# Build the documentation with or without the internals details
ifdef SHOW_INTERNALS
EXCLUDE_FILES = ""
BRIEF = "API Documentation - With Internals"
else
EXCLUDE_FILES = "../lib/libwrtd-internal.h"
BRIEF = "API Documentation"
endif
doxygen:
ifeq ($(TARGET),clean)
@echo "Remove Doxygen files"
@rm -rf $(DOXY_OUT) $(BUILDDIR)
else
GIT_VERSION=$(GIT_VERSION) EXCLUDE_FILES=$(EXCLUDE_FILES) BRIEF=$(BRIEF) \
OUTPUT=$(DOXY_OUT) doxygen ./doxygen-wrtd-config
endif
wrtd-53772dc3cd49421ea1fa6326a199b7a72dc04d18/doc/conf.py 0000664 0000000 0000000 00000024366 13460261316 0021467 0 ustar 00root root 0000000 0000000 # -*- coding: utf-8 -*-
#
# White Rabbit Trigger Distribution documentation build configuration file, created by
# sphinx-quickstart on Fri Jan 25 09:42:58 2019.
#
# This file is execfile()d with the current directory set to its
# containing dir.
#
# Note that not all possible configuration values are present in this
# autogenerated file.
#
# All configuration values have a default; values that are commented out
# serve to show the default.
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
#
# import os
# import sys
# sys.path.insert(0, os.path.abspath('.'))
# -- General configuration ------------------------------------------------
# If your documentation needs a minimal Sphinx version, state it here.
#
# needs_sphinx = '1.0'
# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = [
'sphinx.ext.autodoc',
'sphinx.ext.todo',
'sphinx.ext.mathjax',
'sphinx.ext.viewcode',
'sphinx.ext.graphviz',
'sphinx.ext.coverage',
'breathe',
'recommonmark',
]
# Add any paths that contain templates here, relative to this directory.
# templates_path = ['_templates']
source_suffix = {
'.rst': 'restructuredtext',
'.md': 'markdown',
}
# The encoding of source files.
#
# source_encoding = 'utf-8-sig'
# The master toctree document.
master_doc = 'index'
# General information about the project.
project = u'White Rabbit Trigger Distribution'
copyright = u'2019, CERN'
author = u'Dimitris Lampridis v documentation" by default.
#
# html_title = u'White Rabbit Trigger Distribution v1.0'
# A shorter title for the navigation bar. Default is the same as html_title.
#
# html_short_title = None
# The name of an image file (relative to this directory) to place at the top
# of the sidebar.
#
# html_logo = None
# The name of an image file (relative to this directory) to use as a favicon of
# the docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
# pixels large.
#
# html_favicon = None
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
# html_static_path = ['_static']
# Add any extra paths that contain custom files (such as robots.txt or
# .htaccess) here, relative to this directory. These files are copied
# directly to the root of the documentation.
#
# html_extra_path = []
# If not None, a 'Last updated on:' timestamp is inserted at every page
# bottom, using the given strftime format.
# The empty string is equivalent to '%b %d, %Y'.
#
# html_last_updated_fmt = None
# If true, SmartyPants will be used to convert quotes and dashes to
# typographically correct entities.
#
# html_use_smartypants = True
# Custom sidebar templates, maps document names to template names.
#
# html_sidebars = {}
# Additional templates that should be rendered to pages, maps page names to
# template names.
#
# html_additional_pages = {}
# If false, no module index is generated.
#
# html_domain_indices = True
# If false, no index is generated.
#
# html_use_index = True
# If true, the index is split into individual pages for each letter.
#
# html_split_index = False
# If true, links to the reST sources are added to the pages.
#
html_show_sourcelink = False
# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
#
html_show_sphinx = False
# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
#
# html_show_copyright = True
# If true, an OpenSearch description file will be output, and all pages will
# contain a tag referring to it. The value of this option must be the
# base URL from which the finished HTML is served.
#
# html_use_opensearch = ''
# This is the file name suffix for HTML files (e.g. ".xhtml").
# html_file_suffix = None
# Language to be used for generating the HTML full-text search index.
# Sphinx supports the following languages:
# 'da', 'de', 'en', 'es', 'fi', 'fr', 'hu', 'it', 'ja'
# 'nl', 'no', 'pt', 'ro', 'ru', 'sv', 'tr', 'zh'
#
# html_search_language = 'en'
# A dictionary with options for the search language support, empty by default.
# 'ja' uses this config value.
# 'zh' user can custom change `jieba` dictionary path.
#
# html_search_options = {'type': 'default'}
# The name of a javascript file (relative to the configuration directory) that
# implements a search results scorer. If empty, the default will be used.
#
# html_search_scorer = 'scorer.js'
# Output file base name for HTML help builder.
htmlhelp_basename = 'WhiteRabbitTriggerDistributiondoc'
# -- Options for LaTeX output ---------------------------------------------
latex_elements = {
# The paper size ('letterpaper' or 'a4paper').
#
'papersize': 'a4paper',
# The font size ('10pt', '11pt' or '12pt').
#
# 'pointsize': '10pt',
# Additional stuff for the LaTeX preamble.
#
# 'preamble': '',
# Latex figure (float) alignment
#
# 'figure_align': 'htbp',
}
# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title,
# author, documentclass [howto, manual, or own class]).
latex_documents = [
(master_doc, 'WhiteRabbitTriggerDistribution.tex', u'White Rabbit Trigger Distribution Documentation',
u'Dimitris Lampridis', 'manual'),
]
# The name of an image file (relative to this directory) to place at the top of
# the title page.
#
# latex_logo = None
# For "manual" documents, if this is true, then toplevel headings are parts,
# not chapters.
#
# latex_use_parts = False
# If true, show page references after internal links.
#
# latex_show_pagerefs = False
# If true, show URL addresses after external links.
#
# latex_show_urls = False
# Documents to append as an appendix to all manuals.
#
# latex_appendices = []
# It false, will not define \strong, \code, itleref, \crossref ... but only
# \sphinxstrong, ..., \sphinxtitleref, ... To help avoid clash with user added
# packages.
#
# latex_keep_old_macro_names = True
# If false, no module index is generated.
#
# latex_domain_indices = True
# -- Options for manual page output ---------------------------------------
# One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section).
man_pages = [
(master_doc, 'whiterabbittriggerdistribution', u'White Rabbit Trigger Distribution Documentation',
[author], 1)
]
# If true, show URL addresses after external links.
#
# man_show_urls = False
# -- Options for Texinfo output -------------------------------------------
# Grouping the document tree into Texinfo files. List of tuples
# (source start file, target name, title, author,
# dir menu entry, description, category)
texinfo_documents = [
(master_doc, 'WhiteRabbitTriggerDistribution', u'White Rabbit Trigger Distribution Documentation',
author, 'WhiteRabbitTriggerDistribution', 'One line description of project.',
'Miscellaneous'),
]
# Documents to append as an appendix to all manuals.
#
# texinfo_appendices = []
# If false, no module index is generated.
#
# texinfo_domain_indices = True
# How to display URL addresses: 'footnote', 'no', or 'inline'.
#
# texinfo_show_urls = 'footnote'
# If true, do not generate a @detailmenu in the "Top" node's menu.
#
# texinfo_no_detailmenu = False
from recommonmark.transform import AutoStructify
def setup(app):
app.add_config_value('recommonmark_config', {
'enable_math': True,
'enable_inline_math': True,
'enable_eval_rst': True
}, True)
app.add_transform(AutoStructify)
wrtd-53772dc3cd49421ea1fa6326a199b7a72dc04d18/doc/dictionary.md 0000664 0000000 0000000 00000000300 13460261316 0022635 0 ustar 00root root 0000000 0000000 Dictionary
==========
The main purpose of this dictionary is to explain the
White-Rabbit Trigger-Distribution terminology.
channel
dead time
delay
input
output
pulse
trigger
trigger condition wrtd-53772dc3cd49421ea1fa6326a199b7a72dc04d18/doc/doxygen-wrtd-config 0000664 0000000 0000000 00000001055 13460261316 0023777 0 ustar 00root root 0000000 0000000 PROJECT_NAME = "White Rabbit Trigger Distribution"
PROJECT_NUMBER = $(GIT_VERSION)
PROJECT_BRIEF = $(BRIEF)
PROJECT_LOGO =
OUTPUT_DIRECTORY = $(OUTPUT)
CREATE_SUBDIRS = YES
TAB_SIZE = 8
OPTIMIZE_OUTPUT_FOR_C = YES
EXTRACT_STATIC = YES
CASE_SENSE_NAMES = YES
WARN_NO_PARAMDOC = YES
INPUT = ../lib ../include/wrtd-common.h
RECURSIVE = YES
EXCLUDE = $(EXCLUDE_FILES)
GENERATE_HTML = YES
GENERATE_LATEX = YES
wrtd-53772dc3cd49421ea1fa6326a199b7a72dc04d18/doc/index.rst 0000664 0000000 0000000 00000000765 13460261316 0022026 0 ustar 00root root 0000000 0000000 .. White Rabbit Trigger Distribution documentation master file, created by
sphinx-quickstart on Fri Jan 25 09:42:58 2019.
You can adapt this file completely to your liking, but it should at least
contain the root `toctree` directive.
White Rabbit Trigger Distribution documentation
===============================================
.. toctree::
:maxdepth: 2
:caption: Contents
introduction
Indices and tables
------------------
* :ref:`genindex`
* :ref:`modindex`
* :ref:`search`
wrtd-53772dc3cd49421ea1fa6326a199b7a72dc04d18/doc/introduction.md 0000664 0000000 0000000 00000000164 13460261316 0023221 0 ustar 00root root 0000000 0000000 Introduction
============
`Hello` *there* [link](https://ohwr.org)
- item 1
- item 2
[dictionary](dictionary.md)
wrtd-53772dc3cd49421ea1fa6326a199b7a72dc04d18/doc/requirements.txt 0000664 0000000 0000000 00000000122 13460261316 0023434 0 ustar 00root root 0000000 0000000 docutils==0.14
Sphinx==1.8.3
sphinx_rtd_theme
breathe==4.10.0
recommonmark==0.5.0
wrtd-53772dc3cd49421ea1fa6326a199b7a72dc04d18/hdl/ 0000775 0000000 0000000 00000000000 13460261316 0020157 5 ustar 00root root 0000000 0000000 wrtd-53772dc3cd49421ea1fa6326a199b7a72dc04d18/hdl/syn/ 0000775 0000000 0000000 00000000000 13460261316 0020770 5 ustar 00root root 0000000 0000000 wrtd-53772dc3cd49421ea1fa6326a199b7a72dc04d18/hdl/syn/wrtd_ref_spec150t_adc/ 0000775 0000000 0000000 00000000000 13460261316 0025037 5 ustar 00root root 0000000 0000000 wrtd-53772dc3cd49421ea1fa6326a199b7a72dc04d18/hdl/syn/wrtd_ref_spec150t_adc/.gitignore 0000664 0000000 0000000 00000000067 13460261316 0027032 0 ustar 00root root 0000000 0000000 *
!.gitignore
!Manifest.py
!*.ucf
!syn_extra_steps.tcl
wrtd-53772dc3cd49421ea1fa6326a199b7a72dc04d18/hdl/syn/wrtd_ref_spec150t_adc/Manifest.py 0000664 0000000 0000000 00000001421 13460261316 0027155 0 ustar 00root root 0000000 0000000 # HDLMake 'develop' branch required.
#
# Due to bugs in release v3.0 of hdlmake it is necessary to use the "develop"
# branch of hdlmake, commit db4e1ab.
board = "spec"
target = "xilinx"
action = "synthesis"
syn_device = "xc6slx150t"
syn_grade = "-3"
syn_package = "fgg484"
syn_top = "wrtd_ref_spec150t_adc"
syn_project = "wrtd_ref_spec150t_adc.xise"
syn_tool = "ise"
fetchto = "../../../dependencies"
ctrls = ["bank3_64b_32b"]
syn_post_project_cmd = (
"$(TCL_INTERPRETER) " + \
fetchto + "/general-cores/tools/sdb_desc_gen.tcl " + \
syn_tool + " $(PROJECT_FILE);" \
"$(TCL_INTERPRETER) syn_extra_steps.tcl $(PROJECT_FILE)"
)
files = [
"wrtd_ref_spec150t_adc.ucf",
]
modules = {
"local" : [
"../../top/wrtd_ref_spec150t_adc",
],
}
wrtd-53772dc3cd49421ea1fa6326a199b7a72dc04d18/hdl/syn/wrtd_ref_spec150t_adc/syn_extra_steps.tcl 0000664 0000000 0000000 00000002013 13460261316 0030771 0 ustar 00root root 0000000 0000000 # get project file from 1st command-line argument
set project_file [lindex $argv 0]
if {![file exists $project_file]} {
report ERROR "Missing file $project_file, exiting."
exit -1
}
xilinx::project open $project_file
# Some of these are not respected by ISE when passed through hdlmake,
# so we add them all ourselves after creating the project
#
# Not respected by ISE when passed through hdlmake:
# 1. Pack I/O Registers/Latches into IOBs
# 2. Register Duplication Map
xilinx::project set "Enable Multi-Threading" "2" -process "Map"
xilinx::project set "Enable Multi-Threading" "4" -process "Place & Route"
xilinx::project set "Pack I/O Registers into IOBs" "Yes"
xilinx::project set "Pack I/O Registers/Latches into IOBs" "For Inputs and Outputs"
xilinx::project set "Register Balancing" "Yes"
xilinx::project set "Register Duplication Map" "On"
#xilinx::project set "Placer Extra Effort Map" "Normal"
#xilinx::project set "Extra Effort (Highest PAR level only)" "Normal"
xilinx::project save
xilinx::project close
wrtd_ref_spec150t_adc.ucf 0000664 0000000 0000000 00000047047 13460261316 0031542 0 ustar 00root root 0000000 0000000 wrtd-53772dc3cd49421ea1fa6326a199b7a72dc04d18/hdl/syn/wrtd_ref_spec150t_adc #===============================================================================
# IO Location Constraints
#===============================================================================
#----------------------------------------
# GN4124 interface
#----------------------------------------
NET "gn_rst_n_i" LOC = N20;
NET "gn_p2l_clk_n_i" LOC = M19;
NET "gn_p2l_clk_p_i" LOC = M20;
NET "gn_p2l_rdy_o" LOC = J16;
NET "gn_p2l_dframe_i" LOC = J22;
NET "gn_p2l_valid_i" LOC = L19;
NET "gn_p2l_data_i[15]" LOC = H19;
NET "gn_p2l_data_i[14]" LOC = F21;
NET "gn_p2l_data_i[13]" LOC = F22;
NET "gn_p2l_data_i[12]" LOC = E20;
NET "gn_p2l_data_i[11]" LOC = E22;
NET "gn_p2l_data_i[10]" LOC = J19;
NET "gn_p2l_data_i[9]" LOC = H20;
NET "gn_p2l_data_i[8]" LOC = K19;
NET "gn_p2l_data_i[7]" LOC = K18;
NET "gn_p2l_data_i[6]" LOC = G20;
NET "gn_p2l_data_i[5]" LOC = G22;
NET "gn_p2l_data_i[4]" LOC = K17;
NET "gn_p2l_data_i[3]" LOC = L17;
NET "gn_p2l_data_i[2]" LOC = H21;
NET "gn_p2l_data_i[1]" LOC = H22;
NET "gn_p2l_data_i[0]" LOC = K20;
NET "gn_p_wr_req_i[1]" LOC = M21;
NET "gn_p_wr_req_i[0]" LOC = M22;
NET "gn_p_wr_rdy_o[1]" LOC = K16;
NET "gn_p_wr_rdy_o[0]" LOC = L15;
NET "gn_rx_error_o" LOC = J17;
NET "gn_l2p_clk_n_o" LOC = K22;
NET "gn_l2p_clk_p_o" LOC = K21;
NET "gn_l2p_dframe_o" LOC = U22;
NET "gn_l2p_valid_o" LOC = T18;
NET "gn_l2p_edb_o" LOC = U20;
NET "gn_l2p_data_o[15]" LOC = Y21;
NET "gn_l2p_data_o[14]" LOC = W20;
NET "gn_l2p_data_o[13]" LOC = V20;
NET "gn_l2p_data_o[12]" LOC = V22;
NET "gn_l2p_data_o[11]" LOC = T19;
NET "gn_l2p_data_o[10]" LOC = T21;
NET "gn_l2p_data_o[9]" LOC = R22;
NET "gn_l2p_data_o[8]" LOC = P22;
NET "gn_l2p_data_o[7]" LOC = Y22;
NET "gn_l2p_data_o[6]" LOC = W22;
NET "gn_l2p_data_o[5]" LOC = V19;
NET "gn_l2p_data_o[4]" LOC = V21;
NET "gn_l2p_data_o[3]" LOC = T20;
NET "gn_l2p_data_o[2]" LOC = P18;
NET "gn_l2p_data_o[1]" LOC = P21;
NET "gn_l2p_data_o[0]" LOC = P16;
NET "gn_l2p_rdy_i" LOC = U19;
NET "gn_l_wr_rdy_i[1]" LOC = T22;
NET "gn_l_wr_rdy_i[0]" LOC = R20;
NET "gn_p_rd_d_rdy_i[1]" LOC = P19;
NET "gn_p_rd_d_rdy_i[0]" LOC = N16;
NET "gn_tx_error_i" LOC = M17;
NET "gn_vc_rdy_i[1]" LOC = B22;
NET "gn_vc_rdy_i[0]" LOC = B21;
NET "gn_gpio_b[1]" LOC = U16;
NET "gn_gpio_b[0]" LOC = AB19;
NET "gn_rst_n_i" IOSTANDARD = "LVCMOS18";
NET "gn_p2l_clk_?_i" IOSTANDARD = "DIFF_SSTL18_I";
NET "gn_p2l_rdy_o" IOSTANDARD = "SSTL18_I";
NET "gn_p2l_dframe_i" IOSTANDARD = "SSTL18_I";
NET "gn_p2l_valid_i" IOSTANDARD = "SSTL18_I";
NET "gn_p2l_data_i[*]" IOSTANDARD = "SSTL18_I";
NET "gn_p_wr_req_i[*]" IOSTANDARD = "SSTL18_I";
NET "gn_p_wr_rdy_o[*]" IOSTANDARD = "SSTL18_I";
NET "gn_rx_error_o" IOSTANDARD = "SSTL18_I";
NET "gn_l2p_clk_?_o" IOSTANDARD = "DIFF_SSTL18_I";
NET "gn_l2p_dframe_o" IOSTANDARD = "SSTL18_I";
NET "gn_l2p_valid_o" IOSTANDARD = "SSTL18_I";
NET "gn_l2p_edb_o" IOSTANDARD = "SSTL18_I";
NET "gn_l2p_data_o[*]" IOSTANDARD = "SSTL18_I";
NET "gn_l2p_rdy_i" IOSTANDARD = "SSTL18_I";
NET "gn_l_wr_rdy_i[*]" IOSTANDARD = "SSTL18_I";
NET "gn_p_rd_d_rdy_i[*]" IOSTANDARD = "SSTL18_I";
NET "gn_tx_error_i" IOSTANDARD = "SSTL18_I";
NET "gn_vc_rdy_i[*]" IOSTANDARD = "SSTL18_I";
NET "gn_gpio_b[*]" IOSTANDARD = "LVCMOS25";
#----------------------------------------
# Clock and reset inputs
#----------------------------------------
NET "clk_20m_vcxo_i" LOC = H12;
NET "clk_125m_pllref_n_i" LOC = F10;
NET "clk_125m_pllref_p_i" LOC = G9;
NET "clk_125m_gtp_n_i" LOC = D11;
NET "clk_125m_gtp_p_i" LOC = C11;
NET "clk_20m_vcxo_i" IOSTANDARD = "LVCMOS25";
NET "clk_125m_pllref_n_i" IOSTANDARD = "LVDS_25";
NET "clk_125m_pllref_p_i" IOSTANDARD = "LVDS_25";
NET "clk_125m_gtp_n_i" IOSTANDARD = "LVDS_25";
NET "clk_125m_gtp_p_i" IOSTANDARD = "LVDS_25";
#----------------------------------------
# SFP slot
#----------------------------------------
NET "sfp_rxn_i" LOC = C15;
NET "sfp_rxp_i" LOC = D15;
NET "sfp_txn_o" LOC = A16;
NET "sfp_txp_o" LOC = B16;
NET "sfp_los_i" LOC = D18;
NET "sfp_mod_def0_i" LOC = G15;
NET "sfp_mod_def1_b" LOC = C17;
NET "sfp_mod_def2_b" LOC = G16;
NET "sfp_rate_select_o" LOC = H14;
NET "sfp_tx_disable_o" LOC = F17;
NET "sfp_tx_fault_i" LOC = B18;
NET "sfp_los_i" IOSTANDARD = "LVCMOS25";
NET "sfp_mod_def0_i" IOSTANDARD = "LVCMOS25";
NET "sfp_mod_def1_b" IOSTANDARD = "LVCMOS25";
NET "sfp_mod_def2_b" IOSTANDARD = "LVCMOS25";
NET "sfp_rate_select_o" IOSTANDARD = "LVCMOS25";
NET "sfp_tx_disable_o" IOSTANDARD = "LVCMOS25";
NET "sfp_tx_fault_i" IOSTANDARD = "LVCMOS25";
#----------------------------------------
# DAC interfaces (for VCXO)
#----------------------------------------
NET "pll25dac_sync_n_o" LOC = A3;
NET "pll20dac_sync_n_o" LOC = B3;
NET "plldac_din_o" LOC = C4;
NET "plldac_sclk_o" LOC = A4;
NET "pll25dac_sync_n_o" IOSTANDARD = "LVCMOS25";
NET "pll20dac_sync_n_o" IOSTANDARD = "LVCMOS25";
NET "plldac_din_o" IOSTANDARD = "LVCMOS25";
NET "plldac_sclk_o" IOSTANDARD = "LVCMOS25";
#----------------------------------------
# SPI FLASH
#----------------------------------------
NET "spi_ncs_o" LOC = AA3;
NET "spi_sclk_o" LOC = Y20;
NET "spi_mosi_o" LOC = AB20;
NET "spi_miso_i" LOC = AA20;
NET "spi_ncs_o" IOSTANDARD = "LVCMOS25";
NET "spi_sclk_o" IOSTANDARD = "LVCMOS25";
NET "spi_mosi_o" IOSTANDARD = "LVCMOS25";
NET "spi_miso_i" IOSTANDARD = "LVCMOS25";
#----------------------------------------
# UART
#----------------------------------------
NET "uart_txd_o" LOC = B2;
NET "uart_rxd_i" LOC = A2;
NET "uart_txd_o" IOSTANDARD = "LVCMOS25";
NET "uart_rxd_i" IOSTANDARD = "LVCMOS25";
#----------------------------------------
# 1-wire thermometer + unique ID
#----------------------------------------
NET "carrier_onewire_b" LOC = D4;
NET "carrier_onewire_b" IOSTANDARD = "LVCMOS25";
#----------------------------------------
# Carrier front panel LEDs
#----------------------------------------
NET "led_sfp_red_o" LOC = D5;
NET "led_sfp_green_o" LOC = E5;
NET "led_sfp_red_o" IOSTANDARD = "LVCMOS25";
NET "led_sfp_green_o" IOSTANDARD = "LVCMOS25";
#----------------------------------------
# PCB revision
#----------------------------------------
NET "pcbrev_i[0]" LOC = P5;
NET "pcbrev_i[1]" LOC = P4;
NET "pcbrev_i[2]" LOC = AA2;
NET "pcbrev_i[3]" LOC = AA1;
NET "pcbrev_i[*]" IOSTANDARD = "LVCMOS15";
#----------------------------------------
# PCB Buttons and LEDs
#----------------------------------------
NET "button1_n_i" LOC = C22;
NET "aux_leds_o[0]" LOC = G19;
NET "aux_leds_o[1]" LOC = F20;
NET "aux_leds_o[2]" LOC = F18;
NET "aux_leds_o[3]" LOC = C20;
NET "button1_n_i" IOSTANDARD = "LVCMOS18";
NET "aux_leds_o[*]" IOSTANDARD = "LVCMOS18";
#----------------------------------------
# FMC slot management
#----------------------------------------
NET "fmc0_prsnt_m2c_n_i" LOC = AB14;
NET "fmc0_scl_b" LOC = F7;
NET "fmc0_sda_b" LOC = F8;
NET "fmc0_prsnt_m2c_n_i" IOSTANDARD = "LVCMOS25";
NET "fmc0_scl_b" IOSTANDARD = "LVCMOS25";
NET "fmc0_sda_b" IOSTANDARD = "LVCMOS25";
#----------------------------------------
# IOBs
#----------------------------------------
INST "cmp_gn4124_core/cmp_wrapped_gn4124/l2p_rdy_t" IOB = FALSE;
INST "cmp_gn4124_core/cmp_wrapped_gn4124/l_wr_rdy_t*" IOB = FALSE;
NET "fmc?_adc_gpio*" IOB = FALSE;
#===============================================================================
# Timing constraints and exceptions
#===============================================================================
# All input clocks
NET "clk_125m_pllref_n_i" TNM_NET = clk_125m_pllref_n_i;
TIMESPEC TS_clk_125m_pllref_n_i = PERIOD "clk_125m_pllref_n_i" 8 ns HIGH 50%;
NET "clk_125m_gtp_n_i" TNM_NET = clk_125m_gtp_n_i;
TIMESPEC TS_clk_125m_gtp_n_i = PERIOD "clk_125m_gtp_n_i" 8 ns HIGH 50%;
NET "clk_20m_vcxo_i" TNM_NET = "clk_20m_vcxo_i";
TIMESPEC TS_clk_20m_vcxo_i = PERIOD "clk_20m_vcxo_i" 50 ns HIGH 50%;
NET "cmp_xwrc_board_spec/*/gen_phy_spartan6.cmp_gtp/ch1_gtp_clkout_int<1>" TNM_NET = wrc_gtp_clk;
TIMESPEC TS_wrc_gtp_clk = PERIOD "wrc_gtp_clk" 8 ns HIGH 50%;
NET "gn_p2l_clk_n_i" TNM_NET = "p2l_clk";
TIMESPEC TS_p2l_clk = PERIOD "p2l_clk" 5 ns HIGH 50%;
#----------------------------------------
# WR DMTD tweaks
#----------------------------------------
INST "*/U_SOFTPLL/U_Wrapped_Softpll/gen_feedback_dmtds*/clk_in" TNM = skew_limit;
INST "*/U_SOFTPLL/U_Wrapped_Softpll/gen_ref_dmtds*/clk_in" TNM = skew_limit;
TIMESPEC TS_dmtd_skew = FROM "skew_limit" TO "FFS" 1 ns DATAPATHONLY;
#----------------------------------------
# Asynchronous resets
#----------------------------------------
# GN4124
NET "gn_rst_n_i" TIG;
NET "cmp_gn4124_core/cmp_wrapped_gn4124/rst_*" TIG;
# Ignore async reset inputs to reset synchronisers
NET "*/gc_reset_async_in" TIG;
#----------------------------------------
# Cross-clock domain sync
#----------------------------------------
# Declaration of domains
NET "clk_sys_62m5" TNM_NET = sys_clk_62_5;
NET "clk_ref_125m" TNM_NET = clk_125m_pllref;
NET "clk_ddr_333m" TNM_NET = ddr_clk_333m;
NET "cmp_xwrc_board_spec/clk_pll_dmtd" TNM_NET = clk_dmtd;
NET "cmp_xwrc_board_spec/phy8_to_wrc_rx_clk" TNM_NET = phy_clk;
NET "cmp_gn4124_core/cmp_wrapped_gn4124/sys_clk" TNM_NET = pci_sys_clk;
NET "cmp_gn4124_core/cmp_wrapped_gn4124/io_clk" TNM_NET = pci_io_clk;
TIMEGRP "sys_clk" = "sys_clk_62_5" "clk_125m_pllref";
TIMEGRP "pci_clk" = "pci_sys_clk" "pci_io_clk";
# Exceptions for crossings via gc_sync_ffs
NET "*/gc_sync_ffs_in" TNM_NET = "sync_ffs";
TIMEGRP "pci_sync_ffs" = "sync_ffs" EXCEPT "pci_clk";
TIMEGRP "sys_sync_ffs" = "sync_ffs" EXCEPT "sys_clk";
TIMEGRP "dmtd_sync_ffs" = "sync_ffs" EXCEPT "clk_dmtd";
TIMEGRP "phy_sync_ffs" = "sync_ffs" EXCEPT "phy_clk";
TIMESPEC TS_pci_sync_ffs = FROM pci_clk TO "pci_sync_ffs" TIG;
TIMESPEC TS_sys_sync_ffs = FROM sys_clk TO "sys_sync_ffs" TIG;
TIMESPEC TS_dmtd_sync_ffs = FROM clk_dmtd TO "dmtd_sync_ffs" TIG;
TIMESPEC TS_phy_sync_ffs = FROM phy_clk TO "phy_sync_ffs" TIG;
# Exceptions for crossings via gc_sync_register
NET "*/gc_sync_register_in[*]" TNM_NET = "sync_reg";
TIMEGRP "pci_sync_reg" = "sync_reg" EXCEPT "pci_clk";
TIMEGRP "sys_sync_reg" = "sync_reg" EXCEPT "sys_clk";
TIMEGRP "dmtd_sync_reg" = "sync_reg" EXCEPT "clk_dmtd";
TIMEGRP "phy_sync_reg" = "sync_reg" EXCEPT "phy_clk";
TIMESPEC TS_pci_sync_reg = FROM pci_clk TO "pci_sync_reg" 5ns DATAPATHONLY;
TIMESPEC TS_sys_62m5_sync_reg = FROM sys_clk_62_5 TO "sys_sync_reg" 16ns DATAPATHONLY;
TIMESPEC TS_sys_125m_sync_reg = FROM clk_125m_pllref TO "sys_sync_reg" 8ns DATAPATHONLY;
TIMESPEC TS_dmtd_sync_reg = FROM clk_dmtd TO "dmtd_sync_reg" 16ns DATAPATHONLY;
TIMESPEC TS_phy_sync_reg = FROM phy_clk TO "phy_sync_reg" 8ns DATAPATHONLY;
# DDR (bank 3)
NET "ddr0_rzq_b" LOC = K7;
NET "ddr0_we_n_o" LOC = H2;
NET "ddr0_udqs_p_b" LOC = V2;
NET "ddr0_udqs_n_b" LOC = V1;
NET "ddr0_udm_o" LOC = P3;
NET "ddr0_reset_n_o" LOC = E3;
NET "ddr0_ras_n_o" LOC = M5;
NET "ddr0_odt_o" LOC = L6;
NET "ddr0_ldqs_p_b" LOC = N3;
NET "ddr0_ldqs_n_b" LOC = N1;
NET "ddr0_ldm_o" LOC = N4;
NET "ddr0_cke_o" LOC = F2;
NET "ddr0_ck_p_o" LOC = K4;
NET "ddr0_ck_n_o" LOC = K3;
NET "ddr0_cas_n_o" LOC = M4;
NET "ddr0_dq_b[15]" LOC = Y1;
NET "ddr0_dq_b[14]" LOC = Y2;
NET "ddr0_dq_b[13]" LOC = W1;
NET "ddr0_dq_b[12]" LOC = W3;
NET "ddr0_dq_b[11]" LOC = U1;
NET "ddr0_dq_b[10]" LOC = U3;
NET "ddr0_dq_b[9]" LOC = T1;
NET "ddr0_dq_b[8]" LOC = T2;
NET "ddr0_dq_b[7]" LOC = M1;
NET "ddr0_dq_b[6]" LOC = M2;
NET "ddr0_dq_b[5]" LOC = L1;
NET "ddr0_dq_b[4]" LOC = L3;
NET "ddr0_dq_b[3]" LOC = P1;
NET "ddr0_dq_b[2]" LOC = P2;
NET "ddr0_dq_b[1]" LOC = R1;
NET "ddr0_dq_b[0]" LOC = R3;
NET "ddr0_ba_o[2]" LOC = H1;
NET "ddr0_ba_o[1]" LOC = J1;
NET "ddr0_ba_o[0]" LOC = J3;
NET "ddr0_a_o[13]" LOC = J6;
NET "ddr0_a_o[12]" LOC = F1;
NET "ddr0_a_o[11]" LOC = E1;
NET "ddr0_a_o[10]" LOC = J4;
NET "ddr0_a_o[9]" LOC = G1;
NET "ddr0_a_o[8]" LOC = G3;
NET "ddr0_a_o[7]" LOC = K6;
NET "ddr0_a_o[6]" LOC = L4;
NET "ddr0_a_o[5]" LOC = M3;
NET "ddr0_a_o[4]" LOC = H3;
NET "ddr0_a_o[3]" LOC = M6;
NET "ddr0_a_o[2]" LOC = K5;
NET "ddr0_a_o[1]" LOC = K1;
NET "ddr0_a_o[0]" LOC = K2;
# DDR IO standards and terminations
NET "ddr0_udqs_p_b" IOSTANDARD = "DIFF_SSTL15_II";
NET "ddr0_udqs_n_b" IOSTANDARD = "DIFF_SSTL15_II";
NET "ddr0_ldqs_p_b" IOSTANDARD = "DIFF_SSTL15_II";
NET "ddr0_ldqs_n_b" IOSTANDARD = "DIFF_SSTL15_II";
NET "ddr0_ck_p_o" IOSTANDARD = "DIFF_SSTL15_II";
NET "ddr0_ck_n_o" IOSTANDARD = "DIFF_SSTL15_II";
NET "ddr0_rzq_b" IOSTANDARD = "SSTL15_II";
NET "ddr0_we_n_o" IOSTANDARD = "SSTL15_II";
NET "ddr0_udm_o" IOSTANDARD = "SSTL15_II";
NET "ddr0_reset_n_o" IOSTANDARD = "SSTL15_II";
NET "ddr0_ras_n_o" IOSTANDARD = "SSTL15_II";
NET "ddr0_odt_o" IOSTANDARD = "SSTL15_II";
NET "ddr0_ldm_o" IOSTANDARD = "SSTL15_II";
NET "ddr0_cke_o" IOSTANDARD = "SSTL15_II";
NET "ddr0_cas_n_o" IOSTANDARD = "SSTL15_II";
NET "ddr0_dq_b[*]" IOSTANDARD = "SSTL15_II";
NET "ddr0_ba_o[*]" IOSTANDARD = "SSTL15_II";
NET "ddr0_a_o[*]" IOSTANDARD = "SSTL15_II";
NET "ddr0_dq_b[*]" IN_TERM = NONE;
NET "ddr0_ldqs_p_b" IN_TERM = NONE;
NET "ddr0_ldqs_n_b" IN_TERM = NONE;
NET "ddr0_udqs_p_b" IN_TERM = NONE;
NET "ddr0_udqs_n_b" IN_TERM = NONE;
#----------------------------------------
# FMC slot
#----------------------------------------
NET "fmc0_adc_ext_trigger_n_i" LOC = AB13;
NET "fmc0_adc_ext_trigger_p_i" LOC = Y13;
# dco_p and dco_n are swapped compared to the FMC ADC schematics
# this is to be coherent in the hdl design
NET "fmc0_adc_dco_n_i" LOC = AB11;
NET "fmc0_adc_dco_p_i" LOC = Y11;
# fr_p and fr_n are swapped compared to the FMC ADC schematics
# this is to be coherent in the hdl design
NET "fmc0_adc_fr_n_i" LOC = AB12;
NET "fmc0_adc_fr_p_i" LOC = AA12;
NET "fmc0_adc_outa_n_i[0]" LOC = AB4;
NET "fmc0_adc_outa_p_i[0]" LOC = AA4;
NET "fmc0_adc_outb_n_i[0]" LOC = W11;
NET "fmc0_adc_outb_p_i[0]" LOC = V11;
NET "fmc0_adc_outa_n_i[1]" LOC = Y12;
NET "fmc0_adc_outa_p_i[1]" LOC = W12;
NET "fmc0_adc_outb_n_i[1]" LOC = AB9;
NET "fmc0_adc_outb_p_i[1]" LOC = Y9;
NET "fmc0_adc_outa_n_i[2]" LOC = AB8;
NET "fmc0_adc_outa_p_i[2]" LOC = AA8;
NET "fmc0_adc_outb_n_i[2]" LOC = AB7;
NET "fmc0_adc_outb_p_i[2]" LOC = Y7;
NET "fmc0_adc_outa_n_i[3]" LOC = V9;
NET "fmc0_adc_outa_p_i[3]" LOC = U9;
NET "fmc0_adc_outb_n_i[3]" LOC = AB6;
NET "fmc0_adc_outb_p_i[3]" LOC = AA6;
NET "fmc0_adc_spi_din_i" LOC = T15;
NET "fmc0_adc_spi_dout_o" LOC = C18;
NET "fmc0_adc_spi_sck_o" LOC = D17;
NET "fmc0_adc_spi_cs_adc_n_o" LOC = V17;
NET "fmc0_adc_spi_cs_dac1_n_o" LOC = B20;
NET "fmc0_adc_spi_cs_dac2_n_o" LOC = A20;
NET "fmc0_adc_spi_cs_dac3_n_o" LOC = C19;
NET "fmc0_adc_spi_cs_dac4_n_o" LOC = A19;
NET "fmc0_adc_gpio_dac_clr_n_o" LOC = W18;
NET "fmc0_adc_gpio_led_acq_o" LOC = W15;
NET "fmc0_adc_gpio_led_trig_o" LOC = Y16;
NET "fmc0_adc_gpio_ssr_ch1_o[0]" LOC = Y17;
NET "fmc0_adc_gpio_ssr_ch1_o[1]" LOC = AB17;
NET "fmc0_adc_gpio_ssr_ch1_o[2]" LOC = AB18;
NET "fmc0_adc_gpio_ssr_ch1_o[3]" LOC = U15;
NET "fmc0_adc_gpio_ssr_ch1_o[4]" LOC = W14;
NET "fmc0_adc_gpio_ssr_ch1_o[5]" LOC = Y14;
NET "fmc0_adc_gpio_ssr_ch1_o[6]" LOC = W17;
NET "fmc0_adc_gpio_ssr_ch2_o[0]" LOC = R11;
NET "fmc0_adc_gpio_ssr_ch2_o[1]" LOC = AB15;
NET "fmc0_adc_gpio_ssr_ch2_o[2]" LOC = R13;
NET "fmc0_adc_gpio_ssr_ch2_o[3]" LOC = T14;
NET "fmc0_adc_gpio_ssr_ch2_o[4]" LOC = V13;
NET "fmc0_adc_gpio_ssr_ch2_o[5]" LOC = AA18;
NET "fmc0_adc_gpio_ssr_ch2_o[6]" LOC = W13;
NET "fmc0_adc_gpio_ssr_ch3_o[0]" LOC = R9;
NET "fmc0_adc_gpio_ssr_ch3_o[1]" LOC = R8;
NET "fmc0_adc_gpio_ssr_ch3_o[2]" LOC = T10;
NET "fmc0_adc_gpio_ssr_ch3_o[3]" LOC = U10;
NET "fmc0_adc_gpio_ssr_ch3_o[4]" LOC = W10;
NET "fmc0_adc_gpio_ssr_ch3_o[5]" LOC = Y10;
NET "fmc0_adc_gpio_ssr_ch3_o[6]" LOC = T11;
NET "fmc0_adc_gpio_ssr_ch4_o[0]" LOC = W6;
NET "fmc0_adc_gpio_ssr_ch4_o[1]" LOC = Y6;
NET "fmc0_adc_gpio_ssr_ch4_o[2]" LOC = V7;
NET "fmc0_adc_gpio_ssr_ch4_o[3]" LOC = W8;
NET "fmc0_adc_gpio_ssr_ch4_o[4]" LOC = T8;
NET "fmc0_adc_gpio_ssr_ch4_o[5]" LOC = Y5;
NET "fmc0_adc_gpio_ssr_ch4_o[6]" LOC = U8;
NET "fmc0_adc_gpio_si570_oe_o" LOC = AB5;
NET "fmc0_adc_si570_scl_b" LOC = U12;
NET "fmc0_adc_si570_sda_b" LOC = T12;
NET "fmc0_adc_one_wire_b" LOC = Y18;
# IO standards
NET "fmc0_adc_ext_trigger_?_i" IOSTANDARD = "LVDS_25";
NET "fmc0_adc_dco_?_i" IOSTANDARD = "LVDS_25";
NET "fmc0_adc_fr_?_i" IOSTANDARD = "LVDS_25";
NET "fmc0_adc_out?_?_i[*]" IOSTANDARD = "LVDS_25";
NET "fmc0_adc_spi_din_i" IOSTANDARD = "LVCMOS25";
NET "fmc0_adc_spi_dout_o" IOSTANDARD = "LVCMOS25";
NET "fmc0_adc_spi_sck_o" IOSTANDARD = "LVCMOS25";
NET "fmc0_adc_spi_cs_adc_n_o" IOSTANDARD = "LVCMOS25";
NET "fmc0_adc_spi_cs_dac?_n_o" IOSTANDARD = "LVCMOS25";
NET "fmc0_adc_gpio_dac_clr_n_o" IOSTANDARD = "LVCMOS25";
NET "fmc0_adc_gpio_led_acq_o" IOSTANDARD = "LVCMOS25";
NET "fmc0_adc_gpio_led_trig_o" IOSTANDARD = "LVCMOS25";
NET "fmc0_adc_gpio_ssr_ch?_o[*]" IOSTANDARD = "LVCMOS25";
NET "fmc0_adc_gpio_si570_oe_o" IOSTANDARD = "LVCMOS25";
NET "fmc0_adc_si570_scl_b" IOSTANDARD = "LVCMOS25";
NET "fmc0_adc_si570_sda_b" IOSTANDARD = "LVCMOS25";
NET "fmc0_adc_one_wire_b" IOSTANDARD = "LVCMOS25";
#----------------------------------------
# IOBs
#----------------------------------------
INST "cmp0_fmc_adc_mezzanine/cmp_fmc_spi/*/Wrapped_SPI/shift/s_out" IOB = FALSE;
INST "cmp0_fmc_adc_mezzanine/cmp_fmc_spi/*/Wrapped_SPI/clgen/clk_out" IOB = FALSE;
#----------------------------------------
# Clocks
#----------------------------------------
NET "fmc0_adc_dco_n_i" TNM_NET = fmc0_adc_dco_n_i;
TIMESPEC TS_fmc0_adc_dco_n_i = PERIOD "fmc0_adc_dco_n_i" 2.5 ns HIGH 50%;
#----------------------------------------
# Xilinx MCB tweaks
#----------------------------------------
# These are suggested by the Xilinx-generated MCB.
# More info in the UCF file found in the "user_design/par" of the generated core.
NET "cmp_ddr0_ctrl_bank/*/c?_pll_lock" TIG;
NET "cmp_ddr0_ctrl_bank/*/memc?_mcb_raw_wrapper_inst/selfrefresh_mcb_mode" TIG;
#NET "cmp_ddr0_ctrl_bank/*/mcb_soft_calibration_inst/DONE_SOFTANDHARD_CAL" TIG;
#ERR NET "cmp_ddr0_ctrl_bank/*/mcb_soft_calibration_inst/SELFREFRESH_MCB_REQ" TIG;
#----------------------------------------
# Asynchronous resets
#----------------------------------------
# Ignore async reset to DDR controller
NET "ddr0_rst" TPTHRU = ddr_rst;
TIMESPEC TS_ddr_rst_tig = FROM FFS THRU ddr_rst TIG;
#----------------------------------------
# Cross-clock domain sync
#----------------------------------------
NET "cmp0_fmc_adc_mezzanine/cmp_fmc_adc_100Ms_core/fs_clk" TNM_NET = fs_clk;
NET "cmp_ddr0_ctrl_bank/*/memc3_infrastructure_inst/mcb_drp_clk_bufg_in" TNM_NET = ddr0_bank3_clk;
TIMEGRP "ddr0_clk" = "ddr0_clk_333m" "ddr0_bank3_clk";
TIMEGRP "ddr0_sync_ffs" = "sync_ffs" EXCEPT "ddr0_clk";
TIMEGRP "fmc0_adc_sync_ffs" = "sync_ffs" EXCEPT "fs_clk";
TIMESPEC TS_ddr0_sync_ffs = FROM ddr0_clk TO "ddr0_sync_ffs" TIG;
TIMESPEC TS_adc0_sync_ffs = FROM fs0_clk TO "adc0_sync_ffs" TIG;
TIMEGRP "ddr0_sync_reg" = "sync_reg" EXCEPT "ddr0_clk";
TIMEGRP "fmc0_adc_sync_reg" = "sync_reg" EXCEPT "fs_clk";
TIMESPEC TS_ddr_sync_reg = FROM ddr_clk TO "ddr0_sync_reg" 3ns DATAPATHONLY;
TIMESPEC TS_adc_sync_reg = FROM fs_clk TO "fmc0_adc_sync_reg" 10ns DATAPATHONLY;
wrtd-53772dc3cd49421ea1fa6326a199b7a72dc04d18/hdl/syn/wrtd_ref_svec_tdc_fd/ 0000775 0000000 0000000 00000000000 13460261316 0025127 5 ustar 00root root 0000000 0000000 wrtd-53772dc3cd49421ea1fa6326a199b7a72dc04d18/hdl/syn/wrtd_ref_svec_tdc_fd/.gitignore 0000664 0000000 0000000 00000000067 13460261316 0027122 0 ustar 00root root 0000000 0000000 *
!.gitignore
!Manifest.py
!*.ucf
!syn_extra_steps.tcl
wrtd-53772dc3cd49421ea1fa6326a199b7a72dc04d18/hdl/syn/wrtd_ref_svec_tdc_fd/Manifest.py 0000664 0000000 0000000 00000001362 13460261316 0027251 0 ustar 00root root 0000000 0000000 # HDLMake 'develop' branch required.
#
# Due to bugs in release v3.0 of hdlmake it is necessary to use the "develop"
# branch of hdlmake, commit db4e1ab.
board = "svec"
target = "xilinx"
action = "synthesis"
syn_device = "xc6slx150t"
syn_grade = "-3"
syn_package = "fgg900"
syn_top = "wrtd_ref_svec_tdc_fd"
syn_project = "wrtd_ref_svec_tdc_fd.xise"
syn_tool = "ise"
fetchto = "../../../dependencies"
syn_post_project_cmd = (
"$(TCL_INTERPRETER) " + \
fetchto + "/general-cores/tools/sdb_desc_gen.tcl " + \
syn_tool + " $(PROJECT_FILE);" \
"$(TCL_INTERPRETER) syn_extra_steps.tcl $(PROJECT_FILE)"
)
files = [
"wrtd_ref_svec_tdc_fd.ucf",
]
modules = {
"local" : [
"../../top/wrtd_ref_svec_tdc_fd",
],
}
wrtd-53772dc3cd49421ea1fa6326a199b7a72dc04d18/hdl/syn/wrtd_ref_svec_tdc_fd/syn_extra_steps.tcl 0000664 0000000 0000000 00000002013 13460261316 0031061 0 ustar 00root root 0000000 0000000 # get project file from 1st command-line argument
set project_file [lindex $argv 0]
if {![file exists $project_file]} {
report ERROR "Missing file $project_file, exiting."
exit -1
}
xilinx::project open $project_file
# Some of these are not respected by ISE when passed through hdlmake,
# so we add them all ourselves after creating the project
#
# Not respected by ISE when passed through hdlmake:
# 1. Pack I/O Registers/Latches into IOBs
# 2. Register Duplication Map
xilinx::project set "Enable Multi-Threading" "2" -process "Map"
xilinx::project set "Enable Multi-Threading" "4" -process "Place & Route"
xilinx::project set "Pack I/O Registers into IOBs" "Yes"
xilinx::project set "Pack I/O Registers/Latches into IOBs" "For Inputs and Outputs"
xilinx::project set "Register Balancing" "Yes"
xilinx::project set "Register Duplication Map" "On"
#xilinx::project set "Placer Extra Effort Map" "Normal"
#xilinx::project set "Extra Effort (Highest PAR level only)" "Normal"
xilinx::project save
xilinx::project close
wrtd-53772dc3cd49421ea1fa6326a199b7a72dc04d18/hdl/syn/wrtd_ref_svec_tdc_fd/wrtd_ref_svec_tdc_fd.ucf 0000664 0000000 0000000 00000074272 13460261316 0032001 0 ustar 00root root 0000000 0000000 #===============================================================================
# IO Location Constraints
#===============================================================================
#----------------------------------------
# VME interface
#----------------------------------------
NET "vme_write_n_i" LOC = R1;
NET "vme_sysreset_n_i" LOC = P4;
NET "vme_retry_oe_o" LOC = R4;
NET "vme_retry_n_o" LOC = AB2;
NET "vme_lword_n_b" LOC = M7;
NET "vme_iackout_n_o" LOC = N3;
NET "vme_iackin_n_i" LOC = P7;
NET "vme_iack_n_i" LOC = N1;
NET "vme_dtack_oe_o" LOC = T1;
NET "vme_dtack_n_o" LOC = R5;
NET "vme_ds_n_i[1]" LOC = Y6;
NET "vme_ds_n_i[0]" LOC = Y7;
NET "vme_data_oe_n_o" LOC = P1;
NET "vme_data_dir_o" LOC = P2;
NET "vme_berr_o" LOC = R3;
NET "vme_as_n_i" LOC = P6;
NET "vme_addr_oe_n_o" LOC = N4;
NET "vme_addr_dir_o" LOC = N5;
NET "vme_irq_o[7]" LOC = R7;
NET "vme_irq_o[6]" LOC = AH2;
NET "vme_irq_o[5]" LOC = AF2;
NET "vme_irq_o[4]" LOC = N9;
NET "vme_irq_o[3]" LOC = N10;
NET "vme_irq_o[2]" LOC = AH4;
NET "vme_irq_o[1]" LOC = AG4;
NET "vme_gap_i" LOC = M6;
NET "vme_ga_i[4]" LOC = V9;
NET "vme_ga_i[3]" LOC = V10;
NET "vme_ga_i[2]" LOC = AJ1;
NET "vme_ga_i[1]" LOC = AH1;
NET "vme_ga_i[0]" LOC = V7;
NET "vme_data_b[31]" LOC = AK3;
NET "vme_data_b[30]" LOC = AH3;
NET "vme_data_b[29]" LOC = T8;
NET "vme_data_b[28]" LOC = T9;
NET "vme_data_b[27]" LOC = AK4;
NET "vme_data_b[26]" LOC = AJ4;
NET "vme_data_b[25]" LOC = W6;
NET "vme_data_b[24]" LOC = W7;
NET "vme_data_b[23]" LOC = AB6;
NET "vme_data_b[22]" LOC = AB7;
NET "vme_data_b[21]" LOC = W9;
NET "vme_data_b[20]" LOC = W10;
NET "vme_data_b[19]" LOC = AK5;
NET "vme_data_b[18]" LOC = AH5;
NET "vme_data_b[17]" LOC = AD6;
NET "vme_data_b[16]" LOC = AC6;
NET "vme_data_b[15]" LOC = AA6;
NET "vme_data_b[14]" LOC = AA7;
NET "vme_data_b[13]" LOC = T6;
NET "vme_data_b[12]" LOC = T7;
NET "vme_data_b[11]" LOC = AG5;
NET "vme_data_b[10]" LOC = AE5;
NET "vme_data_b[9]" LOC = Y11;
NET "vme_data_b[8]" LOC = W11;
NET "vme_data_b[7]" LOC = AF6;
NET "vme_data_b[6]" LOC = AE6;
NET "vme_data_b[5]" LOC = Y8;
NET "vme_data_b[4]" LOC = Y9;
NET "vme_data_b[3]" LOC = AE7;
NET "vme_data_b[2]" LOC = AD7;
NET "vme_data_b[1]" LOC = AA9;
NET "vme_data_b[0]" LOC = AA10;
NET "vme_am_i[5]" LOC = V8;
NET "vme_am_i[4]" LOC = AG3;
NET "vme_am_i[3]" LOC = AF3;
NET "vme_am_i[2]" LOC = AF4;
NET "vme_am_i[1]" LOC = AE4;
NET "vme_am_i[0]" LOC = AK2;
NET "vme_addr_b[31]" LOC = T2;
NET "vme_addr_b[30]" LOC = T3;
NET "vme_addr_b[29]" LOC = T4;
NET "vme_addr_b[28]" LOC = U1;
NET "vme_addr_b[27]" LOC = U3;
NET "vme_addr_b[26]" LOC = U4;
NET "vme_addr_b[25]" LOC = U5;
NET "vme_addr_b[24]" LOC = V1;
NET "vme_addr_b[23]" LOC = V2;
NET "vme_addr_b[22]" LOC = W1;
NET "vme_addr_b[21]" LOC = W3;
NET "vme_addr_b[20]" LOC = AA4;
NET "vme_addr_b[19]" LOC = AA5;
NET "vme_addr_b[18]" LOC = Y1;
NET "vme_addr_b[17]" LOC = Y2;
NET "vme_addr_b[16]" LOC = Y3;
NET "vme_addr_b[15]" LOC = Y4;
NET "vme_addr_b[14]" LOC = AC1;
NET "vme_addr_b[13]" LOC = AC3;
NET "vme_addr_b[12]" LOC = AD1;
NET "vme_addr_b[11]" LOC = AD2;
NET "vme_addr_b[10]" LOC = AB3;
NET "vme_addr_b[9]" LOC = AB4;
NET "vme_addr_b[8]" LOC = AD3;
NET "vme_addr_b[7]" LOC = AD4;
NET "vme_addr_b[6]" LOC = AC4;
NET "vme_addr_b[5]" LOC = AC5;
NET "vme_addr_b[4]" LOC = N7;
NET "vme_addr_b[3]" LOC = N8;
NET "vme_addr_b[2]" LOC = AE1;
NET "vme_addr_b[1]" LOC = AE3;
NET "vme_write_n_i" IOSTANDARD = "LVCMOS33";
NET "vme_sysreset_n_i" IOSTANDARD = "LVCMOS33";
NET "vme_retry_oe_o" IOSTANDARD = "LVCMOS33";
NET "vme_retry_n_o" IOSTANDARD = "LVCMOS33";
NET "vme_lword_n_b" IOSTANDARD = "LVCMOS33";
NET "vme_iackout_n_o" IOSTANDARD = "LVCMOS33";
NET "vme_iackin_n_i" IOSTANDARD = "LVCMOS33";
NET "vme_iack_n_i" IOSTANDARD = "LVCMOS33";
NET "vme_dtack_oe_o" IOSTANDARD = "LVCMOS33";
NET "vme_dtack_n_o" IOSTANDARD = "LVCMOS33";
NET "vme_ds_n_i[1]" IOSTANDARD = "LVCMOS33";
NET "vme_ds_n_i[0]" IOSTANDARD = "LVCMOS33";
NET "vme_data_oe_n_o" IOSTANDARD = "LVCMOS33";
NET "vme_data_dir_o" IOSTANDARD = "LVCMOS33";
NET "vme_berr_o" IOSTANDARD = "LVCMOS33";
NET "vme_as_n_i" IOSTANDARD = "LVCMOS33";
NET "vme_addr_oe_n_o" IOSTANDARD = "LVCMOS33";
NET "vme_addr_dir_o" IOSTANDARD = "LVCMOS33";
NET "vme_irq_o[7]" IOSTANDARD = "LVCMOS33";
NET "vme_irq_o[6]" IOSTANDARD = "LVCMOS33";
NET "vme_irq_o[5]" IOSTANDARD = "LVCMOS33";
NET "vme_irq_o[4]" IOSTANDARD = "LVCMOS33";
NET "vme_irq_o[3]" IOSTANDARD = "LVCMOS33";
NET "vme_irq_o[2]" IOSTANDARD = "LVCMOS33";
NET "vme_irq_o[1]" IOSTANDARD = "LVCMOS33";
NET "vme_gap_i" IOSTANDARD = "LVCMOS33";
NET "vme_ga_i[4]" IOSTANDARD = "LVCMOS33";
NET "vme_ga_i[3]" IOSTANDARD = "LVCMOS33";
NET "vme_ga_i[2]" IOSTANDARD = "LVCMOS33";
NET "vme_ga_i[1]" IOSTANDARD = "LVCMOS33";
NET "vme_ga_i[0]" IOSTANDARD = "LVCMOS33";
NET "vme_data_b[31]" IOSTANDARD = "LVCMOS33";
NET "vme_data_b[30]" IOSTANDARD = "LVCMOS33";
NET "vme_data_b[29]" IOSTANDARD = "LVCMOS33";
NET "vme_data_b[28]" IOSTANDARD = "LVCMOS33";
NET "vme_data_b[27]" IOSTANDARD = "LVCMOS33";
NET "vme_data_b[26]" IOSTANDARD = "LVCMOS33";
NET "vme_data_b[25]" IOSTANDARD = "LVCMOS33";
NET "vme_data_b[24]" IOSTANDARD = "LVCMOS33";
NET "vme_data_b[23]" IOSTANDARD = "LVCMOS33";
NET "vme_data_b[22]" IOSTANDARD = "LVCMOS33";
NET "vme_data_b[21]" IOSTANDARD = "LVCMOS33";
NET "vme_data_b[20]" IOSTANDARD = "LVCMOS33";
NET "vme_data_b[19]" IOSTANDARD = "LVCMOS33";
NET "vme_data_b[18]" IOSTANDARD = "LVCMOS33";
NET "vme_data_b[17]" IOSTANDARD = "LVCMOS33";
NET "vme_data_b[16]" IOSTANDARD = "LVCMOS33";
NET "vme_data_b[15]" IOSTANDARD = "LVCMOS33";
NET "vme_data_b[14]" IOSTANDARD = "LVCMOS33";
NET "vme_data_b[13]" IOSTANDARD = "LVCMOS33";
NET "vme_data_b[12]" IOSTANDARD = "LVCMOS33";
NET "vme_data_b[11]" IOSTANDARD = "LVCMOS33";
NET "vme_data_b[10]" IOSTANDARD = "LVCMOS33";
NET "vme_data_b[9]" IOSTANDARD = "LVCMOS33";
NET "vme_data_b[8]" IOSTANDARD = "LVCMOS33";
NET "vme_data_b[7]" IOSTANDARD = "LVCMOS33";
NET "vme_data_b[6]" IOSTANDARD = "LVCMOS33";
NET "vme_data_b[5]" IOSTANDARD = "LVCMOS33";
NET "vme_data_b[4]" IOSTANDARD = "LVCMOS33";
NET "vme_data_b[3]" IOSTANDARD = "LVCMOS33";
NET "vme_data_b[2]" IOSTANDARD = "LVCMOS33";
NET "vme_data_b[1]" IOSTANDARD = "LVCMOS33";
NET "vme_data_b[0]" IOSTANDARD = "LVCMOS33";
NET "vme_am_i[5]" IOSTANDARD = "LVCMOS33";
NET "vme_am_i[4]" IOSTANDARD = "LVCMOS33";
NET "vme_am_i[3]" IOSTANDARD = "LVCMOS33";
NET "vme_am_i[2]" IOSTANDARD = "LVCMOS33";
NET "vme_am_i[1]" IOSTANDARD = "LVCMOS33";
NET "vme_am_i[0]" IOSTANDARD = "LVCMOS33";
NET "vme_addr_b[31]" IOSTANDARD = "LVCMOS33";
NET "vme_addr_b[30]" IOSTANDARD = "LVCMOS33";
NET "vme_addr_b[29]" IOSTANDARD = "LVCMOS33";
NET "vme_addr_b[28]" IOSTANDARD = "LVCMOS33";
NET "vme_addr_b[27]" IOSTANDARD = "LVCMOS33";
NET "vme_addr_b[26]" IOSTANDARD = "LVCMOS33";
NET "vme_addr_b[25]" IOSTANDARD = "LVCMOS33";
NET "vme_addr_b[24]" IOSTANDARD = "LVCMOS33";
NET "vme_addr_b[23]" IOSTANDARD = "LVCMOS33";
NET "vme_addr_b[22]" IOSTANDARD = "LVCMOS33";
NET "vme_addr_b[21]" IOSTANDARD = "LVCMOS33";
NET "vme_addr_b[20]" IOSTANDARD = "LVCMOS33";
NET "vme_addr_b[19]" IOSTANDARD = "LVCMOS33";
NET "vme_addr_b[18]" IOSTANDARD = "LVCMOS33";
NET "vme_addr_b[17]" IOSTANDARD = "LVCMOS33";
NET "vme_addr_b[16]" IOSTANDARD = "LVCMOS33";
NET "vme_addr_b[15]" IOSTANDARD = "LVCMOS33";
NET "vme_addr_b[14]" IOSTANDARD = "LVCMOS33";
NET "vme_addr_b[13]" IOSTANDARD = "LVCMOS33";
NET "vme_addr_b[12]" IOSTANDARD = "LVCMOS33";
NET "vme_addr_b[11]" IOSTANDARD = "LVCMOS33";
NET "vme_addr_b[10]" IOSTANDARD = "LVCMOS33";
NET "vme_addr_b[9]" IOSTANDARD = "LVCMOS33";
NET "vme_addr_b[8]" IOSTANDARD = "LVCMOS33";
NET "vme_addr_b[7]" IOSTANDARD = "LVCMOS33";
NET "vme_addr_b[6]" IOSTANDARD = "LVCMOS33";
NET "vme_addr_b[5]" IOSTANDARD = "LVCMOS33";
NET "vme_addr_b[4]" IOSTANDARD = "LVCMOS33";
NET "vme_addr_b[3]" IOSTANDARD = "LVCMOS33";
NET "vme_addr_b[2]" IOSTANDARD = "LVCMOS33";
NET "vme_addr_b[1]" IOSTANDARD = "LVCMOS33";
#----------------------------------------
# Clock and reset inputs
#----------------------------------------
NET "rst_n_i" LOC = AD28;
NET "rst_n_i" IOSTANDARD = "LVCMOS33";
NET "clk_20m_vcxo_i" LOC = V26;
NET "clk_20m_vcxo_i" IOSTANDARD = "LVCMOS33";
NET "clk_125m_pllref_n_i" LOC = AB30;
NET "clk_125m_pllref_p_i" LOC = AB28;
NET "clk_125m_pllref_n_i" IOSTANDARD = "LVDS_25";
NET "clk_125m_pllref_n_i" IOSTANDARD = "LVDS_25";
NET "clk_125m_gtp_p_i" LOC = B19;
NET "clk_125m_gtp_n_i" LOC = A19;
#----------------------------------------
# SFP slot
#----------------------------------------
NET "sfp_txp_o" LOC = B23;
NET "sfp_txn_o" LOC = A23;
NET "sfp_rxp_i" LOC = D22;
NET "sfp_rxn_i" LOC = C22;
NET "sfp_los_i" LOC = W25;
NET "sfp_mod_def0_i" LOC = Y26;
NET "sfp_mod_def1_b" LOC = Y27;
NET "sfp_mod_def2_b" LOC = AA24;
NET "sfp_rate_select_o" LOC = W24;
NET "sfp_tx_disable_o" LOC = AA25;
NET "sfp_tx_fault_i" LOC = AA27;
NET "sfp_los_i" IOSTANDARD = "LVCMOS33";
NET "sfp_mod_def0_i" IOSTANDARD = "LVCMOS33";
NET "sfp_mod_def1_b" IOSTANDARD = "LVCMOS33";
NET "sfp_mod_def2_b" IOSTANDARD = "LVCMOS33";
NET "sfp_rate_select_o" IOSTANDARD = "LVCMOS33";
NET "sfp_tx_disable_o" IOSTANDARD = "LVCMOS33";
NET "sfp_tx_fault_i" IOSTANDARD = "LVCMOS33";
#----------------------------------------
# Clock controls
#----------------------------------------
NET "pll20dac_din_o" LOC = U28;
NET "pll20dac_sclk_o" LOC = AA28;
NET "pll20dac_sync_n_o" LOC = N28;
NET "pll25dac_din_o" LOC = P25;
NET "pll25dac_sclk_o" LOC = N27;
NET "pll25dac_sync_n_o" LOC = P26;
NET "pll20dac_din_o" IOSTANDARD = "LVCMOS33";
NET "pll20dac_sclk_o" IOSTANDARD = "LVCMOS33";
NET "pll20dac_sync_n_o" IOSTANDARD = "LVCMOS33";
NET "pll25dac_din_o" IOSTANDARD = "LVCMOS33";
NET "pll25dac_sclk_o" IOSTANDARD = "LVCMOS33";
NET "pll25dac_sync_n_o" IOSTANDARD = "LVCMOS33";
#----------------------------------------
# SPI FLASH
#----------------------------------------
NET "spi_ncs_o" LOC = AG27;
NET "spi_ncs_o" IOSTANDARD = "LVCMOS33";
NET "spi_sclk_o" LOC = AG26;
NET "spi_sclk_o" IOSTANDARD = "LVCMOS33";
NET "spi_mosi_o" LOC = AH26;
NET "spi_mosi_o" IOSTANDARD = "LVCMOS33";
NET "spi_miso_i" LOC = AH27;
NET "spi_miso_i" IOSTANDARD = "LVCMOS33";
#----------------------------------------
# UART
#----------------------------------------
NET "uart_txd_o" LOC = U27;
NET "uart_rxd_i" LOC = U25;
NET "uart_txd_o" IOSTANDARD = "LVCMOS33";
NET "uart_rxd_i" IOSTANDARD = "LVCMOS33";
#----------------------------------------
# 1-wire thermoeter + unique ID
#----------------------------------------
NET "carrier_onewire_b" LOC = AC30;
NET "carrier_onewire_b" IOSTANDARD = "LVCMOS33";
#----------------------------------------
# Front panel LEDs
#----------------------------------------
NET "fp_led_line_oen_o[0]" LOC = AD26;
NET "fp_led_line_oen_o[1]" LOC = AD27;
NET "fp_led_line_o[0]" LOC = AC27;
NET "fp_led_line_o[1]" LOC = AC28;
NET "fp_led_column_o[0]" LOC = AE30;
NET "fp_led_column_o[1]" LOC = AE27;
NET "fp_led_column_o[2]" LOC = AE28;
NET "fp_led_column_o[3]" LOC = AF28;
NET "fp_led_line_oen_o[0]" IOSTANDARD="LVCMOS33";
NET "fp_led_line_oen_o[1]" IOSTANDARD="LVCMOS33";
NET "fp_led_line_o[0]" IOSTANDARD="LVCMOS33";
NET "fp_led_line_o[1]" IOSTANDARD="LVCMOS33";
NET "fp_led_column_o[0]" IOSTANDARD="LVCMOS33";
NET "fp_led_column_o[1]" IOSTANDARD="LVCMOS33";
NET "fp_led_column_o[2]" IOSTANDARD="LVCMOS33";
NET "fp_led_column_o[3]" IOSTANDARD="LVCMOS33";
#----------------------------------------
# Front panel IOs
#----------------------------------------
NET "fp_gpio1_o" LOC = T28;
NET "fp_gpio2_o" LOC = R30;
NET "fp_gpio3_i" LOC = V27;
NET "fp_gpio4_i" LOC = U29;
NET "fp_gpio1_a2b_o" LOC = T30;
NET "fp_gpio2_a2b_o" LOC = R29;
NET "fp_gpio34_a2b_o" LOC = V28;
NET "fp_term_en_o[1]" LOC = AB1;
NET "fp_term_en_o[2]" LOC = W5;
NET "fp_term_en_o[3]" LOC = W4;
NET "fp_term_en_o[4]" LOC = V4;
NET "fp_gpio1_o" IOSTANDARD = "LVCMOS33";
NET "fp_gpio2_o" IOSTANDARD = "LVCMOS33";
NET "fp_gpio3_i" IOSTANDARD = "LVCMOS33";
NET "fp_gpio4_i" IOSTANDARD = "LVCMOS33";
NET "fp_gpio1_a2b_o" IOSTANDARD = "LVCMOS33";
NET "fp_gpio2_a2b_o" IOSTANDARD = "LVCMOS33";
NET "fp_gpio34_a2b_o" IOSTANDARD = "LVCMOS33";
NET "fp_term_en_o[1]" IOSTANDARD = "LVCMOS33";
NET "fp_term_en_o[2]" IOSTANDARD = "LVCMOS33";
NET "fp_term_en_o[3]" IOSTANDARD = "LVCMOS33";
NET "fp_term_en_o[4]" IOSTANDARD = "LVCMOS33";
#----------------------------------------
# Carrier I2C EEPROM
#----------------------------------------
NET "carrier_scl_b" LOC = AC29;
NET "carrier_sda_b" LOC = AA30;
NET "carrier_scl_b" IOSTANDARD = "LVCMOS33";
NET "carrier_sda_b" IOSTANDARD = "LVCMOS33";
#----------------------------------------
# FMCs
#----------------------------------------
NET "fmc0_prsntm2c_n_i" LOC = N30;
NET "fmc0_scl_b" LOC = P28;
NET "fmc0_sda_b" LOC = P30;
NET "fmc1_prsntm2c_n_i" LOC = AE29;
NET "fmc1_scl_b" LOC = W29;
NET "fmc1_sda_b" LOC = V30;
NET "fmc1_prsntm2c_n_i" IOSTANDARD = "LVCMOS33";
NET "fmc1_scl_b" IOSTANDARD = "LVCMOS33";
NET "fmc1_sda_b" IOSTANDARD = "LVCMOS33";
NET "fmc0_prsntm2c_n_i" IOSTANDARD = "LVCMOS33";
NET "fmc0_scl_b" IOSTANDARD = "LVCMOS33";
NET "fmc0_sda_b" IOSTANDARD = "LVCMOS33";
# ucfgen pin assignments for mezzanine fmc-tdc-v3 slot 0
NET "fmc0_tdc_acam_refclk_p_i" LOC = "H15";
NET "fmc0_tdc_acam_refclk_p_i" IOSTANDARD = "LVDS_25";
NET "fmc0_tdc_acam_refclk_n_i" LOC = "G15";
NET "fmc0_tdc_acam_refclk_n_i" IOSTANDARD = "LVDS_25";
NET "fmc0_tdc_125m_clk_p_i" LOC = "E16";
NET "fmc0_tdc_125m_clk_p_i" IOSTANDARD = "LVDS_25";
NET "fmc0_tdc_125m_clk_n_i" LOC = "D16";
NET "fmc0_tdc_125m_clk_n_i" IOSTANDARD = "LVDS_25";
NET "fmc0_tdc_led_trig1_o" LOC = "H13";
NET "fmc0_tdc_led_trig1_o" IOSTANDARD = "LVCMOS25";
NET "fmc0_tdc_led_trig2_o" LOC = "H11";
NET "fmc0_tdc_led_trig2_o" IOSTANDARD = "LVCMOS25";
NET "fmc0_tdc_led_trig3_o" LOC = "G11";
NET "fmc0_tdc_led_trig3_o" IOSTANDARD = "LVCMOS25";
NET "fmc0_tdc_term_en_1_o" LOC = "C16";
NET "fmc0_tdc_term_en_1_o" IOSTANDARD = "LVCMOS25";
NET "fmc0_tdc_term_en_2_o" LOC = "A16";
NET "fmc0_tdc_term_en_2_o" IOSTANDARD = "LVCMOS25";
NET "fmc0_tdc_ef1_i" LOC = "F19";
NET "fmc0_tdc_ef1_i" IOSTANDARD = "LVCMOS25";
NET "fmc0_tdc_ef2_i" LOC = "E19";
NET "fmc0_tdc_ef2_i" IOSTANDARD = "LVCMOS25";
NET "fmc0_tdc_term_en_3_o" LOC = "F15";
NET "fmc0_tdc_term_en_3_o" IOSTANDARD = "LVCMOS25";
NET "fmc0_tdc_term_en_4_o" LOC = "E15";
NET "fmc0_tdc_term_en_4_o" IOSTANDARD = "LVCMOS25";
NET "fmc0_tdc_term_en_5_o" LOC = "F13";
NET "fmc0_tdc_term_en_5_o" IOSTANDARD = "LVCMOS25";
NET "fmc0_tdc_led_status_o" LOC = "E13";
NET "fmc0_tdc_led_status_o" IOSTANDARD = "LVCMOS25";
NET "fmc0_tdc_led_trig4_o" LOC = "L11";
NET "fmc0_tdc_led_trig4_o" IOSTANDARD = "LVCMOS25";
NET "fmc0_tdc_led_trig5_o" LOC = "K11";
NET "fmc0_tdc_led_trig5_o" IOSTANDARD = "LVCMOS25";
NET "fmc0_tdc_pll_sclk_o" LOC = "M15";
NET "fmc0_tdc_pll_sclk_o" IOSTANDARD = "LVCMOS25";
NET "fmc0_tdc_pll_dac_sync_n_o" LOC = "K15";
NET "fmc0_tdc_pll_dac_sync_n_o" IOSTANDARD = "LVCMOS25";
NET "fmc0_tdc_pll_cs_n_o" LOC = "L14";
NET "fmc0_tdc_pll_cs_n_o" IOSTANDARD = "LVCMOS25";
NET "fmc0_tdc_cs_n_o" LOC = "K14";
NET "fmc0_tdc_cs_n_o" IOSTANDARD = "LVCMOS25";
NET "fmc0_tdc_err_flag_i" LOC = "H16";
NET "fmc0_tdc_err_flag_i" IOSTANDARD = "LVCMOS25";
NET "fmc0_tdc_int_flag_i" LOC = "G16";
NET "fmc0_tdc_int_flag_i" IOSTANDARD = "LVCMOS25";
NET "fmc0_tdc_start_dis_o" LOC = "F11";
NET "fmc0_tdc_start_dis_o" IOSTANDARD = "LVCMOS25";
NET "fmc0_tdc_stop_dis_o" LOC = "E11";
NET "fmc0_tdc_stop_dis_o" IOSTANDARD = "LVCMOS25";
NET "fmc0_tdc_pll_sdo_i" LOC = "L13";
NET "fmc0_tdc_pll_sdo_i" IOSTANDARD = "LVCMOS25";
NET "fmc0_tdc_pll_status_i" LOC = "E9";
NET "fmc0_tdc_pll_status_i" IOSTANDARD = "LVCMOS25";
NET "fmc0_tdc_pll_sdi_o" LOC = "M13";
NET "fmc0_tdc_pll_sdi_o" IOSTANDARD = "LVCMOS25";
NET "fmc0_tdc_start_from_fpga_o" LOC = "F9";
NET "fmc0_tdc_start_from_fpga_o" IOSTANDARD = "LVCMOS25";
NET "fmc0_tdc_start_from_fpga_o" SLEW = SLOW;
NET "fmc0_tdc_start_from_fpga_o" DRIVE = 4;
NET "fmc0_tdc_data_bus_io[27]" LOC = "E17";
NET "fmc0_tdc_data_bus_io[27]" IOSTANDARD = "LVCMOS25";
NET "fmc0_tdc_data_bus_io[26]" LOC = "F17";
NET "fmc0_tdc_data_bus_io[26]" IOSTANDARD = "LVCMOS25";
NET "fmc0_tdc_data_bus_io[25]" LOC = "F18";
NET "fmc0_tdc_data_bus_io[25]" IOSTANDARD = "LVCMOS25";
NET "fmc0_tdc_data_bus_io[24]" LOC = "G18";
NET "fmc0_tdc_data_bus_io[24]" IOSTANDARD = "LVCMOS25";
NET "fmc0_tdc_data_bus_io[23]" LOC = "F20";
NET "fmc0_tdc_data_bus_io[23]" IOSTANDARD = "LVCMOS25";
NET "fmc0_tdc_data_bus_io[22]" LOC = "G20";
NET "fmc0_tdc_data_bus_io[22]" IOSTANDARD = "LVCMOS25";
NET "fmc0_tdc_data_bus_io[21]" LOC = "E21";
NET "fmc0_tdc_data_bus_io[21]" IOSTANDARD = "LVCMOS25";
NET "fmc0_tdc_data_bus_io[20]" LOC = "F21";
NET "fmc0_tdc_data_bus_io[20]" IOSTANDARD = "LVCMOS25";
NET "fmc0_tdc_data_bus_io[19]" LOC = "K21";
NET "fmc0_tdc_data_bus_io[19]" IOSTANDARD = "LVCMOS25";
NET "fmc0_tdc_data_bus_io[18]" LOC = "L21";
NET "fmc0_tdc_data_bus_io[18]" IOSTANDARD = "LVCMOS25";
NET "fmc0_tdc_data_bus_io[17]" LOC = "L20";
NET "fmc0_tdc_data_bus_io[17]" IOSTANDARD = "LVCMOS25";
NET "fmc0_tdc_data_bus_io[16]" LOC = "M20";
NET "fmc0_tdc_data_bus_io[16]" IOSTANDARD = "LVCMOS25";
NET "fmc0_tdc_data_bus_io[15]" LOC = "F22";
NET "fmc0_tdc_data_bus_io[15]" IOSTANDARD = "LVCMOS25";
NET "fmc0_tdc_data_bus_io[14]" LOC = "G22";
NET "fmc0_tdc_data_bus_io[14]" IOSTANDARD = "LVCMOS25";
NET "fmc0_tdc_data_bus_io[13]" LOC = "L19";
NET "fmc0_tdc_data_bus_io[13]" IOSTANDARD = "LVCMOS25";
NET "fmc0_tdc_data_bus_io[12]" LOC = "M19";
NET "fmc0_tdc_data_bus_io[12]" IOSTANDARD = "LVCMOS25";
NET "fmc0_tdc_data_bus_io[11]" LOC = "E23";
NET "fmc0_tdc_data_bus_io[11]" IOSTANDARD = "LVCMOS25";
NET "fmc0_tdc_data_bus_io[10]" LOC = "F23";
NET "fmc0_tdc_data_bus_io[10]" IOSTANDARD = "LVCMOS25";
NET "fmc0_tdc_data_bus_io[9]" LOC = "A25";
NET "fmc0_tdc_data_bus_io[9]" IOSTANDARD = "LVCMOS25";
NET "fmc0_tdc_data_bus_io[8]" LOC = "B25";
NET "fmc0_tdc_data_bus_io[8]" IOSTANDARD = "LVCMOS25";
NET "fmc0_tdc_data_bus_io[7]" LOC = "G21";
NET "fmc0_tdc_data_bus_io[7]" IOSTANDARD = "LVCMOS25";
NET "fmc0_tdc_data_bus_io[6]" LOC = "C24";
NET "fmc0_tdc_data_bus_io[6]" IOSTANDARD = "LVCMOS25";
NET "fmc0_tdc_data_bus_io[5]" LOC = "H21";
NET "fmc0_tdc_data_bus_io[5]" IOSTANDARD = "LVCMOS25";
NET "fmc0_tdc_data_bus_io[4]" LOC = "D24";
NET "fmc0_tdc_data_bus_io[4]" IOSTANDARD = "LVCMOS25";
NET "fmc0_tdc_data_bus_io[3]" LOC = "D25";
NET "fmc0_tdc_data_bus_io[3]" IOSTANDARD = "LVCMOS25";
NET "fmc0_tdc_data_bus_io[2]" LOC = "E25";
NET "fmc0_tdc_data_bus_io[2]" IOSTANDARD = "LVCMOS25";
NET "fmc0_tdc_data_bus_io[1]" LOC = "H22";
NET "fmc0_tdc_data_bus_io[1]" IOSTANDARD = "LVCMOS25";
NET "fmc0_tdc_data_bus_io[0]" LOC = "J22";
NET "fmc0_tdc_data_bus_io[0]" IOSTANDARD = "LVCMOS25";
NET "fmc0_tdc_address_o[3]" LOC = "F14";
NET "fmc0_tdc_address_o[3]" IOSTANDARD = "LVCMOS25";
NET "fmc0_tdc_address_o[2]" LOC = "G14";
NET "fmc0_tdc_address_o[2]" IOSTANDARD = "LVCMOS25";
NET "fmc0_tdc_address_o[1]" LOC = "H14";
NET "fmc0_tdc_address_o[1]" IOSTANDARD = "LVCMOS25";
NET "fmc0_tdc_address_o[0]" LOC = "J14";
NET "fmc0_tdc_address_o[0]" IOSTANDARD = "LVCMOS25";
NET "fmc0_tdc_oe_n_o" LOC = "G12";
NET "fmc0_tdc_oe_n_o" IOSTANDARD = "LVCMOS25";
NET "fmc0_tdc_oe_n_o" SLEW = SLOW;
NET "fmc0_tdc_oe_n_o" DRIVE = 4;
NET "fmc0_tdc_rd_n_o" LOC = "A15";
NET "fmc0_tdc_rd_n_o" IOSTANDARD = "LVCMOS25";
NET "fmc0_tdc_rd_n_o" SLEW = SLOW;
NET "fmc0_tdc_rd_n_o" DRIVE = 4;
NET "fmc0_tdc_wr_n_o" LOC = "B15";
NET "fmc0_tdc_wr_n_o" IOSTANDARD = "LVCMOS25";
NET "fmc0_tdc_wr_n_o" SLEW = SLOW;
NET "fmc0_tdc_wr_n_o" DRIVE = 4;
NET "fmc0_tdc_enable_inputs_o" LOC = "J12";
NET "fmc0_tdc_enable_inputs_o" IOSTANDARD = "LVCMOS25";
NET "fmc0_tdc_one_wire_b" LOC = "H12";
NET "fmc0_tdc_one_wire_b" IOSTANDARD = "LVCMOS25";
# ucfgen pin assignments for mezzanine fmc-delay-v4 slot 1
NET "fmc1_fd_clk_ref_p_i" LOC = "AH16";
NET "fmc1_fd_clk_ref_p_i" IOSTANDARD = "LVDS_25";
NET "fmc1_fd_clk_ref_n_i" LOC = "AK16";
NET "fmc1_fd_clk_ref_n_i" IOSTANDARD = "LVDS_25";
NET "fmc1_fd_tdc_start_p_i" LOC = "AF16";
NET "fmc1_fd_tdc_start_p_i" IOSTANDARD = "LVDS_25";
NET "fmc1_fd_tdc_start_n_i" LOC = "AG16";
NET "fmc1_fd_tdc_start_n_i" IOSTANDARD = "LVDS_25";
NET "fmc1_fd_delay_len_o[3]" LOC = "AB21";
NET "fmc1_fd_delay_len_o[3]" IOSTANDARD = "LVCMOS25";
NET "fmc1_fd_delay_len_o[3]" SLEW = SLOW;
NET "fmc1_fd_delay_len_o[3]" DRIVE = 4;
NET "fmc1_fd_delay_len_o[2]" LOC = "AC21";
NET "fmc1_fd_delay_len_o[2]" IOSTANDARD = "LVCMOS25";
NET "fmc1_fd_delay_len_o[2]" SLEW = SLOW;
NET "fmc1_fd_delay_len_o[2]" DRIVE = 4;
NET "fmc1_fd_delay_len_o[1]" LOC = "AD24";
NET "fmc1_fd_delay_len_o[1]" IOSTANDARD = "LVCMOS25";
NET "fmc1_fd_delay_len_o[1]" SLEW = SLOW;
NET "fmc1_fd_delay_len_o[1]" DRIVE = 4;
NET "fmc1_fd_delay_len_o[0]" LOC = "AC24";
NET "fmc1_fd_delay_len_o[0]" IOSTANDARD = "LVCMOS25";
NET "fmc1_fd_delay_len_o[0]" SLEW = SLOW;
NET "fmc1_fd_delay_len_o[0]" DRIVE = 4;
NET "fmc1_fd_delay_pulse_o[3]" LOC = "AE22";
NET "fmc1_fd_delay_pulse_o[3]" IOSTANDARD = "LVCMOS25";
NET "fmc1_fd_delay_pulse_o[1]" LOC = "AD17";
NET "fmc1_fd_delay_pulse_o[1]" IOSTANDARD = "LVCMOS25";
NET "fmc1_fd_delay_pulse_o[2]" LOC = "AD22";
NET "fmc1_fd_delay_pulse_o[2]" IOSTANDARD = "LVCMOS25";
NET "fmc1_fd_delay_pulse_o[0]" LOC = "AB17";
NET "fmc1_fd_delay_pulse_o[0]" IOSTANDARD = "LVCMOS25";
NET "fmc1_fd_delay_val_o[3]" LOC = "AA19";
NET "fmc1_fd_delay_val_o[3]" IOSTANDARD = "LVCMOS25";
NET "fmc1_fd_delay_val_o[3]" SLEW = SLOW;
NET "fmc1_fd_delay_val_o[3]" DRIVE = 4;
NET "fmc1_fd_delay_val_o[1]" LOC = "W19";
NET "fmc1_fd_delay_val_o[1]" IOSTANDARD = "LVCMOS25";
NET "fmc1_fd_delay_val_o[1]" SLEW = SLOW;
NET "fmc1_fd_delay_val_o[1]" DRIVE = 4;
NET "fmc1_fd_delay_val_o[7]" LOC = "Y21";
NET "fmc1_fd_delay_val_o[7]" IOSTANDARD = "LVCMOS25";
NET "fmc1_fd_delay_val_o[7]" SLEW = SLOW;
NET "fmc1_fd_delay_val_o[7]" DRIVE = 4;
NET "fmc1_fd_delay_val_o[5]" LOC = "W20";
NET "fmc1_fd_delay_val_o[5]" IOSTANDARD = "LVCMOS25";
NET "fmc1_fd_delay_val_o[5]" SLEW = SLOW;
NET "fmc1_fd_delay_val_o[5]" DRIVE = 4;
NET "fmc1_fd_delay_val_o[9]" LOC = "AA22";
NET "fmc1_fd_delay_val_o[9]" IOSTANDARD = "LVCMOS25";
NET "fmc1_fd_delay_val_o[9]" SLEW = SLOW;
NET "fmc1_fd_delay_val_o[9]" DRIVE = 4;
NET "fmc1_fd_spi_mosi_o" LOC = "AB20";
NET "fmc1_fd_spi_mosi_o" IOSTANDARD = "LVCMOS25";
NET "fmc1_fd_spi_sclk_o" LOC = "AC19";
NET "fmc1_fd_spi_sclk_o" IOSTANDARD = "LVCMOS25";
NET "fmc1_fd_tdc_oe_n_o" LOC = "AF25";
NET "fmc1_fd_tdc_oe_n_o" IOSTANDARD = "LVCMOS25";
NET "fmc1_fd_tdc_start_dis_o" LOC = "AE24";
NET "fmc1_fd_tdc_start_dis_o" IOSTANDARD = "LVCMOS25";
NET "fmc1_fd_spi_cs_gpio_n_o" LOC = "AE19";
NET "fmc1_fd_spi_cs_gpio_n_o" IOSTANDARD = "LVCMOS25";
NET "fmc1_fd_tdc_cal_pulse_o" LOC = "AE23";
NET "fmc1_fd_tdc_cal_pulse_o" IOSTANDARD = "LVCMOS25";
NET "fmc1_fd_dmtd_clk_o" LOC = "AE21";
NET "fmc1_fd_dmtd_clk_o" IOSTANDARD = "LVCMOS25";
NET "fmc1_fd_tdc_wr_n_o" LOC = "AC16";
NET "fmc1_fd_tdc_wr_n_o" IOSTANDARD = "LVCMOS25";
NET "fmc1_fd_tdc_alutrigger_o" LOC = "AB14";
NET "fmc1_fd_tdc_alutrigger_o" IOSTANDARD = "LVCMOS25";
NET "fmc1_fd_led_trig_o" LOC = "Y17";
NET "fmc1_fd_led_trig_o" IOSTANDARD = "LVCMOS25";
NET "fmc1_fd_tdc_d_b[26]" LOC = "Y15";
NET "fmc1_fd_tdc_d_b[26]" IOSTANDARD = "LVCMOS25";
NET "fmc1_fd_tdc_d_b[24]" LOC = "AC15";
NET "fmc1_fd_tdc_d_b[24]" IOSTANDARD = "LVCMOS25";
NET "fmc1_fd_tdc_d_b[20]" LOC = "AE15";
NET "fmc1_fd_tdc_d_b[20]" IOSTANDARD = "LVCMOS25";
NET "fmc1_fd_tdc_d_b[22]" LOC = "Y16";
NET "fmc1_fd_tdc_d_b[22]" IOSTANDARD = "LVCMOS25";
NET "fmc1_fd_tdc_d_b[18]" LOC = "Y14";
NET "fmc1_fd_tdc_d_b[18]" IOSTANDARD = "LVCMOS25";
NET "fmc1_fd_tdc_d_b[16]" LOC = "W14";
NET "fmc1_fd_tdc_d_b[16]" IOSTANDARD = "LVCMOS25";
NET "fmc1_fd_tdc_d_b[10]" LOC = "AB12";
NET "fmc1_fd_tdc_d_b[10]" IOSTANDARD = "LVCMOS25";
NET "fmc1_fd_tdc_d_b[14]" LOC = "AD12";
NET "fmc1_fd_tdc_d_b[14]" IOSTANDARD = "LVCMOS25";
NET "fmc1_fd_tdc_d_b[8]" LOC = "AD10";
NET "fmc1_fd_tdc_d_b[8]" IOSTANDARD = "LVCMOS25";
NET "fmc1_fd_tdc_d_b[12]" LOC = "AE11";
NET "fmc1_fd_tdc_d_b[12]" IOSTANDARD = "LVCMOS25";
NET "fmc1_fd_tdc_d_b[3]" LOC = "AJ15";
NET "fmc1_fd_tdc_d_b[3]" IOSTANDARD = "LVCMOS25";
NET "fmc1_fd_tdc_d_b[5]" LOC = "AE13";
NET "fmc1_fd_tdc_d_b[5]" IOSTANDARD = "LVCMOS25";
NET "fmc1_fd_tdc_d_b[7]" LOC = "AC11";
NET "fmc1_fd_tdc_d_b[7]" IOSTANDARD = "LVCMOS25";
NET "fmc1_fd_tdc_d_b[2]" LOC = "AG8";
NET "fmc1_fd_tdc_d_b[2]" IOSTANDARD = "LVCMOS25";
NET "fmc1_fd_trig_a_i" LOC = "AJ17";
NET "fmc1_fd_trig_a_i" IOSTANDARD = "LVCMOS25";
NET "fmc1_fd_delay_val_o[2]" LOC = "AB19";
NET "fmc1_fd_delay_val_o[2]" IOSTANDARD = "LVCMOS25";
NET "fmc1_fd_delay_val_o[2]" SLEW = SLOW;
NET "fmc1_fd_delay_val_o[2]" DRIVE = 4;
NET "fmc1_fd_delay_val_o[0]" LOC = "Y19";
NET "fmc1_fd_delay_val_o[0]" IOSTANDARD = "LVCMOS25";
NET "fmc1_fd_delay_val_o[0]" SLEW = SLOW;
NET "fmc1_fd_delay_val_o[0]" DRIVE = 4;
NET "fmc1_fd_delay_val_o[6]" LOC = "AA21";
NET "fmc1_fd_delay_val_o[6]" IOSTANDARD = "LVCMOS25";
NET "fmc1_fd_delay_val_o[6]" SLEW = SLOW;
NET "fmc1_fd_delay_val_o[6]" DRIVE = 4;
NET "fmc1_fd_delay_val_o[4]" LOC = "Y20";
NET "fmc1_fd_delay_val_o[4]" IOSTANDARD = "LVCMOS25";
NET "fmc1_fd_delay_val_o[4]" SLEW = SLOW;
NET "fmc1_fd_delay_val_o[4]" DRIVE = 4;
NET "fmc1_fd_delay_val_o[8]" LOC = "AC22";
NET "fmc1_fd_delay_val_o[8]" IOSTANDARD = "LVCMOS25";
NET "fmc1_fd_delay_val_o[8]" SLEW = SLOW;
NET "fmc1_fd_delay_val_o[8]" DRIVE = 4;
NET "fmc1_fd_spi_miso_i" LOC = "AC20";
NET "fmc1_fd_spi_miso_i" IOSTANDARD = "LVCMOS25";
NET "fmc1_fd_spi_cs_pll_n_o" LOC = "AD19";
NET "fmc1_fd_spi_cs_pll_n_o" IOSTANDARD = "LVCMOS25";
NET "fmc1_fd_spi_cs_dac_n_o" LOC = "AG25";
NET "fmc1_fd_spi_cs_dac_n_o" IOSTANDARD = "LVCMOS25";
NET "fmc1_fd_tdc_stop_dis_o" LOC = "AF24";
NET "fmc1_fd_tdc_stop_dis_o" IOSTANDARD = "LVCMOS25";
NET "fmc1_fd_ext_rst_n_o" LOC = "AF19";
NET "fmc1_fd_ext_rst_n_o" IOSTANDARD = "LVCMOS25";
NET "fmc1_fd_pll_status_i" LOC = "AF23";
NET "fmc1_fd_pll_status_i" IOSTANDARD = "LVCMOS25";
NET "fmc1_fd_dmtd_fb_out_i" LOC = "AF21";
NET "fmc1_fd_dmtd_fb_out_i" IOSTANDARD = "LVCMOS25";
NET "fmc1_fd_tdc_rd_n_o" LOC = "AD16";
NET "fmc1_fd_tdc_rd_n_o" IOSTANDARD = "LVCMOS25";
NET "fmc1_fd_tdc_emptyf_i" LOC = "AC14";
NET "fmc1_fd_tdc_emptyf_i" IOSTANDARD = "LVCMOS25";
NET "fmc1_fd_onewire_b" LOC = "AA17";
NET "fmc1_fd_onewire_b" IOSTANDARD = "LVCMOS25";
NET "fmc1_fd_tdc_d_b[27]" LOC = "AA15";
NET "fmc1_fd_tdc_d_b[27]" IOSTANDARD = "LVCMOS25";
NET "fmc1_fd_tdc_d_b[25]" LOC = "AD15";
NET "fmc1_fd_tdc_d_b[25]" IOSTANDARD = "LVCMOS25";
NET "fmc1_fd_tdc_d_b[21]" LOC = "AF15";
NET "fmc1_fd_tdc_d_b[21]" IOSTANDARD = "LVCMOS25";
NET "fmc1_fd_tdc_d_b[23]" LOC = "AB16";
NET "fmc1_fd_tdc_d_b[23]" IOSTANDARD = "LVCMOS25";
NET "fmc1_fd_tdc_d_b[19]" LOC = "AA14";
NET "fmc1_fd_tdc_d_b[19]" IOSTANDARD = "LVCMOS25";
NET "fmc1_fd_tdc_d_b[17]" LOC = "Y13";
NET "fmc1_fd_tdc_d_b[17]" IOSTANDARD = "LVCMOS25";
NET "fmc1_fd_tdc_d_b[11]" LOC = "AC12";
NET "fmc1_fd_tdc_d_b[11]" IOSTANDARD = "LVCMOS25";
NET "fmc1_fd_tdc_d_b[15]" LOC = "AE12";
NET "fmc1_fd_tdc_d_b[15]" IOSTANDARD = "LVCMOS25";
NET "fmc1_fd_tdc_d_b[9]" LOC = "AE10";
NET "fmc1_fd_tdc_d_b[9]" IOSTANDARD = "LVCMOS25";
NET "fmc1_fd_tdc_d_b[13]" LOC = "AF11";
NET "fmc1_fd_tdc_d_b[13]" IOSTANDARD = "LVCMOS25";
NET "fmc1_fd_tdc_d_b[1]" LOC = "AK15";
NET "fmc1_fd_tdc_d_b[1]" IOSTANDARD = "LVCMOS25";
NET "fmc1_fd_tdc_d_b[4]" LOC = "AF13";
NET "fmc1_fd_tdc_d_b[4]" IOSTANDARD = "LVCMOS25";
NET "fmc1_fd_tdc_d_b[6]" LOC = "AD11";
NET "fmc1_fd_tdc_d_b[6]" IOSTANDARD = "LVCMOS25";
NET "fmc1_fd_tdc_d_b[0]" LOC = "AH8";
NET "fmc1_fd_tdc_d_b[0]" IOSTANDARD = "LVCMOS25";
NET "fmc1_fd_dmtd_fb_in_i" LOC = "AK17";
NET "fmc1_fd_dmtd_fb_in_i" IOSTANDARD = "LVCMOS25";
#===============================================================================
# Timing constraints and exceptions
#===============================================================================
# All input clocks
NET "clk_125m_pllref_n_i" TNM_NET = clk_125m_pllref_n_i;
TIMESPEC TS_clk_125m_pllref_n_i = PERIOD "clk_125m_pllref_n_i" 8 ns HIGH 50%;
NET "clk_125m_gtp_n_i" TNM_NET = clk_125m_gtp_n_i;
TIMESPEC TS_clk_125m_gtp_n_i = PERIOD "clk_125m_gtp_n_i" 8 ns HIGH 50%;
NET "clk_20m_vcxo_i" TNM_NET = "clk_20m_vcxo_i";
TIMESPEC TS_clk_20m_vcxo_i = PERIOD "clk_20m_vcxo_i" 50 ns HIGH 50%;
NET "fp_gpio3_i" TNM_NET = fp_gpio3_i;
TIMESPEC TS_fp_gpio3_i = PERIOD "fp_gpio3_i" 100 ns HIGH 50%;
NET "fmc0_tdc_125m_clk_n_i" TNM_NET = fmc0_tdc_125m_clk_n_i;
TIMESPEC TS_fmc0_tdc_125m_clk_n_i = PERIOD "fmc0_tdc_125m_clk_n_i" 8 ns HIGH 50%;
NET "fmc1_fd_clk_ref_n_i" TNM_NET = fmc1_fd_clk_ref_n_i;
TIMESPEC TS_fmc1_fd_clk_ref_n_i = PERIOD "fmc1_fd_clk_ref_n_i" 8 ns HIGH 50%;
# relax all paths through syncrhonisers:
# 1. define groups for each clock domain
# 2. define group for all sync chains
# 3. create sync chain groups that exclude one clock domain each
# 4. relax path from each clock domain to respective sync chain group
NET "clk_ref_125m" TNM_NET = clk_125m_pllref;
NET "clk_sys_62m5" TNM_NET = clk_sys;
NET "dcm1_clk_ref_0" TNM_NET = dcm1_clk_ref_0;
NET "tdc_clk_125m" TNM_NET = tdc_clk_125m;
NET "cmp_xwrc_board_svec/phy8_to_wrc_rx_clk" TNM_NET = phy_rx_rbclk;
NET "*/gc_sync_ffs_in" TNM_NET = "sync_ffs";
NET "*/gc_sync_register_in[*]" TNM_NET = "sync_reg";
TIMEGRP "synchronizers"="sync_ffs" "sync_reg";
TIMEGRP "ref_sync"="synchronizers" EXCEPT "clk_125m_pllref";
TIMEGRP "sys_sync"="synchronizers" EXCEPT "clk_sys";
TIMEGRP "fdl_sync"="synchronizers" EXCEPT "dcm1_clk_ref_0";
TIMEGRP "tdc_sync"="synchronizers" EXCEPT "tdc_clk_125m";
TIMEGRP "phy_sync"="synchronizers" EXCEPT "phy_rx_rbclk";
TIMESPEC TS_ref_sync_ffs = FROM clk_125m_pllref TO "ref_sync" 20ns DATAPATHONLY;
TIMESPEC TS_sys_sync_ffs = FROM clk_sys TO "sys_sync" 20ns DATAPATHONLY;
TIMESPEC TS_fdl_sync_ffs = FROM dcm1_clk_ref_0 TO "fdl_sync" 20ns DATAPATHONLY;
TIMESPEC TS_tdc_sync_ffs = FROM tdc_clk_125m TO "tdc_sync" 20ns DATAPATHONLY;
TIMESPEC TS_phy_sync_ffs = FROM phy_rx_rbclk TO "phy_sync" 20ns DATAPATHONLY;
# Relax the path where TAI time crosses from WR ref to MT sys clock
# This is already synced via a gc_pulse_synchronizer, which makes sure that
# TAI WR ref value is stable when sampled by the MT sys clock
NET "cmp_mock_turtle/gen_cpus[*].U_CPU_Block/tm_p_sys" TNM_NET = "tm_mt_sync";
TIMESPEC TS_tm_mt_sync = FROM clk_125m_pllref TO "tm_mt_sync" 20ns DATAPATHONLY;
# Relax timing from spll_aligner outputs cref and cin (driven by ref clock)
# to the spll registers (driven by sys clock). The two sides are already sychronized
# via a gc_pulse_synchronizer, which makes sure that cref and cin are stable
# when sampled by the sys clock.
NET "*/WRPC/U_SOFTPLL/U_Wrapped_Softpll/aligner_sample_cref(*)" TNM_NET = "wr_spll_sync";
NET "*/WRPC/U_SOFTPLL/U_Wrapped_Softpll/aligner_sample_cin(*)" TNM_NET = "wr_spll_sync";
TIMESPEC TS_wr_spll_sync = FROM clk_125m_pllref TO "wr_spll_sync" 20ns DATAPATHONLY;
# External async resets
NET "rst_n_i" TIG;
NET "vme_sysreset_n_i" TIG;
wrtd-53772dc3cd49421ea1fa6326a199b7a72dc04d18/hdl/testbench/ 0000775 0000000 0000000 00000000000 13460261316 0022136 5 ustar 00root root 0000000 0000000 wrtd-53772dc3cd49421ea1fa6326a199b7a72dc04d18/hdl/testbench/.gitignore 0000664 0000000 0000000 00000000021 13460261316 0024117 0 ustar 00root root 0000000 0000000 test_results.xml
wrtd-53772dc3cd49421ea1fa6326a199b7a72dc04d18/hdl/testbench/Makefile 0000664 0000000 0000000 00000011336 13460261316 0023602 0 ustar 00root root 0000000 0000000 # This Makefile can be called by the Continuous Integration (CI) tool to execute all
# testbenches added for CI
#
# Author: Adam Wujek, CERN 2017
TB_DIRS = wrtd_ref_svec_tdc_fd wrtd_ref_spec150t_adc
test_results_xml=test_results.xml
.PHONY: $(TB_DIRS)
all: $(TB_DIRS) summary summary_total summary_xml
FW_BRAM = ../../software/firmware/fd/wrtd-rt-fd.bram \
../../software/firmware/tdc/wrtd-rt-tdc.bram \
../../software/firmware/adc/wrtd-rt-adc.bram
wrtd-system: $(FW_BRAM)
$(FW_BRAM):
$(MAKE) -C $(@D) defconfig
$(MAKE) -C $(@D) $(notdir $@) EXTRA2_CFLAGS=-DSIMULATION
$(TB_DIRS):
@echo $@
@echo "Run HDL-MAKE"
cd "$@"; \
$(HDLMAKE_PATH)/hdl-make 2>&1
@echo "Run make"
$(MAKE) -C $@ $(TARGET) -j 1
@echo "Run vsim"
cd "$@" ;\
vsim -c -do "run_ci.do" -l transcript."$@".txt;\
echo "vsim returned $$?"
summary: $(TB_DIRS)
@echo "-------------------------------------------------------------------"
@echo "Summary:"
@for d in $(TB_DIRS); do \
if [ -f $$d/transcript."$$d".txt ]; then \
echo "Warnings for $$d:"; \
cat $$d/transcript."$$d".txt | grep Warning:; \
if [ $$? -eq 1 ]; then echo "None"; fi ;\
echo "Errors for $$d:"; \
cat $$d/transcript."$$d".txt | grep Error:; \
if [ $$? -eq 1 ]; then echo "None"; fi ;\
echo "Fatals for $$d:"; \
cat $$d/transcript."$$d".txt | grep Fatal:; \
if [ $$? -eq 1 ]; then echo "None"; fi ;\
else \
echo "No transcript file for $$d"; \
fi \
done
# Run tasks all before summary_total, because if there is a failure summary_total breaks the make execution
summary_total: summary summary_xml
@echo "-------------------------------------------------------------------"
@echo ""
@echo "Summary total:"
@echo "+---------------------------------------------------+----------+----------+----------+"
@echo "| Test bench | Warnings | Errors | Fatals |"
@echo "+---------------------------------------------------+----------+----------+----------+"
@is_error=0;\
for d in $(TB_DIRS); do \
if [ -f $$d/transcript."$$d".txt ]; then \
printf "| %-50s" $$d; \
printf "| %8d " `cat $$d/transcript."$$d".txt | grep Warning: | wc -l`; \
error_n=`cat $$d/transcript."$$d".txt | grep Error: | wc -l`; \
printf "| %8d " $$error_n;\
if [ $$error_n -gt 0 ]; then is_error=1; fi ;\
fatal_n=`cat $$d/transcript."$$d".txt | grep Fatal: | wc -l`; \
printf "| %8d |\n" $$fatal_n;\
if [ $$fatal_n -gt 0 ]; then is_error=1; fi ;\
else \
printf "| %-30s" $$d; \
echo "| No transcript file! |"; is_error=1; \
fi \
done ;\
echo "+---------------------------------------------------+----------+----------+----------+";\
if [ $$is_error -gt 0 ]; then exit 1; fi ;
summary_xml: summary
@echo '' > $(test_results_xml)
@echo '' >> $(test_results_xml)
@for d in $(TB_DIRS); do \
is_test_error=0;\
error_n=0;\
fatal_n=0;\
echo -n " > $(test_results_xml) ;\
if [ -f $$d/transcript."$$d".txt ]; then \
error_n=`cat $$d/transcript."$$d".txt | grep Error: | wc -l`; \
fatal_n=`cat $$d/transcript."$$d".txt | grep Fatal: | wc -l`; \
if [ $$error_n -gt 0 ] || [ $$fatal_n -gt 0 ]; then is_test_error=1; fi ;\
echo -n $$is_test_error >> $(test_results_xml);\
else \
is_test_error=2; \
echo -n "1" >> $(test_results_xml); \
fi; \
echo "\" disabled=\"0\" errors=\"0\" time=\"0\">" >> $(test_results_xml) ;\
echo " " >> $(test_results_xml) ;\
if [ $$is_test_error -eq 1 ]; then \
if [ $$error_n -gt 0 ]; then \
echo " > $(test_results_xml) ;\
cat $$d/transcript."$$d".txt | grep Error: >> $(test_results_xml);\
echo " ]]>" >> $(test_results_xml) ;\
fi;\
if [ $$fatal_n -gt 0 ]; then \
echo " > $(test_results_xml) ;\
cat $$d/transcript."$$d".txt | grep Fatal: >> $(test_results_xml);\
echo " ]]>" >> $(test_results_xml) ;\
fi;\
fi ;\
if [ $$is_test_error -eq 2 ]; then \
echo " " >> $(test_results_xml) ;\
echo "" >> $(test_results_xml) ;\
echo " " >> $(test_results_xml) ;\
fi ;\
echo " " >> $(test_results_xml) ;\
echo " " >> $(test_results_xml) ;\
done ;\
echo "" >> $(test_results_xml)
clean:
@for d in $(TB_DIRS); do \
if [ -f $$d/Makefile ]; then \
$(MAKE) -C $$d $@; \
rm -f $$d/Makefile; \
fi \
done
wrtd-53772dc3cd49421ea1fa6326a199b7a72dc04d18/hdl/testbench/include/ 0000775 0000000 0000000 00000000000 13460261316 0023561 5 ustar 00root root 0000000 0000000 wrtd-53772dc3cd49421ea1fa6326a199b7a72dc04d18/hdl/testbench/include/wrtd_alarm.svh 0000664 0000000 0000000 00000005507 13460261316 0026446 0 ustar 00root root 0000000 0000000 //------------------------------------------------------------------------------
// CERN BE-CO-HT
// White Rabbit Trigger Distribution (WRTD)
// https://ohwr.org/projects/wrtd
//------------------------------------------------------------------------------
//
// unit name: WrtdAlarm
//
// description: A SystemVerilog Class for a WRTD "alarm" repeated capability
//
//------------------------------------------------------------------------------
// Copyright CERN 2019
//------------------------------------------------------------------------------
// Copyright and related rights are licensed under the Solderpad Hardware
// License, Version 2.0 (the "License"); you may not use this file except
// in compliance with the License. You may obtain a copy of the License at
// http://solderpad.org/licenses/SHL-2.0.
// Unless required by applicable law or agreed to in writing, software,
// hardware and materials distributed under this License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
// or implied. See the License for the specific language governing permissions
// and limitations under the License.
//------------------------------------------------------------------------------
`ifndef __WRTD_ALARM_INCLUDED
`define __WRTD_ALARM_INCLUDED
`include "wrtd_rep_cap.svh"
class WrtdAlarm extends WrtdRepCap;
protected WrtdTstamp setup_time;
protected wrtd_event ev;
protected int repeat_count;
protected uint32_t period_ns;
function new ( int core, int index, string name = "" );
super.new ( core, index, name );
this.setup_time = new();
this.ev.ts = new();
this.ev.id = new();
clear();
endfunction // new
function void clear ( );
super.clear();
this.setup_time.zero();
this.ev.ts.zero();
this.ev.id.clear();
this.ev.seq = 0;
this.ev.flags = 0;
this.repeat_count = 0;
this.period_ns = 0;
endfunction // clear
function wrtd_data data_pack ( );
wrtd_data ret = new[`WRTD_ALRM_WORD_SIZE];
ret[0:2] = this.setup_time.data_pack();
ret[3:5] = this.ev.ts.data_pack();
ret[6:9] = this.ev.id.data_pack();
ret[10] = this.ev.seq;
ret[11] = this.ev.flags;
ret[12] = this.enabled;
ret[13] = this.repeat_count;
ret[14] = this.period_ns;
return ret;
endfunction // data_pack
function void data_unpack ( wrtd_data data );
this.setup_time.data_unpack ( data[0:2] );
this.ev.ts.data_unpack ( data[3:5] );
this.ev.id.data_unpack ( data[6:9] );
this.ev.seq = data[10];
this.ev.flags = data[11];
this.enabled = data[12];
this.repeat_count = data[13];
this.period_ns = data[14];
endfunction // data_unpack
endclass //WrtdAlarm
`endif // `ifndef __WRTD_ALARM_INCLUDED
wrtd-53772dc3cd49421ea1fa6326a199b7a72dc04d18/hdl/testbench/include/wrtd_definitions.svh 0000664 0000000 0000000 00000014512 13460261316 0027661 0 ustar 00root root 0000000 0000000 //------------------------------------------------------------------------------
// CERN BE-CO-HT
// White Rabbit Trigger Distribution (WRTD)
// https://ohwr.org/projects/wrtd
//------------------------------------------------------------------------------
//
// unit name: WrtdTstamp
//
// description: A collection of definitions and types used by the WrtdDev class.
//
// These are mostly copy-pasted from the WRTD library.
//
//------------------------------------------------------------------------------
// Copyright CERN 2019
//------------------------------------------------------------------------------
// Copyright and related rights are licensed under the Solderpad Hardware
// License, Version 2.0 (the "License"); you may not use this file except
// in compliance with the License. You may obtain a copy of the License at
// http://solderpad.org/licenses/SHL-2.0.
// Unless required by applicable law or agreed to in writing, software,
// hardware and materials distributed under this License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
// or implied. See the License for the specific language governing permissions
// and limitations under the License.
//------------------------------------------------------------------------------
`ifndef __WRTD_DEFINE_INCLUDED
`define __WRTD_DEFINE_INCLUDED
`include "simdrv_defs.svh"
`define WRTD_MAX_CPUS 4
`define WRTD_MAX_DEVS 4
`define WRTD_ID_LEN 16
`define WRTD_IO_MSG_WORD_SIZE 2
`define WRTD_CFG_MSG_WORD_SIZE 5
`define WRTD_ROOT_WORD_SIZE 13
`define WRTD_RULE_WORD_SIZE 40
`define WRTD_ALRM_WORD_SIZE 15
`define WRTD_DEST_CPU_LOCAL 'hfe
`define WRTD_DEST_CH_NET 'hff
enum {
WRTD_ACTION_GET_CONFIG,
WRTD_ACTION_READW,
WRTD_ACTION_WRITEW
} wrtd_trtl_actions;
`define WRTD_ACTION_LOG 'h20
typedef enum uint32_t {
WRTD_LOG_MSG_EV_GENERATED = 0,
WRTD_LOG_MSG_EV_CONSUMED,
WRTD_LOG_MSG_EV_DISCARDED,
WRTD_LOG_MSG_EV_NETWORK,
WRTD_LOG_MSG_LINK
} wrtd_log_msg_type;
typedef enum uint32_t {
WRTD_LOG_GENERATED_ALARM = 1,
WRTD_LOG_GENERATED_DEVICE_0 = 8,
WRTD_LOG_GENERATED_DEVICE_1 = 16,
WRTD_LOG_GENERATED_DEVICE_2 = 24,
WRTD_LOG_GENERATED_DEVICE_3 = 32,
WRTD_LOG_GENERATED_DEVICE_4 = 40,
WRTD_LOG_GENERATED_DEVICE_5 = 48,
WRTD_LOG_GENERATED_DEVICE_6 = 56,
WRTD_LOG_GENERATED_DEVICE_7 = 64
} wrtd_log_gen_reason;
typedef enum uint32_t {
WRTD_LOG_CONSUMED_START = 1,
WRTD_LOG_CONSUMED_DONE
} wrtd_log_con_reason;
typedef enum uint32_t {
WRTD_LOG_DISCARD_NO_SYNC = 1,
WRTD_LOG_DISCARD_TIMEOUT,
WRTD_LOG_DISCARD_OVERFLOW
} wrtd_log_dsc_reason;
typedef enum uint32_t {
WRTD_LOG_NETWORK_TX = 1,
WRTD_LOG_NETWORK_RX
} wrtd_log_net_reason;
enum {
WRTD_DIR_INPUT,
WRTD_DIR_OUTPUT
} wrtd_dir;
typedef uint32_t wrtd_data[];
function int wrtd_gen_hash ( string s );
return ( s[0] ^ s[3] ^ s[4] ^ s[7] );
endfunction // wrtd_gen_hash
class WrtdTstamp;
protected string name;
protected uint32_t seconds;
protected uint32_t ns;
protected uint32_t frac;
function new ( uint32_t seconds = 0,
uint32_t ns = 0,
uint32_t frac = 0 );
set ( seconds, ns, frac );
endfunction // new
function void set ( uint32_t seconds, uint32_t ns, uint32_t frac );
this.seconds = seconds;
this.ns = ns;
this.frac = frac;
endfunction // set
function uint32_t get_sec ( );
return this.seconds;
endfunction // get_sec
function uint32_t get_ns ( );
return this.ns;
endfunction // get_ns
function uint32_t get_frac ( );
return this.frac;
endfunction // get_frac
function wrtd_data data_pack ( );
wrtd_data ret=new[3];
ret[0] = this.seconds;
ret[1] = this.ns;
ret[2] = this.frac;
return ret;
endfunction // data_pack
function void data_unpack ( wrtd_data data);
this.seconds = data[0];
this.ns = data[1];
this.frac = data[2];
endfunction // data_unpack
function void zero ( );
set ( 0, 0, 0 );
endfunction // zero
function string tostring ( );
return $sformatf ( "%0d:%0d.%0d", this.seconds, this.ns, this.frac );
endfunction; // tostring
endclass // WrtdTstamp
class WrtdId;
protected string id;
function new ();
clear();
endfunction // new
function void clear ();
id = "";
endfunction // clear
function void set ( string id );
if ( id.len() > `WRTD_ID_LEN )
$error ( "length of string longer than the available storage" );
else
begin
this.clear();
this.id = id;
end
endfunction // set
function string get ( );
return this.id;
endfunction // get
function wrtd_data data_pack ( );
int i;
wrtd_data d;
d = new[`WRTD_ID_LEN / 4];
for ( i = 0; i < `WRTD_ID_LEN / 4; i ++ )
d[i] = 0;
for ( i = 0; i < this.id.len(); i ++ )
d[i/4] |= this.id[i] << ( 8 * ( i % 4 ) );
return d;
endfunction // data_pack
function void data_unpack ( wrtd_data data );
if ( data.size() > `WRTD_ID_LEN / 4 )
$error ( "length of data longer than the available storage" );
else
this.id = { <<32 { { <<8 { data } } } };
endfunction // data_unpack
function int is_empty ( );
return ( this.id.len() == 0 );
endfunction // is_empty
endclass // WrtdId
typedef struct {
WrtdTstamp ts;
WrtdId id;
uint32_t seq;
byte unsigned flags;
} wrtd_event;
typedef struct {
uint32_t addr;
uint32_t nbr_alarms;
uint32_t alarms_addr;
uint32_t nbr_rules;
uint32_t rules_addr;
uint32_t nbr_devs;
uint32_t devs_addr[4];
} wrtd_root;
typedef struct {
int core;
int index;
int ch_en;
} wrtd_dev;
typedef struct {
string name;
uint32_t dir;
uint32_t nbr_chs;
string channels[];
/* -----\/----- EXCLUDED -----\/-----
enum wrtd_status (*configure)(struct wrtd_dev *wrtd,
unsigned cpu, unsigned dev,
unsigned int mask);
-----/\----- EXCLUDED -----/\----- */
} wrtd_mt_device;
typedef struct {
uint32_t fw_id;
uint32_t nbr_devices;
wrtd_mt_device devices[`WRTD_MAX_DEVS];
} wrtd_mt_cpu_config;
typedef struct {
uint32_t mt_app_id;
uint32_t nbr_cpus;
uint32_t tx_cpu;
uint32_t rx_cpu;
wrtd_mt_cpu_config cpus[`WRTD_MAX_CPUS];
} wrtd_mt_config;
`endif // `ifndef __WRTD_DEFINE_INCLUDED
wrtd-53772dc3cd49421ea1fa6326a199b7a72dc04d18/hdl/testbench/include/wrtd_driver.svh 0000664 0000000 0000000 00000035220 13460261316 0026640 0 ustar 00root root 0000000 0000000 //------------------------------------------------------------------------------
// CERN BE-CO-HT
// White Rabbit Trigger Distribution (WRTD)
// https://ohwr.org/projects/wrtd
//------------------------------------------------------------------------------
//
// unit name: WrtdDrv
//
// description: A SystemVerilog Class to provide an abstraction of a complete
// WRTD device.
//
//------------------------------------------------------------------------------
// Copyright CERN 2019
//------------------------------------------------------------------------------
// Copyright and related rights are licensed under the Solderpad Hardware
// License, Version 2.0 (the "License"); you may not use this file except
// in compliance with the License. You may obtain a copy of the License at
// http://solderpad.org/licenses/SHL-2.0.
// Unless required by applicable law or agreed to in writing, software,
// hardware and materials distributed under this License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
// or implied. See the License for the specific language governing permissions
// and limitations under the License.
//------------------------------------------------------------------------------
`ifndef __WRTD_DRV_INCLUDED
`define __WRTD_DRV_INCLUDED
`include "wrtd_definitions.svh"
`include "wrtd_rule.svh"
`include "wrtd_alarm.svh"
`include "mock_turtle_driver.svh"
class WrtdDrv;
uint32_t ready;
protected string name;
protected byte unsigned enable_logging;
protected MockTurtleDriver mt;
protected uint32_t nbr_cpus;
protected uint32_t free_rule_slots[];
protected uint32_t hmq_words[];
protected wrtd_mt_config cfg;
protected wrtd_root roots[];
protected wrtd_dev devices[$];
protected WrtdRepCapCollection rules;
protected WrtdRepCapCollection alarms;
function new ( CBusAccessor acc, uint64_t base,
vIMockTurtleIRQ irq, string name = "",
byte unsigned enable_logging = 1 );
this.name = name;
this.mt = new (acc, base, irq, name);
this.enable_logging = enable_logging;
endfunction // new
task mdisplay ( string str );
string tmp;
if (this.name == "")
tmp = $sformatf("<%t> %s", $realtime, str);
else
tmp = $sformatf("[%s] <%t> %s", this.name, $realtime, str);
$display (tmp);
endtask // mdisplay
task init ( );
int i, j;
uint32_t val, cpu_ready;
WrtdRule new_rule;
WrtdAlarm new_alarm;
wrtd_dev new_dev;
uint32_t data[];
this.ready = 0;
mt.init ( );
// TODO: replace with non-hardcoded values
this.cfg.mt_app_id = 'h115790d1;
this.cfg.nbr_cpus = 1;
this.cfg.tx_cpu = 0;
this.cfg.rx_cpu = 0;
this.cfg.cpus[0].fw_id = 'h35b0;
this.cfg.cpus[0].nbr_devices = 2;
this.cfg.cpus[0].devices[0].name = "FMC ADCin 5CH";
this.cfg.cpus[0].devices[0].dir = WRTD_DIR_INPUT;
this.cfg.cpus[0].devices[0].nbr_chs = 5;
this.cfg.cpus[0].devices[0].channels = new[5];
this.cfg.cpus[0].devices[0].channels[0] = "ADCI1";
this.cfg.cpus[0].devices[0].channels[1] = "ADCI2";
this.cfg.cpus[0].devices[0].channels[2] = "ADCI3";
this.cfg.cpus[0].devices[0].channels[3] = "ADCI4";
this.cfg.cpus[0].devices[0].channels[4] = "ADCI5";
this.cfg.cpus[0].devices[1].name = "FMC ADCout";
this.cfg.cpus[0].devices[1].dir = WRTD_DIR_OUTPUT;
this.cfg.cpus[0].devices[1].nbr_chs = 1;
this.cfg.cpus[0].devices[1].channels = new[1];
this.cfg.cpus[0].devices[1].channels[0] = "ADCO1";
this.nbr_cpus = mt.rom.getCoreCount ( );
this.free_rule_slots = new[this.nbr_cpus];
this.hmq_words = new[this.nbr_cpus];
this.roots = new[this.nbr_cpus];
for ( i = 0; i < this.nbr_cpus; i++ )
begin
this.hmq_words[i] =
`TRTL_CONFIG_ROM_MQ_SIZE_PAYLOAD( mt.rom.getHmqDimensions( i, 0 ) );
mt.enable_hmqi_irq ( i, 0, 1 );
mt.enable_console_irq ( i, 1 );
mt.reset_core ( i, 0 );
end
fork
begin
for ( i = 0; i < this.nbr_cpus; i++ )
begin
// wait for ready notification from firmware
cpu_ready = 0;
while ( cpu_ready == 0 )
begin
val = 0;
mt.get_single_cpu_notification ( 0, val );
if ( val == TRTL_CPU_NOTIFY_MAIN )
cpu_ready = 1;
# 1us;
end
// retrieve address of root
msg_get_config ( i, data );
this.roots[i].addr = data[0];
// retrieve root
msg_readw ( i, this.roots[i].addr, `WRTD_ROOT_WORD_SIZE, data );
this.roots[i].nbr_rules = ( data[1] & 'h00ff0000 ) >> 16;
this.roots[i].nbr_alarms = ( data[1] & 'h0000ff00 ) >> 8;
this.roots[i].nbr_devs = ( data[1] & 'h000000ff ) >> 0;
this.roots[i].devs_addr[0:3] = data[4:7];
this.roots[i].rules_addr = data[8];
this.roots[i].alarms_addr = data[9];
// init free rule slots
this.free_rule_slots[i] = this.roots[i].nbr_rules;
// turn on all logging if enabled
if ( this.enable_logging )
msg_writew ( i, this.roots[i].addr + 12, 1, { data[3] | 32'hff } );
end
// initialise rules
this.rules = new ( this.name );
for ( i = 0; i < this.nbr_cpus; i++ )
for ( j = 0; j < this.roots[i].nbr_rules; j++ )
begin
new_rule = new ( i, j, this.name );
this.rules.collection.push_back ( new_rule );
end
// initialise alarms
this.alarms = new ( this.name );
for ( i = 0; i < this.nbr_cpus; i++ )
for ( j = 0; j < this.roots[i].nbr_alarms; j++ )
begin
new_alarm = new ( i, j, this.name );
this.alarms.collection.push_back ( new_alarm );
end
// initialise devices
this.devices.delete();
for ( i = 0; i < this.nbr_cpus; i++ )
for ( j = 0; j < this.roots[i].nbr_devs; j++ )
begin
new_dev.core = i;
new_dev.index = j;
new_dev.ch_en = 0;
this.devices.push_back ( new_dev );
end
// TODO remove hard-coded ADC init
adc_init ();
this.ready = 1;
end
begin
while ( this.ready == 0 )
begin
mt.update ( );
# 1us;
end
end
join
endtask // init
task msg_get_config ( int core, ref uint32_t data[] );
int i;
MQueueMsg msg;
if ( data.size() < `WRTD_CFG_MSG_WORD_SIZE )
data = new[`WRTD_CFG_MSG_WORD_SIZE];
msg = new ( core, 0 );
msg.header.flags = `TRTL_HMQ_HEADER_FLAG_RPC | `TRTL_HMQ_HEADER_FLAG_SYNC;
msg.header.msg_id = WRTD_ACTION_GET_CONFIG;
msg.header.len = 0;
mt.hmq_send_message ( msg );
while ( mt.hmq_pending_messages ( msg.core, 0 ) == 0 ) #1us;
mt.hmq_receive_message ( msg );
if ( msg.header.len != `WRTD_CFG_MSG_WORD_SIZE )
begin
$error ( "get_config: unexpected message header length" );
mdisplay ( $sformatf ( "message received: %s", msg.tostring() ) );
end
for ( i = 0; i < `WRTD_CFG_MSG_WORD_SIZE; i++ )
data[i] = msg.data[i];
endtask // msg_get_config
task msg_readw ( int core, uint32_t addr,
uint32_t count, ref uint32_t data[] );
int i;
MQueueMsg msg;
uint32_t tlen, offset;
if ( data.size() < count )
data = new[count];
offset = 0;
while ( offset < count )
begin
tlen = this.hmq_words[core] - `WRTD_IO_MSG_WORD_SIZE;
if ( tlen > count - offset )
tlen = count - offset;
msg = new ( core, 0 );
msg.header.flags = `TRTL_HMQ_HEADER_FLAG_RPC | `TRTL_HMQ_HEADER_FLAG_SYNC;
msg.header.msg_id = WRTD_ACTION_READW;
msg.header.len = `WRTD_IO_MSG_WORD_SIZE;
msg.data = '{ addr + offset, tlen };
mt.hmq_send_message ( msg );
while ( mt.hmq_pending_messages ( msg.core, 0 ) == 0 ) #1us;
mt.hmq_receive_message ( msg );
if ( msg.header.len != tlen )
begin
$error ( "readw: unexpected message header length" );
mdisplay ( $sformatf ( "message received: %s", msg.tostring() ) );
end
for ( i = 0; i < tlen; i++ )
data[offset+i] = msg.data[i];
offset += tlen;
end
endtask // msg_readw
task msg_writew ( int core, uint32_t addr,
uint32_t count, uint32_t data[] );
int i;
MQueueMsg msg;
uint32_t tlen, offset;
offset = 0;
while ( offset < count )
begin
tlen = this.hmq_words[core] - `WRTD_IO_MSG_WORD_SIZE;
if ( tlen > count - offset )
tlen = count - offset;
msg = new ( core, 0 );
msg.header.flags = `TRTL_HMQ_HEADER_FLAG_RPC | `TRTL_HMQ_HEADER_FLAG_SYNC;
msg.header.msg_id = WRTD_ACTION_WRITEW;
msg.header.len = `WRTD_IO_MSG_WORD_SIZE + count;
msg.data = '{ addr + offset, tlen };
for ( i = 0; i < tlen; i++ )
msg.data[i+2] = data[offset+i];
mt.hmq_send_message ( msg );
while ( mt.hmq_pending_messages ( msg.core, 0 ) == 0 ) #1us;
mt.hmq_receive_message ( msg );
offset += tlen;
end
endtask // msg_writew
task adc_init ( );
uint32_t addr;
uint32_t data[1];
addr = this.roots[0].devs_addr[0] + 'h4;
data[0] = 'h10f;
msg_writew ( 0, addr, 1, data );
endtask // adc_init
task add_rule ( string rep_cap_id );
int idx;
idx = this.rules.add ( rep_cap_id );
endtask // add_rule
function int find_rule ( string rep_cap_id );
return this.rules.find ( rep_cap_id );
endfunction // find_rule
task remove_rule ( string rep_cap_id );
int idx;
idx = this.rules.remove ( rep_cap_id );
write_rule ( idx );
endtask // remove_rule
task set_rule ( string rep_cap_id,
string src, string dst,
uint32_t delay_ns );
int idx;
WrtdRule rule;
idx = this.rules.find ( rep_cap_id );
if ( idx == -1 )
$error ( "%s repeated capability ID cannot be set because it does not exist", rep_cap_id );
if ( this.rules.collection[idx].is_enabled ( ) )
$error ( "%s repeated capability ID cannot be set because it is enabled", rep_cap_id );
$cast ( rule, this.rules.collection[idx] );
rule.set_src ( src );
rule.set_dst ( dst );
rule.set_delay_ns ( delay_ns );
endtask // set_rule
task write_rule ( int idx );
int core, hash;
uint32_t addr;
uint32_t data[];
WrtdRule rule;
if ( idx < 0 )
$error ( "cannot write rule with negative index" );
$cast ( rule, this.rules.collection[idx] );
hash = wrtd_gen_hash ( rule.get_src() ) % this.rules.collection.size();
core = rule.get_core ( );
addr = this.roots[core].rules_addr + hash * `WRTD_RULE_WORD_SIZE * 4;
data = rule.data_pack ( );
msg_writew ( core, addr, `WRTD_RULE_WORD_SIZE, data );
endtask // write_rule
task enable_rule ( string rep_cap_id );
int idx;
string id;
uint32_t src_cpu;
WrtdRule rule;
idx = this.rules.find ( rep_cap_id );
if ( idx == -1 )
$error ( "%s repeated capability ID cannot be enabled because it does not exist", rep_cap_id );
$cast ( rule, this.rules.collection[idx] );
rule.set_enable ( );
// TODO, replace hard-coding
src_cpu = 0;
if ( this.free_rule_slots[src_cpu] == 0 )
$error ( "no more available free rule slots on CPU %d", src_cpu );
this.free_rule_slots[src_cpu] -= 1;
rule.set_dest_cpu ( `WRTD_DEST_CPU_LOCAL );
id = rule.get_dst ( );
if ( id == "ADCO1" )
rule.set_dest_ch ( 0 );
else
rule.set_dest_ch ( `WRTD_DEST_CH_NET );
write_rule ( idx );
endtask // enable_rule
task add_alarm ( string rep_cap_id );
int idx;
idx = this.alarms.add ( rep_cap_id );
write_alarm ( idx );
endtask // add_alarm
function int find_alarm ( string rep_cap_id );
return this.alarms.find ( rep_cap_id );
endfunction // find_alarm
task remove_alarm ( string rep_cap_id );
int idx;
idx = this.alarms.remove ( rep_cap_id );
write_alarm ( idx );
endtask // remove_alarm
task write_alarm ( int idx );
int core, index;
uint32_t addr;
uint32_t data[];
if ( idx < 0 )
$error ( "cannot write alarm with negative index" );
core = this.alarms.collection[idx].get_core ( );
index = this.alarms.collection[idx].get_index ();
addr = this.roots[core].alarms_addr + index * `WRTD_ALRM_WORD_SIZE * 4;
data = this.alarms.collection[idx].data_pack( );
msg_writew ( core, addr, `WRTD_ALRM_WORD_SIZE, data );
endtask // write_alarm
function string log_msg_tostring ( MQueueMsg msg );
string ret;
wrtd_log_msg_type msg_type;
wrtd_log_gen_reason gen_reason;
wrtd_log_con_reason con_reason;
wrtd_log_dsc_reason dsc_reason;
wrtd_log_net_reason net_reason;
WrtdTstamp ev_tstamp, msg_tstamp;
WrtdId ev_id;
ret = "";
if ( msg.header.msg_id != `WRTD_ACTION_LOG )
begin
$error ( "log_msg_tostring: unknown message id %.8x", msg.header.msg_id );
return ret;
end
msg_tstamp = new ();
msg_tstamp.data_unpack ( msg.data[11:13] );
ret = { ret, $sformatf ( "log timestamp: %s", msg_tstamp.tostring() ) };
ev_tstamp = new ();
ev_tstamp.data_unpack ( msg.data[2:4] );
ret = { ret, $sformatf ( ", event timestamp: %s", ev_tstamp.tostring() ) };
ev_id = new ();
ev_id.data_unpack ( msg.data[5:8] );
ret = { ret, $sformatf ( ", id: %s, seq: %0d", ev_id.get(), msg.data[9] ) };
$cast ( msg_type, msg.data[0] );
ret = { ret, $sformatf ( ", log type: %s", msg_type.name() ) };
case ( msg_type )
WRTD_LOG_MSG_EV_GENERATED :
begin
$cast ( gen_reason, msg.data[1] );
ret = { ret, $sformatf ( ", reason: %s", gen_reason.name() ) };
end
WRTD_LOG_MSG_EV_CONSUMED :
begin
$cast ( con_reason, msg.data[1] );
ret = { ret, $sformatf ( ", reason: %s", con_reason.name() ) };
end
WRTD_LOG_MSG_EV_DISCARDED :
begin
$cast ( dsc_reason, msg.data[1] );
ret = { ret, $sformatf ( ", reason: %s", dsc_reason.name() ) };
end
WRTD_LOG_MSG_EV_NETWORK :
begin
$cast ( net_reason, msg.data[1] );
ret = { ret, $sformatf ( ", reason: %s", net_reason.name() ) };
end
endcase; // case ( msg_type )
return ret;
endfunction // log_msg_tostring
task check_logs ( );
int i;
MQueueMsg msg;
for (int i = 0; i < this.nbr_cpus; i++)
begin
while ( mt.hmq_pending_messages ( i, 0 ) )
begin
msg = new ( i, 0 );
mt.hmq_peek_message ( msg );
if ( msg.header.msg_id != `WRTD_ACTION_LOG ) break;
mt.hmq_receive_message ( msg );
mdisplay ( $sformatf ( "LOG MSG from core %0d: %s", i, log_msg_tostring ( msg ) ) );
end
end
endtask // check_logs
task update ( );
mt.update ( );
if ( this.enable_logging )
check_logs ( );
endtask // update
endclass // WrtdDrv
`endif // `ifndef __WRTD_DRV_INCLUDED
wrtd-53772dc3cd49421ea1fa6326a199b7a72dc04d18/hdl/testbench/include/wrtd_rep_cap.svh 0000664 0000000 0000000 00000012167 13460261316 0026763 0 ustar 00root root 0000000 0000000 //------------------------------------------------------------------------------
// CERN BE-CO-HT
// White Rabbit Trigger Distribution (WRTD)
// https://ohwr.org/projects/wrtd
//------------------------------------------------------------------------------
//
// unit name: WrtdRepCap, WrtdRepCapCollection
//
// description: A SystemVerilog Class for a WRTD "repeated capability"
//
//------------------------------------------------------------------------------
// Copyright CERN 2019
//------------------------------------------------------------------------------
// Copyright and related rights are licensed under the Solderpad Hardware
// License, Version 2.0 (the "License"); you may not use this file except
// in compliance with the License. You may obtain a copy of the License at
// http://solderpad.org/licenses/SHL-2.0.
// Unless required by applicable law or agreed to in writing, software,
// hardware and materials distributed under this License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
// or implied. See the License for the specific language governing permissions
// and limitations under the License.
//------------------------------------------------------------------------------
`ifndef __WRTD_REPCAP_INCLUDED
`define __WRTD_REPCAP_INCLUDED
`include "wrtd_definitions.svh"
virtual class WrtdRepCap;
protected string name;
protected WrtdId rep_cap_id;
protected int core;
protected int index;
protected int enabled;
function new ( int core, int index, string name = "" );
this.core = core;
this.index = index;
this.name = name;
this.rep_cap_id = new();
clear();
endfunction // new
function void clear ( );
this.rep_cap_id.clear();
this.enabled = 0;
endfunction // clear
task mdisplay ( string str );
string tmp;
if (this.name == "")
tmp = $sformatf("<%t> %s", $realtime, str);
else
tmp = $sformatf("[%s] <%t> %s", this.name, $realtime, str);
$display (tmp);
endtask // mdisplay
function int get_core ( );
return this.core;
endfunction // get_core
function int get_index ( );
return this.index;
endfunction // get_index
function string get_rep_cap_id ( );
return this.rep_cap_id.get();
endfunction // get_rep_cap_id
function void set_rep_cap_id ( string id );
this.rep_cap_id.set( id );
endfunction // set_rep_cap_id
function int match ( string id );
return ( get_rep_cap_id().compare ( id ) == 0 );
endfunction // is_equal
function int is_free ( );
return this.rep_cap_id.is_empty();
endfunction // is_free
function int is_enabled ( );
return ( this.enabled > 0 );
endfunction // is_enabled
function void set_enable ( );
this.enabled = 1;
endfunction // set_enable
function void set_disable ( );
this.enabled = 0;
endfunction // set_disable
pure virtual function wrtd_data data_pack ( );
pure virtual function void data_unpack ( wrtd_data data );
endclass //WrtdRepCap
class WrtdRepCapCollection;
protected string name;
WrtdRepCap collection[$];
function new ( string name );
this.name = name;
this.collection.delete();
endfunction // new
task mdisplay ( string str );
string tmp;
if (this.name == "")
tmp = $sformatf("<%t> %s", $realtime, str);
else
tmp = $sformatf("[%s] <%t> %s", this.name, $realtime, str);
$display (tmp);
endtask // mdisplay
function void validate_id ( string rep_cap_id );
if ( rep_cap_id.len() > `WRTD_ID_LEN )
$error ( "repeated capability name '%s' is too long", rep_cap_id );
if ( rep_cap_id.len() == 0 )
$error ( "repeated capability name is null" );
endfunction // validate_id
function int add ( string rep_cap_id );
int i, idx;
validate_id ( rep_cap_id );
idx = -1;
for ( i = 0; i < this.collection.size(); i++ )
begin
if ( this.collection[i].match ( rep_cap_id ) )
begin
$error ( "'%s' repeated capability ID already exists", rep_cap_id );
return -1;
end
if ( idx == -1 && this.collection[i].is_free() )
idx = i;
end
if ( idx == -1 )
$error ( "cannot add '%s' repeated capability, no space available", rep_cap_id );
else
this.collection[idx].set_rep_cap_id ( rep_cap_id );
return idx;
endfunction // add
function int find ( string rep_cap_id );
int i;
validate_id ( rep_cap_id );
for ( i = 0; i < this.collection.size(); i++ )
if ( this.collection[i].match ( rep_cap_id ) )
return i;
return -1;
endfunction // find
function int remove ( string rep_cap_id );
int idx;
idx = find ( rep_cap_id );
if ( idx == -1 )
begin
$error ( "%s repeated capability ID cannot be removed because it does not exist", rep_cap_id );
return idx;
end
if ( this.collection[idx].is_enabled ( ) )
$error ( "%s repeated capability ID cannot be removed because it is enabled", rep_cap_id );
else
this.collection[idx].clear();
return idx;
endfunction // remove
endclass // WrtdRepCapCollection
`endif // `ifndef __WRTD_REPCAP_INCLUDED
wrtd-53772dc3cd49421ea1fa6326a199b7a72dc04d18/hdl/testbench/include/wrtd_rule.svh 0000664 0000000 0000000 00000014215 13460261316 0026315 0 ustar 00root root 0000000 0000000 //------------------------------------------------------------------------------
// CERN BE-CO-HT
// White Rabbit Trigger Distribution (WRTD)
// https://ohwr.org/projects/wrtd
//------------------------------------------------------------------------------
//
// unit name: WrtdRule
//
// description: A SystemVerilog Class for a WRTD "rule" repeated capability
//
//------------------------------------------------------------------------------
// Copyright CERN 2019
//------------------------------------------------------------------------------
// Copyright and related rights are licensed under the Solderpad Hardware
// License, Version 2.0 (the "License"); you may not use this file except
// in compliance with the License. You may obtain a copy of the License at
// http://solderpad.org/licenses/SHL-2.0.
// Unless required by applicable law or agreed to in writing, software,
// hardware and materials distributed under this License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
// or implied. See the License for the specific language governing permissions
// and limitations under the License.
//------------------------------------------------------------------------------
`ifndef __WRTD_RULE_INCLUDED
`define __WRTD_RULE_INCLUDED
`include "wrtd_rep_cap.svh"
class WrtdRule extends WrtdRepCap;
protected WrtdId src;
protected WrtdId dst;
protected byte unsigned dest_cpu;
protected byte unsigned dest_ch;
protected byte unsigned send_late;
protected uint32_t repeat_count;
protected uint32_t delay_ns;
protected uint32_t hold_off_ns;
protected uint32_t resync_period_ns;
protected uint32_t resync_delay_ns;
int hash_chain;
protected uint32_t rx_events;
protected WrtdTstamp rx_last;
protected uint32_t tx_events;
protected WrtdTstamp tx_last;
protected uint32_t lat_max_ns;
protected uint32_t lat_lo_ns;
protected uint32_t lat_hi_ns;
protected uint32_t lat_nbr;
protected uint32_t miss_holdoff;
protected uint32_t miss_late;
protected WrtdTstamp miss_last;
protected WrtdTstamp hold_off;
protected uint32_t seq;
function new ( int core, int index, string name = "" );
super.new ( core, index, name );
this.src = new();
this.dst = new();
this.rx_last = new();
this.tx_last = new();
this.miss_last = new();
this.hold_off = new();
clear();
endfunction // new
function void clear ( );
super.clear();
this.src.clear();
this.dst.clear();
this.rx_last.zero();
this.tx_last.zero();
this.miss_last.zero();
this.hold_off.zero();
this.dest_cpu = 0;
this.dest_ch = 0;
this.send_late = 1;
this.repeat_count = 0;
this.delay_ns = 0;
this.hold_off_ns = 0;
this.resync_period_ns = 0;
this.resync_delay_ns = 0;
this.hash_chain = -1;
endfunction // clear
function wrtd_data data_pack ( );
wrtd_data ret = new[`WRTD_RULE_WORD_SIZE];
ret[0:3] = this.rep_cap_id.data_pack();
ret[4:7] = this.src.data_pack();
ret[8:11] = this.dst.data_pack();
ret[12] = this.dest_cpu << 0;
ret[12] |= this.dest_ch << 8;
ret[12] |= this.enabled << 16;
ret[12] |= this.send_late << 24;
ret[13] = this.repeat_count;
ret[14] = this.delay_ns;
ret[15] = this.hold_off_ns;
ret[16] = this.resync_period_ns;
ret[17] = this.resync_delay_ns;
ret[18] = this.hash_chain;
ret[19] = this.rx_events;
ret[20:22] = this.rx_last.data_pack();
ret[23] = this.tx_events;
ret[24:26] = this.tx_last.data_pack();
ret[27] = this.lat_max_ns;
ret[28] = this.lat_lo_ns;
ret[29] = this.lat_hi_ns;
ret[30] = this.lat_nbr;
ret[31] = this.miss_holdoff;
ret[32] = this.miss_late;
ret[33:35] = this.miss_last.data_pack();
ret[36:38] = this.hold_off.data_pack();
ret[39] = this.seq;
return ret;
endfunction // data_pack
function void data_unpack ( wrtd_data data );
this.rep_cap_id.data_unpack ( data[0:3] );
this.src.data_unpack (data[4:7] );
this.dst.data_unpack( data[8:11] );
this.dest_cpu = ( data[12] & 'h000000ff ) >> 0;
this.dest_ch = ( data[12] & 'h0000ff00 ) >> 8;
this.enabled = ( data[12] & 'h00ff0000 ) >> 16;
this.send_late = ( data[12] & 'hff000000 ) >> 24;
this.repeat_count = data[13];
this.delay_ns = data[14];
this.hold_off_ns = data[15];
this.resync_period_ns = data[16];
this.resync_delay_ns = data[17];
this.hash_chain = data[18];
this.rx_events = data[19];
this.rx_last.data_unpack ( data[20:22] );
this.tx_events = data[23];
this.tx_last.data_unpack ( data[24:26] );
this.lat_max_ns = data[27];
this.lat_lo_ns = data[28];
this.lat_hi_ns = data[29];
this.lat_nbr = data[30];
this.miss_holdoff = data[31];
this.miss_late = data[32];
this.miss_last.data_unpack ( data[33:35] );
this.hold_off.data_unpack ( data[36:38] );
this.seq = data[39];
endfunction // data_unpack
function string get_src ( );
return this.src.get();
endfunction // get_src
function string get_dst ( );
return this.dst.get();
endfunction // get_dst
function void set_src ( string src );
this.src.set ( src );
endfunction // set_src
function void set_dst ( string dst );
this.dst.set ( dst );
endfunction // set_src
function void set_dest_cpu ( uint32_t dest_cpu );
this.dest_cpu = dest_cpu;
endfunction // set_dest_cpu
function void set_dest_ch ( uint32_t dest_ch );
this.dest_ch = dest_ch;
endfunction // set_dest_ch
function void set_delay_ns ( uint32_t delay_ns );
this.delay_ns = delay_ns;
endfunction // set_delay_ns
endclass //WrtdRule
`endif // `ifndef __WRTD_RULE_INCLUDED
wrtd-53772dc3cd49421ea1fa6326a199b7a72dc04d18/hdl/testbench/wrtd_ref_spec150t_adc/ 0000775 0000000 0000000 00000000000 13460261316 0026205 5 ustar 00root root 0000000 0000000 wrtd-53772dc3cd49421ea1fa6326a199b7a72dc04d18/hdl/testbench/wrtd_ref_spec150t_adc/.gitignore 0000664 0000000 0000000 00000000067 13460261316 0030200 0 ustar 00root root 0000000 0000000 work/
NullFile
Makefile
modelsim.ini
transcript*
*.wlf
wrtd-53772dc3cd49421ea1fa6326a199b7a72dc04d18/hdl/testbench/wrtd_ref_spec150t_adc/Manifest.py 0000664 0000000 0000000 00000001201 13460261316 0030317 0 ustar 00root root 0000000 0000000 board = "spec"
sim_tool = "modelsim"
top_module = "main"
action = "simulation"
target = "xilinx"
syn_device = "xc6slx150t"
vcom_opt = "-93 -mixedsvvh"
fetchto = "../../../dependencies"
ctrls = ["bank3_64b_32b"]
include_dirs = [
"../include",
fetchto + "/gn4124-core/hdl/gn4124core/sim/gn4124_bfm",
fetchto + "/general-cores/sim",
fetchto + "/mock-turtle/hdl/testbench/include",
fetchto + "/fmc-adc-100m14b4cha-gw/hdl/testbench/include",
]
files = [
"main.sv",
"dut_env.sv",
"synthesis_descriptor.vhd",
]
modules = {
"local" : [
"../../top/wrtd_ref_spec150t_adc",
],
}
wrtd-53772dc3cd49421ea1fa6326a199b7a72dc04d18/hdl/testbench/wrtd_ref_spec150t_adc/README.md 0000664 0000000 0000000 00000001215 13460261316 0027463 0 ustar 00root root 0000000 0000000 Introduction
============
This is a testbench for the SPEC150T-based FMC ADC WRTD reference design.
Dependencies
============
To build this, you will need [hdl-make][1], using commit `968fa87` (or newer), as well as GNU Make.
To run it, you will need Modelsim/Questa. It has been tested with Questa 10.5c on Linux.
Build/Run Instrunctions
=======================
1. If not already done, pull all dependencies using `git submodule update --init` from within the
WRTD repository.
2. Run `hdlmake` from this directory.
3. Run `make` on the hdlmake-generated Makefile.
4. Run `vsim -c -do run.do`.
[1]: https://www.ohwr.org/projects/hdl-make/wiki
wrtd-53772dc3cd49421ea1fa6326a199b7a72dc04d18/hdl/testbench/wrtd_ref_spec150t_adc/dut_env.sv 0000664 0000000 0000000 00000024733 13460261316 0030234 0 ustar 00root root 0000000 0000000 //------------------------------------------------------------------------------
// CERN BE-CO-HT
// White Rabbit Trigger Distribution (WRTD)
// https://ohwr.org/projects/wrtd
//------------------------------------------------------------------------------
//
// unit name: dut_env
//
// description: Wrapper for the Device Under Test (SPEC150T-based FMC ADC WRTD
// reference design) and its peripherals.
//
//------------------------------------------------------------------------------
// Copyright CERN 2019
//------------------------------------------------------------------------------
// Copyright and related rights are licensed under the Solderpad Hardware
// License, Version 2.0 (the "License"); you may not use this file except
// in compliance with the License. You may obtain a copy of the License at
// http://solderpad.org/licenses/SHL-2.0.
// Unless required by applicable law or agreed to in writing, software,
// hardware and materials distributed under this License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
// or implied. See the License for the specific language governing permissions
// and limitations under the License.
//------------------------------------------------------------------------------
`timescale 1ns/1ps
`include "gn4124_bfm.svh"
module dut_env
(
IGN4124PCIMaster i_gn4124,
output[2:0] acq_fsm_state,
output sfp_txp_o, sfp_txn_o,
input sfp_rxp_i, sfp_rxn_i,
input ext_trigger_i
);
reg clk_125m_pll = 0;
reg clk_125m_gtp = 0;
reg clk_20m_vcxo = 0;
reg clk_400m_adc = 0;
reg clk_62m5_sys = 0;
always #1.25ns clk_400m_adc <= ~clk_400m_adc;
always #4ns clk_125m_pll <= ~clk_125m_pll;
always #4ns clk_125m_gtp <= ~clk_125m_gtp;
always #8ns clk_62m5_sys <= ~clk_62m5_sys;
always #25ns clk_20m_vcxo <= ~clk_20m_vcxo;
reg adc0_fr = 1'b0;
reg adc_data_dir = 1'b0;
reg[3:0] adc0_dat_odd = 4'h0;
reg[3:0] adc0_dat_even = 4'h0;
reg signed [13:0] adc0_data = 0;
int adc_div = 0;
wire ddr_cas_n, ddr_ck_p, ddr_ck_n, ddr_cke;
wire [1:0] ddr_dm, ddr_dqs_p, ddr_dqs_n;
wire ddr_odt, ddr_ras_n, ddr_reset_n, ddr_we_n;
wire [15:0] ddr_dq;
wire [13:0] ddr_a;
wire [2:0] ddr_ba;
wire ddr_rzq;
pulldown(ddr_rzq);
wire sfp_scl, sfp_sda, sfp_sda_en;
//---------------------------------------------------------------------------
// The DUT
//---------------------------------------------------------------------------
wrtd_ref_spec150t_adc #
(
.g_SIMULATION (1),
.g_WRPC_INITF ("../../../dependencies/wr-cores/bin/wrpc/wrc_phy8_sim.bram")
)
DUT
(
.button1_n_i (1'b1),
.clk_20m_vcxo_i (clk_20m_vcxo),
.clk_125m_pllref_p_i (clk_125m_pll),
.clk_125m_pllref_n_i (~clk_125m_pll),
.clk_125m_gtp_n_i (clk_125m_gtp),
.clk_125m_gtp_p_i (~clk_125m_gtp),
.pll25dac_sync_n_o (),
.pll20dac_sync_n_o (),
.plldac_din_o (),
.plldac_sclk_o (),
.led_sfp_red_o (),
.led_sfp_green_o (),
.aux_leds_o (),
.pcbrev_i (4'b0),
.carrier_onewire_b (),
.sfp_txp_o (sfp_txp_o),
.sfp_txn_o (sfp_txn_o),
.sfp_rxp_i (sfp_rxp_i),
.sfp_rxn_i (sfp_rxn_i),
.sfp_mod_def0_i (1'b0),
.sfp_mod_def1_b (sfp_scl),
.sfp_mod_def2_b (sfp_sda),
.sfp_rate_select_o (),
.sfp_tx_fault_i (1'b0),
.sfp_tx_disable_o (),
.sfp_los_i (1'b0),
.spi_sclk_o (),
.spi_ncs_o (),
.spi_mosi_o (),
.spi_miso_i (1'b0),
.uart_rxd_i (1'b0),
.uart_txd_o (),
.gn_rst_n_i (i_gn4124.rst_n),
.gn_p2l_clk_n_i (i_gn4124.p2l_clk_n),
.gn_p2l_clk_p_i (i_gn4124.p2l_clk_p),
.gn_p2l_rdy_o (i_gn4124.p2l_rdy),
.gn_p2l_dframe_i (i_gn4124.p2l_dframe),
.gn_p2l_valid_i (i_gn4124.p2l_valid),
.gn_p2l_data_i (i_gn4124.p2l_data),
.gn_p_wr_req_i (i_gn4124.p_wr_req),
.gn_p_wr_rdy_o (i_gn4124.p_wr_rdy),
.gn_rx_error_o (i_gn4124.rx_error),
.gn_l2p_clk_n_o (i_gn4124.l2p_clk_n),
.gn_l2p_clk_p_o (i_gn4124.l2p_clk_p),
.gn_l2p_dframe_o (i_gn4124.l2p_dframe),
.gn_l2p_valid_o (i_gn4124.l2p_valid),
.gn_l2p_edb_o (i_gn4124.l2p_edb),
.gn_l2p_data_o (i_gn4124.l2p_data),
.gn_l2p_rdy_i (i_gn4124.l2p_rdy),
.gn_l_wr_rdy_i (i_gn4124.l_wr_rdy),
.gn_p_rd_d_rdy_i (i_gn4124.p_rd_d_rdy),
.gn_tx_error_i (i_gn4124.tx_error),
.gn_vc_rdy_i (i_gn4124.vc_rdy),
.gn_gpio_b (),
.ddr0_a_o (ddr_a),
.ddr0_ba_o (ddr_ba),
.ddr0_cas_n_o (ddr_cas_n),
.ddr0_ck_n_o (ddr_ck_n),
.ddr0_ck_p_o (ddr_ck_p),
.ddr0_cke_o (ddr_cke),
.ddr0_dq_b (ddr_dq),
.ddr0_ldm_o (ddr_dm[0]),
.ddr0_ldqs_n_b (ddr_dqs_n[0]),
.ddr0_ldqs_p_b (ddr_dqs_p[0]),
.ddr0_odt_o (ddr_odt),
.ddr0_ras_n_o (ddr_ras_n),
.ddr0_reset_n_o (ddr_reset_n),
.ddr0_rzq_b (ddr_rzq),
.ddr0_udm_o (ddr_dm[1]),
.ddr0_udqs_n_b (ddr_dqs_n[1]),
.ddr0_udqs_p_b (ddr_dqs_p[1]),
.ddr0_we_n_o (ddr_we_n),
.fmc0_adc_ext_trigger_p_i (ext_trigger_i),
.fmc0_adc_ext_trigger_n_i (~ext_trigger_i),
.fmc0_adc_dco_p_i (clk_400m_adc),
.fmc0_adc_dco_n_i (~clk_400m_adc),
.fmc0_adc_fr_p_i (~adc0_fr),
.fmc0_adc_fr_n_i (adc0_fr),
.fmc0_adc_outa_p_i (adc0_dat_odd),
.fmc0_adc_outa_n_i (~adc0_dat_odd),
.fmc0_adc_outb_p_i (adc0_dat_even),
.fmc0_adc_outb_n_i (~adc0_dat_even),
.fmc0_adc_spi_din_i (),
.fmc0_adc_spi_dout_o (),
.fmc0_adc_spi_sck_o (),
.fmc0_adc_spi_cs_adc_n_o (),
.fmc0_adc_spi_cs_dac1_n_o (),
.fmc0_adc_spi_cs_dac2_n_o (),
.fmc0_adc_spi_cs_dac3_n_o (),
.fmc0_adc_spi_cs_dac4_n_o (),
.fmc0_adc_gpio_dac_clr_n_o (),
.fmc0_adc_gpio_led_acq_o (),
.fmc0_adc_gpio_led_trig_o (),
.fmc0_adc_gpio_ssr_ch1_o (),
.fmc0_adc_gpio_ssr_ch2_o (),
.fmc0_adc_gpio_ssr_ch3_o (),
.fmc0_adc_gpio_ssr_ch4_o (),
.fmc0_adc_gpio_si570_oe_o (),
.fmc0_adc_si570_scl_b (),
.fmc0_adc_si570_sda_b (),
.fmc0_adc_one_wire_b (),
.fmc0_prsnt_m2c_n_i (1'b0),
.fmc0_scl_b (),
.fmc0_sda_b ()
);
assign acq_fsm_state = DUT.cmp0_fmc_adc_mezzanine.cmp_fmc_adc_100Ms_core.acq_fsm_state;
//---------------------------------------------------------------------------
// DDR memory model
//---------------------------------------------------------------------------
ddr3 #
(
.DEBUG(0),
.check_strict_timing(0),
.check_strict_mrbits(0)
)
DDR_MEM
(
.rst_n (ddr_reset_n),
.ck (ddr_ck_p),
.ck_n (ddr_ck_n),
.cke (ddr_cke),
.cs_n (1'b0),
.ras_n (ddr_ras_n),
.cas_n (ddr_cas_n),
.we_n (ddr_we_n),
.dm_tdqs (ddr_dm),
.ba (ddr_ba),
.addr (ddr_a),
.dq (ddr_dq),
.dqs (ddr_dqs_p),
.dqs_n (ddr_dqs_n),
.tdqs_n (),
.odt (ddr_odt)
);
//---------------------------------------------------------------------------
// SFP I2C Adapter
//---------------------------------------------------------------------------
gc_sfp_i2c_adapter
SFP_I2C
(
.clk_i (clk_125m_pll),
.rst_n_i (1'b1),
.scl_i (sfp_scl),
.sda_i (sfp_sda),
.sda_en_o (sfp_sda_en),
.sfp_det_valid_i (1'b1),
.sfp_data_i (128'h0123456789ABCDEF0123456789ABCDEF)
);
assign sfp_sda = (sfp_sda_en) ? 1'b0:1'bz;
//---------------------------------------------------------------------------
// Dummy ADC data generator
//---------------------------------------------------------------------------
always@(negedge clk_400m_adc)
begin
#625ps;
if(adc_div == 1) begin
adc0_fr <= ~adc0_fr;
adc_div <= 0;
end
else begin
adc_div <= adc_div + 1;
end
end
always@(posedge adc0_fr)
begin
if ((adc0_data > 400) || (adc0_data < -400)) begin
adc_data_dir = ~adc_data_dir;
end
if (adc_data_dir == 0) begin
adc0_data = adc0_data + 8;
end
else begin
adc0_data = adc0_data - 8;
end
adc0_dat_odd = {4{adc0_data[13]}};
adc0_dat_even = {4{adc0_data[12]}};
#1250ps;
adc0_dat_odd = {4{adc0_data[11]}};
adc0_dat_even = {4{adc0_data[10]}};
#1250ps;
adc0_dat_odd = {4{adc0_data[9]}};
adc0_dat_even = {4{adc0_data[8]}};
#1250ps;
adc0_dat_odd = {4{adc0_data[7]}};
adc0_dat_even = {4{adc0_data[6]}};
#1250ps;
adc0_dat_odd = {4{adc0_data[5]}};
adc0_dat_even = {4{adc0_data[4]}};
#1250ps;
adc0_dat_odd = {4{adc0_data[3]}};
adc0_dat_even = {4{adc0_data[2]}};
#1250ps;
adc0_dat_odd = {4{adc0_data[1]}};
adc0_dat_even = {4{adc0_data[0]}};
#1250ps;
adc0_dat_odd = {4{1'b0}};
adc0_dat_even = {4{1'b0}};
end
initial begin
// Skip WR SoftPLL lock
force DUT.cmp_xwrc_board_spec.cmp_board_common.cmp_xwr_core.
WRPC.U_SOFTPLL.U_Wrapped_Softpll.out_locked_o = 3'b111;
// Silence Xilinx unisim DSP48A1 warnings about invalid OPMODE
force DUT.cmp_xwrc_board_spec.cmp_board_common.cmp_xwr_core.
WRPC.LM32_CORE.gen_profile_medium_icache.U_Wrapped_LM32.cpu.
multiplier.D1.OPMODE_dly = 0;
force DUT.cmp_xwrc_board_spec.cmp_board_common.cmp_xwr_core.
WRPC.LM32_CORE.gen_profile_medium_icache.U_Wrapped_LM32.cpu.
multiplier.D2.OPMODE_dly = 0;
force DUT.cmp_xwrc_board_spec.cmp_board_common.cmp_xwr_core.
WRPC.LM32_CORE.gen_profile_medium_icache.U_Wrapped_LM32.cpu.
multiplier.D3.OPMODE_dly = 0;
end // initial begin
endmodule // dut_env
wrtd-53772dc3cd49421ea1fa6326a199b7a72dc04d18/hdl/testbench/wrtd_ref_spec150t_adc/main.sv 0000664 0000000 0000000 00000017211 13460261316 0027505 0 ustar 00root root 0000000 0000000 //------------------------------------------------------------------------------
// CERN BE-CO-HT
// White Rabbit Trigger Distribution (WRTD)
// https://ohwr.org/projects/wrtd
//------------------------------------------------------------------------------
//
// unit name: main
//
// description: Testbench for the SPEC150T-based FMC ADC WRTD reference design.
//
//------------------------------------------------------------------------------
// Copyright CERN 2019
//------------------------------------------------------------------------------
// Copyright and related rights are licensed under the Solderpad Hardware
// License, Version 2.0 (the "License"); you may not use this file except
// in compliance with the License. You may obtain a copy of the License at
// http://solderpad.org/licenses/SHL-2.0.
// Unless required by applicable law or agreed to in writing, software,
// hardware and materials distributed under this License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
// or implied. See the License for the specific language governing permissions
// and limitations under the License.
//------------------------------------------------------------------------------
`timescale 1ns/1ps
`include "gn4124_bfm.svh"
`include "wrtd_driver.svh"
`include "fmc_adc_100Ms_csr.v"
`include "fmc_adc_alt_trigout.v"
`define ADC_CSR_BASE 'h5000
module main;
IGN4124PCIMaster hostA ();
IGN4124PCIMaster hostB ();
reg duta_ext_trig, dutb_ext_trig;
wire[2:0] duta_acq_state, dutb_acq_state;
dut_env DUTA (hostA, duta_acq_state, a2b_txp, a2b_txn, a2b_rxp, a2b_rxn, duta_ext_trig);
dut_env DUTB (hostB, dutb_acq_state, a2b_rxp, a2b_rxn, a2b_txp, a2b_txn, dutb_ext_trig);
IMockTurtleIRQ MtIrqMonitorA (`MT_ATTACH_IRQ(DUTA.DUT.cmp_mock_turtle));
IMockTurtleIRQ MtIrqMonitorB (`MT_ATTACH_IRQ(DUTB.DUT.cmp_mock_turtle));
CBusAccessor accA, accB;
WrtdDrv devA, devB;
const uint64_t MT_BASE = 'h0002_0000;
initial begin
uint64_t val, expected;
$timeformat (-6, 3, "us", 10);
duta_ext_trig <= 1'b0;
wait ((hostA.ready == 1'b1) && (hostB.ready == 1'b1));
fork
begin
accA = hostA.get_accessor();
accA.set_default_xfer_size(4);
devA = new (accA, MT_BASE, MtIrqMonitorA, "DUT:A");
devA.init();
devA.add_rule ( "rule0" );
devA.set_rule ( "rule0", "ADCI5", "NET0", 0 );
devA.enable_rule ( "rule0" );
// Config DUTA to trigger on external trigger and get 64 samples
accA.write(`ADC_CSR_BASE + `ADDR_FMC_ADC_100MS_CSR_PRE_SAMPLES, 'h00);
accA.write(`ADC_CSR_BASE + `ADDR_FMC_ADC_100MS_CSR_POST_SAMPLES, 'h40);
accA.write(`ADC_CSR_BASE + `ADDR_FMC_ADC_100MS_CSR_SHOTS, 'h01);
accA.write(`ADC_CSR_BASE + `ADDR_FMC_ADC_100MS_CSR_CH1_GAIN, 'h8000);
accA.write(`ADC_CSR_BASE + `ADDR_FMC_ADC_100MS_CSR_CH2_GAIN, 'h8000);
accA.write(`ADC_CSR_BASE + `ADDR_FMC_ADC_100MS_CSR_CH3_GAIN, 'h8000);
accA.write(`ADC_CSR_BASE + `ADDR_FMC_ADC_100MS_CSR_CH4_GAIN, 'h8000);
accA.write(`ADC_CSR_BASE + `ADDR_FMC_ADC_100MS_CSR_CH1_SAT, 'h7fff);
accA.write(`ADC_CSR_BASE + `ADDR_FMC_ADC_100MS_CSR_CH2_SAT, 'h7fff);
accA.write(`ADC_CSR_BASE + `ADDR_FMC_ADC_100MS_CSR_CH3_SAT, 'h7fff);
accA.write(`ADC_CSR_BASE + `ADDR_FMC_ADC_100MS_CSR_CH4_SAT, 'h7fff);
val = (1'b1 << `FMC_ADC_100MS_CSR_TRIG_EN_EXT_OFFSET);
accA.write(`ADC_CSR_BASE + `ADDR_FMC_ADC_100MS_CSR_TRIG_EN, val);
expected = 'h39;
accA.read(`ADC_CSR_BASE + `ADDR_FMC_ADC_100MS_CSR_STA, val);
if (val != expected)
$fatal (1, "ADC status error (got 0x%8x, expected 0x%8x).", val, expected);
$display ("[DUT:A] <%t> ADC configured and armed", $realtime);
wait (duta_acq_state == 1);
end
begin
accB = hostB.get_accessor();
accB.set_default_xfer_size(4);
devB = new (accB, MT_BASE, MtIrqMonitorB, "DUT:B");
devB.init();
devB.add_rule ( "rule0" );
devB.set_rule ( "rule0", "NET0", "ADCO1", 50000 );
devB.enable_rule ( "rule0" );
// Config DUTB to trigger on WRTD and get 64 samples
accB.write(`ADC_CSR_BASE + `ADDR_FMC_ADC_100MS_CSR_PRE_SAMPLES, 'h00);
accB.write(`ADC_CSR_BASE + `ADDR_FMC_ADC_100MS_CSR_POST_SAMPLES, 'h40);
accB.write(`ADC_CSR_BASE + `ADDR_FMC_ADC_100MS_CSR_SHOTS, 'h01);
accB.write(`ADC_CSR_BASE + `ADDR_FMC_ADC_100MS_CSR_CH1_GAIN, 'h8000);
accB.write(`ADC_CSR_BASE + `ADDR_FMC_ADC_100MS_CSR_CH2_GAIN, 'h8000);
accB.write(`ADC_CSR_BASE + `ADDR_FMC_ADC_100MS_CSR_CH3_GAIN, 'h8000);
accB.write(`ADC_CSR_BASE + `ADDR_FMC_ADC_100MS_CSR_CH4_GAIN, 'h8000);
accB.write(`ADC_CSR_BASE + `ADDR_FMC_ADC_100MS_CSR_CH1_SAT, 'h7fff);
accB.write(`ADC_CSR_BASE + `ADDR_FMC_ADC_100MS_CSR_CH2_SAT, 'h7fff);
accB.write(`ADC_CSR_BASE + `ADDR_FMC_ADC_100MS_CSR_CH3_SAT, 'h7fff);
accB.write(`ADC_CSR_BASE + `ADDR_FMC_ADC_100MS_CSR_CH4_SAT, 'h7fff);
val = (1'b1 << `FMC_ADC_100MS_CSR_TRIG_EN_ALT_TIME_OFFSET);
accB.write(`ADC_CSR_BASE + `ADDR_FMC_ADC_100MS_CSR_TRIG_EN, val);
expected = 'h39;
accB.read(`ADC_CSR_BASE + `ADDR_FMC_ADC_100MS_CSR_STA, val);
if (val != expected)
$fatal (1, "ADC status error (got 0x%8x, expected 0x%8x).", val, expected);
$display ("[DUT:B] <%t> ADC configured and armed", $realtime);
wait (dutb_acq_state == 1);
end
join
#50us;
$display("[DUT:B] <%t> START ACQ 1", $realtime);
accB.write(`ADC_CSR_BASE + `ADDR_FMC_ADC_100MS_CSR_CTL, 'h00000001); // FSM start
$display("[DUT:A] <%t> START ACQ 1", $realtime);
accA.write(`ADC_CSR_BASE + `ADDR_FMC_ADC_100MS_CSR_CTL, 'h00000001); // FSM start
#5us;
duta_ext_trig <= 1'b1;
#10ns;
duta_ext_trig <= 1'b0;
fork
begin
wait (duta_acq_state == 1);
$display("[DUT:A] <%t> END ACQ 1", $realtime);
accA.read(`ADC_CSR_BASE + `ADDR_FMC_ADC_100MS_CSR_TRIG_POS, val);
$display("[DUT:A] <%t> TRIG POSITION %.8x", $realtime, val);
// DMA transfer
accA.write('h2008, val); // dma start addr
accA.write('h200C, 'h00001000); // host addr
accA.write('h2010, 'h00000000);
accA.write('h2014, 'h00000100); // len << 2
accA.write('h2018, 'h00000000); // next
accA.write('h201C, 'h00000000);
accA.write('h2020, 'h00000000); // attrib: pcie -> host
accA.write('h2000, 'h00000001); // xfer start
wait (DUTA.DUT.dma_irq[0] == 1);
$display("[DUT:A] <%t> END DMA 1", $realtime);
end
begin
wait (dutb_acq_state == 1);
$display("[DUT:B] <%t> END ACQ 1", $realtime);
accB.read(`ADC_CSR_BASE + `ADDR_FMC_ADC_100MS_CSR_TRIG_POS, val);
$display("[DUT:B] <%t> TRIG POSITION %.8x", $realtime, val);
// DMA transfer
accB.write('h2008, val); // dma start addr
accB.write('h200C, 'h00001000); // host addr
accB.write('h2010, 'h00000000);
accB.write('h2014, 'h00000100); // len << 2
accB.write('h2018, 'h00000000); // next
accB.write('h201C, 'h00000000);
accB.write('h2020, 'h00000000); // attrib: pcie -> host
accB.write('h2000, 'h00000001); // xfer start
wait (DUTB.DUT.dma_irq[0] == 1);
$display("[DUT:B] <%t> END DMA 1", $realtime);
end
join
end
initial begin
forever begin
if ( ( devA != null ) && ( devA.ready ) )
devA.update();
if ( ( devB != null ) && ( devB.ready ) )
devB.update();
#1us;
end
end
initial begin
$display();
$display("Start of simulation");
$display("-------------------");
$display();
#5000us;
$display();
$display("Simulation PASSED");
$finish;
end
endmodule // main
wrtd-53772dc3cd49421ea1fa6326a199b7a72dc04d18/hdl/testbench/wrtd_ref_spec150t_adc/run.do 0000664 0000000 0000000 00000000231 13460261316 0027331 0 ustar 00root root 0000000 0000000 vsim -quiet -t 10fs -L unisim work.main -suppress 1270,8617,8683,8684
set StdArithNoWarnings 1
set NumericStdNoWarnings 1
radix -hexadecimal
run -all
synthesis_descriptor.vhd 0000664 0000000 0000000 00000002254 13460261316 0033123 0 ustar 00root root 0000000 0000000 wrtd-53772dc3cd49421ea1fa6326a199b7a72dc04d18/hdl/testbench/wrtd_ref_spec150t_adc --------------------------------------------------------------------------------
-- SDB meta information for wrtd_ref_spec150t_adc.xise.
--
-- This file was automatically generated by ../../../dependencies/general-cores/tools/sdb_desc_gen.tcl on:
-- Wednesday, January 30 2019
--
-- ../../../dependencies/general-cores/tools/sdb_desc_gen.tcl is part of OHWR general-cores:
-- https://www.ohwr.org/projects/general-cores/wiki
--
-- For more information on SDB meta information, see also:
-- https://www.ohwr.org/projects/sdb/wiki
--------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use work.wishbone_pkg.all;
package synthesis_descriptor is
constant c_sdb_synthesis_info : t_sdb_synthesis := (
syn_module_name => "wrtd_ref_spec150",
syn_commit_id => "eaa378a35717954407166b2e80e34c2*",
syn_tool_name => "ISE ",
syn_tool_version => x"00000147",
syn_date => x"20190130",
syn_username => "Dimitris Lampri");
constant c_sdb_repo_url : t_sdb_repo_url := (
repo_url => "git@ohwr-gitlab.cern.ch:project/wrtd.git ");
end package synthesis_descriptor;
wrtd-53772dc3cd49421ea1fa6326a199b7a72dc04d18/hdl/testbench/wrtd_ref_svec_tdc_fd/ 0000775 0000000 0000000 00000000000 13460261316 0026275 5 ustar 00root root 0000000 0000000 wrtd-53772dc3cd49421ea1fa6326a199b7a72dc04d18/hdl/testbench/wrtd_ref_svec_tdc_fd/.gitignore 0000664 0000000 0000000 00000000056 13460261316 0030266 0 ustar 00root root 0000000 0000000 work/
Makefile
modelsim.ini
transcript*
*.wlf
wrtd-53772dc3cd49421ea1fa6326a199b7a72dc04d18/hdl/testbench/wrtd_ref_svec_tdc_fd/Manifest.py 0000664 0000000 0000000 00000000747 13460261316 0030425 0 ustar 00root root 0000000 0000000 board = "svec"
sim_tool = "modelsim"
sim_top = "main"
action = "simulation"
target = "xilinx"
syn_device = "xc6slx150t"
vcom_opt = "-93 -mixedsvvh"
fetchto="../../../dependencies"
include_dirs = [
"../include",
fetchto + "/general-cores/sim/",
fetchto + "/mock-turtle/hdl/testbench/include/",
]
files = [
"main.sv",
"dut_env.sv",
"synthesis_descriptor.vhd",
]
modules = {
"local" : [
"../../top/wrtd_ref_svec_tdc_fd",
],
}
wrtd-53772dc3cd49421ea1fa6326a199b7a72dc04d18/hdl/testbench/wrtd_ref_svec_tdc_fd/dut_env.sv 0000664 0000000 0000000 00000025667 13460261316 0030333 0 ustar 00root root 0000000 0000000 //------------------------------------------------------------------------------
// CERN BE-CO-HT
// White Rabbit Trigger Distribution (WRTD)
// https://ohwr.org/projects/wrtd
//------------------------------------------------------------------------------
//
// unit name: dut_env
//
// description: Wrapper for the Device Under Test (SVEC-based FMC TDC+FD WRTD
// reference design) and its peripherals.
//
//------------------------------------------------------------------------------
// Copyright CERN 2019
//------------------------------------------------------------------------------
// Copyright and related rights are licensed under the Solderpad Hardware
// License, Version 2.0 (the "License"); you may not use this file except
// in compliance with the License. You may obtain a copy of the License at
// http://solderpad.org/licenses/SHL-2.0.
// Unless required by applicable law or agreed to in writing, software,
// hardware and materials distributed under this License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
// or implied. See the License for the specific language governing permissions
// and limitations under the License.
//------------------------------------------------------------------------------
`timescale 1ns/1ps
`include "vhd_wishbone_master.svh"
`include "simdrv_defs.svh"
module simple_tdc_driver
(
input clk,
input [3:0] addr,
inout [27:0] data,
input wr,
input rd,
output reg ef1,
output reg ef2,
input tstart,
output intflag
);
typedef struct {
int channel;
time ts;
} acam_fifo_entry;
acam_fifo_entry pulses[$];
logic [27:0] fifos[2][$];
reg [7:0] start = 0;
time start_time;
reg [16:0] start01 = 0;
reg [7:0] start_rep = 0;
const int start_timer = 15 + 1;
reg restart_pulse = 0;
time restart_time;
reg [27:0] rdata;
assign data = rdata;
assign intflag = start[7];
task push_pulse(int channel, time ts);
pulses.push_back('{channel: channel, ts: ts});
endtask
// Convert trigger to ACAM data
always begin
acam_fifo_entry t;
time now;
wait (pulses.size() != 0)
;
t = pulses.pop_front();
now = $time;
if (t.ts <= now)
$display("TDC: pulse in the past (%t now=%t)!", t.ts, now);
else
begin
const int fifo_n = t.channel / 4;
logic [27:0] val;
#(t.ts - now) ;
val[27:26] = t.channel & 2'b11;
val[25:18] = start;
val[17] = 1'b1;
val[16:0] = (t.ts - start_time) / 81ps;
$display("TDC: pulse at %t for channel %0d (start #0x%x, time_data 0x%x, start_time %t)",
t.ts, t.channel, start, val[16:0], start_time);
fifos[t.channel / 4].push_back(val);
end
end
initial begin
rdata = 28'bz;
end
always@(posedge tstart) begin
restart_pulse = 1;
restart_time = $time;
end;
// Internal start retrigger
always@(posedge clk) begin
start_rep++;
if (start_rep == start_timer) begin
start_rep = 0;
if (restart_pulse) begin
start = 1;
restart_pulse = 0;
start01 = ($time - restart_time) / 81ps;
end
else begin
start_time = $time;
start++;
end
end
end
always@(rd) begin
rdata <= 28'bz;
if (rd == 1'b0) begin
if (addr == 8) begin
rdata <= fifos[0].pop_front();
end
else if (addr == 9) begin
rdata <= fifos[1].pop_front();
end
else if (addr == 10) begin
rdata <= start01;
end
else begin
$display("invalid ACAM read 0x%x", addr);
end
end
end
assign ef1 = fifos[0].size() == 0;
assign ef2 = fifos[1].size() == 0;
always@(negedge wr) begin
// Unused in simulation mode.
$display("invalid ACAM write 0x%x <- 0x%08x", addr, data);
end
endmodule // simple_tdc_driver
module simple_fdelay_mon
(
input [3:0] len,
input [9:0] val,
input [3:0] pulse
);
typedef struct {
int channel;
time ts;
} fifo_entry;
fifo_entry pulses[$];
task push_pulse(int channel, time ts);
pulses.push_back('{channel: channel, ts: ts});
endtask
initial begin
reg [3:0] prev;
time now;
// Do nothing before 100us, hw is not initialized.
# 100us ;
prev = 0;
while (pulses.size() != 0) begin
@pulse ;
now = $time;
$display("[FDEL] <%t> Pulse: len=%x, val=%x, out=%x", now, len, val, pulse);
for(int i = 0; i < 4; i++) begin
if (prev[i] == 1'b0 && pulse[i] == 1'b1) begin
automatic fifo_entry e = pulses.pop_front();
automatic time diff;
$display("[FDEL] pulse on channel %0d", i);
if (e.channel != i) begin
$display("FAIL: [FDEL] Bad channel (expected %0d)", e.channel);
$finish(1);
end
diff = now - e.ts;
if (diff > 2us && diff < -2us) begin
$display("FAIL: [FDEL] Bad timestamp: pulse at %t, expected at %t", now, e.ts);
$finish(1);
end
end
end
prev = pulse;
end
$display("SUCCESS: done");
$finish(0);
end
endmodule // simple_fdelay_mon
module dut_env
(
IVHDWishboneMaster host,
output sfp_txp_o, sfp_txn_o,
input sfp_rxp_i, sfp_rxn_i
);
reg clk_125m_pll = 0;
reg clk_125m_gtp = 0;
reg clk_20m_vcxo = 0;
reg clk_62m5_sys = 0;
reg clk_31m5_acam = 0;
always #4ns clk_125m_pll <= ~clk_125m_pll;
always #4ns clk_125m_gtp <= ~clk_125m_gtp;
always #8ns clk_62m5_sys <= ~clk_62m5_sys;
always #16ns clk_31m5_acam <= ~clk_31m5_acam;
always #25ns clk_20m_vcxo <= ~clk_20m_vcxo;
wire tdc_ef1, tdc_ef2;
wire tdc_rd_n, tdc_wr_n;
wire tdc_int, tdc_start;
wire [3:0] tdc_addr;
wire [27:0] tdc_data;
wire [3:0] fdl_len, fdl_pulse;
wire [9:0] fdl_val;
wire sfp_scl, sfp_sda, sfp_sda_en;
//---------------------------------------------------------------------------
// The DUT
//---------------------------------------------------------------------------
wrtd_ref_svec_tdc_fd #
(
.g_SIMULATION (1),
.g_SIM_BYPASS_VME (1),
.g_WRPC_INITF ("../../../dependencies/wr-cores/bin/wrpc/wrc_phy8_sim.bram"),
.g_MT_CPU0_INITF ("../../../software/firmware/tdc/wrtd-rt-tdc.bram"),
.g_MT_CPU1_INITF ("../../../software/firmware/fd/wrtd-rt-fd.bram")
)
DUT
(
.rst_n_i (1'b1),
.clk_125m_pllref_p_i (clk_125m_pll),
.clk_125m_pllref_n_i (~clk_125m_pll),
.clk_125m_gtp_p_i (clk_125m_gtp),
.clk_125m_gtp_n_i (~clk_125m_gtp),
.clk_20m_vcxo_i (clk_20m_vcxo),
.sim_wb_i (host.out),
.sim_wb_o (host.in),
.carrier_onewire_b (),
.sfp_txp_o (sfp_txp_o),
.sfp_txn_o (sfp_txn_o),
.sfp_rxp_i (sfp_rxp_i),
.sfp_rxn_i (sfp_rxn_i),
.sfp_mod_def0_i (1'b0),
.sfp_mod_def1_b (sfp_scl),
.sfp_mod_def2_b (sfp_sda),
.sfp_rate_select_o (),
.sfp_tx_fault_i (1'b0),
.sfp_tx_disable_o (),
.sfp_los_i (1'b0),
.spi_sclk_o (),
.spi_ncs_o (),
.spi_mosi_o (),
.spi_miso_i (1'b0),
.uart_rxd_i (1'b0),
.uart_txd_o (),
.fmc0_tdc_pll_status_i (1'b1),
.fmc0_tdc_125m_clk_p_i (clk_125m_pll),
.fmc0_tdc_125m_clk_n_i (~clk_125m_pll),
.fmc0_tdc_acam_refclk_p_i (clk_31m5_acam),
.fmc0_tdc_acam_refclk_n_i (~clk_31m5_acam),
.fmc0_tdc_start_from_fpga_o (tdc_start),
.fmc0_tdc_ef1_i (tdc_ef1),
.fmc0_tdc_ef2_i (tdc_ef2),
.fmc0_tdc_err_flag_i (1'b0),
.fmc0_tdc_int_flag_i (tdc_int),
.fmc0_tdc_data_bus_io (tdc_data),
.fmc0_tdc_address_o (tdc_addr),
.fmc0_tdc_rd_n_o (tdc_rd_n),
.fmc0_tdc_wr_n_o (tdc_wr_n),
.fmc1_fd_clk_ref_p_i (clk_125m_pll),
.fmc1_fd_clk_ref_n_i (~clk_125m_pll),
.fmc1_fd_delay_len_o (fdl_len),
.fmc1_fd_delay_val_o (fdl_val),
.fmc1_fd_delay_pulse_o (fdl_pulse)
);
//---------------------------------------------------------------------------
// TDC driver
//---------------------------------------------------------------------------
simple_tdc_driver
TDC
(
.clk(clk_31m5_acam),
.addr(tdc_addr),
.data(tdc_data),
.wr(tdc_wr_n),
.rd(tdc_rd_n),
.ef1(tdc_ef1),
.ef2(tdc_ef2),
.tstart(tdc_start),
.intflag(tdc_int)
);
//---------------------------------------------------------------------------
// Fine Delay monitor
//---------------------------------------------------------------------------
simple_fdelay_mon
FDL
(
.len (fdl_len),
.val (fdl_val),
.pulse (fdl_pulse)
);
//---------------------------------------------------------------------------
// SFP I2C Adapter
//---------------------------------------------------------------------------
gc_sfp_i2c_adapter
SFP_I2C
(
.clk_i (clk_125m_pll),
.rst_n_i (1'b1),
.scl_i (sfp_scl),
.sda_i (sfp_sda),
.sda_en_o (sfp_sda_en),
.sfp_det_valid_i (1'b1),
.sfp_data_i (128'h0123456789ABCDEF0123456789ABCDEF)
);
assign sfp_sda = (sfp_sda_en) ? 1'b0:1'bz;
//---------------------------------------------------------------------------
// Initial processes
//---------------------------------------------------------------------------
task push_pulse(int channel, time ts);
TDC.push_pulse(channel, ts);
FDL.push_pulse(channel, ts + 100us); // Delay time (from fd firmware)
endtask
initial begin
// No pulse before: WR (300us) + TDC setup.
automatic time start = 480us;
push_pulse(0, start + 10us);
push_pulse(1, start + 30us);
push_pulse(2, start + 50us);
#(start + 200us) ;
// Should have been finished by the FD monitor.
$fatal(1, "FAILED");
end
initial begin
// Skip WR SoftPLL lock
force DUT.cmp_xwrc_board_svec.cmp_board_common.cmp_xwr_core.
WRPC.U_SOFTPLL.U_Wrapped_Softpll.out_locked_o = 3'b111;
// Silence Xilinx unisim DSP48A1 warnings about invalid OPMODE
force DUT.cmp_xwrc_board_svec.cmp_board_common.cmp_xwr_core.
WRPC.LM32_CORE.gen_profile_medium_icache.U_Wrapped_LM32.cpu.
multiplier.D1.OPMODE_dly = 0;
force DUT.cmp_xwrc_board_svec.cmp_board_common.cmp_xwr_core.
WRPC.LM32_CORE.gen_profile_medium_icache.U_Wrapped_LM32.cpu.
multiplier.D2.OPMODE_dly = 0;
force DUT.cmp_xwrc_board_svec.cmp_board_common.cmp_xwr_core.
WRPC.LM32_CORE.gen_profile_medium_icache.U_Wrapped_LM32.cpu.
multiplier.D3.OPMODE_dly = 0;
end // initial begin
endmodule // dut_env
wrtd-53772dc3cd49421ea1fa6326a199b7a72dc04d18/hdl/testbench/wrtd_ref_svec_tdc_fd/list_driver.svh 0000664 0000000 0000000 00000011210 13460261316 0031340 0 ustar 00root root 0000000 0000000 //
// unit name: ListDriver
//
// description: A SystemVerilog Class to provide an abstraction of a complete
// LIST system.
//
//------------------------------------------------------------------------------
// Copyright CERN 2018
//------------------------------------------------------------------------------
// Copyright and related rights are licensed under the Solderpad Hardware
// License, Version 2.0 (the "License"); you may not use this file except
// in compliance with the License. You may obtain a copy of the License at
// http://solderpad.org/licenses/SHL-2.0.
// Unless required by applicable law or agreed to in writing, software,
// hardware and materials distributed under this License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
// or implied. See the License for the specific language governing permissions
// and limitations under the License.
//------------------------------------------------------------------------------
`ifndef __LIST_DRIVER_INCLUDED
`define __LIST_DRIVER_INCLUDED
`include "mock_turtle_driver.svh"
`define LIST_HMQ_LOG_SLOT 0
typedef struct {
uint32_t system;
uint32_t source_port;
uint32_t trigger;
} list_trig_id;
typedef struct {
uint64_t seconds;
uint32_t ticks;
uint32_t frac;
} wr_timestamp;
typedef enum {
NOT_MISSED = -1,
DEAD_TIME = 0,
OVERFLOW = 1,
NO_WR = 2,
TIMEOUT = 3
} list_log_miss_reason;
typedef enum {
RAW = (1 << 0),
SENT = (1 << 1),
PROMISC = (1 << 2),
FILTERED = (1 << 3),
EXECUTED = (1 << 4),
MISSED = (1 << 5)
} list_log_type;
typedef enum {
LIST_IN = 2,
LIST_OUT = 6
} list_log_origin;
class ListLogMsg;
list_log_origin origin;
list_log_type ltype;
uint32_t seq;
int channel;
list_trig_id id;
wr_timestamp ts;
list_log_miss_reason miss_reason;
function new ( MQueueMsg msg );
this.origin = list_log_origin'(msg.header.msg_id);
this.ltype = list_log_type'(msg.data[0]);
this.seq = msg.data[1];
this.channel = msg.data[2];
this.id.system = msg.data[3];
this.id.source_port = msg.data[4];
this.id.trigger = msg.data[5];
this.ts.seconds = (msg.data[7] << 32) | msg.data[6];
this.ts.ticks = msg.data[8];
this.ts.frac = msg.data[9];
if ( this.ltype == MISSED )
this.miss_reason = list_log_miss_reason'(msg.data[10]);
else
this.miss_reason = NOT_MISSED;
endfunction // new
function string tostring ();
string str;
str = $sformatf ( {"[%8s] TYPE: %8s, SEQ: %3d, CHANNEL: %2d, ",
"TRIG_SYS: %0d, TRIG_PORT: %0d, TRIG_ID: %0d, ",
"TS_SEC: %2d, TS_TICKS: %10dns" },
origin.name(), ltype.name(), seq, channel,
id.system, id.source_port, id.trigger,
ts.seconds, ts.ticks * 8);
if ( ts.frac > 0 )
str = { str, $sformatf ( ", TS_FRAC: %0d", ts.frac ) };
if ( miss_reason != NOT_MISSED )
str = { str, $sformatf ( ", MISS_REASON: %s", miss_reason ) };
return str;
endfunction // tostring
endclass // ListLogMsg
class ListDriver;
protected string name;
protected int hmq_log_slot;
protected MockTurtleDriver mt;
function new ( CBusAccessor acc, uint64_t base,
vIMockTurtleIRQ irq, string name = "" );
this.name = name;
this.mt = new (acc, base, irq, name);
endfunction // new
task mdisplay ( string str );
string tmp;
if (this.name == "")
tmp = $sformatf("<%t> %s", $realtime, str);
else
tmp = $sformatf("[%s] <%t> %s", this.name, $realtime, str);
$display (tmp);
endtask // mdisplay
task init ( string cpu0_fw = "",
string cpu1_fw = "");
mt.init ( );
mt.enable_console_irq ( 0, 1 );
mt.enable_console_irq ( 1, 1 );
mt.enable_hmqi_irq ( 0, 0, 1 );
mt.enable_hmqi_irq ( 1, 0, 1 );
mt.reset_core ( 0, 1 );
mt.reset_core ( 1, 1 );
if ( cpu0_fw != "" )
mt.load_firmware ( 0, cpu0_fw, 1'b0 );
if ( cpu1_fw != "" )
mt.load_firmware ( 0, cpu1_fw, 1'b0 );
mt.reset_core ( 0, 0 );
mt.reset_core ( 1, 0 );
endtask // init
task check_log_queue ( int core );
ListLogMsg log_msg;
MQueueMsg msg;
msg = new ( core, `LIST_HMQ_LOG_SLOT );
while ( mt.hmq_pending_messages ( core, `LIST_HMQ_LOG_SLOT ) )
begin
mt.hmq_receive_message ( msg );
log_msg = new ( msg );
mdisplay ( log_msg.tostring ( ) );
end
endtask // check_log_queue
task update ( );
mt.update ( );
fork
check_log_queue ( 0 );
check_log_queue ( 1 );
join
endtask // update
endclass // ListDriver
`endif // `ifndef __LIST_DRIVER_INCLUDED
wrtd-53772dc3cd49421ea1fa6326a199b7a72dc04d18/hdl/testbench/wrtd_ref_svec_tdc_fd/main.sv 0000664 0000000 0000000 00000004520 13460261316 0027574 0 ustar 00root root 0000000 0000000 //------------------------------------------------------------------------------
// CERN BE-CO-HT
// White Rabbit Trigger Distribution (WRTD)
// https://ohwr.org/projects/wrtd
//------------------------------------------------------------------------------
//
// unit name: main
//
// description: Testbench for the SPEC150T-based FMC ADC WRTD reference design.
//
//------------------------------------------------------------------------------
// Copyright CERN 2018-2019
//------------------------------------------------------------------------------
// Copyright and related rights are licensed under the Solderpad Hardware
// License, Version 2.0 (the "License"); you may not use this file except
// in compliance with the License. You may obtain a copy of the License at
// http://solderpad.org/licenses/SHL-2.0.
// Unless required by applicable law or agreed to in writing, software,
// hardware and materials distributed under this License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
// or implied. See the License for the specific language governing permissions
// and limitations under the License.
//------------------------------------------------------------------------------
`timescale 1ns/1ps
`include "wrtd_driver.svh"
`include "vhd_wishbone_master.svh"
module main;
wire sfp_txp, sfp_txn, sfp_rxp, sfp_rxn;
IVHDWishboneMaster host (DUT.DUT.clk_sys_62m5, DUT.DUT.rst_sys_62m5_n);
dut_env DUT (host, sfp_txp, sfp_txn, sfp_rxp, sfp_rxn);
IMockTurtleIRQ MtIrqMonitor (`MT_ATTACH_IRQ(DUT.DUT.cmp_mock_turtle));
assign sfp_rxp = sfp_txp;
assign sfp_rxn = sfp_txn;
CBusAccessor acc;
WrtdDrv dev;
const uint64_t MT_BASE = 'h0002_0000;
initial begin
$timeformat (-6, 3, "us", 10);
@(posedge DUT.DUT.rst_sys_62m5_n);
@(posedge DUT.DUT.clk_sys_62m5);
acc = host.get_accessor();
acc.set_default_xfer_size(4);
dev = new (acc, MT_BASE, MtIrqMonitor, "DUT");
dev.init();
dev.add_rule ( "rule0" );
dev.set_rule ( "rule0", "NET0", "FD", 100000 );
dev.enable_rule ( "rule0" );
dev.add_rule ( "rule1" );
dev.set_rule ( "rule1", "TDC", "NET0", 0 );
dev.enable_rule ( "rule1" );
forever begin
if ( ( dev != null ) && ( dev.ready ) )
dev.update ();
#1us;
end
end
endmodule // main
wrtd-53772dc3cd49421ea1fa6326a199b7a72dc04d18/hdl/testbench/wrtd_ref_svec_tdc_fd/run.do 0000664 0000000 0000000 00000000206 13460261316 0027423 0 ustar 00root root 0000000 0000000 vsim -quiet -t 10fs -L unisim work.main
set StdArithNoWarnings 1
set NumericStdNoWarnings 1
radix -hexadecimal
log -r /*
run -all
wrtd-53772dc3cd49421ea1fa6326a199b7a72dc04d18/hdl/testbench/wrtd_ref_svec_tdc_fd/run_ci.do 0000664 0000000 0000000 00000000303 13460261316 0030074 0 ustar 00root root 0000000 0000000 # Modelsim run script for continuous integration
# execute: vsim -c -do "run_ci.do"
vsim -quiet -t 10fs -L unisim work.main
set StdArithNoWarnings 1
set NumericStdNoWarnings 1
run -all
exit
synthesis_descriptor.vhd 0000664 0000000 0000000 00000002231 13460261316 0033206 0 ustar 00root root 0000000 0000000 wrtd-53772dc3cd49421ea1fa6326a199b7a72dc04d18/hdl/testbench/wrtd_ref_svec_tdc_fd --------------------------------------------------------------------------------
-- SDB meta information for svec_list_tdc_fd.xise.
--
-- This file was automatically generated by ../../../ip_cores/general-cores/tools/sdb_desc_gen.tcl on:
-- Friday, July 20 2018
--
-- ../../../ip_cores/general-cores/tools/sdb_desc_gen.tcl is part of OHWR general-cores:
-- https://www.ohwr.org/projects/general-cores/wiki
--
-- For more information on SDB meta information, see also:
-- https://www.ohwr.org/projects/sdb/wiki
--------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use work.wishbone_pkg.all;
package synthesis_descriptor is
constant c_sdb_synthesis_info : t_sdb_synthesis := (
syn_module_name => "svec_list_tdc_fd",
syn_commit_id => "4a68a12eede44d878435d25c3c7eaaf4",
syn_tool_name => "ISE ",
syn_tool_version => x"00000147",
syn_date => x"20180720",
syn_username => "Dimitris Lampri");
constant c_sdb_repo_url : t_sdb_repo_url := (
repo_url => "ssh://git@gitlab.cern.ch:7999/coht/wr-trigger-distribution.git ");
end package synthesis_descriptor;
wrtd-53772dc3cd49421ea1fa6326a199b7a72dc04d18/hdl/top/ 0000775 0000000 0000000 00000000000 13460261316 0020761 5 ustar 00root root 0000000 0000000 wrtd-53772dc3cd49421ea1fa6326a199b7a72dc04d18/hdl/top/wrtd_ref_spec150t_adc/ 0000775 0000000 0000000 00000000000 13460261316 0025030 5 ustar 00root root 0000000 0000000 wrtd-53772dc3cd49421ea1fa6326a199b7a72dc04d18/hdl/top/wrtd_ref_spec150t_adc/Manifest.py 0000664 0000000 0000000 00000001136 13460261316 0027151 0 ustar 00root root 0000000 0000000 files = [
"wrtd_ref_spec150t_adc.vhd",
"carrier_csr_wbgen2_pkg.vhd",
"carrier_csr.vhd",
"dma_eic.vhd",
]
fetchto = "../../../dependencies"
modules = {
"git" : [
"git://ohwr.org/hdl-core-lib/general-cores.git",
"git://ohwr.org/hdl-core-lib/wr-cores.git",
"git://ohwr.org/hdl-core-lib/urv-core.git",
"git://ohwr.org/hdl-core-lib/mock-turtle.git",
"git://ohwr.org/hdl-core-lib/ddr3-sp6-core.git",
"git://ohwr.org/hdl-core-lib/gn4124-core.git",
"git://ohwr.org/fmc-projects/fmc-adc-100m14b4cha/fmc-adc-100m14b4cha-gw.git",
],
}
wrtd-53772dc3cd49421ea1fa6326a199b7a72dc04d18/hdl/top/wrtd_ref_spec150t_adc/carrier_csr.vhd 0000664 0000000 0000000 00000022332 13460261316 0030033 0 ustar 00root root 0000000 0000000 ---------------------------------------------------------------------------------------
-- Title : Wishbone slave core for Carrier control and status registers
---------------------------------------------------------------------------------------
-- File : ../carrier_csr.vhd
-- Author : auto-generated by wbgen2 from carrier_csr.wb
-- Created : Wed Jan 30 13:16:24 2019
-- Standard : VHDL'87
---------------------------------------------------------------------------------------
-- THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE carrier_csr.wb
-- DO NOT HAND-EDIT UNLESS IT'S ABSOLUTELY NECESSARY!
---------------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.carrier_csr_wbgen2_pkg.all;
entity carrier_csr is
port (
rst_n_i : in std_logic;
clk_sys_i : in std_logic;
wb_adr_i : in std_logic_vector(1 downto 0);
wb_dat_i : in std_logic_vector(31 downto 0);
wb_dat_o : out std_logic_vector(31 downto 0);
wb_cyc_i : in std_logic;
wb_sel_i : in std_logic_vector(3 downto 0);
wb_stb_i : in std_logic;
wb_we_i : in std_logic;
wb_ack_o : out std_logic;
wb_err_o : out std_logic;
wb_rty_o : out std_logic;
wb_stall_o : out std_logic;
regs_i : in t_carrier_csr_in_registers;
regs_o : out t_carrier_csr_out_registers
);
end carrier_csr;
architecture syn of carrier_csr is
signal carrier_csr_ctrl_led_green_int : std_logic ;
signal carrier_csr_ctrl_led_red_int : std_logic ;
signal carrier_csr_ctrl_dac_clr_n_int : std_logic ;
signal carrier_csr_rst_fmc0_int : std_logic ;
signal ack_sreg : std_logic_vector(9 downto 0);
signal rddata_reg : std_logic_vector(31 downto 0);
signal wrdata_reg : std_logic_vector(31 downto 0);
signal bwsel_reg : std_logic_vector(3 downto 0);
signal rwaddr_reg : std_logic_vector(1 downto 0);
signal ack_in_progress : std_logic ;
signal wr_int : std_logic ;
signal rd_int : std_logic ;
signal allones : std_logic_vector(31 downto 0);
signal allzeros : std_logic_vector(31 downto 0);
begin
-- Some internal signals assignments
wrdata_reg <= wb_dat_i;
--
-- Main register bank access process.
process (clk_sys_i, rst_n_i)
begin
if (rst_n_i = '0') then
ack_sreg <= "0000000000";
ack_in_progress <= '0';
rddata_reg <= "00000000000000000000000000000000";
carrier_csr_ctrl_led_green_int <= '0';
carrier_csr_ctrl_led_red_int <= '0';
carrier_csr_ctrl_dac_clr_n_int <= '0';
carrier_csr_rst_fmc0_int <= '0';
elsif rising_edge(clk_sys_i) then
-- advance the ACK generator shift register
ack_sreg(8 downto 0) <= ack_sreg(9 downto 1);
ack_sreg(9) <= '0';
if (ack_in_progress = '1') then
if (ack_sreg(0) = '1') then
ack_in_progress <= '0';
else
end if;
else
if ((wb_cyc_i = '1') and (wb_stb_i = '1')) then
case rwaddr_reg(1 downto 0) is
when "00" =>
if (wb_we_i = '1') then
end if;
rddata_reg(3 downto 0) <= regs_i.carrier_pcb_rev_i;
rddata_reg(15 downto 4) <= regs_i.carrier_reserved_i;
rddata_reg(31 downto 16) <= regs_i.carrier_type_i;
ack_sreg(0) <= '1';
ack_in_progress <= '1';
when "01" =>
if (wb_we_i = '1') then
end if;
rddata_reg(0) <= regs_i.stat_fmc_pres_i;
rddata_reg(1) <= regs_i.stat_p2l_pll_lck_i;
rddata_reg(2) <= regs_i.stat_sys_pll_lck_i;
rddata_reg(3) <= regs_i.stat_ddr3_cal_done_i;
rddata_reg(4) <= 'X';
rddata_reg(5) <= 'X';
rddata_reg(6) <= 'X';
rddata_reg(7) <= 'X';
rddata_reg(8) <= 'X';
rddata_reg(9) <= 'X';
rddata_reg(10) <= 'X';
rddata_reg(11) <= 'X';
rddata_reg(12) <= 'X';
rddata_reg(13) <= 'X';
rddata_reg(14) <= 'X';
rddata_reg(15) <= 'X';
rddata_reg(16) <= 'X';
rddata_reg(17) <= 'X';
rddata_reg(18) <= 'X';
rddata_reg(19) <= 'X';
rddata_reg(20) <= 'X';
rddata_reg(21) <= 'X';
rddata_reg(22) <= 'X';
rddata_reg(23) <= 'X';
rddata_reg(24) <= 'X';
rddata_reg(25) <= 'X';
rddata_reg(26) <= 'X';
rddata_reg(27) <= 'X';
rddata_reg(28) <= 'X';
rddata_reg(29) <= 'X';
rddata_reg(30) <= 'X';
rddata_reg(31) <= 'X';
ack_sreg(0) <= '1';
ack_in_progress <= '1';
when "10" =>
if (wb_we_i = '1') then
carrier_csr_ctrl_led_green_int <= wrdata_reg(0);
carrier_csr_ctrl_led_red_int <= wrdata_reg(1);
carrier_csr_ctrl_dac_clr_n_int <= wrdata_reg(2);
end if;
rddata_reg(0) <= carrier_csr_ctrl_led_green_int;
rddata_reg(1) <= carrier_csr_ctrl_led_red_int;
rddata_reg(2) <= carrier_csr_ctrl_dac_clr_n_int;
rddata_reg(3) <= 'X';
rddata_reg(4) <= 'X';
rddata_reg(5) <= 'X';
rddata_reg(6) <= 'X';
rddata_reg(7) <= 'X';
rddata_reg(8) <= 'X';
rddata_reg(9) <= 'X';
rddata_reg(10) <= 'X';
rddata_reg(11) <= 'X';
rddata_reg(12) <= 'X';
rddata_reg(13) <= 'X';
rddata_reg(14) <= 'X';
rddata_reg(15) <= 'X';
rddata_reg(16) <= 'X';
rddata_reg(17) <= 'X';
rddata_reg(18) <= 'X';
rddata_reg(19) <= 'X';
rddata_reg(20) <= 'X';
rddata_reg(21) <= 'X';
rddata_reg(22) <= 'X';
rddata_reg(23) <= 'X';
rddata_reg(24) <= 'X';
rddata_reg(25) <= 'X';
rddata_reg(26) <= 'X';
rddata_reg(27) <= 'X';
rddata_reg(28) <= 'X';
rddata_reg(29) <= 'X';
rddata_reg(30) <= 'X';
rddata_reg(31) <= 'X';
ack_sreg(0) <= '1';
ack_in_progress <= '1';
when "11" =>
if (wb_we_i = '1') then
carrier_csr_rst_fmc0_int <= wrdata_reg(0);
end if;
rddata_reg(0) <= carrier_csr_rst_fmc0_int;
rddata_reg(1) <= 'X';
rddata_reg(2) <= 'X';
rddata_reg(3) <= 'X';
rddata_reg(4) <= 'X';
rddata_reg(5) <= 'X';
rddata_reg(6) <= 'X';
rddata_reg(7) <= 'X';
rddata_reg(8) <= 'X';
rddata_reg(9) <= 'X';
rddata_reg(10) <= 'X';
rddata_reg(11) <= 'X';
rddata_reg(12) <= 'X';
rddata_reg(13) <= 'X';
rddata_reg(14) <= 'X';
rddata_reg(15) <= 'X';
rddata_reg(16) <= 'X';
rddata_reg(17) <= 'X';
rddata_reg(18) <= 'X';
rddata_reg(19) <= 'X';
rddata_reg(20) <= 'X';
rddata_reg(21) <= 'X';
rddata_reg(22) <= 'X';
rddata_reg(23) <= 'X';
rddata_reg(24) <= 'X';
rddata_reg(25) <= 'X';
rddata_reg(26) <= 'X';
rddata_reg(27) <= 'X';
rddata_reg(28) <= 'X';
rddata_reg(29) <= 'X';
rddata_reg(30) <= 'X';
rddata_reg(31) <= 'X';
ack_sreg(0) <= '1';
ack_in_progress <= '1';
when others =>
-- prevent the slave from hanging the bus on invalid address
ack_in_progress <= '1';
ack_sreg(0) <= '1';
end case;
end if;
end if;
end if;
end process;
-- Drive the data output bus
wb_dat_o <= rddata_reg;
-- PCB revision
-- Reserved register
-- Carrier type
-- FMC presence
-- GN4142 core P2L PLL status
-- System clock PLL status
-- DDR3 calibration status
-- Green LED
regs_o.ctrl_led_green_o <= carrier_csr_ctrl_led_green_int;
-- Red LED
regs_o.ctrl_led_red_o <= carrier_csr_ctrl_led_red_int;
-- DAC clear
regs_o.ctrl_dac_clr_n_o <= carrier_csr_ctrl_dac_clr_n_int;
-- State of the reset line
regs_o.rst_fmc0_o <= carrier_csr_rst_fmc0_int;
rwaddr_reg <= wb_adr_i;
wb_stall_o <= (not ack_sreg(0)) and (wb_stb_i and wb_cyc_i);
wb_err_o <= '0';
wb_rty_o <= '0';
-- ACK signal generation. Just pass the LSB of ACK counter.
wb_ack_o <= ack_sreg(0);
end syn;
carrier_csr_wbgen2_pkg.vhd 0000664 0000000 0000000 00000007507 13460261316 0032070 0 ustar 00root root 0000000 0000000 wrtd-53772dc3cd49421ea1fa6326a199b7a72dc04d18/hdl/top/wrtd_ref_spec150t_adc ---------------------------------------------------------------------------------------
-- Title : Wishbone slave core for Carrier control and status registers
---------------------------------------------------------------------------------------
-- File : ../carrier_csr_wbgen2_pkg.vhd
-- Author : auto-generated by wbgen2 from carrier_csr.wb
-- Created : Wed Jan 30 13:16:24 2019
-- Standard : VHDL'87
---------------------------------------------------------------------------------------
-- THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE carrier_csr.wb
-- DO NOT HAND-EDIT UNLESS IT'S ABSOLUTELY NECESSARY!
---------------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
package carrier_csr_wbgen2_pkg is
-- Input registers (user design -> WB slave)
type t_carrier_csr_in_registers is record
carrier_pcb_rev_i : std_logic_vector(3 downto 0);
carrier_reserved_i : std_logic_vector(11 downto 0);
carrier_type_i : std_logic_vector(15 downto 0);
stat_fmc_pres_i : std_logic;
stat_p2l_pll_lck_i : std_logic;
stat_sys_pll_lck_i : std_logic;
stat_ddr3_cal_done_i : std_logic;
end record;
constant c_carrier_csr_in_registers_init_value: t_carrier_csr_in_registers := (
carrier_pcb_rev_i => (others => '0'),
carrier_reserved_i => (others => '0'),
carrier_type_i => (others => '0'),
stat_fmc_pres_i => '0',
stat_p2l_pll_lck_i => '0',
stat_sys_pll_lck_i => '0',
stat_ddr3_cal_done_i => '0'
);
-- Output registers (WB slave -> user design)
type t_carrier_csr_out_registers is record
ctrl_led_green_o : std_logic;
ctrl_led_red_o : std_logic;
ctrl_dac_clr_n_o : std_logic;
rst_fmc0_o : std_logic;
end record;
constant c_carrier_csr_out_registers_init_value: t_carrier_csr_out_registers := (
ctrl_led_green_o => '0',
ctrl_led_red_o => '0',
ctrl_dac_clr_n_o => '0',
rst_fmc0_o => '0'
);
function "or" (left, right: t_carrier_csr_in_registers) return t_carrier_csr_in_registers;
function f_x_to_zero (x:std_logic) return std_logic;
function f_x_to_zero (x:std_logic_vector) return std_logic_vector;
end package;
package body carrier_csr_wbgen2_pkg is
function f_x_to_zero (x:std_logic) return std_logic is
begin
if x = '1' then
return '1';
else
return '0';
end if;
end function;
function f_x_to_zero (x:std_logic_vector) return std_logic_vector is
variable tmp: std_logic_vector(x'length-1 downto 0);
begin
for i in 0 to x'length-1 loop
if(x(i) = '1') then
tmp(i):= '1';
else
tmp(i):= '0';
end if;
end loop;
return tmp;
end function;
function "or" (left, right: t_carrier_csr_in_registers) return t_carrier_csr_in_registers is
variable tmp: t_carrier_csr_in_registers;
begin
tmp.carrier_pcb_rev_i := f_x_to_zero(left.carrier_pcb_rev_i) or f_x_to_zero(right.carrier_pcb_rev_i);
tmp.carrier_reserved_i := f_x_to_zero(left.carrier_reserved_i) or f_x_to_zero(right.carrier_reserved_i);
tmp.carrier_type_i := f_x_to_zero(left.carrier_type_i) or f_x_to_zero(right.carrier_type_i);
tmp.stat_fmc_pres_i := f_x_to_zero(left.stat_fmc_pres_i) or f_x_to_zero(right.stat_fmc_pres_i);
tmp.stat_p2l_pll_lck_i := f_x_to_zero(left.stat_p2l_pll_lck_i) or f_x_to_zero(right.stat_p2l_pll_lck_i);
tmp.stat_sys_pll_lck_i := f_x_to_zero(left.stat_sys_pll_lck_i) or f_x_to_zero(right.stat_sys_pll_lck_i);
tmp.stat_ddr3_cal_done_i := f_x_to_zero(left.stat_ddr3_cal_done_i) or f_x_to_zero(right.stat_ddr3_cal_done_i);
return tmp;
end function;
end package body;
wrtd-53772dc3cd49421ea1fa6326a199b7a72dc04d18/hdl/top/wrtd_ref_spec150t_adc/dma_eic.vhd 0000664 0000000 0000000 00000030113 13460261316 0027112 0 ustar 00root root 0000000 0000000 ---------------------------------------------------------------------------------------
-- Title : Wishbone slave core for GN4124 DMA enhanced interrupt controller
---------------------------------------------------------------------------------------
-- File : ../dma_eic.vhd
-- Author : auto-generated by wbgen2 from dma_eic.wb
-- Created : Wed Jan 30 13:16:24 2019
-- Standard : VHDL'87
---------------------------------------------------------------------------------------
-- THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE dma_eic.wb
-- DO NOT HAND-EDIT UNLESS IT'S ABSOLUTELY NECESSARY!
---------------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.wbgen2_pkg.all;
entity dma_eic is
port (
rst_n_i : in std_logic;
clk_sys_i : in std_logic;
wb_adr_i : in std_logic_vector(1 downto 0);
wb_dat_i : in std_logic_vector(31 downto 0);
wb_dat_o : out std_logic_vector(31 downto 0);
wb_cyc_i : in std_logic;
wb_sel_i : in std_logic_vector(3 downto 0);
wb_stb_i : in std_logic;
wb_we_i : in std_logic;
wb_ack_o : out std_logic;
wb_err_o : out std_logic;
wb_rty_o : out std_logic;
wb_stall_o : out std_logic;
wb_int_o : out std_logic;
irq_dma_done_i : in std_logic;
irq_dma_error_i : in std_logic
);
end dma_eic;
architecture syn of dma_eic is
signal eic_idr_int : std_logic_vector(1 downto 0);
signal eic_idr_write_int : std_logic ;
signal eic_ier_int : std_logic_vector(1 downto 0);
signal eic_ier_write_int : std_logic ;
signal eic_imr_int : std_logic_vector(1 downto 0);
signal eic_isr_clear_int : std_logic_vector(1 downto 0);
signal eic_isr_status_int : std_logic_vector(1 downto 0);
signal eic_irq_ack_int : std_logic_vector(1 downto 0);
signal eic_isr_write_int : std_logic ;
signal irq_inputs_vector_int : std_logic_vector(1 downto 0);
signal ack_sreg : std_logic_vector(9 downto 0);
signal rddata_reg : std_logic_vector(31 downto 0);
signal wrdata_reg : std_logic_vector(31 downto 0);
signal bwsel_reg : std_logic_vector(3 downto 0);
signal rwaddr_reg : std_logic_vector(1 downto 0);
signal ack_in_progress : std_logic ;
signal wr_int : std_logic ;
signal rd_int : std_logic ;
signal allones : std_logic_vector(31 downto 0);
signal allzeros : std_logic_vector(31 downto 0);
begin
-- Some internal signals assignments
wrdata_reg <= wb_dat_i;
--
-- Main register bank access process.
process (clk_sys_i, rst_n_i)
begin
if (rst_n_i = '0') then
ack_sreg <= "0000000000";
ack_in_progress <= '0';
rddata_reg <= "00000000000000000000000000000000";
eic_idr_write_int <= '0';
eic_ier_write_int <= '0';
eic_isr_write_int <= '0';
elsif rising_edge(clk_sys_i) then
-- advance the ACK generator shift register
ack_sreg(8 downto 0) <= ack_sreg(9 downto 1);
ack_sreg(9) <= '0';
if (ack_in_progress = '1') then
if (ack_sreg(0) = '1') then
eic_idr_write_int <= '0';
eic_ier_write_int <= '0';
eic_isr_write_int <= '0';
ack_in_progress <= '0';
else
end if;
else
if ((wb_cyc_i = '1') and (wb_stb_i = '1')) then
case rwaddr_reg(1 downto 0) is
when "00" =>
if (wb_we_i = '1') then
eic_idr_write_int <= '1';
end if;
rddata_reg(0) <= 'X';
rddata_reg(1) <= 'X';
rddata_reg(2) <= 'X';
rddata_reg(3) <= 'X';
rddata_reg(4) <= 'X';
rddata_reg(5) <= 'X';
rddata_reg(6) <= 'X';
rddata_reg(7) <= 'X';
rddata_reg(8) <= 'X';
rddata_reg(9) <= 'X';
rddata_reg(10) <= 'X';
rddata_reg(11) <= 'X';
rddata_reg(12) <= 'X';
rddata_reg(13) <= 'X';
rddata_reg(14) <= 'X';
rddata_reg(15) <= 'X';
rddata_reg(16) <= 'X';
rddata_reg(17) <= 'X';
rddata_reg(18) <= 'X';
rddata_reg(19) <= 'X';
rddata_reg(20) <= 'X';
rddata_reg(21) <= 'X';
rddata_reg(22) <= 'X';
rddata_reg(23) <= 'X';
rddata_reg(24) <= 'X';
rddata_reg(25) <= 'X';
rddata_reg(26) <= 'X';
rddata_reg(27) <= 'X';
rddata_reg(28) <= 'X';
rddata_reg(29) <= 'X';
rddata_reg(30) <= 'X';
rddata_reg(31) <= 'X';
ack_sreg(0) <= '1';
ack_in_progress <= '1';
when "01" =>
if (wb_we_i = '1') then
eic_ier_write_int <= '1';
end if;
rddata_reg(0) <= 'X';
rddata_reg(1) <= 'X';
rddata_reg(2) <= 'X';
rddata_reg(3) <= 'X';
rddata_reg(4) <= 'X';
rddata_reg(5) <= 'X';
rddata_reg(6) <= 'X';
rddata_reg(7) <= 'X';
rddata_reg(8) <= 'X';
rddata_reg(9) <= 'X';
rddata_reg(10) <= 'X';
rddata_reg(11) <= 'X';
rddata_reg(12) <= 'X';
rddata_reg(13) <= 'X';
rddata_reg(14) <= 'X';
rddata_reg(15) <= 'X';
rddata_reg(16) <= 'X';
rddata_reg(17) <= 'X';
rddata_reg(18) <= 'X';
rddata_reg(19) <= 'X';
rddata_reg(20) <= 'X';
rddata_reg(21) <= 'X';
rddata_reg(22) <= 'X';
rddata_reg(23) <= 'X';
rddata_reg(24) <= 'X';
rddata_reg(25) <= 'X';
rddata_reg(26) <= 'X';
rddata_reg(27) <= 'X';
rddata_reg(28) <= 'X';
rddata_reg(29) <= 'X';
rddata_reg(30) <= 'X';
rddata_reg(31) <= 'X';
ack_sreg(0) <= '1';
ack_in_progress <= '1';
when "10" =>
if (wb_we_i = '1') then
end if;
rddata_reg(1 downto 0) <= eic_imr_int(1 downto 0);
rddata_reg(2) <= 'X';
rddata_reg(3) <= 'X';
rddata_reg(4) <= 'X';
rddata_reg(5) <= 'X';
rddata_reg(6) <= 'X';
rddata_reg(7) <= 'X';
rddata_reg(8) <= 'X';
rddata_reg(9) <= 'X';
rddata_reg(10) <= 'X';
rddata_reg(11) <= 'X';
rddata_reg(12) <= 'X';
rddata_reg(13) <= 'X';
rddata_reg(14) <= 'X';
rddata_reg(15) <= 'X';
rddata_reg(16) <= 'X';
rddata_reg(17) <= 'X';
rddata_reg(18) <= 'X';
rddata_reg(19) <= 'X';
rddata_reg(20) <= 'X';
rddata_reg(21) <= 'X';
rddata_reg(22) <= 'X';
rddata_reg(23) <= 'X';
rddata_reg(24) <= 'X';
rddata_reg(25) <= 'X';
rddata_reg(26) <= 'X';
rddata_reg(27) <= 'X';
rddata_reg(28) <= 'X';
rddata_reg(29) <= 'X';
rddata_reg(30) <= 'X';
rddata_reg(31) <= 'X';
ack_sreg(0) <= '1';
ack_in_progress <= '1';
when "11" =>
if (wb_we_i = '1') then
eic_isr_write_int <= '1';
end if;
rddata_reg(1 downto 0) <= eic_isr_status_int(1 downto 0);
rddata_reg(2) <= 'X';
rddata_reg(3) <= 'X';
rddata_reg(4) <= 'X';
rddata_reg(5) <= 'X';
rddata_reg(6) <= 'X';
rddata_reg(7) <= 'X';
rddata_reg(8) <= 'X';
rddata_reg(9) <= 'X';
rddata_reg(10) <= 'X';
rddata_reg(11) <= 'X';
rddata_reg(12) <= 'X';
rddata_reg(13) <= 'X';
rddata_reg(14) <= 'X';
rddata_reg(15) <= 'X';
rddata_reg(16) <= 'X';
rddata_reg(17) <= 'X';
rddata_reg(18) <= 'X';
rddata_reg(19) <= 'X';
rddata_reg(20) <= 'X';
rddata_reg(21) <= 'X';
rddata_reg(22) <= 'X';
rddata_reg(23) <= 'X';
rddata_reg(24) <= 'X';
rddata_reg(25) <= 'X';
rddata_reg(26) <= 'X';
rddata_reg(27) <= 'X';
rddata_reg(28) <= 'X';
rddata_reg(29) <= 'X';
rddata_reg(30) <= 'X';
rddata_reg(31) <= 'X';
ack_sreg(0) <= '1';
ack_in_progress <= '1';
when others =>
-- prevent the slave from hanging the bus on invalid address
ack_in_progress <= '1';
ack_sreg(0) <= '1';
end case;
end if;
end if;
end if;
end process;
-- Drive the data output bus
wb_dat_o <= rddata_reg;
-- extra code for reg/fifo/mem: Interrupt disable register
eic_idr_int(1 downto 0) <= wrdata_reg(1 downto 0);
-- extra code for reg/fifo/mem: Interrupt enable register
eic_ier_int(1 downto 0) <= wrdata_reg(1 downto 0);
-- extra code for reg/fifo/mem: Interrupt status register
eic_isr_clear_int(1 downto 0) <= wrdata_reg(1 downto 0);
-- extra code for reg/fifo/mem: IRQ_CONTROLLER
eic_irq_controller_inst : wbgen2_eic
generic map (
g_num_interrupts => 2,
g_irq00_mode => 0,
g_irq01_mode => 0,
g_irq02_mode => 0,
g_irq03_mode => 0,
g_irq04_mode => 0,
g_irq05_mode => 0,
g_irq06_mode => 0,
g_irq07_mode => 0,
g_irq08_mode => 0,
g_irq09_mode => 0,
g_irq0a_mode => 0,
g_irq0b_mode => 0,
g_irq0c_mode => 0,
g_irq0d_mode => 0,
g_irq0e_mode => 0,
g_irq0f_mode => 0,
g_irq10_mode => 0,
g_irq11_mode => 0,
g_irq12_mode => 0,
g_irq13_mode => 0,
g_irq14_mode => 0,
g_irq15_mode => 0,
g_irq16_mode => 0,
g_irq17_mode => 0,
g_irq18_mode => 0,
g_irq19_mode => 0,
g_irq1a_mode => 0,
g_irq1b_mode => 0,
g_irq1c_mode => 0,
g_irq1d_mode => 0,
g_irq1e_mode => 0,
g_irq1f_mode => 0
)
port map (
clk_i => clk_sys_i,
rst_n_i => rst_n_i,
irq_i => irq_inputs_vector_int,
irq_ack_o => eic_irq_ack_int,
reg_imr_o => eic_imr_int,
reg_ier_i => eic_ier_int,
reg_ier_wr_stb_i => eic_ier_write_int,
reg_idr_i => eic_idr_int,
reg_idr_wr_stb_i => eic_idr_write_int,
reg_isr_o => eic_isr_status_int,
reg_isr_i => eic_isr_clear_int,
reg_isr_wr_stb_i => eic_isr_write_int,
wb_irq_o => wb_int_o
);
irq_inputs_vector_int(0) <= irq_dma_done_i;
irq_inputs_vector_int(1) <= irq_dma_error_i;
rwaddr_reg <= wb_adr_i;
wb_stall_o <= (not ack_sreg(0)) and (wb_stb_i and wb_cyc_i);
wb_err_o <= '0';
wb_rty_o <= '0';
-- ACK signal generation. Just pass the LSB of ACK counter.
wb_ack_o <= ack_sreg(0);
end syn;
wrtd-53772dc3cd49421ea1fa6326a199b7a72dc04d18/hdl/top/wrtd_ref_spec150t_adc/wb_gen/ 0000775 0000000 0000000 00000000000 13460261316 0026271 5 ustar 00root root 0000000 0000000 wrtd-53772dc3cd49421ea1fa6326a199b7a72dc04d18/hdl/top/wrtd_ref_spec150t_adc/wb_gen/.gitignore 0000664 0000000 0000000 00000000036 13460261316 0030260 0 ustar 00root root 0000000 0000000 *
!.gitignore
!*.wb
!Makefile
wrtd-53772dc3cd49421ea1fa6326a199b7a72dc04d18/hdl/top/wrtd_ref_spec150t_adc/wb_gen/Makefile 0000664 0000000 0000000 00000000325 13460261316 0027731 0 ustar 00root root 0000000 0000000 WBGEN2 = $(shell which wbgen2)
RTL = ..
all: carrier_csr dma_eic
carrier_csr:
$(WBGEN2) -l vhdl -H record -V $(RTL)/$@.vhd -p $(RTL)/$@_wbgen2_pkg.vhd $@.wb
dma_eic:
$(WBGEN2) -l vhdl -V $(RTL)/$@.vhd $@.wb
wrtd-53772dc3cd49421ea1fa6326a199b7a72dc04d18/hdl/top/wrtd_ref_spec150t_adc/wb_gen/carrier_csr.wb 0000664 0000000 0000000 00000006201 13460261316 0031120 0 ustar 00root root 0000000 0000000 peripheral {
name = "Carrier control and status registers";
description = "Wishbone slave for control and status registers related to the FMC carrier";
hdl_entity = "carrier_csr";
prefix = "carrier_csr";
reg {
name = "Carrier type and PCB version";
prefix = "carrier";
field {
name = "PCB revision";
description = "Binary coded PCB layout revision.";
prefix = "pcb_rev";
type = SLV;
size = 4;
access_bus = READ_ONLY;
access_dev = WRITE_ONLY;
};
field {
name = "Reserved register";
description = "Ignore on read, write with 0's.";
prefix = "reserved";
type = SLV;
size = 12;
access_bus = READ_ONLY;
access_dev = WRITE_ONLY;
};
field {
name = "Carrier type";
description = "Carrier type identifier\n1 = SPEC\n2 = SVEC\n3 = VFC\n4 = SPEXI";
prefix = "type";
type = SLV;
size = 16;
access_bus = READ_ONLY;
access_dev = WRITE_ONLY;
};
};
reg {
name = "Status";
prefix = "stat";
field {
name = "FMC presence";
description = "0: FMC slot is populated\n1: FMC slot is not populated.";
prefix = "fmc_pres";
type = BIT;
access_bus = READ_ONLY;
access_dev = WRITE_ONLY;
};
field {
name = "GN4142 core P2L PLL status";
description = "0: not locked\n1: locked.";
prefix = "p2l_pll_lck";
type = BIT;
access_bus = READ_ONLY;
access_dev = WRITE_ONLY;
};
field {
name = "System clock PLL status";
description = "0: not locked\n1: locked.";
prefix = "sys_pll_lck";
type = BIT;
access_bus = READ_ONLY;
access_dev = WRITE_ONLY;
};
field {
name = "DDR3 calibration status";
description = "0: not done\n1: done.";
prefix = "ddr3_cal_done";
type = BIT;
access_bus = READ_ONLY;
access_dev = WRITE_ONLY;
};
};
reg {
name = "Control";
prefix = "ctrl";
field {
name = "Green LED";
description = "Manual control of the front panel green LED (unused in the fmc-adc application)";
prefix = "led_green";
type = BIT;
access_bus = READ_WRITE;
access_dev = READ_ONLY;
};
field {
name = "Red LED";
description = "Manual control of the front panel red LED (unused in the fmc-adc application)";
prefix = "led_red";
type = BIT;
access_bus = READ_WRITE;
access_dev = READ_ONLY;
};
field {
name = "DAC clear";
description = "Active low clear signal for VCXO DACs";
prefix = "dac_clr_n";
type = BIT;
access_bus = READ_WRITE;
access_dev = READ_ONLY;
};
};
reg {
name = "Reset Register";
prefix = "rst";
description = "Controls software reset of the mezzanine including the ddr interface and the time-tagging core.";
field {
name = "State of the reset line";
description = "write 0: Normal FMC operation\
write 1: FMC is held in reset";
type = BIT;
size = 1;
prefix = "fmc0";
access_bus = WRITE;
access_dev = READ;
};
};
};
wrtd-53772dc3cd49421ea1fa6326a199b7a72dc04d18/hdl/top/wrtd_ref_spec150t_adc/wb_gen/dma_eic.wb 0000664 0000000 0000000 00000001067 13460261316 0030210 0 ustar 00root root 0000000 0000000 peripheral {
name = "GN4124 DMA enhanced interrupt controller";
description = "Enhanced interrrupt controller for GN4124 DMA.";
hdl_entity = "dma_eic";
prefix = "dma_eic";
irq {
name = "DMA done interrupt";
description = "DMA done interrupt line (rising edge sensitive).";
prefix = "dma_done";
trigger = EDGE_RISING;
};
irq {
name = "DMA error interrupt";
description = "DMA error interrupt line (rising edge sensitive).";
prefix = "dma_error";
trigger = EDGE_RISING;
};
};
wrtd_ref_spec150t_adc.vhd 0000664 0000000 0000000 00000126052 13460261316 0031531 0 ustar 00root root 0000000 0000000 wrtd-53772dc3cd49421ea1fa6326a199b7a72dc04d18/hdl/top/wrtd_ref_spec150t_adc --------------------------------------------------------------------------------
-- CERN BE-CO-HT
-- White Rabbit Trigger Distribution (WRTD)
-- https://ohwr.org/projects/wrtd
--------------------------------------------------------------------------------
--
-- unit name: wrtd_ref_spec150t_adc
--
-- description: Top entity for WRTD reference design.
--
-- Top level design of the SPEC150T-based FMC ADC WRTD node. The WRTD-enabled
-- FMC ADC is capable of triggering on WRTD messages, as well as to generate
-- WRTD messages as a result of another trigger (internal, external, etc.)
--
--------------------------------------------------------------------------------
-- Copyright CERN 2018-2019
--------------------------------------------------------------------------------
-- Copyright and related rights are licensed under the Solderpad Hardware
-- License, Version 2.0 (the "License"); you may not use this file except
-- in compliance with the License. You may obtain a copy of the License at
-- http://solderpad.org/licenses/SHL-2.0.
-- Unless required by applicable law or agreed to in writing, software,
-- hardware and materials distributed under this License is distributed on an
-- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
-- or implied. See the License for the specific language governing permissions
-- and limitations under the License.
--------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
library work;
use work.gencores_pkg.all;
use work.wishbone_pkg.all;
use work.gn4124_core_pkg.all;
use work.carrier_csr_wbgen2_pkg.all;
use work.mt_mqueue_pkg.all;
use work.mock_turtle_pkg.all;
use work.synthesis_descriptor.all;
use work.wr_xilinx_pkg.all;
use work.wr_board_pkg.all;
use work.wr_spec_pkg.all;
use work.wr_fabric_pkg.all;
use work.fmc_adc_mezzanine_pkg.all;
use work.ddr3_ctrl_pkg.all;
entity wrtd_ref_spec150t_adc is
generic (
g_WRPC_INITF : string := "../../../dependencies/wr-cores/bin/wrpc/wrc_phy8.bram";
g_MT_CPU0_INITF : string := "../../../software/firmware/adc/wrtd-rt-adc.bram";
-- Simulation-mode enable parameter. Set by default (synthesis) to 0, and
-- changed to non-zero in the instantiation of the top level DUT in the
-- testbench. Its purpose is to reduce some internal counters/timeouts
-- to speed up simulations.
g_SIMULATION : integer := 0);
port (
-- Reset button
button1_n_i : in std_logic;
-- Local oscillators
clk_20m_vcxo_i : in std_logic; -- 20MHz VCXO clock
clk_125m_pllref_p_i : in std_logic; -- 125 MHz PLL reference
clk_125m_pllref_n_i : in std_logic;
clk_125m_gtp_n_i : in std_logic; -- 125 MHz GTP reference
clk_125m_gtp_p_i : in std_logic;
-- DAC interface (20MHz and 25MHz VCXO)
pll25dac_sync_n_o : out std_logic; -- 25MHz VCXO
pll20dac_sync_n_o : out std_logic; -- 20MHz VCXO
plldac_din_o : out std_logic;
plldac_sclk_o : out std_logic;
-- Carrier front panel LEDs
led_sfp_red_o : out std_logic;
led_sfp_green_o : out std_logic;
-- Auxiliary pins
aux_leds_o : out std_logic_vector(3 downto 0);
-- PCB version
pcbrev_i : in std_logic_vector(3 downto 0);
-- Carrier 1-wire interface (DS18B20 thermometer + unique ID)
carrier_onewire_b : inout std_logic;
-- SFP
sfp_txp_o : out std_logic;
sfp_txn_o : out std_logic;
sfp_rxp_i : in std_logic;
sfp_rxn_i : in std_logic;
sfp_mod_def0_i : in std_logic; -- sfp detect
sfp_mod_def1_b : inout std_logic; -- scl
sfp_mod_def2_b : inout std_logic; -- sda
sfp_rate_select_o : out std_logic;
sfp_tx_fault_i : in std_logic;
sfp_tx_disable_o : out std_logic;
sfp_los_i : in std_logic;
-- SPI
spi_sclk_o : out std_logic;
spi_ncs_o : out std_logic;
spi_mosi_o : out std_logic;
spi_miso_i : in std_logic := 'L';
-- UART
uart_rxd_i : in std_logic;
uart_txd_o : out std_logic;
------------------------------------------
-- GN4124 interface
--
-- gn_gpio_b[0] -> AB19 -> GN4124 GPIO9
-- gn_gpio_b[1] -> U16 -> GN4124 GPIO8
------------------------------------------
gn_rst_n_i : in std_logic;
gn_p2l_clk_n_i : in std_logic;
gn_p2l_clk_p_i : in std_logic;
gn_p2l_rdy_o : out std_logic;
gn_p2l_dframe_i : in std_logic;
gn_p2l_valid_i : in std_logic;
gn_p2l_data_i : in std_logic_vector(15 downto 0);
gn_p_wr_req_i : in std_logic_vector(1 downto 0);
gn_p_wr_rdy_o : out std_logic_vector(1 downto 0);
gn_rx_error_o : out std_logic;
gn_l2p_clk_n_o : out std_logic;
gn_l2p_clk_p_o : out std_logic;
gn_l2p_dframe_o : out std_logic;
gn_l2p_valid_o : out std_logic;
gn_l2p_edb_o : out std_logic;
gn_l2p_data_o : out std_logic_vector(15 downto 0);
gn_l2p_rdy_i : in std_logic;
gn_l_wr_rdy_i : in std_logic_vector(1 downto 0);
gn_p_rd_d_rdy_i : in std_logic_vector(1 downto 0);
gn_tx_error_i : in std_logic;
gn_vc_rdy_i : in std_logic_vector(1 downto 0);
gn_gpio_b : inout std_logic_vector(1 downto 0);
------------------------------------------
-- DDR (bank 3)
------------------------------------------
ddr0_a_o : out std_logic_vector(13 downto 0);
ddr0_ba_o : out std_logic_vector(2 downto 0);
ddr0_cas_n_o : out std_logic;
ddr0_ck_n_o : out std_logic;
ddr0_ck_p_o : out std_logic;
ddr0_cke_o : out std_logic;
ddr0_dq_b : inout std_logic_vector(15 downto 0);
ddr0_ldm_o : out std_logic;
ddr0_ldqs_n_b : inout std_logic;
ddr0_ldqs_p_b : inout std_logic;
ddr0_odt_o : out std_logic;
ddr0_ras_n_o : out std_logic;
ddr0_reset_n_o : out std_logic;
ddr0_rzq_b : inout std_logic;
ddr0_udm_o : out std_logic;
ddr0_udqs_n_b : inout std_logic;
ddr0_udqs_p_b : inout std_logic;
ddr0_we_n_o : out std_logic;
------------------------------------------
-- FMC slots
------------------------------------------
fmc0_adc_ext_trigger_p_i : in std_logic; -- External trigger
fmc0_adc_ext_trigger_n_i : in std_logic;
fmc0_adc_dco_p_i : in std_logic; -- ADC data clock
fmc0_adc_dco_n_i : in std_logic;
fmc0_adc_fr_p_i : in std_logic; -- ADC frame start
fmc0_adc_fr_n_i : in std_logic;
fmc0_adc_outa_p_i : in std_logic_vector(3 downto 0); -- ADC serial data (odd bits)
fmc0_adc_outa_n_i : in std_logic_vector(3 downto 0);
fmc0_adc_outb_p_i : in std_logic_vector(3 downto 0); -- ADC serial data (even bits)
fmc0_adc_outb_n_i : in std_logic_vector(3 downto 0);
fmc0_adc_spi_din_i : in std_logic; -- SPI data from FMC
fmc0_adc_spi_dout_o : out std_logic; -- SPI data to FMC
fmc0_adc_spi_sck_o : out std_logic; -- SPI clock
fmc0_adc_spi_cs_adc_n_o : out std_logic; -- SPI ADC chip select (active low)
fmc0_adc_spi_cs_dac1_n_o : out std_logic; -- SPI channel 1 offset DAC chip select (active low)
fmc0_adc_spi_cs_dac2_n_o : out std_logic; -- SPI channel 2 offset DAC chip select (active low)
fmc0_adc_spi_cs_dac3_n_o : out std_logic; -- SPI channel 3 offset DAC chip select (active low)
fmc0_adc_spi_cs_dac4_n_o : out std_logic; -- SPI channel 4 offset DAC chip select (active low)
fmc0_adc_gpio_dac_clr_n_o : out std_logic; -- offset DACs clear (active low)
fmc0_adc_gpio_led_acq_o : out std_logic; -- Mezzanine front panel power LED (PWR)
fmc0_adc_gpio_led_trig_o : out std_logic; -- Mezzanine front panel trigger LED (TRIG)
fmc0_adc_gpio_ssr_ch1_o : out std_logic_vector(6 downto 0); -- Channel 1 solid state relays control
fmc0_adc_gpio_ssr_ch2_o : out std_logic_vector(6 downto 0); -- Channel 2 solid state relays control
fmc0_adc_gpio_ssr_ch3_o : out std_logic_vector(6 downto 0); -- Channel 3 solid state relays control
fmc0_adc_gpio_ssr_ch4_o : out std_logic_vector(6 downto 0); -- Channel 4 solid state relays control
fmc0_adc_gpio_si570_oe_o : out std_logic; -- Si570 (programmable oscillator) output enable
fmc0_adc_si570_scl_b : inout std_logic; -- I2C bus clock (Si570)
fmc0_adc_si570_sda_b : inout std_logic; -- I2C bus data (Si570)
fmc0_adc_one_wire_b : inout std_logic; -- Mezzanine 1-wire interface (DS18B20 thermometer + unique ID)
-- FMC slot management
fmc0_prsnt_m2c_n_i : in std_logic;
fmc0_scl_b : inout std_logic;
fmc0_sda_b : inout std_logic);
end entity wrtd_ref_spec150t_adc;
architecture arch of wrtd_ref_spec150t_adc is
-----------------------------------------------------------------------------
-- Constants
-----------------------------------------------------------------------------
-- WRPC Xilinx platform auxiliary clock configuration, used for DDR clock
constant c_WRPC_PLL_CONFIG : t_px_pll_cfg := (
enabled => TRUE, divide => 3, multiply => 8 );
-- SPEC carrier CSR constants
constant c_CARRIER_TYPE : std_logic_vector(15 downto 0) := X"0001";
-- Number of masters attached to the primary wishbone crossbar
constant c_NUM_WB_MASTERS : integer := 1;
-- Number of slaves attached to the primary wishbone crossbar
constant c_NUM_WB_SLAVES : integer := 3 + 4;
-- Primary Wishbone master(s) offsets
constant c_WB_MASTER_GENNUM : integer := 0;
-- Primary Wishbone slave(s) offsets
constant c_WB_SLAVE_SPEC_CSR : integer := 0;
constant c_WB_SLAVE_VIC : integer := 1;
constant c_WB_SLAVE_BASE : integer := 2;
constant c_WB_SLAVE_DMA : integer := c_WB_SLAVE_BASE + 0;
constant c_WB_SLAVE_DMA_EIC : integer := c_WB_SLAVE_BASE + 1;
constant c_WB_SLAVE_FMC_ADC : integer := c_WB_SLAVE_BASE + 2;
constant c_WB_SLAVE_MT : integer := c_WB_SLAVE_BASE + 0 + 3;
constant c_WB_SLAVE_WRC : integer := c_WB_SLAVE_BASE + 1 + 3;
constant c_WB_DESC_SYN : integer := c_WB_SLAVE_BASE + 2 + 3;
constant c_WB_DESC_URL : integer := c_WB_SLAVE_BASE + 3 + 3;
-- sdb header address on primary crossbar
constant c_SDB_ADDRESS : t_wishbone_address := x"00000000";
-- f_xwb_bridge_manual_sdb(size, sdb_addr)
-- Note: sdb_addr is the sdb records address relative to the bridge base address
constant c_wrc_bridge_sdb : t_sdb_bridge :=
f_xwb_bridge_manual_sdb(x"0003ffff", x"00030000");
constant c_WB_SPEC_CSR_SDB : t_sdb_device := (
abi_class => x"0000", -- undocumented device
abi_ver_major => x"01",
abi_ver_minor => x"01",
wbd_endian => c_SDB_ENDIAN_BIG,
wbd_width => x"4", -- 32-bit port granularity
sdb_component => (
addr_first => x"0000000000000000",
addr_last => x"000000000000001F",
product => (
vendor_id => x"000000000000CE42", -- CERN
device_id => x"00000603",
version => x"00000001",
date => x"20121116",
name => "WB-SPEC-CSR ")));
constant c_FMC_BRIDGE_SDB : t_sdb_bridge := f_xwb_bridge_manual_sdb(x"00001fff", x"00000000");
constant c_WB_DMA_CTRL_SDB : t_sdb_device := (
abi_class => x"0000", -- undocumented device
abi_ver_major => x"01",
abi_ver_minor => x"01",
wbd_endian => c_SDB_ENDIAN_BIG,
wbd_width => x"4", -- 32-bit port granularity
sdb_component => (
addr_first => x"0000000000000000",
addr_last => x"000000000000003F",
product => (
vendor_id => x"000000000000CE42", -- CERN
device_id => x"00000601",
version => x"00000001",
date => x"20121116",
name => "WB-DMA.Control ")));
constant c_WB_DMA_EIC_SDB : t_sdb_device := (
abi_class => x"0000", -- undocumented device
abi_ver_major => x"01",
abi_ver_minor => x"01",
wbd_endian => c_SDB_ENDIAN_BIG,
wbd_width => x"4", -- 32-bit port granularity
sdb_component => (
addr_first => x"0000000000000000",
addr_last => x"000000000000000F",
product => (
vendor_id => x"000000000000CE42", -- CERN
device_id => x"d5735ab4", -- echo "WB-DMA.EIC " | md5sum | cut -c1-8
version => x"00000001",
date => x"20131204",
name => "WB-DMA.EIC ")));
-- Primary wishbone crossbar layout
constant c_WB_LAYOUT : t_sdb_record_array(c_NUM_WB_SLAVES + 1 downto 0) := (
c_WB_SLAVE_SPEC_CSR => f_sdb_embed_device(c_WB_SPEC_CSR_SDB, x"00001000"),
c_WB_SLAVE_VIC => f_sdb_embed_device(c_XWB_VIC_SDB, x"00001200"),
c_WB_SLAVE_DMA => f_sdb_embed_device(c_WB_DMA_CTRL_SDB, x"00002000"),
c_WB_SLAVE_DMA_EIC => f_sdb_embed_device(c_WB_DMA_EIC_SDB, x"00002200"),
c_WB_SLAVE_FMC_ADC => f_sdb_embed_bridge(c_FMC_BRIDGE_SDB, x"00004000"),
c_WB_SLAVE_MT => f_sdb_embed_device(c_MOCK_TURTLE_SDB, x"00020000"),
c_WB_SLAVE_WRC => f_sdb_embed_bridge(c_wrc_bridge_sdb, x"00040000"),
c_WB_DESC_SYN => f_sdb_embed_synthesis(c_SDB_SYNTHESIS_INFO),
c_WB_DESC_URL => f_sdb_embed_repo_url(c_SDB_REPO_URL));
-- not really used, will be reprogrammed by software
constant c_VIC_VECTOR_TABLE : t_wishbone_address_array(0 to 5) := (
0 => x"00005500", -- FMC EIC
1 => x"00002200", -- DMA EIC
2 => x"00020000", -- MT Mqueue in interrupt
3 => x"00020001", -- MT Mqueue out interrupt
4 => x"00020002", -- MT Console interrupt
5 => x"00020003"); -- MT Notify interrupt
constant c_FMC_MUX_ADDR : t_wishbone_address_array(0 downto 0) :=
(0 => x"00000000");
constant c_FMC_MUX_MASK : t_wishbone_address_array(0 downto 0) :=
(0 => x"10000000");
constant c_MT_CONFIG : t_mt_config :=
(
app_id => x"115790d1",
cpu_count => 1,
cpu_config => (
0 => (
memsize => 8192,
hmq_config => (
slot_count => 1,
slot_config => (
0 => (
entries_bits => 4,
width_bits => 7,
header_bits => 2,
endpoint_id => x"0000_0000",
enable_config_space => FALSE),
others => c_DUMMY_MT_MQUEUE_SLOT)),
rmq_config => (
slot_count => 1,
slot_config => (
0 => (
entries_bits => 4,
width_bits => 7,
header_bits => 4,
endpoint_id => x"0000_0000",
enable_config_space => TRUE),
others => c_DUMMY_MT_MQUEUE_SLOT))),
others => (
0, c_MT_DEFAULT_MQUEUE_CONFIG, c_MT_DEFAULT_MQUEUE_CONFIG)),
shared_mem_size => 256
);
-----------------------------------------------------------------------------
-- Signals
-----------------------------------------------------------------------------
-- Clocks and resets
signal clk_sys_62m5 : std_logic;
signal clk_ref_125m : std_logic;
signal sys_clk_pll_locked : std_logic;
signal clk_ddr_333m : std_logic;
signal rst_sys_62m5_n : std_logic := '0';
signal rst_ref_125m_n : std_logic := '0';
signal rst_ddr_333m_n : std_logic := '0';
signal sw_rst_fmc : std_logic := '1';
signal sw_rst_fmc_sync : std_logic := '1';
signal fmc_rst_ref_125m_n : std_logic := '0';
signal fmc_rst_sys_n : std_logic := '0';
signal ddr0_rst : std_logic := '1';
attribute keep : string;
attribute keep of clk_sys_62m5 : signal is "TRUE";
attribute keep of clk_ref_125m : signal is "TRUE";
attribute keep of clk_ddr_333m : signal is "TRUE";
attribute keep of ddr0_rst : signal is "TRUE";
-- GN4124
signal gn4124_status : std_logic_vector(31 downto 0);
signal gn4124_access : std_logic;
-- Wishbone buse(s) from master(s) to crossbar slave port(s)
signal cnx_master_out : t_wishbone_master_out_array(c_NUM_WB_MASTERS-1 downto 0);
signal cnx_master_in : t_wishbone_master_in_array(c_NUM_WB_MASTERS-1 downto 0);
-- Wishbone buse(s) from crossbar master port(s) to slave(s)
signal cnx_slave_out : t_wishbone_slave_out_array(c_NUM_WB_SLAVES-1 downto 0);
signal cnx_slave_in : t_wishbone_slave_in_array(c_NUM_WB_SLAVES-1 downto 0);
-- GN4124 core DMA port to DDR wishbone bus
signal gn_wb_ddr_in : t_wishbone_master_in;
signal gn_wb_ddr_out : t_wishbone_master_out;
-- Interrupts and status
signal dma_irq : std_logic_vector(1 downto 0);
signal fmc_host_irq : std_logic_vector(0 downto 0) := "0";
signal mt_hmq_in_irq : std_logic;
signal mt_hmq_out_irq : std_logic;
signal mt_console_irq : std_logic;
signal mt_notify_irq : std_logic;
signal vic_master_irq : std_logic;
-- Front panel LED control
signal led_red : std_logic;
signal led_green : std_logic;
-- SFP
signal sfp_sda_in : std_logic;
signal sfp_sda_out : std_logic;
signal sfp_scl_in : std_logic;
signal sfp_scl_out : std_logic;
-- OneWire
signal onewire_data : std_logic;
signal onewire_oe : std_logic;
-- LEDs and GPIO
signal pps : std_logic;
signal pps_led : std_logic;
signal pps_ext_in : std_logic;
signal svec_led : std_logic_vector(15 downto 0);
signal wr_led_link : std_logic;
signal wr_led_act : std_logic;
-- MT endpoints
signal rmq_endpoint_out : t_mt_rmq_endpoint_iface_out;
signal rmq_endpoint_in : t_mt_rmq_endpoint_iface_in;
signal rmq_src_in : t_mt_stream_source_in;
signal rmq_src_out : t_mt_stream_source_out;
signal rmq_src_cfg_in : t_mt_stream_config_in;
signal rmq_src_cfg_out : t_mt_stream_config_out;
signal rmq_snk_in : t_mt_stream_sink_in;
signal rmq_snk_out : t_mt_stream_sink_out;
signal rmq_snk_cfg_in : t_mt_stream_config_in;
signal rmq_snk_cfg_out : t_mt_stream_config_out;
-- MT fabric.
signal eth_tx_out : t_wrf_source_out;
signal eth_tx_in : t_wrf_source_in;
signal eth_rx_out : t_wrf_sink_out;
signal eth_rx_in : t_wrf_sink_in;
-- MT Dedicated WB interfaces to FMCs
signal fmc_dp_wb_out : t_wishbone_master_out;
signal fmc_dp_wb_in : t_wishbone_master_in;
-- WRPC TM interface and aux clocks
signal tm_link_up : std_logic;
signal tm_tai : std_logic_vector(39 downto 0);
signal tm_cycles : std_logic_vector(27 downto 0);
signal tm_time_valid : std_logic;
signal tm_clk_aux_lock_en : std_logic_vector(1 downto 0);
signal tm_clk_aux_locked : std_logic_vector(1 downto 0) := "00";
signal tm_dac_value : std_logic_vector(23 downto 0);
signal tm_dac_wr : std_logic_vector(1 downto 0);
signal wrabbit_en : std_logic;
-- MT TM interface
signal tm : t_mt_timing_if;
signal fmc0_scl_out : std_logic := '1';
signal fmc0_sda_out : std_logic := '1';
attribute iob : string;
attribute iob of pps : signal is "FORCE";
-- IO for CSR registers
signal csr_regin : t_carrier_csr_in_registers;
signal csr_regout : t_carrier_csr_out_registers;
constant g_FMC0_MULTISHOT_RAM_SIZE : natural := 2048;
constant g_FMC0_CALIB_SOFT_IP : string := "TRUE";
-- Wishbone bus from cross-clocking module to FMC0 mezzanine
signal cnx_fmc0_sync_master_out : t_wishbone_master_out;
signal cnx_fmc0_sync_master_in : t_wishbone_master_in;
-- Wishbone bus from MT cpus to adc.
signal wb_adc0_trigin_slave_out : t_wishbone_slave_out;
signal wb_adc0_trigin_slave_in : t_wishbone_slave_in;
signal wb_adc0_trigout_slave_out : t_wishbone_slave_out;
signal wb_adc0_trigout_slave_in : t_wishbone_slave_in;
-- Wishbone buses from FMC ADC cores to DDR controller
signal fmc0_wb_ddr_in : t_wishbone_master_data64_in;
signal fmc0_wb_ddr_out : t_wishbone_master_data64_out;
-- Interrupts and status
signal ddr0_wr_fifo_empty : std_logic;
signal ddr0_wr_fifo_empty_sync : std_logic;
signal fmc0_irq : std_logic;
signal tm_time_valid_sync : std_logic;
-- Conversion of g_simulation to string needed for DDR controller
function fmc0_f_int2string (n : natural) return string is
begin
if n = 0 then
return "FALSE";
else
return "TRUE ";
end if;
end;
constant c_FMC0_SIMULATION_STR : string :=
fmc0_f_int2string(g_SIMULATION);
-- DDR
signal ddr0_status : std_logic_vector(31 downto 0);
signal ddr0_calib_done : std_logic;
signal ddr0_addr_cnt : unsigned(31 downto 0);
signal ddr0_dat_cyc_d : std_logic;
signal ddr0_addr_cnt_en : std_logic;
-- Interrupts and status
signal dma_eic_irq : std_logic;
-- Resync interrupts to sys domain
signal dma_irq_sync : std_logic_vector(1 downto 0);
signal ddr_wr_fifo_empty_sync : std_logic;
signal fmc_irq_sync : std_logic;
begin -- architecture arch
------------------------------------------------------------------------------
-- Reset logic
------------------------------------------------------------------------------
sys_clk_pll_locked <= '1';
-- reset for mezzanine
-- including soft reset, with re-sync from 62.5MHz domain
-- and registers to help with timing
cmp_fmc_sw_reset_sync : gc_sync_ffs
port map (
clk_i => clk_ref_125m,
rst_n_i => '1',
data_i => sw_rst_fmc,
synced_o => sw_rst_fmc_sync);
fmc_rst_ref_125m_n <= rst_ref_125m_n and not sw_rst_fmc_sync;
fmc_rst_sys_n <= rst_sys_62m5_n and not sw_rst_fmc;
-- reset for DDR including soft reset.
-- This is treated as async and will be re-synced by the DDR controller
ddr0_rst <= not rst_ddr_333m_n or sw_rst_fmc;
------------------------------------------------------------------------------
-- Carrier CSR
-- Carrier type and PCB version
-- Bitstream (firmware) type and date
-- Release tag
-- VCXO DAC control (CLR_N)
------------------------------------------------------------------------------
cmp_carrier_csr : entity work.carrier_csr
port map (
rst_n_i => rst_sys_62m5_n,
clk_sys_i => clk_sys_62m5,
wb_adr_i => cnx_slave_in(c_WB_SLAVE_SPEC_CSR).adr(3 downto 2), -- cnx_slave_in.adr is byte address
wb_dat_i => cnx_slave_in(c_WB_SLAVE_SPEC_CSR).dat,
wb_dat_o => cnx_slave_out(c_WB_SLAVE_SPEC_CSR).dat,
wb_cyc_i => cnx_slave_in(c_WB_SLAVE_SPEC_CSR).cyc,
wb_sel_i => cnx_slave_in(c_WB_SLAVE_SPEC_CSR).sel,
wb_stb_i => cnx_slave_in(c_WB_SLAVE_SPEC_CSR).stb,
wb_we_i => cnx_slave_in(c_WB_SLAVE_SPEC_CSR).we,
wb_ack_o => cnx_slave_out(c_WB_SLAVE_SPEC_CSR).ack,
wb_stall_o => open,
regs_i => csr_regin,
regs_o => csr_regout);
csr_regin.carrier_pcb_rev_i <= pcbrev_i;
csr_regin.carrier_reserved_i <= (others => '0');
csr_regin.carrier_type_i <= c_CARRIER_TYPE;
csr_regin.stat_fmc_pres_i <= fmc0_prsnt_m2c_n_i;
csr_regin.stat_p2l_pll_lck_i <= gn4124_status(0);
csr_regin.stat_sys_pll_lck_i <= sys_clk_pll_locked;
csr_regin.stat_ddr3_cal_done_i <= ddr0_calib_done;
led_red <= csr_regout.ctrl_led_red_o;
led_green <= csr_regout.ctrl_led_green_o;
sw_rst_fmc <= csr_regout.rst_fmc0_o;
-- Unused wishbone signals
cnx_slave_out(c_WB_SLAVE_SPEC_CSR).err <= '0';
cnx_slave_out(c_WB_SLAVE_SPEC_CSR).rty <= '0';
cnx_slave_out(c_WB_SLAVE_SPEC_CSR).stall <= '0';
------------------------------------------------------------------------------
-- GN4124 interface
------------------------------------------------------------------------------
cmp_gn4124_core : xwb_gn4124_core
port map (
rst_n_a_i => gn_rst_n_i,
status_o => gn4124_status,
p2l_clk_p_i => gn_p2l_clk_p_i,
p2l_clk_n_i => gn_p2l_clk_n_i,
p2l_data_i => gn_p2l_data_i,
p2l_dframe_i => gn_p2l_dframe_i,
p2l_valid_i => gn_p2l_valid_i,
p2l_rdy_o => gn_p2l_rdy_o,
p_wr_req_i => gn_p_wr_req_i,
p_wr_rdy_o => gn_p_wr_rdy_o,
rx_error_o => gn_rx_error_o,
l2p_clk_p_o => gn_l2p_clk_p_o,
l2p_clk_n_o => gn_l2p_clk_n_o,
l2p_data_o => gn_l2p_data_o,
l2p_dframe_o => gn_l2p_dframe_o,
l2p_valid_o => gn_l2p_valid_o,
l2p_edb_o => gn_l2p_edb_o,
l2p_rdy_i => gn_l2p_rdy_i,
l_wr_rdy_i => gn_l_wr_rdy_i,
p_rd_d_rdy_i => gn_p_rd_d_rdy_i,
tx_error_i => gn_tx_error_i,
vc_rdy_i => gn_vc_rdy_i,
dma_irq_o => dma_irq,
irq_p_i => vic_master_irq,
irq_p_o => gn_gpio_b(1),
wb_master_clk_i => clk_sys_62m5,
wb_master_rst_n_i => rst_sys_62m5_n,
wb_master_i => cnx_master_in(c_WB_MASTER_GENNUM),
wb_master_o => cnx_master_out(c_WB_MASTER_GENNUM),
wb_dma_cfg_clk_i => clk_sys_62m5,
wb_dma_cfg_rst_n_i => rst_sys_62m5_n,
wb_dma_cfg_i => cnx_slave_in(c_WB_SLAVE_DMA),
wb_dma_cfg_o => cnx_slave_out(c_WB_SLAVE_DMA),
wb_dma_dat_clk_i => clk_sys_62m5,
wb_dma_dat_rst_n_i => rst_sys_62m5_n,
wb_dma_dat_i => gn_wb_ddr_in,
wb_dma_dat_o => gn_wb_ddr_out);
-- Assign unused outputs
gn_gpio_b(0) <= '0';
------------------------------------------------------------------------------
-- Primary wishbone crossbar
------------------------------------------------------------------------------
cmp_sdb_crossbar : xwb_sdb_crossbar
generic map (
g_VERBOSE => FALSE,
g_NUM_MASTERS => c_NUM_WB_MASTERS,
g_NUM_SLAVES => c_NUM_WB_SLAVES,
g_REGISTERED => TRUE,
g_WRAPAROUND => TRUE,
g_LAYOUT => c_WB_LAYOUT,
g_SDB_ADDR => c_SDB_ADDRESS)
port map (
clk_sys_i => clk_sys_62m5,
rst_n_i => rst_sys_62m5_n,
slave_i => cnx_master_out,
slave_o => cnx_master_in,
master_i => cnx_slave_out,
master_o => cnx_slave_in);
-----------------------------------------------------------------------------
-- Vectored Interrupt Controller (WB Slave)
-----------------------------------------------------------------------------
cmp_vic : xwb_vic
generic map (
g_INTERFACE_MODE => PIPELINED,
g_ADDRESS_GRANULARITY => BYTE,
g_NUM_INTERRUPTS => 6,
g_INIT_VECTORS => c_VIC_VECTOR_TABLE)
port map (
clk_sys_i => clk_sys_62m5,
rst_n_i => rst_sys_62m5_n,
slave_i => cnx_slave_in(c_WB_SLAVE_VIC),
slave_o => cnx_slave_out(c_WB_SLAVE_VIC),
irqs_i(0) => fmc_host_irq(0),
irqs_i(1) => dma_eic_irq,
irqs_i(2) => mt_hmq_in_irq,
irqs_i(3) => mt_hmq_out_irq,
irqs_i(4) => mt_console_irq,
irqs_i(5) => mt_notify_irq,
irq_master_o => vic_master_irq);
-----------------------------------------------------------------------------
-- Mock Turtle (WB Slave)
-----------------------------------------------------------------------------
cmp_mock_turtle : entity work.mock_turtle_core
generic map (
g_CONFIG => c_MT_CONFIG,
g_CPU0_IRAM_INITF => g_MT_CPU0_INITF,
g_WITH_WHITE_RABBIT => TRUE)
port map (
clk_i => clk_sys_62m5,
rst_n_i => rst_sys_62m5_n,
sp_master_o => open,
sp_master_i => c_DUMMY_WB_MASTER_IN,
dp_master_o(0) => fmc_dp_wb_out,
dp_master_i(0) => fmc_dp_wb_in,
rmq_endpoint_o => rmq_endpoint_out,
rmq_endpoint_i => rmq_endpoint_in,
host_slave_i => cnx_slave_in(c_WB_SLAVE_MT),
host_slave_o => cnx_slave_out(c_WB_SLAVE_MT),
clk_ref_i => clk_ref_125m,
tm_i => tm,
hmq_in_irq_o => mt_hmq_in_irq,
hmq_out_irq_o => mt_hmq_out_irq,
notify_irq_o => mt_notify_irq,
console_irq_o => mt_console_irq);
tm.cycles <= tm_cycles;
tm.tai <= tm_tai;
tm.time_valid <= tm_time_valid;
tm.link_up <= tm_link_up;
tm.aux_locked(1 downto 0) <= tm_clk_aux_locked;
tm.aux_locked(7 downto 2) <= (others => '0');
cmp_eth_endpoint : entity work.mt_ep_ethernet_single
port map (
clk_i => clk_sys_62m5,
rst_n_i => rst_sys_62m5_n,
rmq_src_i => rmq_src_in,
rmq_src_o => rmq_src_out,
rmq_src_config_i => rmq_snk_cfg_out,
rmq_src_config_o => rmq_snk_cfg_in,
rmq_snk_i => rmq_snk_in,
rmq_snk_o => rmq_snk_out,
rmq_snk_config_i => rmq_src_cfg_out,
rmq_snk_config_o => rmq_src_cfg_in,
eth_src_o => eth_tx_out,
eth_src_i => eth_tx_in,
eth_snk_o => eth_rx_out,
eth_snk_i => eth_rx_in);
p_rmq_assign : process (rmq_endpoint_out, rmq_snk_cfg_in, rmq_snk_out,
rmq_src_cfg_in, rmq_src_out) is
begin
rmq_endpoint_in <= c_MT_RMQ_ENDPOINT_IFACE_IN_DEFAULT_VALUE;
-- WR->MT (RX, to MT CPU0)
rmq_src_in <= rmq_endpoint_out.snk_out(0)(0);
rmq_endpoint_in.snk_in(0)(0) <= rmq_src_out;
rmq_snk_cfg_out <= rmq_endpoint_out.snk_config_out(0)(0);
rmq_endpoint_in.snk_config_in(0)(0) <= rmq_snk_cfg_in;
-- MT->WR (TX, from MT CPU0)
rmq_snk_in <= rmq_endpoint_out.src_out(0)(0);
rmq_endpoint_in.src_in(0)(0) <= rmq_snk_out;
rmq_src_cfg_out <= rmq_endpoint_out.src_config_out(0)(0);
rmq_endpoint_in.src_config_in(0)(0) <= rmq_src_cfg_in;
end process p_rmq_assign;
-----------------------------------------------------------------------------
-- The WR PTP core SVEC board package (WB Slave)
-----------------------------------------------------------------------------
cmp_xwrc_board_spec : xwrc_board_spec
generic map (
g_SIMULATION => g_SIMULATION,
g_VERBOSE => FALSE,
g_WITH_EXTERNAL_CLOCK_INPUT => FALSE,
g_DPRAM_INITF => g_WRPC_INITF,
g_AUX_PLL_CONFIG => c_WRPC_PLL_CONFIG,
g_FABRIC_IFACE => PLAIN)
port map (
clk_20m_vcxo_i => clk_20m_vcxo_i,
clk_125m_pllref_p_i => clk_125m_pllref_p_i,
clk_125m_pllref_n_i => clk_125m_pllref_n_i,
clk_125m_gtp_n_i => clk_125m_gtp_n_i,
clk_125m_gtp_p_i => clk_125m_gtp_p_i,
areset_n_i => button1_n_i,
areset_edge_n_i => gn_rst_n_i,
clk_sys_62m5_o => clk_sys_62m5,
clk_ref_125m_o => clk_ref_125m,
clk_pll_aux_o => clk_ddr_333m,
rst_sys_62m5_n_o => rst_sys_62m5_n,
rst_ref_125m_n_o => rst_ref_125m_n,
rst_pll_aux_n_o => rst_ddr_333m_n,
plldac_sclk_o => plldac_sclk_o,
plldac_din_o => plldac_din_o,
pll25dac_cs_n_o => pll25dac_sync_n_o,
pll20dac_cs_n_o => pll20dac_sync_n_o,
sfp_txp_o => sfp_txp_o,
sfp_txn_o => sfp_txn_o,
sfp_rxp_i => sfp_rxp_i,
sfp_rxn_i => sfp_rxn_i,
sfp_det_i => sfp_mod_def0_i,
sfp_sda_i => sfp_sda_in,
sfp_sda_o => sfp_sda_out,
sfp_scl_i => sfp_scl_in,
sfp_scl_o => sfp_scl_out,
sfp_rate_select_o => sfp_rate_select_o,
sfp_tx_fault_i => sfp_tx_fault_i,
sfp_tx_disable_o => sfp_tx_disable_o,
sfp_los_i => sfp_los_i,
onewire_i => onewire_data,
onewire_oen_o => onewire_oe,
uart_rxd_i => uart_rxd_i,
uart_txd_o => uart_txd_o,
flash_sclk_o => spi_sclk_o,
flash_ncs_o => spi_ncs_o,
flash_mosi_o => spi_mosi_o,
flash_miso_i => spi_miso_i,
wb_slave_o => cnx_slave_out(c_WB_SLAVE_WRC),
wb_slave_i => cnx_slave_in(c_WB_SLAVE_WRC),
wrf_src_o => eth_rx_in,
wrf_src_i => eth_rx_out,
wrf_snk_o => eth_tx_in,
wrf_snk_i => eth_tx_out,
tm_link_up_o => tm_link_up,
tm_time_valid_o => tm_time_valid,
tm_tai_o => tm_tai,
tm_cycles_o => tm_cycles,
pps_p_o => open,
pps_led_o => pps_led,
led_link_o => wr_led_link,
led_act_o => wr_led_act,
link_ok_o => wrabbit_en);
-- Tristates for SFP EEPROM
sfp_mod_def1_b <= '0' when sfp_scl_out = '0' else 'Z';
sfp_mod_def2_b <= '0' when sfp_sda_out = '0' else 'Z';
sfp_scl_in <= sfp_mod_def1_b;
sfp_sda_in <= sfp_mod_def2_b;
-- Tristates for Carrier OneWire
carrier_onewire_b <= '0' when onewire_oe = '1' else 'Z';
onewire_data <= carrier_onewire_b;
-- fmc i2c
fmc0_scl_b <= '0' when (fmc0_scl_out = '0') else 'Z';
fmc0_sda_b <= '0' when (fmc0_sda_out = '0') else 'Z';
------------------------------------------------------------------------------
-- GN4124 DMA interrupt controller
------------------------------------------------------------------------------
gen_dma_irq : for I in 0 to 1 generate
cmp_dma_irq_sync : gc_sync_ffs
port map (
clk_i => clk_sys_62m5,
rst_n_i => '1',
data_i => dma_irq(I),
synced_o => dma_irq_sync(I));
end generate gen_dma_irq;
cmp_dma_eic : entity work.dma_eic
port map (
rst_n_i => rst_sys_62m5_n,
clk_sys_i => clk_sys_62m5,
wb_adr_i => cnx_slave_in(c_WB_SLAVE_DMA_EIC).adr(3 downto 2), -- cnx_slave_in.adr is byte address
wb_dat_i => cnx_slave_in(c_WB_SLAVE_DMA_EIC).dat,
wb_dat_o => cnx_slave_out(c_WB_SLAVE_DMA_EIC).dat,
wb_cyc_i => cnx_slave_in(c_WB_SLAVE_DMA_EIC).cyc,
wb_sel_i => cnx_slave_in(c_WB_SLAVE_DMA_EIC).sel,
wb_stb_i => cnx_slave_in(c_WB_SLAVE_DMA_EIC).stb,
wb_we_i => cnx_slave_in(c_WB_SLAVE_DMA_EIC).we,
wb_ack_o => cnx_slave_out(c_WB_SLAVE_DMA_EIC).ack,
wb_stall_o => cnx_slave_out(c_WB_SLAVE_DMA_EIC).stall,
wb_int_o => dma_eic_irq,
irq_dma_done_i => dma_irq_sync(0),
irq_dma_error_i => dma_irq_sync(1)
);
-- Unused wishbone signals
cnx_slave_out(c_WB_SLAVE_DMA_EIC).err <= '0';
cnx_slave_out(c_WB_SLAVE_DMA_EIC).rty <= '0';
cmp_fmc0_irq_sync : gc_sync_ffs
port map (
clk_i => clk_sys_62m5,
rst_n_i => '1',
data_i => fmc0_irq,
synced_o => fmc_host_irq(0));
------------------------------------------------------------------------------
-- FMC ADC mezzanines (wb bridge with cross-clocking)
-- Mezzanine system managment I2C master
-- Mezzanine SPI master
-- Mezzanine I2C
-- ADC core
-- Mezzanine 1-wire master
------------------------------------------------------------------------------
cmp0_xwb_clock_bridge : xwb_clock_bridge
port map (
slave_clk_i => clk_sys_62m5,
slave_rst_n_i => rst_sys_62m5_n,
slave_i => cnx_slave_in(c_WB_SLAVE_FMC_ADC),
slave_o => cnx_slave_out(c_WB_SLAVE_FMC_ADC),
master_clk_i => clk_ref_125m,
master_rst_n_i => rst_ref_125m_n,
master_i => cnx_fmc0_sync_master_in,
master_o => cnx_fmc0_sync_master_out);
cmp0_fmc_ddr_wr_fifo_sync : gc_sync_ffs
port map (
clk_i => clk_ref_125m,
rst_n_i => '1',
data_i => ddr0_wr_fifo_empty,
synced_o => ddr0_wr_fifo_empty_sync);
cmp0_tm_time_valid_sync : gc_sync_ffs
port map (
clk_i => clk_ref_125m,
rst_n_i => '1',
data_i => tm_time_valid,
synced_o => tm_time_valid_sync);
cmp0_fmc_adc_mezzanine : entity work.fmc_adc_mezzanine
generic map (
g_MULTISHOT_RAM_SIZE => g_FMC0_MULTISHOT_RAM_SIZE,
g_WB_MODE => PIPELINED,
g_WB_GRANULARITY => BYTE)
port map (
sys_clk_i => clk_ref_125m,
sys_rst_n_i => rst_ref_125m_n,
wb_csr_slave_i => cnx_fmc0_sync_master_out,
wb_csr_slave_o => cnx_fmc0_sync_master_in,
wb_ddr_clk_i => clk_ref_125m,
wb_ddr_rst_n_i => rst_ref_125m_n,
wb_ddr_master_i => fmc0_wb_ddr_in,
wb_ddr_master_o => fmc0_wb_ddr_out,
ddr_wr_fifo_empty_i => ddr0_wr_fifo_empty_sync,
trig_irq_o => open,
acq_end_irq_o => open,
eic_irq_o => fmc0_irq,
acq_cfg_ok_o => open,
wb_trigin_slave_i => wb_adc0_trigin_slave_in,
wb_trigin_slave_o => wb_adc0_trigin_slave_out,
wb_trigout_slave_i => wb_adc0_trigout_slave_in,
wb_trigout_slave_o => wb_adc0_trigout_slave_out,
ext_trigger_p_i => fmc0_adc_ext_trigger_p_i,
ext_trigger_n_i => fmc0_adc_ext_trigger_n_i,
adc_dco_p_i => fmc0_adc_dco_p_i,
adc_dco_n_i => fmc0_adc_dco_n_i,
adc_fr_p_i => fmc0_adc_fr_p_i,
adc_fr_n_i => fmc0_adc_fr_n_i,
adc_outa_p_i => fmc0_adc_outa_p_i,
adc_outa_n_i => fmc0_adc_outa_n_i,
adc_outb_p_i => fmc0_adc_outb_p_i,
adc_outb_n_i => fmc0_adc_outb_n_i,
gpio_dac_clr_n_o => fmc0_adc_gpio_dac_clr_n_o,
gpio_led_acq_o => fmc0_adc_gpio_led_acq_o,
gpio_led_trig_o => fmc0_adc_gpio_led_trig_o,
gpio_ssr_ch1_o => fmc0_adc_gpio_ssr_ch1_o,
gpio_ssr_ch2_o => fmc0_adc_gpio_ssr_ch2_o,
gpio_ssr_ch3_o => fmc0_adc_gpio_ssr_ch3_o,
gpio_ssr_ch4_o => fmc0_adc_gpio_ssr_ch4_o,
gpio_si570_oe_o => fmc0_adc_gpio_si570_oe_o,
spi_din_i => fmc0_adc_spi_din_i,
spi_dout_o => fmc0_adc_spi_dout_o,
spi_sck_o => fmc0_adc_spi_sck_o,
spi_cs_adc_n_o => fmc0_adc_spi_cs_adc_n_o,
spi_cs_dac1_n_o => fmc0_adc_spi_cs_dac1_n_o,
spi_cs_dac2_n_o => fmc0_adc_spi_cs_dac2_n_o,
spi_cs_dac3_n_o => fmc0_adc_spi_cs_dac3_n_o,
spi_cs_dac4_n_o => fmc0_adc_spi_cs_dac4_n_o,
si570_scl_b => fmc0_adc_si570_scl_b,
si570_sda_b => fmc0_adc_si570_sda_b,
mezz_one_wire_b => fmc0_adc_one_wire_b,
sys_scl_b => fmc0_scl_b,
sys_sda_b => fmc0_sda_b,
wr_tm_link_up_i => tm_link_up,
wr_tm_time_valid_i => tm_time_valid_sync,
wr_tm_tai_i => tm_tai,
wr_tm_cycles_i => tm_cycles,
wr_enable_i => wrabbit_en);
------------------------------------------------------------------------------
-- DMA wishbone bus slaves
-- -> DDR3 controller
------------------------------------------------------------------------------
cmp_ddr0_ctrl_bank : ddr3_ctrl
generic map(
g_RST_ACT_LOW => 0, -- active high reset (simpler internal logic)
g_BANK_PORT_SELECT => "SPEC_BANK3_64B_32B",
g_MEMCLK_PERIOD => 3000,
g_SIMULATION => c_FMC0_SIMULATION_STR,
g_CALIB_SOFT_IP => g_FMC0_CALIB_SOFT_IP,
g_P0_MASK_SIZE => 8,
g_P0_DATA_PORT_SIZE => 64,
g_P0_BYTE_ADDR_WIDTH => 30,
g_P1_MASK_SIZE => 4,
g_P1_DATA_PORT_SIZE => 32,
g_P1_BYTE_ADDR_WIDTH => 30)
port map (
clk_i => clk_ddr_333m,
rst_n_i => ddr0_rst,
status_o => ddr0_status,
ddr3_dq_b => ddr0_dq_b,
ddr3_a_o => ddr0_a_o,
ddr3_ba_o => ddr0_ba_o,
ddr3_ras_n_o => ddr0_ras_n_o,
ddr3_cas_n_o => ddr0_cas_n_o,
ddr3_we_n_o => ddr0_we_n_o,
ddr3_odt_o => ddr0_odt_o,
ddr3_rst_n_o => ddr0_reset_n_o,
ddr3_cke_o => ddr0_cke_o,
ddr3_dm_o => ddr0_ldm_o,
ddr3_udm_o => ddr0_udm_o,
ddr3_dqs_p_b => ddr0_ldqs_p_b,
ddr3_dqs_n_b => ddr0_ldqs_n_b,
ddr3_udqs_p_b => ddr0_udqs_p_b,
ddr3_udqs_n_b => ddr0_udqs_n_b,
ddr3_clk_p_o => ddr0_ck_p_o,
ddr3_clk_n_o => ddr0_ck_n_o,
ddr3_rzq_b => ddr0_rzq_b,
wb0_rst_n_i => fmc_rst_ref_125m_n,
wb0_clk_i => clk_ref_125m,
wb0_sel_i => fmc0_wb_ddr_out.sel,
wb0_cyc_i => fmc0_wb_ddr_out.cyc,
wb0_stb_i => fmc0_wb_ddr_out.stb,
wb0_we_i => fmc0_wb_ddr_out.we,
wb0_addr_i => fmc0_wb_ddr_out.adr,
wb0_data_i => fmc0_wb_ddr_out.dat,
wb0_data_o => fmc0_wb_ddr_in.dat,
wb0_ack_o => fmc0_wb_ddr_in.ack,
wb0_stall_o => fmc0_wb_ddr_in.stall,
p0_cmd_empty_o => open,
p0_cmd_full_o => open,
p0_rd_full_o => open,
p0_rd_empty_o => open,
p0_rd_count_o => open,
p0_rd_overflow_o => open,
p0_rd_error_o => open,
p0_wr_full_o => open,
p0_wr_empty_o => ddr0_wr_fifo_empty,
p0_wr_count_o => open,
p0_wr_underrun_o => open,
p0_wr_error_o => open,
wb1_rst_n_i => rst_sys_62m5_n,
wb1_clk_i => clk_sys_62m5,
wb1_sel_i => gn_wb_ddr_out.sel,
wb1_cyc_i => gn_wb_ddr_out.cyc,
wb1_stb_i => gn_wb_ddr_out.stb,
wb1_we_i => gn_wb_ddr_out.we,
wb1_addr_i => gn_wb_ddr_out.adr,
wb1_data_i => gn_wb_ddr_out.dat,
wb1_data_o => gn_wb_ddr_in.dat,
wb1_ack_o => gn_wb_ddr_in.ack,
wb1_stall_o => gn_wb_ddr_in.stall,
p1_cmd_empty_o => open,
p1_cmd_full_o => open,
p1_rd_full_o => open,
p1_rd_empty_o => open,
p1_rd_count_o => open,
p1_rd_overflow_o => open,
p1_rd_error_o => open,
p1_wr_full_o => open,
p1_wr_empty_o => open,
p1_wr_count_o => open,
p1_wr_underrun_o => open,
p1_wr_error_o => open);
fmc0_wb_ddr_in.err <= '0';
fmc0_wb_ddr_in.rty <= '0';
cmp_ddr0_calib_done_sync : gc_sync_ffs
port map (
clk_i => clk_sys_62m5,
rst_n_i => '1',
data_i => ddr0_status(0),
synced_o => ddr0_calib_done);
-- unused Wishbone signals
gn_wb_ddr_in.err <= '0';
gn_wb_ddr_in.rty <= '0';
-- Note: g_address/g_mask index direction is to, master_i/master_o is downto
cpu0_crossbar : xwb_crossbar
generic map (
g_VERBOSE => FALSE,
g_num_masters => 1,
g_num_slaves => 2,
g_registered => False,
g_address(0) => x"00000000",
g_address(1) => x"00001000",
g_mask(0) => x"0000_f000",
g_mask(1) => x"0000_f000")
port map (
clk_sys_i => clk_sys_62m5,
rst_n_i => rst_sys_62m5_n,
slave_i(0) => fmc_dp_wb_out,
slave_o(0) => fmc_dp_wb_in,
master_i(1) => wb_adc0_trigout_slave_out,
master_i(0) => wb_adc0_trigin_slave_out,
master_o(1) => wb_adc0_trigout_slave_in,
master_o(0) => wb_adc0_trigin_slave_in);
------------------------------------------------------------------------------
-- Carrier LEDs
------------------------------------------------------------------------------
cmp_pci_access_led : gc_extend_pulse
generic map (
g_width => 2500000)
port map (
clk_i => clk_sys_62m5,
rst_n_i => rst_sys_62m5_n,
pulse_i => cnx_slave_in(c_WB_MASTER_GENNUM).cyc,
extended_o => gn4124_access);
aux_leds_o(0) <= not gn4124_access;
aux_leds_o(1) <= '1';
aux_leds_o(2) <= not tm_time_valid;
aux_leds_o(3) <= not pps_led;
-- SPEC front panel leds
led_sfp_red_o <= led_red or wr_led_act;
led_sfp_green_o <= led_green or wr_led_link;
end architecture arch;
wrtd-53772dc3cd49421ea1fa6326a199b7a72dc04d18/hdl/top/wrtd_ref_svec_tdc_fd/ 0000775 0000000 0000000 00000000000 13460261316 0025120 5 ustar 00root root 0000000 0000000 wrtd-53772dc3cd49421ea1fa6326a199b7a72dc04d18/hdl/top/wrtd_ref_svec_tdc_fd/Manifest.py 0000664 0000000 0000000 00000001007 13460261316 0027236 0 ustar 00root root 0000000 0000000 files = [
"wrtd_ref_svec_tdc_fd.vhd",
]
fetchto = "../../../dependencies"
modules = {
"git" : [
"git://ohwr.org/hdl-core-lib/general-cores.git",
"git://ohwr.org/hdl-core-lib/wr-cores.git",
"git://ohwr.org/hdl-core-lib/vme64x-core.git",
"git://ohwr.org/hdl-core-lib/urv-core.git",
"git://ohwr.org/hdl-core-lib/mock-turtle.git",
"git://ohwr.org/fmc-projects/fmc-tdc/fmc-tdc-1ns-5cha-gw.git",
"git://ohwr.org/fmc-projects/fmc-delay-1ns-8cha.git",
],
}
wrtd-53772dc3cd49421ea1fa6326a199b7a72dc04d18/hdl/top/wrtd_ref_svec_tdc_fd/wrtd_ref_svec_tdc_fd.vhd 0000664 0000000 0000000 00000124470 13460261316 0031772 0 ustar 00root root 0000000 0000000 --------------------------------------------------------------------------------
-- CERN BE-CO-HT
-- White Rabbit Trigger Distribution
-- https://ohwr-gitlab.cern.ch/projects/wrtd
--------------------------------------------------------------------------------
--
-- unit name: wrtd_ref_svec_tdc_fd
--
-- description: Top entity for WRTD reference design
--
-- Top level design of the SVEC-based WRTD node, with
-- an FMC TDC in slot 1 and an FMC Fine Delay in slot 2.
--
-- This is the standard pulse-in/pulse-out WRTD node, with the FMC TDC
-- injecting pulses into the WR network in the form of WRTD messages and
-- the FMC Fine Delay converting those messages back to pulses at the
-- destination.
--
--------------------------------------------------------------------------------
-- Copyright CERN 2014-2019
--------------------------------------------------------------------------------
-- Copyright and related rights are licensed under the Solderpad Hardware
-- License, Version 2.0 (the "License"); you may not use this file except
-- in compliance with the License. You may obtain a copy of the License at
-- http://solderpad.org/licenses/SHL-2.0.
-- Unless required by applicable law or agreed to in writing, software,
-- hardware and materials distributed under this License is distributed on an
-- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
-- or implied. See the License for the specific language governing permissions
-- and limitations under the License.
--------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
library work;
use work.gencores_pkg.all;
use work.wishbone_pkg.all;
use work.vme64x_pkg.all;
use work.wr_board_pkg.all;
use work.wr_svec_pkg.all;
use work.wr_fabric_pkg.all;
use work.mt_mqueue_pkg.all;
use work.mock_turtle_pkg.all;
use work.tdc_core_pkg.all;
use work.fine_delay_pkg.all;
use work.synthesis_descriptor.all;
library unisim;
use unisim.vcomponents.all;
entity wrtd_ref_svec_tdc_fd is
generic (
g_WRPC_INITF : string := "../../../dependencies/wr-cores/bin/wrpc/wrc_phy8.bram";
g_MT_CPU0_INITF : string := "../../../software/firmware/tdc/wrtd-rt-tdc.bram";
g_MT_CPU1_INITF : string := "../../../software/firmware/fd/wrtd-rt-fd.bram";
-- Simulation-mode enable parameter. Set by default (synthesis) to 0, and
-- changed to non-zero in the instantiation of the top level DUT in the
-- testbench. Its purpose is to reduce some internal counters/timeouts
-- to speed up simulations.
g_SIMULATION : integer := 0;
-- Bypass VME core, useful only in simulation
g_SIM_BYPASS_VME : boolean := FALSE);
port (
---------------------------------------------------------------------------
-- Clocks/resets
---------------------------------------------------------------------------
-- Reset from system fpga
rst_n_i : in std_logic;
-- Local oscillators
clk_20m_vcxo_i : in std_logic; -- 20MHz VCXO clock
clk_125m_pllref_p_i : in std_logic; -- 125 MHz PLL reference
clk_125m_pllref_n_i : in std_logic;
clk_125m_gtp_n_i : in std_logic; -- 125 MHz GTP reference
clk_125m_gtp_p_i : in std_logic;
---------------------------------------------------------------------------
-- VME interface
---------------------------------------------------------------------------
-- Bypass VME core, useful only in simulation
-- synthesis translate_off
sim_wb_i : in t_wishbone_slave_in := cc_dummy_slave_in;
sim_wb_o : out t_wishbone_slave_out;
-- synthesis translate_on
vme_write_n_i : in std_logic;
vme_sysreset_n_i : in std_logic;
vme_retry_oe_o : out std_logic;
vme_retry_n_o : out std_logic;
vme_lword_n_b : inout std_logic;
vme_iackout_n_o : out std_logic;
vme_iackin_n_i : in std_logic;
vme_iack_n_i : in std_logic;
vme_gap_i : in std_logic;
vme_dtack_oe_o : out std_logic;
vme_dtack_n_o : out std_logic;
vme_ds_n_i : in std_logic_vector(1 downto 0);
vme_data_oe_n_o : out std_logic;
vme_data_dir_o : out std_logic;
vme_berr_o : out std_logic;
vme_as_n_i : in std_logic;
vme_addr_oe_n_o : out std_logic;
vme_addr_dir_o : out std_logic;
vme_irq_o : out std_logic_vector(7 downto 1);
vme_ga_i : in std_logic_vector(4 downto 0);
vme_data_b : inout std_logic_vector(31 downto 0);
vme_am_i : in std_logic_vector(5 downto 0);
vme_addr_b : inout std_logic_vector(31 downto 1);
---------------------------------------------------------------------------
-- SPI interfaces to DACs
---------------------------------------------------------------------------
pll20dac_din_o : out std_logic;
pll20dac_sclk_o : out std_logic;
pll20dac_sync_n_o : out std_logic;
pll25dac_din_o : out std_logic;
pll25dac_sclk_o : out std_logic;
pll25dac_sync_n_o : out std_logic;
---------------------------------------------------------------------------
-- SFP I/O for transceiver
---------------------------------------------------------------------------
sfp_txp_o : out std_logic;
sfp_txn_o : out std_logic;
sfp_rxp_i : in std_logic;
sfp_rxn_i : in std_logic;
sfp_mod_def0_i : in std_logic; -- sfp detect
sfp_mod_def1_b : inout std_logic; -- scl
sfp_mod_def2_b : inout std_logic; -- sda
sfp_rate_select_o : out std_logic;
sfp_tx_fault_i : in std_logic;
sfp_tx_disable_o : out std_logic;
sfp_los_i : in std_logic;
---------------------------------------------------------------------------
-- Carrier I2C EEPROM
---------------------------------------------------------------------------
carrier_scl_b : inout std_logic;
carrier_sda_b : inout std_logic;
---------------------------------------------------------------------------
-- Onewire interface
---------------------------------------------------------------------------
carrier_onewire_b : inout std_logic;
---------------------------------------------------------------------------
-- UART
---------------------------------------------------------------------------
uart_rxd_i : in std_logic;
uart_txd_o : out std_logic;
---------------------------------------------------------------------------
-- SPI (flash is connected to SFPGA and routed to AFPGA
-- once the boot process is complete)
---------------------------------------------------------------------------
spi_sclk_o : out std_logic;
spi_ncs_o : out std_logic;
spi_mosi_o : out std_logic;
spi_miso_i : in std_logic;
---------------------------------------------------------------------------
-- Carrier front panel LEDs and IOs
---------------------------------------------------------------------------
fp_led_line_oen_o : out std_logic_vector(1 downto 0);
fp_led_line_o : out std_logic_vector(1 downto 0);
fp_led_column_o : out std_logic_vector(3 downto 0);
fp_gpio1_o : out std_logic; -- PPS output
fp_gpio2_o : out std_logic; -- Ref clock div2 output
fp_gpio3_i : in std_logic; -- ext 10MHz clock input
fp_gpio4_i : in std_logic; -- ext PPS input
fp_term_en_o : out std_logic_vector(4 downto 1);
fp_gpio1_a2b_o : out std_logic;
fp_gpio2_a2b_o : out std_logic;
fp_gpio34_a2b_o : out std_logic;
---------------------------------------------------------------------------
-- FMC slot 1 pins (TDC mezzanine)
---------------------------------------------------------------------------
-- TDC1 PLL AD9516 and DAC AD5662 interface
fmc0_tdc_pll_sclk_o : out std_logic;
fmc0_tdc_pll_sdi_o : out std_logic;
fmc0_tdc_pll_cs_n_o : out std_logic;
fmc0_tdc_pll_dac_sync_n_o : out std_logic;
fmc0_tdc_pll_sdo_i : in std_logic;
fmc0_tdc_pll_status_i : in std_logic;
fmc0_tdc_125m_clk_p_i : in std_logic;
fmc0_tdc_125m_clk_n_i : in std_logic;
fmc0_tdc_acam_refclk_p_i : in std_logic;
fmc0_tdc_acam_refclk_n_i : in std_logic;
-- TDC1 ACAM timing interface
fmc0_tdc_start_from_fpga_o : out std_logic;
fmc0_tdc_err_flag_i : in std_logic;
fmc0_tdc_int_flag_i : in std_logic;
fmc0_tdc_start_dis_o : out std_logic;
fmc0_tdc_stop_dis_o : out std_logic;
-- TDC1 ACAM data interface
fmc0_tdc_data_bus_io : inout std_logic_vector(27 downto 0);
fmc0_tdc_address_o : out std_logic_vector(3 downto 0);
fmc0_tdc_cs_n_o : out std_logic;
fmc0_tdc_oe_n_o : out std_logic;
fmc0_tdc_rd_n_o : out std_logic;
fmc0_tdc_wr_n_o : out std_logic;
fmc0_tdc_ef1_i : in std_logic;
fmc0_tdc_ef2_i : in std_logic;
-- TDC1 Input Logic
fmc0_tdc_enable_inputs_o : out std_logic;
fmc0_tdc_term_en_1_o : out std_logic;
fmc0_tdc_term_en_2_o : out std_logic;
fmc0_tdc_term_en_3_o : out std_logic;
fmc0_tdc_term_en_4_o : out std_logic;
fmc0_tdc_term_en_5_o : out std_logic;
-- TDC1 1-wire UniqueID & Thermometer
fmc0_tdc_one_wire_b : inout std_logic;
-- TDC1 EEPROM I2C
fmc0_tdc_scl_b : inout std_logic;
fmc0_tdc_sda_b : inout std_logic;
-- TDC1 LEDs
fmc0_tdc_led_status_o : out std_logic;
fmc0_tdc_led_trig1_o : out std_logic;
fmc0_tdc_led_trig2_o : out std_logic;
fmc0_tdc_led_trig3_o : out std_logic;
fmc0_tdc_led_trig4_o : out std_logic;
fmc0_tdc_led_trig5_o : out std_logic;
-- TDC1 Input channels
-- also arriving to the FPGA (not used for the moment)
fmc0_tdc_in_fpga_1_i : in std_logic;
fmc0_tdc_in_fpga_2_i : in std_logic;
fmc0_tdc_in_fpga_3_i : in std_logic;
fmc0_tdc_in_fpga_4_i : in std_logic;
fmc0_tdc_in_fpga_5_i : in std_logic;
fmc0_prsntm2c_n_i : in std_logic;
fmc0_scl_b : inout std_logic;
fmc0_sda_b : inout std_logic;
---------------------------------------------------------------------------
-- FMC slot 2 pins (FDELAY mezzanine)
---------------------------------------------------------------------------
fmc1_fd_tdc_start_p_i : in std_logic;
fmc1_fd_tdc_start_n_i : in std_logic;
fmc1_fd_clk_ref_p_i : in std_logic;
fmc1_fd_clk_ref_n_i : in std_logic;
fmc1_fd_trig_a_i : in std_logic;
fmc1_fd_tdc_cal_pulse_o : out std_logic;
fmc1_fd_tdc_d_b : inout std_logic_vector(27 downto 0);
fmc1_fd_tdc_emptyf_i : in std_logic;
fmc1_fd_tdc_alutrigger_o : out std_logic;
fmc1_fd_tdc_wr_n_o : out std_logic;
fmc1_fd_tdc_rd_n_o : out std_logic;
fmc1_fd_tdc_oe_n_o : out std_logic;
fmc1_fd_led_trig_o : out std_logic;
fmc1_fd_tdc_start_dis_o : out std_logic;
fmc1_fd_tdc_stop_dis_o : out std_logic;
fmc1_fd_spi_cs_dac_n_o : out std_logic;
fmc1_fd_spi_cs_pll_n_o : out std_logic;
fmc1_fd_spi_cs_gpio_n_o : out std_logic;
fmc1_fd_spi_sclk_o : out std_logic;
fmc1_fd_spi_mosi_o : out std_logic;
fmc1_fd_spi_miso_i : in std_logic;
fmc1_fd_delay_len_o : out std_logic_vector(3 downto 0);
fmc1_fd_delay_val_o : out std_logic_vector(9 downto 0);
fmc1_fd_delay_pulse_o : out std_logic_vector(3 downto 0);
fmc1_fd_dmtd_clk_o : out std_logic;
fmc1_fd_dmtd_fb_in_i : in std_logic;
fmc1_fd_dmtd_fb_out_i : in std_logic;
fmc1_fd_pll_status_i : in std_logic;
fmc1_fd_ext_rst_n_o : out std_logic;
fmc1_fd_onewire_b : inout std_logic;
fmc1_prsntm2c_n_i : in std_logic;
fmc1_scl_b : inout std_logic;
fmc1_sda_b : inout std_logic);
end entity wrtd_ref_svec_tdc_fd;
architecture arch of wrtd_ref_svec_tdc_fd is
-----------------------------------------------------------------------------
-- Components
-----------------------------------------------------------------------------
component fd_ddr_pll
port (
RST : in std_logic;
LOCKED : out std_logic;
CLK_IN1_P : in std_logic;
CLK_IN1_N : in std_logic;
CLK_OUT1 : out std_logic;
CLK_OUT2 : out std_logic);
end component;
-----------------------------------------------------------------------------
-- Constants
-----------------------------------------------------------------------------
-- Number of masters attached to the primary wishbone crossbar
constant c_NUM_WB_MASTERS : integer := 1;
-- Number of slaves attached to the primary wishbone crossbar
constant c_NUM_WB_SLAVES : integer := 5;
-- Primary Wishbone master(s) offsets
constant c_WB_MASTER_VME : integer := 0;
-- Primary Wishbone slave(s) offsets
constant c_WB_SLAVE_VIC : integer := 0;
constant c_WB_SLAVE_FDL : integer := 1;
constant c_WB_SLAVE_TDC : integer := 2;
constant c_WB_SLAVE_MT : integer := 3;
constant c_WB_SLAVE_WRC : integer := 4;
constant c_WB_DESC_SYN : integer := c_NUM_WB_SLAVES;
constant c_WB_DESC_URL : integer := c_NUM_WB_SLAVES + 1;
-- sdb header address on primary crossbar
constant c_SDB_ADDRESS : t_wishbone_address := x"00000000";
-- f_xwb_bridge_manual_sdb(size, sdb_addr)
-- Note: sdb_addr is the sdb records address relative to the bridge base address
constant c_WRC_BRIDGE_SDB : t_sdb_bridge :=
f_xwb_bridge_manual_sdb(x"0003ffff", x"00030000");
constant c_TDC_BRIDGE_SDB : t_sdb_bridge :=
f_xwb_bridge_manual_sdb(x"0000ffff", x"00000000");
-- Primary wishbone crossbar layout
constant c_WB_LAYOUT : t_sdb_record_array(c_NUM_WB_SLAVES + 1 downto 0) := (
c_WB_SLAVE_VIC => f_sdb_embed_device(c_XWB_VIC_SDB, x"00002000"),
c_WB_SLAVE_FDL => f_sdb_embed_device(c_FD_SDB_DEVICE, x"00008000"),
c_WB_SLAVE_TDC => f_sdb_embed_bridge(c_TDC_BRIDGE_SDB, x"00010000"),
c_WB_SLAVE_MT => f_sdb_embed_device(c_MOCK_TURTLE_SDB, x"00020000"),
c_WB_SLAVE_WRC => f_sdb_embed_bridge(c_WRC_BRIDGE_SDB, x"00040000"),
c_WB_DESC_SYN => f_sdb_embed_synthesis(c_SDB_SYNTHESIS_INFO),
c_WB_DESC_URL => f_sdb_embed_repo_url(c_SDB_REPO_URL));
-- not really used, will be reprogrammed by software
constant c_VIC_VECTOR_TABLE : t_wishbone_address_array(0 to 5) := (
0 => x"00013000", -- FMC TDC
1 => x"00018000", -- FMC Fine Delay
2 => x"00020000", -- MT Mqueue in interrupt
3 => x"00020001", -- MT Mqueue out interrupt
4 => x"00020002", -- MT Console interrupt
5 => x"00020003"); -- MT Notify interrupt
constant c_FMC_MUX_ADDR : t_wishbone_address_array(0 downto 0) :=
(0 => x"00000000");
constant c_FMC_MUX_MASK : t_wishbone_address_array(0 downto 0) :=
(0 => x"10000000");
constant c_MT_CONFIG : t_mt_config :=
(
app_id => x"115790de",
cpu_count => 2,
cpu_config => (
0 | 1 => (
memsize => 8192,
hmq_config => (
slot_count => 1,
slot_config => (
0 => (
entries_bits => 4,
width_bits => 7,
header_bits => 2,
endpoint_id => x"0000_0000",
enable_config_space => FALSE),
others => c_DUMMY_MT_MQUEUE_SLOT)),
rmq_config => (
slot_count => 1,
slot_config => (
0 => (
entries_bits => 4,
width_bits => 7,
header_bits => 4,
endpoint_id => x"0000_0000",
enable_config_space => TRUE),
others => c_DUMMY_MT_MQUEUE_SLOT))),
others => (
0, c_MT_DEFAULT_MQUEUE_CONFIG, c_MT_DEFAULT_MQUEUE_CONFIG)),
shared_mem_size => 256
);
-----------------------------------------------------------------------------
-- Signals
-----------------------------------------------------------------------------
-- Wishbone buse(s) from masters attached to crossbar
signal cnx_master_out : t_wishbone_master_out_array(c_NUM_WB_MASTERS-1 downto 0);
signal cnx_master_in : t_wishbone_master_in_array(c_NUM_WB_MASTERS-1 downto 0);
-- Wishbone buse(s) to slaves attached to crossbar
signal cnx_slave_out : t_wishbone_slave_out_array(c_NUM_WB_SLAVES-1 downto 0);
signal cnx_slave_in : t_wishbone_slave_in_array(c_NUM_WB_SLAVES-1 downto 0);
-- clock and reset
signal areset_n : std_logic;
signal clk_sys_62m5 : std_logic;
signal rst_sys_62m5_n : std_logic;
signal clk_ref_125m : std_logic;
signal clk_ref_div2 : std_logic;
signal clk_ext_ref : std_logic;
signal tdc_clk_125m : std_logic;
signal dcm1_clk_ref_0 : std_logic;
signal dcm1_clk_ref_180 : std_logic;
attribute keep : string;
attribute keep of clk_sys_62m5 : signal is "TRUE";
attribute keep of clk_ref_125m : signal is "TRUE";
attribute keep of tdc_clk_125m : signal is "TRUE";
attribute keep of dcm1_clk_ref_0 : signal is "TRUE";
-- I2C EEPROM
signal eeprom_sda_in : std_logic;
signal eeprom_sda_out : std_logic;
signal eeprom_scl_in : std_logic;
signal eeprom_scl_out : std_logic;
-- VME
signal vme_data_b_out : std_logic_vector(31 downto 0);
signal vme_addr_b_out : std_logic_vector(31 downto 1);
signal vme_lword_n_b_out : std_logic;
signal vme_data_dir_int : std_logic;
signal vme_addr_dir_int : std_logic;
signal vme_ga : std_logic_vector(5 downto 0);
signal vme_berr_n : std_logic;
signal vme_irq_n : std_logic_vector(7 downto 1);
signal vme_access_led : std_logic;
-- SFP
signal sfp_sda_in : std_logic;
signal sfp_sda_out : std_logic;
signal sfp_scl_in : std_logic;
signal sfp_scl_out : std_logic;
-- OneWire
signal onewire_data : std_logic;
signal onewire_oe : std_logic;
-- LEDs and GPIO
signal pps : std_logic;
signal pps_led : std_logic;
signal pps_ext_in : std_logic;
signal svec_led : std_logic_vector(15 downto 0);
signal wr_led_link : std_logic;
signal wr_led_act : std_logic;
-- VIC
signal fmc_host_irq : std_logic_vector(1 downto 0);
signal mt_hmq_in_irq : std_logic;
signal mt_hmq_out_irq : std_logic;
signal mt_console_irq : std_logic;
signal mt_notify_irq : std_logic;
signal vic_master_irq : std_logic;
-- MT endpoints
signal rmq_endpoint_out : t_mt_rmq_endpoint_iface_out;
signal rmq_endpoint_in : t_mt_rmq_endpoint_iface_in;
signal rmq_src_in : t_mt_stream_source_in;
signal rmq_src_out : t_mt_stream_source_out;
signal rmq_src_cfg_in : t_mt_stream_config_in;
signal rmq_src_cfg_out : t_mt_stream_config_out;
signal rmq_snk_in : t_mt_stream_sink_in;
signal rmq_snk_out : t_mt_stream_sink_out;
signal rmq_snk_cfg_in : t_mt_stream_config_in;
signal rmq_snk_cfg_out : t_mt_stream_config_out;
-- MT fabric.
signal eth_tx_out : t_wrf_source_out;
signal eth_tx_in : t_wrf_source_in;
signal eth_rx_out : t_wrf_sink_out;
signal eth_rx_in : t_wrf_sink_in;
-- MT Dedicated WB interfaces to FMCs
signal fmc_dp_wb_out : t_wishbone_master_out_array(0 to 1);
signal fmc_dp_wb_in : t_wishbone_master_in_array(0 to 1);
-- Muxed Host and MT WB interface to FMC1
signal fmc1_mux_wb_out : t_wishbone_master_out;
signal fmc1_mux_wb_in : t_wishbone_master_in;
-- WRPC TM interface and aux clocks
signal tm_link_up : std_logic;
signal tm_tai : std_logic_vector(39 downto 0);
signal tm_cycles : std_logic_vector(27 downto 0);
signal tm_time_valid : std_logic;
signal tm_clk_aux_lock_en : std_logic_vector(1 downto 0);
signal tm_clk_aux_locked : std_logic_vector(1 downto 0);
signal tm_dac_value : std_logic_vector(23 downto 0);
signal tm_dac_wr : std_logic_vector(1 downto 0);
-- MT TM interface
signal tm : t_mt_timing_if;
-- Misc FMC signals
signal fmc1_fd_tdc_start : std_logic;
signal ddr1_pll_reset : std_logic;
signal ddr1_pll_locked : std_logic;
signal fmc1_fd_pll_status : std_logic;
signal fmc1_fd_tdc_data_out : std_logic_vector(27 downto 0);
signal fmc1_fd_tdc_data_in : std_logic_vector(27 downto 0);
signal fmc1_fd_tdc_data_oe : std_logic;
signal fmc1_fd_owr_en, fmc1_fd_owr_in : std_logic;
signal fmc1_fd_scl_out, fmc1_fd_scl_in : std_logic;
signal fmc1_fd_sda_out, fmc1_fd_sda_in : std_logic;
signal fmc0_scl_out : std_logic;
signal fmc0_sda_out : std_logic;
attribute iob : string;
attribute iob of pps : signal is "FORCE";
begin -- architecture arch
-----------------------------------------------------------------------------
-- System reset
-----------------------------------------------------------------------------
areset_n <= vme_sysreset_n_i and rst_n_i;
-----------------------------------------------------------------------------
-- Primary wishbone Crossbar
-----------------------------------------------------------------------------
cmp_sdb_crossbar : xwb_sdb_crossbar
generic map (
g_VERBOSE => FALSE,
g_NUM_MASTERS => c_NUM_WB_MASTERS,
g_NUM_SLAVES => c_NUM_WB_SLAVES,
g_REGISTERED => TRUE,
g_WRAPAROUND => TRUE,
g_LAYOUT => c_WB_LAYOUT,
g_SDB_ADDR => c_SDB_ADDRESS)
port map (
clk_sys_i => clk_sys_62m5,
rst_n_i => rst_sys_62m5_n,
slave_i => cnx_master_out,
slave_o => cnx_master_in,
master_i => cnx_slave_out,
master_o => cnx_slave_in);
-----------------------------------------------------------------------------
-- VME64x Core (WB Master)
-----------------------------------------------------------------------------
gen_with_vme64_core : if not g_SIM_BYPASS_VME generate
cmp_vme_core : xvme64x_core
generic map (
g_CLOCK_PERIOD => 16,
g_DECODE_AM => TRUE,
g_USER_CSR_EXT => FALSE,
g_WB_GRANULARITY => BYTE,
g_MANUFACTURER_ID => c_CERN_ID,
g_BOARD_ID => c_SVEC_ID,
g_REVISION_ID => c_SVEC_REVISION_ID,
g_PROGRAM_ID => c_SVEC_PROGRAM_ID)
port map (
clk_i => clk_sys_62m5,
rst_n_i => rst_sys_62m5_n,
vme_i.as_n => vme_as_n_i,
vme_i.rst_n => vme_sysreset_n_i,
vme_i.write_n => vme_write_n_i,
vme_i.am => vme_am_i,
vme_i.ds_n => vme_ds_n_i,
vme_i.ga => vme_ga,
vme_i.lword_n => vme_lword_n_b,
vme_i.addr => vme_addr_b,
vme_i.data => vme_data_b,
vme_i.iack_n => vme_iack_n_i,
vme_i.iackin_n => vme_iackin_n_i,
vme_o.berr_n => vme_berr_n,
vme_o.dtack_n => vme_dtack_n_o,
vme_o.retry_n => vme_retry_n_o,
vme_o.retry_oe => vme_retry_oe_o,
vme_o.lword_n => vme_lword_n_b_out,
vme_o.data => vme_data_b_out,
vme_o.addr => vme_addr_b_out,
vme_o.irq_n => vme_irq_n,
vme_o.iackout_n => vme_iackout_n_o,
vme_o.dtack_oe => vme_dtack_oe_o,
vme_o.data_dir => vme_data_dir_int,
vme_o.data_oe_n => vme_data_oe_n_o,
vme_o.addr_dir => vme_addr_dir_int,
vme_o.addr_oe_n => vme_addr_oe_n_o,
wb_o => cnx_master_out(c_WB_MASTER_VME),
wb_i => cnx_master_in(c_WB_MASTER_VME),
int_i => vic_master_irq);
vme_ga <= vme_gap_i & vme_ga_i;
vme_berr_o <= not vme_berr_n;
vme_irq_o <= not vme_irq_n;
-- VME tri-state buffers
vme_data_b <= vme_data_b_out when vme_data_dir_int = '1' else (others => 'Z');
vme_addr_b <= vme_addr_b_out when vme_addr_dir_int = '1' else (others => 'Z');
vme_lword_n_b <= vme_lword_n_b_out when vme_addr_dir_int = '1' else 'Z';
vme_addr_dir_o <= vme_addr_dir_int;
vme_data_dir_o <= vme_data_dir_int;
end generate gen_with_vme64_core;
gen_without_vme64_core : if g_SIM_BYPASS_VME generate
-- synthesis translate_off
cnx_master_out(c_WB_MASTER_VME) <= sim_wb_i;
sim_wb_o <= cnx_master_in(c_WB_MASTER_VME);
-- synthesis translate_on
end generate gen_without_vme64_core;
cmp_vme_led_extend : gc_extend_pulse
generic map (
g_width => 5000000)
port map (
clk_i => clk_sys_62m5,
rst_n_i => rst_sys_62m5_n,
pulse_i => cnx_slave_in(c_WB_MASTER_VME).cyc,
extended_o => vme_access_led);
-----------------------------------------------------------------------------
-- Vectored Interrupt Controller (WB Slave)
-----------------------------------------------------------------------------
cmp_vic : xwb_vic
generic map (
g_INTERFACE_MODE => PIPELINED,
g_ADDRESS_GRANULARITY => BYTE,
g_NUM_INTERRUPTS => 6,
g_INIT_VECTORS => c_VIC_VECTOR_TABLE)
port map (
clk_sys_i => clk_sys_62m5,
rst_n_i => rst_sys_62m5_n,
slave_i => cnx_slave_in(c_WB_SLAVE_VIC),
slave_o => cnx_slave_out(c_WB_SLAVE_VIC),
irqs_i(0) => fmc_host_irq(0),
irqs_i(1) => fmc_host_irq(1),
irqs_i(2) => mt_hmq_in_irq,
irqs_i(3) => mt_hmq_out_irq,
irqs_i(4) => mt_console_irq,
irqs_i(5) => mt_notify_irq,
irq_master_o => vic_master_irq);
-----------------------------------------------------------------------------
-- Mock Turtle (WB Slave)
-----------------------------------------------------------------------------
cmp_mock_turtle : entity work.mock_turtle_core
generic map (
g_CONFIG => c_MT_CONFIG,
g_CPU0_IRAM_INITF => g_MT_CPU0_INITF,
g_CPU1_IRAM_INITF => g_MT_CPU1_INITF,
g_WITH_WHITE_RABBIT => TRUE)
port map (
clk_i => clk_sys_62m5,
rst_n_i => rst_sys_62m5_n,
sp_master_o => open,
sp_master_i => c_DUMMY_WB_MASTER_IN,
dp_master_o => fmc_dp_wb_out,
dp_master_i => fmc_dp_wb_in,
rmq_endpoint_o => rmq_endpoint_out,
rmq_endpoint_i => rmq_endpoint_in,
host_slave_i => cnx_slave_in(c_WB_SLAVE_MT),
host_slave_o => cnx_slave_out(c_WB_SLAVE_MT),
clk_ref_i => clk_ref_125m,
tm_i => tm,
hmq_in_irq_o => mt_hmq_in_irq,
hmq_out_irq_o => mt_hmq_out_irq,
notify_irq_o => mt_notify_irq,
console_irq_o => mt_console_irq);
tm.cycles <= tm_cycles;
tm.tai <= tm_tai;
tm.time_valid <= tm_time_valid;
tm.link_up <= tm_link_up;
tm.aux_locked(1 downto 0) <= tm_clk_aux_locked;
tm.aux_locked(7 downto 2) <= (others => '0');
cmp_eth_endpoint : entity work.mt_ep_ethernet_single
port map (
clk_i => clk_sys_62m5,
rst_n_i => rst_sys_62m5_n,
rmq_src_i => rmq_src_in,
rmq_src_o => rmq_src_out,
rmq_src_config_i => rmq_snk_cfg_out,
rmq_src_config_o => rmq_snk_cfg_in,
rmq_snk_i => rmq_snk_in,
rmq_snk_o => rmq_snk_out,
rmq_snk_config_i => rmq_src_cfg_out,
rmq_snk_config_o => rmq_src_cfg_in,
eth_src_o => eth_tx_out,
eth_src_i => eth_tx_in,
eth_snk_o => eth_rx_out,
eth_snk_i => eth_rx_in);
p_rmq_assign : process (rmq_endpoint_out, rmq_snk_cfg_in, rmq_snk_out,
rmq_src_cfg_in, rmq_src_out) is
begin
rmq_endpoint_in <= c_MT_RMQ_ENDPOINT_IFACE_IN_DEFAULT_VALUE;
-- WR->MT (RX, to MT CPU1)
rmq_src_in <= rmq_endpoint_out.snk_out(1)(0);
rmq_endpoint_in.snk_in(1)(0) <= rmq_src_out;
rmq_snk_cfg_out <= rmq_endpoint_out.snk_config_out(1)(0);
rmq_endpoint_in.snk_config_in(1)(0) <= rmq_snk_cfg_in;
-- MT->WR (TX, from MT CPU0)
rmq_snk_in <= rmq_endpoint_out.src_out(0)(0);
rmq_endpoint_in.src_in(0)(0) <= rmq_snk_out;
rmq_src_cfg_out <= rmq_endpoint_out.src_config_out(0)(0);
rmq_endpoint_in.src_config_in(0)(0) <= rmq_src_cfg_in;
end process p_rmq_assign;
-----------------------------------------------------------------------------
-- The WR PTP core SVEC board package (WB Slave)
-----------------------------------------------------------------------------
cmp_xwrc_board_svec : xwrc_board_svec
generic map (
g_SIMULATION => g_SIMULATION,
g_VERBOSE => FALSE,
g_WITH_EXTERNAL_CLOCK_INPUT => TRUE,
g_DPRAM_INITF => g_WRPC_INITF,
g_AUX_CLKS => 2)
port map (
clk_20m_vcxo_i => clk_20m_vcxo_i,
clk_125m_pllref_p_i => clk_125m_pllref_p_i,
clk_125m_pllref_n_i => clk_125m_pllref_n_i,
clk_125m_gtp_n_i => clk_125m_gtp_n_i,
clk_125m_gtp_p_i => clk_125m_gtp_p_i,
clk_10m_ext_i => clk_ext_ref,
clk_aux_i(0) => tdc_clk_125m,
clk_aux_i(1) => dcm1_clk_ref_0,
areset_n_i => areset_n,
clk_sys_62m5_o => clk_sys_62m5,
clk_ref_125m_o => clk_ref_125m,
rst_sys_62m5_n_o => rst_sys_62m5_n,
pll20dac_din_o => pll20dac_din_o,
pll20dac_sclk_o => pll20dac_sclk_o,
pll20dac_sync_n_o => pll20dac_sync_n_o,
pll25dac_din_o => pll25dac_din_o,
pll25dac_sclk_o => pll25dac_sclk_o,
pll25dac_sync_n_o => pll25dac_sync_n_o,
sfp_txp_o => sfp_txp_o,
sfp_txn_o => sfp_txn_o,
sfp_rxp_i => sfp_rxp_i,
sfp_rxn_i => sfp_rxn_i,
sfp_det_i => sfp_mod_def0_i,
sfp_sda_i => sfp_sda_in,
sfp_sda_o => sfp_sda_out,
sfp_scl_i => sfp_scl_in,
sfp_scl_o => sfp_scl_out,
sfp_rate_select_o => sfp_rate_select_o,
sfp_tx_fault_i => sfp_tx_fault_i,
sfp_tx_disable_o => sfp_tx_disable_o,
sfp_los_i => sfp_los_i,
eeprom_sda_i => eeprom_sda_in,
eeprom_sda_o => eeprom_sda_out,
eeprom_scl_i => eeprom_scl_in,
eeprom_scl_o => eeprom_scl_out,
onewire_i => onewire_data,
onewire_oen_o => onewire_oe,
uart_rxd_i => uart_rxd_i,
uart_txd_o => uart_txd_o,
spi_sclk_o => spi_sclk_o,
spi_ncs_o => spi_ncs_o,
spi_mosi_o => spi_mosi_o,
spi_miso_i => spi_miso_i,
wb_slave_o => cnx_slave_out(c_WB_SLAVE_WRC),
wb_slave_i => cnx_slave_in(c_WB_SLAVE_WRC),
wrf_src_o => eth_rx_in,
wrf_src_i => eth_rx_out,
wrf_snk_o => eth_tx_in,
wrf_snk_i => eth_tx_out,
tm_link_up_o => tm_link_up,
tm_time_valid_o => tm_time_valid,
tm_tai_o => tm_tai,
tm_cycles_o => tm_cycles,
tm_dac_value_o => tm_dac_value,
tm_dac_wr_o => tm_dac_wr,
tm_clk_aux_lock_en_i => tm_clk_aux_lock_en,
tm_clk_aux_locked_o => tm_clk_aux_locked,
pps_ext_i => pps_ext_in,
pps_p_o => pps,
pps_led_o => pps_led,
led_link_o => wr_led_link,
led_act_o => wr_led_act);
-- tri-state Carrier EEPROM
carrier_sda_b <= '0' when (eeprom_sda_out = '0') else 'Z';
eeprom_sda_in <= carrier_sda_b;
carrier_scl_b <= '0' when (eeprom_scl_out = '0') else 'Z';
eeprom_scl_in <= carrier_scl_b;
-- Tristates for SFP EEPROM
sfp_mod_def1_b <= '0' when sfp_scl_out = '0' else 'Z';
sfp_mod_def2_b <= '0' when sfp_sda_out = '0' else 'Z';
sfp_scl_in <= sfp_mod_def1_b;
sfp_sda_in <= sfp_mod_def2_b;
-- tri-state onewire access
carrier_onewire_b <= '0' when (onewire_oe = '1') else 'Z';
onewire_data <= carrier_onewire_b;
-----------------------------------------------------------------------------
-- FMC TDC (SVEC slot #1)
-----------------------------------------------------------------------------
U_TDC_Core : fmc_tdc_wrapper
generic map (
g_SIMULATION => f_int2bool(g_SIMULATION),
g_WITH_DIRECT_READOUT => TRUE)
port map (
clk_sys_i => clk_sys_62m5,
rst_sys_n_i => rst_sys_62m5_n,
rst_n_a_i => rst_sys_62m5_n,
pll_sclk_o => fmc0_tdc_pll_sclk_o,
pll_sdi_o => fmc0_tdc_pll_sdi_o,
pll_cs_o => fmc0_tdc_pll_cs_n_o,
pll_dac_sync_o => fmc0_tdc_pll_dac_sync_n_o,
pll_sdo_i => fmc0_tdc_pll_sdo_i,
pll_status_i => fmc0_tdc_pll_status_i,
tdc_clk_125m_p_i => fmc0_tdc_125m_clk_p_i,
tdc_clk_125m_n_i => fmc0_tdc_125m_clk_n_i,
acam_refclk_p_i => fmc0_tdc_acam_refclk_p_i,
acam_refclk_n_i => fmc0_tdc_acam_refclk_n_i,
start_from_fpga_o => fmc0_tdc_start_from_fpga_o,
err_flag_i => fmc0_tdc_err_flag_i,
int_flag_i => fmc0_tdc_int_flag_i,
start_dis_o => fmc0_tdc_start_dis_o,
stop_dis_o => fmc0_tdc_stop_dis_o,
data_bus_io => fmc0_tdc_data_bus_io,
address_o => fmc0_tdc_address_o,
cs_n_o => fmc0_tdc_cs_n_o,
oe_n_o => fmc0_tdc_oe_n_o,
rd_n_o => fmc0_tdc_rd_n_o,
wr_n_o => fmc0_tdc_wr_n_o,
ef1_i => fmc0_tdc_ef1_i,
ef2_i => fmc0_tdc_ef2_i,
enable_inputs_o => fmc0_tdc_enable_inputs_o,
term_en_1_o => fmc0_tdc_term_en_1_o,
term_en_2_o => fmc0_tdc_term_en_2_o,
term_en_3_o => fmc0_tdc_term_en_3_o,
term_en_4_o => fmc0_tdc_term_en_4_o,
term_en_5_o => fmc0_tdc_term_en_5_o,
tdc_led_status_o => fmc0_tdc_led_status_o,
tdc_led_trig1_o => fmc0_tdc_led_trig1_o,
tdc_led_trig2_o => fmc0_tdc_led_trig2_o,
tdc_led_trig3_o => fmc0_tdc_led_trig3_o,
tdc_led_trig4_o => fmc0_tdc_led_trig4_o,
tdc_led_trig5_o => fmc0_tdc_led_trig5_o,
tdc_in_fpga_1_i => fmc0_tdc_in_fpga_1_i,
tdc_in_fpga_2_i => fmc0_tdc_in_fpga_2_i,
tdc_in_fpga_3_i => fmc0_tdc_in_fpga_3_i,
tdc_in_fpga_4_i => fmc0_tdc_in_fpga_4_i,
tdc_in_fpga_5_i => fmc0_tdc_in_fpga_5_i,
mezz_scl_i => fmc0_scl_b,
mezz_sda_i => fmc0_sda_b,
mezz_scl_o => fmc0_scl_out,
mezz_sda_o => fmc0_sda_out,
mezz_one_wire_b => fmc0_tdc_one_wire_b,
tm_link_up_i => tm_link_up,
tm_time_valid_i => tm_time_valid,
tm_cycles_i => tm_cycles,
tm_tai_i => tm_tai,
tm_clk_aux_lock_en_o => tm_clk_aux_lock_en(0),
tm_clk_aux_locked_i => tm_clk_aux_locked(0),
tm_clk_dmtd_locked_i => '1',
tm_dac_value_i => tm_dac_value,
tm_dac_wr_i => tm_dac_wr(0),
direct_slave_i => fmc_dp_wb_out(0),
direct_slave_o => fmc_dp_wb_in(0),
slave_i => cnx_slave_in(c_WB_SLAVE_TDC),
slave_o => cnx_slave_out(c_WB_SLAVE_TDC),
irq_o => fmc_host_irq(0),
clk_125m_tdc_o => tdc_clk_125m);
fmc0_scl_b <= '0' when fmc0_scl_out = '0' else 'Z';
fmc0_sda_b <= '0' when fmc0_sda_out = '0' else 'Z';
-----------------------------------------------------------------------------
-- FMC FDELAY (SVEC slot #2)
-----------------------------------------------------------------------------
cmp_fd_tdc_start1 : IBUFDS
generic map (
DIFF_TERM => TRUE,
IBUF_LOW_PWR => FALSE)
port map (
O => fmc1_fd_tdc_start,
I => fmc1_fd_tdc_start_p_i,
IB => fmc1_fd_tdc_start_n_i);
U_DDR_PLL1 : fd_ddr_pll
port map (
RST => ddr1_pll_reset,
LOCKED => ddr1_pll_locked,
CLK_IN1_P => fmc1_fd_clk_ref_p_i,
CLK_IN1_N => fmc1_fd_clk_ref_n_i,
CLK_OUT1 => dcm1_clk_ref_0,
CLK_OUT2 => dcm1_clk_ref_180);
ddr1_pll_reset <= not fmc1_fd_pll_status_i;
fmc1_fd_pll_status <= fmc1_fd_pll_status_i and ddr1_pll_locked;
U_FineDelay_Core : fine_delay_core
generic map (
g_WITH_WR_CORE => TRUE,
g_SIMULATION => f_int2bool(g_SIMULATION),
g_INTERFACE_MODE => PIPELINED,
g_ADDRESS_GRANULARITY => BYTE)
port map (
clk_ref_0_i => dcm1_clk_ref_0,
clk_ref_180_i => dcm1_clk_ref_180,
clk_sys_i => clk_sys_62m5,
clk_dmtd_i => '0',
rst_n_i => rst_sys_62m5_n,
dcm_reset_o => open,
dcm_locked_i => ddr1_pll_locked,
trig_a_i => fmc1_fd_trig_a_i,
tdc_cal_pulse_o => fmc1_fd_tdc_cal_pulse_o,
tdc_start_i => fmc1_fd_tdc_start,
dmtd_fb_in_i => fmc1_fd_dmtd_fb_in_i,
dmtd_fb_out_i => fmc1_fd_dmtd_fb_out_i,
dmtd_samp_o => fmc1_fd_dmtd_clk_o,
led_trig_o => fmc1_fd_led_trig_o,
ext_rst_n_o => fmc1_fd_ext_rst_n_o,
pll_status_i => fmc1_fd_pll_status,
acam_d_o => fmc1_fd_tdc_data_out,
acam_d_i => fmc1_fd_tdc_data_in,
acam_d_oen_o => fmc1_fd_tdc_data_oe,
acam_emptyf_i => fmc1_fd_tdc_emptyf_i,
acam_alutrigger_o => fmc1_fd_tdc_alutrigger_o,
acam_wr_n_o => fmc1_fd_tdc_wr_n_o,
acam_rd_n_o => fmc1_fd_tdc_rd_n_o,
acam_start_dis_o => fmc1_fd_tdc_start_dis_o,
acam_stop_dis_o => fmc1_fd_tdc_stop_dis_o,
spi_cs_dac_n_o => fmc1_fd_spi_cs_dac_n_o,
spi_cs_pll_n_o => fmc1_fd_spi_cs_pll_n_o,
spi_cs_gpio_n_o => fmc1_fd_spi_cs_gpio_n_o,
spi_sclk_o => fmc1_fd_spi_sclk_o,
spi_mosi_o => fmc1_fd_spi_mosi_o,
spi_miso_i => fmc1_fd_spi_miso_i,
delay_len_o => fmc1_fd_delay_len_o,
delay_val_o => fmc1_fd_delay_val_o,
delay_pulse_o => fmc1_fd_delay_pulse_o,
tm_link_up_i => tm_link_up,
tm_time_valid_i => tm_time_valid,
tm_cycles_i => tm_cycles,
tm_utc_i => tm_tai,
tm_clk_aux_lock_en_o => tm_clk_aux_lock_en(1),
tm_clk_aux_locked_i => tm_clk_aux_locked(1),
tm_clk_dmtd_locked_i => '1',
tm_dac_value_i => tm_dac_value,
tm_dac_wr_i => tm_dac_wr(1),
owr_en_o => fmc1_fd_owr_en,
owr_i => fmc1_fd_owr_in,
i2c_scl_oen_o => fmc1_fd_scl_out,
i2c_scl_i => fmc1_fd_scl_in,
i2c_sda_oen_o => fmc1_fd_sda_out,
i2c_sda_i => fmc1_fd_sda_in,
fmc_present_n_i => fmc1_prsntm2c_n_i,
wb_adr_i => fmc1_mux_wb_out.adr,
wb_dat_i => fmc1_mux_wb_out.dat,
wb_dat_o => fmc1_mux_wb_in.dat,
wb_sel_i => fmc1_mux_wb_out.sel,
wb_cyc_i => fmc1_mux_wb_out.cyc,
wb_stb_i => fmc1_mux_wb_out.stb,
wb_we_i => fmc1_mux_wb_out.we,
wb_ack_o => fmc1_mux_wb_in.ack,
wb_stall_o => fmc1_mux_wb_in.stall,
wb_irq_o => fmc_host_irq(1));
cmp_fmc1_wb_mux : xwb_crossbar
generic map (
g_VERBOSE => FALSE,
g_NUM_MASTERS => 2,
g_NUM_SLAVES => 1,
g_REGISTERED => TRUE,
g_ADDRESS => c_FMC_MUX_ADDR,
g_MASK => c_FMC_MUX_MASK)
port map (
clk_sys_i => clk_sys_62m5,
rst_n_i => rst_sys_62m5_n,
slave_i(0) => fmc_dp_wb_out(1),
slave_i(1) => cnx_slave_in(c_WB_SLAVE_FDL),
slave_o(0) => fmc_dp_wb_in(1),
slave_o(1) => cnx_slave_out(c_WB_SLAVE_FDL),
master_i(0) => fmc1_mux_wb_in,
master_o(0) => fmc1_mux_wb_out);
fmc1_mux_wb_in.err <= '0';
fmc1_mux_wb_in.rty <= '0';
-- tristate buffer for the TDC data bus:
fmc1_fd_tdc_d_b <= fmc1_fd_tdc_data_out when fmc1_fd_tdc_data_oe = '1' else (others => 'Z');
fmc1_fd_tdc_oe_n_o <= '1';
fmc1_fd_tdc_data_in <= fmc1_fd_tdc_d_b;
fmc1_fd_onewire_b <= '0' when fmc1_fd_owr_en = '1' else 'Z';
fmc1_fd_owr_in <= fmc1_fd_onewire_b;
fmc1_scl_b <= '0' when (fmc1_fd_scl_out = '0') else 'Z';
fmc1_sda_b <= '0' when (fmc1_fd_sda_out = '0') else 'Z';
fmc1_fd_scl_in <= fmc1_scl_b;
fmc1_fd_sda_in <= fmc1_sda_b;
-----------------------------------------------------------------------------
-- Carrier front panel LEDs and LEMOs
-----------------------------------------------------------------------------
cmp_led_controller : gc_bicolor_led_ctrl
generic map(
g_NB_COLUMN => 4,
g_NB_LINE => 2,
g_CLK_FREQ => 62500000, -- in Hz
g_REFRESH_RATE => 250 -- in Hz
)
port map(
rst_n_i => rst_sys_62m5_n,
clk_i => clk_sys_62m5,
led_intensity_i => "1100100", -- in %
led_state_i => svec_led,
column_o => fp_led_column_o,
line_o => fp_led_line_o,
line_oen_o => fp_led_line_oen_o);
-- LED 4
svec_led(1 downto 0) <= c_LED_GREEN when wr_led_link = '1' else c_LED_RED;
-- LED 3
svec_led(3 downto 2) <= c_LED_GREEN when tm_clk_aux_locked(1) = '1' else c_LED_RED;
-- LED 2
svec_led(5 downto 4) <= c_LED_GREEN when tm_time_valid = '1' else c_LED_RED;
-- LED 1
svec_led(7 downto 6) <= c_LED_RED_GREEN when vme_access_led = '1' else c_LED_OFF;
-- LED 8
svec_led(9 downto 8) <= c_LED_RED_GREEN when wr_led_act = '1' else c_LED_OFF;
-- LED 7
svec_led(11 downto 10) <= c_LED_GREEN when tm_clk_aux_locked(0) = '1' else c_LED_RED;
-- LED 6
svec_led(13 downto 12) <= c_LED_OFF;
-- LED 5
svec_led(15 downto 14) <= c_LED_GREEN when pps_led = '1' else c_LED_OFF;
-- Div by 2 reference clock to LEMO connector
process(clk_ref_125m)
begin
if rising_edge(clk_ref_125m) then
clk_ref_div2 <= not clk_ref_div2;
end if;
end process;
-- Front panel IO configuration
fp_gpio1_o <= pps;
fp_gpio2_o <= clk_ref_div2;
clk_ext_ref <= fp_gpio3_i;
pps_ext_in <= fp_gpio4_i;
fp_term_en_o <= (others => '0');
fp_gpio1_a2b_o <= '1';
fp_gpio2_a2b_o <= '1';
fp_gpio34_a2b_o <= '0';
end architecture arch;
wrtd-53772dc3cd49421ea1fa6326a199b7a72dc04d18/software/ 0000775 0000000 0000000 00000000000 13460261316 0021242 5 ustar 00root root 0000000 0000000 wrtd-53772dc3cd49421ea1fa6326a199b7a72dc04d18/software/.gitignore 0000664 0000000 0000000 00000000037 13460261316 0023232 0 ustar 00root root 0000000 0000000 *.o
parent_common.mk
common.mk
wrtd-53772dc3cd49421ea1fa6326a199b7a72dc04d18/software/Makefile 0000664 0000000 0000000 00000001147 13460261316 0022705 0 ustar 00root root 0000000 0000000 -include Makefile.specific
# include parent_common.mk for buildsystem's defines
# use absolute path for REPO_PARENT
CURDIR:=$(shell /bin/pwd)
REPO_PARENT ?= $(CURDIR)/..
-include $(REPO_PARENT)/parent_common.mk
# This can be overriden in cases where WRTD itself is a dependency
# and one does not want to recursively check out WRTD's dependency
# on Mock Turtle.
WRTD_DEP_TRTL ?= $(CURDIR)/../dependencies/mock-turtle
DIRS = $(WRTD_DEP_TRTL)/software lib tools firmware
all clean: $(DIRS)
tools: lib
.PHONY: all clean $(DIRS)
clean: TARGET = clean
modules: TARGET = modules
$(DIRS):
$(MAKE) -C $@ $(TARGET)
wrtd-53772dc3cd49421ea1fa6326a199b7a72dc04d18/software/firmware/ 0000775 0000000 0000000 00000000000 13460261316 0023056 5 ustar 00root root 0000000 0000000 wrtd-53772dc3cd49421ea1fa6326a199b7a72dc04d18/software/firmware/.gitignore 0000664 0000000 0000000 00000000110 13460261316 0025036 0 ustar 00root root 0000000 0000000 *.elf
*.bin
*.o
*.d
*.bram
Makefile.specific
build/
.config
.config.old
wrtd-53772dc3cd49421ea1fa6326a199b7a72dc04d18/software/firmware/Makefile 0000664 0000000 0000000 00000000725 13460261316 0024522 0 ustar 00root root 0000000 0000000 -include Makefile.specific
DIRS := tdc fd adc
all clean cleanall modules install modules_install: $(DIRS)
clean: TARGET = clean
cleanall: TARGET = cleanall
modules: TARGET = modules
install: TARGET = install
modules_install: TARGET = modules_install
DOT-CONFIGS = $(addsuffix /.config,$(DIRS))
$(DIRS): $(DOT-CONFIGS)
$(MAKE) -C $@ $(TARGET)
$(DOT-CONFIGS):
$(MAKE) -C $(@D) defconfig
.PHONY: all clean cleanall modules install modules_install
.PHONY: $(DIRS)
wrtd-53772dc3cd49421ea1fa6326a199b7a72dc04d18/software/firmware/adc/ 0000775 0000000 0000000 00000000000 13460261316 0023605 5 ustar 00root root 0000000 0000000 wrtd-53772dc3cd49421ea1fa6326a199b7a72dc04d18/software/firmware/adc/Kconfig 0000664 0000000 0000000 00000000212 13460261316 0025103 0 ustar 00root root 0000000 0000000 mainmenu "WRTD ADC firmware configuration"
comment "Project specific configuration"
# include Mock Turtle's Kconfig
source "Kconfig.mt"
wrtd-53772dc3cd49421ea1fa6326a199b7a72dc04d18/software/firmware/adc/Makefile 0000664 0000000 0000000 00000001244 13460261316 0025246 0 ustar 00root root 0000000 0000000 -include Makefile.specific
CUR_DIR := $(shell pwd)
WRTD_DEP_TRTL_FW ?= $(CUR_DIR)/../../../dependencies/mock-turtle/software/firmware
WRTD_DEP_FMC_ADC ?= $(CUR_DIR)/../../../dependencies/fmc-adc-100m14b4cha-gw
WRTD_DEP_GEN_CORES ?= $(CUR_DIR)/../../../dependencies/general-cores
EXTRA2_CFLAGS += # To be set by user on make line
EXTRA_CFLAGS += $(EXTRA2_CFLAGS)
EXTRA_CFLAGS += -I$(CUR_DIR)/../../include
EXTRA_CFLAGS += -I$(CUR_DIR)/../common
EXTRA_CFLAGS += -I$(WRTD_DEP_FMC_ADC)/hdl/rtl/wb_gen
all:
# Redirect all rules to MockTurtle
%:
$(MAKE) -C $(WRTD_DEP_TRTL_FW) M=$(shell /bin/pwd) \
GEN_CORES=$(WRTD_DEP_GEN_CORES) EXTRA_CFLAGS="$(EXTRA_CFLAGS)" $@
wrtd-53772dc3cd49421ea1fa6326a199b7a72dc04d18/software/firmware/adc/TBuild 0000664 0000000 0000000 00000000054 13460261316 0024712 0 ustar 00root root 0000000 0000000 OBJS := wrtd-rt-adc.o
OUTPUT = wrtd-rt-adc
wrtd-53772dc3cd49421ea1fa6326a199b7a72dc04d18/software/firmware/adc/configs/ 0000775 0000000 0000000 00000000000 13460261316 0025235 5 ustar 00root root 0000000 0000000 wrtd-53772dc3cd49421ea1fa6326a199b7a72dc04d18/software/firmware/adc/configs/mt_defconfig 0000664 0000000 0000000 00000001477 13460261316 0027615 0 ustar 00root root 0000000 0000000 #
# Automatically generated file; DO NOT EDIT.
# fmc-svec-carrier fw-01 demo configuration
#
#
# Project specific configuration
#
#
# Mock Turtle configuration
#
CONFIG_FPGA_APPLICATION_ID=0
CONFIG_RT_APPLICATION_ID=0
CONFIG_CFLAGS_OPT="-Os"
CONFIG_CFLAGS_EXTRA="-ggdb"
#
# Mock Turtle framework configuration
#
CONFIG_MOCKTURTLE_FRAMEWORK_ENABLE=y
CONFIG_MOCKTURTLE_FRAMEWORK_ACTION_ENABLE=y
CONFIG_MOCKTURTLE_FRAMEWORK_VARIABLE_ENABLE=y
CONFIG_MOCKTURTLE_FRAMEWORK_BUFFER_ENABLE=y
CONFIG_MOCKTURTLE_FRAMEWORK_PING_ENABLE=y
CONFIG_MOCKTURTLE_FRAMEWORK_VERSION_ENABLE=y
#
# Mock Turtle library configuration
#
CONFIG_MOCKTURTLE_LIBRARY_PRINT_ENABLE=y
# CONFIG_MOCKTURTLE_LIBRARY_PRINT_DEBUG_ENABLE is not set
# CONFIG_MOCKTURTLE_LIBRARY_PRINT_ERROR_ENABLE is not set
# CONFIG_MOCKTURTLE_LIBRARY_PRINT_MESSAGE_ENABLE is not set
wrtd-53772dc3cd49421ea1fa6326a199b7a72dc04d18/software/firmware/adc/out_queue.h 0000664 0000000 0000000 00000005022 13460261316 0025770 0 ustar 00root root 0000000 0000000 /* Generic output queue.
User needs to define:
OUT_QUEUE_PREFIX: the prefix (ends with an '_')
OUT_QUEUE_SIZE: max length of the queue
OUT_QUEUE_MAXTIME: maximum time in advance.
*/
#ifndef OUT_QUEUE_PREFIX
#error "OUT_QUEUE_PREFIX not defined"
#endif
#define OUT_QUEUE_CONCAT2(x,y) x##y
#define OUT_QUEUE_CONCAT(x,y) OUT_QUEUE_CONCAT2(x,y)
#define OUT_QUEUE_NAME(x) OUT_QUEUE_CONCAT(OUT_QUEUE_PREFIX,x)
#define OUT_QUEUE_STRUCT OUT_QUEUE_NAME(out_queue)
struct OUT_QUEUE_STRUCT {
struct wrtd_event events[OUT_QUEUE_SIZE];
int head, tail, count;
/* Last timestamp value written to output config. */
uint32_t last_programmed_sec;
uint32_t last_programmed_ns;
};
/**
* Initializes an empty pulse queue
*/
static void OUT_QUEUE_NAME(out_queue_init)(struct OUT_QUEUE_STRUCT *p)
{
p->head = 0;
p->tail = 0;
p->count = 0;
p->last_programmed_sec = 0;
p->last_programmed_ns = 0;
}
/**
* Requests a new entry in a pulse queue. Returns pointer to the ne
* entry or NULL if the queue is full.
*/
static struct wrtd_event *OUT_QUEUE_NAME(out_queue_push)(struct OUT_QUEUE_STRUCT *p)
{
struct wrtd_event *ev;
if (p->count == OUT_QUEUE_SIZE)
return NULL;
ev = &p->events[p->head];
p->count++;
p->head++;
if (p->head == OUT_QUEUE_SIZE)
p->head = 0;
return ev;
}
/**
* Returns non-0 if pulse queue p contains any pulses.
*/
static inline int OUT_QUEUE_NAME(out_queue_empty)(struct OUT_QUEUE_STRUCT *p)
{
return (p->count == 0);
}
/**
* Returns the oldest entry in the pulse queue (or NULL if empty).
*/
static struct wrtd_event *OUT_QUEUE_NAME(out_queue_front)(struct OUT_QUEUE_STRUCT *p)
{
if (!p->count)
return NULL;
return &p->events[p->tail];
}
/**
* Releases the oldest entry from the pulse queue.
*/
static void OUT_QUEUE_NAME(out_queue_pop)(struct OUT_QUEUE_STRUCT *p)
{
p->tail++;
if(p->tail == OUT_QUEUE_SIZE)
p->tail = 0;
p->count--;
}
/**
* Checks if the timestamp of the last programmed pulse is lost because
* of timeout
*/
static int OUT_QUEUE_NAME(out_queue_check_timeout) (struct OUT_QUEUE_STRUCT *q,
struct wrtd_tstamp *now)
{
int delta;
if(q->last_programmed_sec > now->seconds + OUT_QUEUE_MAXTIME) {
pr_error("Enqueued event very far in the future. Dropping.");
return 0;
}
/* Current time exceeds FD setpoint? */
delta = now->seconds - q->last_programmed_sec;
if (delta != 0)
return delta > 0;
delta = now->ns - q->last_programmed_ns;
return (delta > 0);
}
#undef OUT_QUEUE_STRUCT
#undef OUT_QUEUE_NAME
#undef OUT_QUEUE_CONCAT
#undef OUT_QUEUE_CONCAT2
wrtd-53772dc3cd49421ea1fa6326a199b7a72dc04d18/software/firmware/adc/wrtd-adcin.c 0000664 0000000 0000000 00000005517 13460261316 0026015 0 ustar 00root root 0000000 0000000 /*
* Copyright (C) 2018 CERN (www.cern.ch)
* Author: Dimitris Lampridis
*
* SPDX-License-Identifier: LGPL-3.0-or-later
*/
/* ADCIN: trigger coming from the ADC mezzanine. */
#include "mockturtle-rt.h"
#define ADCIN_NUM_CHANNELS 5
struct wrtd_adcin_dev {
uint32_t io_addr;
/* FIXME: base channel (to create the event id). */
};
static inline void adcin_writel(const struct wrtd_adcin_dev *dev,
uint32_t value, uint32_t reg)
{
dp_writel(value, dev->io_addr + reg);
}
static inline uint32_t adcin_readl(const struct wrtd_adcin_dev *dev, uint32_t reg)
{
return dp_readl(dev->io_addr + reg);
}
static inline int adcin_wr_link_up(struct wrtd_adcin_dev *adcin)
{
return adcin_readl(adcin, ALT_TRIGOUT_STATUS) & ALT_TRIGOUT_WR_LINK;
}
static inline int adcin_wr_time_locked(struct wrtd_adcin_dev *adcin)
{
return 1;
}
static void adcin_wr_enable_lock(struct wrtd_adcin_dev *dev, int enable)
{
return;
}
static inline int adcin_wr_time_ready(struct wrtd_adcin_dev *adcin)
{
return adcin_readl(adcin, ALT_TRIGOUT_STATUS) & ALT_TRIGOUT_WR_VALID;
}
static inline int adcin_wr_sync_timeout(void)
{
return 0;
}
/**
* Handles input timestamps from all ADC channels.
*
* TODO: adc config: base address
* first channel number (for sid)
* time offset
*/
static void adcin_input(struct wrtd_adcin_dev *adcin)
{
uint32_t status = adcin_readl(adcin, ALT_TRIGOUT_STATUS);
uint32_t mask;
struct wrtd_event ev;
int i;
/* Poll the FIFO and read the timestamp */
if(!(status & ALT_TRIGOUT_TS_PRESENT))
return;
/* FIXME: MSB word ? */
mask = adcin_readl(adcin, ALT_TRIGOUT_TS_MASK_SEC + 0);
ev.ts.seconds = adcin_readl(adcin, ALT_TRIGOUT_TS_MASK_SEC + 4);
ev.ts.ns = adcin_readl(adcin, ALT_TRIGOUT_TS_CYCLES) * 8;
ev.ts.frac = 0;
for (i = 0; i < ADCIN_NUM_CHANNELS; i++) {
/* The last channel is the ext trigger with a different mask */
if ( i == ADCIN_NUM_CHANNELS - 1 ) {
if (!(mask & (ALT_TRIGOUT_EXT_MASK >> 32)))
continue;
}
else if (!(mask & ((ALT_TRIGOUT_CH1_MASK >> 32) << i)))
continue;
memset(ev.id, 0, WRTD_ID_LEN);
ev.id[0] = 'A';
ev.id[1] = 'D';
ev.id[2] = 'C';
ev.id[3] = 'I';
ev.id[4] = '1' + i;
ev.flags = 0;
wrtd_log(WRTD_LOG_MSG_EV_GENERATED,
WRTD_LOG_GENERATED_DEVICE + (i * 8), &ev, NULL);
/* Pass to wrtd. */
wrtd_route_in(&ev);
}
}
static int adcin_init(struct wrtd_adcin_dev *adcin)
{
/* Disable all channels. */
adcin_writel(adcin, 0, ALT_TRIGOUT_ENABLE);
pr_debug("adcin initialization complete\n\r");
return 0;
}
wrtd-53772dc3cd49421ea1fa6326a199b7a72dc04d18/software/firmware/adc/wrtd-adcout.c 0000664 0000000 0000000 00000011227 13460261316 0026211 0 ustar 00root root 0000000 0000000 /*
* Copyright (C) 2013-2018 CERN (www.cern.ch)
* Author: Federico Vaga
* Author: Tomasz Wlostowski
*
* SPDX-License-Identifier: LGPL-3.0-or-later
*/
/* ADCout: trigger ADC sampling. Output from the WRTD pov. */
#include
#include
#include "mockturtle-rt.h"
#include
#include "wrtd-common.h"
#include "fmc_adc_alt_trigin.h"
#define OUT_QUEUE_MAXTIME 10
#define OUT_QUEUE_PREFIX adcout_
#define OUT_QUEUE_SIZE 4
#include "out_queue.h"
struct wrtd_adcout_dev {
uint32_t io_addr;
int idle;
struct adcout_out_queue queue;
};
static inline int adcout_wr_present(struct wrtd_adcout_dev *fd)
{
return 1;
}
static inline int adcout_wr_link_up(struct wrtd_adcout_dev *fd)
{
return 1;
}
static inline int adcout_wr_time_locked(struct wrtd_adcout_dev *fd)
{
return 1;
}
static inline int adcout_wr_time_ready(struct wrtd_adcout_dev *fd)
{
return 1;
}
static inline int adcout_wr_sync_timeout(void)
{
return 0;
}
static void adcout_wr_enable_lock(struct wrtd_adcout_dev *fd, int enable)
{
return;
}
static inline void adcout_writel(struct wrtd_adcout_dev *dev, uint32_t value,
uint32_t reg)
{
dp_writel(value, dev->io_addr + reg);
}
static inline uint32_t adcout_readl (struct wrtd_adcout_dev *dev, uint32_t reg)
{
return dp_readl(dev->io_addr + reg);
}
/**
* Drop the given enqueued trigger
*/
static void adcout_drop_trigger(struct wrtd_adcout_dev *dev,
struct wrtd_event *ev, unsigned reason,
struct wrtd_tstamp *now)
{
struct adcout_out_queue *q = &dev->queue;
dev->idle = 1;
if (adcout_out_queue_empty(q)) {
/* Should never happen. */
return;
}
/* Drop the pulse */
adcout_out_queue_pop(q);
/* Disarm the ADC output */
adcout_writel(dev, 0, ALT_TRIGIN_CTRL);
wrtd_log(WRTD_LOG_MSG_EV_DISCARDED, reason, ev, now);
}
/**
* Output driving function. Reads pulses from the output queue,
* programs the output and updates the output statistics.
*/
static void adcout_output (struct wrtd_adcout_dev *dev)
{
struct adcout_out_queue *q = &dev->queue;
struct wrtd_event *ev = adcout_out_queue_front(q);
uint32_t ctrl = adcout_readl(dev, ALT_TRIGIN_CTRL);
struct wrtd_tstamp *ts;
/* Check if the output has triggered */
if (!dev->idle) {
#if 0
if (!wr_is_timing_ok()) {
/* Timing has been lost. */
drop_trigger(out, ev, q, WRTD_LOG_DISCARD_NO_SYNC);
return;
}
#endif
if (ctrl & ALT_TRIGIN_CTRL_ENABLE) {
/* Armed but still waiting for trigger */
struct wrtd_tstamp now;
ts_now(&now);
if (adcout_out_queue_check_timeout (q, &now)) {
/* Will never trigger. Missed. */
adcout_drop_trigger(dev, ev, WRTD_LOG_DISCARD_TIMEOUT, &now);
}
} else {
/* Has been triggered. */
wrtd_log(WRTD_LOG_MSG_EV_CONSUMED, WRTD_LOG_CONSUMED_DONE, ev, NULL);
adcout_out_queue_pop(q);
dev->idle = 1;
}
return;
}
/* Output is idle: check if there's something in the queue to execute */
if (adcout_out_queue_empty(q))
return;
ev = adcout_out_queue_front(q);
ts = &ev->ts;
if (!wr_is_timing_ok()) {
adcout_drop_trigger(dev, ev, WRTD_LOG_DISCARD_NO_SYNC, NULL);
return;
}
/* Program the output start time */
adcout_writel(dev, 0, ALT_TRIGIN_SECONDS + 0);
adcout_writel(dev, ts->seconds, ALT_TRIGIN_SECONDS + 4);
adcout_writel(dev, ts->ns / 8, ALT_TRIGIN_CYCLES);
adcout_writel(dev, ALT_TRIGIN_CTRL_ENABLE, ALT_TRIGIN_CTRL);
wrtd_log(WRTD_LOG_MSG_EV_CONSUMED, WRTD_LOG_CONSUMED_START, ev, NULL);
ts_add2_ns (ts, 8000);
/*
* Store the last programmed timestamp (+ some margin) and mark
* the output as busy
*/
q->last_programmed_sec = ts->seconds;
q->last_programmed_ns = ts->ns;
dev->idle = 0;
}
static void adcout_local_output(struct wrtd_adcout_dev *dev,
struct wrtd_event *ev, unsigned ch)
{
struct wrtd_event *pq_ev;
pq_ev = adcout_out_queue_push(&dev->queue);
if (!pq_ev) {
/* overflow.
FIXME: stats ? */
wrtd_log(WRTD_LOG_MSG_EV_DISCARDED, WRTD_LOG_DISCARD_OVERFLOW,
ev, NULL);
return;
}
*pq_ev = *ev;
}
#if 0
/**
* It disable the given channel and clear its internal queue
*/
static int wrtd_out_disable(struct trtl_fw_msg *msg_i,
struct trtl_fw_msg *msg_o)
{
uint32_t ch = ((uint32_t *)msg_i->payload)[0];
pulse_queue_init(&wrtd_out_channels[ch].queue);
fd_ch_writel(&wrtd_out_channels[ch], FD_DCR_MODE, FD_REG_DCR);
msg_o->header->msg_id = msg_i->header->msg_id;
return 0;
}
#endif
static void adcout_init(struct wrtd_adcout_dev *dev)
{
adcout_out_queue_init(&dev->queue);
dev->idle = 1;
pr_debug("adcout initialization complete\n\r");
}
wrtd-53772dc3cd49421ea1fa6326a199b7a72dc04d18/software/firmware/adc/wrtd-rt-adc.c 0000664 0000000 0000000 00000004210 13460261316 0026076 0 ustar 00root root 0000000 0000000 /*
* Copyright (C) 2013-2018 CERN (www.cern.ch)
* Author: Federico Vaga
* Author: Tomasz Wlostowski
*
* SPDX-License-Identifier: LGPL-3.0-or-later
*/
#include "mockturtle-rt.h"
#include
#include "wrtd-common.h"
#include "fmc_adc_alt_trigout.h"
#define NBR_CPUS 1
#define CPU_IDX 0
#define NBR_LOCAL_INPUTS 5
#define NBR_LOCAL_OUTPUTS 1
#define NBR_RULES 16
#define NBR_DEVICES 2
#define NBR_ALARMS 1
/* Addresses comes from cpu0 crossbar. */
#define DEVICES_IO_ADDR { TRTL_ADDR_DP_BASE + 0x0000, TRTL_ADDR_DP_BASE + 0x1000, 0, 0}
#define APP_ID WRTD_APP_ADCIO_5CH
#define APP_VER RT_VERSION(2, 0)
#define APP_NAME "wrtd-adc"
#define WRTD_NET_TX
#define WRTD_NET_RX
#include "wrtd-rt-common.h"
#include "wrtd-adcout.c"
#include "wrtd-adcin.c"
static struct wrtd_adcin_dev adcin0 =
{
.io_addr = 0x0000,
};
static struct wrtd_adcout_dev adcout0 =
{
.io_addr = 0x1000,
};
static inline int wr_link_up(void)
{
if (!adcin_wr_link_up(&adcin0))
return 0;
if (!adcout_wr_link_up(&adcout0))
return 0;
return 1;
}
static inline int wr_time_locked(void)
{
if (!adcin_wr_time_locked(&adcin0))
return 0;
if (!adcout_wr_time_locked(&adcout0))
return 0;
return 1;
}
static inline int wr_time_ready(void)
{
if (!adcin_wr_time_ready(&adcin0))
return 0;
if (!adcout_wr_time_ready(&adcout0))
return 0;
return 1;
}
static inline void wr_enable_lock(int enable)
{
adcin_wr_enable_lock(&adcin0, enable);
adcout_wr_enable_lock(&adcout0, enable);
}
static inline int wr_sync_timeout(void)
{
int res, val;
res = 0;
val = adcin_wr_sync_timeout();
res = val > res ? val : res;
val = adcout_wr_sync_timeout();
res = val > res ? val : res;
return res;
}
static void wrtd_local_output(struct wrtd_event *ev, unsigned ch)
{
adcout_local_output(&adcout0, ev, ch);
return;
}
static int wrtd_user_init(void)
{
adcin_init(&adcin0);
adcout_init(&adcout0);
wr_enable_lock(0);
pr_debug("rt-input firmware initialized.\n\r");
return 0;
}
static void wrtd_io(void)
{
adcin_input(&adcin0);
adcout_output(&adcout0);
}
wrtd-53772dc3cd49421ea1fa6326a199b7a72dc04d18/software/firmware/adc/wrtd-rt-adcout.c 0000664 0000000 0000000 00000004317 13460261316 0026636 0 ustar 00root root 0000000 0000000 /*
* Copyright (C) 2013-2018 CERN (www.cern.ch)
* Author: Federico Vaga
* Author: Tomasz Wlostowski
*
* SPDX-License-Identifier: LGPL-3.0-or-later
*/
#include "mockturtle-rt.h"
#include
#include "wrtd-common.h"
#include "fmc_adc_alt_trigout.h"
#define NBR_CPUS 1
#define CPU_IDX 0
#define NBR_LOCAL_INPUTS 5
#define NBR_LOCAL_OUTPUTS 0
#define NBR_RULES 16
#define NBR_DEVICES 1
#define NBR_ALARMS 0
#define DEVICES_IO_ADDR { TRTL_ADDR_DP_BASE + 0x0000, 0, 0, 0}
#define APP_ID WRTD_APP_ADCIN_5CH
#define APP_VER RT_VERSION(2, 0)
#define APP_NAME "wrtd-adcin"
#define WRTD_NET_TX
#include "wrtd-rt-common.h"
#include "wrtd-adcout.c"
static struct wrtd_adcout_dev adcout0 =
{
.io_addr = 0x0,
};
static inline int wr_link_up(void)
{
return adcout_wr_link_up(&adcout0);
}
static inline int wr_time_locked(void)
{
return adcout_wr_time_locked(&adcout0);
}
static inline int wr_time_ready(void)
{
return adcout_wr_time_ready(&adcout0);
}
static inline void wr_enable_lock(int enable)
{
}
static inline int wr_sync_timeout(void)
{
return 0;
}
static void wrtd_local_output(struct wrtd_event *ev, unsigned ch)
{
/* No output. */
return;
}
#ifdef SIMULATION
static int wrtd_i_sim_init(struct wrtd_tdc_dev *tdc)
{
/* TODO: preconfigure the rules. */
int i;
for(i = 0; i < TDC_NUM_CHANNELS; i++) {
wrtd_in_channels[i].config.log_level = WRTD_LOG_ALL;
wrtd_in_channels[i].config.id.system = 0;
wrtd_in_channels[i].config.id.source_port = i;
wrtd_in_channels[i].config.id.trigger = i;
wrtd_in_channels[i].config.flags =
WRTD_ENABLED | WRTD_ARMED | WRTD_TRIGGER_ASSIGNED;
}
tdc_writel(tdc, 0x40, BASE_DP_TDC_DIRECT + DR_REG_DEAD_TIME);
tdc_writel(tdc, 0x1f, BASE_DP_TDC_DIRECT + DR_REG_CHAN_ENABLE);
return 0;
}
#endif
static int wrtd_user_init(void)
{
#ifdef SIMULATION
/* Skip WR sync and automatically generate some events when
simulating */
wrtd_i_sim_init(&tdc0);
#else
adcout_init(&adcout0);
#endif
wr_enable_lock(0);
pr_debug("rt-input firmware initialized.\n\r");
return 0;
}
static void wrtd_io(void)
{
adcout_input(&adcout0);
}
wrtd-53772dc3cd49421ea1fa6326a199b7a72dc04d18/software/firmware/common/ 0000775 0000000 0000000 00000000000 13460261316 0024346 5 ustar 00root root 0000000 0000000 wrtd-53772dc3cd49421ea1fa6326a199b7a72dc04d18/software/firmware/common/hw/ 0000775 0000000 0000000 00000000000 13460261316 0024764 5 ustar 00root root 0000000 0000000 wrtd-53772dc3cd49421ea1fa6326a199b7a72dc04d18/software/firmware/common/hw/acam_gpx.h 0000664 0000000 0000000 00000006212 13460261316 0026715 0 ustar 00root root 0000000 0000000 /*
* acam_gpx.h
*
* Copyright (c) 2012-2013 CERN (http://www.cern.ch)
* Author: Tomasz Wlostowski
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation; version 2 of the License.
*/
#ifndef __ACAM_GPX_H
#define __ACAM_GPX_H
/* ACAM TDC-GPX Register bits definitions */
#define AR0_ROsc (1<<0)
#define AR0_RiseEn0 (1<<1)
#define AR0_FallEn0 (1<<2)
#define AR0_RiseEn1 (1<<3)
#define AR0_FallEn1 (1<<4)
#define AR0_RiseEn2 (1<<5)
#define AR0_FallEn2 (1<<6)
#define AR0_HQSel (1<<7)
#define AR0_TRiseEn(port) (1<<(10+port))
#define AR0_TFallEn(port) (1<<(19+port))
#define AR1_Adj(chan, value) (((value) & 0xf) << (chan * 4))
#define AR2_GMode (1<<0)
#define AR2_IMode (1<<1)
#define AR2_RMode (1<<2)
#define AR2_Disable(chan) (1<<(3+chan))
#define AR2_Adj(chan, value) (((value)&0xf)<<(12+4*(chan-7)))
#define AR2_DelRise1(value) (((value)&0x3)<<(20))
#define AR2_DelFall1(value) (((value)&0x3)<<(22))
#define AR2_DelRise2(value) (((value)&0x3)<<(24))
#define AR2_DelFall2(value) (((value)&0x3)<<(26))
#define AR3_DelTx(chan, value) (((value)&0x3)<<(5 + (chan-1) * 2))
#define AR3_RaSpeed(chan, value) (((value)&0x3)<<(21 + (chan) * 2))
#define AR4_RaSpeed(chan, value) (((value)&0x3)<<(10 + (chan-3) * 2))
#define AR3_Zero (0) // nothing interesting for the Fine Delay
#define AR4_StartTimer(value) ((value) & 0xff)
#define AR4_Quiet (1<<8)
#define AR4_MMode (1<<9)
#define AR4_MasterReset (1<<22)
#define AR4_PartialReset (1<<23)
#define AR4_AluTrigSoft (1<<24)
#define AR4_EFlagHiZN (1<<25)
#define AR4_MTimerStart (1<<26)
#define AR4_MTimerStop (1<<27)
#define AR5_StartOff1(value) ((value)&0x3ffff)
#define AR5_StopDisStart (1<<21)
#define AR5_StartDisStart (1<<22)
#define AR5_MasterAluTrig (1<<23)
#define AR5_PartialAluTrig (1<<24)
#define AR5_MasterOenTrig (1<<25)
#define AR5_PartialOenTrig (1<<26)
#define AR5_StartRetrig (1<<27)
#define AR6_Fill(value) ((value)&0xff)
#define AR6_StartOff2(value) (((value)&0x3ffff)<<8)
#define AR6_InSelECL (1<<26)
#define AR6_PowerOnECL (1<<27)
#define AR7_HSDiv(value) ((value)&0xff)
#define AR7_RefClkDiv(value) (((value)&0x7)<<8)
#define AR7_ResAdj (1<<11)
#define AR7_NegPhase (1<<12)
#define AR7_Track (1<<13)
#define AR7_MTimer(value) (((value) & 0x1ff)<<15)
#define AR14_16BitMode (1<<4)
#define AR8I_IFIFO1(reg) ((reg) & 0x1ffff)
#define AR8I_Slope1(reg) ((reg) & (1<<17) ? 1 : 0)
#define AR8I_StartN1(reg) (((reg) >> 18) & 0xff)
#define AR8I_ChaCode1(reg) (((reg) >> 26) & 0x3)
#define AR9I_IFIFO2(reg) ((reg) & 0x1ffff)
#define AR9I_Slope2(reg) ((reg) & (1<<17) ? 1 : 0)
#define AR9I_StartN2(reg) (((reg) >> 18) & 0xff)
#define AR9I_ChaCode2(reg) (((reg) >> 26) & 0x3)
#define AR8R_IFIFO1(reg) ((reg) & 0x3fffff)
#define AR9R_IFIFO2(reg) ((reg) & 0x3fffff)
#define AR11_StopCounter0(num) ((num) & 0xff)
#define AR11_StopCounter1(num) (((num) & 0xff) << 8)
#define AR11_HFifoErrU(num) (1 << (num+16))
#define AR11_IFifoErrU(num) (1 << (num+24))
#define AR11_NotLockErrU (1 << 26)
#define AR12_HFifoE (1<<11)
#define AR12_NotLocked (1<<10)
#define AR12_StartNU (1<<26)
#endif
wrtd-53772dc3cd49421ea1fa6326a199b7a72dc04d18/software/firmware/common/wrtd-rt-common.h 0000664 0000000 0000000 00000043672 13460261316 0027424 0 ustar 00root root 0000000 0000000 /* Code to insert inside the firmware:
#define NBR_CPUS xxx
#define CPU_IDX xxx
#define NBR_LOCAL_INPUTS xxx
#define NBR_RULES xxx
#define NBR_DEVICES xxx
#define NBR_ALARMS xxx
#define DEVICES_IO_ADDR { xxx, 0, 0, 0}
#define APP_ID WRTD_APP_xxx
#define APP_VER RT_VERSION(xxx, 0)
#define APP_NAME xxx
#define/#undef WRTD_NET_RX
#define/#undef WRTD_NET_TX
#include "wrtd-rt-common.h"
*/
/* Remote message queue for network. */
#define WRTD_RMQ 0
/* By default use lxi-evntsvc. */
#define WRTD_UDP_PORT 5044
/* Functions defined by the user. */
static void wrtd_local_output(struct wrtd_event *ev, unsigned ch);
static void wrtd_io(void);
static int wrtd_user_init(void);
static void wr_update_link(void);
static int wr_sync_timeout(void);
static void wr_enable_lock(int enable);
static int wr_time_ready(void);
static int wr_time_locked(void);
static int wr_link_up(void);
static struct wrtd_rule rules[NBR_RULES];
static struct wrtd_alarm alarms[NBR_ALARMS];
static uint32_t tai_start = 0;
static struct wrtd_root root =
{
.ver_major = WRTD_VERSION_MAJOR,
.ver_minor = WRTD_VERSION_MINOR,
.nbr_devices = NBR_DEVICES,
.nbr_alarms = NBR_ALARMS,
.nbr_rules = NBR_RULES,
.wr_state = WR_LINK_OFFLINE,
.log_flags = 0,
.freeze_flag = 0,
.devices_io_addr = DEVICES_IO_ADDR,
.rules_addr = (uint32_t)rules,
.alarms_addr = (uint32_t)alarms
};
static inline int wr_is_timing_ok(void)
{
return (root.wr_state == WR_LINK_SYNCED);
}
/**
* It updates the White-Rabbit link status
*/
static void wr_update_link(void)
{
switch (root.wr_state) {
case WR_LINK_OFFLINE:
if (wr_link_up())
root.wr_state = WR_LINK_ONLINE;
break;
case WR_LINK_ONLINE:
if (wr_time_ready()) {
root.wr_state = WR_LINK_SYNCING;
wr_enable_lock(1);
}
break;
case WR_LINK_SYNCING:
if (wr_time_locked()) {
pr_debug("rt-tdc: WR synced, waiting for TDC plumbing to catch up...\n\r");
root.wr_state = WR_LINK_WAIT;
tai_start = lr_readl(MT_CPU_LR_REG_TAI_SEC);
}
break;
case WR_LINK_WAIT:
if (wr_sync_timeout() == 0
|| (lr_readl(MT_CPU_LR_REG_TAI_SEC)
>= (tai_start + wr_sync_timeout()))) {
pr_debug("rt-tdc: WR TDC synced\n\r");
root.wr_state = WR_LINK_SYNCED;
}
break;
case WR_LINK_SYNCED:
break;
}
if (root.wr_state != WR_LINK_OFFLINE && !wr_link_up()) {
pr_error("rt-tdc: WR sync lost\n\r");
root.wr_state = WR_LINK_OFFLINE;
wr_enable_lock(0);
}
}
#if NBR_CPUS > 1
/* Number of entries; must be a power of 2. */
#define LOOPBACK_QUEUE_SIZE (1 << 3)
struct loopback_queue {
unsigned read_idx;
unsigned write_idx;
int count;
int lock;
struct wrtd_loopback_event {
unsigned ch;
struct wrtd_event ev;
} buf[LOOPBACK_QUEUE_SIZE];
};
SMEM struct loopback_queue lqueues[NBR_CPUS];
static void wrtd_remote_output(struct wrtd_event *ev,
unsigned dest_cpu, unsigned ch)
{
volatile struct loopback_queue *q = &lqueues[dest_cpu];
if (q->count >= LOOPBACK_QUEUE_SIZE) {
/* FIXME: log. */
return;
}
/* Get lock. */
while (1) {
unsigned int i;
if(smem_atomic_test_and_set(&q->lock) == 0)
break;
/* Busy... Wait a little bit. */
for (i = 0; i < 16; i++)
asm volatile ("nop");
}
q->buf[q->write_idx].ev = *ev;
q->buf[q->write_idx].ch = ch;
q->write_idx = (q->write_idx + 1) & (LOOPBACK_QUEUE_SIZE - 1);
smem_atomic_add(&q->count, 1);
q->lock = 0;
}
static void wrtd_recv_loopback(void)
{
volatile struct loopback_queue *q = &lqueues[CPU_IDX];
volatile struct wrtd_loopback_event *e;
if (q->count == 0)
return; /* No entry */
e = &q->buf[q->read_idx];
wrtd_local_output((struct wrtd_event *)&e->ev, e->ch);
q->read_idx = (q->read_idx + 1) & (LOOPBACK_QUEUE_SIZE - 1);
smem_atomic_add(&q->count, -1);
}
#endif
static inline void ts_add2_ns(struct wrtd_tstamp *ts, uint32_t ns)
{
ts->ns += ns;
if (ts->ns >= 1000000000) {
ts->ns -= 1000000000;
ts->seconds++;
}
}
static inline void ts_add3_ns(struct wrtd_tstamp *dest,
const struct wrtd_tstamp *src, uint32_t ns)
{
dest->seconds = src->seconds;
dest->ns = src->ns + ns;
dest->frac = src->frac;
if (dest->ns >= 1000000000) {
dest->ns -= 1000000000;
dest->seconds++;
}
}
static inline int ts_cmp(const struct wrtd_tstamp *l, const struct wrtd_tstamp *r)
{
if (l->seconds < r->seconds)
return -1;
if (l->seconds > r->seconds)
return 1;
if (l->ns < r->ns)
return -1;
if (l->ns > r->ns)
return 1;
if (l->frac < r->frac)
return -1;
if (l->frac > r->frac)
return 1;
return 0;
}
static void ts_now(struct wrtd_tstamp *now)
{
/*
* Read the current WR time, order is important: first seconds,
* then cycles (cycles get latched on reading secs register.
*/
now->seconds = lr_readl(MT_CPU_LR_REG_TAI_SEC);
now->ns = lr_readl(MT_CPU_LR_REG_TAI_CYCLES) * 8;
now->frac = 0;
}
static void wrtd_log(uint32_t type, uint32_t reason,
const struct wrtd_event *ev,
const struct wrtd_tstamp *ts)
{
struct wrtd_log_entry *log;
struct trtl_fw_msg msg;
int ret;
if (!(root.log_flags & (1 << type))) {
root.log_nbr_discarded++;
return;
}
ret = mq_claim(TRTL_HMQ, WRTD_HMQ);
if (ret == -EBUSY) {
root.log_nbr_busy++;
return;
}
mq_map_out_message(TRTL_HMQ, WRTD_HMQ, &msg);
msg.header->flags = 0;
msg.header->msg_id = WRTD_ACTION_LOG;
msg.header->len = sizeof(struct wrtd_log_entry) / 4;
log = (struct wrtd_log_entry *)msg.payload;
log->type = type;
log->reason = reason;
if (ev != NULL)
log->event = *ev;
else
memset(&log->event, 0, sizeof(struct wrtd_event));
if (ts != NULL)
log->ts = *ts;
else
memset(&log->ts, 0, sizeof(struct wrtd_tstamp));
mq_send(TRTL_HMQ, WRTD_HMQ);
root.log_nbr_sent++;
}
#ifdef WRTD_NET_TX
static void wrtd_init_tx(void)
{
static const struct trtl_ep_eth_address addr = {
.type = TRTL_EP_FRAME_UDP,
.dst_mac = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
.dst_ip = 0xFFFFFFFF, /* broadcast on 255.255.255.255 */
.src_ip = 0xC0A85A11,
.dst_port = WRTD_UDP_PORT,
.src_port = WRTD_UDP_PORT,
.ethertype = 0x800, /* IPv4 */
.filter = 0 /* only the TX path of the endpoint is used */
};
rmq_bind_out(WRTD_RMQ, TRTL_EP_ETH, &addr);
}
static void wrtd_send_network(struct wrtd_event *ev)
{
int ret;
struct trtl_fw_msg fw_msg;
ret = mq_claim(TRTL_RMQ, WRTD_RMQ);
if (ret < 0) {
/* FIXME: log ? */
pr_error("RMQ full\n\r");
return;
}
mq_map_out_message(TRTL_RMQ, WRTD_RMQ, &fw_msg);
fw_msg.header->msg_id = 0;
fw_msg.header->len = sizeof(struct wrtd_message) / 4;
/* Maybe volatile is too pessimistic, but still needed. */
volatile struct wrtd_message *msg = fw_msg.payload;
msg->hw_detect[0] = 'L';
msg->hw_detect[1] = 'X';
msg->hw_detect[2] = 'I';
msg->domain = 0;
memcpy((unsigned char *)msg->event_id, ev->id, WRTD_ID_LEN);
msg->seq = ev->seq;
msg->ts_sec = ev->ts.seconds;
msg->ts_ns = ev->ts.ns;
msg->ts_frac = ev->ts.frac >> 16;
msg->ts_hi_sec = 0;
msg->flags = 0;
msg->zero[0] = 0;
msg->zero[1] = 0;
msg->pad[0] = 0;
mq_send(TRTL_RMQ, WRTD_RMQ);
wrtd_log(WRTD_LOG_MSG_EV_NETWORK, WRTD_LOG_NETWORK_TX, ev, NULL);
}
#endif
static void wrtd_route(struct wrtd_rule *rule, const struct wrtd_event *ev)
{
struct wrtd_event tev;
struct wrtd_tstamp now;
uint32_t lat_ns;
/* Event was received. */
rule->stat.rx_events++;
rule->stat.rx_last = ev->ts;
/* Check hold-off.
Note: this also exclude events that came before the last
one. */
if (rule->conf.hold_off_ns) {
if (ts_cmp(&ev->ts, &rule->stat.hold_off) < 0) {
rule->stat.miss_holdoff++;
rule->stat.miss_last = ev->ts;
wrtd_log(WRTD_LOG_MSG_EV_DISCARDED, 0, ev, NULL);
return;
}
/* Update hold-off. */
ts_add3_ns(&rule->stat.hold_off,
&ev->ts, rule->conf.hold_off_ns);
}
ts_now(&now);
/* Compute latency. */
do {
lat_ns = now.ns - ev->ts.ns;
if(lat_ns >> 31) {
/* Result is negatif, possible only if differ by
1 sec. */
if (ev->ts.seconds + 1 == now.seconds)
lat_ns += 1000000000;
else
break;
}
else if (ev->ts.seconds != now.seconds) {
/* In the future or way in the past. */
break;
}
if (lat_ns > rule->stat.lat_max_ns)
rule->stat.lat_max_ns = lat_ns;
rule->stat.lat_lo_ns += lat_ns;
if (rule->stat.lat_lo_ns < lat_ns)
rule->stat.lat_hi_ns++;
rule->stat.lat_nbr++;
}
while (0);
/* Delay. */
if (rule->conf.delay_ns)
ts_add3_ns(&tev.ts, &ev->ts, rule->conf.delay_ns);
else
tev.ts = ev->ts;
/* Resync. */
if (rule->conf.resync_period_ns) {
uint32_t r = tev.ts.ns % rule->conf.resync_period_ns;
if (r != 0)
ts_add2_ns(&tev.ts, rule->conf.resync_period_ns - r);
tev.ts.frac = 0;
}
ts_add2_ns(&tev.ts, rule->conf.resync_delay_ns);
/* Check with current time. */
if (!rule->conf.send_late) {
if (tev.ts.seconds < now.seconds
|| (tev.ts.seconds == now.seconds
&& tev.ts.ns < now.ns)) {
/* Too late... */
rule->stat.miss_late++;
rule->stat.miss_last = ev->ts;
wrtd_log(WRTD_LOG_MSG_EV_DISCARDED, 0, ev, &now);
return;
}
}
/* Repeat count. */
if (rule->conf.repeat_count != 0) {
rule->conf.repeat_count--;
if (rule->conf.repeat_count == 0)
rule->conf.enabled = 0;
}
/* Rename event. */
memcpy(tev.id, rule->conf.dest_id, WRTD_ID_LEN);
tev.seq = rule->stat.seq++;
/* Send. */
rule->stat.tx_events++;
rule->stat.tx_last = ev->ts;
if (rule->conf.dest_ch == WRTD_DEST_CH_NET) {
#ifdef WRTD_NET_TX
wrtd_send_network(&tev);
#else
wrtd_remote_output
(&tev, rule->conf.dest_cpu, WRTD_DEST_CH_NET);
#endif
}
else {
if (rule->conf.dest_cpu != WRTD_DEST_CPU_LOCAL) {
#if NBR_CPUS > 1
wrtd_remote_output
(&tev, rule->conf.dest_cpu, rule->conf.dest_ch);
#endif
} else {
/* Local delivery. */
wrtd_local_output(&tev, rule->conf.dest_ch);
}
}
}
#if defined(WRTD_NET_RX) || NBR_ALARMS > 0 || NBR_LOCAL_INPUTS > 0
/* Route an event coming from network, or alarm. */
static void wrtd_route_in(struct wrtd_event *ev)
{
struct wrtd_rule *rule;
unsigned int hash = wrtd_id_hash(ev->id) % NBR_RULES;
rule = &rules[hash];
while (1) {
/* A disabled rule cannot be followed by an enabled one. */
if (!rule->conf.enabled)
break;
if (memcmp(ev->id, rule->conf.source_id, WRTD_ID_LEN) == 0)
wrtd_route(rule, ev);
if (rule->conf.hash_chain == -1)
break;
rule = &rules[rule->conf.hash_chain];
}
}
#endif
#ifdef WRTD_NET_RX
static void wrtd_init_rx(void)
{
static const struct trtl_ep_eth_address addr = {
.type = TRTL_EP_FRAME_UDP,
.dst_mac = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
.dst_port = WRTD_UDP_PORT,
.ethertype = 0x800, /* IPv4 */
.filter = (TRTL_EP_FILTER_UDP
| TRTL_EP_FILTER_DST_PORT
| TRTL_EP_FILTER_ENABLE)
};
rmq_bind_in(WRTD_RMQ, TRTL_EP_ETH, &addr);
}
static void wrtd_recv_network(void)
{
volatile struct wrtd_message *msg;
struct wrtd_event ev;
if (!mq_poll_in(TRTL_RMQ, 1 << WRTD_RMQ)) {
/* No packet. */
return;
}
msg = mq_map_in_buffer(TRTL_RMQ, WRTD_RMQ);
ev.ts.seconds = msg->ts_sec | ((uint64_t)msg->ts_hi_sec << 32);
ev.ts.ns = msg->ts_ns;
ev.ts.frac = msg->ts_frac << 16;
memcpy(ev.id, (char *)msg->event_id, WRTD_ID_LEN);
ev.flags = msg->flags;
mq_discard(TRTL_RMQ, WRTD_RMQ);
wrtd_log(WRTD_LOG_MSG_EV_NETWORK, WRTD_LOG_NETWORK_RX, &ev, NULL);
wrtd_route_in(&ev);
/* FIXME: counter ? */
}
#endif
#if NBR_ALARMS > 0
static void wrtd_alarms(void)
{
struct wrtd_tstamp now;
int i;
if (!wr_is_timing_ok())
return;
ts_now(&now);
for (i = 0; i < NBR_ALARMS; i++) {
struct wrtd_alarm *al = &alarms[i];
if (!al->enabled)
continue;
if (ts_cmp(&al->setup_time, &now) > 0)
continue;
wrtd_log(WRTD_LOG_MSG_EV_GENERATED, WRTD_LOG_GENERATED_ALARM,
&al->event, &now);
/* Trigger. */
wrtd_route_in(&al->event);
/* Repeat ? */
if (al->repeat_count > 0) {
al->repeat_count--;
if (al->repeat_count == 0) {
/* Disabled. */
al->enabled = 0;
continue;
}
}
if (al->period_ns == 0) {
al->enabled = 0;
continue;
}
ts_add2_ns(&al->event.ts, al->period_ns);
ts_add2_ns(&al->setup_time, al->period_ns);
}
}
#endif
static int wrtd_action_readw(struct trtl_fw_msg *msg_i,
struct trtl_fw_msg *msg_o)
{
volatile struct wrtd_io_msg *imsg;
volatile uint32_t *odata;
volatile uint32_t *addr;
uint32_t len;
unsigned int i;
/* Verify that the size is correct */
if (msg_i->header->len != sizeof(struct wrtd_io_msg) / 4)
return -EINVAL;
imsg = (volatile struct wrtd_io_msg *)msg_i->payload;
odata = (volatile uint32_t *)msg_o->payload;
addr = (volatile uint32_t *)imsg->addr;
len = imsg->nwords;
/* Copy data. */
for (i = 0; i < len; i++)
odata[i] = addr[i];
msg_o->header->msg_id = WRTD_ACTION_READW;
msg_o->header->len = len;
return 0;
}
static int wrtd_action_writew(struct trtl_fw_msg *msg_i,
struct trtl_fw_msg *msg_o)
{
volatile uint32_t *idata;
volatile uint32_t *addr;
uint32_t len;
unsigned int i;
/* Verify that the size is correct */
if (msg_i->header->len * 4 < sizeof(uint32_t))
return -EINVAL;
idata = (volatile uint32_t *)msg_i->payload;
addr = (volatile uint32_t *)idata[0];
len = idata[1];
/* Copy data. */
for (i = 0; i < len; i++)
addr[i] = idata[i + 2];
msg_o->header->msg_id = WRTD_ACTION_WRITEW;
msg_o->header->len = 0;
return 0;
}
static int wrtd_action_get_config(struct trtl_fw_msg *msg_i,
struct trtl_fw_msg *msg_o)
{
struct wrtd_config_msg *cfg;
/* Verify that the size is correct */
if (msg_i->header->len * 4 != 0)
return -EINVAL;
cfg = (struct wrtd_config_msg *)msg_o->payload;
cfg->root_addr = (uint32_t) &root;
cfg->sync_flag = wr_is_timing_ok();
ts_now(&cfg->now);
msg_o->header->msg_id = WRTD_ACTION_GET_CONFIG;
msg_o->header->len = sizeof(*cfg) / 4;
return 0;
}
static trtl_fw_action_t *wrtd_actions[] = {
[WRTD_ACTION_GET_CONFIG] = wrtd_action_get_config,
[WRTD_ACTION_READW] = wrtd_action_readw,
[WRTD_ACTION_WRITEW] = wrtd_action_writew
};
static int wrtd_main(void)
{
while (1) {
if (!root.freeze_flag) {
wrtd_io();
#ifdef WRTD_NET_RX
wrtd_recv_network();
#endif
#if NBR_CPUS > 1
wrtd_recv_loopback();
#endif
#if NBR_ALARMS > 0
wrtd_alarms();
#endif
}
trtl_fw_mq_action_dispatch(TRTL_HMQ, WRTD_HMQ);
wr_update_link();
}
return 0;
}
static int wrtd_sys_init(void)
{
#ifdef WRTD_NET_RX
wrtd_init_rx();
#endif
#ifdef WRTD_NET_TX
wrtd_init_tx();
#endif
return wrtd_user_init();
}
struct trtl_fw_application app = {
.name = APP_NAME,
.version = {
.rt_id = APP_ID,
.rt_version = APP_VER,
.git_version = GIT_VERSION
},
.actions = wrtd_actions,
.n_actions = ARRAY_SIZE(wrtd_actions),
.init = wrtd_sys_init,
.main = wrtd_main,
.exit = NULL,
};
wrtd-53772dc3cd49421ea1fa6326a199b7a72dc04d18/software/firmware/fd/ 0000775 0000000 0000000 00000000000 13460261316 0023447 5 ustar 00root root 0000000 0000000 wrtd-53772dc3cd49421ea1fa6326a199b7a72dc04d18/software/firmware/fd/Kconfig 0000664 0000000 0000000 00000000221 13460261316 0024745 0 ustar 00root root 0000000 0000000 mainmenu "WRTD Fine Delay firmware configuration"
comment "Project specific configuration"
# include Mock Turtle's Kconfig
source "Kconfig.mt"
wrtd-53772dc3cd49421ea1fa6326a199b7a72dc04d18/software/firmware/fd/Makefile 0000664 0000000 0000000 00000001037 13460261316 0025110 0 ustar 00root root 0000000 0000000 -include Makefile.specific
CUR_DIR := $(shell pwd)
WRTD_DEP_TRTL_FW ?= $(CUR_DIR)/../../../dependencies/mock-turtle/software/firmware
WRTD_DEP_GEN_CORES ?= $(CUR_DIR)/../../../dependencies/general-cores
EXTRA2_CFLAGS += # To be set by user on make line
EXTRA_CFLAGS += $(EXTRA2_CFLAGS)
EXTRA_CFLAGS += -I$(CUR_DIR)/../../include
EXTRA_CFLAGS += -I$(CUR_DIR)/../common
all:
# Redirect all rules to MockTurtle
%:
$(MAKE) -C $(WRTD_DEP_TRTL_FW) M=$(shell /bin/pwd) \
GEN_CORES=$(WRTD_DEP_GEN_CORES) EXTRA_CFLAGS="$(EXTRA_CFLAGS)" $@
wrtd-53772dc3cd49421ea1fa6326a199b7a72dc04d18/software/firmware/fd/TBuild 0000664 0000000 0000000 00000000162 13460261316 0024554 0 ustar 00root root 0000000 0000000 OBJS := wrtd-rt-fd.o
OBJS += fd-acam.o fd-gpio.o fd-pll.o fd-i2c.o fd-calibrate.o fd-init.o
OUTPUT = wrtd-rt-fd
wrtd-53772dc3cd49421ea1fa6326a199b7a72dc04d18/software/firmware/fd/configs/ 0000775 0000000 0000000 00000000000 13460261316 0025077 5 ustar 00root root 0000000 0000000 wrtd-53772dc3cd49421ea1fa6326a199b7a72dc04d18/software/firmware/fd/configs/mt_defconfig 0000664 0000000 0000000 00000001477 13460261316 0027457 0 ustar 00root root 0000000 0000000 #
# Automatically generated file; DO NOT EDIT.
# fmc-svec-carrier fw-01 demo configuration
#
#
# Project specific configuration
#
#
# Mock Turtle configuration
#
CONFIG_FPGA_APPLICATION_ID=0
CONFIG_RT_APPLICATION_ID=0
CONFIG_CFLAGS_OPT="-Os"
CONFIG_CFLAGS_EXTRA="-ggdb"
#
# Mock Turtle framework configuration
#
CONFIG_MOCKTURTLE_FRAMEWORK_ENABLE=y
CONFIG_MOCKTURTLE_FRAMEWORK_ACTION_ENABLE=y
CONFIG_MOCKTURTLE_FRAMEWORK_VARIABLE_ENABLE=y
CONFIG_MOCKTURTLE_FRAMEWORK_BUFFER_ENABLE=y
CONFIG_MOCKTURTLE_FRAMEWORK_PING_ENABLE=y
CONFIG_MOCKTURTLE_FRAMEWORK_VERSION_ENABLE=y
#
# Mock Turtle library configuration
#
CONFIG_MOCKTURTLE_LIBRARY_PRINT_ENABLE=y
# CONFIG_MOCKTURTLE_LIBRARY_PRINT_DEBUG_ENABLE is not set
# CONFIG_MOCKTURTLE_LIBRARY_PRINT_ERROR_ENABLE is not set
# CONFIG_MOCKTURTLE_LIBRARY_PRINT_MESSAGE_ENABLE is not set
wrtd-53772dc3cd49421ea1fa6326a199b7a72dc04d18/software/firmware/fd/fd-acam.c 0000664 0000000 0000000 00000022216 13460261316 0025106 0 ustar 00root root 0000000 0000000 /*
* Accessing the ACAM chip and configuring it.
*
* Copyright (C) 2012 CERN (www.cern.ch)
* Author: Tomasz Wlostowski
* Author: Alessandro Rubini
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* version 2 as published by the Free Software Foundation or, at your
* option, any later version.
*/
#include "mockturtle-rt.h"
#include "hw/fd_main_regs.h"
#include "hw/acam_gpx.h"
#include "wrtd-fd.h"
/*
* Calculation is fixed point: picoseconds and 16 decimals (i.e. ps << 16).
* We know the bin is small, but the Tref is several nanos so we need 64 bits
* (although our current values fit in 32 bits after the division)
*/
#define ACAM_FP_BIN ((int)(ACAM_DESIRED_BIN * (1 << 16)))
#define ACAM_FP_TREF (((1000LL * 1000 * 1000) << 16) / ACAM_CLOCK_FREQ_KHZ)
/* Default values of control registers for the ACAM TDC working in G-Mode
(eeprom values are obsolete) */
#define ACAM_GMODE_START_OFFSET 10000
#define ACAM_GMODE_ASOR 17000
#define ACAM_GMODE_ATMCR (26 | (1500 << 8))
#define ACAM_GMODE_ADSFR 84977
static int acam_calc_pll(uint64_t tref, int bin, int *hsdiv_out,
int *refdiv_out)
{
uint64_t tmpll;
int x, refdiv, hsdiv;
/*
* Tbin(I-mode) = (Tref << refdiv) / (216 * hsdiv)
*
* so, calling X the value "hsdiv >> refdiv" we have
*
* X = Tref / (216 * Tbin)
*
* Then, we can choose refdiv == 7 to have the best bits,
* and then shift out the zeros to get smaller values.
*
*/
if (0) {
x = (tref << 16) / 216 / bin;
//printf("x = %lf\n", (double)x / (1<<16));
} else {
/* We can't divide 64 bits in kernel space */
tmpll = div_u64(tref << 16, 216);
x = div_u64(tmpll, bin);
}
/* Now, shift out the max bits (usually 7) and drop decimal part */
refdiv = ACAM_MAX_REFDIV;
hsdiv = (x << refdiv) >> 16;
/* Check the first decimal bit and approximate */
if ((x << refdiv) & (1 << 15))
hsdiv++;
/* until we have zeroes as LSB, shift out to decrease pll quotient */
while (refdiv > 0 && !(hsdiv & 1)) {
refdiv--;
hsdiv >>= 1;
}
*hsdiv_out = hsdiv;
*refdiv_out = refdiv;
/* Finally, calculate what we really have */
if (0) {
bin = (tref << refdiv) / 216 / hsdiv;
} else {
tmpll = div_u64(tref << refdiv, 216);
bin = div_u64(tmpll, hsdiv);
}
return (bin + 1); /* We always return the bin size in the I mode. Other modes should scale it appropriately. */
}
static void acam_set_address(struct wrtd_fd_dev *fd, int addr)
{
if (fd->fd_acam_addr == addr)
return;
if (fd->fd_acam_addr == -1) {
/* first time */
fd_gpio_dir(fd, 0xf00, FD_GPIO_OUT);
}
fd_gpio_val(fd, 0xf00, addr << 8);
fd->fd_acam_addr = addr;
}
/* Warning: acam_readl and acam_writel only work if GCR.BYPASS is set */
uint32_t acam_readl(struct wrtd_fd_dev *fd, int reg)
{
acam_set_address(fd, reg);
fd_writel(fd, FD_TDCSR_READ, FD_REG_TDCSR);
return fd_readl(fd, FD_REG_TDR) & ACAM_MASK;
}
void acam_writel(struct wrtd_fd_dev *fd, int val, int reg)
{
acam_set_address(fd, reg);
fd_writel(fd, val, FD_REG_TDR);
fd_writel(fd, FD_TDCSR_WRITE, FD_REG_TDCSR);
}
static void acam_set_bypass(struct wrtd_fd_dev *fd, int on)
{
/* warning: this clears the "input enable" bit: call at init only */
fd_writel(fd, on ? FD_GCR_BYPASS : 0, FD_REG_GCR);
}
static inline int acam_is_pll_locked(struct wrtd_fd_dev *fd)
{
return !(acam_readl(fd, 12) & AR12_NotLocked);
}
/* Two test functions to verify the bus is working -- Tom */
static int acam_test_addr_bit(struct wrtd_fd_dev *fd,
int base, int bit, int data)
{
int addr1 = base;
int addr2 = base + (1<calib.acam_start_offset) */
| AR5_MasterAluTrig},
{6, AR6_Fill(200) | AR6_PowerOnECL},
{7, /* AR7_HSDiv(hsdiv) | AR7_RefClkDiv(refdiv) */ 0
| AR7_ResAdj | AR7_NegPhase},
{11, 0x7ff0000},
{12, 0x0000000},
{14, 0},
/* finally, reset */
{4, AR4_EFlagHiZN | AR4_MasterReset | AR4_StartTimer(0)},
};
static struct acam_init_data acam_init_regs_imode[] = {
{0, AR0_TRiseEn(0) | AR0_HQSel | AR0_ROsc},
{2, AR2_IMode},
{5, AR5_StartOff1(3000) | AR5_MasterAluTrig},
{6, 0},
{7, /* AR7_HSDiv(hsdiv) | AR7_RefClkDiv(refdiv) */ 0
| AR7_ResAdj | AR7_NegPhase},
{11, 0x7ff0000},
{12, 0x0000000},
{14, 0},
/* finally, reset */
{4, AR4_EFlagHiZN | AR4_MasterReset | AR4_StartTimer(0)},
};
static int acam_configure(struct wrtd_fd_dev *fd, enum fd_acam_modes mode,
const struct acam_init_data *regs, int n_regs )
{
int i, hsdiv, refdiv, reg7val;
const struct acam_init_data *p;
uint32_t regval;
int locked = 0;
fd->fd_bin_size = acam_calc_pll(ACAM_FP_TREF, ACAM_FP_BIN,
&hsdiv, &refdiv);
reg7val = AR7_HSDiv(hsdiv) | AR7_RefClkDiv(refdiv);
pr_debug("ACAM config: mode %d bin 0x%x, hsdiv %i, refdiv %i\n",
mode, fd->fd_bin_size, hsdiv, refdiv);
/* Disable TDC inputs prior to configuring */
fd_writel(fd, FD_TDCSR_STOP_DIS | FD_TDCSR_START_DIS, FD_REG_TDCSR);
/* Disable the ACAM PLL for a while to make sure it is reset */
acam_writel(fd, 0, 0);
acam_writel(fd, 7, 0);
mdelay(100);
for (p = regs, i = 0; i < n_regs; p++, i++) {
regval = p->val;
if (p->addr == 7)
regval |= reg7val;
if (p->addr == 5 && mode == ACAM_GMODE )
regval |= AR5_StartOff1(ACAM_GMODE_START_OFFSET);
if (p->addr == 6 && mode == ACAM_GMODE )
regval |= AR6_StartOff2(ACAM_GMODE_START_OFFSET);
acam_writel(fd, regval, p->addr);
}
for (i = 0; i < 20; i++)
{
if (acam_is_pll_locked(fd))
{
locked = 1;
break;
}
mdelay(100);
}
if(!locked)
{
pp_printf("Error: ACAM PLL doesn't lock.\n");
return -1;
}
/* after config, set the FIFO address for further reads */
acam_set_address(fd, 8);
return 0;
}
int fd_acam_init(struct wrtd_fd_dev *fd)
{
int ret;
fd->fd_acam_addr = -1; /* First time must be activated */
acam_set_bypass(fd, 1); /* Driven by host, not core */
if ( (ret = acam_test_bus(fd)) )
return ret;
if ( (ret = acam_configure(fd, ACAM_IMODE, acam_init_regs_imode, ARRAY_SIZE(acam_init_regs_imode))) )
return ret;
if ( (ret = fd_calibrate_outputs(fd)) )
return ret;
if ( (ret = acam_configure(fd, ACAM_GMODE, acam_init_regs_gmode, ARRAY_SIZE(acam_init_regs_gmode))) )
return ret;
acam_set_bypass(fd, 0); /* Driven by core, not host */
/* Clear and disable the timestamp readout buffer */
fd_writel(fd, FD_TSBCR_PURGE | FD_TSBCR_RST_SEQ, FD_REG_TSBCR);
/*
* Program the ACAM-specific TS registers w pre-defined calib values:
* - bin -> internal timebase scalefactor (ADSFR),
* - Start offset (must be consistent with value in ACAM reg 4)
* - timestamp merging control register (ATMCR)
* GMode fix: we no longer use the values from the EEPROM (they are fixed anyway)
*/
fd_writel(fd, ACAM_GMODE_ADSFR, FD_REG_ADSFR);
fd_writel(fd, ACAM_GMODE_ASOR, FD_REG_ASOR);
fd_writel(fd, ACAM_GMODE_ATMCR, FD_REG_ATMCR);
return 0;
}
wrtd-53772dc3cd49421ea1fa6326a199b7a72dc04d18/software/firmware/fd/fd-calibrate.c 0000664 0000000 0000000 00000007705 13460261316 0026141 0 ustar 00root root 0000000 0000000 /*
* Calibrate the output path.
*
* Copyright (C) 2012 CERN (www.cern.ch)
* Author: Tomasz Wlostowski
* Author: Alessandro Rubini
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* version 2 as published by the Free Software Foundation or, at your
* option, any later version.
*/
#include "mockturtle-rt.h"
#include "wrtd-fd.h"
#include "hw/fd_main_regs.h"
#include "hw/acam_gpx.h"
#include "hw/fd_channel_regs.h"
/* This is the same as in ./acam.c: use only at init time */
static void acam_set_bypass(struct wrtd_fd_dev *fd, int on)
{
fd_writel(fd, on ? FD_GCR_BYPASS : 0, FD_REG_GCR);
}
/*
* Measures the the FPGA-generated TDC start and the output of one of
* the fine delay chips (channel) at a pre-defined number of taps
* (fine). Retuns the delay in picoseconds. The measurement is
* repeated and averaged (n_avgs) times. Also, the standard deviation
* of the result can be written to (sdev) if it's not NULL.
*/
/* Note: channel is the "internal" one: 0..3 */
static uint64_t output_delay_ps(struct wrtd_fd_dev *fd, int ch, int fine, int n)
{
int i;
uint64_t acc = 0;
/* Disable the output for the channel being calibrated */
fd_gpio_clr(fd, FD_GPIO_OUTPUT_EN(FD_CH_EXT(ch)));
/* Enable the stop input in ACAM for the channel being calibrated */
acam_writel(fd, AR0_TRiseEn(0) | AR0_TRiseEn(FD_CH_EXT(ch))
| AR0_HQSel | AR0_ROsc, 0);
/* Program the output delay line setpoint */
fd_drv_ch_writel(fd, ch, fine, FD_REG_FRR);
fd_drv_ch_writel(fd, ch, FD_DCR_ENABLE | FD_DCR_MODE | FD_DCR_UPDATE,
FD_REG_DCR);
fd_drv_ch_writel(fd, ch, FD_DCR_FORCE_DLY | FD_DCR_ENABLE, FD_REG_DCR);
/*
* Set the calibration pulse mask to genrate calibration
* pulses only on one channel at a time. This minimizes the
* crosstalk in the output buffer which can severely decrease
* the accuracy of calibration measurements
*/
fd_writel(fd, FD_CALR_PSEL_W(1 << ch), FD_REG_CALR);
udelay(1);
/* Do n_avgs single measurements and average */
for (i = 0; i < n; i++) {
uint32_t fr;
/* Re-arm the ACAM (it's working in a single-shot mode) */
fd_writel(fd, FD_TDCSR_ALUTRIG, FD_REG_TDCSR);
udelay(1);
/* Produce a calib pulse on the TDC start and the output ch */
fd_writel(fd, FD_CALR_CAL_PULSE |
FD_CALR_PSEL_W(1 << ch), FD_REG_CALR);
udelay(1);
/* read the tag, convert to picoseconds (fixed point: 16.16) */
fr = acam_readl(fd, 8 /* fifo */) & 0x1ffff;
//pp_printf("i %d fr %x\n\r", i, fr);
acc += fr * fd->fd_bin_size;
}
fd_drv_ch_writel(fd, ch, 0, FD_REG_DCR);
/* Calculate avg, min max */
acc = div_u64((acc + n / 2), n );
//pp_printf("ch %d avg %08x%08x\n\r", ch, (uint32_t)(acc>>32), (uint32_t)acc);
return acc;
}
static int fd_find_8ns_tap(struct wrtd_fd_dev *fd, int ch)
{
int l = 0, mid, r = FD_NUM_TAPS - 1;
uint64_t bias, dly;
/*
* Measure the delay at zero setting, so it can be further
* subtracted to get only the delay part introduced by the
* delay line (ingoring the TDC, FPGA and routing delays).
* Use a binary search of the delay value.
*/
bias = output_delay_ps(fd, ch, 0, FD_CAL_STEPS);
while( r - l > 1) {
mid = ( l + r) / 2;
dly = output_delay_ps(fd, ch, mid, FD_CAL_STEPS) - bias;
if(dly < 8000 << 16)
l = mid;
else
r = mid;
}
return l;
}
/**
* fd_calibrate_outputs
* It calibrates the delay line by finding the correct 8ns-tap value
* for each channel. This is done during ACAM initialization, so on driver
* probe.
*/
int fd_calibrate_outputs(struct wrtd_fd_dev *fd)
{
int ch;
int measured;
acam_set_bypass(fd, 1); /* not useful */
fd_writel(fd, FD_TDCSR_START_EN | FD_TDCSR_STOP_EN, FD_REG_TDCSR);
for (ch = 0; ch < FD_NUM_CHANNELS; ch++) {
measured = fd_find_8ns_tap(fd, ch);
fd_drv_ch_writel(fd, ch, measured, FD_REG_FRR);
pr_debug("Channel %d: 8ns @ %i taps.\n\r", ch+1, measured );
}
return 0;
}
wrtd-53772dc3cd49421ea1fa6326a199b7a72dc04d18/software/firmware/fd/fd-gpio.c 0000664 0000000 0000000 00000004757 13460261316 0025155 0 ustar 00root root 0000000 0000000 /*
* SPI access to fine-delay internals
*
* Copyright (C) 2012 CERN (www.cern.ch)
* Author: Tomasz Wlostowski
* Author: Alessandro Rubini
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* version 2 as published by the Free Software Foundation or, at your
* option, any later version.
*/
#include "mockturtle-rt.h"
#include "wrtd-fd.h"
#define SPI_RETRIES 100
int gpio_writel(struct wrtd_fd_dev *fd, int val, int reg)
{
int rval = fd_spi_xfer(fd, FD_CS_GPIO, 24,
0x4e0000 | (reg << 8) | val, NULL);
return rval;
}
static int gpio_readl(struct wrtd_fd_dev *fd, int reg)
{
uint32_t ret;
int err;
err = fd_spi_xfer(fd, FD_CS_GPIO, 24,
0x4f0000 | (reg << 8), &ret);
if (err < 0)
return err;
return ret & 0xff;
}
static int gpio_writel_with_retry(struct wrtd_fd_dev *fd, int val, int reg)
{
int retries = SPI_RETRIES, rv;
while(retries--)
{
gpio_writel(fd, val, reg);
rv = gpio_readl(fd, reg);
if(rv >= 0 && (rv == val))
{
if(SPI_RETRIES-1-retries > 0)
pr_debug("gpio_writel_with_retry: succeded after %d retries\n",
SPI_RETRIES - 1 - retries);
return 0;
}
}
return -EIO;
}
void fd_gpio_dir(struct wrtd_fd_dev *fd, int mask, int dir)
{
fd->fd_mcp_iodir &= ~mask;
if (dir == FD_GPIO_IN)
fd->fd_mcp_iodir |= mask;
gpio_writel_with_retry(fd, (fd->fd_mcp_iodir & 0xff), FD_MCP_IODIR);
gpio_writel_with_retry(fd, (fd->fd_mcp_iodir >> 8), FD_MCP_IODIR+1);
}
void fd_gpio_val(struct wrtd_fd_dev *fd, int mask, int values)
{
fd->fd_mcp_olat &= ~mask;
fd->fd_mcp_olat |= values;
gpio_writel_with_retry(fd, (fd->fd_mcp_olat & 0xff), FD_MCP_OLAT);
gpio_writel_with_retry(fd, (fd->fd_mcp_olat >> 8), FD_MCP_OLAT+1);
}
void fd_gpio_set_clr(struct wrtd_fd_dev *fd, int mask, int set)
{
fd_gpio_val(fd, mask, set ? mask : 0);
}
int fd_gpio_init(struct wrtd_fd_dev *fd)
{
int i, val;
fd->fd_mcp_iodir = 0xffff;
fd->fd_mcp_olat = 0;
if (gpio_writel(fd, 0x00, FD_MCP_IOCON) < 0)
goto out;
/* Try to read and write a register to test the SPI connection */
for (val = 0xaa; val >= 0; val -= 0x11) {
if (gpio_writel(fd, val, FD_MCP_IPOL) < 0)
goto out;
i = gpio_readl(fd, FD_MCP_IPOL);
if (i < 0)
goto out;
if (i != val) {
pr_error("GPIO comm error (got 0x%x, expected 0x%x)\n", i, val);
return -EIO;
}
}
/* last time we wrote 0, ok */
return 0;
out:
return -EIO;
}
wrtd-53772dc3cd49421ea1fa6326a199b7a72dc04d18/software/firmware/fd/fd-i2c.c 0000664 0000000 0000000 00000005462 13460261316 0024666 0 ustar 00root root 0000000 0000000 /*
* I2C access (on-board EEPROM)
*
* Copyright (C) 2012 CERN (www.cern.ch)
* Author: Tomasz Wlostowski
* Author: Alessandro Rubini
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* version 2 as published by the Free Software Foundation or, at your
* option, any later version.
*/
#include "mockturtle-rt.h"
#include "wrtd-fd.h"
#include "hw/fd_main_regs.h"
static void set_sda(struct wrtd_fd_dev *fd, int val)
{
uint32_t reg;
reg = fd_readl(fd, FD_REG_I2CR) & ~FD_I2CR_SDA_OUT;
if (val)
reg |= FD_I2CR_SDA_OUT;
fd_writel(fd, reg, FD_REG_I2CR);
udelay(3);
}
static void set_scl(struct wrtd_fd_dev *fd, int val)
{
uint32_t reg;
reg = fd_readl(fd, FD_REG_I2CR) & ~FD_I2CR_SCL_OUT;
if (val)
reg |= FD_I2CR_SCL_OUT;
fd_writel(fd, reg, FD_REG_I2CR);
udelay(3);
}
static int get_sda(struct wrtd_fd_dev *fd)
{
return fd_readl(fd, FD_REG_I2CR) & FD_I2CR_SDA_IN ? 1 : 0;
}
static void mi2c_start(struct wrtd_fd_dev *fd)
{
set_sda(fd, 0);
set_scl(fd, 0);
}
static void mi2c_stop(struct wrtd_fd_dev *fd)
{
set_sda(fd, 0);
set_scl(fd, 1);
set_sda(fd, 1);
}
int mi2c_put_byte(struct wrtd_fd_dev *fd, int data)
{
int i;
int ack;
for (i = 0; i < 8; i++, data<<=1) {
set_sda(fd, data & 0x80);
set_scl(fd, 1);
set_scl(fd, 0);
}
set_sda(fd, 1);
set_scl(fd, 1);
ack = get_sda(fd);
set_scl(fd, 0);
set_sda(fd, 0);
return ack ? -EIO : 0; /* ack low == success */
}
int mi2c_get_byte(struct wrtd_fd_dev *fd, unsigned char *data, int sendack)
{
int i;
int indata = 0;
/* assert: scl is low */
set_scl(fd, 0);
set_sda(fd, 1);
for (i = 0; i < 8; i++) {
set_scl(fd, 1);
indata <<= 1;
if (get_sda(fd))
indata |= 0x01;
set_scl(fd, 0);
}
set_sda(fd, (sendack ? 0 : 1));
set_scl(fd, 1);
set_scl(fd, 0);
set_sda(fd, 0);
*data= indata;
return 0;
}
void mi2c_init(struct wrtd_fd_dev *fd)
{
set_scl(fd, 1);
set_sda(fd, 1);
}
void mi2c_scan(struct wrtd_fd_dev *fd)
{
int i;
for(i = 0; i < 256; i += 2) {
mi2c_start(fd);
if(!mi2c_put_byte(fd, i))
pr_debug("Found i2c device at 0x%x\n",
i >> 1);
mi2c_stop(fd);
}
}
/* FIXME: this is very inefficient: read several bytes in a row instead */
int fd_eeprom_read(struct wrtd_fd_dev *fd, int i2c_addr, uint32_t offset,
void *buf, size_t size)
{
int i;
uint8_t *buf8 = buf;
unsigned char c;
for(i = 0; i < size; i++) {
mi2c_start(fd);
if(mi2c_put_byte(fd, i2c_addr << 1) < 0) {
mi2c_stop(fd);
return -EIO;
}
mi2c_put_byte(fd, (offset >> 8) & 0xff);
mi2c_put_byte(fd, offset & 0xff);
offset++;
mi2c_stop(fd);
mi2c_start(fd);
mi2c_put_byte(fd, (i2c_addr << 1) | 1);
mi2c_get_byte(fd, &c, 0);
*buf8++ = c;
mi2c_stop(fd);
}
return size;
}
wrtd-53772dc3cd49421ea1fa6326a199b7a72dc04d18/software/firmware/fd/fd-init.c 0000664 0000000 0000000 00000005654 13460261316 0025157 0 ustar 00root root 0000000 0000000 /*
* Copyright (C) 2018 CERN (www.cern.ch)
* Author: Federico Vaga
* Author: Tomasz Wlostowski
*
* SPDX-License-Identifier: LGPL-3.0-or-later
*/
#include
#include
#include "mockturtle-rt.h"
#include
#include "wrtd-common.h"
#include "hw/fd_channel_regs.h"
#include "hw/fd_main_regs.h"
#include "wrtd-fd.h"
#ifdef SIMULATION
#define UDELAY(X)
#define MDELAY(X)
#else
#define UDELAY(X) udelay(X)
#define MDELAY(X) mdelay(X)
#endif
/**
* fd_do_reset
* The reset function (by Tomasz)
*
* This function can reset the entire mezzanine (FMC) or just
* the fine-delay core (CORE).
* In the reset register 0 means reset, 1 means normal operation.
*/
static void fd_do_reset(struct wrtd_fd_dev *fd, int hw_reset)
{
if (hw_reset) {
/* clear RSTS_RST_FMC bit, set RSTS_RST_CORE bit*/
fd_writel(fd, FD_RSTR_LOCK_W(0xdead) | FD_RSTR_RST_CORE_MASK,
FD_REG_RSTR);
UDELAY(10000);
fd_writel(fd, FD_RSTR_LOCK_W(0xdead) | FD_RSTR_RST_CORE_MASK
| FD_RSTR_RST_FMC_MASK, FD_REG_RSTR);
/* TPS3307 supervisor needs time to de-assert master reset */
MDELAY(600);
return;
}
/* clear RSTS_RST_CORE bit, set RSTS_RST_FMC bit */
fd_writel(fd, FD_RSTR_LOCK_W(0xdead) | FD_RSTR_RST_FMC_MASK,
FD_REG_RSTR);
UDELAY(1000);
fd_writel(fd, FD_RSTR_LOCK_W(0xdead) | FD_RSTR_RST_FMC_MASK
| FD_RSTR_RST_CORE_MASK, FD_REG_RSTR);
UDELAY(1000);
}
/* Some init procedures to be intermixed with subsystems */
int fd_gpio_defaults(struct wrtd_fd_dev *fd)
{
fd_gpio_dir(fd, FD_GPIO_TRIG_INTERNAL, FD_GPIO_OUT);
fd_gpio_set(fd, FD_GPIO_TRIG_INTERNAL);
fd_gpio_set(fd, FD_GPIO_OUTPUT_MASK);
fd_gpio_dir(fd, FD_GPIO_OUTPUT_MASK, FD_GPIO_OUT);
fd_gpio_dir(fd, FD_GPIO_TERM_EN, FD_GPIO_OUT);
fd_gpio_clr(fd, FD_GPIO_TERM_EN);
return 0;
}
int fd_reset_again(struct wrtd_fd_dev *fd)
{
/* Reset the FD core once we have proper reference/TDC clocks */
fd_do_reset(fd, 0 /* not hw */);
MDELAY(10);
if (! (fd_readl(fd, FD_REG_GCR) & FD_GCR_DDR_LOCKED) )
{
pr_error("timeout waiting for GCR lock bit\n");
return -EIO;
}
fd_do_reset(fd, 0 /* not hw */);
return 0;
}
/* FIXME missing all calibration */
int fd_init(struct wrtd_fd_dev *fd)
{
int err, ch;
pr_debug("Initializing the Fine Delay board...\n");
fd_do_reset(fd, 1);
err = fd_gpio_init(fd);
if (err)
return err;
err = fd_pll_init(fd);
if (err)
return err;
fd_gpio_defaults(fd);
err = fd_reset_again(fd);
if (err)
return err;
err = fd_acam_init(fd);
if (err)
return err;
for (ch = 1; ch <= FD_NUM_CHANNELS; ch++)
fd_gpio_set(fd, FD_GPIO_OUTPUT_EN(ch));
// todo: read offsets from the EEPROM. I2C should be working OK.
return 0;
}
#ifdef SIMULATION
int fd_sim_init(void)
{
int err;
pr_debug("Initializing the Fine Delay board...\n");
fd_do_reset(1);
err = fd_reset_again();
if (err)
return err;
return 0;
}
#endif
wrtd-53772dc3cd49421ea1fa6326a199b7a72dc04d18/software/firmware/fd/fd-pll.c 0000664 0000000 0000000 00000013633 13460261316 0024777 0 ustar 00root root 0000000 0000000 /*
* Copyright (C) 2018 CERN (www.cern.ch)
* Author: Federico Vaga
* Author: Tomasz Wlostowski
*
* SPDX-License-Identifier: LGPL-3.0-or-later
*/
#include
#include
#include "mockturtle-rt.h"
#include
#include "wrtd-common.h"
#include "hw/fd_channel_regs.h"
#include "hw/fd_main_regs.h"
#include "wrtd-fd.h"
struct ad9516_reg {
unsigned short reg;
unsigned char val;
};
static const struct ad9516_reg __9516_regs[] = {
{0x0000, 0x99}, /* Config SPI */
{0x0001, 0x00},
{0x0002, 0x10},
{0x0003, 0xC3},
{0x0004, 0x00},
/* PLL */
{0x0010, 0x7C}, /* PFD and charge pump */
{0x0011, 0x05}, /* R divider (1) */
{0x0012, 0x00}, /* R divider (2) */
{0x0013, 0x0C}, /* A counter */
{0x0014, 0x12}, /* B counter (1) */
{0x0015, 0x00}, /* B counter (2) */
{0x0016, 0x05}, /* PLL control (1) */
{0x0017, 0xb4}, /* PLL control (2) PLL_STATUS = Lock Detect */
{0x0018, 0x07}, /* PLL control (3) */
{0x0019, 0x00}, /* PLL control (4) */
{0x001A, 0x00}, /* PLL control (5) */
{0x001B, 0xE0}, /* PLL control (6) */
{0x001C, 0x02}, /* PLL control (7) */
{0x001D, 0x00}, /* PLL control (8) */
{0x001E, 0x00}, /* PLL control (9) */
{0x001F, 0x0E}, /* PLL readback */
/* Fine Delay */
{0x00A0, 0x01}, /* OUT6 Delay bypass */
{0x00A1, 0x00}, /* OUT6 Delay full-scale */
{0x00A2, 0x00}, /* OUT6 Delay fraction */
{0x00A3, 0x01}, /* OUT7 Delay bypass */
{0x00A4, 0x00}, /* OUT7 Delay full-scale */
{0x00A5, 0x00}, /* OUT7 Delay fraction */
{0x00A6, 0x01}, /* OUT8 Delay bypass */
{0x00A7, 0x00}, /* OUT8 Delay full-scale */
{0x00A8, 0x00}, /* OUT8 Delay fraction */
{0x00A9, 0x01}, /* OUT9 Delay bypass */
{0x00AA, 0x00}, /* OUT9 Delay full-scale */
{0x00AB, 0x00}, /* OUT9 Delay fraction */
/* LVPECL */
{0x00F0, 0x08}, /* OUT0 */
{0x00F1, 0x08}, /* OUT1 */
{0x00F2, 0x08}, /* OUT2 */
{0x00F3, 0x18}, /* OUT3, inverted */
{0x00F4, 0x00}, /* OUT4 */
{0x00F5, 0x08}, /* OUT5 */
/* LVDS/CMOS */
{0x0140, 0x5A}, /* OUT6 */
{0x0141, 0x5A}, /* OUT7 */
{0x0142, 0x5B}, /* OUT8 */
{0x0143, 0x42}, /* OUT9 */
/* LVPECL Channel divider */
{0x0190, 0x00}, /* Divider 0 (1) */
{0x0191, 0x80}, /* Divider 0 (2) */
{0x0192, 0x00}, /* Divider 0 (3) */
{0x0193, 0x00}, /* Divider 1 (1) */
{0x0194, 0x80}, /* Divider 1 (2) */
{0x0195, 0x00}, /* Divider 1 (3) */
{0x0196, 0xFF}, /* Divider 2 (1) */
{0x0197, 0x00}, /* Divider 2 (2) */
{0x0198, 0x00}, /* Divider 2 (3) */
/* LVDS/CMOS Channel divider */
{0x0199, 0x33}, /* Divider 3 (1) */
{0x019A, 0x00}, /* Divider 3 (2) */
{0x019B, 0x11}, /* Divider 3 (3) */
{0x019C, 0x20}, /* Divider 3 (4) */
{0x019D, 0x00}, /* Divider 3 (5) */
{0x019E, 0x00}, /* Divider 4 (1) */
{0x019F, 0x00}, /* Divider 4 (2) */
{0x01A0, 0x11}, /* Divider 4 (3) */
{0x01A1, 0x20}, /* Divider 4 (4) */
{0x01A2, 0x00}, /* Divider 4 (5) */
{0x01A3, 0x00},
/* VCO Divider and CLK Input */
{0x01E0, 0x04}, /* VCO divider VCODIV = 6 */
{0x01E1, 0x02}, /* Input Clock */
/* System */
{0x0230, 0x00}, /* Power down and sync */
{0x0231, 0x00},
/* Update All registers */
{0x0232, 0x00}, /* Update All registers */
};
int fd_spi_xfer(struct wrtd_fd_dev *fd,
int ss, int num_bits, uint32_t in, uint32_t *out)
{
uint32_t scr = 0, r;
unsigned long timeout;
scr = FD_SCR_DATA_W(in)| FD_SCR_CPOL;
if(ss == FD_CS_PLL)
scr |= FD_SCR_SEL_PLL;
else if(ss == FD_CS_GPIO)
scr |= FD_SCR_SEL_GPIO;
fd_writel(fd, scr, FD_REG_SCR);
fd_writel(fd, scr | FD_SCR_START, FD_REG_SCR);
timeout = trtl_get_runtime_milliseconds() + 1000;
while (!(fd_readl(fd, FD_REG_SCR) & FD_SCR_READY))
if (trtl_get_runtime_milliseconds() > timeout)
break;
if (!(fd_readl(fd, FD_REG_SCR) & FD_SCR_READY))
return -EIO;
scr = fd_readl(fd, FD_REG_SCR);
r = FD_SCR_DATA_R(scr);
if(out)
*out=r;
udelay(100); /* FIXME: check */
return 0;
}
static int fd_pll_writel(struct wrtd_fd_dev *fd, int val, int reg)
{
return fd_spi_xfer(fd, FD_CS_PLL, 24, (reg << 8) | val, NULL);
}
static int fd_pll_readl(struct wrtd_fd_dev *fd, int reg)
{
uint32_t ret;
int err;
err = fd_spi_xfer(fd, FD_CS_PLL, 24, (reg << 8) | (1 << 23), &ret);
if (err < 0)
return err;
return ret & 0xff;
}
/* Just check the id register of the pll.
Detect broken SPI link. */
static int fd_pll_check(struct wrtd_fd_dev *fd)
{
int id;
id = fd_pll_readl(fd, 0x003);
if (id < 0)
return -EIO;
if (id != 0xc3) {
pr_error("Error in PLL communication\n"
" (got 0x%x, expected 0xc3)\n", id);
return -EIO;
}
return 0;
}
int fd_pll_init(struct wrtd_fd_dev *fd)
{
int i, ret;
unsigned long timeout;
const struct ad9516_reg *r;
if (fd_pll_writel(fd, 0x99, 0x000) < 0)
return -EIO;
if (fd_pll_writel(fd, 0x01, 0x232) < 0)
return -EIO;
if (fd_pll_check(fd) < 0)
return -EIO;
/* Write the magic config */
for (i = 0, r = __9516_regs; i < ARRAY_SIZE(__9516_regs); i++, r++) {
if (fd_pll_writel(fd, r->val, r->reg) < 0) {
pr_error("Error in configuring PLL (step %i)\n", i);
return -EIO;
}
}
/* Enable the new config. */
if (fd_pll_writel(fd, 0x01, 0x232) < 0)
return -EIO;
if (fd_pll_check(fd) < 0)
return -EIO;
/* Wait (at most 500ms) for it to lock */
timeout = trtl_get_runtime_milliseconds() + 500;
do {
ret = fd_pll_readl(fd, 0x1f);
if (ret < 0)
return -EIO;
if (ret & 0x1)
break;
} while (trtl_get_runtime_milliseconds() < timeout);
if (!(ret & 0x1))
return -EIO;
if (fd_pll_check(fd) < 0)
return -EIO;
/*
* Synchronize the phase of all clock outputs
* (this is critical for the accuracy!)
*/
if (fd_pll_writel(fd, 0x01, 0x230) < 0)
return -EIO;
if (fd_pll_writel(fd, 0x01, 0x232) < 0)
return -EIO;
if (fd_pll_writel(fd, 0x00, 0x230) < 0)
return -EIO;
if (fd_pll_writel(fd, 0x01, 0x232) < 0)
return -EIO;
return 0;
}
wrtd-53772dc3cd49421ea1fa6326a199b7a72dc04d18/software/firmware/fd/hw/ 0000775 0000000 0000000 00000000000 13460261316 0024065 5 ustar 00root root 0000000 0000000 wrtd-53772dc3cd49421ea1fa6326a199b7a72dc04d18/software/firmware/fd/hw/fd_channel_regs.h 0000664 0000000 0000000 00000011727 13460261316 0027347 0 ustar 00root root 0000000 0000000 /*
Register definitions for slave core: Fine Delay Channel WB Slave
* File : fd_channel_regs.h
* Author : auto-generated by wbgen2 from fd_channel_wishbone_slave.wb
* Created : Fri Feb 15 12:07:17 2013
* Standard : ANSI C
THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE fd_channel_wishbone_slave.wb
DO NOT HAND-EDIT UNLESS IT'S ABSOLUTELY NECESSARY!
*/
#ifndef __WBGEN2_REGDEFS_FD_CHANNEL_WISHBONE_SLAVE_WB
#define __WBGEN2_REGDEFS_FD_CHANNEL_WISHBONE_SLAVE_WB
#include
#if defined( __GNUC__)
#define PACKED __attribute__ ((packed))
#else
#error "Unsupported compiler?"
#endif
#ifndef __WBGEN2_MACROS_DEFINED__
#define __WBGEN2_MACROS_DEFINED__
#define WBGEN2_GEN_MASK(offset, size) (((1<<(size))-1) << (offset))
#define WBGEN2_GEN_WRITE(value, offset, size) (((value) & ((1<<(size))-1)) << (offset))
#define WBGEN2_GEN_READ(reg, offset, size) (((reg) >> (offset)) & ((1<<(size))-1))
#define WBGEN2_SIGN_EXTEND(value, bits) (((value) & (1<