pax_global_header 0000666 0000000 0000000 00000000064 12562737151 0014523 g ustar 00root root 0000000 0000000 52 comment=05c77d236b93a06053a6ec2d8ebcad493b999f28
x393_sata-05c77d236b93a06053a6ec2d8ebcad493b999f28/ 0000775 0000000 0000000 00000000000 12562737151 0020255 5 ustar 00root root 0000000 0000000 x393_sata-05c77d236b93a06053a6ec2d8ebcad493b999f28/.gitmodules 0000664 0000000 0000000 00000000112 12562737151 0022424 0 ustar 00root root 0000000 0000000 [submodule "x393"]
path = x393
url = https://github.com/Elphel/x393.git
x393_sata-05c77d236b93a06053a6ec2d8ebcad493b999f28/LICENSE 0000664 0000000 0000000 00000104506 12562737151 0021270 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
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
{one line to give the program's name and a brief idea of what it does.}
Copyright (C) {year} {name of author}
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, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:
{project} Copyright (C) {year} {fullname}
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, your program's commands
might be different; for a GUI interface, you would use an "about box".
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
.
The GNU General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
.
x393_sata-05c77d236b93a06053a6ec2d8ebcad493b999f28/README.md 0000664 0000000 0000000 00000001036 12562737151 0021534 0 ustar 00root root 0000000 0000000 # x393_sata
SATA controller for x393 camera
Board: Zynq 7z30
FPGA: Kintex-7
# Current step:
Connecting Ashwin's core (slow interface to the system is almost done, have to completely rewrite phy-level). Feels like making the phy works is going to require a lot of effort
# Going to do afterwards:
Complete and test the 'current step'. Write host controller with ~same functionallity, check if it works with previously verified higher-level code.
And then to spin out the full-compatible functionallity (ideally somewhere to the level of ahci)
x393_sata-05c77d236b93a06053a6ec2d8ebcad493b999f28/axi_regs.v 0000664 0000000 0000000 00000015364 12562737151 0022256 0 ustar 00root root 0000000 0000000 /*******************************************************************************
* Module: axi_regs
* Date: 2015-07-11
* Author: Alexey
* Description: slave axi interface buffer
*
* Copyright (c) 2015 Elphel, Inc.
* axi_regs.v 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, either version 3 of the License, or
* (at your option) any later version.
*
* axi_regs.v file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*******************************************************************************/
`include "axibram_read.v"
`include "axibram_write.v"
module axi_regs #(
parameter REGISTERS_CNT = 20
)
(
input wire ACLK, // AXI PS Master GP1 Clock , input
input wire ARESETN, // AXI PS Master GP1 Reset, output
// AXI PS Master GP1: Read Address
input wire [31:0] ARADDR, // AXI PS Master GP1 ARADDR[31:0], output
input wire ARVALID, // AXI PS Master GP1 ARVALID, output
output wire ARREADY, // AXI PS Master GP1 ARREADY, input
input wire [11:0] ARID, // AXI PS Master GP1 ARID[11:0], output
input wire [1:0] ARLOCK, // AXI PS Master GP1 ARLOCK[1:0], output
input wire [3:0] ARCACHE, // AXI PS Master GP1 ARCACHE[3:0], output
input wire [2:0] ARPROT, // AXI PS Master GP1 ARPROT[2:0], output
input wire [3:0] ARLEN, // AXI PS Master GP1 ARLEN[3:0], output
input wire [1:0] ARSIZE, // AXI PS Master GP1 ARSIZE[1:0], output
input wire [1:0] ARBURST, // AXI PS Master GP1 ARBURST[1:0], output
input wire [3:0] ARQOS, // AXI PS Master GP1 ARQOS[3:0], output
// AXI PS Master GP1: Read Data
output wire [31:0] RDATA, // AXI PS Master GP1 RDATA[31:0], input
output wire RVALID, // AXI PS Master GP1 RVALID, input
input wire RREADY, // AXI PS Master GP1 RREADY, output
output wire [11:0] RID, // AXI PS Master GP1 RID[11:0], input
output wire RLAST, // AXI PS Master GP1 RLAST, input
output wire [1:0] RRESP, // AXI PS Master GP1 RRESP[1:0], input
// AXI PS Master GP1: Write Address
input wire [31:0] AWADDR, // AXI PS Master GP1 AWADDR[31:0], output
input wire AWVALID, // AXI PS Master GP1 AWVALID, output
output wire AWREADY, // AXI PS Master GP1 AWREADY, input
input wire [11:0] AWID, // AXI PS Master GP1 AWID[11:0], output
input wire [1:0] AWLOCK, // AXI PS Master GP1 AWLOCK[1:0], output
input wire [3:0] AWCACHE, // AXI PS Master GP1 AWCACHE[3:0], output
input wire [2:0] AWPROT, // AXI PS Master GP1 AWPROT[2:0], output
input wire [3:0] AWLEN, // AXI PS Master GP1 AWLEN[3:0], outpu:t
input wire [1:0] AWSIZE, // AXI PS Master GP1 AWSIZE[1:0], output
input wire [1:0] AWBURST, // AXI PS Master GP1 AWBURST[1:0], output
input wire [3:0] AWQOS, // AXI PS Master GP1 AWQOS[3:0], output
// AXI PS Master GP1: Write Data
input wire [31:0] WDATA, // AXI PS Master GP1 WDATA[31:0], output
input wire WVALID, // AXI PS Master GP1 WVALID, output
output wire WREADY, // AXI PS Master GP1 WREADY, input
input wire [11:0] WID, // AXI PS Master GP1 WID[11:0], output
input wire WLAST, // AXI PS Master GP1 WLAST, output
input wire [3:0] WSTRB, // AXI PS Master GP1 WSTRB[3:0], output
// AXI PS Master GP1: Write Responce
output wire BVALID, // AXI PS Master GP1 BVALID, input
input wire BREADY, // AXI PS Master GP1 BREADY, output
output wire [11:0] BID, // AXI PS Master GP1 BID[11:0], input
output wire [1:0] BRESP, // AXI PS Master GP1 BRESP[1:0], input
// registers iface
input wire [31:0] bram_rdata,
output wire [31:0] bram_waddr,
output wire [31:0] bram_wdata,
output wire [31:0] bram_raddr,
output wire [3:0] bram_wstb,
output wire bram_wen,
output wire bram_ren,
output wire bram_regen
);
/*
* Converntional MAXI interface from x393 project
*/
// Interface's instantiation
axibram_write #(
.ADDRESS_BITS(16)
)
axibram_write(
.aclk (ACLK),
.rst (ARESETN),
.awaddr (AWADDR),
.awvalid (AWVALID),
.awready (AWREADY),
.awid (AWID),
.awlen (AWLEN),
.awsize (AWSIZE),
.awburst (AWBURST),
.wdata (WDATA),
.wvalid (WVALID),
.wready (WREADY),
.wid (WID),
.wlast (WLAST),
.wstb (WSTRB),
.bvalid (BVALID),
.bready (BREADY),
.bid (BID),
.bresp (BRESP),
.pre_awaddr (),
.start_burst (),
.dev_ready (1'b1),
.bram_wclk (),
.bram_waddr (bram_waddr[15:0]),
.bram_wen (bram_wen),
.bram_wstb (bram_wstb),
.bram_wdata (bram_wdata)
);
axibram_read #(
.ADDRESS_BITS(16)
)
axibram_read(
.aclk (ACLK),
.rst (ARESETN),
.araddr (ARADDR),
.arvalid (ARVALID),
.arready (ARREADY),
.arid (ARID),
.arlen (ARLEN),
.arsize (ARSIZE),
.arburst (ARBURST),
.rdata (RDATA),
.rvalid (RVALID),
.rready (RREADY),
.rid (RID),
.rlast (RLAST),
.rresp (RRESP),
.pre_araddr (),
.start_burst (),
.dev_ready (1'b1),
.bram_rclk (),
.bram_raddr (bram_raddr[15:0]),
.bram_ren (bram_ren),
.bram_regen (bram_regen),
.bram_rdata (bram_rdata)
);
endmodule
x393_sata-05c77d236b93a06053a6ec2d8ebcad493b999f28/dma_adapter.v 0000664 0000000 0000000 00000042571 12562737151 0022716 0 ustar 00root root 0000000 0000000 /*******************************************************************************
* Module: dma_adapter
* Date: 2015-07-11
* Author: Alexey
* Description: temporary interconnect to membridge testing purposes only
*
* Copyright (c) 2015 Elphel, Inc.
* dma_adapter.v 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, either version 3 of the License, or
* (at your option) any later version.
*
* dma_adapter.v file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*******************************************************************************/
/*
* The module is temporary
* It could make transactions from DMA data buffer to membridge and vice versa.
* Processes 1 transaction of 16 x 64bit-words at a time.
* Waits until 1 read or 1 write is completely done.
* After that it deasserts busy and is ready to process a new transaction.
*
* The whole purpose of a module as a system block is to be a buffer between
* a big dma data storage and axi interface. So it shall recieve data and control
* for 1 burst and pass it to axi.
*/
module dma_adapter(
input wire clk,
input wire rst,
// cmd iface
input wire cmd_type, // 1 = wr, 0 = rd
input wire cmd_val, // issue a cmd
input wire [31:7] cmd_addr, // [2:0] - 64-bit (8-bytes) word offset, [6:3] - 16-words transfer offset
output wire cmd_busy, // no-pipelined cmd execution, 1 cmd at a time
// data iface
input wire [63:0] wr_data_in,
input wire wr_val_in,
output wire wr_ack_out,
output wire [63:0] rd_data_out,
output wire rd_val_out,
input wire rd_ack_in,
// membridge iface
output wire [7:0] cmd_ad,
output wire cmd_stb,
input wire [7:0] status_ad,
input wire status_rq,
output wire status_start,
input wire frame_start_chn,
input wire next_page_chn,
output wire cmd_wrmem,
output wire page_ready_chn,
output wire frame_done_chn,
output wire [15:0] line_unfinished_chn1,
input wire suspend_chn1,
output wire xfer_reset_page_rd,
output wire buf_wpage_nxt,
output wire buf_wr,
output wire [63:0] buf_wdata,
output wire xfer_reset_page_wr,
output wire buf_rpage_nxt,
output wire buf_rd,
input wire [63:0] buf_rdata,
// additinal wire to indicate if membridge recieved a packet
input wire rdata_done // = membridge.is_last_in_page & membridge.afi_rready;
);
// cmd handling
// if not busy and got cmd with val => cmd recieved, assert busy, start a respective algorithm
wire wr_start;
wire rd_start;
wire dma_start;
reg wr_done;
reg rd_done;
reg cmd_type_r;
reg [31:7] cmd_addr_r;
reg cmd_busy_r;
wire set_busy;
wire clr_busy;
assign set_busy = ~cmd_busy_r & cmd_val;
assign clr_busy = cmd_busy_r & (wr_done | rd_done);
assign cmd_busy = cmd_busy_r;
assign wr_start = set_busy & cmd_type;
assign rd_start = set_busy & ~cmd_type;
always @ (posedge clk)
begin
cmd_type_r <= rst ? 1'b0 : set_busy ? cmd_type : cmd_type_r;
cmd_addr_r <= rst ? 1'b0 : set_busy ? cmd_addr : cmd_addr_r;
cmd_busy_r <= (cmd_busy_r | set_busy) & ~rst & ~clr_busy;
end
/*
* Read/write data state machine
* For better readability the state machine is splitted to two pieces:
* the first one is responsible only for the CMD WRITE case handling,
* the second one, respectively, for CMD READ
*
* Simultaniously with each fsm starts a membridge fsm, which, if being 1st time launched,
* sets up membridge's registers, or, if have been launched before, just programs read/write
* address.
*
* Current implementation is extremely slow, but simple and reliable
* After all other parts are implemented and this place occurs to be a bottleneck
* then replace it (and may be membridge too) with something more ... pipelined
*/
// check if memberidge was already set up
reg membr_is_set;
always @ (posedge clk)
membr_is_set <= (membr_is_set | dma_start) & ~rst;
// common state register
reg [3:0] rdwr_state;
// Get data from buffer
localparam READ_IDLE = 0;
localparam READ_WAIT_ADDR = 3;
localparam READ_DATA = 4;
reg rd_reset_page;
reg rd_next_page;
reg rd_data;
reg [6:0] rd_data_count;
reg rd_en;
wire rd_stop;
wire rd_cnt_to_pull;
assign rd_cnt_to_pull = 7'hf;
assign rd_stop = rd_ack_in & rd_data_count == rd_cnt_to_pull;
assign rd_data_out = rd_data;
always @ (posedge clk)
if (rst)
begin
rdwr_state <= READ_IDLE;
rd_done <= 1'b0;
rd_data_count <= 7'h0;
rd_next_page <= 1'b0;
rd_en <= 1'b0;
end
else
case (rdwr_state)
READ_IDLE:
begin
rdwr_state <= rd_start ? READ_WAIT_ADDR : READ_IDLE;
rd_done <= 1'b0;
rd_data_count <= 7'h0;
rd_next_page <= 1'b0;
rd_en <= 1'b0;
end
READ_WAIT_ADDR: // wait until address information is sent to the bus and input buffer got data
begin
rdwr_state <= membr_state == READ_IDLE & rdata_done ? READ_DATA : READ_WAIT_ADDR;
rd_done <= 1'b0;
rd_data_count <= 7'h0;
rd_next_page <= 1'b0;
rd_en <= 1'b0;
end
READ_DATA:
begin
rdwr_state <= rd_stop ? READ_IDLE : READ_DATA;
rd_done <= rd_stop ? 1'b1 : 1'b0;
rd_data_count <= rd_ack_in ? rd_data_count + 1'b1 : rd_data_count;
rd_next_page <= rd_stop ? 1'b1 : 1'b0;
rd_en <= rd_ack_in ? 1'b1 : 1'b0;
end
default: // write is processing
begin
rdwr_state <= READ_IDLE;
rd_done <= 1'b0;
rd_data_count <= 7'h0;
rd_next_page <= 1'b0;
rd_en <= 1'b0;
end
endcase
// Put data into buffer
localparam WRITE_IDLE = 0;
localparam WRITE_DATA = 1;
localparam WRITE_WAIT_ADDR = 2;
reg wr_en;
reg wr_reset_page;
reg wr_next_page;
reg [63:0] wr_data;
reg [6:0] wr_data_count;
reg wr_page_ready;
reg wr_val;
wire [6:0] wr_cnt_to_push;
wire wr_stop;
assign wr_cnt_to_push = 7'hf;
assign wr_stop = wr_val_in & wr_data_count == wr_cnt_to_push;
assign wr_ack_out = wr_val_in & rdwr_state == WRITE_DATA;
assign wr_data_in = wr_data;
// assuming for now we write only pre-defined 16 64-bit words
always @ (posedge clk)
if (rst)
begin
wr_done <= 1'b0;
wr_data_count <= 7'd0;
wr_val <= 1'b0;
wr_data <= 64'h0;
wr_next_page <= 1'b0;
wr_reset_page <= 1'b0;
wr_en <= 1'b0;
wr_page_ready <= 1'b0;
rdwr_state <= WRITE_IDLE;
end
else
case (rdwr_state)
WRITE_IDLE:
begin
wr_data_count <= 7'd0;
wr_done <= 1'b0;
wr_data <= 64'h0;
wr_next_page <= 1'b0;
wr_reset_page <= wr_start ? 1'b1 : 1'b0;
wr_en <= 1'b0;
wr_page_ready <= 1'b0;
rdwr_state <= wr_start ? WRITE_DATA : WRITE_IDLE;
end
WRITE_DATA:
begin
wr_done <= wr_stop & membr_state == WRITE_IDLE ? 1'b1 : 1'b0;
wr_data_count <= wr_val_in ? wr_data_count + 1'b1 : wr_data_count;
wr_data <= wr_data_in;
wr_next_page <= wr_stop ? 1'b1 : 1'b0;
wr_reset_page <= 1'b0;
wr_en <= wr_val_in;
wr_page_ready <= wr_stop ? 1'b1 : 1'b0;
rdwr_state <= wr_stop & membr_state == WRITE_IDLE ? WRITE_IDLE :
wr_stop ? WRITE_WAIT_ADDR : WRITE_DATA;
end
WRITE_WAIT_ADDR: // in case all data is written into a buffer, but address is still being issued on axi bus
begin
wr_done <= membr_state == WRITE_IDLE ? 1'b1 : 1'b0;
wr_data_count <= 7'd0;
wr_data <= 64'h0;
wr_next_page <= 1'b0;
wr_reset_page <= 1'b0;
wr_en <= 1'b0;
wr_page_ready <= 1'b0;
rdwr_state <= membr_state == WRITE_IDLE ? WRITE_IDLE : WRITE_WAIT_ADDR;
end
default: // read is executed
begin
wr_done <= 1'b0;
wr_data_count <= 7'd0;
wr_data <= 64'h0;
wr_next_page <= 1'b0;
wr_reset_page <= 1'b0;
wr_en <= 1'b0;
wr_page_ready <= 1'b0;
rdwr_state <= rdwr_state;
end
endcase
// membridge interface assigments
assign status_start = 1'b0; // no need until status is used
assign cmd_wrmem = ~cmd_type_r;
assign xfer_reset_page_wr = rd_reset_page;
assign buf_rpage_nxt = rd_next_page;
assign buf_rd = rd_en;
assign buf_wdata = wr_data;
assign buf_wr = wr_en;
assign buf_wpage_nxt = wr_next_page;
assign xfer_reset_page_rd = wr_reset_page;
assign page_ready_chn = cmd_wrmem ? 1'b0 : wr_page_ready;
assign frame_done_chn = 1'b1;
/*
* Transfer address and membridge set-ups state machine
*/
localparam MEMBR_IDLE = 0;
localparam MEMBR_MODE = 1;
localparam MEMBR_WIDTH = 2;
localparam MEMBR_LEN = 3;
localparam MEMBR_START = 4;
localparam MEMBR_SIZE = 5;
localparam MEMBR_LOADDR = 6;
localparam MEMBR_CTRL = 7;
reg [32:0] membr_data;
reg [15:0] membr_addr;
reg membr_start;
reg membr_done;
reg [2:0] membr_state;
reg membr_setup; // indicates the first tick of the state
wire membr_inprocess;
assign dma_start = wr_start | rd_start;
always @ (posedge clk)
if (rst)
begin
membr_data <= 32'h0;
membr_addr <= 16'h0;
membr_start <= 1'b0;
membr_setup <= 1'b0;
membr_done <= 1'b0;
membr_state <= MEMBR_IDLE;
end
else
case (membr_state)
MEMBR_IDLE:
begin
membr_data <= 32'h0;
membr_addr <= 16'h200;
membr_start <= dma_start ? 1'b1 : 1'b0;
membr_setup <= dma_start ? 1'b1 : 1'b0;
membr_done <= 1'b0;
membr_state <= dma_start & membr_is_set ? MEMBR_LOADDR :
dma_start ? MEMBR_MODE : MEMBR_IDLE;
end
MEMBR_MODE:
begin
membr_data <= 32'h3;
membr_addr <= 16'h207;
membr_start <= membr_inprocess ? 1'b0 : 1'b1;
membr_setup <= membr_inprocess | membr_setup ? 1'b0 : 1'b1;
membr_done <= 1'b0;
membr_state <= membr_inprocess | membr_setup ? MEMBR_MODE : MEMBR_WIDTH;
end
MEMBR_WIDTH:
begin
membr_data <= 32'h10;
membr_addr <= 16'h206;
membr_start <= membr_inprocess ? 1'b0 : 1'b1;
membr_setup <= membr_inprocess | membr_setup ? 1'b0 : 1'b1;
membr_done <= 1'b0;
membr_state <= membr_inprocess | membr_setup ? MEMBR_WIDTH : MEMBR_LEN;
end
MEMBR_LEN:
begin
membr_data <= 32'h10;
membr_addr <= 16'h205;
membr_start <= membr_inprocess ? 1'b0 : 1'b1;
membr_setup <= membr_inprocess | membr_setup ? 1'b0 : 1'b1;
membr_done <= 1'b0;
membr_state <= membr_inprocess | membr_setup ? MEMBR_LEN : MEMBR_START;
end
MEMBR_START:
begin
membr_data <= 32'h0;
membr_addr <= 16'h204;
membr_start <= membr_inprocess ? 1'b0 : 1'b1;
membr_setup <= membr_inprocess | membr_setup ? 1'b0 : 1'b1;
membr_done <= 1'b0;
membr_state <= membr_inprocess | membr_setup ? MEMBR_START : MEMBR_SIZE;
end
MEMBR_SIZE:
begin
membr_data <= 32'h10;
membr_addr <= 16'h203;
membr_start <= membr_inprocess ? 1'b0 : 1'b1;
membr_setup <= membr_inprocess | membr_setup ? 1'b0 : 1'b1;
membr_done <= 1'b0;
membr_state <= membr_inprocess | membr_setup ? MEMBR_SIZE : MEMBR_LOADDR;
end
MEMBR_LOADDR:
begin
membr_data <= cmd_addr_r;
membr_addr <= 16'h202;
membr_start <= membr_inprocess ? 1'b0 : 1'b1;
membr_setup <= membr_inprocess | membr_setup ? 1'b0 : 1'b1;
membr_done <= 1'b0;
membr_state <= membr_inprocess | membr_setup ? MEMBR_LOADDR : MEMBR_CTRL;
end
MEMBR_CTRL:
begin
membr_data <= {28'h0000000, 4'b0011};
membr_addr <= 16'h200;
membr_start <= membr_inprocess ? 1'b0 : 1'b1;
membr_setup <= 1'b0;
membr_done <= membr_inprocess | membr_setup ? 1'b0 : 1'b1;
membr_state <= membr_inprocess | membr_setup ? MEMBR_CTRL : MEMBR_IDLE;
end
default:
begin
membr_data <= 32'h0;
membr_addr <= 16'h0;
membr_start <= 1'b0;
membr_setup <= 1'b0;
membr_done <= 1'b0;
membr_state <= MEMBR_IDLE;
end
endcase
// write to memridge registers fsm
localparam STATE_IDLE = 3'h0;
localparam STATE_CMD_0 = 3'h1;
localparam STATE_CMD_1 = 3'h2;
localparam STATE_DATA_0 = 3'h3;
localparam STATE_DATA_1 = 3'h4;
localparam STATE_DATA_2 = 3'h5;
localparam STATE_DATA_3 = 3'h6;
reg [2:0] state;
reg [7:0] out_ad;
reg out_stb;
assign membr_inprocess = state != STATE_IDLE;
assign cmd_ad = out_ad;
assign cmd_stb = out_stb;
always @ (posedge clk)
if (rst)
begin
state <= STATE_IDLE;
out_ad <= 8'h0;
out_stb <= 1'b0;
end
else
case (state)
STATE_IDLE:
begin
out_ad <= 8'h0;
out_stb <= 1'b0;
state <= membr_setup ? STATE_CMD_0 : STATE_IDLE;
end
STATE_CMD_0:
begin
out_ad <= membr_addr[7:0];
out_stb <= 1'b1;
state <= STATE_CMD_1;
end
STATE_CMD_1:
begin
out_ad <= membr_addr[15:8];
out_stb <= 1'b0;
state <= STATE_DATA_0;
end
STATE_DATA_0:
begin
out_ad <= membr_data[7:0];
out_stb <= 1'b0;
state <= STATE_DATA_1;
end
STATE_DATA_1:
begin
out_ad <= membr_data[15:8];
out_stb <= 1'b0;
state <= STATE_DATA_2;
end
STATE_DATA_2:
begin
out_ad <= membr_data[23:16];
out_stb <= 1'b0;
state <= STATE_DATA_3;
end
STATE_DATA_3:
begin
out_ad <= membr_data[31:24];
out_stb <= 1'b0;
state <= STATE_IDLE;
end
default:
begin
out_ad <= 8'hff;
out_stb <= 1'b0;
state <= STATE_IDLE;
end
endcase
endmodule
x393_sata-05c77d236b93a06053a6ec2d8ebcad493b999f28/dma_control.v 0000664 0000000 0000000 00000034327 12562737151 0022756 0 ustar 00root root 0000000 0000000 /*******************************************************************************
* Module: dma_control
* Date: 2015-07-11
* Author: Alexey
* Description: temporary dma request control logic
*
* Copyright (c) 2015 Elphel, Inc.
* dma_control.v 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, either version 3 of the License, or
* (at your option) any later version.
*
* dma_control.v file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*******************************************************************************/
/*
* Later on most of address evaluation logic could be divided into 2 parts, which
* could be presented as 2 instances of 1 parameterized module
* + split data and address parts. Didnt do that because not sure if
* virtual channels would be implemented in the future
*/
module dma_control(
input wire sclk, // sata clock
input wire hclk, // axi-hp clock
input wire rst,
// registers iface
input wire [31:7] mem_address,
input wire [31:0] lba,
input wire [31:0] sector_cnt,
input wire dma_type,
input wire dma_start,
output wire dma_done,
// adapter command iface
input wire adp_busy,
output wire [31:7] adp_addr,
output wire adp_type,
output wire adp_val,
// sata host command iface
input wire host_ready_for_cmd,
output wire host_new_cmd,
output wire [1:0] host_cmd_type,
output wire [31:0] host_sector_count,
output wire [31:0] host_sector_addr,
// adapter data iface
// to main memory
output wire [63:0] to_data,
output wire to_val,
input wire to_ack,
// from main memory
input wire [63:0] from_data,
input wire from_val,
output wire from_ack,
// sata host iface
// data from sata host
input wire [31:0] in_data,
output wire in_val,
input wire in_busy,
// data to sata host
output wire [31:0] out_data,
output wire out_val,
input wire out_busy
);
//////////////////////////////////////////////////////////////////////////////////////
//// ADDRESS
//////////////////////////////////////////////////////////////////////////////////////
wire dma_done_adp;
wire dma_done_host;
assign dma_done = dma_done_host & dma_done_adp;
reg adp_busy_sclk;
/*
* Commands to sata host fsm
*/
// for now only 2 states: idle and send a pulse
reg host_issued;
wire host_issued_set;
wire host_issued_clr;
assign dma_done_host = host_issued;
assign host_issued_set = ~adp_busy_sclk & host_ready_for_cmd & dma_start;
assign host_issued_clr = dma_done;
always @ (posedge sclk)
host_issued <= (host_issued | host_issued_set) & ~host_issued_clr & ~rst;
// drive iface signals
assign host_new_cmd = host_issued_set;
assign host_cmd_type = dma_type;
assign host_sector_count = sector_cnt;
assign host_sector_addr = lba;
/*
* Commands to adapter fsm
*/
reg [33:0] quarter_sector_cnt;
wire last_data; // last 128 bytes of data are transmitted now
wire adp_val_sclk;
reg [31:7] current_addr;
reg current_type;
// synchronize with host fsm
reg adp_done;
wire adp_done_clr;
wire adp_done_set;
assign dma_done_adp = adp_done;
assign adp_done_set = state_wait_done & clr_wait_done & ~set_wait_busy; // = state_wait_done & set_idle;
assign adp_done_clr = dma_done;
always @ (posedge sclk)
adp_done <= (adp_done | adp_done_set) & ~adp_done_clr & ~rst;
// calculate sent sector count
// 1 sector = 512 bytes for now => 1 quarter_sector = 128 bytes
always @ (posedge sclk)
quarter_sector_cnt <= ~set_wait_busy ? quarter_sector_cnt :
state_idle ? 34'h0 : // new dma request
quarter_sector_cnt + 1'b1; // same dma request, next 128 bytes
// flags if we're currently sending the last data piece of dma transaction
assign last_data = (sector_cnt == quarter_sector_cnt[33:2] + 1'b1) & (&quarter_sector_cnt[1:0]);
// calculate outgoing address
// increment every transaction to adapter
always @ (posedge sclk)
current_addr <= ~set_wait_busy ? current_addr :
state_idle ? mem_address : // new dma request
current_addr + 1'b1; // same dma request, next 128 bytes
always @ (posedge sclk)
current_type <= ~set_wait_busy ? current_type :
state_idle ? dma_type : // new dma request
current_type; // same dma request, next 128 bytes
// fsm itself
wire state_idle;
reg state_wait_busy;
reg state_wait_done;
wire set_wait_busy;
wire set_wait_done;
wire clr_wait_busy;
wire clr_wait_done;
assign set_wait_busy = state_idle & host_issued_set // same start pulse for both fsms
| state_wait_done & clr_wait_done & ~last_data; // still have some data to transmit within a current dma request
assign set_wait_done = state_wait_busy & clr_wait_busy;
assign clr_wait_busy = adp_busy_sclk;
assign clr_wait_done = ~adp_busy_sclk;
assign state_idle = ~state_wait_busy & ~state_wait_done;
always @ (posedge sclk)
begin
state_wait_busy <= (state_wait_busy | set_wait_busy) & ~clr_wait_busy & ~rst;
state_wait_done <= (state_wait_done | set_wait_done) & ~clr_wait_done & ~rst;
end
// conrol signals resync
reg adp_val_r;
reg adp_val_rr;
always @ (posedge hclk)
begin
adp_val_r <= adp_val_sclk;
adp_val_rr <= adp_val_r;
end
assign adp_addr = current_addr;
assign adp_type = current_type;
assign adp_val = adp_val_rr;
// Maintaining correct adp_busy level @ sclk
// assuming busy won't toggle rapidly, can afford not implementing handshakes
wire adp_busy_sclk_set;
wire adp_busy_sclk_clr;
wire adp_busy_set;
wire adp_busy_clr;
reg adp_busy_r;
assign adp_busy_set = adp_busy & ~adp_busy_r;
assign adp_busy_clr = ~adp_busy & adp_busy_r;
always @ (posedge sclk)
adp_busy_sclk <= (adp_busy_sclk | adp_busy_sclk_set) & ~rst & ~adp_busy_sclk_clr;
always @ (posedge hclk)
adp_busy_r <= adp_busy;
pulse_cross_clock adp_busy_set_pulse(
.rst (rst),
.src_clk (hclk),
.dst_clk (sclk),
.in_pulse (adp_busy_set),
.out_pulse (adp_busy_sclk_set),
.busy ()
);
pulse_cross_clock adp_busy_clr_pulse(
.rst (rst),
.src_clk (hclk),
.dst_clk (sclk),
.in_pulse (adp_busy_clr),
.out_pulse (adp_busy_sclk_clr),
.busy ()
);
//////////////////////////////////////////////////////////////////////////////////////
//// DATA
//////////////////////////////////////////////////////////////////////////////////////
/*
* from main memory resyncronisation circuit
*/
reg [9:0] from_rd_addr;
reg [8:0] from_wr_addr;
// incremened addresses
wire [8:0] from_wr_next_addr;
wire [9:0] from_rd_next_addr;
// gray coded addresses
reg [9:0] from_rd_addr_gr;
reg [8:0] from_wr_addr_gr;
// anti-metastability shift registers for gray-coded addresses
reg [9:0] from_rd_addr_gr_r;
reg [8:0] from_wr_addr_gr_r;
reg [9:0] from_rd_addr_gr_rr;
reg [8:0] from_wr_addr_gr_rr;
// resynced to opposite clks addresses
wire [9:0] from_rd_addr_r;
wire [8:0] from_wr_addr_r;
// fifo states
wire from_full; // MAY BE full. ~full -> MUST NOT be full
wire from_empty; // MAY BE empty. ~empty -> MUST NOT be empty
wire from_re;
wire from_we;
assign from_wr_next_addr = from_wr_addr + 1'b1;
assign from_rd_next_addr = from_rd_addr + 1'b1;
// hclk domain counters
always @ (posedge hclk)
begin
from_wr_addr <= rst ? 9'h0 : from_we ? from_wr_next_addr : from_wr_addr;
from_wr_addr_gr <= rst ? 9'h0 : from_we ? from_wr_next_addr ^ {1'b0, from_wr_next_addr[8:1]} : from_wr_addr_gr;
end
// sclk domain counters
always @ (posedge sclk)
begin
from_rd_addr <= rst ? 10'h0 : from_re ? from_rd_next_addr : from_rd_addr;
from_rd_addr_gr <= rst ? 10'h0 : from_re ? from_rd_next_addr ^ {1'b0, from_rd_next_addr[9:1]} : from_rd_addr_gr;
end
// write address -> sclk (rd) domain to compare
always @ (posedge sclk)
begin
from_wr_addr_gr_r <= rst ? 9'h0 : from_wr_addr;
from_wr_addr_gr_rr <= rst ? 9'h0 : from_wr_addr_gr_r;
end
// read address -> hclk (wr) domain to compare
always @ (posedge hclk)
begin
from_rd_addr_gr_r <= rst ? 10'h0 : from_rd_addr;
from_rd_addr_gr_rr <= rst ? 10'h0 : from_rd_addr_gr_r;
end
// translate resynced write address into ordinary (non-gray) address
genvar ii;
generate
for (ii = 0; ii < 9; ii = ii + 1)
begin: from_wr_antigray
assign from_wr_addr_r[ii] = ^from_wr_addr_gr_rr[8:ii];
end
endgenerate
// translate resynced read address into ordinary (non-gray) address
generate
for (ii = 0; ii < 10; ii = ii + 1)
begin: from_rd_antigray
assign from_rd_addr_r[ii] = ^from_rd_addr_gr_rr[9:ii];
end
endgenerate
// so we've got the following:
// hclk domain: from_wr_addr - current write address
// from_rd_addr_r - read address some hclk ticks ago
// => we can say if the fifo have the possibility to be full
// since actual from_rd_addr could only be incremented
//
// sclk domain: from_rd_addr - current read address
// from_wr_addr_r - write address some sclk ticks ago
// => we can say if the fifo have the possibility to be empty
// since actual from_wr_addr could only be incremented
assign from_full = {from_wr_addr, 1'b0} == from_rd_addr_r + 1'b1;
assign from_empty = {from_wr_addr_r, 1'b0} == from_rd_addr; // overflows must never be achieved
// calculate bus responses in order to fifo status:
assign from_ack = from_val & ~from_full;
assign out_val = ~out_busy & ~from_empty;
assign from_re = out_val;
assign from_we = from_ack;
// data buffer, recieves 64-bit data from main memory, directs it to sata host
ram_512x64w_1kx32r #(
.REGISTERS (0)
)
dma_data_from_mem (
.rclk (sclk),
.raddr (from_rd_addr),
.ren (from_re),
.regen (1'b0),
.data_out (out_data),
.wclk (hclk),
.waddr (from_wr_addr),
.we (from_we),
.web (8'hff),
.data_in (from_data)
);
/////////////////////////////////////////////////////////////////////////////////
/*
* to main memory resyncronisation circuit
*/
reg [8:0] to_rd_addr;
reg [9:0] to_wr_addr;
// incremened addresses
wire [9:0] to_wr_next_addr;
wire [8:0] to_rd_next_addr;
// gray coded addresses
reg [8:0] to_rd_addr_gr;
reg [9:0] to_wr_addr_gr;
// anti-metastability shift registers for gray-coded addresses
reg [8:0] to_rd_addr_gr_r;
reg [9:0] to_wr_addr_gr_r;
reg [8:0] to_rd_addr_gr_rr;
reg [9:0] to_wr_addr_gr_rr;
// resynced to opposite clks addresses
wire [8:0] to_rd_addr_r;
wire [9:0] to_wr_addr_r;
// fifo states
wire to_full; // MAY BE full. ~full -> MUST NOT be full
wire to_empty; // MAY BE empty. ~empty -> MUST NOT be empty
wire to_re;
wire to_we;
assign to_wr_next_addr = to_wr_addr + 1'b1;
assign to_rd_next_addr = to_rd_addr + 1'b1;
// sclk domain counters
always @ (posedge sclk)
begin
to_wr_addr <= rst ? 10'h0 : to_we ? to_wr_next_addr : to_wr_addr;
to_wr_addr_gr <= rst ? 10'h0 : to_we ? to_wr_next_addr ^ {1'b0, to_wr_next_addr[9:1]} : to_wr_addr_gr;
end
// hclk domain counters
always @ (posedge hclk)
begin
to_rd_addr <= rst ? 9'h0 : to_re ? to_rd_next_addr : to_rd_addr;
to_rd_addr_gr <= rst ? 9'h0 : to_re ? to_rd_next_addr ^ {1'b0, to_rd_next_addr[8:1]} : to_rd_addr_gr;
end
// write address -> hclk (rd) domain to compare
always @ (posedge hclk)
begin
to_wr_addr_gr_r <= rst ? 10'h0 : to_wr_addr;
to_wr_addr_gr_rr <= rst ? 10'h0 : to_wr_addr_gr_r;
end
// read address -> sclk (wr) domain to compare
always @ (posedge sclk)
begin
to_rd_addr_gr_r <= rst ? 9'h0 : to_rd_addr;
to_rd_addr_gr_rr <= rst ? 9'h0 : to_rd_addr_gr_r;
end
// translate resynced write address into ordinary (non-gray) address
generate
for (ii = 0; ii < 10; ii = ii + 1)
begin: to_wr_antigray
assign to_wr_addr_r[ii] = ^to_wr_addr_gr_rr[9:ii];
end
endgenerate
// translate resynced read address into ordinary (non-gray) address
generate
for (ii = 0; ii < 9; ii = ii + 1)
begin: to_rd_antigray
assign to_rd_addr_r[ii] = ^to_rd_addr_gr_rr[8:ii];
end
endgenerate
// so we've got the following:
// sclk domain: to_wr_addr - current write address
// to_rd_addr_r - read address some sclk ticks ago
// => we can say if the fifo have the possibility to be full
// since actual to_rd_addr could only be incremented
//
// hclk domain: to_rd_addr - current read address
// to_wr_addr_r - write address some hclk ticks ago
// => we can say if the fifo have the possibility to be empty
// since actual to_wr_addr could only be incremented
assign to_full = {to_wr_addr, 1'b0} == to_rd_addr_r + 1'b1;
assign to_empty = {to_wr_addr_r, 1'b0} == to_rd_addr; // overflows must never be achieved
// calculate bus responses in order to fifo status:
assign to_val = ~to_empty;
assign in_val = ~in_busy & ~to_full;
assign to_re = to_ack;
assign to_we = in_val;
// data buffer, recieves 32-bit data from sata host, directs it to the main memory
ram_1kx32w_512x64r #(
.REGISTERS (0)
)
dma_data_to_mem (
.rclk (hclk),
.raddr (to_rd_addr),
.ren (to_re),
.regen (1'b0),
.data_out (to_data),
.wclk (sclk),
.waddr (to_wr_addr),
.we (to_we),
.web (4'hf),
.data_in (in_data)
);
endmodule
x393_sata-05c77d236b93a06053a6ec2d8ebcad493b999f28/dma_regs.v 0000664 0000000 0000000 00000026476 12562737151 0022244 0 ustar 00root root 0000000 0000000 /*******************************************************************************
* Module: dma_regs
* Date: 2015-07-11
* Author: Alexey
* Description: temporary registers, connected to axi bus
*
* Copyright (c) 2015 Elphel, Inc.
* dma_regs.v 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, either version 3 of the License, or
* (at your option) any later version.
*
* dma_regs.v file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*******************************************************************************/
module dma_regs #(
parameter REGISTERS_CNT = 20
)
(
input wire rst,
input wire ACLK,
input wire sclk,
// registers iface
output wire [31:7] mem_address,
output wire [31:0] lba,
output wire [31:0] sector_cnt,
output wire dma_type,
output wire dma_start,
input wire dma_done,
// axi buffer iface
output wire [31:0] bram_rdata,
input wire [31:0] bram_raddr,
input wire [31:0] bram_waddr,
input wire [31:0] bram_wdata,
input wire [3:0] bram_wstb,
input wire bram_wen,
input wire bram_ren,
input wire bram_regen,
// tmp to cmd control
output wire cmd_val_out,
output wire [31:0] cmd_out,
// tmp to shadow registers
output wire [31:0] sh_data, // write data
output wire sh_data_val, // write strobe
output wire sh_data_strobe, // read strobe
output wire [15:0] sh_feature,
output wire sh_feature_val,
output wire [23:0] sh_lba_lo,
output wire sh_lba_lo_val,
output wire [23:0] sh_lba_hi,
output wire sh_lba_hi_val,
output wire [15:0] sh_count,
output wire sh_count_val,
output wire [7:0] sh_command,
output wire sh_command_val,
output wire [7:0] sh_dev,
output wire sh_dev_val,
output wire [7:0] sh_control,
output wire sh_control_val,
output wire [31:0] sh_dma_id_lo
output wire sh_dma_id_lo_val,
output wire [31:0] sh_dma_id_hi,
output wire sh_dma_id_hi_val,
output wire [31:0] sh_buf_off,
output wire sh_buf_off_val,
output wire [31:0] sh_dma_cnt,
output wire sh_dma_cnt_val,
output wire [31:0] sh_tran_cnt,
output wire sh_tran_cnt_val,
output wire sh_autoact,
output wire sh_autoact_val,
output wire sh_inter,
output wire sh_inter_val,
output wire [3:0] sh_port,
output wire sh_port_val,
output wire sh_notif,
output wire sh_notif_val,
output wire sh_dir,
output wire sh_dir_val,
// inputs from sh registers
input wire sh_data_val_in,
input wire [31:0] sh_data_in,
input wire [7:0] sh_control_in,
input wire [15:0] sh_feature_in,
input wire [47:0] sh_lba_in,
input wire [15:0] sh_count_in,
input wire [7:0] sh_command_in,
input wire [7:0] sh_err_in,
input wire [7:0] sh_status_in,
input wire [7:0] sh_estatus_in, // E_Status
input wire [7:0] sh_dev_in,
input wire [3:0] sh_port_in,
input wire sh_inter_in,
input wire sh_dir_in,
input wire [63:0] sh_dma_id_in,
input wire [31:0] sh_dma_off_in,
input wire [31:0] sh_dma_cnt_in,
input wire [15:0] sh_tran_cnt_in, // Transfer Count
input wire sh_notif_in,
input wire sh_autoact_in
// inputs from cmd control
input wire [31:0] cmd_in
);
//reg [32*REGISTERS_CNT - 1:0] mem;
/*
* Converntional MAXI interface from x393 project, uses fifos, writes to/reads from memory
*/
/*
* Temporary mapping:
* rw 0x00: dma address (will automatically align to 128-bytes boundary, i.e. [6:0] -> 0
* rw 0x04: lba
* rw 0x08: sector count
* rw 0x0c: dma type (any(0x0c) => write)
* r1c 0x10: writes: dma start (any(0x10) => start)
* reads: dma status of last issued transfer (0xffffffff => done)
* ro 0x14: dma last issued dma_address
*/
reg [31:0] reg00;
reg [31:0] reg04;
reg [31:0] reg08;
reg [31:0] reg0c;
reg [31:0] reg10;
reg [31:0] reg14;
wire dma_done_aclk;
wire dma_start_aclk;
reg dma_issued;
wire [31:0] wdata;
pulse_cross_clock dma_done_pulse(
.rst (rst),
.src_clk (sclk),
.dst_clk (ACLK),
.in_pulse (dma_done),
.out_pulse (dma_done_aclk),
.busy ()
);
pulse_cross_clock dma_start_pulse(
.rst (rst),
.src_clk (ACLK),
.dst_clk (sclk),
.in_pulse (dma_start_aclk & ~dma_issued),
.out_pulse (dma_start),
.busy ()
);
assign dma_start_aclk = bram_wen & (bram_waddr[7:0] == 8'hf4) & |wdata;
assign wdata = bram_wdata[31:0] & {{8{bram_wstb[3]}}, {8{bram_wstb[2]}}, {8{bram_wstb[1]}}, {8{bram_wstb[0]}}};
always @ (posedge ACLK)
dma_issued <= (dma_issued | dma_start_aclk) & ~rst & ~dma_done_aclk;
assign mem_address = reg00[31:7];
assign lba = reg04;
assign sector_cnt = reg08;
assign dma_type = |reg0c;
always @ (posedge ACLK)
begin
reg00 <= rst ? 32'h0 : bram_wen & (bram_waddr[7:0] == 8'hf0) ? wdata : reg00;
reg04 <= rst ? 32'h0 : bram_wen & (bram_waddr[7:0] == 8'hf1) ? wdata : reg04;
reg08 <= rst ? 32'h0 : bram_wen & (bram_waddr[7:0] == 8'hf2) ? wdata : reg08;
reg0c <= rst ? 32'h0 : bram_wen & (bram_waddr[7:0] == 8'hf3) ? wdata : reg0c;
reg10 <= rst ? 32'h0 : dma_start_aclk ? 32'h0 : dma_done_aclk ? 32'hffffffff : reg10; // status reg
reg14 <= rst ? 32'h0 : dma_done_aclk ? reg00 : reg14;
end
// writes to shadow registers:
assign sh_data_val = bram_wen & (bram_waddr[7:0] == 8'h0);
assign sh_feature_val = bram_wen & (bram_waddr[7:0] == 8'h1);
assign sh_lba_lo_val = bram_wen & (bram_waddr[7:0] == 8'h2);
assign sh_lba_hi_val = bram_wen & (bram_waddr[7:0] == 8'h3);
assign sh_count_val = bram_wen & (bram_waddr[7:0] == 8'h4);
assign sh_command_val = bram_wen & (bram_waddr[7:0] == 8'h5);
assign sh_dev_val = bram_wen & (bram_waddr[7:0] == 8'h6);
assign sh_control_val = bram_wen & (bram_waddr[7:0] == 8'h7);
assign sh_dma_id_lo_val = bram_wen & (bram_waddr[7:0] == 8'h8);
assign sh_dma_id_hi_val = bram_wen & (bram_waddr[7:0] == 8'h9);
assign sh_buf_off_val = bram_wen & (bram_waddr[7:0] == 8'ha);
assign sh_tran_cnt_val = bram_wen & (bram_waddr[7:0] == 8'hb);
assign sh_autoact_val = bram_wen & (bram_waddr[7:0] == 8'hc);
assign sh_inter_val = bram_wen & (bram_waddr[7:0] == 8'hd);
assign sh_dir_val = bram_wen & (bram_waddr[7:0] == 8'he);
assign cmd_val_out = bram_wen & (bram_waddr[7:0] == 8'hf);
assign sh_port = bram_wen & (bram_waddr[7:0] == 8'h13);
assign sh_dma_cnt_val = bram_wen & (bram_waddr[7:0] == 8'h14);
assign sh_notif_val = bram_wen & (bram_waddr[7:0] == 8'h15);
assign sh_data = wdata;
assign sh_feature = wdata;
assign sh_lba_lo = wdata;
assign sh_lba_hi = wdata;
assign sh_count = wdata;
assign sh_command = wdata;
assign sh_dev = wdata;
assign sh_control = wdata;
assign sh_dma_id_lo = wdata;
assign sh_dma_id_hi = wdata;
assign sh_buf_off = wdata;
assign sh_tran_cnt = wdata;
assign sh_autoact = wdata;
assign sh_inter = wdata;
assign sh_dir = wdata;
assign sh_port = wdata;
assign sh_notif = wdata;
assign sh_dma_cnt = wdata;
assign cmd_out = wdata;
assign sh_data_strobe = bram_regen & bram_raddr_r == 8'h00;
// read from registers. Interface's protocol assumes returning data with a delay
reg [7:0] bram_raddr_r;
reg [31:0] bram_rdata_r;
always @ (posedge ACLK) begin
bram_raddr_r <= bram_ren ? bram_raddr[7:0] : bram_raddr_r;
bram_rdata_r <= ~bram_regen ? bram_rdata_r :
bram_raddr_r == 8'hf0 ? reg00 :
bram_raddr_r == 8'hf1 ? reg04 :
bram_raddr_r == 8'hf2 ? reg08 :
bram_raddr_r == 8'hf3 ? reg0c :
bram_raddr_r == 8'hf4 ? reg10 :
bram_raddr_r == 8'hf5 ? reg14 :
bram_raddr_r == 8'h00 ? sh_data_in :
bram_raddr_r == 8'h01 ? sh_feature_in :
bram_raddr_r == 8'h02 ? sh_lba_in[23:0] :
bram_raddr_r == 8'h03 ? sh_lba_in[47:24] :
bram_raddr_r == 8'h04 ? sh_count_in :
bram_raddr_r == 8'h05 ? sh_command_in :
bram_raddr_r == 8'h06 ? sh_dev_in :
bram_raddr_r == 8'h07 ? sh_control_in :
bram_raddr_r == 8'h08 ? sh_dma_id_in[31:0] :
bram_raddr_r == 8'h09 ? sh_dma_id_in[63:32] :
bram_raddr_r == 8'h0a ? sh_dma_off_in :
bram_raddr_r == 8'h0b ? sh_tran_cnt_in : // Transfer Count
bram_raddr_r == 8'h0c ? sh_autoact_in :
bram_raddr_r == 8'h0d ? sh_inter_in :
bram_raddr_r == 8'h0e ? sh_dir_in :
bram_raddr_r == 8'h0f ? cmd_in :
bram_raddr_r == 8'h10 ? sh_err_in :
bram_raddr_r == 8'h11 ? sh_status_in :
bram_raddr_r == 8'h12 ? sh_estatus_in : // E_Status
bram_raddr_r == 8'h13 ? sh_port_in :
bram_raddr_r == 8'h14 ? sh_dma_cnt_in :
bram_raddr_r == 8'h15 ? sh_notif_in :
32'hd34db33f;
end
assign bram_rdata = bram_rdata_r;
/*
// for testing purposes the 'memory' is a set of registers for now
// later on will try to use them as an application level registers
genvar ii;
generate
for (ii = 0; ii < REGISTERS_CNT; ii = ii + 1)
begin: write_to_mem
always @ (posedge ACLK)
begin
mem[32*ii + 31-:8] <= bram_wen & (bram_waddr[3:0] == ii) ? bram_wdata[31-:8] & {8{bram_wstb[3]}}: mem[32*ii + 31-:8];
mem[32*ii + 23-:8] <= bram_wen & (bram_waddr[3:0] == ii) ? bram_wdata[23-:8] & {8{bram_wstb[2]}}: mem[32*ii + 23-:8];
mem[32*ii + 15-:8] <= bram_wen & (bram_waddr[3:0] == ii) ? bram_wdata[15-:8] & {8{bram_wstb[1]}}: mem[32*ii + 15-:8];
mem[32*ii + 7-:8] <= bram_wen & (bram_waddr[3:0] == ii) ? bram_wdata[ 7-:8] & {8{bram_wstb[0]}}: mem[32*ii + 7-:8];
end
end
endgenerate
// read from memory. Interface's protocol assumes returning data with a delay
reg [3:0] bram_raddr_r;
reg [31:0] bram_rdata_r;
always @ (posedge ACLK) begin
bram_raddr_r <= bram_ren ? bram_raddr[3:0] : bram_raddr_r;
bram_rdata_r <= bram_regen ? mem[32*bram_raddr_r + 31-:32] : bram_rdata_r;
end
assign bram_rdata = bram_rdata_r;
*/
endmodule
x393_sata-05c77d236b93a06053a6ec2d8ebcad493b999f28/host/ 0000775 0000000 0000000 00000000000 12562737151 0021232 5 ustar 00root root 0000000 0000000 x393_sata-05c77d236b93a06053a6ec2d8ebcad493b999f28/host/command.v 0000664 0000000 0000000 00000027742 12562737151 0023053 0 ustar 00root root 0000000 0000000 /*******************************************************************************
* Module: command
* Date: 2015-07-11
* Author: Alexey
* Description: sata command layer temporary implementation
*
* Copyright (c) 2015 Elphel, Inc.
* command.v 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, either version 3 of the License, or
* (at your option) any later version.
*
* command.v file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*******************************************************************************/
/*
* For testing purposes almost neat, manually-controlled
*/
module command(
input rst,
input clk,
// tl cmd iface
output wire [2:0] cmd_type,
output wire cmd_val,
output wire [3:0] cmd_port,
input wire cmd_busy,
input wire cmd_done_good,
input wire cmd_done_bad,
// temporary TODO
input wire [31:0] al_cmd_in, // == {cmd_type, cmd_port, cmd_val, cmd_done_bad, cmd_done_good, cmd_busy}
input wire al_cmd_val_in,
output wire [31:0] al_cmd_out, // same
// data from tl
input wire [31:0] tl_data_in,
input wire tl_data_val_in,
input wire tl_data_last_in,
output wire tl_data_busy_out,
// to tl
output wire [31:0] tl_data_out,
output wire tl_data_last_out,
output wire tl_data_val_out,
input wire tl_data_strobe_in,
// tmp inputs directly from registers for each and every shadow register and control bit
// from al
input wire [31:0] al_sh_data_in, // write data
input wire al_sh_data_val_in, // write strobe
input wire al_sh_data_strobe_in, // read strobe
input wire [15:0] al_sh_feature_in,
input wire al_sh_feature_val_in,
input wire [23:0] al_sh_lba_lo_in,
input wire al_sh_lba_lo_val_in,
input wire [23:0] al_sh_lba_hi_in,
input wire al_sh_lba_hi_val_in,
input wire [15:0] al_sh_count_in,
input wire al_sh_count_val_in,
input wire [7:0] al_sh_command_in,
input wire al_sh_command_val_in,
input wire [7:0] al_sh_dev_in,
input wire al_sh_dev_val_in,
input wire [7:0] al_sh_control_in,
input wire al_sh_control_val_in,
input wire [31:0] al_sh_dma_id_lo_in,
input wire al_sh_dma_id_lo_val_in,
input wire [31:0] al_sh_dma_id_hi_in,
input wire al_sh_dma_id_hi_val_in,
input wire [31:0] al_sh_buf_off_in,
input wire al_sh_buf_off_val_in,
input wire [31:0] al_sh_tran_cnt_in,
input wire al_sh_tran_cnt_val_in,
input wire al_sh_autoact_in,
input wire al_sh_autoact_val_in,
input wire al_sh_inter_in,
input wire al_sh_inter_val_in,
input wire al_sh_dir_in,
input wire al_sh_dir_val_in,
input wire [31:0] al_sh_dma_cnt_in,
input wire al_sh_dma_cnt_val_in,
input wire al_sh_notif_in,
input wire al_sh_notif_val_in,
input wire [3:0] al_sh_port_in,
input wire al_sh_port_val_in,
// from tl
input wire [47:0] tl_sh_lba_in,
input wire [15:0] tl_sh_count_in,
input wire [7:0] tl_sh_command_in,
input wire [7:0] tl_sh_err_in,
input wire [7:0] tl_sh_status_in,
input wire [7:0] tl_sh_estatus_in, // E_Status
input wire [7:0] tl_sh_dev_in,
input wire [3:0] tl_sh_port_in,
input wire tl_sh_inter_in,
input wire tl_sh_dir_in,
input wire [63:0] tl_sh_dma_id_in,
input wire [31:0] tl_sh_dma_off_in,
input wire [31:0] tl_sh_dma_cnt_in,
input wire [15:0] tl_sh_tran_cnt_in, // Transfer Count
input wire tl_sh_notif_in,
input wire tl_sh_autoact_in,
input wire tl_sh_lba_val_in,
input wire tl_sh_count_val_in,
input wire tl_sh_command_val_in,
input wire tl_sh_err_val_in,
input wire tl_sh_status_val_in,
input wire tl_sh_estatus_val_in, // E_Status
input wire tl_sh_dev_val_in,
input wire tl_sh_port_val_in,
input wire tl_sh_inter_val_in,
input wire tl_sh_dir_val_in,
input wire tl_sh_dma_id_val_in,
input wire tl_sh_dma_off_val_in,
input wire tl_sh_dma_cnt_val_in,
input wire tl_sh_tran_cnt_val_in, // Transfer Count
input wire tl_sh_notif_val_in,
input wire tl_sh_autoact_val_in,
// all regs to output
output wire sh_data_val_out,
output wire [31:0] sh_data_out,
output wire [7:0] sh_control_out,
output wire [15:0] sh_feature_out,
output wire [47:0] sh_lba_out,
output wire [15:0] sh_count_out,
output wire [7:0] sh_command_out,
output wire [7:0] sh_err_out,
output wire [7:0] sh_status_out,
output wire [7:0] sh_estatus_out, // E_Status
output wire [7:0] sh_dev_out,
output wire [3:0] sh_port_out,
output wire sh_inter_out,
output wire sh_dir_out,
output wire [63:0] sh_dma_id_out,
output wire [31:0] sh_dma_off_out,
output wire [31:0] sh_dma_cnt_out,
output wire [15:0] sh_tran_cnt_out, // Transfer Count
output wire sh_notif_out,
output wire sh_autoact_out
);
// shadow registers
wire [31:0] sh_data;
reg [7:0] sh_control;
reg [15:0] sh_feature;
reg [47:0] sh_lba;
reg [15:0] sh_count;
reg [7:0] sh_command;
reg [7:0] sh_err;
reg [7:0] sh_status;
reg [7:0] sh_estatus; // E_Status
reg [7:0] sh_dev;
reg [3:0] sh_port;
reg sh_inter;
reg sh_dir;
reg [63:0] sh_dma_id;
reg [31:0] sh_dma_off;
reg [31:0] sh_dma_cnt;
reg [15:0] sh_tran_cnt; // Transfer Count
reg sh_notif;
reg sh_autoact;
always @ (posedge clk)
begin
// sh_data <= rst ? 32'h0 : al_sh_data_val_in ? al_sh_data_in : /*tl_sh_data_val_in ? tl_sh_data_in :*/ sh_data;
sh_control <= rst ? 8'h0 : al_sh_control_val_in ? al_sh_control_in : /*tl_sh_control_val_in ? tl_sh_control_in :*/ sh_control;
sh_feature <= rst ? 16'h0 : al_sh_feature_val_in ? al_sh_feature_in : /*tl_sh_feature_val_in ? tl_sh_feature_in :*/ sh_feature;
sh_lba[23:0] <= rst ? 24'h0 : al_sh_lba_lo_val_in ? al_sh_lba_lo_in : tl_sh_lba_val_in ? tl_sh_lba_in[23:0] : sh_lba[23:0];
sh_lba[47:24] <= rst ? 24'h0 : al_sh_lba_hi_val_in ? al_sh_lba_hi_in : tl_sh_lba_val_in ? tl_sh_lba_in[47:24] : sh_lba[47:24];
sh_count <= rst ? 16'h0 : al_sh_count_val_in ? al_sh_count_in : tl_sh_count_val_in ? tl_sh_count_in : sh_count;
sh_command <= rst ? 8'h0 : al_sh_command_val_in ? al_sh_command_in : tl_sh_command_val_in ? tl_sh_command_in : sh_command;
sh_err <= rst ? 8'h0 :/* al_sh_err_val_in ? al_sh_err_in :*/ tl_sh_err_val_in ? tl_sh_err_in : sh_err;
sh_status <= rst ? 8'h0 :/* al_sh_status_val_in ? al_sh_status_in :*/ tl_sh_status_val_in ? tl_sh_status_in : sh_status;
sh_estatus <= rst ? 8'h0 :/* al_sh_estatus_val_in ? al_sh_estatus_in :*/ tl_sh_estatus_val_in ? tl_sh_estatus_in : sh_estatus;
sh_dev <= rst ? 8'h0 : al_sh_dev_val_in ? al_sh_dev_in : tl_sh_dev_val_in ? tl_sh_dev_in : sh_dev;
sh_port <= rst ? 4'h0 : al_sh_port_val_in ? al_sh_port_in : tl_sh_port_val_in ? tl_sh_port_in : sh_port;
sh_inter <= rst ? 1'h0 : al_sh_inter_val_in ? al_sh_inter_in : tl_sh_inter_val_in ? tl_sh_inter_in : sh_inter;
sh_dir <= rst ? 1'h0 : al_sh_dir_val_in ? al_sh_dir_in : tl_sh_dir_val_in ? tl_sh_dir_in : sh_dir;
sh_dma_id[31:0] <= rst ? 32'h0 : al_sh_dma_id_lo_val_in ? al_sh_dma_id_lo_in : tl_sh_dma_id_val_in ? tl_sh_dma_id_in[31:0] : sh_dma_id[31:0];
sh_dma_id[63:32] <= rst ? 32'h0 : al_sh_dma_id_lo_val_in ? al_sh_dma_id_hi_in : tl_sh_dma_id_val_in ? tl_sh_dma_id_in[63:32] : sh_dma_id[63:32];
sh_dma_off <= rst ? 32'h0 : al_sh_buf_off_val_in ? al_sh_buf_off_in : tl_sh_dma_off_val_in ? tl_sh_dma_off_in : sh_dma_off;
sh_dma_cnt <= rst ? 32'h0 : al_sh_dma_cnt_val_in ? al_sh_dma_cnt_in : tl_sh_dma_cnt_val_in ? tl_sh_dma_cnt_in : sh_dma_cnt;
sh_tran_cnt <= rst ? 32'h0 : al_sh_tran_cnt_val_in ? al_sh_tran_cnt_in : tl_sh_tran_cnt_val_in ? tl_sh_tran_cnt_in : sh_tran_cnt;
sh_notif <= rst ? 1'h0 : al_sh_notif_val_in ? al_sh_notif_in : tl_sh_notif_val_in ? tl_sh_notif_in : sh_notif;
sh_autoact <= rst ? 1'h0 : al_sh_autoact_val_in ? al_sh_autoact_in : tl_sh_autoact_val_in ? tl_sh_autoact_in : sh_autoact;
end
// outputs assignment
assign sh_data_out = sh_data;
assign sh_control_out = sh_control;
assign sh_feature_out = sh_feature;
assign sh_lba_out = sh_lba;
assign sh_count_out = sh_count;
assign sh_command_out = sh_command;
assign sh_err_out = sh_err;
assign sh_status_out = sh_status;
assign sh_estatus_out = sh_estatus;
assign sh_dev_out = sh_dev;
assign sh_port_out = sh_port;
assign sh_inter_out = sh_inter;
assign sh_dir_out = sh_dir;
assign sh_dma_id_out = sh_dma_id;
assign sh_dma_off_out = sh_dma_off;
assign sh_dma_cnt_out = sh_dma_cnt;
assign sh_tran_cnt_out = sh_tran_cnt;
assign sh_notif_out = sh_notif;
assign sh_autoact_out = sh_autoact;
// temporaty command register TODO
reg [31:0] cmd;
assign al_cmd_out = cmd;
always @ (posedge clk)
begin
cmd[31:4] <= rst ? 28'h0 : al_cmd_val_in ? al_cmd_in : cmd;
cmd[3] <= rst ? 1'b0 : al_cmd_val_in ? al_cmd_in[3] : cmd_val ? 1'b0 : cmd[3];
cmd[2] <= rst ? 1'b0 : al_cmd_val_in ? 1'b0 : cmd_done_bad ? 1'b1 : cmd[2];
cmd[1] <= rst ? 1'b0 : al_cmd_val_in ? 1'b0 : cmd_done_good ? 1'b1 : cmd[2];
cmd[0] <= rst ? 1'b0 : al_cmd_val_in ? 1'b0 : cmd_busy;
end
assign cmd_val = ~cmd_busy & cmd[3];
assign cmd_type = cmd[10:8];
assign cmd_port = cmd[7:4];
// data read buffer, 2048 dwords
reg [9:0] raddr;
reg [9:0] waddr;
assign tl_data_busy_out = 1'b0;
assign tl_data_out = 32'h0;
assign tl_data_last_out = 1'b0;
assign tl_data_val_out = 1'b0;
always @ (posedge clk)
waddr <= rst ? 1'b0 : ~tl_data_val_in ? waddr : (raddr == waddr + 1'b1) ? waddr : waddr + 1'b1;
always @ (posedge clk)
raddr <= rst ? 1'b0 : al_sh_data_strobe_in ? raddr + 1'b1 : waddr;
ram_1kx32_1kx32 rbuf(
.rclk (clk), // clock for read port
.raddr (raddr), // read address
.ren (al_sh_data_strobe_in), // read port enable
.regen (1'b0), // output register enable
.data_out (sh_data), // data out
.wclk (clk), // clock for read port
.waddr (waddr), // write address
.we (tl_data_val_in), // write port enable
.web (4'hf),
.data_in (tl_data_in) // data out
);
endmodule
x393_sata-05c77d236b93a06053a6ec2d8ebcad493b999f28/host/crc.v 0000664 0000000 0000000 00000022040 12562737151 0022166 0 ustar 00root root 0000000 0000000 /*******************************************************************************
* Module: crc
* Date: 2015-07-11
* Author: Alexey
* Description: crc calculations for the link layer
*
* Copyright (c) 2015 Elphel, Inc.
* crc.v 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, either version 3 of the License, or
* (at your option) any later version.
*
* crc.v file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*******************************************************************************/
/* same as for a scrambler, @ doc p.561 */
// TODO make it parallel, make another widths support
module crc #(
parameter DATA_BYTE_WIDTH = 4
)
(
input wire clk,
input wire rst,
input wire val_in,
input wire [DATA_BYTE_WIDTH*8 - 1:0] data_in,
output wire [DATA_BYTE_WIDTH*8 - 1:0] crc_out
);
reg [31:0] crc;
wire[31:0] crc_bit;
reg [31:0] new_bit;
always @ (posedge clk)
crc <= rst ? 32'h52325032 : val_in ? new_bit : crc;
assign crc_bit = crc ^ data_in;
assign crc_out = crc;
always @ (*)
begin
new_bit[31] = crc_bit[31] ^ crc_bit[30] ^ crc_bit[29] ^ crc_bit[28] ^ crc_bit[27] ^ crc_bit[25] ^ crc_bit[24] ^
crc_bit[23] ^ crc_bit[15] ^ crc_bit[11] ^ crc_bit[9] ^ crc_bit[8] ^ crc_bit[5];
new_bit[30] = crc_bit[30] ^ crc_bit[29] ^ crc_bit[28] ^ crc_bit[27] ^ crc_bit[26] ^ crc_bit[24] ^ crc_bit[23] ^
crc_bit[22] ^ crc_bit[14] ^ crc_bit[10] ^ crc_bit[8] ^ crc_bit[7] ^ crc_bit[4];
new_bit[29] = crc_bit[31] ^ crc_bit[29] ^ crc_bit[28] ^ crc_bit[27] ^ crc_bit[26] ^ crc_bit[25] ^ crc_bit[23] ^
crc_bit[22] ^ crc_bit[21] ^ crc_bit[13] ^ crc_bit[9] ^ crc_bit[7] ^ crc_bit[6] ^ crc_bit[3];
new_bit[28] = crc_bit[30] ^ crc_bit[28] ^ crc_bit[27] ^ crc_bit[26] ^ crc_bit[25] ^ crc_bit[24] ^ crc_bit[22] ^
crc_bit[21] ^ crc_bit[20] ^ crc_bit[12] ^ crc_bit[8] ^ crc_bit[6] ^ crc_bit[5] ^ crc_bit[2];
new_bit[27] = crc_bit[29] ^ crc_bit[27] ^ crc_bit[26] ^ crc_bit[25] ^ crc_bit[24] ^ crc_bit[23] ^ crc_bit[21] ^
crc_bit[20] ^ crc_bit[19] ^ crc_bit[11] ^ crc_bit[7] ^ crc_bit[5] ^ crc_bit[4] ^ crc_bit[1];
new_bit[26] = crc_bit[31] ^ crc_bit[28] ^ crc_bit[26] ^ crc_bit[25] ^ crc_bit[24] ^ crc_bit[23] ^ crc_bit[22] ^
crc_bit[20] ^ crc_bit[19] ^ crc_bit[18] ^ crc_bit[10] ^ crc_bit[6] ^ crc_bit[4] ^ crc_bit[3] ^
crc_bit[0];
new_bit[25] = crc_bit[31] ^ crc_bit[29] ^ crc_bit[28] ^ crc_bit[22] ^ crc_bit[21] ^ crc_bit[19] ^ crc_bit[18] ^
crc_bit[17] ^ crc_bit[15] ^ crc_bit[11] ^ crc_bit[8] ^ crc_bit[3] ^ crc_bit[2];
new_bit[24] = crc_bit[30] ^ crc_bit[28] ^ crc_bit[27] ^ crc_bit[21] ^ crc_bit[20] ^ crc_bit[18] ^ crc_bit[17] ^
crc_bit[16] ^ crc_bit[14] ^ crc_bit[10] ^ crc_bit[7] ^ crc_bit[2] ^ crc_bit[1];
new_bit[23] = crc_bit[31] ^ crc_bit[29] ^ crc_bit[27] ^ crc_bit[26] ^ crc_bit[20] ^ crc_bit[19] ^ crc_bit[17] ^
crc_bit[16] ^ crc_bit[15] ^ crc_bit[13] ^ crc_bit[9] ^ crc_bit[6] ^ crc_bit[1] ^ crc_bit[0];
new_bit[22] = crc_bit[31] ^ crc_bit[29] ^ crc_bit[27] ^ crc_bit[26] ^ crc_bit[24] ^ crc_bit[23] ^ crc_bit[19] ^
crc_bit[18] ^ crc_bit[16] ^ crc_bit[14] ^ crc_bit[12] ^ crc_bit[11] ^ crc_bit[9] ^ crc_bit[0];
new_bit[21] = crc_bit[31] ^ crc_bit[29] ^ crc_bit[27] ^ crc_bit[26] ^ crc_bit[24] ^ crc_bit[22] ^ crc_bit[18] ^
crc_bit[17] ^ crc_bit[13] ^ crc_bit[10] ^ crc_bit[9] ^ crc_bit[5];
new_bit[20] = crc_bit[30] ^ crc_bit[28] ^ crc_bit[26] ^ crc_bit[25] ^ crc_bit[23] ^ crc_bit[21] ^ crc_bit[17] ^
crc_bit[16] ^ crc_bit[12] ^ crc_bit[9] ^ crc_bit[8] ^ crc_bit[4];
new_bit[19] = crc_bit[29] ^ crc_bit[27] ^ crc_bit[25] ^ crc_bit[24] ^ crc_bit[22] ^ crc_bit[20] ^ crc_bit[16] ^
crc_bit[15] ^ crc_bit[11] ^ crc_bit[8] ^ crc_bit[7] ^ crc_bit[3];
new_bit[18] = crc_bit[31] ^ crc_bit[28] ^ crc_bit[26] ^ crc_bit[24] ^ crc_bit[23] ^ crc_bit[21] ^ crc_bit[19] ^
crc_bit[15] ^ crc_bit[14] ^ crc_bit[10] ^ crc_bit[7] ^ crc_bit[6] ^ crc_bit[2];
new_bit[17] = crc_bit[31] ^ crc_bit[30] ^ crc_bit[27] ^ crc_bit[25] ^ crc_bit[23] ^ crc_bit[22] ^ crc_bit[20] ^
crc_bit[18] ^ crc_bit[14] ^ crc_bit[13] ^ crc_bit[9] ^ crc_bit[6] ^ crc_bit[5] ^ crc_bit[1];
new_bit[16] = crc_bit[30] ^ crc_bit[29] ^ crc_bit[26] ^ crc_bit[24] ^ crc_bit[22] ^ crc_bit[21] ^ crc_bit[19] ^
crc_bit[17] ^ crc_bit[13] ^ crc_bit[12] ^ crc_bit[8] ^ crc_bit[5] ^ crc_bit[4] ^ crc_bit[0];
new_bit[15] = crc_bit[30] ^ crc_bit[27] ^ crc_bit[24] ^ crc_bit[21] ^ crc_bit[20] ^ crc_bit[18] ^ crc_bit[16] ^
crc_bit[15] ^ crc_bit[12] ^ crc_bit[9] ^ crc_bit[8] ^ crc_bit[7] ^ crc_bit[5] ^ crc_bit[4] ^
crc_bit[3];
new_bit[14] = crc_bit[29] ^ crc_bit[26] ^ crc_bit[23] ^ crc_bit[20] ^ crc_bit[19] ^ crc_bit[17] ^ crc_bit[15] ^
crc_bit[14] ^ crc_bit[11] ^ crc_bit[8] ^ crc_bit[7] ^ crc_bit[6] ^ crc_bit[4] ^ crc_bit[3] ^
crc_bit[2];
new_bit[13] = crc_bit[31] ^ crc_bit[28] ^ crc_bit[25] ^ crc_bit[22] ^ crc_bit[19] ^ crc_bit[18] ^ crc_bit[16] ^
crc_bit[14] ^ crc_bit[13] ^ crc_bit[10] ^ crc_bit[7] ^ crc_bit[6] ^ crc_bit[5] ^ crc_bit[3] ^
crc_bit[2] ^ crc_bit[1];
new_bit[12] = crc_bit[31] ^ crc_bit[30] ^ crc_bit[27] ^ crc_bit[24] ^ crc_bit[21] ^ crc_bit[18] ^ crc_bit[17] ^
crc_bit[15] ^ crc_bit[13] ^ crc_bit[12] ^ crc_bit[9] ^ crc_bit[6] ^ crc_bit[5] ^ crc_bit[4] ^
crc_bit[2] ^ crc_bit[1] ^ crc_bit[0];
new_bit[11] = crc_bit[31] ^ crc_bit[28] ^ crc_bit[27] ^ crc_bit[26] ^ crc_bit[25] ^ crc_bit[24] ^ crc_bit[20] ^
crc_bit[17] ^ crc_bit[16] ^ crc_bit[15] ^ crc_bit[14] ^ crc_bit[12] ^ crc_bit[9] ^ crc_bit[4] ^
crc_bit[3] ^ crc_bit[1] ^ crc_bit[0];
new_bit[10] = crc_bit[31] ^ crc_bit[29] ^ crc_bit[28] ^ crc_bit[26] ^ crc_bit[19] ^ crc_bit[16] ^ crc_bit[14] ^
crc_bit[13] ^ crc_bit[9] ^ crc_bit[5] ^ crc_bit[3] ^ crc_bit[2] ^ crc_bit[0];
new_bit[9] = crc_bit[29] ^ crc_bit[24] ^ crc_bit[23] ^ crc_bit[18] ^ crc_bit[13] ^ crc_bit[12] ^ crc_bit[11] ^
crc_bit[9] ^ crc_bit[5] ^ crc_bit[4] ^ crc_bit[2] ^ crc_bit[1];
new_bit[8] = crc_bit[31] ^ crc_bit[28] ^ crc_bit[23] ^ crc_bit[22] ^ crc_bit[17] ^ crc_bit[12] ^ crc_bit[11] ^
crc_bit[10] ^ crc_bit[8] ^ crc_bit[4] ^ crc_bit[3] ^ crc_bit[1] ^ crc_bit[0];
new_bit[7] = crc_bit[29] ^ crc_bit[28] ^ crc_bit[25] ^ crc_bit[24] ^ crc_bit[23] ^ crc_bit[22] ^ crc_bit[21] ^
crc_bit[16] ^ crc_bit[15] ^ crc_bit[10] ^ crc_bit[8] ^ crc_bit[7] ^ crc_bit[5] ^ crc_bit[3] ^
crc_bit[2] ^ crc_bit[0];
new_bit[6] = crc_bit[30] ^ crc_bit[29] ^ crc_bit[25] ^ crc_bit[22] ^ crc_bit[21] ^ crc_bit[20] ^ crc_bit[14] ^
crc_bit[11] ^ crc_bit[8] ^ crc_bit[7] ^ crc_bit[6] ^ crc_bit[5] ^ crc_bit[4] ^ crc_bit[2] ^
crc_bit[1];
new_bit[5] = crc_bit[29] ^ crc_bit[28] ^ crc_bit[24] ^ crc_bit[21] ^ crc_bit[20] ^ crc_bit[19] ^ crc_bit[13] ^
crc_bit[10] ^ crc_bit[7] ^ crc_bit[6] ^ crc_bit[5] ^ crc_bit[4] ^ crc_bit[3] ^ crc_bit[1] ^
crc_bit[0];
new_bit[4] = crc_bit[31] ^ crc_bit[30] ^ crc_bit[29] ^ crc_bit[25] ^ crc_bit[24] ^ crc_bit[20] ^ crc_bit[19] ^
crc_bit[18] ^ crc_bit[15] ^ crc_bit[12] ^ crc_bit[11] ^ crc_bit[8] ^ crc_bit[6] ^ crc_bit[4] ^
crc_bit[3] ^ crc_bit[2] ^ crc_bit[0];
new_bit[3] = crc_bit[31] ^ crc_bit[27] ^ crc_bit[25] ^ crc_bit[19] ^ crc_bit[18] ^ crc_bit[17] ^ crc_bit[15] ^
crc_bit[14] ^ crc_bit[10] ^ crc_bit[9] ^ crc_bit[8] ^ crc_bit[7] ^ crc_bit[3] ^ crc_bit[2] ^
crc_bit[1];
new_bit[2] = crc_bit[31] ^ crc_bit[30] ^ crc_bit[26] ^ crc_bit[24] ^ crc_bit[18] ^ crc_bit[17] ^ crc_bit[16] ^
crc_bit[14] ^ crc_bit[13] ^ crc_bit[9] ^ crc_bit[8] ^ crc_bit[7] ^ crc_bit[6] ^ crc_bit[2] ^
crc_bit[1] ^ crc_bit[0];
new_bit[1] = crc_bit[28] ^ crc_bit[27] ^ crc_bit[24] ^ crc_bit[17] ^ crc_bit[16] ^ crc_bit[13] ^ crc_bit[12] ^
crc_bit[11] ^ crc_bit[9] ^ crc_bit[7] ^ crc_bit[6] ^ crc_bit[1] ^ crc_bit[0];
new_bit[0] = crc_bit[31] ^ crc_bit[30] ^ crc_bit[29] ^ crc_bit[28] ^ crc_bit[26] ^ crc_bit[25] ^ crc_bit[24] ^
crc_bit[16] ^ crc_bit[12] ^ crc_bit[10] ^ crc_bit[9] ^ crc_bit[6] ^ crc_bit[0];
end
endmodule
x393_sata-05c77d236b93a06053a6ec2d8ebcad493b999f28/host/link.v 0000664 0000000 0000000 00000101152 12562737151 0022356 0 ustar 00root root 0000000 0000000 /*******************************************************************************
* Module: link
* Date: 2015-07-11
* Author: Alexey
* Description: sata link layer implementation
*
* Copyright (c) 2015 Elphel, Inc.
* link.v 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, either version 3 of the License, or
* (at your option) any later version.
*
* link.v file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*******************************************************************************/
module link #(
// 4 = dword. 4-bytes aligned data transfers TODO 2 = word - easy, 8 = qword - difficult
parameter DATA_BYTE_WIDTH = 4
)
(
// TODO insert watchdogs
input wire rst,
input wire clk,
// data inputs from transport layer
// input data stream (if any data during OOB setting => ignored)
input wire [DATA_BYTE_WIDTH*8 - 1:0] data_in,
// in case of strange data aligments and size (1st mentioned @ doc, p.310, odd number of words case)
// Actually, only last data bundle shall be masked, others are always valid.
// Mask could be encoded into 3 bits instead of 4 for qword, but encoding+decoding aren't worth the bit
// TODO, for now not supported, all mask bits are assumed to be set
input wire [DATA_BYTE_WIDTH/2 - 1:0] data_mask_in,
// buffer read strobe
output wire data_strobe_out,
// transaction's last data budle pulse
input wire data_last_in,
// read data is valid (if 0 while last pulse wasn't received => need to hold the line)
input wire data_val_in,
// data outputs to transport layer
// read data, same as related inputs
output wire [DATA_BYTE_WIDTH*8 - 1:0] data_out,
// same thing - all 1s for now. TODO
output wire [DATA_BYTE_WIDTH/2 - 1:0] data_mask_out,
// count every data bundle read by transport layer, even if busy flag is set
// let the transport layer handle oveflows by himself
output wire data_val_out,
// transport layer tells if its inner buffer is almost full
input wire data_busy_in,
output wire data_last_out,
// request for a new frame transition
input wire frame_req,
// a little bit of overkill with the cound of response signals, think of throwing out 1 of them
// LL tells back if it cant handle the request for now
output wire frame_busy,
// LL tells if the request is transmitting
output wire frame_ack,
// or if it was cancelled because of simultanious incoming transmission
output wire frame_rej,
// TL tell if the outcoming transaction is done and how it was done
output wire frame_done_good,
output wire frame_done_bad,
// if started an incoming transaction
output wire incom_start,
// if incoming transition was completed
output wire incom_done,
// if incoming transition had errors
output wire incom_invalidate,
// transport layer responds on a completion of a FIS
input wire incom_ack_good,
input wire incom_ack_bad,
// oob sequence is reinitiated and link now is not established or rxelecidle
input wire link_reset,
// TL demands to brutally cancel current transaction
input wire sync_escape_req,
// acknowlegement of a successful reception
output wire sync_escape_ack,
// TL demands to stop current recieving session
input wire incom_stop_req,
// inputs from phy
// phy is ready - link is established
input wire phy_ready,
// data-primitives stream from phy
input wire [DATA_BYTE_WIDTH*8 - 1:0] phy_data_in,
input wire [DATA_BYTE_WIDTH/2 - 1:0] phy_isk_in, // charisk
input wire [DATA_BYTE_WIDTH/2 - 1:0] phy_err_in, // disperr | notintable
// to phy
output wire [DATA_BYTE_WIDTH*8 - 1:0] phy_data_out,
output wire [DATA_BYTE_WIDTH/2 - 1:0] phy_isk_out // charisk
);
// scrambled data
wire [DATA_BYTE_WIDTH*8 - 1:0] scrambler_out;
wire dec_err; // doc, p.311
// while receiving session shows crc check status
wire crc_good;
wire crc_bad;
// current crc
wire [31:0] crc_dword;
reg data_txing; // if there are still some data to transmit and the transaction wasn't cancelled
always @ (posedge clk)
data_txing <= rst | (data_last_in & data_strobe_out | dword_val & rcvd_dword[CODE_DMATP]) ? 1'b0 : frame_req ? 1'b1 : data_txing;
// send primitives variety count, including CRC and DATA as primitives
localparam PRIM_NUM = 15;
// list of bits of rcvd_dword
wire [PRIM_NUM:0] rcvd_dword; // shows current processing primitive (or just data dword)
wire dword_val;
localparam CODE_DATA = 0;
localparam CODE_CRC = 1;
localparam CODE_SYNCP = 2;
localparam CODE_ALIGNP = 3;
localparam CODE_XRDYP = 4;
localparam CODE_SOFP = 5;
localparam CODE_HOLDAP = 6;
localparam CODE_HOLDP = 7;
localparam CODE_EOFP = 8;
localparam CODE_WTRMP = 9;
localparam CODE_RRDYP = 10;
localparam CODE_IPP = 11;
localparam CODE_DMATP = 12;
localparam CODE_OKP = 13;
localparam CODE_ERRP = 14;
// fsm
// states and transitions are taken from the doc, "Link Layer State Machine" chapter
// power mode states are not implemented. TODO insert them as an additional branch of fsm
// !!!IMPORTANT!!! If add/remove any states, dont forget to change this parameter value
localparam STATES_COUNT = 23;
// idle state
wire state_idle;
reg state_sync_esc; // SyncEscape
reg state_nocommerr; // NoComErr
reg state_nocomm; // NoComm
reg state_align; // SendAlign
reg state_reset; // RESET
// tranmitter branch
reg state_send_rdy; // SendChkRdy
reg state_send_sof; // SendSOF
reg state_send_data; // SendData
reg state_send_rhold; // RcvrHold - hold initiated by current data reciever
reg state_send_shold; // SendHold - hold initiated by current data sender
reg state_send_crc; // SendCVC
reg state_send_eof; // SendEOF
reg state_wait; // Wait
// receiver branch
reg state_rcvr_wait; // RcvWaitFifo
reg state_rcvr_rdy; // RcvChkRdy
reg state_rcvr_data; // RcvData
reg state_rcvr_rhold; // Hold - hold initiated by current data reciever
reg state_rcvr_shold; // RcvHold - hold initiated by current data sender
reg state_rcvr_eof; // RcvEOF
reg state_rcvr_goodcrc; // GoodCRC
reg state_rcvr_goodend; // GoodEnd
reg state_rcvr_badend; // BadEnd
wire set_sync_esc;
wire set_nocommerr;
wire set_nocomm;
wire set_align;
wire set_reset;
wire set_send_rdy;
wire set_send_sof;
wire set_send_data;
wire set_send_rhold;
wire set_send_shold;
wire set_send_crc;
wire set_send_eof;
wire set_wait;
wire set_rcvr_wait;
wire set_rcvr_rdy;
wire set_rcvr_data;
wire set_rcvr_rhold;
wire set_rcvr_shold;
wire set_rcvr_eof;
wire set_rcvr_goodcrc;
wire set_rcvr_goodend;
wire set_rcvr_badend;
wire clr_sync_esc;
wire clr_nocommerr;
wire clr_nocomm;
wire clr_align;
wire clr_reset;
wire clr_send_rdy;
wire clr_send_sof;
wire clr_send_data;
wire clr_send_rhold;
wire clr_send_shold;
wire clr_send_crc;
wire clr_send_eof;
wire clr_wait;
wire clr_rcvr_wait;
wire clr_rcvr_rdy;
wire clr_rcvr_data;
wire clr_rcvr_rhold;
wire clr_rcvr_shold;
wire clr_rcvr_eof;
wire clr_rcvr_goodcrc;
wire clr_rcvr_goodend;
wire clr_rcvr_badend;
assign state_idle = ~state_sync_esc
| ~state_nocommerr
| ~state_nocomm
| ~state_align
| ~state_reset
| ~state_send_rdy
| ~state_send_sof
| ~state_send_data
| ~state_send_rhold
| ~state_send_shold
| ~state_send_crc
| ~state_send_eof
| ~state_wait
| ~state_rcvr_wait
| ~state_rcvr_rdy
| ~state_rcvr_data
| ~state_rcvr_rhold
| ~state_rcvr_shold
| ~state_rcvr_eof
| ~state_rcvr_goodcrc
| ~state_rcvr_goodend
| ~state_rcvr_badend;
// got an escaping primitive = request to cancel the transmission
wire alignes_pair; // pauses every state go give a chance to insert 2 align primitives on a line at least every 256 dwords due to spec
wire alignes_pair_0; // time for 1st align primitive
wire alignes_pair_1; // time for 2nd align primitive
reg [8:0] alignes_timer;
assign alignes_pair_0 = alignes_timer == 9'd252;
assign alignes_pair_1 = alignes_timer == 9'd253;
assign alignes_pair = alignes_pair_0 | alignes_pair_1;
always @ (posedge clk)
alignes_timer <= rst | alignes_pair_1 | state_reset ? 9'h0 : alignes_timer + 1'b1;
wire got_escape;
assign got_escape = dword_val & rcvd_dword[CODE_SYNCP];
// escaping is done
assign sync_escape_ack = state_sync_esc;
// Whole transitions table, literally from doc pages 311-328
assign set_sync_esc = sync_escape_req;
assign set_nocommerr = ~phy_ready & ~state_nocomm & ~state_reset;
assign set_nocomm = state_nocommerr;
assign set_align = state_reset & ~link_reset;
assign set_reset = link_reset;
assign set_send_rdy = state_idle & frame_req;
assign set_send_sof = state_send_rdy & phy_ready & dword_val & rcvd_dword[CODE_RRDYP];
assign set_send_data = state_send_sof & phy_ready
| state_send_rhold & data_txing & ~dec_err & dword_val & ~rcvd_dword[CODE_HOLDP] & ~rcvd_dword[CODE_SYNCP] & ~rcvd_dword[CODE_DMATP]
| state_send_shold & data_txing & data_val_in & dword_val & ~rcvd_dword[CODE_HOLDP] & ~rcvd_dword[CODE_SYNCP];
assign set_send_rhold = state_send_data & data_txing & data_val_in & ~data_last_in & dword_val & rcvd_dword[CODE_HOLDP]
| state_send_shold & data_txing & data_val_in & dword_val & rcvd_dword[CODE_HOLDP];
assign set_send_shold = state_send_data & data_txing & ~data_val_in & dword_val & ~rcvd_dword[CODE_SYNCP];
assign set_send_crc = state_send_data & data_txing & data_val_in & data_last_in & dword_val & ~rcvd_dword[CODE_SYNCP]
| state_send_data & dword_val & rcvd_dword[CODE_DMATP];
assign set_send_eof = state_send_crc & phy_ready & dword_val & ~rcvd_dword[CODE_SYNCP];
assign set_wait = state_send_eof & phy_ready & dword_val & ~rcvd_dword[CODE_SYNCP];
// receiver's branch
assign set_rcvr_wait = state_idle & dword_val & rcvd_dword[CODE_XRDYP]
| state_send_rdy & dword_val & rcvd_dword[CODE_XRDYP];
assign set_rcvr_rdy = state_rcvr_wait & dword_val & rcvd_dword[CODE_XRDYP] & ~data_busy_in;
assign set_rcvr_data = state_rcvr_rdy & dword_val & rcvd_dword[CODE_SOFP]
| state_rcvr_rhold & dword_val & ~rcvd_dword[CODE_HOLDP] & ~rcvd_dword[CODE_EOFP] & ~rcvd_dword[CODE_SYNCP] & ~data_busy_in
| state_rcvr_shold & dword_val & ~rcvd_dword[CODE_HOLDP] & ~rcvd_dword[CODE_EOFP] & ~rcvd_dword[CODE_SYNCP];
assign set_rcvr_rhold = state_rcvr_data & dword_val & rcvd_dword[CODE_DATA] & data_busy_in;
assign set_rcvr_shold = state_rcvr_data & dword_val & rcvd_dword[CODE_HOLDP]
| state_rcvr_rhold & dword_val & rcvd_dword[CODE_HOLDP] & ~data_busy_in;
assign set_rcvr_eof = state_rcvr_data & dword_val & rcvd_dword[CODE_EOFP]
| state_rcvr_rhold & dword_val & rcvd_dword[CODE_EOFP]
| state_rcvr_shold & dword_val & rcvd_dword[CODE_EOFP];
assign set_rcvr_goodcrc = state_rcvr_eof & crc_good;
assign set_rcvr_goodend = state_rcvr_goodcrc& incom_ack_good;
assign set_rcvr_badend = state_rcvr_data & dword_val & rcvd_dword[CODE_WTRMP]
| state_rcvr_eof & crc_bad
| state_rcvr_goodcrc& incom_ack_bad;
assign clr_sync_esc = set_nocommerr | set_reset | dword_val & (rcvd_dword[CODE_RRDYP] | rcvd_dword[CODE_SYNCP]);
assign clr_nocommerr = set_reset | set_nocomm;
assign clr_nocomm = set_reset | set_align;
assign clr_align = set_nocommerr | set_reset | phy_ready;
assign clr_reset = ~link_reset;
assign clr_send_rdy = set_nocommerr | set_reset | set_sync_esc | set_send_sof | set_rcvr_wait;
assign clr_send_sof = set_nocommerr | set_reset | set_sync_esc | set_send_data | got_escape;
assign clr_send_data = set_nocommerr | set_reset | set_sync_esc | set_send_rhold | set_send_shold | set_send_crc | got_escape;
assign clr_send_rhold = set_nocommerr | set_reset | set_sync_esc | set_send_data | set_send_crc | got_escape;
assign clr_send_shold = set_nocommerr | set_reset | set_sync_esc | set_send_data | set_send_rhold | set_send_crc | got_escape;
assign clr_send_crc = set_nocommerr | set_reset | set_sync_esc | set_send_eof | got_escape;
assign clr_send_eof = set_nocommerr | set_reset | set_sync_esc | set_wait | got_escape;
assign clr_wait = set_nocommerr | set_reset | set_sync_esc | frame_done | got_escape;
assign clr_rcvr_wait = set_nocommerr | set_reset | set_sync_esc | set_rcvr_rdy | dword_val & ~rcvd_dword[CODE_RRDYP];
assign clr_rcvr_rdy = set_nocommerr | set_reset | set_sync_esc | set_rcvr_data | dword_val & ~rcvd_dword[CODE_RRDYP] & ~rcvd_dword[CODE_SOFP];
assign clr_rcvr_data = set_nocommerr | set_reset | set_sync_esc | set_rcvr_rhold | set_rcvr_shold | set_rcvr_eof | set_rcvr_badend | got_escape;
assign clr_rcvr_rhold = set_nocommerr | set_reset | set_sync_esc | set_rcvr_data | set_rcvr_eof | set_rcvr_shold | got_escape;
assign clr_rcvr_shold = set_nocommerr | set_reset | set_sync_esc | set_rcvr_data | set_rcvr_eof | got_escape;
assign clr_rcvr_eof = set_nocommerr | set_reset | set_sync_esc | set_rcvr_eof | set_rcvr_goodcrc | set_rcvr_badend;
assign clr_rcvr_goodcrc = set_nocommerr | set_reset | set_sync_esc | set_rcvr_goodend | set_rcvr_badend | set_rcvr_goodcrc | got_escape;
assign clr_rcvr_goodend = set_nocommerr | set_reset | set_sync_esc | got_escape;
assign clr_rcvr_badend = set_nocommerr | set_reset | set_sync_esc | got_escape;
// the only truely asynchronous transaction between states is -> state_ reset. It shall not be delayed by sending alignes
// Luckily, while in that state, the line is off, so we dont need to care about merging alignes and state-bounded primitives
// Others transitions are straightforward
always @ (posedge clk)
begin
state_sync_esc <= (state_sync_esc | set_sync_esc & ~alignes_pair) & ~clr_sync_esc & ~rst;
state_nocommerr <= (state_nocommerr | set_nocommerr & ~alignes_pair) & ~clr_nocommerr & ~rst;
state_nocomm <= (state_nocomm | set_nocomm & ~alignes_pair) & ~clr_nocomm & ~rst;
state_align <= (state_align | set_align & ~alignes_pair) & ~clr_align & ~rst;
state_reset <= (state_reset | set_reset ) & ~clr_reset & ~rst;
state_send_rdy <= (state_send_rdy | set_send_rdy & ~alignes_pair) & ~clr_send_rdy & ~rst;
state_send_sof <= (state_send_sof | set_send_sof & ~alignes_pair) & ~clr_send_sof & ~rst;
state_send_data <= (state_send_data | set_send_data & ~alignes_pair) & ~clr_send_data & ~rst;
state_send_rhold <= (state_send_rhold | set_send_rhold & ~alignes_pair) & ~clr_send_rhold & ~rst;
state_send_shold <= (state_send_shold | set_send_shold & ~alignes_pair) & ~clr_send_shold & ~rst;
state_send_crc <= (state_send_crc | set_send_crc & ~alignes_pair) & ~clr_send_crc & ~rst;
state_send_eof <= (state_send_eof | set_send_eof & ~alignes_pair) & ~clr_send_eof & ~rst;
state_wait <= (state_wait | set_wait & ~alignes_pair) & ~clr_wait & ~rst;
state_rcvr_wait <= (state_rcvr_wait | set_rcvr_wait & ~alignes_pair) & ~clr_rcvr_wait & ~rst;
state_rcvr_rdy <= (state_rcvr_rdy | set_rcvr_rdy & ~alignes_pair) & ~clr_rcvr_rdy & ~rst;
state_rcvr_data <= (state_rcvr_data | set_rcvr_data & ~alignes_pair) & ~clr_rcvr_data & ~rst;
state_rcvr_rhold <= (state_rcvr_rhold | set_rcvr_rhold & ~alignes_pair) & ~clr_rcvr_rhold & ~rst;
state_rcvr_shold <= (state_rcvr_shold | set_rcvr_shold & ~alignes_pair) & ~clr_rcvr_shold & ~rst;
state_rcvr_eof <= (state_rcvr_eof | set_rcvr_eof & ~alignes_pair) & ~clr_rcvr_eof & ~rst;
state_rcvr_goodcrc <= (state_rcvr_goodcrc | set_rcvr_goodcrc & ~alignes_pair) & ~clr_rcvr_goodcrc & ~rst;
state_rcvr_goodend <= (state_rcvr_goodend | set_rcvr_goodend & ~alignes_pair) & ~clr_rcvr_goodend & ~rst;
state_rcvr_badend <= (state_rcvr_badend | set_rcvr_badend & ~alignes_pair) & ~clr_rcvr_badend & ~rst;
end
// flag if incoming request to terminate current transaction came from TL
reg incom_stop_f;
always @ (posedge clk)
incom_stop_f <= rst | incom_done | ~frame_busy ? 1'b0 : incom_stop_req ? 1'b1 : incom_stop_f;
// form data to phy
reg [DATA_BYTE_WIDTH*8 - 1:0] to_phy_data;
reg [DATA_BYTE_WIDTH/2 - 1:0] to_phy_isk;
// TODO implement CONTP
localparam [15:0] PRIM_SYNCP_HI = {3'd5, 5'd21, 3'd5, 5'd21};
localparam [15:0] PRIM_SYNCP_LO = {3'd4, 5'd21, 3'd3, 5'd28};
localparam [15:0] PRIM_ALIGNP_HI = {3'd3, 5'd27, 3'd2, 5'd10};
localparam [15:0] PRIM_ALIGNP_LO = {3'd2, 5'd10, 3'd5, 5'd28};
localparam [15:0] PRIM_XRDYP_HI = {3'd2, 5'd23, 3'd2, 5'd23};
localparam [15:0] PRIM_XRDYP_LO = {3'd5, 5'd21, 3'd3, 5'd28};
localparam [15:0] PRIM_SOFP_HI = {3'd1, 5'd23, 3'd1, 5'd23};
localparam [15:0] PRIM_SOFP_LO = {3'd5, 5'd21, 3'd3, 5'd28};
localparam [15:0] PRIM_HOLDAP_HI = {3'd4, 5'd21, 3'd4, 5'd21};
localparam [15:0] PRIM_HOLDAP_LO = {3'd5, 5'd10, 3'd3, 5'd28};
localparam [15:0] PRIM_HOLDP_HI = {3'd6, 5'd21, 3'd6, 5'd21};
localparam [15:0] PRIM_HOLDP_LO = {3'd5, 5'd10, 3'd3, 5'd28};
localparam [15:0] PRIM_EOFP_HI = {3'd6, 5'd21, 3'd6, 5'd21};
localparam [15:0] PRIM_EOFP_LO = {3'd5, 5'd21, 3'd3, 5'd28};
localparam [15:0] PRIM_WTRMP_HI = {3'd2, 5'd24, 3'd2, 5'd24};
localparam [15:0] PRIM_WTRMP_LO = {3'd5, 5'd21, 3'd3, 5'd28};
localparam [15:0] PRIM_RRDYP_HI = {3'd2, 5'd10, 3'd2, 5'd10};
localparam [15:0] PRIM_RRDYP_LO = {3'd4, 5'd21, 3'd3, 5'd28};
localparam [15:0] PRIM_IPP_HI = {3'd2, 5'd21, 3'd2, 5'd21};
localparam [15:0] PRIM_IPP_LO = {3'd5, 5'd21, 3'd3, 5'd28};
localparam [15:0] PRIM_DMATP_HI = {3'd1, 5'd22, 3'd1, 5'd22};
localparam [15:0] PRIM_DMATP_LO = {3'd5, 5'd21, 3'd3, 5'd28};
localparam [15:0] PRIM_OKP_HI = {3'd1, 5'd21, 3'd1, 5'd21};
localparam [15:0] PRIM_OKP_LO = {3'd5, 5'd21, 3'd3, 5'd28};
localparam [15:0] PRIM_ERRP_HI = {3'd2, 5'd22, 3'd2, 5'd22};
localparam [15:0] PRIM_ERRP_LO = {3'd5, 5'd21, 3'd3, 5'd28};
wire [DATA_BYTE_WIDTH*8 - 1:0] prim_data [PRIM_NUM - 1:0];
// fill all possible output primitives to choose from them after
generate
if (DATA_BYTE_WIDTH == 2)
begin
reg prim_word; // word counter in a primitive TODO logic
assign prim_data[CODE_SYNCP] = prim_word ? PRIM_SYNCP_HI : PRIM_SYNCP_LO;
assign prim_data[CODE_ALIGNP] = prim_word ? PRIM_ALIGNP_HI : PRIM_ALIGNP_LO;
assign prim_data[CODE_XRDYP] = prim_word ? PRIM_XRDYP_HI : PRIM_XRDYP_LO;
assign prim_data[CODE_SOFP] = prim_word ? PRIM_SOFP_HI : PRIM_SOFP_LO;
assign prim_data[CODE_DATA] = scrambler_out;
assign prim_data[CODE_HOLDAP] = prim_word ? PRIM_HOLDAP_HI : PRIM_HOLDAP_LO;
assign prim_data[CODE_HOLDP] = prim_word ? PRIM_HOLDP_HI : PRIM_HOLDP_LO;
assign prim_data[CODE_CRC] = scrambler_out;
assign prim_data[CODE_EOFP] = prim_word ? PRIM_EOFP_HI : PRIM_EOFP_LO;
assign prim_data[CODE_WTRMP] = prim_word ? PRIM_WTRMP_HI : PRIM_WTRMP_LO;
assign prim_data[CODE_RRDYP] = prim_word ? PRIM_RRDYP_HI : PRIM_RRDYP_LO;
assign prim_data[CODE_IPP] = prim_word ? PRIM_IPP_HI : PRIM_IPP_LO;
assign prim_data[CODE_DMATP] = prim_word ? PRIM_DMATP_HI : PRIM_DMATP_LO;
assign prim_data[CODE_OKP] = prim_word ? PRIM_OKP_HI : PRIM_OKP_LO;
assign prim_data[CODE_ERRP] = prim_word ? PRIM_ERRP_HI : PRIM_ERRP_LO;
always @ (posedge clk)
begin
$display("%m: unsupported data width");
$finish;
end
end
else
if (DATA_BYTE_WIDTH == 4)
begin
assign prim_data[CODE_SYNCP] = {PRIM_SYNCP_HI , PRIM_SYNCP_LO};
assign prim_data[CODE_ALIGNP] = {PRIM_ALIGNP_HI , PRIM_ALIGNP_LO};
assign prim_data[CODE_XRDYP] = {PRIM_XRDYP_HI , PRIM_XRDYP_LO};
assign prim_data[CODE_SOFP] = {PRIM_SOFP_HI , PRIM_SOFP_LO};
assign prim_data[CODE_DATA] = scrambler_out;
assign prim_data[CODE_HOLDAP] = {PRIM_HOLDAP_HI , PRIM_HOLDAP_LO};
assign prim_data[CODE_HOLDP] = {PRIM_HOLDP_HI , PRIM_HOLDP_LO};
assign prim_data[CODE_CRC] = scrambler_out;
assign prim_data[CODE_EOFP] = {PRIM_EOFP_HI , PRIM_EOFP_LO};
assign prim_data[CODE_WTRMP] = {PRIM_WTRMP_HI , PRIM_WTRMP_LO};
assign prim_data[CODE_RRDYP] = {PRIM_RRDYP_HI , PRIM_RRDYP_LO};
assign prim_data[CODE_IPP] = {PRIM_IPP_HI , PRIM_IPP_LO};
assign prim_data[CODE_DMATP] = {PRIM_DMATP_HI , PRIM_DMATP_LO};
assign prim_data[CODE_OKP] = {PRIM_OKP_HI , PRIM_OKP_LO};
assign prim_data[CODE_ERRP] = {PRIM_ERRP_HI , PRIM_ERRP_LO};
end
else
begin
always @ (posedge clk)
begin
$display("%m: unsupported data width");
$finish;
end
end
endgenerate
// select which primitive shall be sent
wire [PRIM_NUM - 1:0] select_prim;
assign select_prim[CODE_SYNCP] = ~alignes_pair & (state_idle | state_sync_esc | state_rcvr_wait | state_reset);
assign select_prim[CODE_ALIGNP] = alignes_pair | (state_nocomm | state_nocommerr | state_align);
assign select_prim[CODE_XRDYP] = ~alignes_pair & (state_send_rdy);
assign select_prim[CODE_SOFP] = ~alignes_pair & (state_send_sof);
assign select_prim[CODE_DATA] = ~alignes_pair & (state_send_data & ~set_send_shold); // if there's no data availible for a transmission, fsm still = state_send_data. Need to explicitly count this case.
assign select_prim[CODE_HOLDAP] = ~alignes_pair & (state_send_rhold | state_rcvr_shold & ~incom_stop_f);
assign select_prim[CODE_HOLDP] = ~alignes_pair & (state_send_shold | state_rcvr_rhold | state_send_data & set_send_shold); // the case mentioned 2 lines upper
assign select_prim[CODE_CRC] = ~alignes_pair & (state_send_crc);
assign select_prim[CODE_EOFP] = ~alignes_pair & (state_send_eof);
assign select_prim[CODE_WTRMP] = ~alignes_pair & (state_wait);
assign select_prim[CODE_RRDYP] = ~alignes_pair & (state_rcvr_rdy);
assign select_prim[CODE_IPP] = ~alignes_pair & (state_rcvr_data & ~incom_stop_f | state_rcvr_eof | state_rcvr_goodcrc);
assign select_prim[CODE_DMATP] = ~alignes_pair & (state_rcvr_data & incom_stop_f | state_rcvr_shold & incom_stop_f);
assign select_prim[CODE_OKP] = ~alignes_pair & (state_rcvr_goodend);
assign select_prim[CODE_ERRP] = ~alignes_pair & (state_rcvr_badend);
// primitive selector MUX
always @ (posedge clk)
to_phy_data <= rst ? {DATA_BYTE_WIDTH*8{1'b0}}:
{DATA_BYTE_WIDTH*8{select_prim[CODE_SYNCP]}} & prim_data[CODE_SYNCP] |
{DATA_BYTE_WIDTH*8{select_prim[CODE_ALIGNP]}} & prim_data[CODE_ALIGNP] |
{DATA_BYTE_WIDTH*8{select_prim[CODE_RRDYP]}} & prim_data[CODE_RRDYP] |
{DATA_BYTE_WIDTH*8{select_prim[CODE_SOFP]}} & prim_data[CODE_SOFP] |
{DATA_BYTE_WIDTH*8{select_prim[CODE_HOLDAP]}} & prim_data[CODE_HOLDAP] |
{DATA_BYTE_WIDTH*8{select_prim[CODE_HOLDP]}} & prim_data[CODE_HOLDP] |
{DATA_BYTE_WIDTH*8{select_prim[CODE_EOFP]}} & prim_data[CODE_EOFP] |
{DATA_BYTE_WIDTH*8{select_prim[CODE_WTRMP]}} & prim_data[CODE_WTRMP] |
{DATA_BYTE_WIDTH*8{select_prim[CODE_XRDYP]}} & prim_data[CODE_XRDYP] |
{DATA_BYTE_WIDTH*8{select_prim[CODE_IPP]}} & prim_data[CODE_IPP] |
{DATA_BYTE_WIDTH*8{select_prim[CODE_DMATP]}} & prim_data[CODE_DMATP] |
{DATA_BYTE_WIDTH*8{select_prim[CODE_OKP]}} & prim_data[CODE_OKP] |
{DATA_BYTE_WIDTH*8{select_prim[CODE_ERRP]}} & prim_data[CODE_ERRP] |
{DATA_BYTE_WIDTH*8{select_prim[CODE_CRC]}} & prim_data[CODE_CRC] |
{DATA_BYTE_WIDTH*8{select_prim[CODE_DATA]}} & prim_data[CODE_DATA];
always @ (posedge clk)
to_phy_isk <= rst | ~select_prim[CODE_DATA] & ~select_prim[CODE_CRC] ? {{(DATA_BYTE_WIDTH/2 - 1){1'b0}}, 1'b1} : {DATA_BYTE_WIDTH/2{1'b0}} ;
// incoming data is data
wire inc_is_data;
assign inc_is_data = dword_val & rcvd_dword[CODE_DATA] & (state_rcvr_data | state_rcvr_rhold) & ~alignes_pair;
/*
* Scrambler can work both as a scrambler and a descramler, because data stream could be
* one direction at a time
*/
scrambler scrambler(
.rst (select_prim[CODE_SOFP] | dword_val & rcvd_dword[CODE_SOFP]),
.clk (clk),
.val_in (select_prim[CODE_DATA] | inc_is_data),
.data_in (crc_dword & {DATA_BYTE_WIDTH*8{select_prim[CODE_CRC]}} |
data_in & {DATA_BYTE_WIDTH*8{select_prim[CODE_DATA]}} |
phy_data_in & {DATA_BYTE_WIDTH*8{inc_is_data}}),
.data_out (scrambler_out)
);
/*
* Same as for scrambler, crc computation for both directions
*/
crc crc(
.clk (clk),
.rst (select_prim[CODE_SOFP] | dword_val & rcvd_dword[CODE_SOFP]),
.val_in (select_prim[CODE_DATA] | inc_is_data),
.data_in (data_in & {DATA_BYTE_WIDTH*8{select_prim[CODE_DATA]}} | phy_data_in & {DATA_BYTE_WIDTH*8{inc_is_data}}),
.crc_out (crc_dword)
);
// the output of crc module shall be 0 if 1 tick later reciever got a crc checksum and no errors occured
assign crc_good = ~|crc_dword & state_rcvr_eof;
assign crc_bad = |crc_dword & state_rcvr_eof;
// to TL data outputs assigment
// delay outputs so the last data would be marked
reg [31:0] data_out_r;
reg data_val_out_r;
reg [31:0] data_out_rr;
reg data_val_out_rr;
// if current == EOF => _r == CRC and _rr == last data piece
always @ (posedge clk)
begin
data_out_r <= scrambler_out;
data_out_rr <= data_out_r;
data_val_out_r <= inc_is_data;
data_val_out_rr <= data_val_out_r;
end
assign data_out = data_out_rr;
assign data_mask_out = 2'b11;//{DATA_BYTE_WIDTH/2{1'b1}};
assign data_val_out = data_val_out_rr;
assign data_last_out = set_rcvr_eof;
// from TL data
// gives a strobe everytime data is present and we're at a corresponding state.
assign data_strobe_out = select_prim[CODE_DATA];
// assign phy data outputs
assign phy_data_out = to_phy_data;
assign phy_isk_out = to_phy_isk;
assign frame_busy = ~state_idle;
assign frame_ack = state_send_sof;
assign frame_rej = set_rcvr_wait & state_send_rdy & ~alignes_pair;
// incoming fises detected
assign incom_start = set_rcvr_wait & ~alignes_pair;
// ... and processed
assign incom_done = set_rcvr_goodcrc & ~alignes_pair;
// or the FIS had errors
assign incom_invalidate = state_rcvr_eof & crc_bad & ~alignes_pair | state_rcvr_data & dword_val & rcvd_dword[CODE_WTRMP];
// shows that incoming primitive or data is ready to be processed // TODO somehow move alignes_pair into dword_val
assign dword_val = |rcvd_dword & phy_ready;
// determine imcoming primitive type
assign rcvd_dword[CODE_DATA] = ~|phy_isk_in;
assign rcvd_dword[CODE_CRC] = 1'b0;
assign rcvd_dword[CODE_SYNCP] = phy_isk_in[0] == 1'b1 & ~|phy_isk_in[DATA_BYTE_WIDTH/2-1:1] & prim_data[CODE_SYNCP ] == phy_data_in;
assign rcvd_dword[CODE_ALIGNP] = phy_isk_in[0] == 1'b1 & ~|phy_isk_in[DATA_BYTE_WIDTH/2-1:1] & prim_data[CODE_ALIGNP] == phy_data_in;
assign rcvd_dword[CODE_XRDYP] = phy_isk_in[0] == 1'b1 & ~|phy_isk_in[DATA_BYTE_WIDTH/2-1:1] & prim_data[CODE_XRDYP ] == phy_data_in;
assign rcvd_dword[CODE_SOFP] = phy_isk_in[0] == 1'b1 & ~|phy_isk_in[DATA_BYTE_WIDTH/2-1:1] & prim_data[CODE_SOFP ] == phy_data_in;
assign rcvd_dword[CODE_HOLDAP] = phy_isk_in[0] == 1'b1 & ~|phy_isk_in[DATA_BYTE_WIDTH/2-1:1] & prim_data[CODE_HOLDAP] == phy_data_in;
assign rcvd_dword[CODE_HOLDP] = phy_isk_in[0] == 1'b1 & ~|phy_isk_in[DATA_BYTE_WIDTH/2-1:1] & prim_data[CODE_HOLDP ] == phy_data_in;
assign rcvd_dword[CODE_EOFP] = phy_isk_in[0] == 1'b1 & ~|phy_isk_in[DATA_BYTE_WIDTH/2-1:1] & prim_data[CODE_EOFP ] == phy_data_in;
assign rcvd_dword[CODE_WTRMP] = phy_isk_in[0] == 1'b1 & ~|phy_isk_in[DATA_BYTE_WIDTH/2-1:1] & prim_data[CODE_WTRMP ] == phy_data_in;
assign rcvd_dword[CODE_RRDYP] = phy_isk_in[0] == 1'b1 & ~|phy_isk_in[DATA_BYTE_WIDTH/2-1:1] & prim_data[CODE_RRDYP ] == phy_data_in;
assign rcvd_dword[CODE_IPP] = phy_isk_in[0] == 1'b1 & ~|phy_isk_in[DATA_BYTE_WIDTH/2-1:1] & prim_data[CODE_IPP ] == phy_data_in;
assign rcvd_dword[CODE_DMATP] = phy_isk_in[0] == 1'b1 & ~|phy_isk_in[DATA_BYTE_WIDTH/2-1:1] & prim_data[CODE_DMATP ] == phy_data_in;
assign rcvd_dword[CODE_OKP] = phy_isk_in[0] == 1'b1 & ~|phy_isk_in[DATA_BYTE_WIDTH/2-1:1] & prim_data[CODE_OKP ] == phy_data_in;
assign rcvd_dword[CODE_ERRP] = phy_isk_in[0] == 1'b1 & ~|phy_isk_in[DATA_BYTE_WIDTH/2-1:1] & prim_data[CODE_ERRP ] == phy_data_in;
// phy level errors handling TODO
assign dec_err = |phy_err_in;
// form a response to transport layer
wire frame_done;
assign frame_done = frame_done_good | frame_done_bad;
assign frame_done_good = state_wait & dword_val & rcvd_dword[CODE_OKP];
assign frame_done_bad = state_wait & dword_val & rcvd_dword[CODE_ERRP];
`ifdef CHECKERS_ENABLED
// incoming primitives
always @ (posedge clk)
if (~|rcvd_dword & phy_ready)
begin
$display("%m: invalid primitive recieved : %h, conrol : %h, err : %h", phy_data_in, phy_isk_in, phy_err_in);
$finish;
end
// States checker
reg [STATES_COUNT - 1:0] sim_states_concat;
always @ (posedge clk)
if (~rst)
if ((state_idle
+ state_sync_esc
+ state_nocommerr
+ state_nocomm
+ state_align
+ state_reset
+ state_send_rdy
+ state_send_sof
+ state_send_data
+ state_send_rhold
+ state_send_shold
+ state_send_crc
+ state_send_eof
+ state_wait
+ state_rcvr_wait
+ state_rcvr_rdy
+ state_rcvr_data
+ state_rcvr_rhold
+ state_rcvr_shold
+ state_rcvr_eof
+ state_rcvr_goodcrc
+ state_rcvr_goodend
+ state_rcvr_badend
) != 1)
begin
sim_state_concat = {
state_idle
, state_sync_esc
, state_nocommerr
, state_nocomm
, state_align
, state_reset
, state_send_rdy
, state_send_sof
, state_send_data
, state_send_rhold
, state_send_shold
, state_send_crc
, state_send_eof
, state_wait
, state_rcvr_wait
, state_rcvr_rdy
, state_rcvr_data
, state_rcvr_rhold
, state_rcvr_shold
, state_rcvr_eof
, state_rcvr_goodcrc
, state_rcvr_goodend
, state_rcvr_badend
};
$display("%m: invalid states: %b", sim_state_concat);
$finish;
end
`endif
endmodule
x393_sata-05c77d236b93a06053a6ec2d8ebcad493b999f28/host/oob.v 0000664 0000000 0000000 00000027702 12562737151 0022210 0 ustar 00root root 0000000 0000000 /*******************************************************************************
* Module: oob
* Date: 2015-07-11
* Author: Alexey
* Description: sata oob unit implementation
*
* Copyright (c) 2015 Elphel, Inc.
* oob.v 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, either version 3 of the License, or
* (at your option) any later version.
*
* oob.v file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*******************************************************************************/
/*
* For now both device and host shall be set up to SATA2 speeds.
* Need to think how to change speed grades on fly (either to broaden
* data iface width or to change RXRATE/TXRATE)
*/
// All references to doc = to SerialATA_Revision_2_6_Gold.pdf
module oob #(
parameter DATA_BYTE_WIDTH = 4,
parameter CLK_SPEED_GRADE = 2 // 1 - 75 Mhz, 2 - 150Mhz, 4 - 300Mhz
)
(
// sata clk = usrclk2
input wire clk,
// reset oob
input wire rst,
// oob responces
input wire rxcominitdet_in,
input wire rxcomwakedet_in,
input wire rxelecidle_in,
// oob issues
output wire txcominit,
output wire txcomwake,
output wire txelecidle,
// input data stream (if any data during OOB setting => ignored)
input wire [DATA_BYTE_WIDTH*8 - 1:0] txdata_in,
input wire [DATA_BYTE_WIDTH - 1:0] txcharisk_in,
// output data stream to gtx
output wire [DATA_BYTE_WIDTH*8 - 1:0] txdata_out,
output wire [DATA_BYTE_WIDTH - 1:0] txcharisk_out,
// input data from gtx
input wire [DATA_BYTE_WIDTH*8 - 1:0] rxdata_in,
input wire [DATA_BYTE_WIDTH - 1:0] rxcharisk_in,
// bypassed data from gtx
output wire [DATA_BYTE_WIDTH*8 - 1:0] rxdata_out,
output wire [DATA_BYTE_WIDTH - 1:0] rxcharisk_out,
// oob sequence needs to be issued
input wire oob_start,
// connection established, all further data is valid
output wire oob_done,
// doc p265, link is established after 3back-to-back non-ALIGNp
output wire link_up,
// link goes down - if rxelecidle
output wire link_down,
// the device itself sends cominit
output wire cominit_req,
// allow to respond to cominit
input wire cominit_allow,
// status information to handle by a control block if any exists
// incompatible host-device speed grades (host cannot lock to alignp)
output wire oob_incompatible,
// timeout in an unexpected place
output wire oob_error,
// noone responds to our cominits
output wire oob_silence
`ifdef OOB_MULTISPEED
//TODO
// !!Implement it later on, ref to gen.adjustment fsm in the notebook!!
// speed grade control
,
// current speed grade, dynamic instead of static parameter
input wire [2:0] speed_grade,
// clock to be adjusted to best speed
input wire adj_clk,
// ask for slower protocol clock
output wire speed_down_req,
input wire speed_down_ack,
// reset speedgrade to the fastest one
output wire speed_rst_req,
input wire speed_rst_ack
`endif //OOB_MULTISPEED
);
// 873.8 us error timer
// = 2621400 SATA2 serial ticks (period = 0.000333 us)
// = 131070 ticks @ 150Mhz
// = 65535 ticks @ 75Mhz
localparam [19:0] CLK_TO_TIMER_CONTRIB = CLK_SPEED_GRADE == 1 ? 20'h4 :
CLK_SPEED_GRADE == 2 ? 20'h2 :
CLK_SPEED_GRADE == 4 ? 20'h1 : 20'h1;
localparam [19:0] TIMER_LIMIT = 19'd262140;
reg [19:0] timer;
wire timer_clr;
wire timer_fin;
// latching inputs from gtx
reg rxcominitdet;
reg rxcomwakedet;
reg rxelecidle;
reg [DATA_BYTE_WIDTH*8 - 1:0] rxdata;
reg [DATA_BYTE_WIDTH - 1:0] rxcharisk;
// primitives detection
wire detected_alignp;
wire detected_syncp;
// fsm, doc p265,266
wire state_idle;
reg state_wait_cominit;
reg state_wait_comwake;
reg state_wait_align;
reg state_wait_synp;
reg state_wait_linkup;
reg state_error;
wire set_wait_cominit;
wire set_wait_comwake;
wire set_wait_align;
wire set_wait_synp;
wire set_wait_linkup;
wire set_error;
wire clr_wait_cominit;
wire clr_wait_comwake;
wire clr_wait_align;
wire clr_wait_synp;
wire clr_wait_linkup;
wire clr_error;
assign state_idle = ~state_wait_cominit & ~state_wait_comwake & ~state_wait_align & ~state_wait_synp & ~state_wait_linkup & ~state_error;
always @ (posedge clk)
begin
state_wait_cominit <= (state_wait_cominit | set_wait_cominit) & ~clr_wait_cominit & ~rst;
state_wait_comwake <= (state_wait_comwake | set_wait_comwake) & ~clr_wait_comwake & ~rst;
state_wait_align <= (state_wait_align | set_wait_align ) & ~clr_wait_align & ~rst;
state_wait_synp <= (state_wait_synp | set_wait_synp ) & ~clr_wait_synp & ~rst;
state_wait_linkup <= (state_wait_linkup | set_wait_linkup ) & ~clr_wait_linkup & ~rst;
state_error <= (state_error | set_error ) & ~clr_error & ~rst;
end
assign set_wait_cominit = state_idle & oob_start & ~cominit_req;
assign set_wait_comwake = state_idle & cominit_req & cominit_allow | state_wait_cominit & rxcominitdet;
assign set_wait_align = state_wait_comwake & rxcomwakedet;
assign set_wait_synp = state_wait_align & detected_alignp;
assign set_wait_linkup = state_wait_synp & detected_syncp;
assign set_error = timer_fin & (state_wait_cominit | state_wait_comwake | state_wait_align | state_wait_synp/* | state_wait_linkup*/);
assign clr_wait_cominit = set_wait_comwake | set_error;
assign clr_wait_comwake = set_wait_align | set_error;
assign clr_wait_align = set_wait_synp | set_error;
assign clr_wait_synp = set_wait_linkup | set_error;
assign clr_wait_linkup = state_wait_linkup; //TODO not so important, but still have to trace 3 back-to-back non alignp primitives
assign clr_error = state_error;
// waiting timeout timer
assign timer_fin = timer == TIMER_LIMIT;
assign timer_clr = set_error | state_idle;
always @ (posedge clk)
timer <= rst ? 20'h0 : timer + CLK_TO_TIMER_CONTRIB;
// something is wrong with speed grades if the host cannot lock to device's alignp stream
assign oob_incompatible = state_wait_align & set_error;
// oob sequence is done, everything is okay
assign oob_done = set_wait_linkup;
// noone responds to cominits
assign oob_silence = set_error & state_wait_cominit;
// other timeouts
assign oob_error = set_error & ~oob_silence & ~oob_incompatible;
// set gtx controls
reg txelecidle_r;
always @ (posedge clk)
txelecidle_r <= rst ? 1'b0 : clr_wait_cominit ? 1'b0 : set_wait_cominit ? 1'b1 : txelecidle_r;
assign txcominit = set_wait_cominit;
assign txcomwake = set_wait_comwake;
assign txelecidle = set_wait_cominit | txelecidle_r;
// indicate if link up condition was made
assign link_up = clr_wait_linkup;
// link goes down when line is idle
reg rxelecidle_r;
reg rxelecidle_rr;
always @ (posedge clk)
begin
rxelecidle_rr <= rxelecidle_r;
rxelecidle_r <= rxelecidle;
end
assign link_down = rxelecidle_rr;
// indicate that device is requesting for oob
reg cominit_req_r;
wire cominit_req_set;
assign cominit_req_set = state_idle & rxcominitdet;
always @ (posedge clk)
cominit_req_r <= (cominit_req_r | cominit_req_set) & ~(cominit_allow & cominit_req) & ~rst;
assign cominit_req = cominit_req_set | cominit_req_r;
// detect which primitives sends the device after comwake was done
generate
if (DATA_BYTE_WIDTH == 2)
begin
reg detected_alignp_f;
always @ (posedge clk)
detected_alignp_f <= rst | ~state_wait_align ? 1'b0 :
~|(rxdata ^ {8'b01001010, 8'b10111100}) & ~|(rxcharisk ^ 2'b01); // {D10.2, K28.5}
assign detected_alignp = detected_alignp_f & ~|(rxdata ^ {8'b01111011, 8'b01001010}) & ~|(rxcharisk ^ 2'b00); // {D27.3, D10.2}
reg detected_syncp_f;
always @ (posedge clk)
detected_syncp_f <= rst | ~state_wait_synp ? 1'b0 :
~|(rxdata ^ {8'b10010101, 8'b01111100}) & ~|(rxcharisk ^ 2'b01); // {D21.4, K28.3}
assign detected_syncp = detected_syncp_f & ~|(rxdata ^ {8'b10110101, 8'b10110101}) & ~|(rxcharisk ^ 2'b00); // {D21.5, D21.5}
end
else
if (DATA_BYTE_WIDTH == 4)
begin
assign detected_alignp = ~|(rxdata ^ {8'b01111011, 8'b01001010, 8'b01001010, 8'b10111100}) & ~|(rxcharisk ^ 4'h1); // {D27.3, D10.2, D10.2, K28.5}
assign detected_syncp = ~|(rxdata ^ {8'b10110101, 8'b10110101, 8'b10010101, 8'b01111100}) & ~|(rxcharisk ^ 4'h1); // {D21.5, D21.5, D21.4, K28.3}
end
else
if (DATA_BYTE_WIDTH == 8)
begin
assign detected_alignp = ~|(rxdata ^ {2{8'b01111011, 8'b01001010, 8'b01001010, 8'b10111100}}) & ~|(rxcharisk ^ 8'h11); // {D27.3, D10.2, D10.2, K28.5}
assign detected_syncp = ~|(rxdata ^ {2{8'b10110101, 8'b10110101, 8'b10010101, 8'b01111100}}) & ~|(rxcharisk ^ 8'h11); // {D21.5, D21.5, D21.4, K28.3}
end
else
begin
always @ (posedge clk)
begin
$display("%m oob module works only with 16/32/64 gtx input data width");
$finish;
end
end
endgenerate
// buf inputs from gtx
always @ (posedge clk)
begin
rxcominitdet <= rxcominitdet_in;
rxcomwakedet <= rxcomwakedet_in;
rxelecidle <= rxelecidle_in;
rxdata <= rxdata_in;
rxcharisk <= rxcharisk_in;
end
// set data outputs to upper levels
assign rxdata_out = rxdata;
assign rxcharisk_out = rxcharisk;
// as depicted @ doc, p264, figure 163, have to insert D10.2 and align primitives after
// getting comwake from device
reg [DATA_BYTE_WIDTH*8 - 1:0] txdata;
reg [DATA_BYTE_WIDTH - 1:0] txcharisk;
wire [DATA_BYTE_WIDTH*8 - 1:0] txdata_d102;
wire [DATA_BYTE_WIDTH - 1:0] txcharisk_d102;
wire [DATA_BYTE_WIDTH*8 - 1:0] txdata_align;
wire [DATA_BYTE_WIDTH - 1:0] txcharisk_align;
always @ (posedge clk)
begin
txdata <= state_wait_align ? txdata_d102 :
state_wait_synp ? txdata_align : txdata_in;
txcharisk <= state_wait_align ? txcharisk_d102 :
state_wait_synp ? txcharisk_align : txcharisk_in;
end
// Continious D10.2 primitive
assign txcharisk_d102 = {DATA_BYTE_WIDTH{1'b0}};
assign txdata_d102 = {DATA_BYTE_WIDTH{8'b01001010}};
// Align primitive: K28.5 + D10.2 + D10.2 + D27.3
generate
if (DATA_BYTE_WIDTH == 2)
begin
reg align_odd;
always @ (posedge clk)
align_odd <= rst | ~state_wait_synp ? 1'b0 : ~align_odd;
assign txcharisk_align = align_odd ? 2'b01 : 2'b00;
assign txdata_align = align_odd ? {8'b01001010, 8'b10111100} : // {D10.2, K28.5}
{8'b01111011, 8'b01001010}; // {D27.3, D10.2}
end
else
if (DATA_BYTE_WIDTH == 4)
begin
assign txcharisk_align = 4'h1;
assign txdata_align = {8'b01111011, 8'b01001010, 8'b01001010, 8'b10111100}; // {D27.3, D10.2, D10.2, K28.5}
end
else
if (DATA_BYTE_WIDTH == 8)
begin
assign txcharisk_align = 8'h11;
assign txdata_align = {2{8'b01111011, 8'b01001010, 8'b01001010, 8'b10111100}}; // 2x{D27.3, D10.2, D10.2, K28.5}
end
else
always @ (posedge clk)
begin
$display("%m oob module works only with 16/32/64 gtx input data width");
$finish;
end
endgenerate
// set data outputs to gtx
assign txdata_out = txdata;
assign txcharisk_out = txcharisk;
endmodule
x393_sata-05c77d236b93a06053a6ec2d8ebcad493b999f28/host/oob_ctrl.v 0000664 0000000 0000000 00000013202 12562737151 0023222 0 ustar 00root root 0000000 0000000 /*******************************************************************************
* Module: oob_ctrl
* Date: 2015-07-11
* Author: Alexey
* Description: module to start oob sequences and to handle errors
*
* Copyright (c) 2015 Elphel, Inc.
* oob_ctrl.v 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, either version 3 of the License, or
* (at your option) any later version.
*
* oob_ctrl.v file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*******************************************************************************/
`include "oob.v"
module oob_ctrl #(
parameter DATA_BYTE_WIDTH = 4,
parameter CLK_SPEED_GRADE = 2 // 1 - 75 Mhz, 2 - 150Mhz, 4 - 300Mhz
)
(
// sata clk = usrclk2
input wire clk,
// reset oob
input wire rst,
// gtx is ready = all resets are done
input wire gtx_ready,
// oob responces
input wire rxcominitdet_in,
input wire rxcomwakedet_in,
input wire rxelecidle_in,
// oob issues
output wire txcominit,
output wire txcomwake,
output wire txelecidle,
// input data stream (if any data during OOB setting => ignored)
input wire [DATA_BYTE_WIDTH*8 - 1:0] txdata_in,
input wire [DATA_BYTE_WIDTH - 1:0] txcharisk_in,
// output data stream to gtx
output wire [DATA_BYTE_WIDTH*8 - 1:0] txdata_out,
output wire [DATA_BYTE_WIDTH - 1:0] txcharisk_out,
// input data from gtx
input wire [DATA_BYTE_WIDTH*8 - 1:0] rxdata_in,
input wire [DATA_BYTE_WIDTH - 1:0] rxcharisk_in,
// bypassed data from gtx
output wire [DATA_BYTE_WIDTH*8 - 1:0] rxdata_out,
output wire [DATA_BYTE_WIDTH - 1:0] rxcharisk_out,
// obvious
input wire rxbyteisaligned,
// shows if channel is ready
output wire phy_ready
);
// oob sequence needs to be issued
wire oob_start;
// connection established, all further data is valid
wire oob_done;
// doc p265, link is established after 3back-to-back non-ALIGNp
wire link_up;
wire link_down;
// the device itself sends cominit
wire cominit_req;
// allow to respond to cominit
wire cominit_allow;
// status information to handle by a control block if any exists
// incompatible host-device speed grades (host cannot lock to alignp)
wire oob_incompatible; // TODO
// timeout in an unexpected place
wire oob_error;
// noone responds to our cominits
wire oob_silence;
// for the resync sake
reg rxbyteisaligned_r;
reg rxbyteisaligned_rr;
always @ (posedge clk)
begin
rxbyteisaligned_rr <= rxbyteisaligned_r;
rxbyteisaligned <= rxbyteisaligned;
end
// 1 - link is up and running, 0 - probably not
reg link_state;
// 1 - connection is being established, 0 - is not
reg oob_state;
assign phy_ready = link_state & gtx_ready & rxbyteisaligned_rr;
always @ (posedge clk)
link_state <= (link_state | link_up) & ~link_down & ~rst;
always @ (posedge clk)
oob_state <= (oob_state | oob_start | cominit_req & cominit_allow) & ~oob_error & ~oob_silence & ~link_up & ~rst;
// decide when to issue oob: always when gtx is ready
assign oob_start = gtx_ready & ~oob_state;
// let devices always begin oob sequence, if only it's not a glitch
assign cominit_allow = cominit_req & link_state;
oob #(
.DATA_BYTE_WIDTH (DATA_BYTE_WIDTH),
.CLK_SPEED_GRADE (CLK_SPEED_GRADE)
)
oob
(
// sata clk = usrclk2
.clk (clk),
// reset oob
.rst (rst),
// oob responces
.rxcominitdet_in (rxcominitdet_in),
.rxcomwakedet_in (rxcomwakedet_in),
.rxelecidle_in (rxelecidle_in),
// oob issues
.txcominit (txcominit),
.txcomwake (txcomwake),
.txelecidle (txelecidle),
// input data stream (if any data during OOB setting => ignored)
.txdata_in (txdata_in),
.txcharisk_in (txcharisk_in),
// output data stream to gtx
.txdata_out (txdata_out),
.txcharisk_out (txcharisk_out),
// input data from gtx
.rxdata_in (rxdata_in),
.rxcharisk_in (rxcharisk_in),
// bypassed data from gtx
.rxdata_out (rxdata_out),
.rxcharisk_out (rxcharisk_out),
// oob sequence needs to be issued
.oob_start (oob_start),
// connection established, all further data is valid
.oob_done (oob_done),
// doc p265, link is established after 3back-to-back non-ALIGNp
.link_up (link_up),
.link_down (link_down),
// the device itself sends cominit
.cominit_req (cominit_req),
// allow to respond to cominit
.cominit_allow (cominit_allow),
// status information to handle by a control block if any exists
// incompatible host-device speed grades (host cannot lock to alignp)
.oob_incompatible (oob_incompatible),
// timeout in an unexpected place
.oob_error (oob_error),
// noone responds to our cominits
.oob_silence (oob_silence)
);
endmodule
x393_sata-05c77d236b93a06053a6ec2d8ebcad493b999f28/host/scrambler.v 0000664 0000000 0000000 00000010676 12562737151 0023405 0 ustar 00root root 0000000 0000000 /*******************************************************************************
* Module: scrambler
* Date: 2015-07-11
* Author: Alexey
* Description: a scrambler for the link layer
*
* Copyright (c) 2015 Elphel, Inc.
* scrambler.v 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, either version 3 of the License, or
* (at your option) any later version.
*
* scrambler.v file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*******************************************************************************/
/*
* Algorithm is taken from the doc, p.565. TODO make it parallel
*/
// TODO another widths support
module scrambler #(
parameter DATA_BYTE_WIDTH = 4
)
(
input wire clk,
input wire rst,
input wire val_in,
input wire [DATA_BYTE_WIDTH*8 - 1:0] data_in,
output wire [DATA_BYTE_WIDTH*8 - 1:0] data_out
);
reg [15:0] now;
reg [31:0] next;
always @ (posedge clk)
now <= rst ? 16'hf0f6 : val_in ? next : now;
assign data_out = val_in ? data_in ^ next : data_in;
always @ (*)
/* if (rst)
next = 32'h0;
else*/
begin
next[31] = now[12] ^ now[10] ^ now[7] ^ now[3] ^ now[1] ^ now[0];
next[30] = now[15] ^ now[14] ^ now[12] ^ now[11] ^ now[9] ^ now[6] ^ now[3] ^ now[2] ^ now[0];
next[29] = now[15] ^ now[13] ^ now[12] ^ now[11] ^ now[10] ^ now[8] ^ now[5] ^ now[3] ^ now[2] ^ now[1];
next[28] = now[14] ^ now[12] ^ now[11] ^ now[10] ^ now[9] ^ now[7] ^ now[4] ^ now[2] ^ now[1] ^ now[0];
next[27] = now[15] ^ now[14] ^ now[13] ^ now[12] ^ now[11] ^ now[10] ^ now[9] ^ now[8] ^ now[6] ^ now[1] ^ now[0];
next[26] = now[15] ^ now[13] ^ now[11] ^ now[10] ^ now[9] ^ now[8] ^ now[7] ^ now[5] ^ now[3] ^ now[0];
next[25] = now[15] ^ now[10] ^ now[9] ^ now[8] ^ now[7] ^ now[6] ^ now[4] ^ now[3] ^ now[2];
next[24] = now[14] ^ now[9] ^ now[8] ^ now[7] ^ now[6] ^ now[5] ^ now[3] ^ now[2] ^ now[1];
next[23] = now[13] ^ now[8] ^ now[7] ^ now[6] ^ now[5] ^ now[4] ^ now[2] ^ now[1] ^ now[0];
next[22] = now[15] ^ now[14] ^ now[7] ^ now[6] ^ now[5] ^ now[4] ^ now[1] ^ now[0];
next[21] = now[15] ^ now[13] ^ now[12] ^ now[6] ^ now[5] ^ now[4] ^ now[0];
next[20] = now[15] ^ now[11] ^ now[5] ^ now[4];
next[19] = now[14] ^ now[10] ^ now[4] ^ now[3];
next[18] = now[13] ^ now[9] ^ now[3] ^ now[2];
next[17] = now[12] ^ now[8] ^ now[2] ^ now[1];
next[16] = now[11] ^ now[7] ^ now[1] ^ now[0];
next[15] = now[15] ^ now[14] ^ now[12] ^ now[10] ^ now[6] ^ now[3] ^ now[0];
next[14] = now[15] ^ now[13] ^ now[12] ^ now[11] ^ now[9] ^ now[5] ^ now[3] ^ now[2];
next[13] = now[14] ^ now[12] ^ now[11] ^ now[10] ^ now[8] ^ now[4] ^ now[2] ^ now[1];
next[12] = now[13] ^ now[11] ^ now[10] ^ now[9] ^ now[7] ^ now[3] ^ now[1] ^ now[0];
next[11] = now[15] ^ now[14] ^ now[10] ^ now[9] ^ now[8] ^ now[6] ^ now[3] ^ now[2] ^ now[0];
next[10] = now[15] ^ now[13] ^ now[12] ^ now[9] ^ now[8] ^ now[7] ^ now[5] ^ now[3] ^ now[2] ^ now[1];
next[9] = now[14] ^ now[12] ^ now[11] ^ now[8] ^ now[7] ^ now[6] ^ now[4] ^ now[2] ^ now[1] ^ now[0];
next[8] = now[15] ^ now[14] ^ now[13] ^ now[12] ^ now[11] ^ now[10] ^ now[7] ^ now[6] ^ now[5] ^ now[1] ^ now[0];
next[7] = now[15] ^ now[13] ^ now[11] ^ now[10] ^ now[9] ^ now[6] ^ now[5] ^ now[4] ^ now[3] ^ now[0];
next[6] = now[15] ^ now[10] ^ now[9] ^ now[8] ^ now[5] ^ now[4] ^ now[2];
next[5] = now[14] ^ now[9] ^ now[8] ^ now[7] ^ now[4] ^ now[3] ^ now[1];
next[4] = now[13] ^ now[8] ^ now[7] ^ now[6] ^ now[3] ^ now[2] ^ now[0];
next[3] = now[15] ^ now[14] ^ now[7] ^ now[6] ^ now[5] ^ now[3] ^ now[2] ^ now[1];
next[2] = now[14] ^ now[13] ^ now[6] ^ now[5] ^ now[4] ^ now[2] ^ now[1] ^ now[0];
next[1] = now[15] ^ now[14] ^ now[13] ^ now[5] ^ now[4] ^ now[1] ^ now[0];
next[0] = now[15] ^ now[13] ^ now[4] ^ now[0];
end
endmodule
x393_sata-05c77d236b93a06053a6ec2d8ebcad493b999f28/host/transport.v 0000664 0000000 0000000 00000146570 12562737151 0023472 0 ustar 00root root 0000000 0000000 /*******************************************************************************
* Module: transport
* Date: 2015-07-11
* Author: Alexey
* Description: sata transport layer implementation
*
* Copyright (c) 2015 Elphel, Inc.
* transport.v 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, either version 3 of the License, or
* (at your option) any later version.
*
* transport.v file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*******************************************************************************/
module transport #(
parameter DATA_BYTE_WIDTH = 4
)
(
input wire clk,
input wire rst,
// link layer (LL) control
// issue a frame
output wire frame_req,
// frame started to be transmitted
input wire frame_ack,
// frame issue was rejected because of incoming frame with higher priority
input wire frame_rej,
// LL is not ready to receive a frame request. frame_req shall be low if busy is asserted
input wire frame_busy,
// frame was transmitted w/o probles and successfully received @ a device side
input wire frame_done_good,
// frame was transmitted, but device messages of problems with receiving
input wire frame_done_bad,
// LL reports of an incoming frame transmission. They're always allowed and have the highest priority
input wire incom_start,
// LL reports of a completion of an incoming frame transmission.
input wire incom_done,
// LL reports of errors in current FIS
input wire incom_invalidate, // TODO
// TL analyzes FIS and returnes if FIS makes sense.
output wire incom_ack_good,
// ... and if it doesn't
output wire incom_ack_bad,
// transmission interrupts
// TL demands to brutally cancel current transaction TODO
input wire sync_escape_req,
// acknowlegement of a successful reception TODO
output wire sync_escape_ack,
// TL demands to stop current recieving session TODO
input wire incom_stop_req,
// controls from a command layer (CL)
// FIS type, ordered by CL
input wire [2:0] cmd_type,
// request itself
input wire cmd_val,
// destination port
input wire [3:0] cmd_port,
// if cmd got into processing, busy asserts, when TL is ready to receive a new cmd, busy deasserts
output wire cmd_busy,
// indicates completion of a request
output wire cmd_done_good,
// request is completed, but device wasn't able to receive
output wire cmd_done_bad,
// shadow registers TODO reduce outputs/inputs count. or not
// actual registers are stored in CL
input wire [31:0] sh_data_in,
input wire [15:0] sh_feature_in,
input wire [47:0] sh_lba_in,
input wire [15:0] sh_count_in,
input wire [7:0] sh_command_in,
input wire [7:0] sh_dev_in,
input wire [7:0] sh_control_in,
input wire sh_autoact_in,
input wire sh_inter_in,
input wire sh_dir_in,
input wire [63:0] sh_dma_id_in,
input wire [31:0] sh_buf_off_in,
input wire [32:0] sh_dma_cnt_in,
input wire sh_notif_in,
input wire [31:0] sh_tran_cnt_in,
input wire [3:0] sh_port_in,
// TL decodes register writes and sends corresponding issues to CL
output wire [47:0] sh_lba_out,
output wire [15:0] sh_count_out,
output wire [7:0] sh_command_out,
output wire [7:0] sh_err_out,
output wire [7:0] sh_status_out,
output wire [7:0] sh_estatus_out, // E_Status
output wire [7:0] sh_dev_out,
output wire [3:0] sh_port_out,
output wire sh_inter_out,
output wire sh_dir_out,
output wire [63:0] sh_dma_id_out,
output wire [31:0] sh_dma_off_out,
output wire [31:0] sh_dma_cnt_out,
output wire [15:0] sh_tran_cnt_out, // Transfer Count
output wire sh_notif_out,
output wire sh_autoact_out,
output wire sh_lba_val_out,
output wire sh_count_val_out,
output wire sh_command_val_out,
output wire sh_err_val_out,
output wire sh_status_val_out,
output wire sh_estatus_val_out, // E_Status
output wire sh_dev_val_out,
output wire sh_port_val_out,
output wire sh_inter_val_out,
output wire sh_dir_val_out,
output wire sh_dma_id_val_out,
output wire sh_dma_off_val_out,
output wire sh_dma_cnt_val_out,
output wire sh_tran_cnt_val_out, // Transfer Count
output wire sh_notif_val_out,
output wire sh_autoact_val_out,
// shows if dma activate was received (a pulse)
output wire got_dma_activate,
output wire [3:0] got_dma_activate_port,
// if CL made a mistake in controlling data FIS length
output wire data_limit_exceeded,
// LL data
// data inputs from LL
input wire [DATA_BYTE_WIDTH*8 - 1:0] ll_data_in,
input wire [DATA_BYTE_WIDTH/2 - 1:0] ll_data_mask_in,
input wire ll_data_val_in,
input wire ll_data_last_in,
// transport layer tells if its inner buffer is almost full
output wire ll_data_busy_out,
// data outputs to LL
output wire [DATA_BYTE_WIDTH*8 - 1:0] ll_data_out,
// not implemented yet TODO
output wire [DATA_BYTE_WIDTH*8 - 1:0] ll_data_mask_out,
output wire ll_data_last_out,
output wire ll_data_val_out,
input wire ll_data_strobe_in,
// CL data
// required content is bypassed from ll, other is trimmed
// only content of data FIS, starting from 1st dword. Max burst = 2048 dwords
// data outputs to CL
output wire [DATA_BYTE_WIDTH*8 - 1:0] cl_data_out,
output wire [DATA_BYTE_WIDTH/2 - 1:0] cl_data_mask_out,
output wire cl_data_val_out,
output wire cl_data_last_out,
// transport layer tells if its inner buffer is almost full
input wire cl_data_busy_in,
// data inputs from CL
input wire [DATA_BYTE_WIDTH*8 - 1:0] cl_data_in,
// not implemented yet TODO
input wire [DATA_BYTE_WIDTH/2 - 1:0] cl_data_mask_in,
input wire cl_data_last_in,
input wire cl_data_val_in,
output wire cl_data_strobe_out,
// watchdog timers calls. They shall be handled in TL, but for debug purposes are wired to the upper level
// when eof acknowledgement is not received after sent FIS
output wire watchdog_eof,
// when too many dwords is in current FIS
output wire watchdog_dwords
);
// How much time does device have to response on EOF
parameter [13:0] WATCHDOG_EOF_LIMIT = 14'd1000;
// must have a local reserve copy of shadow registers in case of
// a) received FIS with incorrect length (seems like an error, so no registers shall be written)
// b) incoming transmission overrides outcoming, so we have to latch outcoming values in real shadow registers
// while storing incoming ones in the local copy
reg [47:0] loc_lba;
reg [15:0] loc_count;
reg [7:0] loc_command;
reg [7:0] loc_err;
reg [7:0] loc_status;
reg [7:0] loc_estatus; // E_Status
reg [7:0] loc_dev;
reg [3:0] loc_port;
reg loc_inter;
reg loc_dir;
reg [63:0] loc_dma_id;
reg [31:0] loc_dma_off;
reg [31:0] loc_dma_cnt;
reg [15:0] loc_tran_cnt; // Transfer Count
reg loc_notif;
reg loc_autoact;
// latching cmd inputs
reg [3:0] cmd_port_r;
reg [2:0] cmd_type_r;
always @ (posedge clk)
cmd_type_r <= rst ? 3'h0 : cmd_val ? cmd_type : cmd_type_r;
always @ (posedge clk)
cmd_port_r <= rst ? 4'h0 : cmd_val ? cmd_port : cmd_port_r;
// incomming command type decode, shows which type of FIS shall be issued
localparam [2:0] CMD_TYPE_REG_DEV = 3'h0; // Reg H2D, bit C -> 0
localparam [2:0] CMD_TYPE_REG_CMD = 3'h1; // Reg H2D, bit C -> 1
localparam [2:0] CMD_TYPE_DMA_SETUP = 3'h2;
localparam [2:0] CMD_TYPE_DATA = 3'h3;
localparam [2:0] CMD_TYPE_BIST_ACT = 3'h4;
// asserts after FIS is sent
reg cmd_done_f;
// current header dword
wire [31:0] ll_header_dword;
// current dword shall be header's
wire ll_header_val;
// if last data dword is header's
wire ll_header_last;
// incorrect size or unmatched type of a received FIS
reg bad_fis_received;
// if a FIS has wrong size, make sure it would stop, universal dword counter
reg [13:0] dword_cnt;
// FIS dword size exceeded condition
assign watchdog_dwords = dword_cnt == 14'd2049;
// ask for a receiving termination in case of errors
reg incom_stop_req_timeout;
// dma activate is received when its type met and no errors occurs
assign got_dma_activate = state == STATE_INCOMING & cl_data_last_in & ll_data_val_in & ll_data_in[7:0] == 8'h39;
assign got_dma_activate_port = {4{got_dma_activate}} & ll_data_in[11:8];
// global TL fsm
/*
idle -----> outcoming FIS ----> outcoming ----non-data--> fill dwords -------------------------+
| |if rej | |
| | +-----data--> make header --> bypass data from CL -+
| V |
+-------> incoming FIS -------detect type---non-data--> parse dwords, write sh regs ---------+
| |
+-------------data--> get header ---> bypass data to CL -----> done
*/
localparam STATE_IDLE = 8'h0;
localparam STATE_INCOMING = 8'h1;
localparam STATE_OUTCOMING = 8'h2;
localparam STATE_IN_DATA = 8'h10; // Data FIS from device
localparam STATE_IN_REG_1 = 8'h20; // Register FIS Device to Host: 1st dword
localparam STATE_IN_REG_2 = 8'h21; // Register FIS Device to Host: 2nd dword
localparam STATE_IN_REG_3 = 8'h22; // Register FIS Device to Host: 3rd dword
localparam STATE_IN_REG_4 = 8'h23; // Register FIS Device to Host: 4th dword
localparam STATE_IN_REG_ERR = 8'h24; // Register FIS Device to Host: Error happened
localparam STATE_IN_DMAA_ERR = 8'h30; // DMA Activate: Error Happened
localparam STATE_IN_DMAS_1 = 8'h40; // DMA Setup FIS device to host: 1st dword
localparam STATE_IN_DMAS_2 = 8'h41; // DMA Setup FIS device to host: 2nd dword
localparam STATE_IN_DMAS_3 = 8'h42; // DMA Setup FIS device to host: 3rd dword
localparam STATE_IN_DMAS_4 = 8'h43; // DMA Setup FIS device to host: 4th dword
localparam STATE_IN_DMAS_5 = 8'h44; // DMA Setup FIS device to host: 5th dword
localparam STATE_IN_DMAS_6 = 8'h45; // DMA Setup FIS device to host: 6th dword
localparam STATE_IN_DMAS_ERR = 8'h46; // DMA Setup FIS device to host: Error happened
localparam STATE_IN_BIST_1 = 8'h50; // BIST Activate FIS Device to Host: 1st dword
localparam STATE_IN_BIST_2 = 8'h51; // BIST Activate FIS Device to Host: 2nd dword
localparam STATE_IN_BIST_ERR = 8'h52; // BIST Activate FIS Device to Host: Error happened
localparam STATE_IN_PIOS_1 = 8'h60; // PIO Setup FIS: 1st dword
localparam STATE_IN_PIOS_2 = 8'h61; // PIO Setup FIS: 2nd dword
localparam STATE_IN_PIOS_3 = 8'h62; // PIO Setup FIS: 3rd dword
localparam STATE_IN_PIOS_4 = 8'h63; // PIO Setup FIS: 4th dword
localparam STATE_IN_PIOS_ERR = 8'h64; // PIO Setup FIS: Error happened
localparam STATE_IN_SDB_1 = 8'h70; // Set Device Bits FIS: 1st dword
localparam STATE_IN_SDB_ERR = 8'h70; // Set Device Bits FIS: Error happened
localparam STATE_OUT_DATA_H = 8'h80; // Data FIS from host: header
localparam STATE_OUT_DATA_D = 8'h81; // Data FIS from host: payload
localparam STATE_OUT_REG = 8'h90; // Register FIS Host to Device
localparam STATE_OUT_DMAS = 8'ha0; // DMA Setup FIS Host to Device
localparam STATE_OUT_BIST = 8'hb0; // BIST Activate FIS Host to Device
localparam STATE_OUT_WAIT_RESP = 8'hc0; //
localparam STATE_IN_UNRECOG = 8'hf0; // Unrecognized FIS from Device
reg [7:0] state;
always @ (posedge clk)
if (rst)
begin
state <= STATE_IDLE;
dword_cnt <= 14'h0;
incom_stop_req_timeout <= 1'b0;
bad_fis_received <= 1'b0;
loc_lba <= 48'h0;
loc_count <= 32'h0;
loc_command <= 8'h0;
loc_err <= 8'h0;
loc_status <= 8'h0;
loc_estatus <= 8'h0;
loc_dev <= 8'h0;
loc_port <= 4'h0;
loc_inter <= 1'h0;
loc_dir <= 1'h0;
loc_dma_id <= 64'h0;
loc_dma_off <= 32'h0;
loc_dma_cnt <= 32'h0;
loc_tran_cnt <= 16'h0;
loc_notif <= 1'h0;
loc_autoact <= 1'h0;
end
else
case (state)
STATE_IDLE:
begin
dword_cnt <= 14'h0;
incom_stop_req_timeout <= 1'b0;
bad_fis_received <= 1'b0;
if (frame_req)
state <= STATE_OUTCOMING;
else
if (incom_start | frame_req)
state <= STATE_INCOMING;
else
state <= STATE_IDLE;
loc_lba <= sh_lba_in;
loc_count <= sh_count_in;
loc_command <= sh_command_in;
loc_err <= 8'h0;
loc_status <= 8'h0;
loc_estatus <= 8'h0;
loc_dev <= 8'h0;
loc_port <= sh_port_in;
loc_inter <= sh_inter_in;
loc_dir <= sh_dir_in;
loc_dma_id <= sh_dma_id_in;
loc_dma_off <= sh_buf_off_in;
loc_dma_cnt <= sh_dma_cnt_in;
loc_tran_cnt <= sh_tran_cnt_in;
loc_notif <= sh_notif_in;
loc_autoact <= sh_autoact_in;
end
STATE_INCOMING:
// enter state when we're starting to get a FIS, leave after 1st dword is received
begin
if (ll_data_val_in)
// if 0-th dword came
case (ll_data_in[7:0])
// act depending on packet type
8'h34:
// register
begin
if (~ll_data_last_in)
begin
loc_port <= ll_data_in[11:8];
loc_inter <= ll_data_in[14];
loc_status <= ll_data_in[23:16];
loc_err <= ll_data_in[31:24];
state <= STATE_IN_REG_1;
end
else
// an error state, too little dwords transfered
begin
bad_fis_received <= 1'b1;
state <= STATE_IDLE;
end
end
8'h39:
// DMA Activate
begin
if (~ll_data_last_in)
begin
state <= STATE_IN_DMAA_ERR;
dword_cnt <= 14'h1;
end
else
begin
// got_dma_activate - wire assigment
state <= STATE_IDLE;
end
end
8'h41:
// DMA Setup
begin
if (~ll_data_last_in)
begin
loc_port <= ll_data_in[11:8];
loc_dir <= ll_data_in[13];
loc_inter <= ll_data_in[14];
loc_autoact <= ll_data_in[15];
state <= STATE_IN_DMAS_1;
end
else
// an error state, too little dwords transfered
begin
bad_fis_received <= 1'b1;
state <= STATE_IDLE;
end
end
8'h46:
// Data FIS
begin
if (~ll_data_last_in)
begin
loc_port <= ll_data_in[11:8];
dword_cnt <= 14'h1;
state <= STATE_IN_DATA;
end
else
// an error state, too little dwords transfered
begin
bad_fis_received <= 1'b1;
state <= STATE_IDLE;
end
end
8'h58:
// BIST
begin
// for now skips payload, just controls length TODO
state <= STATE_IN_BIST_1;
end
8'h5f:
// PIO setup
begin
if (~ll_data_last_in)
begin
loc_port <= ll_data_in[11:8];
loc_dir <= ll_data_in[13];
loc_inter <= ll_data_in[14];
loc_status <= ll_data_in[23:16];
loc_err <= ll_data_in[31:24];
state <= STATE_IN_PIOS_1;
end
else
// an error state, too little dwords transfered
begin
bad_fis_received <= 1'b1;
state <= STATE_IDLE;
end
end
8'ha1:
// Set Device Bits
begin
if (~ll_data_last_in)
begin
loc_inter <= ll_data_in[14];
loc_notif <= ll_data_in[15];
loc_status[2:0] <= ll_data_in[19:17];
loc_status[6:4] <= ll_data_in[23:21];
loc_err <= ll_data_in[31:24];
state <= STATE_IN_SDB_1;
end
else
// an error state, too little dwords transfered
begin
bad_fis_received <= 1'b1;
state <= STATE_IDLE;
end
end
default:
// no known FIS type matched
begin
dword_cnt <= 14'h0;
state <= STATE_IN_UNRECOG;
end
endcase
end
STATE_OUTCOMING:
// enter state when we're issuing a FIS, leave when got an ack from ll (FIS started to transmit)
// or if FIS won't start because of incoming transmission. In such case outcoming request parameter shall be latched TODO or not?
begin
dword_cnt <= 14'h0;
state <= frame_rej ? STATE_INCOMING :
frame_ack & cmd_type_r == CMD_TYPE_REG_DEV ? STATE_OUT_REG :
frame_ack & cmd_type_r == CMD_TYPE_REG_CMD ? STATE_OUT_REG :
frame_ack & cmd_type_r == CMD_TYPE_DMA_SETUP ? STATE_OUT_DMAS :
frame_ack & cmd_type_r == CMD_TYPE_DATA ? STATE_OUT_DATA_H :
frame_ack & cmd_type_r == CMD_TYPE_BIST_ACT ? STATE_OUT_BIST :
STATE_OUTCOMING;
end
STATE_IN_DATA:
// receiving data from Data FIS, bypass it into buffer at upper level
begin
if (incom_done)
// EOF received, CRC good
begin
state <= STATE_IDLE;
end
else
if (ll_data_val_in)
begin
if (dword_cnt == 14'd2049)
// if too much data for a data FIS TODO handle this excpetion properly
state <= STATE_IDLE;
else
// continuing receiving data
begin
dword_cnt <= dword_cnt + 1'b1;
state <= STATE_IN_DATA;
end
end
end
STATE_IN_REG_1:
// receiving register FIS, dword by dword
begin
if (ll_data_val_in)
if (ll_data_last_in)
// incorrect frame size
begin
bad_fis_received <= 1'b1;
state <= STATE_IDLE;
end
else
// going to the next dword, parse current one: {Device, LBA High, LBA Mid, LBA Low}
begin
loc_lba[7:0] <= ll_data_in[7:0];
loc_lba[23:16] <= ll_data_in[15:8];
loc_lba[39:32] <= ll_data_in[23:16];
loc_dev[7:0] <= ll_data_in[31:24];
state <= STATE_IN_REG_2;
end
end
STATE_IN_REG_2:
// receiving register FIS, dword by dword
begin
if (ll_data_val_in)
if (ll_data_last_in)
// incorrect frame size
begin
bad_fis_received <= 1'b1;
state <= STATE_IDLE;
end
else
// going to the next dword, parse current one: {Reserved, LBA High (exp), LBA Mid (exp), LBA Low (exp)}
begin
loc_lba[15:8] <= ll_data_in[7:0];
loc_lba[31:24] <= ll_data_in[15:8];
loc_lba[47:40] <= ll_data_in[23:16];
state <= STATE_IN_REG_3;
end
end
STATE_IN_REG_3:
// receiving register FIS, dword by dword
begin
if (ll_data_val_in)
if (ll_data_last_in)
// incorrect frame size
begin
bad_fis_received <= 1'b1;
state <= STATE_IDLE;
end
else
// going to the next dword, parse current one: {Reserved, Reserved, Sector Count (exp), Sector Count}
begin
loc_count[15:0] <= ll_data_in[15:0];
state <= STATE_IN_REG_4;
end
end
STATE_IN_REG_4:
// receiving register FIS, dword by dword
begin
if (ll_data_val_in)
if (ll_data_last_in)
// correct frame size, finishing
begin
state <= STATE_IDLE;
end
else
// incorrect frame size
begin
state <= STATE_IN_REG_ERR;
dword_cnt <= 14'h4;
end
end
STATE_IN_REG_ERR:
// FIS was started as REG, but for some reason it has a size more than needed
// just wait until it's over and assert an error
begin
if (ll_data_val_in)
if (ll_data_last_in)
begin
bad_fis_received <= 1'b1;
state <= STATE_IDLE;
end
else
begin
if (watchdog_dwords)
// if for some reason FIS continue transferring for too long, terminate it
begin
state <= STATE_IDLE;
incom_stop_req_timeout <= 1'b1;
end
else
dword_cnt <= dword_cnt + 1'b1;
end
end
STATE_IN_DMAA_ERR:
// FIS was started as DMA Activate, but for some reason it has a size more than needed
// just wait until it's over and assert an error
begin
if (ll_data_val_in)
if (ll_data_last_in)
begin
bad_fis_received <= 1'b1;
state <= STATE_IDLE;
end
else
begin
if (watchdog_dwords)
// if for some reason FIS continue transferring for too long, terminate it
begin
state <= STATE_IDLE;
incom_stop_req_timeout <= 1'b1;
end
else
dword_cnt <= dword_cnt + 1'b1;
end
end
STATE_IN_DMAS_1:
// receiving DMA Setup FIS, dword by dword
begin
if (ll_data_val_in)
if (ll_data_last_in)
// incorrect frame size
begin
bad_fis_received <= 1'b1;
state <= STATE_IDLE;
end
else
// going to the next dword, parse current one: DMA Buffer Id Low
begin
loc_dma_id[31:0] <= ll_data_in[31:0];
state <= STATE_IN_DMAS_2;
end
end
STATE_IN_DMAS_2:
// receiving DMA Setup FIS, dword by dword
begin
if (ll_data_val_in)
if (ll_data_last_in)
// incorrect frame size
begin
bad_fis_received <= 1'b1;
state <= STATE_IDLE;
end
else
// going to the next dword, parse current one: DMA Buffer Id High
begin
loc_dma_id[63:32] <= ll_data_in[31:0];
state <= STATE_IN_DMAS_3;
end
end
STATE_IN_DMAS_3:
// receiving DMA Setup FIS, dword by dword
begin
if (ll_data_val_in)
if (ll_data_last_in)
// incorrect frame size
begin
bad_fis_received <= 1'b1;
state <= STATE_IDLE;
end
else
// going to the next dword, parse current one: Reserved
begin
state <= STATE_IN_DMAS_4;
end
end
STATE_IN_DMAS_4:
// receiving DMA Setup FIS, dword by dword
begin
if (ll_data_val_in)
if (ll_data_last_in)
// incorrect frame size
begin
bad_fis_received <= 1'b1;
state <= STATE_IDLE;
end
else
// going to the next dword, parse current one: DMA Buffer Offset
begin
loc_dma_off[31:0] <= ll_data_in[31:0];
state <= STATE_IN_DMAS_5;
end
end
STATE_IN_DMAS_5:
// receiving DMA Setup FIS, dword by dword
begin
if (ll_data_val_in)
if (ll_data_last_in)
// incorrect frame size
begin
bad_fis_received <= 1'b1;
state <= STATE_IDLE;
end
else
// going to the next dword, parse current one: DMA Transfer Count
begin
loc_dma_cnt[31:0] <= ll_data_in[31:0];
state <= STATE_IN_DMAS_6;
end
end
STATE_IN_DMAS_6:
// receiving DMA Setup FIS, dword by dword
begin
if (ll_data_val_in)
if (ll_data_last_in)
// correct frame size, finishing, current dword: Reserved
begin
state <= STATE_IDLE;
end
else
// incorrect frame size
begin
state <= STATE_IN_DMAS_ERR;
dword_cnt <= 14'h6;
end
end
STATE_IN_DMAS_ERR:
// FIS was started as DMA Setup, but for some reason it has a size more than needed
// just wait until it's over and assert an error
begin
if (ll_data_val_in)
if (ll_data_last_in)
begin
bad_fis_received <= 1'b1;
state <= STATE_IDLE;
end
else
begin
if (watchdog_dwords)
// if for some reason FIS continue transferring for too long, terminate it
begin
state <= STATE_IDLE;
incom_stop_req_timeout <= 1'b1;
end
else
dword_cnt <= dword_cnt + 1'b1;
end
end
STATE_IN_BIST_1:
// receiving BIST FIS, dword by dword
begin
if (ll_data_val_in)
if (ll_data_last_in)
// incorrect frame size
begin
bad_fis_received <= 1'b1;
state <= STATE_IDLE;
end
else
// going to the next dword, parse current one: TODO
begin
state <= STATE_IN_BIST_2;
end
end
STATE_IN_BIST_2:
// receiving BIST FIS, dword by dword
begin
if (ll_data_val_in)
if (ll_data_last_in)
// correct frame size, finishing, current dword: Reserved
begin
state <= STATE_IDLE;
end
else
// incorrect frame size
begin
state <= STATE_IN_BIST_ERR;
dword_cnt <= 14'h2;
end
end
STATE_IN_BIST_ERR:
// FIS was started as BIST Activate, but for some reason it has a size more than needed
// just wait until it's over and assert an error
begin
if (ll_data_val_in)
if (ll_data_last_in)
begin
bad_fis_received <= 1'b1;
state <= STATE_IDLE;
end
else
begin
if (watchdog_dwords)
// if for some reason FIS continue transferring for too long, terminate it
begin
state <= STATE_IDLE;
incom_stop_req_timeout <= 1'b1;
end
else
dword_cnt <= dword_cnt + 1'b1;
end
end
STATE_IN_PIOS_1:
// receiving PIO Setup FIS, dword by dword
begin
if (ll_data_val_in)
if (ll_data_last_in)
// incorrect frame size
begin
bad_fis_received <= 1'b1;
state <= STATE_IDLE;
end
else
// going to the next dword, parse current one: {Device, LBA High, LBA Mid, LBA Low}
begin
loc_lba[7:0] <= ll_data_in[7:0];
loc_lba[23:16] <= ll_data_in[15:8];
loc_lba[39:32] <= ll_data_in[23:16];
loc_dev <= ll_data_in[31:24];
state <= STATE_IN_PIOS_2;
end
end
STATE_IN_PIOS_2:
// receiving PIO Setup FIS, dword by dword
begin
if (ll_data_val_in)
if (ll_data_last_in)
// incorrect frame size
begin
bad_fis_received <= 1'b1;
state <= STATE_IDLE;
end
else
// going to the next dword, parse current one: {Reserved, LBA High (exp), LBA Mid (exp), LBA Low (exp)}
begin
loc_lba[15:8] <= ll_data_in[7:0];
loc_lba[31:24] <= ll_data_in[15:8];
loc_lba[47:40] <= ll_data_in[23:16];
state <= STATE_IN_PIOS_3;
end
end
STATE_IN_PIOS_3:
// receiving PIOS FIS, dword by dword
begin
if (ll_data_val_in)
if (ll_data_last_in)
// incorrect frame size
begin
bad_fis_received <= 1'b1;
state <= STATE_IDLE;
end
else
// going to the next dword, parse current one: {E_Status, Reserved, Sector Count (exp), Sector Count}
begin
loc_count[15:0] <= ll_data_in[15:0];
loc_estatus <= ll_data_in[31:24];
state <= STATE_IN_PIOS_4;
end
end
STATE_IN_PIOS_4:
// receiving PIO Setup FIS, dword by dword
begin
if (ll_data_val_in)
if (ll_data_last_in)
// correct frame size, finishing, current dword: {Reserved, Transfer Count}
begin
loc_tran_cnt <= ll_data_in[15:0];
state <= STATE_IDLE;
end
else
// incorrect frame size
begin
state <= STATE_IN_BIST_ERR;
dword_cnt <= 14'h4;
end
end
STATE_IN_PIOS_ERR:
// FIS was started as PIO Setup Activate, but for some reason it has a size more than needed
// just wait until it's over and assert an error
begin
if (ll_data_val_in)
if (ll_data_last_in)
begin
bad_fis_received <= 1'b1;
state <= STATE_IDLE;
end
else
begin
if (watchdog_dwords)
// if for some reason FIS continue transferring for too long, terminate it
begin
state <= STATE_IDLE;
incom_stop_req_timeout <= 1'b1;
end
else
dword_cnt <= dword_cnt + 1'b1;
end
end
STATE_IN_SDB_1:
// receiving Set Device Bits FIS, dword by dword
begin
if (ll_data_val_in)
if (ll_data_last_in)
// correct frame size, finishing, current dword: Reserved
begin
state <= STATE_IDLE;
end
else
// incorrect frame size
begin
state <= STATE_IN_SDB_ERR;
dword_cnt <= 14'h1;
end
end
STATE_IN_SDB_ERR:
// FIS was started as Set Device Bits FIS, but for some reason it has a size more than needed
// just wait until it's over and assert an error
begin
if (ll_data_val_in)
if (ll_data_last_in)
begin
bad_fis_received <= 1'b1;
state <= STATE_IDLE;
end
else
begin
if (watchdog_dwords)
// if for some reason FIS continue transferring for too long, terminate it
begin
state <= STATE_IDLE;
incom_stop_req_timeout <= 1'b1;
end
else
dword_cnt <= dword_cnt + 1'b1;
end
end
STATE_OUT_DATA_H:
// Send data FIS header
begin
if (ll_data_strobe_in)
begin
state <= STATE_OUT_DATA_D;
dword_cnt <= 14'h1;
end
end
STATE_OUT_DATA_D:
// Send data FIS data payload
begin
if (ll_data_strobe_in)
begin
if (cl_data_last_in)
begin
// All data is transmitted
dword_cnt <= 14'h0;
state <= STATE_OUT_WAIT_RESP;
end
else
if (dword_cnt == 2048)
// data_limit_exceed - wire assigned
state <= STATE_IDLE;
else
begin
state <= STATE_OUT_DATA_D;
dword_cnt <= dword_cnt + 1'b1;
end
end
end
STATE_OUT_REG:
// Register Host 2 Device FIS
begin
if (ll_data_strobe_in)
// 5 header dwords, then wait for a reception on a device side
if (dword_cnt[2:0] == 3'h4)
begin
dword_cnt <= 14'h0;
state <= STATE_OUT_WAIT_RESP;
end
else
begin
state <= STATE_OUT_REG;
dword_cnt <= dword_cnt + 1'b1;
end
end
STATE_OUT_DMAS:
// DMA Setup outcoming FIS
begin
if (ll_data_strobe_in)
// 7 header dwords, then wait for a reception on a device side
if (dword_cnt[2:0] == 3'h6)
begin
dword_cnt <= 14'h0;
state <= STATE_OUT_WAIT_RESP;
end
else
begin
state <= STATE_OUT_DMAS;
dword_cnt <= dword_cnt + 1'b1;
end
end
STATE_OUT_BIST:
begin
if (ll_data_strobe_in)
// 3 header dwords, then wait for a reception on a device side
if (dword_cnt[2:0] == 3'h2)
begin
dword_cnt <= 14'h0;
state <= STATE_OUT_WAIT_RESP;
end
else
begin
state <= STATE_OUT_BIST;
dword_cnt <= dword_cnt + 1'b1;
end
end
STATE_OUT_WAIT_RESP:
begin
if (frame_done_good)
// cmd_done_good wire assigned
state <= STATE_IDLE;
else
if (frame_done_bad)
// cmd_done_bad wire assigned
state <= STATE_IDLE;
else
if (dword_cnt == WATCHDOG_EOF_LIMIT)
// in here dword_cnt works as a watchdog timer
begin
state <= STATE_IDLE;
// watchdog_eof wire assigned
// for now while debugging let it be indicated on higher level TODO Choose exception. May be send incom stop req.
// Be aware of no response for that. In such case go for rst for ll. Or better make link_reset -> 1. And dont forget for oob
end
else
begin
dword_cnt <= dword_cnt + 1'b1;
state <= STATE_OUT_WAIT_RESP;
end
end
STATE_IN_UNRECOG:
begin
if (incom_done | incom_invalidate)
// transmission complete
// incom_ack_bad wire assigned
state <= STATE_IDLE;
else
if (watchdog_dwords)
begin
state <= STATE_IDLE;
incom_stop_req_timeout <= 1'b1;
end
else
begin
dword_cnt <= dword_cnt + 1'b1;
state <= STATE_IN_UNRECOG;
end
end
default:
begin
end
endcase
// buys circuit
assign cmd_busy = |state | frame_busy;
// respond if received FIS had any meaning in terms of TL
// actual response shall come next tick after done signal to fit LL fsm
reg incom_done_r;
always @ (posedge clk)
incom_done_r <= incom_done;
assign incom_ack_bad = state == STATE_IN_UNRECOG & incom_done_r | bad_fis_received;
assign incom_ack_good = incom_done_r & ~incom_ack_bad;
// after a device says it received the FIS, reveal the error code
assign cmd_done_good = state == STATE_OUT_WAIT_RESP & frame_done_good;
assign cmd_done_bad = state == STATE_OUT_WAIT_RESP & frame_done_bad;
// Reg H2D FIS header
wire [31:0] header_regfis;
assign header_regfis = dword_cnt[2:0] == 3'h0 ? {sh_feature_in[7:0], sh_command_in, cmd_type_r == CMD_TYPE_REG_CMD, 3'h0, cmd_port_r, 8'h27} : // features command C R R R PMPort FISType
dword_cnt[2:0] == 3'h1 ? {sh_dev_in, sh_lba_in[39:32], sh_lba_in[23:16], sh_lba_in[7:0]} : // Device LBAHigh LBAMid LBALow
dword_cnt[2:0] == 3'h2 ? {sh_feature_in[15:8], sh_lba_in[47:40], sh_lba_in[31:24], sh_lba_in[15:8]} : // Features (exp) LBAHigh (exp) LBAMid (exp) LBALow (exp)
dword_cnt[2:0] == 3'h3 ? {sh_control_in[7:0], 8'h00, sh_count_in[15:0]} : // Control Reserved SectorCount (exp) SectorCount
/*dword_cnt[2:0] == 3'h4 ?*/ {32'h0000}; // Reserved
// DMA Setup FIS header
wire [31:0] header_dmas;
assign header_dmas = dword_cnt[3:0] == 3'h0 ? {8'h0, 8'h0, sh_autoact_in, sh_inter_in, sh_dir_in, 1'b0, cmd_port_r, 8'h41} : // Reserved, Reserved, A I D R PMPort, FIS Type
dword_cnt[3:0] == 3'h1 ? {sh_dma_id_in[31:0]} : // DMA Buffer Identifier Low
dword_cnt[3:0] == 3'h2 ? {sh_dma_id_in[63:32]} : // DMA Buffer Identifier High
dword_cnt[3:0] == 3'h4 ? {sh_buf_off_in[31:0]} : // DMA Buffer Offset
dword_cnt[3:0] == 3'h5 ? {sh_tran_cnt_in[31:0]} : // DMA Transfer Count
/* 3'h3 | 3'h6 */ {32'h0000}; // Reserved
// BIST Activate FIS header
wire [31:0] header_bist; // TODO
assign header_bist = dword_cnt[3:0] == 3'h0 ? {8'h00, 8'h00, 4'h0, cmd_port_r, 8'h58} : // Reserved, T A S L F P R V, R R R R PMPort, FIS Type
dword_cnt[3:0] == 3'h1 ? {32'h00000000} : // Data1
dword_cnt[3:0] == 3'h2 ? {32'h00000000} : // Data2
{32'h00000000};
// Data FIS header
wire [31:0] header_data;
assign header_data = {8'h00, 8'h00, 4'h0, cmd_port_r, 8'h46}; // Reserved, Reserved, R R R R PMPort, FIS Type
assign ll_header_val = state == STATE_OUT_REG | state == STATE_OUT_DMAS | state == STATE_OUT_BIST | state == STATE_OUT_DATA_H;
assign ll_header_last = state == STATE_OUT_REG & dword_cnt[2:0] == 3'h4 |
state == STATE_OUT_DMAS & dword_cnt[2:0] == 3'h6 |
state == STATE_OUT_BIST & dword_cnt[2:0] == 3'h2;
assign ll_header_dword = {32{state == STATE_OUT_REG}} & header_regfis |
{32{state == STATE_OUT_DMAS}} & header_dmas |
{32{state == STATE_OUT_BIST}} & header_bist |
{32{state == STATE_OUT_DATA_H}} & header_data;
// bypass data from ll to cl if it's data stage in data FIS
assign cl_data_val_out = ll_data_val_in & state == STATE_IN_DATA;
assign cl_data_last_out = ll_data_val_in & ll_data_last_in & state == STATE_IN_DATA;
assign cl_data_mask_out = ll_data_mask_in;
assign cl_data_out = ll_data_in & {32{cl_data_val_out}};
// set data to ll: bypass payload from cl or headers constructed in here
assign ll_data_val_out = ll_header_val | cl_data_val_in;
assign ll_data_last_out = ll_header_last & ll_header_val | cl_data_last_in & ~ll_header_val;
assign ll_data_out = ll_header_dword & {32{ll_header_val}} | cl_data_in & {32{~ll_header_val}};
assign ll_data_mask_out = {2{ll_header_val}} | cl_data_mask_in & {2{~ll_header_val}};
// limit was 2048 words + 1 headers
assign data_limit_exceeded = dword_cnt == 14'd2048 & ~cl_data_last_in;
// check if no data was obtained from buffer by ll when we're waiting for a response
wire chk_strobe_while_waitresp;
assign chk_strobe_while_waitresp = state == STATE_OUT_WAIT_RESP & ll_data_strobe_in;
// update shadow registers as soon as transaction finishes TODO invalidate in case of errors
// TODO update only corresponding fields, which was updated during the transmission
assign sh_lba_out = loc_lba;
assign sh_count_out = loc_count;
assign sh_command_out = loc_command;
assign sh_err_out = loc_err;
assign sh_status_out = loc_status;
assign sh_estatus_out = loc_estatus;
assign sh_dev_out = loc_dev;
assign sh_port_out = loc_port;
assign sh_inter_out = loc_inter;
assign sh_dir_out = loc_dir;
assign sh_dma_id_out = loc_dma_id;
assign sh_dma_off_out = loc_dma_off;
assign sh_dma_cnt_out = loc_dma_cnt;
assign sh_tran_cnt_out = loc_tran_cnt;
assign sh_notif_out = loc_notif;
assign sh_autoact_out = loc_autoact;
assign sh_lba_val_out = ll_data_last_in;
assign sh_count_val_out = ll_data_last_in;
assign sh_command_val_out = ll_data_last_in;
assign sh_err_val_out = ll_data_last_in;
assign sh_status_val_out = ll_data_last_in;
assign sh_estatus_val_out = ll_data_last_in;
assign sh_dev_val_out = ll_data_last_in;
assign sh_port_val_out = ll_data_last_in;
assign sh_inter_val_out = ll_data_last_in;
assign sh_dir_val_out = ll_data_last_in;
assign sh_dma_id_val_out = ll_data_last_in;
assign sh_dma_off_val_out = ll_data_last_in;
assign sh_dma_cnt_val_out = ll_data_last_in;
assign sh_tran_cnt_val_out = ll_data_last_in;
assign sh_notif_val_out = ll_data_last_in;
assign sh_autoact_val_out = ll_data_last_in;
`ifdef CHECKERS_ENABLED
always @ (posedge clk)
if (~rst)
if (chk_strobe_while_waitresp)
begin
$display("ERROR in %m: retrieving data while being in a STATE_OUT_WAIT_RESP state");
$finish;
end
`endif
// eof response watchdog
assign watchdog_eof = dword_cnt == WATCHDOG_EOF_LIMIT & state == STATE_OUT_WAIT_RESP;
`ifdef CHECKERS_ENABLED
always @ (posedge clk)
if (~rst)
if (watchgod_eof)
begin
$display("WARNING in %m: watchdog_eof asserted");
$stop;
end
`endif
`ifdef CHECKERS_ENABLED
always @ (posedge clk)
if (~rst)
if (watchdog_dwords)
begin
$display("ERROR in %m: state %h - current FIS contains more than 2048 dwords", state);
$finish;
end
`endif
wire chk_inc_dword_limit_exceeded;
assign chk_inc_dword_limit_exceeded = state == STATE_IN_DATA & dword_cnt == 14'd2049;
`ifdef CHECKERS_ENABLED
always @ (posedge clk)
if (~rst)
if (chk_inc_dword_limit_exceeded)
begin
$display("ERROR in %m: received more than 2048 words in one FIS");
$finish;
end
`endif
endmodule
x393_sata-05c77d236b93a06053a6ec2d8ebcad493b999f28/host/verilog/ 0000775 0000000 0000000 00000000000 12562737151 0022701 5 ustar 00root root 0000000 0000000 x393_sata-05c77d236b93a06053a6ec2d8ebcad493b999f28/host/verilog/mux_21.v 0000664 0000000 0000000 00000002357 12562737151 0024212 0 ustar 00root root 0000000 0000000 //--------------------------------------------------------------------------------
// Entity mux_21
// Version: 1.0
// Author: Ashwin Mendon
// Description: 2 bit 2:1 Multiplexer
//--------------------------------------------------------------------------------
// Copyright (C) 2012
// Ashwin A. Mendon
//
// This file is part of SATA2 core.
//
// 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; either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see .
module mux_21
(
input wire [1:0] a,
input wire [1:0] b,
input wire sel,
output reg [1:0] o
);
always @ (a or b or sel)
begin
case (sel)
1'b0:
o = a;
1'b1:
o = b;
endcase
end
endmodule
x393_sata-05c77d236b93a06053a6ec2d8ebcad493b999f28/host/verilog/mux_41.v 0000664 0000000 0000000 00000002573 12562737151 0024214 0 ustar 00root root 0000000 0000000 //--------------------------------------------------------------------------------
// Entity mux_21
// Version: 1.0
// Author: Ashwin Mendon
// Description: 32 bit 4:1 Multiplexer
//--------------------------------------------------------------------------------
// Copyright (C) 2012
// Ashwin A. Mendon
//
// This file is part of SATA2 core.
//
// 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; either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see .
module mux_41
(
input wire [31:0] a,
input wire [31:0] b,
input wire [31:0] c,
input wire [31:0] d,
input wire [1:0] sel,
output reg [31:0] o
);
always @ (a or b or c or d or sel)
begin
case (sel)
2'b00:
o = a;
2'b01:
o = b;
2'b10:
o = c;
2'b11:
o = d;
endcase
end
endmodule
x393_sata-05c77d236b93a06053a6ec2d8ebcad493b999f28/host/verilog/oob_control.v 0000664 0000000 0000000 00000033100 12562737151 0025404 0 ustar 00root root 0000000 0000000 //*****************************************************************************/
// Module : OOB_control
// Version: 1.0
// Author: Ashwin Mendon
// Description: This module handles the Out-Of-Band (OOB) sinaling requirements
// for link initialization and synchronization
// It has been modified from Xilinx XAPP870 to support Virtex 6 GTX
// transceivers
//*****************************************************************************/
module OOB_control (
clk, // Clock
reset, // reset
oob_control_ila_control,
/**** GTX ****/
rxreset, // GTX PCS reset
rx_locked, // GTX PLL is locked
gen2, // Generation 2 speed
txcominit, // TX OOB issue RESET/INIT
txcomwake, // TX OOB issue WAKE
cominitdet, // RX OOB detect INIT
comwakedet, // RX OOB detect WAKE
rxelecidle, // RX electrical idle
txelecidle_out,// TX electircal idel
rxbyteisaligned,// RX byte alignment completed
tx_dataout, // Outgoing TX data to GTX
tx_charisk_out,// TX byted is K character
rx_datain, // Data from GTX
rx_charisk_in, // K character from GTX
/**** GTX ****/
/**** LINK LAYER ****/
// INPUT
tx_datain, // Incoming TX data from SATA Link Layer
tx_charisk_in, // K character indicator
// OUTPUT
rx_dataout, // Data to SATA Link Layer
rx_charisk_out,
linkup, // SATA link is established
linkup_led_out, // LINKUP LED output
align_en_out,
CurrentState_out // Current state for Chipscope
/**** LINK LAYER ****/
);
parameter CHIPSCOPE = "FALSE";
input clk;
input reset;
input [35:0] oob_control_ila_control;
input rx_locked;
input gen2;
// Added for GTX
input cominitdet;
input comwakedet;
// Added for GTX
input rxelecidle;
input rxbyteisaligned;
input [31:0] tx_datain;
input tx_charisk_in;
input [3:0] rx_charisk_in;
input [31:0] rx_datain; //changed for GTX
output rxreset;
// Added for GTX
output txcominit;
output txcomwake;
// Added for GTX
output txelecidle_out;
output [31:0] tx_dataout; //changed for GTX
output tx_charisk_out;
output [31:0] rx_dataout;
output [3:0] rx_charisk_out;
output linkup;
output linkup_led_out;
output align_en_out;
output [7:0] CurrentState_out;
parameter [3:0]
host_comreset = 8'h00,
wait_dev_cominit = 8'h01,
host_comwake = 8'h02,
wait_dev_comwake = 8'h03,
wait_after_comwake = 8'h04,
wait_after_comwake1 = 8'h05,
host_d10_2 = 8'h06,
host_send_align = 8'h07,
link_ready = 8'h08,
link_idle = 8'h09;
// Primitves
parameter ALIGN = 4'b00;
parameter SYNC = 4'b01;
parameter DIAL = 4'b10;
//parameter R_RDY = 4'b11;
parameter LINK_LAYER = 4'b11;
reg [7:0] CurrentState, NextState;
reg [17:0] count;
reg [3:0] align_char_cnt_reg;
reg align_char_cnt_rst, align_char_cnt_inc;
reg count_en;
reg tx_charisk, tx_charisk_next;
reg txelecidle, txelecidle_next;
reg linkup_r, linkup_r_next;
reg rxreset;
reg [31:0] tx_datain_r;
wire [31:0] tx_dataout_i;
reg [31:0] rx_dataout_i;
wire [31:0] tx_align, tx_sync, tx_dial, tx_r_rdy;
reg [3:0] rx_charisk_r;
reg txcominit_r, txcomwake_r;
wire [1:0] align_count_mux_out;
reg [8:0] align_count;
reg [1:0] prim_type, prim_type_next;
wire align_det, sync_det, cont_det, sof_det, eof_det, x_rdy_det, r_err_det, r_ok_det;
reg align_en, align_en_r;
reg rxelecidle_r;
reg [31:0] rx_datain_r;
reg [3:0] rx_charisk_in_r;
reg rxbyteisaligned_r;
reg comwakedet_r, cominitdet_r;
// OOB FSM Logic Process
always @ ( CurrentState or count or rxelecidle_r or rx_locked or rx_datain_r or
cominitdet_r or comwakedet_r or
align_det or sync_det or cont_det or
tx_charisk_in )
begin : Comb_FSM
count_en = 1'b0;
NextState = host_comreset;
linkup_r_next = linkup_r;
txcominit_r =1'b0;
txcomwake_r = 1'b0;
rxreset = 1'b0;
txelecidle_next = txelecidle;
prim_type_next = prim_type;
tx_charisk_next = tx_charisk;
rx_dataout_i = 32'b0;
rx_charisk_r = 4'b0;
case (CurrentState)
host_comreset :
begin
txelecidle_next = 1'b1;
prim_type_next = ALIGN;
if (rx_locked)
begin
if ((~gen2 && count == 18'h00051) || (gen2 && count == 18'h000A2))
begin
txcominit_r =1'b0;
NextState = wait_dev_cominit;
end
else //Issue COMRESET
begin
txcominit_r =1'b1;
count_en = 1'b1;
NextState = host_comreset;
end
end
else
begin
txcominit_r =1'b0;
NextState = host_comreset;
end
end
wait_dev_cominit : //1
begin
if (cominitdet_r == 1'b1) //device cominit detected
begin
NextState = host_comwake;
end
else
begin
`ifdef SIM
if(count == 18'h001ff)
`else
if(count == 18'h203AD) //restart comreset after no cominit for at least 880us
`endif
begin
count_en = 1'b0;
NextState = host_comreset;
end
else
begin
count_en = 1'b1;
NextState = wait_dev_cominit;
end
end
end
host_comwake : //2
begin
if ((~gen2 && count == 18'h0004E) || (gen2 && count == 18'h0009B))
begin
txcomwake_r =1'b0;
NextState = wait_dev_comwake;
end
else
begin
txcomwake_r =1'b1;
count_en = 1'b1;
NextState = host_comwake;
end
end
wait_dev_comwake : //3
begin
if (comwakedet_r == 1'b1) //device comwake detected
begin
NextState = wait_after_comwake;
end
else
begin
if(count == 18'h203AD) //restart comreset after no cominit for 880us
begin
count_en = 1'b0;
NextState = host_comreset;
end
else
begin
count_en = 1'b1;
NextState = wait_dev_comwake;
end
end
end
wait_after_comwake : // 4
begin
if (count == 6'h3F)
begin
NextState = wait_after_comwake1;
end
else
begin
count_en = 1'b1;
NextState = wait_after_comwake;
end
end
wait_after_comwake1 : //5
begin
if (rxelecidle_r == 1'b0)
begin
rxreset = 1'b1;
NextState = host_d10_2;
end
else
NextState = wait_after_comwake1;
end
host_d10_2 : //6
begin
txelecidle_next = 1'b0;
// D10.2-D10.2 "dial tone"
rx_dataout_i = rx_datain_r;
prim_type_next = DIAL;
tx_charisk_next = 1'b0;
if (align_det)
begin
NextState = host_send_align;
end
else
begin
if(count == 18'h203AD) // restart comreset after 880us
begin
count_en = 1'b0;
NextState = host_comreset;
end
else
begin
count_en = 1'b1;
NextState = host_d10_2;
end
end
end
host_send_align : //7
begin
rx_dataout_i = rx_datain_r;
// Send Align primitives. Align is
// K28.5, D10.2, D10.2, D27.3
prim_type_next = ALIGN;
tx_charisk_next = 1'b1;
if (sync_det) // SYNC detected
begin
linkup_r_next = 1'b1;
NextState = link_ready;
end
else
NextState = host_send_align;
end
link_ready : // 8
begin
if (rxelecidle_r == 1'b1)
begin
NextState = link_ready;
linkup_r_next = 1'b0;
end
else
begin
NextState = link_ready;
linkup_r_next = 1'b1;
rx_charisk_r = rx_charisk_in_r;
rx_dataout_i = rx_datain_r;
// Send LINK_LAYER DATA
prim_type_next = LINK_LAYER;
if (align_en)
tx_charisk_next = 1'b1;
else
tx_charisk_next = tx_charisk_in;
end
end
default : NextState = host_comreset;
endcase
end
// OOB FSM Synchronous Process
always@(posedge clk or posedge reset)
begin : Seq_FSM
if (reset)
begin
CurrentState <= host_comreset;
prim_type <= ALIGN;
tx_charisk <= 1'b0;
txelecidle <= 1'b1;
linkup_r <= 1'b0;
align_en_r <= 1'b0;
rxelecidle_r <= 1'b0;
rx_datain_r <= 32'b0;
rx_charisk_in_r <= 4'b0;
rxbyteisaligned_r <= 1'b0;
cominitdet_r <= 1'b0;
comwakedet_r <= 1'b0;
end
else
begin
CurrentState <= NextState;
prim_type <= prim_type_next;
tx_charisk <= tx_charisk_next;
txelecidle <= txelecidle_next;
linkup_r <= linkup_r_next;
align_en_r <= align_en;
rxelecidle_r <= rxelecidle;
rx_datain_r <= rx_datain;
rx_charisk_in_r <= rx_charisk_in;
rxbyteisaligned_r <= rxbyteisaligned;
cominitdet_r <= cominitdet;
comwakedet_r <= comwakedet;
end
end
always@(posedge clk or posedge reset)
begin : freecount
if (reset)
begin
count <= 18'b0;
end
else if (count_en)
begin
count <= count + 1;
end
else
begin
count <= 18'b0;
end
end
assign txcominit = txcominit_r;
assign txcomwake = txcomwake_r;
assign txelecidle_out = txelecidle;
//Primitive detection
// Changed for 32-bit GTX
assign align_det = (rx_datain_r == 32'h7B4A4ABC) && (rxbyteisaligned_r == 1'b1); //prevent invalid align at wrong speed
assign sync_det = (rx_datain_r == 32'hB5B5957C);
assign cont_det = (rx_datain_r == 32'h9999AA7C);
assign sof_det = (rx_datain_r == 32'h3737B57C);
assign eof_det = (rx_datain_r == 32'hD5D5B57C);
assign x_rdy_det = (rx_datain_r == 32'h5757B57C);
assign r_err_det = (rx_datain_r == 32'h5656B57C);
assign r_ok_det = (rx_datain_r == 32'h3535B57C);
assign linkup = linkup_r;
assign linkup_led_out = ((CurrentState == link_ready) && (rxelecidle_r == 1'b0)) ? 1'b1 : 1'b0;
assign CurrentState_out = CurrentState;
assign rx_charisk_out = rx_charisk_r;
assign tx_charisk_out = tx_charisk;
assign rx_dataout = rx_dataout_i;
// SATA Primitives
// ALIGN
assign tx_align = 32'h7B4A4ABC;
// SYNC
assign tx_sync = 32'hB5B5957C;
// Dial Tone
assign tx_dial = 32'h4A4A4A4A;
// R_RDY
assign tx_r_rdy = 32'h4A4A957C;
// Mux to switch between ALIGN and other primitives/data
mux_21 i_align_count
(
.a (prim_type),
.b (ALIGN),
.sel (align_en_r),
.o (align_count_mux_out)
);
// Output to Link Layer to Pause writing data frame
assign align_en_out = align_en;
//ALIGN Primitives transmitted every 256 DWORDS for speed alignment
always@(posedge clk or posedge reset)
begin : align_cnt
if (reset)
begin
align_count <= 9'b0;
end
else if (align_count < 9'h0FF) //255
begin
if (align_count == 9'h001) //de-assert after 2 ALIGN primitives
begin
align_en <= 1'b0;
end
align_count <= align_count + 1;
end
else
begin
align_count <= 9'b0;
align_en <= 1'b1;
end
end
//OUTPUT MUX
mux_41 i_tx_out
(
.a (tx_align),
.b (tx_sync),
.c (tx_dial),
//.d (tx_r_rdy),
.d (tx_datain),
.sel (align_count_mux_out),
.o (tx_dataout_i)
);
assign tx_dataout = tx_dataout_i;
// OOB ILA
wire [15:0] trig0;
wire [15:0] trig1;
wire [15:0] trig2;
wire [15:0] trig3;
wire [31:0] trig4;
wire [3:0] trig5;
wire [31:0] trig6;
wire [31:0] trig7;
wire [35:0] control;
/*
if (CHIPSCOPE == "TRUE") begin
oob_control_ila i_oob_control_ila
(
.control(oob_control_ila_control),
.clk(clk),
.trig0(trig0),
.trig1(trig1),
.trig2(trig2),
.trig3(trig3),
.trig4(trig4),
.trig5(trig5),
.trig6(trig6),
.trig7(trig7)
);
end
*/
assign trig0[0] = txcomwake_r;
assign trig0[1] = tx_charisk;
assign trig0[2] = rxbyteisaligned_r;
assign trig0[3] = count_en;
assign trig0[4] = tx_charisk_in;
assign trig0[5] = txelecidle;
assign trig0[6] = rx_locked;
assign trig0[7] = gen2;
assign trig0[11:8] = rx_charisk_in_r;
assign trig0[15:12] = 4'b0;
assign trig1[15:12] = prim_type;
assign trig1[11:10] = 2'b0;
assign trig1[9] = align_en_r;
assign trig1[8] = rxelecidle_r;
assign trig1[7:0] = CurrentState_out;
assign trig2[15:7] = align_count;
assign trig2[6:5] = 2'b0;
assign trig2[4] = cominitdet_r;
assign trig2[3] = comwakedet_r;
assign trig2[2] = align_det;
assign trig2[1] = sync_det;
assign trig2[0] = cont_det;
assign trig3[0] = sof_det;
assign trig3[1] = eof_det;
assign trig3[2] = x_rdy_det;
assign trig3[3] = r_err_det;
assign trig3[4] = r_ok_det;
assign trig3[15:5] = 11'b0;
assign trig4 = rx_datain_r;
assign trig5[0] = txcominit_r;
assign trig5[1] = linkup_r;
assign trig5[2] = align_en;
assign trig5[3] = 1'b0;
assign trig6 = tx_datain;
assign trig7 = tx_dataout_i;
endmodule
module oob_control_ila
(
control,
clk,
trig0,
trig1,
trig2,
trig3,
trig4,
trig5,
trig6,
trig7
);
input [35:0] control;
input clk;
input [15:0] trig0;
input [15:0] trig1;
input [15:0] trig2;
input [15:0] trig3;
input [31:0] trig4;
input [3:0] trig5;
input [31:0] trig6;
input [31:0] trig7;
endmodule
x393_sata-05c77d236b93a06053a6ec2d8ebcad493b999f28/host/vhdl/ 0000775 0000000 0000000 00000000000 12562737151 0022167 5 ustar 00root root 0000000 0000000 x393_sata-05c77d236b93a06053a6ec2d8ebcad493b999f28/host/vhdl/command_layer.vhd 0000664 0000000 0000000 00000050417 12562737151 0025513 0 ustar 00root root 0000000 0000000 -- Copyright (C) 2012
-- Ashwin A. Mendon
--
-- This file is part of SATA2 core.
--
-- 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; either version 3 of the License, or
-- (at your option) any later version.
--
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-- GNU General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with this program. If not, see .
----------------------------------------------------------------------------------------
-- ENTITY: command_layer
-- Version: 1.0
-- Author: Ashwin Mendon
-- Description: This sub-module implements the Command Layer of the SATA Protocol
-- The User Command parameters such as: cmd_type, sector_address, sector_count
-- are encoded into a command FIS according to the ATA format and passed to
-- the Transport Layer.
--
-- PORTS:
-----------------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.STD_LOGIC_ARITH.all;
use IEEE.STD_LOGIC_UNSIGNED.all;
entity command_layer is
generic(
CHIPSCOPE : boolean := false
);
port(
-- Clock and Reset Signals
clk : in std_logic;
sw_reset : in std_logic;
-- ChipScope ILA / Trigger Signals
cmd_layer_ila_control : in std_logic_vector(35 downto 0);
---------------------------------------
-- Signals from/to User Logic
new_cmd : in std_logic;
cmd_done : out std_logic;
cmd_type : in std_logic_vector(1 downto 0);
sector_count : in std_logic_vector(31 downto 0);
sector_addr : in std_logic_vector(31 downto 0);
user_din : in std_logic_vector(31 downto 0);
user_din_re_out : out std_logic;
user_dout : out std_logic_vector(31 downto 0);
user_dout_re : in std_logic;
user_fifo_empty : in std_logic;
user_fifo_full : in std_logic;
sector_timer_out : out std_logic_vector(31 downto 0);
-- Signals from/to Link Layer
write_fifo_full : in std_logic;
ll_ready_for_cmd : in std_logic;
ll_cmd_start : out std_logic;
ll_cmd_type : out std_logic_vector(1 downto 0);
ll_dout : out std_logic_vector(31 downto 0);
ll_dout_we : out std_logic;
ll_din : in std_logic_vector(31 downto 0);
ll_din_re : out std_logic
);
end command_layer;
-------------------------------------------------------------------------------
-- ARCHITECTURE
-------------------------------------------------------------------------------
architecture BEHAV of command_layer is
-------------------------------------------------------------------------------
-- COMMAND LAYER
-------------------------------------------------------------------------------
constant READ_DMA : std_logic_vector(7 downto 0) := x"25";
constant WRITE_DMA : std_logic_vector(7 downto 0) := x"35";
constant REG_FIS_VALUE : std_logic_vector(7 downto 0) := x"27";
constant DATA_FIS_VALUE : std_logic_vector(7 downto 0) := x"46";
constant DEVICE_REG : std_logic_vector(7 downto 0) := x"E0";
constant FEATURES : std_logic_vector(7 downto 0) := x"00";
constant READ_DMA_CMD : std_logic_vector(1 downto 0) := "01";
constant WRITE_DMA_CMD : std_logic_vector(1 downto 0) := "10";
constant DATA_FIS_HEADER : std_logic_vector(31 downto 0) := x"00000046";
constant NDWORDS_PER_DATA_FIS : std_logic_vector(15 downto 0) := conv_std_logic_vector(2048, 16);--128*16
constant SECTOR_NDWORDS : integer := 128; -- 128 DWORDS / 512 Byte Sector
component cmd_layer_ila
port (
control : in std_logic_vector(35 downto 0);
clk : in std_logic;
trig0 : in std_logic_vector(3 downto 0);
trig1 : in std_logic_vector(31 downto 0);
trig2 : in std_logic_vector(31 downto 0);
trig3 : in std_logic_vector(31 downto 0);
trig4 : in std_logic_vector(31 downto 0);
trig5 : in std_logic_vector(1 downto 0);
trig6 : in std_logic_vector(1 downto 0);
trig7 : in std_logic_vector(31 downto 0);
trig8 : in std_logic_vector(31 downto 0);
trig9 : in std_logic_vector(23 downto 0);
trig10 : in std_logic_vector(15 downto 0);
trig11 : in std_logic_vector(11 downto 0);
trig12 : in std_logic_vector(15 downto 0);
trig13 : in std_logic_vector(31 downto 0)
);
end component;
-----------------------------------------------------------------------------
-- Finite State Machine Declaration (curr and next states)
-----------------------------------------------------------------------------
type COMMAND_FSM_TYPE is (wait_for_cmd, build_REG_FIS, send_REG_FIS_DW1,
send_REG_FIS_DW2, send_REG_FIS_DW3, send_REG_FIS_DW4, send_REG_FIS_DW5,
send_DATA_FIS_HEADER, send_write_data, send_cmd_start, wait_for_cmd_start,
wait_for_cmd_done, dead
);
signal command_fsm_curr, command_fsm_next : COMMAND_FSM_TYPE := wait_for_cmd;
signal command_fsm_value : std_logic_vector (0 to 3);
signal ll_cmd_start_next : std_logic;
signal ll_cmd_start_out : std_logic;
signal cmd_done_next : std_logic;
signal cmd_done_out : std_logic;
signal read_fifo_empty : std_logic;
signal ll_dout_next : std_logic_vector(0 to 31);
signal ll_dout_we_next : std_logic;
signal ll_dout_out : std_logic_vector(0 to 31);
signal ll_dout_we_out : std_logic;
signal ll_cmd_type_next : std_logic_vector(0 to 1);
signal ll_cmd_type_out : std_logic_vector(0 to 1);
signal dword_count : std_logic_vector(0 to 15);
signal dword_count_next : std_logic_vector(0 to 15);
signal write_data_count : std_logic_vector(0 to 31);
signal write_data_count_next : std_logic_vector(0 to 31);
signal user_din_re : std_logic;
signal sector_count_int : integer;
--- ILA signals ----
signal user_dout_ila : std_logic_vector(0 to 31);
signal ll_din_re_ila : std_logic;
--- Timer ----
signal sector_timer : std_logic_vector(31 downto 0);
--signal sata_timer : std_logic_vector(31 downto 0);
type reg_fis_type is
record
FIS_type : std_logic_vector(7 downto 0);
pad_8 : std_logic_vector(7 downto 0);
command : std_logic_vector(7 downto 0);
features : std_logic_vector(7 downto 0);
LBA : std_logic_vector(23 downto 0);
device : std_logic_vector(7 downto 0);
LBA_exp : std_logic_vector(23 downto 0);
features_exp : std_logic_vector(7 downto 0);
sector_count : std_logic_vector(15 downto 0);
pad_16 : std_logic_vector(15 downto 0);
pad_32 : std_logic_vector(31 downto 0);
end record;
signal reg_fis : reg_fis_type;
signal reg_fis_next : reg_fis_type;
-------------------------------------------------------------------------------
-- BEGIN
-------------------------------------------------------------------------------
begin
-------------------------------------------------------------------------------
-- LINK LAYER
-------------------------------------------------------------------------------
-----------------------------------------------------------------------------
-- PROCESS: COMMAND_FSM_VALUE_PROC
-- PURPOSE: ChipScope State Indicator Signal
-----------------------------------------------------------------------------
COMMAND_FSM_VALUE_PROC : process (command_fsm_curr) is
begin
case (command_fsm_curr) is
when wait_for_cmd => command_fsm_value <= x"0";
when build_REG_FIS => command_fsm_value <= x"1";
when send_REG_FIS_DW1 => command_fsm_value <= x"2";
when send_REG_FIS_DW2 => command_fsm_value <= x"3";
when send_REG_FIS_DW3 => command_fsm_value <= x"4";
when send_REG_FIS_DW4 => command_fsm_value <= x"5";
when send_REG_FIS_DW5 => command_fsm_value <= x"6";
when send_DATA_FIS_HEADER => command_fsm_value <= x"7";
when send_write_data => command_fsm_value <= x"8";
when send_cmd_start => command_fsm_value <= x"9";
when wait_for_cmd_start => command_fsm_value <= x"A";
when wait_for_cmd_done => command_fsm_value <= x"B";
when dead => command_fsm_value <= x"C";
when others => command_fsm_value <= x"D";
end case;
end process COMMAND_FSM_VALUE_PROC;
-----------------------------------------------------------------------------
-- PROCESS: COMMAND_FSM_STATE_PROC
-- PURPOSE: Registering Signals and Next State
-----------------------------------------------------------------------------
COMMAND_FSM_STATE_PROC: process (clk)
begin
if ((clk'event) and (clk = '1')) then
if (sw_reset = '1') then
--Initializing internal signals
command_fsm_curr <= wait_for_cmd;
cmd_done_out <= '0';
ll_cmd_start_out <= '0';
ll_dout_we_out <= '0';
ll_dout_out <= (others => '0');
ll_cmd_type_out <= (others => '0');
write_data_count <= (others => '0');
dword_count <= (others => '0');
reg_fis.FIS_type <= (others => '0');
reg_fis.pad_8 <= (others => '0');
reg_fis.command <= (others => '0');
reg_fis.features <= (others => '0');
reg_fis.LBA <= (others => '0');
reg_fis.device <= (others => '0');
reg_fis.LBA_exp <= (others => '0');
reg_fis.features_exp <= (others => '0');
reg_fis.sector_count <= (others => '0');
reg_fis.pad_16 <= (others => '0');
reg_fis.pad_32 <= (others => '0');
else
-- Register all Current Signals to their _next Signals
command_fsm_curr <= command_fsm_next;
cmd_done_out <= cmd_done_next;
ll_cmd_start_out <= ll_cmd_start_next;
ll_dout_we_out <= ll_dout_we_next;
ll_dout_out <= ll_dout_next;
ll_cmd_type_out <= ll_cmd_type_next;
dword_count <= dword_count_next;
write_data_count <= write_data_count_next;
reg_fis.FIS_type <= reg_fis_next.FIS_type ;
reg_fis.pad_8 <= reg_fis_next.pad_8;
reg_fis.command <= reg_fis_next.command;
reg_fis.features <= reg_fis_next.features;
reg_fis.LBA <= reg_fis_next.LBA;
reg_fis.device <= reg_fis_next.device;
reg_fis.LBA_exp <= reg_fis_next.LBA_exp;
reg_fis.features_exp <= reg_fis_next.features_exp;
reg_fis.sector_count <= reg_fis_next.sector_count;
reg_fis.pad_16 <= reg_fis_next.pad_16;
reg_fis.pad_32 <= reg_fis_next.pad_32;
end if;
end if;
end process COMMAND_FSM_STATE_PROC;
-----------------------------------------------------------------------------
-- PROCESS: COMMAND_FSM_LOGIC_PROC
-- PURPOSE: Registering Signals and Next State
-----------------------------------------------------------------------------
COMMAND_FSM_LOGIC_PROC : process (command_fsm_curr, new_cmd, cmd_type,
ll_cmd_start_out, ll_dout_we_out,
ll_dout_out, dword_count, write_data_count
) is
begin
-- Register _next to current signals
command_fsm_next <= command_fsm_curr;
cmd_done_next <= cmd_done_out;
ll_cmd_start_next <= ll_cmd_start_out;
ll_dout_we_next <= ll_dout_we_out;
ll_dout_next <= ll_dout_out;
ll_cmd_type_next <= cmd_type;
user_din_re <= '0';
dword_count_next <= dword_count;
write_data_count_next <= write_data_count;
reg_fis_next.FIS_type <= reg_fis.FIS_type ;
reg_fis_next.pad_8 <= reg_fis.pad_8;
reg_fis_next.command <= reg_fis.command;
reg_fis_next.features <= reg_fis.features;
reg_fis_next.LBA <= reg_fis.LBA;
reg_fis_next.device <= reg_fis.device;
reg_fis_next.LBA_exp <= reg_fis.LBA_exp;
reg_fis_next.features_exp <= reg_fis.features_exp;
reg_fis_next.sector_count <= reg_fis.sector_count;
reg_fis_next.pad_16 <= reg_fis.pad_16;
reg_fis_next.pad_32 <= reg_fis.pad_32;
---------------------------------------------------------------------------
-- Finite State Machine
---------------------------------------------------------------------------
case (command_fsm_curr) is
-- x0
when wait_for_cmd =>
cmd_done_next <= '1';
ll_cmd_start_next <= '0';
ll_dout_we_next <= '0';
ll_dout_next <= (others => '0');
if (new_cmd = '1') then
cmd_done_next <= '0';
command_fsm_next <= build_REG_FIS;
end if;
-- x1
when build_REG_FIS =>
reg_fis_next.FIS_type <= REG_FIS_VALUE;
reg_fis_next.pad_8 <= x"80";
if (cmd_type = READ_DMA_CMD) then
reg_fis_next.command <= READ_DMA;
else
reg_fis_next.command <= WRITE_DMA;
end if;
reg_fis_next.features <= FEATURES;
reg_fis_next.LBA <= sector_addr(23 downto 0);
reg_fis_next.device <= DEVICE_REG;
reg_fis_next.LBA_exp <= (others => '0');
reg_fis_next.features_exp <= FEATURES;
reg_fis_next.sector_count <= sector_count(15 downto 0);
reg_fis_next.pad_16 <= (others => '0');
reg_fis_next.pad_32 <= (others => '0');
command_fsm_next <= send_REG_FIS_DW1;
-- x2
when send_REG_FIS_DW1 =>
ll_dout_next <= reg_fis.FEATURES & reg_fis.command & reg_fis.pad_8 & reg_fis.FIS_type;
ll_dout_we_next <= '1';
command_fsm_next <= send_REG_FIS_DW2;
-- x3
when send_REG_FIS_DW2 =>
ll_dout_next <= reg_fis.device & reg_fis.LBA;
ll_dout_we_next <= '1';
command_fsm_next <= send_REG_FIS_DW3;
-- x4
when send_REG_FIS_DW3 =>
ll_dout_next <= reg_fis.features_exp & reg_fis.LBA_exp;
ll_dout_we_next <= '1';
command_fsm_next <= send_REG_FIS_DW4;
-- x5
when send_REG_FIS_DW4 =>
ll_dout_next <= reg_fis.pad_16 & reg_fis.sector_count ;
ll_dout_we_next <= '1';
command_fsm_next <= send_REG_FIS_DW5;
-- x6
when send_REG_FIS_DW5 =>
ll_dout_next <= reg_fis.pad_32;
ll_dout_we_next <= '1';
command_fsm_next <= send_cmd_start;
-- x7
when send_DATA_FIS_HEADER =>
if (user_fifo_full = '1') then
ll_dout_next <= DATA_FIS_HEADER;
ll_dout_we_next <= '1';
command_fsm_next <= send_write_data;
end if;
-- x8
when send_write_data =>
if(dword_count >= NDWORDS_PER_DATA_FIS) then
user_din_re <= '0';
ll_dout_we_next <= '0';
ll_dout_next <= (others => '0');
dword_count_next <= (others => '0');
command_fsm_next <= send_DATA_FIS_HEADER;
elsif (write_fifo_full = '1' or user_fifo_empty = '1') then
user_din_re <= '0';
ll_dout_we_next <= '0';
ll_dout_next <= (others => '0');
else
write_data_count_next <= write_data_count + 1;
dword_count_next <= dword_count + 1;
user_din_re <= '1';
ll_dout_next <= user_din;
ll_dout_we_next <= '1';
end if;
if (write_data_count = (SECTOR_NDWORDS*sector_count_int)) then
write_data_count_next <= (others => '0');
dword_count_next <= (others => '0');
user_din_re <= '0';
ll_dout_we_next <= '0';
ll_dout_next <= (others => '0');
command_fsm_next <= wait_for_cmd_done;
end if;
-- x9
when send_cmd_start =>
ll_dout_we_next <= '0';
ll_dout_next <= (others => '0');
if (ll_ready_for_cmd = '1') then
ll_cmd_start_next <= '1';
command_fsm_next <= wait_for_cmd_start;
end if;
-- xA
when wait_for_cmd_start =>
ll_cmd_start_next <= '0';
if (ll_ready_for_cmd = '0') then
if (cmd_type = READ_DMA_CMD) then
command_fsm_next <= wait_for_cmd_done;
else
command_fsm_next <= send_DATA_FIS_HEADER;
end if;
end if;
-- xB
when wait_for_cmd_done =>
if (ll_ready_for_cmd = '1') then
cmd_done_next <= '1';
command_fsm_next <= wait_for_cmd;
end if;
-- xC
when dead =>
command_fsm_next <= dead;
-- xD
when others =>
command_fsm_next <= dead;
end case;
end process COMMAND_FSM_LOGIC_PROC;
cmd_done <= cmd_done_out;
ll_cmd_start <= ll_cmd_start_out;
ll_cmd_type <= ll_cmd_type_out;
user_din_re_out <= user_din_re;
user_dout_ila <= ll_din;
user_dout <= user_dout_ila;
ll_dout <= ll_dout_out;
ll_dout_we <= ll_dout_we_out;
ll_din_re_ila <= user_dout_re;
ll_din_re <= ll_din_re_ila;
sector_count_int <= conv_integer(sector_count);
-----------------------------------------------------------------------------
-- PROCESS: TIMER PROCESS
-- PURPOSE: Count time to read a sector
-----------------------------------------------------------------------------
TIMER_PROC: process (clk)
begin
if ((clk'event) and (clk = '1')) then
if (sw_reset = '1') then
sector_timer <= (others => '0');
-- sata_timer <= (others => '0');
--elsif ((command_fsm_curr = wait_for_cmd_done) and (ready_for_cmd = '1')) then
--sata_timer <= sata_timer + sector_timer;
elsif (command_fsm_curr = wait_for_cmd) then
if (new_cmd = '1') then
sector_timer <= (others => '0');
else
sector_timer <= sector_timer;
end if;
else
sector_timer <= sector_timer + '1';
end if;
end if;
end process TIMER_PROC;
sector_timer_out <= sector_timer;
chipscope_gen_ila : if (CHIPSCOPE) generate
CMD_LAYER_ILA_i : cmd_layer_ila
port map (
control => cmd_layer_ila_control,
clk => clk,
trig0 => command_fsm_value,
trig1 => user_din,
trig2 => user_dout_ila,
trig3 => ll_din,
trig4 => ll_dout_out,
trig5 => cmd_type,
trig6 => ll_cmd_type_out,
trig7 => sector_timer,
trig8 => sector_addr,
trig9 => reg_fis.LBA,
trig10 => reg_fis.sector_count,
trig11(0) => new_cmd,
trig11(1) => user_din_re,
trig11(2) => user_dout_re,
trig11(3) => ll_ready_for_cmd,
trig11(4) => ll_cmd_start_out,
trig11(5) => ll_dout_we_out,
trig11(6) => ll_din_re_ila,
trig11(7) => cmd_done_out,
trig11(8) => '0',
trig11(9) => write_fifo_full,
trig11(10) => user_fifo_empty,
trig11(11) => user_fifo_full,
trig12 => dword_count,
trig13 => write_data_count
);
end generate chipscope_gen_ila;
end BEHAV;
x393_sata-05c77d236b93a06053a6ec2d8ebcad493b999f28/host/vhdl/crc.vhd 0000664 0000000 0000000 00000030416 12562737151 0023445 0 ustar 00root root 0000000 0000000 -- Copyright (C) 2012
-- Ashwin A. Mendon
--
-- This file is part of SATA2 core.
--
-- 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; either version 3 of the License, or
-- (at your option) any later version.
--
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-- GNU General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with this program. If not, see .
----------------------------------------------------------------------------------------
-- ENTITY: crc
-- Version: 1.0
-- Author: Ashwin Mendon
-- Description: This sub-module implements the CRC Circuit for the SATA Protocol
-- The code takes 32-bit data word inputs and calculates the CRC for the stream
-- The generator polynomial used is
-- 32 26 23 22 16 12 11 10 8 7 5 4 2
-- G(x) = x + x + x + x + x + x + x + x + x + x + x + x + x + x + 1
-- The CRC value is initialized to 0x52325032 as defined in the Serial ATA
-- specification
-- PORTS:
-----------------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.STD_LOGIC_ARITH.all;
use IEEE.STD_LOGIC_UNSIGNED.all;
entity crc is
generic(
CHIPSCOPE : boolean := false
);
port(
-- Clock and Reset Signals
clk : in std_logic;
reset : in std_logic;
-- ChipScope ILA / Trigger Signals
--crc_ila_control : in std_logic_vector(35 downto 0);
---------------------------------------
-- Signals from/to Sata Link Layer
crc_en : in std_logic;
data_in : in std_logic_vector(0 to 31);
data_out : out std_logic_vector(0 to 31)
);
end crc;
-------------------------------------------------------------------------------
-- ARCHITECTURE
-------------------------------------------------------------------------------
architecture BEHAV of crc is
-------------------------------------------------------------------------------
-- Constants
-------------------------------------------------------------------------------
constant CRC_INIT : std_logic_vector(0 to 31) := x"52325032";
signal crc : std_logic_vector (31 downto 0);
signal crc_next : std_logic_vector (31 downto 0);
signal crc_new : std_logic_vector (31 downto 0);
signal data_out_ila : std_logic_vector (31 downto 0);
-------------------------------------------------------------------------------
-- BEGIN
-------------------------------------------------------------------------------
begin
-----------------------------------------------------------------------------
-- PROCESS: CRC_PROC
-- PURPOSE: Registering Signals and Next State
-----------------------------------------------------------------------------
CRC_PROC : process (clk)
begin
if ((clk'event) and (clk = '1')) then
if (reset = '1') then
--Initializing internal signals
crc <= CRC_INIT;
elsif (crc_en = '1') then
-- Register all Current Signals to their _next Signals
crc <= crc_next;
else
crc <= crc;
end if;
end if;
end process CRC_PROC ;
crc_new <= crc xor data_in;
crc_next(31) <= crc_new(31) xor crc_new(30) xor crc_new(29) xor crc_new(28) xor crc_new(27) xor crc_new(25) xor crc_new(24) xor
crc_new(23) xor crc_new(15) xor crc_new(11) xor crc_new(9) xor crc_new(8) xor crc_new(5);
crc_next(30) <= crc_new(30) xor crc_new(29) xor crc_new(28) xor crc_new(27) xor crc_new(26) xor crc_new(24) xor crc_new(23) xor
crc_new(22) xor crc_new(14) xor crc_new(10) xor crc_new(8) xor crc_new(7) xor crc_new(4);
crc_next(29) <= crc_new(31) xor crc_new(29) xor crc_new(28) xor crc_new(27) xor crc_new(26) xor crc_new(25) xor crc_new(23) xor
crc_new(22) xor crc_new(21) xor crc_new(13) xor crc_new(9) xor crc_new(7) xor crc_new(6) xor crc_new(3);
crc_next(28) <= crc_new(30) xor crc_new(28) xor crc_new(27) xor crc_new(26) xor crc_new(25) xor crc_new(24) xor crc_new(22) xor
crc_new(21) xor crc_new(20) xor crc_new(12) xor crc_new(8) xor crc_new(6) xor crc_new(5) xor crc_new(2);
crc_next(27) <= crc_new(29) xor crc_new(27) xor crc_new(26) xor crc_new(25) xor crc_new(24) xor crc_new(23) xor crc_new(21) xor
crc_new(20) xor crc_new(19) xor crc_new(11) xor crc_new(7) xor crc_new(5) xor crc_new(4) xor crc_new(1);
crc_next(26) <= crc_new(31) xor crc_new(28) xor crc_new(26) xor crc_new(25) xor crc_new(24) xor crc_new(23) xor crc_new(22) xor
crc_new(20) xor crc_new(19) xor crc_new(18) xor crc_new(10) xor crc_new(6) xor crc_new(4) xor crc_new(3) xor
crc_new(0);
crc_next(25) <= crc_new(31) xor crc_new(29) xor crc_new(28) xor crc_new(22) xor crc_new(21) xor crc_new(19) xor crc_new(18) xor
crc_new(17) xor crc_new(15) xor crc_new(11) xor crc_new(8) xor crc_new(3) xor crc_new(2);
crc_next(24) <= crc_new(30) xor crc_new(28) xor crc_new(27) xor crc_new(21) xor crc_new(20) xor crc_new(18) xor crc_new(17) xor
crc_new(16) xor crc_new(14) xor crc_new(10) xor crc_new(7) xor crc_new(2) xor crc_new(1);
crc_next(23) <= crc_new(31) xor crc_new(29) xor crc_new(27) xor crc_new(26) xor crc_new(20) xor crc_new(19) xor crc_new(17) xor
crc_new(16) xor crc_new(15) xor crc_new(13) xor crc_new(9) xor crc_new(6) xor crc_new(1) xor crc_new(0);
crc_next(22) <= crc_new(31) xor crc_new(29) xor crc_new(27) xor crc_new(26) xor crc_new(24) xor crc_new(23) xor crc_new(19) xor
crc_new(18) xor crc_new(16) xor crc_new(14) xor crc_new(12) xor crc_new(11) xor crc_new(9) xor crc_new(0);
crc_next(21) <= crc_new(31) xor crc_new(29) xor crc_new(27) xor crc_new(26) xor crc_new(24) xor crc_new(22) xor crc_new(18) xor
crc_new(17) xor crc_new(13) xor crc_new(10) xor crc_new(9) xor crc_new(5);
crc_next(20) <= crc_new(30) xor crc_new(28) xor crc_new(26) xor crc_new(25) xor crc_new(23) xor crc_new(21) xor crc_new(17) xor
crc_new(16) xor crc_new(12) xor crc_new(9) xor crc_new(8) xor crc_new(4);
crc_next(19) <= crc_new(29) xor crc_new(27) xor crc_new(25) xor crc_new(24) xor crc_new(22) xor crc_new(20) xor crc_new(16) xor
crc_new(15) xor crc_new(11) xor crc_new(8) xor crc_new(7) xor crc_new(3);
crc_next(18) <= crc_new(31) xor crc_new(28) xor crc_new(26) xor crc_new(24) xor crc_new(23) xor crc_new(21) xor crc_new(19) xor
crc_new(15) xor crc_new(14) xor crc_new(10) xor crc_new(7) xor crc_new(6) xor crc_new(2);
crc_next(17) <= crc_new(31) xor crc_new(30) xor crc_new(27) xor crc_new(25) xor crc_new(23) xor crc_new(22) xor crc_new(20) xor
crc_new(18) xor crc_new(14) xor crc_new(13) xor crc_new(9) xor crc_new(6) xor crc_new(5) xor crc_new(1);
crc_next(16) <= crc_new(30) xor crc_new(29) xor crc_new(26) xor crc_new(24) xor crc_new(22) xor crc_new(21) xor crc_new(19) xor
crc_new(17) xor crc_new(13) xor crc_new(12) xor crc_new(8) xor crc_new(5) xor crc_new(4) xor crc_new(0);
crc_next(15) <= crc_new(30) xor crc_new(27) xor crc_new(24) xor crc_new(21) xor crc_new(20) xor crc_new(18) xor crc_new(16) xor
crc_new(15) xor crc_new(12) xor crc_new(9) xor crc_new(8) xor crc_new(7) xor crc_new(5) xor crc_new(4) xor
crc_new(3);
crc_next(14) <= crc_new(29) xor crc_new(26) xor crc_new(23) xor crc_new(20) xor crc_new(19) xor crc_new(17) xor crc_new(15) xor
crc_new(14) xor crc_new(11) xor crc_new(8) xor crc_new(7) xor crc_new(6) xor crc_new(4) xor crc_new(3) xor
crc_new(2);
crc_next(13) <= crc_new(31) xor crc_new(28) xor crc_new(25) xor crc_new(22) xor crc_new(19) xor crc_new(18) xor crc_new(16) xor
crc_new(14) xor crc_new(13) xor crc_new(10) xor crc_new(7) xor crc_new(6) xor crc_new(5) xor crc_new(3) xor
crc_new(2) xor crc_new(1);
crc_next(12) <= crc_new(31) xor crc_new(30) xor crc_new(27) xor crc_new(24) xor crc_new(21) xor crc_new(18) xor crc_new(17) xor
crc_new(15) xor crc_new(13) xor crc_new(12) xor crc_new(9) xor crc_new(6) xor crc_new(5) xor crc_new(4) xor
crc_new(2) xor crc_new(1) xor crc_new(0);
crc_next(11) <= crc_new(31) xor crc_new(28) xor crc_new(27) xor crc_new(26) xor crc_new(25) xor crc_new(24) xor crc_new(20) xor
crc_new(17) xor crc_new(16) xor crc_new(15) xor crc_new(14) xor crc_new(12) xor crc_new(9) xor crc_new(4) xor
crc_new(3) xor crc_new(1) xor crc_new(0);
crc_next(10) <= crc_new(31) xor crc_new(29) xor crc_new(28) xor crc_new(26) xor crc_new(19) xor crc_new(16) xor crc_new(14) xor
crc_new(13) xor crc_new(9) xor crc_new(5) xor crc_new(3) xor crc_new(2) xor crc_new(0);
crc_next(9) <= crc_new(29) xor crc_new(24) xor crc_new(23) xor crc_new(18) xor crc_new(13) xor crc_new(12) xor crc_new(11) xor
crc_new(9) xor crc_new(5) xor crc_new(4) xor crc_new(2) xor crc_new(1);
crc_next(8) <= crc_new(31) xor crc_new(28) xor crc_new(23) xor crc_new(22) xor crc_new(17) xor crc_new(12) xor crc_new(11) xor
crc_new(10) xor crc_new(8) xor crc_new(4) xor crc_new(3) xor crc_new(1) xor crc_new(0);
crc_next(7) <= crc_new(29) xor crc_new(28) xor crc_new(25) xor crc_new(24) xor crc_new(23) xor crc_new(22) xor crc_new(21) xor
crc_new(16) xor crc_new(15) xor crc_new(10) xor crc_new(8) xor crc_new(7) xor crc_new(5) xor crc_new(3) xor
crc_new(2) xor crc_new(0);
crc_next(6) <= crc_new(30) xor crc_new(29) xor crc_new(25) xor crc_new(22) xor crc_new(21) xor crc_new(20) xor crc_new(14) xor
crc_new(11) xor crc_new(8) xor crc_new(7) xor crc_new(6) xor crc_new(5) xor crc_new(4) xor crc_new(2) xor
crc_new(1);
crc_next(5) <= crc_new(29) xor crc_new(28) xor crc_new(24) xor crc_new(21) xor crc_new(20) xor crc_new(19) xor crc_new(13) xor
crc_new(10) xor crc_new(7) xor crc_new(6) xor crc_new(5) xor crc_new(4) xor crc_new(3) xor crc_new(1) xor
crc_new(0);
crc_next(4) <= crc_new(31) xor crc_new(30) xor crc_new(29) xor crc_new(25) xor crc_new(24) xor crc_new(20) xor crc_new(19) xor
crc_new(18) xor crc_new(15) xor crc_new(12) xor crc_new(11) xor crc_new(8) xor crc_new(6) xor crc_new(4) xor
crc_new(3) xor crc_new(2) xor crc_new(0);
crc_next(3) <= crc_new(31) xor crc_new(27) xor crc_new(25) xor crc_new(19) xor crc_new(18) xor crc_new(17) xor crc_new(15) xor
crc_new(14) xor crc_new(10) xor crc_new(9) xor crc_new(8) xor crc_new(7) xor crc_new(3) xor crc_new(2) xor
crc_new(1);
crc_next(2) <= crc_new(31) xor crc_new(30) xor crc_new(26) xor crc_new(24) xor crc_new(18) xor crc_new(17) xor crc_new(16) xor
crc_new(14) xor crc_new(13) xor crc_new(9) xor crc_new(8) xor crc_new(7) xor crc_new(6) xor crc_new(2) xor
crc_new(1) xor crc_new(0);
crc_next(1) <= crc_new(28) xor crc_new(27) xor crc_new(24) xor crc_new(17) xor crc_new(16) xor crc_new(13) xor crc_new(12) xor
crc_new(11) xor crc_new(9) xor crc_new(7) xor crc_new(6) xor crc_new(1) xor crc_new(0);
crc_next(0) <= crc_new(31) xor crc_new(30) xor crc_new(29) xor crc_new(28) xor crc_new(26) xor crc_new(25) xor crc_new(24) xor
crc_new(16) xor crc_new(12) xor crc_new(10) xor crc_new(9) xor crc_new(6) xor crc_new(0);
data_out_ila <= crc_next;
--data_out_ila <= crc;
-----------------------------------------------------------------------------
-- ILA Instantiation
-----------------------------------------------------------------------------
data_out <= data_out_ila;
end BEHAV;
x393_sata-05c77d236b93a06053a6ec2d8ebcad493b999f28/host/vhdl/mux_161.vhd 0000664 0000000 0000000 00000006022 12562737151 0024072 0 ustar 00root root 0000000 0000000 -- Copyright (C) 2012
-- Ashwin A. Mendon
--
-- This file is part of SATA2 core.
--
-- 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; either version 3 of the License, or
-- (at your option) any later version.
--
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-- GNU General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with this program. If not, see .
--------------------------------------------------------------------------------
-- Entity mux_161
-- Version: 1.0
-- Author: Ashwin Mendon
-- Description: 32 bit 16:1 Multiplexer
--
--------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity mux_161 is
generic(
DATA_WIDTH: natural := 32
);
port(
a : in std_logic_vector(DATA_WIDTH-1 downto 0);
b : in std_logic_vector(DATA_WIDTH-1 downto 0);
c : in std_logic_vector(DATA_WIDTH-1 downto 0);
d : in std_logic_vector(DATA_WIDTH-1 downto 0);
e : in std_logic_vector(DATA_WIDTH-1 downto 0);
f : in std_logic_vector(DATA_WIDTH-1 downto 0);
g : in std_logic_vector(DATA_WIDTH-1 downto 0);
h : in std_logic_vector(DATA_WIDTH-1 downto 0);
i : in std_logic_vector(DATA_WIDTH-1 downto 0);
j : in std_logic_vector(DATA_WIDTH-1 downto 0);
k : in std_logic_vector(DATA_WIDTH-1 downto 0);
l : in std_logic_vector(DATA_WIDTH-1 downto 0);
m : in std_logic_vector(DATA_WIDTH-1 downto 0);
n : in std_logic_vector(DATA_WIDTH-1 downto 0);
o : in std_logic_vector(DATA_WIDTH-1 downto 0);
p : in std_logic_vector(DATA_WIDTH-1 downto 0);
sel : in std_logic_vector(3 downto 0);
output : out std_logic_vector(DATA_WIDTH-1 downto 0)
);
end mux_161;
architecture mux_behav of mux_161 is
begin
process(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,sel)
begin
case (sel) is
when "0000" =>
output <= a;
when "0001" =>
output <= b;
when "0010" =>
output <= c;
when "0011" =>
output <= d;
when "0100" =>
output <= e;
when "0101" =>
output <= f;
when "0110" =>
output <= g;
when "0111" =>
output <= h;
when "1000" =>
output <= i;
when "1001" =>
output <= j;
when "1010" =>
output <= k;
when "1011" =>
output <= l;
when "1100" =>
output <= m;
when "1101" =>
output <= n;
when "1110" =>
output <= o;
when others =>
output <= p;
end case;
end process;
end mux_behav;
x393_sata-05c77d236b93a06053a6ec2d8ebcad493b999f28/host/vhdl/sata_core.vhd 0000664 0000000 0000000 00000027213 12562737151 0024637 0 ustar 00root root 0000000 0000000 -- Copyright (C) 2012
-- Ashwin A. Mendon
--
-- This file is part of SATA2 core.
--
-- 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; either version 3 of the License, or
-- (at your option) any later version.
--
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-- GNU General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with this program. If not, see .
----------------------------------------------------------------------------------------
-- ENTITY: sata_core
-- Version: 1.0
-- Author: Ashwin Mendon
-- Description: The SATA core implements the Command, Transport and Link Layers of
-- the SATA protocol and provides a Physical Layer Wrapper for the GTX
-- transceivers. The Physical Layer Wrapper also includes an Out of Band
-- Signaling (OOB) controller state machine which deals with initialization
-- and synchronization of the SATA link. It can interface with SATA 2
-- Winchester style Hard Disks as well as Flash-based Solid State Drives
-- The core provides a simple interface to issue READ/WRITE sector commands.
-- The DATA interface is 32-bit FIFO like.
-- A 150 MHz input reference clock is needed for the GTX transceivers.
-- The output data is delivered 4 bytes @ 75 MHz (user output clock)
-- for a theoretical peak bandwidth of 300 MB/s (SATA 2).
--
--
-- PORTS:
-- Command, Control and Status --
-- ready_for_cmd : When asserted, SATA core is ready to execute new command.
-- This signal goes low after new_cmd is asserted.
-- It also serves as the command done signal
-- new_cmd : Asserted for one clock cycle to start a request
-- cmd_type : "01" for READ request and "10" for WRITE request
-- sector_count : Number of sectors requested by user
-- sector_addr : Starting address of request
-- Data and User Clock --
-- sata_din : Data from user to Write to Disk
-- sata_din_we : Write Enable to SATA Core when FULL is low
-- sata_core_full : SATA Core Full- de-assert WE
-- sata_dout : Data output from SATA Core
-- sata_dout_re : Read Enable from SATA asserted when EMPTY is low
-- sata_core_empty : SATA Core Empty- de-assert RE
-- SATA_USER_DATA_CLK_IN : SATA Core Write Clock
-- SATA_USER_DATA_CLK_OUT : SATA Core Read Clock
-- sata_timer : SATA core timer output to check performance
--PHY Signals--
-- CLKIN_150 : 150 Mhz input reference clock for the GTX transceivers
-- reset : Resets GTX and SATA core; can be tied to a software reset
-- LINKUP : Indicates Link Initialization done (OOB) and SATA link is up
--GTX transmit/receive pins: Connected to the FMC_HPC pins on a ML605 board
-- TXP0_OUT, TXN0_OUT, RXP0_IN, RXN0_IN
-----------------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.STD_LOGIC_ARITH.all;
use IEEE.STD_LOGIC_UNSIGNED.all;
entity sata_core is
generic(
CHIPSCOPE : boolean := false;
DATA_WIDTH : natural := 32
);
port(
-- ChipScope ILA / Trigger Signals
sata_rx_frame_ila_control : in std_logic_vector(35 downto 0);
sata_tx_frame_ila_control : in std_logic_vector(35 downto 0);
sata_phy_ila_control : in std_logic_vector(35 downto 0);
oob_control_ila_control : in std_logic_vector(35 downto 0);
cmd_layer_ila_control : in std_logic_vector(35 downto 0);
scrambler_ila_control : in std_logic_vector(35 downto 0);
descrambler_ila_control : in std_logic_vector(35 downto 0);
---------------------------------------
-- SATA Interface -----
-- Command, Control and Status --
ready_for_cmd : out std_logic;
new_cmd : in std_logic;
cmd_type : in std_logic_vector(1 downto 0);
sector_count : in std_logic_vector(31 downto 0);
sector_addr : in std_logic_vector(31 downto 0);
-- Data and User Clock --
sata_din : in std_logic_vector(31 downto 0);
sata_din_we : in std_logic;
sata_core_full : out std_logic;
sata_dout : out std_logic_vector(31 downto 0);
sata_dout_re : in std_logic;
sata_core_empty : out std_logic;
SATA_USER_DATA_CLK_IN : in std_logic;
SATA_USER_DATA_CLK_OUT : out std_logic;
-- Timer --
sata_timer : out std_logic_vector(31 downto 0);
-- PHY Signals
-- Clock and Reset Signals
CLKIN_150 : in std_logic;
reset : in std_logic;
LINKUP : out std_logic;
TXP0_OUT : out std_logic;
TXN0_OUT : out std_logic;
RXP0_IN : in std_logic;
RXN0_IN : in std_logic;
PLLLKDET_OUT_N : out std_logic;
DCMLOCKED_OUT : out std_logic
);
end sata_core;
-------------------------------------------------------------------------------
-- ARCHITECTURE
-------------------------------------------------------------------------------
architecture BEHAV of sata_core is
-- Sata Phy
signal sata_user_clk : std_logic;
--signal GTXRESET : std_logic;
signal LINKUP_i : std_logic;
-- Sata Phy
signal REFCLK_PAD_P_IN_i : std_logic;
signal REFCLK_PAD_N_IN_i : std_logic;
-- COMMAND LAYER / LINK LAYER SIGNALS
signal ll_ready_for_cmd_i : std_logic;
signal sata_ready_for_cmd_i : std_logic;
signal ll_cmd_start : std_logic;
signal ll_cmd_type : std_logic_vector(1 downto 0);
signal ll_dout : std_logic_vector(31 downto 0);
signal ll_dout_we : std_logic;
signal ll_din : std_logic_vector(31 downto 0);
signal ll_din_re : std_logic;
signal sector_count_int : integer;
-- User FIFO signals
signal user_din_re : std_logic;
signal user_fifo_dout : std_logic_vector(31 downto 0);
signal user_fifo_full : std_logic;
signal user_fifo_prog_full : std_logic;
signal user_fifo_empty : std_logic;
signal write_fifo_full_i : std_logic;
signal read_fifo_empty : std_logic;
-- USER FIFO DECLARATION
component user_fifo
port (
rst: IN std_logic;
wr_clk: IN std_logic;
din: IN std_logic_VECTOR(31 downto 0);
wr_en: IN std_logic;
rd_clk: IN std_logic;
rd_en: IN std_logic;
dout: OUT std_logic_VECTOR(31 downto 0);
full: OUT std_logic;
prog_full: OUT std_logic;
empty: OUT std_logic);
end component;
-------------------------------------------------------------------------------
-- BEGIN
-------------------------------------------------------------------------------
begin
--- User Logic Fifo for writing data ---
USER_FIFO_i : user_fifo
port map (
rst => reset,
wr_clk => SATA_USER_DATA_CLK_IN,
din => sata_din,
wr_en => sata_din_we,
rd_clk => sata_user_clk,
dout => user_fifo_dout,
rd_en => user_din_re,
full => user_fifo_full,
prog_full => user_fifo_prog_full,
empty => user_fifo_empty);
-- SATA Core Output Signals
ready_for_cmd <= sata_ready_for_cmd_i;
--sata_core_full <= write_fifo_full_i;
sata_core_full <= user_fifo_prog_full;
sata_core_empty <= read_fifo_empty;
SATA_USER_DATA_CLK_OUT <= sata_user_clk;
LINKUP <= LINKUP_i;
-----------------------------------------------------------------------------
-- Command Layer Instance
-----------------------------------------------------------------------------
COMMAND_LAYER_i : entity work.command_layer
generic map
(
CHIPSCOPE => CHIPSCOPE
)
port map
(
-- ChipScope Signal
cmd_layer_ila_control => cmd_layer_ila_control,
-- Clock and Reset Signals
sw_reset => reset,
clk => sata_user_clk,
new_cmd => new_cmd,
cmd_done => sata_ready_for_cmd_i,
cmd_type => cmd_type,
sector_count => sector_count,
sector_addr => sector_addr,
user_din => user_fifo_dout,
user_din_re_out => user_din_re,
user_dout => sata_dout,
user_dout_re => sata_dout_re,
write_fifo_full => write_fifo_full_i,
user_fifo_empty => user_fifo_empty,
user_fifo_full => user_fifo_prog_full,
sector_timer_out => sata_timer,
-- Signals from/to Link Layer
ll_ready_for_cmd => ll_ready_for_cmd_i,
ll_cmd_start => ll_cmd_start,
ll_cmd_type => ll_cmd_type,
ll_dout => ll_dout,
ll_dout_we => ll_dout_we,
ll_din => ll_din,
ll_din_re => ll_din_re
);
------------------------------------------
-- Sata Link Layer Module Instance
------------------------------------------
sector_count_int <= conv_integer(sector_count);
SATA_LINK_LAYER_i: entity work.sata_link_layer
generic map(
CHIPSCOPE => CHIPSCOPE,
DATA_WIDTH => DATA_WIDTH
)
port map(
-- Clock and Reset Signals
CLKIN_150 => CLKIN_150,
sw_reset => reset,
-- ChipScope ILA / Trigger Signals
sata_rx_frame_ila_control => sata_rx_frame_ila_control ,
sata_tx_frame_ila_control => sata_tx_frame_ila_control ,
oob_control_ila_control => oob_control_ila_control,
sata_phy_ila_control => sata_phy_ila_control,
scrambler_ila_control => scrambler_ila_control,
descrambler_ila_control => descrambler_ila_control,
---------------------------------------
-- Ports from/to User Logic
read_fifo_empty => read_fifo_empty,
write_fifo_full => write_fifo_full_i,
GTX_RESET_IN => reset,
sector_count => sector_count_int,
sata_user_clk_out => sata_user_clk,
-- Ports from/to Command Layer
ready_for_cmd_out => ll_ready_for_cmd_i,
new_cmd_in => ll_cmd_start,
cmd_type => ll_cmd_type,
sata_din => ll_dout,
sata_din_we => ll_dout_we,
sata_dout => ll_din,
sata_dout_re => ll_din_re,
---------------------------------------
-- Ports to SATA PHY
REFCLK_PAD_P_IN => REFCLK_PAD_P_IN_i,
REFCLK_PAD_N_IN => REFCLK_PAD_N_IN_i,
TXP0_OUT => TXP0_OUT,
TXN0_OUT => TXN0_OUT,
RXP0_IN => RXP0_IN,
RXN0_IN => RXN0_IN,
PLLLKDET_OUT_N => PLLLKDET_OUT_N,
DCMLOCKED_OUT => DCMLOCKED_OUT,
LINKUP_led => LINKUP_i
);
end BEHAV;
x393_sata-05c77d236b93a06053a6ec2d8ebcad493b999f28/host/vhdl/sata_link_layer.vhd 0000664 0000000 0000000 00000173363 12562737151 0026050 0 ustar 00root root 0000000 0000000 -- Copyright (C) 2012
-- Ashwin A. Mendon
--
-- This file is part of SATA2 core.
--
-- 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; either version 3 of the License, or
-- (at your option) any later version.
--
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-- GNU General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with this program. If not, see .
----------------------------------------------------------------------------------------
-- ENTITY: sata_link_layer
-- Version: 1.0
-- Author: Ashwin Mendon
-- Description: This sub-module implements the Transport and Link Layers of the SATA Protocol
-- It is the heart of the SATA Core where the major functions of sending/receiving
-- sequences of Frame Information Structures (FIS), packing them into
-- Frames and sending/receiving Frames are accomplished.
-- The Master FSM deals with the Transport Layer functions of sending receiving FISs
-- using the TX and RX FSMs.
-- The TX and RX FSMs use the crc, scrambler and primitive muxes to construct and
-- deconstruct Frames. They also implement a Frame transmission/reception protocol.
-- PORTS:
-----------------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.STD_LOGIC_ARITH.all;
use IEEE.STD_LOGIC_UNSIGNED.all;
entity sata_link_layer is
generic(
CHIPSCOPE : boolean := false;
DATA_WIDTH : natural := 32
);
port(
-- Clock and Reset Signals
--clk : in std_logic;
sw_reset : in std_logic;
-- ChipScope ILA / Trigger Signals
sata_rx_frame_ila_control : in std_logic_vector(35 downto 0);
sata_tx_frame_ila_control : in std_logic_vector(35 downto 0);
--master_fsm_ila_control : in std_logic_vector(35 downto 0);
oob_control_ila_control : in std_logic_vector(35 downto 0);
sata_phy_ila_control : in std_logic_vector(35 downto 0);
scrambler_ila_control : in std_logic_vector (35 downto 0);
descrambler_ila_control : in std_logic_vector (35 downto 0);
---------------------------------------
-- Signals from/to User Logic
sata_user_clk_out : out std_logic;
GTX_RESET_IN : in std_logic;
ready_for_cmd_out : out std_logic;
new_cmd_in : in std_logic;
cmd_type : in std_logic_vector(1 downto 0);
sector_count : in integer;
sata_din : in std_logic_vector(DATA_WIDTH-1 downto 0);
sata_din_we : in std_logic;
sata_dout : out std_logic_vector(DATA_WIDTH-1 downto 0);
sata_dout_re : in std_logic;
read_fifo_empty : out std_logic;
write_fifo_full : out std_logic;
---------------------------------------
-- Ports from/to SATA PHY
REFCLK_PAD_P_IN : in std_logic; -- MGTCLKA, clocks GTP_X0Y0-2
REFCLK_PAD_N_IN : in std_logic; -- MGTCLKA
TXP0_OUT : out std_logic;
TXN0_OUT : out std_logic;
RXP0_IN : in std_logic;
RXN0_IN : in std_logic;
PLLLKDET_OUT_N : out std_logic;
DCMLOCKED_OUT : out std_logic;
LINKUP_led : out std_logic;
--GEN2_led : out std_logic;
CLKIN_150 : in std_logic
);
end sata_link_layer;
-------------------------------------------------------------------------------
-- ARCHITECTURE
-------------------------------------------------------------------------------
architecture BEHAV of sata_link_layer is
-------------------------------------------------------------------------------
-- LINK LAYER
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
-- Constants
-------------------------------------------------------------------------------
--Commands
constant IDEN_DEV : std_logic_vector(1 downto 0) := "00";
constant READ_DMA : std_logic_vector(1 downto 0) := "01";
constant WRITE_DMA : std_logic_vector(1 downto 0) := "10";
constant SET_FEATURES : std_logic_vector(1 downto 0) := "11";
--Primitves
constant SYNC : std_logic_vector(3 downto 0) := "0000";
constant R_RDY : std_logic_vector(3 downto 0) := "0001";
constant R_IP : std_logic_vector(3 downto 0) := "0010";
constant R_OK : std_logic_vector(3 downto 0) := "0011";
constant R_ERR : std_logic_vector(3 downto 0) := "0100";
constant X_RDY : std_logic_vector(3 downto 0) := "0101";
constant WTRM : std_logic_vector(3 downto 0) := "0110";
constant HOLD : std_logic_vector(3 downto 0) := "0111";
constant HOLD_ACK : std_logic_vector(3 downto 0) := "1000";
constant CONT : std_logic_vector(3 downto 0) := "1001";
constant SOF : std_logic_vector(3 downto 0) := "1010";
constant EOF : std_logic_vector(3 downto 0) := "1011";
constant FIS : std_logic_vector(3 downto 0) := "1100";
constant PRIM_SCRM : std_logic_vector(3 downto 0) := "1101";
constant COMMAND_FIS : std_logic_vector(15 downto 0) := conv_std_logic_vector(5, 16); -- (6DWORDS: 5 + 1CRC)
--constant DATA_FIS : std_logic_vector(15 downto 0) := conv_std_logic_vector(259, 16); -- 260 WORDS (130DWORDS: 1FIS_TYPE + 128DATA + 1CRC)
constant REG_FIS_NDWORDS : std_logic_vector(15 downto 0) := conv_std_logic_vector(6, 16); -- (6DWORDS: 5 + 1CRC)
constant DATA_FIS_NDWORDS : integer := 130;
constant SECTOR_NDWORDS : integer := 128; -- 256 WORDS / 512 Byte Sector
constant NDWORDS_PER_DATA_FIS : std_logic_vector(15 downto 0) := conv_std_logic_vector(2048, 16);--128*16
constant NDWORDS_PER_DATA_FIS_32 : std_logic_vector(31 downto 0) := conv_std_logic_vector(2048, 32);--128*16
constant SYNC_COUNT_VALUE : std_logic_vector(7 downto 0) := conv_std_logic_vector(30, 8); -- 50 WORDS
-----------------------------------------------------------------------------
-- Finite State Machine Declaration (curr and next states)
-----------------------------------------------------------------------------
type MASTER_FSM_TYPE is (idle, capture_dev_sign, wait_for_cmd, H2D_REG_FIS, D2H_DMA_ACT_FIS,
H2D_DATA_FIS, D2H_REG_FIS, D2H_DATA_FIS, D2H_PIO_SETUP, dead
);
signal master_fsm_curr, master_fsm_next : MASTER_FSM_TYPE := idle;
signal master_fsm_value : std_logic_vector (0 to 3);
type RX_FRAME_FSM_TYPE is (idle, send_R_RDY, send_R_IP, send_HOLD_ACK, send_R_OK,
send_SYNC, wait_for_X_RDY, dead
);
signal rx_frame_curr, rx_frame_next : RX_FRAME_FSM_TYPE := idle;
signal rx_frame_value : std_logic_vector (0 to 3);
type TX_FRAME_FSM_TYPE is (idle, send_X_RDY, send_SOF, send_FIS, send_EOF, send_WTRM,
send_SYNC, send_HOLD_ACK, send_HOLD, dead
);
signal tx_frame_curr, tx_frame_next : TX_FRAME_FSM_TYPE := idle;
signal tx_frame_value : std_logic_vector (0 to 3);
-----------------------------------------------------------------------------
-- Finite State Machine Declaration (curr and next states)
-----------------------------------------------------------------------------
signal new_cmd : std_logic;
signal FIS_word_count, FIS_word_count_next : std_logic_vector(0 to 15); --Counter for FIS WORD Count (WRITE)
signal FIS_count_value, FIS_count_value_next : std_logic_vector(0 to 15); --Counter LIMIT for FIS WORD Count (WRITE)
signal rx_sector_count : std_logic_vector(0 to 15); --Counter for number of received sectors
signal tx_sector_count, tx_sector_count_next : std_logic_vector(0 to 15); --Counter for number of transmitted sectors
signal dword_count : std_logic_vector(0 to 7); --Counter for DWORDS in each received sector
signal DATA_FIS_dword_count : std_logic_vector(0 to 15); --Counter for DWORDS in each received DATA FIS
signal dword_count_init_value : std_logic_vector(0 to 31);
signal dword_count_value : std_logic_vector(0 to 15);
signal start_rx, start_tx, rx_done, tx_done : std_logic;
signal start_rx_next, start_tx_next, rx_done_next, tx_done_next : std_logic;
signal prim_type_rx, prim_type_tx, prim_type : std_logic_vector (0 to 3);
signal prim_type_rx_next, prim_type_tx_next : std_logic_vector (0 to 3);
signal rx_tx_state_sel, rx_tx_state_sel_next : std_logic;
signal sync_count_rx, sync_count_rx_next : std_logic_vector (0 to 7);
signal sync_count_tx, sync_count_tx_next : std_logic_vector (0 to 7);
signal ready_for_cmd_next : std_logic;
signal ready_for_cmd : std_logic;
signal frame_err, frame_err_next : std_logic;
signal tx_err, tx_err_next : std_logic;
signal tx_r_rdy, tx_r_ip, tx_r_ok, tx_r_err : std_logic_vector(0 to DATA_WIDTH-1);
signal tx_x_rdy, tx_wtrm, tx_sof, tx_eof, tx_sync : std_logic_vector(0 to DATA_WIDTH-1);
signal tx_hold, tx_hold_ack, tx_cont : std_logic_vector(0 to DATA_WIDTH-1);
signal tx_dataout : std_logic_vector(0 to DATA_WIDTH-1);
signal tx_charisk_out : std_logic;
signal tx_charisk_RX_FRAME, tx_charisk_TX_FRAME: std_logic;
signal output_mux_sel : std_logic_vector(0 to 3);
signal align_en_out : std_logic;
-- Primitive Detectors
signal SYNC_det : std_logic;
signal R_RDY_det : std_logic;
signal R_IP_det : std_logic;
signal R_OK_det : std_logic;
signal R_ERR_det : std_logic;
signal SOF_det : std_logic;
signal EOF_det : std_logic;
signal X_RDY_det : std_logic;
signal WTRM_det : std_logic;
signal CONT_det : std_logic;
signal HOLD_det : std_logic;
signal HOLD_det_r : std_logic;
signal HOLD_det_r2 : std_logic;
signal HOLD_det_r3 : std_logic;
signal HOLD_det_r4 : std_logic;
signal HOLD_start_det : std_logic;
signal HOLD_stop_det : std_logic;
signal HOLD_stop_after_ALIGN_det : std_logic;
signal CORNER_CASE_HOLD : std_logic;
signal HOLD_ACK_det : std_logic;
signal ALIGN_det : std_logic;
signal ALIGN_det_r : std_logic;
signal ALIGN_det_r2 : std_logic;
signal TWO_HOLD_det : std_logic;
signal TWO_HOLD_det_r : std_logic;
-----------------------------------------------------------------------------
-- Internal Signals
-----------------------------------------------------------------------------
signal sata_user_clk : std_logic;
signal rx_datain : std_logic_vector(0 to DATA_WIDTH-1);
signal rxelecidle : std_logic;
signal rx_charisk_in : std_logic_vector(3 downto 0);
-- Debugging OOB
signal OOB_state : std_logic_vector (0 to 7);
signal LINKUP : std_logic;
signal GEN2_led_i : std_logic;
-- Scrambler/DeScrambler
signal scrambler_din : std_logic_vector(0 to DATA_WIDTH-1);
signal scrambler_dout : std_logic_vector(0 to DATA_WIDTH-1);
signal scrambler_en, scrambler_en_r : std_logic;
signal scrambler_din_re, scrambler_din_re_r : std_logic;
signal scrambler_dout_we : std_logic;
signal scrambler_reset : std_logic;
signal scrambler_reset_after_FIS : std_logic;
signal descrambler_din : std_logic_vector(0 to DATA_WIDTH-1);
signal descrambler_dout : std_logic_vector(0 to DATA_WIDTH-1);
signal descrambler_en : std_logic;
signal descrambler_din_re, descrambler_din_re_r : std_logic;
signal descrambler_dout_we : std_logic;
signal descrambler_reset : std_logic;
signal scrambler_count : std_logic_vector(0 to 15);
signal scrambler_count_init_value : std_logic_vector(0 to 31);
signal scrambler_count_value : std_logic_vector(0 to 15);
signal scrambler_count_en_reg_fis : std_logic;
signal scrambler_count_en_data_fis : std_logic;
-- CRC
signal crc_reset : std_logic;
signal crc_din : std_logic_vector(0 to DATA_WIDTH-1);
signal crc_dout : std_logic_vector(0 to DATA_WIDTH-1);
signal crc_dout_r : std_logic_vector(0 to DATA_WIDTH-1);
signal crc_en : std_logic;
-----------------------------------------------------------------------------
-- Post-DeScramble Read FIFO to Command Layer
-----------------------------------------------------------------------------
signal read_fifo_re : std_logic;
signal read_fifo_we : std_logic;
signal read_fifo_empty_i : std_logic;
signal read_fifo_almost_empty : std_logic;
signal read_fifo_full : std_logic;
signal read_fifo_prog_full : std_logic;
signal read_fifo_din : std_logic_vector(0 to DATA_WIDTH-1);
signal read_fifo_dout : std_logic_vector(0 to DATA_WIDTH-1);
-----------------------------------------------------------------------------
-- Pre-DeScramble RX FIFO from PHY Layer
-----------------------------------------------------------------------------
signal rx_fifo_we : std_logic;
signal rx_fifo_we_next : std_logic;
signal rx_fifo_re : std_logic;
signal rx_fifo_empty : std_logic;
signal rx_fifo_almost_empty : std_logic;
signal rx_fifo_full : std_logic;
signal rx_fifo_prog_full : std_logic;
signal rx_fifo_din : std_logic_vector(0 to DATA_WIDTH-1);
signal rx_fifo_dout : std_logic_vector(0 to DATA_WIDTH-1);
signal rx_fifo_data_count : std_logic_vector(0 to 9);
signal rx_fifo_reset : std_logic;
-----------------------------------------------------------------------------
-- Pre-Scramble Write FIFO from Command Layer
-----------------------------------------------------------------------------
signal write_fifo_we : std_logic;
signal write_fifo_re : std_logic;
signal write_fifo_empty : std_logic;
signal write_fifo_almost_empty : std_logic;
signal write_fifo_full_i : std_logic;
signal write_fifo_prog_full : std_logic;
signal write_fifo_din : std_logic_vector(0 to DATA_WIDTH-1);
signal write_fifo_dout : std_logic_vector(0 to DATA_WIDTH-1);
-----------------------------------------------------------------------------
-- Post-Scramble TX FIFO to PHY Layer
-----------------------------------------------------------------------------
signal tx_fifo_re : std_logic;
signal tx_fifo_re_next : std_logic;
signal tx_fifo_we : std_logic;
signal tx_fifo_empty : std_logic;
signal tx_fifo_almost_empty : std_logic;
signal tx_fifo_full : std_logic;
signal tx_fifo_prog_full : std_logic;
signal tx_fifo_din : std_logic_vector(0 to DATA_WIDTH-1);
signal tx_fifo_dout : std_logic_vector(0 to DATA_WIDTH-1);
signal tx_fifo_data_count : std_logic_vector(0 to 9);
-----------------------------------------------------------------------------
-- Replay FIFO Signals
-----------------------------------------------------------------------------
signal replay_buffer_clear : std_logic;
signal replay_buffer_clear_next: std_logic;
-----------------------------------------------------------------------------
-- FIFO Declarations
-----------------------------------------------------------------------------
component read_write_fifo
port (
clk: IN std_logic;
rst: IN std_logic;
rd_en: IN std_logic;
din: IN std_logic_VECTOR(31 downto 0);
wr_en: IN std_logic;
dout: OUT std_logic_VECTOR(31 downto 0);
almost_empty: OUT std_logic;
empty: OUT std_logic;
full: OUT std_logic;
prog_full: OUT std_logic
);
end component;
component rx_tx_fifo
port (
clk: IN std_logic;
rst: IN std_logic;
rd_en: IN std_logic;
din: IN std_logic_VECTOR(31 downto 0);
wr_en: IN std_logic;
dout: OUT std_logic_VECTOR(31 downto 0);
almost_empty: OUT std_logic;
empty: OUT std_logic;
full: OUT std_logic;
prog_full: OUT std_logic;
data_count: OUT std_logic_vector(9 downto 0)
);
end component;
-----------------------------------------------------------------------------
-- SATA PHY Declaration
-----------------------------------------------------------------------------
component sata_phy
port (
oob_control_ila_control: in std_logic_vector(35 downto 0);
sata_phy_ila_control : in std_logic_vector(35 downto 0);
REFCLK_PAD_P_IN : in std_logic; -- MGTCLKA, clocks GTP_X0Y0-2
REFCLK_PAD_N_IN : in std_logic; -- MGTCLKA
GTXRESET_IN : in std_logic; -- GTP initialization
PLLLKDET_OUT_N : out std_logic;
TXP0_OUT : out std_logic;
TXN0_OUT : out std_logic;
RXP0_IN : in std_logic;
RXN0_IN : in std_logic;
DCMLOCKED_OUT : out std_logic;
LINKUP : out std_logic;
LINKUP_led : out std_logic;
sata_user_clk : out std_logic;
GEN2_led : out std_logic;
align_en_out : out std_logic;
tx_datain : in std_logic_vector(DATA_WIDTH-1 downto 0);
tx_charisk_in : in std_logic;
rx_dataout : out std_logic_vector(DATA_WIDTH-1 downto 0);
rx_charisk_out : out std_logic_vector(3 downto 0);
CurrentState_out : out std_logic_vector(7 downto 0);
rxelecidle_out : out std_logic;
CLKIN_150 : in std_logic
);
end component;
component sata_rx_frame_ila
port (
control : in std_logic_vector(35 downto 0);
clk : in std_logic;
trig0 : in std_logic_vector(3 downto 0);
trig1 : in std_logic_vector(31 downto 0);
trig2 : in std_logic_vector(7 downto 0);
trig3 : in std_logic_vector(3 downto 0);
trig4 : in std_logic_vector(3 downto 0);
trig5 : in std_logic_vector(7 downto 0);
trig6 : in std_logic_vector(31 downto 0);
trig7 : in std_logic_vector(31 downto 0);
trig8 : in std_logic_vector(31 downto 0);
trig9 : in std_logic_vector(31 downto 0);
trig10 : in std_logic_vector(31 downto 0);
trig11 : in std_logic_vector(7 downto 0);
trig12 : in std_logic_vector(15 downto 0);
trig13 : in std_logic_vector(15 downto 0);
trig14 : in std_logic_vector(15 downto 0);
trig15 : in std_logic_vector(31 downto 0)
);
end component;
component sata_tx_frame_ila
port (
control : in std_logic_vector(35 downto 0);
clk : in std_logic;
trig0 : in std_logic_vector(3 downto 0);
trig1 : in std_logic_vector(31 downto 0);
trig2 : in std_logic_vector(31 downto 0);
trig3 : in std_logic_vector(31 downto 0);
trig4 : in std_logic_vector(3 downto 0);
trig5 : in std_logic_vector(31 downto 0);
trig6 : in std_logic_vector(31 downto 0);
trig7 : in std_logic_vector(31 downto 0);
trig8 : in std_logic_vector(15 downto 0);
trig9 : in std_logic_vector(15 downto 0);
trig10 : in std_logic_vector(31 downto 0);
trig11 : in std_logic_vector(31 downto 0);
trig12 : in std_logic_vector(31 downto 0);
trig13 : in std_logic_vector(15 downto 0);
trig14 : in std_logic_vector(15 downto 0);
trig15 : in std_logic_vector(9 downto 0)
);
end component;
-------------------------------------------------------------------------------
-- BEGIN
-------------------------------------------------------------------------------
begin
-------------------------------------------------------------------------------
-- LINK LAYER
-------------------------------------------------------------------------------
-----------------------------------------------------------------------------
-- PROCESS: MASTER_FSM_VALUE_PROC
-- PURPOSE: ChipScope State Indicator Signal
-----------------------------------------------------------------------------
MASTER_FSM_VALUE_PROC : process (master_fsm_curr) is
begin
case (master_fsm_curr) is
when idle => master_fsm_value <= x"0";
when capture_dev_sign => master_fsm_value <= x"1";
when wait_for_cmd => master_fsm_value <= x"2";
when H2D_REG_FIS => master_fsm_value <= x"3";
when D2H_DMA_ACT_FIS => master_fsm_value <= x"4";
when H2D_DATA_FIS => master_fsm_value <= x"5";
when D2H_DATA_FIS => master_fsm_value <= x"6";
when D2H_REG_FIS => master_fsm_value <= x"7";
when D2H_PIO_SETUP => master_fsm_value <= x"8";
when dead => master_fsm_value <= x"9";
when others => master_fsm_value <= x"A";
end case;
end process MASTER_FSM_VALUE_PROC;
-----------------------------------------------------------------------------
-- PROCESS: MASTER_FSM_STATE_PROC
-- PURPOSE: Registering Signals and Next State
-----------------------------------------------------------------------------
MASTER_FSM_STATE_PROC : process (sata_user_clk)
begin
if ((sata_user_clk'event) and (sata_user_clk = '1')) then
if (sw_reset = '1') then
--Initializing internal signals
master_fsm_curr <= idle;
FIS_count_value <= (others => '0');
start_rx <= '0';
start_tx <= '0';
new_cmd <= '0';
ready_for_cmd <= '0';
else
-- Register all Current Signals to their _next Signals
master_fsm_curr <= master_fsm_next;
FIS_count_value <= FIS_count_value_next;
start_rx <= start_rx_next;
start_tx <= start_tx_next;
ready_for_cmd <= ready_for_cmd_next;
if (new_cmd_in = '1') then
new_cmd <= '1';
else
new_cmd <= '0';
end if;
end if;
end if;
end process MASTER_FSM_STATE_PROC;
-----------------------------------------------------------------------------
-- PROCESS: MASTER_FSM_LOGIC_PROC
-- PURPOSE: Implements a Sequence of FIS transfers for sending READ/WRITE sector
-- command. (Transport Layer)
-----------------------------------------------------------------------------
MASTER_FSM_LOGIC_PROC : process (master_fsm_curr, rx_done, tx_done, tx_err,
LINKUP, new_cmd, tx_sector_count
) is
begin
-- Register _next to current signals
master_fsm_next <= master_fsm_curr;
FIS_count_value_next <= (others => '0');
start_rx_next <= start_rx;
start_tx_next <= start_tx;
---------------------------------------------------------------------------
-- Finite State Machine
---------------------------------------------------------------------------
case (master_fsm_curr) is
-- x0
when idle =>
if (LINKUP = '1') then
start_rx_next <= '1';
master_fsm_next <= capture_dev_sign;
end if;
-- x1
when capture_dev_sign =>
start_rx_next <= '0';
if (rx_done = '1') then
master_fsm_next <= wait_for_cmd;
end if;
-- x2
when wait_for_cmd =>
if (new_cmd = '1') then
start_tx_next <= '1';
master_fsm_next <= H2D_REG_FIS;
end if;
-- x3
when H2D_REG_FIS =>
FIS_count_value_next <= COMMAND_FIS;
start_tx_next <= '0';
if (tx_done = '1') then
start_rx_next <= '1';
case (cmd_type) is
when IDEN_DEV =>
master_fsm_next <= D2H_PIO_SETUP;
when READ_DMA =>
master_fsm_next <= D2H_DATA_FIS;
when WRITE_DMA =>
master_fsm_next <= D2H_DMA_ACT_FIS;
when others =>
master_fsm_next <= D2H_REG_FIS;
end case;
end if;
if(tx_err = '1') then
start_tx_next <= '1';
master_fsm_next <= H2D_REG_FIS;
end if;
-- x4
when D2H_DMA_ACT_FIS =>
start_rx_next <= '0';
if (rx_done = '1') then
start_tx_next <= '1';
master_fsm_next <= H2D_DATA_FIS;
end if;
-- x5
when H2D_DATA_FIS =>
--FIS_count_value_next <= conv_std_logic_vector(((SECTOR_NDWORDS * sector_count) + 1), 16);
FIS_count_value_next <= (NDWORDS_PER_DATA_FIS + 1);
start_tx_next <= '0';
if ((tx_done = '1') or (tx_err = '1')) then
start_rx_next <= '1';
if (tx_sector_count >= conv_std_logic_vector(sector_count, 16)) then
master_fsm_next <= D2H_REG_FIS;
else
master_fsm_next <= D2H_DMA_ACT_FIS;
end if;
end if;
-- x6
when D2H_DATA_FIS =>
start_rx_next <= '0';
if (rx_done = '1') then
if (cmd_type = READ_DMA) then
start_rx_next <= '1';
master_fsm_next <= D2H_REG_FIS;
else
master_fsm_next <= wait_for_cmd;
end if;
end if;
-- x7
when D2H_REG_FIS =>
start_rx_next <= '0';
if (rx_done = '1') then
master_fsm_next <= wait_for_cmd;
end if;
-- x8
when D2H_PIO_SETUP =>
start_rx_next <= '0';
if (rx_done = '1') then
start_rx_next <= '1';
master_fsm_next <= D2H_DATA_FIS;
end if;
-- x9
when dead =>
master_fsm_next <= dead;
-- xA
when others =>
master_fsm_next <= dead;
end case;
end process MASTER_FSM_LOGIC_PROC;
ready_for_cmd_next <= '1' when (master_fsm_curr = wait_for_cmd) else '0';
ready_for_cmd_out <= ready_for_cmd;
-----------------------------------------------------------------------------
-- PROCESS: RX_FRAME_VALUE_PROC
-- PURPOSE: ChipScope State Indicator Signal
-----------------------------------------------------------------------------
RX_FRAME_VALUE_PROC : process (rx_frame_curr) is
begin
case (rx_frame_curr) is
when idle => rx_frame_value <= x"0";
when send_R_RDY => rx_frame_value <= x"1";
when send_R_IP => rx_frame_value <= x"2";
when send_HOLD_ACK => rx_frame_value <= x"3";
when send_R_OK => rx_frame_value <= x"4";
when send_SYNC => rx_frame_value <= x"5";
when wait_for_X_RDY => rx_frame_value <= x"6";
when dead => rx_frame_value <= x"7";
when others => rx_frame_value <= x"8";
end case;
end process RX_FRAME_VALUE_PROC;
-----------------------------------------------------------------------------
-- PROCESS: RX_FRAME_STATE_PROC
-- PURPOSE: Registering Signals and Next State
-----------------------------------------------------------------------------
RX_FRAME_STATE_PROC : process (sata_user_clk)
begin
if ((sata_user_clk'event) and (sata_user_clk = '1')) then
if (sw_reset = '1') then
--Initializing internal signals
rx_frame_curr <= idle;
sync_count_rx <= (others => '0');
rx_done <= '0';
rx_fifo_we <= '0';
prim_type_rx <= (others => '0');
ALIGN_det_r <= '0';
ALIGN_det_r2 <= '0';
HOLD_det_r <= '0';
HOLD_det_r2 <= '0';
HOLD_det_r3 <= '0';
HOLD_det_r4 <= '0';
TWO_HOLD_det_r <= '0';
else
-- Register all Current Signals to their _next Signals
rx_frame_curr <= rx_frame_next;
sync_count_rx <= sync_count_rx_next;
rx_done <= rx_done_next;
rx_fifo_we <= rx_fifo_we_next;
prim_type_rx <= prim_type_rx_next;
ALIGN_det_r <= ALIGN_det;
ALIGN_det_r2 <= ALIGN_det_r;
HOLD_det_r <= HOLD_det;
HOLD_det_r2 <= HOLD_det_r;
HOLD_det_r3 <= HOLD_det_r2;
HOLD_det_r4 <= HOLD_det_r3;
TWO_HOLD_det_r <= TWO_HOLD_det;
end if;
end if;
end process RX_FRAME_STATE_PROC;
-----------------------------------------------------------------------------
-- PROCESS: RX_FRAME_LOGIC_PROC
-- PURPOSE: Receive FRAME from disk and unpack the FIS
-----------------------------------------------------------------------------
RX_FRAME_LOGIC_PROC : process (rx_frame_curr, sync_count_rx, ALIGN_det, HOLD_det,
HOLD_stop_after_ALIGN_det,
SOF_det, EOF_det, HOLD_start_det, HOLD_stop_det, SYNC_det,
start_rx, LINKUP, rx_datain, rx_sector_count, sector_count
) is
begin
-- Register _next to current signals
rx_frame_next <= rx_frame_curr;
sync_count_rx_next <= sync_count_rx;
rx_done_next <= rx_done;
prim_type_rx_next <= prim_type_rx;
rx_fifo_we_next <= '0';
---------------------------------------------------------------------------
-- Finite State Machine
---------------------------------------------------------------------------
case (rx_frame_curr) is
-- x0
when idle =>
rx_done_next <= '0';
prim_type_rx_next <= SYNC;
if (start_rx = '1') then
--if (master_fsm_curr = capture_dev_sign) then
rx_frame_next <= send_R_RDY;
--else
-- rx_frame_next <= wait_for_X_RDY;
--end if;
end if;
-- x6
--Wait for X_RDY before sending R_RDY
when wait_for_X_RDY =>
prim_type_rx_next <= SYNC;
if (X_RDY_det = '1') then
rx_frame_next <= send_R_RDY;
end if;
-- x1
when send_R_RDY =>
--Send R_RDY to get device signature
prim_type_rx_next <= R_RDY;
if (SOF_det = '1') then
rx_frame_next <= send_R_IP;
end if;
-- x2
when send_R_IP =>
--Send R_IP to indicate Reception in Progress
prim_type_rx_next <= R_IP;
rx_fifo_we_next <= '1';
if (ALIGN_det = '1' or HOLD_det = '1') then
rx_fifo_we_next <= '0';
end if;
if (EOF_det = '1') then
rx_fifo_we_next <= '0';
rx_frame_next <= send_R_OK;
end if;
-- Check for 2 HOLD primitives followed by CONT which indicates FIS pause
if (HOLD_start_det = '1') then
rx_fifo_we_next <= '0';
rx_frame_next <= send_HOLD_ACK;
end if;
-- x3
when send_HOLD_ACK =>
-- Send HOLD ACK to Acknowledge FIS pause
prim_type_rx_next <= HOLD_ACK;
if (HOLD_stop_after_ALIGN_det = '1') then
rx_fifo_we_next <= '1';
rx_frame_next <= send_R_IP;
end if;
if (HOLD_stop_det = '1') then
rx_frame_next <= send_R_IP;
end if;
-- x4
when send_R_OK =>
-- Send R_OK to indicate good frame
prim_type_rx_next <= R_OK;
if (SYNC_det = '1') then
if (master_fsm_curr = D2H_DATA_FIS) then
if (rx_sector_count < conv_std_logic_vector(sector_count,16)) then
rx_frame_next <= send_R_RDY;
else
rx_done_next <= '1';
rx_frame_next <= idle;
end if;
else
rx_frame_next <= send_SYNC;
end if;
end if;
-- x5
when send_SYNC =>
-- Send SYNC to indicate host idle
prim_type_rx_next <= SYNC;
if (sync_count_rx = SYNC_COUNT_VALUE) then
rx_done_next <= '1';
sync_count_rx_next <= (others => '0');
rx_frame_next <= idle;
else
sync_count_rx_next <= sync_count_rx + 1;
end if;
-- x6
when dead =>
rx_frame_next <= dead;
-- x7
when others =>
rx_frame_next <= dead;
end case;
end process RX_FRAME_LOGIC_PROC;
-- Counter for number of received sectors (used when number of RX sectors exceeds max 16 in one data FIS)
RX_SECTOR_CNT: process(sata_user_clk) is
begin
if ((sata_user_clk'event) and (sata_user_clk = '1')) then
if (sw_reset = '1' or new_cmd = '1') then
dword_count <= (others => '0');
rx_sector_count <= (others => '0');
elsif ((dword_count < (SECTOR_NDWORDS-1)) and (master_fsm_curr = D2H_DATA_FIS) and (rx_fifo_we_next = '1')) then
dword_count <= dword_count + 1;
elsif (dword_count = (SECTOR_NDWORDS-1)) then
dword_count <= (others => '0');
rx_sector_count <= rx_sector_count + 1;
elsif (EOF_det = '1') then
dword_count <= (others => '0');
else
dword_count <= dword_count;
rx_sector_count <= rx_sector_count;
end if;
end if;
end process RX_SECTOR_CNT;
-- DATA FIS DWORD Counter for stripping off DATA FIS header and CRC
DATA_FIS_DWORD_CNT: process(sata_user_clk) is
begin
if ((sata_user_clk'event) and (sata_user_clk = '1')) then
if (sw_reset = '1') then
DATA_FIS_dword_count <= (others => '0');
dword_count_init_value <= (others => '0');
elsif ((master_fsm_curr = D2H_DATA_FIS) and (DATA_FIS_dword_count < dword_count_value)) then
if (descrambler_dout_we = '1') then
DATA_FIS_dword_count <= DATA_FIS_dword_count + 1;
else
DATA_FIS_dword_count <= DATA_FIS_dword_count;
end if;
elsif ((DATA_FIS_dword_count = dword_count_value) and (master_fsm_curr = D2H_DATA_FIS)) then
if(dword_count_init_value >= NDWORDS_PER_DATA_FIS_32) then
dword_count_init_value <= (dword_count_init_value - NDWORDS_PER_DATA_FIS_32);
end if;
DATA_FIS_dword_count <= (others => '0');
else
DATA_FIS_dword_count <= (others => '0');
end if;
if(new_cmd = '1') then
dword_count_init_value <= conv_std_logic_vector((SECTOR_NDWORDS * sector_count), 32);
dword_count_value <= (others => '0');
elsif(dword_count_init_value < NDWORDS_PER_DATA_FIS_32) then
dword_count_value <= dword_count_init_value(16 to 31) + conv_std_logic_vector(1,16);
elsif(dword_count_init_value >= NDWORDS_PER_DATA_FIS_32) then
dword_count_value <= NDWORDS_PER_DATA_FIS + 1;
end if;
end if;
end process DATA_FIS_DWORD_CNT;
-----------------------------------------------------------------------------
-- PROCESS: TX_FRAME_VALUE_PROC
-- PURPOSE: ChipScope State Indicator Signal
-----------------------------------------------------------------------------
TX_FRAME_VALUE_PROC : process (tx_frame_curr) is
begin
case (tx_frame_curr) is
when idle => tx_frame_value <= x"0";
when send_X_RDY => tx_frame_value <= x"1";
when send_SOF => tx_frame_value <= x"2";
when send_FIS => tx_frame_value <= x"3";
when send_EOF => tx_frame_value <= x"4";
when send_WTRM => tx_frame_value <= x"5";
when send_SYNC => tx_frame_value <= x"6";
when send_HOLD_ACK => tx_frame_value <= x"7";
when send_HOLD => tx_frame_value <= x"8";
when dead => tx_frame_value <= x"9";
when others => tx_frame_value <= x"A";
end case;
end process TX_FRAME_VALUE_PROC;
-----------------------------------------------------------------------------
-- PROCESS: TX_FRAME_STATE_PROC
-- PURPOSE: Registering Signals and Next State
-----------------------------------------------------------------------------
TX_FRAME_STATE_PROC : process (sata_user_clk)
begin
if ((sata_user_clk'event) and (sata_user_clk = '1')) then
if (sw_reset = '1') then
--Initializing internal signals
tx_frame_curr <= idle;
sync_count_tx <= (others => '0');
rx_tx_state_sel <= '0';
tx_done <= '0';
tx_fifo_re <= '0';
frame_err <= '0';
tx_err <= '0';
replay_buffer_clear <= '0';
prim_type_tx <= (others => '0');
FIS_word_count <= (others => '0');
tx_sector_count <= (others => '0');
elsif(new_cmd = '1') then
tx_sector_count <= (others => '0');
else
-- Register all Current Signals to their _next Signals
tx_frame_curr <= tx_frame_next;
sync_count_tx <= sync_count_tx_next;
rx_tx_state_sel <= rx_tx_state_sel_next;
tx_done <= tx_done_next;
tx_fifo_re <= tx_fifo_re_next;
frame_err <= frame_err_next;
tx_err <= tx_err_next;
replay_buffer_clear <= replay_buffer_clear_next;
prim_type_tx <= prim_type_tx_next;
FIS_word_count <= FIS_word_count_next;
tx_sector_count <= tx_sector_count_next;
end if;
end if;
end process TX_FRAME_STATE_PROC;
-----------------------------------------------------------------------------
-- PROCESS: TX_FRAME_LOGIC_PROC
-- PURPOSE: Next State and Output Logic
-----------------------------------------------------------------------------
TX_FRAME_LOGIC_PROC : process (tx_frame_curr, FIS_word_count, sector_count,
tx_sector_count,
R_RDY_det, R_OK_det, sync_count_tx, start_tx,
LINKUP, frame_err
) is
begin
-- Register _next to current signals
tx_frame_next <= tx_frame_curr;
sync_count_tx_next <= sync_count_tx;
rx_tx_state_sel_next <= rx_tx_state_sel;
tx_fifo_re_next <= tx_fifo_re;
tx_done_next <= tx_done;
frame_err_next <= frame_err;
tx_err_next <= tx_err;
replay_buffer_clear_next <= replay_buffer_clear;
prim_type_tx_next <= prim_type_tx;
FIS_word_count_next <= FIS_word_count;
tx_sector_count_next <= tx_sector_count;
tx_charisk_TX_FRAME <= '1';
---------------------------------------------------------------------------
-- Finite State Machine
---------------------------------------------------------------------------
case (tx_frame_curr) is
-- x0
when idle =>
tx_done_next <= '0';
tx_err_next <= '0';
replay_buffer_clear_next <= '0';
prim_type_tx_next <= SYNC;
FIS_word_count_next <= (others => '0');
if (start_tx = '1') then
rx_tx_state_sel_next <= '1';
tx_frame_next <= send_X_RDY;
end if;
-- x1
when send_X_RDY =>
-- Send X_RDY to indicate host ready to transmit
prim_type_tx_next <= X_RDY;
if (R_RDY_det = '1') then
tx_frame_next <= send_SOF;
end if;
-- x2
when send_SOF =>
--Send SOF to indicate start of new FRAME
prim_type_tx_next <= SOF;
if (align_en_out = '0') then
tx_frame_next <= send_FIS;
end if;
-- x3
when send_FIS =>
tx_charisk_TX_FRAME <= '0';
--Send FIS data
prim_type_tx_next <= FIS;
-- ALIGN primitives after 256 DWORDS
if (align_en_out = '1' or tx_fifo_almost_empty = '1') then
FIS_word_count_next <= FIS_word_count;
tx_fifo_re_next <= '0';
else
FIS_word_count_next <= FIS_word_count + '1';
tx_fifo_re_next <= '1';
end if;
-- Receive buffer empty condition
if (HOLD_start_det = '1') then
tx_frame_next <= send_HOLD_ACK;
end if;
-- Transmit buffer empty condition
if (tx_fifo_almost_empty = '1') then
if (align_en_out = '0') then
tx_charisk_TX_FRAME <= '1';
prim_type_tx_next <= HOLD;
tx_frame_next <= send_HOLD;
end if;
end if;
-- Transmitted sector count
if(((conv_integer(FIS_word_count) mod SECTOR_NDWORDS)=0) and (conv_integer(FIS_word_count)>0) and (align_en_out='0') and (tx_fifo_almost_empty='0')) then
tx_sector_count_next <= tx_sector_count + 1;
else
tx_sector_count_next <= tx_sector_count;
end if;
if ((tx_sector_count >= conv_std_logic_vector(sector_count, 16)) or (FIS_word_count >= FIS_count_value)) then
if (align_en_out = '0') then
tx_charisk_TX_FRAME <= '0';
FIS_word_count_next <= (others => '0');
tx_fifo_re_next <= '1';
prim_type_tx_next <= FIS;
tx_frame_next <= send_EOF;
end if;
end if;
-- x7
when send_HOLD_ACK =>
-- Send HOLD ACK to Acknowledge FIS pause
prim_type_tx_next <= HOLD_ACK;
tx_fifo_re_next <= '0';
--if (HOLD_stop_det = '1') then
if (R_IP_det = '1') then
tx_frame_next <= send_FIS;
end if;
-- x8
when send_HOLD =>
-- Send HOLD to indicate transmit buffer empty
prim_type_tx_next <= HOLD;
tx_fifo_re_next <= '0';
if (tx_fifo_empty = '0') then
tx_frame_next <= send_FIS;
end if;
-- x4
when send_EOF =>
--Send EOF to indicate end of FRAME
tx_fifo_re_next <= '0';
prim_type_tx_next <= EOF;
if (align_en_out = '0') then
tx_frame_next <= send_WTRM;
end if;
-- x5
when send_WTRM =>
-- Send WTRM to indicate Waiting for Frame Termination
prim_type_tx_next <= WTRM;
if (R_OK_det = '1' or R_ERR_det = '1' or SYNC_det = '1') then
if (R_ERR_det = '1' or SYNC_det = '1') then
if (master_fsm_curr = H2D_REG_FIS) then
frame_err_next <= '1';
else
frame_err_next <= '0';
end if;
end if;
if (R_OK_det = '1') then
replay_buffer_clear_next <= '1';
frame_err_next <= '0';
end if;
tx_frame_next <= send_SYNC;
end if;
-- x6
when send_SYNC =>
-- Send SYNC to indicate host idle
prim_type_tx_next <= SYNC;
if (sync_count_tx = SYNC_COUNT_VALUE) then
sync_count_tx_next <= (others => '0');
if (frame_err = '1') then
tx_err_next <= '1';
else
tx_done_next <= '1';
end if;
rx_tx_state_sel_next <= '0';
tx_frame_next <= idle;
else
sync_count_tx_next <= sync_count_tx + 1;
end if;
-- x8
when dead =>
tx_frame_next <= dead;
-- x9
when others =>
tx_frame_next <= dead;
end case;
end process TX_FRAME_LOGIC_PROC;
-- ASYNCHRONOUS MUXES
tx_charisk_RX_FRAME <= '1';
--tx_charisk_TX_FRAME <= '0' when (((tx_frame_curr = send_FIS) and (tx_fifo_almost_empty = '0')) or ((tx_frame_curr=send_FIS) and
-- (tx_fifo_almost_empty = '1') and (master_fsm_curr = H2D_REG_FIS))) else '1';
--tx_charisk_out <= '0' when ((tx_frame_curr = send_FIS) or (prim_type_tx = PRIM_SCRM)) else tx_charisk_RX_FRAME when (rx_tx_state_sel = '0') else tx_charisk_TX_FRAME;
tx_charisk_out <= tx_charisk_RX_FRAME when (rx_tx_state_sel = '0') else tx_charisk_TX_FRAME;
prim_type <= prim_type_rx when (rx_tx_state_sel = '0') else prim_type_tx;
-- ASYNCHRONOUS MUXES
-- Primitive detection
ALIGN_det <= '1' when (rx_datain = x"7B4A4ABC") else '0';
SYNC_det <= '1' when (rx_datain = x"B5B5957C") else '0';
R_RDY_det <= '1' when (rx_datain = x"4A4A957C") else '0';
R_IP_det <= '1' when (rx_datain = x"5555B57C") else '0';
R_OK_det <= '1' when (rx_datain = x"3535B57C") else '0';
R_ERR_det <= '1' when (rx_datain = x"5656B57C") else '0';
SOF_det <= '1' when (rx_datain = x"3737B57C") else '0';
EOF_det <= '1' when (rx_datain = x"D5D5B57C") else '0';
X_RDY_det <= '1' when (rx_datain = x"5757B57C") else '0';
WTRM_det <= '1' when (rx_datain = x"5858B57C") else '0';
CONT_det <= '1' when (rx_datain = x"9999AA7C") else '0';
HOLD_det <= '1' when (rx_datain = x"D5D5AA7C") else '0';
HOLD_start_det <= '1' when (((TWO_HOLD_det_r = '1') and (CONT_det = '1')) or (CORNER_CASE_HOLD = '1')) else '0';
TWO_HOLD_det <= '1' when ((rx_datain = x"D5D5AA7C") and (HOLD_det_r = '1')) else '0';
HOLD_stop_det <= '1' when ((rx_datain = x"D5D5AA7C") and (ALIGN_det_r = '0') and (TWO_HOLD_det = '0')) else '0';
HOLD_stop_after_ALIGN_det <= '1' when ((HOLD_det_r = '1') and (ALIGN_det_r2 = '1') and (ALIGN_det_r = '0') and (TWO_HOLD_det = '0')) or ((TWO_HOLD_det_r = '1') and (CONT_det = '0')) else '0';
-- Corner Case
-- ALIGN primitives are received between two HOLD primitives or between 2 HOLD and a CONT primitive
CORNER_CASE_HOLD <= '1' when ((CONT_det = '1') and (HOLD_det_r4 = '1')) else '0';
-- SATA Primitives
-- SYNC
tx_sync <= x"B5B5957C";
-- R_RDY
tx_r_rdy <= x"4A4A957C";
-- R_OK
tx_r_ok <= x"3535B57C";
-- R_ERR
tx_r_err <= x"5656B57C";
-- R_IP
tx_r_ip <= x"5555B57C";
-- X_RDY
tx_x_rdy <= x"5757B57C";
-- CONT
tx_cont <= x"9999AA7C";
-- WTRM
tx_wtrm <= x"5858B57C";
-- SOF
tx_sof <= x"3737B57C";
-- EOF
tx_eof <= x"D5D5B57C";
-- HOLD
tx_hold <= x"D5D5AA7C";
-- HOLD_ACK
tx_hold_ack <= x"9595AA7C";
-- Output Mux
OUTPUT_MUX_i: entity work.mux_161
generic map
(
DATA_WIDTH => 32
)
port map
(
a => tx_sync,
b => tx_r_rdy,
c => tx_r_ip,
d => tx_r_ok,
e => tx_r_err,
f => tx_x_rdy,
g => tx_wtrm,
h => tx_hold,
i => tx_hold_ack,
j => tx_cont,
k => tx_sof,
l => tx_eof,
m => tx_fifo_dout,
--n => tx_prim_scrm,
n => (others => '0'),
o => (others => '0'),
p => (others => '0'),
sel=> output_mux_sel,
output=> tx_dataout
);
output_mux_sel <= prim_type;
-------------------------------------------------------------------------------
-- LINK LAYER
-------------------------------------------------------------------------------
---------------------------------------------------------------------------
-- Pre-DeScramble RX FIFO from PHY Layer
---------------------------------------------------------------------------
rx_fifo_din <= rx_datain;
rx_fifo_re <= descrambler_din_re_r;
rx_fifo_reset <= sw_reset or descrambler_reset;
RX_FIFO : rx_tx_fifo
port map (
clk => sata_user_clk,
rst => rx_fifo_reset,
rd_en => rx_fifo_re,
din => rx_fifo_din,
wr_en => rx_fifo_we_next,
dout => rx_fifo_dout,
almost_empty => rx_fifo_almost_empty,
empty => rx_fifo_empty,
full => rx_fifo_full,
prog_full => rx_fifo_prog_full,
data_count => rx_fifo_data_count
);
---------------------------------------------------------------------------
-- DESCRAMBLER
---------------------------------------------------------------------------
--descrambler_din(0 to 15) <= rx_fifo_dout(16 to 31);
--descrambler_din(16 to 31) <= rx_fifo_dout(0 to 15);
descrambler_din <= rx_fifo_dout;
descrambler_en <= not(rx_fifo_almost_empty);
descrambler_reset <= '1' when ((start_rx='1') or ((rx_frame_curr = send_R_OK) and (SYNC_det = '1'))) else '0';
DESCRAMBLER_i: entity work.scrambler
generic map(
CHIPSCOPE => FALSE
)
port map(
-- Clock and Reset Signals
clk => sata_user_clk,
reset => descrambler_reset,
-- ChipScope ILA / Trigger Signals
scrambler_ila_control => descrambler_ila_control,
---------------------------------------
-- Signals from/to Sata Link Layer FIFOs
prim_scrambler => '0',
scrambler_en => descrambler_en,
din_re => descrambler_din_re,
data_in => descrambler_din,
data_out => descrambler_dout,
dout_we => descrambler_dout_we
);
---------------------------------------------------------------------------
-- Post-DeScramble Read FIFO to Command Layer
---------------------------------------------------------------------------
read_fifo_din <= descrambler_dout;
read_fifo_we <= descrambler_dout_we when ((master_fsm_curr = D2H_DATA_FIS) and (DATA_FIS_dword_count > 0) and (DATA_FIS_dword_count < dword_count_value)) else '0';
READ_FIFO_i : read_write_fifo
port map (
clk => sata_user_clk,
rst => sw_reset,
rd_en => read_fifo_re,
din => read_fifo_din,
wr_en => read_fifo_we,
dout => read_fifo_dout,
almost_empty => read_fifo_almost_empty,
empty => read_fifo_empty_i,
full => read_fifo_full,
prog_full => read_fifo_prog_full
);
-- Data Output to Command Layer
sata_dout <= read_fifo_dout;
-- Input from Command Layer
read_fifo_re <= sata_dout_re;
read_fifo_empty <= read_fifo_empty_i;
---------------------------------------------------------------------------
-- Pre-Scramble Write FIFO from Command Layer
---------------------------------------------------------------------------
write_fifo_we <= sata_din_we;
write_fifo_din <= sata_din;
write_fifo_full <= write_fifo_prog_full;
--write_fifo_re <= scrambler_din_re_r when (scrambler_en = '1') else '0';
write_fifo_re <= scrambler_din_re_r when ((scrambler_en='1') and (scrambler_count_en_reg_fis='1')) or ((scrambler_count < scrambler_count_value) and (scrambler_count_en_data_fis = '1') and (write_fifo_empty = '0')) else '0';
WRITE_FIFO_i : read_write_fifo
port map (
clk => sata_user_clk,
rst => sw_reset,
din => write_fifo_din,
wr_en => write_fifo_we,
dout => write_fifo_dout,
rd_en => write_fifo_re,
almost_empty => write_fifo_almost_empty,
empty => write_fifo_empty,
full => write_fifo_full_i,
prog_full => write_fifo_prog_full
);
---------------------------------------------------------------------------
-- CRC
---------------------------------------------------------------------------
crc_reset <= scrambler_reset;
crc_en <= scrambler_dout_we;
crc_din <= write_fifo_dout;
CRC_i : entity work.crc
generic map (
CHIPSCOPE => FALSE
)
port map (
clk => sata_user_clk,
reset => crc_reset,
--crc_ila_control => crc_ila_control,
crc_en => crc_en,
data_in => crc_din,
data_out => crc_dout
);
---------------------------------------------------------------------------
-- SCRAMBLER
---------------------------------------------------------------------------
REGISTER_PROCESS : process(sata_user_clk) is
begin
if sata_user_clk'event and sata_user_clk = '1' then
if sw_reset = '1' then
scrambler_din_re_r <= '0';
descrambler_din_re_r <= '0';
crc_dout_r <= (others => '0');
else
scrambler_din_re_r <= scrambler_din_re;
descrambler_din_re_r <= descrambler_din_re;
crc_dout_r <= crc_dout;
end if;
end if;
end process REGISTER_PROCESS;
scrambler_count_en_reg_fis <= '1' when (master_fsm_curr = H2D_REG_FIS) else '0';
scrambler_count_en_data_fis <= '1' when ((master_fsm_curr = H2D_DATA_FIS) or ((master_fsm_curr = D2H_DMA_ACT_FIS) and (tx_sector_count > 0))) else '0';
-- To disable scrambler after the REG FIS
SCRAMBLER_CNT: process(sata_user_clk) is
begin
if ((sata_user_clk'event) and (sata_user_clk = '1')) then
if (sw_reset = '1') then
scrambler_count <= (others => '0');
scrambler_count_init_value <= (others => '0');
scrambler_count_value <= (others => '0');
scrambler_reset_after_FIS <= '0';
elsif ((scrambler_count < (REG_FIS_NDWORDS)) and (scrambler_count_en_reg_fis = '1')) then
scrambler_count <= scrambler_count + 1;
elsif ((scrambler_count < scrambler_count_value) and (scrambler_count_en_data_fis = '1') and (tx_fifo_we = '1') and (write_fifo_empty = '0')) then
scrambler_count <= scrambler_count + 1;
if (scrambler_count = NDWORDS_PER_DATA_FIS) then
scrambler_reset_after_FIS <= '1';
end if;
elsif (( scrambler_count = (NDWORDS_PER_DATA_FIS+1)) and (scrambler_count_en_data_fis = '1')) then
scrambler_count_init_value <= (scrambler_count_init_value - NDWORDS_PER_DATA_FIS_32);
scrambler_count <= (others => '0');
scrambler_reset_after_FIS <= '0';
else
scrambler_count <= scrambler_count;
end if;
if (scrambler_reset = '1') then
scrambler_count <= (others => '0');
scrambler_reset_after_FIS <= '0';
end if;
if(new_cmd = '1') then
scrambler_count_init_value <= conv_std_logic_vector((SECTOR_NDWORDS * sector_count), 32);
scrambler_count_value <= (others => '0');
elsif(scrambler_count_init_value < NDWORDS_PER_DATA_FIS_32) then
scrambler_count_value <= scrambler_count_init_value(16 to 31) + conv_std_logic_vector(1,16);
elsif(scrambler_count_init_value >= NDWORDS_PER_DATA_FIS_32) then
scrambler_count_value <= NDWORDS_PER_DATA_FIS + 1;
end if;
end if;
end process SCRAMBLER_CNT;
scrambler_reset <= (sw_reset or new_cmd or scrambler_reset_after_FIS or (tx_done and scrambler_count_en_reg_fis)) ;
scrambler_din <= crc_dout_r when ((scrambler_count = REG_FIS_NDWORDS) and (scrambler_count_en_reg_fis = '1')) or ((scrambler_count = scrambler_count_value) and (scrambler_count_en_data_fis = '1')) else write_fifo_dout;
scrambler_en <= not(write_fifo_empty) when (((scrambler_count_en_reg_fis = '1') and (scrambler_count < REG_FIS_NDWORDS))
--or ((scrambler_count_en_data_fis = '1') and (scrambler_count = NDWORDS_PER_DATA_FIS) and (tx_fifo_prog_full = '1'))
or ((scrambler_count_en_data_fis = '1') and (scrambler_count = (scrambler_count_value - '1'))))
else not(write_fifo_almost_empty) when ((scrambler_count_en_data_fis = '1') and (scrambler_count < scrambler_count_value) and (tx_fifo_prog_full = '0'))
else '0';
-- Corner Case: tx_fifo_almost_full goes high when (scrambler_count = NDWORDS_PER_DATA_FIS)
SCRAMBLER_i: entity work.scrambler
generic map(
CHIPSCOPE => FALSE
)
port map(
-- Clock and Reset Signals
clk => sata_user_clk,
reset => scrambler_reset,
-- ChipScope ILA / Trigger Signals
scrambler_ila_control => scrambler_ila_control,
---------------------------------------
-- Signals from/to Sata Link Layer FIFOs
prim_scrambler => '0',
scrambler_en => scrambler_en,
din_re => scrambler_din_re,
data_in => scrambler_din,
data_out => scrambler_dout,
dout_we => scrambler_dout_we
);
---------------------------------------------------------------------------
-- Post-Scramble TX FIFO to PHY Layer
---------------------------------------------------------------------------
-- Input Signals from User Logic
tx_fifo_din <= scrambler_dout;
tx_fifo_we <= scrambler_dout_we;
TX_FIFO: rx_tx_fifo
port map (
clk => sata_user_clk,
rst => sw_reset,
rd_en => tx_fifo_re,
din => tx_fifo_din,
wr_en => tx_fifo_we,
dout => tx_fifo_dout,
almost_empty => tx_fifo_almost_empty,
empty => tx_fifo_empty,
full => tx_fifo_full,
prog_full => tx_fifo_prog_full,
data_count => tx_fifo_data_count
);
---------------------------------------------------------------------------
-- Sata Phy Instantiation
---------------------------------------------------------------------------
SATA_PHY_i : sata_phy
port map (
oob_control_ila_control=> oob_control_ila_control,
sata_phy_ila_control => sata_phy_ila_control,
REFCLK_PAD_P_IN => REFCLK_PAD_P_IN ,
REFCLK_PAD_N_IN => REFCLK_PAD_N_IN ,
GTXRESET_IN => GTX_RESET_IN ,
PLLLKDET_OUT_N => PLLLKDET_OUT_N ,
TXP0_OUT => TXP0_OUT,
TXN0_OUT => TXN0_OUT,
RXP0_IN => RXP0_IN ,
RXN0_IN => RXN0_IN ,
DCMLOCKED_OUT => DCMLOCKED_OUT,
LINKUP => LINKUP ,
LINKUP_led => LINKUP_led ,
sata_user_clk => sata_user_clk ,
GEN2_led => GEN2_led_i ,
align_en_out => align_en_out,
tx_datain => tx_dataout,
tx_charisk_in => tx_charisk_out,
rx_dataout => rx_datain,
rx_charisk_out => rx_charisk_in,
CurrentState_out => OOB_state,
rxelecidle_out => rxelecidle,
CLKIN_150 => CLKIN_150
);
sata_user_clk_out <= sata_user_clk;
-----------------------------------------------------------------------------
-- ILA Instantiations
-----------------------------------------------------------------------------
chipscope_gen_ila : if (CHIPSCOPE) generate
SATA_RX_FRAME_ILA_i : sata_rx_frame_ila
port map (
control => sata_rx_frame_ila_control,
clk => sata_user_clk,
trig0 => rx_frame_value,
trig1 => tx_dataout,
trig2 => sync_count_rx,
trig3 => master_fsm_value,
trig4 => rx_charisk_in,
trig5 => OOB_state,
trig6 => rx_datain,
trig7 => rx_fifo_dout,
trig8 => read_fifo_din,
trig9 => read_fifo_dout,
trig10(0) => SOF_det,
trig10(1) => EOF_det,
trig10(2) => X_RDY_det,
trig10(3) => WTRM_det,
trig10(4) => HOLD_start_det,
trig10(5) => HOLD_stop_det,
trig10(6) => SYNC_det,
trig10(7) => CONT_det,
trig10(8) => ALIGN_det,
trig10(9) => new_cmd,
trig10(10) => start_rx,
trig10(11) => rx_done,
trig10(12) => descrambler_dout_we,
trig10(13) => tx_charisk_out,
trig10(14) => sw_reset,
trig10(15) => LINKUP,
trig10(16) => rx_fifo_we_next,
trig10(17) => rx_fifo_re,
trig10(18) => rx_fifo_empty,
trig10(19) => descrambler_reset,
trig10(20) => descrambler_en,
trig10(21) => read_fifo_we,
trig10(22) => read_fifo_re,
trig10(23) => rx_fifo_almost_empty,
trig10(24) => HOLD_det_r,
trig10(25) => ALIGN_det_r,
trig10(26) => TWO_HOLD_det,
trig10(27) => read_fifo_empty_i,
trig10(28) => TWO_HOLD_det_r,
trig10(29) => HOLD_det,
trig10(30) => HOLD_stop_after_ALIGN_det,
trig10(31) => ALIGN_det_r2,
trig11 => dword_count,
trig12 => rx_sector_count,
trig13 => DATA_FIS_dword_count,
trig14 => dword_count_value,
trig15 => dword_count_init_value
);
SATA_TX_FRAME_ILA_i : sata_tx_frame_ila
port map (
control => sata_tx_frame_ila_control,
clk => sata_user_clk,
trig0 => tx_frame_value,
trig1 => tx_dataout,
trig2 => rx_datain,
trig3 => tx_fifo_dout,
trig4 => master_fsm_value,
trig5 => tx_fifo_din,
trig6 => write_fifo_din,
trig7 => write_fifo_dout,
trig8 => FIS_word_count,
trig9 => scrambler_count,
trig10(0) => tx_fifo_we,
trig10(1) => tx_fifo_re,
trig10(2) => tx_fifo_full,
trig10(3) => align_en_out,
trig10(4) => SYNC_det,
trig10(5) => R_RDY_det,
trig10(6) => R_IP_det,
trig10(7) => R_OK_det,
trig10(8) => R_ERR_det,
trig10(9) => start_tx,
trig10(10) => tx_done,
trig10(11) => tx_fifo_almost_empty,
trig10(12) => tx_charisk_out,
trig10(13) => tx_fifo_empty,
trig10(14) => scrambler_din_re,
trig10(15) => ALIGN_det,
trig10(16) => HOLD_start_det,
trig10(17) => HOLD_stop_det,
trig10(18) => CONT_det,
trig10(19) => write_fifo_prog_full,
trig10(20) => tx_err,
trig10(21) => write_fifo_almost_empty,
trig10(22) => new_cmd,
trig10(23) => scrambler_reset_after_FIS,
trig10(24) => write_fifo_we,
trig10(25) => write_fifo_re,
trig10(26) => write_fifo_empty,
trig10(27) => scrambler_en,
trig10(28) => tx_fifo_prog_full,
trig10(29) => scrambler_count_en_data_fis,
trig10(30) => scrambler_reset,
trig10(31) => crc_en,
trig11 => scrambler_din,
trig12 => crc_dout,
trig13 => tx_sector_count,
trig14 => scrambler_count_value,
trig15 => tx_fifo_data_count
);
--trig14 => scrambler_count_init_value,
end generate chipscope_gen_ila;
end BEHAV;
x393_sata-05c77d236b93a06053a6ec2d8ebcad493b999f28/host/vhdl/scrambler.vhd 0000664 0000000 0000000 00000024247 12562737151 0024655 0 ustar 00root root 0000000 0000000 -- Copyright (C) 2012
-- Ashwin A. Mendon
--
-- This file is part of SATA2 core.
--
-- 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; either version 3 of the License, or
-- (at your option) any later version.
--
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-- GNU General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with this program. If not, see .
----------------------------------------------------------------------------------------
-- ENTITY: scrambler
-- Version: 1.0
-- Author: Ashwin Mendon
-- Description: This sub-module implements the Scrambler Circuit for the SATA Protocol
-- The code provides a parallel implementation of the following
-- generator polynomial
-- 16 15 13 4
-- G(x) = x + x + x + x + 1
-- The output of this scrambler is then XORed with the input data DWORD
-- The scrambler is initialized to a value of 0xF0F6.
-- The first DWORD output of the implementation is equal to 0xC2D2768D
-- PORTS:
-----------------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.STD_LOGIC_ARITH.all;
use IEEE.STD_LOGIC_UNSIGNED.all;
entity scrambler is
generic(
CHIPSCOPE : boolean := false
);
port(
-- Clock and Reset Signals
clk : in std_logic;
reset : in std_logic;
-- ChipScope ILA / Trigger Signals
scrambler_ila_control : in std_logic_vector(35 downto 0);
---------------------------------------
-- Signals from/to Sata Link Layer
scrambler_en : in std_logic;
prim_scrambler : in std_logic;
din_re : out std_logic;
data_in : in std_logic_vector(0 to 31);
data_out : out std_logic_vector(0 to 31);
dout_we : out std_logic
);
end scrambler;
-------------------------------------------------------------------------------
-- ARCHITECTURE
-------------------------------------------------------------------------------
architecture BEHAV of scrambler is
-------------------------------------------------------------------------------
-- Constants
-------------------------------------------------------------------------------
constant SCRAMBLER_INIT : std_logic_vector(0 to 15) := x"F0F6";
signal context : std_logic_vector (15 downto 0);
signal context_next : std_logic_vector (31 downto 0);
signal context_reg : std_logic_vector (31 downto 0);
signal data_out_ila : std_logic_vector (31 downto 0);
signal dout_we_reg : std_logic;
signal dout_we_ila : std_logic;
signal din_re_ila : std_logic;
-----------------------------------------------------------------------------
-- ILA Declaration
-----------------------------------------------------------------------------
component scrambler_ila
port (
control : in std_logic_vector(35 downto 0);
clk : in std_logic;
trig0 : in std_logic_vector(31 downto 0);
trig1 : in std_logic_vector(31 downto 0);
trig2 : in std_logic_vector(31 downto 0);
trig3 : in std_logic_vector(31 downto 0);
trig4 : in std_logic_vector(15 downto 0);
trig5 : in std_logic_vector(3 downto 0)
);
end component;
-------------------------------------------------------------------------------
-- BEGIN
-------------------------------------------------------------------------------
begin
-----------------------------------------------------------------------------
-- PROCESS: SCRAMBLER_PROC
-- PURPOSE: Registering Signals and Next State
-----------------------------------------------------------------------------
SCRAMBLER_PROC : process (clk)
begin
if ((clk'event) and (clk = '1')) then
if (reset = '1') then
--Initializing internal signals
context <= SCRAMBLER_INIT;
context_reg <= (others => '0');
dout_we_reg <= '0';
elsif (scrambler_en = '1') then
-- Register all Current Signals to their _next Signals
context <= context_next(31 downto 16);
context_reg <= context_next;
dout_we_reg <= '1';
else
context <= context;
context_reg <= context_reg;
dout_we_reg <= '0';
end if;
end if;
end process SCRAMBLER_PROC ;
context_next(31) <= context(12) xor context(10) xor context(7) xor context(3) xor context(1) xor context(0);
context_next(30) <= context(15) xor context(14) xor context(12) xor context(11) xor context(9) xor context(6) xor context(3) xor context(2) xor context(0);
context_next(29) <= context(15) xor context(13) xor context(12) xor context(11) xor context(10) xor context(8) xor context(5) xor context(3) xor context(2) xor context(1);
context_next(28) <= context(14) xor context(12) xor context(11) xor context(10) xor context(9) xor context(7) xor context(4) xor context(2) xor context(1) xor context(0);
context_next(27) <= context(15) xor context(14) xor context(13) xor context(12) xor context(11) xor context(10) xor context(9) xor context(8) xor context(6) xor context(1) xor context(0);
context_next(26) <= context(15) xor context(13) xor context(11) xor context(10) xor context(9) xor context(8) xor context(7) xor context(5) xor context(3) xor context(0);
context_next(25) <= context(15) xor context(10) xor context(9) xor context(8) xor context(7) xor context(6) xor context(4) xor context(3) xor context(2);
context_next(24) <= context(14) xor context(9) xor context(8) xor context(7) xor context(6) xor context(5) xor context(3) xor context(2) xor context(1);
context_next(23) <= context(13) xor context(8) xor context(7) xor context(6) xor context(5) xor context(4) xor context(2) xor context(1) xor context(0);
context_next(22) <= context(15) xor context(14) xor context(7) xor context(6) xor context(5) xor context(4) xor context(1) xor context(0);
context_next(21) <= context(15) xor context(13) xor context(12) xor context(6) xor context(5) xor context(4) xor context(0);
context_next(20) <= context(15) xor context(11) xor context(5) xor context(4);
context_next(19) <= context(14) xor context(10) xor context(4) xor context(3);
context_next(18) <= context(13) xor context(9) xor context(3) xor context(2);
context_next(17) <= context(12) xor context(8) xor context(2) xor context(1);
context_next(16) <= context(11) xor context(7) xor context(1) xor context(0);
context_next(15) <= context(15) xor context(14) xor context(12) xor context(10) xor context(6) xor context(3) xor context(0);
context_next(14) <= context(15) xor context(13) xor context(12) xor context(11) xor context(9) xor context(5) xor context(3) xor context(2);
context_next(13) <= context(14) xor context(12) xor context(11) xor context(10) xor context(8) xor context(4) xor context(2) xor context(1);
context_next(12) <= context(13) xor context(11) xor context(10) xor context(9) xor context(7) xor context(3) xor context(1) xor context(0);
context_next(11) <= context(15) xor context(14) xor context(10) xor context(9) xor context(8) xor context(6) xor context(3) xor context(2) xor context(0);
context_next(10) <= context(15) xor context(13) xor context(12) xor context(9) xor context(8) xor context(7) xor context(5) xor context(3) xor context(2) xor context(1);
context_next(9) <= context(14) xor context(12) xor context(11) xor context(8) xor context(7) xor context(6) xor context(4) xor context(2) xor context(1) xor context(0);
context_next(8) <= context(15) xor context(14) xor context(13) xor context(12) xor context(11) xor context(10) xor context(7) xor context(6) xor context(5) xor context(1) xor context(0);
context_next(7) <= context(15) xor context(13) xor context(11) xor context(10) xor context(9) xor context(6) xor context(5) xor context(4) xor context(3) xor context(0);
context_next(6) <= context(15) xor context(10) xor context(9) xor context(8) xor context(5) xor context(4) xor context(2);
context_next(5) <= context(14) xor context(9) xor context(8) xor context(7) xor context(4) xor context(3) xor context(1);
context_next(4) <= context(13) xor context(8) xor context(7) xor context(6) xor context(3) xor context(2) xor context(0);
context_next(3) <= context(15) xor context(14) xor context(7) xor context(6) xor context(5) xor context(3) xor context(2) xor context(1);
context_next(2) <= context(14) xor context(13) xor context(6) xor context(5) xor context(4) xor context(2) xor context(1) xor context(0);
context_next(1) <= context(15) xor context(14) xor context(13) xor context(5) xor context(4) xor context(1) xor context(0);
context_next(0) <= context(15) xor context(13) xor context(4) xor context(0);
data_out_ila <= (context_reg xor data_in) when prim_scrambler = '0' else (context_reg);
--dout_we_ila <= dout_we_reg when scrambler_en = '1' else '0';
dout_we_ila <= dout_we_reg;
din_re_ila <= '1' when scrambler_en = '1' else '0';
-----------------------------------------------------------------------------
-- ILA Instantiation
-----------------------------------------------------------------------------
data_out <= data_out_ila;
dout_we <= dout_we_ila;
din_re <= din_re_ila;
chipscope_gen_ila : if (CHIPSCOPE) generate
SCRAMBLER_ILA_i : scrambler_ila
port map (
control => scrambler_ila_control,
clk => clk,
trig0 => data_in,
trig1 => data_out_ila,
trig2 => context_reg,
trig3 => context_next,
trig4 => context,
trig5(0) => scrambler_en,
trig5(1) => din_re_ila,
trig5(2) => dout_we_ila,
trig5(3) => reset
);
end generate chipscope_gen_ila;
end BEHAV;
x393_sata-05c77d236b93a06053a6ec2d8ebcad493b999f28/sata_host.v 0000664 0000000 0000000 00000067012 12562737151 0022437 0 ustar 00root root 0000000 0000000 /*******************************************************************************
* Module: sata_host
* Date: 2015-07-11
* Author: Alexey
* Description: is a wrapper for command + transport + link + phy levels
*
* Copyright (c) 2015 Elphel, Inc.
* sata_host.v 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, either version 3 of the License, or
* (at your option) any later version.
*
* sata_host.v file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*******************************************************************************/
`include "sata_phy.v"
`include "link.v"
`include "transport.v"
`include "command.v"
module sata_host(
input wire rst,
// sata clk
output wire clk,
// temporary
input wire [31:0] al_cmd_in; // == {cmd_type, cmd_port, cmd_val, cmd_done_bad, cmd_done_good; cmd_busy}
input wire al_cmd_val_in;
input wire [31:0] al_cmd_out; // same
// tmp inputs directly from registers for each and every shadow register and control bit
// from al
input wire [31:0] al_sh_data_in, // write data
input wire al_sh_data_val_in, // write strobe
input wire al_sh_data_strobe_in, // read strobe
input wire [15:0] al_sh_feature_in,
input wire al_sh_feature_val_in,
input wire [23:0] al_sh_lba_lo_in,
input wire al_sh_lba_lo_val_in,
input wire [23:0] al_sh_lba_hi_in,
input wire al_sh_lba_hi_val_in,
input wire [15:0] al_sh_count_in,
input wire al_sh_count_val_in,
input wire [7:0] al_sh_command_in,
input wire al_sh_command_val_in,
input wire [7:0] al_sh_dev_in,
input wire al_sh_dev_val_in,
input wire [7:0] al_sh_control_in,
input wire al_sh_control_val_in,
input wire [31:0] al_sh_dma_id_lo_in
input wire al_sh_dma_id_lo_val_in,
input wire [31:0] al_sh_dma_id_hi_in,
input wire al_sh_dma_id_hi_val_in,
input wire [31:0] al_sh_buf_off_in,
input wire al_sh_buf_off_val_in,
input wire [31:0] al_sh_tran_cnt_in,
input wire al_sh_tran_cnt_val_in,
input wire al_sh_autoact_in,
input wire al_sh_autoact_val_in,
input wire al_sh_inter_in,
input wire al_sh_inter_val_in,
input wire al_sh_dir_in,
input wire al_sh_dir_val_in,
input wire [31:0] al_sh_dma_cnt_in,
input wire al_sh_dma_cnt_val_in,
input wire al_sh_notif_in,
input wire al_sh_notif_val_in,
input wire [3:0] al_sh_port_in,
input wire al_sh_port_val_in,
// top-level ifaces
// ref clk from an external source, shall be connected to pads
input wire extclk_p;
input wire extclk_n;
// sata physical link data pins
input wire txp_out;
input wire txn_out;
input wire rxp_in;
input wire rxn_in;
);
wire rst;
// sata clk
wire clk;
// tl cmd iface
wire [2:0] cl2tl_cmd_type;
wire cl2tl_cmd_val;
wire [3:0] cl2tl_cmd_port;
wire cl2tl_cmd_busy;
wire cl2tl_cmd_done_good;
wire cl2tl_cmd_done_bad;
// data from tl
wire [31:0] tl2cl_data;
wire tl2cl_data_val;
wire tl2cl_data_last;
wire tl2cl_data_busy;
// to tl
wire [31:0] cl2tl_data;
wire cl2tl_data_last;
wire cl2tl_data_val;
wire cl2tl_data_strobe;
// from tl
wire [47:0] tl2cl_sh_lba_in;
wire [15:0] tl2cl_sh_count_in;
wire [7:0] tl2cl_sh_command_in;
wire [7:0] tl2cl_sh_err_in;
wire [7:0] tl2cl_sh_status_in;
wire [7:0] tl2cl_sh_estatus_in; // E_Status
wire [7:0] tl2cl_sh_dev_in;
wire [3:0] tl2cl_sh_port_in;
wire tl2cl_sh_inter_in;
wire tl2cl_sh_dir_in;
wire [63:0] tl2cl_sh_dma_id_in;
wire [31:0] tl2cl_sh_dma_off_in;
wire [31:0] tl2cl_sh_dma_cnt_in;
wire [15:0] tl2cl_sh_tran_cnt_in; // Transfer Count
wire tl2cl_sh_notif_in;
wire tl2cl_sh_autoact_in;
wire tl2cl_sh_lba_val_in;
wire tl2cl_sh_count_val_in;
wire tl2cl_sh_command_val_in;
wire tl2cl_sh_err_val_in;
wire tl2cl_sh_status_val_in;
wire tl2cl_sh_estatus_val_in; // E_Status
wire tl2cl_sh_dev_val_in;
wire tl2cl_sh_port_val_in;
wire tl2cl_sh_inter_val_in;
wire tl2cl_sh_dir_val_in;
wire tl2cl_sh_dma_id_val_in;
wire tl2cl_sh_dma_off_val_in;
wire tl2cl_sh_dma_cnt_val_in;
wire tl2cl_sh_tran_cnt_val_in; // Transfer Count
wire tl2cl_sh_notif_val_in;
wire tl2cl_sh_autoact_val_in;
// all regs to output
wire sh_data_val;
wire [31:0] sh_data;
wire [7:0] sh_control;
wire [15:0] sh_feature;
wire [47:0] sh_lba;
wire [15:0] sh_count;
wire [7:0] sh_command;
wire [7:0] sh_err;
wire [7:0] sh_status;
wire [7:0] sh_estatus; // E_Status
wire [7:0] sh_dev;
wire [3:0] sh_port;
wire sh_inter;
wire sh_dir;
wire [63:0] sh_dma_id;
wire [31:0] sh_dma_off;
wire [31:0] sh_dma_cnt;
wire [15:0] sh_tran_cnt; // Transfer Count
wire sh_notif;
wire sh_autoact;
command command(
.rst (rst),
.clk (clk),
// tl cmd iface
.cmd_type (cl2tl_cmd_type),
.cmd_val (cl2tl_cmd_val),
.cmd_port (cl2tl_cmd_port),
.cmd_busy (cl2tl_cmd_busy),
.cmd_done_good (cl2tl_cmd_done_good),
.cmd_done_bad (cl2tl_cmd_done_bad),
// temporary TODO
.al_cmd_in (al_cmd_in), // == {cmd_type, cmd_port, cmd_val, cmd_done_bad, cmd_done_good, cmd_busy}
.al_cmd_val_in (al_cmd_val_in),
.al_cmd_out (al_cmd_out), // same
// data from tl
.tl_data_in (tl2cl_data),
.tl_data_val_in (tl2tl_data_val),
.tl_data_last_in (tl2tl_data_last),
.tl_data_busy_out (tl2tl_data_busy),
// to tl
.tl_data_out (cl2tl_data),
.tl_data_last_out (cl2tl_data_last),
.tl_data_val_out (cl2tl_data_val),
.tl_data_strobe_in (cl2tl_data_strobe),
// tmp inputs directly from registers for each and every shadow register and control bit
// from al
.al_sh_data_in (al_sh_data_in), // write data
.al_sh_data_val_in (al_sh_data_val_in), // write strobe
.al_sh_data_strobe_in (al_sh_data_strobe_in), // read strobe
.al_sh_feature_in (al_sh_feature_in),
.al_sh_feature_val_in (al_sh_feature_val_in),
.al_sh_lba_lo_in (al_sh_lba_lo_in),
.al_sh_lba_lo_val_in (al_sh_lba_lo_val_in),
.al_sh_lba_hi_in (al_sh_lba_hi_in),
.al_sh_lba_hi_val_in (al_sh_lba_hi_val_in),
.al_sh_count_in (al_sh_count_in),
.al_sh_count_val_in (al_sh_count_val_in),
.al_sh_command_in (al_sh_command_in),
.al_sh_command_val_in (al_sh_command_val_in),
.al_sh_dev_in (al_sh_dev_in),
.al_sh_dev_val_in (al_sh_dev_val_in),
.al_sh_control_in (al_sh_control_in),
.al_sh_control_val_in (al_sh_control_val_in),
.al_sh_dma_id_lo_in (al_sh_dma_id_lo_in),
.al_sh_dma_id_lo_val_in (al_sh_dma_id_lo_val_in),
.al_sh_dma_id_hi_in (al_sh_dma_id_hi_in),
.al_sh_dma_id_hi_val_in (al_sh_dma_id_hi_val_in),
.al_sh_buf_off_in (al_sh_buf_off_in),
.al_sh_buf_off_val_in (al_sh_buf_off_val_in),
.al_sh_tran_cnt_in (al_sh_tran_cnt_in),
.al_sh_tran_cnt_val_in (al_sh_tran_cnt_val_in),
.al_sh_autoact_in (al_sh_autoact_in),
.al_sh_autoact_val_in (al_sh_autoact_val_in),
.al_sh_inter_in (al_sh_inter_in),
.al_sh_inter_val_in (al_sh_inter_val_in),
.al_sh_dir_in (al_sh_dir_in),
.al_sh_dir_val_in (al_sh_dir_val_in),
.al_sh_dma_cnt_in (al_sh_dma_cnt_in),
.al_sh_dma_cnt_val_in (al_sh_dma_cnt_val_in),
.al_sh_notif_in (al_sh_notif_in),
.al_sh_notif_val_in (al_sh_notif_val_in),
.al_sh_port_in (al_sh_port_in),
.al_sh_port_val_in (al_sh_port_val_in),
// from tl
.tl_sh_lba_in (tl_sh_lba_in),
.tl_sh_count_in (tl_sh_count_in),
.tl_sh_command_in (tl_sh_command_in),
.tl_sh_err_in (tl_sh_err_in),
.tl_sh_status_in (tl_sh_status_in),
.tl_sh_estatus_in (tl_sh_estatus_in), // E_Status
.tl_sh_dev_in (tl_sh_dev_in),
.tl_sh_port_in (tl_sh_port_in),
.tl_sh_inter_in (tl_sh_inter_in),
.tl_sh_dir_in (tl_sh_dir_in),
.tl_sh_dma_id_in (tl_sh_dma_id_in),
.tl_sh_dma_off_in (tl_sh_dma_off_in),
.tl_sh_dma_cnt_in (tl_sh_dma_cnt_in),
.tl_sh_tran_cnt_in (tl_sh_tran_cnt_in), // Transfer Count
.tl_sh_notif_in (tl_sh_notif_in),
.tl_sh_autoact_in (tl_sh_autoact_in),
.tl_sh_lba_val_in (tl_sh_lba_val_in),
.tl_sh_count_val_in (tl_sh_count_val_in),
.tl_sh_command_val_in (tl_sh_command_val_in),
.tl_sh_err_val_in (tl_sh_err_val_in),
.tl_sh_status_val_in (tl_sh_status_val_in),
.tl_sh_estatus_val_in (tl_sh_estatus_val_in), // E_Status
.tl_sh_dev_val_in (tl_sh_dev_val_in),
.tl_sh_port_val_in (tl_sh_port_val_in),
.tl_sh_inter_val_in (tl_sh_inter_val_in),
.tl_sh_dir_val_in (tl_sh_dir_val_in),
.tl_sh_dma_id_val_in (tl_sh_dma_id_val_in),
.tl_sh_dma_off_val_in (tl_sh_dma_off_val_in),
.tl_sh_dma_cnt_val_in (tl_sh_dma_cnt_val_in),
.tl_sh_tran_cnt_val_in (tl_sh_tran_cnt_val_in), // Transfer Count
.tl_sh_notif_val_in (tl_sh_notif_val_in),
.tl_sh_autoact_val_in (tl_sh_autoact_val_in),
// all regs to output
.sh_data_val_out (sh_data_val_out),
.sh_data_out (sh_data_out),
.sh_control_out (sh_control_out),
.sh_feature_out (sh_feature_out),
.sh_lba_out (sh_lba_out),
.sh_count_out (sh_count_out),
.sh_command_out (sh_command_out),
.sh_err_out (sh_err_out),
.sh_status_out (sh_status_out),
.sh_estatus_out (sh_estatus_out), // E_Status
.sh_dev_out (sh_dev_out),
.sh_port_out (sh_port_out),
.sh_inter_out (sh_inter_out),
.sh_dir_out (sh_dir_out),
.sh_dma_id_out (sh_dma_id_out),
.sh_dma_off_out (sh_dma_off_out),
.sh_dma_cnt_out (sh_dma_cnt_out),
.sh_tran_cnt_out (sh_tran_cnt_out), // Transfer Count
.sh_notif_out (sh_notif_out),
.sh_autoact_out (sh_autoact_out)
);
// issue a frame
wire tl2ll_frame_req;
// frame started to be transmitted
wire tl2ll_frame_ack;
// frame issue was rejected because of incoming frame with higher priority
wire tl2ll_frame_rej;
// LL is not ready to receive a frame request. frame_req shall be low if busy is asserted
wire tl2ll_frame_busy;
// frame was transmitted w/o probles and successfully received @ a device side
wire tl2ll_frame_done_good;
// frame was transmitted, but device messages of problems with receiving
wire tl2ll_frame_done_bad;
// LL reports of an incoming frame transmission. They're always allowed and have the highest priority
wire ll2tl_incom_start;
// LL reports of a completion of an incoming frame transmission.
wire ll2tl_incom_done;
// LL reports of errors in current FIS
wire ll2tl_incom_invalidate; // TODO
// TL analyzes FIS and returnes if FIS makes sense.
wire ll2tl_incom_ack_good;
// ... and if it doesn't
wire ll2tl_incom_ack_bad;
// transmission interrupts
// TL demands to brutally cancel current transaction TODO
wire tl2ll_sync_escape_req;
// acknowlegement of a successful reception TODO
wire tl2ll_sync_escape_ack;
// TL demands to stop current recieving session TODO
wire tl2ll_incom_stop_req;
// shows if dma activate was received (a pulse)
wire got_dma_activate;
wire [3:0] got_dma_activate_port;
// if CL made a mistake in controlling data FIS length
wire data_limit_exceeded;
// LL data
// data inputs from LL
wire [DATA_BYTE_WIDTH*8 - 1:0] ll2tl_data;
wire [DATA_BYTE_WIDTH/2 - 1:0] ll2tl_data_mask;
wire ll2tl_data_val;
wire ll2tl_data_last;
// transport layer tells if its inner buffer is almost full
wire ll2tl_data_busy;
// data outputs to LL
wire [DATA_BYTE_WIDTH*8 - 1:0] tl2ll_data;
// not implemented yet TODO
wire [DATA_BYTE_WIDTH*8 - 1:0] tl2ll_data_mask;
wire tl2ll_data_last;
wire tl2ll_data_val;
wire tl2ll_data_strobe;
// watchdog timers calls. They shall be handled in TL, but for debug purposes are wired to the upper level
// when eof acknowledgement is not received after sent FIS
wire watchdog_eof;
// when too many dwords is in current FIS
wire watchdog_dwords;
transport transport(
.clk (clk),
.rst (rst),
// link layer (LL) control
// issue a frame
.frame_req (frame_req),
// frame started to be transmitted
.frame_ack (frame_ack),
// frame issue was rejected because of incoming frame with higher priority
.frame_rej (frame_rej),
// LL is not ready to receive a frame request. frame_req shall be low if busy is asserted
.frame_busy (frame_busy),
// frame was transmitted w/o probles and successfully received @ a device side
.frame_done_good (frame_done_good),
// frame was transmitted, but device messages of problems with receiving
.frame_done_bad (frame_done_bad),
// LL reports of an incoming frame transmission. They're always allowed and have the highest priority
.incom_start (incom_start),
// LL reports of a completion of an incoming frame transmission.
.incom_done (incom_done),
// LL reports of errors in current FIS
.incom_invalidate (incom_invalidate), // TODO
// TL analyzes FIS and returnes if FIS makes sense.
.incom_ack_good (incom_ack_good),
// ... and if it doesn't
.incom_ack_bad (incom_ack_bad),
// transmission interrupts
// TL demands to brutally cancel current transaction TODO
.sync_escape_req (sync_escape_req),
// acknowlegement of a successful reception TODO
.sync_escape_ack (sync_escape_ack),
// TL demands to stop current recieving session TODO
.incom_stop_req (incom_stop_req),
// controls from a command layer (CL)
// FIS type, ordered by CL
.cmd_type (cl2tl_cmd_type),
// request itself
.cmd_val (cl2tl_cmd_val),
// destination port
.cmd_port (cl2tl_cmd_port),
// if cmd got into processing, busy asserts, when TL is ready to receive a new cmd, busy deasserts
.cmd_busy (cl2tl_cmd_busy),
// indicates completion of a request
.cmd_done_good (cl2tl_cmd_done_good),
// request is completed, but device wasn't able to receive
.cmd_done_bad (cl2tl_cmd_done_bad),
// shadow registers TODO reduce outputs/inputs count. or not
// actual registers are stored in CL
.sh_data_in (sh_data),
.sh_feature_in (sh_feature),
.sh_lba_in (sh_lba),
.sh_count_in (sh_count),
.sh_command_in (sh_command),
.sh_dev_in (sh_dev),
.sh_control_in (sh_control),
.sh_autoact_in (sh_autoact),
.sh_inter_in (sh_inter),
.sh_dir_in (sh_dir),
.sh_dma_id_in (sh_dma_id),
.sh_buf_off_in (sh_buf_off),
.sh_dma_cnt_in (sh_dma_cnt),
.sh_notif_in (sh_notif),
.sh_tran_cnt_in (sh_tran_cnt),
.sh_port_in (sh_port),
// TL decodes register writes and sends corresponding issues to CL
.sh_lba_out (tl2cl_sh_lba_out),
.sh_count_out (tl2cl_sh_count_out),
.sh_command_out (tl2cl_sh_command_out),
.sh_err_out (tl2cl_sh_err_out),
.sh_status_out (tl2cl_sh_status_out),
.sh_estatus_out (tl2cl_sh_estatus_out), // E_Status
.sh_dev_out (tl2cl_sh_dev_out),
.sh_port_out (tl2cl_sh_port_out),
.sh_inter_out (tl2cl_sh_inter_out),
.sh_dir_out (tl2cl_sh_dir_out),
.sh_dma_id_out (tl2cl_sh_dma_id_out),
.sh_dma_off_out (tl2cl_sh_dma_off_out),
.sh_dma_cnt_out (tl2cl_sh_dma_cnt_out),
.sh_tran_cnt_out (tl2cl_sh_tran_cnt_out), // Transfer Count
.sh_notif_out (tl2cl_sh_notif_out),
.sh_autoact_out (tl2cl_sh_autoact_out),
.sh_lba_val_out (tl2cl_sh_lba_val_out),
.sh_count_val_out (tl2cl_sh_count_val_out),
.sh_command_val_out (tl2cl_sh_command_val_out),
.sh_err_val_out (tl2cl_sh_err_val_out),
.sh_status_val_out (tl2cl_sh_status_val_out),
.sh_estatus_val_out (tl2cl_sh_estatus_val_out), // E_Status
.sh_dev_val_out (tl2cl_sh_dev_val_out),
.sh_port_val_out (tl2cl_sh_port_val_out),
.sh_inter_val_out (tl2cl_sh_inter_val_out),
.sh_dir_val_out (tl2cl_sh_dir_val_out),
.sh_dma_id_val_out (tl2cl_sh_dma_id_val_out),
.sh_dma_off_val_out (tl2cl_sh_dma_off_val_out),
.sh_dma_cnt_val_out (tl2cl_sh_dma_cnt_val_out),
.sh_tran_cnt_val_out (tl2cl_sh_tran_cnt_val_out), // Transfer Count
.sh_notif_val_out (tl2cl_sh_notif_val_out),
.sh_autoact_val_out (tl2cl_sh_autoact_val_out),
// shows if dma activate was received (a pulse)
.got_dma_activate (got_dma_activate),
.got_dma_activate_port (got_dma_activate_port),
// if CL made a mistake in controlling data FIS length
.data_limit_exceeded (data_limit_exceeded),
// LL data
// data inputs from LL
.ll_data_in (ll_data_in),
.ll_data_mask_in (ll_data_mask_in),
.ll_data_val_in (ll_data_val_in),
.ll_data_last_in (ll_data_last_in),
// transport layer tells if its inner buffer is almost full
.ll_data_busy_out (ll_data_busy_out),
// data outputs to LL
.ll_data_out (ll_data_out),
// not implemented yet TODO
.ll_data_mask_out (ll_data_mask_out),
.ll_data_last_out (ll_data_last_out),
.ll_data_val_out (ll_data_val_out),
.ll_data_strobe_in (ll_data_strobe_in),
// CL data
// required content is bypassed from ll, other is trimmed
// only content of data FIS, starting from 1st dword. Max burst = 2048 dwords
// data outputs to CL
.cl_data_out (tl2cl_data),
.cl_data_mask_out (),
.cl_data_val_out (tl2cl_data_val),
.cl_data_last_out (tl2cl_data_last),
// transport layer tells if its inner buffer is almost full
.cl_data_busy_in (tl2cl_data_busy),
// data inputs from CL
.cl_data_in (cl2tl_data),
// not implemented yet TODO
.cl_data_mask_in (cl2tl_data_mask),
.cl_data_last_in (cl2tl_data_last),
.cl_data_val_in (cl2tl_data_val),
.cl_data_strobe_out (cl2tl_data_strobe),
// watchdog timers calls. They shall be handled in TL, but for debug purposes are wired to the upper level
// when eof acknowledgement is not received after sent FIS
.watchdog_eof (watchdog_eof),
// when too many dwords is in current FIS
.watchdog_dwords (watchdog_dwords)
);
// oob sequence is reinitiated and link now is not established or rxelecidle
wire link_reset,
// phy is ready - link is established
wire phy_ready,
// data-primitives stream from phy
wire [DATA_BYTE_WIDTH*8 - 1:0] phy2ll_data;
wire [DATA_BYTE_WIDTH/2 - 1:0] phy2ll_isk; // charisk
wire [DATA_BYTE_WIDTH/2 - 1:0] phy2ll_err; // disperr | notintable
// to phy
wire [DATA_BYTE_WIDTH*8 - 1:0] ll2phy_data;
wire [DATA_BYTE_WIDTH/2 - 1:0] ll2phy_isk; // charisk
link link(
// TODO insert watchdogs
.rst (rst),
.clk (clk),
// data inputs from transport layer
// input data stream (if any data during OOB setting => ignored)
.data_in (tl2ll_data),
// in case of strange data aligments and size (1st mentioned @ doc, p.310, odd number of words case)
// Actually, only last data bundle shall be masked, others are always valid.
// Mask could be encoded into 3 bits instead of 4 for qword, but encoding+decoding aren't worth the bit
// TODO, for now not supported, all mask bits are assumed to be set
.data_mask_in (tl2ll_data_mask),
// buffer read strobe
.data_strobe_out (tl2ll_data_strobe),
// transaction's last data budle pulse
.data_last_in (tl2ll_data_last),
// read data is valid (if 0 while last pulse wasn't received => need to hold the line)
.data_val_in (tl2ll_val),
// data outputs to transport layer
// read data, same as related inputs
.data_out (ll2tl_data),
// same thing - all 1s for now. TODO
.data_mask_out (ll2tl_data_mask),
// count every data bundle read by transport layer, even if busy flag is set
// let the transport layer handle oveflows by himself
.data_val_out (ll2tl_data_val),
// transport layer tells if its inner buffer is almost full
.data_busy_in (ll2tl_busy),
.data_last_out (ll2tl_data_last),
// request for a new frame transition
.frame_req (tl2ll_frame_req),
// a little bit of overkill with the cound of response signals, think of throwing out 1 of them
// LL tells back if it cant handle the request for now
.frame_busy (tl2ll_frame_busy),
// LL tells if the request is transmitting
.frame_ack (tl2ll_frame_ack),
// or if it was cancelled because of simultanious incoming transmission
.frame_rej (tl2ll_frame_rej),
// TL tell if the outcoming transaction is done and how it was done
.frame_done_good (tl2ll_frame_done_good),
.frame_done_bad (tl2ll_frame_done_bad),
// if started an incoming transaction
.incom_start (ll2tl_incom_start),
// if incoming transition was completed
.incom_done (ll2tl_incom_done),
// if incoming transition had errors
.incom_invalidate (ll2tl_incom_invalidate),
// transport layer responds on a completion of a FIS
.incom_ack_good (ll2tl_incom_ack_good),
.incom_ack_bad (ll2tl_incom_ack_bad),
// oob sequence is reinitiated and link now is not established or rxelecidle
.link_reset (link_reset),
// TL demands to brutally cancel current transaction
.sync_escape_req (tl2ll_sync_escape_req),
// acknowlegement of a successful reception
.sync_escape_ack (tl2ll_sync_escape_ack),
// TL demands to stop current recieving session
.incom_stop_req (tl2ll_incom_stop_req),
// inputs from phy
// phy is ready - link is established
.phy_ready (phy_ready),
// data-primitives stream from phy
.phy_data_in (phy2ll_data),
.phy_isk_in (phy2ll_isk), // charisk
.phy_err_in (phy2ll_err), // disperr | notintable
// to phy
.phy_data_out (ll2phy_data),
.phy_isk_out (ll2phy_isk)// charis
);
sata_phy phy(
.rst (rst),
// sata clk, generated in pll as usrclk2
.clk (clk),
// state
.phy_ready (phy_ready),
// top-level ifaces
// ref clk from an external source, shall be connected to pads
.extclk_p (extclk_p),
.extclk_n (extclk_n),
// sata link data pins
.txp_out (txp_out),
.txn_out (txn_out),
.rxp_in (rxp_in),
.rxn_in (rxn_in),
// to link layer
.ll_data_out (phy2ll_data),
.ll_charisk_out (phy2ll_isk),
.ll_err_out (phy2ll_err),
// from link layer
.ll_data_in (ll2phy_data),
.ll_charisk_in (ll2phy_charisk)
);
endmodule
x393_sata-05c77d236b93a06053a6ec2d8ebcad493b999f28/sata_phy.v 0000664 0000000 0000000 00000070677 12562737151 0022275 0 ustar 00root root 0000000 0000000 /*******************************************************************************
* Module: sata_phy
* Date: 2015-07-11
* Author: Alexey
* Description: phy-level, including oob, clock generation and GTXE2
*
* Copyright (c) 2015 Elphel, Inc.
* sata_phy.v 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, either version 3 of the License, or
* (at your option) any later version.
*
* sata_phy.v file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*******************************************************************************/
`include "oob_ctrl.v"
module sata_phy(
input wire rst,
// sata clk, generated in pll as usrclk2
output wire clk,
// state
output wire phy_ready,
// top-level ifaces
// ref clk from an external source, shall be connected to pads
input wire extclk_p,
input wire extclk_n,
// sata link data pins
output wire txp_out,
output wire txn_out,
input wire rxp_in,
input wire rxn_in,
// to link layer
output wire [31:0] ll_data_out,
output wire [3:0] ll_charisk_out,
output wire [3:0] ll_err_out, // TODO!!!
// from link layer
input wire [31:0] ll_data_in,
input wire [3:0] ll_charisk_in
);
parameter CHIPSCOPE = "FALSE";
wire [31:0] txdata;
wire [3:0] txcharisk;
wire [63:0] rxdata;
wire [3:0] rxcharisk;
wire [31:0] rxdata_out;
wire [31:0] txdata_in;
wire [3:0] txcharisk_in;
wire [3:0] rxcharisk_out;
wire rxcomwakedet;
wire rxcominitdet;
wire cplllock;
wire txcominit;
wire txcomwake;
wire rxreset;
wire rxelecidle;
wire txelecidle;
wire rxbyteisaligned;
oob_ctrl oob_ctrl(
// sata clk = usrclk2
.clk (clk),
// reset oob
.rst (rst),
// gtx is ready = all resets are done
.gtx_ready (gtx_ready),
// oob responces
.rxcominitdet_in (rxcominitdet),
.rxcomwakedet_in (rxcomwakedet),
.rxelecidle_in (rxelecidle),
// oob issues
.txcominit (txcominit),
.txcomwake (txcomwake),
.txelecidle (txelecidle),
// input data stream (if any data during OOB setting => ignored)
.txdata_in (txdata_in),
.txcharisk_in (txcharisk_in),
// output data stream to gtx
.txdata_out (txdata_out),
.txcharisk_out (txcharisk_out),
// input data from gtx
.rxdata_in (rxdata_in),
.rxcharisk_in (rxcharisk_in),
// bypassed data from gtx
.rxdata_out (rxdata_out),
.rxcharisk_out (rxcharisk_out),
// receiving data is aligned
.rxbyteisaligned (rxbyteisaligned),
// shows if channel is ready
.phy_ready (phy_ready)
);
wire cplllockdetclk; // TODO
wire drpclk; // TODO
wire cpllreset;
wire gtrefclk;
wire rxresetdone;
wire txresetdone;
wire txreset;
wire txuserrdy;
wire rxuserrdy;
wire txusrclk;
wire txusrclk2;
wire rxusrclk;
wire rxusrclk2;
wire txp;
wire txn;
wire rxp;
wire rxn;
wire txoutclk;
wire txpmareset_done;
wire rxeyereset_done;
// tx reset sequence; waves @ ug476 p67
localparam TXPMARESET_TIME = 5'h1;
reg [2:0] txpmareset_cnt;
assign txpmareset_done = txpmareset_cnt == TXPMARESET_TIME;
always @ (posedge gtrefclk)
txpmareset_cnt <= txreset ? 3'h0 : txpmareset_done ? txpmareset_cnt : txpmareset_cnt + 1'b1;
// rx reset sequence; waves @ ug476 p77
localparam RXPMARESET_TIME = 5'h11;
localparam RXCDRPHRESET_TIME = 5'h1;
localparam RXCDRFREQRESET_TIME = 5'h1;
localparam RXDFELPMRESET_TIME = 7'hf;
localparam RXISCANRESET_TIME = 5'h1;
localparam RXEYERESET_TIME = 7'h0 + RXPMARESET_TIME + RXCDRPHRESET_TIME + RXCDRFREQRESET_TIME + RXDFELPMRESET_TIME + RXISCANRESET_TIME;
reg [6:0] rxeyereset_cnt;
assign rxeyereset_done = rxeyereset_cnt == RXEYERESET_TIME;
always @ (posedge gtrefclk)
rxeyereset_cnt <= rxreset ? 3'h0 : rxeyereset_done ? rxeyereset_cnt : rxeyereset_cnt + 1'b1;
/*
* Resets
*/
wire usrpll_locked;
assign cpllreset = rst;
assign rxreset = ~cplllock | cpllreset;
assign txreset = ~cplllock | cpllreset;
assign rxuserrdy = usrpll_locked & cplllock & ~cpllreset & ~rxreset & rxeyereset_done;
assign txuserrdy = usrpll_locked & cplllock & ~cpllreset & ~txreset & txpmareset_done;
/*
* USRCLKs generation. USRCLK @ 150MHz, same as TXOUTCLK; USRCLK2 @ 75Mhz -> sata_clk === sclk
* It's recommended to use MMCM instead of PLL, whatever
*/
wire usrpll_fb_clk;
wire usrclk;
wire usrclk2;
assign txusrclk = usrclk;
assign txusrclk2 = usrclk2;
assign rxusrclk = usrclk;
assign rxusrclk2 = usrclk2;
PLLE2_ADV #(
.BANDWIDTH ("OPTIMIZED"),
.CLKFBOUT_MULT (8),
.CLKFBOUT_PHASE (0.000),
.CLKIN1_PERIOD (6.666),
.CLKIN2_PERIOD (0.000),
.CLKOUT0_DIVIDE (8),
.CLKOUT0_DUTY_CYCLE (0.500),
.CLKOUT0_PHASE (0.000),
.CLKOUT1_DIVIDE (16),
.CLKOUT1_DUTY_CYCLE (0.500),
.CLKOUT1_PHASE (0.000),
/* .CLKOUT2_DIVIDE = 1,
.CLKOUT2_DUTY_CYCLE = 0.500,
.CLKOUT2_PHASE = 0.000,
.CLKOUT3_DIVIDE = 1,
.CLKOUT3_DUTY_CYCLE = 0.500,
.CLKOUT3_PHASE = 0.000,
.CLKOUT4_DIVIDE = 1,
.CLKOUT4_DUTY_CYCLE = 0.500,
.CLKOUT4_PHASE = 0.000,
.CLKOUT5_DIVIDE = 1,
.CLKOUT5_DUTY_CYCLE = 0.500,
.CLKOUT5_PHASE = 0.000,*/
.COMPENSATION ("ZHOLD"),
.DIVCLK_DIVIDE (1),
.IS_CLKINSEL_INVERTED (1'b0),
.IS_PWRDWN_INVERTED (1'b0),
.IS_RST_INVERTED (1'b0),
.REF_JITTER1 (0.010),
.REF_JITTER2 (0.010),
.STARTUP_WAIT ("FALSE")
)
usrclk_pll(
.CLKFBOUT (usrpll_fb_clk),
.CLKOUT0 (usrclk),
.CLKOUT1 (usrclk2),
.CLKOUT2 (),
.CLKOUT3 (),
.CLKOUT4 (),
.CLKOUT5 (),
.DO (),
.DRDY (),
.LOCKED (usrpll_locked),
.CLKFBIN (usrpll_fb_clk),
.CLKIN1 (txoutclk),
.CLKIN2 (1'b0),
.CLKINSEL (1'b1),
.DADDR (7'h0),
.DCLK (drpclk),
.DEN (1'b0),
.DI (16'h0),
.DWE (1'b0),
.PWRDWN (1'b0),
.RST (~cplllock)
);
/*
* Padding for an external input clock @ 150 MHz
*/
localparam [1:0] CLKSWING_CFG = 2'b11;
IBUFDS_GTE2 #(
.CLKRCV_TRST ("TRUE"),
.CLKCM_CFG ("TRUE"),
.CLKSWING_CFG (CLKSWING_CFG)
)
ext_clock_buf(
.I (extclk_p),
.IB (extclk_n),
.CEB (1'b0),
.O (gtrefclk),
.ODIV2 ()
);
GTXE2_CHANNEL #(
.SIM_RECEIVER_DETECT_PASS ("TRUE"),
.SIM_TX_EIDLE_DRIVE_LEVEL ("X"),
.SIM_RESET_SPEEDUP ("FALSE"),
.SIM_CPLLREFCLK_SEL (3'b001),
.SIM_VERSION ("4.0"),
.ALIGN_COMMA_DOUBLE ("FALSE"),
.ALIGN_COMMA_ENABLE (10'b1111111111),
.ALIGN_COMMA_WORD (1),
.ALIGN_MCOMMA_DET ("TRUE"),
.ALIGN_MCOMMA_VALUE (10'b1010000011),
.ALIGN_PCOMMA_DET ("TRUE"),
.ALIGN_PCOMMA_VALUE (10'b0101111100),
.SHOW_REALIGN_COMMA ("TRUE"),
.RXSLIDE_AUTO_WAIT (7),
.RXSLIDE_MODE ("OFF"),
.RX_SIG_VALID_DLY (10),
.RX_DISPERR_SEQ_MATCH ("TRUE"),
.DEC_MCOMMA_DETECT ("TRUE"),
.DEC_PCOMMA_DETECT ("TRUE"),
.DEC_VALID_COMMA_ONLY ("FALSE"),
.CBCC_DATA_SOURCE_SEL ("DECODED"),
.CLK_COR_SEQ_2_USE ("FALSE"),
.CLK_COR_KEEP_IDLE ("FALSE"),
.CLK_COR_MAX_LAT (9),
.CLK_COR_MIN_LAT (7),
.CLK_COR_PRECEDENCE ("TRUE"),
.CLK_COR_REPEAT_WAIT (0),
.CLK_COR_SEQ_LEN (1),
.CLK_COR_SEQ_1_ENABLE (4'b1111),
.CLK_COR_SEQ_1_1 (10'b0100000000),
.CLK_COR_SEQ_1_2 (10'b0000000000),
.CLK_COR_SEQ_1_3 (10'b0000000000),
.CLK_COR_SEQ_1_4 (10'b0000000000),
.CLK_CORRECT_USE ("FALSE"),
.CLK_COR_SEQ_2_ENABLE (4'b1111),
.CLK_COR_SEQ_2_1 (10'b0100000000),
.CLK_COR_SEQ_2_2 (10'b0000000000),
.CLK_COR_SEQ_2_3 (10'b0000000000),
.CLK_COR_SEQ_2_4 (10'b0000000000),
.CHAN_BOND_KEEP_ALIGN ("FALSE"),
.CHAN_BOND_MAX_SKEW (1),
.CHAN_BOND_SEQ_LEN (1),
.CHAN_BOND_SEQ_1_1 (10'b0000000000),
.CHAN_BOND_SEQ_1_2 (10'b0000000000),
.CHAN_BOND_SEQ_1_3 (10'b0000000000),
.CHAN_BOND_SEQ_1_4 (10'b0000000000),
.CHAN_BOND_SEQ_1_ENABLE (4'b1111),
.CHAN_BOND_SEQ_2_1 (10'b0000000000),
.CHAN_BOND_SEQ_2_2 (10'b0000000000),
.CHAN_BOND_SEQ_2_3 (10'b0000000000),
.CHAN_BOND_SEQ_2_4 (10'b0000000000),
.CHAN_BOND_SEQ_2_ENABLE (4'b1111),
.CHAN_BOND_SEQ_2_USE ("FALSE"),
.FTS_DESKEW_SEQ_ENABLE (4'b1111),
.FTS_LANE_DESKEW_CFG (4'b1111),
.FTS_LANE_DESKEW_EN ("FALSE"),
.ES_CONTROL (6'b000000),
.ES_ERRDET_EN ("FALSE"),
.ES_EYE_SCAN_EN ("TRUE"),
.ES_HORZ_OFFSET (12'h000),
.ES_PMA_CFG (10'b0000000000),
.ES_PRESCALE (5'b00000),
.ES_QUALIFIER (80'h00000000000000000000),
.ES_QUAL_MASK (80'h00000000000000000000),
.ES_SDATA_MASK (80'h00000000000000000000),
.ES_VERT_OFFSET (9'b000000000),
.RX_DATA_WIDTH (20),
.OUTREFCLK_SEL_INV (2'b11),
.PMA_RSV (32'h00018480),
.PMA_RSV2 (16'h2050),
.PMA_RSV3 (2'b00),
.PMA_RSV4 (32'h00000000),
.RX_BIAS_CFG (12'b000000000100),
.DMONITOR_CFG (24'h000A00),
.RX_CM_SEL (2'b11),
.RX_CM_TRIM (3'b010),
.RX_DEBUG_CFG (12'b000000000000),
.RX_OS_CFG (13'b0000010000000),
.TERM_RCAL_CFG (5'b10000),
.TERM_RCAL_OVRD (1'b0),
.TST_RSV (32'h00000000),
.RX_CLK25_DIV (6),
.TX_CLK25_DIV (6),
.UCODEER_CLR (1'b0),
.PCS_PCIE_EN ("FALSE"),
.PCS_RSVD_ATTR (48'h0100),
.RXBUF_ADDR_MODE ("FAST"),
.RXBUF_EIDLE_HI_CNT (4'b1000),
.RXBUF_EIDLE_LO_CNT (4'b0000),
.RXBUF_EN ("TRUE"),
.RX_BUFFER_CFG (6'b000000),
.RXBUF_RESET_ON_CB_CHANGE ("TRUE"),
.RXBUF_RESET_ON_COMMAALIGN ("FALSE"),
.RXBUF_RESET_ON_EIDLE ("FALSE"),
.RXBUF_RESET_ON_RATE_CHANGE ("TRUE"),
.RXBUFRESET_TIME (5'b00001),
.RXBUF_THRESH_OVFLW (61),
.RXBUF_THRESH_OVRD ("FALSE"),
.RXBUF_THRESH_UNDFLW (4),
.RXDLY_CFG (16'h001F),
.RXDLY_LCFG (9'h030),
.RXDLY_TAP_CFG (16'h0000),
.RXPH_CFG (24'h000000),
.RXPHDLY_CFG (24'h084020),
.RXPH_MONITOR_SEL (5'b00000),
.RX_XCLK_SEL ("RXREC"),
.RX_DDI_SEL (6'b000000),
.RX_DEFER_RESET_BUF_EN ("TRUE"),
.RXCDR_CFG (72'h03000023ff10200020),
.RXCDR_FR_RESET_ON_EIDLE (1'b0),
.RXCDR_HOLD_DURING_EIDLE (1'b0),
.RXCDR_PH_RESET_ON_EIDLE (1'b0),
.RXCDR_LOCK_CFG (6'b010101),
.RXCDRFREQRESET_TIME (RXCDRFREQRESET_TIME),
.RXCDRPHRESET_TIME (RXCDRPHRESET_TIME),
.RXISCANRESET_TIME (RXISCANRESET_TIME),
.RXPCSRESET_TIME (5'b00001),
.RXPMARESET_TIME (RXPMARESET_TIME),
.RXOOB_CFG (7'b0000110),
.RXGEARBOX_EN ("FALSE"),
.GEARBOX_MODE (3'b000),
.RXPRBS_ERR_LOOPBACK (1'b0),
.PD_TRANS_TIME_FROM_P2 (12'h03c),
.PD_TRANS_TIME_NONE_P2 (8'h3c),
.PD_TRANS_TIME_TO_P2 (8'h64),
.SAS_MAX_COM (64),
.SAS_MIN_COM (36),
.SATA_BURST_SEQ_LEN (4'b0111),
.SATA_BURST_VAL (3'b110),
.SATA_EIDLE_VAL (3'b110),
.SATA_MAX_BURST (8),
.SATA_MAX_INIT (21),
.SATA_MAX_WAKE (7),
.SATA_MIN_BURST (4),
.SATA_MIN_INIT (12),
.SATA_MIN_WAKE (4),
.TRANS_TIME_RATE (8'h0E),
.TXBUF_EN ("TRUE"),
.TXBUF_RESET_ON_RATE_CHANGE ("TRUE"),
.TXDLY_CFG (16'h001F),
.TXDLY_LCFG (9'h030),
.TXDLY_TAP_CFG (16'h0000),
.TXPH_CFG (16'h0780),
.TXPHDLY_CFG (24'h084020),
.TXPH_MONITOR_SEL (5'b00000),
.TX_XCLK_SEL ("TXOUT"),
.TX_DATA_WIDTH (40),
.TX_DEEMPH0 (5'b00000),
.TX_DEEMPH1 (5'b00000),
.TX_EIDLE_ASSERT_DELAY (3'b110),
.TX_EIDLE_DEASSERT_DELAY (3'b100),
.TX_LOOPBACK_DRIVE_HIZ ("FALSE"),
.TX_MAINCURSOR_SEL (1'b0),
.TX_DRIVE_MODE ("DIRECT"),
.TX_MARGIN_FULL_0 (7'b1001110),
.TX_MARGIN_FULL_1 (7'b1001001),
.TX_MARGIN_FULL_2 (7'b1000101),
.TX_MARGIN_FULL_3 (7'b1000010),
.TX_MARGIN_FULL_4 (7'b1000000),
.TX_MARGIN_LOW_0 (7'b1000110),
.TX_MARGIN_LOW_1 (7'b1000100),
.TX_MARGIN_LOW_2 (7'b1000010),
.TX_MARGIN_LOW_3 (7'b1000000),
.TX_MARGIN_LOW_4 (7'b1000000),
.TXGEARBOX_EN ("FALSE"),
.TXPCSRESET_TIME (5'b00001),
.TXPMARESET_TIME (TXPMARESET_TIME),
.TX_RXDETECT_CFG (14'h1832),
.TX_RXDETECT_REF (3'b100),
.CPLL_CFG (24'hBC07DC),
.CPLL_FBDIV (4),
.CPLL_FBDIV_45 (5),
.CPLL_INIT_CFG (24'h00001E),
.CPLL_LOCK_CFG (16'h01E8),
.CPLL_REFCLK_DIV (1),
.RXOUT_DIV (2),
.TXOUT_DIV (2),
.SATA_CPLL_CFG ("VCO_3000MHZ"),
.RXDFELPMRESET_TIME (RXDFELPMRESET_TIME),
.RXLPM_HF_CFG (14'b00000011110000),
.RXLPM_LF_CFG (14'b00000011110000),
.RX_DFE_GAIN_CFG (23'h020FEA),
.RX_DFE_H2_CFG (12'b000000000000),
.RX_DFE_H3_CFG (12'b000001000000),
.RX_DFE_H4_CFG (11'b00011110000),
.RX_DFE_H5_CFG (11'b00011100000),
.RX_DFE_KL_CFG (13'b0000011111110),
.RX_DFE_LPM_CFG (16'h0954),
.RX_DFE_LPM_HOLD_DURING_EIDLE (1'b0),
.RX_DFE_UT_CFG (17'b10001111000000000),
.RX_DFE_VP_CFG (17'b00011111100000011),
.RX_CLKMUX_PD (1'b1),
.TX_CLKMUX_PD (1'b1),
.RX_INT_DATAWIDTH (0),
.TX_INT_DATAWIDTH (0),
.TX_QPI_STATUS_EN (1'b0),
.RX_DFE_KL_CFG2 (32'h301148AC),
.RX_DFE_XYD_CFG (13'b0000000000000),
.TX_PREDRIVER_MODE (1'b0)
)
dut(
.CPLLFBCLKLOST (),
.CPLLLOCK (cplllock),
.CPLLLOCKDETCLK (cplllockdetclk),
.CPLLLOCKEN (1'b1),
.CPLLPD (1'b0),
.CPLLREFCLKLOST (),
.CPLLREFCLKSEL (3'b001),
.CPLLRESET (cpllreset),
.GTRSVD (1'b0),
.PCSRSVDIN (1'b0),
.PCSRSVDIN2 (1'b0),
.PMARSVDIN (1'b0),
.PMARSVDIN2 (1'b0),
.TSTIN (1'b1),
.TSTOUT (),
.CLKRSVD (4'b0000),
.GTGREFCLK (1'b0),
.GTNORTHREFCLK0 (1'b0),
.GTNORTHREFCLK1 (1'b0),
.GTREFCLK0 (gtrefclk),
.GTREFCLK1 (1'b0),
.GTSOUTHREFCLK0 (1'b0),
.GTSOUTHREFCLK1 (1'b0),
.DRPADDR (9'b0),
.DRPCLK (drpclk),
.DRPDI (16'b0),
.DRPDO (),
.DRPEN (1'b0),
.DRPRDY (),
.DRPWE (1'b0),
.GTREFCLKMONITOR (),
.QPLLCLK (gtrefclk),
.QPLLREFCLK (gtrefclk),
.RXSYSCLKSEL (2'b00),
.TXSYSCLKSEL (2'b00),
.DMONITOROUT (),
.TX8B10BEN (1'b1),
.LOOPBACK (3'd0),
.PHYSTATUS (),
.RXRATE (3'd0),
.RXVALID (),
.RXPD (2'b00),
.TXPD (2'b00),
.SETERRSTATUS (1'b0),
.EYESCANRESET (1'b0),//rxreset), // p78
.RXUSERRDY (rxuserrdy),
.EYESCANDATAERROR (),
.EYESCANMODE (1'b0),
.EYESCANTRIGGER (1'b0),
.RXCDRFREQRESET (1'b0),
.RXCDRHOLD (1'b0),
.RXCDRLOCK (),
.RXCDROVRDEN (1'b0),
.RXCDRRESET (1'b0),
.RXCDRRESETRSV (1'b0),
.RXCLKCORCNT (),
.RX8B10BEN (1'b1),
.RXUSRCLK (rxusrclk),
.RXUSRCLK2 (rxusrclk2),
.RXDATA (rxdata),
.RXPRBSERR (),
.RXPRBSSEL (3'd0),
.RXPRBSCNTRESET (1'b0),
.RXDFEXYDEN (1'b1),
.RXDFEXYDHOLD (1'b0),
.RXDFEXYDOVRDEN (1'b0),
.RXDISPERR (),
.RXNOTINTABLE (),
.GTXRXP (rxp),
.GTXRXN (rxn),
.RXBUFRESET (1'b0),
.RXBUFSTATUS (),
.RXDDIEN (1'b0),
.RXDLYBYPASS (1'b1),
.RXDLYEN (1'b0),
.RXDLYOVRDEN (1'b0),
.RXDLYSRESET (1'b0),
.RXDLYSRESETDONE (),
.RXPHALIGN (1'b0),
.RXPHALIGNDONE (),
.RXPHALIGNEN (1'b0),
.RXPHDLYPD (1'b0),
.RXPHDLYRESET (1'b0),
.RXPHMONITOR (),
.RXPHOVRDEN (1'b0),
.RXPHSLIPMONITOR (),
.RXSTATUS (),
.RXBYTEISALIGNED (rxbyteisaligned),
.RXBYTEREALIGN (),
.RXCOMMADET (),
.RXCOMMADETEN (1'b1),
.RXMCOMMAALIGNEN (1'b1),
.RXPCOMMAALIGNEN (1'b1),
.RXCHANBONDSEQ (),
.RXCHBONDEN (1'b0),
.RXCHBONDLEVEL (3'd0),
.RXCHBONDMASTER (1'b0),
.RXCHBONDO (),
.RXCHBONDSLAVE (1'b0),
.RXCHANISALIGNED (),
.RXCHANREALIGN (),
.RXLPMHFHOLD (1'b0),
.RXLPMHFOVRDEN (1'b0),
.RXLPMLFHOLD (1'b0),
.RXDFEAGCHOLD (1'b0),
.RXDFEAGCOVRDEN (1'b0),
.RXDFECM1EN (1'b0),
.RXDFELFHOLD (1'b0),
.RXDFELFOVRDEN (1'b1),
.RXDFELPMRESET (rxreset),
.RXDFETAP2HOLD (1'b0),
.RXDFETAP2OVRDEN (1'b0),
.RXDFETAP3HOLD (1'b0),
.RXDFETAP3OVRDEN (1'b0),
.RXDFETAP4HOLD (1'b0),
.RXDFETAP4OVRDEN (1'b0),
.RXDFETAP5HOLD (1'b0),
.RXDFETAP5OVRDEN (1'b0),
.RXDFEUTHOLD (1'b0),
.RXDFEUTOVRDEN (1'b0),
.RXDFEVPHOLD (1'b0),
.RXDFEVPOVRDEN (1'b0),
// .RXDFEVSEN (1'b0),
.RXLPMLFKLOVRDEN (1'b0),
.RXMONITOROUT (),
.RXMONITORSEL (2'b01),
.RXOSHOLD (1'b0),
.RXOSOVRDEN (1'b0),
.RXRATEDONE (),
.RXOUTCLK (),
.RXOUTCLKFABRIC (),
.RXOUTCLKPCS (),
.RXOUTCLKSEL (3'b010),
.RXDATAVALID (),
.RXHEADER (),
.RXHEADERVALID (),
.RXSTARTOFSEQ (),
.RXGEARBOXSLIP (1'b0),
.GTRXRESET (rxreset),
.RXOOBRESET (1'b0),
.RXPCSRESET (1'b0),
.RXPMARESET (1'b0),//rxreset), // p78
.RXLPMEN (1'b0),
.RXCOMSASDET (),
.RXCOMWAKEDET (rxcomwakedet),
.RXCOMINITDET (rxcominitdet),
.RXELECIDLE (rxelecidle),
.RXELECIDLEMODE (2'b00),
.RXPOLARITY (1'b0),
.RXSLIDE (1'b0),
.RXCHARISCOMMA (),
.RXCHARISK (rxcharisk),
.RXCHBONDI (5'b00000),
.RXRESETDONE (rxresetdone),
.RXQPIEN (1'b0),
.RXQPISENN (),
.RXQPISENP (),
.TXPHDLYTSTCLK (1'b0),
.TXPOSTCURSOR (5'b00000),
.TXPOSTCURSORINV (1'b0),
.TXPRECURSOR (5'd0),
.TXPRECURSORINV (1'b0),
.TXQPIBIASEN (1'b0),
.TXQPISTRONGPDOWN (1'b0),
.TXQPIWEAKPUP (1'b0),
.CFGRESET (1'b0),
.GTTXRESET (txreset),
.PCSRSVDOUT (),
.TXUSERRDY (txuserrdy),
.GTRESETSEL (1'b0),
.RESETOVRD (1'b0),
.TXCHARDISPMODE (8'd0),
.TXCHARDISPVAL (8'd0),
.TXUSRCLK (txusrclk),
.TXUSRCLK2 (txusrclk2),
.TXELECIDLE (txelecidle),
.TXMARGIN (3'd0),
.TXRATE (3'd0),
.TXSWING (1'b0),
.TXPRBSFORCEERR (1'b0),
.TXDLYBYPASS (1'b1),
.TXDLYEN (1'b0),
.TXDLYHOLD (1'b0),
.TXDLYOVRDEN (1'b0),
.TXDLYSRESET (1'b0),
.TXDLYSRESETDONE (),
.TXDLYUPDOWN (1'b0),
.TXPHALIGN (1'b0),
.TXPHALIGNDONE (),
.TXPHALIGNEN (1'b0),
.TXPHDLYPD (1'b0),
.TXPHDLYRESET (1'b0),
.TXPHINIT (1'b0),
.TXPHINITDONE (),
.TXPHOVRDEN (1'b0),
.TXBUFSTATUS (),
.TXBUFDIFFCTRL (3'b100),
.TXDEEMPH (1'b0),
.TXDIFFCTRL (4'b1000),
.TXDIFFPD (1'b0),
.TXINHIBIT (1'b0),
.TXMAINCURSOR (7'b0000000),
.TXPISOPD (1'b0),
.TXDATA ({32'h0, txdata}),
.GTXTXN (txn),
.GTXTXP (txp),
.TXOUTCLK (txoutclk),
.TXOUTCLKFABRIC (),
.TXOUTCLKPCS (),
.TXOUTCLKSEL (3'b010),
.TXRATEDONE (),
.TXCHARISK ({4'b0, txcharisk}),
.TXGEARBOXREADY (),
.TXHEADER (3'd0),
.TXSEQUENCE (7'd0),
.TXSTARTSEQ (1'b0),
.TXPCSRESET (1'b0),
.TXPMARESET (1'b0),
.TXRESETDONE (txresetdone),
.TXCOMFINISH (),
.TXCOMINIT (txcominit),
.TXCOMSAS (1'b0),
.TXCOMWAKE (txcomwake),
.TXPDELECIDLEMODE (1'b0),
.TXPOLARITY (1'b0),
.TXDETECTRX (1'b0),
.TX8B10BBYPASS (8'd0),
.TXPRBSSEL (3'd0),
.TXQPISENN (),
.TXQPISENP ()/*,
.TXSYNCMODE (1'b0),
.TXSYNCALLIN (1'b0),
.TXSYNCIN (1'b0)*/
);
/*
* Interfaces
*/
assign cplllockdetclk = CLKIN_150;
assign drpclk = CLKIN_150;
assign clk = usrclk2;
assign rxn = rxn_in;
assign rxp = rxp_in;
assign txp_out = txn;
assign txp_out = txp;
assign ll_data_out = rxdata_out;
assign ll_charisk_out = rxcharisk_out;
assign txdata_in = ll_data_in;
assign txcharisk_in = ll_charisk_in;
endmodule
x393_sata-05c77d236b93a06053a6ec2d8ebcad493b999f28/sata_top.v 0000664 0000000 0000000 00000047152 12562737151 0022267 0 ustar 00root root 0000000 0000000 /*******************************************************************************
* Module: sata_top
* Date: 2015-07-11
* Author: Alexey
* Description: sata for z7nq top-level module
*
* Copyright (c) 2015 Elphel, Inc.
* sata_top.v 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, either version 3 of the License, or
* (at your option) any later version.
*
* sata_top.v file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*******************************************************************************/
`timescale 1ns/1ns
`include "axi_regs.v"
`include "dma_regs.v"
`include "sata_host.v"
`include "dma_adapter.v"
`include "dma_control.v"
`include "membridge.v"
/*
* Takes commands from axi iface as a slave, transfers data with another axi iface as a master
*/
module sata_top(
/*
* Commands interface
*/
input wire ACLK, // AXI PS Master GP1 Clock , input
input wire ARESETN, // AXI PS Master GP1 Reset, output
// AXI PS Master GP1: Read Address
input wire [31:0] ARADDR, // AXI PS Master GP1 ARADDR[31:0], output
input wire ARVALID, // AXI PS Master GP1 ARVALID, output
output wire ARREADY, // AXI PS Master GP1 ARREADY, input
input wire [11:0] ARID, // AXI PS Master GP1 ARID[11:0], output
input wire [1:0] ARLOCK, // AXI PS Master GP1 ARLOCK[1:0], output
input wire [3:0] ARCACHE, // AXI PS Master GP1 ARCACHE[3:0], output
input wire [2:0] ARPROT, // AXI PS Master GP1 ARPROT[2:0], output
input wire [3:0] ARLEN, // AXI PS Master GP1 ARLEN[3:0], output
input wire [1:0] ARSIZE, // AXI PS Master GP1 ARSIZE[1:0], output
input wire [1:0] ARBURST, // AXI PS Master GP1 ARBURST[1:0], output
input wire [3:0] ARQOS, // AXI PS Master GP1 ARQOS[3:0], output
// AXI PS Master GP1: Read Data
output wire [31:0] RDATA, // AXI PS Master GP1 RDATA[31:0], input
output wire RVALID, // AXI PS Master GP1 RVALID, input
input wire RREADY, // AXI PS Master GP1 RREADY, output
output wire [11:0] RID, // AXI PS Master GP1 RID[11:0], input
output wire RLAST, // AXI PS Master GP1 RLAST, input
output wire [1:0] RRESP, // AXI PS Master GP1 RRESP[1:0], input
// AXI PS Master GP1: Write Address
input wire [31:0] AWADDR, // AXI PS Master GP1 AWADDR[31:0], output
input wire AWVALID, // AXI PS Master GP1 AWVALID, output
output wire AWREADY, // AXI PS Master GP1 AWREADY, input
input wire [11:0] AWID, // AXI PS Master GP1 AWID[11:0], output
input wire [1:0] AWLOCK, // AXI PS Master GP1 AWLOCK[1:0], output
input wire [3:0] AWCACHE, // AXI PS Master GP1 AWCACHE[3:0], output
input wire [2:0] AWPROT, // AXI PS Master GP1 AWPROT[2:0], output
input wire [3:0] AWLEN, // AXI PS Master GP1 AWLEN[3:0], outpu:t
input wire [1:0] AWSIZE, // AXI PS Master GP1 AWSIZE[1:0], output
input wire [1:0] AWBURST, // AXI PS Master GP1 AWBURST[1:0], output
input wire [3:0] AWQOS, // AXI PS Master GP1 AWQOS[3:0], output
// AXI PS Master GP1: Write Data
input wire [31:0] WDATA, // AXI PS Master GP1 WDATA[31:0], output
input wire WVALID, // AXI PS Master GP1 WVALID, output
output wire WREADY, // AXI PS Master GP1 WREADY, input
input wire [11:0] WID, // AXI PS Master GP1 WID[11:0], output
input wire WLAST, // AXI PS Master GP1 WLAST, output
input wire [3:0] WSTRB, // AXI PS Master GP1 WSTRB[3:0], output
// AXI PS Master GP1: Write Responce
output wire BVALID, // AXI PS Master GP1 BVALID, input
input wire BREADY, // AXI PS Master GP1 BREADY, output
output wire [11:0] BID, // AXI PS Master GP1 BID[11:0], input
output wire [1:0] BRESP, // AXI PS Master GP1 BRESP[1:0], input
/*
* Data interface
*/
output wire [31:0] afi_awaddr,
output wire afi_awvalid,
input wire afi_awready,
output wire [5:0] afi_awid,
output wire [1:0] afi_awlock,
output wire [3:0] afi_awcache,
output wire [2:0] afi_awprot,
output wire [3:0] afi_awlen,
output wire [2:0] afi_awsize,
output wire [1:0] afi_awburst,
output wire [3:0] afi_awqos,
// write data
output wire [63:0] afi_wdata,
output wire afi_wvalid,
input wire afi_wready,
output wire [5:0] afi_wid,
output wire afi_wlast,
output wire [7:0] afi_wstrb,
// write response
input wire afi_bvalid,
output wire afi_bready,
input wire [5:0] afi_bid,
input wire [1:0] afi_bresp,
// PL extra (non-AXI) signals
input wire [7:0] afi_wcount,
input wire [5:0] afi_wacount,
output wire afi_wrissuecap1en,
// AXI_HP signals - read channel
// read address
output wire [31:0] afi_araddr,
output wire afi_arvalid,
input wire afi_arready,
output wire [5:0] afi_arid,
output wire [1:0] afi_arlock,
output wire [3:0] afi_arcache,
output wire [2:0] afi_arprot,
output wire [3:0] afi_arlen,
output wire [2:0] afi_arsize,
output wire [1:0] afi_arburst,
output wire [3:0] afi_arqos,
// read data
input wire [63:0] afi_rdata,
input wire afi_rvalid,
output wire afi_rready,
input wire [5:0] afi_rid,
input wire afi_rlast,
input wire [1:0] afi_rresp,
// PL extra (non-AXI) signals
input wire [7:0] afi_rcount,
input wire [2:0] afi_racount,
output wire afi_rdissuecap1en,
/*
* PHY
*/
output wire TXN,
output wire TXP,
output wire RXN,
output wire RXP,
input wire REFCLK_PAD_P_IN,
input wire REFCLK_PAD_N_IN
);
// axi_regs <-> data regs
wire [31:0] bram_rdata;
wire [31:0] bram_waddr;
wire [31:0] bram_wdata;
wire [31:0] bram_raddr;
wire [3:0] bram_wstb;
wire bram_wen;
wire bram_ren;
wire bram_regen;
// sata logic reset
wire rst;
// sata clk
wire sclk;
// dma_regs <-> dma_control
wire [31:7] mem_address;
wire [31:0] lba;
wire [31:0] sector_cnt;
wire dma_type;
wire dma_start;
wire dma_done;
// axi-hp clock
wire hclk;
// dma_control <-> dma_adapter command iface
wire adp_busy;
wire [31:7] adp_addr;
wire adp_type;
wire adp_val;
// dma_control <-> sata_host command iface
wire host_ready_for_cmd;
wire host_new_cmd;
wire [1:0] host_cmd_type;
wire [31:0] host_sector_count;
wire [31:0] host_sector_addr;
// dma_control <-> dma_adapter data iface
wire [63:0] to_data;
wire to_val;
wire to_ack;
wire [63:0] from_data;
wire from_val;
wire from_ack;
// dma_control <-> sata_host data iface
wire [31:0] in_data;
wire in_val;
wire in_busy;
wire [31:0] out_data;
wire out_val;
wire out_busy;
// adapter <-> membridge iface
wire [7:0] cmd_ad;
wire cmd_stb;
wire [7:0] status_ad;
wire status_rq;
wire status_start;
wire frame_start_chn;
wire next_page_chn;
wire cmd_wrmem;
wire page_ready_chn;
wire frame_done_chn;
wire [15:0] line_unfinished_chn1;
wire suspend_chn1;
wire xfer_reset_page_rd;
wire buf_wpage_nxt;
wire buf_wr;
wire [63:0] buf_wdata;
wire xfer_reset_page_wr;
wire buf_rpage_nxt;
wire buf_rd;
wire [63:0] buf_rdata;
// additional adapter <-> membridge wire
wire rdata_done; // = membridge.is_last_in_page & membridge.afi_rready;
// sata_host timer
wire host_sata_timer;
// sata_host diag
wire host_linkup;
wire host_plllkdet;
wire host_dcmlocked;
// temporary 150Mhz clk
wire gtrefclk;
assign rst = ARESETN;
axi_regs axi_regs(
// axi iface
.ACLK (ACLK),
.ARESETN (ARESETN),
.ARADDR (ARADDR),
.ARVALID (ARVALID),
.ARREADY (ARREADY),
.ARID (ARID),
.ARLOCK (ARLOCK),
.ARCACHE (ARCACHE),
.ARPROT (ARPROT),
.ARLEN (ARLEN),
.ARSIZE (ARSIZE),
.ARBURST (ARBURST),
.ARQOS (ARQOS),
.RDATA (RDATA),
.RVALID (RVALID),
.RREADY (RREADY),
.RID (RID),
.RLAST (RLAST),
.RRESP (RRESP),
.AWADDR (AWADDR),
.AWVALID (AWVALID),
.AWREADY (AWREADY),
.AWID (AWID),
.AWLOCK (AWLOCK),
.AWCACHE (AWCACHE),
.AWPROT (AWPROT),
.AWLEN (AWLEN),
.AWSIZE (AWSIZE),
.AWBURST (AWBURST),
.AWQOS (AWQOS),
.WDATA (WDATA),
.WVALID (WVALID),
.WREADY (WREADY),
.WID (WID),
.WLAST (WLAST),
.WSTRB (WSTRB),
.BVALID (BVALID),
.BREADY (BREADY),
.BID (BID),
.BRESP (BRESP),
// registers iface
.bram_rdata (bram_rdata),
.bram_waddr (bram_waddr),
.bram_wdata (bram_wdata),
.bram_raddr (bram_raddr),
.bram_wstb (bram_wstb),
.bram_wen (bram_wen),
.bram_ren (bram_ren),
.bram_regen (bram_regen)
);
/*
* Programmable sata controller registers
*/
dma_regs dma_regs(
.rst (rst),
.ACLK (ACLK),
.sclk (sclk),
// control iface
.mem_address (mem_address),
.lba (lba),
.sector_cnt (sector_cnt),
.dma_type (dma_type),
.dma_start (dma_start),
.dma_done (dma_done),
// axi buffer iface
.bram_rdata (bram_rdata),
.bram_raddr (bram_raddr),
.bram_waddr (bram_waddr),
.bram_wdata (bram_wdata),
.bram_wstb (bram_wstb),
.bram_wen (bram_wen),
.bram_ren (bram_ren),
.bram_regen (bram_regen)
);
dma_control dma_control(
.sclk (sclk),
.hclk (hclk),
.rst (rst),
// registers iface
.mem_address (mem_address),
.lba (lba),
.sector_cnt (sector_cnt),
.dma_type (dma_type),
.dma_start (dma_start),
.dma_done (dma_done),
// adapter command iface
.adp_busy (adp_busy),
.adp_addr (adp_addr),
.adp_type (adp_type),
.adp_val (adp_val),
// sata host command iface
.host_ready_for_cmd (host_ready_for_cmd),
.host_new_cmd (host_new_cmd),
.host_cmd_type (host_cmd_type),
.host_sector_count (host_sector_count),
.host_sector_addr (host_sector_addr),
// adapter data iface
// to main memory
.to_data (to_data),
.to_val (to_val),
.to_ack (to_ack),
// from main memory
.from_data (from_data),
.from_val (from_val),
.from_ack (from_ack),
// sata host iface
// data from sata host
.in_data (in_data),
.in_val (in_val),
.in_busy (in_busy),
// data to sata host
.out_data (out_data),
.out_val (out_val),
.out_busy (out_busy)
);
//assign rdata_done = membridge.is_last_in_page & membridge.afi_rready;
dma_adapter dma_adapter(
.clk (hclk),
.rst (rst),
// command iface
.cmd_type (adp_type),
.cmd_val (adp_val),
.cmd_addr (adp_addr),
.cmd_busy (adp_busy),
// data iface
.wr_data_in (to_data),
.wr_val_in (to_val),
.wr_ack_out (to_ack),
.rd_data_out (from_data),
.rd_val_out (from_val),
.rd_ack_in (from_ack),
// membridge iface
.cmd_ad (cmd_ad),
.cmd_stb (cmd_stb),
.status_ad (status_ad),
.status_rq (status_rq),
.status_start (status_start),
.frame_start_chn (frame_start_chn),
.next_page_chn (next_page_chn),
.cmd_wrmem (cmd_wrmem),
.page_ready_chn (page_ready_chn),
.frame_done_chn (frame_done_chn),
.line_unfinished_chn1 (line_unfinished_chn1),
.suspend_chn1 (suspend_chn1),
.xfer_reset_page_rd (xfer_reset_page_rd),
.buf_wpage_nxt (buf_wpage_nxt),
.buf_wr (buf_wr),
.buf_wdata (buf_wdata),
.xfer_reset_page_wr (xfer_reset_page_wr),
.buf_rpage_nxt (buf_rpage_nxt),
.buf_rd (buf_rd),
.buf_rdata (buf_rdata),
.rdata_done (rdata_done)
);
membridge /*#(
V .MEMBRIDGE_ADDR (),
.MEMBRIDGE_MASK (),
.MEMBRIDGE_CTRL (),
.MEMBRIDGE_STATUS_CNTRL (),
.MEMBRIDGE_LO_ADDR64 (),
.MEMBRIDGE_SIZE64 (),
.MEMBRIDGE_START64 (),
.MEMBRIDGE_LEN64 (),
.MEMBRIDGE_WIDTH64 (),
.MEMBRIDGE_MODE (),
.MEMBRIDGE_STATUS_REG (),
.FRAME_HEIGHT_BITS (),
.FRAME_WIDTH_BITS ()
)*/ membridge(
.rst (rst), // input
.mclk (hclk), // input
.hclk (hclk), // input
.cmd_ad (cmd_ad),
.cmd_stb (cmd_stb),
.status_ad (status_ad),
.status_rq (status_rq),
.status_start (status_start),
.frame_start_chn (frame_start_chn),
.next_page_chn (next_page_chn),
.cmd_wrmem (cmd_wrmem),
.page_ready_chn (page_ready_chn),
.frame_done_chn (frame_done_chn),
.line_unfinished_chn1 (line_unfinished_chn1),
.suspend_chn1 (suspend_chn1),
.xfer_reset_page_rd (xfer_reset_page_rd),
.buf_wpage_nxt (buf_wpage_nxt),
.buf_wr (buf_wr),
.buf_wdata (buf_wdata),
.xfer_reset_page_wr (xfer_reset_page_wr),
.buf_rpage_nxt (buf_rpage_nxt),
.buf_rd (buf_rd),
.buf_rdata (buf_rdata),
.afi_awaddr (afi_awaddr), // output[31:0]
.afi_awvalid (afi_awvalid), // output
.afi_awready (afi_awready), // input
.afi_awid (afi_awid), // output[5:0]
.afi_awlock (afi_awlock), // output[1:0]
.afi_awcache (afi_awcache), // output[3:0]
.afi_awprot (afi_awprot), // output[2:0]
.afi_awlen (afi_awlen), // output[3:0]
.afi_awsize (afi_awsize), // output[2:0]
.afi_awburst (afi_awburst), // output[1:0]
.afi_awqos (afi_awqos), // output[3:0]
.afi_wdata (afi_wdata), // output[63:0]
.afi_wvalid (afi_wvalid), // output
.afi_wready (afi_wready), // input
.afi_wid (afi_wid), // output[5:0]
.afi_wlast (afi_wlast), // output
.afi_wstrb (afi_wstrb), // output[7:0]
.afi_bvalid (afi_bvalid), // input
.afi_bready (afi_bready), // output
.afi_bid (afi_bid), // input[5:0]
.afi_bresp (afi_bresp), // input[1:0]
.afi_wcount (afi_wcount), // input[7:0]
.afi_wacount (afi_wacount), // input[5:0]
.afi_wrissuecap1en (afi_wrissuecap1en), // output
.afi_araddr (afi_araddr), // output[31:0]
.afi_arvalid (afi_arvalid), // output
.afi_arready (afi_arready), // input
.afi_arid (afi_arid), // output[5:0]
.afi_arlock (afi_arlock), // output[1:0]
.afi_arcache (afi_arcache), // output[3:0]
.afi_arprot (afi_arprot), // output[2:0]
.afi_arlen (afi_arlen), // output[3:0]
.afi_arsize (afi_arsize), // output[2:0]
.afi_arburst (afi_arburst), // output[1:0]
.afi_arqos (afi_arqos), // output[3:0]
.afi_rdata (afi_rdata), // input[63:0]
.afi_rvalid (afi_rvalid), // input
.afi_rready (afi_rready), // output
.afi_rid (afi_rid), // input[5:0]
.afi_rlast (afi_rlast), // input
.afi_rresp (afi_rresp), // input[2:0]
.afi_rcount (afi_rcount), // input[7:0]
.afi_racount (afi_racount), // input[2:0]
.afi_rdissuecap1en (afi_rdissuecap1en), // output
.rdata_done (rdata_done)
);
sata_host sata_host(
.ready_for_cmd (host_ready_for_cmd),
.new_cmd (host_new_cmd),
.cmd_type (host_cmd_type),
.sector_count (host_sector_count),
.sector_addr (host_sector_addr),
.sata_din (out_data),
.sata_din_we (out_val),
.sata_core_full (out_busy),
.sata_dout (in_data),
.sata_dout_re (in_val),
.sata_core_empty (in_busy),
.data_clk_in (sclk),
.data_clk_out (sclk),
.sata_timer (host_sata_timer),
.clkin_150 (gtrefclk),
.reset (rst),
.linkup (host_linkup),
.txp_out (TXP),
.txn_out (TXN),
.rxp_in (RXP),
.rxn_in (RXN),
.plllkdet (host_plllkdet),
.dcmlocked (host_dcmlocked)
);
/*
* Padding for an external input clock @ 150 MHz
* TODO!!! Shall be done on phy-level
*/
localparam [1:0] CLKSWING_CFG = 2'b11;
IBUFDS_GTE2 #(
.CLKRCV_TRST ("TRUE"),
.CLKCM_CFG ("TRUE"),
.CLKSWING_CFG (CLKSWING_CFG)
)
ext_clock_buf(
.I (REFCLK_PAD_P_IN),
.IB (REFCLK_PAD_N_IN),
.CEB (1'b0),
.O (gtrefclk),
.ODIV2 ()
);
endmodule
x393_sata-05c77d236b93a06053a6ec2d8ebcad493b999f28/simul/ 0000775 0000000 0000000 00000000000 12562737151 0021406 5 ustar 00root root 0000000 0000000 x393_sata-05c77d236b93a06053a6ec2d8ebcad493b999f28/simul/build 0000775 0000000 0000000 00000001620 12562737151 0022432 0 ustar 00root root 0000000 0000000 #!/bin/bash
LOGFILE_PATH="bld.log"
rm a.out
if [ "$SATA_PATH" == '' ]
then
export SATA_PATH=".."
fi
if [ "$UNISIMS_PATH" == '' ]
then
export UNISIMS_PATH="../x393/unisims"
fi
if [ "$HOST_PATH" == '' ]
then
export HOST_PATH="../host"
fi
if [ "$GTX_PATH" == '' ]
then
export GTX_PATH=$SATA_PATH
fi
iverilog -Wall $SATA_PATH/tb/tb_top.v $SATA_PATH/x393/glbl.v -I$SATA_PATH/tb -I$SATA_PATH -I$SATA_PATH/x393/axi -I$SATA_PATH/x393 -y$SATA_PATH/x393/util_modules -y$SATA_PATH/x393/wrap -y$UNISIMS_PATH -y$SATA_PATH/x393/memctrl -y$SATA_PATH/x393/axi -y$SATA_PATH/x393/simulation_modules $SATA_PATH/x393/simulation_modules/simul_axi_fifo_out.v -y$SATA_PATH/x393/
#iverilog $SATA_PATH/tb/tb_top.v $SATA_PATH/x393/glbl.v -f opts -stb -sglbl $1 2>&1| tee $LOGFILE_PATH
#-y$SATA_PATH/x393/util_modules -I$SATA_PATH/x393/ -I$SATA_PATH/x393/axi/ $SATA_PATH/tb/tb_axiregs.v -I$SATA_PATH/ -I$SATA_PATH/tb/
x393_sata-05c77d236b93a06053a6ec2d8ebcad493b999f28/simul/doall 0000775 0000000 0000000 00000000344 12562737151 0022430 0 ustar 00root root 0000000 0000000 #!/bin/bash
if [ ! -z "$1" ]
then
SAV_FILE=$1
else
SAV_FILE="save.gtkw"
fi
./build #-pfileline=1
./simul
if [ $? != 0 ]
then
echo "BUILD FAILED"
exit
fi
gtkwave test.vcd $SAV_FILE &> waves.log &
echo all done
x393_sata-05c77d236b93a06053a6ec2d8ebcad493b999f28/simul/opts 0000664 0000000 0000000 00000000541 12562737151 0022316 0 ustar 00root root 0000000 0000000 -v ${SATA_PATH}/x393/simulation_modules/simul_axi_fifo_out.v
-y ${SATA_PATH}/x393/simulation_modules
-y ${SATA_PATH}/x393/memctrl
-y ${SATA_PATH}/x393/wrap
-y ${UNISIMS_PATH}/
-y ${SATA_PATH}/x393/util_modules
-v ${SATA_PATH}/x393/axi_hp_clk.v
+incdir+${SATA_PATH}/tb/
+incdir+${SATA_PATH}/x393/
+incdir+${SATA_PATH}/x393/axi/
+incdir+${SATA_PATH}/
x393_sata-05c77d236b93a06053a6ec2d8ebcad493b999f28/simul/simul 0000775 0000000 0000000 00000000135 12562737151 0022464 0 ustar 00root root 0000000 0000000 #!/bin/bash
LOGFILE_PATH="sim.log"
/usr/local/bin/vvp a.out -v $1 #2>&1 | tee $LOGFILE_PATH
x393_sata-05c77d236b93a06053a6ec2d8ebcad493b999f28/synt/ 0000775 0000000 0000000 00000000000 12562737151 0021252 5 ustar 00root root 0000000 0000000 x393_sata-05c77d236b93a06053a6ec2d8ebcad493b999f28/synt/axi_regs.xdc 0000664 0000000 0000000 00000000130 12562737151 0023545 0 ustar 00root root 0000000 0000000 create_clock -period 20.000 -name axi_aclk -waveform {0.000 10.000} [get_nets axi_aclk]
x393_sata-05c77d236b93a06053a6ec2d8ebcad493b999f28/tb/ 0000775 0000000 0000000 00000000000 12562737151 0020662 5 ustar 00root root 0000000 0000000 x393_sata-05c77d236b93a06053a6ec2d8ebcad493b999f28/tb/tb_axiregs.v 0000664 0000000 0000000 00000016323 12562737151 0023205 0 ustar 00root root 0000000 0000000 /*******************************************************************************
* Module: tb
* Date: 2015-07-11
* Author: Alexey
* Description: testbench for axi_regs.v
*
* Copyright (c) 2015 Elphel, Inc.
* tb_axiregs.v 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, either version 3 of the License, or
* (at your option) any later version.
*
* tb_axiregs.v file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*******************************************************************************/
`timescale 1ns/1ns
`include "axi_regs.v"
`include "test_axi_regs.v"
module tb();
initial #1 $display("HI THERE");
initial
begin
$dumpfile("test.vcd");
$dumpvars(0,tb);
end
wire ACLK; // AXI PS Master GP1 Clock , input
wire ARESETN; // AXI PS Master GP1 Reset, output
wire [31:0] ARADDR; // AXI PS Master GP1 ARADDR[31:0], output
wire ARVALID; // AXI PS Master GP1 ARVALID, output
wire ARREADY; // AXI PS Master GP1 ARREADY, input
wire [11:0] ARID; // AXI PS Master GP1 ARID[11:0], output
wire [1:0] ARLOCK; // AXI PS Master GP1 ARLOCK[1:0], output
wire [3:0] ARCACHE; // AXI PS Master GP1 ARCACHE[3:0], output
wire [2:0] ARPROT; // AXI PS Master GP1 ARPROT[2:0], output
wire [3:0] ARLEN; // AXI PS Master GP1 ARLEN[3:0], output
wire [1:0] ARSIZE; // AXI PS Master GP1 ARSIZE[1:0], output
wire [1:0] ARBURST; // AXI PS Master GP1 ARBURST[1:0], output
wire [3:0] ARQOS; // AXI PS Master GP1 ARQOS[3:0], output
wire [31:0] RDATA; // AXI PS Master GP1 RDATA[31:0], input
wire RVALID; // AXI PS Master GP1 RVALID, input
wire RREADY; // AXI PS Master GP1 RREADY, output
wire [11:0] RID; // AXI PS Master GP1 RID[11:0], input
wire RLAST; // AXI PS Master GP1 RLAST, input
wire [1:0] RRESP; // AXI PS Master GP1 RRESP[1:0], input
wire [31:0] AWADDR; // AXI PS Master GP1 AWADDR[31:0], output
wire AWVALID; // AXI PS Master GP1 AWVALID, output
wire AWREADY; // AXI PS Master GP1 AWREADY, input
wire [11:0] AWID; // AXI PS Master GP1 AWID[11:0], output
wire [1:0] AWLOCK; // AXI PS Master GP1 AWLOCK[1:0], output
wire [3:0] AWCACHE; // AXI PS Master GP1 AWCACHE[3:0], output
wire [2:0] AWPROT; // AXI PS Master GP1 AWPROT[2:0], output
wire [3:0] AWLEN; // AXI PS Master GP1 AWLEN[3:0], outpu:t
wire [1:0] AWSIZE; // AXI PS Master GP1 AWSIZE[1:0], output
wire [1:0] AWBURST; // AXI PS Master GP1 AWBURST[1:0], output
wire [3:0] AWQOS; // AXI PS Master GP1 AWQOS[3:0], output
wire [31:0] WDATA; // AXI PS Master GP1 WDATA[31:0], output
wire WVALID; // AXI PS Master GP1 WVALID, output
wire WREADY; // AXI PS Master GP1 WREADY, input
wire [11:0] WID; // AXI PS Master GP1 WID[11:0], output
wire WLAST; // AXI PS Master GP1 WLAST, output
wire [3:0] WSTRB; // AXI PS Master GP1 WSTRB[3:0], output
wire BVALID; // AXI PS Master GP1 BVALID, input
wire BREADY; // AXI PS Master GP1 BREADY, output
wire [11:0] BID; // AXI PS Master GP1 BID[11:0], input
wire [1:0] BRESP; // AXI PS Master GP1 BRESP[1:0], input
/*
axibram_write dut(
.aclk (ACLK),
.rst (~ARESETN),
.awaddr (AWADDR),
.awvalid (AWVALID),
.awready (AWREADY),
.awid (AWID),
.awlen (AWLEN),
.awsize (AWSIZE),
.awburst (AWBURST),
.wdata (WDATA),
.wvalid (WVALID),
.wready (WREADY),
.wid (WID),
.wlast (WLAST),
.wstb (WSTRB),
.bvalid (BVALID),
.bready (BREADY),
.bid (BID),
.bresp (BRESP),
.pre_awaddr (),
.start_burst (),
.dev_ready (1'b1),
.bram_wclk (),
.bram_waddr (),
.bram_wen (),
.bram_wstb (),
.bram_wdata ()
);
axibram_read dut2(
.aclk (ACLK),
.rst (~ARESETN),
.araddr (ARADDR),
.arvalid (ARVALID),
.arready (ARREADY),
.arid (ARID),
.arlen (ARLEN),
.arsize (ARSIZE),
.arburst (ARBURST),
.rdata (RDATA),
.rvalid (RVALID),
.rready (RREADY),
.rid (RID),
.rlast (RLAST),
.rresp (RRESP),
.pre_araddr (),
.start_burst (),
.dev_ready (1'b1),
.bram_rclk (),
.bram_raddr (),
.bram_ren (bram_ren),
.bram_regen (),
.bram_rdata (bram_ren ? 32'hdeadbeef : 0)
);
*/
axi_regs dut(
.ACLK (ACLK),
.ARESETN (ARESETN),
.ARADDR (ARADDR),
.ARVALID (ARVALID),
.ARREADY (ARREADY),
.ARID (ARID),
.ARLOCK (ARLOCK),
.ARCACHE (ARCACHE),
.ARPROT (ARPROT),
.ARLEN (ARLEN),
.ARSIZE (ARSIZE),
.ARBURST (ARBURST),
.ARQOS (ARQOS),
.RDATA (RDATA),
.RVALID (RVALID),
.RREADY (RREADY),
.RID (RID),
.RLAST (RLAST),
.RRESP (RRESP),
.AWADDR (AWADDR),
.AWVALID (AWVALID),
.AWREADY (AWREADY),
.AWID (AWID),
.AWLOCK (AWLOCK),
.AWCACHE (AWCACHE),
.AWPROT (AWPROT),
.AWLEN (AWLEN),
.AWSIZE (AWSIZE),
.AWBURST (AWBURST),
.AWQOS (AWQOS),
.WDATA (WDATA),
.WVALID (WVALID),
.WREADY (WREADY),
.WID (WID),
.WLAST (WLAST),
.WSTRB (WSTRB),
.BVALID (BVALID),
.BREADY (BREADY),
.BID (BID),
.BRESP (BRESP)
);
test_axi_regs test(
.ACLK (ACLK),
.ARESETN (ARESETN),
.ARADDR (ARADDR),
.ARVALID (ARVALID),
.ARREADY (ARREADY),
.ARID (ARID),
.ARLOCK (ARLOCK),
.ARCACHE (ARCACHE),
.ARPROT (ARPROT),
.ARLEN (ARLEN),
.ARSIZE (ARSIZE),
.ARBURST (ARBURST),
.ARQOS (ARQOS),
.RDATA (RDATA),
.RVALID (RVALID),
.RREADY (RREADY),
.RID (RID),
.RLAST (RLAST),
.RRESP (RRESP),
.AWADDR (AWADDR),
.AWVALID (AWVALID),
.AWREADY (AWREADY),
.AWID (AWID),
.AWLOCK (AWLOCK),
.AWCACHE (AWCACHE),
.AWPROT (AWPROT),
.AWLEN (AWLEN),
.AWSIZE (AWSIZE),
.AWBURST (AWBURST),
.AWQOS (AWQOS),
.WDATA (WDATA),
.WVALID (WVALID),
.WREADY (WREADY),
.WID (WID),
.WLAST (WLAST),
.WSTRB (WSTRB),
.BVALID (BVALID),
.BREADY (BREADY),
.BID (BID),
.BRESP (BRESP)
);
endmodule
x393_sata-05c77d236b93a06053a6ec2d8ebcad493b999f28/tb/tb_top.v 0000664 0000000 0000000 00000047125 12562737151 0022351 0 ustar 00root root 0000000 0000000 /*******************************************************************************
* Module: tb
* Date: 2015-07-11
* Author: Alexey
* Description: testbench for top.v
*
* Copyright (c) 2015 Elphel, Inc.
* tb_top.v 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, either version 3 of the License, or
* (at your option) any later version.
*
* tb_top.v file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*******************************************************************************/
/*
* using x393_testbench01.tf style, contains a lot of copy-pasted code from there
*/
`timescale 1ns/1ps
`include "top.v"
module tb #(
`include "includes/x393_parameters.vh" // SuppressThisWarning VEditor - not used
`include "includes/x393_simulation_parameters.vh"
)
(
);
initial #1 $display("HI THERE");
initial
begin
$dumpfile("test.vcd");
$dumpvars(0,tb);
end
reg [11:0] ARID_IN_r;
reg [31:0] ARADDR_IN_r;
reg [3:0] ARLEN_IN_r;
reg [2:0] ARSIZE_IN_r;
reg [1:0] ARBURST_IN_r;
reg [11:0] AWID_IN_r;
reg [31:0] AWADDR_IN_r;
reg [3:0] AWLEN_IN_r;
reg [2:0] AWSIZE_IN_r;
reg [1:0] AWBURST_IN_r;
reg [11:0] WID_IN_r;
reg [31:0] WDATA_IN_r;
reg [3:0] WSTRB_IN_r;
reg WLAST_IN_r;
reg DEBUG1, DEBUG2, DEBUG3;
reg [11:0] GLOBAL_WRITE_ID=0;
reg [11:0] GLOBAL_READ_ID=0;
reg [11:0] LAST_ARID; // last issued ARID
// SuppressWarnings VEditor : assigned in $readmem() system task
wire [SIMUL_AXI_READ_WIDTH-1:0] SIMUL_AXI_ADDR_W;
// SuppressWarnings VEditor
wire SIMUL_AXI_MISMATCH;
// SuppressWarnings VEditor
reg [31:0] SIMUL_AXI_READ;
// SuppressWarnings VEditor
reg [SIMUL_AXI_READ_WIDTH-1:0] SIMUL_AXI_ADDR;
// SuppressWarnings VEditor
reg SIMUL_AXI_FULL; // some data available
wire SIMUL_AXI_EMPTY= ~rvalid && rready && (rid==LAST_ARID); //SuppressThisWarning VEditor : may be unused, just for simulation // use it to wait for?
reg [31:0] registered_rdata; // here read data from task
reg CLK;
reg RST;
reg AR_SET_CMD_r;
wire AR_READY;
reg AW_SET_CMD_r;
wire AW_READY;
reg W_SET_CMD_r;
wire W_READY;
reg [3:0] RD_LAG; // ready signal lag in axi read channel (0 - RDY=1, 1..15 - RDY is asserted N cycles after valid)
reg [3:0] B_LAG; // ready signal lag in axi arete response channel (0 - RDY=1, 1..15 - RDY is asserted N cycles after valid)
// Simulation modules interconnection
wire [11:0] arid;
wire [31:0] araddr;
wire [3:0] arlen;
wire [2:0] arsize;
wire [1:0] arburst;
// SuppressWarnings VEditor : assigned in $readmem(14) system task
wire [3:0] arcache;
// SuppressWarnings VEditor : assigned in $readmem() system task
wire [2:0] arprot;
wire arvalid;
wire arready;
wire [11:0] awid;
wire [31:0] awaddr;
wire [3:0] awlen;
wire [2:0] awsize;
wire [1:0] awburst;
// SuppressWarnings VEditor : assigned in $readmem() system task
wire [3:0] awcache;
// SuppressWarnings VEditor : assigned in $readmem() system task
wire [2:0] awprot;
wire awvalid;
wire awready;
wire [11:0] wid;
wire [31:0] wdata;
wire [3:0] wstrb;
wire wlast;
wire wvalid;
wire wready;
wire [31:0] rdata;
// SuppressWarnings VEditor : assigned in $readmem() system task
wire [11:0] rid;
wire rlast;
// SuppressWarnings VEditor : assigned in $readmem() system task
wire [1:0] rresp;
wire rvalid;
wire rready;
wire rstb=rvalid && rready;
// SuppressWarnings VEditor : assigned in $readmem() system task
wire [1:0] bresp;
// SuppressWarnings VEditor : assigned in $readmem() system task
wire [11:0] bid;
wire bvalid;
wire bready;
integer NUM_WORDS_READ;
integer NUM_WORDS_EXPECTED;
reg [15:0] ENABLED_CHANNELS = 0; // currently enabled memory channels
// integer SCANLINE_CUR_X;
// integer SCANLINE_CUR_Y;
wire AXI_RD_EMPTY=NUM_WORDS_READ==NUM_WORDS_EXPECTED; //SuppressThisWarning VEditor : may be unused, just for simulation
wire [11:0] #(AXI_TASK_HOLD) ARID_IN = ARID_IN_r;
wire [31:0] #(AXI_TASK_HOLD) ARADDR_IN = ARADDR_IN_r;
wire [3:0] #(AXI_TASK_HOLD) ARLEN_IN = ARLEN_IN_r;
wire [2:0] #(AXI_TASK_HOLD) ARSIZE_IN = ARSIZE_IN_r;
wire [1:0] #(AXI_TASK_HOLD) ARBURST_IN = ARBURST_IN_r;
wire [11:0] #(AXI_TASK_HOLD) AWID_IN = AWID_IN_r;
wire [31:0] #(AXI_TASK_HOLD) AWADDR_IN = AWADDR_IN_r;
wire [3:0] #(AXI_TASK_HOLD) AWLEN_IN = AWLEN_IN_r;
wire [2:0] #(AXI_TASK_HOLD) AWSIZE_IN = AWSIZE_IN_r;
wire [1:0] #(AXI_TASK_HOLD) AWBURST_IN = AWBURST_IN_r;
wire [11:0] #(AXI_TASK_HOLD) WID_IN = WID_IN_r;
wire [31:0] #(AXI_TASK_HOLD) WDATA_IN = WDATA_IN_r;
wire [ 3:0] #(AXI_TASK_HOLD) WSTRB_IN = WSTRB_IN_r;
wire #(AXI_TASK_HOLD) WLAST_IN = WLAST_IN_r;
wire #(AXI_TASK_HOLD) AR_SET_CMD = AR_SET_CMD_r;
wire #(AXI_TASK_HOLD) AW_SET_CMD = AW_SET_CMD_r;
wire #(AXI_TASK_HOLD) W_SET_CMD = W_SET_CMD_r;
always #(CLKIN_PERIOD/2) CLK = ~CLK;
/*
* connect axi ports to the dut
*/
assign dut.ps7_i.FCLKCLK= {4{CLK}};
assign dut.ps7_i.FCLKRESETN= {RST,~RST,RST,~RST};
// Read address
assign dut.ps7_i.MAXIGP1ARADDR= araddr;
assign dut.ps7_i.MAXIGP1ARVALID= arvalid;
assign arready= dut.ps7_i.MAXIGP1ARREADY;
assign dut.ps7_i.MAXIGP1ARID= arid;
assign dut.ps7_i.MAXIGP1ARLEN= arlen;
assign dut.ps7_i.MAXIGP1ARSIZE= arsize[1:0]; // arsize[2] is not used
assign dut.ps7_i.MAXIGP1ARBURST= arburst;
// Read data
assign rdata= dut.ps7_i.MAXIGP1RDATA;
assign rvalid= dut.ps7_i.MAXIGP1RVALID;
assign dut.ps7_i.MAXIGP1RREADY= rready;
assign rid= dut.ps7_i.MAXIGP1RID;
assign rlast= dut.ps7_i.MAXIGP1RLAST;
assign rresp= dut.ps7_i.MAXIGP1RRESP;
// Write address
assign dut.ps7_i.MAXIGP1AWADDR= awaddr;
assign dut.ps7_i.MAXIGP1AWVALID= awvalid;
assign awready= dut.ps7_i.MAXIGP1AWREADY;
//assign awready= AWREADY_AAAA;
assign dut.ps7_i.MAXIGP1AWID=awid;
// SuppressWarnings VEditor all
// wire [ 1:0] AWLOCK;
// SuppressWarnings VEditor all
// wire [ 3:0] AWCACHE;
// SuppressWarnings VEditor all
// wire [ 2:0] AWPROT;
assign dut.ps7_i.MAXIGP1AWLEN= awlen;
assign dut.ps7_i.MAXIGP1AWSIZE= awsize[1:0]; // awsize[2] is not used
assign dut.ps7_i.MAXIGP1AWBURST= awburst;
// SuppressWarnings VEditor all
// wire [ 3:0] AWQOS;
// Write data
assign dut.ps7_i.MAXIGP1WDATA= wdata;
assign dut.ps7_i.MAXIGP1WVALID= wvalid;
assign wready= dut.ps7_i.MAXIGP1WREADY;
assign dut.ps7_i.MAXIGP1WID= wid;
assign dut.ps7_i.MAXIGP1WLAST= wlast;
assign dut.ps7_i.MAXIGP1WSTRB= wstrb;
// Write response
assign bvalid= dut.ps7_i.MAXIGP1BVALID;
assign dut.ps7_i.MAXIGP1BREADY= bready;
assign bid= dut.ps7_i.MAXIGP1BID;
assign bresp= dut.ps7_i.MAXIGP1BRESP;
// Simulation modules
simul_axi_master_rdaddr
#(
.ID_WIDTH(12),
.ADDRESS_WIDTH(32),
.LATENCY(AXI_RDADDR_LATENCY), // minimal delay between inout and output ( 0 - next cycle)
.DEPTH(8), // maximal number of commands in FIFO
.DATA_DELAY(3.5),
.VALID_DELAY(4.0)
) simul_axi_master_rdaddr_i (
.clk(CLK),
.reset(RST),
.arid_in(ARID_IN[11:0]),
.araddr_in(ARADDR_IN[31:0]),
.arlen_in(ARLEN_IN[3:0]),
.arsize_in(ARSIZE_IN[2:0]),
.arburst_in(ARBURST_IN[1:0]),
.arcache_in(4'b0),
.arprot_in(3'b0), // .arprot_in(2'b0),
.arid(arid[11:0]),
.araddr(araddr[31:0]),
.arlen(arlen[3:0]),
.arsize(arsize[2:0]),
.arburst(arburst[1:0]),
.arcache(arcache[3:0]),
.arprot(arprot[2:0]),
.arvalid(arvalid),
.arready(arready),
.set_cmd(AR_SET_CMD), // latch all other input data at posedge of clock
.ready(AR_READY) // command/data FIFO can accept command
);
simul_axi_master_wraddr
#(
.ID_WIDTH(12),
.ADDRESS_WIDTH(32),
.LATENCY(AXI_WRADDR_LATENCY), // minimal delay between inout and output ( 0 - next cycle)
.DEPTH(8), // maximal number of commands in FIFO
.DATA_DELAY(3.5),
.VALID_DELAY(4.0)
) simul_axi_master_wraddr_i (
.clk(CLK),
.reset(RST),
.awid_in(AWID_IN[11:0]),
.awaddr_in(AWADDR_IN[31:0]),
.awlen_in(AWLEN_IN[3:0]),
.awsize_in(AWSIZE_IN[2:0]),
.awburst_in(AWBURST_IN[1:0]),
.awcache_in(4'b0),
.awprot_in(3'b0), //.awprot_in(2'b0),
.awid(awid[11:0]),
.awaddr(awaddr[31:0]),
.awlen(awlen[3:0]),
.awsize(awsize[2:0]),
.awburst(awburst[1:0]),
.awcache(awcache[3:0]),
.awprot(awprot[2:0]),
.awvalid(awvalid),
.awready(awready),
.set_cmd(AW_SET_CMD), // latch all other input data at posedge of clock
.ready(AW_READY) // command/data FIFO can accept command
);
simul_axi_master_wdata
#(
.ID_WIDTH(12),
.DATA_WIDTH(32),
.WSTB_WIDTH(4),
.LATENCY(AXI_WRDATA_LATENCY), // minimal delay between inout and output ( 0 - next cycle)
.DEPTH(8), // maximal number of commands in FIFO
.DATA_DELAY(3.2),
.VALID_DELAY(3.6)
) simul_axi_master_wdata_i (
.clk(CLK),
.reset(RST),
.wid_in(WID_IN[11:0]),
.wdata_in(WDATA_IN[31:0]),
.wstrb_in(WSTRB_IN[3:0]),
.wlast_in(WLAST_IN),
.wid(wid[11:0]),
.wdata(wdata[31:0]),
.wstrb(wstrb[3:0]),
.wlast(wlast),
.wvalid(wvalid),
.wready(wready),
.set_cmd(W_SET_CMD), // latch all other input data at posedge of clock
.ready(W_READY) // command/data FIFO can accept command
);
simul_axi_slow_ready simul_axi_slow_ready_read_i(
.clk(CLK),
.reset(RST), //input reset,
.delay(RD_LAG), //input [3:0] delay,
.valid(rvalid), // input valid,
.ready(rready) //output ready
);
simul_axi_slow_ready simul_axi_slow_ready_write_resp_i(
.clk(CLK),
.reset(RST), //input reset,
.delay(B_LAG), //input [3:0] delay,
.valid(bvalid), // input ADDRESS_NUMBER+2:0 valid,
.ready(bready) //output ready
);
simul_axi_read #(
.ADDRESS_WIDTH(SIMUL_AXI_READ_WIDTH)
) simul_axi_read_i(
.clk(CLK),
.reset(RST),
.last(rlast),
.data_stb(rstb),
.raddr(ARADDR_IN[SIMUL_AXI_READ_WIDTH+1:2]),
.rlen(ARLEN_IN),
.rcmd(AR_SET_CMD),
.addr_out(SIMUL_AXI_ADDR_W[SIMUL_AXI_READ_WIDTH-1:0]),
.burst(), // burst in progress - just debug
.err_out()); // data last does not match predicted or FIFO over/under run - just debug
reg EXT_REF_CLK_P = 1'b1;
reg EXT_REF_CLK_N = 1'b0;
// device-under-test instance
top dut(
.RXN (1'b0),
.RXP (1'b0),
.TXN (),
.TXP (),
.REFCLK_PAD_P_IN (EXT_REF_CLK_P),
.REFCLK_PAD_N_IN (EXT_REF_CLK_N)
);
// SAXI HP interface
// axi_hp simulation signals
wire HCLK;
wire [31:0] afi_sim_rd_address; // output[31:0]
wire [ 5:0] afi_sim_rid; // output[5:0] SuppressThisWarning VEditor - not used - just view
// reg afi_sim_rd_valid; // input
wire afi_sim_rd_valid; // input
wire afi_sim_rd_ready; // output
// reg [63:0] afi_sim_rd_data; // input[63:0]
wire [63:0] afi_sim_rd_data; // input[63:0]
wire [ 2:0] afi_sim_rd_cap; // output[2:0] SuppressThisWarning VEditor - not used - just view
wire [ 3:0] afi_sim_rd_qos; // output[3:0] SuppressThisWarning VEditor - not used - just view
wire [ 1:0] afi_sim_rd_resp; // input[1:0]
// reg [ 1:0] afi_sim_rd_resp; // input[1:0]
wire [31:0] afi_sim_wr_address; // output[31:0] SuppressThisWarning VEditor - not used - just view
wire [ 5:0] afi_sim_wid; // output[5:0] SuppressThisWarning VEditor - not used - just view
wire afi_sim_wr_valid; // output
wire afi_sim_wr_ready; // input
// reg afi_sim_wr_ready; // input
wire [63:0] afi_sim_wr_data; // output[63:0] SuppressThisWarning VEditor - not used - just view
wire [ 7:0] afi_sim_wr_stb; // output[7:0] SuppressThisWarning VEditor - not used - just view
wire [ 3:0] afi_sim_bresp_latency; // input[3:0]
// reg [ 3:0] afi_sim_bresp_latency; // input[3:0]
wire [ 2:0] afi_sim_wr_cap; // output[2:0] SuppressThisWarning VEditor - not used - just view
wire [ 3:0] afi_sim_wr_qos; // output[3:0] SuppressThisWarning VEditor - not used - just view
assign HCLK = dut.ps7_i.SAXIHP3ACLK; // shortcut name
// afi loopback
assign #1 afi_sim_rd_data= afi_sim_rd_ready?{2'h0,afi_sim_rd_address[31:3],1'h1, 2'h0,afi_sim_rd_address[31:3],1'h0}:64'bx;
assign #1 afi_sim_rd_valid = afi_sim_rd_ready;
assign #1 afi_sim_rd_resp = afi_sim_rd_ready?2'b0:2'bx;
assign #1 afi_sim_wr_ready = afi_sim_wr_valid;
assign #1 afi_sim_bresp_latency=4'h5;
// axi_hp register access
// PS memory mapped registers to read/write over a separate simulation bus running at HCLK, no waits
reg [31:0] PS_REG_ADDR;
reg PS_REG_WR;
reg PS_REG_RD;
reg [31:0] PS_REG_DIN;
wire [31:0] PS_REG_DOUT;
reg [31:0] PS_RDATA; // SuppressThisWarning VEditor - not used - just view
/*
reg [31:0] afi_reg_addr;
reg afi_reg_wr;
reg afi_reg_rd;
reg [31:0] afi_reg_din;
wire [31:0] afi_reg_dout;
reg [31:0] AFI_REG_RD; // SuppressThisWarning VEditor - not used - just view
*/
initial begin
PS_REG_ADDR <= 'bx;
PS_REG_WR <= 0;
PS_REG_RD <= 0;
PS_REG_DIN <= 'bx;
PS_RDATA <= 'bx;
end
always @ (posedge HCLK) if (PS_REG_RD) PS_RDATA <= PS_REG_DOUT;
simul_axi_hp_rd #(
.HP_PORT(3)
) simul_axi_hp_rd_i (
.rst (RST), // input
.aclk (dut.ps7_i.SAXIHP3ACLK), // input
.aresetn (), // output
.araddr (dut.ps7_i.SAXIHP3ARADDR[31:0]), // input[31:0]
.arvalid (dut.ps7_i.SAXIHP3ARVALID), // input
.arready (dut.ps7_i.SAXIHP3ARREADY), // output
.arid (dut.ps7_i.SAXIHP3ARID), // input[5:0]
.arlock (dut.ps7_i.SAXIHP3ARLOCK), // input[1:0]
.arcache (dut.ps7_i.SAXIHP3ARCACHE), // input[3:0]
.arprot (dut.ps7_i.SAXIHP3ARPROT), // input[2:0]
.arlen (dut.ps7_i.SAXIHP3ARLEN), // input[3:0]
.arsize (dut.ps7_i.SAXIHP3ARSIZE), // input[2:0]
.arburst (dut.ps7_i.SAXIHP3ARBURST), // input[1:0]
.arqos (dut.ps7_i.SAXIHP3ARQOS), // input[3:0]
.rdata (dut.ps7_i.SAXIHP3RDATA), // output[63:0]
.rvalid (dut.ps7_i.SAXIHP3RVALID), // output
.rready (dut.ps7_i.SAXIHP3RREADY), // input
.rid (dut.ps7_i.SAXIHP3RID), // output[5:0]
.rlast (dut.ps7_i.SAXIHP3RLAST), // output
.rresp (dut.ps7_i.SAXIHP3RRESP), // output[1:0]
.rcount (dut.ps7_i.SAXIHP3RCOUNT), // output[7:0]
.racount (dut.ps7_i.SAXIHP3RACOUNT), // output[2:0]
.rdissuecap1en (dut.ps7_i.SAXIHP3RDISSUECAP1EN), // input
.sim_rd_address (afi_sim_rd_address), // output[31:0]
.sim_rid (afi_sim_rid), // output[5:0]
.sim_rd_valid (afi_sim_rd_valid), // input
.sim_rd_ready (afi_sim_rd_ready), // output
.sim_rd_data (afi_sim_rd_data), // input[63:0]
.sim_rd_cap (afi_sim_rd_cap), // output[2:0]
.sim_rd_qos (afi_sim_rd_qos), // output[3:0]
.sim_rd_resp (afi_sim_rd_resp), // input[1:0]
.reg_addr (PS_REG_ADDR), // input[31:0]
.reg_wr (PS_REG_WR), // input
.reg_rd (PS_REG_RD), // input
.reg_din (PS_REG_DIN), // input[31:0]
.reg_dout (PS_REG_DOUT) // output[31:0]
);
simul_axi_hp_wr #(
.HP_PORT(3)
) simul_axi_hp_wr_i (
.rst (RST), // input
.aclk (dut.ps7_i.SAXIHP3ACLK), // input
.aresetn (), // output
.awaddr (dut.ps7_i.SAXIHP3AWADDR), // input[31:0]
.awvalid (dut.ps7_i.SAXIHP3AWVALID), // input
.awready (dut.ps7_i.SAXIHP3AWREADY), // output
.awid (dut.ps7_i.SAXIHP3AWID), // input[5:0]
.awlock (dut.ps7_i.SAXIHP3AWLOCK), // input[1:0]
.awcache (dut.ps7_i.SAXIHP3AWCACHE), // input[3:0]
.awprot (dut.ps7_i.SAXIHP3AWPROT), // input[2:0]
.awlen (dut.ps7_i.SAXIHP3AWLEN), // input[3:0]
.awsize (dut.ps7_i.SAXIHP3AWSIZE), // input[2:0]
.awburst (dut.ps7_i.SAXIHP3AWBURST), // input[1:0]
.awqos (dut.ps7_i.SAXIHP3AWQOS), // input[3:0]
.wdata (dut.ps7_i.SAXIHP3WDATA), // input[63:0]
.wvalid (dut.ps7_i.SAXIHP3WVALID), // input
.wready (dut.ps7_i.SAXIHP3WREADY), // output
.wid (dut.ps7_i.SAXIHP3WID), // input[5:0]
.wlast (dut.ps7_i.SAXIHP3WLAST), // input
.wstrb (dut.ps7_i.SAXIHP3WSTRB), // input[7:0]
.bvalid (dut.ps7_i.SAXIHP3BVALID), // output
.bready (dut.ps7_i.SAXIHP3BREADY), // input
.bid (dut.ps7_i.SAXIHP3BID), // output[5:0]
.bresp (dut.ps7_i.SAXIHP3BRESP), // output[1:0]
.wcount (dut.ps7_i.SAXIHP3WCOUNT), // output[7:0]
.wacount (dut.ps7_i.SAXIHP3WACOUNT), // output[5:0]
.wrissuecap1en (dut.ps7_i.SAXIHP3WRISSUECAP1EN), // input
.sim_wr_address (afi_sim_wr_address), // output[31:0]
.sim_wid (afi_sim_wid), // output[5:0]
.sim_wr_valid (afi_sim_wr_valid), // output
.sim_wr_ready (afi_sim_wr_ready), // input
.sim_wr_data (afi_sim_wr_data), // output[63:0]
.sim_wr_stb (afi_sim_wr_stb), // output[7:0]
.sim_bresp_latency(afi_sim_bresp_latency), // input[3:0]
.sim_wr_cap (afi_sim_wr_cap), // output[2:0]
.sim_wr_qos (afi_sim_wr_qos), // output[3:0]
.reg_addr (PS_REG_ADDR), // input[31:0]
.reg_wr (PS_REG_WR), // input
.reg_rd (PS_REG_RD), // input
.reg_din (PS_REG_DIN), // input[31:0]
.reg_dout (PS_REG_DOUT) // output[31:0]
);
// wire [ 3:0] SIMUL_ADD_ADDR;
always @ (posedge CLK) begin
if (RST) SIMUL_AXI_FULL <=0;
else if (rstb) SIMUL_AXI_FULL <=1;
if (RST) begin
NUM_WORDS_READ <= 0;
end else if (rstb) begin
NUM_WORDS_READ <= NUM_WORDS_READ + 1;
end
if (rstb) begin
SIMUL_AXI_ADDR <= SIMUL_AXI_ADDR_W;
SIMUL_AXI_READ <= rdata;
`ifdef DEBUG_RD_DATA
$display (" Read data (addr:data): 0x%x:0x%x @%t",SIMUL_AXI_ADDR_W,rdata,$time);
`endif
end
end
//tasks
`include "includes/x393_tasks01.vh"
`include "includes/x393_tasks_afi.vh"
// testing itself
`include "test_top.v"
endmodule
x393_sata-05c77d236b93a06053a6ec2d8ebcad493b999f28/tb/test_axi_regs.v 0000664 0000000 0000000 00000017701 12562737151 0023717 0 ustar 00root root 0000000 0000000 /*******************************************************************************
* Module: test_axi_regs
* Date: 2015-07-11
* Author: Alexey
* Description: test generator for axi_regs.v
*
* Copyright (c) 2015 Elphel, Inc.
* test_axi_regs.v 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, either version 3 of the License, or
* (at your option) any later version.
*
* test_axi_regs.v file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*******************************************************************************/
module test_axi_regs(
output reg ACLK,
output reg ARESETN,
// AXI PS Master GP1: Read Address
output reg [31:0] ARADDR,
output reg ARVALID,
input wire ARREADY,
output reg [11:0] ARID,
output reg [1:0] ARLOCK,
output reg [3:0] ARCACHE,
output reg [2:0] ARPROT,
output reg [3:0] ARLEN,
output reg [1:0] ARSIZE,
output reg [1:0] ARBURST,
output reg [3:0] ARQOS,
// AXI PS Master GP1: Read Data
input wire [31:0] RDATA,
input wire RVALID,
output reg RREADY,
input wire [11:0] RID,
input wire RLAST,
input wire [1:0] RRESP,
// AXI PS Master GP1: Write Address
output reg [31:0] AWADDR,
output reg AWVALID,
input wire AWREADY,
output reg [11:0] AWID,
output reg [1:0] AWLOCK,
output reg [3:0] AWCACHE,
output reg [2:0] AWPROT,
output reg [3:0] AWLEN,
output reg [1:0] AWSIZE,
output reg [1:0] AWBURST,
output reg [3:0] AWQOS,
// AXI PS Master GP1: Write Data
output reg [31:0] WDATA,
output reg WVALID,
input wire WREADY,
output reg [11:0] WID,
output reg WLAST,
output reg [3:0] WSTRB,
// AXI PS Master GP1: Write Responce
input wire BVALID,
output reg BREADY,
input wire [11:0] BID,
input wire [1:0] BRESP
);
// finish
initial #5000 $finish;
// clock
initial
ACLK = 0;
always #5
ACLK = ~ACLK;
// reset
initial
begin
#50;
ARESETN <= 1'b1;
#50;
ARESETN <= 1'b0;
#50;
ARESETN <= 1'b1;
end
// Trying to write a word
initial
begin
ARVALID <= 1'b0;
ARADDR <= 1'b0;
ARID <= 1'b0;
ARLOCK <= 1'b0;
ARCACHE <= 1'b0;
ARPROT <= 1'b0;
ARLEN <= 1'b0;
ARSIZE <= 1'b0;
ARBURST <= 1'b0;
RREADY <= 1'b0;
AWVALID <= 1'b0;
AWADDR <= 1'b0;
AWID <= 1'b0;
AWLOCK <= 1'b0;
AWCACHE <= 1'b0;
AWPROT <= 1'b0;
AWLEN <= 1'b0;
AWSIZE <= 1'b0;
AWBURST <= 1'b0;
WVALID <= 1'b0;
WID <= 1'b0;
WSTRB <= 1'b0;
#220;
repeat (10)
@ (posedge ACLK);
AWVALID <= 1'b1;
AWADDR <= 32'h5;
AWID <= 1'b0;
AWLOCK <= 1'b0;
AWCACHE <= 1'b0;
AWPROT <= 1'b0;
AWLEN <= 1'b0;
AWSIZE <= 2'b10;
AWBURST <= 1'b0;
if (AWREADY == 1'b0)
@ (posedge AWREADY);
@ (posedge ACLK);
AWVALID <= 1'b0;
WDATA <= 32'hdeadbeef;
WVALID <= 1'b1;
WSTRB <= 4'b1011;
WID <= 12'h123;
if (WREADY == 1'b0)
@ (posedge WREADY);
@ (posedge ACLK);
WVALID <= 1'b0;
repeat (10)
@ (posedge ACLK);
// Trying to read a word
#170;
repeat (10)
@ (posedge ACLK);
ARADDR <= 32'h5;
ARVALID <= 1'b1;
ARID <= 1'b0;
ARLOCK <= 1'b0;
ARCACHE <= 1'b0;
ARPROT <= 1'b0;
ARLEN <= 1'b0;
ARSIZE <= 1'b0;
ARBURST <= 1'b0;
if (ARREADY == 1'b0)
@ (posedge ARREADY);
@ (posedge ACLK);
ARVALID <= 1'b0;
RREADY <= 1'b1;
if (RVALID == 1'b0)
@ (posedge RVALID);
@ (posedge ACLK);
RREADY <= 1'b0;
end
*/
// Simulation modules
simul_axi_master_rdaddr
#(
.ID_WIDTH(12),
.ADDRESS_WIDTH(32),
.LATENCY(AXI_RDADDR_LATENCY), // minimal delay between inout and output ( 0 - next cycle)
.DEPTH(8), // maximal number of commands in FIFO
.DATA_DELAY(3.5),
.VALID_DELAY(4.0)
) simul_axi_master_rdaddr_i (
.clk(CLK),
.reset(RST),
.arid_in(ARID_IN[11:0]),
.araddr_in(ARADDR_IN[31:0]),
.arlen_in(ARLEN_IN[3:0]),
.arsize_in(ARSIZE_IN[2:0]),
.arburst_in(ARBURST_IN[1:0]),
.arcache_in(4'b0),
.arprot_in(3'b0), // .arprot_in(2'b0),
.arid(arid[11:0]),
.araddr(araddr[31:0]),
.arlen(arlen[3:0]),
.arsize(arsize[2:0]),
.arburst(arburst[1:0]),
.arcache(arcache[3:0]),
.arprot(arprot[2:0]),
.arvalid(arvalid),
.arready(arready),
.set_cmd(AR_SET_CMD), // latch all other input data at posedge of clock
.ready(AR_READY) // command/data FIFO can accept command
);
simul_axi_master_wraddr
#(
.ID_WIDTH(12),
.ADDRESS_WIDTH(32),
.LATENCY(AXI_WRADDR_LATENCY), // minimal delay between inout and output ( 0 - next cycle)
.DEPTH(8), // maximal number of commands in FIFO
.DATA_DELAY(3.5),
.VALID_DELAY(4.0)
) simul_axi_master_wraddr_i (
.clk(CLK),
.reset(RST),
.awid_in(AWID_IN[11:0]),
.awaddr_in(AWADDR_IN[31:0]),
.awlen_in(AWLEN_IN[3:0]),
.awsize_in(AWSIZE_IN[2:0]),
.awburst_in(AWBURST_IN[1:0]),
.awcache_in(4'b0),
.awprot_in(3'b0), //.awprot_in(2'b0),
.awid(awid[11:0]),
.awaddr(awaddr[31:0]),
.awlen(awlen[3:0]),
.awsize(awsize[2:0]),
.awburst(awburst[1:0]),
.awcache(awcache[3:0]),
.awprot(awprot[2:0]),
.awvalid(awvalid),
.awready(awready),
.set_cmd(AW_SET_CMD), // latch all other input data at posedge of clock
.ready(AW_READY) // command/data FIFO can accept command
);
simul_axi_master_wdata
#(
.ID_WIDTH(12),
.DATA_WIDTH(32),
.WSTB_WIDTH(4),
.LATENCY(AXI_WRDATA_LATENCY), // minimal delay between inout and output ( 0 - next cycle)
.DEPTH(8), // maximal number of commands in FIFO
.DATA_DELAY(3.2),
.VALID_DELAY(3.6)
) simul_axi_master_wdata_i (
.clk(CLK),
.reset(RST),
.wid_in(WID_IN[11:0]),
.wdata_in(WDATA_IN[31:0]),
.wstrb_in(WSTRB_IN[3:0]),
.wlast_in(WLAST_IN),
.wid(wid[11:0]),
.wdata(wdata[31:0]),
.wstrb(wstrb[3:0]),
.wlast(wlast),
.wvalid(wvalid),
.wready(wready),
.set_cmd(W_SET_CMD), // latch all other input data at posedge of clock
.ready(W_READY) // command/data FIFO can accept command
);
simul_axi_slow_ready simul_axi_slow_ready_read_i(
.clk(CLK),
.reset(RST), //input reset,
.delay(RD_LAG), //input [3:0] delay,
.valid(rvalid), // input valid,
.ready(rready) //output ready
);
simul_axi_slow_ready simul_axi_slow_ready_write_resp_i(
.clk(CLK),
.reset(RST), //input reset,
.delay(B_LAG), //input [3:0] delay,
.valid(bvalid), // input ADDRESS_NUMBER+2:0 valid,
.ready(bready) //output ready
);
simul_axi_read #(
.ADDRESS_WIDTH(SIMUL_AXI_READ_WIDTH)
) simul_axi_read_i(
.clk(CLK),
.reset(RST),
.last(rlast),
.data_stb(rstb),
.raddr(ARADDR_IN[SIMUL_AXI_READ_WIDTH+1:2]),
.rlen(ARLEN_IN),
.rcmd(AR_SET_CMD),
.addr_out(SIMUL_AXI_ADDR_W[SIMUL_AXI_READ_WIDTH-1:0]),
.burst(), // burst in progress - just debug
.err_out()); // data last does not match predicted or FIFO over/under run - just debug
endmodule
x393_sata-05c77d236b93a06053a6ec2d8ebcad493b999f28/tb/test_top.v 0000664 0000000 0000000 00000004566 12562737151 0022725 0 ustar 00root root 0000000 0000000 /*******************************************************************************
* Module: tb
* Date: 2015-07-11
* Author: Alexey
* Description: dut inputs control for for tb_top.v
*
* Copyright (c) 2015 Elphel, Inc.
* test_top.v 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, either version 3 of the License, or
* (at your option) any later version.
*
* test_top.v file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*******************************************************************************/
/*
* this file is included into tb_top.v due to the compatibility with x393 design testbench
*/
// external clock to gtx
always #3.333
begin
EXT_REF_CLK_P = ~EXT_REF_CLK_P;
EXT_REF_CLK_N = ~EXT_REF_CLK_N;
end
// write registers
initial
begin
CLK =1'b0;
RST = 1'bx;
AR_SET_CMD_r = 1'b0;
AW_SET_CMD_r = 1'b0;
W_SET_CMD_r = 1'b0;
#500;
// $display ("x393_i.ddrc_sequencer_i.phy_cmd_i.phy_top_i.rst=%d",x393_i.ddrc_sequencer_i.phy_cmd_i.phy_top_i.rst);
#500;
RST = 1'b1;
NUM_WORDS_EXPECTED =0;
// #99000; // same as glbl
#900; // same as glbl
repeat (20) @(posedge CLK) ;
RST =1'b0;
repeat (20)
@ (posedge CLK);
// test MAXI1 inface
axi_set_rd_lag(0);
axi_write_single(32'h4, 32'hdeadbeef);
axi_read_addr(12'h777, 32'h4, 4'h3, 2'b01);
repeat (7)
@ (posedge CLK);
axi_write_single(32'h8, 32'hd34db33f);
axi_read_addr(12'h555, 32'h0, 4'h3, 2'b01);
// test SAXI3 iface
afi_setup(3);
axi_write_single(32'h10, 32'h0add9e55); // addr
axi_write_single(32'h14, 32'h12345678); // lba
axi_write_single(32'h18, 32'h00000020); // sector count
axi_write_single(32'h20, 32'h00100000); // dma type
axi_write_single(32'h24, 32'h00010000); // start
/* axi_write_single(32'h28, 32'hdeadbee2); // data
axi_write_single(32'h2c, 32'hdeadbee3); // data
axi_write_single(32'h1c, 32'hffffffff); // start */
end
initial
#10000 $finish;
x393_sata-05c77d236b93a06053a6ec2d8ebcad493b999f28/top.v 0000664 0000000 0000000 00000162406 12562737151 0021257 0 ustar 00root root 0000000 0000000 /*******************************************************************************
* Module: top
* Date: 2015-07-11
* Author: Alexey
* Description: top-level module, instantiates PS7 + sata host controller
*
* Copyright (c) 2015 Elphel, Inc.
* top.v 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, either version 3 of the License, or
* (at your option) any later version.
*
* top.v file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*******************************************************************************/
/*
* all signals' and modules' names and interconnections are taken from x393.v
* to make the final integration easier - just to make an instance of
* what is called now 'axi_regs' and connect it
*/
`include "system_defines.vh"
`include "sata_top.v"
module top #(
`include "includes/x393_parameters.vh"
)
(
// sata serial data iface
input wire RXN,
input wire RXP,
output wire TXN,
output wire TXP,
// sata clocking iface
input wire REFCLK_PAD_P_IN,
input wire REFCLK_PAD_N_IN
);
parameter REGISTERS_CNT = 20;
wire [32*REGISTERS_CNT - 1:0] outmem;
wire clrstart;
wire [3:0] fclk;
wire [3:0] frst;
wire axi_aclk;
wire axi_rst;
wire hclk;
wire comb_rst;
wire [31:0] ARADDR;
wire ARVALID;
wire ARREADY;
wire [11:0] ARID;
wire [1:0] ARLOCK;
wire [3:0] ARCACHE;
wire [2:0] ARPROT;
wire [3:0] ARLEN;
wire [1:0] ARSIZE;
wire [1:0] ARBURST;
wire [3:0] ARQOS;
wire [31:0] RDATA;
wire RVALID;
wire RREADY;
wire [11:0] RID;
wire RLAST;
wire [1:0] RRESP;
wire [31:0] AWADDR;
wire AWVALID;
wire AWREADY;
wire [11:0] AWID;
wire [1:0] AWLOCK;
wire [3:0] AWCACHE;
wire [2:0] AWPROT;
wire [3:0] AWLEN;
wire [1:0] AWSIZE;
wire [1:0] AWBURST;
wire [3:0] AWQOS;
wire [31:0] WDATA;
wire WVALID;
wire WREADY;
wire [11:0] WID;
wire WLAST;
wire [3:0] WSTRB;
wire BVALID;
wire BREADY;
wire [11:0] BID;
wire [1:0] BRESP;
reg axi_rst_pre;
// membridge
wire [31:0] afi0_awaddr; // output[31:0]
wire afi0_awvalid; // output
wire afi0_awready; // input
wire [ 5:0] afi0_awid; // output[5:0]
wire [ 1:0] afi0_awlock; // output[1:0]
wire [ 3:0] afi0_awcache; // output[3:0]
wire [ 2:0] afi0_awprot; // output[2:0]
wire [ 3:0] afi0_awlen; // output[3:0]
wire [ 2:0] afi0_awsize; // output[2:0]
wire [ 1:0] afi0_awburst; // output[1:0]
wire [ 3:0] afi0_awqos; // output[3:0]
wire [63:0] afi0_wdata; // output[63:0]
wire afi0_wvalid; // output
wire afi0_wready; // input
wire [ 5:0] afi0_wid; // output[5:0]
wire afi0_wlast; // output
wire [ 7:0] afi0_wstrb; // output[7:0]
wire afi0_bvalid; // input
wire afi0_bready; // output
wire [ 5:0] afi0_bid; // input[5:0]
wire [ 1:0] afi0_bresp; // input[1:0]
wire [ 7:0] afi0_wcount; // input[7:0]
wire [ 5:0] afi0_wacount; // input[5:0]
wire afi0_wrissuecap1en; // output
wire [31:0] afi0_araddr; // output[31:0]
wire afi0_arvalid; // output
wire afi0_arready; // input
wire [ 5:0] afi0_arid; // output[5:0]
wire [ 1:0] afi0_arlock; // output[1:0]
wire [ 3:0] afi0_arcache; // output[3:0]
wire [ 2:0] afi0_arprot; // output[2:0]
wire [ 3:0] afi0_arlen; // output[3:0]
wire [ 2:0] afi0_arsize; // output[2:0]
wire [ 1:0] afi0_arburst; // output[1:0]
wire [ 3:0] afi0_arqos; // output[3:0]
wire [63:0] afi0_rdata; // input[63:0]
wire afi0_rvalid; // input
wire afi0_rready; // output
wire [ 5:0] afi0_rid; // input[5:0]
wire afi0_rlast; // input
wire [ 1:0] afi0_rresp; // input[2:0]
wire [ 7:0] afi0_rcount; // input[7:0]
wire [ 2:0] afi0_racount; // input[2:0]
wire afi0_rdissuecap1en; // output
// send_dma
wire [7:0] cmd_ad;
wire cmd_stb;
wire [7:0] status_ad;
wire status_rq;
wire status_start;
wire frame_start_chn;
wire next_page_chn;
wire cmd_wrmem;
wire page_ready_chn;
wire frame_done_chn;
wire [15:0] line_unfinished_chn1;
wire suspend_chn1;
wire xfer_reset_page_rd;
wire buf_wpage_nxt;
wire buf_wr;
wire [63:0] buf_wdata;
wire xfer_reset_page_wr;
wire buf_rpage_nxt;
wire buf_rd;
wire [63:0] buf_rdata;
assign comb_rst=~frst[0] | frst[1];
always @(posedge comb_rst or posedge axi_aclk) begin
if (comb_rst) axi_rst_pre <= 1'b1;
else axi_rst_pre <= 1'b0;
end
BUFG bufg_axi_aclk_i (.O(axi_aclk),.I(fclk[0]));
BUFG bufg_axi_rst_i (.O(axi_rst),.I(axi_rst_pre));
axi_hp_clk #(
.CLKIN_PERIOD(20),
.CLKFBOUT_MULT_AXIHP(18),
.CLKFBOUT_DIV_AXIHP(6)
) axi_hp_clk_i (
.rst (axi_rst), // input
.clk_in (axi_aclk), // input
.clk_axihp (hclk), // output
.locked_axihp () // output // not controlled?
);
sata_top sata_top(
.ACLK (axi_aclk),
.ARESETN (axi_rst),
// AXI PS Master GP1: Read Address
.ARADDR (ARADDR),
.ARVALID (ARVALID),
.ARREADY (ARREADY),
.ARID (ARID),
.ARLOCK (ARLOCK),
.ARCACHE (ARCACHE),
.ARPROT (ARPROT),
.ARLEN (ARLEN),
.ARSIZE (ARSIZE),
.ARBURST (ARBURST),
.ARQOS (ARQOS),
// AXI PS Master GP1: Read Data
.RDATA (RDATA),
.RVALID (RVALID),
.RREADY (RREADY),
.RID (RID),
.RLAST (RLAST),
.RRESP (RRESP),
// AXI PS Master GP1: Write Address
.AWADDR (AWADDR),
.AWVALID (AWVALID),
.AWREADY (AWREADY),
.AWID (AWID),
.AWLOCK (AWLOCK),
.AWCACHE (AWCACHE),
.AWPROT (AWPROT),
.AWLEN (AWLEN),
.AWSIZE (AWSIZE),
.AWBURST (AWBURST),
.AWQOS (AWQOS),
// AXI PS Master GP1: Write Data
.WDATA (WDATA),
.WVALID (WVALID),
.WREADY (WREADY),
.WID (WID),
.WLAST (WLAST),
.WSTRB (WSTRB),
// AXI PS Master GP1: Write Responce
.BVALID (BVALID),
.BREADY (BREADY),
.BID (BID),
.BRESP (BRESP),
/*
* Data interface
*/
.afi_awaddr (afi0_awaddr),
.afi_awvalid (afi0_awvalid),
.afi_awready (afi0_awready),
.afi_awid (afi0_awid),
.afi_awlock (afi0_awlock),
.afi_awcache (afi0_awcache),
.afi_awprot (afi0_awprot),
.afi_awlen (afi0_awlen),
.afi_awsize (afi0_awsize),
.afi_awburst (afi0_awburst),
.afi_awqos (afi0_awqos),
// write data
.afi_wdata (afi0_wdata),
.afi_wvalid (afi0_wvalid),
.afi_wready (afi0_wready),
.afi_wid (afi0_wid),
.afi_wlast (afi0_wlast),
.afi_wstrb (afi0_wstrb),
// write response
.afi_bvalid (afi0_bvalid),
.afi_bready (afi0_bready),
.afi_bid (afi0_bid),
.afi_bresp (afi0_bresp),
// PL extra (non-AXI) signal
.afi_wcount (afi0_wcount),
.afi_wacount (afi0_wacount),
.afi_wrissuecap1en (afi0_wrissuecap1en),
// AXI_HP signals - read channel
// read address
.afi_araddr (afi0_araddr),
.afi_arvalid (afi0_arvalid),
.afi_arready (afi0_arready),
.afi_arid (afi0_arid),
.afi_arlock (afi0_arlock),
.afi_arcache (afi0_arcache),
.afi_arprot (afi0_arprot),
.afi_arlen (afi0_arlen),
.afi_arsize (afi0_arsize),
.afi_arburst (afi0_arburst),
.afi_arqos (afi0_arqos),
// read data
.afi_rdata (afi0_rdata),
.afi_rvalid (afi0_rvalid),
.afi_rready (afi0_rready),
.afi_rid (afi0_rid),
.afi_rlast (afi0_rlast),
.afi_rresp (afi0_rresp),
// PL extra (non-AXI) signal
.afi_rcount (afi0_rcount),
.afi_racount (afi0_racount),
.afi_rdissuecap1en (afi0_rdissuecap1en),
/*
* PHY
*/
.TXN (TXN),
.TXP (TXP),
.RXN (RXN),
.RXP (RXP),
.REFCLK_PAD_P_IN (REFCLK_PAD_P_IN),
.REFCLK_PAD_N_IN (REFCLK_PAD_N_IN)
);
PS7 ps7_i (
// EMIO interface
// CAN interface
.EMIOCAN0PHYTX(), // CAN 0 TX, output
.EMIOCAN0PHYRX(), // CAN 0 RX, input
.EMIOCAN1PHYTX(), // Can 1 TX, output
.EMIOCAN1PHYRX(), // CAN 1 RX, input
// GMII 0
.EMIOENET0GMIICRS(), // GMII 0 Carrier sense, input
.EMIOENET0GMIICOL(), // GMII 0 Collision detect, input
.EMIOENET0EXTINTIN(), // GMII 0 Controller Interrupt input, input
// GMII 0 TX signals
.EMIOENET0GMIITXCLK(), // GMII 0 TX clock, input
.EMIOENET0GMIITXD(), // GMII 0 Tx Data[7:0], output
.EMIOENET0GMIITXEN(), // GMII 0 Tx En, output
.EMIOENET0GMIITXER(), // GMII 0 Tx Err, output
// GMII 0 TX timestamp signals
.EMIOENET0SOFTX(), // GMII 0 Tx Tx Start-of-Frame, output
.EMIOENET0PTPDELAYREQTX(), // GMII 0 Tx PTP delay req frame detected, output
.EMIOENET0PTPPDELAYREQTX(), // GMII 0 Tx PTP peer delay frame detect, output
.EMIOENET0PTPPDELAYRESPTX(), // GMII 0 Tx PTP pear delay response frame detected, output
.EMIOENET0PTPSYNCFRAMETX(), // GMII 0 Tx PTP sync frame detected, output
// GMII 0 RX signals
.EMIOENET0GMIIRXCLK(), // GMII 0 Rx Clock, input
.EMIOENET0GMIIRXD(), // GMII 0 Rx Data (7:0), input
.EMIOENET0GMIIRXDV(), // GMII 0 Rx Data valid, input
.EMIOENET0GMIIRXER(), // GMII 0 Rx Error, input
// GMII 0 RX timestamp signals
.EMIOENET0SOFRX(), // GMII 0 Rx Start of Frame, output
.EMIOENET0PTPDELAYREQRX(), // GMII 0 Rx PTP delay req frame detected
.EMIOENET0PTPPDELAYREQRX(), // GMII 0 Rx PTP peer delay frame detected, output
.EMIOENET0PTPPDELAYRESPRX(), // GMII 0 Rx PTP peer delay responce frame detected, output
.EMIOENET0PTPSYNCFRAMERX(), // GMII 0 Rx PTP sync frame detected, output
// MDIO 0
.EMIOENET0MDIOMDC(), // MDIO 0 MD clock output, output
.EMIOENET0MDIOO(), // MDIO 0 MD data output, output
.EMIOENET0MDIOTN(), // MDIO 0 MD data 3-state, output
.EMIOENET0MDIOI(), // MDIO 0 MD data input, input
// GMII 1
.EMIOENET1GMIICRS(), // GMII 1 Carrier sense, input
.EMIOENET1GMIICOL(), // GMII 1 Collision detect, input
.EMIOENET1EXTINTIN(), // GMII 1 Controller Interrupt input, input
// GMII 1 TX signals
.EMIOENET1GMIITXCLK(), // GMII 1 TX clock, input
.EMIOENET1GMIITXD(), // GMII 1 Tx Data[7:0], output
.EMIOENET1GMIITXEN(), // GMII 1 Tx En, output
.EMIOENET1GMIITXER(), // GMII 1 Tx Err, output
// GMII 1 TX timestamp signals
.EMIOENET1SOFTX(), // GMII 1 Tx Tx Start-of-Frame, output
.EMIOENET1PTPDELAYREQTX(), // GMII 1 Tx PTP delay req frame detected, output
.EMIOENET1PTPPDELAYREQTX(), // GMII 1 Tx PTP peer delay frame detect, output
.EMIOENET1PTPPDELAYRESPTX(), // GMII 1 Tx PTP pear delay response frame detected, output
.EMIOENET1PTPSYNCFRAMETX(), // GMII 1 Tx PTP sync frame detected, output
// GMII 1 RX signals
.EMIOENET1GMIIRXCLK(), // GMII 1 Rx Clock, input
.EMIOENET1GMIIRXD(), // GMII 1 Rx Data (7:0), input
.EMIOENET1GMIIRXDV(), // GMII 1 Rx Data valid, input
.EMIOENET1GMIIRXER(), // GMII 1 Rx Error, input
// GMII 1 RX timestamp signals
.EMIOENET1SOFRX(), // GMII 1 Rx Start of Frame, output
.EMIOENET1PTPDELAYREQRX(), // GMII 1 Rx PTP delay req frame detected
.EMIOENET1PTPPDELAYREQRX(), // GMII 1 Rx PTP peer delay frame detected, output
.EMIOENET1PTPPDELAYRESPRX(), // GMII 1 Rx PTP peer delay responce frame detected, output
.EMIOENET1PTPSYNCFRAMERX(), // GMII 1 Rx PTP sync frame detected, output
// MDIO 1
.EMIOENET1MDIOMDC(), // MDIO 1 MD clock output, output
.EMIOENET1MDIOO(), // MDIO 1 MD data output, output
.EMIOENET1MDIOTN(), // MDIO 1 MD data 3-state, output
.EMIOENET1MDIOI(), // MDIO 1 MD data input, input
// EMIO GPIO
.EMIOGPIOO(), // EMIO GPIO Data out[63:0], output
.EMIOGPIOI(/*gpio_in[63:0]*/), // EMIO GPIO Data in[63:0], input
.EMIOGPIOTN(), // EMIO GPIO OutputEnable[63:0], output
// EMIO I2C 0
.EMIOI2C0SCLO(), // I2C 0 SCL OUT, output // manual says input
.EMIOI2C0SCLI(), // I2C 0 SCL IN, input // manual says output
.EMIOI2C0SCLTN(), // I2C 0 SCL EN, output // manual says input
.EMIOI2C0SDAO(), // I2C 0 SDA OUT, output // manual says input
.EMIOI2C0SDAI(), // I2C 0 SDA IN, input // manual says output
.EMIOI2C0SDATN(), // I2C 0 SDA EN, output // manual says input
// EMIO I2C 1
.EMIOI2C1SCLO(), // I2C 1 SCL OUT, output // manual says input
.EMIOI2C1SCLI(), // I2C 1 SCL IN, input // manual says output
.EMIOI2C1SCLTN(), // I2C 1 SCL EN, output // manual says input
.EMIOI2C1SDAO(), // I2C 1 SDA OUT, output // manual says input
.EMIOI2C1SDAI(), // I2C 1 SDA IN, input // manual says output
.EMIOI2C1SDATN(), // I2C 1 SDA EN, output // manual says input
// JTAG
.EMIOPJTAGTCK(), // JTAG TCK, input
.EMIOPJTAGTMS(), // JTAG TMS, input
.EMIOPJTAGTDI(), // JTAG TDI, input
.EMIOPJTAGTDO(), // JTAG TDO, output
.EMIOPJTAGTDTN(), // JTAG TDO OE, output
// SDIO 0
.EMIOSDIO0CLKFB(), // SDIO 0 Clock feedback, input
.EMIOSDIO0CLK(), // SDIO 0 Clock, output
.EMIOSDIO0CMDI(), // SDIO 0 Command in, input
.EMIOSDIO0CMDO(), // SDIO 0 Command out, output
.EMIOSDIO0CMDTN(), // SDIO 0 command OE, output
.EMIOSDIO0DATAI(), // SDIO 0 Data in [3:0], input
.EMIOSDIO0DATAO(), // SDIO 0 Data out [3:0], output
.EMIOSDIO0DATATN(), // SDIO 0 Data OE [3:0], output
.EMIOSDIO0CDN(), // SDIO 0 Card detect, input
.EMIOSDIO0WP(), // SDIO 0 Write protect, input
.EMIOSDIO0BUSPOW(), // SDIO 0 Power control, output
.EMIOSDIO0LED(), // SDIO 0 LED control, output
.EMIOSDIO0BUSVOLT(), // SDIO 0 Bus voltage [2:0], output
// SDIO 1
.EMIOSDIO1CLKFB(), // SDIO 1 Clock feedback, input
.EMIOSDIO1CLK(), // SDIO 1 Clock, output
.EMIOSDIO1CMDI(), // SDIO 1 Command in, input
.EMIOSDIO1CMDO(), // SDIO 1 Command out, output
.EMIOSDIO1CMDTN(), // SDIO 1 command OE, output
.EMIOSDIO1DATAI(), // SDIO 1 Data in [3:0], input
.EMIOSDIO1DATAO(), // SDIO 1 Data out [3:0], output
.EMIOSDIO1DATATN(), // SDIO 1 Data OE [3:0], output
.EMIOSDIO1CDN(), // SDIO 1 Card detect, input
.EMIOSDIO1WP(), // SDIO 1 Write protect, input
.EMIOSDIO1BUSPOW(), // SDIO 1 Power control, output
.EMIOSDIO1LED(), // SDIO 1 LED control, output
.EMIOSDIO1BUSVOLT(), // SDIO 1 Bus voltage [2:0], output
// SPI 0
.EMIOSPI0SCLKI(), // SPI 0 CLK in , input
.EMIOSPI0SCLKO(), // SPI 0 CLK out, output
.EMIOSPI0SCLKTN(), // SPI 0 CLK OE, output
.EMIOSPI0SI(), // SPI 0 MOSI in , input
.EMIOSPI0MO(), // SPI 0 MOSI out , output
.EMIOSPI0MOTN(), // SPI 0 MOSI OE, output
.EMIOSPI0MI(), // SPI 0 MISO in, input
.EMIOSPI0SO(), // SPI 0 MISO out, output
.EMIOSPI0STN(), // SPI 0 MISO OE, output
.EMIOSPI0SSIN(), // SPI 0 Slave select 0 in, input
.EMIOSPI0SSON(), // SPI 0 Slave select [2:0] out, output
.EMIOSPI0SSNTN(), // SPI 0 Slave select OE, output
// SPI 1
.EMIOSPI1SCLKI(), // SPI 1 CLK in , input
.EMIOSPI1SCLKO(), // SPI 1 CLK out, output
.EMIOSPI1SCLKTN(), // SPI 1 CLK OE, output
.EMIOSPI1SI(), // SPI 1 MOSI in , input
.EMIOSPI1MO(), // SPI 1 MOSI out , output
.EMIOSPI1MOTN(), // SPI 1 MOSI OE, output
.EMIOSPI1MI(), // SPI 1 MISO in, input
.EMIOSPI1SO(), // SPI 1 MISO out, output
.EMIOSPI1STN(), // SPI 1 MISO OE, output
.EMIOSPI1SSIN(), // SPI 1 Slave select 0 in, input
.EMIOSPI1SSON(), // SPI 1 Slave select [2:0] out, output
.EMIOSPI1SSNTN(), // SPI 1 Slave select OE, output
// TPIU signals (Trace)
.EMIOTRACECTL(), // Trace CTL, output
.EMIOTRACEDATA(), // Trace Data[31:0], output
.EMIOTRACECLK(), // Trace CLK, input
// Timers/counters
.EMIOTTC0CLKI(), // Counter/Timer 0 clock in [2:0], input
.EMIOTTC0WAVEO(), // Counter/Timer 0 wave out[2:0], output
.EMIOTTC1CLKI(), // Counter/Timer 1 clock in [2:0], input
.EMIOTTC1WAVEO(), // Counter/Timer 1 wave out[2:0], output
//UART 0
.EMIOUART0TX(), // UART 0 Transmit, output
.EMIOUART0RX(), // UART 0 Receive, input
.EMIOUART0CTSN(), // UART 0 Clear To Send, input
.EMIOUART0RTSN(), // UART 0 Ready to Send, output
.EMIOUART0DSRN(), // UART 0 Data Set Ready , input
.EMIOUART0DCDN(), // UART 0 Data Carrier Detect, input
.EMIOUART0RIN(), // UART 0 Ring Indicator, input
.EMIOUART0DTRN(), // UART 0 Data Terminal Ready, output
//UART 1
.EMIOUART1TX(), // UART 1 Transmit, output
.EMIOUART1RX(), // UART 1 Receive, input
.EMIOUART1CTSN(), // UART 1 Clear To Send, input
.EMIOUART1RTSN(), // UART 1 Ready to Send, output
.EMIOUART1DSRN(), // UART 1 Data Set Ready , input
.EMIOUART1DCDN(), // UART 1 Data Carrier Detect, input
.EMIOUART1RIN(), // UART 1 Ring Indicator, input
.EMIOUART1DTRN(), // UART 1 Data Terminal Ready, output
// USB 0
.EMIOUSB0PORTINDCTL(), // USB 0 Port Indicator [1:0], output
.EMIOUSB0VBUSPWRFAULT(), // USB 0 Power Fault, input
.EMIOUSB0VBUSPWRSELECT(), // USB 0 Power Select, output
// USB 1
.EMIOUSB1PORTINDCTL(), // USB 1 Port Indicator [1:0], output
.EMIOUSB1VBUSPWRFAULT(), // USB 1 Power Fault, input
.EMIOUSB1VBUSPWRSELECT(), // USB 1 Power Select, output
// Watchdog Timer
.EMIOWDTCLKI(), // Watchdog Timer Clock in, input
.EMIOWDTRSTO(), // Watchdog Timer Reset out, output
// DMAC 0
.DMA0ACLK(), // DMAC 0 Clock, input
.DMA0DRVALID(), // DMAC 0 DMA Request Valid, input
.DMA0DRLAST(), // DMAC 0 DMA Request Last, input
.DMA0DRTYPE(), // DMAC 0 DMA Request Type [1:0] ()single/burst/ackn flush/reserved), input
.DMA0DRREADY(), // DMAC 0 DMA Request Ready, output
.DMA0DAVALID(), // DMAC 0 DMA Acknowledge Valid (DA_TYPE[1:0] valid), output
.DMA0DAREADY(), // DMAC 0 DMA Acknowledge (peripheral can accept DA_TYPE[1:0]), input
.DMA0DATYPE(), // DMAC 0 DMA Ackbowledge TYpe (completed single AXI, completed burst AXI, flush request), output
.DMA0RSTN(), // DMAC 0 RESET output (reserved, do not use), output
// DMAC 1
.DMA1ACLK(), // DMAC 1 Clock, input
.DMA1DRVALID(), // DMAC 1 DMA Request Valid, input
.DMA1DRLAST(), // DMAC 1 DMA Request Last, input
.DMA1DRTYPE(), // DMAC 1 DMA Request Type [1:0] ()single/burst/ackn flush/reserved), input
.DMA1DRREADY(), // DMAC 1 DMA Request Ready, output
.DMA1DAVALID(), // DMAC 1 DMA Acknowledge Valid (DA_TYPE[1:0] valid), output
.DMA1DAREADY(), // DMAC 1 DMA Acknowledge (peripheral can accept DA_TYPE[1:0]), input
.DMA1DATYPE(), // DMAC 1 DMA Ackbowledge TYpe (completed single AXI, completed burst AXI, flush request), output
.DMA1RSTN(), // DMAC 1 RESET output (reserved, do not use), output
// DMAC 2
.DMA2ACLK(), // DMAC 2 Clock, input
.DMA2DRVALID(), // DMAC 2 DMA Request Valid, input
.DMA2DRLAST(), // DMAC 2 DMA Request Last, input
.DMA2DRTYPE(), // DMAC 2 DMA Request Type [1:0] ()single/burst/ackn flush/reserved), input
.DMA2DRREADY(), // DMAC 2 DMA Request Ready, output
.DMA2DAVALID(), // DMAC 2 DMA Acknowledge Valid (DA_TYPE[1:0] valid), output
.DMA2DAREADY(), // DMAC 2 DMA Acknowledge (peripheral can accept DA_TYPE[1:0]), input
.DMA2DATYPE(), // DMAC 2 DMA Ackbowledge TYpe (completed single AXI, completed burst AXI, flush request), output
.DMA2RSTN(), // DMAC 2 RESET output (reserved, do not use), output
// DMAC 3
.DMA3ACLK(), // DMAC 3 Clock, input
.DMA3DRVALID(), // DMAC 3 DMA Request Valid, input
.DMA3DRLAST(), // DMAC 3 DMA Request Last, input
.DMA3DRTYPE(), // DMAC 3 DMA Request Type [1:0] ()single/burst/ackn flush/reserved), input
.DMA3DRREADY(), // DMAC 3 DMA Request Ready, output
.DMA3DAVALID(), // DMAC 3 DMA Acknowledge Valid (DA_TYPE[1:0] valid), output
.DMA3DAREADY(), // DMAC 3 DMA Acknowledge (peripheral can accept DA_TYPE[1:0]), input
.DMA3DATYPE(), // DMAC 3 DMA Ackbowledge TYpe (completed single AXI, completed burst AXI, flush request), output
.DMA3RSTN(), // DMAC 3 RESET output (reserved, do not use), output
// Interrupt signals
.IRQF2P(), // Interrupts, OL to PS [19:0], input
.IRQP2F(), // Interrupts, OL to PS [28:0], output
// Event Signals
.EVENTEVENTI(), // EVENT Wake up one or both CPU from WFE state, input
.EVENTEVENTO(), // EVENT Asserted when one of the COUs executed SEV instruction, output
.EVENTSTANDBYWFE(), // EVENT CPU standby mode [1:0], asserted when CPU is waiting for an event, output
.EVENTSTANDBYWFI(), // EVENT CPU standby mode [1:0], asserted when CPU is waiting for an interrupt, output
// PL Resets and clocks
.FCLKCLK(fclk[3:0]), // PL Clocks [3:0], output
.FCLKCLKTRIGN(), // PL Clock Throttle Control [3:0], input
.FCLKRESETN(frst[3:0]), // PL General purpose user reset [3:0], output (active low)
// Debug signals
.FTMTP2FDEBUG(), // Debug General purpose debug output [31:0], output
.FTMTF2PDEBUG(), // Debug General purpose debug input [31:0], input
.FTMTP2FTRIG(), // Debug Trigger PS to PL [3:0], output
.FTMTP2FTRIGACK(), // Debug Trigger PS to PL acknowledge[3:0], input
.FTMTF2PTRIG(), // Debug Trigger PL to PS [3:0], input
.FTMTF2PTRIGACK(), // Debug Trigger PL to PS acknowledge[3:0], output
.FTMDTRACEINCLOCK(), // Debug Trace PL to PS Clock, input
.FTMDTRACEINVALID(), // Debug Trace PL to PS Clock, data&id valid, input
.FTMDTRACEINDATA(), // Debug Trace PL to PS data [31:0], input
.FTMDTRACEINATID(), // Debug Trace PL to PS ID [3:0], input
// DDR Urgent
.DDRARB(), // DDR Urgent[3:0], input
// SRAM interrupt (on rising edge)
.EMIOSRAMINTIN(), // SRAM interrupt #50 shared with NAND busy, input
// AXI interfaces
.FPGAIDLEN(1'b1), //Idle PL AXI interfaces (active low), input
// AXI PS Master GP0
// AXI PS Master GP0: Clock, Reset
.MAXIGP0ACLK(/*axi_aclk*/), // AXI PS Master GP0 Clock , input
// .MAXIGP0ACLK(/*fclk[0]*/), // AXI PS Master GP0 Clock , input
// .MAXIGP0ACLK(/*~fclk[0]*/), // AXI PS Master GP0 Clock , input
// .MAXIGP0ACLK(/*axi_naclk*/), // AXI PS Master GP0 Clock , input
//
.MAXIGP0ARESETN(), // AXI PS Master GP0 Reset, output
// AXI PS Master GP0: Read Address
.MAXIGP0ARADDR (/*axi_araddr[31:0]*/), // AXI PS Master GP0 ARADDR[31:0], output
.MAXIGP0ARVALID (/*axi_arvalid*/), // AXI PS Master GP0 ARVALID, output
.MAXIGP0ARREADY (/*axi_arready*/), // AXI PS Master GP0 ARREADY, input
.MAXIGP0ARID (/*axi_arid[11:0]*/), // AXI PS Master GP0 ARID[11:0], output
.MAXIGP0ARLOCK (), // AXI PS Master GP0 ARLOCK[1:0], output
.MAXIGP0ARCACHE (),// AXI PS Master GP0 ARCACHE[3:0], output
.MAXIGP0ARPROT(), // AXI PS Master GP0 ARPROT[2:0], output
.MAXIGP0ARLEN (/*axi_arlen[3:0]*/), // AXI PS Master GP0 ARLEN[3:0], output
.MAXIGP0ARSIZE (/*axi_arsize[1:0]*/), // AXI PS Master GP0 ARSIZE[1:0], output
.MAXIGP0ARBURST (/*axi_arburst[1:0]*/),// AXI PS Master GP0 ARBURST[1:0], output
.MAXIGP0ARQOS (), // AXI PS Master GP0 ARQOS[3:0], output
// AXI PS Master GP0: Read Data
.MAXIGP0RDATA (/*axi_rdata[31:0]*/), // AXI PS Master GP0 RDATA[31:0], input
.MAXIGP0RVALID (/*axi_rvalid*/), // AXI PS Master GP0 RVALID, input
.MAXIGP0RREADY (/*axi_rready*/), // AXI PS Master GP0 RREADY, output
.MAXIGP0RID (/*axi_rid[11:0]*/), // AXI PS Master GP0 RID[11:0], input
.MAXIGP0RLAST (/*axi_rlast*/), // AXI PS Master GP0 RLAST, input
.MAXIGP0RRESP (/*axi_rresp[1:0]*/), // AXI PS Master GP0 RRESP[1:0], input
// AXI PS Master GP0: Write Address
.MAXIGP0AWADDR (/*axi_awaddr[31:0]*/), // AXI PS Master GP0 AWADDR[31:0], output
.MAXIGP0AWVALID (/*axi_awvalid*/), // AXI PS Master GP0 AWVALID, output
.MAXIGP0AWREADY (/*axi_awready*/), // AXI PS Master GP0 AWREADY, input
.MAXIGP0AWID (/*axi_awid[11:0]*/), // AXI PS Master GP0 AWID[11:0], output
.MAXIGP0AWLOCK (), // AXI PS Master GP0 AWLOCK[1:0], output
.MAXIGP0AWCACHE (),// AXI PS Master GP0 AWCACHE[3:0], output
.MAXIGP0AWPROT (), // AXI PS Master GP0 AWPROT[2:0], output
.MAXIGP0AWLEN (/*axi_awlen[3:0]*/), // AXI PS Master GP0 AWLEN[3:0], output
.MAXIGP0AWSIZE (/*axi_awsize[1:0]*/), // AXI PS Master GP0 AWSIZE[1:0], output
.MAXIGP0AWBURST (/*axi_awburst[1:0]*/),// AXI PS Master GP0 AWBURST[1:0], output
.MAXIGP0AWQOS (), // AXI PS Master GP0 AWQOS[3:0], output
// AXI PS Master GP0: Write Data
.MAXIGP0WDATA (/*axi_wdata[31:0]*/), // AXI PS Master GP0 WDATA[31:0], output
.MAXIGP0WVALID (/*axi_wvalid*/), // AXI PS Master GP0 WVALID, output
.MAXIGP0WREADY (/*axi_wready*/), // AXI PS Master GP0 WREADY, input
.MAXIGP0WID (/*axi_wid[11:0]*/), // AXI PS Master GP0 WID[11:0], output
.MAXIGP0WLAST (/*axi_wlast*/), // AXI PS Master GP0 WLAST, output
.MAXIGP0WSTRB (/*axi_wstb[3:0]*/), // AXI PS Master GP0 WSTRB[3:0], output
// AXI PS Master GP0: Write Responce
.MAXIGP0BVALID (/*axi_bvalid*/), // AXI PS Master GP0 BVALID, input
.MAXIGP0BREADY (/*axi_bready*/), // AXI PS Master GP0 BREADY, output
.MAXIGP0BID (/*axi_bid[11:0]*/), // AXI PS Master GP0 BID[11:0], input
.MAXIGP0BRESP (/*axi_bresp[1:0]*/), // AXI PS Master GP0 BRESP[1:0], input
// AXI PS Master GP1
// AXI PS Master GP1: Clock, Reset
.MAXIGP1ACLK (axi_aclk), // AXI PS Master GP1 Clock , input
.MAXIGP1ARESETN (), // AXI PS Master GP1 Reset, output
// AXI PS Master GP1: Read Address
.MAXIGP1ARADDR (ARADDR), // AXI PS Master GP1 ARADDR[31:0], output
.MAXIGP1ARVALID (ARVALID), // AXI PS Master GP1 ARVALID, output
.MAXIGP1ARREADY (ARREADY), // AXI PS Master GP1 ARREADY, input
.MAXIGP1ARID (ARID), // AXI PS Master GP1 ARID[11:0], output
.MAXIGP1ARLOCK (ARLOCK), // AXI PS Master GP1 ARLOCK[1:0], output
.MAXIGP1ARCACHE (ARCACHE), // AXI PS Master GP1 ARCACHE[3:0], output
.MAXIGP1ARPROT (ARPROT), // AXI PS Master GP1 ARPROT[2:0], output
.MAXIGP1ARLEN (ARLEN), // AXI PS Master GP1 ARLEN[3:0], output
.MAXIGP1ARSIZE (ARSIZE), // AXI PS Master GP1 ARSIZE[1:0], output
.MAXIGP1ARBURST (ARBURST), // AXI PS Master GP1 ARBURST[1:0], output
.MAXIGP1ARQOS (ARQOS), // AXI PS Master GP1 ARQOS[3:0], output
// AXI PS Master GP1: Read Data
.MAXIGP1RDATA (RDATA), // AXI PS Master GP1 RDATA[31:0], input
.MAXIGP1RVALID (RVALID), // AXI PS Master GP1 RVALID, input
.MAXIGP1RREADY (RREADY), // AXI PS Master GP1 RREADY, output
.MAXIGP1RID (RID), // AXI PS Master GP1 RID[11:0], input
.MAXIGP1RLAST (RLAST), // AXI PS Master GP1 RLAST, input
.MAXIGP1RRESP (RRESP), // AXI PS Master GP1 RRESP[1:0], input
// AXI PS Master GP1: Write Address
.MAXIGP1AWADDR (AWADDR), // AXI PS Master GP1 AWADDR[31:0], output
.MAXIGP1AWVALID (AWVALID), // AXI PS Master GP1 AWVALID, output
.MAXIGP1AWREADY (AWREADY), // AXI PS Master GP1 AWREADY, input
.MAXIGP1AWID (AWID), // AXI PS Master GP1 AWID[11:0], output
.MAXIGP1AWLOCK (AWLOCK), // AXI PS Master GP1 AWLOCK[1:0], output
.MAXIGP1AWCACHE (AWCACHE), // AXI PS Master GP1 AWCACHE[3:0], output
.MAXIGP1AWPROT (AWPROT), // AXI PS Master GP1 AWPROT[2:0], output
.MAXIGP1AWLEN (AWLEN), // AXI PS Master GP1 AWLEN[3:0], output
.MAXIGP1AWSIZE (AWSIZE), // AXI PS Master GP1 AWSIZE[1:0], output
.MAXIGP1AWBURST (AWBURST), // AXI PS Master GP1 AWBURST[1:0], output
.MAXIGP1AWQOS (AWQOS), // AXI PS Master GP1 AWQOS[3:0], output
// AXI PS Master GP1: Write Data
.MAXIGP1WDATA (WDATA), // AXI PS Master GP1 WDATA[31:0], output
.MAXIGP1WVALID (WVALID), // AXI PS Master GP1 WVALID, output
.MAXIGP1WREADY (WREADY), // AXI PS Master GP1 WREADY, input
.MAXIGP1WID (WID), // AXI PS Master GP1 WID[11:0], output
.MAXIGP1WLAST (WLAST), // AXI PS Master GP1 WLAST, output
.MAXIGP1WSTRB (WSTRB), // AXI PS Master GP1 WSTRB[3:0], output
// AXI PS Master GP1: Write Responce
.MAXIGP1BVALID (BVALID), // AXI PS Master GP1 BVALID, input
.MAXIGP1BREADY (BREADY), // AXI PS Master GP1 BREADY, output
.MAXIGP1BID (BID), // AXI PS Master GP1 BID[11:0], input
.MAXIGP1BRESP (BRESP), // AXI PS Master GP1 BRESP[1:0], input
// AXI PS Slave GP0
// AXI PS Slave GP0: Clock, Reset
.SAXIGP0ACLK(), // AXI PS Slave GP0 Clock , input
.SAXIGP0ARESETN(), // AXI PS Slave GP0 Reset, output
// AXI PS Slave GP0: Read Address
.SAXIGP0ARADDR(), // AXI PS Slave GP0 ARADDR[31:0], input
.SAXIGP0ARVALID(), // AXI PS Slave GP0 ARVALID, input
.SAXIGP0ARREADY(), // AXI PS Slave GP0 ARREADY, output
.SAXIGP0ARID(), // AXI PS Slave GP0 ARID[5:0], input
.SAXIGP0ARLOCK(), // AXI PS Slave GP0 ARLOCK[1:0], input
.SAXIGP0ARCACHE(), // AXI PS Slave GP0 ARCACHE[3:0], input
.SAXIGP0ARPROT(), // AXI PS Slave GP0 ARPROT[2:0], input
.SAXIGP0ARLEN(), // AXI PS Slave GP0 ARLEN[3:0], input
.SAXIGP0ARSIZE(), // AXI PS Slave GP0 ARSIZE[1:0], input
.SAXIGP0ARBURST(), // AXI PS Slave GP0 ARBURST[1:0], input
.SAXIGP0ARQOS(), // AXI PS Slave GP0 ARQOS[3:0], input
// AXI PS Slave GP0: Read Data
.SAXIGP0RDATA(), // AXI PS Slave GP0 RDATA[31:0], output
.SAXIGP0RVALID(), // AXI PS Slave GP0 RVALID, output
.SAXIGP0RREADY(), // AXI PS Slave GP0 RREADY, input
.SAXIGP0RID(), // AXI PS Slave GP0 RID[5:0], output
.SAXIGP0RLAST(), // AXI PS Slave GP0 RLAST, output
.SAXIGP0RRESP(), // AXI PS Slave GP0 RRESP[1:0], output
// AXI PS Slave GP0: Write Address
.SAXIGP0AWADDR(), // AXI PS Slave GP0 AWADDR[31:0], input
.SAXIGP0AWVALID(), // AXI PS Slave GP0 AWVALID, input
.SAXIGP0AWREADY(), // AXI PS Slave GP0 AWREADY, output
.SAXIGP0AWID(), // AXI PS Slave GP0 AWID[5:0], input
.SAXIGP0AWLOCK(), // AXI PS Slave GP0 AWLOCK[1:0], input
.SAXIGP0AWCACHE(), // AXI PS Slave GP0 AWCACHE[3:0], input
.SAXIGP0AWPROT(), // AXI PS Slave GP0 AWPROT[2:0], input
.SAXIGP0AWLEN(), // AXI PS Slave GP0 AWLEN[3:0], input
.SAXIGP0AWSIZE(), // AXI PS Slave GP0 AWSIZE[1:0], input
.SAXIGP0AWBURST(), // AXI PS Slave GP0 AWBURST[1:0], input
.SAXIGP0AWQOS(), // AXI PS Slave GP0 AWQOS[3:0], input
// AXI PS Slave GP0: Write Data
.SAXIGP0WDATA(), // AXI PS Slave GP0 WDATA[31:0], input
.SAXIGP0WVALID(), // AXI PS Slave GP0 WVALID, input
.SAXIGP0WREADY(), // AXI PS Slave GP0 WREADY, output
.SAXIGP0WID(), // AXI PS Slave GP0 WID[5:0], input
.SAXIGP0WLAST(), // AXI PS Slave GP0 WLAST, input
.SAXIGP0WSTRB(), // AXI PS Slave GP0 WSTRB[3:0], input
// AXI PS Slave GP0: Write Responce
.SAXIGP0BVALID(), // AXI PS Slave GP0 BVALID, output
.SAXIGP0BREADY(), // AXI PS Slave GP0 BREADY, input
.SAXIGP0BID(), // AXI PS Slave GP0 BID[5:0], output //TODO: Update range !!!
.SAXIGP0BRESP(), // AXI PS Slave GP0 BRESP[1:0], output
// AXI PS Slave GP1
// AXI PS Slave GP1: Clock, Reset
.SAXIGP1ACLK(), // AXI PS Slave GP1 Clock , input
.SAXIGP1ARESETN(), // AXI PS Slave GP1 Reset, output
// AXI PS Slave GP1: Read Address
.SAXIGP1ARADDR(), // AXI PS Slave GP1 ARADDR[31:0], input
.SAXIGP1ARVALID(), // AXI PS Slave GP1 ARVALID, input
.SAXIGP1ARREADY(), // AXI PS Slave GP1 ARREADY, output
.SAXIGP1ARID(), // AXI PS Slave GP1 ARID[5:0], input
.SAXIGP1ARLOCK(), // AXI PS Slave GP1 ARLOCK[1:0], input
.SAXIGP1ARCACHE(), // AXI PS Slave GP1 ARCACHE[3:0], input
.SAXIGP1ARPROT(), // AXI PS Slave GP1 ARPROT[2:0], input
.SAXIGP1ARLEN(), // AXI PS Slave GP1 ARLEN[3:0], input
.SAXIGP1ARSIZE(), // AXI PS Slave GP1 ARSIZE[1:0], input
.SAXIGP1ARBURST(), // AXI PS Slave GP1 ARBURST[1:0], input
.SAXIGP1ARQOS(), // AXI PS Slave GP1 ARQOS[3:0], input
// AXI PS Slave GP1: Read Data
.SAXIGP1RDATA(), // AXI PS Slave GP1 RDATA[31:0], output
.SAXIGP1RVALID(), // AXI PS Slave GP1 RVALID, output
.SAXIGP1RREADY(), // AXI PS Slave GP1 RREADY, input
.SAXIGP1RID(), // AXI PS Slave GP1 RID[5:0], output
.SAXIGP1RLAST(), // AXI PS Slave GP1 RLAST, output
.SAXIGP1RRESP(), // AXI PS Slave GP1 RRESP[1:0], output
// AXI PS Slave GP1: Write Address
.SAXIGP1AWADDR(), // AXI PS Slave GP1 AWADDR[31:0], input
.SAXIGP1AWVALID(), // AXI PS Slave GP1 AWVALID, input
.SAXIGP1AWREADY(), // AXI PS Slave GP1 AWREADY, output
.SAXIGP1AWID(), // AXI PS Slave GP1 AWID[5:0], input
.SAXIGP1AWLOCK(), // AXI PS Slave GP1 AWLOCK[1:0], input
.SAXIGP1AWCACHE(), // AXI PS Slave GP1 AWCACHE[3:0], input
.SAXIGP1AWPROT(), // AXI PS Slave GP1 AWPROT[2:0], input
.SAXIGP1AWLEN(), // AXI PS Slave GP1 AWLEN[3:0], input
.SAXIGP1AWSIZE(), // AXI PS Slave GP1 AWSIZE[1:0], input
.SAXIGP1AWBURST(), // AXI PS Slave GP1 AWBURST[1:0], input
.SAXIGP1AWQOS(), // AXI PS Slave GP1 AWQOS[3:0], input
// AXI PS Slave GP1: Write Data
.SAXIGP1WDATA(), // AXI PS Slave GP1 WDATA[31:0], input
.SAXIGP1WVALID(), // AXI PS Slave GP1 WVALID, input
.SAXIGP1WREADY(), // AXI PS Slave GP1 WREADY, output
.SAXIGP1WID(), // AXI PS Slave GP1 WID[5:0], input
.SAXIGP1WLAST(), // AXI PS Slave GP1 WLAST, input
.SAXIGP1WSTRB(), // AXI PS Slave GP1 WSTRB[3:0], input
// AXI PS Slave GP1: Write Responce
.SAXIGP1BVALID(), // AXI PS Slave GP1 BVALID, output
.SAXIGP1BREADY(), // AXI PS Slave GP1 BREADY, input
.SAXIGP1BID(), // AXI PS Slave GP1 BID[5:0], output
.SAXIGP1BRESP(), // AXI PS Slave GP1 BRESP[1:0], output
// AXI PS Slave HP0
// AXI PS Slave HP0: Clock, Reset
.SAXIHP0ACLK(), // AXI PS Slave HP0 Clock , input
.SAXIHP0ARESETN(), // AXI PS Slave HP0 Reset, output
// AXI PS Slave HP0: Read Address
.SAXIHP0ARADDR(), // AXI PS Slave HP0 ARADDR[31:0], input
.SAXIHP0ARVALID(), // AXI PS Slave HP0 ARVALID, input
.SAXIHP0ARREADY(), // AXI PS Slave HP0 ARREADY, output
.SAXIHP0ARID(), // AXI PS Slave HP0 ARID[5:0], input
.SAXIHP0ARLOCK(), // AXI PS Slave HP0 ARLOCK[1:0], input
.SAXIHP0ARCACHE(), // AXI PS Slave HP0 ARCACHE[3:0], input
.SAXIHP0ARPROT(), // AXI PS Slave HP0 ARPROT[2:0], input
.SAXIHP0ARLEN(), // AXI PS Slave HP0 ARLEN[3:0], input
.SAXIHP0ARSIZE(), // AXI PS Slave HP0 ARSIZE[2:0], input
.SAXIHP0ARBURST(), // AXI PS Slave HP0 ARBURST[1:0], input
.SAXIHP0ARQOS(), // AXI PS Slave HP0 ARQOS[3:0], input
// AXI PS Slave HP0: Read Data
.SAXIHP0RDATA(), // AXI PS Slave HP0 RDATA[63:0], output
.SAXIHP0RVALID(), // AXI PS Slave HP0 RVALID, output
.SAXIHP0RREADY(), // AXI PS Slave HP0 RREADY, input
.SAXIHP0RID(), // AXI PS Slave HP0 RID[5:0], output
.SAXIHP0RLAST(), // AXI PS Slave HP0 RLAST, output
.SAXIHP0RRESP(), // AXI PS Slave HP0 RRESP[1:0], output
.SAXIHP0RCOUNT(), // AXI PS Slave HP0 RCOUNT[7:0], output
.SAXIHP0RACOUNT(), // AXI PS Slave HP0 RACOUNT[2:0], output
.SAXIHP0RDISSUECAP1EN(), // AXI PS Slave HP0 RDISSUECAP1EN, input
// AXI PS Slave HP0: Write Address
.SAXIHP0AWADDR(), // AXI PS Slave HP0 AWADDR[31:0], input
.SAXIHP0AWVALID(), // AXI PS Slave HP0 AWVALID, input
.SAXIHP0AWREADY(), // AXI PS Slave HP0 AWREADY, output
.SAXIHP0AWID(), // AXI PS Slave HP0 AWID[5:0], input
.SAXIHP0AWLOCK(), // AXI PS Slave HP0 AWLOCK[1:0], input
.SAXIHP0AWCACHE(), // AXI PS Slave HP0 AWCACHE[3:0], input
.SAXIHP0AWPROT(), // AXI PS Slave HP0 AWPROT[2:0], input
.SAXIHP0AWLEN(), // AXI PS Slave HP0 AWLEN[3:0], input
.SAXIHP0AWSIZE(), // AXI PS Slave HP0 AWSIZE[1:0], input
.SAXIHP0AWBURST(), // AXI PS Slave HP0 AWBURST[1:0], input
.SAXIHP0AWQOS(), // AXI PS Slave HP0 AWQOS[3:0], input
// AXI PS Slave HP0: Write Data
.SAXIHP0WDATA(), // AXI PS Slave HP0 WDATA[63:0], input
.SAXIHP0WVALID(), // AXI PS Slave HP0 WVALID, input
.SAXIHP0WREADY(), // AXI PS Slave HP0 WREADY, output
.SAXIHP0WID(), // AXI PS Slave HP0 WID[5:0], input
.SAXIHP0WLAST(), // AXI PS Slave HP0 WLAST, input
.SAXIHP0WSTRB(), // AXI PS Slave HP0 WSTRB[7:0], input
.SAXIHP0WCOUNT(), // AXI PS Slave HP0 WCOUNT[7:0], output
.SAXIHP0WACOUNT(), // AXI PS Slave HP0 WACOUNT[5:0], output
.SAXIHP0WRISSUECAP1EN(), // AXI PS Slave HP0 WRISSUECAP1EN, input
// AXI PS Slave HP0: Write Responce
.SAXIHP0BVALID(), // AXI PS Slave HP0 BVALID, output
.SAXIHP0BREADY(), // AXI PS Slave HP0 BREADY, input
.SAXIHP0BID(), // AXI PS Slave HP0 BID[5:0], output
.SAXIHP0BRESP(), // AXI PS Slave HP0 BRESP[1:0], output
// AXI PS Slave HP1
// AXI PS Slave 1: Clock, Reset
.SAXIHP1ACLK(), // AXI PS Slave HP1 Clock , input
.SAXIHP1ARESETN(), // AXI PS Slave HP1 Reset, output
// AXI PS Slave HP1: Read Address
.SAXIHP1ARADDR(), // AXI PS Slave HP1 ARADDR[31:0], input
.SAXIHP1ARVALID(), // AXI PS Slave HP1 ARVALID, input
.SAXIHP1ARREADY(), // AXI PS Slave HP1 ARREADY, output
.SAXIHP1ARID(), // AXI PS Slave HP1 ARID[5:0], input
.SAXIHP1ARLOCK(), // AXI PS Slave HP1 ARLOCK[1:0], input
.SAXIHP1ARCACHE(), // AXI PS Slave HP1 ARCACHE[3:0], input
.SAXIHP1ARPROT(), // AXI PS Slave HP1 ARPROT[2:0], input
.SAXIHP1ARLEN(), // AXI PS Slave HP1 ARLEN[3:0], input
.SAXIHP1ARSIZE(), // AXI PS Slave HP1 ARSIZE[2:0], input
.SAXIHP1ARBURST(), // AXI PS Slave HP1 ARBURST[1:0], input
.SAXIHP1ARQOS(), // AXI PS Slave HP1 ARQOS[3:0], input
// AXI PS Slave HP1: Read Data
.SAXIHP1RDATA(), // AXI PS Slave HP1 RDATA[63:0], output
.SAXIHP1RVALID(), // AXI PS Slave HP1 RVALID, output
.SAXIHP1RREADY(), // AXI PS Slave HP1 RREADY, input
.SAXIHP1RID(), // AXI PS Slave HP1 RID[5:0], output
.SAXIHP1RLAST(), // AXI PS Slave HP1 RLAST, output
.SAXIHP1RRESP(), // AXI PS Slave HP1 RRESP[1:0], output
.SAXIHP1RCOUNT(), // AXI PS Slave HP1 RCOUNT[7:0], output
.SAXIHP1RACOUNT(), // AXI PS Slave HP1 RACOUNT[2:0], output
.SAXIHP1RDISSUECAP1EN(), // AXI PS Slave HP1 RDISSUECAP1EN, input
// AXI PS Slave HP1: Write Address
.SAXIHP1AWADDR(), // AXI PS Slave HP1 AWADDR[31:0], input
.SAXIHP1AWVALID(), // AXI PS Slave HP1 AWVALID, input
.SAXIHP1AWREADY(), // AXI PS Slave HP1 AWREADY, output
.SAXIHP1AWID(), // AXI PS Slave HP1 AWID[5:0], input
.SAXIHP1AWLOCK(), // AXI PS Slave HP1 AWLOCK[1:0], input
.SAXIHP1AWCACHE(), // AXI PS Slave HP1 AWCACHE[3:0], input
.SAXIHP1AWPROT(), // AXI PS Slave HP1 AWPROT[2:0], input
.SAXIHP1AWLEN(), // AXI PS Slave HP1 AWLEN[3:0], input
.SAXIHP1AWSIZE(), // AXI PS Slave HP1 AWSIZE[1:0], input
.SAXIHP1AWBURST(), // AXI PS Slave HP1 AWBURST[1:0], input
.SAXIHP1AWQOS(), // AXI PS Slave HP1 AWQOS[3:0], input
// AXI PS Slave HP1: Write Data
.SAXIHP1WDATA(), // AXI PS Slave HP1 WDATA[63:0], input
.SAXIHP1WVALID(), // AXI PS Slave HP1 WVALID, input
.SAXIHP1WREADY(), // AXI PS Slave HP1 WREADY, output
.SAXIHP1WID(), // AXI PS Slave HP1 WID[5:0], input
.SAXIHP1WLAST(), // AXI PS Slave HP1 WLAST, input
.SAXIHP1WSTRB(), // AXI PS Slave HP1 WSTRB[7:0], input
.SAXIHP1WCOUNT(), // AXI PS Slave HP1 WCOUNT[7:0], output
.SAXIHP1WACOUNT(), // AXI PS Slave HP1 WACOUNT[5:0], output
.SAXIHP1WRISSUECAP1EN(), // AXI PS Slave HP1 WRISSUECAP1EN, input
// AXI PS Slave HP1: Write Responce
.SAXIHP1BVALID(), // AXI PS Slave HP1 BVALID, output
.SAXIHP1BREADY(), // AXI PS Slave HP1 BREADY, input
.SAXIHP1BID(), // AXI PS Slave HP1 BID[5:0], output
.SAXIHP1BRESP(), // AXI PS Slave HP1 BRESP[1:0], output
// AXI PS Slave HP2
// AXI PS Slave HP2: Clock, Reset
.SAXIHP2ACLK(), // AXI PS Slave HP2 Clock , input
.SAXIHP2ARESETN(), // AXI PS Slave HP2 Reset, output
// AXI PS Slave HP2: Read Address
.SAXIHP2ARADDR(), // AXI PS Slave HP2 ARADDR[31:0], input
.SAXIHP2ARVALID(), // AXI PS Slave HP2 ARVALID, input
.SAXIHP2ARREADY(), // AXI PS Slave HP2 ARREADY, output
.SAXIHP2ARID(), // AXI PS Slave HP2 ARID[5:0], input
.SAXIHP2ARLOCK(), // AXI PS Slave HP2 ARLOCK[1:0], input
.SAXIHP2ARCACHE(), // AXI PS Slave HP2 ARCACHE[3:0], input
.SAXIHP2ARPROT(), // AXI PS Slave HP2 ARPROT[2:0], input
.SAXIHP2ARLEN(), // AXI PS Slave HP2 ARLEN[3:0], input
.SAXIHP2ARSIZE(), // AXI PS Slave HP2 ARSIZE[2:0], input
.SAXIHP2ARBURST(), // AXI PS Slave HP2 ARBURST[1:0], input
.SAXIHP2ARQOS(), // AXI PS Slave HP2 ARQOS[3:0], input
// AXI PS Slave HP2: Read Data
.SAXIHP2RDATA(), // AXI PS Slave HP2 RDATA[63:0], output
.SAXIHP2RVALID(), // AXI PS Slave HP2 RVALID, output
.SAXIHP2RREADY(), // AXI PS Slave HP2 RREADY, input
.SAXIHP2RID(), // AXI PS Slave HP2 RID[5:0], output
.SAXIHP2RLAST(), // AXI PS Slave HP2 RLAST, output
.SAXIHP2RRESP(), // AXI PS Slave HP2 RRESP[1:0], output
.SAXIHP2RCOUNT(), // AXI PS Slave HP2 RCOUNT[7:0], output
.SAXIHP2RACOUNT(), // AXI PS Slave HP2 RACOUNT[2:0], output
.SAXIHP2RDISSUECAP1EN(), // AXI PS Slave HP2 RDISSUECAP1EN, input
// AXI PS Slave HP2: Write Address
.SAXIHP2AWADDR(), // AXI PS Slave HP2 AWADDR[31:0], input
.SAXIHP2AWVALID(), // AXI PS Slave HP2 AWVALID, input
.SAXIHP2AWREADY(), // AXI PS Slave HP2 AWREADY, output
.SAXIHP2AWID(), // AXI PS Slave HP2 AWID[5:0], input
.SAXIHP2AWLOCK(), // AXI PS Slave HP2 AWLOCK[1:0], input
.SAXIHP2AWCACHE(), // AXI PS Slave HP2 AWCACHE[3:0], input
.SAXIHP2AWPROT(), // AXI PS Slave HP2 AWPROT[2:0], input
.SAXIHP2AWLEN(), // AXI PS Slave HP2 AWLEN[3:0], input
.SAXIHP2AWSIZE(), // AXI PS Slave HP2 AWSIZE[1:0], input
.SAXIHP2AWBURST(), // AXI PS Slave HP2 AWBURST[1:0], input
.SAXIHP2AWQOS(), // AXI PS Slave HP2 AWQOS[3:0], input
// AXI PS Slave HP2: Write Data
.SAXIHP2WDATA(), // AXI PS Slave HP2 WDATA[63:0], input
.SAXIHP2WVALID(), // AXI PS Slave HP2 WVALID, input
.SAXIHP2WREADY(), // AXI PS Slave HP2 WREADY, output
.SAXIHP2WID(), // AXI PS Slave HP2 WID[5:0], input
.SAXIHP2WLAST(), // AXI PS Slave HP2 WLAST, input
.SAXIHP2WSTRB(), // AXI PS Slave HP2 WSTRB[7:0], input
.SAXIHP2WCOUNT(), // AXI PS Slave HP2 WCOUNT[7:0], output
.SAXIHP2WACOUNT(), // AXI PS Slave HP2 WACOUNT[5:0], output
.SAXIHP2WRISSUECAP1EN(), // AXI PS Slave HP2 WRISSUECAP1EN, input
// AXI PS Slave HP2: Write Responce
.SAXIHP2BVALID(), // AXI PS Slave HP2 BVALID, output
.SAXIHP2BREADY(), // AXI PS Slave HP2 BREADY, input
.SAXIHP2BID(), // AXI PS Slave HP2 BID[5:0], output
.SAXIHP2BRESP(), // AXI PS Slave HP2 BRESP[1:0], output
// AXI PS Slave HP3
// AXI PS Slave HP3: Clock, Reset
.SAXIHP3ACLK (hclk), // AXI PS Slave HP3 Clock , input
.SAXIHP3ARESETN(), // AXI PS Slave HP3 Reset, output
// AXI PS Slave HP3: Read Address
.SAXIHP3ARADDR (afi0_araddr), // AXI PS Slave HP3 ARADDR[31:0], input
.SAXIHP3ARVALID (afi0_arvalid), // AXI PS Slave HP3 ARVALID, input
.SAXIHP3ARREADY (afi0_arready), // AXI PS Slave HP3 ARREADY, output
.SAXIHP3ARID (afi0_arid), // AXI PS Slave HP3 ARID[5:0], input
.SAXIHP3ARLOCK (afi0_arlock), // AXI PS Slave HP3 ARLOCK[1:0], input
.SAXIHP3ARCACHE (afi0_arcache), // AXI PS Slave HP3 ARCACHE[3:0], input
.SAXIHP3ARPROT (afi0_arprot), // AXI PS Slave HP3 ARPROT[2:0], input
.SAXIHP3ARLEN (afi0_arlen), // AXI PS Slave HP3 ARLEN[3:0], input
.SAXIHP3ARSIZE (afi0_arsize), // AXI PS Slave HP3 ARSIZE[2:0], input
.SAXIHP3ARBURST (afi0_arburst), // AXI PS Slave HP3 ARBURST[1:0], input
.SAXIHP3ARQOS (afi0_arqos), // AXI PS Slave HP3 ARQOS[3:0], input
// AXI PS Slave HP3: Read Data
.SAXIHP3RDATA (afi0_rdata), // AXI PS Slave HP3 RDATA[63:0], output
.SAXIHP3RVALID (afi0_rvalid), // AXI PS Slave HP3 RVALID, output
.SAXIHP3RREADY (afi0_rready), // AXI PS Slave HP3 RREADY, input
.SAXIHP3RID (afi0_rid), // AXI PS Slave HP3 RID[5:0], output
.SAXIHP3RLAST (afi0_rlast), // AXI PS Slave HP3 RLAST, output
.SAXIHP3RRESP (afi0_rresp), // AXI PS Slave HP3 RRESP[1:0], output
.SAXIHP3RCOUNT (afi0_rcount), // AXI PS Slave HP3 RCOUNT[7:0], output
.SAXIHP3RACOUNT (afi0_racount), // AXI PS Slave HP3 RACOUNT[2:0], output
.SAXIHP3RDISSUECAP1EN (afi0_rdissuecap1en), // AXI PS Slave HP3 RDISSUECAP1EN, input
// AXI PS Slave HP3: Write Address
.SAXIHP3AWADDR (afi0_awaddr), // AXI PS Slave HP3 AWADDR[31:0], input
.SAXIHP3AWVALID (afi0_awvalid), // AXI PS Slave HP3 AWVALID, input
.SAXIHP3AWREADY (afi0_awready), // AXI PS Slave HP3 AWREADY, output
.SAXIHP3AWID (afi0_awid), // AXI PS Slave HP3 AWID[5:0], input
.SAXIHP3AWLOCK (afi0_awlock), // AXI PS Slave HP3 AWLOCK[1:0], input
.SAXIHP3AWCACHE (afi0_awcache), // AXI PS Slave HP3 AWCACHE[3:0], input
.SAXIHP3AWPROT (afi0_awprot), // AXI PS Slave HP3 AWPROT[2:0], input
.SAXIHP3AWLEN (afi0_awlen), // AXI PS Slave HP3 AWLEN[3:0], input
.SAXIHP3AWSIZE (afi0_awsize), // AXI PS Slave HP3 AWSIZE[1:0], input
.SAXIHP3AWBURST (afi0_awburst), // AXI PS Slave HP3 AWBURST[1:0], input
.SAXIHP3AWQOS (afi0_awqos), // AXI PS Slave HP3 AWQOS[3:0], input
// AXI PS Slave HP3: Write Data
.SAXIHP3WDATA (afi0_wdata), // AXI PS Slave HP3 WDATA[63:0], input
.SAXIHP3WVALID (afi0_wvalid), // AXI PS Slave HP3 WVALID, input
.SAXIHP3WREADY (afi0_wready), // AXI PS Slave HP3 WREADY, output
.SAXIHP3WID (afi0_wid), // AXI PS Slave HP3 WID[5:0], input
.SAXIHP3WLAST (afi0_wlast), // AXI PS Slave HP3 WLAST, input
.SAXIHP3WSTRB (afi0_wstrb), // AXI PS Slave HP3 WSTRB[7:0], input
.SAXIHP3WCOUNT (afi0_wcount), // AXI PS Slave HP3 WCOUNT[7:0], output
.SAXIHP3WACOUNT (afi0_wacount), // AXI PS Slave HP3 WACOUNT[5:0], output
.SAXIHP3WRISSUECAP1EN (afi0_wrissuecap1en), // AXI PS Slave HP3 WRISSUECAP1EN, input
// AXI PS Slave HP3: Write Responce
.SAXIHP3BVALID (afi0_bvalid), // AXI PS Slave HP3 BVALID, output
.SAXIHP3BREADY (afi0_bready), // AXI PS Slave HP3 BREADY, input
.SAXIHP3BID (afi0_bid), // AXI PS Slave HP3 BID[5:0], output
.SAXIHP3BRESP (afi0_bresp), // AXI PS Slave HP3 BRESP[1:0], output
// AXI PS Slave ACP
// AXI PS Slave ACP: Clock, Reset
.SAXIACPACLK(), // AXI PS Slave ACP Clock, input
.SAXIACPARESETN(), // AXI PS Slave ACP Reset, output
// AXI PS Slave ACP: Read Address
.SAXIACPARADDR(), // AXI PS Slave ACP ARADDR[31:0], input
.SAXIACPARVALID(), // AXI PS Slave ACP ARVALID, input
.SAXIACPARREADY(), // AXI PS Slave ACP ARREADY, output
.SAXIACPARID(), // AXI PS Slave ACP ARID[2:0], input
.SAXIACPARLOCK(), // AXI PS Slave ACP ARLOCK[1:0], input
.SAXIACPARCACHE(), // AXI PS Slave ACP ARCACHE[3:0], input
.SAXIACPARPROT(), // AXI PS Slave ACP ARPROT[2:0], input
.SAXIACPARLEN(), // AXI PS Slave ACP ARLEN[3:0], input
.SAXIACPARSIZE(), // AXI PS Slave ACP ARSIZE[2:0], input
.SAXIACPARBURST(), // AXI PS Slave ACP ARBURST[1:0], input
.SAXIACPARQOS(), // AXI PS Slave ACP ARQOS[3:0], input
.SAXIACPARUSER(), // AXI PS Slave ACP ARUSER[4:0], input
// AXI PS Slave ACP: Read Data
.SAXIACPRDATA(), // AXI PS Slave ACP RDATA[63:0], output
.SAXIACPRVALID(), // AXI PS Slave ACP RVALID, output
.SAXIACPRREADY(), // AXI PS Slave ACP RREADY, input
.SAXIACPRID(), // AXI PS Slave ACP RID[2:0], output
.SAXIACPRLAST(), // AXI PS Slave ACP RLAST, output
.SAXIACPRRESP(), // AXI PS Slave ACP RRESP[1:0], output
// AXI PS Slave ACP: Write Address
.SAXIACPAWADDR(), // AXI PS Slave ACP AWADDR[31:0], input
.SAXIACPAWVALID(), // AXI PS Slave ACP AWVALID, input
.SAXIACPAWREADY(), // AXI PS Slave ACP AWREADY, output
.SAXIACPAWID(), // AXI PS Slave ACP AWID[2:0], input
.SAXIACPAWLOCK(), // AXI PS Slave ACP AWLOCK[1:0], input
.SAXIACPAWCACHE(), // AXI PS Slave ACP AWCACHE[3:0], input
.SAXIACPAWPROT(), // AXI PS Slave ACP AWPROT[2:0], input
.SAXIACPAWLEN(), // AXI PS Slave ACP AWLEN[3:0], input
.SAXIACPAWSIZE(), // AXI PS Slave ACP AWSIZE[1:0], input
.SAXIACPAWBURST(), // AXI PS Slave ACP AWBURST[1:0], input
.SAXIACPAWQOS(), // AXI PS Slave ACP AWQOS[3:0], input
.SAXIACPAWUSER(), // AXI PS Slave ACP AWUSER[4:0], input
// AXI PS Slave ACP: Write Data
.SAXIACPWDATA(), // AXI PS Slave ACP WDATA[63:0], input
.SAXIACPWVALID(), // AXI PS Slave ACP WVALID, input
.SAXIACPWREADY(), // AXI PS Slave ACP WREADY, output
.SAXIACPWID(), // AXI PS Slave ACP WID[2:0], input
.SAXIACPWLAST(), // AXI PS Slave ACP WLAST, input
.SAXIACPWSTRB(), // AXI PS Slave ACP WSTRB[7:0], input
// AXI PS Slave ACP: Write Responce
.SAXIACPBVALID(), // AXI PS Slave ACP BVALID, output
.SAXIACPBREADY(), // AXI PS Slave ACP BREADY, input
.SAXIACPBID(), // AXI PS Slave ACP BID[2:0], output
.SAXIACPBRESP(), // AXI PS Slave ACP BRESP[1:0], output
// Direct connection to PS package pads
.DDRA(), // PS DDRA[14:0], inout
.DDRBA(), // PS DDRBA[2:0], inout
.DDRCASB(), // PS DDRCASB, inout
.DDRCKE(), // PS DDRCKE, inout
.DDRCKP(), // PS DDRCKP, inout
.DDRCKN(), // PS DDRCKN, inout
.DDRCSB(), // PS DDRCSB, inout
.DDRDM(), // PS DDRDM[3:0], inout
.DDRDQ(), // PS DDRDQ[31:0], inout
.DDRDQSP(), // PS DDRDQSP[3:0], inout
.DDRDQSN(), // PS DDRDQSN[3:0], inout
.DDRDRSTB(), // PS DDRDRSTB, inout
.DDRODT(), // PS DDRODT, inout
.DDRRASB(), // PS DDRRASB, inout
.DDRVRN(), // PS DDRVRN, inout
.DDRVRP(), // PS DDRVRP, inout
.DDRWEB(), // PS DDRWEB, inout
.MIO(), // PS MIO[53:0], inout // clg225 has less
.PSCLK(), // PS PSCLK, inout
.PSPORB(), // PS PSPORB, inout
.PSSRSTB() // PS PSSRSTB, inout
);
endmodule
x393_sata-05c77d236b93a06053a6ec2d8ebcad493b999f28/top_axi_regs.v 0000664 0000000 0000000 00000144022 12562737151 0023132 0 ustar 00root root 0000000 0000000 /*******************************************************************************
* Module: top
* Date: 2015-07-11
* Author: Alexey
* Description: top-level module, instantiates PS7 + sata host controller
*
* Copyright (c) 2015 Elphel, Inc.
* top.v 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, either version 3 of the License, or
* (at your option) any later version.
*
* top.v file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*******************************************************************************/
/*
* all signals' and modules' names and interconnections are taken from x393.v
* to make the final integration easier - just to make an instance of
* what is called now 'axi_regs' and connect it
*/
`include "system_defines.vh"
`include "axi_regs.v"
module top #(
`include "includes/x393_parameters.vh"
)
(
);
wire [3:0] fclk;
wire [3:0] frst;
wire axi_aclk;
wire axi_rst;
wire comb_rst;
wire [31:0] ARADDR;
wire ARVALID;
wire ARREADY;
wire [11:0] ARID;
wire [1:0] ARLOCK;
wire [3:0] ARCACHE;
wire [2:0] ARPROT;
wire [3:0] ARLEN;
wire [1:0] ARSIZE;
wire [1:0] ARBURST;
wire [3:0] ARQOS;
wire [31:0] RDATA;
wire RVALID;
wire RREADY;
wire [11:0] RID;
wire RLAST;
wire [1:0] RRESP;
wire [31:0] AWADDR;
wire AWVALID;
wire AWREADY;
wire [11:0] AWID;
wire [1:0] AWLOCK;
wire [3:0] AWCACHE;
wire [2:0] AWPROT;
wire [3:0] AWLEN;
wire [1:0] AWSIZE;
wire [1:0] AWBURST;
wire [3:0] AWQOS;
wire [31:0] WDATA;
wire WVALID;
wire WREADY;
wire [11:0] WID;
wire WLAST;
wire [3:0] WSTRB;
wire BVALID;
wire BREADY;
wire [11:0] BID;
wire [1:0] BRESP;
reg axi_rst_pre;
assign comb_rst=~frst[0] | frst[1];
always @(posedge comb_rst or posedge axi_aclk) begin
if (comb_rst) axi_rst_pre <= 1'b1;
else axi_rst_pre <= 1'b0;
end
BUFG bufg_axi_aclk_i (.O(axi_aclk),.I(fclk[0]));
BUFG bufg_axi_rst_i (.O(axi_rst),.I(axi_rst_pre));
axi_regs axi_regs(
.ACLK (axi_aclk),
.ARESETN (axi_rst),
.ARADDR (ARADDR),
.ARVALID (ARVALID),
.ARREADY (ARREADY),
.ARID (ARID),
.ARLOCK (ARLOCK),
.ARCACHE (ARCACHE),
.ARPROT (ARPROT),
.ARLEN (ARLEN),
.ARSIZE (ARSIZE),
.ARBURST (ARBURST),
.ARQOS (ARQOS),
.RDATA (RDATA),
.RVALID (RVALID),
.RREADY (RREADY),
.RID (RID),
.RLAST (RLAST),
.RRESP (RRESP),
.AWADDR (AWADDR),
.AWVALID (AWVALID),
.AWREADY (AWREADY),
.AWID (AWID),
.AWLOCK (AWLOCK),
.AWCACHE (AWCACHE),
.AWPROT (AWPROT),
.AWLEN (AWLEN),
.AWSIZE (AWSIZE),
.AWBURST (AWBURST),
.AWQOS (AWQOS),
.WDATA (WDATA),
.WVALID (WVALID),
.WREADY (WREADY),
.WID (WID),
.WLAST (WLAST),
.WSTRB (WSTRB),
.BVALID (BVALID),
.BREADY (BREADY),
.BID (BID),
.BRESP (BRESP)
);
PS7 ps7_i (
// EMIO interface
// CAN interface
.EMIOCAN0PHYTX(), // CAN 0 TX, output
.EMIOCAN0PHYRX(), // CAN 0 RX, input
.EMIOCAN1PHYTX(), // Can 1 TX, output
.EMIOCAN1PHYRX(), // CAN 1 RX, input
// GMII 0
.EMIOENET0GMIICRS(), // GMII 0 Carrier sense, input
.EMIOENET0GMIICOL(), // GMII 0 Collision detect, input
.EMIOENET0EXTINTIN(), // GMII 0 Controller Interrupt input, input
// GMII 0 TX signals
.EMIOENET0GMIITXCLK(), // GMII 0 TX clock, input
.EMIOENET0GMIITXD(), // GMII 0 Tx Data[7:0], output
.EMIOENET0GMIITXEN(), // GMII 0 Tx En, output
.EMIOENET0GMIITXER(), // GMII 0 Tx Err, output
// GMII 0 TX timestamp signals
.EMIOENET0SOFTX(), // GMII 0 Tx Tx Start-of-Frame, output
.EMIOENET0PTPDELAYREQTX(), // GMII 0 Tx PTP delay req frame detected, output
.EMIOENET0PTPPDELAYREQTX(), // GMII 0 Tx PTP peer delay frame detect, output
.EMIOENET0PTPPDELAYRESPTX(), // GMII 0 Tx PTP pear delay response frame detected, output
.EMIOENET0PTPSYNCFRAMETX(), // GMII 0 Tx PTP sync frame detected, output
// GMII 0 RX signals
.EMIOENET0GMIIRXCLK(), // GMII 0 Rx Clock, input
.EMIOENET0GMIIRXD(), // GMII 0 Rx Data (7:0), input
.EMIOENET0GMIIRXDV(), // GMII 0 Rx Data valid, input
.EMIOENET0GMIIRXER(), // GMII 0 Rx Error, input
// GMII 0 RX timestamp signals
.EMIOENET0SOFRX(), // GMII 0 Rx Start of Frame, output
.EMIOENET0PTPDELAYREQRX(), // GMII 0 Rx PTP delay req frame detected
.EMIOENET0PTPPDELAYREQRX(), // GMII 0 Rx PTP peer delay frame detected, output
.EMIOENET0PTPPDELAYRESPRX(), // GMII 0 Rx PTP peer delay responce frame detected, output
.EMIOENET0PTPSYNCFRAMERX(), // GMII 0 Rx PTP sync frame detected, output
// MDIO 0
.EMIOENET0MDIOMDC(), // MDIO 0 MD clock output, output
.EMIOENET0MDIOO(), // MDIO 0 MD data output, output
.EMIOENET0MDIOTN(), // MDIO 0 MD data 3-state, output
.EMIOENET0MDIOI(), // MDIO 0 MD data input, input
// GMII 1
.EMIOENET1GMIICRS(), // GMII 1 Carrier sense, input
.EMIOENET1GMIICOL(), // GMII 1 Collision detect, input
.EMIOENET1EXTINTIN(), // GMII 1 Controller Interrupt input, input
// GMII 1 TX signals
.EMIOENET1GMIITXCLK(), // GMII 1 TX clock, input
.EMIOENET1GMIITXD(), // GMII 1 Tx Data[7:0], output
.EMIOENET1GMIITXEN(), // GMII 1 Tx En, output
.EMIOENET1GMIITXER(), // GMII 1 Tx Err, output
// GMII 1 TX timestamp signals
.EMIOENET1SOFTX(), // GMII 1 Tx Tx Start-of-Frame, output
.EMIOENET1PTPDELAYREQTX(), // GMII 1 Tx PTP delay req frame detected, output
.EMIOENET1PTPPDELAYREQTX(), // GMII 1 Tx PTP peer delay frame detect, output
.EMIOENET1PTPPDELAYRESPTX(), // GMII 1 Tx PTP pear delay response frame detected, output
.EMIOENET1PTPSYNCFRAMETX(), // GMII 1 Tx PTP sync frame detected, output
// GMII 1 RX signals
.EMIOENET1GMIIRXCLK(), // GMII 1 Rx Clock, input
.EMIOENET1GMIIRXD(), // GMII 1 Rx Data (7:0), input
.EMIOENET1GMIIRXDV(), // GMII 1 Rx Data valid, input
.EMIOENET1GMIIRXER(), // GMII 1 Rx Error, input
// GMII 1 RX timestamp signals
.EMIOENET1SOFRX(), // GMII 1 Rx Start of Frame, output
.EMIOENET1PTPDELAYREQRX(), // GMII 1 Rx PTP delay req frame detected
.EMIOENET1PTPPDELAYREQRX(), // GMII 1 Rx PTP peer delay frame detected, output
.EMIOENET1PTPPDELAYRESPRX(), // GMII 1 Rx PTP peer delay responce frame detected, output
.EMIOENET1PTPSYNCFRAMERX(), // GMII 1 Rx PTP sync frame detected, output
// MDIO 1
.EMIOENET1MDIOMDC(), // MDIO 1 MD clock output, output
.EMIOENET1MDIOO(), // MDIO 1 MD data output, output
.EMIOENET1MDIOTN(), // MDIO 1 MD data 3-state, output
.EMIOENET1MDIOI(), // MDIO 1 MD data input, input
// EMIO GPIO
.EMIOGPIOO(), // EMIO GPIO Data out[63:0], output
.EMIOGPIOI(/*gpio_in[63:0]*/), // EMIO GPIO Data in[63:0], input
.EMIOGPIOTN(), // EMIO GPIO OutputEnable[63:0], output
// EMIO I2C 0
.EMIOI2C0SCLO(), // I2C 0 SCL OUT, output // manual says input
.EMIOI2C0SCLI(), // I2C 0 SCL IN, input // manual says output
.EMIOI2C0SCLTN(), // I2C 0 SCL EN, output // manual says input
.EMIOI2C0SDAO(), // I2C 0 SDA OUT, output // manual says input
.EMIOI2C0SDAI(), // I2C 0 SDA IN, input // manual says output
.EMIOI2C0SDATN(), // I2C 0 SDA EN, output // manual says input
// EMIO I2C 1
.EMIOI2C1SCLO(), // I2C 1 SCL OUT, output // manual says input
.EMIOI2C1SCLI(), // I2C 1 SCL IN, input // manual says output
.EMIOI2C1SCLTN(), // I2C 1 SCL EN, output // manual says input
.EMIOI2C1SDAO(), // I2C 1 SDA OUT, output // manual says input
.EMIOI2C1SDAI(), // I2C 1 SDA IN, input // manual says output
.EMIOI2C1SDATN(), // I2C 1 SDA EN, output // manual says input
// JTAG
.EMIOPJTAGTCK(), // JTAG TCK, input
.EMIOPJTAGTMS(), // JTAG TMS, input
.EMIOPJTAGTDI(), // JTAG TDI, input
.EMIOPJTAGTDO(), // JTAG TDO, output
.EMIOPJTAGTDTN(), // JTAG TDO OE, output
// SDIO 0
.EMIOSDIO0CLKFB(), // SDIO 0 Clock feedback, input
.EMIOSDIO0CLK(), // SDIO 0 Clock, output
.EMIOSDIO0CMDI(), // SDIO 0 Command in, input
.EMIOSDIO0CMDO(), // SDIO 0 Command out, output
.EMIOSDIO0CMDTN(), // SDIO 0 command OE, output
.EMIOSDIO0DATAI(), // SDIO 0 Data in [3:0], input
.EMIOSDIO0DATAO(), // SDIO 0 Data out [3:0], output
.EMIOSDIO0DATATN(), // SDIO 0 Data OE [3:0], output
.EMIOSDIO0CDN(), // SDIO 0 Card detect, input
.EMIOSDIO0WP(), // SDIO 0 Write protect, input
.EMIOSDIO0BUSPOW(), // SDIO 0 Power control, output
.EMIOSDIO0LED(), // SDIO 0 LED control, output
.EMIOSDIO0BUSVOLT(), // SDIO 0 Bus voltage [2:0], output
// SDIO 1
.EMIOSDIO1CLKFB(), // SDIO 1 Clock feedback, input
.EMIOSDIO1CLK(), // SDIO 1 Clock, output
.EMIOSDIO1CMDI(), // SDIO 1 Command in, input
.EMIOSDIO1CMDO(), // SDIO 1 Command out, output
.EMIOSDIO1CMDTN(), // SDIO 1 command OE, output
.EMIOSDIO1DATAI(), // SDIO 1 Data in [3:0], input
.EMIOSDIO1DATAO(), // SDIO 1 Data out [3:0], output
.EMIOSDIO1DATATN(), // SDIO 1 Data OE [3:0], output
.EMIOSDIO1CDN(), // SDIO 1 Card detect, input
.EMIOSDIO1WP(), // SDIO 1 Write protect, input
.EMIOSDIO1BUSPOW(), // SDIO 1 Power control, output
.EMIOSDIO1LED(), // SDIO 1 LED control, output
.EMIOSDIO1BUSVOLT(), // SDIO 1 Bus voltage [2:0], output
// SPI 0
.EMIOSPI0SCLKI(), // SPI 0 CLK in , input
.EMIOSPI0SCLKO(), // SPI 0 CLK out, output
.EMIOSPI0SCLKTN(), // SPI 0 CLK OE, output
.EMIOSPI0SI(), // SPI 0 MOSI in , input
.EMIOSPI0MO(), // SPI 0 MOSI out , output
.EMIOSPI0MOTN(), // SPI 0 MOSI OE, output
.EMIOSPI0MI(), // SPI 0 MISO in, input
.EMIOSPI0SO(), // SPI 0 MISO out, output
.EMIOSPI0STN(), // SPI 0 MISO OE, output
.EMIOSPI0SSIN(), // SPI 0 Slave select 0 in, input
.EMIOSPI0SSON(), // SPI 0 Slave select [2:0] out, output
.EMIOSPI0SSNTN(), // SPI 0 Slave select OE, output
// SPI 1
.EMIOSPI1SCLKI(), // SPI 1 CLK in , input
.EMIOSPI1SCLKO(), // SPI 1 CLK out, output
.EMIOSPI1SCLKTN(), // SPI 1 CLK OE, output
.EMIOSPI1SI(), // SPI 1 MOSI in , input
.EMIOSPI1MO(), // SPI 1 MOSI out , output
.EMIOSPI1MOTN(), // SPI 1 MOSI OE, output
.EMIOSPI1MI(), // SPI 1 MISO in, input
.EMIOSPI1SO(), // SPI 1 MISO out, output
.EMIOSPI1STN(), // SPI 1 MISO OE, output
.EMIOSPI1SSIN(), // SPI 1 Slave select 0 in, input
.EMIOSPI1SSON(), // SPI 1 Slave select [2:0] out, output
.EMIOSPI1SSNTN(), // SPI 1 Slave select OE, output
// TPIU signals (Trace)
.EMIOTRACECTL(), // Trace CTL, output
.EMIOTRACEDATA(), // Trace Data[31:0], output
.EMIOTRACECLK(), // Trace CLK, input
// Timers/counters
.EMIOTTC0CLKI(), // Counter/Timer 0 clock in [2:0], input
.EMIOTTC0WAVEO(), // Counter/Timer 0 wave out[2:0], output
.EMIOTTC1CLKI(), // Counter/Timer 1 clock in [2:0], input
.EMIOTTC1WAVEO(), // Counter/Timer 1 wave out[2:0], output
//UART 0
.EMIOUART0TX(), // UART 0 Transmit, output
.EMIOUART0RX(), // UART 0 Receive, input
.EMIOUART0CTSN(), // UART 0 Clear To Send, input
.EMIOUART0RTSN(), // UART 0 Ready to Send, output
.EMIOUART0DSRN(), // UART 0 Data Set Ready , input
.EMIOUART0DCDN(), // UART 0 Data Carrier Detect, input
.EMIOUART0RIN(), // UART 0 Ring Indicator, input
.EMIOUART0DTRN(), // UART 0 Data Terminal Ready, output
//UART 1
.EMIOUART1TX(), // UART 1 Transmit, output
.EMIOUART1RX(), // UART 1 Receive, input
.EMIOUART1CTSN(), // UART 1 Clear To Send, input
.EMIOUART1RTSN(), // UART 1 Ready to Send, output
.EMIOUART1DSRN(), // UART 1 Data Set Ready , input
.EMIOUART1DCDN(), // UART 1 Data Carrier Detect, input
.EMIOUART1RIN(), // UART 1 Ring Indicator, input
.EMIOUART1DTRN(), // UART 1 Data Terminal Ready, output
// USB 0
.EMIOUSB0PORTINDCTL(), // USB 0 Port Indicator [1:0], output
.EMIOUSB0VBUSPWRFAULT(), // USB 0 Power Fault, input
.EMIOUSB0VBUSPWRSELECT(), // USB 0 Power Select, output
// USB 1
.EMIOUSB1PORTINDCTL(), // USB 1 Port Indicator [1:0], output
.EMIOUSB1VBUSPWRFAULT(), // USB 1 Power Fault, input
.EMIOUSB1VBUSPWRSELECT(), // USB 1 Power Select, output
// Watchdog Timer
.EMIOWDTCLKI(), // Watchdog Timer Clock in, input
.EMIOWDTRSTO(), // Watchdog Timer Reset out, output
// DMAC 0
.DMA0ACLK(), // DMAC 0 Clock, input
.DMA0DRVALID(), // DMAC 0 DMA Request Valid, input
.DMA0DRLAST(), // DMAC 0 DMA Request Last, input
.DMA0DRTYPE(), // DMAC 0 DMA Request Type [1:0] ()single/burst/ackn flush/reserved), input
.DMA0DRREADY(), // DMAC 0 DMA Request Ready, output
.DMA0DAVALID(), // DMAC 0 DMA Acknowledge Valid (DA_TYPE[1:0] valid), output
.DMA0DAREADY(), // DMAC 0 DMA Acknowledge (peripheral can accept DA_TYPE[1:0]), input
.DMA0DATYPE(), // DMAC 0 DMA Ackbowledge TYpe (completed single AXI, completed burst AXI, flush request), output
.DMA0RSTN(), // DMAC 0 RESET output (reserved, do not use), output
// DMAC 1
.DMA1ACLK(), // DMAC 1 Clock, input
.DMA1DRVALID(), // DMAC 1 DMA Request Valid, input
.DMA1DRLAST(), // DMAC 1 DMA Request Last, input
.DMA1DRTYPE(), // DMAC 1 DMA Request Type [1:0] ()single/burst/ackn flush/reserved), input
.DMA1DRREADY(), // DMAC 1 DMA Request Ready, output
.DMA1DAVALID(), // DMAC 1 DMA Acknowledge Valid (DA_TYPE[1:0] valid), output
.DMA1DAREADY(), // DMAC 1 DMA Acknowledge (peripheral can accept DA_TYPE[1:0]), input
.DMA1DATYPE(), // DMAC 1 DMA Ackbowledge TYpe (completed single AXI, completed burst AXI, flush request), output
.DMA1RSTN(), // DMAC 1 RESET output (reserved, do not use), output
// DMAC 2
.DMA2ACLK(), // DMAC 2 Clock, input
.DMA2DRVALID(), // DMAC 2 DMA Request Valid, input
.DMA2DRLAST(), // DMAC 2 DMA Request Last, input
.DMA2DRTYPE(), // DMAC 2 DMA Request Type [1:0] ()single/burst/ackn flush/reserved), input
.DMA2DRREADY(), // DMAC 2 DMA Request Ready, output
.DMA2DAVALID(), // DMAC 2 DMA Acknowledge Valid (DA_TYPE[1:0] valid), output
.DMA2DAREADY(), // DMAC 2 DMA Acknowledge (peripheral can accept DA_TYPE[1:0]), input
.DMA2DATYPE(), // DMAC 2 DMA Ackbowledge TYpe (completed single AXI, completed burst AXI, flush request), output
.DMA2RSTN(), // DMAC 2 RESET output (reserved, do not use), output
// DMAC 3
.DMA3ACLK(), // DMAC 3 Clock, input
.DMA3DRVALID(), // DMAC 3 DMA Request Valid, input
.DMA3DRLAST(), // DMAC 3 DMA Request Last, input
.DMA3DRTYPE(), // DMAC 3 DMA Request Type [1:0] ()single/burst/ackn flush/reserved), input
.DMA3DRREADY(), // DMAC 3 DMA Request Ready, output
.DMA3DAVALID(), // DMAC 3 DMA Acknowledge Valid (DA_TYPE[1:0] valid), output
.DMA3DAREADY(), // DMAC 3 DMA Acknowledge (peripheral can accept DA_TYPE[1:0]), input
.DMA3DATYPE(), // DMAC 3 DMA Ackbowledge TYpe (completed single AXI, completed burst AXI, flush request), output
.DMA3RSTN(), // DMAC 3 RESET output (reserved, do not use), output
// Interrupt signals
.IRQF2P(), // Interrupts, OL to PS [19:0], input
.IRQP2F(), // Interrupts, OL to PS [28:0], output
// Event Signals
.EVENTEVENTI(), // EVENT Wake up one or both CPU from WFE state, input
.EVENTEVENTO(), // EVENT Asserted when one of the COUs executed SEV instruction, output
.EVENTSTANDBYWFE(), // EVENT CPU standby mode [1:0], asserted when CPU is waiting for an event, output
.EVENTSTANDBYWFI(), // EVENT CPU standby mode [1:0], asserted when CPU is waiting for an interrupt, output
// PL Resets and clocks
.FCLKCLK(fclk[3:0]), // PL Clocks [3:0], output
.FCLKCLKTRIGN(), // PL Clock Throttle Control [3:0], input
.FCLKRESETN(frst[3:0]), // PL General purpose user reset [3:0], output (active low)
// Debug signals
.FTMTP2FDEBUG(), // Debug General purpose debug output [31:0], output
.FTMTF2PDEBUG(), // Debug General purpose debug input [31:0], input
.FTMTP2FTRIG(), // Debug Trigger PS to PL [3:0], output
.FTMTP2FTRIGACK(), // Debug Trigger PS to PL acknowledge[3:0], input
.FTMTF2PTRIG(), // Debug Trigger PL to PS [3:0], input
.FTMTF2PTRIGACK(), // Debug Trigger PL to PS acknowledge[3:0], output
.FTMDTRACEINCLOCK(), // Debug Trace PL to PS Clock, input
.FTMDTRACEINVALID(), // Debug Trace PL to PS Clock, data&id valid, input
.FTMDTRACEINDATA(), // Debug Trace PL to PS data [31:0], input
.FTMDTRACEINATID(), // Debug Trace PL to PS ID [3:0], input
// DDR Urgent
.DDRARB(), // DDR Urgent[3:0], input
// SRAM interrupt (on rising edge)
.EMIOSRAMINTIN(), // SRAM interrupt #50 shared with NAND busy, input
// AXI interfaces
.FPGAIDLEN(1'b1), //Idle PL AXI interfaces (active low), input
// AXI PS Master GP0
// AXI PS Master GP0: Clock, Reset
.MAXIGP0ACLK(/*axi_aclk*/), // AXI PS Master GP0 Clock , input
// .MAXIGP0ACLK(/*fclk[0]*/), // AXI PS Master GP0 Clock , input
// .MAXIGP0ACLK(/*~fclk[0]*/), // AXI PS Master GP0 Clock , input
// .MAXIGP0ACLK(/*axi_naclk*/), // AXI PS Master GP0 Clock , input
//
.MAXIGP0ARESETN(), // AXI PS Master GP0 Reset, output
// AXI PS Master GP0: Read Address
.MAXIGP0ARADDR (/*axi_araddr[31:0]*/), // AXI PS Master GP0 ARADDR[31:0], output
.MAXIGP0ARVALID (/*axi_arvalid*/), // AXI PS Master GP0 ARVALID, output
.MAXIGP0ARREADY (/*axi_arready*/), // AXI PS Master GP0 ARREADY, input
.MAXIGP0ARID (/*axi_arid[11:0]*/), // AXI PS Master GP0 ARID[11:0], output
.MAXIGP0ARLOCK (), // AXI PS Master GP0 ARLOCK[1:0], output
.MAXIGP0ARCACHE (),// AXI PS Master GP0 ARCACHE[3:0], output
.MAXIGP0ARPROT(), // AXI PS Master GP0 ARPROT[2:0], output
.MAXIGP0ARLEN (/*axi_arlen[3:0]*/), // AXI PS Master GP0 ARLEN[3:0], output
.MAXIGP0ARSIZE (/*axi_arsize[1:0]*/), // AXI PS Master GP0 ARSIZE[1:0], output
.MAXIGP0ARBURST (/*axi_arburst[1:0]*/),// AXI PS Master GP0 ARBURST[1:0], output
.MAXIGP0ARQOS (), // AXI PS Master GP0 ARQOS[3:0], output
// AXI PS Master GP0: Read Data
.MAXIGP0RDATA (/*axi_rdata[31:0]*/), // AXI PS Master GP0 RDATA[31:0], input
.MAXIGP0RVALID (/*axi_rvalid*/), // AXI PS Master GP0 RVALID, input
.MAXIGP0RREADY (/*axi_rready*/), // AXI PS Master GP0 RREADY, output
.MAXIGP0RID (/*axi_rid[11:0]*/), // AXI PS Master GP0 RID[11:0], input
.MAXIGP0RLAST (/*axi_rlast*/), // AXI PS Master GP0 RLAST, input
.MAXIGP0RRESP (/*axi_rresp[1:0]*/), // AXI PS Master GP0 RRESP[1:0], input
// AXI PS Master GP0: Write Address
.MAXIGP0AWADDR (/*axi_awaddr[31:0]*/), // AXI PS Master GP0 AWADDR[31:0], output
.MAXIGP0AWVALID (/*axi_awvalid*/), // AXI PS Master GP0 AWVALID, output
.MAXIGP0AWREADY (/*axi_awready*/), // AXI PS Master GP0 AWREADY, input
.MAXIGP0AWID (/*axi_awid[11:0]*/), // AXI PS Master GP0 AWID[11:0], output
.MAXIGP0AWLOCK (), // AXI PS Master GP0 AWLOCK[1:0], output
.MAXIGP0AWCACHE (),// AXI PS Master GP0 AWCACHE[3:0], output
.MAXIGP0AWPROT (), // AXI PS Master GP0 AWPROT[2:0], output
.MAXIGP0AWLEN (/*axi_awlen[3:0]*/), // AXI PS Master GP0 AWLEN[3:0], output
.MAXIGP0AWSIZE (/*axi_awsize[1:0]*/), // AXI PS Master GP0 AWSIZE[1:0], output
.MAXIGP0AWBURST (/*axi_awburst[1:0]*/),// AXI PS Master GP0 AWBURST[1:0], output
.MAXIGP0AWQOS (), // AXI PS Master GP0 AWQOS[3:0], output
// AXI PS Master GP0: Write Data
.MAXIGP0WDATA (/*axi_wdata[31:0]*/), // AXI PS Master GP0 WDATA[31:0], output
.MAXIGP0WVALID (/*axi_wvalid*/), // AXI PS Master GP0 WVALID, output
.MAXIGP0WREADY (/*axi_wready*/), // AXI PS Master GP0 WREADY, input
.MAXIGP0WID (/*axi_wid[11:0]*/), // AXI PS Master GP0 WID[11:0], output
.MAXIGP0WLAST (/*axi_wlast*/), // AXI PS Master GP0 WLAST, output
.MAXIGP0WSTRB (/*axi_wstb[3:0]*/), // AXI PS Master GP0 WSTRB[3:0], output
// AXI PS Master GP0: Write Responce
.MAXIGP0BVALID (/*axi_bvalid*/), // AXI PS Master GP0 BVALID, input
.MAXIGP0BREADY (/*axi_bready*/), // AXI PS Master GP0 BREADY, output
.MAXIGP0BID (/*axi_bid[11:0]*/), // AXI PS Master GP0 BID[11:0], input
.MAXIGP0BRESP (/*axi_bresp[1:0]*/), // AXI PS Master GP0 BRESP[1:0], input
// AXI PS Master GP1
// AXI PS Master GP1: Clock, Reset
.MAXIGP1ACLK (axi_aclk), // AXI PS Master GP1 Clock , input
.MAXIGP1ARESETN (), // AXI PS Master GP1 Reset, output
// AXI PS Master GP1: Read Address
.MAXIGP1ARADDR (ARADDR), // AXI PS Master GP1 ARADDR[31:0], output
.MAXIGP1ARVALID (ARVALID), // AXI PS Master GP1 ARVALID, output
.MAXIGP1ARREADY (ARREADY), // AXI PS Master GP1 ARREADY, input
.MAXIGP1ARID (ARID), // AXI PS Master GP1 ARID[11:0], output
.MAXIGP1ARLOCK (ARLOCK), // AXI PS Master GP1 ARLOCK[1:0], output
.MAXIGP1ARCACHE (ARCACHE), // AXI PS Master GP1 ARCACHE[3:0], output
.MAXIGP1ARPROT (ARPROT), // AXI PS Master GP1 ARPROT[2:0], output
.MAXIGP1ARLEN (ARLEN), // AXI PS Master GP1 ARLEN[3:0], output
.MAXIGP1ARSIZE (ARSIZE), // AXI PS Master GP1 ARSIZE[1:0], output
.MAXIGP1ARBURST (ARBURST), // AXI PS Master GP1 ARBURST[1:0], output
.MAXIGP1ARQOS (ARQOS), // AXI PS Master GP1 ARQOS[3:0], output
// AXI PS Master GP1: Read Data
.MAXIGP1RDATA (RDATA), // AXI PS Master GP1 RDATA[31:0], input
.MAXIGP1RVALID (RVALID), // AXI PS Master GP1 RVALID, input
.MAXIGP1RREADY (RREADY), // AXI PS Master GP1 RREADY, output
.MAXIGP1RID (RID), // AXI PS Master GP1 RID[11:0], input
.MAXIGP1RLAST (RLAST), // AXI PS Master GP1 RLAST, input
.MAXIGP1RRESP (RRESP), // AXI PS Master GP1 RRESP[1:0], input
// AXI PS Master GP1: Write Address
.MAXIGP1AWADDR (AWADDR), // AXI PS Master GP1 AWADDR[31:0], output
.MAXIGP1AWVALID (AWVALID), // AXI PS Master GP1 AWVALID, output
.MAXIGP1AWREADY (AWREADY), // AXI PS Master GP1 AWREADY, input
.MAXIGP1AWID (AWID), // AXI PS Master GP1 AWID[11:0], output
.MAXIGP1AWLOCK (AWLOCK), // AXI PS Master GP1 AWLOCK[1:0], output
.MAXIGP1AWCACHE (AWCACHE), // AXI PS Master GP1 AWCACHE[3:0], output
.MAXIGP1AWPROT (AWPROT), // AXI PS Master GP1 AWPROT[2:0], output
.MAXIGP1AWLEN (AWLEN), // AXI PS Master GP1 AWLEN[3:0], output
.MAXIGP1AWSIZE (AWSIZE), // AXI PS Master GP1 AWSIZE[1:0], output
.MAXIGP1AWBURST (AWBURST), // AXI PS Master GP1 AWBURST[1:0], output
.MAXIGP1AWQOS (AWQOS), // AXI PS Master GP1 AWQOS[3:0], output
// AXI PS Master GP1: Write Data
.MAXIGP1WDATA (WDATA), // AXI PS Master GP1 WDATA[31:0], output
.MAXIGP1WVALID (WVALID), // AXI PS Master GP1 WVALID, output
.MAXIGP1WREADY (WREADY), // AXI PS Master GP1 WREADY, input
.MAXIGP1WID (WID), // AXI PS Master GP1 WID[11:0], output
.MAXIGP1WLAST (WLAST), // AXI PS Master GP1 WLAST, output
.MAXIGP1WSTRB (WSTRB), // AXI PS Master GP1 WSTRB[3:0], output
// AXI PS Master GP1: Write Responce
.MAXIGP1BVALID (BVALID), // AXI PS Master GP1 BVALID, input
.MAXIGP1BREADY (BREADY), // AXI PS Master GP1 BREADY, output
.MAXIGP1BID (BID), // AXI PS Master GP1 BID[11:0], input
.MAXIGP1BRESP (BRESP), // AXI PS Master GP1 BRESP[1:0], input
// AXI PS Slave GP0
// AXI PS Slave GP0: Clock, Reset
.SAXIGP0ACLK(), // AXI PS Slave GP0 Clock , input
.SAXIGP0ARESETN(), // AXI PS Slave GP0 Reset, output
// AXI PS Slave GP0: Read Address
.SAXIGP0ARADDR(), // AXI PS Slave GP0 ARADDR[31:0], input
.SAXIGP0ARVALID(), // AXI PS Slave GP0 ARVALID, input
.SAXIGP0ARREADY(), // AXI PS Slave GP0 ARREADY, output
.SAXIGP0ARID(), // AXI PS Slave GP0 ARID[5:0], input
.SAXIGP0ARLOCK(), // AXI PS Slave GP0 ARLOCK[1:0], input
.SAXIGP0ARCACHE(), // AXI PS Slave GP0 ARCACHE[3:0], input
.SAXIGP0ARPROT(), // AXI PS Slave GP0 ARPROT[2:0], input
.SAXIGP0ARLEN(), // AXI PS Slave GP0 ARLEN[3:0], input
.SAXIGP0ARSIZE(), // AXI PS Slave GP0 ARSIZE[1:0], input
.SAXIGP0ARBURST(), // AXI PS Slave GP0 ARBURST[1:0], input
.SAXIGP0ARQOS(), // AXI PS Slave GP0 ARQOS[3:0], input
// AXI PS Slave GP0: Read Data
.SAXIGP0RDATA(), // AXI PS Slave GP0 RDATA[31:0], output
.SAXIGP0RVALID(), // AXI PS Slave GP0 RVALID, output
.SAXIGP0RREADY(), // AXI PS Slave GP0 RREADY, input
.SAXIGP0RID(), // AXI PS Slave GP0 RID[5:0], output
.SAXIGP0RLAST(), // AXI PS Slave GP0 RLAST, output
.SAXIGP0RRESP(), // AXI PS Slave GP0 RRESP[1:0], output
// AXI PS Slave GP0: Write Address
.SAXIGP0AWADDR(), // AXI PS Slave GP0 AWADDR[31:0], input
.SAXIGP0AWVALID(), // AXI PS Slave GP0 AWVALID, input
.SAXIGP0AWREADY(), // AXI PS Slave GP0 AWREADY, output
.SAXIGP0AWID(), // AXI PS Slave GP0 AWID[5:0], input
.SAXIGP0AWLOCK(), // AXI PS Slave GP0 AWLOCK[1:0], input
.SAXIGP0AWCACHE(), // AXI PS Slave GP0 AWCACHE[3:0], input
.SAXIGP0AWPROT(), // AXI PS Slave GP0 AWPROT[2:0], input
.SAXIGP0AWLEN(), // AXI PS Slave GP0 AWLEN[3:0], input
.SAXIGP0AWSIZE(), // AXI PS Slave GP0 AWSIZE[1:0], input
.SAXIGP0AWBURST(), // AXI PS Slave GP0 AWBURST[1:0], input
.SAXIGP0AWQOS(), // AXI PS Slave GP0 AWQOS[3:0], input
// AXI PS Slave GP0: Write Data
.SAXIGP0WDATA(), // AXI PS Slave GP0 WDATA[31:0], input
.SAXIGP0WVALID(), // AXI PS Slave GP0 WVALID, input
.SAXIGP0WREADY(), // AXI PS Slave GP0 WREADY, output
.SAXIGP0WID(), // AXI PS Slave GP0 WID[5:0], input
.SAXIGP0WLAST(), // AXI PS Slave GP0 WLAST, input
.SAXIGP0WSTRB(), // AXI PS Slave GP0 WSTRB[3:0], input
// AXI PS Slave GP0: Write Responce
.SAXIGP0BVALID(), // AXI PS Slave GP0 BVALID, output
.SAXIGP0BREADY(), // AXI PS Slave GP0 BREADY, input
.SAXIGP0BID(), // AXI PS Slave GP0 BID[5:0], output //TODO: Update range !!!
.SAXIGP0BRESP(), // AXI PS Slave GP0 BRESP[1:0], output
// AXI PS Slave GP1
// AXI PS Slave GP1: Clock, Reset
.SAXIGP1ACLK(), // AXI PS Slave GP1 Clock , input
.SAXIGP1ARESETN(), // AXI PS Slave GP1 Reset, output
// AXI PS Slave GP1: Read Address
.SAXIGP1ARADDR(), // AXI PS Slave GP1 ARADDR[31:0], input
.SAXIGP1ARVALID(), // AXI PS Slave GP1 ARVALID, input
.SAXIGP1ARREADY(), // AXI PS Slave GP1 ARREADY, output
.SAXIGP1ARID(), // AXI PS Slave GP1 ARID[5:0], input
.SAXIGP1ARLOCK(), // AXI PS Slave GP1 ARLOCK[1:0], input
.SAXIGP1ARCACHE(), // AXI PS Slave GP1 ARCACHE[3:0], input
.SAXIGP1ARPROT(), // AXI PS Slave GP1 ARPROT[2:0], input
.SAXIGP1ARLEN(), // AXI PS Slave GP1 ARLEN[3:0], input
.SAXIGP1ARSIZE(), // AXI PS Slave GP1 ARSIZE[1:0], input
.SAXIGP1ARBURST(), // AXI PS Slave GP1 ARBURST[1:0], input
.SAXIGP1ARQOS(), // AXI PS Slave GP1 ARQOS[3:0], input
// AXI PS Slave GP1: Read Data
.SAXIGP1RDATA(), // AXI PS Slave GP1 RDATA[31:0], output
.SAXIGP1RVALID(), // AXI PS Slave GP1 RVALID, output
.SAXIGP1RREADY(), // AXI PS Slave GP1 RREADY, input
.SAXIGP1RID(), // AXI PS Slave GP1 RID[5:0], output
.SAXIGP1RLAST(), // AXI PS Slave GP1 RLAST, output
.SAXIGP1RRESP(), // AXI PS Slave GP1 RRESP[1:0], output
// AXI PS Slave GP1: Write Address
.SAXIGP1AWADDR(), // AXI PS Slave GP1 AWADDR[31:0], input
.SAXIGP1AWVALID(), // AXI PS Slave GP1 AWVALID, input
.SAXIGP1AWREADY(), // AXI PS Slave GP1 AWREADY, output
.SAXIGP1AWID(), // AXI PS Slave GP1 AWID[5:0], input
.SAXIGP1AWLOCK(), // AXI PS Slave GP1 AWLOCK[1:0], input
.SAXIGP1AWCACHE(), // AXI PS Slave GP1 AWCACHE[3:0], input
.SAXIGP1AWPROT(), // AXI PS Slave GP1 AWPROT[2:0], input
.SAXIGP1AWLEN(), // AXI PS Slave GP1 AWLEN[3:0], input
.SAXIGP1AWSIZE(), // AXI PS Slave GP1 AWSIZE[1:0], input
.SAXIGP1AWBURST(), // AXI PS Slave GP1 AWBURST[1:0], input
.SAXIGP1AWQOS(), // AXI PS Slave GP1 AWQOS[3:0], input
// AXI PS Slave GP1: Write Data
.SAXIGP1WDATA(), // AXI PS Slave GP1 WDATA[31:0], input
.SAXIGP1WVALID(), // AXI PS Slave GP1 WVALID, input
.SAXIGP1WREADY(), // AXI PS Slave GP1 WREADY, output
.SAXIGP1WID(), // AXI PS Slave GP1 WID[5:0], input
.SAXIGP1WLAST(), // AXI PS Slave GP1 WLAST, input
.SAXIGP1WSTRB(), // AXI PS Slave GP1 WSTRB[3:0], input
// AXI PS Slave GP1: Write Responce
.SAXIGP1BVALID(), // AXI PS Slave GP1 BVALID, output
.SAXIGP1BREADY(), // AXI PS Slave GP1 BREADY, input
.SAXIGP1BID(), // AXI PS Slave GP1 BID[5:0], output
.SAXIGP1BRESP(), // AXI PS Slave GP1 BRESP[1:0], output
// AXI PS Slave HP0
// AXI PS Slave HP0: Clock, Reset
.SAXIHP0ACLK(), // AXI PS Slave HP0 Clock , input
.SAXIHP0ARESETN(), // AXI PS Slave HP0 Reset, output
// AXI PS Slave HP0: Read Address
.SAXIHP0ARADDR(), // AXI PS Slave HP0 ARADDR[31:0], input
.SAXIHP0ARVALID(), // AXI PS Slave HP0 ARVALID, input
.SAXIHP0ARREADY(), // AXI PS Slave HP0 ARREADY, output
.SAXIHP0ARID(), // AXI PS Slave HP0 ARID[5:0], input
.SAXIHP0ARLOCK(), // AXI PS Slave HP0 ARLOCK[1:0], input
.SAXIHP0ARCACHE(), // AXI PS Slave HP0 ARCACHE[3:0], input
.SAXIHP0ARPROT(), // AXI PS Slave HP0 ARPROT[2:0], input
.SAXIHP0ARLEN(), // AXI PS Slave HP0 ARLEN[3:0], input
.SAXIHP0ARSIZE(), // AXI PS Slave HP0 ARSIZE[2:0], input
.SAXIHP0ARBURST(), // AXI PS Slave HP0 ARBURST[1:0], input
.SAXIHP0ARQOS(), // AXI PS Slave HP0 ARQOS[3:0], input
// AXI PS Slave HP0: Read Data
.SAXIHP0RDATA(), // AXI PS Slave HP0 RDATA[63:0], output
.SAXIHP0RVALID(), // AXI PS Slave HP0 RVALID, output
.SAXIHP0RREADY(), // AXI PS Slave HP0 RREADY, input
.SAXIHP0RID(), // AXI PS Slave HP0 RID[5:0], output
.SAXIHP0RLAST(), // AXI PS Slave HP0 RLAST, output
.SAXIHP0RRESP(), // AXI PS Slave HP0 RRESP[1:0], output
.SAXIHP0RCOUNT(), // AXI PS Slave HP0 RCOUNT[7:0], output
.SAXIHP0RACOUNT(), // AXI PS Slave HP0 RACOUNT[2:0], output
.SAXIHP0RDISSUECAP1EN(), // AXI PS Slave HP0 RDISSUECAP1EN, input
// AXI PS Slave HP0: Write Address
.SAXIHP0AWADDR(), // AXI PS Slave HP0 AWADDR[31:0], input
.SAXIHP0AWVALID(), // AXI PS Slave HP0 AWVALID, input
.SAXIHP0AWREADY(), // AXI PS Slave HP0 AWREADY, output
.SAXIHP0AWID(), // AXI PS Slave HP0 AWID[5:0], input
.SAXIHP0AWLOCK(), // AXI PS Slave HP0 AWLOCK[1:0], input
.SAXIHP0AWCACHE(), // AXI PS Slave HP0 AWCACHE[3:0], input
.SAXIHP0AWPROT(), // AXI PS Slave HP0 AWPROT[2:0], input
.SAXIHP0AWLEN(), // AXI PS Slave HP0 AWLEN[3:0], input
.SAXIHP0AWSIZE(), // AXI PS Slave HP0 AWSIZE[1:0], input
.SAXIHP0AWBURST(), // AXI PS Slave HP0 AWBURST[1:0], input
.SAXIHP0AWQOS(), // AXI PS Slave HP0 AWQOS[3:0], input
// AXI PS Slave HP0: Write Data
.SAXIHP0WDATA(), // AXI PS Slave HP0 WDATA[63:0], input
.SAXIHP0WVALID(), // AXI PS Slave HP0 WVALID, input
.SAXIHP0WREADY(), // AXI PS Slave HP0 WREADY, output
.SAXIHP0WID(), // AXI PS Slave HP0 WID[5:0], input
.SAXIHP0WLAST(), // AXI PS Slave HP0 WLAST, input
.SAXIHP0WSTRB(), // AXI PS Slave HP0 WSTRB[7:0], input
.SAXIHP0WCOUNT(), // AXI PS Slave HP0 WCOUNT[7:0], output
.SAXIHP0WACOUNT(), // AXI PS Slave HP0 WACOUNT[5:0], output
.SAXIHP0WRISSUECAP1EN(), // AXI PS Slave HP0 WRISSUECAP1EN, input
// AXI PS Slave HP0: Write Responce
.SAXIHP0BVALID(), // AXI PS Slave HP0 BVALID, output
.SAXIHP0BREADY(), // AXI PS Slave HP0 BREADY, input
.SAXIHP0BID(), // AXI PS Slave HP0 BID[5:0], output
.SAXIHP0BRESP(), // AXI PS Slave HP0 BRESP[1:0], output
// AXI PS Slave HP1
// AXI PS Slave 1: Clock, Reset
.SAXIHP1ACLK(), // AXI PS Slave HP1 Clock , input
.SAXIHP1ARESETN(), // AXI PS Slave HP1 Reset, output
// AXI PS Slave HP1: Read Address
.SAXIHP1ARADDR(), // AXI PS Slave HP1 ARADDR[31:0], input
.SAXIHP1ARVALID(), // AXI PS Slave HP1 ARVALID, input
.SAXIHP1ARREADY(), // AXI PS Slave HP1 ARREADY, output
.SAXIHP1ARID(), // AXI PS Slave HP1 ARID[5:0], input
.SAXIHP1ARLOCK(), // AXI PS Slave HP1 ARLOCK[1:0], input
.SAXIHP1ARCACHE(), // AXI PS Slave HP1 ARCACHE[3:0], input
.SAXIHP1ARPROT(), // AXI PS Slave HP1 ARPROT[2:0], input
.SAXIHP1ARLEN(), // AXI PS Slave HP1 ARLEN[3:0], input
.SAXIHP1ARSIZE(), // AXI PS Slave HP1 ARSIZE[2:0], input
.SAXIHP1ARBURST(), // AXI PS Slave HP1 ARBURST[1:0], input
.SAXIHP1ARQOS(), // AXI PS Slave HP1 ARQOS[3:0], input
// AXI PS Slave HP1: Read Data
.SAXIHP1RDATA(), // AXI PS Slave HP1 RDATA[63:0], output
.SAXIHP1RVALID(), // AXI PS Slave HP1 RVALID, output
.SAXIHP1RREADY(), // AXI PS Slave HP1 RREADY, input
.SAXIHP1RID(), // AXI PS Slave HP1 RID[5:0], output
.SAXIHP1RLAST(), // AXI PS Slave HP1 RLAST, output
.SAXIHP1RRESP(), // AXI PS Slave HP1 RRESP[1:0], output
.SAXIHP1RCOUNT(), // AXI PS Slave HP1 RCOUNT[7:0], output
.SAXIHP1RACOUNT(), // AXI PS Slave HP1 RACOUNT[2:0], output
.SAXIHP1RDISSUECAP1EN(), // AXI PS Slave HP1 RDISSUECAP1EN, input
// AXI PS Slave HP1: Write Address
.SAXIHP1AWADDR(), // AXI PS Slave HP1 AWADDR[31:0], input
.SAXIHP1AWVALID(), // AXI PS Slave HP1 AWVALID, input
.SAXIHP1AWREADY(), // AXI PS Slave HP1 AWREADY, output
.SAXIHP1AWID(), // AXI PS Slave HP1 AWID[5:0], input
.SAXIHP1AWLOCK(), // AXI PS Slave HP1 AWLOCK[1:0], input
.SAXIHP1AWCACHE(), // AXI PS Slave HP1 AWCACHE[3:0], input
.SAXIHP1AWPROT(), // AXI PS Slave HP1 AWPROT[2:0], input
.SAXIHP1AWLEN(), // AXI PS Slave HP1 AWLEN[3:0], input
.SAXIHP1AWSIZE(), // AXI PS Slave HP1 AWSIZE[1:0], input
.SAXIHP1AWBURST(), // AXI PS Slave HP1 AWBURST[1:0], input
.SAXIHP1AWQOS(), // AXI PS Slave HP1 AWQOS[3:0], input
// AXI PS Slave HP1: Write Data
.SAXIHP1WDATA(), // AXI PS Slave HP1 WDATA[63:0], input
.SAXIHP1WVALID(), // AXI PS Slave HP1 WVALID, input
.SAXIHP1WREADY(), // AXI PS Slave HP1 WREADY, output
.SAXIHP1WID(), // AXI PS Slave HP1 WID[5:0], input
.SAXIHP1WLAST(), // AXI PS Slave HP1 WLAST, input
.SAXIHP1WSTRB(), // AXI PS Slave HP1 WSTRB[7:0], input
.SAXIHP1WCOUNT(), // AXI PS Slave HP1 WCOUNT[7:0], output
.SAXIHP1WACOUNT(), // AXI PS Slave HP1 WACOUNT[5:0], output
.SAXIHP1WRISSUECAP1EN(), // AXI PS Slave HP1 WRISSUECAP1EN, input
// AXI PS Slave HP1: Write Responce
.SAXIHP1BVALID(), // AXI PS Slave HP1 BVALID, output
.SAXIHP1BREADY(), // AXI PS Slave HP1 BREADY, input
.SAXIHP1BID(), // AXI PS Slave HP1 BID[5:0], output
.SAXIHP1BRESP(), // AXI PS Slave HP1 BRESP[1:0], output
// AXI PS Slave HP2
// AXI PS Slave HP2: Clock, Reset
.SAXIHP2ACLK(), // AXI PS Slave HP2 Clock , input
.SAXIHP2ARESETN(), // AXI PS Slave HP2 Reset, output
// AXI PS Slave HP2: Read Address
.SAXIHP2ARADDR(), // AXI PS Slave HP2 ARADDR[31:0], input
.SAXIHP2ARVALID(), // AXI PS Slave HP2 ARVALID, input
.SAXIHP2ARREADY(), // AXI PS Slave HP2 ARREADY, output
.SAXIHP2ARID(), // AXI PS Slave HP2 ARID[5:0], input
.SAXIHP2ARLOCK(), // AXI PS Slave HP2 ARLOCK[1:0], input
.SAXIHP2ARCACHE(), // AXI PS Slave HP2 ARCACHE[3:0], input
.SAXIHP2ARPROT(), // AXI PS Slave HP2 ARPROT[2:0], input
.SAXIHP2ARLEN(), // AXI PS Slave HP2 ARLEN[3:0], input
.SAXIHP2ARSIZE(), // AXI PS Slave HP2 ARSIZE[2:0], input
.SAXIHP2ARBURST(), // AXI PS Slave HP2 ARBURST[1:0], input
.SAXIHP2ARQOS(), // AXI PS Slave HP2 ARQOS[3:0], input
// AXI PS Slave HP2: Read Data
.SAXIHP2RDATA(), // AXI PS Slave HP2 RDATA[63:0], output
.SAXIHP2RVALID(), // AXI PS Slave HP2 RVALID, output
.SAXIHP2RREADY(), // AXI PS Slave HP2 RREADY, input
.SAXIHP2RID(), // AXI PS Slave HP2 RID[5:0], output
.SAXIHP2RLAST(), // AXI PS Slave HP2 RLAST, output
.SAXIHP2RRESP(), // AXI PS Slave HP2 RRESP[1:0], output
.SAXIHP2RCOUNT(), // AXI PS Slave HP2 RCOUNT[7:0], output
.SAXIHP2RACOUNT(), // AXI PS Slave HP2 RACOUNT[2:0], output
.SAXIHP2RDISSUECAP1EN(), // AXI PS Slave HP2 RDISSUECAP1EN, input
// AXI PS Slave HP2: Write Address
.SAXIHP2AWADDR(), // AXI PS Slave HP2 AWADDR[31:0], input
.SAXIHP2AWVALID(), // AXI PS Slave HP2 AWVALID, input
.SAXIHP2AWREADY(), // AXI PS Slave HP2 AWREADY, output
.SAXIHP2AWID(), // AXI PS Slave HP2 AWID[5:0], input
.SAXIHP2AWLOCK(), // AXI PS Slave HP2 AWLOCK[1:0], input
.SAXIHP2AWCACHE(), // AXI PS Slave HP2 AWCACHE[3:0], input
.SAXIHP2AWPROT(), // AXI PS Slave HP2 AWPROT[2:0], input
.SAXIHP2AWLEN(), // AXI PS Slave HP2 AWLEN[3:0], input
.SAXIHP2AWSIZE(), // AXI PS Slave HP2 AWSIZE[1:0], input
.SAXIHP2AWBURST(), // AXI PS Slave HP2 AWBURST[1:0], input
.SAXIHP2AWQOS(), // AXI PS Slave HP2 AWQOS[3:0], input
// AXI PS Slave HP2: Write Data
.SAXIHP2WDATA(), // AXI PS Slave HP2 WDATA[63:0], input
.SAXIHP2WVALID(), // AXI PS Slave HP2 WVALID, input
.SAXIHP2WREADY(), // AXI PS Slave HP2 WREADY, output
.SAXIHP2WID(), // AXI PS Slave HP2 WID[5:0], input
.SAXIHP2WLAST(), // AXI PS Slave HP2 WLAST, input
.SAXIHP2WSTRB(), // AXI PS Slave HP2 WSTRB[7:0], input
.SAXIHP2WCOUNT(), // AXI PS Slave HP2 WCOUNT[7:0], output
.SAXIHP2WACOUNT(), // AXI PS Slave HP2 WACOUNT[5:0], output
.SAXIHP2WRISSUECAP1EN(), // AXI PS Slave HP2 WRISSUECAP1EN, input
// AXI PS Slave HP2: Write Responce
.SAXIHP2BVALID(), // AXI PS Slave HP2 BVALID, output
.SAXIHP2BREADY(), // AXI PS Slave HP2 BREADY, input
.SAXIHP2BID(), // AXI PS Slave HP2 BID[5:0], output
.SAXIHP2BRESP(), // AXI PS Slave HP2 BRESP[1:0], output
// AXI PS Slave HP3
// AXI PS Slave HP3: Clock, Reset
.SAXIHP3ACLK(), // AXI PS Slave HP3 Clock , input
.SAXIHP3ARESETN(), // AXI PS Slave HP3 Reset, output
// AXI PS Slave HP3: Read Address
.SAXIHP3ARADDR(), // AXI PS Slave HP3 ARADDR[31:0], input
.SAXIHP3ARVALID(), // AXI PS Slave HP3 ARVALID, input
.SAXIHP3ARREADY(), // AXI PS Slave HP3 ARREADY, output
.SAXIHP3ARID(), // AXI PS Slave HP3 ARID[5:0], input
.SAXIHP3ARLOCK(), // AXI PS Slave HP3 ARLOCK[1:0], input
.SAXIHP3ARCACHE(), // AXI PS Slave HP3 ARCACHE[3:0], input
.SAXIHP3ARPROT(), // AXI PS Slave HP3 ARPROT[2:0], input
.SAXIHP3ARLEN(), // AXI PS Slave HP3 ARLEN[3:0], input
.SAXIHP3ARSIZE(), // AXI PS Slave HP3 ARSIZE[2:0], input
.SAXIHP3ARBURST(), // AXI PS Slave HP3 ARBURST[1:0], input
.SAXIHP3ARQOS(), // AXI PS Slave HP3 ARQOS[3:0], input
// AXI PS Slave HP3: Read Data
.SAXIHP3RDATA(), // AXI PS Slave HP3 RDATA[63:0], output
.SAXIHP3RVALID(), // AXI PS Slave HP3 RVALID, output
.SAXIHP3RREADY(), // AXI PS Slave HP3 RREADY, input
.SAXIHP3RID(), // AXI PS Slave HP3 RID[5:0], output
.SAXIHP3RLAST(), // AXI PS Slave HP3 RLAST, output
.SAXIHP3RRESP(), // AXI PS Slave HP3 RRESP[1:0], output
.SAXIHP3RCOUNT(), // AXI PS Slave HP3 RCOUNT[7:0], output
.SAXIHP3RACOUNT(), // AXI PS Slave HP3 RACOUNT[2:0], output
.SAXIHP3RDISSUECAP1EN(), // AXI PS Slave HP3 RDISSUECAP1EN, input
// AXI PS Slave HP3: Write Address
.SAXIHP3AWADDR(), // AXI PS Slave HP3 AWADDR[31:0], input
.SAXIHP3AWVALID(), // AXI PS Slave HP3 AWVALID, input
.SAXIHP3AWREADY(), // AXI PS Slave HP3 AWREADY, output
.SAXIHP3AWID(), // AXI PS Slave HP3 AWID[5:0], input
.SAXIHP3AWLOCK(), // AXI PS Slave HP3 AWLOCK[1:0], input
.SAXIHP3AWCACHE(), // AXI PS Slave HP3 AWCACHE[3:0], input
.SAXIHP3AWPROT(), // AXI PS Slave HP3 AWPROT[2:0], input
.SAXIHP3AWLEN(), // AXI PS Slave HP3 AWLEN[3:0], input
.SAXIHP3AWSIZE(), // AXI PS Slave HP3 AWSIZE[1:0], input
.SAXIHP3AWBURST(), // AXI PS Slave HP3 AWBURST[1:0], input
.SAXIHP3AWQOS(), // AXI PS Slave HP3 AWQOS[3:0], input
// AXI PS Slave HP3: Write Data
.SAXIHP3WDATA(), // AXI PS Slave HP3 WDATA[63:0], input
.SAXIHP3WVALID(), // AXI PS Slave HP3 WVALID, input
.SAXIHP3WREADY(), // AXI PS Slave HP3 WREADY, output
.SAXIHP3WID(), // AXI PS Slave HP3 WID[5:0], input
.SAXIHP3WLAST(), // AXI PS Slave HP3 WLAST, input
.SAXIHP3WSTRB(), // AXI PS Slave HP3 WSTRB[7:0], input
.SAXIHP3WCOUNT(), // AXI PS Slave HP3 WCOUNT[7:0], output
.SAXIHP3WACOUNT(), // AXI PS Slave HP3 WACOUNT[5:0], output
.SAXIHP3WRISSUECAP1EN(), // AXI PS Slave HP3 WRISSUECAP1EN, input
// AXI PS Slave HP3: Write Responce
.SAXIHP3BVALID(), // AXI PS Slave HP3 BVALID, output
.SAXIHP3BREADY(), // AXI PS Slave HP3 BREADY, input
.SAXIHP3BID(), // AXI PS Slave HP3 BID[5:0], output
.SAXIHP3BRESP(), // AXI PS Slave HP3 BRESP[1:0], output
// AXI PS Slave ACP
// AXI PS Slave ACP: Clock, Reset
.SAXIACPACLK(), // AXI PS Slave ACP Clock, input
.SAXIACPARESETN(), // AXI PS Slave ACP Reset, output
// AXI PS Slave ACP: Read Address
.SAXIACPARADDR(), // AXI PS Slave ACP ARADDR[31:0], input
.SAXIACPARVALID(), // AXI PS Slave ACP ARVALID, input
.SAXIACPARREADY(), // AXI PS Slave ACP ARREADY, output
.SAXIACPARID(), // AXI PS Slave ACP ARID[2:0], input
.SAXIACPARLOCK(), // AXI PS Slave ACP ARLOCK[1:0], input
.SAXIACPARCACHE(), // AXI PS Slave ACP ARCACHE[3:0], input
.SAXIACPARPROT(), // AXI PS Slave ACP ARPROT[2:0], input
.SAXIACPARLEN(), // AXI PS Slave ACP ARLEN[3:0], input
.SAXIACPARSIZE(), // AXI PS Slave ACP ARSIZE[2:0], input
.SAXIACPARBURST(), // AXI PS Slave ACP ARBURST[1:0], input
.SAXIACPARQOS(), // AXI PS Slave ACP ARQOS[3:0], input
.SAXIACPARUSER(), // AXI PS Slave ACP ARUSER[4:0], input
// AXI PS Slave ACP: Read Data
.SAXIACPRDATA(), // AXI PS Slave ACP RDATA[63:0], output
.SAXIACPRVALID(), // AXI PS Slave ACP RVALID, output
.SAXIACPRREADY(), // AXI PS Slave ACP RREADY, input
.SAXIACPRID(), // AXI PS Slave ACP RID[2:0], output
.SAXIACPRLAST(), // AXI PS Slave ACP RLAST, output
.SAXIACPRRESP(), // AXI PS Slave ACP RRESP[1:0], output
// AXI PS Slave ACP: Write Address
.SAXIACPAWADDR(), // AXI PS Slave ACP AWADDR[31:0], input
.SAXIACPAWVALID(), // AXI PS Slave ACP AWVALID, input
.SAXIACPAWREADY(), // AXI PS Slave ACP AWREADY, output
.SAXIACPAWID(), // AXI PS Slave ACP AWID[2:0], input
.SAXIACPAWLOCK(), // AXI PS Slave ACP AWLOCK[1:0], input
.SAXIACPAWCACHE(), // AXI PS Slave ACP AWCACHE[3:0], input
.SAXIACPAWPROT(), // AXI PS Slave ACP AWPROT[2:0], input
.SAXIACPAWLEN(), // AXI PS Slave ACP AWLEN[3:0], input
.SAXIACPAWSIZE(), // AXI PS Slave ACP AWSIZE[1:0], input
.SAXIACPAWBURST(), // AXI PS Slave ACP AWBURST[1:0], input
.SAXIACPAWQOS(), // AXI PS Slave ACP AWQOS[3:0], input
.SAXIACPAWUSER(), // AXI PS Slave ACP AWUSER[4:0], input
// AXI PS Slave ACP: Write Data
.SAXIACPWDATA(), // AXI PS Slave ACP WDATA[63:0], input
.SAXIACPWVALID(), // AXI PS Slave ACP WVALID, input
.SAXIACPWREADY(), // AXI PS Slave ACP WREADY, output
.SAXIACPWID(), // AXI PS Slave ACP WID[2:0], input
.SAXIACPWLAST(), // AXI PS Slave ACP WLAST, input
.SAXIACPWSTRB(), // AXI PS Slave ACP WSTRB[7:0], input
// AXI PS Slave ACP: Write Responce
.SAXIACPBVALID(), // AXI PS Slave ACP BVALID, output
.SAXIACPBREADY(), // AXI PS Slave ACP BREADY, input
.SAXIACPBID(), // AXI PS Slave ACP BID[2:0], output
.SAXIACPBRESP(), // AXI PS Slave ACP BRESP[1:0], output
// Direct connection to PS package pads
.DDRA(), // PS DDRA[14:0], inout
.DDRBA(), // PS DDRBA[2:0], inout
.DDRCASB(), // PS DDRCASB, inout
.DDRCKE(), // PS DDRCKE, inout
.DDRCKP(), // PS DDRCKP, inout
.DDRCKN(), // PS DDRCKN, inout
.DDRCSB(), // PS DDRCSB, inout
.DDRDM(), // PS DDRDM[3:0], inout
.DDRDQ(), // PS DDRDQ[31:0], inout
.DDRDQSP(), // PS DDRDQSP[3:0], inout
.DDRDQSN(), // PS DDRDQSN[3:0], inout
.DDRDRSTB(), // PS DDRDRSTB, inout
.DDRODT(), // PS DDRODT, inout
.DDRRASB(), // PS DDRRASB, inout
.DDRVRN(), // PS DDRVRN, inout
.DDRVRP(), // PS DDRVRP, inout
.DDRWEB(), // PS DDRWEB, inout
.MIO(), // PS MIO[53:0], inout // clg225 has less
.PSCLK(), // PS PSCLK, inout
.PSPORB(), // PS PSPORB, inout
.PSSRSTB() // PS PSSRSTB, inout
);
endmodule
x393_sata-05c77d236b93a06053a6ec2d8ebcad493b999f28/x393/ 0000775 0000000 0000000 00000000000 12562737151 0020763 5 ustar 00root root 0000000 0000000