diff --git a/.gitignore b/.gitignore index 6225f22e..44a67bf6 100644 --- a/.gitignore +++ b/.gitignore @@ -54,3 +54,5 @@ xgui/ #ASIC proprietary files proprietary/ +# parallella_base intermediate files +src/parallella/fpga/parallella_base/src diff --git a/src/adi/Makefile b/src/adi/Makefile new file mode 100644 index 00000000..16085fce --- /dev/null +++ b/src/adi/Makefile @@ -0,0 +1,14 @@ +LIBRARY := ./hdl/library +IPS := axi_clkgen axi_hdmi_tx axi_spdif_tx axi_dmac + +.PHONY: all clean + +all: + for ip in $(IPS); do \ + make -C $(LIBRARY)/$$ip; \ + done + +clean: + for ip in $(IPS); do \ + make -C $(LIBRARY)/$$ip clean; \ + done diff --git a/src/adi/hdl/.gitattributes b/src/adi/hdl/.gitattributes new file mode 100644 index 00000000..96ff5a1f --- /dev/null +++ b/src/adi/hdl/.gitattributes @@ -0,0 +1,15 @@ +* text=auto + +*.c text +*.h text +*.prj +*.tcl text +*.txt text +*.ucf text +*.v text +*.vhd text +*.xdc text +*.xml text +*.qsys text +*.xise text +Makefile text diff --git a/src/adi/hdl/.gitignore b/src/adi/hdl/.gitignore new file mode 100644 index 00000000..052d4076 --- /dev/null +++ b/src/adi/hdl/.gitignore @@ -0,0 +1,79 @@ +*.cache +*.data +*.xpr +*.log +*.bld +*.chk +*.cmd_log +*.cxt +*.gise +*.gyd +*.jed +*.lso +*.mfd +*.nga +*.ngc +*.ngd +*.ngr +*.pad +*.pnx +*.prj +*.rpt +*.stx +*.syr +*.tim +*.tspec +*.vm6 +*.xst +*.html +*.xrpt +*.err +*_html +*.sld +*.txt +*.qsys +*.csv +xst +netgen +iseconfig +xlnx_auto* +_ngo +_xmsgs +component.xml +*.jou +xgui +*.runs +*.srcs +*.sdk +.Xil +*_INFO.txt +*_dump.txt +db +*.asm.rpt +*.done +*.eda.rpt +*.fit.* +*.map.* +*.sta.* +*.qsf +*.qpf +*.qws +*.sof +*.rbf +system_qsys_script.tcl +hc_output +hps_isw_handoff +hps_sdram_*.csv +incremental_db +system_bd/ +reconfig_mif +*.sopcinfo +*.jdi +*.pin +*.os +*webtalk* +*.xml +*.hw +gui +.timestamp_altera + diff --git a/src/adi/hdl/LICENSE b/src/adi/hdl/LICENSE new file mode 100644 index 00000000..731f5fdf --- /dev/null +++ b/src/adi/hdl/LICENSE @@ -0,0 +1,57 @@ + +In this HDL repository, there are many different and unique modules, consisting +of various HDL (Verilog or VHDL) components. The individual modules are +developed independently, and may be accompanied by separate and unique license +terms (such as GPL, LGPL, BSD, modified BSD, commercial or others). Your license +rights with respect to individual modules accompanied by separate license terms +are defined by those terms. The license agreement for each module is generally +located in the module source code. Nothing else shall restrict, limit, or +otherwise affect any rights or obligations you may have, or conditions to which +you may be subject, under such license terms. This agreement does not limit your +rights under, or grant you rights that supersede, the license terms of any +particular module. + +The mere aggregation of these modules (putting them side by side in the same +source code repository or on a hard disk) does not mean that there is one master +license for all the files. It is up to you, the user, to ensure that during the +building a project, which combines these modules together so that they form a +bit file (either one, or multiple for partial reconfiguration), all the individual +licenses are compatible. For example, if a single module is covered by the GPL, +the whole combination must also be released under the GPL. If you can't, or +won't, do that, you may not distribute the resulting bit file. + +The majority of ADI created modules are dual-licensed, allowing the user to pick +which license they want to use, (and the rights and obligations they have). + - The ADI BSD license, which allows you to make bit files, and not release your + source, as long as it attaches to an ADI device. This is not truly open + source, since it does place extra restrictions on developers. + - The GPL v2 license, which allows you to make bit files, but you must release + all other HDL (except vendor produced, which we consider as a run-time library), + permitted by GPL section 3, along with your bit file. This is truly open + source, and places no additional restrictions on use or fields of endeavor. The + GPL is ideal for use cases such as open source projects with open source + distribution, student/academic purposes, hobby projects, internal research + projects without external distribution, or other projects where all GPL + obligations can be met. + +In these cases, support is handled via web (https://ez.analog.com/community/fpga), +on a best effort basis. Note that our best efforts may not match your product +development schedule. This is a free, non-deterministic support, and is not meant +as a replacement for professional services. However, if this is not adequate +for your needs, or you require support within a specific time frame we recommend +you seek alternatives including seeking professional service and/or commercial/deterministic +support. + +There are also specific modules which are only single-licensed, as listed +below. This list may not be complete, it's up to the user to check each module +license. + - SPDIF, which is released under the LGPL license only. See + https://opencores.org/project,spdif_interface for support. + - The ADI created JESD Core, which is released under the GPL and a commercial + license only. + + The commercial license gives you the full rights to create and distribute + bit files on your own terms without any open source license obligations, + and special avenues for support may be possible. If you are interested + in such a license, contact us at jesd204-licensing@analog.com for more + information. + diff --git a/src/adi/hdl/LICENSE_ADIBSD b/src/adi/hdl/LICENSE_ADIBSD new file mode 100644 index 00000000..b7901834 --- /dev/null +++ b/src/adi/hdl/LICENSE_ADIBSD @@ -0,0 +1,33 @@ + +Copyright 2011(c) Analog Devices, Inc. + +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + - Neither the name of Analog Devices, Inc. nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + - The use of this software may or may not infringe the patent rights + of one or more patent holders. This license does not release you + from the requirement that you obtain separate licenses from these + patent holders to use this software. + - Use of the software either in source or binary form, must be run + on or directly connected to an Analog Devices Inc. component. + +THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE ARE DISCLAIMED. + +IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, INTELLECTUAL PROPERTY +RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR +BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF +THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/src/adi/hdl/LICENSE_GPL2 b/src/adi/hdl/LICENSE_GPL2 new file mode 100644 index 00000000..d81184bb --- /dev/null +++ b/src/adi/hdl/LICENSE_GPL2 @@ -0,0 +1,310 @@ + GNU GENERAL PUBLIC LICENSE + + Version 2, June 1991 + +Copyright (C) 1989, 1991 Free Software Foundation, Inc. 51 Franklin Street, +Fifth Floor, Boston, MA 02110-1301, USA + +Everyone is permitted to copy and distribute verbatim copies of this license +document, but changing it is not allowed. + + Preamble + +The licenses for most software are designed to take away your freedom to share +and change it. By contrast, the GNU General Public License is intended to +guarantee your freedom to share and change free software--to make sure the +software is free for all its users. This General Public License applies to most +of the Free Software Foundation's software and to any other program whose +authors commit to using it. (Some other Free Software Foundation software is +covered by the GNU Lesser General Public License instead.) You can apply it to +your programs, too. + +When we speak of free software, we are referring to freedom, not price. Our +General Public Licenses are designed to make sure that you have the freedom to +distribute copies of free software (and charge for this service if you wish), +that you receive source code or can get it if you want it, that you can change +the software or use pieces of it in new free programs; and that you know you can +do these things. + +To protect your rights, we need to make restrictions that forbid anyone to deny +you these rights or to ask you to surrender the rights. These restrictions +translate to certain responsibilities for you if you distribute copies of the +software, or if you modify it. + +For example, if you distribute copies of such a program, whether gratis or for a +fee, you must give the recipients all the rights that you have. You must make +sure that they, too, receive or can get the source code. And you must show them +these terms so they know their rights. + +We protect your rights with two steps: (1) copyright the software, and (2) offer +you this license which gives you legal permission to copy, distribute and/or +modify the software. + +Also, for each author's protection and ours, we want to make certain that +everyone understands that there is no warranty for this free software. If the +software is modified by someone else and passed on, we want its recipients to +know that what they have is not the original, so that any problems introduced by +others will not reflect on the original authors' reputations. + +Finally, any free program is threatened constantly by software patents. We wish +to avoid the danger that redistributors of a free program will individually +obtain patent licenses, in effect making the program proprietary. To prevent +this, we have made it clear that any patent must be licensed for everyone's free +use or not licensed at all. + +The precise terms and conditions for copying, distribution and modification +follow. + + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + +0. This License applies to any program or other work which contains a notice +placed by the copyright holder saying it may be distributed under the terms of +this General Public License. The "Program", below, refers to any such program or +work, and a "work based on the Program" means either the Program or any +derivative work under copyright law: that is to say, a work containing the +Program or a portion of it, either verbatim or with modifications and/or +translated into another language. (Hereinafter, translation is included without +limitation in the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not covered by +this License; they are outside its scope. The act of running the Program is not +restricted, and the output from the Program is covered only if its contents +constitute a work based on the Program (independent of having been made by +running the Program). Whether that is true depends on what the Program does. + +1. You may copy and distribute verbatim copies of the Program's source code as +you receive it, in any medium, provided that you conspicuously and appropriately +publish on each copy an appropriate copyright notice and disclaimer of warranty; +keep intact all the notices that refer to this License and to the absence of any +warranty; and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and you may at +your option offer warranty protection in exchange for a fee. + +2. You may modify your copy or copies of the Program or any portion of it, thus +forming a work based on the Program, and copy and distribute such modifications +or work under the terms of Section 1 above, provided that you also meet all of +these conditions: + + a) You must cause the modified files to carry prominent notices stating that +you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in whole or +in part contains or is derived from the Program or any part thereof, to be +licensed as a whole at no charge to all third parties under the terms of this +License. + + c) If the modified program normally reads commands interactively when run, +you must cause it, when started running for such interactive use in the most +ordinary way, to print or display an announcement including an appropriate +copyright notice and a notice that there is no warranty (or else, saying that +you provide a warranty) and that users may redistribute the program under these +conditions, and telling the user how to view a copy of this License. (Exception: +if the Program itself is interactive but does not normally print such an +announcement, your work based on the Program is not required to print an +announcement.) These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, and can be +reasonably considered independent and separate works in themselves, then this +License, and its terms, do not apply to those sections when you distribute them +as separate works. But when you distribute the same sections as part of a whole +which is a work based on the Program, the distribution of the whole must be on +the terms of this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest your +rights to work written entirely by you; rather, the intent is to exercise the +right to control the distribution of derivative or collective works based on the +Program. + +In addition, mere aggregation of another work not based on the Program with the +Program (or with a work based on the Program) on a volume of a storage or +distribution medium does not bring the other work under the scope of this +License. + +3. You may copy and distribute the Program (or a work based on it, under Section +2) in object code or executable form under the terms of Sections 1 and 2 above +provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable source +code, which must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three years, to +give any third party, for a charge no more than your cost of physically +performing source distribution, a complete machine-readable copy of the +corresponding source code, to be distributed under the terms of Sections 1 and 2 +above on a medium customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer to +distribute corresponding source code. (This alternative is allowed only for +noncommercial distribution and only if you received the program in object code +or executable form with such an offer, in accord with Subsection b above.) The +source code for a work means the preferred form of the work for making +modifications to it. For an executable work, complete source code means all the +source code for all modules it contains, plus any associated interface +definition files, plus the scripts used to control compilation and installation +of the executable. However, as a special exception, the source code distributed +need not include anything that is normally distributed (in either source or +binary form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component itself +accompanies the executable. + +If distribution of executable or object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the source code +from the same place counts as distribution of the source code, even though third +parties are not compelled to copy the source along with the object code. + +4. You may not copy, modify, sublicense, or distribute the Program except as +expressly provided under this License. Any attempt otherwise to copy, modify, +sublicense or distribute the Program is void, and will automatically terminate +your rights under this License. However, parties who have received copies, or +rights, from you under this License will not have their licenses terminated so +long as such parties remain in full compliance. + +5. You are not required to accept this License, since you have not signed it. +However, nothing else grants you permission to modify or distribute the Program +or its derivative works. These actions are prohibited by law if you do not +accept this License. Therefore, by modifying or distributing the Program (or any +work based on the Program), you indicate your acceptance of this License to do +so, and all its terms and conditions for copying, distributing or modifying the +Program or works based on it. + +6. Each time you redistribute the Program (or any work based on the Program), +the recipient automatically receives a license from the original licensor to +copy, distribute or modify the Program subject to these terms and conditions. +You may not impose any further restrictions on the recipients' exercise of the +rights granted herein. You are not responsible for enforcing compliance by third +parties to this License. + +7. If, as a consequence of a court judgment or allegation of patent infringement +or for any other reason (not limited to patent issues), conditions are imposed +on you (whether by court order, agreement or otherwise) that contradict the +conditions of this License, they do not excuse you from the conditions of this +License. If you cannot distribute so as to satisfy simultaneously your +obligations under this License and any other pertinent obligations, then as a +consequence you may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by all those +who receive copies directly or indirectly through you, then the only way you +could satisfy both it and this License would be to refrain entirely from +distribution of the Program. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply and the +section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any patents or +other property right claims or to contest validity of any such claims; this +section has the sole purpose of protecting the integrity of the free software +distribution system, which is implemented by public license practices. Many +people have made generous contributions to the wide range of software +distributed through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing to +distribute software through any other system and a licensee cannot impose that +choice. + +This section is intended to make thoroughly clear what is believed to be a +consequence of the rest of this License. + +8. If the distribution and/or use of the Program is restricted in certain +countries either by patents or by copyrighted interfaces, the original copyright +holder who places the Program under this License may add an explicit +geographical distribution limitation excluding those countries, so that +distribution is permitted only in or among countries not thus excluded. In such +case, this License incorporates the limitation as if written in the body of this +License. + +9. The Free Software Foundation may publish revised and/or new versions of the +General Public License from time to time. Such new versions will be similar in +spirit to the present version, but may differ in detail to address new problems +or concerns. + +Each version is given a distinguishing version number. If the Program specifies +a version number of this License which applies to it and "any later version", +you have the option of following the terms and conditions either of that version +or of any later version published by the Free Software Foundation. If the +Program does not specify a version number of this License, you may choose any +version ever published by the Free Software Foundation. + +10. If you wish to incorporate parts of the Program into other free programs +whose distribution conditions are different, write to the author to ask for +permission. For software which is copyrighted by the Free Software Foundation, +write to the Free Software Foundation; we sometimes make exceptions for this. +Our decision will be guided by the two goals of preserving the free status of +all derivatives of our free software and of promoting the sharing and reuse of +software generally. + + NO WARRANTY + +11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE +PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED +IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS +IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT +NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + +12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL +ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE +PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, +SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY +TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF +THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER +PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + +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 convey 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 an idea of what it does. Copyright (C) +yyyy 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 2 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, write to the Free Software Foundation, Inc., 51 Franklin +Street, Fifth Floor, Boston, MA 02110-1301, USA. Also add information on how +to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this when it +starts in an interactive mode: + +Gnomovision version 69, Copyright (C) year name of author Gnomovision 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, the commands you use +may be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your school, +if any, to sign a "copyright disclaimer" for the program, if necessary. Here is +a sample; alter the names: + +Yoyodyne, Inc., hereby disclaims all copyright interest in the program +`Gnomovision' (which makes passes at compilers) written by James Hacker. + +signature of Ty Coon, 1 April 1989 Ty Coon, President of Vice This 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. diff --git a/src/adi/hdl/LICENSE_LGPL b/src/adi/hdl/LICENSE_LGPL new file mode 100644 index 00000000..aebcbdd7 --- /dev/null +++ b/src/adi/hdl/LICENSE_LGPL @@ -0,0 +1,152 @@ + GNU LESSER 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. + + + This version of the GNU Lesser General Public License incorporates the terms +and conditions of version 3 of the GNU General Public License, supplemented by +the additional permissions listed below. + + 0. Additional Definitions. + + As used herein, "this License" refers to version 3 of the GNU Lesser General +Public License, and the "GNU GPL" refers to version 3 of the GNU General Public +License. + + "The Library" refers to a covered work governed by this License, other than an +Application or a Combined Work as defined below. + + An "Application" is any work that makes use of an interface provided by the +Library, but which is not otherwise based on the Library. Defining a subclass +of a class defined by the Library is deemed a mode of using an interface +provided by the Library. + + A "Combined Work" is a work produced by combining or linking an Application +with the Library. The particular version of the Library with which the Combined +Work was made is also called the "Linked Version". + + The "Minimal Corresponding Source" for a Combined Work means the Corresponding +Source for the Combined Work, excluding any source code for portions of the +Combined Work that, considered in isolation, are based on the Application, and +not on the Linked Version. + + The "Corresponding Application Code" for a Combined Work means the object code +and/or source code for the Application, including any data and utility programs +needed for reproducing the Combined Work from the Application, but excluding the +System Libraries of the Combined Work. + + 1. Exception to Section 3 of the GNU GPL. + + You may convey a covered work under sections 3 and 4 of this License without +being bound by section 3 of the GNU GPL. + + 2. Conveying Modified Versions. + + If you modify a copy of the Library, and, in your modifications, a facility +refers to a function or data to be supplied by an Application that uses the +facility (other than as an argument passed when the facility is invoked), then +you may convey a copy of the modified version: + + a) under this License, provided that you make a good faith effort to ensure +that, in the event an Application does not supply the function or data, the +facility still operates, and performs whatever part of its purpose remains +meaningful, or + + b) under the GNU GPL, with none of the additional permissions of this License +applicable to that copy. + + 3. Object Code Incorporating Material from Library Header Files. + + The object code form of an Application may incorporate material from a header +file that is part of the Library. You may convey such object code under terms +of your choice, provided that, if the incorporated material is not limited to +numerical parameters, data structure layouts and accessors, or small macros, +inline functions and templates (ten or fewer lines in length), you do both of +the following: + + a) Give prominent notice with each copy of the object code that the Library +is used in it and that the Library and its use are covered by this License. + + b) Accompany the object code with a copy of the GNU GPL and this license +document. + + 4. Combined Works. + + You may convey a Combined Work under terms of your choice that, taken +together, effectively do not restrict modification of the portions of the +Library contained in the Combined Work and reverse engineering for debugging +such modifications, if you also do each of the following: + + a) Give prominent notice with each copy of the Combined Work that the Library +is used in it and that the Library and its use are covered by this License. + + b) Accompany the Combined Work with a copy of the GNU GPL and this license +document. + + c) For a Combined Work that displays copyright notices during execution, +include the copyright notice for the Library among these notices, as well as a +reference directing the user to the copies of the GNU GPL and this license +document. + + d) Do one of the following: + + 0) Convey the Minimal Corresponding Source under the terms of this +License, and the Corresponding Application Code in a form suitable for, and +under terms that permit, the user to recombine or relink the Application with a +modified version of the Linked Version to produce a modified Combined Work, in +the manner specified by section 6 of the GNU GPL for conveying Corresponding +Source. + + 1) Use a suitable shared library mechanism for linking with the Library. +A suitable mechanism is one that (a) uses at run time a copy of the Library +already present on the user's computer system, and (b) will operate properly +with a modified version of the Library that is interface-compatible with the +Linked Version. + + e) Provide Installation Information, but only if you would otherwise be +required to provide such information under section 6 of the GNU GPL, and only to +the extent that such information is necessary to install and execute a modified +version of the Combined Work produced by recombining or relinking the +Application with a modified version of the Linked Version. (If you use option +4d0, the Installation Information must accompany the Minimal Corresponding +Source and Corresponding Application Code. If you use option 4d1, you must +provide the Installation Information in the manner specified by section 6 of the +GNU GPL for conveying Corresponding Source.) + + 5. Combined Libraries. + + You may place library facilities that are a work based on the Library side by +side in a single library together with other library facilities that are not +Applications and are not covered by this License, and convey such a combined +library under terms of your choice, if you do both of the following: + + a) Accompany the combined library with a copy of the same work based on the +Library, uncombined with any other library facilities, conveyed under the terms +of this License. + + b) Give prominent notice with the combined library that part of it is a work +based on the Library, and explaining where to find the accompanying uncombined +form of the same work. + + 6. Revised Versions of the GNU Lesser General Public License. + + The Free Software Foundation may publish revised and/or new versions of the +GNU Lesser 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 Library as you +received it specifies that a certain numbered version of the GNU Lesser General +Public License "or any later version" applies to it, you have the option of +following the terms and conditions either of that published version or of any +later version published by the Free Software Foundation. If the Library as you +received it does not specify a version number of the GNU Lesser General Public +License, you may choose any version of the GNU Lesser General Public License +ever published by the Free Software Foundation. + + If the Library as you received it specifies that a proxy can decide whether +future versions of the GNU Lesser General Public License shall apply, that +proxy's public statement of acceptance of any version is permanent authorization +for you to choose that version for the Library. diff --git a/src/adi/hdl/Makefile b/src/adi/hdl/Makefile new file mode 100644 index 00000000..4d2d0434 --- /dev/null +++ b/src/adi/hdl/Makefile @@ -0,0 +1,50 @@ +#################################################################################### +#################################################################################### +## Copyright 2011(c) Analog Devices, Inc. +## Auto-generated, do not modify! +#################################################################################### +#################################################################################### + +include quiet.mk + +help: + @echo "" + @echo "Please specify a target." + @echo "" + @echo "To make all projects:" + @echo " make all" + @echo "" + @echo "To build a specific project:" + @echo " make proj.board" + @echo "e.g.," + @echo " make adv7511.zed" + + +PROJECTS := $(filter-out $(NO_PROJ), $(notdir $(wildcard projects/*))) +SUBPROJECTS := $(foreach projname,$(PROJECTS), \ + $(foreach archname,$(notdir $(subst /Makefile,,$(wildcard projects/$(projname)/*/Makefile))), \ + $(projname).$(archname))) + +.PHONY: lib all clean clean-all $(SUBPROJECTS) + +$(SUBPROJECTS): + $(MAKE) -C projects/$(subst .,/,$@) + +lib: + $(MAKE) -C library/ all + + +all: + $(MAKE) -C projects/ all + + +clean: + $(MAKE) -C projects/ clean + + +clean-all:clean + $(MAKE) -C projects/ clean + $(MAKE) -C library/ clean + +#################################################################################### +#################################################################################### diff --git a/src/adi/hdl/README.md b/src/adi/hdl/README.md new file mode 100644 index 00000000..1e024f67 --- /dev/null +++ b/src/adi/hdl/README.md @@ -0,0 +1,72 @@ + +# HDL Reference Designs + +[Analog Devices Inc.](http://www.analog.com/en/index.html) HDL libraries and projects. + +## Getting started + +This repository supports reference designs for different [Analog Devices boards](../master/projects) based on [Intel and Xilinx FPGA development boards](../master/projects/common) or standalone. + +### Prerequisites + + * [Vivado Design Suite](https://www.xilinx.com/support/download.html) + +**or** + + * [Quartus Prime Design Suite](https://www.altera.com/downloads/download-center.html) + +Please make sure that you have the [required](https://github.com/analogdevicesinc/hdl/releases) tool version. + +### How to build a project + +For building a projects, you have to use the [GNU Make tool](https://www.gnu.org/software/make/). If you're a +Windows user please checkout [this page](https://wiki.analog.com/resources/fpga/docs/build#windows_environment_setup), to see how you can install this tool. + +To build a project, checkout the [latest release](https://github.com/analogdevicesinc/hdl/releases), after that just **cd** to the +project that you want to build and run make: +``` + [~]cd projects/fmcomms2/zc706 + [~]make +``` + +A more comprehensive build guide can be found under the following link: + + +## Software + +In general all the projects have no-OS (baremetal) and a Linux support. See [no-OS](https://github.com/analogdevicesinc/no-OS) or [Linux](https://github.com/analogdevicesinc/Linux) for +more information. + +## Which branch should I use? + + * If you want to use the most stable code base, always use the [latest release branch](https://github.com/analogdevicesinc/hdl/releases). + + * If you want to use the greatest and latest, check out the master branch. + +## License + +In this HDL repository, there are many different and unique modules, consisting +of various HDL (Verilog or VHDL) components. The individual modules are +developed independently, and may be accompanied by separate and unique license +terms. + +The user should read each of these license terms, and understand the +freedoms and responsibilities that he or she has by using this source/core. + +See [LICENSE](../master/LICENSE) for more details. The separate license files +cab be found here: + + * [LICENSE_ADIBSD](../master/LICENSE_ADIBSD) + + * [LICENSE_GPL2](../master/LICENSE_GPL2) + + * [LICENSE_LGPL](../master/LICENSE_LGPL) + +## Comprehensive user guide + +See [HDL User Guide](https://wiki.analog.com/resources/fpga/docs/hdl) for a more detailed guide. + +## Support + +Feel free to ask any question at [EngineerZone](https://ez.analog.com/community/fpga). + diff --git a/src/adi/hdl/library/Makefile b/src/adi/hdl/library/Makefile new file mode 100644 index 00000000..08b80ff6 --- /dev/null +++ b/src/adi/hdl/library/Makefile @@ -0,0 +1,227 @@ +#################################################################################### +#################################################################################### +## Copyright 2011(c) Analog Devices, Inc. +## Auto-generated, do not modify! +#################################################################################### +#################################################################################### + +include ../quiet.mk + +.PHONY: all lib clean clean-all +all: lib + + +clean: + $(MAKE) -C altera/adi_jesd204 clean + $(MAKE) -C altera/avl_adxcfg clean + $(MAKE) -C altera/avl_adxcvr clean + $(MAKE) -C altera/avl_adxcvr_octet_swap clean + $(MAKE) -C altera/avl_adxphy clean + $(MAKE) -C altera/avl_dacfifo clean + $(MAKE) -C altera/axi_adxcvr clean + $(MAKE) -C altera/common/alt_ifconv clean + $(MAKE) -C altera/common/alt_mem_asym clean + $(MAKE) -C altera/common/alt_mul clean + $(MAKE) -C altera/common/alt_serdes clean + $(MAKE) -C altera/jesd204_phy clean + $(MAKE) -C axi_ad5766 clean + $(MAKE) -C axi_ad6676 clean + $(MAKE) -C axi_ad7616 clean + $(MAKE) -C axi_ad9122 clean + $(MAKE) -C axi_ad9144 clean + $(MAKE) -C axi_ad9152 clean + $(MAKE) -C axi_ad9162 clean + $(MAKE) -C axi_ad9250 clean + $(MAKE) -C axi_ad9265 clean + $(MAKE) -C axi_ad9361 clean + $(MAKE) -C axi_ad9371 clean + $(MAKE) -C axi_ad9434 clean + $(MAKE) -C axi_ad9467 clean + $(MAKE) -C axi_ad9625 clean + $(MAKE) -C axi_ad9671 clean + $(MAKE) -C axi_ad9680 clean + $(MAKE) -C axi_ad9684 clean + $(MAKE) -C axi_ad9739a clean + $(MAKE) -C axi_ad9963 clean + $(MAKE) -C axi_adc_decimate clean + $(MAKE) -C axi_adc_trigger clean + $(MAKE) -C axi_adrv9009 clean + $(MAKE) -C axi_clkgen clean + $(MAKE) -C axi_dac_interpolate clean + $(MAKE) -C axi_dmac clean + $(MAKE) -C axi_fmcadc5_sync clean + $(MAKE) -C axi_generic_adc clean + $(MAKE) -C axi_gpreg clean + $(MAKE) -C axi_hdmi_rx clean + $(MAKE) -C axi_hdmi_tx clean + $(MAKE) -C axi_i2s_adi clean + $(MAKE) -C axi_intr_monitor clean + $(MAKE) -C axi_logic_analyzer clean + $(MAKE) -C axi_mc_controller clean + $(MAKE) -C axi_mc_current_monitor clean + $(MAKE) -C axi_mc_speed clean + $(MAKE) -C axi_rd_wr_combiner clean + $(MAKE) -C axi_spdif_rx clean + $(MAKE) -C axi_spdif_tx clean + $(MAKE) -C axi_usb_fx3 clean + $(MAKE) -C cn0363/cn0363_dma_sequencer clean + $(MAKE) -C cn0363/cn0363_phase_data_sync clean + $(MAKE) -C cordic_demod clean + $(MAKE) -C jesd204/ad_ip_jesd204_tpl_adc clean + $(MAKE) -C jesd204/ad_ip_jesd204_tpl_dac clean + $(MAKE) -C jesd204/axi_jesd204_common clean + $(MAKE) -C jesd204/axi_jesd204_rx clean + $(MAKE) -C jesd204/axi_jesd204_tx clean + $(MAKE) -C jesd204/jesd204_common clean + $(MAKE) -C jesd204/jesd204_rx clean + $(MAKE) -C jesd204/jesd204_rx_static_config clean + $(MAKE) -C jesd204/jesd204_soft_pcs_rx clean + $(MAKE) -C jesd204/jesd204_soft_pcs_tx clean + $(MAKE) -C jesd204/jesd204_tx clean + $(MAKE) -C jesd204/jesd204_tx_static_config clean + $(MAKE) -C spi_engine/axi_spi_engine clean + $(MAKE) -C spi_engine/spi_engine_execution clean + $(MAKE) -C spi_engine/spi_engine_interconnect clean + $(MAKE) -C spi_engine/spi_engine_offload clean + $(MAKE) -C util_adcfifo clean + $(MAKE) -C util_axis_fifo clean + $(MAKE) -C util_axis_resize clean + $(MAKE) -C util_axis_upscale clean + $(MAKE) -C util_bsplit clean + $(MAKE) -C util_cdc clean + $(MAKE) -C util_cic clean + $(MAKE) -C util_clkdiv clean + $(MAKE) -C util_cpack clean + $(MAKE) -C util_dacfifo clean + $(MAKE) -C util_delay clean + $(MAKE) -C util_extract clean + $(MAKE) -C util_fir_dec clean + $(MAKE) -C util_fir_int clean + $(MAKE) -C util_gmii_to_rgmii clean + $(MAKE) -C util_i2c_mixer clean + $(MAKE) -C util_mfifo clean + $(MAKE) -C util_pulse_gen clean + $(MAKE) -C util_rfifo clean + $(MAKE) -C util_sigma_delta_spi clean + $(MAKE) -C util_tdd_sync clean + $(MAKE) -C util_upack clean + $(MAKE) -C util_var_fifo clean + $(MAKE) -C util_wfifo clean + $(MAKE) -C xilinx/axi_adcfifo clean + $(MAKE) -C xilinx/axi_adxcvr clean + $(MAKE) -C xilinx/axi_dacfifo clean + $(MAKE) -C xilinx/axi_xcvrlb clean + $(MAKE) -C xilinx/util_adxcvr clean + + $(MAKE) -C interfaces clean + + +clean-all:clean + + +lib: + $(MAKE) -C altera/adi_jesd204 + $(MAKE) -C altera/avl_adxcfg + $(MAKE) -C altera/avl_adxcvr + $(MAKE) -C altera/avl_adxcvr_octet_swap + $(MAKE) -C altera/avl_adxphy + $(MAKE) -C altera/avl_dacfifo + $(MAKE) -C altera/axi_adxcvr + $(MAKE) -C altera/common/alt_ifconv + $(MAKE) -C altera/common/alt_mem_asym + $(MAKE) -C altera/common/alt_mul + $(MAKE) -C altera/common/alt_serdes + $(MAKE) -C altera/jesd204_phy + $(MAKE) -C axi_ad5766 + $(MAKE) -C axi_ad6676 + $(MAKE) -C axi_ad7616 + $(MAKE) -C axi_ad9122 + $(MAKE) -C axi_ad9144 + $(MAKE) -C axi_ad9152 + $(MAKE) -C axi_ad9162 + $(MAKE) -C axi_ad9250 + $(MAKE) -C axi_ad9265 + $(MAKE) -C axi_ad9361 + $(MAKE) -C axi_ad9371 + $(MAKE) -C axi_ad9434 + $(MAKE) -C axi_ad9467 + $(MAKE) -C axi_ad9625 + $(MAKE) -C axi_ad9671 + $(MAKE) -C axi_ad9680 + $(MAKE) -C axi_ad9684 + $(MAKE) -C axi_ad9739a + $(MAKE) -C axi_ad9963 + $(MAKE) -C axi_adc_decimate + $(MAKE) -C axi_adc_trigger + $(MAKE) -C axi_adrv9009 + $(MAKE) -C axi_clkgen + $(MAKE) -C axi_dac_interpolate + $(MAKE) -C axi_dmac + $(MAKE) -C axi_fmcadc5_sync + $(MAKE) -C axi_generic_adc + $(MAKE) -C axi_gpreg + $(MAKE) -C axi_hdmi_rx + $(MAKE) -C axi_hdmi_tx + $(MAKE) -C axi_i2s_adi + $(MAKE) -C axi_intr_monitor + $(MAKE) -C axi_logic_analyzer + $(MAKE) -C axi_mc_controller + $(MAKE) -C axi_mc_current_monitor + $(MAKE) -C axi_mc_speed + $(MAKE) -C axi_rd_wr_combiner + $(MAKE) -C axi_spdif_rx + $(MAKE) -C axi_spdif_tx + $(MAKE) -C axi_usb_fx3 + $(MAKE) -C cn0363/cn0363_dma_sequencer + $(MAKE) -C cn0363/cn0363_phase_data_sync + $(MAKE) -C cordic_demod + $(MAKE) -C jesd204/ad_ip_jesd204_tpl_adc + $(MAKE) -C jesd204/ad_ip_jesd204_tpl_dac + $(MAKE) -C jesd204/axi_jesd204_common + $(MAKE) -C jesd204/axi_jesd204_rx + $(MAKE) -C jesd204/axi_jesd204_tx + $(MAKE) -C jesd204/jesd204_common + $(MAKE) -C jesd204/jesd204_rx + $(MAKE) -C jesd204/jesd204_rx_static_config + $(MAKE) -C jesd204/jesd204_soft_pcs_rx + $(MAKE) -C jesd204/jesd204_soft_pcs_tx + $(MAKE) -C jesd204/jesd204_tx + $(MAKE) -C jesd204/jesd204_tx_static_config + $(MAKE) -C spi_engine/axi_spi_engine + $(MAKE) -C spi_engine/spi_engine_execution + $(MAKE) -C spi_engine/spi_engine_interconnect + $(MAKE) -C spi_engine/spi_engine_offload + $(MAKE) -C util_adcfifo + $(MAKE) -C util_axis_fifo + $(MAKE) -C util_axis_resize + $(MAKE) -C util_axis_upscale + $(MAKE) -C util_bsplit + $(MAKE) -C util_cdc + $(MAKE) -C util_cic + $(MAKE) -C util_clkdiv + $(MAKE) -C util_cpack + $(MAKE) -C util_dacfifo + $(MAKE) -C util_delay + $(MAKE) -C util_extract + $(MAKE) -C util_fir_dec + $(MAKE) -C util_fir_int + $(MAKE) -C util_gmii_to_rgmii + $(MAKE) -C util_i2c_mixer + $(MAKE) -C util_mfifo + $(MAKE) -C util_pulse_gen + $(MAKE) -C util_rfifo + $(MAKE) -C util_sigma_delta_spi + $(MAKE) -C util_tdd_sync + $(MAKE) -C util_upack + $(MAKE) -C util_var_fifo + $(MAKE) -C util_wfifo + $(MAKE) -C xilinx/axi_adcfifo + $(MAKE) -C xilinx/axi_adxcvr + $(MAKE) -C xilinx/axi_dacfifo + $(MAKE) -C xilinx/axi_xcvrlb + $(MAKE) -C xilinx/util_adxcvr + + $(MAKE) -C interfaces + +#################################################################################### +#################################################################################### diff --git a/src/adi/hdl/library/altera/common/ad_dcfilter.v b/src/adi/hdl/library/altera/common/ad_dcfilter.v new file mode 100644 index 00000000..2cd19c3e --- /dev/null +++ b/src/adi/hdl/library/altera/common/ad_dcfilter.v @@ -0,0 +1,85 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright 2014 - 2017 (c) Analog Devices, Inc. All rights reserved. +// +// In this HDL repository, there are many different and unique modules, consisting +// of various HDL (Verilog or VHDL) components. The individual modules are +// developed independently, and may be accompanied by separate and unique license +// terms. +// +// The user should read each of these license terms, and understand the +// freedoms and responsibilities that he or she has by using this source/core. +// +// This core 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. +// +// Redistribution and use of source or resulting binaries, with or without modification +// of this file, are permitted under one of the following two license terms: +// +// 1. The GNU General Public License version 2 as published by the +// Free Software Foundation, which can be found in the top level directory +// of this repository (LICENSE_GPL2), and also online at: +// +// +// OR +// +// 2. An ADI specific BSD license, which can be found in the top level directory +// of this repository (LICENSE_ADIBSD), and also on-line at: +// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD +// This will allow to generate bit files and not release the source code, +// as long as it attaches to an ADI device. +// +// *************************************************************************** +// *************************************************************************** +// dc filter- y(n) = c*x(n) + (1-c)*y(n-1) +// NOT IMPLEMENTED + +`timescale 1ps/1ps + +module ad_dcfilter #( + + // data path disable + + parameter DISABLE = 0) ( + + // data interface + + input clk, + input valid, + input [15:0] data, + output reg valid_out, + output reg [15:0] data_out, + + // control interface + + input dcfilt_enb, + input [15:0] dcfilt_coeff, + input [15:0] dcfilt_offset); + + // internal registers + + reg valid_d = 'd0; + reg [15:0] data_d = 'd0; + reg valid_2d = 'd0; + reg [15:0] data_2d = 'd0; + + // internal signals + + wire [47:0] dc_offset_s; + + always @(posedge clk) begin + valid_d <= valid; + if (valid == 1'b1) begin + data_d <= data + dcfilt_offset; + end + valid_2d <= valid_d; + data_2d <= data_d; + valid_out <= valid_2d; + data_out <= data_2d; + end + +endmodule + +// *************************************************************************** +// *************************************************************************** diff --git a/src/adi/hdl/library/altera/common/ad_mul.v b/src/adi/hdl/library/altera/common/ad_mul.v new file mode 100644 index 00000000..eaaef8b7 --- /dev/null +++ b/src/adi/hdl/library/altera/common/ad_mul.v @@ -0,0 +1,90 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright 2014 - 2017 (c) Analog Devices, Inc. All rights reserved. +// +// In this HDL repository, there are many different and unique modules, consisting +// of various HDL (Verilog or VHDL) components. The individual modules are +// developed independently, and may be accompanied by separate and unique license +// terms. +// +// The user should read each of these license terms, and understand the +// freedoms and responsibilities that he or she has by using this source/core. +// +// This core 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. +// +// Redistribution and use of source or resulting binaries, with or without modification +// of this file, are permitted under one of the following two license terms: +// +// 1. The GNU General Public License version 2 as published by the +// Free Software Foundation, which can be found in the top level directory +// of this repository (LICENSE_GPL2), and also online at: +// +// +// OR +// +// 2. An ADI specific BSD license, which can be found in the top level directory +// of this repository (LICENSE_ADIBSD), and also on-line at: +// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD +// This will allow to generate bit files and not release the source code, +// as long as it attaches to an ADI device. +// +// *************************************************************************** +// *************************************************************************** + +`timescale 1ps/1ps + +module ad_mul #( + + parameter A_DATA_WIDTH = 17, + parameter B_DATA_WIDTH = 17, + parameter DELAY_DATA_WIDTH = 16) ( + + // data_p = data_a * data_b; + + input clk, + input [ A_DATA_WIDTH-1:0] data_a, + input [ B_DATA_WIDTH-1:0] data_b, + output [A_DATA_WIDTH + B_DATA_WIDTH-1:0] data_p, + + // delay interface + + input [(DELAY_DATA_WIDTH-1):0] ddata_in, + output reg [(DELAY_DATA_WIDTH-1):0] ddata_out); + + + // internal registers + + reg [(DELAY_DATA_WIDTH-1):0] p1_ddata = 'd0; + reg [(DELAY_DATA_WIDTH-1):0] p2_ddata = 'd0; + + // a/b reg, m-reg, p-reg delay match + + always @(posedge clk) begin + p1_ddata <= ddata_in; + p2_ddata <= p1_ddata; + ddata_out <= p2_ddata; + end + + lpm_mult #( + .lpm_type ("lpm_mult"), + .lpm_widtha (A_DATA_WIDTH), + .lpm_widthb (B_DATA_WIDTH), + .lpm_widthp (A_DATA_WIDTH + B_DATA_WIDTH), + .lpm_representation ("SIGNED"), + .lpm_pipeline (3)) + i_lpm_mult ( + .clken (1'b1), + .aclr (1'b0), + .sclr (1'b0), + .sum (1'b0), + .clock (clk), + .dataa (data_a), + .datab (data_b), + .result (data_p)); + +endmodule + +// *************************************************************************** +// *************************************************************************** diff --git a/src/adi/hdl/library/altera/common/alt_ifconv/Makefile b/src/adi/hdl/library/altera/common/alt_ifconv/Makefile new file mode 100644 index 00000000..2fa8c247 --- /dev/null +++ b/src/adi/hdl/library/altera/common/alt_ifconv/Makefile @@ -0,0 +1,11 @@ +#################################################################################### +## Copyright 2018(c) Analog Devices, Inc. +## Auto-generated, do not modify! +#################################################################################### + +LIBRARY_NAME := alt_ifconv + +ALTERA_DEPS += alt_ifconv.v +ALTERA_DEPS += alt_ifconv_hw.tcl + +include ../../../scripts/library.mk diff --git a/src/adi/hdl/library/altera/common/alt_ifconv/alt_ifconv.v b/src/adi/hdl/library/altera/common/alt_ifconv/alt_ifconv.v new file mode 100644 index 00000000..3bf502ab --- /dev/null +++ b/src/adi/hdl/library/altera/common/alt_ifconv/alt_ifconv.v @@ -0,0 +1,60 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright 2014 - 2017 (c) Analog Devices, Inc. All rights reserved. +// +// In this HDL repository, there are many different and unique modules, consisting +// of various HDL (Verilog or VHDL) components. The individual modules are +// developed independently, and may be accompanied by separate and unique license +// terms. +// +// The user should read each of these license terms, and understand the +// freedoms and responsibilities that he or she has by using this source/core. +// +// This core 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. +// +// Redistribution and use of source or resulting binaries, with or without modification +// of this file, are permitted under one of the following two license terms: +// +// 1. The GNU General Public License version 2 as published by the +// Free Software Foundation, which can be found in the top level directory +// of this repository (LICENSE_GPL2), and also online at: +// +// +// OR +// +// 2. An ADI specific BSD license, which can be found in the top level directory +// of this repository (LICENSE_ADIBSD), and also on-line at: +// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD +// This will allow to generate bit files and not release the source code, +// as long as it attaches to an ADI device. +// +// *************************************************************************** +// *************************************************************************** + +`timescale 1ns/100ps + +module alt_ifconv #( + + // parameters + + parameter WIDTH = 1, + parameter INTERFACE_NAME_IN = "input-interface-name", + parameter INTERFACE_NAME_OUT = "output-interface-name", + parameter SIGNAL_NAME_IN = "input-signal-name", + parameter SIGNAL_NAME_OUT = "output-signal-name") ( + + // bad tools - ugly stuff + + input [(WIDTH-1):0] din, + output [(WIDTH-1):0] dout); + + // avoiding qsys signal conflicts + + assign dout = din; + +endmodule + +// *************************************************************************** +// *************************************************************************** diff --git a/src/adi/hdl/library/altera/common/alt_ifconv/alt_ifconv_hw.tcl b/src/adi/hdl/library/altera/common/alt_ifconv/alt_ifconv_hw.tcl new file mode 100644 index 00000000..4e16e4d3 --- /dev/null +++ b/src/adi/hdl/library/altera/common/alt_ifconv/alt_ifconv_hw.tcl @@ -0,0 +1,34 @@ + +package require qsys + +source ../../../scripts/adi_env.tcl +source $ad_hdl_dir/library/scripts/adi_ip_alt.tcl + +ad_ip_create alt_ifconv {Altera Interface Translator} alt_ifconv_elab +ad_ip_files alt_ifconv { \ + $ad_hdl_dir/library/altera/common/alt_ifconv/alt_ifconv.v \ +} + +# parameters + +ad_ip_parameter DEVICE_FAMILY STRING {Arria 10} +ad_ip_parameter WIDTH INTEGER 1 +ad_ip_parameter INTERFACE_NAME_IN STRING {input-interface-name} +ad_ip_parameter INTERFACE_NAME_OUT STRING {output-interface-name} +ad_ip_parameter SIGNAL_NAME_IN STRING {input-signal-name} +ad_ip_parameter SIGNAL_NAME_OUT STRING {output-signal-name} + +proc alt_ifconv_elab {} { + + set m_width [get_parameter_value "WIDTH"] + set m_if_name_in [get_parameter_value "INTERFACE_NAME_IN"] + set m_if_name_out [get_parameter_value "INTERFACE_NAME_OUT"] + set m_sig_name_in [get_parameter_value "SIGNAL_NAME_IN"] + set m_sig_name_out [get_parameter_value "SIGNAL_NAME_OUT"] + + add_interface $m_if_name_in conduit end + add_interface_port $m_if_name_in din $m_sig_name_in input $m_width + add_interface $m_if_name_out conduit end + add_interface_port $m_if_name_out dout $m_sig_name_out output $m_width +} + diff --git a/src/adi/hdl/library/altera/common/alt_mem_asym/Makefile b/src/adi/hdl/library/altera/common/alt_mem_asym/Makefile new file mode 100644 index 00000000..126d3ada --- /dev/null +++ b/src/adi/hdl/library/altera/common/alt_mem_asym/Makefile @@ -0,0 +1,10 @@ +#################################################################################### +## Copyright 2018(c) Analog Devices, Inc. +## Auto-generated, do not modify! +#################################################################################### + +LIBRARY_NAME := alt_mem_asym + +ALTERA_DEPS += alt_mem_asym_hw.tcl + +include ../../../scripts/library.mk diff --git a/src/adi/hdl/library/altera/common/alt_mem_asym/alt_mem_asym_hw.tcl b/src/adi/hdl/library/altera/common/alt_mem_asym/alt_mem_asym_hw.tcl new file mode 100644 index 00000000..77fe3cb7 --- /dev/null +++ b/src/adi/hdl/library/altera/common/alt_mem_asym/alt_mem_asym_hw.tcl @@ -0,0 +1,49 @@ + +package require qsys + +source ../../../scripts/adi_env.tcl +source $ad_hdl_dir/library/scripts/adi_ip_alt.tcl + +ad_ip_create alt_mem_asym {Altera Asymmetric Memory} +set_module_property COMPOSITION_CALLBACK p_alt_mem_asym + +# parameters + +ad_ip_parameter DEVICE_FAMILY STRING {Arria 10} +ad_ip_parameter A_ADDRESS_WIDTH INTEGER 8 +ad_ip_parameter A_DATA_WIDTH INTEGER 512 +ad_ip_parameter B_ADDRESS_WIDTH INTEGER 8 +ad_ip_parameter B_DATA_WIDTH INTEGER 64 + +# compose + +proc p_alt_mem_asym {} { + + set m_addr_width_a [get_parameter_value "A_ADDRESS_WIDTH"] + set m_data_width_a [get_parameter_value "A_DATA_WIDTH"] + set m_addr_width_b [get_parameter_value "B_ADDRESS_WIDTH"] + set m_data_width_b [get_parameter_value "B_DATA_WIDTH"] + + set m_size [expr ((2**$m_addr_width_a)*$m_data_width_a)] + if {$m_addr_width_a == 0} { + set m_size [expr ((2**$m_addr_width_b)*$m_data_width_b)] + } + + add_instance alt_mem ram_2port + set_instance_parameter_value alt_mem {GUI_MODE} 0 + set_instance_parameter_value alt_mem {GUI_MEM_IN_BITS} 1 + set_instance_parameter_value alt_mem {GUI_MEMSIZE_BITS} $m_size + set_instance_parameter_value alt_mem {GUI_VAR_WIDTH} 1 + set_instance_parameter_value alt_mem {GUI_QA_WIDTH} $m_data_width_a + set_instance_parameter_value alt_mem {GUI_DATAA_WIDTH} $m_data_width_a + set_instance_parameter_value alt_mem {GUI_QB_WIDTH} $m_data_width_b + set_instance_parameter_value alt_mem {GUI_READ_OUTPUT_QB} {false} + set_instance_parameter_value alt_mem {GUI_RAM_BLOCK_TYPE} {M20K} + set_instance_parameter_value alt_mem {GUI_CLOCK_TYPE} 1 + + add_interface mem_i conduit end + add_interface mem_o conduit end + set_interface_property mem_i EXPORT_OF alt_mem.ram_input + set_interface_property mem_o EXPORT_OF alt_mem.ram_output +} + diff --git a/src/adi/hdl/library/altera/common/alt_mul/Makefile b/src/adi/hdl/library/altera/common/alt_mul/Makefile new file mode 100644 index 00000000..c0152d5e --- /dev/null +++ b/src/adi/hdl/library/altera/common/alt_mul/Makefile @@ -0,0 +1,10 @@ +#################################################################################### +## Copyright 2018(c) Analog Devices, Inc. +## Auto-generated, do not modify! +#################################################################################### + +LIBRARY_NAME := alt_mul + +ALTERA_DEPS += alt_mul_hw.tcl + +include ../../../scripts/library.mk diff --git a/src/adi/hdl/library/altera/common/alt_mul/alt_mul_hw.tcl b/src/adi/hdl/library/altera/common/alt_mul/alt_mul_hw.tcl new file mode 100644 index 00000000..11428e32 --- /dev/null +++ b/src/adi/hdl/library/altera/common/alt_mul/alt_mul_hw.tcl @@ -0,0 +1,35 @@ + +package require qsys + +source ../../../scripts/adi_env.tcl +source $ad_hdl_dir/library/scripts/adi_ip_alt.tcl + +ad_ip_create alt_mul {Altera LPM Multiplier} +set_module_property COMPOSITION_CALLBACK p_alt_mul + +# parameters + +ad_ip_parameter DEVICE_FAMILY STRING {Arria 10} + +# compose + +proc p_alt_mul {} { + + add_instance alt_mul lpm_mult + set_instance_parameter_value alt_mul {GUI_USE_MULT} {1} + set_instance_parameter_value alt_mul {GUI_WIDTH_A} {17} + set_instance_parameter_value alt_mul {GUI_WIDTH_B} {17} + set_instance_parameter_value alt_mul {GUI_AUTO_SIZE_RESULT} {0} + set_instance_parameter_value alt_mul {GUI_WIDTH_P} {34} + set_instance_parameter_value alt_mul {GUI_B_IS_CONSTANT} {0} + set_instance_parameter_value alt_mul {GUI_SIGNED_MULT} {1} + set_instance_parameter_value alt_mul {GUI_PIPELINE} {1} + set_instance_parameter_value alt_mul {GUI_LATENCY} {3} + set_instance_parameter_value alt_mul {GUI_OPTIMIZE} {1} + + add_interface mult_i conduit end + add_interface mult_o conduit end + set_interface_property mult_i EXPORT_OF alt_mul.mult_input + set_interface_property mult_o EXPORT_OF alt_mul.mult_output +} + diff --git a/src/adi/hdl/library/altera/common/alt_serdes/Makefile b/src/adi/hdl/library/altera/common/alt_serdes/Makefile new file mode 100644 index 00000000..4ba4f424 --- /dev/null +++ b/src/adi/hdl/library/altera/common/alt_serdes/Makefile @@ -0,0 +1,10 @@ +#################################################################################### +## Copyright 2018(c) Analog Devices, Inc. +## Auto-generated, do not modify! +#################################################################################### + +LIBRARY_NAME := alt_serdes + +ALTERA_DEPS += alt_serdes_hw.tcl + +include ../../../scripts/library.mk diff --git a/src/adi/hdl/library/altera/common/alt_serdes/alt_serdes_hw.tcl b/src/adi/hdl/library/altera/common/alt_serdes/alt_serdes_hw.tcl new file mode 100644 index 00000000..bd2e3106 --- /dev/null +++ b/src/adi/hdl/library/altera/common/alt_serdes/alt_serdes_hw.tcl @@ -0,0 +1,132 @@ + +package require qsys + +source ../../../scripts/adi_env.tcl +source $ad_hdl_dir/library/scripts/adi_ip_alt.tcl + +ad_ip_create alt_serdes {Altera SERDES} +set_module_property COMPOSITION_CALLBACK p_alt_serdes + +# parameters + +ad_ip_parameter DEVICE_FAMILY STRING {Arria 10} +ad_ip_parameter MODE STRING "CLK" false +ad_ip_parameter DDR_OR_SDR_N INTEGER 1 false +ad_ip_parameter SERDES_FACTOR INTEGER 8 false +ad_ip_parameter CLKIN_FREQUENCY FLOAT 500.0 false + +set_parameter_property MODE ALLOWED_RANGES {"CLK" "IN" "OUT"} +set_parameter_property DDR_OR_SDR_N ALLOWED_RANGES {0 1} +set_parameter_property SERDES_FACTOR ALLOWED_RANGES {4 8} +set_parameter_property CLKIN_FREQUENCY DISPLAY_UNITS "MHz" + +proc p_alt_serdes {} { + + set m_mode [get_parameter_value "MODE"] + set m_ddr_or_sdr_n [get_parameter_value "DDR_OR_SDR_N"] + set m_serdes_factor [get_parameter_value "SERDES_FACTOR"] + set m_clkin_frequency [get_parameter_value "CLKIN_FREQUENCY"] + + set m_hs_data_rate [expr ($m_clkin_frequency * ($m_ddr_or_sdr_n + 1))] + set m_ls_data_rate [expr ($m_hs_data_rate/$m_serdes_factor)] + + set m_ls_phase 22.5 + set m_ld_phase 315.0 + set m_ld_duty_cycle 12.5 + + if {$m_serdes_factor == 4} { + set m_ls_phase 45 + set m_ld_phase 270.0 + set m_ld_duty_cycle 25.0 + } + + ## arria 10 only + + if {$m_mode == "CLK"} { + add_instance alt_serdes_pll altera_iopll + set_instance_parameter_value alt_serdes_pll {gui_reference_clock_frequency} $m_clkin_frequency + set_instance_parameter_value alt_serdes_pll {gui_use_locked} {1} + set_instance_parameter_value alt_serdes_pll {gui_operation_mode} {lvds} + set_instance_parameter_value alt_serdes_pll {gui_number_of_clocks} {3} + set_instance_parameter_value alt_serdes_pll {gui_en_lvds_ports} {Enable LVDS_CLK/LOADEN 0} + set_instance_parameter_value alt_serdes_pll {gui_en_phout_ports} {true} + set_instance_parameter_value alt_serdes_pll {gui_output_clock_frequency0} $m_hs_data_rate + set_instance_parameter_value alt_serdes_pll {gui_ps_units0} {degrees} + set_instance_parameter_value alt_serdes_pll {gui_phase_shift_deg0} {180.0} + set_instance_parameter_value alt_serdes_pll {gui_output_clock_frequency1} $m_ls_data_rate + set_instance_parameter_value alt_serdes_pll {gui_ps_units1} {degrees} + set_instance_parameter_value alt_serdes_pll {gui_phase_shift_deg1} $m_ld_phase + set_instance_parameter_value alt_serdes_pll {gui_duty_cycle1} $m_ld_duty_cycle + set_instance_parameter_value alt_serdes_pll {gui_output_clock_frequency2} $m_ls_data_rate + set_instance_parameter_value alt_serdes_pll {gui_phase_shift_deg2} $m_ls_phase + set_instance_parameter_value alt_serdes_pll {gui_ps_units2} {degrees} + add_interface rst reset sink + set_interface_property rst EXPORT_OF alt_serdes_pll.reset + add_interface ref_clk clock sink + set_interface_property ref_clk EXPORT_OF alt_serdes_pll.refclk + add_interface locked conduit end + set_interface_property locked EXPORT_OF alt_serdes_pll.locked + add_interface hs_phase conduit end + set_interface_property hs_phase EXPORT_OF alt_serdes_pll.phout + add_interface hs_clk conduit end + set_interface_property hs_clk EXPORT_OF alt_serdes_pll.lvds_clk + add_interface loaden conduit end + set_interface_property loaden EXPORT_OF alt_serdes_pll.loaden + add_interface ls_clk clock source + set_interface_property ls_clk EXPORT_OF alt_serdes_pll.outclk2 + return + } + + if {$m_mode == "IN"} { + add_instance alt_serdes_in altera_lvds + set_instance_parameter_value alt_serdes_in {MODE} {RX_DPA-FIFO} + set_instance_parameter_value alt_serdes_in {NUM_CHANNELS} {1} + set_instance_parameter_value alt_serdes_in {DATA_RATE} $m_hs_data_rate + set_instance_parameter_value alt_serdes_in {J_FACTOR} $m_serdes_factor + set_instance_parameter_value alt_serdes_in {USE_EXTERNAL_PLL} {true} + set_instance_parameter_value alt_serdes_in {INCLOCK_FREQUENCY} $m_clkin_frequency + set_instance_parameter_value alt_serdes_in {PLL_USE_RESET} {false} + add_interface data_in conduit end + set_interface_property data_in EXPORT_OF alt_serdes_in.rx_in + add_interface clk conduit end + set_interface_property clk EXPORT_OF alt_serdes_in.ext_fclk + add_interface loaden conduit end + set_interface_property loaden EXPORT_OF alt_serdes_in.ext_loaden + add_interface div_clk conduit end + set_interface_property div_clk EXPORT_OF alt_serdes_in.ext_coreclock + add_interface hs_phase conduit end + set_interface_property hs_phase EXPORT_OF alt_serdes_in.ext_vcoph + add_interface locked conduit end + set_interface_property locked EXPORT_OF alt_serdes_in.ext_pll_locked + add_interface data_s conduit end + set_interface_property data_s EXPORT_OF alt_serdes_in.rx_out + add_interface delay_locked conduit end + set_interface_property delay_locked EXPORT_OF alt_serdes_in.rx_dpa_locked + return + } + + if {$m_mode == "OUT"} { + add_instance alt_serdes_out altera_lvds + set_instance_parameter_value alt_serdes_out {MODE} {TX} + set_instance_parameter_value alt_serdes_out {NUM_CHANNELS} {1} + set_instance_parameter_value alt_serdes_out {DATA_RATE} $m_hs_data_rate + set_instance_parameter_value alt_serdes_out {J_FACTOR} $m_serdes_factor + set_instance_parameter_value alt_serdes_out {TX_EXPORT_CORECLOCK} {false} + set_instance_parameter_value alt_serdes_out {TX_USE_OUTCLOCK} {false} + set_instance_parameter_value alt_serdes_out {USE_EXTERNAL_PLL} {true} + set_instance_parameter_value alt_serdes_out {INCLOCK_FREQUENCY} $m_clkin_frequency + set_instance_parameter_value alt_serdes_out {PLL_USE_RESET} {false} + add_interface data_out conduit end + set_interface_property data_out EXPORT_OF alt_serdes_out.tx_out + add_interface clk conduit end + set_interface_property clk EXPORT_OF alt_serdes_out.ext_fclk + add_interface loaden conduit end + set_interface_property loaden EXPORT_OF alt_serdes_out.ext_loaden + add_interface div_clk conduit end + set_interface_property div_clk EXPORT_OF alt_serdes_out.ext_coreclock + add_interface data_s conduit end + set_interface_property data_s EXPORT_OF alt_serdes_out.tx_in + return + } +} + diff --git a/src/adi/hdl/library/altera/common/up_clock_mon_constr.sdc b/src/adi/hdl/library/altera/common/up_clock_mon_constr.sdc new file mode 100644 index 00000000..b01a9f28 --- /dev/null +++ b/src/adi/hdl/library/altera/common/up_clock_mon_constr.sdc @@ -0,0 +1,4 @@ + +set_false_path -from [get_registers *up_clock_mon:i_clock_mon|d_count_run_m3*] -to [get_registers *up_clock_mon:i_clock_mon|up_count_running_m1*] +set_false_path -from [get_registers *up_clock_mon:i_clock_mon|up_count_run*] -to [get_registers *up_clock_mon:i_clock_mon|d_count_run_m1*] +set_false_path -from [get_registers *up_clock_mon:i_clock_mon|d_count*] -to [get_registers *up_clock_mon:i_clock_mon|up_d_count*] diff --git a/src/adi/hdl/library/altera/common/up_rst_constr.sdc b/src/adi/hdl/library/altera/common/up_rst_constr.sdc new file mode 100644 index 00000000..95fe2ad9 --- /dev/null +++ b/src/adi/hdl/library/altera/common/up_rst_constr.sdc @@ -0,0 +1,4 @@ + +set_false_path -to [get_pins -hierarchical -nocase rst_async_d*|CLRN] +set_false_path -to [get_pins -hierarchical -nocase rst_sync|CLRN] + diff --git a/src/adi/hdl/library/altera/common/up_xfer_cntrl_constr.sdc b/src/adi/hdl/library/altera/common/up_xfer_cntrl_constr.sdc new file mode 100644 index 00000000..0b4c0ba7 --- /dev/null +++ b/src/adi/hdl/library/altera/common/up_xfer_cntrl_constr.sdc @@ -0,0 +1,4 @@ + +set_false_path -from [get_registers *up_xfer_cntrl:i_xfer_cntrl|d_xfer_toggle*] -to [get_registers *up_xfer_cntrl:i_xfer_cntrl|up_xfer_state_m1*] +set_false_path -from [get_registers *up_xfer_cntrl:i_xfer_cntrl|up_xfer_toggle*] -to [get_registers *up_xfer_cntrl:i_xfer_cntrl|d_xfer_toggle_m1*] +set_false_path -from [get_registers *up_xfer_cntrl:i_xfer_cntrl|up_xfer_data*] -to [get_registers *up_xfer_cntrl:i_xfer_cntrl|d_data_cntrl*] diff --git a/src/adi/hdl/library/altera/common/up_xfer_status_constr.sdc b/src/adi/hdl/library/altera/common/up_xfer_status_constr.sdc new file mode 100644 index 00000000..432525b0 --- /dev/null +++ b/src/adi/hdl/library/altera/common/up_xfer_status_constr.sdc @@ -0,0 +1,4 @@ + +set_false_path -from [get_registers *up_xfer_status:i_xfer_status|up_xfer_toggle*] -to [get_registers *up_xfer_status:i_xfer_status|d_xfer_state_m1*] +set_false_path -from [get_registers *up_xfer_status:i_xfer_status|d_xfer_toggle*] -to [get_registers *up_xfer_status:i_xfer_status|up_xfer_toggle_m1*] +set_false_path -from [get_registers *up_xfer_status:i_xfer_status|d_xfer_data*] -to [get_registers *up_xfer_status:i_xfer_status|up_data_status*] diff --git a/src/adi/hdl/library/axi_clkgen/Makefile b/src/adi/hdl/library/axi_clkgen/Makefile new file mode 100644 index 00000000..041c35f4 --- /dev/null +++ b/src/adi/hdl/library/axi_clkgen/Makefile @@ -0,0 +1,17 @@ +#################################################################################### +## Copyright 2018(c) Analog Devices, Inc. +## Auto-generated, do not modify! +#################################################################################### + +LIBRARY_NAME := axi_clkgen + +GENERIC_DEPS += ../common/ad_rst.v +GENERIC_DEPS += ../common/up_axi.v +GENERIC_DEPS += ../common/up_clkgen.v +GENERIC_DEPS += axi_clkgen.v + +XILINX_DEPS += ../xilinx/common/ad_mmcm_drp.v +XILINX_DEPS += axi_clkgen_ip.tcl +XILINX_DEPS += bd/bd.tcl + +include ../scripts/library.mk diff --git a/src/adi/hdl/library/axi_clkgen/axi_clkgen.v b/src/adi/hdl/library/axi_clkgen/axi_clkgen.v new file mode 100644 index 00000000..582495e7 --- /dev/null +++ b/src/adi/hdl/library/axi_clkgen/axi_clkgen.v @@ -0,0 +1,215 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright 2014 - 2017 (c) Analog Devices, Inc. All rights reserved. +// +// In this HDL repository, there are many different and unique modules, consisting +// of various HDL (Verilog or VHDL) components. The individual modules are +// developed independently, and may be accompanied by separate and unique license +// terms. +// +// The user should read each of these license terms, and understand the +// freedoms and responsibilities that he or she has by using this source/core. +// +// This core 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. +// +// Redistribution and use of source or resulting binaries, with or without modification +// of this file, are permitted under one of the following two license terms: +// +// 1. The GNU General Public License version 2 as published by the +// Free Software Foundation, which can be found in the top level directory +// of this repository (LICENSE_GPL2), and also online at: +// +// +// OR +// +// 2. An ADI specific BSD license, which can be found in the top level directory +// of this repository (LICENSE_ADIBSD), and also on-line at: +// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD +// This will allow to generate bit files and not release the source code, +// as long as it attaches to an ADI device. +// +// *************************************************************************** +// *************************************************************************** +// software programmable clock generator (still needs a reference input!) + +`timescale 1ns/100ps + +module axi_clkgen #( + + parameter ID = 0, + parameter DEVICE_TYPE = 0, + parameter CLKSEL_EN = 0, + parameter real CLKIN_PERIOD = 5.000, + parameter real CLKIN2_PERIOD = 5.000, + parameter integer VCO_DIV = 11, + parameter real VCO_MUL = 49.000, + parameter real CLK0_DIV = 6.000, + parameter real CLK0_PHASE = 0.000, + parameter integer CLK1_DIV = 6, + parameter real CLK1_PHASE = 0.000) ( + + // clocks + + input clk, + input clk2, + output clk_0, + output clk_1, + + // axi interface + + input s_axi_aclk, + input s_axi_aresetn, + input s_axi_awvalid, + input [15:0] s_axi_awaddr, + output s_axi_awready, + input s_axi_wvalid, + input [31:0] s_axi_wdata, + input [ 3:0] s_axi_wstrb, + output s_axi_wready, + output s_axi_bvalid, + output [ 1:0] s_axi_bresp, + input s_axi_bready, + input s_axi_arvalid, + input [15:0] s_axi_araddr, + output s_axi_arready, + output s_axi_rvalid, + output [31:0] s_axi_rdata, + output [ 1:0] s_axi_rresp, + input s_axi_rready, + input [ 2:0] s_axi_awprot, + input [ 2:0] s_axi_arprot); + + + // reset and clocks + + wire mmcm_rst; + wire clk_sel_s; + wire up_clk_sel_s; + wire up_rstn; + wire up_clk; + + // internal signals + + wire up_drp_sel_s; + wire up_drp_wr_s; + wire [11:0] up_drp_addr_s; + wire [15:0] up_drp_wdata_s; + wire [15:0] up_drp_rdata_s; + wire up_drp_ready_s; + wire up_drp_locked_s; + wire up_wreq_s; + wire [13:0] up_waddr_s; + wire [31:0] up_wdata_s; + wire up_wack_s; + wire up_rreq_s; + wire [13:0] up_raddr_s; + wire [31:0] up_rdata_s; + wire up_rack_s; + + // signal name changes + + assign up_clk = s_axi_aclk; + assign up_rstn = s_axi_aresetn; + + // up bus interface + + up_axi i_up_axi ( + .up_rstn (up_rstn), + .up_clk (up_clk), + .up_axi_awvalid (s_axi_awvalid), + .up_axi_awaddr (s_axi_awaddr), + .up_axi_awready (s_axi_awready), + .up_axi_wvalid (s_axi_wvalid), + .up_axi_wdata (s_axi_wdata), + .up_axi_wstrb (s_axi_wstrb), + .up_axi_wready (s_axi_wready), + .up_axi_bvalid (s_axi_bvalid), + .up_axi_bresp (s_axi_bresp), + .up_axi_bready (s_axi_bready), + .up_axi_arvalid (s_axi_arvalid), + .up_axi_araddr (s_axi_araddr), + .up_axi_arready (s_axi_arready), + .up_axi_rvalid (s_axi_rvalid), + .up_axi_rresp (s_axi_rresp), + .up_axi_rdata (s_axi_rdata), + .up_axi_rready (s_axi_rready), + .up_wreq (up_wreq_s), + .up_waddr (up_waddr_s), + .up_wdata (up_wdata_s), + .up_wack (up_wack_s), + .up_rreq (up_rreq_s), + .up_raddr (up_raddr_s), + .up_rdata (up_rdata_s), + .up_rack (up_rack_s)); + + // processor interface + + up_clkgen #( + .ID(ID) + ) i_up_clkgen ( + .mmcm_rst (mmcm_rst), + .clk_sel (up_clk_sel_s), + .up_drp_sel (up_drp_sel_s), + .up_drp_wr (up_drp_wr_s), + .up_drp_addr (up_drp_addr_s), + .up_drp_wdata (up_drp_wdata_s), + .up_drp_rdata (up_drp_rdata_s), + .up_drp_ready (up_drp_ready_s), + .up_drp_locked (up_drp_locked_s), + .up_rstn (up_rstn), + .up_clk (up_clk), + .up_wreq (up_wreq_s), + .up_waddr (up_waddr_s), + .up_wdata (up_wdata_s), + .up_wack (up_wack_s), + .up_rreq (up_rreq_s), + .up_raddr (up_raddr_s), + .up_rdata (up_rdata_s), + .up_rack (up_rack_s)); + + // If CLKSEL_EN is not active, the clk0 port of the MMCM is used, this + // should be used when the MMCM has only one active clock source + + generate if (CLKSEL_EN == 1) begin + assign clk_sel_s = up_clk_sel_s; + end else begin + assign clk_sel_s = 1'b1; + end + endgenerate + + // mmcm instantiations + + ad_mmcm_drp #( + .MMCM_DEVICE_TYPE (DEVICE_TYPE), + .MMCM_CLKIN_PERIOD (CLKIN_PERIOD), + .MMCM_CLKIN2_PERIOD (CLKIN2_PERIOD), + .MMCM_VCO_DIV (VCO_DIV), + .MMCM_VCO_MUL (VCO_MUL), + .MMCM_CLK0_DIV (CLK0_DIV), + .MMCM_CLK0_PHASE (CLK0_PHASE), + .MMCM_CLK1_DIV (CLK1_DIV), + .MMCM_CLK1_PHASE (CLK1_PHASE)) + i_mmcm_drp ( + .clk (clk), + .clk2 (clk2), + .clk_sel(clk_sel_s), + .mmcm_rst (mmcm_rst), + .mmcm_clk_0 (clk_0), + .mmcm_clk_1 (clk_1), + .mmcm_clk_2 (), + .up_clk (up_clk), + .up_rstn (up_rstn), + .up_drp_sel (up_drp_sel_s), + .up_drp_wr (up_drp_wr_s), + .up_drp_addr (up_drp_addr_s), + .up_drp_wdata (up_drp_wdata_s), + .up_drp_rdata (up_drp_rdata_s), + .up_drp_ready (up_drp_ready_s), + .up_drp_locked (up_drp_locked_s)); + +endmodule + +// *************************************************************************** +// *************************************************************************** diff --git a/src/adi/hdl/library/axi_clkgen/axi_clkgen_ip.tcl b/src/adi/hdl/library/axi_clkgen/axi_clkgen_ip.tcl new file mode 100644 index 00000000..f6ab698f --- /dev/null +++ b/src/adi/hdl/library/axi_clkgen/axi_clkgen_ip.tcl @@ -0,0 +1,52 @@ +# ip + +source ../scripts/adi_env.tcl +source $ad_hdl_dir/library/scripts/adi_ip.tcl + +adi_ip_create axi_clkgen +adi_ip_files axi_clkgen [list \ + "$ad_hdl_dir/library/common/ad_rst.v" \ + "$ad_hdl_dir/library/xilinx/common/ad_mmcm_drp.v" \ + "$ad_hdl_dir/library/common/up_axi.v" \ + "$ad_hdl_dir/library/common/up_clkgen.v" \ + "bd/bd.tcl" \ + "axi_clkgen.v" ] + +adi_ip_properties axi_clkgen +adi_ip_bd axi_clkgen "bd/bd.tcl" + +ipx::infer_bus_interface clk xilinx.com:signal:clock_rtl:1.0 [ipx::current_core] +ipx::infer_bus_interface clk2 xilinx.com:signal:clock_rtl:1.0 [ipx::current_core] +ipx::infer_bus_interface clk_0 xilinx.com:signal:clock_rtl:1.0 [ipx::current_core] +ipx::infer_bus_interface clk_1 xilinx.com:signal:clock_rtl:1.0 [ipx::current_core] + +set cc [ipx::current_core] +set page0 [ipgui::get_pagespec -name "Page 0" -component $cc] + +set param [ipx::add_user_parameter ENABLE_CLKIN2 $cc] +set_property -dict {value_resolve_type user value_format bool value false} $param + +set param [ipgui::add_param -name {ENABLE_CLKIN2} -component $cc -parent $page0] +set_property -dict [list \ + display_name {Enable secondary clock input} \ + widget {checkBox} \ +] $param + +set param [ipx::add_user_parameter ENABLE_CLKOUT1 $cc] +set_property -dict {value_resolve_type user value_format bool value false} $param + +set param [ipgui::add_param -name {ENABLE_CLKOUT1} -component $cc -parent $page0] +set_property -dict [list \ + display_name {Enable secondary clock output} \ + widget {checkBox} \ +] $param + +set_property enablement_tcl_expr {$ENABLE_CLKIN2} [ipx::get_user_parameters CLKIN2_PERIOD -of_objects $cc] +set_property enablement_tcl_expr {$ENABLE_CLKOUT1} [ipx::get_user_parameters CLK1_DIV -of_objects $cc] +set_property enablement_tcl_expr {$ENABLE_CLKOUT1} [ipx::get_user_parameters CLK1_PHASE -of_objects $cc] + +adi_set_ports_dependency clk2 ENABLE_CLKIN2 0 +adi_set_ports_dependency clk_1 ENABLE_CLKOUT1 + +ipx::create_xgui_files $cc +ipx::save_core $cc diff --git a/src/adi/hdl/library/axi_clkgen/bd/bd.tcl b/src/adi/hdl/library/axi_clkgen/bd/bd.tcl new file mode 100644 index 00000000..4e92dab3 --- /dev/null +++ b/src/adi/hdl/library/axi_clkgen/bd/bd.tcl @@ -0,0 +1,75 @@ +proc init {cellpath otherInfo} { + set ip [get_bd_cells $cellpath] + + bd::mark_propagate_override $ip \ + "CLKIN_PERIOD CLKIN2_PERIOD" +} + +proc axi_clkgen_get_infer_period {ip param clk_name} { + set param_src [get_property "CONFIG.$param.VALUE_SRC" $ip] + if {[string equal $param_src "USER"]} { + return; + } + + set clk [get_bd_pins "$ip/$clk_name"] + set clk_freq [get_property CONFIG.FREQ_HZ $clk] + + if {$clk_freq != {}} { + set clk_period [expr 1000000000.0 / $clk_freq] + set_property "CONFIG.$param" [format "%.6f" $clk_period] $ip + } +} + +proc propagate {cellpath otherinfo} { + set ip [get_bd_cells $cellpath] + + set vco_mul [get_property CONFIG.VCO_MUL $ip] + set vco_div [get_property CONFIG.VCO_DIV $ip] + set clk0_div [get_property CONFIG.CLK0_DIV $ip] + set clk1_div [get_property CONFIG.CLK1_DIV $ip] + + if {$vco_mul == {} || $vco_mul < 1} { + set vco_mul 1 + } + if {$vco_div == {} || $vco_div < 1} { + set vco_div 1 + } + if {$clk0_div == {} || $clk0_div < 1} { + set clk0_div 1 + } + if {$clk1_div == {} || $clk0_div < 1} { + set clk1_div 1 + } + + set clk [get_bd_pins "$ip/clk"] + set clk_freq [get_property CONFIG.FREQ_HZ $clk] + if {[get_property "CONFIG.ENABLE_CLKIN2" $ip] == "true"} { + set clk2 [get_bd_pins "$ip/clk"] + set clk2_freq [get_property CONFIG.FREQ_HZ $clk2] + # Use the larger of the two + if {$clk_freq == {} || $clk2_freq > $clk_freq} { + set clk_freq $clk2_freq + } + } + + if {$clk_freq != {}} { + set clk0_out [get_bd_pins "$ip/clk_0"] + set clk0_out_freq [expr ($clk_freq + 0.0) * $vco_mul / ($vco_div * $clk0_div)] + set_property CONFIG.FREQ_HZ $clk0_out_freq $clk0_out + + if {[get_property "CONFIG.ENABLE_CLKOUT1" $ip] == "true"} { + set clk0_out [get_bd_pins "$ip/clk_1"] + set clk1_out_freq [expr ($clk_freq + 0.0) * $vco_mul / ($vco_div * $clk1_div)] + set_property CONFIG.FREQ_HZ $clk1_out_freq $clk1_out + } + } +} + +proc post_propagate {cellpath otherinfo} { + set ip [get_bd_cells $cellpath] + + axi_clkgen_get_infer_period $ip CLKIN_PERIOD clk + if {[get_property "CONFIG.ENABLE_CLKIN2" $ip] == "true"} { + axi_clkgen_get_infer_period $ip CLKIN2_PERIOD clk2 + } +} diff --git a/src/adi/hdl/library/axi_dmac/2d_transfer.v b/src/adi/hdl/library/axi_dmac/2d_transfer.v new file mode 100644 index 00000000..69ac6d0c --- /dev/null +++ b/src/adi/hdl/library/axi_dmac/2d_transfer.v @@ -0,0 +1,193 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright 2014 - 2017 (c) Analog Devices, Inc. All rights reserved. +// +// In this HDL repository, there are many different and unique modules, consisting +// of various HDL (Verilog or VHDL) components. The individual modules are +// developed independently, and may be accompanied by separate and unique license +// terms. +// +// The user should read each of these license terms, and understand the +// freedoms and responsibilities that he or she has by using this source/core. +// +// This core 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. +// +// Redistribution and use of source or resulting binaries, with or without modification +// of this file, are permitted under one of the following two license terms: +// +// 1. The GNU General Public License version 2 as published by the +// Free Software Foundation, which can be found in the top level directory +// of this repository (LICENSE_GPL2), and also online at: +// +// +// OR +// +// 2. An ADI specific BSD license, which can be found in the top level directory +// of this repository (LICENSE_ADIBSD), and also on-line at: +// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD +// This will allow to generate bit files and not release the source code, +// as long as it attaches to an ADI device. +// +// *************************************************************************** +// *************************************************************************** + +`timescale 1ns/100ps + +module dmac_2d_transfer #( + + parameter DMA_AXI_ADDR_WIDTH = 32, + parameter DMA_LENGTH_WIDTH = 24, + parameter BYTES_PER_BURST_WIDTH = 7, + parameter BYTES_PER_BEAT_WIDTH_SRC = 3, + parameter BYTES_PER_BEAT_WIDTH_DEST = 3)( + + input req_aclk, + input req_aresetn, + + input req_valid, + output reg req_ready, + + input [DMA_AXI_ADDR_WIDTH-1:BYTES_PER_BEAT_WIDTH_DEST] req_dest_address, + input [DMA_AXI_ADDR_WIDTH-1:BYTES_PER_BEAT_WIDTH_SRC] req_src_address, + input [DMA_LENGTH_WIDTH-1:0] req_x_length, + input [DMA_LENGTH_WIDTH-1:0] req_y_length, + input [DMA_LENGTH_WIDTH-1:0] req_dest_stride, + input [DMA_LENGTH_WIDTH-1:0] req_src_stride, + input req_sync_transfer_start, + input req_last, + + output reg req_eot, + output reg [BYTES_PER_BURST_WIDTH-1:0] req_measured_burst_length, + output reg req_response_partial, + output reg req_response_valid, + input req_response_ready, + + input out_abort_req, + + output reg out_req_valid, + input out_req_ready, + output [DMA_AXI_ADDR_WIDTH-1:BYTES_PER_BEAT_WIDTH_DEST] out_req_dest_address, + output [DMA_AXI_ADDR_WIDTH-1:BYTES_PER_BEAT_WIDTH_SRC] out_req_src_address, + output [DMA_LENGTH_WIDTH-1:0] out_req_length, + output reg out_req_sync_transfer_start, + output out_req_last, + + input out_eot, + input [BYTES_PER_BURST_WIDTH-1:0] out_measured_burst_length, + input out_response_partial, + input out_response_valid, + output reg out_response_ready = 1'b1 + +); + +reg [DMA_AXI_ADDR_WIDTH-1:BYTES_PER_BEAT_WIDTH_DEST] dest_address = 'h00; +reg [DMA_AXI_ADDR_WIDTH-1:BYTES_PER_BEAT_WIDTH_SRC] src_address = 'h00; +reg [DMA_LENGTH_WIDTH-1:0] x_length = 'h00; +reg [DMA_LENGTH_WIDTH-1:0] y_length = 'h00; +reg [DMA_LENGTH_WIDTH-1:0] dest_stride = 'h0; +reg [DMA_LENGTH_WIDTH-1:0] src_stride = 'h00; + +reg gen_last = 'h0; + +reg [1:0] req_id = 'h00; +reg [1:0] eot_id = 'h00; +reg [3:0] last_req = 'h00; + +wire out_last; + +assign out_req_dest_address = dest_address; +assign out_req_src_address = src_address; +assign out_req_length = x_length; +assign out_last = y_length == 'h00; + +always @(posedge req_aclk) begin + if (req_aresetn == 1'b0) begin + req_id <= 2'b0; + eot_id <= 2'b0; + req_eot <= 1'b0; + end else begin + if (out_req_valid == 1'b1 && out_req_ready == 1'b1) begin + req_id <= req_id + 1'b1; + end + + if (out_eot == 1'b1 && out_response_valid == 1'b1 && out_response_ready == 1'b1) begin + eot_id <= eot_id + 1'b1; + req_eot <= last_req[eot_id]; + end else begin + req_eot <= 1'b0; + end + end +end + +always @(posedge req_aclk) begin + if (out_req_valid == 1'b1 && out_req_ready == 1'b1) begin + last_req[req_id] <= out_last; + end +end + +always @(posedge req_aclk) begin + if (out_response_valid == 1'b1 && out_response_ready == 1'b1) begin + req_measured_burst_length <= out_measured_burst_length; + req_response_partial <= out_response_partial; + end +end + +always @(posedge req_aclk) begin + if (out_response_valid == 1'b1 && out_response_ready == 1'b1) begin + req_response_valid <= 1'b1; + end else if (req_response_ready == 1'b1) begin + req_response_valid <= 1'b0; + end +end + +always @(posedge req_aclk) begin + if (req_aresetn == 1'b0) begin + out_response_ready <= 1'b1; + end else if (out_response_ready == 1'b1) begin + out_response_ready <= ~out_response_valid; + end else if (req_response_ready == 1'b1) begin + out_response_ready <= 1'b1; + end +end + +always @(posedge req_aclk) begin + if (req_ready == 1'b1 && req_valid == 1'b1) begin + dest_address <= req_dest_address; + src_address <= req_src_address; + x_length <= req_x_length; + y_length <= req_y_length; + dest_stride <= req_dest_stride; + src_stride <= req_src_stride; + out_req_sync_transfer_start <= req_sync_transfer_start; + gen_last <= req_last; + end else if (out_abort_req == 1'b1) begin + y_length <= 0; + end else if (out_req_valid == 1'b1 && out_req_ready == 1'b1) begin + dest_address <= dest_address + dest_stride[DMA_LENGTH_WIDTH-1:BYTES_PER_BEAT_WIDTH_DEST]; + src_address <= src_address + src_stride[DMA_LENGTH_WIDTH-1:BYTES_PER_BEAT_WIDTH_SRC]; + y_length <= y_length - 1'b1; + out_req_sync_transfer_start <= 1'b0; + end +end + +always @(posedge req_aclk) begin + if (req_aresetn == 1'b0) begin + req_ready <= 1'b1; + out_req_valid <= 1'b0; + end else begin + if (req_ready == 1'b1 && req_valid == 1'b1) begin + req_ready <= 1'b0; + out_req_valid <= 1'b1; + end else if (out_req_valid == 1'b1 && out_req_ready == 1'b1 && + out_last == 1'b1) begin + out_req_valid <= 1'b0; + req_ready <= 1'b1; + end + end +end + +assign out_req_last = out_last & gen_last; + +endmodule diff --git a/src/adi/hdl/library/axi_dmac/Makefile b/src/adi/hdl/library/axi_dmac/Makefile new file mode 100644 index 00000000..61d74ffe --- /dev/null +++ b/src/adi/hdl/library/axi_dmac/Makefile @@ -0,0 +1,56 @@ +#################################################################################### +## Copyright 2018(c) Analog Devices, Inc. +## Auto-generated, do not modify! +#################################################################################### + +LIBRARY_NAME := axi_dmac + +GENERIC_DEPS += ../common/ad_mem.v +GENERIC_DEPS += ../common/up_axi.v +GENERIC_DEPS += 2d_transfer.v +GENERIC_DEPS += address_generator.v +GENERIC_DEPS += axi_dmac.v +GENERIC_DEPS += axi_dmac_burst_memory.v +GENERIC_DEPS += axi_dmac_regmap.v +GENERIC_DEPS += axi_dmac_regmap_request.v +GENERIC_DEPS += axi_dmac_reset_manager.v +GENERIC_DEPS += axi_dmac_resize_dest.v +GENERIC_DEPS += axi_dmac_resize_src.v +GENERIC_DEPS += axi_dmac_response_manager.v +GENERIC_DEPS += axi_dmac_transfer.v +GENERIC_DEPS += axi_register_slice.v +GENERIC_DEPS += data_mover.v +GENERIC_DEPS += dest_axi_mm.v +GENERIC_DEPS += dest_axi_stream.v +GENERIC_DEPS += dest_fifo_inf.v +GENERIC_DEPS += inc_id.vh +GENERIC_DEPS += request_arb.v +GENERIC_DEPS += request_generator.v +GENERIC_DEPS += resp.vh +GENERIC_DEPS += response_generator.v +GENERIC_DEPS += response_handler.v +GENERIC_DEPS += splitter.v +GENERIC_DEPS += src_axi_mm.v +GENERIC_DEPS += src_axi_stream.v +GENERIC_DEPS += src_fifo_inf.v + +XILINX_DEPS += axi_dmac_constr.ttcl +XILINX_DEPS += axi_dmac_ip.tcl +XILINX_DEPS += bd/bd.tcl + +XILINX_DEPS += ../interfaces/fifo_rd.xml +XILINX_DEPS += ../interfaces/fifo_rd_rtl.xml +XILINX_DEPS += ../interfaces/fifo_wr.xml +XILINX_DEPS += ../interfaces/fifo_wr_rtl.xml + +XILINX_LIB_DEPS += util_axis_fifo +XILINX_LIB_DEPS += util_cdc + +ALTERA_DEPS += ../util_axis_fifo/util_axis_fifo.v +ALTERA_DEPS += ../util_axis_fifo/address_sync.v +ALTERA_DEPS += ../util_cdc/sync_bits.v +ALTERA_DEPS += ../util_cdc/sync_event.v +ALTERA_DEPS += axi_dmac_constr.sdc +ALTERA_DEPS += axi_dmac_hw.tcl + +include ../scripts/library.mk diff --git a/src/adi/hdl/library/axi_dmac/address_generator.v b/src/adi/hdl/library/axi_dmac/address_generator.v new file mode 100644 index 00000000..49966757 --- /dev/null +++ b/src/adi/hdl/library/axi_dmac/address_generator.v @@ -0,0 +1,184 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright 2014 - 2017 (c) Analog Devices, Inc. All rights reserved. +// +// In this HDL repository, there are many different and unique modules, consisting +// of various HDL (Verilog or VHDL) components. The individual modules are +// developed independently, and may be accompanied by separate and unique license +// terms. +// +// The user should read each of these license terms, and understand the +// freedoms and responsibilities that he or she has by using this source/core. +// +// This core 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. +// +// Redistribution and use of source or resulting binaries, with or without modification +// of this file, are permitted under one of the following two license terms: +// +// 1. The GNU General Public License version 2 as published by the +// Free Software Foundation, which can be found in the top level directory +// of this repository (LICENSE_GPL2), and also online at: +// +// +// OR +// +// 2. An ADI specific BSD license, which can be found in the top level directory +// of this repository (LICENSE_ADIBSD), and also on-line at: +// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD +// This will allow to generate bit files and not release the source code, +// as long as it attaches to an ADI device. +// +// *************************************************************************** +// *************************************************************************** + +`timescale 1ns/100ps + +module dmac_address_generator #( + + parameter ID_WIDTH = 3, + parameter DMA_DATA_WIDTH = 64, + parameter DMA_ADDR_WIDTH = 32, + parameter BEATS_PER_BURST_WIDTH = 4, + parameter BYTES_PER_BEAT_WIDTH = $clog2(DMA_DATA_WIDTH/8), + parameter LENGTH_WIDTH = 8)( + + input clk, + input resetn, + + input req_valid, + output reg req_ready, + input [DMA_ADDR_WIDTH-1:BYTES_PER_BEAT_WIDTH] req_address, + + output reg [ID_WIDTH-1:0] id, + input [ID_WIDTH-1:0] request_id, + + input bl_valid, + output reg bl_ready, + input [BEATS_PER_BURST_WIDTH-1:0] measured_last_burst_length, + + input eot, + + input enable, + output reg enabled, + + input addr_ready, + output reg addr_valid, + output [DMA_ADDR_WIDTH-1:0] addr, + output [LENGTH_WIDTH-1:0] len, + output [ 2:0] size, + output [ 1:0] burst, + output [ 2:0] prot, + output [ 3:0] cache +); + +localparam MAX_BEATS_PER_BURST = {1'b1,{BEATS_PER_BURST_WIDTH{1'b0}}}; +localparam MAX_LENGTH = {BEATS_PER_BURST_WIDTH{1'b1}}; + +`include "inc_id.vh" + +assign burst = 2'b01; +assign prot = 3'b000; +assign cache = 4'b0011; +assign size = DMA_DATA_WIDTH == 1024 ? 3'b111 : + DMA_DATA_WIDTH == 512 ? 3'b110 : + DMA_DATA_WIDTH == 256 ? 3'b101 : + DMA_DATA_WIDTH == 128 ? 3'b100 : + DMA_DATA_WIDTH == 64 ? 3'b011 : + DMA_DATA_WIDTH == 32 ? 3'b010 : + DMA_DATA_WIDTH == 16 ? 3'b001 : 3'b000; + +reg [LENGTH_WIDTH-1:0] length = 'h0; +reg [DMA_ADDR_WIDTH-BYTES_PER_BEAT_WIDTH-1:0] address = 'h00; +reg [BEATS_PER_BURST_WIDTH-1:0] last_burst_len = 'h00; +assign addr = {address, {BYTES_PER_BEAT_WIDTH{1'b0}}}; +assign len = length; + +reg addr_valid_d1; +reg last = 1'b0; + +// If we already asserted addr_valid we have to wait until it is accepted before +// we can disable the address generator. +always @(posedge clk) begin + if (resetn == 1'b0) begin + enabled <= 1'b0; + end else if (enable == 1'b1) begin + enabled <= 1'b1; + end else if (addr_valid == 1'b0) begin + enabled <= 1'b0; + end +end + +always @(posedge clk) begin + if (bl_valid == 1'b1 && bl_ready == 1'b1) begin + last_burst_len <= measured_last_burst_length; + end +end + +always @(posedge clk) begin + if (addr_valid == 1'b0) begin + last <= eot; + if (eot == 1'b1) begin + length <= last_burst_len; + end else begin + length <= MAX_LENGTH; + end + end +end + +always @(posedge clk) begin + if (req_ready == 1'b1) begin + address <= req_address; + end else if (addr_valid == 1'b1 && addr_ready == 1'b1) begin + address <= address + MAX_BEATS_PER_BURST; + end +end + +always @(posedge clk) begin + if (resetn == 1'b0) begin + bl_ready <= 1'b1; + end else begin + if (bl_ready == 1'b1) begin + bl_ready <= ~bl_valid; + end else if (addr_valid == 1'b0 && eot == 1'b1) begin + // assert bl_ready only when the addr_valid asserts in the next cycle + if (id != request_id && enable == 1'b1) begin + bl_ready <= 1'b1; + end + end + end +end + +always @(posedge clk) begin + if (resetn == 1'b0) begin + req_ready <= 1'b1; + addr_valid <= 1'b0; + end else begin + if (req_ready == 1'b1) begin + req_ready <= ~req_valid; + end else if (addr_valid == 1'b1 && addr_ready == 1'b1) begin + addr_valid <= 1'b0; + req_ready <= last; + end else if (id != request_id && enable == 1'b1) begin + // if eot wait until the last_burst_len gets synced over + if (eot == 1'b0 || (eot == 1'b1 && bl_ready == 1'b0)) begin + addr_valid <= 1'b1; + end + end + end +end + +always @(posedge clk) begin + addr_valid_d1 <= addr_valid; +end + +always @(posedge clk) begin + if (resetn == 1'b0) begin + id <= 'h0; + end else if (addr_valid == 1'b1 && addr_valid_d1 == 1'b0) begin + id <= inc_id(id); + end +end + +endmodule diff --git a/src/adi/hdl/library/axi_dmac/axi_dmac.v b/src/adi/hdl/library/axi_dmac/axi_dmac.v new file mode 100644 index 00000000..30e3901c --- /dev/null +++ b/src/adi/hdl/library/axi_dmac/axi_dmac.v @@ -0,0 +1,599 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright 2014 - 2017 (c) Analog Devices, Inc. All rights reserved. +// +// In this HDL repository, there are many different and unique modules, consisting +// of various HDL (Verilog or VHDL) components. The individual modules are +// developed independently, and may be accompanied by separate and unique license +// terms. +// +// The user should read each of these license terms, and understand the +// freedoms and responsibilities that he or she has by using this source/core. +// +// This core 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. +// +// Redistribution and use of source or resulting binaries, with or without modification +// of this file, are permitted under one of the following two license terms: +// +// 1. The GNU General Public License version 2 as published by the +// Free Software Foundation, which can be found in the top level directory +// of this repository (LICENSE_GPL2), and also online at: +// +// +// OR +// +// 2. An ADI specific BSD license, which can be found in the top level directory +// of this repository (LICENSE_ADIBSD), and also on-line at: +// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD +// This will allow to generate bit files and not release the source code, +// as long as it attaches to an ADI device. +// +// *************************************************************************** +// *************************************************************************** + +`timescale 1ns/100ps + +module axi_dmac #( + + parameter ID = 0, + parameter DMA_DATA_WIDTH_SRC = 64, + parameter DMA_DATA_WIDTH_DEST = 64, + parameter DMA_LENGTH_WIDTH = 24, + parameter DMA_2D_TRANSFER = 0, + parameter ASYNC_CLK_REQ_SRC = 1, + parameter ASYNC_CLK_SRC_DEST = 1, + parameter ASYNC_CLK_DEST_REQ = 1, + parameter AXI_SLICE_DEST = 0, + parameter AXI_SLICE_SRC = 0, + parameter SYNC_TRANSFER_START = 0, + parameter CYCLIC = 1, + parameter DMA_AXI_PROTOCOL_DEST = 0, + parameter DMA_AXI_PROTOCOL_SRC = 0, + parameter DMA_TYPE_DEST = 0, + parameter DMA_TYPE_SRC = 2, + parameter DMA_AXI_ADDR_WIDTH = 32, + parameter MAX_BYTES_PER_BURST = 128, + parameter FIFO_SIZE = 8, // In bursts + parameter AXI_ID_WIDTH_SRC = 1, + parameter AXI_ID_WIDTH_DEST = 1, + parameter DISABLE_DEBUG_REGISTERS = 0, + parameter ENABLE_DIAGNOSTICS_IF = 0)( + // Slave AXI interface + input s_axi_aclk, + input s_axi_aresetn, + + input s_axi_awvalid, + input [11:0] s_axi_awaddr, + output s_axi_awready, + input [2:0] s_axi_awprot, + input s_axi_wvalid, + input [31:0] s_axi_wdata, + input [ 3:0] s_axi_wstrb, + output s_axi_wready, + output s_axi_bvalid, + output [ 1:0] s_axi_bresp, + input s_axi_bready, + input s_axi_arvalid, + input [11:0] s_axi_araddr, + output s_axi_arready, + input [2:0] s_axi_arprot, + output s_axi_rvalid, + input s_axi_rready, + output [ 1:0] s_axi_rresp, + output [31:0] s_axi_rdata, + + // Interrupt + output irq, + + // Master AXI interface + input m_dest_axi_aclk, + input m_dest_axi_aresetn, + + // Write address + output [DMA_AXI_ADDR_WIDTH-1:0] m_dest_axi_awaddr, + output [7-(4*DMA_AXI_PROTOCOL_DEST):0] m_dest_axi_awlen, + output [ 2:0] m_dest_axi_awsize, + output [ 1:0] m_dest_axi_awburst, + output [ 2:0] m_dest_axi_awprot, + output [ 3:0] m_dest_axi_awcache, + output m_dest_axi_awvalid, + input m_dest_axi_awready, + output [AXI_ID_WIDTH_DEST-1:0] m_dest_axi_awid, + output [DMA_AXI_PROTOCOL_DEST:0] m_dest_axi_awlock, + + // Write data + output [DMA_DATA_WIDTH_DEST-1:0] m_dest_axi_wdata, + output [(DMA_DATA_WIDTH_DEST/8)-1:0] m_dest_axi_wstrb, + input m_dest_axi_wready, + output m_dest_axi_wvalid, + output m_dest_axi_wlast, + output [AXI_ID_WIDTH_DEST-1:0] m_dest_axi_wid, + + // Write response + input m_dest_axi_bvalid, + input [ 1:0] m_dest_axi_bresp, + output m_dest_axi_bready, + input [AXI_ID_WIDTH_DEST-1:0] m_dest_axi_bid, + + // Unused read interface + output m_dest_axi_arvalid, + output [DMA_AXI_ADDR_WIDTH-1:0] m_dest_axi_araddr, + output [7-(4*DMA_AXI_PROTOCOL_DEST):0] m_dest_axi_arlen, + output [ 2:0] m_dest_axi_arsize, + output [ 1:0] m_dest_axi_arburst, + output [ 3:0] m_dest_axi_arcache, + output [ 2:0] m_dest_axi_arprot, + input m_dest_axi_arready, + input m_dest_axi_rvalid, + input [ 1:0] m_dest_axi_rresp, + input [DMA_DATA_WIDTH_DEST-1:0] m_dest_axi_rdata, + output m_dest_axi_rready, + output [AXI_ID_WIDTH_DEST-1:0] m_dest_axi_arid, + output [DMA_AXI_PROTOCOL_DEST:0] m_dest_axi_arlock, + input [AXI_ID_WIDTH_DEST-1:0] m_dest_axi_rid, + input m_dest_axi_rlast, + + // Master AXI interface + input m_src_axi_aclk, + input m_src_axi_aresetn, + + // Read address + input m_src_axi_arready, + output m_src_axi_arvalid, + output [DMA_AXI_ADDR_WIDTH-1:0] m_src_axi_araddr, + output [7-(4*DMA_AXI_PROTOCOL_SRC):0] m_src_axi_arlen, + output [ 2:0] m_src_axi_arsize, + output [ 1:0] m_src_axi_arburst, + output [ 2:0] m_src_axi_arprot, + output [ 3:0] m_src_axi_arcache, + output [AXI_ID_WIDTH_SRC-1:0] m_src_axi_arid, + output [DMA_AXI_PROTOCOL_SRC:0] m_src_axi_arlock, + + // Read data and response + input [DMA_DATA_WIDTH_SRC-1:0] m_src_axi_rdata, + output m_src_axi_rready, + input m_src_axi_rvalid, + input [ 1:0] m_src_axi_rresp, + input [AXI_ID_WIDTH_SRC-1:0] m_src_axi_rid, + input m_src_axi_rlast, + + // Unused write interface + output m_src_axi_awvalid, + output [DMA_AXI_ADDR_WIDTH-1:0] m_src_axi_awaddr, + output [7-(4*DMA_AXI_PROTOCOL_SRC):0] m_src_axi_awlen, + output [ 2:0] m_src_axi_awsize, + output [ 1:0] m_src_axi_awburst, + output [ 3:0] m_src_axi_awcache, + output [ 2:0] m_src_axi_awprot, + input m_src_axi_awready, + output m_src_axi_wvalid, + output [DMA_DATA_WIDTH_SRC-1:0] m_src_axi_wdata, + output [(DMA_DATA_WIDTH_SRC/8)-1:0] m_src_axi_wstrb, + output m_src_axi_wlast, + input m_src_axi_wready, + input m_src_axi_bvalid, + input [ 1:0] m_src_axi_bresp, + output m_src_axi_bready, + output [AXI_ID_WIDTH_SRC-1:0] m_src_axi_awid, + output [DMA_AXI_PROTOCOL_SRC:0] m_src_axi_awlock, + output [AXI_ID_WIDTH_SRC-1:0] m_src_axi_wid, + input [AXI_ID_WIDTH_SRC-1:0] m_src_axi_bid, + + + + // Slave streaming AXI interface + input s_axis_aclk, + output s_axis_ready, + input s_axis_valid, + input [DMA_DATA_WIDTH_SRC-1:0] s_axis_data, + input [0:0] s_axis_user, + input s_axis_last, + output s_axis_xfer_req, + + // Master streaming AXI interface + input m_axis_aclk, + input m_axis_ready, + output m_axis_valid, + output [DMA_DATA_WIDTH_DEST-1:0] m_axis_data, + output m_axis_last, + output m_axis_xfer_req, + + // Input FIFO interface + input fifo_wr_clk, + input fifo_wr_en, + input [DMA_DATA_WIDTH_SRC-1:0] fifo_wr_din, + output fifo_wr_overflow, + input fifo_wr_sync, + output fifo_wr_xfer_req, + + // Input FIFO interface + input fifo_rd_clk, + input fifo_rd_en, + output fifo_rd_valid, + output [DMA_DATA_WIDTH_DEST-1:0] fifo_rd_dout, + output fifo_rd_underflow, + output fifo_rd_xfer_req, + + // Diagnostics interface + output [7:0] dest_diag_level_bursts +); + + +localparam DMA_TYPE_AXI_MM = 0; +localparam DMA_TYPE_AXI_STREAM = 1; +localparam DMA_TYPE_FIFO = 2; + +localparam HAS_DEST_ADDR = DMA_TYPE_DEST == DMA_TYPE_AXI_MM; +localparam HAS_SRC_ADDR = DMA_TYPE_SRC == DMA_TYPE_AXI_MM; + +// Argh... "[Synth 8-2722] system function call clog2 is not allowed here" +localparam BYTES_PER_BEAT_WIDTH_DEST = DMA_DATA_WIDTH_DEST > 1024 ? 8 : + DMA_DATA_WIDTH_DEST > 512 ? 7 : + DMA_DATA_WIDTH_DEST > 256 ? 6 : + DMA_DATA_WIDTH_DEST > 128 ? 5 : + DMA_DATA_WIDTH_DEST > 64 ? 4 : + DMA_DATA_WIDTH_DEST > 32 ? 3 : + DMA_DATA_WIDTH_DEST > 16 ? 2 : + DMA_DATA_WIDTH_DEST > 8 ? 1 : 0; +localparam BYTES_PER_BEAT_WIDTH_SRC = DMA_DATA_WIDTH_SRC > 1024 ? 8 : + DMA_DATA_WIDTH_SRC > 512 ? 7 : + DMA_DATA_WIDTH_SRC > 256 ? 6 : + DMA_DATA_WIDTH_SRC > 128 ? 5 : + DMA_DATA_WIDTH_SRC > 64 ? 4 : + DMA_DATA_WIDTH_SRC > 32 ? 3 : + DMA_DATA_WIDTH_SRC > 16 ? 2 : + DMA_DATA_WIDTH_SRC > 8 ? 1 : 0; +localparam ID_WIDTH = (FIFO_SIZE) > 64 ? 8 : + (FIFO_SIZE) > 32 ? 7 : + (FIFO_SIZE) > 16 ? 6 : + (FIFO_SIZE) > 8 ? 5 : + (FIFO_SIZE) > 4 ? 4 : + (FIFO_SIZE) > 2 ? 3 : + (FIFO_SIZE) > 1 ? 2 : 1; +localparam DBG_ID_PADDING = ID_WIDTH > 8 ? 0 : 8 - ID_WIDTH; + +/* AXI3 supports a maximum of 16 beats per burst. AXI4 supports a maximum of + 256 beats per burst. If either bus is AXI3 set the maximum number of beats + per burst to 16. For non AXI interfaces the maximum beats per burst is in + theory unlimted. Set it to 1024 to provide a reasonable upper threshold */ +localparam BEATS_PER_BURST_LIMIT_DEST = + (DMA_TYPE_DEST == DMA_TYPE_AXI_MM) ? + (DMA_AXI_PROTOCOL_DEST == 1 ? 16 : 256) : + 1024; +localparam BYTES_PER_BURST_LIMIT_DEST = + BEATS_PER_BURST_LIMIT_DEST * DMA_DATA_WIDTH_DEST / 8; +localparam BEATS_PER_BURST_LIMIT_SRC = + (DMA_TYPE_SRC == DMA_TYPE_AXI_MM) ? + (DMA_AXI_PROTOCOL_SRC == 1 ? 16 : 256) : + 1024; +localparam BYTES_PER_BURST_LIMIT_SRC = + BEATS_PER_BURST_LIMIT_SRC * DMA_DATA_WIDTH_SRC / 8; + +/* The smaller bus limits the maximum bytes per burst. */ +localparam BYTES_PER_BURST_LIMIT = + (BYTES_PER_BURST_LIMIT_DEST < BYTES_PER_BURST_LIMIT_SRC) ? + BYTES_PER_BURST_LIMIT_DEST : BYTES_PER_BURST_LIMIT_SRC; + +/* Make sure the requested MAX_BYTES_PER_BURST does not exceed what the + interfaces can support. Limit the value if necessary. */ +localparam REAL_MAX_BYTES_PER_BURST = + BYTES_PER_BURST_LIMIT < MAX_BYTES_PER_BURST ? + BYTES_PER_BURST_LIMIT : MAX_BYTES_PER_BURST; + +/* Align to the length to the wider interface */ +localparam DMA_LENGTH_ALIGN = + BYTES_PER_BEAT_WIDTH_DEST < BYTES_PER_BEAT_WIDTH_SRC ? + BYTES_PER_BEAT_WIDTH_SRC : BYTES_PER_BEAT_WIDTH_DEST; + +localparam BYTES_PER_BURST_WIDTH = + REAL_MAX_BYTES_PER_BURST > 2048 ? 12 : + REAL_MAX_BYTES_PER_BURST > 1024 ? 11 : + REAL_MAX_BYTES_PER_BURST > 512 ? 10 : + REAL_MAX_BYTES_PER_BURST > 256 ? 9 : + REAL_MAX_BYTES_PER_BURST > 128 ? 8 : + REAL_MAX_BYTES_PER_BURST > 64 ? 7 : + REAL_MAX_BYTES_PER_BURST > 32 ? 6 : + REAL_MAX_BYTES_PER_BURST > 16 ? 5 : + REAL_MAX_BYTES_PER_BURST > 8 ? 4 : + REAL_MAX_BYTES_PER_BURST > 4 ? 3 : + REAL_MAX_BYTES_PER_BURST > 2 ? 2 : 1; + +// ID signals from the DMAC, just for debugging +wire [ID_WIDTH-1:0] dest_request_id; +wire [ID_WIDTH-1:0] dest_data_id; +wire [ID_WIDTH-1:0] dest_address_id; +wire [ID_WIDTH-1:0] dest_response_id; +wire [ID_WIDTH-1:0] src_request_id; +wire [ID_WIDTH-1:0] src_data_id; +wire [ID_WIDTH-1:0] src_address_id; +wire [ID_WIDTH-1:0] src_response_id; +wire [11:0] dbg_status; +wire [31:0] dbg_ids0; +wire [31:0] dbg_ids1; + +assign m_dest_axi_araddr = 'd0; +assign m_dest_axi_arlen = 'd0; +assign m_dest_axi_arsize = 'd0; +assign m_dest_axi_arburst = 'd0; +assign m_dest_axi_arcache = 'd0; +assign m_dest_axi_arprot = 'd0; +assign m_dest_axi_awid = 'h0; +assign m_dest_axi_awlock = 'h0; +assign m_dest_axi_wid = 'h0; +assign m_dest_axi_arid = 'h0; +assign m_dest_axi_arlock = 'h0; +assign m_src_axi_awaddr = 'd0; +assign m_src_axi_awlen = 'd0; +assign m_src_axi_awsize = 'd0; +assign m_src_axi_awburst = 'd0; +assign m_src_axi_awcache = 'd0; +assign m_src_axi_awprot = 'd0; +assign m_src_axi_wdata = 'd0; +assign m_src_axi_wstrb = 'd0; +assign m_src_axi_wlast = 'd0; +assign m_src_axi_awid = 'h0; +assign m_src_axi_awlock = 'h0; +assign m_src_axi_wid = 'h0; +assign m_src_axi_arid = 'h0; +assign m_src_axi_arlock = 'h0; + +wire up_req_eot; +wire [BYTES_PER_BURST_WIDTH-1:0] up_req_measured_burst_length; +wire up_response_partial; +wire up_response_valid; +wire up_response_ready; + +wire ctrl_enable; +wire ctrl_pause; + +wire up_dma_req_valid; +wire up_dma_req_ready; +wire [DMA_AXI_ADDR_WIDTH-1:BYTES_PER_BEAT_WIDTH_DEST] up_dma_req_dest_address; +wire [DMA_AXI_ADDR_WIDTH-1:BYTES_PER_BEAT_WIDTH_SRC] up_dma_req_src_address; +wire [DMA_LENGTH_WIDTH-1:0] up_dma_req_x_length; +wire [DMA_LENGTH_WIDTH-1:0] up_dma_req_y_length; +wire [DMA_LENGTH_WIDTH-1:0] up_dma_req_dest_stride; +wire [DMA_LENGTH_WIDTH-1:0] up_dma_req_src_stride; +wire up_dma_req_sync_transfer_start; +wire up_dma_req_last; + +assign dbg_ids0 = { + {DBG_ID_PADDING{1'b0}}, dest_response_id, + {DBG_ID_PADDING{1'b0}}, dest_data_id, + {DBG_ID_PADDING{1'b0}}, dest_address_id, + {DBG_ID_PADDING{1'b0}}, dest_request_id +}; + +assign dbg_ids1 = { + {DBG_ID_PADDING{1'b0}}, src_response_id, + {DBG_ID_PADDING{1'b0}}, src_data_id, + {DBG_ID_PADDING{1'b0}}, src_address_id, + {DBG_ID_PADDING{1'b0}}, src_request_id +}; + +axi_dmac_regmap #( + .DISABLE_DEBUG_REGISTERS(DISABLE_DEBUG_REGISTERS), + .BYTES_PER_BEAT_WIDTH_DEST(BYTES_PER_BEAT_WIDTH_DEST), + .BYTES_PER_BEAT_WIDTH_SRC(BYTES_PER_BEAT_WIDTH_SRC), + .BYTES_PER_BURST_WIDTH(BYTES_PER_BURST_WIDTH), + .DMA_AXI_ADDR_WIDTH(DMA_AXI_ADDR_WIDTH), + .DMA_LENGTH_WIDTH(DMA_LENGTH_WIDTH), + .DMA_LENGTH_ALIGN(DMA_LENGTH_ALIGN), + .DMA_CYCLIC(CYCLIC), + .HAS_DEST_ADDR(HAS_DEST_ADDR), + .HAS_SRC_ADDR(HAS_SRC_ADDR), + .DMA_2D_TRANSFER(DMA_2D_TRANSFER), + .SYNC_TRANSFER_START(SYNC_TRANSFER_START) +) i_regmap ( + .s_axi_aclk(s_axi_aclk), + .s_axi_aresetn(s_axi_aresetn), + + .s_axi_awvalid(s_axi_awvalid), + .s_axi_awaddr(s_axi_awaddr), + .s_axi_awready(s_axi_awready), + .s_axi_awprot(s_axi_awprot), + .s_axi_wvalid(s_axi_wvalid), + .s_axi_wdata(s_axi_wdata), + .s_axi_wstrb(s_axi_wstrb), + .s_axi_wready(s_axi_wready), + .s_axi_bvalid(s_axi_bvalid), + .s_axi_bresp(s_axi_bresp), + .s_axi_bready(s_axi_bready), + .s_axi_arvalid(s_axi_arvalid), + .s_axi_araddr(s_axi_araddr), + .s_axi_arready(s_axi_arready), + .s_axi_arprot(s_axi_arprot), + .s_axi_rvalid(s_axi_rvalid), + .s_axi_rready(s_axi_rready), + .s_axi_rresp(s_axi_rresp), + .s_axi_rdata(s_axi_rdata), + + // Interrupt + .irq(irq), + + // Control interface + .ctrl_enable(ctrl_enable), + .ctrl_pause(ctrl_pause), + + // Request interface + .request_valid(up_dma_req_valid), + .request_ready(up_dma_req_ready), + .request_dest_address(up_dma_req_dest_address), + .request_src_address(up_dma_req_src_address), + .request_x_length(up_dma_req_x_length), + .request_y_length(up_dma_req_y_length), + .request_dest_stride(up_dma_req_dest_stride), + .request_src_stride(up_dma_req_src_stride), + .request_sync_transfer_start(up_dma_req_sync_transfer_start), + .request_last(up_dma_req_last), + + // DMA response interface + .response_eot(up_req_eot), + .response_measured_burst_length(up_req_measured_burst_length), + .response_partial(up_response_partial), + .response_valid(up_response_valid), + .response_ready(up_response_ready), + + // Debug interface + .dbg_dest_addr(m_dest_axi_awaddr), + .dbg_src_addr(m_src_axi_araddr), + .dbg_status(dbg_status), + .dbg_ids0(dbg_ids0), + .dbg_ids1(dbg_ids1) +); + +axi_dmac_transfer #( + .DMA_DATA_WIDTH_SRC(DMA_DATA_WIDTH_SRC), + .DMA_DATA_WIDTH_DEST(DMA_DATA_WIDTH_DEST), + .DMA_LENGTH_WIDTH(DMA_LENGTH_WIDTH), + .BYTES_PER_BEAT_WIDTH_DEST(BYTES_PER_BEAT_WIDTH_DEST), + .BYTES_PER_BEAT_WIDTH_SRC(BYTES_PER_BEAT_WIDTH_SRC), + .BYTES_PER_BURST_WIDTH(BYTES_PER_BURST_WIDTH), + .DMA_TYPE_DEST(DMA_TYPE_DEST), + .DMA_TYPE_SRC(DMA_TYPE_SRC), + .DMA_AXI_ADDR_WIDTH(DMA_AXI_ADDR_WIDTH), + .DMA_2D_TRANSFER(DMA_2D_TRANSFER), + .ASYNC_CLK_REQ_SRC(ASYNC_CLK_REQ_SRC), + .ASYNC_CLK_SRC_DEST(ASYNC_CLK_SRC_DEST), + .ASYNC_CLK_DEST_REQ(ASYNC_CLK_DEST_REQ), + .AXI_SLICE_DEST(AXI_SLICE_DEST), + .AXI_SLICE_SRC(AXI_SLICE_SRC), + .MAX_BYTES_PER_BURST(REAL_MAX_BYTES_PER_BURST), + .FIFO_SIZE(FIFO_SIZE), + .ID_WIDTH(ID_WIDTH), + .AXI_LENGTH_WIDTH_SRC(8-(4*DMA_AXI_PROTOCOL_SRC)), + .AXI_LENGTH_WIDTH_DEST(8-(4*DMA_AXI_PROTOCOL_DEST)), + .ENABLE_DIAGNOSTICS_IF(ENABLE_DIAGNOSTICS_IF) +) i_transfer ( + .ctrl_clk(s_axi_aclk), + .ctrl_resetn(s_axi_aresetn), + + .ctrl_enable(ctrl_enable), + .ctrl_pause(ctrl_pause), + + .req_valid(up_dma_req_valid), + .req_ready(up_dma_req_ready), + .req_dest_address(up_dma_req_dest_address), + .req_src_address(up_dma_req_src_address), + .req_x_length(up_dma_req_x_length), + .req_y_length(up_dma_req_y_length), + .req_dest_stride(up_dma_req_dest_stride), + .req_src_stride(up_dma_req_src_stride), + .req_sync_transfer_start(up_dma_req_sync_transfer_start), + .req_last(up_dma_req_last), + + .req_eot(up_req_eot), + .req_measured_burst_length(up_req_measured_burst_length), + .req_response_partial(up_response_partial), + .req_response_valid(up_response_valid), + .req_response_ready(up_response_ready), + + .m_dest_axi_aclk(m_dest_axi_aclk), + .m_dest_axi_aresetn(m_dest_axi_aresetn), + .m_src_axi_aclk(m_src_axi_aclk), + .m_src_axi_aresetn(m_src_axi_aresetn), + + .m_axi_awaddr(m_dest_axi_awaddr), + .m_axi_awlen(m_dest_axi_awlen), + .m_axi_awsize(m_dest_axi_awsize), + .m_axi_awburst(m_dest_axi_awburst), + .m_axi_awprot(m_dest_axi_awprot), + .m_axi_awcache(m_dest_axi_awcache), + .m_axi_awvalid(m_dest_axi_awvalid), + .m_axi_awready(m_dest_axi_awready), + + .m_axi_wdata(m_dest_axi_wdata), + .m_axi_wstrb(m_dest_axi_wstrb), + .m_axi_wready(m_dest_axi_wready), + .m_axi_wvalid(m_dest_axi_wvalid), + .m_axi_wlast(m_dest_axi_wlast), + + .m_axi_bvalid(m_dest_axi_bvalid), + .m_axi_bresp(m_dest_axi_bresp), + .m_axi_bready(m_dest_axi_bready), + + .m_axi_arready(m_src_axi_arready), + .m_axi_arvalid(m_src_axi_arvalid), + .m_axi_araddr(m_src_axi_araddr), + .m_axi_arlen(m_src_axi_arlen), + .m_axi_arsize(m_src_axi_arsize), + .m_axi_arburst(m_src_axi_arburst), + .m_axi_arprot(m_src_axi_arprot), + .m_axi_arcache(m_src_axi_arcache), + + .m_axi_rdata(m_src_axi_rdata), + .m_axi_rready(m_src_axi_rready), + .m_axi_rvalid(m_src_axi_rvalid), + .m_axi_rlast(m_src_axi_rlast), + .m_axi_rresp(m_src_axi_rresp), + + .s_axis_aclk(s_axis_aclk), + .s_axis_ready(s_axis_ready), + .s_axis_valid(s_axis_valid), + .s_axis_data(s_axis_data), + .s_axis_user(s_axis_user), + .s_axis_last(s_axis_last), + .s_axis_xfer_req(s_axis_xfer_req), + + .m_axis_aclk(m_axis_aclk), + .m_axis_ready(m_axis_ready), + .m_axis_valid(m_axis_valid), + .m_axis_data(m_axis_data), + .m_axis_last(m_axis_last), + .m_axis_xfer_req(m_axis_xfer_req), + + .fifo_wr_clk(fifo_wr_clk), + .fifo_wr_en(fifo_wr_en), + .fifo_wr_din(fifo_wr_din), + .fifo_wr_overflow(fifo_wr_overflow), + .fifo_wr_sync(fifo_wr_sync), + .fifo_wr_xfer_req(fifo_wr_xfer_req), + + .fifo_rd_clk(fifo_rd_clk), + .fifo_rd_en(fifo_rd_en), + .fifo_rd_valid(fifo_rd_valid), + .fifo_rd_dout(fifo_rd_dout), + .fifo_rd_underflow(fifo_rd_underflow), + .fifo_rd_xfer_req(fifo_rd_xfer_req), + + // DBG + .dbg_dest_request_id(dest_request_id), + .dbg_dest_address_id(dest_address_id), + .dbg_dest_data_id(dest_data_id), + .dbg_dest_response_id(dest_response_id), + .dbg_src_request_id(src_request_id), + .dbg_src_address_id(src_address_id), + .dbg_src_data_id(src_data_id), + .dbg_src_response_id(src_response_id), + .dbg_status(dbg_status), + + .dest_diag_level_bursts(dest_diag_level_bursts) +); + +assign m_dest_axi_arvalid = 1'b0; +assign m_dest_axi_rready = 1'b0; +assign m_dest_axi_araddr = 'h0; +assign m_dest_axi_arlen = 'h0; +assign m_dest_axi_arsize = 'h0; +assign m_dest_axi_arburst = 'h0; +assign m_dest_axi_arcache = 'h0; +assign m_dest_axi_arprot = 'h0; + +assign m_src_axi_awvalid = 1'b0; +assign m_src_axi_wvalid = 1'b0; +assign m_src_axi_bready = 1'b0; +assign m_src_axi_awvalid = 'h0; +assign m_src_axi_awaddr = 'h0; +assign m_src_axi_awlen = 'h0; +assign m_src_axi_awsize = 'h0; +assign m_src_axi_awburst = 'h0; +assign m_src_axi_awcache = 'h0; +assign m_src_axi_awprot = 'h0; +assign m_src_axi_wvalid = 'h0; +assign m_src_axi_wdata = 'h0; +assign m_src_axi_wstrb = 'h0; +assign m_src_axi_wlast = 'h0; + +endmodule diff --git a/src/adi/hdl/library/axi_dmac/axi_dmac_burst_memory.v b/src/adi/hdl/library/axi_dmac/axi_dmac_burst_memory.v new file mode 100644 index 00000000..2addd78f --- /dev/null +++ b/src/adi/hdl/library/axi_dmac/axi_dmac_burst_memory.v @@ -0,0 +1,460 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright 2014 - 2018 (c) Analog Devices, Inc. All rights reserved. +// +// In this HDL repository, there are many different and unique modules, consisting +// of various HDL (Verilog or VHDL) components. The individual modules are +// developed independently, and may be accompanied by separate and unique license +// terms. +// +// The user should read each of these license terms, and understand the +// freedoms and responsibilities that he or she has by using this source/core. +// +// This core 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. +// +// Redistribution and use of source or resulting binaries, with or without modification +// of this file, are permitted under one of the following two license terms: +// +// 1. The GNU General Public License version 2 as published by the +// Free Software Foundation, which can be found in the top level directory +// of this repository (LICENSE_GPL2), and also online at: +// +// +// OR +// +// 2. An ADI specific BSD license, which can be found in the top level directory +// of this repository (LICENSE_ADIBSD), and also on-line at: +// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD +// This will allow to generate bit files and not release the source code, +// as long as it attaches to an ADI device. +// +// *************************************************************************** +// *************************************************************************** + +`timescale 1ns/100ps + +module axi_dmac_burst_memory #( + parameter DATA_WIDTH_SRC = 64, + parameter DATA_WIDTH_DEST = 64, + parameter ID_WIDTH = 3, + parameter MAX_BYTES_PER_BURST = 128, + parameter ASYNC_CLK = 1, + parameter BYTES_PER_BEAT_WIDTH_SRC = $clog2(DATA_WIDTH_SRC/8), + parameter BYTES_PER_BURST_WIDTH = $clog2(MAX_BYTES_PER_BURST), + parameter ENABLE_DIAGNOSTICS_IF = 0 +) ( + input src_clk, + input src_reset, + + input src_data_valid, + input [DATA_WIDTH_SRC-1:0] src_data, + input src_data_last, + input [BYTES_PER_BEAT_WIDTH_SRC-1:0] src_data_valid_bytes, + input src_data_partial_burst, + + output [ID_WIDTH-1:0] src_data_request_id, + + input dest_clk, + input dest_reset, + + output dest_data_valid, + input dest_data_ready, + output [DATA_WIDTH_DEST-1:0] dest_data, + output dest_data_last, + + output [BYTES_PER_BURST_WIDTH-1:0] dest_burst_info_length, + output dest_burst_info_partial, + output [ID_WIDTH-1:0] dest_burst_info_id, + output reg dest_burst_info_write = 1'b0, + + output [ID_WIDTH-1:0] dest_request_id, + input [ID_WIDTH-1:0] dest_data_request_id, + output [ID_WIDTH-1:0] dest_data_response_id, + + // Diagnostics interface + output [7:0] dest_diag_level_bursts +); + +localparam DATA_WIDTH = DATA_WIDTH_SRC > DATA_WIDTH_DEST ? + DATA_WIDTH_SRC : DATA_WIDTH_DEST; + +/* A burst can have up to 256 beats */ +localparam BURST_LEN = MAX_BYTES_PER_BURST / (DATA_WIDTH / 8); +localparam BURST_LEN_WIDTH = BURST_LEN > 128 ? 8 : + BURST_LEN > 64 ? 7 : + BURST_LEN > 32 ? 6 : + BURST_LEN > 16 ? 5 : + BURST_LEN > 8 ? 4 : + BURST_LEN > 4 ? 3 : + BURST_LEN > 2 ? 2 : 1; + +localparam ADDRESS_WIDTH = BURST_LEN_WIDTH + ID_WIDTH - 1; + +localparam AUX_FIFO_SIZE = 2**(ID_WIDTH-1); + +localparam DEST_SRC_RATIO = DATA_WIDTH_DEST/DATA_WIDTH_SRC; + +localparam DEST_SRC_RATIO_WIDTH = DEST_SRC_RATIO > 64 ? 7 : + DEST_SRC_RATIO > 32 ? 6 : + DEST_SRC_RATIO > 16 ? 5 : + DEST_SRC_RATIO > 8 ? 4 : + DEST_SRC_RATIO > 4 ? 3 : + DEST_SRC_RATIO > 2 ? 2 : + DEST_SRC_RATIO > 1 ? 1 : 0; + +/* + * The burst memory is separated into 2**(ID_WIDTH-1) segments. Each segment can + * hold up to BURST_LEN beats. The addresses that are used to access the memory + * are split into two parts. The MSBs index the segment and the LSBs index a + * beat in a specific segment. + * + * src_id and dest_id are used to index the segment of the burst memory on the + * write and read side respectively. The IDs are 1 bit wider than the address of + * the burst memory. So we can't use them directly as an index into the burst + * memory. Since the IDs are gray counted we also can't just leave out the MSB + * like with a binary counter. But XOR-ing the two MSBs of a gray counter gives + * us a gray counter of 1 bit less. Use this to generate the segment index. + * These addresses are captured in the src_id_reduced and dest_id_reduced + * signals. + * + * src_beat_counter and dest_beat_counter are used to index the beat on the + * write and read side respectively. They will be incremented for each beat that + * is written/read. Note that the beat counters are not reset to 0 on the last + * beat of a burst. This means the first beat of a burst might not be stored at + * offset 0 in the segment memory. But this is OK since the beat counter + * increments modulo the segment size and both the write and read side agree on + * the order. + */ + +reg [ID_WIDTH-1:0] src_id_next; +reg [ID_WIDTH-1:0] src_id = 'h0; +reg src_id_reduced_msb = 1'b0; +reg [BURST_LEN_WIDTH-1:0] src_beat_counter = 'h00; + +reg [ID_WIDTH-1:0] dest_id_next = 'h0; +reg dest_id_reduced_msb_next = 1'b0; +reg dest_id_reduced_msb = 1'b0; +reg [ID_WIDTH-1:0] dest_id = 'h0; +reg [BURST_LEN_WIDTH-1:0] dest_beat_counter = 'h00; +wire [BURST_LEN_WIDTH-1:0] dest_burst_len; +reg dest_valid = 1'b0; +reg dest_mem_data_valid = 1'b0; +reg dest_mem_data_last = 1'b0; + +reg [BYTES_PER_BURST_WIDTH+1-1:0] burst_len_mem[0:AUX_FIFO_SIZE-1]; + +wire [BYTES_PER_BURST_WIDTH+1-1:0] src_burst_len_data; +reg [BYTES_PER_BURST_WIDTH+1-1:0] dest_burst_len_data = 'h00; + +wire src_beat; +wire src_last_beat; +wire [ID_WIDTH-1:0] src_dest_id; +wire [ADDRESS_WIDTH-1:0] src_waddr; +wire [ID_WIDTH-2:0] src_id_reduced; +wire src_mem_data_valid; +wire src_mem_data_last; +wire [DATA_WIDTH-1:0] src_mem_data; + +wire dest_beat; +wire dest_last_beat; +wire dest_last; +wire [ID_WIDTH-1:0] dest_src_id; +wire [ADDRESS_WIDTH-1:0] dest_raddr; +wire [ID_WIDTH-2:0] dest_id_reduced_next; +wire [ID_WIDTH-1:0] dest_id_next_inc; +wire [ID_WIDTH-2:0] dest_id_reduced; +wire dest_burst_valid; +wire dest_burst_ready; +wire dest_ready; +wire [DATA_WIDTH-1:0] dest_mem_data; +wire dest_mem_data_ready; + +`include "inc_id.vh" + +generate if (ID_WIDTH >= 3) begin + assign src_id_reduced = {src_id_reduced_msb,src_id[ID_WIDTH-3:0]}; + assign dest_id_reduced_next = {dest_id_reduced_msb_next,dest_id_next[ID_WIDTH-3:0]}; + assign dest_id_reduced = {dest_id_reduced_msb,dest_id[ID_WIDTH-3:0]}; +end else begin + assign src_id_reduced = src_id_reduced_msb; + assign dest_id_reduced_next = dest_id_reduced_msb_next; + assign dest_id_reduced = dest_id_reduced_msb; +end endgenerate + +assign src_beat = src_mem_data_valid; +assign src_last_beat = src_beat & src_mem_data_last; +assign src_waddr = {src_id_reduced,src_beat_counter}; + +assign src_data_request_id = src_dest_id; + +always @(*) begin + if (src_last_beat == 1'b1) begin + src_id_next <= inc_id(src_id); + end else begin + src_id_next <= src_id; + end +end + +always @(posedge src_clk) begin + if (src_reset == 1'b1) begin + src_id <= 'h00; + src_id_reduced_msb <= 1'b0; + end else begin + src_id <= src_id_next; + src_id_reduced_msb <= ^src_id_next[ID_WIDTH-1-:2]; + end +end + +always @(posedge src_clk) begin + if (src_reset == 1'b1) begin + src_beat_counter <= 'h00; + end else if (src_beat == 1'b1) begin + src_beat_counter <= src_beat_counter + 1'b1; + end +end + +always @(posedge src_clk) begin + if (src_last_beat == 1'b1) begin + burst_len_mem[src_id_reduced] <= src_burst_len_data; + end +end + +assign dest_ready = ~dest_mem_data_valid | dest_mem_data_ready; +assign dest_last = dest_beat_counter == dest_burst_len; + +assign dest_beat = dest_valid & dest_ready; +assign dest_last_beat = dest_last & dest_beat; +assign dest_raddr = {dest_id_reduced,dest_beat_counter}; + +assign dest_burst_valid = dest_data_request_id != dest_id_next; +assign dest_burst_ready = ~dest_valid | dest_last_beat; + +/* + * The data valid signal for the destination side is asserted if there are one + * or more pending bursts. It is de-asserted if there are no more pending burst + * and it is the last beat of the current burst + */ +always @(posedge dest_clk) begin + if (dest_reset == 1'b1) begin + dest_valid <= 1'b0; + end else if (dest_burst_valid == 1'b1) begin + dest_valid <= 1'b1; + end else if (dest_last_beat == 1'b1) begin + dest_valid <= 1'b0; + end +end + +/* + * The output register of the memory creates a extra clock cycle of latency on + * the data path. We need to handle this more the handshaking signals. If data + * is available in the memory it will be available one clock cycle later in the + * output register. + */ +always @(posedge dest_clk) begin + if (dest_reset == 1'b1) begin + dest_mem_data_valid <= 1'b0; + end else if (dest_valid == 1'b1) begin + dest_mem_data_valid <= 1'b1; + end else if (dest_mem_data_ready == 1'b1) begin + dest_mem_data_valid <= 1'b0; + end +end + +/* + * This clears dest_data_last after the last beat. Strictly speaking this is not + * necessary if this followed AXI handshaking rules since dest_data_last would + * be qualified by dest_data_valid and it is OK to retain the previous value of + * dest_data_last when dest_data_valid is not asserted. But clearing the signal + * here doesn't cost much and can simplify some of the more congested + * combinatorical logic further up the pipeline since we can assume that + * fifo_last == 1'b1 implies fifo_valid == 1'b1. + */ +always @(posedge dest_clk) begin + if (dest_reset == 1'b1) begin + dest_mem_data_last <= 1'b0; + end else if (dest_beat == 1'b1) begin + dest_mem_data_last <= dest_last; + end else if (dest_mem_data_ready == 1'b1) begin + dest_mem_data_last <= 1'b0; + end +end + +assign dest_id_next_inc = inc_id(dest_id_next); + +always @(posedge dest_clk) begin + if (dest_reset == 1'b1) begin + dest_id_next <= 'h00; + dest_id_reduced_msb_next <= 1'b0; + end else if (dest_burst_valid == 1'b1 && dest_burst_ready == 1'b1) begin + dest_id_next <= dest_id_next_inc; + dest_id_reduced_msb_next <= ^dest_id_next_inc[ID_WIDTH-1-:2]; + end +end + +always @(posedge dest_clk) begin + if (dest_burst_valid == 1'b1 && dest_burst_ready == 1'b1) begin + dest_burst_len_data <= burst_len_mem[dest_id_reduced_next]; + end +end + +always @(posedge dest_clk) begin + if (dest_burst_ready == 1'b1) begin + dest_id <= dest_id_next; + dest_id_reduced_msb <= dest_id_reduced_msb_next; + end +end + +always @(posedge dest_clk) begin + if (dest_reset == 1'b1) begin + dest_beat_counter <= 'h00; + end else if (dest_beat == 1'b1) begin + dest_beat_counter <= dest_beat_counter + 1'b1; + end +end + +assign dest_burst_info_length = dest_burst_len_data[BYTES_PER_BURST_WIDTH-1:0]; +assign dest_burst_info_partial = dest_burst_len_data[BYTES_PER_BURST_WIDTH]; +assign dest_burst_info_id = dest_id; + +always @(posedge dest_clk) begin + dest_burst_info_write <= (dest_burst_valid == 1'b1 && dest_burst_ready == 1'b1); +end + +// If destination is wider track the number of source beats in a destination +// beat in case the stream is not destination width aligned. +generate if (DATA_WIDTH_SRC < DATA_WIDTH_DEST) begin + + reg [DEST_SRC_RATIO_WIDTH-1:0] src_num_beats = {DEST_SRC_RATIO_WIDTH{1'b1}}; + reg [BYTES_PER_BEAT_WIDTH_SRC-1:0] src_data_valid_bytes_d = 'h00; + reg src_data_partial_burst_d = 'h0; + + // This counter will hold the number of source beat in a destination beat + // minus one + always @(posedge src_clk) begin + if (src_mem_data_last == 1'b1 && src_mem_data_valid == 1'b1) begin + if (src_data_valid) begin + src_num_beats <= {DEST_SRC_RATIO_WIDTH{1'b0}}; + end else begin + src_num_beats <= {DEST_SRC_RATIO_WIDTH{1'b1}}; + end + end else if (src_data_valid) begin + src_num_beats <= src_num_beats + 1'b1; + end + end + + // Compensate the delay through the resize block + always @(posedge src_clk) begin + if (src_data_valid == 1'b1) begin + src_data_valid_bytes_d <= src_data_valid_bytes; + src_data_partial_burst_d <= src_data_partial_burst; + end + end + + assign src_burst_len_data = {src_data_partial_burst_d, + src_beat_counter, + src_num_beats, + src_data_valid_bytes_d}; +end else begin + + assign src_burst_len_data = {src_data_partial_burst, + src_beat_counter, + src_data_valid_bytes}; +end +endgenerate + +assign dest_burst_len = dest_burst_len_data[BYTES_PER_BURST_WIDTH-1 -: BURST_LEN_WIDTH]; + +axi_dmac_resize_src #( + .DATA_WIDTH_SRC (DATA_WIDTH_SRC), + .DATA_WIDTH_MEM (DATA_WIDTH) +) i_resize_src ( + .clk (src_clk), + .reset (src_reset), + + .src_data_valid (src_data_valid), + .src_data (src_data), + .src_data_last (src_data_last), + + .mem_data_valid (src_mem_data_valid), + .mem_data (src_mem_data), + .mem_data_last (src_mem_data_last) +); + +ad_mem #( + .DATA_WIDTH (DATA_WIDTH), + .ADDRESS_WIDTH (ADDRESS_WIDTH) +) i_mem ( + .clka (src_clk), + .wea (src_beat), + .addra (src_waddr), + .dina (src_mem_data), + + .clkb (dest_clk), + .reb (dest_beat), + .addrb (dest_raddr), + .doutb (dest_mem_data) +); + +axi_dmac_resize_dest #( + .DATA_WIDTH_DEST (DATA_WIDTH_DEST), + .DATA_WIDTH_MEM (DATA_WIDTH) +) i_resize_dest ( + .clk (dest_clk), + .reset (dest_reset), + + .mem_data_valid (dest_mem_data_valid), + .mem_data_ready (dest_mem_data_ready), + .mem_data (dest_mem_data), + .mem_data_last (dest_mem_data_last), + + .dest_data_valid (dest_data_valid), + .dest_data_ready (dest_data_ready), + .dest_data (dest_data), + .dest_data_last (dest_data_last) +); + +sync_bits #( + .NUM_OF_BITS (ID_WIDTH), + .ASYNC_CLK (ASYNC_CLK) +) i_dest_sync_id ( + .in (src_id), + .out_clk (dest_clk), + .out_resetn (1'b1), + .out (dest_src_id) +); + +sync_bits #( + .NUM_OF_BITS (ID_WIDTH), + .ASYNC_CLK (ASYNC_CLK) +) i_src_sync_id ( + .in (dest_id), + .out_clk (src_clk), + .out_resetn (1'b1), + .out (src_dest_id) +); + +assign dest_request_id = dest_src_id; +assign dest_data_response_id = dest_id; + +generate if (ENABLE_DIAGNOSTICS_IF == 1) begin + + reg [ID_WIDTH-1:0] _dest_diag_level_bursts = 'h0; + + // calculate buffer fullness in bursts + always @(posedge dest_clk) begin + if (dest_reset == 1'b1) begin + _dest_diag_level_bursts <= 'h0; + end else begin + _dest_diag_level_bursts <= g2b(dest_src_id) - g2b(dest_id); + end + end + assign dest_diag_level_bursts = {{{8-ID_WIDTH}{1'b0}},_dest_diag_level_bursts}; + +end else begin + assign dest_diag_level_bursts = 'h0; +end +endgenerate + +endmodule diff --git a/src/adi/hdl/library/axi_dmac/axi_dmac_constr.sdc b/src/adi/hdl/library/axi_dmac/axi_dmac_constr.sdc new file mode 100644 index 00000000..2e482979 --- /dev/null +++ b/src/adi/hdl/library/axi_dmac/axi_dmac_constr.sdc @@ -0,0 +1,34 @@ + + +set_false_path -to [get_registers *axi_dmac*cdc_sync_stage1*] +set_false_path -from [get_registers *axi_dmac*cdc_sync_fifo_ram*] +set_false_path -from [get_registers *axi_dmac*eot_mem*] +set_false_path -from [get_registers *axi_dmac*bl_mem*] + +# Burst memory +set_false_path -from [get_registers *axi_dmac*burst_len_mem*] + +# Reset manager +set_false_path \ + -from [get_registers {*|axi_dmac_transfer:i_transfer|axi_dmac_reset_manager:i_reset_manager|do_reset}] \ + -to [get_pins -compatibility_mode {*|axi_dmac_transfer:i_transfer|axi_dmac_reset_manager:i_reset_manager|reset_gen[*].reset_async[*]|clrn}] + +set_false_path \ + -from [get_registers {*|axi_dmac_transfer:i_transfer|axi_dmac_reset_manager:i_reset_manager|reset_gen[*].reset_async[0]}] \ + -to [get_registers {*|axi_dmac_transfer:i_transfer|axi_dmac_reset_manager:i_reset_manager|reset_gen[*].reset_async[3]}] + +set_false_path \ + -from [get_registers {*|axi_dmac_transfer:i_transfer|axi_dmac_reset_manager:i_reset_manager|reset_gen[*].reset_async[0]}] \ + -to [get_pins -compatibility_mode {*|axi_dmac_transfer:i_transfer|axi_dmac_reset_manager:i_reset_manager|reset_gen[*].reset_sync_in|clrn}] + +set_false_path \ + -from [get_registers {*|axi_dmac_transfer:i_transfer|axi_dmac_reset_manager:i_reset_manager|reset_gen[*].reset_sync[0]}] \ + -to [get_pins -compatibility_mode {*|axi_dmac_transfer:i_transfer|axi_dmac_reset_manager:i_reset_manager|reset_gen[*].reset_sync_in|clrn}] + +# Debug signals +set_false_path -from [get_registers *axi_dmac*|*i_request_arb*|cdc_sync_stage2*] -to [get_registers *axi_dmac*up_rdata*] +set_false_path -from [get_registers *axi_dmac*|*i_request_arb*|*id*] -to [get_registers *axi_dmac*up_rdata*] +set_false_path -from [get_registers *axi_dmac*|*i_request_arb*|address*] -to [get_registers *axi_dmac*up_rdata*] +set_false_path \ + -from [get_registers {*|axi_dmac_transfer:i_transfer|axi_dmac_reset_manager:i_reset_manager|reset_gen[*].reset_sync[0]}] \ + -to [get_registers {*|axi_dmac_regmap:i_regmap|up_rdata[*]}] diff --git a/src/adi/hdl/library/axi_dmac/axi_dmac_constr.ttcl b/src/adi/hdl/library/axi_dmac/axi_dmac_constr.ttcl new file mode 100644 index 00000000..f947fe18 --- /dev/null +++ b/src/adi/hdl/library/axi_dmac/axi_dmac_constr.ttcl @@ -0,0 +1,250 @@ +<: set ComponentName [getComponentNameString] :> +<: setOutputDirectory "./" :> +<: setFileName [ttcl_add $ComponentName "_constr"] :> +<: setFileExtension ".xdc" :> +<: setFileProcessingOrder late :> +<: set async_dest_req [getBooleanValue "ASYNC_CLK_DEST_REQ"] :> +<: set async_req_src [getBooleanValue "ASYNC_CLK_REQ_SRC"] :> +<: set async_src_dest [getBooleanValue "ASYNC_CLK_SRC_DEST"] :> +<: set disable_debug_registers [getBooleanValue "DISABLE_DEBUG_REGISTERS"] :> + +set req_clk [get_clocks -of_objects [get_ports s_axi_aclk]] +set src_clk [get_clocks -of_objects [get_ports -quiet {fifo_wr_clk s_axis_aclk m_src_axi_aclk}]] +set dest_clk [get_clocks -of_objects [get_ports -quiet {fifo_rd_clk m_axis_aclk m_dest_axi_aclk}]] + +<: if {$async_req_src || $async_src_dest || $async_dest_req} { :> +set_property ASYNC_REG TRUE \ + [get_cells -quiet -hier *cdc_sync_stage1_reg*] \ + [get_cells -quiet -hier *cdc_sync_stage2_reg*] + +<: } :> +<: if {$async_req_src} { :> +set_max_delay -quiet -datapath_only \ + -from $req_clk \ + -to [get_cells -quiet -hier *cdc_sync_stage1_reg* \ + -filter {NAME =~ *i_sync_src_request_id* && IS_SEQUENTIAL}] \ + [get_property -min PERIOD $req_clk] + +set_false_path -quiet \ + -from $src_clk \ + -to [get_cells -quiet -hier *cdc_sync_stage1_reg* \ + -filter {NAME =~ *i_sync_status_src* && IS_SEQUENTIAL}] + +set_false_path -quiet \ + -from $req_clk \ + -to [get_cells -quiet -hier *cdc_sync_stage1_reg* \ + -filter {NAME =~ *i_sync_control_src* && IS_SEQUENTIAL}] + +set_max_delay -quiet -datapath_only \ + -from $req_clk \ + -to [get_cells -quiet -hier *cdc_sync_stage1_reg* \ + -filter {NAME =~ *i_src_req_fifo/i_waddr_sync* && IS_SEQUENTIAL}] \ + [get_property -min PERIOD $req_clk] + +set_max_delay -quiet -datapath_only \ + -from $src_clk \ + -to [get_cells -quiet -hier *cdc_sync_stage1_reg* \ + -filter {NAME =~ *i_src_req_fifo/i_raddr_sync* && IS_SEQUENTIAL}] \ + [get_property -min PERIOD $src_clk] + +set_max_delay -quiet -datapath_only \ + -from [get_cells -quiet -hier *cdc_sync_fifo_ram_reg* \ + -filter {NAME =~ *i_src_req_fifo* && IS_SEQUENTIAL}] \ + -to $src_clk \ + [get_property -min PERIOD $src_clk] + +set_max_delay -quiet -datapath_only \ + -from $req_clk \ + -through [get_cells -quiet -hier DP \ + -filter {NAME =~ *i_request_arb/eot_mem_src_reg*}] \ + -to $src_clk \ + [get_property -min PERIOD $src_clk] + +set_max_delay -quiet -datapath_only \ + -from $src_clk \ + -to [get_cells -quiet -hier *cdc_sync_stage1_reg* \ + -filter {NAME =~ *i_rewind_req_fifo/i_waddr_sync* && IS_SEQUENTIAL}] \ + [get_property -min PERIOD $src_clk] + +set_max_delay -quiet -datapath_only \ + -from $dest_clk \ + -to [get_cells -quiet -hier *cdc_sync_stage1_reg* \ + -filter {NAME =~ *i_rewind_req_fifo/i_raddr_sync* && IS_SEQUENTIAL}] \ + [get_property -min PERIOD $dest_clk] + +set_max_delay -quiet -datapath_only \ + -from [get_cells -quiet -hier *cdc_sync_fifo_ram_reg* \ + -filter {NAME =~ *i_rewind_req_fifo* && IS_SEQUENTIAL}] \ + -to $dest_clk \ + [get_property -min PERIOD $dest_clk] + +set_false_path -quiet \ + -from $req_clk \ + -to [get_cells -quiet -hier *cdc_sync_stage1_reg* \ + -filter {NAME =~ *sync_rewind/i_sync_out* && IS_SEQUENTIAL}] + +set_false_path -quiet \ + -from $src_clk \ + -to [get_cells -quiet -hier *cdc_sync_stage1_reg* \ + -filter {NAME =~ *sync_rewind/i_sync_in* && IS_SEQUENTIAL}] + +<: } :> +<: if {$async_dest_req} { :> +set_max_delay -quiet -datapath_only \ + -from $dest_clk \ + -to [get_cells -hier *cdc_sync_stage1_reg* \ + -filter {NAME =~ *i_sync_req_response_id* && IS_SEQUENTIAL}] \ + [get_property -min PERIOD $dest_clk] + +set_false_path -quiet \ + -from $dest_clk \ + -to [get_cells -quiet -hier *cdc_sync_stage1_reg* \ + -filter {NAME =~ *i_sync_status_dest* && IS_SEQUENTIAL}] + +set_false_path -quiet \ + -from $req_clk \ + -to [get_cells -quiet -hier *cdc_sync_stage1_reg* \ + -filter {NAME =~ *i_sync_control_dest* && IS_SEQUENTIAL}] + +set_max_delay -quiet -datapath_only \ + -from $dest_clk \ + -to [get_cells -quiet -hier *cdc_sync_stage1_reg* \ + -filter {NAME =~ *i_dest_response_fifo/i_waddr_sync* && IS_SEQUENTIAL}] \ + [get_property -min PERIOD $dest_clk] + +set_max_delay -quiet -datapath_only \ + -from $req_clk \ + -to [get_cells -quiet -hier *cdc_sync_stage1_reg* \ + -filter {NAME =~ *i_dest_response_fifo/i_raddr_sync* && IS_SEQUENTIAL}] \ + [get_property -min PERIOD $req_clk] +set_max_delay -quiet -datapath_only \ + -from [get_cells -quiet -hier *cdc_sync_fifo_ram_reg* \ + -filter {NAME =~ *i_dest_response_fifo* && IS_SEQUENTIAL}] \ + -to $req_clk \ + [get_property -min PERIOD $req_clk] + +<: } :> +<: if {$async_src_dest} { :> +set_max_delay -quiet -datapath_only \ + -from $src_clk \ + -to [get_cells -quiet -hier *cdc_sync_stage1_reg* \ + -filter {NAME =~ *i_sync_dest_request_id* && IS_SEQUENTIAL}] \ + [get_property -min PERIOD $src_clk] + +set_max_delay -quiet -datapath_only \ + -from $src_clk \ + -to [get_cells -quiet -hier *cdc_sync_stage1_reg* \ + -filter {NAME =~ *i_store_and_forward/i_dest_sync_id* && IS_SEQUENTIAL}] \ + [get_property -min PERIOD $src_clk] + +set_max_delay -quiet -datapath_only \ + -from $dest_clk \ + -to [get_cells -quiet -hier *cdc_sync_stage1_reg* \ + -filter {NAME =~ *i_store_and_forward/i_src_sync_id* && IS_SEQUENTIAL}] \ + [get_property -min PERIOD $dest_clk] + +set_max_delay -quiet -datapath_only \ + -from $src_clk \ + -through [get_cells -quiet -hier \ + -filter {IS_SEQUENTIAL && NAME =~ *i_store_and_forward/burst_len_mem_reg*}] \ + -to $dest_clk \ + [get_property -min PERIOD $dest_clk] + +set_max_delay -quiet -datapath_only \ + -from $src_clk \ + -to [get_cells -quiet -hier *cdc_sync_stage1_reg* \ + -filter {NAME =~ *i_dest_req_fifo/i_waddr_sync* && IS_SEQUENTIAL}] \ + [get_property -min PERIOD $src_clk] + +set_max_delay -quiet -datapath_only \ + -from $dest_clk \ + -to [get_cells -quiet -hier *cdc_sync_stage1_reg* \ + -filter {NAME =~ *i_dest_req_fifo/i_raddr_sync* && IS_SEQUENTIAL}] \ + [get_property -min PERIOD $dest_clk] + +set_max_delay -quiet -datapath_only \ + -from [get_cells -quiet -hier *cdc_sync_fifo_ram_reg* \ + -filter {NAME =~ *i_dest_req_fifo* && IS_SEQUENTIAL}] \ + -to $dest_clk \ + [get_property -min PERIOD $dest_clk] + +set_max_delay -quiet -datapath_only \ + -from $src_clk \ + -to [get_cells -quiet -hier *cdc_sync_stage1_reg* \ + -filter {NAME =~ *i_src_dest_bl_fifo/i_waddr_sync* && IS_SEQUENTIAL}] \ + [get_property -min PERIOD $src_clk] + +set_max_delay -quiet -datapath_only \ + -from $dest_clk \ + -to [get_cells -quiet -hier *cdc_sync_stage1_reg* \ + -filter {NAME =~ *i_src_dest_bl_fifo/i_raddr_sync* && IS_SEQUENTIAL}] \ + [get_property -min PERIOD $dest_clk] + +set_max_delay -quiet -datapath_only \ + -from [get_cells -quiet -hier *cdc_sync_fifo_ram_reg* \ + -filter {NAME =~ *i_src_dest_bl_fifo* && IS_SEQUENTIAL}] \ + -to $dest_clk \ + [get_property -min PERIOD $dest_clk] + + set_max_delay -quiet -datapath_only \ + -from $src_clk \ + -through [get_cells -quiet -hier DP \ + -filter {NAME =~ *i_request_arb/eot_mem_dest_reg*}] \ + -to $dest_clk \ + [get_property -min PERIOD $dest_clk] + +<: } :> +# Reset signals +set_false_path -quiet \ + -from [get_cells -quiet -hier *do_reset_reg* \ + -filter {NAME =~ *i_reset_manager* && IS_SEQUENTIAL}] \ + -to [get_pins -quiet -hier *reset_async_reg*/PRE] + +set_false_path -quiet \ + -from [get_cells -quiet -hier *reset_async_reg[0] \ + -filter {NAME =~ *i_reset_manager* && IS_SEQUENTIAL}] \ + -to [get_cells -quiet -hier *reset_async_reg[3]* \ + -filter {NAME =~ *i_reset_manager* && IS_SEQUENTIAL}] + +set_false_path -quiet \ + -from [get_cells -quiet -hier *reset_async_reg[0] \ + -filter {NAME =~ *i_reset_manager* && IS_SEQUENTIAL}] \ + -to [get_pins -quiet -hier *reset_sync_in_reg*/PRE \ + -filter {NAME =~ *i_reset_manager*}] + +set_false_path -quiet \ + -from [get_cells -quiet -hier *reset_sync_reg[0] \ + -filter {NAME =~ *i_reset_manager* && IS_SEQUENTIAL}] \ + -to [get_pins -quiet -hier *reset_sync_in_reg*/PRE \ + -filter {NAME =~ *i_reset_manager*}] + +set_property -dict { \ + SHREG_EXTRACT NO \ + ASYNC_REG TRUE \ + } [get_cells -quiet -hier *reset_async_reg*] + +set_property -dict { \ + SHREG_EXTRACT NO \ + ASYNC_REG TRUE \ + } [get_cells -quiet -hier *reset_sync_reg*] + +# Ignore timing for debug signals to register map +<: if {!$disable_debug_registers} { :> +set_false_path -quiet \ + -from [get_cells -quiet -hier *cdc_sync_stage2_reg* \ + -filter {name =~ *i_sync_src_request_id* && IS_SEQUENTIAL}] \ + -to [get_cells -quiet -hier *up_rdata_reg* -filter {IS_SEQUENTIAL}] +set_false_path -quiet \ + -from [get_cells -quiet -hier *cdc_sync_stage2_reg* \ + -filter {name =~ *i_dest_sync_id* && IS_SEQUENTIAL}] \ + -to [get_cells -quiet -hier *up_rdata_reg* -filter {IS_SEQUENTIAL}] +set_false_path -quiet \ + -from [get_cells -quiet -hier *id_reg* -filter {name =~ *i_request_arb* && IS_SEQUENTIAL}] \ + -to [get_cells -quiet -hier *up_rdata_reg* -filter {IS_SEQUENTIAL}] +set_false_path -quiet \ + -from [get_cells -quiet -hier *address_reg* -filter {name =~ *i_addr_gen* && IS_SEQUENTIAL}] \ + -to [get_cells -quiet -hier *up_rdata_reg* -filter {IS_SEQUENTIAL}] +set_false_path -quiet \ + -from [get_cells -quiet -hier *reset_sync_reg* -filter {name =~ *i_reset_manager* && IS_SEQUENTIAL}] \ + -to [get_cells -quiet -hier *up_rdata_reg* -filter {IS_SEQUENTIAL}] +<: } :> diff --git a/src/adi/hdl/library/axi_dmac/axi_dmac_hw.tcl b/src/adi/hdl/library/axi_dmac/axi_dmac_hw.tcl new file mode 100644 index 00000000..933a850d --- /dev/null +++ b/src/adi/hdl/library/axi_dmac/axi_dmac_hw.tcl @@ -0,0 +1,498 @@ + + +package require qsys +source ../scripts/adi_env.tcl +source ../scripts/adi_ip_alt.tcl + +set_module_property NAME axi_dmac +set_module_property DESCRIPTION "AXI DMA Controller" +set_module_property VERSION 1.0 +set_module_property GROUP "Analog Devices" +set_module_property DISPLAY_NAME axi_dmac +set_module_property ELABORATION_CALLBACK axi_dmac_elaborate +set_module_property VALIDATION_CALLBACK axi_dmac_validate + +# files + +ad_ip_files axi_dmac [list \ + $ad_hdl_dir/library/util_cdc/sync_bits.v \ + $ad_hdl_dir/library/util_cdc/sync_event.v \ + $ad_hdl_dir/library/common/up_axi.v \ + $ad_hdl_dir/library/util_axis_fifo/util_axis_fifo.v \ + $ad_hdl_dir/library/util_axis_fifo/address_sync.v \ + $ad_hdl_dir/library/common/ad_mem.v \ + inc_id.vh \ + resp.vh \ + axi_dmac_burst_memory.v \ + axi_dmac_regmap.v \ + axi_dmac_regmap_request.v \ + axi_dmac_reset_manager.v \ + axi_dmac_resize_dest.v \ + axi_dmac_resize_src.v \ + axi_dmac_response_manager.v \ + axi_dmac_transfer.v \ + address_generator.v \ + data_mover.v \ + request_arb.v \ + request_generator.v \ + response_handler.v \ + axi_register_slice.v \ + 2d_transfer.v \ + dest_axi_mm.v \ + dest_axi_stream.v \ + dest_fifo_inf.v \ + src_axi_mm.v \ + src_axi_stream.v \ + src_fifo_inf.v \ + splitter.v \ + response_generator.v \ + axi_dmac.v \ + axi_dmac_constr.sdc \ +] + +# Disable dual-clock RAM read-during-write behaviour warning. +set_qip_strings { "set_instance_assignment -name MESSAGE_DISABLE 276027 -entity axi_dmac_burst_memory" } + +# parameters + +set group "General Configuration" + +add_parameter ID INTEGER 0 +set_parameter_property ID DISPLAY_NAME "Core ID" +set_parameter_property ID HDL_PARAMETER true +set_parameter_property ID GROUP $group + +add_parameter DMA_LENGTH_WIDTH INTEGER 24 +set_parameter_property DMA_LENGTH_WIDTH DISPLAY_NAME "DMA Transfer Length Register Width" +set_parameter_property DMA_LENGTH_WIDTH UNITS Bits +set_parameter_property DMA_LENGTH_WIDTH HDL_PARAMETER true +set_parameter_property DMA_LENGTH_WIDTH ALLOWED_RANGES {8:32} +set_parameter_property DMA_LENGTH_WIDTH GROUP $group + +add_parameter FIFO_SIZE INTEGER 8 +set_parameter_property FIFO_SIZE DISPLAY_NAME "Store-and-Forward Memory Size (In Bursts)" +set_parameter_property FIFO_SIZE HDL_PARAMETER true +set_parameter_property FIFO_SIZE ALLOWED_RANGES {2 4 8 16 32} +set_parameter_property FIFO_SIZE GROUP $group + +add_parameter MAX_BYTES_PER_BURST INTEGER 128 +set_parameter_property MAX_BYTES_PER_BURST DISPLAY_NAME "Maximum bytes per burst" +set_parameter_property MAX_BYTES_PER_BURST HDL_PARAMETER true +set_parameter_property MAX_BYTES_PER_BURST GROUP $group + +foreach {suffix group} { \ + "SRC" "Source" \ + "DEST" "Destination" \ + } { + + add_display_item "Endpoint Configuration" $group "group" + + add_parameter DMA_TYPE_$suffix INTEGER 0 + set_parameter_property DMA_TYPE_$suffix DISPLAY_NAME "Type" + set_parameter_property DMA_TYPE_$suffix HDL_PARAMETER true + set_parameter_property DMA_TYPE_$suffix ALLOWED_RANGES \ + { "0:Memory-Mapped AXI" "1:Streaming AXI" "2:FIFO Interface" } + set_parameter_property DMA_TYPE_$suffix GROUP $group + + add_parameter DMA_AXI_PROTOCOL_$suffix INTEGER 1 + set_parameter_property DMA_AXI_PROTOCOL_$suffix DISPLAY_NAME "AXI Protocol" + set_parameter_property DMA_AXI_PROTOCOL_$suffix HDL_PARAMETER true + set_parameter_property DMA_AXI_PROTOCOL_$suffix ALLOWED_RANGES { "0:AXI4" "1:AXI3" } + set_parameter_property DMA_AXI_PROTOCOL_$suffix GROUP $group + + add_parameter DMA_DATA_WIDTH_$suffix INTEGER 64 + set_parameter_property DMA_DATA_WIDTH_$suffix DISPLAY_NAME "Bus Width" + set_parameter_property DMA_DATA_WIDTH_$suffix UNITS Bits + set_parameter_property DMA_DATA_WIDTH_$suffix HDL_PARAMETER true + set_parameter_property DMA_DATA_WIDTH_$suffix ALLOWED_RANGES {16 32 64 128 256 512 1024} + set_parameter_property DMA_DATA_WIDTH_$suffix GROUP $group + + add_parameter USE_TLAST_$suffix INTEGER 0 + set_parameter_property USE_TLAST_$suffix DISPLAY_NAME "Use TLAST" + set_parameter_property USE_TLAST_$suffix HDL_PARAMETER false + set_parameter_property USE_TLAST_$suffix DISPLAY_HINT boolean + set_parameter_property USE_TLAST_$suffix GROUP $group + + add_parameter AXI_SLICE_$suffix INTEGER 0 + set_parameter_property AXI_SLICE_$suffix DISPLAY_NAME "Insert Register Slice" + set_parameter_property AXI_SLICE_$suffix DISPLAY_HINT boolean + set_parameter_property AXI_SLICE_$suffix HDL_PARAMETER true + set_parameter_property AXI_SLICE_$suffix GROUP $group +} + +# FIFO interface +set_parameter_property DMA_TYPE_SRC DEFAULT_VALUE 2 + +set group "Features" + +add_parameter CYCLIC INTEGER 1 +set_parameter_property CYCLIC DISPLAY_NAME "Cyclic Transfer Support" +set_parameter_property CYCLIC DISPLAY_HINT boolean +set_parameter_property CYCLIC HDL_PARAMETER true +set_parameter_property CYCLIC GROUP $group + +add_parameter DMA_2D_TRANSFER INTEGER 0 +set_parameter_property DMA_2D_TRANSFER DISPLAY_NAME "2D Transfer Support" +set_parameter_property DMA_2D_TRANSFER DISPLAY_HINT boolean +set_parameter_property DMA_2D_TRANSFER HDL_PARAMETER true +set_parameter_property DMA_2D_TRANSFER GROUP $group + +add_parameter SYNC_TRANSFER_START INTEGER 0 +set_parameter_property SYNC_TRANSFER_START DISPLAY_NAME "Transfer Start Synchronization Support" +set_parameter_property SYNC_TRANSFER_START DISPLAY_HINT boolean +set_parameter_property SYNC_TRANSFER_START HDL_PARAMETER true +set_parameter_property SYNC_TRANSFER_START GROUP $group + +set group "Clock Domain Configuration" + +add_parameter AUTO_ASYNC_CLK BOOLEAN 1 +set_parameter_property AUTO_ASYNC_CLK DISPLAY_NAME "Automatically Detect Clock Domains" +set_parameter_property AUTO_ASYNC_CLK HDL_PARAMETER false +set_parameter_property AUTO_ASYNC_CLK GROUP $group + +foreach {p name} { \ + ASYNC_CLK_REQ_SRC "Request and Source" \ + ASYNC_CLK_SRC_DEST "Source and Destination" \ + ASYNC_CLK_DEST_REQ "Destination and Request" \ + } { + + add_parameter ${p}_MANUAL INTEGER 1 + set_parameter_property ${p}_MANUAL DISPLAY_NAME [concat $name "Clock Asynchronous"] + set_parameter_property ${p}_MANUAL DISPLAY_HINT boolean + set_parameter_property ${p}_MANUAL HDL_PARAMETER false + set_parameter_property ${p}_MANUAL VISIBLE false + set_parameter_property ${p}_MANUAL GROUP $group + + add_parameter $p INTEGER 1 + set_parameter_property $p DISPLAY_NAME [concat $name "Clock Asynchronous"] + set_parameter_property $p DISPLAY_HINT boolean + set_parameter_property $p HDL_PARAMETER true + set_parameter_property $p DERIVED true + set_parameter_property $p GROUP $group +} + +add_parameter CLK_DOMAIN_REQ INTEGER +set_parameter_property CLK_DOMAIN_REQ HDL_PARAMETER false +set_parameter_property CLK_DOMAIN_REQ SYSTEM_INFO {CLOCK_DOMAIN s_axi_clock} +set_parameter_property CLK_DOMAIN_REQ VISIBLE false +set_parameter_property CLK_DOMAIN_REQ GROUP $group + +set src_clks { \ + {CLK_DOMAIN_SRC_AXI m_src_axi_clock} \ + {CLK_DOMAIN_SRC_SAXI if_s_axis_aclk} \ + {CLK_DOMAIN_SRC_FIFO if_fifo_wr_clk} \ +} + +set dest_clks { \ + {CLK_DOMAIN_DEST_AXI m_dest_axi_clock} \ + {CLK_DOMAIN_DEST_SAXI if_m_axis_aclk} \ + {CLK_DOMAIN_DEST_FIFO if_fifo_rd_clk} \ +} + +foreach domain [list {*}$src_clks {*}$dest_clks] { + lassign $domain p clk + add_parameter $p INTEGER + set_parameter_property $p HDL_PARAMETER false + set_parameter_property $p SYSTEM_INFO [list CLOCK_DOMAIN $clk] + set_parameter_property $p VISIBLE false + set_parameter_property $p GROUP $group +} + +# axi4 slave + +ad_ip_intf_s_axi s_axi_aclk s_axi_aresetn 12 + +add_interface interrupt_sender interrupt end +set_interface_property interrupt_sender associatedAddressablePoint s_axi +set_interface_property interrupt_sender associatedClock s_axi_clock +set_interface_property interrupt_sender associatedReset s_axi_reset +set_interface_property interrupt_sender ENABLED true +set_interface_property interrupt_sender EXPORT_OF "" +set_interface_property interrupt_sender PORT_NAME_MAP "" +set_interface_property interrupt_sender CMSIS_SVD_VARIABLES "" +set_interface_property interrupt_sender SVD_ADDRESS_GROUP "" + +add_interface_port interrupt_sender irq irq Output 1 + +proc axi_dmac_validate {} { + set auto_clk [get_parameter_value AUTO_ASYNC_CLK] + set type_src [get_parameter_value DMA_TYPE_SRC] + set type_dest [get_parameter_value DMA_TYPE_DEST] + + set max_burst 32768 + + if {$auto_clk == true} { + global src_clks dest_clks + + set req_domain [get_parameter_value CLK_DOMAIN_REQ] + set src_domain [get_parameter_value [lindex $src_clks $type_src 0]] + set dest_domain [get_parameter_value [lindex $dest_clks $type_dest 0]] + + if {$req_domain != 0 && $req_domain == $src_domain} { + set_parameter_value ASYNC_CLK_REQ_SRC 0 + } else { + set_parameter_value ASYNC_CLK_REQ_SRC 1 + } + + if {$src_domain != 0 && $src_domain == $dest_domain} { + set_parameter_value ASYNC_CLK_SRC_DEST 0 + } else { + set_parameter_value ASYNC_CLK_SRC_DEST 1 + } + + if {$dest_domain != 0 && $dest_domain == $req_domain} { + set_parameter_value ASYNC_CLK_DEST_REQ 0 + } else { + set_parameter_value ASYNC_CLK_DEST_REQ 1 + } + } else { + foreach p {ASYNC_CLK_REQ_SRC ASYNC_CLK_SRC_DEST ASYNC_CLK_DEST_REQ} { + set_parameter_value $p [get_parameter_value ${p}_MANUAL] + } + } + + foreach p {ASYNC_CLK_REQ_SRC ASYNC_CLK_SRC_DEST ASYNC_CLK_DEST_REQ} { + set_parameter_property ${p}_MANUAL VISIBLE [expr $auto_clk ? false : true] + set_parameter_property $p VISIBLE $auto_clk + } + foreach suffix {SRC DEST} { + if {[get_parameter_value DMA_TYPE_$suffix] == 0} { + set show_axi_protocol true + set proto [get_parameter_value DMA_AXI_PROTOCOL_$suffix] + set width [get_parameter_value DMA_DATA_WIDTH_$suffix] + if {$proto == 0} { + set max_burst [expr min($max_burst, $width * 256 / 8)] + } else { + set max_burst [expr min($max_burst, $width * 16 / 8)] + } + } else { + set show_axi_protocol false + } + set_parameter_property DMA_AXI_PROTOCOL_$suffix VISIBLE $show_axi_protocol + } + + foreach suffix {SRC DEST} { + if {[get_parameter_value DMA_TYPE_$suffix] == 1} { + set_parameter_property USE_TLAST_$suffix VISIBLE true + } else { + set_parameter_property USE_TLAST_$suffix VISIBLE false + } + } + set_parameter_property MAX_BYTES_PER_BURST ALLOWED_RANGES "1:$max_burst" +} + +# conditional interfaces + +# axi4 destination/source + +add_interface m_dest_axi_clock clock end +add_interface_port m_dest_axi_clock m_dest_axi_aclk clk Input 1 + +add_interface m_dest_axi_reset reset end +set_interface_property m_dest_axi_reset associatedClock m_dest_axi_clock +add_interface_port m_dest_axi_reset m_dest_axi_aresetn reset_n Input 1 + + +add_interface m_src_axi_clock clock end +add_interface_port m_src_axi_clock m_src_axi_aclk clk Input 1 + +add_interface m_src_axi_reset reset end +set_interface_property m_src_axi_reset associatedClock m_src_axi_clock +add_interface_port m_src_axi_reset m_src_axi_aresetn reset_n Input 1 + +# axis destination/source + +ad_alt_intf clock m_axis_aclk input 1 clk +ad_alt_intf signal m_axis_valid output 1 valid +ad_alt_intf signal m_axis_data output DMA_DATA_WIDTH_DEST data +ad_alt_intf signal m_axis_ready input 1 ready +ad_alt_intf signal m_axis_last output 1 last +ad_alt_intf signal m_axis_xfer_req output 1 xfer_req + +ad_alt_intf clock s_axis_aclk input 1 clk +ad_alt_intf signal s_axis_valid input 1 valid +ad_alt_intf signal s_axis_data input DMA_DATA_WIDTH_SRC data +ad_alt_intf signal s_axis_ready output 1 ready +ad_alt_intf signal s_axis_last input 1 last +ad_alt_intf signal s_axis_xfer_req output 1 xfer_req +ad_alt_intf signal s_axis_user input 1 user + +# fifo destination/source + +ad_alt_intf clock fifo_rd_clk input 1 clk +ad_alt_intf signal fifo_rd_en input 1 valid +ad_alt_intf signal fifo_rd_valid output 1 valid +ad_alt_intf signal fifo_rd_dout output DMA_DATA_WIDTH_DEST data +ad_alt_intf signal fifo_rd_underflow output 1 unf +ad_alt_intf signal fifo_rd_xfer_req output 1 xfer_req + +ad_alt_intf clock fifo_wr_clk input 1 clk +ad_alt_intf signal fifo_wr_en input 1 valid +ad_alt_intf signal fifo_wr_din input DMA_DATA_WIDTH_SRC data +ad_alt_intf signal fifo_wr_overflow output 1 ovf +ad_alt_intf signal fifo_wr_sync input 1 sync +ad_alt_intf signal fifo_wr_xfer_req output 1 xfer_req + +proc add_axi_master_interface {axi_type port suffix} { + add_interface $port $axi_type start + set_interface_property $port associatedClock ${port}_clock + set_interface_property $port associatedReset ${port}_reset + set_interface_property $port readIssuingCapability 1 + add_interface_port $port ${port}_awvalid awvalid Output 1 + add_interface_port $port ${port}_awaddr awaddr Output 32 + add_interface_port $port ${port}_awready awready Input 1 + add_interface_port $port ${port}_wvalid wvalid Output 1 + add_interface_port $port ${port}_wdata wdata Output DMA_DATA_WIDTH_${suffix} + add_interface_port $port ${port}_wstrb wstrb Output DMA_DATA_WIDTH_${suffix}/8 + add_interface_port $port ${port}_wready wready Input 1 + add_interface_port $port ${port}_bvalid bvalid Input 1 + add_interface_port $port ${port}_bresp bresp Input 2 + add_interface_port $port ${port}_bready bready Output 1 + add_interface_port $port ${port}_arvalid arvalid Output 1 + add_interface_port $port ${port}_araddr araddr Output 32 + add_interface_port $port ${port}_arready arready Input 1 + add_interface_port $port ${port}_rvalid rvalid Input 1 + add_interface_port $port ${port}_rresp rresp Input 2 + add_interface_port $port ${port}_rdata rdata Input DMA_DATA_WIDTH_${suffix} + add_interface_port $port ${port}_rready rready Output 1 + add_interface_port $port ${port}_awlen awlen Output "8-(4*DMA_AXI_PROTOCOL_${suffix})" + add_interface_port $port ${port}_awsize awsize Output 3 + add_interface_port $port ${port}_awburst awburst Output 2 + add_interface_port $port ${port}_awcache awcache Output 4 + add_interface_port $port ${port}_awprot awprot Output 3 + add_interface_port $port ${port}_wlast wlast Output 1 + add_interface_port $port ${port}_arlen arlen Output "8-(4*DMA_AXI_PROTOCOL_${suffix})" + add_interface_port $port ${port}_arsize arsize Output 3 + add_interface_port $port ${port}_arburst arburst Output 2 + add_interface_port $port ${port}_arcache arcache Output 4 + add_interface_port $port ${port}_arprot arprot Output 3 + # Some signals are mandatory in Altera's implementation of AXI3 + # awid, awlock, wid, bid, arid, arlock, rid, rlast + # Hide them in AXI4 + add_interface_port $port ${port}_awid awid Output 1 + add_interface_port $port ${port}_awlock awlock Output "1+DMA_AXI_PROTOCOL_${suffix}" + add_interface_port $port ${port}_wid wid Output 1 + add_interface_port $port ${port}_arid arid Output 1 + add_interface_port $port ${port}_arlock arlock Output "1+DMA_AXI_PROTOCOL_${suffix}" + add_interface_port $port ${port}_rid rid Input 1 + add_interface_port $port ${port}_bid bid Input 1 + add_interface_port $port ${port}_rlast rlast Input 1 + if {$axi_type == "axi4"} { + set_port_property ${port}_awid TERMINATION true + set_port_property ${port}_awlock TERMINATION true + set_port_property ${port}_wid TERMINATION true + set_port_property ${port}_arid TERMINATION true + set_port_property ${port}_arlock TERMINATION true + set_port_property ${port}_rid TERMINATION true + set_port_property ${port}_bid TERMINATION true + if {$port == "m_dest_axi"} { + set_port_property ${port}_rlast TERMINATION true + } + } +} +proc axi_dmac_elaborate {} { + set fifo_size [get_parameter_value FIFO_SIZE] + set disabled_intfs {} + + # add axi3 or axi4 interface depending on user selection + foreach {suffix port} {SRC m_src_axi DEST m_dest_axi} { + if {[get_parameter_value DMA_AXI_PROTOCOL_${suffix}] == 0} { + set axi_type axi4 + } else { + set axi_type axi + } + add_axi_master_interface $axi_type $port $suffix + } + + # axi4 destination/source + + if {[get_parameter_value DMA_TYPE_DEST] == 0} { + set_interface_property m_dest_axi writeIssuingCapability $fifo_size + set_interface_property m_dest_axi combinedIssuingCapability $fifo_size + } else { + lappend disabled_intfs m_dest_axi_clock m_dest_axi_reset m_dest_axi + } + + if {[get_parameter_value DMA_TYPE_SRC] == 0} { + set_interface_property m_src_axi readIssuingCapability $fifo_size + set_interface_property m_src_axi combinedIssuingCapability $fifo_size + } else { + lappend disabled_intfs m_src_axi_clock m_src_axi_reset m_src_axi + } + + # axis destination/source + + if {[get_parameter_value DMA_TYPE_DEST] != 1} { + lappend disabled_intfs \ + if_m_axis_aclk if_m_axis_valid if_m_axis_data if_m_axis_ready \ + if_m_axis_last if_m_axis_xfer_req + } + + if {[get_parameter_value DMA_TYPE_DEST] == 1 && + [get_parameter_value USE_TLAST_DEST] == 0} { + set_port_property m_axis_last termination true + } + + if {[get_parameter_value DMA_TYPE_SRC] != 1} { + lappend disabled_intfs \ + if_s_axis_aclk if_s_axis_valid if_s_axis_data if_s_axis_ready \ + if_s_axis_xfer_req if_s_axis_user if_s_axis_last + } + + if {[get_parameter_value DMA_TYPE_SRC] == 1 && + [get_parameter_value SYNC_TRANSFER_START] == 0} { + set_port_property s_axis_user termination true + set_port_property s_axis_user termination_value 1 + } + + if {[get_parameter_value DMA_TYPE_SRC] == 1 && + [get_parameter_value USE_TLAST_SRC] == 0} { + set_port_property s_axis_last termination true + set_port_property s_axis_last termination_value 0 + } + + # fifo destination/source + + if {[get_parameter_value DMA_TYPE_DEST] != 2} { + lappend disabled_intfs \ + if_fifo_rd_clk if_fifo_rd_en if_fifo_rd_valid if_fifo_rd_dout \ + if_fifo_rd_underflow if_fifo_rd_xfer_req + } + + if {[get_parameter_value DMA_TYPE_SRC] != 2} { + lappend disabled_intfs \ + if_fifo_wr_clk if_fifo_wr_en if_fifo_wr_din if_fifo_wr_overflow \ + if_fifo_wr_sync if_fifo_wr_xfer_req + } + + if {[get_parameter_value DMA_TYPE_SRC] == 2 && + [get_parameter_value SYNC_TRANSFER_START] == 0} { + set_port_property fifo_wr_sync termination true + set_port_property fifo_wr_sync termination_value 1 + } + + if {[get_parameter_value ENABLE_DIAGNOSTICS_IF] != 1} { + lappend disabled_intfs diagnostics_if + } + + foreach intf $disabled_intfs { + set_interface_property $intf ENABLED false + } +} + +set group "Debug" + +add_parameter DISABLE_DEBUG_REGISTERS INTEGER 0 +set_parameter_property DISABLE_DEBUG_REGISTERS DISPLAY_NAME "Disable debug registers" +set_parameter_property DISABLE_DEBUG_REGISTERS DISPLAY_HINT boolean +set_parameter_property DISABLE_DEBUG_REGISTERS HDL_PARAMETER false +set_parameter_property DISABLE_DEBUG_REGISTERS GROUP $group + +add_parameter ENABLE_DIAGNOSTICS_IF INTEGER 0 +set_parameter_property ENABLE_DIAGNOSTICS_IF DISPLAY_NAME "Enable Diagnostics Interface" +set_parameter_property ENABLE_DIAGNOSTICS_IF DISPLAY_HINT boolean +set_parameter_property ENABLE_DIAGNOSTICS_IF HDL_PARAMETER true +set_parameter_property ENABLE_DIAGNOSTICS_IF GROUP $group + +add_interface diagnostics_if conduit end +add_interface_port diagnostics_if dest_diag_level_bursts dest_diag_level_bursts Output "8" diff --git a/src/adi/hdl/library/axi_dmac/axi_dmac_ip.tcl b/src/adi/hdl/library/axi_dmac/axi_dmac_ip.tcl new file mode 100644 index 00000000..7e831347 --- /dev/null +++ b/src/adi/hdl/library/axi_dmac/axi_dmac_ip.tcl @@ -0,0 +1,400 @@ +# ip + +source ../scripts/adi_env.tcl +source $ad_hdl_dir/library/scripts/adi_ip.tcl + +adi_ip_create axi_dmac +adi_ip_files axi_dmac [list \ + "$ad_hdl_dir/library/common/ad_mem.v" \ + "$ad_hdl_dir/library/common/up_axi.v" \ + "inc_id.vh" \ + "resp.vh" \ + "axi_dmac_burst_memory.v" \ + "axi_dmac_regmap.v" \ + "axi_dmac_regmap_request.v" \ + "axi_dmac_reset_manager.v" \ + "axi_dmac_resize_dest.v" \ + "axi_dmac_resize_src.v" \ + "axi_dmac_response_manager.v" \ + "axi_dmac_transfer.v" \ + "address_generator.v" \ + "data_mover.v" \ + "request_arb.v" \ + "request_generator.v" \ + "response_handler.v" \ + "axi_register_slice.v" \ + "2d_transfer.v" \ + "dest_axi_mm.v" \ + "dest_axi_stream.v" \ + "dest_fifo_inf.v" \ + "src_axi_mm.v" \ + "src_axi_stream.v" \ + "src_fifo_inf.v" \ + "splitter.v" \ + "response_generator.v" \ + "axi_dmac.v" \ + "axi_dmac_constr.ttcl" \ + "axi_dmac_pkg_sv.ttcl" \ + "bd/bd.tcl" ] + +adi_ip_properties axi_dmac +adi_ip_infer_mm_interfaces axi_dmac +adi_ip_ttcl axi_dmac "axi_dmac_constr.ttcl" +adi_ip_sim_ttcl axi_dmac "axi_dmac_pkg_sv.ttcl" +adi_ip_bd axi_dmac "bd/bd.tcl" + +adi_ip_add_core_dependencies { \ + analog.com:user:util_axis_fifo:1.0 \ + analog.com:user:util_cdc:1.0 \ +} + +set_property display_name "ADI AXI DMA Controller" [ipx::current_core] +set_property description "ADI AXI DMA Controller" [ipx::current_core] + +adi_add_bus "s_axis" "slave" \ + "xilinx.com:interface:axis_rtl:1.0" \ + "xilinx.com:interface:axis:1.0" \ + [list {"s_axis_ready" "TREADY"} \ + {"s_axis_valid" "TVALID"} \ + {"s_axis_data" "TDATA"} \ + {"s_axis_last" "TLAST"} \ + {"s_axis_user" "TUSER"} ] +adi_add_bus_clock "s_axis_aclk" "s_axis" + +adi_add_bus "m_axis" "master" \ + "xilinx.com:interface:axis_rtl:1.0" \ + "xilinx.com:interface:axis:1.0" \ + [list {"m_axis_ready" "TREADY"} \ + {"m_axis_valid" "TVALID"} \ + {"m_axis_data" "TDATA"} \ + {"m_axis_last" "TLAST"} ] +adi_add_bus_clock "m_axis_aclk" "m_axis" + +adi_set_bus_dependency "m_src_axi" "m_src_axi" \ + "(spirit:decode(id('MODELPARAM_VALUE.DMA_TYPE_SRC')) = 0)" +adi_set_bus_dependency "m_dest_axi" "m_dest_axi" \ + "(spirit:decode(id('MODELPARAM_VALUE.DMA_TYPE_DEST')) = 0)" +adi_set_bus_dependency "s_axis" "s_axis" \ + "(spirit:decode(id('MODELPARAM_VALUE.DMA_TYPE_SRC')) = 1)" +adi_set_bus_dependency "m_axis" "m_axis" \ + "(spirit:decode(id('MODELPARAM_VALUE.DMA_TYPE_DEST')) = 1)" +adi_set_ports_dependency "fifo_rd" \ + "(spirit:decode(id('MODELPARAM_VALUE.DMA_TYPE_DEST')) = 2)" +adi_set_ports_dependency "dest_diag_level_bursts" \ + "(spirit:decode(id('MODELPARAM_VALUE.ENABLE_DIAGNOSTICS_IF')) = 1)" + +# These are in the design to keep the Altera tools happy which can't handle +# uni-directional AXI interfaces. The Xilinx tools can and do a better job when +# they know that the interface is uni-directional, so disable the ports. +set dummy_axi_ports [list \ + "m_dest_axi_arvalid" \ + "m_dest_axi_arready" \ + "m_dest_axi_araddr" \ + "m_dest_axi_arlen" \ + "m_dest_axi_arsize" \ + "m_dest_axi_arburst" \ + "m_dest_axi_arcache" \ + "m_dest_axi_arprot" \ + "m_dest_axi_rready" \ + "m_dest_axi_rvalid" \ + "m_dest_axi_rresp" \ + "m_dest_axi_rdata" \ + "m_src_axi_awvalid" \ + "m_src_axi_awready" \ + "m_src_axi_awvalid" \ + "m_src_axi_awaddr" \ + "m_src_axi_awlen" \ + "m_src_axi_awsize" \ + "m_src_axi_awburst" \ + "m_src_axi_awcache" \ + "m_src_axi_awprot" \ + "m_src_axi_wvalid" \ + "m_src_axi_wready" \ + "m_src_axi_wvalid" \ + "m_src_axi_wdata" \ + "m_src_axi_wstrb" \ + "m_src_axi_wlast" \ + "m_src_axi_bready" \ + "m_src_axi_bvalid" \ + "m_src_axi_bresp" \ +] + +# These are in the design to keep the Altera tools happy which require +# certain signals in AXI3 mode even if these are defined as optinal in the standard. +lappend dummy_axi_ports \ + "m_dest_axi_awid" \ + "m_dest_axi_awlock" \ + "m_dest_axi_wid" \ + "m_dest_axi_bid" \ + "m_dest_axi_arid" \ + "m_dest_axi_arlock" \ + "m_dest_axi_rid" \ + "m_dest_axi_rlast" \ + "m_src_axi_arid" \ + "m_src_axi_arlock" \ + "m_src_axi_rid" \ + "m_src_axi_awid" \ + "m_src_axi_awlock" \ + "m_src_axi_wid" \ + "m_src_axi_bid" + + +foreach p $dummy_axi_ports { + adi_set_ports_dependency $p "false" +} + +set_property master_address_space_ref m_dest_axi \ + [ipx::get_bus_interfaces m_dest_axi \ + -of_objects [ipx::current_core]] +set_property master_address_space_ref m_src_axi \ + [ipx::get_bus_interfaces m_src_axi \ + -of_objects [ipx::current_core]] + +adi_add_bus "fifo_wr" "slave" \ + "analog.com:interface:fifo_wr_rtl:1.0" \ + "analog.com:interface:fifo_wr:1.0" \ + { \ + {"fifo_wr_en" "EN"} \ + {"fifo_wr_din" "DATA"} \ + {"fifo_wr_overflow" "OVERFLOW"} \ + {"fifo_wr_sync" "SYNC"} \ + {"fifo_wr_xfer_req" "XFER_REQ"} \ + } + +adi_add_bus_clock "fifo_wr_clk" "fifo_wr" + +adi_set_bus_dependency "fifo_wr" "fifo_wr" \ + "(spirit:decode(id('MODELPARAM_VALUE.DMA_TYPE_SRC')) = 2)" + +adi_add_bus "fifo_rd" "slave" \ + "analog.com:interface:fifo_rd_rtl:1.0" \ + "analog.com:interface:fifo_rd:1.0" \ + { + {"fifo_rd_en" "EN"} \ + {"fifo_rd_dout" "DATA"} \ + {"fifo_rd_valid" "VALID"} \ + {"fifo_rd_underflow" "UNDERFLOW"} \ + } + +adi_add_bus_clock "fifo_rd_clk" "fifo_rd" + +adi_set_bus_dependency "fifo_rd" "fifo_rd" \ + "(spirit:decode(id('MODELPARAM_VALUE.DMA_TYPE_DEST')) = 2)" + +foreach port {"m_dest_axi_aresetn" "m_src_axi_aresetn" \ + "s_axis_valid" "s_axis_data" "s_axis_last" "m_axis_ready" \ + "fifo_wr_en" "fifo_wr_din" "fifo_rd_en"} { + set_property DRIVER_VALUE "0" [ipx::get_ports $port] +} + +foreach port {"s_axis_user" "fifo_wr_sync"} { + set_property DRIVER_VALUE "1" [ipx::get_ports $port] +} + +# Infer interrupt +ipx::infer_bus_interface irq xilinx.com:signal:interrupt_rtl:1.0 [ipx::current_core] + +set cc [ipx::current_core] + +# The core does not issue narrow bursts +foreach intf [ipx::get_bus_interfaces m_*_axi -of_objects $cc] { + set para [ipx::add_bus_parameter SUPPORTS_NARROW_BURST $intf] + set_property "VALUE" "0" $para +} + +set_property -dict [list \ + "value_validation_type" "list" \ + "value_validation_list" "2 4 8 16 32" \ + ] \ + [ipx::get_user_parameters FIFO_SIZE -of_objects $cc] + +set_property -dict [list \ + "value_validation_type" "range_long" \ + "value_validation_range_minimum" "8" \ + "value_validation_range_maximum" "32" \ + ] \ + [ipx::get_user_parameters DMA_LENGTH_WIDTH -of_objects $cc] + +foreach {k v} { \ + "ASYNC_CLK_REQ_SRC" "true" \ + "ASYNC_CLK_SRC_DEST" "true" \ + "ASYNC_CLK_DEST_REQ" "true" \ + "CYCLIC" "false" \ + "DMA_2D_TRANSFER" "false" \ + "SYNC_TRANSFER_START" "false" \ + "AXI_SLICE_SRC" "false" \ + "AXI_SLICE_DEST" "false" \ + "DISABLE_DEBUG_REGISTERS" "false" \ + "ENABLE_DIAGNOSTICS_IF" "false" \ + } { \ + set_property -dict [list \ + "value_format" "bool" \ + "value" $v \ + ] \ + [ipx::get_user_parameters $k -of_objects $cc] + set_property -dict [list \ + "value_format" "bool" \ + "value" $v \ + ] \ + [ipx::get_hdl_parameters $k -of_objects $cc] +} + +set_property -dict [list \ + "enablement_tcl_expr" "\$DMA_TYPE_SRC != 0" \ +] \ +[ipx::get_user_parameters SYNC_TRANSFER_START -of_objects $cc] + +foreach dir {"SRC" "DEST"} { + set_property -dict [list \ + "value_validation_type" "list" \ + "value_validation_list" "16 32 64 128 256 512 1024" \ + ] \ + [ipx::get_user_parameters DMA_DATA_WIDTH_${dir} -of_objects $cc] + + set_property -dict [list \ + "value_validation_type" "pairs" \ + "value_validation_pairs" {"AXI3" "1" "AXI4" "0"} \ + "enablement_tcl_expr" "\$DMA_TYPE_${dir} == 0" \ + ] \ + [ipx::get_user_parameters DMA_AXI_PROTOCOL_${dir} -of_objects $cc] + + set_property -dict [list \ + "value_validation_type" "pairs" \ + "value_validation_pairs" { \ + "Memory-Mapped AXI" "0" \ + "Streaming AXI" "1" \ + "FIFO Interface" "2" \ + } \ + ] \ + [ipx::get_user_parameters DMA_TYPE_${dir} -of_objects $cc] +} + +set page0 [ipgui::get_pagespec -name "Page 0" -component $cc] +set g [ipgui::add_group -name {DMA Endpoint Configuration} -component $cc \ + -parent $page0 -display_name {DMA Endpoint Configuration} \ + -layout "horizontal"] +set src_group [ipgui::add_group -name {Source} -component $cc -parent $g \ + -display_name {Source}] +set dest_group [ipgui::add_group -name {Destination} -component $cc -parent $g \ + -display_name {Destination}] + +foreach {dir group} [list "SRC" $src_group "DEST" $dest_group] { + set p [ipgui::get_guiparamspec -name "DMA_TYPE_${dir}" -component $cc] + ipgui::move_param -component $cc -order 0 $p -parent $group + set_property -dict [list \ + "widget" "comboBox" \ + "display_name" "Type" \ + ] $p + + set p [ipgui::get_guiparamspec -name "DMA_AXI_PROTOCOL_${dir}" -component $cc] + ipgui::move_param -component $cc -order 1 $p -parent $group + set_property -dict [list \ + "widget" "comboBox" \ + "display_name" "AXI Protocol" \ + ] $p + + set p [ipgui::get_guiparamspec -name "DMA_DATA_WIDTH_${dir}" -component $cc] + ipgui::move_param -component $cc -order 2 $p -parent $group + set_property -dict [list \ + "display_name" "Bus Width" \ + ] $p + + set p [ipgui::get_guiparamspec -name "AXI_SLICE_${dir}" -component $cc] + ipgui::move_param -component $cc -order 3 $p -parent $group + set_property -dict [list \ + "display_name" "Insert Register Slice" \ + ] $p +} + +set p [ipgui::get_guiparamspec -name "SYNC_TRANSFER_START" -component $cc] +ipgui::move_param -component $cc -order 4 $p -parent $src_group +set_property -dict [list \ + "display_name" "Transfer Start Synchronization Support" \ +] $p + +set general_group [ipgui::add_group -name "General Configuration" -component $cc \ + -parent $page0 -display_name "General Configuration"] + +set p [ipgui::get_guiparamspec -name "ID" -component $cc] +ipgui::move_param -component $cc -order 0 $p -parent $general_group +set_property -dict [list \ + "display_name" "Core ID" \ +] $p + +set p [ipgui::get_guiparamspec -name "DMA_LENGTH_WIDTH" -component $cc] +ipgui::move_param -component $cc -order 1 $p -parent $general_group +set_property -dict [list \ + "display_name" "DMA Transfer Length Register Width" \ +] $p + +set p [ipgui::get_guiparamspec -name "FIFO_SIZE" -component $cc] +ipgui::move_param -component $cc -order 2 $p -parent $general_group +set_property -dict [list \ + "widget" "comboBox" \ + "display_name" "Store-and-Forward Memory Size (In Bursts)" \ +] $p + +set p [ipgui::get_guiparamspec -name "MAX_BYTES_PER_BURST" -component $cc] +ipgui::move_param -component $cc -order 3 $p -parent $general_group +set_property -dict [list \ + "display_name" "Maximum Bytes per Burst" \ +] $p + +set feature_group [ipgui::add_group -name "Features" -component $cc \ + -parent $page0 -display_name "Features"] + +set p [ipgui::get_guiparamspec -name "CYCLIC" -component $cc] +ipgui::move_param -component $cc -order 0 $p -parent $feature_group +set_property -dict [list \ + "display_name" "Cyclic Transfer Support" \ +] $p + +set p [ipgui::get_guiparamspec -name "DMA_2D_TRANSFER" -component $cc] +ipgui::move_param -component $cc -order 1 $p -parent $feature_group +set_property -dict [list \ + "display_name" "2D Transfer Support" \ +] $p + +set clk_group [ipgui::add_group -name {Clock Domain Configuration} -component $cc \ + -parent $page0 -display_name {Clock Domain Configuration}] + +set p [ipgui::get_guiparamspec -name "ASYNC_CLK_REQ_SRC" -component $cc] +ipgui::move_param -component $cc -order 0 $p -parent $clk_group +set_property -dict [list \ + "display_name" "Request and Source Clock Asynchronous" \ +] $p + +set p [ipgui::get_guiparamspec -name "ASYNC_CLK_SRC_DEST" -component $cc] +ipgui::move_param -component $cc -order 1 $p -parent $clk_group +set_property -dict [list \ + "display_name" "Source and Destination Clock Asynchronous" \ +] $p + +set p [ipgui::get_guiparamspec -name "ASYNC_CLK_DEST_REQ" -component $cc] +ipgui::move_param -component $cc -order 2 $p -parent $clk_group +set_property -dict [list \ + "display_name" "Destination and Request Clock Asynchronous" \ +] $p + +set dbg_group [ipgui::add_group -name {Debug} -component $cc \ + -parent $page0 -display_name {Debug}] + +set p [ipgui::get_guiparamspec -name "DISABLE_DEBUG_REGISTERS" -component $cc] +ipgui::move_param -component $cc -order 0 $p -parent $dbg_group +set_property -dict [list \ + "display_name" "Disable Debug Registers" \ +] $p + +set p [ipgui::get_guiparamspec -name "ENABLE_DIAGNOSTICS_IF" -component $cc] +ipgui::move_param -component $cc -order 1 $p -parent $dbg_group +set_property -dict [list \ + "display_name" "Enable Diagnostics Interface" \ +] $p + +ipgui::remove_param -component $cc [ipgui::get_guiparamspec -name "DMA_AXI_ADDR_WIDTH" -component $cc] +ipgui::remove_param -component $cc [ipgui::get_guiparamspec -name "AXI_ID_WIDTH_SRC" -component $cc] +ipgui::remove_param -component $cc [ipgui::get_guiparamspec -name "AXI_ID_WIDTH_DEST" -component $cc] + + +ipx::create_xgui_files [ipx::current_core] +ipx::save_core $cc diff --git a/src/adi/hdl/library/axi_dmac/axi_dmac_pkg_sv.ttcl b/src/adi/hdl/library/axi_dmac/axi_dmac_pkg_sv.ttcl new file mode 100644 index 00000000..30572ad0 --- /dev/null +++ b/src/adi/hdl/library/axi_dmac/axi_dmac_pkg_sv.ttcl @@ -0,0 +1,64 @@ +<: :> +<: set ComponentName [getComponentNameString] :> +<: setOutputDirectory "./sim/" :> +<: setFileName ${ComponentName}_pkg :> +<: setFileExtension ".sv" :> +<: set id [get_property MODELPARAM_VALUE.ID] :> +<: set dma_data_width_src [get_property MODELPARAM_VALUE.DMA_DATA_WIDTH_SRC] :> +<: set dma_data_width_dest [get_property MODELPARAM_VALUE.DMA_DATA_WIDTH_DEST] :> +<: set dma_length_width [get_property MODELPARAM_VALUE.DMA_LENGTH_WIDTH] :> +<: set dma_2d_transfer [get_property MODELPARAM_VALUE.DMA_2D_TRANSFER] :> +<: set async_clk_req_src [get_property MODELPARAM_VALUE.ASYNC_CLK_REQ_SRC] :> +<: set async_clk_src_dest [get_property MODELPARAM_VALUE.ASYNC_CLK_SRC_DEST] :> +<: set async_clk_dest_req [get_property MODELPARAM_VALUE.ASYNC_CLK_DEST_REQ] :> +<: set axi_slice_dest [get_property MODELPARAM_VALUE.AXI_SLICE_DEST] :> +<: set axi_slice_src [get_property MODELPARAM_VALUE.AXI_SLICE_SRC] :> +<: set sync_transfer_start [get_property MODELPARAM_VALUE.SYNC_TRANSFER_START] :> +<: set cyclic [get_property MODELPARAM_VALUE.CYCLIC] :> +<: set dma_axi_protocol_dest [get_property MODELPARAM_VALUE.DMA_AXI_PROTOCOL_DEST] :> +<: set dma_axi_protocol_src [get_property MODELPARAM_VALUE.DMA_AXI_PROTOCOL_SRC] :> +<: set dma_type_dest [get_property MODELPARAM_VALUE.DMA_TYPE_DEST] :> +<: set dma_type_src [get_property MODELPARAM_VALUE.DMA_TYPE_SRC] :> +<: set dma_axi_addr_width [get_property MODELPARAM_VALUE.DMA_AXI_ADDR_WIDTH] :> +<: set max_bytes_per_burst [get_property MODELPARAM_VALUE.MAX_BYTES_PER_BURST] :> +<: set fifo_size [get_property MODELPARAM_VALUE.FIFO_SIZE] :> +<: set axi_id_width_src [get_property MODELPARAM_VALUE.AXI_ID_WIDTH_SRC] :> +<: set axi_id_width_dest [get_property MODELPARAM_VALUE.AXI_ID_WIDTH_DEST] :> +<: set disable_debug_registers [get_property MODELPARAM_VALUE.DISABLE_DEBUG_REGISTERS] :> + +<: proc b2i {b} { if {$b==true} {return 1} else {return 0}} :> +/////////////////////////////////////////////////////////////////////////// +//NOTE: This file has been automatically generated by Vivado. +/////////////////////////////////////////////////////////////////////////// + +package <=: ComponentName :>_pkg; + +/////////////////////////////////////////////////////////////////////////// +// These parameters are named after the component for use in your verification +// environment. +/////////////////////////////////////////////////////////////////////////// + parameter <=: ComponentName :>_ID = <=: $id :>; + parameter <=: ComponentName :>_DMA_DATA_WIDTH_SRC = <=: $dma_data_width_src :>; + parameter <=: ComponentName :>_DMA_DATA_WIDTH_DEST = <=: $dma_data_width_dest :>; + parameter <=: ComponentName :>_DMA_LENGTH_WIDTH = <=: $dma_length_width :>; + parameter <=: ComponentName :>_DMA_2D_TRANSFER = <=: b2i $dma_2d_transfer :>; + parameter <=: ComponentName :>_ASYNC_CLK_REQ_SRC = <=: b2i $async_clk_req_src :>; + parameter <=: ComponentName :>_ASYNC_CLK_SRC_DEST = <=: b2i $async_clk_src_dest :>; + parameter <=: ComponentName :>_ASYNC_CLK_DEST_REQ = <=: b2i $async_clk_dest_req :>; + parameter <=: ComponentName :>_AXI_SLICE_DEST = <=: b2i $axi_slice_dest :>; + parameter <=: ComponentName :>_AXI_SLICE_SRC = <=: b2i $axi_slice_src :>; + parameter <=: ComponentName :>_SYNC_TRANSFER_START = <=: b2i $sync_transfer_start :>; + parameter <=: ComponentName :>_CYCLIC = <=: b2i $cyclic :>; + parameter <=: ComponentName :>_DMA_AXI_PROTOCOL_DEST = <=: $dma_axi_protocol_dest :>; + parameter <=: ComponentName :>_DMA_AXI_PROTOCOL_SRC = <=: $dma_axi_protocol_src :>; + parameter <=: ComponentName :>_DMA_TYPE_DEST = <=: $dma_type_dest :>; + parameter <=: ComponentName :>_DMA_TYPE_SRC = <=: $dma_type_src :>; + parameter <=: ComponentName :>_DMA_AXI_ADDR_WIDTH = <=: $dma_axi_addr_width :>; + parameter <=: ComponentName :>_MAX_BYTES_PER_BURST = <=: $max_bytes_per_burst :>; + parameter <=: ComponentName :>_FIFO_SIZE = <=: $fifo_size :>; + parameter <=: ComponentName :>_AXI_ID_WIDTH_SRC = <=: $axi_id_width_src :>; + parameter <=: ComponentName :>_AXI_ID_WIDTH_DEST = <=: $axi_id_width_dest :>; + parameter <=: ComponentName :>_DISABLE_DEBUG_REGISTERS = <=: b2i $disable_debug_registers :>; +////////////////////////////////////////////////////////////////////////// + +endpackage : <=: ComponentName :>_pkg diff --git a/src/adi/hdl/library/axi_dmac/axi_dmac_regmap.v b/src/adi/hdl/library/axi_dmac/axi_dmac_regmap.v new file mode 100644 index 00000000..5f8bfafb --- /dev/null +++ b/src/adi/hdl/library/axi_dmac/axi_dmac_regmap.v @@ -0,0 +1,296 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright 2014 - 2018 (c) Analog Devices, Inc. All rights reserved. +// +// In this HDL repository, there are many different and unique modules, consisting +// of various HDL (Verilog or VHDL) components. The individual modules are +// developed independently, and may be accompanied by separate and unique license +// terms. +// +// The user should read each of these license terms, and understand the +// freedoms and responsibilities that he or she has by using this source/core. +// +// This core 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. +// +// Redistribution and use of source or resulting binaries, with or without modification +// of this file, are permitted under one of the following two license terms: +// +// 1. The GNU General Public License version 2 as published by the +// Free Software Foundation, which can be found in the top level directory +// of this repository (LICENSE_GPL2), and also online at: +// +// +// OR +// +// 2. An ADI specific BSD license, which can be found in the top level directory +// of this repository (LICENSE_ADIBSD), and also on-line at: +// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD +// This will allow to generate bit files and not release the source code, +// as long as it attaches to an ADI device. +// +// *************************************************************************** +// *************************************************************************** + +`timescale 1ns/100ps + +module axi_dmac_regmap #( + parameter ID = 0, + parameter DISABLE_DEBUG_REGISTERS = 0, + parameter BYTES_PER_BEAT_WIDTH_DEST = 1, + parameter BYTES_PER_BEAT_WIDTH_SRC = 1, + parameter BYTES_PER_BURST_WIDTH = 7, + parameter DMA_AXI_ADDR_WIDTH = 32, + parameter DMA_LENGTH_WIDTH = 24, + parameter DMA_LENGTH_ALIGN = 3, + parameter DMA_CYCLIC = 0, + parameter HAS_DEST_ADDR = 1, + parameter HAS_SRC_ADDR = 1, + parameter DMA_2D_TRANSFER = 0, + parameter SYNC_TRANSFER_START = 0 +) ( + // Slave AXI interface + input s_axi_aclk, + input s_axi_aresetn, + + input s_axi_awvalid, + output s_axi_awready, + input [11:0] s_axi_awaddr, + input [2:0] s_axi_awprot, + + input s_axi_wvalid, + output s_axi_wready, + input [31:0] s_axi_wdata, + input [3:0] s_axi_wstrb, + + output s_axi_bvalid, + input s_axi_bready, + output [1:0] s_axi_bresp, + + input s_axi_arvalid, + output s_axi_arready, + input [11:0] s_axi_araddr, + input [2:0] s_axi_arprot, + + output s_axi_rvalid, + input s_axi_rready, + output [1:0] s_axi_rresp, + output [31:0] s_axi_rdata, + + // Interrupt + output reg irq, + + // Control interface + output reg ctrl_enable = 1'b0, + output reg ctrl_pause = 1'b0, + + // DMA request interface + output request_valid, + input request_ready, + output [DMA_AXI_ADDR_WIDTH-1:BYTES_PER_BEAT_WIDTH_DEST] request_dest_address, + output [DMA_AXI_ADDR_WIDTH-1:BYTES_PER_BEAT_WIDTH_SRC] request_src_address, + output [DMA_LENGTH_WIDTH-1:0] request_x_length, + output [DMA_LENGTH_WIDTH-1:0] request_y_length, + output [DMA_LENGTH_WIDTH-1:0] request_dest_stride, + output [DMA_LENGTH_WIDTH-1:0] request_src_stride, + output request_sync_transfer_start, + output request_last, + + // DMA response interface + input response_eot, + input [BYTES_PER_BURST_WIDTH-1:0] response_measured_burst_length, + input response_partial, + input response_valid, + output response_ready, + + // Debug interface + input [DMA_AXI_ADDR_WIDTH-1:0] dbg_src_addr, + input [DMA_AXI_ADDR_WIDTH-1:0] dbg_dest_addr, + input [11:0] dbg_status, + input [31:0] dbg_ids0, + input [31:0] dbg_ids1 +); + +localparam PCORE_VERSION = 'h00040261; + +// Register interface signals +reg [31:0] up_rdata = 32'h00; +reg up_wack = 1'b0; +reg up_rack = 1'b0; + +wire up_wreq; +wire up_rreq; +wire [31:0] up_wdata; +wire [8:0] up_waddr; +wire [8:0] up_raddr; +wire [31:0] up_rdata_request; + +// Scratch register +reg [31:0] up_scratch = 32'h00; + +// Start and end of transfer +wire up_eot; // Asserted for one cycle when a transfer has been completed +wire up_sot; // Asserted for one cycle when a transfer has been queued + +// Interupt handling +reg [1:0] up_irq_mask = 2'h3; +reg [1:0] up_irq_source = 2'h0; + +wire [1:0] up_irq_pending; +wire [1:0] up_irq_trigger; +wire [1:0] up_irq_source_clear; + +// IRQ handling +assign up_irq_pending = ~up_irq_mask & up_irq_source; +assign up_irq_trigger = {up_eot, up_sot}; +assign up_irq_source_clear = (up_wreq == 1'b1 && up_waddr == 9'h021) ? up_wdata[1:0] : 2'b00; + +always @(posedge s_axi_aclk) begin + if (s_axi_aresetn == 1'b0) begin + irq <= 1'b0; + end else begin + irq <= |up_irq_pending; + end +end + +always @(posedge s_axi_aclk) begin + if (s_axi_aresetn == 1'b0) begin + up_irq_source <= 2'b00; + end else begin + up_irq_source <= up_irq_trigger | (up_irq_source & ~up_irq_source_clear); + end +end + +// Register Interface + +always @(posedge s_axi_aclk) begin + if (s_axi_aresetn == 1'b0) begin + ctrl_enable <= 1'b0; + ctrl_pause <= 1'b0; + up_irq_mask <= 2'b11; + up_scratch <= 32'h00; + up_wack <= 1'b0; + end else begin + up_wack <= up_wreq; + + if (up_wreq == 1'b1) begin + case (up_waddr) + 9'h002: up_scratch <= up_wdata; + 9'h020: up_irq_mask <= up_wdata[1:0]; + 9'h100: {ctrl_pause, ctrl_enable} <= up_wdata[1:0]; + endcase + end + end +end + +always @(posedge s_axi_aclk) begin + if (s_axi_aresetn == 1'b0) begin + up_rack <= 'd0; + end else begin + up_rack <= up_rreq; + end +end + +always @(posedge s_axi_aclk) begin + if (up_rreq == 1'b1) begin + case (up_raddr) + 9'h000: up_rdata <= PCORE_VERSION; + 9'h001: up_rdata <= ID; + 9'h002: up_rdata <= up_scratch; + 9'h003: up_rdata <= 32'h444d4143; // "DMAC" + 9'h020: up_rdata <= up_irq_mask; + 9'h021: up_rdata <= up_irq_pending; + 9'h022: up_rdata <= up_irq_source; + 9'h100: up_rdata <= {ctrl_pause, ctrl_enable}; + 9'h10d: up_rdata <= DISABLE_DEBUG_REGISTERS ? 32'h00 : dbg_dest_addr; + 9'h10e: up_rdata <= DISABLE_DEBUG_REGISTERS ? 32'h00 : dbg_src_addr; + 9'h10f: up_rdata <= DISABLE_DEBUG_REGISTERS ? 32'h00 : dbg_status; + 9'h110: up_rdata <= DISABLE_DEBUG_REGISTERS ? 32'h00 : dbg_ids0; + 9'h111: up_rdata <= DISABLE_DEBUG_REGISTERS ? 32'h00 : dbg_ids1; + default: up_rdata <= up_rdata_request; + endcase + end +end + +axi_dmac_regmap_request #( + .DISABLE_DEBUG_REGISTERS(DISABLE_DEBUG_REGISTERS), + .BYTES_PER_BEAT_WIDTH_DEST(BYTES_PER_BEAT_WIDTH_DEST), + .BYTES_PER_BEAT_WIDTH_SRC(BYTES_PER_BEAT_WIDTH_SRC), + .BYTES_PER_BURST_WIDTH(BYTES_PER_BURST_WIDTH), + .DMA_AXI_ADDR_WIDTH(DMA_AXI_ADDR_WIDTH), + .DMA_LENGTH_WIDTH(DMA_LENGTH_WIDTH), + .DMA_LENGTH_ALIGN(DMA_LENGTH_ALIGN), + .DMA_CYCLIC(DMA_CYCLIC), + .HAS_DEST_ADDR(HAS_DEST_ADDR), + .HAS_SRC_ADDR(HAS_SRC_ADDR), + .DMA_2D_TRANSFER(DMA_2D_TRANSFER), + .SYNC_TRANSFER_START(SYNC_TRANSFER_START) +) i_regmap_request ( + .clk(s_axi_aclk), + .reset(~s_axi_aresetn), + + .up_sot(up_sot), + .up_eot(up_eot), + + .up_wreq(up_wreq), + .up_rreq(up_rreq), + .up_waddr(up_waddr), + .up_wdata(up_wdata), + .up_raddr(up_raddr), + .up_rdata(up_rdata_request), + + .ctrl_enable(ctrl_enable), + + .request_valid(request_valid), + .request_ready(request_ready), + .request_dest_address(request_dest_address), + .request_src_address(request_src_address), + .request_x_length(request_x_length), + .request_y_length(request_y_length), + .request_dest_stride(request_dest_stride), + .request_src_stride(request_src_stride), + .request_sync_transfer_start(request_sync_transfer_start), + .request_last(request_last), + + .response_eot(response_eot), + .response_measured_burst_length(response_measured_burst_length), + .response_partial(response_partial), + .response_valid(response_valid), + .response_ready(response_ready) +); + +up_axi #( + .AXI_ADDRESS_WIDTH (12), + .ADDRESS_WIDTH (9) +) i_up_axi ( + .up_rstn(s_axi_aresetn), + .up_clk(s_axi_aclk), + .up_axi_awvalid(s_axi_awvalid), + .up_axi_awaddr(s_axi_awaddr), + .up_axi_awready(s_axi_awready), + .up_axi_wvalid(s_axi_wvalid), + .up_axi_wdata(s_axi_wdata), + .up_axi_wstrb(s_axi_wstrb), + .up_axi_wready(s_axi_wready), + .up_axi_bvalid(s_axi_bvalid), + .up_axi_bresp(s_axi_bresp), + .up_axi_bready(s_axi_bready), + .up_axi_arvalid(s_axi_arvalid), + .up_axi_araddr(s_axi_araddr), + .up_axi_arready(s_axi_arready), + .up_axi_rvalid(s_axi_rvalid), + .up_axi_rresp(s_axi_rresp), + .up_axi_rdata(s_axi_rdata), + .up_axi_rready(s_axi_rready), + .up_wreq(up_wreq), + .up_waddr(up_waddr), + .up_wdata(up_wdata), + .up_wack(up_wack), + .up_rreq(up_rreq), + .up_raddr(up_raddr), + .up_rdata(up_rdata), + .up_rack(up_rack) +); + +endmodule diff --git a/src/adi/hdl/library/axi_dmac/axi_dmac_regmap_request.v b/src/adi/hdl/library/axi_dmac/axi_dmac_regmap_request.v new file mode 100644 index 00000000..9ff1de2e --- /dev/null +++ b/src/adi/hdl/library/axi_dmac/axi_dmac_regmap_request.v @@ -0,0 +1,308 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright 2014 - 2018 (c) Analog Devices, Inc. All rights reserved. +// +// In this HDL repository, there are many different and unique modules, consisting +// of various HDL (Verilog or VHDL) components. The individual modules are +// developed independently, and may be accompanied by separate and unique license +// terms. +// +// The user should read each of these license terms, and understand the +// freedoms and responsibilities that he or she has by using this source/core. +// +// This core 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. +// +// Redistribution and use of source or resulting binaries, with or without modification +// of this file, are permitted under one of the following two license terms: +// +// 1. The GNU General Public License version 2 as published by the +// Free Software Foundation, which can be found in the top level directory +// of this repository (LICENSE_GPL2), and also online at: +// +// +// OR +// +// 2. An ADI specific BSD license, which can be found in the top level directory +// of this repository (LICENSE_ADIBSD), and also on-line at: +// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD +// This will allow to generate bit files and not release the source code, +// as long as it attaches to an ADI device. +// +// *************************************************************************** +// *************************************************************************** + +`timescale 1ns/100ps + +module axi_dmac_regmap_request #( + parameter DISABLE_DEBUG_REGISTERS = 0, + parameter BYTES_PER_BEAT_WIDTH_DEST = 1, + parameter BYTES_PER_BEAT_WIDTH_SRC = 1, + parameter BYTES_PER_BURST_WIDTH = 7, + parameter DMA_AXI_ADDR_WIDTH = 32, + parameter DMA_LENGTH_WIDTH = 24, + parameter DMA_LENGTH_ALIGN = 3, + parameter DMA_CYCLIC = 0, + parameter HAS_DEST_ADDR = 1, + parameter HAS_SRC_ADDR = 1, + parameter DMA_2D_TRANSFER = 0, + parameter SYNC_TRANSFER_START = 0 +) ( + input clk, + input reset, + + // Interrupts + output up_sot, + output up_eot, + + // Register map interface + input up_wreq, + input up_rreq, + input [8:0] up_waddr, + input [31:0] up_wdata, + input [8:0] up_raddr, + output reg [31:0] up_rdata, + + // Control interface + input ctrl_enable, + + // DMA request interface + output request_valid, + input request_ready, + output [DMA_AXI_ADDR_WIDTH-1:BYTES_PER_BEAT_WIDTH_DEST] request_dest_address, + output [DMA_AXI_ADDR_WIDTH-1:BYTES_PER_BEAT_WIDTH_SRC] request_src_address, + output [DMA_LENGTH_WIDTH-1:0] request_x_length, + output [DMA_LENGTH_WIDTH-1:0] request_y_length, + output [DMA_LENGTH_WIDTH-1:0] request_dest_stride, + output [DMA_LENGTH_WIDTH-1:0] request_src_stride, + output request_sync_transfer_start, + output request_last, + + // DMA response interface + input response_eot, + input [BYTES_PER_BURST_WIDTH-1:0] response_measured_burst_length, + input response_partial, + input response_valid, + output reg response_ready = 1'b1 + +); + +localparam MEASURED_LENGTH_WIDTH = (DMA_2D_TRANSFER == 1) ? 32 : DMA_LENGTH_WIDTH; + +// DMA transfer signals +reg up_dma_req_valid = 1'b0; +wire up_dma_req_ready; + +reg [1:0] up_transfer_id = 2'b0; +reg [1:0] up_transfer_id_eot = 2'b0; +reg [3:0] up_transfer_done_bitmap = 4'b0; + +reg [DMA_AXI_ADDR_WIDTH-1:BYTES_PER_BEAT_WIDTH_DEST] up_dma_dest_address = 'h00; +reg [DMA_AXI_ADDR_WIDTH-1:BYTES_PER_BEAT_WIDTH_SRC] up_dma_src_address = 'h00; +reg [DMA_LENGTH_WIDTH-1:0] up_dma_x_length = {DMA_LENGTH_ALIGN{1'b1}}; +reg up_dma_cyclic = DMA_CYCLIC ? 1'b1 : 1'b0; +reg up_dma_last = 1'b1; +reg up_dma_enable_tlen_reporting = 1'b0; + +wire up_tlf_s_ready; +reg up_tlf_s_valid = 1'b0; + +wire [MEASURED_LENGTH_WIDTH+2-1:0] up_tlf_data; +wire up_tlf_valid; +wire up_tlf_rd; +reg up_partial_length_valid = 1'b0; + +reg [MEASURED_LENGTH_WIDTH-1:0] up_measured_transfer_length = 'h0; +reg up_clear_tl = 1'b0; +reg [1:0] up_transfer_id_eot_d = 'h0; +wire up_bl_partial; + +assign request_dest_address = up_dma_dest_address; +assign request_src_address = up_dma_src_address; +assign request_x_length = up_dma_x_length; +assign request_sync_transfer_start = SYNC_TRANSFER_START ? 1'b1 : 1'b0; +assign request_last = up_dma_last; + +always @(posedge clk) begin + if (reset == 1'b1) begin + up_dma_src_address <= 'h00; + up_dma_dest_address <= 'h00; + up_dma_x_length[DMA_LENGTH_WIDTH-1:DMA_LENGTH_ALIGN] <= 'h00; + up_dma_req_valid <= 1'b0; + up_dma_cyclic <= DMA_CYCLIC ? 1'b1 : 1'b0; + up_dma_last <= 1'b1; + up_dma_enable_tlen_reporting <= 1'b0; + end else begin + if (ctrl_enable == 1'b1) begin + if (up_wreq == 1'b1 && up_waddr == 9'h102) begin + up_dma_req_valid <= up_dma_req_valid | up_wdata[0]; + end else if (up_sot == 1'b1) begin + up_dma_req_valid <= 1'b0; + end + end else begin + up_dma_req_valid <= 1'b0; + end + + if (up_wreq == 1'b1) begin + case (up_waddr) + 9'h103: begin + if (DMA_CYCLIC) up_dma_cyclic <= up_wdata[0]; + up_dma_last <= up_wdata[1]; + up_dma_enable_tlen_reporting <= up_wdata[2]; + end + 9'h104: up_dma_dest_address <= up_wdata[DMA_AXI_ADDR_WIDTH-1:BYTES_PER_BEAT_WIDTH_DEST]; + 9'h105: up_dma_src_address <= up_wdata[DMA_AXI_ADDR_WIDTH-1:BYTES_PER_BEAT_WIDTH_SRC]; + 9'h106: up_dma_x_length[DMA_LENGTH_WIDTH-1:DMA_LENGTH_ALIGN] <= up_wdata[DMA_LENGTH_WIDTH-1:DMA_LENGTH_ALIGN]; + endcase + end + end +end + +always @(*) begin + case (up_raddr) + 9'h101: up_rdata <= up_transfer_id; + 9'h102: up_rdata <= up_dma_req_valid; + 9'h103: up_rdata <= {29'h00, up_dma_enable_tlen_reporting, up_dma_last, up_dma_cyclic}; // Flags + 9'h104: up_rdata <= HAS_DEST_ADDR ? {up_dma_dest_address,{BYTES_PER_BEAT_WIDTH_DEST{1'b0}}} : 'h00; + 9'h105: up_rdata <= HAS_SRC_ADDR ? {up_dma_src_address,{BYTES_PER_BEAT_WIDTH_SRC{1'b0}}} : 'h00; + 9'h106: up_rdata <= up_dma_x_length; + 9'h107: up_rdata <= request_y_length; + 9'h108: up_rdata <= request_dest_stride; + 9'h109: up_rdata <= request_src_stride; + 9'h10a: up_rdata <= {up_partial_length_valid,27'b0,up_transfer_done_bitmap}; + 9'h10b: up_rdata <= up_transfer_id_eot; + 9'h10c: up_rdata <= 32'h0; + 9'h112: up_rdata <= up_measured_transfer_length; + 9'h113: up_rdata <= up_tlf_data[MEASURED_LENGTH_WIDTH-1 : 0]; // Length + 9'h114: up_rdata <= up_tlf_data[MEASURED_LENGTH_WIDTH+: 2]; // ID + default: up_rdata <= 32'h00; + endcase +end + +generate +if (DMA_2D_TRANSFER == 1) begin + reg [DMA_LENGTH_WIDTH-1:0] up_dma_y_length = 'h00; + reg [DMA_LENGTH_WIDTH-1:0] up_dma_src_stride = 'h00; + reg [DMA_LENGTH_WIDTH-1:0] up_dma_dest_stride = 'h00; + + always @(posedge clk) begin + if (reset == 1'b1) begin + up_dma_y_length <= 'h00; + up_dma_dest_stride[DMA_LENGTH_WIDTH-1:BYTES_PER_BEAT_WIDTH_DEST] <= 'h00; + up_dma_src_stride[DMA_LENGTH_WIDTH-1:BYTES_PER_BEAT_WIDTH_SRC] <= 'h00; + end else if (up_wreq == 1'b1) begin + case (up_waddr) + 9'h107: up_dma_y_length <= up_wdata[DMA_LENGTH_WIDTH-1:0]; + 9'h108: up_dma_dest_stride[DMA_LENGTH_WIDTH-1:BYTES_PER_BEAT_WIDTH_DEST] <= up_wdata[DMA_LENGTH_WIDTH-1:BYTES_PER_BEAT_WIDTH_DEST]; + 9'h109: up_dma_src_stride[DMA_LENGTH_WIDTH-1:BYTES_PER_BEAT_WIDTH_SRC] <= up_wdata[DMA_LENGTH_WIDTH-1:BYTES_PER_BEAT_WIDTH_SRC]; + endcase + end + end + assign request_y_length = up_dma_y_length; + assign request_dest_stride = up_dma_dest_stride; + assign request_src_stride = up_dma_src_stride; +end else begin + assign request_y_length = 'h0; + assign request_dest_stride = 'h0; + assign request_src_stride = 'h0; +end +endgenerate + +// In cyclic mode the same transfer is submitted over and over again +assign up_sot = up_dma_cyclic ? 1'b0 : up_dma_req_valid & up_dma_req_ready; +assign up_eot = up_dma_cyclic ? 1'b0 : response_eot & response_valid & response_ready; + +assign request_valid = up_dma_req_valid; +assign up_dma_req_ready = request_ready; + +// Request ID and Request done bitmap handling +always @(posedge clk) begin + if (ctrl_enable == 1'b0) begin + up_transfer_id <= 2'h0; + up_transfer_id_eot <= 2'h0; + up_transfer_done_bitmap <= 4'h0; + end else begin + if (up_sot == 1'b1) begin + up_transfer_id <= up_transfer_id + 1'b1; + up_transfer_done_bitmap[up_transfer_id] <= 1'b0; + end + + if (up_eot == 1'b1) begin + up_transfer_id_eot <= up_transfer_id_eot + 1'b1; + up_transfer_done_bitmap[up_transfer_id_eot] <= 1'b1; + end + end +end + +assign up_tlf_rd = up_rreq && up_raddr == 'h114; +assign up_bl_partial = response_valid & response_ready & response_partial & up_dma_enable_tlen_reporting; + +always @(posedge clk) begin + if (ctrl_enable == 1'b0) begin + up_partial_length_valid <= 1'b0; + end else begin + if (up_bl_partial == 1'b1) begin + up_partial_length_valid <= 1'b1; + end else if (up_tlf_rd == 1'b1) begin + up_partial_length_valid <= 1'b0; + end else if (up_tlf_valid == 1'b1) begin + up_partial_length_valid <= 1'b1; + end + end +end + +always @(posedge clk) +begin + if (response_valid == 1'b1 & response_ready == 1'b1) begin + up_measured_transfer_length <= up_measured_transfer_length + response_measured_burst_length + 1'b1; + up_transfer_id_eot_d <= up_transfer_id_eot; + end else if (up_clear_tl == 1'b1) begin + up_measured_transfer_length <= 'h0; + end +end + +always @(posedge clk) +begin + if (ctrl_enable == 1'b0) begin + response_ready <= 1'b1; + end else if (response_ready == 1'b1) begin + response_ready <= ~response_valid; + end else if (up_tlf_s_ready == 1'b1) begin + response_ready <= 1'b1; + end +end + +always @(posedge clk) +begin + if (response_valid == 1'b1 && response_ready == 1'b1) begin + up_tlf_s_valid <= up_bl_partial; + up_clear_tl <= up_eot; + end else if (up_tlf_s_ready == 1'b1) begin + up_tlf_s_valid <= 1'b0; + end +end + +// Buffer the length and transfer ID of partial transfers +util_axis_fifo #( + .DATA_WIDTH(MEASURED_LENGTH_WIDTH + 2), + .ADDRESS_WIDTH(2), + .ASYNC_CLK(0) +) i_transfer_lenghts_fifo ( + .s_axis_aclk(clk), + .s_axis_aresetn(ctrl_enable), + .s_axis_valid(up_tlf_s_valid), + .s_axis_ready(up_tlf_s_ready), + .s_axis_empty(), + .s_axis_data({up_transfer_id_eot_d, up_measured_transfer_length}), + .s_axis_room(), + + .m_axis_aclk(clk), + .m_axis_aresetn(ctrl_enable), + .m_axis_valid(up_tlf_valid), + .m_axis_ready(up_tlf_rd & up_tlf_valid), + .m_axis_data(up_tlf_data), + .m_axis_level() +); + +endmodule diff --git a/src/adi/hdl/library/axi_dmac/axi_dmac_reset_manager.v b/src/adi/hdl/library/axi_dmac/axi_dmac_reset_manager.v new file mode 100644 index 00000000..e889e6e8 --- /dev/null +++ b/src/adi/hdl/library/axi_dmac/axi_dmac_reset_manager.v @@ -0,0 +1,304 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright 2014 - 2018 (c) Analog Devices, Inc. All rights reserved. +// +// In this HDL repository, there are many different and unique modules, consisting +// of various HDL (Verilog or VHDL) components. The individual modules are +// developed independently, and may be accompanied by separate and unique license +// terms. +// +// The user should read each of these license terms, and understand the +// freedoms and responsibilities that he or she has by using this source/core. +// +// This core 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. +// +// Redistribution and use of source or resulting binaries, with or without modification +// of this file, are permitted under one of the following two license terms: +// +// 1. The GNU General Public License version 2 as published by the +// Free Software Foundation, which can be found in the top level directory +// of this repository (LICENSE_GPL2), and also online at: +// +// +// OR +// +// 2. An ADI specific BSD license, which can be found in the top level directory +// of this repository (LICENSE_ADIBSD), and also on-line at: +// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD +// This will allow to generate bit files and not release the source code, +// as long as it attaches to an ADI device. +// +// *************************************************************************** +// *************************************************************************** + +`timescale 1ns/100ps + +module axi_dmac_reset_manager #( + parameter ASYNC_CLK_REQ_SRC = 1, + parameter ASYNC_CLK_SRC_DEST = 1, + parameter ASYNC_CLK_DEST_REQ = 1 +) ( + input clk, + input resetn, + + input ctrl_enable, + input ctrl_pause, + + output req_resetn, + output req_enable, + input req_enabled, + + input dest_clk, + input dest_ext_resetn, + output dest_resetn, + output dest_enable, + input dest_enabled, + + input src_clk, + input src_ext_resetn, + output src_resetn, + output src_enable, + input src_enabled, + + output [11:0] dbg_status +); + +/* + * TODO: + * If an external reset is asserted for a domain that domain will go into reset + * immediately. If a transfer is currently active the transfer will be aborted + * and other domains will be shutdown gracefully. The reset manager will stay in + * the shutdown state until all external resets have been de-asserted. + */ + +localparam STATE_DO_RESET = 3'h0; +localparam STATE_RESET = 3'h1; +localparam STATE_DISABLED = 3'h2; +localparam STATE_STARTUP = 3'h3; +localparam STATE_ENABLED = 3'h4; +localparam STATE_SHUTDOWN = 3'h5; + +reg [2:0] state = 3'b000; +reg needs_reset = 1'b0; +reg do_reset = 1'b0; +reg do_enable = 1'b0; + +wire enabled_dest; +wire enabled_src; + +wire enabled_all; +wire disabled_all; + +assign enabled_all = req_enabled & enabled_src & enabled_dest; +assign disabled_all = ~(req_enabled | enabled_src | enabled_dest); + +assign req_enable = do_enable; + +assign dbg_status = {needs_reset,req_resetn,src_resetn,dest_resetn,1'b0,req_enabled,enabled_src,enabled_dest,1'b0,state}; + +always @(posedge clk) begin + if (state == STATE_DO_RESET) begin + do_reset <= 1'b1; + end else begin + do_reset <= 1'b0; + end +end + +always @(posedge clk) begin + if (state == STATE_STARTUP || state == STATE_ENABLED) begin + do_enable <= 1'b1; + end else begin + do_enable <= 1'b0; + end +end + +/* + * If ctrl_enable goes from 1 to 0 a shutdown procedure is initiated. During the + * shutdown procedure all domains are signaled that a shutdown should occur. The + * domains will then complete any active transactions that are required to + * complete according to the interface semantics. Once a domain has completed + * its transactions it will indicate that it has been shutdown. Once all domains + * indicate that they have been disabled a reset pulse will be generated to all + * domains to clear all residual state. The reset pulse is long enough so that it + * is active in all domains for at least 4 clock cycles. + * + * Once the reset signal is de-asserted the DMA is in an idle state and can be + * enabled again. If the DMA receives a enable while it is performing a shutdown + * sequence it will only be re-enabled once the shutdown sequence has + * successfully completed. + * + * If ctrl_pause is asserted all domains will be disabled. But there will be no + * reset, so when the ctrl_pause signal is de-asserted again the DMA will resume + * with its previous state. + * + */ + +/* + * If ctrl_enable goes low, even for a single clock cycle, we want to go through + * a full reset sequence. This might happen when the state machine is busy, e.g. + * going through a startup sequence. To avoid missing the event store it for + * later. + */ +always @(posedge clk) begin + if (state == STATE_RESET) begin + needs_reset <= 1'b0; + end else if (ctrl_enable == 1'b0) begin + needs_reset <= 1'b1; + end +end + +always @(posedge clk) begin + if (resetn == 1'b0) begin + state <= STATE_DO_RESET; + end else begin + case (state) + STATE_DO_RESET: begin + state <= STATE_RESET; + end + STATE_RESET: begin + /* + * Wait for the reset sequence to complete. Stay in this state when + * ctrl_enable == 1'b0, otherwise we'd go through the reset sequence + * again and again. + */ + if (ctrl_enable == 1'b1 && req_resetn == 1'b1) begin + state <= STATE_DISABLED; + end + end + STATE_DISABLED: begin + if (needs_reset == 1'b1) begin + state <= STATE_DO_RESET; + end else if (ctrl_pause == 1'b0) begin + state <= STATE_STARTUP; + end + end + STATE_STARTUP: begin + /* Wait for all domains to be ready */ + if (enabled_all == 1'b1) begin + state <= STATE_ENABLED; + end + end + STATE_ENABLED: begin + if (needs_reset == 1'b1 || ctrl_pause == 1'b1) begin + state <= STATE_SHUTDOWN; + end + end + STATE_SHUTDOWN: begin + /* Wait for all domains to complete outstanding transactions */ + if (disabled_all == 1'b1) begin + state <= STATE_DISABLED; + end + end + endcase + end +end + +/* + * Chain the reset through all clock domains. This makes sure that is asserted + * for at least 4 clock cycles of the slowest domain, no matter what. If + * successive domains have the same clock they'll share their reset signal. + */ + +wire [3:0] reset_async_chain; +wire [3:0] reset_sync_chain; +wire [2:0] reset_chain_clks = {clk, src_clk, dest_clk}; + +localparam GEN_ASYNC_RESET = { + ASYNC_CLK_REQ_SRC ? 1'b1 : 1'b0, + ASYNC_CLK_SRC_DEST ? 1'b1 : 1'b0, + 1'b1 +}; + +assign reset_async_chain[0] = 1'b0; +assign reset_sync_chain[0] = reset_async_chain[3]; + +generate +genvar i; + +for (i = 0; i < 3; i = i + 1) begin: reset_gen + + if (GEN_ASYNC_RESET[i] == 1'b1) begin + + reg [3:0] reset_async = 4'b1111; + reg [1:0] reset_sync = 2'b11; + reg reset_sync_in = 1'b1; + + always @(posedge reset_chain_clks[i] or posedge reset_sync_chain[i]) begin + if (reset_sync_chain[i] == 1'b1) begin + reset_sync_in <= 1'b1; + end else begin + reset_sync_in <= reset_async[0]; + end + end + + always @(posedge reset_chain_clks[i] or posedge do_reset) begin + if (do_reset == 1'b1) begin + reset_async <= 4'b1111; + end else begin + reset_async <= {reset_async_chain[i], reset_async[3:1]}; + end + end + + always @(posedge reset_chain_clks[i]) begin + reset_sync <= {reset_sync_in,reset_sync[1]}; + end + + assign reset_async_chain[i+1] = reset_async[0]; + assign reset_sync_chain[i+1] = reset_sync[0]; + + end else begin + assign reset_async_chain[i+1] = reset_async_chain[i]; + assign reset_sync_chain[i+1] = reset_sync_chain[i]; + end +end + +endgenerate + +/* De-assertions in the opposite direction of the data flow: dest, src, request */ +assign dest_resetn = ~reset_sync_chain[1]; +assign src_resetn = ~reset_sync_chain[2]; +assign req_resetn = ~reset_sync_chain[3]; + +sync_bits #( + .NUM_OF_BITS (1), + .ASYNC_CLK (ASYNC_CLK_DEST_REQ) +) i_sync_control_dest ( + .out_clk (dest_clk), + .out_resetn (1'b1), + .in (do_enable), + .out (dest_enable) +); + +sync_bits #( + .NUM_OF_BITS (1), + .ASYNC_CLK (ASYNC_CLK_DEST_REQ) +) i_sync_status_dest ( + .out_clk (clk), + .out_resetn (1'b1), + .in (dest_enabled), + .out (enabled_dest) +); + +sync_bits #( + .NUM_OF_BITS (1), + .ASYNC_CLK (ASYNC_CLK_REQ_SRC) +) i_sync_control_src ( + .out_clk (src_clk), + .out_resetn (1'b1), + .in (do_enable), + .out (src_enable) +); + +sync_bits #( + .NUM_OF_BITS (1), + .ASYNC_CLK (ASYNC_CLK_REQ_SRC) +) i_sync_status_src ( + .out_clk (clk), + .out_resetn (1'b1), + .in (src_enabled), + .out (enabled_src) +); + +endmodule diff --git a/src/adi/hdl/library/axi_dmac/axi_dmac_resize_dest.v b/src/adi/hdl/library/axi_dmac/axi_dmac_resize_dest.v new file mode 100644 index 00000000..c57b7897 --- /dev/null +++ b/src/adi/hdl/library/axi_dmac/axi_dmac_resize_dest.v @@ -0,0 +1,115 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright 2014 - 2017 (c) Analog Devices, Inc. All rights reserved. +// +// In this HDL repository, there are many different and unique modules, consisting +// of various HDL (Verilog or VHDL) components. The individual modules are +// developed independently, and may be accompanied by separate and unique license +// terms. +// +// The user should read each of these license terms, and understand the +// freedoms and responsibilities that he or she has by using this source/core. +// +// This core 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. +// +// Redistribution and use of source or resulting binaries, with or without modification +// of this file, are permitted under one of the following two license terms: +// +// 1. The GNU General Public License version 2 as published by the +// Free Software Foundation, which can be found in the top level directory +// of this repository (LICENSE_GPL2), and also online at: +// +// +// OR +// +// 2. An ADI specific BSD license, which can be found in the top level directory +// of this repository (LICENSE_ADIBSD), and also on-line at: +// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD +// This will allow to generate bit files and not release the source code, +// as long as it attaches to an ADI device. +// +// *************************************************************************** +// *************************************************************************** + +`timescale 1ns/100ps + +module axi_dmac_resize_dest #( + parameter DATA_WIDTH_DEST = 64, + parameter DATA_WIDTH_MEM = 64 +) ( + input clk, + input reset, + + input mem_data_valid, + output mem_data_ready, + input [DATA_WIDTH_MEM-1:0] mem_data, + input mem_data_last, + + output dest_data_valid, + input dest_data_ready, + output [DATA_WIDTH_DEST-1:0] dest_data, + output dest_data_last +); + +/* + * Resize the data width between the burst memory and the destination interface + * if necessary. + */ + +generate if (DATA_WIDTH_DEST == DATA_WIDTH_MEM) begin + assign dest_data_valid = mem_data_valid; + assign dest_data = mem_data; + assign dest_data_last = mem_data_last; + assign mem_data_ready = dest_data_ready; +end else begin + + localparam RATIO = DATA_WIDTH_MEM / DATA_WIDTH_DEST; + + reg [$clog2(RATIO)-1:0] count = 'h0; + reg valid = 1'b0; + reg [RATIO-1:0] last = 'h0; + reg [DATA_WIDTH_MEM-1:0] data = 'h0; + + wire last_beat; + + assign last_beat = count == RATIO - 1; + + always @(posedge clk) begin + if (reset == 1'b1) begin + valid <= 1'b0; + end else if (mem_data_valid == 1'b1) begin + valid <= 1'b1; + end else if (last_beat == 1'b1 && dest_data_ready == 1'b1) begin + valid <= 1'b0; + end + end + + always @(posedge clk) begin + if (reset == 1'b1) begin + count <= 'h0; + end else if (dest_data_ready == 1'b1 && dest_data_valid == 1'b1) begin + count <= count + 1; + end + end + + assign mem_data_ready = ~valid | (dest_data_ready & last_beat); + + always @(posedge clk) begin + if (mem_data_ready == 1'b1) begin + data <= mem_data; + last <= {mem_data_last,{RATIO-1{1'b0}}}; + end else if (dest_data_ready == 1'b1) begin + data[DATA_WIDTH_MEM-DATA_WIDTH_DEST-1:0] <= data[DATA_WIDTH_MEM-1:DATA_WIDTH_DEST]; + last[RATIO-2:0] <= last[RATIO-1:1]; + end + end + + assign dest_data_valid = valid; + assign dest_data = data[DATA_WIDTH_DEST-1:0]; + assign dest_data_last = last[0]; + +end endgenerate + +endmodule diff --git a/src/adi/hdl/library/axi_dmac/axi_dmac_resize_src.v b/src/adi/hdl/library/axi_dmac/axi_dmac_resize_src.v new file mode 100644 index 00000000..24f696f0 --- /dev/null +++ b/src/adi/hdl/library/axi_dmac/axi_dmac_resize_src.v @@ -0,0 +1,105 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright 2014 - 2017 (c) Analog Devices, Inc. All rights reserved. +// +// In this HDL repository, there are many different and unique modules, consisting +// of various HDL (Verilog or VHDL) components. The individual modules are +// developed independently, and may be accompanied by separate and unique license +// terms. +// +// The user should read each of these license terms, and understand the +// freedoms and responsibilities that he or she has by using this source/core. +// +// This core 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. +// +// Redistribution and use of source or resulting binaries, with or without modification +// of this file, are permitted under one of the following two license terms: +// +// 1. The GNU General Public License version 2 as published by the +// Free Software Foundation, which can be found in the top level directory +// of this repository (LICENSE_GPL2), and also online at: +// +// +// OR +// +// 2. An ADI specific BSD license, which can be found in the top level directory +// of this repository (LICENSE_ADIBSD), and also on-line at: +// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD +// This will allow to generate bit files and not release the source code, +// as long as it attaches to an ADI device. +// +// *************************************************************************** +// *************************************************************************** + +/* + * Resize the data width between the source interface and the burst memory + * if necessary. + */ + +`timescale 1ns/100ps + +module axi_dmac_resize_src #( + parameter DATA_WIDTH_SRC = 64, + parameter DATA_WIDTH_MEM = 64 +) ( + input clk, + input reset, + + input src_data_valid, + input [DATA_WIDTH_SRC-1:0] src_data, + input src_data_last, + + output mem_data_valid, + output [DATA_WIDTH_MEM-1:0] mem_data, + output mem_data_last +); + +generate if (DATA_WIDTH_SRC == DATA_WIDTH_MEM) begin + assign mem_data_valid = src_data_valid; + assign mem_data = src_data; + assign mem_data_last = src_data_last; +end else begin + + localparam RATIO = DATA_WIDTH_MEM / DATA_WIDTH_SRC; + + reg [RATIO-1:0] mask = 'h1; + reg valid = 1'b0; + reg last = 1'b0; + reg [DATA_WIDTH_MEM-1:0] data = 'h0; + + always @(posedge clk) begin + if (reset == 1'b1) begin + valid <= 1'b0; + mask <= 'h1; + end else if (src_data_valid == 1'b1) begin + valid <= mask[RATIO-1] || src_data_last; + if (src_data_last) begin + mask <= 'h1; + end else begin + mask <= {mask[RATIO-2:0],mask[RATIO-1]}; + end + end else begin + valid <= 1'b0; + end + end + + integer i; + + always @(posedge clk) begin + for (i = 0; i < RATIO; i = i+1) begin + if (mask[i] == 1'b1) begin + data[i*DATA_WIDTH_SRC+:DATA_WIDTH_SRC] <= src_data; + end + end + last <= src_data_last; + end + + assign mem_data_valid = valid; + assign mem_data = data; + assign mem_data_last = last; + +end endgenerate + +endmodule diff --git a/src/adi/hdl/library/axi_dmac/axi_dmac_response_manager.v b/src/adi/hdl/library/axi_dmac/axi_dmac_response_manager.v new file mode 100644 index 00000000..f55ae933 --- /dev/null +++ b/src/adi/hdl/library/axi_dmac/axi_dmac_response_manager.v @@ -0,0 +1,279 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright 2014 - 2017 (c) Analog Devices, Inc. All rights reserved. +// +// In this HDL repository, there are many different and unique modules, consisting +// of various HDL (Verilog or VHDL) components. The individual modules are +// developed independently, and may be accompanied by separate and unique license +// terms. +// +// The user should read each of these license terms, and understand the +// freedoms and responsibilities that he or she has by using this source/core. +// +// This core 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. +// +// Redistribution and use of source or resulting binaries, with or without modification +// of this file, are permitted under one of the following two license terms: +// +// 1. The GNU General Public License version 2 as published by the +// Free Software Foundation, which can be found in the top level directory +// of this repository (LICENSE_GPL2), and also online at: +// +// +// OR +// +// 2. An ADI specific BSD license, which can be found in the top level directory +// of this repository (LICENSE_ADIBSD), and also on-line at: +// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD +// This will allow to generate bit files and not release the source code, +// as long as it attaches to an ADI device. +// +// *************************************************************************** +// *************************************************************************** + +`timescale 1ns/100ps + +module axi_dmac_response_manager #( + parameter DMA_DATA_WIDTH_SRC = 64, + parameter DMA_DATA_WIDTH_DEST = 64, + parameter DMA_LENGTH_WIDTH = 24, + parameter BYTES_PER_BURST_WIDTH = 7, + parameter BYTES_PER_BEAT_WIDTH_SRC = $clog2(DMA_DATA_WIDTH_SRC/8), + parameter ASYNC_CLK_DEST_REQ = 1 +)( + // Interface to destination side + input dest_clk, + input dest_resetn, + + input dest_response_valid, + output dest_response_ready, + input [1:0] dest_response_resp, + input dest_response_partial, + input dest_response_resp_eot, + input [BYTES_PER_BURST_WIDTH-1:0] dest_response_data_burst_length, + + // Interface to processor + input req_clk, + input req_resetn, + + output response_eot, + output reg [BYTES_PER_BURST_WIDTH-1:0] measured_burst_length = 'h0, + output response_partial, + output reg response_valid = 1'b0, + input response_ready, + + // Interface to requester side + input completion_req_valid, + input completion_req_last, + input [1:0] completion_transfer_id +); + +localparam STATE_IDLE = 3'h0; +localparam STATE_ACC = 3'h1; +localparam STATE_WRITE_RESPR = 3'h2; +localparam STATE_ZERO_COMPL = 3'h3; +localparam STATE_WRITE_ZRCMPL = 3'h4; + +reg [2:0] state = STATE_IDLE; +reg [2:0] nx_state; + +localparam DEST_SRC_RATIO = DMA_DATA_WIDTH_DEST/DMA_DATA_WIDTH_SRC; + +localparam DEST_SRC_RATIO_WIDTH = DEST_SRC_RATIO > 64 ? 7 : + DEST_SRC_RATIO > 32 ? 6 : + DEST_SRC_RATIO > 16 ? 5 : + DEST_SRC_RATIO > 8 ? 4 : + DEST_SRC_RATIO > 4 ? 3 : + DEST_SRC_RATIO > 2 ? 2 : + DEST_SRC_RATIO > 1 ? 1 : 0; + +localparam BYTES_PER_BEAT_WIDTH = DEST_SRC_RATIO_WIDTH + BYTES_PER_BEAT_WIDTH_SRC; +localparam BURST_LEN_WIDTH = BYTES_PER_BURST_WIDTH - BYTES_PER_BEAT_WIDTH; + +wire do_acc_st; +wire do_compl; +reg req_eot = 1'b0; +reg req_response_partial = 1'b0; +reg [BYTES_PER_BURST_WIDTH-1:0] req_response_dest_data_burst_length = 'h0; + +wire response_dest_valid; +reg response_dest_ready = 1'b1; +wire [1:0] response_dest_resp; +wire response_dest_resp_eot; +wire [BYTES_PER_BURST_WIDTH-1:0] response_dest_data_burst_length; + +wire [BURST_LEN_WIDTH-1:0] burst_lenght; +reg [BURST_LEN_WIDTH-1:0] burst_pointer_end; + +reg [1:0] to_complete_count = 'h0; +reg [1:0] transfer_id = 'h0; +reg completion_req_last_found = 1'b0; + +util_axis_fifo #( + .DATA_WIDTH(BYTES_PER_BURST_WIDTH+1+1), + .ADDRESS_WIDTH(0), + .ASYNC_CLK(ASYNC_CLK_DEST_REQ) +) i_dest_response_fifo ( + .s_axis_aclk(dest_clk), + .s_axis_aresetn(dest_resetn), + .s_axis_valid(dest_response_valid), + .s_axis_ready(dest_response_ready), + .s_axis_empty(), + .s_axis_data({dest_response_data_burst_length, + dest_response_partial, + dest_response_resp_eot}), + .s_axis_room(), + + .m_axis_aclk(req_clk), + .m_axis_aresetn(req_resetn), + .m_axis_valid(response_dest_valid), + .m_axis_ready(response_dest_ready), + .m_axis_data({response_dest_data_burst_length, + response_dest_partial, + response_dest_resp_eot}), + .m_axis_level() +); + +always @(posedge req_clk) +begin + if (response_dest_valid & response_dest_ready) begin + req_eot <= response_dest_resp_eot; + req_response_partial <= response_dest_partial; + req_response_dest_data_burst_length <= response_dest_data_burst_length; + end +end + +always @(posedge req_clk) +begin + if (req_resetn == 1'b0) begin + response_dest_ready <= 1'b1; + end else begin + response_dest_ready <= (nx_state == STATE_IDLE); + end +end + +assign response_eot = (state == STATE_WRITE_RESPR) ? req_eot : 1'b1; +assign response_partial = (state == STATE_WRITE_RESPR) ? req_response_partial : 1'b0; + +always @(posedge req_clk) +begin + if (req_resetn == 1'b0) begin + response_valid <= 1'b0; + end else begin + if (nx_state == STATE_WRITE_RESPR || nx_state == STATE_WRITE_ZRCMPL) begin + response_valid <= 1'b1; + end else if (response_ready == 1'b1) begin + response_valid <= 1'b0; + end + end +end + +// transform the free running pointer from burst memory into burst length +assign burst_lenght = req_response_dest_data_burst_length[BYTES_PER_BURST_WIDTH-1 -: BURST_LEN_WIDTH] - + burst_pointer_end - 1'b1; + +always @(posedge req_clk) +begin + if (req_resetn == 1'b0) begin + burst_pointer_end <= {BURST_LEN_WIDTH{1'b1}}; + end else if (state == STATE_ACC) begin + burst_pointer_end <= req_response_dest_data_burst_length[BYTES_PER_BURST_WIDTH-1 -: BURST_LEN_WIDTH]; + end +end + +always @(posedge req_clk) +begin + if (state == STATE_ZERO_COMPL) begin + measured_burst_length <= {BYTES_PER_BURST_WIDTH{1'b1}}; + end else if (state == STATE_ACC) begin + measured_burst_length[BYTES_PER_BURST_WIDTH-1 -: BURST_LEN_WIDTH] <= burst_lenght; + measured_burst_length[BYTES_PER_BEAT_WIDTH-1 : 0] <= + req_response_dest_data_burst_length[BYTES_PER_BEAT_WIDTH-1: 0]; + end +end + +always @(*) begin + nx_state = state; + case (state) + STATE_IDLE: begin + if (response_dest_valid == 1'b1) begin + nx_state = STATE_ACC; + end else if (|to_complete_count) begin + if (transfer_id == completion_transfer_id) + nx_state = STATE_ZERO_COMPL; + end + end + STATE_ACC: begin + nx_state = STATE_WRITE_RESPR; + end + STATE_WRITE_RESPR: begin + if (response_ready == 1'b1) begin + nx_state = STATE_IDLE; + end + end + STATE_ZERO_COMPL: begin + if (|to_complete_count) begin + nx_state = STATE_WRITE_ZRCMPL; + end else begin + if (completion_req_last_found == 1'b1) begin + nx_state = STATE_IDLE; + end + end + end + STATE_WRITE_ZRCMPL:begin + if (response_ready == 1'b1) begin + nx_state = STATE_ZERO_COMPL; + end + end + default: begin + nx_state = STATE_IDLE; + end + endcase +end + +always @(posedge req_clk) begin + if (req_resetn == 1'b0) begin + state <= STATE_IDLE; + end else begin + state <= nx_state; + end +end + +assign do_compl = (state == STATE_WRITE_ZRCMPL) && response_ready; + +// Once the last completion request from request generator is received +// we can wait for completions from the destination side +always @(posedge req_clk) begin + if (req_resetn == 1'b0) begin + completion_req_last_found <= 1'b0; + end else if (completion_req_valid) begin + completion_req_last_found <= completion_req_last; + end else if (state ==STATE_ZERO_COMPL && ~(|to_complete_count)) begin + completion_req_last_found <= 1'b0; + end +end + +// Track transfers so we can tell when did the destination completed all its +// transfers +always @(posedge req_clk) begin + if (req_resetn == 1'b0) begin + transfer_id <= 'h0; + end else if ((state == STATE_ACC && req_eot) || do_compl) begin + transfer_id <= transfer_id + 1; + end +end + +// Count how many transfers we need to complete +always @(posedge req_clk) begin + if (req_resetn == 1'b0) begin + to_complete_count <= 'h0; + end else if (completion_req_valid & ~do_compl) begin + to_complete_count <= to_complete_count + 1; + end else if (~completion_req_valid & do_compl) begin + to_complete_count <= to_complete_count - 1; + end +end + +endmodule diff --git a/src/adi/hdl/library/axi_dmac/axi_dmac_transfer.v b/src/adi/hdl/library/axi_dmac/axi_dmac_transfer.v new file mode 100644 index 00000000..d9afc751 --- /dev/null +++ b/src/adi/hdl/library/axi_dmac/axi_dmac_transfer.v @@ -0,0 +1,451 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright 2014 - 2018 (c) Analog Devices, Inc. All rights reserved. +// +// In this HDL repository, there are many different and unique modules, consisting +// of various HDL (Verilog or VHDL) components. The individual modules are +// developed independently, and may be accompanied by separate and unique license +// terms. +// +// The user should read each of these license terms, and understand the +// freedoms and responsabilities that he or she has by using this source/core. +// +// This core 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. +// +// Redistribution and use of source or resulting binaries, with or without modification +// of this file, are permitted under one of the following two license terms: +// +// 1. The GNU General Public License version 2 as published by the +// Free Software Foundation, which can be found in the top level directory +// of this repository (LICENSE_GPL2), and also online at: +// +// +// OR +// +// 2. An ADI specific BSD license, which can be found in the top level directory +// of this repository (LICENSE_ADIBSD), and also on-line at: +// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD +// This will allow to generate bit files and not release the source code, +// as long as it attaches to an ADI device. +// +// *************************************************************************** +// *************************************************************************** + +`timescale 1ns/100ps + +module axi_dmac_transfer #( + parameter DMA_DATA_WIDTH_SRC = 64, + parameter DMA_DATA_WIDTH_DEST = 64, + parameter DMA_LENGTH_WIDTH = 24, + parameter BYTES_PER_BEAT_WIDTH_DEST = $clog2(DMA_DATA_WIDTH_DEST/8), + parameter BYTES_PER_BEAT_WIDTH_SRC = $clog2(DMA_DATA_WIDTH_SRC/8), + parameter DMA_TYPE_DEST = 0, + parameter DMA_TYPE_SRC = 2, + parameter DMA_AXI_ADDR_WIDTH = 32, + parameter DMA_2D_TRANSFER = 1, + parameter ASYNC_CLK_REQ_SRC = 1, + parameter ASYNC_CLK_SRC_DEST = 1, + parameter ASYNC_CLK_DEST_REQ = 1, + parameter AXI_SLICE_DEST = 0, + parameter AXI_SLICE_SRC = 0, + parameter MAX_BYTES_PER_BURST = 128, + parameter BYTES_PER_BURST_WIDTH = 7, + parameter FIFO_SIZE = 8, + parameter ID_WIDTH = $clog2(FIFO_SIZE*2), + parameter AXI_LENGTH_WIDTH_SRC = 8, + parameter AXI_LENGTH_WIDTH_DEST = 8, + parameter ENABLE_DIAGNOSTICS_IF = 0 +) ( + input ctrl_clk, + input ctrl_resetn, + + input ctrl_enable, + input ctrl_pause, + + input req_valid, + output req_ready, + + input [DMA_AXI_ADDR_WIDTH-1:BYTES_PER_BEAT_WIDTH_DEST] req_dest_address, + input [DMA_AXI_ADDR_WIDTH-1:BYTES_PER_BEAT_WIDTH_SRC] req_src_address, + input [DMA_LENGTH_WIDTH-1:0] req_x_length, + input [DMA_LENGTH_WIDTH-1:0] req_y_length, + input [DMA_LENGTH_WIDTH-1:0] req_dest_stride, + input [DMA_LENGTH_WIDTH-1:0] req_src_stride, + input req_sync_transfer_start, + input req_last, + + output req_eot, + output [BYTES_PER_BURST_WIDTH-1:0] req_measured_burst_length, + output req_response_partial, + output req_response_valid, + input req_response_ready, + + // Master AXI interface + input m_dest_axi_aclk, + input m_dest_axi_aresetn, + input m_src_axi_aclk, + input m_src_axi_aresetn, + + // Write address + output [DMA_AXI_ADDR_WIDTH-1:0] m_axi_awaddr, + output [AXI_LENGTH_WIDTH_DEST-1:0] m_axi_awlen, + output [2:0] m_axi_awsize, + output [1:0] m_axi_awburst, + output [2:0] m_axi_awprot, + output [3:0] m_axi_awcache, + output m_axi_awvalid, + input m_axi_awready, + + // Write data + output [DMA_DATA_WIDTH_DEST-1:0] m_axi_wdata, + output [(DMA_DATA_WIDTH_DEST/8)-1:0] m_axi_wstrb, + input m_axi_wready, + output m_axi_wvalid, + output m_axi_wlast, + + // Write response + input m_axi_bvalid, + input [1:0] m_axi_bresp, + output m_axi_bready, + + // Read address + input m_axi_arready, + output m_axi_arvalid, + output [DMA_AXI_ADDR_WIDTH-1:0] m_axi_araddr, + output [AXI_LENGTH_WIDTH_SRC-1:0] m_axi_arlen, + output [2:0] m_axi_arsize, + output [1:0] m_axi_arburst, + output [2:0] m_axi_arprot, + output [3:0] m_axi_arcache, + + // Read data and response + input [DMA_DATA_WIDTH_SRC-1:0] m_axi_rdata, + input m_axi_rlast, + output m_axi_rready, + input m_axi_rvalid, + input [1:0] m_axi_rresp, + + // Slave streaming AXI interface + input s_axis_aclk, + output s_axis_ready, + input s_axis_valid, + input [DMA_DATA_WIDTH_SRC-1:0] s_axis_data, + input [0:0] s_axis_user, + input s_axis_last, + output s_axis_xfer_req, + + // Master streaming AXI interface + input m_axis_aclk, + input m_axis_ready, + output m_axis_valid, + output [DMA_DATA_WIDTH_DEST-1:0] m_axis_data, + output m_axis_last, + output m_axis_xfer_req, + + // Input FIFO interface + input fifo_wr_clk, + input fifo_wr_en, + input [DMA_DATA_WIDTH_SRC-1:0] fifo_wr_din, + output fifo_wr_overflow, + input fifo_wr_sync, + output fifo_wr_xfer_req, + + // Input FIFO interface + input fifo_rd_clk, + input fifo_rd_en, + output fifo_rd_valid, + output [DMA_DATA_WIDTH_DEST-1:0] fifo_rd_dout, + output fifo_rd_underflow, + output fifo_rd_xfer_req, + + output [ID_WIDTH-1:0] dbg_dest_request_id, + output [ID_WIDTH-1:0] dbg_dest_address_id, + output [ID_WIDTH-1:0] dbg_dest_data_id, + output [ID_WIDTH-1:0] dbg_dest_response_id, + output [ID_WIDTH-1:0] dbg_src_request_id, + output [ID_WIDTH-1:0] dbg_src_address_id, + output [ID_WIDTH-1:0] dbg_src_data_id, + output [ID_WIDTH-1:0] dbg_src_response_id, + output [11:0] dbg_status, + + // Diagnostics interface + output [7:0] dest_diag_level_bursts +); + +wire dma_req_valid; +wire dma_req_ready; +wire [DMA_AXI_ADDR_WIDTH-1:BYTES_PER_BEAT_WIDTH_DEST] dma_req_dest_address; +wire [DMA_AXI_ADDR_WIDTH-1:BYTES_PER_BEAT_WIDTH_SRC] dma_req_src_address; +wire [DMA_LENGTH_WIDTH-1:0] dma_req_length; +wire [BYTES_PER_BURST_WIDTH-1:0] dma_req_measured_burst_length; +wire dma_req_eot; +wire dma_response_valid; +wire dma_response_ready; +wire dma_response_partial; +wire dma_req_sync_transfer_start; +wire dma_req_last; + +wire req_clk = ctrl_clk; +wire req_resetn; + +wire req_enable; + +wire dest_clk; +wire dest_ext_resetn; +wire dest_resetn; +wire dest_enable; +wire dest_enabled; + +wire src_clk; +wire src_ext_resetn; +wire src_resetn; +wire src_enable; +wire src_enabled; + +wire req_valid_gated; +wire req_ready_gated; + +wire abort_req; + +axi_dmac_reset_manager #( + .ASYNC_CLK_REQ_SRC (ASYNC_CLK_REQ_SRC), + .ASYNC_CLK_SRC_DEST (ASYNC_CLK_SRC_DEST), + .ASYNC_CLK_DEST_REQ (ASYNC_CLK_DEST_REQ) +) i_reset_manager ( + .clk (ctrl_clk), + .resetn (ctrl_resetn), + + .ctrl_enable (ctrl_enable), + .ctrl_pause (ctrl_pause), + + .req_resetn (req_resetn), + .req_enable (req_enable), + .req_enabled (req_enable), + + .dest_clk (dest_clk), + .dest_ext_resetn (dest_ext_resetn), + .dest_resetn (dest_resetn), + .dest_enable (dest_enable), + .dest_enabled (dest_enabled), + + .src_clk (src_clk), + .src_ext_resetn (src_ext_resetn), + .src_resetn (src_resetn), + .src_enable (src_enable), + .src_enabled (src_enabled), + + .dbg_status (dbg_status) +); + +/* + * Things become a lot easier if we gate incoming requests in a central place + * before they are propagated downstream. Otherwise we'd need to take special + * care to not accidentally accept requests while the DMA is going through a + * shutdown and reset phase. + */ +assign req_valid_gated = req_enable & req_valid; +assign req_ready = req_enable & req_ready_gated; + +generate if (DMA_2D_TRANSFER == 1) begin + +dmac_2d_transfer #( + .DMA_AXI_ADDR_WIDTH(DMA_AXI_ADDR_WIDTH), + .DMA_LENGTH_WIDTH (DMA_LENGTH_WIDTH), + .BYTES_PER_BURST_WIDTH (BYTES_PER_BURST_WIDTH), + .BYTES_PER_BEAT_WIDTH_DEST (BYTES_PER_BEAT_WIDTH_DEST), + .BYTES_PER_BEAT_WIDTH_SRC (BYTES_PER_BEAT_WIDTH_SRC) +) i_2d_transfer ( + .req_aclk (req_clk), + .req_aresetn (req_resetn), + + .req_eot (req_eot), + .req_measured_burst_length (req_measured_burst_length), + .req_response_partial (req_response_partial), + .req_response_valid (req_response_valid), + .req_response_ready (req_response_ready), + + .req_valid (req_valid_gated), + .req_ready (req_ready_gated), + .req_dest_address (req_dest_address), + .req_src_address (req_src_address), + .req_x_length (req_x_length), + .req_y_length (req_y_length), + .req_dest_stride (req_dest_stride), + .req_src_stride (req_src_stride), + .req_sync_transfer_start (req_sync_transfer_start), + .req_last (req_last), + + .out_abort_req (abort_req), + .out_req_valid (dma_req_valid), + .out_req_ready (dma_req_ready), + .out_req_dest_address (dma_req_dest_address), + .out_req_src_address (dma_req_src_address), + .out_req_length (dma_req_length), + .out_req_sync_transfer_start (dma_req_sync_transfer_start), + .out_req_last (dma_req_last), + .out_eot (dma_req_eot), + .out_measured_burst_length (dma_req_measured_burst_length), + .out_response_partial (dma_response_partial), + .out_response_valid (dma_response_valid), + .out_response_ready (dma_response_ready) + ); + +end else begin + +/* Request */ +assign dma_req_valid = req_valid_gated; +assign req_ready_gated = dma_req_ready; + +assign dma_req_dest_address = req_dest_address; +assign dma_req_src_address = req_src_address; +assign dma_req_length = req_x_length; +assign dma_req_sync_transfer_start = req_sync_transfer_start; +assign dma_req_last = req_last; + +/* Response */ +assign req_eot = dma_req_eot; +assign req_measured_burst_length = dma_req_measured_burst_length; +assign req_response_partial = dma_response_partial; +assign req_response_valid = dma_response_valid; +assign dma_response_ready = req_response_ready; + +end endgenerate + +dmac_request_arb #( + .DMA_DATA_WIDTH_SRC (DMA_DATA_WIDTH_SRC), + .DMA_DATA_WIDTH_DEST (DMA_DATA_WIDTH_DEST), + .DMA_LENGTH_WIDTH (DMA_LENGTH_WIDTH), + .BYTES_PER_BEAT_WIDTH_DEST (BYTES_PER_BEAT_WIDTH_DEST), + .BYTES_PER_BEAT_WIDTH_SRC (BYTES_PER_BEAT_WIDTH_SRC), + .DMA_TYPE_DEST (DMA_TYPE_DEST), + .DMA_TYPE_SRC (DMA_TYPE_SRC), + .DMA_AXI_ADDR_WIDTH (DMA_AXI_ADDR_WIDTH), + .ASYNC_CLK_REQ_SRC (ASYNC_CLK_REQ_SRC), + .ASYNC_CLK_SRC_DEST (ASYNC_CLK_SRC_DEST), + .ASYNC_CLK_DEST_REQ (ASYNC_CLK_DEST_REQ), + .AXI_SLICE_DEST (AXI_SLICE_DEST), + .AXI_SLICE_SRC (AXI_SLICE_SRC), + .MAX_BYTES_PER_BURST (MAX_BYTES_PER_BURST), + .BYTES_PER_BURST_WIDTH (BYTES_PER_BURST_WIDTH), + .FIFO_SIZE (FIFO_SIZE), + .ID_WIDTH (ID_WIDTH), + .AXI_LENGTH_WIDTH_DEST (AXI_LENGTH_WIDTH_DEST), + .AXI_LENGTH_WIDTH_SRC (AXI_LENGTH_WIDTH_SRC), + .ENABLE_DIAGNOSTICS_IF(ENABLE_DIAGNOSTICS_IF) +) i_request_arb ( + .req_clk (req_clk), + .req_resetn (req_resetn), + + .req_valid (dma_req_valid), + .req_ready (dma_req_ready), + .req_dest_address (dma_req_dest_address), + .req_src_address (dma_req_src_address), + .req_length (dma_req_length), + .req_xlast (dma_req_last), + .req_sync_transfer_start (dma_req_sync_transfer_start), + + .eot (dma_req_eot), + .measured_burst_length(dma_req_measured_burst_length), + .response_partial (dma_response_partial), + .response_valid (dma_response_valid), + .response_ready (dma_response_ready), + + .abort_req (abort_req), + + .req_enable (req_enable), + + .dest_clk (dest_clk), + .dest_ext_resetn (dest_ext_resetn), + .dest_resetn (dest_resetn), + .dest_enable (dest_enable), + .dest_enabled (dest_enabled), + + .src_clk (src_clk), + .src_ext_resetn (src_ext_resetn), + .src_resetn (src_resetn), + .src_enable (src_enable), + .src_enabled (src_enabled), + + .m_dest_axi_aclk (m_dest_axi_aclk), + .m_dest_axi_aresetn (m_dest_axi_aresetn), + .m_src_axi_aclk (m_src_axi_aclk), + .m_src_axi_aresetn (m_src_axi_aresetn), + + .m_axi_awvalid (m_axi_awvalid), + .m_axi_awready (m_axi_awready), + .m_axi_awaddr (m_axi_awaddr), + .m_axi_awlen (m_axi_awlen), + .m_axi_awsize (m_axi_awsize), + .m_axi_awburst (m_axi_awburst), + .m_axi_awprot (m_axi_awprot), + .m_axi_awcache (m_axi_awcache), + + .m_axi_wvalid (m_axi_wvalid), + .m_axi_wready (m_axi_wready), + .m_axi_wdata (m_axi_wdata), + .m_axi_wstrb (m_axi_wstrb), + .m_axi_wlast (m_axi_wlast), + + .m_axi_bvalid (m_axi_bvalid), + .m_axi_bready (m_axi_bready), + .m_axi_bresp (m_axi_bresp), + + .m_axi_arvalid (m_axi_arvalid), + .m_axi_arready (m_axi_arready), + .m_axi_araddr (m_axi_araddr), + .m_axi_arlen (m_axi_arlen), + .m_axi_arsize (m_axi_arsize), + .m_axi_arburst (m_axi_arburst), + .m_axi_arprot (m_axi_arprot), + .m_axi_arcache (m_axi_arcache), + + .m_axi_rready (m_axi_rready), + .m_axi_rvalid (m_axi_rvalid), + .m_axi_rdata (m_axi_rdata), + .m_axi_rlast (m_axi_rlast), + .m_axi_rresp (m_axi_rresp), + + .s_axis_aclk (s_axis_aclk), + .s_axis_ready (s_axis_ready), + .s_axis_valid (s_axis_valid), + .s_axis_data (s_axis_data), + .s_axis_user (s_axis_user), + .s_axis_last (s_axis_last), + .s_axis_xfer_req (s_axis_xfer_req), + + .m_axis_aclk (m_axis_aclk), + .m_axis_ready (m_axis_ready), + .m_axis_valid (m_axis_valid), + .m_axis_data (m_axis_data), + .m_axis_last (m_axis_last), + .m_axis_xfer_req (m_axis_xfer_req), + + .fifo_wr_clk (fifo_wr_clk), + .fifo_wr_en (fifo_wr_en), + .fifo_wr_din (fifo_wr_din), + .fifo_wr_overflow (fifo_wr_overflow), + .fifo_wr_sync (fifo_wr_sync), + .fifo_wr_xfer_req (fifo_wr_xfer_req), + + .fifo_rd_clk (fifo_rd_clk), + .fifo_rd_en (fifo_rd_en), + .fifo_rd_valid (fifo_rd_valid), + .fifo_rd_dout (fifo_rd_dout), + .fifo_rd_underflow (fifo_rd_underflow), + .fifo_rd_xfer_req (fifo_rd_xfer_req), + + .dbg_dest_request_id (dbg_dest_request_id), + .dbg_dest_address_id (dbg_dest_address_id), + .dbg_dest_data_id (dbg_dest_data_id), + .dbg_dest_response_id (dbg_dest_response_id), + .dbg_src_request_id (dbg_src_request_id), + .dbg_src_address_id (dbg_src_address_id), + .dbg_src_data_id (dbg_src_data_id), + .dbg_src_response_id (dbg_src_response_id), + + .dest_diag_level_bursts(dest_diag_level_bursts) +); + +endmodule diff --git a/src/adi/hdl/library/axi_dmac/axi_register_slice.v b/src/adi/hdl/library/axi_dmac/axi_register_slice.v new file mode 100644 index 00000000..e2eea500 --- /dev/null +++ b/src/adi/hdl/library/axi_dmac/axi_register_slice.v @@ -0,0 +1,139 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright 2014 - 2017 (c) Analog Devices, Inc. All rights reserved. +// +// In this HDL repository, there are many different and unique modules, consisting +// of various HDL (Verilog or VHDL) components. The individual modules are +// developed independently, and may be accompanied by separate and unique license +// terms. +// +// The user should read each of these license terms, and understand the +// freedoms and responsibilities that he or she has by using this source/core. +// +// This core 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. +// +// Redistribution and use of source or resulting binaries, with or without modification +// of this file, are permitted under one of the following two license terms: +// +// 1. The GNU General Public License version 2 as published by the +// Free Software Foundation, which can be found in the top level directory +// of this repository (LICENSE_GPL2), and also online at: +// +// +// OR +// +// 2. An ADI specific BSD license, which can be found in the top level directory +// of this repository (LICENSE_ADIBSD), and also on-line at: +// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD +// This will allow to generate bit files and not release the source code, +// as long as it attaches to an ADI device. +// +// *************************************************************************** +// *************************************************************************** + +`timescale 1ns/100ps + +module axi_register_slice #( + + parameter DATA_WIDTH = 32, + parameter FORWARD_REGISTERED = 0, + parameter BACKWARD_REGISTERED = 0)( + + input clk, + input resetn, + + input s_axi_valid, + output s_axi_ready, + input [DATA_WIDTH-1:0] s_axi_data, + + output m_axi_valid, + input m_axi_ready, + output [DATA_WIDTH-1:0] m_axi_data +); + +/* + s_axi_data -> bwd_data -> fwd_data(1) -> m_axi_data + s_axi_valid -> bwd_valid -> fwd_valid(1) -> m_axi_valid + s_axi_ready <- bwd_ready(2) <- fwd_ready <- m_axi_ready + + (1) FORWARD_REGISTERED inserts a set of FF before m_axi_data and m_axi_valid + (2) BACKWARD_REGISTERED insters a FF before s_axi_ready +*/ + +wire [DATA_WIDTH-1:0] bwd_data_s; +wire bwd_valid_s; +wire bwd_ready_s; +wire [DATA_WIDTH-1:0] fwd_data_s; +wire fwd_valid_s; +wire fwd_ready_s; + +generate if (FORWARD_REGISTERED == 1) begin + +reg fwd_valid = 1'b0; +reg [DATA_WIDTH-1:0] fwd_data = 'h00; + +assign fwd_ready_s = ~fwd_valid | m_axi_ready; +assign fwd_valid_s = fwd_valid; +assign fwd_data_s = fwd_data; + +always @(posedge clk) begin + if (~fwd_valid | m_axi_ready) + fwd_data <= bwd_data_s; +end + +always @(posedge clk) begin + if (resetn == 1'b0) begin + fwd_valid <= 1'b0; + end else begin + if (bwd_valid_s) + fwd_valid <= 1'b1; + else if (m_axi_ready) + fwd_valid <= 1'b0; + end +end + +end else begin +assign fwd_data_s = bwd_data_s; +assign fwd_valid_s = bwd_valid_s; +assign fwd_ready_s = m_axi_ready; +end +endgenerate + +generate if (BACKWARD_REGISTERED == 1) begin + +reg bwd_ready = 1'b1; +reg [DATA_WIDTH-1:0] bwd_data = 'h00; + +assign bwd_valid_s = ~bwd_ready | s_axi_valid; +assign bwd_data_s = bwd_ready ? s_axi_data : bwd_data; +assign bwd_ready_s = bwd_ready; + +always @(posedge clk) begin + if (bwd_ready) + bwd_data <= s_axi_data; +end + +always @(posedge clk) begin + if (resetn == 1'b0) begin + bwd_ready <= 1'b1; + end else begin + if (fwd_ready_s) + bwd_ready <= 1'b1; + else if (s_axi_valid) + bwd_ready <= 1'b0; + end +end + +end else begin +assign bwd_valid_s = s_axi_valid; +assign bwd_data_s = s_axi_data; +assign bwd_ready_s = fwd_ready_s; +end endgenerate + +assign m_axi_data = fwd_data_s; +assign m_axi_valid = fwd_valid_s; +assign s_axi_ready = bwd_ready_s; + +endmodule diff --git a/src/adi/hdl/library/axi_dmac/bd/bd.tcl b/src/adi/hdl/library/axi_dmac/bd/bd.tcl new file mode 100644 index 00000000..54dc8e76 --- /dev/null +++ b/src/adi/hdl/library/axi_dmac/bd/bd.tcl @@ -0,0 +1,161 @@ + +proc init {cellpath otherInfo} { + set ip [get_bd_cells $cellpath] + + bd::mark_propagate_override $ip \ + "ASYNC_CLK_REQ_SRC ASYNC_CLK_SRC_DEST ASYNC_CLK_DEST_REQ" + + bd::mark_propagate_only $ip \ + "DMA_AXI_ADDR_WIDTH" + + # On ZYNQ the core is most likely connected to the AXI3 HP ports so use AXI3 + # as the default. + set family [string tolower [get_property FAMILY [get_property PART [current_project]]]] + if {$family == "zynq"} { + set axi_protocol 1 + } else { + set axi_protocol 0 + } + + foreach dir {SRC DEST} { + # This is a bit of a hack, but we can't change the protocol if the type + # is not AXI MM + set old [get_property "CONFIG.DMA_TYPE_${dir}" $ip] + set_property "CONFIG.DMA_TYPE_${dir}" "0" $ip + set_property "CONFIG.DMA_AXI_PROTOCOL_${dir}" $axi_protocol $ip + set_property "CONFIG.DMA_TYPE_${dir}" $old $ip + } +} + +proc post_config_ip {cellpath otherinfo} { + set ip [get_bd_cells $cellpath] + + # Update AXI interface properties according to configuration + set max_bytes_per_burst [get_property "CONFIG.MAX_BYTES_PER_BURST" $ip] + set fifo_size [get_property "CONFIG.FIFO_SIZE" $ip] + + foreach dir {"SRC" "DEST"} { + set type [get_property "CONFIG.DMA_TYPE_$dir" $ip] + if {$type != 0} { + continue + } + + set axi_protocol [get_property "CONFIG.DMA_AXI_PROTOCOL_$dir" $ip] + set data_width [get_property "CONFIG.DMA_DATA_WIDTH_$dir" $ip] + set max_beats_per_burst [expr {int(ceil($max_bytes_per_burst * 8.0 / $data_width))}] + + if {$axi_protocol == 0} { + set axi_protocol_str "AXI4" + if {$max_beats_per_burst > 256} { + set max_beats_per_burst 256 + } + } else { + set axi_protocol_str "AXI3" + if {$max_beats_per_burst > 16} { + set max_beats_per_burst 16 + } + } + + set intf [get_bd_intf_pins [format "%s/m_%s_axi" $cellpath [string tolower $dir]]] + set_property CONFIG.PROTOCOL $axi_protocol_str $intf + set_property CONFIG.MAX_BURST_LENGTH $max_beats_per_burst $intf + + # The core issues as many requests as the amount of data the FIFO can hold + if {$dir == "SRC"} { + set_property CONFIG.NUM_WRITE_OUTSTANDING 0 $intf + set_property CONFIG.NUM_READ_OUTSTANDING $fifo_size $intf + } else { + set_property CONFIG.NUM_WRITE_OUTSTANDING $fifo_size $intf + set_property CONFIG.NUM_READ_OUTSTANDING 0 $intf + } + } +} + +proc axi_dmac_detect_async_clk { cellpath ip param_name clk_a clk_b } { + set param_src [get_property "CONFIG.$param_name.VALUE_SRC" $ip] + if {[string equal $param_src "USER"]} { + return; + } + + set clk_domain_a [get_property CONFIG.CLK_DOMAIN $clk_a] + set clk_domain_b [get_property CONFIG.CLK_DOMAIN $clk_b] + set clk_freq_a [get_property CONFIG.FREQ_HZ $clk_a] + set clk_freq_b [get_property CONFIG.FREQ_HZ $clk_b] + set clk_phase_a [get_property CONFIG.PHASE $clk_a] + set clk_phase_b [get_property CONFIG.PHASE $clk_b] + + # Only mark it as sync if we can make sure that it is sync, if the + # relationship of the clocks is unknown mark it as async + if {$clk_domain_a != {} && $clk_domain_b != {} && \ + $clk_domain_a == $clk_domain_b && $clk_freq_a == $clk_freq_b && \ + $clk_phase_a == $clk_phase_b} { + set clk_async 0 + } else { + set clk_async 1 + } + + set_property "CONFIG.$param_name" $clk_async $ip + +# if {$clk_async == 0} { +# bd::send_msg -of $cellpath -type INFO -msg_id 1 -text "$clk_a and $clk_b are synchronous" +# } else { +# bd::send_msg -of $cellpath -type INFO -msg_id 1 -text "$clk_a and $clk_b are asynchronous" +# } +} + +proc propagate {cellpath otherinfo} { + set ip [get_bd_cells $cellpath] + set src_type [get_property CONFIG.DMA_TYPE_SRC $ip] + set dest_type [get_property CONFIG.DMA_TYPE_DEST $ip] + + set req_clk [get_bd_pins "$ip/s_axi_aclk"] + + if {$src_type == 2} { + set src_clk [get_bd_pins "$ip/fifo_wr_clk"] + } elseif {$src_type == 1} { + set src_clk [get_bd_pins "$ip/s_axis_aclk"] + } else { + set src_clk [get_bd_pins "$ip/m_src_axi_aclk"] + } + + if {$dest_type == 2} { + set dest_clk [get_bd_pins "$ip/fifo_rd_clk"] + } elseif {$dest_type == 1} { + set dest_clk [get_bd_pins "$ip/m_axis_aclk"] + } else { + set dest_clk [get_bd_pins "$ip/m_dest_axi_aclk"] + } + + axi_dmac_detect_async_clk $cellpath $ip "ASYNC_CLK_REQ_SRC" $req_clk $src_clk + axi_dmac_detect_async_clk $cellpath $ip "ASYNC_CLK_SRC_DEST" $src_clk $dest_clk + axi_dmac_detect_async_clk $cellpath $ip "ASYNC_CLK_DEST_REQ" $dest_clk $req_clk +} + +proc post_propagate {cellpath otherinfo} { + set ip [get_bd_cells $cellpath] + + set addr_width 16 + + foreach dir {"SRC" "DEST"} { + set type [get_property "CONFIG.DMA_TYPE_$dir" $ip] + if {$type != 0} { + continue + } + + set intf [get_bd_intf_pins [format "%s/m_%s_axi" $cellpath [string tolower $dir]]] + set addr_segs [get_bd_addr_segs -of_objects [get_bd_addr_spaces $intf]] + + if {$addr_segs != {}} { + foreach addr_seg $addr_segs { + set range [get_property "range" $addr_seg] + set offset [get_property "offset" $addr_seg] + set addr_width [expr max(int(ceil(log($range - 1 + $offset) / log(2))), $addr_width)] + } + } else { + set addr_width 32 + } + + } + + set_property "CONFIG.DMA_AXI_ADDR_WIDTH" $addr_width $ip +} diff --git a/src/adi/hdl/library/axi_dmac/data_mover.v b/src/adi/hdl/library/axi_dmac/data_mover.v new file mode 100644 index 00000000..6da3444b --- /dev/null +++ b/src/adi/hdl/library/axi_dmac/data_mover.v @@ -0,0 +1,266 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright 2014 - 2017 (c) Analog Devices, Inc. All rights reserved. +// +// In this HDL repository, there are many different and unique modules, consisting +// of various HDL (Verilog or VHDL) components. The individual modules are +// developed independently, and may be accompanied by separate and unique license +// terms. +// +// The user should read each of these license terms, and understand the +// freedoms and responsibilities that he or she has by using this source/core. +// +// This core 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. +// +// Redistribution and use of source or resulting binaries, with or without modification +// of this file, are permitted under one of the following two license terms: +// +// 1. The GNU General Public License version 2 as published by the +// Free Software Foundation, which can be found in the top level directory +// of this repository (LICENSE_GPL2), and also online at: +// +// +// OR +// +// 2. An ADI specific BSD license, which can be found in the top level directory +// of this repository (LICENSE_ADIBSD), and also on-line at: +// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD +// This will allow to generate bit files and not release the source code, +// as long as it attaches to an ADI device. +// +// *************************************************************************** +// *************************************************************************** + +`timescale 1ns/100ps + +module dmac_data_mover #( + + parameter ID_WIDTH = 3, + parameter DATA_WIDTH = 64, + parameter BEATS_PER_BURST_WIDTH = 4, + parameter ALLOW_ABORT = 0) ( + + input clk, + input resetn, + + input [ID_WIDTH-1:0] request_id, + output [ID_WIDTH-1:0] response_id, + input eot, + + output rewind_req_valid, + input rewind_req_ready, + output [ID_WIDTH+3-1:0] rewind_req_data, + + output reg bl_valid = 'b0, + input bl_ready, + output reg [BEATS_PER_BURST_WIDTH-1:0] measured_last_burst_length, + + output block_descr_to_dst, + + output [ID_WIDTH-1:0] source_id, + output source_eot, + + output xfer_req, + + output s_axi_ready, + input s_axi_valid, + input [DATA_WIDTH-1:0] s_axi_data, + input s_axi_last, + input s_axi_sync, + + output m_axi_valid, + output [DATA_WIDTH-1:0] m_axi_data, + output m_axi_last, + output m_axi_partial_burst, + + input req_valid, + output req_ready, + input [BEATS_PER_BURST_WIDTH-1:0] req_last_burst_length, + input req_sync_transfer_start, + input req_xlast +); + +localparam BEAT_COUNTER_MAX = {BEATS_PER_BURST_WIDTH{1'b1}}; + +`include "inc_id.vh" + +reg [BEATS_PER_BURST_WIDTH-1:0] last_burst_length = 'h00; +reg [BEATS_PER_BURST_WIDTH-1:0] beat_counter = 'h00; +reg [BEATS_PER_BURST_WIDTH-1:0] beat_counter_minus_one = 'h0; +reg [ID_WIDTH-1:0] id = 'h00; +reg [ID_WIDTH-1:0] id_next = 'h00; + +reg pending_burst = 1'b0; +reg active = 1'b0; +reg last_eot = 1'b0; +reg last_non_eot = 1'b0; + +reg needs_sync = 1'b0; +wire has_sync = ~needs_sync | s_axi_sync; + +wire s_axi_sync_valid = has_sync & s_axi_valid; +wire transfer_abort_s; + +wire last_load; +wire last; +wire early_tlast; + +assign xfer_req = active; + +assign response_id = id; + +assign source_id = id; +assign source_eot = eot || early_tlast; + +assign last = eot ? last_eot : last_non_eot; + +assign s_axi_ready = (pending_burst & active) & ~transfer_abort_s; +assign m_axi_valid = s_axi_sync_valid & s_axi_ready; +assign m_axi_data = s_axi_data; +assign m_axi_last = last || early_tlast; +assign m_axi_partial_burst = early_tlast; + +assign block_descr_to_dst = transfer_abort_s; + +generate if (ALLOW_ABORT == 1) begin + wire programmed_last; + + reg transfer_abort = 1'b0; + reg req_xlast_d = 1'b0; + reg [1:0] transfer_id = 2'b0; + + assign programmed_last = (last == 1'b1 && eot == 1'b1 && req_xlast_d == 1'b1); + /* + * A 'last' on the external interface indicates the end of an packet. If such a + * 'last' indicator is observed before the end of the current transfer stop + * accepting data on the external interface until a new descriptor is + * received that is the first segment of a transfer. + */ + always @(posedge clk) begin + if (resetn == 1'b0) begin + transfer_abort <= 1'b0; + end else if (req_valid == 1'b1 && req_ready == 1'b1 && req_xlast_d == 1'b1) begin + transfer_abort <= 1'b0; + end else if (m_axi_valid == 1'b1) begin + if (programmed_last == 1'b1) begin + transfer_abort <= 1'b0; + end else if (s_axi_last == 1'b1) begin + transfer_abort <= 1'b1; + end + end + end + + always @(posedge clk) begin + if (req_ready == 1'b1 && req_valid == 1'b1) begin + req_xlast_d <= req_xlast; + end + end + + assign transfer_abort_s = transfer_abort; + assign early_tlast = (s_axi_ready == 1'b1) && (m_axi_valid == 1'b1) && + (s_axi_last == 1'b1) && (programmed_last == 1'b0); + + assign rewind_req_valid = early_tlast; + assign rewind_req_data = {transfer_id,req_xlast_d,id_next}; + + // The width of the id must fit the number of transfers that can be in flight + // in the burst memory + always @(posedge clk) begin + if (resetn == 1'b0) begin + transfer_id <= 2'b0; + end else if (req_valid == 1'b1 && req_ready == 1'b1) begin + transfer_id <= transfer_id + 1'b1; + end + end + +end else begin + assign transfer_abort_s = 1'b0; + assign early_tlast = 1'b0; + assign rewind_req_valid = 1'b0; + assign rewind_req_data = 'h0; +end endgenerate + +/* + * If req_sync_transfer_start is set all incoming beats will be skipped until + * one has s_axi_sync set. This will be the first beat that is passsed through. + */ +always @(posedge clk) begin + if (req_ready == 1'b1) begin + needs_sync <= req_sync_transfer_start; + end else if (m_axi_valid == 1'b1) begin + needs_sync <= 1'b0; + end +end + +// If we want to support zero delay between transfers we have to assert +// req_ready on the same cycle on which the last load happens. +assign last_load = m_axi_valid && last_eot && eot; +assign req_ready = last_load || ~active || (transfer_abort_s & rewind_req_ready); + +always @(posedge clk) begin + if (req_ready) begin + last_eot <= req_last_burst_length == 'h0; + last_non_eot <= 1'b0; + beat_counter <= 'h1; + end else if (m_axi_valid == 1'b1) begin + last_eot <= beat_counter == last_burst_length; + last_non_eot <= beat_counter == BEAT_COUNTER_MAX; + beat_counter <= beat_counter + 1'b1; + end +end + +always @(posedge clk) begin + if (req_ready) + last_burst_length <= req_last_burst_length; +end + +always @(posedge clk) begin + if (req_ready) begin + beat_counter_minus_one <= 'h0; + end else if (m_axi_valid == 1'b1) begin + beat_counter_minus_one <= beat_counter; + end +end + +always @(posedge clk) begin + if (last_load || early_tlast) begin + bl_valid <= 1'b1; + measured_last_burst_length <= beat_counter_minus_one; + end else if (bl_ready) begin + bl_valid <= 1'b0; + end +end + +always @(posedge clk) begin + if (resetn == 1'b0) begin + active <= 1'b0; + end else if (req_valid == 1'b1) begin + active <= 1'b1; + end else if (last_load == 1'b1) begin + active <= 1'b0; + end +end + +always @(*) +begin + if (m_axi_valid == 1'b1 && (last == 1'b1 || early_tlast == 1'b1)) + id_next <= inc_id(id); + else + id_next <= id; +end + +always @(posedge clk) begin + if (resetn == 1'b0) begin + id <= 'h0; + end else begin + id <= id_next; + end +end + +always @(posedge clk) begin + pending_burst <= id_next != request_id; +end + +endmodule diff --git a/src/adi/hdl/library/axi_dmac/dest_axi_mm.v b/src/adi/hdl/library/axi_dmac/dest_axi_mm.v new file mode 100644 index 00000000..7b54c485 --- /dev/null +++ b/src/adi/hdl/library/axi_dmac/dest_axi_mm.v @@ -0,0 +1,191 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright 2014 - 2017 (c) Analog Devices, Inc. All rights reserved. +// +// In this HDL repository, there are many different and unique modules, consisting +// of various HDL (Verilog or VHDL) components. The individual modules are +// developed independently, and may be accompanied by separate and unique license +// terms. +// +// The user should read each of these license terms, and understand the +// freedoms and responsibilities that he or she has by using this source/core. +// +// This core 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. +// +// Redistribution and use of source or resulting binaries, with or without modification +// of this file, are permitted under one of the following two license terms: +// +// 1. The GNU General Public License version 2 as published by the +// Free Software Foundation, which can be found in the top level directory +// of this repository (LICENSE_GPL2), and also online at: +// +// +// OR +// +// 2. An ADI specific BSD license, which can be found in the top level directory +// of this repository (LICENSE_ADIBSD), and also on-line at: +// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD +// This will allow to generate bit files and not release the source code, +// as long as it attaches to an ADI device. +// +// *************************************************************************** +// *************************************************************************** + +`timescale 1ns/100ps + +module dmac_dest_mm_axi #( + + parameter ID_WIDTH = 3, + parameter DMA_DATA_WIDTH = 64, + parameter DMA_ADDR_WIDTH = 32, + parameter BYTES_PER_BEAT_WIDTH = $clog2(DMA_DATA_WIDTH/8), + parameter BEATS_PER_BURST_WIDTH = 4, + parameter MAX_BYTES_PER_BURST = 128, + parameter BYTES_PER_BURST_WIDTH = $clog2(MAX_BYTES_PER_BURST), + parameter AXI_LENGTH_WIDTH = 8)( + + input m_axi_aclk, + input m_axi_aresetn, + + input req_valid, + output req_ready, + input [DMA_ADDR_WIDTH-1:BYTES_PER_BEAT_WIDTH] req_address, + + input bl_valid, + output bl_ready, + input [BEATS_PER_BURST_WIDTH-1:0] measured_last_burst_length, + + input enable, + output enabled, + + output response_valid, + input response_ready, + output [1:0] response_resp, + output response_resp_eot, + output response_resp_partial, + output [BYTES_PER_BURST_WIDTH-1:0] response_data_burst_length, + + input [ID_WIDTH-1:0] request_id, + output [ID_WIDTH-1:0] response_id, + + output [ID_WIDTH-1:0] address_id, + input address_eot, + input response_eot, + + input fifo_valid, + output fifo_ready, + input [DMA_DATA_WIDTH-1:0] fifo_data, + input fifo_last, + + input [BYTES_PER_BURST_WIDTH-1:0] dest_burst_info_length, + input dest_burst_info_partial, + input [ID_WIDTH-1:0] dest_burst_info_id, + input dest_burst_info_write, + // Write address + input m_axi_awready, + output m_axi_awvalid, + output [DMA_ADDR_WIDTH-1:0] m_axi_awaddr, + output [AXI_LENGTH_WIDTH-1:0] m_axi_awlen, + output [ 2:0] m_axi_awsize, + output [ 1:0] m_axi_awburst, + output [ 2:0] m_axi_awprot, + output [ 3:0] m_axi_awcache, + + // Write data + output [DMA_DATA_WIDTH-1:0] m_axi_wdata, + output [(DMA_DATA_WIDTH/8)-1:0] m_axi_wstrb, + input m_axi_wready, + output m_axi_wvalid, + output m_axi_wlast, + + // Write response + input m_axi_bvalid, + input [ 1:0] m_axi_bresp, + output m_axi_bready +); + +wire address_enabled; + +dmac_address_generator #( + .ID_WIDTH(ID_WIDTH), + .BEATS_PER_BURST_WIDTH(BEATS_PER_BURST_WIDTH), + .BYTES_PER_BEAT_WIDTH(BYTES_PER_BEAT_WIDTH), + .DMA_DATA_WIDTH(DMA_DATA_WIDTH), + .LENGTH_WIDTH(AXI_LENGTH_WIDTH), + .DMA_ADDR_WIDTH(DMA_ADDR_WIDTH) +) i_addr_gen ( + .clk(m_axi_aclk), + .resetn(m_axi_aresetn), + + .enable(enable), + .enabled(address_enabled), + + .id(address_id), + .request_id(request_id), + + .req_valid(req_valid), + .req_ready(req_ready), + .req_address(req_address), + + .bl_valid(bl_valid), + .bl_ready(bl_ready), + .measured_last_burst_length(measured_last_burst_length), + + .eot(address_eot), + + .addr_ready(m_axi_awready), + .addr_valid(m_axi_awvalid), + .addr(m_axi_awaddr), + .len(m_axi_awlen), + .size(m_axi_awsize), + .burst(m_axi_awburst), + .prot(m_axi_awprot), + .cache(m_axi_awcache) +); + +assign m_axi_wvalid = fifo_valid; +assign fifo_ready = m_axi_wready; +assign m_axi_wlast = fifo_last; +assign m_axi_wdata = fifo_data; + +assign m_axi_wstrb = {(DMA_DATA_WIDTH/8){1'b1}}; + +dmac_response_handler #( + .ID_WIDTH(ID_WIDTH) +) i_response_handler ( + .clk(m_axi_aclk), + .resetn(m_axi_aresetn), + .bvalid(m_axi_bvalid), + .bready(m_axi_bready), + .bresp(m_axi_bresp), + + .enable(address_enabled), + .enabled(enabled), + + .id(response_id), + .request_id(address_id), + + .eot(response_eot), + + .resp_valid(response_valid), + .resp_ready(response_ready), + .resp_resp(response_resp), + .resp_eot(response_resp_eot) +); + +reg [BYTES_PER_BURST_WIDTH+1-1:0] bl_mem [0:2**(ID_WIDTH)-1]; + +assign {response_resp_partial, + response_data_burst_length} = bl_mem[response_id]; + +always @(posedge m_axi_aclk) begin + if (dest_burst_info_write) begin + bl_mem[dest_burst_info_id] <= {dest_burst_info_partial, + dest_burst_info_length}; + end +end + + +endmodule diff --git a/src/adi/hdl/library/axi_dmac/dest_axi_stream.v b/src/adi/hdl/library/axi_dmac/dest_axi_stream.v new file mode 100644 index 00000000..b377d8e6 --- /dev/null +++ b/src/adi/hdl/library/axi_dmac/dest_axi_stream.v @@ -0,0 +1,156 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright 2014 - 2017 (c) Analog Devices, Inc. All rights reserved. +// +// In this HDL repository, there are many different and unique modules, consisting +// of various HDL (Verilog or VHDL) components. The individual modules are +// developed independently, and may be accompanied by separate and unique license +// terms. +// +// The user should read each of these license terms, and understand the +// freedoms and responsibilities that he or she has by using this source/core. +// +// This core 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. +// +// Redistribution and use of source or resulting binaries, with or without modification +// of this file, are permitted under one of the following two license terms: +// +// 1. The GNU General Public License version 2 as published by the +// Free Software Foundation, which can be found in the top level directory +// of this repository (LICENSE_GPL2), and also online at: +// +// +// OR +// +// 2. An ADI specific BSD license, which can be found in the top level directory +// of this repository (LICENSE_ADIBSD), and also on-line at: +// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD +// This will allow to generate bit files and not release the source code, +// as long as it attaches to an ADI device. +// +// *************************************************************************** +// *************************************************************************** + +`timescale 1ns/100ps + +module dmac_dest_axi_stream #( + + parameter ID_WIDTH = 3, + parameter S_AXIS_DATA_WIDTH = 64, + parameter BEATS_PER_BURST_WIDTH = 4)( + + input s_axis_aclk, + input s_axis_aresetn, + + input enable, + output enabled, + output xfer_req, + + output [ID_WIDTH-1:0] response_id, + output [ID_WIDTH-1:0] data_id, + input data_eot, + input response_eot, + + input m_axis_ready, + output m_axis_valid, + output [S_AXIS_DATA_WIDTH-1:0] m_axis_data, + output m_axis_last, + + output fifo_ready, + input fifo_valid, + input [S_AXIS_DATA_WIDTH-1:0] fifo_data, + input fifo_last, + + input req_valid, + output req_ready, + input req_xlast, + + output response_valid, + input response_ready, + output response_resp_eot, + output [1:0] response_resp +); + +`include "inc_id.vh" + +reg data_enabled = 1'b0; +reg req_xlast_d = 1'b0; +reg active = 1'b0; + +reg [ID_WIDTH-1:0] id = 'h0; + +/* Last beat of the burst */ +wire fifo_last_beat; +/* Last beat of the segment */ +wire fifo_eot_beat; + +/* fifo_last == 1'b1 implies fifo_valid == 1'b1 */ +assign fifo_last_beat = fifo_ready & fifo_last; +assign fifo_eot_beat = fifo_last_beat & data_eot; + +assign req_ready = fifo_eot_beat | ~active; +assign data_id = id; +assign xfer_req = active; + +assign m_axis_valid = fifo_valid & active; +assign fifo_ready = m_axis_ready & active; +assign m_axis_last = req_xlast_d & fifo_last & data_eot; +assign m_axis_data = fifo_data; + +always @(posedge s_axis_aclk) begin + if (s_axis_aresetn == 1'b0) begin + data_enabled <= 1'b0; + end else if (enable == 1'b1) begin + data_enabled <= 1'b1; + end else if (m_axis_valid == 1'b0 || m_axis_ready == 1'b1) begin + data_enabled <= 1'b0; + end +end + +always @(posedge s_axis_aclk) begin + if (req_ready == 1'b1) begin + req_xlast_d <= req_xlast; + end +end + +always @(posedge s_axis_aclk) begin + if (s_axis_aresetn == 1'b0) begin + active <= 1'b0; + end else if (req_valid == 1'b1) begin + active <= 1'b1; + end else if (fifo_eot_beat == 1'b1) begin + active <= 1'b0; + end +end + +always @(posedge s_axis_aclk) begin + if (s_axis_aresetn == 1'b0) begin + id <= 'h00; + end else if (fifo_last_beat == 1'b1) begin + id <= inc_id(id); + end +end + +dmac_response_generator # ( + .ID_WIDTH(ID_WIDTH) +) i_response_generator ( + .clk(s_axis_aclk), + .resetn(s_axis_aresetn), + + .enable(data_enabled), + .enabled(enabled), + + .request_id(id), + .response_id(response_id), + + .eot(response_eot), + + .resp_valid(response_valid), + .resp_ready(response_ready), + .resp_eot(response_resp_eot), + .resp_resp(response_resp) +); + +endmodule diff --git a/src/adi/hdl/library/axi_dmac/dest_fifo_inf.v b/src/adi/hdl/library/axi_dmac/dest_fifo_inf.v new file mode 100644 index 00000000..486c7c3c --- /dev/null +++ b/src/adi/hdl/library/axi_dmac/dest_fifo_inf.v @@ -0,0 +1,144 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright 2014 - 2017 (c) Analog Devices, Inc. All rights reserved. +// +// In this HDL repository, there are many different and unique modules, consisting +// of various HDL (Verilog or VHDL) components. The individual modules are +// developed independently, and may be accompanied by separate and unique license +// terms. +// +// The user should read each of these license terms, and understand the +// freedoms and responsibilities that he or she has by using this source/core. +// +// This core 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. +// +// Redistribution and use of source or resulting binaries, with or without modification +// of this file, are permitted under one of the following two license terms: +// +// 1. The GNU General Public License version 2 as published by the +// Free Software Foundation, which can be found in the top level directory +// of this repository (LICENSE_GPL2), and also online at: +// +// +// OR +// +// 2. An ADI specific BSD license, which can be found in the top level directory +// of this repository (LICENSE_ADIBSD), and also on-line at: +// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD +// This will allow to generate bit files and not release the source code, +// as long as it attaches to an ADI device. +// +// *************************************************************************** +// *************************************************************************** + +`timescale 1ns/100ps + +module dmac_dest_fifo_inf #( + + parameter ID_WIDTH = 3, + parameter DATA_WIDTH = 64, + parameter BEATS_PER_BURST_WIDTH = 4)( + + input clk, + input resetn, + + input enable, + output enabled, + + input req_valid, + output req_ready, + + output [ID_WIDTH-1:0] response_id, + output reg [ID_WIDTH-1:0] data_id = 'h0, + input data_eot, + input response_eot, + + input en, + output reg [DATA_WIDTH-1:0] dout, + output reg valid, + output reg underflow, + + output xfer_req, + + output fifo_ready, + input fifo_valid, + input [DATA_WIDTH-1:0] fifo_data, + input fifo_last, + + output response_valid, + input response_ready, + output response_resp_eot, + output [1:0] response_resp +); + +`include "inc_id.vh" + +reg active = 1'b0; + +/* Last beat of the burst */ +wire fifo_last_beat; +/* Last beat of the segment */ +wire fifo_eot_beat; + +assign enabled = enable; +assign fifo_ready = en & (fifo_valid | ~enable); + +/* fifo_last == 1'b1 implies fifo_valid == 1'b1 */ +assign fifo_last_beat = fifo_ready & fifo_last; +assign fifo_eot_beat = fifo_last_beat & data_eot; + +assign req_ready = fifo_eot_beat | ~active; +assign xfer_req = active; + +always @(posedge clk) begin + if (en) begin + dout <= fifo_valid ? fifo_data : {DATA_WIDTH{1'b0}}; + valid <= fifo_valid & enable; + underflow <= ~(fifo_valid & enable); + end else begin + valid <= 1'b0; + underflow <= 1'b0; + end +end + +always @(posedge clk) begin + if (resetn == 1'b0) begin + data_id <= 'h00; + end else if (fifo_last_beat == 1'b1) begin + data_id <= inc_id(data_id); + end +end + +always @(posedge clk) begin + if (resetn == 1'b0) begin + active <= 1'b0; + end else if (req_valid == 1'b1) begin + active <= 1'b1; + end else if (fifo_eot_beat == 1'b1) begin + active <= 1'b0; + end +end + +dmac_response_generator # ( + .ID_WIDTH(ID_WIDTH) +) i_response_generator ( + .clk(clk), + .resetn(resetn), + + .enable(enable), + .enabled(), + + .request_id(data_id), + .response_id(response_id), + + .eot(response_eot), + + .resp_valid(response_valid), + .resp_ready(response_ready), + .resp_eot(response_resp_eot), + .resp_resp(response_resp) +); + +endmodule diff --git a/src/adi/hdl/library/axi_dmac/inc_id.vh b/src/adi/hdl/library/axi_dmac/inc_id.vh new file mode 100644 index 00000000..4213143a --- /dev/null +++ b/src/adi/hdl/library/axi_dmac/inc_id.vh @@ -0,0 +1,67 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright 2013(c) Analog Devices, Inc. +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// - Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// - Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in +// the documentation and/or other materials provided with the +// distribution. +// - Neither the name of Analog Devices, Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// - The use of this software may or may not infringe the patent rights +// of one or more patent holders. This license does not release you +// from the requirement that you obtain separate licenses from these +// patent holders to use this software. +// - Use of the software either in source or binary form, must be run +// on or directly connected to an Analog Devices Inc. component. +// +// THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, +// INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A +// PARTICULAR PURPOSE ARE DISCLAIMED. +// +// IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, INTELLECTUAL PROPERTY +// RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR +// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF +// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// *************************************************************************** +// *************************************************************************** + +function [ID_WIDTH-1:0] g2b; + input [ID_WIDTH-1:0] g; + reg [ID_WIDTH-1:0] b; + integer i; + begin + b[ID_WIDTH-1] = g[ID_WIDTH-1]; + for (i = ID_WIDTH - 2; i >= 0; i = i - 1) + b[i] = b[i + 1] ^ g[i]; + g2b = b; + end +endfunction + +function [ID_WIDTH-1:0] b2g; + input [ID_WIDTH-1:0] b; + reg [ID_WIDTH-1:0] g; + integer i; + begin + g[ID_WIDTH-1] = b[ID_WIDTH-1]; + for (i = ID_WIDTH - 2; i >= 0; i = i -1) + g[i] = b[i + 1] ^ b[i]; + b2g = g; + end +endfunction + +function [ID_WIDTH-1:0] inc_id; +input [ID_WIDTH-1:0] id; +begin + inc_id = b2g(g2b(id) + 1); +end +endfunction diff --git a/src/adi/hdl/library/axi_dmac/request_arb.v b/src/adi/hdl/library/axi_dmac/request_arb.v new file mode 100644 index 00000000..3ae9cf18 --- /dev/null +++ b/src/adi/hdl/library/axi_dmac/request_arb.v @@ -0,0 +1,1171 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright 2014 - 2017 (c) Analog Devices, Inc. All rights reserved. +// +// In this HDL repository, there are many different and unique modules, consisting +// of various HDL (Verilog or VHDL) components. The individual modules are +// developed independently, and may be accompanied by separate and unique license +// terms. +// +// The user should read each of these license terms, and understand the +// freedoms and responsibilities that he or she has by using this source/core. +// +// This core 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. +// +// Redistribution and use of source or resulting binaries, with or without modification +// of this file, are permitted under one of the following two license terms: +// +// 1. The GNU General Public License version 2 as published by the +// Free Software Foundation, which can be found in the top level directory +// of this repository (LICENSE_GPL2), and also online at: +// +// +// OR +// +// 2. An ADI specific BSD license, which can be found in the top level directory +// of this repository (LICENSE_ADIBSD), and also on-line at: +// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD +// This will allow to generate bit files and not release the source code, +// as long as it attaches to an ADI device. +// +// *************************************************************************** +// *************************************************************************** + +`timescale 1ns/100ps + +module dmac_request_arb #( + parameter DMA_DATA_WIDTH_SRC = 64, + parameter DMA_DATA_WIDTH_DEST = 64, + parameter DMA_LENGTH_WIDTH = 24, + parameter BYTES_PER_BEAT_WIDTH_DEST = $clog2(DMA_DATA_WIDTH_DEST/8), + parameter BYTES_PER_BEAT_WIDTH_SRC = $clog2(DMA_DATA_WIDTH_SRC/8), + parameter DMA_TYPE_DEST = 0, + parameter DMA_TYPE_SRC = 2, + parameter DMA_AXI_ADDR_WIDTH = 32, + parameter ASYNC_CLK_REQ_SRC = 1, + parameter ASYNC_CLK_SRC_DEST = 1, + parameter ASYNC_CLK_DEST_REQ = 1, + parameter AXI_SLICE_DEST = 0, + parameter AXI_SLICE_SRC = 0, + parameter MAX_BYTES_PER_BURST = 128, + parameter BYTES_PER_BURST_WIDTH = 7, + parameter FIFO_SIZE = 8, + parameter ID_WIDTH = $clog2(FIFO_SIZE*2), + parameter AXI_LENGTH_WIDTH_SRC = 8, + parameter AXI_LENGTH_WIDTH_DEST = 8, + parameter ENABLE_DIAGNOSTICS_IF = 0)( + + input req_clk, + input req_resetn, + + input req_valid, + output req_ready, + input [DMA_AXI_ADDR_WIDTH-1:BYTES_PER_BEAT_WIDTH_DEST] req_dest_address, + input [DMA_AXI_ADDR_WIDTH-1:BYTES_PER_BEAT_WIDTH_SRC] req_src_address, + input [DMA_LENGTH_WIDTH-1:0] req_length, + input req_xlast, + input req_sync_transfer_start, + + output eot, + output [BYTES_PER_BURST_WIDTH-1:0] measured_burst_length, + output response_partial, + output response_valid, + input response_ready, + + output abort_req, + + // Master AXI interface + input m_dest_axi_aclk, + input m_dest_axi_aresetn, + input m_src_axi_aclk, + input m_src_axi_aresetn, + + // Write address + output [DMA_AXI_ADDR_WIDTH-1:0] m_axi_awaddr, + output [AXI_LENGTH_WIDTH_DEST-1:0] m_axi_awlen, + output [ 2:0] m_axi_awsize, + output [ 1:0] m_axi_awburst, + output [ 2:0] m_axi_awprot, + output [ 3:0] m_axi_awcache, + output m_axi_awvalid, + input m_axi_awready, + + // Write data + output [DMA_DATA_WIDTH_DEST-1:0] m_axi_wdata, + output [(DMA_DATA_WIDTH_DEST/8)-1:0] m_axi_wstrb, + input m_axi_wready, + output m_axi_wvalid, + output m_axi_wlast, + + // Write response + input m_axi_bvalid, + input [ 1:0] m_axi_bresp, + output m_axi_bready, + + // Read address + input m_axi_arready, + output m_axi_arvalid, + output [DMA_AXI_ADDR_WIDTH-1:0] m_axi_araddr, + output [AXI_LENGTH_WIDTH_SRC-1:0] m_axi_arlen, + output [ 2:0] m_axi_arsize, + output [ 1:0] m_axi_arburst, + output [ 2:0] m_axi_arprot, + output [ 3:0] m_axi_arcache, + + // Read data and response + input [DMA_DATA_WIDTH_SRC-1:0] m_axi_rdata, + output m_axi_rready, + input m_axi_rvalid, + input m_axi_rlast, + input [ 1:0] m_axi_rresp, + + // Slave streaming AXI interface + input s_axis_aclk, + output s_axis_ready, + input s_axis_valid, + input [DMA_DATA_WIDTH_SRC-1:0] s_axis_data, + input s_axis_last, + input [0:0] s_axis_user, + output s_axis_xfer_req, + + // Master streaming AXI interface + input m_axis_aclk, + input m_axis_ready, + output m_axis_valid, + output [DMA_DATA_WIDTH_DEST-1:0] m_axis_data, + output m_axis_last, + output m_axis_xfer_req, + + // Input FIFO interface + input fifo_wr_clk, + input fifo_wr_en, + input [DMA_DATA_WIDTH_SRC-1:0] fifo_wr_din, + output fifo_wr_overflow, + input fifo_wr_sync, + output fifo_wr_xfer_req, + + // Input FIFO interface + input fifo_rd_clk, + input fifo_rd_en, + output fifo_rd_valid, + output [DMA_DATA_WIDTH_DEST-1:0] fifo_rd_dout, + output fifo_rd_underflow, + output fifo_rd_xfer_req, + + output [ID_WIDTH-1:0] dbg_dest_request_id, + output [ID_WIDTH-1:0] dbg_dest_address_id, + output [ID_WIDTH-1:0] dbg_dest_data_id, + output [ID_WIDTH-1:0] dbg_dest_response_id, + output [ID_WIDTH-1:0] dbg_src_request_id, + output [ID_WIDTH-1:0] dbg_src_address_id, + output [ID_WIDTH-1:0] dbg_src_data_id, + output [ID_WIDTH-1:0] dbg_src_response_id, + + input req_enable, + + output dest_clk, + input dest_resetn, + output dest_ext_resetn, + input dest_enable, + output dest_enabled, + + output src_clk, + input src_resetn, + output src_ext_resetn, + input src_enable, + output src_enabled, + + // Diagnostics interface + output [7:0] dest_diag_level_bursts +); + +localparam DMA_TYPE_MM_AXI = 0; +localparam DMA_TYPE_STREAM_AXI = 1; +localparam DMA_TYPE_FIFO = 2; + +localparam DMA_ADDRESS_WIDTH_DEST = DMA_AXI_ADDR_WIDTH - BYTES_PER_BEAT_WIDTH_DEST; +localparam DMA_ADDRESS_WIDTH_SRC = DMA_AXI_ADDR_WIDTH - BYTES_PER_BEAT_WIDTH_SRC; + +// Bytes per burst is the same for both dest and src, but bytes per beat may +// differ, so beats per burst may also differ + +localparam BEATS_PER_BURST_WIDTH_SRC = BYTES_PER_BURST_WIDTH - BYTES_PER_BEAT_WIDTH_SRC; +localparam BEATS_PER_BURST_WIDTH_DEST = BYTES_PER_BURST_WIDTH - BYTES_PER_BEAT_WIDTH_DEST; + +localparam BURSTS_PER_TRANSFER_WIDTH = DMA_LENGTH_WIDTH - BYTES_PER_BURST_WIDTH; + + +reg eot_mem_src[0:2**ID_WIDTH-1]; +reg eot_mem_dest[0:2**ID_WIDTH-1]; +wire request_eot; +wire source_eot; + +wire [ID_WIDTH-1:0] request_id; +wire [ID_WIDTH-1:0] source_id; +wire [ID_WIDTH-1:0] response_id; + +wire enabled_src; +wire enabled_dest; + +wire req_gen_valid; +wire req_gen_ready; +wire src_dest_valid; +wire src_dest_ready; +wire req_src_valid; +wire req_src_ready; + +wire dest_req_valid; +wire dest_req_ready; +wire [DMA_ADDRESS_WIDTH_DEST-1:0] dest_req_dest_address; +wire dest_req_xlast; + +wire dest_response_valid; +wire dest_response_ready; +wire [1:0] dest_response_resp; +wire dest_response_resp_eot; +wire [BYTES_PER_BURST_WIDTH-1:0] dest_response_data_burst_length; +wire dest_response_partial; + +wire [ID_WIDTH-1:0] dest_request_id; +wire [ID_WIDTH-1:0] dest_data_request_id; +wire [ID_WIDTH-1:0] dest_data_response_id; +wire [ID_WIDTH-1:0] dest_response_id; + +wire dest_valid; +wire dest_ready; +wire [DMA_DATA_WIDTH_DEST-1:0] dest_data; +wire dest_last; +wire dest_fifo_valid; +wire dest_fifo_ready; +wire [DMA_DATA_WIDTH_DEST-1:0] dest_fifo_data; +wire dest_fifo_last; + +wire src_req_valid; +wire src_req_ready; +wire [DMA_ADDRESS_WIDTH_DEST-1:0] src_req_dest_address; +wire [DMA_ADDRESS_WIDTH_SRC-1:0] src_req_src_address; +wire [BEATS_PER_BURST_WIDTH_SRC-1:0] src_req_last_burst_length; +wire src_req_sync_transfer_start; +wire src_req_xlast; + +reg [DMA_ADDRESS_WIDTH_DEST-1:0] src_req_dest_address_cur = 'h0; +reg src_req_xlast_cur = 1'b0; + +/* TODO +wire src_response_valid; +wire src_response_ready; +wire src_response_empty; +wire [1:0] src_response_resp; +*/ + +wire [ID_WIDTH-1:0] src_request_id; +reg [ID_WIDTH-1:0] src_throttled_request_id; +wire [ID_WIDTH-1:0] src_data_request_id; +wire [ID_WIDTH-1:0] src_response_id; + +wire src_valid; +wire [DMA_DATA_WIDTH_SRC-1:0] src_data; +wire src_last; +wire src_partial_burst; +wire block_descr_to_dst; +wire src_fifo_valid; +wire [DMA_DATA_WIDTH_SRC-1:0] src_fifo_data; +wire src_fifo_last; +wire src_fifo_partial_burst; + +wire src_bl_valid; +wire src_bl_ready; +wire [BEATS_PER_BURST_WIDTH_SRC-1:0] src_burst_length; + +wire [BYTES_PER_BURST_WIDTH-1:0] dest_burst_info_length; +wire dest_burst_info_partial; +wire [ID_WIDTH-1:0] dest_burst_info_id; +wire dest_burst_info_write; + +reg src_dest_valid_hs = 1'b0; +wire src_dest_valid_hs_masked; +wire src_dest_ready_hs; + +wire req_rewind_req_valid; +wire [ID_WIDTH+3-1:0] req_rewind_req_data; + +wire completion_req_valid; +wire completion_req_last; +wire [1:0] completion_transfer_id; + +wire rewind_req_valid; +wire rewind_req_ready; +wire [ID_WIDTH+3-1:0] rewind_req_data; + +reg src_throttler_enabled = 1'b1; +wire src_throttler_enable; +wire rewind_state; + +/* Unused for now +wire response_src_valid; +wire response_src_ready = 1'b1; +wire [1:0] response_src_resp; +*/ + +assign dbg_dest_request_id = dest_request_id; +assign dbg_dest_response_id = dest_response_id; +assign dbg_src_request_id = src_request_id; +assign dbg_src_response_id = src_response_id; + +always @(posedge req_clk) +begin + eot_mem_src[request_id] <= request_eot; +end + +always @(posedge src_clk) +begin + eot_mem_dest[source_id] <= source_eot; +end + + +generate if (DMA_TYPE_DEST == DMA_TYPE_MM_AXI) begin + +wire dest_bl_valid; +wire dest_bl_ready; +wire [BEATS_PER_BURST_WIDTH_DEST-1:0] dest_burst_length; +wire [BEATS_PER_BURST_WIDTH_SRC-1:0] dest_src_burst_length; + +assign dest_clk = m_dest_axi_aclk; +assign dest_ext_resetn = m_dest_axi_aresetn; + +wire [ID_WIDTH-1:0] dest_address_id; +wire dest_address_eot = eot_mem_dest[dest_address_id]; +wire dest_response_eot = eot_mem_dest[dest_response_id]; + +assign dbg_dest_address_id = dest_address_id; +assign dbg_dest_data_id = dest_data_response_id; + +assign dest_data_request_id = dest_address_id; + +dmac_dest_mm_axi #( + .ID_WIDTH(ID_WIDTH), + .DMA_DATA_WIDTH(DMA_DATA_WIDTH_DEST), + .DMA_ADDR_WIDTH(DMA_AXI_ADDR_WIDTH), + .BEATS_PER_BURST_WIDTH(BEATS_PER_BURST_WIDTH_DEST), + .BYTES_PER_BEAT_WIDTH(BYTES_PER_BEAT_WIDTH_DEST), + .MAX_BYTES_PER_BURST(MAX_BYTES_PER_BURST), + .BYTES_PER_BURST_WIDTH(BYTES_PER_BURST_WIDTH), + .AXI_LENGTH_WIDTH(AXI_LENGTH_WIDTH_DEST) +) i_dest_dma_mm ( + .m_axi_aclk(m_dest_axi_aclk), + .m_axi_aresetn(dest_resetn), + + .enable(dest_enable), + .enabled(dest_enabled), + + .req_valid(dest_req_valid), + .req_ready(dest_req_ready), + .req_address(dest_req_dest_address), + + .bl_valid(dest_bl_valid), + .bl_ready(dest_bl_ready), + .measured_last_burst_length(dest_burst_length), + + .response_valid(dest_response_valid), + .response_ready(dest_response_ready), + .response_resp(dest_response_resp), + .response_resp_eot(dest_response_resp_eot), + .response_resp_partial(dest_response_partial), + .response_data_burst_length(dest_response_data_burst_length), + + .request_id(dest_request_id), + .response_id(dest_response_id), + + .address_id(dest_address_id), + + .address_eot(dest_address_eot), + .response_eot(dest_response_eot), + + .fifo_valid(dest_valid), + .fifo_ready(dest_ready), + .fifo_data(dest_data), + .fifo_last(dest_last), + + .dest_burst_info_length(dest_burst_info_length), + .dest_burst_info_partial(dest_burst_info_partial), + .dest_burst_info_id(dest_burst_info_id), + .dest_burst_info_write(dest_burst_info_write), + + .m_axi_awready(m_axi_awready), + .m_axi_awvalid(m_axi_awvalid), + .m_axi_awaddr(m_axi_awaddr), + .m_axi_awlen(m_axi_awlen), + .m_axi_awsize(m_axi_awsize), + .m_axi_awburst(m_axi_awburst), + .m_axi_awprot(m_axi_awprot), + .m_axi_awcache(m_axi_awcache), + .m_axi_wready(m_axi_wready), + .m_axi_wvalid(m_axi_wvalid), + .m_axi_wdata(m_axi_wdata), + .m_axi_wstrb(m_axi_wstrb), + .m_axi_wlast(m_axi_wlast), + + .m_axi_bvalid(m_axi_bvalid), + .m_axi_bresp(m_axi_bresp), + .m_axi_bready(m_axi_bready) +); + +util_axis_fifo #( + .DATA_WIDTH(BEATS_PER_BURST_WIDTH_SRC), + .ADDRESS_WIDTH(0), + .ASYNC_CLK(ASYNC_CLK_SRC_DEST) +) i_src_dest_bl_fifo ( + .s_axis_aclk(src_clk), + .s_axis_aresetn(src_resetn), + .s_axis_valid(src_bl_valid), + .s_axis_ready(src_bl_ready), + .s_axis_empty(), + .s_axis_data(src_burst_length), + .s_axis_room(), + + .m_axis_aclk(dest_clk), + .m_axis_aresetn(dest_resetn), + .m_axis_valid(dest_bl_valid), + .m_axis_ready(dest_bl_ready), + .m_axis_data(dest_src_burst_length), + .m_axis_level() +); + +// Adapt burst length from source width to destination width by either +// truncation or completion with ones. +if (BEATS_PER_BURST_WIDTH_SRC == BEATS_PER_BURST_WIDTH_DEST) begin +assign dest_burst_length = dest_src_burst_length; +end + +if (BEATS_PER_BURST_WIDTH_SRC < BEATS_PER_BURST_WIDTH_DEST) begin +assign dest_burst_length = {dest_src_burst_length, + {BEATS_PER_BURST_WIDTH_DEST - BEATS_PER_BURST_WIDTH_SRC{1'b1}}}; +end + +if (BEATS_PER_BURST_WIDTH_SRC > BEATS_PER_BURST_WIDTH_DEST) begin +assign dest_burst_length = dest_src_burst_length[BEATS_PER_BURST_WIDTH_SRC-1 -: BEATS_PER_BURST_WIDTH_DEST]; +end + +end else begin + +assign m_axi_awvalid = 1'b0; +assign m_axi_awaddr = 'h00; +assign m_axi_awlen = 'h00; +assign m_axi_awsize = 'h00; +assign m_axi_awburst = 'h00; +assign m_axi_awprot = 'h00; +assign m_axi_awcache = 'h00; + +assign m_axi_wvalid = 1'b0; +assign m_axi_wdata = 'h00; +assign m_axi_wstrb = 'h00; +assign m_axi_wlast = 1'b0; + +assign m_axi_bready = 1'b0; + +assign src_bl_ready = 1'b1; + +assign dest_response_partial = 1'b0; +assign dest_response_data_burst_length = 'h0; + +end + +if (DMA_TYPE_DEST == DMA_TYPE_STREAM_AXI) begin + +assign dest_clk = m_axis_aclk; +assign dest_ext_resetn = 1'b1; + +wire [ID_WIDTH-1:0] data_id; + +wire data_eot = eot_mem_dest[data_id]; +wire response_eot = eot_mem_dest[dest_response_id]; + +assign dest_data_request_id = dest_request_id; + +assign dbg_dest_address_id = 'h00; +assign dbg_dest_data_id = data_id; + + +dmac_dest_axi_stream #( + .ID_WIDTH(ID_WIDTH), + .S_AXIS_DATA_WIDTH(DMA_DATA_WIDTH_DEST), + .BEATS_PER_BURST_WIDTH(BEATS_PER_BURST_WIDTH_DEST) +) i_dest_dma_stream ( + .s_axis_aclk(m_axis_aclk), + .s_axis_aresetn(dest_resetn), + + .enable(dest_enable), + .enabled(dest_enabled), + + .req_valid(dest_req_valid), + .req_ready(dest_req_ready), + .req_xlast(dest_req_xlast), + + .response_valid(dest_response_valid), + .response_ready(dest_response_ready), + .response_resp(dest_response_resp), + .response_resp_eot(dest_response_resp_eot), + + .response_id(dest_response_id), + .data_id(data_id), + .xfer_req(m_axis_xfer_req), + + .data_eot(data_eot), + .response_eot(response_eot), + + .fifo_valid(dest_valid), + .fifo_ready(dest_ready), + .fifo_data(dest_data), + .fifo_last(dest_last), + + .m_axis_valid(m_axis_valid), + .m_axis_ready(m_axis_ready), + .m_axis_data(m_axis_data), + .m_axis_last(m_axis_last) +); + +end else begin + +assign m_axis_valid = 1'b0; +assign m_axis_last = 1'b0; +assign m_axis_xfer_req = 1'b0; +assign m_axis_data = 'h00; + +end + +if (DMA_TYPE_DEST == DMA_TYPE_FIFO) begin + +assign dest_clk = fifo_rd_clk; +assign dest_ext_resetn = 1'b1; + +wire [ID_WIDTH-1:0] data_id; + +wire data_eot = eot_mem_dest[data_id]; +wire response_eot = eot_mem_dest[dest_response_id]; + +assign dest_data_request_id = dest_request_id; + +assign dbg_dest_address_id = 'h00; +assign dbg_dest_data_id = data_id; + +dmac_dest_fifo_inf #( + .ID_WIDTH(ID_WIDTH), + .DATA_WIDTH(DMA_DATA_WIDTH_DEST), + .BEATS_PER_BURST_WIDTH(BEATS_PER_BURST_WIDTH_DEST) +) i_dest_dma_fifo ( + .clk(fifo_rd_clk), + .resetn(dest_resetn), + + .enable(dest_enable), + .enabled(dest_enabled), + + .req_valid(dest_req_valid), + .req_ready(dest_req_ready), + + .response_valid(dest_response_valid), + .response_ready(dest_response_ready), + .response_resp(dest_response_resp), + .response_resp_eot(dest_response_resp_eot), + + .response_id(dest_response_id), + .data_id(data_id), + + .data_eot(data_eot), + .response_eot(response_eot), + + .fifo_valid(dest_valid), + .fifo_ready(dest_ready), + .fifo_data(dest_data), + .fifo_last(dest_last), + + .en(fifo_rd_en), + .valid(fifo_rd_valid), + .dout(fifo_rd_dout), + .underflow(fifo_rd_underflow), + .xfer_req(fifo_rd_xfer_req) +); + +end else begin + +assign fifo_rd_valid = 1'b0; +assign fifo_rd_dout = 'h0; +assign fifo_rd_underflow = 1'b0; +assign fifo_rd_xfer_req = 1'b0; + +end endgenerate + +generate if (DMA_TYPE_SRC == DMA_TYPE_MM_AXI) begin + +wire [ID_WIDTH-1:0] src_data_id; +wire [ID_WIDTH-1:0] src_address_id; +wire src_address_eot = eot_mem_src[src_address_id]; + +assign source_id = src_address_id; +assign source_eot = src_address_eot; + +assign src_clk = m_src_axi_aclk; +assign src_ext_resetn = m_src_axi_aresetn; + +assign dbg_src_address_id = src_address_id; +assign dbg_src_data_id = src_data_id; + +dmac_src_mm_axi #( + .ID_WIDTH(ID_WIDTH), + .DMA_DATA_WIDTH(DMA_DATA_WIDTH_SRC), + .DMA_ADDR_WIDTH(DMA_AXI_ADDR_WIDTH), + .BEATS_PER_BURST_WIDTH(BEATS_PER_BURST_WIDTH_SRC), + .BYTES_PER_BEAT_WIDTH(BYTES_PER_BEAT_WIDTH_SRC), + .AXI_LENGTH_WIDTH(AXI_LENGTH_WIDTH_SRC) +) i_src_dma_mm ( + .m_axi_aclk(m_src_axi_aclk), + .m_axi_aresetn(src_resetn), + + .enable(src_enable), + .enabled(src_enabled), + + .req_valid(src_req_valid), + .req_ready(src_req_ready), + .req_address(src_req_src_address), + .req_last_burst_length(src_req_last_burst_length), + + .bl_valid(src_bl_valid), + .bl_ready(src_bl_ready), + .measured_last_burst_length(src_burst_length), + +/* TODO + .response_valid(src_response_valid), + .response_ready(src_response_ready), + .response_resp(src_response_resp), +*/ + + .request_id(src_throttled_request_id), + .response_id(src_response_id), + .address_id(src_address_id), + .data_id(src_data_id), + + .address_eot(src_address_eot), + + .fifo_valid(src_valid), + .fifo_data(src_data), + .fifo_last(src_last), + + .m_axi_arready(m_axi_arready), + .m_axi_arvalid(m_axi_arvalid), + .m_axi_araddr(m_axi_araddr), + .m_axi_arlen(m_axi_arlen), + .m_axi_arsize(m_axi_arsize), + .m_axi_arburst(m_axi_arburst), + .m_axi_arprot(m_axi_arprot), + .m_axi_arcache(m_axi_arcache), + + .m_axi_rready(m_axi_rready), + .m_axi_rvalid(m_axi_rvalid), + .m_axi_rdata(m_axi_rdata), + .m_axi_rlast(m_axi_rlast), + .m_axi_rresp(m_axi_rresp) +); + +end else begin + +assign m_axi_arvalid = 1'b0; +assign m_axi_araddr = 'h00; +assign m_axi_arlen = 'h00; +assign m_axi_arsize = 'h00; +assign m_axi_arburst = 'h00; +assign m_axi_arcache = 'h00; +assign m_axi_arprot = 'h00; +assign m_axi_rready = 1'b0; + +end + +if (DMA_TYPE_SRC == DMA_TYPE_STREAM_AXI) begin + +assign src_clk = s_axis_aclk; +assign src_ext_resetn = 1'b1; + +wire src_eot = eot_mem_src[src_response_id]; + +assign dbg_src_address_id = 'h00; +assign dbg_src_data_id = 'h00; + +/* TODO +assign src_response_valid = 1'b0; +assign src_response_resp = 2'b0; +*/ + + +dmac_src_axi_stream #( + .ID_WIDTH(ID_WIDTH), + .S_AXIS_DATA_WIDTH(DMA_DATA_WIDTH_SRC), + .BEATS_PER_BURST_WIDTH(BEATS_PER_BURST_WIDTH_SRC) +) i_src_dma_stream ( + .s_axis_aclk(s_axis_aclk), + .s_axis_aresetn(src_resetn), + + .enable(src_enable), + .enabled(src_enabled), + + .req_valid(src_req_valid), + .req_ready(src_req_ready), + .req_last_burst_length(src_req_last_burst_length), + .req_sync_transfer_start(src_req_sync_transfer_start), + .req_xlast(src_req_xlast), + + .request_id(src_throttled_request_id), + .response_id(src_response_id), + + .eot(src_eot), + + .rewind_req_valid(rewind_req_valid), + .rewind_req_ready(rewind_req_ready), + .rewind_req_data(rewind_req_data), + + .bl_valid(src_bl_valid), + .bl_ready(src_bl_ready), + .measured_last_burst_length(src_burst_length), + + .block_descr_to_dst(block_descr_to_dst), + + .source_id(source_id), + .source_eot(source_eot), + + .fifo_valid(src_valid), + .fifo_data(src_data), + .fifo_last(src_last), + .fifo_partial_burst(src_partial_burst), + + .s_axis_valid(s_axis_valid), + .s_axis_ready(s_axis_ready), + .s_axis_data(s_axis_data), + .s_axis_last(s_axis_last), + .s_axis_user(s_axis_user), + .s_axis_xfer_req(s_axis_xfer_req) +); + +util_axis_fifo #( + .DATA_WIDTH(ID_WIDTH + 3), + .ADDRESS_WIDTH(0), + .ASYNC_CLK(ASYNC_CLK_REQ_SRC) +) i_rewind_req_fifo ( + .s_axis_aclk(src_clk), + .s_axis_aresetn(src_resetn), + .s_axis_valid(rewind_req_valid), + .s_axis_ready(rewind_req_ready), + .s_axis_empty(), + .s_axis_data(rewind_req_data), + .s_axis_room(), + + .m_axis_aclk(req_clk), + .m_axis_aresetn(req_resetn), + .m_axis_valid(req_rewind_req_valid), + .m_axis_ready(1'b1), + .m_axis_data(req_rewind_req_data), + .m_axis_level() +); + +end else begin + +assign s_axis_ready = 1'b0; +assign s_axis_xfer_req = 1'b0; +assign rewind_req_valid = 1'b0; +assign rewind_req_data = 'h0; + +assign req_rewind_req_valid = 'b0; +assign req_rewind_req_data = 'h0; + +assign src_partial_burst = 1'b0; +assign block_descr_to_dst = 1'b0; + +end + +if (DMA_TYPE_SRC == DMA_TYPE_FIFO) begin + +wire src_eot = eot_mem_src[src_response_id]; + +assign source_id = src_response_id; +assign source_eot = src_eot; + +assign src_clk = fifo_wr_clk; +assign src_ext_resetn = 1'b1; + +assign dbg_src_address_id = 'h00; +assign dbg_src_data_id = 'h00; + +/* TODO +assign src_response_valid = 1'b0; +assign src_response_resp = 2'b0; +*/ + +dmac_src_fifo_inf #( + .ID_WIDTH(ID_WIDTH), + .DATA_WIDTH(DMA_DATA_WIDTH_SRC), + .BEATS_PER_BURST_WIDTH(BEATS_PER_BURST_WIDTH_SRC) +) i_src_dma_fifo ( + .clk(fifo_wr_clk), + .resetn(src_resetn), + + .enable(src_enable), + .enabled(src_enabled), + + .req_valid(src_req_valid), + .req_ready(src_req_ready), + .req_last_burst_length(src_req_last_burst_length), + .req_sync_transfer_start(src_req_sync_transfer_start), + + .request_id(src_throttled_request_id), + .response_id(src_response_id), + + .eot(src_eot), + + .bl_valid(src_bl_valid), + .bl_ready(src_bl_ready), + .measured_last_burst_length(src_burst_length), + + .fifo_valid(src_valid), + .fifo_data(src_data), + .fifo_last(src_last), + + .en(fifo_wr_en), + .din(fifo_wr_din), + .overflow(fifo_wr_overflow), + .sync(fifo_wr_sync), + .xfer_req(fifo_wr_xfer_req) +); + +end else begin + +assign fifo_wr_overflow = 1'b0; +assign fifo_wr_xfer_req = 1'b0; + +end endgenerate + +sync_bits #( + .NUM_OF_BITS(ID_WIDTH), + .ASYNC_CLK(ASYNC_CLK_REQ_SRC) +) i_sync_src_request_id ( + .out_clk(src_clk), + .out_resetn(1'b1), + .in(request_id), + .out(src_request_id) +); + +`include "inc_id.vh" + +function compare_id; + input [ID_WIDTH-1:0] a; + input [ID_WIDTH-1:0] b; + begin + compare_id = a[ID_WIDTH-1] == b[ID_WIDTH-1]; + if (ID_WIDTH >= 2) begin + if (a[ID_WIDTH-2] == b[ID_WIDTH-2]) begin + compare_id = 1'b1; + end + end + if (ID_WIDTH >= 3) begin + if (a[ID_WIDTH-3:0] != b[ID_WIDTH-3:0]) begin + compare_id = 1'b1; + end + end + end +endfunction + +sync_event #(.ASYNC_CLK(ASYNC_CLK_REQ_SRC)) sync_rewind ( + .in_clk(req_clk), + .in_event(rewind_state), + .out_clk(src_clk), + .out_event(src_throttler_enable) +); + +always @(posedge src_clk) begin + if (src_resetn == 1'b0) begin + src_throttler_enabled <= 'b1; + end else if (rewind_req_valid) begin + src_throttler_enabled <= 'b0; + end else if (src_throttler_enable) begin + src_throttler_enabled <= 'b1; + end +end + +/* + * Make sure that we do not request more data than what fits into the + * store-and-forward burst memory. + * Throttler must be blocked during rewind since it does not tolerate + * a decrement of the request ID. + */ +always @(posedge src_clk) begin + if (src_resetn == 1'b0) begin + src_throttled_request_id <= 'h00; + end else if (rewind_req_valid) begin + src_throttled_request_id <= rewind_req_data[ID_WIDTH-1:0]; + end else if (src_throttled_request_id != src_request_id && + compare_id(src_throttled_request_id, src_data_request_id) && + src_throttler_enabled) begin + src_throttled_request_id <= inc_id(src_throttled_request_id); + end +end + +sync_bits #( + .NUM_OF_BITS(ID_WIDTH), + .ASYNC_CLK(ASYNC_CLK_DEST_REQ) +) i_sync_req_response_id ( + .out_clk(req_clk), + .out_resetn(1'b1), + .in(dest_response_id), + .out(response_id) +); + +axi_register_slice #( + .DATA_WIDTH(DMA_DATA_WIDTH_SRC + 2), + .FORWARD_REGISTERED(AXI_SLICE_SRC), + .BACKWARD_REGISTERED(0) +) i_src_slice ( + .clk(src_clk), + .resetn(src_resetn), + .s_axi_valid(src_valid), + .s_axi_ready(), + .s_axi_data({src_data,src_last,src_partial_burst}), + .m_axi_valid(src_fifo_valid), + .m_axi_ready(1'b1), /* No backpressure */ + .m_axi_data({src_fifo_data,src_fifo_last,src_fifo_partial_burst}) +); + +axi_dmac_burst_memory #( + .DATA_WIDTH_SRC(DMA_DATA_WIDTH_SRC), + .DATA_WIDTH_DEST(DMA_DATA_WIDTH_DEST), + .ID_WIDTH(ID_WIDTH), + .MAX_BYTES_PER_BURST(MAX_BYTES_PER_BURST), + .ASYNC_CLK(ASYNC_CLK_SRC_DEST), + .BYTES_PER_BEAT_WIDTH_SRC(BYTES_PER_BEAT_WIDTH_SRC), + .BYTES_PER_BURST_WIDTH(BYTES_PER_BURST_WIDTH), + .ENABLE_DIAGNOSTICS_IF(ENABLE_DIAGNOSTICS_IF) +) i_store_and_forward ( + .src_clk(src_clk), + .src_reset(~src_resetn), + .src_data_valid(src_fifo_valid), + .src_data(src_fifo_data), + .src_data_last(src_fifo_last), + .src_data_valid_bytes({BYTES_PER_BEAT_WIDTH_SRC{1'b1}}), + .src_data_partial_burst(src_fifo_partial_burst), + + .src_data_request_id(src_data_request_id), + + .dest_clk(dest_clk), + .dest_reset(~dest_resetn), + .dest_data_valid(dest_fifo_valid), + .dest_data_ready(dest_fifo_ready), + .dest_data(dest_fifo_data), + .dest_data_last(dest_fifo_last), + + .dest_burst_info_length(dest_burst_info_length), + .dest_burst_info_partial(dest_burst_info_partial), + .dest_burst_info_id(dest_burst_info_id), + .dest_burst_info_write(dest_burst_info_write), + + .dest_request_id(dest_request_id), + .dest_data_request_id(dest_data_request_id), + .dest_data_response_id(dest_data_response_id), + + .dest_diag_level_bursts(dest_diag_level_bursts) +); + +axi_register_slice #( + .DATA_WIDTH(DMA_DATA_WIDTH_DEST + 1), + .FORWARD_REGISTERED(AXI_SLICE_DEST), + .BACKWARD_REGISTERED(AXI_SLICE_DEST) +) i_dest_slice ( + .clk(dest_clk), + .resetn(dest_resetn), + .s_axi_valid(dest_fifo_valid), + .s_axi_ready(dest_fifo_ready), + .s_axi_data({ + dest_fifo_last, + dest_fifo_data + }), + .m_axi_valid(dest_valid), + .m_axi_ready(dest_ready), + .m_axi_data({ + dest_last, + dest_data + }) +); + +// Don't let the request generator run in advance more than one descriptor +// The descriptor FIFO should not block the start of the request generator +// since it becomes ready earlier. +assign req_gen_valid = req_valid & req_ready; +assign req_src_valid = req_valid & req_ready; +assign req_ready = req_gen_ready & req_src_ready; + +util_axis_fifo #( + .DATA_WIDTH(DMA_ADDRESS_WIDTH_DEST + 1), + .ADDRESS_WIDTH(0), + .ASYNC_CLK(ASYNC_CLK_SRC_DEST) +) i_dest_req_fifo ( + .s_axis_aclk(src_clk), + .s_axis_aresetn(src_resetn), + .s_axis_valid(src_dest_valid_hs_masked), + .s_axis_ready(src_dest_ready_hs), + .s_axis_empty(), + .s_axis_data({ + src_req_dest_address_cur, + src_req_xlast_cur + }), + .s_axis_room(), + + .m_axis_aclk(dest_clk), + .m_axis_aresetn(dest_resetn), + .m_axis_valid(dest_req_valid), + .m_axis_ready(dest_req_ready), + .m_axis_data({ + dest_req_dest_address, + dest_req_xlast + }), + .m_axis_level() +); + +util_axis_fifo #( + .DATA_WIDTH(DMA_ADDRESS_WIDTH_DEST + DMA_ADDRESS_WIDTH_SRC + BEATS_PER_BURST_WIDTH_SRC + 2), + .ADDRESS_WIDTH(0), + .ASYNC_CLK(ASYNC_CLK_REQ_SRC) +) i_src_req_fifo ( + .s_axis_aclk(req_clk), + .s_axis_aresetn(req_resetn), + .s_axis_valid(req_src_valid), + .s_axis_ready(req_src_ready), + .s_axis_empty(), + .s_axis_data({ + req_dest_address, + req_src_address, + req_length[BYTES_PER_BURST_WIDTH-1:BYTES_PER_BEAT_WIDTH_SRC], + req_sync_transfer_start, + req_xlast + }), + .s_axis_room(), + + .m_axis_aclk(src_clk), + .m_axis_aresetn(src_resetn), + .m_axis_valid(src_req_spltr_valid), + .m_axis_ready(src_req_spltr_ready), + .m_axis_data({ + src_req_dest_address, + src_req_src_address, + src_req_last_burst_length, + src_req_sync_transfer_start, + src_req_xlast + }), + .m_axis_level() +); + +// Save the descriptor in the source clock domain since the submission to +// destination is delayed. +always @(posedge src_clk) begin + if (src_req_valid == 1'b1 && src_req_ready == 1'b1) begin + src_req_dest_address_cur <= src_req_dest_address; + src_req_xlast_cur <= src_req_xlast; + end +end + +always @(posedge src_clk) begin + if (src_resetn == 1'b0) begin + src_dest_valid_hs <= 1'b0; + end else if (src_req_valid == 1'b1 && src_req_ready == 1'b1) begin + src_dest_valid_hs <= 1'b1; + end else if (src_dest_ready_hs == 1'b1) begin + src_dest_valid_hs <= 1'b0; + end +end + +// Forward the descriptor to the destination only after the source decided to +// do so +assign src_dest_valid_hs_masked = src_dest_valid_hs == 1'b1 && block_descr_to_dst == 1'b0; +assign src_req_spltr_ready = src_req_ready && src_dest_ready_hs; +assign src_req_valid = src_req_spltr_valid && src_req_spltr_ready; + + +/* Unused for now +util_axis_fifo #( + .DATA_WIDTH(2), + .ADDRESS_WIDTH(0), + .ASYNC_CLK(ASYNC_CLK_REQ_SRC) +) i_src_response_fifo ( + .s_axis_aclk(src_clk), + .s_axis_aresetn(src_resetn), + .s_axis_valid(src_response_valid), + .s_axis_ready(src_response_ready), + .s_axis_empty(src_response_empty), + .s_axis_data(src_response_resp), + .m_axis_aclk(req_clk), + .m_axis_aresetn(req_resetn), + .m_axis_valid(response_src_valid), + .m_axis_ready(response_src_ready), + .m_axis_data(response_src_resp) +); +assign src_response_empty = 1'b1; +assign src_response_ready = 1'b1; +*/ + +dmac_request_generator #( + .ID_WIDTH(ID_WIDTH), + .BURSTS_PER_TRANSFER_WIDTH(BURSTS_PER_TRANSFER_WIDTH) +) i_req_gen ( + .clk(req_clk), + .resetn(req_resetn), + + .request_id(request_id), + .response_id(response_id), + + .rewind_req_valid(req_rewind_req_valid), + .rewind_req_data(req_rewind_req_data), + .rewind_state(rewind_state), + + .abort_req(abort_req), + + .completion_req_valid(completion_req_valid), + .completion_req_last(completion_req_last), + .completion_transfer_id(completion_transfer_id), + + .req_valid(req_gen_valid), + .req_ready(req_gen_ready), + .req_burst_count(req_length[DMA_LENGTH_WIDTH-1:BYTES_PER_BURST_WIDTH]), + .req_xlast(req_xlast), + + .enable(req_enable), + + .eot(request_eot) +); + +axi_dmac_response_manager #( + .DMA_DATA_WIDTH_SRC(DMA_DATA_WIDTH_SRC), + .DMA_DATA_WIDTH_DEST(DMA_DATA_WIDTH_DEST), + .DMA_LENGTH_WIDTH(DMA_LENGTH_WIDTH), + .BYTES_PER_BURST_WIDTH(BYTES_PER_BURST_WIDTH), + .BYTES_PER_BEAT_WIDTH_SRC(BYTES_PER_BEAT_WIDTH_SRC), + .ASYNC_CLK_DEST_REQ(ASYNC_CLK_DEST_REQ) +) i_response_manager( + .dest_clk(dest_clk), + .dest_resetn(dest_resetn), + .dest_response_valid(dest_response_valid), + .dest_response_ready(dest_response_ready), + .dest_response_resp(dest_response_resp), + .dest_response_partial(dest_response_partial), + .dest_response_resp_eot(dest_response_resp_eot), + .dest_response_data_burst_length(dest_response_data_burst_length), + + .req_clk(req_clk), + .req_resetn(req_resetn), + .response_eot(eot), + .measured_burst_length(measured_burst_length), + .response_partial(response_partial), + .response_valid(response_valid), + .response_ready(response_ready), + + .completion_req_valid(completion_req_valid), + .completion_req_last(completion_req_last), + .completion_transfer_id(completion_transfer_id) + +); + + +endmodule diff --git a/src/adi/hdl/library/axi_dmac/request_generator.v b/src/adi/hdl/library/axi_dmac/request_generator.v new file mode 100644 index 00000000..75bd7774 --- /dev/null +++ b/src/adi/hdl/library/axi_dmac/request_generator.v @@ -0,0 +1,255 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright 2014 - 2017 (c) Analog Devices, Inc. All rights reserved. +// +// In this HDL repository, there are many different and unique modules, consisting +// of various HDL (Verilog or VHDL) components. The individual modules are +// developed independently, and may be accompanied by separate and unique license +// terms. +// +// The user should read each of these license terms, and understand the +// freedoms and responsibilities that he or she has by using this source/core. +// +// This core 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. +// +// Redistribution and use of source or resulting binaries, with or without modification +// of this file, are permitted under one of the following two license terms: +// +// 1. The GNU General Public License version 2 as published by the +// Free Software Foundation, which can be found in the top level directory +// of this repository (LICENSE_GPL2), and also online at: +// +// +// OR +// +// 2. An ADI specific BSD license, which can be found in the top level directory +// of this repository (LICENSE_ADIBSD), and also on-line at: +// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD +// This will allow to generate bit files and not release the source code, +// as long as it attaches to an ADI device. +// +// *************************************************************************** +// *************************************************************************** + +`timescale 1ns/100ps + +module dmac_request_generator #( + + parameter ID_WIDTH = 3, + parameter BURSTS_PER_TRANSFER_WIDTH = 17)( + + input clk, + input resetn, + + output [ID_WIDTH-1:0] request_id, + input [ID_WIDTH-1:0] response_id, + + input rewind_req_valid, + input [ID_WIDTH+3-1:0] rewind_req_data, + output rewind_state, + + output abort_req, + + output reg completion_req_valid = 1'b0, + output completion_req_last, + output [1:0] completion_transfer_id, + + input req_valid, + output reg req_ready, + input [BURSTS_PER_TRANSFER_WIDTH-1:0] req_burst_count, + input req_xlast, + + input enable, + + output eot +); + +`include "inc_id.vh" + +localparam STATE_IDLE = 3'h0; +localparam STATE_GEN_ID = 3'h1; +localparam STATE_REWIND_ID = 3'h2; +localparam STATE_CONSUME = 3'h3; +localparam STATE_WAIT_LAST = 3'h4; + +reg [2:0] state = STATE_IDLE; +reg [2:0] nx_state; + +reg [1:0] rew_transfer_id = 1'b0; +reg rew_req_xlast; +reg [ID_WIDTH-1:0] rew_id = 'h0; + +reg cur_transfer_id = 1'b0; +reg cur_req_xlast; + +wire transfer_id_match; +reg nx_completion_req_valid; + +/* + * Here we only need to count the number of bursts, which means we can ignore + * the lower bits of the byte count. The last last burst may not contain the + * maximum number of bytes, but the address_generator and data_mover will take + * care that only the requested ammount of bytes is transfered. + */ + +reg [BURSTS_PER_TRANSFER_WIDTH-1:0] burst_count = 'h00; +reg [BURSTS_PER_TRANSFER_WIDTH-1:0] cur_burst_length = 'h00; +reg [ID_WIDTH-1:0] id; +wire [ID_WIDTH-1:0] id_next = inc_id(id); +wire incr_en; +wire incr_id; + +assign eot = burst_count == 'h00; +assign request_id = id; + +assign incr_en = (response_id != id_next) && (enable == 1'b1); +assign incr_id = (state == STATE_GEN_ID) && (incr_en == 1'b1); + +always @(posedge clk) begin + if (state == STATE_IDLE) begin + burst_count <= req_burst_count; + end else if (state == STATE_REWIND_ID) begin + burst_count <= cur_burst_length; + end else if (incr_id == 1'b1) begin + burst_count <= burst_count - 1'b1; + end +end +always @(posedge clk) begin + if (req_ready == 1'b1 & req_valid == 1'b1) begin + cur_req_xlast <= req_xlast; + cur_burst_length <= req_burst_count; + end +end + +always @(posedge clk) begin + if (resetn == 1'b0) begin + id <= 'h0; + end else if (state == STATE_REWIND_ID) begin + id <= rew_id; + end else if (incr_id == 1'b1) begin + id <= id_next; + end +end + +always @(posedge clk) begin + if (resetn == 1'b0) begin + req_ready <= 1'b0; + end else begin + req_ready <= (nx_state == STATE_IDLE || nx_state == STATE_CONSUME); + end +end + +assign transfer_id_match = cur_transfer_id == rew_transfer_id[0]; + +always @(posedge clk) begin + if (resetn == 1'b0) begin + cur_transfer_id <= 1'b0; + end else if (req_valid == 1'b1 && req_ready == 1'b1) begin + cur_transfer_id <= ~cur_transfer_id; + end +end + +/* + * Once rewind request is received we need to stop incrementing the burst ID. + * + * If the current segment matches the segment that was interrupted and + * if it was a last segment we ignore consecutive segments until the last + * segment is received, in other case we can jump to the next segment. + * + * If the current segment is newer than the one got interrupted and the + * interrupted one was a last segment we need to replay the current + * segment with the adjusted burst ID. If the interrupted segment was not last + * we need to consume/ignore all segments until a last segment is received. + * + * Completion requests are generated for every segment that is + * consumed/ignored. These are handled by the response_manager once the + * interrupted segment got transferred to the destination. + */ +always @(*) begin + nx_state = state; + nx_completion_req_valid = 0; + case (state) + STATE_IDLE: begin + if (rewind_req_valid == 1'b1) begin + nx_state = STATE_REWIND_ID; + end else if (req_valid == 1'b1) begin + nx_state = STATE_GEN_ID; + end + end + STATE_GEN_ID: begin + if (rewind_req_valid == 1'b1) begin + nx_state = STATE_REWIND_ID; + end else if (eot == 1'b1 && incr_en == 1'b1) begin + nx_state = STATE_IDLE; + end + end + STATE_REWIND_ID: begin + if (transfer_id_match) begin + if (rew_req_xlast) begin + nx_state = STATE_IDLE; + end else begin + nx_state = STATE_CONSUME; + end + end else begin + if (rew_req_xlast) begin + nx_state = STATE_GEN_ID; + end else if (cur_req_xlast) begin + nx_state = STATE_IDLE; + nx_completion_req_valid = 1; + end else begin + nx_state = STATE_CONSUME; + nx_completion_req_valid = 1; + end + end + end + STATE_CONSUME: begin + if (req_valid) begin + nx_completion_req_valid = 1; + nx_state = STATE_WAIT_LAST; + end + end + STATE_WAIT_LAST:begin + if (cur_req_xlast) begin + nx_state = STATE_IDLE; + end else begin + nx_state = STATE_CONSUME; + end + end + + default: begin + nx_state = STATE_IDLE; + end + endcase +end + +always @(posedge clk) begin + if (resetn == 1'b0) begin + state <= STATE_IDLE; + end else begin + state <= nx_state; + end +end + +always @(posedge clk) begin + if (rewind_req_valid == 1'b1) begin + {rew_transfer_id, rew_req_xlast, rew_id} <= rewind_req_data; + end +end + +always @(posedge clk) begin + if (resetn == 1'b0) begin + completion_req_valid <= 1'b0; + end else begin + completion_req_valid <= nx_completion_req_valid; + end +end +assign completion_req_last = cur_req_xlast; +assign completion_transfer_id = rew_transfer_id; + +assign rewind_state = (state == STATE_REWIND_ID); + +assign abort_req = (state == STATE_REWIND_ID) && !rew_req_xlast && !cur_req_xlast; + +endmodule diff --git a/src/adi/hdl/library/axi_dmac/resp.vh b/src/adi/hdl/library/axi_dmac/resp.vh new file mode 100644 index 00000000..a3a73835 --- /dev/null +++ b/src/adi/hdl/library/axi_dmac/resp.vh @@ -0,0 +1,4 @@ +localparam RESP_OKAY = 2'b00; +localparam RESP_EXOKAY = 2'b01; +localparam RESP_SLVERR = 2'b10; +localparam RESP_DECERR = 2'b11; diff --git a/src/adi/hdl/library/axi_dmac/response_generator.v b/src/adi/hdl/library/axi_dmac/response_generator.v new file mode 100644 index 00000000..4e7e87b7 --- /dev/null +++ b/src/adi/hdl/library/axi_dmac/response_generator.v @@ -0,0 +1,86 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright 2014 - 2017 (c) Analog Devices, Inc. All rights reserved. +// +// In this HDL repository, there are many different and unique modules, consisting +// of various HDL (Verilog or VHDL) components. The individual modules are +// developed independently, and may be accompanied by separate and unique license +// terms. +// +// The user should read each of these license terms, and understand the +// freedoms and responsibilities that he or she has by using this source/core. +// +// This core 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. +// +// Redistribution and use of source or resulting binaries, with or without modification +// of this file, are permitted under one of the following two license terms: +// +// 1. The GNU General Public License version 2 as published by the +// Free Software Foundation, which can be found in the top level directory +// of this repository (LICENSE_GPL2), and also online at: +// +// +// OR +// +// 2. An ADI specific BSD license, which can be found in the top level directory +// of this repository (LICENSE_ADIBSD), and also on-line at: +// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD +// This will allow to generate bit files and not release the source code, +// as long as it attaches to an ADI device. +// +// *************************************************************************** +// *************************************************************************** + +`timescale 1ns/100ps + +module dmac_response_generator #( + + parameter ID_WIDTH = 3)( + + input clk, + input resetn, + + input enable, + output reg enabled, + + input [ID_WIDTH-1:0] request_id, + output reg [ID_WIDTH-1:0] response_id, + + input eot, + + output resp_valid, + input resp_ready, + output resp_eot, + output [1:0] resp_resp +); + +`include "inc_id.vh" +`include "resp.vh" + +assign resp_resp = RESP_OKAY; +assign resp_eot = eot; + +assign resp_valid = request_id != response_id && enabled; + +// We have to wait for all responses before we can disable the response handler +always @(posedge clk) begin + if (resetn == 1'b0) begin + enabled <= 1'b0; + end else if (enable == 1'b1) begin + enabled <= 1'b1; + end else if (request_id == response_id) begin + enabled <= 1'b0; + end +end + +always @(posedge clk) begin + if (resetn == 1'b0) begin + response_id <= 'h0; + end else if (resp_valid == 1'b1 && resp_ready == 1'b1) begin + response_id <= inc_id(response_id); + end +end + +endmodule diff --git a/src/adi/hdl/library/axi_dmac/response_handler.v b/src/adi/hdl/library/axi_dmac/response_handler.v new file mode 100644 index 00000000..9dec16b7 --- /dev/null +++ b/src/adi/hdl/library/axi_dmac/response_handler.v @@ -0,0 +1,93 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright 2014 - 2017 (c) Analog Devices, Inc. All rights reserved. +// +// In this HDL repository, there are many different and unique modules, consisting +// of various HDL (Verilog or VHDL) components. The individual modules are +// developed independently, and may be accompanied by separate and unique license +// terms. +// +// The user should read each of these license terms, and understand the +// freedoms and responsibilities that he or she has by using this source/core. +// +// This core 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. +// +// Redistribution and use of source or resulting binaries, with or without modification +// of this file, are permitted under one of the following two license terms: +// +// 1. The GNU General Public License version 2 as published by the +// Free Software Foundation, which can be found in the top level directory +// of this repository (LICENSE_GPL2), and also online at: +// +// +// OR +// +// 2. An ADI specific BSD license, which can be found in the top level directory +// of this repository (LICENSE_ADIBSD), and also on-line at: +// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD +// This will allow to generate bit files and not release the source code, +// as long as it attaches to an ADI device. +// +// *************************************************************************** +// *************************************************************************** + +`timescale 1ns/100ps + +module dmac_response_handler #( + + parameter ID_WIDTH = 3)( + + input clk, + input resetn, + + input bvalid, + output bready, + input [1:0] bresp, + + output reg [ID_WIDTH-1:0] id, + input [ID_WIDTH-1:0] request_id, + + input enable, + output reg enabled, + + input eot, + + output resp_valid, + input resp_ready, + output resp_eot, + output [1:0] resp_resp +); + +`include "resp.vh" +`include "inc_id.vh" + +assign resp_resp = bresp; +assign resp_eot = eot; + +wire active = id != request_id; + +assign bready = active && resp_ready; +assign resp_valid = active && bvalid; + +// We have to wait for all responses before we can disable the response handler +always @(posedge clk) begin + if (resetn == 1'b0) begin + enabled <= 1'b0; + end else if (enable == 1'b1) begin + enabled <= 1'b1; + end else if (request_id == id) begin + enabled <= 1'b0; + end +end + +always @(posedge clk) begin + if (resetn == 1'b0) begin + id <= 'h0; + end else if (bready == 1'b1 && bvalid == 1'b1) begin + id <= inc_id(id); + end +end + +endmodule diff --git a/src/adi/hdl/library/axi_dmac/splitter.v b/src/adi/hdl/library/axi_dmac/splitter.v new file mode 100644 index 00000000..04f1287d --- /dev/null +++ b/src/adi/hdl/library/axi_dmac/splitter.v @@ -0,0 +1,69 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright 2014 - 2017 (c) Analog Devices, Inc. All rights reserved. +// +// In this HDL repository, there are many different and unique modules, consisting +// of various HDL (Verilog or VHDL) components. The individual modules are +// developed independently, and may be accompanied by separate and unique license +// terms. +// +// The user should read each of these license terms, and understand the +// freedoms and responsibilities that he or she has by using this source/core. +// +// This core 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. +// +// Redistribution and use of source or resulting binaries, with or without modification +// of this file, are permitted under one of the following two license terms: +// +// 1. The GNU General Public License version 2 as published by the +// Free Software Foundation, which can be found in the top level directory +// of this repository (LICENSE_GPL2), and also online at: +// +// +// OR +// +// 2. An ADI specific BSD license, which can be found in the top level directory +// of this repository (LICENSE_ADIBSD), and also on-line at: +// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD +// This will allow to generate bit files and not release the source code, +// as long as it attaches to an ADI device. +// +// *************************************************************************** +// *************************************************************************** + +`timescale 1ns/100ps + +module splitter #( + + parameter NUM_M = 2)( + + input clk, + input resetn, + + input s_valid, + output s_ready, + + output [NUM_M-1:0] m_valid, + input [NUM_M-1:0] m_ready +); + +reg [NUM_M-1:0] acked; + +assign s_ready = &(m_ready | acked); +assign m_valid = s_valid ? ~acked : {NUM_M{1'b0}}; + +always @(posedge clk) +begin + if (resetn == 1'b0) begin + acked <= {NUM_M{1'b0}}; + end else begin + if (s_valid & s_ready) + acked <= {NUM_M{1'b0}}; + else + acked <= acked | (m_ready & m_valid); + end +end + +endmodule diff --git a/src/adi/hdl/library/axi_dmac/src_axi_mm.v b/src/adi/hdl/library/axi_dmac/src_axi_mm.v new file mode 100644 index 00000000..e813a01d --- /dev/null +++ b/src/adi/hdl/library/axi_dmac/src_axi_mm.v @@ -0,0 +1,222 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright 2014 - 2017 (c) Analog Devices, Inc. All rights reserved. +// +// In this HDL repository, there are many different and unique modules, consisting +// of various HDL (Verilog or VHDL) components. The individual modules are +// developed independently, and may be accompanied by separate and unique license +// terms. +// +// The user should read each of these license terms, and understand the +// freedoms and responsibilities that he or she has by using this source/core. +// +// This core 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. +// +// Redistribution and use of source or resulting binaries, with or without modification +// of this file, are permitted under one of the following two license terms: +// +// 1. The GNU General Public License version 2 as published by the +// Free Software Foundation, which can be found in the top level directory +// of this repository (LICENSE_GPL2), and also online at: +// +// +// OR +// +// 2. An ADI specific BSD license, which can be found in the top level directory +// of this repository (LICENSE_ADIBSD), and also on-line at: +// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD +// This will allow to generate bit files and not release the source code, +// as long as it attaches to an ADI device. +// +// *************************************************************************** +// *************************************************************************** + +`timescale 1ns/100ps + +module dmac_src_mm_axi #( + + parameter ID_WIDTH = 3, + parameter DMA_DATA_WIDTH = 64, + parameter DMA_ADDR_WIDTH = 32, + parameter BYTES_PER_BEAT_WIDTH = 3, + parameter BEATS_PER_BURST_WIDTH = 4, + parameter AXI_LENGTH_WIDTH = 8)( + + input m_axi_aclk, + input m_axi_aresetn, + + input req_valid, + output req_ready, + input [DMA_ADDR_WIDTH-1:BYTES_PER_BEAT_WIDTH] req_address, + input [BEATS_PER_BURST_WIDTH-1:0] req_last_burst_length, + + input enable, + output reg enabled = 1'b0, + + output bl_valid, + input bl_ready, + output [BEATS_PER_BURST_WIDTH-1:0] measured_last_burst_length, +/* + output response_valid, + input response_ready, + output [1:0] response_resp, +*/ + + input [ID_WIDTH-1:0] request_id, + output [ID_WIDTH-1:0] response_id, + + output [ID_WIDTH-1:0] data_id, + output [ID_WIDTH-1:0] address_id, + input address_eot, + + output fifo_valid, + output [DMA_DATA_WIDTH-1:0] fifo_data, + output fifo_last, + + // Read address + input m_axi_arready, + output m_axi_arvalid, + output [DMA_ADDR_WIDTH-1:0] m_axi_araddr, + output [AXI_LENGTH_WIDTH-1:0] m_axi_arlen, + output [ 2:0] m_axi_arsize, + output [ 1:0] m_axi_arburst, + output [ 2:0] m_axi_arprot, + output [ 3:0] m_axi_arcache, + + // Read data and response + input [DMA_DATA_WIDTH-1:0] m_axi_rdata, + output m_axi_rready, + input m_axi_rvalid, + input m_axi_rlast, + input [ 1:0] m_axi_rresp +); + +`include "inc_id.vh" + +reg [ID_WIDTH-1:0] id = 'h00; + +wire address_enabled; +wire req_ready_ag; +wire req_valid_ag; +wire bl_ready_ag; +wire bl_valid_ag; + +assign data_id = id; +assign response_id = id; + +assign measured_last_burst_length = req_last_burst_length; + +splitter #( + .NUM_M(3) +) i_req_splitter ( + .clk(m_axi_aclk), + .resetn(m_axi_aresetn), + .s_valid(req_valid), + .s_ready(req_ready), + .m_valid({ + bl_valid, + bl_valid_ag, + req_valid_ag + }), + .m_ready({ + bl_ready, + bl_ready_ag, + req_ready_ag + }) +); + +dmac_address_generator #( + .ID_WIDTH(ID_WIDTH), + .BEATS_PER_BURST_WIDTH(BEATS_PER_BURST_WIDTH), + .BYTES_PER_BEAT_WIDTH(BYTES_PER_BEAT_WIDTH), + .DMA_DATA_WIDTH(DMA_DATA_WIDTH), + .LENGTH_WIDTH(AXI_LENGTH_WIDTH), + .DMA_ADDR_WIDTH(DMA_ADDR_WIDTH) +) i_addr_gen ( + .clk(m_axi_aclk), + .resetn(m_axi_aresetn), + + .enable(enable), + .enabled(address_enabled), + + .request_id(request_id), + .id(address_id), + + .req_valid(req_valid_ag), + .req_ready(req_ready_ag), + .req_address(req_address), + + .bl_valid(bl_valid_ag), + .bl_ready(bl_ready_ag), + .measured_last_burst_length(req_last_burst_length), + + .eot(address_eot), + + .addr_ready(m_axi_arready), + .addr_valid(m_axi_arvalid), + .addr(m_axi_araddr), + .len(m_axi_arlen), + .size(m_axi_arsize), + .burst(m_axi_arburst), + .prot(m_axi_arprot), + .cache(m_axi_arcache) +); + +assign fifo_valid = m_axi_rvalid; +assign fifo_data = m_axi_rdata; +assign fifo_last = m_axi_rlast; + +/* + * There is a requirement that data_id <= address_id (modulo 2**ID_WIDTH). We + * know that we will never receive data before we have requested it so there is + * an implicit dependency between data_id and address_id and no need to + * explicitly track it. + */ +always @(posedge m_axi_aclk) begin + if (m_axi_aresetn == 1'b0) begin + id <= 'h00; + end else if (m_axi_rvalid == 1'b1 && m_axi_rlast == 1'b1) begin + id <= inc_id(id); + end +end + +/* + * We won't be receiving data before we've requested it and we won't request + * data unless there is room in the store-and-forward memory. + */ +assign m_axi_rready = 1'b1; + +/* + * We need to complete all bursts for which an address has been put onto the + * AXI-MM interface. + */ +always @(posedge m_axi_aclk) begin + if (m_axi_aresetn == 1'b0) begin + enabled <= 1'b0; + end else if (address_enabled == 1'b1) begin + enabled <= 1'b1; + end else if (id == address_id) begin + enabled <= 1'b0; + end +end + +/* TODO +`include "resp.vh" + +assign response_valid = 1'b0; +assign response_resp = RESP_OKAY; + +reg [1:0] rresp; + +always @(posedge m_axi_aclk) +begin + if (m_axi_rvalid && m_axi_rready) begin + if (m_axi_rresp != 2'b0) + rresp <= m_axi_rresp; + end +end +*/ + +endmodule diff --git a/src/adi/hdl/library/axi_dmac/src_axi_stream.v b/src/adi/hdl/library/axi_dmac/src_axi_stream.v new file mode 100644 index 00000000..e9d59c06 --- /dev/null +++ b/src/adi/hdl/library/axi_dmac/src_axi_stream.v @@ -0,0 +1,135 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright 2014 - 2017 (c) Analog Devices, Inc. All rights reserved. +// +// In this HDL repository, there are many different and unique modules, consisting +// of various HDL (Verilog or VHDL) components. The individual modules are +// developed independently, and may be accompanied by separate and unique license +// terms. +// +// The user should read each of these license terms, and understand the +// freedoms and responsibilities that he or she has by using this source/core. +// +// This core 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. +// +// Redistribution and use of source or resulting binaries, with or without modification +// of this file, are permitted under one of the following two license terms: +// +// 1. The GNU General Public License version 2 as published by the +// Free Software Foundation, which can be found in the top level directory +// of this repository (LICENSE_GPL2), and also online at: +// +// +// OR +// +// 2. An ADI specific BSD license, which can be found in the top level directory +// of this repository (LICENSE_ADIBSD), and also on-line at: +// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD +// This will allow to generate bit files and not release the source code, +// as long as it attaches to an ADI device. +// +// *************************************************************************** +// *************************************************************************** + +`timescale 1ns/100ps + +module dmac_src_axi_stream #( + + parameter ID_WIDTH = 3, + parameter S_AXIS_DATA_WIDTH = 64, + parameter LENGTH_WIDTH = 24, + parameter BEATS_PER_BURST_WIDTH = 4)( + + input s_axis_aclk, + input s_axis_aresetn, + + input enable, + output enabled, + + input [ID_WIDTH-1:0] request_id, + output [ID_WIDTH-1:0] response_id, + input eot, + + output rewind_req_valid, + input rewind_req_ready, + output [ID_WIDTH+3-1:0] rewind_req_data, + + output bl_valid, + input bl_ready, + output [BEATS_PER_BURST_WIDTH-1:0] measured_last_burst_length, + + output block_descr_to_dst, + + output [ID_WIDTH-1:0] source_id, + output source_eot, + + output s_axis_ready, + input s_axis_valid, + input [S_AXIS_DATA_WIDTH-1:0] s_axis_data, + input [0:0] s_axis_user, + input s_axis_last, + output s_axis_xfer_req, + + output fifo_valid, + output [S_AXIS_DATA_WIDTH-1:0] fifo_data, + output fifo_last, + output fifo_partial_burst, + + input req_valid, + output req_ready, + input [BEATS_PER_BURST_WIDTH-1:0] req_last_burst_length, + input req_sync_transfer_start, + input req_xlast +); + +assign enabled = enable; + +dmac_data_mover # ( + .ID_WIDTH(ID_WIDTH), + .DATA_WIDTH(S_AXIS_DATA_WIDTH), + .BEATS_PER_BURST_WIDTH(BEATS_PER_BURST_WIDTH), + .ALLOW_ABORT(1) +) i_data_mover ( + .clk(s_axis_aclk), + .resetn(s_axis_aresetn), + + .xfer_req(s_axis_xfer_req), + + .request_id(request_id), + .response_id(response_id), + .eot(eot), + + .rewind_req_valid(rewind_req_valid), + .rewind_req_ready(rewind_req_ready), + .rewind_req_data(rewind_req_data), + + .bl_valid(bl_valid), + .bl_ready(bl_ready), + .measured_last_burst_length(measured_last_burst_length), + + .block_descr_to_dst(block_descr_to_dst), + + .source_id(source_id), + .source_eot(source_eot), + + .req_valid(req_valid), + .req_ready(req_ready), + .req_last_burst_length(req_last_burst_length), + .req_sync_transfer_start(req_sync_transfer_start), + .req_xlast(req_xlast), + + .s_axi_valid(s_axis_valid), + .s_axi_ready(s_axis_ready), + .s_axi_data(s_axis_data), + .s_axi_last(s_axis_last), + .s_axi_sync(s_axis_user[0]), + + .m_axi_valid(fifo_valid), + .m_axi_data(fifo_data), + .m_axi_last(fifo_last), + .m_axi_partial_burst(fifo_partial_burst) +); + +endmodule diff --git a/src/adi/hdl/library/axi_dmac/src_fifo_inf.v b/src/adi/hdl/library/axi_dmac/src_fifo_inf.v new file mode 100644 index 00000000..a9e417bb --- /dev/null +++ b/src/adi/hdl/library/axi_dmac/src_fifo_inf.v @@ -0,0 +1,125 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright 2014 - 2017 (c) Analog Devices, Inc. All rights reserved. +// +// In this HDL repository, there are many different and unique modules, consisting +// of various HDL (Verilog or VHDL) components. The individual modules are +// developed independently, and may be accompanied by separate and unique license +// terms. +// +// The user should read each of these license terms, and understand the +// freedoms and responsibilities that he or she has by using this source/core. +// +// This core 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. +// +// Redistribution and use of source or resulting binaries, with or without modification +// of this file, are permitted under one of the following two license terms: +// +// 1. The GNU General Public License version 2 as published by the +// Free Software Foundation, which can be found in the top level directory +// of this repository (LICENSE_GPL2), and also online at: +// +// +// OR +// +// 2. An ADI specific BSD license, which can be found in the top level directory +// of this repository (LICENSE_ADIBSD), and also on-line at: +// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD +// This will allow to generate bit files and not release the source code, +// as long as it attaches to an ADI device. +// +// *************************************************************************** +// *************************************************************************** + +`timescale 1ns/100ps + +module dmac_src_fifo_inf #( + + parameter ID_WIDTH = 3, + parameter DATA_WIDTH = 64, + parameter BEATS_PER_BURST_WIDTH = 4)( + + input clk, + input resetn, + + input enable, + output enabled, + + input [ID_WIDTH-1:0] request_id, + output [ID_WIDTH-1:0] response_id, + input eot, + + output bl_valid, + input bl_ready, + output [BEATS_PER_BURST_WIDTH-1:0] measured_last_burst_length, + + input en, + input [DATA_WIDTH-1:0] din, + output reg overflow, + input sync, + output xfer_req, + + output fifo_valid, + output [DATA_WIDTH-1:0] fifo_data, + output fifo_last, + + input req_valid, + output req_ready, + input [BEATS_PER_BURST_WIDTH-1:0] req_last_burst_length, + input req_sync_transfer_start +); + +wire ready; +wire valid; + +assign enabled = enable; + +assign valid = en & ready; + +always @(posedge clk) +begin + if (enable) begin + overflow <= en & ~ready; + end else begin + overflow <= en; + end +end + +dmac_data_mover # ( + .ID_WIDTH(ID_WIDTH), + .DATA_WIDTH(DATA_WIDTH), + .BEATS_PER_BURST_WIDTH(BEATS_PER_BURST_WIDTH) +) i_data_mover ( + .clk(clk), + .resetn(resetn), + + .xfer_req(xfer_req), + + .request_id(request_id), + .response_id(response_id), + .eot(eot), + + .bl_valid(bl_valid), + .bl_ready(bl_ready), + .measured_last_burst_length(measured_last_burst_length), + + .req_valid(req_valid), + .req_ready(req_ready), + .req_last_burst_length(req_last_burst_length), + .req_sync_transfer_start(req_sync_transfer_start), + .req_xlast(1'b0), + + .s_axi_ready(ready), + .s_axi_valid(valid), + .s_axi_data(din), + .s_axi_sync(sync), + .s_axi_last(1'b0), + + .m_axi_valid(fifo_valid), + .m_axi_data(fifo_data), + .m_axi_last(fifo_last) +); + +endmodule diff --git a/src/adi/hdl/library/axi_dmac/tb/axi_read_slave.v b/src/adi/hdl/library/axi_dmac/tb/axi_read_slave.v new file mode 100644 index 00000000..281418bc --- /dev/null +++ b/src/adi/hdl/library/axi_dmac/tb/axi_read_slave.v @@ -0,0 +1,99 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright 2018 (c) Analog Devices, Inc. All rights reserved. +// +// In this HDL repository, there are many different and unique modules, consisting +// of various HDL (Verilog or VHDL) components. The individual modules are +// developed independently, and may be accompanied by separate and unique license +// terms. +// +// The user should read each of these license terms, and understand the +// freedoms and responsibilities that he or she has by using this source/core. +// +// This core 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. +// +// Redistribution and use of source or resulting binaries, with or without modification +// of this file, are permitted under one of the following two license terms: +// +// 1. The GNU General Public License version 2 as published by the +// Free Software Foundation, which can be found in the top level directory +// of this repository (LICENSE_GPL2), and also online at: +// +// +// OR +// +// 2. An ADI specific BSD license, which can be found in the top level directory +// of this repository (LICENSE_ADIBSD), and also on-line at: +// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD +// This will allow to generate bit files and not release the source code, +// as long as it attaches to an ADI device. +// +// *************************************************************************** +// *************************************************************************** + +`timescale 1ns/100ps + +module axi_read_slave #( + parameter DATA_WIDTH = 32, + parameter READ_ACCEPTANCE = 4, + parameter MIN_LATENCY = 48, + parameter MAX_LATENCY = 48 +) ( + input clk, + input reset, + + input arvalid, + output arready, + input [31:0] araddr, + input [7:0] arlen, + input [2:0] arsize, + input [1:0] arburst, + input [2:0] arprot, + input [3:0] arcache, + + output rvalid, + input rready, + output [DATA_WIDTH-1:0] rdata, + output [1:0] rresp, + output rlast +); + +reg [DATA_WIDTH-1:0] data = 'h00; + +assign rresp = 2'b00; +//assign rdata = data; + +always @(posedge clk) begin + if (reset == 1'b1) begin + data <= 'h00; + end else if (rvalid == 1'b1 && rready == 1'b1) begin + data <= data + 1'b1; + end +end + +axi_slave #( + .ACCEPTANCE(READ_ACCEPTANCE), + .MIN_LATENCY(MIN_LATENCY), + .MAX_LATENCY(MAX_LATENCY) +) i_axi_slave ( + .clk(clk), + .reset(reset), + + .valid(arvalid), + .ready(arready), + .addr(araddr), + .len(arlen), + .size(arsize), + .burst(arburst), + .prot(arprot), + .cache(arcache), + + .beat_stb(rvalid), + .beat_ack(rvalid & rready), + .beat_last(rlast), + .beat_addr(rdata) +); + +endmodule diff --git a/src/adi/hdl/library/axi_dmac/tb/axi_slave.v b/src/adi/hdl/library/axi_dmac/tb/axi_slave.v new file mode 100644 index 00000000..c60b225a --- /dev/null +++ b/src/adi/hdl/library/axi_dmac/tb/axi_slave.v @@ -0,0 +1,112 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright 2018 (c) Analog Devices, Inc. All rights reserved. +// +// In this HDL repository, there are many different and unique modules, consisting +// of various HDL (Verilog or VHDL) components. The individual modules are +// developed independently, and may be accompanied by separate and unique license +// terms. +// +// The user should read each of these license terms, and understand the +// freedoms and responsibilities that he or she has by using this source/core. +// +// This core 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. +// +// Redistribution and use of source or resulting binaries, with or without modification +// of this file, are permitted under one of the following two license terms: +// +// 1. The GNU General Public License version 2 as published by the +// Free Software Foundation, which can be found in the top level directory +// of this repository (LICENSE_GPL2), and also online at: +// +// +// OR +// +// 2. An ADI specific BSD license, which can be found in the top level directory +// of this repository (LICENSE_ADIBSD), and also on-line at: +// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD +// This will allow to generate bit files and not release the source code, +// as long as it attaches to an ADI device. +// +// *************************************************************************** +// *************************************************************************** + +`timescale 1ns/100ps + +module axi_slave #( + parameter ACCEPTANCE = 3, + parameter MIN_LATENCY = 16, + parameter MAX_LATENCY = 32 +) ( + input clk, + input reset, + + input valid, + output ready, + input [31:0] addr, + input [7:0] len, + input [2:0] size, + input [1:0] burst, + input [2:0] prot, + input [3:0] cache, + + output beat_stb, + input beat_ack, + output [31:0] beat_addr, + output beat_last +); + +reg [31:0] timestamp = 'h00; + +always @(posedge clk) begin + if (reset == 1'b1) begin + timestamp <= 'h00; + end else begin + timestamp <= timestamp + 1'b1; + end +end + +reg [32+32+8-1:0] req_fifo[0:15]; +reg [3:0] req_fifo_rd = 'h00; +reg [3:0] req_fifo_wr = 'h00; +wire [3:0] req_fifo_level = req_fifo_wr - req_fifo_rd; + +assign ready = req_fifo_level < ACCEPTANCE; + +always @(posedge clk) begin + if (reset == 1'b1) begin + req_fifo_wr <= 'h00; + end else begin + if (valid == 1'b1 && ready == 1'b1) begin + req_fifo[req_fifo_wr][71:40] <= timestamp + {$random} % (MAX_LATENCY - MIN_LATENCY + 1) + MIN_LATENCY; + req_fifo[req_fifo_wr][39:0] <= {addr,len}; + req_fifo_wr <= req_fifo_wr + 1'b1; + end + end +end + +reg [7:0] beat_counter = 'h00; + +assign beat_stb = req_fifo_level != 0 && timestamp > req_fifo[req_fifo_rd][71:40]; +assign beat_last = beat_stb ? beat_counter == req_fifo[req_fifo_rd][0+:8] : 1'b0; +assign beat_addr = req_fifo[req_fifo_rd][8+:32] + beat_counter * 4; + +always @(posedge clk) begin + if (reset == 1'b1) begin + beat_counter <= 'h00; + req_fifo_rd <= 'h00; + end else begin + if (beat_ack == 1'b1) begin + if (beat_last == 1'b1) begin + beat_counter <= 'h00; + req_fifo_rd <= req_fifo_rd + 1'b1; + end else begin + beat_counter <= beat_counter + 1'b1; + end + end + end +end + +endmodule diff --git a/src/adi/hdl/library/axi_dmac/tb/axi_write_slave.v b/src/adi/hdl/library/axi_dmac/tb/axi_write_slave.v new file mode 100644 index 00000000..06de2f18 --- /dev/null +++ b/src/adi/hdl/library/axi_dmac/tb/axi_write_slave.v @@ -0,0 +1,130 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright 2018 (c) Analog Devices, Inc. All rights reserved. +// +// In this HDL repository, there are many different and unique modules, consisting +// of various HDL (Verilog or VHDL) components. The individual modules are +// developed independently, and may be accompanied by separate and unique license +// terms. +// +// The user should read each of these license terms, and understand the +// freedoms and responsibilities that he or she has by using this source/core. +// +// This core 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. +// +// Redistribution and use of source or resulting binaries, with or without modification +// of this file, are permitted under one of the following two license terms: +// +// 1. The GNU General Public License version 2 as published by the +// Free Software Foundation, which can be found in the top level directory +// of this repository (LICENSE_GPL2), and also online at: +// +// +// OR +// +// 2. An ADI specific BSD license, which can be found in the top level directory +// of this repository (LICENSE_ADIBSD), and also on-line at: +// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD +// This will allow to generate bit files and not release the source code, +// as long as it attaches to an ADI device. +// +// *************************************************************************** +// *************************************************************************** + +`timescale 1ns/100ps + +module axi_write_slave #( + parameter DATA_WIDTH = 32, + parameter WRITE_ACCEPTANCE = 3 +) ( + input clk, + input reset, + + input awvalid, + output awready, + input [31:0] awaddr, + input [7:0] awlen, + input [2:0] awsize, + input [1:0] awburst, + input [2:0] awprot, + input [3:0] awcache, + + input wvalid, + output wready, + input [DATA_WIDTH-1:0] wdata, + input [DATA_WIDTH/8-1:0] wstrb, + input wlast, + + output reg bvalid, + input bready, + output [1:0] bresp +); + +wire beat_last; + +axi_slave #( + .ACCEPTANCE(WRITE_ACCEPTANCE) +) i_axi_slave ( + .clk(clk), + .reset(reset), + + .valid(awvalid), + .ready(awready), + .addr(awaddr), + .len(awlen), + .size(awsize), + .burst(awburst), + .prot(awprot), + .cache(awcache), + + .beat_stb(wready), + .beat_ack(wvalid & wready), + .beat_last(beat_last) +); + +reg [4:0] resp_count = 'h00; +wire [4:0] resp_count_next; +reg [DATA_WIDTH-1:0] data_cmp = 'h00; +reg failed = 'b0; + +assign bresp = 2'b00; + +wire resp_count_dec = bvalid & bready; +wire resp_count_inc = wvalid & wready & beat_last; +assign resp_count_next = resp_count - resp_count_dec + resp_count_inc; + +always @(posedge clk) begin + if (reset == 1'b1) begin + resp_count <= 'h00; + end else begin + resp_count <= resp_count - resp_count_dec + resp_count_inc; + end +end + +always @(posedge clk) begin + if (reset == 1'b1) begin + bvalid <= 1'b0; + end else if (bvalid == 1'b0 || bready == 1'b1) begin + if (resp_count_next != 'h00) begin + bvalid <= {$random} % 4 == 0; + end else begin + bvalid <= 1'b0; + end + end +end + +always @(posedge clk) begin + if (reset) begin + data_cmp <= 'h00; + failed <= 'b0; + end else if (wvalid & wready) begin + if (data_cmp !== wdata) begin + failed <= 1'b1; + end + data_cmp <= data_cmp + 'h4; + end +end + +endmodule diff --git a/src/adi/hdl/library/axi_dmac/tb/dma_read_shutdown_tb b/src/adi/hdl/library/axi_dmac/tb/dma_read_shutdown_tb new file mode 100755 index 00000000..6ba47d32 --- /dev/null +++ b/src/adi/hdl/library/axi_dmac/tb/dma_read_shutdown_tb @@ -0,0 +1,19 @@ +#!/bin/bash + +SOURCE="$0.v" +SOURCE+=" axi_read_slave.v axi_slave.v" +SOURCE+=" ../axi_dmac_transfer.v ../request_arb.v ../request_generator.v ../splitter.v" +SOURCE+=" ../2d_transfer.v" +SOURCE+=" ../axi_dmac_resize_src.v ../axi_dmac_resize_dest.v" +SOURCE+=" ../axi_dmac_burst_memory.v" +SOURCE+=" ../axi_dmac_reset_manager.v ../axi_register_slice.v" +SOURCE+=" ../dest_fifo_inf.v" +SOURCE+=" ../axi_dmac_response_manager.v" +SOURCE+=" ../src_axi_mm.v ../address_generator.v ../response_generator.v" +SOURCE+=" ../../util_axis_fifo/util_axis_fifo.v" +SOURCE+=" ../../util_cdc/sync_bits.v" +SOURCE+=" ../../util_cdc/sync_event.v" +SOURCE+=" ../../common/ad_mem.v" + +cd `dirname $0` +source run_tb.sh diff --git a/src/adi/hdl/library/axi_dmac/tb/dma_read_shutdown_tb.v b/src/adi/hdl/library/axi_dmac/tb/dma_read_shutdown_tb.v new file mode 100644 index 00000000..d1d0ec6e --- /dev/null +++ b/src/adi/hdl/library/axi_dmac/tb/dma_read_shutdown_tb.v @@ -0,0 +1,162 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright 2014 - 2018 (c) Analog Devices, Inc. All rights reserved. +// +// In this HDL repository, there are many different and unique modules, consisting +// of various HDL (Verilog or VHDL) components. The individual modules are +// developed independently, and may be accompanied by separate and unique license +// terms. +// +// The user should read each of these license terms, and understand the +// freedoms and responsibilities that he or she has by using this source/core. +// +// This core 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. +// +// Redistribution and use of source or resulting binaries, with or without modification +// of this file, are permitted under one of the following two license terms: +// +// 1. The GNU General Public License version 2 as published by the +// Free Software Foundation, which can be found in the top level directory +// of this repository (LICENSE_GPL2), and also online at: +// +// +// OR +// +// 2. An ADI specific BSD license, which can be found in the top level directory +// of this repository (LICENSE_ADIBSD), and also on-line at: +// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD +// This will allow to generate bit files and not release the source code, +// as long as it attaches to an ADI device. +// +// *************************************************************************** +// *************************************************************************** + +`timescale 1ns/100ps + +module dmac_dma_read_shutdown_tb; + parameter VCD_FILE = {`__FILE__,"cd"}; + + `include "tb_base.v" + + localparam TRANSFER_ADDR = 32'h80000000; + localparam TRANSFER_LEN = 24'h2ff; + + reg fifo_clk = 1'b0; + + wire awvalid; + wire awready; + wire [31:0] araddr; + wire [7:0] arlen; + wire [2:0] arsize; + wire [1:0] arburst; + wire [2:0] arprot; + wire [3:0] arcache; + + wire rlast; + wire rvalid; + wire rready; + wire [1:0] rresp; + wire [31:0] rdata; + + /* Twice as fast as the AXI clk so we have lots of read requests */ + always @(*) #5 fifo_clk <= ~fifo_clk; + + axi_read_slave #( + .DATA_WIDTH(32) + ) i_read_slave ( + .clk(clk), + .reset(reset), + + .arvalid(arvalid), + .arready(arready), + .araddr(araddr), + .arlen(arlen), + .arsize(arsize), + .arburst(arburst), + .arprot(arprot), + .arcache(arcache), + + .rready(rready), + .rvalid(rvalid), + .rdata(rdata), + .rresp(rresp), + .rlast(rlast) + ); + + wire [11:0] dbg_status; + + reg ctrl_enable = 1'b0; + + initial begin + #1000 + @(posedge clk) ctrl_enable <= 1'b1; + #3000 + @(posedge clk) ctrl_enable <= 1'b0; + end + + always @(posedge clk) begin + /* + * When disabled the DMA should eventually end up in an idle state and all + * requests that were sent out need to be accepted + */ + failed <= ctrl_enable == 1'b0 && ( + dbg_status !== 12'h701 || + i_read_slave.i_axi_slave.req_fifo_level !== 'h00); + end + + axi_dmac_transfer #( + .DMA_TYPE_SRC(0), + .DMA_TYPE_DEST(2), + .DMA_DATA_WIDTH_SRC(32), + .DMA_DATA_WIDTH_DEST(32), + .FIFO_SIZE(8) + ) i_transfer ( + .m_src_axi_aclk (clk), + .m_src_axi_aresetn(resetn), + + .m_axi_arvalid(arvalid), + .m_axi_arready(arready), + .m_axi_araddr(araddr), + .m_axi_arlen(arlen), + .m_axi_arsize(arsize), + .m_axi_arburst(arburst), + .m_axi_arprot(arprot), + .m_axi_arcache(arcache), + + .m_axi_rready(rready), + .m_axi_rvalid(rvalid), + .m_axi_rdata(rdata), + .m_axi_rlast(rlast), + .m_axi_rresp(rresp), + + .ctrl_clk(clk), + .ctrl_resetn(resetn), + + .ctrl_enable(ctrl_enable), + .ctrl_pause(1'b0), + + .req_eot(), + + .req_valid(1'b1), + .req_ready(), + .req_dest_address(TRANSFER_ADDR[31:2]), + .req_src_address(TRANSFER_ADDR[31:2]), + .req_x_length(TRANSFER_LEN), + .req_y_length(24'h00), + .req_dest_stride(24'h00), + .req_src_stride(24'h00), + .req_sync_transfer_start(1'b0), + .req_last(1'b0), + + .fifo_rd_clk(fifo_clk), + .fifo_rd_en(1'b1), + .fifo_rd_valid(), + .fifo_rd_underflow(), + .fifo_rd_dout(), + + .dbg_status(dbg_status) + ); + +endmodule diff --git a/src/adi/hdl/library/axi_dmac/tb/dma_read_tb b/src/adi/hdl/library/axi_dmac/tb/dma_read_tb new file mode 100755 index 00000000..7378f36e --- /dev/null +++ b/src/adi/hdl/library/axi_dmac/tb/dma_read_tb @@ -0,0 +1,18 @@ +#!/bin/bash + +SOURCE="dma_read_tb.v" +SOURCE+=" axi_read_slave.v axi_slave.v" +SOURCE+=" ../axi_dmac_transfer.v ../2d_transfer.v ../request_arb.v ../request_generator.v ../splitter.v" +SOURCE+=" ../axi_dmac_resize_src.v ../axi_dmac_resize_dest.v" +SOURCE+=" ../axi_dmac_burst_memory.v" +SOURCE+=" ../axi_dmac_reset_manager.v ../axi_register_slice.v" +SOURCE+=" ../dest_fifo_inf.v" +SOURCE+=" ../axi_dmac_response_manager.v" +SOURCE+=" ../src_axi_mm.v ../address_generator.v ../response_generator.v" +SOURCE+=" ../../util_axis_fifo/util_axis_fifo.v" +SOURCE+=" ../../util_cdc/sync_bits.v" +SOURCE+=" ../../util_cdc/sync_event.v" +SOURCE+=" ../../common/ad_mem.v" + +cd `dirname $0` +source run_tb.sh diff --git a/src/adi/hdl/library/axi_dmac/tb/dma_read_tb.v b/src/adi/hdl/library/axi_dmac/tb/dma_read_tb.v new file mode 100644 index 00000000..18075e78 --- /dev/null +++ b/src/adi/hdl/library/axi_dmac/tb/dma_read_tb.v @@ -0,0 +1,177 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright 2018 (c) Analog Devices, Inc. All rights reserved. +// +// In this HDL repository, there are many different and unique modules, consisting +// of various HDL (Verilog or VHDL) components. The individual modules are +// developed independently, and may be accompanied by separate and unique license +// terms. +// +// The user should read each of these license terms, and understand the +// freedoms and responsibilities that he or she has by using this source/core. +// +// This core 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. +// +// Redistribution and use of source or resulting binaries, with or without modification +// of this file, are permitted under one of the following two license terms: +// +// 1. The GNU General Public License version 2 as published by the +// Free Software Foundation, which can be found in the top level directory +// of this repository (LICENSE_GPL2), and also online at: +// +// +// OR +// +// 2. An ADI specific BSD license, which can be found in the top level directory +// of this repository (LICENSE_ADIBSD), and also on-line at: +// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD +// This will allow to generate bit files and not release the source code, +// as long as it attaches to an ADI device. +// +// *************************************************************************** +// *************************************************************************** + +`timescale 1ns/100ps + +module dmac_dma_read_tb; + parameter VCD_FILE = {`__FILE__,"cd"}; + + `include "tb_base.v" + + localparam TRANSFER_ADDR = 32'h80000000; + localparam TRANSFER_LEN = 24'h203; + + reg req_valid = 1'b1; + wire req_ready; + reg [23:0] req_length = 'h03; + + wire awvalid; + wire awready; + wire [31:0] araddr; + wire [7:0] arlen; + wire [2:0] arsize; + wire [1:0] arburst; + wire [2:0] arprot; + wire [3:0] arcache; + + wire rlast; + wire rvalid; + wire rready; + wire [1:0] rresp; + wire [31:0] rdata; + + always @(posedge clk) begin + if (reset != 1'b1 && req_ready == 1'b1) begin + req_valid <= 1'b1; + req_length <= req_length + 4; + end + end + + axi_read_slave #( + .DATA_WIDTH(32) + ) i_write_slave ( + .clk(clk), + .reset(reset), + + .arvalid(arvalid), + .arready(arready), + .araddr(araddr), + .arlen(arlen), + .arsize(arsize), + .arburst(arburst), + .arprot(arprot), + .arcache(arcache), + + .rready(rready), + .rvalid(rvalid), + .rdata(rdata), + .rresp(rresp), + .rlast(rlast) + ); + + wire fifo_rd_en = 1'b1; + wire fifo_rd_valid; + wire fifo_rd_underflow; + wire [31:0] fifo_rd_dout; + reg [31:0] fifo_rd_dout_cmp = TRANSFER_ADDR; + reg fifo_rd_dout_mismatch = 1'b0; + reg [31:0] fifo_rd_dout_limit = 'h0; + + axi_dmac_transfer #( + .DMA_TYPE_SRC(0), + .DMA_TYPE_DEST(2), + .DMA_DATA_WIDTH_SRC(32), + .DMA_DATA_WIDTH_DEST(32), + .FIFO_SIZE(8) + ) transfer ( + .m_src_axi_aclk(clk), + .m_src_axi_aresetn(resetn), + + .m_axi_arvalid(arvalid), + .m_axi_arready(arready), + .m_axi_araddr(araddr), + .m_axi_arlen(arlen), + .m_axi_arsize(arsize), + .m_axi_arburst(arburst), + .m_axi_arprot(arprot), + .m_axi_arcache(arcache), + + .m_axi_rready(rready), + .m_axi_rvalid(rvalid), + .m_axi_rdata(rdata), + .m_axi_rlast(rlast), + .m_axi_rresp(rresp), + + .ctrl_clk(clk), + .ctrl_resetn(resetn), + + .ctrl_enable(1'b1), + .ctrl_pause(1'b0), + + .req_eot(eot), + + .req_valid(req_valid), + .req_ready(req_ready), + .req_dest_address(TRANSFER_ADDR[31:2]), + .req_src_address(TRANSFER_ADDR[31:2]), + .req_x_length(req_length), + .req_y_length(24'h00), + .req_dest_stride(24'h00), + .req_src_stride(24'h00), + .req_sync_transfer_start(1'b0), + + .fifo_rd_clk(clk), + .fifo_rd_en(fifo_rd_en), + .fifo_rd_valid(fifo_rd_valid), + .fifo_rd_underflow(fifo_rd_underflow), + .fifo_rd_dout(fifo_rd_dout) + ); + + always @(posedge clk) begin + if (reset == 1'b1) begin + fifo_rd_dout_cmp <= TRANSFER_ADDR; + fifo_rd_dout_mismatch <= 1'b0; + end else begin + fifo_rd_dout_mismatch <= 1'b0; + + if (fifo_rd_valid == 1'b1) begin + if (fifo_rd_dout_cmp < TRANSFER_ADDR + fifo_rd_dout_limit) begin + fifo_rd_dout_cmp <= (fifo_rd_dout_cmp + 'h4); + end else begin + fifo_rd_dout_cmp <= TRANSFER_ADDR; + fifo_rd_dout_limit <= fifo_rd_dout_limit + 'h4; + end + if (fifo_rd_dout_cmp != fifo_rd_dout) begin + fifo_rd_dout_mismatch <= 1'b1; + end + end + end + end + + always @(posedge clk) begin + failed <= failed | fifo_rd_dout_mismatch; + end + +endmodule diff --git a/src/adi/hdl/library/axi_dmac/tb/dma_write_shutdown_tb b/src/adi/hdl/library/axi_dmac/tb/dma_write_shutdown_tb new file mode 100755 index 00000000..5fdb11f7 --- /dev/null +++ b/src/adi/hdl/library/axi_dmac/tb/dma_write_shutdown_tb @@ -0,0 +1,19 @@ +#!/bin/bash + +SOURCE="$0.v" +SOURCE+=" axi_write_slave.v axi_slave.v" +SOURCE+=" ../axi_dmac_transfer.v ../request_arb.v ../request_generator.v ../splitter.v" +SOURCE+=" ../2d_transfer.v" +SOURCE+=" ../axi_dmac_resize_src.v ../axi_dmac_resize_dest.v" +SOURCE+=" ../axi_dmac_burst_memory.v" +SOURCE+=" ../axi_dmac_reset_manager.v ../data_mover.v ../axi_register_slice.v" +SOURCE+=" ../src_fifo_inf.v" +SOURCE+=" ../axi_dmac_response_manager.v" +SOURCE+=" ../dest_axi_mm.v ../response_handler.v ../address_generator.v" +SOURCE+=" ../../util_axis_fifo/util_axis_fifo.v" +SOURCE+=" ../../util_cdc/sync_bits.v" +SOURCE+=" ../../util_cdc/sync_event.v" +SOURCE+=" ../../common/ad_mem.v" + +cd `dirname $0` +source run_tb.sh diff --git a/src/adi/hdl/library/axi_dmac/tb/dma_write_shutdown_tb.v b/src/adi/hdl/library/axi_dmac/tb/dma_write_shutdown_tb.v new file mode 100644 index 00000000..af037908 --- /dev/null +++ b/src/adi/hdl/library/axi_dmac/tb/dma_write_shutdown_tb.v @@ -0,0 +1,169 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright 2014 - 2018 (c) Analog Devices, Inc. All rights reserved. +// +// In this HDL repository, there are many different and unique modules, consisting +// of various HDL (Verilog or VHDL) components. The individual modules are +// developed independently, and may be accompanied by separate and unique license +// terms. +// +// The user should read each of these license terms, and understand the +// freedoms and responsibilities that he or she has by using this source/core. +// +// This core 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. +// +// Redistribution and use of source or resulting binaries, with or without modification +// of this file, are permitted under one of the following two license terms: +// +// 1. The GNU General Public License version 2 as published by the +// Free Software Foundation, which can be found in the top level directory +// of this repository (LICENSE_GPL2), and also online at: +// +// +// OR +// +// 2. An ADI specific BSD license, which can be found in the top level directory +// of this repository (LICENSE_ADIBSD), and also on-line at: +// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD +// This will allow to generate bit files and not release the source code, +// as long as it attaches to an ADI device. +// +// *************************************************************************** +// *************************************************************************** + +`timescale 1ns/100ps + +module dmac_dma_write_shutdown_tb; + parameter VCD_FILE = {`__FILE__,"cd"}; + + `include "tb_base.v" + + localparam TRANSFER_ADDR = 32'h80000000; + localparam TRANSFER_LEN = 24'h2ff; + + reg fifo_clk = 1'b0; + + wire awvalid; + wire awready; + wire [31:0] awaddr; + wire [7:0] awlen; + wire [2:0] awsize; + wire [1:0] awburst; + wire [2:0] awprot; + wire [3:0] awcache; + + wire wlast; + wire wvalid; + wire wready; + wire [3:0] wstrb; + wire [31:0] wdata; + + wire bready; + wire bvalid; + wire [1:0] bresp; + + wire [11:0] dbg_status; + + /* Twice as fast as the AXI clk so the FIFO fills up */ + always @(*) #5 fifo_clk <= ~fifo_clk; + + axi_write_slave #( + .DATA_WIDTH(32) + ) i_write_slave ( + .clk(clk), + .reset(reset), + + .awvalid(awvalid), + .awready(awready), + .awaddr(awaddr), + .awlen(awlen), + .awsize(awsize), + .awburst(awburst), + .awprot(awprot), + .awcache(awcache), + + .wready(wready), + .wvalid(wvalid), + .wdata(wdata), + .wstrb(wstrb), + .wlast(wlast), + + .bvalid(bvalid), + .bready(bready), + .bresp(bresp) + ); + + reg ctrl_enable = 1'b0; + + initial begin + #1000 + @(posedge clk) ctrl_enable <= 1'b1; + #3000 + @(posedge clk) ctrl_enable <= 1'b0; + end + + always @(posedge clk) begin + failed <= ctrl_enable == 1'b0 && ( + dbg_status !== 12'h701 || + i_write_slave.i_axi_slave.req_fifo_level !== 'h00); + end + + axi_dmac_transfer #( + .DMA_DATA_WIDTH_SRC(32), + .DMA_DATA_WIDTH_DEST(32), + .FIFO_SIZE(8) + ) i_transfer ( + .m_dest_axi_aclk (clk), + .m_dest_axi_aresetn(resetn), + + .m_axi_awvalid(awvalid), + .m_axi_awready(awready), + .m_axi_awaddr(awaddr), + .m_axi_awlen(awlen), + .m_axi_awsize(awsize), + .m_axi_awburst(awburst), + .m_axi_awprot(awprot), + .m_axi_awcache(awcache), + + .m_axi_wready(wready), + .m_axi_wvalid(wvalid), + .m_axi_wdata(wdata), + .m_axi_wstrb(wstrb), + .m_axi_wlast(wlast), + + .m_axi_bvalid(bvalid), + .m_axi_bready(bready), + .m_axi_bresp(bresp), + + .ctrl_clk(clk), + .ctrl_resetn(resetn), + + .ctrl_enable(ctrl_enable), + .ctrl_pause(1'b0), + + .req_eot(), + .req_response_ready(1'b1), + + .req_valid(1'b1), + .req_ready(), + .req_dest_address(TRANSFER_ADDR[31:2]), + .req_src_address(TRANSFER_ADDR[31:2]), + .req_x_length(TRANSFER_LEN), + .req_y_length(24'h00), + .req_dest_stride(24'h00), + .req_src_stride(24'h00), + .req_sync_transfer_start(1'b0), + .req_last(1'b0), + + .fifo_wr_clk(fifo_clk), + .fifo_wr_en(1'b1), + .fifo_wr_din(32'h00), + .fifo_wr_sync(1'b1), + .fifo_wr_xfer_req(), + + .dbg_status(dbg_status) + ); + +endmodule diff --git a/src/adi/hdl/library/axi_dmac/tb/dma_write_tb b/src/adi/hdl/library/axi_dmac/tb/dma_write_tb new file mode 100755 index 00000000..8538ac08 --- /dev/null +++ b/src/adi/hdl/library/axi_dmac/tb/dma_write_tb @@ -0,0 +1,18 @@ +#!/bin/bash + +SOURCE="dma_write_tb.v" +SOURCE+=" axi_write_slave.v axi_slave.v" +SOURCE+=" ../axi_dmac_transfer.v ../2d_transfer.v ../request_arb.v ../request_generator.v ../splitter.v" +SOURCE+=" ../axi_dmac_resize_src.v ../axi_dmac_resize_dest.v" +SOURCE+=" ../axi_dmac_burst_memory.v" +SOURCE+=" ../axi_dmac_reset_manager.v ../data_mover.v ../axi_register_slice.v" +SOURCE+=" ../src_fifo_inf.v" +SOURCE+=" ../axi_dmac_response_manager.v" +SOURCE+=" ../dest_axi_mm.v ../response_handler.v ../address_generator.v" +SOURCE+=" ../../util_axis_fifo/util_axis_fifo.v" +SOURCE+=" ../../util_cdc/sync_bits.v" +SOURCE+=" ../../util_cdc/sync_event.v" +SOURCE+=" ../../common/ad_mem.v" + +cd `dirname $0` +source run_tb.sh diff --git a/src/adi/hdl/library/axi_dmac/tb/dma_write_tb.v b/src/adi/hdl/library/axi_dmac/tb/dma_write_tb.v new file mode 100644 index 00000000..90164525 --- /dev/null +++ b/src/adi/hdl/library/axi_dmac/tb/dma_write_tb.v @@ -0,0 +1,178 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright 2018 (c) Analog Devices, Inc. All rights reserved. +// +// In this HDL repository, there are many different and unique modules, consisting +// of various HDL (Verilog or VHDL) components. The individual modules are +// developed independently, and may be accompanied by separate and unique license +// terms. +// +// The user should read each of these license terms, and understand the +// freedoms and responsibilities that he or she has by using this source/core. +// +// This core 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. +// +// Redistribution and use of source or resulting binaries, with or without modification +// of this file, are permitted under one of the following two license terms: +// +// 1. The GNU General Public License version 2 as published by the +// Free Software Foundation, which can be found in the top level directory +// of this repository (LICENSE_GPL2), and also online at: +// +// +// OR +// +// 2. An ADI specific BSD license, which can be found in the top level directory +// of this repository (LICENSE_ADIBSD), and also on-line at: +// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD +// This will allow to generate bit files and not release the source code, +// as long as it attaches to an ADI device. +// +// *************************************************************************** +// *************************************************************************** + +`timescale 1ns/100ps + +module dmac_dma_write_tb; + parameter VCD_FILE = {`__FILE__,"cd"}; + + `include "tb_base.v" + + reg req_valid = 1'b1; + wire req_ready; + reg [23:0] req_length = 'h03; + wire awvalid; + wire awready; + wire [31:0] awaddr; + wire [7:0] awlen; + wire [2:0] awsize; + wire [1:0] awburst; + wire [2:0] awprot; + wire [3:0] awcache; + + wire wlast; + wire wvalid; + wire wready; + wire [3:0] wstrb; + wire [31:0] wdata; + + reg [31:0] fifo_wr_din = 'b0; + reg fifo_wr_rq = 'b0; + wire fifo_wr_xfer_req; + + wire bready; + wire bvalid; + wire [1:0] bresp; + + always @(posedge clk) begin + if (reset != 1'b1 && req_ready == 1'b1) begin + req_valid <= 1'b1; + req_length <= req_length + 'h4; + end + end + + axi_write_slave #( + .DATA_WIDTH(32) + ) i_write_slave ( + .clk(clk), + .reset(reset), + + .awvalid(awvalid), + .awready(awready), + .awaddr(awaddr), + .awlen(awlen), + .awsize(awsize), + .awburst(awburst), + .awprot(awprot), + .awcache(awcache), + + .wready(wready), + .wvalid(wvalid), + .wdata(wdata), + .wstrb(wstrb), + .wlast(wlast), + + .bvalid(bvalid), + .bready(bready), + .bresp(bresp) + ); + + axi_dmac_transfer #( + .DMA_DATA_WIDTH_SRC(32), + .DMA_DATA_WIDTH_DEST(32) + ) i_transfer ( + .m_dest_axi_aclk (clk), + .m_dest_axi_aresetn(resetn), + + .m_axi_awvalid(awvalid), + .m_axi_awready(awready), + .m_axi_awaddr(awaddr), + .m_axi_awlen(awlen), + .m_axi_awsize(awsize), + .m_axi_awburst(awburst), + .m_axi_awprot(awprot), + .m_axi_awcache(awcache), + + .m_axi_wready(wready), + .m_axi_wvalid(wvalid), + .m_axi_wdata(wdata), + .m_axi_wstrb(wstrb), + .m_axi_wlast(wlast), + + .m_axi_bvalid(bvalid), + .m_axi_bready(bready), + .m_axi_bresp(bresp), + + .ctrl_clk(clk), + .ctrl_resetn(resetn), + + .ctrl_enable(1'b1), + .ctrl_pause(1'b0), + + .req_eot(eot), + .req_response_ready(1'b1), + + .req_valid(req_valid), + .req_ready(req_ready), + .req_dest_address(30'h7e09000), + .req_x_length(req_length), + .req_y_length(24'h00), + .req_dest_stride(24'h00), + .req_src_stride(24'h00), + .req_sync_transfer_start(1'b0), + + .fifo_wr_clk(clk), + .fifo_wr_en(fifo_wr_en), + .fifo_wr_din(fifo_wr_din), + .fifo_wr_overflow(fifo_wr_overflow), + .fifo_wr_sync(1'b1), + .fifo_wr_xfer_req(fifo_wr_xfer_req) + ); + + always @(posedge clk) begin + if (reset) begin + fifo_wr_din <= 'b0; + fifo_wr_rq <= 'b0; + end else begin + if (fifo_wr_en) begin + fifo_wr_din <= fifo_wr_din + 'h4; + end + fifo_wr_rq <= (($random % 4) == 0); + end + end + + assign fifo_wr_en = fifo_wr_rq & fifo_wr_xfer_req; + + always @(posedge clk) begin + if (reset) begin + failed <= 'b0; + end else begin + failed <= failed | + i_write_slave.failed | + fifo_wr_overflow; + end + end + +endmodule diff --git a/src/adi/hdl/library/axi_dmac/tb/regmap_tb b/src/adi/hdl/library/axi_dmac/tb/regmap_tb new file mode 100755 index 00000000..b2467157 --- /dev/null +++ b/src/adi/hdl/library/axi_dmac/tb/regmap_tb @@ -0,0 +1,10 @@ +#!/bin/bash + +SOURCE="regmap_tb.v" +SOURCE+=" ../axi_dmac_regmap.v ../axi_dmac_regmap_request.v" +SOURCE+=" ../../common/up_axi.v" +SOURCE+=" ../../util_axis_fifo/util_axis_fifo.v" +SOURCE+=" ../../util_axis_fifo/address_sync.v" + +cd `dirname $0` +source run_tb.sh diff --git a/src/adi/hdl/library/axi_dmac/tb/regmap_tb.v b/src/adi/hdl/library/axi_dmac/tb/regmap_tb.v new file mode 100644 index 00000000..1ab42df5 --- /dev/null +++ b/src/adi/hdl/library/axi_dmac/tb/regmap_tb.v @@ -0,0 +1,384 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright 2014 - 2017 (c) Analog Devices, Inc. All rights reserved. +// +// In this HDL repository, there are many different and unique modules, consisting +// of various HDL (Verilog or VHDL) components. The individual modules are +// developed independently, and may be accompanied by separate and unique license +// terms. +// +// The user should read each of these license terms, and understand the +// freedoms and responsibilities that he or she has by using this source/core. +// +// This core 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. +// +// Redistribution and use of source or resulting binaries, with or without modification +// of this file, are permitted under one of the following two license terms: +// +// 1. The GNU General Public License version 2 as published by the +// Free Software Foundation, which can be found in the top level directory +// of this repository (LICENSE_GPL2), and also online at: +// +// +// OR +// +// 2. An ADI specific BSD license, which can be found in the top level directory +// of this repository (LICENSE_ADIBSD), and also on-line at: +// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD +// This will allow to generate bit files and not release the source code, +// as long as it attaches to an ADI device. +// +// *************************************************************************** +// *************************************************************************** + +`timescale 1ns/100ps + +module dmac_regmap_tb; + parameter VCD_FILE = {`__FILE__,"cd"}; + + `define TIMEOUT 1000000 + `include "tb_base.v" + + localparam DMA_LENGTH_WIDTH = 24; + localparam DMA_LENGTH_ALIGN = 3; + localparam BYTES_PER_BEAT = 1; + localparam DMA_AXI_ADDR_WIDTH = 32; + + localparam LENGTH_ALIGN = 2; + localparam LENGTH_MASK = {DMA_LENGTH_WIDTH{1'b1}}; + localparam LENGTH_ALIGN_MASK = {LENGTH_ALIGN{1'b1}}; + localparam STRIDE_MASK = {{DMA_LENGTH_WIDTH-BYTES_PER_BEAT{1'b1}},{BYTES_PER_BEAT{1'b0}}}; + localparam ADDR_MASK = {{DMA_AXI_ADDR_WIDTH-BYTES_PER_BEAT{1'b1}},{BYTES_PER_BEAT{1'b0}}}; + + localparam VAL_DBG_SRC_ADDR = 32'h76543210; + localparam VAL_DBG_DEST_ADDR = 32'hfedcba98; + localparam VAL_DBG_STATUS = 8'ha5; + localparam VAL_DBG_IDS0 = 32'h01234567; + localparam VAL_DBG_IDS1 = 32'h89abcdef; + + localparam AW = 12; + localparam NUM_REGS = 'h200; + + wire s_axi_aclk = clk; + wire s_axi_aresetn = ~reset; + + reg s_axi_awvalid = 1'b0; + reg s_axi_wvalid = 1'b0; + reg [AW-1:0] s_axi_awaddr = 'h00; + reg [31:0] s_axi_wdata = 'h00; + wire [1:0] s_axi_bresp; + wire s_axi_awready; + wire s_axi_wready; + wire s_axi_bready = 1'b1; + wire [3:0] s_axi_wstrb = 4'b1111; + wire [2:0] s_axi_awprot = 3'b000; + wire [2:0] s_axi_arprot = 3'b000; + wire [1:0] s_axi_rresp; + wire [31:0] s_axi_rdata; + + task write_reg; + input [31:0] addr; + input [31:0] value; + begin + @(posedge s_axi_aclk) + s_axi_awvalid <= 1'b1; + s_axi_wvalid <= 1'b1; + s_axi_awaddr <= addr; + s_axi_wdata <= value; + @(posedge s_axi_aclk) + while (s_axi_awvalid || s_axi_wvalid) begin + @(posedge s_axi_aclk) + if (s_axi_awready) + s_axi_awvalid <= 1'b0; + if (s_axi_wready) + s_axi_wvalid <= 1'b0; + end + end + endtask + + reg [31:0] expected_reg_mem[0:NUM_REGS-1]; + + reg [AW-1:0] s_axi_araddr = 'h0; + reg s_axi_arvalid = 'h0; + reg s_axi_rready = 'h0; + wire s_axi_arready; + wire s_axi_rvalid; + + task read_reg; + input [31:0] addr; + output [31:0] value; + begin + s_axi_arvalid <= 1'b1; + s_axi_araddr <= addr; + s_axi_rready <= 1'b1; + @(posedge s_axi_aclk) #0; + while (s_axi_arvalid) begin + if (s_axi_arready == 1'b1) begin + s_axi_arvalid <= 1'b0; + end + @(posedge s_axi_aclk) #0; + end + + while (s_axi_rready) begin + if (s_axi_rvalid == 1'b1) begin + value <= s_axi_rdata; + s_axi_rready <= 1'b0; + end + @(posedge s_axi_aclk) #0; + end + end + endtask + + task read_reg_check; + input [31:0] addr; + output match; + reg [31:0] value; + reg [31:0] expected; + input [255:0] message; + begin + read_reg(addr, value); + expected = expected_reg_mem[addr[11:2]]; + match <= value === expected; + if (value !== expected) begin + $display("%0s: Register mismatch for %x. Expected %x, got %x", + message, addr, expected, value); + end + end + endtask + + reg read_match = 1'b1; + + always @(posedge clk) begin + if (read_match == 1'b0) begin + failed <= 1'b1; + end + end + + + task set_reset_reg_value; + input [31:0] addr; + input [31:0] value; + begin + expected_reg_mem[addr[AW-1:2]] <= value; + end + endtask + + task initialize_expected_reg_mem; + integer i; + begin + for (i = 0; i < NUM_REGS; i = i + 1) + expected_reg_mem[i] <= 'h00; + /* Non zero power-on-reset values */ + set_reset_reg_value('h00, 32'h00040161); /* PCORE version register */ + set_reset_reg_value('h0c, 32'h444d4143); /* PCORE magic register */ + set_reset_reg_value('h80, 'h3); /* IRQ mask */ + + set_reset_reg_value('h40c, 'h3); /* Flags */ + set_reset_reg_value('h418, LENGTH_ALIGN_MASK); /* Length alignment */ + + set_reset_reg_value('h434, VAL_DBG_DEST_ADDR); + set_reset_reg_value('h438, VAL_DBG_SRC_ADDR); + set_reset_reg_value('h43c, VAL_DBG_STATUS); + set_reset_reg_value('h440, VAL_DBG_IDS0); + set_reset_reg_value('h444, VAL_DBG_IDS1); + end + endtask + + task check_all_registers; + input [255:0] message; + integer i; + begin + for (i = 0; i < NUM_REGS*4; i = i + 4) begin + read_reg_check(i, read_match, message); + end + end + endtask + + task write_reg_and_update; + input [31:0] addr; + input [31:0] value; + integer i; + begin + write_reg(addr, value); + expected_reg_mem[addr[AW-1:2]] <= value; + end + endtask + + task invert_register; + input [31:0] addr; + reg [31:0] value; + begin + read_reg(addr, value); + write_reg(addr, ~value); + end + endtask + + task invert_all_registers; + integer i; + begin + for (i = 0; i < NUM_REGS*4; i = i + 4) begin + invert_register(i); + end + end + endtask + + reg request_ready = 1'b0; + wire [31:BYTES_PER_BEAT] request_dest_address; + wire [31:BYTES_PER_BEAT] request_src_address; + wire [DMA_LENGTH_WIDTH-1:0] request_x_length; + wire [DMA_LENGTH_WIDTH-1:0] request_y_length; + wire [DMA_LENGTH_WIDTH-1:0] request_dest_stride; + wire [DMA_LENGTH_WIDTH-1:0] request_src_stride; + wire request_last; + + reg response_eot = 1'b0; + + integer i; + initial begin + initialize_expected_reg_mem(); + @(posedge s_axi_aresetn) + check_all_registers("Initial"); + + /* Check scratch */ + write_reg_and_update('h08, 32'h12345678); + check_all_registers("Scratch"); + + /* Check IRQ mask */ + write_reg_and_update('h80, 32'h0); + check_all_registers("IRQ mask"); + + /* Check transfer registers */ + write_reg_and_update('h40c, 'h3); + write_reg_and_update('h410, ADDR_MASK); + write_reg_and_update('h414, ADDR_MASK); + write_reg_and_update('h418, LENGTH_MASK); + write_reg_and_update('h41c, LENGTH_MASK); + write_reg_and_update('h420, STRIDE_MASK); + write_reg_and_update('h424, STRIDE_MASK); + + check_all_registers("Transfer setup 1"); + + /* Check transfer registers */ + write_reg_and_update('h40c, {$random} & 'h3); + write_reg_and_update('h410, {$random} & ADDR_MASK); + write_reg_and_update('h414, {$random} & ADDR_MASK); + write_reg_and_update('h418, {$random} & LENGTH_MASK | LENGTH_ALIGN_MASK); + write_reg_and_update('h41c, {$random} & LENGTH_MASK); + write_reg_and_update('h420, {$random} & STRIDE_MASK); + write_reg_and_update('h424, {$random} & STRIDE_MASK); + + check_all_registers("Transfer setup 2"); + + /* Start transfer */ + write_reg_and_update('h400, 'h01); + write_reg_and_update('h408, 'h01); + + check_all_registers("Transfer submitted"); + + @(posedge clk) request_ready <= 1'b1; + + /* Interrupt pending */ + set_reset_reg_value('h84, 'h01); + set_reset_reg_value('h88, 'h01); + + /* Transfer ID */ + set_reset_reg_value('h404, 'h01); + + /* Tansfer pending */ + set_reset_reg_value('h408, 'h00); + + check_all_registers("Transfer accepted"); + + @(posedge clk) response_eot <= 1'b1; + @(posedge clk) response_eot <= 1'b0; + + /* Interrupt registers */ + set_reset_reg_value('h84, 'h03); + set_reset_reg_value('h88, 'h03); + + /* Transfer done */ + set_reset_reg_value('h428, 'h01); + + /* Active ID */ + set_reset_reg_value('h42c, 'h01); + + check_all_registers("Transfer completed"); + + /* Clear interrupts */ + write_reg('h84, 'h01); + set_reset_reg_value('h84, 'h02); + set_reset_reg_value('h88, 'h02); + + check_all_registers("Clear interrupts 1"); + + write_reg('h84, 'h02); + set_reset_reg_value('h84, 'h00); + set_reset_reg_value('h88, 'h00); + + check_all_registers("Clear interrupts 2"); + + /* Check that reset works for all registers */ + do_trigger_reset(); + initialize_expected_reg_mem(); + check_all_registers("Reset 1"); + invert_all_registers(); + do_trigger_reset(); + check_all_registers("Reset 2"); + end + + axi_dmac_regmap #( + .ID(0), + .BYTES_PER_BEAT_WIDTH_DEST(BYTES_PER_BEAT), + .BYTES_PER_BEAT_WIDTH_SRC(BYTES_PER_BEAT), + .DMA_AXI_ADDR_WIDTH(DMA_AXI_ADDR_WIDTH), + .DMA_LENGTH_WIDTH(DMA_LENGTH_WIDTH), + .DMA_LENGTH_ALIGN(DMA_LENGTH_ALIGN), + .DMA_CYCLIC(1), + .HAS_DEST_ADDR(1), + .HAS_SRC_ADDR(1), + .DMA_2D_TRANSFER(1) + ) i_axi ( + .s_axi_aclk(s_axi_aclk), + .s_axi_aresetn(s_axi_aresetn), + .s_axi_awvalid(s_axi_awvalid), + .s_axi_awaddr(s_axi_awaddr), + .s_axi_awready(s_axi_awready), + .s_axi_awprot(s_axi_awprot), + .s_axi_wvalid(s_axi_wvalid), + .s_axi_wdata(s_axi_wdata), + .s_axi_wstrb(s_axi_wstrb), + .s_axi_wready(s_axi_wready), + .s_axi_bvalid(s_axi_bvalid), + .s_axi_bresp(s_axi_bresp), + .s_axi_bready(s_axi_bready), + .s_axi_arvalid(s_axi_arvalid), + .s_axi_araddr(s_axi_araddr), + .s_axi_arready(s_axi_arready), + .s_axi_arprot(s_axi_arprot), + .s_axi_rvalid(s_axi_rvalid), + .s_axi_rready(s_axi_rready), + .s_axi_rresp(s_axi_rresp), + .s_axi_rdata(s_axi_rdata), + + .request_valid(request_valid), + .request_ready(request_ready), + .request_dest_address(request_dest_address), + .request_src_address(request_src_address), + .request_x_length(request_x_length), + .request_y_length(request_y_length), + .request_dest_stride(request_dest_stride), + .request_src_stride(request_src_stride), + .request_last(request_last), + + .response_eot(response_eot), + + .dbg_src_addr(VAL_DBG_SRC_ADDR), + .dbg_dest_addr(VAL_DBG_DEST_ADDR), + .dbg_status(VAL_DBG_STATUS), + .dbg_ids0(VAL_DBG_IDS0), + .dbg_ids1(VAL_DBG_IDS1) + ); + +endmodule diff --git a/src/adi/hdl/library/axi_dmac/tb/reset_manager_tb b/src/adi/hdl/library/axi_dmac/tb/reset_manager_tb new file mode 100755 index 00000000..cd656cdb --- /dev/null +++ b/src/adi/hdl/library/axi_dmac/tb/reset_manager_tb @@ -0,0 +1,8 @@ +#!/bin/bash + +SOURCE="$0.v" +SOURCE+=" ../axi_dmac_reset_manager.v" +SOURCE+=" ../../util_cdc/sync_bits.v" + +cd `dirname $0` +source run_tb.sh diff --git a/src/adi/hdl/library/axi_dmac/tb/reset_manager_tb.v b/src/adi/hdl/library/axi_dmac/tb/reset_manager_tb.v new file mode 100644 index 00000000..e113af59 --- /dev/null +++ b/src/adi/hdl/library/axi_dmac/tb/reset_manager_tb.v @@ -0,0 +1,121 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright 2014 - 2017 (c) Analog Devices, Inc. All rights reserved. +// +// In this HDL repository, there are many different and unique modules, consisting +// of various HDL (Verilog or VHDL) components. The individual modules are +// developed independently, and may be accompanied by separate and unique license +// terms. +// +// The user should read each of these license terms, and understand the +// freedoms and responsibilities that he or she has by using this source/core. +// +// This core 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. +// +// Redistribution and use of source or resulting binaries, with or without modification +// of this file, are permitted under one of the following two license terms: +// +// 1. The GNU General Public License version 2 as published by the +// Free Software Foundation, which can be found in the top level directory +// of this repository (LICENSE_GPL2), and also online at: +// +// +// OR +// +// 2. An ADI specific BSD license, which can be found in the top level directory +// of this repository (LICENSE_ADIBSD), and also on-line at: +// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD +// This will allow to generate bit files and not release the source code, +// as long as it attaches to an ADI device. +// +// *************************************************************************** +// *************************************************************************** + +`timescale 1ns/100ps + +module dmac_reset_manager_tb; + parameter VCD_FILE = {`__FILE__,"cd"}; + + `define TIMEOUT 1000000 + `include "tb_base.v" + + + reg clk_a = 1'b0; + reg clk_b = 1'b0; + reg clk_c = 1'b0; + + reg [5:0] resetn_shift = 'h0; + + reg [10:0] counter = 'h00; + + reg ctrl_enable = 1'b0; + reg ctrl_pause = 1'b0; + + always #10 clk_a <= ~clk_a; + always #3 clk_b <= ~clk_b; + always #7 clk_c <= ~clk_c; + + always @(posedge clk_a) begin + counter <= counter + 1'b1; + if (counter == 'h60 || counter == 'h150 || counter == 'h185) begin + ctrl_enable <= 1'b1; + end else if (counter == 'h100 || counter == 'h110 || counter == 'h180) begin + ctrl_enable <= 1'b0; + end + + if (counter == 'h160) begin + ctrl_pause = 1'b1; + end else if (counter == 'h190) begin + ctrl_pause = 1'b0; + end + end + + reg [15:0] req_enabled_shift; + wire req_enable; + wire req_enabled = req_enabled_shift[15]; + + reg [15:0] dest_enabled_shift; + wire dest_enable; + wire dest_enabled = dest_enabled_shift[15]; + + reg [15:0] src_enabled_shift; + wire src_enable; + wire src_enabled = src_enabled_shift[15]; + + + always @(posedge clk_a) begin + req_enabled_shift <= {req_enabled_shift[14:0],req_enable}; + end + + always @(posedge clk_b) begin + dest_enabled_shift <= {dest_enabled_shift[14:0],dest_enable}; + end + + always @(posedge clk_c) begin + src_enabled_shift <= {src_enabled_shift[14:0],src_enable}; + end + + axi_dmac_reset_manager i_reset_manager ( + .clk(clk_a), + .resetn(resetn), + + .ctrl_pause(ctrl_pause), + .ctrl_enable(ctrl_enable), + + .req_enable(req_enable), + .req_enabled(req_enabled), + + .dest_clk(clk_b), + .dest_ext_resetn(1'b0), + .dest_enable(dest_enable), + .dest_enabled(dest_enabled), + + .src_clk(clk_c), + .src_ext_resetn(1'b0), + .src_enable(src_enable), + .src_enabled(src_enabled) + ); + +endmodule diff --git a/src/adi/hdl/library/axi_dmac/tb/run_tb.sh b/src/adi/hdl/library/axi_dmac/tb/run_tb.sh new file mode 100644 index 00000000..ddf9cc40 --- /dev/null +++ b/src/adi/hdl/library/axi_dmac/tb/run_tb.sh @@ -0,0 +1,24 @@ +NAME=`basename $0` + +case "$SIMULATOR" in + modelsim) + # ModelSim flow + vlib work + vlog ${SOURCE} || exit 1 + vsim "dmac_"${NAME} -do "add log /* -r; run -a" -gui || exit 1 + ;; + xsim) + # xsim flow + xvlog -log ${NAME}_xvlog.log --sourcelibdir . ${SOURCE} + xelab -log ${NAME}_xelab.log -debug all dmac_${NAME} + xsim work.dmac_${NAME} -R + ;; + *) + #Icarus flow is the default + mkdir -p run + mkdir -p vcd + iverilog -o run/run_${NAME} -I.. ${SOURCE} $1 || exit 1 + cd vcd + ../run/run_${NAME} + ;; +esac diff --git a/src/adi/hdl/library/axi_dmac/tb/tb_base.v b/src/adi/hdl/library/axi_dmac/tb/tb_base.v new file mode 100644 index 00000000..e6dd7ad9 --- /dev/null +++ b/src/adi/hdl/library/axi_dmac/tb/tb_base.v @@ -0,0 +1,76 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright 2014 - 2017 (c) Analog Devices, Inc. All rights reserved. +// +// In this HDL repository, there are many different and unique modules, consisting +// of various HDL (Verilog or VHDL) components. The individual modules are +// developed independently, and may be accompanied by separate and unique license +// terms. +// +// The user should read each of these license terms, and understand the +// freedoms and responsibilities that he or she has by using this source/core. +// +// This core 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. +// +// Redistribution and use of source or resulting binaries, with or without modification +// of this file, are permitted under one of the following two license terms: +// +// 1. The GNU General Public License version 2 as published by the +// Free Software Foundation, which can be found in the top level directory +// of this repository (LICENSE_GPL2), and also online at: +// +// +// OR +// +// 2. An ADI specific BSD license, which can be found in the top level directory +// of this repository (LICENSE_ADIBSD), and also on-line at: +// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD +// This will allow to generate bit files and not release the source code, +// as long as it attaches to an ADI device. +// +// *************************************************************************** +// *************************************************************************** + + reg clk = 1'b0; + reg [3:0] reset_shift = 4'b1111; + reg trigger_reset = 1'b0; + wire reset; + wire resetn = ~reset; + + reg failed = 1'b0; + + initial + begin + $dumpfile (VCD_FILE); + $dumpvars; +`ifdef TIMEOUT + #`TIMEOUT +`else + #100000 +`endif + if (failed == 1'b0) + $display("SUCCESS"); + else + $display("FAILED"); + $finish; + end + + always @(*) #10 clk <= ~clk; + always @(posedge clk) begin + if (trigger_reset == 1'b1) begin + reset_shift <= 3'b111; + end else begin + reset_shift <= {reset_shift[2:0],1'b0}; + end + end + + assign reset = reset_shift[3]; + + task do_trigger_reset; + begin + @(posedge clk) trigger_reset <= 1'b1; + @(posedge clk) trigger_reset <= 1'b0; + end + endtask diff --git a/src/adi/hdl/library/axi_hdmi_tx/Makefile b/src/adi/hdl/library/axi_hdmi_tx/Makefile new file mode 100644 index 00000000..609b75bd --- /dev/null +++ b/src/adi/hdl/library/axi_hdmi_tx/Makefile @@ -0,0 +1,41 @@ +#################################################################################### +## Copyright 2018(c) Analog Devices, Inc. +## Auto-generated, do not modify! +#################################################################################### + +LIBRARY_NAME := axi_hdmi_tx + +GENERIC_DEPS += ../common/ad_csc_1.v +GENERIC_DEPS += ../common/ad_csc_1_add.v +GENERIC_DEPS += ../common/ad_csc_1_mul.v +GENERIC_DEPS += ../common/ad_csc_RGB2CrYCb.v +GENERIC_DEPS += ../common/ad_mem.v +GENERIC_DEPS += ../common/ad_rst.v +GENERIC_DEPS += ../common/ad_ss_444to422.v +GENERIC_DEPS += ../common/up_axi.v +GENERIC_DEPS += ../common/up_clock_mon.v +GENERIC_DEPS += ../common/up_hdmi_tx.v +GENERIC_DEPS += ../common/up_xfer_cntrl.v +GENERIC_DEPS += ../common/up_xfer_status.v +GENERIC_DEPS += axi_hdmi_tx.v +GENERIC_DEPS += axi_hdmi_tx_core.v +GENERIC_DEPS += axi_hdmi_tx_es.v +GENERIC_DEPS += axi_hdmi_tx_vdma.v + +XILINX_DEPS += ../xilinx/common/ad_mul.v +XILINX_DEPS += ../xilinx/common/ad_rst_constr.xdc +XILINX_DEPS += ../xilinx/common/up_clock_mon_constr.xdc +XILINX_DEPS += ../xilinx/common/up_xfer_cntrl_constr.xdc +XILINX_DEPS += ../xilinx/common/up_xfer_status_constr.xdc +XILINX_DEPS += axi_hdmi_tx_constr.xdc +XILINX_DEPS += axi_hdmi_tx_ip.tcl + +ALTERA_DEPS += ../altera/common/ad_mul.v +ALTERA_DEPS += ../altera/common/up_clock_mon_constr.sdc +ALTERA_DEPS += ../altera/common/up_rst_constr.sdc +ALTERA_DEPS += ../altera/common/up_xfer_cntrl_constr.sdc +ALTERA_DEPS += ../altera/common/up_xfer_status_constr.sdc +ALTERA_DEPS += axi_hdmi_tx_constr.sdc +ALTERA_DEPS += axi_hdmi_tx_hw.tcl + +include ../scripts/library.mk diff --git a/src/adi/hdl/library/axi_hdmi_tx/axi_hdmi_tx.v b/src/adi/hdl/library/axi_hdmi_tx/axi_hdmi_tx.v new file mode 100644 index 00000000..6eb75699 --- /dev/null +++ b/src/adi/hdl/library/axi_hdmi_tx/axi_hdmi_tx.v @@ -0,0 +1,342 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright 2014 - 2017 (c) Analog Devices, Inc. All rights reserved. +// +// In this HDL repository, there are many different and unique modules, consisting +// of various HDL (Verilog or VHDL) components. The individual modules are +// developed independently, and may be accompanied by separate and unique license +// terms. +// +// The user should read each of these license terms, and understand the +// freedoms and responsibilities that he or she has by using this source/core. +// +// This core 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. +// +// Redistribution and use of source or resulting binaries, with or without modification +// of this file, are permitted under one of the following two license terms: +// +// 1. The GNU General Public License version 2 as published by the +// Free Software Foundation, which can be found in the top level directory +// of this repository (LICENSE_GPL2), and also online at: +// +// +// OR +// +// 2. An ADI specific BSD license, which can be found in the top level directory +// of this repository (LICENSE_ADIBSD), and also on-line at: +// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD +// This will allow to generate bit files and not release the source code, +// as long as it attaches to an ADI device. +// +// *************************************************************************** +// *************************************************************************** + +`timescale 1ns/100ps + +module axi_hdmi_tx #( + + parameter ID = 0, + parameter CR_CB_N = 0, + parameter DEVICE_TYPE = 0, + parameter INTERFACE = "16_BIT", + parameter OUT_CLK_POLARITY = 0) ( + + // hdmi interface + + input hdmi_clk, + output hdmi_out_clk, + + // 16-bit interface + + output hdmi_16_hsync, + output hdmi_16_vsync, + output hdmi_16_data_e, + output [15:0] hdmi_16_data, + output [15:0] hdmi_16_es_data, + + // 24-bit interface + + output hdmi_24_hsync, + output hdmi_24_vsync, + output hdmi_24_data_e, + output [23:0] hdmi_24_data, + + // 36-bit interface + + output hdmi_36_hsync, + output hdmi_36_vsync, + output hdmi_36_data_e, + output [35:0] hdmi_36_data, + + // vdma interface + + input vdma_clk, + input vdma_end_of_frame, + input vdma_valid, + input [63:0] vdma_data, + output vdma_ready, + + // axi interface + + input s_axi_aclk, + input s_axi_aresetn, + input s_axi_awvalid, + input [15:0] s_axi_awaddr, + input [ 2:0] s_axi_awprot, + output s_axi_awready, + input s_axi_wvalid, + input [31:0] s_axi_wdata, + input [ 3:0] s_axi_wstrb, + output s_axi_wready, + output s_axi_bvalid, + output [ 1:0] s_axi_bresp, + input s_axi_bready, + input s_axi_arvalid, + input [15:0] s_axi_araddr, + input [ 2:0] s_axi_arprot, + output s_axi_arready, + output s_axi_rvalid, + output [ 1:0] s_axi_rresp, + output [31:0] s_axi_rdata, + input s_axi_rready); + + /* 0 = Launch on rising edge, 1 = Launch on falling edge */ + + localparam EMBEDDED_SYNC = (INTERFACE == "16_BIT_EMBEDDED_SYNC") ? 1 : 0; + localparam XILINX_7SERIES = 0; + localparam XILINX_ULTRASCALE = 1; + localparam ALTERA_5SERIES = 16; + + // reset and clocks + + wire up_rstn; + wire up_clk; + wire hdmi_rst; + wire vdma_rst; + + // internal signals + + wire up_wreq_s; + wire [13:0] up_waddr_s; + wire [31:0] up_wdata_s; + wire up_wack_s; + wire up_rreq_s; + wire [13:0] up_raddr_s; + wire [31:0] up_rdata_s; + wire up_rack_s; + wire hdmi_csc_bypass_s; + wire hdmi_ss_bypass_s; + wire [ 1:0] hdmi_srcsel_s; + wire [23:0] hdmi_const_rgb_s; + wire [15:0] hdmi_hl_active_s; + wire [15:0] hdmi_hl_width_s; + wire [15:0] hdmi_hs_width_s; + wire [15:0] hdmi_he_max_s; + wire [15:0] hdmi_he_min_s; + wire [15:0] hdmi_vf_active_s; + wire [15:0] hdmi_vf_width_s; + wire [15:0] hdmi_vs_width_s; + wire [15:0] hdmi_ve_max_s; + wire [15:0] hdmi_ve_min_s; + wire [23:0] hdmi_clip_max_s; + wire [23:0] hdmi_clip_min_s; + wire hdmi_fs_toggle_s; + wire [ 8:0] hdmi_raddr_g_s; + wire hdmi_tpm_oos_s; + wire hdmi_status_s; + wire vdma_wr_s; + wire [ 8:0] vdma_waddr_s; + wire [47:0] vdma_wdata_s; + wire vdma_fs_ret_toggle_s; + wire [ 8:0] vdma_fs_waddr_s; + wire vdma_ovf_s; + wire vdma_unf_s; + wire vdma_tpm_oos_s; + + // signal name changes + + assign up_rstn = s_axi_aresetn; + assign up_clk = s_axi_aclk; + + // axi interface + + up_axi i_up_axi ( + .up_rstn (up_rstn), + .up_clk (up_clk), + .up_axi_awvalid (s_axi_awvalid), + .up_axi_awaddr (s_axi_awaddr), + .up_axi_awready (s_axi_awready), + .up_axi_wvalid (s_axi_wvalid), + .up_axi_wdata (s_axi_wdata), + .up_axi_wstrb (s_axi_wstrb), + .up_axi_wready (s_axi_wready), + .up_axi_bvalid (s_axi_bvalid), + .up_axi_bresp (s_axi_bresp), + .up_axi_bready (s_axi_bready), + .up_axi_arvalid (s_axi_arvalid), + .up_axi_araddr (s_axi_araddr), + .up_axi_arready (s_axi_arready), + .up_axi_rvalid (s_axi_rvalid), + .up_axi_rresp (s_axi_rresp), + .up_axi_rdata (s_axi_rdata), + .up_axi_rready (s_axi_rready), + .up_wreq (up_wreq_s), + .up_waddr (up_waddr_s), + .up_wdata (up_wdata_s), + .up_wack (up_wack_s), + .up_rreq (up_rreq_s), + .up_raddr (up_raddr_s), + .up_rdata (up_rdata_s), + .up_rack (up_rack_s)); + + // processor interface + + up_hdmi_tx i_up ( + .hdmi_clk (hdmi_clk), + .hdmi_rst (hdmi_rst), + .hdmi_csc_bypass (hdmi_csc_bypass_s), + .hdmi_ss_bypass (hdmi_ss_bypass_s), + .hdmi_srcsel (hdmi_srcsel_s), + .hdmi_const_rgb (hdmi_const_rgb_s), + .hdmi_hl_active (hdmi_hl_active_s), + .hdmi_hl_width (hdmi_hl_width_s), + .hdmi_hs_width (hdmi_hs_width_s), + .hdmi_he_max (hdmi_he_max_s), + .hdmi_he_min (hdmi_he_min_s), + .hdmi_vf_active (hdmi_vf_active_s), + .hdmi_vf_width (hdmi_vf_width_s), + .hdmi_vs_width (hdmi_vs_width_s), + .hdmi_ve_max (hdmi_ve_max_s), + .hdmi_ve_min (hdmi_ve_min_s), + .hdmi_clip_max (hdmi_clip_max_s), + .hdmi_clip_min (hdmi_clip_min_s), + .hdmi_status (hdmi_status_s), + .hdmi_tpm_oos (hdmi_tpm_oos_s), + .hdmi_clk_ratio (32'd1), + .vdma_clk (vdma_clk), + .vdma_rst (vdma_rst), + .vdma_ovf (vdma_ovf_s), + .vdma_unf (vdma_unf_s), + .vdma_tpm_oos (vdma_tpm_oos_s), + .up_rstn (up_rstn), + .up_clk (up_clk), + .up_wreq (up_wreq_s), + .up_waddr (up_waddr_s), + .up_wdata (up_wdata_s), + .up_wack (up_wack_s), + .up_rreq (up_rreq_s), + .up_raddr (up_raddr_s), + .up_rdata (up_rdata_s), + .up_rack (up_rack_s)); + + // vdma interface + + axi_hdmi_tx_vdma i_vdma ( + .hdmi_fs_toggle (hdmi_fs_toggle_s), + .hdmi_raddr_g (hdmi_raddr_g_s), + .vdma_clk (vdma_clk), + .vdma_rst (vdma_rst), + .vdma_valid (vdma_valid), + .vdma_data (vdma_data), + .vdma_ready (vdma_ready), + .vdma_end_of_frame (vdma_end_of_frame), + .vdma_wr (vdma_wr_s), + .vdma_waddr (vdma_waddr_s), + .vdma_wdata (vdma_wdata_s), + .vdma_fs_ret_toggle (vdma_fs_ret_toggle_s), + .vdma_fs_waddr (vdma_fs_waddr_s), + .vdma_tpm_oos (vdma_tpm_oos_s), + .vdma_ovf (vdma_ovf_s), + .vdma_unf (vdma_unf_s)); + + // hdmi interface + + axi_hdmi_tx_core #( + .CR_CB_N(CR_CB_N), + .EMBEDDED_SYNC(EMBEDDED_SYNC)) + i_tx_core ( + .hdmi_clk (hdmi_clk), + .hdmi_rst (hdmi_rst), + .hdmi_16_hsync (hdmi_16_hsync), + .hdmi_16_vsync (hdmi_16_vsync), + .hdmi_16_data_e (hdmi_16_data_e), + .hdmi_16_data (hdmi_16_data), + .hdmi_16_es_data (hdmi_16_es_data), + .hdmi_24_hsync (hdmi_24_hsync), + .hdmi_24_vsync (hdmi_24_vsync), + .hdmi_24_data_e (hdmi_24_data_e), + .hdmi_24_data (hdmi_24_data), + .hdmi_36_hsync (hdmi_36_hsync), + .hdmi_36_vsync (hdmi_36_vsync), + .hdmi_36_data_e (hdmi_36_data_e), + .hdmi_36_data (hdmi_36_data), + .hdmi_fs_toggle (hdmi_fs_toggle_s), + .hdmi_raddr_g (hdmi_raddr_g_s), + .hdmi_tpm_oos (hdmi_tpm_oos_s), + .hdmi_status (hdmi_status_s), + .vdma_clk (vdma_clk), + .vdma_wr (vdma_wr_s), + .vdma_waddr (vdma_waddr_s), + .vdma_wdata (vdma_wdata_s), + .vdma_fs_ret_toggle (vdma_fs_ret_toggle_s), + .vdma_fs_waddr (vdma_fs_waddr_s), + .hdmi_csc_bypass (hdmi_csc_bypass_s), + .hdmi_ss_bypass (hdmi_ss_bypass_s), + .hdmi_srcsel (hdmi_srcsel_s), + .hdmi_const_rgb (hdmi_const_rgb_s), + .hdmi_hl_active (hdmi_hl_active_s), + .hdmi_hl_width (hdmi_hl_width_s), + .hdmi_hs_width (hdmi_hs_width_s), + .hdmi_he_max (hdmi_he_max_s), + .hdmi_he_min (hdmi_he_min_s), + .hdmi_vf_active (hdmi_vf_active_s), + .hdmi_vf_width (hdmi_vf_width_s), + .hdmi_vs_width (hdmi_vs_width_s), + .hdmi_ve_max (hdmi_ve_max_s), + .hdmi_ve_min (hdmi_ve_min_s), + .hdmi_clip_max (hdmi_clip_max_s), + .hdmi_clip_min (hdmi_clip_min_s)); + + // hdmi output clock + + generate + if (DEVICE_TYPE == XILINX_ULTRASCALE) begin + ODDRE1 #(.SRVAL(1'b0)) i_clk_oddr ( + .SR (1'b0), + .D1 (~OUT_CLK_POLARITY), + .D2 (OUT_CLK_POLARITY), + .C (hdmi_clk), + .Q (hdmi_out_clk)); + end + if (DEVICE_TYPE == ALTERA_5SERIES) begin + altddio_out #(.WIDTH(1)) i_clk_oddr ( + .aclr (1'b0), + .aset (1'b0), + .sclr (1'b0), + .sset (1'b0), + .oe (1'b1), + .outclocken (1'b1), + .datain_h (~OUT_CLK_POLARITY), + .datain_l (OUT_CLK_POLARITY), + .outclock (hdmi_clk), + .oe_out (), + .dataout (hdmi_out_clk)); + end + if (DEVICE_TYPE == XILINX_7SERIES) begin + ODDR #(.INIT(1'b0)) i_clk_oddr ( + .R (1'b0), + .S (1'b0), + .CE (1'b1), + .D1 (~OUT_CLK_POLARITY), + .D2 (OUT_CLK_POLARITY), + .C (hdmi_clk), + .Q (hdmi_out_clk)); + end + endgenerate + +endmodule + +// *************************************************************************** +// *************************************************************************** diff --git a/src/adi/hdl/library/axi_hdmi_tx/axi_hdmi_tx_constr.sdc b/src/adi/hdl/library/axi_hdmi_tx/axi_hdmi_tx_constr.sdc new file mode 100644 index 00000000..7f715c9a --- /dev/null +++ b/src/adi/hdl/library/axi_hdmi_tx/axi_hdmi_tx_constr.sdc @@ -0,0 +1,10 @@ + +set_false_path -from [get_registers *hdmi_fs_toggle*] -to [get_registers *vdma_fs_toggle_m1] +set_false_path -from [get_registers *hdmi_raddr_g*] -to [get_registers *vdma_raddr_g_m1*] +set_false_path -from [get_registers *vdma_fs_ret_toggle*] -to [get_registers *hdmi_fs_ret_toggle_m1] +set_false_path -from [get_registers *vdma_fs_waddr*] -to [get_registers *hdmi_fs_waddr*] + +set_false_path -from [get_registers *up_xfer_status:i_vdma_xfer_status|up_xfer_toggle*] -to [get_registers *up_xfer_status:i_vdma_xfer_status|d_xfer_state_m1*] +set_false_path -from [get_registers *up_xfer_status:i_vdma_xfer_status|d_xfer_toggle*] -to [get_registers *up_xfer_status:i_vdma_xfer_status|up_xfer_toggle_m1*] +set_false_path -from [get_registers *up_xfer_status:i_vdma_xfer_status|d_xfer_data*] -to [get_registers *up_xfer_status:i_vdma_xfer_status|up_data_status*] +set_false_path -from [get_registers *up_core_preset*] -to [get_registers *ad_rst_sync_m1] diff --git a/src/adi/hdl/library/axi_hdmi_tx/axi_hdmi_tx_constr.xdc b/src/adi/hdl/library/axi_hdmi_tx/axi_hdmi_tx_constr.xdc new file mode 100644 index 00000000..d7ab709a --- /dev/null +++ b/src/adi/hdl/library/axi_hdmi_tx/axi_hdmi_tx_constr.xdc @@ -0,0 +1,10 @@ + +set_property ASYNC_REG TRUE [get_cells -hier -filter {name =~ *vdma_fs_toggle*}] +set_property ASYNC_REG TRUE [get_cells -hier -filter {name =~ *vdma_raddr_g*}] +set_property ASYNC_REG TRUE [get_cells -hier -filter {name =~ *hdmi_fs_ret_toggle*}] + +set_false_path -from [get_cells -hier -filter {name =~ *hdmi_fs_toggle_reg && IS_SEQUENTIAL}] -to [get_cells -hier -filter {name =~ *vdma_fs_toggle_m1_reg && IS_SEQUENTIAL}] +set_false_path -from [get_cells -hier -filter {name =~ *hdmi_raddr_g* && IS_SEQUENTIAL}] -to [get_cells -hier -filter {name =~ *vdma_raddr_g_m1* && IS_SEQUENTIAL}] +set_false_path -from [get_cells -hier -filter {name =~ *vdma_fs_ret_toggle_reg && IS_SEQUENTIAL}] -to [get_cells -hier -filter {name =~ *hdmi_fs_ret_toggle_m1_reg && IS_SEQUENTIAL}] +set_false_path -from [get_cells -hier -filter {name =~ *vdma_fs_waddr* && IS_SEQUENTIAL}] -to [get_cells -hier -filter {name =~ *hdmi_fs_waddr* && IS_SEQUENTIAL}] + diff --git a/src/adi/hdl/library/axi_hdmi_tx/axi_hdmi_tx_core.v b/src/adi/hdl/library/axi_hdmi_tx/axi_hdmi_tx_core.v new file mode 100644 index 00000000..8191cf6b --- /dev/null +++ b/src/adi/hdl/library/axi_hdmi_tx/axi_hdmi_tx_core.v @@ -0,0 +1,572 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright 2014 - 2017 (c) Analog Devices, Inc. All rights reserved. +// +// In this HDL repository, there are many different and unique modules, consisting +// of various HDL (Verilog or VHDL) components. The individual modules are +// developed independently, and may be accompanied by separate and unique license +// terms. +// +// The user should read each of these license terms, and understand the +// freedoms and responsibilities that he or she has by using this source/core. +// +// This core 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. +// +// Redistribution and use of source or resulting binaries, with or without modification +// of this file, are permitted under one of the following two license terms: +// +// 1. The GNU General Public License version 2 as published by the +// Free Software Foundation, which can be found in the top level directory +// of this repository (LICENSE_GPL2), and also online at: +// +// +// OR +// +// 2. An ADI specific BSD license, which can be found in the top level directory +// of this repository (LICENSE_ADIBSD), and also on-line at: +// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD +// This will allow to generate bit files and not release the source code, +// as long as it attaches to an ADI device. +// +// *************************************************************************** +// *************************************************************************** +// Transmit HDMI, video dma data in, hdmi separate syncs data out. + +`timescale 1ns/100ps + +module axi_hdmi_tx_core #( + + parameter CR_CB_N = 0, + parameter EMBEDDED_SYNC = 0) ( + + // hdmi interface + + input hdmi_clk, + input hdmi_rst, + + // 16-bit interface + + output reg hdmi_16_hsync, + output reg hdmi_16_vsync, + output reg hdmi_16_data_e, + output reg [15:0] hdmi_16_data, + output reg [15:0] hdmi_16_es_data, + + // 24-bit interface + + output reg hdmi_24_hsync, + output reg hdmi_24_vsync, + output reg hdmi_24_data_e, + output reg [23:0] hdmi_24_data, + + // 36-bit interface + + output reg hdmi_36_hsync, + output reg hdmi_36_vsync, + output reg hdmi_36_data_e, + output reg [35:0] hdmi_36_data, + + // control signals + + output reg hdmi_fs_toggle, + output reg [ 8:0] hdmi_raddr_g, + output reg hdmi_tpm_oos, + output reg hdmi_status, + + // vdma interface + + input vdma_clk, + input vdma_wr, + input [ 8:0] vdma_waddr, + input [47:0] vdma_wdata, + input vdma_fs_ret_toggle, + input [ 8:0] vdma_fs_waddr, + + // processor interface + + input hdmi_csc_bypass, + input hdmi_ss_bypass, + input [ 1:0] hdmi_srcsel, + input [23:0] hdmi_const_rgb, + input [15:0] hdmi_hl_active, + input [15:0] hdmi_hl_width, + input [15:0] hdmi_hs_width, + input [15:0] hdmi_he_max, + input [15:0] hdmi_he_min, + input [15:0] hdmi_vf_active, + input [15:0] hdmi_vf_width, + input [15:0] hdmi_vs_width, + input [15:0] hdmi_ve_max, + input [15:0] hdmi_ve_min, + input [23:0] hdmi_clip_max, + input [23:0] hdmi_clip_min); + + + // internal registers + + reg hdmi_enable = 'd0; + reg [15:0] hdmi_hs_count = 'd0; + reg [15:0] hdmi_vs_count = 'd0; + reg hdmi_fs = 'd0; + reg hdmi_fs_ret_toggle_m1 = 'd0; + reg hdmi_fs_ret_toggle_m2 = 'd0; + reg hdmi_fs_ret_toggle_m3 = 'd0; + reg hdmi_fs_ret = 'd0; + reg [ 8:0] hdmi_fs_waddr = 'd0; + reg hdmi_hs = 'd0; + reg hdmi_vs = 'd0; + reg hdmi_hs_de = 'd0; + reg hdmi_vs_de = 'd0; + reg [ 9:0] hdmi_raddr = 'd0; + reg hdmi_hs_d = 'd0; + reg hdmi_vs_d = 'd0; + reg hdmi_hs_de_d = 'd0; + reg hdmi_vs_de_d = 'd0; + reg hdmi_de_d = 'd0; + reg hdmi_data_sel_d = 'd0; + reg hdmi_hs_2d = 'd0; + reg hdmi_vs_2d = 'd0; + reg hdmi_hs_de_2d = 'd0; + reg hdmi_vs_de_2d = 'd0; + reg hdmi_de_2d = 'd0; + reg hdmi_data_sel_2d = 'd0; + reg [47:0] hdmi_data_2d = 'd0; + reg [23:0] hdmi_tpm_data = 'd0; + reg hdmi_hsync = 'd0; + reg hdmi_vsync = 'd0; + reg hdmi_hsync_data_e = 'd0; + reg hdmi_vsync_data_e = 'd0; + reg hdmi_data_e = 'd0; + reg [23:0] hdmi_data = 'd0; + reg hdmi_24_csc_hsync = 'd0; + reg hdmi_24_csc_vsync = 'd0; + reg hdmi_24_csc_hsync_data_e = 'd0; + reg hdmi_24_csc_vsync_data_e = 'd0; + reg hdmi_24_csc_data_e = 'd0; + reg [23:0] hdmi_24_csc_data = 'd0; + reg hdmi_16_hsync_d = 'd0; + reg hdmi_16_vsync_d = 'd0; + reg hdmi_16_hsync_data_e_d = 'd0; + reg hdmi_16_vsync_data_e_d = 'd0; + reg hdmi_16_data_e_d = 'd0; + reg [15:0] hdmi_16_data_d = 'd0; + reg hdmi_es_hs_de = 'd0; + reg hdmi_es_vs_de = 'd0; + reg [15:0] hdmi_es_data = 'd0; + reg [23:0] hdmi_clip_data = 'd0; + reg hdmi_clip_hs_de_d = 'd0; + reg hdmi_clip_vs_de_d = 'd0; + reg hdmi_clip_hs_d = 'd0; + reg hdmi_clip_vs_d = 'd0; + reg hdmi_clip_de_d = 'd0; + + // internal wires + + wire [15:0] hdmi_hl_width_s; + wire [15:0] hdmi_vf_width_s; + wire [15:0] hdmi_he_width_s; + wire [15:0] hdmi_ve_width_s; + wire hdmi_fs_ret_s; + wire hdmi_de_s; + wire [47:0] hdmi_rdata_s; + wire [23:0] hdmi_data_2d_s; + wire hdmi_tpm_mismatch_s; + wire [23:0] hdmi_tpg_data_s; + wire hdmi_csc_hsync_s; + wire hdmi_csc_vsync_s; + wire hdmi_csc_hsync_data_e_s; + wire hdmi_csc_vsync_data_e_s; + wire hdmi_csc_data_e_s; + wire [23:0] hdmi_csc_data_s; + wire hdmi_ss_hsync_s; + wire hdmi_ss_vsync_s; + wire hdmi_ss_hsync_data_e_s; + wire hdmi_ss_vsync_data_e_s; + wire hdmi_ss_data_e_s; + wire [15:0] hdmi_ss_data_s; + wire [15:0] hdmi_es_data_s; + + // binary to grey conversion + + function [8:0] b2g; + input [8:0] b; + reg [8:0] g; + begin + g[8] = b[8]; + g[7] = b[8] ^ b[7]; + g[6] = b[7] ^ b[6]; + g[5] = b[6] ^ b[5]; + g[4] = b[5] ^ b[4]; + g[3] = b[4] ^ b[3]; + g[2] = b[3] ^ b[2]; + g[1] = b[2] ^ b[1]; + g[0] = b[1] ^ b[0]; + b2g = g; + end + endfunction + + // status and enable + + always @(posedge hdmi_clk) begin + if (hdmi_rst == 1'b1) begin + hdmi_status <= 1'b0; + hdmi_enable <= 1'b0; + end else begin + hdmi_status <= 1'b1; + hdmi_enable <= hdmi_srcsel[1] | hdmi_srcsel[0]; + end + end + + // calculate useful limits + + assign hdmi_hl_width_s = hdmi_hl_width - 1'b1; + assign hdmi_vf_width_s = hdmi_vf_width - 1'b1; + assign hdmi_he_width_s = hdmi_hl_width - (hdmi_hl_active + 1'b1); + assign hdmi_ve_width_s = hdmi_vf_width - (hdmi_vf_active + 1'b1); + + // hdmi counters + + always @(posedge hdmi_clk) begin + if (hdmi_hs_count >= hdmi_hl_width_s) begin + hdmi_hs_count <= 0; + end else begin + hdmi_hs_count <= hdmi_hs_count + 1'b1; + end + if (hdmi_hs_count >= hdmi_hl_width_s) begin + if (hdmi_vs_count >= hdmi_vf_width_s) begin + hdmi_vs_count <= 0; + end else begin + hdmi_vs_count <= hdmi_vs_count + 1'b1; + end + end + end + + // hdmi start of frame + + always @(posedge hdmi_clk) begin + if (hdmi_rst == 1'b1) begin + hdmi_fs_toggle <= 1'b0; + hdmi_fs <= 1'b0; + end else begin + if (EMBEDDED_SYNC == 1) begin + if ((hdmi_hs_count == 1) && (hdmi_vs_count == hdmi_ve_width_s)) begin + hdmi_fs <= hdmi_enable; + end else begin + hdmi_fs <= 1'b0; + end + end else begin + if ((hdmi_hs_count == 1) && (hdmi_vs_count == hdmi_vs_width)) begin + hdmi_fs <= hdmi_enable; + end else begin + hdmi_fs <= 1'b0; + end + end + if (hdmi_fs == 1'b1) begin + hdmi_fs_toggle <= ~hdmi_fs_toggle; + end + end + end + + // hdmi sof write address + + assign hdmi_fs_ret_s = hdmi_fs_ret_toggle_m2 ^ hdmi_fs_ret_toggle_m3; + + always @(posedge hdmi_clk or posedge hdmi_rst) begin + if (hdmi_rst == 1'b1) begin + hdmi_fs_ret_toggle_m1 <= 1'd0; + hdmi_fs_ret_toggle_m2 <= 1'd0; + hdmi_fs_ret_toggle_m3 <= 1'd0; + end else begin + hdmi_fs_ret_toggle_m1 <= vdma_fs_ret_toggle; + hdmi_fs_ret_toggle_m2 <= hdmi_fs_ret_toggle_m1; + hdmi_fs_ret_toggle_m3 <= hdmi_fs_ret_toggle_m2; + end + end + + always @(posedge hdmi_clk) begin + hdmi_fs_ret <= hdmi_fs_ret_s; + hdmi_fs_waddr <= vdma_fs_waddr; + end + + // hdmi sync signals + + always @(posedge hdmi_clk) begin + if (EMBEDDED_SYNC == 1) begin + hdmi_hs <= 1'b0; + hdmi_vs <= 1'b0; + if (hdmi_hs_count <= hdmi_he_width_s) begin + hdmi_hs_de <= 1'b0; + end else begin + hdmi_hs_de <= hdmi_enable; + end + if (hdmi_vs_count <= hdmi_ve_width_s) begin + hdmi_vs_de <= 1'b0; + end else begin + hdmi_vs_de <= hdmi_enable; + end + end else begin + if (hdmi_hs_count < hdmi_hs_width) begin + hdmi_hs <= hdmi_enable; + end else begin + hdmi_hs <= 1'b0; + end + if (hdmi_vs_count < hdmi_vs_width) begin + hdmi_vs <= hdmi_enable; + end else begin + hdmi_vs <= 1'b0; + end + if ((hdmi_hs_count < hdmi_he_min) || (hdmi_hs_count >= hdmi_he_max)) begin + hdmi_hs_de <= 1'b0; + end else begin + hdmi_hs_de <= hdmi_enable; + end + if ((hdmi_vs_count < hdmi_ve_min) || (hdmi_vs_count >= hdmi_ve_max)) begin + hdmi_vs_de <= 1'b0; + end else begin + hdmi_vs_de <= hdmi_enable; + end + end + end + + // hdmi read data + + assign hdmi_de_s = hdmi_hs_de & hdmi_vs_de; + + always @(posedge hdmi_clk) begin + if (hdmi_rst == 1'b1) begin + hdmi_raddr <= 10'd0; + end else if (hdmi_fs == 1'b1) begin + hdmi_raddr <= {hdmi_fs_waddr, 1'b0}; + end else if (hdmi_de_s == 1'b1) begin + hdmi_raddr <= hdmi_raddr + 1'b1; + end + hdmi_raddr_g <= b2g(hdmi_raddr[9:1]); + end + + // control and data pipe line + + always @(posedge hdmi_clk) begin + hdmi_hs_d <= hdmi_hs; + hdmi_vs_d <= hdmi_vs; + hdmi_hs_de_d <= hdmi_hs_de; + hdmi_vs_de_d <= hdmi_vs_de; + hdmi_de_d <= hdmi_de_s; + hdmi_data_sel_d <= hdmi_raddr[0]; + hdmi_hs_2d <= hdmi_hs_d; + hdmi_vs_2d <= hdmi_vs_d; + hdmi_hs_de_2d <= hdmi_hs_de_d; + hdmi_vs_de_2d <= hdmi_vs_de_d; + hdmi_de_2d <= hdmi_de_d; + hdmi_data_sel_2d <= hdmi_data_sel_d; + hdmi_data_2d <= hdmi_rdata_s; + end + + // hdmi data count (may be used to monitor or insert) + + assign hdmi_data_2d_s = (hdmi_data_sel_2d == 1'b1) ? hdmi_data_2d[47:24] : hdmi_data_2d[23:0]; + assign hdmi_tpm_mismatch_s = (hdmi_data_2d_s == hdmi_tpm_data) ? 1'b0 : hdmi_de_2d; + assign hdmi_tpg_data_s = hdmi_tpm_data; + + always @(posedge hdmi_clk) begin + if ((hdmi_rst == 1'b1) || (hdmi_fs_ret == 1'b1)) begin + hdmi_tpm_data <= 'd0; + end else if (hdmi_de_2d == 1'b1) begin + hdmi_tpm_data <= hdmi_tpm_data + 1'b1; + end + hdmi_tpm_oos <= hdmi_tpm_mismatch_s; + end + + // hdmi data select + + always @(posedge hdmi_clk) begin + hdmi_hsync <= hdmi_hs_2d; + hdmi_vsync <= hdmi_vs_2d; + hdmi_hsync_data_e <= hdmi_hs_de_2d; + hdmi_vsync_data_e <= hdmi_vs_de_2d; + hdmi_data_e <= hdmi_de_2d; + case (hdmi_srcsel) + 2'b11: hdmi_data <= hdmi_const_rgb; + 2'b10: hdmi_data <= hdmi_tpg_data_s; + 2'b01: hdmi_data <= hdmi_data_2d_s; + default: hdmi_data <= 24'd0; + endcase + end + + // Color space conversion bypass (RGB/YCbCr) + + always @(posedge hdmi_clk) begin + if (hdmi_csc_bypass == 1'b1) begin + hdmi_24_csc_hsync <= hdmi_hsync; + hdmi_24_csc_vsync <= hdmi_vsync; + hdmi_24_csc_hsync_data_e <= hdmi_hsync_data_e; + hdmi_24_csc_vsync_data_e <= hdmi_vsync_data_e; + hdmi_24_csc_data_e <= hdmi_data_e; + hdmi_24_csc_data <= hdmi_data; + end else begin + hdmi_24_csc_hsync <= hdmi_csc_hsync_s; + hdmi_24_csc_vsync <= hdmi_csc_vsync_s; + hdmi_24_csc_hsync_data_e <= hdmi_csc_hsync_data_e_s; + hdmi_24_csc_vsync_data_e <= hdmi_csc_vsync_data_e_s; + hdmi_24_csc_data_e <= hdmi_csc_data_e_s; + hdmi_24_csc_data <= hdmi_csc_data_s; + end + end + + // hdmi clipping + + always @(posedge hdmi_clk) begin + hdmi_clip_hs_d <= hdmi_24_csc_hsync; + hdmi_clip_vs_d <= hdmi_24_csc_vsync; + hdmi_clip_hs_de_d <= hdmi_24_csc_hsync_data_e; + hdmi_clip_vs_de_d <= hdmi_24_csc_vsync_data_e; + hdmi_clip_de_d <= hdmi_24_csc_data_e; + + // Cr (red-diff) / red + + if (hdmi_24_csc_data[23:16] > hdmi_clip_max[23:16]) begin + hdmi_clip_data[23:16] <= hdmi_clip_max[23:16]; + end else if (hdmi_24_csc_data[23:16] < hdmi_clip_min[23:16]) begin + hdmi_clip_data[23:16] <= hdmi_clip_min[23:16]; + end else begin + hdmi_clip_data[23:16] <= hdmi_24_csc_data[23:16]; + end + + // Y (luma) / green + + if (hdmi_24_csc_data[15:8] > hdmi_clip_max[15:8]) begin + hdmi_clip_data[15:8] <= hdmi_clip_max[15:8]; + end else if (hdmi_24_csc_data[15:8] < hdmi_clip_min[15:8]) begin + hdmi_clip_data[15:8] <= hdmi_clip_min[15:8]; + end else begin + hdmi_clip_data[15:8] <= hdmi_24_csc_data[15:8]; + end + + // Cb (blue-diff) / blue + + if (hdmi_24_csc_data[7:0] > hdmi_clip_max[7:0]) begin + hdmi_clip_data[7:0] <= hdmi_clip_max[7:0]; + end else if (hdmi_24_csc_data[7:0] < hdmi_clip_min[7:0]) begin + hdmi_clip_data[7:0] <= hdmi_clip_min[7:0]; + end else begin + hdmi_clip_data[7:0] <= hdmi_24_csc_data[7:0]; + end + end + + // hdmi csc 16, 24 and 36 outputs + + always @(posedge hdmi_clk) begin + + hdmi_36_hsync <= hdmi_clip_hs_d; + hdmi_36_vsync <= hdmi_clip_vs_d; + hdmi_36_data_e <= hdmi_clip_de_d; + hdmi_36_data[35:24] <= {hdmi_clip_data[23:16], hdmi_clip_data[23:20]}; + hdmi_36_data[23:12] <= {hdmi_clip_data[15: 8], hdmi_clip_data[15:12]}; + hdmi_36_data[11: 0] <= {hdmi_clip_data[ 7: 0], hdmi_clip_data[ 7: 4]}; + + hdmi_24_hsync <= hdmi_clip_hs_d; + hdmi_24_vsync <= hdmi_clip_vs_d; + hdmi_24_data_e <= hdmi_clip_de_d; + hdmi_24_data <= hdmi_clip_data; + + hdmi_16_hsync <= hdmi_16_hsync_d; + hdmi_16_vsync <= hdmi_16_vsync_d; + hdmi_16_data_e <= hdmi_16_data_e_d; + hdmi_16_data <= hdmi_16_data_d; + hdmi_16_es_data <= hdmi_es_data_s; + + if (hdmi_ss_bypass == 1'b1) begin + hdmi_16_hsync_d <= hdmi_clip_hs_d; + hdmi_16_vsync_d <= hdmi_clip_vs_d; + hdmi_16_hsync_data_e_d <= hdmi_clip_hs_de_d; + hdmi_16_vsync_data_e_d <= hdmi_clip_vs_de_d; + hdmi_16_data_e_d <= hdmi_clip_de_d; + hdmi_16_data_d <= hdmi_clip_data[15:0]; // Ignore the upper 8 bit + end else begin + hdmi_16_hsync_d <= hdmi_ss_hsync_s; + hdmi_16_vsync_d <= hdmi_ss_vsync_s; + hdmi_16_hsync_data_e_d <= hdmi_ss_hsync_data_e_s; + hdmi_16_vsync_data_e_d <= hdmi_ss_vsync_data_e_s; + hdmi_16_data_e_d <= hdmi_ss_data_e_s; + hdmi_16_data_d <= hdmi_ss_data_s; + end + end + + // hdmi embedded sync + + always @(posedge hdmi_clk) begin + hdmi_es_hs_de <= hdmi_16_hsync_data_e_d; + hdmi_es_vs_de <= hdmi_16_vsync_data_e_d; + if (hdmi_16_data_e_d == 1'b0) begin + hdmi_es_data[15:8] <= 8'h80; + end else begin + hdmi_es_data[15:8] <= hdmi_16_data_d[15:8]; + end + if (hdmi_16_data_e_d == 1'b0) begin + hdmi_es_data[7:0] <= 8'h80; + end else begin + hdmi_es_data[7:0] <= hdmi_16_data_d[7:0]; + end + end + + // data memory + + ad_mem #(.DATA_WIDTH(48), .ADDRESS_WIDTH(9)) i_mem ( + .clka (vdma_clk), + .wea (vdma_wr), + .addra (vdma_waddr), + .dina (vdma_wdata), + .clkb (hdmi_clk), + .reb (1'b1), + .addrb (hdmi_raddr[9:1]), + .doutb (hdmi_rdata_s)); + + // color space coversion, RGB to CrYCb + + ad_csc_RGB2CrYCb #(.DELAY_DATA_WIDTH(5)) i_csc_RGB2CrYCb ( + .clk (hdmi_clk), + .RGB_sync ({hdmi_hsync, + hdmi_vsync, + hdmi_hsync_data_e, + hdmi_vsync_data_e, + hdmi_data_e}), + .RGB_data (hdmi_data), + .CrYCb_sync ({hdmi_csc_hsync_s, + hdmi_csc_vsync_s, + hdmi_csc_hsync_data_e_s, + hdmi_csc_vsync_data_e_s, + hdmi_csc_data_e_s}), + .CrYCb_data (hdmi_csc_data_s)); + + // sub sampling, 444 to 422 + + ad_ss_444to422 #(.DELAY_DATA_WIDTH(5), .CR_CB_N(CR_CB_N)) i_ss_444to422 ( + .clk (hdmi_clk), + .s444_de (hdmi_clip_de_d), + .s444_sync ({hdmi_clip_hs_d, + hdmi_clip_vs_d, + hdmi_clip_hs_de_d, + hdmi_clip_vs_de_d, + hdmi_clip_de_d}), + .s444_data (hdmi_clip_data), + .s422_sync ({hdmi_ss_hsync_s, + hdmi_ss_vsync_s, + hdmi_ss_hsync_data_e_s, + hdmi_ss_vsync_data_e_s, + hdmi_ss_data_e_s}), + .s422_data (hdmi_ss_data_s)); + + // embedded sync + + axi_hdmi_tx_es #(.DATA_WIDTH(16)) i_es ( + .hdmi_clk (hdmi_clk), + .hdmi_hs_de (hdmi_es_hs_de), + .hdmi_vs_de (hdmi_es_vs_de), + .hdmi_data_de (hdmi_es_data), + .hdmi_data (hdmi_es_data_s)); + +endmodule + +// *************************************************************************** +// *************************************************************************** diff --git a/src/adi/hdl/library/axi_hdmi_tx/axi_hdmi_tx_es.v b/src/adi/hdl/library/axi_hdmi_tx/axi_hdmi_tx_es.v new file mode 100644 index 00000000..feaae2cd --- /dev/null +++ b/src/adi/hdl/library/axi_hdmi_tx/axi_hdmi_tx_es.v @@ -0,0 +1,107 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright 2014 - 2017 (c) Analog Devices, Inc. All rights reserved. +// +// In this HDL repository, there are many different and unique modules, consisting +// of various HDL (Verilog or VHDL) components. The individual modules are +// developed independently, and may be accompanied by separate and unique license +// terms. +// +// The user should read each of these license terms, and understand the +// freedoms and responsibilities that he or she has by using this source/core. +// +// This core 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. +// +// Redistribution and use of source or resulting binaries, with or without modification +// of this file, are permitted under one of the following two license terms: +// +// 1. The GNU General Public License version 2 as published by the +// Free Software Foundation, which can be found in the top level directory +// of this repository (LICENSE_GPL2), and also online at: +// +// +// OR +// +// 2. An ADI specific BSD license, which can be found in the top level directory +// of this repository (LICENSE_ADIBSD), and also on-line at: +// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD +// This will allow to generate bit files and not release the source code, +// as long as it attaches to an ADI device. +// +// *************************************************************************** +// *************************************************************************** +// Transmit HDMI, video dma data in, hdmi separate syncs data out. + +`timescale 1ns/100ps + +module axi_hdmi_tx_es #( + + parameter DATA_WIDTH = 32) ( + + // hdmi interface + + input hdmi_clk, + input hdmi_hs_de, + input hdmi_vs_de, + input [(DATA_WIDTH-1):0] hdmi_data_de, + output reg [(DATA_WIDTH-1):0] hdmi_data); + + localparam BYTE_WIDTH = DATA_WIDTH/8; + + // internal registers + + reg hdmi_hs_de_d = 'd0; + reg [(DATA_WIDTH-1):0] hdmi_data_d = 'd0; + reg hdmi_hs_de_2d = 'd0; + reg [(DATA_WIDTH-1):0] hdmi_data_2d = 'd0; + reg hdmi_hs_de_3d = 'd0; + reg [(DATA_WIDTH-1):0] hdmi_data_3d = 'd0; + reg hdmi_hs_de_4d = 'd0; + reg [(DATA_WIDTH-1):0] hdmi_data_4d = 'd0; + reg hdmi_hs_de_5d = 'd0; + reg [(DATA_WIDTH-1):0] hdmi_data_5d = 'd0; + + // internal wires + + wire [(DATA_WIDTH-1):0] hdmi_sav_s; + wire [(DATA_WIDTH-1):0] hdmi_eav_s; + + // hdmi embedded sync insertion + + assign hdmi_sav_s = (hdmi_vs_de == 1) ? {BYTE_WIDTH{8'h80}} : {BYTE_WIDTH{8'hab}}; + assign hdmi_eav_s = (hdmi_vs_de == 1) ? {BYTE_WIDTH{8'h9d}} : {BYTE_WIDTH{8'hb6}}; + + always @(posedge hdmi_clk) begin + hdmi_hs_de_d <= hdmi_hs_de; + case ({hdmi_hs_de_4d, hdmi_hs_de_3d, hdmi_hs_de_2d, + hdmi_hs_de_d, hdmi_hs_de}) + 5'b11000: hdmi_data_d <= {BYTE_WIDTH{8'h00}}; + 5'b11100: hdmi_data_d <= {BYTE_WIDTH{8'h00}}; + 5'b11110: hdmi_data_d <= {BYTE_WIDTH{8'hff}}; + 5'b10000: hdmi_data_d <= hdmi_eav_s; + default: hdmi_data_d <= hdmi_data_de; + endcase + hdmi_hs_de_2d <= hdmi_hs_de_d; + hdmi_data_2d <= hdmi_data_d; + hdmi_hs_de_3d <= hdmi_hs_de_2d; + hdmi_data_3d <= hdmi_data_2d; + hdmi_hs_de_4d <= hdmi_hs_de_3d; + hdmi_data_4d <= hdmi_data_3d; + hdmi_hs_de_5d <= hdmi_hs_de_4d; + hdmi_data_5d <= hdmi_data_4d; + case ({hdmi_hs_de_5d, hdmi_hs_de_4d, hdmi_hs_de_3d, + hdmi_hs_de_2d, hdmi_hs_de_d}) + 5'b00111: hdmi_data <= {BYTE_WIDTH{8'h00}}; + 5'b00011: hdmi_data <= {BYTE_WIDTH{8'h00}}; + 5'b00001: hdmi_data <= {BYTE_WIDTH{8'hff}}; + 5'b01111: hdmi_data <= hdmi_sav_s; + default: hdmi_data <= hdmi_data_5d; + endcase + end + +endmodule + +// *************************************************************************** +// *************************************************************************** diff --git a/src/adi/hdl/library/axi_hdmi_tx/axi_hdmi_tx_hw.tcl b/src/adi/hdl/library/axi_hdmi_tx/axi_hdmi_tx_hw.tcl new file mode 100644 index 00000000..15fbb9bf --- /dev/null +++ b/src/adi/hdl/library/axi_hdmi_tx/axi_hdmi_tx_hw.tcl @@ -0,0 +1,104 @@ + + +package require qsys +source ../scripts/adi_env.tcl +source ../scripts/adi_ip_alt.tcl + +set_module_property NAME axi_hdmi_tx +set_module_property DESCRIPTION "AXI HDMI Transmit Interface" +set_module_property VERSION 1.0 +set_module_property GROUP "Analog Devices" +set_module_property DISPLAY_NAME axi_hdmi_tx + +# files + +add_fileset quartus_synth QUARTUS_SYNTH "" "Quartus Synthesis" +set_fileset_property quartus_synth TOP_LEVEL axi_hdmi_tx +add_fileset_file ad_mem.v VERILOG PATH $ad_hdl_dir/library/common/ad_mem.v +add_fileset_file ad_rst.v VERILOG PATH $ad_hdl_dir/library/common/ad_rst.v +add_fileset_file ad_csc_1_mul.v VERILOG PATH $ad_hdl_dir/library/common/ad_csc_1_mul.v +add_fileset_file ad_csc_1_add.v VERILOG PATH $ad_hdl_dir/library/common/ad_csc_1_add.v +add_fileset_file ad_csc_1.v VERILOG PATH $ad_hdl_dir/library/common/ad_csc_1.v +add_fileset_file ad_csc_RGB2CrYCb.v VERILOG PATH $ad_hdl_dir/library/common/ad_csc_RGB2CrYCb.v +add_fileset_file ad_ss_444to422.v VERILOG PATH $ad_hdl_dir/library/common/ad_ss_444to422.v +add_fileset_file up_axi.v VERILOG PATH $ad_hdl_dir/library/common/up_axi.v +add_fileset_file up_xfer_cntrl.v VERILOG PATH $ad_hdl_dir/library/common/up_xfer_cntrl.v +add_fileset_file up_xfer_status.v VERILOG PATH $ad_hdl_dir/library/common/up_xfer_status.v +add_fileset_file up_clock_mon.v VERILOG PATH $ad_hdl_dir/library/common/up_clock_mon.v +add_fileset_file up_hdmi_tx.v VERILOG PATH $ad_hdl_dir/library/common/up_hdmi_tx.v +add_fileset_file ad_mul.v VERILOG PATH $ad_hdl_dir/library/altera/common/ad_mul.v +add_fileset_file axi_hdmi_tx_vdma.v VERILOG PATH axi_hdmi_tx_vdma.v +add_fileset_file axi_hdmi_tx_es.v VERILOG PATH axi_hdmi_tx_es.v +add_fileset_file axi_hdmi_tx_core.v VERILOG PATH axi_hdmi_tx_core.v +add_fileset_file axi_hdmi_tx.v VERILOG PATH axi_hdmi_tx.v TOP_LEVEL_FILE +add_fileset_file up_xfer_cntrl_constr.sdc SDC PATH $ad_hdl_dir/library/altera/common/up_xfer_cntrl_constr.sdc +add_fileset_file up_xfer_status_constr.sdc SDC PATH $ad_hdl_dir/library/altera/common/up_xfer_status_constr.sdc +add_fileset_file up_clock_mon_constr.sdc SDC PATH $ad_hdl_dir/library/altera/common/up_clock_mon_constr.sdc +add_fileset_file up_rst_constr.sdc SDC PATH $ad_hdl_dir/library/altera/common/up_rst_constr.sdc +add_fileset_file axi_hdmi_tx_constr.sdc SDC PATH axi_hdmi_tx_constr.sdc + +# parameters + +add_parameter ID INTEGER 0 +set_parameter_property ID DEFAULT_VALUE 0 +set_parameter_property ID DISPLAY_NAME ID +set_parameter_property ID TYPE INTEGER +set_parameter_property ID UNITS None +set_parameter_property ID HDL_PARAMETER true + +add_parameter CR_CB_N INTEGER 0 +set_parameter_property CR_CB_N DEFAULT_VALUE 0 +set_parameter_property CR_CB_N DISPLAY_NAME CR_CB_N +set_parameter_property CR_CB_N TYPE INTEGER +set_parameter_property CR_CB_N UNITS None +set_parameter_property CR_CB_N HDL_PARAMETER true + +add_parameter DEVICE_TYPE INTEGER 0 +set_parameter_property DEVICE_TYPE DEFAULT_VALUE 16 +set_parameter_property DEVICE_TYPE DISPLAY_NAME DEVICE_TYPE +set_parameter_property DEVICE_TYPE TYPE INTEGER +set_parameter_property DEVICE_TYPE UNITS None +set_parameter_property DEVICE_TYPE HDL_PARAMETER true + +add_parameter EMBEDDED_SYNC INTEGER 0 +set_parameter_property EMBEDDED_SYNC DEFAULT_VALUE 0 +set_parameter_property EMBEDDED_SYNC DISPLAY_NAME EMBEDDED_SYNC +set_parameter_property EMBEDDED_SYNC TYPE INTEGER +set_parameter_property EMBEDDED_SYNC UNITS None +set_parameter_property EMBEDDED_SYNC HDL_PARAMETER true + +# axi4 slave + +ad_ip_intf_s_axi s_axi_aclk s_axi_aresetn + +# hdmi interface + +add_interface hdmi_clock clock end +add_interface_port hdmi_clock hdmi_clk clk Input 1 + +add_interface hdmi_if conduit end +set_interface_property hdmi_if associatedClock hdmi_clock +add_interface_port hdmi_if hdmi_out_clk h_clk Output 1 +add_interface_port hdmi_if hdmi_16_hsync h16_hsync Output 1 +add_interface_port hdmi_if hdmi_16_vsync h16_vsync Output 1 +add_interface_port hdmi_if hdmi_16_data_e h16_data_e Output 1 +add_interface_port hdmi_if hdmi_16_data h16_data Output 16 +add_interface_port hdmi_if hdmi_16_es_data h16_es_data Output 16 +add_interface_port hdmi_if hdmi_24_hsync h24_hsync Output 1 +add_interface_port hdmi_if hdmi_24_vsync h24_vsync Output 1 +add_interface_port hdmi_if hdmi_24_data_e h24_data_e Output 1 +add_interface_port hdmi_if hdmi_24_data h24_data Output 24 +add_interface_port hdmi_if hdmi_36_hsync h36_hsync Output 1 +add_interface_port hdmi_if hdmi_36_vsync h36_vsync Output 1 +add_interface_port hdmi_if hdmi_36_data_e h36_data_e Output 1 +add_interface_port hdmi_if hdmi_36_data h36_data Output 36 + +# avalon streaming dma + +add_interface vdma_clock clock end +add_interface_port vdma_clock vdma_clk clk Input 1 + +ad_alt_intf signal vdma_ready output 1 ready +ad_alt_intf signal vdma_valid input 1 valid +ad_alt_intf signal vdma_data input 64 data +ad_alt_intf signal vdma_end_of_frame input 1 last diff --git a/src/adi/hdl/library/axi_hdmi_tx/axi_hdmi_tx_ip.tcl b/src/adi/hdl/library/axi_hdmi_tx/axi_hdmi_tx_ip.tcl new file mode 100644 index 00000000..6b42f6e2 --- /dev/null +++ b/src/adi/hdl/library/axi_hdmi_tx/axi_hdmi_tx_ip.tcl @@ -0,0 +1,72 @@ +# ip + +source ../scripts/adi_env.tcl +source $ad_hdl_dir/library/scripts/adi_ip.tcl + +adi_ip_create axi_hdmi_tx +adi_ip_files axi_hdmi_tx [list \ + "$ad_hdl_dir/library/common/ad_mem.v" \ + "$ad_hdl_dir/library/common/ad_rst.v" \ + "$ad_hdl_dir/library/common/ad_csc_1_mul.v" \ + "$ad_hdl_dir/library/common/ad_csc_1_add.v" \ + "$ad_hdl_dir/library/common/ad_csc_1.v" \ + "$ad_hdl_dir/library/common/ad_csc_RGB2CrYCb.v" \ + "$ad_hdl_dir/library/common/ad_ss_444to422.v" \ + "$ad_hdl_dir/library/common/up_axi.v" \ + "$ad_hdl_dir/library/common/up_xfer_cntrl.v" \ + "$ad_hdl_dir/library/common/up_xfer_status.v" \ + "$ad_hdl_dir/library/common/up_clock_mon.v" \ + "$ad_hdl_dir/library/common/up_hdmi_tx.v" \ + "$ad_hdl_dir/library/xilinx/common/ad_mul.v" \ + "$ad_hdl_dir/library/xilinx/common/up_xfer_cntrl_constr.xdc" \ + "$ad_hdl_dir/library/xilinx/common/ad_rst_constr.xdc" \ + "$ad_hdl_dir/library/xilinx/common/up_xfer_status_constr.xdc" \ + "$ad_hdl_dir/library/xilinx/common/up_clock_mon_constr.xdc" \ + "axi_hdmi_tx_constr.xdc" \ + "axi_hdmi_tx_vdma.v" \ + "axi_hdmi_tx_es.v" \ + "axi_hdmi_tx_core.v" \ + "axi_hdmi_tx.v" ] + +adi_ip_properties axi_hdmi_tx + +set_property driver_value 0 [ipx::get_ports *hsync* -of_objects [ipx::current_core]] +set_property driver_value 0 [ipx::get_ports *vsync* -of_objects [ipx::current_core]] +set_property driver_value 0 [ipx::get_ports *data* -of_objects [ipx::current_core]] +set_property driver_value 0 [ipx::get_ports *es_data* -of_objects [ipx::current_core]] + +set_property driver_value 0 [ipx::get_ports *vdma_end_of_frame* -of_objects [ipx::current_core]] +set_property driver_value 0 [ipx::get_ports *vdma_valid* -of_objects [ipx::current_core]] +set_property driver_value 0 [ipx::get_ports *vdma_data* -of_objects [ipx::current_core]] +set_property driver_value 0 [ipx::get_ports *vdma_ready* -of_objects [ipx::current_core]] + +set_property value_format string [ipx::get_user_parameters INTERFACE -of_objects [ipx::current_core]] +set_property value_format string [ipx::get_hdl_parameters INTERFACE -of_objects [ipx::current_core]] +set_property value_validation_list {16_BIT 24_BIT 36_BIT 16_BIT_EMBEDDED_SYNC} \ + [ipx::get_user_parameters INTERFACE -of_objects [ipx::current_core]] + +set_property enablement_dependency {spirit:decode(id('MODELPARAM_VALUE.INTERFACE')) == "16_BIT"} \ + [ipx::get_ports *hdmi_16* -of_objects [ipx::current_core]] +set_property enablement_dependency {spirit:decode(id('MODELPARAM_VALUE.INTERFACE')) == "24_BIT"} \ + [ipx::get_ports *hdmi_24* -of_objects [ipx::current_core]] +set_property enablement_dependency {spirit:decode(id('MODELPARAM_VALUE.INTERFACE')) == "36_BIT"} \ + [ipx::get_ports *hdmi_36* -of_objects [ipx::current_core]] +set_property enablement_dependency {spirit:decode(id('MODELPARAM_VALUE.INTERFACE')) == "16_BIT_EMBEDDED_SYNC"} \ + [ipx::get_ports *hdmi_16_es_data* -of_objects [ipx::current_core]] + +adi_add_bus "s_axis" "slave" \ + "xilinx.com:interface:axis_rtl:1.0" \ + "xilinx.com:interface:axis:1.0" \ + [list {"vdma_ready" "TREADY"} \ + {"vdma_valid" "TVALID"} \ + {"vdma_data" "TDATA"} \ + {"vdma_end_of_frame" "TLAST"} ] + +ipx::infer_bus_interface hdmi_clk xilinx.com:signal:clock_rtl:1.0 [ipx::current_core] +ipx::infer_bus_interface hdmi_out_clk xilinx.com:signal:clock_rtl:1.0 [ipx::current_core] +ipx::infer_bus_interface vdma_clk xilinx.com:signal:clock_rtl:1.0 [ipx::current_core] + +ipx::associate_bus_interfaces -busif s_axis -clock vdma_clk [ipx::current_core] + +ipx::save_core [ipx::current_core] + diff --git a/src/adi/hdl/library/axi_hdmi_tx/axi_hdmi_tx_vdma.v b/src/adi/hdl/library/axi_hdmi_tx/axi_hdmi_tx_vdma.v new file mode 100644 index 00000000..4db00e13 --- /dev/null +++ b/src/adi/hdl/library/axi_hdmi_tx/axi_hdmi_tx_vdma.v @@ -0,0 +1,235 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright 2014 - 2017 (c) Analog Devices, Inc. All rights reserved. +// +// In this HDL repository, there are many different and unique modules, consisting +// of various HDL (Verilog or VHDL) components. The individual modules are +// developed independently, and may be accompanied by separate and unique license +// terms. +// +// The user should read each of these license terms, and understand the +// freedoms and responsibilities that he or she has by using this source/core. +// +// This core 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. +// +// Redistribution and use of source or resulting binaries, with or without modification +// of this file, are permitted under one of the following two license terms: +// +// 1. The GNU General Public License version 2 as published by the +// Free Software Foundation, which can be found in the top level directory +// of this repository (LICENSE_GPL2), and also online at: +// +// +// OR +// +// 2. An ADI specific BSD license, which can be found in the top level directory +// of this repository (LICENSE_ADIBSD), and also on-line at: +// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD +// This will allow to generate bit files and not release the source code, +// as long as it attaches to an ADI device. +// +// *************************************************************************** +// *************************************************************************** +// Transmit HDMI, video dma data in, hdmi separate syncs data out. + +`timescale 1ns/100ps + +module axi_hdmi_tx_vdma ( + + // hdmi interface + + input hdmi_fs_toggle, + input [ 8:0] hdmi_raddr_g, + + // vdma interface + + input vdma_clk, + input vdma_rst, + input vdma_end_of_frame, + input vdma_valid, + input [63:0] vdma_data, + output reg vdma_ready, + output reg vdma_wr, + output reg [ 8:0] vdma_waddr, + output reg [47:0] vdma_wdata, + output reg vdma_fs_ret_toggle, + output reg [ 8:0] vdma_fs_waddr, + output reg vdma_tpm_oos, + output reg vdma_ovf, + output reg vdma_unf); + + localparam BUF_THRESHOLD_LO = 9'd3; + localparam BUF_THRESHOLD_HI = 9'd509; + localparam RDY_THRESHOLD_LO = 9'd450; + localparam RDY_THRESHOLD_HI = 9'd500; + + // internal registers + + reg vdma_fs_toggle_m1 = 1'd0; + reg vdma_fs_toggle_m2 = 1'd0; + reg vdma_fs_toggle_m3 = 1'd0; + reg [22:0] vdma_tpm_data = 23'd0; + reg [ 8:0] vdma_raddr_g_m1 = 9'd0; + reg [ 8:0] vdma_raddr_g_m2 = 9'd0; + reg [ 8:0] vdma_raddr = 9'd0; + reg [ 8:0] vdma_addr_diff = 9'd0; + reg vdma_almost_full = 1'd0; + reg vdma_almost_empty = 1'd0; + reg hdmi_fs = 1'd0; + reg vdma_fs = 1'd0; + reg vdma_end_of_frame_d = 1'd0; + reg vdma_active_frame = 1'd0; + + // internal wires + + wire [47:0] vdma_tpm_data_s; + wire vdma_tpm_oos_s; + wire [ 9:0] vdma_addr_diff_s; + wire vdma_ovf_s; + wire vdma_unf_s; + + // grey to binary conversion + + function [8:0] g2b; + input [8:0] g; + reg [8:0] b; + begin + b[8] = g[8]; + b[7] = b[8] ^ g[7]; + b[6] = b[7] ^ g[6]; + b[5] = b[6] ^ g[5]; + b[4] = b[5] ^ g[4]; + b[3] = b[4] ^ g[3]; + b[2] = b[3] ^ g[2]; + b[1] = b[2] ^ g[1]; + b[0] = b[1] ^ g[0]; + g2b = b; + end + endfunction + + // hdmi frame sync + + always @(posedge vdma_clk or posedge vdma_rst) begin + if (vdma_rst == 1'b1) begin + vdma_fs_toggle_m1 <= 1'd0; + vdma_fs_toggle_m2 <= 1'd0; + vdma_fs_toggle_m3 <= 1'd0; + end else begin + vdma_fs_toggle_m1 <= hdmi_fs_toggle; + vdma_fs_toggle_m2 <= vdma_fs_toggle_m1; + vdma_fs_toggle_m3 <= vdma_fs_toggle_m2; + end + hdmi_fs <= vdma_fs_toggle_m2 ^ vdma_fs_toggle_m3; + end + + // dma frame sync + + always @(posedge vdma_clk or posedge vdma_rst) begin + if (vdma_rst == 1'b1) begin + vdma_end_of_frame_d <= 1'b0; + vdma_fs <= 1'b0; + end else begin + vdma_end_of_frame_d <= vdma_end_of_frame; + vdma_fs <= vdma_end_of_frame_d; + end + end + + // sync dma and hdmi frames + + always @(posedge vdma_clk) begin + if (vdma_rst == 1'b1) begin + vdma_fs_ret_toggle = 1'b0; + vdma_fs_waddr <= 9'b0; + end else begin + if (vdma_fs) begin + vdma_fs_ret_toggle <= ~vdma_fs_ret_toggle; + vdma_fs_waddr <= vdma_waddr ; + end + end + end + + // accept new frame from dma + + always @(posedge vdma_clk) begin + if (vdma_rst == 1'b1) begin + vdma_active_frame <= 1'b0; + end else begin + if ((vdma_active_frame == 1'b1) && (vdma_end_of_frame == 1'b1)) begin + vdma_active_frame <= 1'b0; + end else if ((vdma_active_frame == 1'b0) && (hdmi_fs == 1'b1)) begin + vdma_active_frame <= 1'b1; + end + end + end + + // vdma write + + always @(posedge vdma_clk) begin + vdma_wr <= vdma_valid & vdma_ready; + if (vdma_rst == 1'b1) begin + vdma_waddr <= 9'd0; + end else if (vdma_wr == 1'b1) begin + vdma_waddr <= vdma_waddr + 1'b1; + end + vdma_wdata <= {vdma_data[55:32], vdma_data[23:0]}; + end + + // test error conditions + + assign vdma_tpm_data_s = {vdma_tpm_data, 1'b1, vdma_tpm_data, 1'b0}; + assign vdma_tpm_oos_s = (vdma_wdata == vdma_tpm_data_s) ? 1'b0 : vdma_wr; + + always @(posedge vdma_clk) begin + if ((vdma_rst == 1'b1) || (vdma_fs == 1'b1)) begin + vdma_tpm_data <= 23'd0; + vdma_tpm_oos <= 1'd0; + end else if (vdma_wr == 1'b1) begin + vdma_tpm_data <= vdma_tpm_data + 1'b1; + vdma_tpm_oos <= vdma_tpm_oos_s; + end + end + + // overflow or underflow status + + assign vdma_addr_diff_s = {1'b1, vdma_waddr} - vdma_raddr; + assign vdma_ovf_s = (vdma_addr_diff < BUF_THRESHOLD_LO) ? vdma_almost_full : 1'b0; + assign vdma_unf_s = (vdma_addr_diff > BUF_THRESHOLD_HI) ? vdma_almost_empty : 1'b0; + + always @(posedge vdma_clk or posedge vdma_rst) begin + if (vdma_rst == 1'b1) begin + vdma_raddr_g_m1 <= 9'd0; + vdma_raddr_g_m2 <= 9'd0; + end else begin + vdma_raddr_g_m1 <= hdmi_raddr_g; + vdma_raddr_g_m2 <= vdma_raddr_g_m1; + end + end + + always @(posedge vdma_clk) begin + vdma_raddr <= g2b(vdma_raddr_g_m2); + vdma_addr_diff <= vdma_addr_diff_s[8:0]; + if (vdma_addr_diff >= RDY_THRESHOLD_HI) begin + vdma_ready <= 1'b0; + end else if (vdma_addr_diff <= RDY_THRESHOLD_LO) begin + vdma_ready <= vdma_active_frame; + end + if (vdma_addr_diff > BUF_THRESHOLD_HI) begin + vdma_almost_full <= 1'b1; + end else begin + vdma_almost_full <= 1'b0; + end + if (vdma_addr_diff < BUF_THRESHOLD_LO) begin + vdma_almost_empty <= 1'b1; + end else begin + vdma_almost_empty <= 1'b0; + end + vdma_ovf <= vdma_ovf_s; + vdma_unf <= vdma_unf_s; + end + +endmodule + +// *************************************************************************** +// *************************************************************************** diff --git a/src/adi/hdl/library/axi_spdif_tx/Makefile b/src/adi/hdl/library/axi_spdif_tx/Makefile new file mode 100644 index 00000000..469e8164 --- /dev/null +++ b/src/adi/hdl/library/axi_spdif_tx/Makefile @@ -0,0 +1,19 @@ +#################################################################################### +## Copyright 2018(c) Analog Devices, Inc. +## Auto-generated, do not modify! +#################################################################################### + +LIBRARY_NAME := axi_spdif_tx + +GENERIC_DEPS += ../common/axi_ctrlif.vhd +GENERIC_DEPS += ../common/axi_streaming_dma_tx_fifo.vhd +GENERIC_DEPS += ../common/dma_fifo.vhd +GENERIC_DEPS += ../common/pl330_dma_fifo.vhd +GENERIC_DEPS += axi_spdif_tx.vhd +GENERIC_DEPS += tx_encoder.vhd +GENERIC_DEPS += tx_package.vhd + +XILINX_DEPS += axi_spdif_tx_constr.xdc +XILINX_DEPS += axi_spdif_tx_ip.tcl + +include ../scripts/library.mk diff --git a/src/adi/hdl/library/axi_spdif_tx/axi_spdif_tx.vhd b/src/adi/hdl/library/axi_spdif_tx/axi_spdif_tx.vhd new file mode 100644 index 00000000..6940c543 --- /dev/null +++ b/src/adi/hdl/library/axi_spdif_tx/axi_spdif_tx.vhd @@ -0,0 +1,318 @@ +-- *************************************************************************** +-- *************************************************************************** +-- Copyright 2014 - 2017 (c) Analog Devices, Inc. All rights reserved. +-- +-- In this HDL repository, there are many different and unique modules, consisting +-- of various HDL (Verilog or VHDL) components. The individual modules are +-- developed independently, and may be accompanied by separate and unique license +-- terms. +-- +-- The user should read each of these license terms, and understand the +-- freedoms and responsibilities that he or she has by using this source/core. +-- +-- This core 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. +-- +-- Redistribution and use of source or resulting binaries, with or without modification +-- of this file, are permitted under one of the following two license terms: +-- +-- 1. The GNU General Public License version 2 as published by the +-- Free Software Foundation, which can be found in the top level directory +-- of this repository (LICENSE_GPL2), and also online at: +-- +-- +-- OR +-- +-- 2. An ADI specific BSD license, which can be found in the top level directory +-- of this repository (LICENSE_ADIBSD), and also on-line at: +-- https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD +-- This will allow to generate bit files and not release the source code, +-- as long as it attaches to an ADI device. +-- +-- *************************************************************************** +-- *************************************************************************** + +library ieee; +use ieee.std_logic_1164.all; + +library work; +use work.tx_package.all; +use work.axi_ctrlif; +use work.axi_streaming_dma_tx_fifo; +use work.pl330_dma_fifo; + +entity axi_spdif_tx is + generic ( + S_AXI_DATA_WIDTH : integer := 32; + S_AXI_ADDRESS_WIDTH : integer := 32; + DEVICE_FAMILY : string := "virtex6"; + DMA_TYPE : integer := 0 + ); + port ( + --SPDIF ports + spdif_data_clk : in std_logic; + spdif_tx_o : out std_logic; + + --AXI Lite interface + s_axi_aclk : in std_logic; + s_axi_aresetn : in std_logic; + s_axi_awaddr : in std_logic_vector(S_AXI_ADDRESS_WIDTH-1 downto 0); + s_axi_awprot : in std_logic_vector(2 downto 0); + s_axi_awvalid : in std_logic; + s_axi_wdata : in std_logic_vector(S_AXI_DATA_WIDTH-1 downto 0); + s_axi_wstrb : in std_logic_vector((S_AXI_DATA_WIDTH/8)-1 downto 0); + s_axi_wvalid : in std_logic; + s_axi_bready : in std_logic; + s_axi_araddr : in std_logic_vector(S_AXI_ADDRESS_WIDTH-1 downto 0); + s_axi_arprot : in std_logic_vector(2 downto 0); + s_axi_arvalid : in std_logic; + s_axi_rready : in std_logic; + s_axi_arready : out std_logic; + s_axi_rdata : out std_logic_vector(S_AXI_DATA_WIDTH-1 downto 0); + s_axi_rresp : out std_logic_vector(1 downto 0); + s_axi_rvalid : out std_logic; + s_axi_wready : out std_logic; + s_axi_bresp : out std_logic_vector(1 downto 0); + s_axi_bvalid : out std_logic; + s_axi_awready : out std_logic; + + --axi streaming interface + s_axis_aclk : in std_logic; + s_axis_aresetn : in std_logic; + s_axis_tready : out std_logic; + s_axis_tdata : in std_logic_vector(31 downto 0); + s_axis_tlast : in std_logic; + s_axis_tvalid : in std_logic; + + --PL330 DMA interface + dma_req_aclk : in std_logic; + dma_req_rstn : in std_logic; + dma_req_davalid : in std_logic; + dma_req_datype : in std_logic_vector(1 downto 0); + dma_req_daready : out std_logic; + dma_req_drvalid : out std_logic; + dma_req_drtype : out std_logic_vector(1 downto 0); + dma_req_drlast : out std_logic; + dma_req_drready : in std_logic + ); +end entity axi_spdif_tx; + +------------------------------------------------------------------------------ +-- Architecture section +------------------------------------------------------------------------------ + +architecture IMP of axi_spdif_tx is + ------------------------------------------ + -- SPDIF signals + ------------------------------------------ + signal config_reg : std_logic_vector(S_AXI_DATA_WIDTH-1 downto 0); + signal chstatus_reg : std_logic_vector(S_AXI_DATA_WIDTH-1 downto 0); + + signal chstat_freq : std_logic_vector(1 downto 0); + signal chstat_gstat, chstat_preem, chstat_copy, chstat_audio : std_logic; + signal sample_data_ack : std_logic; + signal sample_data: std_logic_vector(15 downto 0); + signal conf_mode : std_logic_vector(3 downto 0); + signal conf_ratio : std_logic_vector(7 downto 0); + signal conf_tinten, conf_txdata, conf_txen : std_logic; + signal channel : std_logic; + signal enable : boolean; + + signal fifo_data_out : std_logic_vector(31 downto 0); + signal fifo_data_ack : std_logic; + signal fifo_reset : std_logic; + signal tx_fifo_stb : std_logic; + + -- Register access + signal wr_data : std_logic_vector(31 downto 0); + signal rd_data : std_logic_vector(31 downto 0); + signal wr_addr : integer range 0 to 3; + signal rd_addr : integer range 0 to 3; + signal wr_stb : std_logic; + signal rd_ack : std_logic; +begin + + fifo_reset <= not conf_txdata; + enable <= conf_txdata = '1'; + fifo_data_ack <= channel and sample_data_ack; + + streaming_dma_gen: if DMA_TYPE = 0 generate + fifo: entity axi_streaming_dma_tx_fifo + generic map ( + RAM_ADDR_WIDTH => 3, + FIFO_DWIDTH => 32 + ) + port map ( + clk => s_axi_aclk, + resetn => s_axi_aresetn, + fifo_reset => fifo_reset, + enable => enable, + s_axis_aclk => s_axis_aclk, + s_axis_tready => s_axis_tready, + s_axis_tdata => s_axis_tdata, + s_axis_tvalid => s_axis_tlast, + s_axis_tlast => s_axis_tvalid, + + out_ack => fifo_data_ack, + out_data => fifo_data_out + ); + end generate; + + no_streaming_dma_gen: if DMA_TYPE /= 0 generate + s_axis_tready <= '0'; + end generate; + + pl330_dma_gen: if DMA_TYPE = 1 generate + tx_fifo_stb <= '1' when wr_addr = 3 and wr_stb = '1' else '0'; + + fifo: entity pl330_dma_fifo + generic map( + RAM_ADDR_WIDTH => 3, + FIFO_DWIDTH => 32, + FIFO_DIRECTION => 0 + ) + port map ( + clk => s_axi_aclk, + resetn => s_axi_aresetn, + fifo_reset => fifo_reset, + enable => enable, + + in_data => wr_data, + in_stb => tx_fifo_stb, + + out_ack => fifo_data_ack, + out_data => fifo_data_out, + + dclk => dma_req_aclk, + dresetn => dma_req_rstn, + davalid => dma_req_davalid, + daready => dma_req_daready, + datype => dma_req_datype, + drvalid => dma_req_drvalid, + drready => dma_req_drreadY, + drtype => dma_req_drtype, + drlast => dma_req_drlast + ); + end generate; + + no_pl330_dma_gen: if DMA_TYPE /= 1 generate + dma_req_daready <= '0'; + dma_req_drvalid <= '0'; + dma_req_drtype <= (others => '0'); + dma_req_drlast <= '0'; + end generate; + + sample_data_mux: process (fifo_data_out, channel) is + begin + if channel = '0' then + sample_data <= fifo_data_out(15 downto 0); + else + sample_data <= fifo_data_out(31 downto 16); + end if; + end process; + + -- Configuration signals update + conf_mode(3 downto 0) <= config_reg(23 downto 20); + conf_ratio(7 downto 0) <= config_reg(15 downto 8); + conf_tinten <= config_reg(2); + conf_txdata <= config_reg(1); + conf_txen <= config_reg(0); + + -- Channel status signals update + chstat_freq(1 downto 0) <= chstatus_reg(7 downto 6); + chstat_gstat <= chstatus_reg(3); + chstat_preem <= chstatus_reg(2); + chstat_copy <= chstatus_reg(1); + chstat_audio <= chstatus_reg(0); + + -- Transmit encoder + TENC: tx_encoder + generic map ( + DATA_WIDTH => 16 + ) + port map ( + up_clk => s_axi_aclk, + data_clk => spdif_data_clk, -- data clock + resetn => s_axi_aresetn, -- resetn + conf_mode => conf_mode, -- sample format + conf_ratio => conf_ratio, -- clock divider + conf_txdata => conf_txdata, -- sample data enable + conf_txen => conf_txen, -- spdif signal enable + chstat_freq => chstat_freq, -- sample freq. + chstat_gstat => chstat_gstat, -- generation status + chstat_preem => chstat_preem, -- preemphasis status + chstat_copy => chstat_copy, -- copyright bit + chstat_audio => chstat_audio, -- data format + sample_data => sample_data, -- audio data + sample_data_ack => sample_data_ack, -- sample buffer read + channel => channel, -- which channel should be read + spdif_tx_o => spdif_tx_o -- SPDIF output signal + ); + + ctrlif: entity axi_ctrlif + generic map ( + C_S_AXI_ADDR_WIDTH => S_AXI_ADDRESS_WIDTH, + C_S_AXI_DATA_WIDTH => S_AXI_DATA_WIDTH, + C_NUM_REG => 4 + ) + port map( + s_axi_aclk => s_axi_aclk, + s_axi_aresetn => s_axi_aresetn, + s_axi_awaddr => s_axi_awaddr, + s_axi_awvalid => s_axi_awvalid, + s_axi_wdata => s_axi_wdata, + s_axi_wstrb => s_axi_wstrb, + s_axi_wvalid => s_axi_wvalid, + s_axi_bready => s_axi_bready, + s_axi_araddr => s_axi_araddr, + s_axi_arvalid => s_axi_arvalid, + s_axi_rready => s_axi_rready, + s_axi_arready => s_axi_arready, + s_axi_rdata => s_axi_rdata, + s_axi_rresp => s_axi_rresp, + s_axi_rvalid => s_axi_rvalid, + s_axi_wready => s_axi_wready, + s_axi_bresp => s_axi_bresp, + s_axi_bvalid => s_axi_bvalid, + s_axi_awready => s_axi_awready, + + rd_addr => rd_addr, + rd_data => rd_data, + rd_ack => rd_ack, + rd_stb => '1', + + wr_addr => wr_addr, + wr_data => wr_data, + wr_ack => '1', + wr_stb => wr_stb + ); + + process (s_axi_aclk) + begin + if rising_edge(s_axi_aclk) then + if s_axi_aresetn = '0' then + config_reg <= (others => '0'); + chstatus_reg <= (others => '0'); + else + if wr_stb = '1' then + case wr_addr is + when 0 => config_reg <= wr_data; + when 1 => chstatus_reg <= wr_data; + when others => null; + end case; + end if; + end if; + end if; + end process; + + process (rd_addr, config_reg, chstatus_reg) + begin + case rd_addr is + when 0 => rd_data <= config_reg; + when 1 => rd_data <= chstatus_reg; + when others => rd_data <= (others => '0'); + end case; + end process; + +end IMP; diff --git a/src/adi/hdl/library/axi_spdif_tx/axi_spdif_tx_constr.xdc b/src/adi/hdl/library/axi_spdif_tx/axi_spdif_tx_constr.xdc new file mode 100644 index 00000000..c874131d --- /dev/null +++ b/src/adi/hdl/library/axi_spdif_tx/axi_spdif_tx_constr.xdc @@ -0,0 +1,11 @@ +set_property ASYNC_REG TRUE \ + [get_cells -hier cdc_sync_stage1_*_reg] \ + [get_cells -hier cdc_sync_stage2_*_reg] + +set_false_path \ + -from [get_cells -hier cdc_sync_stage0_*_reg -filter {PRIMITIVE_SUBGROUP == flop || primitive_subgroup == SDR}] \ + -to [get_cells -hier cdc_sync_stage1_*_reg -filter {PRIMITIVE_SUBGROUP == flop || primitive_subgroup == SDR}] + +set_false_path \ + -from [get_cells -hier spdif_out_reg -filter {PRIMITIVE_SUBGROUP == flop || primitive_subgroup == SDR}] \ + -to [get_cells -hier spdif_tx_o_reg -filter {PRIMITIVE_SUBGROUP == flop || primitive_subgroup == SDR}] diff --git a/src/adi/hdl/library/axi_spdif_tx/axi_spdif_tx_ip.tcl b/src/adi/hdl/library/axi_spdif_tx/axi_spdif_tx_ip.tcl new file mode 100644 index 00000000..7919a6f0 --- /dev/null +++ b/src/adi/hdl/library/axi_spdif_tx/axi_spdif_tx_ip.tcl @@ -0,0 +1,50 @@ +# ip + +source ../scripts/adi_env.tcl +source $ad_hdl_dir/library/scripts/adi_ip.tcl + +adi_ip_create axi_spdif_tx +adi_ip_files axi_spdif_tx [list \ + "$ad_hdl_dir/library/common/axi_ctrlif.vhd" \ + "$ad_hdl_dir/library/common/axi_streaming_dma_tx_fifo.vhd" \ + "$ad_hdl_dir/library/common/pl330_dma_fifo.vhd" \ + "$ad_hdl_dir/library/common/dma_fifo.vhd" \ + "tx_package.vhd" \ + "tx_encoder.vhd" \ + "axi_spdif_tx.vhd" \ + "axi_spdif_tx_constr.xdc" ] + +adi_ip_properties axi_spdif_tx +adi_ip_infer_streaming_interfaces axi_spdif_tx + +adi_add_bus "dma_ack" "slave" \ + "xilinx.com:interface:axis_rtl:1.0" \ + "xilinx.com:interface:axis:1.0" \ + [list {"dma_req_davalid" "TVALID"} \ + {"dma_req_daready" "TREADY"} \ + {"dma_req_datype" "TUSER"} ] +adi_add_bus "dma_req" "master" \ + "xilinx.com:interface:axis_rtl:1.0" \ + "xilinx.com:interface:axis:1.0" \ + [list {"dma_req_drvalid" "TVALID"} \ + {"dma_req_drready" "TREADY"} \ + {"dma_req_drtype" "TUSER"} \ + {"dma_req_drlast" "TLAST"} ] + +# Clock and reset are for both dma_req and dma_ack +adi_add_bus_clock "dma_req_aclk" "dma_req:dma_ack" "dma_req_rstn" + +adi_set_bus_dependency "s_axis" "s_axis" \ + "(spirit:decode(id('MODELPARAM_VALUE.DMA_TYPE')) = 0)" + +adi_set_bus_dependency "dma_ack" "dma_req_da" \ + "(spirit:decode(id('MODELPARAM_VALUE.DMA_TYPE')) = 1)" +adi_set_bus_dependency "dma_req" "dma_req_dr" \ + "(spirit:decode(id('MODELPARAM_VALUE.DMA_TYPE')) = 1)" +adi_set_ports_dependency "dma_req_aclk" \ + "(spirit:decode(id('MODELPARAM_VALUE.DMA_TYPE')) = 1)" +adi_set_ports_dependency "dma_req_rstn" \ + "(spirit:decode(id('MODELPARAM_VALUE.DMA_TYPE')) = 1)" + +ipx::save_core [ipx::current_core] + diff --git a/src/adi/hdl/library/axi_spdif_tx/tx_encoder.vhd b/src/adi/hdl/library/axi_spdif_tx/tx_encoder.vhd new file mode 100644 index 00000000..898f81ee --- /dev/null +++ b/src/adi/hdl/library/axi_spdif_tx/tx_encoder.vhd @@ -0,0 +1,495 @@ +---------------------------------------------------------------------- +---- ---- +---- WISHBONE SPDIF IP Core ---- +---- ---- +---- This file is part of the SPDIF project ---- +---- http://www.opencores.org/cores/spdif_interface/ ---- +---- ---- +---- Description ---- +---- SPDIF transmitter signal encoder. Reads out samples from the ---- +---- sample buffer, assembles frames and subframes and encodes ---- +---- serial data as bi-phase mark code. ---- +---- ---- +---- To Do: ---- +---- - ---- +---- ---- +---- Author(s): ---- +---- - Geir Drange, gedra@opencores.org ---- +---- ---- +---------------------------------------------------------------------- +---- ---- +---- Copyright (C) 2004 Authors and OPENCORES.ORG ---- +---- ---- +---- This source file may be used and distributed without ---- +---- restriction provided that this copyright statement is not ---- +---- removed from the file and that any derivative work contains ---- +---- the original copyright notice and the associated disclaimer. ---- +---- ---- +---- This source file is free software; you can redistribute it ---- +---- and/or modify it under the terms of the GNU Lesser General ---- +---- Public License as published by the Free Software Foundation; ---- +---- either version 2.1 of the License, or (at your option) any ---- +---- later version. ---- +---- ---- +---- This source 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 Lesser General Public License for more ---- +---- details. ---- +---- ---- +---- You should have received a copy of the GNU Lesser General ---- +---- Public License along with this source; if not, download it ---- +---- from http://www.opencores.org/lgpl.shtml ---- +---- ---- +---------------------------------------------------------------------- +-- +-- CVS Revision History +-- +-- $Log: not supported by cvs2svn $ +-- +-- + +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +entity tx_encoder is + generic (DATA_WIDTH: integer range 16 to 32 := 32); + port ( + up_clk: in std_logic; -- clock + data_clk : in std_logic; -- data clock + resetn : in std_logic; -- resetn + conf_mode: in std_logic_vector(3 downto 0); -- sample format + conf_ratio: in std_logic_vector(7 downto 0); -- clock divider + conf_txdata: in std_logic; -- sample data enable + conf_txen: in std_logic; -- spdif signal enable + chstat_freq: in std_logic_vector(1 downto 0); -- sample freq. + chstat_gstat: in std_logic; -- generation status + chstat_preem: in std_logic; -- preemphasis status + chstat_copy: in std_logic; -- copyright bit + chstat_audio: in std_logic; -- data format + sample_data: in std_logic_vector(DATA_WIDTH - 1 downto 0); -- audio data + sample_data_ack: out std_logic; -- sample buffer read + channel: out std_logic; + spdif_tx_o: out std_logic); +end tx_encoder; + +architecture rtl of tx_encoder is + + signal spdif_clk_en, spdif_out : std_logic; + signal clk_cnt : integer range 0 to 511; + type buf_states is (IDLE, READ_CHA, READ_CHB, CHA_RDY, CHB_RDY); + signal bufctrl : buf_states; + signal cha_samp_ack, chb_samp_ack : std_logic; + type frame_states is (IDLE, BLOCK_START, CHANNEL_A, CHANNEL_B); + signal framest : frame_states; + signal frame_cnt : integer range 0 to 191; + signal bit_cnt, par_cnt : integer range 0 to 31; + signal inv_preamble, toggle, valid : std_logic; + signal def_user_data, def_ch_status : std_logic_vector(191 downto 0); + signal active_user_data, active_ch_status : std_logic_vector(191 downto 0); + signal audio : std_logic_vector(23 downto 0); + signal par_vector : std_logic_vector(26 downto 0); + signal send_audio : std_logic; + + signal cdc_sync_stage0_tick_counter : std_logic := '0'; + signal cdc_sync_stage1_tick_counter : std_logic := '0'; + signal cdc_sync_stage2_tick_counter : std_logic := '0'; + signal cdc_sync_stage3_tick_counter : std_logic := '0'; + signal tick_counter : std_logic; + + constant X_PREAMBLE : std_logic_vector(0 to 7) := "11100010"; + constant Y_PREAMBLE : std_logic_vector(0 to 7) := "11100100"; + constant Z_PREAMBLE : std_logic_vector(0 to 7) := "11101000"; + + function encode_bit ( + signal bit_cnt : integer; -- sub-frame bit position + signal valid : std_logic; -- validity bit + signal frame_cnt : integer; -- frame counter + signal par_cnt : integer; -- parity counter + signal user_data : std_logic_vector(191 downto 0); + signal ch_status : std_logic_vector(191 downto 0); + signal audio : std_logic_vector(23 downto 0); + signal toggle : std_logic; + signal prev_spdif : std_logic) -- prev. value of spdif signal + + return std_logic is + variable spdif, next_bit : std_logic; + begin + if bit_cnt > 3 and bit_cnt < 28 then -- audio part + next_bit := audio(bit_cnt - 4); + elsif bit_cnt = 28 then -- validity bit + next_bit := valid; + elsif bit_cnt = 29 then -- user data + next_bit := user_data(frame_cnt); + elsif bit_cnt = 30 then + next_bit := ch_status(frame_cnt); -- channel status + elsif bit_cnt = 31 then + if par_cnt mod 2 = 1 then + next_bit := '1'; + else + next_bit := '0'; + end if; + end if; + -- bi-phase mark encoding: + if next_bit = '0' then + if toggle = '0' then + spdif := not prev_spdif; + else + spdif := prev_spdif; + end if; + else + spdif := not prev_spdif; + end if; + return(spdif); + end encode_bit; + +begin + +-- SPDIF clock enable generation. The clock is a fraction of the data clock, +-- determined by the conf_ratio value. + DCLK : process (data_clk) + begin + if rising_edge(data_clk) then + cdc_sync_stage0_tick_counter <= not cdc_sync_stage0_tick_counter; + end if; + end process DCLK; + + process (up_clk) begin + if rising_edge(up_clk) then + cdc_sync_stage1_tick_counter <= cdc_sync_stage0_tick_counter; + cdc_sync_stage2_tick_counter <= cdc_sync_stage1_tick_counter; + cdc_sync_stage3_tick_counter <= cdc_sync_stage2_tick_counter; + end if; + end process; + + tick_counter <= cdc_sync_stage3_tick_counter xor cdc_sync_stage2_tick_counter; + + CGEN: process (up_clk) + begin + if rising_edge(up_clk) then + if resetn = '0' or conf_txen = '0' then + clk_cnt <= 0; + spdif_clk_en <= '0'; + else + spdif_clk_en <= '0'; + + if tick_counter = '1' then + if clk_cnt < to_integer(unsigned(conf_ratio)) then + clk_cnt <= clk_cnt + 1; + else + clk_cnt <= 0; + spdif_clk_en <= '1'; + end if; + end if; + end if; + end if; + end process CGEN; + + SRD: process (up_clk) + begin + if rising_edge(up_clk) then + if resetn = '0' or conf_txdata = '0' then + bufctrl <= IDLE; + sample_data_ack <= '0'; + channel <= '0'; + else + case bufctrl is + when IDLE => + sample_data_ack <= '0'; + if conf_txdata = '1' then + bufctrl <= READ_CHA; + sample_data_ack <='1'; + end if; + when READ_CHA => + channel <= '0'; + sample_data_ack <= '0'; + bufctrl <= CHA_RDY; + when CHA_RDY => + if cha_samp_ack = '1' then + sample_data_ack <= '1'; + bufctrl <= READ_CHB; + end if; + when READ_CHB => + channel <= '1'; + sample_data_ack <= '0'; + bufctrl <= CHB_RDY; + when CHB_RDY => + if chb_samp_ack = '1' then + sample_data_ack <= '1'; + bufctrl <= READ_CHA; + end if; + when others => + bufctrl <= IDLE; + end case; + end if; + end if; + end process SRD; + + TXSYNC: process (data_clk) + begin + if (rising_edge(data_clk)) then + spdif_tx_o <= spdif_out; + end if; + end process TXSYNC; + +-- State machine that generates sub-frames and blocks + + FRST: process (up_clk) + begin + if rising_edge(up_clk) then + if resetn = '0' or conf_txen = '0' then + framest <= IDLE; + frame_cnt <= 0; + bit_cnt <= 0; + spdif_out <= '0'; + inv_preamble <= '0'; + toggle <= '0'; + valid <= '1'; + send_audio <= '0'; + cha_samp_ack <= '0'; + chb_samp_ack <= '0'; + else + if spdif_clk_en = '1' then -- SPDIF clock is twice the bit rate + case framest is + when IDLE => + bit_cnt <= 0; + frame_cnt <= 0; + inv_preamble <= '0'; + toggle <= '0'; + framest <= BLOCK_START; + when BLOCK_START => -- Start of channels status block/Ch. A + chb_samp_ack <= '0'; + toggle <= not toggle; -- Each bit uses two clock enables, + if toggle = '1' then -- counted by the toggle bit. + if bit_cnt < 31 then + bit_cnt <= bit_cnt + 1; + else + bit_cnt <= 0; + if send_audio = '1' then + cha_samp_ack <= '1'; + end if; + framest <= CHANNEL_B; + end if; + end if; + -- Block start uses preamble Z. + if bit_cnt < 4 then + if toggle = '0' then + spdif_out <= Z_PREAMBLE(2 * bit_cnt) xor inv_preamble; + else + spdif_out <= Z_PREAMBLE(2 * bit_cnt + 1) xor inv_preamble; + end if; + par_cnt <= 0; + elsif bit_cnt > 3 and bit_cnt <= 31 then + spdif_out <= encode_bit(bit_cnt, valid, frame_cnt, + par_cnt, active_user_data, + active_ch_status, + audio, toggle, spdif_out); + if bit_cnt = 31 then + inv_preamble <= encode_bit(bit_cnt, valid, frame_cnt, + par_cnt, active_user_data, + active_ch_status, + audio, toggle, spdif_out); + end if; + if toggle = '0' then + if bit_cnt > 3 and bit_cnt < 31 and + par_vector(bit_cnt - 4) = '1' then + par_cnt <= par_cnt + 1; + end if; + end if; + end if; + when CHANNEL_A => -- Sub-frame: channel A. + chb_samp_ack <= '0'; + toggle <= not toggle; + if toggle = '1' then + if bit_cnt < 31 then + bit_cnt <= bit_cnt + 1; + else + bit_cnt <= 0; + if spdif_out = '1' then + inv_preamble <= '1'; + else + inv_preamble <= '0'; + end if; + if send_audio = '1' then + cha_samp_ack <= '1'; + end if; + framest <= CHANNEL_B; + end if; + end if; + -- Channel A uses preable X. + if bit_cnt < 4 then + if toggle = '0' then + spdif_out <= X_PREAMBLE(2 * bit_cnt) xor inv_preamble; + else + spdif_out <= X_PREAMBLE(2 * bit_cnt + 1) xor inv_preamble; + end if; + par_cnt <= 0; + elsif bit_cnt > 3 and bit_cnt <= 31 then + spdif_out <= encode_bit(bit_cnt, valid, frame_cnt, + par_cnt, active_user_data, + active_ch_status, + audio, toggle, spdif_out); + if bit_cnt = 31 then + inv_preamble <= encode_bit(bit_cnt, valid, frame_cnt, + par_cnt, active_user_data, + active_ch_status, + audio, toggle, spdif_out); + end if; + if toggle = '0' then + if bit_cnt > 3 and bit_cnt < 31 and + par_vector(bit_cnt - 4) = '1' then + par_cnt <= par_cnt + 1; + end if; + end if; + end if; + when CHANNEL_B => -- Sub-frame: channel B. + cha_samp_ack <= '0'; + toggle <= not toggle; + if toggle = '1' then + if bit_cnt < 31 then + bit_cnt <= bit_cnt + 1; + else + bit_cnt <= 0; + valid <= not conf_txdata; + if spdif_out = '1' then + inv_preamble <= '1'; + else + inv_preamble <= '0'; + end if; + send_audio <= conf_txdata; -- 1 if audio samples sohuld be sent + if send_audio = '1' then + chb_samp_ack <= '1'; + end if; + if frame_cnt < 191 then -- One block is 192 frames + frame_cnt <= frame_cnt + 1; + framest <= CHANNEL_A; + else + frame_cnt <= 0; + framest <= BLOCK_START; + end if; + end if; + end if; + -- Channel B uses preable Y. + if bit_cnt < 4 then + if toggle = '0' then + spdif_out <= Y_PREAMBLE(2 * bit_cnt) xor inv_preamble; + else + spdif_out <= Y_PREAMBLE(2 * bit_cnt + 1) xor inv_preamble; + end if; + par_cnt <= 0; + elsif bit_cnt > 3 and bit_cnt <= 31 then + spdif_out <= encode_bit(bit_cnt, valid, frame_cnt, + par_cnt, active_user_data, + active_ch_status, + audio, toggle, spdif_out); + if bit_cnt = 31 then + inv_preamble <= encode_bit(bit_cnt, valid, frame_cnt, + par_cnt, active_user_data, + active_ch_status, + audio, toggle, spdif_out); + end if; + if toggle = '0' then + if bit_cnt > 3 and bit_cnt < 31 and + par_vector(bit_cnt - 4) = '1' then + par_cnt <= par_cnt + 1; + end if; + end if; + end if; + when others => + framest <= IDLE; + end case; + end if; + end if; + end if; + end process FRST; + +-- Audio data latching + DA32: if DATA_WIDTH = 32 generate + ALAT: process (up_clk) + begin + if rising_edge(up_clk) then + if send_audio = '0' then + audio(23 downto 0) <= (others => '0'); + else + case to_integer(unsigned(conf_mode)) is + when 0 => -- 16 bit audio + audio(23 downto 8) <= sample_data(15 downto 0); + audio(7 downto 0) <= (others => '0'); + when 1 => -- 17 bit audio + audio(23 downto 7) <= sample_data(16 downto 0); + audio(6 downto 0) <= (others => '0'); + when 2 => -- 18 bit audio + audio(23 downto 6) <= sample_data(17 downto 0); + audio(5 downto 0) <= (others => '0'); + when 3 => -- 19 bit audio + audio(23 downto 5) <= sample_data(18 downto 0); + audio(4 downto 0) <= (others => '0'); + when 4 => -- 20 bit audio + audio(23 downto 4) <= sample_data(19 downto 0); + audio(3 downto 0) <= (others => '0'); + when 5 => -- 21 bit audio + audio(23 downto 3) <= sample_data(20 downto 0); + audio(2 downto 0) <= (others => '0'); + when 6 => -- 22 bit audio + audio(23 downto 2) <= sample_data(21 downto 0); + audio(1 downto 0) <= (others => '0'); + when 7 => -- 23 bit audio + audio(23 downto 1) <= sample_data(22 downto 0); + audio(0) <= '0'; + when 8 => -- 24 bit audio + audio(23 downto 0) <= sample_data(23 downto 0); + when others => -- unsupported modes + audio(23 downto 0) <= (others => '0'); + end case; + end if; + end if; + end process ALAT; + end generate DA32; + + DA16: if DATA_WIDTH = 16 generate + ALAT: process (up_clk) + begin + if rising_edge(up_clk) then + if send_audio = '0' then + audio(23 downto 0) <= (others => '0'); + else + audio(23 downto 8) <= sample_data(15 downto 0); + audio(7 downto 0) <= (others => '0'); + end if; + end if; + end process ALAT; + end generate DA16; + +-- Parity vector. These bits are counted to generate even parity + par_vector(23 downto 0) <= audio(23 downto 0); + par_vector(24) <= valid; + par_vector(25) <= active_user_data(frame_cnt); + par_vector(26) <= active_ch_status(frame_cnt); + +-- Channel status and user datat to be used if buffers are disabled. +-- User data is then all zero, while channel status bits are taken from +-- register TxChStat. + def_user_data(191 downto 0) <= (others => '0'); + def_ch_status(0) <= '0'; -- consumer mode + def_ch_status(1) <= chstat_audio; -- audio bit + def_ch_status(2) <= chstat_copy; -- copy right + def_ch_status(5 downto 3) <= "000" when chstat_preem = '0' + else "001"; -- pre-emphasis + def_ch_status(7 downto 6) <= "00"; + def_ch_status(14 downto 8) <= (others => '0'); + def_ch_status(15) <= chstat_gstat; -- generation status + def_ch_status(23 downto 16) <= (others => '0'); + def_ch_status(27 downto 24) <= "0000" when chstat_freq = "00" else + "0010" when chstat_freq = "01" else + "0011" when chstat_freq = "10" else + "0001"; + def_ch_status(191 downto 28) <= (others => '0'); --191 28 + +-- Generate channel status vector based on configuration register setting. + active_ch_status <= def_ch_status; + +-- Generate user data vector based on configuration register setting. + active_user_data <= def_user_data; + +end rtl; diff --git a/src/adi/hdl/library/axi_spdif_tx/tx_package.vhd b/src/adi/hdl/library/axi_spdif_tx/tx_package.vhd new file mode 100644 index 00000000..2e658590 --- /dev/null +++ b/src/adi/hdl/library/axi_spdif_tx/tx_package.vhd @@ -0,0 +1,88 @@ +---------------------------------------------------------------------- +---- ---- +---- WISHBONE SPDIF IP Core ---- +---- ---- +---- This file is part of the SPDIF project ---- +---- http://www.opencores.org/cores/spdif_interface/ ---- +---- ---- +---- Description ---- +---- SPDIF transmitter component package. ---- +---- ---- +---- ---- +---- To Do: ---- +---- - ---- +---- ---- +---- Author(s): ---- +---- - Geir Drange, gedra@opencores.org ---- +---- ---- +---------------------------------------------------------------------- +---- ---- +---- Copyright (C) 2004 Authors and OPENCORES.ORG ---- +---- ---- +---- This source file may be used and distributed without ---- +---- restriction provided that this copyright statement is not ---- +---- removed from the file and that any derivative work contains ---- +---- the original copyright notice and the associated disclaimer. ---- +---- ---- +---- This source file is free software; you can redistribute it ---- +---- and/or modify it under the terms of the GNU Lesser General ---- +---- Public License as published by the Free Software Foundation; ---- +---- either version 2.1 of the License, or (at your option) any ---- +---- later version. ---- +---- ---- +---- This source 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 Lesser General Public License for more ---- +---- details. ---- +---- ---- +---- You should have received a copy of the GNU Lesser General ---- +---- Public License along with this source; if not, download it ---- +---- from http://www.opencores.org/lgpl.shtml ---- +---- ---- +---------------------------------------------------------------------- +-- +-- CVS Revision History +-- +-- $Log: not supported by cvs2svn $ +-- Revision 1.2 2004/07/14 17:58:49 gedra +-- Added new components. +-- +-- Revision 1.1 2004/07/13 18:30:25 gedra +-- Transmitter component declarations. +-- +-- +-- + +library ieee; +use ieee.std_logic_1164.all; + +package tx_package is + + component tx_encoder + generic + ( + DATA_WIDTH: integer range 16 to 32 := 32 + ); + port + ( + up_clk: in std_logic; -- clock + data_clk : in std_logic; -- data clock + resetn : in std_logic; -- resetn + conf_mode: in std_logic_vector(3 downto 0); -- sample format + conf_ratio: in std_logic_vector(7 downto 0); -- clock divider + conf_txdata: in std_logic; -- sample data enable + conf_txen: in std_logic; -- spdif signal enable + chstat_freq: in std_logic_vector(1 downto 0); -- sample freq. + chstat_gstat: in std_logic; -- generation status + chstat_preem: in std_logic; -- preemphasis status + chstat_copy: in std_logic; -- copyright bit + chstat_audio: in std_logic; -- data format + sample_data: in std_logic_vector(DATA_WIDTH - 1 downto 0); -- audio data + sample_data_ack : out std_logic; -- sample buffer read + channel: out std_logic; + spdif_tx_o: out std_logic + ); + end component; + +end tx_package; diff --git a/src/adi/hdl/library/common/ad_addsub.v b/src/adi/hdl/library/common/ad_addsub.v new file mode 100644 index 00000000..250f4576 --- /dev/null +++ b/src/adi/hdl/library/common/ad_addsub.v @@ -0,0 +1,115 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright 2014 - 2017 (c) Analog Devices, Inc. All rights reserved. +// +// In this HDL repository, there are many different and unique modules, consisting +// of various HDL (Verilog or VHDL) components. The individual modules are +// developed independently, and may be accompanied by separate and unique license +// terms. +// +// The user should read each of these license terms, and understand the +// freedoms and responsibilities that he or she has by using this source/core. +// +// This core 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. +// +// Redistribution and use of source or resulting binaries, with or without modification +// of this file, are permitted under one of the following two license terms: +// +// 1. The GNU General Public License version 2 as published by the +// Free Software Foundation, which can be found in the top level directory +// of this repository (LICENSE_GPL2), and also online at: +// +// +// OR +// +// 2. An ADI specific BSD license, which can be found in the top level directory +// of this repository (LICENSE_ADIBSD), and also on-line at: +// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD +// This will allow to generate bit files and not release the source code, +// as long as it attaches to an ADI device. +// +// *************************************************************************** +// *************************************************************************** + +// A simple adder/substracter width preconfigured input ports width and turn-around value +// Output = A - B_constant or A + B_constant +// Constraints: Awidth >= Bwidth + +`timescale 1ns/1ps + +module ad_addsub #( + + parameter A_DATA_WIDTH = 32, + parameter B_DATA_VALUE = 32'h1, + parameter ADD_OR_SUB_N = 0) ( + input clk, + input [(A_DATA_WIDTH-1):0] A, + input [(A_DATA_WIDTH-1):0] Amax, + output reg [(A_DATA_WIDTH-1):0] out, + input CE); + + + localparam ADDER = 1; + localparam SUBSTRACTER = 0; + + // registers + + reg [A_DATA_WIDTH:0] out_d = 'b0; + reg [A_DATA_WIDTH:0] out_d2 = 'b0; + reg [(A_DATA_WIDTH-1):0] A_d = 'b0; + reg [(A_DATA_WIDTH-1):0] Amax_d = 'b0; + reg [(A_DATA_WIDTH-1):0] Amax_d2 = 'b0; + + // constant regs + + reg [(A_DATA_WIDTH-1):0] B_reg = B_DATA_VALUE; + + // latch the inputs + + always @(posedge clk) begin + A_d <= A; + Amax_d <= Amax; + Amax_d2 <= Amax_d; + end + + // ADDER/SUBSTRACTER + + always @(posedge clk) begin + if ( ADD_OR_SUB_N == ADDER ) begin + out_d <= A_d + B_reg; + end else begin + out_d <= A_d - B_reg; + end + end + + // Resolve + + always @(posedge clk) begin + if ( ADD_OR_SUB_N == ADDER ) begin + if ( out_d > Amax_d2 ) begin + out_d2 <= out_d - Amax_d2; + end else begin + out_d2 <= out_d; + end + end else begin // SUBSTRACTER + if ( out_d[A_DATA_WIDTH] == 1'b1 ) begin + out_d2 <= Amax_d2 + out_d; + end else begin + out_d2 <= out_d; + end + end + end + + // output logic + + always @(posedge clk) begin + if ( CE ) begin + out <= out_d2; + end else begin + out <= 'b0; + end + end + +endmodule diff --git a/src/adi/hdl/library/common/ad_adl5904_rst.v b/src/adi/hdl/library/common/ad_adl5904_rst.v new file mode 100644 index 00000000..ce5f7aa2 --- /dev/null +++ b/src/adi/hdl/library/common/ad_adl5904_rst.v @@ -0,0 +1,78 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright 2014 - 2017 (c) Analog Devices, Inc. All rights reserved. +// +// In this HDL repository, there are many different and unique modules, consisting +// of various HDL (Verilog or VHDL) components. The individual modules are +// developed independently, and may be accompanied by separate and unique license +// terms. +// +// The user should read each of these license terms, and understand the +// freedoms and responsibilities that he or she has by using this source/core. +// +// This core 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. +// +// Redistribution and use of source or resulting binaries, with or without modification +// of this file, are permitted under one of the following two license terms: +// +// 1. The GNU General Public License version 2 as published by the +// Free Software Foundation, which can be found in the top level directory +// of this repository (LICENSE_GPL2), and also online at: +// +// +// OR +// +// 2. An ADI specific BSD license, which can be found in the top level directory +// of this repository (LICENSE_ADIBSD), and also on-line at: +// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD +// This will allow to generate bit files and not release the source code, +// as long as it attaches to an ADI device. +// +// *************************************************************************** +// *************************************************************************** + +`timescale 1ns/100ps + +module ad_adl5904_rst ( + + input sys_cpu_clk, + input rf_peak_det_n, + output rf_peak_rst); + + // internal registers + + reg rf_peak_det_n_d = 'd0; + reg rf_peak_det_enb_d = 'd0; + reg rf_peak_rst_enb = 'd0; + reg rf_peak_rst_int = 'd0; + + // internal signals + + wire rf_peak_det_enb_s; + wire rf_peak_rst_1_s; + wire rf_peak_rst_0_s; + + // adl5904 input protection + + assign rf_peak_rst = rf_peak_rst_int; + assign rf_peak_det_enb_s = ~(rf_peak_det_n_d & rf_peak_det_n); + assign rf_peak_rst_1_s = ~rf_peak_det_enb_d & rf_peak_det_enb_s; + assign rf_peak_rst_0_s = rf_peak_det_enb_d & ~rf_peak_det_enb_s; + + always @(posedge sys_cpu_clk) begin + rf_peak_det_n_d <= rf_peak_det_n; + rf_peak_det_enb_d <= rf_peak_det_enb_s; + if (rf_peak_rst_1_s == 1'b1) begin + rf_peak_rst_enb <= 1'b1; + end else if (rf_peak_rst_0_s == 1'b1) begin + rf_peak_rst_enb <= 1'b0; + end + rf_peak_rst_int = ~rf_peak_rst_int & rf_peak_rst_enb; + end + +endmodule + +// *************************************************************************** +// *************************************************************************** diff --git a/src/adi/hdl/library/common/ad_axis_inf_rx.v b/src/adi/hdl/library/common/ad_axis_inf_rx.v new file mode 100644 index 00000000..0b49eb0d --- /dev/null +++ b/src/adi/hdl/library/common/ad_axis_inf_rx.v @@ -0,0 +1,193 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright 2014 - 2017 (c) Analog Devices, Inc. All rights reserved. +// +// In this HDL repository, there are many different and unique modules, consisting +// of various HDL (Verilog or VHDL) components. The individual modules are +// developed independently, and may be accompanied by separate and unique license +// terms. +// +// The user should read each of these license terms, and understand the +// freedoms and responsibilities that he or she has by using this source/core. +// +// This core 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. +// +// Redistribution and use of source or resulting binaries, with or without modification +// of this file, are permitted under one of the following two license terms: +// +// 1. The GNU General Public License version 2 as published by the +// Free Software Foundation, which can be found in the top level directory +// of this repository (LICENSE_GPL2), and also online at: +// +// +// OR +// +// 2. An ADI specific BSD license, which can be found in the top level directory +// of this repository (LICENSE_ADIBSD), and also on-line at: +// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD +// This will allow to generate bit files and not release the source code, +// as long as it attaches to an ADI device. +// +// *************************************************************************** +// *************************************************************************** + +`timescale 1ns/100ps + +module ad_axis_inf_rx #( + + parameter DATA_WIDTH = 16) ( + + // adi interface + + input clk, + input rst, + input valid, + input last, + input [(DATA_WIDTH-1):0] data, + + // xilinx interface + + output reg inf_valid, + output reg inf_last, + output reg [(DATA_WIDTH-1):0] inf_data, + input inf_ready); + + // internal registers + + reg [ 2:0] wcnt = 'd0; + reg wlast_0 = 'd0; + reg [(DATA_WIDTH-1):0] wdata_0 = 'd0; + reg wlast_1 = 'd0; + reg [(DATA_WIDTH-1):0] wdata_1 = 'd0; + reg wlast_2 = 'd0; + reg [(DATA_WIDTH-1):0] wdata_2 = 'd0; + reg wlast_3 = 'd0; + reg [(DATA_WIDTH-1):0] wdata_3 = 'd0; + reg wlast_4 = 'd0; + reg [(DATA_WIDTH-1):0] wdata_4 = 'd0; + reg wlast_5 = 'd0; + reg [(DATA_WIDTH-1):0] wdata_5 = 'd0; + reg wlast_6 = 'd0; + reg [(DATA_WIDTH-1):0] wdata_6 = 'd0; + reg wlast_7 = 'd0; + reg [(DATA_WIDTH-1):0] wdata_7 = 'd0; + reg [ 2:0] rcnt = 'd0; + + // internal signals + + wire inf_ready_s; + reg inf_last_s; + reg [(DATA_WIDTH-1):0] inf_data_s; + + // write interface + + always @(posedge clk) begin + if (rst == 1'b1) begin + wcnt <= 'd0; + end else if (valid == 1'b1) begin + wcnt <= wcnt + 1'b1; + end + if ((wcnt == 3'd0) && (valid == 1'b1)) begin + wlast_0 <= last; + wdata_0 <= data; + end + if ((wcnt == 3'd1) && (valid == 1'b1)) begin + wlast_1 <= last; + wdata_1 <= data; + end + if ((wcnt == 3'd2) && (valid == 1'b1)) begin + wlast_2 <= last; + wdata_2 <= data; + end + if ((wcnt == 3'd3) && (valid == 1'b1)) begin + wlast_3 <= last; + wdata_3 <= data; + end + if ((wcnt == 3'd4) && (valid == 1'b1)) begin + wlast_4 <= last; + wdata_4 <= data; + end + if ((wcnt == 3'd5) && (valid == 1'b1)) begin + wlast_5 <= last; + wdata_5 <= data; + end + if ((wcnt == 3'd6) && (valid == 1'b1)) begin + wlast_6 <= last; + wdata_6 <= data; + end + if ((wcnt == 3'd7) && (valid == 1'b1)) begin + wlast_7 <= last; + wdata_7 <= data; + end + end + + // read interface + + assign inf_ready_s = inf_ready | ~inf_valid; + + always @(rcnt or wlast_0 or wdata_0 or wlast_1 or wdata_1 or + wlast_2 or wdata_2 or wlast_3 or wdata_3 or wlast_4 or wdata_4 or + wlast_5 or wdata_5 or wlast_6 or wdata_6 or wlast_7 or wdata_7) begin + case (rcnt) + 3'd0: begin + inf_last_s = wlast_0; + inf_data_s = wdata_0; + end + 3'd1: begin + inf_last_s = wlast_1; + inf_data_s = wdata_1; + end + 3'd2: begin + inf_last_s = wlast_2; + inf_data_s = wdata_2; + end + 3'd3: begin + inf_last_s = wlast_3; + inf_data_s = wdata_3; + end + 3'd4: begin + inf_last_s = wlast_4; + inf_data_s = wdata_4; + end + 3'd5: begin + inf_last_s = wlast_5; + inf_data_s = wdata_5; + end + 3'd6: begin + inf_last_s = wlast_6; + inf_data_s = wdata_6; + end + default: begin + inf_last_s = wlast_7; + inf_data_s = wdata_7; + end + endcase + end + + always @(posedge clk) begin + if (rst == 1'b1) begin + rcnt <= 'd0; + inf_valid <= 'd0; + inf_last <= 'b0; + inf_data <= 'd0; + end else if (inf_ready_s == 1'b1) begin + if (rcnt == wcnt) begin + rcnt <= rcnt; + inf_valid <= 1'd0; + inf_last <= 1'b0; + inf_data <= 'd0; + end else begin + rcnt <= rcnt + 1'b1; + inf_valid <= 1'b1; + inf_last <= inf_last_s; + inf_data <= inf_data_s; + end + end + end + +endmodule + +// *************************************************************************** +// *************************************************************************** diff --git a/src/adi/hdl/library/common/ad_b2g.v b/src/adi/hdl/library/common/ad_b2g.v new file mode 100644 index 00000000..15f68c0f --- /dev/null +++ b/src/adi/hdl/library/common/ad_b2g.v @@ -0,0 +1,59 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright 2014 - 2017 (c) Analog Devices, Inc. All rights reserved. +// +// In this HDL repository, there are many different and unique modules, consisting +// of various HDL (Verilog or VHDL) components. The individual modules are +// developed independently, and may be accompanied by separate and unique license +// terms. +// +// The user should read each of these license terms, and understand the +// freedoms and responsibilities that he or she has by using this source/core. +// +// This core 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. +// +// Redistribution and use of source or resulting binaries, with or without modification +// of this file, are permitted under one of the following two license terms: +// +// 1. The GNU General Public License version 2 as published by the +// Free Software Foundation, which can be found in the top level directory +// of this repository (LICENSE_GPL2), and also online at: +// +// +// OR +// +// 2. An ADI specific BSD license, which can be found in the top level directory +// of this repository (LICENSE_ADIBSD), and also on-line at: +// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD +// This will allow to generate bit files and not release the source code, +// as long as it attaches to an ADI device. +// +// *************************************************************************** +// *************************************************************************** + +`timescale 1ns/100ps + +module ad_b2g #( + + parameter DATA_WIDTH = 8) ( + + input [DATA_WIDTH-1:0] din, + output [DATA_WIDTH-1:0] dout); + + function [DATA_WIDTH-1:0] b2g; + input [DATA_WIDTH-1:0] b; + integer i; + begin + b2g[DATA_WIDTH-1] = b[DATA_WIDTH-1]; + for (i = DATA_WIDTH-1; i > 0; i = i -1) begin + b2g[i-1] = b[i] ^ b[i-1]; + end + end + endfunction + + assign dout = b2g(din); + +endmodule + diff --git a/src/adi/hdl/library/common/ad_csc_1.v b/src/adi/hdl/library/common/ad_csc_1.v new file mode 100644 index 00000000..3cacf023 --- /dev/null +++ b/src/adi/hdl/library/common/ad_csc_1.v @@ -0,0 +1,115 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright 2014 - 2017 (c) Analog Devices, Inc. All rights reserved. +// +// In this HDL repository, there are many different and unique modules, consisting +// of various HDL (Verilog or VHDL) components. The individual modules are +// developed independently, and may be accompanied by separate and unique license +// terms. +// +// The user should read each of these license terms, and understand the +// freedoms and responsibilities that he or she has by using this source/core. +// +// This core 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. +// +// Redistribution and use of source or resulting binaries, with or without modification +// of this file, are permitted under one of the following two license terms: +// +// 1. The GNU General Public License version 2 as published by the +// Free Software Foundation, which can be found in the top level directory +// of this repository (LICENSE_GPL2), and also online at: +// +// +// OR +// +// 2. An ADI specific BSD license, which can be found in the top level directory +// of this repository (LICENSE_ADIBSD), and also on-line at: +// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD +// This will allow to generate bit files and not release the source code, +// as long as it attaches to an ADI device. +// +// *************************************************************************** +// *************************************************************************** +// csc = c1*d[23:16] + c2*d[15:8] + c3*d[7:0] + c4; + +`timescale 1ns/100ps + +module ad_csc_1 #( + + parameter DELAY_DATA_WIDTH = 16) ( + + // data + + input clk, + input [DW:0] sync, + input [23:0] data, + + // constants + + input [16:0] C1, + input [16:0] C2, + input [16:0] C3, + input [24:0] C4, + + // sync is delay matched + + output [DW:0] csc_sync_1, + output [ 7:0] csc_data_1); + + localparam DW = DELAY_DATA_WIDTH - 1; + + // internal wires + + wire [24:0] data_1_m_s; + wire [24:0] data_2_m_s; + wire [24:0] data_3_m_s; + wire [DW:0] sync_3_m_s; + + // c1*R + + ad_csc_1_mul #(.DELAY_DATA_WIDTH(1)) i_mul_c1 ( + .clk (clk), + .data_a (C1), + .data_b (data[23:16]), + .data_p (data_1_m_s), + .ddata_in (1'd0), + .ddata_out ()); + + // c2*G + + ad_csc_1_mul #(.DELAY_DATA_WIDTH(1)) i_mul_c2 ( + .clk (clk), + .data_a (C2), + .data_b (data[15:8]), + .data_p (data_2_m_s), + .ddata_in (1'd0), + .ddata_out ()); + + // c3*B + + ad_csc_1_mul #(.DELAY_DATA_WIDTH(DELAY_DATA_WIDTH)) i_mul_c3 ( + .clk (clk), + .data_a (C3), + .data_b (data[7:0]), + .data_p (data_3_m_s), + .ddata_in (sync), + .ddata_out (sync_3_m_s)); + + // sum + c4 + + ad_csc_1_add #(.DELAY_DATA_WIDTH(DELAY_DATA_WIDTH)) i_add_c4 ( + .clk (clk), + .data_1 (data_1_m_s), + .data_2 (data_2_m_s), + .data_3 (data_3_m_s), + .data_4 (C4), + .data_p (csc_data_1), + .ddata_in (sync_3_m_s), + .ddata_out (csc_sync_1)); + +endmodule + +// *************************************************************************** +// *************************************************************************** diff --git a/src/adi/hdl/library/common/ad_csc_1_add.v b/src/adi/hdl/library/common/ad_csc_1_add.v new file mode 100644 index 00000000..3acb3970 --- /dev/null +++ b/src/adi/hdl/library/common/ad_csc_1_add.v @@ -0,0 +1,147 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright 2014 - 2017 (c) Analog Devices, Inc. All rights reserved. +// +// In this HDL repository, there are many different and unique modules, consisting +// of various HDL (Verilog or VHDL) components. The individual modules are +// developed independently, and may be accompanied by separate and unique license +// terms. +// +// The user should read each of these license terms, and understand the +// freedoms and responsibilities that he or she has by using this source/core. +// +// This core 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. +// +// Redistribution and use of source or resulting binaries, with or without modification +// of this file, are permitted under one of the following two license terms: +// +// 1. The GNU General Public License version 2 as published by the +// Free Software Foundation, which can be found in the top level directory +// of this repository (LICENSE_GPL2), and also online at: +// +// +// OR +// +// 2. An ADI specific BSD license, which can be found in the top level directory +// of this repository (LICENSE_ADIBSD), and also on-line at: +// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD +// This will allow to generate bit files and not release the source code, +// as long as it attaches to an ADI device. +// +// *************************************************************************** +// *************************************************************************** +// Color Space Conversion, adder. This is a simple adder, but had to be +// pipe-lined for faster clock rates. The delay input is delay-matched to +// the sum pipe-line stages + +`timescale 1ps/1ps + +module ad_csc_1_add #( + + parameter DELAY_DATA_WIDTH = 16) ( + + // all signed + + input clk, + input [24:0] data_1, + input [24:0] data_2, + input [24:0] data_3, + input [24:0] data_4, + output reg [ 7:0] data_p, + + // delay match + + input [DW:0] ddata_in, + output reg [DW:0] ddata_out); + + localparam DW = DELAY_DATA_WIDTH - 1; + + // internal registers + + reg [DW:0] p1_ddata = 'd0; + reg [24:0] p1_data_1 = 'd0; + reg [24:0] p1_data_2 = 'd0; + reg [24:0] p1_data_3 = 'd0; + reg [24:0] p1_data_4 = 'd0; + reg [DW:0] p2_ddata = 'd0; + reg [24:0] p2_data_0 = 'd0; + reg [24:0] p2_data_1 = 'd0; + reg [DW:0] p3_ddata = 'd0; + reg [24:0] p3_data = 'd0; + + // internal signals + + wire [24:0] p1_data_1_p_s; + wire [24:0] p1_data_1_n_s; + wire [24:0] p1_data_1_s; + wire [24:0] p1_data_2_p_s; + wire [24:0] p1_data_2_n_s; + wire [24:0] p1_data_2_s; + wire [24:0] p1_data_3_p_s; + wire [24:0] p1_data_3_n_s; + wire [24:0] p1_data_3_s; + wire [24:0] p1_data_4_p_s; + wire [24:0] p1_data_4_n_s; + wire [24:0] p1_data_4_s; + + // pipe line stage 1, get the two's complement versions + + assign p1_data_1_p_s = {1'b0, data_1[23:0]}; + assign p1_data_1_n_s = ~p1_data_1_p_s + 1'b1; + assign p1_data_1_s = (data_1[24] == 1'b1) ? p1_data_1_n_s : p1_data_1_p_s; + + assign p1_data_2_p_s = {1'b0, data_2[23:0]}; + assign p1_data_2_n_s = ~p1_data_2_p_s + 1'b1; + assign p1_data_2_s = (data_2[24] == 1'b1) ? p1_data_2_n_s : p1_data_2_p_s; + + assign p1_data_3_p_s = {1'b0, data_3[23:0]}; + assign p1_data_3_n_s = ~p1_data_3_p_s + 1'b1; + assign p1_data_3_s = (data_3[24] == 1'b1) ? p1_data_3_n_s : p1_data_3_p_s; + + assign p1_data_4_p_s = {1'b0, data_4[23:0]}; + assign p1_data_4_n_s = ~p1_data_4_p_s + 1'b1; + assign p1_data_4_s = (data_4[24] == 1'b1) ? p1_data_4_n_s : p1_data_4_p_s; + + always @(posedge clk) begin + p1_ddata <= ddata_in; + p1_data_1 <= p1_data_1_s; + p1_data_2 <= p1_data_2_s; + p1_data_3 <= p1_data_3_s; + p1_data_4 <= p1_data_4_s; + end + + // pipe line stage 2, get the sum (intermediate, 4->2) + + always @(posedge clk) begin + p2_ddata <= p1_ddata; + p2_data_0 <= p1_data_1 + p1_data_2; + p2_data_1 <= p1_data_3 + p1_data_4; + end + + // pipe line stage 3, get the sum (final, 2->1) + + always @(posedge clk) begin + p3_ddata <= p2_ddata; + p3_data <= p2_data_0 + p2_data_1; + end + + // output registers, output is unsigned (0 if sum is < 0) and saturated. + // the inputs are expected to be 1.4.20 format (output is 8bits). + + always @(posedge clk) begin + ddata_out <= p3_ddata; + if (p3_data[24] == 1'b1) begin + data_p <= 8'h00; + end else if (p3_data[23:20] == 'd0) begin + data_p <= p3_data[19:12]; + end else begin + data_p <= 8'hff; + end + end + +endmodule + +// *************************************************************************** +// *************************************************************************** diff --git a/src/adi/hdl/library/common/ad_csc_1_mul.v b/src/adi/hdl/library/common/ad_csc_1_mul.v new file mode 100644 index 00000000..5847e128 --- /dev/null +++ b/src/adi/hdl/library/common/ad_csc_1_mul.v @@ -0,0 +1,97 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright 2014 - 2017 (c) Analog Devices, Inc. All rights reserved. +// +// In this HDL repository, there are many different and unique modules, consisting +// of various HDL (Verilog or VHDL) components. The individual modules are +// developed independently, and may be accompanied by separate and unique license +// terms. +// +// The user should read each of these license terms, and understand the +// freedoms and responsibilities that he or she has by using this source/core. +// +// This core 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. +// +// Redistribution and use of source or resulting binaries, with or without modification +// of this file, are permitted under one of the following two license terms: +// +// 1. The GNU General Public License version 2 as published by the +// Free Software Foundation, which can be found in the top level directory +// of this repository (LICENSE_GPL2), and also online at: +// +// +// OR +// +// 2. An ADI specific BSD license, which can be found in the top level directory +// of this repository (LICENSE_ADIBSD), and also on-line at: +// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD +// This will allow to generate bit files and not release the source code, +// as long as it attaches to an ADI device. +// +// *************************************************************************** +// *************************************************************************** +// Color Space Conversion, multiplier. This is a simple partial product adder +// that generates the product of the two inputs. + +`timescale 1ps/1ps + +module ad_csc_1_mul #( + + parameter DELAY_DATA_WIDTH = 16) ( + + // data_a is signed + + input clk, + input [16:0] data_a, + input [ 7:0] data_b, + output [24:0] data_p, + + // delay match + + input [(DELAY_DATA_WIDTH-1):0] ddata_in, + output [(DELAY_DATA_WIDTH-1):0] ddata_out); + + // internal registers + + reg [(DELAY_DATA_WIDTH-1):0] p1_ddata = 'd0; + reg [(DELAY_DATA_WIDTH-1):0] p2_ddata = 'd0; + reg [(DELAY_DATA_WIDTH-1):0] p3_ddata = 'd0; + reg p1_sign = 'd0; + reg p2_sign = 'd0; + reg p3_sign = 'd0; + + // internal signals + + wire [33:0] p3_data_s; + + // a/b reg, m-reg, p-reg delay match + + always @(posedge clk) begin + p1_ddata <= ddata_in; + p2_ddata <= p1_ddata; + p3_ddata <= p2_ddata; + end + + always @(posedge clk) begin + p1_sign <= data_a[16]; + p2_sign <= p1_sign; + p3_sign <= p2_sign; + end + + assign ddata_out = p3_ddata; + assign data_p = {p3_sign, p3_data_s[23:0]}; + + ad_mul ad_mul_1 ( + .clk(clk), + .data_a({1'b0, data_a[15:0]}), + .data_b({9'b0, data_b}), + .data_p(p3_data_s), + .ddata_in(16'h0), + .ddata_out()); + +endmodule + +// *************************************************************************** +// *************************************************************************** diff --git a/src/adi/hdl/library/common/ad_csc_CrYCb2RGB.v b/src/adi/hdl/library/common/ad_csc_CrYCb2RGB.v new file mode 100644 index 00000000..12ec8c07 --- /dev/null +++ b/src/adi/hdl/library/common/ad_csc_CrYCb2RGB.v @@ -0,0 +1,103 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright 2014 - 2017 (c) Analog Devices, Inc. All rights reserved. +// +// In this HDL repository, there are many different and unique modules, consisting +// of various HDL (Verilog or VHDL) components. The individual modules are +// developed independently, and may be accompanied by separate and unique license +// terms. +// +// The user should read each of these license terms, and understand the +// freedoms and responsibilities that he or she has by using this source/core. +// +// This core 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. +// +// Redistribution and use of source or resulting binaries, with or without modification +// of this file, are permitted under one of the following two license terms: +// +// 1. The GNU General Public License version 2 as published by the +// Free Software Foundation, which can be found in the top level directory +// of this repository (LICENSE_GPL2), and also online at: +// +// +// OR +// +// 2. An ADI specific BSD license, which can be found in the top level directory +// of this repository (LICENSE_ADIBSD), and also on-line at: +// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD +// This will allow to generate bit files and not release the source code, +// as long as it attaches to an ADI device. +// +// *************************************************************************** +// *************************************************************************** +// Transmit HDMI, CrYCb to RGB conversion +// The multiplication coefficients are in 1.4.12 format +// The addition coefficients are in 1.12.12 format +// R = (+408.583/256)*Cr + (+298.082/256)*Y + ( 000.000/256)*Cb + (-222.921); +// G = (-208.120/256)*Cr + (+298.082/256)*Y + (-100.291/256)*Cb + (+135.576); +// B = ( 000.000/256)*Cr + (+298.082/256)*Y + (+516.412/256)*Cb + (-276.836); + +`timescale 1ns/100ps + +module ad_csc_CrYCb2RGB #( + + parameter DELAY_DATA_WIDTH = 16) ( + + // Cr-Y-Cb inputs + + input clk, + input [DW:0] CrYCb_sync, + input [23:0] CrYCb_data, + + // R-G-B outputs + + output [DW:0] RGB_sync, + output [23:0] RGB_data); + + localparam DW = DELAY_DATA_WIDTH - 1; + + // red + + ad_csc_1 #(.DELAY_DATA_WIDTH(DELAY_DATA_WIDTH)) i_csc_1_R ( + .clk (clk), + .sync (CrYCb_sync), + .data (CrYCb_data), + .C1 (17'h01989), + .C2 (17'h012a1), + .C3 (17'h00000), + .C4 (25'h10deebc), + .csc_sync_1 (RGB_sync), + .csc_data_1 (RGB_data[23:16])); + + // green + + ad_csc_1 #(.DELAY_DATA_WIDTH(1)) i_csc_1_G ( + .clk (clk), + .sync (1'd0), + .data (CrYCb_data), + .C1 (17'h10d01), + .C2 (17'h012a1), + .C3 (17'h10644), + .C4 (25'h0087937), + .csc_sync_1 (), + .csc_data_1 (RGB_data[15:8])); + + // blue + + ad_csc_1 #(.DELAY_DATA_WIDTH(1)) i_csc_1_B ( + .clk (clk), + .sync (1'd0), + .data (CrYCb_data), + .C1 (17'h00000), + .C2 (17'h012a1), + .C3 (17'h02046), + .C4 (25'h1114d60), + .csc_sync_1 (), + .csc_data_1 (RGB_data[7:0])); + +endmodule + +// *************************************************************************** +// *************************************************************************** diff --git a/src/adi/hdl/library/common/ad_csc_RGB2CrYCb.v b/src/adi/hdl/library/common/ad_csc_RGB2CrYCb.v new file mode 100644 index 00000000..4b7e90ee --- /dev/null +++ b/src/adi/hdl/library/common/ad_csc_RGB2CrYCb.v @@ -0,0 +1,103 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright 2014 - 2017 (c) Analog Devices, Inc. All rights reserved. +// +// In this HDL repository, there are many different and unique modules, consisting +// of various HDL (Verilog or VHDL) components. The individual modules are +// developed independently, and may be accompanied by separate and unique license +// terms. +// +// The user should read each of these license terms, and understand the +// freedoms and responsibilities that he or she has by using this source/core. +// +// This core 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. +// +// Redistribution and use of source or resulting binaries, with or without modification +// of this file, are permitted under one of the following two license terms: +// +// 1. The GNU General Public License version 2 as published by the +// Free Software Foundation, which can be found in the top level directory +// of this repository (LICENSE_GPL2), and also online at: +// +// +// OR +// +// 2. An ADI specific BSD license, which can be found in the top level directory +// of this repository (LICENSE_ADIBSD), and also on-line at: +// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD +// This will allow to generate bit files and not release the source code, +// as long as it attaches to an ADI device. +// +// *************************************************************************** +// *************************************************************************** +// Transmit HDMI, RGB to CrYCb conversion +// The multiplication coefficients are in 1.4.12 format +// The addition coefficients are in 1.12.12 format +// Cr = (+112.439/256)*R + (-094.154/256)*G + (-018.285/256)*B + 128; +// Y = (+065.738/256)*R + (+129.057/256)*G + (+025.064/256)*B + 16; +// Cb = (-037.945/256)*R + (-074.494/256)*G + (+112.439/256)*B + 128; + +`timescale 1ns/100ps + +module ad_csc_RGB2CrYCb #( + + parameter DELAY_DATA_WIDTH = 16) ( + + // R-G-B inputs + + input clk, + input [DW:0] RGB_sync, + input [23:0] RGB_data, + + // Cr-Y-Cb outputs + + output [DW:0] CrYCb_sync, + output [23:0] CrYCb_data); + + localparam DW = DELAY_DATA_WIDTH - 1; + + // Cr (red-diff) + + ad_csc_1 #(.DELAY_DATA_WIDTH(DELAY_DATA_WIDTH)) i_csc_1_Cr ( + .clk (clk), + .sync (RGB_sync), + .data (RGB_data), + .C1 (17'h00707), + .C2 (17'h105e2), + .C3 (17'h10124), + .C4 (25'h0080000), + .csc_sync_1 (CrYCb_sync), + .csc_data_1 (CrYCb_data[23:16])); + + // Y (luma) + + ad_csc_1 #(.DELAY_DATA_WIDTH(1)) i_csc_1_Y ( + .clk (clk), + .sync (1'd0), + .data (RGB_data), + .C1 (17'h0041b), + .C2 (17'h00810), + .C3 (17'h00191), + .C4 (25'h0010000), + .csc_sync_1 (), + .csc_data_1 (CrYCb_data[15:8])); + + // Cb (blue-diff) + + ad_csc_1 #(.DELAY_DATA_WIDTH(1)) i_csc_1_Cb ( + .clk (clk), + .sync (1'd0), + .data (RGB_data), + .C1 (17'h1025f), + .C2 (17'h104a7), + .C3 (17'h00707), + .C4 (25'h0080000), + .csc_sync_1 (), + .csc_data_1 (CrYCb_data[7:0])); + +endmodule + +// *************************************************************************** +// *************************************************************************** diff --git a/src/adi/hdl/library/common/ad_datafmt.v b/src/adi/hdl/library/common/ad_datafmt.v new file mode 100644 index 00000000..0d47f7f8 --- /dev/null +++ b/src/adi/hdl/library/common/ad_datafmt.v @@ -0,0 +1,108 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright 2014 - 2017 (c) Analog Devices, Inc. All rights reserved. +// +// In this HDL repository, there are many different and unique modules, consisting +// of various HDL (Verilog or VHDL) components. The individual modules are +// developed independently, and may be accompanied by separate and unique license +// terms. +// +// The user should read each of these license terms, and understand the +// freedoms and responsibilities that he or she has by using this source/core. +// +// This core 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. +// +// Redistribution and use of source or resulting binaries, with or without modification +// of this file, are permitted under one of the following two license terms: +// +// 1. The GNU General Public License version 2 as published by the +// Free Software Foundation, which can be found in the top level directory +// of this repository (LICENSE_GPL2), and also online at: +// +// +// OR +// +// 2. An ADI specific BSD license, which can be found in the top level directory +// of this repository (LICENSE_ADIBSD), and also on-line at: +// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD +// This will allow to generate bit files and not release the source code, +// as long as it attaches to an ADI device. +// +// *************************************************************************** +// *************************************************************************** +// data format (offset binary or 2's complement only) + +`timescale 1ps/1ps + +module ad_datafmt #( + + // data bus width + + parameter DATA_WIDTH = 16, + parameter DISABLE = 0) ( + + // data path + + input clk, + input valid, + input [(DATA_WIDTH-1):0] data, + output valid_out, + output [15:0] data_out, + + // control signals + + input dfmt_enable, + input dfmt_type, + input dfmt_se); + + // internal registers + + reg valid_int = 'd0; + reg [15:0] data_int = 'd0; + + // internal signals + + wire type_s; + wire [15:0] data_out_s; + + // data-path disable + + generate + if (DISABLE == 1) begin + assign valid_out = valid; + assign data_out = data; + end else begin + assign valid_out = valid_int; + assign data_out = data_int; + end + endgenerate + + // if offset-binary convert to 2's complement first + + assign type_s = dfmt_enable & dfmt_type; + + generate + if (DATA_WIDTH < 16) begin + wire signext_s; + wire sign_s; + + assign signext_s = dfmt_enable & dfmt_se; + assign sign_s = signext_s & (type_s ^ data[(DATA_WIDTH-1)]); + assign data_out_s[15:DATA_WIDTH] = {(16-DATA_WIDTH){sign_s}}; + end + endgenerate + + assign data_out_s[(DATA_WIDTH-1)] = type_s ^ data[(DATA_WIDTH-1)]; + assign data_out_s[(DATA_WIDTH-2):0] = data[(DATA_WIDTH-2):0]; + + always @(posedge clk) begin + valid_int <= valid; + data_int <= data_out_s[15:0]; + end + +endmodule + +// *************************************************************************** +// *************************************************************************** diff --git a/src/adi/hdl/library/common/ad_dds.v b/src/adi/hdl/library/common/ad_dds.v new file mode 100644 index 00000000..76cf18aa --- /dev/null +++ b/src/adi/hdl/library/common/ad_dds.v @@ -0,0 +1,132 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright 2014 - 2018 (c) Analog Devices, Inc. All rights reserved. +// +// In this HDL repository, there are many different and unique modules, consisting +// of various HDL (Verilog or VHDL) components. The individual modules are +// developed independently, and may be accompanied by separate and unique license +// terms. +// +// The user should read each of these license terms, and understand the +// freedoms and responsibilities that he or she has by using this source/core. +// +// This core 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. +// +// Redistribution and use of source or resulting binaries, with or without modification +// of this file, are permitted under one of the following two license terms: +// +// 1. The GNU General Public License version 2 as published by the +// Free Software Foundation, which can be found in the top level directory +// of this repository (LICENSE_GPL2), and also online at: +// +// +// OR +// +// 2. An ADI specific BSD license, which can be found in the top level directory +// of this repository (LICENSE_ADIBSD), and also on-line at: +// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD +// This will allow to generate bit files and not release the source code, +// as long as it attaches to an ADI device. +// +// *************************************************************************** +// *************************************************************************** + +`timescale 1ns/100ps + +// single channel dds (dual tone) +module ad_dds #( + + parameter DISABLE = 0, + // range 8-24 + parameter DDS_DW = 16, + // range 8-16 (FIX ME) + parameter PHASE_DW = 16, + // set 1 for CORDIC or 2 for Polynomial + parameter DDS_TYPE = 1, + // range 8-24 + parameter CORDIC_DW = 16, + // range 8-24 (make sure CORDIC_PHASE_DW < CORDIC_DW) + parameter CORDIC_PHASE_DW = 16, + // the clock radtio between the device clock(sample rate) and the dac_core clock + // 2^N, 1 1)begin + dac_dds_phase_0[i] <= dac_dds_phase_0[i-1] + tone_1_freq_word; + dac_dds_phase_1[i] <= dac_dds_phase_1[i-1] + tone_2_freq_word; + end + end else if (dac_valid == 1'b1) begin + dac_dds_phase_0[i] <= dac_dds_phase_0[i] + dac_dds_incr_0; + dac_dds_phase_1[i] <= dac_dds_phase_1[i] + dac_dds_incr_1; + end + end + + // phase to amplitude convertor + ad_dds_2 #( + .DDS_DW (DDS_DW), + .PHASE_DW (PHASE_DW), + .DDS_TYPE (DDS_TYPE), + .CORDIC_DW (CORDIC_DW), + .CORDIC_PHASE_DW (CORDIC_PHASE_DW)) + i_dds_2 ( + .clk (clk), + .dds_format (dac_dds_format), + .dds_phase_0 (dac_dds_phase_0[i]), + .dds_scale_0 (tone_1_scale), + .dds_phase_1 (dac_dds_phase_1[i]), + .dds_scale_1 (tone_2_scale), + .dds_data (dac_dds_data_s[(DDS_DW*i)-1:DDS_DW*(i-1)])); + end + end + endgenerate + +endmodule diff --git a/src/adi/hdl/library/common/ad_dds_1.v b/src/adi/hdl/library/common/ad_dds_1.v new file mode 100644 index 00000000..7c41b15e --- /dev/null +++ b/src/adi/hdl/library/common/ad_dds_1.v @@ -0,0 +1,115 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright 2014 - 2018 (c) Analog Devices, Inc. All rights reserved. +// +// In this HDL repository, there are many different and unique modules, consisting +// of various HDL (Verilog or VHDL) components. The individual modules are +// developed independently, and may be accompanied by separate and unique license +// terms. +// +// The user should read each of these license terms, and understand the +// freedoms and responsibilities that he or she has by using this source/core. +// +// This core 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. +// +// Redistribution and use of source or resulting binaries, with or without modification +// of this file, are permitted under one of the following two license terms: +// +// 1. The GNU General Public License version 2 as published by the +// Free Software Foundation, which can be found in the top level directory +// of this repository (LICENSE_GPL2), and also online at: +// +// +// OR +// +// 2. An ADI specific BSD license, which can be found in the top level directory +// of this repository (LICENSE_ADIBSD), and also on-line at: +// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD +// This will allow to generate bit files and not release the source code, +// as long as it attaches to an ADI device. +// +// *************************************************************************** +// *************************************************************************** + +`timescale 1ns/100ps + +module ad_dds_1 #( + + // parameters + + parameter DDS_TYPE = 1, + parameter DDS_D_DW = 16, + parameter DDS_P_DW = 16) ( + + // interface + + input clk, + input [DDS_P_DW-1:0] angle, + input [ 15:0] scale, + output reg [DDS_D_DW-1:0] dds_data); + + // local parameters + + localparam DDS_CORDIC_TYPE = 1; + localparam DDS_POLINOMIAL_TYPE = 2; + + // internal signals + + wire [ DDS_D_DW-1:0] sine_s; + wire [DDS_D_DW+17:0] s1_data_s; + + // sine + + generate + if (DDS_TYPE == DDS_CORDIC_TYPE) begin + + ad_dds_sine_cordic #( + .CORDIC_DW(DDS_D_DW), + .PHASE_DW(DDS_P_DW), + .DELAY_DW(1)) + i_dds_sine ( + .clk (clk), + .angle (angle), + .sine (sine_s), + .cosine (), + .ddata_in (1'b0), + .ddata_out ()); + + end else begin + + ad_dds_sine i_dds_sine ( + .clk (clk), + .angle (angle), + .sine (sine_s), + .ddata_in (1'b0), + .ddata_out ()); + end + endgenerate + + // scale for a sine generator + + ad_mul #( + .A_DATA_WIDTH(DDS_D_DW + 1), + .B_DATA_WIDTH(17), + .DELAY_DATA_WIDTH(1)) + i_dds_scale ( + .clk (clk), + .data_a ({sine_s[DDS_D_DW-1], sine_s}), + .data_b ({scale[15], scale}), + .data_p (s1_data_s), + .ddata_in (1'b0), + .ddata_out ()); + + // dds data + + always @(posedge clk) begin + //15'h8000 is the maximum scale + dds_data <= s1_data_s[DDS_D_DW+13:14]; + end + +endmodule + +// *************************************************************************** +// *************************************************************************** diff --git a/src/adi/hdl/library/common/ad_dds_2.v b/src/adi/hdl/library/common/ad_dds_2.v new file mode 100644 index 00000000..3f965bc3 --- /dev/null +++ b/src/adi/hdl/library/common/ad_dds_2.v @@ -0,0 +1,156 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright 2014 - 2017 (c) Analog Devices, Inc. All rights reserved. +// +// In this HDL repository, there are many different and unique modules, consisting +// of various HDL (Verilog or VHDL) components. The individual modules are +// developed independently, and may be accompanied by separate and unique license +// terms. +// +// The user should read each of these license terms, and understand the +// freedoms and responsibilities that he or she has by using this source/core. +// +// This core 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. +// +// Redistribution and use of source or resulting binaries, with or without modification +// of this file, are permitted under one of the following two license terms: +// +// 1. The GNU General Public License version 2 as published by the +// Free Software Foundation, which can be found in the top level directory +// of this repository (LICENSE_GPL2), and also online at: +// +// +// OR +// +// 2. An ADI specific BSD license, which can be found in the top level directory +// of this repository (LICENSE_ADIBSD), and also on-line at: +// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD +// This will allow to generate bit files and not release the source code, +// as long as it attaches to an ADI device. +// +// *************************************************************************** +// *************************************************************************** + +`timescale 1ns/100ps + +module ad_dds_2 #( + + // Range = 8-24 + parameter DDS_DW = 16, + // Range = 8-24 + parameter PHASE_DW = 16, + // Set 1 for CORDIC or 2 for Polynomial + parameter DDS_TYPE = 1, + // Range = 8-24 + parameter CORDIC_DW = 16, + // Range = 8-24 ( make sure CORDIC_PHASE_DW < CORDIC_DW) + parameter CORDIC_PHASE_DW = 16) ( + + // interface + + input clk, + input dds_format, + input [PHASE_DW-1:0] dds_phase_0, + input [ 15:0] dds_scale_0, + input [PHASE_DW-1:0] dds_phase_1, + input [ 15:0] dds_scale_1, + output [ DDS_DW-1:0] dds_data); + + // Local parameters + + localparam CORDIC = 1; + localparam POLYNOMIAL = 2; + + // The width for Polynomial DDS is fixed (16) + localparam DDS_D_DW = (DDS_TYPE == CORDIC) ? CORDIC_DW : 16; + localparam DDS_P_DW = (DDS_TYPE == CORDIC) ? CORDIC_PHASE_DW : 16; + // concatenation or truncation width + localparam C_T_WIDTH = (DDS_D_DW > DDS_DW) ? (DDS_D_DW - DDS_DW) : (DDS_DW - DDS_D_DW); + + // internal registers + + reg [ DDS_DW-1:0] dds_data_width = 0; + reg [DDS_D_DW-1:0] dds_data_rownd = 0; + reg [DDS_D_DW-1:0] dds_data_int = 0; + reg [ 15:0] dds_scale_0_d = 0; + reg [ 15:0] dds_scale_1_d = 0; + reg [ DDS_DW-1:0] dds_data_out = 0; + + // internal signals + + wire [DDS_D_DW-1:0] dds_data_0_s; + wire [DDS_D_DW-1:0] dds_data_1_s; + wire [DDS_P_DW-1:0] dds_phase_0_s; + wire [DDS_P_DW-1:0] dds_phase_1_s; + + generate + // dds channel output + assign dds_data = dds_data_out; + + // output data format + always @(posedge clk) begin + dds_data_out[DDS_DW-1] <= dds_data_width[DDS_DW-1] ^ dds_format; + dds_data_out[DDS_DW-2: 0] <= dds_data_width[DDS_DW-2: 0]; + end + + // set desired data width + always @(posedge clk) begin + if (DDS_DW < DDS_D_DW) begin // truncation + // fair rownding + dds_data_rownd <= dds_data_int + {(C_T_WIDTH){dds_data_int[DDS_D_DW-1]}}; + dds_data_width <= dds_data_rownd[DDS_D_DW-1:DDS_D_DW-DDS_DW]; + end else begin // concatenation + dds_data_width <= dds_data_int << C_T_WIDTH; + end + end + + // dual tone + always @(posedge clk) begin + dds_data_int <= dds_data_0_s + dds_data_1_s; + end + + always @(posedge clk) begin + dds_scale_0_d <= dds_scale_0; + dds_scale_1_d <= dds_scale_1; + end + + // phase + if (DDS_P_DW > PHASE_DW) begin + assign dds_phase_0_s = {dds_phase_0,{DDS_P_DW-PHASE_DW{1'b0}}}; + assign dds_phase_1_s = {dds_phase_1,{DDS_P_DW-PHASE_DW{1'b0}}}; + end else begin + assign dds_phase_0_s = dds_phase_0[(PHASE_DW-1):PHASE_DW-DDS_P_DW]; + assign dds_phase_1_s = dds_phase_1[(PHASE_DW-1):PHASE_DW-DDS_P_DW]; + end + + // dds-1 + + ad_dds_1 #( + .DDS_TYPE(DDS_TYPE), + .DDS_D_DW(DDS_D_DW), + .DDS_P_DW(DDS_P_DW)) + i_dds_1_0 ( + .clk (clk), + .angle (dds_phase_0_s), + .scale (dds_scale_0_d), + .dds_data (dds_data_0_s)); + + // dds-2 + + ad_dds_1 #( + .DDS_TYPE(DDS_TYPE), + .DDS_D_DW(DDS_D_DW), + .DDS_P_DW(DDS_P_DW)) + i_dds_1_1 ( + .clk (clk), + .angle (dds_phase_1_s), + .scale (dds_scale_1_d), + .dds_data (dds_data_1_s)); + endgenerate + +endmodule + +// *************************************************************************** +// *************************************************************************** diff --git a/src/adi/hdl/library/common/ad_dds_cordic_pipe.v b/src/adi/hdl/library/common/ad_dds_cordic_pipe.v new file mode 100644 index 00000000..926c47d1 --- /dev/null +++ b/src/adi/hdl/library/common/ad_dds_cordic_pipe.v @@ -0,0 +1,100 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright 2014 - 2017 (c) Analog Devices, Inc. All rights reserved. +// +// In this HDL repository, there are many different and unique modules, consisting +// of various HDL (Verilog or VHDL) components. The individual modules are +// developed independently, and may be accompanied by separate and unique license +// terms. +// +// The user should read each of these license terms, and understand the +// freedoms and responsibilities that he or she has by using this source/core. +// +// This core 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. +// +// Redistribution and use of source or resulting binaries, with or without modification +// of this file, are permitted under one of the following two license terms: +// +// 1. The GNU General Public License version 2 as published by the +// Free Software Foundation, which can be found in the top level directory +// of this repository (LICENSE_GPL2), and also online at: +// +// +// OR +// +// 2. An ADI specific BSD license, which can be found in the top level directory +// of this repository (LICENSE_ADIBSD), and also on-line at: +// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD +// This will allow to generate bit files and not release the source code, +// as long as it attaches to an ADI device. +// +// *************************************************************************** +// *************************************************************************** + +`timescale 1ns/100ps + +module ad_dds_cordic_pipe#( + + // parameters + + // Range = N/A + parameter P_DW = 16, + // Range = N/A + parameter D_DW = 16, + // Range = N/A + parameter DELAY_DW = 1, + // Range = 0-(DW - 1) + parameter SHIFT = 0) ( + + // Interface + + input clk, + (* keep = "TRUE" *) input dir, + (* keep = "TRUE" *) input [ D_DW-1:0] dataa_x, + (* keep = "TRUE" *) input [ D_DW-1:0] dataa_y, + (* keep = "TRUE" *) input [ P_DW-1:0] dataa_z, + (* keep = "TRUE" *) input [ P_DW-1:0] datab_z, + (* keep = "TRUE" *) output reg [ D_DW-1:0] result_x, + (* keep = "TRUE" *) output reg [ D_DW-1:0] result_y, + (* keep = "TRUE" *) output reg [ P_DW-1:0] result_z, + input [DELAY_DW:1] data_delay_in, + output [DELAY_DW:1] data_delay_out); + + // Registers Declarations + + reg [DELAY_DW:1] data_delay = 'd0; + + // Wires Declarations + + wire [ D_DW-1:0] sgn_shift_x; + wire [ D_DW-1:0] sgn_shift_y; + wire dir_inv = ~dir; + + // Sign shift + + assign sgn_shift_x = {{SHIFT{dataa_x[D_DW-1]}}, dataa_x[D_DW-1:SHIFT]}; + assign sgn_shift_y = {{SHIFT{dataa_y[D_DW-1]}}, dataa_y[D_DW-1:SHIFT]}; + + // Stage rotation + + always @(posedge clk) begin + result_x <= dataa_x + ({D_DW{dir_inv}} ^ sgn_shift_y) + dir_inv; + result_y <= dataa_y + ({D_DW{dir}} ^ sgn_shift_x) + dir; + result_z <= dataa_z + ({P_DW{dir_inv}} ^ datab_z) + dir_inv; + end + + // Delay data (if used) + + generate + if (DELAY_DW > 1) begin + always @(posedge clk) begin + data_delay <= data_delay_in; + end + end + endgenerate + + assign data_delay_out = data_delay; + +endmodule diff --git a/src/adi/hdl/library/common/ad_dds_sine.v b/src/adi/hdl/library/common/ad_dds_sine.v new file mode 100644 index 00000000..b1755a0f --- /dev/null +++ b/src/adi/hdl/library/common/ad_dds_sine.v @@ -0,0 +1,206 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright 2014 - 2017 (c) Analog Devices, Inc. All rights reserved. +// +// In this HDL repository, there are many different and unique modules, consisting +// of various HDL (Verilog or VHDL) components. The individual modules are +// developed independently, and may be accompanied by separate and unique license +// terms. +// +// The user should read each of these license terms, and understand the +// freedoms and responsibilities that he or she has by using this source/core. +// +// This core 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. +// +// Redistribution and use of source or resulting binaries, with or without modification +// of this file, are permitted under one of the following two license terms: +// +// 1. The GNU General Public License version 2 as published by the +// Free Software Foundation, which can be found in the top level directory +// of this repository (LICENSE_GPL2), and also online at: +// +// +// OR +// +// 2. An ADI specific BSD license, which can be found in the top level directory +// of this repository (LICENSE_ADIBSD), and also on-line at: +// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD +// This will allow to generate bit files and not release the source code, +// as long as it attaches to an ADI device. +// +// *************************************************************************** +// *************************************************************************** +// this is a sine function (approximate), the basic idea is to approximate sine as a +// polynomial function (there are a lot of stuff about this on the web) + +`timescale 1ns/100ps + +module ad_dds_sine #( + + parameter DELAY_DATA_WIDTH = 16) ( + + // sine = sin(angle) + + input clk, + input [15:0] angle, + output [15:0] sine, + input [(DELAY_DATA_WIDTH-1):0] ddata_in, + output [(DELAY_DATA_WIDTH-1):0] ddata_out); + + // internal registers + + reg [33:0] s1_data_p = 'd0; + reg [33:0] s1_data_n = 'd0; + reg [15:0] s1_angle = 'd0; + reg [(DELAY_DATA_WIDTH-1):0] s1_ddata = 'd0; + reg [18:0] s2_data_0 = 'd0; + reg [18:0] s2_data_1 = 'd0; + reg [(DELAY_DATA_WIDTH-1):0] s2_ddata = 'd0; + reg [18:0] s3_data = 'd0; + reg [(DELAY_DATA_WIDTH-1):0] s3_ddata = 'd0; + reg [33:0] s4_data2_p = 'd0; + reg [33:0] s4_data2_n = 'd0; + reg [16:0] s4_data1_p = 'd0; + reg [16:0] s4_data1_n = 'd0; + reg [(DELAY_DATA_WIDTH-1):0] s4_ddata = 'd0; + reg [16:0] s5_data2_0 = 'd0; + reg [16:0] s5_data2_1 = 'd0; + reg [16:0] s5_data1 = 'd0; + reg [(DELAY_DATA_WIDTH-1):0] s5_ddata = 'd0; + reg [16:0] s6_data2 = 'd0; + reg [16:0] s6_data1 = 'd0; + reg [(DELAY_DATA_WIDTH-1):0] s6_ddata = 'd0; + reg [33:0] s7_data = 'd0; + reg [(DELAY_DATA_WIDTH-1):0] s7_ddata = 'd0; + reg [15:0] sine_int = 'd0; + reg [(DELAY_DATA_WIDTH-1):0] ddata_out_int = 'd0; + + // internal signals + + wire [15:0] angle_s; + wire [33:0] s1_data_s; + wire [(DELAY_DATA_WIDTH-1):0] s1_ddata_s; + wire [15:0] s1_angle_s; + wire [33:0] s4_data2_s; + wire [(DELAY_DATA_WIDTH-1):0] s4_ddata_s; + wire [16:0] s4_data1_s; + wire [33:0] s7_data2_s; + wire [33:0] s7_data1_s; + wire [(DELAY_DATA_WIDTH-1):0] s7_ddata_s; + + // make angle 2's complement + + assign angle_s = {~angle[15], angle[14:0]}; + + // level 1 - intermediate + + ad_mul #(.DELAY_DATA_WIDTH(DELAY_DATA_WIDTH+16)) i_mul_s1 ( + .clk (clk), + .data_a ({angle_s[15], angle_s}), + .data_b ({angle_s[15], angle_s}), + .data_p (s1_data_s), + .ddata_in ({ddata_in, angle_s}), + .ddata_out ({s1_ddata_s, s1_angle_s})); + + // 2's complement versions + + always @(posedge clk) begin + s1_data_p <= s1_data_s; + s1_data_n <= ~s1_data_s + 1'b1; + s1_angle <= s1_angle_s; + s1_ddata <= s1_ddata_s; + end + + // select partial products + + always @(posedge clk) begin + s2_data_0 <= (s1_angle[15] == 1'b0) ? s1_data_n[31:13] : s1_data_p[31:13]; + s2_data_1 <= {s1_angle[15], s1_angle[15:0], 2'b00}; + s2_ddata <= s1_ddata; + end + + // unit-sine + + always @(posedge clk) begin + s3_data <= s2_data_0 + s2_data_1; + s3_ddata <= s2_ddata; + end + + // level 2 - final + + ad_mul #(.DELAY_DATA_WIDTH(DELAY_DATA_WIDTH+17)) i_mul_s2 ( + .clk (clk), + .data_a (s3_data[16:0]), + .data_b (s3_data[16:0]), + .data_p (s4_data2_s), + .ddata_in ({s3_ddata, s3_data[16:0]}), + .ddata_out ({s4_ddata_s, s4_data1_s})); + + // 2's complement versions + + always @(posedge clk) begin + s4_data2_p <= s4_data2_s; + s4_data2_n <= ~s4_data2_s + 1'b1; + s4_data1_p <= s4_data1_s; + s4_data1_n <= ~s4_data1_s + 1'b1; + s4_ddata <= s4_ddata_s; + end + + // select partial products + + always @(posedge clk) begin + s5_data2_0 <= (s4_data1_p[16] == 1'b1) ? s4_data2_n[31:15] : s4_data2_p[31:15]; + s5_data2_1 <= s4_data1_n; + s5_data1 <= s4_data1_p; + s5_ddata <= s4_ddata; + end + + // corrected-sine + + always @(posedge clk) begin + s6_data2 <= s5_data2_0 + s5_data2_1; + s6_data1 <= s5_data1; + s6_ddata <= s5_ddata; + end + + // full-scale + + ad_mul #(.DELAY_DATA_WIDTH(1)) i_mul_s3_2 ( + .clk (clk), + .data_a (s6_data2), + .data_b (17'h1d08), + .data_p (s7_data2_s), + .ddata_in (1'b0), + .ddata_out ()); + + ad_mul #(.DELAY_DATA_WIDTH(DELAY_DATA_WIDTH)) i_mul_s3_1 ( + .clk (clk), + .data_a (s6_data1), + .data_b (17'h7fff), + .data_p (s7_data1_s), + .ddata_in (s6_ddata), + .ddata_out (s7_ddata_s)); + + // corrected sum + + always @(posedge clk) begin + s7_data <= s7_data2_s + s7_data1_s; + s7_ddata <= s7_ddata_s; + end + + // output registers + + assign sine = sine_int; + assign ddata_out = ddata_out_int; + + always @(posedge clk) begin + sine_int <= s7_data[30:15]; + ddata_out_int <= s7_ddata; + end + +endmodule + +// *************************************************************************** +// *************************************************************************** diff --git a/src/adi/hdl/library/common/ad_dds_sine_cordic.v b/src/adi/hdl/library/common/ad_dds_sine_cordic.v new file mode 100644 index 00000000..66eba7e3 --- /dev/null +++ b/src/adi/hdl/library/common/ad_dds_sine_cordic.v @@ -0,0 +1,430 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright 2014 - 2017 (c) Analog Devices, Inc. All rights reserved. +// +// In this HDL repository, there are many different and unique modules, consisting +// of various HDL (Verilog or VHDL) components. The individual modules are +// developed independently, and may be accompanied by separate and unique license +// terms. +// +// The user should read each of these license terms, and understand the +// freedoms and responsibilities that he or she has by using this source/core. +// +// This core 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. +// +// Redistribution and use of source or resulting binaries, with or without modification +// of this file, are permitted under one of the following two license terms: +// +// 1. The GNU General Public License version 2 as published by the +// Free Software Foundation, which can be found in the top level directory +// of this repository (LICENSE_GPL2), and also online at: +// +// +// OR +// +// 2. An ADI specific BSD license, which can be found in the top level directory +// of this repository (LICENSE_ADIBSD), and also on-line at: +// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD +// This will allow to generate bit files and not release the source code, +// as long as it attaches to an ADI device. +// +// *************************************************************************** +// *************************************************************************** + +`timescale 1ns/100ps + +module ad_dds_sine_cordic #( + + // Range = 8-24 + parameter PHASE_DW = 16, + // Range = 8-24 + parameter CORDIC_DW = 16, + // Range = N/A + parameter DELAY_DW = 1) ( + + // interface + + input clk, + input [ PHASE_DW-1:0] angle, + output reg [CORDIC_DW-1:0] sine, + output reg [CORDIC_DW-1:0] cosine, + input [ DELAY_DW-1:0] ddata_in, + output reg [ DELAY_DW-1:0] ddata_out); + + // Local Parameters + localparam LUT_FSCALE = 1 << (PHASE_DW); + + // 1.64676025812 =~ system gain + localparam X_FSCALE = 1 << (CORDIC_DW); + localparam APROX_DW_GAIN_ERR = (CORDIC_DW < 21) ? 4 : + (CORDIC_DW <= 24) ? 7 : 0; + // ((2^N)/2)/1.647... + localparam [CORDIC_DW-1:0] X_VALUE = ((X_FSCALE/2)/(1.64676))-APROX_DW_GAIN_ERR; + + // Registers Declarations + + reg [CORDIC_DW-1:0] x0 = 'd0; + reg [CORDIC_DW-1:0] y0 = 'd0; + reg [ PHASE_DW-1:0] z0 = 'd0; + + // Wires Declarations + + wire [CORDIC_DW-1:0] x_s [0:CORDIC_DW-1]; + wire [CORDIC_DW-1:0] y_s [0:CORDIC_DW-1]; + wire [ PHASE_DW-1:0] z_s [0:CORDIC_DW-1]; + wire [ DELAY_DW-1:0] data_in_d [0:CORDIC_DW-1]; + wire [ PHASE_DW-1:0] atan_table[0:CORDIC_DW-2]; + wire [ 1:0] quadrant; + + // arc tangent LUT + + generate + if (PHASE_DW == 24) begin + assign atan_table[ 0] = 24'd2097152; // 45.0000000000000 + assign atan_table[ 1] = 24'd1238021; // 26.5650511770780 + assign atan_table[ 2] = 24'd654136; // 14.0362434679265 + assign atan_table[ 3] = 24'd332050; // 7.12501634890180 + assign atan_table[ 4] = 24'd166669; // 3.57633437499735 + assign atan_table[ 5] = 24'd83416; // 1.78991060824607 + assign atan_table[ 6] = 24'd41718; // 0.89517371021107 + assign atan_table[ 7] = 24'd20860; // 0.44761417086055 + assign atan_table[ 8] = 24'd10430; // 0.22381050036853 + assign atan_table[ 9] = 24'd5215; // 0.11190567706620 + assign atan_table[10] = 24'd2608; // 0.05595289189380 + assign atan_table[11] = 24'd1304; // 0.02797645261700 + assign atan_table[12] = 24'd652; // 0.01398822714226 + assign atan_table[13] = 24'd326; // 0.00699411367535 + assign atan_table[14] = 24'd163; // 0.00349705685070 + assign atan_table[15] = 24'd81; // 0.00174852842698 + assign atan_table[16] = 24'd41; // 0.00087426421369 + assign atan_table[17] = 24'd20; // 0.00043713210687 + assign atan_table[18] = 24'd10; // 0.00021856605343 + assign atan_table[19] = 24'd5; // 0.00010928302672 + assign atan_table[20] = 24'd3; // 0.00005464151336 + assign atan_table[21] = 24'd1; // 0.00002732075668 + assign atan_table[22] = 24'd1; // 0.00001366037834 + end else if (PHASE_DW == 23) begin + assign atan_table[ 0] = 23'd1048576; // 45.0000000000000 + assign atan_table[ 1] = 23'd619011; // 26.5650511770780 + assign atan_table[ 2] = 23'd327068; // 14.0362434679265 + assign atan_table[ 3] = 23'd166025; // 7.12501634890180 + assign atan_table[ 4] = 23'd83335; // 3.57633437499735 + assign atan_table[ 5] = 23'd41708; // 1.78991060824607 + assign atan_table[ 6] = 23'd20859; // 0.89517371021107 + assign atan_table[ 7] = 23'd10430; // 0.44761417086055 + assign atan_table[ 8] = 23'd5215; // 0.22381050036853 + assign atan_table[ 9] = 23'd2608; // 0.11190567706620 + assign atan_table[10] = 23'd1304; // 0.05595289189380 + assign atan_table[11] = 23'd652; // 0.02797645261700 + assign atan_table[12] = 23'd326; // 0.01398822714226 + assign atan_table[13] = 23'd163; // 0.00699411367535 + assign atan_table[14] = 23'd81; // 0.00349705685070 + assign atan_table[15] = 23'd41; // 0.00174852842698 + assign atan_table[16] = 23'd20; // 0.00087426421369 + assign atan_table[17] = 23'd10; // 0.00043713210687 + assign atan_table[18] = 23'd5; // 0.00021856605343 + assign atan_table[19] = 23'd3; // 0.00010928302672 + assign atan_table[20] = 23'd1; // 0.00005464151336 + assign atan_table[21] = 23'd1; // 0.00002732075668 + end else if (PHASE_DW == 22) begin + assign atan_table[ 0] = 22'd524288; // ... + assign atan_table[ 1] = 22'd309505; + assign atan_table[ 2] = 22'd163534; + assign atan_table[ 3] = 22'd83012; + assign atan_table[ 4] = 22'd41667; + assign atan_table[ 5] = 22'd20854; + assign atan_table[ 6] = 22'd10430; + assign atan_table[ 7] = 22'd5215; + assign atan_table[ 8] = 22'd2608; + assign atan_table[ 9] = 22'd1304; + assign atan_table[10] = 22'd652; + assign atan_table[11] = 22'd326; + assign atan_table[12] = 22'd163; + assign atan_table[13] = 22'd81; + assign atan_table[14] = 22'd41; + assign atan_table[15] = 22'd20; + assign atan_table[16] = 22'd10; + assign atan_table[17] = 22'd5; + assign atan_table[18] = 22'd3; + assign atan_table[19] = 22'd1; + assign atan_table[20] = 22'd1; + end else if (PHASE_DW == 21) begin + assign atan_table[ 0] = 21'd262144; + assign atan_table[ 1] = 21'd154753; + assign atan_table[ 2] = 21'd81767; + assign atan_table[ 3] = 21'd41506; + assign atan_table[ 4] = 21'd20834; + assign atan_table[ 5] = 21'd10427; + assign atan_table[ 6] = 21'd5215; + assign atan_table[ 7] = 21'd2608; + assign atan_table[ 8] = 21'd1304; + assign atan_table[ 9] = 21'd652; + assign atan_table[10] = 21'd326; + assign atan_table[11] = 21'd163; + assign atan_table[12] = 21'd81; + assign atan_table[13] = 21'd41; + assign atan_table[14] = 21'd20; + assign atan_table[15] = 21'd10; + assign atan_table[16] = 21'd5; + assign atan_table[17] = 21'd3; + assign atan_table[18] = 21'd1; + assign atan_table[19] = 21'd1; + end else if (PHASE_DW == 20) begin + assign atan_table[ 0] = 20'd131072; + assign atan_table[ 1] = 20'd77376; + assign atan_table[ 2] = 20'd40884; + assign atan_table[ 3] = 20'd20753; + assign atan_table[ 4] = 20'd10417; + assign atan_table[ 5] = 20'd5213; + assign atan_table[ 6] = 20'd2607; + assign atan_table[ 7] = 20'd1304; + assign atan_table[ 8] = 20'd652; + assign atan_table[ 9] = 20'd326; + assign atan_table[10] = 20'd163; + assign atan_table[11] = 20'd81; + assign atan_table[12] = 20'd41; + assign atan_table[13] = 20'd20; + assign atan_table[14] = 20'd10; + assign atan_table[15] = 20'd5; + assign atan_table[16] = 20'd3; + assign atan_table[17] = 20'd1; + assign atan_table[18] = 20'd1; + end else if (PHASE_DW == 19) begin + assign atan_table[ 0] = 19'd65536; + assign atan_table[ 1] = 19'd38688; + assign atan_table[ 2] = 19'd20442; + assign atan_table[ 3] = 19'd10377; + assign atan_table[ 4] = 19'd5208; + assign atan_table[ 5] = 19'd2607; + assign atan_table[ 6] = 19'd1304; + assign atan_table[ 7] = 19'd652; + assign atan_table[ 8] = 19'd326; + assign atan_table[ 9] = 19'd163; + assign atan_table[10] = 19'd81; + assign atan_table[11] = 19'd41; + assign atan_table[12] = 19'd20; + assign atan_table[13] = 19'd10; + assign atan_table[14] = 19'd5; + assign atan_table[15] = 19'd3; + assign atan_table[16] = 19'd1; + assign atan_table[17] = 19'd1; + end else if (PHASE_DW == 18) begin + assign atan_table[ 0] = 18'd32768; + assign atan_table[ 1] = 18'd19344; + assign atan_table[ 2] = 18'd10221; + assign atan_table[ 3] = 18'd5188; + assign atan_table[ 4] = 18'd2604; + assign atan_table[ 5] = 18'd1303; + assign atan_table[ 6] = 18'd652; + assign atan_table[ 7] = 18'd326; + assign atan_table[ 8] = 18'd163; + assign atan_table[ 9] = 18'd81; + assign atan_table[10] = 18'd41; + assign atan_table[11] = 18'd20; + assign atan_table[12] = 18'd10; + assign atan_table[13] = 18'd5; + assign atan_table[14] = 18'd3; + assign atan_table[15] = 18'd1; + assign atan_table[16] = 18'd1; + end else if (PHASE_DW == 17) begin + assign atan_table[ 0] = 17'd16384; + assign atan_table[ 1] = 17'd9672; + assign atan_table[ 2] = 17'd5110; + assign atan_table[ 3] = 17'd2594; + assign atan_table[ 4] = 17'd1302; + assign atan_table[ 5] = 17'd652; + assign atan_table[ 6] = 17'd326; + assign atan_table[ 7] = 17'd163; + assign atan_table[ 8] = 17'd81; + assign atan_table[ 9] = 17'd41; + assign atan_table[10] = 17'd20; + assign atan_table[11] = 17'd10; + assign atan_table[12] = 17'd5; + assign atan_table[13] = 17'd3; + assign atan_table[14] = 17'd1; + assign atan_table[15] = 17'd1; + end else if (PHASE_DW == 16) begin + assign atan_table[ 0] = 16'd8192; + assign atan_table[ 1] = 16'd4836; + assign atan_table[ 2] = 16'd2555; + assign atan_table[ 3] = 16'd1297; + assign atan_table[ 4] = 16'd651; + assign atan_table[ 5] = 16'd326; + assign atan_table[ 6] = 16'd163; + assign atan_table[ 7] = 16'd81; + assign atan_table[ 8] = 16'd41; + assign atan_table[ 9] = 16'd20; + assign atan_table[10] = 16'd10; + assign atan_table[11] = 16'd5; + assign atan_table[12] = 16'd3; + assign atan_table[13] = 16'd1; + assign atan_table[14] = 16'd1; + end else if (PHASE_DW == 15) begin + assign atan_table[ 0] = 15'd4096; + assign atan_table[ 1] = 15'd2418; + assign atan_table[ 2] = 15'd1278; + assign atan_table[ 3] = 15'd649; + assign atan_table[ 4] = 15'd326; + assign atan_table[ 5] = 15'd163; + assign atan_table[ 6] = 15'd81; + assign atan_table[ 7] = 15'd41; + assign atan_table[ 8] = 15'd20; + assign atan_table[ 9] = 15'd10; + assign atan_table[10] = 15'd5; + assign atan_table[11] = 15'd3; + assign atan_table[12] = 15'd1; + assign atan_table[13] = 15'd1; + end else if (PHASE_DW == 14) begin + assign atan_table[ 0] = 14'd2048; + assign atan_table[ 1] = 14'd1209; + assign atan_table[ 2] = 14'd639; + assign atan_table[ 3] = 14'd324; + assign atan_table[ 4] = 14'd163; + assign atan_table[ 5] = 14'd81; + assign atan_table[ 6] = 14'd41; + assign atan_table[ 7] = 14'd20; + assign atan_table[ 8] = 14'd10; + assign atan_table[ 9] = 14'd5; + assign atan_table[10] = 14'd3; + assign atan_table[11] = 14'd1; + assign atan_table[12] = 14'd1; + end else if (PHASE_DW == 13) begin + assign atan_table[ 0] = 13'd1024; + assign atan_table[ 1] = 13'd605; + assign atan_table[ 2] = 13'd319; + assign atan_table[ 3] = 13'd162; + assign atan_table[ 4] = 13'd81; + assign atan_table[ 5] = 13'd41; + assign atan_table[ 6] = 13'd20; + assign atan_table[ 7] = 13'd10; + assign atan_table[ 8] = 13'd5; + assign atan_table[ 9] = 13'd3; + assign atan_table[10] = 13'd1; + assign atan_table[11] = 13'd1; + end else if (PHASE_DW == 12) begin + assign atan_table[ 0] = 12'd512; + assign atan_table[ 1] = 12'd302; + assign atan_table[ 2] = 12'd160; + assign atan_table[ 3] = 12'd81; + assign atan_table[ 4] = 12'd41; + assign atan_table[ 5] = 12'd20; + assign atan_table[ 6] = 12'd10; + assign atan_table[ 7] = 12'd5; + assign atan_table[ 8] = 12'd3; + assign atan_table[ 9] = 12'd1; + assign atan_table[10] = 12'd1; + end else if (PHASE_DW == 11) begin + assign atan_table[ 0] = 11'd256; + assign atan_table[ 1] = 11'd151; + assign atan_table[ 2] = 11'd80; + assign atan_table[ 3] = 11'd41; + assign atan_table[ 4] = 11'd20; + assign atan_table[ 5] = 11'd10; + assign atan_table[ 6] = 11'd5; + assign atan_table[ 7] = 11'd3; + assign atan_table[ 8] = 11'd1; + assign atan_table[ 9] = 11'd1; + end else if (PHASE_DW == 10) begin + assign atan_table[ 0] = 10'd128; + assign atan_table[ 1] = 10'd76; + assign atan_table[ 2] = 10'd40; + assign atan_table[ 3] = 10'd20; + assign atan_table[ 4] = 10'd10; + assign atan_table[ 5] = 10'd5; + assign atan_table[ 6] = 10'd3; + assign atan_table[ 7] = 10'd1; + assign atan_table[ 8] = 10'd1; + end else if (PHASE_DW == 9) begin + assign atan_table[ 0] = 9'd64; + assign atan_table[ 1] = 9'd38; + assign atan_table[ 2] = 9'd20; + assign atan_table[ 3] = 9'd10; + assign atan_table[ 4] = 9'd5; + assign atan_table[ 5] = 9'd3; + assign atan_table[ 6] = 9'd1; + assign atan_table[ 7] = 9'd1; + end else if (PHASE_DW == 8) begin + assign atan_table[ 0] = 8'd32; + assign atan_table[ 1] = 8'd19; + assign atan_table[ 2] = 8'd10; + assign atan_table[ 3] = 8'd5; + assign atan_table[ 4] = 8'd3; + assign atan_table[ 5] = 8'd1; + assign atan_table[ 6] = 8'd1; + end + endgenerate + + // pre-rotating + + // first two bits represent the quadrant in the unit circle + assign quadrant = angle[PHASE_DW-1:PHASE_DW-2]; + + always @(posedge clk) begin + case (quadrant) + 2'b00, + 2'b11: begin + x0 <= X_VALUE; + y0 <= 0; + z0 <= angle; + end + + 2'b01: begin + x0 <= 0; + y0 <= X_VALUE; + z0 <= {2'b00, angle[PHASE_DW-3:0]}; + end + + 2'b10: begin + x0 <= 0; + y0 <= -X_VALUE; + z0 <= {2'b11, angle[PHASE_DW-3:0]}; + end + endcase + end + + assign x_s[0] = x0; + assign y_s[0] = y0; + assign z_s[0] = z0; + assign data_in_d[0] = ddata_in; + + // cordic pipeline + + genvar i; + + generate + for (i=0; i < PHASE_DW-1; i=i+1) begin: rotation + ad_dds_cordic_pipe #( + .P_DW (PHASE_DW), + .D_DW (CORDIC_DW), + .DELAY_DW (DELAY_DW), + .SHIFT(i)) + pipe ( + .clk (clk), + .dataa_x (x_s[i]), + .dataa_y (y_s[i]), + .dataa_z (z_s[i]), + .datab_z (atan_table[i]), + .dir (z_s[i][PHASE_DW-1]), + .result_x (x_s[i+1]), + .result_y (y_s[i+1]), + .result_z (z_s[i+1]), + .data_delay_in (data_in_d[i]), + .data_delay_out (data_in_d[i+1]) + ); + end + endgenerate + + // x and y are cos(angle) and sin(angle) + + always @(posedge clk) begin + ddata_out <= data_in_d[PHASE_DW-1]; + sine <= y_s[PHASE_DW-1]; + cosine <= x_s[PHASE_DW-1]; + end + +endmodule + +// *************************************************************************** +// *************************************************************************** diff --git a/src/adi/hdl/library/common/ad_edge_detect.v b/src/adi/hdl/library/common/ad_edge_detect.v new file mode 100644 index 00000000..12f5ae2c --- /dev/null +++ b/src/adi/hdl/library/common/ad_edge_detect.v @@ -0,0 +1,83 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright 2014 - 2017 (c) Analog Devices, Inc. All rights reserved. +// +// In this HDL repository, there are many different and unique modules, consisting +// of various HDL (Verilog or VHDL) components. The individual modules are +// developed independently, and may be accompanied by separate and unique license +// terms. +// +// The user should read each of these license terms, and understand the +// freedoms and responsibilities that he or she has by using this source/core. +// +// This core 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. +// +// Redistribution and use of source or resulting binaries, with or without modification +// of this file, are permitted under one of the following two license terms: +// +// 1. The GNU General Public License version 2 as published by the +// Free Software Foundation, which can be found in the top level directory +// of this repository (LICENSE_GPL2), and also online at: +// +// +// OR +// +// 2. An ADI specific BSD license, which can be found in the top level directory +// of this repository (LICENSE_ADIBSD), and also on-line at: +// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD +// This will allow to generate bit files and not release the source code, +// as long as it attaches to an ADI device. +// +// *************************************************************************** +// *************************************************************************** + +// A simple edge detector circuit + +`timescale 1ns/100ps + +module ad_edge_detect #( + + parameter EDGE = 0) ( + + input clk, + input rst, + + input in, + output reg out); + + + localparam POS_EDGE = 0; + localparam NEG_EDGE = 1; + localparam ANY_EDGE = 2; + + reg ff_m1 = 0; + reg ff_m2 = 0; + + always @(posedge clk) begin + if (rst == 1) begin + ff_m1 <= 0; + ff_m2 <= 0; + end else begin + ff_m1 <= in; + ff_m2 <= ff_m1; + end + end + + always @(posedge clk) begin + if (rst == 1) begin + out <= 1'b0; + end else begin + if (EDGE == POS_EDGE) begin + out <= ff_m1 & ~ff_m2; + end else if (EDGE == NEG_EDGE) begin + out <= ~ff_m1 & ff_m2; + end else begin + out <= ff_m1 ^ ff_m2; + end + end + end + +endmodule + diff --git a/src/adi/hdl/library/common/ad_g2b.v b/src/adi/hdl/library/common/ad_g2b.v new file mode 100644 index 00000000..7d6ada66 --- /dev/null +++ b/src/adi/hdl/library/common/ad_g2b.v @@ -0,0 +1,59 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright 2014 - 2017 (c) Analog Devices, Inc. All rights reserved. +// +// In this HDL repository, there are many different and unique modules, consisting +// of various HDL (Verilog or VHDL) components. The individual modules are +// developed independently, and may be accompanied by separate and unique license +// terms. +// +// The user should read each of these license terms, and understand the +// freedoms and responsibilities that he or she has by using this source/core. +// +// This core 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. +// +// Redistribution and use of source or resulting binaries, with or without modification +// of this file, are permitted under one of the following two license terms: +// +// 1. The GNU General Public License version 2 as published by the +// Free Software Foundation, which can be found in the top level directory +// of this repository (LICENSE_GPL2), and also online at: +// +// +// OR +// +// 2. An ADI specific BSD license, which can be found in the top level directory +// of this repository (LICENSE_ADIBSD), and also on-line at: +// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD +// This will allow to generate bit files and not release the source code, +// as long as it attaches to an ADI device. +// +// *************************************************************************** +// *************************************************************************** + +`timescale 1ns/100ps + +module ad_g2b #( + + parameter DATA_WIDTH = 8) ( + + input [DATA_WIDTH-1:0] din, + output [DATA_WIDTH-1:0] dout); + + function [DATA_WIDTH-1:0] g2b; + input [DATA_WIDTH-1:0] g; + integer i; + begin + g2b[DATA_WIDTH-1] = g[DATA_WIDTH-1]; + for (i = DATA_WIDTH-1; i > 0; i = i -1) begin + g2b[i-1] = g2b[i] ^ g[i-1]; + end + end + endfunction + + assign dout = g2b(din); + +endmodule + diff --git a/src/adi/hdl/library/common/ad_iqcor.v b/src/adi/hdl/library/common/ad_iqcor.v new file mode 100644 index 00000000..cb1ae63d --- /dev/null +++ b/src/adi/hdl/library/common/ad_iqcor.v @@ -0,0 +1,183 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright 2014 - 2017 (c) Analog Devices, Inc. All rights reserved. +// +// In this HDL repository, there are many different and unique modules, consisting +// of various HDL (Verilog or VHDL) components. The individual modules are +// developed independently, and may be accompanied by separate and unique license +// terms. +// +// The user should read each of these license terms, and understand the +// freedoms and responsibilities that he or she has by using this source/core. +// +// This core 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. +// +// Redistribution and use of source or resulting binaries, with or without modification +// of this file, are permitted under one of the following two license terms: +// +// 1. The GNU General Public License version 2 as published by the +// Free Software Foundation, which can be found in the top level directory +// of this repository (LICENSE_GPL2), and also online at: +// +// +// OR +// +// 2. An ADI specific BSD license, which can be found in the top level directory +// of this repository (LICENSE_ADIBSD), and also on-line at: +// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD +// This will allow to generate bit files and not release the source code, +// as long as it attaches to an ADI device. +// +// *************************************************************************** +// *************************************************************************** +// iq correction = a*(i+x) + b*(q+y); offsets are added in dcfilter. +// if SCALE_ONLY is set to 1, b*(q+y) is set to 0, and the module is used for +// scale correction of channel I + +`timescale 1ns/100ps + +module ad_iqcor #( + + // select i/q if disabled + + parameter Q_OR_I_N = 0, + parameter SCALE_ONLY = 0, + parameter DISABLE = 0) ( + + // data interface + + input clk, + input valid, + input [15:0] data_in, + input [15:0] data_iq, + output valid_out, + output [15:0] data_out, + + // control interface + + input iqcor_enable, + input [15:0] iqcor_coeff_1, + input [15:0] iqcor_coeff_2); + + // internal registers + + reg p1_valid = 'd0; + reg [33:0] p1_data_p = 'd0; + reg valid_int = 'd0; + reg [15:0] data_int = 'd0; + reg [15:0] iqcor_coeff_1_r = 'd0; + reg [15:0] iqcor_coeff_2_r = 'd0; + + // internal signals + + wire [15:0] data_i_s; + wire [15:0] data_q_s; + wire [33:0] p1_data_p_i_s; + wire p1_valid_s; + wire [15:0] p1_data_i_s; + wire [33:0] p1_data_p_q_s; + wire [15:0] p1_data_q_s; + wire [15:0] p1_data_i_int; + wire [15:0] p1_data_q_int; + + // data-path disable + + generate + if (DISABLE == 1) begin + assign valid_out = valid; + assign data_out = data_in; + end else begin + assign valid_out = valid_int; + assign data_out = data_int; + end + endgenerate + + // swap i & q + + assign data_i_s = (Q_OR_I_N == 1 && SCALE_ONLY == 1'b0) ? data_iq : data_in; + assign data_q_s = (Q_OR_I_N == 1) ? data_in : data_iq; + + // coefficients are flopped to remove warnings from vivado + + always @(posedge clk) begin + iqcor_coeff_1_r <= iqcor_coeff_1; + iqcor_coeff_2_r <= iqcor_coeff_2; + end + + // scaling functions - i + + ad_mul #(.DELAY_DATA_WIDTH(17)) i_mul_i ( + .clk (clk), + .data_a ({data_i_s[15], data_i_s}), + .data_b ({iqcor_coeff_1_r[15], iqcor_coeff_1_r}), + .data_p (p1_data_p_i_s), + .ddata_in ({valid, data_i_s}), + .ddata_out ({p1_valid_s, p1_data_i_s})); + + generate + if (SCALE_ONLY == 0) begin + // scaling functions - q + + ad_mul #(.DELAY_DATA_WIDTH(16)) i_mul_q ( + .clk (clk), + .data_a ({data_q_s[15], data_q_s}), + .data_b ({iqcor_coeff_2_r[15], iqcor_coeff_2_r}), + .data_p (p1_data_p_q_s), + .ddata_in (data_q_s), + .ddata_out (p1_data_q_s)); + + // sum + end else begin + assign p1_data_p_q_s = 34'h0; + assign p1_data_q_s = 16'h0; + end + + endgenerate + generate + if (Q_OR_I_N == 1 && SCALE_ONLY == 0) begin + reg [15:0] p1_data_q = 'd0; + + always @(posedge clk) begin + p1_data_q <= p1_data_q_s; + end + + assign p1_data_i_int = 16'h0; + assign p1_data_q_int = p1_data_q; + + // sum + end else begin + reg [15:0] p1_data_i = 'd0; + + always @(posedge clk) begin + p1_data_i <= p1_data_i_s; + end + + assign p1_data_i_int = p1_data_i; + assign p1_data_q_int = 16'h0; + end + endgenerate + + always @(posedge clk) begin + p1_valid <= p1_valid_s; + p1_data_p <= p1_data_p_i_s + p1_data_p_q_s; + end + // output registers + + always @(posedge clk) begin + valid_int <= p1_valid; + if (iqcor_enable == 1'b1) begin + data_int <= p1_data_p[29:14]; + end else if (Q_OR_I_N == 1 && SCALE_ONLY == 0) begin + data_int <= p1_data_q_int; + end else begin + data_int <= p1_data_i_int; + end + end + + +endmodule + +// *************************************************************************** +// *************************************************************************** diff --git a/src/adi/hdl/library/common/ad_mem.v b/src/adi/hdl/library/common/ad_mem.v new file mode 100644 index 00000000..0843d4a1 --- /dev/null +++ b/src/adi/hdl/library/common/ad_mem.v @@ -0,0 +1,71 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright 2014 - 2017 (c) Analog Devices, Inc. All rights reserved. +// +// In this HDL repository, there are many different and unique modules, consisting +// of various HDL (Verilog or VHDL) components. The individual modules are +// developed independently, and may be accompanied by separate and unique license +// terms. +// +// The user should read each of these license terms, and understand the +// freedoms and responsibilities that he or she has by using this source/core. +// +// This core 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. +// +// Redistribution and use of source or resulting binaries, with or without modification +// of this file, are permitted under one of the following two license terms: +// +// 1. The GNU General Public License version 2 as published by the +// Free Software Foundation, which can be found in the top level directory +// of this repository (LICENSE_GPL2), and also online at: +// +// +// OR +// +// 2. An ADI specific BSD license, which can be found in the top level directory +// of this repository (LICENSE_ADIBSD), and also on-line at: +// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD +// This will allow to generate bit files and not release the source code, +// as long as it attaches to an ADI device. +// +// *************************************************************************** +// *************************************************************************** + +`timescale 1ns/100ps + +module ad_mem #( + + parameter DATA_WIDTH = 16, + parameter ADDRESS_WIDTH = 5) ( + + input clka, + input wea, + input [(ADDRESS_WIDTH-1):0] addra, + input [(DATA_WIDTH-1):0] dina, + + input clkb, + input reb, + input [(ADDRESS_WIDTH-1):0] addrb, + output reg [(DATA_WIDTH-1):0] doutb); + + (* ram_style = "block" *) + reg [(DATA_WIDTH-1):0] m_ram[0:((2**ADDRESS_WIDTH)-1)]; + + always @(posedge clka) begin + if (wea == 1'b1) begin + m_ram[addra] <= dina; + end + end + + always @(posedge clkb) begin + if (reb == 1'b1) begin + doutb <= m_ram[addrb]; + end + end + +endmodule + +// *************************************************************************** +// *************************************************************************** diff --git a/src/adi/hdl/library/common/ad_mem_asym.v b/src/adi/hdl/library/common/ad_mem_asym.v new file mode 100644 index 00000000..b4319690 --- /dev/null +++ b/src/adi/hdl/library/common/ad_mem_asym.v @@ -0,0 +1,148 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright 2014 - 2017 (c) Analog Devices, Inc. All rights reserved. +// +// In this HDL repository, there are many different and unique modules, consisting +// of various HDL (Verilog or VHDL) components. The individual modules are +// developed independently, and may be accompanied by separate and unique license +// terms. +// +// The user should read each of these license terms, and understand the +// freedoms and responsibilities that he or she has by using this source/core. +// +// This core 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. +// +// Redistribution and use of source or resulting binaries, with or without modification +// of this file, are permitted under one of the following two license terms: +// +// 1. The GNU General Public License version 2 as published by the +// Free Software Foundation, which can be found in the top level directory +// of this repository (LICENSE_GPL2), and also online at: +// +// +// OR +// +// 2. An ADI specific BSD license, which can be found in the top level directory +// of this repository (LICENSE_ADIBSD), and also on-line at: +// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD +// This will allow to generate bit files and not release the source code, +// as long as it attaches to an ADI device. +// +// *************************************************************************** +// *************************************************************************** + +// A simple asymetric memory. The write and read memory space must have the same size. +// 2^A_ADDRESS_WIDTH * A_DATA_WIDTH == 2^B_ADDRESS_WIDTH * B_DATA_WIDTH + +`timescale 1ns/100ps + +module ad_mem_asym #( + + parameter A_ADDRESS_WIDTH = 8, + parameter A_DATA_WIDTH = 256, + parameter B_ADDRESS_WIDTH = 10, + parameter B_DATA_WIDTH = 64) ( + + input clka, + input wea, + input [A_ADDRESS_WIDTH-1:0] addra, + input [A_DATA_WIDTH-1:0] dina, + + input clkb, + input reb, + input [B_ADDRESS_WIDTH-1:0] addrb, + output reg [B_DATA_WIDTH-1:0] doutb); + + + `define max(a,b) {(a) > (b) ? (a) : (b)} + `define min(a,b) {(a) < (b) ? (a) : (b)} + + function integer clog2; + input integer value; + begin + if (value < 2) + clog2 = value; + else begin + value = value - 1; + for (clog2 = 0; value > 0; clog2 = clog2 + 1) + value = value >> 1; + end + end + endfunction + + localparam MEM_ADDRESS_WIDTH = `max(A_ADDRESS_WIDTH, B_ADDRESS_WIDTH); + localparam MIN_WIDTH = `min(A_DATA_WIDTH, B_DATA_WIDTH); + localparam MAX_WIDTH = `max(A_DATA_WIDTH, B_DATA_WIDTH); + localparam MEM_DATA_WIDTH = MIN_WIDTH; + localparam MEM_SIZE = 2 ** MEM_ADDRESS_WIDTH; + localparam MEM_RATIO = MAX_WIDTH / MIN_WIDTH; + localparam MEM_RATIO_LOG2 = clog2(MEM_RATIO); + + // internal registers + + reg [MEM_DATA_WIDTH-1:0] m_ram[0:MEM_SIZE-1]; + + //--------------------------------------------------------------------------- + // write interface + //--------------------------------------------------------------------------- + + // write data width is narrower than read data width + generate if (A_DATA_WIDTH <= B_DATA_WIDTH) begin + always @(posedge clka) begin + if (wea == 1'b1) begin + m_ram[addra] <= dina; + end + end + end + endgenerate + + // write data width is wider than read data width + generate if (A_DATA_WIDTH > B_DATA_WIDTH) begin + always @(posedge clka) begin : memwrite + integer i; + reg [MEM_RATIO_LOG2-1:0] lsb; + for (i = 0; i < MEM_RATIO; i = i + 1) begin : awrite + lsb = i; + if (wea) begin + m_ram[{addra, lsb}] <= dina[i * MIN_WIDTH +: MIN_WIDTH]; + end + end + end + end + endgenerate + + //--------------------------------------------------------------------------- + // read interface + //--------------------------------------------------------------------------- + + // read data width is narrower than write data width + generate if (A_DATA_WIDTH >= B_DATA_WIDTH) begin + always @(posedge clkb) begin + if (reb == 1'b1) begin + doutb <= m_ram[addrb]; + end + end + end + endgenerate + + // read data width is wider than write data width + generate if (A_DATA_WIDTH < B_DATA_WIDTH) begin + always @(posedge clkb) begin : memread + integer i; + reg [MEM_RATIO_LOG2-1:0] lsb; + for (i = 0; i < MEM_RATIO; i = i + 1) begin : aread + lsb = i; + if (reb == 1'b1) begin + doutb[i*MIN_WIDTH +: MIN_WIDTH] <= m_ram[{addrb, lsb}]; + end + end + end + end + endgenerate + +endmodule + +// *************************************************************************** +// *************************************************************************** diff --git a/src/adi/hdl/library/common/ad_perfect_shuffle.v b/src/adi/hdl/library/common/ad_perfect_shuffle.v new file mode 100644 index 00000000..c0427651 --- /dev/null +++ b/src/adi/hdl/library/common/ad_perfect_shuffle.v @@ -0,0 +1,68 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright 2018 (c) Analog Devices, Inc. All rights reserved. +// +// Each core or library found in this collection may have its own licensing terms. +// The user should keep this in in mind while exploring these cores. +// +// Redistribution and use in source and binary forms, +// with or without modification of this file, are permitted under the terms of either +// (at the option of the user): +// +// 1. The GNU General Public License version 2 as published by the +// Free Software Foundation, which can be found in the top level directory, or at: +// https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html +// +// OR +// +// 2. An ADI specific BSD license as noted in the top level directory, or on-line at: +// https://github.com/analogdevicesinc/hdl/blob/dev/LICENSE +// +// *************************************************************************** +// *************************************************************************** + +`timescale 1ns/100ps + +module ad_perfect_shuffle #( + parameter NUM_GROUPS = 2, + parameter WORDS_PER_GROUP = 2, + parameter WORD_WIDTH = 8 +) ( + input [NUM_GROUPS*WORDS_PER_GROUP*WORD_WIDTH-1:0] data_in, + output [NUM_GROUPS*WORDS_PER_GROUP*WORD_WIDTH-1:0] data_out +); + /* + * Performs the perfect shuffle operation. + * + * The perfect shuffle splits the input vector into NUM_GROUPS groups and then + * each group in WORDS_PER_GROUP. The output vector consists of WORDS_PER_GROUP + * groups and each group has NUM_GROUPS words. The data is remapped, so that + * the i-th word of the j-th word in the output vector is the j-th word of the + * i-th group of the input vector. + + * The inverse operation of the perfect shuffle is the perfect shuffle with + * both parameters swapped. + * I.e. [perfect_suffle B A [perfect_shuffle A B data]] == data + * + * Examples: + * NUM_GROUPS = 2, WORDS_PER_GROUP = 4 + * [A B C D a b c d] => [A a B b C c D d] + * NUM_GROUPS = 4, WORDS_PER_GROUP = 2 + * [A a B b C c D d] => [A B C D a b c d] + * NUM_GROUPS = 3, WORDS_PER_GROUP = 2 + * [A B a b 1 2] => [A a 1 B b 2] + */ + generate + genvar i; + genvar j; + for (i = 0; i < NUM_GROUPS; i = i + 1) begin: shuffle_outer + for (j = 0; j < WORDS_PER_GROUP; j = j + 1) begin: shuffle_inner + localparam src_lsb = (j + i * WORDS_PER_GROUP) * WORD_WIDTH; + localparam dst_lsb = (i + j * NUM_GROUPS) * WORD_WIDTH; + + assign data_out[dst_lsb+:WORD_WIDTH] = data_in[src_lsb+:WORD_WIDTH]; + end + end + endgenerate + +endmodule diff --git a/src/adi/hdl/library/common/ad_pnmon.v b/src/adi/hdl/library/common/ad_pnmon.v new file mode 100644 index 00000000..b6e52e75 --- /dev/null +++ b/src/adi/hdl/library/common/ad_pnmon.v @@ -0,0 +1,106 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright 2014 - 2017 (c) Analog Devices, Inc. All rights reserved. +// +// In this HDL repository, there are many different and unique modules, consisting +// of various HDL (Verilog or VHDL) components. The individual modules are +// developed independently, and may be accompanied by separate and unique license +// terms. +// +// The user should read each of these license terms, and understand the +// freedoms and responsibilities that he or she has by using this source/core. +// +// This core 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. +// +// Redistribution and use of source or resulting binaries, with or without modification +// of this file, are permitted under one of the following two license terms: +// +// 1. The GNU General Public License version 2 as published by the +// Free Software Foundation, which can be found in the top level directory +// of this repository (LICENSE_GPL2), and also online at: +// +// +// OR +// +// 2. An ADI specific BSD license, which can be found in the top level directory +// of this repository (LICENSE_ADIBSD), and also on-line at: +// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD +// This will allow to generate bit files and not release the source code, +// as long as it attaches to an ADI device. +// +// *************************************************************************** +// *************************************************************************** +// PN monitors + +`timescale 1ns/100ps + +module ad_pnmon #( + + parameter DATA_WIDTH = 16) ( + + // adc interface + + input adc_clk, + input adc_valid_in, + input [(DATA_WIDTH-1):0] adc_data_in, + input [(DATA_WIDTH-1):0] adc_data_pn, + + // pn out of sync and error + + output adc_pn_oos, + output adc_pn_err); + + // internal registers + + reg adc_valid_d = 'd0; + reg adc_pn_match_d = 'd0; + reg adc_pn_match_z = 'd0; + reg adc_pn_oos_int = 'd0; + reg adc_pn_err_int = 'd0; + reg [ 3:0] adc_pn_oos_count = 'd0; + + // internal signals + + wire adc_pn_match_d_s; + wire adc_pn_match_z_s; + wire adc_pn_match_s; + wire adc_pn_update_s; + wire adc_pn_err_s; + + // make sure data is not 0, sequence will fail. + + assign adc_pn_match_d_s = (adc_data_in == adc_data_pn) ? 1'b1 : 1'b0; + assign adc_pn_match_z_s = (adc_data_in == 'd0) ? 1'b0 : 1'b1; + assign adc_pn_match_s = adc_pn_match_d & adc_pn_match_z; + assign adc_pn_update_s = ~(adc_pn_oos_int ^ adc_pn_match_s); + assign adc_pn_err_s = ~(adc_pn_oos_int | adc_pn_match_s); + + // pn oos and counters (16 to clear and set). + + assign adc_pn_oos = adc_pn_oos_int; + assign adc_pn_err = adc_pn_err_int; + + always @(posedge adc_clk) begin + adc_valid_d <= adc_valid_in; + adc_pn_match_d <= adc_pn_match_d_s; + adc_pn_match_z <= adc_pn_match_z_s; + if (adc_valid_d == 1'b1) begin + adc_pn_err_int <= adc_pn_err_s; + if ((adc_pn_update_s == 1'b1) && (adc_pn_oos_count >= 15)) begin + adc_pn_oos_int <= ~adc_pn_oos_int; + end + if (adc_pn_update_s == 1'b1) begin + adc_pn_oos_count <= adc_pn_oos_count + 1'b1; + end else begin + adc_pn_oos_count <= 'd0; + end + end + end + +endmodule + +// *************************************************************************** +// *************************************************************************** + diff --git a/src/adi/hdl/library/common/ad_pps_receiver.v b/src/adi/hdl/library/common/ad_pps_receiver.v new file mode 100644 index 00000000..7a9c1b28 --- /dev/null +++ b/src/adi/hdl/library/common/ad_pps_receiver.v @@ -0,0 +1,130 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright 2014 - 2017 (c) Analog Devices, Inc. All rights reserved. +// +// In this HDL repository, there are many different and unique modules, consisting +// of various HDL (Verilog or VHDL) components. The individual modules are +// developed independently, and may be accompanied by separate and unique license +// terms. +// +// The user should read each of these license terms, and understand the +// freedoms and responsibilities that he or she has by using this source/core. +// +// This core 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. +// +// Redistribution and use of source or resulting binaries, with or without modification +// of this file, are permitted under one of the following two license terms: +// +// 1. The GNU General Public License version 2 as published by the +// Free Software Foundation, which can be found in the top level directory +// of this repository (LICENSE_GPL2), and also online at: +// +// +// OR +// +// 2. An ADI specific BSD license, which can be found in the top level directory +// of this repository (LICENSE_ADIBSD), and also on-line at: +// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD +// This will allow to generate bit files and not release the source code, +// as long as it attaches to an ADI device. +// +// *************************************************************************** +// *************************************************************************** +`timescale 1ns/1ps + +module ad_pps_receiver ( + input clk, + input rst, + input gps_pps, + + input up_clk, + input up_rstn, + output reg [31:0] up_pps_rcounter, + output reg up_pps_status, + input up_irq_mask, + output reg up_irq); + + // ************************************************************************* + // 1PPS reception and reporting counter implementation + // Note: this module should run on the core clock + // ************************************************************************* + + reg [ 2:0] gps_pps_m = 3'b0; + reg [ 2:0] up_pps_m = 3'b0; + reg up_pps_status_m = 1'b0; + reg pps_toggle = 1'b0; + reg [31:0] free_rcounter = 32'b0; + reg [31:0] pps_rcounter = 32'b0; + reg pps_status = 1'b0; + + wire pps_posedge_s; + wire up_pps_posedge_s; + + // gps_pps is asynchronous from the clk + + always @(posedge clk) begin + if (rst == 1'b1) begin + gps_pps_m <= 3'b0; + end else begin + gps_pps_m <= {gps_pps_m[1:0], gps_pps}; + end + end + assign pps_posedge_s = ~gps_pps_m[2] & gps_pps_m[1]; + + always @(posedge clk) begin + if (rst == 1'b1) begin + free_rcounter <= 32'b0; + pps_rcounter <= 32'b0; + pps_status <= 1'b1; + end else if (pps_posedge_s == 1'b1) begin + free_rcounter <= 32'b0; + pps_rcounter <= free_rcounter; + pps_status <= 1'b0; + end else begin + free_rcounter <= free_rcounter + 32'b1; + if (free_rcounter[28] == 1'b1) begin + pps_status <= 1'b1; + end + end + end + + // up_tdd_pps_rcounter CDC + + always @(posedge clk) begin + if (rst == 1'b1) begin + pps_toggle <= 1'b0; + end else if (pps_posedge_s == 1'b1) begin + pps_toggle <= ~pps_toggle; + end + end + + always @(posedge up_clk) begin + if (up_rstn == 1'b0) begin + up_pps_m <= 3'b0; + up_pps_rcounter <= 1'b0; + up_pps_status_m <= 1'b1; + up_pps_status <= 1'b1; + end else begin + up_pps_m <= {up_pps_m[1:0], pps_toggle}; + up_pps_status_m <= pps_status; + up_pps_status <= up_pps_status_m; + if ((up_pps_m[2] ^ up_pps_m[1]) == 1'b1) begin + up_pps_rcounter <= pps_rcounter; + end + end + end + assign up_pps_posedge_s = ~up_pps_m[2] & up_pps_m[1]; + + // IRQ generation + + always @(posedge up_clk) begin + if (up_rstn == 1'b0) begin + up_irq <= 1'b0; + end else begin + up_irq <= up_pps_posedge_s & ~up_irq_mask; + end + end + +endmodule diff --git a/src/adi/hdl/library/common/ad_pps_receiver_constr.ttcl b/src/adi/hdl/library/common/ad_pps_receiver_constr.ttcl new file mode 100644 index 00000000..5ed2c38a --- /dev/null +++ b/src/adi/hdl/library/common/ad_pps_receiver_constr.ttcl @@ -0,0 +1,20 @@ +<: set ComponentName [getComponentNameString] :> +<: setOutputDirectory "./" :> +<: setFileName [ttcl_add $ComponentName "_pps_constr"] :> +<: setFileExtension ".xdc" :> +<: setFileProcessingOrder late :> +<: set pps_enable [getBooleanValue "PPS_RECEIVER_ENABLE"] :> + +<: if {$pps_enable} { :> + + set_property ASYNC_REG TRUE \ + [get_cells -hier *_pps_m*] \ + [get_cells -hier *_pps_status_m*] + + set_false_path -to [get_cells -hier -filter {name =~ *_pps_m_reg[0] && IS_SEQUENTIAL}] + set_false_path -from [get_cells -hier -filter {name =~ *pps_status_reg && IS_SEQUENTIAL}] \ + -to [get_cells -hier -filter {name =~ *up_pps_status_m_reg && IS_SEQUENTIAL}] + set_false_path -to [get_cells -hier -filter {name =~ *up_pps_rcounter_reg* && IS_SEQUENTIAL}] + +<: } :> + diff --git a/src/adi/hdl/library/common/ad_rst.v b/src/adi/hdl/library/common/ad_rst.v new file mode 100644 index 00000000..43109633 --- /dev/null +++ b/src/adi/hdl/library/common/ad_rst.v @@ -0,0 +1,77 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright 2014 - 2017 (c) Analog Devices, Inc. All rights reserved. +// +// In this HDL repository, there are many different and unique modules, consisting +// of various HDL (Verilog or VHDL) components. The individual modules are +// developed independently, and may be accompanied by separate and unique license +// terms. +// +// The user should read each of these license terms, and understand the +// freedoms and responsibilities that he or she has by using this source/core. +// +// This core 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. +// +// Redistribution and use of source or resulting binaries, with or without modification +// of this file, are permitted under one of the following two license terms: +// +// 1. The GNU General Public License version 2 as published by the +// Free Software Foundation, which can be found in the top level directory +// of this repository (LICENSE_GPL2), and also online at: +// +// +// OR +// +// 2. An ADI specific BSD license, which can be found in the top level directory +// of this repository (LICENSE_ADIBSD), and also on-line at: +// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD +// This will allow to generate bit files and not release the source code, +// as long as it attaches to an ADI device. +// +// *************************************************************************** +// *************************************************************************** + +`timescale 1ns/100ps + +module ad_rst ( + + // clock reset + + input rst_async, + input clk, + output rstn, + output reg rst); + + // internal registers + reg rst_async_d1 = 1'd1; + reg rst_async_d2 = 1'd1; + reg rst_sync = 1'd1; + reg rst_sync_d = 1'd1; + + // simple reset synchronizer + always @(posedge clk or posedge rst_async) begin + if (rst_async) begin + rst_async_d1 <= 1'b1; + rst_async_d2 <= 1'b1; + rst_sync <= 1'b1; + end else begin + rst_async_d1 <= 1'b0; + rst_async_d2 <= rst_async_d1; + rst_sync <= rst_async_d2; + end + end + + // two-stage synchronizer to prevent metastability on the falling edge + always @(posedge clk) begin + rst_sync_d <= rst_sync; + rst <= rst_sync_d; + end + + assign rstn = ~rst; + +endmodule + +// *************************************************************************** +// *************************************************************************** diff --git a/src/adi/hdl/library/common/ad_ss_422to444.v b/src/adi/hdl/library/common/ad_ss_422to444.v new file mode 100644 index 00000000..d408d910 --- /dev/null +++ b/src/adi/hdl/library/common/ad_ss_422to444.v @@ -0,0 +1,138 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright 2014 - 2017 (c) Analog Devices, Inc. All rights reserved. +// +// In this HDL repository, there are many different and unique modules, consisting +// of various HDL (Verilog or VHDL) components. The individual modules are +// developed independently, and may be accompanied by separate and unique license +// terms. +// +// The user should read each of these license terms, and understand the +// freedoms and responsibilities that he or she has by using this source/core. +// +// This core 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. +// +// Redistribution and use of source or resulting binaries, with or without modification +// of this file, are permitted under one of the following two license terms: +// +// 1. The GNU General Public License version 2 as published by the +// Free Software Foundation, which can be found in the top level directory +// of this repository (LICENSE_GPL2), and also online at: +// +// +// OR +// +// 2. An ADI specific BSD license, which can be found in the top level directory +// of this repository (LICENSE_ADIBSD), and also on-line at: +// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD +// This will allow to generate bit files and not release the source code, +// as long as it attaches to an ADI device. +// +// *************************************************************************** +// *************************************************************************** +// Input must be RGB or CrYCb in that order, output is CrY/CbY + +`timescale 1ns/100ps + +module ad_ss_422to444 #( + + parameter CR_CB_N = 0, + parameter DELAY_DATA_WIDTH = 16) ( + + // 422 inputs + + input clk, + input s422_de, + input [DW:0] s422_sync, + input [15:0] s422_data, + + // 444 outputs + + output reg [DW:0] s444_sync, + output reg [23:0] s444_data); + + localparam DW = DELAY_DATA_WIDTH - 1; + + // internal registers + + reg cr_cb_sel = 'd0; + reg s422_de_d = 'd0; + reg [DW:0] s422_sync_d = 'd0; + reg s422_de_2d = 'd0; + reg [7:0] s422_Y_d; + reg [7:0] s422_CbCr_d; + reg [7:0] s422_CbCr_2d; + reg [ 8:0] s422_CbCr_avg; + + // internal wires + + wire [ 7:0] s422_Y; + wire [ 7:0] s422_CbCr; + + // Input format is + // [15:8] Cb/Cr + // [ 7:0] Y + // + // Output format is + // [23:15] Cr + // [16: 8] Y + // [ 7: 0] Cb + + assign s422_Y = s422_data[7:0]; + assign s422_CbCr = s422_data[15:8]; + + // first data on de assertion is cb (0x0), then cr (0x1). + // previous data is held when not current + + always @(posedge clk) begin + if (s422_de_d == 1'b1) begin + cr_cb_sel <= ~cr_cb_sel; + end else begin + cr_cb_sel <= CR_CB_N; + end + end + + // pipe line stages + + always @(posedge clk) begin + s422_de_d <= s422_de; + s422_sync_d <= s422_sync; + s422_de_2d <= s422_de_d; + s422_Y_d <= s422_Y; + + s422_CbCr_d <= s422_CbCr; + s422_CbCr_2d <= s422_CbCr_d; + end + + // If both the left and the right sample are valid do the average, otherwise + // use the only valid. + always @(s422_de_2d, s422_de, s422_CbCr, s422_CbCr_2d) + begin + if (s422_de == 1'b1 && s422_de_2d) + s422_CbCr_avg <= s422_CbCr + s422_CbCr_2d; + else if (s422_de == 1'b1) + s422_CbCr_avg <= {s422_CbCr, 1'b0}; + else + s422_CbCr_avg <= {s422_CbCr_2d, 1'b0}; + end + + // 444 outputs + + always @(posedge clk) begin + s444_sync <= s422_sync_d; + s444_data[15:8] <= s422_Y_d; + if (cr_cb_sel) begin + s444_data[23:16] <= s422_CbCr_d; + s444_data[ 7: 0] <= s422_CbCr_avg[8:1]; + end else begin + s444_data[23:16] <= s422_CbCr_avg[8:1]; + s444_data[ 7: 0] <= s422_CbCr_d; + end + end + +endmodule + +// *************************************************************************** +// *************************************************************************** diff --git a/src/adi/hdl/library/common/ad_ss_444to422.v b/src/adi/hdl/library/common/ad_ss_444to422.v new file mode 100644 index 00000000..542de95a --- /dev/null +++ b/src/adi/hdl/library/common/ad_ss_444to422.v @@ -0,0 +1,134 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright 2014 - 2017 (c) Analog Devices, Inc. All rights reserved. +// +// In this HDL repository, there are many different and unique modules, consisting +// of various HDL (Verilog or VHDL) components. The individual modules are +// developed independently, and may be accompanied by separate and unique license +// terms. +// +// The user should read each of these license terms, and understand the +// freedoms and responsibilities that he or she has by using this source/core. +// +// This core 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. +// +// Redistribution and use of source or resulting binaries, with or without modification +// of this file, are permitted under one of the following two license terms: +// +// 1. The GNU General Public License version 2 as published by the +// Free Software Foundation, which can be found in the top level directory +// of this repository (LICENSE_GPL2), and also online at: +// +// +// OR +// +// 2. An ADI specific BSD license, which can be found in the top level directory +// of this repository (LICENSE_ADIBSD), and also on-line at: +// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD +// This will allow to generate bit files and not release the source code, +// as long as it attaches to an ADI device. +// +// *************************************************************************** +// *************************************************************************** +// Input must be RGB or CrYCb in that order, output is CrY/CbY + +`timescale 1ns/100ps + +module ad_ss_444to422 #( + + parameter CR_CB_N = 0, + parameter DELAY_DATA_WIDTH = 16) ( + + // 444 inputs + + input clk, + input s444_de, + input [DW:0] s444_sync, + input [23:0] s444_data, + + // 422 outputs + + output reg [DW:0] s422_sync, + output reg [15:0] s422_data); + + localparam DW = DELAY_DATA_WIDTH - 1; + + // internal registers + + reg s444_de_d = 'd0; + reg [DW:0] s444_sync_d = 'd0; + reg [23:0] s444_data_d = 'd0; + reg s444_de_2d = 'd0; + reg [DW:0] s444_sync_2d = 'd0; + reg [23:0] s444_data_2d = 'd0; + reg s444_de_3d = 'd0; + reg [DW:0] s444_sync_3d = 'd0; + reg [23:0] s444_data_3d = 'd0; + reg [ 7:0] cr = 'd0; + reg [ 7:0] cb = 'd0; + reg cr_cb_sel = 'd0; + + // internal wires + + wire [ 9:0] cr_s; + wire [ 9:0] cb_s; + + // fill the data pipe lines, hold the last data on edges + + always @(posedge clk) begin + s444_de_d <= s444_de; + s444_sync_d <= s444_sync; + if (s444_de == 1'b1) begin + s444_data_d <= s444_data; + end + s444_de_2d <= s444_de_d; + s444_sync_2d <= s444_sync_d; + if (s444_de_d == 1'b1) begin + s444_data_2d <= s444_data_d; + end + s444_de_3d <= s444_de_2d; + s444_sync_3d <= s444_sync_2d; + if (s444_de_2d == 1'b1) begin + s444_data_3d <= s444_data_2d; + end + end + + // get the average 0.25*s(n-1) + 0.5*s(n) + 0.25*s(n+1) + + assign cr_s = {2'd0, s444_data_d[23:16]} + + {2'd0, s444_data_3d[23:16]} + + {1'd0, s444_data_2d[23:16], 1'd0}; + + assign cb_s = {2'd0, s444_data_d[7:0]} + + {2'd0, s444_data_3d[7:0]} + + {1'd0, s444_data_2d[7:0], 1'd0}; + + always @(posedge clk) begin + cr <= cr_s[9:2]; + cb <= cb_s[9:2]; + if (s444_de_3d == 1'b1) begin + cr_cb_sel <= ~cr_cb_sel; + end else begin + cr_cb_sel <= CR_CB_N; + end + end + + // 422 outputs + + always @(posedge clk) begin + s422_sync <= s444_sync_3d; + if (s444_de_3d == 1'b0) begin + s422_data <= 'd0; + end else if (cr_cb_sel == 1'b1) begin + s422_data <= {cr, s444_data_3d[15:8]}; + end else begin + s422_data <= {cb, s444_data_3d[15:8]}; + end + end + +endmodule + +// *************************************************************************** +// *************************************************************************** diff --git a/src/adi/hdl/library/common/ad_sysref_gen.v b/src/adi/hdl/library/common/ad_sysref_gen.v new file mode 100644 index 00000000..1b255eab --- /dev/null +++ b/src/adi/hdl/library/common/ad_sysref_gen.v @@ -0,0 +1,85 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright 2014 - 2017 (c) Analog Devices, Inc. All rights reserved. +// +// In this HDL repository, there are many different and unique modules, consisting +// of various HDL (Verilog or VHDL) components. The individual modules are +// developed independently, and may be accompanied by separate and unique license +// terms. +// +// The user should read each of these license terms, and understand the +// freedoms and responsibilities that he or she has by using this source/core. +// +// This core 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. +// +// Redistribution and use of source or resulting binaries, with or without modification +// of this file, are permitted under one of the following two license terms: +// +// 1. The GNU General Public License version 2 as published by the +// Free Software Foundation, which can be found in the top level directory +// of this repository (LICENSE_GPL2), and also online at: +// +// +// OR +// +// 2. An ADI specific BSD license, which can be found in the top level directory +// of this repository (LICENSE_ADIBSD), and also on-line at: +// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD +// This will allow to generate bit files and not release the source code, +// as long as it attaches to an ADI device. +// +// *************************************************************************** +// *************************************************************************** + +`timescale 1ns/100ps + +module ad_sysref_gen ( + + input core_clk, + + input sysref_en, + output reg sysref_out +); + + // SYSREF period is multiple of core_clk, and has a duty cycle of 50% + // NOTE: if SYSREF always on (this is a JESD204 IP configuration), + // the period must be a correct multiple of the multiframe period + parameter SYSREF_PERIOD = 128; + + localparam SYSREF_HALFPERIOD = SYSREF_PERIOD/2 - 1; + + reg [ 7:0] counter; + reg sysref_en_m1; + reg sysref_en_m2; + reg sysref_en_int; + + // bring the enable signal to JESD core clock domain + always @(posedge core_clk) begin + sysref_en_m1 <= sysref_en; + sysref_en_m2 <= sysref_en_m1; + sysref_en_int <= sysref_en_m2; + end + + // free running counter for periodic SYSREF generation + always @(posedge core_clk) begin + if (sysref_en_int) begin + counter <= (counter < SYSREF_HALFPERIOD) ? counter + 1'b1 : 8'h0; + end else begin + counter <= 8'h0; + end + end + + // generate SYSREF + always @(posedge core_clk) begin + if (sysref_en_int) begin + if (counter == SYSREF_HALFPERIOD) begin + sysref_out <= ~sysref_out; + end + end else begin + sysref_out <= 1'b0; + end + end + +endmodule diff --git a/src/adi/hdl/library/common/ad_tdd_control.v b/src/adi/hdl/library/common/ad_tdd_control.v new file mode 100644 index 00000000..31658982 --- /dev/null +++ b/src/adi/hdl/library/common/ad_tdd_control.v @@ -0,0 +1,834 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright 2014 - 2017 (c) Analog Devices, Inc. All rights reserved. +// +// In this HDL repository, there are many different and unique modules, consisting +// of various HDL (Verilog or VHDL) components. The individual modules are +// developed independently, and may be accompanied by separate and unique license +// terms. +// +// The user should read each of these license terms, and understand the +// freedoms and responsibilities that he or she has by using this source/core. +// +// This core 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. +// +// Redistribution and use of source or resulting binaries, with or without modification +// of this file, are permitted under one of the following two license terms: +// +// 1. The GNU General Public License version 2 as published by the +// Free Software Foundation, which can be found in the top level directory +// of this repository (LICENSE_GPL2), and also online at: +// +// +// OR +// +// 2. An ADI specific BSD license, which can be found in the top level directory +// of this repository (LICENSE_ADIBSD), and also on-line at: +// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD +// This will allow to generate bit files and not release the source code, +// as long as it attaches to an ADI device. +// +// *************************************************************************** +// *************************************************************************** + +`timescale 1ns/1ps + +module ad_tdd_control#( + + parameter integer TX_DATA_PATH_DELAY = 0, + parameter integer CONTROL_PATH_DELAY = 0) ( + + // clock and reset + + input clk, + input rst, + + // TDD timing signals + + input tdd_enable, + input tdd_secondary, + input tdd_tx_only, + input tdd_rx_only, + input [ 7:0] tdd_burst_count, + input [23:0] tdd_counter_init, + input [23:0] tdd_frame_length, + input [23:0] tdd_vco_rx_on_1, + input [23:0] tdd_vco_rx_off_1, + input [23:0] tdd_vco_tx_on_1, + input [23:0] tdd_vco_tx_off_1, + input [23:0] tdd_rx_on_1, + input [23:0] tdd_rx_off_1, + input [23:0] tdd_rx_dp_on_1, + input [23:0] tdd_rx_dp_off_1, + input [23:0] tdd_tx_on_1, + input [23:0] tdd_tx_off_1, + input [23:0] tdd_tx_dp_on_1, + input [23:0] tdd_tx_dp_off_1, + input [23:0] tdd_vco_rx_on_2, + input [23:0] tdd_vco_rx_off_2, + input [23:0] tdd_vco_tx_on_2, + input [23:0] tdd_vco_tx_off_2, + input [23:0] tdd_rx_on_2, + input [23:0] tdd_rx_off_2, + input [23:0] tdd_rx_dp_on_2, + input [23:0] tdd_rx_dp_off_2, + input [23:0] tdd_tx_on_2, + input [23:0] tdd_tx_off_2, + input [23:0] tdd_tx_dp_on_2, + input [23:0] tdd_tx_dp_off_2, + input tdd_sync, + + // TDD control signals + + output reg tdd_tx_dp_en, + output reg tdd_rx_dp_en, + output reg tdd_rx_vco_en, + output reg tdd_tx_vco_en, + output reg tdd_rx_rf_en, + output reg tdd_tx_rf_en, + + output [23:0] tdd_counter_status); + + + localparam ON = 1; + localparam OFF = 0; + + // tdd control related + + // tdd counter related + + reg [23:0] tdd_counter = 24'h0; + reg [ 5:0] tdd_burst_counter = 6'h0; + + reg tdd_cstate = OFF; + reg tdd_cstate_next = OFF; + + reg counter_at_tdd_vco_rx_on_1 = 1'b0; + reg counter_at_tdd_vco_rx_off_1 = 1'b0; + reg counter_at_tdd_vco_tx_on_1 = 1'b0; + reg counter_at_tdd_vco_tx_off_1 = 1'b0; + reg counter_at_tdd_rx_on_1 = 1'b0; + reg counter_at_tdd_rx_off_1 = 1'b0; + reg counter_at_tdd_rx_dp_on_1 = 1'b0; + reg counter_at_tdd_rx_dp_off_1 = 1'b0; + reg counter_at_tdd_tx_on_1 = 1'b0; + reg counter_at_tdd_tx_off_1 = 1'b0; + reg counter_at_tdd_tx_dp_on_1 = 1'b0; + reg counter_at_tdd_tx_dp_off_1 = 1'b0; + reg counter_at_tdd_vco_rx_on_2 = 1'b0; + reg counter_at_tdd_vco_rx_off_2 = 1'b0; + reg counter_at_tdd_vco_tx_on_2 = 1'b0; + reg counter_at_tdd_vco_tx_off_2 = 1'b0; + reg counter_at_tdd_rx_on_2 = 1'b0; + reg counter_at_tdd_rx_off_2 = 1'b0; + reg counter_at_tdd_rx_dp_on_2 = 1'b0; + reg counter_at_tdd_rx_dp_off_2 = 1'b0; + reg counter_at_tdd_tx_on_2 = 1'b0; + reg counter_at_tdd_tx_off_2 = 1'b0; + reg counter_at_tdd_tx_dp_on_2 = 1'b0; + reg counter_at_tdd_tx_dp_off_2 = 1'b0; + + reg tdd_last_burst = 1'b0; + + reg tdd_sync_d1 = 1'b0; + reg tdd_sync_d2 = 1'b0; + reg tdd_sync_d3 = 1'b0; + + reg tdd_endof_frame = 1'b0; + + // internal signals + + wire [23:0] tdd_vco_rx_on_1_s; + wire [23:0] tdd_vco_rx_off_1_s; + wire [23:0] tdd_vco_tx_on_1_s; + wire [23:0] tdd_vco_tx_off_1_s; + wire [23:0] tdd_rx_on_1_s; + wire [23:0] tdd_rx_off_1_s; + wire [23:0] tdd_tx_on_1_s; + wire [23:0] tdd_tx_off_1_s; + wire [23:0] tdd_tx_dp_on_1_s; + wire [23:0] tdd_tx_dp_off_1_s; + + wire [23:0] tdd_vco_rx_on_2_s; + wire [23:0] tdd_vco_rx_off_2_s; + wire [23:0] tdd_vco_tx_on_2_s; + wire [23:0] tdd_vco_tx_off_2_s; + wire [23:0] tdd_rx_on_2_s; + wire [23:0] tdd_rx_off_2_s; + wire [23:0] tdd_tx_on_2_s; + wire [23:0] tdd_tx_off_2_s; + wire [23:0] tdd_tx_dp_on_2_s; + wire [23:0] tdd_tx_dp_off_2_s; + wire tdd_endof_burst; + wire tdd_txrx_only_en_s; + + assign tdd_counter_status = tdd_counter; + + // synchronization of tdd_sync + always @(posedge clk) begin + if (rst == 1'b1) begin + tdd_sync_d1 <= 1'b0; + tdd_sync_d2 <= 1'b0; + tdd_sync_d3 <= 1'b0; + end else begin + tdd_sync_d1 <= tdd_sync; + tdd_sync_d2 <= tdd_sync_d1; + tdd_sync_d3 <= tdd_sync_d2; + end + end + + // *************************************************************************** + // tdd counter (state machine) + // *************************************************************************** + + always @(posedge clk) begin + if (rst == 1'b1) begin + tdd_cstate <= OFF; + end else begin + tdd_cstate <= tdd_cstate_next; + end + end + + always @* begin + tdd_cstate_next <= tdd_cstate; + + case (tdd_cstate) + ON : begin + if ((tdd_enable == 1'b0) || (tdd_endof_burst == 1'b1)) begin + tdd_cstate_next <= OFF; + end + end + + OFF : begin + if(tdd_enable == 1'b1) begin + tdd_cstate_next <= ((~tdd_sync_d3 & tdd_sync_d2) == 1'b1) ? ON : OFF; + end + end + endcase + end + + always @(posedge clk) begin + if (tdd_counter == (tdd_frame_length - 1'b1)) begin + tdd_endof_frame <= 1'b1; + end else begin + tdd_endof_frame <= 1'b0; + end + end + assign tdd_endof_burst = ((tdd_last_burst == 1'b1) && (tdd_endof_frame == 1'b1)) ? 1'b1 : 1'b0; + + // tdd free running counter + always @(posedge clk) begin + if (rst == 1'b1) begin + tdd_counter <= tdd_counter_init; + end else begin + if (tdd_cstate == ON) begin + if ((~tdd_sync_d3 & tdd_sync_d2) == 1'b1) begin + tdd_counter <= 24'b0; + end else begin + tdd_counter <= (tdd_endof_frame == 1'b1) ? 24'b0 : tdd_counter + 1'b1; + end + end else begin + tdd_counter <= tdd_counter_init; + end + end + end + + // tdd burst counter + always @(posedge clk) begin + if (tdd_cstate == OFF) begin + tdd_burst_counter <= tdd_burst_count; + end else if ((tdd_burst_counter != 0) && (tdd_endof_frame == 1'b1)) begin + tdd_burst_counter <= tdd_burst_counter - 1'b1; + end + end + + always @(posedge clk) begin + tdd_last_burst <= (tdd_burst_counter == 6'b1) ? 1'b1 : 1'b0; + end + + // *************************************************************************** + // generate control signals + // *************************************************************************** + + // start/stop rx vco + always @(posedge clk) begin + if(rst == 1'b1) begin + counter_at_tdd_vco_rx_on_1 <= 1'b0; + end else if(tdd_counter == tdd_vco_rx_on_1_s) begin + counter_at_tdd_vco_rx_on_1 <= 1'b1; + end else begin + counter_at_tdd_vco_rx_on_1 <= 1'b0; + end + end + + always @(posedge clk) begin + if(rst == 1'b1) begin + counter_at_tdd_vco_rx_on_2 <= 1'b0; + end else if((tdd_secondary == 1'b1) && (tdd_counter == tdd_vco_rx_on_2_s)) begin + counter_at_tdd_vco_rx_on_2 <= 1'b1; + end else begin + counter_at_tdd_vco_rx_on_2 <= 1'b0; + end + end + + always @(posedge clk) begin + if(rst == 1'b1) begin + counter_at_tdd_vco_rx_off_1 <= 1'b0; + end else if(tdd_counter == tdd_vco_rx_off_1_s) begin + counter_at_tdd_vco_rx_off_1 <= 1'b1; + end else begin + counter_at_tdd_vco_rx_off_1 <= 1'b0; + end + end + + always @(posedge clk) begin + if(rst == 1'b1) begin + counter_at_tdd_vco_rx_off_2 <= 1'b0; + end else if((tdd_secondary == 1'b1) && (tdd_counter == tdd_vco_rx_off_2_s)) begin + counter_at_tdd_vco_rx_off_2 <= 1'b1; + end else begin + counter_at_tdd_vco_rx_off_2 <= 1'b0; + end + end + + // start/stop tx vco + always @(posedge clk) begin + if(rst == 1'b1) begin + counter_at_tdd_vco_tx_on_1 <= 1'b0; + end else if(tdd_counter == tdd_vco_tx_on_1_s) begin + counter_at_tdd_vco_tx_on_1 <= 1'b1; + end else begin + counter_at_tdd_vco_tx_on_1 <= 1'b0; + end + end + + always @(posedge clk) begin + if(rst == 1'b1) begin + counter_at_tdd_vco_tx_on_2 <= 1'b0; + end else if((tdd_secondary == 1'b1) && (tdd_counter == tdd_vco_tx_on_2_s)) begin + counter_at_tdd_vco_tx_on_2 <= 1'b1; + end else begin + counter_at_tdd_vco_tx_on_2 <= 1'b0; + end + end + + always @(posedge clk) begin + if(rst == 1'b1) begin + counter_at_tdd_vco_tx_off_1 <= 1'b0; + end else if(tdd_counter == tdd_vco_tx_off_1_s) begin + counter_at_tdd_vco_tx_off_1 <= 1'b1; + end else begin + counter_at_tdd_vco_tx_off_1 <= 1'b0; + end + end + + always @(posedge clk) begin + if(rst == 1'b1) begin + counter_at_tdd_vco_tx_off_2 <= 1'b0; + end else if((tdd_secondary == 1'b1) && (tdd_counter == tdd_vco_tx_off_2_s)) begin + counter_at_tdd_vco_tx_off_2 <= 1'b1; + end else begin + counter_at_tdd_vco_tx_off_2 <= 1'b0; + end + end + + // start/stop rx rf path + always @(posedge clk) begin + if(rst == 1'b1) begin + counter_at_tdd_rx_on_1 <= 1'b0; + end else if(tdd_counter == tdd_rx_on_1_s) begin + counter_at_tdd_rx_on_1 <= 1'b1; + end else begin + counter_at_tdd_rx_on_1 <= 1'b0; + end + end + + always @(posedge clk) begin + if(rst == 1'b1) begin + counter_at_tdd_rx_on_2 <= 1'b0; + end else if((tdd_secondary == 1'b1) && (tdd_counter == tdd_rx_on_2_s)) begin + counter_at_tdd_rx_on_2 <= 1'b1; + end else begin + counter_at_tdd_rx_on_2 <= 1'b0; + end + end + + always @(posedge clk) begin + if(rst == 1'b1) begin + counter_at_tdd_rx_off_1 <= 1'b0; + end else if(tdd_counter == tdd_rx_off_1_s) begin + counter_at_tdd_rx_off_1 <= 1'b1; + end else begin + counter_at_tdd_rx_off_1 <= 1'b0; + end + end + + always @(posedge clk) begin + if(rst == 1'b1) begin + counter_at_tdd_rx_off_2 <= 1'b0; + end else if((tdd_secondary == 1'b1) && (tdd_counter == tdd_rx_off_2_s)) begin + counter_at_tdd_rx_off_2 <= 1'b1; + end else begin + counter_at_tdd_rx_off_2 <= 1'b0; + end + end + + // start/stop tx rf path + always @(posedge clk) begin + if(rst == 1'b1) begin + counter_at_tdd_tx_on_1 <= 1'b0; + end else if(tdd_counter == tdd_tx_on_1_s) begin + counter_at_tdd_tx_on_1 <= 1'b1; + end else begin + counter_at_tdd_tx_on_1 <= 1'b0; + end + end + + always @(posedge clk) begin + if(rst == 1'b1) begin + counter_at_tdd_tx_on_2 <= 1'b0; + end else if((tdd_secondary == 1'b1) && (tdd_counter == tdd_tx_on_2_s)) begin + counter_at_tdd_tx_on_2 <= 1'b1; + end else begin + counter_at_tdd_tx_on_2 <= 1'b0; + end + end + + always @(posedge clk) begin + if(rst == 1'b1) begin + counter_at_tdd_tx_off_1 <= 1'b0; + end else if(tdd_counter == tdd_tx_off_1_s) begin + counter_at_tdd_tx_off_1 <= 1'b1; + end else begin + counter_at_tdd_tx_off_1 <= 1'b0; + end + end + + always @(posedge clk) begin + if(rst == 1'b1) begin + counter_at_tdd_tx_off_2 <= 1'b0; + end else if((tdd_secondary == 1'b1) && (tdd_counter == tdd_tx_off_2_s)) begin + counter_at_tdd_tx_off_2 <= 1'b1; + end else begin + counter_at_tdd_tx_off_2 <= 1'b0; + end + end + + // start/stop tx data path + always @(posedge clk) begin + if(rst == 1'b1) begin + counter_at_tdd_tx_dp_on_1 <= 1'b0; + end else if(tdd_counter == tdd_tx_dp_on_1_s) begin + counter_at_tdd_tx_dp_on_1 <= 1'b1; + end else begin + counter_at_tdd_tx_dp_on_1 <= 1'b0; + end + end + + always @(posedge clk) begin + if(rst == 1'b1) begin + counter_at_tdd_tx_dp_on_2 <= 1'b0; + end else if((tdd_secondary == 1'b1) && (tdd_counter == tdd_tx_dp_on_2_s)) begin + counter_at_tdd_tx_dp_on_2 <= 1'b1; + end else begin + counter_at_tdd_tx_dp_on_2 <= 1'b0; + end + end + + always @(posedge clk) begin + if(rst == 1'b1) begin + counter_at_tdd_tx_dp_off_1 <= 1'b0; + end else if(tdd_counter == tdd_tx_dp_off_1_s) begin + counter_at_tdd_tx_dp_off_1 <= 1'b1; + end else begin + counter_at_tdd_tx_dp_off_1 <= 1'b0; + end + end + + always @(posedge clk) begin + if(rst == 1'b1) begin + counter_at_tdd_tx_dp_off_2 <= 1'b0; + end else if((tdd_secondary == 1'b1) && (tdd_counter == tdd_tx_dp_off_2_s)) begin + counter_at_tdd_tx_dp_off_2 <= 1'b1; + end else begin + counter_at_tdd_tx_dp_off_2 <= 1'b0; + end + end + + // start/stop rx data path + always @(posedge clk) begin + if(rst == 1'b1) begin + counter_at_tdd_rx_dp_on_1 <= 1'b0; + end else if(tdd_counter == tdd_rx_dp_on_1) begin + counter_at_tdd_rx_dp_on_1 <= 1'b1; + end else begin + counter_at_tdd_rx_dp_on_1 <= 1'b0; + end + end + + always @(posedge clk) begin + if(rst == 1'b1) begin + counter_at_tdd_rx_dp_on_2 <= 1'b0; + end else if((tdd_secondary == 1'b1) && (tdd_counter == tdd_rx_dp_on_2)) begin + counter_at_tdd_rx_dp_on_2 <= 1'b1; + end else begin + counter_at_tdd_rx_dp_on_2 <= 1'b0; + end + end + + always @(posedge clk) begin + if(rst == 1'b1) begin + counter_at_tdd_rx_dp_off_1 <= 1'b0; + end else if(tdd_counter == tdd_rx_dp_off_1) begin + counter_at_tdd_rx_dp_off_1 <= 1'b1; + end else begin + counter_at_tdd_rx_dp_off_1 <= 1'b0; + end + end + + always @(posedge clk) begin + if(rst == 1'b1) begin + counter_at_tdd_rx_dp_off_2 <= 1'b0; + end else if((tdd_secondary == 1'b1) && (tdd_counter == tdd_rx_dp_off_2)) begin + counter_at_tdd_rx_dp_off_2 <= 1'b1; + end else begin + counter_at_tdd_rx_dp_off_2 <= 1'b0; + end + end + + // control-path delay compensation + + ad_addsub #( + .A_DATA_WIDTH(24), + .B_DATA_VALUE(CONTROL_PATH_DELAY), + .ADD_OR_SUB_N(0) + ) i_vco_rx_on_1_comp ( + .clk(clk), + .A(tdd_vco_rx_on_1), + .Amax(tdd_frame_length), + .out(tdd_vco_rx_on_1_s), + .CE(1'b1) + ); + + ad_addsub #( + .A_DATA_WIDTH(24), + .B_DATA_VALUE(CONTROL_PATH_DELAY), + .ADD_OR_SUB_N(0) + ) i_vco_rx_off_1_comp ( + .clk(clk), + .A(tdd_vco_rx_off_1), + .Amax(tdd_frame_length), + .out(tdd_vco_rx_off_1_s), + .CE(1'b1) + ); + + ad_addsub #( + .A_DATA_WIDTH(24), + .B_DATA_VALUE(CONTROL_PATH_DELAY), + .ADD_OR_SUB_N(0) + ) i_vco_tx_on_1_comp ( + .clk(clk), + .A(tdd_vco_tx_on_1), + .Amax(tdd_frame_length), + .out(tdd_vco_tx_on_1_s), + .CE(1'b1) + ); + + ad_addsub #( + .A_DATA_WIDTH(24), + .B_DATA_VALUE(CONTROL_PATH_DELAY), + .ADD_OR_SUB_N(0) + ) i_vco_tx_off_1_comp ( + .clk(clk), + .A(tdd_vco_tx_off_1), + .Amax(tdd_frame_length), + .out(tdd_vco_tx_off_1_s), + .CE(1'b1) + ); + + ad_addsub #( + .A_DATA_WIDTH(24), + .B_DATA_VALUE(CONTROL_PATH_DELAY), + .ADD_OR_SUB_N(0) + ) i_rx_on_1_comp ( + .clk(clk), + .A(tdd_rx_on_1), + .Amax(tdd_frame_length), + .out(tdd_rx_on_1_s), + .CE(1'b1) + ); + + ad_addsub #( + .A_DATA_WIDTH(24), + .B_DATA_VALUE(CONTROL_PATH_DELAY), + .ADD_OR_SUB_N(0) + ) i_rx_off_1_comp ( + .clk(clk), + .A(tdd_rx_off_1), + .Amax(tdd_frame_length), + .out(tdd_rx_off_1_s), + .CE(1'b1) + ); + + ad_addsub #( + .A_DATA_WIDTH(24), + .B_DATA_VALUE(CONTROL_PATH_DELAY), + .ADD_OR_SUB_N(0) + ) i_tx_on_1_comp ( + .clk(clk), + .A(tdd_tx_on_1), + .Amax(tdd_frame_length), + .out(tdd_tx_on_1_s), + .CE(1'b1) + ); + + ad_addsub #( + .A_DATA_WIDTH(24), + .B_DATA_VALUE(CONTROL_PATH_DELAY), + .ADD_OR_SUB_N(0) + ) i_tx_off_1_comp ( + .clk(clk), + .A(tdd_tx_off_1), + .Amax(tdd_frame_length), + .out(tdd_tx_off_1_s), + .CE(1'b1) + ); + + ad_addsub #( + .A_DATA_WIDTH(24), + .B_DATA_VALUE(CONTROL_PATH_DELAY), + .ADD_OR_SUB_N(0) + ) i_vco_rx_on_2_comp ( + .clk(clk), + .A(tdd_vco_rx_on_2), + .Amax(tdd_frame_length), + .out(tdd_vco_rx_on_2_s), + .CE(1'b1) + ); + + ad_addsub #( + .A_DATA_WIDTH(24), + .B_DATA_VALUE(CONTROL_PATH_DELAY), + .ADD_OR_SUB_N(0) + ) i_vco_rx_off_2_comp ( + .clk(clk), + .A(tdd_vco_rx_off_2), + .Amax(tdd_frame_length), + .out(tdd_vco_rx_off_2_s), + .CE(1'b1) + ); + + ad_addsub #( + .A_DATA_WIDTH(24), + .B_DATA_VALUE(CONTROL_PATH_DELAY), + .ADD_OR_SUB_N(0) + ) i_vco_tx_on_2_comp ( + .clk(clk), + .A(tdd_vco_tx_on_2), + .Amax(tdd_frame_length), + .out(tdd_vco_tx_on_2_s), + .CE(1'b1) + ); + + ad_addsub #( + .A_DATA_WIDTH(24), + .B_DATA_VALUE(CONTROL_PATH_DELAY), + .ADD_OR_SUB_N(0) + ) i_vco_tx_off_2_comp ( + .clk(clk), + .A(tdd_vco_tx_off_2), + .Amax(tdd_frame_length), + .out(tdd_vco_tx_off_2_s), + .CE(1'b1) + ); + + ad_addsub #( + .A_DATA_WIDTH(24), + .B_DATA_VALUE(CONTROL_PATH_DELAY), + .ADD_OR_SUB_N(0) + ) i_rx_on_2_comp ( + .clk(clk), + .A(tdd_rx_on_2), + .Amax(tdd_frame_length), + .out(tdd_rx_on_2_s), + .CE(1'b1) + ); + + ad_addsub #( + .A_DATA_WIDTH(24), + .B_DATA_VALUE(CONTROL_PATH_DELAY), + .ADD_OR_SUB_N(0) + ) i_rx_off_2_comp ( + .clk(clk), + .A(tdd_rx_off_2), + .Amax(tdd_frame_length), + .out(tdd_rx_off_2_s), + .CE(1'b1) + ); + + ad_addsub #( + .A_DATA_WIDTH(24), + .B_DATA_VALUE(CONTROL_PATH_DELAY), + .ADD_OR_SUB_N(0) + ) i_tx_on_2_comp ( + .clk(clk), + .A(tdd_tx_on_2), + .Amax(tdd_frame_length), + .out(tdd_tx_on_2_s), + .CE(1'b1) + ); + + ad_addsub #( + .A_DATA_WIDTH(24), + .B_DATA_VALUE(CONTROL_PATH_DELAY), + .ADD_OR_SUB_N(0) + ) i_tx_off_2_comp ( + .clk(clk), + .A(tdd_tx_off_2), + .Amax(tdd_frame_length), + .out(tdd_tx_off_2_s), + .CE(1'b1) + ); + + // internal data-path delay compensation + + ad_addsub #( + .A_DATA_WIDTH(24), + .B_DATA_VALUE(TX_DATA_PATH_DELAY), + .ADD_OR_SUB_N(0) + ) i_tx_dp_on_1_comp ( + .clk(clk), + .A(tdd_tx_dp_on_1), + .Amax(tdd_frame_length), + .out(tdd_tx_dp_on_1_s), + .CE(1'b1) + ); + + ad_addsub #( + .A_DATA_WIDTH(24), + .B_DATA_VALUE(TX_DATA_PATH_DELAY), + .ADD_OR_SUB_N(0) + ) i_tx_dp_on_2_comp ( + .clk(clk), + .A(tdd_tx_dp_on_2), + .Amax(tdd_frame_length), + .out(tdd_tx_dp_on_2_s), + .CE(1'b1) + ); + + ad_addsub #( + .A_DATA_WIDTH(24), + .B_DATA_VALUE(TX_DATA_PATH_DELAY), + .ADD_OR_SUB_N(0) + ) i_tx_dp_off_1_comp ( + .clk(clk), + .A(tdd_tx_dp_off_1), + .Amax(tdd_frame_length), + .out(tdd_tx_dp_off_1_s), + .CE(1'b1) + ); + + ad_addsub #( + .A_DATA_WIDTH(24), + .B_DATA_VALUE(TX_DATA_PATH_DELAY), + .ADD_OR_SUB_N(0) + ) i_tx_dp_off_2_comp ( + .clk(clk), + .A(tdd_tx_dp_off_2), + .Amax(tdd_frame_length), + .out(tdd_tx_dp_off_2_s), + .CE(1'b1) + ); + + // output logic + + assign tdd_txrx_only_en_s = tdd_tx_only ^ tdd_rx_only; + + always @(posedge clk) begin + if(rst == 1'b1) begin + tdd_rx_vco_en <= 1'b0; + end else if((tdd_cstate == OFF) || (counter_at_tdd_vco_rx_off_1 == 1'b1) || (counter_at_tdd_vco_rx_off_2 == 1'b1)) begin + tdd_rx_vco_en <= 1'b0; + end else if((tdd_cstate == ON) && ((counter_at_tdd_vco_rx_on_1 == 1'b1) || (counter_at_tdd_vco_rx_on_2 == 1'b1))) begin + tdd_rx_vco_en <= 1'b1; + end else if((tdd_cstate == ON) && (tdd_txrx_only_en_s == 1'b1)) begin + tdd_rx_vco_en <= tdd_rx_only; + end else begin + tdd_rx_vco_en <= tdd_rx_vco_en; + end + end + + always @(posedge clk) begin + if(rst == 1'b1) begin + tdd_tx_vco_en <= 1'b0; + end else if((tdd_cstate == OFF) || (counter_at_tdd_vco_tx_off_1 == 1'b1) || (counter_at_tdd_vco_tx_off_2 == 1'b1)) begin + tdd_tx_vco_en <= 1'b0; + end else if((tdd_cstate == ON) && ((counter_at_tdd_vco_tx_on_1 == 1'b1) || (counter_at_tdd_vco_tx_on_2 == 1'b1))) begin + tdd_tx_vco_en <= 1'b1; + end else if((tdd_cstate == ON) && (tdd_txrx_only_en_s == 1'b1)) begin + tdd_tx_vco_en <= tdd_tx_only; + end else begin + tdd_tx_vco_en <= tdd_tx_vco_en; + end + end + + always @(posedge clk) begin + if(rst == 1'b1) begin + tdd_rx_rf_en <= 1'b0; + end else if((tdd_cstate == OFF) || (counter_at_tdd_rx_off_1 == 1'b1) || (counter_at_tdd_rx_off_2 == 1'b1)) begin + tdd_rx_rf_en <= 1'b0; + end else if((tdd_cstate == ON) && ((counter_at_tdd_rx_on_1 == 1'b1) || (counter_at_tdd_rx_on_2 == 1'b1))) begin + tdd_rx_rf_en <= 1'b1; + end else if((tdd_cstate == ON) && (tdd_txrx_only_en_s == 1'b1)) begin + tdd_rx_rf_en <= tdd_rx_only; + end else begin + tdd_rx_rf_en <= tdd_rx_rf_en; + end + end + + always @(posedge clk) begin + if(rst == 1'b1) begin + tdd_tx_rf_en <= 1'b0; + end else if((tdd_cstate == OFF) || (counter_at_tdd_tx_off_1 == 1'b1) || (counter_at_tdd_tx_off_2 == 1'b1)) begin + tdd_tx_rf_en <= 1'b0; + end else if((tdd_cstate == ON) && ((counter_at_tdd_tx_on_1 == 1'b1) || (counter_at_tdd_tx_on_2 == 1'b1))) begin + tdd_tx_rf_en <= 1'b1; + end else if((tdd_cstate == ON) && (tdd_txrx_only_en_s == 1'b1)) begin + tdd_tx_rf_en <= tdd_tx_only; + end else begin + tdd_tx_rf_en <= tdd_tx_rf_en; + end + end + + always @(posedge clk) begin + if(rst == 1'b1) begin + tdd_tx_dp_en <= 1'b0; + end else if((tdd_cstate == OFF) || (counter_at_tdd_tx_dp_off_1 == 1'b1) || (counter_at_tdd_tx_dp_off_2 == 1'b1)) begin + tdd_tx_dp_en <= 1'b0; + end else if((tdd_cstate == ON) && ((counter_at_tdd_tx_dp_on_1 == 1'b1) || (counter_at_tdd_tx_dp_on_2 == 1'b1))) begin + tdd_tx_dp_en <= 1'b1; + end else if((tdd_cstate == ON) && (tdd_txrx_only_en_s == 1'b1)) begin + tdd_tx_dp_en <= tdd_tx_only; + end else begin + tdd_tx_dp_en <= tdd_tx_dp_en; + end + end + + always @(posedge clk) begin + if(rst == 1'b1) begin + tdd_rx_dp_en <= 1'b0; + end else if((tdd_cstate == OFF) || (counter_at_tdd_rx_dp_off_1 == 1'b1) || (counter_at_tdd_rx_dp_off_2 == 1'b1)) begin + tdd_rx_dp_en <= 1'b0; + end else if((tdd_cstate == ON) && ((counter_at_tdd_rx_dp_on_1 == 1'b1) || (counter_at_tdd_rx_dp_on_2 == 1'b1))) begin + tdd_rx_dp_en <= 1'b1; + end else if((tdd_cstate == ON) && (tdd_txrx_only_en_s == 1'b1)) begin + tdd_rx_dp_en <= tdd_rx_only; + end else begin + tdd_rx_dp_en <= tdd_rx_dp_en; + end + end + +endmodule + diff --git a/src/adi/hdl/library/common/ad_xcvr_rx_if.v b/src/adi/hdl/library/common/ad_xcvr_rx_if.v new file mode 100644 index 00000000..614ab001 --- /dev/null +++ b/src/adi/hdl/library/common/ad_xcvr_rx_if.v @@ -0,0 +1,80 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright 2014 - 2017 (c) Analog Devices, Inc. All rights reserved. +// +// In this HDL repository, there are many different and unique modules, consisting +// of various HDL (Verilog or VHDL) components. The individual modules are +// developed independently, and may be accompanied by separate and unique license +// terms. +// +// The user should read each of these license terms, and understand the +// freedoms and responsibilities that he or she has by using this source/core. +// +// This core 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. +// +// Redistribution and use of source or resulting binaries, with or without modification +// of this file, are permitted under one of the following two license terms: +// +// 1. The GNU General Public License version 2 as published by the +// Free Software Foundation, which can be found in the top level directory +// of this repository (LICENSE_GPL2), and also online at: +// +// +// OR +// +// 2. An ADI specific BSD license, which can be found in the top level directory +// of this repository (LICENSE_ADIBSD), and also on-line at: +// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD +// This will allow to generate bit files and not release the source code, +// as long as it attaches to an ADI device. +// +// *************************************************************************** +// *************************************************************************** + +`timescale 1ns/100ps + +module ad_xcvr_rx_if ( + + // jesd interface + + input rx_clk, + input [ 3:0] rx_ip_sof, + input [31:0] rx_ip_data, + output reg rx_sof, + output reg [31:0] rx_data); + + + // internal registers + + reg [31:0] rx_ip_data_d = 'd0; + reg [ 3:0] rx_ip_sof_hold = 'd0; + reg [ 3:0] rx_ip_sof_d = 'd0; + + // dword may contain more than one frame per clock + + always @(posedge rx_clk) begin + rx_ip_data_d <= rx_ip_data; + rx_ip_sof_d <= rx_ip_sof; + if (rx_ip_sof != 4'h0) begin + rx_ip_sof_hold <= rx_ip_sof; + end + rx_sof <= |rx_ip_sof_d; + if (rx_ip_sof_hold[0] == 1'b1) begin + rx_data <= rx_ip_data; + end else if (rx_ip_sof_hold[1] == 1'b1) begin + rx_data <= {rx_ip_data[ 7:0], rx_ip_data_d[31: 8]}; + end else if (rx_ip_sof_hold[2] == 1'b1) begin + rx_data <= {rx_ip_data[15:0], rx_ip_data_d[31:16]}; + end else if (rx_ip_sof_hold[3] == 1'b1) begin + rx_data <= {rx_ip_data[23:0], rx_ip_data_d[31:24]}; + end else begin + rx_data <= 32'd0; + end + end + +endmodule + +// *************************************************************************** +// *************************************************************************** diff --git a/src/adi/hdl/library/common/axi_ctrlif.vhd b/src/adi/hdl/library/common/axi_ctrlif.vhd new file mode 100644 index 00000000..ddf25aeb --- /dev/null +++ b/src/adi/hdl/library/common/axi_ctrlif.vhd @@ -0,0 +1,148 @@ +-- *************************************************************************** +-- *************************************************************************** +-- Copyright 2014 - 2017 (c) Analog Devices, Inc. All rights reserved. +-- +-- In this HDL repository, there are many different and unique modules, consisting +-- of various HDL (Verilog or VHDL) components. The individual modules are +-- developed independently, and may be accompanied by separate and unique license +-- terms. +-- +-- The user should read each of these license terms, and understand the +-- freedoms and responsibilities that he or she has by using this source/core. +-- +-- This core 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. +-- +-- Redistribution and use of source or resulting binaries, with or without modification +-- of this file, are permitted under one of the following two license terms: +-- +-- 1. The GNU General Public License version 2 as published by the +-- Free Software Foundation, which can be found in the top level directory +-- of this repository (LICENSE_GPL2), and also online at: +-- +-- +-- OR +-- +-- 2. An ADI specific BSD license, which can be found in the top level directory +-- of this repository (LICENSE_ADIBSD), and also on-line at: +-- https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD +-- This will allow to generate bit files and not release the source code, +-- as long as it attaches to an ADI device. +-- +-- *************************************************************************** +-- *************************************************************************** + +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +entity axi_ctrlif is + generic + ( + C_NUM_REG : integer := 32; + C_S_AXI_DATA_WIDTH : integer := 32; + C_S_AXI_ADDR_WIDTH : integer := 32; + C_FAMILY : string := "virtex6" + ); + port + ( + -- AXI bus interface + s_axi_aclk : in std_logic; + s_axi_aresetn : in std_logic; + s_axi_awaddr : in std_logic_vector(C_S_AXI_ADDR_WIDTH-1 downto 0); + s_axi_awvalid : in std_logic; + s_axi_wdata : in std_logic_vector(C_S_AXI_DATA_WIDTH-1 downto 0); + s_axi_wstrb : in std_logic_vector((C_S_AXI_DATA_WIDTH/8)-1 downto 0); + s_axi_wvalid : in std_logic; + s_axi_bready : in std_logic; + s_axi_araddr : in std_logic_vector(C_S_AXI_ADDR_WIDTH-1 downto 0); + s_axi_arvalid : in std_logic; + s_axi_rready : in std_logic; + s_axi_arready : out std_logic; + s_axi_rdata : out std_logic_vector(C_S_AXI_DATA_WIDTH-1 downto 0); + s_axi_rresp : out std_logic_vector(1 downto 0); + s_axi_rvalid : out std_logic; + s_axi_wready : out std_logic; + s_axi_bresp : out std_logic_vector(1 downto 0); + s_axi_bvalid : out std_logic; + s_axi_awready : out std_logic; + + rd_addr : out integer range 0 to C_NUM_REG - 1; + rd_data : in std_logic_vector(C_S_AXI_DATA_WIDTH-1 downto 0); + rd_ack : out std_logic; + rd_stb : in std_logic; + + wr_addr : out integer range 0 to C_NUM_REG - 1; + wr_data : out std_logic_vector(C_S_AXI_DATA_WIDTH-1 downto 0); + wr_ack : in std_logic; + wr_stb : out std_logic + ); +end entity axi_ctrlif; + + +architecture Behavioral of axi_ctrlif is + type state_type is (IDLE, RESP, ACK); + signal rd_state : state_type; + signal wr_state : state_type; +begin + process (s_axi_aclk) + begin + if rising_edge(s_axi_aclk) then + if s_axi_aresetn = '0' then + rd_state <= IDLE; + else + case rd_state is + when IDLE => + if s_axi_arvalid = '1' then + rd_state <= RESP; + rd_addr <= to_integer(unsigned(s_axi_araddr((C_S_AXI_ADDR_WIDTH-1) downto 2))); + end if; + when RESP => + if rd_stb = '1' and s_axi_rready = '1' then + rd_state <= IDLE; + end if; + when others => null; + end case; + end if; + end if; + end process; + + s_axi_arready <= '1' when rd_state = IDLE else '0'; + s_axi_rvalid <= '1' when rd_state = RESP and rd_stb = '1' else '0'; + s_axi_rresp <= "00"; + rd_ack <= '1' when rd_state = RESP and s_axi_rready = '1' else '0'; + s_axi_rdata <= rd_data; + + process (s_axi_aclk) + begin + if rising_edge(s_axi_aclk) then + if s_axi_aresetn = '0' then + wr_state <= IDLE; + else + case wr_state is + when IDLE => + if s_axi_awvalid = '1' and s_axi_wvalid = '1' and wr_ack = '1' then + wr_state <= ACK; + end if; + when ACK => + wr_state <= RESP; + when RESP => + if s_axi_bready = '1' then + wr_state <= IDLE; + end if; + end case; + end if; + end if; + end process; + + wr_stb <= '1' when s_axi_awvalid = '1' and s_axi_wvalid = '1' and wr_state = IDLE else '0'; + wr_data <= s_axi_wdata; + wr_addr <= to_integer(unsigned(s_axi_awaddr((C_S_AXI_ADDR_WIDTH-1) downto 2))); + + s_axi_awready <= '1' when wr_state = ACK else '0'; + s_axi_wready <= '1' when wr_state = ACK else '0'; + + s_axi_bresp <= "00"; + s_axi_bvalid <= '1' when wr_state = RESP else '0'; +end; diff --git a/src/adi/hdl/library/common/axi_streaming_dma_rx_fifo.vhd b/src/adi/hdl/library/common/axi_streaming_dma_rx_fifo.vhd new file mode 100644 index 00000000..b0e26a89 --- /dev/null +++ b/src/adi/hdl/library/common/axi_streaming_dma_rx_fifo.vhd @@ -0,0 +1,117 @@ +-- *************************************************************************** +-- *************************************************************************** +-- Copyright 2014 - 2017 (c) Analog Devices, Inc. All rights reserved. +-- +-- In this HDL repository, there are many different and unique modules, consisting +-- of various HDL (Verilog or VHDL) components. The individual modules are +-- developed independently, and may be accompanied by separate and unique license +-- terms. +-- +-- The user should read each of these license terms, and understand the +-- freedoms and responsibilities that he or she has by using this source/core. +-- +-- This core 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. +-- +-- Redistribution and use of source or resulting binaries, with or without modification +-- of this file, are permitted under one of the following two license terms: +-- +-- 1. The GNU General Public License version 2 as published by the +-- Free Software Foundation, which can be found in the top level directory +-- of this repository (LICENSE_GPL2), and also online at: +-- +-- +-- OR +-- +-- 2. An ADI specific BSD license, which can be found in the top level directory +-- of this repository (LICENSE_ADIBSD), and also on-line at: +-- https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD +-- This will allow to generate bit files and not release the source code, +-- as long as it attaches to an ADI device. +-- +-- *************************************************************************** +-- *************************************************************************** + +library ieee; +use ieee.std_logic_1164.all; + +library work; +use work.dma_fifo; + +entity axi_streaming_dma_rx_fifo is + generic ( + RAM_ADDR_WIDTH : integer := 3; + FIFO_DWIDTH : integer := 32 + ); + port ( + clk : in std_logic; + resetn : in std_logic; + fifo_reset : in std_logic; + + -- Enable DMA interface + enable : in Boolean; + + period_len : in integer range 0 to 65535; + + -- Read port + m_axis_aclk : in std_logic; + m_axis_tready : in std_logic; + m_axis_tdata : out std_logic_vector(FIFO_DWIDTH-1 downto 0); + m_axis_tlast : out std_logic; + m_axis_tvalid : out std_logic; + m_axis_tkeep : out std_logic_vector(3 downto 0); + + -- Write port + in_stb : in std_logic; + in_ack : out std_logic; + in_data : in std_logic_vector(FIFO_DWIDTH-1 downto 0) + ); +end; + +architecture imp of axi_streaming_dma_rx_fifo is + signal out_stb : std_logic; + + signal period_count : integer range 0 to 65535; + signal last : std_logic; +begin + + m_axis_tvalid <= out_stb; + + fifo: entity dma_fifo + generic map ( + RAM_ADDR_WIDTH => RAM_ADDR_WIDTH, + FIFO_DWIDTH => FIFO_DWIDTH + ) + port map ( + clk => clk, + resetn => resetn, + fifo_reset => fifo_reset, + in_stb => in_stb, + in_ack => in_ack, + in_data => in_data, + out_stb => out_stb, + out_ack => m_axis_tready, + out_data => m_axis_tdata + ); + + m_axis_tkeep <= "1111"; + m_axis_tlast <= '1' when period_count = 0 else '0'; + + period_counter: process(m_axis_aclk) is + begin + if rising_edge(m_axis_aclk) then + if resetn = '0' then + period_count <= period_len; + else + if out_stb = '1' and m_axis_tready = '1' then + if period_count = 0 then + period_count <= period_len; + else + period_count <= period_count - 1; + end if; + end if; + end if; + end if; + end process; +end; diff --git a/src/adi/hdl/library/common/axi_streaming_dma_tx_fifo.vhd b/src/adi/hdl/library/common/axi_streaming_dma_tx_fifo.vhd new file mode 100644 index 00000000..20671b02 --- /dev/null +++ b/src/adi/hdl/library/common/axi_streaming_dma_tx_fifo.vhd @@ -0,0 +1,111 @@ +-- *************************************************************************** +-- *************************************************************************** +-- Copyright 2014 - 2017 (c) Analog Devices, Inc. All rights reserved. +-- +-- In this HDL repository, there are many different and unique modules, consisting +-- of various HDL (Verilog or VHDL) components. The individual modules are +-- developed independently, and may be accompanied by separate and unique license +-- terms. +-- +-- The user should read each of these license terms, and understand the +-- freedoms and responsibilities that he or she has by using this source/core. +-- +-- This core 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. +-- +-- Redistribution and use of source or resulting binaries, with or without modification +-- of this file, are permitted under one of the following two license terms: +-- +-- 1. The GNU General Public License version 2 as published by the +-- Free Software Foundation, which can be found in the top level directory +-- of this repository (LICENSE_GPL2), and also online at: +-- +-- +-- OR +-- +-- 2. An ADI specific BSD license, which can be found in the top level directory +-- of this repository (LICENSE_ADIBSD), and also on-line at: +-- https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD +-- This will allow to generate bit files and not release the source code, +-- as long as it attaches to an ADI device. +-- +-- *************************************************************************** +-- *************************************************************************** + +library ieee; +use ieee.std_logic_1164.all; + +library work; +use work.dma_fifo; + +entity axi_streaming_dma_tx_fifo is + generic ( + RAM_ADDR_WIDTH : integer := 3; + FIFO_DWIDTH : integer := 32 + ); + port ( + clk : in std_logic; + resetn : in std_logic; + fifo_reset : in std_logic; + + -- Enable DMA interface + enable : in Boolean; + + -- Write port + s_axis_aclk : in std_logic; + s_axis_tready : out std_logic; + s_axis_tdata : in std_logic_vector(FIFO_DWIDTH-1 downto 0); + s_axis_tlast : in std_logic; + s_axis_tvalid : in std_logic; + + -- Read port + out_stb : out std_logic; + out_ack : in std_logic; + out_data : out std_logic_vector(FIFO_DWIDTH-1 downto 0) + ); +end; + +architecture imp of axi_streaming_dma_tx_fifo is + signal in_ack : std_logic; + signal drain_dma : Boolean; +begin + + fifo: entity dma_fifo + generic map ( + RAM_ADDR_WIDTH => RAM_ADDR_WIDTH, + FIFO_DWIDTH => FIFO_DWIDTH + ) + port map ( + clk => clk, + resetn => resetn, + fifo_reset => fifo_reset, + in_stb => s_axis_tvalid, + in_ack => in_ack, + in_data => s_axis_tdata, + out_stb => out_stb, + out_ack => out_ack, + out_data => out_data + ); + + drain_process: process (s_axis_aclk) is + variable enable_d1 : Boolean; + begin + if rising_edge(s_axis_aclk) then + if resetn = '0' then + drain_dma <= False; + else + if s_axis_tlast = '1' then + drain_dma <= False; + elsif not enable_d1 and enable then + drain_dma <= False; + elsif enable_d1 and not enable then + drain_dma <= True; + end if; + enable_d1 := enable; + end if; + end if; + end process; + + s_axis_tready <= '1' when in_ack = '1' or drain_dma else '0'; +end; diff --git a/src/adi/hdl/library/common/dma_fifo.vhd b/src/adi/hdl/library/common/dma_fifo.vhd new file mode 100644 index 00000000..7143d9cc --- /dev/null +++ b/src/adi/hdl/library/common/dma_fifo.vhd @@ -0,0 +1,112 @@ +-- *************************************************************************** +-- *************************************************************************** +-- Copyright 2014 - 2017 (c) Analog Devices, Inc. All rights reserved. +-- +-- In this HDL repository, there are many different and unique modules, consisting +-- of various HDL (Verilog or VHDL) components. The individual modules are +-- developed independently, and may be accompanied by separate and unique license +-- terms. +-- +-- The user should read each of these license terms, and understand the +-- freedoms and responsibilities that he or she has by using this source/core. +-- +-- This core 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. +-- +-- Redistribution and use of source or resulting binaries, with or without modification +-- of this file, are permitted under one of the following two license terms: +-- +-- 1. The GNU General Public License version 2 as published by the +-- Free Software Foundation, which can be found in the top level directory +-- of this repository (LICENSE_GPL2), and also online at: +-- +-- +-- OR +-- +-- 2. An ADI specific BSD license, which can be found in the top level directory +-- of this repository (LICENSE_ADIBSD), and also on-line at: +-- https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD +-- This will allow to generate bit files and not release the source code, +-- as long as it attaches to an ADI device. +-- +-- *************************************************************************** +-- *************************************************************************** + +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +entity dma_fifo is + generic ( + RAM_ADDR_WIDTH : integer := 3; + FIFO_DWIDTH : integer := 32 + ); + port ( + clk : in std_logic; + resetn : in std_logic; + fifo_reset : in std_logic; + + -- Write port + in_stb : in std_logic; + in_ack : out std_logic; + in_data : in std_logic_vector(FIFO_DWIDTH-1 downto 0); + + -- Read port + out_stb : out std_logic; + out_ack : in std_logic; + out_data : out std_logic_vector(FIFO_DWIDTH-1 downto 0) + ); +end; + +architecture imp of dma_fifo is + + constant FIFO_MAX : natural := 2**RAM_ADDR_WIDTH -1; + type MEM is array (0 to FIFO_MAX) of std_logic_vector(FIFO_DWIDTH - 1 downto 0); + signal data_fifo : MEM; + signal wr_addr : natural range 0 to FIFO_MAX; + signal rd_addr : natural range 0 to FIFO_MAX; + signal not_full, not_empty : Boolean; + +begin + in_ack <= '1' when not_full else '0'; + + out_stb <= '1' when not_empty else '0'; + out_data <= data_fifo(rd_addr); + + fifo_data: process (clk) is + begin + if rising_edge(clk) then + if not_full then + data_fifo(wr_addr) <= in_data; + end if; + end if; + end process; + + fifo_ctrl: process (clk) is + variable free_cnt : integer range 0 to FIFO_MAX + 1; + begin + if rising_edge(clk) then + if (resetn = '0') or (fifo_reset = '1') then + wr_addr <= 0; + rd_addr <= 0; + free_cnt := FIFO_MAX + 1; + not_empty <= False; + not_full <= True; + else + if in_stb = '1' and not_full then + wr_addr <= (wr_addr + 1) mod (FIFO_MAX + 1); + free_cnt := free_cnt - 1; + end if; + + if out_ack = '1' and not_empty then + rd_addr <= (rd_addr + 1) mod (FIFO_MAX + 1); + free_cnt := free_cnt + 1; + end if; + + not_full <= not (free_cnt = 0); + not_empty <= not (free_cnt = FIFO_MAX + 1); + end if; + end if; + end process; +end; diff --git a/src/adi/hdl/library/common/pl330_dma_fifo.vhd b/src/adi/hdl/library/common/pl330_dma_fifo.vhd new file mode 100644 index 00000000..5a4f8ea9 --- /dev/null +++ b/src/adi/hdl/library/common/pl330_dma_fifo.vhd @@ -0,0 +1,175 @@ +-- *************************************************************************** +-- *************************************************************************** +-- Copyright 2014 - 2017 (c) Analog Devices, Inc. All rights reserved. +-- +-- In this HDL repository, there are many different and unique modules, consisting +-- of various HDL (Verilog or VHDL) components. The individual modules are +-- developed independently, and may be accompanied by separate and unique license +-- terms. +-- +-- The user should read each of these license terms, and understand the +-- freedoms and responsibilities that he or she has by using this source/core. +-- +-- This core 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. +-- +-- Redistribution and use of source or resulting binaries, with or without modification +-- of this file, are permitted under one of the following two license terms: +-- +-- 1. The GNU General Public License version 2 as published by the +-- Free Software Foundation, which can be found in the top level directory +-- of this repository (LICENSE_GPL2), and also online at: +-- +-- +-- OR +-- +-- 2. An ADI specific BSD license, which can be found in the top level directory +-- of this repository (LICENSE_ADIBSD), and also on-line at: +-- https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD +-- This will allow to generate bit files and not release the source code, +-- as long as it attaches to an ADI device. +-- +-- *************************************************************************** +-- *************************************************************************** + +library ieee; +use ieee.std_logic_1164.all; + +library work; +use work.dma_fifo; + +entity pl330_dma_fifo is + generic ( + RAM_ADDR_WIDTH : integer := 3; + FIFO_DWIDTH : integer := 32; + FIFO_DIRECTION : integer := 0 -- 0 = write FIFO, 1 = read FIFO + ); + port ( + clk : in std_logic; + resetn : in std_logic; + fifo_reset : in std_logic; + + -- Enable DMA interface + enable : in Boolean; + + -- Write port + in_stb : in std_logic; + in_ack : out std_logic; + in_data : in std_logic_vector(FIFO_DWIDTH-1 downto 0); + + -- Read port + out_stb : out std_logic; + out_ack : in std_logic; + out_data : out std_logic_vector(FIFO_DWIDTH-1 downto 0); + + -- PL330 DMA interface + dclk : in std_logic; + dresetn : in std_logic; + davalid : in std_logic; + daready : out std_logic; + datype : in std_logic_vector(1 downto 0); + drvalid : out std_logic; + drready : in std_logic; + drtype : out std_logic_vector(1 downto 0); + drlast : out std_logic; + + DBG : out std_logic_vector(7 downto 0) + ); +end; + +architecture imp of pl330_dma_fifo is + signal request_data : Boolean; + + type state_type is (IDLE, REQUEST, WAITING, FLUSH); + signal state : state_type; + signal i_in_ack : std_logic; + signal i_out_stb : std_logic; +begin + + in_ack <= i_in_ack; + out_stb <= i_out_stb; + + fifo: entity dma_fifo + generic map ( + RAM_ADDR_WIDTH => RAM_ADDR_WIDTH, + FIFO_DWIDTH => FIFO_DWIDTH + ) + port map ( + clk => clk, + resetn => resetn, + fifo_reset => fifo_reset, + in_stb => in_stb, + in_ack => i_in_ack, + in_data => in_data, + out_stb => i_out_stb, + out_ack => out_ack, + out_data => out_data + ); + + request_data <= i_in_ack = '1' when FIFO_DIRECTION = 0 else i_out_stb = '1'; + + drlast <= '0'; + daready <= '1'; + + drvalid <= '1' when (state = REQUEST) or (state = FLUSH) else '0'; + drtype <= "00" when state = REQUEST else "10"; + + DBG(0) <= davalid; + DBG(2 downto 1) <= datype; + DBG(3) <= '1' when request_data else '0'; + + process (state) + begin + case state is + when IDLE => DBG(5 downto 4) <= "00"; + when REQUEST => DBG(5 downto 4) <= "01"; + when WAITING => DBG(5 downto 4) <= "10"; + when FLUSH => DBG(5 downto 4) <= "11"; + end case; + end process; + + pl330_req_fsm: process (dclk) is + begin + if rising_edge(dclk) then + if dresetn = '0' then + state <= IDLE; + else + -- The controller may send a FLUSH request at any time and it won't + -- respond to any of our requests until we've ack the FLUSH request. + -- The FLUSH request is also supposed to reset our state machine, so + -- go back to idle after having acked the FLUSH. + if davalid = '1' and datype = "10" then + state <= FLUSH; + else + case state is + -- Nothing to do, wait for the fifo to run empty + when IDLE => + if request_data and enable then + state <= REQUEST; + end if; + -- Send out a request to the PL330 + when REQUEST => + if drready = '1' then + state <= WAITING; + end if; + -- Wait for a ACK from the PL330 that it did transfer the data + when WAITING => + if fifo_reset = '1' then + state <= IDLE; + elsif davalid = '1' then + if datype = "00" then + state <= IDLE; + end if; + end if; + -- Send out an ACK for the flush + when FLUSH => + if drready = '1' then + state <= IDLE; + end if; + end case; + end if; + end if; + end if; + end process; +end; diff --git a/src/adi/hdl/library/common/up_adc_channel.v b/src/adi/hdl/library/common/up_adc_channel.v new file mode 100644 index 00000000..f81d9bf1 --- /dev/null +++ b/src/adi/hdl/library/common/up_adc_channel.v @@ -0,0 +1,491 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright 2014 - 2017 (c) Analog Devices, Inc. All rights reserved. +// +// In this HDL repository, there are many different and unique modules, consisting +// of various HDL (Verilog or VHDL) components. The individual modules are +// developed independently, and may be accompanied by separate and unique license +// terms. +// +// The user should read each of these license terms, and understand the +// freedoms and responsibilities that he or she has by using this source/core. +// +// This core 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. +// +// Redistribution and use of source or resulting binaries, with or without modification +// of this file, are permitted under one of the following two license terms: +// +// 1. The GNU General Public License version 2 as published by the +// Free Software Foundation, which can be found in the top level directory +// of this repository (LICENSE_GPL2), and also online at: +// +// +// OR +// +// 2. An ADI specific BSD license, which can be found in the top level directory +// of this repository (LICENSE_ADIBSD), and also on-line at: +// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD +// This will allow to generate bit files and not release the source code, +// as long as it attaches to an ADI device. +// +// *************************************************************************** +// *************************************************************************** + +`timescale 1ns/100ps + +module up_adc_channel #( + + // parameters + + parameter COMMON_ID = 6'h01, + parameter CHANNEL_ID = 4'h0, + parameter USERPORTS_DISABLE = 0, + parameter DATAFORMAT_DISABLE = 0, + parameter DCFILTER_DISABLE = 0, + parameter IQCORRECTION_DISABLE = 0) ( + + // adc interface + + input adc_clk, + input adc_rst, + output adc_enable, + output adc_iqcor_enb, + output adc_dcfilt_enb, + output adc_dfmt_se, + output adc_dfmt_type, + output adc_dfmt_enable, + output [15:0] adc_dcfilt_offset, + output [15:0] adc_dcfilt_coeff, + output [15:0] adc_iqcor_coeff_1, + output [15:0] adc_iqcor_coeff_2, + output [ 3:0] adc_pnseq_sel, + output [ 3:0] adc_data_sel, + input adc_pn_err, + input adc_pn_oos, + input adc_or, + output up_adc_pn_err, + output up_adc_pn_oos, + output up_adc_or, + + // user controls + + output up_usr_datatype_be, + output up_usr_datatype_signed, + output [ 7:0] up_usr_datatype_shift, + output [ 7:0] up_usr_datatype_total_bits, + output [ 7:0] up_usr_datatype_bits, + output [15:0] up_usr_decimation_m, + output [15:0] up_usr_decimation_n, + input adc_usr_datatype_be, + input adc_usr_datatype_signed, + input [ 7:0] adc_usr_datatype_shift, + input [ 7:0] adc_usr_datatype_total_bits, + input [ 7:0] adc_usr_datatype_bits, + input [15:0] adc_usr_decimation_m, + input [15:0] adc_usr_decimation_n, + + // bus interface + + input up_rstn, + input up_clk, + input up_wreq, + input [13:0] up_waddr, + input [31:0] up_wdata, + output up_wack, + input up_rreq, + input [13:0] up_raddr, + output [31:0] up_rdata, + output up_rack); + + // internal registers + + reg up_wack_int = 'd0; + reg up_adc_lb_enb = 'd0; + reg up_adc_pn_sel = 'd0; + reg up_adc_iqcor_enb = 'd0; + reg up_adc_dcfilt_enb = 'd0; + reg up_adc_dfmt_se = 'd0; + reg up_adc_dfmt_type = 'd0; + reg up_adc_dfmt_enable = 'd0; + reg up_adc_pn_type = 'd0; + reg up_adc_enable = 'd0; + reg up_adc_pn_err_int = 'd0; + reg up_adc_pn_oos_int = 'd0; + reg up_adc_or_int = 'd0; + reg [15:0] up_adc_dcfilt_offset = 'd0; + reg [15:0] up_adc_dcfilt_coeff = 'd0; + reg [15:0] up_adc_iqcor_coeff_1 = 'd0; + reg [15:0] up_adc_iqcor_coeff_2 = 'd0; + reg [ 3:0] up_adc_pnseq_sel = 'd0; + reg [ 3:0] up_adc_data_sel = 'd0; + reg up_usr_datatype_be_int = 'd0; + reg up_usr_datatype_signed_int = 'd0; + reg [ 7:0] up_usr_datatype_shift_int = 'd0; + reg [ 7:0] up_usr_datatype_total_bits_int = 'd0; + reg [ 7:0] up_usr_datatype_bits_int = 'd0; + reg [15:0] up_usr_decimation_m_int = 'd0; + reg [15:0] up_usr_decimation_n_int = 'd0; + reg up_rack_int = 'd0; + reg [31:0] up_rdata_int = 'd0; + reg [15:0] up_adc_iqcor_coeff_tc_1 = 'd0; + reg [15:0] up_adc_iqcor_coeff_tc_2 = 'd0; + reg [ 3:0] up_adc_pnseq_sel_m = 'd0; + reg [ 3:0] up_adc_data_sel_m = 'd0; + + // internal signals + + wire up_wreq_s; + wire up_rreq_s; + wire up_adc_pn_err_s; + wire up_adc_pn_oos_s; + wire up_adc_or_s; + + // 2's complement function + + function [15:0] sm2tc; + input [15:0] din; + reg [15:0] dp; + reg [15:0] dn; + reg [15:0] dout; + begin + dp = {1'b0, din[14:0]}; + dn = ~dp + 1'b1; + dout = (din[15] == 1'b1) ? dn : dp; + sm2tc = dout; + end + endfunction + + // up control/status + + assign up_adc_pn_err = up_adc_pn_err_int; + assign up_adc_pn_oos = up_adc_pn_oos_int; + assign up_adc_or = up_adc_or_int; + assign up_usr_datatype_be = up_usr_datatype_be_int; + assign up_usr_datatype_signed = up_usr_datatype_signed_int; + assign up_usr_datatype_shift = up_usr_datatype_shift_int; + assign up_usr_datatype_total_bits = up_usr_datatype_total_bits_int; + assign up_usr_datatype_bits = up_usr_datatype_bits_int; + assign up_usr_decimation_m = up_usr_decimation_m_int; + assign up_usr_decimation_n = up_usr_decimation_n_int; + + // decode block select + + assign up_wreq_s = ((up_waddr[13:8] == COMMON_ID) && (up_waddr[7:4] == CHANNEL_ID)) ? up_wreq : 1'b0; + assign up_rreq_s = ((up_raddr[13:8] == COMMON_ID) && (up_raddr[7:4] == CHANNEL_ID)) ? up_rreq : 1'b0; + + // processor write interface + + assign up_wack = up_wack_int; + + always @(posedge up_clk) begin + if (up_rstn == 0) begin + up_wack_int <= 'd0; + up_adc_lb_enb <= 'd0; + up_adc_pn_sel <= 'd0; + end else begin + up_wack_int <= up_wreq_s; + if ((up_wreq_s == 1'b1) && (up_waddr[3:0] == 4'h0)) begin + up_adc_lb_enb <= up_wdata[11]; + up_adc_pn_sel <= up_wdata[10]; + end + end + end + + generate + if (IQCORRECTION_DISABLE == 1) begin + always @(posedge up_clk) begin + up_adc_iqcor_enb <= 'd0; + end + end else begin + always @(posedge up_clk) begin + if (up_rstn == 0) begin + up_adc_iqcor_enb <= 'd0; + end else begin + if ((up_wreq_s == 1'b1) && (up_waddr[3:0] == 4'h0)) begin + up_adc_iqcor_enb <= up_wdata[9]; + end + end + end + end + endgenerate + + generate + if (DCFILTER_DISABLE == 1) begin + always @(posedge up_clk) begin + up_adc_dcfilt_enb <= 'd0; + end + end else begin + always @(posedge up_clk) begin + if (up_rstn == 0) begin + up_adc_dcfilt_enb <= 'd0; + end else begin + if ((up_wreq_s == 1'b1) && (up_waddr[3:0] == 4'h0)) begin + up_adc_dcfilt_enb <= up_wdata[8]; + end + end + end + end + endgenerate + + generate + if (DATAFORMAT_DISABLE == 1) begin + always @(posedge up_clk) begin + up_adc_dfmt_se <= 'd0; + up_adc_dfmt_type <= 'd0; + up_adc_dfmt_enable <= 'd0; + end + end else begin + always @(posedge up_clk) begin + if (up_rstn == 0) begin + up_adc_dfmt_se <= 'd0; + up_adc_dfmt_type <= 'd0; + up_adc_dfmt_enable <= 'd0; + end else begin + if ((up_wreq_s == 1'b1) && (up_waddr[3:0] == 4'h0)) begin + up_adc_dfmt_se <= up_wdata[6]; + up_adc_dfmt_type <= up_wdata[5]; + up_adc_dfmt_enable <= up_wdata[4]; + end + end + end + end + endgenerate + + always @(posedge up_clk) begin + if (up_rstn == 0) begin + up_adc_pn_type <= 'd0; + up_adc_enable <= 'd0; + up_adc_pn_err_int <= 'd0; + up_adc_pn_oos_int <= 'd0; + up_adc_or_int <= 'd0; + end else begin + if ((up_wreq_s == 1'b1) && (up_waddr[3:0] == 4'h0)) begin + up_adc_pn_type <= up_wdata[1]; + up_adc_enable <= up_wdata[0]; + end + if (up_adc_pn_err_s == 1'b1) begin + up_adc_pn_err_int <= 1'b1; + end else if ((up_wreq_s == 1'b1) && (up_waddr[3:0] == 4'h1)) begin + up_adc_pn_err_int <= up_adc_pn_err_int & ~up_wdata[2]; + end + if (up_adc_pn_oos_s == 1'b1) begin + up_adc_pn_oos_int <= 1'b1; + end else if ((up_wreq_s == 1'b1) && (up_waddr[3:0] == 4'h1)) begin + up_adc_pn_oos_int <= up_adc_pn_oos_int & ~up_wdata[1]; + end + if (up_adc_or_s == 1'b1) begin + up_adc_or_int <= 1'b1; + end else if ((up_wreq_s == 1'b1) && (up_waddr[3:0] == 4'h1)) begin + up_adc_or_int <= up_adc_or_int & ~up_wdata[0]; + end + end + end + + generate + if (DCFILTER_DISABLE == 1) begin + always @(posedge up_clk) begin + up_adc_dcfilt_offset <= 'd0; + up_adc_dcfilt_coeff <= 'd0; + end + end else begin + always @(posedge up_clk) begin + if (up_rstn == 0) begin + up_adc_dcfilt_offset <= 'd0; + up_adc_dcfilt_coeff <= 'd0; + end else begin + if ((up_wreq_s == 1'b1) && (up_waddr[3:0] == 4'h4)) begin + up_adc_dcfilt_offset <= up_wdata[31:16]; + up_adc_dcfilt_coeff <= up_wdata[15:0]; + end + end + end + end + endgenerate + + generate + if (IQCORRECTION_DISABLE == 1) begin + always @(posedge up_clk) begin + up_adc_iqcor_coeff_1 <= 'd0; + up_adc_iqcor_coeff_2 <= 'd0; + end + end else begin + always @(posedge up_clk) begin + if (up_rstn == 0) begin + up_adc_iqcor_coeff_1 <= 'd0; + up_adc_iqcor_coeff_2 <= 'd0; + end else begin + if ((up_wreq_s == 1'b1) && (up_waddr[3:0] == 4'h5)) begin + up_adc_iqcor_coeff_1 <= up_wdata[31:16]; + up_adc_iqcor_coeff_2 <= up_wdata[15:0]; + end + end + end + end + endgenerate + + always @(posedge up_clk) begin + if (up_rstn == 0) begin + up_adc_pnseq_sel <= 'd0; + up_adc_data_sel <= 'd0; + end else begin + if ((up_wreq_s == 1'b1) && (up_waddr[3:0] == 4'h6)) begin + up_adc_pnseq_sel <= up_wdata[19:16]; + up_adc_data_sel <= up_wdata[3:0]; + end + end + end + + generate + if (USERPORTS_DISABLE == 1) begin + always @(posedge up_clk) begin + up_usr_datatype_be_int <= 'd0; + up_usr_datatype_signed_int <= 'd0; + up_usr_datatype_shift_int <= 'd0; + up_usr_datatype_total_bits_int <= 'd0; + up_usr_datatype_bits_int <= 'd0; + up_usr_decimation_m_int <= 'd0; + up_usr_decimation_n_int <= 'd0; + end + end else begin + always @(posedge up_clk) begin + if (up_rstn == 0) begin + up_usr_datatype_be_int <= 'd0; + up_usr_datatype_signed_int <= 'd0; + up_usr_datatype_shift_int <= 'd0; + up_usr_datatype_total_bits_int <= 'd0; + up_usr_datatype_bits_int <= 'd0; + up_usr_decimation_m_int <= 'd0; + up_usr_decimation_n_int <= 'd0; + end else begin + if ((up_wreq_s == 1'b1) && (up_waddr[3:0] == 4'h8)) begin + up_usr_datatype_be_int <= up_wdata[25]; + up_usr_datatype_signed_int <= up_wdata[24]; + up_usr_datatype_shift_int <= up_wdata[23:16]; + up_usr_datatype_total_bits_int <= up_wdata[15:8]; + up_usr_datatype_bits_int <= up_wdata[7:0]; + end + if ((up_wreq_s == 1'b1) && (up_waddr[3:0] == 4'h9)) begin + up_usr_decimation_m_int <= up_wdata[31:16]; + up_usr_decimation_n_int <= up_wdata[15:0]; + end + end + end + end + endgenerate + + // processor read interface + + assign up_rack = up_rack_int; + assign up_rdata = up_rdata_int; + + always @(posedge up_clk) begin + if (up_rstn == 0) begin + up_rack_int <= 'd0; + up_rdata_int <= 'd0; + end else begin + up_rack_int <= up_rreq_s; + if (up_rreq_s == 1'b1) begin + case (up_raddr[3:0]) + 4'h0: up_rdata_int <= { 20'd0, up_adc_lb_enb, up_adc_pn_sel, + up_adc_iqcor_enb, up_adc_dcfilt_enb, + 1'd0, up_adc_dfmt_se, up_adc_dfmt_type, up_adc_dfmt_enable, + 2'd0, up_adc_pn_type, up_adc_enable}; + 4'h1: up_rdata_int <= { 29'd0, up_adc_pn_err_int, up_adc_pn_oos_int, up_adc_or_int}; + 4'h4: up_rdata_int <= { up_adc_dcfilt_offset, up_adc_dcfilt_coeff}; + 4'h5: up_rdata_int <= { up_adc_iqcor_coeff_1, up_adc_iqcor_coeff_2}; + 4'h6: up_rdata_int <= { 12'd0, up_adc_pnseq_sel, 12'd0, up_adc_data_sel}; + 4'h8: up_rdata_int <= { 6'd0, adc_usr_datatype_be, adc_usr_datatype_signed, + adc_usr_datatype_shift, adc_usr_datatype_total_bits, + adc_usr_datatype_bits}; + 4'h9: up_rdata_int <= { adc_usr_decimation_m, adc_usr_decimation_n}; + default: up_rdata_int <= 0; + endcase + end else begin + up_rdata_int <= 32'd0; + end + end + end + + // change coefficients to 2's complements + + always @(posedge up_clk) begin + if (up_rstn == 0) begin + up_adc_iqcor_coeff_tc_1 <= 16'd0; + up_adc_iqcor_coeff_tc_2 <= 16'd0; + end else begin + up_adc_iqcor_coeff_tc_1 <= sm2tc(up_adc_iqcor_coeff_1); + up_adc_iqcor_coeff_tc_2 <= sm2tc(up_adc_iqcor_coeff_2); + end + end + + // data/pn sources + + always @(posedge up_clk) begin + if (up_rstn == 0) begin + up_adc_pnseq_sel_m <= 4'd0; + up_adc_data_sel_m <= 4'd0; + end else begin + case ({up_adc_pn_type, up_adc_pn_sel}) + 2'b10: up_adc_pnseq_sel_m <= 4'h1; + 2'b01: up_adc_pnseq_sel_m <= 4'h9; + default: up_adc_pnseq_sel_m <= up_adc_pnseq_sel; + endcase + if (up_adc_lb_enb == 1'b1) begin + up_adc_data_sel_m <= 4'h1; + end else begin + up_adc_data_sel_m <= up_adc_data_sel; + end + end + end + + // adc control & status + + up_xfer_cntrl #(.DATA_WIDTH(78)) i_xfer_cntrl ( + .up_rstn (up_rstn), + .up_clk (up_clk), + .up_data_cntrl ({ up_adc_iqcor_enb, + up_adc_dcfilt_enb, + up_adc_dfmt_se, + up_adc_dfmt_type, + up_adc_dfmt_enable, + up_adc_enable, + up_adc_dcfilt_offset, + up_adc_dcfilt_coeff, + up_adc_iqcor_coeff_tc_1, + up_adc_iqcor_coeff_tc_2, + up_adc_pnseq_sel_m, + up_adc_data_sel_m}), + .up_xfer_done (), + .d_rst (adc_rst), + .d_clk (adc_clk), + .d_data_cntrl ({ adc_iqcor_enb, + adc_dcfilt_enb, + adc_dfmt_se, + adc_dfmt_type, + adc_dfmt_enable, + adc_enable, + adc_dcfilt_offset, + adc_dcfilt_coeff, + adc_iqcor_coeff_1, + adc_iqcor_coeff_2, + adc_pnseq_sel, + adc_data_sel})); + + up_xfer_status #(.DATA_WIDTH(3)) i_xfer_status ( + .up_rstn (up_rstn), + .up_clk (up_clk), + .up_data_status ({up_adc_pn_err_s, + up_adc_pn_oos_s, + up_adc_or_s}), + .d_rst (adc_rst), + .d_clk (adc_clk), + .d_data_status ({ adc_pn_err, + adc_pn_oos, + adc_or})); + +endmodule + +// *************************************************************************** +// *************************************************************************** diff --git a/src/adi/hdl/library/common/up_adc_common.v b/src/adi/hdl/library/common/up_adc_common.v new file mode 100644 index 00000000..2d55448e --- /dev/null +++ b/src/adi/hdl/library/common/up_adc_common.v @@ -0,0 +1,454 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright 2014 - 2017 (c) Analog Devices, Inc. All rights reserved. +// +// In this HDL repository, there are many different and unique modules, consisting +// of various HDL (Verilog or VHDL) components. The individual modules are +// developed independently, and may be accompanied by separate and unique license +// terms. +// +// The user should read each of these license terms, and understand the +// freedoms and responsibilities that he or she has by using this source/core. +// +// This core 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. +// +// Redistribution and use of source or resulting binaries, with or without modification +// of this file, are permitted under one of the following two license terms: +// +// 1. The GNU General Public License version 2 as published by the +// Free Software Foundation, which can be found in the top level directory +// of this repository (LICENSE_GPL2), and also online at: +// +// +// OR +// +// 2. An ADI specific BSD license, which can be found in the top level directory +// of this repository (LICENSE_ADIBSD), and also on-line at: +// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD +// This will allow to generate bit files and not release the source code, +// as long as it attaches to an ADI device. +// +// *************************************************************************** +// *************************************************************************** + +`timescale 1ns/100ps + +module up_adc_common #( + + // parameters + + parameter ID = 0, + parameter CONFIG = 0, + parameter COMMON_ID = 6'h00, + parameter DRP_DISABLE = 0, + parameter USERPORTS_DISABLE = 0, + parameter GPIO_DISABLE = 0, + parameter START_CODE_DISABLE = 0) ( + + // clock reset + + output mmcm_rst, + + // adc interface + + input adc_clk, + output adc_rst, + output adc_r1_mode, + output adc_ddr_edgesel, + output adc_pin_mode, + input adc_status, + input adc_sync_status, + input adc_status_ovf, + input [31:0] adc_clk_ratio, + output [31:0] adc_start_code, + output adc_sref_sync, + output adc_sync, + input [31:0] up_pps_rcounter, + input up_pps_status, + output reg up_pps_irq_mask, + + // channel interface + + output up_adc_ce, + input up_status_pn_err, + input up_status_pn_oos, + input up_status_or, + + // drp interface + + output up_drp_sel, + output up_drp_wr, + output [11:0] up_drp_addr, + output [31:0] up_drp_wdata, + input [31:0] up_drp_rdata, + input up_drp_ready, + input up_drp_locked, + + // user channel control + + output [ 7:0] up_usr_chanmax_out, + input [ 7:0] up_usr_chanmax_in, + input [31:0] up_adc_gpio_in, + output [31:0] up_adc_gpio_out, + + // bus interface + + input up_rstn, + input up_clk, + input up_wreq, + input [13:0] up_waddr, + input [31:0] up_wdata, + output up_wack, + input up_rreq, + input [13:0] up_raddr, + output [31:0] up_rdata, + output up_rack); + + // parameters + + localparam VERSION = 32'h000a0062; + + // internal registers + + reg up_adc_clk_enb_int = 'd1; + reg up_core_preset = 'd1; + reg up_mmcm_preset = 'd1; + reg up_wack_int = 'd0; + reg [31:0] up_scratch = 'd0; + reg up_adc_clk_enb = 'd0; + reg up_mmcm_resetn = 'd0; + reg up_resetn = 'd0; + reg up_adc_sync = 'd0; + reg up_adc_sref_sync = 'd0; + reg up_adc_r1_mode = 'd0; + reg up_adc_ddr_edgesel = 'd0; + reg up_adc_pin_mode = 'd0; + reg up_status_ovf = 'd0; + reg [ 7:0] up_usr_chanmax_int = 'd0; + reg [31:0] up_adc_start_code = 'd0; + reg [31:0] up_adc_gpio_out_int = 'd0; + reg [31:0] up_timer = 'd0; + reg up_rack_int = 'd0; + reg [31:0] up_rdata_int = 'd0; + + // internal signals + + wire up_wreq_s; + wire up_rreq_s; + wire up_status_s; + wire up_sync_status_s; + wire up_status_ovf_s; + wire up_cntrl_xfer_done_s; + wire [31:0] up_adc_clk_count_s; + wire up_drp_status_s; + wire up_drp_rwn_s; + wire [31:0] up_drp_rdata_hold_s; + + // decode block select + + assign up_wreq_s = (up_waddr[13:8] == COMMON_ID) ? up_wreq : 1'b0; + assign up_rreq_s = (up_raddr[13:8] == COMMON_ID) ? up_rreq : 1'b0; + + // processor write interface + + assign up_wack = up_wack_int; + assign up_adc_ce = up_adc_clk_enb_int; + + always @(posedge up_clk) begin + if (up_rstn == 0) begin + up_adc_clk_enb_int <= 1'd1; + up_core_preset <= 1'd1; + up_mmcm_preset <= 1'd1; + up_wack_int <= 'd0; + up_scratch <= 'd0; + up_adc_clk_enb <= 'd0; + up_mmcm_resetn <= 'd0; + up_resetn <= 'd0; + up_adc_sync <= 'd0; + up_adc_sref_sync <= 'd0; + up_adc_r1_mode <= 'd0; + up_adc_ddr_edgesel <= 'd0; + up_adc_pin_mode <= 'd0; + up_pps_irq_mask <= 1'b1; + end else begin + up_adc_clk_enb_int <= ~up_adc_clk_enb; + up_core_preset <= ~up_resetn; + up_mmcm_preset <= ~up_mmcm_resetn; + up_wack_int <= up_wreq_s; + if ((up_wreq_s == 1'b1) && (up_waddr[7:0] == 8'h02)) begin + up_scratch <= up_wdata; + end + if ((up_wreq_s == 1'b1) && (up_waddr[7:0] == 8'h04)) begin + up_pps_irq_mask <= up_wdata[0]; + end + if ((up_wreq_s == 1'b1) && (up_waddr[7:0] == 8'h10)) begin + up_adc_clk_enb <= up_wdata[2]; + up_mmcm_resetn <= up_wdata[1]; + up_resetn <= up_wdata[0]; + end + if (up_adc_sync == 1'b1) begin + if (up_cntrl_xfer_done_s == 1'b1) begin + up_adc_sync <= 1'b0; + end + end else if ((up_wreq_s == 1'b1) && (up_waddr[7:0] == 8'h11)) begin + up_adc_sync <= up_wdata[3]; + end + if ((up_wreq_s == 1'b1) && (up_waddr[7:0] == 8'h11)) begin + up_adc_sref_sync <= up_wdata[4]; + up_adc_r1_mode <= up_wdata[2]; + up_adc_ddr_edgesel <= up_wdata[1]; + up_adc_pin_mode <= up_wdata[0]; + end + end + end + + generate + if (DRP_DISABLE == 1) begin + + assign up_drp_sel = 'd0; + assign up_drp_wr = 'd0; + assign up_drp_status_s = 'd0; + assign up_drp_rwn_s = 'd0; + assign up_drp_addr = 'd0; + assign up_drp_wdata = 'd0; + assign up_drp_rdata_hold_s = 'd0; + + end else begin + + reg up_drp_sel_int = 'd0; + reg up_drp_wr_int = 'd0; + reg up_drp_status_int = 'd0; + reg up_drp_rwn_int = 'd0; + reg [11:0] up_drp_addr_int = 'd0; + reg [31:0] up_drp_wdata_int = 'd0; + reg [31:0] up_drp_rdata_hold_int = 'd0; + + always @(posedge up_clk) begin + if (up_rstn == 0) begin + up_drp_sel_int <= 'd0; + up_drp_wr_int <= 'd0; + up_drp_status_int <= 'd0; + up_drp_rwn_int <= 'd0; + up_drp_addr_int <= 'd0; + up_drp_wdata_int <= 'd0; + up_drp_rdata_hold_int <= 'd0; + end else begin + if ((up_wreq_s == 1'b1) && (up_waddr[7:0] == 8'h1c)) begin + up_drp_sel_int <= 1'b1; + up_drp_wr_int <= ~up_wdata[28]; + end else begin + up_drp_sel_int <= 1'b0; + up_drp_wr_int <= 1'b0; + end + if ((up_wreq_s == 1'b1) && (up_waddr[7:0] == 8'h1c)) begin + up_drp_status_int <= 1'b1; + end else if (up_drp_ready == 1'b1) begin + up_drp_status_int <= 1'b0; + end + if ((up_wreq_s == 1'b1) && (up_waddr[7:0] == 8'h1c)) begin + up_drp_rwn_int <= up_wdata[28]; + up_drp_addr_int <= up_wdata[27:16]; + end + if ((up_wreq_s == 1'b1) && (up_waddr[7:0] == 8'h1e)) begin + up_drp_wdata_int <= up_wdata; + end + if (up_drp_ready == 1'b1) begin + up_drp_rdata_hold_int <= up_drp_rdata; + end + end + end + + assign up_drp_sel = up_drp_sel_int; + assign up_drp_wr = up_drp_wr_int; + assign up_drp_status_s = up_drp_status_int; + assign up_drp_rwn_s = up_drp_rwn_int; + assign up_drp_addr = up_drp_addr_int; + assign up_drp_wdata = up_drp_wdata_int; + assign up_drp_rdata_hold_s = up_drp_rdata_hold_int; + + end + endgenerate + + always @(posedge up_clk) begin + if (up_rstn == 0) begin + up_status_ovf <= 'd0; + end else begin + if (up_status_ovf_s == 1'b1) begin + up_status_ovf <= 1'b1; + end else if ((up_wreq_s == 1'b1) && (up_waddr[7:0] == 8'h22)) begin + up_status_ovf <= up_status_ovf & ~up_wdata[2]; + end + end + end + + assign up_usr_chanmax_out = up_usr_chanmax_int; + + generate + if (USERPORTS_DISABLE == 1) begin + always @(posedge up_clk) begin + up_usr_chanmax_int <= 'd0; + end + end else begin + always @(posedge up_clk) begin + if (up_rstn == 0) begin + up_usr_chanmax_int <= 'd0; + end else begin + if ((up_wreq_s == 1'b1) && (up_waddr[7:0] == 8'h28)) begin + up_usr_chanmax_int <= up_wdata[7:0]; + end + end + end + end + endgenerate + + assign up_adc_gpio_out = up_adc_gpio_out_int; + + generate + if (GPIO_DISABLE == 1) begin + always @(posedge up_clk) begin + up_adc_gpio_out_int <= 'd0; + end + end else begin + always @(posedge up_clk) begin + if (up_rstn == 0) begin + up_adc_gpio_out_int <= 'd0; + end else begin + if ((up_wreq_s == 1'b1) && (up_waddr[7:0] == 8'h2f)) begin + up_adc_gpio_out_int <= up_wdata; + end + end + end + end + endgenerate + + generate + if (START_CODE_DISABLE == 1) begin + always @(posedge up_clk) begin + up_adc_start_code <= 'd0; + end + end else begin + always @(posedge up_clk) begin + if (up_rstn == 0) begin + up_adc_start_code <= 'd0; + end else begin + if ((up_wreq_s == 1'b1) && (up_waddr[7:0] == 8'h29)) begin + up_adc_start_code <= up_wdata[31:0]; + end + end + end + end + endgenerate + + // timer with premature termination + + always @(posedge up_clk) begin + if (up_rstn == 0) begin + up_timer <= 32'd0; + end else begin + if ((up_wreq_s == 1'b1) && (up_waddr[7:0] == 8'h40)) begin + up_timer <= up_wdata; + end else if (up_timer > 0) begin + up_timer <= up_timer - 1'b1; + end + end + end + + // processor read interface + + assign up_rack = up_rack_int; + assign up_rdata = up_rdata_int; + + always @(posedge up_clk) begin + if (up_rstn == 0) begin + up_rack_int <= 'd0; + up_rdata_int <= 'd0; + end else begin + up_rack_int <= up_rreq_s; + if (up_rreq_s == 1'b1) begin + case (up_raddr[7:0]) + 8'h00: up_rdata_int <= VERSION; + 8'h01: up_rdata_int <= ID; + 8'h02: up_rdata_int <= up_scratch; + 8'h03: up_rdata_int <= CONFIG; + 8'h04: up_rdata_int <= {31'b0, up_pps_irq_mask}; + 8'h10: up_rdata_int <= {29'd0, up_adc_clk_enb, up_mmcm_resetn, up_resetn}; + 8'h11: up_rdata_int <= {27'd0, up_adc_sref_sync, up_adc_sync, up_adc_r1_mode, + up_adc_ddr_edgesel, up_adc_pin_mode}; + 8'h15: up_rdata_int <= up_adc_clk_count_s; + 8'h16: up_rdata_int <= adc_clk_ratio; + 8'h17: up_rdata_int <= {28'd0, up_status_pn_err, up_status_pn_oos, up_status_or, up_status_s}; + 8'h1a: up_rdata_int <= {31'd0, up_sync_status_s}; + 8'h1c: up_rdata_int <= {3'd0, up_drp_rwn_s, up_drp_addr, 16'b0}; + 8'h1d: up_rdata_int <= {14'd0, up_drp_locked, up_drp_status_s, 16'b0}; + 8'h1e: up_rdata_int <= up_drp_wdata; + 8'h1f: up_rdata_int <= up_drp_rdata_hold_s; + 8'h22: up_rdata_int <= {29'd0, up_status_ovf, 2'b0}; + 8'h23: up_rdata_int <= 32'd8; + 8'h28: up_rdata_int <= {24'd0, up_usr_chanmax_in}; + 8'h29: up_rdata_int <= up_adc_start_code; + 8'h2e: up_rdata_int <= up_adc_gpio_in; + 8'h2f: up_rdata_int <= up_adc_gpio_out_int; + 8'h30: up_rdata_int <= up_pps_rcounter; + 8'h31: up_rdata_int <= {31'b0, up_pps_status}; + 8'h40: up_rdata_int <= up_timer; + default: up_rdata_int <= 0; + endcase + end else begin + up_rdata_int <= 32'd0; + end + end + end + + // resets + + ad_rst i_mmcm_rst_reg (.rst_async(up_mmcm_preset), .clk(up_clk), .rstn(), .rst(mmcm_rst)); + ad_rst i_core_rst_reg (.rst_async(up_core_preset), .clk(adc_clk), .rstn(), .rst(adc_rst)); + + // adc control & status + + up_xfer_cntrl #(.DATA_WIDTH(37)) i_xfer_cntrl ( + .up_rstn (up_rstn), + .up_clk (up_clk), + .up_data_cntrl ({ up_adc_sref_sync, + up_adc_sync, + up_adc_start_code, + up_adc_r1_mode, + up_adc_ddr_edgesel, + up_adc_pin_mode}), + .up_xfer_done (up_cntrl_xfer_done_s), + .d_rst (adc_rst), + .d_clk (adc_clk), + .d_data_cntrl ({ adc_sref_sync, + adc_sync, + adc_start_code, + adc_r1_mode, + adc_ddr_edgesel, + adc_pin_mode})); + + up_xfer_status #(.DATA_WIDTH(3)) i_xfer_status ( + .up_rstn (up_rstn), + .up_clk (up_clk), + .up_data_status ({up_sync_status_s, + up_status_s, + up_status_ovf_s}), + .d_rst (adc_rst), + .d_clk (adc_clk), + .d_data_status ({ adc_sync_status, + adc_status, + adc_status_ovf})); + + // adc clock monitor + + up_clock_mon i_clock_mon ( + .up_rstn (up_rstn), + .up_clk (up_clk), + .up_d_count (up_adc_clk_count_s), + .d_rst (adc_rst), + .d_clk (adc_clk)); + +endmodule + +// *************************************************************************** +// *************************************************************************** diff --git a/src/adi/hdl/library/common/up_axi.v b/src/adi/hdl/library/common/up_axi.v new file mode 100644 index 00000000..8811a270 --- /dev/null +++ b/src/adi/hdl/library/common/up_axi.v @@ -0,0 +1,243 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright 2014 - 2017 (c) Analog Devices, Inc. All rights reserved. +// +// In this HDL repository, there are many different and unique modules, consisting +// of various HDL (Verilog or VHDL) components. The individual modules are +// developed independently, and may be accompanied by separate and unique license +// terms. +// +// The user should read each of these license terms, and understand the +// freedoms and responsibilities that he or she has by using this source/core. +// +// This core 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. +// +// Redistribution and use of source or resulting binaries, with or without modification +// of this file, are permitted under one of the following two license terms: +// +// 1. The GNU General Public License version 2 as published by the +// Free Software Foundation, which can be found in the top level directory +// of this repository (LICENSE_GPL2), and also online at: +// +// +// OR +// +// 2. An ADI specific BSD license, which can be found in the top level directory +// of this repository (LICENSE_ADIBSD), and also on-line at: +// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD +// This will allow to generate bit files and not release the source code, +// as long as it attaches to an ADI device. +// +// *************************************************************************** +// *************************************************************************** + +`timescale 1ns/100ps + +module up_axi #( + + parameter ADDRESS_WIDTH = 14, + parameter AXI_ADDRESS_WIDTH = 16) ( + + // reset and clocks + + input up_rstn, + input up_clk, + + // axi4 interface + + input up_axi_awvalid, + input [(AXI_ADDRESS_WIDTH-1):0] up_axi_awaddr, + output up_axi_awready, + input up_axi_wvalid, + input [31:0] up_axi_wdata, + input [ 3:0] up_axi_wstrb, + output up_axi_wready, + output up_axi_bvalid, + output [ 1:0] up_axi_bresp, + input up_axi_bready, + input up_axi_arvalid, + input [(AXI_ADDRESS_WIDTH-1):0] up_axi_araddr, + output up_axi_arready, + output up_axi_rvalid, + output [ 1:0] up_axi_rresp, + output [31:0] up_axi_rdata, + input up_axi_rready, + + // pcore interface + + output up_wreq, + output [(ADDRESS_WIDTH-1):0] up_waddr, + output [31:0] up_wdata, + input up_wack, + output up_rreq, + output [(ADDRESS_WIDTH-1):0] up_raddr, + input [31:0] up_rdata, + input up_rack); + + // internal registers + + reg up_axi_awready_int = 'd0; + reg up_axi_wready_int = 'd0; + reg up_axi_bvalid_int = 'd0; + reg up_wack_d = 'd0; + reg up_wsel = 'd0; + reg up_wreq_int = 'd0; + reg [(ADDRESS_WIDTH-1):0] up_waddr_int = 'd0; + reg [31:0] up_wdata_int = 'd0; + reg [ 4:0] up_wcount = 'd0; + reg up_axi_arready_int = 'd0; + reg up_axi_rvalid_int = 'd0; + reg [31:0] up_axi_rdata_int = 'd0; + reg up_rack_d = 'd0; + reg [31:0] up_rdata_d = 'd0; + reg up_rsel = 'd0; + reg up_rreq_int = 'd0; + reg [(ADDRESS_WIDTH-1):0] up_raddr_int = 'd0; + reg [ 4:0] up_rcount = 'd0; + + // internal signals + + wire up_wack_s; + wire up_rack_s; + wire [31:0] up_rdata_s; + + // write channel interface + + assign up_axi_awready = up_axi_awready_int; + assign up_axi_wready = up_axi_wready_int; + assign up_axi_bvalid = up_axi_bvalid_int; + assign up_axi_bresp = 2'd0; + + always @(posedge up_clk) begin + if (up_rstn == 1'b0) begin + up_axi_awready_int <= 'd0; + up_axi_wready_int <= 'd0; + up_axi_bvalid_int <= 'd0; + end else begin + if (up_axi_awready_int == 1'b1) begin + up_axi_awready_int <= 1'b0; + end else if (up_wack_s == 1'b1) begin + up_axi_awready_int <= 1'b1; + end + if (up_axi_wready_int == 1'b1) begin + up_axi_wready_int <= 1'b0; + end else if (up_wack_s == 1'b1) begin + up_axi_wready_int <= 1'b1; + end + if ((up_axi_bready == 1'b1) && (up_axi_bvalid_int == 1'b1)) begin + up_axi_bvalid_int <= 1'b0; + end else if (up_wack_d == 1'b1) begin + up_axi_bvalid_int <= 1'b1; + end + end + end + + assign up_wreq = up_wreq_int; + assign up_waddr = up_waddr_int; + assign up_wdata = up_wdata_int; + assign up_wack_s = (up_wcount == 5'h1f) ? 1'b1 : (up_wcount[4] & up_wack); + + always @(posedge up_clk) begin + if (up_rstn == 1'b0) begin + up_wack_d <= 'd0; + up_wsel <= 'd0; + up_wreq_int <= 'd0; + up_waddr_int <= 'd0; + up_wdata_int <= 'd0; + up_wcount <= 'd0; + end else begin + up_wack_d <= up_wack_s; + if (up_wsel == 1'b1) begin + if ((up_axi_bready == 1'b1) && (up_axi_bvalid_int == 1'b1)) begin + up_wsel <= 1'b0; + end + up_wreq_int <= 1'b0; + up_waddr_int <= up_waddr_int; + up_wdata_int <= up_wdata_int; + end else begin + up_wsel <= up_axi_awvalid & up_axi_wvalid; + up_wreq_int <= up_axi_awvalid & up_axi_wvalid; + up_waddr_int <= up_axi_awaddr[(ADDRESS_WIDTH+1):2]; + up_wdata_int <= up_axi_wdata; + end + if (up_wack_s == 1'b1) begin + up_wcount <= 5'h00; + end else if (up_wcount[4] == 1'b1) begin + up_wcount <= up_wcount + 1'b1; + end else if (up_wreq_int == 1'b1) begin + up_wcount <= 5'h10; + end + end + end + + // read channel interface + + assign up_axi_arready = up_axi_arready_int; + assign up_axi_rvalid = up_axi_rvalid_int; + assign up_axi_rdata = up_axi_rdata_int; + assign up_axi_rresp = 2'd0; + + always @(posedge up_clk) begin + if (up_rstn == 1'b0) begin + up_axi_arready_int <= 'd0; + up_axi_rvalid_int <= 'd0; + up_axi_rdata_int <= 'd0; + end else begin + if (up_axi_arready_int == 1'b1) begin + up_axi_arready_int <= 1'b0; + end else if (up_rack_s == 1'b1) begin + up_axi_arready_int <= 1'b1; + end + if ((up_axi_rready == 1'b1) && (up_axi_rvalid_int == 1'b1)) begin + up_axi_rvalid_int <= 1'b0; + up_axi_rdata_int <= 32'd0; + end else if (up_rack_d == 1'b1) begin + up_axi_rvalid_int <= 1'b1; + up_axi_rdata_int <= up_rdata_d; + end + end + end + + assign up_rreq = up_rreq_int; + assign up_raddr = up_raddr_int; + assign up_rack_s = (up_rcount == 5'h1f) ? 1'b1 : (up_rcount[4] & up_rack); + assign up_rdata_s = (up_rcount == 5'h1f) ? {2{16'hdead}} : up_rdata; + + always @(posedge up_clk) begin + if (up_rstn == 1'b0) begin + up_rack_d <= 'd0; + up_rdata_d <= 'd0; + up_rsel <= 'd0; + up_rreq_int <= 'd0; + up_raddr_int <= 'd0; + up_rcount <= 'd0; + end else begin + up_rack_d <= up_rack_s; + up_rdata_d <= up_rdata_s; + if (up_rsel == 1'b1) begin + if ((up_axi_rready == 1'b1) && (up_axi_rvalid_int == 1'b1)) begin + up_rsel <= 1'b0; + end + up_rreq_int <= 1'b0; + up_raddr_int <= up_raddr_int; + end else begin + up_rsel <= up_axi_arvalid; + up_rreq_int <= up_axi_arvalid; + up_raddr_int <= up_axi_araddr[(ADDRESS_WIDTH+1):2]; + end + if (up_rack_s == 1'b1) begin + up_rcount <= 5'h00; + end else if (up_rcount[4] == 1'b1) begin + up_rcount <= up_rcount + 1'b1; + end else if (up_rreq_int == 1'b1) begin + up_rcount <= 5'h10; + end + end + end + +endmodule + +// *************************************************************************** +// *************************************************************************** diff --git a/src/adi/hdl/library/common/up_clkgen.v b/src/adi/hdl/library/common/up_clkgen.v new file mode 100644 index 00000000..0837c526 --- /dev/null +++ b/src/adi/hdl/library/common/up_clkgen.v @@ -0,0 +1,184 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright 2014 - 2017 (c) Analog Devices, Inc. All rights reserved. +// +// In this HDL repository, there are many different and unique modules, consisting +// of various HDL (Verilog or VHDL) components. The individual modules are +// developed independently, and may be accompanied by separate and unique license +// terms. +// +// The user should read each of these license terms, and understand the +// freedoms and responsibilities that he or she has by using this source/core. +// +// This core 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. +// +// Redistribution and use of source or resulting binaries, with or without modification +// of this file, are permitted under one of the following two license terms: +// +// 1. The GNU General Public License version 2 as published by the +// Free Software Foundation, which can be found in the top level directory +// of this repository (LICENSE_GPL2), and also online at: +// +// +// OR +// +// 2. An ADI specific BSD license, which can be found in the top level directory +// of this repository (LICENSE_ADIBSD), and also on-line at: +// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD +// This will allow to generate bit files and not release the source code, +// as long as it attaches to an ADI device. +// +// *************************************************************************** +// *************************************************************************** + +`timescale 1ns/100ps + +module up_clkgen #( + + parameter ID = 0) ( + + // mmcm reset + + output mmcm_rst, + + // clock selection + + output clk_sel, + + // drp interface + + output reg up_drp_sel, + output reg up_drp_wr, + output reg [11:0] up_drp_addr, + output reg [15:0] up_drp_wdata, + input [15:0] up_drp_rdata, + input up_drp_ready, + input up_drp_locked, + + // bus interface + + input up_rstn, + input up_clk, + input up_wreq, + input [13:0] up_waddr, + input [31:0] up_wdata, + output reg up_wack, + input up_rreq, + input [13:0] up_raddr, + output reg [31:0] up_rdata, + output reg up_rack); + + localparam PCORE_VERSION = 32'h00040063; + + // internal registers + + reg up_mmcm_preset = 'd0; + reg [31:0] up_scratch = 'd0; + reg up_mmcm_resetn = 'd0; + reg up_resetn = 'd0; + reg up_drp_status = 'd0; + reg up_drp_rwn = 'd0; + reg [15:0] up_drp_rdata_hold = 'd0; + reg up_clk_sel = 'd0; + + // internal signals + + wire up_wreq_s; + wire up_rreq_s; + + // decode block select + + assign up_wreq_s = (up_waddr[13:8] == 6'h00) ? up_wreq : 1'b0; + assign up_rreq_s = (up_raddr[13:8] == 6'h00) ? up_rreq : 1'b0; + + assign clk_sel = ~up_clk_sel; + + // processor write interface + + always @(negedge up_rstn or posedge up_clk) begin + if (up_rstn == 0) begin + up_mmcm_preset <= 1'd1; + up_wack <= 'd0; + up_scratch <= 'd0; + up_mmcm_resetn <= 'd0; + up_resetn <= 'd0; + up_drp_sel <= 'd0; + up_drp_wr <= 'd0; + up_drp_status <= 'd0; + up_drp_rwn <= 'd0; + up_drp_addr <= 'd0; + up_drp_wdata <= 'd0; + up_drp_rdata_hold <= 'd0; + up_clk_sel <= 'd0; + end else begin + up_mmcm_preset <= ~up_mmcm_resetn; + up_wack <= up_wreq_s; + if ((up_wreq_s == 1'b1) && (up_waddr[7:0] == 8'h02)) begin + up_scratch <= up_wdata; + end + if ((up_wreq_s == 1'b1) && (up_waddr[7:0] == 8'h10)) begin + up_mmcm_resetn <= up_wdata[1]; + up_resetn <= up_wdata[0]; + end + if ((up_wreq_s == 1'b1) && (up_waddr[7:0] == 8'h11)) begin + up_clk_sel <= up_wdata[0]; + end + if ((up_wreq_s == 1'b1) && (up_waddr[7:0] == 8'h1c)) begin + up_drp_sel <= 1'b1; + up_drp_wr <= ~up_wdata[28]; + end else begin + up_drp_sel <= 1'b0; + up_drp_wr <= 1'b0; + end + if ((up_wreq_s == 1'b1) && (up_waddr[7:0] == 8'h1c)) begin + up_drp_status <= 1'b1; + end else if (up_drp_ready == 1'b1) begin + up_drp_status <= 1'b0; + end + if ((up_wreq_s == 1'b1) && (up_waddr[7:0] == 8'h1c)) begin + up_drp_rwn <= up_wdata[28]; + up_drp_addr <= up_wdata[27:16]; + up_drp_wdata <= up_wdata[15:0]; + end + if (up_drp_ready == 1'b1) begin + up_drp_rdata_hold <= up_drp_rdata; + end + end + end + + // processor read interface + + always @(negedge up_rstn or posedge up_clk) begin + if (up_rstn == 0) begin + up_rack <= 'd0; + up_rdata <= 'd0; + end else begin + up_rack <= up_rreq_s; + if (up_rreq_s == 1'b1) begin + case (up_raddr[7:0]) + 8'h00: up_rdata <= PCORE_VERSION; + 8'h01: up_rdata <= ID; + 8'h02: up_rdata <= up_scratch; + 8'h10: up_rdata <= {30'd0, up_mmcm_resetn, up_resetn}; + 8'h11: up_rdata <= {31'd0, up_clk_sel}; + 8'h17: up_rdata <= {31'd0, up_drp_locked}; + 8'h1c: up_rdata <= {3'd0, up_drp_rwn, up_drp_addr, up_drp_wdata}; + 8'h1d: up_rdata <= {14'd0, up_drp_locked, up_drp_status, up_drp_rdata_hold}; + default: up_rdata <= 0; + endcase + end else begin + up_rdata <= 32'd0; + end + end + end + + // resets + + ad_rst i_mmcm_rst_reg (.rst_async(up_mmcm_preset), .clk(up_clk), .rstn(), .rst(mmcm_rst)); + +endmodule + +// *************************************************************************** +// *************************************************************************** diff --git a/src/adi/hdl/library/common/up_clock_mon.v b/src/adi/hdl/library/common/up_clock_mon.v new file mode 100644 index 00000000..01a8258c --- /dev/null +++ b/src/adi/hdl/library/common/up_clock_mon.v @@ -0,0 +1,146 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright 2014 - 2017 (c) Analog Devices, Inc. All rights reserved. +// +// In this HDL repository, there are many different and unique modules, consisting +// of various HDL (Verilog or VHDL) components. The individual modules are +// developed independently, and may be accompanied by separate and unique license +// terms. +// +// The user should read each of these license terms, and understand the +// freedoms and responsibilities that he or she has by using this source/core. +// +// This core 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. +// +// Redistribution and use of source or resulting binaries, with or without modification +// of this file, are permitted under one of the following two license terms: +// +// 1. The GNU General Public License version 2 as published by the +// Free Software Foundation, which can be found in the top level directory +// of this repository (LICENSE_GPL2), and also online at: +// +// +// OR +// +// 2. An ADI specific BSD license, which can be found in the top level directory +// of this repository (LICENSE_ADIBSD), and also on-line at: +// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD +// This will allow to generate bit files and not release the source code, +// as long as it attaches to an ADI device. +// +// *************************************************************************** +// *************************************************************************** + +`timescale 1ns/100ps + +module up_clock_mon #( + parameter TOTAL_WIDTH = 32 +) ( + + // processor interface + + input up_rstn, + input up_clk, + output reg [TOTAL_WIDTH-1:0] up_d_count, + + // device interface + + input d_rst, + input d_clk); + + // internal registers + + reg [15:0] up_count = 'd1; + reg up_count_run = 'd0; + reg up_count_running_m1 = 'd0; + reg up_count_running_m2 = 'd0; + reg up_count_running_m3 = 'd0; + reg d_count_run_m1 = 'd0; + reg d_count_run_m2 = 'd0; + reg d_count_run_m3 = 'd0; + reg [TOTAL_WIDTH:0] d_count = 'd0; + + // internal signals + + wire up_count_capture_s; + wire d_count_reset_s; + + // processor reference + + // Capture on the falling edge of running + assign up_count_capture_s = up_count_running_m3 == 1'b1 && up_count_running_m2 == 1'b0; + + always @(posedge up_clk) begin + if (up_rstn == 0) begin + up_count_running_m1 <= 1'b0; + up_count_running_m2 <= 1'b0; + up_count_running_m3 <= 1'b0; + end else begin + up_count_running_m1 <= d_count_run_m3; + up_count_running_m2 <= up_count_running_m1; + up_count_running_m3 <= up_count_running_m2; + end + end + + always @(posedge up_clk) begin + if (up_rstn == 0) begin + up_d_count <= 'd0; + up_count_run <= 1'b0; + end else begin + if (up_count_running_m3 == 1'b0) begin + up_count_run <= 1'b1; + end else if (up_count == 'h00) begin + up_count_run <= 1'b0; + end + + if (up_count_capture_s == 1'b1) begin + up_d_count <= d_count[TOTAL_WIDTH-1:0]; + end else if (up_count == 'h00 && up_count_run != up_count_running_m3) begin + up_d_count <= 'h00; + end + end + end + + always @(posedge up_clk) begin + if (up_count_run == 1'b0 && up_count_running_m3 == 1'b0) begin + up_count <= 'h01; + end else begin + up_count <= up_count + 1'b1; + end + end + + // device free running + + // Reset on the rising edge of run + assign d_count_reset_s = d_count_run_m3 == 1'b0 && d_count_run_m2 == 1'b1; + + always @(posedge d_clk or posedge d_rst) begin + if (d_rst == 1'b1) begin + d_count_run_m1 <= 1'b0; + d_count_run_m2 <= 1'b0; + d_count_run_m3 <= 1'b0; + end else begin + d_count_run_m1 <= up_count_run; + d_count_run_m2 <= d_count_run_m1; + d_count_run_m3 <= d_count_run_m2; + end + end + + always @(posedge d_clk) begin + if (d_count_reset_s == 1'b1) begin + d_count <= 'h00; + end else if (d_count_run_m3 == 1'b1) begin + if (d_count[TOTAL_WIDTH] == 1'b0) begin + d_count <= d_count + 1'b1; + end else begin + d_count <= {TOTAL_WIDTH+1{1'b1}}; + end + end + end + +endmodule + +// *************************************************************************** +// *************************************************************************** diff --git a/src/adi/hdl/library/common/up_dac_channel.v b/src/adi/hdl/library/common/up_dac_channel.v new file mode 100644 index 00000000..8c20ad7a --- /dev/null +++ b/src/adi/hdl/library/common/up_dac_channel.v @@ -0,0 +1,430 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright 2014 - 2017 (c) Analog Devices, Inc. All rights reserved. +// +// In this HDL repository, there are many different and unique modules, consisting +// of various HDL (Verilog or VHDL) components. The individual modules are +// developed independently, and may be accompanied by separate and unique license +// terms. +// +// The user should read each of these license terms, and understand the +// freedoms and responsibilities that he or she has by using this source/core. +// +// This core 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. +// +// Redistribution and use of source or resulting binaries, with or without modification +// of this file, are permitted under one of the following two license terms: +// +// 1. The GNU General Public License version 2 as published by the +// Free Software Foundation, which can be found in the top level directory +// of this repository (LICENSE_GPL2), and also online at: +// +// +// OR +// +// 2. An ADI specific BSD license, which can be found in the top level directory +// of this repository (LICENSE_ADIBSD), and also on-line at: +// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD +// This will allow to generate bit files and not release the source code, +// as long as it attaches to an ADI device. +// +// *************************************************************************** +// *************************************************************************** + +`timescale 1ns/100ps + +module up_dac_channel #( + + // parameters + + parameter COMMON_ID = 6'h11, + parameter CHANNEL_ID = 4'h0, + parameter DDS_DISABLE = 0, + parameter USERPORTS_DISABLE = 0, + parameter IQCORRECTION_DISABLE = 0) ( + + // dac interface + + input dac_clk, + input dac_rst, + output [15:0] dac_dds_scale_1, + output [15:0] dac_dds_init_1, + output [15:0] dac_dds_incr_1, + output [15:0] dac_dds_scale_2, + output [15:0] dac_dds_init_2, + output [15:0] dac_dds_incr_2, + output [15:0] dac_pat_data_1, + output [15:0] dac_pat_data_2, + output [ 3:0] dac_data_sel, + output [ 1:0] dac_iq_mode, + output dac_iqcor_enb, + output [15:0] dac_iqcor_coeff_1, + output [15:0] dac_iqcor_coeff_2, + + // user controls + + output up_usr_datatype_be, + output up_usr_datatype_signed, + output [ 7:0] up_usr_datatype_shift, + output [ 7:0] up_usr_datatype_total_bits, + output [ 7:0] up_usr_datatype_bits, + output [15:0] up_usr_interpolation_m, + output [15:0] up_usr_interpolation_n, + input dac_usr_datatype_be, + input dac_usr_datatype_signed, + input [ 7:0] dac_usr_datatype_shift, + input [ 7:0] dac_usr_datatype_total_bits, + input [ 7:0] dac_usr_datatype_bits, + input [15:0] dac_usr_interpolation_m, + input [15:0] dac_usr_interpolation_n, + + // bus interface + + input up_rstn, + input up_clk, + input up_wreq, + input [13:0] up_waddr, + input [31:0] up_wdata, + output up_wack, + input up_rreq, + input [13:0] up_raddr, + output [31:0] up_rdata, + output up_rack); + + // internal registers + + reg up_wack_int = 'd0; + reg [15:0] up_dac_dds_scale_1 = 'd0; + reg [15:0] up_dac_dds_init_1 = 'd0; + reg [15:0] up_dac_dds_incr_1 = 'd0; + reg [15:0] up_dac_dds_scale_2 = 'd0; + reg [15:0] up_dac_dds_init_2 = 'd0; + reg [15:0] up_dac_dds_incr_2 = 'd0; + reg [15:0] up_dac_pat_data_2 = 'd0; + reg [15:0] up_dac_pat_data_1 = 'd0; + reg up_dac_iqcor_enb = 'd0; + reg up_dac_lb_enb = 'd0; + reg up_dac_pn_enb = 'd0; + reg [ 3:0] up_dac_data_sel = 'd0; + reg [15:0] up_dac_iqcor_coeff_1 = 'd0; + reg [15:0] up_dac_iqcor_coeff_2 = 'd0; + reg up_usr_datatype_be_int = 'd0; + reg up_usr_datatype_signed_int = 'd0; + reg [ 7:0] up_usr_datatype_shift_int = 'd0; + reg [ 7:0] up_usr_datatype_total_bits_int = 'd0; + reg [ 7:0] up_usr_datatype_bits_int = 'd0; + reg [15:0] up_usr_interpolation_m_int = 'd0; + reg [15:0] up_usr_interpolation_n_int = 'd0; + reg [ 1:0] up_dac_iq_mode = 'd0; + reg up_rack_int = 'd0; + reg [31:0] up_rdata_int = 'd0; + reg [15:0] up_dac_dds_scale_tc_1 = 'd0; + reg [15:0] up_dac_dds_scale_tc_2 = 'd0; + reg [15:0] up_dac_iqcor_coeff_tc_1 = 'd0; + reg [15:0] up_dac_iqcor_coeff_tc_2 = 'd0; + reg [ 3:0] up_dac_data_sel_m = 'd0; + + // internal signals + + wire up_wreq_s; + wire up_rreq_s; + + // 2's complement function + + function [15:0] sm2tc; + input [15:0] din; + reg [15:0] dp; + reg [15:0] dn; + reg [15:0] dout; + begin + dp = {1'b0, din[14:0]}; + dn = ~dp + 1'b1; + dout = (din[15] == 1'b1) ? dn : dp; + sm2tc = dout; + end + endfunction + + // decode block select + + assign up_wreq_s = ((up_waddr[13:8] == COMMON_ID) && (up_waddr[7:4] == CHANNEL_ID)) ? up_wreq : 1'b0; + assign up_rreq_s = ((up_raddr[13:8] == COMMON_ID) && (up_raddr[7:4] == CHANNEL_ID)) ? up_rreq : 1'b0; + + // processor write interface + + assign up_wack = up_wack_int; + + always @(negedge up_rstn or posedge up_clk) begin + if (up_rstn == 0) begin + up_wack_int <= 'd0; + end else begin + up_wack_int <= up_wreq_s; + end + end + + generate + if (DDS_DISABLE == 1) begin + always @(posedge up_clk) begin + up_dac_dds_scale_1 <= 'd0; + up_dac_dds_init_1 <= 'd0; + up_dac_dds_incr_1 <= 'd0; + up_dac_dds_scale_2 <= 'd0; + up_dac_dds_init_2 <= 'd0; + up_dac_dds_incr_2 <= 'd0; + end + end else begin + always @(negedge up_rstn or posedge up_clk) begin + if (up_rstn == 0) begin + up_dac_dds_scale_1 <= 'd0; + up_dac_dds_init_1 <= 'd0; + up_dac_dds_incr_1 <= 'd0; + up_dac_dds_scale_2 <= 'd0; + up_dac_dds_init_2 <= 'd0; + up_dac_dds_incr_2 <= 'd0; + end else begin + if ((up_wreq_s == 1'b1) && (up_waddr[3:0] == 4'h0)) begin + up_dac_dds_scale_1 <= up_wdata[15:0]; + end + if ((up_wreq_s == 1'b1) && (up_waddr[3:0] == 4'h1)) begin + up_dac_dds_init_1 <= up_wdata[31:16]; + up_dac_dds_incr_1 <= up_wdata[15:0]; + end + if ((up_wreq_s == 1'b1) && (up_waddr[3:0] == 4'h2)) begin + up_dac_dds_scale_2 <= up_wdata[15:0]; + end + if ((up_wreq_s == 1'b1) && (up_waddr[3:0] == 4'h3)) begin + up_dac_dds_init_2 <= up_wdata[31:16]; + up_dac_dds_incr_2 <= up_wdata[15:0]; + end + end + end + end + endgenerate + + always @(negedge up_rstn or posedge up_clk) begin + if (up_rstn == 0) begin + up_dac_pat_data_2 <= 'd0; + up_dac_pat_data_1 <= 'd0; + end else begin + if ((up_wreq_s == 1'b1) && (up_waddr[3:0] == 4'h4)) begin + up_dac_pat_data_2 <= up_wdata[31:16]; + up_dac_pat_data_1 <= up_wdata[15:0]; + end + end + end + + generate + if (IQCORRECTION_DISABLE == 1) begin + always @(posedge up_clk) begin + up_dac_iqcor_enb <= 'd0; + end + end else begin + always @(negedge up_rstn or posedge up_clk) begin + if (up_rstn == 0) begin + up_dac_iqcor_enb <= 'd0; + end else begin + if ((up_wreq_s == 1'b1) && (up_waddr[3:0] == 4'h5)) begin + up_dac_iqcor_enb <= up_wdata[2]; + end + end + end + end + endgenerate + + always @(negedge up_rstn or posedge up_clk) begin + if (up_rstn == 0) begin + up_dac_lb_enb <= 'd0; + up_dac_pn_enb <= 'd0; + up_dac_data_sel <= 'd0; + end else begin + if ((up_wreq_s == 1'b1) && (up_waddr[3:0] == 4'h5)) begin + up_dac_lb_enb <= up_wdata[1]; + up_dac_pn_enb <= up_wdata[0]; + end + if ((up_wreq_s == 1'b1) && (up_waddr[3:0] == 4'h6)) begin + up_dac_data_sel <= up_wdata[3:0]; + end + end + end + + generate + if (IQCORRECTION_DISABLE == 1) begin + always @(posedge up_clk) begin + up_dac_iqcor_coeff_1 <= 'd0; + up_dac_iqcor_coeff_2 <= 'd0; + end + end else begin + always @(negedge up_rstn or posedge up_clk) begin + if (up_rstn == 0) begin + up_dac_iqcor_coeff_1 <= 'd0; + up_dac_iqcor_coeff_2 <= 'd0; + end else begin + if ((up_wreq_s == 1'b1) && (up_waddr[3:0] == 4'h7)) begin + up_dac_iqcor_coeff_1 <= up_wdata[31:16]; + up_dac_iqcor_coeff_2 <= up_wdata[15:0]; + end + end + end + end + endgenerate + + assign up_usr_datatype_be = up_usr_datatype_be_int; + assign up_usr_datatype_signed = up_usr_datatype_signed_int; + assign up_usr_datatype_shift = up_usr_datatype_shift_int; + assign up_usr_datatype_total_bits = up_usr_datatype_total_bits_int; + assign up_usr_datatype_bits = up_usr_datatype_bits_int; + assign up_usr_interpolation_m = up_usr_interpolation_m_int; + assign up_usr_interpolation_n = up_usr_interpolation_n_int; + + generate + if (USERPORTS_DISABLE == 1) begin + always @(posedge up_clk) begin + up_usr_datatype_be_int <= 'd0; + up_usr_datatype_signed_int <= 'd0; + up_usr_datatype_shift_int <= 'd0; + up_usr_datatype_total_bits_int <= 'd0; + up_usr_datatype_bits_int <= 'd0; + up_usr_interpolation_m_int <= 'd0; + up_usr_interpolation_n_int <= 'd0; + end + end else begin + always @(negedge up_rstn or posedge up_clk) begin + if (up_rstn == 0) begin + up_usr_datatype_be_int <= 'd0; + up_usr_datatype_signed_int <= 'd0; + up_usr_datatype_shift_int <= 'd0; + up_usr_datatype_total_bits_int <= 'd0; + up_usr_datatype_bits_int <= 'd0; + up_usr_interpolation_m_int <= 'd0; + up_usr_interpolation_n_int <= 'd0; + end else begin + if ((up_wreq_s == 1'b1) && (up_waddr[3:0] == 4'h8)) begin + up_usr_datatype_be_int <= up_wdata[25]; + up_usr_datatype_signed_int <= up_wdata[24]; + up_usr_datatype_shift_int <= up_wdata[23:16]; + up_usr_datatype_total_bits_int <= up_wdata[15:8]; + up_usr_datatype_bits_int <= up_wdata[7:0]; + end + if ((up_wreq_s == 1'b1) && (up_waddr[3:0] == 4'h9)) begin + up_usr_interpolation_m_int <= up_wdata[31:16]; + up_usr_interpolation_n_int <= up_wdata[15:0]; + end + end + end + end + endgenerate + + always @(negedge up_rstn or posedge up_clk) begin + if (up_rstn == 0) begin + up_dac_iq_mode <= 'd0; + end else begin + if ((up_wreq_s == 1'b1) && (up_waddr[3:0] == 4'ha)) begin + up_dac_iq_mode <= up_wdata[1:0]; + end + end + end + + // processor read interface + + assign up_rack = up_rack_int; + assign up_rdata = up_rdata_int; + + always @(negedge up_rstn or posedge up_clk) begin + if (up_rstn == 0) begin + up_rack_int <= 'd0; + up_rdata_int <= 'd0; + end else begin + up_rack_int <= up_rreq_s; + if (up_rreq_s == 1'b1) begin + case (up_raddr[3:0]) + 4'h0: up_rdata_int <= { 16'd0, up_dac_dds_scale_1}; + 4'h1: up_rdata_int <= { up_dac_dds_init_1, up_dac_dds_incr_1}; + 4'h2: up_rdata_int <= { 16'd0, up_dac_dds_scale_2}; + 4'h3: up_rdata_int <= { up_dac_dds_init_2, up_dac_dds_incr_2}; + 4'h4: up_rdata_int <= { up_dac_pat_data_2, up_dac_pat_data_1}; + 4'h5: up_rdata_int <= { 29'd0, up_dac_iqcor_enb, up_dac_lb_enb, up_dac_pn_enb}; + 4'h6: up_rdata_int <= { 28'd0, up_dac_data_sel_m}; + 4'h7: up_rdata_int <= { up_dac_iqcor_coeff_1, up_dac_iqcor_coeff_2}; + 4'h8: up_rdata_int <= { 6'd0, dac_usr_datatype_be, dac_usr_datatype_signed, + dac_usr_datatype_shift, dac_usr_datatype_total_bits, + dac_usr_datatype_bits}; + 4'h9: up_rdata_int <= { dac_usr_interpolation_m, dac_usr_interpolation_n}; + 4'ha: up_rdata_int <= { 30'd0, up_dac_iq_mode}; + default: up_rdata_int <= 0; + endcase + end else begin + up_rdata_int <= 32'd0; + end + end + end + + // change coefficients to 2's complements + + always @(negedge up_rstn or posedge up_clk) begin + if (up_rstn == 0) begin + up_dac_dds_scale_tc_1 <= 16'd0; + up_dac_dds_scale_tc_2 <= 16'd0; + up_dac_iqcor_coeff_tc_1 <= 16'd0; + up_dac_iqcor_coeff_tc_2 <= 16'd0; + end else begin + up_dac_dds_scale_tc_1 <= sm2tc(up_dac_dds_scale_1); + up_dac_dds_scale_tc_2 <= sm2tc(up_dac_dds_scale_2); + up_dac_iqcor_coeff_tc_1 <= sm2tc(up_dac_iqcor_coeff_1); + up_dac_iqcor_coeff_tc_2 <= sm2tc(up_dac_iqcor_coeff_2); + end + end + + // backward compatibility + + always @(negedge up_rstn or posedge up_clk) begin + if (up_rstn == 0) begin + up_dac_data_sel_m <= 4'd0; + end else begin + case ({up_dac_lb_enb, up_dac_pn_enb}) + 2'b10: up_dac_data_sel_m <= 4'h8; + 2'b01: up_dac_data_sel_m <= 4'h9; + default: up_dac_data_sel_m <= up_dac_data_sel; + endcase + end + end + + // dac control & status + + up_xfer_cntrl #(.DATA_WIDTH(167)) i_xfer_cntrl ( + .up_rstn (up_rstn), + .up_clk (up_clk), + .up_data_cntrl ({ up_dac_iq_mode, + up_dac_iqcor_enb, + up_dac_iqcor_coeff_tc_1, + up_dac_iqcor_coeff_tc_2, + up_dac_dds_scale_tc_1, + up_dac_dds_init_1, + up_dac_dds_incr_1, + up_dac_dds_scale_tc_2, + up_dac_dds_init_2, + up_dac_dds_incr_2, + up_dac_pat_data_1, + up_dac_pat_data_2, + up_dac_data_sel_m}), + .up_xfer_done (), + .d_rst (dac_rst), + .d_clk (dac_clk), + .d_data_cntrl ({ dac_iq_mode, + dac_iqcor_enb, + dac_iqcor_coeff_1, + dac_iqcor_coeff_2, + dac_dds_scale_1, + dac_dds_init_1, + dac_dds_incr_1, + dac_dds_scale_2, + dac_dds_init_2, + dac_dds_incr_2, + dac_pat_data_1, + dac_pat_data_2, + dac_data_sel})); + +endmodule + +// *************************************************************************** +// *************************************************************************** diff --git a/src/adi/hdl/library/common/up_dac_common.v b/src/adi/hdl/library/common/up_dac_common.v new file mode 100644 index 00000000..55ff8726 --- /dev/null +++ b/src/adi/hdl/library/common/up_dac_common.v @@ -0,0 +1,479 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright 2014 - 2017 (c) Analog Devices, Inc. All rights reserved. +// +// In this HDL repository, there are many different and unique modules, consisting +// of various HDL (Verilog or VHDL) components. The individual modules are +// developed independently, and may be accompanied by separate and unique license +// terms. +// +// The user should read each of these license terms, and understand the +// freedoms and responsibilities that he or she has by using this source/core. +// +// This core 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. +// +// Redistribution and use of source or resulting binaries, with or without modification +// of this file, are permitted under one of the following two license terms: +// +// 1. The GNU General Public License version 2 as published by the +// Free Software Foundation, which can be found in the top level directory +// of this repository (LICENSE_GPL2), and also online at: +// +// +// OR +// +// 2. An ADI specific BSD license, which can be found in the top level directory +// of this repository (LICENSE_ADIBSD), and also on-line at: +// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD +// This will allow to generate bit files and not release the source code, +// as long as it attaches to an ADI device. +// +// *************************************************************************** +// *************************************************************************** + +`timescale 1ns/100ps + +module up_dac_common #( + + // parameters + + parameter ID = 0, + parameter CONFIG = 0, + parameter CLK_EDGE_SEL = 1'b0, + parameter COMMON_ID = 6'h10, + parameter DRP_DISABLE = 0, + parameter USERPORTS_DISABLE = 0, + parameter GPIO_DISABLE = 0) ( + + // mmcm reset + + output mmcm_rst, + + // dac interface + + input dac_clk, + output dac_rst, + output dac_sync, + output dac_frame, + output dac_clksel, + output dac_par_type, + output dac_par_enb, + output dac_r1_mode, + output dac_datafmt, + output [15:0] dac_datarate, + input dac_status, + input dac_status_unf, + input [31:0] dac_clk_ratio, + output up_dac_ce, + input [31:0] up_pps_rcounter, + input up_pps_status, + output reg up_pps_irq_mask, + + // drp interface + + output up_drp_sel, + output up_drp_wr, + output [11:0] up_drp_addr, + output [31:0] up_drp_wdata, + input [31:0] up_drp_rdata, + input up_drp_ready, + input up_drp_locked, + + // user channel control + + output [ 7:0] up_usr_chanmax, + input [ 7:0] dac_usr_chanmax, + input [31:0] up_dac_gpio_in, + output [31:0] up_dac_gpio_out, + + // bus interface + + input up_rstn, + input up_clk, + input up_wreq, + input [13:0] up_waddr, + input [31:0] up_wdata, + output up_wack, + input up_rreq, + input [13:0] up_raddr, + output [31:0] up_rdata, + output up_rack); + + // parameters + + localparam VERSION = 32'h00090062; + + // internal registers + + reg up_core_preset = 'd1; + reg up_mmcm_preset = 'd1; + reg up_wack_int = 'd0; + reg [31:0] up_scratch = 'd0; + reg up_dac_clk_enb_int = 'd0; + reg up_dac_clk_enb = 'd0; + reg up_mmcm_resetn = 'd0; + reg up_resetn = 'd0; + reg up_dac_sync = 'd0; + reg up_dac_par_type = 'd0; + reg up_dac_par_enb = 'd0; + reg up_dac_r1_mode = 'd0; + reg up_dac_datafmt = 'd0; + reg [15:0] up_dac_datarate = 'd0; + reg up_dac_frame = 'd0; + reg up_dac_clksel = CLK_EDGE_SEL; + reg up_status_unf = 'd0; + reg [ 7:0] up_usr_chanmax_int = 'd0; + reg [31:0] up_dac_gpio_out_int = 'd0; + reg [31:0] up_timer = 'd0; + reg up_rack_int = 'd0; + reg [31:0] up_rdata_int = 'd0; + reg dac_sync_d = 'd0; + reg dac_sync_2d = 'd0; + reg [ 5:0] dac_sync_count = 'd0; + reg dac_sync_int = 'd0; + reg dac_frame_d = 'd0; + reg dac_frame_2d = 'd0; + reg dac_frame_int = 'd0; + + // internal signals + + wire up_wreq_s; + wire up_rreq_s; + wire up_xfer_done_s; + wire up_status_s; + wire up_status_unf_s; + wire dac_sync_s; + wire dac_frame_s; + wire [31:0] up_dac_clk_count_s; + wire up_drp_status_s; + wire up_drp_rwn_s; + wire [31:0] up_drp_rdata_hold_s; + + // decode block select + + assign up_wreq_s = (up_waddr[13:8] == COMMON_ID) ? up_wreq : 1'b0; + assign up_rreq_s = (up_raddr[13:8] == COMMON_ID) ? up_rreq : 1'b0; + + assign up_dac_ce = up_dac_clk_enb_int; + + // processor write interface + + assign up_wack = up_wack_int; + + always @(negedge up_rstn or posedge up_clk) begin + if (up_rstn == 0) begin + up_core_preset <= 1'd1; + up_mmcm_preset <= 1'd1; + up_wack_int <= 'd0; + up_scratch <= 'd0; + up_dac_clk_enb_int <= 'd1; + up_dac_clk_enb <= 'd0; + up_mmcm_resetn <= 'd0; + up_resetn <= 'd0; + up_dac_sync <= 'd0; + up_dac_par_type <= 'd0; + up_dac_par_enb <= 'd0; + up_dac_r1_mode <= 'd0; + up_dac_datafmt <= 'd0; + up_dac_datarate <= 'd0; + up_dac_frame <= 'd0; + up_dac_clksel <= CLK_EDGE_SEL; + up_pps_irq_mask <= 1'b1; + end else begin + up_dac_clk_enb_int <= ~up_dac_clk_enb; + up_core_preset <= ~up_resetn; + up_mmcm_preset <= ~up_mmcm_resetn; + up_wack_int <= up_wreq_s; + if ((up_wreq_s == 1'b1) && (up_waddr[7:0] == 8'h02)) begin + up_scratch <= up_wdata; + end + if ((up_wreq_s == 1'b1) && (up_waddr[7:0] == 8'h04)) begin + up_pps_irq_mask <= up_wdata[0]; + end + if ((up_wreq_s == 1'b1) && (up_waddr[7:0] == 8'h10)) begin + up_dac_clk_enb <= up_wdata[2]; + up_mmcm_resetn <= up_wdata[1]; + up_resetn <= up_wdata[0]; + end + if (up_dac_sync == 1'b1) begin + if (up_xfer_done_s == 1'b1) begin + up_dac_sync <= 1'b0; + end + end else if ((up_wreq_s == 1'b1) && (up_waddr[7:0] == 8'h11)) begin + up_dac_sync <= up_wdata[0]; + end + if ((up_wreq_s == 1'b1) && (up_waddr[7:0] == 8'h12)) begin + up_dac_par_type <= up_wdata[7]; + up_dac_par_enb <= up_wdata[6]; + up_dac_r1_mode <= up_wdata[5]; + up_dac_datafmt <= up_wdata[4]; + end + if ((up_wreq_s == 1'b1) && (up_waddr[7:0] == 8'h13)) begin + up_dac_datarate <= up_wdata[15:0]; + end + if (up_dac_frame == 1'b1) begin + if (up_xfer_done_s == 1'b1) begin + up_dac_frame <= 1'b0; + end + end else if ((up_wreq_s == 1'b1) && (up_waddr[7:0] == 8'h14)) begin + up_dac_frame <= up_wdata[0]; + end + if ((up_wreq_s == 1'b1) && (up_waddr[7:0] == 8'h18)) begin + up_dac_clksel <= up_wdata[0]; + end + end + end + + generate + if (DRP_DISABLE == 1) begin + + assign up_drp_sel = 'd0; + assign up_drp_wr = 'd0; + assign up_drp_status_s = 'd0; + assign up_drp_rwn_s = 'd0; + assign up_drp_addr = 'd0; + assign up_drp_wdata = 'd0; + assign up_drp_rdata_hold_s = 'd0; + + end else begin + + reg up_drp_sel_int = 'd0; + reg up_drp_wr_int = 'd0; + reg up_drp_status_int = 'd0; + reg up_drp_rwn_int = 'd0; + reg [11:0] up_drp_addr_int = 'd0; + reg [31:0] up_drp_wdata_int = 'd0; + reg [31:0] up_drp_rdata_hold_int = 'd0; + + always @(negedge up_rstn or posedge up_clk) begin + if (up_rstn == 0) begin + up_drp_sel_int <= 'd0; + up_drp_wr_int <= 'd0; + up_drp_status_int <= 'd0; + up_drp_rwn_int <= 'd0; + up_drp_addr_int <= 'd0; + up_drp_wdata_int <= 'd0; + up_drp_rdata_hold_int <= 'd0; + end else begin + if ((up_wreq_s == 1'b1) && (up_waddr[7:0] == 8'h1c)) begin + up_drp_sel_int <= 1'b1; + up_drp_wr_int <= ~up_wdata[28]; + end else begin + up_drp_sel_int <= 1'b0; + up_drp_wr_int <= 1'b0; + end + if ((up_wreq_s == 1'b1) && (up_waddr[7:0] == 8'h1c)) begin + up_drp_status_int <= 1'b1; + end else if (up_drp_ready == 1'b1) begin + up_drp_status_int <= 1'b0; + end + if ((up_wreq_s == 1'b1) && (up_waddr[7:0] == 8'h1c)) begin + up_drp_rwn_int <= up_wdata[28]; + up_drp_addr_int <= up_wdata[27:16]; + end + if ((up_wreq_s == 1'b1) && (up_waddr[7:0] == 8'h1e)) begin + up_drp_wdata_int <= up_wdata; + end + if (up_drp_ready == 1'b1) begin + up_drp_rdata_hold_int <= up_drp_rdata; + end + end + end + + assign up_drp_sel = up_drp_sel_int; + assign up_drp_wr = up_drp_wr_int; + assign up_drp_status_s = up_drp_status_int; + assign up_drp_rwn_s = up_drp_rwn_int; + assign up_drp_addr = up_drp_addr_int; + assign up_drp_wdata = up_drp_wdata_int; + assign up_drp_rdata_hold_s = up_drp_rdata_hold_int; + + end + endgenerate + + always @(negedge up_rstn or posedge up_clk) begin + if (up_rstn == 0) begin + up_status_unf <= 'd0; + end else begin + if (up_status_unf_s == 1'b1) begin + up_status_unf <= 1'b1; + end else if ((up_wreq_s == 1'b1) && (up_waddr[7:0] == 8'h22)) begin + up_status_unf <= up_status_unf & ~up_wdata[0]; + end + end + end + + assign up_usr_chanmax = up_usr_chanmax_int; + + generate + if (USERPORTS_DISABLE == 1) begin + always @(posedge up_clk) begin + up_usr_chanmax_int <= 'd0; + end + end else begin + always @(negedge up_rstn or posedge up_clk) begin + if (up_rstn == 0) begin + up_usr_chanmax_int <= 'd0; + end else begin + if ((up_wreq_s == 1'b1) && (up_waddr[7:0] == 8'h28)) begin + up_usr_chanmax_int <= up_wdata[7:0]; + end + end + end + end + endgenerate + + assign up_dac_gpio_out = up_dac_gpio_out_int; + + generate + if (GPIO_DISABLE == 1) begin + always @(posedge up_clk) begin + up_dac_gpio_out_int <= 'd0; + end + end else begin + always @(negedge up_rstn or posedge up_clk) begin + if (up_rstn == 0) begin + up_dac_gpio_out_int <= 'd0; + end else begin + if ((up_wreq_s == 1'b1) && (up_waddr[7:0] == 8'h2f)) begin + up_dac_gpio_out_int <= up_wdata; + end + end + end + end + endgenerate + + // timer with premature termination + + always @(negedge up_rstn or posedge up_clk) begin + if (up_rstn == 0) begin + up_timer <= 32'd0; + end else begin + if ((up_wreq_s == 1'b1) && (up_waddr[7:0] == 8'h40)) begin + up_timer <= up_wdata; + end else if (up_timer > 0) begin + up_timer <= up_timer - 1'b1; + end + end + end + + // processor read interface + + assign up_rack = up_rack_int; + assign up_rdata = up_rdata_int; + + always @(negedge up_rstn or posedge up_clk) begin + if (up_rstn == 0) begin + up_rack_int <= 'd0; + up_rdata_int <= 'd0; + end else begin + up_rack_int <= up_rreq_s; + if (up_rreq_s == 1'b1) begin + case (up_raddr[7:0]) + 8'h00: up_rdata_int <= VERSION; + 8'h01: up_rdata_int <= ID; + 8'h02: up_rdata_int <= up_scratch; + 8'h03: up_rdata_int <= CONFIG; + 8'h10: up_rdata_int <= {29'd0, up_dac_clk_enb, up_mmcm_resetn, up_resetn}; + 8'h11: up_rdata_int <= {31'd0, up_dac_sync}; + 8'h12: up_rdata_int <= {24'd0, up_dac_par_type, up_dac_par_enb, up_dac_r1_mode, + up_dac_datafmt, 4'd0}; + 8'h13: up_rdata_int <= {16'd0, up_dac_datarate}; + 8'h14: up_rdata_int <= {31'd0, up_dac_frame}; + 8'h15: up_rdata_int <= up_dac_clk_count_s; + 8'h16: up_rdata_int <= dac_clk_ratio; + 8'h17: up_rdata_int <= {31'd0, up_status_s}; + 8'h18: up_rdata_int <= {31'd0, up_dac_clksel}; + 8'h1c: up_rdata_int <= {3'd0, up_drp_rwn_s, up_drp_addr, 16'b0}; + 8'h1d: up_rdata_int <= {14'd0, up_drp_locked, up_drp_status_s, 16'b0}; + 8'h1e: up_rdata_int <= up_drp_wdata; + 8'h1f: up_rdata_int <= up_drp_rdata_hold_s; + 8'h22: up_rdata_int <= {31'd0, up_status_unf}; + 8'h28: up_rdata_int <= {24'd0, dac_usr_chanmax}; + 8'h2e: up_rdata_int <= up_dac_gpio_in; + 8'h2f: up_rdata_int <= up_dac_gpio_out_int; + 8'h30: up_rdata_int <= up_pps_rcounter; + 8'h31: up_rdata_int <= up_pps_status; + 8'h40: up_rdata_int <= up_timer; + default: up_rdata_int <= 0; + endcase + end else begin + up_rdata_int <= 32'd0; + end + end + end + + // resets + + ad_rst i_mmcm_rst_reg (.rst_async(up_mmcm_preset), .clk(up_clk), .rstn(), .rst(mmcm_rst)); + ad_rst i_core_rst_reg (.rst_async(up_core_preset), .clk(dac_clk), .rstn(), .rst(dac_rst)); + + // dac control & status + + up_xfer_cntrl #(.DATA_WIDTH(23)) i_xfer_cntrl ( + .up_rstn (up_rstn), + .up_clk (up_clk), + .up_data_cntrl ({ up_dac_sync, + up_dac_clksel, + up_dac_frame, + up_dac_par_type, + up_dac_par_enb, + up_dac_r1_mode, + up_dac_datafmt, + up_dac_datarate}), + .up_xfer_done (up_xfer_done_s), + .d_rst (dac_rst), + .d_clk (dac_clk), + .d_data_cntrl ({ dac_sync_s, + dac_clksel, + dac_frame_s, + dac_par_type, + dac_par_enb, + dac_r1_mode, + dac_datafmt, + dac_datarate})); + + up_xfer_status #(.DATA_WIDTH(2)) i_xfer_status ( + .up_rstn (up_rstn), + .up_clk (up_clk), + .up_data_status ({up_status_s, + up_status_unf_s}), + .d_rst (dac_rst), + .d_clk (dac_clk), + .d_data_status ({ dac_status, + dac_status_unf})); + + // generate frame and enable + + assign dac_sync = dac_sync_int; + assign dac_frame = dac_frame_int; + + always @(posedge dac_clk) begin + dac_sync_d <= dac_sync_s; + dac_sync_2d <= dac_sync_d; + if (dac_sync_count[5] == 1'b1) begin + dac_sync_count <= dac_sync_count + 1'b1; + end else if ((dac_sync_d == 1'b1) && (dac_sync_2d == 1'b0)) begin + dac_sync_count <= 6'h20; + end + dac_sync_int <= dac_sync_count[5]; + dac_frame_d <= dac_frame_s; + dac_frame_2d <= dac_frame_d; + dac_frame_int <= dac_frame_d & ~dac_frame_2d; + end + + // dac clock monitor + + up_clock_mon i_clock_mon ( + .up_rstn (up_rstn), + .up_clk (up_clk), + .up_d_count (up_dac_clk_count_s), + .d_rst (dac_rst), + .d_clk (dac_clk)); + +endmodule + +// *************************************************************************** +// *************************************************************************** diff --git a/src/adi/hdl/library/common/up_delay_cntrl.v b/src/adi/hdl/library/common/up_delay_cntrl.v new file mode 100644 index 00000000..ae3210c1 --- /dev/null +++ b/src/adi/hdl/library/common/up_delay_cntrl.v @@ -0,0 +1,218 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright 2014 - 2017 (c) Analog Devices, Inc. All rights reserved. +// +// In this HDL repository, there are many different and unique modules, consisting +// of various HDL (Verilog or VHDL) components. The individual modules are +// developed independently, and may be accompanied by separate and unique license +// terms. +// +// The user should read each of these license terms, and understand the +// freedoms and responsibilities that he or she has by using this source/core. +// +// This core 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. +// +// Redistribution and use of source or resulting binaries, with or without modification +// of this file, are permitted under one of the following two license terms: +// +// 1. The GNU General Public License version 2 as published by the +// Free Software Foundation, which can be found in the top level directory +// of this repository (LICENSE_GPL2), and also online at: +// +// +// OR +// +// 2. An ADI specific BSD license, which can be found in the top level directory +// of this repository (LICENSE_ADIBSD), and also on-line at: +// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD +// This will allow to generate bit files and not release the source code, +// as long as it attaches to an ADI device. +// +// *************************************************************************** +// *************************************************************************** + +`timescale 1ns/100ps + +module up_delay_cntrl #( + + // parameters + + parameter DISABLE = 0, + parameter INIT_DELAY = 0, + parameter DATA_WIDTH = 8, + parameter BASE_ADDRESS = 6'h02) ( + + // delay interface + + input delay_clk, + output delay_rst, + input delay_locked, + + // io interface + + output [(DATA_WIDTH-1):0] up_dld, + output [((DATA_WIDTH*5)-1):0] up_dwdata, + input [((DATA_WIDTH*5)-1):0] up_drdata, + + // processor interface + + input up_rstn, + input up_clk, + input up_wreq, + input [13:0] up_waddr, + input [31:0] up_wdata, + output up_wack, + input up_rreq, + input [13:0] up_raddr, + output [31:0] up_rdata, + output up_rack); + + generate + if (DISABLE == 1) begin + assign up_wack = 1'd0; + assign up_rack = 1'd0; + assign up_rdata = 32'd0; + + assign up_dld = 'd0; + assign up_dwdata = 'd0; + + assign delay_rst = 1'd0; + + end else begin + // internal registers + + reg up_preset = 'd0; + reg up_wack_int = 'd0; + reg up_rack_int = 'd0; + reg [31:0] up_rdata_int = 'd0; + reg up_dlocked_m1 = 'd0; + reg up_dlocked_m2 = 'd0; + reg up_dlocked_m3 = 'd0; + reg up_dlocked = 'd0; + reg [(DATA_WIDTH-1):0] up_dld_int = 'd0; + reg [((DATA_WIDTH*5)-1):0] up_dwdata_int = 'd0; + + // internal signals + + wire up_wreq_s; + wire up_rreq_s; + wire [ 4:0] up_rdata_s; + wire [(DATA_WIDTH-1):0] up_drdata4_s; + wire [(DATA_WIDTH-1):0] up_drdata3_s; + wire [(DATA_WIDTH-1):0] up_drdata2_s; + wire [(DATA_WIDTH-1):0] up_drdata1_s; + wire [(DATA_WIDTH-1):0] up_drdata0_s; + wire [(DATA_WIDTH-1):0] up_dld_s; + wire [((DATA_WIDTH*5)-1):0] up_dwdata_s; + wire [(DATA_WIDTH-1):0] up_dinit_s; + wire [((DATA_WIDTH*5)-1):0] up_dinitdata_s; + wire delay_rst_s; + + // variables + + genvar n; + + // decode block select + + assign up_wreq_s = (up_waddr[13:8] == BASE_ADDRESS) ? up_wreq : 1'b0; + assign up_rreq_s = (up_raddr[13:8] == BASE_ADDRESS) ? up_rreq : 1'b0; + assign up_rdata_s[4] = | up_drdata4_s; + assign up_rdata_s[3] = | up_drdata3_s; + assign up_rdata_s[2] = | up_drdata2_s; + assign up_rdata_s[1] = | up_drdata1_s; + assign up_rdata_s[0] = | up_drdata0_s; + + for (n = 0; n < DATA_WIDTH; n = n + 1) begin: g_drd + assign up_drdata4_s[n] = (up_raddr[7:0] == n) ? up_drdata[((n*5)+4)] : 1'd0; + assign up_drdata3_s[n] = (up_raddr[7:0] == n) ? up_drdata[((n*5)+3)] : 1'd0; + assign up_drdata2_s[n] = (up_raddr[7:0] == n) ? up_drdata[((n*5)+2)] : 1'd0; + assign up_drdata1_s[n] = (up_raddr[7:0] == n) ? up_drdata[((n*5)+1)] : 1'd0; + assign up_drdata0_s[n] = (up_raddr[7:0] == n) ? up_drdata[((n*5)+0)] : 1'd0; + end + + // processor interface + + assign up_wack = up_wack_int; + assign up_rack = up_rack_int; + assign up_rdata = up_rdata_int; + + always @(posedge up_clk) begin + if (up_rstn == 0) begin + up_preset <= 1'd1; + up_wack_int <= 'd0; + up_rack_int <= 'd0; + up_rdata_int <= 'd0; + up_dlocked_m1 <= 'd0; + up_dlocked_m2 <= 'd0; + up_dlocked_m3 <= 'd0; + up_dlocked <= 'd0; + end else begin + up_preset <= 1'd0; + up_wack_int <= up_wreq_s; + up_rack_int <= up_rreq_s; + if (up_rreq_s == 1'b1) begin + if (up_dlocked == 1'b0) begin + up_rdata_int <= 32'hffffffff; + end else begin + up_rdata_int <= {27'd0, up_rdata_s}; + end + end else begin + up_rdata_int <= 32'd0; + end + up_dlocked_m1 <= delay_locked; + up_dlocked_m2 <= up_dlocked_m1; + up_dlocked_m3 <= up_dlocked_m2; + up_dlocked <= up_dlocked_m3; + end + end + + // init delay values (after delay locked) + + for (n = 0; n < DATA_WIDTH; n = n + 1) begin: g_dinit + assign up_dinit_s[n] = up_dlocked_m2 & ~up_dlocked_m3; + assign up_dinitdata_s[((n*5)+4):(n*5)] = INIT_DELAY; + end + + // write does not hold- read back what goes into effect. + + for (n = 0; n < DATA_WIDTH; n = n + 1) begin: g_dwr + assign up_dld_s[n] = (up_waddr[7:0] == n) ? up_wreq_s : 1'b0; + assign up_dwdata_s[((n*5)+4):(n*5)] = (up_waddr[7:0] == n) ? + up_wdata[4:0] : up_dwdata_int[((n*5)+4):(n*5)]; + end + + assign up_dld = up_dld_int; + assign up_dwdata = up_dwdata_int; + + always @(posedge up_clk) begin + if (up_rstn == 0) begin + up_dld_int <= 'd0; + up_dwdata_int <= 'd0; + end else begin + up_dld_int <= up_dld_s | up_dinit_s; + if ((up_dlocked_m2 == 1'b1) && (up_dlocked_m3 == 1'b0)) begin + up_dwdata_int <= up_dinitdata_s; + end else if (up_wreq_s == 1'b1) begin + up_dwdata_int <= up_dwdata_s; + end + end + end + + // resets + + assign delay_rst = delay_rst_s; + + ad_rst i_delay_rst_reg ( + .rst_async (up_preset), + .clk (delay_clk), + .rstn (), + .rst (delay_rst_s)); + end + endgenerate + +endmodule + +// *************************************************************************** +// *************************************************************************** diff --git a/src/adi/hdl/library/common/up_hdmi_rx.v b/src/adi/hdl/library/common/up_hdmi_rx.v new file mode 100644 index 00000000..68955588 --- /dev/null +++ b/src/adi/hdl/library/common/up_hdmi_rx.v @@ -0,0 +1,286 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright 2014 - 2017 (c) Analog Devices, Inc. All rights reserved. +// +// In this HDL repository, there are many different and unique modules, consisting +// of various HDL (Verilog or VHDL) components. The individual modules are +// developed independently, and may be accompanied by separate and unique license +// terms. +// +// The user should read each of these license terms, and understand the +// freedoms and responsibilities that he or she has by using this source/core. +// +// This core 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. +// +// Redistribution and use of source or resulting binaries, with or without modification +// of this file, are permitted under one of the following two license terms: +// +// 1. The GNU General Public License version 2 as published by the +// Free Software Foundation, which can be found in the top level directory +// of this repository (LICENSE_GPL2), and also online at: +// +// +// OR +// +// 2. An ADI specific BSD license, which can be found in the top level directory +// of this repository (LICENSE_ADIBSD), and also on-line at: +// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD +// This will allow to generate bit files and not release the source code, +// as long as it attaches to an ADI device. +// +// *************************************************************************** +// *************************************************************************** + +`timescale 1ns/100ps + +module up_hdmi_rx #( + + parameter ID = 0) ( + + // hdmi interface + + input hdmi_clk, + output hdmi_rst, + output hdmi_edge_sel, + output hdmi_bgr, + output hdmi_packed, + output hdmi_csc_bypass, + output [15:0] hdmi_vs_count, + output [15:0] hdmi_hs_count, + input hdmi_dma_ovf, + input hdmi_dma_unf, + input hdmi_tpm_oos, + input hdmi_vs_oos, + input hdmi_hs_oos, + input hdmi_vs_mismatch, + input hdmi_hs_mismatch, + input [15:0] hdmi_vs, + input [15:0] hdmi_hs, + input [31:0] hdmi_clk_ratio, + + // bus interface + + input up_rstn, + input up_clk, + input up_wreq, + input [13:0] up_waddr, + input [31:0] up_wdata, + output reg up_wack, + input up_rreq, + input [13:0] up_raddr, + output reg [31:0] up_rdata, + output reg up_rack); + + localparam PCORE_VERSION = 32'h00040063; + + // internal registers + + reg up_core_preset = 'd0; + reg up_resetn = 'd0; + reg [31:0] up_scratch = 'd0; + reg up_edge_sel = 'd0; + reg up_bgr = 'd0; + reg up_packed = 'd0; + reg up_csc_bypass = 'd0; + reg up_dma_ovf = 'd0; + reg up_dma_unf = 'd0; + reg up_tpm_oos = 'd0; + reg up_vs_oos = 'd0; + reg up_hs_oos = 'd0; + reg up_vs_mismatch = 'd0; + reg up_hs_mismatch = 'd0; + reg [15:0] up_vs_count = 'd0; + reg [15:0] up_hs_count = 'd0; + + // internal signals + + wire up_wreq_s; + wire up_rreq_s; + wire up_dma_ovf_s; + wire up_dma_unf_s; + wire up_vs_oos_s; + wire up_hs_oos_s; + wire up_vs_mismatch_s; + wire up_hs_mismatch_s; + wire [15:0] up_vs_s; + wire [15:0] up_hs_s; + wire [31:0] up_clk_count_s; + + // decode block select + + assign up_wreq_s = (up_waddr[13:12] == 2'd0) ? up_wreq : 1'b0; + assign up_rreq_s = (up_raddr[13:12] == 2'd0) ? up_rreq : 1'b0; + + // processor write interface + + always @(negedge up_rstn or posedge up_clk) begin + if (up_rstn == 0) begin + up_core_preset <= 1'd1; + up_resetn <= 'd0; + up_wack <= 'd0; + up_scratch <= 'd0; + up_edge_sel <= 'd0; + up_bgr <= 'd0; + up_packed <= 'd0; + up_csc_bypass <= 'd0; + up_dma_ovf <= 'd0; + up_dma_unf <= 'd0; + up_tpm_oos <= 'd0; + up_vs_oos <= 'd0; + up_hs_oos <= 'd0; + up_vs_mismatch <= 'd0; + up_hs_mismatch <= 'd0; + up_vs_count <= 'd0; + up_hs_count <= 'd0; + end else begin + up_wack <= up_wreq_s; + up_core_preset <= ~up_resetn; + if ((up_wreq_s == 1'b1) && (up_waddr[11:0] == 12'h002)) begin + up_scratch <= up_wdata; + end + if ((up_wreq_s == 1'b1) && (up_waddr[11:0] == 12'h010)) begin + up_resetn <= up_wdata[0]; + end + if ((up_wreq_s == 1'b1) && (up_waddr[11:0] == 12'h011)) begin + up_edge_sel <= up_wdata[3]; + up_bgr <= up_wdata[2]; + up_packed <= up_wdata[1]; + up_csc_bypass <= up_wdata[0]; + end + if (up_dma_ovf_s == 1'b1) begin + up_dma_ovf <= 1'b1; + end else if ((up_wreq_s == 1'b1) && (up_waddr[11:0] == 12'h018)) begin + up_dma_ovf <= up_dma_ovf & ~up_wdata[1]; + end + if (up_dma_unf_s == 1'b1) begin + up_dma_unf <= 1'b1; + end else if ((up_wreq_s == 1'b1) && (up_waddr[11:0] == 12'h018)) begin + up_dma_unf <= up_dma_unf & ~up_wdata[0]; + end + if (up_tpm_oos_s == 1'b1) begin + up_tpm_oos <= 1'b1; + end else if ((up_wreq_s == 1'b1) && (up_waddr[11:0] == 12'h019)) begin + up_tpm_oos <= up_tpm_oos & ~up_wdata[1]; + end + if (up_vs_oos_s == 1'b1) begin + up_vs_oos <= 1'b1; + end else if ((up_wreq_s == 1'b1) && (up_waddr[11:0] == 12'h020)) begin + up_vs_oos <= up_vs_oos & ~up_wdata[3]; + end + if (up_hs_oos_s == 1'b1) begin + up_hs_oos <= 1'b1; + end else if ((up_wreq_s == 1'b1) && (up_waddr[11:0] == 12'h020)) begin + up_hs_oos <= up_hs_oos & ~up_wdata[2]; + end + if (up_vs_mismatch_s == 1'b1) begin + up_vs_mismatch <= 1'b1; + end else if ((up_wreq_s == 1'b1) && (up_waddr[11:0] == 12'h020)) begin + up_vs_mismatch <= up_vs_mismatch & ~up_wdata[1]; + end + if (up_hs_mismatch_s == 1'b1) begin + up_hs_mismatch <= 1'b1; + end else if ((up_wreq_s == 1'b1) && (up_waddr[11:0] == 12'h020)) begin + up_hs_mismatch <= up_hs_mismatch & ~up_wdata[0]; + end + if ((up_wreq_s == 1'b1) && (up_waddr[11:0] == 12'h100)) begin + up_vs_count <= up_wdata[31:16]; + up_hs_count <= up_wdata[15:0]; + end + end + end + + // processor read interface + + always @(negedge up_rstn or posedge up_clk) begin + if (up_rstn == 1'b0) begin + up_rack <= 'd0; + up_rdata <= 'd0; + end else begin + up_rack <= up_rreq_s; + if(up_rreq_s == 1'b1) begin + case (up_raddr[11:0]) + 12'h000: up_rdata <= PCORE_VERSION; + 12'h001: up_rdata <= ID; + 12'h002: up_rdata <= up_scratch; + 12'h010: up_rdata <= {31'h0, up_resetn}; + 12'h011: up_rdata <= {28'h0, up_edge_sel, up_bgr, up_packed, up_csc_bypass}; + 12'h015: up_rdata <= up_clk_count_s; + 12'h016: up_rdata <= hdmi_clk_ratio; + 12'h018: up_rdata <= {30'h0, up_dma_ovf, up_dma_unf}; + 12'h019: up_rdata <= {30'h0, up_tpm_oos, 1'b0}; + 12'h020: up_rdata <= {28'h0, up_vs_oos, up_hs_oos, + up_vs_mismatch, up_hs_mismatch}; + 12'h100: up_rdata <= {up_vs_count, up_hs_count}; + 12'h101: up_rdata <= {up_vs_s, up_hs_s}; + default: up_rdata <= 0; + endcase + end + end + end + + // resets + + ad_rst i_hdmi_rst_reg ( + .rst_async (up_core_preset), + .clk (hdmi_clk), + .rstn (), + .rst (hdmi_rst)); + + // hdmi control & status + + up_xfer_cntrl #(.DATA_WIDTH(36)) i_hdmi_xfer_cntrl ( + .up_rstn (up_rstn), + .up_clk (up_clk), + .up_data_cntrl ({ up_edge_sel, + up_bgr, + up_packed, + up_csc_bypass, + up_vs_count, + up_hs_count}), + .up_xfer_done (), + .d_rst (hdmi_rst), + .d_clk (hdmi_clk), + .d_data_cntrl ({ hdmi_edge_sel, + hdmi_bgr, + hdmi_packed, + hdmi_csc_bypass, + hdmi_vs_count, + hdmi_hs_count})); + + up_xfer_status #(.DATA_WIDTH(39)) i_hdmi_xfer_status ( + .up_rstn (up_rstn), + .up_clk (up_clk), + .up_data_status ({ up_dma_ovf_s, + up_dma_unf_s, + up_tpm_oos_s, + up_vs_oos_s, + up_hs_oos_s, + up_vs_mismatch_s, + up_hs_mismatch_s, + up_vs_s, + up_hs_s}), + .d_rst (hdmi_rst), + .d_clk (hdmi_clk), + .d_data_status ({ hdmi_dma_ovf, + hdmi_dma_unf, + hdmi_tpm_oos, + hdmi_vs_oos, + hdmi_hs_oos, + hdmi_vs_mismatch, + hdmi_hs_mismatch, + hdmi_vs, + hdmi_hs})); + + up_clock_mon i_hdmi_clock_mon ( + .up_rstn (up_rstn), + .up_clk (up_clk), + .up_d_count (up_clk_count_s), + .d_rst (hdmi_rst), + .d_clk (hdmi_clk)); + +endmodule + +// *************************************************************************** +// *************************************************************************** diff --git a/src/adi/hdl/library/common/up_hdmi_tx.v b/src/adi/hdl/library/common/up_hdmi_tx.v new file mode 100644 index 00000000..219e34c0 --- /dev/null +++ b/src/adi/hdl/library/common/up_hdmi_tx.v @@ -0,0 +1,350 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright 2014 - 2017 (c) Analog Devices, Inc. All rights reserved. +// +// In this HDL repository, there are many different and unique modules, consisting +// of various HDL (Verilog or VHDL) components. The individual modules are +// developed independently, and may be accompanied by separate and unique license +// terms. +// +// The user should read each of these license terms, and understand the +// freedoms and responsibilities that he or she has by using this source/core. +// +// This core 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. +// +// Redistribution and use of source or resulting binaries, with or without modification +// of this file, are permitted under one of the following two license terms: +// +// 1. The GNU General Public License version 2 as published by the +// Free Software Foundation, which can be found in the top level directory +// of this repository (LICENSE_GPL2), and also online at: +// +// +// OR +// +// 2. An ADI specific BSD license, which can be found in the top level directory +// of this repository (LICENSE_ADIBSD), and also on-line at: +// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD +// This will allow to generate bit files and not release the source code, +// as long as it attaches to an ADI device. +// +// *************************************************************************** +// *************************************************************************** + +`timescale 1ns/100ps + +module up_hdmi_tx #( + + parameter ID = 0) ( + + // hdmi interface + + input hdmi_clk, + output hdmi_rst, + output hdmi_csc_bypass, + output hdmi_ss_bypass, + output [ 1:0] hdmi_srcsel, + output [23:0] hdmi_const_rgb, + output [15:0] hdmi_hl_active, + output [15:0] hdmi_hl_width, + output [15:0] hdmi_hs_width, + output [15:0] hdmi_he_max, + output [15:0] hdmi_he_min, + output [15:0] hdmi_vf_active, + output [15:0] hdmi_vf_width, + output [15:0] hdmi_vs_width, + output [15:0] hdmi_ve_max, + output [15:0] hdmi_ve_min, + output [23:0] hdmi_clip_max, + output [23:0] hdmi_clip_min, + input hdmi_status, + input hdmi_tpm_oos, + input [31:0] hdmi_clk_ratio, + + // vdma interface + + input vdma_clk, + output vdma_rst, + input vdma_ovf, + input vdma_unf, + input vdma_tpm_oos, + + // bus interface + + input up_rstn, + input up_clk, + input up_wreq, + input [13:0] up_waddr, + input [31:0] up_wdata, + output reg up_wack, + input up_rreq, + input [13:0] up_raddr, + output reg [31:0] up_rdata, + output reg up_rack); + + localparam PCORE_VERSION = 32'h00040063; + + // internal registers + + reg up_core_preset = 'd0; + reg [31:0] up_scratch = 'd0; + reg up_resetn = 'd0; + reg up_csc_bypass = 'd0; + reg up_ss_bypass = 'd0; + reg [ 1:0] up_srcsel = 'd1; + reg [23:0] up_const_rgb = 'd0; + reg up_vdma_ovf = 'd0; + reg up_vdma_unf = 'd0; + reg up_hdmi_tpm_oos = 'd0; + reg up_vdma_tpm_oos = 'd0; + reg [15:0] up_hl_active = 'd0; + reg [15:0] up_hl_width = 'd0; + reg [15:0] up_hs_width = 'd0; + reg [15:0] up_he_max = 'd0; + reg [15:0] up_he_min = 'd0; + reg [15:0] up_vf_active = 'd0; + reg [15:0] up_vf_width = 'd0; + reg [15:0] up_vs_width = 'd0; + reg [15:0] up_ve_max = 'd0; + reg [15:0] up_ve_min = 'd0; + reg [23:0] up_clip_max = 'd0; + reg [23:0] up_clip_min = 'd0; + + // internal signals + + wire up_wreq_s; + wire up_rreq_s; + wire up_hdmi_status_s; + wire up_hdmi_tpm_oos_s; + wire [31:0] up_hdmi_clk_count_s; + wire up_vdma_ovf_s; + wire up_vdma_unf_s; + wire up_vdma_tpm_oos_s; + + // decode block select + + assign up_wreq_s = (up_waddr[13:12] == 2'd0) ? up_wreq : 1'b0; + assign up_rreq_s = (up_raddr[13:12] == 2'd0) ? up_rreq : 1'b0; + + // processor write interface + + always @(negedge up_rstn or posedge up_clk) begin + if (up_rstn == 0) begin + up_core_preset <= 1'd1; + up_wack <= 'd0; + up_scratch <= 'd0; + up_resetn <= 'd0; + up_csc_bypass <= 'd0; + up_ss_bypass <= 'd0; + up_srcsel <= 'd1; + up_const_rgb <= 'd0; + up_vdma_ovf <= 'd0; + up_vdma_unf <= 'd0; + up_hdmi_tpm_oos <= 'd0; + up_vdma_tpm_oos <= 'd0; + up_hl_active <= 'd0; + up_hl_width <= 'd0; + up_hs_width <= 'd0; + up_he_max <= 'd0; + up_he_min <= 'd0; + up_vf_active <= 'd0; + up_vf_width <= 'd0; + up_vs_width <= 'd0; + up_ve_max <= 'd0; + up_ve_min <= 'd0; + up_clip_max <= 24'hf0ebf0; + up_clip_min <= 24'h101010; + end else begin + up_core_preset <= ~up_resetn; + up_wack <= up_wreq_s; + if ((up_wreq_s == 1'b1) && (up_waddr[11:0] == 12'h002)) begin + up_scratch <= up_wdata; + end + if ((up_wreq_s == 1'b1) && (up_waddr[11:0] == 12'h010)) begin + up_resetn <= up_wdata[0]; + end + if ((up_wreq_s == 1'b1) && (up_waddr[11:0] == 12'h011)) begin + up_ss_bypass <= up_wdata[2]; + up_csc_bypass <= up_wdata[0]; + end + if ((up_wreq_s == 1'b1) && (up_waddr[11:0] == 12'h012)) begin + up_srcsel <= up_wdata[1:0]; + end + if ((up_wreq_s == 1'b1) && (up_waddr[11:0] == 12'h013)) begin + up_const_rgb <= up_wdata[23:0]; + end + if (up_vdma_ovf_s == 1'b1) begin + up_vdma_ovf <= 1'b1; + end else if ((up_wreq_s == 1'b1) && (up_waddr[11:0] == 12'h018)) begin + up_vdma_ovf <= up_vdma_ovf & ~up_wdata[1]; + end + if (up_vdma_unf_s == 1'b1) begin + up_vdma_unf <= 1'b1; + end else if ((up_wreq_s == 1'b1) && (up_waddr[11:0] == 12'h018)) begin + up_vdma_unf <= up_vdma_unf & ~up_wdata[0]; + end + if (up_hdmi_tpm_oos_s == 1'b1) begin + up_hdmi_tpm_oos <= 1'b1; + end else if ((up_wreq_s == 1'b1) && (up_waddr[11:0] == 12'h019)) begin + up_hdmi_tpm_oos <= up_hdmi_tpm_oos & ~up_wdata[1]; + end + if (up_vdma_tpm_oos_s == 1'b1) begin + up_vdma_tpm_oos <= 1'b1; + end else if ((up_wreq_s == 1'b1) && (up_waddr[11:0] == 12'h019)) begin + up_vdma_tpm_oos <= up_vdma_tpm_oos & ~up_wdata[0]; + end + if ((up_wreq_s == 1'b1) && (up_waddr[11:0] == 12'h01a)) begin + up_clip_max <= up_wdata[23:0]; + end + if ((up_wreq_s == 1'b1) && (up_waddr[11:0] == 12'h01b)) begin + up_clip_min <= up_wdata[23:0]; + end + if ((up_wreq_s == 1'b1) && (up_waddr[11:0] == 12'h100)) begin + up_hl_active <= up_wdata[31:16]; + up_hl_width <= up_wdata[15:0]; + end + if ((up_wreq_s == 1'b1) && (up_waddr[11:0] == 12'h101)) begin + up_hs_width <= up_wdata[15:0]; + end + if ((up_wreq_s == 1'b1) && (up_waddr[11:0] == 12'h102)) begin + up_he_max <= up_wdata[31:16]; + up_he_min <= up_wdata[15:0]; + end + if ((up_wreq_s == 1'b1) && (up_waddr[11:0] == 12'h110)) begin + up_vf_active <= up_wdata[31:16]; + up_vf_width <= up_wdata[15:0]; + end + if ((up_wreq_s == 1'b1) && (up_waddr[11:0] == 12'h111)) begin + up_vs_width <= up_wdata[15:0]; + end + if ((up_wreq_s == 1'b1) && (up_waddr[11:0] == 12'h112)) begin + up_ve_max <= up_wdata[31:16]; + up_ve_min <= up_wdata[15:0]; + end + end + end + + // processor read interface + + always @(negedge up_rstn or posedge up_clk) begin + if (up_rstn == 0) begin + up_rack <= 'd0; + up_rdata <= 'd0; + end else begin + up_rack <= up_rreq_s; + if (up_rreq_s == 1'b1) begin + case (up_raddr[11:0]) + 12'h000: up_rdata <= PCORE_VERSION; + 12'h001: up_rdata <= ID; + 12'h002: up_rdata <= up_scratch; + 12'h010: up_rdata <= {31'd0, up_resetn}; + 12'h011: up_rdata <= {29'd0, up_ss_bypass, 1'b0, up_csc_bypass}; + 12'h012: up_rdata <= {30'd0, up_srcsel}; + 12'h013: up_rdata <= {8'd0, up_const_rgb}; + 12'h015: up_rdata <= up_hdmi_clk_count_s; + 12'h016: up_rdata <= hdmi_clk_ratio; + 12'h017: up_rdata <= {31'd0, up_hdmi_status_s}; + 12'h018: up_rdata <= {30'd0, up_vdma_ovf, up_vdma_unf}; + 12'h019: up_rdata <= {30'd0, up_hdmi_tpm_oos, up_vdma_tpm_oos}; + 12'h01a: up_rdata <= {8'd0, up_clip_max}; + 12'h01b: up_rdata <= {8'd0, up_clip_min}; + + 12'h100: up_rdata <= {up_hl_active, up_hl_width}; + 12'h101: up_rdata <= {16'd0, up_hs_width}; + 12'h102: up_rdata <= {up_he_max, up_he_min}; + 12'h110: up_rdata <= {up_vf_active, up_vf_width}; + 12'h111: up_rdata <= {16'd0, up_vs_width}; + 12'h112: up_rdata <= {up_ve_max, up_ve_min}; + default: up_rdata <= 0; + endcase + end else begin + up_rdata <= 32'd0; + end + end + end + + // resets + + ad_rst i_core_rst_reg (.rst_async(up_core_preset), .clk(hdmi_clk), .rstn(), .rst(hdmi_rst)); + ad_rst i_vdma_rst_reg (.rst_async(up_core_preset), .clk(vdma_clk), .rstn(), .rst(vdma_rst)); + + // hdmi control & status + + up_xfer_cntrl #(.DATA_WIDTH(236)) i_xfer_cntrl ( + .up_rstn (up_rstn), + .up_clk (up_clk), + .up_data_cntrl ({ up_ss_bypass, + up_csc_bypass, + up_srcsel, + up_const_rgb, + up_hl_active, + up_hl_width, + up_hs_width, + up_he_max, + up_he_min, + up_vf_active, + up_vf_width, + up_vs_width, + up_ve_max, + up_ve_min, + up_clip_max, + up_clip_min}), + .up_xfer_done (), + .d_rst (hdmi_rst), + .d_clk (hdmi_clk), + .d_data_cntrl ({ hdmi_ss_bypass, + hdmi_csc_bypass, + hdmi_srcsel, + hdmi_const_rgb, + hdmi_hl_active, + hdmi_hl_width, + hdmi_hs_width, + hdmi_he_max, + hdmi_he_min, + hdmi_vf_active, + hdmi_vf_width, + hdmi_vs_width, + hdmi_ve_max, + hdmi_ve_min, + hdmi_clip_max, + hdmi_clip_min})); + + up_xfer_status #(.DATA_WIDTH(2)) i_xfer_status ( + .up_rstn (up_rstn), + .up_clk (up_clk), + .up_data_status ({up_hdmi_status_s, + up_hdmi_tpm_oos_s}), + .d_rst (hdmi_rst), + .d_clk (hdmi_clk), + .d_data_status ({ hdmi_status, + hdmi_tpm_oos})); + + // hdmi clock monitor + + up_clock_mon i_clock_mon ( + .up_rstn (up_rstn), + .up_clk (up_clk), + .up_d_count (up_hdmi_clk_count_s), + .d_rst (hdmi_rst), + .d_clk (hdmi_clk)); + + // vdma control & status + + up_xfer_status #(.DATA_WIDTH(3)) i_vdma_xfer_status ( + .up_rstn (up_rstn), + .up_clk (up_clk), + .up_data_status ({up_vdma_ovf_s, + up_vdma_unf_s, + up_vdma_tpm_oos_s}), + .d_rst (vdma_rst), + .d_clk (vdma_clk), + .d_data_status ({ vdma_ovf, + vdma_unf, + vdma_tpm_oos})); + +endmodule + +// *************************************************************************** +// *************************************************************************** diff --git a/src/adi/hdl/library/common/up_pmod.v b/src/adi/hdl/library/common/up_pmod.v new file mode 100644 index 00000000..defe31cb --- /dev/null +++ b/src/adi/hdl/library/common/up_pmod.v @@ -0,0 +1,136 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright 2014 - 2017 (c) Analog Devices, Inc. All rights reserved. +// +// In this HDL repository, there are many different and unique modules, consisting +// of various HDL (Verilog or VHDL) components. The individual modules are +// developed independently, and may be accompanied by separate and unique license +// terms. +// +// The user should read each of these license terms, and understand the +// freedoms and responsibilities that he or she has by using this source/core. +// +// This core 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. +// +// Redistribution and use of source or resulting binaries, with or without modification +// of this file, are permitted under one of the following two license terms: +// +// 1. The GNU General Public License version 2 as published by the +// Free Software Foundation, which can be found in the top level directory +// of this repository (LICENSE_GPL2), and also online at: +// +// +// OR +// +// 2. An ADI specific BSD license, which can be found in the top level directory +// of this repository (LICENSE_ADIBSD), and also on-line at: +// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD +// This will allow to generate bit files and not release the source code, +// as long as it attaches to an ADI device. +// +// *************************************************************************** +// *************************************************************************** + +`timescale 1ns/100ps + +module up_pmod #( + + parameter ID = 0) ( + + input pmod_clk, + output pmod_rst, + input [31:0] pmod_signal_freq, + + // bus interface + + input up_rstn, + input up_clk, + input up_wreq, + input [13:0] up_waddr, + input [31:0] up_wdata, + output reg up_wack, + input up_rreq, + input [13:0] up_raddr, + output reg [31:0] up_rdata, + output reg up_rack); + + localparam PCORE_VERSION = 32'h00010001; + + // internal registers + + reg [31:0] up_scratch = 'd0; + reg up_resetn = 'd0; + + // internal signals + + wire [31:0] up_pmod_signal_freq_s; + wire up_wreq_s; + wire up_rreq_s; + + // decode block select + + assign up_wreq_s = (up_waddr[13:8] == 6'h00) ? up_wreq : 1'b0; + assign up_rreq_s = (up_raddr[13:8] == 6'h00) ? up_rreq : 1'b0; + assign up_preset_s = ~up_resetn; + + // processor write interface + + always @(negedge up_rstn or posedge up_clk) begin + if (up_rstn == 0) begin + up_wack <= 'd0; + up_scratch <= 'd0; + up_resetn <= 'd0; + end else begin + up_wack <= up_wreq_s; + if ((up_wreq_s == 1'b1) && (up_waddr[7:0] == 8'h02)) begin + up_scratch <= up_wdata; + end + if ((up_wreq_s == 1'b1) && (up_waddr[7:0] == 8'h10)) begin + up_resetn <= up_wdata[0]; + end + end + end + + // processor read interface + + always @(negedge up_rstn or posedge up_clk) begin + if (up_rstn == 0) begin + up_rack <= 'd0; + up_rdata <= 'd0; + end else begin + up_rack <= up_rreq_s; + if (up_rreq_s == 1'b1) begin + case (up_raddr[7:0]) + 8'h00: up_rdata <= PCORE_VERSION; + 8'h01: up_rdata <= ID; + 8'h02: up_rdata <= up_scratch; + 8'h03: up_rdata <= up_pmod_signal_freq_s; + 8'h10: up_rdata <= up_resetn; + default: up_rdata <= 0; + endcase + end else begin + up_rdata <= 32'd0; + end + end + end + + // resets + + ad_rst i_adc_rst_reg (.rst_async(up_preset_s), .clk(pmod_clk), .rstn(), .rst(pmod_rst)); + + // adc control & status + + up_xfer_status #(.DATA_WIDTH(32)) i_pmod_xfer_status ( + .up_rstn (up_rstn), + .up_clk (up_clk), + .up_data_status (up_pmod_signal_freq_s), + .d_rst (pmod_rst), + .d_clk (pmod_clk), + .d_data_status (pmod_signal_freq)); + +endmodule + +// *************************************************************************** +// *************************************************************************** diff --git a/src/adi/hdl/library/common/up_tdd_cntrl.v b/src/adi/hdl/library/common/up_tdd_cntrl.v new file mode 100644 index 00000000..8715ac36 --- /dev/null +++ b/src/adi/hdl/library/common/up_tdd_cntrl.v @@ -0,0 +1,444 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright 2014 - 2017 (c) Analog Devices, Inc. All rights reserved. +// +// In this HDL repository, there are many different and unique modules, consisting +// of various HDL (Verilog or VHDL) components. The individual modules are +// developed independently, and may be accompanied by separate and unique license +// terms. +// +// The user should read each of these license terms, and understand the +// freedoms and responsibilities that he or she has by using this source/core. +// +// This core 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. +// +// Redistribution and use of source or resulting binaries, with or without modification +// of this file, are permitted under one of the following two license terms: +// +// 1. The GNU General Public License version 2 as published by the +// Free Software Foundation, which can be found in the top level directory +// of this repository (LICENSE_GPL2), and also online at: +// +// +// OR +// +// 2. An ADI specific BSD license, which can be found in the top level directory +// of this repository (LICENSE_ADIBSD), and also on-line at: +// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD +// This will allow to generate bit files and not release the source code, +// as long as it attaches to an ADI device. +// +// *************************************************************************** +// *************************************************************************** +`timescale 1ns/100ps + +module up_tdd_cntrl #( + + parameter ID = 0) ( + + input clk, + input rst, + + //rf tdd interface control + + output tdd_enable, + output tdd_secondary, + output tdd_rx_only, + output tdd_tx_only, + output tdd_gated_rx_dmapath, + output tdd_gated_tx_dmapath, + output [ 7:0] tdd_burst_count, + output [23:0] tdd_counter_init, + output [23:0] tdd_frame_length, + output tdd_terminal_type, + output [23:0] tdd_vco_rx_on_1, + output [23:0] tdd_vco_rx_off_1, + output [23:0] tdd_vco_tx_on_1, + output [23:0] tdd_vco_tx_off_1, + output [23:0] tdd_rx_on_1, + output [23:0] tdd_rx_off_1, + output [23:0] tdd_rx_dp_on_1, + output [23:0] tdd_rx_dp_off_1, + output [23:0] tdd_tx_on_1, + output [23:0] tdd_tx_off_1, + output [23:0] tdd_tx_dp_on_1, + output [23:0] tdd_tx_dp_off_1, + output [23:0] tdd_vco_rx_on_2, + output [23:0] tdd_vco_rx_off_2, + output [23:0] tdd_vco_tx_on_2, + output [23:0] tdd_vco_tx_off_2, + output [23:0] tdd_rx_on_2, + output [23:0] tdd_rx_off_2, + output [23:0] tdd_rx_dp_on_2, + output [23:0] tdd_rx_dp_off_2, + output [23:0] tdd_tx_on_2, + output [23:0] tdd_tx_off_2, + output [23:0] tdd_tx_dp_on_2, + output [23:0] tdd_tx_dp_off_2, + + input [ 7:0] tdd_status, + + // bus interface + + input up_rstn, + input up_clk, + input up_wreq, + input [13:0] up_waddr, + input [31:0] up_wdata, + output reg up_wack, + input up_rreq, + input [13:0] up_raddr, + output reg [31:0] up_rdata, + output reg up_rack); + + localparam PCORE_VERSION = 32'h00010061; + + // internal registers + + reg [31:0] up_scratch = 32'h0; + + reg up_tdd_enable = 1'h0; + reg up_tdd_secondary = 1'h0; + reg up_tdd_rx_only = 1'h0; + reg up_tdd_tx_only = 1'h0; + reg up_tdd_gated_tx_dmapath = 1'h0; + reg up_tdd_gated_rx_dmapath = 1'h0; + reg up_tdd_terminal_type = 1'h0; + + reg [ 7:0] up_tdd_burst_count = 8'h0; + reg [23:0] up_tdd_counter_init = 24'h0; + reg [23:0] up_tdd_frame_length = 24'h0; + + reg [23:0] up_tdd_vco_rx_on_1 = 24'h0; + reg [23:0] up_tdd_vco_rx_off_1 = 24'h0; + reg [23:0] up_tdd_vco_tx_on_1 = 24'h0; + reg [23:0] up_tdd_vco_tx_off_1 = 24'h0; + reg [23:0] up_tdd_rx_on_1 = 24'h0; + reg [23:0] up_tdd_rx_off_1 = 24'h0; + reg [23:0] up_tdd_rx_dp_on_1 = 24'h0; + reg [23:0] up_tdd_rx_dp_off_1 = 24'h0; + reg [23:0] up_tdd_tx_on_1 = 24'h0; + reg [23:0] up_tdd_tx_off_1 = 24'h0; + reg [23:0] up_tdd_tx_dp_on_1 = 24'h0; + reg [23:0] up_tdd_tx_dp_off_1 = 24'h0; + reg [23:0] up_tdd_vco_rx_on_2 = 24'h0; + reg [23:0] up_tdd_vco_rx_off_2 = 24'h0; + reg [23:0] up_tdd_vco_tx_on_2 = 24'h0; + reg [23:0] up_tdd_vco_tx_off_2 = 24'h0; + reg [23:0] up_tdd_rx_on_2 = 24'h0; + reg [23:0] up_tdd_rx_off_2 = 24'h0; + reg [23:0] up_tdd_rx_dp_on_2 = 24'h0; + reg [23:0] up_tdd_rx_dp_off_2 = 24'h0; + reg [23:0] up_tdd_tx_on_2 = 24'h0; + reg [23:0] up_tdd_tx_off_2 = 24'h0; + reg [23:0] up_tdd_tx_dp_on_2 = 24'h0; + reg [23:0] up_tdd_tx_dp_off_2 = 24'h0; + + // internal signals + + wire up_wreq_s; + wire up_rreq_s; + + wire [ 7:0] up_tdd_status_s; + + // decode block select + + assign up_wreq_s = (up_waddr[13:8] == 6'h20) ? up_wreq : 1'b0; + assign up_rreq_s = (up_raddr[13:8] == 6'h20) ? up_rreq : 1'b0; + + // processor write interface + + always @(negedge up_rstn or posedge up_clk) begin + if (up_rstn == 0) begin + up_wack <= 1'h0; + up_scratch <= 32'h0; + up_tdd_enable <= 1'h0; + up_tdd_secondary <= 1'h0; + up_tdd_rx_only <= 1'h0; + up_tdd_tx_only <= 1'h0; + up_tdd_gated_tx_dmapath <= 1'h0; + up_tdd_gated_rx_dmapath <= 1'h0; + up_tdd_terminal_type <= 1'h0; + up_tdd_counter_init <= 24'h0; + up_tdd_frame_length <= 24'h0; + up_tdd_burst_count <= 8'h0; + up_tdd_vco_rx_on_1 <= 24'h0; + up_tdd_vco_rx_off_1 <= 24'h0; + up_tdd_vco_tx_on_1 <= 24'h0; + up_tdd_vco_tx_off_1 <= 24'h0; + up_tdd_rx_on_1 <= 24'h0; + up_tdd_rx_off_1 <= 24'h0; + up_tdd_rx_dp_on_1 <= 24'h0; + up_tdd_rx_dp_off_1 <= 24'h0; + up_tdd_tx_on_1 <= 24'h0; + up_tdd_tx_off_1 <= 24'h0; + up_tdd_tx_dp_on_1 <= 24'h0; + up_tdd_tx_dp_off_1 <= 24'h0; + up_tdd_vco_rx_on_2 <= 24'h0; + up_tdd_vco_rx_off_2 <= 24'h0; + up_tdd_vco_tx_on_2 <= 24'h0; + up_tdd_vco_tx_off_2 <= 24'h0; + up_tdd_rx_on_2 <= 24'h0; + up_tdd_rx_off_2 <= 24'h0; + up_tdd_rx_dp_on_2 <= 24'h0; + up_tdd_rx_dp_off_2 <= 24'h0; + up_tdd_tx_on_2 <= 24'h0; + up_tdd_tx_off_2 <= 24'h0; + up_tdd_tx_dp_on_2 <= 24'h0; + up_tdd_tx_dp_off_2 <= 24'h0; + end else begin + up_wack <= up_wreq_s; + if ((up_wreq_s == 1'b1) && (up_waddr[7:0] == 8'h02)) begin + up_scratch <= up_wdata; + end + if ((up_wreq_s == 1'b1) && (up_waddr[7:0] == 8'h10)) begin + up_tdd_enable <= up_wdata[0]; + up_tdd_secondary <= up_wdata[1]; + up_tdd_rx_only <= up_wdata[2]; + up_tdd_tx_only <= up_wdata[3]; + up_tdd_gated_rx_dmapath <= up_wdata[4]; + up_tdd_gated_tx_dmapath <= up_wdata[5]; + end + if ((up_wreq_s == 1'b1) && (up_waddr[7:0] == 8'h11)) begin + up_tdd_burst_count <= up_wdata[7:0]; + end + if ((up_wreq_s == 1'b1) && (up_waddr[7:0] == 8'h12)) begin + up_tdd_counter_init <= up_wdata[23:0]; + end + if ((up_wreq_s == 1'b1) && (up_waddr[7:0] == 8'h13)) begin + up_tdd_frame_length <= up_wdata[23:0]; + end + if ((up_wreq_s == 1'b1) && (up_waddr[7:0] == 8'h14)) begin + up_tdd_terminal_type <= up_wdata[0]; + end + if ((up_wreq_s == 1'b1) && (up_waddr[7:0] == 8'h20)) begin + up_tdd_vco_rx_on_1 <= up_wdata[23:0]; + end + if ((up_wreq_s == 1'b1) && (up_waddr[7:0] == 8'h21)) begin + up_tdd_vco_rx_off_1 <= up_wdata[23:0]; + end + if ((up_wreq_s == 1'b1) && (up_waddr[7:0] == 8'h22)) begin + up_tdd_vco_tx_on_1 <= up_wdata[23:0]; + end + if ((up_wreq_s == 1'b1) && (up_waddr[7:0] == 8'h23)) begin + up_tdd_vco_tx_off_1 <= up_wdata[23:0]; + end + if ((up_wreq_s == 1'b1) && (up_waddr[7:0] == 8'h24)) begin + up_tdd_rx_on_1 <= up_wdata[23:0]; + end + if ((up_wreq_s == 1'b1) && (up_waddr[7:0] == 8'h25)) begin + up_tdd_rx_off_1 <= up_wdata[23:0]; + end + if ((up_wreq_s == 1'b1) && (up_waddr[7:0] == 8'h26)) begin + up_tdd_tx_on_1 <= up_wdata[23:0]; + end + if ((up_wreq_s == 1'b1) && (up_waddr[7:0] == 8'h27)) begin + up_tdd_tx_off_1 <= up_wdata[23:0]; + end + if ((up_wreq_s == 1'b1) && (up_waddr[7:0] == 8'h28)) begin + up_tdd_rx_dp_on_1 <= up_wdata[23:0]; + end + if ((up_wreq_s == 1'b1) && (up_waddr[7:0] == 8'h29)) begin + up_tdd_rx_dp_off_1 <= up_wdata[23:0]; + end + if ((up_wreq_s == 1'b1) && (up_waddr[7:0] == 8'h2a)) begin + up_tdd_tx_dp_on_1 <= up_wdata[23:0]; + end + if ((up_wreq_s == 1'b1) && (up_waddr[7:0] == 8'h2b)) begin + up_tdd_tx_dp_off_1 <= up_wdata[23:0]; + end + if ((up_wreq_s == 1'b1) && (up_waddr[7:0] == 8'h30)) begin + up_tdd_vco_rx_on_2 <= up_wdata[23:0]; + end + if ((up_wreq_s == 1'b1) && (up_waddr[7:0] == 8'h31)) begin + up_tdd_vco_rx_off_2 <= up_wdata[23:0]; + end + if ((up_wreq_s == 1'b1) && (up_waddr[7:0] == 8'h32)) begin + up_tdd_vco_tx_on_2 <= up_wdata[23:0]; + end + if ((up_wreq_s == 1'b1) && (up_waddr[7:0] == 8'h33)) begin + up_tdd_vco_tx_off_2 <= up_wdata[23:0]; + end + if ((up_wreq_s == 1'b1) && (up_waddr[7:0] == 8'h34)) begin + up_tdd_rx_on_2 <= up_wdata[23:0]; + end + if ((up_wreq_s == 1'b1) && (up_waddr[7:0] == 8'h35)) begin + up_tdd_rx_off_2 <= up_wdata[23:0]; + end + if ((up_wreq_s == 1'b1) && (up_waddr[7:0] == 8'h36)) begin + up_tdd_tx_on_2 <= up_wdata[23:0]; + end + if ((up_wreq_s == 1'b1) && (up_waddr[7:0] == 8'h37)) begin + up_tdd_tx_off_2 <= up_wdata[23:0]; + end + if ((up_wreq_s == 1'b1) && (up_waddr[7:0] == 8'h38)) begin + up_tdd_rx_dp_on_2 <= up_wdata[23:0]; + end + if ((up_wreq_s == 1'b1) && (up_waddr[7:0] == 8'h39)) begin + up_tdd_rx_dp_off_2 <= up_wdata[23:0]; + end + if ((up_wreq_s == 1'b1) && (up_waddr[7:0] == 8'h3a)) begin + up_tdd_tx_dp_on_2 <= up_wdata[23:0]; + end + if ((up_wreq_s == 1'b1) && (up_waddr[7:0] == 8'h3b)) begin + up_tdd_tx_dp_off_2 <= up_wdata[23:0]; + end + end + end + + // processor read interface + + always @(negedge up_rstn or posedge up_clk) begin + if (up_rstn == 0) begin + up_rack <= 1'b0; + up_rdata <= 1'b0; + end else begin + up_rack <= up_rreq_s; + if (up_rreq_s == 1'b1) begin + case (up_raddr[7:0]) + 8'h00: up_rdata <= PCORE_VERSION; + 8'h01: up_rdata <= ID; + 8'h02: up_rdata <= up_scratch; + 8'h10: up_rdata <= {28'h0, up_tdd_gated_tx_dmapath, + up_tdd_gated_rx_dmapath, + up_tdd_tx_only, + up_tdd_rx_only, + up_tdd_secondary, + up_tdd_enable}; + 8'h11: up_rdata <= {24'h0, up_tdd_burst_count}; + 8'h12: up_rdata <= { 8'h0, up_tdd_counter_init}; + 8'h13: up_rdata <= { 8'h0, up_tdd_frame_length}; + 8'h14: up_rdata <= {31'h0, up_tdd_terminal_type}; + 8'h18: up_rdata <= {24'h0, up_tdd_status_s}; + 8'h20: up_rdata <= { 8'h0, up_tdd_vco_rx_on_1}; + 8'h21: up_rdata <= { 8'h0, up_tdd_vco_rx_off_1}; + 8'h22: up_rdata <= { 8'h0, up_tdd_vco_tx_on_1}; + 8'h23: up_rdata <= { 8'h0, up_tdd_vco_tx_off_1}; + 8'h24: up_rdata <= { 8'h0, up_tdd_rx_on_1}; + 8'h25: up_rdata <= { 8'h0, up_tdd_rx_off_1}; + 8'h26: up_rdata <= { 8'h0, up_tdd_tx_on_1}; + 8'h27: up_rdata <= { 8'h0, up_tdd_tx_off_1}; + 8'h28: up_rdata <= { 8'h0, up_tdd_rx_dp_on_1}; + 8'h29: up_rdata <= { 8'h0, up_tdd_rx_dp_off_1}; + 8'h2a: up_rdata <= { 8'h0, up_tdd_tx_dp_on_1}; + 8'h2b: up_rdata <= { 8'h0, up_tdd_tx_dp_off_1}; + 8'h30: up_rdata <= { 8'h0, up_tdd_vco_rx_on_2}; + 8'h31: up_rdata <= { 8'h0, up_tdd_vco_rx_off_2}; + 8'h32: up_rdata <= { 8'h0, up_tdd_vco_tx_on_2}; + 8'h33: up_rdata <= { 8'h0, up_tdd_vco_tx_off_2}; + 8'h34: up_rdata <= { 8'h0, up_tdd_rx_on_2}; + 8'h35: up_rdata <= { 8'h0, up_tdd_rx_off_2}; + 8'h36: up_rdata <= { 8'h0, up_tdd_tx_on_2}; + 8'h37: up_rdata <= { 8'h0, up_tdd_tx_off_2}; + 8'h38: up_rdata <= { 8'h0, up_tdd_rx_dp_on_2}; + 8'h39: up_rdata <= { 8'h0, up_tdd_rx_dp_off_2}; + 8'h3a: up_rdata <= { 8'h0, up_tdd_tx_dp_on_2}; + 8'h3b: up_rdata <= { 8'h0, up_tdd_tx_dp_off_2}; + default: up_rdata <= 32'h0; + endcase + end + end + end + + // rf tdd control signal CDC + + up_xfer_cntrl #(.DATA_WIDTH(15)) i_xfer_tdd_control ( + .up_rstn(up_rstn), + .up_clk(up_clk), + .up_data_cntrl({up_tdd_enable, + up_tdd_secondary, + up_tdd_rx_only, + up_tdd_tx_only, + up_tdd_gated_rx_dmapath, + up_tdd_gated_tx_dmapath, + up_tdd_burst_count, + up_tdd_terminal_type + }), + .up_xfer_done(), + .d_rst(rst), + .d_clk(clk), + .d_data_cntrl({tdd_enable, + tdd_secondary, + tdd_rx_only, + tdd_tx_only, + tdd_gated_rx_dmapath, + tdd_gated_tx_dmapath, + tdd_burst_count, + tdd_terminal_type + })); + + up_xfer_cntrl #(.DATA_WIDTH(624)) i_xfer_tdd_counter_values ( + .up_rstn(up_rstn), + .up_clk(up_clk), + .up_data_cntrl({up_tdd_counter_init, + up_tdd_frame_length, + up_tdd_vco_rx_on_1, + up_tdd_vco_rx_off_1, + up_tdd_vco_tx_on_1, + up_tdd_vco_tx_off_1, + up_tdd_rx_on_1, + up_tdd_rx_off_1, + up_tdd_tx_on_1, + up_tdd_tx_off_1, + up_tdd_rx_dp_on_1, + up_tdd_rx_dp_off_1, + up_tdd_tx_dp_on_1, + up_tdd_tx_dp_off_1, + up_tdd_vco_rx_on_2, + up_tdd_vco_rx_off_2, + up_tdd_vco_tx_on_2, + up_tdd_vco_tx_off_2, + up_tdd_rx_on_2, + up_tdd_rx_off_2, + up_tdd_tx_on_2, + up_tdd_tx_off_2, + up_tdd_rx_dp_on_2, + up_tdd_rx_dp_off_2, + up_tdd_tx_dp_on_2, + up_tdd_tx_dp_off_2 + }), + .up_xfer_done(), + .d_rst(rst), + .d_clk(clk), + .d_data_cntrl({tdd_counter_init, + tdd_frame_length, + tdd_vco_rx_on_1, + tdd_vco_rx_off_1, + tdd_vco_tx_on_1, + tdd_vco_tx_off_1, + tdd_rx_on_1, + tdd_rx_off_1, + tdd_tx_on_1, + tdd_tx_off_1, + tdd_rx_dp_on_1, + tdd_rx_dp_off_1, + tdd_tx_dp_on_1, + tdd_tx_dp_off_1, + tdd_vco_rx_on_2, + tdd_vco_rx_off_2, + tdd_vco_tx_on_2, + tdd_vco_tx_off_2, + tdd_rx_on_2, + tdd_rx_off_2, + tdd_tx_on_2, + tdd_tx_off_2, + tdd_rx_dp_on_2, + tdd_rx_dp_off_2, + tdd_tx_dp_on_2, + tdd_tx_dp_off_2 + })); + + up_xfer_status #(.DATA_WIDTH(8)) i_xfer_tdd_status ( + .up_rstn (up_rstn), + .up_clk (up_clk), + .up_data_status (up_tdd_status_s), + .d_rst (rst), + .d_clk (clk), + .d_data_status (tdd_status)); + +endmodule + +// *************************************************************************** +// *************************************************************************** diff --git a/src/adi/hdl/library/common/up_xfer_cntrl.v b/src/adi/hdl/library/common/up_xfer_cntrl.v new file mode 100644 index 00000000..3a6307cd --- /dev/null +++ b/src/adi/hdl/library/common/up_xfer_cntrl.v @@ -0,0 +1,126 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright 2014 - 2017 (c) Analog Devices, Inc. All rights reserved. +// +// In this HDL repository, there are many different and unique modules, consisting +// of various HDL (Verilog or VHDL) components. The individual modules are +// developed independently, and may be accompanied by separate and unique license +// terms. +// +// The user should read each of these license terms, and understand the +// freedoms and responsibilities that he or she has by using this source/core. +// +// This core 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. +// +// Redistribution and use of source or resulting binaries, with or without modification +// of this file, are permitted under one of the following two license terms: +// +// 1. The GNU General Public License version 2 as published by the +// Free Software Foundation, which can be found in the top level directory +// of this repository (LICENSE_GPL2), and also online at: +// +// +// OR +// +// 2. An ADI specific BSD license, which can be found in the top level directory +// of this repository (LICENSE_ADIBSD), and also on-line at: +// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD +// This will allow to generate bit files and not release the source code, +// as long as it attaches to an ADI device. +// +// *************************************************************************** +// *************************************************************************** + +`timescale 1ns/100ps + +module up_xfer_cntrl #( + + parameter DATA_WIDTH = 8) ( + + // up interface + + input up_rstn, + input up_clk, + input [(DATA_WIDTH-1):0] up_data_cntrl, + output up_xfer_done, + + // device interface + + input d_rst, + input d_clk, + output [(DATA_WIDTH-1):0] d_data_cntrl); + + // internal registers + + reg up_xfer_state_m1 = 'd0; + reg up_xfer_state_m2 = 'd0; + reg up_xfer_state = 'd0; + reg [ 5:0] up_xfer_count = 'd0; + reg up_xfer_done_int = 'd0; + reg up_xfer_toggle = 'd0; + reg [(DATA_WIDTH-1):0] up_xfer_data = 'd0; + reg d_xfer_toggle_m1 = 'd0; + reg d_xfer_toggle_m2 = 'd0; + reg d_xfer_toggle_m3 = 'd0; + reg d_xfer_toggle = 'd0; + reg [(DATA_WIDTH-1):0] d_data_cntrl_int = 'd0; + + // internal signals + + wire up_xfer_enable_s; + wire d_xfer_toggle_s; + + // device control transfer + + assign up_xfer_done = up_xfer_done_int; + assign up_xfer_enable_s = up_xfer_state ^ up_xfer_toggle; + + always @(posedge up_clk) begin + if (up_rstn == 1'b0) begin + up_xfer_state_m1 <= 'd0; + up_xfer_state_m2 <= 'd0; + up_xfer_state <= 'd0; + up_xfer_count <= 'd0; + up_xfer_done_int <= 'd0; + up_xfer_toggle <= 'd0; + up_xfer_data <= 'd0; + end else begin + up_xfer_state_m1 <= d_xfer_toggle; + up_xfer_state_m2 <= up_xfer_state_m1; + up_xfer_state <= up_xfer_state_m2; + up_xfer_count <= up_xfer_count + 1'd1; + up_xfer_done_int <= (up_xfer_count == 6'd1) ? ~up_xfer_enable_s : 1'b0; + if ((up_xfer_count == 6'd1) && (up_xfer_enable_s == 1'b0)) begin + up_xfer_toggle <= ~up_xfer_toggle; + up_xfer_data <= up_data_cntrl; + end + end + end + + assign d_data_cntrl = d_data_cntrl_int; + assign d_xfer_toggle_s = d_xfer_toggle_m3 ^ d_xfer_toggle_m2; + + always @(posedge d_clk or posedge d_rst) begin + if (d_rst == 1'b1) begin + d_xfer_toggle_m1 <= 'd0; + d_xfer_toggle_m2 <= 'd0; + d_xfer_toggle_m3 <= 'd0; + d_xfer_toggle <= 'd0; + d_data_cntrl_int <= 'd0; + end else begin + d_xfer_toggle_m1 <= up_xfer_toggle; + d_xfer_toggle_m2 <= d_xfer_toggle_m1; + d_xfer_toggle_m3 <= d_xfer_toggle_m2; + d_xfer_toggle <= d_xfer_toggle_m3; + if (d_xfer_toggle_s == 1'b1) begin + d_data_cntrl_int <= up_xfer_data; + end + end + end + +endmodule + +// *************************************************************************** +// *************************************************************************** diff --git a/src/adi/hdl/library/common/up_xfer_status.v b/src/adi/hdl/library/common/up_xfer_status.v new file mode 100644 index 00000000..59c5f9f2 --- /dev/null +++ b/src/adi/hdl/library/common/up_xfer_status.v @@ -0,0 +1,128 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright 2014 - 2017 (c) Analog Devices, Inc. All rights reserved. +// +// In this HDL repository, there are many different and unique modules, consisting +// of various HDL (Verilog or VHDL) components. The individual modules are +// developed independently, and may be accompanied by separate and unique license +// terms. +// +// The user should read each of these license terms, and understand the +// freedoms and responsibilities that he or she has by using this source/core. +// +// This core 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. +// +// Redistribution and use of source or resulting binaries, with or without modification +// of this file, are permitted under one of the following two license terms: +// +// 1. The GNU General Public License version 2 as published by the +// Free Software Foundation, which can be found in the top level directory +// of this repository (LICENSE_GPL2), and also online at: +// +// +// OR +// +// 2. An ADI specific BSD license, which can be found in the top level directory +// of this repository (LICENSE_ADIBSD), and also on-line at: +// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD +// This will allow to generate bit files and not release the source code, +// as long as it attaches to an ADI device. +// +// *************************************************************************** +// *************************************************************************** + +`timescale 1ns/100ps + +module up_xfer_status #( + + parameter DATA_WIDTH = 8) ( + + // up interface + + input up_rstn, + input up_clk, + output [(DATA_WIDTH-1):0] up_data_status, + + // device interface + + input d_rst, + input d_clk, + input [(DATA_WIDTH-1):0] d_data_status); + + // internal registers + + reg d_xfer_state_m1 = 'd0; + reg d_xfer_state_m2 = 'd0; + reg d_xfer_state = 'd0; + reg [ 5:0] d_xfer_count = 'd0; + reg d_xfer_toggle = 'd0; + reg [(DATA_WIDTH-1):0] d_xfer_data = 'd0; + reg [(DATA_WIDTH-1):0] d_acc_data = 'd0; + reg up_xfer_toggle_m1 = 'd0; + reg up_xfer_toggle_m2 = 'd0; + reg up_xfer_toggle_m3 = 'd0; + reg up_xfer_toggle = 'd0; + reg [(DATA_WIDTH-1):0] up_data_status_int = 'd0; + + // internal signals + + wire d_xfer_enable_s; + wire up_xfer_toggle_s; + + // device status transfer + + assign d_xfer_enable_s = d_xfer_state ^ d_xfer_toggle; + + always @(posedge d_clk or posedge d_rst) begin + if (d_rst == 1'b1) begin + d_xfer_state_m1 <= 'd0; + d_xfer_state_m2 <= 'd0; + d_xfer_state <= 'd0; + d_xfer_count <= 'd0; + d_xfer_toggle <= 'd0; + d_xfer_data <= 'd0; + d_acc_data <= 'd0; + end else begin + d_xfer_state_m1 <= up_xfer_toggle; + d_xfer_state_m2 <= d_xfer_state_m1; + d_xfer_state <= d_xfer_state_m2; + d_xfer_count <= d_xfer_count + 1'd1; + if ((d_xfer_count == 6'd1) && (d_xfer_enable_s == 1'b0)) begin + d_xfer_toggle <= ~d_xfer_toggle; + d_xfer_data <= d_acc_data; + end + if ((d_xfer_count == 6'd1) && (d_xfer_enable_s == 1'b0)) begin + d_acc_data <= d_data_status; + end else begin + d_acc_data <= d_acc_data | d_data_status; + end + end + end + + assign up_data_status = up_data_status_int; + assign up_xfer_toggle_s = up_xfer_toggle_m3 ^ up_xfer_toggle_m2; + + always @(posedge up_clk) begin + if (up_rstn == 1'b0) begin + up_xfer_toggle_m1 <= 'd0; + up_xfer_toggle_m2 <= 'd0; + up_xfer_toggle_m3 <= 'd0; + up_xfer_toggle <= 'd0; + up_data_status_int <= 'd0; + end else begin + up_xfer_toggle_m1 <= d_xfer_toggle; + up_xfer_toggle_m2 <= up_xfer_toggle_m1; + up_xfer_toggle_m3 <= up_xfer_toggle_m2; + up_xfer_toggle <= up_xfer_toggle_m3; + if (up_xfer_toggle_s == 1'b1) begin + up_data_status_int <= d_xfer_data; + end + end + end + +endmodule + +// *************************************************************************** +// *************************************************************************** diff --git a/src/adi/hdl/library/common/util_axis_upscale.v b/src/adi/hdl/library/common/util_axis_upscale.v new file mode 100644 index 00000000..575070c8 --- /dev/null +++ b/src/adi/hdl/library/common/util_axis_upscale.v @@ -0,0 +1,98 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright 2014 - 2017 (c) Analog Devices, Inc. All rights reserved. +// +// In this HDL repository, there are many different and unique modules, consisting +// of various HDL (Verilog or VHDL) components. The individual modules are +// developed independently, and may be accompanied by separate and unique license +// terms. +// +// The user should read each of these license terms, and understand the +// freedoms and responsibilities that he or she has by using this source/core. +// +// This core 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. +// +// Redistribution and use of source or resulting binaries, with or without modification +// of this file, are permitted under one of the following two license terms: +// +// 1. The GNU General Public License version 2 as published by the +// Free Software Foundation, which can be found in the top level directory +// of this repository (LICENSE_GPL2), and also online at: +// +// +// OR +// +// 2. An ADI specific BSD license, which can be found in the top level directory +// of this repository (LICENSE_ADIBSD), and also on-line at: +// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD +// This will allow to generate bit files and not release the source code, +// as long as it attaches to an ADI device. +// +// *************************************************************************** +// *************************************************************************** +// + A simple AXI stream data upscale module, which can be used with devices +// with resolution which can not be aligned to a WORD (32 bits). Eg. 24 bits +// + It has the same control interface as the ad_datafmt module, which controls +// the data format inside a generic AXI converter core. +// + Supports multiple channels. Contains a single register stage. + +`timescale 1ns/100ps + +module util_axis_upscale # ( + + parameter NUM_OF_CHANNELS = 4, + parameter DATA_WIDTH = 24, + parameter UDATA_WIDTH = 32)( + + input clk, + input resetn, + + input s_axis_valid, + output reg s_axis_ready, + input [(NUM_OF_CHANNELS*DATA_WIDTH)-1:0] s_axis_data, + + output reg m_axis_valid, + input m_axis_ready, + output reg [(NUM_OF_CHANNELS*UDATA_WIDTH)-1:0] m_axis_data, + + input dfmt_enable, + input dfmt_type, + input dfmt_se); + + wire type_s; + wire signext_s; + wire sign_s; + wire [(NUM_OF_CHANNELS*UDATA_WIDTH)-1:0] data_out_s; + + localparam MSB_WIDTH = UDATA_WIDTH - DATA_WIDTH; + + assign type_s = dfmt_enable & dfmt_type; + assign signext_s = dfmt_enable & dfmt_se; + assign sign_s = signext_s & (type_s ^ s_axis_data[(DATA_WIDTH-1)]); + + genvar i; + generate + for (i=1; i <= NUM_OF_CHANNELS; i=i+1) begin + + assign data_out_s[(i*UDATA_WIDTH-1):(i*UDATA_WIDTH-MSB_WIDTH)] = {(MSB_WIDTH){sign_s}}; + assign data_out_s[((i-1)*UDATA_WIDTH+DATA_WIDTH-1)] = type_s ^ s_axis_data[(i*DATA_WIDTH-1)]; + assign data_out_s[((i-1)*UDATA_WIDTH+DATA_WIDTH-2):((i-1)*UDATA_WIDTH)] = s_axis_data[(i*DATA_WIDTH-2):((i-1)*DATA_WIDTH)]; + + end + endgenerate + + always @(posedge clk) begin + if (resetn == 1'b0) begin + m_axis_valid <= 1'b0; + s_axis_ready <= 1'b0; + m_axis_data <= {(NUM_OF_CHANNELS*UDATA_WIDTH){1'b0}}; + end else begin + m_axis_valid <= s_axis_valid; + s_axis_ready <= m_axis_ready; + m_axis_data <= data_out_s; + end + end + +endmodule diff --git a/src/adi/hdl/library/common/util_delay.v b/src/adi/hdl/library/common/util_delay.v new file mode 100644 index 00000000..c7a298a0 --- /dev/null +++ b/src/adi/hdl/library/common/util_delay.v @@ -0,0 +1,74 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright 2014 - 2017 (c) Analog Devices, Inc. All rights reserved. +// +// In this HDL repository, there are many different and unique modules, consisting +// of various HDL (Verilog or VHDL) components. The individual modules are +// developed independently, and may be accompanied by separate and unique license +// terms. +// +// The user should read each of these license terms, and understand the +// freedoms and responsibilities that he or she has by using this source/core. +// +// This core 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. +// +// Redistribution and use of source or resulting binaries, with or without modification +// of this file, are permitted under one of the following two license terms: +// +// 1. The GNU General Public License version 2 as published by the +// Free Software Foundation, which can be found in the top level directory +// of this repository (LICENSE_GPL2), and also online at: +// +// +// OR +// +// 2. An ADI specific BSD license, which can be found in the top level directory +// of this repository (LICENSE_ADIBSD), and also on-line at: +// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD +// This will allow to generate bit files and not release the source code, +// as long as it attaches to an ADI device. +// +// *************************************************************************** +// *************************************************************************** + +`timescale 1ns/100ps + +module util_delay #( + + parameter DATA_WIDTH = 1, + // the minimum valid value for DELAY_CYCLES is 1 + parameter DELAY_CYCLES = 1) ( + + input clk, + input reset, + input din, + output [DATA_WIDTH-1:0] dout); + + reg [DATA_WIDTH-1:0] dbuf[0:(DELAY_CYCLES-1)]; + + always @(posedge clk) begin + if (reset) begin + dbuf[0] <= 0; + end else begin + dbuf[0] <= din; + end + end + + generate + genvar i; + for (i = 1; i < DELAY_CYCLES; i=i+1) begin:register_pipe + always @(posedge clk) begin + if (reset) begin + dbuf[i] <= 0; + end else begin + dbuf[i] <= dbuf[i-1]; + end + end + end + endgenerate + + assign dout = dbuf[(DELAY_CYCLES-1)]; + +endmodule diff --git a/src/adi/hdl/library/common/util_pulse_gen.v b/src/adi/hdl/library/common/util_pulse_gen.v new file mode 100644 index 00000000..93817e1b --- /dev/null +++ b/src/adi/hdl/library/common/util_pulse_gen.v @@ -0,0 +1,93 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright 2014 - 2017 (c) Analog Devices, Inc. All rights reserved. +// +// In this HDL repository, there are many different and unique modules, consisting +// of various HDL (Verilog or VHDL) components. The individual modules are +// developed independently, and may be accompanied by separate and unique license +// terms. +// +// The user should read each of these license terms, and understand the +// freedoms and responsibilities that he or she has by using this source/core. +// +// This core 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. +// +// Redistribution and use of source or resulting binaries, with or without modification +// of this file, are permitted under one of the following two license terms: +// +// 1. The GNU General Public License version 2 as published by the +// Free Software Foundation, which can be found in the top level directory +// of this repository (LICENSE_GPL2), and also online at: +// +// +// OR +// +// 2. An ADI specific BSD license, which can be found in the top level directory +// of this repository (LICENSE_ADIBSD), and also on-line at: +// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD +// This will allow to generate bit files and not release the source code, +// as long as it attaches to an ADI device. +// +// *************************************************************************** +// *************************************************************************** +`timescale 1ns/1ps + +module util_pulse_gen #( + + parameter PULSE_WIDTH = 7, + parameter PULSE_PERIOD = 100000000)( // t_period * clk_freq + + input clk, + input rstn, + + input [31:0] pulse_period, + input pulse_period_en, + + output reg pulse +); + + // internal registers + + reg [(PULSE_WIDTH-1):0] pulse_width_cnt = {PULSE_WIDTH{1'b1}}; + reg [31:0] pulse_period_cnt = 32'h0; + reg [31:0] pulse_period_d = 32'b0; + + wire end_of_period_s; + + // flop the desired period + + always @(posedge clk) begin + pulse_period_d <= (pulse_period_en) ? pulse_period : PULSE_PERIOD; + end + + // a free running pulse generator + + always @(posedge clk) begin + if (rstn == 1'b0) begin + pulse_period_cnt <= 32'h0; + end else begin + pulse_period_cnt <= (pulse_period_cnt == pulse_period_d) ? 32'b0 : (pulse_period_cnt + 1); + end + end + + assign end_of_period_s = (pulse_period_cnt == pulse_period_d) ? 1'b1 : 1'b0; + + // generate pulse with a specified width + + always @(posedge clk) begin + if (rstn == 1'b0) begin + pulse_width_cnt <= 0; + pulse <= 0; + end else begin + pulse_width_cnt <= (pulse == 1'b1) ? pulse_width_cnt + 1 : {PULSE_WIDTH{1'h0}}; + if(end_of_period_s == 1'b1) begin + pulse <= 1'b1; + end else if(pulse_width_cnt == {PULSE_WIDTH{1'b1}}) begin + pulse <= 1'b0; + end + end + end + +endmodule diff --git a/src/adi/hdl/library/interfaces/Makefile b/src/adi/hdl/library/interfaces/Makefile new file mode 100644 index 00000000..5e69904a --- /dev/null +++ b/src/adi/hdl/library/interfaces/Makefile @@ -0,0 +1,52 @@ +#################################################################################### +#################################################################################### +## Copyright 2011(c) Analog Devices, Inc. +## Auto-generated, do not modify! +#################################################################################### +#################################################################################### + +include ../../quiet.mk + +M_DEPS := interfaces_ip.tcl +M_DEPS += ../scripts/adi_env.tcl +M_DEPS += ../scripts/adi_ip.tcl + +M_VIVADO := vivado -mode batch -source + +M_FLIST := *.log +M_FLIST += *.jou +M_FLIST += if_xcvr_cm.xml +M_FLIST += if_xcvr_cm_rtl.xml +M_FLIST += if_xcvr_ch.xml +M_FLIST += if_xcvr_ch_rtl.xml +M_FLIST += if_gt_qpll.xml +M_FLIST += if_gt_qpll_rtl.xml +M_FLIST += if_gt_pll.xml +M_FLIST += if_gt_pll_rtl.xml +M_FLIST += if_gt_rx.xml +M_FLIST += if_gt_rx_rtl.xml +M_FLIST += if_gt_tx.xml +M_FLIST += if_gt_tx_rtl.xml +M_FLIST += if_gt_rx_ksig.xml +M_FLIST += if_gt_rx_ksig_rtl.xml + + +.PHONY: all xilinx clean clean-all +all: xilinx +xilinx: if_xcvr_cm.xml if_xcvr_cm_rtl.xml if_xcvr_ch.xml if_xcvr_ch_rtl.xml if_gt_qpll.xml if_gt_qpll_rtl.xml if_gt_pll.xml if_gt_pll_rtl.xml if_gt_rx.xml if_gt_rx_rtl.xml if_gt_tx.xml if_gt_tx_rtl.xml if_gt_rx_ksig.xml if_gt_rx_ksig_rtl.xml + +clean:clean-all + +clean-all: + $(call clean, \ + $(M_FLIST), \ + interface definitions) + +%.xml: $(M_DEPS) + $(call build, \ + $(M_VIVADO) interfaces_ip.tcl, \ + interfaces_ip.log, \ + interface definitions) + +#################################################################################### +#################################################################################### diff --git a/src/adi/hdl/library/interfaces/interfaces_ip.tcl b/src/adi/hdl/library/interfaces/interfaces_ip.tcl new file mode 100644 index 00000000..83bed7f7 --- /dev/null +++ b/src/adi/hdl/library/interfaces/interfaces_ip.tcl @@ -0,0 +1,99 @@ +# ip + +source ../scripts/adi_env.tcl +source $ad_hdl_dir/library/scripts/adi_ip.tcl + +adi_if_define if_xcvr_cm +adi_if_ports output 1 enb +adi_if_ports output 12 addr +adi_if_ports output 1 wr +adi_if_ports output 16 wdata +adi_if_ports input 16 rdata +adi_if_ports input 1 ready + +adi_if_define if_xcvr_ch +adi_if_ports input 1 pll_locked +adi_if_ports output 1 rst +adi_if_ports output 1 user_ready +adi_if_ports input 1 rst_done +adi_if_ports output 1 lpm_dfe_n +adi_if_ports output 3 rate +adi_if_ports output 2 sys_clk_sel +adi_if_ports output 3 out_clk_sel +adi_if_ports output 4 tx_diffctrl +adi_if_ports output 5 tx_postcursor +adi_if_ports output 5 tx_precursor +adi_if_ports output 1 enb +adi_if_ports output 12 addr +adi_if_ports output 1 wr +adi_if_ports output 16 wdata +adi_if_ports input 16 rdata +adi_if_ports input 1 ready + +adi_if_define if_gt_qpll +adi_if_ports output 1 qpll_rst reset +adi_if_ports output 1 qpll_ref_clk clock + +adi_if_define if_gt_pll +adi_if_ports output 1 cpll_rst_m reset +adi_if_ports output 1 cpll_ref_clk_in clock + +adi_if_define if_gt_rx +adi_if_ports output 1 rx_p +adi_if_ports output 1 rx_n +adi_if_ports input 1 rx_rst reset +adi_if_ports output 1 rx_rst_m reset +adi_if_ports input 1 rx_pll_rst reset +adi_if_ports input 1 rx_gt_rst reset +adi_if_ports output 1 rx_gt_rst_m reset +adi_if_ports input 1 rx_pll_locked +adi_if_ports output 1 rx_pll_locked_m +adi_if_ports input 1 rx_user_ready +adi_if_ports output 1 rx_user_ready_m +adi_if_ports input 1 rx_rst_done +adi_if_ports output 1 rx_rst_done_m +adi_if_ports input 1 rx_out_clk clock +adi_if_ports output 1 rx_clk clock +adi_if_ports output 1 rx_sysref +adi_if_ports input 1 rx_sync +adi_if_ports input 1 rx_sof +adi_if_ports input 32 rx_data +adi_if_ports input 1 rx_ip_rst reset +adi_if_ports output 4 rx_ip_sof +adi_if_ports output 32 rx_ip_data +adi_if_ports input 1 rx_ip_sysref +adi_if_ports output 1 rx_ip_sync +adi_if_ports input 1 rx_ip_rst_done + +adi_if_define if_gt_tx +adi_if_ports input 1 tx_p +adi_if_ports input 1 tx_n +adi_if_ports input 1 tx_rst reset +adi_if_ports output 1 tx_rst_m reset +adi_if_ports input 1 tx_pll_rst reset +adi_if_ports input 1 tx_gt_rst reset +adi_if_ports output 1 tx_gt_rst_m reset +adi_if_ports input 1 tx_pll_locked +adi_if_ports output 1 tx_pll_locked_m +adi_if_ports input 1 tx_user_ready +adi_if_ports output 1 tx_user_ready_m +adi_if_ports input 1 tx_rst_done +adi_if_ports output 1 tx_rst_done_m +adi_if_ports input 1 tx_out_clk clock +adi_if_ports output 1 tx_clk clock +adi_if_ports output 1 tx_sysref +adi_if_ports output 1 tx_sync +adi_if_ports output 32 tx_data +adi_if_ports input 1 tx_ip_rst reset +adi_if_ports input 32 tx_ip_data +adi_if_ports input 1 tx_ip_sysref +adi_if_ports input 1 tx_ip_sync +adi_if_ports input 1 tx_ip_rst_done + +adi_if_define if_gt_rx_ksig +adi_if_ports output 4 rx_gt_ilas_f +adi_if_ports output 4 rx_gt_ilas_q +adi_if_ports output 4 rx_gt_ilas_a +adi_if_ports output 4 rx_gt_ilas_r +adi_if_ports output 4 rx_gt_cgs_k + diff --git a/src/adi/hdl/library/scripts/adi_env.tcl b/src/adi/hdl/library/scripts/adi_env.tcl new file mode 100644 index 00000000..361e8858 --- /dev/null +++ b/src/adi/hdl/library/scripts/adi_env.tcl @@ -0,0 +1,15 @@ + +# environment related stuff + +set ad_hdl_dir [file normalize [file join [file dirname [info script]] "../.."]] +set ad_phdl_dir $ad_hdl_dir + + +if [info exists ::env(ADI_HDL_DIR)] { + set ad_hdl_dir [file normalize $::env(ADI_HDL_DIR)] +} + +if [info exists ::env(ADI_PHDL_DIR)] { + set ad_phdl_dir [file normalize $::env(ADI_PHDL_DIR)] +} + diff --git a/src/adi/hdl/library/scripts/adi_ip.tcl b/src/adi/hdl/library/scripts/adi_ip.tcl new file mode 100644 index 00000000..df83cc57 --- /dev/null +++ b/src/adi/hdl/library/scripts/adi_ip.tcl @@ -0,0 +1,368 @@ +## ############################################################################################### +## ############################################################################################### +## check tool version + +if {![info exists REQUIRED_VIVADO_VERSION]} { + set REQUIRED_VIVADO_VERSION "2018.2" +} + +if {[info exists ::env(ADI_IGNORE_VERSION_CHECK)]} { + set IGNORE_VERSION_CHECK 1 +} elseif {![info exists IGNORE_VERSION_CHECK]} { + set IGNORE_VERSION_CHECK 0 +} + +## ############################################################################################### +## ############################################################################################### +## ip related stuff + +proc adi_ip_ttcl {ip_name ip_constr_files} { + + set proj_filegroup [ipx::get_file_groups -of_objects [ipx::current_core] -filter {NAME =~ *synthesis*}] + set f [ipx::add_file $ip_constr_files $proj_filegroup] + set_property -dict [list \ + type ttcl \ + ] $f + ipx::reorder_files -front $ip_constr_files $proj_filegroup +} + +# add ttcl file to the simulation file set +proc adi_ip_sim_ttcl {ip_name ip_files} { + + set proj_filegroup [ipx::get_file_groups -of_objects [ipx::current_core] -filter {NAME =~ *simulation*}] + set f [ipx::add_file $ip_files $proj_filegroup] + set_property -dict [list \ + type ttcl \ + ] $f + ipx::reorder_files -front $ip_files $proj_filegroup +} + +proc adi_ip_bd {ip_name ip_bd_files} { + set proj_filegroup [ipx::get_file_groups xilinx_blockdiagram -of_objects [ipx::current_core]] + if {$proj_filegroup == {}} { + set proj_filegroup [ipx::add_file_group -type xilinx_blockdiagram "" [ipx::current_core]] + } + set f [ipx::add_file $ip_bd_files $proj_filegroup] + set_property -dict [list \ + type tclSource \ + ] $f +} + +proc adi_ip_infer_streaming_interfaces {ip_name} { + + ipx::infer_bus_interfaces xilinx.com:interface:axis_rtl:1.0 [ipx::current_core] + +} + +proc adi_ip_infer_mm_interfaces {ip_name} { + + ipx::infer_bus_interfaces xilinx.com:interface:aximm_rtl:1.0 [ipx::current_core] + +} + +proc adi_set_ports_dependency {port_prefix dependency {driver_value {}}} { + foreach port [ipx::get_ports [format "%s%s" $port_prefix "*"]] { + set_property ENABLEMENT_DEPENDENCY $dependency $port + if {$driver_value != {}} { + set_property DRIVER_VALUE $driver_value $port + } + } +} + +proc adi_set_bus_dependency {bus prefix dependency} { + set_property ENABLEMENT_DEPENDENCY $dependency [ipx::get_bus_interfaces $bus -of_objects [ipx::current_core]] + adi_set_ports_dependency $prefix $dependency 0 +} + +proc adi_add_port_map {bus phys logic} { + set map [ipx::add_port_map $phys $bus] + set_property "PHYSICAL_NAME" $phys $map + set_property "LOGICAL_NAME" $logic $map +} + +proc adi_add_bus {bus_name mode abs_type bus_type port_maps} { + set bus [ipx::add_bus_interface $bus_name [ipx::current_core]] + + set_property "ABSTRACTION_TYPE_VLNV" $abs_type $bus + set_property "BUS_TYPE_VLNV" $bus_type $bus + set_property "INTERFACE_MODE" $mode $bus + + foreach port_map $port_maps { + adi_add_port_map $bus {*}$port_map + } +} + +proc adi_add_multi_bus {num bus_name_prefix mode abs_type bus_type port_maps dependency} { + for {set i 0} {$i < 8} {incr i} { + set bus_name [format "%s%d" $bus_name_prefix $i] + set bus [ipx::add_bus_interface $bus_name [ipx::current_core]] + + set_property "ABSTRACTION_TYPE_VLNV" $abs_type $bus + set_property "BUS_TYPE_VLNV" $bus_type $bus + set_property "INTERFACE_MODE" $mode $bus + + if {$dependency ne ""} { + set bus_dependency [string map [list "{i}" $i] $dependency] + set_property ENABLEMENT_DEPENDENCY $bus_dependency $bus + } + + foreach port_map $port_maps { + lassign $port_map phys logic width + set map [ipx::add_port_map $phys $bus] + set_property "PHYSICAL_NAME" $phys $map + set_property "LOGICAL_NAME" $logic $map + set_property "PHYSICAL_RIGHT" [expr $i*$width] $map + set_property "PHYSICAL_LEFT" [expr ($i+1)*$width-1] $map + } + } +} + +proc adi_add_bus_clock {clock_signal_name bus_inf_name {reset_signal_name ""} {reset_signal_mode "slave"}} { + set bus_inf_name_clean [string map {":" "_"} $bus_inf_name] + set clock_inf_name [format "%s%s" $bus_inf_name_clean "_signal_clock"] + set clock_inf [ipx::add_bus_interface $clock_inf_name [ipx::current_core]] + set_property abstraction_type_vlnv "xilinx.com:signal:clock_rtl:1.0" $clock_inf + set_property bus_type_vlnv "xilinx.com:signal:clock:1.0" $clock_inf + set_property display_name $clock_inf_name $clock_inf + set clock_map [ipx::add_port_map "CLK" $clock_inf] + set_property physical_name $clock_signal_name $clock_map + + set assoc_busif [ipx::add_bus_parameter "ASSOCIATED_BUSIF" $clock_inf] + set_property value $bus_inf_name $assoc_busif + + if { $reset_signal_name != "" } { + set assoc_reset [ipx::add_bus_parameter "ASSOCIATED_RESET" $clock_inf] + set_property value $reset_signal_name $assoc_reset + + set reset_inf_name [format "%s%s" $bus_inf_name_clean "_signal_reset"] + set reset_inf [ipx::add_bus_interface $reset_inf_name [ipx::current_core]] + set_property abstraction_type_vlnv "xilinx.com:signal:reset_rtl:1.0" $reset_inf + set_property bus_type_vlnv "xilinx.com:signal:reset:1.0" $reset_inf + set_property display_name $reset_inf_name $reset_inf + set_property interface_mode $reset_signal_mode $reset_inf + set reset_map [ipx::add_port_map "RST" $reset_inf] + set_property physical_name $reset_signal_name $reset_map + + set reset_polarity [ipx::add_bus_parameter "POLARITY" $reset_inf] + if {[string match {*[Nn]} $reset_signal_name] == 1} { + set_property value "ACTIVE_LOW" $reset_polarity + } else { + set_property value "ACTIVE_HIGH" $reset_polarity + } + } +} + +proc adi_ip_add_core_dependencies {vlnvs} { + foreach file_group [ipx::get_file_groups * -of_objects [ipx::current_core]] { + foreach vlnv $vlnvs { + ipx::add_subcore $vlnv $file_group + } + } +} + +## ############################################################################################### +## ############################################################################################### +## ip related stuff + +variable ip_constr_files + +proc adi_ip_create {ip_name} { + + global ad_hdl_dir + global ad_phdl_dir + global ip_constr_files + global REQUIRED_VIVADO_VERSION + global IGNORE_VERSION_CHECK + + set VIVADO_VERSION [version -short] + if {[string compare $VIVADO_VERSION $REQUIRED_VIVADO_VERSION] != 0} { + puts -nonewline "CRITICAL WARNING: vivado version mismatch; " + puts -nonewline "expected $REQUIRED_VIVADO_VERSION, " + puts -nonewline "got $VIVADO_VERSION.\n" + } + + create_project $ip_name . -force + + ## Load custom message severity definitions + source $ad_hdl_dir/projects/scripts/adi_xilinx_msg.tcl + + set ip_constr_files "" + set lib_dirs $ad_hdl_dir/library + if {$ad_hdl_dir ne $ad_phdl_dir} { + lappend lib_dirs $ad_phdl_dir/library + } + + set_property ip_repo_paths $lib_dirs [current_fileset] + update_ip_catalog +} + +proc adi_ip_files {ip_name ip_files} { + + global ip_constr_files + + set ip_constr_files "" + foreach m_file $ip_files { + if {[file extension $m_file] eq ".xdc"} { + lappend ip_constr_files $m_file + } + } + + set proj_fileset [get_filesets sources_1] + add_files -norecurse -scan_for_includes -fileset $proj_fileset $ip_files + set_property "top" "$ip_name" $proj_fileset +} + +proc adi_ip_properties_lite {ip_name} { + + global ip_constr_files + + ipx::package_project -root_dir . -vendor analog.com -library user -taxonomy /Analog_Devices + set_property name $ip_name [ipx::current_core] + set_property vendor_display_name {Analog Devices} [ipx::current_core] + set_property company_url {http://www.analog.com} [ipx::current_core] + + set i_families "" + foreach i_part [get_parts] { + lappend i_families [get_property FAMILY $i_part] + } + set i_families [lsort -unique $i_families] + set s_families [get_property supported_families [ipx::current_core]] + foreach i_family $i_families { + set s_families "$s_families $i_family Production" + set s_families "$s_families $i_family Beta" + } + set_property supported_families $s_families [ipx::current_core] + ipx::save_core + + ipx::remove_all_bus_interface [ipx::current_core] + set memory_maps [ipx::get_memory_maps * -of_objects [ipx::current_core]] + foreach map $memory_maps { + ipx::remove_memory_map [lindex $map 2] [ipx::current_core ] + } + ipx::save_core + + set i_filegroup [ipx::get_file_groups -of_objects [ipx::current_core] -filter {NAME =~ *synthesis*}] + foreach i_file $ip_constr_files { + set i_module [file tail $i_file] + regsub {_constr\.xdc} $i_module {} i_module + ipx::add_file $i_file $i_filegroup + ipx::reorder_files -front $i_file $i_filegroup + set_property SCOPED_TO_REF $i_module [ipx::get_files $i_file -of_objects $i_filegroup] + } + ipx::save_core +} + +proc adi_ip_properties {ip_name} { + + adi_ip_properties_lite $ip_name + + ipx::infer_bus_interface {\ + s_axi_awvalid \ + s_axi_awaddr \ + s_axi_awprot \ + s_axi_awready \ + s_axi_wvalid \ + s_axi_wdata \ + s_axi_wstrb \ + s_axi_wready \ + s_axi_bvalid \ + s_axi_bresp \ + s_axi_bready \ + s_axi_arvalid \ + s_axi_araddr \ + s_axi_arprot \ + s_axi_arready \ + s_axi_rvalid \ + s_axi_rdata \ + s_axi_rresp \ + s_axi_rready} \ + xilinx.com:interface:aximm_rtl:1.0 [ipx::current_core] + + ipx::infer_bus_interface s_axi_aclk xilinx.com:signal:clock_rtl:1.0 [ipx::current_core] + ipx::infer_bus_interface s_axi_aresetn xilinx.com:signal:reset_rtl:1.0 [ipx::current_core] + + set raddr_width [expr [get_property SIZE_LEFT [ipx::get_ports -nocase true s_axi_araddr -of_objects [ipx::current_core]]] + 1] + set waddr_width [expr [get_property SIZE_LEFT [ipx::get_ports -nocase true s_axi_awaddr -of_objects [ipx::current_core]]] + 1] + + if {$raddr_width != $waddr_width} { + puts [format "WARNING: AXI address width mismatch for %s (r=%d, w=%d)" $ip_name $raddr_width, $waddr_width] + set range 65536 + } else { + if {$raddr_width >= 16} { + set range 65536 + } else { + set range [expr 1 << $raddr_width] + } + } + + ipx::add_memory_map {s_axi} [ipx::current_core] + set_property slave_memory_map_ref {s_axi} [ipx::get_bus_interfaces s_axi -of_objects [ipx::current_core]] + ipx::add_address_block {axi_lite} [ipx::get_memory_maps s_axi -of_objects [ipx::current_core]] + set_property range $range [ipx::get_address_blocks axi_lite \ + -of_objects [ipx::get_memory_maps s_axi -of_objects [ipx::current_core]]] + ipx::associate_bus_interfaces -clock s_axi_aclk -reset s_axi_aresetn [ipx::current_core] + ipx::save_core +} + +## ############################################################################################### +## ############################################################################################### +## interface related stuff + +proc adi_if_define {name} { + + ipx::create_abstraction_definition analog.com interface ${name}_rtl 1.0 + ipx::create_bus_definition analog.com interface $name 1.0 + + set_property xml_file_name ${name}_rtl.xml [ipx::current_busabs] + set_property xml_file_name ${name}.xml [ipx::current_busdef] + set_property bus_type_vlnv analog.com:interface:${name}:1.0 [ipx::current_busabs] + + ipx::save_abstraction_definition [ipx::current_busabs] + ipx::save_bus_definition [ipx::current_busdef] +} + +proc adi_if_ports {dir width name {type none}} { + + ipx::add_bus_abstraction_port $name [ipx::current_busabs] + set m_intf [ipx::get_bus_abstraction_ports $name -of_objects [ipx::current_busabs]] + set_property master_presence required $m_intf + set_property slave_presence required $m_intf + set_property master_width $width $m_intf + set_property slave_width $width $m_intf + + set m_dir "in" + set s_dir "out" + if {$dir eq "output"} { + set m_dir "out" + set s_dir "in" + } + + set_property master_direction $m_dir $m_intf + set_property slave_direction $s_dir $m_intf + + if {$type ne "none"} { + set_property is_${type} true $m_intf + } + + ipx::save_bus_definition [ipx::current_busdef] + ipx::save_abstraction_definition [ipx::current_busabs] +} + +proc adi_if_infer_bus {if_name mode name maps} { + + ipx::add_bus_interface $name [ipx::current_core] + set m_bus_if [ipx::get_bus_interfaces $name -of_objects [ipx::current_core]] + set_property abstraction_type_vlnv ${if_name}_rtl:1.0 $m_bus_if + set_property bus_type_vlnv ${if_name}:1.0 $m_bus_if + set_property interface_mode $mode $m_bus_if + + foreach map $maps { + set m_maps [regexp -all -inline {\S+} $map] + lassign $m_maps p_name p_map + ipx::add_port_map $p_name $m_bus_if + set_property physical_name $p_map [ipx::get_port_maps $p_name -of_objects $m_bus_if] + } +} + +## ############################################################################################### +## ############################################################################################### diff --git a/src/adi/hdl/library/scripts/adi_ip_alt.tcl b/src/adi/hdl/library/scripts/adi_ip_alt.tcl new file mode 100644 index 00000000..ffd08d3e --- /dev/null +++ b/src/adi/hdl/library/scripts/adi_ip_alt.tcl @@ -0,0 +1,249 @@ +################################################################################################### +################################################################################################### +# keep interface-mess out of the way - keeping it pretty is a waste of time + +proc ad_alt_intf {type name dir width {arg_1 ""} {arg_2 ""}} { + + if {([string equal -nocase ${type} "clock"]) && ([string equal -nocase ${dir} "input"])} { + add_interface if_${name} clock sink + add_interface_port if_${name} ${name} clk ${dir} ${width} + return + } + + if {([string equal -nocase ${type} "clock"]) && ([string equal -nocase ${dir} "output"])} { + add_interface if_${name} clock source + add_interface_port if_${name} ${name} clk ${dir} ${width} + return + } + + if {([string equal -nocase ${type} "reset"]) && ([string equal -nocase ${dir} "input"])} { + add_interface if_${name} reset sink + add_interface_port if_${name} ${name} reset ${dir} ${width} + set_interface_property if_${name} associatedclock ${arg_1} + return + } + + if {([string equal -nocase ${type} "reset"]) && ([string equal -nocase ${dir} "output"])} { + add_interface if_${name} reset source + add_interface_port if_${name} ${name} reset ${dir} ${width} + set_interface_property if_${name} associatedclock ${arg_1} + set_interface_property if_${name} associatedResetSinks ${arg_2} + return + } + + if {([string equal -nocase ${type} "reset-n"]) && ([string equal -nocase ${dir} "input"])} { + add_interface if_${name} reset sink + add_interface_port if_${name} ${name} reset_n ${dir} ${width} + set_interface_property if_${name} associatedclock ${arg_1} + return + } + + if {([string equal -nocase ${type} "reset-n"]) && ([string equal -nocase ${dir} "output"])} { + add_interface if_${name} reset source + add_interface_port if_${name} ${name} reset_n ${dir} ${width} + set_interface_property if_${name} associatedclock ${arg_1} + set_interface_property if_${name} associatedResetSinks ${arg_2} + return + } + + if {([string equal -nocase ${type} "intr"]) && ([string equal -nocase ${dir} "output"])} { + add_interface if_${name} interrupt source + add_interface_port if_${name} ${name} irq ${dir} ${width} + set_interface_property if_${name} associatedclock ${arg_1} + return + } + + set remap $arg_1 + if {$arg_1 eq ""} { + set remap $name + } + + if {[string equal -nocase ${type} "signal"]} { + add_interface if_${name} conduit end + add_interface_port if_${name} ${name} ${remap} ${dir} ${width} + return + } +} + +proc ad_conduit {if_name if_port port dir width} { + + add_interface $if_name conduit end + add_interface_port $if_name $port $if_port $dir $width +} + +proc ad_generate_module_inst { inst_name mark source_file target_file } { + + set fp_source [open $source_file "r"] + set fp_target [open $target_file "w+"] + + fconfigure $fp_source -buffering line + + while { [gets $fp_source data] >= 0 } { + + # update the required module name + regsub $inst_name $data "&_$mark" data + puts $data + puts $fp_target $data + } + + close $fp_source + close $fp_target +} + +################################################################################################### +################################################################################################### + +proc ad_ip_create {pname pdisplay_name {pelabfunction ""} {pcomposefunction ""}} { + + set_module_property NAME $pname + set_module_property DISPLAY_NAME $pdisplay_name + set_module_property DESCRIPTION $pdisplay_name + set_module_property VERSION 1.0 + set_module_property GROUP "Analog Devices" + + if {$pelabfunction ne ""} { + set_module_property ELABORATION_CALLBACK $pelabfunction + } + + if {$pcomposefunction ne ""} { + set_module_property COMPOSITION_CALLBACK $pcomposefunction + } +} + +################################################################################################### +################################################################################################### + +proc ad_ip_parameter {pname ptype pdefault {phdl true} {properties {}}} { + + if {$pname eq "DEVICE_FAMILY"} { + add_parameter DEVICE_FAMILY STRING + set_parameter_property DEVICE_FAMILY SYSTEM_INFO {DEVICE_FAMILY} + set_parameter_property DEVICE_FAMILY AFFECTS_GENERATION true + set_parameter_property DEVICE_FAMILY HDL_PARAMETER false + set_parameter_property DEVICE_FAMILY ENABLED true + } else { + add_parameter $pname $ptype $pdefault + set_parameter_property $pname HDL_PARAMETER $phdl + set_parameter_property $pname ENABLED true + } + + foreach {key value} $properties { + set_parameter_property $pname $key $value + } +} + +################################################################################################### +################################################################################################### + +proc ad_ip_addfile {pname pfile} { + + set pmodule [file tail $pfile] + + regsub {\..$} $pmodule {} mname + if {$pname eq $mname} { + add_fileset_file $pmodule VERILOG PATH $pfile TOP_LEVEL_FILE + return + } + + set ptype [file extension $pfile] + if {$ptype eq ".v"} { + add_fileset_file $pmodule VERILOG PATH $pfile + return + } + if {$ptype eq ".vh"} { + add_fileset_file $pmodule VERILOG_INCLUDE PATH $pfile + return + } + if {$ptype eq ".sdc"} { + add_fileset_file $pmodule SDC PATH $pfile + return + } + if {$ptype eq ".tcl"} { + add_fileset_file $pmodule OTHER PATH $pfile + return + } +} + +proc ad_ip_files {pname pfiles {pfunction ""}} { + + add_fileset quartus_synth QUARTUS_SYNTH $pfunction "" + set_fileset_property quartus_synth TOP_LEVEL $pname + foreach pfile $pfiles { + ad_ip_addfile $pname $pfile + } + + add_fileset quartus_sim SIM_VERILOG $pfunction "" + set_fileset_property quartus_sim TOP_LEVEL $pname + foreach pfile $pfiles { + ad_ip_addfile $pname $pfile + } +} + +################################################################################################### +################################################################################################### + +proc ad_ip_intf_s_axi {aclk arstn {addr_width 16}} { + + add_interface s_axi_clock clock end + add_interface_port s_axi_clock ${aclk} clk Input 1 + + add_interface s_axi_reset reset end + set_interface_property s_axi_reset associatedClock s_axi_clock + add_interface_port s_axi_reset ${arstn} reset_n Input 1 + + add_interface s_axi axi4lite end + set_interface_property s_axi associatedClock s_axi_clock + set_interface_property s_axi associatedReset s_axi_reset + add_interface_port s_axi s_axi_awvalid awvalid Input 1 + add_interface_port s_axi s_axi_awaddr awaddr Input $addr_width + add_interface_port s_axi s_axi_awprot awprot Input 3 + add_interface_port s_axi s_axi_awready awready Output 1 + add_interface_port s_axi s_axi_wvalid wvalid Input 1 + add_interface_port s_axi s_axi_wdata wdata Input 32 + add_interface_port s_axi s_axi_wstrb wstrb Input 4 + add_interface_port s_axi s_axi_wready wready Output 1 + add_interface_port s_axi s_axi_bvalid bvalid Output 1 + add_interface_port s_axi s_axi_bresp bresp Output 2 + add_interface_port s_axi s_axi_bready bready Input 1 + add_interface_port s_axi s_axi_arvalid arvalid Input 1 + add_interface_port s_axi s_axi_araddr araddr Input $addr_width + add_interface_port s_axi s_axi_arprot arprot Input 3 + add_interface_port s_axi s_axi_arready arready Output 1 + add_interface_port s_axi s_axi_rvalid rvalid Output 1 + add_interface_port s_axi s_axi_rresp rresp Output 2 + add_interface_port s_axi s_axi_rdata rdata Output 32 + add_interface_port s_axi s_axi_rready rready Input 1 +} + +################################################################################################### +################################################################################################### + +proc ad_ip_modfile {ifile ofile flist} { + + global ad_hdl_dir + + set srcfile [open ${ad_hdl_dir}/library/altera/common/${ifile} r] + set dstfile [open ${ofile} w] + + regsub {\..$} $ifile {} imodule + regsub {\..$} $ofile {} omodule + + while {[gets $srcfile srcline] >= 0} { + regsub __${imodule}__ $srcline $omodule dstline + set index 0 + foreach fword $flist { + incr index + regsub __${imodule}_${index}__ $dstline $fword dstline + } + puts $dstfile $dstline + } + + close $srcfile + close $dstfile + + ad_ip_addfile ad_ip_addfile $ofile +} + +################################################################################################### +################################################################################################### + diff --git a/src/adi/hdl/library/scripts/library.mk b/src/adi/hdl/library/scripts/library.mk new file mode 100644 index 00000000..e0a4b270 --- /dev/null +++ b/src/adi/hdl/library/scripts/library.mk @@ -0,0 +1,78 @@ +#################################################################################### +## Copyright 2018(c) Analog Devices, Inc. +#################################################################################### + +# Assumes this file is in library/scripts/library.mk +HDL_LIBRARY_PATH := $(subst scripts/library.mk,,$(lastword $(MAKEFILE_LIST))) + +include $(HDL_LIBRARY_PATH)../quiet.mk + +VIVADO := vivado -mode batch -source + +CLEAN_TARGET := *.cache +CLEAN_TARGET += *.data +CLEAN_TARGET += *.xpr +CLEAN_TARGET += *.log +CLEAN_TARGET += component.xml +CLEAN_TARGET += *.jou +CLEAN_TARGET += xgui +CLEAN_TARGET += *.ip_user_files +CLEAN_TARGET += *.srcs +CLEAN_TARGET += *.hw +CLEAN_TARGET += *.sim +CLEAN_TARGET += .Xil +CLEAN_TARGET += .timestamp_altera + +GENERIC_DEPS += $(HDL_LIBRARY_PATH)scripts/adi_env.tcl + +.PHONY: all altera altera_dep xilinx xilinx_dep clean clean-all + +all: altera xilinx + +clean: clean-all + +clean-all: + $(call clean, \ + $(CLEAN_TARGET), \ + $(HL)$(LIBRARY_NAME)$(NC) library) + +ifneq ($(ALTERA_DEPS),) + +ALTERA_DEPS += $(GENERIC_DEPS) +ALTERA_DEPS += $(HDL_LIBRARY_PATH)scripts/adi_ip_alt.tcl +ALTERA_DEPS += $(foreach dep,$(ALTERA_LIB_DEPS),$(HDL_LIBRARY_PATH)$(dep)/.timestamp_altera) + +altera: altera_dep .timestamp_altera + +.timestamp_altera: $(ALTERA_DEPS) + touch $@ + +altera_dep: + @for lib in $(ALTERA_LIB_DEPS); do \ + $(MAKE) -C $(HDL_LIBRARY_PATH)$${lib} altera || exit $$?; \ + done +endif + +ifneq ($(XILINX_DEPS),) + +XILINX_DEPS += $(GENERIC_DEPS) +XILINX_DEPS += $(HDL_LIBRARY_PATH)scripts/adi_ip.tcl +XILINX_DEPS += $(foreach dep,$(XILINX_LIB_DEPS),$(HDL_LIBRARY_PATH)$(dep)/component.xml) + +xilinx: xilinx_dep component.xml + +component.xml: $(XILINX_DEPS) + -rm -rf $(CLEAN_TARGET) + $(call build, \ + $(VIVADO) $(LIBRARY_NAME)_ip.tcl, \ + $(LIBRARY_NAME)_ip.log, \ + $(HL)$(LIBRARY_NAME)$(NC) library) + +xilinx_dep: + @for lib in $(XILINX_LIB_DEPS); do \ + $(MAKE) -C $(HDL_LIBRARY_PATH)$${lib} xilinx || exit $$?; \ + done + @for intf in $(XILINX_INTERFACE_DEPS); do \ + $(MAKE) -C $(HDL_LIBRARY_PATH)$${intf} xilinx || exit $$?; \ + done +endif diff --git a/src/adi/hdl/library/util_axis_fifo/Makefile b/src/adi/hdl/library/util_axis_fifo/Makefile new file mode 100644 index 00000000..d76109dd --- /dev/null +++ b/src/adi/hdl/library/util_axis_fifo/Makefile @@ -0,0 +1,18 @@ +#################################################################################### +## Copyright 2018(c) Analog Devices, Inc. +## Auto-generated, do not modify! +#################################################################################### + +LIBRARY_NAME := util_axis_fifo + +GENERIC_DEPS += ../common/ad_mem.v +GENERIC_DEPS += address_gray.v +GENERIC_DEPS += address_gray_pipelined.v +GENERIC_DEPS += address_sync.v +GENERIC_DEPS += util_axis_fifo.v + +XILINX_DEPS += util_axis_fifo_ip.tcl + +XILINX_LIB_DEPS += util_cdc + +include ../scripts/library.mk diff --git a/src/adi/hdl/library/util_axis_fifo/address_gray.v b/src/adi/hdl/library/util_axis_fifo/address_gray.v new file mode 100644 index 00000000..a3eb5e25 --- /dev/null +++ b/src/adi/hdl/library/util_axis_fifo/address_gray.v @@ -0,0 +1,155 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright 2014 - 2017 (c) Analog Devices, Inc. All rights reserved. +// +// In this HDL repository, there are many different and unique modules, consisting +// of various HDL (Verilog or VHDL) components. The individual modules are +// developed independently, and may be accompanied by separate and unique license +// terms. +// +// The user should read each of these license terms, and understand the +// freedoms and responsibilities that he or she has by using this source/core. +// +// This core 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. +// +// Redistribution and use of source or resulting binaries, with or without modification +// of this file, are permitted under one of the following two license terms: +// +// 1. The GNU General Public License version 2 as published by the +// Free Software Foundation, which can be found in the top level directory +// of this repository (LICENSE_GPL2), and also online at: +// +// +// OR +// +// 2. An ADI specific BSD license, which can be found in the top level directory +// of this repository (LICENSE_ADIBSD), and also on-line at: +// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD +// This will allow to generate bit files and not release the source code, +// as long as it attaches to an ADI device. +// +// *************************************************************************** +// *************************************************************************** + +`timescale 1ns/100ps + +module fifo_address_gray #( + parameter ADDRESS_WIDTH = 4 +) ( + input m_axis_aclk, + input m_axis_aresetn, + input m_axis_ready, + output reg m_axis_valid, + output reg [ADDRESS_WIDTH:0] m_axis_level, + + input s_axis_aclk, + input s_axis_aresetn, + output reg s_axis_ready, + input s_axis_valid, + output reg s_axis_empty, + output [ADDRESS_WIDTH-1:0] s_axis_waddr, + output reg [ADDRESS_WIDTH:0] s_axis_room +); + +reg [ADDRESS_WIDTH:0] _s_axis_waddr = 'h00; +reg [ADDRESS_WIDTH:0] _s_axis_waddr_next; + +reg [ADDRESS_WIDTH:0] _m_axis_raddr = 'h00; +reg [ADDRESS_WIDTH:0] _m_axis_raddr_next; + +reg [ADDRESS_WIDTH:0] s_axis_waddr_gray = 'h00; +wire [ADDRESS_WIDTH:0] s_axis_waddr_gray_next; +wire [ADDRESS_WIDTH:0] s_axis_raddr_gray; + +reg [ADDRESS_WIDTH:0] m_axis_raddr_gray = 'h00; +wire [ADDRESS_WIDTH:0] m_axis_raddr_gray_next; +wire [ADDRESS_WIDTH:0] m_axis_waddr_gray; + +assign s_axis_waddr = _s_axis_waddr[ADDRESS_WIDTH-1:0]; + +always @(*) +begin + if (s_axis_ready && s_axis_valid) + _s_axis_waddr_next <= _s_axis_waddr + 1; + else + _s_axis_waddr_next <= _s_axis_waddr; +end + +assign s_axis_waddr_gray_next = _s_axis_waddr_next ^ _s_axis_waddr_next[ADDRESS_WIDTH:1]; + +always @(posedge s_axis_aclk) +begin + if (s_axis_aresetn == 1'b0) begin + _s_axis_waddr <= 'h00; + s_axis_waddr_gray <= 'h00; + end else begin + _s_axis_waddr <= _s_axis_waddr_next; + s_axis_waddr_gray <= s_axis_waddr_gray_next; + end +end + +always @(*) +begin + if (m_axis_ready && m_axis_valid) + _m_axis_raddr_next <= _m_axis_raddr + 1; + else + _m_axis_raddr_next <= _m_axis_raddr; +end + +assign m_axis_raddr_gray_next = _m_axis_raddr_next ^ _m_axis_raddr_next[ADDRESS_WIDTH:1]; + +always @(posedge m_axis_aclk) +begin + if (m_axis_aresetn == 1'b0) begin + _m_axis_raddr <= 'h00; + m_axis_raddr_gray <= 'h00; + end else begin + _m_axis_raddr <= _m_axis_raddr_next; + m_axis_raddr_gray <= m_axis_raddr_gray_next; + end +end + +sync_bits #( + .NUM_OF_BITS(ADDRESS_WIDTH + 1) +) i_waddr_sync ( + .out_clk(m_axis_aclk), + .out_resetn(m_axis_aresetn), + .in(s_axis_waddr_gray), + .out(m_axis_waddr_gray) +); + +sync_bits #( + .NUM_OF_BITS(ADDRESS_WIDTH + 1) +) i_raddr_sync ( + .out_clk(s_axis_aclk), + .out_resetn(s_axis_aresetn), + .in(m_axis_raddr_gray), + .out(s_axis_raddr_gray) +); + +always @(posedge s_axis_aclk) +begin + if (s_axis_aresetn == 1'b0) begin + s_axis_ready <= 1'b1; + s_axis_empty <= 1'b1; + end else begin + s_axis_ready <= (s_axis_raddr_gray[ADDRESS_WIDTH] == s_axis_waddr_gray_next[ADDRESS_WIDTH] || + s_axis_raddr_gray[ADDRESS_WIDTH-1] == s_axis_waddr_gray_next[ADDRESS_WIDTH-1] || + s_axis_raddr_gray[ADDRESS_WIDTH-2:0] != s_axis_waddr_gray_next[ADDRESS_WIDTH-2:0]); + s_axis_empty <= s_axis_raddr_gray == s_axis_waddr_gray_next; + end +end + +always @(posedge m_axis_aclk) +begin + if (s_axis_aresetn == 1'b0) + m_axis_valid <= 1'b0; + else begin + m_axis_valid <= m_axis_waddr_gray != m_axis_raddr_gray_next; + end +end + +endmodule + diff --git a/src/adi/hdl/library/util_axis_fifo/address_gray_pipelined.v b/src/adi/hdl/library/util_axis_fifo/address_gray_pipelined.v new file mode 100644 index 00000000..1b255543 --- /dev/null +++ b/src/adi/hdl/library/util_axis_fifo/address_gray_pipelined.v @@ -0,0 +1,152 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright 2014 - 2017 (c) Analog Devices, Inc. All rights reserved. +// +// In this HDL repository, there are many different and unique modules, consisting +// of various HDL (Verilog or VHDL) components. The individual modules are +// developed independently, and may be accompanied by separate and unique license +// terms. +// +// The user should read each of these license terms, and understand the +// freedoms and responsibilities that he or she has by using this source/core. +// +// This core 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. +// +// Redistribution and use of source or resulting binaries, with or without modification +// of this file, are permitted under one of the following two license terms: +// +// 1. The GNU General Public License version 2 as published by the +// Free Software Foundation, which can be found in the top level directory +// of this repository (LICENSE_GPL2), and also online at: +// +// +// OR +// +// 2. An ADI specific BSD license, which can be found in the top level directory +// of this repository (LICENSE_ADIBSD), and also on-line at: +// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD +// This will allow to generate bit files and not release the source code, +// as long as it attaches to an ADI device. +// +// *************************************************************************** +// *************************************************************************** + +`timescale 1ns/100ps + +module fifo_address_gray_pipelined #( + parameter ADDRESS_WIDTH = 4 +) ( + input m_axis_aclk, + input m_axis_aresetn, + input m_axis_ready, + output reg m_axis_valid, + output [ADDRESS_WIDTH-1:0] m_axis_raddr, + output reg [ADDRESS_WIDTH:0] m_axis_level, + + input s_axis_aclk, + input s_axis_aresetn, + output reg s_axis_ready, + input s_axis_valid, + output reg s_axis_empty, + output [ADDRESS_WIDTH-1:0] s_axis_waddr, + output reg [ADDRESS_WIDTH:0] s_axis_room +); + +localparam MAX_ROOM = {1'b1,{ADDRESS_WIDTH{1'b0}}}; + +reg [ADDRESS_WIDTH:0] _s_axis_waddr = 'h00; +reg [ADDRESS_WIDTH:0] _s_axis_waddr_next; +wire [ADDRESS_WIDTH:0] _s_axis_raddr; + +reg [ADDRESS_WIDTH:0] _m_axis_raddr = 'h00; +reg [ADDRESS_WIDTH:0] _m_axis_raddr_next; +wire [ADDRESS_WIDTH:0] _m_axis_waddr; + +assign s_axis_waddr = _s_axis_waddr[ADDRESS_WIDTH-1:0]; +assign m_axis_raddr = _m_axis_raddr[ADDRESS_WIDTH-1:0]; + +always @(*) +begin + if (s_axis_ready && s_axis_valid) + _s_axis_waddr_next <= _s_axis_waddr + 1'b1; + else + _s_axis_waddr_next <= _s_axis_waddr; +end + +always @(posedge s_axis_aclk) +begin + if (s_axis_aresetn == 1'b0) begin + _s_axis_waddr <= 'h00; + end else begin + _s_axis_waddr <= _s_axis_waddr_next; + end +end + +always @(*) +begin + if (m_axis_ready && m_axis_valid) + _m_axis_raddr_next <= _m_axis_raddr + 1'b1; + else + _m_axis_raddr_next <= _m_axis_raddr; +end + +always @(posedge m_axis_aclk) +begin + if (m_axis_aresetn == 1'b0) begin + _m_axis_raddr <= 'h00; + end else begin + _m_axis_raddr <= _m_axis_raddr_next; + end +end + +sync_gray #( + .DATA_WIDTH(ADDRESS_WIDTH + 1) +) i_waddr_sync ( + .in_clk(s_axis_aclk), + .in_resetn(s_axis_aresetn), + .out_clk(m_axis_aclk), + .out_resetn(m_axis_aresetn), + .in_count(_s_axis_waddr), + .out_count(_m_axis_waddr) +); + +sync_gray #( + .DATA_WIDTH(ADDRESS_WIDTH + 1) +) i_raddr_sync ( + .in_clk(m_axis_aclk), + .in_resetn(m_axis_aresetn), + .out_clk(s_axis_aclk), + .out_resetn(s_axis_aresetn), + .in_count(_m_axis_raddr), + .out_count(_s_axis_raddr) +); + +always @(posedge s_axis_aclk) +begin + if (s_axis_aresetn == 1'b0) begin + s_axis_ready <= 1'b1; + s_axis_empty <= 1'b1; + s_axis_room <= MAX_ROOM; + end else begin + s_axis_ready <= (_s_axis_raddr[ADDRESS_WIDTH] == _s_axis_waddr_next[ADDRESS_WIDTH] || + _s_axis_raddr[ADDRESS_WIDTH-1:0] != _s_axis_waddr_next[ADDRESS_WIDTH-1:0]); + s_axis_empty <= _s_axis_raddr == _s_axis_waddr_next; + s_axis_room <= _s_axis_raddr - _s_axis_waddr_next + MAX_ROOM; + end +end + +always @(posedge m_axis_aclk) +begin + if (m_axis_aresetn == 1'b0) begin + m_axis_valid <= 1'b0; + m_axis_level <= 'h00; + end else begin + m_axis_valid <= _m_axis_waddr != _m_axis_raddr_next; + m_axis_level <= _m_axis_waddr - _m_axis_raddr_next; + end +end + +endmodule + diff --git a/src/adi/hdl/library/util_axis_fifo/address_sync.v b/src/adi/hdl/library/util_axis_fifo/address_sync.v new file mode 100644 index 00000000..c6b074f2 --- /dev/null +++ b/src/adi/hdl/library/util_axis_fifo/address_sync.v @@ -0,0 +1,109 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright 2014 - 2017 (c) Analog Devices, Inc. All rights reserved. +// +// In this HDL repository, there are many different and unique modules, consisting +// of various HDL (Verilog or VHDL) components. The individual modules are +// developed independently, and may be accompanied by separate and unique license +// terms. +// +// The user should read each of these license terms, and understand the +// freedoms and responsibilities that he or she has by using this source/core. +// +// This core 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. +// +// Redistribution and use of source or resulting binaries, with or without modification +// of this file, are permitted under one of the following two license terms: +// +// 1. The GNU General Public License version 2 as published by the +// Free Software Foundation, which can be found in the top level directory +// of this repository (LICENSE_GPL2), and also online at: +// +// +// OR +// +// 2. An ADI specific BSD license, which can be found in the top level directory +// of this repository (LICENSE_ADIBSD), and also on-line at: +// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD +// This will allow to generate bit files and not release the source code, +// as long as it attaches to an ADI device. +// +// *************************************************************************** +// *************************************************************************** + +`timescale 1ns/100ps + +module fifo_address_sync #( + parameter ADDRESS_WIDTH = 4 +) ( + input clk, + input resetn, + + input m_axis_ready, + output reg m_axis_valid, + output reg [ADDRESS_WIDTH-1:0] m_axis_raddr, + output [ADDRESS_WIDTH:0] m_axis_level, + + output reg s_axis_ready, + input s_axis_valid, + output reg s_axis_empty, + output reg [ADDRESS_WIDTH-1:0] s_axis_waddr, + output [ADDRESS_WIDTH:0] s_axis_room +); + +localparam MAX_ROOM = {1'b1,{ADDRESS_WIDTH{1'b0}}}; + +reg [ADDRESS_WIDTH:0] room = MAX_ROOM; +reg [ADDRESS_WIDTH:0] level = 'h00; +reg [ADDRESS_WIDTH:0] level_next; + +assign s_axis_room = room; +assign m_axis_level = level; + +wire read = m_axis_ready & m_axis_valid; +wire write = s_axis_ready & s_axis_valid; + +always @(posedge clk) +begin + if (resetn == 1'b0) begin + s_axis_waddr <= 'h00; + m_axis_raddr <= 'h00; + end else begin + if (write) + s_axis_waddr <= s_axis_waddr + 1'b1; + if (read) + m_axis_raddr <= m_axis_raddr + 1'b1; + end +end + +always @(*) +begin + if (read & ~write) + level_next <= level - 1'b1; + else if (~read & write) + level_next <= level + 1'b1; + else + level_next <= level; +end + +always @(posedge clk) +begin + if (resetn == 1'b0) begin + m_axis_valid <= 1'b0; + s_axis_ready <= 1'b0; + level <= 'h00; + room <= MAX_ROOM; + s_axis_empty <= 'h00; + end else begin + level <= level_next; + room <= MAX_ROOM - level_next; + m_axis_valid <= level_next != 0; + s_axis_ready <= level_next != MAX_ROOM; + s_axis_empty <= level_next == 0; + end +end + +endmodule + diff --git a/src/adi/hdl/library/util_axis_fifo/util_axis_fifo.v b/src/adi/hdl/library/util_axis_fifo/util_axis_fifo.v new file mode 100644 index 00000000..20316207 --- /dev/null +++ b/src/adi/hdl/library/util_axis_fifo/util_axis_fifo.v @@ -0,0 +1,243 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright 2014 - 2017 (c) Analog Devices, Inc. All rights reserved. +// +// In this HDL repository, there are many different and unique modules, consisting +// of various HDL (Verilog or VHDL) components. The individual modules are +// developed independently, and may be accompanied by separate and unique license +// terms. +// +// The user should read each of these license terms, and understand the +// freedoms and responsibilities that he or she has by using this source/core. +// +// This core 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. +// +// Redistribution and use of source or resulting binaries, with or without modification +// of this file, are permitted under one of the following two license terms: +// +// 1. The GNU General Public License version 2 as published by the +// Free Software Foundation, which can be found in the top level directory +// of this repository (LICENSE_GPL2), and also online at: +// +// +// OR +// +// 2. An ADI specific BSD license, which can be found in the top level directory +// of this repository (LICENSE_ADIBSD), and also on-line at: +// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD +// This will allow to generate bit files and not release the source code, +// as long as it attaches to an ADI device. +// +// *************************************************************************** +// *************************************************************************** + +`timescale 1ns/100ps + +module util_axis_fifo #( + parameter DATA_WIDTH = 64, + parameter ASYNC_CLK = 1, + parameter ADDRESS_WIDTH = 4, + parameter S_AXIS_REGISTERED = 1 +) ( + input m_axis_aclk, + input m_axis_aresetn, + input m_axis_ready, + output m_axis_valid, + output [DATA_WIDTH-1:0] m_axis_data, + output [ADDRESS_WIDTH:0] m_axis_level, + + input s_axis_aclk, + input s_axis_aresetn, + output s_axis_ready, + input s_axis_valid, + input [DATA_WIDTH-1:0] s_axis_data, + output s_axis_empty, + output [ADDRESS_WIDTH:0] s_axis_room +); + +generate if (ADDRESS_WIDTH == 0) begin + + reg [DATA_WIDTH-1:0] cdc_sync_fifo_ram; + reg s_axis_waddr = 1'b0; + reg m_axis_raddr = 1'b0; + + wire m_axis_waddr; + wire s_axis_raddr; + + sync_bits #( + .NUM_OF_BITS(1), + .ASYNC_CLK(ASYNC_CLK) + ) i_waddr_sync ( + .out_clk(m_axis_aclk), + .out_resetn(m_axis_aresetn), + .in(s_axis_waddr), + .out(m_axis_waddr) + ); + + sync_bits #( + .NUM_OF_BITS(1), + .ASYNC_CLK(ASYNC_CLK) + ) i_raddr_sync ( + .out_clk(s_axis_aclk), + .out_resetn(s_axis_aresetn), + .in(m_axis_raddr), + .out(s_axis_raddr) + ); + + assign m_axis_valid = m_axis_raddr != m_axis_waddr; + assign m_axis_level = m_axis_valid; + assign s_axis_ready = s_axis_raddr == s_axis_waddr; + assign s_axis_empty = s_axis_ready; + assign s_axis_room = s_axis_ready; + + always @(posedge s_axis_aclk) begin + if (s_axis_ready == 1'b1 && s_axis_valid == 1'b1) + cdc_sync_fifo_ram <= s_axis_data; + end + + always @(posedge s_axis_aclk) begin + if (s_axis_aresetn == 1'b0) begin + s_axis_waddr <= 1'b0; + end else begin + if (s_axis_ready & s_axis_valid) begin + s_axis_waddr <= s_axis_waddr + 1'b1; + end + end + end + + always @(posedge m_axis_aclk) begin + if (m_axis_aresetn == 1'b0) begin + m_axis_raddr <= 1'b0; + end else begin + if (m_axis_valid & m_axis_ready) + m_axis_raddr <= m_axis_raddr + 1'b1; + end + end + + assign m_axis_data = cdc_sync_fifo_ram; + +end else begin + + reg [DATA_WIDTH-1:0] ram[0:2**ADDRESS_WIDTH-1]; + + wire [ADDRESS_WIDTH-1:0] s_axis_waddr; + wire [ADDRESS_WIDTH-1:0] m_axis_raddr; + wire _m_axis_ready; + wire _m_axis_valid; + + wire s_mem_write; + wire m_mem_read; + + reg valid; + + always @(posedge m_axis_aclk) begin + if (m_axis_aresetn == 1'b0) begin + valid <= 1'b0; + end else begin + if (_m_axis_valid) + valid <= 1'b1; + else if (m_axis_ready) + valid <= 1'b0; + end + end + + assign s_mem_write = s_axis_ready & s_axis_valid; + assign m_mem_read = (~valid || m_axis_ready) && _m_axis_valid; + + if (ASYNC_CLK == 1) begin + + // The assumption is that in this mode the S_AXIS_REGISTERED is 1 + + fifo_address_gray_pipelined #( + .ADDRESS_WIDTH(ADDRESS_WIDTH) + ) i_address_gray ( + .m_axis_aclk(m_axis_aclk), + .m_axis_aresetn(m_axis_aresetn), + .m_axis_ready(_m_axis_ready), + .m_axis_valid(_m_axis_valid), + .m_axis_raddr(m_axis_raddr), + .m_axis_level(m_axis_level), + + .s_axis_aclk(s_axis_aclk), + .s_axis_aresetn(s_axis_aresetn), + .s_axis_ready(s_axis_ready), + .s_axis_valid(s_axis_valid), + .s_axis_empty(s_axis_empty), + .s_axis_waddr(s_axis_waddr), + .s_axis_room(s_axis_room) + ); + + // When the clocks are asynchronous instantiate a block RAM + // regardless of the requested size to make sure we threat the + // clock crossing correctly + ad_mem #( + .DATA_WIDTH (DATA_WIDTH), + .ADDRESS_WIDTH (ADDRESS_WIDTH)) + i_mem ( + .clka(s_axis_aclk), + .wea(s_mem_write), + .addra(s_axis_waddr), + .dina(s_axis_data), + .clkb(m_axis_aclk), + .reb(m_mem_read), + .addrb(m_axis_raddr), + .doutb(m_axis_data) + ); + + assign _m_axis_ready = ~valid || m_axis_ready; + assign m_axis_valid = valid; + + end else begin + + fifo_address_sync #( + .ADDRESS_WIDTH(ADDRESS_WIDTH) + ) i_address_sync ( + .clk(m_axis_aclk), + .resetn(m_axis_aresetn), + .m_axis_ready(_m_axis_ready), + .m_axis_valid(_m_axis_valid), + .m_axis_raddr(m_axis_raddr), + .m_axis_level(m_axis_level), + + .s_axis_ready(s_axis_ready), + .s_axis_valid(s_axis_valid), + .s_axis_empty(s_axis_empty), + .s_axis_waddr(s_axis_waddr), + .s_axis_room(s_axis_room) + ); + + // When the clocks are synchronous use behavioral modeling for the SDP RAM + // Let the synthesizer decide what to infer (distributed or block RAM) + always @(posedge s_axis_aclk) begin + if (s_mem_write) + ram[s_axis_waddr] <= s_axis_data; + end + + if (S_AXIS_REGISTERED == 1) begin + + reg [DATA_WIDTH-1:0] data; + + always @(posedge m_axis_aclk) begin + if (m_mem_read) + data <= ram[m_axis_raddr]; + end + + assign _m_axis_ready = ~valid || m_axis_ready; + assign m_axis_data = data; + assign m_axis_valid = valid; + + end else begin + + assign _m_axis_ready = m_axis_ready; + assign m_axis_valid = _m_axis_valid; + assign m_axis_data = ram[m_axis_raddr]; + + end + + end + +end endgenerate + +endmodule diff --git a/src/adi/hdl/library/util_axis_fifo/util_axis_fifo_ip.tcl b/src/adi/hdl/library/util_axis_fifo/util_axis_fifo_ip.tcl new file mode 100644 index 00000000..d0fc1ce4 --- /dev/null +++ b/src/adi/hdl/library/util_axis_fifo/util_axis_fifo_ip.tcl @@ -0,0 +1,41 @@ + +source ../scripts/adi_env.tcl +source $ad_hdl_dir/library/scripts/adi_ip.tcl + +adi_ip_create util_axis_fifo +adi_ip_files util_axis_fifo [list \ + "address_gray.v" \ + "address_gray_pipelined.v" \ + "address_sync.v" \ + "../common/ad_mem.v" \ + "util_axis_fifo.v" \ +] + +adi_ip_properties_lite util_axis_fifo + +adi_ip_add_core_dependencies { \ + analog.com:user:util_cdc:1.0 \ +} + +adi_add_bus "s_axis" "slave" \ + "xilinx.com:interface:axis_rtl:1.0" \ + "xilinx.com:interface:axis:1.0" \ + { + {"s_axis_valid" "TVALID"} \ + {"s_axis_ready" "TREADY"} \ + {"s_axis_data" "TDATA"} \ + } + +adi_add_bus "m_axis" "master" \ + "xilinx.com:interface:axis_rtl:1.0" \ + "xilinx.com:interface:axis:1.0" \ + { + {"m_axis_valid" "TVALID"} \ + {"m_axis_ready" "TREADY"} \ + {"m_axis_data" "TDATA"} \ + } + +adi_add_bus_clock "m_axis_aclk" "m_axis" "m_axis_aresetn" +adi_add_bus_clock "s_axis_aclk" "s_axis" "m_axis_aresetn" + +ipx::save_core [ipx::current_core] diff --git a/src/adi/hdl/library/util_cdc/Makefile b/src/adi/hdl/library/util_cdc/Makefile new file mode 100644 index 00000000..26b09a09 --- /dev/null +++ b/src/adi/hdl/library/util_cdc/Makefile @@ -0,0 +1,15 @@ +#################################################################################### +## Copyright 2018(c) Analog Devices, Inc. +## Auto-generated, do not modify! +#################################################################################### + +LIBRARY_NAME := util_cdc + +GENERIC_DEPS += sync_bits.v +GENERIC_DEPS += sync_data.v +GENERIC_DEPS += sync_event.v +GENERIC_DEPS += sync_gray.v + +XILINX_DEPS += util_cdc_ip.tcl + +include ../scripts/library.mk diff --git a/src/adi/hdl/library/util_cdc/sync_bits.v b/src/adi/hdl/library/util_cdc/sync_bits.v new file mode 100644 index 00000000..0fbcd053 --- /dev/null +++ b/src/adi/hdl/library/util_cdc/sync_bits.v @@ -0,0 +1,79 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright 2014 - 2017 (c) Analog Devices, Inc. All rights reserved. +// +// In this HDL repository, there are many different and unique modules, consisting +// of various HDL (Verilog or VHDL) components. The individual modules are +// developed independently, and may be accompanied by separate and unique license +// terms. +// +// The user should read each of these license terms, and understand the +// freedoms and responsibilities that he or she has by using this source/core. +// +// This core 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. +// +// Redistribution and use of source or resulting binaries, with or without modification +// of this file, are permitted under one of the following two license terms: +// +// 1. The GNU General Public License version 2 as published by the +// Free Software Foundation, which can be found in the top level directory +// of this repository (LICENSE_GPL2), and also online at: +// +// +// OR +// +// 2. An ADI specific BSD license, which can be found in the top level directory +// of this repository (LICENSE_ADIBSD), and also on-line at: +// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD +// This will allow to generate bit files and not release the source code, +// as long as it attaches to an ADI device. +// +// *************************************************************************** +// *************************************************************************** + +/* + * Helper module for synchronizing bit signals from one clock domain to another. + * It uses the standard approach of 2 FF in series. + * Note, that while the module allows to synchronize multiple bits at once it is + * only able to synchronize multi-bit signals where at max one bit changes per + * clock cycle (e.g. a gray counter). + */ + +`timescale 1ns/100ps + +module sync_bits #( + + // Number of bits to synchronize + parameter NUM_OF_BITS = 1, + // Whether input and output clocks are asynchronous, if 0 the synchronizer will + // be bypassed and the output signal equals the input signal. + parameter ASYNC_CLK = 1)( + + input [NUM_OF_BITS-1:0] in, + input out_resetn, + input out_clk, + output [NUM_OF_BITS-1:0] out); + +generate if (ASYNC_CLK == 1) begin + reg [NUM_OF_BITS-1:0] cdc_sync_stage1 = 'h0; + reg [NUM_OF_BITS-1:0] cdc_sync_stage2 = 'h0; + + always @(posedge out_clk) + begin + if (out_resetn == 1'b0) begin + cdc_sync_stage1 <= 'b0; + cdc_sync_stage2 <= 'b0; + end else begin + cdc_sync_stage1 <= in; + cdc_sync_stage2 <= cdc_sync_stage1; + end + end + + assign out = cdc_sync_stage2; +end else begin + assign out = in; +end endgenerate + +endmodule diff --git a/src/adi/hdl/library/util_cdc/sync_data.v b/src/adi/hdl/library/util_cdc/sync_data.v new file mode 100644 index 00000000..ea5fd7e5 --- /dev/null +++ b/src/adi/hdl/library/util_cdc/sync_data.v @@ -0,0 +1,97 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright 2014 - 2017 (c) Analog Devices, Inc. All rights reserved. +// +// In this HDL repository, there are many different and unique modules, consisting +// of various HDL (Verilog or VHDL) components. The individual modules are +// developed independently, and may be accompanied by separate and unique license +// terms. +// +// The user should read each of these license terms, and understand the +// freedoms and responsibilities that he or she has by using this source/core. +// +// This core 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. +// +// Redistribution and use of source or resulting binaries, with or without modification +// of this file, are permitted under one of the following two license terms: +// +// 1. The GNU General Public License version 2 as published by the +// Free Software Foundation, which can be found in the top level directory +// of this repository (LICENSE_GPL2), and also online at: +// +// +// OR +// +// 2. An ADI specific BSD license, which can be found in the top level directory +// of this repository (LICENSE_ADIBSD), and also on-line at: +// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD +// This will allow to generate bit files and not release the source code, +// as long as it attaches to an ADI device. +// +// *************************************************************************** +// *************************************************************************** + +`timescale 1ns/100ps + +module sync_data #( + parameter NUM_OF_BITS = 1, + parameter ASYNC_CLK = 1 +) ( + input in_clk, + input [NUM_OF_BITS-1:0] in_data, + input out_clk, + output reg [NUM_OF_BITS-1:0] out_data +); + +generate +if (ASYNC_CLK == 1) begin + +wire out_toggle; +wire in_toggle; + +reg out_toggle_d1 = 1'b0; +reg in_toggle_d1 = 1'b0; + +reg [NUM_OF_BITS-1:0] cdc_hold; + +sync_bits i_sync_out ( + .in(in_toggle_d1), + .out_clk(out_clk), + .out_resetn(1'b1), + .out(out_toggle) +); + +sync_bits i_sync_in ( + .in(out_toggle_d1), + .out_clk(in_clk), + .out_resetn(1'b1), + .out(in_toggle) +); + +wire in_load = in_toggle == in_toggle_d1; +wire out_load = out_toggle ^ out_toggle_d1; + +always @(posedge in_clk) begin + if (in_load == 1'b1) begin + cdc_hold <= in_data; + in_toggle_d1 <= ~in_toggle_d1; + end +end + +always @(posedge out_clk) begin + if (out_load == 1'b1) begin + out_data <= cdc_hold; + end + out_toggle_d1 <= out_toggle; +end + +end else begin + always @(*) begin + out_data <= in_data; + end +end +endgenerate + +endmodule diff --git a/src/adi/hdl/library/util_cdc/sync_event.v b/src/adi/hdl/library/util_cdc/sync_event.v new file mode 100644 index 00000000..4c72e8b4 --- /dev/null +++ b/src/adi/hdl/library/util_cdc/sync_event.v @@ -0,0 +1,120 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright 2014 - 2017 (c) Analog Devices, Inc. All rights reserved. +// +// In this HDL repository, there are many different and unique modules, consisting +// of various HDL (Verilog or VHDL) components. The individual modules are +// developed independently, and may be accompanied by separate and unique license +// terms. +// +// The user should read each of these license terms, and understand the +// freedoms and responsibilities that he or she has by using this source/core. +// +// This core 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. +// +// Redistribution and use of source or resulting binaries, with or without modification +// of this file, are permitted under one of the following two license terms: +// +// 1. The GNU General Public License version 2 as published by the +// Free Software Foundation, which can be found in the top level directory +// of this repository (LICENSE_GPL2), and also online at: +// +// +// OR +// +// 2. An ADI specific BSD license, which can be found in the top level directory +// of this repository (LICENSE_ADIBSD), and also on-line at: +// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD +// This will allow to generate bit files and not release the source code, +// as long as it attaches to an ADI device. +// +// *************************************************************************** +// *************************************************************************** + +`timescale 1ns/100ps + +module sync_event #( + parameter NUM_OF_EVENTS = 1, + parameter ASYNC_CLK = 1 +) ( + input in_clk, + input [NUM_OF_EVENTS-1:0] in_event, + input out_clk, + output reg [NUM_OF_EVENTS-1:0] out_event +); + +generate +if (ASYNC_CLK == 1) begin + +wire out_toggle; +wire in_toggle; + +reg out_toggle_d1 = 1'b0; +reg in_toggle_d1 = 1'b0; + +sync_bits i_sync_out ( + .in(in_toggle_d1), + .out_clk(out_clk), + .out_resetn(1'b1), + .out(out_toggle) +); + +sync_bits i_sync_in ( + .in(out_toggle_d1), + .out_clk(in_clk), + .out_resetn(1'b1), + .out(in_toggle) +); + +wire in_ready = in_toggle == in_toggle_d1; +wire load_out = out_toggle ^ out_toggle_d1; + +reg [NUM_OF_EVENTS-1:0] in_event_sticky = 'h00; +wire [NUM_OF_EVENTS-1:0] pending_events = in_event_sticky | in_event; +wire [NUM_OF_EVENTS-1:0] out_event_s; + +always @(posedge in_clk) begin + if (in_ready == 1'b1) begin + in_event_sticky <= {NUM_OF_EVENTS{1'b0}}; + if (|pending_events == 1'b1) begin + in_toggle_d1 <= ~in_toggle_d1; + end + end else begin + in_event_sticky <= pending_events; + end +end + +if (NUM_OF_EVENTS > 1) begin + reg [NUM_OF_EVENTS-1:0] cdc_hold = 'h00; + + always @(posedge in_clk) begin + if (in_ready == 1'b1) begin + cdc_hold <= pending_events; + end + end + + assign out_event_s = cdc_hold; +end else begin + // When there is only one event, we know that it is set. + assign out_event_s = 1'b1; +end + +always @(posedge out_clk) begin + if (load_out == 1'b1) begin + out_event <= out_event_s; + end else begin + out_event <= {NUM_OF_EVENTS{1'b0}}; + end + out_toggle_d1 <= out_toggle; +end + +end else begin + always @(*) begin + out_event <= in_event; + end +end +endgenerate + +endmodule diff --git a/src/adi/hdl/library/util_cdc/sync_gray.v b/src/adi/hdl/library/util_cdc/sync_gray.v new file mode 100644 index 00000000..9382d9dd --- /dev/null +++ b/src/adi/hdl/library/util_cdc/sync_gray.v @@ -0,0 +1,115 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright 2014 - 2017 (c) Analog Devices, Inc. All rights reserved. +// +// In this HDL repository, there are many different and unique modules, consisting +// of various HDL (Verilog or VHDL) components. The individual modules are +// developed independently, and may be accompanied by separate and unique license +// terms. +// +// The user should read each of these license terms, and understand the +// freedoms and responsibilities that he or she has by using this source/core. +// +// This core 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. +// +// Redistribution and use of source or resulting binaries, with or without modification +// of this file, are permitted under one of the following two license terms: +// +// 1. The GNU General Public License version 2 as published by the +// Free Software Foundation, which can be found in the top level directory +// of this repository (LICENSE_GPL2), and also online at: +// +// +// OR +// +// 2. An ADI specific BSD license, which can be found in the top level directory +// of this repository (LICENSE_ADIBSD), and also on-line at: +// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD +// This will allow to generate bit files and not release the source code, +// as long as it attaches to an ADI device. +// +// *************************************************************************** +// *************************************************************************** + +/* + * Helper module for synchronizing a counter from one clock domain to another + * using gray code. To work correctly the counter must not change its value by + * more than one in one clock cycle in the source domain. I.e. the value may + * change by either -1, 0 or +1. + */ + +`timescale 1ns/100ps + +module sync_gray #( + + // Bit-width of the counter + parameter DATA_WIDTH = 1, + // Whether the input and output clock are asynchronous, if set to 0 the + // synchronizer will be bypassed and out_count will be in_count. + parameter ASYNC_CLK = 1)( + + input in_clk, + input in_resetn, + input [DATA_WIDTH-1:0] in_count, + input out_resetn, + input out_clk, + output [DATA_WIDTH-1:0] out_count); + +generate if (ASYNC_CLK == 1) begin + reg [DATA_WIDTH-1:0] cdc_sync_stage0 = 'h0; + reg [DATA_WIDTH-1:0] cdc_sync_stage1 = 'h0; + reg [DATA_WIDTH-1:0] cdc_sync_stage2 = 'h0; + reg [DATA_WIDTH-1:0] out_count_m = 'h0; + + function [DATA_WIDTH-1:0] g2b; + input [DATA_WIDTH-1:0] g; + reg [DATA_WIDTH-1:0] b; + integer i; + begin + b[DATA_WIDTH-1] = g[DATA_WIDTH-1]; + for (i = DATA_WIDTH - 2; i >= 0; i = i - 1) + b[i] = b[i + 1] ^ g[i]; + g2b = b; + end + endfunction + + function [DATA_WIDTH-1:0] b2g; + input [DATA_WIDTH-1:0] b; + reg [DATA_WIDTH-1:0] g; + integer i; + begin + g[DATA_WIDTH-1] = b[DATA_WIDTH-1]; + for (i = DATA_WIDTH - 2; i >= 0; i = i -1) + g[i] = b[i + 1] ^ b[i]; + b2g = g; + end + endfunction + + always @(posedge in_clk) begin + if (in_resetn == 1'b0) begin + cdc_sync_stage0 <= 'h00; + end else begin + cdc_sync_stage0 <= b2g(in_count); + end + end + + always @(posedge out_clk) begin + if (out_resetn == 1'b0) begin + cdc_sync_stage1 <= 'h00; + cdc_sync_stage2 <= 'h00; + out_count_m <= 'h00; + end else begin + cdc_sync_stage1 <= cdc_sync_stage0; + cdc_sync_stage2 <= cdc_sync_stage1; + out_count_m <= g2b(cdc_sync_stage2); + end + end + + assign out_count = out_count_m; +end else begin + assign out_count = in_count; +end endgenerate + +endmodule diff --git a/src/adi/hdl/library/util_cdc/util_cdc_constr.tcl b/src/adi/hdl/library/util_cdc/util_cdc_constr.tcl new file mode 100644 index 00000000..320b114c --- /dev/null +++ b/src/adi/hdl/library/util_cdc/util_cdc_constr.tcl @@ -0,0 +1,58 @@ +# *************************************************************************** +# *************************************************************************** +# Copyright 2014 - 2017 (c) Analog Devices, Inc. All rights reserved. +# +# Each core or library found in this collection may have its own licensing terms. +# The user should keep this in in mind while exploring these cores. +# +# Redistribution and use in source and binary forms, +# with or without modification of this file, are permitted under the terms of either +# (at the option of the user): +# +# 1. The GNU General Public License version 2 as published by the +# Free Software Foundation, which can be found in the top level directory, or at: +# https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html +# +# OR +# +# 2. An ADI specific BSD license as noted in the top level directory, or on-line at: +# https://github.com/analogdevicesinc/hdl/blob/dev/LICENSE +# +# *************************************************************************** +# *************************************************************************** + +proc util_cdc_sync_bits_constr {inst {from {}}} { + if {$from != {}} { + set_false_path \ + -from [get_registers $from] \ + -to [get_registers [format "%s%s" ${inst} {|cdc_sync_stage1[0]}]] + } else { + set_false_path \ + -to [get_registers [format "%s%s" ${inst} {|cdc_sync_stage1[0]}]] + } +} + +proc util_cdc_sync_data_constr {inst} { + util_cdc_sync_bits_constr ${inst}|sync_bits:i_sync_out ${inst}|in_toggle_d1 + util_cdc_sync_bits_constr ${inst}|sync_bits:i_sync_in ${inst}|out_toggle_d1 + + # set_max_skew + set_false_path \ + -from [get_registers [format "%s%s" ${inst} {|cdc_hold[*]}]] \ + -to [get_registers [format "%s%s" ${inst} {|out_data[*]}]] +} + +proc util_cdc_sync_event_constr {inst} { + util_cdc_sync_bits_constr ${inst}|sync_bits:i_sync_out ${inst}|in_toggle_d1 + util_cdc_sync_bits_constr ${inst}|sync_bits:i_sync_in ${inst}|out_toggle_d1 + + set cdc_hold_reg [get_registers -nowarn [format "%s%s" ${inst} {|cdc_hold[*]}]] + + # For a event synchronizer with one event there is no hold register + if {[get_collection_size ${cdc_hold_reg}] != 0} { + # set_max_skew + set_false_path \ + -from ${cdc_hold_reg} \ + -to [get_registers [format "%s%s" ${inst} {|out_event[*]}]] + } +} diff --git a/src/adi/hdl/library/util_cdc/util_cdc_ip.tcl b/src/adi/hdl/library/util_cdc/util_cdc_ip.tcl new file mode 100644 index 00000000..a1bce94b --- /dev/null +++ b/src/adi/hdl/library/util_cdc/util_cdc_ip.tcl @@ -0,0 +1,43 @@ +# *************************************************************************** +# *************************************************************************** +# Copyright 2014 - 2017 (c) Analog Devices, Inc. All rights reserved. +# +# Each core or library found in this collection may have its own licensing terms. +# The user should keep this in in mind while exploring these cores. +# +# Redistribution and use in source and binary forms, +# with or without modification of this file, are permitted under the terms of either +# (at the option of the user): +# +# 1. The GNU General Public License version 2 as published by the +# Free Software Foundation, which can be found in the top level directory, or at: +# https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html +# +# OR +# +# 2. An ADI specific BSD license as noted in the top level directory, or on-line at: +# https://github.com/analogdevicesinc/hdl/blob/dev/LICENSE +# +# *************************************************************************** +# *************************************************************************** + +source ../scripts/adi_env.tcl +source $ad_hdl_dir/library/scripts/adi_ip.tcl + +adi_ip_create util_cdc + +add_files -fileset [get_filesets sources_1] [list \ + "sync_gray.v" \ + "sync_bits.v" \ + "sync_data.v" \ + "sync_event.v" \ +] + +adi_ip_properties_lite util_cdc + +set_property name "util_cdc" [ipx::current_core] +set_property display_name "ADI Clock-Domain-Crossing Utils" [ipx::current_core] +set_property description "ADI Clock-Domain-Crossing Utils" [ipx::current_core] +set_property hide_in_gui {1} [ipx::current_core] + +ipx::save_core [ipx::current_core] diff --git a/src/adi/hdl/library/xilinx/common/ad_data_clk.v b/src/adi/hdl/library/xilinx/common/ad_data_clk.v new file mode 100644 index 00000000..42027091 --- /dev/null +++ b/src/adi/hdl/library/xilinx/common/ad_data_clk.v @@ -0,0 +1,84 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright 2014 - 2017 (c) Analog Devices, Inc. All rights reserved. +// +// In this HDL repository, there are many different and unique modules, consisting +// of various HDL (Verilog or VHDL) components. The individual modules are +// developed independently, and may be accompanied by separate and unique license +// terms. +// +// The user should read each of these license terms, and understand the +// freedoms and responsibilities that he or she has by using this source/core. +// +// This core 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. +// +// Redistribution and use of source or resulting binaries, with or without modification +// of this file, are permitted under one of the following two license terms: +// +// 1. The GNU General Public License version 2 as published by the +// Free Software Foundation, which can be found in the top level directory +// of this repository (LICENSE_GPL2), and also online at: +// +// +// OR +// +// 2. An ADI specific BSD license, which can be found in the top level directory +// of this repository (LICENSE_ADIBSD), and also on-line at: +// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD +// This will allow to generate bit files and not release the source code, +// as long as it attaches to an ADI device. +// +// *************************************************************************** +// *************************************************************************** + +`timescale 1ns/100ps + +module ad_data_clk #( + + parameter SINGLE_ENDED = 0, + parameter DEVICE_TYPE = 0) ( + + input rst, + output locked, + + input clk_in_p, + input clk_in_n, + output clk); + + localparam VIRTEX7 = 0; + localparam ULTRASCALE_PLUS = 2; + localparam ULTRASCALE = 3; + + // internal signals + + wire clk_ibuf_s; + + // defaults + + assign locked = 1'b1; + + // instantiations + + generate + if (SINGLE_ENDED == 1) begin + IBUFG i_rx_clk_ibuf ( + .I (clk_in_p), + .O (clk_ibuf_s)); + end else begin + IBUFGDS i_rx_clk_ibuf ( + .I (clk_in_p), + .IB (clk_in_n), + .O (clk_ibuf_s)); + end + endgenerate + + BUFG i_clk_gbuf ( + .I (clk_ibuf_s), + .O (clk)); + +endmodule + +// *************************************************************************** +// *************************************************************************** diff --git a/src/adi/hdl/library/xilinx/common/ad_data_in.v b/src/adi/hdl/library/xilinx/common/ad_data_in.v new file mode 100644 index 00000000..a07af266 --- /dev/null +++ b/src/adi/hdl/library/xilinx/common/ad_data_in.v @@ -0,0 +1,214 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright 2014 - 2017 (c) Analog Devices, Inc. All rights reserved. +// +// In this HDL repository, there are many different and unique modules, consisting +// of various HDL (Verilog or VHDL) components. The individual modules are +// developed independently, and may be accompanied by separate and unique license +// terms. +// +// The user should read each of these license terms, and understand the +// freedoms and responsibilities that he or she has by using this source/core. +// +// This core 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. +// +// Redistribution and use of source or resulting binaries, with or without modification +// of this file, are permitted under one of the following two license terms: +// +// 1. The GNU General Public License version 2 as published by the +// Free Software Foundation, which can be found in the top level directory +// of this repository (LICENSE_GPL2), and also online at: +// +// +// OR +// +// 2. An ADI specific BSD license, which can be found in the top level directory +// of this repository (LICENSE_ADIBSD), and also on-line at: +// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD +// This will allow to generate bit files and not release the source code, +// as long as it attaches to an ADI device. +// +// *************************************************************************** +// *************************************************************************** + +`timescale 1ns/100ps + +module ad_data_in #( + + // parameters + + parameter SINGLE_ENDED = 0, + parameter DEVICE_TYPE = 0, + parameter IODELAY_ENABLE = 1, + parameter IODELAY_CTRL = 0, + parameter IODELAY_GROUP = "dev_if_delay_group") ( + + // data interface + + input rx_clk, + input rx_data_in_p, + input rx_data_in_n, + output rx_data_p, + output rx_data_n, + + // delay-data interface + + input up_clk, + input up_dld, + input [ 4:0] up_dwdata, + output [ 4:0] up_drdata, + + // delay-cntrl interface + + input delay_clk, + input delay_rst, + output delay_locked); + + // internal parameters + + localparam NONE = -1; + localparam VIRTEX7 = 0; + localparam ULTRASCALE_PLUS = 2; + localparam ULTRASCALE = 3; + + localparam IODELAY_CTRL_ENABLED = (IODELAY_ENABLE == 1) ? IODELAY_CTRL : 0; + localparam IODELAY_CTRL_SIM_DEVICE = (DEVICE_TYPE == ULTRASCALE_PLUS) ? "ULTRASCALE" : + (DEVICE_TYPE == ULTRASCALE) ? "ULTRASCALE" : "7SERIES"; + + localparam IODELAY_DEVICE_TYPE = (IODELAY_ENABLE == 1) ? DEVICE_TYPE : NONE; + localparam IODELAY_SIM_DEVICE = (DEVICE_TYPE == ULTRASCALE_PLUS) ? "ULTRASCALE_PLUS" : + (DEVICE_TYPE == ULTRASCALE) ? "ULTRASCALE" : "7SERIES"; + + // internal signals + + wire rx_data_ibuf_s; + wire rx_data_idelay_s; + wire [ 8:0] up_drdata_s; + + // delay controller + + generate + if (IODELAY_CTRL_ENABLED == 0) begin + assign delay_locked = 1'b1; + end else begin + (* IODELAY_GROUP = IODELAY_GROUP *) + IDELAYCTRL #(.SIM_DEVICE (IODELAY_CTRL_SIM_DEVICE)) i_delay_ctrl ( + .RST (delay_rst), + .REFCLK (delay_clk), + .RDY (delay_locked)); + end + endgenerate + + // receive data interface, ibuf -> idelay -> iddr + + generate + if (SINGLE_ENDED == 1) begin + IBUF i_rx_data_ibuf ( + .I (rx_data_in_p), + .O (rx_data_ibuf_s)); + end else begin + IBUFDS i_rx_data_ibuf ( + .I (rx_data_in_p), + .IB (rx_data_in_n), + .O (rx_data_ibuf_s)); + end + endgenerate + + // idelay + + generate + if (IODELAY_DEVICE_TYPE == VIRTEX7) begin + (* IODELAY_GROUP = IODELAY_GROUP *) + IDELAYE2 #( + .CINVCTRL_SEL ("FALSE"), + .DELAY_SRC ("IDATAIN"), + .HIGH_PERFORMANCE_MODE ("FALSE"), + .IDELAY_TYPE ("VAR_LOAD"), + .IDELAY_VALUE (0), + .REFCLK_FREQUENCY (200.0), + .PIPE_SEL ("FALSE"), + .SIGNAL_PATTERN ("DATA")) + i_rx_data_idelay ( + .CE (1'b0), + .INC (1'b0), + .DATAIN (1'b0), + .LDPIPEEN (1'b0), + .CINVCTRL (1'b0), + .REGRST (1'b0), + .C (up_clk), + .IDATAIN (rx_data_ibuf_s), + .DATAOUT (rx_data_idelay_s), + .LD (up_dld), + .CNTVALUEIN (up_dwdata), + .CNTVALUEOUT (up_drdata)); + end + endgenerate + + generate + if ((IODELAY_DEVICE_TYPE == ULTRASCALE) || (IODELAY_DEVICE_TYPE == ULTRASCALE_PLUS)) begin + assign up_drdata = up_drdata_s[8:4]; + (* IODELAY_GROUP = IODELAY_GROUP *) + IDELAYE3 #( + .SIM_DEVICE (IODELAY_SIM_DEVICE), + .DELAY_SRC ("IDATAIN"), + .DELAY_TYPE ("VAR_LOAD"), + .REFCLK_FREQUENCY (200.0), + .DELAY_FORMAT ("COUNT")) + i_rx_data_idelay ( + .CASC_RETURN (1'b0), + .CASC_IN (1'b0), + .CASC_OUT (), + .CE (1'b0), + .CLK (up_clk), + .INC (1'b0), + .LOAD (up_dld), + .CNTVALUEIN ({up_dwdata, 4'd0}), + .CNTVALUEOUT (up_drdata_s), + .DATAIN (1'b0), + .IDATAIN (rx_data_ibuf_s), + .DATAOUT (rx_data_idelay_s), + .RST (1'b0), + .EN_VTC (~up_dld)); + end + endgenerate + + generate + if (IODELAY_DEVICE_TYPE == NONE) begin + assign rx_data_idelay_s = rx_data_ibuf_s; + assign up_drdata = 5'd0; + end + endgenerate + + // iddr + + generate + if ((DEVICE_TYPE == ULTRASCALE) || (DEVICE_TYPE == ULTRASCALE_PLUS)) begin + IDDRE1 #(.DDR_CLK_EDGE ("SAME_EDGE")) i_rx_data_iddr ( + .R (1'b0), + .C (rx_clk), + .CB (~rx_clk), + .D (rx_data_idelay_s), + .Q1 (rx_data_p), + .Q2 (rx_data_n)); + end + endgenerate + + generate + if (DEVICE_TYPE == VIRTEX7) begin + IDDR #(.DDR_CLK_EDGE ("SAME_EDGE")) i_rx_data_iddr ( + .CE (1'b1), + .R (1'b0), + .S (1'b0), + .C (rx_clk), + .D (rx_data_idelay_s), + .Q1 (rx_data_p), + .Q2 (rx_data_n)); + end + endgenerate + +endmodule + +// *************************************************************************** +// *************************************************************************** diff --git a/src/adi/hdl/library/xilinx/common/ad_data_out.v b/src/adi/hdl/library/xilinx/common/ad_data_out.v new file mode 100644 index 00000000..e292cabd --- /dev/null +++ b/src/adi/hdl/library/xilinx/common/ad_data_out.v @@ -0,0 +1,181 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright 2014 - 2017 (c) Analog Devices, Inc. All rights reserved. +// +// In this HDL repository, there are many different and unique modules, consisting +// of various HDL (Verilog or VHDL) components. The individual modules are +// developed independently, and may be accompanied by separate and unique license +// terms. +// +// The user should read each of these license terms, and understand the +// freedoms and responsibilities that he or she has by using this source/core. +// +// This core 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. +// +// Redistribution and use of source or resulting binaries, with or without modification +// of this file, are permitted under one of the following two license terms: +// +// 1. The GNU General Public License version 2 as published by the +// Free Software Foundation, which can be found in the top level directory +// of this repository (LICENSE_GPL2), and also online at: +// +// +// OR +// +// 2. An ADI specific BSD license, which can be found in the top level directory +// of this repository (LICENSE_ADIBSD), and also on-line at: +// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD +// This will allow to generate bit files and not release the source code, +// as long as it attaches to an ADI device. +// +// *************************************************************************** +// *************************************************************************** + +`timescale 1ns/100ps + +module ad_data_out #( + + parameter DEVICE_TYPE = 0, + parameter SINGLE_ENDED = 0, + parameter IODELAY_ENABLE = 0, + parameter IODELAY_CTRL = 0, + parameter IODELAY_GROUP = "dev_if_delay_group") ( + + // data interface + + input tx_clk, + input tx_data_p, + input tx_data_n, + output tx_data_out_p, + output tx_data_out_n, + + // delay-data interface + + input up_clk, + input up_dld, + input [ 4:0] up_dwdata, + output [ 4:0] up_drdata, + + // delay-cntrl interface + + input delay_clk, + input delay_rst, + output delay_locked); + + localparam NONE = -1; + localparam VIRTEX7 = 0; + localparam ULTRASCALE_PLUS = 2; + localparam ULTRASCALE = 3; + + localparam IODELAY_CTRL_ENABLED = (IODELAY_ENABLE == 1) ? IODELAY_CTRL : 0; + localparam IODELAY_CTRL_SIM_DEVICE = (DEVICE_TYPE == ULTRASCALE_PLUS) ? "ULTRASCALE" : + (DEVICE_TYPE == ULTRASCALE) ? "ULTRASCALE" : "7SERIES"; + + localparam IODELAY_DEVICE_TYPE = (IODELAY_ENABLE == 1) ? DEVICE_TYPE : NONE; + localparam IODELAY_SIM_DEVICE = (DEVICE_TYPE == ULTRASCALE_PLUS) ? "ULTRASCALE_PLUS_ES1" : + (DEVICE_TYPE == ULTRASCALE) ? "ULTRASCALE" : "7SERIES"; + + // internal signals + + wire tx_data_oddr_s; + wire tx_data_odelay_s; + + // delay controller + + generate + if (IODELAY_CTRL_ENABLED == 0) begin + assign delay_locked = 1'b1; + end else begin + (* IODELAY_GROUP = IODELAY_GROUP *) + IDELAYCTRL #(.SIM_DEVICE (IODELAY_CTRL_SIM_DEVICE)) i_delay_ctrl ( + .RST (delay_rst), + .REFCLK (delay_clk), + .RDY (delay_locked)); + end + endgenerate + + // transmit data interface, oddr -> odelay -> obuf + + generate + if ((DEVICE_TYPE == ULTRASCALE) || (DEVICE_TYPE == ULTRASCALE_PLUS)) begin + ODDRE1 i_tx_data_oddr ( + .SR (1'b0), + .C (tx_clk), + .D1 (tx_data_n), + .D2 (tx_data_p), + .Q (tx_data_oddr_s)); + end + endgenerate + + generate + if (DEVICE_TYPE == VIRTEX7) begin + ODDR #(.DDR_CLK_EDGE ("SAME_EDGE")) i_tx_data_oddr ( + .CE (1'b1), + .R (1'b0), + .S (1'b0), + .C (tx_clk), + .D1 (tx_data_n), + .D2 (tx_data_p), + .Q (tx_data_oddr_s)); + end + endgenerate + + // odelay + + generate + if (IODELAY_DEVICE_TYPE == VIRTEX7) begin + (* IODELAY_GROUP = IODELAY_GROUP *) + ODELAYE2 #( + .CINVCTRL_SEL ("FALSE"), + .DELAY_SRC ("ODATAIN"), + .HIGH_PERFORMANCE_MODE ("FALSE"), + .ODELAY_TYPE ("VAR_LOAD"), + .ODELAY_VALUE (0), + .REFCLK_FREQUENCY (200.0), + .PIPE_SEL ("FALSE"), + .SIGNAL_PATTERN ("DATA")) + i_tx_data_odelay ( + .CE (1'b0), + .CLKIN (1'b0), + .INC (1'b0), + .LDPIPEEN (1'b0), + .CINVCTRL (1'b0), + .REGRST (1'b0), + .C (up_clk), + .ODATAIN (tx_data_oddr_s), + .DATAOUT (tx_data_odelay_s), + .LD (up_dld), + .CNTVALUEIN (up_dwdata), + .CNTVALUEOUT (up_drdata)); + end + endgenerate + + generate + if (IODELAY_DEVICE_TYPE == NONE) begin + assign up_drdata = 5'd0; + assign tx_data_odelay_s = tx_data_oddr_s; + end + endgenerate + + // obuf + + generate + if (SINGLE_ENDED == 1) begin + assign tx_data_out_n = 1'b0; + OBUF i_tx_data_obuf ( + .I (tx_data_odelay_s), + .O (tx_data_out_p)); + end else begin + OBUFDS i_tx_data_obuf ( + .I (tx_data_odelay_s), + .O (tx_data_out_p), + .OB (tx_data_out_n)); + end + endgenerate + +endmodule + +// *************************************************************************** +// *************************************************************************** diff --git a/src/adi/hdl/library/xilinx/common/ad_dcfilter.v b/src/adi/hdl/library/xilinx/common/ad_dcfilter.v new file mode 100644 index 00000000..47a2db00 --- /dev/null +++ b/src/adi/hdl/library/xilinx/common/ad_dcfilter.v @@ -0,0 +1,197 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright 2014 - 2017 (c) Analog Devices, Inc. All rights reserved. +// +// In this HDL repository, there are many different and unique modules, consisting +// of various HDL (Verilog or VHDL) components. The individual modules are +// developed independently, and may be accompanied by separate and unique license +// terms. +// +// The user should read each of these license terms, and understand the +// freedoms and responsibilities that he or she has by using this source/core. +// +// This core 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. +// +// Redistribution and use of source or resulting binaries, with or without modification +// of this file, are permitted under one of the following two license terms: +// +// 1. The GNU General Public License version 2 as published by the +// Free Software Foundation, which can be found in the top level directory +// of this repository (LICENSE_GPL2), and also online at: +// +// +// OR +// +// 2. An ADI specific BSD license, which can be found in the top level directory +// of this repository (LICENSE_ADIBSD), and also on-line at: +// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD +// This will allow to generate bit files and not release the source code, +// as long as it attaches to an ADI device. +// +// *************************************************************************** +// *************************************************************************** +// dc filter- y(n) = c*x(n) + (1-c)*y(n-1) + +`timescale 1ps/1ps + +module ad_dcfilter #( + + // data path disable + + parameter DISABLE = 0) ( + + // data interface + + input clk, + input valid, + input [15:0] data, + output valid_out, + output [15:0] data_out, + + // control interface + + input dcfilt_enb, + input [15:0] dcfilt_coeff, + input [15:0] dcfilt_offset); + + // internal registers + + reg [15:0] dcfilt_coeff_d = 'd0; + reg [47:0] dc_offset = 'd0; + reg [47:0] dc_offset_d = 'd0; + reg valid_d = 'd0; + reg [15:0] data_d = 'd0; + reg valid_2d = 'd0; + reg [15:0] data_2d = 'd0; + reg [15:0] data_dcfilt = 'd0; + reg valid_int = 'd0; + reg [15:0] data_int = 'd0; + + // internal signals + + wire [47:0] dc_offset_s; + + // data-path disable + + generate + if (DISABLE == 1) begin + assign valid_out = valid; + assign data_out = data; + end else begin + assign valid_out = valid_int; + assign data_out = data_int; + end + endgenerate + + // dcfilt_coeff is flopped so to remove warnings from vivado + + always @(posedge clk) begin + dcfilt_coeff_d <= dcfilt_coeff; + end + + // removing dc offset + + always @(posedge clk) begin + dc_offset <= dc_offset_s; + dc_offset_d <= dc_offset; + valid_d <= valid; + if (valid == 1'b1) begin + data_d <= data + dcfilt_offset; + end + valid_2d <= valid_d; + data_2d <= data_d; + data_dcfilt <= data_d - dc_offset[32:17]; + if (dcfilt_enb == 1'b1) begin + valid_int <= valid_2d; + data_int <= data_dcfilt; + end else begin + valid_int <= valid_2d; + data_int <= data_2d; + end + end + + // dsp slice instance ((D-A)*B)+C + + DSP48E1 #( + .ACASCREG (1), + .ADREG (1), + .ALUMODEREG (0), + .AREG (1), + .AUTORESET_PATDET ("NO_RESET"), + .A_INPUT ("DIRECT"), + .BCASCREG (1), + .BREG (1), + .B_INPUT ("DIRECT"), + .CARRYINREG (0), + .CARRYINSELREG (0), + .CREG (1), + .DREG (0), + .INMODEREG (0), + .MASK (48'h3fffffffffff), + .MREG (1), + .OPMODEREG (0), + .PATTERN (48'h000000000000), + .PREG (1), + .SEL_MASK ("MASK"), + .SEL_PATTERN ("PATTERN"), + .USE_DPORT ("TRUE"), + .USE_MULT ("MULTIPLY"), + .USE_PATTERN_DETECT ("NO_PATDET"), + .USE_SIMD ("ONE48")) + i_dsp48e1 ( + .CLK (clk), + .A ({{14{dc_offset_s[32]}}, dc_offset_s[32:17]}), + .B ({{2{dcfilt_coeff_d[15]}}, dcfilt_coeff_d}), + .C (dc_offset_d), + .D ({{9{data_d[15]}}, data_d}), + .MULTSIGNIN (1'd0), + .CARRYIN (1'd0), + .CARRYCASCIN (1'd0), + .ACIN (30'd0), + .BCIN (18'd0), + .PCIN (48'd0), + .P (dc_offset_s), + .MULTSIGNOUT (), + .CARRYOUT (), + .CARRYCASCOUT (), + .ACOUT (), + .BCOUT (), + .PCOUT (), + .ALUMODE (4'd0), + .CARRYINSEL (3'd0), + .INMODE (5'b01100), + .OPMODE (7'b0110101), + .PATTERNBDETECT (), + .PATTERNDETECT (), + .OVERFLOW (), + .UNDERFLOW (), + .CEA1 (1'd0), + .CEA2 (1'd1), + .CEAD (1'd1), + .CEALUMODE (1'd0), + .CEB1 (1'd0), + .CEB2 (1'd1), + .CEC (1'd1), + .CECARRYIN (1'd0), + .CECTRL (1'd0), + .CED (1'd1), + .CEINMODE (1'd0), + .CEM (1'd1), + .CEP (1'd0), + .RSTA (1'd0), + .RSTALLCARRYIN (1'd0), + .RSTALUMODE (1'd0), + .RSTB (1'd0), + .RSTC (1'd0), + .RSTCTRL (1'd0), + .RSTD (1'd0), + .RSTINMODE (1'd0), + .RSTM (1'd0), + .RSTP (1'd0)); + +endmodule + +// *************************************************************************** +// *************************************************************************** diff --git a/src/adi/hdl/library/xilinx/common/ad_iobuf.v b/src/adi/hdl/library/xilinx/common/ad_iobuf.v new file mode 100644 index 00000000..7711fa1b --- /dev/null +++ b/src/adi/hdl/library/xilinx/common/ad_iobuf.v @@ -0,0 +1,59 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright 2014 - 2017 (c) Analog Devices, Inc. All rights reserved. +// +// In this HDL repository, there are many different and unique modules, consisting +// of various HDL (Verilog or VHDL) components. The individual modules are +// developed independently, and may be accompanied by separate and unique license +// terms. +// +// The user should read each of these license terms, and understand the +// freedoms and responsibilities that he or she has by using this source/core. +// +// This core 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. +// +// Redistribution and use of source or resulting binaries, with or without modification +// of this file, are permitted under one of the following two license terms: +// +// 1. The GNU General Public License version 2 as published by the +// Free Software Foundation, which can be found in the top level directory +// of this repository (LICENSE_GPL2), and also online at: +// +// +// OR +// +// 2. An ADI specific BSD license, which can be found in the top level directory +// of this repository (LICENSE_ADIBSD), and also on-line at: +// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD +// This will allow to generate bit files and not release the source code, +// as long as it attaches to an ADI device. +// +// *************************************************************************** +// *************************************************************************** + +`timescale 1ns/100ps + +module ad_iobuf #( + + parameter DATA_WIDTH = 1) ( + + input [(DATA_WIDTH-1):0] dio_t, + input [(DATA_WIDTH-1):0] dio_i, + output [(DATA_WIDTH-1):0] dio_o, + inout [(DATA_WIDTH-1):0] dio_p); + + + genvar n; + generate + for (n = 0; n < DATA_WIDTH; n = n + 1) begin: g_iobuf + assign dio_o[n] = dio_p[n]; + assign dio_p[n] = (dio_t[n] == 1'b1) ? 1'bz : dio_i[n]; + end + endgenerate + +endmodule + +// *************************************************************************** +// *************************************************************************** diff --git a/src/adi/hdl/library/xilinx/common/ad_mmcm_drp.v b/src/adi/hdl/library/xilinx/common/ad_mmcm_drp.v new file mode 100644 index 00000000..0fc9a702 --- /dev/null +++ b/src/adi/hdl/library/xilinx/common/ad_mmcm_drp.v @@ -0,0 +1,253 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright 2014 - 2017 (c) Analog Devices, Inc. All rights reserved. +// +// In this HDL repository, there are many different and unique modules, consisting +// of various HDL (Verilog or VHDL) components. The individual modules are +// developed independently, and may be accompanied by separate and unique license +// terms. +// +// The user should read each of these license terms, and understand the +// freedoms and responsibilities that he or she has by using this source/core. +// +// This core 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. +// +// Redistribution and use of source or resulting binaries, with or without modification +// of this file, are permitted under one of the following two license terms: +// +// 1. The GNU General Public License version 2 as published by the +// Free Software Foundation, which can be found in the top level directory +// of this repository (LICENSE_GPL2), and also online at: +// +// +// OR +// +// 2. An ADI specific BSD license, which can be found in the top level directory +// of this repository (LICENSE_ADIBSD), and also on-line at: +// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD +// This will allow to generate bit files and not release the source code, +// as long as it attaches to an ADI device. +// +// *************************************************************************** +// *************************************************************************** +// MMCM_OR_BUFR_N with DRP and device specific + +`timescale 1ns/100ps + +module ad_mmcm_drp #( + + parameter MMCM_DEVICE_TYPE = 0, + parameter MMCM_CLKIN_PERIOD = 1.667, + parameter MMCM_CLKIN2_PERIOD = 1.667, + parameter MMCM_VCO_DIV = 6, + parameter MMCM_VCO_MUL = 12.000, + parameter MMCM_CLK0_DIV = 2.000, + parameter MMCM_CLK0_PHASE = 0.000, + parameter MMCM_CLK1_DIV = 6, + parameter MMCM_CLK1_PHASE = 0.000, + parameter MMCM_CLK2_DIV = 2.000, + parameter MMCM_CLK2_PHASE = 0.000) ( + + // clocks + + input clk, + input clk2, + input clk_sel, + input mmcm_rst, + output mmcm_clk_0, + output mmcm_clk_1, + output mmcm_clk_2, + + // drp interface + + input up_clk, + input up_rstn, + input up_drp_sel, + input up_drp_wr, + input [11:0] up_drp_addr, + input [15:0] up_drp_wdata, + output reg [15:0] up_drp_rdata, + output reg up_drp_ready, + output reg up_drp_locked); + + localparam MMCM_DEVICE_7SERIES = 0; + localparam MMCM_DEVICE_ULTRASCALE = 2; + + + // internal registers + + reg up_drp_locked_m1 = 'd0; + + // internal signals + + wire bufg_fb_clk_s; + wire mmcm_fb_clk_s; + wire mmcm_clk_0_s; + wire mmcm_clk_1_s; + wire mmcm_clk_2_s; + wire mmcm_locked_s; + wire [15:0] up_drp_rdata_s; + wire up_drp_ready_s; + + // drp read and locked + + always @(posedge up_clk) begin + if (up_rstn == 1'b0) begin + up_drp_rdata <= 'd0; + up_drp_ready <= 'd0; + up_drp_locked_m1 <= 1'd0; + up_drp_locked <= 1'd0; + end else begin + up_drp_rdata <= up_drp_rdata_s; + up_drp_ready <= up_drp_ready_s; + up_drp_locked_m1 <= mmcm_locked_s; + up_drp_locked <= up_drp_locked_m1; + end + end + + // instantiations + + generate + if (MMCM_DEVICE_TYPE == MMCM_DEVICE_7SERIES) begin + MMCME2_ADV #( + .BANDWIDTH ("OPTIMIZED"), + .CLKOUT4_CASCADE ("FALSE"), + .COMPENSATION ("ZHOLD"), + .STARTUP_WAIT ("FALSE"), + .DIVCLK_DIVIDE (MMCM_VCO_DIV), + .CLKFBOUT_MULT_F (MMCM_VCO_MUL), + .CLKFBOUT_PHASE (0.000), + .CLKFBOUT_USE_FINE_PS ("FALSE"), + .CLKOUT0_DIVIDE_F (MMCM_CLK0_DIV), + .CLKOUT0_PHASE (MMCM_CLK0_PHASE), + .CLKOUT0_DUTY_CYCLE (0.500), + .CLKOUT0_USE_FINE_PS ("FALSE"), + .CLKOUT1_DIVIDE (MMCM_CLK1_DIV), + .CLKOUT1_PHASE (MMCM_CLK1_PHASE), + .CLKOUT1_DUTY_CYCLE (0.500), + .CLKOUT1_USE_FINE_PS ("FALSE"), + .CLKOUT2_DIVIDE (MMCM_CLK2_DIV), + .CLKOUT2_PHASE (MMCM_CLK2_PHASE), + .CLKOUT2_DUTY_CYCLE (0.500), + .CLKOUT2_USE_FINE_PS ("FALSE"), + .CLKIN1_PERIOD (MMCM_CLKIN_PERIOD), + .CLKIN2_PERIOD (MMCM_CLKIN2_PERIOD), + .REF_JITTER1 (0.010)) + i_mmcm ( + .CLKIN1 (clk), + .CLKFBIN (bufg_fb_clk_s), + .CLKFBOUT (mmcm_fb_clk_s), + .CLKOUT0 (mmcm_clk_0_s), + .CLKOUT1 (mmcm_clk_1_s), + .CLKOUT2 (mmcm_clk_2_s), + .LOCKED (mmcm_locked_s), + .DCLK (up_clk), + .DEN (up_drp_sel), + .DADDR (up_drp_addr[6:0]), + .DWE (up_drp_wr), + .DI (up_drp_wdata), + .DO (up_drp_rdata_s), + .DRDY (up_drp_ready_s), + .CLKFBOUTB (), + .CLKOUT0B (), + .CLKOUT1B (), + .CLKOUT2B (), + .CLKOUT3 (), + .CLKOUT3B (), + .CLKOUT4 (), + .CLKOUT5 (), + .CLKOUT6 (), + .CLKIN2 (clk2), + .CLKINSEL (clk_sel), + .PSCLK (1'b0), + .PSEN (1'b0), + .PSINCDEC (1'b0), + .PSDONE (), + .CLKINSTOPPED (), + .CLKFBSTOPPED (), + .PWRDWN (1'b0), + .RST (mmcm_rst)); + + BUFG i_fb_clk_bufg (.I (mmcm_fb_clk_s), .O (bufg_fb_clk_s)); + BUFG i_clk_0_bufg (.I (mmcm_clk_0_s), .O (mmcm_clk_0)); + BUFG i_clk_1_bufg (.I (mmcm_clk_1_s), .O (mmcm_clk_1)); + BUFG i_clk_2_bufg (.I (mmcm_clk_2_s), .O (mmcm_clk_2)); + + end else if (MMCM_DEVICE_TYPE == MMCM_DEVICE_ULTRASCALE) begin + MMCME3_ADV #( + .BANDWIDTH ("OPTIMIZED"), + .CLKOUT4_CASCADE ("FALSE"), + .COMPENSATION ("AUTO"), + .STARTUP_WAIT ("FALSE"), + + .DIVCLK_DIVIDE (MMCM_VCO_DIV), + .CLKFBOUT_MULT_F (MMCM_VCO_MUL), + .CLKFBOUT_PHASE (0.000), + .CLKFBOUT_USE_FINE_PS ("FALSE"), + .CLKOUT0_DIVIDE_F (MMCM_CLK0_DIV), + .CLKOUT0_PHASE (MMCM_CLK0_PHASE), + .CLKOUT0_DUTY_CYCLE (0.500), + .CLKOUT0_USE_FINE_PS ("FALSE"), + .CLKOUT1_DIVIDE (MMCM_CLK1_DIV), + .CLKOUT1_PHASE (MMCM_CLK1_PHASE), + .CLKOUT1_DUTY_CYCLE (0.500), + .CLKOUT1_USE_FINE_PS ("FALSE"), + .CLKOUT2_DIVIDE (MMCM_CLK2_DIV), + .CLKOUT2_PHASE (MMCM_CLK2_PHASE), + .CLKOUT2_DUTY_CYCLE (0.500), + .CLKOUT2_USE_FINE_PS ("FALSE"), + .CLKIN1_PERIOD (MMCM_CLKIN_PERIOD), + .CLKIN2_PERIOD (MMCM_CLKIN2_PERIOD), + .REF_JITTER1 (0.010)) + i_mmcme3 ( + .CLKIN1 (clk), + .CLKFBIN (bufg_fb_clk_s), + .CLKFBOUT (mmcm_fb_clk_s), + .CLKOUT0 (mmcm_clk_0_s), + .CLKOUT1 (mmcm_clk_1_s), + .CLKOUT2 (mmcm_clk_2_s), + .LOCKED (mmcm_locked_s), + .DCLK (up_clk), + .DEN (up_drp_sel), + .DADDR (up_drp_addr[6:0]), + .DWE (up_drp_wr), + .DI (up_drp_wdata), + .DO (up_drp_rdata_s), + .DRDY (up_drp_ready_s), + .CLKFBOUTB (), + .CLKOUT0B (), + .CLKOUT1B (), + .CLKOUT2B (), + .CLKOUT3 (), + .CLKOUT3B (), + .CLKOUT4 (), + .CLKOUT5 (), + .CLKOUT6 (), + .CLKIN2 (clk2), + .CLKINSEL (clk_sel), + .PSCLK (1'b0), + .PSEN (1'b0), + .PSINCDEC (1'b0), + .PSDONE (), + .CLKINSTOPPED (), + .CLKFBSTOPPED (), + .PWRDWN (1'b0), + .CDDCREQ (1'b0), + .CDDCDONE (), + .RST (mmcm_rst)); + + BUFG i_fb_clk_bufg (.I (mmcm_fb_clk_s), .O (bufg_fb_clk_s)); + BUFG i_clk_0_bufg (.I (mmcm_clk_0_s), .O (mmcm_clk_0)); + BUFG i_clk_1_bufg (.I (mmcm_clk_1_s), .O (mmcm_clk_1)); + BUFG i_clk_2_bufg (.I (mmcm_clk_2_s), .O (mmcm_clk_2)); + + end + endgenerate + + +endmodule + +// *************************************************************************** +// *************************************************************************** diff --git a/src/adi/hdl/library/xilinx/common/ad_mul.v b/src/adi/hdl/library/xilinx/common/ad_mul.v new file mode 100644 index 00000000..9b64ebcc --- /dev/null +++ b/src/adi/hdl/library/xilinx/common/ad_mul.v @@ -0,0 +1,85 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright 2014 - 2017 (c) Analog Devices, Inc. All rights reserved. +// +// In this HDL repository, there are many different and unique modules, consisting +// of various HDL (Verilog or VHDL) components. The individual modules are +// developed independently, and may be accompanied by separate and unique license +// terms. +// +// The user should read each of these license terms, and understand the +// freedoms and responsibilities that he or she has by using this source/core. +// +// This core 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. +// +// Redistribution and use of source or resulting binaries, with or without modification +// of this file, are permitted under one of the following two license terms: +// +// 1. The GNU General Public License version 2 as published by the +// Free Software Foundation, which can be found in the top level directory +// of this repository (LICENSE_GPL2), and also online at: +// +// +// OR +// +// 2. An ADI specific BSD license, which can be found in the top level directory +// of this repository (LICENSE_ADIBSD), and also on-line at: +// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD +// This will allow to generate bit files and not release the source code, +// as long as it attaches to an ADI device. +// +// *************************************************************************** +// *************************************************************************** + +`timescale 1ps/1ps + +module ad_mul #( + + parameter A_DATA_WIDTH = 17, + parameter B_DATA_WIDTH = 17, + parameter DELAY_DATA_WIDTH = 16) ( + + // data_p = data_a * data_b; + + input clk, + input [ A_DATA_WIDTH-1:0] data_a, + input [ B_DATA_WIDTH-1:0] data_b, + output [A_DATA_WIDTH + B_DATA_WIDTH-1:0] data_p, + + // delay interface + + input [(DELAY_DATA_WIDTH-1):0] ddata_in, + output reg [(DELAY_DATA_WIDTH-1):0] ddata_out); + + + // internal registers + + reg [(DELAY_DATA_WIDTH-1):0] p1_ddata = 'd0; + reg [(DELAY_DATA_WIDTH-1):0] p2_ddata = 'd0; + + // a/b reg, m-reg, p-reg delay match + + always @(posedge clk) begin + p1_ddata <= ddata_in; + p2_ddata <= p1_ddata; + ddata_out <= p2_ddata; + end + + MULT_MACRO #( + .LATENCY (3), + .WIDTH_A (A_DATA_WIDTH), + .WIDTH_B (B_DATA_WIDTH)) + i_mult_macro ( + .CE (1'b1), + .RST (1'b0), + .CLK (clk), + .A (data_a), + .B (data_b), + .P (data_p)); + +endmodule + +// *************************************************************************** +// *************************************************************************** diff --git a/src/adi/hdl/library/xilinx/common/ad_rst_constr.xdc b/src/adi/hdl/library/xilinx/common/ad_rst_constr.xdc new file mode 100644 index 00000000..7aab6af3 --- /dev/null +++ b/src/adi/hdl/library/xilinx/common/ad_rst_constr.xdc @@ -0,0 +1,8 @@ + +set_property ASYNC_REG TRUE [get_cells -hier -filter {name =~ *rst_async_d*_reg}] +set_property ASYNC_REG TRUE [get_cells -hier -filter {name =~ *rst_sync_reg}] + +set_false_path -to [get_pins *rst_sync_reg/PRE] +set_false_path -to [get_pins *rst_async_d1_reg/PRE] +set_false_path -to [get_pins *rst_async_d2_reg/PRE] + diff --git a/src/adi/hdl/library/xilinx/common/ad_serdes_clk.v b/src/adi/hdl/library/xilinx/common/ad_serdes_clk.v new file mode 100644 index 00000000..53742998 --- /dev/null +++ b/src/adi/hdl/library/xilinx/common/ad_serdes_clk.v @@ -0,0 +1,160 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright 2014 - 2017 (c) Analog Devices, Inc. All rights reserved. +// +// In this HDL repository, there are many different and unique modules, consisting +// of various HDL (Verilog or VHDL) components. The individual modules are +// developed independently, and may be accompanied by separate and unique license +// terms. +// +// The user should read each of these license terms, and understand the +// freedoms and responsibilities that he or she has by using this source/core. +// +// This core 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. +// +// Redistribution and use of source or resulting binaries, with or without modification +// of this file, are permitted under one of the following two license terms: +// +// 1. The GNU General Public License version 2 as published by the +// Free Software Foundation, which can be found in the top level directory +// of this repository (LICENSE_GPL2), and also online at: +// +// +// OR +// +// 2. An ADI specific BSD license, which can be found in the top level directory +// of this repository (LICENSE_ADIBSD), and also on-line at: +// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD +// This will allow to generate bit files and not release the source code, +// as long as it attaches to an ADI device. +// +// *************************************************************************** +// *************************************************************************** +// serial data output interface: serdes(x8) + +`timescale 1ps/1ps + +module ad_serdes_clk #( + + parameter DEVICE_TYPE = 0, + parameter DDR_OR_SDR_N = 1, + parameter CLKIN_DS_OR_SE_N = 1, + parameter SERDES_FACTOR = 8, + parameter MMCM_OR_BUFR_N = 1, + parameter MMCM_CLKIN_PERIOD = 1.667, + parameter MMCM_VCO_DIV = 6, + parameter MMCM_VCO_MUL = 12.000, + parameter MMCM_CLK0_DIV = 2.000, + parameter MMCM_CLK1_DIV = 6) ( + + // clock and divided clock + + input rst, + input clk_in_p, + input clk_in_n, + output clk, + output div_clk, + output out_clk, + output loaden, + output [ 7:0] phase, + + // drp interface + + input up_clk, + input up_rstn, + input up_drp_sel, + input up_drp_wr, + input [11:0] up_drp_addr, + input [31:0] up_drp_wdata, + output [31:0] up_drp_rdata, + output up_drp_ready, + output up_drp_locked); + + localparam BUFR_DIVIDE = (DDR_OR_SDR_N == 1'b1) ? SERDES_FACTOR / 2 : SERDES_FACTOR; + + // internal signals + + wire clk_in_s; + + // defaults + + assign loaden = 'd0; + assign phase = 'd0; + assign up_drp_rdata[31:16] = 'd0; + + // instantiations + + generate + if (CLKIN_DS_OR_SE_N == 1) begin + IBUFGDS i_clk_in_ibuf ( + .I (clk_in_p), + .IB (clk_in_n), + .O (clk_in_s)); + end else begin + IBUF IBUF_inst ( + .O(clk_in_s), + .I(clk_in_p)); + end + endgenerate + + generate + if (MMCM_OR_BUFR_N == 1) begin + ad_mmcm_drp #( + .MMCM_DEVICE_TYPE (DEVICE_TYPE), + .MMCM_CLKIN_PERIOD (MMCM_CLKIN_PERIOD), + .MMCM_CLKIN2_PERIOD (MMCM_CLKIN_PERIOD), + .MMCM_VCO_DIV (MMCM_VCO_DIV), + .MMCM_VCO_MUL (MMCM_VCO_MUL), + .MMCM_CLK0_DIV (MMCM_CLK0_DIV), + .MMCM_CLK0_PHASE (0.0), + .MMCM_CLK1_DIV (MMCM_CLK1_DIV), + .MMCM_CLK1_PHASE (0.0), + .MMCM_CLK2_DIV (MMCM_CLK0_DIV), + .MMCM_CLK2_PHASE (90.0)) + i_mmcm_drp ( + .clk (clk_in_s), + .clk2 (1'b0), + .clk_sel (1'b1), + .mmcm_rst (rst), + .mmcm_clk_0 (clk), + .mmcm_clk_1 (div_clk), + .mmcm_clk_2 (out_clk), + .up_clk (up_clk), + .up_rstn (up_rstn), + .up_drp_sel (up_drp_sel), + .up_drp_wr (up_drp_wr), + .up_drp_addr (up_drp_addr), + .up_drp_wdata (up_drp_wdata[15:0]), + .up_drp_rdata (up_drp_rdata[15:0]), + .up_drp_ready (up_drp_ready), + .up_drp_locked (up_drp_locked)); + end + endgenerate + + generate + if (MMCM_OR_BUFR_N == 0) begin + BUFIO i_clk_buf ( + .I (clk_in_s), + .O (clk)); + + BUFR #(.BUFR_DIVIDE(BUFR_DIVIDE)) i_div_clk_buf ( + .CLR (1'b0), + .CE (1'b1), + .I (clk_in_s), + .O (div_clk)); + + assign out_clk = clk; + assign up_drp_rdata[15:0] = 'd0; + assign up_drp_ready = 'd0; + assign up_drp_locked = 'd0; + + end + endgenerate + +endmodule + +// *************************************************************************** +// *************************************************************************** + diff --git a/src/adi/hdl/library/xilinx/common/ad_serdes_in.v b/src/adi/hdl/library/xilinx/common/ad_serdes_in.v new file mode 100644 index 00000000..aa585b8b --- /dev/null +++ b/src/adi/hdl/library/xilinx/common/ad_serdes_in.v @@ -0,0 +1,197 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright 2014 - 2017 (c) Analog Devices, Inc. All rights reserved. +// +// In this HDL repository, there are many different and unique modules, consisting +// of various HDL (Verilog or VHDL) components. The individual modules are +// developed independently, and may be accompanied by separate and unique license +// terms. +// +// The user should read each of these license terms, and understand the +// freedoms and responsibilities that he or she has by using this source/core. +// +// This core 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. +// +// Redistribution and use of source or resulting binaries, with or without modification +// of this file, are permitted under one of the following two license terms: +// +// 1. The GNU General Public License version 2 as published by the +// Free Software Foundation, which can be found in the top level directory +// of this repository (LICENSE_GPL2), and also online at: +// +// +// OR +// +// 2. An ADI specific BSD license, which can be found in the top level directory +// of this repository (LICENSE_ADIBSD), and also on-line at: +// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD +// This will allow to generate bit files and not release the source code, +// as long as it attaches to an ADI device. +// +// *************************************************************************** +// *************************************************************************** + +`timescale 1ps/1ps + +module ad_serdes_in #( + + parameter DEVICE_TYPE = 0, + parameter DDR_OR_SDR_N = 0, + parameter SERDES_FACTOR = 8, + parameter DATA_WIDTH = 16, + parameter IODELAY_CTRL = 0, + parameter IODELAY_GROUP = "dev_if_delay_group") ( + + // reset and clocks + + input rst, + input clk, + input div_clk, + input loaden, + input [ 7:0] phase, + input locked, + + // data interface + + output [(DATA_WIDTH-1):0] data_s0, + output [(DATA_WIDTH-1):0] data_s1, + output [(DATA_WIDTH-1):0] data_s2, + output [(DATA_WIDTH-1):0] data_s3, + output [(DATA_WIDTH-1):0] data_s4, + output [(DATA_WIDTH-1):0] data_s5, + output [(DATA_WIDTH-1):0] data_s6, + output [(DATA_WIDTH-1):0] data_s7, + input [(DATA_WIDTH-1):0] data_in_p, + input [(DATA_WIDTH-1):0] data_in_n, + + // delay-data interface + + input up_clk, + input [(DATA_WIDTH-1):0] up_dld, + input [((DATA_WIDTH*5)-1):0] up_dwdata, + output [((DATA_WIDTH*5)-1):0] up_drdata, + + // delay-control interface + + input delay_clk, + input delay_rst, + output delay_locked); + + localparam DEVICE_7SERIES = 0; + localparam DATA_RATE = (DDR_OR_SDR_N) ? "DDR" : "SDR"; + + // internal signals + + wire [(DATA_WIDTH-1):0] data_in_ibuf_s; + wire [(DATA_WIDTH-1):0] data_in_idelay_s; + wire [(DATA_WIDTH-1):0] data_shift1_s; + wire [(DATA_WIDTH-1):0] data_shift2_s; + + // delay controller + + generate + if (IODELAY_CTRL == 1) begin + (* IODELAY_GROUP = IODELAY_GROUP *) + IDELAYCTRL i_delay_ctrl ( + .RST (delay_rst), + .REFCLK (delay_clk), + .RDY (delay_locked)); + end else begin + assign delay_locked = 1'b1; + end + endgenerate + + // received data interface: ibuf -> idelay -> iserdes + + genvar l_inst; + generate if (DEVICE_TYPE == DEVICE_7SERIES) begin + for (l_inst = 0; l_inst <= (DATA_WIDTH-1); l_inst = l_inst + 1) begin: g_data + + IBUFDS i_ibuf ( + .I (data_in_p[l_inst]), + .IB (data_in_n[l_inst]), + .O (data_in_ibuf_s[l_inst])); + + (* IODELAY_GROUP = IODELAY_GROUP *) + IDELAYE2 #( + .CINVCTRL_SEL ("FALSE"), + .DELAY_SRC ("IDATAIN"), + .HIGH_PERFORMANCE_MODE ("FALSE"), + .IDELAY_TYPE ("VAR_LOAD"), + .IDELAY_VALUE (0), + .REFCLK_FREQUENCY (200.0), + .PIPE_SEL ("FALSE"), + .SIGNAL_PATTERN ("DATA")) + i_idelay ( + .CE (1'b0), + .INC (1'b0), + .DATAIN (1'b0), + .LDPIPEEN (1'b0), + .CINVCTRL (1'b0), + .REGRST (1'b0), + .C (up_clk), + .IDATAIN (data_in_ibuf_s[l_inst]), + .DATAOUT (data_in_idelay_s[l_inst]), + .LD (up_dld[l_inst]), + .CNTVALUEIN (up_dwdata[((5*l_inst)+4):(5*l_inst)]), + .CNTVALUEOUT (up_drdata[((5*l_inst)+4):(5*l_inst)])); + + ISERDESE2 #( + .DATA_RATE (DATA_RATE), + .DATA_WIDTH (SERDES_FACTOR), + .DYN_CLKDIV_INV_EN ("FALSE"), + .DYN_CLK_INV_EN ("FALSE"), + .INIT_Q1 (1'b0), + .INIT_Q2 (1'b0), + .INIT_Q3 (1'b0), + .INIT_Q4 (1'b0), + .INTERFACE_TYPE ("NETWORKING"), + .IOBDELAY ("IFD"), + .NUM_CE (2), + .OFB_USED ("FALSE"), + .SERDES_MODE ("MASTER"), + .SRVAL_Q1 (1'b0), + .SRVAL_Q2 (1'b0), + .SRVAL_Q3 (1'b0), + .SRVAL_Q4 (1'b0)) + i_iserdes ( + .O (), + .Q1 (data_s0[l_inst]), + .Q2 (data_s1[l_inst]), + .Q3 (data_s2[l_inst]), + .Q4 (data_s3[l_inst]), + .Q5 (data_s4[l_inst]), + .Q6 (data_s5[l_inst]), + .Q7 (data_s6[l_inst]), + .Q8 (data_s7[l_inst]), + .SHIFTOUT1 (), + .SHIFTOUT2 (), + .BITSLIP (1'b0), + .CE1 (1'b1), + .CE2 (1'b1), + .CLKDIVP (1'b0), + .CLK (clk), + .CLKB (~clk), + .CLKDIV (div_clk), + .OCLK (1'b0), + .DYNCLKDIVSEL (1'b0), + .DYNCLKSEL (1'b0), + .D (1'b0), + .DDLY (data_in_idelay_s[l_inst]), + .OFB (1'b0), + .OCLKB (1'b0), + .RST (rst), + .SHIFTIN1 (1'b0), + .SHIFTIN2 (1'b0)); + end /* g_data */ + + end + endgenerate + + +endmodule + +// *************************************************************************** +// *************************************************************************** diff --git a/src/adi/hdl/library/xilinx/common/ad_serdes_out.v b/src/adi/hdl/library/xilinx/common/ad_serdes_out.v new file mode 100644 index 00000000..354deb7c --- /dev/null +++ b/src/adi/hdl/library/xilinx/common/ad_serdes_out.v @@ -0,0 +1,133 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright 2014 - 2017 (c) Analog Devices, Inc. All rights reserved. +// +// In this HDL repository, there are many different and unique modules, consisting +// of various HDL (Verilog or VHDL) components. The individual modules are +// developed independently, and may be accompanied by separate and unique license +// terms. +// +// The user should read each of these license terms, and understand the +// freedoms and responsibilities that he or she has by using this source/core. +// +// This core 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. +// +// Redistribution and use of source or resulting binaries, with or without modification +// of this file, are permitted under one of the following two license terms: +// +// 1. The GNU General Public License version 2 as published by the +// Free Software Foundation, which can be found in the top level directory +// of this repository (LICENSE_GPL2), and also online at: +// +// +// OR +// +// 2. An ADI specific BSD license, which can be found in the top level directory +// of this repository (LICENSE_ADIBSD), and also on-line at: +// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD +// This will allow to generate bit files and not release the source code, +// as long as it attaches to an ADI device. +// +// *************************************************************************** +// *************************************************************************** +// serial data output interface: serdes(x8) + +`timescale 1ps/1ps + +module ad_serdes_out #( + + parameter DEVICE_TYPE = 0, + parameter DDR_OR_SDR_N = 1, + parameter SERDES_FACTOR = 8, + parameter DATA_WIDTH = 16) ( + + // reset and clocks + + input rst, + input clk, + input div_clk, + input loaden, + + // data interface + + input [(DATA_WIDTH-1):0] data_s0, + input [(DATA_WIDTH-1):0] data_s1, + input [(DATA_WIDTH-1):0] data_s2, + input [(DATA_WIDTH-1):0] data_s3, + input [(DATA_WIDTH-1):0] data_s4, + input [(DATA_WIDTH-1):0] data_s5, + input [(DATA_WIDTH-1):0] data_s6, + input [(DATA_WIDTH-1):0] data_s7, + output [(DATA_WIDTH-1):0] data_out_se, + output [(DATA_WIDTH-1):0] data_out_p, + output [(DATA_WIDTH-1):0] data_out_n); + + localparam DEVICE_7SERIES = 0; + localparam DR_OQ_DDR = DDR_OR_SDR_N == 1'b1 ? "DDR": "SDR"; + + // internal signals + + wire [(DATA_WIDTH-1):0] data_out_s; + wire [(DATA_WIDTH-1):0] serdes_shift1_s; + wire [(DATA_WIDTH-1):0] serdes_shift2_s; + + assign data_out_se = data_out_s; + + // instantiations + + genvar l_inst; + generate + for (l_inst = 0; l_inst <= (DATA_WIDTH-1); l_inst = l_inst + 1) begin: g_data + + if (DEVICE_TYPE == DEVICE_7SERIES) begin + OSERDESE2 #( + .DATA_RATE_OQ (DR_OQ_DDR), + .DATA_RATE_TQ ("SDR"), + .DATA_WIDTH (SERDES_FACTOR), + .TRISTATE_WIDTH (1), + .SERDES_MODE ("MASTER")) + i_serdes ( + .D1 (data_s0[l_inst]), + .D2 (data_s1[l_inst]), + .D3 (data_s2[l_inst]), + .D4 (data_s3[l_inst]), + .D5 (data_s4[l_inst]), + .D6 (data_s5[l_inst]), + .D7 (data_s6[l_inst]), + .D8 (data_s7[l_inst]), + .T1 (1'b0), + .T2 (1'b0), + .T3 (1'b0), + .T4 (1'b0), + .SHIFTIN1 (1'b0), + .SHIFTIN2 (1'b0), + .SHIFTOUT1 (), + .SHIFTOUT2 (), + .OCE (1'b1), + .CLK (clk), + .CLKDIV (div_clk), + .OQ (data_out_s[l_inst]), + .TQ (), + .OFB (), + .TFB (), + .TBYTEIN (1'b0), + .TBYTEOUT (), + .TCE (1'b0), + .RST (rst)); + end + + OBUFDS i_obuf ( + .I (data_out_s[l_inst]), + .O (data_out_p[l_inst]), + .OB (data_out_n[l_inst])); + + end + endgenerate + +endmodule + +// *************************************************************************** +// *************************************************************************** + diff --git a/src/adi/hdl/library/xilinx/common/up_clock_mon_constr.xdc b/src/adi/hdl/library/xilinx/common/up_clock_mon_constr.xdc new file mode 100644 index 00000000..e3084923 --- /dev/null +++ b/src/adi/hdl/library/xilinx/common/up_clock_mon_constr.xdc @@ -0,0 +1,8 @@ + +set_property ASYNC_REG true [get_cells -hier -filter {name =~ *up_count_running_m*}] +set_property ASYNC_REG true [get_cells -hier -filter {name =~ *d_count_run_m*}] + +set_false_path -from [get_cells -hier -filter {name =~ *d_count_run_m3_reg* && IS_SEQUENTIAL}] -to [get_cells -hier -filter {name =~ *up_count_running_m1_reg* && IS_SEQUENTIAL}] +set_false_path -from [get_cells -hier -filter {name =~ *up_count_run_reg* && IS_SEQUENTIAL}] -to [get_cells -hier -filter {name =~ *d_count_run_m1_reg* && IS_SEQUENTIAL}] +set_false_path -from [get_cells -hier -filter {name =~ *d_count_reg* && IS_SEQUENTIAL}] -to [get_cells -hier -filter {name =~ *up_d_count_reg* && IS_SEQUENTIAL}] + diff --git a/src/adi/hdl/library/xilinx/common/up_xfer_cntrl_constr.xdc b/src/adi/hdl/library/xilinx/common/up_xfer_cntrl_constr.xdc new file mode 100644 index 00000000..c089f82b --- /dev/null +++ b/src/adi/hdl/library/xilinx/common/up_xfer_cntrl_constr.xdc @@ -0,0 +1,7 @@ + +set_property ASYNC_REG TRUE [get_cells -hier -filter {name =~ *up_xfer_state*}] +set_property ASYNC_REG TRUE [get_cells -hier -filter {name =~ *d_xfer_toggle_m*}] + +set_false_path -from [get_cells -hier -filter {name =~ *d_xfer_toggle_reg && IS_SEQUENTIAL}] -to [get_cells -hier -filter {name =~ *up_xfer_state_m1_reg && IS_SEQUENTIAL}] +set_false_path -from [get_cells -hier -filter {name =~ *up_xfer_toggle_reg && IS_SEQUENTIAL}] -to [get_cells -hier -filter {name =~ *d_xfer_toggle_m1_reg && IS_SEQUENTIAL}] +set_false_path -from [get_cells -hier -filter {name =~ *up_xfer_data* && IS_SEQUENTIAL}] -to [get_cells -hier -filter {name =~ *d_data_cntrl* && IS_SEQUENTIAL}] diff --git a/src/adi/hdl/library/xilinx/common/up_xfer_status_constr.xdc b/src/adi/hdl/library/xilinx/common/up_xfer_status_constr.xdc new file mode 100644 index 00000000..92231132 --- /dev/null +++ b/src/adi/hdl/library/xilinx/common/up_xfer_status_constr.xdc @@ -0,0 +1,7 @@ + +set_property ASYNC_REG TRUE [get_cells -hier -filter {name =~ *d_xfer_state*}] +set_property ASYNC_REG TRUE [get_cells -hier -filter {name =~ *up_xfer_toggle_m*}] + +set_false_path -from [get_cells -hier -filter {name =~ *d_xfer_toggle_reg && IS_SEQUENTIAL}] -to [get_cells -hier -filter {name =~ *up_xfer_toggle_m1_reg && IS_SEQUENTIAL}] +set_false_path -from [get_cells -hier -filter {name =~ *up_xfer_toggle_reg && IS_SEQUENTIAL}] -to [get_cells -hier -filter {name =~ *d_xfer_state_m1_reg && IS_SEQUENTIAL}] +set_false_path -from [get_cells -hier -filter {name =~ *d_xfer_data* && IS_SEQUENTIAL}] -to [get_cells -hier -filter {name =~ *up_data_status* && IS_SEQUENTIAL}] diff --git a/src/adi/hdl/projects/scripts/adi_board.tcl b/src/adi/hdl/projects/scripts/adi_board.tcl new file mode 100644 index 00000000..ca989459 --- /dev/null +++ b/src/adi/hdl/projects/scripts/adi_board.tcl @@ -0,0 +1,763 @@ +################################################################################################### +################################################################################################### + +variable sys_cpu_interconnect_index +variable sys_hp0_interconnect_index +variable sys_hp1_interconnect_index +variable sys_hp2_interconnect_index +variable sys_hp3_interconnect_index +variable sys_mem_interconnect_index + +variable xcvr_index +variable xcvr_tx_index +variable xcvr_rx_index +variable xcvr_instance + +################################################################################################### +################################################################################################### + +set sys_cpu_interconnect_index 0 +set sys_hp0_interconnect_index -1 +set sys_hp1_interconnect_index -1 +set sys_hp2_interconnect_index -1 +set sys_hp3_interconnect_index -1 +set sys_mem_interconnect_index -1 + +set xcvr_index -1 +set xcvr_tx_index 0 +set xcvr_rx_index 0 +set xcvr_instance NONE + +################################################################################################### +################################################################################################### + +proc ad_ip_instance {i_ip i_name {i_params {}}} { + + set cell [create_bd_cell -type ip -vlnv [get_ipdefs -all -filter "VLNV =~ *:${i_ip}:* && \ + design_tool_contexts =~ *IPI* && UPGRADE_VERSIONS == \"\""] ${i_name}] + if {$i_params != {}} { + set config {} + # Add CONFIG. prefix to all config options + foreach {k v} $i_params { + lappend config "CONFIG.$k" $v + } + set_property -dict $config $cell + } +} + +proc ad_ip_parameter {i_name i_param i_value} { + + set_property ${i_param} ${i_value} [get_bd_cells ${i_name}] +} + +################################################################################################### +################################################################################################### + +proc ad_connect_type {p_name} { + + set m_name "" + + if {$m_name eq ""} {set m_name [get_bd_intf_pins -quiet $p_name]} + if {$m_name eq ""} {set m_name [get_bd_pins -quiet $p_name]} + if {$m_name eq ""} {set m_name [get_bd_intf_ports -quiet $p_name]} + if {$m_name eq ""} {set m_name [get_bd_ports -quiet $p_name]} + if {$m_name eq ""} {set m_name [get_bd_intf_nets -quiet $p_name]} + if {$m_name eq ""} {set m_name [get_bd_nets -quiet $p_name]} + + return $m_name +} + +proc ad_connect {p_name_1 p_name_2} { + + if {($p_name_2 eq "GND") || ($p_name_2 eq "VCC")} { + set p_size 1 + set p_msb [get_property left [get_bd_pins $p_name_1]] + set p_lsb [get_property right [get_bd_pins $p_name_1]] + if {($p_msb ne "") && ($p_lsb ne "")} { + set p_size [expr (($p_msb + 1) - $p_lsb)] + } + set p_cell_name "$p_name_2\_$p_size" + if {[get_bd_cells -quiet $p_cell_name] eq ""} { + if {$p_name_2 eq "VCC"} { + set p_value [expr (1 << $p_size) - 1] + } else { + set p_value 0 + } + ad_ip_instance xlconstant $p_cell_name + set_property CONFIG.CONST_WIDTH $p_size [get_bd_cells $p_cell_name] + set_property CONFIG.CONST_VAL $p_value [get_bd_cells $p_cell_name] + } + puts "connect_bd_net $p_cell_name/dout $p_name_1" + connect_bd_net [get_bd_pins $p_name_1] [get_bd_pins $p_cell_name/dout] + return + } + + set m_name_1 [ad_connect_type $p_name_1] + set m_name_2 [ad_connect_type $p_name_2] + + if {$m_name_1 eq ""} { + if {[get_property CLASS $m_name_2] eq "bd_intf_pin"} { + puts "create_bd_intf_net $p_name_1" + create_bd_intf_net $p_name_1 + } + if {[get_property CLASS $m_name_2] eq "bd_pin"} { + puts "create_bd_net $p_name_1" + create_bd_net $p_name_1 + } + set m_name_1 [ad_connect_type $p_name_1] + } + + if {[get_property CLASS $m_name_1] eq "bd_intf_pin"} { + puts "connect_bd_intf_net $m_name_1 $m_name_2" + connect_bd_intf_net $m_name_1 $m_name_2 + return + } + + if {[get_property CLASS $m_name_1] eq "bd_pin"} { + puts "connect_bd_net $m_name_1 $m_name_2" + connect_bd_net $m_name_1 $m_name_2 + return + } + + if {[get_property CLASS $m_name_1] eq "bd_net"} { + puts "connect_bd_net -net $m_name_1 $m_name_2" + connect_bd_net -net $m_name_1 $m_name_2 + return + } +} + +proc ad_disconnect {p_name_1 p_name_2} { + + set m_name_1 [ad_connect_type $p_name_1] + set m_name_2 [ad_connect_type $p_name_2] + + if {[get_property CLASS $m_name_1] eq "bd_net"} { + disconnect_bd_net $m_name_1 $m_name_2 + return + } + + if {[get_property CLASS $m_name_1] eq "bd_port"} { + delete_bd_objs -quiet [get_bd_nets -quiet -of_objects \ + [find_bd_objs -relation connected_to $m_name_1]] + delete_bd_objs -quiet $m_name_1 + return + } + + if {[get_property CLASS $m_name_1] eq "bd_pin"} { + delete_bd_objs -quiet [get_bd_nets -quiet -of_objects \ + [find_bd_objs -relation connected_to $m_name_1]] + delete_bd_objs -quiet $m_name_1 + return + } +} + +proc ad_reconct {p_name_1 p_name_2} { + + set m_name_1 [ad_connect_type $p_name_1] + set m_name_2 [ad_connect_type $p_name_2] + + if {[get_property CLASS $m_name_1] eq "bd_pin"} { + delete_bd_objs -quiet [get_bd_nets -quiet -of_objects \ + [find_bd_objs -relation connected_to $m_name_1]] + delete_bd_objs -quiet [get_bd_nets -quiet -of_objects \ + [find_bd_objs -relation connected_to $m_name_2]] + } + + if {[get_property CLASS $m_name_1] eq "bd_intf_pin"} { + delete_bd_objs -quiet [get_bd_intf_nets -quiet -of_objects \ + [find_bd_objs -relation connected_to $m_name_1]] + delete_bd_objs -quiet [get_bd_intf_nets -quiet -of_objects \ + [find_bd_objs -relation connected_to $m_name_2]] + } + + ad_connect $p_name_1 $p_name_2 +} + +################################################################################################### +################################################################################################### + +# +# lane_map maps the logical lane $n onto the physical lane $lane_map[$n]. If no +# lane map is provided logical lane $n is mapped onto physical lane $n. +# +proc ad_xcvrcon {u_xcvr a_xcvr a_jesd {lane_map {}} {device_clk {}}} { + + global xcvr_index + global xcvr_tx_index + global xcvr_rx_index + global xcvr_instance + + set no_of_lanes [get_property CONFIG.NUM_OF_LANES [get_bd_cells $a_xcvr]] + set qpll_enable [get_property CONFIG.QPLL_ENABLE [get_bd_cells $a_xcvr]] + set tx_or_rx_n [get_property CONFIG.TX_OR_RX_N [get_bd_cells $a_xcvr]] + +# set jesd204_vlnv [get_property VLNV $a_jesd] +# +# if {[string first "analog.com" $jesd204_vlnv] == 0} { +# set jesd204_type 0 +# } elseif {[string first "xilinx.com" $jesd204_vlnv] == 0} { +# set jesd204_type 1 +# } else { +# return -code 1 "Unsupported JESD204 core type." +# } + + set jesd204_bd_type [get_property TYPE [get_bd_cells $a_jesd]] + + if {$jesd204_bd_type == "hier"} { + set jesd204_type 0 + } else { + set jesd204_type 1 + } + + if {$xcvr_instance ne $u_xcvr} { + set xcvr_index [expr ($xcvr_index + 1)] + set xcvr_tx_index 0 + set xcvr_rx_index 0 + set xcvr_instance $u_xcvr + } + + set txrx "rx" + set data_dir "I" + set ctrl_dir "O" + set index $xcvr_rx_index + + if {$tx_or_rx_n == 1} { + + set txrx "tx" + set data_dir "O" + set ctrl_dir "I" + set index $xcvr_tx_index + } + + set m_sysref ${txrx}_sysref_${index} + set m_sync ${txrx}_sync_${index} + set m_data ${txrx}_data + + if {$xcvr_index >= 1} { + + set m_sysref ${txrx}_sysref_${xcvr_index}_${index} + set m_sync ${txrx}_sync_${xcvr_index}_${index} + set m_data ${txrx}_data_${xcvr_index} + } + + if {$jesd204_type == 0} { + set num_of_links [get_property CONFIG.NUM_LINKS [get_bd_cells $a_jesd/$txrx]] + } else { + set num_of_links 1 + } + + create_bd_port -dir I $m_sysref + create_bd_port -from [expr $num_of_links - 1] -to 0 -dir ${ctrl_dir} $m_sync + + if {$device_clk == {}} { + set device_clk ${u_xcvr}/${txrx}_out_clk_${index} + set rst_gen [regsub -all "/" ${a_jesd}_rstgen "_"] + set create_rst_gen 1 + } else { + set rst_gen ${device_clk}_rstgen + # Only create one reset gen per clock + set create_rst_gen [expr {[get_bd_cells -quiet ${rst_gen}] == {}}] + } + + if {${create_rst_gen}} { + ad_ip_instance proc_sys_reset ${rst_gen} + ad_connect ${device_clk} ${rst_gen}/slowest_sync_clk + ad_connect sys_cpu_resetn ${rst_gen}/ext_reset_in + } + + for {set n 0} {$n < $no_of_lanes} {incr n} { + + set m [expr ($n + $index)] + + if {$tx_or_rx_n == 0} { + ad_connect ${a_xcvr}/up_es_${n} ${u_xcvr}/up_es_${m} + if {$jesd204_type == 0} { + ad_connect ${a_jesd}/phy_en_char_align ${u_xcvr}/${txrx}_calign_${m} + } else { + ad_connect ${a_jesd}/rxencommaalign_out ${u_xcvr}/${txrx}_calign_${m} + } + } + + if {(($m%4) == 0) && ($qpll_enable == 1)} { + ad_connect ${a_xcvr}/up_cm_${n} ${u_xcvr}/up_cm_${m} + } + + if {$lane_map != {}} { + set phys_lane [lindex $lane_map $n] + if {$phys_lane != {}} { + set phys_lane [expr $phys_lane + $index] + } + } else { + set phys_lane $m + } + + ad_connect ${a_xcvr}/up_ch_${n} ${u_xcvr}/up_${txrx}_${m} + ad_connect ${device_clk} ${u_xcvr}/${txrx}_clk_${m} + if {$phys_lane != {}} { + if {$jesd204_type == 0} { + ad_connect ${u_xcvr}/${txrx}_${phys_lane} ${a_jesd}/${txrx}_phy${n} + } else { + ad_connect ${u_xcvr}/${txrx}_${phys_lane} ${a_jesd}/gt${n}_${txrx} + } + } + + create_bd_port -dir ${data_dir} ${m_data}_${m}_p + create_bd_port -dir ${data_dir} ${m_data}_${m}_n + ad_connect ${u_xcvr}/${txrx}_${m}_p ${m_data}_${m}_p + ad_connect ${u_xcvr}/${txrx}_${m}_n ${m_data}_${m}_n + } + + if {$jesd204_type == 0} { + ad_connect ${a_jesd}/sysref $m_sysref + ad_connect ${a_jesd}/sync $m_sync + ad_connect ${device_clk} ${a_jesd}/device_clk +# if {$tx_or_rx_n == 0} { +# ad_connect ${a_xcvr}/up_status ${a_jesd}/phy_ready +# } + } else { + ad_connect ${a_jesd}/${txrx}_sysref $m_sysref + ad_connect ${a_jesd}/${txrx}_sync $m_sync + ad_connect ${device_clk} ${a_jesd}/${txrx}_core_clk + ad_connect ${a_xcvr}/up_status ${a_jesd}/${txrx}_reset_done + ad_connect ${rst_gen}/peripheral_reset ${a_jesd}/${txrx}_reset + } + + if {$tx_or_rx_n == 0} { + set xcvr_rx_index [expr ($xcvr_rx_index + $no_of_lanes)] + } + + if {$tx_or_rx_n == 1} { + set xcvr_tx_index [expr ($xcvr_tx_index + $no_of_lanes)] + } +} + +proc ad_xcvrpll {m_src m_dst} { + + foreach p_dst [get_bd_pins -quiet $m_dst] { + connect_bd_net [ad_connect_type $m_src] $p_dst + } +} + +################################################################################################### +################################################################################################### + +proc ad_mem_hp0_interconnect {p_clk p_name} { + + global sys_zynq + + if {($sys_zynq == 0) && ($p_name eq "sys_ps7/S_AXI_HP0")} {return} + if {$sys_zynq == 0} {ad_mem_hpx_interconnect "MEM" $p_clk $p_name} + if {$sys_zynq >= 1} {ad_mem_hpx_interconnect "HP0" $p_clk $p_name} +} + +proc ad_mem_hp1_interconnect {p_clk p_name} { + + global sys_zynq + + if {($sys_zynq == 0) && ($p_name eq "sys_ps7/S_AXI_HP1")} {return} + if {$sys_zynq == 0} {ad_mem_hpx_interconnect "MEM" $p_clk $p_name} + if {$sys_zynq >= 1} {ad_mem_hpx_interconnect "HP1" $p_clk $p_name} +} + +proc ad_mem_hp2_interconnect {p_clk p_name} { + + global sys_zynq + + if {($sys_zynq == 0) && ($p_name eq "sys_ps7/S_AXI_HP2")} {return} + if {$sys_zynq == 0} {ad_mem_hpx_interconnect "MEM" $p_clk $p_name} + if {$sys_zynq >= 1} {ad_mem_hpx_interconnect "HP2" $p_clk $p_name} +} + +proc ad_mem_hp3_interconnect {p_clk p_name} { + + global sys_zynq + + if {($sys_zynq == 0) && ($p_name eq "sys_ps7/S_AXI_HP3")} {return} + if {$sys_zynq == 0} {ad_mem_hpx_interconnect "MEM" $p_clk $p_name} + if {$sys_zynq >= 1} {ad_mem_hpx_interconnect "HP3" $p_clk $p_name} +} + +################################################################################################### +################################################################################################### + +proc ad_mem_hpx_interconnect {p_sel p_clk p_name} { + + global sys_zynq + global sys_ddr_addr_seg + global sys_hp0_interconnect_index + global sys_hp1_interconnect_index + global sys_hp2_interconnect_index + global sys_hp3_interconnect_index + global sys_mem_interconnect_index + + set p_name_int $p_name + set p_clk_source [get_bd_pins -filter {DIR == O} -of_objects [get_bd_nets $p_clk]] + + if {$p_sel eq "MEM"} { + if {$sys_mem_interconnect_index < 0} { + ad_ip_instance axi_interconnect axi_mem_interconnect + } + set m_interconnect_index $sys_mem_interconnect_index + set m_interconnect_cell [get_bd_cells axi_mem_interconnect] + set m_addr_seg [get_bd_addr_segs -of_objects [get_bd_cells axi_ddr_cntrl]] + } + + if {($p_sel eq "HP0") && ($sys_zynq == 1)} { + if {$sys_hp0_interconnect_index < 0} { + set p_name_int sys_ps7/S_AXI_HP0 + set_property CONFIG.PCW_USE_S_AXI_HP0 {1} [get_bd_cells sys_ps7] + ad_ip_instance axi_interconnect axi_hp0_interconnect + } + set m_interconnect_index $sys_hp0_interconnect_index + set m_interconnect_cell [get_bd_cells axi_hp0_interconnect] + set m_addr_seg [get_bd_addr_segs sys_ps7/S_AXI_HP0/HP0_DDR_LOWOCM] + } + + if {($p_sel eq "HP1") && ($sys_zynq == 1)} { + if {$sys_hp1_interconnect_index < 0} { + set p_name_int sys_ps7/S_AXI_HP1 + set_property CONFIG.PCW_USE_S_AXI_HP1 {1} [get_bd_cells sys_ps7] + ad_ip_instance axi_interconnect axi_hp1_interconnect + } + set m_interconnect_index $sys_hp1_interconnect_index + set m_interconnect_cell [get_bd_cells axi_hp1_interconnect] + set m_addr_seg [get_bd_addr_segs sys_ps7/S_AXI_HP1/HP1_DDR_LOWOCM] + } + + if {($p_sel eq "HP2") && ($sys_zynq == 1)} { + if {$sys_hp2_interconnect_index < 0} { + set p_name_int sys_ps7/S_AXI_HP2 + set_property CONFIG.PCW_USE_S_AXI_HP2 {1} [get_bd_cells sys_ps7] + ad_ip_instance axi_interconnect axi_hp2_interconnect + } + set m_interconnect_index $sys_hp2_interconnect_index + set m_interconnect_cell [get_bd_cells axi_hp2_interconnect] + set m_addr_seg [get_bd_addr_segs sys_ps7/S_AXI_HP2/HP2_DDR_LOWOCM] + } + + if {($p_sel eq "HP3") && ($sys_zynq == 1)} { + if {$sys_hp3_interconnect_index < 0} { + set p_name_int sys_ps7/S_AXI_HP3 + set_property CONFIG.PCW_USE_S_AXI_HP3 {1} [get_bd_cells sys_ps7] + ad_ip_instance axi_interconnect axi_hp3_interconnect + } + set m_interconnect_index $sys_hp3_interconnect_index + set m_interconnect_cell [get_bd_cells axi_hp3_interconnect] + set m_addr_seg [get_bd_addr_segs sys_ps7/S_AXI_HP3/HP3_DDR_LOWOCM] + } + + if {($p_sel eq "HP0") && ($sys_zynq == 2)} { + if {$sys_hp0_interconnect_index < 0} { + set p_name_int sys_ps8/S_AXI_HP0_FPD + set_property CONFIG.PSU__USE__S_AXI_GP2 {1} [get_bd_cells sys_ps8] + ad_ip_instance axi_interconnect axi_hp0_interconnect + } + set m_interconnect_index $sys_hp0_interconnect_index + set m_interconnect_cell [get_bd_cells axi_hp0_interconnect] + set m_addr_seg [get_bd_addr_segs sys_ps8/S_AXI_HP0_FPD/PLLPD_DDR_LOW] + } + + if {($p_sel eq "HP1") && ($sys_zynq == 2)} { + if {$sys_hp1_interconnect_index < 0} { + set p_name_int sys_ps8/S_AXI_HP1_FPD + set_property CONFIG.PSU__USE__S_AXI_GP3 {1} [get_bd_cells sys_ps8] + ad_ip_instance axi_interconnect axi_hp1_interconnect + } + set m_interconnect_index $sys_hp1_interconnect_index + set m_interconnect_cell [get_bd_cells axi_hp1_interconnect] + set m_addr_seg [get_bd_addr_segs sys_ps8/S_AXI_HP1_FPD/HP0_DDR_LOW] + } + + if {($p_sel eq "HP2") && ($sys_zynq == 2)} { + if {$sys_hp2_interconnect_index < 0} { + set p_name_int sys_ps8/S_AXI_HP2_FPD + set_property CONFIG.PSU__USE__S_AXI_GP4 {1} [get_bd_cells sys_ps8] + ad_ip_instance axi_interconnect axi_hp2_interconnect + } + set m_interconnect_index $sys_hp2_interconnect_index + set m_interconnect_cell [get_bd_cells axi_hp2_interconnect] + set m_addr_seg [get_bd_addr_segs sys_ps8/S_AXI_HP2_FPD/HP1_DDR_LOW] + } + + if {($p_sel eq "HP3") && ($sys_zynq == 2)} { + if {$sys_hp3_interconnect_index < 0} { + set p_name_int sys_ps8/S_AXI_HP3_FPD + set_property CONFIG.PSU__USE__S_AXI_GP5 {1} [get_bd_cells sys_ps8] + ad_ip_instance axi_interconnect axi_hp3_interconnect + } + set m_interconnect_index $sys_hp3_interconnect_index + set m_interconnect_cell [get_bd_cells axi_hp3_interconnect] + set m_addr_seg [get_bd_addr_segs sys_ps8/S_AXI_HP3_FPD/HP2_DDR_LOW] + } + + set i_str "S$m_interconnect_index" + if {$m_interconnect_index < 10} { + set i_str "S0$m_interconnect_index" + } + + set m_interconnect_index [expr $m_interconnect_index + 1] + + set p_intf_name [lrange [split $p_name_int "/"] end end] + set p_cell_name [lrange [split $p_name_int "/"] 0 0] + set p_intf_clock [get_bd_pins -filter "TYPE == clk && (CONFIG.ASSOCIATED_BUSIF == ${p_intf_name} || \ + CONFIG.ASSOCIATED_BUSIF =~ ${p_intf_name}:* || CONFIG.ASSOCIATED_BUSIF =~ *:${p_intf_name} || \ + CONFIG.ASSOCIATED_BUSIF =~ *:${p_intf_name}:*)" -quiet -of_objects [get_bd_cells $p_cell_name]] + if {[find_bd_objs -quiet -relation connected_to $p_intf_clock] ne "" || + $p_intf_clock eq $p_clk_source} { + set p_intf_clock "" + } + + regsub clk $p_clk resetn p_rst + if {[get_bd_nets -quiet $p_rst] eq ""} { + set p_rst sys_cpu_resetn + } + + if {$m_interconnect_index == 0} { + set_property CONFIG.NUM_MI 1 $m_interconnect_cell + set_property CONFIG.NUM_SI 1 $m_interconnect_cell + ad_connect $p_rst $m_interconnect_cell/ARESETN + ad_connect $p_clk $m_interconnect_cell/ACLK + ad_connect $p_rst $m_interconnect_cell/M00_ARESETN + ad_connect $p_clk $m_interconnect_cell/M00_ACLK + ad_connect $m_interconnect_cell/M00_AXI $p_name_int + if {$p_intf_clock ne ""} { + ad_connect $p_clk $p_intf_clock + } + } else { + set_property CONFIG.NUM_SI $m_interconnect_index $m_interconnect_cell + ad_connect $p_rst $m_interconnect_cell/${i_str}_ARESETN + ad_connect $p_clk $m_interconnect_cell/${i_str}_ACLK + ad_connect $m_interconnect_cell/${i_str}_AXI $p_name_int + if {$p_intf_clock ne ""} { + ad_connect $p_clk $p_intf_clock + } + assign_bd_address $m_addr_seg + } + + if {$m_interconnect_index > 1} { + set_property CONFIG.STRATEGY {2} $m_interconnect_cell + } + + if {$p_sel eq "MEM"} {set sys_mem_interconnect_index $m_interconnect_index} + if {$p_sel eq "HP0"} {set sys_hp0_interconnect_index $m_interconnect_index} + if {$p_sel eq "HP1"} {set sys_hp1_interconnect_index $m_interconnect_index} + if {$p_sel eq "HP2"} {set sys_hp2_interconnect_index $m_interconnect_index} + if {$p_sel eq "HP3"} {set sys_hp3_interconnect_index $m_interconnect_index} + +} + +################################################################################################### +################################################################################################### + +proc ad_cpu_interconnect {p_address p_name} { + + global sys_zynq + global sys_cpu_interconnect_index + + set i_str "M$sys_cpu_interconnect_index" + if {$sys_cpu_interconnect_index < 10} { + set i_str "M0$sys_cpu_interconnect_index" + } + + if {$sys_cpu_interconnect_index == 0} { + ad_ip_instance axi_interconnect axi_cpu_interconnect + if {$sys_zynq == 2} { + ad_connect sys_cpu_clk sys_ps8/maxihpm0_lpd_aclk + ad_connect sys_cpu_clk axi_cpu_interconnect/ACLK + ad_connect sys_cpu_clk axi_cpu_interconnect/S00_ACLK + ad_connect sys_cpu_resetn axi_cpu_interconnect/ARESETN + ad_connect sys_cpu_resetn axi_cpu_interconnect/S00_ARESETN + ad_connect axi_cpu_interconnect/S00_AXI sys_ps8/M_AXI_HPM0_LPD + } + if {$sys_zynq == 1} { + ad_connect sys_cpu_clk sys_ps7/M_AXI_GP0_ACLK + ad_connect sys_cpu_clk axi_cpu_interconnect/ACLK + ad_connect sys_cpu_clk axi_cpu_interconnect/S00_ACLK + ad_connect sys_cpu_resetn axi_cpu_interconnect/ARESETN + ad_connect sys_cpu_resetn axi_cpu_interconnect/S00_ARESETN + ad_connect axi_cpu_interconnect/S00_AXI sys_ps7/M_AXI_GP0 + } + if {$sys_zynq == 0} { + ad_connect sys_cpu_clk axi_cpu_interconnect/ACLK + ad_connect sys_cpu_clk axi_cpu_interconnect/S00_ACLK + ad_connect sys_cpu_resetn axi_cpu_interconnect/ARESETN + ad_connect sys_cpu_resetn axi_cpu_interconnect/S00_ARESETN + ad_connect axi_cpu_interconnect/S00_AXI sys_mb/M_AXI_DP + } + } + + if {$sys_zynq == 2} { + set sys_addr_cntrl_space [get_bd_addr_spaces sys_ps8/Data] + } + if {$sys_zynq == 1} { + set sys_addr_cntrl_space [get_bd_addr_spaces sys_ps7/Data] + } + if {$sys_zynq == 0} { + set sys_addr_cntrl_space [get_bd_addr_spaces sys_mb/Data] + } + + set sys_cpu_interconnect_index [expr $sys_cpu_interconnect_index + 1] + + + set p_cell [get_bd_cells $p_name] + set p_intf [get_bd_intf_pins -filter "MODE == Slave && VLNV == xilinx.com:interface:aximm_rtl:1.0"\ + -of_objects $p_cell] + + set p_hier_cell $p_cell + set p_hier_intf $p_intf + + while {$p_hier_intf != "" && [get_property TYPE $p_hier_cell] == "hier"} { + set p_hier_intf [find_bd_objs -boundary_type lower \ + -relation connected_to $p_hier_intf] + if {$p_hier_intf != {}} { + set p_hier_cell [get_bd_cells -of_objects $p_hier_intf] + } else { + set p_hier_cell {} + } + } + + set p_intf_clock "" + set p_intf_reset "" + + if {$p_hier_cell != {}} { + set p_intf_name [lrange [split $p_hier_intf "/"] end end] + + set p_intf_clock [get_bd_pins -filter "TYPE == clk && \ + (CONFIG.ASSOCIATED_BUSIF == ${p_intf_name} || \ + CONFIG.ASSOCIATED_BUSIF =~ ${p_intf_name}:* || \ + CONFIG.ASSOCIATED_BUSIF =~ *:${p_intf_name} || \ + CONFIG.ASSOCIATED_BUSIF =~ *:${p_intf_name}:*)" \ + -quiet -of_objects $p_hier_cell] + set p_intf_reset [get_bd_pins -filter "TYPE == rst && \ + (CONFIG.ASSOCIATED_BUSIF == ${p_intf_name} || \ + CONFIG.ASSOCIATED_BUSIF =~ ${p_intf_name}:* || + CONFIG.ASSOCIATED_BUSIF =~ *:${p_intf_name} || \ + CONFIG.ASSOCIATED_BUSIF =~ *:${p_intf_name}:*)" \ + -quiet -of_objects $p_hier_cell] + + if {($p_intf_clock ne "") && ($p_intf_reset eq "")} { + set p_intf_reset [get_property CONFIG.ASSOCIATED_RESET [get_bd_pins ${p_intf_clock}]] + if {$p_intf_reset ne ""} { + set p_intf_reset [get_bd_pins -filter "NAME == $p_intf_reset" -of_objects $p_hier_cell] + } + } + + # Trace back up + set p_hier_cell2 $p_hier_cell + + while {$p_intf_clock != {} && $p_hier_cell2 != $p_cell && $p_hier_cell2 != {}} { + puts $p_intf_clock + puts $p_hier_cell2 + set p_intf_clock [find_bd_objs -boundary_type upper \ + -relation connected_to $p_intf_clock] + if {$p_intf_clock != {}} { + set p_intf_clock [get_bd_pins [get_property PATH $p_intf_clock]] + set p_hier_cell2 [get_bd_cells -of_objects $p_intf_clock] + } + } + + set p_hier_cell2 $p_hier_cell + + while {$p_intf_reset != {} && $p_hier_cell2 != $p_cell && $p_hier_cell2 != {}} { + set p_intf_reset [find_bd_objs -boundary_type upper \ + -relation connected_to $p_intf_reset] + if {$p_intf_reset != {}} { + set p_intf_reset [get_bd_pins [get_property PATH $p_intf_reset]] + set p_hier_cell2 [get_bd_cells -of_objects $p_intf_reset] + } + } + } + + + if {[find_bd_objs -quiet -relation connected_to $p_intf_clock] ne ""} { + set p_intf_clock "" + } + if {$p_intf_reset ne ""} { + if {[find_bd_objs -quiet -relation connected_to $p_intf_reset] ne ""} { + set p_intf_reset "" + } + } + + set_property CONFIG.NUM_MI $sys_cpu_interconnect_index [get_bd_cells axi_cpu_interconnect] + + ad_connect sys_cpu_clk axi_cpu_interconnect/${i_str}_ACLK + if {$p_intf_clock ne ""} { + ad_connect sys_cpu_clk ${p_intf_clock} + } + ad_connect sys_cpu_resetn axi_cpu_interconnect/${i_str}_ARESETN + if {$p_intf_reset ne ""} { + ad_connect sys_cpu_resetn ${p_intf_reset} + } + ad_connect axi_cpu_interconnect/${i_str}_AXI ${p_intf} + + set p_seg [get_bd_addr_segs -of_objects $p_hier_cell] + set p_index 0 + foreach p_seg_name $p_seg { + if {$p_index == 0} { + set p_seg_range [get_property range $p_seg_name] + if {$p_seg_range < 0x1000} { + set p_seg_range 0x1000 + } + if {$sys_zynq == 2} { + if {($p_address >= 0x40000000) && ($p_address <= 0x4fffffff)} { + set p_address [expr ($p_address + 0x40000000)] + } + if {($p_address >= 0x70000000) && ($p_address <= 0x7fffffff)} { + set p_address [expr ($p_address + 0x20000000)] + } + } + create_bd_addr_seg -range $p_seg_range \ + -offset $p_address $sys_addr_cntrl_space \ + $p_seg_name "SEG_data_${p_name}" + } else { + assign_bd_address $p_seg_name + } + incr p_index + } +} + +################################################################################################### +################################################################################################### + +proc ad_cpu_interrupt {p_ps_index p_mb_index p_name} { + + global sys_zynq + + if {$sys_zynq == 0} {set p_index_int $p_mb_index} + if {$sys_zynq >= 1} {set p_index_int $p_ps_index} + + set p_index [regsub -all {[^0-9]} $p_index_int ""] + set m_index [expr ($p_index - 8)] + + if {($sys_zynq == 2) && ($p_index <= 7)} { + set p_net [get_bd_nets -of_objects [get_bd_pins sys_concat_intc_0/In$p_index]] + set p_pin [get_bd_pins sys_concat_intc_0/In$p_index] + + puts "disconnect_bd_net $p_net $p_pin" + disconnect_bd_net $p_net $p_pin + ad_connect sys_concat_intc_0/In$p_index $p_name + } + + if {($sys_zynq == 2) && ($p_index >= 8)} { + set p_net [get_bd_nets -of_objects [get_bd_pins sys_concat_intc_1/In$m_index]] + set p_pin [get_bd_pins sys_concat_intc_1/In$m_index] + + puts "disconnect_bd_net $p_net $p_pin" + disconnect_bd_net $p_net $p_pin + ad_connect sys_concat_intc_1/In$m_index $p_name + } + + if {$sys_zynq <= 1} { + + set p_net [get_bd_nets -of_objects [get_bd_pins sys_concat_intc/In$p_index]] + set p_pin [get_bd_pins sys_concat_intc/In$p_index] + + puts "disconnect_bd_net $p_net $p_pin" + disconnect_bd_net $p_net $p_pin + ad_connect sys_concat_intc/In$p_index $p_name + } +} + +################################################################################################### +################################################################################################### + diff --git a/src/adi/hdl/projects/scripts/adi_env.tcl b/src/adi/hdl/projects/scripts/adi_env.tcl new file mode 100644 index 00000000..361e8858 --- /dev/null +++ b/src/adi/hdl/projects/scripts/adi_env.tcl @@ -0,0 +1,15 @@ + +# environment related stuff + +set ad_hdl_dir [file normalize [file join [file dirname [info script]] "../.."]] +set ad_phdl_dir $ad_hdl_dir + + +if [info exists ::env(ADI_HDL_DIR)] { + set ad_hdl_dir [file normalize $::env(ADI_HDL_DIR)] +} + +if [info exists ::env(ADI_PHDL_DIR)] { + set ad_phdl_dir [file normalize $::env(ADI_PHDL_DIR)] +} + diff --git a/src/adi/hdl/projects/scripts/adi_project.tcl b/src/adi/hdl/projects/scripts/adi_project.tcl new file mode 100644 index 00000000..62d949e2 --- /dev/null +++ b/src/adi/hdl/projects/scripts/adi_project.tcl @@ -0,0 +1,289 @@ + +variable p_board +variable p_device +variable sys_zynq +variable p_prcfg_init +variable p_prcfg_list +variable p_prcfg_status + +if {![info exists REQUIRED_VIVADO_VERSION]} { + set REQUIRED_VIVADO_VERSION "2018.2" +} + +if {[info exists ::env(ADI_IGNORE_VERSION_CHECK)]} { + set IGNORE_VERSION_CHECK 1 +} elseif {![info exists IGNORE_VERSION_CHECK]} { + set IGNORE_VERSION_CHECK 0 +} + +set p_board "not-applicable" +set p_device "none" +set sys_zynq 1 +set ADI_POWER_OPTIMIZATION 0 + +proc adi_project_xilinx {project_name {mode 0}} { + + global ad_hdl_dir + global ad_phdl_dir + global p_board + global p_device + global sys_zynq + global REQUIRED_VIVADO_VERSION + global IGNORE_VERSION_CHECK + + if [regexp "_ac701$" $project_name] { + set p_device "xc7a200tfbg676-2" + set p_board "xilinx.com:ac701:part0:1.0" + set sys_zynq 0 + } + if [regexp "_kc705$" $project_name] { + set p_device "xc7k325tffg900-2" + set p_board "xilinx.com:kc705:part0:1.1" + set sys_zynq 0 + } + if [regexp "_vc707$" $project_name] { + set p_device "xc7vx485tffg1761-2" + set p_board "xilinx.com:vc707:part0:1.1" + set sys_zynq 0 + } + if [regexp "_kcu105$" $project_name] { + set p_device "xcku040-ffva1156-2-e" + set p_board "xilinx.com:kcu105:part0:1.1" + set sys_zynq 0 + } + if [regexp "_zed$" $project_name] { + set p_device "xc7z020clg484-1" + set p_board "em.avnet.com:zed:part0:1.3" + set sys_zynq 1 + } + if [regexp "_microzed$" $project_name] { + set p_device "xc7z010clg400-1" + set p_board "not-applicable" + set sys_zynq 1 + } + if [regexp "_zc702$" $project_name] { + set p_device "xc7z020clg484-1" + set p_board "xilinx.com:zc702:part0:1.2" + set sys_zynq 1 + } + if [regexp "_zc706$" $project_name] { + set p_device "xc7z045ffg900-2" + set p_board "xilinx.com:zc706:part0:1.2" + set sys_zynq 1 + } + if [regexp "_mitx045$" $project_name] { + set p_device "xc7z045ffg900-2" + set p_board "not-applicable" + set sys_zynq 1 + } + if [regexp "_zcu102$" $project_name] { + set p_device "xczu9eg-ffvb1156-2-e" + set p_board "xilinx.com:zcu102:part0:3.2" + set sys_zynq 2 + } + + set VIVADO_VERSION [version -short] + if {[string compare $VIVADO_VERSION $REQUIRED_VIVADO_VERSION] != 0} { + puts -nonewline "CRITICAL WARNING: vivado version mismatch; " + puts -nonewline "expected $REQUIRED_VIVADO_VERSION, " + puts -nonewline "got $VIVADO_VERSION.\n" + } + + if {$mode == 0} { + set project_system_dir "./$project_name.srcs/sources_1/bd/system" + create_project $project_name . -part $p_device -force + } else { + set project_system_dir ".srcs/sources_1/bd/system" + create_project -in_memory -part $p_device + } + + if {$mode == 1} { + file mkdir $project_name.data + } + + if {$p_board ne "not-applicable"} { + set_property board_part $p_board [current_project] + } + + set lib_dirs $ad_hdl_dir/library + if {$ad_hdl_dir ne $ad_phdl_dir} { + lappend lib_dirs $ad_phdl_dir/library + } + + set_property ip_repo_paths $lib_dirs [current_fileset] + update_ip_catalog + + ## Load custom message severity definitions + source $ad_hdl_dir/projects/scripts/adi_xilinx_msg.tcl + + ## In Vivado there is a limit for the number of warnings and errors which are + ## displayed by the tool for a particular error or warning; the default value + ## of this limit is 100. + ## Overrides the default limit to 2000. + set_param messaging.defaultLimit 2000 + + create_bd_design "system" + source system_bd.tcl + + save_bd_design + validate_bd_design + + set_property synth_checkpoint_mode None [get_files $project_system_dir/system.bd] + generate_target {synthesis implementation} [get_files $project_system_dir/system.bd] + make_wrapper -files [get_files $project_system_dir/system.bd] -top + + if {$mode == 0} { + import_files -force -norecurse -fileset sources_1 $project_system_dir/hdl/system_wrapper.v + } else { + write_hwdef -file "$project_name.data/$project_name.hwdef" + } +} + +proc adi_project_files {project_name project_files} { + + add_files -norecurse -fileset sources_1 $project_files + set_property top system_top [current_fileset] +} + +proc adi_project_run {project_name} { + global ADI_POWER_OPTIMIZATION + + launch_runs synth_1 + wait_on_run synth_1 + open_run synth_1 + report_timing_summary -file timing_synth.log + + if {![info exists ::env(ADI_NO_BITSTREAM_COMPRESSION)] && ![info exists ADI_NO_BITSTREAM_COMPRESSION]} { + set_property BITSTREAM.GENERAL.COMPRESS TRUE [current_design] + } + + if {$ADI_POWER_OPTIMIZATION == 1} { + set_property STEPS.POWER_OPT_DESIGN.IS_ENABLED true [get_runs impl_1] + set_property STEPS.POST_PLACE_POWER_OPT_DESIGN.IS_ENABLED true [get_runs impl_1] + } + + launch_runs impl_1 -to_step write_bitstream + wait_on_run impl_1 + open_run impl_1 + report_timing_summary -file timing_impl.log + + file mkdir $project_name.sdk + + if [expr [get_property SLACK [get_timing_paths]] < 0] { + file copy -force $project_name.runs/impl_1/system_top.sysdef $project_name.sdk/system_top_bad_timing.hdf + } else { + file copy -force $project_name.runs/impl_1/system_top.sysdef $project_name.sdk/system_top.hdf + } + + if [expr [get_property SLACK [get_timing_paths]] < 0] { + return -code error [format "ERROR: Timing Constraints NOT met!"] + } +} + +proc adi_project_synth {project_name prcfg_name hdl_files {xdc_files ""}} { + + global p_device + + set p_prefix "$project_name.data/$project_name" + + if {$prcfg_name eq ""} { + + read_verilog .srcs/sources_1/bd/system/hdl/system_wrapper.v + read_verilog $hdl_files + read_xdc $xdc_files + + synth_design -mode default -top system_top -part $p_device > $p_prefix.synth.rds + write_checkpoint -force $p_prefix.synth.dcp + close_project + + } else { + + create_project -in_memory -part $p_device + read_verilog $hdl_files + synth_design -mode out_of_context -top "prcfg" -part $p_device > $p_prefix.${prcfg_name}_synth.rds + write_checkpoint -force $p_prefix.${prcfg_name}_synth.dcp + close_project + } +} + +proc adi_project_impl {project_name prcfg_name {xdc_files ""}} { + + global p_device + global p_prcfg_init + global p_prcfg_list + global p_prcfg_status + + set p_prefix "$project_name.data/$project_name" + + if {$prcfg_name eq "default"} { + set p_prcfg_status 0 + set p_prcfg_list "" + set p_prcfg_init "$p_prefix.${prcfg_name}_impl.dcp" + file mkdir $project_name.sdk + } + + if {$prcfg_name eq "default"} { + + open_checkpoint $p_prefix.synth.dcp -part $p_device + read_xdc $xdc_files + read_checkpoint -cell i_prcfg $p_prefix.${prcfg_name}_synth.dcp + set_property HD.RECONFIGURABLE 1 [get_cells i_prcfg] + opt_design > $p_prefix.${prcfg_name}_opt.rds + write_debug_probes -force $p_prefix.${prcfg_name}_debug_nets.ltx + place_design > $p_prefix.${prcfg_name}_place.rds + route_design > $p_prefix.${prcfg_name}_route.rds + + } else { + + open_checkpoint $p_prefix.default_impl_bb.dcp -part $p_device + lock_design -level routing + read_checkpoint -cell i_prcfg $p_prefix.${prcfg_name}_synth.dcp + read_xdc $xdc_files + opt_design > $p_prefix.${prcfg_name}_opt.rds + place_design > $p_prefix.${prcfg_name}_place.rds + route_design > $p_prefix.${prcfg_name}_route.rds + } + + write_checkpoint -force $p_prefix.${prcfg_name}_impl.dcp + report_utilization -pblocks pb_prcfg -file $p_prefix.${prcfg_name}_utilization.rpt + report_timing_summary -file $p_prefix.${prcfg_name}_timing_summary.rpt + + if [expr [get_property SLACK [get_timing_paths]] < 0] { + set p_prcfg_status 1 + puts "CRITICAL WARNING: Timing Constraints NOT met ($prcfg_name)!" + } + + write_checkpoint -force -cell i_prcfg $p_prefix.${prcfg_name}_prcfg_impl.dcp + update_design -cell i_prcfg -black_box + write_checkpoint -force $p_prefix.${prcfg_name}_impl_bb.dcp + open_checkpoint $p_prefix.${prcfg_name}_impl.dcp -part $p_device + write_bitstream -force -bin_file -file $p_prefix.${prcfg_name}.bit + write_sysdef -hwdef $p_prefix.hwdef -bitfile $p_prefix.${prcfg_name}.bit -file $p_prefix.${prcfg_name}.hdf + file copy -force $p_prefix.${prcfg_name}.hdf $project_name.sdk/system_top.${prcfg_name}.hdf + + if {$prcfg_name ne "default"} { + lappend p_prcfg_list "$p_prefix.${prcfg_name}_impl.dcp" + } + + if {$prcfg_name eq "default"} { + file copy -force $p_prefix.${prcfg_name}.hdf $project_name.sdk/system_top.hdf + } +} + +proc adi_project_verify {project_name} { + + global p_prcfg_init + global p_prcfg_list + global p_prcfg_status + + set p_prefix "$project_name.data/$project_name" + + pr_verify -full_check -initial $p_prcfg_init \ + -additional $p_prcfg_list \ + -file $p_prefix.prcfg_verify.log + + if {$p_prcfg_status == 1} { + return -code error [format "ERROR: Timing Constraints NOT met!"] + } +} + diff --git a/src/adi/hdl/projects/scripts/adi_project_alt.tcl b/src/adi/hdl/projects/scripts/adi_project_alt.tcl new file mode 100644 index 00000000..2e7bb344 --- /dev/null +++ b/src/adi/hdl/projects/scripts/adi_project_alt.tcl @@ -0,0 +1,156 @@ + +variable family +variable device +variable version + +set family "none" +set device "none" +set version "18.0.0" + +proc adi_project_altera {project_name} { + + global ad_hdl_dir + global ad_phdl_dir + global family + global device + global version + global quartus + + if [regexp "_a10gx$" $project_name] { + set family "Arria 10" + set device 10AX115S2F45I1SG + set system_qip_file system_bd/system_bd.qip + } + + if [regexp "_a10soc$" $project_name] { + set family "Arria 10" + set device 10AS066N3F40E2SG + set system_qip_file system_bd/system_bd.qip + } + + if [regexp "_c5soc$" $project_name] { + set family "Cyclone V" + set device 5CSXFC6D6F31C8ES + set system_qip_file system_bd/synthesis/system_bd.qip + } + + if [regexp "de10nano$" $project_name] { + set family "Cyclone V" + set device 5CSEBA6U23I7DK + set system_qip_file system_bd/synthesis/system_bd.qip + } + + if [regexp "_a5soc$" $project_name] { + set family "Arria V" + set device 5ASTFD5K3F40I3ES + set system_qip_file system_bd/synthesis/system_bd.qip + } + + if [regexp "_a5gt$" $project_name] { + set family "Arria V" + set device 5AGTFD7K3F40I3 + set system_qip_file system_bd/synthesis/system_bd.qip + } + + # version check + + set m_version [lindex $quartus(version) 1] + if {[string compare $m_version $version] != 0} { + puts -nonewline "Critical Warning: quartus version mismatch; " + puts -nonewline "expected $version, " + puts -nonewline "got $m_version.\n" + } + + # packages used + + load_package flow + + # project + + project_new $project_name -overwrite + + # library paths + + set ad_lib_folders "$ad_hdl_dir/library/**/*;$ad_phdl_dir/library/**/*" + + set_user_option -name USER_IP_SEARCH_PATHS $ad_lib_folders + set_global_assignment -name IP_SEARCH_PATHS $ad_lib_folders + + # project & qsys + + set_global_assignment -name FAMILY $family + set_global_assignment -name DEVICE $device + + # qsys + + set mmu_enabled 1 + if [info exists ::env(ALT_NIOS_MMU_ENABLED)] { + set mmu_enabled $::env(ALT_NIOS_MMU_ENABLED) + } + + set QFILE [open "system_qsys_script.tcl" "w"] + puts $QFILE "set mmu_enabled $mmu_enabled" + puts $QFILE "set ad_hdl_dir $ad_hdl_dir" + puts $QFILE "set ad_phdl_dir $ad_phdl_dir" + puts $QFILE "package require qsys" + puts $QFILE "set_module_property NAME {system_bd}" + puts $QFILE "set_project_property DEVICE_FAMILY {$family}" + puts $QFILE "set_project_property DEVICE $device" + puts $QFILE "source system_qsys.tcl" + puts $QFILE "set_interconnect_requirement {\$system} {qsys_mm.clockCrossingAdapter} {AUTO}" + puts $QFILE "set_interconnect_requirement {\$system} {qsys_mm.burstAdapterImplementation} {PER_BURST_TYPE_CONVERTER}" + puts $QFILE "set_interconnect_requirement {\$system} {qsys_mm.maxAdditionalLatency} {4}" + puts $QFILE "save_system {system_bd.qsys}" + close $QFILE + + exec -ignorestderr $quartus(quartus_rootpath)/sopc_builder/bin/qsys-script \ + --script=system_qsys_script.tcl + exec -ignorestderr $quartus(quartus_rootpath)/sopc_builder/bin/qsys-generate \ + system_bd.qsys --synthesis=VERILOG --output-directory=system_bd \ + --family=$family --part=$device + + # ignored warnings and such + + set_global_assignment -name MESSAGE_DISABLE 17951 ; ## unused RX channels + set_global_assignment -name MESSAGE_DISABLE 18655 ; ## unused TX channels + set_global_assignment -name MESSAGE_DISABLE 114001 ; ## Time value $x truncated to $y + + # The Merlin cores are especially spammy, lets hope non of these warnings is + # an actual issue... + foreach entity {altera_merlin_axi_master_ni altera_merlin_axi_slave_ni \ + altera_merlin_traffic_limiter altera_merlin_burst_adapter_new} { + ## truncated value + set_instance_assignment -name MESSAGE_DISABLE 10230 -entity $entity + } + ## assigned a value but never read + set_instance_assignment -name MESSAGE_DISABLE 10036 -entity altera_merlin_burst_adapter_new + + # default assignments + + set_global_assignment -name QIP_FILE $system_qip_file + set_global_assignment -name VERILOG_FILE system_top.v + set_global_assignment -name SDC_FILE system_constr.sdc + set_global_assignment -name TOP_LEVEL_ENTITY system_top + + # remove altshift_taps + + set_instance_assignment -name AUTO_SHIFT_REGISTER_RECOGNITION OFF -to * -entity up_xfer_cntrl + set_instance_assignment -name AUTO_SHIFT_REGISTER_RECOGNITION OFF -to * -entity up_xfer_status + set_instance_assignment -name AUTO_SHIFT_REGISTER_RECOGNITION OFF -to * -entity up_clock_mon + set_instance_assignment -name AUTO_SHIFT_REGISTER_RECOGNITION OFF -to * -entity ad_rst + set_instance_assignment -name QII_AUTO_PACKED_REGISTERS OFF -to * -entity up_xfer_cntrl + set_instance_assignment -name QII_AUTO_PACKED_REGISTERS OFF -to * -entity up_xfer_status + set_instance_assignment -name QII_AUTO_PACKED_REGISTERS OFF -to * -entity up_clock_mon + set_instance_assignment -name QII_AUTO_PACKED_REGISTERS OFF -to * -entity ad_rst + + # globals + + set_global_assignment -name SYNCHRONIZER_IDENTIFICATION AUTO + set_global_assignment -name ENABLE_ADVANCED_IO_TIMING ON + set_global_assignment -name USE_TIMEQUEST_TIMING_ANALYZER ON + set_global_assignment -name TIMEQUEST_DO_REPORT_TIMING ON + set_global_assignment -name TIMEQUEST_DO_CCPP_REMOVAL ON + set_global_assignment -name TIMEQUEST_REPORT_SCRIPT $ad_hdl_dir/projects/scripts/adi_tquest.tcl + set_global_assignment -name ON_CHIP_BITSTREAM_DECOMPRESSION OFF +} + diff --git a/src/adi/hdl/projects/scripts/adi_tquest.tcl b/src/adi/hdl/projects/scripts/adi_tquest.tcl new file mode 100644 index 00000000..be50c76b --- /dev/null +++ b/src/adi/hdl/projects/scripts/adi_tquest.tcl @@ -0,0 +1,41 @@ + +report_timing -detail full_path -npaths 20 -setup -file timing_impl.log +report_timing -detail full_path -npaths 20 -hold -append -file timing_impl.log +report_timing -detail full_path -npaths 20 -recovery -append -file timing_impl.log +report_timing -detail full_path -npaths 20 -removal -append -file timing_impl.log + +set worst_path [get_timing_paths -npaths 1 -setup] +foreach_in_collection path $worst_path { + set slack [get_path_info $path -slack] +} + +if {$slack > 0} { + set worst_path [get_timing_paths -npaths 1 -hold] + foreach_in_collection path $worst_path { + set slack [get_path_info $path -slack] + } +} + +if {$slack > 0} { + set worst_path [get_timing_paths -npaths 1 -recovery] + foreach_in_collection path $worst_path { + set slack [get_path_info $path -slack] + } +} + +if {$slack > 0} { + set worst_path [get_timing_paths -npaths 1 -removal] + foreach_in_collection path $worst_path { + set slack [get_path_info $path -slack] + } +} + +if {$slack < 0} { + set sof_files [glob *.sof] + foreach sof_file $sof_files { + set root_sof_file [file rootname $sof_file] + set new_sof_file [append root_sof_file "_timing.sof"] + file rename -force $sof_file $new_sof_file + } + return -code error [format "ERROR: Timing Constraints NOT met!"] +} diff --git a/src/adi/hdl/projects/scripts/adi_xilinx_msg.tcl b/src/adi/hdl/projects/scripts/adi_xilinx_msg.tcl new file mode 100644 index 00000000..212d6e33 --- /dev/null +++ b/src/adi/hdl/projects/scripts/adi_xilinx_msg.tcl @@ -0,0 +1,107 @@ + +################################################################################ +## This file contains all the message severity changes for Vivado 20xx.x.x +## These should reviewed at each release and updated if necessary + +## A MUST: Every severity change must have a well defined and described role +## or purpose, and contains the instance of the original message. The main target +## here is to clean the log file from invalid CRITICAL WARNINGS. +## +## User should never change a CRITICAL WARNING to INFO, just to WARNING! + +## This file is source in two places: +# +## at ~/hdl/library/scripts/adi_ip.tcl +## and +## at ~/hdl/projects/scripts/adi_project.tcl +## +################################################################################ + +################################################################################ +## Tool related messages +## IDs : [Vivado 12-xxxx] +################################################################################ + +## For all projects which has SGMII, the tool presumes that we want ot use the +## eth_avb IP too, and because we don't have any license for it, thoughs out a +## CRITICAL WARNING. Downgrade this critical warning to a simple warning. +set_msg_config -id {Vivado 12-1790} -string "Evaluation features should NOT be used in production systems." -new_severity WARNING + +################################################################################ +## Block Design related messages +## IDs : [BD 41-xxxx] +################################################################################ + +## Temporally disabled - could not find and message with this ID +## set_msg_config -id {BD 41-1348} -new_severity WARNING + +## Reset pin A (associated clock X) is connected to reset source B (associated +## clock Y) -- this is a reset transfer between two clock domain, it should stay +## CRITICAL -- needs to be reviewed +set_msg_config -id {BD 41-1343} -new_severity WARNING + +## The connection to interface pin A is being overridden by the user. This pin +## will not be connected as a part of interface connection B (pin A is part of +## the B interface) +## In the future this should disappear, as we switch to using mostly interfaces +set_msg_config -id {BD 41-1306} -new_severity WARNING + +## Cannot set the parameter XXXXXX. It is read-only. | Parameter does not exist. +## To make sure that each and every IP is configured correctly we push this +## CRITICAL WARNING into the ERRORs domain. +set_msg_config -severity {CRITICAL WARNING} -quiet -id {BD 41-1276} -new_severity ERROR + +################################################################################ +## IP packaging and flow related messages [IP_Flow xx-xxxx] +## IDs : [IP_Flow 19-xxxx] +################################################################################ + +## Temporally disabled - could not find and message with this ID +## set_msg_config -id {IP_Flow 19-1687} -new_severity WARNING + +## If you move the project, the path for repository '~/hdl/library' may become +## invalid. A better location for the repository would be in a path adjacent to +## the project. -- Vivado does not like when library sources are outside the project +## directory. +set_msg_config -id {IP_Flow 19-3656} -new_severity INFO + +## Temporally disabled - could not find and message with this ID +## set_msg_config -id {IP_Flow 19-2999} -new_severity INFO + +## Temporally disabled - could not find and message with this ID +## set_msg_config -id {IP_Flow 19-1654} -new_severity INFO + +## Unrecognized family xxxxxxx. Please verify spelling and reissue command to +## set the supported files. -- the adi_ip.tcl script trying to add all the existent +## family to the supported family list. Apparently Xilinx has some inconsistent +## naming conventions for families. TODO:Maybe we should define exactly the supported +## architectures. +set_msg_config -id {IP_Flow 19-4623} -new_severity INFO + +## IP file '~/hdl/library/common/xxxx.v' appears to be outside of the project area. +## This is similar to 19-3656 +set_msg_config -id {IP_Flow 19-459} -new_severity INFO + +## Temporally disabled - could not find and message with this ID +## set_msg_config -id {filemgmt 20-1763} -new_severity WARNING + +################################################################################ +## Placer related messages +## IDs : [Place 30-xxxx] +################################################################################ + +## Invalid constraint on register */axi_spi/*/IOx_I_REG. It has the property IOB=TRUE, +## but is is not driving or driven by any IO element. -- The AXI_SPI IP after +## 2017.4 has a default constraint which setting the input registers property +## IOB=TRUE, this will cause a CRITICAL WARNING is the interface is not used. +set_msg_config -id {Place 30-73} -string "axi_spi" -new_severity WARNING + +################################################################################ +## Other ID less messages +################################################################################ + +## After Vivado 2017.4, the tool does not like negative DDR_DQS_TO_CLK_DELAY +## values on the DDRx interface, and throw a CRITICAL WARNING. Although a negative +## value is not necessarily invalid, the ZedBoard's interface is working this way. +set_msg_config -string "PCW_UIPARAM_DDR_DQS_TO_CLK_DELAY" -new_severity WARNING + diff --git a/src/adi/hdl/projects/scripts/project-altera.mk b/src/adi/hdl/projects/scripts/project-altera.mk new file mode 100644 index 00000000..8418881f --- /dev/null +++ b/src/adi/hdl/projects/scripts/project-altera.mk @@ -0,0 +1,86 @@ +#################################################################################### +## Copyright 2018(c) Analog Devices, Inc. +#################################################################################### + +# Assumes this file is in projects/scripts/project-altera.mk +HDL_PROJECT_PATH := $(subst scripts/project-altera.mk,,$(lastword $(MAKEFILE_LIST))) +HDL_LIBRARY_PATH := $(HDL_PROJECT_PATH)../library/ + +include $(HDL_PROJECT_PATH)../quiet.mk + +ifeq ($(NIOS2_MMU),) + NIOS2_MMU := 1 +endif + +export ALT_NIOS_MMU_ENABLED := $(NIOS2_MMU) + +ALTERA := quartus_sh --64bit -t + +CLEAN_TARGET += *.log +CLEAN_TARGET += *_INFO.txt +CLEAN_TARGET += *_dump.txt +CLEAN_TARGET += db +CLEAN_TARGET += *.asm.rpt +CLEAN_TARGET += *.done +CLEAN_TARGET += *.eda.rpt +CLEAN_TARGET += *.fit.* +CLEAN_TARGET += *.map.* +CLEAN_TARGET += *.sta.* +CLEAN_TARGET += *.qsf +CLEAN_TARGET += *.qpf +CLEAN_TARGET += *.qws +CLEAN_TARGET += *.sof +CLEAN_TARGET += *.cdf +CLEAN_TARGET += *.sld +CLEAN_TARGET += *.qdf +CLEAN_TARGET += hc_output +CLEAN_TARGET += system_bd +CLEAN_TARGET += hps_isw_handoff +CLEAN_TARGET += hps_sdram_*.csv +CLEAN_TARGET += *ddr3_*.csv +CLEAN_TARGET += incremental_db +CLEAN_TARGET += reconfig_mif +CLEAN_TARGET += *.sopcinfo +CLEAN_TARGET += *.jdi +CLEAN_TARGET += *.pin +CLEAN_TARGET += *_summary.csv +CLEAN_TARGET += *.dpf +CLEAN_TARGET += system_qsys_script.tcl +CLEAN_TARGET += system_bd.qsys +CLEAN_TARGET += .qsys_edit + +M_DEPS += system_top.v +M_DEPS += system_qsys.tcl +M_DEPS += system_project.tcl +M_DEPS += system_constr.sdc +M_DEPS += $(HDL_PROJECT_PATH)scripts/adi_tquest.tcl +M_DEPS += $(HDL_PROJECT_PATH)scripts/adi_project_alt.tcl +M_DEPS += $(HDL_PROJECT_PATH)scripts/adi_env.tcl + +M_DEPS += $(foreach dep,$(LIB_DEPS),$(HDL_LIBRARY_PATH)$(dep)/.timestamp_altera) + +.PHONY: all lib clean clean-all +all: lib $(PROJECT_NAME).sof + + +clean: + $(call clean, \ + $(CLEAN_TARGET), \ + $(HL)$(PROJECT_NAME)$(NC) project) + +clean-all: clean + @for lib in $(LIB_DEPS); do \ + $(MAKE) -C $(HDL_LIBRARY_PATH)$${lib} clean; \ + done + +$(PROJECT_NAME).sof: $(M_DEPS) + -rm -rf $(CLEAN_TARGET) + $(call build,\ + $(ALTERA) system_project.tcl, \ + $(PROJECT_NAME)_quartus.log, \ + $(HL)$(PROJECT_NAME)$(NC)) + +lib: + @for lib in $(LIB_DEPS); do \ + $(MAKE) -C $(HDL_LIBRARY_PATH)$${lib} altera || exit $$?; \ + done diff --git a/src/adi/hdl/projects/scripts/project-toplevel.mk b/src/adi/hdl/projects/scripts/project-toplevel.mk new file mode 100644 index 00000000..ad8dcd8e --- /dev/null +++ b/src/adi/hdl/projects/scripts/project-toplevel.mk @@ -0,0 +1,24 @@ +#################################################################################### +## Copyright 2018(c) Analog Devices, Inc. +#################################################################################### + +# Assumes this file is in projects/scripts/project-toplevel.mk +HDL_PROJECT_PATH := $(subst scripts/project-toplevel.mk,,$(lastword $(MAKEFILE_LIST))) + +include $(HDL_PROJECT_PATH)../quiet.mk + +SUBDIRS := $(dir $(wildcard */Makefile)) + +# Create virtual targets "$project/all", "$project/clean", "$project/clean-all" +SUBDIRS_ALL := $(addsuffix all,$(SUBDIRS)) +SUBDIRS_CLEAN := $(addsuffix clean,$(SUBDIRS)) +SUBDIRS_CLEANALL := $(addsuffix clean-all,$(SUBDIRS)) + +.PHONY: all clean clean-all $(SUBDIRS_ALL) $(SUBDIRS_CLEAN) $(SUBDIRS_CLEANALL) + +all: $(SUBDIRS_ALL) +clean: $(SUBDIRS_CLEAN) +clean-all: $(SUBDIRS_CLEANALL) + +$(SUBDIRS_ALL) $(SUBDIRS_CLEAN) $(SUBDIRS_CLEANALL): + $(MAKE) -C $(@D) $(@F) diff --git a/src/adi/hdl/projects/scripts/project-xilinx.mk b/src/adi/hdl/projects/scripts/project-xilinx.mk new file mode 100644 index 00000000..517de9fd --- /dev/null +++ b/src/adi/hdl/projects/scripts/project-xilinx.mk @@ -0,0 +1,62 @@ +#################################################################################### +## Copyright 2018(c) Analog Devices, Inc. +#################################################################################### + +# Assumes this file is in prpojects/scripts/project-xilinx.mk +HDL_PROJECT_PATH := $(subst scripts/project-xilinx.mk,,$(lastword $(MAKEFILE_LIST))) +HDL_LIBRARY_PATH := $(HDL_PROJECT_PATH)../library/ + +include $(HDL_PROJECT_PATH)../quiet.mk + +VIVADO := vivado -mode batch -source + +CLEAN_TARGET := *.cache +CLEAN_TARGET += *.data +CLEAN_TARGET += *.xpr +CLEAN_TARGET += *.log +CLEAN_TARGET += *.jou +CLEAN_TARGET += xgui +CLEAN_TARGET += *.runs +CLEAN_TARGET += *.srcs +CLEAN_TARGET += *.sdk +CLEAN_TARGET += *.hw +CLEAN_TARGET += *.sim +CLEAN_TARGET += .Xil +CLEAN_TARGET += *.ip_user_files +CLEAN_TARGET += *.str + +# Common dependencies that all projects have +M_DEPS += system_project.tcl +M_DEPS += system_bd.tcl +M_DEPS += $(wildcard system_top*.v) +M_DEPS += $(wildcard system_constr.xdc) # Not all projects have this file +M_DEPS += $(HDL_PROJECT_PATH)scripts/adi_project.tcl +M_DEPS += $(HDL_PROJECT_PATH)scripts/adi_env.tcl +M_DEPS += $(HDL_PROJECT_PATH)scripts/adi_board.tcl + +M_DEPS += $(foreach dep,$(LIB_DEPS),$(HDL_LIBRARY_PATH)$(dep)/component.xml) + +.PHONY: all lib clean clean-all +all: lib $(PROJECT_NAME).sdk/system_top.hdf + +clean: + $(call clean, \ + $(CLEAN_TARGET), \ + $(HL)$(PROJECT_NAME)$(NC) project) + +clean-all: clean + @for lib in $(LIB_DEPS); do \ + $(MAKE) -C $(HDL_LIBRARY_PATH)$${lib} clean; \ + done + +$(PROJECT_NAME).sdk/system_top.hdf: $(M_DEPS) + -rm -rf $(CLEAN_TARGET) + $(call build, \ + $(VIVADO) system_project.tcl, \ + $(PROJECT_NAME)_vivado.log, \ + $(HL)$(PROJECT_NAME)$(NC) project) + +lib: + @for lib in $(LIB_DEPS); do \ + $(MAKE) -C $(HDL_LIBRARY_PATH)$${lib} xilinx || exit $$?; \ + done diff --git a/src/adi/hdl/quiet.mk b/src/adi/hdl/quiet.mk new file mode 100644 index 00000000..051d66f9 --- /dev/null +++ b/src/adi/hdl/quiet.mk @@ -0,0 +1,52 @@ +#################################################################################### +## Copyright 2018(c) Analog Devices, Inc. +#################################################################################### + +ifdef MAKE_TERMOUT + ESC:=$(shell printf '\033') + GREEN:=$(ESC)[1;32m + RED:=$(ESC)[1;31m + HL:=$(ESC)[0;33m + NC:=$(ESC)[0m +else + GREEN:= + RED:= + HL:= + NC:= +endif + +ifneq ($(VERBOSE),1) + MAKEFLAGS += --quiet + + # build - Run a build command + # $(1): Command to execute + # $(2): Logfile name + # $(3): Textual description of the task + define build + @echo -n "Building $(strip $(3)) [$(HL)$(CURDIR)/$(strip $(2))$(NC)] ..." + $(strip $(1)) >> $(strip $(2)) 2>&1; \ + (ERR=$$?; if [ $$ERR = 0 ]; then \ + echo " $(GREEN)OK$(NC)"; \ + else \ + echo " $(RED)FAILED$(NC)"; \ + echo "For details see $(HL)$(CURDIR)/$(strip $(2))$(NC)"; \ + echo ""; \ + fi; exit $$ERR) + endef + + # clean - Run a clean command + # $(1): Files to remove + # $(2): Textural description of the task + define clean + @echo "Cleaning $(strip $(2)) ..." + -rm -rf $(strip $(1)) + endef +else + define build + $(strip $(1)) >> $(strip $(2)) 2>&1 + endef + + define clean + -rm -rf $(strip $(1)) + endef +endif diff --git a/src/common/hdl/oh_memory_ram.v b/src/common/hdl/oh_memory_ram.v index 10a387f2..3465f8da 100644 --- a/src/common/hdl/oh_memory_ram.v +++ b/src/common/hdl/oh_memory_ram.v @@ -5,10 +5,15 @@ //# License: MIT (see LICENSE file in OH! repository) # //############################################################################# +`ifndef CFG_PLATFORM +`define CFG_PLATFORM "GENERIC" +`endif + module oh_memory_ram # (parameter DW = 104, //memory width parameter DEPTH = 32, //memory depth - parameter AW = $clog2(DEPTH) // address width - ) + parameter AW = $clog2(DEPTH), // address width + parameter PLATFORM = `CFG_PLATFORM + ) (// read-port input rd_clk,// rd clock input rd_en, // memory access @@ -20,28 +25,45 @@ module oh_memory_ram # (parameter DW = 104, //memory width input [AW-1:0] wr_addr, // address input [DW-1:0] wr_wem, // write enable vector input [DW-1:0] wr_din // data input - ); - - reg [DW-1:0] ram [DEPTH-1:0]; - integer i; - - //registered read port - always @ (posedge rd_clk) - if(rd_en) - rd_dout[DW-1:0] <= ram[rd_addr[AW-1:0]]; - - //write port with vector enable - always @(posedge wr_clk) - for (i=0;i and is being run in <$current_vivado_version> of Vivado. Please run the script in Vivado <$scripts_vivado_version> then open the design in Vivado <$current_vivado_version>. Upgrade the design by running \"Tools => Report => Report IP Status...\", then run write_bd_tcl to create an updated script."} + + return 1 +} + +################################################################ +# START +################################################################ + +# To test this script, run the following commands from Vivado Tcl console: +# source system_script.tcl + +# If there is no project opened, this script will create a +# project, but make sure you do not have an existing project +# <./myproj/project_1.xpr> in the current working folder. + +set list_projs [get_projects -quiet] +if { $list_projs eq "" } { + create_project project_1 myproj -part xc7z010clg400-1 +} + + +# CHANGE DESIGN NAME HERE +variable design_name +set design_name system + +# If you do not already have an existing IP Integrator design open, +# you can create a design using the following command: +# create_bd_design $design_name + +# Creating design if needed +set errMsg "" +set nRet 0 + +set cur_design [current_bd_design -quiet] +set list_cells [get_bd_cells -quiet] + +if { ${design_name} eq "" } { + # USE CASES: + # 1) Design_name not set + + set errMsg "Please set the variable to a non-empty value." + set nRet 1 + +} elseif { ${cur_design} ne "" && ${list_cells} eq "" } { + # USE CASES: + # 2): Current design opened AND is empty AND names same. + # 3): Current design opened AND is empty AND names diff; design_name NOT in project. + # 4): Current design opened AND is empty AND names diff; design_name exists in project. + + if { $cur_design ne $design_name } { + common::send_msg_id "BD_TCL-001" "INFO" "Changing value of from <$design_name> to <$cur_design> since current design is empty." + set design_name [get_property NAME $cur_design] + } + common::send_msg_id "BD_TCL-002" "INFO" "Constructing design in IPI design <$cur_design>..." + +} elseif { ${cur_design} ne "" && $list_cells ne "" && $cur_design eq $design_name } { + # USE CASES: + # 5) Current design opened AND has components AND same names. + + set errMsg "Design <$design_name> already exists in your project, please set the variable to another value." + set nRet 1 +} elseif { [get_files -quiet ${design_name}.bd] ne "" } { + # USE CASES: + # 6) Current opened design, has components, but diff names, design_name exists in project. + # 7) No opened design, design_name exists in project. + + set errMsg "Design <$design_name> already exists in your project, please set the variable to another value." + set nRet 2 + +} else { + # USE CASES: + # 8) No opened design, design_name not in project. + # 9) Current opened design, has components, but diff names, design_name not in project. + + common::send_msg_id "BD_TCL-003" "INFO" "Currently there is no design <$design_name> in project, so creating one..." + + create_bd_design $design_name + + common::send_msg_id "BD_TCL-004" "INFO" "Making design <$design_name> as current_bd_design." + current_bd_design $design_name + +} + +common::send_msg_id "BD_TCL-005" "INFO" "Currently the variable is equal to \"$design_name\"." + +if { $nRet != 0 } { + catch {common::send_msg_id "BD_TCL-114" "ERROR" $errMsg} + return $nRet +} + +set bCheckIPsPassed 1 +################################################################## +# CHECK IPs +################################################################## +set bCheckIPs 1 +if { $bCheckIPs == 1 } { + set list_check_ips "\ +www.parallella.org:user:parallella_base:1.0\ +xilinx.com:ip:proc_sys_reset:5.0\ +xilinx.com:ip:processing_system7:5.5\ +xilinx.com:ip:xlconcat:2.1\ +analog.com:user:axi_clkgen:1.0\ +analog.com:user:axi_dmac:1.0\ +analog.com:user:axi_hdmi_tx:1.0\ +analog.com:user:axi_spdif_tx:1.0\ +xilinx.com:ip:clk_wiz:6.0\ +" + + set list_ips_missing "" + common::send_msg_id "BD_TCL-006" "INFO" "Checking if the following IPs exist in the project's IP catalog: $list_check_ips ." + + foreach ip_vlnv $list_check_ips { + set ip_obj [get_ipdefs -all $ip_vlnv] + if { $ip_obj eq "" } { + lappend list_ips_missing $ip_vlnv + } + } + + if { $list_ips_missing ne "" } { + catch {common::send_msg_id "BD_TCL-115" "ERROR" "The following IPs are not found in the IP Catalog:\n $list_ips_missing\n\nResolution: Please add the repository containing the IP(s) to the project." } + set bCheckIPsPassed 0 + } + +} + +if { $bCheckIPsPassed != 1 } { + common::send_msg_id "BD_TCL-1003" "WARNING" "Will not continue with creation of design due to the error(s) above." + return 3 +} + +################################################################## +# DESIGN PROCs +################################################################## + + +# Hierarchical cell: hdmi_0 +proc create_hier_cell_hdmi_0 { parentCell nameHier } { + + variable script_folder + + if { $parentCell eq "" || $nameHier eq "" } { + catch {common::send_msg_id "BD_TCL-102" "ERROR" "create_hier_cell_hdmi_0() - Empty argument(s)!"} + return + } + + # Get object for parentCell + set parentObj [get_bd_cells $parentCell] + if { $parentObj == "" } { + catch {common::send_msg_id "BD_TCL-100" "ERROR" "Unable to find parent cell <$parentCell>!"} + return + } + + # Make sure parentObj is hier blk + set parentType [get_property TYPE $parentObj] + if { $parentType ne "hier" } { + catch {common::send_msg_id "BD_TCL-101" "ERROR" "Parent <$parentObj> has TYPE = <$parentType>. Expected to be ."} + return + } + + # Save current instance; Restore later + set oldCurInst [current_bd_instance .] + + # Set parent object as current + current_bd_instance $parentObj + + # Create cell and set as current instance + set hier_obj [create_bd_cell -type hier $nameHier] + current_bd_instance $hier_obj + + # Create interface pins + create_bd_intf_pin -mode Slave -vlnv xilinx.com:interface:axis_rtl:1.0 DMA_ACK + create_bd_intf_pin -mode Master -vlnv xilinx.com:interface:axis_rtl:1.0 DMA_REQ + create_bd_intf_pin -mode Master -vlnv xilinx.com:interface:aximm_rtl:1.0 M00_AXI + create_bd_intf_pin -mode Slave -vlnv xilinx.com:interface:aximm_rtl:1.0 S_AXI + create_bd_intf_pin -mode Slave -vlnv xilinx.com:interface:aximm_rtl:1.0 S_AXI_LITE + create_bd_intf_pin -mode Slave -vlnv xilinx.com:interface:aximm_rtl:1.0 s_axi1 + create_bd_intf_pin -mode Slave -vlnv xilinx.com:interface:aximm_rtl:1.0 s_axi2 + + # Create pins + create_bd_pin -dir I -from 0 -to 0 -type rst axi_resetn + create_bd_pin -dir I clk + create_bd_pin -dir O -from 15 -to 0 hdmi_16_data + create_bd_pin -dir O hdmi_16_data_e + create_bd_pin -dir O hdmi_16_hsync + create_bd_pin -dir O hdmi_16_vsync + create_bd_pin -dir O -type clk hdmi_out_clk + create_bd_pin -dir O -type intr mm2s_introut + create_bd_pin -dir I -type clk s_axi_aclk + create_bd_pin -dir O spdif_tx_o + + # Create instance: axi_clkgen_0, and set properties + set axi_clkgen_0 [ create_bd_cell -type ip -vlnv analog.com:user:axi_clkgen:1.0 axi_clkgen_0 ] + + # Create instance: axi_dmac_0, and set properties + set axi_dmac_0 [ create_bd_cell -type ip -vlnv analog.com:user:axi_dmac:1.0 axi_dmac_0 ] + set_property -dict [ list \ + CONFIG.CYCLIC {true} \ + CONFIG.DMA_2D_TRANSFER {true} \ + CONFIG.DMA_TYPE_DEST {1} \ + CONFIG.DMA_TYPE_SRC {0} \ + ] $axi_dmac_0 + + # Create instance: axi_hdmi_tx_0, and set properties + set axi_hdmi_tx_0 [ create_bd_cell -type ip -vlnv analog.com:user:axi_hdmi_tx:1.0 axi_hdmi_tx_0 ] + + # Create instance: axi_interconnect_0, and set properties + set axi_interconnect_0 [ create_bd_cell -type ip -vlnv xilinx.com:ip:axi_interconnect:2.1 axi_interconnect_0 ] + set_property -dict [ list \ + CONFIG.NUM_MI {1} \ + ] $axi_interconnect_0 + + # Create instance: axi_spdif_tx_0, and set properties + set axi_spdif_tx_0 [ create_bd_cell -type ip -vlnv analog.com:user:axi_spdif_tx:1.0 axi_spdif_tx_0 ] + set_property -dict [ list \ + CONFIG.DMA_TYPE {1} \ + CONFIG.S_AXI_ADDRESS_WIDTH {16} \ + ] $axi_spdif_tx_0 + + # Create instance: spdif_clk_0, and set properties + set spdif_clk_0 [ create_bd_cell -type ip -vlnv xilinx.com:ip:clk_wiz:6.0 spdif_clk_0 ] + set_property -dict [ list \ + CONFIG.AXI_DRP {false} \ + CONFIG.CLKIN1_JITTER_PS {50.0} \ + CONFIG.CLKOUT1_DRIVES {No_buffer} \ + CONFIG.CLKOUT1_JITTER {307.400} \ + CONFIG.CLKOUT1_PHASE_ERROR {262.328} \ + CONFIG.CLKOUT1_REQUESTED_OUT_FREQ {12.288} \ + CONFIG.CLKOUT2_DRIVES {BUFG} \ + CONFIG.CLKOUT3_DRIVES {BUFG} \ + CONFIG.CLKOUT4_DRIVES {BUFG} \ + CONFIG.CLKOUT5_DRIVES {BUFG} \ + CONFIG.CLKOUT6_DRIVES {BUFG} \ + CONFIG.CLKOUT7_DRIVES {BUFG} \ + CONFIG.FEEDBACK_SOURCE {FDBK_ONCHIP} \ + CONFIG.MMCM_CLKFBOUT_MULT_F {47} \ + CONFIG.MMCM_CLKIN1_PERIOD {5.000} \ + CONFIG.MMCM_CLKOUT0_DIVIDE_F {85} \ + CONFIG.MMCM_COMPENSATION {ZHOLD} \ + CONFIG.MMCM_DIVCLK_DIVIDE {9} \ + CONFIG.PHASE_DUTY_CONFIG {false} \ + CONFIG.PRIMITIVE {PLL} \ + CONFIG.PRIM_IN_FREQ {200.000} \ + CONFIG.PRIM_SOURCE {No_buffer} \ + CONFIG.RESET_PORT {resetn} \ + CONFIG.RESET_TYPE {ACTIVE_LOW} \ + CONFIG.SECONDARY_SOURCE {Single_ended_clock_capable_pin} \ + CONFIG.USE_DYN_RECONFIG {false} \ + CONFIG.USE_LOCKED {false} \ + CONFIG.USE_PHASE_ALIGNMENT {false} \ + CONFIG.USE_RESET {true} \ + CONFIG.USE_SAFE_CLOCK_STARTUP {false} \ + ] $spdif_clk_0 + + # Create interface connections + connect_bd_intf_net -intf_net DMA_ACK_1 [get_bd_intf_pins DMA_ACK] [get_bd_intf_pins axi_spdif_tx_0/dma_ack] + connect_bd_intf_net -intf_net S_AXI_1 [get_bd_intf_pins S_AXI] [get_bd_intf_pins axi_spdif_tx_0/s_axi] + connect_bd_intf_net -intf_net S_AXI_LITE_1 [get_bd_intf_pins S_AXI_LITE] [get_bd_intf_pins axi_dmac_0/s_axi] + connect_bd_intf_net -intf_net axi_dmac_0_m_axis [get_bd_intf_pins axi_dmac_0/m_axis] [get_bd_intf_pins axi_hdmi_tx_0/s_axis] + connect_bd_intf_net -intf_net axi_dmac_0_m_src_axi [get_bd_intf_pins axi_dmac_0/m_src_axi] [get_bd_intf_pins axi_interconnect_0/S00_AXI] + connect_bd_intf_net -intf_net axi_interconnect_0_M00_AXI [get_bd_intf_pins M00_AXI] [get_bd_intf_pins axi_interconnect_0/M00_AXI] + connect_bd_intf_net -intf_net axi_spdif_tx_0_DMA_REQ [get_bd_intf_pins DMA_REQ] [get_bd_intf_pins axi_spdif_tx_0/dma_req] + connect_bd_intf_net -intf_net s_axi1_1 [get_bd_intf_pins s_axi1] [get_bd_intf_pins axi_clkgen_0/s_axi] + connect_bd_intf_net -intf_net s_axi2_1 [get_bd_intf_pins s_axi2] [get_bd_intf_pins axi_hdmi_tx_0/s_axi] + + # Create port connections + connect_bd_net -net axi_clkgen_0_clk_0 [get_bd_pins axi_clkgen_0/clk_0] [get_bd_pins axi_hdmi_tx_0/hdmi_clk] + connect_bd_net -net axi_dmac_0_irq [get_bd_pins mm2s_introut] [get_bd_pins axi_dmac_0/irq] + connect_bd_net -net axi_hdmi_tx_0_hdmi_16_data [get_bd_pins hdmi_16_data] [get_bd_pins axi_hdmi_tx_0/hdmi_16_data] + connect_bd_net -net axi_hdmi_tx_0_hdmi_16_data_e [get_bd_pins hdmi_16_data_e] [get_bd_pins axi_hdmi_tx_0/hdmi_16_data_e] + connect_bd_net -net axi_hdmi_tx_0_hdmi_16_hsync [get_bd_pins hdmi_16_hsync] [get_bd_pins axi_hdmi_tx_0/hdmi_16_hsync] + connect_bd_net -net axi_hdmi_tx_0_hdmi_16_vsync [get_bd_pins hdmi_16_vsync] [get_bd_pins axi_hdmi_tx_0/hdmi_16_vsync] + connect_bd_net -net axi_hdmi_tx_0_hdmi_out_clk [get_bd_pins hdmi_out_clk] [get_bd_pins axi_hdmi_tx_0/hdmi_out_clk] + connect_bd_net -net axi_resetn_1 [get_bd_pins axi_resetn] [get_bd_pins axi_clkgen_0/s_axi_aresetn] [get_bd_pins axi_dmac_0/m_src_axi_aresetn] [get_bd_pins axi_dmac_0/s_axi_aresetn] [get_bd_pins axi_hdmi_tx_0/s_axi_aresetn] [get_bd_pins axi_interconnect_0/ARESETN] [get_bd_pins axi_interconnect_0/M00_ARESETN] [get_bd_pins axi_interconnect_0/S00_ARESETN] [get_bd_pins axi_spdif_tx_0/dma_req_rstn] [get_bd_pins axi_spdif_tx_0/s_axi_aresetn] [get_bd_pins spdif_clk_0/resetn] + connect_bd_net -net axi_spdif_tx_0_spdif_tx_o [get_bd_pins spdif_tx_o] [get_bd_pins axi_spdif_tx_0/spdif_tx_o] + connect_bd_net -net clk_1 [get_bd_pins clk] [get_bd_pins axi_clkgen_0/clk] [get_bd_pins spdif_clk_0/clk_in1] + connect_bd_net -net clk_wiz_0_clk_out1 [get_bd_pins axi_spdif_tx_0/spdif_data_clk] [get_bd_pins spdif_clk_0/clk_out1] + connect_bd_net -net s_axi_aclk_1 [get_bd_pins s_axi_aclk] [get_bd_pins axi_clkgen_0/s_axi_aclk] [get_bd_pins axi_dmac_0/m_axis_aclk] [get_bd_pins axi_dmac_0/m_src_axi_aclk] [get_bd_pins axi_dmac_0/s_axi_aclk] [get_bd_pins axi_hdmi_tx_0/s_axi_aclk] [get_bd_pins axi_hdmi_tx_0/vdma_clk] [get_bd_pins axi_interconnect_0/ACLK] [get_bd_pins axi_interconnect_0/M00_ACLK] [get_bd_pins axi_interconnect_0/S00_ACLK] [get_bd_pins axi_spdif_tx_0/dma_req_aclk] [get_bd_pins axi_spdif_tx_0/s_axi_aclk] + + # Restore current instance + current_bd_instance $oldCurInst +} + + +# Procedure to create entire design; Provide argument to make +# procedure reusable. If parentCell is "", will use root. +proc create_root_design { parentCell } { + + variable script_folder + variable design_name + + if { $parentCell eq "" } { + set parentCell [get_bd_cells /] + } + + # Get object for parentCell + set parentObj [get_bd_cells $parentCell] + if { $parentObj == "" } { + catch {common::send_msg_id "BD_TCL-100" "ERROR" "Unable to find parent cell <$parentCell>!"} + return + } + + # Make sure parentObj is hier blk + set parentType [get_property TYPE $parentObj] + if { $parentType ne "hier" } { + catch {common::send_msg_id "BD_TCL-101" "ERROR" "Parent <$parentObj> has TYPE = <$parentType>. Expected to be ."} + return + } + + # Save current instance; Restore later + set oldCurInst [current_bd_instance .] + + # Set parent object as current + current_bd_instance $parentObj + + + # Create interface ports + set DDR [ create_bd_intf_port -mode Master -vlnv xilinx.com:interface:ddrx_rtl:1.0 DDR ] + set FIXED_IO [ create_bd_intf_port -mode Master -vlnv xilinx.com:display_processing_system7:fixedio_rtl:1.0 FIXED_IO ] + + # Create ports + set cclk_n [ create_bd_port -dir O cclk_n ] + set cclk_p [ create_bd_port -dir O cclk_p ] + set chip_nreset [ create_bd_port -dir O chip_nreset ] + set gpio_n [ create_bd_port -dir IO -from 11 -to 0 gpio_n ] + set gpio_p [ create_bd_port -dir IO -from 11 -to 0 gpio_p ] + set hdmi_clk [ create_bd_port -dir O -type clk hdmi_clk ] + set hdmi_d [ create_bd_port -dir O -from 15 -to 0 hdmi_d ] + set hdmi_de [ create_bd_port -dir O hdmi_de ] + set hdmi_hsync [ create_bd_port -dir O hdmi_hsync ] + set hdmi_int [ create_bd_port -dir I hdmi_int ] + set hdmi_spdif [ create_bd_port -dir O hdmi_spdif ] + set hdmi_vsync [ create_bd_port -dir O hdmi_vsync ] + set i2c_scl [ create_bd_port -dir IO i2c_scl ] + set i2c_sda [ create_bd_port -dir IO i2c_sda ] + set rxi_data_n [ create_bd_port -dir I -from 7 -to 0 rxi_data_n ] + set rxi_data_p [ create_bd_port -dir I -from 7 -to 0 rxi_data_p ] + set rxi_frame_n [ create_bd_port -dir I rxi_frame_n ] + set rxi_frame_p [ create_bd_port -dir I rxi_frame_p ] + set rxi_lclk_n [ create_bd_port -dir I rxi_lclk_n ] + set rxi_lclk_p [ create_bd_port -dir I rxi_lclk_p ] + set rxo_rd_wait_n [ create_bd_port -dir O rxo_rd_wait_n ] + set rxo_rd_wait_p [ create_bd_port -dir O rxo_rd_wait_p ] + set rxo_wr_wait_n [ create_bd_port -dir O rxo_wr_wait_n ] + set rxo_wr_wait_p [ create_bd_port -dir O rxo_wr_wait_p ] + set txi_rd_wait_n [ create_bd_port -dir I txi_rd_wait_n ] + set txi_rd_wait_p [ create_bd_port -dir I txi_rd_wait_p ] + set txi_wr_wait_n [ create_bd_port -dir I txi_wr_wait_n ] + set txi_wr_wait_p [ create_bd_port -dir I txi_wr_wait_p ] + set txo_data_n [ create_bd_port -dir O -from 7 -to 0 txo_data_n ] + set txo_data_p [ create_bd_port -dir O -from 7 -to 0 txo_data_p ] + set txo_frame_n [ create_bd_port -dir O txo_frame_n ] + set txo_frame_p [ create_bd_port -dir O txo_frame_p ] + set txo_lclk_n [ create_bd_port -dir O txo_lclk_n ] + set txo_lclk_p [ create_bd_port -dir O txo_lclk_p ] + + # Create instance: axi_hdmi_intercon, and set properties + set axi_hdmi_intercon [ create_bd_cell -type ip -vlnv xilinx.com:ip:axi_interconnect:2.1 axi_hdmi_intercon ] + set_property -dict [ list \ + CONFIG.NUM_MI {4} \ + ] $axi_hdmi_intercon + + # Create instance: axi_parallella_m_intercon, and set properties + set axi_parallella_m_intercon [ create_bd_cell -type ip -vlnv xilinx.com:ip:axi_interconnect:2.1 axi_parallella_m_intercon ] + set_property -dict [ list \ + CONFIG.NUM_MI {1} \ + CONFIG.NUM_SI {1} \ + ] $axi_parallella_m_intercon + + # Create instance: axi_parallella_s_intercon, and set properties + set axi_parallella_s_intercon [ create_bd_cell -type ip -vlnv xilinx.com:ip:axi_interconnect:2.1 axi_parallella_s_intercon ] + set_property -dict [ list \ + CONFIG.NUM_MI {1} \ + ] $axi_parallella_s_intercon + + # Create instance: hdmi_0 + create_hier_cell_hdmi_0 [current_bd_instance .] hdmi_0 + + # Create instance: parallella_base_0, and set properties + set parallella_base_0 [ create_bd_cell -type ip -vlnv www.parallella.org:user:parallella_base:1.0 parallella_base_0 ] + set_property -dict [ list \ + CONFIG.NGPIO {12} \ + ] $parallella_base_0 + + # Create instance: proc_sys_reset_0, and set properties + set proc_sys_reset_0 [ create_bd_cell -type ip -vlnv xilinx.com:ip:proc_sys_reset:5.0 proc_sys_reset_0 ] + + # Create instance: processing_system7_0, and set properties + set processing_system7_0 [ create_bd_cell -type ip -vlnv xilinx.com:ip:processing_system7:5.5 processing_system7_0 ] + set_property -dict [ list \ + CONFIG.PCW_ACT_APU_PERIPHERAL_FREQMHZ {666.666687} \ + CONFIG.PCW_ACT_CAN_PERIPHERAL_FREQMHZ {10.000000} \ + CONFIG.PCW_ACT_DCI_PERIPHERAL_FREQMHZ {10.062893} \ + CONFIG.PCW_ACT_ENET0_PERIPHERAL_FREQMHZ {125.000000} \ + CONFIG.PCW_ACT_ENET1_PERIPHERAL_FREQMHZ {10.000000} \ + CONFIG.PCW_ACT_FPGA0_PERIPHERAL_FREQMHZ {100.000000} \ + CONFIG.PCW_ACT_FPGA1_PERIPHERAL_FREQMHZ {10.000000} \ + CONFIG.PCW_ACT_FPGA2_PERIPHERAL_FREQMHZ {200.000000} \ + CONFIG.PCW_ACT_FPGA3_PERIPHERAL_FREQMHZ {10.000000} \ + CONFIG.PCW_ACT_PCAP_PERIPHERAL_FREQMHZ {200.000000} \ + CONFIG.PCW_ACT_QSPI_PERIPHERAL_FREQMHZ {200.000000} \ + CONFIG.PCW_ACT_SDIO_PERIPHERAL_FREQMHZ {50.000000} \ + CONFIG.PCW_ACT_SMC_PERIPHERAL_FREQMHZ {10.000000} \ + CONFIG.PCW_ACT_SPI_PERIPHERAL_FREQMHZ {10.000000} \ + CONFIG.PCW_ACT_TPIU_PERIPHERAL_FREQMHZ {200.000000} \ + CONFIG.PCW_ACT_TTC0_CLK0_PERIPHERAL_FREQMHZ {111.111115} \ + CONFIG.PCW_ACT_TTC0_CLK1_PERIPHERAL_FREQMHZ {111.111115} \ + CONFIG.PCW_ACT_TTC0_CLK2_PERIPHERAL_FREQMHZ {111.111115} \ + CONFIG.PCW_ACT_TTC1_CLK0_PERIPHERAL_FREQMHZ {111.111115} \ + CONFIG.PCW_ACT_TTC1_CLK1_PERIPHERAL_FREQMHZ {111.111115} \ + CONFIG.PCW_ACT_TTC1_CLK2_PERIPHERAL_FREQMHZ {111.111115} \ + CONFIG.PCW_ACT_UART_PERIPHERAL_FREQMHZ {100.000000} \ + CONFIG.PCW_ACT_WDT_PERIPHERAL_FREQMHZ {111.111115} \ + CONFIG.PCW_ARMPLL_CTRL_FBDIV {40} \ + CONFIG.PCW_CAN_PERIPHERAL_DIVISOR0 {1} \ + CONFIG.PCW_CAN_PERIPHERAL_DIVISOR1 {1} \ + CONFIG.PCW_CLK0_FREQ {100000000} \ + CONFIG.PCW_CLK1_FREQ {10000000} \ + CONFIG.PCW_CLK2_FREQ {200000000} \ + CONFIG.PCW_CLK3_FREQ {10000000} \ + CONFIG.PCW_CORE0_FIQ_INTR {0} \ + CONFIG.PCW_CPU_CPU_PLL_FREQMHZ {1333.333} \ + CONFIG.PCW_CPU_PERIPHERAL_DIVISOR0 {2} \ + CONFIG.PCW_DCI_PERIPHERAL_DIVISOR0 {53} \ + CONFIG.PCW_DCI_PERIPHERAL_DIVISOR1 {3} \ + CONFIG.PCW_DDRPLL_CTRL_FBDIV {48} \ + CONFIG.PCW_DDR_DDR_PLL_FREQMHZ {1600.000} \ + CONFIG.PCW_DDR_PERIPHERAL_DIVISOR0 {4} \ + CONFIG.PCW_DDR_RAM_HIGHADDR {0x3FFFFFFF} \ + CONFIG.PCW_ENET0_ENET0_IO {MIO 16 .. 27} \ + CONFIG.PCW_ENET0_GRP_MDIO_ENABLE {1} \ + CONFIG.PCW_ENET0_GRP_MDIO_IO {EMIO} \ + CONFIG.PCW_ENET0_PERIPHERAL_DIVISOR0 {8} \ + CONFIG.PCW_ENET0_PERIPHERAL_DIVISOR1 {1} \ + CONFIG.PCW_ENET0_PERIPHERAL_ENABLE {1} \ + CONFIG.PCW_ENET0_PERIPHERAL_FREQMHZ {1000 Mbps} \ + CONFIG.PCW_ENET0_RESET_ENABLE {0} \ + CONFIG.PCW_ENET1_GRP_MDIO_ENABLE {0} \ + CONFIG.PCW_ENET1_PERIPHERAL_DIVISOR0 {1} \ + CONFIG.PCW_ENET1_PERIPHERAL_DIVISOR1 {1} \ + CONFIG.PCW_ENET1_PERIPHERAL_ENABLE {0} \ + CONFIG.PCW_ENET1_PERIPHERAL_FREQMHZ {1000 Mbps} \ + CONFIG.PCW_ENET1_RESET_ENABLE {0} \ + CONFIG.PCW_ENET_RESET_ENABLE {1} \ + CONFIG.PCW_ENET_RESET_SELECT {Share reset pin} \ + CONFIG.PCW_EN_CLK1_PORT {0} \ + CONFIG.PCW_EN_CLK2_PORT {1} \ + CONFIG.PCW_EN_CLK3_PORT {0} \ + CONFIG.PCW_EN_EMIO_CD_SDIO1 {0} \ + CONFIG.PCW_EN_EMIO_GPIO {1} \ + CONFIG.PCW_EN_EMIO_I2C0 {1} \ + CONFIG.PCW_EN_EMIO_SDIO1 {0} \ + CONFIG.PCW_EN_EMIO_WP_SDIO1 {0} \ + CONFIG.PCW_EN_ENET0 {1} \ + CONFIG.PCW_EN_GPIO {1} \ + CONFIG.PCW_EN_I2C0 {1} \ + CONFIG.PCW_EN_QSPI {1} \ + CONFIG.PCW_EN_SDIO1 {1} \ + CONFIG.PCW_EN_UART1 {1} \ + CONFIG.PCW_EN_USB0 {1} \ + CONFIG.PCW_EN_USB1 {1} \ + CONFIG.PCW_FCLK0_PERIPHERAL_DIVISOR0 {5} \ + CONFIG.PCW_FCLK0_PERIPHERAL_DIVISOR1 {2} \ + CONFIG.PCW_FCLK1_PERIPHERAL_DIVISOR0 {1} \ + CONFIG.PCW_FCLK1_PERIPHERAL_DIVISOR1 {1} \ + CONFIG.PCW_FCLK2_PERIPHERAL_DIVISOR0 {5} \ + CONFIG.PCW_FCLK2_PERIPHERAL_DIVISOR1 {1} \ + CONFIG.PCW_FCLK3_PERIPHERAL_DIVISOR0 {1} \ + CONFIG.PCW_FCLK3_PERIPHERAL_DIVISOR1 {1} \ + CONFIG.PCW_FCLK_CLK1_BUF {FALSE} \ + CONFIG.PCW_FCLK_CLK2_BUF {TRUE} \ + CONFIG.PCW_FCLK_CLK3_BUF {FALSE} \ + CONFIG.PCW_FPGA0_PERIPHERAL_FREQMHZ {100} \ + CONFIG.PCW_FPGA1_PERIPHERAL_FREQMHZ {152} \ + CONFIG.PCW_FPGA2_PERIPHERAL_FREQMHZ {200} \ + CONFIG.PCW_FPGA3_PERIPHERAL_FREQMHZ {100} \ + CONFIG.PCW_FPGA_FCLK0_ENABLE {1} \ + CONFIG.PCW_FPGA_FCLK1_ENABLE {0} \ + CONFIG.PCW_FPGA_FCLK2_ENABLE {1} \ + CONFIG.PCW_FPGA_FCLK3_ENABLE {0} \ + CONFIG.PCW_GPIO_EMIO_GPIO_ENABLE {1} \ + CONFIG.PCW_GPIO_EMIO_GPIO_IO {64} \ + CONFIG.PCW_GPIO_EMIO_GPIO_WIDTH {64} \ + CONFIG.PCW_GPIO_MIO_GPIO_ENABLE {1} \ + CONFIG.PCW_GPIO_MIO_GPIO_IO {MIO} \ + CONFIG.PCW_I2C0_GRP_INT_ENABLE {1} \ + CONFIG.PCW_I2C0_GRP_INT_IO {EMIO} \ + CONFIG.PCW_I2C0_I2C0_IO {EMIO} \ + CONFIG.PCW_I2C0_PERIPHERAL_ENABLE {1} \ + CONFIG.PCW_I2C0_RESET_ENABLE {0} \ + CONFIG.PCW_I2C1_RESET_ENABLE {0} \ + CONFIG.PCW_I2C_PERIPHERAL_FREQMHZ {111.111115} \ + CONFIG.PCW_I2C_RESET_ENABLE {1} \ + CONFIG.PCW_I2C_RESET_SELECT {Share reset pin} \ + CONFIG.PCW_IOPLL_CTRL_FBDIV {30} \ + CONFIG.PCW_IO_IO_PLL_FREQMHZ {1000.000} \ + CONFIG.PCW_IRQ_F2P_INTR {1} \ + CONFIG.PCW_IRQ_F2P_MODE {DIRECT} \ + CONFIG.PCW_MIO_0_DIRECTION {inout} \ + CONFIG.PCW_MIO_0_IOTYPE {LVCMOS 3.3V} \ + CONFIG.PCW_MIO_0_PULLUP {enabled} \ + CONFIG.PCW_MIO_0_SLEW {slow} \ + CONFIG.PCW_MIO_10_DIRECTION {inout} \ + CONFIG.PCW_MIO_10_IOTYPE {LVCMOS 3.3V} \ + CONFIG.PCW_MIO_10_PULLUP {enabled} \ + CONFIG.PCW_MIO_10_SLEW {slow} \ + CONFIG.PCW_MIO_11_DIRECTION {inout} \ + CONFIG.PCW_MIO_11_IOTYPE {LVCMOS 3.3V} \ + CONFIG.PCW_MIO_11_PULLUP {enabled} \ + CONFIG.PCW_MIO_11_SLEW {slow} \ + CONFIG.PCW_MIO_12_DIRECTION {inout} \ + CONFIG.PCW_MIO_12_IOTYPE {LVCMOS 3.3V} \ + CONFIG.PCW_MIO_12_PULLUP {enabled} \ + CONFIG.PCW_MIO_12_SLEW {slow} \ + CONFIG.PCW_MIO_13_DIRECTION {inout} \ + CONFIG.PCW_MIO_13_IOTYPE {LVCMOS 3.3V} \ + CONFIG.PCW_MIO_13_PULLUP {enabled} \ + CONFIG.PCW_MIO_13_SLEW {slow} \ + CONFIG.PCW_MIO_14_DIRECTION {inout} \ + CONFIG.PCW_MIO_14_IOTYPE {LVCMOS 3.3V} \ + CONFIG.PCW_MIO_14_PULLUP {enabled} \ + CONFIG.PCW_MIO_14_SLEW {slow} \ + CONFIG.PCW_MIO_15_DIRECTION {inout} \ + CONFIG.PCW_MIO_15_IOTYPE {LVCMOS 3.3V} \ + CONFIG.PCW_MIO_15_PULLUP {enabled} \ + CONFIG.PCW_MIO_15_SLEW {slow} \ + CONFIG.PCW_MIO_16_DIRECTION {out} \ + CONFIG.PCW_MIO_16_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_16_PULLUP {enabled} \ + CONFIG.PCW_MIO_16_SLEW {slow} \ + CONFIG.PCW_MIO_17_DIRECTION {out} \ + CONFIG.PCW_MIO_17_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_17_PULLUP {enabled} \ + CONFIG.PCW_MIO_17_SLEW {slow} \ + CONFIG.PCW_MIO_18_DIRECTION {out} \ + CONFIG.PCW_MIO_18_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_18_PULLUP {enabled} \ + CONFIG.PCW_MIO_18_SLEW {slow} \ + CONFIG.PCW_MIO_19_DIRECTION {out} \ + CONFIG.PCW_MIO_19_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_19_PULLUP {enabled} \ + CONFIG.PCW_MIO_19_SLEW {slow} \ + CONFIG.PCW_MIO_1_DIRECTION {out} \ + CONFIG.PCW_MIO_1_IOTYPE {LVCMOS 3.3V} \ + CONFIG.PCW_MIO_1_PULLUP {enabled} \ + CONFIG.PCW_MIO_1_SLEW {slow} \ + CONFIG.PCW_MIO_20_DIRECTION {out} \ + CONFIG.PCW_MIO_20_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_20_PULLUP {enabled} \ + CONFIG.PCW_MIO_20_SLEW {slow} \ + CONFIG.PCW_MIO_21_DIRECTION {out} \ + CONFIG.PCW_MIO_21_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_21_PULLUP {enabled} \ + CONFIG.PCW_MIO_21_SLEW {slow} \ + CONFIG.PCW_MIO_22_DIRECTION {in} \ + CONFIG.PCW_MIO_22_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_22_PULLUP {enabled} \ + CONFIG.PCW_MIO_22_SLEW {slow} \ + CONFIG.PCW_MIO_23_DIRECTION {in} \ + CONFIG.PCW_MIO_23_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_23_PULLUP {enabled} \ + CONFIG.PCW_MIO_23_SLEW {slow} \ + CONFIG.PCW_MIO_24_DIRECTION {in} \ + CONFIG.PCW_MIO_24_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_24_PULLUP {enabled} \ + CONFIG.PCW_MIO_24_SLEW {slow} \ + CONFIG.PCW_MIO_25_DIRECTION {in} \ + CONFIG.PCW_MIO_25_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_25_PULLUP {enabled} \ + CONFIG.PCW_MIO_25_SLEW {slow} \ + CONFIG.PCW_MIO_26_DIRECTION {in} \ + CONFIG.PCW_MIO_26_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_26_PULLUP {enabled} \ + CONFIG.PCW_MIO_26_SLEW {slow} \ + CONFIG.PCW_MIO_27_DIRECTION {in} \ + CONFIG.PCW_MIO_27_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_27_PULLUP {enabled} \ + CONFIG.PCW_MIO_27_SLEW {slow} \ + CONFIG.PCW_MIO_28_DIRECTION {inout} \ + CONFIG.PCW_MIO_28_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_28_PULLUP {enabled} \ + CONFIG.PCW_MIO_28_SLEW {slow} \ + CONFIG.PCW_MIO_29_DIRECTION {in} \ + CONFIG.PCW_MIO_29_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_29_PULLUP {enabled} \ + CONFIG.PCW_MIO_29_SLEW {slow} \ + CONFIG.PCW_MIO_2_DIRECTION {inout} \ + CONFIG.PCW_MIO_2_IOTYPE {LVCMOS 3.3V} \ + CONFIG.PCW_MIO_2_PULLUP {disabled} \ + CONFIG.PCW_MIO_2_SLEW {slow} \ + CONFIG.PCW_MIO_30_DIRECTION {out} \ + CONFIG.PCW_MIO_30_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_30_PULLUP {enabled} \ + CONFIG.PCW_MIO_30_SLEW {slow} \ + CONFIG.PCW_MIO_31_DIRECTION {in} \ + CONFIG.PCW_MIO_31_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_31_PULLUP {enabled} \ + CONFIG.PCW_MIO_31_SLEW {slow} \ + CONFIG.PCW_MIO_32_DIRECTION {inout} \ + CONFIG.PCW_MIO_32_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_32_PULLUP {enabled} \ + CONFIG.PCW_MIO_32_SLEW {slow} \ + CONFIG.PCW_MIO_33_DIRECTION {inout} \ + CONFIG.PCW_MIO_33_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_33_PULLUP {enabled} \ + CONFIG.PCW_MIO_33_SLEW {slow} \ + CONFIG.PCW_MIO_34_DIRECTION {inout} \ + CONFIG.PCW_MIO_34_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_34_PULLUP {enabled} \ + CONFIG.PCW_MIO_34_SLEW {slow} \ + CONFIG.PCW_MIO_35_DIRECTION {inout} \ + CONFIG.PCW_MIO_35_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_35_PULLUP {enabled} \ + CONFIG.PCW_MIO_35_SLEW {slow} \ + CONFIG.PCW_MIO_36_DIRECTION {in} \ + CONFIG.PCW_MIO_36_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_36_PULLUP {enabled} \ + CONFIG.PCW_MIO_36_SLEW {slow} \ + CONFIG.PCW_MIO_37_DIRECTION {inout} \ + CONFIG.PCW_MIO_37_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_37_PULLUP {enabled} \ + CONFIG.PCW_MIO_37_SLEW {slow} \ + CONFIG.PCW_MIO_38_DIRECTION {inout} \ + CONFIG.PCW_MIO_38_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_38_PULLUP {enabled} \ + CONFIG.PCW_MIO_38_SLEW {slow} \ + CONFIG.PCW_MIO_39_DIRECTION {inout} \ + CONFIG.PCW_MIO_39_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_39_PULLUP {enabled} \ + CONFIG.PCW_MIO_39_SLEW {slow} \ + CONFIG.PCW_MIO_3_DIRECTION {inout} \ + CONFIG.PCW_MIO_3_IOTYPE {LVCMOS 3.3V} \ + CONFIG.PCW_MIO_3_PULLUP {disabled} \ + CONFIG.PCW_MIO_3_SLEW {slow} \ + CONFIG.PCW_MIO_40_DIRECTION {inout} \ + CONFIG.PCW_MIO_40_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_40_PULLUP {enabled} \ + CONFIG.PCW_MIO_40_SLEW {slow} \ + CONFIG.PCW_MIO_41_DIRECTION {in} \ + CONFIG.PCW_MIO_41_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_41_PULLUP {enabled} \ + CONFIG.PCW_MIO_41_SLEW {slow} \ + CONFIG.PCW_MIO_42_DIRECTION {out} \ + CONFIG.PCW_MIO_42_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_42_PULLUP {enabled} \ + CONFIG.PCW_MIO_42_SLEW {slow} \ + CONFIG.PCW_MIO_43_DIRECTION {in} \ + CONFIG.PCW_MIO_43_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_43_PULLUP {enabled} \ + CONFIG.PCW_MIO_43_SLEW {slow} \ + CONFIG.PCW_MIO_44_DIRECTION {inout} \ + CONFIG.PCW_MIO_44_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_44_PULLUP {enabled} \ + CONFIG.PCW_MIO_44_SLEW {slow} \ + CONFIG.PCW_MIO_45_DIRECTION {inout} \ + CONFIG.PCW_MIO_45_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_45_PULLUP {enabled} \ + CONFIG.PCW_MIO_45_SLEW {slow} \ + CONFIG.PCW_MIO_46_DIRECTION {inout} \ + CONFIG.PCW_MIO_46_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_46_PULLUP {enabled} \ + CONFIG.PCW_MIO_46_SLEW {slow} \ + CONFIG.PCW_MIO_47_DIRECTION {inout} \ + CONFIG.PCW_MIO_47_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_47_PULLUP {enabled} \ + CONFIG.PCW_MIO_47_SLEW {slow} \ + CONFIG.PCW_MIO_48_DIRECTION {in} \ + CONFIG.PCW_MIO_48_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_48_PULLUP {enabled} \ + CONFIG.PCW_MIO_48_SLEW {slow} \ + CONFIG.PCW_MIO_49_DIRECTION {inout} \ + CONFIG.PCW_MIO_49_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_49_PULLUP {enabled} \ + CONFIG.PCW_MIO_49_SLEW {slow} \ + CONFIG.PCW_MIO_4_DIRECTION {inout} \ + CONFIG.PCW_MIO_4_IOTYPE {LVCMOS 3.3V} \ + CONFIG.PCW_MIO_4_PULLUP {disabled} \ + CONFIG.PCW_MIO_4_SLEW {slow} \ + CONFIG.PCW_MIO_50_DIRECTION {inout} \ + CONFIG.PCW_MIO_50_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_50_PULLUP {enabled} \ + CONFIG.PCW_MIO_50_SLEW {slow} \ + CONFIG.PCW_MIO_51_DIRECTION {inout} \ + CONFIG.PCW_MIO_51_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_51_PULLUP {enabled} \ + CONFIG.PCW_MIO_51_SLEW {slow} \ + CONFIG.PCW_MIO_52_DIRECTION {inout} \ + CONFIG.PCW_MIO_52_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_52_PULLUP {enabled} \ + CONFIG.PCW_MIO_52_SLEW {slow} \ + CONFIG.PCW_MIO_53_DIRECTION {inout} \ + CONFIG.PCW_MIO_53_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_53_PULLUP {enabled} \ + CONFIG.PCW_MIO_53_SLEW {slow} \ + CONFIG.PCW_MIO_5_DIRECTION {inout} \ + CONFIG.PCW_MIO_5_IOTYPE {LVCMOS 3.3V} \ + CONFIG.PCW_MIO_5_PULLUP {disabled} \ + CONFIG.PCW_MIO_5_SLEW {slow} \ + CONFIG.PCW_MIO_6_DIRECTION {out} \ + CONFIG.PCW_MIO_6_IOTYPE {LVCMOS 3.3V} \ + CONFIG.PCW_MIO_6_PULLUP {disabled} \ + CONFIG.PCW_MIO_6_SLEW {slow} \ + CONFIG.PCW_MIO_7_DIRECTION {out} \ + CONFIG.PCW_MIO_7_IOTYPE {LVCMOS 3.3V} \ + CONFIG.PCW_MIO_7_PULLUP {disabled} \ + CONFIG.PCW_MIO_7_SLEW {slow} \ + CONFIG.PCW_MIO_8_DIRECTION {out} \ + CONFIG.PCW_MIO_8_IOTYPE {LVCMOS 3.3V} \ + CONFIG.PCW_MIO_8_PULLUP {disabled} \ + CONFIG.PCW_MIO_8_SLEW {slow} \ + CONFIG.PCW_MIO_9_DIRECTION {in} \ + CONFIG.PCW_MIO_9_IOTYPE {LVCMOS 3.3V} \ + CONFIG.PCW_MIO_9_PULLUP {enabled} \ + CONFIG.PCW_MIO_9_SLEW {slow} \ + CONFIG.PCW_MIO_TREE_PERIPHERALS {GPIO#Quad SPI Flash#Quad SPI Flash#Quad SPI Flash#Quad SPI Flash#Quad SPI Flash#Quad SPI Flash#GPIO#UART 1#UART 1#SD 1#SD 1#SD 1#SD 1#SD 1#SD 1#Enet 0#Enet 0#Enet 0#Enet 0#Enet 0#Enet 0#Enet 0#Enet 0#Enet 0#Enet 0#Enet 0#Enet 0#USB 0#USB 0#USB 0#USB 0#USB 0#USB 0#USB 0#USB 0#USB 0#USB 0#USB 0#USB 0#USB 1#USB 1#USB 1#USB 1#USB 1#USB 1#USB 1#USB 1#USB 1#USB 1#USB 1#USB 1#GPIO#GPIO} \ + CONFIG.PCW_MIO_TREE_SIGNALS {gpio[0]#qspi0_ss_b#qspi0_io[0]#qspi0_io[1]#qspi0_io[2]#qspi0_io[3]/HOLD_B#qspi0_sclk#gpio[7]#tx#rx#data[0]#cmd#clk#data[1]#data[2]#data[3]#tx_clk#txd[0]#txd[1]#txd[2]#txd[3]#tx_ctl#rx_clk#rxd[0]#rxd[1]#rxd[2]#rxd[3]#rx_ctl#data[4]#dir#stp#nxt#data[0]#data[1]#data[2]#data[3]#clk#data[5]#data[6]#data[7]#data[4]#dir#stp#nxt#data[0]#data[1]#data[2]#data[3]#clk#data[5]#data[6]#data[7]#gpio[52]#gpio[53]} \ + CONFIG.PCW_NAND_GRP_D8_ENABLE {0} \ + CONFIG.PCW_NAND_PERIPHERAL_ENABLE {0} \ + CONFIG.PCW_NOR_GRP_A25_ENABLE {0} \ + CONFIG.PCW_NOR_GRP_CS0_ENABLE {0} \ + CONFIG.PCW_NOR_GRP_CS1_ENABLE {0} \ + CONFIG.PCW_NOR_GRP_SRAM_CS0_ENABLE {0} \ + CONFIG.PCW_NOR_GRP_SRAM_CS1_ENABLE {0} \ + CONFIG.PCW_NOR_GRP_SRAM_INT_ENABLE {0} \ + CONFIG.PCW_NOR_PERIPHERAL_ENABLE {0} \ + CONFIG.PCW_PCAP_PERIPHERAL_DIVISOR0 {5} \ + CONFIG.PCW_PRESET_BANK1_VOLTAGE {LVCMOS 1.8V} \ + CONFIG.PCW_QSPI_GRP_FBCLK_ENABLE {0} \ + CONFIG.PCW_QSPI_GRP_IO1_ENABLE {0} \ + CONFIG.PCW_QSPI_GRP_SINGLE_SS_ENABLE {1} \ + CONFIG.PCW_QSPI_GRP_SINGLE_SS_IO {MIO 1 .. 6} \ + CONFIG.PCW_QSPI_GRP_SS1_ENABLE {0} \ + CONFIG.PCW_QSPI_PERIPHERAL_DIVISOR0 {5} \ + CONFIG.PCW_QSPI_PERIPHERAL_ENABLE {1} \ + CONFIG.PCW_QSPI_PERIPHERAL_FREQMHZ {200} \ + CONFIG.PCW_QSPI_QSPI_IO {MIO 1 .. 6} \ + CONFIG.PCW_SD1_GRP_CD_ENABLE {0} \ + CONFIG.PCW_SD1_GRP_POW_ENABLE {0} \ + CONFIG.PCW_SD1_GRP_WP_ENABLE {0} \ + CONFIG.PCW_SD1_PERIPHERAL_ENABLE {1} \ + CONFIG.PCW_SD1_SD1_IO {MIO 10 .. 15} \ + CONFIG.PCW_SDIO_PERIPHERAL_DIVISOR0 {20} \ + CONFIG.PCW_SDIO_PERIPHERAL_FREQMHZ {50} \ + CONFIG.PCW_SDIO_PERIPHERAL_VALID {1} \ + CONFIG.PCW_SINGLE_QSPI_DATA_MODE {x4} \ + CONFIG.PCW_SMC_PERIPHERAL_DIVISOR0 {1} \ + CONFIG.PCW_SPI_PERIPHERAL_DIVISOR0 {1} \ + CONFIG.PCW_TPIU_PERIPHERAL_DIVISOR0 {1} \ + CONFIG.PCW_UART1_GRP_FULL_ENABLE {0} \ + CONFIG.PCW_UART1_PERIPHERAL_ENABLE {1} \ + CONFIG.PCW_UART1_UART1_IO {MIO 8 .. 9} \ + CONFIG.PCW_UART_PERIPHERAL_DIVISOR0 {10} \ + CONFIG.PCW_UART_PERIPHERAL_FREQMHZ {100} \ + CONFIG.PCW_UART_PERIPHERAL_VALID {1} \ + CONFIG.PCW_UIPARAM_ACT_DDR_FREQ_MHZ {400.000000} \ + CONFIG.PCW_UIPARAM_DDR_BANK_ADDR_COUNT {3} \ + CONFIG.PCW_UIPARAM_DDR_BOARD_DELAY0 {0.434} \ + CONFIG.PCW_UIPARAM_DDR_BOARD_DELAY1 {0.398} \ + CONFIG.PCW_UIPARAM_DDR_BOARD_DELAY2 {0.410} \ + CONFIG.PCW_UIPARAM_DDR_BOARD_DELAY3 {0.455} \ + CONFIG.PCW_UIPARAM_DDR_CL {9} \ + CONFIG.PCW_UIPARAM_DDR_COL_ADDR_COUNT {10} \ + CONFIG.PCW_UIPARAM_DDR_CWL {9} \ + CONFIG.PCW_UIPARAM_DDR_DEVICE_CAPACITY {8192 MBits} \ + CONFIG.PCW_UIPARAM_DDR_DQS_TO_CLK_DELAY_0 {0.315} \ + CONFIG.PCW_UIPARAM_DDR_DQS_TO_CLK_DELAY_1 {0.391} \ + CONFIG.PCW_UIPARAM_DDR_DQS_TO_CLK_DELAY_2 {0.374} \ + CONFIG.PCW_UIPARAM_DDR_DQS_TO_CLK_DELAY_3 {0.271} \ + CONFIG.PCW_UIPARAM_DDR_DRAM_WIDTH {32 Bits} \ + CONFIG.PCW_UIPARAM_DDR_FREQ_MHZ {400.00} \ + CONFIG.PCW_UIPARAM_DDR_PARTNO {Custom} \ + CONFIG.PCW_UIPARAM_DDR_ROW_ADDR_COUNT {15} \ + CONFIG.PCW_UIPARAM_DDR_SPEED_BIN {DDR3_1066F} \ + CONFIG.PCW_UIPARAM_DDR_T_FAW {50} \ + CONFIG.PCW_UIPARAM_DDR_T_RAS_MIN {40} \ + CONFIG.PCW_UIPARAM_DDR_T_RC {60} \ + CONFIG.PCW_UIPARAM_DDR_T_RCD {9} \ + CONFIG.PCW_UIPARAM_DDR_T_RP {9} \ + CONFIG.PCW_UIPARAM_DDR_USE_INTERNAL_VREF {1} \ + CONFIG.PCW_USB0_PERIPHERAL_ENABLE {1} \ + CONFIG.PCW_USB0_PERIPHERAL_FREQMHZ {60} \ + CONFIG.PCW_USB0_RESET_ENABLE {0} \ + CONFIG.PCW_USB0_USB0_IO {MIO 28 .. 39} \ + CONFIG.PCW_USB1_PERIPHERAL_ENABLE {1} \ + CONFIG.PCW_USB1_PERIPHERAL_FREQMHZ {60} \ + CONFIG.PCW_USB1_RESET_ENABLE {0} \ + CONFIG.PCW_USB1_USB1_IO {MIO 40 .. 51} \ + CONFIG.PCW_USB_RESET_ENABLE {1} \ + CONFIG.PCW_USB_RESET_SELECT {Share reset pin} \ + CONFIG.PCW_USE_DMA0 {1} \ + CONFIG.PCW_USE_FABRIC_INTERRUPT {1} \ + CONFIG.PCW_USE_M_AXI_GP0 {1} \ + CONFIG.PCW_USE_M_AXI_GP1 {1} \ + CONFIG.PCW_USE_S_AXI_HP0 {1} \ + CONFIG.PCW_USE_S_AXI_HP1 {1} \ + ] $processing_system7_0 + + # Create instance: sys_concat_intc, and set properties + set sys_concat_intc [ create_bd_cell -type ip -vlnv xilinx.com:ip:xlconcat:2.1 sys_concat_intc ] + set_property -dict [ list \ + CONFIG.NUM_PORTS {16} \ + ] $sys_concat_intc + + # Create interface connections + connect_bd_intf_net -intf_net axi_hdmi_intercon_M00_AXI [get_bd_intf_pins axi_hdmi_intercon/M00_AXI] [get_bd_intf_pins hdmi_0/S_AXI] + connect_bd_intf_net -intf_net axi_hdmi_intercon_M01_AXI [get_bd_intf_pins axi_hdmi_intercon/M01_AXI] [get_bd_intf_pins hdmi_0/S_AXI_LITE] + connect_bd_intf_net -intf_net axi_hdmi_intercon_M02_AXI [get_bd_intf_pins axi_hdmi_intercon/M02_AXI] [get_bd_intf_pins hdmi_0/s_axi1] + connect_bd_intf_net -intf_net axi_hdmi_intercon_M03_AXI [get_bd_intf_pins axi_hdmi_intercon/M03_AXI] [get_bd_intf_pins hdmi_0/s_axi2] + connect_bd_intf_net -intf_net axi_parallella_m_intercon_M00_AXI [get_bd_intf_pins axi_parallella_m_intercon/M00_AXI] [get_bd_intf_pins processing_system7_0/S_AXI_HP1] + connect_bd_intf_net -intf_net axi_parallella_s_intercon_M00_AXI [get_bd_intf_pins axi_parallella_s_intercon/M00_AXI] [get_bd_intf_pins parallella_base_0/s_axi] + connect_bd_intf_net -intf_net hdmi_0_DMA_REQ [get_bd_intf_pins hdmi_0/DMA_REQ] [get_bd_intf_pins processing_system7_0/DMA0_REQ] + connect_bd_intf_net -intf_net hdmi_0_M00_AXI [get_bd_intf_pins hdmi_0/M00_AXI] [get_bd_intf_pins processing_system7_0/S_AXI_HP0] + connect_bd_intf_net -intf_net parallella_base_0_m_axi [get_bd_intf_pins axi_parallella_m_intercon/S00_AXI] [get_bd_intf_pins parallella_base_0/m_axi] + connect_bd_intf_net -intf_net processing_system7_0_DDR [get_bd_intf_ports DDR] [get_bd_intf_pins processing_system7_0/DDR] + connect_bd_intf_net -intf_net processing_system7_0_DMA0_ACK [get_bd_intf_pins hdmi_0/DMA_ACK] [get_bd_intf_pins processing_system7_0/DMA0_ACK] + connect_bd_intf_net -intf_net processing_system7_0_FIXED_IO [get_bd_intf_ports FIXED_IO] [get_bd_intf_pins processing_system7_0/FIXED_IO] + connect_bd_intf_net -intf_net processing_system7_0_M_AXI_GP0 [get_bd_intf_pins axi_hdmi_intercon/S00_AXI] [get_bd_intf_pins processing_system7_0/M_AXI_GP0] + connect_bd_intf_net -intf_net processing_system7_0_M_AXI_GP1 [get_bd_intf_pins axi_parallella_s_intercon/S00_AXI] [get_bd_intf_pins processing_system7_0/M_AXI_GP1] + + # Create port connections + connect_bd_net -net hdmi_0_hdmi_16_data [get_bd_ports hdmi_d] [get_bd_pins hdmi_0/hdmi_16_data] + connect_bd_net -net hdmi_0_hdmi_16_data_e [get_bd_ports hdmi_de] [get_bd_pins hdmi_0/hdmi_16_data_e] + connect_bd_net -net hdmi_0_hdmi_16_hsync [get_bd_ports hdmi_hsync] [get_bd_pins hdmi_0/hdmi_16_hsync] + connect_bd_net -net hdmi_0_hdmi_16_vsync [get_bd_ports hdmi_vsync] [get_bd_pins hdmi_0/hdmi_16_vsync] + connect_bd_net -net hdmi_0_hdmi_out_clk [get_bd_ports hdmi_clk] [get_bd_pins hdmi_0/hdmi_out_clk] + connect_bd_net -net hdmi_0_int [get_bd_ports hdmi_int] [get_bd_pins sys_concat_intc/In14] + connect_bd_net -net hdmi_0_mm2s_introut [get_bd_pins hdmi_0/mm2s_introut] [get_bd_pins sys_concat_intc/In15] + connect_bd_net -net hdmi_0_spdif_tx_o1 [get_bd_ports hdmi_spdif] [get_bd_pins hdmi_0/spdif_tx_o] + connect_bd_net -net parallella_base_0_cclk_n [get_bd_ports cclk_n] [get_bd_pins parallella_base_0/cclk_n] + connect_bd_net -net parallella_base_0_cclk_p [get_bd_ports cclk_p] [get_bd_pins parallella_base_0/cclk_p] + connect_bd_net -net parallella_base_0_chip_resetb [get_bd_ports chip_nreset] [get_bd_pins parallella_base_0/chip_nreset] + connect_bd_net -net parallella_base_0_constant_zero [get_bd_pins parallella_base_0/constant_zero] [get_bd_pins sys_concat_intc/In0] [get_bd_pins sys_concat_intc/In1] [get_bd_pins sys_concat_intc/In2] [get_bd_pins sys_concat_intc/In3] [get_bd_pins sys_concat_intc/In4] [get_bd_pins sys_concat_intc/In5] [get_bd_pins sys_concat_intc/In6] [get_bd_pins sys_concat_intc/In7] [get_bd_pins sys_concat_intc/In8] [get_bd_pins sys_concat_intc/In9] [get_bd_pins sys_concat_intc/In10] [get_bd_pins sys_concat_intc/In12] [get_bd_pins sys_concat_intc/In13] + connect_bd_net -net parallella_base_0_gpio_n [get_bd_ports gpio_n] [get_bd_pins parallella_base_0/gpio_n] + connect_bd_net -net parallella_base_0_gpio_p [get_bd_ports gpio_p] [get_bd_pins parallella_base_0/gpio_p] + connect_bd_net -net parallella_base_0_i2c_scl [get_bd_ports i2c_scl] [get_bd_pins parallella_base_0/i2c_scl] + connect_bd_net -net parallella_base_0_i2c_scl_i [get_bd_pins parallella_base_0/i2c_scl_i] [get_bd_pins processing_system7_0/I2C0_SCL_I] + connect_bd_net -net parallella_base_0_i2c_sda [get_bd_ports i2c_sda] [get_bd_pins parallella_base_0/i2c_sda] + connect_bd_net -net parallella_base_0_i2c_sda_i [get_bd_pins parallella_base_0/i2c_sda_i] [get_bd_pins processing_system7_0/I2C0_SDA_I] + connect_bd_net -net parallella_base_0_mailbox_irq [get_bd_pins parallella_base_0/mailbox_irq] [get_bd_pins sys_concat_intc/In11] + connect_bd_net -net parallella_base_0_ps_gpio_i [get_bd_pins parallella_base_0/ps_gpio_i] [get_bd_pins processing_system7_0/GPIO_I] + connect_bd_net -net parallella_base_0_rxo_rd_wait_n [get_bd_ports rxo_rd_wait_n] [get_bd_pins parallella_base_0/rxo_rd_wait_n] + connect_bd_net -net parallella_base_0_rxo_rd_wait_p [get_bd_ports rxo_rd_wait_p] [get_bd_pins parallella_base_0/rxo_rd_wait_p] + connect_bd_net -net parallella_base_0_rxo_wr_wait_n [get_bd_ports rxo_wr_wait_n] [get_bd_pins parallella_base_0/rxo_wr_wait_n] + connect_bd_net -net parallella_base_0_rxo_wr_wait_p [get_bd_ports rxo_wr_wait_p] [get_bd_pins parallella_base_0/rxo_wr_wait_p] + connect_bd_net -net parallella_base_0_txo_data_n [get_bd_ports txo_data_n] [get_bd_pins parallella_base_0/txo_data_n] + connect_bd_net -net parallella_base_0_txo_data_p [get_bd_ports txo_data_p] [get_bd_pins parallella_base_0/txo_data_p] + connect_bd_net -net parallella_base_0_txo_frame_n [get_bd_ports txo_frame_n] [get_bd_pins parallella_base_0/txo_frame_n] + connect_bd_net -net parallella_base_0_txo_frame_p [get_bd_ports txo_frame_p] [get_bd_pins parallella_base_0/txo_frame_p] + connect_bd_net -net parallella_base_0_txo_lclk_n [get_bd_ports txo_lclk_n] [get_bd_pins parallella_base_0/txo_lclk_n] + connect_bd_net -net parallella_base_0_txo_lclk_p [get_bd_ports txo_lclk_p] [get_bd_pins parallella_base_0/txo_lclk_p] + connect_bd_net -net proc_sys_reset_0_interconnect_aresetn [get_bd_pins axi_hdmi_intercon/ARESETN] [get_bd_pins axi_parallella_m_intercon/ARESETN] [get_bd_pins axi_parallella_s_intercon/ARESETN] [get_bd_pins proc_sys_reset_0/interconnect_aresetn] + connect_bd_net -net proc_sys_reset_0_peripheral_aresetn [get_bd_pins axi_hdmi_intercon/M00_ARESETN] [get_bd_pins axi_hdmi_intercon/M01_ARESETN] [get_bd_pins axi_hdmi_intercon/M02_ARESETN] [get_bd_pins axi_hdmi_intercon/M03_ARESETN] [get_bd_pins axi_hdmi_intercon/S00_ARESETN] [get_bd_pins axi_parallella_m_intercon/M00_ARESETN] [get_bd_pins axi_parallella_m_intercon/S00_ARESETN] [get_bd_pins axi_parallella_s_intercon/M00_ARESETN] [get_bd_pins axi_parallella_s_intercon/S00_ARESETN] [get_bd_pins hdmi_0/axi_resetn] [get_bd_pins parallella_base_0/m_axi_aresetn] [get_bd_pins parallella_base_0/s_axi_aresetn] [get_bd_pins parallella_base_0/sys_nreset] [get_bd_pins proc_sys_reset_0/peripheral_aresetn] + connect_bd_net -net processing_system7_0_FCLK_CLK0 [get_bd_pins axi_hdmi_intercon/ACLK] [get_bd_pins axi_hdmi_intercon/M00_ACLK] [get_bd_pins axi_hdmi_intercon/M01_ACLK] [get_bd_pins axi_hdmi_intercon/M02_ACLK] [get_bd_pins axi_hdmi_intercon/M03_ACLK] [get_bd_pins axi_hdmi_intercon/S00_ACLK] [get_bd_pins axi_parallella_m_intercon/ACLK] [get_bd_pins axi_parallella_m_intercon/M00_ACLK] [get_bd_pins axi_parallella_m_intercon/S00_ACLK] [get_bd_pins axi_parallella_s_intercon/ACLK] [get_bd_pins axi_parallella_s_intercon/M00_ACLK] [get_bd_pins axi_parallella_s_intercon/S00_ACLK] [get_bd_pins hdmi_0/s_axi_aclk] [get_bd_pins parallella_base_0/sys_clk] [get_bd_pins proc_sys_reset_0/slowest_sync_clk] [get_bd_pins processing_system7_0/DMA0_ACLK] [get_bd_pins processing_system7_0/FCLK_CLK0] [get_bd_pins processing_system7_0/M_AXI_GP0_ACLK] [get_bd_pins processing_system7_0/M_AXI_GP1_ACLK] [get_bd_pins processing_system7_0/S_AXI_HP0_ACLK] [get_bd_pins processing_system7_0/S_AXI_HP1_ACLK] + connect_bd_net -net processing_system7_0_FCLK_CLK2 [get_bd_pins hdmi_0/clk] [get_bd_pins processing_system7_0/FCLK_CLK2] + connect_bd_net -net processing_system7_0_FCLK_RESET0_N [get_bd_pins proc_sys_reset_0/ext_reset_in] [get_bd_pins processing_system7_0/FCLK_RESET0_N] + connect_bd_net -net processing_system7_0_GPIO_O [get_bd_pins parallella_base_0/ps_gpio_o] [get_bd_pins processing_system7_0/GPIO_O] + connect_bd_net -net processing_system7_0_GPIO_T [get_bd_pins parallella_base_0/ps_gpio_t] [get_bd_pins processing_system7_0/GPIO_T] + connect_bd_net -net processing_system7_0_I2C0_SCL_O [get_bd_pins parallella_base_0/i2c_scl_o] [get_bd_pins processing_system7_0/I2C0_SCL_O] + connect_bd_net -net processing_system7_0_I2C0_SCL_T [get_bd_pins parallella_base_0/i2c_scl_t] [get_bd_pins processing_system7_0/I2C0_SCL_T] + connect_bd_net -net processing_system7_0_I2C0_SDA_O [get_bd_pins parallella_base_0/i2c_sda_o] [get_bd_pins processing_system7_0/I2C0_SDA_O] + connect_bd_net -net processing_system7_0_I2C0_SDA_T [get_bd_pins parallella_base_0/i2c_sda_t] [get_bd_pins processing_system7_0/I2C0_SDA_T] + connect_bd_net -net rxi_data_n_1 [get_bd_ports rxi_data_n] [get_bd_pins parallella_base_0/rxi_data_n] + connect_bd_net -net rxi_data_p_1 [get_bd_ports rxi_data_p] [get_bd_pins parallella_base_0/rxi_data_p] + connect_bd_net -net rxi_frame_n_1 [get_bd_ports rxi_frame_n] [get_bd_pins parallella_base_0/rxi_frame_n] + connect_bd_net -net rxi_frame_p_1 [get_bd_ports rxi_frame_p] [get_bd_pins parallella_base_0/rxi_frame_p] + connect_bd_net -net rxi_lclk_n_1 [get_bd_ports rxi_lclk_n] [get_bd_pins parallella_base_0/rxi_lclk_n] + connect_bd_net -net rxi_lclk_p_1 [get_bd_ports rxi_lclk_p] [get_bd_pins parallella_base_0/rxi_lclk_p] + connect_bd_net -net sys_concat_intc_dout [get_bd_pins processing_system7_0/IRQ_F2P] [get_bd_pins sys_concat_intc/dout] + connect_bd_net -net txi_rd_wait_n_1 [get_bd_ports txi_rd_wait_n] [get_bd_pins parallella_base_0/txi_rd_wait_n] + connect_bd_net -net txi_rd_wait_p_1 [get_bd_ports txi_rd_wait_p] [get_bd_pins parallella_base_0/txi_rd_wait_p] + connect_bd_net -net txi_wr_wait_n_1 [get_bd_ports txi_wr_wait_n] [get_bd_pins parallella_base_0/txi_wr_wait_n] + connect_bd_net -net txi_wr_wait_p_1 [get_bd_ports txi_wr_wait_p] [get_bd_pins parallella_base_0/txi_wr_wait_p] + + # Create address segments + create_bd_addr_seg -range 0x40000000 -offset 0x00000000 [get_bd_addr_spaces parallella_base_0/m_axi] [get_bd_addr_segs processing_system7_0/S_AXI_HP1/HP1_DDR_LOWOCM] SEG_processing_system7_0_HP1_DDR_LOWOCM + create_bd_addr_seg -range 0x00010000 -offset 0x66000000 [get_bd_addr_spaces processing_system7_0/Data] [get_bd_addr_segs hdmi_0/axi_clkgen_0/s_axi/axi_lite] SEG_axi_clkgen_0_axi_lite + create_bd_addr_seg -range 0x00001000 -offset 0x43000000 [get_bd_addr_spaces processing_system7_0/Data] [get_bd_addr_segs hdmi_0/axi_dmac_0/s_axi/axi_lite] SEG_axi_dmac_0_axi_lite + create_bd_addr_seg -range 0x00010000 -offset 0x6C000000 [get_bd_addr_spaces processing_system7_0/Data] [get_bd_addr_segs hdmi_0/axi_hdmi_tx_0/s_axi/axi_lite] SEG_axi_hdmi_tx_0_axi_lite + create_bd_addr_seg -range 0x00010000 -offset 0x75C00000 [get_bd_addr_spaces processing_system7_0/Data] [get_bd_addr_segs hdmi_0/axi_spdif_tx_0/s_axi/axi_lite] SEG_axi_spdif_tx_0_axi_lite + create_bd_addr_seg -range 0x40000000 -offset 0x80000000 [get_bd_addr_spaces processing_system7_0/Data] [get_bd_addr_segs parallella_base_0/s_axi/axi_lite] SEG_parallella_base_0_axi_lite + create_bd_addr_seg -range 0x40000000 -offset 0x00000000 [get_bd_addr_spaces hdmi_0/axi_dmac_0/m_src_axi] [get_bd_addr_segs processing_system7_0/S_AXI_HP0/HP0_DDR_LOWOCM] SEG_processing_system7_0_HP0_DDR_LOWOCM + + + # Restore current instance + current_bd_instance $oldCurInst + + save_bd_design +} +# End of create_root_design() + + +################################################################## +# MAIN FLOW +################################################################## + +create_root_design "" + + diff --git a/src/parallella/fpga/hdmi_e16_z7010/system_params.tcl b/src/parallella/fpga/hdmi_e16_z7010/system_params.tcl new file mode 100644 index 00000000..51b2aecf --- /dev/null +++ b/src/parallella/fpga/hdmi_e16_z7010/system_params.tcl @@ -0,0 +1,27 @@ + +#Design name ("system" recommended) +set design system + +#Project directory ("." recommended) +set projdir ./ + +#Device name +set partname "xc7z010clg400-1" + +#Paths to all IP blocks to use in Vivado "system.bd" + +set ip_repos [list "../parallella_base" "../../../adi/hdl/library"] + +#All source files +set hdl_files [] + +#All constraints files +set constraints_files [list \ + ../parallella_timing.xdc \ + ../parallella_io.xdc \ + ] + +########################################################### +# PREPARE FOR SYNTHESIS +########################################################### +set oh_verilog_define "CFG_ASIC=0 CFG_PLATFORM=\"ZYNQ\"" diff --git a/src/parallella/fpga/hdmi_e16_z7020/Makefile b/src/parallella/fpga/hdmi_e16_z7020/Makefile new file mode 100644 index 00000000..2adf155d --- /dev/null +++ b/src/parallella/fpga/hdmi_e16_z7020/Makefile @@ -0,0 +1,34 @@ + +M_DEPS := run.tcl +M_DEPS += ../parallella_base/parallella_base.xpr +M_DEPS += ../parallella_base/run.tcl + +M_VIVADO := vivado -mode batch -source + +M_FLIST := *.cache +M_FLIST += *.data +M_FLIST += *.xpr +M_FLIST += *.log +M_FLIST += *.jou +M_FLIST += xgui +M_FLIST += *.runs +M_FLIST += *.srcs +M_FLIST += *.sdk +M_FLIST += .Xil +M_FLIST += parallella_e16_hdmi_gpiose_7020.bit.bin +M_FLIST += system_wrapper.bit.bin +M_FLIST += reports +M_FLIST += results +M_FLIST += system.hw +M_FLIST += system.ip_user_files + +.PHONY: all clean + +all: $(M_DEPS) + rm -f system_wrapper.bit.bin bit2bin.bin + $(M_VIVADO) run.tcl + bootgen -image bit2bin.bif -split bin + cp -f system_wrapper.bit.bin parallella_e16_hdmi_gpiose_7020.bit.bin + +clean: + rm -rf $(M_FLIST) diff --git a/src/parallella/fpga/hdmi_e16_z7020/bit2bin.bif b/src/parallella/fpga/hdmi_e16_z7020/bit2bin.bif new file mode 100644 index 00000000..df3de64e --- /dev/null +++ b/src/parallella/fpga/hdmi_e16_z7020/bit2bin.bif @@ -0,0 +1,6 @@ +the_ROM_image: +{ + [bootloader]dummy.elf + ./system.runs/impl_1/system_wrapper.bit +} + diff --git a/src/parallella/fpga/hdmi_e16_z7020/build.sh b/src/parallella/fpga/hdmi_e16_z7020/build.sh new file mode 100644 index 00000000..c43fc220 --- /dev/null +++ b/src/parallella/fpga/hdmi_e16_z7020/build.sh @@ -0,0 +1,6 @@ +#!/bin/bash +rm system_wrapper.bit.bin bit2bin.bin +vivado -mode batch -source run.tcl +bootgen -image bit2bin.bif -split bin +cp system_wrapper.bit.bin parallella_e16_hdmi_gpiose_7020.bit.bin +#archive results based on time stamp diff --git a/src/parallella/fpga/hdmi_e16_z7020/dummy.elf b/src/parallella/fpga/hdmi_e16_z7020/dummy.elf new file mode 100644 index 00000000..6d0b3e0a Binary files /dev/null and b/src/parallella/fpga/hdmi_e16_z7020/dummy.elf differ diff --git a/src/parallella/fpga/hdmi_e16_z7020/run.tcl b/src/parallella/fpga/hdmi_e16_z7020/run.tcl new file mode 100644 index 00000000..0ab34afc --- /dev/null +++ b/src/parallella/fpga/hdmi_e16_z7020/run.tcl @@ -0,0 +1,12 @@ + +#STEP1: DEFINE KEY PARAMETERS +source ./system_params.tcl + +#STEP2: CREATE PROJECT AND READ IN FILES +source ../../../common/fpga/system_init.tcl + +#STEP 3 (OPTIONAL): EDIT system.bd in VIVADO gui, then go to STEP 4. +##... + +#STEP 4: SYNTEHSIZE AND CREATE BITSTRAM +source ../../../common/fpga/system_build.tcl diff --git a/src/parallella/fpga/hdmi_e16_z7020/system_bd.tcl b/src/parallella/fpga/hdmi_e16_z7020/system_bd.tcl new file mode 100644 index 00000000..2e99b4e1 --- /dev/null +++ b/src/parallella/fpga/hdmi_e16_z7020/system_bd.tcl @@ -0,0 +1,925 @@ + +################################################################ +# This is a generated script based on design: system +# +# Though there are limitations about the generated script, +# the main purpose of this utility is to make learning +# IP Integrator Tcl commands easier. +################################################################ + +namespace eval _tcl { +proc get_script_folder {} { + set script_path [file normalize [info script]] + set script_folder [file dirname $script_path] + return $script_folder +} +} +variable script_folder +set script_folder [_tcl::get_script_folder] + +################################################################ +# Check if script is running in correct Vivado version. +################################################################ +set scripts_vivado_version 2018.2 +set current_vivado_version [version -short] + +if { [string first $scripts_vivado_version $current_vivado_version] == -1 } { + puts "" + catch {common::send_msg_id "BD_TCL-109" "ERROR" "This script was generated using Vivado <$scripts_vivado_version> and is being run in <$current_vivado_version> of Vivado. Please run the script in Vivado <$scripts_vivado_version> then open the design in Vivado <$current_vivado_version>. Upgrade the design by running \"Tools => Report => Report IP Status...\", then run write_bd_tcl to create an updated script."} + + return 1 +} + +################################################################ +# START +################################################################ + +# To test this script, run the following commands from Vivado Tcl console: +# source system_script.tcl + +# If there is no project opened, this script will create a +# project, but make sure you do not have an existing project +# <./myproj/project_1.xpr> in the current working folder. + +set list_projs [get_projects -quiet] +if { $list_projs eq "" } { + create_project project_1 myproj -part xc7z020clg400-1 +} + + +# CHANGE DESIGN NAME HERE +variable design_name +set design_name system + +# If you do not already have an existing IP Integrator design open, +# you can create a design using the following command: +# create_bd_design $design_name + +# Creating design if needed +set errMsg "" +set nRet 0 + +set cur_design [current_bd_design -quiet] +set list_cells [get_bd_cells -quiet] + +if { ${design_name} eq "" } { + # USE CASES: + # 1) Design_name not set + + set errMsg "Please set the variable to a non-empty value." + set nRet 1 + +} elseif { ${cur_design} ne "" && ${list_cells} eq "" } { + # USE CASES: + # 2): Current design opened AND is empty AND names same. + # 3): Current design opened AND is empty AND names diff; design_name NOT in project. + # 4): Current design opened AND is empty AND names diff; design_name exists in project. + + if { $cur_design ne $design_name } { + common::send_msg_id "BD_TCL-001" "INFO" "Changing value of from <$design_name> to <$cur_design> since current design is empty." + set design_name [get_property NAME $cur_design] + } + common::send_msg_id "BD_TCL-002" "INFO" "Constructing design in IPI design <$cur_design>..." + +} elseif { ${cur_design} ne "" && $list_cells ne "" && $cur_design eq $design_name } { + # USE CASES: + # 5) Current design opened AND has components AND same names. + + set errMsg "Design <$design_name> already exists in your project, please set the variable to another value." + set nRet 1 +} elseif { [get_files -quiet ${design_name}.bd] ne "" } { + # USE CASES: + # 6) Current opened design, has components, but diff names, design_name exists in project. + # 7) No opened design, design_name exists in project. + + set errMsg "Design <$design_name> already exists in your project, please set the variable to another value." + set nRet 2 + +} else { + # USE CASES: + # 8) No opened design, design_name not in project. + # 9) Current opened design, has components, but diff names, design_name not in project. + + common::send_msg_id "BD_TCL-003" "INFO" "Currently there is no design <$design_name> in project, so creating one..." + + create_bd_design $design_name + + common::send_msg_id "BD_TCL-004" "INFO" "Making design <$design_name> as current_bd_design." + current_bd_design $design_name + +} + +common::send_msg_id "BD_TCL-005" "INFO" "Currently the variable is equal to \"$design_name\"." + +if { $nRet != 0 } { + catch {common::send_msg_id "BD_TCL-114" "ERROR" $errMsg} + return $nRet +} + +set bCheckIPsPassed 1 +################################################################## +# CHECK IPs +################################################################## +set bCheckIPs 1 +if { $bCheckIPs == 1 } { + set list_check_ips "\ +www.parallella.org:user:parallella_base:1.0\ +xilinx.com:ip:proc_sys_reset:5.0\ +xilinx.com:ip:processing_system7:5.5\ +xilinx.com:ip:xlconcat:2.1\ +analog.com:user:axi_clkgen:1.0\ +analog.com:user:axi_dmac:1.0\ +analog.com:user:axi_hdmi_tx:1.0\ +analog.com:user:axi_spdif_tx:1.0\ +xilinx.com:ip:clk_wiz:6.0\ +" + + set list_ips_missing "" + common::send_msg_id "BD_TCL-006" "INFO" "Checking if the following IPs exist in the project's IP catalog: $list_check_ips ." + + foreach ip_vlnv $list_check_ips { + set ip_obj [get_ipdefs -all $ip_vlnv] + if { $ip_obj eq "" } { + lappend list_ips_missing $ip_vlnv + } + } + + if { $list_ips_missing ne "" } { + catch {common::send_msg_id "BD_TCL-115" "ERROR" "The following IPs are not found in the IP Catalog:\n $list_ips_missing\n\nResolution: Please add the repository containing the IP(s) to the project." } + set bCheckIPsPassed 0 + } + +} + +if { $bCheckIPsPassed != 1 } { + common::send_msg_id "BD_TCL-1003" "WARNING" "Will not continue with creation of design due to the error(s) above." + return 3 +} + +################################################################## +# DESIGN PROCs +################################################################## + + +# Hierarchical cell: hdmi_0 +proc create_hier_cell_hdmi_0 { parentCell nameHier } { + + variable script_folder + + if { $parentCell eq "" || $nameHier eq "" } { + catch {common::send_msg_id "BD_TCL-102" "ERROR" "create_hier_cell_hdmi_0() - Empty argument(s)!"} + return + } + + # Get object for parentCell + set parentObj [get_bd_cells $parentCell] + if { $parentObj == "" } { + catch {common::send_msg_id "BD_TCL-100" "ERROR" "Unable to find parent cell <$parentCell>!"} + return + } + + # Make sure parentObj is hier blk + set parentType [get_property TYPE $parentObj] + if { $parentType ne "hier" } { + catch {common::send_msg_id "BD_TCL-101" "ERROR" "Parent <$parentObj> has TYPE = <$parentType>. Expected to be ."} + return + } + + # Save current instance; Restore later + set oldCurInst [current_bd_instance .] + + # Set parent object as current + current_bd_instance $parentObj + + # Create cell and set as current instance + set hier_obj [create_bd_cell -type hier $nameHier] + current_bd_instance $hier_obj + + # Create interface pins + create_bd_intf_pin -mode Slave -vlnv xilinx.com:interface:axis_rtl:1.0 DMA_ACK + create_bd_intf_pin -mode Master -vlnv xilinx.com:interface:axis_rtl:1.0 DMA_REQ + create_bd_intf_pin -mode Master -vlnv xilinx.com:interface:aximm_rtl:1.0 M00_AXI + create_bd_intf_pin -mode Slave -vlnv xilinx.com:interface:aximm_rtl:1.0 S_AXI + create_bd_intf_pin -mode Slave -vlnv xilinx.com:interface:aximm_rtl:1.0 S_AXI_LITE + create_bd_intf_pin -mode Slave -vlnv xilinx.com:interface:aximm_rtl:1.0 s_axi1 + create_bd_intf_pin -mode Slave -vlnv xilinx.com:interface:aximm_rtl:1.0 s_axi2 + + # Create pins + create_bd_pin -dir I -from 0 -to 0 -type rst axi_resetn + create_bd_pin -dir I clk + create_bd_pin -dir O -from 15 -to 0 hdmi_16_data + create_bd_pin -dir O hdmi_16_data_e + create_bd_pin -dir O hdmi_16_hsync + create_bd_pin -dir O hdmi_16_vsync + create_bd_pin -dir O -type clk hdmi_out_clk + create_bd_pin -dir O -type intr mm2s_introut + create_bd_pin -dir I -type clk s_axi_aclk + create_bd_pin -dir O spdif_tx_o + + # Create instance: axi_clkgen_0, and set properties + set axi_clkgen_0 [ create_bd_cell -type ip -vlnv analog.com:user:axi_clkgen:1.0 axi_clkgen_0 ] + + # Create instance: axi_dmac_0, and set properties + set axi_dmac_0 [ create_bd_cell -type ip -vlnv analog.com:user:axi_dmac:1.0 axi_dmac_0 ] + set_property -dict [ list \ + CONFIG.CYCLIC {true} \ + CONFIG.DMA_2D_TRANSFER {true} \ + CONFIG.DMA_TYPE_DEST {1} \ + CONFIG.DMA_TYPE_SRC {0} \ + ] $axi_dmac_0 + + # Create instance: axi_hdmi_tx_0, and set properties + set axi_hdmi_tx_0 [ create_bd_cell -type ip -vlnv analog.com:user:axi_hdmi_tx:1.0 axi_hdmi_tx_0 ] + + # Create instance: axi_interconnect_0, and set properties + set axi_interconnect_0 [ create_bd_cell -type ip -vlnv xilinx.com:ip:axi_interconnect:2.1 axi_interconnect_0 ] + set_property -dict [ list \ + CONFIG.NUM_MI {1} \ + ] $axi_interconnect_0 + + # Create instance: axi_spdif_tx_0, and set properties + set axi_spdif_tx_0 [ create_bd_cell -type ip -vlnv analog.com:user:axi_spdif_tx:1.0 axi_spdif_tx_0 ] + set_property -dict [ list \ + CONFIG.DMA_TYPE {1} \ + CONFIG.S_AXI_ADDRESS_WIDTH {16} \ + ] $axi_spdif_tx_0 + + # Create instance: spdif_clk_0, and set properties + set spdif_clk_0 [ create_bd_cell -type ip -vlnv xilinx.com:ip:clk_wiz:6.0 spdif_clk_0 ] + set_property -dict [ list \ + CONFIG.AXI_DRP {false} \ + CONFIG.CLKIN1_JITTER_PS {50.0} \ + CONFIG.CLKOUT1_DRIVES {No_buffer} \ + CONFIG.CLKOUT1_JITTER {307.400} \ + CONFIG.CLKOUT1_PHASE_ERROR {262.328} \ + CONFIG.CLKOUT1_REQUESTED_OUT_FREQ {12.288} \ + CONFIG.CLKOUT2_DRIVES {BUFG} \ + CONFIG.CLKOUT3_DRIVES {BUFG} \ + CONFIG.CLKOUT4_DRIVES {BUFG} \ + CONFIG.CLKOUT5_DRIVES {BUFG} \ + CONFIG.CLKOUT6_DRIVES {BUFG} \ + CONFIG.CLKOUT7_DRIVES {BUFG} \ + CONFIG.FEEDBACK_SOURCE {FDBK_ONCHIP} \ + CONFIG.MMCM_CLKFBOUT_MULT_F {47} \ + CONFIG.MMCM_CLKIN1_PERIOD {5.000} \ + CONFIG.MMCM_CLKOUT0_DIVIDE_F {85} \ + CONFIG.MMCM_COMPENSATION {ZHOLD} \ + CONFIG.MMCM_DIVCLK_DIVIDE {9} \ + CONFIG.PHASE_DUTY_CONFIG {false} \ + CONFIG.PRIMITIVE {PLL} \ + CONFIG.PRIM_IN_FREQ {200.000} \ + CONFIG.PRIM_SOURCE {No_buffer} \ + CONFIG.RESET_PORT {resetn} \ + CONFIG.RESET_TYPE {ACTIVE_LOW} \ + CONFIG.SECONDARY_SOURCE {Single_ended_clock_capable_pin} \ + CONFIG.USE_DYN_RECONFIG {false} \ + CONFIG.USE_LOCKED {false} \ + CONFIG.USE_PHASE_ALIGNMENT {false} \ + CONFIG.USE_RESET {true} \ + CONFIG.USE_SAFE_CLOCK_STARTUP {false} \ + ] $spdif_clk_0 + + # Create interface connections + connect_bd_intf_net -intf_net DMA_ACK_1 [get_bd_intf_pins DMA_ACK] [get_bd_intf_pins axi_spdif_tx_0/dma_ack] + connect_bd_intf_net -intf_net S_AXI_1 [get_bd_intf_pins S_AXI] [get_bd_intf_pins axi_spdif_tx_0/s_axi] + connect_bd_intf_net -intf_net S_AXI_LITE_1 [get_bd_intf_pins S_AXI_LITE] [get_bd_intf_pins axi_dmac_0/s_axi] + connect_bd_intf_net -intf_net axi_dmac_0_m_axis [get_bd_intf_pins axi_dmac_0/m_axis] [get_bd_intf_pins axi_hdmi_tx_0/s_axis] + connect_bd_intf_net -intf_net axi_dmac_0_m_src_axi [get_bd_intf_pins axi_dmac_0/m_src_axi] [get_bd_intf_pins axi_interconnect_0/S00_AXI] + connect_bd_intf_net -intf_net axi_interconnect_0_M00_AXI [get_bd_intf_pins M00_AXI] [get_bd_intf_pins axi_interconnect_0/M00_AXI] + connect_bd_intf_net -intf_net axi_spdif_tx_0_DMA_REQ [get_bd_intf_pins DMA_REQ] [get_bd_intf_pins axi_spdif_tx_0/dma_req] + connect_bd_intf_net -intf_net s_axi1_1 [get_bd_intf_pins s_axi1] [get_bd_intf_pins axi_clkgen_0/s_axi] + connect_bd_intf_net -intf_net s_axi2_1 [get_bd_intf_pins s_axi2] [get_bd_intf_pins axi_hdmi_tx_0/s_axi] + + # Create port connections + connect_bd_net -net axi_clkgen_0_clk_0 [get_bd_pins axi_clkgen_0/clk_0] [get_bd_pins axi_hdmi_tx_0/hdmi_clk] + connect_bd_net -net axi_dmac_0_irq [get_bd_pins mm2s_introut] [get_bd_pins axi_dmac_0/irq] + connect_bd_net -net axi_hdmi_tx_0_hdmi_16_data [get_bd_pins hdmi_16_data] [get_bd_pins axi_hdmi_tx_0/hdmi_16_data] + connect_bd_net -net axi_hdmi_tx_0_hdmi_16_data_e [get_bd_pins hdmi_16_data_e] [get_bd_pins axi_hdmi_tx_0/hdmi_16_data_e] + connect_bd_net -net axi_hdmi_tx_0_hdmi_16_hsync [get_bd_pins hdmi_16_hsync] [get_bd_pins axi_hdmi_tx_0/hdmi_16_hsync] + connect_bd_net -net axi_hdmi_tx_0_hdmi_16_vsync [get_bd_pins hdmi_16_vsync] [get_bd_pins axi_hdmi_tx_0/hdmi_16_vsync] + connect_bd_net -net axi_hdmi_tx_0_hdmi_out_clk [get_bd_pins hdmi_out_clk] [get_bd_pins axi_hdmi_tx_0/hdmi_out_clk] + connect_bd_net -net axi_resetn_1 [get_bd_pins axi_resetn] [get_bd_pins axi_clkgen_0/s_axi_aresetn] [get_bd_pins axi_dmac_0/m_src_axi_aresetn] [get_bd_pins axi_dmac_0/s_axi_aresetn] [get_bd_pins axi_hdmi_tx_0/s_axi_aresetn] [get_bd_pins axi_interconnect_0/ARESETN] [get_bd_pins axi_interconnect_0/M00_ARESETN] [get_bd_pins axi_interconnect_0/S00_ARESETN] [get_bd_pins axi_spdif_tx_0/dma_req_rstn] [get_bd_pins axi_spdif_tx_0/s_axi_aresetn] [get_bd_pins spdif_clk_0/resetn] + connect_bd_net -net axi_spdif_tx_0_spdif_tx_o [get_bd_pins spdif_tx_o] [get_bd_pins axi_spdif_tx_0/spdif_tx_o] + connect_bd_net -net clk_1 [get_bd_pins clk] [get_bd_pins axi_clkgen_0/clk] [get_bd_pins spdif_clk_0/clk_in1] + connect_bd_net -net clk_wiz_0_clk_out1 [get_bd_pins axi_spdif_tx_0/spdif_data_clk] [get_bd_pins spdif_clk_0/clk_out1] + connect_bd_net -net s_axi_aclk_1 [get_bd_pins s_axi_aclk] [get_bd_pins axi_clkgen_0/s_axi_aclk] [get_bd_pins axi_dmac_0/m_axis_aclk] [get_bd_pins axi_dmac_0/m_src_axi_aclk] [get_bd_pins axi_dmac_0/s_axi_aclk] [get_bd_pins axi_hdmi_tx_0/s_axi_aclk] [get_bd_pins axi_hdmi_tx_0/vdma_clk] [get_bd_pins axi_interconnect_0/ACLK] [get_bd_pins axi_interconnect_0/M00_ACLK] [get_bd_pins axi_interconnect_0/S00_ACLK] [get_bd_pins axi_spdif_tx_0/dma_req_aclk] [get_bd_pins axi_spdif_tx_0/s_axi_aclk] + + # Restore current instance + current_bd_instance $oldCurInst +} + + +# Procedure to create entire design; Provide argument to make +# procedure reusable. If parentCell is "", will use root. +proc create_root_design { parentCell } { + + variable script_folder + variable design_name + + if { $parentCell eq "" } { + set parentCell [get_bd_cells /] + } + + # Get object for parentCell + set parentObj [get_bd_cells $parentCell] + if { $parentObj == "" } { + catch {common::send_msg_id "BD_TCL-100" "ERROR" "Unable to find parent cell <$parentCell>!"} + return + } + + # Make sure parentObj is hier blk + set parentType [get_property TYPE $parentObj] + if { $parentType ne "hier" } { + catch {common::send_msg_id "BD_TCL-101" "ERROR" "Parent <$parentObj> has TYPE = <$parentType>. Expected to be ."} + return + } + + # Save current instance; Restore later + set oldCurInst [current_bd_instance .] + + # Set parent object as current + current_bd_instance $parentObj + + + # Create interface ports + set DDR [ create_bd_intf_port -mode Master -vlnv xilinx.com:interface:ddrx_rtl:1.0 DDR ] + set FIXED_IO [ create_bd_intf_port -mode Master -vlnv xilinx.com:display_processing_system7:fixedio_rtl:1.0 FIXED_IO ] + + # Create ports + set cclk_n [ create_bd_port -dir O cclk_n ] + set cclk_p [ create_bd_port -dir O cclk_p ] + set chip_nreset [ create_bd_port -dir O chip_nreset ] + set gpio_n [ create_bd_port -dir IO -from 23 -to 0 gpio_n ] + set gpio_p [ create_bd_port -dir IO -from 23 -to 0 gpio_p ] + set hdmi_clk [ create_bd_port -dir O -type clk hdmi_clk ] + set hdmi_d [ create_bd_port -dir O -from 15 -to 0 hdmi_d ] + set hdmi_de [ create_bd_port -dir O hdmi_de ] + set hdmi_hsync [ create_bd_port -dir O hdmi_hsync ] + set hdmi_int [ create_bd_port -dir I hdmi_int ] + set hdmi_spdif [ create_bd_port -dir O hdmi_spdif ] + set hdmi_vsync [ create_bd_port -dir O hdmi_vsync ] + set i2c_scl [ create_bd_port -dir IO i2c_scl ] + set i2c_sda [ create_bd_port -dir IO i2c_sda ] + set rxi_data_n [ create_bd_port -dir I -from 7 -to 0 rxi_data_n ] + set rxi_data_p [ create_bd_port -dir I -from 7 -to 0 rxi_data_p ] + set rxi_frame_n [ create_bd_port -dir I rxi_frame_n ] + set rxi_frame_p [ create_bd_port -dir I rxi_frame_p ] + set rxi_lclk_n [ create_bd_port -dir I rxi_lclk_n ] + set rxi_lclk_p [ create_bd_port -dir I rxi_lclk_p ] + set rxo_rd_wait_n [ create_bd_port -dir O rxo_rd_wait_n ] + set rxo_rd_wait_p [ create_bd_port -dir O rxo_rd_wait_p ] + set rxo_wr_wait_n [ create_bd_port -dir O rxo_wr_wait_n ] + set rxo_wr_wait_p [ create_bd_port -dir O rxo_wr_wait_p ] + set txi_rd_wait_n [ create_bd_port -dir I txi_rd_wait_n ] + set txi_rd_wait_p [ create_bd_port -dir I txi_rd_wait_p ] + set txi_wr_wait_n [ create_bd_port -dir I txi_wr_wait_n ] + set txi_wr_wait_p [ create_bd_port -dir I txi_wr_wait_p ] + set txo_data_n [ create_bd_port -dir O -from 7 -to 0 txo_data_n ] + set txo_data_p [ create_bd_port -dir O -from 7 -to 0 txo_data_p ] + set txo_frame_n [ create_bd_port -dir O txo_frame_n ] + set txo_frame_p [ create_bd_port -dir O txo_frame_p ] + set txo_lclk_n [ create_bd_port -dir O txo_lclk_n ] + set txo_lclk_p [ create_bd_port -dir O txo_lclk_p ] + + # Create instance: axi_hdmi_intercon, and set properties + set axi_hdmi_intercon [ create_bd_cell -type ip -vlnv xilinx.com:ip:axi_interconnect:2.1 axi_hdmi_intercon ] + set_property -dict [ list \ + CONFIG.NUM_MI {4} \ + ] $axi_hdmi_intercon + + # Create instance: axi_parallella_m_intercon, and set properties + set axi_parallella_m_intercon [ create_bd_cell -type ip -vlnv xilinx.com:ip:axi_interconnect:2.1 axi_parallella_m_intercon ] + set_property -dict [ list \ + CONFIG.NUM_MI {1} \ + CONFIG.NUM_SI {1} \ + ] $axi_parallella_m_intercon + + # Create instance: axi_parallella_s_intercon, and set properties + set axi_parallella_s_intercon [ create_bd_cell -type ip -vlnv xilinx.com:ip:axi_interconnect:2.1 axi_parallella_s_intercon ] + set_property -dict [ list \ + CONFIG.NUM_MI {1} \ + ] $axi_parallella_s_intercon + + # Create instance: hdmi_0 + create_hier_cell_hdmi_0 [current_bd_instance .] hdmi_0 + + # Create instance: parallella_base_0, and set properties + set parallella_base_0 [ create_bd_cell -type ip -vlnv www.parallella.org:user:parallella_base:1.0 parallella_base_0 ] + set_property -dict [ list \ + CONFIG.NGPIO {24} \ + ] $parallella_base_0 + + # Create instance: proc_sys_reset_0, and set properties + set proc_sys_reset_0 [ create_bd_cell -type ip -vlnv xilinx.com:ip:proc_sys_reset:5.0 proc_sys_reset_0 ] + + # Create instance: processing_system7_0, and set properties + set processing_system7_0 [ create_bd_cell -type ip -vlnv xilinx.com:ip:processing_system7:5.5 processing_system7_0 ] + set_property -dict [ list \ + CONFIG.PCW_ACT_APU_PERIPHERAL_FREQMHZ {666.666687} \ + CONFIG.PCW_ACT_CAN_PERIPHERAL_FREQMHZ {10.000000} \ + CONFIG.PCW_ACT_DCI_PERIPHERAL_FREQMHZ {10.062893} \ + CONFIG.PCW_ACT_ENET0_PERIPHERAL_FREQMHZ {125.000000} \ + CONFIG.PCW_ACT_ENET1_PERIPHERAL_FREQMHZ {10.000000} \ + CONFIG.PCW_ACT_FPGA0_PERIPHERAL_FREQMHZ {100.000000} \ + CONFIG.PCW_ACT_FPGA1_PERIPHERAL_FREQMHZ {10.000000} \ + CONFIG.PCW_ACT_FPGA2_PERIPHERAL_FREQMHZ {200.000000} \ + CONFIG.PCW_ACT_FPGA3_PERIPHERAL_FREQMHZ {10.000000} \ + CONFIG.PCW_ACT_PCAP_PERIPHERAL_FREQMHZ {200.000000} \ + CONFIG.PCW_ACT_QSPI_PERIPHERAL_FREQMHZ {200.000000} \ + CONFIG.PCW_ACT_SDIO_PERIPHERAL_FREQMHZ {50.000000} \ + CONFIG.PCW_ACT_SMC_PERIPHERAL_FREQMHZ {10.000000} \ + CONFIG.PCW_ACT_SPI_PERIPHERAL_FREQMHZ {10.000000} \ + CONFIG.PCW_ACT_TPIU_PERIPHERAL_FREQMHZ {200.000000} \ + CONFIG.PCW_ACT_TTC0_CLK0_PERIPHERAL_FREQMHZ {111.111115} \ + CONFIG.PCW_ACT_TTC0_CLK1_PERIPHERAL_FREQMHZ {111.111115} \ + CONFIG.PCW_ACT_TTC0_CLK2_PERIPHERAL_FREQMHZ {111.111115} \ + CONFIG.PCW_ACT_TTC1_CLK0_PERIPHERAL_FREQMHZ {111.111115} \ + CONFIG.PCW_ACT_TTC1_CLK1_PERIPHERAL_FREQMHZ {111.111115} \ + CONFIG.PCW_ACT_TTC1_CLK2_PERIPHERAL_FREQMHZ {111.111115} \ + CONFIG.PCW_ACT_UART_PERIPHERAL_FREQMHZ {100.000000} \ + CONFIG.PCW_ACT_WDT_PERIPHERAL_FREQMHZ {111.111115} \ + CONFIG.PCW_ARMPLL_CTRL_FBDIV {40} \ + CONFIG.PCW_CAN_PERIPHERAL_DIVISOR0 {1} \ + CONFIG.PCW_CAN_PERIPHERAL_DIVISOR1 {1} \ + CONFIG.PCW_CLK0_FREQ {100000000} \ + CONFIG.PCW_CLK1_FREQ {10000000} \ + CONFIG.PCW_CLK2_FREQ {200000000} \ + CONFIG.PCW_CLK3_FREQ {10000000} \ + CONFIG.PCW_CORE0_FIQ_INTR {0} \ + CONFIG.PCW_CPU_CPU_PLL_FREQMHZ {1333.333} \ + CONFIG.PCW_CPU_PERIPHERAL_DIVISOR0 {2} \ + CONFIG.PCW_DCI_PERIPHERAL_DIVISOR0 {53} \ + CONFIG.PCW_DCI_PERIPHERAL_DIVISOR1 {3} \ + CONFIG.PCW_DDRPLL_CTRL_FBDIV {48} \ + CONFIG.PCW_DDR_DDR_PLL_FREQMHZ {1600.000} \ + CONFIG.PCW_DDR_PERIPHERAL_DIVISOR0 {4} \ + CONFIG.PCW_DDR_RAM_HIGHADDR {0x3FFFFFFF} \ + CONFIG.PCW_ENET0_ENET0_IO {MIO 16 .. 27} \ + CONFIG.PCW_ENET0_GRP_MDIO_ENABLE {1} \ + CONFIG.PCW_ENET0_GRP_MDIO_IO {EMIO} \ + CONFIG.PCW_ENET0_PERIPHERAL_DIVISOR0 {8} \ + CONFIG.PCW_ENET0_PERIPHERAL_DIVISOR1 {1} \ + CONFIG.PCW_ENET0_PERIPHERAL_ENABLE {1} \ + CONFIG.PCW_ENET0_PERIPHERAL_FREQMHZ {1000 Mbps} \ + CONFIG.PCW_ENET0_RESET_ENABLE {0} \ + CONFIG.PCW_ENET1_GRP_MDIO_ENABLE {0} \ + CONFIG.PCW_ENET1_PERIPHERAL_DIVISOR0 {1} \ + CONFIG.PCW_ENET1_PERIPHERAL_DIVISOR1 {1} \ + CONFIG.PCW_ENET1_PERIPHERAL_ENABLE {0} \ + CONFIG.PCW_ENET1_PERIPHERAL_FREQMHZ {1000 Mbps} \ + CONFIG.PCW_ENET1_RESET_ENABLE {0} \ + CONFIG.PCW_ENET_RESET_ENABLE {1} \ + CONFIG.PCW_ENET_RESET_SELECT {Share reset pin} \ + CONFIG.PCW_EN_CLK1_PORT {0} \ + CONFIG.PCW_EN_CLK2_PORT {1} \ + CONFIG.PCW_EN_CLK3_PORT {0} \ + CONFIG.PCW_EN_EMIO_CD_SDIO1 {0} \ + CONFIG.PCW_EN_EMIO_GPIO {1} \ + CONFIG.PCW_EN_EMIO_I2C0 {1} \ + CONFIG.PCW_EN_EMIO_SDIO1 {0} \ + CONFIG.PCW_EN_EMIO_WP_SDIO1 {0} \ + CONFIG.PCW_EN_ENET0 {1} \ + CONFIG.PCW_EN_GPIO {1} \ + CONFIG.PCW_EN_I2C0 {1} \ + CONFIG.PCW_EN_QSPI {1} \ + CONFIG.PCW_EN_SDIO1 {1} \ + CONFIG.PCW_EN_UART1 {1} \ + CONFIG.PCW_EN_USB0 {1} \ + CONFIG.PCW_EN_USB1 {1} \ + CONFIG.PCW_FCLK0_PERIPHERAL_DIVISOR0 {5} \ + CONFIG.PCW_FCLK0_PERIPHERAL_DIVISOR1 {2} \ + CONFIG.PCW_FCLK1_PERIPHERAL_DIVISOR0 {1} \ + CONFIG.PCW_FCLK1_PERIPHERAL_DIVISOR1 {1} \ + CONFIG.PCW_FCLK2_PERIPHERAL_DIVISOR0 {5} \ + CONFIG.PCW_FCLK2_PERIPHERAL_DIVISOR1 {1} \ + CONFIG.PCW_FCLK3_PERIPHERAL_DIVISOR0 {1} \ + CONFIG.PCW_FCLK3_PERIPHERAL_DIVISOR1 {1} \ + CONFIG.PCW_FCLK_CLK1_BUF {FALSE} \ + CONFIG.PCW_FCLK_CLK2_BUF {TRUE} \ + CONFIG.PCW_FCLK_CLK3_BUF {FALSE} \ + CONFIG.PCW_FPGA0_PERIPHERAL_FREQMHZ {100} \ + CONFIG.PCW_FPGA1_PERIPHERAL_FREQMHZ {152} \ + CONFIG.PCW_FPGA2_PERIPHERAL_FREQMHZ {200} \ + CONFIG.PCW_FPGA3_PERIPHERAL_FREQMHZ {100} \ + CONFIG.PCW_FPGA_FCLK0_ENABLE {1} \ + CONFIG.PCW_FPGA_FCLK1_ENABLE {0} \ + CONFIG.PCW_FPGA_FCLK2_ENABLE {1} \ + CONFIG.PCW_FPGA_FCLK3_ENABLE {0} \ + CONFIG.PCW_GPIO_EMIO_GPIO_ENABLE {1} \ + CONFIG.PCW_GPIO_EMIO_GPIO_IO {64} \ + CONFIG.PCW_GPIO_EMIO_GPIO_WIDTH {64} \ + CONFIG.PCW_GPIO_MIO_GPIO_ENABLE {1} \ + CONFIG.PCW_GPIO_MIO_GPIO_IO {MIO} \ + CONFIG.PCW_I2C0_GRP_INT_ENABLE {1} \ + CONFIG.PCW_I2C0_GRP_INT_IO {EMIO} \ + CONFIG.PCW_I2C0_I2C0_IO {EMIO} \ + CONFIG.PCW_I2C0_PERIPHERAL_ENABLE {1} \ + CONFIG.PCW_I2C0_RESET_ENABLE {0} \ + CONFIG.PCW_I2C1_RESET_ENABLE {0} \ + CONFIG.PCW_I2C_PERIPHERAL_FREQMHZ {111.111115} \ + CONFIG.PCW_I2C_RESET_ENABLE {1} \ + CONFIG.PCW_I2C_RESET_SELECT {Share reset pin} \ + CONFIG.PCW_IOPLL_CTRL_FBDIV {30} \ + CONFIG.PCW_IO_IO_PLL_FREQMHZ {1000.000} \ + CONFIG.PCW_IRQ_F2P_INTR {1} \ + CONFIG.PCW_IRQ_F2P_MODE {DIRECT} \ + CONFIG.PCW_MIO_0_DIRECTION {inout} \ + CONFIG.PCW_MIO_0_IOTYPE {LVCMOS 3.3V} \ + CONFIG.PCW_MIO_0_PULLUP {enabled} \ + CONFIG.PCW_MIO_0_SLEW {slow} \ + CONFIG.PCW_MIO_10_DIRECTION {inout} \ + CONFIG.PCW_MIO_10_IOTYPE {LVCMOS 3.3V} \ + CONFIG.PCW_MIO_10_PULLUP {enabled} \ + CONFIG.PCW_MIO_10_SLEW {slow} \ + CONFIG.PCW_MIO_11_DIRECTION {inout} \ + CONFIG.PCW_MIO_11_IOTYPE {LVCMOS 3.3V} \ + CONFIG.PCW_MIO_11_PULLUP {enabled} \ + CONFIG.PCW_MIO_11_SLEW {slow} \ + CONFIG.PCW_MIO_12_DIRECTION {inout} \ + CONFIG.PCW_MIO_12_IOTYPE {LVCMOS 3.3V} \ + CONFIG.PCW_MIO_12_PULLUP {enabled} \ + CONFIG.PCW_MIO_12_SLEW {slow} \ + CONFIG.PCW_MIO_13_DIRECTION {inout} \ + CONFIG.PCW_MIO_13_IOTYPE {LVCMOS 3.3V} \ + CONFIG.PCW_MIO_13_PULLUP {enabled} \ + CONFIG.PCW_MIO_13_SLEW {slow} \ + CONFIG.PCW_MIO_14_DIRECTION {inout} \ + CONFIG.PCW_MIO_14_IOTYPE {LVCMOS 3.3V} \ + CONFIG.PCW_MIO_14_PULLUP {enabled} \ + CONFIG.PCW_MIO_14_SLEW {slow} \ + CONFIG.PCW_MIO_15_DIRECTION {inout} \ + CONFIG.PCW_MIO_15_IOTYPE {LVCMOS 3.3V} \ + CONFIG.PCW_MIO_15_PULLUP {enabled} \ + CONFIG.PCW_MIO_15_SLEW {slow} \ + CONFIG.PCW_MIO_16_DIRECTION {out} \ + CONFIG.PCW_MIO_16_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_16_PULLUP {enabled} \ + CONFIG.PCW_MIO_16_SLEW {slow} \ + CONFIG.PCW_MIO_17_DIRECTION {out} \ + CONFIG.PCW_MIO_17_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_17_PULLUP {enabled} \ + CONFIG.PCW_MIO_17_SLEW {slow} \ + CONFIG.PCW_MIO_18_DIRECTION {out} \ + CONFIG.PCW_MIO_18_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_18_PULLUP {enabled} \ + CONFIG.PCW_MIO_18_SLEW {slow} \ + CONFIG.PCW_MIO_19_DIRECTION {out} \ + CONFIG.PCW_MIO_19_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_19_PULLUP {enabled} \ + CONFIG.PCW_MIO_19_SLEW {slow} \ + CONFIG.PCW_MIO_1_DIRECTION {out} \ + CONFIG.PCW_MIO_1_IOTYPE {LVCMOS 3.3V} \ + CONFIG.PCW_MIO_1_PULLUP {enabled} \ + CONFIG.PCW_MIO_1_SLEW {slow} \ + CONFIG.PCW_MIO_20_DIRECTION {out} \ + CONFIG.PCW_MIO_20_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_20_PULLUP {enabled} \ + CONFIG.PCW_MIO_20_SLEW {slow} \ + CONFIG.PCW_MIO_21_DIRECTION {out} \ + CONFIG.PCW_MIO_21_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_21_PULLUP {enabled} \ + CONFIG.PCW_MIO_21_SLEW {slow} \ + CONFIG.PCW_MIO_22_DIRECTION {in} \ + CONFIG.PCW_MIO_22_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_22_PULLUP {enabled} \ + CONFIG.PCW_MIO_22_SLEW {slow} \ + CONFIG.PCW_MIO_23_DIRECTION {in} \ + CONFIG.PCW_MIO_23_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_23_PULLUP {enabled} \ + CONFIG.PCW_MIO_23_SLEW {slow} \ + CONFIG.PCW_MIO_24_DIRECTION {in} \ + CONFIG.PCW_MIO_24_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_24_PULLUP {enabled} \ + CONFIG.PCW_MIO_24_SLEW {slow} \ + CONFIG.PCW_MIO_25_DIRECTION {in} \ + CONFIG.PCW_MIO_25_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_25_PULLUP {enabled} \ + CONFIG.PCW_MIO_25_SLEW {slow} \ + CONFIG.PCW_MIO_26_DIRECTION {in} \ + CONFIG.PCW_MIO_26_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_26_PULLUP {enabled} \ + CONFIG.PCW_MIO_26_SLEW {slow} \ + CONFIG.PCW_MIO_27_DIRECTION {in} \ + CONFIG.PCW_MIO_27_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_27_PULLUP {enabled} \ + CONFIG.PCW_MIO_27_SLEW {slow} \ + CONFIG.PCW_MIO_28_DIRECTION {inout} \ + CONFIG.PCW_MIO_28_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_28_PULLUP {enabled} \ + CONFIG.PCW_MIO_28_SLEW {slow} \ + CONFIG.PCW_MIO_29_DIRECTION {in} \ + CONFIG.PCW_MIO_29_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_29_PULLUP {enabled} \ + CONFIG.PCW_MIO_29_SLEW {slow} \ + CONFIG.PCW_MIO_2_DIRECTION {inout} \ + CONFIG.PCW_MIO_2_IOTYPE {LVCMOS 3.3V} \ + CONFIG.PCW_MIO_2_PULLUP {disabled} \ + CONFIG.PCW_MIO_2_SLEW {slow} \ + CONFIG.PCW_MIO_30_DIRECTION {out} \ + CONFIG.PCW_MIO_30_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_30_PULLUP {enabled} \ + CONFIG.PCW_MIO_30_SLEW {slow} \ + CONFIG.PCW_MIO_31_DIRECTION {in} \ + CONFIG.PCW_MIO_31_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_31_PULLUP {enabled} \ + CONFIG.PCW_MIO_31_SLEW {slow} \ + CONFIG.PCW_MIO_32_DIRECTION {inout} \ + CONFIG.PCW_MIO_32_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_32_PULLUP {enabled} \ + CONFIG.PCW_MIO_32_SLEW {slow} \ + CONFIG.PCW_MIO_33_DIRECTION {inout} \ + CONFIG.PCW_MIO_33_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_33_PULLUP {enabled} \ + CONFIG.PCW_MIO_33_SLEW {slow} \ + CONFIG.PCW_MIO_34_DIRECTION {inout} \ + CONFIG.PCW_MIO_34_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_34_PULLUP {enabled} \ + CONFIG.PCW_MIO_34_SLEW {slow} \ + CONFIG.PCW_MIO_35_DIRECTION {inout} \ + CONFIG.PCW_MIO_35_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_35_PULLUP {enabled} \ + CONFIG.PCW_MIO_35_SLEW {slow} \ + CONFIG.PCW_MIO_36_DIRECTION {in} \ + CONFIG.PCW_MIO_36_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_36_PULLUP {enabled} \ + CONFIG.PCW_MIO_36_SLEW {slow} \ + CONFIG.PCW_MIO_37_DIRECTION {inout} \ + CONFIG.PCW_MIO_37_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_37_PULLUP {enabled} \ + CONFIG.PCW_MIO_37_SLEW {slow} \ + CONFIG.PCW_MIO_38_DIRECTION {inout} \ + CONFIG.PCW_MIO_38_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_38_PULLUP {enabled} \ + CONFIG.PCW_MIO_38_SLEW {slow} \ + CONFIG.PCW_MIO_39_DIRECTION {inout} \ + CONFIG.PCW_MIO_39_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_39_PULLUP {enabled} \ + CONFIG.PCW_MIO_39_SLEW {slow} \ + CONFIG.PCW_MIO_3_DIRECTION {inout} \ + CONFIG.PCW_MIO_3_IOTYPE {LVCMOS 3.3V} \ + CONFIG.PCW_MIO_3_PULLUP {disabled} \ + CONFIG.PCW_MIO_3_SLEW {slow} \ + CONFIG.PCW_MIO_40_DIRECTION {inout} \ + CONFIG.PCW_MIO_40_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_40_PULLUP {enabled} \ + CONFIG.PCW_MIO_40_SLEW {slow} \ + CONFIG.PCW_MIO_41_DIRECTION {in} \ + CONFIG.PCW_MIO_41_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_41_PULLUP {enabled} \ + CONFIG.PCW_MIO_41_SLEW {slow} \ + CONFIG.PCW_MIO_42_DIRECTION {out} \ + CONFIG.PCW_MIO_42_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_42_PULLUP {enabled} \ + CONFIG.PCW_MIO_42_SLEW {slow} \ + CONFIG.PCW_MIO_43_DIRECTION {in} \ + CONFIG.PCW_MIO_43_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_43_PULLUP {enabled} \ + CONFIG.PCW_MIO_43_SLEW {slow} \ + CONFIG.PCW_MIO_44_DIRECTION {inout} \ + CONFIG.PCW_MIO_44_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_44_PULLUP {enabled} \ + CONFIG.PCW_MIO_44_SLEW {slow} \ + CONFIG.PCW_MIO_45_DIRECTION {inout} \ + CONFIG.PCW_MIO_45_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_45_PULLUP {enabled} \ + CONFIG.PCW_MIO_45_SLEW {slow} \ + CONFIG.PCW_MIO_46_DIRECTION {inout} \ + CONFIG.PCW_MIO_46_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_46_PULLUP {enabled} \ + CONFIG.PCW_MIO_46_SLEW {slow} \ + CONFIG.PCW_MIO_47_DIRECTION {inout} \ + CONFIG.PCW_MIO_47_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_47_PULLUP {enabled} \ + CONFIG.PCW_MIO_47_SLEW {slow} \ + CONFIG.PCW_MIO_48_DIRECTION {in} \ + CONFIG.PCW_MIO_48_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_48_PULLUP {enabled} \ + CONFIG.PCW_MIO_48_SLEW {slow} \ + CONFIG.PCW_MIO_49_DIRECTION {inout} \ + CONFIG.PCW_MIO_49_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_49_PULLUP {enabled} \ + CONFIG.PCW_MIO_49_SLEW {slow} \ + CONFIG.PCW_MIO_4_DIRECTION {inout} \ + CONFIG.PCW_MIO_4_IOTYPE {LVCMOS 3.3V} \ + CONFIG.PCW_MIO_4_PULLUP {disabled} \ + CONFIG.PCW_MIO_4_SLEW {slow} \ + CONFIG.PCW_MIO_50_DIRECTION {inout} \ + CONFIG.PCW_MIO_50_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_50_PULLUP {enabled} \ + CONFIG.PCW_MIO_50_SLEW {slow} \ + CONFIG.PCW_MIO_51_DIRECTION {inout} \ + CONFIG.PCW_MIO_51_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_51_PULLUP {enabled} \ + CONFIG.PCW_MIO_51_SLEW {slow} \ + CONFIG.PCW_MIO_52_DIRECTION {inout} \ + CONFIG.PCW_MIO_52_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_52_PULLUP {enabled} \ + CONFIG.PCW_MIO_52_SLEW {slow} \ + CONFIG.PCW_MIO_53_DIRECTION {inout} \ + CONFIG.PCW_MIO_53_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_53_PULLUP {enabled} \ + CONFIG.PCW_MIO_53_SLEW {slow} \ + CONFIG.PCW_MIO_5_DIRECTION {inout} \ + CONFIG.PCW_MIO_5_IOTYPE {LVCMOS 3.3V} \ + CONFIG.PCW_MIO_5_PULLUP {disabled} \ + CONFIG.PCW_MIO_5_SLEW {slow} \ + CONFIG.PCW_MIO_6_DIRECTION {out} \ + CONFIG.PCW_MIO_6_IOTYPE {LVCMOS 3.3V} \ + CONFIG.PCW_MIO_6_PULLUP {disabled} \ + CONFIG.PCW_MIO_6_SLEW {slow} \ + CONFIG.PCW_MIO_7_DIRECTION {out} \ + CONFIG.PCW_MIO_7_IOTYPE {LVCMOS 3.3V} \ + CONFIG.PCW_MIO_7_PULLUP {disabled} \ + CONFIG.PCW_MIO_7_SLEW {slow} \ + CONFIG.PCW_MIO_8_DIRECTION {out} \ + CONFIG.PCW_MIO_8_IOTYPE {LVCMOS 3.3V} \ + CONFIG.PCW_MIO_8_PULLUP {disabled} \ + CONFIG.PCW_MIO_8_SLEW {slow} \ + CONFIG.PCW_MIO_9_DIRECTION {in} \ + CONFIG.PCW_MIO_9_IOTYPE {LVCMOS 3.3V} \ + CONFIG.PCW_MIO_9_PULLUP {enabled} \ + CONFIG.PCW_MIO_9_SLEW {slow} \ + CONFIG.PCW_MIO_TREE_PERIPHERALS {GPIO#Quad SPI Flash#Quad SPI Flash#Quad SPI Flash#Quad SPI Flash#Quad SPI Flash#Quad SPI Flash#GPIO#UART 1#UART 1#SD 1#SD 1#SD 1#SD 1#SD 1#SD 1#Enet 0#Enet 0#Enet 0#Enet 0#Enet 0#Enet 0#Enet 0#Enet 0#Enet 0#Enet 0#Enet 0#Enet 0#USB 0#USB 0#USB 0#USB 0#USB 0#USB 0#USB 0#USB 0#USB 0#USB 0#USB 0#USB 0#USB 1#USB 1#USB 1#USB 1#USB 1#USB 1#USB 1#USB 1#USB 1#USB 1#USB 1#USB 1#GPIO#GPIO} \ + CONFIG.PCW_MIO_TREE_SIGNALS {gpio[0]#qspi0_ss_b#qspi0_io[0]#qspi0_io[1]#qspi0_io[2]#qspi0_io[3]/HOLD_B#qspi0_sclk#gpio[7]#tx#rx#data[0]#cmd#clk#data[1]#data[2]#data[3]#tx_clk#txd[0]#txd[1]#txd[2]#txd[3]#tx_ctl#rx_clk#rxd[0]#rxd[1]#rxd[2]#rxd[3]#rx_ctl#data[4]#dir#stp#nxt#data[0]#data[1]#data[2]#data[3]#clk#data[5]#data[6]#data[7]#data[4]#dir#stp#nxt#data[0]#data[1]#data[2]#data[3]#clk#data[5]#data[6]#data[7]#gpio[52]#gpio[53]} \ + CONFIG.PCW_NAND_GRP_D8_ENABLE {0} \ + CONFIG.PCW_NAND_PERIPHERAL_ENABLE {0} \ + CONFIG.PCW_NOR_GRP_A25_ENABLE {0} \ + CONFIG.PCW_NOR_GRP_CS0_ENABLE {0} \ + CONFIG.PCW_NOR_GRP_CS1_ENABLE {0} \ + CONFIG.PCW_NOR_GRP_SRAM_CS0_ENABLE {0} \ + CONFIG.PCW_NOR_GRP_SRAM_CS1_ENABLE {0} \ + CONFIG.PCW_NOR_GRP_SRAM_INT_ENABLE {0} \ + CONFIG.PCW_NOR_PERIPHERAL_ENABLE {0} \ + CONFIG.PCW_PCAP_PERIPHERAL_DIVISOR0 {5} \ + CONFIG.PCW_PRESET_BANK1_VOLTAGE {LVCMOS 1.8V} \ + CONFIG.PCW_QSPI_GRP_FBCLK_ENABLE {0} \ + CONFIG.PCW_QSPI_GRP_IO1_ENABLE {0} \ + CONFIG.PCW_QSPI_GRP_SINGLE_SS_ENABLE {1} \ + CONFIG.PCW_QSPI_GRP_SINGLE_SS_IO {MIO 1 .. 6} \ + CONFIG.PCW_QSPI_GRP_SS1_ENABLE {0} \ + CONFIG.PCW_QSPI_PERIPHERAL_DIVISOR0 {5} \ + CONFIG.PCW_QSPI_PERIPHERAL_ENABLE {1} \ + CONFIG.PCW_QSPI_PERIPHERAL_FREQMHZ {200} \ + CONFIG.PCW_QSPI_QSPI_IO {MIO 1 .. 6} \ + CONFIG.PCW_SD1_GRP_CD_ENABLE {0} \ + CONFIG.PCW_SD1_GRP_POW_ENABLE {0} \ + CONFIG.PCW_SD1_GRP_WP_ENABLE {0} \ + CONFIG.PCW_SD1_PERIPHERAL_ENABLE {1} \ + CONFIG.PCW_SD1_SD1_IO {MIO 10 .. 15} \ + CONFIG.PCW_SDIO_PERIPHERAL_DIVISOR0 {20} \ + CONFIG.PCW_SDIO_PERIPHERAL_FREQMHZ {50} \ + CONFIG.PCW_SDIO_PERIPHERAL_VALID {1} \ + CONFIG.PCW_SINGLE_QSPI_DATA_MODE {x4} \ + CONFIG.PCW_SMC_PERIPHERAL_DIVISOR0 {1} \ + CONFIG.PCW_SPI_PERIPHERAL_DIVISOR0 {1} \ + CONFIG.PCW_TPIU_PERIPHERAL_DIVISOR0 {1} \ + CONFIG.PCW_UART1_GRP_FULL_ENABLE {0} \ + CONFIG.PCW_UART1_PERIPHERAL_ENABLE {1} \ + CONFIG.PCW_UART1_UART1_IO {MIO 8 .. 9} \ + CONFIG.PCW_UART_PERIPHERAL_DIVISOR0 {10} \ + CONFIG.PCW_UART_PERIPHERAL_FREQMHZ {100} \ + CONFIG.PCW_UART_PERIPHERAL_VALID {1} \ + CONFIG.PCW_UIPARAM_ACT_DDR_FREQ_MHZ {400.000000} \ + CONFIG.PCW_UIPARAM_DDR_BANK_ADDR_COUNT {3} \ + CONFIG.PCW_UIPARAM_DDR_BOARD_DELAY0 {0.434} \ + CONFIG.PCW_UIPARAM_DDR_BOARD_DELAY1 {0.398} \ + CONFIG.PCW_UIPARAM_DDR_BOARD_DELAY2 {0.410} \ + CONFIG.PCW_UIPARAM_DDR_BOARD_DELAY3 {0.455} \ + CONFIG.PCW_UIPARAM_DDR_CL {9} \ + CONFIG.PCW_UIPARAM_DDR_COL_ADDR_COUNT {10} \ + CONFIG.PCW_UIPARAM_DDR_CWL {9} \ + CONFIG.PCW_UIPARAM_DDR_DEVICE_CAPACITY {8192 MBits} \ + CONFIG.PCW_UIPARAM_DDR_DQS_TO_CLK_DELAY_0 {0.315} \ + CONFIG.PCW_UIPARAM_DDR_DQS_TO_CLK_DELAY_1 {0.391} \ + CONFIG.PCW_UIPARAM_DDR_DQS_TO_CLK_DELAY_2 {0.374} \ + CONFIG.PCW_UIPARAM_DDR_DQS_TO_CLK_DELAY_3 {0.271} \ + CONFIG.PCW_UIPARAM_DDR_DRAM_WIDTH {32 Bits} \ + CONFIG.PCW_UIPARAM_DDR_FREQ_MHZ {400.00} \ + CONFIG.PCW_UIPARAM_DDR_PARTNO {Custom} \ + CONFIG.PCW_UIPARAM_DDR_ROW_ADDR_COUNT {15} \ + CONFIG.PCW_UIPARAM_DDR_SPEED_BIN {DDR3_1066F} \ + CONFIG.PCW_UIPARAM_DDR_T_FAW {50} \ + CONFIG.PCW_UIPARAM_DDR_T_RAS_MIN {40} \ + CONFIG.PCW_UIPARAM_DDR_T_RC {60} \ + CONFIG.PCW_UIPARAM_DDR_T_RCD {9} \ + CONFIG.PCW_UIPARAM_DDR_T_RP {9} \ + CONFIG.PCW_UIPARAM_DDR_USE_INTERNAL_VREF {1} \ + CONFIG.PCW_USB0_PERIPHERAL_ENABLE {1} \ + CONFIG.PCW_USB0_PERIPHERAL_FREQMHZ {60} \ + CONFIG.PCW_USB0_RESET_ENABLE {0} \ + CONFIG.PCW_USB0_USB0_IO {MIO 28 .. 39} \ + CONFIG.PCW_USB1_PERIPHERAL_ENABLE {1} \ + CONFIG.PCW_USB1_PERIPHERAL_FREQMHZ {60} \ + CONFIG.PCW_USB1_RESET_ENABLE {0} \ + CONFIG.PCW_USB1_USB1_IO {MIO 40 .. 51} \ + CONFIG.PCW_USB_RESET_ENABLE {1} \ + CONFIG.PCW_USB_RESET_SELECT {Share reset pin} \ + CONFIG.PCW_USE_DMA0 {1} \ + CONFIG.PCW_USE_FABRIC_INTERRUPT {1} \ + CONFIG.PCW_USE_M_AXI_GP0 {1} \ + CONFIG.PCW_USE_M_AXI_GP1 {1} \ + CONFIG.PCW_USE_S_AXI_HP0 {1} \ + CONFIG.PCW_USE_S_AXI_HP1 {1} \ + ] $processing_system7_0 + + # Create instance: sys_concat_intc, and set properties + set sys_concat_intc [ create_bd_cell -type ip -vlnv xilinx.com:ip:xlconcat:2.1 sys_concat_intc ] + set_property -dict [ list \ + CONFIG.NUM_PORTS {16} \ + ] $sys_concat_intc + + # Create interface connections + connect_bd_intf_net -intf_net axi_hdmi_intercon_M00_AXI [get_bd_intf_pins axi_hdmi_intercon/M00_AXI] [get_bd_intf_pins hdmi_0/S_AXI] + connect_bd_intf_net -intf_net axi_hdmi_intercon_M01_AXI [get_bd_intf_pins axi_hdmi_intercon/M01_AXI] [get_bd_intf_pins hdmi_0/S_AXI_LITE] + connect_bd_intf_net -intf_net axi_hdmi_intercon_M02_AXI [get_bd_intf_pins axi_hdmi_intercon/M02_AXI] [get_bd_intf_pins hdmi_0/s_axi1] + connect_bd_intf_net -intf_net axi_hdmi_intercon_M03_AXI [get_bd_intf_pins axi_hdmi_intercon/M03_AXI] [get_bd_intf_pins hdmi_0/s_axi2] + connect_bd_intf_net -intf_net axi_parallella_m_intercon_M00_AXI [get_bd_intf_pins axi_parallella_m_intercon/M00_AXI] [get_bd_intf_pins processing_system7_0/S_AXI_HP1] + connect_bd_intf_net -intf_net axi_parallella_s_intercon_M00_AXI [get_bd_intf_pins axi_parallella_s_intercon/M00_AXI] [get_bd_intf_pins parallella_base_0/s_axi] + connect_bd_intf_net -intf_net hdmi_0_DMA_REQ [get_bd_intf_pins hdmi_0/DMA_REQ] [get_bd_intf_pins processing_system7_0/DMA0_REQ] + connect_bd_intf_net -intf_net hdmi_0_M00_AXI [get_bd_intf_pins hdmi_0/M00_AXI] [get_bd_intf_pins processing_system7_0/S_AXI_HP0] + connect_bd_intf_net -intf_net parallella_base_0_m_axi [get_bd_intf_pins axi_parallella_m_intercon/S00_AXI] [get_bd_intf_pins parallella_base_0/m_axi] + connect_bd_intf_net -intf_net processing_system7_0_DDR [get_bd_intf_ports DDR] [get_bd_intf_pins processing_system7_0/DDR] + connect_bd_intf_net -intf_net processing_system7_0_DMA0_ACK [get_bd_intf_pins hdmi_0/DMA_ACK] [get_bd_intf_pins processing_system7_0/DMA0_ACK] + connect_bd_intf_net -intf_net processing_system7_0_FIXED_IO [get_bd_intf_ports FIXED_IO] [get_bd_intf_pins processing_system7_0/FIXED_IO] + connect_bd_intf_net -intf_net processing_system7_0_M_AXI_GP0 [get_bd_intf_pins axi_hdmi_intercon/S00_AXI] [get_bd_intf_pins processing_system7_0/M_AXI_GP0] + connect_bd_intf_net -intf_net processing_system7_0_M_AXI_GP1 [get_bd_intf_pins axi_parallella_s_intercon/S00_AXI] [get_bd_intf_pins processing_system7_0/M_AXI_GP1] + + # Create port connections + connect_bd_net -net hdmi_0_hdmi_16_data [get_bd_ports hdmi_d] [get_bd_pins hdmi_0/hdmi_16_data] + connect_bd_net -net hdmi_0_hdmi_16_data_e [get_bd_ports hdmi_de] [get_bd_pins hdmi_0/hdmi_16_data_e] + connect_bd_net -net hdmi_0_hdmi_16_hsync [get_bd_ports hdmi_hsync] [get_bd_pins hdmi_0/hdmi_16_hsync] + connect_bd_net -net hdmi_0_hdmi_16_vsync [get_bd_ports hdmi_vsync] [get_bd_pins hdmi_0/hdmi_16_vsync] + connect_bd_net -net hdmi_0_hdmi_out_clk [get_bd_ports hdmi_clk] [get_bd_pins hdmi_0/hdmi_out_clk] + connect_bd_net -net hdmi_0_int [get_bd_ports hdmi_int] [get_bd_pins sys_concat_intc/In14] + connect_bd_net -net hdmi_0_mm2s_introut [get_bd_pins hdmi_0/mm2s_introut] [get_bd_pins sys_concat_intc/In15] + connect_bd_net -net hdmi_0_spdif_tx_o1 [get_bd_ports hdmi_spdif] [get_bd_pins hdmi_0/spdif_tx_o] + connect_bd_net -net parallella_base_0_cclk_n [get_bd_ports cclk_n] [get_bd_pins parallella_base_0/cclk_n] + connect_bd_net -net parallella_base_0_cclk_p [get_bd_ports cclk_p] [get_bd_pins parallella_base_0/cclk_p] + connect_bd_net -net parallella_base_0_chip_resetb [get_bd_ports chip_nreset] [get_bd_pins parallella_base_0/chip_nreset] + connect_bd_net -net parallella_base_0_constant_zero [get_bd_pins parallella_base_0/constant_zero] [get_bd_pins sys_concat_intc/In0] [get_bd_pins sys_concat_intc/In1] [get_bd_pins sys_concat_intc/In2] [get_bd_pins sys_concat_intc/In3] [get_bd_pins sys_concat_intc/In4] [get_bd_pins sys_concat_intc/In5] [get_bd_pins sys_concat_intc/In6] [get_bd_pins sys_concat_intc/In7] [get_bd_pins sys_concat_intc/In8] [get_bd_pins sys_concat_intc/In9] [get_bd_pins sys_concat_intc/In10] [get_bd_pins sys_concat_intc/In12] [get_bd_pins sys_concat_intc/In13] + connect_bd_net -net parallella_base_0_gpio_n [get_bd_ports gpio_n] [get_bd_pins parallella_base_0/gpio_n] + connect_bd_net -net parallella_base_0_gpio_p [get_bd_ports gpio_p] [get_bd_pins parallella_base_0/gpio_p] + connect_bd_net -net parallella_base_0_i2c_scl [get_bd_ports i2c_scl] [get_bd_pins parallella_base_0/i2c_scl] + connect_bd_net -net parallella_base_0_i2c_scl_i [get_bd_pins parallella_base_0/i2c_scl_i] [get_bd_pins processing_system7_0/I2C0_SCL_I] + connect_bd_net -net parallella_base_0_i2c_sda [get_bd_ports i2c_sda] [get_bd_pins parallella_base_0/i2c_sda] + connect_bd_net -net parallella_base_0_i2c_sda_i [get_bd_pins parallella_base_0/i2c_sda_i] [get_bd_pins processing_system7_0/I2C0_SDA_I] + connect_bd_net -net parallella_base_0_mailbox_irq [get_bd_pins parallella_base_0/mailbox_irq] [get_bd_pins sys_concat_intc/In11] + connect_bd_net -net parallella_base_0_ps_gpio_i [get_bd_pins parallella_base_0/ps_gpio_i] [get_bd_pins processing_system7_0/GPIO_I] + connect_bd_net -net parallella_base_0_rxo_rd_wait_n [get_bd_ports rxo_rd_wait_n] [get_bd_pins parallella_base_0/rxo_rd_wait_n] + connect_bd_net -net parallella_base_0_rxo_rd_wait_p [get_bd_ports rxo_rd_wait_p] [get_bd_pins parallella_base_0/rxo_rd_wait_p] + connect_bd_net -net parallella_base_0_rxo_wr_wait_n [get_bd_ports rxo_wr_wait_n] [get_bd_pins parallella_base_0/rxo_wr_wait_n] + connect_bd_net -net parallella_base_0_rxo_wr_wait_p [get_bd_ports rxo_wr_wait_p] [get_bd_pins parallella_base_0/rxo_wr_wait_p] + connect_bd_net -net parallella_base_0_txo_data_n [get_bd_ports txo_data_n] [get_bd_pins parallella_base_0/txo_data_n] + connect_bd_net -net parallella_base_0_txo_data_p [get_bd_ports txo_data_p] [get_bd_pins parallella_base_0/txo_data_p] + connect_bd_net -net parallella_base_0_txo_frame_n [get_bd_ports txo_frame_n] [get_bd_pins parallella_base_0/txo_frame_n] + connect_bd_net -net parallella_base_0_txo_frame_p [get_bd_ports txo_frame_p] [get_bd_pins parallella_base_0/txo_frame_p] + connect_bd_net -net parallella_base_0_txo_lclk_n [get_bd_ports txo_lclk_n] [get_bd_pins parallella_base_0/txo_lclk_n] + connect_bd_net -net parallella_base_0_txo_lclk_p [get_bd_ports txo_lclk_p] [get_bd_pins parallella_base_0/txo_lclk_p] + connect_bd_net -net proc_sys_reset_0_interconnect_aresetn [get_bd_pins axi_hdmi_intercon/ARESETN] [get_bd_pins axi_parallella_m_intercon/ARESETN] [get_bd_pins axi_parallella_s_intercon/ARESETN] [get_bd_pins proc_sys_reset_0/interconnect_aresetn] + connect_bd_net -net proc_sys_reset_0_peripheral_aresetn [get_bd_pins axi_hdmi_intercon/M00_ARESETN] [get_bd_pins axi_hdmi_intercon/M01_ARESETN] [get_bd_pins axi_hdmi_intercon/M02_ARESETN] [get_bd_pins axi_hdmi_intercon/M03_ARESETN] [get_bd_pins axi_hdmi_intercon/S00_ARESETN] [get_bd_pins axi_parallella_m_intercon/M00_ARESETN] [get_bd_pins axi_parallella_m_intercon/S00_ARESETN] [get_bd_pins axi_parallella_s_intercon/M00_ARESETN] [get_bd_pins axi_parallella_s_intercon/S00_ARESETN] [get_bd_pins hdmi_0/axi_resetn] [get_bd_pins parallella_base_0/m_axi_aresetn] [get_bd_pins parallella_base_0/s_axi_aresetn] [get_bd_pins parallella_base_0/sys_nreset] [get_bd_pins proc_sys_reset_0/peripheral_aresetn] + connect_bd_net -net processing_system7_0_FCLK_CLK0 [get_bd_pins axi_hdmi_intercon/ACLK] [get_bd_pins axi_hdmi_intercon/M00_ACLK] [get_bd_pins axi_hdmi_intercon/M01_ACLK] [get_bd_pins axi_hdmi_intercon/M02_ACLK] [get_bd_pins axi_hdmi_intercon/M03_ACLK] [get_bd_pins axi_hdmi_intercon/S00_ACLK] [get_bd_pins axi_parallella_m_intercon/ACLK] [get_bd_pins axi_parallella_m_intercon/M00_ACLK] [get_bd_pins axi_parallella_m_intercon/S00_ACLK] [get_bd_pins axi_parallella_s_intercon/ACLK] [get_bd_pins axi_parallella_s_intercon/M00_ACLK] [get_bd_pins axi_parallella_s_intercon/S00_ACLK] [get_bd_pins hdmi_0/s_axi_aclk] [get_bd_pins parallella_base_0/sys_clk] [get_bd_pins proc_sys_reset_0/slowest_sync_clk] [get_bd_pins processing_system7_0/DMA0_ACLK] [get_bd_pins processing_system7_0/FCLK_CLK0] [get_bd_pins processing_system7_0/M_AXI_GP0_ACLK] [get_bd_pins processing_system7_0/M_AXI_GP1_ACLK] [get_bd_pins processing_system7_0/S_AXI_HP0_ACLK] [get_bd_pins processing_system7_0/S_AXI_HP1_ACLK] + connect_bd_net -net processing_system7_0_FCLK_CLK2 [get_bd_pins hdmi_0/clk] [get_bd_pins processing_system7_0/FCLK_CLK2] + connect_bd_net -net processing_system7_0_FCLK_RESET0_N [get_bd_pins proc_sys_reset_0/ext_reset_in] [get_bd_pins processing_system7_0/FCLK_RESET0_N] + connect_bd_net -net processing_system7_0_GPIO_O [get_bd_pins parallella_base_0/ps_gpio_o] [get_bd_pins processing_system7_0/GPIO_O] + connect_bd_net -net processing_system7_0_GPIO_T [get_bd_pins parallella_base_0/ps_gpio_t] [get_bd_pins processing_system7_0/GPIO_T] + connect_bd_net -net processing_system7_0_I2C0_SCL_O [get_bd_pins parallella_base_0/i2c_scl_o] [get_bd_pins processing_system7_0/I2C0_SCL_O] + connect_bd_net -net processing_system7_0_I2C0_SCL_T [get_bd_pins parallella_base_0/i2c_scl_t] [get_bd_pins processing_system7_0/I2C0_SCL_T] + connect_bd_net -net processing_system7_0_I2C0_SDA_O [get_bd_pins parallella_base_0/i2c_sda_o] [get_bd_pins processing_system7_0/I2C0_SDA_O] + connect_bd_net -net processing_system7_0_I2C0_SDA_T [get_bd_pins parallella_base_0/i2c_sda_t] [get_bd_pins processing_system7_0/I2C0_SDA_T] + connect_bd_net -net rxi_data_n_1 [get_bd_ports rxi_data_n] [get_bd_pins parallella_base_0/rxi_data_n] + connect_bd_net -net rxi_data_p_1 [get_bd_ports rxi_data_p] [get_bd_pins parallella_base_0/rxi_data_p] + connect_bd_net -net rxi_frame_n_1 [get_bd_ports rxi_frame_n] [get_bd_pins parallella_base_0/rxi_frame_n] + connect_bd_net -net rxi_frame_p_1 [get_bd_ports rxi_frame_p] [get_bd_pins parallella_base_0/rxi_frame_p] + connect_bd_net -net rxi_lclk_n_1 [get_bd_ports rxi_lclk_n] [get_bd_pins parallella_base_0/rxi_lclk_n] + connect_bd_net -net rxi_lclk_p_1 [get_bd_ports rxi_lclk_p] [get_bd_pins parallella_base_0/rxi_lclk_p] + connect_bd_net -net sys_concat_intc_dout [get_bd_pins processing_system7_0/IRQ_F2P] [get_bd_pins sys_concat_intc/dout] + connect_bd_net -net txi_rd_wait_n_1 [get_bd_ports txi_rd_wait_n] [get_bd_pins parallella_base_0/txi_rd_wait_n] + connect_bd_net -net txi_rd_wait_p_1 [get_bd_ports txi_rd_wait_p] [get_bd_pins parallella_base_0/txi_rd_wait_p] + connect_bd_net -net txi_wr_wait_n_1 [get_bd_ports txi_wr_wait_n] [get_bd_pins parallella_base_0/txi_wr_wait_n] + connect_bd_net -net txi_wr_wait_p_1 [get_bd_ports txi_wr_wait_p] [get_bd_pins parallella_base_0/txi_wr_wait_p] + + # Create address segments + create_bd_addr_seg -range 0x40000000 -offset 0x00000000 [get_bd_addr_spaces parallella_base_0/m_axi] [get_bd_addr_segs processing_system7_0/S_AXI_HP1/HP1_DDR_LOWOCM] SEG_processing_system7_0_HP1_DDR_LOWOCM + create_bd_addr_seg -range 0x00010000 -offset 0x66000000 [get_bd_addr_spaces processing_system7_0/Data] [get_bd_addr_segs hdmi_0/axi_clkgen_0/s_axi/axi_lite] SEG_axi_clkgen_0_axi_lite + create_bd_addr_seg -range 0x00001000 -offset 0x43000000 [get_bd_addr_spaces processing_system7_0/Data] [get_bd_addr_segs hdmi_0/axi_dmac_0/s_axi/axi_lite] SEG_axi_dmac_0_axi_lite + create_bd_addr_seg -range 0x00010000 -offset 0x6C000000 [get_bd_addr_spaces processing_system7_0/Data] [get_bd_addr_segs hdmi_0/axi_hdmi_tx_0/s_axi/axi_lite] SEG_axi_hdmi_tx_0_axi_lite + create_bd_addr_seg -range 0x00010000 -offset 0x75C00000 [get_bd_addr_spaces processing_system7_0/Data] [get_bd_addr_segs hdmi_0/axi_spdif_tx_0/s_axi/axi_lite] SEG_axi_spdif_tx_0_axi_lite + create_bd_addr_seg -range 0x40000000 -offset 0x80000000 [get_bd_addr_spaces processing_system7_0/Data] [get_bd_addr_segs parallella_base_0/s_axi/axi_lite] SEG_parallella_base_0_axi_lite + create_bd_addr_seg -range 0x40000000 -offset 0x00000000 [get_bd_addr_spaces hdmi_0/axi_dmac_0/m_src_axi] [get_bd_addr_segs processing_system7_0/S_AXI_HP0/HP0_DDR_LOWOCM] SEG_processing_system7_0_HP0_DDR_LOWOCM + + + # Restore current instance + current_bd_instance $oldCurInst + + save_bd_design +} +# End of create_root_design() + + +################################################################## +# MAIN FLOW +################################################################## + +create_root_design "" + + diff --git a/src/parallella/fpga/hdmi_e16_z7020/system_params.tcl b/src/parallella/fpga/hdmi_e16_z7020/system_params.tcl new file mode 100644 index 00000000..96567a44 --- /dev/null +++ b/src/parallella/fpga/hdmi_e16_z7020/system_params.tcl @@ -0,0 +1,28 @@ + +#Design name ("system" recommended) +set design system + +#Project directory ("." recommended) +set projdir ./ + +#Device name +set partname "xc7z020clg400-1" + +#Paths to all IP blocks to use in Vivado "system.bd" + +set ip_repos [list "../parallella_base" "../../../adi/hdl/library"] + +#All source files +set hdl_files [] + +#All constraints files +set constraints_files [list \ + ../parallella_timing.xdc \ + ../parallella_io.xdc \ + ../parallella_7020_io.xdc \ + ] + +########################################################### +# PREPARE FOR SYNTHESIS +########################################################### +set oh_verilog_define "CFG_ASIC=0 CFG_PLATFORM=\"ZYNQ\"" diff --git a/src/parallella/fpga/headless_e16_z7010/system_bd.tcl b/src/parallella/fpga/headless_e16_z7010/system_bd.tcl index 3f3f7daf..c9e0e28c 100644 --- a/src/parallella/fpga/headless_e16_z7010/system_bd.tcl +++ b/src/parallella/fpga/headless_e16_z7010/system_bd.tcl @@ -7,15 +7,25 @@ # IP Integrator Tcl commands easier. ################################################################ +namespace eval _tcl { +proc get_script_folder {} { + set script_path [file normalize [info script]] + set script_folder [file dirname $script_path] + return $script_folder +} +} +variable script_folder +set script_folder [_tcl::get_script_folder] + ################################################################ # Check if script is running in correct Vivado version. ################################################################ -set scripts_vivado_version 2015.2 +set scripts_vivado_version 2018.2 set current_vivado_version [version -short] if { [string first $scripts_vivado_version $current_vivado_version] == -1 } { puts "" - puts "ERROR: This script was generated using Vivado <$scripts_vivado_version> and is being run in <$current_vivado_version> of Vivado. Please run the script in Vivado <$scripts_vivado_version> then open the design in Vivado <$current_vivado_version>. Upgrade the design by running \"Tools => Report => Report IP Status...\", then run write_bd_tcl to create an updated script." + catch {common::send_msg_id "BD_TCL-109" "ERROR" "This script was generated using Vivado <$scripts_vivado_version> and is being run in <$current_vivado_version> of Vivado. Please run the script in Vivado <$scripts_vivado_version> then open the design in Vivado <$current_vivado_version>. Upgrade the design by running \"Tools => Report => Report IP Status...\", then run write_bd_tcl to create an updated script."} return 1 } @@ -27,19 +37,18 @@ if { [string first $scripts_vivado_version $current_vivado_version] == -1 } { # To test this script, run the following commands from Vivado Tcl console: # source system_script.tcl -# If you do not already have a project created, -# you can create a project using the following command: -# create_project project_1 myproj -part xc7z010clg400-1 +# If there is no project opened, this script will create a +# project, but make sure you do not have an existing project +# <./myproj/project_1.xpr> in the current working folder. -# CHECKING IF PROJECT EXISTS -if { [get_projects -quiet] eq "" } { - puts "ERROR: Please open or create a project!" - return 1 +set list_projs [get_projects -quiet] +if { $list_projs eq "" } { + create_project project_1 myproj -part xc7z010clg400-1 } - # CHANGE DESIGN NAME HERE +variable design_name set design_name system # If you do not already have an existing IP Integrator design open, @@ -57,7 +66,7 @@ if { ${design_name} eq "" } { # USE CASES: # 1) Design_name not set - set errMsg "ERROR: Please set the variable to a non-empty value." + set errMsg "Please set the variable to a non-empty value." set nRet 1 } elseif { ${cur_design} ne "" && ${list_cells} eq "" } { @@ -67,23 +76,23 @@ if { ${design_name} eq "" } { # 4): Current design opened AND is empty AND names diff; design_name exists in project. if { $cur_design ne $design_name } { - puts "INFO: Changing value of from <$design_name> to <$cur_design> since current design is empty." + common::send_msg_id "BD_TCL-001" "INFO" "Changing value of from <$design_name> to <$cur_design> since current design is empty." set design_name [get_property NAME $cur_design] } - puts "INFO: Constructing design in IPI design <$cur_design>..." + common::send_msg_id "BD_TCL-002" "INFO" "Constructing design in IPI design <$cur_design>..." } elseif { ${cur_design} ne "" && $list_cells ne "" && $cur_design eq $design_name } { # USE CASES: # 5) Current design opened AND has components AND same names. - set errMsg "ERROR: Design <$design_name> already exists in your project, please set the variable to another value." + set errMsg "Design <$design_name> already exists in your project, please set the variable to another value." set nRet 1 } elseif { [get_files -quiet ${design_name}.bd] ne "" } { # USE CASES: # 6) Current opened design, has components, but diff names, design_name exists in project. # 7) No opened design, design_name exists in project. - set errMsg "ERROR: Design <$design_name> already exists in your project, please set the variable to another value." + set errMsg "Design <$design_name> already exists in your project, please set the variable to another value." set nRet 2 } else { @@ -91,22 +100,57 @@ if { ${design_name} eq "" } { # 8) No opened design, design_name not in project. # 9) Current opened design, has components, but diff names, design_name not in project. - puts "INFO: Currently there is no design <$design_name> in project, so creating one..." + common::send_msg_id "BD_TCL-003" "INFO" "Currently there is no design <$design_name> in project, so creating one..." create_bd_design $design_name - puts "INFO: Making design <$design_name> as current_bd_design." + common::send_msg_id "BD_TCL-004" "INFO" "Making design <$design_name> as current_bd_design." current_bd_design $design_name } -puts "INFO: Currently the variable is equal to \"$design_name\"." +common::send_msg_id "BD_TCL-005" "INFO" "Currently the variable is equal to \"$design_name\"." if { $nRet != 0 } { - puts $errMsg + catch {common::send_msg_id "BD_TCL-114" "ERROR" $errMsg} return $nRet } +set bCheckIPsPassed 1 +################################################################## +# CHECK IPs +################################################################## +set bCheckIPs 1 +if { $bCheckIPs == 1 } { + set list_check_ips "\ +www.parallella.org:user:parallella_base:1.0\ +xilinx.com:ip:proc_sys_reset:5.0\ +xilinx.com:ip:processing_system7:5.5\ +xilinx.com:ip:xlconcat:2.1\ +" + + set list_ips_missing "" + common::send_msg_id "BD_TCL-006" "INFO" "Checking if the following IPs exist in the project's IP catalog: $list_check_ips ." + + foreach ip_vlnv $list_check_ips { + set ip_obj [get_ipdefs -all $ip_vlnv] + if { $ip_obj eq "" } { + lappend list_ips_missing $ip_vlnv + } + } + + if { $list_ips_missing ne "" } { + catch {common::send_msg_id "BD_TCL-115" "ERROR" "The following IPs are not found in the IP Catalog:\n $list_ips_missing\n\nResolution: Please add the repository containing the IP(s) to the project." } + set bCheckIPsPassed 0 + } + +} + +if { $bCheckIPsPassed != 1 } { + common::send_msg_id "BD_TCL-1003" "WARNING" "Will not continue with creation of design due to the error(s) above." + return 3 +} + ################################################################## # DESIGN PROCs ################################################################## @@ -117,6 +161,9 @@ if { $nRet != 0 } { # procedure reusable. If parentCell is "", will use root. proc create_root_design { parentCell } { + variable script_folder + variable design_name + if { $parentCell eq "" } { set parentCell [get_bd_cells /] } @@ -124,14 +171,14 @@ proc create_root_design { parentCell } { # Get object for parentCell set parentObj [get_bd_cells $parentCell] if { $parentObj == "" } { - puts "ERROR: Unable to find parent cell <$parentCell>!" + catch {common::send_msg_id "BD_TCL-100" "ERROR" "Unable to find parent cell <$parentCell>!"} return } # Make sure parentObj is hier blk set parentType [get_property TYPE $parentObj] if { $parentType ne "hier" } { - puts "ERROR: Parent <$parentObj> has TYPE = <$parentType>. Expected to be ." + catch {common::send_msg_id "BD_TCL-101" "ERROR" "Parent <$parentObj> has TYPE = <$parentType>. Expected to be ."} return } @@ -151,7 +198,7 @@ proc create_root_design { parentCell } { set gpio_n [ create_bd_port -dir IO -from 11 -to 0 gpio_n ] set gpio_p [ create_bd_port -dir IO -from 11 -to 0 gpio_p ] set hdmi_clk [ create_bd_port -dir O hdmi_clk ] - set hdmi_d [ create_bd_port -dir O -from 23 -to 8 hdmi_d ] + set hdmi_d [ create_bd_port -dir O -from 15 -to 0 hdmi_d ] set hdmi_de [ create_bd_port -dir O hdmi_de ] set hdmi_hsync [ create_bd_port -dir O hdmi_hsync ] set hdmi_int [ create_bd_port -dir I hdmi_int ] @@ -182,51 +229,431 @@ proc create_root_design { parentCell } { # Create instance: axi_mem_intercon, and set properties set axi_mem_intercon [ create_bd_cell -type ip -vlnv xilinx.com:ip:axi_interconnect:2.1 axi_mem_intercon ] - set_property -dict [ list CONFIG.NUM_MI {1} ] $axi_mem_intercon + set_property -dict [ list \ + CONFIG.NUM_MI {1} \ + ] $axi_mem_intercon # Create instance: parallella_base_0, and set properties set parallella_base_0 [ create_bd_cell -type ip -vlnv www.parallella.org:user:parallella_base:1.0 parallella_base_0 ] - set_property -dict [ list CONFIG.NGPIO {12} ] $parallella_base_0 + set_property -dict [ list \ + CONFIG.NGPIO {12} \ + ] $parallella_base_0 # Create instance: proc_sys_reset_0, and set properties set proc_sys_reset_0 [ create_bd_cell -type ip -vlnv xilinx.com:ip:proc_sys_reset:5.0 proc_sys_reset_0 ] # Create instance: processing_system7_0, and set properties set processing_system7_0 [ create_bd_cell -type ip -vlnv xilinx.com:ip:processing_system7:5.5 processing_system7_0 ] - set_property -dict [ list CONFIG.PCW_CORE0_FIQ_INTR {0} \ -CONFIG.PCW_ENET0_ENET0_IO {MIO 16 .. 27} CONFIG.PCW_ENET0_GRP_MDIO_ENABLE {1} \ -CONFIG.PCW_ENET0_PERIPHERAL_ENABLE {1} CONFIG.PCW_ENET1_PERIPHERAL_ENABLE {0} \ -CONFIG.PCW_EN_CLK3_PORT {1} CONFIG.PCW_FPGA0_PERIPHERAL_FREQMHZ {100} \ -CONFIG.PCW_FPGA3_PERIPHERAL_FREQMHZ {100} CONFIG.PCW_GPIO_EMIO_GPIO_ENABLE {1} \ -CONFIG.PCW_GPIO_MIO_GPIO_ENABLE {1} CONFIG.PCW_GPIO_MIO_GPIO_IO {MIO} \ -CONFIG.PCW_I2C0_I2C0_IO {EMIO} CONFIG.PCW_I2C0_PERIPHERAL_ENABLE {1} \ -CONFIG.PCW_I2C0_RESET_ENABLE {0} CONFIG.PCW_IRQ_F2P_INTR {1} \ -CONFIG.PCW_IRQ_F2P_MODE {DIRECT} CONFIG.PCW_PRESET_BANK1_VOLTAGE {LVCMOS 1.8V} \ -CONFIG.PCW_QSPI_GRP_SINGLE_SS_ENABLE {1} CONFIG.PCW_QSPI_PERIPHERAL_ENABLE {1} \ -CONFIG.PCW_SD1_PERIPHERAL_ENABLE {1} CONFIG.PCW_SD1_SD1_IO {MIO 10 .. 15} \ -CONFIG.PCW_SDIO_PERIPHERAL_FREQMHZ {50} CONFIG.PCW_UART1_PERIPHERAL_ENABLE {1} \ -CONFIG.PCW_UART1_UART1_IO {MIO 8 .. 9} CONFIG.PCW_UIPARAM_DDR_BOARD_DELAY0 {0.434} \ -CONFIG.PCW_UIPARAM_DDR_BOARD_DELAY1 {0.398} CONFIG.PCW_UIPARAM_DDR_BOARD_DELAY2 {0.410} \ -CONFIG.PCW_UIPARAM_DDR_BOARD_DELAY3 {0.455} CONFIG.PCW_UIPARAM_DDR_CL {9} \ -CONFIG.PCW_UIPARAM_DDR_CWL {9} CONFIG.PCW_UIPARAM_DDR_DEVICE_CAPACITY {8192 MBits} \ -CONFIG.PCW_UIPARAM_DDR_DQS_TO_CLK_DELAY_0 {0.315} CONFIG.PCW_UIPARAM_DDR_DQS_TO_CLK_DELAY_1 {0.391} \ -CONFIG.PCW_UIPARAM_DDR_DQS_TO_CLK_DELAY_2 {0.374} CONFIG.PCW_UIPARAM_DDR_DQS_TO_CLK_DELAY_3 {0.271} \ -CONFIG.PCW_UIPARAM_DDR_DRAM_WIDTH {32 Bits} CONFIG.PCW_UIPARAM_DDR_FREQ_MHZ {400.00} \ -CONFIG.PCW_UIPARAM_DDR_PARTNO {Custom} CONFIG.PCW_UIPARAM_DDR_T_FAW {50} \ -CONFIG.PCW_UIPARAM_DDR_T_RAS_MIN {40} CONFIG.PCW_UIPARAM_DDR_T_RC {60} \ -CONFIG.PCW_UIPARAM_DDR_T_RCD {9} CONFIG.PCW_UIPARAM_DDR_T_RP {9} \ -CONFIG.PCW_UIPARAM_DDR_USE_INTERNAL_VREF {1} CONFIG.PCW_USB0_PERIPHERAL_ENABLE {1} \ -CONFIG.PCW_USB0_RESET_ENABLE {0} CONFIG.PCW_USB1_PERIPHERAL_ENABLE {1} \ -CONFIG.PCW_USE_FABRIC_INTERRUPT {1} CONFIG.PCW_USE_M_AXI_GP1 {1} \ -CONFIG.PCW_USE_S_AXI_HP1 {1} ] $processing_system7_0 + set_property -dict [ list \ + CONFIG.PCW_ACT_APU_PERIPHERAL_FREQMHZ {666.666687} \ + CONFIG.PCW_ACT_CAN_PERIPHERAL_FREQMHZ {10.000000} \ + CONFIG.PCW_ACT_DCI_PERIPHERAL_FREQMHZ {10.062893} \ + CONFIG.PCW_ACT_ENET0_PERIPHERAL_FREQMHZ {125.000000} \ + CONFIG.PCW_ACT_ENET1_PERIPHERAL_FREQMHZ {10.000000} \ + CONFIG.PCW_ACT_FPGA0_PERIPHERAL_FREQMHZ {100.000000} \ + CONFIG.PCW_ACT_FPGA1_PERIPHERAL_FREQMHZ {10.000000} \ + CONFIG.PCW_ACT_FPGA2_PERIPHERAL_FREQMHZ {10.000000} \ + CONFIG.PCW_ACT_FPGA3_PERIPHERAL_FREQMHZ {100.000000} \ + CONFIG.PCW_ACT_PCAP_PERIPHERAL_FREQMHZ {200.000000} \ + CONFIG.PCW_ACT_QSPI_PERIPHERAL_FREQMHZ {200.000000} \ + CONFIG.PCW_ACT_SDIO_PERIPHERAL_FREQMHZ {50.000000} \ + CONFIG.PCW_ACT_SMC_PERIPHERAL_FREQMHZ {10.000000} \ + CONFIG.PCW_ACT_SPI_PERIPHERAL_FREQMHZ {10.000000} \ + CONFIG.PCW_ACT_TPIU_PERIPHERAL_FREQMHZ {200.000000} \ + CONFIG.PCW_ACT_TTC0_CLK0_PERIPHERAL_FREQMHZ {111.111115} \ + CONFIG.PCW_ACT_TTC0_CLK1_PERIPHERAL_FREQMHZ {111.111115} \ + CONFIG.PCW_ACT_TTC0_CLK2_PERIPHERAL_FREQMHZ {111.111115} \ + CONFIG.PCW_ACT_TTC1_CLK0_PERIPHERAL_FREQMHZ {111.111115} \ + CONFIG.PCW_ACT_TTC1_CLK1_PERIPHERAL_FREQMHZ {111.111115} \ + CONFIG.PCW_ACT_TTC1_CLK2_PERIPHERAL_FREQMHZ {111.111115} \ + CONFIG.PCW_ACT_UART_PERIPHERAL_FREQMHZ {100.000000} \ + CONFIG.PCW_ACT_WDT_PERIPHERAL_FREQMHZ {111.111115} \ + CONFIG.PCW_ARMPLL_CTRL_FBDIV {40} \ + CONFIG.PCW_CAN_PERIPHERAL_DIVISOR0 {1} \ + CONFIG.PCW_CAN_PERIPHERAL_DIVISOR1 {1} \ + CONFIG.PCW_CLK0_FREQ {100000000} \ + CONFIG.PCW_CLK1_FREQ {10000000} \ + CONFIG.PCW_CLK2_FREQ {10000000} \ + CONFIG.PCW_CLK3_FREQ {100000000} \ + CONFIG.PCW_CORE0_FIQ_INTR {0} \ + CONFIG.PCW_CPU_CPU_PLL_FREQMHZ {1333.333} \ + CONFIG.PCW_CPU_PERIPHERAL_DIVISOR0 {2} \ + CONFIG.PCW_DCI_PERIPHERAL_DIVISOR0 {53} \ + CONFIG.PCW_DCI_PERIPHERAL_DIVISOR1 {3} \ + CONFIG.PCW_DDRPLL_CTRL_FBDIV {48} \ + CONFIG.PCW_DDR_DDR_PLL_FREQMHZ {1600.000} \ + CONFIG.PCW_DDR_PERIPHERAL_DIVISOR0 {4} \ + CONFIG.PCW_DDR_RAM_HIGHADDR {0x3FFFFFFF} \ + CONFIG.PCW_ENET0_ENET0_IO {MIO 16 .. 27} \ + CONFIG.PCW_ENET0_GRP_MDIO_ENABLE {1} \ + CONFIG.PCW_ENET0_GRP_MDIO_IO {EMIO} \ + CONFIG.PCW_ENET0_PERIPHERAL_DIVISOR0 {8} \ + CONFIG.PCW_ENET0_PERIPHERAL_DIVISOR1 {1} \ + CONFIG.PCW_ENET0_PERIPHERAL_ENABLE {1} \ + CONFIG.PCW_ENET0_PERIPHERAL_FREQMHZ {1000 Mbps} \ + CONFIG.PCW_ENET0_RESET_ENABLE {0} \ + CONFIG.PCW_ENET1_GRP_MDIO_ENABLE {0} \ + CONFIG.PCW_ENET1_PERIPHERAL_DIVISOR0 {1} \ + CONFIG.PCW_ENET1_PERIPHERAL_DIVISOR1 {1} \ + CONFIG.PCW_ENET1_PERIPHERAL_ENABLE {0} \ + CONFIG.PCW_ENET1_PERIPHERAL_FREQMHZ {1000 Mbps} \ + CONFIG.PCW_ENET1_RESET_ENABLE {0} \ + CONFIG.PCW_ENET_RESET_ENABLE {1} \ + CONFIG.PCW_ENET_RESET_SELECT {Share reset pin} \ + CONFIG.PCW_EN_CLK3_PORT {1} \ + CONFIG.PCW_EN_EMIO_CD_SDIO1 {0} \ + CONFIG.PCW_EN_EMIO_GPIO {1} \ + CONFIG.PCW_EN_EMIO_I2C0 {1} \ + CONFIG.PCW_EN_EMIO_SDIO1 {0} \ + CONFIG.PCW_EN_EMIO_WP_SDIO1 {0} \ + CONFIG.PCW_EN_ENET0 {1} \ + CONFIG.PCW_EN_GPIO {1} \ + CONFIG.PCW_EN_I2C0 {1} \ + CONFIG.PCW_EN_QSPI {1} \ + CONFIG.PCW_EN_SDIO1 {1} \ + CONFIG.PCW_EN_UART1 {1} \ + CONFIG.PCW_EN_USB0 {1} \ + CONFIG.PCW_EN_USB1 {1} \ + CONFIG.PCW_FCLK0_PERIPHERAL_DIVISOR0 {5} \ + CONFIG.PCW_FCLK0_PERIPHERAL_DIVISOR1 {2} \ + CONFIG.PCW_FCLK1_PERIPHERAL_DIVISOR0 {1} \ + CONFIG.PCW_FCLK1_PERIPHERAL_DIVISOR1 {1} \ + CONFIG.PCW_FCLK2_PERIPHERAL_DIVISOR0 {1} \ + CONFIG.PCW_FCLK2_PERIPHERAL_DIVISOR1 {1} \ + CONFIG.PCW_FCLK3_PERIPHERAL_DIVISOR0 {5} \ + CONFIG.PCW_FCLK3_PERIPHERAL_DIVISOR1 {2} \ + CONFIG.PCW_FCLK_CLK3_BUF {TRUE} \ + CONFIG.PCW_FPGA0_PERIPHERAL_FREQMHZ {100} \ + CONFIG.PCW_FPGA3_PERIPHERAL_FREQMHZ {100} \ + CONFIG.PCW_FPGA_FCLK0_ENABLE {1} \ + CONFIG.PCW_FPGA_FCLK1_ENABLE {0} \ + CONFIG.PCW_FPGA_FCLK2_ENABLE {0} \ + CONFIG.PCW_FPGA_FCLK3_ENABLE {1} \ + CONFIG.PCW_GPIO_EMIO_GPIO_ENABLE {1} \ + CONFIG.PCW_GPIO_EMIO_GPIO_IO {64} \ + CONFIG.PCW_GPIO_EMIO_GPIO_WIDTH {64} \ + CONFIG.PCW_GPIO_MIO_GPIO_ENABLE {1} \ + CONFIG.PCW_GPIO_MIO_GPIO_IO {MIO} \ + CONFIG.PCW_I2C0_GRP_INT_ENABLE {1} \ + CONFIG.PCW_I2C0_GRP_INT_IO {EMIO} \ + CONFIG.PCW_I2C0_I2C0_IO {EMIO} \ + CONFIG.PCW_I2C0_PERIPHERAL_ENABLE {1} \ + CONFIG.PCW_I2C0_RESET_ENABLE {0} \ + CONFIG.PCW_I2C1_RESET_ENABLE {0} \ + CONFIG.PCW_I2C_PERIPHERAL_FREQMHZ {111.111115} \ + CONFIG.PCW_I2C_RESET_ENABLE {1} \ + CONFIG.PCW_I2C_RESET_SELECT {Share reset pin} \ + CONFIG.PCW_IOPLL_CTRL_FBDIV {30} \ + CONFIG.PCW_IO_IO_PLL_FREQMHZ {1000.000} \ + CONFIG.PCW_IRQ_F2P_INTR {1} \ + CONFIG.PCW_IRQ_F2P_MODE {DIRECT} \ + CONFIG.PCW_MIO_0_DIRECTION {inout} \ + CONFIG.PCW_MIO_0_IOTYPE {LVCMOS 3.3V} \ + CONFIG.PCW_MIO_0_PULLUP {enabled} \ + CONFIG.PCW_MIO_0_SLEW {slow} \ + CONFIG.PCW_MIO_10_DIRECTION {inout} \ + CONFIG.PCW_MIO_10_IOTYPE {LVCMOS 3.3V} \ + CONFIG.PCW_MIO_10_PULLUP {enabled} \ + CONFIG.PCW_MIO_10_SLEW {slow} \ + CONFIG.PCW_MIO_11_DIRECTION {inout} \ + CONFIG.PCW_MIO_11_IOTYPE {LVCMOS 3.3V} \ + CONFIG.PCW_MIO_11_PULLUP {enabled} \ + CONFIG.PCW_MIO_11_SLEW {slow} \ + CONFIG.PCW_MIO_12_DIRECTION {inout} \ + CONFIG.PCW_MIO_12_IOTYPE {LVCMOS 3.3V} \ + CONFIG.PCW_MIO_12_PULLUP {enabled} \ + CONFIG.PCW_MIO_12_SLEW {slow} \ + CONFIG.PCW_MIO_13_DIRECTION {inout} \ + CONFIG.PCW_MIO_13_IOTYPE {LVCMOS 3.3V} \ + CONFIG.PCW_MIO_13_PULLUP {enabled} \ + CONFIG.PCW_MIO_13_SLEW {slow} \ + CONFIG.PCW_MIO_14_DIRECTION {inout} \ + CONFIG.PCW_MIO_14_IOTYPE {LVCMOS 3.3V} \ + CONFIG.PCW_MIO_14_PULLUP {enabled} \ + CONFIG.PCW_MIO_14_SLEW {slow} \ + CONFIG.PCW_MIO_15_DIRECTION {inout} \ + CONFIG.PCW_MIO_15_IOTYPE {LVCMOS 3.3V} \ + CONFIG.PCW_MIO_15_PULLUP {enabled} \ + CONFIG.PCW_MIO_15_SLEW {slow} \ + CONFIG.PCW_MIO_16_DIRECTION {out} \ + CONFIG.PCW_MIO_16_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_16_PULLUP {enabled} \ + CONFIG.PCW_MIO_16_SLEW {slow} \ + CONFIG.PCW_MIO_17_DIRECTION {out} \ + CONFIG.PCW_MIO_17_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_17_PULLUP {enabled} \ + CONFIG.PCW_MIO_17_SLEW {slow} \ + CONFIG.PCW_MIO_18_DIRECTION {out} \ + CONFIG.PCW_MIO_18_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_18_PULLUP {enabled} \ + CONFIG.PCW_MIO_18_SLEW {slow} \ + CONFIG.PCW_MIO_19_DIRECTION {out} \ + CONFIG.PCW_MIO_19_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_19_PULLUP {enabled} \ + CONFIG.PCW_MIO_19_SLEW {slow} \ + CONFIG.PCW_MIO_1_DIRECTION {out} \ + CONFIG.PCW_MIO_1_IOTYPE {LVCMOS 3.3V} \ + CONFIG.PCW_MIO_1_PULLUP {enabled} \ + CONFIG.PCW_MIO_1_SLEW {slow} \ + CONFIG.PCW_MIO_20_DIRECTION {out} \ + CONFIG.PCW_MIO_20_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_20_PULLUP {enabled} \ + CONFIG.PCW_MIO_20_SLEW {slow} \ + CONFIG.PCW_MIO_21_DIRECTION {out} \ + CONFIG.PCW_MIO_21_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_21_PULLUP {enabled} \ + CONFIG.PCW_MIO_21_SLEW {slow} \ + CONFIG.PCW_MIO_22_DIRECTION {in} \ + CONFIG.PCW_MIO_22_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_22_PULLUP {enabled} \ + CONFIG.PCW_MIO_22_SLEW {slow} \ + CONFIG.PCW_MIO_23_DIRECTION {in} \ + CONFIG.PCW_MIO_23_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_23_PULLUP {enabled} \ + CONFIG.PCW_MIO_23_SLEW {slow} \ + CONFIG.PCW_MIO_24_DIRECTION {in} \ + CONFIG.PCW_MIO_24_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_24_PULLUP {enabled} \ + CONFIG.PCW_MIO_24_SLEW {slow} \ + CONFIG.PCW_MIO_25_DIRECTION {in} \ + CONFIG.PCW_MIO_25_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_25_PULLUP {enabled} \ + CONFIG.PCW_MIO_25_SLEW {slow} \ + CONFIG.PCW_MIO_26_DIRECTION {in} \ + CONFIG.PCW_MIO_26_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_26_PULLUP {enabled} \ + CONFIG.PCW_MIO_26_SLEW {slow} \ + CONFIG.PCW_MIO_27_DIRECTION {in} \ + CONFIG.PCW_MIO_27_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_27_PULLUP {enabled} \ + CONFIG.PCW_MIO_27_SLEW {slow} \ + CONFIG.PCW_MIO_28_DIRECTION {inout} \ + CONFIG.PCW_MIO_28_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_28_PULLUP {enabled} \ + CONFIG.PCW_MIO_28_SLEW {slow} \ + CONFIG.PCW_MIO_29_DIRECTION {in} \ + CONFIG.PCW_MIO_29_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_29_PULLUP {enabled} \ + CONFIG.PCW_MIO_29_SLEW {slow} \ + CONFIG.PCW_MIO_2_DIRECTION {inout} \ + CONFIG.PCW_MIO_2_IOTYPE {LVCMOS 3.3V} \ + CONFIG.PCW_MIO_2_PULLUP {disabled} \ + CONFIG.PCW_MIO_2_SLEW {slow} \ + CONFIG.PCW_MIO_30_DIRECTION {out} \ + CONFIG.PCW_MIO_30_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_30_PULLUP {enabled} \ + CONFIG.PCW_MIO_30_SLEW {slow} \ + CONFIG.PCW_MIO_31_DIRECTION {in} \ + CONFIG.PCW_MIO_31_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_31_PULLUP {enabled} \ + CONFIG.PCW_MIO_31_SLEW {slow} \ + CONFIG.PCW_MIO_32_DIRECTION {inout} \ + CONFIG.PCW_MIO_32_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_32_PULLUP {enabled} \ + CONFIG.PCW_MIO_32_SLEW {slow} \ + CONFIG.PCW_MIO_33_DIRECTION {inout} \ + CONFIG.PCW_MIO_33_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_33_PULLUP {enabled} \ + CONFIG.PCW_MIO_33_SLEW {slow} \ + CONFIG.PCW_MIO_34_DIRECTION {inout} \ + CONFIG.PCW_MIO_34_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_34_PULLUP {enabled} \ + CONFIG.PCW_MIO_34_SLEW {slow} \ + CONFIG.PCW_MIO_35_DIRECTION {inout} \ + CONFIG.PCW_MIO_35_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_35_PULLUP {enabled} \ + CONFIG.PCW_MIO_35_SLEW {slow} \ + CONFIG.PCW_MIO_36_DIRECTION {in} \ + CONFIG.PCW_MIO_36_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_36_PULLUP {enabled} \ + CONFIG.PCW_MIO_36_SLEW {slow} \ + CONFIG.PCW_MIO_37_DIRECTION {inout} \ + CONFIG.PCW_MIO_37_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_37_PULLUP {enabled} \ + CONFIG.PCW_MIO_37_SLEW {slow} \ + CONFIG.PCW_MIO_38_DIRECTION {inout} \ + CONFIG.PCW_MIO_38_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_38_PULLUP {enabled} \ + CONFIG.PCW_MIO_38_SLEW {slow} \ + CONFIG.PCW_MIO_39_DIRECTION {inout} \ + CONFIG.PCW_MIO_39_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_39_PULLUP {enabled} \ + CONFIG.PCW_MIO_39_SLEW {slow} \ + CONFIG.PCW_MIO_3_DIRECTION {inout} \ + CONFIG.PCW_MIO_3_IOTYPE {LVCMOS 3.3V} \ + CONFIG.PCW_MIO_3_PULLUP {disabled} \ + CONFIG.PCW_MIO_3_SLEW {slow} \ + CONFIG.PCW_MIO_40_DIRECTION {inout} \ + CONFIG.PCW_MIO_40_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_40_PULLUP {enabled} \ + CONFIG.PCW_MIO_40_SLEW {slow} \ + CONFIG.PCW_MIO_41_DIRECTION {in} \ + CONFIG.PCW_MIO_41_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_41_PULLUP {enabled} \ + CONFIG.PCW_MIO_41_SLEW {slow} \ + CONFIG.PCW_MIO_42_DIRECTION {out} \ + CONFIG.PCW_MIO_42_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_42_PULLUP {enabled} \ + CONFIG.PCW_MIO_42_SLEW {slow} \ + CONFIG.PCW_MIO_43_DIRECTION {in} \ + CONFIG.PCW_MIO_43_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_43_PULLUP {enabled} \ + CONFIG.PCW_MIO_43_SLEW {slow} \ + CONFIG.PCW_MIO_44_DIRECTION {inout} \ + CONFIG.PCW_MIO_44_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_44_PULLUP {enabled} \ + CONFIG.PCW_MIO_44_SLEW {slow} \ + CONFIG.PCW_MIO_45_DIRECTION {inout} \ + CONFIG.PCW_MIO_45_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_45_PULLUP {enabled} \ + CONFIG.PCW_MIO_45_SLEW {slow} \ + CONFIG.PCW_MIO_46_DIRECTION {inout} \ + CONFIG.PCW_MIO_46_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_46_PULLUP {enabled} \ + CONFIG.PCW_MIO_46_SLEW {slow} \ + CONFIG.PCW_MIO_47_DIRECTION {inout} \ + CONFIG.PCW_MIO_47_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_47_PULLUP {enabled} \ + CONFIG.PCW_MIO_47_SLEW {slow} \ + CONFIG.PCW_MIO_48_DIRECTION {in} \ + CONFIG.PCW_MIO_48_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_48_PULLUP {enabled} \ + CONFIG.PCW_MIO_48_SLEW {slow} \ + CONFIG.PCW_MIO_49_DIRECTION {inout} \ + CONFIG.PCW_MIO_49_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_49_PULLUP {enabled} \ + CONFIG.PCW_MIO_49_SLEW {slow} \ + CONFIG.PCW_MIO_4_DIRECTION {inout} \ + CONFIG.PCW_MIO_4_IOTYPE {LVCMOS 3.3V} \ + CONFIG.PCW_MIO_4_PULLUP {disabled} \ + CONFIG.PCW_MIO_4_SLEW {slow} \ + CONFIG.PCW_MIO_50_DIRECTION {inout} \ + CONFIG.PCW_MIO_50_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_50_PULLUP {enabled} \ + CONFIG.PCW_MIO_50_SLEW {slow} \ + CONFIG.PCW_MIO_51_DIRECTION {inout} \ + CONFIG.PCW_MIO_51_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_51_PULLUP {enabled} \ + CONFIG.PCW_MIO_51_SLEW {slow} \ + CONFIG.PCW_MIO_52_DIRECTION {inout} \ + CONFIG.PCW_MIO_52_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_52_PULLUP {enabled} \ + CONFIG.PCW_MIO_52_SLEW {slow} \ + CONFIG.PCW_MIO_53_DIRECTION {inout} \ + CONFIG.PCW_MIO_53_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_53_PULLUP {enabled} \ + CONFIG.PCW_MIO_53_SLEW {slow} \ + CONFIG.PCW_MIO_5_DIRECTION {inout} \ + CONFIG.PCW_MIO_5_IOTYPE {LVCMOS 3.3V} \ + CONFIG.PCW_MIO_5_PULLUP {disabled} \ + CONFIG.PCW_MIO_5_SLEW {slow} \ + CONFIG.PCW_MIO_6_DIRECTION {out} \ + CONFIG.PCW_MIO_6_IOTYPE {LVCMOS 3.3V} \ + CONFIG.PCW_MIO_6_PULLUP {disabled} \ + CONFIG.PCW_MIO_6_SLEW {slow} \ + CONFIG.PCW_MIO_7_DIRECTION {out} \ + CONFIG.PCW_MIO_7_IOTYPE {LVCMOS 3.3V} \ + CONFIG.PCW_MIO_7_PULLUP {disabled} \ + CONFIG.PCW_MIO_7_SLEW {slow} \ + CONFIG.PCW_MIO_8_DIRECTION {out} \ + CONFIG.PCW_MIO_8_IOTYPE {LVCMOS 3.3V} \ + CONFIG.PCW_MIO_8_PULLUP {disabled} \ + CONFIG.PCW_MIO_8_SLEW {slow} \ + CONFIG.PCW_MIO_9_DIRECTION {in} \ + CONFIG.PCW_MIO_9_IOTYPE {LVCMOS 3.3V} \ + CONFIG.PCW_MIO_9_PULLUP {enabled} \ + CONFIG.PCW_MIO_9_SLEW {slow} \ + CONFIG.PCW_MIO_TREE_PERIPHERALS {GPIO#Quad SPI Flash#Quad SPI Flash#Quad SPI Flash#Quad SPI Flash#Quad SPI Flash#Quad SPI Flash#GPIO#UART 1#UART 1#SD 1#SD 1#SD 1#SD 1#SD 1#SD 1#Enet 0#Enet 0#Enet 0#Enet 0#Enet 0#Enet 0#Enet 0#Enet 0#Enet 0#Enet 0#Enet 0#Enet 0#USB 0#USB 0#USB 0#USB 0#USB 0#USB 0#USB 0#USB 0#USB 0#USB 0#USB 0#USB 0#USB 1#USB 1#USB 1#USB 1#USB 1#USB 1#USB 1#USB 1#USB 1#USB 1#USB 1#USB 1#GPIO#GPIO} \ + CONFIG.PCW_MIO_TREE_SIGNALS {gpio[0]#qspi0_ss_b#qspi0_io[0]#qspi0_io[1]#qspi0_io[2]#qspi0_io[3]/HOLD_B#qspi0_sclk#gpio[7]#tx#rx#data[0]#cmd#clk#data[1]#data[2]#data[3]#tx_clk#txd[0]#txd[1]#txd[2]#txd[3]#tx_ctl#rx_clk#rxd[0]#rxd[1]#rxd[2]#rxd[3]#rx_ctl#data[4]#dir#stp#nxt#data[0]#data[1]#data[2]#data[3]#clk#data[5]#data[6]#data[7]#data[4]#dir#stp#nxt#data[0]#data[1]#data[2]#data[3]#clk#data[5]#data[6]#data[7]#gpio[52]#gpio[53]} \ + CONFIG.PCW_NAND_GRP_D8_ENABLE {0} \ + CONFIG.PCW_NAND_PERIPHERAL_ENABLE {0} \ + CONFIG.PCW_NOR_GRP_A25_ENABLE {0} \ + CONFIG.PCW_NOR_GRP_CS0_ENABLE {0} \ + CONFIG.PCW_NOR_GRP_CS1_ENABLE {0} \ + CONFIG.PCW_NOR_GRP_SRAM_CS0_ENABLE {0} \ + CONFIG.PCW_NOR_GRP_SRAM_CS1_ENABLE {0} \ + CONFIG.PCW_NOR_GRP_SRAM_INT_ENABLE {0} \ + CONFIG.PCW_NOR_PERIPHERAL_ENABLE {0} \ + CONFIG.PCW_PCAP_PERIPHERAL_DIVISOR0 {5} \ + CONFIG.PCW_PRESET_BANK1_VOLTAGE {LVCMOS 1.8V} \ + CONFIG.PCW_QSPI_GRP_FBCLK_ENABLE {0} \ + CONFIG.PCW_QSPI_GRP_IO1_ENABLE {0} \ + CONFIG.PCW_QSPI_GRP_SINGLE_SS_ENABLE {1} \ + CONFIG.PCW_QSPI_GRP_SINGLE_SS_IO {MIO 1 .. 6} \ + CONFIG.PCW_QSPI_GRP_SS1_ENABLE {0} \ + CONFIG.PCW_QSPI_PERIPHERAL_DIVISOR0 {5} \ + CONFIG.PCW_QSPI_PERIPHERAL_ENABLE {1} \ + CONFIG.PCW_QSPI_PERIPHERAL_FREQMHZ {200} \ + CONFIG.PCW_QSPI_QSPI_IO {MIO 1 .. 6} \ + CONFIG.PCW_SD1_GRP_CD_ENABLE {0} \ + CONFIG.PCW_SD1_GRP_POW_ENABLE {0} \ + CONFIG.PCW_SD1_GRP_WP_ENABLE {0} \ + CONFIG.PCW_SD1_PERIPHERAL_ENABLE {1} \ + CONFIG.PCW_SD1_SD1_IO {MIO 10 .. 15} \ + CONFIG.PCW_SDIO_PERIPHERAL_DIVISOR0 {20} \ + CONFIG.PCW_SDIO_PERIPHERAL_FREQMHZ {50} \ + CONFIG.PCW_SDIO_PERIPHERAL_VALID {1} \ + CONFIG.PCW_SINGLE_QSPI_DATA_MODE {x4} \ + CONFIG.PCW_SMC_PERIPHERAL_DIVISOR0 {1} \ + CONFIG.PCW_SPI_PERIPHERAL_DIVISOR0 {1} \ + CONFIG.PCW_TPIU_PERIPHERAL_DIVISOR0 {1} \ + CONFIG.PCW_UART1_GRP_FULL_ENABLE {0} \ + CONFIG.PCW_UART1_PERIPHERAL_ENABLE {1} \ + CONFIG.PCW_UART1_UART1_IO {MIO 8 .. 9} \ + CONFIG.PCW_UART_PERIPHERAL_DIVISOR0 {10} \ + CONFIG.PCW_UART_PERIPHERAL_FREQMHZ {100} \ + CONFIG.PCW_UART_PERIPHERAL_VALID {1} \ + CONFIG.PCW_UIPARAM_ACT_DDR_FREQ_MHZ {400.000000} \ + CONFIG.PCW_UIPARAM_DDR_BANK_ADDR_COUNT {3} \ + CONFIG.PCW_UIPARAM_DDR_BOARD_DELAY0 {0.434} \ + CONFIG.PCW_UIPARAM_DDR_BOARD_DELAY1 {0.398} \ + CONFIG.PCW_UIPARAM_DDR_BOARD_DELAY2 {0.410} \ + CONFIG.PCW_UIPARAM_DDR_BOARD_DELAY3 {0.455} \ + CONFIG.PCW_UIPARAM_DDR_CL {9} \ + CONFIG.PCW_UIPARAM_DDR_COL_ADDR_COUNT {10} \ + CONFIG.PCW_UIPARAM_DDR_CWL {9} \ + CONFIG.PCW_UIPARAM_DDR_DEVICE_CAPACITY {8192 MBits} \ + CONFIG.PCW_UIPARAM_DDR_DQS_TO_CLK_DELAY_0 {0.315} \ + CONFIG.PCW_UIPARAM_DDR_DQS_TO_CLK_DELAY_1 {0.391} \ + CONFIG.PCW_UIPARAM_DDR_DQS_TO_CLK_DELAY_2 {0.374} \ + CONFIG.PCW_UIPARAM_DDR_DQS_TO_CLK_DELAY_3 {0.271} \ + CONFIG.PCW_UIPARAM_DDR_DRAM_WIDTH {32 Bits} \ + CONFIG.PCW_UIPARAM_DDR_FREQ_MHZ {400.00} \ + CONFIG.PCW_UIPARAM_DDR_PARTNO {Custom} \ + CONFIG.PCW_UIPARAM_DDR_ROW_ADDR_COUNT {15} \ + CONFIG.PCW_UIPARAM_DDR_SPEED_BIN {DDR3_1066F} \ + CONFIG.PCW_UIPARAM_DDR_T_FAW {50} \ + CONFIG.PCW_UIPARAM_DDR_T_RAS_MIN {40} \ + CONFIG.PCW_UIPARAM_DDR_T_RC {60} \ + CONFIG.PCW_UIPARAM_DDR_T_RCD {9} \ + CONFIG.PCW_UIPARAM_DDR_T_RP {9} \ + CONFIG.PCW_UIPARAM_DDR_USE_INTERNAL_VREF {1} \ + CONFIG.PCW_USB0_PERIPHERAL_ENABLE {1} \ + CONFIG.PCW_USB0_PERIPHERAL_FREQMHZ {60} \ + CONFIG.PCW_USB0_RESET_ENABLE {0} \ + CONFIG.PCW_USB0_USB0_IO {MIO 28 .. 39} \ + CONFIG.PCW_USB1_PERIPHERAL_ENABLE {1} \ + CONFIG.PCW_USB1_PERIPHERAL_FREQMHZ {60} \ + CONFIG.PCW_USB1_RESET_ENABLE {0} \ + CONFIG.PCW_USB1_USB1_IO {MIO 40 .. 51} \ + CONFIG.PCW_USB_RESET_ENABLE {1} \ + CONFIG.PCW_USB_RESET_SELECT {Share reset pin} \ + CONFIG.PCW_USE_FABRIC_INTERRUPT {1} \ + CONFIG.PCW_USE_M_AXI_GP1 {1} \ + CONFIG.PCW_USE_S_AXI_HP1 {1} \ + ] $processing_system7_0 # Create instance: processing_system7_0_axi_periph, and set properties set processing_system7_0_axi_periph [ create_bd_cell -type ip -vlnv xilinx.com:ip:axi_interconnect:2.1 processing_system7_0_axi_periph ] - set_property -dict [ list CONFIG.NUM_MI {1} ] $processing_system7_0_axi_periph + set_property -dict [ list \ + CONFIG.NUM_MI {1} \ + ] $processing_system7_0_axi_periph # Create instance: sys_concat_intc, and set properties set sys_concat_intc [ create_bd_cell -type ip -vlnv xilinx.com:ip:xlconcat:2.1 sys_concat_intc ] - set_property -dict [ list CONFIG.NUM_PORTS {16} ] $sys_concat_intc + set_property -dict [ list \ + CONFIG.NUM_PORTS {16} \ + ] $sys_concat_intc # Create interface connections connect_bd_intf_net -intf_net axi_mem_intercon_M00_AXI [get_bd_intf_pins axi_mem_intercon/M00_AXI] [get_bd_intf_pins processing_system7_0/S_AXI_HP1] @@ -235,15 +662,15 @@ CONFIG.PCW_USE_S_AXI_HP1 {1} ] $processing_system7_0 connect_bd_intf_net -intf_net processing_system7_0_axi_periph_M00_AXI [get_bd_intf_pins parallella_base_0/s_axi] [get_bd_intf_pins processing_system7_0_axi_periph/M00_AXI] # Create port connections - connect_bd_net -net Net [get_bd_ports gpio_n] [get_bd_pins parallella_base_0/gpio_n] - connect_bd_net -net Net1 [get_bd_ports gpio_p] [get_bd_pins parallella_base_0/gpio_p] - connect_bd_net -net Net2 [get_bd_ports i2c_scl] [get_bd_pins parallella_base_0/i2c_scl] - connect_bd_net -net Net3 [get_bd_ports i2c_sda] [get_bd_pins parallella_base_0/i2c_sda] connect_bd_net -net parallella_base_0_cclk_n [get_bd_ports cclk_n] [get_bd_pins parallella_base_0/cclk_n] connect_bd_net -net parallella_base_0_cclk_p [get_bd_ports cclk_p] [get_bd_pins parallella_base_0/cclk_p] connect_bd_net -net parallella_base_0_chip_resetb [get_bd_ports chip_nreset] [get_bd_pins parallella_base_0/chip_nreset] connect_bd_net -net parallella_base_0_constant_zero [get_bd_pins parallella_base_0/constant_zero] [get_bd_pins sys_concat_intc/In0] [get_bd_pins sys_concat_intc/In1] [get_bd_pins sys_concat_intc/In2] [get_bd_pins sys_concat_intc/In3] [get_bd_pins sys_concat_intc/In4] [get_bd_pins sys_concat_intc/In5] [get_bd_pins sys_concat_intc/In6] [get_bd_pins sys_concat_intc/In7] [get_bd_pins sys_concat_intc/In8] [get_bd_pins sys_concat_intc/In9] [get_bd_pins sys_concat_intc/In10] [get_bd_pins sys_concat_intc/In12] [get_bd_pins sys_concat_intc/In13] [get_bd_pins sys_concat_intc/In14] [get_bd_pins sys_concat_intc/In15] + connect_bd_net -net parallella_base_0_gpio_n [get_bd_ports gpio_n] [get_bd_pins parallella_base_0/gpio_n] + connect_bd_net -net parallella_base_0_gpio_p [get_bd_ports gpio_p] [get_bd_pins parallella_base_0/gpio_p] + connect_bd_net -net parallella_base_0_i2c_scl [get_bd_ports i2c_scl] [get_bd_pins parallella_base_0/i2c_scl] connect_bd_net -net parallella_base_0_i2c_scl_i [get_bd_pins parallella_base_0/i2c_scl_i] [get_bd_pins processing_system7_0/I2C0_SCL_I] + connect_bd_net -net parallella_base_0_i2c_sda [get_bd_ports i2c_sda] [get_bd_pins parallella_base_0/i2c_sda] connect_bd_net -net parallella_base_0_i2c_sda_i [get_bd_pins parallella_base_0/i2c_sda_i] [get_bd_pins processing_system7_0/I2C0_SDA_I] connect_bd_net -net parallella_base_0_mailbox_irq [get_bd_pins parallella_base_0/mailbox_irq] [get_bd_pins sys_concat_intc/In11] connect_bd_net -net parallella_base_0_ps_gpio_i [get_bd_pins parallella_base_0/ps_gpio_i] [get_bd_pins processing_system7_0/GPIO_I] @@ -280,9 +707,9 @@ CONFIG.PCW_USE_S_AXI_HP1 {1} ] $processing_system7_0 connect_bd_net -net txi_wr_wait_p_1 [get_bd_ports txi_wr_wait_p] [get_bd_pins parallella_base_0/txi_wr_wait_p] # Create address segments - create_bd_addr_seg -range 0x40000000 -offset 0x0 [get_bd_addr_spaces parallella_base_0/m_axi] [get_bd_addr_segs processing_system7_0/S_AXI_HP1/HP1_DDR_LOWOCM] SEG_processing_system7_0_HP1_DDR_LOWOCM + create_bd_addr_seg -range 0x40000000 -offset 0x00000000 [get_bd_addr_spaces parallella_base_0/m_axi] [get_bd_addr_segs processing_system7_0/S_AXI_HP1/HP1_DDR_LOWOCM] SEG_processing_system7_0_HP1_DDR_LOWOCM create_bd_addr_seg -range 0x40000000 -offset 0x80000000 [get_bd_addr_spaces processing_system7_0/Data] [get_bd_addr_segs parallella_base_0/s_axi/axi_lite] SEG_parallella_base_0_axi_lite - + # Restore current instance current_bd_instance $oldCurInst diff --git a/src/parallella/fpga/headless_e16_z7010/system_params.tcl b/src/parallella/fpga/headless_e16_z7010/system_params.tcl index 4ce1a4cf..cce9bdd2 100644 --- a/src/parallella/fpga/headless_e16_z7010/system_params.tcl +++ b/src/parallella/fpga/headless_e16_z7010/system_params.tcl @@ -24,4 +24,4 @@ set constraints_files [list \ ########################################################### # PREPARE FOR SYNTHESIS ########################################################### -set oh_synthesis_options "-verilog_define CFG_ASIC=0" +set oh_verilog_define "CFG_ASIC=0 CFG_PLATFORM=\"ZYNQ\"" diff --git a/src/parallella/fpga/headless_e16_z7020/parallella.bit.bin b/src/parallella/fpga/headless_e16_z7020/parallella.bit.bin deleted file mode 100644 index 9e1a2137..00000000 Binary files a/src/parallella/fpga/headless_e16_z7020/parallella.bit.bin and /dev/null differ diff --git a/src/parallella/fpga/headless_e16_z7020/parallella_e16_headless_gpiose_7020.bit.bin b/src/parallella/fpga/headless_e16_z7020/parallella_e16_headless_gpiose_7020.bit.bin deleted file mode 100644 index 465d93e8..00000000 Binary files a/src/parallella/fpga/headless_e16_z7020/parallella_e16_headless_gpiose_7020.bit.bin and /dev/null differ diff --git a/src/parallella/fpga/headless_e16_z7020/system_bd.tcl b/src/parallella/fpga/headless_e16_z7020/system_bd.tcl index 6dc43082..c9e4d976 100644 --- a/src/parallella/fpga/headless_e16_z7020/system_bd.tcl +++ b/src/parallella/fpga/headless_e16_z7020/system_bd.tcl @@ -7,15 +7,25 @@ # IP Integrator Tcl commands easier. ################################################################ +namespace eval _tcl { +proc get_script_folder {} { + set script_path [file normalize [info script]] + set script_folder [file dirname $script_path] + return $script_folder +} +} +variable script_folder +set script_folder [_tcl::get_script_folder] + ################################################################ # Check if script is running in correct Vivado version. ################################################################ -set scripts_vivado_version 2015.2 +set scripts_vivado_version 2018.2 set current_vivado_version [version -short] if { [string first $scripts_vivado_version $current_vivado_version] == -1 } { puts "" - puts "ERROR: This script was generated using Vivado <$scripts_vivado_version> and is being run in <$current_vivado_version> of Vivado. Please run the script in Vivado <$scripts_vivado_version> then open the design in Vivado <$current_vivado_version>. Upgrade the design by running \"Tools => Report => Report IP Status...\", then run write_bd_tcl to create an updated script." + catch {common::send_msg_id "BD_TCL-109" "ERROR" "This script was generated using Vivado <$scripts_vivado_version> and is being run in <$current_vivado_version> of Vivado. Please run the script in Vivado <$scripts_vivado_version> then open the design in Vivado <$current_vivado_version>. Upgrade the design by running \"Tools => Report => Report IP Status...\", then run write_bd_tcl to create an updated script."} return 1 } @@ -27,19 +37,18 @@ if { [string first $scripts_vivado_version $current_vivado_version] == -1 } { # To test this script, run the following commands from Vivado Tcl console: # source system_script.tcl -# If you do not already have a project created, -# you can create a project using the following command: -# create_project project_1 myproj -part xc7z020clg400-1 +# If there is no project opened, this script will create a +# project, but make sure you do not have an existing project +# <./myproj/project_1.xpr> in the current working folder. -# CHECKING IF PROJECT EXISTS -if { [get_projects -quiet] eq "" } { - puts "ERROR: Please open or create a project!" - return 1 +set list_projs [get_projects -quiet] +if { $list_projs eq "" } { + create_project project_1 myproj -part xc7z020clg400-1 } - # CHANGE DESIGN NAME HERE +variable design_name set design_name system # If you do not already have an existing IP Integrator design open, @@ -57,7 +66,7 @@ if { ${design_name} eq "" } { # USE CASES: # 1) Design_name not set - set errMsg "ERROR: Please set the variable to a non-empty value." + set errMsg "Please set the variable to a non-empty value." set nRet 1 } elseif { ${cur_design} ne "" && ${list_cells} eq "" } { @@ -67,23 +76,23 @@ if { ${design_name} eq "" } { # 4): Current design opened AND is empty AND names diff; design_name exists in project. if { $cur_design ne $design_name } { - puts "INFO: Changing value of from <$design_name> to <$cur_design> since current design is empty." + common::send_msg_id "BD_TCL-001" "INFO" "Changing value of from <$design_name> to <$cur_design> since current design is empty." set design_name [get_property NAME $cur_design] } - puts "INFO: Constructing design in IPI design <$cur_design>..." + common::send_msg_id "BD_TCL-002" "INFO" "Constructing design in IPI design <$cur_design>..." } elseif { ${cur_design} ne "" && $list_cells ne "" && $cur_design eq $design_name } { # USE CASES: # 5) Current design opened AND has components AND same names. - set errMsg "ERROR: Design <$design_name> already exists in your project, please set the variable to another value." + set errMsg "Design <$design_name> already exists in your project, please set the variable to another value." set nRet 1 } elseif { [get_files -quiet ${design_name}.bd] ne "" } { # USE CASES: # 6) Current opened design, has components, but diff names, design_name exists in project. # 7) No opened design, design_name exists in project. - set errMsg "ERROR: Design <$design_name> already exists in your project, please set the variable to another value." + set errMsg "Design <$design_name> already exists in your project, please set the variable to another value." set nRet 2 } else { @@ -91,22 +100,57 @@ if { ${design_name} eq "" } { # 8) No opened design, design_name not in project. # 9) Current opened design, has components, but diff names, design_name not in project. - puts "INFO: Currently there is no design <$design_name> in project, so creating one..." + common::send_msg_id "BD_TCL-003" "INFO" "Currently there is no design <$design_name> in project, so creating one..." create_bd_design $design_name - puts "INFO: Making design <$design_name> as current_bd_design." + common::send_msg_id "BD_TCL-004" "INFO" "Making design <$design_name> as current_bd_design." current_bd_design $design_name } -puts "INFO: Currently the variable is equal to \"$design_name\"." +common::send_msg_id "BD_TCL-005" "INFO" "Currently the variable is equal to \"$design_name\"." if { $nRet != 0 } { - puts $errMsg + catch {common::send_msg_id "BD_TCL-114" "ERROR" $errMsg} return $nRet } +set bCheckIPsPassed 1 +################################################################## +# CHECK IPs +################################################################## +set bCheckIPs 1 +if { $bCheckIPs == 1 } { + set list_check_ips "\ +www.parallella.org:user:parallella_base:1.0\ +xilinx.com:ip:proc_sys_reset:5.0\ +xilinx.com:ip:processing_system7:5.5\ +xilinx.com:ip:xlconcat:2.1\ +" + + set list_ips_missing "" + common::send_msg_id "BD_TCL-006" "INFO" "Checking if the following IPs exist in the project's IP catalog: $list_check_ips ." + + foreach ip_vlnv $list_check_ips { + set ip_obj [get_ipdefs -all $ip_vlnv] + if { $ip_obj eq "" } { + lappend list_ips_missing $ip_vlnv + } + } + + if { $list_ips_missing ne "" } { + catch {common::send_msg_id "BD_TCL-115" "ERROR" "The following IPs are not found in the IP Catalog:\n $list_ips_missing\n\nResolution: Please add the repository containing the IP(s) to the project." } + set bCheckIPsPassed 0 + } + +} + +if { $bCheckIPsPassed != 1 } { + common::send_msg_id "BD_TCL-1003" "WARNING" "Will not continue with creation of design due to the error(s) above." + return 3 +} + ################################################################## # DESIGN PROCs ################################################################## @@ -117,6 +161,9 @@ if { $nRet != 0 } { # procedure reusable. If parentCell is "", will use root. proc create_root_design { parentCell } { + variable script_folder + variable design_name + if { $parentCell eq "" } { set parentCell [get_bd_cells /] } @@ -124,14 +171,14 @@ proc create_root_design { parentCell } { # Get object for parentCell set parentObj [get_bd_cells $parentCell] if { $parentObj == "" } { - puts "ERROR: Unable to find parent cell <$parentCell>!" + catch {common::send_msg_id "BD_TCL-100" "ERROR" "Unable to find parent cell <$parentCell>!"} return } # Make sure parentObj is hier blk set parentType [get_property TYPE $parentObj] if { $parentType ne "hier" } { - puts "ERROR: Parent <$parentObj> has TYPE = <$parentType>. Expected to be ." + catch {common::send_msg_id "BD_TCL-101" "ERROR" "Parent <$parentObj> has TYPE = <$parentType>. Expected to be ."} return } @@ -150,8 +197,8 @@ proc create_root_design { parentCell } { set chip_nreset [ create_bd_port -dir O chip_nreset ] set gpio_n [ create_bd_port -dir IO -from 23 -to 0 gpio_n ] set gpio_p [ create_bd_port -dir IO -from 23 -to 0 gpio_p ] - set hdmi_clk [ create_bd_port -dir O hdmi_clk ] - set hdmi_d [ create_bd_port -dir O -from 23 -to 8 hdmi_d ] + set hdmi_clk [ create_bd_port -dir O -type clk hdmi_clk ] + set hdmi_d [ create_bd_port -dir O -from 15 -to 0 hdmi_d ] set hdmi_de [ create_bd_port -dir O hdmi_de ] set hdmi_hsync [ create_bd_port -dir O hdmi_hsync ] set hdmi_int [ create_bd_port -dir I hdmi_int ] @@ -182,51 +229,431 @@ proc create_root_design { parentCell } { # Create instance: axi_mem_intercon, and set properties set axi_mem_intercon [ create_bd_cell -type ip -vlnv xilinx.com:ip:axi_interconnect:2.1 axi_mem_intercon ] - set_property -dict [ list CONFIG.NUM_MI {1} ] $axi_mem_intercon + set_property -dict [ list \ + CONFIG.NUM_MI {1} \ + ] $axi_mem_intercon # Create instance: parallella_base_0, and set properties set parallella_base_0 [ create_bd_cell -type ip -vlnv www.parallella.org:user:parallella_base:1.0 parallella_base_0 ] - set_property -dict [ list CONFIG.NGPIO {24} ] $parallella_base_0 + set_property -dict [ list \ + CONFIG.NGPIO {24} \ + ] $parallella_base_0 # Create instance: proc_sys_reset_0, and set properties set proc_sys_reset_0 [ create_bd_cell -type ip -vlnv xilinx.com:ip:proc_sys_reset:5.0 proc_sys_reset_0 ] # Create instance: processing_system7_0, and set properties set processing_system7_0 [ create_bd_cell -type ip -vlnv xilinx.com:ip:processing_system7:5.5 processing_system7_0 ] - set_property -dict [ list CONFIG.PCW_CORE0_FIQ_INTR {0} \ -CONFIG.PCW_ENET0_ENET0_IO {MIO 16 .. 27} CONFIG.PCW_ENET0_GRP_MDIO_ENABLE {1} \ -CONFIG.PCW_ENET0_PERIPHERAL_ENABLE {1} CONFIG.PCW_ENET1_PERIPHERAL_ENABLE {0} \ -CONFIG.PCW_EN_CLK3_PORT {1} CONFIG.PCW_FPGA0_PERIPHERAL_FREQMHZ {100} \ -CONFIG.PCW_FPGA3_PERIPHERAL_FREQMHZ {100} CONFIG.PCW_GPIO_EMIO_GPIO_ENABLE {1} \ -CONFIG.PCW_GPIO_MIO_GPIO_ENABLE {1} CONFIG.PCW_GPIO_MIO_GPIO_IO {MIO} \ -CONFIG.PCW_I2C0_I2C0_IO {EMIO} CONFIG.PCW_I2C0_PERIPHERAL_ENABLE {1} \ -CONFIG.PCW_I2C0_RESET_ENABLE {0} CONFIG.PCW_IRQ_F2P_INTR {1} \ -CONFIG.PCW_IRQ_F2P_MODE {DIRECT} CONFIG.PCW_PRESET_BANK1_VOLTAGE {LVCMOS 1.8V} \ -CONFIG.PCW_QSPI_GRP_SINGLE_SS_ENABLE {1} CONFIG.PCW_QSPI_PERIPHERAL_ENABLE {1} \ -CONFIG.PCW_SD1_PERIPHERAL_ENABLE {1} CONFIG.PCW_SD1_SD1_IO {MIO 10 .. 15} \ -CONFIG.PCW_SDIO_PERIPHERAL_FREQMHZ {50} CONFIG.PCW_UART1_PERIPHERAL_ENABLE {1} \ -CONFIG.PCW_UART1_UART1_IO {MIO 8 .. 9} CONFIG.PCW_UIPARAM_DDR_BOARD_DELAY0 {0.434} \ -CONFIG.PCW_UIPARAM_DDR_BOARD_DELAY1 {0.398} CONFIG.PCW_UIPARAM_DDR_BOARD_DELAY2 {0.410} \ -CONFIG.PCW_UIPARAM_DDR_BOARD_DELAY3 {0.455} CONFIG.PCW_UIPARAM_DDR_CL {9} \ -CONFIG.PCW_UIPARAM_DDR_CWL {9} CONFIG.PCW_UIPARAM_DDR_DEVICE_CAPACITY {8192 MBits} \ -CONFIG.PCW_UIPARAM_DDR_DQS_TO_CLK_DELAY_0 {0.315} CONFIG.PCW_UIPARAM_DDR_DQS_TO_CLK_DELAY_1 {0.391} \ -CONFIG.PCW_UIPARAM_DDR_DQS_TO_CLK_DELAY_2 {0.374} CONFIG.PCW_UIPARAM_DDR_DQS_TO_CLK_DELAY_3 {0.271} \ -CONFIG.PCW_UIPARAM_DDR_DRAM_WIDTH {32 Bits} CONFIG.PCW_UIPARAM_DDR_FREQ_MHZ {400.00} \ -CONFIG.PCW_UIPARAM_DDR_PARTNO {Custom} CONFIG.PCW_UIPARAM_DDR_T_FAW {50} \ -CONFIG.PCW_UIPARAM_DDR_T_RAS_MIN {40} CONFIG.PCW_UIPARAM_DDR_T_RC {60} \ -CONFIG.PCW_UIPARAM_DDR_T_RCD {9} CONFIG.PCW_UIPARAM_DDR_T_RP {9} \ -CONFIG.PCW_UIPARAM_DDR_USE_INTERNAL_VREF {1} CONFIG.PCW_USB0_PERIPHERAL_ENABLE {1} \ -CONFIG.PCW_USB0_RESET_ENABLE {0} CONFIG.PCW_USB1_PERIPHERAL_ENABLE {1} \ -CONFIG.PCW_USE_FABRIC_INTERRUPT {1} CONFIG.PCW_USE_M_AXI_GP1 {1} \ -CONFIG.PCW_USE_S_AXI_HP1 {1} ] $processing_system7_0 + set_property -dict [ list \ + CONFIG.PCW_ACT_APU_PERIPHERAL_FREQMHZ {666.666687} \ + CONFIG.PCW_ACT_CAN_PERIPHERAL_FREQMHZ {10.000000} \ + CONFIG.PCW_ACT_DCI_PERIPHERAL_FREQMHZ {10.062893} \ + CONFIG.PCW_ACT_ENET0_PERIPHERAL_FREQMHZ {125.000000} \ + CONFIG.PCW_ACT_ENET1_PERIPHERAL_FREQMHZ {10.000000} \ + CONFIG.PCW_ACT_FPGA0_PERIPHERAL_FREQMHZ {100.000000} \ + CONFIG.PCW_ACT_FPGA1_PERIPHERAL_FREQMHZ {10.000000} \ + CONFIG.PCW_ACT_FPGA2_PERIPHERAL_FREQMHZ {10.000000} \ + CONFIG.PCW_ACT_FPGA3_PERIPHERAL_FREQMHZ {100.000000} \ + CONFIG.PCW_ACT_PCAP_PERIPHERAL_FREQMHZ {200.000000} \ + CONFIG.PCW_ACT_QSPI_PERIPHERAL_FREQMHZ {200.000000} \ + CONFIG.PCW_ACT_SDIO_PERIPHERAL_FREQMHZ {50.000000} \ + CONFIG.PCW_ACT_SMC_PERIPHERAL_FREQMHZ {10.000000} \ + CONFIG.PCW_ACT_SPI_PERIPHERAL_FREQMHZ {10.000000} \ + CONFIG.PCW_ACT_TPIU_PERIPHERAL_FREQMHZ {200.000000} \ + CONFIG.PCW_ACT_TTC0_CLK0_PERIPHERAL_FREQMHZ {111.111115} \ + CONFIG.PCW_ACT_TTC0_CLK1_PERIPHERAL_FREQMHZ {111.111115} \ + CONFIG.PCW_ACT_TTC0_CLK2_PERIPHERAL_FREQMHZ {111.111115} \ + CONFIG.PCW_ACT_TTC1_CLK0_PERIPHERAL_FREQMHZ {111.111115} \ + CONFIG.PCW_ACT_TTC1_CLK1_PERIPHERAL_FREQMHZ {111.111115} \ + CONFIG.PCW_ACT_TTC1_CLK2_PERIPHERAL_FREQMHZ {111.111115} \ + CONFIG.PCW_ACT_UART_PERIPHERAL_FREQMHZ {100.000000} \ + CONFIG.PCW_ACT_WDT_PERIPHERAL_FREQMHZ {111.111115} \ + CONFIG.PCW_ARMPLL_CTRL_FBDIV {40} \ + CONFIG.PCW_CAN_PERIPHERAL_DIVISOR0 {1} \ + CONFIG.PCW_CAN_PERIPHERAL_DIVISOR1 {1} \ + CONFIG.PCW_CLK0_FREQ {100000000} \ + CONFIG.PCW_CLK1_FREQ {10000000} \ + CONFIG.PCW_CLK2_FREQ {10000000} \ + CONFIG.PCW_CLK3_FREQ {100000000} \ + CONFIG.PCW_CORE0_FIQ_INTR {0} \ + CONFIG.PCW_CPU_CPU_PLL_FREQMHZ {1333.333} \ + CONFIG.PCW_CPU_PERIPHERAL_DIVISOR0 {2} \ + CONFIG.PCW_DCI_PERIPHERAL_DIVISOR0 {53} \ + CONFIG.PCW_DCI_PERIPHERAL_DIVISOR1 {3} \ + CONFIG.PCW_DDRPLL_CTRL_FBDIV {48} \ + CONFIG.PCW_DDR_DDR_PLL_FREQMHZ {1600.000} \ + CONFIG.PCW_DDR_PERIPHERAL_DIVISOR0 {4} \ + CONFIG.PCW_DDR_RAM_HIGHADDR {0x3FFFFFFF} \ + CONFIG.PCW_ENET0_ENET0_IO {MIO 16 .. 27} \ + CONFIG.PCW_ENET0_GRP_MDIO_ENABLE {1} \ + CONFIG.PCW_ENET0_GRP_MDIO_IO {EMIO} \ + CONFIG.PCW_ENET0_PERIPHERAL_DIVISOR0 {8} \ + CONFIG.PCW_ENET0_PERIPHERAL_DIVISOR1 {1} \ + CONFIG.PCW_ENET0_PERIPHERAL_ENABLE {1} \ + CONFIG.PCW_ENET0_PERIPHERAL_FREQMHZ {1000 Mbps} \ + CONFIG.PCW_ENET0_RESET_ENABLE {0} \ + CONFIG.PCW_ENET1_GRP_MDIO_ENABLE {0} \ + CONFIG.PCW_ENET1_PERIPHERAL_DIVISOR0 {1} \ + CONFIG.PCW_ENET1_PERIPHERAL_DIVISOR1 {1} \ + CONFIG.PCW_ENET1_PERIPHERAL_ENABLE {0} \ + CONFIG.PCW_ENET1_PERIPHERAL_FREQMHZ {1000 Mbps} \ + CONFIG.PCW_ENET1_RESET_ENABLE {0} \ + CONFIG.PCW_ENET_RESET_ENABLE {1} \ + CONFIG.PCW_ENET_RESET_SELECT {Share reset pin} \ + CONFIG.PCW_EN_CLK3_PORT {1} \ + CONFIG.PCW_EN_EMIO_CD_SDIO1 {0} \ + CONFIG.PCW_EN_EMIO_GPIO {1} \ + CONFIG.PCW_EN_EMIO_I2C0 {1} \ + CONFIG.PCW_EN_EMIO_SDIO1 {0} \ + CONFIG.PCW_EN_EMIO_WP_SDIO1 {0} \ + CONFIG.PCW_EN_ENET0 {1} \ + CONFIG.PCW_EN_GPIO {1} \ + CONFIG.PCW_EN_I2C0 {1} \ + CONFIG.PCW_EN_QSPI {1} \ + CONFIG.PCW_EN_SDIO1 {1} \ + CONFIG.PCW_EN_UART1 {1} \ + CONFIG.PCW_EN_USB0 {1} \ + CONFIG.PCW_EN_USB1 {1} \ + CONFIG.PCW_FCLK0_PERIPHERAL_DIVISOR0 {5} \ + CONFIG.PCW_FCLK0_PERIPHERAL_DIVISOR1 {2} \ + CONFIG.PCW_FCLK1_PERIPHERAL_DIVISOR0 {1} \ + CONFIG.PCW_FCLK1_PERIPHERAL_DIVISOR1 {1} \ + CONFIG.PCW_FCLK2_PERIPHERAL_DIVISOR0 {1} \ + CONFIG.PCW_FCLK2_PERIPHERAL_DIVISOR1 {1} \ + CONFIG.PCW_FCLK3_PERIPHERAL_DIVISOR0 {5} \ + CONFIG.PCW_FCLK3_PERIPHERAL_DIVISOR1 {2} \ + CONFIG.PCW_FCLK_CLK3_BUF {TRUE} \ + CONFIG.PCW_FPGA0_PERIPHERAL_FREQMHZ {100} \ + CONFIG.PCW_FPGA3_PERIPHERAL_FREQMHZ {100} \ + CONFIG.PCW_FPGA_FCLK0_ENABLE {1} \ + CONFIG.PCW_FPGA_FCLK1_ENABLE {0} \ + CONFIG.PCW_FPGA_FCLK2_ENABLE {0} \ + CONFIG.PCW_FPGA_FCLK3_ENABLE {1} \ + CONFIG.PCW_GPIO_EMIO_GPIO_ENABLE {1} \ + CONFIG.PCW_GPIO_EMIO_GPIO_IO {64} \ + CONFIG.PCW_GPIO_EMIO_GPIO_WIDTH {64} \ + CONFIG.PCW_GPIO_MIO_GPIO_ENABLE {1} \ + CONFIG.PCW_GPIO_MIO_GPIO_IO {MIO} \ + CONFIG.PCW_I2C0_GRP_INT_ENABLE {1} \ + CONFIG.PCW_I2C0_GRP_INT_IO {EMIO} \ + CONFIG.PCW_I2C0_I2C0_IO {EMIO} \ + CONFIG.PCW_I2C0_PERIPHERAL_ENABLE {1} \ + CONFIG.PCW_I2C0_RESET_ENABLE {0} \ + CONFIG.PCW_I2C1_RESET_ENABLE {0} \ + CONFIG.PCW_I2C_PERIPHERAL_FREQMHZ {111.111115} \ + CONFIG.PCW_I2C_RESET_ENABLE {1} \ + CONFIG.PCW_I2C_RESET_SELECT {Share reset pin} \ + CONFIG.PCW_IOPLL_CTRL_FBDIV {30} \ + CONFIG.PCW_IO_IO_PLL_FREQMHZ {1000.000} \ + CONFIG.PCW_IRQ_F2P_INTR {1} \ + CONFIG.PCW_IRQ_F2P_MODE {DIRECT} \ + CONFIG.PCW_MIO_0_DIRECTION {inout} \ + CONFIG.PCW_MIO_0_IOTYPE {LVCMOS 3.3V} \ + CONFIG.PCW_MIO_0_PULLUP {enabled} \ + CONFIG.PCW_MIO_0_SLEW {slow} \ + CONFIG.PCW_MIO_10_DIRECTION {inout} \ + CONFIG.PCW_MIO_10_IOTYPE {LVCMOS 3.3V} \ + CONFIG.PCW_MIO_10_PULLUP {enabled} \ + CONFIG.PCW_MIO_10_SLEW {slow} \ + CONFIG.PCW_MIO_11_DIRECTION {inout} \ + CONFIG.PCW_MIO_11_IOTYPE {LVCMOS 3.3V} \ + CONFIG.PCW_MIO_11_PULLUP {enabled} \ + CONFIG.PCW_MIO_11_SLEW {slow} \ + CONFIG.PCW_MIO_12_DIRECTION {inout} \ + CONFIG.PCW_MIO_12_IOTYPE {LVCMOS 3.3V} \ + CONFIG.PCW_MIO_12_PULLUP {enabled} \ + CONFIG.PCW_MIO_12_SLEW {slow} \ + CONFIG.PCW_MIO_13_DIRECTION {inout} \ + CONFIG.PCW_MIO_13_IOTYPE {LVCMOS 3.3V} \ + CONFIG.PCW_MIO_13_PULLUP {enabled} \ + CONFIG.PCW_MIO_13_SLEW {slow} \ + CONFIG.PCW_MIO_14_DIRECTION {inout} \ + CONFIG.PCW_MIO_14_IOTYPE {LVCMOS 3.3V} \ + CONFIG.PCW_MIO_14_PULLUP {enabled} \ + CONFIG.PCW_MIO_14_SLEW {slow} \ + CONFIG.PCW_MIO_15_DIRECTION {inout} \ + CONFIG.PCW_MIO_15_IOTYPE {LVCMOS 3.3V} \ + CONFIG.PCW_MIO_15_PULLUP {enabled} \ + CONFIG.PCW_MIO_15_SLEW {slow} \ + CONFIG.PCW_MIO_16_DIRECTION {out} \ + CONFIG.PCW_MIO_16_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_16_PULLUP {enabled} \ + CONFIG.PCW_MIO_16_SLEW {slow} \ + CONFIG.PCW_MIO_17_DIRECTION {out} \ + CONFIG.PCW_MIO_17_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_17_PULLUP {enabled} \ + CONFIG.PCW_MIO_17_SLEW {slow} \ + CONFIG.PCW_MIO_18_DIRECTION {out} \ + CONFIG.PCW_MIO_18_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_18_PULLUP {enabled} \ + CONFIG.PCW_MIO_18_SLEW {slow} \ + CONFIG.PCW_MIO_19_DIRECTION {out} \ + CONFIG.PCW_MIO_19_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_19_PULLUP {enabled} \ + CONFIG.PCW_MIO_19_SLEW {slow} \ + CONFIG.PCW_MIO_1_DIRECTION {out} \ + CONFIG.PCW_MIO_1_IOTYPE {LVCMOS 3.3V} \ + CONFIG.PCW_MIO_1_PULLUP {enabled} \ + CONFIG.PCW_MIO_1_SLEW {slow} \ + CONFIG.PCW_MIO_20_DIRECTION {out} \ + CONFIG.PCW_MIO_20_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_20_PULLUP {enabled} \ + CONFIG.PCW_MIO_20_SLEW {slow} \ + CONFIG.PCW_MIO_21_DIRECTION {out} \ + CONFIG.PCW_MIO_21_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_21_PULLUP {enabled} \ + CONFIG.PCW_MIO_21_SLEW {slow} \ + CONFIG.PCW_MIO_22_DIRECTION {in} \ + CONFIG.PCW_MIO_22_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_22_PULLUP {enabled} \ + CONFIG.PCW_MIO_22_SLEW {slow} \ + CONFIG.PCW_MIO_23_DIRECTION {in} \ + CONFIG.PCW_MIO_23_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_23_PULLUP {enabled} \ + CONFIG.PCW_MIO_23_SLEW {slow} \ + CONFIG.PCW_MIO_24_DIRECTION {in} \ + CONFIG.PCW_MIO_24_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_24_PULLUP {enabled} \ + CONFIG.PCW_MIO_24_SLEW {slow} \ + CONFIG.PCW_MIO_25_DIRECTION {in} \ + CONFIG.PCW_MIO_25_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_25_PULLUP {enabled} \ + CONFIG.PCW_MIO_25_SLEW {slow} \ + CONFIG.PCW_MIO_26_DIRECTION {in} \ + CONFIG.PCW_MIO_26_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_26_PULLUP {enabled} \ + CONFIG.PCW_MIO_26_SLEW {slow} \ + CONFIG.PCW_MIO_27_DIRECTION {in} \ + CONFIG.PCW_MIO_27_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_27_PULLUP {enabled} \ + CONFIG.PCW_MIO_27_SLEW {slow} \ + CONFIG.PCW_MIO_28_DIRECTION {inout} \ + CONFIG.PCW_MIO_28_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_28_PULLUP {enabled} \ + CONFIG.PCW_MIO_28_SLEW {slow} \ + CONFIG.PCW_MIO_29_DIRECTION {in} \ + CONFIG.PCW_MIO_29_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_29_PULLUP {enabled} \ + CONFIG.PCW_MIO_29_SLEW {slow} \ + CONFIG.PCW_MIO_2_DIRECTION {inout} \ + CONFIG.PCW_MIO_2_IOTYPE {LVCMOS 3.3V} \ + CONFIG.PCW_MIO_2_PULLUP {disabled} \ + CONFIG.PCW_MIO_2_SLEW {slow} \ + CONFIG.PCW_MIO_30_DIRECTION {out} \ + CONFIG.PCW_MIO_30_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_30_PULLUP {enabled} \ + CONFIG.PCW_MIO_30_SLEW {slow} \ + CONFIG.PCW_MIO_31_DIRECTION {in} \ + CONFIG.PCW_MIO_31_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_31_PULLUP {enabled} \ + CONFIG.PCW_MIO_31_SLEW {slow} \ + CONFIG.PCW_MIO_32_DIRECTION {inout} \ + CONFIG.PCW_MIO_32_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_32_PULLUP {enabled} \ + CONFIG.PCW_MIO_32_SLEW {slow} \ + CONFIG.PCW_MIO_33_DIRECTION {inout} \ + CONFIG.PCW_MIO_33_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_33_PULLUP {enabled} \ + CONFIG.PCW_MIO_33_SLEW {slow} \ + CONFIG.PCW_MIO_34_DIRECTION {inout} \ + CONFIG.PCW_MIO_34_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_34_PULLUP {enabled} \ + CONFIG.PCW_MIO_34_SLEW {slow} \ + CONFIG.PCW_MIO_35_DIRECTION {inout} \ + CONFIG.PCW_MIO_35_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_35_PULLUP {enabled} \ + CONFIG.PCW_MIO_35_SLEW {slow} \ + CONFIG.PCW_MIO_36_DIRECTION {in} \ + CONFIG.PCW_MIO_36_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_36_PULLUP {enabled} \ + CONFIG.PCW_MIO_36_SLEW {slow} \ + CONFIG.PCW_MIO_37_DIRECTION {inout} \ + CONFIG.PCW_MIO_37_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_37_PULLUP {enabled} \ + CONFIG.PCW_MIO_37_SLEW {slow} \ + CONFIG.PCW_MIO_38_DIRECTION {inout} \ + CONFIG.PCW_MIO_38_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_38_PULLUP {enabled} \ + CONFIG.PCW_MIO_38_SLEW {slow} \ + CONFIG.PCW_MIO_39_DIRECTION {inout} \ + CONFIG.PCW_MIO_39_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_39_PULLUP {enabled} \ + CONFIG.PCW_MIO_39_SLEW {slow} \ + CONFIG.PCW_MIO_3_DIRECTION {inout} \ + CONFIG.PCW_MIO_3_IOTYPE {LVCMOS 3.3V} \ + CONFIG.PCW_MIO_3_PULLUP {disabled} \ + CONFIG.PCW_MIO_3_SLEW {slow} \ + CONFIG.PCW_MIO_40_DIRECTION {inout} \ + CONFIG.PCW_MIO_40_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_40_PULLUP {enabled} \ + CONFIG.PCW_MIO_40_SLEW {slow} \ + CONFIG.PCW_MIO_41_DIRECTION {in} \ + CONFIG.PCW_MIO_41_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_41_PULLUP {enabled} \ + CONFIG.PCW_MIO_41_SLEW {slow} \ + CONFIG.PCW_MIO_42_DIRECTION {out} \ + CONFIG.PCW_MIO_42_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_42_PULLUP {enabled} \ + CONFIG.PCW_MIO_42_SLEW {slow} \ + CONFIG.PCW_MIO_43_DIRECTION {in} \ + CONFIG.PCW_MIO_43_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_43_PULLUP {enabled} \ + CONFIG.PCW_MIO_43_SLEW {slow} \ + CONFIG.PCW_MIO_44_DIRECTION {inout} \ + CONFIG.PCW_MIO_44_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_44_PULLUP {enabled} \ + CONFIG.PCW_MIO_44_SLEW {slow} \ + CONFIG.PCW_MIO_45_DIRECTION {inout} \ + CONFIG.PCW_MIO_45_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_45_PULLUP {enabled} \ + CONFIG.PCW_MIO_45_SLEW {slow} \ + CONFIG.PCW_MIO_46_DIRECTION {inout} \ + CONFIG.PCW_MIO_46_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_46_PULLUP {enabled} \ + CONFIG.PCW_MIO_46_SLEW {slow} \ + CONFIG.PCW_MIO_47_DIRECTION {inout} \ + CONFIG.PCW_MIO_47_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_47_PULLUP {enabled} \ + CONFIG.PCW_MIO_47_SLEW {slow} \ + CONFIG.PCW_MIO_48_DIRECTION {in} \ + CONFIG.PCW_MIO_48_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_48_PULLUP {enabled} \ + CONFIG.PCW_MIO_48_SLEW {slow} \ + CONFIG.PCW_MIO_49_DIRECTION {inout} \ + CONFIG.PCW_MIO_49_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_49_PULLUP {enabled} \ + CONFIG.PCW_MIO_49_SLEW {slow} \ + CONFIG.PCW_MIO_4_DIRECTION {inout} \ + CONFIG.PCW_MIO_4_IOTYPE {LVCMOS 3.3V} \ + CONFIG.PCW_MIO_4_PULLUP {disabled} \ + CONFIG.PCW_MIO_4_SLEW {slow} \ + CONFIG.PCW_MIO_50_DIRECTION {inout} \ + CONFIG.PCW_MIO_50_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_50_PULLUP {enabled} \ + CONFIG.PCW_MIO_50_SLEW {slow} \ + CONFIG.PCW_MIO_51_DIRECTION {inout} \ + CONFIG.PCW_MIO_51_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_51_PULLUP {enabled} \ + CONFIG.PCW_MIO_51_SLEW {slow} \ + CONFIG.PCW_MIO_52_DIRECTION {inout} \ + CONFIG.PCW_MIO_52_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_52_PULLUP {enabled} \ + CONFIG.PCW_MIO_52_SLEW {slow} \ + CONFIG.PCW_MIO_53_DIRECTION {inout} \ + CONFIG.PCW_MIO_53_IOTYPE {LVCMOS 1.8V} \ + CONFIG.PCW_MIO_53_PULLUP {enabled} \ + CONFIG.PCW_MIO_53_SLEW {slow} \ + CONFIG.PCW_MIO_5_DIRECTION {inout} \ + CONFIG.PCW_MIO_5_IOTYPE {LVCMOS 3.3V} \ + CONFIG.PCW_MIO_5_PULLUP {disabled} \ + CONFIG.PCW_MIO_5_SLEW {slow} \ + CONFIG.PCW_MIO_6_DIRECTION {out} \ + CONFIG.PCW_MIO_6_IOTYPE {LVCMOS 3.3V} \ + CONFIG.PCW_MIO_6_PULLUP {disabled} \ + CONFIG.PCW_MIO_6_SLEW {slow} \ + CONFIG.PCW_MIO_7_DIRECTION {out} \ + CONFIG.PCW_MIO_7_IOTYPE {LVCMOS 3.3V} \ + CONFIG.PCW_MIO_7_PULLUP {disabled} \ + CONFIG.PCW_MIO_7_SLEW {slow} \ + CONFIG.PCW_MIO_8_DIRECTION {out} \ + CONFIG.PCW_MIO_8_IOTYPE {LVCMOS 3.3V} \ + CONFIG.PCW_MIO_8_PULLUP {disabled} \ + CONFIG.PCW_MIO_8_SLEW {slow} \ + CONFIG.PCW_MIO_9_DIRECTION {in} \ + CONFIG.PCW_MIO_9_IOTYPE {LVCMOS 3.3V} \ + CONFIG.PCW_MIO_9_PULLUP {enabled} \ + CONFIG.PCW_MIO_9_SLEW {slow} \ + CONFIG.PCW_MIO_TREE_PERIPHERALS {GPIO#Quad SPI Flash#Quad SPI Flash#Quad SPI Flash#Quad SPI Flash#Quad SPI Flash#Quad SPI Flash#GPIO#UART 1#UART 1#SD 1#SD 1#SD 1#SD 1#SD 1#SD 1#Enet 0#Enet 0#Enet 0#Enet 0#Enet 0#Enet 0#Enet 0#Enet 0#Enet 0#Enet 0#Enet 0#Enet 0#USB 0#USB 0#USB 0#USB 0#USB 0#USB 0#USB 0#USB 0#USB 0#USB 0#USB 0#USB 0#USB 1#USB 1#USB 1#USB 1#USB 1#USB 1#USB 1#USB 1#USB 1#USB 1#USB 1#USB 1#GPIO#GPIO} \ + CONFIG.PCW_MIO_TREE_SIGNALS {gpio[0]#qspi0_ss_b#qspi0_io[0]#qspi0_io[1]#qspi0_io[2]#qspi0_io[3]/HOLD_B#qspi0_sclk#gpio[7]#tx#rx#data[0]#cmd#clk#data[1]#data[2]#data[3]#tx_clk#txd[0]#txd[1]#txd[2]#txd[3]#tx_ctl#rx_clk#rxd[0]#rxd[1]#rxd[2]#rxd[3]#rx_ctl#data[4]#dir#stp#nxt#data[0]#data[1]#data[2]#data[3]#clk#data[5]#data[6]#data[7]#data[4]#dir#stp#nxt#data[0]#data[1]#data[2]#data[3]#clk#data[5]#data[6]#data[7]#gpio[52]#gpio[53]} \ + CONFIG.PCW_NAND_GRP_D8_ENABLE {0} \ + CONFIG.PCW_NAND_PERIPHERAL_ENABLE {0} \ + CONFIG.PCW_NOR_GRP_A25_ENABLE {0} \ + CONFIG.PCW_NOR_GRP_CS0_ENABLE {0} \ + CONFIG.PCW_NOR_GRP_CS1_ENABLE {0} \ + CONFIG.PCW_NOR_GRP_SRAM_CS0_ENABLE {0} \ + CONFIG.PCW_NOR_GRP_SRAM_CS1_ENABLE {0} \ + CONFIG.PCW_NOR_GRP_SRAM_INT_ENABLE {0} \ + CONFIG.PCW_NOR_PERIPHERAL_ENABLE {0} \ + CONFIG.PCW_PCAP_PERIPHERAL_DIVISOR0 {5} \ + CONFIG.PCW_PRESET_BANK1_VOLTAGE {LVCMOS 1.8V} \ + CONFIG.PCW_QSPI_GRP_FBCLK_ENABLE {0} \ + CONFIG.PCW_QSPI_GRP_IO1_ENABLE {0} \ + CONFIG.PCW_QSPI_GRP_SINGLE_SS_ENABLE {1} \ + CONFIG.PCW_QSPI_GRP_SINGLE_SS_IO {MIO 1 .. 6} \ + CONFIG.PCW_QSPI_GRP_SS1_ENABLE {0} \ + CONFIG.PCW_QSPI_PERIPHERAL_DIVISOR0 {5} \ + CONFIG.PCW_QSPI_PERIPHERAL_ENABLE {1} \ + CONFIG.PCW_QSPI_PERIPHERAL_FREQMHZ {200} \ + CONFIG.PCW_QSPI_QSPI_IO {MIO 1 .. 6} \ + CONFIG.PCW_SD1_GRP_CD_ENABLE {0} \ + CONFIG.PCW_SD1_GRP_POW_ENABLE {0} \ + CONFIG.PCW_SD1_GRP_WP_ENABLE {0} \ + CONFIG.PCW_SD1_PERIPHERAL_ENABLE {1} \ + CONFIG.PCW_SD1_SD1_IO {MIO 10 .. 15} \ + CONFIG.PCW_SDIO_PERIPHERAL_DIVISOR0 {20} \ + CONFIG.PCW_SDIO_PERIPHERAL_FREQMHZ {50} \ + CONFIG.PCW_SDIO_PERIPHERAL_VALID {1} \ + CONFIG.PCW_SINGLE_QSPI_DATA_MODE {x4} \ + CONFIG.PCW_SMC_PERIPHERAL_DIVISOR0 {1} \ + CONFIG.PCW_SPI_PERIPHERAL_DIVISOR0 {1} \ + CONFIG.PCW_TPIU_PERIPHERAL_DIVISOR0 {1} \ + CONFIG.PCW_UART1_GRP_FULL_ENABLE {0} \ + CONFIG.PCW_UART1_PERIPHERAL_ENABLE {1} \ + CONFIG.PCW_UART1_UART1_IO {MIO 8 .. 9} \ + CONFIG.PCW_UART_PERIPHERAL_DIVISOR0 {10} \ + CONFIG.PCW_UART_PERIPHERAL_FREQMHZ {100} \ + CONFIG.PCW_UART_PERIPHERAL_VALID {1} \ + CONFIG.PCW_UIPARAM_ACT_DDR_FREQ_MHZ {400.000000} \ + CONFIG.PCW_UIPARAM_DDR_BANK_ADDR_COUNT {3} \ + CONFIG.PCW_UIPARAM_DDR_BOARD_DELAY0 {0.434} \ + CONFIG.PCW_UIPARAM_DDR_BOARD_DELAY1 {0.398} \ + CONFIG.PCW_UIPARAM_DDR_BOARD_DELAY2 {0.410} \ + CONFIG.PCW_UIPARAM_DDR_BOARD_DELAY3 {0.455} \ + CONFIG.PCW_UIPARAM_DDR_CL {9} \ + CONFIG.PCW_UIPARAM_DDR_COL_ADDR_COUNT {10} \ + CONFIG.PCW_UIPARAM_DDR_CWL {9} \ + CONFIG.PCW_UIPARAM_DDR_DEVICE_CAPACITY {8192 MBits} \ + CONFIG.PCW_UIPARAM_DDR_DQS_TO_CLK_DELAY_0 {0.315} \ + CONFIG.PCW_UIPARAM_DDR_DQS_TO_CLK_DELAY_1 {0.391} \ + CONFIG.PCW_UIPARAM_DDR_DQS_TO_CLK_DELAY_2 {0.374} \ + CONFIG.PCW_UIPARAM_DDR_DQS_TO_CLK_DELAY_3 {0.271} \ + CONFIG.PCW_UIPARAM_DDR_DRAM_WIDTH {32 Bits} \ + CONFIG.PCW_UIPARAM_DDR_FREQ_MHZ {400.00} \ + CONFIG.PCW_UIPARAM_DDR_PARTNO {Custom} \ + CONFIG.PCW_UIPARAM_DDR_ROW_ADDR_COUNT {15} \ + CONFIG.PCW_UIPARAM_DDR_SPEED_BIN {DDR3_1066F} \ + CONFIG.PCW_UIPARAM_DDR_T_FAW {50} \ + CONFIG.PCW_UIPARAM_DDR_T_RAS_MIN {40} \ + CONFIG.PCW_UIPARAM_DDR_T_RC {60} \ + CONFIG.PCW_UIPARAM_DDR_T_RCD {9} \ + CONFIG.PCW_UIPARAM_DDR_T_RP {9} \ + CONFIG.PCW_UIPARAM_DDR_USE_INTERNAL_VREF {1} \ + CONFIG.PCW_USB0_PERIPHERAL_ENABLE {1} \ + CONFIG.PCW_USB0_PERIPHERAL_FREQMHZ {60} \ + CONFIG.PCW_USB0_RESET_ENABLE {0} \ + CONFIG.PCW_USB0_USB0_IO {MIO 28 .. 39} \ + CONFIG.PCW_USB1_PERIPHERAL_ENABLE {1} \ + CONFIG.PCW_USB1_PERIPHERAL_FREQMHZ {60} \ + CONFIG.PCW_USB1_RESET_ENABLE {0} \ + CONFIG.PCW_USB1_USB1_IO {MIO 40 .. 51} \ + CONFIG.PCW_USB_RESET_ENABLE {1} \ + CONFIG.PCW_USB_RESET_SELECT {Share reset pin} \ + CONFIG.PCW_USE_FABRIC_INTERRUPT {1} \ + CONFIG.PCW_USE_M_AXI_GP1 {1} \ + CONFIG.PCW_USE_S_AXI_HP1 {1} \ + ] $processing_system7_0 # Create instance: processing_system7_0_axi_periph, and set properties set processing_system7_0_axi_periph [ create_bd_cell -type ip -vlnv xilinx.com:ip:axi_interconnect:2.1 processing_system7_0_axi_periph ] - set_property -dict [ list CONFIG.NUM_MI {1} ] $processing_system7_0_axi_periph + set_property -dict [ list \ + CONFIG.NUM_MI {1} \ + ] $processing_system7_0_axi_periph # Create instance: sys_concat_intc, and set properties set sys_concat_intc [ create_bd_cell -type ip -vlnv xilinx.com:ip:xlconcat:2.1 sys_concat_intc ] - set_property -dict [ list CONFIG.NUM_PORTS {16} ] $sys_concat_intc + set_property -dict [ list \ + CONFIG.NUM_PORTS {16} \ + ] $sys_concat_intc # Create interface connections connect_bd_intf_net -intf_net axi_mem_intercon_M00_AXI [get_bd_intf_pins axi_mem_intercon/M00_AXI] [get_bd_intf_pins processing_system7_0/S_AXI_HP1] @@ -235,15 +662,15 @@ CONFIG.PCW_USE_S_AXI_HP1 {1} ] $processing_system7_0 connect_bd_intf_net -intf_net processing_system7_0_axi_periph_M00_AXI [get_bd_intf_pins parallella_base_0/s_axi] [get_bd_intf_pins processing_system7_0_axi_periph/M00_AXI] # Create port connections - connect_bd_net -net Net [get_bd_ports gpio_n] [get_bd_pins parallella_base_0/gpio_n] - connect_bd_net -net Net1 [get_bd_ports gpio_p] [get_bd_pins parallella_base_0/gpio_p] - connect_bd_net -net Net2 [get_bd_ports i2c_scl] [get_bd_pins parallella_base_0/i2c_scl] - connect_bd_net -net Net3 [get_bd_ports i2c_sda] [get_bd_pins parallella_base_0/i2c_sda] connect_bd_net -net parallella_base_0_cclk_n [get_bd_ports cclk_n] [get_bd_pins parallella_base_0/cclk_n] connect_bd_net -net parallella_base_0_cclk_p [get_bd_ports cclk_p] [get_bd_pins parallella_base_0/cclk_p] connect_bd_net -net parallella_base_0_chip_resetb [get_bd_ports chip_nreset] [get_bd_pins parallella_base_0/chip_nreset] connect_bd_net -net parallella_base_0_constant_zero [get_bd_pins parallella_base_0/constant_zero] [get_bd_pins sys_concat_intc/In0] [get_bd_pins sys_concat_intc/In1] [get_bd_pins sys_concat_intc/In2] [get_bd_pins sys_concat_intc/In3] [get_bd_pins sys_concat_intc/In4] [get_bd_pins sys_concat_intc/In5] [get_bd_pins sys_concat_intc/In6] [get_bd_pins sys_concat_intc/In7] [get_bd_pins sys_concat_intc/In8] [get_bd_pins sys_concat_intc/In9] [get_bd_pins sys_concat_intc/In10] [get_bd_pins sys_concat_intc/In12] [get_bd_pins sys_concat_intc/In13] [get_bd_pins sys_concat_intc/In14] [get_bd_pins sys_concat_intc/In15] + connect_bd_net -net parallella_base_0_gpio_n [get_bd_ports gpio_n] [get_bd_pins parallella_base_0/gpio_n] + connect_bd_net -net parallella_base_0_gpio_p [get_bd_ports gpio_p] [get_bd_pins parallella_base_0/gpio_p] + connect_bd_net -net parallella_base_0_i2c_scl [get_bd_ports i2c_scl] [get_bd_pins parallella_base_0/i2c_scl] connect_bd_net -net parallella_base_0_i2c_scl_i [get_bd_pins parallella_base_0/i2c_scl_i] [get_bd_pins processing_system7_0/I2C0_SCL_I] + connect_bd_net -net parallella_base_0_i2c_sda [get_bd_ports i2c_sda] [get_bd_pins parallella_base_0/i2c_sda] connect_bd_net -net parallella_base_0_i2c_sda_i [get_bd_pins parallella_base_0/i2c_sda_i] [get_bd_pins processing_system7_0/I2C0_SDA_I] connect_bd_net -net parallella_base_0_mailbox_irq [get_bd_pins parallella_base_0/mailbox_irq] [get_bd_pins sys_concat_intc/In11] connect_bd_net -net parallella_base_0_ps_gpio_i [get_bd_pins parallella_base_0/ps_gpio_i] [get_bd_pins processing_system7_0/GPIO_I] @@ -280,9 +707,9 @@ CONFIG.PCW_USE_S_AXI_HP1 {1} ] $processing_system7_0 connect_bd_net -net txi_wr_wait_p_1 [get_bd_ports txi_wr_wait_p] [get_bd_pins parallella_base_0/txi_wr_wait_p] # Create address segments - create_bd_addr_seg -range 0x40000000 -offset 0x0 [get_bd_addr_spaces parallella_base_0/m_axi] [get_bd_addr_segs processing_system7_0/S_AXI_HP1/HP1_DDR_LOWOCM] SEG_processing_system7_0_HP1_DDR_LOWOCM + create_bd_addr_seg -range 0x40000000 -offset 0x00000000 [get_bd_addr_spaces parallella_base_0/m_axi] [get_bd_addr_segs processing_system7_0/S_AXI_HP1/HP1_DDR_LOWOCM] SEG_processing_system7_0_HP1_DDR_LOWOCM create_bd_addr_seg -range 0x40000000 -offset 0x80000000 [get_bd_addr_spaces processing_system7_0/Data] [get_bd_addr_segs parallella_base_0/s_axi/axi_lite] SEG_parallella_base_0_axi_lite - + # Restore current instance current_bd_instance $oldCurInst diff --git a/src/parallella/fpga/headless_e16_z7020/system_params.tcl b/src/parallella/fpga/headless_e16_z7020/system_params.tcl index 8505cd15..bd03e868 100644 --- a/src/parallella/fpga/headless_e16_z7020/system_params.tcl +++ b/src/parallella/fpga/headless_e16_z7020/system_params.tcl @@ -25,4 +25,4 @@ set constraints_files [list \ ########################################################### # PREPARE FOR SYNTHESIS ########################################################### -set oh_synthesis_options "-verilog_define CFG_ASIC=0" +set oh_verilog_define "CFG_ASIC=0 CFG_PLATFORM=\"ZYNQ\"" diff --git a/src/parallella/fpga/parallella_base/Makefile b/src/parallella/fpga/parallella_base/Makefile index 3a5f15f7..5aa42dfc 100644 --- a/src/parallella/fpga/parallella_base/Makefile +++ b/src/parallella/fpga/parallella_base/Makefile @@ -13,6 +13,13 @@ M_FLIST += *.runs M_FLIST += *.srcs M_FLIST += *.sdk M_FLIST += .Xil +M_FLIST += component.xml +M_FLIST += ip_tmp +M_FLIST += parallella_base.hw +M_FLIST += parallella_base.ip_user_files +M_FLIST += parallella_base.zip +M_FLIST += sim +M_FLIST += src all: $(M_DEPS) $(M_VIVADO) run.tcl diff --git a/src/parallella/fpga/parallella_io.xdc b/src/parallella/fpga/parallella_io.xdc index f66a7ec0..5b9cb475 100644 --- a/src/parallella/fpga/parallella_io.xdc +++ b/src/parallella/fpga/parallella_io.xdc @@ -9,22 +9,22 @@ set_property CONFIG_VOLTAGE 3.3 [current_design] ####################### #TODO: Include for hdmi design set_property IOSTANDARD LVCMOS25 [get_ports {hdmi_*}] -set_property PACKAGE_PIN Y18 [get_ports {hdmi_d[8]}] -set_property PACKAGE_PIN W18 [get_ports {hdmi_d[9]}] -set_property PACKAGE_PIN V18 [get_ports {hdmi_d[10]}] -set_property PACKAGE_PIN V15 [get_ports {hdmi_d[11]}] -set_property PACKAGE_PIN R18 [get_ports {hdmi_d[12]}] -set_property PACKAGE_PIN P18 [get_ports {hdmi_d[13]}] -set_property PACKAGE_PIN Y19 [get_ports {hdmi_d[14]}] -set_property PACKAGE_PIN W19 [get_ports {hdmi_d[15]}] -set_property PACKAGE_PIN W15 [get_ports {hdmi_d[16]}] -set_property PACKAGE_PIN T19 [get_ports {hdmi_d[17]}] -set_property PACKAGE_PIN R19 [get_ports {hdmi_d[18]}] -set_property PACKAGE_PIN P19 [get_ports {hdmi_d[19]}] -set_property PACKAGE_PIN W20 [get_ports {hdmi_d[20]}] -set_property PACKAGE_PIN V20 [get_ports {hdmi_d[21]}] -set_property PACKAGE_PIN U20 [get_ports {hdmi_d[22]}] -set_property PACKAGE_PIN T20 [get_ports {hdmi_d[23]}] +set_property PACKAGE_PIN Y18 [get_ports {hdmi_d[0]}] +set_property PACKAGE_PIN W18 [get_ports {hdmi_d[1]}] +set_property PACKAGE_PIN V18 [get_ports {hdmi_d[2]}] +set_property PACKAGE_PIN V15 [get_ports {hdmi_d[3]}] +set_property PACKAGE_PIN R18 [get_ports {hdmi_d[4]}] +set_property PACKAGE_PIN P18 [get_ports {hdmi_d[5]}] +set_property PACKAGE_PIN Y19 [get_ports {hdmi_d[6]}] +set_property PACKAGE_PIN W19 [get_ports {hdmi_d[7]}] +set_property PACKAGE_PIN W15 [get_ports {hdmi_d[8]}] +set_property PACKAGE_PIN T19 [get_ports {hdmi_d[9]}] +set_property PACKAGE_PIN R19 [get_ports {hdmi_d[10]}] +set_property PACKAGE_PIN P19 [get_ports {hdmi_d[11]}] +set_property PACKAGE_PIN W20 [get_ports {hdmi_d[12]}] +set_property PACKAGE_PIN V20 [get_ports {hdmi_d[13]}] +set_property PACKAGE_PIN U20 [get_ports {hdmi_d[14]}] +set_property PACKAGE_PIN T20 [get_ports {hdmi_d[15]}] set_property PACKAGE_PIN R17 [get_ports hdmi_clk] set_property PACKAGE_PIN V17 [get_ports hdmi_vsync] set_property PACKAGE_PIN T17 [get_ports hdmi_hsync] diff --git a/src/parallella/fpga/parallella_timing.xdc b/src/parallella/fpga/parallella_timing.xdc index 7e84cb5f..a2450dcd 100644 --- a/src/parallella/fpga/parallella_timing.xdc +++ b/src/parallella/fpga/parallella_timing.xdc @@ -1,4 +1,2 @@ -create_clock -period 3.33333333 -name rxi_lclk_p -waveform {0.000 1.66666667} [get_ports rxi_lclk_p] - - +create_clock -period 3.333 -name rxi_lclk_p -waveform {0.000 1.667} [get_ports rxi_lclk_p] diff --git a/src/xilibs/ip/fifo_async_104x32.xci b/src/xilibs/ip/fifo_async_104x32.xci index b2e4cc53..c146c789 100644 --- a/src/xilibs/ip/fifo_async_104x32.xci +++ b/src/xilibs/ip/fifo_async_104x32.xci @@ -1,428 +1,536 @@ - - xilinx.com - xci - unknown - 1.0 - - - fifo_async_104x32 - - - 100000000 - 100000000 - 100000000 - 100000000 - 100000000 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 8 - 1 - 1 - 1 - 1 - 4 - 0 - 32 - 1 - 1 - 1 - 64 - 1 - 8 - 1 - 1 - 1 - 1 - 0 - 0 - 5 - BlankString - 104 - 1 - 32 - 64 - 1 - 64 - 2 - 0 - 104 - 0 - 1 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - zynquplus - 0 - 0 - 0 - 1 - 0 - 0 - 0 - 0 - 1 - 0 - 1 - 0 - 0 - 0 - 0 - 1 - 0 - 1 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 1 - 0 - 1 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 2 - 1 - 1 - 1 - 1 - 1 - 1 - 0 - 0 - 2 - BlankString - 1 - 0 - 0 - 0 - 1 - 0 - 512x72 - 1kx18 - 512x36 - 512x72 - 512x36 - 512x72 - 512x36 - 2 - 1022 - 1022 - 1022 - 1022 - 1022 - 1022 - 3 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 16 - 1023 - 1023 - 1023 - 1023 - 1023 - 1023 - 15 - 1 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 5 - 32 - 1 - 5 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 2 - 0 - 0 - 0 - 0 - 1 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 5 - 32 - 1024 - 16 - 1024 - 16 - 1024 - 16 - 1 - 5 - 10 - 4 - 10 - 4 - 10 - 4 - 1 - 32 - 0 - 0 - false - false - false - 0 - 0 - Slave_Interface_Clock_Enable - Common_Clock - fifo_async_104x32 - 64 - false - 5 - false - false - 0 - 2 - 1022 - 1022 - 1022 - 1022 - 1022 - 1022 - 3 - false - false - false - false - false - false - false - false - false - Hard_ECC - false - false - false - false - false - false - true - false - false - true - Data_FIFO - Data_FIFO - Data_FIFO - Data_FIFO - Data_FIFO - Data_FIFO - Common_Clock_Block_RAM - Common_Clock_Block_RAM - Common_Clock_Block_RAM - Common_Clock_Block_RAM - Common_Clock_Block_RAM - Common_Clock_Block_RAM - Independent_Clocks_Distributed_RAM - 0 - 16 - 1023 - 1023 - 1023 - 1023 - 1023 - 1023 - 15 - false - false - false - 0 - Native - false - false - false - false - false - false - false - false - false - false - false - false - false - false - 104 - 32 - 1024 - 16 - 1024 - 16 - 1024 - 16 - false - 104 - 32 - Embedded_Reg - false - false - Active_High - Active_High - AXI4 - Standard_FIFO - No_Programmable_Empty_Threshold - No_Programmable_Empty_Threshold - No_Programmable_Empty_Threshold - No_Programmable_Empty_Threshold - No_Programmable_Empty_Threshold - No_Programmable_Empty_Threshold - No_Programmable_Empty_Threshold - Single_Programmable_Full_Threshold_Constant - No_Programmable_Full_Threshold - No_Programmable_Full_Threshold - No_Programmable_Full_Threshold - No_Programmable_Full_Threshold - No_Programmable_Full_Threshold - No_Programmable_Full_Threshold - READ_WRITE - 0 - 1 - true - 5 - Fully_Registered - Fully_Registered - Fully_Registered - Fully_Registered - Fully_Registered - Fully_Registered - true - Asynchronous_Reset - false - 1 - 0 - 0 - 1 - 1 - 4 - false - false - Active_High - Active_High - true - false - false - false - false - Active_High - 0 - false - Active_High - 1 - false - 5 - false - FIFO - false - false - false - false - FIFO - FIFO - 2 - 2 - false - FIFO - FIFO - FIFO - zynquplus - - xczu9eg - ffvb1156 - VERILOG - es2 - MIXED - -2 - I - TRUE - TRUE - IP_Flow - 3 - TRUE - . - - . - 2016.4 - OUT_OF_CONTEXT - - - - - - - - - - - - - + + xilinx.com + xci + unknown + 1.0 + + + fifo_async_104x32 + + + + + + 100000000 + 0.000 + + + 100000000 + 0.000 + 1 + 0 + 0 + 0 + + 1 + 100000000 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 1 + 1 + 1 + 1 + 0.000 + AXI4LITE + READ_WRITE + 0 + 0 + 0 + 0 + 0 + + 100000000 + 0 + 0 + 0 + 0 + undef + 0.000 + 0 + 0 + 0 + 0 + + + + 100000000 + 0.000 + + 100000000 + 0.000 + 1 + 0 + 0 + 0 + + 1 + 100000000 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 1 + 1 + 1 + 1 + 0.000 + AXI4LITE + READ_WRITE + 0 + 0 + 0 + 0 + 0 + + 100000000 + 0 + 0 + 0 + 0 + undef + 0.000 + 0 + 0 + 0 + 0 + + + + 100000000 + 0.000 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 8 + 1 + 1 + 1 + 1 + 4 + 0 + 32 + 1 + 1 + 1 + 64 + 1 + 8 + 1 + 1 + 1 + 1 + 0 + 0 + 5 + BlankString + 104 + 1 + 32 + 64 + 1 + 64 + 2 + 0 + 104 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + zynq + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 1 + 0 + 1 + 0 + 0 + 0 + 0 + 1 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 2 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + 2 + BlankString + 1 + 0 + 0 + 0 + 1 + 0 + 512x72 + 1kx18 + 512x36 + 1kx36 + 512x36 + 1kx36 + 512x36 + 2 + 1022 + 1022 + 1022 + 1022 + 1022 + 1022 + 3 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 16 + 1023 + 1023 + 1023 + 1023 + 1023 + 1023 + 15 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 5 + 32 + 1 + 5 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 2 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 5 + 32 + 1024 + 16 + 1024 + 16 + 1024 + 16 + 1 + 5 + 10 + 4 + 10 + 4 + 10 + 4 + 1 + 32 + 0 + 0 + false + false + false + 0 + 0 + Slave_Interface_Clock_Enable + Common_Clock + fifo_async_104x32 + 64 + false + 5 + false + false + 0 + 2 + 1022 + 1022 + 1022 + 1022 + 1022 + 1022 + 3 + false + false + false + false + false + false + false + false + false + Hard_ECC + false + false + false + false + false + false + true + false + false + true + Data_FIFO + Data_FIFO + Data_FIFO + Data_FIFO + Data_FIFO + Data_FIFO + Common_Clock_Block_RAM + Common_Clock_Block_RAM + Common_Clock_Block_RAM + Common_Clock_Block_RAM + Common_Clock_Block_RAM + Common_Clock_Block_RAM + Independent_Clocks_Distributed_RAM + 0 + 16 + 1023 + 1023 + 1023 + 1023 + 1023 + 1023 + 15 + false + false + false + 0 + Native + false + false + false + false + false + false + false + false + false + false + false + false + false + false + 104 + 32 + 1024 + 16 + 1024 + 16 + 1024 + 16 + false + 104 + 32 + Embedded_Reg + false + false + Active_High + Active_High + AXI4 + Standard_FIFO + No_Programmable_Empty_Threshold + No_Programmable_Empty_Threshold + No_Programmable_Empty_Threshold + No_Programmable_Empty_Threshold + No_Programmable_Empty_Threshold + No_Programmable_Empty_Threshold + No_Programmable_Empty_Threshold + Single_Programmable_Full_Threshold_Constant + No_Programmable_Full_Threshold + No_Programmable_Full_Threshold + No_Programmable_Full_Threshold + No_Programmable_Full_Threshold + No_Programmable_Full_Threshold + No_Programmable_Full_Threshold + READ_WRITE + 0 + 1 + true + 5 + Fully_Registered + Fully_Registered + Fully_Registered + Fully_Registered + Fully_Registered + Fully_Registered + true + Asynchronous_Reset + false + 1 + 0 + 0 + 1 + 1 + 4 + false + false + Active_High + Active_High + true + false + false + false + false + Active_High + 0 + false + Active_High + 1 + false + 5 + false + FIFO + false + false + false + false + FIFO + FIFO + 2 + 2 + false + FIFO + FIFO + FIFO + zynq + + xc7z020 + clg400 + VERILOG + + MIXED + -1 + + TRUE + TRUE + IP_Flow + 2 + TRUE + . + + . + 2018.2.2 + GLOBAL + + + + + + + + + + + + + + + + + + + + + + + + + + + + +