diff --git a/.cvsignore b/.cvsignore new file mode 100644 index 00000000..4852975a --- /dev/null +++ b/.cvsignore @@ -0,0 +1,32 @@ +*.dep_ghdl +*.dep_isim +*.dep_xst +work-obj93.cf +*.vcd +*.ghw +*.sav +*.tmp +*.exe +ise +xflow.his +*.ngc +*.ncd +*.pcf +*.bit +*.msk +isim +isim.log +isim.wdb +fuse.log +*_[sft]sim.vhd +*_tsim.sdf +*_xst.log +*_tra.log +*_twr.log +*_map.log +*_par.log +*_pad.log +*_bgn.log +*_svn.log +*_sum.log +*_[dsft]sim.log diff --git a/COPYING.txt b/COPYING.txt new file mode 100644 index 00000000..bfaac45e --- /dev/null +++ b/COPYING.txt @@ -0,0 +1,16 @@ +This package is released under the GPL V2 or higher, all files +contain the disclaimer: + + This program is free software; you may redistribute 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 complete details. + +The full text of the GPL licenses is in this directory as + LICENSE_gpl_v2.txt + LICENSE_gpl_v3.txt diff --git a/LICENSE_gpl_v2.txt b/LICENSE_gpl_v2.txt new file mode 100644 index 00000000..d511905c --- /dev/null +++ b/LICENSE_gpl_v2.txt @@ -0,0 +1,339 @@ + 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. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + 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. + + + Copyright (C) + + 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. + + , 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/LICENSE_gpl_v3.txt b/LICENSE_gpl_v3.txt new file mode 100644 index 00000000..94a9ed02 --- /dev/null +++ b/LICENSE_gpl_v3.txt @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/rtl/bplib/issi/Makefile b/rtl/bplib/issi/Makefile new file mode 100644 index 00000000..a2ab5e30 --- /dev/null +++ b/rtl/bplib/issi/Makefile @@ -0,0 +1,19 @@ +# $Id: Makefile 311 2010-06-30 17:52:37Z mueller $ +# +# Revision History: +# Date Rev Version Comment +# 2007-12-14 101 1.0 Initial version +# +# +.phony : clean +# +clean : ghdl_clean +# +#----- +# +include $(RETROBASE)/rtl/vlib/Makefile.ghdl +# +VBOM_all = $(wildcard *.vbom) +# +include $(VBOM_all:.vbom=.dep_ghdl) +# diff --git a/rtl/bplib/issi/is61lv25616al.vbom b/rtl/bplib/issi/is61lv25616al.vbom new file mode 100644 index 00000000..f7937e51 --- /dev/null +++ b/rtl/bplib/issi/is61lv25616al.vbom @@ -0,0 +1,5 @@ +# libs +../../vlib/slvtypes.vhd +# components +# design +is61lv25616al.vhd diff --git a/rtl/bplib/issi/is61lv25616al.vhd b/rtl/bplib/issi/is61lv25616al.vhd new file mode 100644 index 00000000..6e2410a4 --- /dev/null +++ b/rtl/bplib/issi/is61lv25616al.vhd @@ -0,0 +1,169 @@ +-- $Id: is61lv25616al.vhd 314 2010-07-09 17:38:41Z mueller $ +-- +-- Copyright 2007-2008 by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, 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 complete details. +-- +------------------------------------------------------------------------------ +-- Module Name: is61lv25616al - sim +-- Description: ISSI 61LV25612AL SRAM model +-- Currently a truely minimalistic functional model, without +-- any timing checks. It assumes, that addr/data is stable at +-- the trailing edge of we. +-- +-- Dependencies: - +-- Test bench: - +-- Target Devices: generic +-- Tool versions: xst 8.1, 8.2, 9.1, 9.2; ghdl 0.18-0.25 +-- Revision History: +-- Date Rev Version Comment +-- 2008-05-12 145 1.0.1 BUGFIX: Output now 'Z' if byte enables deasserted +-- 2007-12-14 101 1.0 Initial version (written on warsaw airport) +------------------------------------------------------------------------------ +-- Truth table accoring to data sheet: +-- +-- Mode WE_N CE_N OE_N LB_N UB_N D(7:0) D(15:8) +-- Not selected X H X X X high-Z high-Z +-- Output disabled H L H X X high-Z high-Z +-- X L X H H high-Z high-Z +-- Read H L L L H D_out high-Z +-- H L L H L high-Z D_out +-- H L L L L D_out D_out +-- Write L L X L H D_in high-Z +-- L L X H L high-Z D_in +-- L L X L L D_in D_in + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; + +use work.slvtypes.all; + +entity is61lv25616al is -- ISSI 61LV25612AL SRAM model + port ( + CE_N : in slbit; -- chip enable (act.low) + OE_N : in slbit; -- output enable (act.low) + WE_N : in slbit; -- write enable (act.low) + UB_N : in slbit; -- upper byte enable (act.low) + LB_N : in slbit; -- lower byte enable (act.low) + ADDR : in slv18; -- address lines + DATA : inout slv16 -- data lines + ); +end is61lv25616al; + + +architecture sim of is61lv25616al is + + signal CE : slbit := '0'; + signal OE : slbit := '0'; + signal WE : slbit := '0'; + signal BE_L : slbit := '0'; + signal BE_U : slbit := '0'; + + component is61lv25616al_bank is -- ISSI 61LV25612AL bank + port ( + CE : in slbit; -- chip enable (act.high) + OE : in slbit; -- output enable (act.high) + WE : in slbit; -- write enable (act.high) + BE : in slbit; -- byte enable (act.high) + ADDR : in slv18; -- address lines + DATA : inout slv8 -- data lines + ); + end component; + +begin + + CE <= not CE_N; + OE <= not OE_N; + WE <= not WE_N; + BE_L <= not LB_N; + BE_U <= not UB_N; + + BANK_L : is61lv25616al_bank port map ( + CE => CE, + OE => OE, + WE => WE, + BE => BE_L, + ADDR => ADDR, + DATA => DATA(7 downto 0)); + + BANK_U : is61lv25616al_bank port map ( + CE => CE, + OE => OE, + WE => WE, + BE => BE_U, + ADDR => ADDR, + DATA => DATA(15 downto 8)); + +end sim; + +-- ---------------------------------------------------------------------------- + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; + +use work.slvtypes.all; + +entity is61lv25616al_bank is -- ISSI 61LV25612AL bank + port ( + CE : in slbit; -- chip enable (act.high) + OE : in slbit; -- output enable (act.high) + WE : in slbit; -- write enable (act.high) + BE : in slbit; -- byte enable (act.high) + ADDR : in slv18; -- address lines + DATA : inout slv8 -- data lines + ); +end is61lv25616al_bank; + +architecture sim of is61lv25616al_bank is + + constant T_rc : time := 10 ns; -- read cycle time (min) + constant T_aa : time := 10 ns; -- address access time (max) + constant T_oha : time := 2 ns; -- output hold time (min) + constant T_ace : time := 10 ns; -- ce access time (max) + constant T_doe : time := 4 ns; -- oe access time (max) + constant T_hzoe : time := 4 ns; -- oe to high-Z output (max) + constant T_lzoe : time := 0 ns; -- oe to low-Z output (min) + constant T_hzce : time := 4 ns; -- ce to high-Z output (min=0,max=4) + constant T_lzce : time := 3 ns; -- ce to low-Z output (min) + constant T_ba : time := 4 ns; -- lb,ub access time (max) + constant T_hzb : time := 3 ns; -- lb,ub to high-Z output (min=0,max=3) + constant T_lzb : time := 0 ns; -- lb,ub low-Z output (min) + + constant memsize : positive := 2**(ADDR'length); + constant datzero : slv(DATA'range) := (others=>'0'); + type ram_type is array (0 to memsize-1) of slv(DATA'range); + + signal WE_EFF : slbit := '0'; + +begin + + WE_EFF <= CE and WE and BE; + + proc_sram: process (CE, OE, WE, BE, WE_EFF, ADDR, DATA) + variable ram : ram_type := (others=>datzero); + begin + + if WE_EFF'event and WE_EFF='0' then -- end of write cycle + -- note: to_x01 used below to prevent + -- that 'z' a written into mem. + ram(conv_integer(unsigned(ADDR))) := to_x01(DATA); + end if; + + if CE='1' and OE='1' and BE='1' and WE='0' then -- output driver + DATA <= ram(conv_integer(unsigned(ADDR))); + else + DATA <= (others=>'Z'); + end if; + + end process proc_sram; + +end sim; diff --git a/rtl/bplib/micron/mt45w8mw16b.vbom b/rtl/bplib/micron/mt45w8mw16b.vbom new file mode 100644 index 00000000..9e8e76b5 --- /dev/null +++ b/rtl/bplib/micron/mt45w8mw16b.vbom @@ -0,0 +1,5 @@ +# libs +../../vlib/slvtypes.vhd +# components +# design +mt45w8mw16b.vhd diff --git a/rtl/bplib/micron/mt45w8mw16b.vhd b/rtl/bplib/micron/mt45w8mw16b.vhd new file mode 100644 index 00000000..3d86fa8a --- /dev/null +++ b/rtl/bplib/micron/mt45w8mw16b.vhd @@ -0,0 +1,242 @@ +-- $Id: mt45w8mw16b.vhd 314 2010-07-09 17:38:41Z mueller $ +-- +-- Copyright 2010- by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, 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 complete details. +-- +------------------------------------------------------------------------------ +-- Module Name: mt45w8mw16b - sim +-- Description: Micron MT45W8MW16B CellularRAM model +-- Currently a much simplified model +-- - only async accesses +-- - ignores CLK and CRE +-- - simple model for response of DATA lines, but no +-- check for timing violations of control lines +-- +-- Dependencies: - +-- Test bench: - +-- Target Devices: generic +-- Tool versions: xst 11.4; ghdl 0.26 +-- Revision History: +-- Date Rev Version Comment +-- 2010-06-03 299 1.3.1 improved timing model (WE cycle, robust T_apa) +-- 2010-06-03 298 1.3 add timing model again +-- 2010-05-28 295 1.2 drop timing (was incorrect), pure functional now +-- 2010-05-21 293 1.1 add BCR (only read of default so far) +-- 2010-05-16 291 1.0 Initial version (inspired by is61lv25616al) +------------------------------------------------------------------------------ +-- Truth table accoring to data sheet: +-- +-- Asynchronous Mode (BCR(15)=1) +-- Operation CLK ADV_N CE_N OE_N WE_N CRE xB_N WT DATA +-- Read L L L L H L L act data-out +-- Write L L L X L L L act data-in +-- Standby L X H X X L X 'z' 'z' +-- CRE write L L L H L H X act 'z' +-- CRE read L L L L H H L act conf-out +-- +-- Burst Mode (BCR(15)=0) +-- Operation CLK ADV_N CE_N OE_N WE_N CRE xB_N WT DATA +-- Async read L L L L H L L act data-out +-- Async write L L L X L L L act data-in +-- Standby L X H X X L X 'z' 'z' +-- Initial burst read 0-1 L L X H L L act X +-- Initial burst write 0-1 L L H L L X act X +-- Burst continue 0-1 H L X X X X act data-in/out +-- CRE write 0-1 L L H L H X act 'z' +-- CRE read 0-1 L L L H H L act conf-out +-- + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; + +use work.slvtypes.all; + +entity mt45w8mw16b is -- Micron MT45W8MW16B CellularRAM model + port ( + CLK : in slbit; -- clock for synchonous operation + CE_N : in slbit; -- chip enable (act.low) + OE_N : in slbit; -- output enable (act.low) + WE_N : in slbit; -- write enable (act.low) + UB_N : in slbit; -- upper byte enable (act.low) + LB_N : in slbit; -- lower byte enable (act.low) + ADV_N : in slbit; -- address valid (act.low) + CRE : in slbit; -- control register enable + MWAIT : out slbit; -- wait (for burst read/write) + ADDR : in slv23; -- address lines + DATA : inout slv16 -- data lines + ); +end mt45w8mw16b; + + +architecture sim of mt45w8mw16b is + + -- timing constants for -701 speed grade (70 ns; 104 MHz) + constant T_aa : time := 70 ns; -- address access time (max) + constant T_apa : time := 20 ns; -- page acess time (max) + constant T_oh : time := 5 ns; -- output hold from addr change (max) + constant T_oe : time := 20 ns; -- output enable to valid output (max) + constant T_ohz : time := 8 ns; -- output disable to high-z output (max) + constant T_olz : time := 3 ns; -- output enable to low-z output (min) + constant T_lz : time := 10 ns; -- chip enable to low-z output (min) + constant T_hz : time := 8 ns; -- chip disable to high-z output (max) + + constant memsize : positive := 2**(ADDR'length); + constant datzero : slv(DATA'range) := (others=>'0'); + type ram_type is array (0 to memsize-1) of slv(DATA'range); + + constant bcr_f_mode : integer := 15; -- operating mode + constant bcr_f_ilat : integer := 14; -- initial latency + subtype bcr_f_lc is integer range 13 downto 11; -- latency counter + constant bcr_f_wp : integer := 10; -- wait polarity + constant bcr_f_wc : integer := 8; -- wait configuration + subtype bcr_f_drive is integer range 5 downto 4; -- drive strength + constant bcr_f_bw : integer := 3; -- burst wrap + subtype bcr_f_bl is integer range 2 downto 0; -- burst length + + subtype f_byte1 is integer range 15 downto 8; + subtype f_byte0 is integer range 7 downto 0; + + signal CE : slbit := '0'; + signal OE : slbit := '0'; + signal WE : slbit := '0'; + signal BE_L : slbit := '0'; + signal BE_U : slbit := '0'; + signal ADV : slbit := '0'; + signal WE_L_EFF : slbit := '0'; + signal WE_U_EFF : slbit := '0'; + + signal R_BCR_MODE : slbit := '1'; -- mode: def: async + signal R_BCR_ILAT : slbit := '0'; -- ilat: def: variable + signal R_BCR_LC : slv3 := "011"; -- lc: def: code 3 + signal R_BCR_WP : slbit := '1'; -- wp: def: active high + signal R_BCR_WC : slbit := '1'; -- wc: def: assert one before + signal R_BCR_DRIVE : slv2 := "01"; -- drive:def: 1/2 + signal R_BCR_BW : slbit := '1'; -- bw: def: no wrap + signal R_BCR_BL : slv3 := "111"; -- bl: def: continuous + + signal L_ADDR : slv23 := (others=>'0'); + signal DOUT_VAL_EN : slbit := '0'; + signal DOUT_VAL_AA : slbit := '0'; + signal DOUT_VAL_PA : slbit := '0'; + signal DOUT_VAL_OE : slbit := '0'; + signal DOUT_LZ_CE : slbit := '0'; + signal DOUT_LZ_OE : slbit := '0'; + + signal OEWE : slbit := '0'; + signal DOUT : slv16 := (others=>'0'); +begin + + CE <= not CE_N; + OE <= not OE_N; + WE <= not WE_N; + BE_L <= not LB_N; + BE_U <= not UB_N; + ADV <= not ADV_N; + + WE_L_EFF <= CE and WE and BE_L; + WE_U_EFF <= CE and WE and BE_U; + + -- address valid logic, latch ADDR when ADV true + proc_adv: process (ADV, ADDR) + begin + if ADV = '1' then + L_ADDR <= ADDR; + end if; + end process proc_adv; + + proc_dout_val: process (CE, OE, WE, BE_L, BE_U, ADV, L_ADDR) + variable addr_last : slv23 := (others=>'1'); + begin + if (CE'event and CE='1') or + (BE_L'event and BE_L='1') or + (BE_U'event and BE_U='1') or + (WE'event and WE='0') or + (ADV'event and ADV='1') then + DOUT_VAL_EN <= '0', '1' after T_aa; + end if; + if L_ADDR'event then + DOUT_VAL_PA <= '0', '1' after T_apa; + if L_ADDR(22 downto 4) /= addr_last(22 downto 4) then + DOUT_VAL_AA <= '0', '1' after T_aa; + end if; + addr_last := L_ADDR; + end if; + if OE'event and OE='1' then + DOUT_VAL_OE <= '0', '1' after T_oe; + end if; + end process proc_dout_val; + + -- to simplify things assume that OE and (not WE) have same effect on output + -- drivers. The timing rules are very similar indeed... + OEWE <= OE and (not WE); + + proc_dout_lz: process (CE, OEWE) + begin + if (CE'event) then + if CE = '1' then + DOUT_LZ_CE <= '1' after T_lz; + else + DOUT_LZ_CE <= '0' after T_hz; + end if; + end if; + if (OEwe'event) then + if OEWE = '1' then + DOUT_LZ_OE <= '1' after T_olz; + else + DOUT_LZ_OE <= '0' after T_ohz; + end if; + end if; + end process proc_dout_lz; + + proc_cram: process (CE, OE, WE, WE_L_EFF, WE_U_EFF, L_ADDR, DATA) + variable ram : ram_type := (others=>datzero); + begin + + -- end of write cycle + -- note: to_x01 used below to prevent that 'z' a written into mem. + if WE_L_EFF'event and WE_L_EFF='0' then + ram(conv_integer(unsigned(L_ADDR)))(f_byte0) := to_x01(DATA(f_byte0)); + end if; + if WE_U_EFF'event and WE_U_EFF='0' then + ram(conv_integer(unsigned(L_ADDR)))(f_byte1) := to_x01(DATA(f_byte1)); + end if; + + DOUT <= ram(conv_integer(unsigned(L_ADDR))); + + end process proc_cram; + + proc_data: process (DOUT, DOUT_VAL_EN, DOUT_VAL_AA, DOUT_VAL_PA, DOUT_VAL_OE, + DOUT_LZ_CE, DOUT_LZ_OE) + variable idout : slv16 := (others=>'0'); + begin + idout := DOUT; + if DOUT_VAL_EN='0' or DOUT_VAL_AA='0' or + DOUT_VAL_PA='0' or DOUT_VAL_OE='0' then + idout := (others=>'X'); + end if; + if DOUT_LZ_CE='0' or DOUT_LZ_OE='0' then + idout := (others=>'Z'); + end if; + DATA <= idout; + end process proc_data; + + proc_mwait: process (CE) + begin + -- WT driver (just a dummy) + if CE = '1' then + MWAIT <= '1'; + else + MWAIT <= 'Z'; + end if; + end process proc_mwait; + +end sim; diff --git a/rtl/bplib/nexys2/Makefile b/rtl/bplib/nexys2/Makefile new file mode 100644 index 00000000..b28f3edd --- /dev/null +++ b/rtl/bplib/nexys2/Makefile @@ -0,0 +1,23 @@ +# $Id: Makefile 311 2010-06-30 17:52:37Z mueller $ +# +# Revision History: +# Date Rev Version Comment +# 2010-05-23 293 1.0 Initial version (cloned..) +# +VBOM_all = $(wildcard *.vbom) +NGC_all = $(VBOM_all:.vbom=.ngc) +# +ISE_PATH = xc3s1200e-fg320-4 +# +.phony : all clean +# +all : $(NGC_all) +# +clean : ise_clean +# +#---- +# +include $(RETROBASE)/rtl/vlib/Makefile.xflow +# +include $(VBOM_all:.vbom=.dep_xst) +# diff --git a/rtl/bplib/nexys2/n2_cram_dummy.vbom b/rtl/bplib/nexys2/n2_cram_dummy.vbom new file mode 100644 index 00000000..23afa298 --- /dev/null +++ b/rtl/bplib/nexys2/n2_cram_dummy.vbom @@ -0,0 +1,5 @@ +# libs +../../vlib/slvtypes.vhd +# components +# design +n2_cram_dummy.vhd diff --git a/rtl/bplib/nexys2/n2_cram_dummy.vhd b/rtl/bplib/nexys2/n2_cram_dummy.vhd new file mode 100644 index 00000000..140c7211 --- /dev/null +++ b/rtl/bplib/nexys2/n2_cram_dummy.vhd @@ -0,0 +1,65 @@ +-- $Id: n2_cram_dummy.vhd 314 2010-07-09 17:38:41Z mueller $ +-- +-- Copyright 2010- by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, 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 complete details. +-- +------------------------------------------------------------------------------ +-- Module Name: n2_cram_dummy - syn +-- Description: nexys2: CRAM protection dummy +-- +-- Dependencies: - +-- Test bench: - +-- Target Devices: generic +-- Tool versions: xst 11.4; ghdl 0.26 +-- Revision History: +-- Date Rev Version Comment +-- 2010-05-28 295 1.0.1 use _ADV_N +-- 2010-05-21 292 1.0 Initial version +------------------------------------------------------------------------------ + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; + +use work.slvtypes.all; + +entity n2_cram_dummy is -- CRAM protection dummy + port ( + O_MEM_CE_N : out slbit; -- cram: chip enable (act.low) + O_MEM_BE_N : out slv2; -- cram: byte enables (act.low) + O_MEM_WE_N : out slbit; -- cram: write enable (act.low) + O_MEM_OE_N : out slbit; -- cram: output enable (act.low) + O_MEM_ADV_N : out slbit; -- cram: address valid (act.low) + O_MEM_CLK : out slbit; -- cram: clock + O_MEM_CRE : out slbit; -- cram: command register enable + I_MEM_WAIT : in slbit; -- cram: mem wait + O_FLA_CE_N : out slbit; -- flash ce.. (act.low) + O_MEM_ADDR : out slv23; -- cram: address lines + IO_MEM_DATA : inout slv16 -- cram: data lines + ); +end n2_cram_dummy; + + +architecture syn of n2_cram_dummy is +begin + + O_MEM_CE_N <= '1'; -- disable cram chip + O_MEM_BE_N <= "11"; + O_MEM_WE_N <= '1'; + O_MEM_OE_N <= '1'; + O_MEM_ADV_N <= '1'; + O_MEM_CLK <= '0'; + O_MEM_CRE <= '0'; + O_FLA_CE_N <= '1'; + O_MEM_ADDR <= (others=>'0'); + IO_MEM_DATA <= (others=>'0'); + +end syn; diff --git a/rtl/bplib/nexys2/n2_cram_memctl_as.vbom b/rtl/bplib/nexys2/n2_cram_memctl_as.vbom new file mode 100644 index 00000000..fdf4227d --- /dev/null +++ b/rtl/bplib/nexys2/n2_cram_memctl_as.vbom @@ -0,0 +1,9 @@ +# libs +../../vlib/slvtypes.vhd +../../vlib/xlib/xlib.vhd +# components +../../vlib/xlib/iob_reg_o.vbom +../../vlib/xlib/iob_reg_o_gen.vbom +../../vlib/xlib/iob_reg_io_gen.vbom +# design +n2_cram_memctl_as.vhd diff --git a/rtl/bplib/nexys2/n2_cram_memctl_as.vhd b/rtl/bplib/nexys2/n2_cram_memctl_as.vhd new file mode 100644 index 00000000..09ea689e --- /dev/null +++ b/rtl/bplib/nexys2/n2_cram_memctl_as.vhd @@ -0,0 +1,562 @@ +-- $Id: n2_cram_memctl_as.vhd 314 2010-07-09 17:38:41Z mueller $ +-- +-- Copyright 2010- by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, 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 complete details. +-- +------------------------------------------------------------------------------ +-- Module Name: n2_cram_memctl_as - syn +-- Description: nexys2: CRAM driver - async and page mode +-- +-- Dependencies: vlib/xlib/iob_reg_o +-- vlib/xlib/iob_reg_o_gen +-- vlib/xlib/iob_reg_io_gen +-- Test bench: tb/tb_n2_cram_memctl +-- fw_gen/tst_sram/nexys2/tb/tb_tst_sram_n2 +-- Target Devices: generic +-- Tool versions: xst 11.4; ghdl 0.26 +-- +-- Synthesized (xst): +-- Date Rev ise Target flop lutl lutm slic t peri +-- 2010-06-03 299 11.4 L68 xc3s1200e-4 91 100 0 96 s 6.7 +-- 2010-05-24 294 11.4 L68 xc3s1200e-4 91 99 0 95 s 6.7 +-- 2010-05-23 293 11.4 L68 xc3s1200e-4 91 139 0 99 s 6.7 +-- +-- Revision History: +-- Date Rev Version Comment +-- 2010-06-03 299 1.0.3 add "KEEP" for data iob; MEM_OE='1' on first read +-- cycle; +-- 2010-05-30 297 1.0.2 use READ(0|1)DELAY generic +-- 2010-05-24 294 1.0.1 more compact n.memdi logic; extra wait in s_rdwait1 +-- 2010-05-23 293 1.0 Initial version +-- +-- Notes: +-- 1. READ1DELAY of 2 is needed even though the timing of the memory suggests +-- that 1 cycle is enough (T_apa is 20 ns, so 40 ns round trip is ok). A +-- short READ1 delay works in sim, but not on fpga where the data od the +-- ADDR(0)=0 cycle is re-read (see notes_tst_sram_n2.txt). +-- tb_n2_cram_memctl_as_ISim_tsim works with full sdf even when T_apa is +-- 40ns or 50 ns, only T_apa 60 ns fails ! +-- Unclear what is wrong here, the timing of the memory model seems ok. +-- 2. There is no 'bus-turn-around' cycle needed for a write->read change +-- FPGA_OE goes 1->0 and MEM_OE goes 0->1 on the s_wrput1->s_rdinit +-- transition simultaneously. The FPGA will go high-Z quickly, the memory +-- low-Z delay by the IOB and internal memory delays. No clash. +-- 3. There is a hidden 'bus-turn-around' cycle for a read->write change. +-- MEM_OE goes 1->0 on s_rdget1->s_wrinit and the memory will go high-z with +-- some dekal. FPGA_OE goes 0->1 in the next cycle at s_wrinit->s_wrwait0. +-- Again no clash due to the 1 cycle delay. +-- +-- Timing of some signals: +-- +-- single read request: +-- +-- state |_idle |_rdinit|_rdwt0 |_rdwt0 |_rdget0|_rdwt1 |_rdget1| +-- 0 20 40 60 80 100 120 +-- CLK __|^^^|___|^^^|___|^^^|___|^^^|___|^^^|___|^^^|___|^^^|___|^^^|___| +-- +-- REQ _______|^^^^^|_____________________________________________ +-- WE ___________________________________________________________ +-- +-- IOB_CE __________|^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^|_ +-- IOB_OE _________|^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^|_ +-- +-- DO oooooooooooooooooooooooooooooooooooooooooo|lllllll|lllllll|h +-- BUSY __________|^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^|________________ +-- ACK_R ___________________________________________________________|^^^^^^^|_ +-- +-- single write request: +-- +-- state |_idle |_wrinit|_wrwt0 |_wrwt0 |_wrwt0 |_wrput0|_idle | +-- 0 20 40 60 80 100 120 +-- CLK __|^^^|___|^^^|___|^^^|___|^^^|___|^^^|___|^^^|___|^^^|___|^^^|___| +-- +-- REQ _______|^^^^^|______________________________________ +-- WE _______|^^^^^|______________________________________ +-- +-- IOB_CE __________|^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^|_ +-- IOB_BE __________|^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^|_ +-- IOB_OE ____________________________________________________ +-- IOB_WE ______________|^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^|_____ +-- +-- BUSY __________|^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^|_________ +-- ACK_W __________________________________________|^^^^^^^|_ +-- +------------------------------------------------------------------------------ + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; + +use work.slvtypes.all; +use work.xlib.all; + +entity n2_cram_memctl_as is -- CRAM driver (async+page mode) + generic ( + READ0DELAY : positive := 2; -- read word 0 delay in clock cycles + READ1DELAY : positive := 2; -- read word 1 delay in clock cycles + WRITEDELAY : positive := 3); -- write delay in clock cycles + port ( + CLK : in slbit; -- clock + RESET : in slbit; -- reset + REQ : in slbit; -- request + WE : in slbit; -- write enable + BUSY : out slbit; -- controller busy + ACK_R : out slbit; -- acknowledge read + ACK_W : out slbit; -- acknowledge write + ACT_R : out slbit; -- signal active read + ACT_W : out slbit; -- signal active write + ADDR : in slv22; -- address (32 bit word address) + BE : in slv4; -- byte enable + DI : in slv32; -- data in (memory view) + DO : out slv32; -- data out (memory view) + O_MEM_CE_N : out slbit; -- cram: chip enable (act.low) + O_MEM_BE_N : out slv2; -- cram: byte enables (act.low) + O_MEM_WE_N : out slbit; -- cram: write enable (act.low) + O_MEM_OE_N : out slbit; -- cram: output enable (act.low) + O_MEM_ADV_N : out slbit; -- cram: address valid (act.low) + O_MEM_CLK : out slbit; -- cram: clock + O_MEM_CRE : out slbit; -- cram: command register enable + I_MEM_WAIT : in slbit; -- cram: mem wait + O_FLA_CE_N : out slbit; -- flash ce.. (act.low) + O_MEM_ADDR : out slv23; -- cram: address lines + IO_MEM_DATA : inout slv16 -- cram: data lines + ); +end n2_cram_memctl_as; + + +architecture syn of n2_cram_memctl_as is + + type state_type is ( + s_idle, -- s_idle: wait for req + s_rdinit, -- s_rdinit: read init cycle + s_rdwait0, -- s_rdwait0: read wait low word + s_rdget0, -- s_rdget0: read get low word + s_rdwait1, -- s_rdwait1: read wait high word + s_rdget1, -- s_rdget1: read get high word + s_wrinit, -- s_wrinit: write init cycle + s_wrwait0, -- s_rdwait0: write wait 1st word + s_wrput0, -- s_rdput0: write put 1st word + s_wrini1, -- s_wrini1: write init 2nd word + s_wrwait1, -- s_wrwait1: write wait 2nd word + s_wrput1 -- s_wrput1: write put 2nd word + ); + + type regs_type is record + state : state_type; -- state + ackr : slbit; -- signal ack_r + addr0 : slbit; -- current addr0 + be2nd : slv2; -- be's of 2nd write cycle + cntdly : slv2; -- wait delay counter + cntce : slv7; -- ce counter + fidle : slbit; -- force idle flag + memdo0 : slv16; -- mem data out, low word + memdi : slv32; -- mem data in + end record regs_type; + + constant regs_init : regs_type := ( + s_idle, -- + '0', -- ackr + '0', -- addr0 + "00", -- be2nd + (others=>'0'), -- cntdly + (others=>'0'), -- cntce + '0', -- fidle + (others=>'0'), -- memdo0 + (others=>'0') -- memdi + ); + + signal R_REGS : regs_type := regs_init; -- state registers + signal N_REGS : regs_type := regs_init; -- next value state regs + + signal CLK_180 : slbit := '0'; + signal MEM_CE_N : slbit := '1'; + signal MEM_BE_N : slv2 := "11"; + signal MEM_WE_N : slbit := '1'; + signal MEM_OE_N : slbit := '1'; + signal BE_CE : slbit := '0'; + signal ADDRH_CE : slbit := '0'; + signal ADDR0_CE : slbit := '0'; + signal ADDR0 : slbit := '0'; + signal DATA_CEI : slbit := '0'; + signal DATA_CEO : slbit := '0'; + signal DATA_OE : slbit := '0'; + signal MEM_DO : slv16 := (others=>'0'); + signal MEM_DI : slv16 := (others=>'0'); + +-- these attributes aren't accepted by ghdl 0.26 +-- attribute s : string; +-- attribute s of I_MEM_WAIT : signal is "true"; + +begin + + CLK_180 <= not CLK; + + IOB_MEM_CE : iob_reg_o + generic map ( + INIT => '1') + port map ( + CLK => CLK, + CE => '1', + DO => MEM_CE_N, + PAD => O_MEM_CE_N + ); + + IOB_MEM_BE : iob_reg_o_gen + generic map ( + DWIDTH => 2, + INIT => '1') + port map ( + CLK => CLK, + CE => BE_CE, + DO => MEM_BE_N, + PAD => O_MEM_BE_N + ); + + IOB_MEM_WE : iob_reg_o + generic map ( + INIT => '1') + port map ( + CLK => CLK_180, + CE => '1', + DO => MEM_WE_N, + PAD => O_MEM_WE_N + ); + + IOB_MEM_OE : iob_reg_o + generic map ( + INIT => '1') + port map ( + CLK => CLK, + CE => '1', + DO => MEM_OE_N, + PAD => O_MEM_OE_N + ); + + IOB_MEM_ADDRH : iob_reg_o_gen + generic map ( + DWIDTH => 22) + port map ( + CLK => CLK, + CE => ADDRH_CE, + DO => ADDR, + PAD => O_MEM_ADDR(22 downto 1) + ); + + IOB_MEM_ADDR0 : iob_reg_o + port map ( + CLK => CLK, + CE => ADDR0_CE, + DO => ADDR0, + PAD => O_MEM_ADDR(0) + ); + + IOB_MEM_DATA : iob_reg_io_gen + generic map ( + DWIDTH => 16, + PULL => "KEEP") + port map ( + CLK => CLK, + CEI => DATA_CEI, + CEO => DATA_CEO, + OE => DATA_OE, + DI => MEM_DO, + DO => MEM_DI, + PAD => IO_MEM_DATA + ); + + O_MEM_ADV_N <= '0'; + O_MEM_CLK <= '0'; + O_MEM_CRE <= '0'; + O_FLA_CE_N <= '1'; + + proc_regs: process (CLK) + begin + + if CLK'event and CLK='1' then + if RESET = '1' then + R_REGS <= regs_init; + else + R_REGS <= N_REGS; + end if; + end if; + + end process proc_regs; + + proc_next: process (R_REGS, REQ, WE, BE, DI, MEM_DO) + + variable r : regs_type := regs_init; + variable n : regs_type := regs_init; + variable ibusy : slbit := '0'; + variable iackw : slbit := '0'; + variable iactr : slbit := '0'; + variable iactw : slbit := '0'; + variable imem_ce : slbit := '0'; + variable imem_be : slv2 := "00"; + variable imem_we : slbit := '0'; + variable imem_oe : slbit := '0'; + variable ibe_ce : slbit := '0'; + variable iaddrh_ce : slbit := '0'; + variable iaddr0_ce : slbit := '0'; + variable iaddr0 : slbit := '0'; + variable idata_cei : slbit := '0'; + variable idata_ceo : slbit := '0'; + variable idata_oe : slbit := '0'; + + procedure do_dispatch(nstate : out state_type; + iaddrh_ce : out slbit; + iaddr0_ce : out slbit; + iaddr0 : out slbit; + ibe_ce : out slbit; + imem_be : out slv2; + imem_ce : out slbit; + imem_oe : out slbit; + nbe2nd : out slv2) is + begin + iaddrh_ce := '1'; -- latch address (high part) + iaddr0_ce := '1'; -- latch address 0 bit + ibe_ce := '1'; -- latch be's + imem_ce := '1'; -- ce CRAM next cycle + nbe2nd := "00"; -- assume no 2nd write cycle + if WE = '0' then -- if READ requested + iaddr0 := '0'; -- go first for low word + imem_be := "11"; -- on read always on + imem_oe := '1'; -- oe CRAM next cycle + nstate := s_rdinit; -- next: read init part + else -- if WRITE requested + if BE(1 downto 0) /= "00" then -- low word write + iaddr0 := '0'; -- access word 0 + imem_be := BE(1 downto 0); -- set be's for 1st cycle + nbe2nd := BE(3 downto 2); -- keep be's for 2nd cycle + else -- high word write + iaddr0 := '1'; -- access word 1 + imem_be := BE(3 downto 2); -- set be's for 1st cycle + end if; + nstate := s_wrinit; -- next: write init part + end if; + end procedure do_dispatch; + + begin + + r := R_REGS; + n := R_REGS; + n.ackr := '0'; + + ibusy := '0'; + iackw := '0'; + iactr := '0'; + iactw := '0'; + + imem_ce := '0'; + imem_be := "11"; + imem_we := '0'; + imem_oe := '0'; + ibe_ce := '0'; + iaddrh_ce := '0'; + iaddr0_ce := '0'; + iaddr0 := '0'; + idata_cei := '0'; + idata_ceo := '0'; + idata_oe := '0'; + + if unsigned(r.cntdly) /= 0 then + n.cntdly := unsigned(r.cntdly) - 1; + end if; + + case r.state is + when s_idle => -- s_idle: wait for req + if REQ = '1' then -- if IO requested + do_dispatch(n.state, iaddrh_ce, iaddr0_ce, iaddr0, + ibe_ce, imem_be, imem_ce, imem_oe, n.be2nd); + end if; + + when s_rdinit => -- s_rdinit: read init cycle + ibusy := '1'; -- signal busy, unable to handle req + iactr := '1'; -- signal mem read + imem_ce := '1'; -- ce CRAM next cycle + imem_oe := '1'; -- oe CRAM next cycle + n.cntdly:= conv_std_logic_vector(READ0DELAY-1, n.cntdly'length); + n.state := s_rdwait0; -- next: wait + + when s_rdwait0 => -- s_rdwait0: read wait low word + ibusy := '1'; -- signal busy, unable to handle req + iactr := '1'; -- signal mem read + imem_ce := '1'; -- ce CRAM next cycle + imem_oe := '1'; -- oe CRAM next cycle + if unsigned(r.cntdly) = 0 then -- wait expired ? + n.state := s_rdget0; -- next: get low word + end if; + + when s_rdget0 => -- s_rdget0: read get low word + ibusy := '1'; -- signal busy, unable to handle req + iactr := '1'; -- signal mem read + imem_ce := '1'; -- ce CRAM next cycle + imem_oe := '1'; -- oe CRAM next cycle + idata_cei := '1'; -- latch input data + iaddr0_ce := '1'; -- latch address 0 bit + iaddr0 := '1'; -- now go for high word + n.cntdly:= conv_std_logic_vector(READ1DELAY-1, n.cntdly'length); + n.state := s_rdwait1; -- next: wait high word + + when s_rdwait1 => -- s_rdwait1: read wait high word + ibusy := '1'; -- signal busy, unable to handle req + iactr := '1'; -- signal mem read + imem_ce := '1'; -- ce CRAM next cycle + imem_oe := '1'; -- oe CRAM next cycle + if unsigned(r.cntdly) = 0 then -- wait expired ? + n.state := s_rdget1; -- next: get low word + end if; -- + + when s_rdget1 => -- s_rdget1: read get high word + iactr := '1'; -- signal mem read + n.memdo0:= MEM_DO; -- save low word data + idata_cei := '1'; -- latch input data + n.ackr := '1'; -- ACK_R next cycle + n.state := s_idle; -- next: wait next request + if r.fidle = '1' then -- forced idle cycle + ibusy := '1'; -- signal busy, unable to handle req + else + if REQ = '1' then -- if IO requested + do_dispatch(n.state, iaddrh_ce, iaddr0_ce, iaddr0, + ibe_ce, imem_be, imem_ce, imem_oe, n.be2nd); + end if; + end if; + + when s_wrinit => -- s_wrinit: write init cycle + ibusy := '1'; -- signal busy, unable to handle req + iactw := '1'; -- signal mem write + iackw := '1'; -- signal write done (all latched) + idata_ceo:= '1'; -- latch output data + idata_oe := '1'; -- oe FPGA next cycle + imem_ce := '1'; -- ce CRAM next cycle + imem_we := '1'; -- we CRAM in half cycle + n.cntdly:= conv_std_logic_vector(WRITEDELAY-1, n.cntdly'length); + n.state := s_wrwait0; -- next: wait + + when s_wrwait0 => -- s_rdput0: write wait 1st word + ibusy := '1'; -- signal busy, unable to handle req + iactw := '1'; -- signal mem write + idata_oe := '1'; -- oe FPGA next cycle + imem_ce := '1'; -- ce CRAM next cycle + imem_we := '1'; -- we CRAM next cycle + if unsigned(r.cntdly) = 0 then -- wait expired ? + n.state := s_wrput0; -- next: put 1st word + end if; + + when s_wrput0 => -- s_rdput0: write put 1st word + iactw := '1'; -- signal mem write + imem_we := '0'; -- deassert we CRAM in half cycle + if r.be2nd /= "00" then + ibusy := '1'; -- signal busy, unable to handle req + imem_ce := '1'; -- ce CRAM next cycle + iaddr0_ce := '1'; -- latch address 0 bit + iaddr0 := '1'; -- now go for high word + ibe_ce := '1'; -- latch be's + imem_be := r.be2nd; -- now be's of high word + n.state := s_wrini1; -- next: start 2nd write + else + n.state := s_idle; -- next: wait next request + if r.fidle = '1' then -- forced idle cycle + ibusy := '1'; -- signal busy + else + if REQ = '1' then -- if IO requested + do_dispatch(n.state, iaddrh_ce, iaddr0_ce, iaddr0, + ibe_ce, imem_be, imem_ce, imem_oe, n.be2nd); + end if; + end if; + end if; + + when s_wrini1 => -- s_wrini1: write init 2nd word + ibusy := '1'; -- signal busy, unable to handle req + iactw := '1'; -- signal mem write + idata_ceo:= '1'; -- latch output data + idata_oe := '1'; -- oe FPGA next cycle + imem_ce := '1'; -- ce CRAM next cycle + imem_we := '1'; -- we CRAM in half cycle + n.cntdly:= conv_std_logic_vector(WRITEDELAY-1, n.cntdly'length); + n.state := s_wrwait1; -- next: wait + + when s_wrwait1 => -- s_wrwait1: write wait 2nd word + ibusy := '1'; -- signal busy, unable to handle req + iactw := '1'; -- signal mem write + idata_oe := '1'; -- oe FPGA next cycle + imem_ce := '1'; -- ce CRAM next cycle + imem_we := '1'; -- we CRAM next cycle + if unsigned(r.cntdly) = 0 then -- wait expired ? + n.state := s_wrput1; -- next: put 2nd word + end if; + + when s_wrput1 => -- s_wrput1: write put 2nd word + iactw := '1'; -- signal mem write + imem_we := '0'; -- deassert we CRAM in half cycle + n.state := s_idle; -- next: wait next request + if r.fidle = '1' then -- forced idle cycle + ibusy := '1'; -- signal busy, unable to handle req + else + if REQ = '1' then -- if IO requested + do_dispatch(n.state, iaddrh_ce, iaddr0_ce, iaddr0, + ibe_ce, imem_be, imem_ce, imem_oe, n.be2nd); + end if; + end if; + + when others => null; + end case; + + if imem_ce = '0' then -- if cmem not active + n.cntce := (others=>'0'); -- clear counter + n.fidle := '0'; -- clear force idle flag + else -- if cmem active + if unsigned(r.cntce) >= 127 then -- if max ce count expired + n.fidle := '1'; -- set forced idle flag + else -- if max ce count not yet reached + n.cntce := unsigned(r.cntce) + 1; -- increment counter + end if; + end if; + + if iaddrh_ce = '1' then -- if addresses are latched + n.memdi := DI; -- latch data too... + end if; + + if iaddr0_ce = '1' then -- if address bit 0 changed + n.addr0 := iaddr0; -- mirror it in state regs + end if; + + N_REGS <= n; + + MEM_CE_N <= not imem_ce; + MEM_WE_N <= not imem_we; + MEM_BE_N <= not imem_be; + MEM_OE_N <= not imem_oe; + + if r.addr0 = '0' then + MEM_DI <= r.memdi(15 downto 0); + else + MEM_DI <= r.memdi(31 downto 16); + end if; + + BE_CE <= ibe_ce; + ADDRH_CE <= iaddrh_ce; + ADDR0_CE <= iaddr0_ce; + ADDR0 <= iaddr0; + DATA_CEI <= idata_cei; + DATA_CEO <= idata_ceo; + DATA_OE <= idata_oe; + + BUSY <= ibusy; + ACK_R <= r.ackr; + ACK_W <= iackw; + ACT_R <= iactr; + ACT_W <= iactw; + + DO <= MEM_DO & r.memdo0; + + end process proc_next; + +end syn; diff --git a/rtl/bplib/nexys2/nexys2_pins.ucf b/rtl/bplib/nexys2/nexys2_pins.ucf new file mode 100644 index 00000000..e1b54bdc --- /dev/null +++ b/rtl/bplib/nexys2/nexys2_pins.ucf @@ -0,0 +1,123 @@ +## $Id: nexys2_pins.ucf 311 2010-06-30 17:52:37Z mueller $ +## +## Pin locks for Nexys 2 core functionality (for 1200k FPGA) +## internal RS232 +## human I/O (switches, buttons, leds, display) +## cram +## +## Revision History: +## Date Rev Version Comment +## 2010-05-23 294 1.0.1 use ADV_N rather ADV +## 2010-05-16 291 1.0 Initial version +## +## Note: default is DRIVE=12 | SLEW=SLOW +## +## clocks -------------------------------------------------------------------- +NET "CLK" LOC = "b8" | IOSTANDARD=LVCMOS33; +## +## RS232 interface ----------------------------------------------------------- +NET "I_RXD" LOC = "u6" | IOSTANDARD=LVCMOS33; +NET "O_TXD" LOC = "p9" | IOSTANDARD=LVCMOS33 | DRIVE=12 | SLEW=SLOW; +## +## switches and buttons ------------------------------------------------------ +NET "I_SWI<0>" LOC = "g18" | IOSTANDARD=LVCMOS33; +NET "I_SWI<1>" LOC = "h18" | IOSTANDARD=LVCMOS33; +NET "I_SWI<2>" LOC = "k18" | IOSTANDARD=LVCMOS33; +NET "I_SWI<3>" LOC = "k17" | IOSTANDARD=LVCMOS33; +NET "I_SWI<4>" LOC = "l14" | IOSTANDARD=LVCMOS33; +NET "I_SWI<5>" LOC = "l13" | IOSTANDARD=LVCMOS33; +NET "I_SWI<6>" LOC = "n17" | IOSTANDARD=LVCMOS33; +NET "I_SWI<7>" LOC = "r17" | IOSTANDARD=LVCMOS33; +## +NET "I_BTN<0>" LOC = "b18" | IOSTANDARD=LVCMOS33; +NET "I_BTN<1>" LOC = "d18" | IOSTANDARD=LVCMOS33; +NET "I_BTN<2>" LOC = "e18" | IOSTANDARD=LVCMOS33; +NET "I_BTN<3>" LOC = "h13" | IOSTANDARD=LVCMOS33; +## +## LEDs ---------------------------------------------------------------------- +NET "O_LED<0>" LOC = "j14" | IOSTANDARD=LVCMOS33; +NET "O_LED<1>" LOC = "j15" | IOSTANDARD=LVCMOS33; +NET "O_LED<2>" LOC = "k15" | IOSTANDARD=LVCMOS33; +NET "O_LED<3>" LOC = "k14" | IOSTANDARD=LVCMOS33; +NET "O_LED<4>" LOC = "e16" | IOSTANDARD=LVCMOS33; +NET "O_LED<5>" LOC = "p16" | IOSTANDARD=LVCMOS33; +NET "O_LED<6>" LOC = "e4" | IOSTANDARD=LVCMOS33; +NET "O_LED<7>" LOC = "p4" | IOSTANDARD=LVCMOS33; +NET "O_LED<*>" DRIVE=12 | SLEW=SLOW; +## +## 7 segment display --------------------------------------------------------- +NET "O_ANO_N<0>" LOC = "f17" | IOSTANDARD=LVCMOS33; +NET "O_ANO_N<1>" LOC = "h17" | IOSTANDARD=LVCMOS33; +NET "O_ANO_N<2>" LOC = "c18" | IOSTANDARD=LVCMOS33; +NET "O_ANO_N<3>" LOC = "f15" | IOSTANDARD=LVCMOS33; +NET "O_ANO_N<*>" DRIVE=12 | SLEW=SLOW; +## +NET "O_SEG_N<0>" LOC = "l18" | IOSTANDARD=LVCMOS33; +NET "O_SEG_N<1>" LOC = "f18" | IOSTANDARD=LVCMOS33; +NET "O_SEG_N<2>" LOC = "d17" | IOSTANDARD=LVCMOS33; +NET "O_SEG_N<3>" LOC = "d16" | IOSTANDARD=LVCMOS33; +NET "O_SEG_N<4>" LOC = "g14" | IOSTANDARD=LVCMOS33; +NET "O_SEG_N<5>" LOC = "j17" | IOSTANDARD=LVCMOS33; +NET "O_SEG_N<6>" LOC = "h14" | IOSTANDARD=LVCMOS33; +NET "O_SEG_N<7>" LOC = "c17" | IOSTANDARD=LVCMOS33; +NET "O_SEG_N<*>" DRIVE=12 | SLEW=SLOW; +## +## CRAM ---------------------------------------------------------------------- +NET "O_MEM_CE_N" LOC = "r6" | IOSTANDARD=LVCMOS33 | DRIVE=12 | SLEW=FAST; +NET "O_MEM_WE_N" LOC = "n7" | IOSTANDARD=LVCMOS33 | DRIVE=12 | SLEW=FAST; +NET "O_MEM_OE_N" LOC = "t2" | IOSTANDARD=LVCMOS33 | DRIVE=12 | SLEW=FAST; +## +NET "O_MEM_BE_N<0>" LOC = "k5" | IOSTANDARD=LVCMOS33; +NET "O_MEM_BE_N<1>" LOC = "k4" | IOSTANDARD=LVCMOS33; +NET "O_MEM_BE_N<*>" DRIVE=12 | SLEW=FAST; +## +NET "O_MEM_ADV_N" LOC = "j4" | IOSTANDARD=LVCMOS33 | DRIVE=12 | SLEW=FAST; +NET "O_MEM_CLK" LOC = "h5" | IOSTANDARD=LVCMOS33 | DRIVE=12 | SLEW=FAST; +NET "O_MEM_CRE" LOC = "p7" | IOSTANDARD=LVCMOS33 | DRIVE=12 | SLEW=FAST; +NET "I_MEM_WAIT" LOC = "f5" | IOSTANDARD=LVCMOS33 | PULLDOWN; +## +NET "O_FLA_CE_N" LOC = "r5" | IOSTANDARD=LVCMOS33 | DRIVE=12 | SLEW=FAST; +## +NET "O_MEM_ADDR<0>" LOC = "j1" | IOSTANDARD=LVCMOS33; +NET "O_MEM_ADDR<1>" LOC = "j2" | IOSTANDARD=LVCMOS33; +NET "O_MEM_ADDR<2>" LOC = "h4" | IOSTANDARD=LVCMOS33; +NET "O_MEM_ADDR<3>" LOC = "h1" | IOSTANDARD=LVCMOS33; +NET "O_MEM_ADDR<4>" LOC = "h2" | IOSTANDARD=LVCMOS33; +NET "O_MEM_ADDR<5>" LOC = "j5" | IOSTANDARD=LVCMOS33; +NET "O_MEM_ADDR<6>" LOC = "h3" | IOSTANDARD=LVCMOS33; +NET "O_MEM_ADDR<7>" LOC = "h6" | IOSTANDARD=LVCMOS33; +NET "O_MEM_ADDR<8>" LOC = "f1" | IOSTANDARD=LVCMOS33; +NET "O_MEM_ADDR<9>" LOC = "g3" | IOSTANDARD=LVCMOS33; +NET "O_MEM_ADDR<10>" LOC = "g6" | IOSTANDARD=LVCMOS33; +NET "O_MEM_ADDR<11>" LOC = "g5" | IOSTANDARD=LVCMOS33; +NET "O_MEM_ADDR<12>" LOC = "g4" | IOSTANDARD=LVCMOS33; +NET "O_MEM_ADDR<13>" LOC = "f2" | IOSTANDARD=LVCMOS33; +NET "O_MEM_ADDR<14>" LOC = "e1" | IOSTANDARD=LVCMOS33; +NET "O_MEM_ADDR<15>" LOC = "m5" | IOSTANDARD=LVCMOS33; +NET "O_MEM_ADDR<16>" LOC = "e2" | IOSTANDARD=LVCMOS33; +NET "O_MEM_ADDR<17>" LOC = "c2" | IOSTANDARD=LVCMOS33; +NET "O_MEM_ADDR<18>" LOC = "c1" | IOSTANDARD=LVCMOS33; +NET "O_MEM_ADDR<19>" LOC = "d2" | IOSTANDARD=LVCMOS33; +NET "O_MEM_ADDR<20>" LOC = "k3" | IOSTANDARD=LVCMOS33; +NET "O_MEM_ADDR<21>" LOC = "d1" | IOSTANDARD=LVCMOS33; +NET "O_MEM_ADDR<22>" LOC = "k6" | IOSTANDARD=LVCMOS33; +NET "O_MEM_ADDR<*>" DRIVE=6 | SLEW=FAST; +## +NET "IO_MEM_DATA<0>" LOC = "l1" | IOSTANDARD=LVCMOS33; +NET "IO_MEM_DATA<1>" LOC = "l4" | IOSTANDARD=LVCMOS33; +NET "IO_MEM_DATA<2>" LOC = "l6" | IOSTANDARD=LVCMOS33; +NET "IO_MEM_DATA<3>" LOC = "m4" | IOSTANDARD=LVCMOS33; +NET "IO_MEM_DATA<4>" LOC = "n5" | IOSTANDARD=LVCMOS33; +NET "IO_MEM_DATA<5>" LOC = "p1" | IOSTANDARD=LVCMOS33; +NET "IO_MEM_DATA<6>" LOC = "p2" | IOSTANDARD=LVCMOS33; +NET "IO_MEM_DATA<7>" LOC = "r2" | IOSTANDARD=LVCMOS33; +NET "IO_MEM_DATA<8>" LOC = "l3" | IOSTANDARD=LVCMOS33; +NET "IO_MEM_DATA<9>" LOC = "l5" | IOSTANDARD=LVCMOS33; +NET "IO_MEM_DATA<10>" LOC = "m3" | IOSTANDARD=LVCMOS33; +NET "IO_MEM_DATA<11>" LOC = "m6" | IOSTANDARD=LVCMOS33; +NET "IO_MEM_DATA<12>" LOC = "l2" | IOSTANDARD=LVCMOS33; +NET "IO_MEM_DATA<13>" LOC = "n4" | IOSTANDARD=LVCMOS33; +NET "IO_MEM_DATA<14>" LOC = "r3" | IOSTANDARD=LVCMOS33; +NET "IO_MEM_DATA<15>" LOC = "t1" | IOSTANDARD=LVCMOS33; +NET "IO_MEM_DATA<*>" DRIVE=6 | SLEW=SLOW | KEEPER; +## diff --git a/rtl/bplib/nexys2/nexys2_pins_pmb0_rs232.ucf b/rtl/bplib/nexys2/nexys2_pins_pmb0_rs232.ucf new file mode 100644 index 00000000..9a1e6789 --- /dev/null +++ b/rtl/bplib/nexys2/nexys2_pins_pmb0_rs232.ucf @@ -0,0 +1,12 @@ +## $Id: nexys2_pins_pmb0_rs232.ucf 311 2010-06-30 17:52:37Z mueller $ +## +## Revision History: +## Date Rev Version Comment +## 2010-05-28 295 1.0 Initial version +## +## Pmod connector B top / usage RS232 for FTDI USB serport ------------------- +## +NET "O_FUSP_RTS_N" LOC = "m13" | IOSTANDARD=LVCMOS33 | DRIVE=4 | SLEW=SLOW; +NET "I_FUSP_CTS_N" LOC = "r18" | IOSTANDARD=LVCMOS33 | PULLDOWN; +NET "I_FUSP_RXD" LOC = "r15" | IOSTANDARD=LVCMOS33 | PULLUP; +NET "O_FUSP_TXD" LOC = "t17" | IOSTANDARD=LVCMOS33 | DRIVE=4 | SLEW=SLOW; diff --git a/rtl/bplib/nexys2/nexys2lib.vhd b/rtl/bplib/nexys2/nexys2lib.vhd new file mode 100644 index 00000000..bc89aa2d --- /dev/null +++ b/rtl/bplib/nexys2/nexys2lib.vhd @@ -0,0 +1,136 @@ +-- $Id: nexys2lib.vhd 314 2010-07-09 17:38:41Z mueller $ +-- +-- Copyright 2010- by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, 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 complete details. +-- +------------------------------------------------------------------------------ +-- Package Name: nexys2lib +-- Description: Nexys 2 components +-- +-- Dependencies: - +-- Tool versions: xst 11.4; ghdl 0.26 +-- Revision History: +-- Date Rev Version Comment +-- 2010-05-28 295 1.0.3 use _ADV_N also for n2_cram_dummy +-- 2010-05-23 294 1.0.2 add n2_cram_dummy; +-- 2010-05-23 293 1.0.1 use _ADV_N rather _ADV; add generic for memctl +-- 2010-05-21 292 1.0 Initial version +------------------------------------------------------------------------------ + +library ieee; +use ieee.std_logic_1164.all; + +use work.slvtypes.all; + +package nexys2lib is + +component nexys2_aif is -- NEXYS 2, abstract iface, base + port ( + CLK : in slbit; -- clock + I_RXD : in slbit; -- receive data (board view) + O_TXD : out slbit; -- transmit data (board view) + I_SWI : in slv8; -- s3 switches + I_BTN : in slv4; -- s3 buttons + O_LED : out slv8; -- s3 leds + O_ANO_N : out slv4; -- 7 segment disp: anodes (act.low) + O_SEG_N : out slv8; -- 7 segment disp: segments (act.low) + O_MEM_CE_N : out slbit; -- cram: chip enable (act.low) + O_MEM_BE_N : out slv2; -- cram: byte enables (act.low) + O_MEM_WE_N : out slbit; -- cram: write enable (act.low) + O_MEM_OE_N : out slbit; -- cram: output enable (act.low) + O_MEM_ADV_N : out slbit; -- cram: address valid (act.low) + O_MEM_CLK : out slbit; -- cram: clock + O_MEM_CRE : out slbit; -- cram: command register enable + I_MEM_WAIT : in slbit; -- cram: mem wait + O_FLA_CE_N : out slbit; -- flash ce.. (act.low) + O_MEM_ADDR : out slv23; -- cram: address lines + IO_MEM_DATA : inout slv16 -- cram: data lines + ); +end component; + +component nexys2_fusp_aif is -- NEXYS 2, abstract iface, base+fusp + port ( + CLK : in slbit; -- clock + I_RXD : in slbit; -- receive data (board view) + O_TXD : out slbit; -- transmit data (board view) + I_SWI : in slv8; -- s3 switches + I_BTN : in slv4; -- s3 buttons + O_LED : out slv8; -- s3 leds + O_ANO_N : out slv4; -- 7 segment disp: anodes (act.low) + O_SEG_N : out slv8; -- 7 segment disp: segments (act.low) + O_MEM_CE_N : out slbit; -- cram: chip enable (act.low) + O_MEM_BE_N : out slv2; -- cram: byte enables (act.low) + O_MEM_WE_N : out slbit; -- cram: write enable (act.low) + O_MEM_OE_N : out slbit; -- cram: output enable (act.low) + O_MEM_ADV_N : out slbit; -- cram: address valid (act.low) + O_MEM_CLK : out slbit; -- cram: clock + O_MEM_CRE : out slbit; -- cram: command register enable + I_MEM_WAIT : in slbit; -- cram: mem wait + O_FLA_CE_N : out slbit; -- flash ce.. (act.low) + O_MEM_ADDR : out slv23; -- cram: address lines + IO_MEM_DATA : inout slv16; -- cram: data lines + O_FUSP_RTS_N : out slbit; -- fusp: rs232 rts_n + I_FUSP_CTS_N : in slbit; -- fusp: rs232 cts_n + I_FUSP_RXD : in slbit; -- fusp: rs232 rx + O_FUSP_TXD : out slbit -- fusp: rs232 tx + ); +end component; + +component n2_cram_dummy is -- CRAM protection dummy + port ( + O_MEM_CE_N : out slbit; -- cram: chip enable (act.low) + O_MEM_BE_N : out slv2; -- cram: byte enables (act.low) + O_MEM_WE_N : out slbit; -- cram: write enable (act.low) + O_MEM_OE_N : out slbit; -- cram: output enable (act.low) + O_MEM_ADV_N : out slbit; -- cram: address valid (act.low) + O_MEM_CLK : out slbit; -- cram: clock + O_MEM_CRE : out slbit; -- cram: command register enable + I_MEM_WAIT : in slbit; -- cram: mem wait + O_FLA_CE_N : out slbit; -- flash ce.. (act.low) + O_MEM_ADDR : out slv23; -- cram: address lines + IO_MEM_DATA : inout slv16 -- cram: data lines + ); +end component; + +component n2_cram_memctl_as is -- CRAM driver (async+page mode) + generic ( + READ0DELAY : positive := 2; -- read word 0 delay in clock cycles + READ1DELAY : positive := 2; -- read word 1 delay in clock cycles + WRITEDELAY : positive := 3); -- write delay in clock cycles + port ( + CLK : in slbit; -- clock + RESET : in slbit; -- reset + REQ : in slbit; -- request + WE : in slbit; -- write enable + BUSY : out slbit; -- controller busy + ACK_R : out slbit; -- acknowledge read + ACK_W : out slbit; -- acknowledge write + ACT_R : out slbit; -- signal active read + ACT_W : out slbit; -- signal active write + ADDR : in slv22; -- address (32 bit word address) + BE : in slv4; -- byte enable + DI : in slv32; -- data in (memory view) + DO : out slv32; -- data out (memory view) + O_MEM_CE_N : out slbit; -- cram: chip enable (act.low) + O_MEM_BE_N : out slv2; -- cram: byte enables (act.low) + O_MEM_WE_N : out slbit; -- cram: write enable (act.low) + O_MEM_OE_N : out slbit; -- cram: output enable (act.low) + O_MEM_ADV_N : out slbit; -- cram: address valid (act.low) + O_MEM_CLK : out slbit; -- cram: clock + O_MEM_CRE : out slbit; -- cram: command register enable + I_MEM_WAIT : in slbit; -- cram: mem wait + O_FLA_CE_N : out slbit; -- flash ce.. (act.low) + O_MEM_ADDR : out slv23; -- cram: address lines + IO_MEM_DATA : inout slv16 -- cram: data lines + ); +end component; + +end nexys2lib; diff --git a/rtl/bplib/nexys2/tb/.cvsignore b/rtl/bplib/nexys2/tb/.cvsignore new file mode 100644 index 00000000..046d9e27 --- /dev/null +++ b/rtl/bplib/nexys2/tb/.cvsignore @@ -0,0 +1,7 @@ +tb_nexys2_dummy +tb_nexys2_fusp_dummy +tb_n2_cram_memctl_as +tb_n2_cram_memctl_as_[sft]sim +tb_n2_cram_memctl_as_ISim +tb_n2_cram_memctl_as_ISim_[sft]sim +tb_n2_cram_memctl_stim diff --git a/rtl/bplib/nexys2/tb/Makefile b/rtl/bplib/nexys2/tb/Makefile new file mode 100644 index 00000000..272d43bd --- /dev/null +++ b/rtl/bplib/nexys2/tb/Makefile @@ -0,0 +1,33 @@ +# $Id: Makefile 311 2010-06-30 17:52:37Z mueller $ +# +# Revision History: +# Date Rev Version Comment +# 2010-05-30 297 1.0.2 use tb_n2_cram_memctl_as now +# 2010-05-28 295 1.0.1 add tb_.._dummy's +# 2007-09-23 84 1.0 Initial version +# +EXE_all = tb_nexys2_dummy tb_nexys2_fusp_dummy tb_n2_cram_memctl_as +# +ISE_PATH = xc3s1200e-fg320-4 +# +.phony : all all_ssim all_tsim clean +# +all : $(EXE_all) +all_ssim : $(EXE_all:=_ssim) +all_tsim : $(EXE_all:=_tsim) +# +clean : ise_clean ghdl_clean isim_clean +# +#----- +# +include $(RETROBASE)/rtl/vlib/Makefile.ghdl +include $(RETROBASE)/rtl/vlib/Makefile.isim +include $(RETROBASE)/rtl/vlib/Makefile.xflow +# +VBOM_all = $(wildcard *.vbom) +# +include $(VBOM_all:.vbom=.dep_xst) +include $(VBOM_all:.vbom=.dep_ghdl) +include $(VBOM_all:.vbom=.dep_isim) +include $(wildcard *.o.dep_ghdl) +# diff --git a/rtl/bplib/nexys2/tb/tb_nexys2_core.vbom b/rtl/bplib/nexys2/tb/tb_nexys2_core.vbom new file mode 100644 index 00000000..650cc815 --- /dev/null +++ b/rtl/bplib/nexys2/tb/tb_nexys2_core.vbom @@ -0,0 +1,10 @@ +# libs +../../../vlib/slvtypes.vhd +../../../vlib/serport/serport.vhd +../../../vlib/simlib/simbus.vhd +# components +../../../vlib/serport/serport_uart_rx.vbom +../../../vlib/serport/serport_uart_tx.vbom +../../micron/mt45w8mw16b.vbom +# design +tb_nexys2_core.vhd diff --git a/rtl/bplib/nexys2/tb/tb_nexys2_core.vhd b/rtl/bplib/nexys2/tb/tb_nexys2_core.vhd new file mode 100644 index 00000000..c9219594 --- /dev/null +++ b/rtl/bplib/nexys2/tb/tb_nexys2_core.vhd @@ -0,0 +1,97 @@ +-- $Id: tb_nexys2_core.vhd 314 2010-07-09 17:38:41Z mueller $ +-- +-- Copyright 2010- by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, 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 complete details. +-- +------------------------------------------------------------------------------ +-- Module Name: tb_nexys2_core - sim +-- Description: Test bench for nexys2 - core device handling +-- +-- Dependencies: vlib/parts/micron/mt45w8mw16b +-- +-- To test: generic, any nexys2 target +-- +-- Target Devices: generic +-- Tool versions: xst 11.4; ghdl 0.26 +-- Revision History: +-- Date Rev Version Comment +-- 2010-05-23 294 1.0 Initial version (derived from tb_s3board_core) +------------------------------------------------------------------------------ + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; +use ieee.std_logic_textio.all; +use std.textio.all; + +use work.slvtypes.all; +use work.serport.all; +use work.simbus.all; + +entity tb_nexys2_core is + port ( + I_SWI : out slv8; -- n2 switches + I_BTN : out slv4; -- n2 buttons + O_MEM_CE_N : in slbit; -- cram: chip enable (act.low) + O_MEM_BE_N : in slv2; -- cram: byte enables (act.low) + O_MEM_WE_N : in slbit; -- cram: write enable (act.low) + O_MEM_OE_N : in slbit; -- cram: output enable (act.low) + O_MEM_ADV_N : in slbit; -- cram: address valid (act.low) + O_MEM_CLK : in slbit; -- cram: clock + O_MEM_CRE : in slbit; -- cram: command register enable + I_MEM_WAIT : out slbit; -- cram: mem wait + O_FLA_CE_N : in slbit; -- flash ce.. (act.low) + O_MEM_ADDR : in slv23; -- cram: address lines + IO_MEM_DATA : inout slv16 -- cram: data lines + ); +end tb_nexys2_core; + +architecture sim of tb_nexys2_core is + + signal R_SWI : slv8 := (others=>'0'); + signal R_BTN : slv4 := (others=>'0'); + + constant sbaddr_swi: slv8 := conv_std_logic_vector( 16,8); + constant sbaddr_btn: slv8 := conv_std_logic_vector( 17,8); + +begin + + MEM : entity work.mt45w8mw16b + port map ( + CLK => O_MEM_CLK, + CE_N => O_MEM_CE_N, + OE_N => O_MEM_OE_N, + WE_N => O_MEM_WE_N, + UB_N => O_MEM_BE_N(1), + LB_N => O_MEM_BE_N(0), + ADV_N => O_MEM_ADV_N, + CRE => O_MEM_CRE, + MWAIT => I_MEM_WAIT, + ADDR => O_MEM_ADDR, + DATA => IO_MEM_DATA + ); + + proc_simbus: process (SB_VAL) + begin + if SB_VAL'event and to_x01(SB_VAL)='1' then + if SB_ADDR = sbaddr_swi then + R_SWI <= to_x01(SB_DATA(R_SWI'range)); + end if; + if SB_ADDR = sbaddr_btn then + R_BTN <= to_x01(SB_DATA(R_BTN'range)); + end if; + end if; + end process proc_simbus; + + I_SWI <= R_SWI; + I_BTN <= R_BTN; + +end sim; diff --git a/rtl/bplib/nexys2/tb/tb_nexys2_fusp.vbom b/rtl/bplib/nexys2/tb/tb_nexys2_fusp.vbom new file mode 100644 index 00000000..62319e95 --- /dev/null +++ b/rtl/bplib/nexys2/tb/tb_nexys2_fusp.vbom @@ -0,0 +1,20 @@ +# Not meant for direct top level usage. Used with +# tb_nexys2_fusp_(....)[_ssim].vbom and config +# lines to generate the different cases. +# +# libs +../../../vlib/slvtypes.vhd +../../../vlib/rri/rrilib.vhd +../../../vlib/rri/tb/rritblib.vhd +../../../vlib/serport/serport.vhd +../nexys2lib.vhd +../../../vlib/simlib/simlib.vhd +../../../vlib/simlib/simbus.vhd +# components +../../../vlib/rri/tb/rritb_core.vbom +tb_nexys2_core.vbom +../../../vlib/serport/serport_uart_rxtx.vbom +nexys2_fusp_aif : nexys2_fusp_dummy.vbom +# design +tb_nexys2_fusp.vhd +@top:tb_nexys2_fusp diff --git a/rtl/bplib/nexys2/tb/tb_nexys2_fusp.vhd b/rtl/bplib/nexys2/tb/tb_nexys2_fusp.vhd new file mode 100644 index 00000000..d86f0456 --- /dev/null +++ b/rtl/bplib/nexys2/tb/tb_nexys2_fusp.vhd @@ -0,0 +1,232 @@ +-- $Id: tb_nexys2_fusp.vhd 314 2010-07-09 17:38:41Z mueller $ +-- +-- Copyright 2010- by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, 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 complete details. +-- +------------------------------------------------------------------------------ +-- Module Name: tb_nexys2_fusp - sim +-- Description: Test bench for nexys2 (base+fusp) +-- +-- Dependencies: vlib/rri/tb/rritb_core +-- tb_nexys2_core +-- vlib/serport/serport_uart_rxtx +-- nexys2_fusp_aif [UUT] +-- +-- To test: generic, any nexys2_fusp_aif target +-- +-- Target Devices: generic +-- Tool versions: xst 11.4; ghdl 0.26 +-- Revision History: +-- Date Rev Version Comment +-- 2010-05-28 295 1.0 Initial version (derived from tb_s3board_fusp) +------------------------------------------------------------------------------ + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; +use ieee.std_logic_textio.all; +use std.textio.all; + +use work.slvtypes.all; +use work.rrilib.all; +use work.rritblib.all; +use work.serport.all; +use work.nexys2lib.all; +use work.simlib.all; +use work.simbus.all; + +entity tb_nexys2_fusp is +end tb_nexys2_fusp; + +architecture sim of tb_nexys2_fusp is + + signal CLK : slbit := '0'; + + signal RESET : slbit := '0'; + signal CLKDIV : slv2 := "00"; -- run with 1 clocks / bit !! + signal RXDATA : slv8 := (others=>'0'); + signal RXVAL : slbit := '0'; + signal RXERR : slbit := '0'; + signal RXACT : slbit := '0'; + signal TXDATA : slv8 := (others=>'0'); + signal TXENA : slbit := '0'; + signal TXBUSY : slbit := '0'; + + signal RX_HOLD : slbit := '0'; + + signal I_RXD : slbit := '1'; + signal O_TXD : slbit := '1'; + signal I_SWI : slv8 := (others=>'0'); + signal I_BTN : slv4 := (others=>'0'); + signal O_LED : slv8 := (others=>'0'); + signal O_ANO_N : slv4 := (others=>'0'); + signal O_SEG_N : slv8 := (others=>'0'); + + signal O_MEM_CE_N : slbit := '1'; + signal O_MEM_BE_N : slv2 := (others=>'1'); + signal O_MEM_WE_N : slbit := '1'; + signal O_MEM_OE_N : slbit := '1'; + signal O_MEM_ADV_N : slbit := '1'; + signal O_MEM_CLK : slbit := '0'; + signal O_MEM_CRE : slbit := '0'; + signal I_MEM_WAIT : slbit := '0'; + signal O_FLA_CE_N : slbit := '0'; + signal O_MEM_ADDR : slv23 := (others=>'Z'); + signal IO_MEM_DATA : slv16 := (others=>'0'); + + signal O_FUSP_RTS_N : slbit := '0'; + signal I_FUSP_CTS_N : slbit := '0'; + signal I_FUSP_RXD : slbit := '1'; + signal O_FUSP_TXD : slbit := '1'; + + signal UART_RESET : slbit := '0'; + signal UART_RXD : slbit := '1'; + signal UART_TXD : slbit := '1'; + signal CTS_N : slbit := '0'; + signal RTS_N : slbit := '0'; + + signal R_PORTSEL : slbit := '0'; + + constant sbaddr_portsel: slv8 := conv_std_logic_vector( 8,8); + + constant clock_period : time := 20 ns; + constant clock_offset : time := 200 ns; + constant setup_time : time := 5 ns; + constant c2out_time : time := 10 ns; + +begin + + TBCORE : rritb_core + generic map ( + CLK_PERIOD => clock_period, + CLK_OFFSET => clock_offset, + SETUP_TIME => setup_time, + C2OUT_TIME => c2out_time) + port map ( + CLK => CLK, + RX_DATA => TXDATA, + RX_VAL => TXENA, + RX_HOLD => RX_HOLD, + TX_DATA => RXDATA, + TX_ENA => RXVAL + ); + + RX_HOLD <= TXBUSY or RTS_N; -- back preasure for data flow to tb + + N2CORE : entity work.tb_nexys2_core + port map ( + I_SWI => I_SWI, + I_BTN => I_BTN, + O_MEM_CE_N => O_MEM_CE_N, + O_MEM_BE_N => O_MEM_BE_N, + O_MEM_WE_N => O_MEM_WE_N, + O_MEM_OE_N => O_MEM_OE_N, + O_MEM_ADV_N => O_MEM_ADV_N, + O_MEM_CLK => O_MEM_CLK, + O_MEM_CRE => O_MEM_CRE, + I_MEM_WAIT => I_MEM_WAIT, + O_FLA_CE_N => O_FLA_CE_N, + O_MEM_ADDR => O_MEM_ADDR, + IO_MEM_DATA => IO_MEM_DATA + ); + + UUT : nexys2_fusp_aif + port map ( + CLK => CLK, + I_RXD => I_RXD, + O_TXD => O_TXD, + I_SWI => I_SWI, + I_BTN => I_BTN, + O_LED => O_LED, + O_ANO_N => O_ANO_N, + O_SEG_N => O_SEG_N, + O_MEM_CE_N => O_MEM_CE_N, + O_MEM_BE_N => O_MEM_BE_N, + O_MEM_WE_N => O_MEM_WE_N, + O_MEM_OE_N => O_MEM_OE_N, + O_MEM_ADV_N => O_MEM_ADV_N, + O_MEM_CLK => O_MEM_CLK, + O_MEM_CRE => O_MEM_CRE, + I_MEM_WAIT => I_MEM_WAIT, + O_FLA_CE_N => O_FLA_CE_N, + O_MEM_ADDR => O_MEM_ADDR, + IO_MEM_DATA => IO_MEM_DATA, + O_FUSP_RTS_N => O_FUSP_RTS_N, + I_FUSP_CTS_N => I_FUSP_CTS_N, + I_FUSP_RXD => I_FUSP_RXD, + O_FUSP_TXD => O_FUSP_TXD + ); + + UART : serport_uart_rxtx + generic map ( + CDWIDTH => CLKDIV'length) + port map ( + CLK => CLK, + RESET => UART_RESET, + CLKDIV => CLKDIV, + RXSD => UART_RXD, + RXDATA => RXDATA, + RXVAL => RXVAL, + RXERR => RXERR, + RXACT => RXACT, + TXSD => UART_TXD, + TXDATA => TXDATA, + TXENA => TXENA, + TXBUSY => TXBUSY + ); + + proc_port_mux: process (R_PORTSEL, UART_TXD, CTS_N, + O_TXD, O_FUSP_TXD, O_FUSP_RTS_N) + begin + + if R_PORTSEL = '0' then -- use main board rs232, no flow cntl + I_RXD <= UART_TXD; -- write port 0 inputs + UART_RXD <= O_TXD; -- get port 0 outputs + RTS_N <= '0'; + I_FUSP_RXD <= '1'; -- port 1 inputs to idle state + I_FUSP_CTS_N <= '0'; + else -- otherwise use pmod1 rs232 + I_FUSP_RXD <= UART_TXD; -- write port 1 inputs + I_FUSP_CTS_N <= CTS_N; + UART_RXD <= O_FUSP_TXD; -- get port 1 outputs + RTS_N <= O_FUSP_RTS_N; + I_RXD <= '1'; -- port 0 inputs to idle state + end if; + + end process proc_port_mux; + + proc_moni: process + variable oline : line; + begin + + loop + wait until CLK'event and CLK='1'; + wait for c2out_time; + + if RXERR = '1' then + writetimestamp(oline, SB_CLKCYCLE, " : seen RXERR=1"); + writeline(output, oline); + end if; + + end loop; + + end process proc_moni; + + proc_simbus: process (SB_VAL) + begin + if SB_VAL'event and to_x01(SB_VAL)='1' then + if SB_ADDR = sbaddr_portsel then + R_PORTSEL <= to_x01(SB_DATA(0)); + end if; + end if; + end process proc_simbus; + +end sim; diff --git a/rtl/bplib/nexys2/tb/tbw.dat b/rtl/bplib/nexys2/tb/tbw.dat new file mode 100644 index 00000000..d0b30cf5 --- /dev/null +++ b/rtl/bplib/nexys2/tb/tbw.dat @@ -0,0 +1,4 @@ +# $Id: tbw.dat 311 2010-06-30 17:52:37Z mueller $ +# +[tb_n2_cram_memctl_as] +tb_n2_cram_memctl_stim = tb_n2_cram_memctl_stim.dat diff --git a/rtl/bplib/s3board/Makefile b/rtl/bplib/s3board/Makefile new file mode 100644 index 00000000..a9d8c172 --- /dev/null +++ b/rtl/bplib/s3board/Makefile @@ -0,0 +1,24 @@ +# $Id: Makefile 311 2010-06-30 17:52:37Z mueller $ +# +# Revision History: +# Date Rev Version Comment +# 2007-12-09 100 1.0.1 drop ISE_p definition +# 2007-09-16 83 1.0 Initial version +# +VBOM_all = $(wildcard *.vbom) +NGC_all = $(VBOM_all:.vbom=.ngc) +# +ISE_PATH = xc3s1000-ft256-4 +# +.phony : all clean +# +all : $(NGC_all) +# +clean : ise_clean +# +#---- +# +include $(RETROBASE)/rtl/vlib/Makefile.xflow +# +include $(VBOM_all:.vbom=.dep_xst) +# diff --git a/rtl/bplib/s3board/s3_dispdrv.vbom b/rtl/bplib/s3board/s3_dispdrv.vbom new file mode 100644 index 00000000..179d4b58 --- /dev/null +++ b/rtl/bplib/s3board/s3_dispdrv.vbom @@ -0,0 +1,5 @@ +# libs +../../vlib/slvtypes.vhd +# components +# design +s3_dispdrv.vhd diff --git a/rtl/bplib/s3board/s3_dispdrv.vhd b/rtl/bplib/s3board/s3_dispdrv.vhd new file mode 100644 index 00000000..0d8fa4c4 --- /dev/null +++ b/rtl/bplib/s3board/s3_dispdrv.vhd @@ -0,0 +1,151 @@ +-- $Id: s3_dispdrv.vhd 314 2010-07-09 17:38:41Z mueller $ +-- +-- Copyright 2007-2010 by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, 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 complete details. +-- +------------------------------------------------------------------------------ +-- Module Name: s3_dispdrv - syn +-- Description: s3board: 7 segment display driver +-- +-- Dependencies: - +-- Test bench: - +-- Target Devices: generic +-- Tool versions: xst 8.1, 8.2, 9.1, 9.2, 11.4; ghdl 0.18-0.26 +-- Revision History: +-- Date Rev Version Comment +-- 2010-04-17 278 1.1.1 renamed from dispdrv +-- 2010-03-29 272 1.1 add all ANO off time to allow to driver turn-off +-- delay and to avoid cross talk between digits +-- 2007-12-16 101 1.0.1 use _N for active low +-- 2007-09-16 83 1.0 Initial version +------------------------------------------------------------------------------ + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; + +use work.slvtypes.all; + +entity s3_dispdrv is -- 7 segment display driver + generic ( + CDWIDTH : positive := 6); -- clk divider width (must be >= 5) + port ( + CLK : in slbit; -- clock + DIN : in slv16; -- data + DP : in slv4; -- decimal points + ANO_N : out slv4; -- anodes (act.low) + SEG_N : out slv8 -- segements (act.low) + ); +end s3_dispdrv; + +architecture syn of s3_dispdrv is + + type regs_type is record + cdiv : std_logic_vector(CDWIDTH-1 downto 0); -- clock divider counter + dcnt : slv2; -- digit counter + end record regs_type; + + constant regs_init : regs_type := ( + conv_std_logic_vector(0,CDWIDTH), + (others=>'0') + ); + + type hex2segtbl_type is array (0 to 15) of slv7; + + constant hex2segtbl : hex2segtbl_type := + ("0111111", -- 0: "0000" + "0000110", -- 1: "0001" + "1011011", -- 2: "0010" + "1001111", -- 3: "0011" + "1100110", -- 4: "0100" + "1101101", -- 5: "0101" + "1111101", -- 6: "0110" + "0000111", -- 7: "0111" + "1111111", -- 8: "1000" + "1101111", -- 9: "1001" + "1110111", -- a: "1010" + "1111100", -- b: "1011" + "0111001", -- c: "1100" + "1011110", -- d: "1101" + "1111001", -- e: "1110" + "1110001" -- f: "1111" + ); + + signal R_REGS : regs_type := regs_init; -- state registers + signal N_REGS : regs_type := regs_init; -- next value state regs + +begin + + assert CDWIDTH >= 5 + report "assert(CDWIDTH >= 5): CDWIDTH too small" + severity FAILURE; + + proc_regs: process (CLK) + begin + + if CLK'event and CLK='1' then + R_REGS <= N_REGS; + end if; + + end process proc_regs; + + + proc_next: process (R_REGS, DIN, DP) + + variable r : regs_type := regs_init; + variable n : regs_type := regs_init; + variable cano : slv4 := "0000"; + variable chex : slv4 := "0000"; + variable cdp : slbit := '0'; + + begin + + r := R_REGS; + n := R_REGS; + + n.cdiv := unsigned(r.cdiv) - 1; + if unsigned(r.cdiv) = 0 then + n.dcnt := unsigned(r.dcnt) + 1; + end if; + + chex := "0000"; + cdp := '0'; + + case r.dcnt is + when "00" => chex := DIN( 3 downto 0); cdp := DP(0); + when "01" => chex := DIN( 7 downto 4); cdp := DP(1); + when "10" => chex := DIN(11 downto 8); cdp := DP(2); + when "11" => chex := DIN(15 downto 12); cdp := DP(3); + when others => chex := "----"; cdp := '-'; + end case; + + -- the logic below ensures that the anode PNP driver transistor is switched + -- off 16 cycles before the cathode drivers change. This prevents 'cross + -- talk' between digits due to transistor turn off delays. With no or 4 + -- cycles gap one gets well visible cross talk, with 8 cycles still some + -- weak cross talk. With 16 cycles (at 50MHz) none is visible. The + -- turn-off delay of the anode driver PNP's this therefore larger 160 ns + -- and below 320 ns. + -- As consquence CDWIDTH should be at least 5, better 6. + + cano := "1111"; + if unsigned(r.cdiv) >= 16 then + cano(conv_integer(unsigned(r.dcnt))) := '0'; + end if; + + N_REGS <= n; + + ANO_N <= cano; + SEG_N <= not (cdp & hex2segtbl(conv_integer(unsigned(chex)))); + + end process proc_next; + +end syn; diff --git a/rtl/bplib/s3board/s3_humanio.vbom b/rtl/bplib/s3board/s3_humanio.vbom new file mode 100644 index 00000000..7e851fe2 --- /dev/null +++ b/rtl/bplib/s3board/s3_humanio.vbom @@ -0,0 +1,13 @@ +# libs +../../vlib/slvtypes.vhd +../../vlib/genlib/genlib.vhd +../../vlib/xlib/xlib.vhd +s3boardlib.vbom +## sys_conf : sys_conf.vhd +# components +../../vlib/xlib/iob_reg_i_gen.vbom +../../vlib/xlib/iob_reg_o_gen.vbom +../../vlib/genlib/debounce_gen.vbom +s3_dispdrv.vbom +# design +s3_humanio.vhd diff --git a/rtl/bplib/s3board/s3_humanio.vhd b/rtl/bplib/s3board/s3_humanio.vhd new file mode 100644 index 00000000..5165a65b --- /dev/null +++ b/rtl/bplib/s3board/s3_humanio.vhd @@ -0,0 +1,147 @@ +-- $Id: s3_humanio.vhd 314 2010-07-09 17:38:41Z mueller $ +-- +-- Copyright 2010- by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, 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 complete details. +-- +------------------------------------------------------------------------------ +-- Module Name: s3_humanio - syn +-- Description: All BTN, SWI, LED and DSP handling for s3board +-- +-- Dependencies: xlib/iob_reg_i_gen +-- xlib/iob_reg_o_gen +-- genlib/debounce_gen +-- s3board/s3_dispdrv +-- +-- Test bench: - +-- +-- Target Devices: generic +-- Tool versions: xst 11.4; ghdl 0.26 +-- +-- Synthesized (xst): +-- Date Rev ise Target flop lutl lutm slic t peri +-- 2010-04-10 275 11.4 L68 xc3s1000-4 80 87 0 53 s 5.2 ns +-- +-- Revision History: +-- Date Rev Version Comment +-- 2010-04-17 278 1.1.1 rename dispdrv -> s3_dispdrv +-- 2010-04-11 276 1.1 instantiate BTN/SWI debouncers via DEBOUNCE generic +-- 2010-04-10 275 1.0 Initial version +------------------------------------------------------------------------------ +-- + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; + +use work.slvtypes.all; +use work.xlib.all; +use work.genlib.all; +use work.s3boardlib.all; + +-- ---------------------------------------------------------------------------- + +entity s3_humanio is -- human i/o handling: swi,btn,led,dsp + generic ( + DEBOUNCE : boolean := true); -- instantiate debouncer for SWI,BTN + port ( + CLK : in slbit; -- clock + RESET : in slbit; -- reset + CE_MSEC : in slbit; -- 1 ms clock enable + SWI : out slv8; -- switch settings, debounced + BTN : out slv4; -- button settings, debounced + LED : in slv8; -- led data + DSP_DAT : in slv16; -- display data + DSP_DP : in slv4; -- display decimal points + I_SWI : in slv8; -- pad-i: switches + I_BTN : in slv4; -- pad-i: buttons + O_LED : out slv8; -- pad-o: leds + O_ANO_N : out slv4; -- pad-o: 7 seg disp: anodes (act.low) + O_SEG_N : out slv8 -- pad-o: 7 seg disp: segments (act.low) + ); +end s3_humanio; + +architecture syn of s3_humanio is + + signal RI_SWI : slv8 := (others=>'0'); + signal RI_BTN : slv4 := (others=>'0'); + + signal N_ANO_N : slv4 := (others=>'0'); + signal N_SEG_N : slv8 := (others=>'0'); + +begin + + IOB_SWI : iob_reg_i_gen + generic map (DWIDTH => 8) + port map (CLK => CLK, CE => '1', DI => RI_SWI, PAD => I_SWI); + + IOB_BTN : iob_reg_i_gen + generic map (DWIDTH => 4) + port map (CLK => CLK, CE => '1', DI => RI_BTN, PAD => I_BTN); + + IOB_LED : iob_reg_o_gen + generic map (DWIDTH => 8) + port map (CLK => CLK, CE => '1', DO => LED, PAD => O_LED); + + IOB_ANO_N : iob_reg_o_gen + generic map (DWIDTH => 4) + port map (CLK => CLK, CE => '1', DO => N_ANO_N, PAD => O_ANO_N); + + IOB_SEG_N : iob_reg_o_gen + generic map (DWIDTH => 8) + port map (CLK => CLK, CE => '1', DO => N_SEG_N, PAD => O_SEG_N); + + DEB: if DEBOUNCE generate + + DEB_SWI : debounce_gen + generic map ( + CWIDTH => 2, + CEDIV => 3, + DWIDTH => 8) + port map ( + CLK => CLK, + RESET => RESET, + CE_INT => CE_MSEC, + DI => RI_SWI, + DO => SWI + ); + + DEB_BTN : debounce_gen + generic map ( + CWIDTH => 2, + CEDIV => 3, + DWIDTH => 4) + port map ( + CLK => CLK, + RESET => RESET, + CE_INT => CE_MSEC, + DI => RI_BTN, + DO => BTN + ); + + end generate DEB; + + NODEB: if not DEBOUNCE generate + SWI <= RI_SWI; + BTN <= RI_BTN; + end generate NODEB; + + DRV : s3_dispdrv + generic map ( + CDWIDTH => 6) + port map ( + CLK => CLK, + DIN => DSP_DAT, + DP => DSP_DP, + ANO_N => N_ANO_N, + SEG_N => N_SEG_N + ); + +end syn; diff --git a/rtl/bplib/s3board/s3_humanio_rri.vbom b/rtl/bplib/s3board/s3_humanio_rri.vbom new file mode 100644 index 00000000..a6246abe --- /dev/null +++ b/rtl/bplib/s3board/s3_humanio_rri.vbom @@ -0,0 +1,8 @@ +# libs +../../vlib/slvtypes.vhd +../../vlib/rri/rrilib.vhd +s3boardlib.vbom +# components +s3_humanio.vbom +# design +s3_humanio_rri.vhd diff --git a/rtl/bplib/s3board/s3_humanio_rri.vhd b/rtl/bplib/s3board/s3_humanio_rri.vhd new file mode 100644 index 00000000..e38b2a20 --- /dev/null +++ b/rtl/bplib/s3board/s3_humanio_rri.vhd @@ -0,0 +1,277 @@ +-- $Id: s3_humanio_rri.vhd 314 2010-07-09 17:38:41Z mueller $ +-- +-- Copyright 2010- by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, 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 complete details. +-- +------------------------------------------------------------------------------ +-- Module Name: s3_humanio_rri - syn +-- Description: s3_humanio with rri interceptor +-- +-- Dependencies: s3board/s3_humanio +-- +-- Test bench: - +-- +-- Target Devices: generic +-- Tool versions: xst 11.4; ghdl 0.26 +-- +-- Synthesized (xst): +-- Date Rev ise Target flop lutl lutm slic t peri +-- 2010-06-03 300 11.4 L68 xc3s1000-4 92 137 0 111 s 6.7 ns +-- +-- Revision History: +-- Date Rev Version Comment +-- 2010-06-18 306 1.0.1 rename rbus data fields to _rbf_ +-- 2010-06-03 300 1.0 Initial version +------------------------------------------------------------------------------ +-- +-- rbus registers: +-- +-- Address Bits Name r/w/f Function +-- bbbbbb00 cntl r/w/- Control register and BTN access +-- 11 dat_en r/w/- if 1 display data will be driven by rri +-- 10 dp_en r/w/- if 1 display dp's will be driven by rri +-- 9 led_en r/w/- if 1 LED will be driven by rri +-- 8 swi_en r/w/- if 1 SWI will be driven by rri +-- 3:00 btn r/w/- r: return hio BTN status +-- w: BTN is hio BTN ored with this fields +-- +-- bbbbbb01 7:00 swi r/w/- r: return hio SWI status +-- w: will drive SWI when swi_en=1 +-- +-- bbbbbb10 leddp r/w/- interface to LED and DSP_DP +-- 11:09 dsp_dp r/w/- r: returns DSP_DP status +-- w: will drive display dp's when dp_en=1 +-- 7:00 led r/w/- r: returns LED status +-- w: will drive led's when led_en=1 +-- +-- bbbbbb11 15:00 dsp_dat r/w/- r: return hio DSP_DAT status +-- w: will drive DSP_DAT when dat_en=1 +-- + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; + +use work.slvtypes.all; +use work.rrilib.all; +use work.s3boardlib.all; + +-- ---------------------------------------------------------------------------- + +entity s3_humanio_rri is -- human i/o handling with rri intercept + generic ( + DEBOUNCE : boolean := true; -- instantiate debouncer for SWI,BTN + RB_ADDR : slv8 := conv_std_logic_vector(2#10000000#,8)); + port ( + CLK : in slbit; -- clock + RESET : in slbit; -- reset + CE_MSEC : in slbit; -- 1 ms clock enable + RB_MREQ : in rb_mreq_type; -- rbus: request + RB_SRES : out rb_sres_type; -- rbus: response + SWI : out slv8; -- switch settings, debounced + BTN : out slv4; -- button settings, debounced + LED : in slv8; -- led data + DSP_DAT : in slv16; -- display data + DSP_DP : in slv4; -- display decimal points + I_SWI : in slv8; -- pad-i: switches + I_BTN : in slv4; -- pad-i: buttons + O_LED : out slv8; -- pad-o: leds + O_ANO_N : out slv4; -- pad-o: 7 seg disp: anodes (act.low) + O_SEG_N : out slv8 -- pad-o: 7 seg disp: segments (act.low) + ); +end s3_humanio_rri; + +architecture syn of s3_humanio_rri is + + type regs_type is record + swi : slv8; -- rri swi + btn : slv4; -- rri btn + led : slv8; -- rri led + dsp_dat : slv16; -- rri dsp_dat + dsp_dp : slv4; -- rri dsp_dp + swi_en : slbit; -- enable: swi from rri + led_en : slbit; -- enable: led from rri + dat_en : slbit; -- enable: dsp_dat from rri + dp_en : slbit; -- enable: dsp_dp from rri + end record regs_type; + + constant regs_init : regs_type := ( + (others=>'0'), -- swi + (others=>'0'), -- btn + (others=>'0'), -- led + (others=>'0'), -- dsp_dat + (others=>'0'), -- dsp_dp + '0','0','0','0' -- (swi|led|dat|dp)_en + ); + + signal R_REGS : regs_type := regs_init; -- state registers + signal N_REGS : regs_type := regs_init; -- next value state regs + + constant cntl_rbf_dat_en: integer := 11; + constant cntl_rbf_dp_en: integer := 10; + constant cntl_rbf_led_en: integer := 9; + constant cntl_rbf_swi_en: integer := 8; + subtype cntl_rbf_btn is integer range 3 downto 0; + subtype leddp_rbf_dsp_dp is integer range 11 downto 8; + subtype leddp_rbf_led is integer range 7 downto 0; + + constant rbaddr_cntl: slv2 := "00"; -- 0 -/r/w + constant rbaddr_swi: slv2 := "01"; -- 1 -/r/w + constant rbaddr_leddp: slv2 := "10"; -- 2 -/r/w + constant rbaddr_dsp: slv2 := "11"; -- 3 -/r/w + + signal HIO_SWI : slv8 := (others=>'0'); + signal HIO_BTN : slv4 := (others=>'0'); + signal HIO_LED : slv8 := (others=>'0'); + signal HIO_DSP_DAT : slv16 := (others=>'0'); + signal HIO_DSP_DP : slv4 := (others=>'0'); + +begin + + HIO : s3_humanio + generic map ( + DEBOUNCE => DEBOUNCE) + port map ( + CLK => CLK, + RESET => RESET, + CE_MSEC => CE_MSEC, + SWI => HIO_SWI, + BTN => HIO_BTN, + LED => HIO_LED, + DSP_DAT => HIO_DSP_DAT, + DSP_DP => HIO_DSP_DP, + I_SWI => I_SWI, + I_BTN => I_BTN, + O_LED => O_LED, + O_ANO_N => O_ANO_N, + O_SEG_N => O_SEG_N + ); + + proc_regs: process (CLK) + begin + + if CLK'event and CLK='1' then + if RESET = '1' then + R_REGS <= regs_init; + else + R_REGS <= N_REGS; + end if; + end if; + + end process proc_regs; + + proc_next: process (R_REGS, RB_MREQ, LED, DSP_DAT, DSP_DP, + HIO_SWI, HIO_BTN, HIO_LED, HIO_DSP_DAT, HIO_DSP_DP) + + variable r : regs_type := regs_init; + variable n : regs_type := regs_init; + + variable irb_sel : slbit := '0'; + variable irb_ack : slbit := '0'; + variable irb_busy : slbit := '0'; + variable irb_err : slbit := '0'; + variable irb_dout : slv16 := (others=>'0'); + + begin + + r := R_REGS; + n := R_REGS; + + irb_sel := '0'; + irb_ack := '0'; + irb_busy := '0'; + irb_err := '0'; + irb_dout := (others=>'0'); + + if RB_MREQ.req='1' and RB_MREQ.addr(7 downto 2)=RB_ADDR(7 downto 2) then + irb_sel := '1'; + irb_ack := '1'; + end if; + + if irb_sel = '1' then + case RB_MREQ.addr(1 downto 0) is + + when rbaddr_cntl => + irb_dout(cntl_rbf_dat_en) := r.dat_en; + irb_dout(cntl_rbf_dp_en) := r.dp_en; + irb_dout(cntl_rbf_led_en) := r.led_en; + irb_dout(cntl_rbf_swi_en) := r.swi_en; + irb_dout(cntl_rbf_btn) := HIO_BTN; + if RB_MREQ.we = '1' then + n.dat_en := RB_MREQ.din(cntl_rbf_dat_en); + n.dp_en := RB_MREQ.din(cntl_rbf_dp_en); + n.led_en := RB_MREQ.din(cntl_rbf_led_en); + n.swi_en := RB_MREQ.din(cntl_rbf_swi_en); + n.btn := RB_MREQ.din(cntl_rbf_btn); + end if; + + when rbaddr_swi => + irb_dout(HIO_SWI'range) := HIO_SWI; + if RB_MREQ.we = '1' then + n.swi := RB_MREQ.din(n.swi'range); + end if; + + when rbaddr_leddp => + irb_dout(leddp_rbf_dsp_dp) := HIO_DSP_DP; + irb_dout(leddp_rbf_led) := HIO_LED; + if RB_MREQ.we = '1' then + n.dsp_dp := RB_MREQ.din(leddp_rbf_dsp_dp); + n.led := RB_MREQ.din(leddp_rbf_led); + end if; + + when rbaddr_dsp => + irb_dout := HIO_DSP_DAT; + if RB_MREQ.we = '1' then + n.dsp_dat := RB_MREQ.din; + end if; + + when others => null; + end case; + + end if; + + BTN <= HIO_BTN or r.btn; + + if r.swi_en = '0' then + SWI <= HIO_SWI; + else + SWI <= r.swi; + end if; + + if r.led_en = '0' then + HIO_LED <= LED; + else + HIO_LED <= r.led; + end if; + + if r.dp_en = '0' then + HIO_DSP_DP <= DSP_DP; + else + HIO_DSP_DP <= r.dsp_dp; + end if; + + if r.dat_en = '0' then + HIO_DSP_DAT <= DSP_DAT; + else + HIO_DSP_DAT <= r.dsp_dat; + end if; + + N_REGS <= n; + + RB_SRES <= rb_sres_init; + RB_SRES.ack <= irb_ack; + RB_SRES.busy <= irb_busy; + RB_SRES.err <= irb_err; + RB_SRES.dout <= irb_dout; + + end process proc_next; + +end syn; diff --git a/rtl/bplib/s3board/s3_rs232_iob_ext.vbom b/rtl/bplib/s3board/s3_rs232_iob_ext.vbom new file mode 100644 index 00000000..9aa5b882 --- /dev/null +++ b/rtl/bplib/s3board/s3_rs232_iob_ext.vbom @@ -0,0 +1,8 @@ +# libs +../../vlib/slvtypes.vhd +../../vlib/xlib/xlib.vhd +# components +../../vlib/xlib/iob_reg_i.vbom +../../vlib/xlib/iob_reg_o.vbom +# design +s3_rs232_iob_ext.vhd diff --git a/rtl/bplib/s3board/s3_rs232_iob_ext.vhd b/rtl/bplib/s3board/s3_rs232_iob_ext.vhd new file mode 100644 index 00000000..f2427457 --- /dev/null +++ b/rtl/bplib/s3board/s3_rs232_iob_ext.vhd @@ -0,0 +1,72 @@ +-- $Id: s3_rs232_iob_ext.vhd 314 2010-07-09 17:38:41Z mueller $ +-- +-- Copyright 2010- by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, 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 complete details. +-- +------------------------------------------------------------------------------ +-- Module Name: s3_rs232_iob_ext - syn +-- Description: iob's for external rs232 (PMod) +-- +-- Dependencies: xlib/iob_reg_i +-- xlib/iob_reg_o +-- +-- Test bench: - +-- +-- Target Devices: generic +-- Tool versions: xst 11.4; ghdl 0.26 +-- +-- Revision History: +-- Date Rev Version Comment +-- 2010-04-17 278 1.0 Initial version +------------------------------------------------------------------------------ +-- + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; + +use work.slvtypes.all; +use work.xlib.all; + +-- ---------------------------------------------------------------------------- + +entity s3_rs232_iob_ext is -- iob's for external rs232 (PMod) + port ( + CLK : in slbit; -- clock + RXD : out slbit; -- receive data (board view) + TXD : in slbit; -- transmit data (board view) + CTS_N : out slbit; -- clear to send (act. low) + RTS_N : in slbit; -- request to send (act. low) + I_RXD : in slbit; -- pad-i: receive data (board view) + O_TXD : out slbit; -- pad-o: transmit data (board view) + I_CTS_N : in slbit; -- pad-i: clear to send (act. low) + O_RTS_N : out slbit -- pad-o: request to send (act. low) + ); +end s3_rs232_iob_ext; + +architecture syn of s3_rs232_iob_ext is +begin + + IOB_RXD : iob_reg_i -- line idle=1, so init sync flop =1 + generic map (INIT => '1') + port map (CLK => CLK, CE => '1', DI => RXD, PAD => I_RXD); + + IOB_TXD : iob_reg_o -- line idle=1, so init sync flop =1 + generic map (INIT => '1') + port map (CLK => CLK, CE => '1', DO => TXD, PAD => O_TXD); + + IOB_CTS : iob_reg_i + port map (CLK => CLK, CE => '1', DI => CTS_N, PAD => I_CTS_N); + + IOB_RTS : iob_reg_o + port map (CLK => CLK, CE => '1', DO => RTS_N, PAD => O_RTS_N); + +end syn; diff --git a/rtl/bplib/s3board/s3_rs232_iob_int.vbom b/rtl/bplib/s3board/s3_rs232_iob_int.vbom new file mode 100644 index 00000000..45f225c4 --- /dev/null +++ b/rtl/bplib/s3board/s3_rs232_iob_int.vbom @@ -0,0 +1,8 @@ +# libs +../../vlib/slvtypes.vhd +../../vlib/xlib/xlib.vhd +# components +../../vlib/xlib/iob_reg_i.vbom +../../vlib/xlib/iob_reg_o.vbom +# design +s3_rs232_iob_int.vhd diff --git a/rtl/bplib/s3board/s3_rs232_iob_int.vhd b/rtl/bplib/s3board/s3_rs232_iob_int.vhd new file mode 100644 index 00000000..8149c645 --- /dev/null +++ b/rtl/bplib/s3board/s3_rs232_iob_int.vhd @@ -0,0 +1,62 @@ +-- $Id: s3_rs232_iob_int.vhd 314 2010-07-09 17:38:41Z mueller $ +-- +-- Copyright 2010- by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, 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 complete details. +-- +------------------------------------------------------------------------------ +-- Module Name: s3_rs232_iob_int - syn +-- Description: iob's for internal rs232 +-- +-- Dependencies: xlib/iob_reg_i +-- xlib/iob_reg_o +-- +-- Test bench: - +-- +-- Target Devices: generic +-- Tool versions: xst 11.4; ghdl 0.26 +-- +-- Revision History: +-- Date Rev Version Comment +-- 2010-04-17 278 1.0 Initial version +------------------------------------------------------------------------------ +-- + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; + +use work.slvtypes.all; +use work.xlib.all; + +-- ---------------------------------------------------------------------------- + +entity s3_rs232_iob_int is -- iob's for internal rs232 + port ( + CLK : in slbit; -- clock + RXD : out slbit; -- receive data (board view) + TXD : in slbit; -- transmit data (board view) + I_RXD : in slbit; -- pad-i: receive data (board view) + O_TXD : out slbit -- pad-o: transmit data (board view) + ); +end s3_rs232_iob_int; + +architecture syn of s3_rs232_iob_int is +begin + + IOB_RXD : iob_reg_i -- line idle=1, so init sync flop =1 + generic map (INIT => '1') + port map (CLK => CLK, CE => '1', DI => RXD, PAD => I_RXD); + + IOB_TXD : iob_reg_o -- line idle=1, so init sync flop =1 + generic map (INIT => '1') + port map (CLK => CLK, CE => '1', DO => TXD, PAD => O_TXD); + +end syn; diff --git a/rtl/bplib/s3board/s3_rs232_iob_int_ext.vbom b/rtl/bplib/s3board/s3_rs232_iob_int_ext.vbom new file mode 100644 index 00000000..6f32190c --- /dev/null +++ b/rtl/bplib/s3board/s3_rs232_iob_int_ext.vbom @@ -0,0 +1,8 @@ +# libs +../../vlib/slvtypes.vhd +s3boardlib.vbom +# components +s3_rs232_iob_int.vbom +s3_rs232_iob_ext.vbom +# design +s3_rs232_iob_int_ext.vhd diff --git a/rtl/bplib/s3board/s3_rs232_iob_int_ext.vhd b/rtl/bplib/s3board/s3_rs232_iob_int_ext.vhd new file mode 100644 index 00000000..bee6cf07 --- /dev/null +++ b/rtl/bplib/s3board/s3_rs232_iob_int_ext.vhd @@ -0,0 +1,106 @@ +-- $Id: s3_rs232_iob_int_ext.vhd 314 2010-07-09 17:38:41Z mueller $ +-- +-- Copyright 2010- by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, 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 complete details. +-- +------------------------------------------------------------------------------ +-- Module Name: s3_rs232_iob_int_ext - syn +-- Description: iob's for internal + external rs232, with select +-- +-- Dependencies: s3_rs232_iob_int +-- s3_rs232_iob_ext +-- +-- Test bench: - +-- +-- Target Devices: generic +-- Tool versions: xst 11.4; ghdl 0.26 +-- +-- Revision History: +-- Date Rev Version Comment +-- 2010-04-17 278 1.0 Initial version +------------------------------------------------------------------------------ +-- + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; + +use work.slvtypes.all; +use work.s3boardlib.all; + +-- ---------------------------------------------------------------------------- + +entity s3_rs232_iob_int_ext is -- iob's for int+ext rs232, with select + port ( + CLK : in slbit; -- clock + SEL : in slbit; -- select, '0' for port 0 + RXD : out slbit; -- receive data (board view) + TXD : in slbit; -- transmit data (board view) + CTS_N : out slbit; -- clear to send (act. low) + RTS_N : in slbit; -- request to send (act. low) + I_RXD0 : in slbit; -- pad-i: p0: receive data (board view) + O_TXD0 : out slbit; -- pad-o: p0: transmit data (board view) + I_RXD1 : in slbit; -- pad-i: p1: receive data (board view) + O_TXD1 : out slbit; -- pad-o: p1: transmit data (board view) + I_CTS1_N : in slbit; -- pad-i: p1: clear to send (act. low) + O_RTS1_N : out slbit -- pad-o: p1: request to send (act. low) + ); +end s3_rs232_iob_int_ext; + +architecture syn of s3_rs232_iob_int_ext is + signal RXD0 : slbit := '0'; + signal TXD0 : slbit := '0'; + signal RXD1 : slbit := '0'; + signal TXD1 : slbit := '0'; + signal CTS1_N : slbit := '0'; + signal RTS1_N : slbit := '0'; +begin + + P0 : s3_rs232_iob_int + port map ( + CLK => CLK, + RXD => RXD0, + TXD => TXD0, + I_RXD => I_RXD0, + O_TXD => O_TXD0 + ); + + P1 : s3_rs232_iob_ext + port map ( + CLK => CLK, + RXD => RXD1, + TXD => TXD1, + CTS_N => CTS1_N, + RTS_N => RTS1_N, + I_RXD => I_RXD1, + O_TXD => O_TXD1, + I_CTS_N => I_CTS1_N, + O_RTS_N => O_RTS1_N + ); + + proc_port_mux: process (SEL, RXD0, TXD, RXD1, CTS1_N, RTS_N) + begin + if SEL = '0' then -- use main board rs232, no flow cntl + RXD <= RXD0; -- get port 0 inputs + CTS_N <= '0'; + TXD0 <= TXD; -- set port 0 output + TXD1 <= '1'; -- port 1 outputs to idle state + RTS1_N <= '0'; + else -- otherwise use pmod1 rs232 + RXD <= RXD1; -- get port 1 inputs + CTS_N <= CTS1_N; + TXD1 <= TXD; -- set port 1 outputs + RTS1_N <= RTS_N; + TXD0 <= '1'; -- port 0 output to idle state + end if; + end process proc_port_mux; + +end syn; diff --git a/rtl/bplib/s3board/s3_sram_dummy.vbom b/rtl/bplib/s3board/s3_sram_dummy.vbom new file mode 100644 index 00000000..38df1493 --- /dev/null +++ b/rtl/bplib/s3board/s3_sram_dummy.vbom @@ -0,0 +1,5 @@ +# libs +../../vlib/slvtypes.vhd +# components +# design +s3_sram_dummy.vhd diff --git a/rtl/bplib/s3board/s3_sram_dummy.vhd b/rtl/bplib/s3board/s3_sram_dummy.vhd new file mode 100644 index 00000000..3389e2ab --- /dev/null +++ b/rtl/bplib/s3board/s3_sram_dummy.vhd @@ -0,0 +1,57 @@ +-- $Id: s3_sram_dummy.vhd 314 2010-07-09 17:38:41Z mueller $ +-- +-- Copyright 2007-2010 by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, 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 complete details. +-- +------------------------------------------------------------------------------ +-- Module Name: s3_sram_dummy - syn +-- Description: s3board: SRAM protection dummy +-- +-- Dependencies: - +-- Test bench: - +-- Target Devices: generic +-- Tool versions: xst 8.1, 8.2, 9.1, 9.2, 11.4; ghdl 0.18-0.26 +-- Revision History: +-- Date Rev Version Comment +-- 2010-04-17 278 1.0.2 renamed from sram_dummy +-- 2007-12-09 101 1.0.1 use _N for active low +-- 2007-12-08 100 1.0 Initial version +------------------------------------------------------------------------------ + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; + +use work.slvtypes.all; + +entity s3_sram_dummy is -- SRAM protection dummy + port ( + O_MEM_CE_N : out slv2; -- sram: chip enables (act.low) + O_MEM_BE_N : out slv4; -- sram: byte enables (act.low) + O_MEM_WE_N : out slbit; -- sram: write enable (act.low) + O_MEM_OE_N : out slbit; -- sram: output enable (act.low) + O_MEM_ADDR : out slv18; -- sram: address lines + IO_MEM_DATA : inout slv32 -- sram: data lines + ); +end s3_sram_dummy; + + +architecture syn of s3_sram_dummy is +begin + + O_MEM_CE_N <= "11"; -- disable sram chips + O_MEM_BE_N <= "1111"; + O_MEM_WE_N <= '1'; + O_MEM_OE_N <= '1'; + O_MEM_ADDR <= (others=>'0'); + IO_MEM_DATA <= (others=>'0'); + +end syn; diff --git a/rtl/bplib/s3board/s3_sram_memctl.vbom b/rtl/bplib/s3board/s3_sram_memctl.vbom new file mode 100644 index 00000000..89f13132 --- /dev/null +++ b/rtl/bplib/s3board/s3_sram_memctl.vbom @@ -0,0 +1,9 @@ +# libs +../../vlib/slvtypes.vhd +../../vlib/xlib/xlib.vhd +# components +../../vlib/xlib/iob_reg_o.vbom +../../vlib/xlib/iob_reg_o_gen.vbom +../../vlib/xlib/iob_reg_io_gen.vbom +# design +s3_sram_memctl.vhd diff --git a/rtl/bplib/s3board/s3_sram_memctl.vhd b/rtl/bplib/s3board/s3_sram_memctl.vhd new file mode 100644 index 00000000..4e3208d7 --- /dev/null +++ b/rtl/bplib/s3board/s3_sram_memctl.vhd @@ -0,0 +1,365 @@ +-- $Id: s3_sram_memctl.vhd 314 2010-07-09 17:38:41Z mueller $ +-- +-- Copyright 2007-2010 by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, 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 complete details. +-- +------------------------------------------------------------------------------ +-- Module Name: s3_sram_memctl - syn +-- Description: s3board: SRAM driver +-- +-- Dependencies: vlib/xlib/iob_reg_o +-- vlib/xlib/iob_reg_o_gen +-- vlib/xlib/iob_reg_io_gen +-- Test bench: tb/tb_s3_sram_memctl +-- fw_gen/tst_sram/s3board/tb/tb_tst_sram_s3 +-- Target Devices: generic +-- Tool versions: xst 8.1, 8.2, 9.1, 9.2; ghdl 0.18-0.25 +-- +-- Synthesized (xst): +-- Date Rev ise Target flop lutl lutm slic t peri +-- 2010-05-23 293 11.4 L68 xc3s1000-4 7 22 0 14 s 8.5 +-- 2008-02-16 116 8.2.03 I34 xc3s1000-4 5 30 0 17 s 7.0 +-- +-- Revision History: +-- Date Rev Version Comment +-- 2010-06-03 299 1.0.5 add "KEEP" for data iob; +-- 2010-05-16 291 1.0.4 rename memctl_s3sram -> s3_sram_memctl +-- 2008-02-17 117 1.0.3 use req,we rather req_r,req_w interface +-- 2008-01-20 113 1.0.2 rename memdrv -> memctl_s3sram +-- 2007-12-15 101 1.0.1 use _N for active low; get ce/we clocking right +-- 2007-12-08 100 1.0 Initial version +-- +-- Timing of some signals: +-- +-- single read request: +-- +-- state |_idle |_read |_idle | +-- +-- CLK __|^^^|___|^^^|___|^^^|___|^ +-- +-- REQ _______|^^^^^|______________ +-- WE ____________________________ +-- +-- IOB_CE __________|^^^^^^^|_________ +-- IOB_OE __________|^^^^^^^|_________ +-- +-- DO oooooooooooooooooo|ddddddd|d +-- BUSY ____________________________ +-- ACK_R __________________|^^^^^^^|_ +-- +-- single write request: +-- +-- state |_idle |_write1|_write2|_idle | +-- +-- CLK __|^^^|___|^^^|___|^^^|___|^^^|___|^ +-- +-- REQ _______|^^^^^|______________ +-- WE _______|^^^^^|______________ +-- +-- IOB_CE __________|^^^^^^^^^^^^^^^|_________ +-- IOB_BE __________|^^^^^^^^^^^^^^^|_________ +-- IOB_OE ____________________________________ +-- IOB_WE ______________|^^^^^^^|_____________ +-- +-- BUSY __________|^^^^^^^|_________________ +-- ACK_W __________________|^^^^^^^|_________ +-- +------------------------------------------------------------------------------ + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; + +use work.slvtypes.all; +use work.xlib.all; + +entity s3_sram_memctl is -- SRAM driver for S3BOARD + port ( + CLK : in slbit; -- clock + RESET : in slbit; -- reset + REQ : in slbit; -- request + WE : in slbit; -- write enable + BUSY : out slbit; -- controller busy + ACK_R : out slbit; -- acknowledge read + ACK_W : out slbit; -- acknowledge write + ACT_R : out slbit; -- signal active read + ACT_W : out slbit; -- signal active write + ADDR : in slv18; -- address + BE : in slv4; -- byte enable + DI : in slv32; -- data in (memory view) + DO : out slv32; -- data out (memory view) + O_MEM_CE_N : out slv2; -- sram: chip enables (act.low) + O_MEM_BE_N : out slv4; -- sram: byte enables (act.low) + O_MEM_WE_N : out slbit; -- sram: write enable (act.low) + O_MEM_OE_N : out slbit; -- sram: output enable (act.low) + O_MEM_ADDR : out slv18; -- sram: address lines + IO_MEM_DATA : inout slv32 -- sram: data lines + ); +end s3_sram_memctl; + + +architecture syn of s3_sram_memctl is + + type state_type is ( + s_idle, -- s_idle: wait for req + s_read, -- s_read: read cycle + s_write1, -- s_write1: write cycle, 1st half + s_write2, -- s_write2: write cycle, 2nd half + s_bta_r2w, -- s_bta_r2w: bus turn around: r->w + s_bta_w2r -- s_bta_w2r: bus turn around: w->r + ); + + type regs_type is record + state : state_type; -- state + ackr : slbit; -- signal ack_r + end record regs_type; + + constant regs_init : regs_type := ( + s_idle, + '0' -- ackr + ); + + signal R_REGS : regs_type := regs_init; -- state registers + signal N_REGS : regs_type := regs_init; -- next value state regs + + signal CLK_180 : slbit := '0'; + signal MEM_CE_N : slv2 := "00"; + signal MEM_BE_N : slv4 := "0000"; + signal MEM_WE_N : slbit := '0'; + signal MEM_OE_N : slbit := '0'; + signal ADDR_CE : slbit := '0'; + signal DATA_CEI : slbit := '0'; + signal DATA_CEO : slbit := '0'; + signal DATA_OE : slbit := '0'; + +begin + + CLK_180 <= not CLK; + + IOB_MEM_CE : iob_reg_o_gen + generic map ( + DWIDTH => 2, + INIT => '1') + port map ( + CLK => CLK, + CE => '1', + DO => MEM_CE_N, + PAD => O_MEM_CE_N + ); + + IOB_MEM_BE : iob_reg_o_gen + generic map ( + DWIDTH => 4, + INIT => '1') + port map ( + CLK => CLK, + CE => ADDR_CE, + DO => MEM_BE_N, + PAD => O_MEM_BE_N + ); + + IOB_MEM_WE : iob_reg_o + generic map ( + INIT => '1') + port map ( + CLK => CLK_180, + CE => '1', + DO => MEM_WE_N, + PAD => O_MEM_WE_N + ); + + IOB_MEM_OE : iob_reg_o + generic map ( + INIT => '1') + port map ( + CLK => CLK, + CE => '1', + DO => MEM_OE_N, + PAD => O_MEM_OE_N + ); + + IOB_MEM_ADDR : iob_reg_o_gen + generic map ( + DWIDTH => 18) + port map ( + CLK => CLK, + CE => ADDR_CE, + DO => ADDR, + PAD => O_MEM_ADDR + ); + + IOB_MEM_DATA : iob_reg_io_gen + generic map ( + DWIDTH => 32, + PULL => "KEEP") + port map ( + CLK => CLK, + CEI => DATA_CEI, + CEO => DATA_CEO, + OE => DATA_OE, + DI => DO, + DO => DI, + PAD => IO_MEM_DATA + ); + + proc_regs: process (CLK) + begin + + if CLK'event and CLK='1' then + if RESET = '1' then + R_REGS <= regs_init; + else + R_REGS <= N_REGS; + end if; + end if; + + end process proc_regs; + + proc_next: process (R_REGS, REQ, WE, BE) + + variable r : regs_type := regs_init; + variable n : regs_type := regs_init; + variable ibusy : slbit := '0'; + variable iackw : slbit := '0'; + variable iactr : slbit := '0'; + variable iactw : slbit := '0'; + variable imem_ce : slv2 := "00"; + variable imem_be : slv4 := "0000"; + variable imem_we : slbit := '0'; + variable imem_oe : slbit := '0'; + variable iaddr_ce : slbit := '0'; + variable idata_cei : slbit := '0'; + variable idata_ceo : slbit := '0'; + variable idata_oe : slbit := '0'; + + begin + + r := R_REGS; + n := R_REGS; + n.ackr := '0'; + + ibusy := '0'; + iackw := '0'; + iactr := '0'; + iactw := '0'; + + imem_ce := "00"; + imem_be := "1111"; + imem_we := '0'; + imem_oe := '0'; + iaddr_ce := '0'; + idata_cei := '0'; + idata_ceo := '0'; + idata_oe := '0'; + + case r.state is + when s_idle => -- s_idle: wait for req + if REQ = '1' then -- if IO requested + if WE = '0' then -- if READ requested + iaddr_ce := '1'; -- latch address and be's + imem_ce := "11"; -- ce SRAM next cycle + imem_oe := '1'; -- oe SRAM next cycle + n.state := s_read; -- next: read + else -- if WRITE requested + iaddr_ce := '1'; -- latch address and be's + idata_ceo := '1'; -- latch output data + idata_oe := '1'; -- oe FPGA next cycle + imem_ce := "11"; -- ce SRAM next cycle + imem_be := BE; -- use request BE's + n.state := s_write1; -- next: write 1st part + end if; + end if; + + when s_read => -- s_read: read cycle + idata_cei := '1'; -- latch input data + iactr := '1'; -- signal mem read + n.ackr := '1'; -- ACK_R next cycle + if REQ = '1' then -- if IO requested + if WE = '0' then -- if READ requested + iaddr_ce := '1'; -- latch address and be's + imem_ce := "11"; -- ce SRAM next cycle + imem_oe := '1'; -- oe SRAM next cycle + n.state := s_read; -- next: continue read + else -- if WRITE requested + iaddr_ce := '1'; -- latch address and be's + idata_ceo := '1'; -- latch output data + imem_be := BE; -- use request BE's + n.state := s_bta_r2w; -- next: bus turn around cycle + end if; + else + n.state := s_idle; -- next: idle if nothing to do + end if; + + when s_write1 => -- s_write1: write cycle, 1st half + ibusy := '1'; -- signal busy, unable to handle req + iactw := '1'; -- signal mem write + idata_oe := '1'; -- oe FPGA next cycle + imem_ce := "11"; -- ce SRAM next cycle + imem_we := '1'; -- we SRAM next shifted cycle + n.state := s_write2; -- next: write cycle, 2nd half + + when s_write2 => -- s_write2: write cycle, 2nd half + iactw := '1'; -- signal mem write + iackw := '1'; -- signal write acknowledge + idata_cei := '1'; -- latch input data (from SRAM) + if REQ = '1' then -- if IO requested + if WE = '1' then -- if WRITE requested + iaddr_ce := '1'; -- latch address and be's + idata_ceo := '1'; -- latch output data + idata_oe := '1'; -- oe FPGA next cycle + imem_ce := "11"; -- ce SRAM next cycle + imem_be := BE; -- use request BE's + n.state := s_write1; -- next: continue read + else -- if READ requested + iaddr_ce := '1'; -- latch address and be's + n.state := s_bta_w2r; -- next: bus turn around cycle + end if; + else + n.state := s_idle; -- next: idle if nothing to do + end if; + + when s_bta_r2w => -- s_bta_r2w: bus turn around: r->w + ibusy := '1'; -- signal busy, unable to handle req + iactw := '1'; -- signal mem write + imem_ce := "11"; -- ce SRAM next cycle + idata_oe := '1'; -- oe FPGA next cycle + n.state := s_write1; -- next: start write + + when s_bta_w2r => -- s_bta_w2r: bus turn around: w->r + ibusy := '1'; -- signal busy, unable to handle req + iactr := '1'; -- signal mem read + imem_ce := "11"; -- ce SRAM next cycle + imem_oe := '1'; -- oe SRAM next cycle + n.state := s_read; -- next: start read + + when others => null; + end case; + + N_REGS <= n; + + MEM_CE_N <= not imem_ce; + MEM_WE_N <= not imem_we; + MEM_BE_N <= not imem_be; + MEM_OE_N <= not imem_oe; + ADDR_CE <= iaddr_ce; + DATA_CEI <= idata_cei; + DATA_CEO <= idata_ceo; + DATA_OE <= idata_oe; + + BUSY <= ibusy; + ACK_R <= r.ackr; + ACK_W <= iackw; + ACT_R <= iactr; + ACT_W <= iactw; + + end process proc_next; + +end syn; diff --git a/rtl/bplib/s3board/s3board_a2_pm1_rs232.ucf b/rtl/bplib/s3board/s3board_a2_pm1_rs232.ucf new file mode 100644 index 00000000..4755234c --- /dev/null +++ b/rtl/bplib/s3board/s3board_a2_pm1_rs232.ucf @@ -0,0 +1,15 @@ +## $Id: s3board_a2_pm1_rs232.ucf 311 2010-06-30 17:52:37Z mueller $ +## +## Revision History: +## Date Rev Version Comment +## 2010-05-22 293 1.1 Rename PM1 -> FUSP +## 2010-04-24 281 1.0 Initial version +## +## expansion connector A2 / slot PMod 1 / usage RS232 for FTDI USB serport --- +## +## PmodRS232: pins: 1 RTS; 2 CTS; 3 RXD; 4 TXD; 5 GND; 6 VCC +## +NET "O_FUSP_RTS_N" LOC = "c6" | IOSTANDARD=LVCMOS33 | DRIVE=4 | SLEW=SLOW; +NET "I_FUSP_CTS_N" LOC = "e7" | IOSTANDARD=LVCMOS33 | PULLDOWN; +NET "I_FUSP_RXD" LOC = "c7" | IOSTANDARD=LVCMOS33 | PULLUP; +NET "O_FUSP_TXD" LOC = "d7" | IOSTANDARD=LVCMOS33 | DRIVE=4 | SLEW=SLOW; diff --git a/rtl/bplib/s3board/s3board_pins.ucf b/rtl/bplib/s3board/s3board_pins.ucf new file mode 100644 index 00000000..188f0b23 --- /dev/null +++ b/rtl/bplib/s3board/s3board_pins.ucf @@ -0,0 +1,132 @@ +## $Id: s3board_pins.ucf 311 2010-06-30 17:52:37Z mueller $ +## +## Pin locks for S3BOARD core functionality: +## internal RS232 +## human I/O (switches, buttons, leds, display) +## sram +## +## Revision History: +## Date Rev Version Comment +## 2008-05-25 150 1.1 Use DRIVE=6|SLEW=SLOW|KEEPER for memory data lines +## 2008-02-17 101 1.0 Initial version +## +## Note: default is DRIVE=12 | SLEW=SLOW +## +## clocks -------------------------------------------------------------------- +NET "CLK" LOC = "t9" | IOSTANDARD=LVCMOS33; +## +## RS232 interface ----------------------------------------------------------- +NET "I_RXD" LOC = "t13" | IOSTANDARD=LVCMOS33; +NET "O_TXD" LOC = "r13" | IOSTANDARD=LVCMOS33 | DRIVE=12 | SLEW=SLOW; +## +## switches and buttons ------------------------------------------------------ +NET "I_SWI<0>" LOC = "f12" | IOSTANDARD=LVCMOS33; +NET "I_SWI<1>" LOC = "g12" | IOSTANDARD=LVCMOS33; +NET "I_SWI<2>" LOC = "h14" | IOSTANDARD=LVCMOS33; +NET "I_SWI<3>" LOC = "h13" | IOSTANDARD=LVCMOS33; +NET "I_SWI<4>" LOC = "j14" | IOSTANDARD=LVCMOS33; +NET "I_SWI<5>" LOC = "j13" | IOSTANDARD=LVCMOS33; +NET "I_SWI<6>" LOC = "k14" | IOSTANDARD=LVCMOS33; +NET "I_SWI<7>" LOC = "k13" | IOSTANDARD=LVCMOS33; +## +NET "I_BTN<0>" LOC = "m13" | IOSTANDARD=LVCMOS33; +NET "I_BTN<1>" LOC = "m14" | IOSTANDARD=LVCMOS33; +NET "I_BTN<2>" LOC = "l13" | IOSTANDARD=LVCMOS33; +NET "I_BTN<3>" LOC = "l14" | IOSTANDARD=LVCMOS33; +## +## LEDs ---------------------------------------------------------------------- +NET "O_LED<0>" LOC = "k12" | IOSTANDARD=LVCMOS33; +NET "O_LED<1>" LOC = "p14" | IOSTANDARD=LVCMOS33; +NET "O_LED<2>" LOC = "l12" | IOSTANDARD=LVCMOS33; +NET "O_LED<3>" LOC = "n14" | IOSTANDARD=LVCMOS33; +NET "O_LED<4>" LOC = "p13" | IOSTANDARD=LVCMOS33; +NET "O_LED<5>" LOC = "n12" | IOSTANDARD=LVCMOS33; +NET "O_LED<6>" LOC = "p12" | IOSTANDARD=LVCMOS33; +NET "O_LED<7>" LOC = "p11" | IOSTANDARD=LVCMOS33; +NET "O_LED<*>" DRIVE=12 | SLEW=SLOW; +## +## 7 segment display --------------------------------------------------------- +NET "O_ANO_N<0>" LOC = "d14" | IOSTANDARD=LVCMOS33; +NET "O_ANO_N<1>" LOC = "g14" | IOSTANDARD=LVCMOS33; +NET "O_ANO_N<2>" LOC = "f14" | IOSTANDARD=LVCMOS33; +NET "O_ANO_N<3>" LOC = "e13" | IOSTANDARD=LVCMOS33; +NET "O_ANO_N<*>" DRIVE=12 | SLEW=SLOW; +## +NET "O_SEG_N<0>" LOC = "e14" | IOSTANDARD=LVCMOS33; +NET "O_SEG_N<1>" LOC = "g13" | IOSTANDARD=LVCMOS33; +NET "O_SEG_N<2>" LOC = "n15" | IOSTANDARD=LVCMOS33; +NET "O_SEG_N<3>" LOC = "p15" | IOSTANDARD=LVCMOS33; +NET "O_SEG_N<4>" LOC = "r16" | IOSTANDARD=LVCMOS33; +NET "O_SEG_N<5>" LOC = "f13" | IOSTANDARD=LVCMOS33; +NET "O_SEG_N<6>" LOC = "n16" | IOSTANDARD=LVCMOS33; +NET "O_SEG_N<7>" LOC = "p16" | IOSTANDARD=LVCMOS33; +NET "O_SEG_N<*>" DRIVE=12 | SLEW=SLOW; +## +## SRAM ---------------------------------------------------------------------- +NET "O_MEM_CE_N<0>" LOC = "p7" | IOSTANDARD=LVCMOS33; +NET "O_MEM_CE_N<1>" LOC = "n5" | IOSTANDARD=LVCMOS33; +NET "O_MEM_CE_N<*>" DRIVE=12 | SLEW=FAST; +## +NET "O_MEM_BE_N<0>" LOC = "p6" | IOSTANDARD=LVCMOS33; +NET "O_MEM_BE_N<1>" LOC = "t4" | IOSTANDARD=LVCMOS33; +NET "O_MEM_BE_N<2>" LOC = "p5" | IOSTANDARD=LVCMOS33; +NET "O_MEM_BE_N<3>" LOC = "r4" | IOSTANDARD=LVCMOS33; +NET "O_MEM_BE_N<*>" DRIVE=12 | SLEW=FAST; +## +NET "O_MEM_WE_N" LOC = "g3" | IOSTANDARD=LVCMOS33 | DRIVE=12 | SLEW=FAST; +NET "O_MEM_OE_N" LOC = "k4" | IOSTANDARD=LVCMOS33 | DRIVE=12 | SLEW=FAST; +## +NET "O_MEM_ADDR<0>" LOC = "l5" | IOSTANDARD=LVCMOS33; +NET "O_MEM_ADDR<1>" LOC = "n3" | IOSTANDARD=LVCMOS33; +NET "O_MEM_ADDR<2>" LOC = "m4" | IOSTANDARD=LVCMOS33; +NET "O_MEM_ADDR<3>" LOC = "m3" | IOSTANDARD=LVCMOS33; +NET "O_MEM_ADDR<4>" LOC = "l4" | IOSTANDARD=LVCMOS33; +NET "O_MEM_ADDR<5>" LOC = "g4" | IOSTANDARD=LVCMOS33; +NET "O_MEM_ADDR<6>" LOC = "f3" | IOSTANDARD=LVCMOS33; +NET "O_MEM_ADDR<7>" LOC = "f4" | IOSTANDARD=LVCMOS33; +NET "O_MEM_ADDR<8>" LOC = "e3" | IOSTANDARD=LVCMOS33; +NET "O_MEM_ADDR<9>" LOC = "e4" | IOSTANDARD=LVCMOS33; +NET "O_MEM_ADDR<10>" LOC = "g5" | IOSTANDARD=LVCMOS33; +NET "O_MEM_ADDR<11>" LOC = "h3" | IOSTANDARD=LVCMOS33; +NET "O_MEM_ADDR<12>" LOC = "h4" | IOSTANDARD=LVCMOS33; +NET "O_MEM_ADDR<13>" LOC = "j4" | IOSTANDARD=LVCMOS33; +NET "O_MEM_ADDR<14>" LOC = "j3" | IOSTANDARD=LVCMOS33; +NET "O_MEM_ADDR<15>" LOC = "k3" | IOSTANDARD=LVCMOS33; +NET "O_MEM_ADDR<16>" LOC = "k5" | IOSTANDARD=LVCMOS33; +NET "O_MEM_ADDR<17>" LOC = "l3" | IOSTANDARD=LVCMOS33; +NET "O_MEM_ADDR<*>" DRIVE=6 | SLEW=FAST; +## +NET "IO_MEM_DATA<0>" LOC = "n7" | IOSTANDARD=LVCMOS33; +NET "IO_MEM_DATA<1>" LOC = "t8" | IOSTANDARD=LVCMOS33; +NET "IO_MEM_DATA<2>" LOC = "r6" | IOSTANDARD=LVCMOS33; +NET "IO_MEM_DATA<3>" LOC = "t5" | IOSTANDARD=LVCMOS33; +NET "IO_MEM_DATA<4>" LOC = "r5" | IOSTANDARD=LVCMOS33; +NET "IO_MEM_DATA<5>" LOC = "c2" | IOSTANDARD=LVCMOS33; +NET "IO_MEM_DATA<6>" LOC = "c1" | IOSTANDARD=LVCMOS33; +NET "IO_MEM_DATA<7>" LOC = "b1" | IOSTANDARD=LVCMOS33; +NET "IO_MEM_DATA<8>" LOC = "d3" | IOSTANDARD=LVCMOS33; +NET "IO_MEM_DATA<9>" LOC = "p8" | IOSTANDARD=LVCMOS33; +NET "IO_MEM_DATA<10>" LOC = "f2" | IOSTANDARD=LVCMOS33; +NET "IO_MEM_DATA<11>" LOC = "h1" | IOSTANDARD=LVCMOS33; +NET "IO_MEM_DATA<12>" LOC = "j2" | IOSTANDARD=LVCMOS33; +NET "IO_MEM_DATA<13>" LOC = "l2" | IOSTANDARD=LVCMOS33; +NET "IO_MEM_DATA<14>" LOC = "p1" | IOSTANDARD=LVCMOS33; +NET "IO_MEM_DATA<15>" LOC = "r1" | IOSTANDARD=LVCMOS33; +NET "IO_MEM_DATA<16>" LOC = "p2" | IOSTANDARD=LVCMOS33; +NET "IO_MEM_DATA<17>" LOC = "n2" | IOSTANDARD=LVCMOS33; +NET "IO_MEM_DATA<18>" LOC = "m2" | IOSTANDARD=LVCMOS33; +NET "IO_MEM_DATA<19>" LOC = "k1" | IOSTANDARD=LVCMOS33; +NET "IO_MEM_DATA<20>" LOC = "j1" | IOSTANDARD=LVCMOS33; +NET "IO_MEM_DATA<21>" LOC = "g2" | IOSTANDARD=LVCMOS33; +NET "IO_MEM_DATA<22>" LOC = "e1" | IOSTANDARD=LVCMOS33; +NET "IO_MEM_DATA<23>" LOC = "d1" | IOSTANDARD=LVCMOS33; +NET "IO_MEM_DATA<24>" LOC = "d2" | IOSTANDARD=LVCMOS33; +NET "IO_MEM_DATA<25>" LOC = "e2" | IOSTANDARD=LVCMOS33; +NET "IO_MEM_DATA<26>" LOC = "g1" | IOSTANDARD=LVCMOS33; +NET "IO_MEM_DATA<27>" LOC = "f5" | IOSTANDARD=LVCMOS33; +NET "IO_MEM_DATA<28>" LOC = "c3" | IOSTANDARD=LVCMOS33; +NET "IO_MEM_DATA<29>" LOC = "k2" | IOSTANDARD=LVCMOS33; +NET "IO_MEM_DATA<30>" LOC = "m1" | IOSTANDARD=LVCMOS33; +NET "IO_MEM_DATA<31>" LOC = "n1" | IOSTANDARD=LVCMOS33; +NET "IO_MEM_DATA<*>" DRIVE=6 | SLEW=SLOW | KEEPER; +## diff --git a/rtl/bplib/s3board/s3boardlib.vbom b/rtl/bplib/s3board/s3boardlib.vbom new file mode 100644 index 00000000..0a29ebd3 --- /dev/null +++ b/rtl/bplib/s3board/s3boardlib.vbom @@ -0,0 +1,4 @@ +# libs +../../vlib/slvtypes.vhd +../../vlib/rri/rrilib.vhd +s3boardlib.vhd diff --git a/rtl/bplib/s3board/s3boardlib.vhd b/rtl/bplib/s3board/s3boardlib.vhd new file mode 100644 index 00000000..54574c35 --- /dev/null +++ b/rtl/bplib/s3board/s3boardlib.vhd @@ -0,0 +1,219 @@ +-- $Id: s3boardlib.vhd 314 2010-07-09 17:38:41Z mueller $ +-- +-- Copyright 2007-2010 by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, 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 complete details. +-- +------------------------------------------------------------------------------ +-- Package Name: s3boardlib +-- Description: S3BOARD components +-- +-- Dependencies: - +-- Tool versions: xst 8.1, 8.2, 9.1, 9.2, 11.4; ghdl 0.18-0.26 +-- Revision History: +-- Date Rev Version Comment +-- 2010-06-03 300 1.3 add s3_humanio_rri (now needs rrilib) +-- 2010-05-21 292 1.2.2 rename _PM1_ -> _FUSP_ +-- 2010-05-16 291 1.2.1 rename memctl_s3sram -> s3_sram_memctl; _usp->_fusp +-- 2010-05-01 286 1.2 added s3board_usp_aif (base+pm1_rs232) +-- 2010-04-17 278 1.1.6 rename, prefix dispdrv,sram_summy with s3_; +-- add s3_rs232_iob_(int|ext|int_ext) +-- 2010-04-11 276 1.1.5 add DEBOUNCE for s3_humanio +-- 2010-04-10 275 1.1.4 add s3_humanio +-- 2008-02-17 117 1.1.3 memctl_s3sram: use req,we interface +-- 2008-01-20 113 1.1.2 rename memdrv -> memctl_s3sram +-- 2007-12-16 101 1.1.1 use _N for active low +-- 2007-12-09 100 1.1 add sram memory signals; sram_dummy; memdrv +-- 2007-09-23 84 1.0 Initial version +------------------------------------------------------------------------------ + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; + +use work.slvtypes.all; +use work.rrilib.all; + +package s3boardlib is + +component s3board_aif is -- S3BOARD, abstract iface, base + port ( + CLK : in slbit; -- clock + I_RXD : in slbit; -- receive data (board view) + O_TXD : out slbit; -- transmit data (board view) + I_SWI : in slv8; -- s3 switches + I_BTN : in slv4; -- s3 buttons + O_LED : out slv8; -- s3 leds + O_ANO_N : out slv4; -- 7 segment disp: anodes (act.low) + O_SEG_N : out slv8; -- 7 segment disp: segments (act.low) + O_MEM_CE_N : out slv2; -- sram: chip enables (act.low) + O_MEM_BE_N : out slv4; -- sram: byte enables (act.low) + O_MEM_WE_N : out slbit; -- sram: write enable (act.low) + O_MEM_OE_N : out slbit; -- sram: output enable (act.low) + O_MEM_ADDR : out slv18; -- sram: address lines + IO_MEM_DATA : inout slv32 -- sram: data lines + ); +end component; + +component s3board_fusp_aif is -- S3BOARD, abstract iface, base+fusp + port ( + CLK : in slbit; -- clock + I_RXD : in slbit; -- receive data (board view) + O_TXD : out slbit; -- transmit data (board view) + I_SWI : in slv8; -- s3 switches + I_BTN : in slv4; -- s3 buttons + O_LED : out slv8; -- s3 leds + O_ANO_N : out slv4; -- 7 segment disp: anodes (act.low) + O_SEG_N : out slv8; -- 7 segment disp: segments (act.low) + O_MEM_CE_N : out slv2; -- sram: chip enables (act.low) + O_MEM_BE_N : out slv4; -- sram: byte enables (act.low) + O_MEM_WE_N : out slbit; -- sram: write enable (act.low) + O_MEM_OE_N : out slbit; -- sram: output enable (act.low) + O_MEM_ADDR : out slv18; -- sram: address lines + IO_MEM_DATA : inout slv32; -- sram: data lines + O_FUSP_RTS_N : out slbit; -- fusp: rs232 rts_n + I_FUSP_CTS_N : in slbit; -- fusp: rs232 cts_n + I_FUSP_RXD : in slbit; -- fusp: rs232 rx + O_FUSP_TXD : out slbit -- fusp: rs232 tx + ); +end component; + +component s3_dispdrv is -- 7 segment display driver + generic ( + CDWIDTH : positive := 6); -- clk divider width (must be >= 5) + port ( + CLK : in slbit; -- clock + DIN : in slv16; -- data + DP : in slv4; -- decimal points + ANO_N : out slv4; -- anodes (act.low) + SEG_N : out slv8 -- segements (act.low) + ); +end component; + +component s3_humanio is -- human i/o handling: swi,btn,led,dsp + generic ( + DEBOUNCE : boolean := true); -- instantiate debouncer for SWI,BTN + port ( + CLK : in slbit; -- clock + RESET : in slbit; -- reset + CE_MSEC : in slbit; -- 1 ms clock enable + SWI : out slv8; -- switch settings, debounced + BTN : out slv4; -- button settings, debounced + LED : in slv8; -- led data + DSP_DAT : in slv16; -- display data + DSP_DP : in slv4; -- display decimal points + I_SWI : in slv8; -- pad-i: switches + I_BTN : in slv4; -- pad-i: buttons + O_LED : out slv8; -- pad-o: leds + O_ANO_N : out slv4; -- pad-o: 7 seg disp: anodes (act.low) + O_SEG_N : out slv8 -- pad-o: 7 seg disp: segments (act.low) + ); +end component; + +component s3_humanio_rri is -- human i/o handling with rri intercept + generic ( + DEBOUNCE : boolean := true; -- instantiate debouncer for SWI,BTN + RB_ADDR : slv8 := conv_std_logic_vector(2#10000000#,8)); + port ( + CLK : in slbit; -- clock + RESET : in slbit; -- reset + CE_MSEC : in slbit; -- 1 ms clock enable + RB_MREQ : in rb_mreq_type; -- rbus: request + RB_SRES : out rb_sres_type; -- rbus: response + SWI : out slv8; -- switch settings, debounced + BTN : out slv4; -- button settings, debounced + LED : in slv8; -- led data + DSP_DAT : in slv16; -- display data + DSP_DP : in slv4; -- display decimal points + I_SWI : in slv8; -- pad-i: switches + I_BTN : in slv4; -- pad-i: buttons + O_LED : out slv8; -- pad-o: leds + O_ANO_N : out slv4; -- pad-o: 7 seg disp: anodes (act.low) + O_SEG_N : out slv8 -- pad-o: 7 seg disp: segments (act.low) + ); +end component; + +component s3_rs232_iob_int is -- iob's for internal rs232 + port ( + CLK : in slbit; -- clock + RXD : out slbit; -- receive data (board view) + TXD : in slbit; -- transmit data (board view) + I_RXD : in slbit; -- pad-i: receive data (board view) + O_TXD : out slbit -- pad-o: transmit data (board view) + ); +end component; + +component s3_rs232_iob_ext is -- iob's for external rs232 (Pmod) + port ( + CLK : in slbit; -- clock + RXD : out slbit; -- receive data (board view) + TXD : in slbit; -- transmit data (board view) + CTS_N : out slbit; -- clear to send (act. low) + RTS_N : in slbit; -- request to send (act. low) + I_RXD : in slbit; -- pad-i: receive data (board view) + O_TXD : out slbit; -- pad-o: transmit data (board view) + I_CTS_N : in slbit; -- pad-i: clear to send (act. low) + O_RTS_N : out slbit -- pad-o: request to send (act. low) + ); +end component; + +component s3_rs232_iob_int_ext is -- iob's for int+ext rs232, with select + port ( + CLK : in slbit; -- clock + SEL : in slbit; -- select, '0' for port 0 + RXD : out slbit; -- receive data (board view) + TXD : in slbit; -- transmit data (board view) + CTS_N : out slbit; -- clear to send (act. low) + RTS_N : in slbit; -- request to send (act. low) + I_RXD0 : in slbit; -- pad-i: p0: receive data (board view) + O_TXD0 : out slbit; -- pad-o: p0: transmit data (board view) + I_RXD1 : in slbit; -- pad-i: p1: receive data (board view) + O_TXD1 : out slbit; -- pad-o: p1: transmit data (board view) + I_CTS1_N : in slbit; -- pad-i: p1: clear to send (act. low) + O_RTS1_N : out slbit -- pad-o: p1: request to send (act. low) + ); +end component; + +component s3_sram_dummy is -- SRAM protection dummy + port ( + O_MEM_CE_N : out slv2; -- sram: chip enables (act.low) + O_MEM_BE_N : out slv4; -- sram: byte enables (act.low) + O_MEM_WE_N : out slbit; -- sram: write enable (act.low) + O_MEM_OE_N : out slbit; -- sram: output enable (act.low) + O_MEM_ADDR : out slv18; -- sram: address lines + IO_MEM_DATA : inout slv32 -- sram: data lines + ); +end component; + +component s3_sram_memctl is -- SRAM driver + port ( + CLK : in slbit; -- clock + RESET : in slbit; -- reset + REQ : in slbit; -- request + WE : in slbit; -- write enable + BUSY : out slbit; -- controller busy + ACK_R : out slbit; -- acknowledge read + ACK_W : out slbit; -- acknowledge write + ACT_R : out slbit; -- signal active read + ACT_W : out slbit; -- signal active write + ADDR : in slv18; -- address + BE : in slv4; -- byte enable + DI : in slv32; -- data in (memory view) + DO : out slv32; -- data out (memory view) + O_MEM_CE_N : out slv2; -- sram: chip enables (act.low) + O_MEM_BE_N : out slv4; -- sram: byte enables (act.low) + O_MEM_WE_N : out slbit; -- sram: write enable (act.low) + O_MEM_OE_N : out slbit; -- sram: output enable (act.low) + O_MEM_ADDR : out slv18; -- sram: address lines + IO_MEM_DATA : inout slv32 -- sram: data lines + ); +end component; + +end s3boardlib; diff --git a/rtl/bplib/s3board/tb/.cvsignore b/rtl/bplib/s3board/tb/.cvsignore new file mode 100644 index 00000000..f8fa4aad --- /dev/null +++ b/rtl/bplib/s3board/tb/.cvsignore @@ -0,0 +1,13 @@ +tb_s3board_dummy +tb_s3board_dummy_[sft]sim +tb_s3board_dummy_ISim +tb_s3board_dummy_ISim_[sft]sim +tb_s3board_fusp_dummy +tb_rriext_fifo_rx +tb_rriext_fifo_tx +tb_rriext_conf +tb_s3_sram_memctl +tb_s3_sram_memctl_[sft]sim +tb_s3_sram_memctl_stim +tb_s3_sram_memctl_ISim +tb_s3_sram_memctl_ISim_[sft]sim diff --git a/rtl/bplib/s3board/tb/Makefile b/rtl/bplib/s3board/tb/Makefile new file mode 100644 index 00000000..abd003d5 --- /dev/null +++ b/rtl/bplib/s3board/tb/Makefile @@ -0,0 +1,35 @@ +# $Id: Makefile 311 2010-06-30 17:52:37Z mueller $ +# +# Revision History: +# Date Rev Version Comment +# 2010-05-16 291 1.2.2 rename tb_memctl_s3sram->tb_s3_sram_memctl +# 2010-05-01 286 1.2.1 add tb_s3board_usp_dummy +# 2009-11-21 252 1.2 add ISim support +# 2007-11-26 98 1.1 use make includes +# 2007-09-23 84 1.0 Initial version +# +EXE_all = tb_s3board_dummy tb_s3board_fusp_dummy tb_s3_sram_memctl +# +ISE_PATH = xc3s1000-ft256-4 +# +.phony : all all_ssim all_tsim clean +# +all : $(EXE_all) +all_ssim : $(EXE_all:=_ssim) +all_tsim : $(EXE_all:=_tsim) +# +clean : ise_clean ghdl_clean isim_clean +# +#----- +# +include $(RETROBASE)/rtl/vlib/Makefile.ghdl +include $(RETROBASE)/rtl/vlib/Makefile.isim +include $(RETROBASE)/rtl/vlib/Makefile.xflow +# +VBOM_all = $(wildcard *.vbom) +# +include $(VBOM_all:.vbom=.dep_xst) +include $(VBOM_all:.vbom=.dep_ghdl) +include $(VBOM_all:.vbom=.dep_isim) +include $(wildcard *.o.dep_ghdl) +# diff --git a/rtl/bplib/s3board/tb/tb_s3board_core.vbom b/rtl/bplib/s3board/tb/tb_s3board_core.vbom new file mode 100644 index 00000000..d0331f93 --- /dev/null +++ b/rtl/bplib/s3board/tb/tb_s3board_core.vbom @@ -0,0 +1,10 @@ +# libs +../../../vlib/slvtypes.vhd +../../../vlib/serport/serport.vhd +../../../vlib/simlib/simbus.vhd +# components +../../../vlib/serport/serport_uart_rx.vbom +../../../vlib/serport/serport_uart_tx.vbom +../../issi/is61lv25616al.vbom +# design +tb_s3board_core.vhd diff --git a/rtl/bplib/s3board/tb/tb_s3board_core.vhd b/rtl/bplib/s3board/tb/tb_s3board_core.vhd new file mode 100644 index 00000000..e1f7480c --- /dev/null +++ b/rtl/bplib/s3board/tb/tb_s3board_core.vhd @@ -0,0 +1,100 @@ +-- $Id: tb_s3board_core.vhd 314 2010-07-09 17:38:41Z mueller $ +-- +-- Copyright 2010- by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, 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 complete details. +-- +------------------------------------------------------------------------------ +-- Module Name: tb_s3board_core - sim +-- Description: Test bench for s3board - core device handling +-- +-- Dependencies: vlib/parts/issi/is61lv25616al +-- +-- To test: generic, any s3board target +-- +-- Target Devices: generic +-- Tool versions: xst 11.4; ghdl 0.26 +-- Revision History: +-- Date Rev Version Comment +-- 2010-05-02 287 1.0.1 add sbaddr_(swi|btn) defs, now sbus addr 16,17 +-- 2010-04-24 282 1.0 Initial version (from vlib/s3board/tb/tb_s3board) +------------------------------------------------------------------------------ + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; +use ieee.std_logic_textio.all; +use std.textio.all; + +use work.slvtypes.all; +use work.serport.all; +use work.simbus.all; + +entity tb_s3board_core is + port ( + I_SWI : out slv8; -- s3 switches + I_BTN : out slv4; -- s3 buttons + O_MEM_CE_N : in slv2; -- sram: chip enables (act.low) + O_MEM_BE_N : in slv4; -- sram: byte enables (act.low) + O_MEM_WE_N : in slbit; -- sram: write enable (act.low) + O_MEM_OE_N : in slbit; -- sram: output enable (act.low) + O_MEM_ADDR : in slv18; -- sram: address lines + IO_MEM_DATA : inout slv32 -- sram: data lines + ); +end tb_s3board_core; + +architecture sim of tb_s3board_core is + + signal R_SWI : slv8 := (others=>'0'); + signal R_BTN : slv4 := (others=>'0'); + + constant sbaddr_swi: slv8 := conv_std_logic_vector( 16,8); + constant sbaddr_btn: slv8 := conv_std_logic_vector( 17,8); + +begin + + MEM_L : entity work.is61lv25616al + port map ( + CE_N => O_MEM_CE_N(0), + OE_N => O_MEM_OE_N, + WE_N => O_MEM_WE_N, + UB_N => O_MEM_BE_N(1), + LB_N => O_MEM_BE_N(0), + ADDR => O_MEM_ADDR, + DATA => IO_MEM_DATA(15 downto 0) + ); + + MEM_U : entity work.is61lv25616al + port map ( + CE_N => O_MEM_CE_N(1), + OE_N => O_MEM_OE_N, + WE_N => O_MEM_WE_N, + UB_N => O_MEM_BE_N(3), + LB_N => O_MEM_BE_N(2), + ADDR => O_MEM_ADDR, + DATA => IO_MEM_DATA(31 downto 16) + ); + + proc_simbus: process (SB_VAL) + begin + if SB_VAL'event and to_x01(SB_VAL)='1' then + if SB_ADDR = sbaddr_swi then + R_SWI <= to_x01(SB_DATA(R_SWI'range)); + end if; + if SB_ADDR = sbaddr_btn then + R_BTN <= to_x01(SB_DATA(R_BTN'range)); + end if; + end if; + end process proc_simbus; + + I_SWI <= R_SWI; + I_BTN <= R_BTN; + +end sim; diff --git a/rtl/bplib/s3board/tb/tb_s3board_fusp.vbom b/rtl/bplib/s3board/tb/tb_s3board_fusp.vbom new file mode 100644 index 00000000..4234c89d --- /dev/null +++ b/rtl/bplib/s3board/tb/tb_s3board_fusp.vbom @@ -0,0 +1,20 @@ +# Not meant for direct top level usage. Used with +# tb_s3board_fusp_(....)[_ssim].vbom and config +# lines to generate the different cases. +# +# libs +../../../vlib/slvtypes.vhd +../../../vlib/rri/rrilib.vhd +../../../vlib/rri/tb/rritblib.vhd +../../../vlib/serport/serport.vhd +../s3boardlib.vbom +../../../vlib/simlib/simlib.vhd +../../../vlib/simlib/simbus.vhd +# components +../../../vlib/rri/tb/rritb_core.vbom +tb_s3board_core.vbom +../../../vlib/serport/serport_uart_rxtx.vbom +s3board_fusp_aif : s3board_fusp_dummy.vbom +# design +tb_s3board_fusp.vhd +@top:tb_s3board_fusp diff --git a/rtl/bplib/s3board/tb/tb_s3board_fusp.vhd b/rtl/bplib/s3board/tb/tb_s3board_fusp.vhd new file mode 100644 index 00000000..7f939979 --- /dev/null +++ b/rtl/bplib/s3board/tb/tb_s3board_fusp.vhd @@ -0,0 +1,220 @@ +-- $Id: tb_s3board_fusp.vhd 314 2010-07-09 17:38:41Z mueller $ +-- +-- Copyright 2010- by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, 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 complete details. +-- +------------------------------------------------------------------------------ +-- Module Name: tb_s3board_fusp - sim +-- Description: Test bench for s3board (base+fusp) +-- +-- Dependencies: vlib/rri/tb/rritb_core +-- tb_s3board_core +-- vlib/serport/serport_uart_rxtx +-- s3board_fusp_aif [UUT] +-- +-- To test: generic, any s3board_fusp_aif target +-- +-- Target Devices: generic +-- Tool versions: xst 8.1, 8.2, 9.1, 9.2, 11.4; ghdl 0.18-0.26 +-- Revision History: +-- Date Rev Version Comment +-- 2010-05-21 292 1.0.3 rename _PM1_ -> _FUSP_ +-- 2010-05-16 291 1.0.2 rename tb_s3board_usp->tb_s3board_fusp +-- 2010-05-02 287 1.0.1 add sbaddr_portsel def, now sbus addr 8 +-- 2010-05-01 286 1.0 Initial version (derived from tb_s3board) +------------------------------------------------------------------------------ + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; +use ieee.std_logic_textio.all; +use std.textio.all; + +use work.slvtypes.all; +use work.rrilib.all; +use work.rritblib.all; +use work.serport.all; +use work.s3boardlib.all; +use work.simlib.all; +use work.simbus.all; + +entity tb_s3board_fusp is +end tb_s3board_fusp; + +architecture sim of tb_s3board_fusp is + + signal CLK : slbit := '0'; + + signal RESET : slbit := '0'; + signal CLKDIV : slv2 := "00"; -- run with 1 clocks / bit !! + signal RXDATA : slv8 := (others=>'0'); + signal RXVAL : slbit := '0'; + signal RXERR : slbit := '0'; + signal RXACT : slbit := '0'; + signal TXDATA : slv8 := (others=>'0'); + signal TXENA : slbit := '0'; + signal TXBUSY : slbit := '0'; + + signal RX_HOLD : slbit := '0'; + + signal I_RXD : slbit := '1'; + signal O_TXD : slbit := '1'; + signal I_SWI : slv8 := (others=>'0'); + signal I_BTN : slv4 := (others=>'0'); + signal O_LED : slv8 := (others=>'0'); + signal O_ANO_N : slv4 := (others=>'0'); + signal O_SEG_N : slv8 := (others=>'0'); + + signal O_MEM_CE_N : slv2 := (others=>'1'); + signal O_MEM_BE_N : slv4 := (others=>'1'); + signal O_MEM_WE_N : slbit := '1'; + signal O_MEM_OE_N : slbit := '1'; + signal O_MEM_ADDR : slv18 := (others=>'Z'); + signal IO_MEM_DATA : slv32 := (others=>'0'); + + signal O_FUSP_RTS_N : slbit := '0'; + signal I_FUSP_CTS_N : slbit := '0'; + signal I_FUSP_RXD : slbit := '1'; + signal O_FUSP_TXD : slbit := '1'; + + signal UART_RESET : slbit := '0'; + signal UART_RXD : slbit := '1'; + signal UART_TXD : slbit := '1'; + signal CTS_N : slbit := '0'; + signal RTS_N : slbit := '0'; + + signal R_PORTSEL : slbit := '0'; + + constant sbaddr_portsel: slv8 := conv_std_logic_vector( 8,8); + + constant clock_period : time := 20 ns; + constant clock_offset : time := 200 ns; + constant setup_time : time := 5 ns; + constant c2out_time : time := 10 ns; + +begin + + TBCORE : rritb_core + generic map ( + CLK_PERIOD => clock_period, + CLK_OFFSET => clock_offset, + SETUP_TIME => setup_time, + C2OUT_TIME => c2out_time) + port map ( + CLK => CLK, + RX_DATA => TXDATA, + RX_VAL => TXENA, + RX_HOLD => RX_HOLD, + TX_DATA => RXDATA, + TX_ENA => RXVAL + ); + + RX_HOLD <= TXBUSY or RTS_N; -- back preasure for data flow to tb + + S3CORE : entity work.tb_s3board_core + port map ( + I_SWI => I_SWI, + I_BTN => I_BTN, + O_MEM_CE_N => O_MEM_CE_N, + O_MEM_BE_N => O_MEM_BE_N, + O_MEM_WE_N => O_MEM_WE_N, + O_MEM_OE_N => O_MEM_OE_N, + O_MEM_ADDR => O_MEM_ADDR, + IO_MEM_DATA => IO_MEM_DATA + ); + + UUT : s3board_fusp_aif + port map ( + CLK => CLK, + I_RXD => I_RXD, + O_TXD => O_TXD, + I_SWI => I_SWI, + I_BTN => I_BTN, + O_LED => O_LED, + O_ANO_N => O_ANO_N, + O_SEG_N => O_SEG_N, + O_MEM_CE_N => O_MEM_CE_N, + O_MEM_BE_N => O_MEM_BE_N, + O_MEM_WE_N => O_MEM_WE_N, + O_MEM_OE_N => O_MEM_OE_N, + O_MEM_ADDR => O_MEM_ADDR, + IO_MEM_DATA => IO_MEM_DATA, + O_FUSP_RTS_N => O_FUSP_RTS_N, + I_FUSP_CTS_N => I_FUSP_CTS_N, + I_FUSP_RXD => I_FUSP_RXD, + O_FUSP_TXD => O_FUSP_TXD + ); + + UART : serport_uart_rxtx + generic map ( + CDWIDTH => CLKDIV'length) + port map ( + CLK => CLK, + RESET => UART_RESET, + CLKDIV => CLKDIV, + RXSD => UART_RXD, + RXDATA => RXDATA, + RXVAL => RXVAL, + RXERR => RXERR, + RXACT => RXACT, + TXSD => UART_TXD, + TXDATA => TXDATA, + TXENA => TXENA, + TXBUSY => TXBUSY + ); + + proc_port_mux: process (R_PORTSEL, UART_TXD, CTS_N, + O_TXD, O_FUSP_TXD, O_FUSP_RTS_N) + begin + + if R_PORTSEL = '0' then -- use main board rs232, no flow cntl + I_RXD <= UART_TXD; -- write port 0 inputs + UART_RXD <= O_TXD; -- get port 0 outputs + RTS_N <= '0'; + I_FUSP_RXD <= '1'; -- port 1 inputs to idle state + I_FUSP_CTS_N <= '0'; + else -- otherwise use pmod1 rs232 + I_FUSP_RXD <= UART_TXD; -- write port 1 inputs + I_FUSP_CTS_N <= CTS_N; + UART_RXD <= O_FUSP_TXD; -- get port 1 outputs + RTS_N <= O_FUSP_RTS_N; + I_RXD <= '1'; -- port 0 inputs to idle state + end if; + + end process proc_port_mux; + + proc_moni: process + variable oline : line; + begin + + loop + wait until CLK'event and CLK='1'; + wait for c2out_time; + + if RXERR = '1' then + writetimestamp(oline, SB_CLKCYCLE, " : seen RXERR=1"); + writeline(output, oline); + end if; + + end loop; + + end process proc_moni; + + proc_simbus: process (SB_VAL) + begin + if SB_VAL'event and to_x01(SB_VAL)='1' then + if SB_ADDR = sbaddr_portsel then + R_PORTSEL <= to_x01(SB_DATA(0)); + end if; + end if; + end process proc_simbus; + +end sim; diff --git a/rtl/bplib/s3board/tb/tbw.dat b/rtl/bplib/s3board/tb/tbw.dat new file mode 100644 index 00000000..c2aa650e --- /dev/null +++ b/rtl/bplib/s3board/tb/tbw.dat @@ -0,0 +1,6 @@ +# $Id: tbw.dat 311 2010-06-30 17:52:37Z mueller $ +# +[tb_s3board_dummy] +tb_rriext_fifo_rx = +tb_rriext_fifo_tx = +tb_rriext_conf = diff --git a/rtl/ibus/Makefile b/rtl/ibus/Makefile new file mode 100644 index 00000000..3c4b9c3f --- /dev/null +++ b/rtl/ibus/Makefile @@ -0,0 +1,21 @@ +# $Id: Makefile 311 2010-06-30 17:52:37Z mueller $ +# +# Revision History: +# Date Rev Version Comment +# 2008-08-22 161 1.0 Initial version +# +VBOM_all = $(wildcard *.vbom) +NGC_all = $(VBOM_all:.vbom=.ngc) +# +.phony : all clean +# +all : $(NGC_all) +# +clean : ise_clean +# +#---- +# +include $(RETROBASE)/rtl/vlib/Makefile.xflow +# +include $(VBOM_all:.vbom=.dep_xst) +# diff --git a/rtl/ibus/ib_intmap.vbom b/rtl/ibus/ib_intmap.vbom new file mode 100644 index 00000000..7d1bd751 --- /dev/null +++ b/rtl/ibus/ib_intmap.vbom @@ -0,0 +1,5 @@ +# libs +../vlib/slvtypes.vhd +iblib.vhd +# design +ib_intmap.vhd diff --git a/rtl/ibus/ib_intmap.vhd b/rtl/ibus/ib_intmap.vhd new file mode 100644 index 00000000..f3b2b697 --- /dev/null +++ b/rtl/ibus/ib_intmap.vhd @@ -0,0 +1,138 @@ +-- $Id: ib_intmap.vhd 314 2010-07-09 17:38:41Z mueller $ +-- +-- Copyright 2006-2008 by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, 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 complete details. +-- +------------------------------------------------------------------------------ +-- Module Name: ib_intmap - syn +-- Description: pdp11: external interrupt mapper +-- +-- Dependencies: - +-- Test bench: tb/tb_pdp11_core (implicit) +-- Target Devices: generic +-- Tool versions: xst 8.1, 8.2, 9.1, 9.2; ghdl 0.18-0.25 +-- Revision History: +-- Date Rev Version Comment +-- 2008-08-22 161 1.2.1 renamed pdp11_ -> ib_; use iblib +-- 2008-01-20 112 1.2 add INTMAP generic to externalize config +-- 2008-01-06 111 1.1 add EI_ACK output lines, remove EI_LINE +-- 2007-10-12 88 1.0.2 avoid ieee.std_logic_unsigned, use cast to unsigned +-- 2007-06-14 56 1.0.1 Use slvtypes.all +-- 2007-05-12 26 1.0 Initial version +------------------------------------------------------------------------------ + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; + +use work.slvtypes.all; +use work.iblib.all; + +-- ---------------------------------------------------------------------------- + +entity ib_intmap is -- external interrupt mapper + generic ( + INTMAP : intmap_array_type := intmap_array_init); + port ( + EI_REQ : in slv16_1; -- interrupt request lines + EI_ACKM : in slbit; -- interrupt acknowledge (from master) + EI_ACK : out slv16_1; -- interrupt acknowledge (to requestor) + EI_PRI : out slv3; -- interrupt priority + EI_VECT : out slv9_2 -- interrupt vector + ); +end ib_intmap; + +architecture syn of ib_intmap is + + signal EI_LINE : slv4 := (others=>'0'); -- external interrupt line + + type intp_type is array (15 downto 0) of slv3; + type intv_type is array (15 downto 0) of slv9; + + constant conf_intp : intp_type := + (conv_std_logic_vector(INTMAP(15).pri,3), -- line 15 + conv_std_logic_vector(INTMAP(14).pri,3), -- line 14 + conv_std_logic_vector(INTMAP(13).pri,3), -- line 13 + conv_std_logic_vector(INTMAP(12).pri,3), -- line 12 + conv_std_logic_vector(INTMAP(11).pri,3), -- line 11 + conv_std_logic_vector(INTMAP(10).pri,3), -- line 10 + conv_std_logic_vector(INTMAP( 9).pri,3), -- line 9 + conv_std_logic_vector(INTMAP( 8).pri,3), -- line 8 + conv_std_logic_vector(INTMAP( 7).pri,3), -- line 7 + conv_std_logic_vector(INTMAP( 6).pri,3), -- line 6 + conv_std_logic_vector(INTMAP( 5).pri,3), -- line 5 + conv_std_logic_vector(INTMAP( 4).pri,3), -- line 4 + conv_std_logic_vector(INTMAP( 3).pri,3), -- line 3 + conv_std_logic_vector(INTMAP( 2).pri,3), -- line 2 + conv_std_logic_vector(INTMAP( 1).pri,3), -- line 1 + conv_std_logic_vector( 0,3) -- line 0 (always 0 !!) + ); + + constant conf_intv : intv_type := + (conv_std_logic_vector(INTMAP(15).vec,9), -- line 15 + conv_std_logic_vector(INTMAP(14).vec,9), -- line 14 + conv_std_logic_vector(INTMAP(13).vec,9), -- line 13 + conv_std_logic_vector(INTMAP(12).vec,9), -- line 12 + conv_std_logic_vector(INTMAP(11).vec,9), -- line 11 + conv_std_logic_vector(INTMAP(10).vec,9), -- line 10 + conv_std_logic_vector(INTMAP( 9).vec,9), -- line 9 + conv_std_logic_vector(INTMAP( 8).vec,9), -- line 8 + conv_std_logic_vector(INTMAP( 7).vec,9), -- line 7 + conv_std_logic_vector(INTMAP( 6).vec,9), -- line 6 + conv_std_logic_vector(INTMAP( 5).vec,9), -- line 5 + conv_std_logic_vector(INTMAP( 4).vec,9), -- line 4 + conv_std_logic_vector(INTMAP( 3).vec,9), -- line 3 + conv_std_logic_vector(INTMAP( 2).vec,9), -- line 2 + conv_std_logic_vector(INTMAP( 1).vec,9), -- line 1 + conv_std_logic_vector( 0,9) -- line 0 (always 0 !!) + ); + +-- attribute PRIORITY_EXTRACT : string; +-- attribute PRIORITY_EXTRACT of EI_LINE : signal is "force"; + +begin + + EI_LINE <= "1111" when EI_REQ(15)='1' else + "1110" when EI_REQ(14)='1' else + "1101" when EI_REQ(13)='1' else + "1100" when EI_REQ(12)='1' else + "1011" when EI_REQ(11)='1' else + "1010" when EI_REQ(10)='1' else + "1001" when EI_REQ( 9)='1' else + "1000" when EI_REQ( 8)='1' else + "0111" when EI_REQ( 7)='1' else + "0110" when EI_REQ( 6)='1' else + "0101" when EI_REQ( 5)='1' else + "0100" when EI_REQ( 4)='1' else + "0011" when EI_REQ( 3)='1' else + "0010" when EI_REQ( 2)='1' else + "0001" when EI_REQ( 1)='1' else + "0000"; + + proc_intmap : process (EI_LINE, EI_ACKM) + variable iline : integer := 0; + variable iei_ack : slv16 := (others=>'0'); + begin + + iline := conv_integer(unsigned(EI_LINE)); + + iei_ack := (others=>'0'); + if EI_ACKM = '1' then + iei_ack(iline) := '1'; + end if; + + EI_ACK <= iei_ack(EI_ACK'range); + EI_PRI <= conf_intp(iline); + EI_VECT <= conf_intv(iline)(8 downto 2); + + end process proc_intmap; + +end syn; diff --git a/rtl/ibus/ib_sres_or_2.vbom b/rtl/ibus/ib_sres_or_2.vbom new file mode 100644 index 00000000..e43a430a --- /dev/null +++ b/rtl/ibus/ib_sres_or_2.vbom @@ -0,0 +1,5 @@ +# libs +../vlib/slvtypes.vhd +iblib.vhd +# design +ib_sres_or_2.vhd diff --git a/rtl/ibus/ib_sres_or_2.vhd b/rtl/ibus/ib_sres_or_2.vhd new file mode 100644 index 00000000..163ee2ad --- /dev/null +++ b/rtl/ibus/ib_sres_or_2.vhd @@ -0,0 +1,61 @@ +-- $Id: ib_sres_or_2.vhd 314 2010-07-09 17:38:41Z mueller $ +-- +-- Copyright 2007-2008 by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, 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 complete details. +-- +------------------------------------------------------------------------------ +-- Module Name: ib_sres_or_2 - syn +-- Description: ibus: result or, 2 input +-- +-- Dependencies: - +-- Test bench: tb/tb_pdp11_core (implicit) +-- Target Devices: generic +-- Tool versions: xst 8.1, 8.2, 9.1, 9.2; ghdl 0.18-0.25 +-- Revision History: +-- Date Rev Version Comment +-- 2008-08-22 161 1.0.2 renamed pdp11_ibres_ -> ib_sres_; use iblib +-- 2008-01-05 110 1.0.1 rename IB_MREQ(ena->req) SRES(sel->ack, hold->busy) +-- 2007-12-29 107 1.0 Initial version +------------------------------------------------------------------------------ + +library ieee; +use ieee.std_logic_1164.all; + +use work.slvtypes.all; +use work.iblib.all; + +-- ---------------------------------------------------------------------------- + +entity ib_sres_or_2 is -- ibus result or, 2 input + port ( + IB_SRES_1 : in ib_sres_type; -- ib_sres input 1 + IB_SRES_2 : in ib_sres_type := ib_sres_init; -- ib_sres input 2 + IB_SRES_OR : out ib_sres_type -- ib_sres or'ed output + ); +end ib_sres_or_2; + +architecture syn of ib_sres_or_2 is + +begin + + proc_comb : process (IB_SRES_1, IB_SRES_2) + begin + + IB_SRES_OR.ack <= IB_SRES_1.ack or + IB_SRES_2.ack; + IB_SRES_OR.busy <= IB_SRES_1.busy or + IB_SRES_2.busy; + IB_SRES_OR.dout <= IB_SRES_1.dout or + IB_SRES_2.dout; + + end process proc_comb; + +end syn; diff --git a/rtl/ibus/ib_sres_or_3.vbom b/rtl/ibus/ib_sres_or_3.vbom new file mode 100644 index 00000000..efd19695 --- /dev/null +++ b/rtl/ibus/ib_sres_or_3.vbom @@ -0,0 +1,5 @@ +# libs +../vlib/slvtypes.vhd +iblib.vhd +# design +ib_sres_or_3.vhd diff --git a/rtl/ibus/ib_sres_or_3.vhd b/rtl/ibus/ib_sres_or_3.vhd new file mode 100644 index 00000000..51ad758c --- /dev/null +++ b/rtl/ibus/ib_sres_or_3.vhd @@ -0,0 +1,65 @@ +-- $Id: ib_sres_or_3.vhd 314 2010-07-09 17:38:41Z mueller $ +-- +-- Copyright 2007-2008 by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, 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 complete details. +-- +------------------------------------------------------------------------------ +-- Module Name: ib_sres_or_3 - syn +-- Description: ibus: result or, 3 input +-- +-- Dependencies: - +-- Test bench: tb/tb_pdp11_core (implicit) +-- Target Devices: generic +-- Tool versions: xst 8.1, 8.2, 9.1, 9.2; ghdl 0.18-0.25 +-- Revision History: +-- Date Rev Version Comment +-- 2008-08-22 161 1.0.2 renamed pdp11_ibres_ -> ib_sres_; use iblib +-- 2008-01-05 110 1.0.1 rename IB_MREQ(ena->req) SRES(sel->ack, hold->busy) +-- 2007-12-29 107 1.0 Initial version +------------------------------------------------------------------------------ + +library ieee; +use ieee.std_logic_1164.all; + +use work.slvtypes.all; +use work.iblib.all; + +-- ---------------------------------------------------------------------------- + +entity ib_sres_or_3 is -- ibus result or, 3 input + port ( + IB_SRES_1 : in ib_sres_type; -- ib_sres input 1 + IB_SRES_2 : in ib_sres_type := ib_sres_init; -- ib_sres input 2 + IB_SRES_3 : in ib_sres_type := ib_sres_init; -- ib_sres input 3 + IB_SRES_OR : out ib_sres_type -- ib_sres or'ed output + ); +end ib_sres_or_3; + +architecture syn of ib_sres_or_3 is + +begin + + proc_comb : process (IB_SRES_1, IB_SRES_2, IB_SRES_3) + begin + + IB_SRES_OR.ack <= IB_SRES_1.ack or + IB_SRES_2.ack or + IB_SRES_3.ack; + IB_SRES_OR.busy <= IB_SRES_1.busy or + IB_SRES_2.busy or + IB_SRES_3.busy; + IB_SRES_OR.dout <= IB_SRES_1.dout or + IB_SRES_2.dout or + IB_SRES_3.dout; + + end process proc_comb; + +end syn; diff --git a/rtl/ibus/ib_sres_or_4.vbom b/rtl/ibus/ib_sres_or_4.vbom new file mode 100644 index 00000000..3c06c0d2 --- /dev/null +++ b/rtl/ibus/ib_sres_or_4.vbom @@ -0,0 +1,5 @@ +# libs +../vlib/slvtypes.vhd +iblib.vhd +# design +ib_sres_or_4.vhd diff --git a/rtl/ibus/ib_sres_or_4.vhd b/rtl/ibus/ib_sres_or_4.vhd new file mode 100644 index 00000000..48533489 --- /dev/null +++ b/rtl/ibus/ib_sres_or_4.vhd @@ -0,0 +1,69 @@ +-- $Id: ib_sres_or_4.vhd 314 2010-07-09 17:38:41Z mueller $ +-- +-- Copyright 2007-2008 by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, 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 complete details. +-- +------------------------------------------------------------------------------ +-- Module Name: ib_sres_or_4 - syn +-- Description: ibus: result or, 4 input +-- +-- Dependencies: - +-- Test bench: tb/tb_pdp11_core (implicit) +-- Target Devices: generic +-- Tool versions: xst 8.1, 8.2, 9.1, 9.2; ghdl 0.18-0.25 +-- Revision History: +-- Date Rev Version Comment +-- 2008-08-22 161 1.0.2 renamed pdp11_ibres_ -> ib_sres_; use iblib +-- 2008-01-05 110 1.0.1 rename IB_MREQ(ena->req) SRES(sel->ack, hold->busy) +-- 2007-12-29 107 1.0 Initial version +------------------------------------------------------------------------------ + +library ieee; +use ieee.std_logic_1164.all; + +use work.slvtypes.all; +use work.iblib.all; + +-- ---------------------------------------------------------------------------- + +entity ib_sres_or_4 is -- ibus result or, 4 input + port ( + IB_SRES_1 : in ib_sres_type; -- ib_sres input 1 + IB_SRES_2 : in ib_sres_type := ib_sres_init; -- ib_sres input 2 + IB_SRES_3 : in ib_sres_type := ib_sres_init; -- ib_sres input 3 + IB_SRES_4 : in ib_sres_type := ib_sres_init; -- ib_sres input 4 + IB_SRES_OR : out ib_sres_type -- ib_sres or'ed output + ); +end ib_sres_or_4; + +architecture syn of ib_sres_or_4 is + +begin + + proc_comb : process (IB_SRES_1, IB_SRES_2, IB_SRES_3, IB_SRES_4) + begin + + IB_SRES_OR.ack <= IB_SRES_1.ack or + IB_SRES_2.ack or + IB_SRES_3.ack or + IB_SRES_4.ack; + IB_SRES_OR.busy <= IB_SRES_1.busy or + IB_SRES_2.busy or + IB_SRES_3.busy or + IB_SRES_4.busy; + IB_SRES_OR.dout <= IB_SRES_1.dout or + IB_SRES_2.dout or + IB_SRES_3.dout or + IB_SRES_4.dout; + + end process proc_comb; + +end syn; diff --git a/rtl/ibus/ibd_iist.vbom b/rtl/ibus/ibd_iist.vbom new file mode 100644 index 00000000..b102c01f --- /dev/null +++ b/rtl/ibus/ibd_iist.vbom @@ -0,0 +1,6 @@ +# libs +../vlib/slvtypes.vhd +iblib.vhd +ibdlib.vhd +# design +ibd_iist.vhd diff --git a/rtl/ibus/ibd_iist.vhd b/rtl/ibus/ibd_iist.vhd new file mode 100644 index 00000000..66d516af --- /dev/null +++ b/rtl/ibus/ibd_iist.vhd @@ -0,0 +1,678 @@ +-- $Id: ibd_iist.vhd 314 2010-07-09 17:38:41Z mueller $ +-- +-- Copyright 2009- by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, 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 complete details. +-- +------------------------------------------------------------------------------ +-- Module Name: ibd_iist - syn +-- Description: ibus dev(loc): IIST +-- +-- Dependencies: - +-- Test bench: - +-- Target Devices: generic +-- Tool versions: xst 8.1, 8.2, 9.1, 9.2; ghdl 0.18-0.25 +-- +-- Synthesized (xst): +-- Date Rev ise Target flop lutl lutm slic t peri +-- 2009-06-01 223 10.1.03 K39 xc3s1000-4 111 439 0 256 s 9.8 +-- 2009-06-01 221 10.1.03 K39 xc3s1000-4 111 449 0 258 s 13.3 +-- +-- Revision History: +-- Date Rev Version Comment +-- 2009-06-07 224 0.7 send inverted stc_stp; remove pgc_err; honor msk_im +-- also for dcf_dcf and exc_rte; add iist_mreq and +-- iist_sreq, boot and lock interfaces +-- 2009-06-05 223 0.6 level interrupt, parity logic, exc.ui logic +-- st logic modified (partially tested) +-- 2009-06-01 221 0.5 Initial version (untested, lock&boot missing) +------------------------------------------------------------------------------ + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; + +use work.slvtypes.all; +use work.iblib.all; +use work.ibdlib.all; + +-- ---------------------------------------------------------------------------- +entity ibd_iist is -- ibus dev(loc): IIST + -- fixed address: 177500 + generic ( + SID : slv2 := "00"); -- self id + port ( + CLK : in slbit; -- clock + CE_USEC : in slbit; -- usec pulse + RESET : in slbit; -- system reset + BRESET : in slbit; -- ibus reset + IB_MREQ : in ib_mreq_type; -- ibus request + IB_SRES : out ib_sres_type; -- ibus response + EI_REQ : out slbit; -- interrupt request + EI_ACK : in slbit; -- interrupt acknowledge + IIST_BUS : in iist_bus_type; -- iist bus (input from all iist's) + IIST_OUT : out iist_line_type; -- iist output + IIST_MREQ : out iist_mreq_type; -- iist->cpu requests + IIST_SRES : in iist_sres_type -- cpu->iist responses + ); +end ibd_iist; + +architecture syn of ibd_iist is + + constant ibaddr_iist : slv16 := conv_std_logic_vector(8#177500#,16); + + constant tdlysnd : natural := 150; -- send delay timer + + constant ibaddr_acr : slv1 := "0"; -- acr address offset + constant ibaddr_adr : slv1 := "1"; -- adr address offset + + constant acr_ibf_clr : integer := 15; -- clear flag + subtype acr_ibf_sid is integer range 9 downto 8; -- self id + subtype acr_ibf_ac is integer range 3 downto 0; -- ac code + + constant ac_pge : slv4 := "0000"; -- 0 program generated enables + constant ac_pgc : slv4 := "0001"; -- 1 program generated control/status + constant ac_ste : slv4 := "0010"; -- 2 sanity timer enables + constant ac_stc : slv4 := "0011"; -- 3 sanity timer control/status + constant ac_msk : slv4 := "0100"; -- 4 input masks + constant ac_pgf : slv4 := "0101"; -- 5 program generated flags + constant ac_stf : slv4 := "0110"; -- 6 sanity timer flags + constant ac_dcf : slv4 := "0111"; -- 7 disconnect flags + constant ac_exc : slv4 := "1000"; -- 10 exceptions + constant ac_mtc : slv4 := "1101"; -- 15 maintenance control + + subtype pge_ibf_pbe is integer range 11 downto 8; -- pg boot ena + subtype pge_ibf_pie is integer range 3 downto 0; -- pg int ena + + constant pgc_ibf_err : integer := 15; -- error + constant pgc_ibf_grj : integer := 14; -- go reject + constant pgc_ibf_pgrmr : integer := 13; -- pg req refused + constant pgc_ibf_strmr : integer := 12; -- st req refused + constant pgc_ibf_rdy : integer := 11; -- ready flag + subtype pgc_ibf_sid is integer range 9 downto 8; -- self id + constant pgc_ibf_ip : integer := 3; -- int pending + constant pgc_ibf_ie : integer := 2; -- int enable + constant pgc_ibf_ptp : integer := 1; -- pg parity + constant pgc_ibf_go : integer := 0; -- go flag + + subtype ste_ibf_sbe is integer range 11 downto 8; -- st boot enable + subtype ste_ibf_sie is integer range 3 downto 0; -- st int enable + + subtype stc_ibf_count is integer range 15 downto 8; -- count + constant stc_ibf_tmo : integer := 3; -- timeout + constant stc_ibf_lke : integer := 2; -- lockup enable + constant stc_ibf_stp : integer := 1; -- st parity + constant stc_ibf_enb : integer := 0; -- enable + + subtype msk_ibf_bm is integer range 11 downto 8; -- boot mask + subtype msk_ibf_im is integer range 3 downto 0; -- int mask + + subtype pgf_ibf_pbf is integer range 11 downto 8; -- boot flags + subtype pgf_ibf_pif is integer range 3 downto 0; -- int flags + + subtype stf_ibf_sbf is integer range 11 downto 8; -- boot flags + subtype stf_ibf_sif is integer range 3 downto 0; -- int flags + + subtype dcf_ibf_brk is integer range 11 downto 8; -- break flags + subtype dcf_ibf_dcf is integer range 3 downto 0; -- disconnect flags + + subtype exc_ibf_ui is integer range 11 downto 8; -- unexpected int + subtype exc_ibf_rte is integer range 3 downto 0; -- transm. error + + constant mtc_ibf_mttp : integer := 11; -- maint. type + constant mtc_ibf_mfrm : integer := 10; -- maint. frame err + subtype mtc_ibf_mid is integer range 9 downto 8; -- maint. id + constant mtc_ibf_dsbt : integer := 3; -- disable boot + constant mtc_ibf_enmxd : integer := 2; -- enable maint mux + constant mtc_ibf_enmlp : integer := 1; -- enable maint loop + constant mtc_ibf_dsdrv : integer := 0; -- disable driver + + type state_type is ( + s_idle, -- idle state + s_clear, -- handle acr clr + s_stsnd, -- handle st transmit + s_pgsnd -- handle pg transmit + ); + + type regs_type is record -- state registers + acr_ac : slv4; -- acr: ac + pge_pbe : slv4; -- pge: pg boot ena + pge_pie : slv4; -- pge: pg int ena + pgc_grj : slbit; -- pgc: go reject + pgc_pgrmr : slbit; -- pgc: pg req refused + pgc_strmr : slbit; -- pgc: st req refused + pgc_ie : slbit; -- pgc: int enable + pgc_ptp : slbit; -- pgc: pg parity + ste_sbe : slv4; -- ste: st boot enable + ste_sie : slv4; -- ste: st int enable + stc_count : slv8; -- stc: count + stc_tmo : slbit; -- stc: timeout + stc_lke : slbit; -- stc: lockup enable + stc_stp : slbit; -- stc: st parity + stc_enb : slbit; -- stc: enable + msk_bm : slv4; -- msk: boot mask + msk_im : slv4; -- msk: int mask + pgf_pbf : slv4; -- pgf: boot flags + pgf_pif : slv4; -- pgf: int flags + stf_sbf : slv4; -- stf: boot flags + stf_sif : slv4; -- stf: int flags + dcf_brk : slv4; -- dcf: break flags + dcf_dcf : slv4; -- dcf: disconnect flags + exc_ui : slv4; -- exc: unexpected int + exc_rte : slv4; -- exc: transm. error + mtc_mttp : slbit; -- mtc: maint. type + mtc_mfrm : slbit; -- mtc: maint. frame err + mtc_mid : slv2; -- mtc: maint. id + mtc_dsbt : slbit; -- mtc: disable boot + mtc_enmxd : slbit; -- mtc: enable maint mux + mtc_enmlp : slbit; -- mtc: enable maint loop + mtc_dsdrv : slbit; -- mtc: disable driver + state : state_type; -- state + req_clear : slbit; -- request clear + req_stsnd : slbit; -- request sanity timer transmit + req_pgsnd : slbit; -- request prog. gen. transmit + tcnt256 : slv8; -- usec clock divider for st clock + tcntsnd : slv8; -- timer for transmit delay + req_lock : slbit; -- cpu lock request + req_boot : slbit; -- cpu boot request + end record regs_type; + + constant regs_init : regs_type := ( + "0000", -- acr_ac + "0000","0000", -- pge_pbe, pge_pie + '0', -- pgc_grj + '0','0', -- pgc_pgrmr, pgc_strmr + '0','0', -- pgc_ie, pgc_ptp + "0000","0000", -- ste_sbe, ste_sie + (others=>'0'), -- stc_count + '0','0', -- stc_tmo, stc_lke + '0','0', -- stc_stp, stc_enb + "0000","0000", -- msk_bm, msk_im + "0000","0000", -- pgf_pbf, pgf_pif + "0000","0000", -- stf_sbf, stf_sif + "0000","0000", -- dcf_brk, dcf_dcf + "0000","0000", -- exc_ui, exc_rte + '0','0', -- mtc_mttp, mtc_mfrm + "00", -- mtc_mid + '0','0', -- mtc_dsbt, mtc_enmxd + '0','0', -- mtc_enmlp, mtc_dsdrv + s_idle, -- state + '0', -- req_clear + '0','0', -- req_stsnd, req_pgsnd + (others=>'0'), -- tcnt256 + (others=>'0'), -- tcntsnd + '0','0' -- req_lock, req_boot + ); + + signal R_REGS : regs_type := regs_init; + signal N_REGS : regs_type := regs_init; + +begin + + proc_regs: process (CLK) + begin + if CLK'event and CLK='1' then + if BRESET = '1' or -- BRESET is 1 for system and ibus reset + R_REGS.req_clear='1' then + R_REGS <= regs_init; -- + if RESET = '0' then -- if RESET=0 we do just an ibus reset + R_REGS.pgf_pbf <= N_REGS.pgf_pbf; -- don't reset pg boot flags + R_REGS.stf_sbf <= N_REGS.stf_sbf; -- don't reset st boot flags + R_REGS.tcnt256 <= N_REGS.tcnt256; -- don't reset st clock divider + end if; + else + R_REGS <= N_REGS; + end if; + end if; + end process proc_regs; + + proc_next : process (R_REGS, CE_USEC, IB_MREQ, EI_ACK, EI_ACK, + IIST_BUS(0), IIST_BUS(1), IIST_BUS(2), IIST_BUS(3), + IIST_SRES) + variable r : regs_type := regs_init; + variable n : regs_type := regs_init; + variable ibsel : slbit := '0'; + variable ibbusy : slbit := '0'; + variable idout : slv16 := (others=>'0'); + variable ibrd : slbit := '0'; + variable ibw0 : slbit := '0'; + variable ibw1 : slbit := '0'; + variable int_or : slbit := '0'; + variable tcnt256_end : slbit := '0'; + variable tcntsnd_end : slbit := '0'; + variable eff_id : slv2 := "00"; + variable eff_bus : iist_bus_type := iist_bus_init; + variable par_err : slbit := '0'; + variable act_ibit : slbit := '0'; + variable act_bbit : slbit := '0'; + variable iout : iist_line_type := iist_line_init; + begin + + r := R_REGS; + n := R_REGS; + + ibsel := '0'; + ibbusy := '0'; + idout := (others=>'0'); + ibrd := not IB_MREQ.we; + ibw0 := IB_MREQ.we and IB_MREQ.be0; + ibw1 := IB_MREQ.we and IB_MREQ.be1; + + int_or := r.pgc_grj or r.pgc_pgrmr or r.pgc_strmr; + for i in r.dcf_dcf'range loop + int_or := int_or or r.dcf_dcf(i) or + r.exc_rte(i) or + r.pgf_pif(i) or + r.stf_sif(i); + end loop; -- i + + tcnt256_end := '0'; + if CE_USEC='1' and r.stc_enb='1'then -- if st enabled on every usec + n.tcnt256 := unsigned(r.tcnt256) + 1; -- advance 8 bit counter + if unsigned(r.tcnt256) = 255 then -- if wrap + tcnt256_end := '1'; -- signal 256 usec passed + end if; + end if; + + tcntsnd_end := '0'; + n.tcntsnd := unsigned(r.tcntsnd) + 1; -- advance send timer counter + if unsigned(r.tcntsnd) = tdlysnd-1 then -- if delay time reached + tcntsnd_end := '1'; -- signal end + end if; + + eff_id := SID; -- effective self-id, normally SID + if r.mtc_enmxd = '1' then -- if maint. mux enabled + eff_id := r.mtc_mid; -- use maint. id + end if; + + eff_bus := IIST_BUS; + + par_err := '0'; + act_ibit := '0'; + act_bbit := '0'; + iout := iist_line_init; -- default state of out line + + -- ibus address decoder + if IB_MREQ.req='1' and + IB_MREQ.addr(12 downto 2)=ibaddr_iist(12 downto 2) then + ibsel := '1'; + end if; + + -- internal state machine + case r.state is + when s_idle => -- idle state + n.tcntsnd := (others=>'0'); -- keep send delay timer zero + if r.req_stsnd = '1' then -- sanity timer request pending + n.state := s_stsnd; + elsif r.req_pgsnd = '1' then -- prog. gen. request pending + n.state := s_pgsnd; + end if; + + when s_clear => -- handle acr clr + ibbusy := ibsel; -- keep req pending if selected + ibsel := '0'; -- but don't process selection + -- r.req_clear is set when in this state and cause a reset in prog_regs + -- --> n.req_clear := '0'; + -- --> n.state := s_idle; + + when s_stsnd => -- handle st transmit + if tcntsnd_end = '1' then -- send delay expired + n.req_stsnd := '0'; -- clear st transmit request + iout.req := '1'; -- do transmit + iout.stf := '1'; -- signal type = st + iout.imask := r.ste_sie; -- int enables + iout.bmask := r.ste_sbe; -- boot enables + iout.par := not r.stc_stp; -- send parity (odd incl. stf!) + iout.frm := '0'; -- frame always ok + n.state := s_idle; + end if; + + when s_pgsnd => -- handle pg transmit + if tcntsnd_end = '1' then -- send delay expired + n.req_pgsnd := '0'; -- clear pg transmit request + iout.req := '1'; -- do transmit + iout.stf := '0'; -- signal type = pg + iout.imask := r.pge_pie; -- int enables + iout.bmask := r.pge_pbe; -- boot enables + iout.par := r.pgc_ptp; -- send parity + iout.frm := '0'; -- frame always ok + n.state := s_idle; + end if; + + when others => null; + end case; + + if r.mtc_enmxd = '1' then -- if maintenance mux enabled + iout.stf := r.mtc_mttp; -- force type from mtc_mttp + iout.frm := r.mtc_mfrm; -- force frame from mtc_mfrm + end if; + + -- ibus transactions + if ibsel = '1' then + + if IB_MREQ.addr(1 downto 1) = "0" then -- ACR -- access control reg ----- + + idout(acr_ibf_sid) := SID; + idout(acr_ibf_ac) := r.acr_ac; + + if ibw1 = '1' then + if IB_MREQ.din(acr_ibf_clr) = '1' then + n.req_clear := '1'; + n.state := s_clear; + end if; + end if; + if ibw0 = '1' then + n.acr_ac := IB_MREQ.din(acr_ibf_ac); + end if; + + else -- ADR -- access data reg -------- + case r.acr_ac is + + when ac_pge => -- PGE -- program gen enables -------- + + idout(pge_ibf_pbe) := r.pge_pbe; + idout(pge_ibf_pie) := r.pge_pie; + + if IB_MREQ.we = '1' then + + if r.req_pgsnd = '0' then -- no pg transmit pending + if ibw1 = '1' then + n.pge_pbe := IB_MREQ.din(pge_ibf_pbe); + end if; + if ibw0 = '1' then + n.pge_pie := IB_MREQ.din(pge_ibf_pie); + end if; + else -- if collision with pg transmit + n.pgc_pgrmr := '1'; -- set pge refused flag + end if; + + end if; + + when ac_pgc => -- PGC -- program gen control/status - + + idout(pgc_ibf_err) := r.pgc_grj or r.pgc_pgrmr or r.pgc_strmr; + idout(pgc_ibf_grj) := r.pgc_grj; + idout(pgc_ibf_pgrmr) := r.pgc_pgrmr; + idout(pgc_ibf_strmr) := r.pgc_strmr; + idout(pgc_ibf_rdy) := not r.req_pgsnd; + idout(pgc_ibf_sid) := eff_id; + idout(pgc_ibf_ip) := int_or; + idout(pgc_ibf_ie) := r.pgc_ie; + idout(pgc_ibf_ptp) := r.pgc_ptp; + + if ibw1 = '1' then + if IB_MREQ.din(pgc_ibf_err) = '1' then -- '1' written into ERR + n.pgc_grj := '0'; -- clears GRJ + n.pgc_pgrmr := '0'; -- clears PGRMR + n.pgc_strmr := '0'; -- clears STRMR + end if; + end if; + if ibw0 = '1' then + n.pgc_ie := IB_MREQ.din(pgc_ibf_ie); + n.pgc_ptp := IB_MREQ.din(pgc_ibf_ptp); + if IB_MREQ.din(pgc_ibf_go) = '1' then -- GO bit set + if r.req_pgsnd = '0' then -- if ready (no pgsnd pend) + n.req_pgsnd := '1'; -- request pgsnd + else -- if not ready + n.pgc_grj := '1'; -- set go reject flag + end if; + end if; + end if; + + when ac_ste => -- STE -- sanity timer enables ------- + + idout(ste_ibf_sbe) := r.ste_sbe; + idout(ste_ibf_sie) := r.ste_sie; + + if IB_MREQ.we = '1' then + + if r.req_stsnd = '0' then -- no st transmit pending + if ibw1 = '1' then + n.ste_sbe := IB_MREQ.din(ste_ibf_sbe); + end if; + if ibw0 = '1' then + n.ste_sie := IB_MREQ.din(ste_ibf_sie); + end if; + + else -- if collision with st transmit + n.pgc_strmr := '1'; -- set ste refused flag + end if; + + end if; + + when ac_stc => -- STC -- sanity timer control/status + + idout(stc_ibf_count) := r.stc_count; + idout(stc_ibf_tmo) := r.stc_tmo; + idout(stc_ibf_lke) := r.stc_lke; + idout(stc_ibf_stp) := r.stc_stp; + idout(stc_ibf_enb) := r.stc_enb; + + if ibw1 = '1' then + n.stc_count := IB_MREQ.din(stc_ibf_count); -- reset st count + n.tcnt256 := (others=>'0'); -- reset usec count + end if; + if ibw0 = '1' then + if IB_MREQ.din(stc_ibf_tmo) = '1' then -- 1 written into TMO + n.stc_tmo := '0'; + end if; + n.stc_lke := IB_MREQ.din(stc_ibf_lke); + n.stc_stp := IB_MREQ.din(stc_ibf_stp); + n.stc_enb := IB_MREQ.din(stc_ibf_enb); + end if; + + when ac_msk => -- MSK -- input masks ---------------- + + idout(msk_ibf_bm) := r.msk_bm; + idout(msk_ibf_im) := r.msk_im; + + if ibw1 = '1' then + n.msk_bm := IB_MREQ.din(msk_ibf_bm); + end if; + if ibw0 = '1' then + n.msk_im := IB_MREQ.din(msk_ibf_im); + end if; + + when ac_pgf => -- PGF -- program generated flags ---- + + idout(pgf_ibf_pbf) := r.pgf_pbf; + idout(pgf_ibf_pif) := r.pgf_pif; + + if ibw1 = '1' then + n.pgf_pbf := r.pgf_pbf and not IB_MREQ.din(pgf_ibf_pbf); + end if; + if ibw0 = '1' then + n.pgf_pif := r.pgf_pif and not IB_MREQ.din(pgf_ibf_pif); + end if; + + when ac_stf => -- STF -- sanity timer flags --------- + + idout(stf_ibf_sbf) := r.stf_sbf; + idout(stf_ibf_sif) := r.stf_sif; + + if ibw1 = '1' then + n.stf_sbf := r.stf_sbf and not IB_MREQ.din(stf_ibf_sbf); + end if; + if ibw0 = '1' then + n.stf_sif := r.stf_sif and not IB_MREQ.din(stf_ibf_sif); + end if; + + when ac_dcf => -- DCE -- disconnect flags ----------- + + idout(dcf_ibf_brk) := r.dcf_brk; + idout(dcf_ibf_dcf) := r.dcf_dcf; + + if ibw0 = '1' then + n.dcf_dcf := r.dcf_dcf and not IB_MREQ.din(dcf_ibf_dcf); + end if; + + when ac_exc => -- EXC -- exceptions ----------------- + + idout(exc_ibf_ui) := r.exc_ui; + idout(exc_ibf_rte) := r.exc_rte; + + if ibw1 = '1' then + n.exc_ui := r.exc_ui and not IB_MREQ.din(exc_ibf_ui); + end if; + if ibw0 = '1' then + n.exc_rte := r.exc_rte and not IB_MREQ.din(exc_ibf_rte); + end if; + + when ac_mtc => -- MTC -- maintenance control -------- + + idout(mtc_ibf_mttp) := r.mtc_mttp; + idout(mtc_ibf_mfrm) := r.mtc_mfrm; + idout(mtc_ibf_mid) := r.mtc_mid; + idout(mtc_ibf_dsbt) := r.mtc_dsbt; + idout(mtc_ibf_enmxd) := r.mtc_enmxd; + idout(mtc_ibf_enmlp) := r.mtc_enmlp; + idout(mtc_ibf_dsdrv) := r.mtc_dsdrv; + + if ibw1 = '1' then + n.mtc_mttp := IB_MREQ.din(mtc_ibf_mttp); + n.mtc_mfrm := IB_MREQ.din(mtc_ibf_mfrm); + n.mtc_mid := IB_MREQ.din(mtc_ibf_mid); + end if; + if ibw0 = '1' then + n.mtc_dsbt := IB_MREQ.din(mtc_ibf_dsbt); + n.mtc_enmxd := IB_MREQ.din(mtc_ibf_enmxd); + n.mtc_enmlp := IB_MREQ.din(mtc_ibf_enmlp); + n.mtc_dsdrv := IB_MREQ.din(mtc_ibf_dsdrv); + end if; + + when others => -- access to undefined AC code ------- + null; + + end case; + + if unsigned(r.acr_ac) <= unsigned(ac_exc) then -- if ac 0,..,10 + if IB_MREQ.dip = '0' then -- if not 1st part of rmw + n.acr_ac := unsigned(r.acr_ac) + 1; -- autoincrement + end if; + end if; + + end if; + + end if; + + -- sanity timer + + if tcnt256_end = '1' then -- if 256 usec expired (and enabled) + n.stc_count := unsigned(r.stc_count) - 1; + if unsigned(r.stc_count) = 0 then -- if sanity timer expired + n.stc_tmo := '1'; -- set timeout flag + n.req_stsnd := '1'; -- request st transmit + if r.stc_lke = '1' then -- if lockup enabled + n.req_lock := '1'; -- request lockup + end if; + end if; + end if; + + -- process iist bus inputs + + if r.mtc_enmlp = '1' then -- if mainentance loop + for i in eff_bus'range loop + eff_bus(i) := iout; -- local signal on all input ports + eff_bus(i).dcf := '0'; -- all ports considered connected + end loop; -- i + end if; + + for i in eff_bus'range loop + + par_err := eff_bus(i).stf xor + eff_bus(i).imask(0) xor eff_bus(i).imask(1) xor + eff_bus(i).imask(2) xor eff_bus(i).imask(3) xor + eff_bus(i).bmask(0) xor eff_bus(i).bmask(1) xor + eff_bus(i).bmask(2) xor eff_bus(i).bmask(3) xor + not eff_bus(i).par; + + act_ibit := eff_bus(i).imask(conv_integer(unsigned(eff_id))); + act_bbit := eff_bus(i).bmask(conv_integer(unsigned(eff_id))); + + n.dcf_brk(i) := eff_bus(i).dcf; -- trace dcf state in brk + + if eff_bus(i).dcf = '1' then -- if disconnected + if r.msk_im(i) = '0' then -- if not disabled + n.dcf_dcf(i) := '1'; -- set dcf flag + end if; + + else -- if connected + if eff_bus(i).req = '1' then -- request received ? + if eff_bus(i).frm='1' or -- frame error seen ? + par_err='1' then -- parity error seen ? + if r.msk_im(i) = '0' then -- if not disabled + n.exc_rte(i) := '1'; -- set rte flag + end if; + + else -- here if valid request seen + if act_ibit = '1' then -- interrupt request + if r.msk_im(i) = '1' then -- if disabled + n.exc_ui(i) := '1'; -- set ui flag + else -- if enabled + n.req_lock := '0'; -- release lock + if eff_bus(i).stf = '0' then -- and pg request + n.pgf_pif(i) := '1'; -- set pif flag + else -- and st request + n.stf_sif(i) := '1'; -- set sif flag + end if; + end if; + end if; -- act_ibit='1' + + if act_bbit = '1' then -- boot request + if r.msk_bm(i) = '1' then -- if msk disabled + n.exc_ui(i) := '1'; -- set ui flag + else -- if msk enabled + if r.mtc_dsbt = '0' then -- if mtc enabled + n.req_lock := '0'; -- release lock + n.req_boot := '1'; -- request boot + end if; + if eff_bus(i).stf = '0' then -- and pg request + n.pgf_pbf(i) := '1'; -- set pbf flag + else -- and st request + n.stf_sbf(i) := '1'; -- set sbf flag + end if; + end if; + end if; -- act_bbit='1' + + end if; + + end if; + end if; + end loop; + + -- process cpu->iist responses + if IIST_SRES.ack_lock = '1' then + n.req_lock := '0'; + end if; + if IIST_SRES.ack_boot = '1' then + n.req_boot := '0'; + end if; + + N_REGS <= n; + + IB_SRES.dout <= idout; + IB_SRES.ack <= ibsel; + IB_SRES.busy <= ibbusy; + + EI_REQ <= r.pgc_ie and int_or; + + if r.mtc_dsdrv = '1' then -- if driver disconnected + iout.dcf := '1'; -- set dcf flag + iout.req := '0'; -- suppress requests + end if; + IIST_OUT <= iout; -- and finally send it out... + + IIST_MREQ.lock <= r.req_lock; + IIST_MREQ.boot <= r.req_boot; + + end process proc_next; + + +end syn; diff --git a/rtl/ibus/ibd_kw11l.vbom b/rtl/ibus/ibd_kw11l.vbom new file mode 100644 index 00000000..49f8a443 --- /dev/null +++ b/rtl/ibus/ibd_kw11l.vbom @@ -0,0 +1,5 @@ +# libs +../vlib/slvtypes.vhd +iblib.vhd +# design +ibd_kw11l.vhd diff --git a/rtl/ibus/ibd_kw11l.vhd b/rtl/ibus/ibd_kw11l.vhd new file mode 100644 index 00000000..cf31df86 --- /dev/null +++ b/rtl/ibus/ibd_kw11l.vhd @@ -0,0 +1,161 @@ +-- $Id: ibd_kw11l.vhd 314 2010-07-09 17:38:41Z mueller $ +-- +-- Copyright 2008-2009 by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, 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 complete details. +-- +------------------------------------------------------------------------------ +-- Module Name: ibd_kw11l - syn +-- Description: ibus dev(loc): KW11-L (line clock) +-- +-- Dependencies: - +-- Test bench: - +-- Target Devices: generic +-- Tool versions: xst 8.1, 8.2, 9.1, 9.2, 10.1; ghdl 0.18-0.25 +-- +-- Synthesized (xst): +-- Date Rev ise Target flop lutl lutm slic t peri +-- 2009-07-11 232 10.1.03 K39 xc3s1000-4 8 25 0 15 s 5.3 +-- +-- Revision History: +-- Date Rev Version Comment +-- 2009-06-01 221 1.0.5 BUGFIX: add RESET; don't clear tcnt on ibus reset +-- 2008-08-22 161 1.0.4 use iblib; add EI_ACK to proc_next sens. list +-- 2008-05-09 144 1.0.3 use intreq flop, use EI_ACK +-- 2008-01-20 112 1.0.2 fix proc_next sensitivity list; use BRESET +-- 2008-01-06 111 1.0.1 Renamed to ibd_kw11l (RRI_REQ not used) +-- 2008-01-05 110 1.0 Initial version +------------------------------------------------------------------------------ + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; + +use work.slvtypes.all; +use work.iblib.all; + +-- ---------------------------------------------------------------------------- +entity ibd_kw11l is -- ibus dev(loc): KW11-L (line clock) + -- fixed address: 177546 + port ( + CLK : in slbit; -- clock + CE_MSEC : in slbit; -- msec pulse + RESET : in slbit; -- system reset + BRESET : in slbit; -- ibus reset + IB_MREQ : in ib_mreq_type; -- ibus request + IB_SRES : out ib_sres_type; -- ibus response + EI_REQ : out slbit; -- interrupt request + EI_ACK : in slbit -- interrupt acknowledge + ); +end ibd_kw11l; + +architecture syn of ibd_kw11l is + + constant ibaddr_kw11l : slv16 := conv_std_logic_vector(8#177546#,16); + + constant lks_ibf_ie : integer := 6; + constant lks_ibf_moni : integer := 7; + + constant twidth : natural := 5; + constant tdivide : natural := 20; + + type regs_type is record -- state registers + ie : slbit; -- interrupt enable + moni : slbit; -- monitor bit + intreq : slbit; -- interrupt request + tcnt : slv(twidth-1 downto 0); -- timer counter + end record regs_type; + + constant regs_init : regs_type := ( + '0', -- ie + '1', -- moni (set on reset !!) + '0', -- intreq + (others=>'0') -- tcnt + ); + + signal R_REGS : regs_type := regs_init; + signal N_REGS : regs_type := regs_init; + +begin + + proc_regs: process (CLK) + begin + if CLK'event and CLK='1' then + if BRESET = '1' then -- BRESET is 1 for system and ibus reset + R_REGS <= regs_init; + if RESET = '0' then -- if RESET=0 we do just an ibus reset + R_REGS.tcnt <= N_REGS.tcnt; -- don't clear msec tick counter + end if; + else + R_REGS <= N_REGS; + end if; + end if; + end process proc_regs; + + proc_next : process (R_REGS, IB_MREQ, CE_MSEC, EI_ACK) + variable r : regs_type := regs_init; + variable n : regs_type := regs_init; + variable ibsel : slbit := '0'; + variable idout : slv16 := (others=>'0'); + begin + + r := R_REGS; + n := R_REGS; + + ibsel := '0'; + idout := (others=>'0'); + + -- ibus address decoder + if IB_MREQ.req='1' and IB_MREQ.addr=ibaddr_kw11l(12 downto 1) then + ibsel := '1'; + end if; + + -- ibus output driver + if ibsel = '1' then + idout(lks_ibf_ie) := R_REGS.ie; + idout(lks_ibf_moni) := R_REGS.moni; + end if; + + -- ibus write transactions + if ibsel='1' and IB_MREQ.we='1' and IB_MREQ.be0='1' then + n.ie := IB_MREQ.din(lks_ibf_ie); + n.moni := IB_MREQ.din(lks_ibf_moni); + if IB_MREQ.din(lks_ibf_ie)='0' or IB_MREQ.din(lks_ibf_moni)='0' then + n.intreq := '0'; + end if; + end if; + + -- other state changes + if CE_MSEC = '1' then + n.tcnt := unsigned(r.tcnt) + 1; + if unsigned(r.tcnt) = tdivide-1 then + n.tcnt := (others=>'0'); + n.moni := '1'; + if r.ie = '1' then + n.intreq := '1'; + end if; + end if; + end if; + + if EI_ACK = '1' then + n.intreq := '0'; + end if; + + N_REGS <= n; + + IB_SRES.dout <= idout; + IB_SRES.ack <= ibsel; + IB_SRES.busy <= '0'; + + EI_REQ <= r.intreq; + + end process proc_next; + +end syn; diff --git a/rtl/ibus/ibdlib.vhd b/rtl/ibus/ibdlib.vhd new file mode 100644 index 00000000..f5a6c15c --- /dev/null +++ b/rtl/ibus/ibdlib.vhd @@ -0,0 +1,268 @@ +-- $Id: ibdlib.vhd 314 2010-07-09 17:38:41Z mueller $ +-- +-- Copyright 2008-2010 by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, 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 complete details. +-- +------------------------------------------------------------------------------ +-- Package Name: ibdlib +-- Description: Definitions for ibus devices +-- +-- Dependencies: - +-- Tool versions: xst 8.1, 8.2, 9.1, 9.2; ghdl 0.18-0.25 +-- Revision History: +-- Date Rev Version Comment +-- 2010-06-11 303 1.1 use IB_MREQ.racc instead of RRI_REQ +-- 2009-07-12 233 1.0.5 add RESET, CE_USEC to _dl11, CE_USEC to _minisys +-- 2009-06-07 224 1.0.4 add iist_mreq and iist_sreq; +-- 2009-06-01 221 1.0.3 add RESET to kw11l; add iist; +-- 2009-05-30 220 1.0.2 add most additional device def's +-- 2009-05-24 219 1.0.1 add CE_MSEC to _rk11; add _maxisys +-- 2008-08-22 161 1.0 Initial version (extracted from pdp11.vhd) +------------------------------------------------------------------------------ + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; + +use work.slvtypes.all; +use work.iblib.all; + +package ibdlib is + +type iist_line_type is record -- iist line + dcf : slbit; -- disconnect flag + req : slbit; -- request + stf : slbit; -- sanity timer flag + imask : slv4; -- interrupt mask + bmask : slv4; -- boot mask + par : slbit; -- parity (odd) + frm : slbit; -- frame error flag +end record iist_line_type; + +constant iist_line_init : iist_line_type := ('1','0','0',"0000","0000",'0','0'); + +type iist_bus_type is array (3 downto 0) of iist_line_type; +constant iist_bus_init : iist_bus_type := (others=>iist_line_init); + +type iist_mreq_type is record -- iist->cpu requests + lock : slbit; -- lock-up CPU + boot : slbit; -- boot-up CPU +end record iist_mreq_type; + +constant iist_mreq_init : iist_mreq_type := ('0','0'); + +type iist_sres_type is record -- cpu->iist responses + ack_lock : slbit; -- release lock + ack_boot : slbit; -- boot started +end record iist_sres_type; + +constant iist_sres_init : iist_sres_type := ('0','0'); + +component ibd_iist is -- ibus dev(loc): IIST + -- fixed address: 177500 + generic ( + SID : slv2 := "00"); -- self id + port ( + CLK : in slbit; -- clock + CE_USEC : in slbit; -- usec pulse + RESET : in slbit; -- system reset + BRESET : in slbit; -- ibus reset + IB_MREQ : in ib_mreq_type; -- ibus request + IB_SRES : out ib_sres_type; -- ibus response + EI_REQ : out slbit; -- interrupt request + EI_ACK : in slbit; -- interrupt acknowledge + IIST_BUS : in iist_bus_type; -- iist bus (input from all iist's) + IIST_OUT : out iist_line_type; -- iist output + IIST_MREQ : out iist_mreq_type; -- iist->cpu requests + IIST_SRES : in iist_sres_type -- cpu->iist responses + ); +end component; + +component ibd_kw11p is -- ibus dev(loc): KW11-P (line clock) + -- fixed address: 172540 + port ( + CLK : in slbit; -- clock + CE_USEC : in slbit; -- usec pulse + CE_MSEC : in slbit; -- msec pulse + RESET : in slbit; -- system reset + BRESET : in slbit; -- ibus reset + IB_MREQ : in ib_mreq_type; -- ibus request + IB_SRES : out ib_sres_type; -- ibus response + EI_REQ : out slbit; -- interrupt request + EI_ACK : in slbit -- interrupt acknowledge + ); +end component; + +component ibd_kw11l is -- ibus dev(loc): KW11-L (line clock) + -- fixed address: 177546 + port ( + CLK : in slbit; -- clock + CE_MSEC : in slbit; -- msec pulse + RESET : in slbit; -- system reset + BRESET : in slbit; -- ibus reset + IB_MREQ : in ib_mreq_type; -- ibus request + IB_SRES : out ib_sres_type; -- ibus response + EI_REQ : out slbit; -- interrupt request + EI_ACK : in slbit -- interrupt acknowledge + ); +end component; + +component ibdr_rl11 is -- ibus dev(rem): RL11 + -- fixed address: 174400 + port ( + CLK : in slbit; -- clock + BRESET : in slbit; -- ibus reset + RRI_LAM : out slbit; -- remote attention + IB_MREQ : in ib_mreq_type; -- ibus request + IB_SRES : out ib_sres_type; -- ibus response + EI_REQ : out slbit; -- interrupt request + EI_ACK : in slbit -- interrupt acknowledge + ); +end component; + +component ibdr_rk11 is -- ibus dev(rem): RK11 + -- fixed address: 177400 + port ( + CLK : in slbit; -- clock + CE_MSEC : in slbit; -- msec pulse + BRESET : in slbit; -- ibus reset + RRI_LAM : out slbit; -- remote attention + IB_MREQ : in ib_mreq_type; -- ibus request + IB_SRES : out ib_sres_type; -- ibus response + EI_REQ : out slbit; -- interrupt request + EI_ACK : in slbit -- interrupt acknowledge + ); +end component; + +component ibdr_tm11 is -- ibus dev(rem): TM11 + -- fixed address: 172520 + port ( + CLK : in slbit; -- clock + BRESET : in slbit; -- ibus reset + RRI_LAM : out slbit; -- remote attention + IB_MREQ : in ib_mreq_type; -- ibus request + IB_SRES : out ib_sres_type; -- ibus response + EI_REQ : out slbit; -- interrupt request + EI_ACK : in slbit -- interrupt acknowledge + ); +end component; + +component ibdr_dz11 is -- ibus dev(rem): DZ11 + generic ( + IB_ADDR : slv16 := conv_std_logic_vector(8#160100#,16)); + port ( + CLK : in slbit; -- clock + RESET : in slbit; -- system reset + BRESET : in slbit; -- ibus reset + RRI_LAM : out slbit; -- remote attention + IB_MREQ : in ib_mreq_type; -- ibus request + IB_SRES : out ib_sres_type; -- ibus response + EI_REQ_RX : out slbit; -- interrupt request, receiver + EI_REQ_TX : out slbit; -- interrupt request, transmitter + EI_ACK_RX : in slbit; -- interrupt acknowledge, receiver + EI_ACK_TX : in slbit -- interrupt acknowledge, transmitter + ); +end component; + +component ibdr_dl11 is -- ibus dev(rem): DL11-A/B + generic ( + IB_ADDR : slv16 := conv_std_logic_vector(8#177560#,16)); + port ( + CLK : in slbit; -- clock + CE_USEC : in slbit; -- usec pulse + RESET : in slbit; -- system reset + BRESET : in slbit; -- ibus reset + RRI_LAM : out slbit; -- remote attention + IB_MREQ : in ib_mreq_type; -- ibus request + IB_SRES : out ib_sres_type; -- ibus response + EI_REQ_RX : out slbit; -- interrupt request, receiver + EI_REQ_TX : out slbit; -- interrupt request, transmitter + EI_ACK_RX : in slbit; -- interrupt acknowledge, receiver + EI_ACK_TX : in slbit -- interrupt acknowledge, transmitter + ); +end component; + +component ibdr_pc11 is -- ibus dev(rem): PC11 + -- fixed address: 177550 + port ( + CLK : in slbit; -- clock + RESET : in slbit; -- system reset + BRESET : in slbit; -- ibus reset + RRI_LAM : out slbit; -- remote attention + IB_MREQ : in ib_mreq_type; -- ibus request + IB_SRES : out ib_sres_type; -- ibus response + EI_REQ_PTR : out slbit; -- interrupt request, reader + EI_REQ_PTP : out slbit; -- interrupt request, punch + EI_ACK_PTR : in slbit; -- interrupt acknowledge, reader + EI_ACK_PTP : in slbit -- interrupt acknowledge, punch + ); +end component; + +component ibdr_lp11 is -- ibus dev(rem): LP11 + -- fixed address: 177514 + port ( + CLK : in slbit; -- clock + RESET : in slbit; -- system reset + BRESET : in slbit; -- ibus reset + RRI_LAM : out slbit; -- remote attention + IB_MREQ : in ib_mreq_type; -- ibus request + IB_SRES : out ib_sres_type; -- ibus response + EI_REQ : out slbit; -- interrupt request + EI_ACK : in slbit -- interrupt acknowledge + ); +end component; + +component ibdr_sdreg is -- ibus dev(rem): Switch/Display regs + -- fixed address: 177570 + port ( + CLK : in slbit; -- clock + RESET : in slbit; -- reset + IB_MREQ : in ib_mreq_type; -- ibus request + IB_SRES : out ib_sres_type; -- ibus response + DISPREG : out slv16 -- display register + ); +end component; + +component ibdr_minisys is -- ibus(rem) minimal sys:SDR+KW+DL+RK + port ( + CLK : in slbit; -- clock + CE_USEC : in slbit; -- usec pulse + CE_MSEC : in slbit; -- msec pulse + RESET : in slbit; -- reset + BRESET : in slbit; -- ibus reset + RRI_LAM : out slv16_1; -- remote attention vector + IB_MREQ : in ib_mreq_type; -- ibus request + IB_SRES : out ib_sres_type; -- ibus response + EI_ACKM : in slbit; -- interrupt acknowledge (from master) + EI_PRI : out slv3; -- interrupt priority (to cpu) + EI_VECT : out slv9_2; -- interrupt vector (to cpu) + DISPREG : out slv16 -- display register + ); +end component; + +component ibdr_maxisys is -- ibus(rem) full system + port ( + CLK : in slbit; -- clock + CE_USEC : in slbit; -- usec pulse + CE_MSEC : in slbit; -- msec pulse + RESET : in slbit; -- reset + BRESET : in slbit; -- ibus reset + RRI_LAM : out slv16_1; -- remote attention vector + IB_MREQ : in ib_mreq_type; -- ibus request + IB_SRES : out ib_sres_type; -- ibus response + EI_ACKM : in slbit; -- interrupt acknowledge (from master) + EI_PRI : out slv3; -- interrupt priority (to cpu) + EI_VECT : out slv9_2; -- interrupt vector (to cpu) + DISPREG : out slv16 -- display register + ); +end component; + +end package ibdlib; diff --git a/rtl/ibus/ibdr_dl11.vbom b/rtl/ibus/ibdr_dl11.vbom new file mode 100644 index 00000000..487e1fd0 --- /dev/null +++ b/rtl/ibus/ibdr_dl11.vbom @@ -0,0 +1,5 @@ +# libs +../vlib/slvtypes.vhd +iblib.vhd +# design +ibdr_dl11.vhd diff --git a/rtl/ibus/ibdr_dl11.vhd b/rtl/ibus/ibdr_dl11.vhd new file mode 100644 index 00000000..e19246d3 --- /dev/null +++ b/rtl/ibus/ibdr_dl11.vhd @@ -0,0 +1,341 @@ +-- $Id: ibdr_dl11.vhd 314 2010-07-09 17:38:41Z mueller $ +-- +-- Copyright 2008-2010 by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, 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 complete details. +-- +------------------------------------------------------------------------------ +-- Module Name: ibdr_dl11 - syn +-- Description: ibus dev(rem): DL11-A/B +-- +-- Dependencies: - +-- Test bench: - +-- Target Devices: generic +-- Tool versions: xst 8.1, 8.2, 9.1, 9.2, 10.1; ghdl 0.18-0.25 +-- +-- Synthesized (xst): +-- Date Rev ise Target flop lutl lutm slic t peri +-- 2009-07-12 233 10.1.03 K39 xc3s1000-4 38 119 0 69 s 6.3 +-- 2009-07-11 232 10.1.03 K39 xc3s1000-4 23 61 0 40 s 5.5 +-- +-- Revision History: +-- Date Rev Version Comment +-- 2010-06-11 303 1.1 use IB_MREQ.racc instead of RRI_REQ +-- 2009-07-12 233 1.0.5 add RESET, CE_USEC port; implement input rate limit +-- 2008-08-22 161 1.0.6 use iblib; add EI_ACK_* to proc_next sens. list +-- 2008-05-09 144 1.0.5 use intreq flop, use EI_ACK +-- 2008-03-22 128 1.0.4 rename xdone -> xval (no functional change) +-- 2008-01-27 115 1.0.3 bugfix: set ilam when rbuf read by cpu; +-- add xdone and rrdy bits to rri xbuf read +-- 2008-01-20 113 1.0.2 fix maint mode logic (proper double buffer now) +-- 2008-01-20 112 1.0.1 use BRESET +-- 2008-01-05 108 1.0 Initial version +------------------------------------------------------------------------------ + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; + +use work.slvtypes.all; +use work.iblib.all; + +-- ---------------------------------------------------------------------------- +entity ibdr_dl11 is -- ibus dev(rem): DL11-A/B + generic ( + IB_ADDR : slv16 := conv_std_logic_vector(8#177560#,16)); + port ( + CLK : in slbit; -- clock + CE_USEC : in slbit; -- usec pulse + RESET : in slbit; -- system reset + BRESET : in slbit; -- ibus reset + RRI_LAM : out slbit; -- remote attention + IB_MREQ : in ib_mreq_type; -- ibus request + IB_SRES : out ib_sres_type; -- ibus response + EI_REQ_RX : out slbit; -- interrupt request, receiver + EI_REQ_TX : out slbit; -- interrupt request, transmitter + EI_ACK_RX : in slbit; -- interrupt acknowledge, receiver + EI_ACK_TX : in slbit -- interrupt acknowledge, transmitter + ); +end ibdr_dl11; + +architecture syn of ibdr_dl11 is + + constant ibaddr_rcsr : slv2 := "00"; -- rcsr address offset + constant ibaddr_rbuf : slv2 := "01"; -- rbuf address offset + constant ibaddr_xcsr : slv2 := "10"; -- xcsr address offset + constant ibaddr_xbuf : slv2 := "11"; -- xbuf address offset + + subtype rcsr_ibf_rrlim is integer range 14 downto 12; + constant rcsr_ibf_rdone : integer := 7; + constant rcsr_ibf_rie : integer := 6; + + constant xcsr_ibf_xrdy : integer := 7; + constant xcsr_ibf_xie : integer := 6; + constant xcsr_ibf_xmaint: integer := 2; + + constant xbuf_ibf_xval : integer := 8; + constant xbuf_ibf_rrdy : integer := 9; + + type regs_type is record -- state registers + rrlim : slv3; -- rcsr: receiver rate limit + rdone : slbit; -- rcsr: receiver done + rie : slbit; -- rcsr: receiver interrupt enable + rbuf : slv8; -- rbuf: + rval : slbit; -- rx rbuf valid + rintreq : slbit; -- rx interrupt request + rdlybsy : slbit; -- rx delay busy + rdlycnt : slv10; -- rx delay counter + xrdy : slbit; -- xcsr: transmitter ready + xie : slbit; -- xcsr: transmitter interrupt enable + xmaint : slbit; -- xcsr: maintenance mode + xbuf : slv8; -- xbuf: + xintreq : slbit; -- tx interrupt request + end record regs_type; + + constant regs_init : regs_type := ( + (others=>'0'), -- rrlim + '0','0', -- rdone, rie + (others=>'0'), -- rbuf + '0','0','0', -- rval,rintreq,rdlybsy + (others=>'0'), -- rdlycnt + '1', -- xrdy !! is set !! + '0','0', -- xie,xmaint + (others=>'0'), -- xbuf + '0' -- xintreq + ); + + signal R_REGS : regs_type := regs_init; + signal N_REGS : regs_type := regs_init; + +begin + + proc_regs: process (CLK) + begin + if CLK'event and CLK='1' then + if BRESET = '1' then + R_REGS <= regs_init; + if RESET = '0' then -- if RESET=0 we do just an ibus reset + R_REGS.rrlim <= N_REGS.rrlim; -- don't reset rx rate limit + R_REGS.rdlybsy <= N_REGS.rdlybsy; -- don't reset rx delay busy + R_REGS.rdlycnt <= N_REGS.rdlycnt; -- don't reset rx delay counter + end if; + else + R_REGS <= N_REGS; + end if; + end if; + end process proc_regs; + + proc_next : process (CE_USEC, R_REGS, IB_MREQ, EI_ACK_RX, EI_ACK_TX) + variable r : regs_type := regs_init; + variable n : regs_type := regs_init; + variable ibsel : slbit := '0'; + variable idout : slv16 := (others=>'0'); + variable ibrd : slbit := '0'; + variable ibw0 : slbit := '0'; + variable ibw1 : slbit := '0'; + variable ilam : slbit := '0'; + variable rdlystart : slbit := '0'; + variable rdlyinit : slv10 := (others=>'0'); + begin + + r := R_REGS; + n := R_REGS; + + ibsel := '0'; + idout := (others=>'0'); + ibrd := not IB_MREQ.we; + ibw0 := IB_MREQ.we and IB_MREQ.be0; + ibw1 := IB_MREQ.we and IB_MREQ.be1; + ilam := '0'; + rdlystart := '0'; + + -- ibus address decoder + if IB_MREQ.req='1' and IB_MREQ.addr(12 downto 3)=IB_ADDR(12 downto 3) then + ibsel := '1'; + end if; + + -- ibus transactions + if ibsel = '1' then + case IB_MREQ.addr(2 downto 1) is + + when ibaddr_rcsr => -- RCSR -- receive control status ---- + idout(rcsr_ibf_rdone) := r.rdone; + idout(rcsr_ibf_rie) := r.rie; + + if IB_MREQ.racc = '0' then -- cpu --------------------- + if ibw0 = '1' then + n.rie := IB_MREQ.din(rcsr_ibf_rie); + if IB_MREQ.din(rcsr_ibf_rie) = '1' then + if r.rdone='1' and r.rie='0' then -- ie set while done=1 + n.rintreq := '1'; -- request interrupt + end if; + else + n.rintreq := '0'; + end if; + end if; + + else -- rri --------------------- + idout(rcsr_ibf_rrlim) := r.rrlim; + if ibw1 = '1' then + n.rrlim := IB_MREQ.din(rcsr_ibf_rrlim); + end if; + end if; + + when ibaddr_rbuf => -- RBUF -- receive data buffer ------- + + idout(r.rbuf'range) := r.rbuf; + + if IB_MREQ.racc = '0' then -- cpu --------------------- + if ibrd = '1' then + n.rdone := '0'; -- clear DONE + n.rval := '0'; -- clear rbuf valid + n.rintreq := '0'; -- clear pending interrupts + rdlystart := '1'; -- start rx delay counter + if r.xmaint = '0' then -- if not in loop-back + ilam := '1'; -- request rb attention + end if; + end if; + + else -- rri --------------------- + if ibw0 = '1' then + n.rbuf := IB_MREQ.din(n.rbuf'range); + n.rval := '1'; -- set rbuf valid + if r.rdlybsy = '0' then -- if rdly timer not running + n.rdone := '1'; -- set DONE + if r.rie = '1' then -- if rx interrupt enabled + n.rintreq := '1'; -- request interrupt + end if; + end if; + end if; + end if; + + when ibaddr_xcsr => -- XCSR -- transmit control status --- + + idout(xcsr_ibf_xrdy) := r.xrdy; + idout(xcsr_ibf_xie) := r.xie; + idout(xcsr_ibf_xmaint):= r.xmaint; + + if IB_MREQ.racc = '0' then -- cpu --------------------- + if ibw0 = '1' then + n.xie := IB_MREQ.din(xcsr_ibf_xie); + if IB_MREQ.din(xcsr_ibf_xie) = '1' then + if r.xrdy='1' and r.xie='0' then -- ie set while ready=1 + n.xintreq := '1'; -- request interrupt + end if; + else + n.xintreq := '0'; + end if; + n.xmaint := IB_MREQ.din(xcsr_ibf_xmaint); + end if; + end if; + + when ibaddr_xbuf => -- XBUF -- transmit data buffer ------ + + if IB_MREQ.racc = '0' then -- cpu --------------------- + if ibw0 = '1' then + n.xbuf := IB_MREQ.din(n.xbuf'range); + n.xrdy := '0'; + n.xintreq := '0'; + if r.xmaint = '0' then + ilam := '1'; + end if; + end if; + + else -- rri --------------------- + idout(r.xbuf'range) := r.xbuf; + if r.xmaint = '0' then -- if not in maintenace mode + idout(xbuf_ibf_xval) := not r.xrdy; + idout(xbuf_ibf_rrdy) := not r.rval; + end if; + if ibrd = '1' then + n.xrdy := '1'; + if r.xie = '1' then + n.xintreq := '1'; + end if; + end if; + end if; + + when others => null; + end case; + + else -- if unselected handle loop-back + if r.xmaint = '1' and -- if in maintenace mode + r.xrdy='0' and -- and transmit pending + r.rdone='0' and -- and receive buffer empty + r.rdlybsy='0' then -- and rdly timer not running + n.rbuf := r.xbuf; -- copy transmit to receive buffer + n.xrdy := '1'; -- mark transmit done + n.rdone := '1'; -- make receive done + if r.rie = '1' then -- if rx interrupt enabled + n.rintreq := '1'; -- request it + end if; + if r.xie = '1' then -- if tx interrupt enabled + n.xintreq := '1'; -- request it + end if; + end if; + + end if; + + -- other state changes + + rdlyinit := (others=>'0'); + case r.rrlim is + when "000" => rdlyinit := "0000000000"; -- rlim=0 -> disabled + when "001" => rdlyinit := "0000000011"; -- rlim=1 -> delay by 3+ usec + when "010" => rdlyinit := "0000001111"; -- rlim=2 -> delay by 15+ usec + when "011" => rdlyinit := "0000111111"; -- rlim=3 -> delay by 63+ usec + when "100" => rdlyinit := "0001111111"; -- rlim=4 -> delay by 127+ usec + when "101" => rdlyinit := "0011111111"; -- rlim=5 -> delay by 255+ usec + when "110" => rdlyinit := "0111111111"; -- rlim=6 -> delay by 511+ usec + when "111" => rdlyinit := "1111111111"; -- rlim=7 -> delay by 1023+ usec + when others => null; + end case; + + if rdlystart = '1' then -- if rdly timer start requested + n.rdlycnt := rdlyinit; -- init counter + if r.rrlim /= "000" then -- rate limiter enabled ? + n.rdlybsy := '1'; -- set busy + end if; + elsif CE_USEC = '1' then -- if end-of-usec + n.rdlycnt := unsigned(r.rdlycnt) - 1; -- decrement + if r.rdlybsy='1' and -- if delay busy + unsigned(r.rdlycnt) = 0 then -- and counter at zero + n.rdlybsy := '0'; -- clear busy + if n.rval = '1' then -- if rbuf is valid or is set + -- valid this cycle (use n.!!) + n.rdone := '1'; -- set DONE + if r.rie = '1' then -- if rx interrupt enabled + n.rintreq := '1'; -- request interrupt + end if; + end if; + end if; + end if; + + if EI_ACK_RX = '1' then + n.rintreq := '0'; + end if; + if EI_ACK_TX = '1' then + n.xintreq := '0'; + end if; + + N_REGS <= n; + + IB_SRES.dout <= idout; + IB_SRES.ack <= ibsel; + IB_SRES.busy <= '0'; + + RRI_LAM <= ilam; + EI_REQ_RX <= r.rintreq; + EI_REQ_TX <= r.xintreq; + + end process proc_next; + + +end syn; diff --git a/rtl/ibus/ibdr_lp11.vbom b/rtl/ibus/ibdr_lp11.vbom new file mode 100644 index 00000000..83b0d9b6 --- /dev/null +++ b/rtl/ibus/ibdr_lp11.vbom @@ -0,0 +1,5 @@ +# libs +../vlib/slvtypes.vhd +iblib.vhd +# design +ibdr_lp11.vhd diff --git a/rtl/ibus/ibdr_lp11.vhd b/rtl/ibus/ibdr_lp11.vhd new file mode 100644 index 00000000..c9ed143f --- /dev/null +++ b/rtl/ibus/ibdr_lp11.vhd @@ -0,0 +1,205 @@ +-- $Id: ibdr_lp11.vhd 314 2010-07-09 17:38:41Z mueller $ +-- +-- Copyright 2009-2010 by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, 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 complete details. +-- +------------------------------------------------------------------------------ +-- Module Name: ibdr_lp11 - syn +-- Description: ibus dev(rem): LP11 +-- +-- Dependencies: - +-- Test bench: - +-- Target Devices: generic +-- Tool versions: xst 8.1, 8.2, 9.1, 9.2, 10.1; ghdl 0.18-0.25 +-- +-- Synthesized (xst): +-- Date Rev ise Target flop lutl lutm slic t peri +-- 2009-07-11 232 10.1.03 K39 xc3s1000-4 11 30 0 19 s 5.8 +-- +-- Revision History: +-- Date Rev Version Comment +-- 2010-06-11 303 1.1 use IB_MREQ.racc instead of RRI_REQ +-- 2009-06-21 228 1.0.1 generate interrupt locally when err=1 +-- 2009-05-30 220 1.0 Initial version +------------------------------------------------------------------------------ +-- +-- Notes: +-- - the ERR bit is just a status flag +-- - no hardware interlock (DONE forced 0 when ERR=1), like in simh +-- - also no interrupt when ERR goes 1, like in simh + + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; + +use work.slvtypes.all; +use work.iblib.all; + +-- ---------------------------------------------------------------------------- +entity ibdr_lp11 is -- ibus dev(rem): LP11 + -- fixed address: 177514 + port ( + CLK : in slbit; -- clock + RESET : in slbit; -- system reset + BRESET : in slbit; -- ibus reset + RRI_LAM : out slbit; -- remote attention + IB_MREQ : in ib_mreq_type; -- ibus request + IB_SRES : out ib_sres_type; -- ibus response + EI_REQ : out slbit; -- interrupt request + EI_ACK : in slbit -- interrupt acknowledge + ); +end ibdr_lp11; + +architecture syn of ibdr_lp11 is + + constant ibaddr_lp11 : slv16 := conv_std_logic_vector(8#177514#,16); + + constant ibaddr_csr : slv1 := "0"; -- csr address offset + constant ibaddr_buf : slv1 := "1"; -- buf address offset + + constant csr_ibf_err : integer := 15; + constant csr_ibf_done : integer := 7; + constant csr_ibf_ie : integer := 6; + constant buf_ibf_val : integer := 8; + + type regs_type is record -- state registers + err : slbit; -- csr: error flag + done : slbit; -- csr: done flag + ie : slbit; -- csr: interrupt enable + buf : slv7; -- buf: + intreq : slbit; -- interrupt request + end record regs_type; + + constant regs_init : regs_type := ( + '1', -- err !! is set !! + '1', -- done !! is set !! + '0', -- ie + (others=>'0'), -- buf + '0' -- intreq + ); + + signal R_REGS : regs_type := regs_init; + signal N_REGS : regs_type := regs_init; + +begin + + proc_regs: process (CLK) + begin + if CLK'event and CLK='1' then + if BRESET = '1' then -- BRESET is 1 for system and ibus reset + R_REGS <= regs_init; + if RESET = '0' then -- if RESET=0 we do just an ibus reset + R_REGS.err <= N_REGS.err; -- don't reset ERR flag + end if; + else + R_REGS <= N_REGS; + end if; + end if; + end process proc_regs; + + proc_next : process (R_REGS, IB_MREQ, EI_ACK) + variable r : regs_type := regs_init; + variable n : regs_type := regs_init; + variable ibsel : slbit := '0'; + variable idout : slv16 := (others=>'0'); + variable ibrd : slbit := '0'; + variable ibw0 : slbit := '0'; + variable ilam : slbit := '0'; + begin + + r := R_REGS; + n := R_REGS; + + ibsel := '0'; + idout := (others=>'0'); + ibrd := not IB_MREQ.we; + ibw0 := IB_MREQ.we and IB_MREQ.be0; + ilam := '0'; + + -- ibus address decoder + if IB_MREQ.req='1' and + IB_MREQ.addr(12 downto 2)=ibaddr_lp11(12 downto 2) then + ibsel := '1'; + end if; + + -- ibus transactions + if ibsel = '1' then + case IB_MREQ.addr(1 downto 1) is + + when ibaddr_csr => -- CSR -- control status ------------- + idout(csr_ibf_err) := r.err; + idout(csr_ibf_done) := r.done; + idout(csr_ibf_ie) := r.ie; + if IB_MREQ.racc = '0' then -- cpu + if ibw0 = '1' then + n.ie := IB_MREQ.din(csr_ibf_ie); + if IB_MREQ.din(csr_ibf_ie) = '1' then + if r.done='1' and r.ie='0' then -- ie set while done=1 + n.intreq := '1'; -- request interrupt + end if; + else + n.intreq := '0'; + end if; + end if; + else -- rri + n.err := IB_MREQ.din(csr_ibf_err); + end if; + + when ibaddr_buf => -- BUF -- data buffer ---------------- + if IB_MREQ.racc = '0' then -- cpu + if ibw0 = '1' then + n.buf := IB_MREQ.din(n.buf'range); + if r.err = '0' then -- if online (handle via rbus) + ilam := '1'; -- request attention + n.done := '0'; -- clear done + n.intreq := '0'; -- clear interrupt + else -- if offline (discard locally) + n.done := '1'; -- set done + if r.ie = '1' then -- if interrupts enabled + n.intreq := '1'; -- request interrupt + end if; + end if; + end if; + else -- rri + idout(r.buf'range) := r.buf; + idout(buf_ibf_val) := not r.done; + if ibrd = '1' then + n.done := '1'; + if r.ie = '1' then + n.intreq := '1'; + end if; + end if; + end if; + + when others => null; + end case; + + end if; + + -- other state changes + if EI_ACK = '1' then + n.intreq := '0'; + end if; + + N_REGS <= n; + + IB_SRES.dout <= idout; + IB_SRES.ack <= ibsel; + IB_SRES.busy <= '0'; + + RRI_LAM <= ilam; + EI_REQ <= r.intreq; + + end process proc_next; + + +end syn; diff --git a/rtl/ibus/ibdr_maxisys.vbom b/rtl/ibus/ibdr_maxisys.vbom new file mode 100644 index 00000000..c5313779 --- /dev/null +++ b/rtl/ibus/ibdr_maxisys.vbom @@ -0,0 +1,17 @@ +# libs +../vlib/slvtypes.vhd +iblib.vhd +ibdlib.vhd +# components +ibd_iist.vbom +ibd_kw11l.vbom +ibdr_rk11.vbom +ibdr_dl11.vbom +ibdr_pc11.vbom +ibdr_lp11.vbom +ibdr_sdreg.vbom +ib_sres_or_4.vbom +ib_sres_or_3.vbom +ib_intmap.vbom +# design +ibdr_maxisys.vhd diff --git a/rtl/ibus/ibdr_maxisys.vhd b/rtl/ibus/ibdr_maxisys.vhd new file mode 100644 index 00000000..786efdd8 --- /dev/null +++ b/rtl/ibus/ibdr_maxisys.vhd @@ -0,0 +1,414 @@ +-- $Id: ibdr_maxisys.vhd 314 2010-07-09 17:38:41Z mueller $ +-- +-- Copyright 2009-2010 by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, 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 complete details. +-- +------------------------------------------------------------------------------ +-- Module Name: ibdr_maxisys - syn +-- Description: ibus(rem) devices for full system +-- +-- Dependencies: ibd_iist +-- ibd_kw11l +-- ibdr_rk11 +-- ibdr_dl11 +-- ibdr_pc11 +-- ibdr_lp11 +-- ibdr_sdreg +-- ib_sres_or_4 +-- ib_sres_or_3 +-- ib_intmap +-- Test bench: - +-- Target Devices: generic +-- Tool versions: xst 8.1, 8.2, 9.1, 9.2; ghdl 0.18-0.25 +-- Revision History: +-- Date Rev Version Comment +-- 2010-06-11 303 1.1 use IB_MREQ.racc instead of RRI_REQ +-- 2009-07-12 233 1.0.4 reorder ports; add RESET, CE_USEC to _dl11 +-- 2009-06-20 227 1.0.3 rename generate labels. +-- 2009-06-07 224 1.0.2 add iist_mreq and iist_sres interfaces +-- 2009-06-01 221 1.0.1 add CE_USEC; add RESET to kw11l; add _pc11, _iist +-- 2009-05-24 219 1.0 Initial version +------------------------------------------------------------------------------ +-- +-- +-- full system setup +-- +-- ibbase vec pri slot attn sror device name +-- +-- 172540 104 ?7 14 17 - 1/1 KW11-P +-- 177500 260 6 13 16 - 1/2 IIST +-- 177546 100 6 12 15 - 1/3 KW11-L +-- 174510 120 5 14 9 1/4 DEUNA +-- 176700 254 5 13 6 2/1 RH70/RP06 +-- 174400 160 5 11 12 5 2/2 RL11 +-- 177400 220 5 10 11 4 2/3 RK11 +-- 172520 224 5 10 7 2/4 TM11 +-- 160100 310? 5 9 9 3 3/1 DZ11-RX +-- 314? 5 8 8 ^ DZ11-TX +-- 177560 060 4 7 7 1 3/2 DL11-RX 1st +-- 064 4 6 6 ^ DL11-TX 1st +-- 176500 300 4 5 5 2 3/3 DL11-RX 2nd +-- 304 4 4 4 ^ DL11-TX 2nd +-- 177550 070 4 3 3 10 4/1 PC11/PTR +-- 074 4 2 2 ^ PC11/PTP +-- 177514 200 4 1 1 8 4/2 LP11 +-- 177570 - - - - 4/3 sdreg +-- + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; + +use work.slvtypes.all; +use work.iblib.all; +use work.ibdlib.all; + +-- ---------------------------------------------------------------------------- +entity ibdr_maxisys is -- ibus(rem) full system + port ( + CLK : in slbit; -- clock + CE_USEC : in slbit; -- usec pulse + CE_MSEC : in slbit; -- msec pulse + RESET : in slbit; -- reset + BRESET : in slbit; -- ibus reset + RRI_LAM : out slv16_1; -- remote attention vector + IB_MREQ : in ib_mreq_type; -- ibus request + IB_SRES : out ib_sres_type; -- ibus response + EI_ACKM : in slbit; -- interrupt acknowledge (from master) + EI_PRI : out slv3; -- interrupt priority (to cpu) + EI_VECT : out slv9_2; -- interrupt vector (to cpu) + DISPREG : out slv16 -- display register + ); +end ibdr_maxisys; + +architecture syn of ibdr_maxisys is + + constant conf_intmap : intmap_array_type := + (intmap_init, -- line 15 + (8#104#,6), -- line 14 KW11-P + (8#260#,6), -- line 13 IIST + (8#100#,6), -- line 12 KW11-L + (8#160#,5), -- line 11 RL11 + (8#220#,5), -- line 10 RK11 + (8#310#,5), -- line 9 DZ11-RX + (8#314#,5), -- line 8 DZ11-TX + (8#060#,4), -- line 7 DL11-RX 1st + (8#064#,4), -- line 6 DL11-TX 1st + (8#300#,4), -- line 5 DL11-RX 2nd + (8#304#,4), -- line 4 DL11-TX 2nd + (8#070#,4), -- line 3 PC11-PTR + (8#074#,4), -- line 2 PC11-PTP + (8#200#,4), -- line 1 LP11 + intmap_init -- line 0 + ); + + signal RRI_LAM_DENUA : slbit := '0'; + signal RRI_LAM_RP06 : slbit := '0'; + signal RRI_LAM_RL11 : slbit := '0'; + signal RRI_LAM_RK11 : slbit := '0'; + signal RRI_LAM_TM11 : slbit := '0'; + signal RRI_LAM_DZ11 : slbit := '0'; + signal RRI_LAM_DL11_0 : slbit := '0'; + signal RRI_LAM_DL11_1 : slbit := '0'; + signal RRI_LAM_PC11 : slbit := '0'; + signal RRI_LAM_LP11 : slbit := '0'; + + signal IB_SRES_IIST : ib_sres_type := ib_sres_init; + signal IB_SRES_KW11P : ib_sres_type := ib_sres_init; + signal IB_SRES_KW11L : ib_sres_type := ib_sres_init; + signal IB_SRES_DEUNA : ib_sres_type := ib_sres_init; + signal IB_SRES_RP06 : ib_sres_type := ib_sres_init; + signal IB_SRES_RL11 : ib_sres_type := ib_sres_init; + signal IB_SRES_RK11 : ib_sres_type := ib_sres_init; + signal IB_SRES_TM11 : ib_sres_type := ib_sres_init; + signal IB_SRES_DZ11 : ib_sres_type := ib_sres_init; + signal IB_SRES_DL11_0 : ib_sres_type := ib_sres_init; + signal IB_SRES_DL11_1 : ib_sres_type := ib_sres_init; + signal IB_SRES_PC11 : ib_sres_type := ib_sres_init; + signal IB_SRES_LP11 : ib_sres_type := ib_sres_init; + signal IB_SRES_SDREG : ib_sres_type := ib_sres_init; + + signal IB_SRES_1 : ib_sres_type := ib_sres_init; + signal IB_SRES_2 : ib_sres_type := ib_sres_init; + signal IB_SRES_3 : ib_sres_type := ib_sres_init; + signal IB_SRES_4 : ib_sres_type := ib_sres_init; + + signal EI_REQ : slv16_1 := (others=>'0'); + signal EI_ACK : slv16_1 := (others=>'0'); + + signal EI_REQ_IIST : slbit := '0'; + signal EI_REQ_KW11P : slbit := '0'; + signal EI_REQ_KW11L : slbit := '0'; + signal EI_REQ_DEUNA : slbit := '0'; + signal EI_REQ_RP06 : slbit := '0'; + signal EI_REQ_RL11 : slbit := '0'; + signal EI_REQ_RK11 : slbit := '0'; + signal EI_REQ_TM11 : slbit := '0'; + signal EI_REQ_DZ11RX : slbit := '0'; + signal EI_REQ_DZ11TX : slbit := '0'; + signal EI_REQ_DL11RX_0 : slbit := '0'; + signal EI_REQ_DL11TX_0 : slbit := '0'; + signal EI_REQ_DL11RX_1 : slbit := '0'; + signal EI_REQ_DL11TX_1 : slbit := '0'; + signal EI_REQ_PC11PTR : slbit := '0'; + signal EI_REQ_PC11PTP : slbit := '0'; + signal EI_REQ_LP11 : slbit := '0'; + + signal EI_ACK_IIST : slbit := '0'; + signal EI_ACK_KW11P : slbit := '0'; + signal EI_ACK_KW11L : slbit := '0'; + signal EI_ACK_DEUNA : slbit := '0'; + signal EI_ACK_RP06 : slbit := '0'; + signal EI_ACK_RL11 : slbit := '0'; + signal EI_ACK_RK11 : slbit := '0'; + signal EI_ACK_TM11 : slbit := '0'; + signal EI_ACK_DZ11RX : slbit := '0'; + signal EI_ACK_DZ11TX : slbit := '0'; + signal EI_ACK_DL11RX_0 : slbit := '0'; + signal EI_ACK_DL11TX_0 : slbit := '0'; + signal EI_ACK_DL11RX_1 : slbit := '0'; + signal EI_ACK_DL11TX_1 : slbit := '0'; + signal EI_ACK_PC11PTR : slbit := '0'; + signal EI_ACK_PC11PTP : slbit := '0'; + signal EI_ACK_LP11 : slbit := '0'; + + signal IIST_BUS : iist_bus_type := iist_bus_init; + signal IIST_OUT_0 : iist_line_type := iist_line_init; + signal IIST_MREQ : iist_mreq_type := iist_mreq_init; + signal IIST_SRES : iist_sres_type := iist_sres_init; + +begin + + IIST: if true generate + begin + I0 : ibd_iist + port map ( + CLK => CLK, + CE_USEC => CE_USEC, + RESET => RESET, + BRESET => BRESET, + IB_MREQ => IB_MREQ, + IB_SRES => IB_SRES_IIST, + EI_REQ => EI_REQ_IIST, + EI_ACK => EI_ACK_IIST, + IIST_BUS => IIST_BUS, + IIST_OUT => IIST_OUT_0, + IIST_MREQ => IIST_MREQ, + IIST_SRES => IIST_SRES + ); + + IIST_BUS(0) <= IIST_OUT_0; + IIST_BUS(1) <= iist_line_init; + IIST_BUS(2) <= iist_line_init; + IIST_BUS(3) <= iist_line_init; + + end generate IIST; + + KW11L : ibd_kw11l + port map ( + CLK => CLK, + CE_MSEC => CE_MSEC, + RESET => RESET, + BRESET => BRESET, + IB_MREQ => IB_MREQ, + IB_SRES => IB_SRES_KW11L, + EI_REQ => EI_REQ_KW11L, + EI_ACK => EI_ACK_KW11L + ); + + RK11: if true generate + begin + I0 : ibdr_rk11 + port map ( + CLK => CLK, + CE_MSEC => CE_MSEC, + BRESET => BRESET, + RRI_LAM => RRI_LAM_RK11, + IB_MREQ => IB_MREQ, + IB_SRES => IB_SRES_RK11, + EI_REQ => EI_REQ_RK11, + EI_ACK => EI_ACK_RK11 + ); + end generate RK11; + + DL11_0 : ibdr_dl11 + port map ( + CLK => CLK, + CE_USEC => CE_USEC, + RESET => RESET, + BRESET => BRESET, + RRI_LAM => RRI_LAM_DL11_0, + IB_MREQ => IB_MREQ, + IB_SRES => IB_SRES_DL11_0, + EI_REQ_RX => EI_REQ_DL11RX_0, + EI_REQ_TX => EI_REQ_DL11TX_0, + EI_ACK_RX => EI_ACK_DL11RX_0, + EI_ACK_TX => EI_ACK_DL11TX_0 + ); + + DL11_1: if true generate + begin + I0 : ibdr_dl11 + generic map ( + IB_ADDR => conv_std_logic_vector(8#176500#,16)) + port map ( + CLK => CLK, + CE_USEC => CE_USEC, + RESET => RESET, + BRESET => BRESET, + RRI_LAM => RRI_LAM_DL11_1, + IB_MREQ => IB_MREQ, + IB_SRES => IB_SRES_DL11_1, + EI_REQ_RX => EI_REQ_DL11RX_1, + EI_REQ_TX => EI_REQ_DL11TX_1, + EI_ACK_RX => EI_ACK_DL11RX_1, + EI_ACK_TX => EI_ACK_DL11TX_1 + ); + end generate DL11_1; + + PC11: if true generate + begin + I0 : ibdr_pc11 + port map ( + CLK => CLK, + RESET => RESET, + BRESET => BRESET, + RRI_LAM => RRI_LAM_PC11, + IB_MREQ => IB_MREQ, + IB_SRES => IB_SRES_PC11, + EI_REQ_PTR => EI_REQ_PC11PTR, + EI_REQ_PTP => EI_REQ_PC11PTP, + EI_ACK_PTR => EI_ACK_PC11PTR, + EI_ACK_PTP => EI_ACK_PC11PTP + ); + end generate PC11; + + LP11: if true generate + begin + I0 : ibdr_lp11 + port map ( + CLK => CLK, + RESET => RESET, + BRESET => BRESET, + RRI_LAM => RRI_LAM_LP11, + IB_MREQ => IB_MREQ, + IB_SRES => IB_SRES_LP11, + EI_REQ => EI_REQ_LP11, + EI_ACK => EI_ACK_LP11 + ); + end generate LP11; + + SDREG : ibdr_sdreg + port map ( + CLK => CLK, + RESET => RESET, + IB_MREQ => IB_MREQ, + IB_SRES => IB_SRES_SDREG, + DISPREG => DISPREG + ); + + SRES_OR_1 : ib_sres_or_4 + port map ( + IB_SRES_1 => IB_SRES_KW11P, + IB_SRES_2 => IB_SRES_IIST, + IB_SRES_3 => IB_SRES_KW11L, + IB_SRES_4 => IB_SRES_DEUNA, + IB_SRES_OR => IB_SRES_1 + ); + + SRES_OR_2 : ib_sres_or_4 + port map ( + IB_SRES_1 => IB_SRES_RP06, + IB_SRES_2 => IB_SRES_RL11, + IB_SRES_3 => IB_SRES_RK11, + IB_SRES_4 => IB_SRES_TM11, + IB_SRES_OR => IB_SRES_2 + ); + + SRES_OR_3 : ib_sres_or_3 + port map ( + IB_SRES_1 => IB_SRES_DZ11, + IB_SRES_2 => IB_SRES_DL11_0, + IB_SRES_3 => IB_SRES_DL11_1, + IB_SRES_OR => IB_SRES_3 + ); + + SRES_OR_4 : ib_sres_or_3 + port map ( + IB_SRES_1 => IB_SRES_PC11, + IB_SRES_2 => IB_SRES_LP11, + IB_SRES_3 => IB_SRES_SDREG, + IB_SRES_OR => IB_SRES_4 + ); + + SRES_OR : ib_sres_or_4 + port map ( + IB_SRES_1 => IB_SRES_1, + IB_SRES_2 => IB_SRES_2, + IB_SRES_3 => IB_SRES_3, + IB_SRES_4 => IB_SRES_4, + IB_SRES_OR => IB_SRES + ); + + INTMAP : ib_intmap + generic map ( + INTMAP => conf_intmap) + port map ( + EI_REQ => EI_REQ, + EI_ACKM => EI_ACKM, + EI_ACK => EI_ACK, + EI_PRI => EI_PRI, + EI_VECT => EI_VECT + ); + + EI_REQ(14) <= EI_REQ_KW11P; + EI_REQ(13) <= EI_REQ_IIST; + EI_REQ(12) <= EI_REQ_KW11L; + EI_REQ(11) <= EI_REQ_RL11; + EI_REQ(10) <= EI_REQ_RK11; + EI_REQ( 9) <= EI_REQ_DZ11RX; + EI_REQ( 8) <= EI_REQ_DZ11TX; + EI_REQ( 7) <= EI_REQ_DL11RX_0; + EI_REQ( 6) <= EI_REQ_DL11TX_0; + EI_REQ( 5) <= EI_REQ_DL11RX_1; + EI_REQ( 4) <= EI_REQ_DL11TX_1; + EI_REQ( 3) <= EI_REQ_PC11PTR; + EI_REQ( 2) <= EI_REQ_PC11PTP; + EI_REQ( 1) <= EI_REQ_LP11; + + EI_ACK_KW11P <= EI_ACK(14); + EI_ACK_IIST <= EI_ACK(13); + EI_ACK_KW11L <= EI_ACK(12); + EI_ACK_RL11 <= EI_ACK(11); + EI_ACK_RK11 <= EI_ACK(10); + EI_ACK_DZ11RX <= EI_ACK( 9); + EI_ACK_DZ11TX <= EI_ACK( 8); + EI_ACK_DL11RX_0 <= EI_ACK( 7); + EI_ACK_DL11TX_0 <= EI_ACK( 6); + EI_ACK_DL11RX_1 <= EI_ACK( 5); + EI_ACK_DL11TX_1 <= EI_ACK( 4); + EI_ACK_PC11PTR <= EI_ACK( 3); + EI_ACK_PC11PTP <= EI_ACK( 2); + EI_ACK_LP11 <= EI_ACK( 1); + + RRI_LAM(15 downto 11) <= (others=>'0'); + RRI_LAM(10) <= RRI_LAM_PC11; + RRI_LAM( 9) <= RRI_LAM_DENUA; + RRI_LAM( 8) <= RRI_LAM_LP11; + RRI_LAM( 7) <= RRI_LAM_TM11; + RRI_LAM( 6) <= RRI_LAM_RP06; + RRI_LAM( 5) <= RRI_LAM_RL11; + RRI_LAM( 4) <= RRI_LAM_RK11; + RRI_LAM( 3) <= RRI_LAM_DZ11; + RRI_LAM( 2) <= RRI_LAM_DL11_1; + RRI_LAM( 1) <= RRI_LAM_DL11_0; + +end syn; diff --git a/rtl/ibus/ibdr_minisys.vbom b/rtl/ibus/ibdr_minisys.vbom new file mode 100644 index 00000000..f1ce9806 --- /dev/null +++ b/rtl/ibus/ibdr_minisys.vbom @@ -0,0 +1,13 @@ +# libs +../vlib/slvtypes.vhd +iblib.vhd +ibdlib.vhd +# components +ibdr_sdreg.vbom +ibd_kw11l.vbom +ibdr_dl11.vbom +ibdr_rk11.vbom +ib_sres_or_4.vbom +ib_intmap.vbom +# design +ibdr_minisys.vhd diff --git a/rtl/ibus/ibdr_minisys.vhd b/rtl/ibus/ibdr_minisys.vhd new file mode 100644 index 00000000..6c04b842 --- /dev/null +++ b/rtl/ibus/ibdr_minisys.vhd @@ -0,0 +1,206 @@ +-- $Id: ibdr_minisys.vhd 314 2010-07-09 17:38:41Z mueller $ +-- +-- Copyright 2008-2010 by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, 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 complete details. +-- +------------------------------------------------------------------------------ +-- Module Name: ibdr_minisys - syn +-- Description: ibus(rem) devices for minimal system:SDR+KW+DL+RK +-- +-- Dependencies: ibdr_sdreg +-- ibd_kw11l +-- ibdr_dl11 +-- ibdr_rk11 +-- ib_sres_or_4 +-- ib_intmap +-- Test bench: - +-- Target Devices: generic +-- Tool versions: xst 8.1, 8.2, 9.1, 9.2; ghdl 0.18-0.25 +-- Revision History: +-- Date Rev Version Comment +-- 2010-06-11 303 1.1 use IB_MREQ.racc instead of RRI_REQ +-- 2009-07-12 233 1.0.7 reorder ports, add CE_USEC; add RESET and CE_USEC +-- to _dl11 +-- 2009-05-31 221 1.0.6 add RESET to kw11l; +-- 2009-05-24 219 1.0.5 _rk11 uses now CE_MSEC +-- 2008-08-22 161 1.0.4 use iblib, ibdlib +-- 2008-05-09 144 1.0.3 use EI_ACK with _kw11l, _dl11 +-- 2008-04-18 136 1.0.2 add RESET port, use for ibdr_sdreg +-- 2008-01-20 113 1.0.1 RRI_LAM now vector +-- 2008-01-20 112 1.0 Initial version +------------------------------------------------------------------------------ +-- +-- mini system setup +-- +-- ibbase vec pri slot attn device name +-- +-- 177546 100 6 4 - KW11-L +-- 177400 220 5 3 4 RK11 +-- 177560 060 4 2 1 DL11-RX 1st +-- 064 4 1 ^ DL11-TX 1st +-- 177570 - - - - sdreg +-- + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; + +use work.slvtypes.all; +use work.iblib.all; +use work.ibdlib.all; + +-- ---------------------------------------------------------------------------- +entity ibdr_minisys is -- ibus(rem) minimal sys:SDR+KW+DL+RK + port ( + CLK : in slbit; -- clock + CE_USEC : in slbit; -- usec pulse + CE_MSEC : in slbit; -- msec pulse + RESET : in slbit; -- reset + BRESET : in slbit; -- ibus reset + RRI_LAM : out slv16_1; -- remote attention vector + IB_MREQ : in ib_mreq_type; -- ibus request + IB_SRES : out ib_sres_type; -- ibus response + EI_ACKM : in slbit; -- interrupt acknowledge (from master) + EI_PRI : out slv3; -- interrupt priority (to cpu) + EI_VECT : out slv9_2; -- interrupt vector (to cpu) + DISPREG : out slv16 -- display register + ); +end ibdr_minisys; + +architecture syn of ibdr_minisys is + + constant conf_intmap : intmap_array_type := + (intmap_init, -- line 15 + intmap_init, -- line 14 + intmap_init, -- line 13 + intmap_init, -- line 12 + intmap_init, -- line 11 + intmap_init, -- line 10 + intmap_init, -- line 9 + intmap_init, -- line 8 + intmap_init, -- line 7 + intmap_init, -- line 6 + intmap_init, -- line 5 + (8#100#,6), -- line 4 KW11-L + (8#220#,5), -- line 3 RK11 + (8#060#,4), -- line 2 DL11-RX + (8#064#,4), -- line 1 DL11-TX + intmap_init -- line 0 + ); + + signal RRI_LAM_DL11 : slbit := '0'; + signal RRI_LAM_RK11 : slbit := '0'; + + signal IB_SRES_SDREG : ib_sres_type := ib_sres_init; + signal IB_SRES_KW11L : ib_sres_type := ib_sres_init; + signal IB_SRES_DL11 : ib_sres_type := ib_sres_init; + signal IB_SRES_RK11 : ib_sres_type := ib_sres_init; + + signal EI_REQ : slv16_1 := (others=>'0'); + signal EI_ACK : slv16_1 := (others=>'0'); + + signal EI_REQ_KW11L : slbit := '0'; + signal EI_REQ_DL11RX : slbit := '0'; + signal EI_REQ_DL11TX : slbit := '0'; + signal EI_REQ_RK11 : slbit := '0'; + + signal EI_ACK_KW11L : slbit := '0'; + signal EI_ACK_DL11RX : slbit := '0'; + signal EI_ACK_DL11TX : slbit := '0'; + signal EI_ACK_RK11 : slbit := '0'; + +begin + + SDREG : ibdr_sdreg + port map ( + CLK => CLK, + RESET => RESET, + IB_MREQ => IB_MREQ, + IB_SRES => IB_SRES_SDREG, + DISPREG => DISPREG + ); + + KW11L : ibd_kw11l + port map ( + CLK => CLK, + CE_MSEC => CE_MSEC, + RESET => RESET, + BRESET => BRESET, + IB_MREQ => IB_MREQ, + IB_SRES => IB_SRES_KW11L, + EI_REQ => EI_REQ_KW11L, + EI_ACK => EI_ACK_KW11L + ); + + DL11 : ibdr_dl11 + port map ( + CLK => CLK, + CE_USEC => CE_USEC, + RESET => RESET, + BRESET => BRESET, + RRI_LAM => RRI_LAM_DL11, + IB_MREQ => IB_MREQ, + IB_SRES => IB_SRES_DL11, + EI_REQ_RX => EI_REQ_DL11RX, + EI_REQ_TX => EI_REQ_DL11TX, + EI_ACK_RX => EI_ACK_DL11RX, + EI_ACK_TX => EI_ACK_DL11TX + ); + + RK11 : ibdr_rk11 + port map ( + CLK => CLK, + CE_MSEC => CE_MSEC, + BRESET => BRESET, + RRI_LAM => RRI_LAM_RK11, + IB_MREQ => IB_MREQ, + IB_SRES => IB_SRES_RK11, + EI_REQ => EI_REQ_RK11, + EI_ACK => EI_ACK_RK11 + ); + + SRES_OR : ib_sres_or_4 + port map ( + IB_SRES_1 => IB_SRES_SDREG, + IB_SRES_2 => IB_SRES_KW11L, + IB_SRES_3 => IB_SRES_DL11, + IB_SRES_4 => IB_SRES_RK11, + IB_SRES_OR => IB_SRES + ); + + INTMAP : ib_intmap + generic map ( + INTMAP => conf_intmap) + port map ( + EI_REQ => EI_REQ, + EI_ACKM => EI_ACKM, + EI_ACK => EI_ACK, + EI_PRI => EI_PRI, + EI_VECT => EI_VECT + ); + + EI_REQ(4) <= EI_REQ_KW11L; + EI_REQ(3) <= EI_REQ_RK11; + EI_REQ(2) <= EI_REQ_DL11RX; + EI_REQ(1) <= EI_REQ_DL11TX; + + EI_ACK_KW11L <= EI_ACK(4); + EI_ACK_RK11 <= EI_ACK(3); + EI_ACK_DL11RX <= EI_ACK(2); + EI_ACK_DL11TX <= EI_ACK(1); + + RRI_LAM(1) <= RRI_LAM_DL11; + RRI_LAM(2) <= '0'; -- for 2nd DL11 + RRI_LAM(3) <= '0'; -- for DZ11 + RRI_LAM(4) <= RRI_LAM_RK11; + RRI_LAM(15 downto 5) <= (others=>'0'); + +end syn; diff --git a/rtl/ibus/ibdr_pc11.vbom b/rtl/ibus/ibdr_pc11.vbom new file mode 100644 index 00000000..7f51265d --- /dev/null +++ b/rtl/ibus/ibdr_pc11.vbom @@ -0,0 +1,5 @@ +# libs +../vlib/slvtypes.vhd +iblib.vhd +# design +ibdr_pc11.vhd diff --git a/rtl/ibus/ibdr_pc11.vhd b/rtl/ibus/ibdr_pc11.vhd new file mode 100644 index 00000000..98384a68 --- /dev/null +++ b/rtl/ibus/ibdr_pc11.vhd @@ -0,0 +1,314 @@ +-- $Id: ibdr_pc11.vhd 314 2010-07-09 17:38:41Z mueller $ +-- +-- Copyright 2009-2010 by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, 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 complete details. +-- +------------------------------------------------------------------------------ +-- Module Name: ibdr_pc11 - syn +-- Description: ibus dev(rem): PC11 +-- +-- Dependencies: - +-- Test bench: xxdp: zpcae0 +-- Target Devices: generic +-- Tool versions: xst 8.1, 8.2, 9.1, 9.2; ghdl 0.18-0.25 +-- +-- Synthesized (xst): +-- Date Rev ise Target flop lutl lutm slic t peri +-- 2009-06-28 230 10.1.03 K39 xc3s1000-4 25 92 0 54 s 4.9 +-- +-- Revision History: +-- Date Rev Version Comment +-- 2010-06-11 303 1.1 use IB_MREQ.racc instead of RRI_REQ +-- 2009-06-28 230 1.0 prdy now inits to '1'; setting err bit in csr now +-- causes interrupt, if enabled; validated with zpcae0 +-- 2009-06-01 221 0.9 Initial version (untested) +------------------------------------------------------------------------------ + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; + +use work.slvtypes.all; +use work.iblib.all; + +-- ---------------------------------------------------------------------------- +entity ibdr_pc11 is -- ibus dev(rem): PC11 + -- fixed address: 177550 + port ( + CLK : in slbit; -- clock + RESET : in slbit; -- system reset + BRESET : in slbit; -- ibus reset + RRI_LAM : out slbit; -- remote attention + IB_MREQ : in ib_mreq_type; -- ibus request + IB_SRES : out ib_sres_type; -- ibus response + EI_REQ_PTR : out slbit; -- interrupt request, reader + EI_REQ_PTP : out slbit; -- interrupt request, punch + EI_ACK_PTR : in slbit; -- interrupt acknowledge, reader + EI_ACK_PTP : in slbit -- interrupt acknowledge, punch + ); +end ibdr_pc11; + +architecture syn of ibdr_pc11 is + + constant ibaddr_pc11 : slv16 := conv_std_logic_vector(8#177550#,16); + + constant ibaddr_rcsr : slv2 := "00"; -- rcsr address offset + constant ibaddr_rbuf : slv2 := "01"; -- rbuf address offset + constant ibaddr_pcsr : slv2 := "10"; -- pcsr address offset + constant ibaddr_pbuf : slv2 := "11"; -- pbuf address offset + + constant rcsr_ibf_rerr : integer := 15; + constant rcsr_ibf_rbusy : integer := 11; + constant rcsr_ibf_rdone : integer := 7; + constant rcsr_ibf_rie : integer := 6; + constant rcsr_ibf_renb : integer := 0; + + constant pcsr_ibf_perr : integer := 15; + constant pcsr_ibf_prdy : integer := 7; + constant pcsr_ibf_pie : integer := 6; + + constant pbuf_ibf_pval : integer := 8; + constant pbuf_ibf_rbusy : integer := 9; + + type regs_type is record -- state registers + rerr : slbit; -- rcsr: reader error + rbusy : slbit; -- rcsr: reader busy + rdone : slbit; -- rcsr: reader done + rie : slbit; -- rcsr: reader interrupt enable + rbuf : slv8; -- rbuf: + rintreq : slbit; -- ptr interrupt request + perr : slbit; -- pcsr: punch error + prdy : slbit; -- pcsr: punch ready + pie : slbit; -- pcsr: punch interrupt enable + pbuf : slv8; -- pbuf: + pintreq : slbit; -- ptp interrupt request + end record regs_type; + + constant regs_init : regs_type := ( + '1', -- rerr (init=1!) + '0','0','0', -- rbusy,rdone,rie + (others=>'0'), -- rbuf + '0', -- rintreq + '1', -- perr (init=1!) + '1', -- prdy (init=1!) + '0', -- pie + (others=>'0'), -- pbuf + '0' -- pintreq + ); + + signal R_REGS : regs_type := regs_init; + signal N_REGS : regs_type := regs_init; + +begin + + proc_regs: process (CLK) + begin + if CLK'event and CLK='1' then + if BRESET = '1' then -- BRESET is 1 for system and ibus reset + R_REGS <= regs_init; -- + if RESET = '0' then -- if RESET=0 we do just an ibus reset + R_REGS.rerr <= N_REGS.rerr; -- don't reset RERR flag + R_REGS.perr <= N_REGS.perr; -- don't reset PERR flag + end if; + else + R_REGS <= N_REGS; + end if; + end if; + end process proc_regs; + + proc_next : process (R_REGS, IB_MREQ, EI_ACK_PTR, EI_ACK_PTP) + variable r : regs_type := regs_init; + variable n : regs_type := regs_init; + variable ibsel : slbit := '0'; + variable idout : slv16 := (others=>'0'); + variable ibrd : slbit := '0'; + variable ibw0 : slbit := '0'; + variable ibw1 : slbit := '0'; + variable ilam : slbit := '0'; + begin + + r := R_REGS; + n := R_REGS; + + ibsel := '0'; + idout := (others=>'0'); + ibrd := not IB_MREQ.we; + ibw0 := IB_MREQ.we and IB_MREQ.be0; + ibw1 := IB_MREQ.we and IB_MREQ.be1; + ilam := '0'; + + -- ibus address decoder + if IB_MREQ.req='1' and + IB_MREQ.addr(12 downto 3)=ibaddr_pc11(12 downto 3) then + ibsel := '1'; + end if; + + -- ibus transactions + if ibsel = '1' then + case IB_MREQ.addr(2 downto 1) is + + when ibaddr_rcsr => -- RCSR -- reader control status ----- + + idout(rcsr_ibf_rerr) := r.rerr; + idout(rcsr_ibf_rbusy) := r.rbusy; + idout(rcsr_ibf_rdone) := r.rdone; + idout(rcsr_ibf_rie) := r.rie; + + if IB_MREQ.racc = '0' then -- cpu --------------------- + if ibw0 = '1' then + n.rie := IB_MREQ.din(rcsr_ibf_rie); + if IB_MREQ.din(rcsr_ibf_rie) = '1' then-- set IE to 1 + if r.rie = '0' and -- IE 0->1 transition + IB_MREQ.din(rcsr_ibf_renb)='0' and -- when RENB not set + (r.rerr='1' or r.rdone='1') then -- but err or done set + n.rintreq := '1'; -- request interrupt + end if; + else -- set IE to 0 + n.rintreq := '0'; -- cancel interrupts + end if; + if IB_MREQ.din(rcsr_ibf_renb) = '1' then -- set RENB + if r.rerr = '0' then -- if not in error state + n.rbusy := '1'; -- set busy + n.rdone := '0'; -- clear done + n.rbuf := (others=>'0'); -- clear buffer + n.rintreq := '0'; -- cancel interrupt + ilam := '1'; -- rri lam + else -- if in error state + if r.rie = '1' then -- if interrupts on + n.rintreq := '1'; -- request interrupt + end if; + end if; + end if; + end if; + + else -- rri --------------------- + if ibw1 = '1' then + n.rerr := IB_MREQ.din(rcsr_ibf_rerr); -- set ERR bit + if IB_MREQ.din(rcsr_ibf_rerr)='1' -- if 0->1 transition + and r.rerr='0' then + n.rbusy := '0'; -- clear busy + n.rdone := '0'; -- clear done + if r.rie = '1' then -- if interrupts on + n.rintreq := '1'; -- request interrupt + end if; + end if; + end if; + end if; + + when ibaddr_rbuf => -- RBUF -- reader data buffer -------- + + idout(r.rbuf'range) := r.rbuf; + + if IB_MREQ.racc = '0' then -- cpu --------------------- + if true then -- !! PC11 is unusual !! + n.rdone := '0'; -- any read or write will clear done + n.rbuf := (others=>'0'); -- and the reader buffer + n.rintreq := '0'; -- also interrupt is canceled + end if; + + else -- rri --------------------- + if ibw0 = '1' then + n.rbuf := IB_MREQ.din(n.rbuf'range); + n.rbusy := '0'; + n.rdone := '1'; + if r.rie = '1' then + n.rintreq := '1'; + end if; + end if; + end if; + + when ibaddr_pcsr => -- PCSR -- punch control status ------ + + idout(pcsr_ibf_perr) := r.perr; + idout(pcsr_ibf_prdy) := r.prdy; + idout(pcsr_ibf_pie) := r.pie; + + if IB_MREQ.racc = '0' then -- cpu --------------------- + if ibw0 = '1' then + n.pie := IB_MREQ.din(pcsr_ibf_pie); + if IB_MREQ.din(pcsr_ibf_pie) = '1' then-- set IE to 1 + if r.pie='0' and -- IE 0->1 transition + (r.perr='1' or r.prdy='1') then -- but err or done set + n.pintreq := '1'; -- request interrupt + end if; + else -- set IE to 0 + n.pintreq := '0'; -- cancel interrupts + end if; + end if; + + else -- rri --------------------- + if ibw1 = '1' then + n.perr := IB_MREQ.din(pcsr_ibf_perr); -- set ERR bit + if IB_MREQ.din(pcsr_ibf_perr)='1' -- if 0->1 transition + and r.perr='0' then + n.prdy := '1'; -- set ready + if r.pie = '1' then -- if interrupts on + n.pintreq := '1'; -- request interrupt + end if; + end if; + end if; + end if; + + when ibaddr_pbuf => -- PBUF -- punch data buffer --------- + + if IB_MREQ.racc = '0' then -- cpu --------------------- + if ibw0 = '1' then + if r.perr = '0' then -- if not in error state + n.pbuf := IB_MREQ.din(n.pbuf'range); + n.prdy := '0'; -- clear ready + n.pintreq := '0'; -- cancel interrupts + ilam := '1'; -- rri lam + else -- if in error state + if r.pie = '1' then -- if interrupts on + n.pintreq := '1'; -- request interrupt + end if; + end if; + end if; + + else -- rri --------------------- + idout(r.pbuf'range) := r.pbuf; + idout(pbuf_ibf_pval) := not r.prdy; + idout(pbuf_ibf_rbusy) := r.rbusy; + if ibrd = '1' then + n.prdy := '1'; + if r.pie = '1' then + n.pintreq := '1'; + end if; + end if; + end if; + + when others => null; + end case; + + end if; + + -- other state changes + if EI_ACK_PTR = '1' then + n.rintreq := '0'; + end if; + if EI_ACK_PTP = '1' then + n.pintreq := '0'; + end if; + + N_REGS <= n; + + IB_SRES.dout <= idout; + IB_SRES.ack <= ibsel; + IB_SRES.busy <= '0'; + + RRI_LAM <= ilam; + EI_REQ_PTR <= r.rintreq; + EI_REQ_PTP <= r.pintreq; + + end process proc_next; + + +end syn; diff --git a/rtl/ibus/ibdr_rk11.vbom b/rtl/ibus/ibdr_rk11.vbom new file mode 100644 index 00000000..b40fe6bf --- /dev/null +++ b/rtl/ibus/ibdr_rk11.vbom @@ -0,0 +1,9 @@ +# libs +../vlib/slvtypes.vhd +../vlib/memlib/memlib.vhd +iblib.vhd +# components +[ghdl,isim]../vlib/memlib/ram_1swar_gen.vbom +[xst]../vlib/memlib/ram_1swar_gen_unisim.vbom +# design +ibdr_rk11.vhd diff --git a/rtl/ibus/ibdr_rk11.vhd b/rtl/ibus/ibdr_rk11.vhd new file mode 100644 index 00000000..724321aa --- /dev/null +++ b/rtl/ibus/ibdr_rk11.vhd @@ -0,0 +1,474 @@ +-- $Id: ibdr_rk11.vhd 314 2010-07-09 17:38:41Z mueller $ +-- +-- Copyright 2008-2010 by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, 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 complete details. +-- +------------------------------------------------------------------------------ +-- Module Name: ibdr_rk11 - syn +-- Description: ibus dev(rem): RK11-A/B +-- +-- Dependencies: ram_1swar_gen +-- Test bench: - +-- Target Devices: generic +-- Tool versions: xst 8.1, 8.2, 9.1, 9.2; ghdl 0.18-0.25 +-- +-- Synthesized (xst): +-- Date Rev ise Target flop lutl lutm slic t peri +-- 2009-06-01 221 10.1.03 K39 xc3s1000-4 46 249 16 148 s 7.1 +-- 2008-01-06 111 8.2.03 I34 xc3s1000-4 36 189 16 111 s 6.0 +-- +-- Revision History: +-- Date Rev Version Comment +-- 2010-06-11 303 1.1 use IB_MREQ.racc instead of RRI_REQ +-- 2009-05-24 219 1.0.9 add CE_MSEC input; inc sector counter every msec +-- BUGFIX: sector counter now counts 000,...,013. +-- 2009-05-21 217 1.0.8 cancel pending interrupt requests when IE=0 +-- 2009-05-16 216 1.0.7 BUGFIX: correct interrupt on IE 0->1 logic +-- BUGFIX: re-work the seek complete handling +-- 2008-08-22 161 1.0.6 use iblib +-- 2008-05-30 151 1.0.5 BUGFIX: do control reset locally now, add CRDONE +-- 2008-03-30 131 1.0.4 issue interrupt when IDE bit set with GO=0 +-- 2008-02-23 118 1.0.3 remove redundant condition in rkda access code +-- fix bug in control reset logic (we's missing) +-- 2008-01-20 113 1.0.2 Fix busy handling when control reset done +-- 2008-01-20 112 1.0.1 Fix scp handling; use BRESET +-- 2008-01-06 111 1.0 Initial version +------------------------------------------------------------------------------ + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; + +use work.slvtypes.all; +use work.memlib.all; +use work.iblib.all; + +-- ---------------------------------------------------------------------------- +entity ibdr_rk11 is -- ibus dev(rem): RK11 + -- fixed address: 177400 + port ( + CLK : in slbit; -- clock + CE_MSEC : in slbit; -- msec pulse + BRESET : in slbit; -- ibus reset + RRI_LAM : out slbit; -- remote attention + IB_MREQ : in ib_mreq_type; -- ibus request + IB_SRES : out ib_sres_type; -- ibus response + EI_REQ : out slbit; -- interrupt request + EI_ACK : in slbit -- interrupt acknowledge + ); +end ibdr_rk11; + +architecture syn of ibdr_rk11 is + + constant ibaddr_rk11 : slv16 := conv_std_logic_vector(8#177400#,16); + + constant ibaddr_rkds : slv3 := "000"; -- rkds address offset + constant ibaddr_rker : slv3 := "001"; -- rker address offset + constant ibaddr_rkcs : slv3 := "010"; -- rkcs address offset + constant ibaddr_rkwc : slv3 := "011"; -- rkwc address offset + constant ibaddr_rkba : slv3 := "100"; -- rkba address offset + constant ibaddr_rkda : slv3 := "101"; -- rkba address offset + constant ibaddr_rkmr : slv3 := "110"; -- rkmr address offset + constant ibaddr_rkdb : slv3 := "111"; -- rkdb address offset + + subtype rkds_ibf_id is integer range 15 downto 13; + constant rkds_ibf_adry : integer := 6; + constant rkds_ibf_scsa : integer := 4; + subtype rkds_ibf_sc is integer range 3 downto 0; + + subtype rker_ibf_he is integer range 15 downto 5; + constant rker_ibf_cse : integer := 1; + constant rker_ibf_wce : integer := 0; + + constant rkcs_ibf_err : integer := 15; + constant rkcs_ibf_he : integer := 14; + constant rkcs_ibf_scp : integer := 13; + constant rkcs_ibf_maint : integer := 12; + constant rkcs_ibf_rdy : integer := 7; + constant rkcs_ibf_ide : integer := 6; + subtype rkcs_ibf_mex is integer range 5 downto 4; + subtype rkcs_ibf_func is integer range 3 downto 1; + constant rkcs_ibf_go : integer := 0; + + subtype rkda_ibf_drsel is integer range 15 downto 13; + + subtype rkmr_ibf_rid is integer range 15 downto 13; -- rem id + constant rkmr_ibf_crdone: integer := 11; -- contr. reset done + constant rkmr_ibf_sbclr : integer := 10; -- clear sbusy's + constant rkmr_ibf_creset: integer := 9; -- control reset + constant rkmr_ibf_fdone : integer := 8; -- func done + subtype rkmr_ibf_sdone is integer range 7 downto 0; -- seek done + + type state_type is ( + s_idle, + s_init + ); + + type regs_type is record -- state registers + state : state_type; -- state + id : slv3; -- rkds: drive id of search done + sc : slv4; -- rkds: sector counter + cse : slbit; -- rker: check sum error + wce : slbit; -- rker: write check error + he : slbit; -- rkcs: hard error + scp : slbit; -- rkcs: seek complete + maint : slbit; -- rkcs: maintenance mode + rdy : slbit; -- rkcs: control ready + ide : slbit; -- rkcs: interrupt on done enable + drsel : slv3; -- rkda: currently selected drive + fireq : slbit; -- func done interrupt request flag + sireq : slv8; -- seek done interrupt request flags + sbusy : slv8; -- seek busy flags + rid : slv3; -- drive id for rem ds reads + icnt : slv3; -- init state counter + creset : slbit; -- control reset flag + crdone : slbit; -- control reset done since last fdone + end record regs_type; + + constant regs_init : regs_type := ( + s_init, -- + (others=>'0'), -- id + (others=>'0'), -- sc + '0','0', -- cse, wce + '0','0','0', -- he, scp, maint + '1', -- rdy (SET TO 1) + '0', -- ide + (others=>'0'), -- drsel + '0', -- fireq + (others=>'0'), -- sireq + (others=>'0'), -- sbusy + (others=>'0'), -- rid + (others=>'0'), -- icnt + '0','1' -- creset, crdone + ); + + signal R_REGS : regs_type := regs_init; + signal N_REGS : regs_type := regs_init; + + signal MEM_1_WE : slbit := '0'; + signal MEM_0_WE : slbit := '0'; + signal MEM_ADDR : slv4 := (others=>'0'); + signal MEM_DIN : slv16 := (others=>'0'); + signal MEM_DOUT : slv16 := (others=>'0'); + +begin + + MEM_1 : ram_1swar_gen + generic map ( + AWIDTH => 4, + DWIDTH => 8) + port map ( + CLK => CLK, + WE => MEM_1_WE, + ADDR => MEM_ADDR, + DI => MEM_DIN(ibf_byte1), + DO => MEM_DOUT(ibf_byte1)); + + MEM_0 : ram_1swar_gen + generic map ( + AWIDTH => 4, + DWIDTH => 8) + port map ( + CLK => CLK, + WE => MEM_0_WE, + ADDR => MEM_ADDR, + DI => MEM_DIN(ibf_byte0), + DO => MEM_DOUT(ibf_byte0)); + + proc_regs: process (CLK) + begin + if CLK'event and CLK='1' then + if BRESET='1' or R_REGS.creset='1' then + R_REGS <= regs_init; + if R_REGS.creset = '1' then + R_REGS.sbusy <= N_REGS.sbusy; + end if; + else + R_REGS <= N_REGS; + end if; + end if; + end process proc_regs; + + proc_next : process (R_REGS, CE_MSEC, IB_MREQ, MEM_DOUT, EI_ACK) + variable r : regs_type := regs_init; + variable n : regs_type := regs_init; + variable ibsel : slbit := '0'; + variable ibbusy : slbit := '0'; + variable icrip : slbit := '0'; + variable idout : slv16 := (others=>'0'); + variable ibrd : slbit := '0'; + variable ibrem : slbit := '0'; + variable ibw0 : slbit := '0'; + variable ibw1 : slbit := '0'; + variable ibwrem : slbit := '0'; + variable ilam : slbit := '0'; + variable iscval : slbit := '0'; + variable iscid : slv3 := (others=>'0'); + variable iei_req : slbit := '0'; + + variable imem_we0 : slbit := '0'; + variable imem_we1 : slbit := '0'; + variable imem_addr : slv4 := (others=>'0'); + variable imem_din : slv16 := (others=>'0'); + begin + + r := R_REGS; + n := R_REGS; + + ibsel := '0'; + ibbusy := '0'; + icrip := '0'; + idout := (others=>'0'); + ibrd := not IB_MREQ.we; + ibrem := IB_MREQ.racc or r.maint; + ibw0 := IB_MREQ.we and IB_MREQ.be0; + ibw1 := IB_MREQ.we and IB_MREQ.be1; + ibwrem := IB_MREQ.we and ibrem; + ilam := '0'; + iscval := '0'; + iscid := (others=>'0'); + iei_req := '0'; + + imem_we0 := '0'; + imem_we1 := '0'; + imem_addr := '0' & IB_MREQ.addr(3 downto 1); + imem_din := IB_MREQ.din; + + -- ibus address decoder + if IB_MREQ.req = '1' and + IB_MREQ.addr(12 downto 4)=ibaddr_rk11(12 downto 4) then + ibsel := '1'; + end if; + + -- internal state machine (for control reset) + case r.state is + when s_idle => + null; + + when s_init => + ibbusy := ibsel; -- keep req pending if selected + ibsel := '0'; -- but don't process selection + icrip := '1'; + n.icnt := unsigned(r.icnt) + 1; + if unsigned(r.icnt) = 7 then + n.state := s_idle; + end if; + + when others => null; + end case; + + + -- ibus transactions + if ibsel = '1' then + idout := MEM_DOUT; + imem_we0 := ibw0; + imem_we1 := ibw1; + + case IB_MREQ.addr(3 downto 1) is + + when ibaddr_rkds => -- RKDS -- drive status register ---- + if ibrem = '0' then + imem_addr := '1' & r.drsel; -- loc read ds data: drsel as addr. + else + imem_addr := '1' & r.rid; -- rem read ds data: rid as addr. + end if; + idout(rkds_ibf_id) := r.id; + if ibrem = '0' then -- loc ? simulate drive sector monitor + if r.sc = MEM_DOUT(rkds_ibf_sc) then + idout(rkds_ibf_scsa) := '1'; + else + idout(rkds_ibf_scsa) := '0'; + end if; + idout(rkds_ibf_sc) := r.sc; + end if; + + if r.sbusy(conv_integer(unsigned(imem_addr(2 downto 0))))='1' then + idout(rkds_ibf_adry) := '0'; -- clear drive access rdy + end if; + + if ibwrem = '1' then -- rem write ? than update ds data + imem_addr := '1' & IB_MREQ.din(rkds_ibf_id); -- use id field as addr + else -- loc write ? + imem_we0 := '0'; -- suppress we, is read-only + imem_we1 := '0'; + end if; + + when ibaddr_rker => -- RKER -- error register ------------ + idout(4 downto 2) := (others=>'0'); -- unassigned bits + idout(rker_ibf_cse) := r.cse; -- use state bits (cleared at go !) + idout(rker_ibf_wce) := r.wce; + + if ibwrem = '1' then -- rem write ? + if unsigned(IB_MREQ.din(rker_ibf_he)) /= 0 then -- hard errors set ? + n.he := '1'; + else + n.he := '0'; + end if; + n.cse := IB_MREQ.din(rker_ibf_cse); -- mirror cse bit + n.wce := IB_MREQ.din(rker_ibf_wce); -- mirror wce bit + else -- loc write ? + imem_we0 := '0'; -- suppress we, is read-only + imem_we1 := '0'; + end if; + + when ibaddr_rkcs => -- RKCS -- control status register --- + idout(rkcs_ibf_err) := r.he or r.cse or r.wce; + idout(rkcs_ibf_he) := r.he; + idout(rkcs_ibf_scp) := r.scp; + idout(rkcs_ibf_rdy) := r.rdy; + idout(rkcs_ibf_go) := not r.rdy; + + if ibw1 = '1' then + n.maint := IB_MREQ.din(rkcs_ibf_maint); -- mirror maint bit + end if; + + if ibw0 = '1' then + n.ide := IB_MREQ.din(rkcs_ibf_ide); -- mirror ide bit + if n.ide = '0' then -- if IE 0 or set to 0 + n.fireq := '0'; -- cancel all pending + n.sireq := (others=>'0'); -- interrupt requests + end if; + + if IB_MREQ.din(rkcs_ibf_go) = '1' then -- GO=1 ? + if r.rdy = '1' then -- ready and GO ? + n.scp := '0'; -- go clears scp ! + n.rdy := '0'; -- mark busy + n.cse := '0'; -- clear soft errors + n.wce := '0'; + n.fireq := '0'; -- cancel pend. int + + if unsigned(IB_MREQ.din(rkcs_ibf_func))=0 then -- control reset? + n.creset := '1'; -- handle locally + else + ilam := '1'; -- issue lam + end if; + + if unsigned(IB_MREQ.din(rkcs_ibf_func))=4 or -- if seek + unsigned(IB_MREQ.din(rkcs_ibf_func))=6 then -- or drive reset + n.sbusy(conv_integer(unsigned(r.drsel))) := '1'; -- set busy + end if; + + end if; + else -- GO=0 + if r.ide = '0' and -- if ide now 0 + IB_MREQ.din(rkcs_ibf_ide)='1' and -- and is set to 1 + r.rdy='1' then -- and controller ready + n.fireq := '1'; -- issue interrupt + end if; + end if; + end if; + + when ibaddr_rkda => -- RKDA -- disk address register ----- + if ibrem = '0' then -- loc access ? + if r.rdy = '0' then -- controller busy ? + imem_we0 := '0'; -- suppress write + imem_we1 := '0'; + end if; + end if; + if imem_we1 = '1' then + n.drsel := IB_MREQ.din(rkda_ibf_drsel); -- mirror drsel bits + end if; + + when ibaddr_rkmr => -- RKMR -- maintenance register ------ + idout := (others=>'0'); + idout(rkmr_ibf_rid) := r.rid; + idout(rkmr_ibf_crdone) := r.crdone; + idout(rkmr_ibf_sdone) := r.sbusy; + if ibwrem = '1' then -- rem write ? + n.rid := IB_MREQ.din(rkmr_ibf_rid); + + if r.ide='1' and IB_MREQ.din(rkmr_ibf_sbclr)='0' then + n.sireq := r.sireq or (IB_MREQ.din(rkmr_ibf_sdone) and r.sbusy); + end if; + n.sbusy := r.sbusy and not IB_MREQ.din(rkmr_ibf_sdone); + + if IB_MREQ.din(rkmr_ibf_fdone) = '1' then -- func completed + n.rdy := '1'; + n.crdone := '0'; + if r.ide = '1' then + n.fireq := '1'; + end if; + end if; + if IB_MREQ.din(rkmr_ibf_creset) = '1' then -- control reset + n.creset := '1'; + end if; + end if; + + when others => -- all other regs + null; + + end case; + + end if; + + iscval := '1'; + if r.sireq(7) = '1' then iscid := "111"; + elsif r.sireq(6) = '1' then iscid := "110"; + elsif r.sireq(5) = '1' then iscid := "101"; + elsif r.sireq(4) = '1' then iscid := "100"; + elsif r.sireq(3) = '1' then iscid := "011"; + elsif r.sireq(2) = '1' then iscid := "010"; + elsif r.sireq(1) = '1' then iscid := "001"; + elsif r.sireq(0) = '1' then iscid := "000"; + else + iscval := '0'; + end if; + + if r.ide = '1' then + if r.fireq='1' or iscval='1' then + iei_req := '1'; + end if; + end if; + + if EI_ACK = '1' then -- interrupt executed + if r.fireq = '1' then + n.scp := '0'; -- clear scp flag, is command end + n.fireq := '0'; + elsif iscval = '1' then -- was a seek done + n.scp := '1'; -- signal seek complete interrupt + n.id := iscid; -- load id + n.sireq(conv_integer(unsigned(iscid))) := '0'; -- reset sireq bit + end if; + end if; + + if icrip = '1' then -- control reset in progress ? + imem_addr := '0' & r.icnt; -- use icnt as addr + imem_din := (others=>'0'); -- force data to zero + imem_we0 := '1'; -- enable writes + imem_we1 := '1'; + end if; + + if CE_MSEC = '1' then -- advance sector counter every msec + if unsigned(r.sc) = 8#13# then -- sector counter (count to 8#13#) + n.sc := (others=>'0'); + else + n.sc := unsigned(r.sc) + 1; + end if; + end if; + + N_REGS <= n; + + MEM_0_WE <= imem_we0; + MEM_1_WE <= imem_we1; + MEM_ADDR <= imem_addr; + MEM_DIN <= imem_din; + + IB_SRES.dout <= idout; + IB_SRES.ack <= ibsel; + IB_SRES.busy <= ibbusy; + + RRI_LAM <= ilam; + EI_REQ <= iei_req; + + end process proc_next; + + +end syn; diff --git a/rtl/ibus/ibdr_sdreg.vbom b/rtl/ibus/ibdr_sdreg.vbom new file mode 100644 index 00000000..a7fe1ce3 --- /dev/null +++ b/rtl/ibus/ibdr_sdreg.vbom @@ -0,0 +1,5 @@ +# libs +../vlib/slvtypes.vhd +iblib.vhd +# design +ibdr_sdreg.vhd diff --git a/rtl/ibus/ibdr_sdreg.vhd b/rtl/ibus/ibdr_sdreg.vhd new file mode 100644 index 00000000..90a7156f --- /dev/null +++ b/rtl/ibus/ibdr_sdreg.vhd @@ -0,0 +1,140 @@ +-- $Id: ibdr_sdreg.vhd 314 2010-07-09 17:38:41Z mueller $ +-- +-- Copyright 2007-2010 by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, 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 complete details. +-- +------------------------------------------------------------------------------ +-- Module Name: ibdr_sdreg - syn +-- Description: ibus dev(rem): Switch/Display register +-- +-- Dependencies: - +-- Test bench: - +-- Target Devices: generic +-- Tool versions: xst 8.1, 8.2, 9.1, 9.2, 10.1; ghdl 0.18-0.25 +-- +-- Synthesized (xst): +-- Date Rev ise Target flop lutl lutm slic t peri +-- 2009-07-11 232 10.1.03 K39 xc3s1000-4 32 39 0 29 s 2.5 +-- +-- Revision History: +-- Date Rev Version Comment +-- 2010-06-11 303 1.1 use IB_MREQ.racc instead of RRI_REQ +-- 2008-08-22 161 1.0.4 use iblib +-- 2008-04-18 136 1.0.3 use RESET. Switch/Display not cleared by console +-- reset or reset instruction, only by cpu_reset +-- 2008-01-20 112 1.0.2 use BRESET +-- 2008-01-05 110 1.0.1 rename IB_MREQ(ena->req) SRES(sel->ack, hold->busy) +-- reorganize code, all in state_type/proc_next +-- 2007-12-31 108 1.0 Initial version +------------------------------------------------------------------------------ + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; + +use work.slvtypes.all; +use work.iblib.all; + +-- ---------------------------------------------------------------------------- +entity ibdr_sdreg is -- ibus dev(rem): Switch/Display regs + -- fixed address: 177570 + port ( + CLK : in slbit; -- clock + RESET : in slbit; -- reset + IB_MREQ : in ib_mreq_type; -- ibus request + IB_SRES : out ib_sres_type; -- ibus response + DISPREG : out slv16 -- display register + ); +end ibdr_sdreg; + +architecture syn of ibdr_sdreg is + + constant ibaddr_sdreg : slv16 := conv_std_logic_vector(8#177570#,16); + + type regs_type is record -- state registers + sreg : slv16; -- switch register + dreg : slv16; -- display register + end record regs_type; + + constant regs_init : regs_type := ( + (others=>'0'), + (others=>'0') + ); + + signal R_REGS : regs_type := regs_init; + signal N_REGS : regs_type := regs_init; + +begin + + proc_regs: process (CLK) + begin + if CLK'event and CLK='1' then + if RESET = '1' then + R_REGS <= regs_init; + else + R_REGS <= N_REGS; + end if; + end if; + end process proc_regs; + + proc_next : process (R_REGS, IB_MREQ) + variable r : regs_type := regs_init; + variable n : regs_type := regs_init; + variable ibsel : slbit := '0'; + variable idout : slv16 := (others=>'0'); + begin + + r := R_REGS; + n := R_REGS; + + ibsel := '0'; + idout := (others=>'0'); + + -- ibus address decoder + if IB_MREQ.req='1' and IB_MREQ.addr=ibaddr_sdreg(12 downto 1) then + ibsel := '1'; + end if; + + -- ibus output driver + if ibsel = '1' then + if IB_MREQ.racc = '0' then + idout := r.sreg; -- cpu will read switch register + else + idout := r.dreg; -- rri will read display register + end if; + end if; + + -- ibus write transactions + if ibsel='1' and IB_MREQ.we='1' then + if IB_MREQ.racc = '0' then -- cpu will write display register + if IB_MREQ.be1 = '1' then + n.dreg(ibf_byte1) := IB_MREQ.din(ibf_byte1); + end if; + if IB_MREQ.be0 = '1' then + n.dreg(ibf_byte0) := IB_MREQ.din(ibf_byte0); + end if; + else -- rri will write switch register + n.sreg := IB_MREQ.din; -- byte write not supported + end if; + end if; + + N_REGS <= n; + + IB_SRES.dout <= idout; + IB_SRES.ack <= ibsel; + IB_SRES.busy <= '0'; + + DISPREG <= r.dreg; + + end process proc_next; + + +end syn; diff --git a/rtl/ibus/iblib.vhd b/rtl/ibus/iblib.vhd new file mode 100644 index 00000000..c454f4d7 --- /dev/null +++ b/rtl/ibus/iblib.vhd @@ -0,0 +1,123 @@ +-- $Id: iblib.vhd 314 2010-07-09 17:38:41Z mueller $ +-- +-- Copyright 2008-2010 by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, 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 complete details. +-- +------------------------------------------------------------------------------ +-- Package Name: iblib +-- Description: Definitions for ibus interface and bus entities +-- +-- Dependencies: - +-- Tool versions: xst 8.1, 8.2, 9.1, 9.2; ghdl 0.18-0.25 +-- Revision History: +-- Date Rev Version Comment +-- 2010-06-11 303 1.1 added racc,cacc signals to ib_mreq_type +-- 2009-06-01 221 1.0.1 added dip signal to ib_mreq_type +-- 2008-08-22 161 1.0 Initial version (extracted from pdp11.vhd) +------------------------------------------------------------------------------ + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; + +use work.slvtypes.all; + +package iblib is + +type ib_mreq_type is record -- ibus - master request + req : slbit; -- request + we : slbit; -- write enable + be0 : slbit; -- byte enable low + be1 : slbit; -- byte enable high + dip : slbit; -- data in pause: rmw cycle 1st part + cacc : slbit; -- console access + racc : slbit; -- remote access + addr : slv13_1; -- address bit(12:1) + din : slv16; -- data (input to slave) +end record ib_mreq_type; + +constant ib_mreq_init : ib_mreq_type := + ('0','0','0','0', -- req, we, be0, be1, + '0','0','0', -- dip, cacc, racc + (others=>'0'), -- addr + (others=>'0')); -- din + +type ib_sres_type is record -- ibus - slave response + ack : slbit; -- acknowledge + busy : slbit; -- busy + dout : slv16; -- data (output from slave) +end record ib_sres_type; + +constant ib_sres_init : ib_sres_type := + ('0','0', -- ack, busy + (others=>'0')); -- dout + +type ib_sres_vector is array (natural range <>) of ib_sres_type; + +subtype ibf_byte1 is integer range 15 downto 8; +subtype ibf_byte0 is integer range 7 downto 0; + +component ib_sres_or_2 is -- ibus result or, 2 input + port ( + IB_SRES_1 : in ib_sres_type; -- ib_sres input 1 + IB_SRES_2 : in ib_sres_type := ib_sres_init; -- ib_sres input 2 + IB_SRES_OR : out ib_sres_type -- ib_sres or'ed output + ); +end component; +component ib_sres_or_3 is -- ibus result or, 3 input + port ( + IB_SRES_1 : in ib_sres_type; -- ib_sres input 1 + IB_SRES_2 : in ib_sres_type := ib_sres_init; -- ib_sres input 2 + IB_SRES_3 : in ib_sres_type := ib_sres_init; -- ib_sres input 3 + IB_SRES_OR : out ib_sres_type -- ib_sres or'ed output + ); +end component; +component ib_sres_or_4 is -- ibus result or, 4 input + port ( + IB_SRES_1 : in ib_sres_type; -- ib_sres input 1 + IB_SRES_2 : in ib_sres_type := ib_sres_init; -- ib_sres input 2 + IB_SRES_3 : in ib_sres_type := ib_sres_init; -- ib_sres input 3 + IB_SRES_4 : in ib_sres_type := ib_sres_init; -- ib_sres input 4 + IB_SRES_OR : out ib_sres_type -- ib_sres or'ed output + ); +end component; + +component ib_sres_or_gen is -- ibus result or, generic + generic ( + WIDTH : natural := 4); -- number of input ports + port ( + IB_SRES_IN : in ib_sres_vector(1 to WIDTH); -- ib_sres input array + IB_SRES_OR : out ib_sres_type -- ib_sres or'ed output + ); +end component; + +type intmap_type is record -- interrupt map entry type + vec : integer; -- vector address + pri : integer; -- priority +end record intmap_type; +constant intmap_init : intmap_type := (0,0); + +type intmap_array_type is array (15 downto 0) of intmap_type; +constant intmap_array_init : intmap_array_type := (others=>intmap_init); + +component ib_intmap is -- external interrupt mapper + generic ( + INTMAP : intmap_array_type := intmap_array_init); + port ( + EI_REQ : in slv16_1; -- interrupt request lines + EI_ACKM : in slbit; -- interrupt acknowledge (from master) + EI_ACK : out slv16_1; -- interrupt acknowledge (to requestor) + EI_PRI : out slv3; -- interrupt priority + EI_VECT : out slv9_2 -- interrupt vector + ); +end component; + +end package iblib; diff --git a/rtl/sys_gen/w11a/nexys2/.cvsignore b/rtl/sys_gen/w11a/nexys2/.cvsignore new file mode 100644 index 00000000..33feb0d1 --- /dev/null +++ b/rtl/sys_gen/w11a/nexys2/.cvsignore @@ -0,0 +1,4 @@ +sys_w11a_n2.ucf +*.dep_ucf_cpp +log_* +_impact* diff --git a/rtl/sys_gen/w11a/nexys2/Makefile b/rtl/sys_gen/w11a/nexys2/Makefile new file mode 100644 index 00000000..77fa74d3 --- /dev/null +++ b/rtl/sys_gen/w11a/nexys2/Makefile @@ -0,0 +1,32 @@ +# $Id: Makefile 311 2010-06-30 17:52:37Z mueller $ +# +# Revision History: +# Date Rev Version Comment +# 2010-05-28 295 1.0 Initial version (derived from _s3 version) +# +VBOM_all = $(wildcard *.vbom) +BIT_all = $(VBOM_all:.vbom=.bit) +# +ISE_BOARD = nexys2 +ISE_PATH = xc3s1200e-fg320-4 +# +.phony : all clean +# +all : $(BIT_all) +# +clean : ise_clean + rm -f sys_w11a_n2.ucf +# +sys_w11a_n2.mcs : sys_w11a_n2.bit + promgen -w -x xcf04s -p mcs -u 0 sys_w11a_n2 + mv sys_w11a_n2.prm sys_w11a_n2_prm.log + mv sys_w11a_n2.cfi sys_w11a_n2_cfi.log +# +#---- +# +include $(RETROBASE)/rtl/vlib/Makefile.xflow +include $(RETROBASE)/rtl/vlib/Makefile.ghdl +# +include $(VBOM_all:.vbom=.dep_xst) +include $(VBOM_all:.vbom=.dep_ghdl) +# diff --git a/rtl/sys_gen/w11a/nexys2/sys_conf.vhd b/rtl/sys_gen/w11a/nexys2/sys_conf.vhd new file mode 100644 index 00000000..876f12fe --- /dev/null +++ b/rtl/sys_gen/w11a/nexys2/sys_conf.vhd @@ -0,0 +1,58 @@ +-- $Id: sys_conf.vhd 314 2010-07-09 17:38:41Z mueller $ +-- +-- Copyright 2010- by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, 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 complete details. +-- +------------------------------------------------------------------------------ +-- Package Name: sys_conf +-- Description: Definitions for sys_w11a_n2 (for synthesis) +-- +-- Dependencies: - +-- Tool versions: xst 11.4; ghdl 0.26 +-- Revision History: +-- Date Rev Version Comment +-- 2010-05-05 295 1.0 Initial version (derived from _s3 version) +------------------------------------------------------------------------------ + +library ieee; +use ieee.std_logic_1164.all; + +use work.slvtypes.all; + +package sys_conf is + + constant sys_conf_hio_debounce : boolean := true; -- instantiate debouncers + constant sys_conf_ser2rri_cdinit : integer := 434-1; -- 50000000/115200 + + constant sys_conf_bram : integer := 0; -- no bram, use cache + constant sys_conf_bram_awidth : integer := 14; -- bram size (16 kB) + constant sys_conf_mem_losize : integer := 8#167777#; -- 4 MByte +--constant sys_conf_mem_losize : integer := 8#003777#; -- 128 kByte (debug) + +-- constant sys_conf_bram : integer := 1; -- bram only +-- constant sys_conf_bram_awidth : integer := 15; -- bram size (32 kB) +-- constant sys_conf_mem_losize : integer := 8#000777#; -- 32 kByte + + constant sys_conf_cache_fmiss : slbit := '0'; -- cache enabled + +end package sys_conf; + +-- Note: mem_losize holds 16 MSB of the PA of the addressable memory +-- 2 211 111 111 110 000 000 000 +-- 1 098 765 432 109 876 543 210 +-- +-- 0 000 000 011 111 111 000 000 -> 00037777 --> 14bit --> 16 kByte +-- 0 000 000 111 111 111 000 000 -> 00077777 --> 15bit --> 32 kByte +-- 0 000 001 111 111 111 000 000 -> 00177777 --> 16bit --> 64 kByte +-- 0 000 011 111 111 111 000 000 -> 00377777 --> 17bit --> 128 kByte +-- 0 011 111 111 111 111 000 000 -> 03777777 --> 20bit --> 1 MByte +-- 1 110 111 111 111 111 000 000 -> 16777777 --> 22bit --> 4 MByte +-- upper 256 kB excluded for 11/70 UB diff --git a/rtl/sys_gen/w11a/nexys2/sys_w11a_n2.ucf_cpp b/rtl/sys_gen/w11a/nexys2/sys_w11a_n2.ucf_cpp new file mode 100644 index 00000000..49416082 --- /dev/null +++ b/rtl/sys_gen/w11a/nexys2/sys_w11a_n2.ucf_cpp @@ -0,0 +1,19 @@ +## $Id: sys_w11a_n2.ucf_cpp 311 2010-06-30 17:52:37Z mueller $ +## +## Revision History: +## Date Rev Version Comment +## 2010-05-26 295 1.0 Initial version +## + +NET "CLK" TNM_NET = "CLK"; +TIMESPEC "TS_CLK" = PERIOD "CLK" 20 ns HIGH 50 %; +OFFSET = IN 10 ns BEFORE "CLK"; +OFFSET = OUT 20 ns AFTER "CLK"; + +## std board +## +#include "bplib/nexys2/nexys2_pins.ucf" +## +## Pmod B0 - RS232 +## +#include "bplib/nexys2/nexys2_pins_pmb0_rs232.ucf" diff --git a/rtl/sys_gen/w11a/nexys2/sys_w11a_n2.vbom b/rtl/sys_gen/w11a/nexys2/sys_w11a_n2.vbom new file mode 100644 index 00000000..4538389a --- /dev/null +++ b/rtl/sys_gen/w11a/nexys2/sys_w11a_n2.vbom @@ -0,0 +1,30 @@ +# libs +../../../vlib/slvtypes.vhd +../../../vlib/genlib/genlib.vhd +../../../vlib/rri/rrilib.vhd +../../../bplib/s3board/s3boardlib.vbom +../../../bplib/nexys2/nexys2lib.vhd +../../../ibus/iblib.vhd +../../../ibus/ibdlib.vhd +../../../w11a/pdp11.vhd +sys_conf = sys_conf.vhd +# components +../../../vlib/genlib/clkdivce.vbom +../../../bplib/s3board/s3_rs232_iob_int_ext.vbom +../../../bplib/s3board/s3_humanio_rri.vbom +../../../vlib/rri/rri_core_serport.vbom +../../../vlib/rri/rb_sres_or_3.vbom +../../../w11a/pdp11_core_rri.vbom +../../../w11a/pdp11_core.vbom +../../../w11a/pdp11_bram.vbom +../../../bplib/nexys2/n2_cram_dummy.vbom +../../../w11a/pdp11_cache.vbom +../../../w11a/pdp11_mem70.vbom +../../../bplib/nexys2/n2_cram_memctl_as.vbom +../../../ibus/ib_sres_or_2.vbom +../../../ibus/ibdr_minisys.vbom +../../../ibus/ibdr_maxisys.vbom +[ghdl,isim]../../../w11a/pdp11_tmu_sb.vbom +# design +sys_w11a_n2.vhd +@ucf_cpp: sys_w11a_n2.ucf diff --git a/rtl/sys_gen/w11a/nexys2/sys_w11a_n2.vhd b/rtl/sys_gen/w11a/nexys2/sys_w11a_n2.vhd new file mode 100644 index 00000000..57cbbe95 --- /dev/null +++ b/rtl/sys_gen/w11a/nexys2/sys_w11a_n2.vhd @@ -0,0 +1,553 @@ +-- $Id: sys_w11a_n2.vhd 314 2010-07-09 17:38:41Z mueller $ +-- +-- Copyright 2010- by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, 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 complete details. +-- +------------------------------------------------------------------------------ +-- Module Name: sys_w11a_n2 - syn +-- Description: w11a test design for nexys2 +-- +-- Dependencies: vlib/genlib/clkdivce +-- bplib/s3board/s3_rs232_iob_int_ext +-- bplib/s3board/s3_humanio_rri +-- vlib/rri/rri_core_serport +-- vlib/rri/rb_sres_or_3 +-- w11a/pdp11_core_rri +-- w11a/pdp11_core +-- w11a/pdp11_bram +-- vlib/nexys2/n2_cram_dummy +-- w11a/pdp11_cache +-- w11a/pdp11_mem70 +-- bplib/nexys2/n2_cram_memctl +-- ibus/ib_sres_or_2 +-- ibus/ibdr_minisys +-- ibus/ibdr_maxisys +-- w11a/pdp11_tmu_sb [sim only] +-- +-- Test bench: tb/tb_s3board_w11a_n2 +-- +-- Target Devices: generic +-- Tool versions: xst 8.2, 9.1, 9.2, 10.1, 11.4, 12.1; ghdl 0.26 - 0.29 +-- +-- Synthesized (xst): +-- Date Rev ise Target flop lutl lutm slic t peri +-- 2010-06-27 310 12.1 M53d xc3s1200e-4 1337 4307 242 2630 ok: LP+PC+DL+I +-- 2010-06-26 309 11.4 L68 xc3s1200e-4 1318 4293 242 2612 ok: LP+PC+DL+II +-- 2010-06-18 306 12.1 M53d xc3s1200e-4 1319 4300 242 2624 ok: LP+PC+DL+II +-- " 306 11.4 L68 xc3s1200e-4 1319 4286 242 2618 ok: LP+PC+DL+II +-- " 306 10.1.02 K39 xc3s1200e-4 1309 4311 242 2665 ok: LP+PC+DL+II +-- " 306 9.2.02 J40 xc3s1200e-4 1316 4259 242 2656 ok: LP+PC+DL+II +-- " 306 9.1 J30 xc3s1200e-4 1311 4260 242 2643 ok: LP+PC+DL+II +-- " 306 8.2.03 I34 xc3s1200e-4 1371 4394 242 2765 ok: LP+PC+DL+II +-- 2010-06-13 305 11.4 L68 xc3s1200e-4 1318 4360 242 2629 ok: LP+PC+DL+II +-- 2010-06-12 304 11.4 L68 xc3s1200e-4 1323 4201 242 2574 ok: LP+PC+DL+II +-- 2010-06-03 300 11.4 L68 xc3s1200e-4 1318 4181 242 2572 ok: LP+PC+DL+II +-- 2010-06-03 299 11.4 L68 xc3s1200e-4 1250 4071 224 2489 ok: LP+PC+DL+II +-- 2010-05-26 296 11.4 L68 xc3s1200e-4 1284 4079 224 2492 ok: LP+PC+DL+II +-- +-- Revision History: +-- Date Rev Version Comment +-- 2010-06-26 309 1.1.4 use constants for rbus addresses (rbaddr_...) +-- BUGFIX: resolve rbus address clash hio<->ibr +-- 2010-06-18 306 1.1.3 change proc_led sensitivity list to avoid xst warn; +-- rename RB_ADDR->RB_ADDR_CORE, add RB_ADDR_IBUS; +-- remove pdp11_ibdr_rri +-- 2010-06-13 305 1.1.2 add CP_ADDR, wire up pdp11_core_rri->pdp11_core +-- 2010-06-12 304 1.1.1 re-do LED driver logic (show cpu modes or cpurust) +-- 2010-06-11 303 1.1 use IB_MREQ.racc instead of RRI_REQ +-- 2010-06-03 300 1.0.2 use default FAWIDTH for rri_core_serport +-- use s3_humanio_rri +-- 2010-05-30 297 1.0.1 put MEM_ACT_(R|W) on LED 6,7 +-- 2010-05-28 295 1.0 Initial version (derived from sys_w11a_s3) +------------------------------------------------------------------------------ +-- +-- w11a test design for nexys2 +-- w11a + rri + serport +-- +-- Usage of Nexys 2 Switches, Buttons, LEDs: +-- +-- SWI(0): 0 -> main board RS232 port +-- 1 -> Pmod B/top RS232 port +-- +-- LED(0:4): if cpugo=1 show cpu mode activity +-- (0) user mode +-- (1) supervisor mode +-- (2) kernel mode, wait +-- (3) kernel mode, pri=0 +-- (4) kernel mode, pri>0 +-- if cpugo=0 shows cpurust +-- (3:0) cpurust code +-- (4) '1' +-- (5) cmdbusy (all rri access, mostly rdma) +-- (6) MEM_ACT_R +-- (7) MEM_ACT_W +-- +-- DP(0): RXSD (inverted to signal activity) +-- DP(1): RTS_N (shows rx back preasure) +-- DP(2): TXSD (inverted to signal activity) +-- DP(3): CTS_N (shows tx back preasure) + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; + +use work.slvtypes.all; +use work.genlib.all; +use work.rrilib.all; +use work.s3boardlib.all; +use work.nexys2lib.all; +use work.iblib.all; +use work.ibdlib.all; +use work.pdp11.all; +use work.sys_conf.all; + +-- ---------------------------------------------------------------------------- + +entity sys_w11a_n2 is -- top level + -- implements nexys2_fusp_aif + port ( + CLK : in slbit; -- clock + I_RXD : in slbit; -- receive data (board view) + O_TXD : out slbit; -- transmit data (board view) + I_SWI : in slv8; -- s3 switches + I_BTN : in slv4; -- s3 buttons + O_LED : out slv8; -- s3 leds + O_ANO_N : out slv4; -- 7 segment disp: anodes (act.low) + O_SEG_N : out slv8; -- 7 segment disp: segments (act.low) + O_MEM_CE_N : out slbit; -- cram: chip enable (act.low) + O_MEM_BE_N : out slv2; -- cram: byte enables (act.low) + O_MEM_WE_N : out slbit; -- cram: write enable (act.low) + O_MEM_OE_N : out slbit; -- cram: output enable (act.low) + O_MEM_ADV_N : out slbit; -- cram: address valid (act.low) + O_MEM_CLK : out slbit; -- cram: clock + O_MEM_CRE : out slbit; -- cram: command register enable + I_MEM_WAIT : in slbit; -- cram: mem wait + O_FLA_CE_N : out slbit; -- flash ce.. (act.low) + O_MEM_ADDR : out slv23; -- cram: address lines + IO_MEM_DATA : inout slv16; -- cram: data lines + O_FUSP_RTS_N : out slbit; -- fusp: rs232 rts_n + I_FUSP_CTS_N : in slbit; -- fusp: rs232 cts_n + I_FUSP_RXD : in slbit; -- fusp: rs232 rx + O_FUSP_TXD : out slbit -- fusp: rs232 tx + ); +end sys_w11a_n2; + +architecture syn of sys_w11a_n2 is + + signal RXD : slbit := '1'; + signal TXD : slbit := '0'; + signal RTS_N : slbit := '0'; + signal CTS_N : slbit := '0'; + + signal SWI : slv8 := (others=>'0'); + signal BTN : slv4 := (others=>'0'); + signal LED : slv8 := (others=>'0'); + signal DSP_DAT : slv16 := (others=>'0'); + signal DSP_DP : slv4 := (others=>'0'); + + signal RB_LAM : slv16 := (others=>'0'); + signal RB_STAT : slv3 := (others=>'0'); + + signal RB_MREQ : rb_mreq_type := rb_mreq_init; + signal RB_SRES : rb_sres_type := rb_sres_init; + signal RB_SRES_CPU : rb_sres_type := rb_sres_init; + signal RB_SRES_IBD : rb_sres_type := rb_sres_init; + signal RB_SRES_HIO : rb_sres_type := rb_sres_init; + + signal RESET : slbit := '0'; + signal CE_USEC : slbit := '0'; + signal CE_MSEC : slbit := '0'; + + signal CPU_RESET : slbit := '0'; + signal CP_CNTL : cp_cntl_type := cp_cntl_init; + signal CP_ADDR : cp_addr_type := cp_addr_init; + signal CP_DIN : slv16 := (others=>'0'); + signal CP_STAT : cp_stat_type := cp_stat_init; + signal CP_DOUT : slv16 := (others=>'0'); + + signal EI_PRI : slv3 := (others=>'0'); + signal EI_VECT : slv9_2 := (others=>'0'); + signal EI_ACKM : slbit := '0'; + + signal EM_MREQ : em_mreq_type := em_mreq_init; + signal EM_SRES : em_sres_type := em_sres_init; + + signal HM_ENA : slbit := '0'; + signal MEM70_FMISS : slbit := '0'; + signal CACHE_FMISS : slbit := '0'; + signal CACHE_CHIT : slbit := '0'; + + signal MEM_REQ : slbit := '0'; + signal MEM_WE : slbit := '0'; + signal MEM_BUSY : slbit := '0'; + signal MEM_ACK_R : slbit := '0'; + signal MEM_ACT_R : slbit := '0'; + signal MEM_ACT_W : slbit := '0'; + signal MEM_ADDR : slv20 := (others=>'0'); + signal MEM_BE : slv4 := (others=>'0'); + signal MEM_DI : slv32 := (others=>'0'); + signal MEM_DO : slv32 := (others=>'0'); + + signal MEM_ADDR_EXT : slv22 := (others=>'0'); + + signal BRESET : slbit := '0'; + signal IB_MREQ : ib_mreq_type := ib_mreq_init; + signal IB_SRES : ib_sres_type := ib_sres_init; + + signal IB_SRES_MEM70 : ib_sres_type := ib_sres_init; + signal IB_SRES_IBDR : ib_sres_type := ib_sres_init; + + signal DM_STAT_DP : dm_stat_dp_type := dm_stat_dp_init; + signal DM_STAT_VM : dm_stat_vm_type := dm_stat_vm_init; + signal DM_STAT_CO : dm_stat_co_type := dm_stat_co_init; + signal DM_STAT_SY : dm_stat_sy_type := dm_stat_sy_init; + + signal DISPREG : slv16 := (others=>'0'); + + constant rbaddr_core0 : slv8 := "00000000"; + constant rbaddr_ibus : slv8 := "10000000"; + constant rbaddr_hio : slv8 := "11000000"; + +begin + + CLKDIV : clkdivce + generic map ( + CDUWIDTH => 6, + USECDIV => 50, + MSECDIV => 1000) + port map ( + CLK => CLK, + CE_USEC => CE_USEC, + CE_MSEC => CE_MSEC + ); + + IOB_RS232 : s3_rs232_iob_int_ext + port map ( + CLK => CLK, + SEL => SWI(0), + RXD => RXD, + TXD => TXD, + CTS_N => CTS_N, + RTS_N => RTS_N, + I_RXD0 => I_RXD, + O_TXD0 => O_TXD, + I_RXD1 => I_FUSP_RXD, + O_TXD1 => O_FUSP_TXD, + I_CTS1_N => I_FUSP_CTS_N, + O_RTS1_N => O_FUSP_RTS_N + ); + + HIO : s3_humanio_rri + generic map ( + DEBOUNCE => sys_conf_hio_debounce, + RB_ADDR => rbaddr_hio) + port map ( + CLK => CLK, + RESET => RESET, + CE_MSEC => CE_MSEC, + RB_MREQ => RB_MREQ, + RB_SRES => RB_SRES_HIO, + SWI => SWI, + BTN => BTN, + LED => LED, + DSP_DAT => DSP_DAT, + DSP_DP => DSP_DP, + I_SWI => I_SWI, + I_BTN => I_BTN, + O_LED => O_LED, + O_ANO_N => O_ANO_N, + O_SEG_N => O_SEG_N + ); + + RRI : rri_core_serport + generic map ( + ATOWIDTH => 6, -- 64 cycles access timeout + ITOWIDTH => 6, -- 64 periods max idle timeout + CDWIDTH => 13, + CDINIT => sys_conf_ser2rri_cdinit) + port map ( + CLK => CLK, + CE_USEC => CE_USEC, + CE_MSEC => CE_MSEC, + CE_INT => CE_MSEC, + RESET => RESET, + RXSD => RXD, + TXSD => TXD, + CTS_N => CTS_N, + RTS_N => RTS_N, + RB_MREQ => RB_MREQ, + RB_SRES => RB_SRES, + RB_LAM => RB_LAM, + RB_STAT => RB_STAT + ); + + RB_SRES_OR : rb_sres_or_3 + port map ( + RB_SRES_1 => RB_SRES_CPU, + RB_SRES_2 => RB_SRES_IBD, + RB_SRES_3 => RB_SRES_HIO, + RB_SRES_OR => RB_SRES + ); + + RB2CP : pdp11_core_rri + generic map ( + RB_ADDR_CORE => rbaddr_core0, + RB_ADDR_IBUS => rbaddr_ibus) + port map ( + CLK => CLK, + RESET => RESET, + RB_MREQ => RB_MREQ, + RB_SRES => RB_SRES_CPU, + RB_STAT => RB_STAT, + RRI_LAM => RB_LAM(0), + CPU_RESET => CPU_RESET, + CP_CNTL => CP_CNTL, + CP_ADDR => CP_ADDR, + CP_DIN => CP_DIN, + CP_STAT => CP_STAT, + CP_DOUT => CP_DOUT + ); + + CORE : pdp11_core + port map ( + CLK => CLK, + RESET => CPU_RESET, + CP_CNTL => CP_CNTL, + CP_ADDR => CP_ADDR, + CP_DIN => CP_DIN, + CP_STAT => CP_STAT, + CP_DOUT => CP_DOUT, + EI_PRI => EI_PRI, + EI_VECT => EI_VECT, + EI_ACKM => EI_ACKM, + EM_MREQ => EM_MREQ, + EM_SRES => EM_SRES, + BRESET => BRESET, + IB_MREQ_M => IB_MREQ, + IB_SRES_M => IB_SRES, + DM_STAT_DP => DM_STAT_DP, + DM_STAT_VM => DM_STAT_VM, + DM_STAT_CO => DM_STAT_CO + ); + + MEM_BRAM: if sys_conf_bram > 0 generate + signal HM_VAL_BRAM : slbit := '0'; + begin + + MEM : pdp11_bram + generic map ( + AWIDTH => sys_conf_bram_awidth) + port map ( + CLK => CLK, + GRESET => CPU_RESET, + EM_MREQ => EM_MREQ, + EM_SRES => EM_SRES + ); + + HM_VAL_BRAM <= not EM_MREQ.we; -- assume hit if read, miss if write + + MEM70: pdp11_mem70 + port map ( + CLK => CLK, + CRESET => BRESET, + HM_ENA => EM_MREQ.req, + HM_VAL => HM_VAL_BRAM, + CACHE_FMISS => MEM70_FMISS, + IB_MREQ => IB_MREQ, + IB_SRES => IB_SRES_MEM70 + ); + + SRAM_PROT : n2_cram_dummy -- connect CRAM to protection dummy + port map ( + O_MEM_CE_N => O_MEM_CE_N, + O_MEM_BE_N => O_MEM_BE_N, + O_MEM_WE_N => O_MEM_WE_N, + O_MEM_OE_N => O_MEM_OE_N, + O_MEM_ADV_N => O_MEM_ADV_N, + O_MEM_CLK => O_MEM_CLK, + O_MEM_CRE => O_MEM_CRE, + I_MEM_WAIT => I_MEM_WAIT, + O_FLA_CE_N => O_FLA_CE_N, + O_MEM_ADDR => O_MEM_ADDR, + IO_MEM_DATA => IO_MEM_DATA + ); + + end generate MEM_BRAM; + + MEM_SRAM: if sys_conf_bram = 0 generate + + CACHE: pdp11_cache + port map ( + CLK => CLK, + GRESET => CPU_RESET, + EM_MREQ => EM_MREQ, + EM_SRES => EM_SRES, + FMISS => CACHE_FMISS, + CHIT => CACHE_CHIT, + MEM_REQ => MEM_REQ, + MEM_WE => MEM_WE, + MEM_BUSY => MEM_BUSY, + MEM_ACK_R => MEM_ACK_R, + MEM_ADDR => MEM_ADDR, + MEM_BE => MEM_BE, + MEM_DI => MEM_DI, + MEM_DO => MEM_DO + ); + + MEM70: pdp11_mem70 + port map ( + CLK => CLK, + CRESET => BRESET, + HM_ENA => HM_ENA, + HM_VAL => CACHE_CHIT, + CACHE_FMISS => MEM70_FMISS, + IB_MREQ => IB_MREQ, + IB_SRES => IB_SRES_MEM70 + ); + + HM_ENA <= EM_SRES.ack_r or EM_SRES.ack_w; + CACHE_FMISS <= MEM70_FMISS or sys_conf_cache_fmiss; + + MEM_ADDR_EXT <= "00" & MEM_ADDR; -- just use lower 4 MB (of 16 MB) + + SRAM_CTL: n2_cram_memctl_as + generic map ( + READ0DELAY => 2, + READ1DELAY => 2, + WRITEDELAY => 3) + port map ( + CLK => CLK, + RESET => CPU_RESET, + REQ => MEM_REQ, + WE => MEM_WE, + BUSY => MEM_BUSY, + ACK_R => MEM_ACK_R, + ACK_W => open, + ACT_R => MEM_ACT_R, + ACT_W => MEM_ACT_W, + ADDR => MEM_ADDR_EXT, + BE => MEM_BE, + DI => MEM_DI, + DO => MEM_DO, + O_MEM_CE_N => O_MEM_CE_N, + O_MEM_BE_N => O_MEM_BE_N, + O_MEM_WE_N => O_MEM_WE_N, + O_MEM_OE_N => O_MEM_OE_N, + O_MEM_ADV_N => O_MEM_ADV_N, + O_MEM_CLK => O_MEM_CLK, + O_MEM_CRE => O_MEM_CRE, + I_MEM_WAIT => I_MEM_WAIT, + O_FLA_CE_N => O_FLA_CE_N, + O_MEM_ADDR => O_MEM_ADDR, + IO_MEM_DATA => IO_MEM_DATA + ); + + end generate MEM_SRAM; + + IB_SRES_OR : ib_sres_or_2 + port map ( + IB_SRES_1 => IB_SRES_MEM70, + IB_SRES_2 => IB_SRES_IBDR, + IB_SRES_OR => IB_SRES + ); + + IBD_MINI : if false generate + begin + IBDR_SYS : ibdr_minisys + port map ( + CLK => CLK, + CE_USEC => CE_USEC, + CE_MSEC => CE_MSEC, + RESET => CPU_RESET, + BRESET => BRESET, + RRI_LAM => RB_LAM(15 downto 1), + IB_MREQ => IB_MREQ, + IB_SRES => IB_SRES_IBDR, + EI_ACKM => EI_ACKM, + EI_PRI => EI_PRI, + EI_VECT => EI_VECT, + DISPREG => DISPREG + ); + end generate IBD_MINI; + + IBD_MAXI : if true generate + begin + IBDR_SYS : ibdr_maxisys + port map ( + CLK => CLK, + CE_USEC => CE_USEC, + CE_MSEC => CE_MSEC, + RESET => CPU_RESET, + BRESET => BRESET, + RRI_LAM => RB_LAM(15 downto 1), + IB_MREQ => IB_MREQ, + IB_SRES => IB_SRES_IBDR, + EI_ACKM => EI_ACKM, + EI_PRI => EI_PRI, + EI_VECT => EI_VECT, + DISPREG => DISPREG + ); + end generate IBD_MAXI; + + DSP_DAT(15 downto 0) <= DISPREG; + DSP_DP(0) <= not RXD; + DSP_DP(1) <= RTS_N; + DSP_DP(2) <= not TXD; + DSP_DP(3) <= CTS_N; + + proc_led: process (MEM_ACT_W, MEM_ACT_R, CP_STAT, DM_STAT_DP.psw) + variable iled : slv8 := (others=>'0'); + begin + iled := (others=>'0'); + iled(7) := MEM_ACT_W; + iled(6) := MEM_ACT_R; + iled(5) := CP_STAT.cmdbusy; + if CP_STAT.cpugo = '1' then + case DM_STAT_DP.psw.cmode is + when c_psw_kmode => + if CP_STAT.cpuwait = '1' then + iled(2) := '1'; + elsif unsigned(DM_STAT_DP.psw.pri) = 0 then + iled(3) := '1'; + else + iled(4) := '1'; + end if; + when c_psw_smode => + iled(1) := '1'; + when c_psw_umode => + iled(0) := '1'; + when others => null; + end case; + else + iled(4) := '1'; + iled(3 downto 0) := CP_STAT.cpurust; + end if; + LED <= iled; + end process; + +-- synthesis translate_off + DM_STAT_SY.emmreq <= EM_MREQ; + DM_STAT_SY.emsres <= EM_SRES; + DM_STAT_SY.chit <= CACHE_CHIT; + + TMU : pdp11_tmu_sb + generic map ( + ENAPIN => 13) + port map ( + CLK => CLK, + DM_STAT_DP => DM_STAT_DP, + DM_STAT_VM => DM_STAT_VM, + DM_STAT_CO => DM_STAT_CO, + DM_STAT_SY => DM_STAT_SY + ); + +-- synthesis translate_on +end syn; diff --git a/rtl/sys_gen/w11a/nexys2/tb/.cvsignore b/rtl/sys_gen/w11a/nexys2/tb/.cvsignore new file mode 100644 index 00000000..508fb898 --- /dev/null +++ b/rtl/sys_gen/w11a/nexys2/tb/.cvsignore @@ -0,0 +1,8 @@ +tb_w11a_n2 +tb_w11a_n2_[sft]sim +tb_rriext_fifo_rx +tb_rriext_fifo_tx +tb_rriext_conf +tmu_ofile +sys_w11a_n2.ucf +*.dep_ucf_cpp diff --git a/rtl/sys_gen/w11a/nexys2/tb/Makefile b/rtl/sys_gen/w11a/nexys2/tb/Makefile new file mode 100644 index 00000000..2655db1e --- /dev/null +++ b/rtl/sys_gen/w11a/nexys2/tb/Makefile @@ -0,0 +1,30 @@ +# $Id: Makefile 311 2010-06-30 17:52:37Z mueller $ +# +# Revision History: +# Date Rev Version Comment +# 2010-05-26 295 1.0 Initial version +# +EXE_all = tb_w11a_n2 +# +ISE_PATH = xc3s1200e-fg320-4 +# +# +.phony : all all_ssim all_tsim clean +# +all : $(EXE_all) +all_ssim : $(EXE_all:=_ssim) +all_tsim : $(EXE_all:=_tsim) +# +clean : ise_clean ghdl_clean +# +#----- +# +include $(RETROBASE)/rtl/vlib/Makefile.ghdl +include $(RETROBASE)/rtl/vlib/Makefile.xflow +# +VBOM_all = $(wildcard *.vbom) +# +include $(VBOM_all:.vbom=.dep_xst) +include $(VBOM_all:.vbom=.dep_ghdl) +include $(wildcard *.o.dep_ghdl) +# diff --git a/rtl/sys_gen/w11a/nexys2/tb/sys_conf_sim.vhd b/rtl/sys_gen/w11a/nexys2/tb/sys_conf_sim.vhd new file mode 100644 index 00000000..47708aa7 --- /dev/null +++ b/rtl/sys_gen/w11a/nexys2/tb/sys_conf_sim.vhd @@ -0,0 +1,58 @@ +-- $Id: sys_conf_sim.vhd 314 2010-07-09 17:38:41Z mueller $ +-- +-- Copyright 2010- by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, 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 complete details. +-- +------------------------------------------------------------------------------ +-- Package Name: sys_conf +-- Description: Definitions for sys_w11a_n2 (for simulation) +-- +-- Dependencies: - +-- Tool versions: xst 11.4; ghdl 0.26 +-- Revision History: +-- Date Rev Version Comment +-- 2010-05-28 295 1.0 Initial version (cloned from _s3) +------------------------------------------------------------------------------ + +library ieee; +use ieee.std_logic_1164.all; + +use work.slvtypes.all; + +package sys_conf is + + constant sys_conf_hio_debounce : boolean := false; -- no debouncers + constant sys_conf_ser2rri_cdinit : integer := 1-1; -- 1 cycle/bit in sim + + constant sys_conf_bram : integer := 0; -- no bram, use cache + constant sys_conf_bram_awidth : integer := 14; -- bram size (16 kB) + constant sys_conf_mem_losize : integer := 8#167777#; -- 4 MByte +--constant sys_conf_mem_losize : integer := 8#003777#; -- 128 kByte (debug) + +-- constant sys_conf_bram : integer := 1; -- bram only +-- constant sys_conf_bram_awidth : integer := 16; -- bram size (64 kB) +-- constant sys_conf_mem_losize : integer := 8#001777#; -- 64 kByte + + constant sys_conf_cache_fmiss : slbit := '0'; -- cache enabled + +end package sys_conf; + +-- Note: mem_losize holds 16 MSB of the PA of the addressable memory +-- 2 211 111 111 110 000 000 000 +-- 1 098 765 432 109 876 543 210 +-- +-- 0 000 000 011 111 111 000 000 -> 00037777 --> 14bit --> 16 kByte +-- 0 000 000 111 111 111 000 000 -> 00077777 --> 15bit --> 32 kByte +-- 0 000 001 111 111 111 000 000 -> 00177777 --> 16bit --> 64 kByte +-- 0 000 011 111 111 111 000 000 -> 00377777 --> 17bit --> 128 kByte +-- 0 011 111 111 111 111 000 000 -> 03777777 --> 20bit --> 1 MByte +-- 1 110 111 111 111 111 000 000 -> 16777777 --> 22bit --> 4 MByte +-- upper 256 kB excluded for 11/70 UB diff --git a/rtl/sys_gen/w11a/nexys2/tb/sys_w11a_n2.ucf_cpp b/rtl/sys_gen/w11a/nexys2/tb/sys_w11a_n2.ucf_cpp new file mode 120000 index 00000000..822deb46 --- /dev/null +++ b/rtl/sys_gen/w11a/nexys2/tb/sys_w11a_n2.ucf_cpp @@ -0,0 +1 @@ +../sys_w11a_n2.ucf_cpp \ No newline at end of file diff --git a/rtl/sys_gen/w11a/nexys2/tb/tb_w11a_n2.vbom b/rtl/sys_gen/w11a/nexys2/tb/tb_w11a_n2.vbom new file mode 100644 index 00000000..115b9f84 --- /dev/null +++ b/rtl/sys_gen/w11a/nexys2/tb/tb_w11a_n2.vbom @@ -0,0 +1,7 @@ +# configure tb_nexys2_fusp with sys_w11a_n2 target; +# use vhdl configure file (tb_w11a_n2.vhd) to allow +# that all configurations will co-exist in work library +nexys2_fusp_aif = ../sys_w11a_n2.vbom +sys_conf = sys_conf_sim.vhd +../../../../bplib/nexys2/tb/tb_nexys2_fusp.vbom +tb_w11a_n2.vhd diff --git a/rtl/sys_gen/w11a/nexys2/tb/tb_w11a_n2.vhd b/rtl/sys_gen/w11a/nexys2/tb/tb_w11a_n2.vhd new file mode 100644 index 00000000..20e1994f --- /dev/null +++ b/rtl/sys_gen/w11a/nexys2/tb/tb_w11a_n2.vhd @@ -0,0 +1,40 @@ +-- $Id: tb_w11a_n2.vhd 314 2010-07-09 17:38:41Z mueller $ +-- +-- Copyright 2010- by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, 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 complete details. +-- +------------------------------------------------------------------------------ +-- Module Name: tb_w11a_n2 +-- Description: Configuration for tb_w11a_n2 for tb_nexys2_fusp +-- +-- Dependencies: sys_w11a_n2 +-- +-- To test: sys_w11a_n2 +-- +-- Verified (with (#1) ../../tb/tb_rritba_pdp11core_stim.dat +-- (#2) ../../tb/tb_pdp11_core_stim.dat): +-- Date Rev Code ghdl ise Target Comment +-- 2010-05-28 295 - -.-- - - -:-- +-- +-- Revision History: +-- Date Rev Version Comment +-- 2010-05-26 295 1.0 Initial version (cloned from _s3) +------------------------------------------------------------------------------ + +configuration tb_w11a_n2 of tb_nexys2_fusp is + + for sim + for all : nexys2_fusp_aif + use entity work.sys_w11a_n2; + end for; + end for; + +end tb_w11a_n2; diff --git a/rtl/sys_gen/w11a/nexys2/tb/tbw.dat b/rtl/sys_gen/w11a/nexys2/tb/tbw.dat new file mode 100644 index 00000000..7e8386d7 --- /dev/null +++ b/rtl/sys_gen/w11a/nexys2/tb/tbw.dat @@ -0,0 +1,6 @@ +# $Id: tbw.dat 311 2010-06-30 17:52:37Z mueller $ +# +[tb_w11a_n2] +tb_rriext_fifo_rx = +tb_rriext_fifo_tx = +tb_rriext_conf = diff --git a/rtl/sys_gen/w11a/s3board/.cvsignore b/rtl/sys_gen/w11a/s3board/.cvsignore new file mode 100644 index 00000000..efaafedb --- /dev/null +++ b/rtl/sys_gen/w11a/s3board/.cvsignore @@ -0,0 +1,4 @@ +sys_w11a_s3.ucf +*.dep_ucf_cpp +log_* +_impact* diff --git a/rtl/sys_gen/w11a/s3board/Makefile b/rtl/sys_gen/w11a/s3board/Makefile new file mode 100644 index 00000000..60565927 --- /dev/null +++ b/rtl/sys_gen/w11a/s3board/Makefile @@ -0,0 +1,37 @@ +# $Id: Makefile 311 2010-06-30 17:52:37Z mueller $ +# +# Revision History: +# Date Rev Version Comment +# 2010-05-28 295 1.1.4 rename sys_pdp11core -> sys_w11a_s3 +# 2010-04-24 282 1.1.3 use %.impact rule, all=BIT_all now +# 2009-11-20 251 1.1.2 add .mcs rule +# 2009-07-26 236 1.1.1 add program: rule +# 2007-11-26 98 1.1 include $(RETROBASE)/vlib/Makefile.(ghdl|xflow) +# 2007-07-08 65 1.0 Initial version +# +VBOM_all = $(wildcard *.vbom) +BIT_all = $(VBOM_all:.vbom=.bit) +# +ISE_BOARD = s3board +ISE_PATH = xc3s1000-ft256-4 +# +.phony : all clean +# +all : $(BIT_all) +# +clean : ise_clean + rm -f sys_w11a_s3.ucf +# +sys_w11a_s3.mcs : sys_w11a_s3.bit + promgen -w -x xcf04s -p mcs -u 0 sys_w11a_s3 + mv sys_w11a_s3.prm sys_w11a_s3_prm.log + mv sys_w11a_s3.cfi sys_w11a_s3_cfi.log +# +#---- +# +include $(RETROBASE)/rtl/vlib/Makefile.xflow +include $(RETROBASE)/rtl/vlib/Makefile.ghdl +# +include $(VBOM_all:.vbom=.dep_xst) +include $(VBOM_all:.vbom=.dep_ghdl) +# diff --git a/rtl/sys_gen/w11a/s3board/sys_conf.vhd b/rtl/sys_gen/w11a/s3board/sys_conf.vhd new file mode 100644 index 00000000..fa96e16f --- /dev/null +++ b/rtl/sys_gen/w11a/s3board/sys_conf.vhd @@ -0,0 +1,60 @@ +-- $Id: sys_conf.vhd 314 2010-07-09 17:38:41Z mueller $ +-- +-- Copyright 2007-2008 by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, 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 complete details. +-- +------------------------------------------------------------------------------ +-- Package Name: sys_conf +-- Description: Definitions for sys_w11a_s3 (for synthesis) +-- +-- Dependencies: - +-- Tool versions: xst 8.1, 8.2, 9.1, 9.2; ghdl 0.18-0.25 +-- Revision History: +-- Date Rev Version Comment +-- 2010-05-05 288 1.1.1 add sys_conf_hio_debounce +-- 2008-02-23 118 1.1 add memory config +-- 2007-09-23 84 1.0 Initial version +------------------------------------------------------------------------------ + +library ieee; +use ieee.std_logic_1164.all; + +use work.slvtypes.all; + +package sys_conf is + + constant sys_conf_hio_debounce : boolean := true; -- instantiate debouncers + constant sys_conf_ser2rri_cdinit : integer := 434-1; -- 50000000/115200 + + constant sys_conf_bram : integer := 0; -- no bram, use cache + constant sys_conf_bram_awidth : integer := 14; -- bram size (16 kB) + constant sys_conf_mem_losize : integer := 8#037777#; -- 1 MByte +--constant sys_conf_mem_losize : integer := 8#003777#; -- 128 kByte (debug) + +-- constant sys_conf_bram : integer := 1; -- bram only +-- constant sys_conf_bram_awidth : integer := 15; -- bram size (32 kB) +-- constant sys_conf_mem_losize : integer := 8#000777#; -- 32 kByte + + constant sys_conf_cache_fmiss : slbit := '0'; -- cache enabled + +end package sys_conf; + +-- Note: mem_losize holds 16 MSB of the PA of the addressable memory +-- 2 211 111 111 110 000 000 000 +-- 1 098 765 432 109 876 543 210 +-- +-- 0 000 000 011 111 111 000 000 -> 00037777 --> 14bit --> 16 kByte +-- 0 000 000 111 111 111 000 000 -> 00077777 --> 15bit --> 32 kByte +-- 0 000 001 111 111 111 000 000 -> 00177777 --> 16bit --> 64 kByte +-- 0 000 011 111 111 111 000 000 -> 00377777 --> 17bit --> 128 kByte +-- 0 011 111 111 111 111 000 000 -> 03777777 --> 20bit --> 1 MByte +-- 1 110 111 111 111 111 000 000 -> 16777777 --> 22bit --> 4 MByte +-- upper 256 kB excluded for 11/70 UB diff --git a/rtl/sys_gen/w11a/s3board/sys_w11a_s3.ucf_cpp b/rtl/sys_gen/w11a/s3board/sys_w11a_s3.ucf_cpp new file mode 100644 index 00000000..e1b634a4 --- /dev/null +++ b/rtl/sys_gen/w11a/s3board/sys_w11a_s3.ucf_cpp @@ -0,0 +1,21 @@ +## $Id: sys_w11a_s3.ucf_cpp 311 2010-06-30 17:52:37Z mueller $ +## +## Revision History: +## Date Rev Version Comment +## 2010-05-02 287 2.0 added defs for pm1 rs232 +## 2007-12-16 101 1.1 converted to ucf_cpp, factor out std pins +## 2007-12-09 100 1.0 Initial version +## + +NET "CLK" TNM_NET = "CLK"; +TIMESPEC "TS_CLK" = PERIOD "CLK" 20 ns HIGH 50 %; +OFFSET = IN 10 ns BEFORE "CLK"; +OFFSET = OUT 20 ns AFTER "CLK"; + +## std board +## +#include "bplib/s3board/s3board_pins.ucf" +## +## Pmod1-RS232 on A2 connector +## +#include "bplib/s3board/s3board_a2_pm1_rs232.ucf" diff --git a/rtl/sys_gen/w11a/s3board/sys_w11a_s3.vbom b/rtl/sys_gen/w11a/s3board/sys_w11a_s3.vbom new file mode 100644 index 00000000..dac05208 --- /dev/null +++ b/rtl/sys_gen/w11a/s3board/sys_w11a_s3.vbom @@ -0,0 +1,29 @@ +# libs +../../../vlib/slvtypes.vhd +../../../vlib/genlib/genlib.vhd +../../../vlib/rri/rrilib.vhd +../../../bplib/s3board/s3boardlib.vbom +../../../ibus/iblib.vhd +../../../ibus/ibdlib.vhd +../../../w11a/pdp11.vhd +sys_conf = sys_conf.vhd +# components +../../../vlib/genlib/clkdivce.vbom +../../../bplib/s3board/s3_rs232_iob_int_ext.vbom +../../../bplib/s3board/s3_humanio.vbom +../../../vlib/rri/rri_core_serport.vbom +../../../vlib/rri/rb_sres_or_2.vbom +../../../w11a/pdp11_core_rri.vbom +../../../w11a/pdp11_core.vbom +../../../w11a/pdp11_bram.vbom +../../../bplib/s3board/s3_sram_dummy.vbom +../../../w11a/pdp11_cache.vbom +../../../w11a/pdp11_mem70.vbom +../../../bplib/s3board/s3_sram_memctl.vbom +../../../ibus/ib_sres_or_2.vbom +../../../ibus/ibdr_minisys.vbom +../../../ibus/ibdr_maxisys.vbom +[ghdl,isim]../../../w11a/pdp11_tmu_sb.vbom +# design +sys_w11a_s3.vhd +@ucf_cpp: sys_w11a_s3.ucf diff --git a/rtl/sys_gen/w11a/s3board/sys_w11a_s3.vhd b/rtl/sys_gen/w11a/s3board/sys_w11a_s3.vhd new file mode 100644 index 00000000..bd52a4d4 --- /dev/null +++ b/rtl/sys_gen/w11a/s3board/sys_w11a_s3.vhd @@ -0,0 +1,519 @@ +-- $Id: sys_w11a_s3.vhd 314 2010-07-09 17:38:41Z mueller $ +-- +-- Copyright 2007-2010 by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, 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 complete details. +-- +------------------------------------------------------------------------------ +-- Module Name: sys_w11a_s3 - syn +-- Description: w11a test design for s3board +-- +-- Dependencies: vlib/genlib/clkdivce +-- bplib/s3board/s3_rs232_iob_int_ext +-- bplib/s3board/s3_humanio +-- vlib/rri/rri_core_serport +-- vlib/rri/rb_sres_or_2 +-- w11a/pdp11_core_rri +-- w11a/pdp11_core +-- w11a/pdp11_bram +-- vlib/s3board/s3_sram_dummy +-- w11a/pdp11_cache +-- w11a/pdp11_mem70 +-- bplib/s3board/s3_sram_memctl +-- ibus/ib_sres_or_2 +-- ibus/ibdr_minisys +-- ibus/ibdr_maxisys +-- w11a/pdp11_tmu_sb [sim only] +-- +-- Test bench: tb/tb_s3board_w11a_s3 +-- +-- Target Devices: generic +-- Tool versions: xst 8.1, 8.2, 9.1, 9.2, 10.1, 11.4; ghdl 0.18-0.26 +-- +-- Synthesized (xst): +-- Date Rev ise Target flop lutl lutm slic t peri +-- 2010-05-01 285 11.4 L68 xc3s1000-4 1239 4086 224 2471 OK: LP+PC+DL+II +-- 2010-04-26 283 11.4 L68 xc3s1000-4 1245 4083 224 2474 OK: LP+PC+DL+II +-- 2009-07-12 233 11.2 L46 xc3s1000-4 1245 4078 224 2472 OK: LP+PC+DL+II +-- 2009-07-12 233 10.1.03 K39 xc3s1000-4 1250 4097 224 2494 OK: LP+PC+DL+II +-- 2009-06-01 221 10.1.03 K39 xc3s1000-4 1209 3986 224 2425 OK: LP+PC+DL+II +-- 2009-05-17 216 10.1.03 K39 xc3s1000-4 1039 3542 224 2116 m+p; TIME OK +-- 2009-05-09 213 10.1.03 K39 xc3s1000-4 1037 3500 224 2100 m+p; TIME OK +-- 2009-04-26 209 8.2.03 I34 xc3s1000-4 1099 3557 224 2264 m+p; TIME OK +-- 2008-12-13 176 8.2.03 I34 xc3s1000-4 1116 3672 224 2280 m+p; TIME OK +-- 2008-12-06 174 10.1.02 K37 xc3s1000-4 1038 3503 224 2100 m+p; TIME OK +-- 2008-12-06 174 8.2.03 I34 xc3s1000-4 1116 3682 224 2281 m+p; TIME OK +-- 2008-08-22 161 8.2.03 I34 xc3s1000-4 1118 3677 224 2288 m+p; TIME OK +-- 2008-08-22 161 10.1.02 K37 xc3s1000-4 1035 3488 224 2086 m+p; TIME OK +-- 2008-05-01 140 8.2.03 I34 xc3s1000-4 1057 3344 224 2119 m+p; 21ns;BR-32 +-- 2008-05-01 140 8.2.03 I34 xc3s1000-4 1057 3357 224 2128 m+p; 21ns;BR-16 +-- 2008-05-01 140 8.2.03 I34 xc3s1000-4 1057 3509 224 2220 m+p; TIME OK +-- 2008-05-01 140 9.2.04 J40 xc3s200-4 1009 3195 224 1918 m+p; T-OK;BR-16 +-- 2008-03-19 127 8.2.03 I34 xc3s1000-4 1077 3471 224 2207 m+p; TIME OK +-- 2008-03-02 122 8.2.03 I34 xc3s1000-4 1068 3448 224 2179 m+p; TIME OK +-- 2008-03-02 121 8.2.03 I34 xc3s1000-4 1064 3418 224 2148 m+p; TIME FAIL +-- 2008-02-24 119 8.2.03 I34 xc3s1000-4 1071 3372 224 2141 m+p; TIME OK +-- 2008-02-23 118 8.2.03 I34 xc3s1000-4 1035 3301 182 1996 m+p; TIME OK +-- 2008-01-06 111 8.2.03 I34 xc3s1000-4 971 2898 182 1831 m+p; TIME OK +-- 2007-12-30 107 8.2.03 I34 xc3s1000-4 891 2719 137 1515 s 18.8 +-- 2007-12-30 107 8.2.03 I34 xc3s1000-4 891 2661 137 1654 m+p; TIME OK +-- +-- Revision History: +-- Date Rev Version Comment +-- 2010-06-26 309 1.3.2 use constants for rbus addresses (rbaddr_...) +-- 2010-06-18 306 1.3.1 rename RB_ADDR->RB_ADDR_CORE, add RB_ADDR_IBUS; +-- remove pdp11_ibdr_rri +-- 2010-06-13 305 1.6.1 add CP_ADDR, wire up pdp11_core_rri->pdp11_core +-- 2010-06-11 303 1.6 use IB_MREQ.racc instead of RRI_REQ +-- 2010-06-03 300 1.5.6 use default FAWIDTH for rri_core_serport +-- 2010-05-28 295 1.5.5 rename sys_pdp11core -> sys_w11a_s3 +-- 2010-05-21 292 1.5.4 rename _PM1_ -> _FUSP_ +-- 2010-05-16 291 1.5.3 rename memctl_s3sram->s3_sram_memctl +-- 2010-05-05 288 1.5.2 add sys_conf_hio_debounce +-- 2010-05-02 287 1.5.1 ren CE_XSEC->CE_INT,RP_STAT->RB_STAT,AP_LAM->RB_LAM +-- drop RP_IINT from interfaces; drop RTSFLUSH generic +-- add pm1 rs232 (usp) support +-- 2010-05-01 285 1.5 port to rri V2 interface, use rri_core_serport +-- 2010-04-17 278 1.4.5 rename sram_dummy -> s3_sram_dummy +-- 2010-04-10 275 1.4.4 use s3_humanio; invert DP(1,3) +-- 2009-07-12 233 1.4.3 adapt to ibdr_(mini|maxi)sys interface changes +-- 2009-06-01 221 1.4.2 support ibdr_maxisys as well as _minisys +-- 2009-05-10 214 1.4.1 use pdp11_tmu_sb instead of pdp11_tmu +-- 2008-08-22 161 1.4.0 use iblib, ibdlib; renames +-- 2008-05-03 143 1.3.6 rename _cpursta->_cpurust +-- 2008-05-01 142 1.3.5 reassign LED(cpugo,halt,rust) and DISP(dispreg) +-- 2008-04-19 137 1.3.4 add DM_STAT_(DP|VM|CO|SY) signals, add pdp11_tmu +-- 2008-04-18 136 1.3.3 add RESET for ibdr_minisys +-- 2008-04-13 135 1.3.2 add _mem70 also for _bram configs +-- 2008-02-23 118 1.3.1 add _mem70 +-- 2008-02-17 117 1.3 use ext. memory interface of _core; +-- use _cache + memctl or _bram (configurable) +-- 2008-01-20 113 1.2.1 finalize AP_LAM handling (0=cpu,1=dl11;4=rk05) +-- 2008-01-20 112 1.2 rename clkgen->clkdivce; use ibdr_minisys, BRESET +-- add _ib_mux2 +-- 2008-01-06 111 1.1 use now iob_reg_*; remove rricp_pdp11core hack +-- instanciate all parts directly +-- 2007-12-23 105 1.0.4 add rritb_cpmon_sb +-- 2007-12-16 101 1.0.3 use _N for active low; set IOB attribute to RI/RO +-- 2007-12-09 100 1.0.2 add sram memory signals, dummy handle them +-- 2007-10-19 90 1.0.1 init RI_RXD,RO_TXD=1 to avoid startup glitch +-- 2007-09-23 84 1.0 Initial version +------------------------------------------------------------------------------ +-- +-- w11a test design for s3board +-- w11a + rri + serport +-- +-- Usage of S3BOARD Switches, Buttons, LEDs: +-- LED(7..0):last RXDATA +-- +-- DP(0): RXSD (inverted to signal activity) +-- DP(1): RTS_N (shows rx back preasure) +-- DP(2): TXSD (inverted to signal activity) +-- DP(3): CTS_N (shows tx back preasure) + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; + +use work.slvtypes.all; +use work.genlib.all; +use work.rrilib.all; +use work.s3boardlib.all; +use work.iblib.all; +use work.ibdlib.all; +use work.pdp11.all; +use work.sys_conf.all; + +-- ---------------------------------------------------------------------------- + +entity sys_w11a_s3 is -- top level + -- implements s3board_fusp_aif + port ( + CLK : in slbit; -- clock + I_RXD : in slbit; -- receive data (board view) + O_TXD : out slbit; -- transmit data (board view) + I_SWI : in slv8; -- s3 switches + I_BTN : in slv4; -- s3 buttons + O_LED : out slv8; -- s3 leds + O_ANO_N : out slv4; -- 7 segment disp: anodes (act.low) + O_SEG_N : out slv8; -- 7 segment disp: segments (act.low) + O_MEM_CE_N : out slv2; -- sram: chip enables (act.low) + O_MEM_BE_N : out slv4; -- sram: byte enables (act.low) + O_MEM_WE_N : out slbit; -- sram: write enable (act.low) + O_MEM_OE_N : out slbit; -- sram: output enable (act.low) + O_MEM_ADDR : out slv18; -- sram: address lines + IO_MEM_DATA : inout slv32; -- sram: data lines + O_FUSP_RTS_N : out slbit; -- fusp: rs232 rts_n + I_FUSP_CTS_N : in slbit; -- fusp: rs232 cts_n + I_FUSP_RXD : in slbit; -- fusp: rs232 rx + O_FUSP_TXD : out slbit -- fusp: rs232 tx + ); +end sys_w11a_s3; + +architecture syn of sys_w11a_s3 is + + signal RXD : slbit := '1'; + signal TXD : slbit := '0'; + signal RTS_N : slbit := '0'; + signal CTS_N : slbit := '0'; + + signal SWI : slv8 := (others=>'0'); + signal BTN : slv4 := (others=>'0'); + signal LED : slv8 := (others=>'0'); + signal DSP_DAT : slv16 := (others=>'0'); + signal DSP_DP : slv4 := (others=>'0'); + + signal RB_LAM : slv16 := (others=>'0'); + signal RB_STAT : slv3 := (others=>'0'); + + signal RB_MREQ : rb_mreq_type := rb_mreq_init; + signal RB_SRES : rb_sres_type := rb_sres_init; + signal RB_SRES_CPU : rb_sres_type := rb_sres_init; + signal RB_SRES_IBD : rb_sres_type := rb_sres_init; + + signal RESET : slbit := '0'; + signal CE_USEC : slbit := '0'; + signal CE_MSEC : slbit := '0'; + + signal CPU_RESET : slbit := '0'; + signal CP_CNTL : cp_cntl_type := cp_cntl_init; + signal CP_ADDR : cp_addr_type := cp_addr_init; + signal CP_DIN : slv16 := (others=>'0'); + signal CP_STAT : cp_stat_type := cp_stat_init; + signal CP_DOUT : slv16 := (others=>'0'); + + signal EI_PRI : slv3 := (others=>'0'); + signal EI_VECT : slv9_2 := (others=>'0'); + signal EI_ACKM : slbit := '0'; + + signal EM_MREQ : em_mreq_type := em_mreq_init; + signal EM_SRES : em_sres_type := em_sres_init; + + signal HM_ENA : slbit := '0'; + signal MEM70_FMISS : slbit := '0'; + signal CACHE_FMISS : slbit := '0'; + signal CACHE_CHIT : slbit := '0'; + + signal MEM_REQ : slbit := '0'; + signal MEM_WE : slbit := '0'; + signal MEM_BUSY : slbit := '0'; + signal MEM_ACK_R : slbit := '0'; + signal MEM_ADDR : slv20 := (others=>'0'); + signal MEM_BE : slv4 := (others=>'0'); + signal MEM_DI : slv32 := (others=>'0'); + signal MEM_DO : slv32 := (others=>'0'); + + signal BRESET : slbit := '0'; + signal IB_MREQ : ib_mreq_type := ib_mreq_init; + signal IB_SRES : ib_sres_type := ib_sres_init; + + signal IB_SRES_MEM70 : ib_sres_type := ib_sres_init; + signal IB_SRES_IBDR : ib_sres_type := ib_sres_init; + + signal DM_STAT_DP : dm_stat_dp_type := dm_stat_dp_init; + signal DM_STAT_VM : dm_stat_vm_type := dm_stat_vm_init; + signal DM_STAT_CO : dm_stat_co_type := dm_stat_co_init; + signal DM_STAT_SY : dm_stat_sy_type := dm_stat_sy_init; + + signal DISPREG : slv16 := (others=>'0'); + + constant rbaddr_core0 : slv8 := "00000000"; + constant rbaddr_ibus : slv8 := "10000000"; + constant rbaddr_hio : slv8 := "11000000"; + +begin + + CLKDIV : clkdivce + generic map ( + CDUWIDTH => 6, + USECDIV => 50, + MSECDIV => 1000) + port map ( + CLK => CLK, + CE_USEC => CE_USEC, + CE_MSEC => CE_MSEC + ); + + IOB_RS232 : s3_rs232_iob_int_ext + port map ( + CLK => CLK, + SEL => SWI(0), + RXD => RXD, + TXD => TXD, + CTS_N => CTS_N, + RTS_N => RTS_N, + I_RXD0 => I_RXD, + O_TXD0 => O_TXD, + I_RXD1 => I_FUSP_RXD, + O_TXD1 => O_FUSP_TXD, + I_CTS1_N => I_FUSP_CTS_N, + O_RTS1_N => O_FUSP_RTS_N + ); + + HIO : s3_humanio + generic map ( + DEBOUNCE => sys_conf_hio_debounce) + port map ( + CLK => CLK, + RESET => RESET, + CE_MSEC => CE_MSEC, + SWI => SWI, + BTN => BTN, + LED => LED, + DSP_DAT => DSP_DAT, + DSP_DP => DSP_DP, + I_SWI => I_SWI, + I_BTN => I_BTN, + O_LED => O_LED, + O_ANO_N => O_ANO_N, + O_SEG_N => O_SEG_N + ); + + RRI : rri_core_serport + generic map ( + ATOWIDTH => 6, -- 64 cycles access timeout + ITOWIDTH => 6, -- 64 periods max idle timeout + CDWIDTH => 13, + CDINIT => sys_conf_ser2rri_cdinit) + port map ( + CLK => CLK, + CE_USEC => CE_USEC, + CE_MSEC => CE_MSEC, + CE_INT => CE_MSEC, + RESET => RESET, + RXSD => RXD, + TXSD => TXD, + CTS_N => CTS_N, + RTS_N => RTS_N, + RB_MREQ => RB_MREQ, + RB_SRES => RB_SRES, + RB_LAM => RB_LAM, + RB_STAT => RB_STAT + ); + + RB_SRES_OR : rb_sres_or_2 + port map ( + RB_SRES_1 => RB_SRES_CPU, + RB_SRES_2 => RB_SRES_IBD, + RB_SRES_OR => RB_SRES + ); + + RP2CP : pdp11_core_rri + generic map ( + RB_ADDR_CORE => rbaddr_core0, + RB_ADDR_IBUS => rbaddr_ibus) + port map ( + CLK => CLK, + RESET => RESET, + RB_MREQ => RB_MREQ, + RB_SRES => RB_SRES_CPU, + RB_STAT => RB_STAT, + RRI_LAM => RB_LAM(0), + CPU_RESET => CPU_RESET, + CP_CNTL => CP_CNTL, + CP_ADDR => CP_ADDR, + CP_DIN => CP_DIN, + CP_STAT => CP_STAT, + CP_DOUT => CP_DOUT + ); + + CORE : pdp11_core + port map ( + CLK => CLK, + RESET => CPU_RESET, + CP_CNTL => CP_CNTL, + CP_ADDR => CP_ADDR, + CP_DIN => CP_DIN, + CP_STAT => CP_STAT, + CP_DOUT => CP_DOUT, + EI_PRI => EI_PRI, + EI_VECT => EI_VECT, + EI_ACKM => EI_ACKM, + EM_MREQ => EM_MREQ, + EM_SRES => EM_SRES, + BRESET => BRESET, + IB_MREQ_M => IB_MREQ, + IB_SRES_M => IB_SRES, + DM_STAT_DP => DM_STAT_DP, + DM_STAT_VM => DM_STAT_VM, + DM_STAT_CO => DM_STAT_CO + ); + + MEM_BRAM: if sys_conf_bram > 0 generate + signal HM_VAL_BRAM : slbit := '0'; + begin + + MEM : pdp11_bram + generic map ( + AWIDTH => sys_conf_bram_awidth) + port map ( + CLK => CLK, + GRESET => CPU_RESET, + EM_MREQ => EM_MREQ, + EM_SRES => EM_SRES + ); + + HM_VAL_BRAM <= not EM_MREQ.we; -- assume hit if read, miss if write + + MEM70: pdp11_mem70 + port map ( + CLK => CLK, + CRESET => BRESET, + HM_ENA => EM_MREQ.req, + HM_VAL => HM_VAL_BRAM, + CACHE_FMISS => MEM70_FMISS, + IB_MREQ => IB_MREQ, + IB_SRES => IB_SRES_MEM70 + ); + + SRAM_PROT : s3_sram_dummy -- connect SRAM to protection dummy + port map ( + O_MEM_CE_N => O_MEM_CE_N, + O_MEM_BE_N => O_MEM_BE_N, + O_MEM_WE_N => O_MEM_WE_N, + O_MEM_OE_N => O_MEM_OE_N, + O_MEM_ADDR => O_MEM_ADDR, + IO_MEM_DATA => IO_MEM_DATA + ); + + end generate MEM_BRAM; + + MEM_SRAM: if sys_conf_bram = 0 generate + + CACHE: pdp11_cache + port map ( + CLK => CLK, + GRESET => CPU_RESET, + EM_MREQ => EM_MREQ, + EM_SRES => EM_SRES, + FMISS => CACHE_FMISS, + CHIT => CACHE_CHIT, + MEM_REQ => MEM_REQ, + MEM_WE => MEM_WE, + MEM_BUSY => MEM_BUSY, + MEM_ACK_R => MEM_ACK_R, + MEM_ADDR => MEM_ADDR, + MEM_BE => MEM_BE, + MEM_DI => MEM_DI, + MEM_DO => MEM_DO + ); + + MEM70: pdp11_mem70 + port map ( + CLK => CLK, + CRESET => BRESET, + HM_ENA => HM_ENA, + HM_VAL => CACHE_CHIT, + CACHE_FMISS => MEM70_FMISS, + IB_MREQ => IB_MREQ, + IB_SRES => IB_SRES_MEM70 + ); + + HM_ENA <= EM_SRES.ack_r or EM_SRES.ack_w; + CACHE_FMISS <= MEM70_FMISS or sys_conf_cache_fmiss; + + SRAM_CTL: s3_sram_memctl + port map ( + CLK => CLK, + RESET => CPU_RESET, + REQ => MEM_REQ, + WE => MEM_WE, + BUSY => MEM_BUSY, + ACK_R => MEM_ACK_R, + ACK_W => open, + ACT_R => open, + ACT_W => open, + ADDR => MEM_ADDR(17 downto 0), + BE => MEM_BE, + DI => MEM_DI, + DO => MEM_DO, + O_MEM_CE_N => O_MEM_CE_N, + O_MEM_BE_N => O_MEM_BE_N, + O_MEM_WE_N => O_MEM_WE_N, + O_MEM_OE_N => O_MEM_OE_N, + O_MEM_ADDR => O_MEM_ADDR, + IO_MEM_DATA => IO_MEM_DATA + ); + + end generate MEM_SRAM; + + IB_SRES_OR : ib_sres_or_2 + port map ( + IB_SRES_1 => IB_SRES_MEM70, + IB_SRES_2 => IB_SRES_IBDR, + IB_SRES_OR => IB_SRES); + + IBD_MINI : if false generate + begin + IBDR_SYS : ibdr_minisys + port map ( + CLK => CLK, + CE_USEC => CE_USEC, + CE_MSEC => CE_MSEC, + RESET => CPU_RESET, + BRESET => BRESET, + RRI_LAM => RB_LAM(15 downto 1), + IB_MREQ => IB_MREQ, + IB_SRES => IB_SRES_IBDR, + EI_ACKM => EI_ACKM, + EI_PRI => EI_PRI, + EI_VECT => EI_VECT, + DISPREG => DISPREG); + end generate IBD_MINI; + + IBD_MAXI : if true generate + begin + IBDR_SYS : ibdr_maxisys + port map ( + CLK => CLK, + CE_USEC => CE_USEC, + CE_MSEC => CE_MSEC, + RESET => CPU_RESET, + BRESET => BRESET, + RRI_LAM => RB_LAM(15 downto 1), + IB_MREQ => IB_MREQ, + IB_SRES => IB_SRES_IBDR, + EI_ACKM => EI_ACKM, + EI_PRI => EI_PRI, + EI_VECT => EI_VECT, + DISPREG => DISPREG); + end generate IBD_MAXI; + + DSP_DAT(15 downto 0) <= DISPREG; + DSP_DP(0) <= not RXD; + DSP_DP(1) <= RTS_N; + DSP_DP(2) <= not TXD; + DSP_DP(3) <= CTS_N; + + LED(0) <= CP_STAT.cpugo; + LED(1) <= CP_STAT.cpuhalt; + LED(5 downto 2) <= CP_STAT.cpurust; + LED(6) <= SWI(0) or SWI(1) or SWI(2) or SWI(3) or + SWI(4) or SWI(5) or SWI(6) or SWI(7); + LED(7) <= BTN(0) or BTN(1) or BTN(2) or BTN(3); + +-- synthesis translate_off + DM_STAT_SY.emmreq <= EM_MREQ; + DM_STAT_SY.emsres <= EM_SRES; + DM_STAT_SY.chit <= CACHE_CHIT; + + TMU : pdp11_tmu_sb + generic map ( + ENAPIN => 13) + port map ( + CLK => CLK, + DM_STAT_DP => DM_STAT_DP, + DM_STAT_VM => DM_STAT_VM, + DM_STAT_CO => DM_STAT_CO, + DM_STAT_SY => DM_STAT_SY + ); + +-- synthesis translate_on +end syn; diff --git a/rtl/sys_gen/w11a/s3board/tb/.cvsignore b/rtl/sys_gen/w11a/s3board/tb/.cvsignore new file mode 100644 index 00000000..bc320f4c --- /dev/null +++ b/rtl/sys_gen/w11a/s3board/tb/.cvsignore @@ -0,0 +1,8 @@ +tb_w11a_s3 +tb_w11a_s3_[sft]sim +tb_rriext_fifo_rx +tb_rriext_fifo_tx +tb_rriext_conf +tmu_ofile +sys_w11a_s3.ucf +*.dep_ucf_cpp diff --git a/rtl/sys_gen/w11a/s3board/tb/Makefile b/rtl/sys_gen/w11a/s3board/tb/Makefile new file mode 100644 index 00000000..5ed30ff2 --- /dev/null +++ b/rtl/sys_gen/w11a/s3board/tb/Makefile @@ -0,0 +1,32 @@ +# $Id: Makefile 311 2010-06-30 17:52:37Z mueller $ +# +# Revision History: +# Date Rev Version Comment +# 2010-05-26 295 1.2 rename tb_s3board_pdp11core -> tb_w11a_s3 +# 2007-11-26 98 1.1 add all_ssim and all_tsim targets +# 2007-09-23 84 1.0 Initial version +# +EXE_all = tb_w11a_s3 +# +ISE_PATH = xc3s1000-ft256-4 +# +# +.phony : all all_ssim all_tsim clean +# +all : $(EXE_all) +all_ssim : $(EXE_all:=_ssim) +all_tsim : $(EXE_all:=_tsim) +# +clean : ise_clean ghdl_clean +# +#----- +# +include $(RETROBASE)/rtl/vlib/Makefile.ghdl +include $(RETROBASE)/rtl/vlib/Makefile.xflow +# +VBOM_all = $(wildcard *.vbom) +# +include $(VBOM_all:.vbom=.dep_xst) +include $(VBOM_all:.vbom=.dep_ghdl) +include $(wildcard *.o.dep_ghdl) +# diff --git a/rtl/sys_gen/w11a/s3board/tb/sys_conf_sim.vhd b/rtl/sys_gen/w11a/s3board/tb/sys_conf_sim.vhd new file mode 100644 index 00000000..612f4c96 --- /dev/null +++ b/rtl/sys_gen/w11a/s3board/tb/sys_conf_sim.vhd @@ -0,0 +1,60 @@ +-- $Id: sys_conf_sim.vhd 314 2010-07-09 17:38:41Z mueller $ +-- +-- Copyright 2007-2008 by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, 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 complete details. +-- +------------------------------------------------------------------------------ +-- Package Name: sys_conf +-- Description: Definitions for sys_w11a_s3 (for simulation) +-- +-- Dependencies: - +-- Tool versions: xst 8.1, 8.2, 9.1, 9.2; ghdl 0.18-0.25 +-- Revision History: +-- Date Rev Version Comment +-- 2010-05-05 288 1.1.1 add sys_conf_hio_debounce +-- 2008-02-23 118 1.1 add memory config +-- 2007-09-23 84 1.0 Initial version +------------------------------------------------------------------------------ + +library ieee; +use ieee.std_logic_1164.all; + +use work.slvtypes.all; + +package sys_conf is + + constant sys_conf_hio_debounce : boolean := false; -- no debouncers + constant sys_conf_ser2rri_cdinit : integer := 1-1; -- 1 cycle/bit in sim + + constant sys_conf_bram : integer := 0; -- no bram, use cache + constant sys_conf_bram_awidth : integer := 14; -- bram size (16 kB) + constant sys_conf_mem_losize : integer := 8#037777#; -- 1 MByte +--constant sys_conf_mem_losize : integer := 8#003777#; -- 128 kByte (debug) + +-- constant sys_conf_bram : integer := 1; -- bram only +-- constant sys_conf_bram_awidth : integer := 16; -- bram size (64 kB) +-- constant sys_conf_mem_losize : integer := 8#001777#; -- 64 kByte + + constant sys_conf_cache_fmiss : slbit := '0'; -- cache enabled + +end package sys_conf; + +-- Note: mem_losize holds 16 MSB of the PA of the addressable memory +-- 2 211 111 111 110 000 000 000 +-- 1 098 765 432 109 876 543 210 +-- +-- 0 000 000 011 111 111 000 000 -> 00037777 --> 14bit --> 16 kByte +-- 0 000 000 111 111 111 000 000 -> 00077777 --> 15bit --> 32 kByte +-- 0 000 001 111 111 111 000 000 -> 00177777 --> 16bit --> 64 kByte +-- 0 000 011 111 111 111 000 000 -> 00377777 --> 17bit --> 128 kByte +-- 0 011 111 111 111 111 000 000 -> 03777777 --> 20bit --> 1 MByte +-- 1 110 111 111 111 111 000 000 -> 16777777 --> 22bit --> 4 MByte +-- upper 256 kB excluded for 11/70 UB diff --git a/rtl/sys_gen/w11a/s3board/tb/sys_w11a_s3.ucf_cpp b/rtl/sys_gen/w11a/s3board/tb/sys_w11a_s3.ucf_cpp new file mode 120000 index 00000000..83d2249f --- /dev/null +++ b/rtl/sys_gen/w11a/s3board/tb/sys_w11a_s3.ucf_cpp @@ -0,0 +1 @@ +../sys_w11a_s3.ucf_cpp \ No newline at end of file diff --git a/rtl/sys_gen/w11a/s3board/tb/tb_w11a_s3.vbom b/rtl/sys_gen/w11a/s3board/tb/tb_w11a_s3.vbom new file mode 100644 index 00000000..d2f42dc7 --- /dev/null +++ b/rtl/sys_gen/w11a/s3board/tb/tb_w11a_s3.vbom @@ -0,0 +1,7 @@ +# configure tb_s3board_fusp with sys_w11a_s3 target; +# use vhdl configure file (tb_w11a_s3.vhd) to allow +# that all configurations will co-exist in work library +s3board_fusp_aif = ../sys_w11a_s3.vbom +sys_conf = sys_conf_sim.vhd +../../../../bplib/s3board/tb/tb_s3board_fusp.vbom +tb_w11a_s3.vhd diff --git a/rtl/sys_gen/w11a/s3board/tb/tb_w11a_s3.vhd b/rtl/sys_gen/w11a/s3board/tb/tb_w11a_s3.vhd new file mode 100644 index 00000000..ba3c097b --- /dev/null +++ b/rtl/sys_gen/w11a/s3board/tb/tb_w11a_s3.vhd @@ -0,0 +1,49 @@ +-- $Id: tb_w11a_s3.vhd 314 2010-07-09 17:38:41Z mueller $ +-- +-- Copyright 2007-2010 by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, 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 complete details. +-- +------------------------------------------------------------------------------ +-- Module Name: tb_w11a_s3 +-- Description: Configuration for tb_w11a_s3 for tb_s3board_fusp +-- +-- Dependencies: sys_w11a_s3 +-- +-- To test: sys_w11a_s3 +-- +-- Verified (with (#1) ../../tb/tb_rritba_pdp11core_stim.dat +-- (#2) ../../tb/tb_pdp11_core_stim.dat): +-- Date Rev Code ghdl ise Target Comment +-- 2007-11-23 97 _tsim 0.26 9.1 J30 xc3s1000 d:ok (#2) 91497s; 632m +-- 2007-11-23 97 _tsim 0.26 9.1 J30 xc3s1000 d:ok (#1) 3356s; 632m +-- 2007-11-23 97 _ssim 0.26 8.1.03 I27 xc3s1000 c:ok (#2) 2227s +-- 2007-11-23 97 _ssim 0.26 8.1.03 I27 xc3s1000 c:ok (#1) 82s +-- 2007-10-21 91 - 0.26 - - d:ok (#2) +-- 2007-10-19 90 - 0.26 - - d:ok (#2) +-- 2007-10-19 90 - 0.26 - - d:ok (#1) +-- +-- Revision History: +-- Date Rev Version Comment +-- 2010-05-26 295 1.1.2 rename tb_s3board_pdp11core -> tb_w11a_s3 +-- 2010-05-16 291 1.1.1 use now tb_s3board_fusp +-- 2010-05-02 287 1.1 use now tb_s3board_usp +-- 2007-09-23 84 1.0 Initial version +------------------------------------------------------------------------------ + +configuration tb_w11a_s3 of tb_s3board_fusp is + + for sim + for all : s3board_fusp_aif + use entity work.sys_w11a_s3; + end for; + end for; + +end tb_w11a_s3; diff --git a/rtl/sys_gen/w11a/s3board/tb/tbw.dat b/rtl/sys_gen/w11a/s3board/tb/tbw.dat new file mode 100644 index 00000000..4bafd16f --- /dev/null +++ b/rtl/sys_gen/w11a/s3board/tb/tbw.dat @@ -0,0 +1,6 @@ +# $Id: tbw.dat 311 2010-06-30 17:52:37Z mueller $ +# +[tb_w11a_s3] +tb_rriext_fifo_rx = +tb_rriext_fifo_tx = +tb_rriext_conf = diff --git a/rtl/sys_gen/w11a/tb/.cvsignore b/rtl/sys_gen/w11a/tb/.cvsignore new file mode 100644 index 00000000..938f5ce8 --- /dev/null +++ b/rtl/sys_gen/w11a/tb/.cvsignore @@ -0,0 +1,14 @@ +tb_rriext_fifo_rx +tb_rriext_fifo_tx +tb_rriext_conf +to_ptp +to_lda +tmu_ofile +*.dsk +*.log +*.log.gz +*.lst +*.lda +lpt.dat +ptp.dat +*.LOG diff --git a/rtl/sys_gen/w11a/tb/211bsd_rk_boot.pcmd b/rtl/sys_gen/w11a/tb/211bsd_rk_boot.pcmd new file mode 100644 index 00000000..d045201c --- /dev/null +++ b/rtl/sys_gen/w11a/tb/211bsd_rk_boot.pcmd @@ -0,0 +1,28 @@ +; $Id: 211bsd_rk_boot.pcmd 312 2010-07-04 18:25:58Z mueller $ +; +; Setup file for 211bsd RK based system (w11a, in sys/tb area...) +; +; Usage: +; +; telnet_starter -d DL0 & +; telnet_starter -d DL1 & +; +; dorri -s3 @211bsd_rk_boot.pcmd (for ghdl sim of tb_w11a_s3) +; dorri -n2 @211bsd_rk_boot.pcmd (for ghdl sim of tb_w11a_n2) +; +; dorri -t @211bsd_rk_boot.pcmd (fpga link via /dev/ttyS0) +; dorri -u0,460 @211bsd_rk_boot.pcmd (fpga link via /dev/ttyUSB0) +; +.mode serv11 +; +att TT0 8000 +att TT1 8001 +; +reset +att rk0 211bsd_rk_root.dsk +att rk1 211bsd_rk_swap.dsk +att rk2 211bsd_rk_tmp.dsk +att rk3 211bsd_rk_bin.dsk +att rk4 211bsd_rk_usr.dsk +boot rk0 +server diff --git a/rtl/sys_gen/w11a/tb/dorri b/rtl/sys_gen/w11a/tb/dorri new file mode 100755 index 00000000..7569f7b9 --- /dev/null +++ b/rtl/sys_gen/w11a/tb/dorri @@ -0,0 +1,200 @@ +#!/usr/bin/perl -w +# $Id: dorri 311 2010-06-30 17:52:37Z mueller $ +# +# Revision History: +# Date Rev Version Comment +# 2010-05-29 296 1.4 allow -ux,baud (usb devnum and baudrate) +# 2010-05-28 295 1.3 w11a_s3/w11a_n2 support: -s3 and -n2 instead of -f +# add -tmu option +# 2010-05-03 287 1.2 add -u[123] options for fast usb serport +# 2009-08-01 237 1.1.1 use 115200 instead of 38400 as default baud rate +# 2009-04-26 209 1.1 add -b (batch) option +# 2009-04-11 206 1.0 Initial version +# + +use 5.005; # require Perl 5.005 or higher +use strict; # require strict checking +use FileHandle; + +sub print_usage; + +autoflush STDOUT 1; # autoflush, so noting lost on exec later + +my $opt_b; +my $opt_io; +my $opt_tmu; +my $pirri; +my $val_cmax="3"; +my $val_time="3."; +my $val_term=",115200,1"; +my $val_log="rri.log"; +my $val_tb_s3="tbw ../s3board/tb/tb_w11a_s3"; +my $val_tb_n2="tbw ../nexys2/tb/tb_w11a_n2"; +my $val_tb; +my $val_e; + +my @arglist; + +my %baudtbl = ( + "57" => 57600, + "115" => 115200, + "230" => 230400, + "460" => 460800, + "500" => 500000, + "1000" => 1000000, + "2000" => 2000000, + "3000" => 2000000 + ); + +# +# process dorri options +# +while (scalar(@ARGV)) { + my $curarg = $ARGV[0]; + if ($curarg =~ m{^-b$} ) { # -b + $opt_b = 1; + shift @ARGV; + } elsif ($curarg =~ m{^-tmu$} ) { # -tmu + $opt_tmu = 1; + shift @ARGV; + } elsif ($curarg =~ m{^-s3$} ) { # -s3 + $opt_io = "f"; + $val_tb = $val_tb_s3; + shift @ARGV; + } elsif ($curarg =~ m{^-n2$} ) { # -n2 + $opt_io = "f"; + $val_tb = $val_tb_n2; + shift @ARGV; + } elsif ($curarg =~ m{^-t$} ) { # -t + $opt_io = "t"; + + } elsif ($curarg =~ m{^-u(\d)} ) { # -ux... + my $devnum = $1; + my $rest = $'; + my $baudspec = "115"; + my $baudrate; + if ($rest ne "") { + if ($rest =~ m{^,(\d*)$}) { + $baudspec = $1; + } else { + print STDERR "dorri-E: invalid format of -u option\n"; + exit 1; + } + } + if (defined $baudtbl{$baudspec}) { + $baudrate = $baudtbl{$baudspec}; + } else { + print STDERR "dorri-E: invalid baudrate specification\n"; + exit 1; + } + $opt_io = "t"; + $val_term = sprintf "/dev/ttyUSB%d,%d,1", $devnum, $baudrate; + shift @ARGV; + + } elsif ($curarg =~ m{^-e$} ) { # -e + print STDERR "dorri-W: multiple -e options, only last taken\n" + if defined $val_e; + shift @ARGV; + if (scalar(@ARGV) == 0 || $ARGV[0] =~ m{^-}) { + print STDERR "dorri-E: no file name after -e option\n"; + exit 1; + } else { + $val_e = shift @ARGV; + if (not -r $val_e) { + print STDERR "dorri-E: file '$val_e' not found\n"; + exit 1; + } + } + } else { + last; + } +} + +# +# rename old log file +# +if (-r $val_log) { + my $old_log = $val_log; + $old_log =~ s{\.log}{\.old\.log}; + rename $val_log, $old_log + or die "failed to rename: $!"; +} + +# +# check that either -s3/n2 or -t given +# setup pi_rri options for either case +# + +if ($opt_io eq "f") { + push @arglist, "--fifo"; + push @arglist, "--run"; + push @arglist, $val_tb; +} elsif ($opt_io eq "t") { + push @arglist, "--term=$val_term"; +} else { + print STDERR "dorri-E: neither -s3/-n2 nor -t specified\n"; + print_usage(); + exit 1; +} + +# +# setup all other options +# + +push @arglist, "--timeout=$val_time"; +push @arglist, "--cmax=$val_cmax"; +push @arglist, "--log=$val_log"; +push @arglist, "--dserv"; +push @arglist, "--tserv"; +push @arglist, "--int" unless $opt_b; + +if (defined $val_e) { + push @arglist, ".mode serv11"; + push @arglist, "ldabs $val_e"; + push @arglist, "set sim tmu 1" if $opt_tmu; + push @arglist, "start 200"; +} + +while (scalar(@ARGV)) { + my $curarg = shift @ARGV; + if ($curarg =~ m{^@(.*)$} && ! -r $1) { + print STDERR "dorri-E: file '$1' not found\n"; + exit 1; + } + push @arglist,$curarg; +} + +if (defined $val_e) { + push @arglist, "server"; +} + +# +# find pi_rri executable +# + +$pirri=`which pi_rri`; +chomp $pirri; +if ($pirri eq "" || ! -e $pirri) { + print STDERR "dorri-E: failed to locate pi_rri\n"; + exit 1; +} + +# +# print command file +# +if (1) { + print "pi_rri ", join (" ", map {(m{\s}) ? "\"$_\"" : $_} @arglist) , "\n"; +} + +# +# and do it +# +exec $pirri, @arglist + or die "failed to exec: $!"; + +exit 1; + +# ---------------------------------------------------------------------------- +sub print_usage { + print "usage: dorri [-f] [-t] [-u(123) [-e file] ...\n"; +} diff --git a/rtl/sys_gen/w11a/tb/uv5_boot.pcmd b/rtl/sys_gen/w11a/tb/uv5_boot.pcmd new file mode 100644 index 00000000..3cd69ea9 --- /dev/null +++ b/rtl/sys_gen/w11a/tb/uv5_boot.pcmd @@ -0,0 +1,22 @@ +; $Id: uv5_boot.pcmd 312 2010-07-04 18:25:58Z mueller $ +; +; Setup file for Unix V5 System +; +; Usage: +; +; telnet_starter -d DL0 & +; +; dorri -s3 @uv5_boot.pcmd (for ghdl sim of tb_w11a_s3) +; dorri -n2 @uv5_boot.pcmd (for ghdl sim of tb_w11a_n2) +; +; dorri -t @uv5_boot.pcmd (fpga link via /dev/ttyS0) +; dorri -u0,460 @uv5_boot.pcmd (fpga link via /dev/ttyUSB0) +; +.mode serv11 +; +att TT0 8000 +; +reset +att rk0 unix_v5_rk.dsk +boot rk0 +server diff --git a/rtl/vlib/Makefile b/rtl/vlib/Makefile new file mode 100644 index 00000000..8b9f22b2 --- /dev/null +++ b/rtl/vlib/Makefile @@ -0,0 +1,5 @@ +# $Id: Makefile 311 2010-06-30 17:52:37Z mueller $ +# +# +include Makefile.xflow +# diff --git a/rtl/vlib/Makefile.ghdl b/rtl/vlib/Makefile.ghdl new file mode 100644 index 00000000..c73e1916 --- /dev/null +++ b/rtl/vlib/Makefile.ghdl @@ -0,0 +1,47 @@ +# $Id: Makefile.ghdl 311 2010-06-30 17:52:37Z mueller $ +# +# Revision History: +# Date Rev Version Comment +# 2007-11-04 95 1.2.2 fix find statement in ghdl_tmp_clean +# 2007-11-02 94 1.2.1 don't delete cext_*.o in ghdl_tmp_clean +# 2007-07-08 65 1.2 support now autobuilding of _fsim and _tsim models +# 2007-06-16 57 1.1 cleanup ghdl_clean handling +# 2007-06-10 52 1.0 Initial version +# +GHDLIEEE = --ieee=synopsys +GHDLUNISIM = -P$(XILINX)/ghdl/unisim +GHDLSIMPRIM = -P$(XILINX)/ghdl/simprim +GHDL = ghdl +COMPILE.vhd = $(GHDL) -a $(GHDLIEEE) +LINK.vhd = $(GHDL) -e $(GHDLIEEE) +# +% : %.vbom + vbomconv --ghdl_i $< + vbomconv --ghdl_m $< +# +# rules for _[ft]sim to use 'virtual' [ft]sim vbom's (derived from _ssim) +# +%_fsim : %_ssim.vbom + vbomconv --ghdl_i $*_fsim.vbom + vbomconv --ghdl_m $*_fsim.vbom +# +%_tsim : %_ssim.vbom + vbomconv --ghdl_i $*_tsim.vbom + vbomconv --ghdl_m $*_tsim.vbom +# +%.dep_ghdl: %.vbom + vbomconv --dep_ghdl $< > $@ +# +.phony: ghdl_clean ghdl_tmp_clean +# +ghdl_clean: ghdl_tmp_clean + rm -f $(EXE_all) + rm -f $(EXE_all:%=%_[sft]sim) + rm -f $(EXE_all:%=%.exe) + rm -f $(EXE_all:%=%_[sft]sim.exe) + rm -f cext_*.o +# +ghdl_tmp_clean: + find -maxdepth 1 -name "*.o" | grep -v "^\./cext_" | xargs rm -f + rm -f work-obj93.cf +# diff --git a/rtl/vlib/Makefile.isim b/rtl/vlib/Makefile.isim new file mode 100644 index 00000000..97583c37 --- /dev/null +++ b/rtl/vlib/Makefile.isim @@ -0,0 +1,49 @@ +# $Id: Makefile.isim 311 2010-06-30 17:52:37Z mueller $ +# +# Revision History: +# Date Rev Version Comment +# 2010-04-26 284 1.1 add _[sft]sim support +# 2009-11-22 252 1.0 Initial version +# +FUSE = fuse +# +%_ISim : %.vbom + vbomconv -isim_prj $< > $*_isim.prj + $(FUSE) $* -prj $*_isim.prj -o $*_ISim + rm -rf $*_isim.prj +# +# rule for _ssim to call FUSE with right top level name +# +%_ISim_ssim : %_ssim.vbom + vbomconv -isim_prj $*_ssim.vbom > $*_isim_ssim.prj + $(FUSE) $* -prj $*_isim_ssim.prj -o $*_ISim_ssim + rm -rf $*_isim_ssim.prj +# +# rule for _[ft]sim to use 'virtual' _[ft]sim vbom's (derived from _ssim) +# +%_ISim_fsim : %_ssim.vbom + vbomconv -isim_prj $*_fsim.vbom > $*_isim_fsim.prj + $(FUSE) $* -prj $*_isim_fsim.prj -o $*_ISim_fsim + rm -rf $*_isim_fsim.prj +# +%_ISim_tsim : %_ssim.vbom + vbomconv -isim_prj $*_tsim.vbom > $*_isim_tsim.prj + $(FUSE) $* -prj $*_isim_tsim.prj -o $*_ISim_tsim + rm -rf $*_isim_tsim.prj +# +%.dep_isim: %.vbom + vbomconv --dep_isim $< > $@ +# +.phony: isim_clean isim_tmp_clean +# +isim_clean: isim_tmp_clean + rm -f $(EXE_all:%=%_ISim) + rm -f $(EXE_all:%=%_ISim_ssim) + rm -f $(EXE_all:%=%_ISim_fsim) + rm -f $(EXE_all:%=%_ISim_tsim) +# +isim_tmp_clean: + rm -f isim.log isim.wdb + rm -f fuse.log + rm -rf isim +# diff --git a/rtl/vlib/Makefile.xflow b/rtl/vlib/Makefile.xflow new file mode 100644 index 00000000..87dea6a7 --- /dev/null +++ b/rtl/vlib/Makefile.xflow @@ -0,0 +1,243 @@ +# $Id: Makefile.xflow 311 2010-06-30 17:52:37Z mueller $ +# +# Revision History: +# Date Rev Version Comment +# 2010-05-06 289 1.5.7 add xilinx_tsim_xon support +# 2010-04-24 282 1.5.6 add %.impact rule to run impact_wrapper +# 2010-04-17 278 1.4.5 add '|| true' after grep in diag summary to prevent +# a make abort in case no diags are seen +# 2010-04-02 273 1.4.4 add -I{RETROBASE} to ucf_cpp processing rules +# 2010-03-14 268 1.4.3 add XFLOWOPT_SYN and XFLOWOPT_IMP +# 2009-11-21 252 1.4.2 use bitgen directly, use ISE_USERID +# 2007-12-17 102 1.4.1 fix %.dep_ucf_cpp : %.ucf_cpp rule +# 2007-12-16 101 1.4 add ucf_cpp rules +# 2007-12-09 100 1.3.7 ifndef define ISE_PATH to xc3s1000-ft256-4 +# 2007-11-02 94 1.3.6 use .SECONDARY to keep intermediate files +# 2007-10-28 93 1.3.5 call xst_count_bels -xsts when _ssim is generated +# 2007-10-12 88 1.3.4 support .xcf files, if provided +# 2007-10-06 87 1.3.3 remove *_twr.log in clean +# 2007-07-20 67 1.3.2 handle local/global xst_vhdl.opt +# 2007-07-15 66 1.3.1 add rule "%.ngc: ../%.vbom" to support _*sim in ./tb +# add XST diagnostics summary at end of listing +# 2007-07-06 64 1.3 all vbom based now +# 2007-06-16 57 1.2.1 cleanup ghdl_clean handling (rm _[sft]sim) +# 2007-06-10 52 1.2 reorganized svn directory structure +# 2007-06-10 51 1.1 consolidate test bench generation +# 2007-06-03 45 1.0 Initial version +#--- +# +# setup default board (for impact), device and userid (for bitgen) +# +ifndef ISE_BOARD +ISE_BOARD = s3board +endif +# +ifndef ISE_PATH +ISE_PATH = xc3s1000-ft256-4 +endif +# +ifndef ISE_USERID +ISE_USERID = 0xffffffff +endif +# +# setup defaults for xflow option files for synthesis and implementation +# +ifndef XFLOWOPT_SYN +XFLOWOPT_SYN = xst_vhdl.opt +endif +# +ifndef XFLOWOPT_IMP +XFLOWOPT_IMP = balanced.opt +endif +# +XFLOW = xflow -p ${ISE_PATH} +# +# $@ first target +# $< first dependency +# $* stem in rule match +# +# when chaining, don't delete 'expensive' intermediate files: +.SECONDARY : +# +# Synthesize (xst) +# input: %.vbom vbom project description +# output: %.ngc +# %_xst.log xst log file +# +%.ngc: %.vbom + if [ ! -d ./ise ]; then mkdir ./ise; fi + (cd ./ise; vbomconv --xst_prj ../$< > $*.prj) + (cd ./ise; touch $*.xcf) + if [ -r $*.xcf ]; then cp $*.xcf ./ise; fi + if [ -r ${RETROBASE}/vlib/${XFLOWOPT_SYN} ]; then \ + cp ${RETROBASE}/vlib/${XFLOWOPT_SYN} ./ise; fi + if [ -r ${XFLOWOPT_SYN} ]; then cp ${XFLOWOPT_SYN} ./ise; fi + ${XFLOW} -wd ise -synth ${XFLOWOPT_SYN} $*.prj + (cd ./ise; chmod -x *.* ) + if [ -r ./ise/$*.ngc ]; then cp -p ./ise/$*.ngc .; fi + if [ -r ./ise/$*_xst.log ]; then cp -p ./ise/$*_xst.log .; fi + @ echo "===============================================================" + @ echo "* Makefile.xflow: XST Diagnostic Summary *" + @ echo "===============================================================" + @ grep -i -A 1 ":.*:" $*_xst.log || true + @ echo "===============================================================" +# +# the following rule needed to generate an %_*sim.vhd in a ./tb sub-directory +# it will look for a matching vbom in the parent directory +%.ngc: ../%.vbom + if [ ! -d ./ise ]; then mkdir ./ise; fi + (cd ./ise; vbomconv --xst_prj ../$< > $*.prj) + (cd ./ise; touch $*.xcf) + if [ -r $*.xcf ]; then cp $*.xcf ./ise; fi + if [ -r ${RETROBASE}/vlib/${XFLOWOPT_SYN} ]; then \ + cp ${RETROBASE}/vlib/${XFLOWOPT_SYN} ./ise; fi + if [ -r ${XFLOWOPT_SYN} ]; then cp ${XFLOWOPT_SYN} ./ise; fi + ${XFLOW} -wd ise -synth ${XFLOWOPT_SYN} $*.prj + (cd ./ise; chmod -x *.* ) + if [ -r ./ise/$*.ngc ]; then cp -p ./ise/$*.ngc .; fi + if [ -r ./ise/$*_xst.log ]; then cp -p ./ise/$*_xst.log .; fi + @ echo "===============================================================" + @ echo "* Makefile.xflow: XST Diagnostic Summary *" + @ echo "===============================================================" + @ grep -i -A 1 ":.*:" $*_xst.log || true + @ echo "===============================================================" +# +# Implement (map+par) +# input: %.ngc +# %.ucf constraint file (if available) +# output: %.ncd +# %.pcf +# %_tra.log translate (ngdbuild) log file (renamed %.bld) +# %_map.log map log file (renamed %_map.mrp) +# %_par.log par log file (renamed %.par) +# %_pad.log pad file (renamed %_pad.txt) +# +%.ncd %.pcf: %.ngc + if [ ! -d ./ise ]; then mkdir ./ise; fi + if [ -r $*.ngc ]; then cp -p $*.ngc ./ise; fi + if [ -r $*.ucf ]; then cp -p $*.ucf ./ise; fi + if [ -r ${RETROBASE}/vlib/${XFLOWOPT_IMP} ]; then \ + cp ${RETROBASE}/vlib/${XFLOWOPT_IMP} ./ise; fi + if [ -r ${XFLOWOPT_IMP} ]; then cp -p ${XFLOWOPT_IMP} ./ise; fi + ${XFLOW} -wd ise -implement ${XFLOWOPT_IMP} $< + (cd ./ise; chmod -x *.* ) + if [ -r ./ise/$*.ncd ]; then cp -p ./ise/$*.ncd .; fi + if [ -r ./ise/$*.pcf ]; then cp -p ./ise/$*.pcf .; fi + if [ -r ./ise/$*.bld ]; then cp -p ./ise/$*.bld ./$*_tra.log; fi + if [ -r ./ise/$*_map.mrp ]; then cp -p ./ise/$*_map.mrp ./$*_map.log; fi + if [ -r ./ise/$*.par ]; then cp -p ./ise/$*.par ./$*_par.log; fi + if [ -r ./ise/$*_pad.txt ]; then cp -p ./ise/$*_pad.txt ./$*_pad.log; fi + if [ -r ./ise/$*.twr ]; then cp -p ./ise/$*.twr ./$*_twr.log; fi +# +# Configure (bitgen) +# input: %.ncd +# output: %.bit +# %.msk +# %_bgn.log bitgen log file (renamed %.bgn) +# +%.bit: %.ncd + if [ ! -d ./ise ]; then mkdir ./ise; fi + if [ -r $*.ncd ]; then cp -p $*.ncd ./ise; fi + (cd ./ise; bitgen -l -w -m -g ReadBack -g UserId:${ISE_USERID} -intstyle xflow $*.ncd) + (cd ./ise; chmod -x *.* ) + if [ -r ./ise/$*.bit ]; then cp -p ./ise/$*.bit .; fi + if [ -r ./ise/$*.msk ]; then cp -p ./ise/$*.msk .; fi + if [ -r ./ise/$*.bgn ]; then cp -p ./ise/$*.bgn ./$*_bgn.log; fi +# +# Program FPGA with impact +# input: %.bit +# output: .phony +# +%.impact: %.bit + impact_wrapper --board=${ISE_BOARD} --path=${ISE_PATH} $*.bit + +# +# Post-XST simulation model (netgen -sim; UNISIM based) +# input: %.ngc +# output: %_ssim.vhd +# %_ngn_ssim.log netgen log file (renamed %.nlf) +# +%_ssim.vhd: %.ngc + if [ ! -d ./ise ]; then mkdir ./ise; fi + if [ -r $*.ngc ]; then cp -p $*.ngc ./ise; fi + (cd ise; netgen -sim -intstyle xflow -ofmt vhdl -w $*.ngc) + (cd ./ise; chmod -x *.* ) + if [ -r ./ise/$*.vhd ]; then cp -p ./ise/$*.vhd ./$*_ssim.vhd; fi + if [ -r ./ise/$*.nlf ]; then cp -p ./ise/$*.nlf ./$*_ngn_ssim.log; fi + if [ -r $*_ssim.vhd ]; then xst_count_bels -xsts $*_ssim.vhd; fi +# +# Post-XST simulation model (netgen -sim; SIMPRIM based) +# input: %.ngc +# output: %_fsim.vhd +# %_ngn_fsim.log netgen log file (renamed %.nlf) +# +%_fsim.vhd: %.ngc + if [ ! -d ./ise ]; then mkdir ./ise; fi + if [ -r $*.ngc ]; then cp -p $*.ngc ./ise; fi + (cd ise; ngdbuild -p ${ISE_PATH} -nt timestamp -intstyle xflow \ + $*.ngc $*.ngd) + (cd ise; netgen -sim -intstyle xflow -ofmt vhdl -w $*.ngd) + (cd ./ise; chmod -x *.* ) + if [ -r ./ise/$*.vhd ]; then cp -p ./ise/$*.vhd ./$*_fsim.vhd; fi + if [ -r ./ise/$*.nlf ]; then cp -p ./ise/$*.nlf ./$*_ngn_fsim.log; fi +# +# Post-par timing simulation model (netgen -sim) +# input: %.ncd +# output: %_tsim.vhd +# %_ngn_tsim.log netgen log file (renamed time_sim.nlf) +# +#!! use netgen directly because xflow 8.1 goes mad when -tsim used a 2nd time +#!! see blog_xilinx_webpack.txt 2007-06-10 +# +%_tsim.vhd %_tsim.sdf: %.ncd + if [ ! -d ./ise ]; then mkdir ./ise; fi + if [ -r $*.ncd ]; then cp -p $*.ncd ./ise; fi + if [ -r $*.pcf ]; then cp -p $*.pcf ./ise; fi + (cd ise; netgen -ofmt vhdl -sim -w -intstyle xflow -pcf \ + $*.pcf $*.ncd $*_tsim.vhd ) + (cd ./ise; chmod -x *.* ) + if [ -r ./ise/$*_tsim.vhd ]; then cp -p ./ise/$*_tsim.vhd .; fi + if [ -r ./ise/$*_tsim.sdf ]; then cp -p ./ise/$*_tsim.sdf .; fi + if [ -r ./ise/$*_tsim.nlf ]; then cp -p ./ise/$*_tsim.nlf ./$*_ngn_tsim.log; fi + if [ -r $*_tsim.vhd -a -r $*.tsim_xon_dat ]; then xilinx_tsim_xon $*; fi +# +# generate dep_xst files from vbom +# +%.dep_xst: %.vbom + vbomconv --dep_xst $< > $@ +# +# generate cpp'ed ucf files from ucf_cpp +# +%.ucf : %.ucf_cpp + cpp -I${RETROBASE}/rtl $*.ucf_cpp $*.ucf +# +# generate nested dependency rules for cpp'ed ucf files from ucf_cpp +# +%.dep_ucf_cpp : %.ucf_cpp + cpp -I${RETROBASE}/rtl -MM $*.ucf_cpp |\ + sed 's/\.o:/\.ucf:/' > $*.dep_ucf_cpp +# +.phony : ise_clean ise_tmp_clean +# +ise_clean: ise_tmp_clean + rm -rf *.ngc + rm -rf *.ncd + rm -rf *.pcf + rm -rf *.bit + rm -rf *.msk + rm -rf *_[sft]sim.vhd + rm -rf *_tsim.sdf + rm -rf *_xst.log + rm -rf *_tra.log + rm -rf *_map.log + rm -rf *_par.log + rm -rf *_pad.log + rm -rf *_twr.log + rm -rf *_bgn.log + rm -rf *_ngn_[sft]sim.log + rm -rf *_svn.log + rm -rf *_sum.log +# +ise_tmp_clean: + rm -rf ./ise +# diff --git a/rtl/vlib/Makefile.xflow_cpld b/rtl/vlib/Makefile.xflow_cpld new file mode 100644 index 00000000..abd5bca9 --- /dev/null +++ b/rtl/vlib/Makefile.xflow_cpld @@ -0,0 +1,129 @@ +# $Id: Makefile.xflow_cpld 311 2010-06-30 17:52:37Z mueller $ +# +# Revision History: +# Date Rev Version Comment +# 2010-03-13 268 1.0 Initial version, cloned from .xflow Rev 252 +#--- +# +# setup default device +# +ifndef ISE_PATH +ISE_PATH = xc2c64a-7-vq44 +endif +# +# setup defaults for xflow option files for synthesis and implementation +# +ifndef XFLOWOPT_SYN +XFLOWOPT_SYN = xst_vhdl.opt +endif +# +ifndef XFLOWOPT_IMP +XFLOWOPT_IMP = balanced.opt +endif +# +XFLOW = xflow -p ${ISE_PATH} +# +# $@ first target +# $< first dependency +# $* stem in rule match +# +# when chaining, don't delete 'expensive' intermediate files: +.SECONDARY : +# +# Synthesize (xst) +# input: %.prj project file +# output: %.ngc +# %_xst.log xst log file +# +# Note: removed "cp ${RETROBASE}/vlib/${XFLOWOPT_SYN} ./ise" option +# +%.ngc: %.vbom + if [ ! -d ./ise ]; then mkdir ./ise; fi + (cd ./ise; vbomconv --xst_prj ../$< > $*.prj) + (cd ./ise; touch $*.xcf) + if [ -r $*.xcf ]; then cp $*.xcf ./ise; fi + if [ -r ${XFLOWOPT_SYN} ]; then cp ${XFLOWOPT_SYN} ./ise; fi + ${XFLOW} -wd ise -synth ${XFLOWOPT_SYN} $*.prj + (cd ./ise; chmod -x *.* ) + if [ -r ./ise/$*.ngc ]; then cp -p ./ise/$*.ngc .; fi + if [ -r ./ise/$*_xst.log ]; then cp -p ./ise/$*_xst.log .; fi + @ echo "===============================================================" + @ echo "* Makefile.xflow: XST Diagnostic Summary *" + @ echo "===============================================================" + @ grep -i -A 1 ":.*:" $*_xst.log + @ echo "===============================================================" +# +# the following rule needed to generate an %_*sim.vhd in a ./tb sub-directory +# it will look for a matching vbom in the parent directory +%.ngc: ../%.vbom + if [ ! -d ./ise ]; then mkdir ./ise; fi + (cd ./ise; vbomconv --xst_prj ../$< > $*.prj) + (cd ./ise; touch $*.xcf) + if [ -r $*.xcf ]; then cp $*.xcf ./ise; fi + if [ -r ${XFLOWOPT_SYN} ]; then cp ${XFLOWOPT_SYN} ./ise; fi + ${XFLOW} -wd ise -synth ${XFLOWOPT_SYN} $*.prj + (cd ./ise; chmod -x *.* ) + if [ -r ./ise/$*.ngc ]; then cp -p ./ise/$*.ngc .; fi + if [ -r ./ise/$*_xst.log ]; then cp -p ./ise/$*_xst.log .; fi + @ echo "===============================================================" + @ echo "* Makefile.xflow: XST Diagnostic Summary *" + @ echo "===============================================================" + @ grep -i -A 1 ":.*:" $*_xst.log + @ echo "===============================================================" +# +# Fit (map + cpldfit + +# input: %.ngc project file +# output: %.ncd +# %.jed +# %_tra.log translate (ngdbuild) log file (renamed %.bld) +# %_fit.log cpldfit log file (renamed %.rpt) +# %_tim.log timing analyser log file (renamed %.tim) +# %_pad.log pad file (renamed %.pad) +# +# Note: removed "cp ${RETROBASE}/vlib/balanced.opt" option +# currently ise 'density.opt' as steering file +# +%.ncd %.jed: %.ngc + if [ ! -d ./ise ]; then mkdir ./ise; fi + if [ -r $*.ngc ]; then cp -p $*.ngc ./ise; fi + if [ -r $*.ucf ]; then cp -p $*.ucf ./ise; fi + if [ -r ${XFLOWOPT_IMP} ]; then cp -p ${XFLOWOPT_IMP} ./ise; fi + ${XFLOW} -wd ise -fit ${XFLOWOPT_IMP} $< + (cd ./ise; chmod -x *.* ) + if [ -r ./ise/$*.ncd ]; then cp -p ./ise/$*.ncd .; fi + if [ -r ./ise/$*.jed ]; then cp -p ./ise/$*.jed .; fi + if [ -r ./ise/$*.bld ]; then cp -p ./ise/$*.bld ./$*_tra.log; fi + if [ -r ./ise/$*.rpt ]; then cp -p ./ise/$*.rpt ./$*_fit.log; fi + if [ -r ./ise/$*.tim ]; then cp -p ./ise/$*.tim ./$*_tim.log; fi + if [ -r ./ise/$*.pad ]; then cp -p ./ise/$*.pad ./$*_pad.log; fi +# +# generate dep_xst files from vbom +# +%.dep_xst: %.vbom + vbomconv --dep_xst $< > $@ +# +# generate cpp'ed ucf files from ucf_cpp +# +%.ucf : %.ucf_cpp + cpp $*.ucf_cpp $*.ucf +# +# generate nested dependency rules for cpp'ed ucf files from ucf_cpp +# +%.dep_ucf_cpp : %.ucf_cpp + cpp -MM $*.ucf_cpp | sed 's/\.o:/\.ucf:/' > $*.dep_ucf_cpp +# +.phony : ise_clean ise_tmp_clean +# +ise_clean: ise_tmp_clean + rm -rf *.ngc + rm -rf *.ncd + rm -rf *.jed + rm -rf *_xst.log + rm -rf *_tra.log + rm -rf *_fit.log + rm -rf *_tim.log + rm -rf *_pad.log +# +ise_tmp_clean: + rm -rf ./ise +# diff --git a/rtl/vlib/balanced.opt b/rtl/vlib/balanced.opt new file mode 100644 index 00000000..171c88dc --- /dev/null +++ b/rtl/vlib/balanced.opt @@ -0,0 +1,95 @@ +FLOWTYPE = FPGA; +############################################################### +## Filename: balanced.opt +## +## Option File For Xilinx FPGA Implementation Flow +## +## Version: 8.1.1 +## $Header: /devl/xcs/repo/env/Jobs/Xflow/data/optionfiles/virtex_fpga_balanced.opt,v 1.14 2004/10/01 22:29:20 rvklair Exp $ +############################################################### +# +# Options for Translator +# +# Type "ngdbuild -h" for a detailed list of ngdbuild command line options +# +Program ngdbuild +-p ; # Partname to use - picked from xflow commandline +-nt timestamp; # NGO File generation. Regenerate only when + # source netlist is newer than existing + # NGO file (default) +-intstyle xflow; # Message Reporting Style: ise, xflow, or silent +#-bm .bmm # Block RAM memory map file +; # User design - pick from xflow command line +.ngd; # Name of NGD file. Filebase same as design filebase +End Program ngdbuild + +# +# Options for Mapper +# +# Type "map -h " for a detailed list of map command line options +# +Program map +-o _map.ncd; # Output Mapped ncd file +-intstyle xflow; # Message Reporting Style: ise, xflow, or silent +# -fp .mfp; # Floorplan file +# -gm incremental; # Guide mode +# -timing; # Perform Timing-Driven Packing and Placement +# -ol med; # Map Effort Levels. -ol [std|med|high] + # Note: If -timing is not specified, -ol switch is ignored. + # Device families supported: Virtex2, Virtex2P +.ngd; # Input NGD file +.pcf; # Physical constraints file +END Program map + +# +# Options for Post Map Trace +# +# Type "trce -h" for a detailed list of trce command line options +# +Program post_map_trce +-v 3; # Produce verbose timing report +#-e 3; # Produce error report (limit 3 items/constraint) +-xml _map.twx; # Output XML version of the timing report +-intstyle xflow; # Message Reporting Style: ise, xflow, or silent +#-o _map.twr; # Output trace report file +#-tsi _map.tsi; # Produce Timing Specification Interaction report +#-fastpaths; # Report minimum paths in verbose mode +#-nodatasheet; # Do not create the datasheet section of the report +_map.ncd; # Input mapped ncd +.pcf; # Physical constraints file +END Program post_map_trce + +# +# Options for Place and Route +# +# Type "par -h" for a detailed list of par command line options +# +Program par +-w; # Overwrite existing placed and routed ncd +-ol high; # Overall effort level +-intstyle xflow; # Message Reporting Style: ise, xflow, or silent +# -gm incremental; # Guide mode +_map.ncd; # Input mapped NCD file +.ncd; # Output placed and routed NCD +.pcf; # Input physical constraints file +END Program par + +# +# Options for Post Par Trace +# +# Type "trce -h" for a detailed list of trce command line options +# +Program post_par_trce +-v 3; # Produce verbose timing report +#-e 3; # Produce error report (limit 3 items/constraint) +-intstyle xflow; # Message Reporting Style: ise, xflow, or silent +-xml .twx; # Output XML version of the timing report +#-o .twr; # Output trace report file +#-tsi .tsi; # Produce Timing Specification Interaction report +#-fastpaths; # Report minimum paths in verbose mode +#-nodatasheet; # Do not create the datasheet section of the report +.ncd; # Input placed and routed ncd +.pcf; # Physical constraints file +END Program post_par_trce + + diff --git a/rtl/vlib/comlib/Makefile b/rtl/vlib/comlib/Makefile new file mode 100644 index 00000000..ea3c32f9 --- /dev/null +++ b/rtl/vlib/comlib/Makefile @@ -0,0 +1,22 @@ +# $Id: Makefile 311 2010-06-30 17:52:37Z mueller $ +# +# Revision History: +# Date Rev Version Comment +# 2007-07-06 64 1.1 use Makefile.xflow +# 2007-06-03 45 1.0 Initial version +# +VBOM_all = $(wildcard *.vbom) +NGC_all = $(VBOM_all:.vbom=.ngc) +# +.phony : all clean +# +all : $(NGC_all) +# +clean : ise_clean +# +#---- +# +include $(RETROBASE)/rtl/vlib/Makefile.xflow +# +include $(VBOM_all:.vbom=.dep_xst) +# diff --git a/rtl/vlib/comlib/byte2cdata.vbom b/rtl/vlib/comlib/byte2cdata.vbom new file mode 100644 index 00000000..00d22b98 --- /dev/null +++ b/rtl/vlib/comlib/byte2cdata.vbom @@ -0,0 +1,4 @@ +# libs +../slvtypes.vhd +# design +byte2cdata.vhd diff --git a/rtl/vlib/comlib/byte2cdata.vhd b/rtl/vlib/comlib/byte2cdata.vhd new file mode 100644 index 00000000..c14daab6 --- /dev/null +++ b/rtl/vlib/comlib/byte2cdata.vhd @@ -0,0 +1,149 @@ +-- $Id: byte2cdata.vhd 314 2010-07-09 17:38:41Z mueller $ +-- +-- Copyright 2007- by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, 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 complete details. +-- +------------------------------------------------------------------------------ +-- Module Name: byte2cdata - syn +-- Description: Byte stream to 9 bit comma,data converter +-- +-- Dependencies: - +-- Test bench: - +-- Target Devices: generic +-- Tool versions: xst 8.1, 8.2, 9.1, 9.2; ghdl 0.18-0.25 +-- Revision History: +-- Date Rev Version Comment +-- 2007-10-12 88 1.0.1 avoid ieee.std_logic_unsigned, use cast to unsigned +-- 2007-08-27 76 1.0 Initial version +------------------------------------------------------------------------------ + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; + +use work.slvtypes.all; + +entity byte2cdata is -- byte stream -> 9bit comma,data + generic ( + CPREF : slv4 := "1000"; -- comma prefix + NCOMM : positive := 4); -- number of comma chars + port ( + CLK : in slbit; -- clock + RESET : in slbit; -- reset + DI : in slv8; -- input data + ENA : in slbit; -- write enable + BUSY : out slbit; -- write port hold + DO : out slv9; -- output data; bit 8 = komma flag + VAL : out slbit; -- read valid + HOLD : in slbit -- read hold + ); +end byte2cdata; + + +architecture syn of byte2cdata is + + type state_type is ( + s_idle, + s_data, + s_escape + ); + + type regs_type is record + data : slv9; -- current data + state : state_type; -- state + end record regs_type; + + constant regs_init : regs_type := ( + (others=>'0'), + s_idle + ); + + signal R_REGS : regs_type := regs_init; -- state registers + signal N_REGS : regs_type := regs_init; -- next value state regs + +begin + + assert NCOMM <= 14 + report "assert(NCOMM <= 14)" + severity FAILURE; + + proc_regs: process (CLK) + begin + + if CLK'event and CLK='1' then + if RESET = '1' then + R_REGS <= regs_init; + else + R_REGS <= N_REGS; + end if; + end if; + + end process proc_regs; + + proc_next: process (R_REGS, DI, ENA, HOLD) + + variable r : regs_type := regs_init; + variable n : regs_type := regs_init; + + variable ival : slbit := '0'; + variable ibusy : slbit := '0'; + + begin + + r := R_REGS; + n := R_REGS; + + ival := '0'; + ibusy := '1'; + + case r.state is + + when s_idle => + ibusy := '0'; + if ENA = '1' then + n.data := "0" & DI; + n.state := s_data; + if DI(7 downto 4) = CPREF then + if DI(3 downto 0) = "1111" then + n.state := s_escape; + elsif unsigned(DI(3 downto 0)) <= NCOMM then + n.data := "10000" & DI(3 downto 0); + n.state := s_data; + end if; + end if; + end if; + + when s_data => + ival := '1'; + if HOLD = '0' then + n.state := s_idle; + end if; + + when s_escape => + ibusy := '0'; + if ENA = '1' then + n.data := "0" & CPREF & DI(3 downto 0); + n.state := s_data; + end if; + + when others => null; + end case; + + N_REGS <= n; + + DO <= r.data; + VAL <= ival; + BUSY <= ibusy; + + end process proc_next; + + +end syn; diff --git a/rtl/vlib/comlib/cdata2byte.vbom b/rtl/vlib/comlib/cdata2byte.vbom new file mode 100644 index 00000000..74fae6f2 --- /dev/null +++ b/rtl/vlib/comlib/cdata2byte.vbom @@ -0,0 +1,4 @@ +# libs +../slvtypes.vhd +# design +cdata2byte.vhd diff --git a/rtl/vlib/comlib/cdata2byte.vhd b/rtl/vlib/comlib/cdata2byte.vhd new file mode 100644 index 00000000..5b767497 --- /dev/null +++ b/rtl/vlib/comlib/cdata2byte.vhd @@ -0,0 +1,168 @@ +-- $Id: cdata2byte.vhd 314 2010-07-09 17:38:41Z mueller $ +-- +-- Copyright 2007- by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, 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 complete details. +-- +------------------------------------------------------------------------------ +-- Module Name: cdata2byte - syn +-- Description: 9 bit comma,data to Byte stream converter +-- +-- Dependencies: - +-- Test bench: - +-- Target Devices: generic +-- Tool versions: xst 8.1, 8.2, 9.1, 9.2; ghdl 0.18-0.25 +-- Revision History: +-- Date Rev Version Comment +-- 2007-10-12 88 1.0.1 avoid ieee.std_logic_unsigned, use cast to unsigned +-- 2007-06-30 62 1.0 Initial version +------------------------------------------------------------------------------ + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; + +use work.slvtypes.all; + +entity cdata2byte is -- 9bit comma,data -> byte stream + generic ( + CPREF : slv4 := "1000"; -- comma prefix + NCOMM : positive := 4); -- number of comma chars + port ( + CLK : in slbit; -- clock + RESET : in slbit; -- reset + DI : in slv9; -- input data; bit 8 = komma flag + ENA : in slbit; -- write enable + BUSY : out slbit; -- write port hold + DO : out slv8; -- output data + VAL : out slbit; -- read valid + HOLD : in slbit -- read hold + ); +end cdata2byte; + + +architecture syn of cdata2byte is + + type state_type is ( + s_idle, + s_data, + s_comma, + s_escape, + s_edata + ); + + type regs_type is record + data : slv8; -- current data + state : state_type; -- state + end record regs_type; + + constant regs_init : regs_type := ( + (others=>'0'), + s_idle + ); + + signal R_REGS : regs_type := regs_init; -- state registers + signal N_REGS : regs_type := regs_init; -- next value state regs + +begin + + assert NCOMM <= 14 + report "assert(NCOMM <= 14)" + severity FAILURE; + + proc_regs: process (CLK) + begin + + if CLK'event and CLK='1' then + if RESET = '1' then + R_REGS <= regs_init; + else + R_REGS <= N_REGS; + end if; + end if; + + end process proc_regs; + + proc_next: process (R_REGS, DI, ENA, HOLD) + + variable r : regs_type := regs_init; + variable n : regs_type := regs_init; + + variable ido : slv8 := (others=>'0'); + variable ival : slbit := '0'; + variable ibusy : slbit := '0'; + + begin + + r := R_REGS; + n := R_REGS; + + ido := r.data; + ival := '0'; + ibusy := '1'; + + case r.state is + + when s_idle => + ibusy := '0'; + if ENA = '1' then + n.data := DI(7 downto 0); + n.state := s_data; + if DI(8) = '1' then + n.state := s_comma; + else + if DI(7 downto 4)=CPREF and + (DI(3 downto 0)="1111" or + unsigned(DI(3 downto 0))<=NCOMM) then + n.state := s_escape; + end if; + end if; + end if; + + when s_data => + ival := '1'; + if HOLD = '0' then + n.state := s_idle; + end if; + + when s_comma => + ido := CPREF & r.data(3 downto 0); + ival := '1'; + if HOLD = '0' then + n.state := s_idle; + end if; + + when s_escape => + ido := CPREF & "1111"; + ival := '1'; + if HOLD = '0' then + n.state := s_edata; + end if; + + when s_edata => + ido := (not CPREF) & r.data(3 downto 0); + ival := '1'; + if HOLD = '0' then + n.state := s_idle; + end if; + + when others => null; + end case; + + N_REGS <= n; + + DO <= ido; + VAL <= ival; + BUSY <= ibusy; + + end process proc_next; + + +end syn; diff --git a/rtl/vlib/comlib/comlib.vhd b/rtl/vlib/comlib/comlib.vhd new file mode 100644 index 00000000..24057f52 --- /dev/null +++ b/rtl/vlib/comlib/comlib.vhd @@ -0,0 +1,155 @@ +-- $Id: comlib.vhd 314 2010-07-09 17:38:41Z mueller $ +-- +-- Copyright 2007- by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, 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 complete details. +-- +------------------------------------------------------------------------------ +-- Package Name: comlib +-- Description: communication components +-- +-- Dependencies: - +-- Tool versions: xst 8.1, 8.2, 9.1, 9.2, 11.4; ghdl 0.18-0.26 +-- Revision History: +-- Date Rev Version Comment +-- 2007-10-12 88 1.2.1 avoid ieee.std_logic_unsigned, use cast to unsigned +-- 2007-07-08 65 1.2 added procedure crc8_update_tbl +-- 2007-06-29 61 1.1.1 rename for crc8 SALT->INIT +-- 2007-06-17 58 1.1 add crc8 +-- 2007-06-03 45 1.0 Initial version +------------------------------------------------------------------------------ + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; + +use work.slvtypes.all; + +package comlib is + +component cdata2byte is -- 9bit comma,data -> byte stream + generic ( + CPREF : slv4 := "1000"; -- comma prefix + NCOMM : positive := 4); -- number of comma chars + port ( + CLK : in slbit; -- clock + RESET : in slbit; -- reset + DI : in slv9; -- input data; bit 8 = komma flag + ENA : in slbit; -- write enable + BUSY : out slbit; -- write port hold + DO : out slv8; -- output data + VAL : out slbit; -- read valid + HOLD : in slbit -- read hold + ); +end component; + +component byte2cdata is -- byte stream -> 9bit comma,data + generic ( + CPREF : slv4 := "1000"; -- comma prefix + NCOMM : positive := 4); -- number of comma chars + port ( + CLK : in slbit; -- clock + RESET : in slbit; -- reset + DI : in slv8; -- input data + ENA : in slbit; -- write enable + BUSY : out slbit; -- write port hold + DO : out slv9; -- output data; bit 8 = komma flag + VAL : out slbit; -- read valid + HOLD : in slbit -- read hold + ); +end component; + +component crc8 is -- crc-8 generator, checker + generic ( + INIT: slv8 := "00000000"); -- initial state of crc register + port ( + CLK : in slbit; -- clock + RESET : in slbit; -- reset + ENA : in slbit; -- update enable + DI : in slv8; -- input data + CRC : out slv8 -- crc code + ); +end component; + + procedure crc8_update (crc : inout slv8; + data : in slv8); + procedure crc8_update_tbl (crc : inout slv8; + data : in slv8); + +end comlib; + +-- ---------------------------------------------------------------------------- + +package body comlib is + + procedure crc8_update (crc : inout slv8; + data : in slv8) is + variable t : slv8 := (others=>'0'); + begin + + t := data xor crc; + crc(0) := t(0) xor t(4) xor t(5) xor t(6); + crc(1) := t(1) xor t(5) xor t(6) xor t(7); + crc(2) := t(0) xor t(2) xor t(4) xor t(5) xor t(7); + crc(3) := t(0) xor t(1) xor t(3) xor t(4); + crc(4) := t(0) xor t(1) xor t(2) xor t(6); + crc(5) := t(1) xor t(2) xor t(3) xor t(7); + crc(6) := t(2) xor t(3) xor t(4); + crc(7) := t(3) xor t(4) xor t(5); + + end procedure crc8_update; + + procedure crc8_update_tbl (crc : inout slv8; + data : in slv8) is + + type crc8_tbl_type is array (0 to 255) of integer; + variable crc8_tbl : crc8_tbl_type := -- generated with gen_crc8_tbl + ( 0, 29, 58, 39, 116, 105, 78, 83, + 232, 245, 210, 207, 156, 129, 166, 187, + 205, 208, 247, 234, 185, 164, 131, 158, + 37, 56, 31, 2, 81, 76, 107, 118, + 135, 154, 189, 160, 243, 238, 201, 212, + 111, 114, 85, 72, 27, 6, 33, 60, + 74, 87, 112, 109, 62, 35, 4, 25, + 162, 191, 152, 133, 214, 203, 236, 241, + 19, 14, 41, 52, 103, 122, 93, 64, + 251, 230, 193, 220, 143, 146, 181, 168, + 222, 195, 228, 249, 170, 183, 144, 141, + 54, 43, 12, 17, 66, 95, 120, 101, + 148, 137, 174, 179, 224, 253, 218, 199, + 124, 97, 70, 91, 8, 21, 50, 47, + 89, 68, 99, 126, 45, 48, 23, 10, + 177, 172, 139, 150, 197, 216, 255, 226, + 38, 59, 28, 1, 82, 79, 104, 117, + 206, 211, 244, 233, 186, 167, 128, 157, + 235, 246, 209, 204, 159, 130, 165, 184, + 3, 30, 57, 36, 119, 106, 77, 80, + 161, 188, 155, 134, 213, 200, 239, 242, + 73, 84, 115, 110, 61, 32, 7, 26, + 108, 113, 86, 75, 24, 5, 34, 63, + 132, 153, 190, 163, 240, 237, 202, 215, + 53, 40, 15, 18, 65, 92, 123, 102, + 221, 192, 231, 250, 169, 180, 147, 142, + 248, 229, 194, 223, 140, 145, 182, 171, + 16, 13, 42, 55, 100, 121, 94, 67, + 178, 175, 136, 149, 198, 219, 252, 225, + 90, 71, 96, 125, 46, 51, 20, 9, + 127, 98, 69, 88, 11, 22, 49, 44, + 151, 138, 173, 176, 227, 254, 217, 196 + ); + + begin + + crc := conv_std_logic_vector( + crc8_tbl(conv_integer(unsigned(data xor crc))), 8); + + end procedure crc8_update_tbl; + +end package body comlib; diff --git a/rtl/vlib/comlib/crc8.vbom b/rtl/vlib/comlib/crc8.vbom new file mode 100644 index 00000000..2b111e3d --- /dev/null +++ b/rtl/vlib/comlib/crc8.vbom @@ -0,0 +1,5 @@ +# libs +../slvtypes.vhd +comlib.vhd +# design +crc8.vhd diff --git a/rtl/vlib/comlib/crc8.vhd b/rtl/vlib/comlib/crc8.vhd new file mode 100644 index 00000000..a3b70917 --- /dev/null +++ b/rtl/vlib/comlib/crc8.vhd @@ -0,0 +1,101 @@ +-- $Id: crc8.vhd 314 2010-07-09 17:38:41Z mueller $ +-- +-- Copyright 2007- by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, 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 complete details. +-- +------------------------------------------------------------------------------ +-- Module Name: crc8 - syn +-- Description: 8bit CRC generator, use CRC-8-SAE J1850 polynomial. +-- Based on CRC-8-SAE J1850 polynomial: +-- x^8 + x^4 + x^3 + x^2 + 1 (0x1d) +-- It is irreducible, and can be implemented with <= 54 xor's +-- +-- Notes: # XST synthesis for a Spartan-3 gives: +-- 1-bit xor2 : 11 +-- 1-bit xor4 : 5 +-- 1-bit xor5 : 1 +-- Number of 4 input LUTs: 20 +-- # Synthesis with crc8_update_tbl gives a lut-rom based table +-- design. Even though a 256x8 bit ROM is behind, the optimizer +-- gets it into 12 slices with 22 4 input LUTs, thus only +-- little larger than with xor's. +-- +-- Dependencies: - +-- Test bench: - +-- Target Devices: generic +-- Tool versions: xst 8.1, 8.2, 9.1, 9.2; ghdl 0.18-0.25 +-- Revision History: +-- Date Rev Version Comment +-- 2007-07-08 65 1.0 Initial version +------------------------------------------------------------------------------ + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; + +use work.slvtypes.all; +use work.comlib.all; + +entity crc8 is -- crc-8 generator, checker + generic ( + INIT: slv8 := "00000000"); -- initial state of crc register + port ( + CLK : in slbit; -- clock + RESET : in slbit; -- reset + ENA : in slbit; -- update enable + DI : in slv8; -- input data + CRC : out slv8 -- crc code + ); +end crc8; + + +architecture syn of crc8 is + + signal R_CRC : slv8 := INIT; -- state registers + signal N_CRC : slv8 := INIT; -- next value state regs + +begin + + proc_regs: process (CLK) + begin + + if CLK'event and CLK='1' then + if RESET = '1' then + R_CRC <= INIT; + else + R_CRC <= N_CRC; + end if; + end if; + + end process proc_regs; + + proc_next: process (R_CRC, DI, ENA) + + variable r : slv8 := INIT; + variable n : slv8 := INIT; + + begin + + r := R_CRC; + n := R_CRC; + + if ENA = '1' then + crc8_update(n, DI); + end if; + + N_CRC <= n; + + CRC <= R_CRC; + + end process proc_next; + + +end syn; diff --git a/rtl/vlib/comlib/misc/.cvsignore b/rtl/vlib/comlib/misc/.cvsignore new file mode 100644 index 00000000..928e0799 --- /dev/null +++ b/rtl/vlib/comlib/misc/.cvsignore @@ -0,0 +1,2 @@ +gen_crc8_tbl +gen_crc8_tbl_check diff --git a/rtl/vlib/comlib/misc/Makefile b/rtl/vlib/comlib/misc/Makefile new file mode 100644 index 00000000..5c966c87 --- /dev/null +++ b/rtl/vlib/comlib/misc/Makefile @@ -0,0 +1,25 @@ +# $Id: Makefile 311 2010-06-30 17:52:37Z mueller $ +# +# Revision History: +# Date Rev Version Comment +# 2007-11-26 98 1.0 Initial version +# +EXE_all = gen_crc8_tbl gen_crc8_tbl_check +# +# +.phony : all clean +# +all : $(EXE_all) +# +clean : ghdl_clean +# +#----- +# +include $(RETROBASE)/rtl/vlib/Makefile.ghdl +# +VBOM_all = $(wildcard *.vbom) +# +include $(VBOM_all:.vbom=.dep_ghdl) +# +#----- +# diff --git a/rtl/vlib/comlib/misc/gen_crc8_tbl.vbom b/rtl/vlib/comlib/misc/gen_crc8_tbl.vbom new file mode 100644 index 00000000..5f077677 --- /dev/null +++ b/rtl/vlib/comlib/misc/gen_crc8_tbl.vbom @@ -0,0 +1,6 @@ +#libs +../../slvtypes.vhd +../comlib.vhd +#components +#design +gen_crc8_tbl.vhd diff --git a/rtl/vlib/comlib/misc/gen_crc8_tbl.vhd b/rtl/vlib/comlib/misc/gen_crc8_tbl.vhd new file mode 100644 index 00000000..fc333f2f --- /dev/null +++ b/rtl/vlib/comlib/misc/gen_crc8_tbl.vhd @@ -0,0 +1,61 @@ +-- $Id: gen_crc8_tbl.vhd 314 2010-07-09 17:38:41Z mueller $ +-- +-- Copyright 2007- by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, 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 complete details. +-- +------------------------------------------------------------------------------ +-- Module Name: gen_crc8_tbl - sim +-- Description: stand-alone program to print crc8 transition table +-- +-- Dependencies: comlib/crc8_update (procedure) +-- +-- Revision History: +-- Date Rev Version Comment +-- 2007-10-12 88 1.0.1 avoid ieee.std_logic_unsigned, use cast to unsigned +-- 2007-07-08 65 1.0 Initial version +------------------------------------------------------------------------------ + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; +use ieee.std_logic_textio.all; +use std.textio.all; + +use work.slvtypes.all; +use work.comlib.all; + +entity gen_crc8_tbl is +end gen_crc8_tbl; + +architecture sim of gen_crc8_tbl is +begin + + process + variable crc : slv8 := (others=>'0'); + variable dat : slv8 := (others=>'0'); + variable oline : line; + begin + for i in 0 to 255 loop + crc := (others=>'0'); + dat := conv_std_logic_vector(i,8); + crc8_update(crc, dat); + write(oline, conv_integer(unsigned(crc)), right, 4); + if i /= 255 then + write(oline, string'(",")); + end if; + if (i mod 8) = 7 then + writeline(output, oline); + end if; + end loop; -- i + wait; + end process; + +end sim; diff --git a/rtl/vlib/comlib/misc/gen_crc8_tbl_check.vbom b/rtl/vlib/comlib/misc/gen_crc8_tbl_check.vbom new file mode 100644 index 00000000..13f3da1e --- /dev/null +++ b/rtl/vlib/comlib/misc/gen_crc8_tbl_check.vbom @@ -0,0 +1,6 @@ +#libs +#../../slvtypes.vhd +#../comlib.vhd +#components +#design +gen_crc8_tbl_check.vhd diff --git a/rtl/vlib/comlib/misc/gen_crc8_tbl_check.vhd b/rtl/vlib/comlib/misc/gen_crc8_tbl_check.vhd new file mode 100644 index 00000000..6935d886 --- /dev/null +++ b/rtl/vlib/comlib/misc/gen_crc8_tbl_check.vhd @@ -0,0 +1,100 @@ +-- $Id: gen_crc8_tbl_check.vhd 314 2010-07-09 17:38:41Z mueller $ +-- +-- Copyright 2007- by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, 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 complete details. +-- +------------------------------------------------------------------------------ +-- Module Name: gen_crc8_tbl - sim +-- Description: stand-alone program to test crc8 transition table +-- +-- Dependencies: - +-- +-- Revision History: +-- Date Rev Version Comment +-- 2007-10-12 88 1.0.1 avoid ieee.std_logic_unsigned, use cast to unsigned +-- 2007-07-08 65 1.0 Initial version +------------------------------------------------------------------------------ + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; +use ieee.std_logic_textio.all; +use std.textio.all; + +--use work.slvtypes.all; +--use work.comlib.all; + +entity gen_crc8_tbl_check is +end gen_crc8_tbl_check; + +architecture sim of gen_crc8_tbl_check is +begin + + process + type crc8_tbl_type is array (0 to 255) of integer; + + variable crc8_tbl : crc8_tbl_type := -- generated with gen_crc8_tbl + ( 0, 29, 58, 39, 116, 105, 78, 83, + 232, 245, 210, 207, 156, 129, 166, 187, + 205, 208, 247, 234, 185, 164, 131, 158, + 37, 56, 31, 2, 81, 76, 107, 118, + 135, 154, 189, 160, 243, 238, 201, 212, + 111, 114, 85, 72, 27, 6, 33, 60, + 74, 87, 112, 109, 62, 35, 4, 25, + 162, 191, 152, 133, 214, 203, 236, 241, + 19, 14, 41, 52, 103, 122, 93, 64, + 251, 230, 193, 220, 143, 146, 181, 168, + 222, 195, 228, 249, 170, 183, 144, 141, + 54, 43, 12, 17, 66, 95, 120, 101, + 148, 137, 174, 179, 224, 253, 218, 199, + 124, 97, 70, 91, 8, 21, 50, 47, + 89, 68, 99, 126, 45, 48, 23, 10, + 177, 172, 139, 150, 197, 216, 255, 226, + 38, 59, 28, 1, 82, 79, 104, 117, + 206, 211, 244, 233, 186, 167, 128, 157, + 235, 246, 209, 204, 159, 130, 165, 184, + 3, 30, 57, 36, 119, 106, 77, 80, + 161, 188, 155, 134, 213, 200, 239, 242, + 73, 84, 115, 110, 61, 32, 7, 26, + 108, 113, 86, 75, 24, 5, 34, 63, + 132, 153, 190, 163, 240, 237, 202, 215, + 53, 40, 15, 18, 65, 92, 123, 102, + 221, 192, 231, 250, 169, 180, 147, 142, + 248, 229, 194, 223, 140, 145, 182, 171, + 16, 13, 42, 55, 100, 121, 94, 67, + 178, 175, 136, 149, 198, 219, 252, 225, + 90, 71, 96, 125, 46, 51, 20, 9, + 127, 98, 69, 88, 11, 22, 49, 44, + 151, 138, 173, 176, 227, 254, 217, 196 + ); + + variable crc : integer := 0; + variable oline : line; + + begin + + loop_i: for i in 0 to 255 loop + write(oline, i, right, 4); + write(oline, string'(": cycle length = ")); + crc := i; + loop_n: for n in 1 to 256 loop + crc := crc8_tbl(crc); + if crc = i then + write(oline, n, right, 4); + writeline(output, oline); + exit loop_n; + end if; + end loop; -- n + end loop; -- i + wait; + end process; + +end sim; diff --git a/rtl/vlib/genlib/Makefile b/rtl/vlib/genlib/Makefile new file mode 100644 index 00000000..2abd59df --- /dev/null +++ b/rtl/vlib/genlib/Makefile @@ -0,0 +1,23 @@ +# $Id: Makefile 311 2010-06-30 17:52:37Z mueller $ +# +# Revision History: +# Date Rev Version Comment +# 2007-12-09 100 1.1.1 drop ISE_p definition +# 2007-06-03 47 1.1 use Makefile.xflow +# 2007-06-03 45 1.0 Initial version +# +VBOM_all = $(wildcard *.vbom) +NGC_all = $(VBOM_all:.vbom=.ngc) +# +.phony : all clean +# +all : $(NGC_all) +# +clean : ise_clean +# +#---- +# +include $(RETROBASE)/rtl/vlib/Makefile.xflow +# +include $(VBOM_all:.vbom=.dep_xst) +# diff --git a/rtl/vlib/genlib/clkdivce.vbom b/rtl/vlib/genlib/clkdivce.vbom new file mode 100644 index 00000000..f6ec8f1b --- /dev/null +++ b/rtl/vlib/genlib/clkdivce.vbom @@ -0,0 +1,4 @@ +# libs +../slvtypes.vhd +# design +clkdivce.vhd diff --git a/rtl/vlib/genlib/clkdivce.vhd b/rtl/vlib/genlib/clkdivce.vhd new file mode 100644 index 00000000..1fcebb33 --- /dev/null +++ b/rtl/vlib/genlib/clkdivce.vhd @@ -0,0 +1,114 @@ +-- $Id: clkdivce.vhd 314 2010-07-09 17:38:41Z mueller $ +-- +-- Copyright 2007- by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, 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 complete details. +-- +------------------------------------------------------------------------------ +-- Module Name: clkgen - syn +-- Description: Generate usec and msec enable signals +-- +-- Dependencies: - +-- Test bench: - +-- Target Devices: generic +-- Tool versions: xst 8.1, 8.2, 9.1, 9.2; ghdl 0.18-0.25 +-- Revision History: +-- Date Rev Version Comment +-- 2008-01-20 112 1.0.2 rename clkgen->clkdivce; remove SYS_CLK port +-- 2007-10-12 88 1.0.1 avoid ieee.std_logic_unsigned, use cast to unsigned +-- 2007-06-30 62 1.0 Initial version +------------------------------------------------------------------------------ + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; + +use work.slvtypes.all; + +entity clkdivce is -- generate usec/msec ce pulses + generic ( + CDUWIDTH : positive := 6; -- usec clock divider width + USECDIV : positive := 50; -- divider ratio for usec pulse + MSECDIV : positive := 1000); -- divider ratio for msec pulse + port ( + CLK : in slbit; -- input clock + CE_USEC : out slbit; -- usec pulse + CE_MSEC : out slbit -- msec pulse + ); +end clkdivce; + + +architecture syn of clkdivce is + + type regs_type is record + ucnt : slv(CDUWIDTH-1 downto 0); -- usec clock divider counter + mcnt : slv10; -- msec clock divider counter + usec : slbit; -- usec pulse + msec : slbit; -- msec pulse + end record regs_type; + + constant regs_init : regs_type := ( + conv_std_logic_vector(USECDIV-1,CDUWIDTH), + conv_std_logic_vector(MSECDIV-1,10), + '0','0' + ); + + signal R_REGS : regs_type := regs_init; -- state registers + signal N_REGS : regs_type := regs_init; -- next value state regs + +begin + + assert USECDIV <= 2**CDUWIDTH and MSECDIV <= 1024 + report "assert(USECDIV <= 2**CDUWIDTH and MSECDIV <= 1024): " & + "USECDIV too large for given CDUWIDTH or MSECDIV>1024" + severity FAILURE; + + proc_regs: process (CLK) + begin + + if CLK'event and CLK='1' then + R_REGS <= N_REGS; + end if; + + end process proc_regs; + + proc_next: process (R_REGS) + + variable r : regs_type := regs_init; + variable n : regs_type := regs_init; + + begin + + r := R_REGS; + n := R_REGS; + + n.usec := '0'; + n.msec := '0'; + + n.ucnt := unsigned(r.ucnt) - 1; + if unsigned(r.ucnt) = 0 then + n.usec := '1'; + n.ucnt := conv_std_logic_vector(USECDIV-1,CDUWIDTH); + n.mcnt := unsigned(r.mcnt) - 1; + if unsigned(r.mcnt) = 0 then + n.msec := '1'; + n.mcnt := conv_std_logic_vector(MSECDIV-1,10); + end if; + end if; + + N_REGS <= n; + + CE_USEC <= r.usec; + CE_MSEC <= r.msec; + + end process proc_next; + + +end syn; diff --git a/rtl/vlib/genlib/debounce_gen.vbom b/rtl/vlib/genlib/debounce_gen.vbom new file mode 100644 index 00000000..e7dd2dc5 --- /dev/null +++ b/rtl/vlib/genlib/debounce_gen.vbom @@ -0,0 +1,4 @@ +# libs +../slvtypes.vhd +# design +debounce_gen.vhd diff --git a/rtl/vlib/genlib/debounce_gen.vhd b/rtl/vlib/genlib/debounce_gen.vhd new file mode 100644 index 00000000..e3129750 --- /dev/null +++ b/rtl/vlib/genlib/debounce_gen.vhd @@ -0,0 +1,132 @@ +-- $Id: debounce_gen.vhd 314 2010-07-09 17:38:41Z mueller $ +-- +-- Copyright 2007- by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, 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 complete details. +-- +------------------------------------------------------------------------------ +-- Module Name: debounce_gen - syn +-- Description: Generic signal debouncer +-- +-- Dependencies: - +-- Test bench: tb/tb_debounce_gen +-- Target Devices: generic +-- Tool versions: xst 8.1, 8.2, 9.1, 9.2; ghdl 0.18-0.25 +-- Revision History: +-- Date Rev Version Comment +-- 2007-12-26 105 1.0.2 add default for RESET +-- 2007-10-12 88 1.0.1 avoid ieee.std_logic_unsigned, use cast to unsigned +-- 2007-06-29 61 1.0 Initial version +------------------------------------------------------------------------------ + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; + +use work.slvtypes.all; + +entity debounce_gen is -- debounce, generic vector + generic ( + CWIDTH : positive := 2; -- clock interval counter width + CEDIV : positive := 3; -- clock interval divider + DWIDTH : positive := 8); -- data width + port ( + CLK : in slbit; -- clock + RESET : in slbit := '0'; -- reset + CE_INT : in slbit; -- clock interval enable (usec or msec) + DI : in slv(DWIDTH-1 downto 0); -- data in + DO : out slv(DWIDTH-1 downto 0) -- data out + ); +end entity debounce_gen; + + +architecture syn of debounce_gen is + + constant cntzero : slv(CWIDTH-1 downto 0) := (others=>'0'); + constant datazero : slv(dWIDTH-1 downto 0) := (others=>'0'); + + type regs_type is record + cecnt : slv(CWIDTH-1 downto 0); -- clock interval counter + dref : slv(DWIDTH-1 downto 0); -- data reference + dchange : slv(DWIDTH-1 downto 0); -- data change flag + dout : slv(DWIDTH-1 downto 0); -- data output + end record regs_type; + + constant regs_init : regs_type := ( + cntzero, + datazero, + datazero, + datazero + ); + + signal R_REGS : regs_type := regs_init; -- state registers + signal N_REGS : regs_type := regs_init; -- next value state regs + +begin + + assert CEDIV<=2**CWIDTH report "assert(CEDIV<=2**CWIDTH)" severity failure; + + proc_regs: process (CLK) + begin + + if CLK'event and CLK='1' then + if RESET = '1' then + R_REGS.cecnt <= cntzero; + R_REGS.dref <= DI; + R_REGS.dchange <= datazero; + R_REGS.dout <= DI; + else + R_REGS <= N_REGS; + end if; + end if; + + end process proc_regs; + + proc_next: process (R_REGS, CE_INT, DI) + + variable r : regs_type := regs_init; + variable n : regs_type := regs_init; + + begin + + r := R_REGS; + n := R_REGS; + + for i in DI'range loop + if DI(i) /= r.dref(i) then + n.dchange(i) := '1'; + end if; + end loop; + + if CE_INT = '1' then + if unsigned(r.cecnt) = 0 then + n.cecnt := conv_std_logic_vector(CEDIV-1,CWIDTH); + n.dref := DI; + n.dchange := datazero; + for i in DI'range loop + if r.dchange(i) = '0' then + n.dout(i) := r.dref(i); + end if; + end loop; + + else + n.cecnt := unsigned(r.cecnt) - 1; + end if; + end if; + + N_REGS <= n; + + DO <= r.dout; + + end process proc_next; + + +end syn; + diff --git a/rtl/vlib/genlib/genlib.vhd b/rtl/vlib/genlib/genlib.vhd new file mode 100644 index 00000000..975e18ad --- /dev/null +++ b/rtl/vlib/genlib/genlib.vhd @@ -0,0 +1,156 @@ +-- $Id: genlib.vhd 314 2010-07-09 17:38:41Z mueller $ +-- +-- Copyright 2007-2010 by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, 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 complete details. +-- +------------------------------------------------------------------------------ +-- Package Name: genlib +-- Description: some general purpose components +-- +-- Dependencies: - +-- Tool versions: xst 8.1, 8.2, 9.1, 9.2, 11.4; ghdl 0.18-0.26 +-- Revision History: +-- Date Rev Version Comment +-- 2010-04-17 277 1.0.7 timer: no default for START,DONE,BUSY; drop STOP +-- 2010-04-02 273 1.0.6 add timer +-- 2008-01-20 112 1.0.5 rename clkgen->clkdivce +-- 2007-12-26 106 1.0.4 added gray_cnt_(4|5|n|gen) and gray2bin_gen +-- 2007-12-25 105 1.0.3 RESET:='0' defaults +-- 2007-06-17 58 1.0.2 added debounce_gen +-- 2007-06-16 57 1.0.1 added cnt_array_dram, cnt_array_regs +-- 2007-06-03 45 1.0 Initial version +------------------------------------------------------------------------------ + +library ieee; +use ieee.std_logic_1164.all; + +use work.slvtypes.all; + +package genlib is + +component clkdivce is -- generate usec/msec ce pulses + generic ( + CDUWIDTH : positive := 6; -- usec clock divider width + USECDIV : positive := 50; -- divider ratio for usec pulse + MSECDIV : positive := 1000); -- divider ratio for msec pulse + port ( + CLK : in slbit; -- input clock + CE_USEC : out slbit; -- usec pulse + CE_MSEC : out slbit -- msec pulse + ); +end component; + +component cnt_array_dram is -- counter array, dram based + generic ( + AWIDTH : positive := 4; -- address width + DWIDTH : positive := 16); -- data width + port ( + CLK : in slbit; -- clock + RESET : in slbit := '0'; -- clear counters + CE : in slv(2**AWIDTH-1 downto 0); -- count enables + ADDR : out slv(AWIDTH-1 downto 0); -- counter address + DATA : out slv(DWIDTH-1 downto 0); -- counter data + ACT : out slbit -- active (not reseting) + ); +end component; + +component cnt_array_regs is -- counter array, register based + generic ( + AWIDTH : positive := 4; -- address width + DWIDTH : positive := 16); -- data width + port ( + CLK : in slbit; -- clock + RESET : in slbit := '0'; -- clear counters + CE : in slv(2**AWIDTH-1 downto 0); -- count enables + ADDR : in slv(AWIDTH-1 downto 0); -- address + DATA : out slv(DWIDTH-1 downto 0) -- counter data + ); +end component; + +component debounce_gen is -- debounce, generic vector + generic ( + CWIDTH : positive := 2; -- clock interval counter width + CEDIV : positive := 3; -- clock interval divider + DWIDTH : positive := 8); -- data width + port ( + CLK : in slbit; -- clock + RESET : in slbit := '0'; -- reset + CE_INT : in slbit; -- clock interval enable (usec or msec) + DI : in slv(DWIDTH-1 downto 0); -- data in + DO : out slv(DWIDTH-1 downto 0) -- data out + ); +end component; + +component gray_cnt_gen is -- gray code counter, generic vector + generic ( + DWIDTH : positive := 4); -- data width + port ( + CLK : in slbit; -- clock + RESET : in slbit := '0'; -- reset + CE : in slbit := '1'; -- count enable + DATA : out slv(DWIDTH-1 downto 0) -- data out + ); +end component; + +component gray_cnt_4 is -- 4 bit gray code counter (ROM based) + port ( + CLK : in slbit; -- clock + RESET : in slbit := '0'; -- reset + CE : in slbit := '1'; -- count enable + DATA : out slv4 -- data out + ); +end component; + +component gray_cnt_5 is -- 5 bit gray code counter (ROM based) + port ( + CLK : in slbit; -- clock + RESET : in slbit := '0'; -- reset + CE : in slbit := '1'; -- count enable + DATA : out slv5 -- data out + ); +end component; + +component gray_cnt_n is -- n bit gray code counter + generic ( + DWIDTH : positive := 8); -- data width + port ( + CLK : in slbit; -- clock + RESET : in slbit := '0'; -- reset + CE : in slbit := '1'; -- count enable + DATA : out slv(DWIDTH-1 downto 0) -- data out + ); +end component; + +component gray2bin_gen is -- gray->bin converter, generic vector + generic ( + DWIDTH : positive := 4); -- data width + port ( + DI : in slv(DWIDTH-1 downto 0); -- gray code input + DO : out slv(DWIDTH-1 downto 0) -- binary code output + ); +end component; + +component timer is -- retriggerable timer + generic ( + TWIDTH : positive := 4; -- timer counter width + RETRIG : boolean := true); -- re-triggerable true/false + port ( + CLK : in slbit; -- clock + CE : in slbit := '1'; -- clock enable + DELAY : in slv(TWIDTH-1 downto 0) := (others=>'1'); -- timer delay + START : in slbit; -- start timer + STOP : in slbit := '0'; -- stop timer + DONE : out slbit; -- mark last delay cycle + BUSY : out slbit -- timer running + ); +end component; + +end genlib; diff --git a/rtl/vlib/memlib/Makefile b/rtl/vlib/memlib/Makefile new file mode 100644 index 00000000..76292ba0 --- /dev/null +++ b/rtl/vlib/memlib/Makefile @@ -0,0 +1,22 @@ +# $Id: Makefile 311 2010-06-30 17:52:37Z mueller $ +# +# Revision History: +# Date Rev Version Comment +# 2007-12-09 100 1.0.1 drop ISE_p definition +# 2007-06-03 45 1.0 Initial version +# +VBOM_all = $(wildcard *.vbom) +NGC_all = $(VBOM_all:.vbom=.ngc) +# +.phony : all clean +# +all : $(NGC_all) +# +clean : ise_clean +# +#---- +# +include $(RETROBASE)/rtl/vlib/Makefile.xflow +# +include $(VBOM_all:.vbom=.dep_xst) +# diff --git a/rtl/vlib/memlib/fifo_1c_dram.vbom b/rtl/vlib/memlib/fifo_1c_dram.vbom new file mode 100644 index 00000000..784cfa4a --- /dev/null +++ b/rtl/vlib/memlib/fifo_1c_dram.vbom @@ -0,0 +1,7 @@ +# libs +../slvtypes.vhd +memlib.vhd +# components +fifo_1c_dram_raw.vbom +# design +fifo_1c_dram.vhd diff --git a/rtl/vlib/memlib/fifo_1c_dram.vhd b/rtl/vlib/memlib/fifo_1c_dram.vhd new file mode 100644 index 00000000..286564ff --- /dev/null +++ b/rtl/vlib/memlib/fifo_1c_dram.vhd @@ -0,0 +1,95 @@ +-- $Id: fifo_1c_dram.vhd 314 2010-07-09 17:38:41Z mueller $ +-- +-- Copyright 2007- by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, 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 complete details. +-- +------------------------------------------------------------------------------ +-- Module Name: fifo_1c_dram - syn +-- Description: FIFO, single clock domain, distributed RAM based, with +-- enable/busy/valid/hold interface. +-- +-- Dependencies: fifo_1c_dram_raw +-- +-- Test bench: tb/tb_fifo_1c_dram +-- Target Devices: generic Spartan, Virtex +-- Tool versions: xst 8.1, 8.2, 9.1, 9.2; ghdl 0.18-0.25 +-- Revision History: +-- Date Rev Version Comment +-- 2007-06-06 49 1.0 Initial version +-- +-- Some synthesis results: +-- - 2007-12-27 ise 8.2.03 for xc3s1000-ft256-4: +-- AWIDTH DWIDTH LUT.l LUT.m Flop clock(xst est.) +-- 4 16 31 32 22 153MHz ( 16 words) +-- 5 16 49 64 23 120MHz ( 32 words) +-- 6 16 70 128 23 120MHz ( 64 words) +-- 7 16 111 256 30 120MHz (128 words) +------------------------------------------------------------------------------ + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; + +use work.slvtypes.all; +use work.memlib.all; + +entity fifo_1c_dram is -- fifo, 1 clock, dram based + generic ( + AWIDTH : positive := 7; -- address width (sets size) + DWIDTH : positive := 16); -- data width + port ( + CLK : in slbit; -- clock + RESET : in slbit; -- reset + DI : in slv(DWIDTH-1 downto 0); -- input data + ENA : in slbit; -- write enable + BUSY : out slbit; -- write port hold + DO : out slv(DWIDTH-1 downto 0); -- output data + VAL : out slbit; -- read valid + HOLD : in slbit; -- read hold + SIZE : out slv(AWIDTH downto 0) -- number of used slots + ); +end fifo_1c_dram; + + +architecture syn of fifo_1c_dram is + + signal WE : slbit := '0'; + signal RE : slbit := '0'; + signal SIZE_L : slv(AWIDTH-1 downto 0) := (others=>'0'); + signal EMPTY : slbit := '0'; + signal FULL : slbit := '0'; + +begin + + FIFO : fifo_1c_dram_raw + generic map ( + AWIDTH => AWIDTH, + DWIDTH => DWIDTH) + port map ( + CLK => CLK, + RESET => RESET, + WE => WE, + RE => RE, + DI => DI, + DO => DO, + SIZE => SIZE_L, + EMPTY => EMPTY, + FULL => FULL + ); + + WE <= ENA and (not FULL); + RE <= (not EMPTY) and (not HOLD); + + BUSY <= FULL; + VAL <= not EMPTY; + SIZE <= FULL & SIZE_L; + +end syn; diff --git a/rtl/vlib/memlib/fifo_1c_dram_raw.vbom b/rtl/vlib/memlib/fifo_1c_dram_raw.vbom new file mode 100644 index 00000000..2f470174 --- /dev/null +++ b/rtl/vlib/memlib/fifo_1c_dram_raw.vbom @@ -0,0 +1,8 @@ +# libs +../slvtypes.vhd +memlib.vhd +# components +[ghdl,isim]ram_1swar_1ar_gen.vbom +[xst]ram_1swar_1ar_gen_unisim.vbom +# design +fifo_1c_dram_raw.vhd diff --git a/rtl/vlib/memlib/fifo_1c_dram_raw.vhd b/rtl/vlib/memlib/fifo_1c_dram_raw.vhd new file mode 100644 index 00000000..68a2373e --- /dev/null +++ b/rtl/vlib/memlib/fifo_1c_dram_raw.vhd @@ -0,0 +1,160 @@ +-- $Id: fifo_1c_dram_raw.vhd 314 2010-07-09 17:38:41Z mueller $ +-- +-- Copyright 2007- by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, 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 complete details. +-- +------------------------------------------------------------------------------ +-- Module Name: fifo_1c_dram_raw - syn +-- Description: FIFO, single clock domain, distributed RAM based, 'raw' +-- interface exposing dram signals. +-- +-- Dependencies: ram_1swar_1ar_gen +-- +-- Test bench: tb/tb_fifo_1c_dram +-- Target Devices: generic Spartan, Virtex +-- Tool versions: xst 8.1, 8.2, 9.1, 9.2; ghdl 0.18-0.25 +-- Revision History: +-- Date Rev Version Comment +-- 2007-10-12 88 1.0.1 avoid ieee.std_logic_unsigned, use cast to unsigned +-- 2007-06-03 47 1.0 Initial version +------------------------------------------------------------------------------ + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; + +use work.slvtypes.all; +use work.memlib.all; + +entity fifo_1c_dram_raw is -- fifo, 1 clock, dram based, raw + generic ( + AWIDTH : positive := 4; -- address width (sets size) + DWIDTH : positive := 16); -- data width + port ( + CLK : in slbit; -- clock + RESET : in slbit; -- reset + WE : in slbit; -- write enable + RE : in slbit; -- read enable + DI : in slv(DWIDTH-1 downto 0); -- input data + DO : out slv(DWIDTH-1 downto 0); -- output data + SIZE : out slv(AWIDTH-1 downto 0); -- number of used slots + EMPTY : out slbit; -- empty flag + FULL : out slbit -- full flag + ); +end fifo_1c_dram_raw; + + +architecture syn of fifo_1c_dram_raw is + + type regs_type is record + waddr : slv(AWIDTH-1 downto 0); -- write address + raddr : slv(AWIDTH-1 downto 0); -- read address + empty : slbit; -- empty flag + full : slbit; -- full flag + end record regs_type; + + constant memsize : positive := 2**AWIDTH; + constant regs_init : regs_type := ( + conv_std_logic_vector(0,AWIDTH), + conv_std_logic_vector(0,AWIDTH), + '1','0' + ); + + signal R_REGS : regs_type := regs_init; -- state registers + signal N_REGS : regs_type := regs_init; -- next value state regs + + signal RAM_WE : slbit := '0'; + +begin + + RAM : ram_1swar_1ar_gen + generic map ( + AWIDTH => AWIDTH, + DWIDTH => DWIDTH) + port map ( + CLK => CLK, + WE => RAM_WE, + ADDRA => R_REGS.waddr, + ADDRB => R_REGS.raddr, + DI => DI, + DOA => open, + DOB => DO + ); + + proc_regs: process (CLK) + begin + + if CLK'event and CLK='1' then + R_REGS <= N_REGS; + end if; + + end process proc_regs; + + proc_next: process (R_REGS, RESET, WE, RE) + + variable r : regs_type := regs_init; + variable n : regs_type := regs_init; + + variable isize : slv(AWIDTH-1 downto 0) := (others=>'0'); + + variable we_val : slbit := '0'; + variable re_val : slbit := '0'; + variable iram_we : slbit := '0'; + + begin + + r := R_REGS; + n := R_REGS; + + re_val := RE and not r.empty; + we_val := WE and ((not r.full) or RE); + isize := unsigned(r.waddr) - unsigned(r.raddr); + iram_we := '0'; + + if RESET = '1' then + n := regs_init; + + else + + if we_val = '1' then + n.waddr := unsigned(r.waddr) + 1; + iram_we := '1'; + if re_val = '0' then + n.empty := '0'; + if unsigned(isize) = memsize-1 then + n.full := '1'; + end if; + end if; + end if; + + if re_val = '1' then + n.raddr := unsigned(r.raddr) + 1; + if we_val = '0' then + n.full := '0'; + if unsigned(isize) = 1 then + n.empty := '1'; + end if; + end if; + end if; + + end if; + + N_REGS <= n; + + RAM_WE <= iram_we; + + SIZE <= isize; + EMPTY <= r.empty; + FULL <= r.full; + + end process proc_next; + +end syn; diff --git a/rtl/vlib/memlib/memlib.vhd b/rtl/vlib/memlib/memlib.vhd new file mode 100644 index 00000000..5af9e5ac --- /dev/null +++ b/rtl/vlib/memlib/memlib.vhd @@ -0,0 +1,238 @@ +-- $Id: memlib.vhd 314 2010-07-09 17:38:41Z mueller $ +-- +-- Copyright 2006-2007 by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, 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 complete details. +-- +------------------------------------------------------------------------------ +-- Package Name: memlib +-- Description: Basic memory components: single/dual port synchronous and +-- asynchronus rams; Fifo's. +-- +-- Dependencies: - +-- Tool versions: xst 8.1, 8.2, 9.1, 9.2; ghdl 0.18-0.25 +-- Revision History: +-- Date Rev Version Comment +-- 2008-03-08 123 1.0.3 add ram_2swsr_xfirst_gen_unisim +-- 2008-03-02 122 1.0.2 change generic default for BRAM models +-- 2007-12-27 106 1.0.1 add fifo_2c_dram +-- 2007-06-03 45 1.0 Initial version +------------------------------------------------------------------------------ + +library ieee; +use ieee.std_logic_1164.all; + +use work.slvtypes.all; + +package memlib is + +component ram_1swar_gen is -- RAM, 1 sync w asyn r port + generic ( + AWIDTH : positive := 4; -- address port width + DWIDTH : positive := 16); -- data port width + port ( + CLK : in slbit; -- clock + WE : in slbit; -- write enable + ADDR : in slv(AWIDTH-1 downto 0); -- address port + DI : in slv(DWIDTH-1 downto 0); -- data in port + DO : out slv(DWIDTH-1 downto 0) -- data out port + ); +end component; + +component ram_1swar_1ar_gen is -- RAM, 1 sync w asyn r + 1 asyn r port + generic ( + AWIDTH : positive := 4; -- address port width + DWIDTH : positive := 16); -- data port width + port ( + CLK : in slbit; -- clock + WE : in slbit; -- write enable (port A) + ADDRA : in slv(AWIDTH-1 downto 0); -- address port A + ADDRB : in slv(AWIDTH-1 downto 0); -- address port B + DI : in slv(DWIDTH-1 downto 0); -- data in (port A) + DOA : out slv(DWIDTH-1 downto 0); -- data out port A + DOB : out slv(DWIDTH-1 downto 0) -- data out port B + ); +end component; + +component ram_1swsr_wfirst_gen is -- RAM, 1 sync r/w ports, write first + generic ( + AWIDTH : positive := 10; -- address port width + DWIDTH : positive := 16); -- data port width + port( + CLK : in slbit; -- clock + EN : in slbit; -- enable + WE : in slbit; -- write enable + ADDR : in slv(AWIDTH-1 downto 0); -- address port + DI : in slv(DWIDTH-1 downto 0); -- data in port + DO : out slv(DWIDTH-1 downto 0) -- data out port + ); +end component; + +component ram_1swsr_rfirst_gen is -- RAM, 1 sync r/w ports, read first + generic ( + AWIDTH : positive := 11; -- address port width + DWIDTH : positive := 9); -- data port width + port( + CLK : in slbit; -- clock + EN : in slbit; -- enable + WE : in slbit; -- write enable + ADDR : in slv(AWIDTH-1 downto 0); -- address port + DI : in slv(DWIDTH-1 downto 0); -- data in port + DO : out slv(DWIDTH-1 downto 0) -- data out port + ); +end component; + +component ram_2swsr_wfirst_gen is -- RAM, 2 sync r/w ports, write first + generic ( + AWIDTH : positive := 11; -- address port width + DWIDTH : positive := 9); -- data port width + port( + CLKA : in slbit; -- clock port A + CLKB : in slbit; -- clock port B + ENA : in slbit; -- enable port A + ENB : in slbit; -- enable port B + WEA : in slbit; -- write enable port A + WEB : in slbit; -- write enable port B + ADDRA : in slv(AWIDTH-1 downto 0); -- address port A + ADDRB : in slv(AWIDTH-1 downto 0); -- address port B + DIA : in slv(DWIDTH-1 downto 0); -- data in port A + DIB : in slv(DWIDTH-1 downto 0); -- data in port B + DOA : out slv(DWIDTH-1 downto 0); -- data out port A + DOB : out slv(DWIDTH-1 downto 0) -- data out port B + ); +end component; + +component ram_2swsr_rfirst_gen is -- RAM, 2 sync r/w ports, read first + generic ( + AWIDTH : positive := 11; -- address port width + DWIDTH : positive := 9); -- data port width + port( + CLKA : in slbit; -- clock port A + CLKB : in slbit; -- clock port B + ENA : in slbit; -- enable port A + ENB : in slbit; -- enable port B + WEA : in slbit; -- write enable port A + WEB : in slbit; -- write enable port B + ADDRA : in slv(AWIDTH-1 downto 0); -- address port A + ADDRB : in slv(AWIDTH-1 downto 0); -- address port B + DIA : in slv(DWIDTH-1 downto 0); -- data in port A + DIB : in slv(DWIDTH-1 downto 0); -- data in port B + DOA : out slv(DWIDTH-1 downto 0); -- data out port A + DOB : out slv(DWIDTH-1 downto 0) -- data out port B + ); +end component; + +component ram_1swsr_xfirst_gen_unisim is -- RAM, 1 sync r/w port + generic ( + AWIDTH : positive := 11; -- address port width + DWIDTH : positive := 9; -- data port width + WRITE_MODE : string := "READ_FIRST"); -- write mode: (READ|WRITE)_FIRST + port( + CLK : in slbit; -- clock + EN : in slbit; -- enable + WE : in slbit; -- write enable + ADDR : in slv(AWIDTH-1 downto 0); -- address + DI : in slv(DWIDTH-1 downto 0); -- data in + DO : out slv(DWIDTH-1 downto 0) -- data out + ); +end component; + +component ram_2swsr_xfirst_gen_unisim is -- RAM, 2 sync r/w ports + generic ( + AWIDTH : positive := 11; -- address port width + DWIDTH : positive := 9; -- data port width + WRITE_MODE : string := "READ_FIRST"); -- write mode: (READ|WRITE)_FIRST + port( + CLKA : in slbit; -- clock port A + CLKB : in slbit; -- clock port B + ENA : in slbit; -- enable port A + ENB : in slbit; -- enable port B + WEA : in slbit; -- write enable port A + WEB : in slbit; -- write enable port B + ADDRA : in slv(AWIDTH-1 downto 0); -- address port A + ADDRB : in slv(AWIDTH-1 downto 0); -- address port B + DIA : in slv(DWIDTH-1 downto 0); -- data in port A + DIB : in slv(DWIDTH-1 downto 0); -- data in port B + DOA : out slv(DWIDTH-1 downto 0); -- data out port A + DOB : out slv(DWIDTH-1 downto 0) -- data out port B + ); +end component; + +component fifo_1c_dram_raw is -- fifo, 1 clock, dram based, raw + generic ( + AWIDTH : positive := 4; -- address width (sets size) + DWIDTH : positive := 16); -- data width + port ( + CLK : in slbit; -- clock + RESET : in slbit; -- reset + WE : in slbit; -- write enable + RE : in slbit; -- read enable + DI : in slv(DWIDTH-1 downto 0); -- input data + DO : out slv(DWIDTH-1 downto 0); -- output data + SIZE : out slv(AWIDTH-1 downto 0); -- number of used slots + EMPTY : out slbit; -- empty flag + FULL : out slbit -- full flag + ); +end component; + +component fifo_1c_dram is -- fifo, 1 clock, dram based + generic ( + AWIDTH : positive := 4; -- address width (sets size) + DWIDTH : positive := 16); -- data width + port ( + CLK : in slbit; -- clock + RESET : in slbit; -- reset + DI : in slv(DWIDTH-1 downto 0); -- input data + ENA : in slbit; -- write enable + BUSY : out slbit; -- write port hold + DO : out slv(DWIDTH-1 downto 0); -- output data + VAL : out slbit; -- read valid + HOLD : in slbit; -- read hold + SIZE : out slv(AWIDTH downto 0) -- number of used slots + ); +end component; + +component fifo_1c_bubble is -- fifo, 1 clock, bubble regs + generic ( + NSTAGE : positive := 4; -- number of stages + DWIDTH : positive := 16); -- data width + port ( + CLK : in slbit; -- clock + RESET : in slbit; -- reset + DI : in slv(DWIDTH-1 downto 0); -- input data + ENA : in slbit; -- write enable + BUSY : out slbit; -- write port hold + DO : out slv(DWIDTH-1 downto 0); -- output data + VAL : out slbit; -- read valid + HOLD : in slbit -- read hold + ); +end component; + +component fifo_2c_dram is -- fifo, 2 clock, dram based + generic ( + AWIDTH : positive := 4; -- address width (sets size) + DWIDTH : positive := 16); -- data width + port ( + CLKW : in slbit; -- clock (write side) + CLKR : in slbit; -- clock (read side) + RESETW : in slbit; -- reset (synchronous with CLKW) + RESETR : in slbit; -- reset (synchronous with CLKR) + DI : in slv(DWIDTH-1 downto 0); -- input data + ENA : in slbit; -- write enable + BUSY : out slbit; -- write port hold + DO : out slv(DWIDTH-1 downto 0); -- output data + VAL : out slbit; -- read valid + HOLD : in slbit; -- read hold + SIZEW : out slv(AWIDTH-1 downto 0); -- number slots to write (synch w/ CLKW) + SIZER : out slv(AWIDTH-1 downto 0) -- number slots to read (synch w/ CLKR) + ); +end component; + +end memlib; diff --git a/rtl/vlib/memlib/ram_1swar_1ar_gen.vbom b/rtl/vlib/memlib/ram_1swar_1ar_gen.vbom new file mode 100644 index 00000000..e64a1989 --- /dev/null +++ b/rtl/vlib/memlib/ram_1swar_1ar_gen.vbom @@ -0,0 +1,4 @@ +# libs +../slvtypes.vhd +# design +ram_1swar_1ar_gen.vhd diff --git a/rtl/vlib/memlib/ram_1swar_1ar_gen.vhd b/rtl/vlib/memlib/ram_1swar_1ar_gen.vhd new file mode 100644 index 00000000..ae7458f2 --- /dev/null +++ b/rtl/vlib/memlib/ram_1swar_1ar_gen.vhd @@ -0,0 +1,88 @@ +-- $Id: ram_1swar_1ar_gen.vhd 314 2010-07-09 17:38:41Z mueller $ +-- +-- Copyright 2006-2008 by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, 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 complete details. +-- +------------------------------------------------------------------------------ +-- Module Name: ram_1swar_1ar_gen - syn +-- Description: Dual-Port RAM with with one synchronous write and two +-- asynchronius read ports (as distributed RAM). +-- The code is inspired by Xilinx example rams_09.vhd. The +-- 'ram_style' attribute is set to 'distributed', this will +-- force in XST a synthesis as distributed RAM. +-- +-- Dependencies: - +-- Test bench: - +-- Target Devices: generic Spartan, Virtex +-- Tool versions: xst 8.1, 8.2, 9.1, 9.2; ghdl 0.18-0.25 +-- Revision History: +-- Date Rev Version Comment +-- 2008-03-08 123 1.0.1 use std_logic_arith, not _unsigned; use unsigned() +-- 2007-06-03 45 1.0 Initial version +-- +-- Some synthesis results: +-- - 2010-06-03 ise 11.4 for xc3s1000-ft256-4: +-- AWIDTH DWIDTH LUTl LUTm Comments +-- 4 16 - 32 16*RAM16X1D +-- 5 16 34 64 32*RAM16X1D +-- 6 16 68 128 64*RAM16X1D, 32*MUXF5 +-- 7 16 136 256 128*RAM16X1D, 64*MUXF5, 32*MUXF6 +-- 8 16 292 512 256*RAM16X1D,144*MUXF5, 64*MUXF6, 32*MUXF7 +-- - 2007-12-31 ise 8.2.03 for xc3s1000-ft256-4: +-- {same results as above for AW=4 and 6} +------------------------------------------------------------------------------ + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; + +use work.slvtypes.all; + +entity ram_1swar_1ar_gen is -- RAM, 1 sync w asyn r + 1 asyn r port + generic ( + AWIDTH : positive := 4; -- address port width + DWIDTH : positive := 16); -- data port width + port ( + CLK : in slbit; -- clock + WE : in slbit; -- write enable (port A) + ADDRA : in slv(AWIDTH-1 downto 0); -- address port A + ADDRB : in slv(AWIDTH-1 downto 0); -- address port B + DI : in slv(DWIDTH-1 downto 0); -- data in (port A) + DOA : out slv(DWIDTH-1 downto 0); -- data out port A + DOB : out slv(DWIDTH-1 downto 0) -- data out port B + ); +end ram_1swar_1ar_gen; + + +architecture syn of ram_1swar_1ar_gen is + constant memsize : positive := 2**AWIDTH; + constant datzero : slv(DWIDTH-1 downto 0) := (others=>'0'); + type ram_type is array (memsize-1 downto 0) of slv (DWIDTH-1 downto 0); + signal RAM : ram_type := (others=>datzero); + + attribute ram_style : string; + attribute ram_style of RAM : signal is "distributed"; + +begin + + proc_clk: process (CLK) + begin + if CLK'event and CLK='1' then + if WE = '1' then + RAM(conv_integer(unsigned(ADDRA))) <= DI; + end if; + end if; + end process proc_clk; + + DOA <= RAM(conv_integer(unsigned(ADDRA))); + DOB <= RAM(conv_integer(unsigned(ADDRB))); + +end syn; diff --git a/rtl/vlib/memlib/ram_1swar_1ar_gen_unisim.vbom b/rtl/vlib/memlib/ram_1swar_1ar_gen_unisim.vbom new file mode 100644 index 00000000..1ae4791b --- /dev/null +++ b/rtl/vlib/memlib/ram_1swar_1ar_gen_unisim.vbom @@ -0,0 +1,5 @@ +# libs +../slvtypes.vhd +@lib:unisim +# design +ram_1swar_1ar_gen_unisim.vhd diff --git a/rtl/vlib/memlib/ram_1swar_1ar_gen_unisim.vhd b/rtl/vlib/memlib/ram_1swar_1ar_gen_unisim.vhd new file mode 100644 index 00000000..1f29f14b --- /dev/null +++ b/rtl/vlib/memlib/ram_1swar_1ar_gen_unisim.vhd @@ -0,0 +1,170 @@ +-- $Id: ram_1swar_1ar_gen_unisim.vhd 314 2010-07-09 17:38:41Z mueller $ +-- +-- Copyright 2008-2010 by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, 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 complete details. +-- +------------------------------------------------------------------------------ +-- Module Name: ram_1swar_1ar_gen - syn +-- Description: Dual-Port RAM with with one synchronous write and two +-- asynchronius read ports (as distributed RAM). +-- Direct instantiation of Xilinx UNISIM primitives +-- +-- Dependencies: - +-- Test bench: - +-- Target Devices: generic Spartan, Virtex +-- Tool versions: xst 8.1, 8.2, 9.1, 9.2; ghdl 0.18-0.25 +-- Revision History: +-- Date Rev Version Comment +-- 2010-06-03 300 1.1 add hack for AW=5 for Spartan's +-- 2008-03-08 123 1.0.1 use shorter label names +-- 2008-03-02 122 1.0 Initial version +------------------------------------------------------------------------------ + +library ieee; +use ieee.std_logic_1164.all; + +library unisim; +use unisim.vcomponents.ALL; + +use work.slvtypes.all; + +entity ram_1swar_1ar_gen is -- RAM, 1 sync w asyn r + 1 asyn r port + generic ( + AWIDTH : positive := 4; -- address port width + DWIDTH : positive := 16); -- data port width + port ( + CLK : in slbit; -- clock + WE : in slbit; -- write enable (port A) + ADDRA : in slv(AWIDTH-1 downto 0); -- address port A + ADDRB : in slv(AWIDTH-1 downto 0); -- address port B + DI : in slv(DWIDTH-1 downto 0); -- data in (port A) + DOA : out slv(DWIDTH-1 downto 0); -- data out port A + DOB : out slv(DWIDTH-1 downto 0) -- data out port B + ); +end ram_1swar_1ar_gen; + + +architecture syn of ram_1swar_1ar_gen is + +begin + + assert AWIDTH>=4 and AWIDTH<=5 + report "assert(AWIDTH>=4 and AWIDTH<=5): only 4..5 bit AWIDTH supported" + severity failure; + + AW_4: if AWIDTH = 4 generate + GL: for i in DWIDTH-1 downto 0 generate + MEM : RAM16X1D + generic map ( + INIT => X"0000") + port map ( + DPO => DOB(i), + SPO => DOA(i), + A0 => ADDRA(0), + A1 => ADDRA(1), + A2 => ADDRA(2), + A3 => ADDRA(3), + D => DI(i), + DPRA0 => ADDRB(0), + DPRA1 => ADDRB(1), + DPRA2 => ADDRB(2), + DPRA3 => ADDRB(3), + WCLK => CLK, + WE => WE + ); + end generate GL; + end generate AW_4; + + -- Note: Spartan-3 doesn't support RAM32X1D, therefore this kludge.. + AW_5: if AWIDTH = 5 generate + signal WE0 : slbit := '0'; + signal WE1 : slbit := '0'; + signal DOA0 : slv(DWIDTH-1 downto 0) := (others=>'0'); + signal DOA1 : slv(DWIDTH-1 downto 0) := (others=>'0'); + signal DOB0 : slv(DWIDTH-1 downto 0) := (others=>'0'); + signal DOB1 : slv(DWIDTH-1 downto 0) := (others=>'0'); + begin + WE0 <= WE and not ADDRA(4); + WE1 <= WE and ADDRA(4); + GL: for i in DWIDTH-1 downto 0 generate + MEM0 : RAM16X1D + generic map ( + INIT => X"0000") + port map ( + DPO => DOB0(i), + SPO => DOA0(i), + A0 => ADDRA(0), + A1 => ADDRA(1), + A2 => ADDRA(2), + A3 => ADDRA(3), + D => DI(i), + DPRA0 => ADDRB(0), + DPRA1 => ADDRB(1), + DPRA2 => ADDRB(2), + DPRA3 => ADDRB(3), + WCLK => CLK, + WE => WE0 + ); + MEM1 : RAM16X1D + generic map ( + INIT => X"0000") + port map ( + DPO => DOB1(i), + SPO => DOA1(i), + A0 => ADDRA(0), + A1 => ADDRA(1), + A2 => ADDRA(2), + A3 => ADDRA(3), + D => DI(i), + DPRA0 => ADDRB(0), + DPRA1 => ADDRB(1), + DPRA2 => ADDRB(2), + DPRA3 => ADDRB(3), + WCLK => CLK, + WE => WE1 + ); + DOA <= DOA0 when ADDRA(4)='0' else DOA1; + DOB <= DOB0 when ADDRB(4)='0' else DOB1; + end generate GL; + end generate AW_5; + +-- AW_6: if AWIDTH = 6 generate +-- GL: for i in DWIDTH-1 downto 0 generate +-- MEM : RAM64X1D +-- generic map ( +-- INIT => X"0000000000000000") +-- port map ( +-- DPO => DOB(i), +-- SPO => DOA(i), +-- A0 => ADDRA(0), +-- A1 => ADDRA(1), +-- A2 => ADDRA(2), +-- A3 => ADDRA(3), +-- A4 => ADDRA(4), +-- A5 => ADDRA(5), +-- D => DI(i), +-- DPRA0 => ADDRB(0), +-- DPRA1 => ADDRB(1), +-- DPRA2 => ADDRB(2), +-- DPRA3 => ADDRB(3), +-- DPRA4 => ADDRB(4), +-- DPRA5 => ADDRB(5), +-- WCLK => CLK, +-- WE => WE +-- ); +-- end generate GL; +-- end generate AW_6; + +end syn; + +-- Note: The VHDL instantiation example in the 8.1i Librariers Guide is wrong. +-- The annotation states that DPO is the port A output and SPO is port B +-- output. The text before is correct, DPO is port B and SPO is port A. diff --git a/rtl/vlib/memlib/ram_1swar_gen.vbom b/rtl/vlib/memlib/ram_1swar_gen.vbom new file mode 100644 index 00000000..50e7fe92 --- /dev/null +++ b/rtl/vlib/memlib/ram_1swar_gen.vbom @@ -0,0 +1,4 @@ +# libs +../slvtypes.vhd +# design +ram_1swar_gen.vhd diff --git a/rtl/vlib/memlib/ram_1swar_gen.vhd b/rtl/vlib/memlib/ram_1swar_gen.vhd new file mode 100644 index 00000000..6db9eeb1 --- /dev/null +++ b/rtl/vlib/memlib/ram_1swar_gen.vhd @@ -0,0 +1,81 @@ +-- $Id: ram_1swar_gen.vhd 314 2010-07-09 17:38:41Z mueller $ +-- +-- Copyright 2006-2008 by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, 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 complete details. +-- +------------------------------------------------------------------------------ +-- Module Name: ram_1swar_gen - syn +-- Description: Single-Port RAM with with one synchronous write and one +-- asynchronius read port (as distributed RAM). +-- The code is inspired by Xilinx example rams_04.vhd. The +-- 'ram_style' attribute is set to 'distributed', this will +-- force in XST a synthesis as distributed RAM. +-- +-- Dependencies: - +-- Test bench: - +-- Target Devices: generic Spartan, Virtex +-- Tool versions: xst 8.1, 8.2, 9.1, 9.2; ghdl 0.18-0.25 +-- Revision History: +-- Date Rev Version Comment +-- 2008-03-08 123 1.0.1 use std_logic_arith, not _unsigned; use unsigned() +-- 2007-06-03 45 1.0 Initial version +-- +-- Some synthesis results: +-- - 2007-12-31 ise 8.2.03 for xc3s1000-ft256-4: +-- AWIDTH DWIDTH LUTl LUTm Comments +-- 4 16 - 16 16*RAM16X1S +-- 5 16 - 32 16*RAM32X1S +-- 6 16 18 64 32*RAM32X1S Note: A(4) via F5MUX, A(5) via LUT +------------------------------------------------------------------------------ + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; + +use work.slvtypes.all; + +entity ram_1swar_gen is -- RAM, 1 sync w asyn r port + generic ( + AWIDTH : positive := 4; -- address port width + DWIDTH : positive := 16); -- data port width + port ( + CLK : in slbit; -- clock + WE : in slbit; -- write enable + ADDR : in slv(AWIDTH-1 downto 0); -- address port + DI : in slv(DWIDTH-1 downto 0); -- data in port + DO : out slv(DWIDTH-1 downto 0) -- data out port + ); +end ram_1swar_gen; + + +architecture syn of ram_1swar_gen is + constant memsize : positive := 2**AWIDTH; + constant datzero : slv(DWIDTH-1 downto 0) := (others=>'0'); + type ram_type is array (memsize-1 downto 0) of slv (DWIDTH-1 downto 0); + signal RAM : ram_type := (others=>datzero); + + attribute ram_style : string; + attribute ram_style of RAM : signal is "distributed"; + +begin + + proc_clk: process (CLK) + begin + if CLK'event and CLK='1' then + if WE = '1' then + RAM(conv_integer(unsigned(ADDR))) <= DI; + end if; + end if; + end process proc_clk; + + DO <= RAM(conv_integer(unsigned(ADDR))); + +end syn; diff --git a/rtl/vlib/memlib/ram_1swar_gen_unisim.vbom b/rtl/vlib/memlib/ram_1swar_gen_unisim.vbom new file mode 100644 index 00000000..549799a4 --- /dev/null +++ b/rtl/vlib/memlib/ram_1swar_gen_unisim.vbom @@ -0,0 +1,5 @@ +# libs +../slvtypes.vhd +@lib:unisim +# design +ram_1swar_gen_unisim.vhd diff --git a/rtl/vlib/memlib/ram_1swar_gen_unisim.vhd b/rtl/vlib/memlib/ram_1swar_gen_unisim.vhd new file mode 100644 index 00000000..4e46c80c --- /dev/null +++ b/rtl/vlib/memlib/ram_1swar_gen_unisim.vhd @@ -0,0 +1,118 @@ +-- $Id: ram_1swar_gen_unisim.vhd 314 2010-07-09 17:38:41Z mueller $ +-- +-- Copyright 2008- by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, 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 complete details. +-- +------------------------------------------------------------------------------ +-- Module Name: ram_1swar_gen_unisim - syn +-- Description: Single-Port RAM with with one synchronous write and one +-- asynchronius read port (as distributed RAM). +-- Direct instantiation of Xilinx UNISIM primitives +-- +-- Dependencies: - +-- Test bench: - +-- Target Devices: generic Spartan, Virtex +-- Tool versions: xst 8.1, 8.2, 9.1, 9.2; ghdl 0.18-0.25 +-- Revision History: +-- Date Rev Version Comment +-- 2008-03-08 123 1.0.1 use shorter label names +-- 2008-03-02 122 1.0 Initial version +-- +------------------------------------------------------------------------------ + +library ieee; +use ieee.std_logic_1164.all; + +library unisim; +use unisim.vcomponents.ALL; + +use work.slvtypes.all; + +entity ram_1swar_gen is -- RAM, 1 sync w asyn r port + generic ( + AWIDTH : positive := 4; -- address port width + DWIDTH : positive := 16); -- data port width + port ( + CLK : in slbit; -- clock + WE : in slbit; -- write enable + ADDR : in slv(AWIDTH-1 downto 0); -- address port + DI : in slv(DWIDTH-1 downto 0); -- data in port + DO : out slv(DWIDTH-1 downto 0) -- data out port + ); +end ram_1swar_gen; + + +architecture syn of ram_1swar_gen is + +begin + + assert AWIDTH>=4 and AWIDTH<=6 + report "assert(AWIDTH>=4 and AWIDTH<=6): only 4..6 bit AWIDTH supported" + severity failure; + + AW_4: if AWIDTH = 4 generate + GL: for i in DWIDTH-1 downto 0 generate + MEM : RAM16X1S + generic map ( + INIT => X"0000") + port map ( + O => DO(i), + A0 => ADDR(0), + A1 => ADDR(1), + A2 => ADDR(2), + A3 => ADDR(3), + D => DI(i), + WCLK => CLK, + WE => WE + ); + end generate GL; + end generate AW_4; + + AW_5: if AWIDTH = 5 generate + GL: for i in DWIDTH-1 downto 0 generate + MEM : RAM32X1S + generic map ( + INIT => X"00000000") + port map ( + O => DO(i), + A0 => ADDR(0), + A1 => ADDR(1), + A2 => ADDR(2), + A3 => ADDR(3), + A4 => ADDR(4), + D => DI(i), + WCLK => CLK, + WE => WE + ); + end generate GL; + end generate AW_5; + + AW_6: if AWIDTH = 6 generate + GL: for i in DWIDTH-1 downto 0 generate + MEM : RAM64X1S + generic map ( + INIT => X"0000000000000000") + port map ( + O => DO(i), + A0 => ADDR(0), + A1 => ADDR(1), + A2 => ADDR(2), + A3 => ADDR(3), + A4 => ADDR(4), + A5 => ADDR(5), + D => DI(i), + WCLK => CLK, + WE => WE + ); + end generate GL; + end generate AW_6; + +end syn; diff --git a/rtl/vlib/memlib/ram_2swsr_rfirst_gen.vbom b/rtl/vlib/memlib/ram_2swsr_rfirst_gen.vbom new file mode 100644 index 00000000..1c9672ca --- /dev/null +++ b/rtl/vlib/memlib/ram_2swsr_rfirst_gen.vbom @@ -0,0 +1,4 @@ +# libs +../slvtypes.vhd +# design +ram_2swsr_rfirst_gen.vhd diff --git a/rtl/vlib/memlib/ram_2swsr_rfirst_gen.vhd b/rtl/vlib/memlib/ram_2swsr_rfirst_gen.vhd new file mode 100644 index 00000000..2ed3244f --- /dev/null +++ b/rtl/vlib/memlib/ram_2swsr_rfirst_gen.vhd @@ -0,0 +1,103 @@ +-- $Id: ram_2swsr_rfirst_gen.vhd 314 2010-07-09 17:38:41Z mueller $ +-- +-- Copyright 2006-2010 by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, 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 complete details. +-- +------------------------------------------------------------------------------ +-- Module Name: ram_2swsr_rfirst_gen - syn +-- Description: Dual-Port RAM with with two synchronous read/write ports +-- and 'read-before-write' semantics (as block RAM). +-- The code is inspired by Xilinx example rams_16.vhd. The +-- 'ram_style' attribute is set to 'block', this will +-- force in XST a synthesis as block RAM. +-- +-- Dependencies: - +-- Test bench: - +-- Target Devices: generic Spartan, Virtex +-- Tool versions: xst 8.1, 8.2, 9.1, 9.2; ghdl 0.18-0.25 +-- Revision History: +-- Date Rev Version Comment +-- 2010-06-03 299 1.0.3 use sv_ prefix for shared variables +-- 2008-03-08 123 1.0.2 use std_logic_arith, not _unsigned; use unsigned(); +-- now initialize DO to all '0' at start +-- 2008-03-02 122 1.0.1 change generic default for BRAM models +-- 2007-06-03 45 1.0 Initial version +------------------------------------------------------------------------------ + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; + +use work.slvtypes.all; + +entity ram_2swsr_rfirst_gen is -- RAM, 2 sync r/w ports, read first + generic ( + AWIDTH : positive := 11; -- address port width + DWIDTH : positive := 9); -- data port width + port( + CLKA : in slbit; -- clock port A + CLKB : in slbit; -- clock port B + ENA : in slbit; -- enable port A + ENB : in slbit; -- enable port B + WEA : in slbit; -- write enable port A + WEB : in slbit; -- write enable port B + ADDRA : in slv(AWIDTH-1 downto 0); -- address port A + ADDRB : in slv(AWIDTH-1 downto 0); -- address port B + DIA : in slv(DWIDTH-1 downto 0); -- data in port A + DIB : in slv(DWIDTH-1 downto 0); -- data in port B + DOA : out slv(DWIDTH-1 downto 0); -- data out port A + DOB : out slv(DWIDTH-1 downto 0) -- data out port B + ); +end ram_2swsr_rfirst_gen; + + +architecture syn of ram_2swsr_rfirst_gen is + constant memsize : positive := 2**AWIDTH; + constant datzero : slv(DWIDTH-1 downto 0) := (others=>'0'); + type ram_type is array (0 to memsize-1) of slv(DWIDTH-1 downto 0); + shared variable sv_ram : ram_type := (others=>datzero); + + attribute ram_style : string; + attribute ram_style of sv_ram : variable is "block"; + + signal R_DOA : slv(DWIDTH-1 downto 0) := datzero; + signal R_DOB : slv(DWIDTH-1 downto 0) := datzero; + +begin + + proc_clka: process (CLKA) + begin + if CLKA'event and CLKA='1' then + if ENA = '1' then + R_DOA <= sv_ram(conv_integer(unsigned(ADDRA))); + if WEA = '1' then + sv_ram(conv_integer(unsigned(ADDRA))) := DIA; + end if; + end if; + end if; + end process proc_clka; + + proc_clkb: process (CLKB) + begin + if CLKB'event and CLKB='1' then + if ENB = '1' then + R_DOB <= sv_ram(conv_integer(unsigned(ADDRB))); + if WEB = '1' then + sv_ram(conv_integer(unsigned(ADDRB))) := DIB; + end if; + end if; + end if; + end process proc_clkb; + + DOA <= R_DOA; + DOB <= R_DOB; + +end syn; diff --git a/rtl/vlib/memlib/ram_2swsr_rfirst_gen_unisim.vbom b/rtl/vlib/memlib/ram_2swsr_rfirst_gen_unisim.vbom new file mode 100644 index 00000000..bee9bc98 --- /dev/null +++ b/rtl/vlib/memlib/ram_2swsr_rfirst_gen_unisim.vbom @@ -0,0 +1,7 @@ +# libs +../slvtypes.vhd +memlib.vhd +# components +ram_2swsr_xfirst_gen_unisim.vbom +# design +ram_2swsr_rfirst_gen_unisim.vhd diff --git a/rtl/vlib/memlib/ram_2swsr_rfirst_gen_unisim.vhd b/rtl/vlib/memlib/ram_2swsr_rfirst_gen_unisim.vhd new file mode 100644 index 00000000..7cfbff1b --- /dev/null +++ b/rtl/vlib/memlib/ram_2swsr_rfirst_gen_unisim.vhd @@ -0,0 +1,83 @@ +-- $Id: ram_2swsr_rfirst_gen_unisim.vhd 314 2010-07-09 17:38:41Z mueller $ +-- +-- Copyright 2008- by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, 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 complete details. +-- +------------------------------------------------------------------------------ +-- Module Name: ram_2swsr_rfirst_gen - syn +-- Description: Dual-Port RAM with with two synchronous read/write ports +-- and 'read-before-write' semantics (as block RAM). +-- Direct instantiation of Xilinx UNISIM primitives +-- +-- Dependencies: - +-- Test bench: - +-- Target Devices: Spartan-3, Virtex-2,-4 +-- Tool versions: xst 8.1, 8.2, 9.1, 9.2; ghdl 0.18-0.25 +-- Revision History: +-- Date Rev Version Comment +-- 2008-03-08 123 1.1 use now ram_2swsr_xfirst_gen_unisim +-- 2008-03-02 122 1.0 Initial version +------------------------------------------------------------------------------ + +library ieee; +use ieee.std_logic_1164.all; + +library unisim; +use unisim.vcomponents.ALL; + +use work.slvtypes.all; +use work.memlib.all; + +entity ram_2swsr_rfirst_gen is -- RAM, 2 sync r/w ports, read first + generic ( + AWIDTH : positive := 13; -- address port width 11/9 or 13/8 + DWIDTH : positive := 8); -- data port width + port( + CLKA : in slbit; -- clock port A + CLKB : in slbit; -- clock port B + ENA : in slbit; -- enable port A + ENB : in slbit; -- enable port B + WEA : in slbit; -- write enable port A + WEB : in slbit; -- write enable port B + ADDRA : in slv(AWIDTH-1 downto 0); -- address port A + ADDRB : in slv(AWIDTH-1 downto 0); -- address port B + DIA : in slv(DWIDTH-1 downto 0); -- data in port A + DIB : in slv(DWIDTH-1 downto 0); -- data in port B + DOA : out slv(DWIDTH-1 downto 0); -- data out port A + DOB : out slv(DWIDTH-1 downto 0) -- data out port B + ); +end ram_2swsr_rfirst_gen; + + +architecture syn of ram_2swsr_rfirst_gen is +begin + + UMEM: ram_2swsr_xfirst_gen_unisim + generic map ( + AWIDTH => AWIDTH, + DWIDTH => DWIDTH, + WRITE_MODE => "READ_FIRST") + port map ( + CLKA => CLKA, + CLKB => CLKB, + ENA => ENA, + ENB => ENB, + WEA => WEA, + WEB => WEB, + ADDRA => ADDRA, + ADDRB => ADDRB, + DIA => DIA, + DIB => DIB, + DOA => DOA, + DOB => DOB + ); + +end syn; diff --git a/rtl/vlib/memlib/ram_2swsr_xfirst_gen_unisim.vbom b/rtl/vlib/memlib/ram_2swsr_xfirst_gen_unisim.vbom new file mode 100644 index 00000000..cc5efd56 --- /dev/null +++ b/rtl/vlib/memlib/ram_2swsr_xfirst_gen_unisim.vbom @@ -0,0 +1,5 @@ +# libs +../slvtypes.vhd +@lib:unisim +# design +ram_2swsr_xfirst_gen_unisim.vhd diff --git a/rtl/vlib/memlib/ram_2swsr_xfirst_gen_unisim.vhd b/rtl/vlib/memlib/ram_2swsr_xfirst_gen_unisim.vhd new file mode 100644 index 00000000..c341b606 --- /dev/null +++ b/rtl/vlib/memlib/ram_2swsr_xfirst_gen_unisim.vhd @@ -0,0 +1,435 @@ +-- $Id: ram_2swsr_xfirst_gen_unisim.vhd 314 2010-07-09 17:38:41Z mueller $ +-- +-- Copyright 2008- by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, 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 complete details. +-- +------------------------------------------------------------------------------ +-- Module Name: ram_2swsr_xfirst_gen_unisim - syn +-- Description: Dual-Port RAM with with two synchronous read/write ports +-- Direct instantiation of Xilinx UNISIM primitives +-- +-- Dependencies: - +-- Test bench: - +-- Target Devices: Spartan-3, Virtex-2,-4 +-- Tool versions: xst 8.1, 8.2, 9.1, 9.2; ghdl 0.18-0.25 +-- Revision History: +-- Date Rev Version Comment +-- 2008-04-13 135 1.0.1 fix range error for AW_14_S1 +-- 2008-03-08 123 1.0 Initial version (merged from _rfirst/_wfirst) +------------------------------------------------------------------------------ + +library ieee; +use ieee.std_logic_1164.all; + +library unisim; +use unisim.vcomponents.ALL; + +use work.slvtypes.all; + +entity ram_2swsr_xfirst_gen_unisim is -- RAM, 2 sync r/w ports + generic ( + AWIDTH : positive := 11; -- address port width + DWIDTH : positive := 9; -- data port width + WRITE_MODE : string := "READ_FIRST"); -- write mode: (READ|WRITE)_FIRST + port( + CLKA : in slbit; -- clock port A + CLKB : in slbit; -- clock port B + ENA : in slbit; -- enable port A + ENB : in slbit; -- enable port B + WEA : in slbit; -- write enable port A + WEB : in slbit; -- write enable port B + ADDRA : in slv(AWIDTH-1 downto 0); -- address port A + ADDRB : in slv(AWIDTH-1 downto 0); -- address port B + DIA : in slv(DWIDTH-1 downto 0); -- data in port A + DIB : in slv(DWIDTH-1 downto 0); -- data in port B + DOA : out slv(DWIDTH-1 downto 0); -- data out port A + DOB : out slv(DWIDTH-1 downto 0) -- data out port B + ); +end ram_2swsr_xfirst_gen_unisim; + + +architecture syn of ram_2swsr_xfirst_gen_unisim is + + constant ok_mod32 : boolean := (DWIDTH mod 32)=0 and + ((DWIDTH+35)/36)=((DWIDTH+31)/32); + constant ok_mod16 : boolean := (DWIDTH mod 16)=0 and + ((DWIDTH+17)/18)=((DWIDTH+16)/16); + constant ok_mod08 : boolean := (DWIDTH mod 32)=0 and + ((DWIDTH+8)/9)=((DWIDTH+7)/8); + +begin + + assert AWIDTH>=9 and AWIDTH<=14 + report "assert(AWIDTH>=9 and AWIDTH<=14): unsupported BRAM from factor" + severity failure; + + AW_09_S36: if AWIDTH=9 and not ok_mod32 generate + constant dw_mem : positive := ((DWIDTH+35)/36)*36; + signal L_DOA : slv(dw_mem-1 downto 0) := (others=> '0'); + signal L_DOB : slv(dw_mem-1 downto 0) := (others=> '0'); + signal L_DIA : slv(dw_mem-1 downto 0) := (others=> '0'); + signal L_DIB : slv(dw_mem-1 downto 0) := (others=> '0'); + begin + + L_DIA(DIA'range) <= DIA; + L_DIB(DIB'range) <= DIB; + + GL: for i in dw_mem/36-1 downto 0 generate + MEM : RAMB16_S36_S36 + generic map ( + INIT_A => O"000000000000", + INIT_B => O"000000000000", + SRVAL_A => O"000000000000", + SRVAL_B => O"000000000000", + WRITE_MODE_A => WRITE_MODE, + WRITE_MODE_B => WRITE_MODE) + port map ( + DOA => L_DOA(36*i+31 downto 36*i), + DOB => L_DOB(36*i+31 downto 36*i), + DOPA => L_DOA(36*i+35 downto 36*i+32), + DOPB => L_DOB(36*i+35 downto 36*i+32), + ADDRA => ADDRA, + ADDRB => ADDRB, + CLKA => CLKA, + CLKB => CLKB, + DIA => L_DIA(36*i+31 downto 36*i), + DIB => L_DIB(36*i+31 downto 36*i), + DIPA => L_DIA(36*i+35 downto 36*i+32), + DIPB => L_DIB(36*i+35 downto 36*i+32), + ENA => ENA, + ENB => ENB, + SSRA => '0', + SSRB => '0', + WEA => WEA, + WEB => WEB + ); + end generate GL; + + DOA <= L_DOA(DOA'range); + DOB <= L_DOB(DOB'range); + + end generate AW_09_S36; + + AW_09_S32: if AWIDTH=9 and ok_mod32 generate + GL: for i in DWIDTH/32-1 downto 0 generate + MEM : RAMB16_S36_S36 + generic map ( + INIT_A => X"00000000", + INIT_B => X"00000000", + SRVAL_A => X"00000000", + SRVAL_B => X"00000000", + WRITE_MODE_A => WRITE_MODE, + WRITE_MODE_B => WRITE_MODE) + port map ( + DOA => DOA(32*i+31 downto 32*i), + DOB => DOB(32*i+31 downto 32*i), + DOPA => open, + DOPB => open, + ADDRA => ADDRA, + ADDRB => ADDRB, + CLKA => CLKA, + CLKB => CLKB, + DIA => DIA(32*i+31 downto 32*i), + DIB => DIB(32*i+31 downto 32*i), + DIPA => "0000", + DIPB => "0000", + ENA => ENA, + ENB => ENB, + SSRA => '0', + SSRB => '0', + WEA => WEA, + WEB => WEB + ); + end generate GL; + end generate AW_09_S32; + + AW_10_S18: if AWIDTH=10 and not ok_mod16 generate + constant dw_mem : positive := ((DWIDTH+17)/18)*18; + signal L_DOA : slv(dw_mem-1 downto 0) := (others=> '0'); + signal L_DOB : slv(dw_mem-1 downto 0) := (others=> '0'); + signal L_DIA : slv(dw_mem-1 downto 0) := (others=> '0'); + signal L_DIB : slv(dw_mem-1 downto 0) := (others=> '0'); + begin + + L_DIA(DIA'range) <= DIA; + L_DIB(DIB'range) <= DIB; + + GL: for i in dw_mem/18-1 downto 0 generate + MEM : RAMB16_S18_S18 + generic map ( + INIT_A => O"000000", + INIT_B => O"000000", + SRVAL_A => O"000000", + SRVAL_B => O"000000", + WRITE_MODE_A => WRITE_MODE, + WRITE_MODE_B => WRITE_MODE) + port map ( + DOA => L_DOA(18*i+15 downto 18*i), + DOB => L_DOB(18*i+15 downto 18*i), + DOPA => L_DOA(18*i+17 downto 18*i+16), + DOPB => L_DOB(18*i+17 downto 18*i+16), + ADDRA => ADDRA, + ADDRB => ADDRB, + CLKA => CLKA, + CLKB => CLKB, + DIA => L_DIA(18*i+15 downto 18*i), + DIB => L_DIB(18*i+15 downto 18*i), + DIPA => L_DIA(18*i+17 downto 18*i+16), + DIPB => L_DIB(18*i+17 downto 18*i+16), + ENA => ENA, + ENB => ENB, + SSRA => '0', + SSRB => '0', + WEA => WEA, + WEB => WEB + ); + end generate GL; + + DOA <= L_DOA(DOA'range); + DOB <= L_DOB(DOB'range); + + end generate AW_10_S18; + + AW_10_S16: if AWIDTH=10 and ok_mod16 generate + GL: for i in DWIDTH/16-1 downto 0 generate + MEM : RAMB16_S18_S18 + generic map ( + INIT_A => X"0000", + INIT_B => X"0000", + SRVAL_A => X"0000", + SRVAL_B => X"0000", + WRITE_MODE_A => WRITE_MODE, + WRITE_MODE_B => WRITE_MODE) + port map ( + DOA => DOA(16*i+15 downto 16*i), + DOB => DOB(16*i+15 downto 16*i), + DOPA => open, + DOPB => open, + ADDRA => ADDRA, + ADDRB => ADDRB, + CLKA => CLKA, + CLKB => CLKB, + DIA => DIA(16*i+15 downto 16*i), + DIB => DIB(16*i+15 downto 16*i), + DIPA => "00", + DIPB => "00", + ENA => ENA, + ENB => ENB, + SSRA => '0', + SSRB => '0', + WEA => WEA, + WEB => WEB + ); + end generate GL; + end generate AW_10_S16; + + AW_11_S9: if AWIDTH=11 and not ok_mod08 generate + constant dw_mem : positive := ((DWIDTH+8)/9)*9; + signal L_DOA : slv(dw_mem-1 downto 0) := (others=> '0'); + signal L_DOB : slv(dw_mem-1 downto 0) := (others=> '0'); + signal L_DIA : slv(dw_mem-1 downto 0) := (others=> '0'); + signal L_DIB : slv(dw_mem-1 downto 0) := (others=> '0'); + begin + + L_DIA(DIA'range) <= DIA; + L_DIB(DIB'range) <= DIB; + + GL: for i in dw_mem/9-1 downto 0 generate + MEM : RAMB16_S9_S9 + generic map ( + INIT_A => O"000", + INIT_B => O"000", + SRVAL_A => O"000", + SRVAL_B => O"000", + WRITE_MODE_A => WRITE_MODE, + WRITE_MODE_B => WRITE_MODE) + port map ( + DOA => L_DOA(9*i+7 downto 9*i), + DOB => L_DOB(9*i+7 downto 9*i), + DOPA => L_DOA(9*i+8 downto 9*i+8), + DOPB => L_DOB(9*i+8 downto 9*i+8), + ADDRA => ADDRA, + ADDRB => ADDRB, + CLKA => CLKA, + CLKB => CLKB, + DIA => L_DIA(9*i+7 downto 9*i), + DIB => L_DIB(9*i+7 downto 9*i), + DIPA => L_DIA(9*i+8 downto 9*i+8), + DIPB => L_DIB(9*i+8 downto 9*i+8), + ENA => ENA, + ENB => ENB, + SSRA => '0', + SSRB => '0', + WEA => WEA, + WEB => WEB + ); + end generate GL; + + DOA <= L_DOA(DOA'range); + DOB <= L_DOB(DOB'range); + + end generate AW_11_S9; + + AW_11_S8: if AWIDTH=11 and ok_mod08 generate + GL: for i in DWIDTH/8-1 downto 0 generate + MEM : RAMB16_S9_S9 + generic map ( + INIT_A => X"00", + INIT_B => X"00", + SRVAL_A => X"00", + SRVAL_B => X"00", + WRITE_MODE_A => WRITE_MODE, + WRITE_MODE_B => WRITE_MODE) + port map ( + DOA => DOA(8*i+7 downto 8*i), + DOB => DOB(8*i+7 downto 8*i), + DOPA => open, + DOPB => open, + ADDRA => ADDRA, + ADDRB => ADDRB, + CLKA => CLKA, + CLKB => CLKB, + DIA => DIA(8*i+7 downto 8*i), + DIB => DIB(8*i+7 downto 8*i), + DIPA => "0", + DIPB => "0", + ENA => ENA, + ENB => ENB, + SSRA => '0', + SSRB => '0', + WEA => WEA, + WEB => WEB + ); + end generate GL; + end generate AW_11_S8; + + AW_12_S4: if AWIDTH = 12 generate + constant dw_mem : positive := ((DWIDTH+3)/4)*4; + signal L_DOA : slv(dw_mem-1 downto 0) := (others=> '0'); + signal L_DOB : slv(dw_mem-1 downto 0) := (others=> '0'); + signal L_DIA : slv(dw_mem-1 downto 0) := (others=> '0'); + signal L_DIB : slv(dw_mem-1 downto 0) := (others=> '0'); + begin + + L_DIA(DIA'range) <= DIA; + L_DIB(DIB'range) <= DIB; + + GL: for i in dw_mem/4-1 downto 0 generate + MEM : RAMB16_S4_S4 + generic map ( + INIT_A => X"0", + INIT_B => X"0", + SRVAL_A => X"0", + SRVAL_B => X"0", + WRITE_MODE_A => WRITE_MODE, + WRITE_MODE_B => WRITE_MODE) + port map ( + DOA => L_DOA(4*i+3 downto 4*i), + DOB => L_DOB(4*i+3 downto 4*i), + ADDRA => ADDRA, + ADDRB => ADDRB, + CLKA => CLKA, + CLKB => CLKB, + DIA => L_DIA(4*i+3 downto 4*i), + DIB => L_DIB(4*i+3 downto 4*i), + ENA => ENA, + ENB => ENB, + SSRA => '0', + SSRB => '0', + WEA => WEA, + WEB => WEB + ); + end generate GL; + + DOA <= L_DOA(DOA'range); + DOB <= L_DOB(DOB'range); + + end generate AW_12_S4; + + AW_13_S2: if AWIDTH = 13 generate + constant dw_mem : positive := ((DWIDTH+1)/2)*2; + signal L_DOA : slv(dw_mem-1 downto 0) := (others=> '0'); + signal L_DOB : slv(dw_mem-1 downto 0) := (others=> '0'); + signal L_DIA : slv(dw_mem-1 downto 0) := (others=> '0'); + signal L_DIB : slv(dw_mem-1 downto 0) := (others=> '0'); + begin + + L_DIA(DIA'range) <= DIA; + L_DIB(DIB'range) <= DIB; + + GL: for i in dw_mem/2-1 downto 0 generate + MEM : RAMB16_S2_S2 + generic map ( + INIT_A => "00", + INIT_B => "00", + SRVAL_A => "00", + SRVAL_B => "00", + WRITE_MODE_A => WRITE_MODE, + WRITE_MODE_B => WRITE_MODE) + port map ( + DOA => L_DOA(2*i+1 downto 2*i), + DOB => L_DOB(2*i+1 downto 2*i), + ADDRA => ADDRA, + ADDRB => ADDRB, + CLKA => CLKA, + CLKB => CLKB, + DIA => L_DIA(2*i+1 downto 2*i), + DIB => L_DIB(2*i+1 downto 2*i), + ENA => ENA, + ENB => ENB, + SSRA => '0', + SSRB => '0', + WEA => WEA, + WEB => WEB + ); + end generate GL; + + DOA <= L_DOA(DOA'range); + DOB <= L_DOB(DOB'range); + + end generate AW_13_S2; + + AW_14_S1: if AWIDTH = 14 generate + GL: for i in DWIDTH-1 downto 0 generate + MEM : RAMB16_S1_S1 + generic map ( + INIT_A => "0", + INIT_B => "0", + SRVAL_A => "0", + SRVAL_B => "0", + WRITE_MODE_A => WRITE_MODE, + WRITE_MODE_B => WRITE_MODE) + port map ( + DOA => DOA(i downto i), + DOB => DOB(i downto i), + ADDRA => ADDRA, + ADDRB => ADDRB, + CLKA => CLKA, + CLKB => CLKB, + DIA => DIA(i downto i), + DIB => DIB(i downto i), + ENA => ENA, + ENB => ENB, + SSRA => '0', + SSRB => '0', + WEA => WEA, + WEB => WEB + ); + end generate GL; + end generate AW_14_S1; + + +end syn; + +-- Note: in XST 8.2 the defaults for INIT_(A|B) and SRVAL_(A|B) are +-- nonsense: INIT_A : bit_vector := X"000"; +-- This is a 12 bit value, while a 9 bit one is needed. Thus the +-- explicit definition above. diff --git a/rtl/vlib/rri/Makefile b/rtl/vlib/rri/Makefile new file mode 100644 index 00000000..d4cefdf7 --- /dev/null +++ b/rtl/vlib/rri/Makefile @@ -0,0 +1,22 @@ +# $Id: Makefile 311 2010-06-30 17:52:37Z mueller $ +# +# Revision History: +# Date Rev Version Comment +# 2007-12-09 100 1.0.1 drop ISE_p definition +# 2007-07-06 64 1.0 Initial version +# +VBOM_all = $(wildcard *.vbom) +NGC_all = $(VBOM_all:.vbom=.ngc) +# +.phony : all clean +# +all : $(NGC_all) +# +clean : ise_clean +# +#---- +# +include $(RETROBASE)/rtl/vlib/Makefile.xflow +# +include $(VBOM_all:.vbom=.dep_xst) +# diff --git a/rtl/vlib/rri/rb_sres_or_2.vbom b/rtl/vlib/rri/rb_sres_or_2.vbom new file mode 100644 index 00000000..e74f2182 --- /dev/null +++ b/rtl/vlib/rri/rb_sres_or_2.vbom @@ -0,0 +1,8 @@ +# libs +../slvtypes.vhd +rrilib.vhd +[ghdl,isim]tb/rritblib.vhd +# components +[ghdl,isim]tb/rritb_sres_or_mon.vbom +# design +rb_sres_or_2.vhd diff --git a/rtl/vlib/rri/rb_sres_or_2.vhd b/rtl/vlib/rri/rb_sres_or_2.vhd new file mode 100644 index 00000000..a51376f2 --- /dev/null +++ b/rtl/vlib/rri/rb_sres_or_2.vhd @@ -0,0 +1,76 @@ +-- $Id: rb_sres_or_2.vhd 314 2010-07-09 17:38:41Z mueller $ +-- +-- Copyright 2008-2010 by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, 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 complete details. +-- +------------------------------------------------------------------------------ +-- Module Name: rb_sres_or_2 - syn +-- Description: rribus result or, 2 input +-- +-- Dependencies: rritb_sres_or_mon [sim only] +-- Test bench: - +-- Target Devices: generic +-- Tool versions: xst 8.1, 8.2, 9.1, 9.2, 11.4; ghdl 0.18-0.29 +-- Revision History: +-- Date Rev Version Comment +-- 2010-06-26 309 1.1 add rritb_sres_or_mon +-- 2008-08-22 161 1.0.1 renamed rri_rbres_ -> rb_sres_ +-- 2008-01-20 113 1.0 Initial version +------------------------------------------------------------------------------ + +library ieee; +use ieee.std_logic_1164.all; + +use work.slvtypes.all; +use work.rrilib.all; +-- synthesis translate_off +use work.rritblib.all; +-- synthesis translate_on + +-- ---------------------------------------------------------------------------- + +entity rb_sres_or_2 is -- rribus result or, 2 input + port ( + RB_SRES_1 : in rb_sres_type; -- rb_sres input 1 + RB_SRES_2 : in rb_sres_type := rb_sres_init; -- rb_sres input 2 + RB_SRES_OR : out rb_sres_type -- rb_sres or'ed output + ); +end rb_sres_or_2; + +architecture syn of rb_sres_or_2 is + +begin + + proc_comb : process (RB_SRES_1, RB_SRES_2) + begin + + RB_SRES_OR.ack <= RB_SRES_1.ack or + RB_SRES_2.ack; + RB_SRES_OR.busy <= RB_SRES_1.busy or + RB_SRES_2.busy; + RB_SRES_OR.err <= RB_SRES_1.err or + RB_SRES_2.err; + RB_SRES_OR.dout <= RB_SRES_1.dout or + RB_SRES_2.dout; + + end process proc_comb; + +-- synthesis translate_off + ORMON : rritb_sres_or_mon + port map ( + RB_SRES_1 => RB_SRES_1, + RB_SRES_2 => RB_SRES_2, + RB_SRES_3 => rb_sres_init, + RB_SRES_4 => rb_sres_init + ); +-- synthesis translate_on + +end syn; diff --git a/rtl/vlib/rri/rb_sres_or_3.vbom b/rtl/vlib/rri/rb_sres_or_3.vbom new file mode 100644 index 00000000..cfba7cd3 --- /dev/null +++ b/rtl/vlib/rri/rb_sres_or_3.vbom @@ -0,0 +1,8 @@ +# libs +../slvtypes.vhd +rrilib.vhd +[ghdl,isim]tb/rritblib.vhd +# components +[ghdl,isim]tb/rritb_sres_or_mon.vbom +# design +rb_sres_or_3.vhd diff --git a/rtl/vlib/rri/rb_sres_or_3.vhd b/rtl/vlib/rri/rb_sres_or_3.vhd new file mode 100644 index 00000000..cac90e26 --- /dev/null +++ b/rtl/vlib/rri/rb_sres_or_3.vhd @@ -0,0 +1,81 @@ +-- $Id: rb_sres_or_3.vhd 314 2010-07-09 17:38:41Z mueller $ +-- +-- Copyright 2008-2010 by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, 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 complete details. +-- +------------------------------------------------------------------------------ +-- Module Name: rb_sres_or_3 - syn +-- Description: rribus result or, 3 input +-- +-- Dependencies: rritb_sres_or_mon [sim only] +-- Test bench: - +-- Target Devices: generic +-- Tool versions: xst 8.1, 8.2, 9.1, 9.2, 11.4; ghdl 0.18-0.29 +-- Revision History: +-- Date Rev Version Comment +-- 2010-06-26 309 1.1 add rritb_sres_or_mon +-- 2008-08-22 161 1.0.1 renamed rri_rbres_ -> rb_sres_ +-- 2008-01-20 113 1.0 Initial version +------------------------------------------------------------------------------ + +library ieee; +use ieee.std_logic_1164.all; + +use work.slvtypes.all; +use work.rrilib.all; +-- synthesis translate_off +use work.rritblib.all; +-- synthesis translate_on + +-- ---------------------------------------------------------------------------- + +entity rb_sres_or_3 is -- rribus result or, 3 input + port ( + RB_SRES_1 : in rb_sres_type; -- rb_sres input 1 + RB_SRES_2 : in rb_sres_type := rb_sres_init; -- rb_sres input 2 + RB_SRES_3 : in rb_sres_type := rb_sres_init; -- rb_sres input 3 + RB_SRES_OR : out rb_sres_type -- rb_sres or'ed output + ); +end rb_sres_or_3; + +architecture syn of rb_sres_or_3 is + +begin + + proc_comb : process (RB_SRES_1, RB_SRES_2, RB_SRES_3) + begin + + RB_SRES_OR.ack <= RB_SRES_1.ack or + RB_SRES_2.ack or + RB_SRES_3.ack; + RB_SRES_OR.busy <= RB_SRES_1.busy or + RB_SRES_2.busy or + RB_SRES_3.busy; + RB_SRES_OR.err <= RB_SRES_1.err or + RB_SRES_2.err or + RB_SRES_3.err; + RB_SRES_OR.dout <= RB_SRES_1.dout or + RB_SRES_2.dout or + RB_SRES_3.dout; + + end process proc_comb; + +-- synthesis translate_off + ORMON : rritb_sres_or_mon + port map ( + RB_SRES_1 => RB_SRES_1, + RB_SRES_2 => RB_SRES_2, + RB_SRES_3 => RB_SRES_3, + RB_SRES_4 => rb_sres_init + ); +-- synthesis translate_on + +end syn; diff --git a/rtl/vlib/rri/rri_core.vbom b/rtl/vlib/rri/rri_core.vbom new file mode 100644 index 00000000..bfcf2c34 --- /dev/null +++ b/rtl/vlib/rri/rri_core.vbom @@ -0,0 +1,8 @@ +# libs +../slvtypes.vhd +../comlib/comlib.vhd +rrilib.vhd +# components +../comlib/crc8.vbom +# design +rri_core.vhd diff --git a/rtl/vlib/rri/rri_core.vhd b/rtl/vlib/rri/rri_core.vhd new file mode 100644 index 00000000..e4e0a89a --- /dev/null +++ b/rtl/vlib/rri/rri_core.vhd @@ -0,0 +1,809 @@ +-- $Id: rri_core.vhd 314 2010-07-09 17:38:41Z mueller $ +-- +-- Copyright 2007-2010 by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, 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 complete details. +-- +------------------------------------------------------------------------------ +-- Module Name: rri_core - syn +-- Description: rri: core interface +-- +-- Dependencies: comlib/crc8 +-- +-- Test bench: tb/tb_rri_core +-- tb/tb_rritba_ttcombo +-- tb/tb_rriext_ttcombo +-- +-- Target Devices: generic +-- Tool versions: xst 8.1, 8.2, 9.1, 9.2, 11.4; ghdl 0.18-0.26 +-- +-- Synthesized (xst): +-- Date Rev ise Target flop lutl lutm slic t peri +-- 2010-06-06 302 11.4 L68 xc3s1000-4 151 323 0 197 s 8.9 +-- 2010-04-03 274 11.4 L68 xc3s1000-4 148 313 0 190 s 8.0 +-- 2009-07-11 232 10.1.03 K39 xc3s1000-4 147 321 0 197 s 8.3 +-- +-- Revision History: +-- Date Rev Version Comment +-- 2010-06-20 308 2.6 use rbinit,rbreq,rbwe state flops to drive rb_mreq; +-- now nak on reserved cmd 111; use do_comma_abort(); +-- 2010-06-18 306 2.5.1 rename rbus data fields to _rbf_ +-- 2010-06-06 302 2.5 use sop/eop framing instead of soc+chaining +-- 2010-06-03 299 2.1.2 drop unneeded unsigned casts; change init encoding +-- 2010-05-02 287 2.1.1 ren CE_XSEC->CE_INT,RP_STAT->RB_STAT,AP_LAM->RB_LAM +-- drop RP_IINT signal from interfaces +-- 2010-04-03 274 2.1 add CP_FLUSH output +-- 2009-07-12 233 2.0.1 remove snoopers +-- 2008-08-24 162 2.0 with new rb_mreq/rb_sres interface +-- 2008-03-02 121 1.1.1 comment out snoopers +-- 2007-11-24 98 1.1 new internal init handling (addr=11111111) +-- 2007-10-12 88 1.0.1 avoid ieee.std_logic_unsigned, use cast to unsigned +-- 2007-09-15 82 1.0 Initial version, fully functional +-- 2007-06-17 58 0.5 First preliminary version +------------------------------------------------------------------------------ +-- +-- Overall protocol: +-- _idle : expect +-- sop -> _txsop (echo sop, , to _txsop, _rxcmd) +-- eop -> _txeop (send nak,eop , to _txnak, _txeop, _idle) +-- nak -> _txnak (silently ignore nak) +-- attn -> _txito (send ito , to _idle) +-- data -> _idle (silently ignore data) +-- _error: expect +-- sop -> _txnak (send nak , to _txnak, _error) +-- eop -> _txeop (echo eop , to _txeop, _idle) +-- nak -> _txnak (echo nak , to _txnak, _error) +-- attn -> _txito (silently ignore attn) +-- data -> _idle (silently ignore data) +-- _rxcmd: expect +-- sop -> _txnak (send nak , to _txnak, _error) +-- eop -> _txeop (echo eop , to _txeop, _idle) +-- nak -> _txnak (echo nak , to _txnak, _error) +-- attn -> _txito (silently ignore attn) +-- data -> _idle (decode command) +-- _rx...: expect +-- sop -> _txnak (send nak , to _txnak, _error) +-- eop -> _txnak (send nak,eop , to _txnak, _txeop, _idle) +-- nak -> _txnak (echo nak , to _txnak, _error) +-- attn -> _txito (silently ignore attn) +-- data -> _idle (decode data) +-- +-- 7 supported commands: +-- +-- 000 read reg (rreg): +-- rx: cmd addr ccrc +-- tx: cmd dl dh stat crc +-- seq: _rxcmd _rxaddr _rxccrc (_txcmd|_txnak) +-- _rreg _txdatl _txdath _txstat _txcrc (_rxcmd|_idle) +-- +-- 001 read blk (rblk): +-- rx: cmd addr cnt ccrc +-- tx: cmd cnt dl dh ... stat crc +-- seq: _rxcmd _rxaddr _rxcnt _rxccrc (_txcmd|_txnak) _txcnt +-- {_rreg _txdatl _txdath _blk}* _txstat _txcrc (_rxcmd|_idle) +-- +-- 010 write reg (wreg): +-- rx: cmd addr dl dh ccrc +-- tx: cmd stat crc +-- seq: _rxcmd _rxaddr _rxdatl _rxdath _rxccrc (_txcmd|_txnak) +-- seq: _wreg _txstat _txcrc (_rxcmd|_idle) +-- +-- 011 write blk (wblk): +-- rx: cmd addr cnt ccrc dl dh ... dcrc +-- tx: cmd stat crc +-- seq: _rxcmd _rxaddr _rxcnt _rxccrc (_txcmd|_txnak) +-- {_rxdatl _rxdath _wreg _blk}* _rxdcrc _txstat _txcrc (_rxcmd|_idle) +-- +-- 100 read stat (stat): +-- rx: cmd ccrc +-- tx: cmd ccmd dl dh stat crc +-- seq: _rxcmd _rxccrc (_txcmd|_txnak) +-- _txccmd _txdatl _txdath _txstat _txcrc (_rxcmd|_idle) +-- +-- 101 read attn (attn): +-- rx: cmd ccrc +-- tx: cmd dl dh stat crc +-- seq: _rxcmd _rxccrc (_txcmd|_txnak) +-- _attn _txdatl _txdath _txstat _txcrc (_rxcmd|_idle) +-- +-- 110 write init (init): +-- rx: cmd addr dl dh ccrc +-- tx: cmd stat crc +-- seq: _rxcmd _rxaddr _rxdatl _rxdath _rxccrc (_txcmd|_txnak) +-- seq: _txstat _txcrc (_rxcmd|_idle) +-- like wreg, but no rp_we - rp_hold, just a 1 cycle rp_init pulse +-- +-- 111 is currently not a legal command and causes a nak +-- seq: _txnak +-- +-- The different rbus cycle types are encoded as: +-- +-- init ack we +-- 0 0 0 idle +-- 0 0 1 idle +-- 0 1 0 read +-- 0 1 1 write +-- 1 0 0 internal init +-- 1 0 1 external init +-- 1 1 0 not allowed +-- 1 1 1 not allowed +-- + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; + +use work.slvtypes.all; +use work.comlib.all; +use work.rrilib.all; + +entity rri_core is -- rri, core interface + generic ( + ATOWIDTH : positive := 5; -- access timeout counter width + ITOWIDTH : positive := 6); -- idle timeout counter width + port ( + CLK : in slbit; -- clock + CE_INT : in slbit := '0'; -- rri ito time unit clock enable + RESET : in slbit; -- reset + CP_DI : in slv9; -- comm port: data in + CP_ENA : in slbit; -- comm port: data enable + CP_BUSY : out slbit; -- comm port: data busy + CP_DO : out slv9; -- comm port: data out + CP_VAL : out slbit; -- comm port: data valid + CP_HOLD : in slbit; -- comm port: data hold + CP_FLUSH : out slbit; -- comm port: data flush + RB_MREQ : out rb_mreq_type; -- rbus: request + RB_SRES : in rb_sres_type; -- rbus: response + RB_LAM : in slv16; -- rbus: look at me + RB_STAT : in slv3 -- rbus: status flags + ); +end entity rri_core; + + +architecture syn of rri_core is + + type state_type is ( + s_idle, -- s_idle: wait for sop + s_txito, -- s_txito: send timeout symbol + s_txsop, -- s_txsop: send sop + s_txnak, -- s_txnak: send nak + s_txeop, -- s_txeop: send eop + s_error, -- s_error: wait for eop + s_rxcmd, -- s_rxcmd: wait for cmd + s_rxaddr, -- s_rxaddr: wait for addr + s_rxdatl, -- s_rxdatl: wait for data low + s_rxdath, -- s_rxdath: wait for data high + s_rxcnt, -- s_rxcnt: wait for count + s_rxccrc, -- s_rxccrc: wait for command crc + s_txcmd, -- s_txcmd: send cmd + s_txcnt, -- s_txcnt: send cnt + s_rreg, -- s_rreg: reg or blk read + s_txdatl, -- s_txdatl: send data low + s_txdath, -- s_txdath: send data high + s_wreg, -- s_wreg: reg or blk write + s_blk, -- s_blk: block count handling + s_rxdcrc, -- s_rxdcrc: wait for data crc + s_attn, -- s_attn: handle attention flags + s_txccmd, -- s_txccmd: send last command + s_txstat, -- s_txstat: send status + s_txcrc -- s_txcrc: send crc + ); + + type regs_type is record + state : state_type; -- state + rcmd : slv8; -- received command + ccmd : slv8; -- current command + addr : slv8; -- register address + dil : slv8; -- input data, lsb + dih : slv8; -- input data, msb + dol : slv8; -- output data, lsb + doh : slv8; -- output data, msb + cnt : slv8; -- block transfer count + attn : slv16; -- attn mask + atocnt : slv(ATOWIDTH-1 downto 0); -- access timeout counter + itocnt : slv(ITOWIDTH-1 downto 0); -- idle timeout counter + itoval : slv(ITOWIDTH-1 downto 0); -- idle timeout value + itoena : slbit; -- idle timeout enable flag + anena : slbit; -- attn notification enable flag + andone : slbit; -- attn notification done + ccrc : slbit; -- stat: command crc error + dcrc : slbit; -- stat: data crc error + ioto : slbit; -- stat: i/o time out + ioerr : slbit; -- stat: i/o time error + nakeop : slbit; -- send eop after nak + rbinit : slbit; -- rbus init signal + rbreq : slbit; -- rbus req signal + rbwe : slbit; -- rbus we signal + flush : slbit; -- flush pulse + stat : slv3; -- external status flags + end record regs_type; + + constant atocnt_init : slv(ATOWIDTH-1 downto 0) := (others=>'1'); + constant itocnt_init : slv(ITOWIDTH-1 downto 0) := (others=>'0'); + + constant c_idle : slv4 := "0000"; + constant c_sop : slv4 := "0001"; + constant c_eop : slv4 := "0010"; + constant c_nak : slv4 := "0011"; + constant c_attn : slv4 := "0100"; + + constant regs_init : regs_type := ( + s_idle, -- + (others=>'0'), -- rcmd + (others=>'0'), -- ccmd + (others=>'0'), -- addr + (others=>'0'), -- dil + (others=>'0'), -- dih + (others=>'0'), -- dol + (others=>'0'), -- doh + (others=>'0'), -- cnt + (others=>'0'), -- attn + atocnt_init, -- atocnt + itocnt_init, -- itocnt + itocnt_init, -- itoval + '0', -- itoena + '0','0', -- anena, andone + '0','0','0','0', -- stat flags + '0', -- nakeop + '0','0','0', -- rbinit,rbreq,rbwe + '0', -- flush + (others=>'0') -- stat + ); + + signal R_REGS : regs_type := regs_init; -- state registers + signal N_REGS : regs_type := regs_init; -- next value state regs + + signal CRC_RESET : slbit := '0'; + signal ICRC_ENA : slbit := '0'; + signal OCRC_ENA : slbit := '0'; + signal ICRC_OUT : slv8 := (others=>'0'); + signal OCRC_OUT : slv8 := (others=>'0'); + signal OCRC_IN : slv8 := (others=>'0'); + +begin + + assert ITOWIDTH<=8 + report "assert(ITOWIDTH<=8): max byte size ITO counter supported" + severity failure; + + ICRC : crc8 -- crc generator for input data + port map ( + CLK => CLK, + RESET => CRC_RESET, + ENA => ICRC_ENA, + DI => CP_DI(7 downto 0), + CRC => ICRC_OUT + ); + + OCRC : crc8 -- crc generator for output data + port map ( + CLK => CLK, + RESET => CRC_RESET, + ENA => OCRC_ENA, + DI => OCRC_IN, + CRC => OCRC_OUT + ); + + proc_regs: process (CLK) + begin + + if CLK'event and CLK='1' then + if RESET = '1' then + R_REGS <= regs_init; + else + R_REGS <= N_REGS; + end if; + end if; + + end process proc_regs; + + proc_next: process (R_REGS, CE_INT, CP_DI, CP_ENA, CP_HOLD, RB_LAM, + RB_SRES, RB_STAT, ICRC_OUT, OCRC_OUT) + + variable r : regs_type := regs_init; + variable n : regs_type := regs_init; + + variable ival : slbit := '0'; + variable ibusy : slbit := '0'; + variable ido : slv9 := (others=>'0'); + variable ato_go : slbit := '0'; + variable ato_end : slbit := '0'; + variable ito_go : slbit := '0'; + variable ito_end : slbit := '0'; + variable crcreset : slbit := '0'; + variable icrcena : slbit := '0'; + variable ocrcena : slbit := '0'; + variable has_attn : slbit := '0'; + variable idi8 : slv8 := (others=>'0'); + variable is_comma : slbit := '0'; + variable comma_typ : slv4 := "0000"; + + procedure do_comma_abort(nstate : inout state_type; + nnakeop : inout slbit; + comma_typ : in slv4) is + begin + if comma_typ=c_sop or comma_typ=c_eop or comma_typ=c_nak then + if comma_typ = c_eop then + nnakeop := '1'; + end if; + nstate := s_txnak; -- next: send nak + end if; + end procedure do_comma_abort; + + begin + + r := R_REGS; + n := R_REGS; + + idi8 := CP_DI(7 downto 0); -- get data part of CP_DI + is_comma := CP_DI(8); -- get comma marker + comma_typ := CP_DI(3 downto 0); -- get comma type + + n.rbinit := '0'; -- clear rbinit,rbreq,rbwe by default + n.rbreq := '0'; -- they must always be set by the + n.rbwe := '0'; -- 'previous state' + + n.flush := '0'; -- dito for flush + + ibusy := '1'; -- default is to hold input + ival := '0'; + ido := (others=>'0'); + + crcreset := '0'; + icrcena := '0'; + ocrcena := '0'; + + for i in RB_LAM'range loop -- handle attention "LAM's" + if RB_LAM(i) = '1' then -- if LAM bit set + n.attn(i) := '1'; -- set attention bit + end if; + end loop; + + has_attn := '0'; + if unsigned(r.attn) /= 0 then -- is any of the attn bits set ? + has_attn := '1'; + end if; + + ato_go := '0'; -- default: keep access timeout in reset + ato_end := '0'; + if unsigned(r.atocnt) = 0 then -- if access timeout count at zero + ato_end := '1'; -- signal expiration + end if; + + ito_go := '0'; -- default: keep idle timeout in reset + ito_end := '0'; + if unsigned(r.itocnt) = 0 then -- if idle timeout count at zero + ito_end := '1'; -- signal expiration + end if; + + case r.state is + when s_idle => -- s_idle: wait for sop -------------- + ito_go := '1'; -- idle timeout active + if (r.anena='1' and -- if attn notification to send + has_attn='1' and r.andone='0') then + n.state := s_txito; -- next send ito byte + else + ibusy := '0'; -- accept input + if CP_ENA = '1' then -- if input + if is_comma = '1' then -- if comma + case comma_typ is + when c_sop => -- if sop + crcreset := '1'; -- reset crc generators + n.state := s_txsop; -- next: echo it + when c_eop => -- if eop (unexpected) + n.nakeop := '1'; -- send nak,eop + n.state := s_txnak; -- next: send nak + when c_attn => -- if attn + n.state := s_txito; -- next: send ito byte + when others => null; -- other commas: silently ignore + end case; + else -- if normal data + n.state := s_idle; -- silently dropped + end if; + elsif (r.itoena='1' and -- if ito enable, expired and XSEC + ito_end='1' and CE_INT='1') then + n.state := s_txito; -- next: send ito byte + end if; + end if; + + when s_txito => -- s_txito: send timeout symbol ------ + if has_attn = '1' then + ido := c_rri_dat_attn; -- if attn pending: send attn symbol + n.andone := '1'; + else + ido := c_rri_dat_idle; -- otherwise: send idle symbol + end if; + ival := '1'; + if CP_HOLD = '0' then -- wait for accept + n.state := s_idle; -- next: wait for sop + end if; + + when s_txsop => -- s_txsop: send sop ----------------- + ido := c_rri_dat_sop; -- send sop character + ival := '1'; + if CP_HOLD = '0' then -- wait for accept + n.state := s_rxcmd; -- next: read first command + end if; + + when s_txnak => -- s_txnak: send nak ----------------- + ido := c_rri_dat_nak; -- send nak character + ival := '1'; + if CP_HOLD = '0' then -- wait for accept + n.nakeop := '0'; + if r.nakeop = '1' then -- if eop after nak requested + n.state := s_txeop; -- next: send eop + else + n.state := s_error; -- next: error state, wait for eop + end if; + end if; + + when s_txeop => -- s_txeop: send eop ----------------- + ido := c_rri_dat_eop; -- send eop character + ival := '1'; + if CP_HOLD = '0' then -- wait for accept + n.flush := '1'; -- send flush pulse + n.state := s_idle; -- next: idle state, wait for sop + end if; + + when s_error => -- s_error: wait for eop ------------- + ibusy := '0'; -- accept input + if CP_ENA = '1' then + if is_comma = '1' then -- if comma + case comma_typ is + when c_sop => -- if sop (unexpected) + n.state := s_txnak; -- next: send nak + when c_eop => -- if eop + n.state := s_txeop; -- next: echo eop + when c_nak => -- if nak + n.state := s_txnak; -- next: echo nak + when others => null; -- other commas: silently ignore + end case; + else -- if normal data + n.state := s_error; -- silently dropped + end if; + end if; + + when s_rxcmd => -- s_rxcmd: wait for cmd ------------- + ibusy := '0'; -- accept input + if CP_ENA = '1' then + if is_comma = '1' then -- if comma + case comma_typ is + when c_sop => -- if sop (unexpected) + n.state := s_txnak; -- next: send nak + when c_eop => -- if eop + n.state := s_txeop; -- next: echo eop + when c_nak => -- if nak + n.state := s_txnak; -- next: echo nak + when others => null; --other commas: silently ignore + end case; + else + icrcena := '1'; -- update input crc + n.rcmd := idi8; -- latch read command code + case CP_DI(c_rri_cmd_rbf_code) is + when c_rri_cmd_rreg | c_rri_cmd_rblk | + c_rri_cmd_wreg | c_rri_cmd_wblk | + c_rri_cmd_init => -- for commands needing addr(data) + n.state := s_rxaddr; -- next: read address + when c_rri_cmd_stat | c_rri_cmd_attn => -- stat and attn commands + n.state := s_rxccrc; -- next: read command crc + when others => + n.state := s_idle; -- if bad command abort here + end case; -- rcmd,ccmd always hold good cmd + end if; + end if; + + when s_rxaddr => -- s_rxaddr: wait for addr ----------- + ibusy := '0'; -- accept input + if CP_ENA = '1' then + if is_comma = '1' then -- if comma + do_comma_abort(n.state, n.nakeop, comma_typ); + else + icrcena := '1'; -- update input crc + n.addr := idi8; -- latch read address + case r.rcmd(c_rri_cmd_rbf_code) is + when c_rri_cmd_rreg => -- for rreg command + n.state := s_rxccrc; -- next: read command crc + when c_rri_cmd_wreg | c_rri_cmd_init => -- for wreg, init command + n.state := s_rxdatl; -- next: read data lsb + when others => -- for rblk or wblk + n.state := s_rxcnt; -- next: read count + end case; + end if; + end if; + + when s_rxdatl => -- s_rxdatl: wait for data low ------- + ibusy := '0'; -- accept input + if CP_ENA = '1' then + if is_comma = '1' then -- if comma + do_comma_abort(n.state, n.nakeop, comma_typ); + else + icrcena := '1'; -- update input crc + n.dil := idi8; -- latch data lsb part + n.state := s_rxdath; -- next: read data msb + end if; + end if; + + when s_rxdath => -- s_rxdath: wait for data high ------ + ibusy := '0'; -- accept input + if CP_ENA = '1' then + if is_comma = '1' then -- if comma + do_comma_abort(n.state, n.nakeop, comma_typ); + else + icrcena := '1'; -- update input crc + n.dih := idi8; -- latch data msb part + if r.rcmd(c_rri_cmd_rbf_code) = c_rri_cmd_wblk then -- if wblk + n.rbreq := '1'; + n.rbwe := '1'; + n.state := s_wreg; -- next: write reg + else -- otherwise + n.state := s_rxccrc; -- next: read command crc + end if; + end if; + end if; + + when s_rxcnt => -- s_rxcnt: wait for count ----------- + ibusy := '0'; -- accept input + if CP_ENA = '1' then + if is_comma = '1' then -- if comma + do_comma_abort(n.state, n.nakeop, comma_typ); + else + icrcena := '1'; -- update input crc + n.cnt := idi8; -- latch count + n.state := s_rxccrc; -- next: read command crc + end if; + end if; + + when s_rxccrc => -- s_rxccrc: wait for command crc ---- + ibusy := '0'; -- accept input + if CP_ENA = '1' then + if is_comma = '1' then -- if comma + do_comma_abort(n.state, n.nakeop, comma_typ); + else + if idi8 /= ICRC_OUT then -- if crc error + n.ccrc := '1'; -- set command crc error flag + n.state := s_txnak; -- next: send nak + else -- if crc ok + n.state := s_txcmd; -- next: echo command + end if; + end if; + end if; + + when s_txcmd => -- s_txcmd: send cmd ----------------- + ido := '0' & r.rcmd; -- send read command + ival := '1'; + if CP_HOLD = '0' then -- wait for accept + ocrcena := '1'; -- update output crc + if r.rcmd(c_rri_cmd_rbf_code) /= c_rri_cmd_stat then -- unless stat + n.ccmd := r.rcmd; -- latch read command in ccmd + n.stat := RB_STAT; -- latch external status bits + n.ccrc := '0'; + n.dcrc := '0'; + n.ioto := '0'; + n.ioerr := '0'; + end if; + case r.rcmd(c_rri_cmd_rbf_code) is -- main command dispatcher + when c_rri_cmd_rreg => -- rreg ---------------- + n.rbreq := '1'; + n.state := s_rreg; + when c_rri_cmd_rblk => -- rblk ---------------- + n.state := s_txcnt; + when c_rri_cmd_wreg => -- wreg ---------------- + n.rbreq := '1'; + n.rbwe := '1'; + n.state := s_wreg; + when c_rri_cmd_wblk => -- wblk ---------------- + n.state := s_rxdatl; + when c_rri_cmd_stat => -- stat ---------------- + n.state := s_txccmd; + when c_rri_cmd_attn => -- attn ---------------- + n.state := s_attn; + + when c_rri_cmd_init => -- init ---------------- + n.rbinit := '1'; -- send init pulse + if r.addr(7 downto 3) = "11111" then -- is internal init + if r.addr(2 downto 0) = "111" then -- is rri init + n.anena := r.dih(c_rri_iint_rbf_anena - 8); + n.itoena := r.dih(c_rri_iint_rbf_itoena - 8); + n.itoval := r.dil(ITOWIDTH-1 downto 0); + -- note: itocnt will load in next + -- cycle because ito_go=0, so no + -- action required here + + end if; + else -- is external init + n.rbwe := '1'; -- send init with we + end if; + n.state := s_txstat; + + when others => -- '111' --------------- + n.state := s_txnak; -- send NAK on reserved command + end case; + end if; + + when s_txcnt => -- s_txcnt: send cnt ----------------- + ido := '0' & r.cnt; -- send cnt + ival := '1'; + if CP_HOLD = '0' then -- wait for accept + ocrcena := '1'; -- update output crc + n.rbreq := '1'; + n.state := s_rreg; -- next: first read reg + end if; + + when s_rreg => -- s_rreg: reg or blk read ----------- + -- this state handles all rbus reads. Expects that previous state + -- sets n.rbreq := '1' to start an rbus read cycle + ato_go := '1'; -- activate timeout counter + if RB_SRES.err = '1' then -- latch error flag + n.ioerr := '1'; + end if; + n.doh := RB_SRES.dout(15 downto 8); -- latch data + n.dol := RB_SRES.dout( 7 downto 0); + n.stat := RB_STAT; -- latch external status bits + if RB_SRES.busy='0' or ato_end='1' then -- wait for non-busy or timeout + if RB_SRES.busy='1' and ato_end='1' then -- if timeout and still busy + n.ioto := '1'; -- set timeout flag + elsif RB_SRES.ack = '0' then -- if non-busy and no ack + n.ioto := '1'; -- set timeout flag + end if; + n.state := s_txdatl; -- next: send data lsb + else -- otherwise rbus read continues + n.rbreq := '1'; -- extend req + end if; + + when s_txdatl => -- s_txdatl: send data low ----------- + ido := '0' & r.dol; -- send data + ival := '1'; + if CP_HOLD = '0' then -- wait for accept + ocrcena := '1'; -- update output crc + n.state := s_txdath; -- next: send data msb + end if; + + when s_txdath => -- s_txdath: send data high + ido := '0' & r.doh; -- send data + ival := '1'; + if CP_HOLD = '0' then -- wait for accept + ocrcena := '1'; -- update output crc + if r.rcmd(c_rri_cmd_rbf_code) = c_rri_cmd_rblk then -- if rblk + n.state := s_blk; -- next: block count handling + else -- otherwise + n.state := s_txstat; -- next: send stat + end if; + end if; + + when s_wreg => -- s_wreg: reg or blk write ---------- + -- this state handles all rbus writes. Expects that previous state + -- sets n.rbreq := '1' and n.rbwe := '1' to start an rbus write cycle + ato_go := '1'; -- activate timeout counter + if RB_SRES.err = '1' then -- latch error flag + n.ioerr := '1'; + end if; + n.stat := RB_STAT; -- latch external status bits + if RB_SRES.busy='0' or ato_end='1' then -- wait for non-busy or timeout + if RB_SRES.busy='1' and ato_end='1' then -- if timeout and still busy + n.ioto := '1'; -- set timeout flag + elsif RB_SRES.ack='0' then -- if non-busy and no ack + n.ioto := '1'; -- set timeout flag + end if; + if r.rcmd(c_rri_cmd_rbf_code) = c_rri_cmd_wblk then -- if wblk + n.state := s_blk; -- next: block count handling + else -- otherwise + n.state := s_txstat; -- next: send stat + end if; + else -- otherwise rbus write continues + n.rbreq := '1'; -- extend req + n.rbwe := '1'; -- extend we + end if; + + when s_blk => -- s_blk: block count handling ------- + n.cnt := unsigned(r.cnt) - 1; -- decrement transfer count + if unsigned(r.cnt) = 0 then -- if last transfer + if r.rcmd(c_rri_cmd_rbf_code) = c_rri_cmd_rblk then -- if rblk + n.state := s_txstat; -- next: send stat + else -- otherwise + n.state := s_rxdcrc; -- next: read data crc + end if; + + else -- otherwise more to transfer + if r.rcmd(c_rri_cmd_rbf_code) = c_rri_cmd_rblk then -- if rblk + n.rbreq := '1'; + n.state := s_rreg; -- next: read blk + else -- otherwise + n.state := s_rxdatl; -- next: read data + end if; + end if; + + when s_rxdcrc => -- s_rxdcrc: wait for data crc ------- + ibusy := '0'; -- accept input + if CP_ENA = '1' then + if is_comma = '1' then -- if comma + do_comma_abort(n.state, n.nakeop, comma_typ); + else + if idi8 /= ICRC_OUT then -- if crc error + n.dcrc := '1'; -- set data crc error flag + end if; + n.state := s_txstat; -- next: echo command + end if; + end if; + + when s_attn => -- s_attn: handle attention flags ---- + n.dol := r.attn(7 downto 0); -- move attention flags to do buffer + n.doh := r.attn(15 downto 8); + n.attn := RB_LAM; -- LAM in current cycle send next time + n.andone := '0'; -- reenable attn nofification + n.state := s_txdatl; -- next: send data lsb + + when s_txccmd => -- s_txccmd: send last command + ido := '0' & r.ccmd; -- send last accepted command + ival := '1'; + if CP_HOLD = '0' then -- wait for accept + ocrcena := '1'; -- update output crc + n.state := s_txdatl; -- next: send last data lsb + end if; + + when s_txstat => -- s_txstat: send status ------------- + ido := (others=>'0'); + ido(c_rri_stat_rbf_stat) := r.stat; + ido(c_rri_stat_rbf_attn) := has_attn; + ido(c_rri_stat_rbf_ccrc) := r.ccrc; + ido(c_rri_stat_rbf_dcrc) := r.dcrc; + ido(c_rri_stat_rbf_ioto) := r.ioto; + ido(c_rri_stat_rbf_ioerr) := r.ioerr; + ival := '1'; + if CP_HOLD ='0' then -- wait for accept + ocrcena := '1'; -- update output crc + n.state := s_txcrc; -- next: send crc + end if; + + when s_txcrc => -- s_txcrc: send crc ----------------- + ido := "0" & OCRC_OUT; -- send crc code + ival := '1'; + if CP_HOLD = '0' then -- wait for accept + n.state := s_rxcmd; -- next: read command or eop + end if; + + when others => null; -- <> -------------------------------- + end case; + + if ato_go = '0' then -- handle access timeout counter + n.atocnt := atocnt_init; -- if ato_go=0, keep in reset + else + n.atocnt := unsigned(r.atocnt) - 1;-- otherwise count down + end if; + + if ito_go = '0' then -- handle idle timeout counter + n.itocnt := r.itoval; -- if ito_go=0, keep at start value + else + if CE_INT = '1' then + n.itocnt := unsigned(r.itocnt) - 1;-- otherwise count down every CE_INT + end if; + end if; + + N_REGS <= n; + + CP_BUSY <= ibusy; + CP_DO <= ido; + CP_VAL <= ival; + CP_FLUSH <= r.flush; + + RB_MREQ <= rb_mreq_init; + RB_MREQ.req <= r.rbreq; + RB_MREQ.we <= r.rbwe; + RB_MREQ.init <= r.rbinit; + RB_MREQ.addr <= r.addr; + RB_MREQ.din <= r.dih & r.dil; + + CRC_RESET <= crcreset; + ICRC_ENA <= icrcena; + OCRC_ENA <= ocrcena; + OCRC_IN <= ido(7 downto 0); + + end process proc_next; + +end syn; diff --git a/rtl/vlib/rri/rri_core_serport.vbom b/rtl/vlib/rri/rri_core_serport.vbom new file mode 100644 index 00000000..9b91c0f0 --- /dev/null +++ b/rtl/vlib/rri/rri_core_serport.vbom @@ -0,0 +1,11 @@ +# libs +../slvtypes.vhd +rrilib.vhd +[ghdl,isim]tb/rritblib.vhd +# components +rri_serport.vbom +rri_core.vbom +[ghdl,isim]tb/rritb_cpmon_sb.vbom +[ghdl,isim]tb/rritb_rbmon_sb.vbom +# design +rri_core_serport.vhd diff --git a/rtl/vlib/rri/rri_core_serport.vhd b/rtl/vlib/rri/rri_core_serport.vhd new file mode 100644 index 00000000..51d14750 --- /dev/null +++ b/rtl/vlib/rri/rri_core_serport.vhd @@ -0,0 +1,170 @@ +-- $Id: rri_core_serport.vhd 314 2010-07-09 17:38:41Z mueller $ +-- +-- Copyright 2010- by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, 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 complete details. +-- +------------------------------------------------------------------------------ +-- Module Name: rri_core_serport - syn +-- Description: rri: core + serport combo, with cpmon and rbmon +-- +-- Dependencies: rri_serport +-- rri_core +-- rritb_cpmon_sb [sim only] +-- rritb_rbmon_sb [sim only] +-- +-- Test bench: - +-- +-- Target Devices: generic +-- Tool versions: xst 11.4; ghdl 0.26 +-- +-- Synthesized (xst): +-- Date Rev ise Target flop lutl lutm slic t peri +-- 2010-04-03 275 11.4 L68 xc3s1000-4 280 600 18 375 s 9.8 +-- +-- Revision History: +-- Date Rev Version Comment +-- 2010-06-05 301 1.2.2 renamed _rpmon -> _rbmon +-- 2010-06-03 300 1.2.1 use FAWIDTH=5 +-- 2010-05-02 287 1.2 ren CE_XSEC->CE_INT,RP_STAT->RB_STAT,AP_LAM->RB_LAM +-- drop RP_IINT from interfaces; drop RTSFLUSH generic +-- 2010-04-18 279 1.1 drop RTSFBUF generic +-- 2010-04-10 275 1.0 Initial version +------------------------------------------------------------------------------ + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; + +use work.slvtypes.all; +use work.rrilib.all; +-- synthesis translate_off +use work.rritblib.all; +-- synthesis translate_on + +entity rri_core_serport is -- rri, core+serport with cpmon+rbmon + generic ( + ATOWIDTH : positive := 5; -- access timeout counter width + ITOWIDTH : positive := 6; -- idle timeout counter width + FAWIDTH : positive := 5; -- rx fifo address port width + CDWIDTH : positive := 13; -- clk divider width + CDINIT : natural := 15); -- clk divider initial/reset setting + port ( + CLK : in slbit; -- clock + CE_USEC : in slbit; -- 1 usec clock enable + CE_MSEC : in slbit; -- 1 msec clock enable + CE_INT : in slbit := '0'; -- rri ito time unit clock enable + RESET : in slbit; -- reset + RXSD : in slbit; -- receive serial data (board view) + TXSD : out slbit; -- transmit serial data (board view) + CTS_N : in slbit := '0'; -- clear to send (act.low, board view) + RTS_N : out slbit; -- request to send (act.low, board view) + RB_MREQ : out rb_mreq_type; -- rbus: request + RB_SRES : in rb_sres_type; -- rbus: response + RB_LAM : in slv16; -- rbus: look at me + RB_STAT : in slv3 -- rbus: status flags + ); +end entity rri_core_serport; + + +architecture syn of rri_core_serport is + + signal CP_DI : slv9 := (others=>'0'); + signal CP_ENA : slbit := '0'; + signal CP_BUSY : slbit := '0'; + signal CP_DO : slv9 := (others=>'0'); + signal CP_VAL : slbit := '0'; + signal CP_HOLD : slbit := '0'; + signal CP_FLUSH : slbit := '0'; + + signal RB_MREQ_L : rb_mreq_type := rb_mreq_init; -- local, readable RB_MREQ + +begin + + SER2RRI : rri_serport + generic map ( + CPREF => "1000", + FAWIDTH => FAWIDTH, + CDWIDTH => CDWIDTH, + CDINIT => CDINIT) + port map ( + CLK => CLK, + CE_USEC => CE_USEC, + CE_MSEC => CE_MSEC, + RESET => RESET, + RXSD => RXSD, + TXSD => TXSD, + CTS_N => CTS_N, + RTS_N => RTS_N, + CP_DI => CP_DI, + CP_ENA => CP_ENA, + CP_BUSY => CP_BUSY, + CP_DO => CP_DO, + CP_VAL => CP_VAL, + CP_HOLD => CP_HOLD, + CP_FLUSH => CP_FLUSH + ); + + RRI : rri_core + generic map ( + ATOWIDTH => ATOWIDTH, + ITOWIDTH => ITOWIDTH) + port map ( + CLK => CLK, + CE_INT => CE_INT, + RESET => RESET, + CP_DI => CP_DI, + CP_ENA => CP_ENA, + CP_BUSY => CP_BUSY, + CP_DO => CP_DO, + CP_VAL => CP_VAL, + CP_HOLD => CP_HOLD, + CP_FLUSH => CP_FLUSH, + RB_MREQ => RB_MREQ_L, + RB_SRES => RB_SRES, + RB_LAM => RB_LAM, + RB_STAT => RB_STAT + ); + + -- vhdl'93 unfortunately doesn't allow to read a signal bound to an out port + -- because RB_MREQ is read by the monitors, an extra internal + -- signal must be used. This will not be needed with vhdl'2000 anymore + + RB_MREQ <= RB_MREQ_L; + +-- synthesis translate_off + CPMON : rritb_cpmon_sb + generic map ( + DWIDTH => CP_DI'length, + ENAPIN => 15) + port map ( + CLK => CLK, + CP_DI => CP_DI, + CP_ENA => CP_ENA, + CP_BUSY => CP_BUSY, + CP_DO => CP_DO, + CP_VAL => CP_VAL, + CP_HOLD => CP_HOLD + ); + + RBMON : rritb_rbmon_sb + generic map ( + DBASE => 8, + ENAPIN => 14) + port map ( + CLK => CLK, + RB_MREQ => RB_MREQ_L, + RB_SRES => RB_SRES, + RB_LAM => RB_LAM, + RB_STAT => RB_STAT + ); +-- synthesis translate_on + +end syn; diff --git a/rtl/vlib/rri/rri_serport.vbom b/rtl/vlib/rri/rri_serport.vbom new file mode 100644 index 00000000..5189108d --- /dev/null +++ b/rtl/vlib/rri/rri_serport.vbom @@ -0,0 +1,14 @@ +# libs +../slvtypes.vhd +../genlib/genlib.vhd +../memlib/memlib.vhd +../comlib/comlib.vhd +../serport/serport.vhd +rrilib.vhd +# components +../serport/serport_uart_rxtx_ab.vbom +../comlib/byte2cdata.vbom +../comlib/cdata2byte.vbom +../memlib/fifo_1c_dram.vbom +# design +rri_serport.vhd diff --git a/rtl/vlib/rri/rri_serport.vhd b/rtl/vlib/rri/rri_serport.vhd new file mode 100644 index 00000000..9557f588 --- /dev/null +++ b/rtl/vlib/rri/rri_serport.vhd @@ -0,0 +1,201 @@ +-- $Id: rri_serport.vhd 314 2010-07-09 17:38:41Z mueller $ +-- +-- Copyright 2007-2010 by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, 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 complete details. +-- +------------------------------------------------------------------------------ +-- Module Name: rri_serport - syn +-- Description: rri: serport adapter +-- +-- Dependencies: serport/serport_uart_rxtx_ab +-- comlib/byte2cdata +-- comlib/cdata2byte +-- memlib/fifo_1c_dram +-- +-- Test bench: tb/tb_rri_serport +-- +-- Target Devices: generic +-- Tool versions: xst 8.1, 8.2, 9.1, 9.2, 11.4; ghdl 0.18-0.26 +-- Revision History: +-- Date Rev Version Comment +-- 2010-06-06 301 2.3 use NCOMM=4 (new eop,nak commas) +-- 2010-06-03 300 2.2.1 use FAWIDTH=5 +-- 2010-05-02 287 2.2 drop RTSFLUSH generic +-- 2010-04-18 279 2.1 rewrite flow control, drop RTSFBUF generic +-- 2010-04-03 274 2.0 flow control interfaces: RTSFLUSH, CTS_N, RTS_N +-- 2007-06-24 60 1.0 Initial version +------------------------------------------------------------------------------ + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; + +use work.slvtypes.all; +use work.genlib.all; +use work.memlib.all; +use work.comlib.all; +use work.serport.all; +use work.rrilib.all; + +entity rri_serport is -- rri serport adapter + generic ( + CPREF : slv4 := "1000"; -- comma prefix + FAWIDTH : positive := 5; -- rx fifo address port width + CDWIDTH : positive := 13; -- clk divider width + CDINIT : natural := 15); -- clk divider initial/reset setting + port ( + CLK : in slbit; -- clock + CE_USEC : in slbit; -- 1 usec clock enable + CE_MSEC : in slbit; -- 1 msec clock enable + RESET : in slbit; -- reset + RXSD : in slbit; -- receive serial data (board view) + TXSD : out slbit; -- transmit serial data (board view) + CTS_N : in slbit := '0'; -- clear to send (act.low, board view) + RTS_N : out slbit; -- request to send (act.low, board view) + CP_DI : out slv9; -- comm port: data in + CP_ENA : out slbit; -- comm port: data enable + CP_BUSY : in slbit; -- comm port: data busy + CP_DO : in slv9; -- comm port: data out + CP_VAL : in slbit; -- comm port: data valid + CP_HOLD : out slbit; -- comm port: data hold + CP_FLUSH : in slbit := '0' -- comm port: data flush + ); +end rri_serport; + + +architecture syn of rri_serport is + + signal LRESET : slbit := '0'; + signal RXDATA : slv8 := (others=>'0'); + signal RXVAL : slbit := '0'; + signal TXDATA : slv8 := (others=>'0'); + signal TXENA : slbit := '0'; + signal TXBUSY : slbit := '0'; + signal ABACT : slbit := '0'; + signal FIFO_DI : slv9 := (others=>'0'); + signal FIFO_ENA : slbit := '0'; + signal FIFO_BUSY : slbit := '0'; + signal FIFO_SIZE : slv(FAWIDTH downto 0) := (others=>'0'); + signal CD2B_HOLD : slbit := '0'; + + signal R_FIFOBLOCK : slbit := '0'; -- fifo block flag + signal FLUSH_PULSE : slbit := '0'; -- rri flush as 2-3 usec pulse + + constant NCOMM : positive := 4; + +begin + + UART : serport_uart_rxtx_ab -- uart, rx+tx+autobauder combo + generic map ( + CDWIDTH => CDWIDTH, + CDINIT => CDINIT) + port map ( + CLK => CLK, + CE_MSEC => CE_MSEC, + RESET => RESET, + RXSD => RXSD, + RXDATA => RXDATA, + RXVAL => RXVAL, + RXERR => open, + RXACT => open, + TXSD => TXSD, + TXDATA => TXDATA, + TXENA => TXENA, + TXBUSY => TXBUSY, + ABACT => ABACT, + ABDONE => open + ); + + LRESET <= RESET or ABACT; + + B2CD : byte2cdata -- byte stream -> 9bit comma,data + generic map ( + CPREF => CPREF, + NCOMM => NCOMM) + port map ( + CLK => CLK, + RESET => LRESET, + DI => RXDATA, + ENA => RXVAL, + BUSY => open, + DO => FIFO_DI, + VAL => FIFO_ENA, + HOLD => FIFO_BUSY + ); + + CD2B : cdata2byte -- 9bit comma,data -> byte stream + generic map ( + CPREF => CPREF, + NCOMM => NCOMM) + port map ( + CLK => CLK, + RESET => LRESET, + DI => CP_DO, + ENA => CP_VAL, + BUSY => CP_HOLD, + DO => TXDATA, + VAL => TXENA, + HOLD => CD2B_HOLD + ); + + FIFO : fifo_1c_dram -- fifo, 1 clock, dram based + generic map ( + AWIDTH => FAWIDTH, + DWIDTH => 9) + port map ( + CLK => CLK, + RESET => LRESET, + DI => FIFO_DI, + ENA => FIFO_ENA, + BUSY => FIFO_BUSY, + DO => CP_DI, + VAL => CP_ENA, + HOLD => CP_BUSY, + SIZE => FIFO_SIZE + ); + +-- re-write later, use RB_MREQ internal init to set parameters which +-- control the flush logic. +-- +--DOFLUSH: if RTSFLUSH generate +-- +-- PGEN : timer +-- generic map ( +-- TWIDTH => 1, +-- RETRIG => true) +-- port map ( +-- CLK => CLK, +-- CE => CE_USEC, +-- DELAY => "1", +-- START => CP_FLUSH, +-- STOP => RESET, +-- BUSY => FLUSH_PULSE +-- ); +--end generate DOFLUSH; + + proc_fifoblock: process (CLK) + begin + + if CLK'event and CLK='1' then + if unsigned(FIFO_SIZE) >= 3*2**(FAWIDTH-2) then -- more than 3/4 full + R_FIFOBLOCK <= '1'; -- block + elsif unsigned(FIFO_SIZE) < 2**(FAWIDTH-1) then -- less than 1/2 full + R_FIFOBLOCK <= '0'; -- unblock + end if; + end if; + + end process proc_fifoblock; + + RTS_N <= R_FIFOBLOCK or FLUSH_PULSE; + + CD2B_HOLD <= TXBUSY or CTS_N; + +end syn; diff --git a/rtl/vlib/rri/rrilib.vhd b/rtl/vlib/rri/rrilib.vhd new file mode 100644 index 00000000..78fa58db --- /dev/null +++ b/rtl/vlib/rri/rrilib.vhd @@ -0,0 +1,259 @@ +-- $Id: rrilib.vhd 314 2010-07-09 17:38:41Z mueller $ +-- +-- Copyright 2007-2010 by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, 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 complete details. +-- +------------------------------------------------------------------------------ +-- Package Name: rrilib +-- Description: Remote Register Interface components +-- +-- Dependencies: - +-- Tool versions: xst 8.1, 8.2, 9.1, 9.2, 11.4; ghdl 0.18-0.26 +-- Revision History: +-- Date Rev Version Comment +-- 2010-06-18 306 2.5.1 rename rbus data fields to _rbf_ +-- 2010-06-06 302 2.5 use sop/eop framing instead of soc+chaining +-- 2010-06-03 300 2.1.5 use FAWIDTH=5 for rri_serport +-- 2010-05-02 287 2.1.4 ren CE_XSEC->CE_INT,RP_STAT->RB_STAT,AP_LAM->RB_LAM +-- drop RP_IINT from interfaces; drop RTSFLUSH generic +-- 2010-05-01 285 2.1.3 remove rri_rb_rpcompat, now obsolete +-- 2010-04-18 279 2.1.2 rri_core_serport: drop RTSFBUF generic +-- 2010-04-10 275 2.1.1 add rri_core_serport +-- 2010-04-03 274 2.1 add CP_FLUSH for rri_core, rri_serport; +-- CE_USEC, RTSFLUSH, CTS_N, RTS_N for rri_serport +-- 2008-08-24 162 2.0 all with new rb_mreq/rb_sres interface +-- 2008-08-22 161 1.3 renamed rri_rbres_ -> rb_sres_; drop rri_[24]rp +-- 2008-02-16 116 1.2.1 added rri_wreg(rw|w|r)_3 +-- 2008-01-20 113 1.2 added rb_[mreq|sres]; _rbres_or_*; _rb_rpcompat +-- 2007-11-24 98 1.1 added RP_IINT for rri_core. +-- 2007-09-09 81 1.0 Initial version +------------------------------------------------------------------------------ + +library ieee; +use ieee.std_logic_1164.all; + +use work.slvtypes.all; + +package rrilib is + +constant c_rri_dat_idle : slv9 := "100000000"; +constant c_rri_dat_sop : slv9 := "100000001"; +constant c_rri_dat_eop : slv9 := "100000010"; +constant c_rri_dat_nak : slv9 := "100000011"; +constant c_rri_dat_attn : slv9 := "100000100"; + +constant c_rri_cmd_rreg : slv3 := "000"; +constant c_rri_cmd_rblk : slv3 := "001"; +constant c_rri_cmd_wreg : slv3 := "010"; +constant c_rri_cmd_wblk : slv3 := "011"; +constant c_rri_cmd_stat : slv3 := "100"; +constant c_rri_cmd_attn : slv3 := "101"; +constant c_rri_cmd_init : slv3 := "110"; + +constant c_rri_iint_rbf_anena: integer := 15; -- anena flag +constant c_rri_iint_rbf_itoena: integer := 14; -- itoena flag +subtype c_rri_iint_rbf_itoval is integer range 7 downto 0; -- command code + +subtype c_rri_cmd_rbf_seq is integer range 7 downto 3; -- sequence number +subtype c_rri_cmd_rbf_code is integer range 2 downto 0; -- command code + +subtype c_rri_stat_rbf_stat is integer range 7 downto 5; -- ext status bits +constant c_rri_stat_rbf_attn: integer := 4; -- attention flags set +constant c_rri_stat_rbf_ccrc: integer := 3; -- command crc error +constant c_rri_stat_rbf_dcrc: integer := 2; -- data crc error +constant c_rri_stat_rbf_ioto: integer := 1; -- i/o time out +constant c_rri_stat_rbf_ioerr: integer := 0; -- i/o error + +type rb_mreq_type is record -- rribus - master request + req : slbit; -- request + we : slbit; -- write enable + init : slbit; -- init + addr : slv8; -- address + din : slv16; -- data (input to slave) +end record rb_mreq_type; + +constant rb_mreq_init : rb_mreq_type := + ('0','0','0', -- req, we, init + (others=>'0'), -- addr + (others=>'0')); -- din + +type rb_sres_type is record -- rribus - slave response + ack : slbit; -- acknowledge + busy : slbit; -- busy + err : slbit; -- error + dout : slv16; -- data (output from slave) +end record rb_sres_type; + +constant rb_sres_init : rb_sres_type := + ('0','0','0', -- ack, busy, err + (others=>'0')); -- dout + +component rri_core is -- rri, core interface + generic ( + ATOWIDTH : positive := 5; -- access timeout counter width + ITOWIDTH : positive := 6); -- idle timeout counter width + port ( + CLK : in slbit; -- clock + CE_INT : in slbit := '0'; -- rri ito time unit clock enable + RESET : in slbit; -- reset + CP_DI : in slv9; -- comm port: data in + CP_ENA : in slbit; -- comm port: data enable + CP_BUSY : out slbit; -- comm port: data busy + CP_DO : out slv9; -- comm port: data out + CP_VAL : out slbit; -- comm port: data valid + CP_HOLD : in slbit; -- comm port: data hold + CP_FLUSH : out slbit; -- comm port: data flush + RB_MREQ : out rb_mreq_type; -- rbus: request + RB_SRES : in rb_sres_type; -- rbus: response + RB_LAM : in slv16; -- rbus: look at me + RB_STAT : in slv3 -- rbus: status flags + ); +end component; + +component rricp_aif is -- rri comm port, abstract interface + port ( + CLK : in slbit; -- clock + CE_INT : in slbit := '0'; -- rri ito time unit clock enable + RESET : in slbit :='0'; -- reset + CP_DI : in slv9; -- comm port: data in + CP_ENA : in slbit; -- comm port: data enable + CP_BUSY : out slbit; -- comm port: data busy + CP_DO : out slv9; -- comm port: data out + CP_VAL : out slbit; -- comm port: data valid + CP_HOLD : in slbit := '0' -- comm port: data hold + ); +end component; + +component rrirp_aif is -- rri reg port, abstract interface + port ( + CLK : in slbit; -- clock + RESET : in slbit := '0'; -- reset + RB_MREQ : in rb_mreq_type; -- rbus: request + RB_SRES : out rb_sres_type; -- rbus: response + RB_LAM : out slv16; -- rbus: look at me + RB_STAT : out slv3 -- rbus: status flags + ); +end component; + +component rri_serport is -- rri serport adapter + generic ( + CPREF : slv4 := "1000"; -- comma prefix + FAWIDTH : positive := 5; -- rx fifo address port width + CDWIDTH : positive := 13; -- clk divider width + CDINIT : natural := 15); -- clk divider initial/reset setting + port ( + CLK : in slbit; -- clock + CE_USEC : in slbit; -- 1 usec clock enable + CE_MSEC : in slbit; -- 1 msec clock enable + RESET : in slbit; -- reset + RXSD : in slbit; -- receive serial data (board view) + TXSD : out slbit; -- transmit serial data (board view) + CTS_N : in slbit := '0'; -- clear to send (act.low, board view) + RTS_N : out slbit; -- request to send (act.low, board view) + CP_DI : out slv9; -- comm port: data in + CP_ENA : out slbit; -- comm port: data enable + CP_BUSY : in slbit; -- comm port: data busy + CP_DO : in slv9; -- comm port: data out + CP_VAL : in slbit; -- comm port: data valid + CP_HOLD : out slbit; -- comm port: data hold + CP_FLUSH : in slbit := '0' -- comm port: data flush + ); +end component; + +component rri_core_serport is -- rri, core+serport with cpmon+rbmon + generic ( + ATOWIDTH : positive := 5; -- access timeout counter width + ITOWIDTH : positive := 6; -- idle timeout counter width + FAWIDTH : positive := 5; -- rx fifo address port width + CDWIDTH : positive := 13; -- clk divider width + CDINIT : natural := 15); -- clk divider initial/reset setting + port ( + CLK : in slbit; -- clock + CE_USEC : in slbit; -- 1 usec clock enable + CE_MSEC : in slbit; -- 1 msec clock enable + CE_INT : in slbit := '0'; -- rri ito time unit clock enable + RESET : in slbit; -- reset + RXSD : in slbit; -- receive serial data (board view) + TXSD : out slbit; -- transmit serial data (board view) + CTS_N : in slbit := '0'; -- clear to send (act.low, board view) + RTS_N : out slbit; -- request to send (act.low, board view) + RB_MREQ : out rb_mreq_type; -- rbus: request + RB_SRES : in rb_sres_type; -- rbus: response + RB_LAM : in slv16; -- rbus: look at me + RB_STAT : in slv3 -- rbus: status flags + ); +end component; + +component rb_sres_or_2 is -- rribus result or, 2 input + port ( + RB_SRES_1 : in rb_sres_type; -- rb_sres input 1 + RB_SRES_2 : in rb_sres_type := rb_sres_init; -- rb_sres input 2 + RB_SRES_OR : out rb_sres_type -- rb_sres or'ed output + ); +end component; +component rb_sres_or_3 is -- rribus result or, 3 input + port ( + RB_SRES_1 : in rb_sres_type; -- rb_sres input 1 + RB_SRES_2 : in rb_sres_type := rb_sres_init; -- rb_sres input 2 + RB_SRES_3 : in rb_sres_type := rb_sres_init; -- rb_sres input 3 + RB_SRES_OR : out rb_sres_type -- rb_sres or'ed output + ); +end component; +component rb_sres_or_4 is -- rribus result or, 4 input + port ( + RB_SRES_1 : in rb_sres_type; -- rb_sres input 1 + RB_SRES_2 : in rb_sres_type := rb_sres_init; -- rb_sres input 2 + RB_SRES_3 : in rb_sres_type := rb_sres_init; -- rb_sres input 3 + RB_SRES_4 : in rb_sres_type := rb_sres_init; -- rb_sres input 4 + RB_SRES_OR : out rb_sres_type -- rb_sres or'ed output + ); +end component; + +component rri_wreg_rw_3 is -- rri: wide register r/w 3 bit select + generic ( + DWIDTH : positive := 16); + port ( + CLK : in slbit; -- clock + RESET : in slbit; -- reset + FADDR : slv3; -- field address + SEL : slbit; -- select + DATA : out slv(DWIDTH-1 downto 0); -- data + RB_MREQ : in rb_mreq_type; -- rribus request + RB_SRES : out rb_sres_type -- rribus response + ); +end component; + +component rri_wreg_w_3 is -- rri: wide register w-o 3 bit select + generic ( + DWIDTH : positive := 16); + port ( + CLK : in slbit; -- clock + RESET : in slbit; -- reset + FADDR : slv3; -- field address + SEL : slbit; -- select + DATA : out slv(DWIDTH-1 downto 0); -- data + RB_MREQ : in rb_mreq_type; -- rribus request + RB_SRES : out rb_sres_type -- rribus response + ); +end component; + +component rri_wreg_r_3 is -- rri: wide register r-o 3 bit select + generic ( + DWIDTH : positive := 16); + port ( + FADDR : slv3; -- field address + SEL : slbit; -- select + DATA : in slv(DWIDTH-1 downto 0); -- data + RB_SRES : out rb_sres_type -- rribus response + ); +end component; + +end rrilib; diff --git a/rtl/vlib/rri/tb/.cvsignore b/rtl/vlib/rri/tb/.cvsignore new file mode 100644 index 00000000..ccd22f92 --- /dev/null +++ b/rtl/vlib/rri/tb/.cvsignore @@ -0,0 +1,19 @@ +tb_rri_stim +tb_rri_core +tb_rri_core_[sft]sim +tb_rri_core_ISim +tb_rri_core_ISim_[sft]sim +tb_rri_serport +tb_rri_serport_[sft]sim +tb_rri_serport_ISim +tb_rri_serport_ISim_[sft]sim +tb_rritba_stim +tb_rritba_ttcombo +tb_rritba_ttcombo_[sft]sim +tb_rritba_ttcombo_ISim +tb_rritba_ttcombo_ISim_[sft]sim +tb_rriext_ttcombo +tb_rriext_ttcombo_[sft]sim +tb_rriext_fifo_rx +tb_rriext_fifo_tx +tb_rriext_conf diff --git a/rtl/vlib/rri/tb/Makefile b/rtl/vlib/rri/tb/Makefile new file mode 100644 index 00000000..ea191432 --- /dev/null +++ b/rtl/vlib/rri/tb/Makefile @@ -0,0 +1,35 @@ +# $Id: Makefile 311 2010-06-30 17:52:37Z mueller $ +# +# Revision History: +# Date Rev Version Comment +# 2009-11-21 252 1.2 add ISim support +# 2007-11-03 95 1.1.2 use .log rather .dat output in check_dsim +# 2007-09-16 83 1.1.1 add include *.o.dep_ghdl +# 2007-06-29 61 1.1 add clean and all +# 2007-06-10 51 1.0 Initial version +# +EXE_all = tb_rri_core tb_rri_serport \ + tb_rritba_ttcombo tb_rriext_ttcombo +# +# +.phony : all all_ssim all_tsim clean +# +all : $(EXE_all) +all_ssim : $(EXE_all:=_ssim) +all_tsim : $(EXE_all:=_tsim) +# +clean : ise_clean ghdl_clean isim_clean +# +#----- +# +include $(RETROBASE)/rtl/vlib/Makefile.ghdl +include $(RETROBASE)/rtl/vlib/Makefile.isim +include $(RETROBASE)/rtl/vlib/Makefile.xflow +# +VBOM_all = $(wildcard *.vbom) +# +include $(VBOM_all:.vbom=.dep_xst) +include $(VBOM_all:.vbom=.dep_ghdl) +include $(VBOM_all:.vbom=.dep_isim) +include $(wildcard *.o.dep_ghdl) +# diff --git a/rtl/vlib/rri/tb/cext_rriext.c b/rtl/vlib/rri/tb/cext_rriext.c new file mode 100644 index 00000000..714a58ca --- /dev/null +++ b/rtl/vlib/rri/tb/cext_rriext.c @@ -0,0 +1,215 @@ +/* $Id: cext_rriext.c 314 2010-07-09 17:38:41Z mueller $ + * + * Copyright 2007- by Walter F.J. Mueller + * + * This program is free software; you may redistribute and/or modify it under + * the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 2, 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 complete details. + * + * Revision History: + * Date Rev Vers Comment + * 2007-11-18 96 1.2 add 'read before write' logic to avoid deadlocks + * under cygwin broken fifo (size=1 !) implementation + * 2007-10-19 90 1.1 add trace option, controlled by setting an + * the environment variable CEXT_RRIEXT_TRACE=1 + * 2007-09-23 84 1.0 Initial version + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define CPREF 0x80 +#define CESC (CPREF|0x0f) +#define QRBUFSIZE 1024 + +static int fd_rx = -1; +static int fd_tx = -1; + +static int io_trace = 0; + +static char qr_buf[QRBUFSIZE]; +static int qr_pr = 0; +static int qr_pw = 0; +static int qr_nb = 0; +static int qr_eof = 0; +static int qr_err = EAGAIN; + +/* returns: + * <0 if error + * >=0 <=0xff normal data + * == 0x100 idle + * 0x1aahhll if side band message seen + * + */ + +/* returns + 0 if EGAIN or + */ + +static void cext_dotrace(const char *text, int dat) +{ + int i; + int mask = 0x80; + printf("cext_rriext-I: %s ", text); + for (i=0; i<8; i++) { + printf("%c", (dat&mask)?'1':'0' ); + mask >>= 1; + } + printf("\n"); +} + +static void cext_doread() +{ + char buf[1]; + ssize_t nbyte; + nbyte = read(fd_rx, buf, 1); + if (nbyte < 0) { + qr_err = errno; + } else if (nbyte == 0) { + qr_err = EAGAIN; + qr_eof = 1; + } else { + qr_err = EAGAIN; + if (qr_nb < QRBUFSIZE) { + if (io_trace) cext_dotrace("rcv8", (unsigned char) buf[0]); + qr_buf[qr_pw++] = buf[0]; + if (qr_pw >= QRBUFSIZE) qr_pw = 0; + qr_nb += 1; + } else { + printf("Buffer overflow\n"); /* FIXME: better error handling */ + } + } +} + +int cext_getbyte(int clk) +{ + char buf[1]; + ssize_t nbyte; + int irc; + int tdat; + char* env_val; + + static int odat; + static int nidle = 0; + static int ncesc = 0; + static int nside = -1; + + if (fd_rx < 0) { /* fifo's not yet opened */ + fd_rx = open("tb_rriext_fifo_rx", O_RDONLY|O_NONBLOCK); + if (fd_rx <= 0) { + perror("cext_rriext-E: failed to open tb_rriext_fifo_rx"); + return -2; + } + printf("cext_rriext-I: connected to tb_rriext_fifo_rx\n"); + fd_tx = open("tb_rriext_fifo_tx", O_WRONLY); + if (fd_tx <= 0) { + perror("cext_rriext-E: failed to open tb_rriext_fifo_tx"); + return -2; + } + printf("cext_rriext-I: connected to tb_rriext_fifo_tx\n"); + nidle = 0; + ncesc = 0; + nside = -1; + + io_trace = 0; + env_val = getenv("CEXT_RRIEXT_TRACE"); + if (env_val && strcmp(env_val, "1") == 0) { + io_trace = 1; + } + + } + + cext_doread(); + + if (qr_nb == 0) { /* no character to be processed */ + if (qr_eof != 0) { /* EOF seen */ + if (ncesc >= 2) { /* two+ CESC seen ? */ + printf("cext_rriext-I: seen EOF, wait for reconnect\n"); + close(fd_rx); + close(fd_tx); + fd_rx = -1; + fd_tx = -1; + usleep(500000); /* wait 0.5 sec */ + return 0x100; /* return idle, will reconnect */ + } + + printf("cext_rriext-I: seen EOF, schedule clock stop and exit\n"); + return -1; /* signal EOF seen */ + } else if (qr_err == EAGAIN) { /* nothing read, return idle */ + if (nidle < 8 || (nidle%1024)==0) { + irc = sched_yield(); + if (irc < 0) perror("cext_rriext-W: sched_yield failed"); + } + nidle += 1; + return 0x100; + } else { /* must be a read error */ + errno = qr_err; + perror("cext_rriext-E: read error on tb_rriext_fifo_rx"); + return -3; + } + } + + nidle = 0; + tdat = (unsigned char) qr_buf[qr_pr++]; + if (qr_pr >= QRBUFSIZE) qr_pr = 0; + qr_nb -= 1; + + if (tdat == CESC) { + ncesc += 1; + if (ncesc == 2) nside = 0; + } else { + ncesc = 0; + } + + switch (nside) { + case -1: /* normal data */ + return tdat; + case 0: /* 2nd CESC, return it */ + nside += 1; + return tdat; + case 1: /* get ADDR byte */ + nside += 1; + odat = 0x1000000 | (tdat<<16); + return 0x100; + case 2: /* get DL byte */ + nside += 1; + odat |= tdat; + return 0x100; + case 3: /* get DH byte */ + nside = -1; + odat |= tdat<<8; + return odat; + } +} + +int cext_putbyte(int dat) +{ + char buf[1]; + ssize_t nbyte; + + cext_doread(); + + if (io_trace) cext_dotrace("snd8", dat); + + buf[0] = (unsigned char) dat; + nbyte = write(fd_tx, buf, 1); + + if (nbyte < 0) { + perror("cext_rriext-E: write error on tb_rriext_fifo_tx"); + return -3; + } + + return 0; +} diff --git a/rtl/vlib/rri/tb/rritb_core.vbom b/rtl/vlib/rri/tb/rritb_core.vbom new file mode 100644 index 00000000..7962d3d5 --- /dev/null +++ b/rtl/vlib/rri/tb/rritb_core.vbom @@ -0,0 +1,12 @@ +# libs +../../slvtypes.vhd +../../simlib/simlib.vhd +../../simlib/simbus.vhd +rritblib.vhd +vhpi_rriext.vhd +# components +../../simlib/simclk.vbom +# vhpi +cext_rriext.c +# design +rritb_core.vhd diff --git a/rtl/vlib/rri/tb/rritb_core.vhd b/rtl/vlib/rri/tb/rritb_core.vhd new file mode 100644 index 00000000..6b1a1e74 --- /dev/null +++ b/rtl/vlib/rri/tb/rritb_core.vhd @@ -0,0 +1,264 @@ +-- $Id: rritb_core.vhd 314 2010-07-09 17:38:41Z mueller $ +-- +-- Copyright 2010- by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, 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 complete details. +-- +------------------------------------------------------------------------------ +-- Module Name: rritb_core - sim +-- Description: Core for a rri and cext based test bench +-- +-- Dependencies: simlib/simclk +-- +-- To test: generic, any rri/cext based target +-- +-- Target Devices: generic +-- Tool versions: xst 11.4; ghdl 0.26 +-- Revision History: +-- Date Rev Version Comment +-- 2010-06-05 301 1.1.2 renamed .rpmon -> .rbmon +-- 2010-05-02 287 1.1.1 rename config command .sdata -> .sinit; +-- use sbcntl_sbf_(cp|rp)mon defs, use rritblib; +-- 2010-04-25 283 1.1 new clk handling in proc_stim, wait period-setup +-- 2010-04-24 282 1.0 Initial version (from vlib/s3board/tb/tb_s3board) +------------------------------------------------------------------------------ + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; +use ieee.std_logic_textio.all; +use std.textio.all; + +use work.slvtypes.all; +use work.simlib.all; +use work.simbus.all; +use work.rritblib.all; +use work.vhpi_rriext.all; + +entity rritb_core is -- core of rri/cext based test bench + generic ( + CLK_PERIOD : time := 20 ns; -- clock period + CLK_OFFSET : time := 200 ns; -- clock offset (time to start clock) + SETUP_TIME : time := 5 ns; -- setup time + C2OUT_TIME : time := 10 ns); -- clock to output time + port ( + CLK : out slbit; -- main clock + RX_DATA : out slv8; -- read data (data ext->tb) + RX_VAL : out slbit; -- read data valid (data ext->tb) + RX_HOLD : in slbit; -- read data hold (data ext->tb) + TX_DATA : in slv8; -- write data (data tb->ext) + TX_ENA : in slbit -- write data enable (data tb->ext) + ); +end rritb_core; + +architecture sim of rritb_core is + + signal CLK_L : slbit := '0'; + signal CLK_STOP : slbit := '0'; + +begin + + SYSCLK : simclk + generic map ( + PERIOD => CLK_PERIOD, + OFFSET => CLK_OFFSET) + port map ( + CLK => CLK_L, + CLK_CYCLE => SB_CLKCYCLE, + CLK_STOP => CLK_STOP + ); + + CLK <= CLK_L; + + proc_conf: process + file fconf : text open read_mode is "tb_rriext_conf"; + variable iline : line; + variable oline : line; + variable ok : boolean; + variable dname : string(1 to 6) := (others=>' '); + variable ien : slbit := '0'; + variable ibit : integer := 0; + variable iaddr : slv8 := (others=>'0'); + variable idata : slv16 := (others=>'0'); + begin + + SB_CNTL <= (others=>'L'); + SB_VAL <= 'L'; + SB_ADDR <= (others=>'L'); + SB_DATA <= (others=>'L'); + + file_loop: while not endfile(fconf) loop + + readline (fconf, iline); + readcomment(iline, ok); + next file_loop when ok; + readword(iline, dname, ok); + + if ok then + case dname is + + when ".scntl" => -- .scntl + read_ea(iline, ibit); + read_ea(iline, ien); + assert (ibit>=SB_CNTL'low and ibit<=SB_CNTL'high) + report "assert bit number in range of SB_CNTL" + severity failure; + if ien = '1' then + SB_CNTL(ibit) <= 'H'; + else + SB_CNTL(ibit) <= 'L'; + end if; + + when ".cpmon" => -- .cpmon + read_ea(iline, ien); + if ien = '1' then + SB_CNTL(sbcntl_sbf_cpmon) <= 'H'; + else + SB_CNTL(sbcntl_sbf_cpmon) <= 'L'; + end if; + + when ".rbmon" => -- .rbmon + read_ea(iline, ien); + if ien = '1' then + SB_CNTL(sbcntl_sbf_rbmon) <= 'H'; + else + SB_CNTL(sbcntl_sbf_rbmon) <= 'L'; + end if; + + when ".sinit" => -- .sinit + readgen_ea(iline, iaddr, 8); + readgen_ea(iline, idata, 8); + SB_ADDR <= iaddr; + SB_DATA <= idata; + SB_VAL <= 'H'; + wait for 0 ns; + SB_VAL <= 'L'; + SB_ADDR <= (others=>'L'); + SB_DATA <= (others=>'L'); + wait for 0 ns; + + when others => -- bad command + write(oline, string'("?? unknown command: ")); + write(oline, dname); + writeline(output, oline); + report "aborting" severity failure; + end case; + else + report "failed to find command" severity failure; + end if; + + testempty_ea(iline); + + end loop; -- file_loop: + + wait; -- halt process here + + end process proc_conf; + + proc_stim: process + variable icycle : integer := 0; + variable irxint : integer := 0; + variable irxslv : slv24 := (others=>'0'); + variable ibit : integer := 0; + variable oline : line; + variable r_sb_cntl : slv16 := (others=>'Z'); + variable iaddr : slv8 := (others=>'0'); + variable idata : slv16 := (others=>'0'); + begin + + wait for CLK_OFFSET; + wait for 10*CLK_PERIOD; + + stim_loop: loop + + wait until CLK_L'event and CLK_L='1'; + wait for CLK_PERIOD-SETUP_TIME; + + SB_ADDR <= (others=>'Z'); + SB_DATA <= (others=>'Z'); + + icycle := conv_integer(unsigned(SB_CLKCYCLE)); + RX_VAL <= '0'; + + if RX_HOLD = '0' then + irxint := cext_getbyte(icycle); + if irxint >= 0 then + if irxint <= 16#ff# then -- normal data byte + RX_DATA <= conv_std_logic_vector(irxint, 8); + RX_VAL <= '1'; + elsif irxint >= 16#1000000# then -- out-of-band message + irxslv := conv_std_logic_vector(irxint, 24); + iaddr := irxslv(23 downto 16); + idata := irxslv(15 downto 0); + writetimestamp(oline, SB_CLKCYCLE, ": OOB-MSG"); + write(oline, irxslv(23 downto 16), right, 9); + write(oline, irxslv(15 downto 8), right, 9); + write(oline, irxslv( 7 downto 0), right, 9); + write(oline, string'(" : ")); + writeoct(oline, iaddr, right, 3); + writeoct(oline, idata, right, 7); + writeline(output, oline); + if unsigned(iaddr) = 0 then + ibit := conv_integer(unsigned(idata(15 downto 8))); + r_sb_cntl(ibit) := idata(0); + else + SB_ADDR <= iaddr; + SB_DATA <= idata; + SB_VAL <= '1'; + wait for 0 ns; + SB_VAL <= 'Z'; + wait for 0 ns; + end if; + end if; + elsif irxint = -1 then -- end-of-file seen + exit stim_loop; + else + report "cext_getbyte error: " & integer'image(-irxint) + severity failure; + end if; + end if; + + SB_CNTL <= r_sb_cntl; + + end loop; + + wait for 50*CLK_PERIOD; + CLK_STOP <= '1'; + + writetimestamp(oline, SB_CLKCYCLE, ": DONE "); + writeline(output, oline); + + wait; -- suspend proc_stim forever + -- clock is stopped, sim will end + + end process proc_stim; + + proc_moni: process + variable itxdata : integer := 0; + variable itxrc : integer := 0; + variable oline : line; + begin + + loop + wait until CLK_L'event and CLK_L='1'; + wait for C2OUT_TIME; + if TX_ENA = '1' then + itxdata := conv_integer(unsigned(TX_DATA)); + itxrc := cext_putbyte(itxdata); + assert itxrc=0 + report "cext_putbyte error: " & integer'image(itxrc) + severity failure; + end if; + + end loop; + + end process proc_moni; + +end sim; diff --git a/rtl/vlib/rri/tb/rritb_cpmon.vbom b/rtl/vlib/rri/tb/rritb_cpmon.vbom new file mode 100644 index 00000000..f5d41c82 --- /dev/null +++ b/rtl/vlib/rri/tb/rritb_cpmon.vbom @@ -0,0 +1,7 @@ +# libs +../../slvtypes.vhd +../../simlib/simlib.vhd +../rrilib.vhd +# components +# design +rritb_cpmon.vhd diff --git a/rtl/vlib/rri/tb/rritb_cpmon.vhd b/rtl/vlib/rri/tb/rritb_cpmon.vhd new file mode 100644 index 00000000..138782a3 --- /dev/null +++ b/rtl/vlib/rri/tb/rritb_cpmon.vhd @@ -0,0 +1,144 @@ +-- $Id: rritb_cpmon.vhd 314 2010-07-09 17:38:41Z mueller $ +-- +-- Copyright 2007-2010 by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, 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 complete details. +-- +------------------------------------------------------------------------------ +-- Module Name: rritb_cpmon - sim +-- Description: rritb: rri comm port monitor +-- +-- Dependencies: - +-- Test bench: - +-- Tool versions: xst 8.1, 8.2, 9.1, 9.2; ghdl 0.18-0.25 +-- Revision History: +-- Date Rev Version Comment +-- 2010-06-11 303 2.5.1 fix data9 assignment, always proper width now +-- 2010-06-07 302 2.5 use sop/eop framing instead of soc+chaining +-- 2008-03-24 129 1.0.1 CLK_CYCLE now 31 bits +-- 2007-09-09 81 1.0 Initial version +------------------------------------------------------------------------------ + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; +use ieee.std_logic_textio.all; +use std.textio.all; + +use work.slvtypes.all; +use work.simlib.all; +use work.rrilib.all; + +entity rritb_cpmon is -- rritb, rri comm port monitor + generic ( + DWIDTH : positive := 9); -- data port width (8 or 9) + port ( + CLK : in slbit; -- clock + CLK_CYCLE : in slv31 := (others=>'0'); -- clock cycle number + ENA : in slbit := '1'; -- enable monitor output + CP_DI : in slv(DWIDTH-1 downto 0); -- comm port: data in + CP_ENA : in slbit; -- comm port: data enable + CP_BUSY : in slbit; -- comm port: data busy + CP_DO : in slv(DWIDTH-1 downto 0); -- comm port: data out + CP_VAL : in slbit; -- comm port: data valid + CP_HOLD : in slbit -- comm port: data hold + ); +end rritb_cpmon; + + +architecture sim of rritb_cpmon is + +begin + + assert DWIDTH=8 or DWIDTH=9 + report "assert(DWIDTH=8 or DWIDTH=9)" severity failure; + + proc_cpmoni: process + variable oline : line; + variable nbusy : integer := 0; + variable nhold : integer := 0; + + procedure write_val(L: inout line; + data: in slv(DWIDTH-1 downto 0); + nwait: in integer; + txt1: in string; + txt2: in string) is + variable data9 : slv9 := (others=>'0'); + begin + + writetimestamp(L, CLK_CYCLE, txt1); + + if DWIDTH = 9 then + write(L, data(data'left), right, 1); + else + write(L, string'(" ")); + end if; + + write(L, data(7 downto 0), right, 9); + if nwait > 0 then + write(L, txt2); + write(L, nwait); + end if; + + if DWIDTH=9 and data(data'left)='1' then + -- a copy to data9 needed to allow following case construct + -- using data directly gives a 'subtype is not locally static' error + data9 := (others=>'0'); + data9(data'range) := data; + write(L, string'(" comma")); + case data9 is + when c_rri_dat_idle => write(L, string'(" idle")); + when c_rri_dat_sop => write(L, string'(" sop")); + when c_rri_dat_eop => write(L, string'(" eop")); + when c_rri_dat_nak => write(L, string'(" nak")); + when c_rri_dat_attn => write(L, string'(" attn")); + when others => null; + end case; + end if; + + writeline(output, L); + end procedure write_val; + + begin + + loop + + if ENA='0' then -- if disabled + wait until ENA='1'; -- stall process till enabled + end if; + + wait until CLK'event and CLK='1'; -- check at end of clock cycle + + if CP_ENA = '1' then + if CP_BUSY = '1' then + nbusy := nbusy + 1; + else + write_val(oline, CP_DI, nbusy, ": cprx ", " nbusy="); + nbusy := 0; + end if; + else + nbusy := 0; + end if; + + if CP_VAL = '1' then + if CP_HOLD = '1' then + nhold := nhold + 1; + else + write_val(oline, CP_DO, nhold, ": cptx ", " nhold="); + nhold := 0; + end if; + else + nhold := 0; + end if; + + end loop; + end process proc_cpmoni; + +end sim; diff --git a/rtl/vlib/rri/tb/rritb_cpmon_sb.vbom b/rtl/vlib/rri/tb/rritb_cpmon_sb.vbom new file mode 100644 index 00000000..2a07a902 --- /dev/null +++ b/rtl/vlib/rri/tb/rritb_cpmon_sb.vbom @@ -0,0 +1,9 @@ +# libs +../../slvtypes.vhd +../../simlib/simlib.vhd +../../simlib/simbus.vhd +rritblib.vhd +# components +rritb_cpmon.vbom +# design +rritb_cpmon_sb.vhd diff --git a/rtl/vlib/rri/tb/rritb_cpmon_sb.vhd b/rtl/vlib/rri/tb/rritb_cpmon_sb.vhd new file mode 100644 index 00000000..dc9c1ddd --- /dev/null +++ b/rtl/vlib/rri/tb/rritb_cpmon_sb.vhd @@ -0,0 +1,77 @@ +-- $Id: rritb_cpmon_sb.vhd 314 2010-07-09 17:38:41Z mueller $ +-- +-- Copyright 2007-2010 by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, 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 complete details. +-- +------------------------------------------------------------------------------ +-- Module Name: rritb_cpmon_sb - sim +-- Description: rritb: rri comm port monitor; simbus wrapper +-- +-- Dependencies: simbus +-- Test bench: - +-- Tool versions: xst 8.1, 8.2, 9.1, 9.2; ghdl 0.18-0.25 +-- Revision History: +-- Date Rev Version Comment +-- 2010-05-02 287 1.0.1 use sbcntl_sbf_cpmon def +-- 2007-08-25 75 1.0 Initial version +------------------------------------------------------------------------------ + +library ieee; +use ieee.std_logic_1164.all; + +use work.slvtypes.all; +use work.simlib.all; +use work.simbus.all; +use work.rritblib.all; + +entity rritb_cpmon_sb is -- simbus wrap rri comm port monitor + generic ( + DWIDTH : positive := 9; -- data port width (8 or 9) + ENAPIN : integer := sbcntl_sbf_cpmon); -- SB_CNTL signal to use for enable + port ( + CLK : in slbit; -- clock + CP_DI : in slv(DWIDTH-1 downto 0); -- comm port: data in + CP_ENA : in slbit; -- comm port: data enable + CP_BUSY : in slbit; -- comm port: data busy + CP_DO : in slv(DWIDTH-1 downto 0); -- comm port: data out + CP_VAL : in slbit; -- comm port: data valid + CP_HOLD : in slbit -- comm port: data hold + ); +end rritb_cpmon_sb; + + +architecture sim of rritb_cpmon_sb is + + signal ENA : slbit := '0'; + +begin + + assert ENAPIN>=SB_CNTL'low and ENAPIN<=SB_CNTL'high + report "assert(ENAPIN in SB_CNTL'range)" severity failure; + + ENA <= to_x01(SB_CNTL(ENAPIN)); + + CPMON : rritb_cpmon + generic map ( + DWIDTH => DWIDTH) + port map ( + CLK => CLK, + CLK_CYCLE => SB_CLKCYCLE, + ENA => ENA, + CP_DI => CP_DI, + CP_ENA => CP_ENA, + CP_BUSY => CP_BUSY, + CP_DO => CP_DO, + CP_VAL => CP_VAL, + CP_HOLD => CP_HOLD + ); + +end sim; diff --git a/rtl/vlib/rri/tb/rritb_rbmon.vbom b/rtl/vlib/rri/tb/rritb_rbmon.vbom new file mode 100644 index 00000000..c31a5544 --- /dev/null +++ b/rtl/vlib/rri/tb/rritb_rbmon.vbom @@ -0,0 +1,7 @@ +# libs +../../slvtypes.vhd +../../simlib/simlib.vhd +../rrilib.vhd +# components +# design +rritb_rbmon.vhd diff --git a/rtl/vlib/rri/tb/rritb_rbmon.vhd b/rtl/vlib/rri/tb/rritb_rbmon.vhd new file mode 100644 index 00000000..767e403a --- /dev/null +++ b/rtl/vlib/rri/tb/rritb_rbmon.vhd @@ -0,0 +1,146 @@ +-- $Id: rritb_rbmon.vhd 314 2010-07-09 17:38:41Z mueller $ +-- +-- Copyright 2007-2010 by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, 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 complete details. +-- +------------------------------------------------------------------------------ +-- Module Name: rritb_rbmon - sim +-- Description: rritb: rri rbus monitor +-- +-- Dependencies: - +-- Test bench: - +-- Tool versions: xst 8.1, 8.2, 9.1, 9.2; ghdl 0.18-0.25 +-- Revision History: +-- Date Rev Version Comment +-- 2010-06-05 301 2.1.1 renamed _rpmon -> _rbmon +-- 2010-06-03 299 2.1 new init encoding (WE=0/1 int/ext) +-- 2010-05-02 287 2.0.1 rename RP_STAT->RB_STAT,AP_LAM->RB_LAM +-- drop RP_IINT signal from interfaces +-- 2008-08-24 162 2.0 with new rb_mreq/rb_sres interface +-- 2008-03-24 129 1.2.1 CLK_CYCLE now 31 bits +-- 2007-12-23 105 1.2 added AP_LAM display +-- 2007-11-24 98 1.1 added RP_IINT support +-- 2007-08-27 76 1.0 Initial version +------------------------------------------------------------------------------ + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; +use ieee.std_logic_textio.all; +use std.textio.all; + +use work.slvtypes.all; +use work.simlib.all; +use work.rrilib.all; + +entity rritb_rbmon is -- rritb, rri rbus monitor + generic ( + DBASE : positive := 2); -- base for writing data values + port ( + CLK : in slbit; -- clock + CLK_CYCLE : in slv31 := (others=>'0'); -- clock cycle number + ENA : in slbit := '1'; -- enable monitor output + RB_MREQ : in rb_mreq_type; -- rbus: request + RB_SRES : in rb_sres_type; -- rbus: response + RB_LAM : in slv16 := (others=>'0'); -- rbus: look at me + RB_STAT : in slv3 -- rbus: status flags + ); +end rritb_rbmon; + + +architecture sim of rritb_rbmon is + +begin + + proc_rbmoni: process + variable oline : line; + variable nhold : integer := 0; + variable data : slv16 := (others=>'0'); + variable tag : string(1 to 8) := (others=>' '); + variable err : slbit := '0'; + + procedure write_data(L: inout line; + tag: in string; + data: in slv16; + nhold: in integer := 0; + cond: in boolean := false; + ctxt: in string := " ") is + begin + writetimestamp(L, CLK_CYCLE, tag); + write(L, RB_MREQ.addr, right, 10); + write(L, string'(" ")); + writegen(L, data, right, 0, DBASE); + write(L, RB_STAT, right, 4); + if nhold > 0 then + write(L, string'(" nhold=")); + write(L, nhold); + end if; + if cond then + write(L, ctxt); + end if; + writeline(output, L); + end procedure write_data; + + begin + + loop + + if ENA = '0' then -- if disabled + wait until ENA='1'; -- stall process till enabled + end if; + + wait until CLK'event and CLK='1'; -- check at end of clock cycle + + if RB_MREQ.req = '1' then + if RB_SRES.err = '1' then + err := '1'; + end if; + if RB_SRES.busy = '1' then + nhold := nhold + 1; + else + if RB_MREQ.req = '1' then + if RB_MREQ.we = '0' then + data := RB_SRES.dout; + tag := ": rbre "; + else + data := RB_MREQ.din; + tag := ": rbwe "; + end if; + end if; + + write_data(oline, tag, data, nhold, err='1', " ERR='1'"); + nhold := 0; + end if; + + else + if nhold > 0 then + write_data(oline, tag, data, nhold, true, " TIMEOUT"); + end if; + nhold := 0; + err := '0'; + end if; + + if RB_MREQ.init = '1' then -- init + if RB_MREQ.we = '1' then + write_data(oline, ": rbini ", RB_MREQ.din); -- external + else + write_data(oline, ": rbint ", RB_MREQ.din); -- internal + end if; + end if; + + if unsigned(RB_LAM) /= 0 then + write_data(oline, ": rblam ", RB_LAM, 0, true, " RB_LAM active"); + end if; + + end loop; + end process proc_rbmoni; + +end sim; diff --git a/rtl/vlib/rri/tb/rritb_rbmon_sb.vbom b/rtl/vlib/rri/tb/rritb_rbmon_sb.vbom new file mode 100644 index 00000000..3018c56a --- /dev/null +++ b/rtl/vlib/rri/tb/rritb_rbmon_sb.vbom @@ -0,0 +1,10 @@ +# libs +../../slvtypes.vhd +../../simlib/simlib.vhd +../../simlib/simbus.vhd +../rrilib.vhd +rritblib.vhd +# components +rritb_rbmon.vbom +# design +rritb_rbmon_sb.vhd diff --git a/rtl/vlib/rri/tb/rritb_rbmon_sb.vhd b/rtl/vlib/rri/tb/rritb_rbmon_sb.vhd new file mode 100644 index 00000000..718e3d08 --- /dev/null +++ b/rtl/vlib/rri/tb/rritb_rbmon_sb.vhd @@ -0,0 +1,80 @@ +-- $Id: rritb_rbmon_sb.vhd 314 2010-07-09 17:38:41Z mueller $ +-- +-- Copyright 2007-2010 by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, 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 complete details. +-- +------------------------------------------------------------------------------ +-- Module Name: rritb_rbmon_sb - sim +-- Description: rritb: rri reg port monitor; simbus wrapper +-- +-- Dependencies: simbus +-- Test bench: - +-- Tool versions: xst 8.1, 8.2, 9.1, 9.2; ghdl 0.18-0.25 +-- Revision History: +-- Date Rev Version Comment +-- 2010-06-05 301 2.0.2 renamed _rpmon -> _rbmon +-- 2010-05-02 287 2.0.1 rename RP_STAT->RB_STAT,AP_LAM->RB_LAM +-- drop RP_IINT signal from interfaces +-- use sbcntl_sbf_cpmon def +-- 2008-08-24 162 2.0 with new rb_mreq/rb_sres interface +-- 2007-12-23 105 1.2 added AP_LAM display +-- 2007-11-24 98 1.1 added RP_IINT support +-- 2007-08-27 76 1.0 Initial version +------------------------------------------------------------------------------ + +library ieee; +use ieee.std_logic_1164.all; + +use work.slvtypes.all; +use work.simlib.all; +use work.simbus.all; +use work.rrilib.all; +use work.rritblib.all; + +entity rritb_rbmon_sb is -- simbus wrap for rri rbus monitor + generic ( + DBASE : positive := 2; -- base for writing data values + ENAPIN : integer := sbcntl_sbf_rbmon); -- SB_CNTL signal to use for enable + port ( + CLK : in slbit; -- clock + RB_MREQ : in rb_mreq_type; -- rbus: request + RB_SRES : in rb_sres_type; -- rbus: response + RB_LAM : in slv16 := (others=>'0'); -- rbus: look at me + RB_STAT : in slv3 -- rbus: status flags + ); +end rritb_rbmon_sb; + + +architecture sim of rritb_rbmon_sb is + + signal ENA : slbit := '0'; + +begin + + assert ENAPIN>=SB_CNTL'low and ENAPIN<=SB_CNTL'high + report "assert(ENAPIN in SB_CNTL'range)" severity failure; + + ENA <= to_x01(SB_CNTL(ENAPIN)); + + RBMON : rritb_rbmon + generic map ( + DBASE => DBASE) + port map ( + CLK => CLK, + CLK_CYCLE => SB_CLKCYCLE, + ENA => ENA, + RB_MREQ => RB_MREQ, + RB_SRES => RB_SRES, + RB_LAM => RB_LAM, + RB_STAT => RB_STAT + ); + +end sim; diff --git a/rtl/vlib/rri/tb/rritb_sres_or_mon.vbom b/rtl/vlib/rri/tb/rritb_sres_or_mon.vbom new file mode 100644 index 00000000..04cfc42a --- /dev/null +++ b/rtl/vlib/rri/tb/rritb_sres_or_mon.vbom @@ -0,0 +1,5 @@ +# libs +../../slvtypes.vhd +../rrilib.vhd +# design +rritb_sres_or_mon.vhd diff --git a/rtl/vlib/rri/tb/rritb_sres_or_mon.vhd b/rtl/vlib/rri/tb/rritb_sres_or_mon.vhd new file mode 100644 index 00000000..7f4d0586 --- /dev/null +++ b/rtl/vlib/rri/tb/rritb_sres_or_mon.vhd @@ -0,0 +1,108 @@ +-- $Id: rritb_sres_or_mon.vhd 314 2010-07-09 17:38:41Z mueller $ +-- +-- Copyright 2010- by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, 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 complete details. +-- +------------------------------------------------------------------------------ +-- Module Name: rritb_sres_or_mon - sim +-- Description: rribus result or monitor +-- +-- Dependencies: - +-- Test bench: - +-- Tool versions: ghdl 0.29 +-- Revision History: +-- Date Rev Version Comment +-- 2010-06-26 309 1.0 Initial version +------------------------------------------------------------------------------ + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_textio.all; +use std.textio.all; + +use work.slvtypes.all; +use work.rrilib.all; + +-- ---------------------------------------------------------------------------- + +entity rritb_sres_or_mon is -- rribus result or monitor + port ( + RB_SRES_1 : in rb_sres_type; -- rb_sres input 1 + RB_SRES_2 : in rb_sres_type; -- rb_sres input 2 + RB_SRES_3 : in rb_sres_type := rb_sres_init; -- rb_sres input 3 + RB_SRES_4 : in rb_sres_type := rb_sres_init -- rb_sres input 4 + ); +end rritb_sres_or_mon; + +architecture sim of rritb_sres_or_mon is + +begin + + proc_comb : process (RB_SRES_1, RB_SRES_2, RB_SRES_3, RB_SRES_4) + constant dzero : slv16 := (others=>'0'); + variable oline : line; + variable nack : integer := 0; + variable nbusy : integer := 0; + variable nerr : integer := 0; + variable ndout : integer := 0; + begin + + nack := 0; + nbusy := 0; + nerr := 0; + ndout := 0; + + if RB_SRES_1.ack /= '0' then nack := nack + 1; end if; + if RB_SRES_2.ack /= '0' then nack := nack + 1; end if; + if RB_SRES_3.ack /= '0' then nack := nack + 1; end if; + if RB_SRES_4.ack /= '0' then nack := nack + 1; end if; + + if RB_SRES_1.busy /= '0' then nbusy := nbusy + 1; end if; + if RB_SRES_2.busy /= '0' then nbusy := nbusy + 1; end if; + if RB_SRES_3.busy /= '0' then nbusy := nbusy + 1; end if; + if RB_SRES_4.busy /= '0' then nbusy := nbusy + 1; end if; + + if RB_SRES_1.err /= '0' then nerr := nerr + 1; end if; + if RB_SRES_2.err /= '0' then nerr := nerr + 1; end if; + if RB_SRES_3.err /= '0' then nerr := nerr + 1; end if; + if RB_SRES_4.err /= '0' then nerr := nerr + 1; end if; + + if RB_SRES_1.dout /= dzero then ndout := ndout + 1; end if; + if RB_SRES_2.dout /= dzero then ndout := ndout + 1; end if; + if RB_SRES_3.dout /= dzero then ndout := ndout + 1; end if; + if RB_SRES_4.dout /= dzero then ndout := ndout + 1; end if; + + if nack>1 or nbusy>1 or nerr>1 or ndout>1 then + write(oline, now, right, 12); + if nack > 1 then + write(oline, string'(" #ack=")); + write(oline, nack); + end if; + if nbusy > 1 then + write(oline, string'(" #busy=")); + write(oline, nbusy); + end if; + if nerr > 1 then + write(oline, string'(" #err=")); + write(oline, nerr); + end if; + if ndout > 1 then + write(oline, string'(" #dout=")); + write(oline, ndout); + end if; + write(oline, string'(" FAIL in ")); + write(oline, rritb_sres_or_mon'path_name); + writeline(output, oline); + end if; + + end process proc_comb; + +end sim; diff --git a/rtl/vlib/rri/tb/rritblib.vhd b/rtl/vlib/rri/tb/rritblib.vhd new file mode 100644 index 00000000..388640ff --- /dev/null +++ b/rtl/vlib/rri/tb/rritblib.vhd @@ -0,0 +1,152 @@ +-- $Id: rritblib.vhd 314 2010-07-09 17:38:41Z mueller $ +-- +-- Copyright 2007-2010 by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, 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 complete details. +-- +------------------------------------------------------------------------------ +-- Package Name: rritblib +-- Description: Remote Register Interface test environment components +-- +-- Dependencies: - +-- Tool versions: xst 8.1, 8.2, 9.1, 9.2, 11.4; ghdl 0.18-0.29 +-- Revision History: +-- Date Rev Version Comment +-- 2010-06-26 309 2.5.1 add rritb_sres_or_mon +-- 2010-06-06 302 2.5 use sop/eop framing instead of soc+chaining +-- 2010-06-05 301 2.1.2 renamed _rpmon -> _rbmon +-- 2010-05-02 287 2.1.1 rename CE_XSEC->CE_INT,RP_STAT->RB_STAT +-- drop RP_IINT signal from interfaces +-- add sbcntl_sbf_(cp|rp)mon defs +-- 2010-04-24 282 2.1 add rritb_core +-- 2008-08-24 162 2.0 all with new rb_mreq/rb_sres interface +-- 2008-03-24 129 1.1.5 CLK_CYCLE now 31 bits +-- 2007-12-23 105 1.1.4 add AP_LAM for rritb_rpmon(_sb) +-- 2007-11-24 98 1.1.3 add RP_IINT for rritb_rpmon(_sb) +-- 2007-09-01 78 1.1.2 add rricp_rp +-- 2007-08-25 75 1.1.1 add rritb_cpmon_sb, rritb_rpmon_sb +-- 2007-08-16 74 1.1 remove rritb_tt* component; some interface changes +-- 2007-08-03 71 1.0.2 use rrirp_acif; change generics for rritb_[cr]pmon +-- 2007-07-22 68 1.0.1 add rritb_cpmon rritb_rpmon monitors +-- 2007-07-15 66 1.0 Initial version +------------------------------------------------------------------------------ + +library ieee; +use ieee.std_logic_1164.all; + +use work.slvtypes.all; +use work.rrilib.all; + +package rritblib is + +-- simbus sb_cntl field usage for rri + constant sbcntl_sbf_cpmon : integer := 15; + constant sbcntl_sbf_rbmon : integer := 14; + + +component rritb_cpmon is -- rritb, rri comm port monitor + generic ( + DWIDTH : positive := 9); -- data port width (8 or 9) + port ( + CLK : in slbit; -- clock + CLK_CYCLE : in slv31 := (others=>'0'); -- clock cycle number + ENA : in slbit := '1'; -- enable monitor output + CP_DI : in slv(DWIDTH-1 downto 0); -- comm port: data in + CP_ENA : in slbit; -- comm port: data enable + CP_BUSY : in slbit; -- comm port: data busy + CP_DO : in slv(DWIDTH-1 downto 0); -- comm port: data out + CP_VAL : in slbit; -- comm port: data valid + CP_HOLD : in slbit -- comm port: data hold + ); +end component; + +component rritb_cpmon_sb is -- simbus wrap for rri comm port monitor + generic ( + DWIDTH : positive := 9; -- data port width (8 or 9) + ENAPIN : integer := sbcntl_sbf_cpmon); -- SB_CNTL signal to use for enable + port ( + CLK : in slbit; -- clock + CP_DI : in slv(DWIDTH-1 downto 0); -- comm port: data in + CP_ENA : in slbit; -- comm port: data enable + CP_BUSY : in slbit; -- comm port: data busy + CP_DO : in slv(DWIDTH-1 downto 0); -- comm port: data out + CP_VAL : in slbit; -- comm port: data valid + CP_HOLD : in slbit -- comm port: data hold + ); +end component; + +component rritb_rbmon is -- rritb, rri rbus monitor + generic ( + DBASE : positive := 2); -- base for writing data values + port ( + CLK : in slbit; -- clock + CLK_CYCLE : in slv31 := (others=>'0'); -- clock cycle number + ENA : in slbit := '1'; -- enable monitor output + RB_MREQ : in rb_mreq_type; -- rbus: request + RB_SRES : in rb_sres_type; -- rbus: response + RB_LAM : in slv16 := (others=>'0'); -- rbus: look at me + RB_STAT : in slv3 -- rbus: status flags + ); +end component; + +component rritb_rbmon_sb is -- simbus wrap for rri rbus monitor + generic ( + DBASE : positive := 2; -- base for writing data values + ENAPIN : integer := sbcntl_sbf_rbmon); -- SB_CNTL signal to use for enable + port ( + CLK : in slbit; -- clock + RB_MREQ : in rb_mreq_type; -- rbus: request + RB_SRES : in rb_sres_type; -- rbus: response + RB_LAM : in slv16 := (others=>'0'); -- rbus: look at me + RB_STAT : in slv3 -- rbus: status flags + ); +end component; + +component rritb_sres_or_mon is -- rribus result or monitor + port ( + RB_SRES_1 : in rb_sres_type; -- rb_sres input 1 + RB_SRES_2 : in rb_sres_type; -- rb_sres input 2 + RB_SRES_3 : in rb_sres_type := rb_sres_init; -- rb_sres input 3 + RB_SRES_4 : in rb_sres_type := rb_sres_init -- rb_sres input 4 + ); +end component; + +component rritb_core is -- core of rri/cext based test bench + generic ( + CLK_PERIOD : time := 20 ns; -- clock period + CLK_OFFSET : time := 200 ns; -- clock offset (time to start clock) + SETUP_TIME : time := 5 ns; -- setup time + C2OUT_TIME : time := 10 ns); -- clock to output time + port ( + CLK : out slbit; -- main clock + RX_DATA : out slv8; -- read data (data ext->tb) + RX_VAL : out slbit; -- read data valid (data ext->tb) + RX_HOLD : in slbit; -- read data hold (data ext->tb) + TX_DATA : in slv8; -- write data (data tb->ext) + TX_ENA : in slbit -- write data enable (data tb->ext) + ); +end component; + +component rricp_rp is -- rri comm->reg port aif forwarder + -- implements rricp_aif, uses rrirp_aif + port ( + CLK : in slbit; -- clock + CE_INT : in slbit := '0'; -- rri ito time unit clock enable + RESET : in slbit :='0'; -- reset + CP_DI : in slv9; -- comm port: data in + CP_ENA : in slbit; -- comm port: data enable + CP_BUSY : out slbit; -- comm port: data busy + CP_DO : out slv9; -- comm port: data out + CP_VAL : out slbit; -- comm port: data valid + CP_HOLD : in slbit := '0' -- comm port: data hold + ); +end component; + +end rritblib; diff --git a/rtl/vlib/rri/tb/rritblib.vhd.bak b/rtl/vlib/rri/tb/rritblib.vhd.bak new file mode 100644 index 00000000..585828ea --- /dev/null +++ b/rtl/vlib/rri/tb/rritblib.vhd.bak @@ -0,0 +1,207 @@ +-- $Id: rritblib.vhd 314 2010-07-09 17:38:41Z mueller $ +-- +-- Copyright 2007-2010 by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, 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 complete details. +-- +------------------------------------------------------------------------------ +-- Package Name: rritblib +-- Description: Remote Register Interface test environment components +-- +-- Dependencies: - +-- Tool versions: xst 8.1, 8.2, 9.1, 9.2, 11.4; ghdl 0.18-0.29 +-- Revision History: +-- Date Rev Version Comment +-- 2010-06-26 309 2.5.1 add rritb_sres_or_mon +-- 2010-06-06 302 2.5 use sop/eop framing instead of soc+chaining +-- 2010-06-05 301 2.1.2 renamed _rpmon -> _rbmon +-- 2010-05-02 287 2.1.1 rename CE_XSEC->CE_INT,RP_STAT->RB_STAT +-- drop RP_IINT signal from interfaces +-- add sbcntl_sbf_(cp|rp)mon defs +-- 2010-04-24 282 2.1 add rritb_core +-- 2008-08-24 162 2.0 all with new rb_mreq/rb_sres interface +-- 2008-03-24 129 1.1.5 CLK_CYCLE now 31 bits +-- 2007-12-23 105 1.1.4 add AP_LAM for rritb_rpmon(_sb) +-- 2007-11-24 98 1.1.3 add RP_IINT for rritb_rpmon(_sb) +-- 2007-09-01 78 1.1.2 add rricp_rp +-- 2007-08-25 75 1.1.1 add rritb_cpmon_sb, rritb_rpmon_sb +-- 2007-08-16 74 1.1 remove rritb_tt* component; some interface changes +-- 2007-08-03 71 1.0.2 use rrirp_acif; change generics for rritb_[cr]pmon +-- 2007-07-22 68 1.0.1 add rritb_cpmon rritb_rpmon monitors +-- 2007-07-15 66 1.0 Initial version +------------------------------------------------------------------------------ + +library ieee; +use ieee.std_logic_1164.all; + +use work.slvtypes.all; +use work.rrilib.all; + +package rritblib is + +-- simbus sb_cntl field usage for rri + constant sbcntl_sbf_cpmon : integer := 15; + constant sbcntl_sbf_rbmon : integer := 14; + +-- GenericSimplePreProcessor Mask w11 +type rritba_cntl_type is record -- tba control + cmd : slv3; -- command code + ena : slbit; -- command enable + addr : slv8; -- address + cnt : slv8; -- block size + eop : slbit; -- end packet after current command +end record rritba_cntl_type; + +constant rritba_cntl_init : rritba_cntl_type := ( + (others=>'0'), -- cmd + '0', -- ena + (others=>'0'), -- addr + (others=>'0'), -- cnt + '0'); -- eop + +type rritba_stat_type is record -- tba status + busy : slbit; -- command busy + ack : slbit; -- command acknowledge + err : slbit; -- command error flag + stat : slv8; -- status flags + braddr : slv8; -- block read address (for wblk) + bre : slbit; -- block read enable (for wblk) + bwaddr : slv8; -- block write address (for rblk) + bwe : slbit; -- block write enable (for rblk) + attnpend : slbit; -- attn pending + attnint : slbit; -- attn interrupt +end record rritba_stat_type; + +constant rritba_stat_init : rritba_stat_type := ( + '0','0','0', -- busy, ack, err + (others=>'0'), -- stat + (others=>'0'), -- braddr + '0', -- bre + (others=>'0'), -- bwaddr + '0', -- bwe + '0','0'); -- attnpend, attnint + +component rritba is -- rritba, test bench adapter + port ( + CLK : in slbit; -- clock + RESET : in slbit; -- reset + CNTL : in rritba_cntl_type; -- control port + DI : in slv16; -- input data + STAT : out rritba_stat_type; -- status port + DO : out slv16; -- output data + CP_DI : out slv9; -- comm port: data in + CP_ENA : out slbit; -- comm port: data enable + CP_BUSY : in slbit; -- comm port: data busy + CP_DO : in slv9; -- comm port: data out + CP_VAL : in slbit; -- comm port: data valid + CP_HOLD : out slbit -- comm port: data hold + ); +end component; +-- GenericSimplePreProcessor End w11 + +component rritb_cpmon is -- rritb, rri comm port monitor + generic ( + DWIDTH : positive := 9); -- data port width (8 or 9) + port ( + CLK : in slbit; -- clock + CLK_CYCLE : in slv31 := (others=>'0'); -- clock cycle number + ENA : in slbit := '1'; -- enable monitor output + CP_DI : in slv(DWIDTH-1 downto 0); -- comm port: data in + CP_ENA : in slbit; -- comm port: data enable + CP_BUSY : in slbit; -- comm port: data busy + CP_DO : in slv(DWIDTH-1 downto 0); -- comm port: data out + CP_VAL : in slbit; -- comm port: data valid + CP_HOLD : in slbit -- comm port: data hold + ); +end component; + +component rritb_cpmon_sb is -- simbus wrap for rri comm port monitor + generic ( + DWIDTH : positive := 9; -- data port width (8 or 9) + ENAPIN : integer := sbcntl_sbf_cpmon); -- SB_CNTL signal to use for enable + port ( + CLK : in slbit; -- clock + CP_DI : in slv(DWIDTH-1 downto 0); -- comm port: data in + CP_ENA : in slbit; -- comm port: data enable + CP_BUSY : in slbit; -- comm port: data busy + CP_DO : in slv(DWIDTH-1 downto 0); -- comm port: data out + CP_VAL : in slbit; -- comm port: data valid + CP_HOLD : in slbit -- comm port: data hold + ); +end component; + +component rritb_rbmon is -- rritb, rri rbus monitor + generic ( + DBASE : positive := 2); -- base for writing data values + port ( + CLK : in slbit; -- clock + CLK_CYCLE : in slv31 := (others=>'0'); -- clock cycle number + ENA : in slbit := '1'; -- enable monitor output + RB_MREQ : in rb_mreq_type; -- rbus: request + RB_SRES : in rb_sres_type; -- rbus: response + RB_LAM : in slv16 := (others=>'0'); -- rbus: look at me + RB_STAT : in slv3 -- rbus: status flags + ); +end component; + +component rritb_rbmon_sb is -- simbus wrap for rri rbus monitor + generic ( + DBASE : positive := 2; -- base for writing data values + ENAPIN : integer := sbcntl_sbf_rbmon); -- SB_CNTL signal to use for enable + port ( + CLK : in slbit; -- clock + RB_MREQ : in rb_mreq_type; -- rbus: request + RB_SRES : in rb_sres_type; -- rbus: response + RB_LAM : in slv16 := (others=>'0'); -- rbus: look at me + RB_STAT : in slv3 -- rbus: status flags + ); +end component; + +component rritb_sres_or_mon is -- rribus result or monitor + port ( + RB_SRES_1 : in rb_sres_type; -- rb_sres input 1 + RB_SRES_2 : in rb_sres_type; -- rb_sres input 2 + RB_SRES_3 : in rb_sres_type := rb_sres_init; -- rb_sres input 3 + RB_SRES_4 : in rb_sres_type := rb_sres_init -- rb_sres input 4 + ); +end component; + +component rritb_core is -- core of rri/cext based test bench + generic ( + CLK_PERIOD : time := 20 ns; -- clock period + CLK_OFFSET : time := 200 ns; -- clock offset (time to start clock) + SETUP_TIME : time := 5 ns; -- setup time + C2OUT_TIME : time := 10 ns); -- clock to output time + port ( + CLK : out slbit; -- main clock + RX_DATA : out slv8; -- read data (data ext->tb) + RX_VAL : out slbit; -- read data valid (data ext->tb) + RX_HOLD : in slbit; -- read data hold (data ext->tb) + TX_DATA : in slv8; -- write data (data tb->ext) + TX_ENA : in slbit -- write data enable (data tb->ext) + ); +end component; + +component rricp_rp is -- rri comm->reg port aif forwarder + -- implements rricp_aif, uses rrirp_aif + port ( + CLK : in slbit; -- clock + CE_INT : in slbit := '0'; -- rri ito time unit clock enable + RESET : in slbit :='0'; -- reset + CP_DI : in slv9; -- comm port: data in + CP_ENA : in slbit; -- comm port: data enable + CP_BUSY : out slbit; -- comm port: data busy + CP_DO : out slv9; -- comm port: data out + CP_VAL : out slbit; -- comm port: data valid + CP_HOLD : in slbit := '0' -- comm port: data hold + ); +end component; + +end rritblib; diff --git a/rtl/vlib/rri/tb/tb_rri.vbom b/rtl/vlib/rri/tb/tb_rri.vbom new file mode 100644 index 00000000..0a4ff30c --- /dev/null +++ b/rtl/vlib/rri/tb/tb_rri.vbom @@ -0,0 +1,17 @@ +# Not meant for direct top level usage. Used with +# tb_rri_(core|serport|...)[_ssim].vbom and config +# lines to generate the different cases. +# +# libs +../../slvtypes.vhd +../../genlib/genlib.vhd +../../comlib/comlib.vhd +../rrilib.vhd +../../simlib/simlib.vhd +# components +../../simlib/simclk.vbom +../../genlib/clkdivce.vbom +tbd_rri_gen : tbd_rri_core.vbom +# design +tb_rri.vhd +@top:tb_rri diff --git a/rtl/vlib/rri/tb/tb_rri.vhd b/rtl/vlib/rri/tb/tb_rri.vhd new file mode 100644 index 00000000..b232779c --- /dev/null +++ b/rtl/vlib/rri/tb/tb_rri.vhd @@ -0,0 +1,720 @@ +-- $Id: tb_rri.vhd 314 2010-07-09 17:38:41Z mueller $ +-- +-- Copyright 2007-2010 by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, 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 complete details. +-- +------------------------------------------------------------------------------ +-- Module Name: tb_rri - sim +-- Description: Test bench for rri_core +-- +-- Dependencies: simlib/simclk +-- genlib/clkdivce +-- tbd_rri_gen [UUT] +-- +-- To test: rri_core +-- rri_serport +-- +-- Target Devices: generic +-- Tool versions: xst 8.1, 8.2, 9.1, 9.2, 11.4; ghdl 0.18-0.26 +-- Revision History: +-- Date Rev Version Comment +-- 2010-06-06 302 2.5 use sop/eop framing instead of soc+chaining +-- 2010-06-03 299 2.2.2 new init encoding (WE=0/1 int/ext);use sv_ prefix +-- for shared variables +-- 2010-05-02 287 2.2.1 ren CE_XSEC->CE_INT,RP_STAT->RB_STAT,AP_LAM->RB_LAM +-- drop RP_IINT signal from interfaces +-- 2010-04-03 274 2.2 add CE_USEC in tbd_rri_gen interface +-- 2009-03-14 197 2.1 remove records in interface to allow _ssim usage +-- 2008-08-24 162 2.0 with new rb_mreq/rb_sres interface +-- 2008-03-24 129 1.1.2 CLK_CYCLE now 31 bits +-- 2008-01-20 112 1.1.1 rename clkgen->clkdivce +-- 2007-11-24 98 1.1 add RP_IINT support, add checkmiss_tx to test +-- for missing responses +-- 2007-10-26 92 1.0.2 add DONE timestamp at end of execution +-- 2007-10-12 88 1.0.1 avoid ieee.std_logic_unsigned, use cast to unsigned +-- 2007-09-09 81 1.0 Initial version +------------------------------------------------------------------------------ + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; +use ieee.std_logic_textio.all; +use std.textio.all; + +use work.slvtypes.all; +use work.genlib.all; +use work.comlib.all; +use work.rrilib.all; +use work.simlib.all; + +entity tb_rri is +end tb_rri; + +architecture sim of tb_rri is + + signal CLK : slbit := '0'; + signal CE_USEC : slbit := '0'; + signal CE_MSEC : slbit := '0'; + signal RESET : slbit := '0'; + signal CP_DI : slv9 := (others=>'0'); + signal CP_ENA : slbit := '0'; + signal CP_BUSY : slbit := '0'; + signal CP_DO : slv9 := (others=>'0'); + signal CP_VAL : slbit := '0'; + signal CP_HOLD : slbit := '0'; + signal RB_MREQ_req : slbit := '0'; + signal RB_MREQ_we : slbit := '0'; + signal RB_MREQ_initt: slbit := '0'; + signal RB_MREQ_addr : slv8 := (others=>'0'); + signal RB_MREQ_din : slv16 := (others=>'0'); + signal RB_SRES_ack : slbit := '0'; + signal RB_SRES_busy : slbit := '0'; + signal RB_SRES_err : slbit := '0'; + signal RB_SRES_dout : slv16 := (others=>'0'); + signal RB_LAM : slv16 := (others=>'0'); + signal RB_STAT : slv3 := (others=>'0'); + signal TXRXACT : slbit := '0'; + + signal CLK_STOP : slbit := '0'; + signal CLK_CYCLE : slv31 := (others=>'0'); + + constant slv9_zero : slv9 := (others=>'0'); + constant slv16_zero : slv16 := (others=>'0'); + + type slv9_array_type is array (0 to 255) of slv9; + type slv16_array_type is array (0 to 255) of slv16; + + shared variable sv_rxlist : slv9_array_type := (others=>slv9_zero); + shared variable sv_nrxlist : natural := 0; + shared variable sv_rxind : natural := 0; + + constant clock_period : time := 20 ns; + constant clock_offset : time := 200 ns; + constant setup_time : time := 5 ns; + constant c2out_time : time := 10 ns; + +component tbd_rri_gen is -- rri, generic tb design interface + port ( + CLK : in slbit; -- clock + CE_INT : in slbit; -- rri ito time unit clock enable + CE_USEC : in slbit; -- 1 usec clock enable + RESET : in slbit; -- reset + CP_DI : in slv9; -- comm port: data in + CP_ENA : in slbit; -- comm port: data enable + CP_BUSY : out slbit; -- comm port: data busy + CP_DO : out slv9; -- comm port: data out + CP_VAL : out slbit; -- comm port: data valid + CP_HOLD : in slbit; -- comm port: data hold + RB_MREQ_req : out slbit; -- rbus: request - req + RB_MREQ_we : out slbit; -- rbus: request - we + RB_MREQ_initt: out slbit; -- rbus: request - init; avoid name coll + RB_MREQ_addr : out slv8; -- rbus: request - addr + RB_MREQ_din : out slv16; -- rbus: request - din + RB_SRES_ack : in slbit; -- rbus: response - ack + RB_SRES_busy : in slbit; -- rbus: response - busy + RB_SRES_err : in slbit; -- rbus: response - err + RB_SRES_dout : in slv16; -- rbus: response - dout + RB_LAM : in slv16; -- rbus: look at me + RB_STAT : in slv3; -- rbus: status flags + TXRXACT : out slbit -- txrx active flag + ); +end component; + +begin + + SYSCLK : simclk + generic map ( + PERIOD => clock_period, + OFFSET => clock_offset) + port map ( + CLK => CLK, + CLK_CYCLE => CLK_CYCLE, + CLK_STOP => CLK_STOP + ); + + CLKDIV : clkdivce + generic map ( + CDUWIDTH => 6, + USECDIV => 4, + MSECDIV => 5 + ) + port map ( + CLK => CLK, + CE_USEC => CE_USEC, + CE_MSEC => CE_MSEC + ); + + UUT : tbd_rri_gen + port map ( + CLK => CLK, + CE_INT => CE_MSEC, + CE_USEC => CE_USEC, + RESET => RESET, + CP_DI => CP_DI, + CP_ENA => CP_ENA, + CP_BUSY => CP_BUSY, + CP_DO => CP_DO, + CP_VAL => CP_VAL, + CP_HOLD => CP_HOLD, + RB_MREQ_req => RB_MREQ_req, + RB_MREQ_we => RB_MREQ_we, + RB_MREQ_initt=> RB_MREQ_initt, + RB_MREQ_addr => RB_MREQ_addr, + RB_MREQ_din => RB_MREQ_din, + RB_SRES_ack => RB_SRES_ack, + RB_SRES_busy => RB_SRES_busy, + RB_SRES_err => RB_SRES_err, + RB_SRES_dout => RB_SRES_dout, + RB_LAM => RB_LAM, + RB_STAT => RB_STAT, + TXRXACT => TXRXACT + ); + + + proc_stim: process + file fstim : text open read_mode is "tb_rri_stim"; + variable iline : line; + variable oline : line; + variable icmd : slv8 := (others=>'0'); + variable iaddr : slv8 := (others=>'0'); + variable icnt : slv8 := (others=>'0'); + variable istat : slv3 := (others=>'0'); + variable iattn : slv8 := (others=>'0'); + variable idata : slv16 := (others=>'0'); + variable ioob : slv9 := (others=>'0'); + variable ok : boolean; + variable dname : string(1 to 6) := (others=>' '); + variable idelta : integer := 0; + variable iowait : integer := 0; + variable txcrc,rxcrc : slv8 := (others=>'0'); + variable txlist : slv9_array_type := (others=>slv9_zero); + variable ntxlist : natural := 0; + + procedure do_tx8 (data : inout slv8) is + begin + txlist(ntxlist) := '0' & data; + ntxlist := ntxlist + 1; + crc8_update_tbl(txcrc, data); + end procedure do_tx8; + + procedure do_tx16 (data : inout slv16) is + begin + do_tx8(data( 7 downto 0)); + do_tx8(data(15 downto 8)); + end procedure do_tx16; + + procedure do_rx8 (data : inout slv8) is + begin + sv_rxlist(sv_nrxlist) := '0' & data; + sv_nrxlist := sv_nrxlist + 1; + crc8_update_tbl(rxcrc, data); + end procedure do_rx8; + + procedure do_rx16 (data : inout slv16) is + begin + do_rx8(data( 7 downto 0)); + do_rx8(data(15 downto 8)); + end procedure do_rx16; + + procedure checkmiss_rx is + begin + if sv_rxind < sv_nrxlist then + for i in sv_rxind to sv_nrxlist-1 loop + writetimestamp(oline, CLK_CYCLE, ": moni "); + write(oline, string'(" FAIL MISSING DATA=")); + write(oline, sv_rxlist(i)(8)); + write(oline, string'(" ")); + write(oline, sv_rxlist(i)(7 downto 0)); + writeline(output, oline); + end loop; + + end if; + end procedure checkmiss_rx; + + begin + + wait for clock_offset - setup_time; + + file_loop: while not endfile(fstim) loop + + readline (fstim, iline); + + readcomment(iline, ok); + next file_loop when ok; + + readcommand(iline, dname, ok); + if ok then + case dname is + when ".reset" => -- .reset + write(oline, string'(".reset")); + writeline(output, oline); + RESET <= '1'; + wait for clock_period; + RESET <= '0'; + wait for 9*clock_period; + + when ".wait " => -- .wait + read_ea(iline, idelta); + wait for idelta*clock_period; + + when ".iowt " => -- .iowt + read_ea(iline, iowait); + idelta := iowait; + while idelta > 0 loop -- until time has expired + if TXRXACT = '1' then -- if any io activity + idelta := iowait; -- restart timer + else + idelta := idelta - 1; -- otherwise count down time + end if; + wait for clock_period; + end loop; + + when ".stat " => -- .stat + read_ea(iline, istat); + RB_STAT <= istat; -- set ext. status lines + wait for clock_period; -- ensure some setling + + when ".attn " => -- .attn + read_ea(iline, iattn); + RB_LAM(7 downto 0) <= iattn; -- pulse lsb attn lines + wait for clock_period; -- for 1 clock + RB_LAM(7 downto 0) <= (others=>'0'); + + when ".txsop" => -- .txsop send sop + txlist(0) := c_rri_dat_sop; + ntxlist := 1; + txcrc := (others=>'0'); + when ".txeop" => -- .txeop send eop + txlist(0) := c_rri_dat_eop; + ntxlist := 1; + txcrc := (others=>'0'); + when ".txnak" => -- .txnak send nak + txlist(0) := c_rri_dat_nak; + ntxlist := 1; + txcrc := (others=>'0'); + when ".tx8 " => -- .tx8 send 8 bit value + read_ea(iline, iaddr); + ntxlist := 0; + do_tx8(iaddr); + when ".tx16 " => -- .tx16 send 16 bit value + read_ea(iline, idata); + ntxlist := 0; + do_tx16(idata); + when ".txcrc" => -- .txcrc send crc + txlist(0) := '0' & txcrc; + ntxlist := 1; + + when ".txc " => -- .txc send: cmd crc + read_ea(iline, icmd); + ntxlist := 0; + do_tx8(icmd); + txlist(ntxlist) := '0' & txcrc; + ntxlist := ntxlist + 1; + + when ".txca " => -- .txc send: cmd addr crc + read_ea(iline, icmd); + read_ea(iline, iaddr); + ntxlist := 0; + do_tx8(icmd); + do_tx8(iaddr); + txlist(ntxlist) := '0' & txcrc; + ntxlist := ntxlist + 1; + + when ".txcad" => -- .txc send: cmd addr data crc + read_ea(iline, icmd); + read_ea(iline, iaddr); + read_ea(iline, idata); + ntxlist := 0; + do_tx8(icmd); + do_tx8(iaddr); + do_tx16(idata); + txlist(ntxlist) := '0' & txcrc; + ntxlist := ntxlist + 1; + + when ".txcac" => -- .txc send: cmd addr cnt crc + read_ea(iline, icmd); + read_ea(iline, iaddr); + read_ea(iline, icnt); + ntxlist := 0; + do_tx8(icmd); + do_tx8(iaddr); + do_tx8(icnt); + txlist(ntxlist) := '0' & txcrc; + ntxlist := ntxlist + 1; + + when ".rxsop" => -- .rxsop expect sop + checkmiss_rx; + sv_rxlist(0) := c_rri_dat_sop; + sv_nrxlist := 1; + sv_rxind := 0; + rxcrc := (others=>'0'); + when ".rxeop" => -- .rxeop expect eop + sv_rxlist(sv_nrxlist) := c_rri_dat_eop; + sv_nrxlist := sv_nrxlist + 1; + when ".rxnak" => -- .rxnak expect nak + sv_rxlist(sv_nrxlist) := c_rri_dat_nak; + sv_nrxlist := sv_nrxlist + 1; + when ".rx8 " => -- .rx8 expect 8 bit value + read_ea(iline, iaddr); + do_rx8(iaddr); + when ".rx16 " => -- .rx16 expect 16 bit value + read_ea(iline, idata); + do_rx16(idata); + when ".rxcrc" => -- .rxcrc expect crc + sv_rxlist(sv_nrxlist) := '0' & rxcrc; + sv_nrxlist := sv_nrxlist+1; + + when ".rxcs " => -- .rxcs expect: cmd stat crc + read_ea(iline, icmd); + read_ea(iline, iaddr); + do_rx8(icmd); + do_rx8(iaddr); + sv_rxlist(sv_nrxlist) := '0' & rxcrc; + sv_nrxlist := sv_nrxlist + 1; + + when ".rxcds" => -- .rxcsd expect: cmd data stat crc + read_ea(iline, icmd); + read_ea(iline, idata); + read_ea(iline, iaddr); + do_rx8(icmd); + do_rx16(idata); + do_rx8(iaddr); + sv_rxlist(sv_nrxlist) := '0' & rxcrc; + sv_nrxlist := sv_nrxlist + 1; + + when ".rxccd" => -- .rxccd expect: cmd ccmd dat stat crc + read_ea(iline, icmd); + read_ea(iline, icnt); + read_ea(iline, idata); + read_ea(iline, iaddr); + do_rx8(icmd); + do_rx8(icnt); + do_rx16(idata); + do_rx8(iaddr); + sv_rxlist(sv_nrxlist) := '0' & rxcrc; + sv_nrxlist := sv_nrxlist + 1; + + when ".rxoob" => -- .rxoob expect: out-of-band symbol + read_ea(iline, ioob); + sv_rxlist(sv_nrxlist) := ioob; + sv_nrxlist := sv_nrxlist + 1; + + when others => -- bad directive + write(oline, string'("?? unknown directive: ")); + write(oline, dname); + writeline(output, oline); + report "aborting" severity failure; + end case; + + else + read_ea(iline, txlist(0)); + ntxlist := 1; + + end if; + + next file_loop when ntxlist=0; + + for i in 0 to ntxlist-1 loop + + CP_DI <= txlist(i); + CP_ENA <= '1'; + + writetimestamp(oline, CLK_CYCLE, ": stim "); + write(oline, txlist(i)(8), right, 3); + write(oline, txlist(i)(7 downto 0), right, 9); + if txlist(i)(8) = '1' then + case txlist(i) is + when c_rri_dat_idle => + write(oline, string'(" (idle)")); + when c_rri_dat_sop => + write(oline, string'(" (sop) ")); + when c_rri_dat_eop => + write(oline, string'(" (eop) ")); + when c_rri_dat_nak => + write(oline, string'(" (nak) ")); + when c_rri_dat_attn => + write(oline, string'(" (attn)")); + when others => + write(oline, string'(" (????)")); + end case; + end if; + writeline(output, oline); + + wait for clock_period; + while CP_BUSY = '1' loop + wait for clock_period; + end loop; + CP_ENA <= '0'; + + end loop; -- i + + ntxlist := 0; + + end loop; -- file fstim + + wait for 50*clock_period; + + checkmiss_rx; + writetimestamp(oline, CLK_CYCLE, ": DONE "); + writeline(output, oline); + + CLK_STOP <= '1'; + + wait; -- suspend proc_stim forever + -- clock is stopped, sim will end + + end process proc_stim; + + + proc_moni: process + variable oline : line; + begin + + loop + wait until CLK'event and CLK='1'; + wait for c2out_time; + + if CP_VAL = '1' then + writetimestamp(oline, CLK_CYCLE, ": moni "); + write(oline, CP_DO(8), right, 3); + write(oline, CP_DO(7 downto 0), right, 9); + if CP_DO(8) = '1' then + case CP_DO is + when c_rri_dat_idle => + write(oline, string'(" (idle)")); + when c_rri_dat_sop => + write(oline, string'(" (sop) ")); + when c_rri_dat_eop => + write(oline, string'(" (eop) ")); + when c_rri_dat_nak => + write(oline, string'(" (nak) ")); + when c_rri_dat_attn => + write(oline, string'(" (attn)")); + when others => + write(oline, string'(" (????)")); + end case; + end if; + if sv_nrxlist > 0 then + write(oline, string'(" CHECK")); + if sv_rxind < sv_nrxlist then + if CP_DO = sv_rxlist(sv_rxind) then + write(oline, string'(" OK")); + else + write(oline, string'(" FAIL, exp=")); + write(oline, sv_rxlist(sv_rxind)(8), right, 2); + write(oline, sv_rxlist(sv_rxind)(7 downto 0), right, 9); + end if; + sv_rxind := sv_rxind + 1; + else + write(oline, string'(" FAIL, UNEXPECTED")); + end if; + end if; + writeline(output, oline); + end if; + + end loop; + + end process proc_moni; + + +-- simulated target: +-- 00000000 ... 00111111: 64 registers, no wait states +-- 00010000 : (16) pointer register for mem 0 +-- 00010001 : (17) pointer register for mem 1 +-- 00010010 : (18) counter for init's +-- 01000000 ... 01111111: 64 registers, addr(5 downto 0)+1 wait states +-- 10000000 : 256 word memory, addressed by reg(00010000) +-- 10000001 : 256 word memory, addressed by reg(00010001) +-- 10000010 : ping RB_LAM(15 downto 8) on WE access +-- 11000000 : signal err, write noop, read 10101010 +-- others : no ack +-- + + proc_targ: process + variable reg0 : slv16_array_type := (others=>slv16_zero); + variable reg1 : slv16_array_type := (others=>slv16_zero); + variable mem0 : slv16_array_type := (others=>slv16_zero); + variable mem1 : slv16_array_type := (others=>slv16_zero); + variable iack : slbit := '0'; + variable ierr : slbit := '0'; + variable nhold : integer := 0; + variable addr : slv8 := (others=>'0'); + variable idout : slv16 := (others=>'0'); + variable ind : integer := 0; + variable oline : line; + + constant c2out_setup : time := clock_period-c2out_time-setup_time; + + type acc_type is (acc_reg0, acc_reg1, acc_mem0, acc_mem1, acc_lam, + acc_err, acc_bad); + variable acc : acc_type := acc_bad; + + procedure write_data (pref : in string; + data : in slv16; + iack : in slbit; + ierr : in slbit; + nhold : in integer) is + variable oline : line; + begin + writetimestamp(oline, CLK_CYCLE, pref); + write(oline, RB_MREQ_addr, right, 10); + write(oline, data, right, 18); + if nhold > 0 then + write(oline, string'(" nhold=")); + write(oline, nhold, right, 2); + end if; + if iack = '0' then + write(oline, string'(" ACK=0")); + end if; + if ierr = '1' then + write(oline, string'(" ERR=1")); + end if; + writeline(output, oline); + end procedure write_data; + + begin + +-- assert c2out_setup>0 report "assert(x>0)" severity FAILURE; + + wait until CLK'event and CLK='1'; + wait for c2out_time; + + RB_SRES_ack <= '0'; + RB_SRES_busy <= '0'; + RB_SRES_err <= '0'; + RB_SRES_dout <= (others=>'1'); + + addr := RB_MREQ_addr; + idout := (others=>'0'); + nhold := 0; + + acc := acc_bad; + if unsigned(addr) <= 2#00111111# then + acc := acc_reg0; + elsif unsigned(addr) <= 2#01111111# then + acc := acc_reg1; + nhold := conv_integer(unsigned(addr and "00111111")) + 1; + elsif unsigned(addr) = 2#10000000# then + acc := acc_mem0; + elsif unsigned(addr) = 2#10000001# then + acc := acc_mem1; + elsif unsigned(addr) = 2#10000010# then + acc := acc_lam; + elsif unsigned(addr) = 2#11000000# then + acc := acc_err; + end if; + + iack := '1'; + ierr := '0'; + + if acc = acc_bad then -- if bad address + iack := '0'; -- don't acknowledge + end if; + + RB_SRES_ack <= iack; + + RB_LAM(15 downto 8) <= (others=>'0'); + + if RB_MREQ_req = '1' then + + -- handle WE transactions + if RB_MREQ_we ='1' then + case acc is + when acc_reg0 => + reg0(conv_integer(unsigned(addr))) := RB_MREQ_din; + when acc_reg1 => + reg1(conv_integer(unsigned(addr))) := RB_MREQ_din; + when acc_mem0 => + ind := conv_integer(unsigned(reg0(16) and X"00ff")); + mem0(ind) := RB_MREQ_din; + reg0(16) := unsigned(reg0(16)) + 1; + when acc_mem1 => + ind := conv_integer(unsigned(reg0(17) and X"00ff")); + mem1(ind) := RB_MREQ_din; + reg0(17) := unsigned(reg0(17)) + 1; + when acc_lam => + RB_LAM(15 downto 8) <= RB_MREQ_din(15 downto 8); + writetimestamp(oline, CLK_CYCLE, + ": targ w ap_lam(15 downto 8) pinged"); + writeline(output, oline); + when acc_err => + ierr := '1'; + when others => null; + end case; + + write_data(": targ w ", RB_MREQ_din, iack, ierr, nhold); + + while nhold>0 and RB_MREQ_req='1' loop + RB_SRES_busy <= '1'; + wait for clock_period; + nhold := nhold - 1; + end loop; + RB_SRES_ack <= iack; + RB_SRES_err <= ierr; + RB_SRES_busy <= '0'; + + -- handle RE transactions + else + case acc is + when acc_reg0 => + idout := reg0(conv_integer(unsigned(addr))); + when acc_reg1 => + idout := reg1(conv_integer(unsigned(addr))); + when acc_mem0 => + ind := conv_integer(unsigned(reg0(16) and X"00ff")); + idout := mem0(ind); + reg0(16) := unsigned(reg0(16)) + 1; + when acc_mem1 => + ind := conv_integer(unsigned(reg0(17) and X"00ff")); + idout := mem1(ind); + reg0(17) := unsigned(reg0(17)) + 1; + when acc_err => + ierr := '1'; + idout := "1010101010101010"; + when acc_bad => + idout := "1010101010101010"; + when others => null; + end case; + + write_data(": targ r ", idout, iack, ierr, nhold); + + RB_SRES_dout <= "0101010101010101"; + wait for c2out_setup; + + while nhold>0 and RB_MREQ_req='1' loop + RB_SRES_busy <= '1'; + wait for clock_period; + nhold := nhold - 1; + end loop; + RB_SRES_ack <= iack; + RB_SRES_err <= ierr; + RB_SRES_busy <= '0'; + + RB_SRES_dout <= idout; + + end if; + end if; + + -- handle INIT transactions (ext and int) (just for monitoring...) + + if RB_MREQ_initt = '1' then + if RB_MREQ_we = '1' then -- ext init + write_data(": targ i ", RB_MREQ_din, '1', '0', 0); + reg0(18) := unsigned(reg0(18)) + 1; + else -- int init + write_data(": iint ", RB_MREQ_din, '1', '0', 0); + end if; + end if; + + end process proc_targ; + + +end sim; diff --git a/rtl/vlib/rri/tb/tb_rri_core.vbom b/rtl/vlib/rri/tb/tb_rri_core.vbom new file mode 100644 index 00000000..631ec130 --- /dev/null +++ b/rtl/vlib/rri/tb/tb_rri_core.vbom @@ -0,0 +1,6 @@ +# configure tb_rri with tbd_rri_core wrapper +# use vhdl configure file (tb_rri_core.vhd) at allow +# that all configurations will co-exist in work library +tbd_rri_gen = tbd_rri_core.vbom +tb_rri.vbom +tb_rri_core.vhd diff --git a/rtl/vlib/rri/tb/tb_rri_core.vhd b/rtl/vlib/rri/tb/tb_rri_core.vhd new file mode 100644 index 00000000..4cee273d --- /dev/null +++ b/rtl/vlib/rri/tb/tb_rri_core.vhd @@ -0,0 +1,44 @@ +-- $Id: tb_rri_core.vhd 314 2010-07-09 17:38:41Z mueller $ +-- +-- Copyright 2007- by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, 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 complete details. +-- +------------------------------------------------------------------------------ +-- Module Name: tb_rri_core +-- Description: Configuration for tb_rri_core for tb_rri. +-- +-- Dependencies: tbd_rri_gen +-- +-- To test: rri_core +-- +-- Target Devices: generic +-- +-- Verified (with tb_rri_stim.dat): +-- Date Rev Code ghdl ise Target Comment +-- 2007-11-02 93 _tsim 0.26 8.2.03 I34 xc3s1000 d:ok +-- 2007-10-12 88 _ssim 0.26 8.1.03 I27 xc3s1000 c:ok +-- 2007-10-12 88 - 0.26 - - c:ok +-- +-- Revision History: +-- Date Rev Version Comment +-- 2007-11-25 98 1.0.1 use entity rather arch name to switch core/serport +-- 2007-07-08 65 1.0 Initial version +------------------------------------------------------------------------------ + +configuration tb_rri_core of tb_rri is + + for sim + for all : tbd_rri_gen + use entity work.tbd_rri_core; + end for; + end for; + +end tb_rri_core; diff --git a/rtl/vlib/rri/tb/tb_rri_serport.vbom b/rtl/vlib/rri/tb/tb_rri_serport.vbom new file mode 100644 index 00000000..012cf9ec --- /dev/null +++ b/rtl/vlib/rri/tb/tb_rri_serport.vbom @@ -0,0 +1,6 @@ +# configure tb_rri with tbd_rri_serport wrapper; +# use vhdl configure file (tb_rri_serport.vhd) to allow +# that all configurations will co-exist in work library +tbd_rri_gen = tbd_rri_serport.vbom +tb_rri.vbom +tb_rri_serport.vhd diff --git a/rtl/vlib/rri/tb/tb_rri_serport.vhd b/rtl/vlib/rri/tb/tb_rri_serport.vhd new file mode 100644 index 00000000..90932802 --- /dev/null +++ b/rtl/vlib/rri/tb/tb_rri_serport.vhd @@ -0,0 +1,44 @@ +-- $Id: tb_rri_serport.vhd 314 2010-07-09 17:38:41Z mueller $ +-- +-- Copyright 2007- by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, 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 complete details. +-- +------------------------------------------------------------------------------ +-- Module Name: tb_rri_serport +-- Description: Configuration for tb_rri_serport for tb_rri. +-- +-- Dependencies: tbd_rri_gen +-- +-- To test: rri_serport +-- rri_core +-- +-- Target Devices: generic +-- +-- Verified (with tb_rri_stim.dat): +-- Date Rev Code ghdl ise Target Comment +-- 2007-10-12 88 _ssim 0.26 8.1.03 I27 xc3s1000 c:ok (Test 15 fails) +-- 2007-10-12 88 - 0.26 - - c:ok (Test 15 fails) +-- +-- Revision History: +-- Date Rev Version Comment +-- 2007-11-25 98 1.0.1 use entity rather arch name to switch core/serport +-- 2007-07-08 65 1.0 Initial version +------------------------------------------------------------------------------ + +configuration tb_rri_serport of tb_rri is + + for sim + for all : tbd_rri_gen + use entity work.tbd_rri_serport; + end for; + end for; + +end tb_rri_serport; diff --git a/rtl/vlib/rri/tb/tb_rri_stim.dat b/rtl/vlib/rri/tb/tb_rri_stim.dat new file mode 100644 index 00000000..e0c3f163 --- /dev/null +++ b/rtl/vlib/rri/tb/tb_rri_stim.dat @@ -0,0 +1,648 @@ +# $Id: tb_rri_stim.dat 311 2010-06-30 17:52:37Z mueller $ +# +# Revision History: +# Date Rev Version Comment +# 2010-06-06 302 2.0 use sop/eop framing instead of soc+chaining +# 2007-11-24 98 1.2 adapt to new internal init handling +# 2007-11-04 95 1.1 add .iowt's in Test 15 to get serport timing right +# 2007-06-17 58 1.0 Initial version +# +.wait 5 +C some non frame data first +.tx8 00000000 +.wait 5 +.tx8 00000001 +.wait 5 +.tx8 00000010 +# +.iowt 10 +C ----------------------------------------------------------------------------- +C Test 1: wreg +C wreg: tx: sop - cmd(10000,010) addr(0000) dl dh ccrc - eop +C rx: sop - cmd(010) stat crc - eop +# +.rxsop +.rxcs 10000010 00000000 +.rxeop +# +.txsop +.txcad 10000010 00000000 0011001111001100 +.txeop +# +.iowt 10 +C ----------------------------------------------------------------------------- +C Test 2: rreg +C rreg: tx: sop - cmd(10010,000) addr(0000) ccrc - eop +C rx: sop - cmd(000) dl dh stat crc - eop +# +.rxsop +.rxcds 10010000 0011001111001100 00000000 +.rxeop +# +.txsop +.txca 10010000 00000000 +.txeop +# +.iowt 10 +C ----------------------------------------------------------------------------- +C Test 3: chained wreg - wreg - rreg +C wreg: tx: sop - cmd(11001,010) addr(0001) dl dh ccrc +C wreg: tx: - cmd(11011,010) addr(0010) dl dh ccrc +C rreg: tx: - cmd(11100,000) addr(0001) ccrc +C tx: - eop +C rx: sop - cmd(010) stat crc +C rx: - cmd(010) stat crc +C rx: - cmd(000) dl dh stat crc +C rx: - eop +# +.rxsop +.rxcs 11001010 00000000 +.rxcs 11001010 00000000 +.rxcds 11100000 1111111100000001 00000000 +.rxeop +# +.txsop +.txcad 11001010 00000001 1111111100000001 +.txcad 11001010 00000010 1111111100000010 +.txca 11100000 00000001 +.txeop +# +.iowt 10 +C ----------------------------------------------------------------------------- +C Test 4: wblk - rblk +C wblk: rx: sop - cmd(10100,011) addr(10000000) cnt(8->111) ccrc dl dh .. dcrc +C rx: - eop +C rx: sop - cmd(011) stat crc +C rx: - eop +# +.rxsop +.rxcs 10100011 00000000 +.rxeop +# +.txsop +.txcac 10100011 10000000 00000111 +.tx16 0000000001000000 +.tx16 0000000001000001 +.tx16 0000000001000010 +.tx16 0000000001000011 +.tx16 0000000001000100 +.tx16 0000000001000101 +.tx16 0000000001000110 +.tx16 0000000001000111 +.txcrc +.txeop +# +.iowt 10 +C +C now check, that register 16 holds 8, clear it to prepare reread: +C rreg: tx: sop - cmd(10011,000) addr(10000) ccrc +C wreg: tx: - cmd(10000,010) addr(10000) dl dh ccrc +C tx: - eop +C rx: sop - cmd(000) dl dh stat crc +C rx: - cmd(010) stat crc +C rx: - eop +# +.rxsop +.rxcds 10011000 0000000000001000 00000000 +.rxcs 10000010 00000000 +.rxeop +# +.txsop +.txca 10011000 00010000 +.txcad 10000010 00010000 00000000000000000 +.txeop +# +.iowt 10 +C rblk: rx: sop - cmd(10110,001) addr(10000000) cnt(8->111) ccrc - eop +C rx: sop - cmd(001) cnt dl dh ... stat crc - eop +# +.rxsop +.rx8 10110001 +.rx8 00000111 +.rx16 0000000001000000 +.rx16 0000000001000001 +.rx16 0000000001000010 +.rx16 0000000001000011 +.rx16 0000000001000100 +.rx16 0000000001000101 +.rx16 0000000001000110 +.rx16 0000000001000111 +.rx8 00000000 +.rxcrc +.rxeop +# +.txsop +.txcac 10110001 10000000 00000111 +.txeop +# +.iowt 10 +C ----------------------------------------------------------------------------- +C Test 5: stat (in non-error case) re-read last cmd twice, shouldn't change +C wreg: tx: sop - cmd(00001,010) addr(0010) dl dh ccrc +C wreg: tx: - cmd(00011,010) addr(0011) dl dh ccrc +C rreg: tx: - cmd(00101,000) addr(0010) ccrc +C rreg: tx: - cmd(00111,000) addr(0011) ccrc +C stat: tx: - cmd(01001,100) ccrc +C stat: tx: - cmd(01010,100) ccrc +C tx: - eop +C rx: sop - cmd(010) stat crc +C rx: - cmd(010) stat crc +C rx: - cmd(000) dl dh stat crc +C rx: - cmd(000) dl dh stat crc +C rx: - cmd(100) ccmd (000) dl dh stat crc +C rx: - cmd(100) ccmd (000) dl dh stat crc +C rx: - eop +# +.rxsop +.rxcs 00001010 00000000 +.rxcs 00011010 00000000 +.rxcds 00101000 1000000000000010 00000000 +.rxcds 00111000 1000000100000011 00000000 +.rxccd 01001100 00111000 1000000100000011 00000000 +.rxccd 01010100 00111000 1000000100000011 00000000 +.rxeop +# +.txsop +.txcad 00001010 00000010 1000000000000010 +.txcad 00011010 00000011 1000000100000011 +.txca 00101000 00000010 +.txca 00111000 00000011 +.txc 01001100 +.txc 01010100 +.txeop +# +.iowt 10 +C ----------------------------------------------------------------------------- +C Test 6: ccrc error abort +C wreg: tx: sop - cmd(01001,010) addr(0010) dl dh ccrc +C wreg: tx: - cmd(01011,010) addr(0011) dl dh ccrc +C rreg: tx: - cmd(01101,000) addr(0010) ccrc +C rreg: tx: - cmd(01110,000) addr(0011) *BAD CRC* +C tx: - eop +C rx: sop - cmd(010) stat crc +C rx: - cmd(010) stat crc +C rx: - cmd(000) dl dh stat crc +C rx: - nak *ABORT* +C rx: - eop +# +.rxsop +.rxcs 01001010 00000000 +.rxcs 01011010 00000000 +.rxcds 01101000 1000000100001010 00000000 +.rxnak +.rxeop +# +.txsop +.txcad 01001010 00000010 1000000100001010 +.txcad 01011010 00000011 1000000100001011 +.txca 01101000 00000010 +.tx8 01110000 +.tx8 00000011 +.tx8 00000000 +.txeop +# +.iowt 10 +C +C now check that stat reflects last successfull rreg; re-read ccrc=1 sticks ! +C stat: tx: sop - cmd(10001,100) ccrc +C stat: tx: - cmd(10010,100) ccrc +C tx: - eop +C rx: - cmd(100) ccmd (000) dl dh stat crc +C rx: - cmd(100) ccmd (000) dl dh stat crc +C rx: - eop +C stat: stat(000),attn(0),ccrc(1),dcrc(0),ioto(0),ioerr(0) -> 00001000 +.rxsop +.rxccd 10001100 01101000 1000000100001010 00001000 +.rxccd 10010100 01101000 1000000100001010 00001000 +.rxeop +# +.txsop +.txc 10001100 +.txc 10010100 +.txeop +# +.iowt 10 +C ----------------------------------------------------------------------------- +C Test 7: dcrc error condition +C wreg: tx: sop - cmd(00001,010) addr(10000) dl dh ccrc +C wblk: rx: - cmd(00011,011) addr(10000000) cnt(4->011) ccrc dl dh .. +C *BAD CRC* +C rx: - eop +C rx: sop - cmd(010) stat crc +C rx: - cmd(011) stat crc +C rx: - eop +C stat: stat(000),attn(0),ccrc(0),dcrc(1),ioto(0),ioerr(0) -> 00000100 +# +.rxsop +.rxcs 00001010 00000000 +.rxcs 00010011 00000100 +.rxeop +# +.txsop +.txcad 00001010 00010000 00000000000000000 +.txcac 00010011 10000000 00000011 +.tx16 0001000001000000 +.tx16 0001000001000001 +.tx16 0001000001000010 +.tx16 0001000001000011 +.tx8 00000000 +.txeop +# +.iowt 10 +C +C now check that stat reflects bad dcrc: re-read dcrc=1 sticks ! +C stat: tx: sop - cmd(00101,100) ccrc +C stat: tx: - cmd(00110,100) ccrc +C tx: - eop +C rx: - cmd(100) ccmd (000) dl dh stat crc +C rx: - cmd(100) ccmd (000) dl dh stat crc +C rx: - eop +C stat: stat(000),attn(0),ccrc(0),dcrc(1),ioto(0),ioerr(0) -> 00000100 +C Note: dl,dh still the last read of Test 6 !! +.rxsop +.rxccd 00101100 00010011 1000000100001010 00000100 +.rxccd 00110100 00010011 1000000100001010 00000100 +.rxeop +# +.txsop +.txc 00101100 +.txc 00110100 +.txeop +# +.iowt 10 +C ----------------------------------------------------------------------------- +C Test 8: err(bad address) condition; 11000000 is an address returning err=1 +C rreg: tx: sop - cmd(00001,000) addr(00010000) ccrc +C rreg: tx: - cmd(00011,000) addr(11000000) ccrc +C wreg: tx: - cmd(00101,010) addr(00010000) dl dh ccrc +C wreg: tx: - cmd(00110,010) addr(11000000) dl dh ccrc +C tx: - eop +C Note: the rreg(10000) will return 4, the prt after the last wblk ! +C Note: tb returns 1010101010101010 for access to bad addresses +C stat: stat(000),attn(0),ccrc(0),dcrc(0),ioto(0),ioerr(1) -> 00000001 +# +.rxsop +.rxcds 00001000 0000000000000100 00000000 +.rxcds 00011000 1010101010101010 00000001 +.rxcs 00101010 00000000 +.rxcs 00110010 00000001 +.rxeop +# +.txsop +.txca 00001000 00010000 +.txca 00011000 11000000 +.txcad 00101010 00010000 0000000000000000 +.txcad 00110010 11000000 1000111110001111 +.txeop +# +.iowt 10 +C ----------------------------------------------------------------------------- +C Test 9: to(time out) condition; 01bbbbbb addressed take n+1 hold states +C wreg: tx: sop - cmd(00001,010) addr(01000000) dl dh ccrc (nh=1) +C wreg: tx: - cmd(00011,010) addr(01001111) dl dh ccrc (nh=16) +C wreg: tx: - cmd(00101,010) addr(01011101) dl dh ccrc (nh=30) +C wreg: tx: - cmd(00111,010) addr(01011110) dl dh ccrc (nh=31) +C wreg: tx: - cmd(01001,010) addr(01011111) dl dh ccrc (nh=32) TO +C wreg: tx: - cmd(01011,010) addr(01100000) dl dh ccrc (nh=33) TO +C wreg: tx: - cmd(01101,010) addr(01111111) dl dh ccrc (nh=64) TO +C wreg: tx: - cmd(01110,010) addr(01000001) dl dh ccrc (nh=2) +C tx: - eop +C stat: stat(000),attn(0),ccrc(0),dcrc(0),ioto(1),ioerr(0) -> 00000010 +# +.rxsop +.rxcs 00001010 00000000 +.rxcs 00011010 00000000 +.rxcs 00101010 00000000 +.rxcs 00111010 00000000 +.rxcs 01001010 00000010 +.rxcs 01011010 00000010 +.rxcs 01101010 00000010 +.rxcs 01110010 00000000 +.rxeop +# +.txsop +.txcad 00001010 01000000 0000000001000000 +.txcad 00011010 01001111 0000000001001111 +.txcad 00101010 01011101 0000000001011101 +.txcad 00111010 01011110 0000000001011110 +.txcad 01001010 01011111 0000000001011111 +.txcad 01011010 01100000 0000000001100000 +.txcad 01101010 01111110 0000000001111111 +.txcad 01110010 01000001 0000000001000001 +.txeop +.iowt 10 +C +C now same with rreg +C rreg: tx: sop - cmd(00001,000) addr(01000000) ccrc (nh=1) +C rreg: tx: - cmd(00011,000) addr(01001111) ccrc (nh=16) +C rreg: tx: - cmd(00101,000) addr(01011101) ccrc (nh=30) +C rreg: tx: - cmd(00111,000) addr(01011110) ccrc (nh=31) +C rreg: tx: - cmd(01001,000) addr(01011111) ccrc (nh=32) TO +C rreg: tx: - cmd(01011,000) addr(01100000) ccrc (nh=33) TO +C rreg: tx: - cmd(01101,000) addr(01111111) ccrc (nh=64) TO +C rreg: tx: - cmd(01110,000) addr(01000001) ccrc (nh=2) +C tx: - eop +C Note: tb returns 0101010101010101 for timeout +# +.rxsop +.rxcds 00001000 0000000001000000 00000000 +.rxcds 00011000 0000000001001111 00000000 +.rxcds 00101000 0000000001011101 00000000 +.rxcds 00111000 0000000001011110 00000000 +.rxcds 01001000 0101010101010101 00000010 +.rxcds 01011000 0101010101010101 00000010 +.rxcds 01101000 0101010101010101 00000010 +.rxcds 01110000 0000000001000001 00000000 +.rxeop +# +.txsop +.txca 00001000 01000000 +.txca 00011000 01001111 +.txca 00101000 01011101 +.txca 00111000 01011110 +.txca 01001000 01011111 +.txca 01011000 01100000 +.txca 01101000 01111110 +.txca 01110000 01000001 +.txeop +# +.iowt 10 +C ----------------------------------------------------------------------------- +C Test 10: external init command +C rreg: tx: sop - cmd(00001,000) addr(00010010) ccrc +C init: tx: - cmd(00011,110) addr(10000111) dl dh ccrc +C rreg: tx: - cmd(00100,000) addr(00010010) ccrc +C tx: - eop +C rx: sop - cmd(000) dl dh stat crc +C rx: - cmd(110) stat crc +C rx: - cmd(000) dl dh stat crc +C rx: - eop +# +.rxsop +.rxcds 00001000 0000000000000000 00000000 +.rxcs 00011110 00000000 +.rxcds 00100000 0000000000000001 00000000 +.rxeop +# +.txsop +.txca 00001000 00010010 +.txcad 00011110 10000111 0000111000111000 +.txca 00100000 00010010 +.txeop +# +.iowt 10 +C ----------------------------------------------------------------------------- +C Test 11: external status bit (RP_STAT) +C Note: stat bits are not latched for stat command ! +C stat <= "001" +C rreg: tx: sop - cmd(00000,000) addr(00010010) ccrc - eop +C rx: sop - cmd(000) dl dh stat crc - eop +# +.rxsop +.rxcds 00000000 0000000000000001 00100000 +.rxeop +# +.stat 001 +.txsop +.txca 00000000 00010010 +.txeop +# +.iowt 10 +C stat <= "010" +C stat: tx: sop - cmd(00011,100) ccrc +C rreg: tx: - cmd(00100,000) addr(00010010) ccrc +C tx: - eop +C rx: sop - cmd(100) ccmd (000) dl dh stat crc +C rx: - cmd(000) dl dh stat crc +C rx: - eop +C Note: stat command returns old 001 status +C rreg command returns new 010 status +.rxsop +.rxccd 00011100 00000000 0000000000000001 00100000 +.rxcds 00010000 0000000000000001 01000000 +.rxeop +# +.stat 010 +.txsop +.txc 00011100 +.txca 00010000 00010010 +.txeop +# +C stat <= "100" +C rreg: tx: sop - cmd(00110,000) addr(00010010) ccrc - eop +C rx: sop - cmd(000) dl dh stat crc - eop +C stat <= '000' +.iowt 10 +# +.rxsop +.rxcds 00110000 0000000000000001 10000000 +.rxeop +# +.stat 100 +.txsop +.txca 00110000 00010010 +.txeop +# +.iowt 10 +.stat 000 +C ----------------------------------------------------------------------------- +C Test 12: attention logic +C attn <= "0000000000000100" (async case) +C rreg: tx: sop - cmd(01001,000) addr(00010010) ccrc +C attn: tx: - cmd(01011,101) ccrc +C attn: tx: - cmd(01101,101) ccrc +C rreg: tx: - cmd(01110,000) addr(00010010) ccrc +C tx: - eop +C Note: the rreg command returns attn=1 +C the attn has attn=0, because stat is evaluated after read+clear !! +C stat: stat(000),attn(1),ccrc(0),dcrc(0),ioto(0),ioerr(0) -> 00010000 +# +.rxsop +.rxcds 01001000 0000000000000001 00010000 +.rxcds 01011101 0000000000000100 00000000 +.rxcds 01101101 0000000000000000 00000000 +.rxcds 01110000 0000000000000001 00000000 +.rxeop +# +.wait 5 +.attn 00000100 +.wait 5 +.txsop +.txca 01001000 00010010 +.txc 01011101 +.txc 01101101 +.txca 01110000 00010010 +.txeop +# +.iowt 10 +C +C now test sync case, the transaction causes the attention +C a write to 10000010 causes AP_LAM(15 downto 8) be pinged with RP_DO data +C wreg: tx: sob - cmd(10001,010) addr(10000010) dl dh ccrc +C rreg: tx: - cmd(10011,000) addr(00010010) ccrc +C attn: tx: - cmd(10101,101) ccrc +C attn: tx: - cmd(10111,101) ccrc +C rreg: tx: - cmd(11000,000) addr(00010010) ccrc +C tx: - eop +.rxsop +.rxcs 10001010 00010000 +.rxcds 10011000 0000000000000001 00010000 +.rxcds 10101101 0000000100000000 00000000 +.rxcds 10111101 0000000000000000 00000000 +.rxcds 11000000 0000000000000001 00000000 +.rxeop +# +.txsop +.txcad 10001010 10000010 0000000100000000 +.txca 10011000 00010010 +.txc 10101101 +.txc 10111101 +.txca 11000000 00010010 +.txeop +# +.iowt 10 +C ----------------------------------------------------------------------------- +C Test 13: verify that extra 'idle' commas are tolerated +C do wreg+rreg, with "100000000" between bytes +C use as data 1000000 and 10000001 to force escaping here +C wreg: tx: sop - cmd(00001,010) addr(0000) dl dh ccrc +C rreg: tx: sop - cmd(00010,000) addr(0000) ccrc +C tx: - eop +C rx: sop - cmd(010) stat crc +C rx: sop - cmd(000) dl dh stat crc +C rx: - eop +# +.rxsop +.rxcs 00001010 00000000 +.rxcds 00010000 1000000010000001 00000000 +.rxeop +# +100000000 +.txsop +100000000 +.tx8 00001010 +100000000 +.tx8 00000000 +100000000 +.tx8 10000001 +100000000 +100000000 +.tx8 10000000 +100000000 +.txcrc +100000000 +.tx8 00010000 +100000000 +100000000 +100000000 +.tx8 00000000 +100000000 +.txcrc +.txeop +# +.iowt 10 +C ----------------------------------------------------------------------------- +C Test 14: enable and test asynchronous attn notification +C init: tx: sob - cmd(00000,110) addr(00000001) dl dh ccrc - eop +C init: anena(1), itoena(0), ito(0) -> 11111111,1000000000000000 +# +.rxsop +.rxcs 00000110 00000000 +.rxeop +# +.txsop +.txcad 00000110 11111111 1000000000000000 +.txeop +.iowt 10 +# +C now ping an attention line, expect oob attn symbol +.wait 50 +.rxoob 100000100 +.attn 00000001 +.iowt 10 +C finally read attn flags +C attn: tx: - cmd(00010,101) ccrc - eop +.rxsop +.rxcds 00010101 0000000000000001 00000000 +.rxeop +# +.txsop +.txc 00010101 +.txeop +# +.iowt 10 +C ----------------------------------------------------------------------------- +C Test 15: enable and test idle timeout +C init: tx: sob - cmd(00100,110) addr(00000011) dl dh ccrc - eop +C init: anena(1), itoena(1), ito(9) -> 11111111,1100000000001001 +C ito=9 --> divider=10; ce_xsec div is 1:20 --> total every 200 cycles +# +.rxsop +.rxcs 00100110 00000000 +.rxeop +.rxoob 100000000 +.rxoob 100000000 +.rxoob 100000100 +.rxoob 100000100 +.rxoob 100000100 +# +.txsop +.txcad 00100110 11111111 1100000000001001 +.txeop +# +.iowt 10 +C total ito now 200 cycles; wait 500 cycles, see 2 idle symbols +.wait 500 +C ping an attention line, expect oob attn symbol +.attn 00000010 +.iowt 10 +C wait 500 more cycles, see 2 attn symbols +.wait 500 +C finally read attn flags +C attn: tx: - cmd(00110,101) ccrc - eop +.rxsop +.rxcds 00110101 0000000000000010 00000000 +.rxeop +# +.txsop +.txc 00110101 +.txeop +# +.iowt 10 +C wait 500 more cycles, see 2 idle symbols again +.rxoob 100000000 +.rxoob 100000000 +.wait 500 +C finally disable attn notification and idle timeout again +C init: tx: sob - cmd(00000,110) addr(00000000) dl dh ccrc - eop +C init: anena(0), itoena(0), ito(0) -> 11111111,0000000000000000 +# +.rxsop +.rxcs 00000110 00000000 +.rxeop +# +.txsop +.txcad 00000110 11111111 0000000000000000 +.txeop +# +.iowt 10 +C ----------------------------------------------------------------------------- +C Test 16: attn poll +# +C send 2 attn, expect two idles back +.rxoob 100000000 +.rxoob 100000000 +100000100 +100000100 +.iowt 10 +# +C ping an attention line +.attn 00000010 +# +C send 2 attn, expect two attn back +.rxoob 100000100 +.rxoob 100000100 +100000100 +100000100 +.iowt 10 +# diff --git a/rtl/vlib/rri/tb/tbd_rri_core.vbom b/rtl/vlib/rri/tb/tbd_rri_core.vbom new file mode 100644 index 00000000..4fc65d6e --- /dev/null +++ b/rtl/vlib/rri/tb/tbd_rri_core.vbom @@ -0,0 +1,7 @@ +# libs +../../slvtypes.vhd +../rrilib.vhd +# components +../rri_core.vbom +# design +tbd_rri_core.vhd diff --git a/rtl/vlib/rri/tb/tbd_rri_core.vhd b/rtl/vlib/rri/tb/tbd_rri_core.vhd new file mode 100644 index 00000000..abb20432 --- /dev/null +++ b/rtl/vlib/rri/tb/tbd_rri_core.vhd @@ -0,0 +1,126 @@ +-- $Id: tbd_rri_core.vhd 314 2010-07-09 17:38:41Z mueller $ +-- +-- Copyright 2007-2010 by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, 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 complete details. +-- +------------------------------------------------------------------------------ +-- Module Name: tbd_rri_core - syn +-- Description: Wrapper for rri_core to avoid records. It has a port +-- interface which will not be modified by xst synthesis +-- (no records, no generic port). +-- +-- Dependencies: rri_core +-- +-- To test: rri_core +-- +-- Target Devices: generic +-- +-- Synthesized (xst): +-- Date Rev ise Target flop lutl lutm slic t peri +-- 2007-11-24 92 8.1.03 I27 xc3s1000-4 143 309 0 166 s 7.64 +-- 2007-10-27 92 9.2.02 J39 xc3s1000-4 148 320 0 - t 8.34 +-- 2007-10-27 92 9.1 J30 xc3s1000-4 148 315 0 - t 8.34 +-- 2007-10-27 92 8.2.03 I34 xc3s1000-4 153 302 0 162 s 7.65 +-- 2007-10-27 92 8.1.03 I27 xc3s1000-4 138 306 0 - s 7.64 +-- +-- Tool versions: xst 8.1, 8.2, 9.1, 9.2, 11.4; ghdl 0.18-0.26 +-- Revision History: +-- Date Rev Version Comment +-- 2010-05-02 287 2.2.1 ren CE_XSEC->CE_INT,RP_STAT->RB_STAT,AP_LAM->RB_LAM +-- drop RP_IINT signal from interfaces +-- 2010-04-03 274 2.2 add CP_FLUSH for rri_core, add CE_USEC +-- 2009-03-14 197 2.1 remove records in interface to allow _ssim usage +-- 2008-08-24 162 2.0 with new rb_mreq/rb_sres interface +-- 2007-11-25 98 1.1 added RP_IINT support; use entity rather arch +-- name to switch core/serport +-- 2007-07-02 63 1.0 Initial version +------------------------------------------------------------------------------ + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; + +use work.slvtypes.all; +use work.rrilib.all; + +entity tbd_rri_core is -- rri_core tb design + -- generic: ATOWIDTH=5; ITOWIDTH=6 + -- implements tbd_rri_gen + port ( + CLK : in slbit; -- clock + CE_INT : in slbit; -- rri ito time unit clock enable + CE_USEC : in slbit; -- 1 usec clock enable + RESET : in slbit; -- reset + CP_DI : in slv9; -- comm port: data in + CP_ENA : in slbit; -- comm port: data enable + CP_BUSY : out slbit; -- comm port: data busy + CP_DO : out slv9; -- comm port: data out + CP_VAL : out slbit; -- comm port: data valid + CP_HOLD : in slbit; -- comm port: data hold + RB_MREQ_req : out slbit; -- rbus: request - req + RB_MREQ_we : out slbit; -- rbus: request - we + RB_MREQ_initt : out slbit; -- rbus: request - init; avoid name coll + RB_MREQ_addr : out slv8; -- rbus: request - addr + RB_MREQ_din : out slv16; -- rbus: request - din + RB_SRES_ack : in slbit; -- rbus: response - ack + RB_SRES_busy : in slbit; -- rbus: response - busy + RB_SRES_err : in slbit; -- rbus: response - err + RB_SRES_dout : in slv16; -- rbus: response - dout + RB_LAM : in slv16; -- rbus: look at me + RB_STAT : in slv3; -- rbus: status flags + TXRXACT : out slbit -- txrx active flag + ); +end entity tbd_rri_core; + + +architecture syn of tbd_rri_core is + + signal CP_FLUSH : slbit := '0'; + signal RB_MREQ : rb_mreq_type := rb_mreq_init; + signal RB_SRES : rb_sres_type := rb_sres_init; + +begin + + RB_MREQ_req <= RB_MREQ.req; + RB_MREQ_we <= RB_MREQ.we; + RB_MREQ_initt<= RB_MREQ.init; + RB_MREQ_addr <= RB_MREQ.addr; + RB_MREQ_din <= RB_MREQ.din; + + RB_SRES.ack <= RB_SRES_ack; + RB_SRES.busy <= RB_SRES_busy; + RB_SRES.err <= RB_SRES_err; + RB_SRES.dout <= RB_SRES_dout; + + UUT : rri_core + generic map ( + ATOWIDTH => 5, + ITOWIDTH => 6) + port map ( + CLK => CLK, + CE_INT => CE_INT, + RESET => RESET, + CP_DI => CP_DI, + CP_ENA => CP_ENA, + CP_BUSY => CP_BUSY, + CP_DO => CP_DO, + CP_VAL => CP_VAL, + CP_HOLD => CP_HOLD, + CP_FLUSH => CP_FLUSH, + RB_MREQ => RB_MREQ, + RB_SRES => RB_SRES, + RB_LAM => RB_LAM, + RB_STAT => RB_STAT + ); + + TXRXACT <= '0'; + +end syn; diff --git a/rtl/vlib/rri/tb/tbd_rri_serport.vbom b/rtl/vlib/rri/tb/tbd_rri_serport.vbom new file mode 100644 index 00000000..151f2685 --- /dev/null +++ b/rtl/vlib/rri/tb/tbd_rri_serport.vbom @@ -0,0 +1,13 @@ +# libs +../../slvtypes.vhd +../../comlib/comlib.vhd +../../serport/serport.vhd +../rrilib.vhd +# components +tbu_rri_serport : tbu_rri_serport.vbom +../../serport/serport_uart_tx.vbom +../../serport/serport_uart_rx.vbom +../../comlib/byte2cdata.vbom +../../comlib/cdata2byte.vbom +# design +tbd_rri_serport.vhd diff --git a/rtl/vlib/rri/tb/tbd_rri_serport.vhd b/rtl/vlib/rri/tb/tbd_rri_serport.vhd new file mode 100644 index 00000000..4e9f202f --- /dev/null +++ b/rtl/vlib/rri/tb/tbd_rri_serport.vhd @@ -0,0 +1,246 @@ +-- $Id: tbd_rri_serport.vhd 314 2010-07-09 17:38:41Z mueller $ +-- +-- Copyright 2007-2010 by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, 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 complete details. +-- +------------------------------------------------------------------------------ +-- Module Name: tbd_rri_serport - syn +-- Description: Wrapper for rri_core plus rri_serport with an interface +-- compatible to the rri_core only module. +-- NOTE: this implementation is a hack, should be redone +-- using configurations. +-- +-- Dependencies: tbu_rri_serport [UUT] +-- serport_uart_tx +-- serport_uart_rx +-- byte2cdata +-- cdata2byte +-- +-- To test: rri_serport +-- +-- Target Devices: generic +-- Tool versions: xst 8.1, 8.2, 9.1, 9.2; ghdl 0.18-0.25 +-- Revision History: +-- Date Rev Version Comment +-- 2010-06-06 301 2.3 use NCOMM=4 (new eop,nak commas) +-- 2010-05-02 287 2.2.2 ren CE_XSEC->CE_INT,RP_STAT->RB_STAT,AP_LAM->RB_LAM +-- drop RP_IINT signal from interfaces +-- 2010-04-24 281 2.2.1 use serport_uart_[tr]x directly again +-- 2010-04-03 274 2.2 add CE_USEC +-- 2009-03-14 197 2.1 remove records in interface to allow _ssim usage +-- 2008-08-24 162 2.0 with new rb_mreq/rb_sres interface +-- 2007-11-25 98 1.1 added RP_IINT support; use entity rather arch +-- name to switch core/serport; +-- use serport_uart_[tr]x_tb to allow that UUT is a +-- [sft]sim model compiled with keep hierarchy +-- 2007-07-02 63 1.0 Initial version +------------------------------------------------------------------------------ + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; +-- synthesis translate_off +use ieee.std_logic_textio.all; +use std.textio.all; +-- synthesis translate_on + +use work.slvtypes.all; +use work.rrilib.all; +use work.comlib.all; +use work.serport.all; + +entity tbd_rri_serport is -- rri_core+rri_serport tb design + -- implements tbd_rri_gen + port ( + CLK : in slbit; -- clock + CE_INT : in slbit; -- rri ito time unit clock enable + CE_USEC : in slbit; -- 1 usec clock enable + RESET : in slbit; -- reset + CP_DI : in slv9; -- comm port: data in + CP_ENA : in slbit; -- comm port: data enable + CP_BUSY : out slbit; -- comm port: data busy + CP_DO : out slv9; -- comm port: data out + CP_VAL : out slbit; -- comm port: data valid + CP_HOLD : in slbit; -- comm port: data hold + RB_MREQ_req : out slbit; -- rbus: request - req + RB_MREQ_we : out slbit; -- rbus: request - we + RB_MREQ_initt : out slbit; -- rbus: request - init; avoid name coll + RB_MREQ_addr : out slv8; -- rbus: request - addr + RB_MREQ_din : out slv16; -- rbus: request - din + RB_SRES_ack : in slbit; -- rbus: response - ack + RB_SRES_busy : in slbit; -- rbus: response - busy + RB_SRES_err : in slbit; -- rbus: response - err + RB_SRES_dout : in slv16; -- rbus: response - dout + RB_LAM : in slv16; -- rbus: look at me + RB_STAT : in slv3; -- rbus: status flags + TXRXACT : out slbit -- txrx active flag + ); +end entity tbd_rri_serport; + + +architecture syn of tbd_rri_serport is + + signal RRI_RXSD : slbit := '0'; + signal RRI_TXSD : slbit := '0'; + signal RXDATA : slv8 := (others=>'0'); + signal RXVAL : slbit := '0'; + signal RXACT : slbit := '0'; + signal TXDATA : slv8 := (others=>'0'); + signal TXENA : slbit := '0'; + signal TXBUSY : slbit := '0'; + signal CLKDIV : slv13 := conv_std_logic_vector(1,13); + -- NOTE: change also CDINIT in tbu_rri_serport !! + +component tbu_rri_serport is -- rri core+serport combo + port ( + CLK : in slbit; -- clock + CE_INT : in slbit; -- rri ito time unit clock enable + CE_USEC : in slbit; -- 1 usec clock enable + CE_MSEC : in slbit; -- 1 msec clock enable + RESET : in slbit; -- reset + RXSD : in slbit; -- receive serial data (uart view) + TXSD : out slbit; -- transmit serial data (uart view) + RB_MREQ_req : out slbit; -- rbus: request - req + RB_MREQ_we : out slbit; -- rbus: request - we + RB_MREQ_initt : out slbit; -- rbus: request - init; avoid name coll + RB_MREQ_addr : out slv8; -- rbus: request - addr + RB_MREQ_din : out slv16; -- rbus: request - din + RB_SRES_ack : in slbit; -- rbus: response - ack + RB_SRES_busy : in slbit; -- rbus: response - busy + RB_SRES_err : in slbit; -- rbus: response - err + RB_SRES_dout : in slv16; -- rbus: response - dout + RB_LAM : in slv16; -- rbus: look at me + RB_STAT : in slv3 -- rbus: status flags + ); +end component; + + constant CPREF : slv4 := "1000"; + constant NCOMM : positive := 4; + +begin + + UUT : tbu_rri_serport + port map ( + CLK => CLK, + CE_INT => CE_INT, + CE_USEC => CE_USEC, + CE_MSEC => '1', + RESET => RESET, + RXSD => RRI_RXSD, + TXSD => RRI_TXSD, + RB_MREQ_req => RB_MREQ_req, + RB_MREQ_we => RB_MREQ_we, + RB_MREQ_initt=> RB_MREQ_initt, + RB_MREQ_addr => RB_MREQ_addr, + RB_MREQ_din => RB_MREQ_din, + RB_SRES_ack => RB_SRES_ack, + RB_SRES_busy => RB_SRES_busy, + RB_SRES_err => RB_SRES_err, + RB_SRES_dout => RB_SRES_dout, + RB_LAM => RB_LAM, + RB_STAT => RB_STAT + ); + + UARTRX : serport_uart_rx + generic map ( + CDWIDTH => 13) + port map ( + CLK => CLK, + RESET => RESET, + CLKDIV => CLKDIV, + RXSD => RRI_TXSD, + RXDATA => RXDATA, + RXVAL => RXVAL, + RXERR => open, + RXACT => RXACT + ); + + UARTTX : serport_uart_tx + generic map ( + CDWIDTH => 13) + port map ( + CLK => CLK, + RESET => RESET, + CLKDIV => CLKDIV, + TXSD => RRI_RXSD, + TXDATA => TXDATA, + TXENA => TXENA, + TXBUSY => TXBUSY + ); + + TXRXACT <= RXACT or TXBUSY; + + B2CD : byte2cdata -- byte stream -> 9bit comma,data + generic map ( + CPREF => CPREF, + NCOMM => NCOMM) + port map ( + CLK => CLK, + RESET => RESET, + DI => RXDATA, + ENA => RXVAL, + BUSY => open, + DO => CP_DO, + VAL => CP_VAL, + HOLD => CP_HOLD + ); + + CD2B : cdata2byte -- 9bit comma,data -> byte stream + generic map ( + CPREF => CPREF, + NCOMM => NCOMM) + port map ( + CLK => CLK, + RESET => RESET, + DI => CP_DI, + ENA => CP_ENA, + BUSY => CP_BUSY, + DO => TXDATA, + VAL => TXENA, + HOLD => TXBUSY + ); + +-- synthesis translate_off + proc_moni: process + variable oline : line; + constant c2out_time : time := 10 ns; -- FIXME - this isn't modular !!! + + begin + + loop + wait until CLK'event and CLK='1'; + wait for c2out_time; + + if TXENA='1' and TXBUSY='0' then + write(oline, now, right, 12); + write(oline, string'(" ")); + write(oline, string'(": tx ")); + write(oline, string'(" ")); + write(oline, TXDATA, right, 9); + writeline(output, oline); + end if; + + if RXVAL = '1' then + write(oline, now, right, 12); + write(oline, string'(" ")); + write(oline, string'(": rx ")); + write(oline, string'(" ")); + write(oline, RXDATA, right, 9); + writeline(output, oline); + end if; + + end loop; + + end process proc_moni; +-- synthesis translate_on + + +end syn; diff --git a/rtl/vlib/rri/tb/tbu_rri_serport.vbom b/rtl/vlib/rri/tb/tbu_rri_serport.vbom new file mode 100644 index 00000000..e861f7d8 --- /dev/null +++ b/rtl/vlib/rri/tb/tbu_rri_serport.vbom @@ -0,0 +1,8 @@ +# libs +../../slvtypes.vhd +../rrilib.vhd +# components +../rri_core.vbom +../rri_serport.vbom +# design +tbu_rri_serport.vhd diff --git a/rtl/vlib/rri/tb/tbu_rri_serport.vhd b/rtl/vlib/rri/tb/tbu_rri_serport.vhd new file mode 100644 index 00000000..42f31401 --- /dev/null +++ b/rtl/vlib/rri/tb/tbu_rri_serport.vhd @@ -0,0 +1,150 @@ +-- $Id: tbu_rri_serport.vhd 314 2010-07-09 17:38:41Z mueller $ +-- +-- Copyright 2007-2010 by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, 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 complete details. +-- +------------------------------------------------------------------------------ +-- Module Name: tbu_rri_serport - syn +-- Description: Wrapper for rri_core plus rri_serport to avoid records. It +-- has a port interface which will not be modified by xst +-- synthesis (no records, no generic port). +-- +-- Dependencies: rri_core +-- rri_serport +-- +-- To test: rri_serport +-- +-- Target Devices: generic +-- +-- Synthesized (xst): +-- Date Rev ise Target flop lutl lutm slic t peri +-- 2010-04-03 274 11.4 L68 xc3s1000-4 278 588 18 366 s 9.83 +-- 2007-10-27 92 9.2.02 J39 xc3s1000-4 273 547 18 - t 9.65 +-- 2007-10-27 92 9.1 J30 xc3s1000-4 273 545 18 - t 9.65 +-- 2007-10-27 92 8.2.03 I34 xc3s1000-4 283 594 18 323 s 10.3 +-- 2007-10-27 92 8.1.03 I27 xc3s1000-4 285 596 18 - s 9.32 +-- +-- Tool versions: xst 8.1, 8.2, 9.1, 9.2, 11.4; ghdl 0.18-0.26 +-- Revision History: +-- Date Rev Version Comment +-- 2010-06-03 300 2.2.3 use default FAWIDTH for rri_core_serport +-- 2010-05-02 287 2.2.2 ren CE_XSEC->CE_INT,RP_STAT->RB_STAT,AP_LAM->RB_LAM +-- drop RP_IINT from interfaces; drop RTSFLUSH generic +-- 2010-04-18 279 2.2.1 drop RTSFBUF generic for rri_serport +-- 2010-04-03 274 2.2 add CP_FLUSH, add rri_serport handshake logic +-- 2009-03-14 197 2.1 remove records in interface to allow _ssim usage +-- 2008-08-24 162 2.0 with new rb_mreq/rb_sres interface +-- 2007-11-24 98 1.1 added RP_IINT support +-- 2007-07-02 63 1.0 Initial version +------------------------------------------------------------------------------ + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; + +use work.slvtypes.all; +use work.rrilib.all; + +entity tbu_rri_serport is -- rri core+serport combo + port ( + CLK : in slbit; -- clock + CE_INT : in slbit; -- rri ito time unit clock enable + CE_USEC : in slbit; -- 1 usec clock enable + CE_MSEC : in slbit; -- 1 msec clock enable + RESET : in slbit; -- reset + RXSD : in slbit; -- receive serial data (board view) + TXSD : out slbit; -- transmit serial data (board view) + RB_MREQ_req : out slbit; -- rbus: request - req + RB_MREQ_we : out slbit; -- rbus: request - we + RB_MREQ_initt: out slbit; -- rbus: request - init; avoid name coll + RB_MREQ_addr : out slv8; -- rbus: request - addr + RB_MREQ_din : out slv16; -- rbus: request - din + RB_SRES_ack : in slbit; -- rbus: response - ack + RB_SRES_busy : in slbit; -- rbus: response - busy + RB_SRES_err : in slbit; -- rbus: response - err + RB_SRES_dout : in slv16; -- rbus: response - dout + RB_LAM : in slv16; -- rbus: look at me + RB_STAT : in slv3 -- rbus: status flags + ); +end entity tbu_rri_serport; + + +architecture syn of tbu_rri_serport is + + signal RB_MREQ : rb_mreq_type := rb_mreq_init; + signal RB_SRES : rb_sres_type := rb_sres_init; + + signal CTS_N : slbit := '0'; + signal RTS_N : slbit := '0'; + + signal CP_DI : slv9 := (others=>'0'); + signal CP_ENA : slbit := '0'; + signal CP_BUSY : slbit := '0'; + signal CP_DO : slv9 := (others=>'0'); + signal CP_VAL : slbit := '0'; + signal CP_HOLD : slbit := '0'; + signal CP_FLUSH : slbit := '0'; + +begin + + RB_MREQ_req <= RB_MREQ.req; + RB_MREQ_we <= RB_MREQ.we; + RB_MREQ_initt<= RB_MREQ.init; + RB_MREQ_addr <= RB_MREQ.addr; + RB_MREQ_din <= RB_MREQ.din; + + RB_SRES.ack <= RB_SRES_ack; + RB_SRES.busy <= RB_SRES_busy; + RB_SRES.err <= RB_SRES_err; + RB_SRES.dout <= RB_SRES_dout; + + CORE : rri_core + port map ( + CLK => CLK, + CE_INT => CE_INT, + RESET => RESET, + CP_DI => CP_DI, + CP_ENA => CP_ENA, + CP_BUSY => CP_BUSY, + CP_DO => CP_DO, + CP_VAL => CP_VAL, + CP_HOLD => CP_HOLD, + CP_FLUSH => CP_FLUSH, + RB_MREQ => RB_MREQ, + RB_SRES => RB_SRES, + RB_LAM => RB_LAM, + RB_STAT => RB_STAT + ); + + SERPORT : rri_serport + generic map ( + CPREF => "1000", + CDWIDTH => 13, + CDINIT => 1) -- NOTE: change also CLKDIV in tbd_rri_serport !! + port map ( + CLK => CLK, + CE_USEC => CE_USEC, + CE_MSEC => CE_MSEC, + RESET => RESET, + RXSD => RXSD, + TXSD => TXSD, + CTS_N => CTS_N, + RTS_N => RTS_N, + CP_DI => CP_DI, + CP_ENA => CP_ENA, + CP_BUSY => CP_BUSY, + CP_DO => CP_DO, + CP_VAL => CP_VAL, + CP_HOLD => CP_HOLD, + CP_FLUSH => CP_FLUSH + ); + +end syn; diff --git a/rtl/vlib/rri/tb/tbw.dat b/rtl/vlib/rri/tb/tbw.dat new file mode 100644 index 00000000..dd8df08c --- /dev/null +++ b/rtl/vlib/rri/tb/tbw.dat @@ -0,0 +1,12 @@ +# $Id: tbw.dat 311 2010-06-30 17:52:37Z mueller $ +# +[tb_rri_core] +tb_rri_stim = tb_rri_stim.dat +[tb_rri_serport] +tb_rri_stim = tb_rri_stim.dat +[tb_rritba_ttcombo] +tb_rritba_stim = tb_rritba_ttcombo_stim.dat +[tb_rriext_ttcombo] +tb_rriext_fifo_rx = +tb_rriext_fifo_tx = +tb_rriext_conf = diff --git a/rtl/vlib/rri/tb/vhpi_rriext.vhd b/rtl/vlib/rri/tb/vhpi_rriext.vhd new file mode 100644 index 00000000..22f48955 --- /dev/null +++ b/rtl/vlib/rri/tb/vhpi_rriext.vhd @@ -0,0 +1,55 @@ +-- $Id: vhpi_rriext.vhd 314 2010-07-09 17:38:41Z mueller $ +-- +-- Copyright 2007- by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, 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 complete details. +-- +------------------------------------------------------------------------------ +-- Package Name: vhpi_rriext +-- Description: VHDL procedural interface: VHDL declaration side +-- +-- Dependencies: - +-- Tool versions: xst 8.1, 8.2, 9.1, 9.2; ghdl 0.18-0.25 +-- Revision History: +-- Date Rev Version Comment +-- 2007-08-26 76 1.0 Initial version +------------------------------------------------------------------------------ + +package vhpi_rriext is + + impure function cext_getbyte ( + clk : integer) -- clock cycle + return integer; + attribute foreign of cext_getbyte : function is "VHPIDIRECT cext_getbyte"; + + impure function cext_putbyte ( + dat : integer) -- data byte + return integer; + attribute foreign of cext_putbyte : function is "VHPIDIRECT cext_putbyte"; + +end vhpi_rriext; + +package body vhpi_rriext is + + impure function cext_getbyte ( + clk : integer) -- clock cycle + return integer is + begin + report "cext_getbyte not vhpi'ed" severity failure; + end cext_getbyte; + + impure function cext_putbyte ( + dat : integer) -- data byte + return integer is + begin + report "cext_getbyte not vhpi'ed" severity failure; + end cext_putbyte; + +end vhpi_rriext; diff --git a/rtl/vlib/serport/Makefile b/rtl/vlib/serport/Makefile new file mode 100644 index 00000000..e394d08b --- /dev/null +++ b/rtl/vlib/serport/Makefile @@ -0,0 +1,22 @@ +# $Id: Makefile 311 2010-06-30 17:52:37Z mueller $ +# +# Revision History: +# Date Rev Version Comment +# 2007-12-09 100 1.0.1 drop ISE_p definition +# 2007-07-03 45 1.0 Initial version +# +VBOM_all = $(wildcard *.vbom) +NGC_all = $(VBOM_all:.vbom=.ngc) +# +.phony : all clean +# +all : $(NGC_all) +# +clean : ise_clean +# +#---- +# +include $(RETROBASE)/rtl/vlib/Makefile.xflow +# +include $(VBOM_all:.vbom=.dep_xst) +# diff --git a/rtl/vlib/serport/serport.vhd b/rtl/vlib/serport/serport.vhd new file mode 100644 index 00000000..47a969f5 --- /dev/null +++ b/rtl/vlib/serport/serport.vhd @@ -0,0 +1,134 @@ +-- $Id: serport.vhd 314 2010-07-09 17:38:41Z mueller $ +-- +-- Copyright 2007-2010 by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, 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 complete details. +-- +------------------------------------------------------------------------------ +-- Package Name: serport +-- Description: serial port interface components +-- +-- Dependencies: - +-- Tool versions: xst 8.1, 8.2, 9.1, 9.2, 11.4; ghdl 0.18-0.26 +-- Revision History: +-- Date Rev Version Comment +-- 2010-04-10 276 1.2 add clock divider constant defs +-- 2007-10-22 88 1.1 renames (in prev revs); remove std_logic_unsigned +-- 2007-06-03 45 1.0 Initial version +------------------------------------------------------------------------------ + +library ieee; +use ieee.std_logic_1164.all; + +use work.slvtypes.all; + +package serport is + +-- clock divider constants assume 50 MHz clock + + constant serport_clkdiv_009600 : integer := 5208-1; -- 50000000/ 9600=5208.33 + constant serport_clkdiv_019200 : integer := 2604-1; -- 50000000/ 19200=2604.16 + constant serport_clkdiv_038400 : integer := 1302-1; -- 50000000/ 38400=1302.08 + constant serport_clkdiv_057600 : integer := 868-1; -- 50000000/ 57600= 868.05 + constant serport_clkdiv_115200 : integer := 434-1; -- 50000000/115200= 434.02 + constant serport_clkdiv_230400 : integer := 217-1; -- 50000000/230400= 217.01 + constant serport_clkdiv_460800 : integer := 109-1; -- 50000000/460800= 108.51 + constant serport_clkdiv_500000 : integer := 100-1; -- 50000000/500000= 100 + constant serport_clkdiv_576000 : integer := 87-1; -- 50000000/576000= 86.80 + constant serport_clkdiv_921600 : integer := 54-1; -- 50000000/921600= 54.25 + constant serport_clkdiv_1M : integer := 50-1; -- 50000000/1M = 50 + constant serport_clkdiv_2M : integer := 24-1; -- 50000000/2M = 25 + +component serport_uart_rxtx is -- serial port uart: rx+tx combo + generic ( + CDWIDTH : positive := 13); -- clk divider width + port ( + CLK : in slbit; -- clock + RESET : in slbit; -- reset + CLKDIV : in slv(CDWIDTH-1 downto 0); -- clock divider setting + RXSD : in slbit; -- receive serial data (uart view) + RXDATA : out slv8; -- receiver data out + RXVAL : out slbit; -- receiver data valid + RXERR : out slbit; -- receiver data error (frame error) + RXACT : out slbit; -- receiver active + TXSD : out slbit; -- transmit serial data (uart view) + TXDATA : in slv8; -- transmit data in + TXENA : in slbit; -- transmit data enable + TXBUSY : out slbit -- transmit busy + ); +end component; + +component serport_uart_rx is -- serial port uart: receive part + generic ( + CDWIDTH : positive := 13); -- clk divider width + port ( + CLK : in slbit; -- clock + RESET : in slbit; -- reset + CLKDIV : in slv(CDWIDTH-1 downto 0); -- clock divider setting + RXSD : in slbit; -- receive serial data (uart view) + RXDATA : out slv8; -- receiver data out + RXVAL : out slbit; -- receiver data valid + RXERR : out slbit; -- receiver data error (frame error) + RXACT : out slbit -- receiver active + ); +end component; + +component serport_uart_tx is -- serial port uart: transmit part + generic ( + CDWIDTH : positive := 13); -- clk divider width + port ( + CLK : in slbit; -- clock + RESET : in slbit; -- reset + CLKDIV : in slv(CDWIDTH-1 downto 0); -- clock divider setting + TXSD : out slbit; -- transmit serial data (uart view) + TXDATA : in slv8; -- transmit data in + TXENA : in slbit; -- transmit data enable + TXBUSY : out slbit -- transmit busy + ); +end component; + +component serport_uart_rxtx_ab is -- serial port uart: rx+tx+autobaud + generic ( + CDWIDTH : positive := 13; -- clk divider width + CDINIT: natural := 15); -- clk divider initial/reset setting + port ( + CLK : in slbit; -- clock + CE_MSEC : in slbit; -- 1 msec clock enable + RESET : in slbit; -- reset + RXSD : in slbit; -- receive serial data (uart view) + RXDATA : out slv8; -- receiver data out + RXVAL : out slbit; -- receiver data valid + RXERR : out slbit; -- receiver data error (frame error) + RXACT : out slbit; -- receiver active + TXSD : out slbit; -- transmit serial data (uart view) + TXDATA : in slv8; -- transmit data in + TXENA : in slbit; -- transmit data enable + TXBUSY : out slbit; -- transmit busy + ABACT : out slbit; -- autobaud active; if 1 clkdiv invalid + ABDONE : out slbit -- autobaud resync done + ); +end component; + +component serport_uart_autobaud is -- serial port uart: autobauder + generic ( + CDWIDTH : positive := 13; -- clk divider width + CDINIT: natural := 15); -- clk divider initial/reset setting + port ( + CLK : in slbit; -- clock + CE_MSEC : in slbit; -- 1 msec clock enable + RESET : in slbit; -- reset + RXSD : in slbit; -- receive serial data (uart view) + CLKDIV : out slv(CDWIDTH-1 downto 0); -- clock divider setting + ACT : out slbit; -- active; if 1 clkdiv is invalid + DONE : out slbit -- resync done + ); +end component; + +end serport; diff --git a/rtl/vlib/serport/serport_uart_autobaud.vbom b/rtl/vlib/serport/serport_uart_autobaud.vbom new file mode 100644 index 00000000..503320db --- /dev/null +++ b/rtl/vlib/serport/serport_uart_autobaud.vbom @@ -0,0 +1,4 @@ +# libs +../slvtypes.vhd +# design +serport_uart_autobaud.vhd diff --git a/rtl/vlib/serport/serport_uart_autobaud.vhd b/rtl/vlib/serport/serport_uart_autobaud.vhd new file mode 100644 index 00000000..545eccf9 --- /dev/null +++ b/rtl/vlib/serport/serport_uart_autobaud.vhd @@ -0,0 +1,173 @@ +-- $Id: serport_uart_autobaud.vhd 314 2010-07-09 17:38:41Z mueller $ +-- +-- Copyright 2007-2010 by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, 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 complete details. +-- +------------------------------------------------------------------------------ +-- Module Name: serport_uart_autobaud - syn +-- Description: serial port UART - autobauder +-- +-- Dependencies: - +-- Test bench: tb/tb_serport_autobaud +-- Target Devices: generic +-- Tool versions: xst 8.1, 8.2, 9.1, 9.2, 11.4; ghdl 0.18-0.26 +-- Revision History: +-- Date Rev Version Comment +-- 2010-04-18 279 1.0.3 change ccnt start value to -3, better rounding +-- 2007-10-14 89 1.0.2 all instantiation with CDINIT=0 +-- 2007-10-12 88 1.0.1 avoid ieee.std_logic_unsigned, use cast to unsigned +-- 2007-06-30 62 1.0 Initial version +------------------------------------------------------------------------------ + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; + +use work.slvtypes.all; + +entity serport_uart_autobaud is -- serial port uart: autobauder + generic ( + CDWIDTH : positive := 13; -- clk divider width + CDINIT: natural := 15); -- clk divider initial/reset setting + port ( + CLK : in slbit; -- clock + CE_MSEC : in slbit; -- 1 msec clock enable + RESET : in slbit; -- reset + RXSD : in slbit; -- receive serial data (uart view) + CLKDIV : out slv(CDWIDTH-1 downto 0); -- clock divider setting + ACT : out slbit; -- active; if 1 clkdiv is invalid + DONE : out slbit -- resync done + ); +end serport_uart_autobaud; + + +architecture syn of serport_uart_autobaud is + + type state_type is ( + s_idle, + s_break, + s_wait, + s_sync + ); + + type regs_type is record + ccnt : slv(CDWIDTH-1+3 downto 0); -- clock divider counter + mcnt : slv7; -- msec counter + seen1 : slbit; -- seen a '1' in this msec + state : state_type; -- state + end record regs_type; + + -- Note on initialization of ccnt: + -- - in the current logic ccnt is incremented n-1 times when n is number + -- clock cycles with a RXD of '0'. When running at 50 MBaud, ccnt will + -- be incremented 7 (not 8!) times. + -- - the three LSBs of ccnt should be at 100 under perfect conditions, this + -- gives the best rounded estimate of CLKDIV. + -- - therefore ccnt is inititialized with 111111.101: 101 + 111 -> 1100 + -- --> ccntinit = -3 + + constant ccntinit : slv(CDWIDTH-1+3 downto 0) := + conv_std_logic_vector(2**(CDWIDTH+3)-3, CDWIDTH+3); + constant mcntzero : slv7 := (others=>'0'); + constant mcntlast : slv7 := (others=>'1'); + constant regs_init : regs_type := ( + conv_std_logic_vector(CDINIT,CDWIDTH)&"000", + (others=>'0'), + '0', + s_idle + ); + + signal R_REGS : regs_type := regs_init; -- state registers + signal N_REGS : regs_type := regs_init; -- next value state regs + +begin + + assert CDINIT <= 2**CDWIDTH-1 + report "assert(CDINIT <= 2**CDWIDTH-1): CDINIT too large for given CDWIDTH" + severity FAILURE; + + proc_regs: process (CLK) + begin + + if CLK'event and CLK='1' then + if RESET = '1' then + R_REGS <= regs_init; + else + R_REGS <= N_REGS; + end if; + end if; + + end process proc_regs; + + proc_next: process (R_REGS, CE_MSEC, RESET, RXSD) + + variable r : regs_type := regs_init; + variable n : regs_type := regs_init; + + variable iact : slbit := '0'; + variable idone : slbit := '0'; + + begin + + r := R_REGS; + n := R_REGS; + + iact := '1'; + idone := '0'; + + case r.state is + when s_idle => -- s_idle: idle, detect break -------- + iact := '0'; + if CE_MSEC = '1' then -- if end of msec + if r.seen1 = '0' then -- if no '1' seen on RXD + n.mcnt := unsigned(r.mcnt) + 1; -- up break timer counter + if r.mcnt = mcntlast then -- after 127 msec + n.state := s_break; -- break detected ! + end if; + else -- otherwise if '1' seen + n.mcnt := mcntzero; -- clear break timer again + end if; + n.seen1 := RXSD; -- latch current RXD value + else -- otherwise if not at end-of-msec + n.seen1 := r.seen1 or RXSD; -- remember whether RXS=1 seen + end if; + + when s_break => -- s_break: detect end of break ------ + if RXSD = '1' then -- if end of break seen + n.state := s_wait; -- to s_wait to wait for sync char + n.ccnt := ccntinit; -- and initialize ccnt + end if; -- otherwise stay in s_break + + when s_wait => -- s_wait: wait for sync char -------- + if RXSD = '0' then -- if start bit if sync char seen + n.state := s_sync; -- to s_sync to wait for end of '0' + end if; -- otherwise stay in s_wait + + when s_sync => -- s_sync: wait for end of '0' bits -- + if RXSD = '1' then -- if end of '0' bits seen + n.state := s_idle; -- to s_idle, autobauding done + idone := '1'; -- emit done pulse + else -- otherwise still in '0' of sync + n.ccnt := unsigned(n.ccnt) + 1; -- increment ccnt + end if; + + when others => null; -- ----------------------------------- + end case; + + N_REGS <= n; + + CLKDIV <= r.ccnt(CDWIDTH-1+3 downto 3); + ACT <= iact or RESET; + DONE <= idone; + + end process proc_next; + +end syn; diff --git a/rtl/vlib/serport/serport_uart_rx.vbom b/rtl/vlib/serport/serport_uart_rx.vbom new file mode 100644 index 00000000..1443c5db --- /dev/null +++ b/rtl/vlib/serport/serport_uart_rx.vbom @@ -0,0 +1,4 @@ +# libs +../slvtypes.vhd +# design +serport_uart_rx.vhd diff --git a/rtl/vlib/serport/serport_uart_rx.vhd b/rtl/vlib/serport/serport_uart_rx.vhd new file mode 100644 index 00000000..c1f38dd0 --- /dev/null +++ b/rtl/vlib/serport/serport_uart_rx.vhd @@ -0,0 +1,312 @@ +-- $Id: serport_uart_rx.vhd 314 2010-07-09 17:38:41Z mueller $ +-- +-- Copyright 2007-2009 by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, 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 complete details. +-- +-- The uart expects CLKDIV+1 wide input bit symbols. +-- This implementation counts the number of 1's in the first CLKDIV clock +-- cycles, and checks in the last cycle of the symbol time whether the +-- number of 1's was > CLKDIV/2. This supresses short glitches nicely, +-- especially for larger clock dividers. +-- +------------------------------------------------------------------------------ +-- Module Name: serport_uart_rx - syn +-- Description: serial port UART - receiver +-- +-- Dependencies: - +-- Test bench: tb/tb_serport_uart_rxtx +-- Target Devices: generic +-- Tool versions: xst 8.1, 8.2, 9.1, 9.2; ghdl 0.18-0.25 +-- Revision History: +-- Date Rev Version Comment +-- 2009-07-12 233 2.0.2 remove snoopers +-- 2008-03-02 121 2.0.1 comment out snoopers +-- 2007-10-21 91 2.0 re-designed and -implemented with state machine. +-- allow CLKDIV=0 with 1 stop bit; allow max. CLKDIV +-- (all 1's); aborts bad start bit after 1/2 cell; +-- accepts stop bit after 1/2 cell, permits tx clock +-- be ~3 percent faster than rx clock. +-- for 3s1000ft256: 50 -> 58 slices for CDWIDTH=13 +-- 2007-10-14 89 1.1 almost full rewrite, handles now CLKDIV=0 properly +-- for 3s1000ft256: 43 -> 50 slices for CDWIDTH=13 +-- 2007-10-12 88 1.0.1 avoid ieee.std_logic_unsigned, use cast to unsigned +-- 2007-06-30 62 1.0 Initial version +------------------------------------------------------------------------------ + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; + +-- synthesis translate_off +use ieee.std_logic_textio.all; +use std.textio.all; +-- synthesis translate_on + +use work.slvtypes.all; + +entity serport_uart_rx is -- serial port uart: receive part + generic ( + CDWIDTH : positive := 13); -- clk divider width + port ( + CLK : in slbit; -- clock + RESET : in slbit; -- reset + CLKDIV : in slv(CDWIDTH-1 downto 0); -- clock divider setting + RXSD : in slbit; -- receive serial data (uart view) + RXDATA : out slv8; -- receiver data out + RXVAL : out slbit; -- receiver data valid + RXERR : out slbit; -- receiver data error (frame error) + RXACT : out slbit -- receiver active + ); +end serport_uart_rx; + + +architecture syn of serport_uart_rx is + + type state_type is ( + s_idle, -- s_idle: idle + s_colb0, -- s_colb0: collect b0 (start bit) + s_endb0, -- s_endb0: finish b0 (start bit) + s_colbx, -- s_colbx: collect bx + s_endbx, -- s_endbx: finish bx + s_colb9, -- s_colb9: collect bx (stop bit) + s_endb9 -- s_endb9: finish bx (stop bit) + ); + + type regs_type is record + state : state_type; -- state + ccnt : slv(CDWIDTH-1 downto 0); -- clock divider counter + dcnt : slv(CDWIDTH downto 0); -- data '1' counter + bcnt : slv4; -- bit counter + sreg : slv8; -- input shift register + end record regs_type; + + constant ccntzero : slv(CDWIDTH-1 downto 0) := (others=>'0'); + constant dcntzero : slv(CDWIDTH downto 0) := (others=>'0'); + constant regs_init : regs_type := ( + s_idle, + ccntzero, + dcntzero, + (others=>'0'), + (others=>'0') + ); + + signal R_REGS : regs_type := regs_init; -- state registers + signal N_REGS : regs_type := regs_init; -- next value state regs + +begin + + proc_regs: process (CLK) + begin + + if CLK'event and CLK='1' then + R_REGS <= N_REGS; + end if; + + end process proc_regs; + + proc_next: process (R_REGS, RESET, CLKDIV, RXSD) + + variable r : regs_type := regs_init; + variable n : regs_type := regs_init; + + variable dbit : slbit := '0'; + variable ld_ccnt : slbit := '0'; + variable tc_ccnt : slbit := '0'; + variable tc_bcnt : slbit := '0'; + variable ld_dcnt : slbit := '0'; + variable ld_bcnt : slbit := '0'; + variable ce_bcnt : slbit := '0'; + variable iact : slbit := '0'; + variable ival : slbit := '0'; + variable ierr : slbit := '0'; + + begin + + r := R_REGS; + n := R_REGS; + + dbit := '0'; + ld_ccnt := '0'; + tc_ccnt := '0'; + tc_bcnt := '0'; + ld_dcnt := '0'; + ld_bcnt := '0'; + ce_bcnt := '0'; + iact := '1'; + ival := '0'; + ierr := '0'; + + if unsigned(r.ccnt) = 0 then + tc_ccnt := '1'; + end if; + if unsigned(r.bcnt) = 9 then + tc_bcnt := '1'; + end if; + + if unsigned(r.dcnt) > unsigned("00" & CLKDIV(CDWIDTH-1 downto 1)) then + dbit := '1'; + end if; + + case r.state is + + when s_idle => -- s_idle: idle ---------------------- + iact := '0'; + ld_dcnt := '1'; -- always keep dcnt in reset + if RXSD = '0' then -- if start bit seen + if tc_ccnt = '1' then + n.state := s_endb0; -- finish b0 + ld_ccnt := '1'; -- start next bit + ce_bcnt := '1'; + else + n.state := s_colb0; -- collect b0 + end if; + else -- otherwise + ld_ccnt := '1'; -- keep all counters in reset + ld_bcnt := '1'; + end if; + + when s_colb0 => -- s_colb0: collect b0 (start bit) --- + if tc_ccnt = '1' then -- last cycle of b0 ? + n.state := s_endb0; -- finish b0 + ld_ccnt := '1'; -- " + ce_bcnt := '1'; + else -- continue in b0 ? + if dbit='1' and RXSD='1' then -- too many 1's ? + n.state := s_idle; -- abort to idle + ld_dcnt := '1'; -- put counters in reset + ld_ccnt := '1'; + ld_bcnt := '1'; + end if; + end if; + + when s_endb0 => -- s_endb0: finish b0 (start bit) --- + ld_dcnt := '1'; -- start next bit + if dbit = '1' then -- was it a 1 ? + n.state := s_idle; -- abort to idle + ld_ccnt := '1'; -- put counters in reset + ld_bcnt := '1'; + else + if tc_ccnt = '1' then -- last cycle of bx ? + n.state := s_endbx; -- finish bx + ld_ccnt := '1'; + ce_bcnt := '1'; + else -- continue in b0 ? + n.state := s_colbx; -- collect bx + end if; + end if; + + when s_colbx => -- s_colbx: collect bx --------------- + if tc_ccnt = '1' then -- last cycle of bx ? + n.state := s_endbx; -- finish bx + ld_ccnt := '1'; + ce_bcnt := '1'; + end if; + + when s_endbx => -- s_endbx: finish bx --------------- + ld_dcnt := '1'; -- start next bit + n.sreg := dbit & r.sreg(7 downto 1); + if tc_ccnt = '1' then -- last cycle of bx ? + if tc_bcnt = '1' then + n.state := s_endb9; -- finish b9 + ld_bcnt := '1'; -- and wrap bcnt + else + n.state := s_endbx; -- finish bx + ce_bcnt := '1'; + end if; + ld_ccnt := '1'; + else -- continue in bx ? + if tc_bcnt = '1' then + n.state := s_colb9; -- collect b9 + else + n.state := s_colbx; -- collect bx + end if; + end if; + + when s_colb9 => -- s_colb9: collect bx (stop bit) ---- + if tc_ccnt = '1' then -- last cycle of b9 ? + n.state := s_endb9; -- finish b9 + ld_ccnt := '1'; -- " + ld_bcnt := '1'; -- and wrap bcnt + else -- continue in b9 ? + if dbit='1' and RXSD='1' then -- already enough 1's ? + n.state := s_idle; -- finish to idle + ld_dcnt := '1'; -- put counters in reset + ld_ccnt := '1'; + ld_bcnt := '1'; + ival := '1'; + end if; + end if; + + when s_endb9 => -- s_endb9: finish bx (stop bit) ---- + ld_dcnt := '1'; -- start next bit + if dbit = '1' then -- was it a valid stop bit ? + ival := '1'; + else + ierr := '1'; + end if; + if RXSD = '1' then -- line in idle state ? + n.state := s_idle; -- finish to idle state + ld_ccnt := '1'; -- and put counters in reset + ld_bcnt := '1'; -- " + else + if tc_ccnt = '1' then -- last cycle of b9 ? + n.state := s_endb0; -- finish b0 + ld_ccnt := '1'; -- " + ce_bcnt := '1'; + else -- continue in b0 ? + n.state := s_colb0; -- collect bx + end if; + end if; + + when others => null; -- ----------------------------------- + + end case; + + if RESET = '1' then -- RESET seen + ld_ccnt := '1'; -- keep all counters in reset + ld_dcnt := '1'; + ld_bcnt := '1'; + n.state := s_idle; + end if; + + if ld_ccnt = '1' then -- implement ccnt + n.ccnt := CLKDIV; + else + n.ccnt := unsigned(r.ccnt) - 1; + end if; + + if ld_dcnt = '1' then -- implement dcnt + n.dcnt(CDWIDTH downto 1) := (others=>'0'); + n.dcnt(0) := RXSD; + else + if RXSD = '1' then + n.dcnt := unsigned(r.dcnt) + 1; + end if; + end if; + + if ld_bcnt = '1' then -- implement bcnt + n.bcnt := (others=>'0'); + else + if ce_bcnt = '1' then + n.bcnt := unsigned(r.bcnt) + 1; + end if; + end if; + + N_REGS <= n; + + RXDATA <= r.sreg; + RXACT <= iact; + RXVAL <= ival; + RXERR <= ierr; + + end process proc_next; + +end syn; diff --git a/rtl/vlib/serport/serport_uart_rxtx.vbom b/rtl/vlib/serport/serport_uart_rxtx.vbom new file mode 100644 index 00000000..cc39b2db --- /dev/null +++ b/rtl/vlib/serport/serport_uart_rxtx.vbom @@ -0,0 +1,8 @@ +# libs +../slvtypes.vhd +serport.vhd +# components +serport_uart_rx.vbom +serport_uart_tx.vbom +# design +serport_uart_rxtx.vhd diff --git a/rtl/vlib/serport/serport_uart_rxtx.vhd b/rtl/vlib/serport/serport_uart_rxtx.vhd new file mode 100644 index 00000000..0cdb7038 --- /dev/null +++ b/rtl/vlib/serport/serport_uart_rxtx.vhd @@ -0,0 +1,85 @@ +-- $Id: serport_uart_rxtx.vhd 314 2010-07-09 17:38:41Z mueller $ +-- +-- Copyright 2007- by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, 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 complete details. +-- +------------------------------------------------------------------------------ +-- Module Name: serport_uart_rxtx - syn +-- Description: serial port UART - transmitter + receiver +-- +-- Dependencies: serport_uart_rx +-- serport_uart_tx +-- Test bench: tb/tb_serport_uart_rxtx +-- Target Devices: generic +-- Tool versions: xst 8.1, 8.2, 9.1, 9.2, 11.4; ghdl 0.18-0.26 +-- Revision History: +-- Date Rev Version Comment +-- 2007-06-24 60 1.0 Initial version +------------------------------------------------------------------------------ + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; + +use work.slvtypes.all; +use work.serport.all; + +entity serport_uart_rxtx is -- serial port uart: rx+tx combo + generic ( + CDWIDTH : positive := 13); -- clk divider width + port ( + CLK : in slbit; -- clock + RESET : in slbit; -- reset + CLKDIV : in slv(CDWIDTH-1 downto 0); -- clock divider setting + RXSD : in slbit; -- receive serial data (uart view) + RXDATA : out slv8; -- receiver data out + RXVAL : out slbit; -- receiver data valid + RXERR : out slbit; -- receiver data error (frame error) + RXACT : out slbit; -- receiver active + TXSD : out slbit; -- transmit serial data (uart view) + TXDATA : in slv8; -- transmit data in + TXENA : in slbit; -- transmit data enable + TXBUSY : out slbit -- transmit busy + ); +end serport_uart_rxtx; + +architecture syn of serport_uart_rxtx is + +begin + + RX : serport_uart_rx + generic map ( + CDWIDTH => CDWIDTH) + port map ( + CLK => CLK, + RESET => RESET, + CLKDIV => CLKDIV, + RXSD => RXSD, + RXDATA => RXDATA, + RXVAL => RXVAL, + RXERR => RXERR, + RXACT => RXACT + ); + + TX : serport_uart_tx + generic map ( + CDWIDTH => CDWIDTH) + port map ( + CLK => CLK, + RESET => RESET, + CLKDIV => CLKDIV, + TXSD => TXSD, + TXDATA => TXDATA, + TXENA => TXENA, + TXBUSY => TXBUSY + ); + +end syn; diff --git a/rtl/vlib/serport/serport_uart_rxtx_ab.vbom b/rtl/vlib/serport/serport_uart_rxtx_ab.vbom new file mode 100644 index 00000000..5d13fcb3 --- /dev/null +++ b/rtl/vlib/serport/serport_uart_rxtx_ab.vbom @@ -0,0 +1,8 @@ +# libs +../slvtypes.vhd +serport.vhd +# components +serport_uart_autobaud.vbom +serport_uart_rxtx.vbom +# design +serport_uart_rxtx_ab.vhd diff --git a/rtl/vlib/serport/serport_uart_rxtx_ab.vhd b/rtl/vlib/serport/serport_uart_rxtx_ab.vhd new file mode 100644 index 00000000..85258193 --- /dev/null +++ b/rtl/vlib/serport/serport_uart_rxtx_ab.vhd @@ -0,0 +1,100 @@ +-- $Id: serport_uart_rxtx_ab.vhd 314 2010-07-09 17:38:41Z mueller $ +-- +-- Copyright 2007- by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, 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 complete details. +-- +------------------------------------------------------------------------------ +-- Module Name: serport_uart_rxtx_ab - syn +-- Description: serial port UART - transmitter-receiver + autobauder +-- +-- Dependencies: serport_uart_autobaud +-- serport_uart_rxtx +-- Test bench: - +-- Target Devices: generic +-- Tool versions: xst 8.1, 8.2, 9.1, 9.2, 11.4; ghdl 0.18-0.26 +-- Revision History: +-- Date Rev Version Comment +-- 2007-06-24 60 1.0 Initial version +------------------------------------------------------------------------------ + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; + +use work.slvtypes.all; +use work.serport.all; + +entity serport_uart_rxtx_ab is -- serial port uart: rx+tx+autobaud + generic ( + CDWIDTH : positive := 13; -- clk divider width + CDINIT: natural := 15); -- clk divider initial/reset setting + port ( + CLK : in slbit; -- clock + CE_MSEC : in slbit; -- 1 msec clock enable + RESET : in slbit; -- reset + RXSD : in slbit; -- receive serial data (uart view) + RXDATA : out slv8; -- receiver data out + RXVAL : out slbit; -- receiver data valid + RXERR : out slbit; -- receiver data error (frame error) + RXACT : out slbit; -- receiver active + TXSD : out slbit; -- transmit serial data (uart view) + TXDATA : in slv8; -- transmit data in + TXENA : in slbit; -- transmit data enable + TXBUSY : out slbit; -- transmit busy + ABACT : out slbit; -- autobaud active; if 1 clkdiv invalid + ABDONE : out slbit -- autobaud resync done + ); +end serport_uart_rxtx_ab; + +architecture syn of serport_uart_rxtx_ab is + + signal CLKDIV : slv(CDWIDTH-1 downto 0) := conv_std_logic_vector(0, CDWIDTH); + signal ABACT_L : slbit := '0'; -- local readable copy of ABACT + signal UART_RESET : slbit := '0'; + +begin + + AB : serport_uart_autobaud + generic map ( + CDWIDTH => CDWIDTH, + CDINIT => CDINIT) + port map ( + CLK => CLK, + CE_MSEC => CE_MSEC, + RESET => RESET, + RXSD => RXSD, + CLKDIV => CLKDIV, + ACT => ABACT_L, + DONE => ABDONE + ); + + UART_RESET <= ABACT_L or RESET; + ABACT <= ABACT_L; + + RXTX : serport_uart_rxtx + generic map ( + CDWIDTH => CDWIDTH) + port map ( + CLK => CLK, + RESET => UART_RESET, + CLKDIV => CLKDIV, + RXSD => RXSD, + RXDATA => RXDATA, + RXVAL => RXVAL, + RXERR => RXERR, + RXACT => RXACT, + TXSD => TXSD, + TXDATA => TXDATA, + TXENA => TXENA, + TXBUSY => TXBUSY + ); + +end syn; diff --git a/rtl/vlib/serport/serport_uart_tx.vbom b/rtl/vlib/serport/serport_uart_tx.vbom new file mode 100644 index 00000000..38de4fc3 --- /dev/null +++ b/rtl/vlib/serport/serport_uart_tx.vbom @@ -0,0 +1,4 @@ +# libs +../slvtypes.vhd +# design +serport_uart_tx.vhd diff --git a/rtl/vlib/serport/serport_uart_tx.vhd b/rtl/vlib/serport/serport_uart_tx.vhd new file mode 100644 index 00000000..99e1ee06 --- /dev/null +++ b/rtl/vlib/serport/serport_uart_tx.vhd @@ -0,0 +1,132 @@ +-- $Id: serport_uart_tx.vhd 314 2010-07-09 17:38:41Z mueller $ +-- +-- Copyright 2007- by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, 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 complete details. +-- +------------------------------------------------------------------------------ +-- Module Name: serport_uart_tx - syn +-- Description: serial port UART - transmitter +-- +-- Dependencies: - +-- Test bench: tb/tb_serport_uart_rxtx +-- Target Devices: generic +-- Tool versions: xst 8.1, 8.2, 9.1, 9.2; ghdl 0.18-0.25 +-- Revision History: +-- Date Rev Version Comment +-- 2007-10-21 91 1.0.3 use 1 stop bits (redesigned _rx allows this) +-- 2007-10-19 90 1.0.2 use 2 stop bits (allow CLKDIV=0 operation in sim) +-- 2007-10-12 88 1.0.1 avoid ieee.std_logic_unsigned, use cast to unsigned +-- 2007-06-30 62 1.0 Initial version +------------------------------------------------------------------------------ + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; + +use work.slvtypes.all; + +entity serport_uart_tx is -- serial port uart: transmit part + generic ( + CDWIDTH : positive := 13); -- clk divider width + port ( + CLK : in slbit; -- clock + RESET : in slbit; -- reset + CLKDIV : in slv(CDWIDTH-1 downto 0); -- clock divider setting + TXSD : out slbit; -- transmit serial data (uart view) + TXDATA : in slv8; -- transmit data in + TXENA : in slbit; -- transmit data enable + TXBUSY : out slbit -- transmit busy + ); +end serport_uart_tx; + + +architecture syn of serport_uart_tx is + + type regs_type is record + ccnt : slv(CDWIDTH-1 downto 0); -- clock divider counter + bcnt : slv4; -- bit counter + sreg : slv9; -- output shift register + busy : slbit; + end record regs_type; + + constant cntzero : slv(CDWIDTH-1 downto 0) := (others=>'0'); + constant regs_init : regs_type := ( + cntzero, + (others=>'0'), + (others=>'1'), -- sreg to all 1 !! + '0' + ); + + signal R_REGS : regs_type := regs_init; -- state registers + signal N_REGS : regs_type := regs_init; -- next value state regs + +begin + + proc_regs: process (CLK) + begin + + if CLK'event and CLK='1' then + R_REGS <= N_REGS; + end if; + + end process proc_regs; + + proc_next: process (R_REGS, RESET, CLKDIV, TXDATA, TXENA) + + variable r : regs_type := regs_init; + variable n : regs_type := regs_init; + variable ld_ccnt : slbit := '0'; + + begin + + r := R_REGS; + n := R_REGS; + ld_ccnt := '0'; + + if r.busy = '0' then + ld_ccnt := '1'; + n.bcnt := (others=>'0'); + if TXENA = '1' then + n.sreg := TXDATA & '0'; -- add start (0) bit + n.busy := '1'; + end if; + + else + + if unsigned(r.ccnt) = 0 then + ld_ccnt := '1'; + n.sreg := '1' & r.sreg(8 downto 1); + n.bcnt := unsigned(r.bcnt) + 1; + if unsigned(r.bcnt) = 9 then -- if 10 bits send + n.busy := '0'; -- declare all done + end if; + end if; + end if; + + if RESET = '1' then + ld_ccnt := '1'; + n.busy := '0'; + end if; + + if ld_ccnt = '1' then + n.ccnt := CLKDIV; + else + n.ccnt := unsigned(r.ccnt) - 1; + end if; + + N_REGS <= n; + + TXBUSY <= r.busy; + TXSD <= r.sreg(0); + + end process proc_next; + +end syn; diff --git a/rtl/vlib/serport/tb/.cvsignore b/rtl/vlib/serport/tb/.cvsignore new file mode 100644 index 00000000..cfec62b6 --- /dev/null +++ b/rtl/vlib/serport/tb/.cvsignore @@ -0,0 +1,15 @@ +tb_serport_autobaud +tb_serport_autobaud_stim +tb_serport_autobaud_[sft]sim +tb_serport_autobaud_ISim +tb_serport_autobaud_ISim_[sft]sim +tb_serport_uart_rx +tb_serport_uart_rx_stim +tb_serport_uart_rx_[sft]sim +tb_serport_uart_rx_ISim +tb_serport_uart_rx_ISim_[sft]sim +tb_serport_uart_rxtx +tb_serport_uart_rxtx_stim +tb_serport_uart_rxtx_[sft]sim +tb_serport_uart_rxtx_ISim +tb_serport_uart_rxtx_ISim_[sft]sim diff --git a/rtl/vlib/serport/tb/Makefile b/rtl/vlib/serport/tb/Makefile new file mode 100644 index 00000000..aaa5107a --- /dev/null +++ b/rtl/vlib/serport/tb/Makefile @@ -0,0 +1,30 @@ +# $Id: Makefile 311 2010-06-30 17:52:37Z mueller $ +# +# Revision History: +# Date Rev Version Comment +# 2009-11-21 252 1.2 add ISim support +# 2007-11-26 98 1.1 use make includes +# 2007-06-03 48 1.0 Initial version +# +EXE_all = tb_serport_uart_rx tb_serport_uart_rxtx tb_serport_autobaud +# +.phony : all all_ssim all_tsim clean +# +all : $(EXE_all) +all_ssim : $(EXE_all:=_ssim) +all_tsim : $(EXE_all:=_tsim) +# +clean : ise_clean ghdl_clean isim_clean +# +#----- +# +include $(RETROBASE)/rtl/vlib/Makefile.ghdl +include $(RETROBASE)/rtl/vlib/Makefile.isim +include $(RETROBASE)/rtl/vlib/Makefile.xflow +# +VBOM_all = $(wildcard *.vbom) +# +include $(VBOM_all:.vbom=.dep_xst) +include $(VBOM_all:.vbom=.dep_ghdl) +include $(VBOM_all:.vbom=.dep_isim) +# diff --git a/rtl/vlib/serport/tb/tb_serport_autobaud.vbom b/rtl/vlib/serport/tb/tb_serport_autobaud.vbom new file mode 100644 index 00000000..3b1317b8 --- /dev/null +++ b/rtl/vlib/serport/tb/tb_serport_autobaud.vbom @@ -0,0 +1,9 @@ +# libs +../../slvtypes.vhd +../../simlib/simlib.vhd +../serport.vhd +# components +../../simlib/simclk.vbom +tbd_serport_autobaud : tbd_serport_autobaud.vbom +# design +tb_serport_autobaud.vhd diff --git a/rtl/vlib/serport/tb/tb_serport_autobaud.vhd b/rtl/vlib/serport/tb/tb_serport_autobaud.vhd new file mode 100644 index 00000000..996ebe57 --- /dev/null +++ b/rtl/vlib/serport/tb/tb_serport_autobaud.vhd @@ -0,0 +1,292 @@ +-- $Id: tb_serport_autobaud.vhd 314 2010-07-09 17:38:41Z mueller $ +-- +-- Copyright 2007-2010 by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, 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 complete details. +-- +------------------------------------------------------------------------------ +-- Module Name: tb_serport_autobaud - sim +-- Description: Test bench for serport_autobaud +-- +-- Dependencies: simlib/simclk +-- tbd_serport_autobaud [UUT] +-- +-- To test: serport_autobaud +-- +-- Target Devices: generic +-- +-- Verified (with tb_serport_autobaud_stim.dat): +-- Date Rev Code ghdl ise Target Comment +-- 2007-11-02 93 _tsim 0.26 8.2.03 I34 xc3s1000 d:ok +-- 2007-10-21 91 _ssim 0.26 8.1.03 I27 xc3s1000 c:ok +-- 2007-10-21 91 - 0.26 - - c:ok +-- 2007-10-14 89 - 0.26 - - c:ok +-- 2007-10-12 88 _ssim 0.26 8.1.03 I27 xc3s1000 c:ok +-- 2007-10-12 88 - 0.26 - - c:ok +-- +-- Revision History: +-- Date Rev Version Comment +-- 2010-04-24 281 1.1.2 use direct instatiation for tbd_ +-- 2008-03-24 129 1.1.1 CLK_CYCLE now 31 bits +-- 2007-10-21 91 1.1 now use 'send' command, self-checking (FAIL's) +-- 2007-10-14 89 1.1 add extra stop bit for CLKDIV=0; drop c2out wait; +-- add moni for autobauder +-- 2007-10-12 88 1.0.1 avoid ieee.std_logic_unsigned, use cast to unsigned +-- 2007-08-27 76 1.0 Initial version +------------------------------------------------------------------------------ + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; +use ieee.std_logic_textio.all; +use std.textio.all; + +use work.slvtypes.all; +use work.simlib.all; +use work.serport.all; + +entity tb_serport_autobaud is +end tb_serport_autobaud; + +architecture sim of tb_serport_autobaud is + + signal CLK : slbit := '0'; + signal RESET : slbit := '0'; + signal RXSD : slbit := '0'; + signal CE_USEC : slbit := '0'; + signal CE_MSEC : slbit := '0'; + signal CLKDIV : slv13 := (others=>'0'); + signal ABACT : slbit := '0'; + signal ABDONE : slbit := '0'; + signal RXDATA : slv8 := (others=>'0'); + signal RXVAL : slbit := '0'; + signal RXERR : slbit := '0'; + signal RXACT : slbit := '0'; + signal TXSD2 : slbit := '0'; + signal RXDATA3 : slv8 := (others=>'0'); + signal RXVAL3 : slbit := '0'; + signal RXERR3 : slbit := '0'; + signal RXACT3 : slbit := '0'; + + signal CLK_STOP : slbit := '0'; + signal CLK_CYCLE : slv31 := (others=>'0'); + + signal N_MON_VAL : slbit := '0'; + signal N_MON_DAT : slv8 := (others=>'0'); + signal R_MON_VAL_1 : slbit := '0'; + signal R_MON_DAT_1 : slv8 := (others=>'0'); + signal R_MON_VAL_2 : slbit := '0'; + signal R_MON_DAT_2 : slv8 := (others=>'0'); + + constant clock_period : time := 20 ns; + constant clock_offset : time := 200 ns; + constant setup_time : time := 5 ns; + constant c2out_time : time := 10 ns; + +begin + + SYSCLK : simclk + generic map ( + PERIOD => clock_period, + OFFSET => clock_offset) + port map ( + CLK => CLK, + CLK_CYCLE => CLK_CYCLE, + CLK_STOP => CLK_STOP + ); + + UUT : entity work.tbd_serport_autobaud + port map ( + CLK => CLK, + RESET => RESET, + RXSD => RXSD, + CE_USEC => CE_USEC, + CE_MSEC => CE_MSEC, + CLKDIV => CLKDIV, + ABACT => ABACT, + ABDONE => ABDONE, + RXDATA => RXDATA, + RXVAL => RXVAL, + RXERR => RXERR, + RXACT => RXACT, + TXSD2 => TXSD2, + RXDATA3 => RXDATA3, + RXVAL3 => RXVAL3, + RXERR3 => RXERR3, + RXACT3 => RXACT3 + ); + + + proc_stim: process + file fstim : text open read_mode is "tb_serport_autobaud_stim"; + variable iline : line; + variable oline : line; + variable ok : boolean; + variable dname : string(1 to 6) := (others=>' '); + variable idelta : integer := 0; + variable irate : integer := 16; + variable ival : slbit; + variable itxdata : slv8 := (others=>'0'); + + begin + + RXSD <= '1'; + + wait for clock_offset - setup_time; + + file_loop: while not endfile(fstim) loop + + readline (fstim, iline); + + readcomment(iline, ok); + next file_loop when ok; + + readword(iline, dname, ok); + if ok then + case dname is + when ".reset" => -- .reset + write(oline, string'(".reset")); + writeline(output, oline); + RESET <= '1'; + wait for clock_period; + RESET <= '0'; + wait for 9*clock_period; + + when ".break" => -- .break + read_ea(iline, idelta); + write(oline, string'(".break")); + writeline(output, oline); + RXSD <= '0'; + wait for idelta*clock_period; + RXSD <= '1'; + + when ".wait " => -- .wait + read_ea(iline, idelta); + wait for idelta*clock_period; + + when ".rate " => -- .rate + read_ea(iline, irate); + + when "send " => -- send + read_ea(iline, ival); + read_ea(iline, itxdata); + + writetimestamp(oline, CLK_CYCLE, ": send "); + write(oline, itxdata, right, 10); + writeline(output, oline); + + RXSD <= '0'; -- start bit + N_MON_VAL <= ival; + N_MON_DAT <= itxdata; + wait for clock_period; + N_MON_VAL <= '0'; + wait for (irate-1)*clock_period; + RXSD <= '1'; + + for i in itxdata'reverse_range loop -- transmit lsb first + RXSD <= itxdata(i); -- data bit + wait for irate*clock_period; + end loop; + + RXSD <= '1'; -- stop bit (plus extra cycle) + wait for (irate+1)*clock_period; + + when others => -- unknown command + write(oline, string'("?? unknown command: ")); + write(oline, dname); + writeline(output, oline); + report "aborting" severity failure; + end case; + + else + report "failed to find command" severity failure; + + end if; + + end loop; + + writetimestamp(oline, CLK_CYCLE, ": DONE "); + writeline(output, oline); + + wait for 25*irate*clock_period; + + CLK_STOP <= '1'; + + wait; -- suspend proc_stim forever + -- clock is stopped, sim will end + + end process proc_stim; + + + proc_moni: process + variable oline : line; + variable iabact : slbit := '0'; + begin + + loop + wait until CLK'event and CLK='1'; + + if R_MON_VAL_1 = '1' then + if R_MON_VAL_2 = '1' then + writetimestamp(oline, CLK_CYCLE, ": moni "); + write(oline, string'(" FAIL MISSING DATA=")); + write(oline, R_MON_DAT_2); + writeline(output, oline); + end if; + R_MON_VAL_2 <= R_MON_VAL_1; + R_MON_DAT_2 <= R_MON_DAT_1; + end if; + + R_MON_VAL_1 <= N_MON_VAL; + R_MON_DAT_1 <= N_MON_DAT; + + if (ABACT xor iabact)='1' then + writetimestamp(oline, CLK_CYCLE, ": auto ABACT ="); + write(oline, ABACT, right, 2); + iabact := ABACT; + writeline(output, oline); + end if; + + if ABDONE = '1' then + writetimestamp(oline, CLK_CYCLE, ": auto CLKDIV ="); + write(oline, conv_integer(unsigned(CLKDIV)), right, 3); + writeline(output, oline); + end if; + + if RXVAL='1' or (ABACT='0' and RXERR='1' and unsigned(RXDATA)/=0) then + writetimestamp(oline, CLK_CYCLE, ": moni "); + write(oline, RXDATA, right, 10); + if RXERR = '1' then + write(oline, string'(" RXERR=1")); + end if; + + if R_MON_VAL_2 = '0' then + write(oline, string'(" FAIL UNEXPECTED")); + else + write(oline, string'(" CHECK")); + R_MON_VAL_2 <= '0'; + + if R_MON_DAT_2 = RXDATA and + RXERR='0' then + write(oline, string'(" OK")); + else + write(oline, string'(" FAIL")); + end if; + + end if; + + writeline(output, oline); + end if; + + end loop; + + end process proc_moni; + +end sim; diff --git a/rtl/vlib/serport/tb/tb_serport_autobaud_ssim.vbom b/rtl/vlib/serport/tb/tb_serport_autobaud_ssim.vbom new file mode 100644 index 00000000..c68eeb90 --- /dev/null +++ b/rtl/vlib/serport/tb/tb_serport_autobaud_ssim.vbom @@ -0,0 +1,4 @@ +# configure for _*sim case +tbd_serport_autobaud = tbd_serport_autobaud_ssim.vhd +tb_serport_autobaud.vbom +@top:tb_serport_autobaud diff --git a/rtl/vlib/serport/tb/tb_serport_autobaud_stim.dat b/rtl/vlib/serport/tb/tb_serport_autobaud_stim.dat new file mode 100644 index 00000000..2ae81bf2 --- /dev/null +++ b/rtl/vlib/serport/tb/tb_serport_autobaud_stim.dat @@ -0,0 +1,77 @@ +# $Id: tb_serport_autobaud_stim.dat 311 2010-06-30 17:52:37Z mueller $ +# +# +C ---------------------------------------------------------------------------- +C start without autobauding and default setup clock divisor of 16 (CLKDIV=15) +.reset +.rate 16 +.wait 5 +send 1 00000001 +send 1 10000000 +# +C ---------------------------------------------------------------------------- +C now break + autobaud with clock divisor = 8 (CLKDIV=7) +.break 3000 +.wait 20 +.rate 8 +send 0 10000000 +send 1 10000000 +send 1 00000011 +send 1 00001100 +send 1 00110000 +send 1 11000000 +# +C ---------------------------------------------------------------------------- +C now break + autobaud with clock divisor = 4 (CLKDIV=3) +.break 3000 +.wait 20 +.rate 4 +send 0 10000000 +send 1 10000000 +send 1 00000011 +send 1 00001100 +send 1 00110000 +send 1 11000000 +# +C ---------------------------------------------------------------------------- +C now break + autobaud with clock divisor = 2 (CLKDIV=1) +.break 3000 +.wait 20 +.rate 2 +send 0 10000000 +send 1 10000000 +send 1 00000011 +send 1 00001100 +send 1 00110000 +send 1 11000000 +# +C ---------------------------------------------------------------------------- +C now break + autobaud with clock divisor = 1 (CLKDIV=0) +.break 3000 +.wait 20 +.rate 1 +send 0 10000000 +send 1 10000000 +send 1 01000000 +send 1 00100000 +send 1 00010000 +send 1 00001000 +send 1 00000100 +send 1 00000010 +send 1 00000001 +send 1 00000011 +send 1 00001100 +send 1 00110000 +send 1 11000000 +# +C ---------------------------------------------------------------------------- +C now break + autobaud with clock divisor = 32 (CLKDIV=31) +.break 3000 +.wait 20 +.rate 32 +send 0 10000000 +send 1 10000000 +send 1 00000011 +send 1 00001100 +send 1 00110000 +send 1 11000000 diff --git a/rtl/vlib/serport/tb/tb_serport_uart_rx.vbom b/rtl/vlib/serport/tb/tb_serport_uart_rx.vbom new file mode 100644 index 00000000..2be7c6b3 --- /dev/null +++ b/rtl/vlib/serport/tb/tb_serport_uart_rx.vbom @@ -0,0 +1,9 @@ +# libs +../../slvtypes.vhd +../../simlib/simlib.vhd +../serport.vhd +# components +../../simlib/simclk.vbom +tbd_serport_uart_rx : tbd_serport_uart_rx.vbom +# design +tb_serport_uart_rx.vhd diff --git a/rtl/vlib/serport/tb/tb_serport_uart_rx.vhd b/rtl/vlib/serport/tb/tb_serport_uart_rx.vhd new file mode 100644 index 00000000..803f20f0 --- /dev/null +++ b/rtl/vlib/serport/tb/tb_serport_uart_rx.vhd @@ -0,0 +1,328 @@ +-- $Id: tb_serport_uart_rx.vhd 314 2010-07-09 17:38:41Z mueller $ +-- +-- Copyright 2007-2010 by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, 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 complete details. +-- +------------------------------------------------------------------------------ +-- Module Name: tb_serport_uart_rx - sim +-- Description: Test bench for serport_uart_rx +-- +-- Dependencies: simlib/simclk +-- tbd_serport_uart_rx [UUT] +-- +-- To test: serport_uart_rx +-- +-- Target Devices: generic +-- +-- Verified (with tb_serport_uart_rx_stim.dat): +-- Date Rev Code ghdl ise Target Comment +-- 2007-11-02 93 _tsim 0.26 8.2.03 I34 xc3s1000 d:ok +-- 2007-10-21 91 _ssim 0.26 8.1.03 I27 xc3s1000 c:ok (63488 cl 15.21s) +-- 2007-10-21 91 - 0.26 - - c:ok (63488 cl 7.12s) +-- +-- Revision History: +-- Date Rev Version Comment +-- 2010-04-24 281 1.0.2 use direct instatiation for tbd_ +-- 2008-03-24 129 1.0.1 CLK_CYCLE now 31 bits +-- 2007-10-21 91 1.0 Initial version +------------------------------------------------------------------------------ + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; +use ieee.std_logic_textio.all; +use std.textio.all; + +use work.slvtypes.all; +use work.simlib.all; +use work.serport.all; + +entity tb_serport_uart_rx is +end tb_serport_uart_rx; + +architecture sim of tb_serport_uart_rx is + + signal CLK : slbit := '0'; + signal RESET : slbit := '0'; + signal CLKDIV : slv5 := conv_std_logic_vector(15, 5); + signal RXSD : slbit := '1'; + signal RXDATA : slv8 := (others=>'0'); + signal RXVAL : slbit := '0'; + signal RXERR : slbit := '0'; + signal RXACT : slbit := '0'; + + signal CLK_STOP : slbit := '0'; + signal CLK_CYCLE : slv31 := (others=>'0'); + + signal N_MON_VAL : slbit := '0'; + signal N_MON_ERR : slbit := '0'; + signal N_MON_DAT : slv8 := (others=>'0'); + signal R_MON_VAL_1 : slbit := '0'; + signal R_MON_ERR_1 : slbit := '0'; + signal R_MON_DAT_1 : slv8 := (others=>'0'); + signal R_MON_VAL_2 : slbit := '0'; + signal R_MON_ERR_2 : slbit := '0'; + signal R_MON_DAT_2 : slv8 := (others=>'0'); + + constant clock_period : time := 20 ns; + constant clock_offset : time := 200 ns; + constant setup_time : time := 5 ns; + constant c2out_time : time := 10 ns; + +begin + + SYSCLK : simclk + generic map ( + PERIOD => clock_period, + OFFSET => clock_offset) + port map ( + CLK => CLK, + CLK_CYCLE => CLK_CYCLE, + CLK_STOP => CLK_STOP + ); + + UUT : entity work.tbd_serport_uart_rx + port map ( + CLK => CLK, + RESET => RESET, + CLKDIV => CLKDIV, + RXSD => RXSD, + RXDATA => RXDATA, + RXVAL => RXVAL, + RXERR => RXERR, + RXACT => RXACT + ); + + + proc_stim: process + file fstim : text open read_mode is "tb_serport_uart_rx_stim"; + variable iline : line; + variable oline : line; + variable idelta : integer := 0; + variable itxdata : slv8 := (others=>'0'); + variable irxval : slbit := '0'; + variable irxerr : slbit := '0'; + variable irxdata : slv8 := (others=>'0'); + variable ok : boolean; + variable dname : string(1 to 6) := (others=>' '); + variable irate : integer := 16; + + type bit_10_array_type is array (0 to 9) of slbit; + type int_10_array_type is array (0 to 9) of integer; + variable valpuls : bit_10_array_type := (others=>'0'); + variable delpuls : int_10_array_type := (others=>0); + variable npuls : integer := 0; + + begin + + wait for clock_offset - setup_time; + + file_loop: while not endfile(fstim) loop + + readline (fstim, iline); + + readcomment(iline, ok); + next file_loop when ok; + + readword(iline, dname, ok); + if ok then + case dname is + when ".reset" => -- .reset + write(oline, string'(".reset")); + writeline(output, oline); + RESET <= '1'; + wait for clock_period; + RESET <= '0'; + wait for 9*clock_period; + + when ".wait " => -- .wait + read_ea(iline, idelta); + wait for idelta*clock_period; + + when ".rate " => -- .rate + idelta := 0; + while RXACT='1' loop -- ensure that uart isn't active + wait for clock_period; + idelta := idelta + 1; + exit when idelta>3000; + end loop; + read_ea(iline, irate); + wait for 2*clock_period; + CLKDIV <= conv_std_logic_vector(irate-1, CLKDIV'length); + wait for 2*clock_period; + + when ".xrate" => -- .xrate + read_ea(iline, irate); + + when "puls " => -- puls + writetimestamp(oline, CLK_CYCLE, ": puls "); + + read_ea(iline, irxval); + read_ea(iline, irxerr); + read_ea(iline, irxdata); + + npuls := 0; + for i in valpuls'range loop + testempty(iline, ok); + if ok then + exit; + end if; + read_ea(iline, valpuls(i)); + read_ea(iline, delpuls(i)); + assert delpuls(i)>0 + report "assert puls length > 0" severity failure; + npuls := npuls + 1; + write(oline, valpuls(i), right, 3); + write(oline, delpuls(i), right, 3); + end loop; -- i + writeline(output, oline); + + if npuls > 0 then + N_MON_VAL <= irxval; + N_MON_ERR <= irxerr; + N_MON_DAT <= irxdata; + for i in 0 to npuls-1 loop + RXSD <= valpuls(i); + wait for clock_period; + N_MON_VAL <= '0'; + wait for (delpuls(i)-1)*clock_period; + end loop; -- i + end if; + + when "send " => -- send + read_ea(iline, idelta); + read_ea(iline, itxdata); + + RXSD <= '1'; + wait for idelta*clock_period; + + writetimestamp(oline, CLK_CYCLE, ": send "); + write(oline, itxdata, right, 10); + writeline(output, oline); + + N_MON_VAL <= '1'; + N_MON_ERR <= '0'; + N_MON_DAT <= itxdata; + + RXSD <= '0'; -- start bit + wait for clock_period; + N_MON_VAL <= '0'; + wait for (irate-1)*clock_period; + RXSD <= '1'; + + for i in itxdata'reverse_range loop -- transmit lsb first + RXSD <= itxdata(i); -- data bit + wait for irate*clock_period; + end loop; + + RXSD <= '1'; -- stop bit + wait for irate*clock_period; + + when others => -- unknown command + write(oline, string'("?? unknown command: ")); + write(oline, dname); + writeline(output, oline); + report "aborting" severity failure; + end case; + + else + report "failed to find command" severity failure; + + end if; + + testempty_ea(iline); + end loop; -- file_loop: + + idelta := 0; + while RXACT='1' loop + wait for clock_period; + idelta := idelta + 1; + exit when idelta>3000; + end loop; + + writetimestamp(oline, CLK_CYCLE, ": DONE "); + writeline(output, oline); + + wait for 12*irate*clock_period; + + CLK_STOP <= '1'; + + wait; -- suspend proc_stim forever + -- clock is stopped, sim will end + + end process proc_stim; + + + proc_moni: process + variable oline : line; + begin + + loop + wait until CLK'event and CLK='1'; + + if R_MON_VAL_1 = '1' then + if R_MON_VAL_2 = '1' then + writetimestamp(oline, CLK_CYCLE, ": moni "); + write(oline, string'(" FAIL MISSING ERR=")); + write(oline, R_MON_ERR_2); + write(oline, string'(" DATA=")); + write(oline, R_MON_DAT_2); + writeline(output, oline); + end if; + R_MON_VAL_2 <= R_MON_VAL_1; + R_MON_ERR_2 <= R_MON_ERR_1; + R_MON_DAT_2 <= R_MON_DAT_1; + end if; + + R_MON_VAL_1 <= N_MON_VAL; + R_MON_ERR_1 <= N_MON_ERR; + R_MON_DAT_1 <= N_MON_DAT; + + if RXVAL='1' or RXERR='1' then + writetimestamp(oline, CLK_CYCLE, ": moni "); + write(oline, RXDATA, right, 10); + if RXERR = '1' then + write(oline, string'(" RXERR=1")); + end if; + + if R_MON_VAL_2 = '0' then + write(oline, string'(" FAIL UNEXPECTED")); + else + write(oline, string'(" CHECK")); + R_MON_VAL_2 <= '0'; + + if R_MON_ERR_2 = '0' then + if R_MON_DAT_2 = RXDATA and + RXERR='0' then + write(oline, string'(" OK")); + else + write(oline, string'(" FAIL")); + end if; + + else + if RXERR = '1' then + write(oline, string'(" OK")); + else + write(oline, string'(" FAIL, RXERR=1 expected")); + end if; + + end if; + + end if; + + writeline(output, oline); + end if; + + end loop; + + end process proc_moni; + +end sim; diff --git a/rtl/vlib/serport/tb/tb_serport_uart_rx_ssim.vbom b/rtl/vlib/serport/tb/tb_serport_uart_rx_ssim.vbom new file mode 100644 index 00000000..75ec6933 --- /dev/null +++ b/rtl/vlib/serport/tb/tb_serport_uart_rx_ssim.vbom @@ -0,0 +1,4 @@ +# configure for _*sim case +tbd_serport_uart_rx = tbd_serport_uart_rx_ssim.vhd +tb_serport_uart_rx.vbom +@top:tb_serport_uart_rx diff --git a/rtl/vlib/serport/tb/tb_serport_uart_rx_stim.dat b/rtl/vlib/serport/tb/tb_serport_uart_rx_stim.dat new file mode 100644 index 00000000..f53f66d4 --- /dev/null +++ b/rtl/vlib/serport/tb/tb_serport_uart_rx_stim.dat @@ -0,0 +1,529 @@ +# $Id: tb_serport_uart_rx_stim.dat 311 2010-06-30 17:52:37Z mueller $ +# +# +C setting rate=1 -> CLKDIV=0 ------------------------------------------------ +.wait 5 +.rate 1 +C test frame error (send 7,8,9,10 '0' bits, followed by 10 '1' bits) +puls 1 0 11000000 0 7 1 10 -- VAL=1 ERR=0 DAT=11000000 +puls 1 0 10000000 0 8 1 10 -- VAL=1 ERR=0 DAT=10000000 +puls 1 0 00000000 0 9 1 10 -- VAL=1 ERR=0 DAT=00000000 +puls 1 1 00000000 0 10 1 10 -- VAL=1 ERR=1 DAT=00000000 +C test 1 stop bits +puls 1 0 00000000 0 9 1 1 -- 1 stop bit VAL=1 ERR=0 DAT=00000000 +puls 1 0 11111111 0 1 1 9 -- 1 stop bit VAL=1 ERR=0 DAT=11111111 +puls 1 0 00000000 0 9 1 1 -- 1 stop bit VAL=1 ERR=0 DAT=00000000 +puls 1 0 11111111 0 1 1 9 -- 1 stop bit VAL=1 ERR=0 DAT=11111111 +C test 2 stop bits +puls 1 0 00000000 0 9 1 2 -- 2 stop bit VAL=1 ERR=0 DAT=00000000 +puls 1 0 11111111 0 1 1 10 -- 2 stop bit VAL=1 ERR=0 DAT=11111111 +puls 1 0 00000000 0 9 1 2 -- 2 stop bit VAL=1 ERR=0 DAT=00000000 +puls 1 0 11111111 0 1 1 10 -- 2 stop bit VAL=1 ERR=0 DAT=11111111 +C test 3 stop bits +puls 1 0 00000000 0 9 1 3 -- 3 stop bit VAL=1 ERR=0 DAT=00000000 +puls 1 0 11111111 0 1 1 11 -- 3 stop bit VAL=1 ERR=0 DAT=11111111 +puls 1 0 00000000 0 9 1 3 -- 3 stop bit VAL=1 ERR=0 DAT=00000000 +puls 1 0 11111111 0 1 1 11 -- 3 stop bit VAL=1 ERR=0 DAT=11111111 +C test 4 stop bits +puls 1 0 00000000 0 9 1 4 -- 4 stop bit VAL=1 ERR=0 DAT=00000000 +puls 1 0 11111111 0 1 1 12 -- 4 stop bit VAL=1 ERR=0 DAT=11111111 +puls 1 0 00000000 0 9 1 4 -- 4 stop bit VAL=1 ERR=0 DAT=00000000 +puls 1 0 11111111 0 1 1 12 -- 4 stop bit VAL=1 ERR=0 DAT=11111111 +C test back-to-back data +send 0 00000000 +send 0 00000001 +send 0 00000010 +send 0 00000100 +send 0 00001000 +send 0 00010000 +send 0 00100000 +send 0 01000000 +send 0 10000000 +send 0 11111110 +send 0 11111101 +send 0 11111011 +send 0 11110111 +send 0 11101111 +send 0 11011111 +send 0 10111111 +send 0 01111111 +send 0 00000000 +send 0 11111111 +send 0 00000011 +send 0 00001100 +send 0 00110000 +send 0 11000000 +C test data with 2 stop bits +send 1 00000000 +send 1 00000001 +send 1 00000010 +send 1 00000100 +send 1 00001000 +send 1 00010000 +send 1 00100000 +send 1 01000000 +send 1 10000000 +send 1 11111110 +send 1 11111101 +send 1 11111011 +send 1 11110111 +send 1 11101111 +send 1 11011111 +send 1 10111111 +send 1 01111111 +send 1 00000000 +send 1 11111111 +send 1 00000011 +send 1 00001100 +send 1 00110000 +send 1 11000000 +C test data with 3 stop bits +send 2 00000000 +send 2 00000001 +send 2 00000010 +send 2 00000100 +send 2 00001000 +send 2 00010000 +send 2 00100000 +send 2 01000000 +send 2 10000000 +send 2 11111110 +send 2 11111101 +send 2 11111011 +send 2 11110111 +send 2 11101111 +send 2 11011111 +send 2 10111111 +send 2 01111111 +send 2 00000000 +send 2 11111111 +send 2 00000011 +send 2 00001100 +send 2 00110000 +send 2 11000000 +# +C setting rate=2 -> CLKDIV=1 ------------------------------------------------ +.wait 5 +.rate 2 +C test frame error (send 16,17,18,19,20 '0' bits, followed by 10 '1' bits) +puls 1 0 10000000 0 16 1 10 -- VAL=1 ERR=0 DAT=10000000 +puls 1 0 10000000 0 17 1 10 -- VAL=1 ERR=0 DAT=10000000 +puls 1 0 00000000 0 18 1 10 -- VAL=1 ERR=0 DAT=00000000 +puls 1 0 00000000 0 19 1 10 -- VAL=1 ERR=0 DAT=00000000 +puls 1 1 00000000 0 20 1 10 -- VAL=1 ERR=1 DAT=00000000 +C test 1 stop bits +puls 1 0 00000000 0 18 1 2 -- 1 stop bit VAL=1 ERR=0 DAT=00000000 +puls 1 0 11111111 0 2 1 18 -- 1 stop bit VAL=1 ERR=0 DAT=11111111 +puls 1 0 00000000 0 18 1 2 -- 1 stop bit VAL=1 ERR=0 DAT=00000000 +puls 1 0 11111111 0 2 1 18 -- 1 stop bit VAL=1 ERR=0 DAT=11111111 +C test 2 stop bits +puls 1 0 00000000 0 18 1 4 -- 2 stop bit VAL=1 ERR=0 DAT=00000000 +puls 1 0 11111111 0 2 1 20 -- 2 stop bit VAL=1 ERR=0 DAT=11111111 +puls 1 0 00000000 0 18 1 4 -- 2 stop bit VAL=1 ERR=0 DAT=00000000 +puls 1 0 11111111 0 2 1 20 -- 2 stop bit VAL=1 ERR=0 DAT=11111111 +C test 3 stop bits +puls 1 0 00000000 0 18 1 6 -- 3 stop bit VAL=1 ERR=0 DAT=00000000 +puls 1 0 11111111 0 2 1 22 -- 3 stop bit VAL=1 ERR=0 DAT=11111111 +puls 1 0 00000000 0 18 1 6 -- 3 stop bit VAL=1 ERR=0 DAT=00000000 +puls 1 0 11111111 0 2 1 22 -- 3 stop bit VAL=1 ERR=0 DAT=11111111 +C test 4 stop bits +puls 1 0 00000000 0 18 1 8 -- 4 stop bit VAL=1 ERR=0 DAT=00000000 +puls 1 0 11111111 0 2 1 24 -- 4 stop bit VAL=1 ERR=0 DAT=11111111 +puls 1 0 00000000 0 18 1 8 -- 4 stop bit VAL=1 ERR=0 DAT=00000000 +puls 1 0 11111111 0 2 1 24 -- 4 stop bit VAL=1 ERR=0 DAT=11111111 +C test back-to-back data +send 0 00000000 +send 0 00000001 +send 0 00000010 +send 0 00000100 +send 0 00001000 +send 0 00010000 +send 0 00100000 +send 0 01000000 +send 0 10000000 +send 0 11111110 +send 0 11111101 +send 0 11111011 +send 0 11110111 +send 0 11101111 +send 0 11011111 +send 0 10111111 +send 0 01111111 +send 0 00000000 +send 0 11111111 +send 0 00000011 +send 0 00001100 +send 0 00110000 +send 0 11000000 +C test data with 2 stop bits +send 1 00000000 +send 1 00000001 +send 1 00000010 +send 1 00000100 +send 1 00001000 +send 1 00010000 +send 1 00100000 +send 1 01000000 +send 1 10000000 +send 1 11111110 +send 1 11111101 +send 1 11111011 +send 1 11110111 +send 1 11101111 +send 1 11011111 +send 1 10111111 +send 1 01111111 +send 1 00000000 +send 1 11111111 +send 1 00000011 +send 1 00001100 +send 1 00110000 +send 1 11000000 +C test data with 3 stop bits +send 2 00000000 +send 2 00000001 +send 2 00000010 +send 2 00000100 +send 2 00001000 +send 2 00010000 +send 2 00100000 +send 2 01000000 +send 2 10000000 +send 2 11111110 +send 2 11111101 +send 2 11111011 +send 2 11110111 +send 2 11101111 +send 2 11011111 +send 2 10111111 +send 2 01111111 +send 2 00000000 +send 2 11111111 +send 2 00000011 +send 2 00001100 +send 2 00110000 +send 2 11000000 +# +C setting rate=4 -> CLKDIV=3 ------------------------------------------------ +.wait 5 +.rate 4 +C test back-to-back data +send 0 00000000 +send 0 00000001 +send 0 00000010 +send 0 00000100 +send 0 00001000 +send 0 00010000 +send 0 00100000 +send 0 01000000 +send 0 10000000 +send 0 11111110 +send 0 11111101 +send 0 11111011 +send 0 11110111 +send 0 11101111 +send 0 11011111 +send 0 10111111 +send 0 01111111 +send 0 00000000 +send 0 11111111 +send 0 00000011 +send 0 00001100 +send 0 00110000 +send 0 11000000 +C test data with 2 stop bits +send 1 00000000 +send 1 00000001 +send 1 00000010 +send 1 00000100 +send 1 00001000 +send 1 00010000 +send 1 00100000 +send 1 01000000 +send 1 10000000 +send 1 11111110 +send 1 11111101 +send 1 11111011 +send 1 11110111 +send 1 11101111 +send 1 11011111 +send 1 10111111 +send 1 01111111 +send 1 00000000 +send 1 11111111 +send 1 00000011 +send 1 00001100 +send 1 00110000 +send 1 11000000 +# +C setting rate=16 -> CLKDIV=15 ----------------------------------------------- +.wait 5 +.rate 16 +# +C test resonse to start bit runts +puls 0 0 00000000 0 1 1 20 -- will recover fast +puls 0 0 00000000 0 2 1 20 -- " +puls 0 0 00000000 0 3 1 20 +puls 0 0 00000000 0 4 1 20 +puls 0 0 00000000 0 6 1 20 +puls 1 0 11111111 0 10 1 200 -- will be taken as start bit +# +C test back-to-back data +send 0 00000000 +send 0 00000001 +send 0 00000010 +send 0 00000100 +send 0 00001000 +send 0 00010000 +send 0 00100000 +send 0 01000000 +send 0 10000000 +send 0 11111110 +send 0 11111101 +send 0 11111011 +send 0 11110111 +send 0 11101111 +send 0 11011111 +send 0 10111111 +send 0 01111111 +send 0 00000000 +send 0 11111111 +send 0 00000011 +send 0 00001100 +send 0 00110000 +send 0 11000000 +C test data with 2 stop bits +send 1 00000000 +send 1 11110000 +send 1 00001111 +send 1 11111111 +C test data with 3 stop bits +send 2 00000000 +send 2 11110000 +send 2 00001111 +send 2 11111111 +C test data with 4 stop bits +send 3 00000000 +send 3 11110000 +send 3 00001111 +send 3 11111111 +# +C setting rate=32 -> CLKDIV=31 ----------------------------------------------- +.wait 5 +.rate 32 +C test back-to-back data +send 0 00000000 +send 0 00000001 +send 0 00000010 +send 0 00000100 +send 0 00001000 +send 0 00010000 +send 0 00100000 +send 0 01000000 +send 0 10000000 +send 0 11111110 +send 0 11111101 +send 0 11111011 +send 0 11110111 +send 0 11101111 +send 0 11011111 +send 0 10111111 +send 0 01111111 +send 0 00000000 +send 0 11111111 +send 0 00000011 +send 0 00001100 +send 0 00110000 +send 0 11000000 +C test data with 2 stop bits +send 1 00000000 +send 1 11110000 +send 1 00001111 +send 1 11111111 +C test data with 3 stop bits +send 2 00000000 +send 2 11110000 +send 2 00001111 +send 2 11111111 +C test data with 4 stop bits +send 3 00000000 +send 3 11110000 +send 3 00001111 +send 3 11111111 +# +C setting rate=32 -> CLKDIV=31 ---- txrate = 31 !! --------------------------- +.wait 5 +.rate 32 +.xrate 31 +C test back-to-back data +send 0 00000000 +send 0 00000001 +send 0 00000010 +send 0 00000100 +send 0 00001000 +send 0 00010000 +send 0 00100000 +send 0 01000000 +send 0 10000000 +send 0 11111110 +send 0 11111101 +send 0 11111011 +send 0 11110111 +send 0 11101111 +send 0 11011111 +send 0 10111111 +send 0 01111111 +send 0 00000000 +send 0 11111111 +send 0 00000011 +send 0 00001100 +send 0 00110000 +send 0 11000000 +C test data with 2 stop bits +send 1 00000000 +send 1 11110000 +send 1 00001111 +send 1 11111111 +C test data with 3 stop bits +send 2 00000000 +send 2 11110000 +send 2 00001111 +send 2 11111111 +C test data with 4 stop bits +send 3 00000000 +send 3 11110000 +send 3 00001111 +send 3 11111111 +# +C setting rate=32 -> CLKDIV=31 ---- txrate = 33 !! --------------------------- +.wait 5 +.rate 32 +.xrate 33 +C test back-to-back data +send 0 00000000 +send 0 00000001 +send 0 00000010 +send 0 00000100 +send 0 00001000 +send 0 00010000 +send 0 00100000 +send 0 01000000 +send 0 10000000 +send 0 11111110 +send 0 11111101 +send 0 11111011 +send 0 11110111 +send 0 11101111 +send 0 11011111 +send 0 10111111 +send 0 01111111 +send 0 00000000 +send 0 11111111 +send 0 00000011 +send 0 00001100 +send 0 00110000 +send 0 11000000 +C test data with 2 stop bits +send 1 00000000 +send 1 11110000 +send 1 00001111 +send 1 11111111 +C test data with 3 stop bits +send 2 00000000 +send 2 11110000 +send 2 00001111 +send 2 11111111 +C test data with 4 stop bits +send 3 00000000 +send 3 11110000 +send 3 00001111 +send 3 11111111 +# +C setting rate=27 -> CLKDIV=25 ---- txrate = 26 !! --------------------------- +.wait 5 +.rate 27 +.xrate 26 +C test back-to-back data +send 0 00000000 +send 0 00000001 +send 0 00000010 +send 0 00000100 +send 0 00001000 +send 0 00010000 +send 0 00100000 +send 0 01000000 +send 0 10000000 +send 0 11111110 +send 0 11111101 +send 0 11111011 +send 0 11110111 +send 0 11101111 +send 0 11011111 +send 0 10111111 +send 0 01111111 +send 0 00000000 +send 0 11111111 +send 0 00000011 +send 0 00001100 +send 0 00110000 +send 0 11000000 +C test data with 2 stop bits +send 1 00000000 +send 1 11110000 +send 1 00001111 +send 1 11111111 +C test data with 3 stop bits +send 2 00000000 +send 2 11110000 +send 2 00001111 +send 2 11111111 +C test data with 4 stop bits +send 3 00000000 +send 3 11110000 +send 3 00001111 +send 3 11111111 +# +C setting rate=27 -> CLKDIV=27 ---- txrate = 28 !! --------------------------- +.wait 5 +.rate 27 +.xrate 28 +C test back-to-back data +send 0 00000000 +send 0 00000001 +send 0 00000010 +send 0 00000100 +send 0 00001000 +send 0 00010000 +send 0 00100000 +send 0 01000000 +send 0 10000000 +send 0 11111110 +send 0 11111101 +send 0 11111011 +send 0 11110111 +send 0 11101111 +send 0 11011111 +send 0 10111111 +send 0 01111111 +send 0 00000000 +send 0 11111111 +send 0 00000011 +send 0 00001100 +send 0 00110000 +send 0 11000000 +C test data with 2 stop bits +send 1 00000000 +send 1 11110000 +send 1 00001111 +send 1 11111111 +C test data with 3 stop bits +send 2 00000000 +send 2 11110000 +send 2 00001111 +send 2 11111111 +C test data with 4 stop bits +send 3 00000000 +send 3 11110000 +send 3 00001111 +send 3 11111111 +# diff --git a/rtl/vlib/serport/tb/tb_serport_uart_rxtx.vbom b/rtl/vlib/serport/tb/tb_serport_uart_rxtx.vbom new file mode 100644 index 00000000..44dff80f --- /dev/null +++ b/rtl/vlib/serport/tb/tb_serport_uart_rxtx.vbom @@ -0,0 +1,9 @@ +# libs +../../slvtypes.vhd +../../simlib/simlib.vhd +../serport.vhd +# components +../../simlib/simclk.vbom +tbd_serport_uart_rxtx : tbd_serport_uart_rxtx.vbom +# design +tb_serport_uart_rxtx.vhd diff --git a/rtl/vlib/serport/tb/tb_serport_uart_rxtx.vhd b/rtl/vlib/serport/tb/tb_serport_uart_rxtx.vhd new file mode 100644 index 00000000..fd07e16e --- /dev/null +++ b/rtl/vlib/serport/tb/tb_serport_uart_rxtx.vhd @@ -0,0 +1,262 @@ +-- $Id: tb_serport_uart_rxtx.vhd 314 2010-07-09 17:38:41Z mueller $ +-- +-- Copyright 2007-2010 by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, 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 complete details. +-- +------------------------------------------------------------------------------ +-- Module Name: tb_serport_uart_rxtx - sim +-- Description: Test bench for serport_uart_rxtx +-- +-- Dependencies: simlib/simclk +-- tbd_serport_uart_rxtx [UUT] +-- +-- To test: serport_uart_rxtx +-- +-- Target Devices: generic +-- +-- Verified (with tb_serport_uart_rxtx_stim.dat): +-- Date Rev Code ghdl ise Target Comment +-- 2007-11-02 93 _tsim 0.26 8.2.03 I34 xc3s1000 d:ok +-- 2007-10-21 91 _ssim 0.26 8.1.03 I27 xc3s1000 c:ok +-- 2007-10-21 91 - 0.26 - - c:ok +-- 2007-10-14 89 - 0.26 - - c:ok +-- 2007-10-12 88 _ssim 0.26 8.1.03 I27 xc3s1000 c:ok +-- 2007-10-12 88 - 0.26 - - c:ok +-- +-- Revision History: +-- Date Rev Version Comment +-- 2010-04-24 281 1.1.2 use direct instatiation for tbd_ +-- 2008-03-24 129 1.1.1 CLK_CYCLE now 31 bits +-- 2007-10-21 91 1.1 now use 'send' command, self-checking (FAIL's) +-- 2007-10-12 88 1.0.1 avoid ieee.std_logic_unsigned, use cast to unsigned +-- 2007-08-27 76 1.0 Initial version +------------------------------------------------------------------------------ + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; +use ieee.std_logic_textio.all; +use std.textio.all; + +use work.slvtypes.all; +use work.simlib.all; +use work.serport.all; + +entity tb_serport_uart_rxtx is +end tb_serport_uart_rxtx; + +architecture sim of tb_serport_uart_rxtx is + + signal CLK : slbit := '0'; + signal RESET : slbit := '0'; + signal CLKDIV : slv13 := conv_std_logic_vector(15, 13); + signal RXDATA : slv8 := (others=>'0'); + signal RXVAL : slbit := '0'; + signal RXERR : slbit := '0'; + signal RXACT : slbit := '0'; + signal TXSD : slbit := '0'; + signal TXDATA : slv8 := (others=>'0'); + signal TXENA : slbit := '0'; + signal TXBUSY : slbit := '0'; + + signal CLK_STOP : slbit := '0'; + signal CLK_CYCLE : slv31 := (others=>'0'); + + signal N_MON_VAL : slbit := '0'; + signal N_MON_DAT : slv8 := (others=>'0'); + signal R_MON_VAL_1 : slbit := '0'; + signal R_MON_DAT_1 : slv8 := (others=>'0'); + signal R_MON_VAL_2 : slbit := '0'; + signal R_MON_DAT_2 : slv8 := (others=>'0'); + + constant clock_period : time := 20 ns; + constant clock_offset : time := 200 ns; + constant setup_time : time := 5 ns; + constant c2out_time : time := 10 ns; + +begin + + SYSCLK : simclk + generic map ( + PERIOD => clock_period, + OFFSET => clock_offset) + port map ( + CLK => CLK, + CLK_CYCLE => CLK_CYCLE, + CLK_STOP => CLK_STOP + ); + + UUT : entity work.tbd_serport_uart_rxtx + port map ( + CLK => CLK, + RESET => RESET, + CLKDIV => CLKDIV, + RXSD => TXSD, + RXDATA => RXDATA, + RXVAL => RXVAL, + RXERR => RXERR, + RXACT => RXACT, + TXSD => TXSD, + TXDATA => TXDATA, + TXENA => TXENA, + TXBUSY => TXBUSY + ); + + + proc_stim: process + file fstim : text open read_mode is "tb_serport_uart_rxtx_stim"; + variable iline : line; + variable oline : line; + variable idelta : integer := 0; + variable itxdata : slv8 := (others=>'0'); + variable ok : boolean; + variable dname : string(1 to 6) := (others=>' '); + variable irate : integer := 16; + + begin + + wait for clock_offset - setup_time; + + file_loop: while not endfile(fstim) loop + + readline (fstim, iline); + + readcomment(iline, ok); + next file_loop when ok; + + readword(iline, dname, ok); + if ok then + case dname is + when ".reset" => -- .reset + write(oline, string'(".reset")); + writeline(output, oline); + RESET <= '1'; + wait for clock_period; + RESET <= '0'; + wait for 9*clock_period; + + when ".wait " => -- .wait + read_ea(iline, idelta); + wait for idelta*clock_period; + + when ".rate " => -- .rate + read_ea(iline, irate); + CLKDIV <= conv_std_logic_vector(irate-1, 13); + + when "send " => -- send + read_ea(iline, idelta); + read_ea(iline, itxdata); + + while TXBUSY='1' loop + wait for clock_period; + end loop; + + wait for idelta*clock_period; + + writetimestamp(oline, CLK_CYCLE, ": send "); + write(oline, itxdata, right, 10); + writeline(output, oline); + + TXDATA <= itxdata; + TXENA <= '1'; + N_MON_VAL <= '1'; + N_MON_DAT <= itxdata; + + wait for clock_period; + TXENA <= '0'; + N_MON_VAL <= '0'; + + when others => -- unknown command + write(oline, string'("?? unknown command: ")); + write(oline, dname); + writeline(output, oline); + report "aborting" severity failure; + end case; + + else + report "failed to find command" severity failure; + + end if; + + testempty_ea(iline); + end loop; -- file_loop + + idelta := 0; + while TXBUSY='1' or RXACT='1' loop + wait for clock_period; + idelta := idelta + 1; + exit when idelta>3000; + end loop; + + writetimestamp(oline, CLK_CYCLE, ": DONE "); + writeline(output, oline); + + wait for 12*irate*clock_period; + + CLK_STOP <= '1'; + + wait; -- suspend proc_stim forever + -- clock is stopped, sim will end + + end process proc_stim; + + + proc_moni: process + variable oline : line; + begin + + loop + wait until CLK'event and CLK='1'; + + if R_MON_VAL_1 = '1' then + if R_MON_VAL_2 = '1' then + writetimestamp(oline, CLK_CYCLE, ": moni "); + write(oline, string'(" FAIL MISSING DATA=")); + write(oline, R_MON_DAT_2); + writeline(output, oline); + end if; + R_MON_VAL_2 <= R_MON_VAL_1; + R_MON_DAT_2 <= R_MON_DAT_1; + end if; + + R_MON_VAL_1 <= N_MON_VAL; + R_MON_DAT_1 <= N_MON_DAT; + + if RXVAL='1' or RXERR='1' then + writetimestamp(oline, CLK_CYCLE, ": moni "); + write(oline, RXDATA, right, 10); + if RXERR = '1' then + write(oline, string'(" RXERR=1")); + end if; + + if R_MON_VAL_2 = '0' then + write(oline, string'(" FAIL UNEXPECTED")); + else + write(oline, string'(" CHECK")); + R_MON_VAL_2 <= '0'; + + if R_MON_DAT_2 = RXDATA and + RXERR='0' then + write(oline, string'(" OK")); + else + write(oline, string'(" FAIL")); + end if; + + end if; + + writeline(output, oline); + end if; + + end loop; + + end process proc_moni; + +end sim; diff --git a/rtl/vlib/serport/tb/tb_serport_uart_rxtx_ssim.vbom b/rtl/vlib/serport/tb/tb_serport_uart_rxtx_ssim.vbom new file mode 100644 index 00000000..02225ee8 --- /dev/null +++ b/rtl/vlib/serport/tb/tb_serport_uart_rxtx_ssim.vbom @@ -0,0 +1,4 @@ +# configure for _*sim case +tbd_serport_uart_rxtx = tbd_serport_uart_rxtx_ssim.vhd +tb_serport_uart_rxtx.vbom +@top:tb_serport_uart_rxtx diff --git a/rtl/vlib/serport/tb/tb_serport_uart_rxtx_stim.dat b/rtl/vlib/serport/tb/tb_serport_uart_rxtx_stim.dat new file mode 100644 index 00000000..2feef810 --- /dev/null +++ b/rtl/vlib/serport/tb/tb_serport_uart_rxtx_stim.dat @@ -0,0 +1,57 @@ +# $Id: tb_serport_uart_rxtx_stim.dat 311 2010-06-30 17:52:37Z mueller $ +# +# +C ---------------------------------------------------------------------------- +C with startup setting rate=16 -> CLKDIV=15 +send 0 00000000 +send 0 00000001 +send 0 00000010 +send 0 00000100 +send 10 00001000 +send 50 00010000 +send 0 00100000 +send 0 01000000 +send 0 10000000 +send 0 11111111 +send 0 11001100 +send 0 00110011 +# +C ---------------------------------------------------------------------------- +# wait >16*10 cycles +.wait 200 +C now try rate=2 -> CLKDIV=1 +.rate 2 +.reset +.wait 20 +send 0 00000000 +send 0 00000001 +send 0 00000010 +send 0 00000100 +send 10 00001000 +send 50 00010000 +send 0 00100000 +send 0 01000000 +send 0 10000000 +send 0 11111111 +send 0 11001100 +send 0 00110011 +# +C ---------------------------------------------------------------------------- +# wait >2*10 cycles +.wait 30 +C now try rate=1 -> CLKDIV=0 +.rate 1 +.reset +.wait 20 +send 0 00000000 +send 0 00000001 +send 0 00000010 +send 0 00000100 +send 10 00001000 +send 50 00010000 +send 0 00100000 +send 0 01000000 +send 0 10000000 +send 0 11111111 +send 0 11001100 +send 0 00110011 diff --git a/rtl/vlib/serport/tb/tbd_serport_autobaud.vbom b/rtl/vlib/serport/tb/tbd_serport_autobaud.vbom new file mode 100644 index 00000000..312968c2 --- /dev/null +++ b/rtl/vlib/serport/tb/tbd_serport_autobaud.vbom @@ -0,0 +1,11 @@ +# libs +../../slvtypes.vhd +../../genlib/genlib.vhd +../serport.vhd +# components +../../genlib/clkdivce.vbom +../serport_uart_autobaud.vbom +../serport_uart_rxtx.vbom +../serport_uart_rx.vbom +# design +tbd_serport_autobaud.vhd diff --git a/rtl/vlib/serport/tb/tbd_serport_autobaud.vhd b/rtl/vlib/serport/tb/tbd_serport_autobaud.vhd new file mode 100644 index 00000000..36bdd61c --- /dev/null +++ b/rtl/vlib/serport/tb/tbd_serport_autobaud.vhd @@ -0,0 +1,152 @@ +-- $Id: tbd_serport_autobaud.vhd 314 2010-07-09 17:38:41Z mueller $ +-- +-- Copyright 2007- by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, 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 complete details. +-- +------------------------------------------------------------------------------ +-- Module Name: tbd_serport_autobaud - syn +-- Description: Wrapper for serport_uart_autobaud and serport_uart_rxtx to +-- avoid records. It has a port interface which will not be +-- modified by xst synthesis (no records, no generic port). +-- +-- Dependencies: clkdivce +-- serport_uart_autobaud +-- serport_uart_rxtx +-- serport_uart_rx +-- +-- To test: serport_uart_autobaud +-- serport_uart_rxtx +-- +-- Target Devices: generic +-- +-- Synthesized (xst): +-- Date Rev ise Target flop lutl lutm slic t peri +-- 2007-10-27 92 9.2.02 J39 xc3s1000-4 151 291 0 - t 9.23 +-- 2007-10-27 92 9.1 J30 xc3s1000-4 151 291 0 - t 9.23 +-- 2007-10-27 92 8.2.03 I34 xc3s1000-4 153 338 0 178 s 9.45 +-- 2007-10-27 92 8.1.03 I27 xc3s1000-4 152 293 0 - s 9.40 +-- +-- Tool versions: xst 8.1, 8.2, 9.1, 9.2; ghdl 0.18-0.25 +-- Revision History: +-- Date Rev Version Comment +-- 2008-01-20 112 1.0.1 rename clkgen->clkdivce +-- 2007-06-24 60 1.0 Initial version +------------------------------------------------------------------------------ + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; + +use work.slvtypes.all; +use work.genlib.all; +use work.serport.all; + +entity tbd_serport_autobaud is -- serial port autobaud [tb design] + port ( + CLK : in slbit; -- clock + RESET : in slbit; -- reset + RXSD : in slbit; -- receive serial data (uart view) + CE_USEC : out slbit; -- usec pulse (here every 4 clocks) + CE_MSEC : out slbit; -- msec pulse (here every 20 clocks) + CLKDIV : out slv13; -- clock divider setting + ABACT : out slbit; -- autobaud active + ABDONE : out slbit; -- autobaud done + RXDATA : out slv8; -- receiver data out (1st rx) + RXVAL : out slbit; -- receiver data valid (1st rx) + RXERR : out slbit; -- receiver data error (1st rx) + RXACT : out slbit; -- receiver active (1st rx) + TXSD2 : out slbit; -- transmit serial data (2nd tx) + RXDATA3 : out slv8; -- receiver data out (3rd rx) + RXVAL3 : out slbit; -- receiver data valid (3rd rx) + RXERR3 : out slbit; -- receiver data error (3rd rx) + RXACT3 : out slbit -- receiver active (3rd rx) + ); +end tbd_serport_autobaud; + + +architecture syn of tbd_serport_autobaud is + + constant cdwidth : positive := 13; + + signal LCE_MSEC : slbit := '0'; + signal LCLKDIV : slv13 := (others=>'0'); + signal LRXDATA : slv8 := (others=>'0'); + signal LRXVAL : slbit := '0'; + signal LTXSD2 : slbit := '0'; + signal LABACT : slbit := '0'; + +begin + + CKLDIV : clkdivce + generic map ( + CDUWIDTH => 6, + USECDIV => 4, + MSECDIV => 5) + port map ( + CLK => CLK, + CE_USEC => CE_USEC, + CE_MSEC => LCE_MSEC + ); + + AUTOBAUD : serport_uart_autobaud + generic map ( + CDWIDTH => cdwidth, + CDINIT => 15) + port map ( + CLK => CLK, + CE_MSEC => LCE_MSEC, + RESET => RESET, + RXSD => RXSD, + CLKDIV => LCLKDIV, + ACT => LABACT, + DONE => ABDONE + ); + + UART1 : serport_uart_rxtx + generic map ( + CDWIDTH => cdwidth) + port map ( + CLK => CLK, + RESET => LABACT, + CLKDIV => LCLKDIV, + RXSD => RXSD, + RXDATA => LRXDATA, + RXVAL => LRXVAL, + RXERR => RXERR, + RXACT => RXACT, + TXSD => LTXSD2, + TXDATA => LRXDATA, + TXENA => LRXVAL, + TXBUSY => open + ); + + UART2 : serport_uart_rx + generic map ( + CDWIDTH => cdwidth) + port map ( + CLK => CLK, + RESET => LABACT, + CLKDIV => LCLKDIV, + RXSD => LTXSD2, + RXDATA => RXDATA3, + RXVAL => RXVAL3, + RXERR => RXERR3, + RXACT => RXACT3 + ); + + CE_MSEC <= LCE_MSEC; + CLKDIV <= LCLKDIV; + ABACT <= LABACT; + RXDATA <= LRXDATA; + RXVAL <= LRXVAL; + TXSD2 <= LTXSD2; + +end syn; diff --git a/rtl/vlib/serport/tb/tbd_serport_uart_rx.vbom b/rtl/vlib/serport/tb/tbd_serport_uart_rx.vbom new file mode 100644 index 00000000..64b74c60 --- /dev/null +++ b/rtl/vlib/serport/tb/tbd_serport_uart_rx.vbom @@ -0,0 +1,7 @@ +# libs +../../slvtypes.vhd +../serport.vhd +# components +../serport_uart_rx.vbom +# design +tbd_serport_uart_rx.vhd diff --git a/rtl/vlib/serport/tb/tbd_serport_uart_rx.vhd b/rtl/vlib/serport/tb/tbd_serport_uart_rx.vhd new file mode 100644 index 00000000..bca2626c --- /dev/null +++ b/rtl/vlib/serport/tb/tbd_serport_uart_rx.vhd @@ -0,0 +1,79 @@ +-- $Id: tbd_serport_uart_rx.vhd 314 2010-07-09 17:38:41Z mueller $ +-- +-- Copyright 2007- by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, 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 complete details. +-- +------------------------------------------------------------------------------ +-- Module Name: tbd_serport_uart_rx - syn +-- Description: Wrapper for serport_uart_rx to avoid records. It +-- has a port interface which will not be modified by xst +-- synthesis (no records, no generic port). +-- +-- Dependencies: serport_uart_rx +-- +-- To test: serport_uart_rx +-- +-- Target Devices: generic +-- +-- Synthesized (xst): +-- Date Rev ise Target flop lutl lutm slic t peri +-- 2007-10-27 92 9.2.02 J39 xc3s1000-4 26 67 0 - t 8.17 +-- 2007-10-27 92 9.1 J30 xc3s1000-4 26 67 0 - t 8.25 +-- 2007-10-27 92 8.2.03 I34 xc3s1000-4 29 90 0 47 s 8.45 +-- 2007-10-27 92 8.1.03 I27 xc3s1000-4 31 92 0 - s 8.25 +-- +-- Tool versions: xst 8.1, 8.2, 9.1, 9.2; ghdl 0.18-0.25 +-- Revision History: +-- Date Rev Version Comment +-- 2007-10-21 91 1.0 Initial version +------------------------------------------------------------------------------ + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; + +use work.slvtypes.all; +use work.serport.all; + +entity tbd_serport_uart_rx is -- serial port uart rx [tb design] + -- generic: CDWIDTH=5 + port ( + CLK : in slbit; -- clock + RESET : in slbit; -- reset + CLKDIV : in slv5; -- clock divider setting + RXSD : in slbit; -- receive serial data (uart view) + RXDATA : out slv8; -- receiver data out + RXVAL : out slbit; -- receiver data valid + RXERR : out slbit; -- receiver data error (frame error) + RXACT : out slbit -- receiver active + ); +end tbd_serport_uart_rx; + + +architecture syn of tbd_serport_uart_rx is + +begin + + UART : serport_uart_rx + generic map ( + CDWIDTH => 5) + port map ( + CLK => CLK, + RESET => RESET, + CLKDIV => CLKDIV, + RXSD => RXSD, + RXDATA => RXDATA, + RXVAL => RXVAL, + RXERR => RXERR, + RXACT => RXACT + ); + +end syn; diff --git a/rtl/vlib/serport/tb/tbd_serport_uart_rxtx.vbom b/rtl/vlib/serport/tb/tbd_serport_uart_rxtx.vbom new file mode 100644 index 00000000..fa4069c9 --- /dev/null +++ b/rtl/vlib/serport/tb/tbd_serport_uart_rxtx.vbom @@ -0,0 +1,7 @@ +# libs +../../slvtypes.vhd +../serport.vhd +# components +../serport_uart_rxtx.vbom +# design +tbd_serport_uart_rxtx.vhd diff --git a/rtl/vlib/serport/tb/tbd_serport_uart_rxtx.vhd b/rtl/vlib/serport/tb/tbd_serport_uart_rxtx.vhd new file mode 100644 index 00000000..b4e00b88 --- /dev/null +++ b/rtl/vlib/serport/tb/tbd_serport_uart_rxtx.vhd @@ -0,0 +1,87 @@ +-- $Id: tbd_serport_uart_rxtx.vhd 314 2010-07-09 17:38:41Z mueller $ +-- +-- Copyright 2007- by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, 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 complete details. +-- +------------------------------------------------------------------------------ +-- Module Name: tbd_serport_uart_rxtx - syn +-- Description: Wrapper for serport_uart_rxtx to avoid records. It +-- has a port interface which will not be modified by xst +-- synthesis (no records, no generic port). +-- +-- Dependencies: serport_uart_rxtx +-- +-- To test: serport_uart_rxtx +-- +-- Target Devices: generic +-- +-- Synthesized (xst): +-- Date Rev ise Target flop lutl lutm slic t peri +-- 2007-10-27 92 9.2.02 J39 xc3s1000-4 69 122 0 - t 9.13 +-- 2007-10-27 92 9.1 J30 xc3s1000-4 69 122 0 - t 9.13 +-- 2007-10-27 92 8.2.03 I34 xc3s1000-4 73 152 0 81 s 9.30 +-- 2007-10-27 92 8.1.03 I27 xc3s1000-4 73 125 0 - s 9.30 +-- +-- Tool versions: xst 8.1, 8.2, 9.1, 9.2; ghdl 0.18-0.25 +-- Revision History: +-- Date Rev Version Comment +-- 2007-10-21 91 1.0 Initial version +------------------------------------------------------------------------------ + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; + +use work.slvtypes.all; +use work.serport.all; + +entity tbd_serport_uart_rxtx is -- serial port uart [tb design] + -- generic: CDWIDTH=13 + port ( + CLK : in slbit; -- clock + RESET : in slbit; -- reset + CLKDIV : in slv13; -- clock divider setting + RXSD : in slbit; -- receive serial data (uart view) + RXDATA : out slv8; -- receiver data out + RXVAL : out slbit; -- receiver data valid + RXERR : out slbit; -- receiver data error (frame error) + RXACT : out slbit; -- receiver active + TXSD : out slbit; -- transmit serial data (uart view) + TXDATA : in slv8; -- transmit data in + TXENA : in slbit; -- transmit data enable + TXBUSY : out slbit -- transmit busy + ); +end tbd_serport_uart_rxtx; + + +architecture syn of tbd_serport_uart_rxtx is + +begin + + UART : serport_uart_rxtx + generic map ( + CDWIDTH => 13) + port map ( + CLK => CLK, + RESET => RESET, + CLKDIV => CLKDIV, + RXSD => RXSD, + RXDATA => RXDATA, + RXVAL => RXVAL, + RXERR => RXERR, + RXACT => RXACT, + TXSD => TXSD, + TXDATA => TXDATA, + TXENA => TXENA, + TXBUSY => TXBUSY + ); + +end syn; diff --git a/rtl/vlib/simlib/simbus.vhd b/rtl/vlib/simlib/simbus.vhd new file mode 100644 index 00000000..10aefdba --- /dev/null +++ b/rtl/vlib/simlib/simbus.vhd @@ -0,0 +1,46 @@ +-- $Id: simbus.vhd 314 2010-07-09 17:38:41Z mueller $ +-- +-- Copyright 2007-2010 by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, 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 complete details. +-- +------------------------------------------------------------------------------ +-- Package Name: simbus +-- Description: Global signals for support control in test benches +-- +-- Dependencies: - +-- Tool versions: xst 8.1, 8.2, 9.1, 9.2, 11.4; ghdl 0.18-0.25 +-- Revision History: +-- Date Rev Version Comment +-- 2010-04-24 282 1.1 add SB_(VAL|ADDR|DATA) +-- 2008-03-24 129 1.0.1 use 31 bits for SB_CLKCYCLE +-- 2007-08-27 76 1.0 Initial version +------------------------------------------------------------------------------ + +library ieee; +use ieee.std_logic_1164.all; + +use work.slvtypes.all; + +package simbus is + + signal SB_CLKSTOP : slbit := '0'; -- global clock stop + signal SB_CLKCYCLE : slv31 := (others=>'0'); -- global clock cycle + signal SB_CNTL : slv16 := (others=>'0'); -- global signals tb -> uut + signal SB_STAT : slv16 := (others=>'0'); -- global signals uut -> tb + signal SB_VAL : slbit := '0'; -- init bcast valid + signal SB_ADDR : slv8 := (others=>'0'); -- init bcast address + signal SB_DATA : slv16 := (others=>'0'); -- init bcast data + + -- Note: SB_CNTL, SB_VAL, SB_ADDR, SB_DATA can have weak ('L','H') and + -- strong ('0','1') drivers. Therefore always remove strenght before + -- using, e.g. with to_x01() + +end package simbus; diff --git a/rtl/vlib/simlib/simclk.vbom b/rtl/vlib/simlib/simclk.vbom new file mode 100644 index 00000000..2f04a16c --- /dev/null +++ b/rtl/vlib/simlib/simclk.vbom @@ -0,0 +1,5 @@ +# libs +../slvtypes.vhd +# components +# design +simclk.vhd diff --git a/rtl/vlib/simlib/simclk.vhd b/rtl/vlib/simlib/simclk.vhd new file mode 100644 index 00000000..8ff42ff4 --- /dev/null +++ b/rtl/vlib/simlib/simclk.vhd @@ -0,0 +1,78 @@ +-- $Id: simclk.vhd 314 2010-07-09 17:38:41Z mueller $ +-- +-- Copyright 2007-2008 by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, 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 complete details. +-- +------------------------------------------------------------------------------ +-- Module Name: simclk - sim +-- Description: Clock generator for test benches +-- +-- Dependencies: - +-- Test bench: - +-- Target Devices: generic +-- Tool versions: xst 8.1, 8.2, 9.1, 9.2; ghdl 0.18-0.25 +-- Revision History: +-- Date Rev Version Comment +-- 2008-03-24 129 1.0.2 CLK_CYCLE now 31 bits +-- 2007-10-12 88 1.0.1 avoid ieee.std_logic_unsigned, use cast to unsigned +-- 2007-08-10 72 1.0 Initial version +------------------------------------------------------------------------------ + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; +use work.slvtypes.all; + +entity simclk is -- test bench clock generator + generic ( + PERIOD : time := 20 ns; -- clock period + OFFSET : time := 200 ns); -- clock offset (first up transition) + port ( + CLK : out slbit; -- clock + CLK_CYCLE : out slv31; -- clock cycle number + CLK_STOP : in slbit -- clock stop trigger + ); +end entity simclk; + +architecture sim of simclk is +begin + + clk_proc: process + constant clock_halfperiod : time := PERIOD/2; + variable icycle : slv31 := (others=>'0'); + begin + + CLK <= '0'; + CLK_CYCLE <= (others=>'0'); + wait for OFFSET; + + clk_loop: loop + CLK <= '1'; + wait for 0 ns; -- make a delta cycle so that clock + icycle := unsigned(icycle) + 1; -- cycle number is updated after the + CLK_CYCLE <= icycle; -- clock transition. all edge triggered + -- proc's will thus read old value. + wait for clock_halfperiod; + CLK <= '0'; + wait for clock_halfperiod; + exit clk_loop when CLK_STOP = '1'; + end loop; + + CLK <= '1'; -- final clock cycle for clk_sim + wait for clock_halfperiod; + CLK <= '0'; + wait for clock_halfperiod; + + wait; -- endless wait, simulator will stop + + end process; + +end sim; diff --git a/rtl/vlib/simlib/simlib.vhd b/rtl/vlib/simlib/simlib.vhd new file mode 100644 index 00000000..8555b5c8 --- /dev/null +++ b/rtl/vlib/simlib/simlib.vhd @@ -0,0 +1,1063 @@ +-- $Id: simlib.vhd 314 2010-07-09 17:38:41Z mueller $ +-- +-- Copyright 2006-2008 by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, 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 complete details. +-- +------------------------------------------------------------------------------ +-- Module Name: simlib - sim +-- Description: Support routines for test benches +-- +-- Dependencies: - +-- Test bench: - +-- Target Devices: generic +-- Tool versions: xst 8.1, 8.2, 9.1, 9.2; ghdl 0.18-0.25 +-- Revision History: +-- Date Rev Version Comment +-- 2008-03-24 129 1.3.5 CLK_CYCLE now 31 bits +-- 2008-03-02 121 1.3.4 added readempty (to discard rest of line) +-- 2007-12-27 106 1.3.3 added simclk2v +-- 2007-12-15 101 1.3.2 add read_ea(time), readtagval[_ea](std_logic) +-- 2007-10-12 88 1.3.1 avoid ieee.std_logic_unsigned, use cast to unsigned +-- 2007-08-28 76 1.3 added writehex and writegen +-- 2007-08-10 72 1.2.2 remove entity simclk, put into separate source +-- 2007-08-03 71 1.2.1 readgen, readtagval, readtagval2: add base arg +-- 2007-07-29 70 1.2 readtagval2: add tag=- support; add readword_ea, +-- readoptchar, writetimestamp +-- 2007-07-28 69 1.1.1 rename readrest -> testempty; add readgen +-- use readgen in readtagval() and readtagval2() +-- 2007-07-22 68 1.1 add readrest, readtagval, readtagval2 +-- 2007-06-30 62 1.0.1 remove clock_period ect constant defs +-- 2007-06-14 56 1.0 Initial version (renamed from pdp11_sim.vhd) +------------------------------------------------------------------------------ + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; +use ieee.std_logic_textio.all; +use std.textio.all; + +use work.slvtypes.all; + +package simlib is + +constant null_char : character := character'val(0); -- '\0' +constant null_string : string(1 to 1) := (others=>null_char); -- "\0" + +procedure readwhite( -- read over white space + L: inout line); -- line + +procedure readoct( -- read slv in octal base (arb. length) + L: inout line; -- line + value: out std_logic_vector; -- value to be read + good: out boolean); -- success flag + +procedure readhex( -- read slv in hex base (arb. length) + L: inout line; -- line + value: out std_logic_vector; -- value to be read + good: out boolean); -- success flag + +procedure readgen( -- read slv generic base + L: inout line; -- line + value: out std_logic_vector; -- value to be read + good: out boolean; -- success flag + base: in integer:= 2); -- default base + +procedure readcomment( + L: inout line; + good: out boolean); + +procedure readcommand( + L: inout line; + name: out string; + good: out boolean); + +procedure readword( + L: inout line; + name: out string; + good: out boolean); + +procedure readoptchar( + L: inout line; + char: in character; + good: out boolean); + +procedure readempty( + L: inout line); + +procedure testempty( + L: inout line; + good: out boolean); + +procedure testempty_ea( + L: inout line); + +procedure read_ea( + L: inout line; + value: out integer); +procedure read_ea( + L: inout line; + value: out time); + +procedure read_ea( + L: inout line; + value: out std_logic); +procedure read_ea( + L: inout line; + value: out std_logic_vector); + +procedure readoct_ea( + L: inout line; + value: out std_logic_vector); + +procedure readhex_ea( + L: inout line; + value: out std_logic_vector); + +procedure readgen_ea( + L: inout line; + value: out std_logic_vector; + base: in integer:= 2); + +procedure readword_ea( + L: inout line; + name: out string); + +procedure readtagval( + L: inout line; + tag: in string; + match: out boolean; + val: out std_logic_vector; + good: out boolean; + base: in integer:= 2); +procedure readtagval_ea( + L: inout line; + tag: in string; + match: out boolean; + val: out std_logic_vector; + base: in integer:= 2); + +procedure readtagval( + L: inout line; + tag: in string; + match: out boolean; + val: out std_logic; + good: out boolean); +procedure readtagval_ea( + L: inout line; + tag: in string; + match: out boolean; + val: out std_logic); + +procedure readtagval2( + L: inout line; + tag: in string; + match: out boolean; + val1: out std_logic_vector; + val2: out std_logic_vector; + good: out boolean; + base: in integer:= 2); +procedure readtagval2_ea( + L: inout line; + tag: in string; + match: out boolean; + val1: out std_logic_vector; + val2: out std_logic_vector; + base: in integer:= 2); + +procedure writeoct( -- write slv in octal base (arb. length) + L: inout line; -- line + value: in std_logic_vector; -- value to be written + justified: in side:=right; -- justification (left/right) + field: in width:=0); -- field width + +procedure writehex( -- write slv in hex base (arb. length) + L: inout line; -- line + value: in std_logic_vector; -- value to be written + justified: in side:=right; -- justification (left/right) + field: in width:=0); -- field width + +procedure writegen( -- write slv in generic base (arb. lth) + L: inout line; -- line + value: in std_logic_vector; -- value to be written + justified: in side:=right; -- justification (left/right) + field: in width:=0; -- field width + base: in integer:= 2); -- default base + +procedure writetimestamp( + L: inout line; + clkcyc: in slv31; + str : in string := null_string); + +-- ---------------------------------------------------------------------------- + +component simclk is -- test bench clock generator + generic ( + PERIOD : time := 20 ns; -- clock period + OFFSET : time := 200 ns); -- clock offset (first up transition) + port ( + CLK : out slbit; -- clock + CLK_CYCLE : out slv31; -- clock cycle number + CLK_STOP : in slbit -- clock stop trigger + ); +end component; + +component simclkv is -- test bench clock generator + -- with variable periods + port ( + CLK : out slbit; -- clock + CLK_CYCLE : out slv31; -- clock cycle number + CLK_PERIOD : in time; -- clock period + CLK_HOLD : in slbit; -- if 1, hold clocks in 0 state + CLK_STOP : in slbit -- clock stop trigger + ); +end component; + +end package simlib; + +-- ---------------------------------------------------------------------------- + +package body simlib is + +procedure readwhite( -- read over white space + L: inout line) is -- line + variable ch : character; +begin + while L'length>0 loop + ch := L(L'left); + exit when (ch/=' ' and ch/=HT); + read(L,ch); + end loop; + +end procedure readwhite; + +-- ------------------------------------- + +procedure readoct( -- read slv in octal base (arb. length) + L: inout line; -- line + value: out std_logic_vector; -- value to be read + good: out boolean) is -- success flag + + variable nibble : std_logic_vector(2 downto 0); + variable sum : std_logic_vector(31 downto 0); + variable ndig : integer; -- number of digits + variable ok : boolean; + variable ichar : character; + +begin + + assert not value'ascending(1) + report "readoct called with ascending range" + severity failure; + assert value'length<=32 + report "readoct called with value'length > 32" + severity failure; + + readwhite(L); + + ndig := 0; + sum := (others=>'U'); + + while L'length>0 loop + ok := true; + case L(L'left) is + when '0' => nibble := "000"; + when '1' => nibble := "001"; + when '2' => nibble := "010"; + when '3' => nibble := "011"; + when '4' => nibble := "100"; + when '5' => nibble := "101"; + when '6' => nibble := "110"; + when '7' => nibble := "111"; + when 'u'|'U' => nibble := "UUU"; + when 'x'|'X' => nibble := "XXX"; + when 'z'|'Z' => nibble := "ZZZ"; + when '-' => nibble := "---"; + when others => ok := false; + end case; + + exit when not ok; + read(L,ichar); + ndig := ndig + 1; + sum(sum'left downto 3) := sum(sum'left-3 downto 0); + sum(2 downto 0) := nibble; + end loop; + + ok := ndig>0; + value := sum(value'range); + good := ok; + +end procedure readoct; + +-- ------------------------------------- + +procedure readhex( -- read slv in hex base (arb. length) + L: inout line; -- line + value: out std_logic_vector; -- value to be read + good: out boolean) is -- success flag + + variable nibble : std_logic_vector(3 downto 0); + variable sum : std_logic_vector(31 downto 0); + variable ndig : integer; -- number of digits + variable ok : boolean; + variable ichar : character; + +begin + + assert not value'ascending(1) + report "readhex called with ascending range" + severity failure; + assert value'length<=32 + report "readhex called with value'length > 32" + severity failure; + + readwhite(L); + + ndig := 0; + sum := (others=>'U'); + + while L'length>0 loop + ok := true; + case L(L'left) is + when '0' => nibble := "0000"; + when '1' => nibble := "0001"; + when '2' => nibble := "0010"; + when '3' => nibble := "0011"; + when '4' => nibble := "0100"; + when '5' => nibble := "0101"; + when '6' => nibble := "0110"; + when '7' => nibble := "0111"; + when '8' => nibble := "1000"; + when '9' => nibble := "1001"; + when 'a'|'A' => nibble := "1010"; + when 'b'|'B' => nibble := "1011"; + when 'c'|'C' => nibble := "1100"; + when 'd'|'D' => nibble := "1101"; + when 'e'|'E' => nibble := "1110"; + when 'f'|'F' => nibble := "1111"; + when 'u'|'U' => nibble := "UUUU"; + when 'x'|'X' => nibble := "XXXX"; + when 'z'|'Z' => nibble := "ZZZZ"; + when '-' => nibble := "----"; + when others => ok := false; + end case; + + exit when not ok; + read(L,ichar); + ndig := ndig + 1; + sum(sum'left downto 4) := sum(sum'left-4 downto 0); + sum(3 downto 0) := nibble; + end loop; + + ok := ndig>0; + value := sum(value'range); + good := ok; + +end procedure readhex; + +-- ------------------------------------- + +procedure readgen( -- read slv generic base + L: inout line; -- line + value: out std_logic_vector; -- value to be read + good: out boolean; -- success flag + base: in integer := 2) is -- default base + + variable nibble : std_logic_vector(3 downto 0); + variable sum : std_logic_vector(31 downto 0); + variable lbase : integer; -- local base + variable cbase : integer; -- current base + variable ok : boolean; + variable ivalue : integer; + variable ichar : character; + +begin + + assert not value'ascending(1) + report "readgen called with ascending range" + severity failure; + assert value'length<=32 + report "readgen called with value'length > 32" + severity failure; + assert base=2 or base=8 or base=10 or base=16 + report "readgen base not 2,8,10, or 16" + severity failure; + + readwhite(L); + + cbase := base; + lbase := 0; + ok := true; + + if L'length >= 2 then + if L(L'left+1) = '"' then + case L(L'left) is + when 'b'|'B' => lbase := 2; + when 'o'|'O' => lbase := 8; + when 'd'|'D' => lbase := 10; + when 'x'|'X' => lbase := 16; + when others => ok := false; + end case; + end if; + if lbase /= 0 then + read(L, ichar); + read(L, ichar); + cbase := lbase; + end if; + end if; + + if ok then + case cbase is + when 2 => read(L, value, ok); + when 8 => readoct(L, value, ok); + when 16 => readhex(L, value, ok); + when 10 => + read(L, ivalue, ok); + value := conv_std_logic_vector(ivalue, value'length); + when others => null; + end case; + end if; + + if ok and lbase/=0 then + if L'length>0 and L(L'left)='"' then + read(L, ichar); + else + ok := false; + end if; + end if; + + good := ok; + +end procedure readgen; + +-- ------------------------------------- + +procedure readcomment( + L: inout line; + good: out boolean) is + variable ichar : character; +begin + + readwhite(L); + + good := true; + if L'length > 0 then + good := false; + if L(L'left) = '#' then + good := true; + elsif L(L'left) = 'C' then + good := true; + writeline(output, L); + end if; + end if; + +end procedure readcomment; + +-- ------------------------------------- + +procedure readcommand( + L: inout line; + name: out string; + good: out boolean) is +begin + + for i in name'range loop + name(i) := ' '; + end loop; + good := false; + + if L'length>0 and L(L'left)='.' then + readword(L, name, good); + end if; + +end procedure readcommand; + +-- ------------------------------------- + +procedure readword( + L: inout line; + name: out string; + good: out boolean) is + + variable ichar : character; + variable ind : integer; + +begin + + assert name'ascending(1) + report "readword called with descending range for name" + severity failure; + + readwhite(L); + + for i in name'range loop + name(i) := ' '; + end loop; + ind := name'left; + + while L'length>0 and ind<=name'right loop + ichar := L(L'left); + exit when ichar=' ' or ichar=',' or ichar='|'; + read(L,ichar); + name(ind) := ichar; + ind := ind + 1; + end loop; + + good := ind /= name'left; -- ok if one non-blank found + +end procedure readword; + +-- ------------------------------------- + +procedure readoptchar( + L: inout line; + char: in character; + good: out boolean) is + + variable ichar : character; + +begin + + good := false; + if L'length > 0 then + if L(L'left) = char then + read(L, ichar); + good := true; + end if; + end if; + +end procedure readoptchar; + +-- ------------------------------------- + +procedure readempty( + L: inout line) is + + variable ch : character; + +begin + + while L'length>0 loop -- anything left ? + read(L,ch); -- read and discard it + end loop; + +end procedure readempty; + +-- ------------------------------------- + +procedure testempty( + L: inout line; + good: out boolean) is + +begin + + readwhite(L); -- discard white space + good := true; -- good if now empty + + if L'length > 0 then -- anything left ? + good := false; -- assume bad + if L'length >= 2 and -- check for "--" + L(L'left)='-' and L(L'left+1)='-' then + good := true; -- in that case comment -> good + end if; + end if; + +end procedure testempty; + +-- ------------------------------------- + +procedure testempty_ea( + L: inout line) is + + variable ok : boolean := false; + +begin + + testempty(L, ok); + assert ok report "extra chars in """ & L.all & """" severity failure; + +end procedure testempty_ea; + +-- ------------------------------------- + +procedure read_ea( + L: inout line; + value: out integer) is + + variable ok : boolean := false; + +begin + + read(L, value, ok); + assert ok report "read(integer) conversion error in """ & + L.all & """" severity failure; + +end procedure read_ea; + +-- ------------------------------------- + +procedure read_ea( + L: inout line; + value: out time) is + + variable ok : boolean := false; + +begin + + read(L, value, ok); + assert ok report "read(time) conversion error in """ & + L.all & """" severity failure; + +end procedure read_ea; + +-- ------------------------------------- + +procedure read_ea( + L: inout line; + value: out std_logic) is + + variable ok : boolean := false; + +begin + + read(L, value, ok); + assert ok report "read(std_logic) conversion error in """ & + L.all & """" severity failure; + +end procedure read_ea; + +-- ------------------------------------- + +procedure read_ea( + L: inout line; + value: out std_logic_vector) is + + variable ok : boolean := false; + +begin + + read(L, value, ok); + assert ok report "read(std_logic_vector) conversion error in """ & + L.all & """" severity failure; + +end procedure read_ea; + +-- ------------------------------------- + +procedure readoct_ea( + L: inout line; + value: out std_logic_vector) is + + variable ok : boolean := false; + +begin + + readoct(L, value, ok); + assert ok report "readoct() conversion error in """ & + L.all & """" severity failure; + +end procedure readoct_ea; + +-- ------------------------------------- + +procedure readhex_ea( + L: inout line; + value: out std_logic_vector) is + + variable ok : boolean := false; + +begin + + readhex(L, value, ok); + assert ok report "readhex() conversion error in """ & + L.all & """" severity failure; + +end procedure readhex_ea; + +-- ------------------------------------- + +procedure readgen_ea( + L: inout line; + value: out std_logic_vector; + base: in integer := 2) is + + variable ok : boolean := false; + +begin + + readgen(L, value, ok, base); + assert ok report "readgen() conversion error in """ & + L.all & """" severity failure; + +end procedure readgen_ea; + +-- ------------------------------------- + +procedure readword_ea( + L: inout line; + name: out string) is + + variable ok : boolean := false; + +begin + + readword(L, name, ok); + assert ok report "readword() read error in """ & + L.all & """" severity failure; + +end procedure readword_ea; + +-- ------------------------------------- + +procedure readtagval( + L: inout line; + tag: in string; + match: out boolean; + val: out std_logic_vector; + good: out boolean; + base: in integer:= 2) is + + variable itag : string(tag'range); + variable ichar : character; + variable imatch : boolean; + +begin + + readwhite(L); + + for i in val'range loop + val(i) := '0'; + end loop; + good := true; + imatch := false; + + if L'length > tag'length then + imatch := L(L'left to L'left+tag'length-1) = tag and + L(L'left+tag'length) = '='; + if imatch then + read(L, itag); + read(L, ichar); + readgen(L, val, good, base); + end if; + end if; + match := imatch; + +end procedure readtagval; + +-- ------------------------------------- + +procedure readtagval_ea( + L: inout line; + tag: in string; + match: out boolean; + val: out std_logic_vector; + base: in integer:= 2) is + + variable ok : boolean := false; + +begin + readtagval(L, tag, match, val, ok, base); + assert ok report "readtagval(std_logic_vector) conversion error in """ & + L.all & """" severity failure; +end procedure readtagval_ea; + +-- ------------------------------------- + +procedure readtagval( + L: inout line; + tag: in string; + match: out boolean; + val: out std_logic; + good: out boolean) is + + variable itag : string(tag'range); + variable ichar : character; + variable imatch : boolean; + +begin + + readwhite(L); + + val := '0'; + good := true; + imatch := false; + + if L'length > tag'length then + imatch := L(L'left to L'left+tag'length-1) = tag and + L(L'left+tag'length) = '='; + if imatch then + read(L, itag); + read(L, ichar); + read(L, val, good); + end if; + end if; + match := imatch; + +end procedure readtagval; + +-- ------------------------------------- + +procedure readtagval_ea( + L: inout line; + tag: in string; + match: out boolean; + val: out std_logic) is + + variable ok : boolean := false; + +begin + readtagval(L, tag, match, val, ok); + assert ok report "readtagval(std_logic) conversion error in """ & + L.all & """" severity failure; +end procedure readtagval_ea; + +-- ------------------------------------- + +procedure readtagval2( + L: inout line; + tag: in string; + match: out boolean; + val1: out std_logic_vector; + val2: out std_logic_vector; + good: out boolean; + base: in integer:= 2) is + + variable itag : string(tag'range); + variable imatch : boolean; + variable igood : boolean; + variable ichar : character; + variable ok : boolean; + +begin + + readwhite(L); + + for i in val1'range loop -- zero val1 + val1(i) := '0'; + end loop; + for i in val2'range loop -- zero val2 + val2(i) := '0'; + end loop; + igood := true; + imatch := false; + + if L'length > tag'length then -- check for tag + imatch := L(L'left to L'left+tag'length-1) = tag and + L(L'left+tag'length) = '='; + + if imatch then -- if found + read(L, itag); -- remove tag + read(L, ichar); -- remove = + + igood := false; + readoptchar(L, '-', ok); -- check for tag=- + if ok then + for i in val2'range loop -- set mask to all 1 (ignore) + val2(i) := '1'; + end loop; + igood := true; + else -- here if tag=bit[,bit] + readgen(L, val1, igood, base); -- read val1 + if igood then + readoptchar(L, ',', ok); -- check(and remove) , + if ok then + readgen(L, val2, igood, base); -- and read val2 + end if; + end if; + end if; + end if; + end if; + + match := imatch; + good := igood; + +end procedure readtagval2; + +-- ------------------------------------- + +procedure readtagval2_ea( + L: inout line; + tag: in string; + match: out boolean; + val1: out std_logic_vector; + val2: out std_logic_vector; + base: in integer:= 2) is + + variable ok : boolean := false; + +begin + readtagval2(L, tag, match, val1, val2, ok, base); + assert ok report "readtagval2() conversion error in """ & + L.all & """" severity failure; +end procedure readtagval2_ea; + +-- ------------------------------------- + +procedure writeoct( -- write slv in octal base (arb. length) + L: inout line; -- line + value: in std_logic_vector; -- value to be written + justified: in side:=right; -- justification (left/right) + field: in width:=0) is -- field width + + variable nbit : integer; -- number of bits + variable ndig : integer; -- number of digits + variable iwidth : integer; + variable ioffset : integer; + variable nibble : std_logic_vector(2 downto 0); + variable ochar : character; + +begin + + assert not value'ascending(1) + report "writeoct called with ascending range" + severity failure; + + nbit := value'length(1); + ndig := (nbit+2)/3; + iwidth := nbit mod 3; + if iwidth = 0 then + iwidth := 3; + end if; + ioffset := value'left(1) - iwidth+1; + if justified=right and field>ndig then + for i in ndig+1 to field loop + write(L,' '); + end loop; -- i + end if; + for i in 0 to ndig-1 loop + nibble := "000"; + nibble(iwidth-1 downto 0) := value(ioffset+iwidth-1 downto ioffset); + ochar := ' '; + for i in nibble'range loop + case nibble(i) is + when 'U' => ochar := 'U'; + when 'X' => ochar := 'X'; + when 'Z' => ochar := 'Z'; + when '-' => ochar := '-'; + when others => null; + end case; + end loop; -- i + if ochar = ' ' then + write(L,conv_integer(unsigned(nibble))); + else + write(L,ochar); + end if; + iwidth := 3; + ioffset := ioffset - 3; + end loop; -- i + if justified=left and field>ndig then + for i in ndig+1 to field loop + write(L,' '); + end loop; -- i + end if; +end procedure writeoct; + +-- ------------------------------------- + +procedure writehex( -- write slv in hex base (arb. length) + L: inout line; -- line + value: in std_logic_vector; -- value to be written + justified: in side:=right; -- justification (left/right) + field: in width:=0) is -- field width + + variable nbit : integer; -- number of bits + variable ndig : integer; -- number of digits + variable iwidth : integer; + variable ioffset : integer; + variable nibble : std_logic_vector(3 downto 0); + variable ochar : character; + variable hextab : string(1 to 16) := "0123456789abcdef"; + +begin + + assert not value'ascending(1) + report "writehex called with ascending range" + severity failure; + + nbit := value'length(1); + ndig := (nbit+3)/4; + iwidth := nbit mod 4; + if iwidth = 0 then + iwidth := 4; + end if; + ioffset := value'left(1) - iwidth+1; + if justified=right and field>ndig then + for i in ndig+1 to field loop + write(L,' '); + end loop; -- i + end if; + for i in 0 to ndig-1 loop + nibble := "0000"; + nibble(iwidth-1 downto 0) := value(ioffset+iwidth-1 downto ioffset); + ochar := ' '; + for i in nibble'range loop + case nibble(i) is + when 'U' => ochar := 'U'; + when 'X' => ochar := 'X'; + when 'Z' => ochar := 'Z'; + when '-' => ochar := '-'; + when others => null; + end case; + end loop; -- i + if ochar = ' ' then + write(L,hextab(conv_integer(unsigned(nibble))+1)); + else + write(L,ochar); + end if; + iwidth := 4; + ioffset := ioffset - 4; + end loop; -- i + if justified=left and field>ndig then + for i in ndig+1 to field loop + write(L,' '); + end loop; -- i + end if; +end procedure writehex; + +-- ------------------------------------- + +procedure writegen( -- write slv in generic base (arb. lth) + L: inout line; -- line + value: in std_logic_vector; -- value to be written + justified: in side:=right; -- justification (left/right) + field: in width:=0; -- field width + base: in integer:=2) is -- default base + +begin + + case base is + when 2 => write(L, value, justified, field); + when 8 => writeoct(L, value, justified, field); + when 16 => writehex(L, value, justified, field); + when others => report "writegen base not 2,8, or 16" + severity failure; + end case; + +end procedure writegen; + +-- ------------------------------------- + +procedure writetimestamp( + L: inout line; + clkcyc: in slv31; + str: in string := null_string) is + +begin + + write(L, now, right, 12); + write(L, conv_integer(unsigned(clkcyc)), right, 7); + if str /= null_string then + write(L, str); + end if; + +end procedure writetimestamp; + +end package body simlib; + diff --git a/rtl/vlib/slvtypes.vhd b/rtl/vlib/slvtypes.vhd new file mode 100644 index 00000000..15d9c2cf --- /dev/null +++ b/rtl/vlib/slvtypes.vhd @@ -0,0 +1,79 @@ +-- $Id: slvtypes.vhd 314 2010-07-09 17:38:41Z mueller $ +-- +-- Copyright 2007-2008 by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, 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 complete details. +-- +------------------------------------------------------------------------------ +-- Package Name: slvtypes +-- Description: Short names for std_logic types. +-- This package simply defines short hands for the std_logic +-- types. slbit and slv are just aliases for std_logic and +-- std_logic_vector. slv are subtype definitions for +-- commonly used (n downto 0) vectors +-- +-- Dependencies: - +-- Tool versions: xst 8.1, 8.2, 9.1, 9.2; ghdl 0.18-0.25 +-- Revision History: +-- Date Rev Version Comment +-- 2008-08-24 162 1.0.4 add slv60 and 64 +-- 2008-08-22 161 1.0.3 add slvnn_m subtypes from pdp11 package +-- 2008-03-24 129 1.0.2 add slv31 +-- 2007-12-08 100 1.0.1 add slv1 +-- 2007-06-02 44 1.0 Initial version +------------------------------------------------------------------------------ + +library ieee; +use ieee.std_logic_1164.all; + +package slvtypes is + + subtype slbit is std_logic; -- bit + subtype slv is std_logic_vector; -- vector + + subtype slv1 is std_logic_vector( 0 downto 0); -- 1 bit word + subtype slv2 is std_logic_vector( 1 downto 0); -- 2 bit word + subtype slv3 is std_logic_vector( 2 downto 0); -- 3 bit word + subtype slv4 is std_logic_vector( 3 downto 0); -- 4 bit word + subtype slv5 is std_logic_vector( 4 downto 0); -- 5 bit word + subtype slv6 is std_logic_vector( 5 downto 0); -- 6 bit word + subtype slv7 is std_logic_vector( 6 downto 0); -- 7 bit word + subtype slv8 is std_logic_vector( 7 downto 0); -- 8 bit word + subtype slv9 is std_logic_vector( 8 downto 0); -- 9 bit word + subtype slv10 is std_logic_vector( 9 downto 0); -- 10 bit word + subtype slv11 is std_logic_vector(10 downto 0); -- 11 bit word + subtype slv12 is std_logic_vector(11 downto 0); -- 12 bit word + subtype slv13 is std_logic_vector(12 downto 0); -- 13 bit word + subtype slv14 is std_logic_vector(13 downto 0); -- 14 bit word + subtype slv15 is std_logic_vector(14 downto 0); -- 15 bit word + subtype slv16 is std_logic_vector(15 downto 0); -- 16 bit word + + subtype slv17 is std_logic_vector(16 downto 0); -- 17 bit word + subtype slv18 is std_logic_vector(17 downto 0); -- 18 bit word + subtype slv19 is std_logic_vector(18 downto 0); -- 19 bit word + subtype slv20 is std_logic_vector(19 downto 0); -- 20 bit word + subtype slv21 is std_logic_vector(20 downto 0); -- 21 bit word + subtype slv22 is std_logic_vector(21 downto 0); -- 22 bit word + subtype slv23 is std_logic_vector(22 downto 0); -- 23 bit word + subtype slv24 is std_logic_vector(23 downto 0); -- 24 bit word + subtype slv31 is std_logic_vector(30 downto 0); -- 31 bit word + subtype slv32 is std_logic_vector(31 downto 0); -- 32 bit word + + subtype slv60 is std_logic_vector(59 downto 0); -- 59 bit word + subtype slv64 is std_logic_vector(63 downto 0); -- 63 bit word + + subtype slv8_1 is std_logic_vector(7 downto 1); -- 8 bit word, 1 lsb drop + subtype slv9_2 is std_logic_vector(8 downto 2); -- 9 bit word, 2 lsb drop + subtype slv13_1 is std_logic_vector(12 downto 1); -- 13 bit word, 1 lsb drop + subtype slv16_1 is std_logic_vector(15 downto 1); -- 16 bit word, 1 lsb drop + subtype slv18_1 is std_logic_vector(17 downto 1); -- 18 bit word, 1 lsb drop + subtype slv22_1 is std_logic_vector(21 downto 1); -- 22 bit word, 1 lsb drop + +end package slvtypes; diff --git a/rtl/vlib/xlib/Makefile b/rtl/vlib/xlib/Makefile new file mode 100644 index 00000000..ce5f37d0 --- /dev/null +++ b/rtl/vlib/xlib/Makefile @@ -0,0 +1,21 @@ +# $Id: Makefile 311 2010-06-30 17:52:37Z mueller $ +# +# Revision History: +# Date Rev Version omment +# 2007-12-08 100 1.0 Initial version +# +VBOM_all = $(wildcard *.vbom) +NGC_all = $(VBOM_all:.vbom=.ngc) +# +.phony : all clean +# +all : $(NGC_all) +# +clean : ise_clean +# +#---- +# +include $(RETROBASE)/rtl/vlib/Makefile.xflow +# +include $(VBOM_all:.vbom=.dep_xst) +# diff --git a/rtl/vlib/xlib/iob_keeper_gen.vbom b/rtl/vlib/xlib/iob_keeper_gen.vbom new file mode 100644 index 00000000..9ab3a257 --- /dev/null +++ b/rtl/vlib/xlib/iob_keeper_gen.vbom @@ -0,0 +1,4 @@ +# libs +../slvtypes.vhd +# design +iob_keeper_gen.vhd diff --git a/rtl/vlib/xlib/iob_keeper_gen.vhd b/rtl/vlib/xlib/iob_keeper_gen.vhd new file mode 100644 index 00000000..fabca080 --- /dev/null +++ b/rtl/vlib/xlib/iob_keeper_gen.vhd @@ -0,0 +1,63 @@ +-- $Id: iob_keeper_gen.vhd 314 2010-07-09 17:38:41Z mueller $ +-- +-- Copyright 2010- by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, 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 complete details. +-- +------------------------------------------------------------------------------ +-- Module Name: iob_keeper_gen - sim +-- Description: keeper for IOB, vector +-- +-- Dependencies: - +-- Test bench: - +-- Target Devices: generic Spartan, Virtex +-- Tool versions: xst 8.1, 8.2, 9.1, 9.2; ghdl 0.18-0.25 +-- Revision History: +-- Date Rev Version Comment +-- 2010-06-03 299 1.1 add explicit R_KEEP and driver +-- 2008-05-22 148 1.0 Initial version +------------------------------------------------------------------------------ + +library ieee; +use ieee.std_logic_1164.all; + +use work.slvtypes.all; +use work.xlib.all; + +entity iob_keeper_gen is -- keeper for IOB, vector + generic ( + DWIDTH : positive := 16); -- data port width + port ( + PAD : inout slv(DWIDTH-1 downto 0) -- i/o pad + ); +end iob_keeper_gen; + +-- Is't possible to directly use 'PAD<='H' in proc_pad. Introduced R_KEEP and +-- the explicit driver 'PAD<=R_KEEP' to state the keeper function more clearly. + +architecture sim of iob_keeper_gen is + signal R_KEEP : slv(DWIDTH-1 downto 0) := (others=>'W'); +begin + + proc_keep: process (PAD) + begin + for i in PAD'range loop + if PAD(i) = '1' then + R_KEEP(i) <= 'H'; + elsif PAD(i) = '0' then + R_KEEP(i) <= 'L'; + elsif PAD(i)='X' or PAD(i)='U' then + R_KEEP(i) <= 'W'; + end if; + end loop; + PAD <= R_KEEP; + end process proc_keep; + +end sim; diff --git a/rtl/vlib/xlib/iob_reg_i.vbom b/rtl/vlib/xlib/iob_reg_i.vbom new file mode 100644 index 00000000..45e9ebb0 --- /dev/null +++ b/rtl/vlib/xlib/iob_reg_i.vbom @@ -0,0 +1,7 @@ +# libs +../slvtypes.vhd +xlib.vhd +# components +iob_reg_i_gen.vbom +# design +iob_reg_i.vhd diff --git a/rtl/vlib/xlib/iob_reg_i.vhd b/rtl/vlib/xlib/iob_reg_i.vhd new file mode 100644 index 00000000..091cf2a1 --- /dev/null +++ b/rtl/vlib/xlib/iob_reg_i.vhd @@ -0,0 +1,61 @@ +-- $Id: iob_reg_i.vhd 314 2010-07-09 17:38:41Z mueller $ +-- +-- Copyright 2007- by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, 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 complete details. +-- +------------------------------------------------------------------------------ +-- Module Name: iob_reg_i - syn +-- Description: Registered IOB, input only +-- +-- Dependencies: - +-- Test bench: - +-- Target Devices: generic Spartan, Virtex +-- Tool versions: xst 8.1, 8.2, 9.1, 9.2; ghdl 0.18-0.25 +-- Revision History: +-- Date Rev Version Comment +-- 2007-12-16 101 1.0.1 add INIT generic port +-- 2007-12-08 100 1.0 Initial version +------------------------------------------------------------------------------ + +library ieee; +use ieee.std_logic_1164.all; + +use work.slvtypes.all; +use work.xlib.all; + +entity iob_reg_i is -- registered IOB, input + generic ( + INIT : slbit := '0'); -- initial state + port ( + CLK : in slbit; -- clock + CE : in slbit := '1'; -- clock enable + DI : out slbit; -- input data + PAD : in slbit -- i/o pad + ); +end iob_reg_i; + + +architecture syn of iob_reg_i is + +begin + + IOB : iob_reg_i_gen + generic map ( + DWIDTH => 1, + INIT => INIT) + port map ( + CLK => CLK, + CE => CE, + DI(0) => DI, + PAD(0) => PAD + ); + +end syn; diff --git a/rtl/vlib/xlib/iob_reg_i_gen.vbom b/rtl/vlib/xlib/iob_reg_i_gen.vbom new file mode 100644 index 00000000..b8e64c4a --- /dev/null +++ b/rtl/vlib/xlib/iob_reg_i_gen.vbom @@ -0,0 +1,4 @@ +# libs +../slvtypes.vhd +# design +iob_reg_i_gen.vhd diff --git a/rtl/vlib/xlib/iob_reg_i_gen.vhd b/rtl/vlib/xlib/iob_reg_i_gen.vhd new file mode 100644 index 00000000..4c3d014e --- /dev/null +++ b/rtl/vlib/xlib/iob_reg_i_gen.vhd @@ -0,0 +1,67 @@ +-- $Id: iob_reg_i_gen.vhd 314 2010-07-09 17:38:41Z mueller $ +-- +-- Copyright 2007- by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, 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 complete details. +-- +------------------------------------------------------------------------------ +-- Module Name: iob_reg_i_gen - syn +-- Description: Registered IOB, input only, vector +-- +-- Dependencies: - +-- Test bench: - +-- Target Devices: generic Spartan, Virtex +-- Tool versions: xst 8.1, 8.2, 9.1, 9.2; ghdl 0.18-0.25 +-- Revision History: +-- Date Rev Version Comment +-- 2007-12-16 101 1.0.1 add INIT generic port +-- 2007-12-08 100 1.0 Initial version +------------------------------------------------------------------------------ + +library ieee; +use ieee.std_logic_1164.all; + +use work.slvtypes.all; +use work.xlib.all; + +entity iob_reg_i_gen is -- registered IOB, input, vector + generic ( + DWIDTH : positive := 16; -- data port width + INIT : slbit := '0'); -- initial state + port ( + CLK : in slbit; -- clock + CE : in slbit := '1'; -- clock enable + DI : out slv(DWIDTH-1 downto 0); -- input data + PAD : in slv(DWIDTH-1 downto 0) -- i/o pad + ); +end iob_reg_i_gen; + + +architecture syn of iob_reg_i_gen is + + signal R_DI : slv(DWIDTH-1 downto 0) := (others=>INIT); + + attribute iob : string; + attribute iob of R_DI : signal is "true"; + +begin + + proc_regs: process (CLK) + begin + if CLK'event and CLK='1' then + if CE = '1' then + R_DI <= PAD; + end if; + end if; + end process proc_regs; + + DI <= R_DI; + +end syn; diff --git a/rtl/vlib/xlib/iob_reg_io_gen.vbom b/rtl/vlib/xlib/iob_reg_io_gen.vbom new file mode 100644 index 00000000..4883f327 --- /dev/null +++ b/rtl/vlib/xlib/iob_reg_io_gen.vbom @@ -0,0 +1,6 @@ +# libs +../slvtypes.vhd +# components +[ghdl,isim]iob_keeper_gen.vbom +# design +iob_reg_io_gen.vhd diff --git a/rtl/vlib/xlib/iob_reg_io_gen.vhd b/rtl/vlib/xlib/iob_reg_io_gen.vhd new file mode 100644 index 00000000..8a0427c1 --- /dev/null +++ b/rtl/vlib/xlib/iob_reg_io_gen.vhd @@ -0,0 +1,123 @@ +-- $Id: iob_reg_io_gen.vhd 314 2010-07-09 17:38:41Z mueller $ +-- +-- Copyright 2007-2008 by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, 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 complete details. +-- +------------------------------------------------------------------------------ +-- Module Name: iob_reg_io_gen - syn +-- Description: Registered IOB, in/output, vector +-- +-- Dependencies: iob_keeper_gen [sim only] +-- Test bench: - +-- Target Devices: generic Spartan, Virtex +-- Tool versions: xst 8.1, 8.2, 9.1, 9.2; ghdl 0.18-0.25 +-- Revision History: +-- Date Rev Version Comment +-- 2008-05-22 149 1.0.4 use internally TE to match OBUFT T polarity +-- 2008-05-22 148 1.0.3 remove UNISIM prim's; PULL implemented only for sim +-- 2008-05-18 147 1.0.2 add PULL generic, to enable PULL-UP,-DOWN or KEEPER +-- 2007-12-16 101 1.0.1 add INIT generic ports +-- 2007-12-08 100 1.0 Initial version +------------------------------------------------------------------------------ + +library ieee; +use ieee.std_logic_1164.all; + +use work.slvtypes.all; +use work.xlib.all; + +entity iob_reg_io_gen is -- registered IOB, in/output, vector + generic ( + DWIDTH : positive := 16; -- data port width + INITI : slbit := '0'; -- initial state ( in flop) + INITO : slbit := '0'; -- initial state (out flop) + INITE : slbit := '0'; -- initial state ( oe flop) + PULL : string := "NONE"); -- pull-up,-down or keeper + port ( + CLK : in slbit; -- clock + CEI : in slbit := '1'; -- clock enable ( in flops) + CEO : in slbit := '1'; -- clock enable (out flops) + OE : in slbit; -- output enable + DI : out slv(DWIDTH-1 downto 0); -- input data (read from pad) + DO : in slv(DWIDTH-1 downto 0); -- output data (write to pad) + PAD : inout slv(DWIDTH-1 downto 0) -- i/o pad + ); +end iob_reg_io_gen; + + +architecture syn of iob_reg_io_gen is + + signal R_TE : slbit := not INITE; + signal R_DI : slv(DWIDTH-1 downto 0) := (others=>INITI); + signal R_DO : slv(DWIDTH-1 downto 0) := (others=>INITO); + + constant all_z : slv(DWIDTH-1 downto 0) := (others=>'Z'); + constant all_l : slv(DWIDTH-1 downto 0) := (others=>'L'); + constant all_h : slv(DWIDTH-1 downto 0) := (others=>'H'); + + attribute iob : string; + attribute iob of R_TE : signal is "true"; + attribute iob of R_DI : signal is "true"; + attribute iob of R_DO : signal is "true"; + +begin + + assert PULL="NONE" or PULL="UP" or PULL="DOWN" or PULL="KEEP" + report "assert(PULL): only NONE, UP, DOWN, OR KEEP supported" + severity failure; + + proc_regs: process (CLK) + begin + if CLK'event and CLK='1' then + R_TE <= not OE; + if CEI = '1' then + R_DI <= to_x01(PAD); + end if; + if CEO = '1' then + R_DO <= DO; + end if; + end if; + end process proc_regs; + + proc_comb: process (R_TE, R_DO) + begin + if R_TE = '1' then + PAD <= all_z; + else + PAD <= R_DO; + end if; + end process proc_comb; + + DI <= R_DI; + +-- Note: PULL (UP, DOWN or KEEP) is only implemented for simulation, not +-- for inference in synthesis. Use pin attributes in UCF's or use +-- iob_reg_io_gen_unisim +-- +-- synthesis translate_off + + PULL_UP: if PULL = "UP" generate + PAD <= all_h; + end generate PULL_UP; + + PULL_DOWN: if PULL = "DOWN" generate + PAD <= all_l; + end generate PULL_DOWN; + + PULL_KEEP: if PULL = "KEEP" generate + KEEPER : iob_keeper_gen + generic map (DWIDTH => DWIDTH) + port map (PAD => PAD); + end generate PULL_KEEP; + +-- synthesis translate_on + +end syn; diff --git a/rtl/vlib/xlib/iob_reg_o.vbom b/rtl/vlib/xlib/iob_reg_o.vbom new file mode 100644 index 00000000..4647b58e --- /dev/null +++ b/rtl/vlib/xlib/iob_reg_o.vbom @@ -0,0 +1,7 @@ +# libs +../slvtypes.vhd +xlib.vhd +# components +iob_reg_o_gen.vbom +# design +iob_reg_o.vhd diff --git a/rtl/vlib/xlib/iob_reg_o.vhd b/rtl/vlib/xlib/iob_reg_o.vhd new file mode 100644 index 00000000..94f4cfed --- /dev/null +++ b/rtl/vlib/xlib/iob_reg_o.vhd @@ -0,0 +1,61 @@ +-- $Id: iob_reg_o.vhd 314 2010-07-09 17:38:41Z mueller $ +-- +-- Copyright 2007- by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, 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 complete details. +-- +------------------------------------------------------------------------------ +-- Module Name: iob_reg_i - syn +-- Description: Registered IOB, output only +-- +-- Dependencies: - +-- Test bench: - +-- Target Devices: generic Spartan, Virtex +-- Tool versions: xst 8.1, 8.2, 9.1, 9.2; ghdl 0.18-0.25 +-- Revision History: +-- Date Rev Version Comment +-- 2007-12-16 101 1.0.1 add INIT generic port +-- 2007-12-08 100 1.0 Initial version +------------------------------------------------------------------------------ + +library ieee; +use ieee.std_logic_1164.all; + +use work.slvtypes.all; +use work.xlib.all; + +entity iob_reg_o is -- registered IOB, output + generic ( + INIT : slbit := '0'); -- initial state + port ( + CLK : in slbit; -- clock + CE : in slbit := '1'; -- clock enable + DO : in slbit; -- output data + PAD : out slbit -- i/o pad + ); +end iob_reg_o; + + +architecture syn of iob_reg_o is + +begin + + IOB : iob_reg_o_gen + generic map ( + DWIDTH => 1, + INIT => INIT) + port map ( + CLK => CLK, + CE => CE, + DO(0) => DO, + PAD(0) => PAD + ); + +end syn; diff --git a/rtl/vlib/xlib/iob_reg_o_gen.vbom b/rtl/vlib/xlib/iob_reg_o_gen.vbom new file mode 100644 index 00000000..83f20617 --- /dev/null +++ b/rtl/vlib/xlib/iob_reg_o_gen.vbom @@ -0,0 +1,4 @@ +# libs +../slvtypes.vhd +# design +iob_reg_o_gen.vhd diff --git a/rtl/vlib/xlib/iob_reg_o_gen.vhd b/rtl/vlib/xlib/iob_reg_o_gen.vhd new file mode 100644 index 00000000..f93ff424 --- /dev/null +++ b/rtl/vlib/xlib/iob_reg_o_gen.vhd @@ -0,0 +1,67 @@ +-- $Id: iob_reg_o_gen.vhd 314 2010-07-09 17:38:41Z mueller $ +-- +-- Copyright 2007- by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, 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 complete details. +-- +------------------------------------------------------------------------------ +-- Module Name: iob_reg_o_gen - syn +-- Description: Registered IOB, output only, vector +-- +-- Dependencies: - +-- Test bench: - +-- Target Devices: generic Spartan, Virtex +-- Tool versions: xst 8.1, 8.2, 9.1, 9.2; ghdl 0.18-0.25 +-- Revision History: +-- Date Rev Version Comment +-- 2007-12-16 101 1.0.1 add INIT generic port +-- 2007-12-08 100 1.0 Initial version +------------------------------------------------------------------------------ + +library ieee; +use ieee.std_logic_1164.all; + +use work.slvtypes.all; +use work.xlib.all; + +entity iob_reg_o_gen is -- registered IOB, output, vector + generic ( + DWIDTH : positive := 16; -- data port width + INIT : slbit := '0'); -- initial state + port ( + CLK : in slbit; -- clock + CE : in slbit := '1'; -- clock enable + DO : in slv(DWIDTH-1 downto 0); -- output data + PAD : out slv(DWIDTH-1 downto 0) -- i/o pad + ); +end iob_reg_o_gen; + + +architecture syn of iob_reg_o_gen is + + signal R_DO : slv(DWIDTH-1 downto 0) := (others=>INIT); + + attribute iob : string; + attribute iob of R_DO : signal is "true"; + +begin + + proc_regs: process (CLK) + begin + if CLK'event and CLK='1' then + if CE = '1' then + R_DO <= DO; + end if; + end if; + end process proc_regs; + + PAD <= R_DO; + +end syn; diff --git a/rtl/vlib/xlib/xlib.vhd b/rtl/vlib/xlib/xlib.vhd new file mode 100644 index 00000000..4570fd01 --- /dev/null +++ b/rtl/vlib/xlib/xlib.vhd @@ -0,0 +1,154 @@ +-- $Id: xlib.vhd 314 2010-07-09 17:38:41Z mueller $ +-- +-- Copyright 2007-2008 by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, 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 complete details. +-- +------------------------------------------------------------------------------ +-- Package Name: xlib +-- Description: Xilinx specific components +-- +-- Dependencies: - +-- Tool versions: xst 8.1, 8.2, 9.1, 9.2; ghdl 0.18-0.25 +-- Revision History: +-- Date Rev Version Comment +-- 2008-05-23 149 1.0.4 add iob_io(_gen) +-- 2008-05-22 148 1.0.3 add iob_keeper(_gen); +-- 2008-05-18 147 1.0.2 add PULL generic to iob_reg_io(_gen) +-- 2007-12-16 101 1.0.1 add INIT generic ports +-- 2007-12-08 100 1.0 Initial version +------------------------------------------------------------------------------ + +library ieee; +use ieee.std_logic_1164.all; + +use work.slvtypes.all; + +package xlib is + +component iob_reg_i is -- registered IOB, input + generic ( + INIT : slbit := '0'); -- initial state + port ( + CLK : in slbit; -- clock + CE : in slbit := '1'; -- clock enable + DI : out slbit; -- input data + PAD : in slbit -- i/o pad + ); +end component; + +component iob_reg_i_gen is -- registered IOB, input, vector + generic ( + DWIDTH : positive := 16; -- data port width + INIT : slbit := '0'); -- initial state + port ( + CLK : in slbit; -- clock + CE : in slbit := '1'; -- clock enable + DI : out slv(DWIDTH-1 downto 0); -- input data + PAD : in slv(DWIDTH-1 downto 0) -- i/o pad + ); +end component; + +component iob_reg_o is -- registered IOB, output + generic ( + INIT : slbit := '0'); -- initial state + port ( + CLK : in slbit; -- clock + CE : in slbit := '1'; -- clock enable + DO : in slbit; -- output data + PAD : out slbit -- i/o pad + ); +end component; + +component iob_reg_o_gen is -- registered IOB, output, vector + generic ( + DWIDTH : positive := 16; -- data port width + INIT : slbit := '0'); -- initial state + port ( + CLK : in slbit; -- clock + CE : in slbit := '1'; -- clock enable + DO : in slv(DWIDTH-1 downto 0); -- output data + PAD : out slv(DWIDTH-1 downto 0) -- i/o pad + ); +end component; + +component iob_reg_io is -- registered IOB, in/output + generic ( + INITI : slbit := '0'; -- initial state ( in flop) + INITO : slbit := '0'; -- initial state (out flop) + INITE : slbit := '0'; -- initial state ( oe flop) + PULL : string := "NONE"); -- pull-up,-down or keeper + port ( + CLK : in slbit; -- clock + CEI : in slbit := '1'; -- clock enable ( in flops) + CEO : in slbit := '1'; -- clock enable (out flops) + OE : in slbit; -- output enable + DI : out slbit; -- input data (read from pad) + DO : in slbit; -- output data (write to pad) + PAD : inout slbit -- i/o pad + ); +end component; + +component iob_reg_io_gen is -- registered IOB, in/output, vector + generic ( + DWIDTH : positive := 16; -- data port width + INITI : slbit := '0'; -- initial state ( in flop) + INITO : slbit := '0'; -- initial state (out flop) + INITE : slbit := '0'; -- initial state ( oe flop) + PULL : string := "NONE"); -- pull-up,-down or keeper + port ( + CLK : in slbit; -- clock + CEI : in slbit := '1'; -- clock enable ( in flops) + CEO : in slbit := '1'; -- clock enable (out flops) + OE : in slbit; -- output enable + DI : out slv(DWIDTH-1 downto 0); -- input data (read from pad) + DO : in slv(DWIDTH-1 downto 0); -- output data (write to pad) + PAD : inout slv(DWIDTH-1 downto 0) -- i/o pad + ); +end component; + +component iob_io is -- un-registered IOB, in/output + generic ( + PULL : string := "NONE"); -- pull-up,-down or keeper + port ( + OE : in slbit; -- output enable + DI : out slbit; -- input data (read from pad) + DO : in slbit; -- output data (write to pad) + PAD : inout slbit -- i/o pad + ); +end component; + +component iob_io_gen is -- un-registered IOB, in/output, vector + generic ( + DWIDTH : positive := 16; -- data port width + PULL : string := "NONE"); -- pull-up,-down or keeper + port ( + OE : in slbit; -- output enable + DI : out slv(DWIDTH-1 downto 0); -- input data (read from pad) + DO : in slv(DWIDTH-1 downto 0); -- output data (write to pad) + PAD : inout slv(DWIDTH-1 downto 0) -- i/o pad + ); +end component; + +component iob_keeper is -- keeper for IOB + port ( + PAD : inout slbit -- i/o pad + ); +end component; + +component iob_keeper_gen is -- keeper for IOB, vector + generic ( + DWIDTH : positive := 16); -- data port width + port ( + PAD : inout slv(DWIDTH-1 downto 0) -- i/o pad + ); +end component; + +end xlib; diff --git a/rtl/vlib/xst_vhdl.opt b/rtl/vlib/xst_vhdl.opt new file mode 100644 index 00000000..9d2c67ac --- /dev/null +++ b/rtl/vlib/xst_vhdl.opt @@ -0,0 +1,63 @@ +FLOWTYPE = FPGA_SYNTHESIS; +######################################################### +## Filename: xst_vhdl.opt +## +## VHDL Option File for XST targeted for speed +## This works for FPGA devices. +## +## Version: 8.1.1 +## $Header: /devl/xcs/repo/env/Jobs/Xflow/data/optionfiles/fpga_xst_vhdl_speed.opt,v 1.13 2004/10/01 22:29:20 rvklair Exp $ +######################################################### +# Options for XST +# +# +# +Program xst +-ifn _xst.scr; # input XST script file +-ofn _xst.log; # output XST log file +-intstyle xflow; # Message Reporting Style: ise, xflow, or silent +# +# The options listed under ParamFile are the XST Properties that can be set by the +# user. To turn on an option, uncomment by removing the '#' in front of the switch. +# +ParamFile: _xst.scr +"run"; +# +# Global Synthesis Options +# +"-ifn "; # Input/Project File Name +"-ifmt VHDL"; # Input Format +"-ofn "; # Output File Name +"-ofmt ngc"; # Output File Format +"-p "; # Target Device +"-opt_mode SPEED"; # Optimization Criteria # AREA or SPEED +"-opt_level 2"; +"-uc .xcf"; # Constraint File name +#"-case maintain"; # Specifies how to handle source name case + # upper, lower +#"-keep_hierarchy NO"; # Prevents optimization across module boundaries + # CPLD default YES, FPGA default NO +#"-write_timing_constraints NO"; # Write Timing Constraints + # YES, NO +#"-cross_clock_analysis NO"; # Cross Clock Option + # YES, NO +#"-iobuf YES"; # Add I/O Buffers to top level portS + # YES, NO +# +# The following are HDL Options +# +# The following are Xilinx FPGA specific options for Virtex, VirtexE, Virtex-II and Spartan2 +# +#"-register_balancing NO"; # Register Balancing + # YES, NO, Forward, Backward +#"-move_first_stage YES"; # Move First Flip-Flop Stage + # YES, NO +#"-move_last_stage YES"; # Move Last Flip-Flop Stage + # YES, NO +End ParamFile +End Program xst +# +# See XST USER Guide Chapter 8 (Command Line Mode) for all XST options +# + + diff --git a/rtl/w11a/Makefile b/rtl/w11a/Makefile new file mode 100644 index 00000000..a63ebe78 --- /dev/null +++ b/rtl/w11a/Makefile @@ -0,0 +1,22 @@ +# $Id: Makefile 311 2010-06-30 17:52:37Z mueller $ +# +# Revision History: +# Date Rev Version Comment +# 2007-12-09 100 1.0.1 drop ISE_p def +# 2007-07-08 65 1.0 Initial version +# +VBOM_all = $(wildcard *.vbom) +NGC_all = $(VBOM_all:.vbom=.ngc) +# +.phony : all clean +# +all : $(NGC_all) +# +clean : ise_clean +# +#---- +# +include $(RETROBASE)/rtl/vlib/Makefile.xflow +# +include $(VBOM_all:.vbom=.dep_xst) +# diff --git a/rtl/w11a/pdp11.vbom b/rtl/w11a/pdp11.vbom new file mode 100644 index 00000000..24d4a329 --- /dev/null +++ b/rtl/w11a/pdp11.vbom @@ -0,0 +1,5 @@ +# libs +../vlib/slvtypes.vhd +../ibus/iblib.vhd +../vlib/rri/rrilib.vhd +pdp11.vhd diff --git a/rtl/w11a/pdp11.vhd b/rtl/w11a/pdp11.vhd new file mode 100644 index 00000000..c6c0547d --- /dev/null +++ b/rtl/w11a/pdp11.vhd @@ -0,0 +1,1098 @@ +-- $Id: pdp11.vhd 314 2010-07-09 17:38:41Z mueller $ +-- +-- Copyright 2006-2010 by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, 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 complete details. +-- +------------------------------------------------------------------------------ +-- Package Name: pdp11 +-- Description: Definitions for pdp11 components +-- +-- Dependencies: - +-- Tool versions: xst 8.1, 8.2, 9.1, 9.2, 11.4; ghdl 0.18-0.26 +-- Revision History: +-- Date Rev Version Comment +-- 2010-06-20 308 1.4.3 add c_ibrb_ibf_ def's +-- 2010-06-20 307 1.4.2 rename cpacc to cacc in vm_cntl_type, mmu_cntl_type +-- 2010-06-18 306 1.4.1 add racc, be to cp_addr_type; rm pdp11_ibdr_rri +-- 2010-06-13 305 1.4 add rnum to cp_cntl_type, cprnum to cpustat_type; +-- reassign cp command codes and rename: c_cp_func_... +-- -> c_cpfunc_...; remove cpaddr_(lal|lah|inc) from +-- dpath_cntl_type; add cpdout_we to dpath_cntl_type; +-- reassign rbus adresses and rename: c_rb_addr_... +-- -> c_rbaddr_...; rename rbus fields: c_rb_statf_... +-- -> c_stat_rbf_... +-- 2010-06-12 304 1.3.3 add cpuwait to cp_stat_type and cpustat_type +-- 2010-06-11 303 1.3.2 use IB_MREQ.racc instead of RRI_REQ +-- 2010-05-02 287 1.3.1 rename RP_STAT->RB_STAT +-- 2010-05-01 285 1.3 port to rri V2 interface; drop pdp11_rri_2rp; +-- rename c_rp_addr_* -> c_rb_addr_* +-- 2010-03-21 270 1.2.6 add pdp11_du_drv +-- 2009-05-30 220 1.2.5 final removal of snoopers (were already commented) +-- 2009-05-10 214 1.2.4 add ENA (trace enable) for _tmu; add _pdp11_tmu_sb +-- 2009-05-09 213 1.2.3 BUGFIX: default for inst_compl now '0' +-- 2008-12-14 177 1.2.2 add gpr_* fields to DM_STAT_DP +-- 2008-11-30 174 1.2.1 BUGFIX: add updt_dstadsrc; +-- 2008-08-22 161 1.2 move slvnn_m subtypes to slvtypes; +-- move (and rename) intbus defs to iblib package; +-- move intbus devices to ibdlib package; +-- rename ubf_ --> ibf_; +-- 2008-05-09 144 1.1.17 use EI_ACK with _kw11l, _dl11 +-- 2008-05-03 143 1.1.16 rename _cpursta->_cpurust +-- 2008-04-27 140 1.1.15 add c_cpursta_xxx defs; cpufail->cpursta in cp_stat +-- 2008-04-25 138 1.1.14 add BRESET port to _mmu, _vmbox, use in _irq +-- 2008-04-19 137 1.1.13 add _tmu,_sys70 entity, dm_stat_** types and ports +-- 2008-04-18 136 1.1.12 ibdr_sdreg: use RESET; ibdr_minisys: add RESET +-- 2008-03-02 121 1.1.11 remove snoopers; add waitsusp in cpustat_type +-- 2008-02-24 119 1.1.10 add lah,rps,wps commands, cp_addr_type. +-- _vmbox,_mmu interface changed +-- 2008-02-17 117 1.1.9 add em_(mreq|sres)_type, pdp11_cache, pdp11_bram +-- 2008-01-27 115 1.1.8 add pdp11_ubmap, pdp11_mem70 +-- 2008-01-26 114 1.1.7 add c_rp_addr_ibr(b) defs (for ibr addresses) +-- 2008-01-20 113 1.1.6 _core_rri: use RRI_LAM; _minisys: RRI_LAM vector +-- 2008-01-20 112 1.1.5 added ibdr_minisys; _ibdr_rri +-- 2008-01-06 111 1.1.4 rename ibdr_kw11l->ibd_kw11l; add ibdr_(dl11|rk11) +-- mod pdp11_intmap; +-- 2008-01-05 110 1.1.3 delete _mmu_regfile; rename _mmu_regs->_mmu_sadr +-- rename IB_MREQ(ena->req) SRES(sel->ack, hold->busy) +-- add ibdr_kw11l. +-- 2008-01-01 109 1.1.2 _vmbox w/ IB_SRES_(CPU|EXT); remove vm_regs_type +-- 2007-12-30 108 1.1.1 add ibdr_sdreg, ubf_byte[01] +-- 2007-12-30 107 1.1 use IB_MREQ/IB_SRES interface now; remove DMA port +-- 2007-08-16 74 1.0.6 add AP_LAM interface to pdp11_core_rri +-- 2007-08-12 73 1.0.5 add c_rp_addr_xxx and c_rp_statf_xxx def's +-- 2007-08-10 72 1.0.4 added c_cp_func_xxx constant def's for commands +-- 2007-07-15 66 1.0.3 rename pdp11_top -> pdp11_core +-- 2007-07-02 63 1.0.2 reordered ports on pdp11_top (by function, not i/o) +-- 2007-06-14 56 1.0.1 Use slvtypes.all +-- 2007-05-12 26 1.0 Initial version +------------------------------------------------------------------------------ + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; + +use work.slvtypes.all; +use work.iblib.all; +use work.rrilib.all; + +package pdp11 is + + type psw_type is record -- processor status + cmode : slv2; -- current mode + pmode : slv2; -- previous mode + rset : slbit; -- register set + pri : slv3; -- processor priority + tflag : slbit; -- trace flag + cc : slv4; -- condition codes (NZVC). + end record psw_type; + + constant psw_init : psw_type := ( + "00","00", -- cmode, pmode (=kernel) + '0',"111",'0', -- rset, pri (=7), tflag + "0000" -- cc NZVC=0 + ); + + constant c_psw_kmode : slv2 := "00"; -- processor mode: kernel + constant c_psw_smode : slv2 := "01"; -- processor mode: supervisor + constant c_psw_umode : slv2 := "11"; -- processor mode: user + + subtype psw_ibf_cmode is integer range 15 downto 14; + subtype psw_ibf_pmode is integer range 13 downto 12; + constant psw_ibf_rset: integer := 11; + subtype psw_ibf_pri is integer range 7 downto 5; + constant psw_ibf_tflag: integer := 4; + subtype psw_ibf_cc is integer range 3 downto 0; + + type sarsdr_type is record -- combined SAR/SDR MMU status + saf : slv16; -- segment address field + slf : slv7; -- segment length field + ed : slbit; -- expansion direction + acf : slv3; -- access control field + end record sarsdr_type; + + constant sarsdr_init : sarsdr_type := ( + (others=>'0'), -- saf + "0000000",'0',"000" -- slf, ed, acf + ); + + type dpath_cntl_type is record -- data path control + gpr_asrc : slv3; -- src register address + gpr_adst : slv3; -- dst register address + gpr_mode : slv2; -- psw mode for gpr access + gpr_rset : slbit; -- register set + gpr_we : slbit; -- gpr write enable + gpr_bytop : slbit; -- gpr high byte enable + gpr_pcinc : slbit; -- pc increment enable + psr_ccwe : slbit; -- enable update cc + psr_we: slbit; -- write enable psw (from DIN) + psr_func : slv3; -- write function psw (from DIN) + dsrc_sel : slbit; -- src data register source select + dsrc_we : slbit; -- src data register write enable + ddst_sel : slbit; -- dst data register source select + ddst_we : slbit; -- dst data register write enable + dtmp_sel : slv2; -- tmp data register source select + dtmp_we : slbit; -- tmp data register write enable + abox_asel : slv2; -- abox a port selector + abox_azero : slbit; -- abox a port force zero + abox_const : slv9; -- abox b port const + abox_bsel : slv2; -- abox b port selector + abox_opsub : slbit; -- abox operation + dbox_srcmod : slv2; -- dbox src port modifier + dbox_dstmod : slv2; -- dbox dst port modifier + dbox_cimod : slv2; -- dbox ci port modifier + dbox_cc1op : slbit; -- dbox use cc modes (1 op instruction) + dbox_ccmode : slv3; -- dbox cc port mode + dbox_bytop : slbit; -- dbox byte operation + lbox_func : slv4; -- lbox function + lbox_bytop : slbit; -- lbox byte operation + mbox_func : slv2; -- mbox function + mbox_s_div : slbit; -- mbox s_opg_div state + mbox_s_div_cn : slbit; -- mbox s_opg_div_cn state + mbox_s_div_cr : slbit; -- mbox s_opg_div_cr state + mbox_s_ash : slbit; -- mbox s_opg_ash state + mbox_s_ash_cn : slbit; -- mbox s_opg_ash_cn state + mbox_s_ashc : slbit; -- mbox s_opg_ashc state + mbox_s_ashc_cn : slbit; -- mbox s_opg_ashc_cn state + ireg_we : slbit; -- ireg register write enable + cres_sel : slv3; -- result bus (cres) select + dres_sel : slv3; -- result bus (dres) select + vmaddr_sel : slv2; -- virtual address select + cpdout_we : slbit; -- capture dres for cpdout + end record dpath_cntl_type; + + constant dpath_cntl_init : dpath_cntl_type := ( + "000","000","00",'0','0','0','0', -- gpr + '0','0',"000", -- psr + '0','0','0','0',"00",'0', -- dsrc,..,dtmp + "00",'0',"000000000","00",'0', -- abox + "00","00","00",'0',"000",'0', -- dbox + "0000",'0', -- lbox + "00",'0','0','0','0','0','0','0', -- mbox + '0',"000","000","00",'0' -- rest + ); + + constant c_dpath_dsrc_src : slbit := '0'; -- DSRC = R(SRC) + constant c_dpath_dsrc_res : slbit := '1'; -- DSRC = DRES + constant c_dpath_ddst_dst : slbit := '0'; -- DDST = R(DST) + constant c_dpath_ddst_res : slbit := '1'; -- DDST = DRES + + constant c_dpath_dtmp_dsrc : slv2 := "00"; -- DTMP = DSRC + constant c_dpath_dtmp_psw : slv2 := "01"; -- DTMP = PSW + constant c_dpath_dtmp_dres : slv2 := "10"; -- DTMP = DRES + constant c_dpath_dtmp_drese : slv2 := "11"; -- DTMP = DRESE + + constant c_dpath_res_abox : slv3 := "000"; -- D/CRES = ABOX + constant c_dpath_res_dbox : slv3 := "001"; -- D/CRES = DBOX + constant c_dpath_res_lbox : slv3 := "010"; -- D/CRES = LBOX + constant c_dpath_res_mbox : slv3 := "011"; -- D/CRES = MBOX + constant c_dpath_res_vmdout : slv3 := "100"; -- D/CRES = VMDOUT + constant c_dpath_res_fpdout : slv3 := "101"; -- D/CRES = FPDOUT + constant c_dpath_res_ireg : slv3 := "110"; -- D/CRES = IREG + constant c_dpath_res_cpdin : slv3 := "111"; -- D/CRES = CPDIN + + constant c_dpath_vmaddr_dsrc : slv2 := "00"; -- VMADDR = DSRC + constant c_dpath_vmaddr_ddst : slv2 := "01"; -- VMADDR = DDST + constant c_dpath_vmaddr_pc : slv2 := "10"; -- VMADDR = PC + constant c_dpath_vmaddr_dtmp : slv2 := "11"; -- VMADDR = DTMP + + type dpath_stat_type is record -- data path status + ccout_z : slbit; -- current effective Z cc flag + shc_tc : slbit; -- last shc cycle (shc==0) + div_cr : slbit; -- division: reminder correction needed + div_cq : slbit; -- division: quotient correction needed + div_zero : slbit; -- division: divident or divisor zero + div_ovfl : slbit; -- division: overflow + end record dpath_stat_type; + + constant dpath_stat_init : dpath_stat_type := (others=>'0'); + + type decode_stat_type is record -- decode status + is_dstmode0 : slbit; -- dest. is register mode + is_srcpc : slbit; -- source is pc + is_srcpcmode1 : slbit; -- source is pc and mode=1 + is_dstpc : slbit; -- dest. is pc + is_dstw_reg : slbit; -- dest. register to be written + is_dstw_pc : slbit; -- pc register to be written + is_rmwop : slbit; -- read-modify-write operation + is_bytop : slbit; -- byte operation + is_res : slbit; -- reserved operation code + op_rtt : slbit; -- RTT instruction + op_mov : slbit; -- MOV instruction + trap_vec : slv3; -- trap vector addr bits 4:2 + force_srcsp : slbit; -- force src register to be sp + updt_dstadsrc : slbit; -- update dsrc in dsta flow + dbox_srcmod : slv2; -- dbox src port modifier + dbox_dstmod : slv2; -- dbox dst port modifier + dbox_cimod : slv2; -- dbox ci port modifier + dbox_cc1op : slbit; -- dbox use cc modes (1 op instruction) + dbox_ccmode : slv3; -- dbox cc port mode + lbox_func : slv4; -- lbox function + mbox_func : slv2; -- mbox function + res_sel : slv3; -- result bus (cres/dres) select + fork_op : slv4; -- op fork after idecode state + fork_srcr : slv2; -- src-read fork after idecode state + fork_dstr : slv2; -- dst-read fork after src read state + fork_dsta : slv2; -- dst-addr fork after idecode state + fork_opg : slv4; -- opg fork + fork_opa : slv3; -- opa fork + do_fork_op : slbit; -- execute fork_op + do_fork_srcr : slbit; -- execute fork_srcr + do_fork_dstr : slbit; -- execute fork_dstr + do_fork_dsta : slbit; -- execute fork_dsta + do_fork_opg : slbit; -- execute fork_opg + do_pref_dec : slbit; -- can do prefetch at decode phase + end record decode_stat_type; + + constant decode_stat_init : decode_stat_type := ( + '0','0','0','0','0','0','0','0','0', -- is_ + '0','0',"000",'0','0', -- op_, trap_, force_, updt_ + "00","00","00",'0',"000", -- dbox_ + "0000","00","000", -- lbox_, mbox_, res_ + "0000","00","00","00","0000","000", -- fork_ + '0','0','0','0','0', -- do_fork_ + '0' -- do_pref_ + ); + + constant c_fork_op_halt : slv4 := "0000"; + constant c_fork_op_wait : slv4 := "0001"; + constant c_fork_op_rtti : slv4 := "0010"; + constant c_fork_op_trap : slv4 := "0011"; + constant c_fork_op_reset: slv4 := "0100"; + constant c_fork_op_rts : slv4 := "0101"; + constant c_fork_op_spl : slv4 := "0110"; + constant c_fork_op_mcc : slv4 := "0111"; + constant c_fork_op_br : slv4 := "1000"; + constant c_fork_op_mark : slv4 := "1001"; + constant c_fork_op_sob : slv4 := "1010"; + constant c_fork_op_mtp : slv4 := "1011"; + + constant c_fork_srcr_def : slv2:= "00"; + constant c_fork_srcr_inc : slv2:= "01"; + constant c_fork_srcr_dec : slv2:= "10"; + constant c_fork_srcr_ind : slv2:= "11"; + + constant c_fork_dstr_def : slv2:= "00"; + constant c_fork_dstr_inc : slv2:= "01"; + constant c_fork_dstr_dec : slv2:= "10"; + constant c_fork_dstr_ind : slv2:= "11"; + + constant c_fork_dsta_def : slv2:= "00"; + constant c_fork_dsta_inc : slv2:= "01"; + constant c_fork_dsta_dec : slv2:= "10"; + constant c_fork_dsta_ind : slv2:= "11"; + + constant c_fork_opg_gen : slv4 := "0000"; + constant c_fork_opg_wdef : slv4 := "0001"; + constant c_fork_opg_winc : slv4 := "0010"; + constant c_fork_opg_wdec : slv4 := "0011"; + constant c_fork_opg_wind : slv4 := "0100"; + constant c_fork_opg_mul : slv4 := "0101"; + constant c_fork_opg_div : slv4 := "0110"; + constant c_fork_opg_ash : slv4 := "0111"; + constant c_fork_opg_ashc : slv4 := "1000"; + + constant c_fork_opa_jsr : slv3 := "000"; + constant c_fork_opa_jmp : slv3 := "001"; + constant c_fork_opa_mtp : slv3 := "010"; + constant c_fork_opa_mfp_reg : slv3 := "011"; + constant c_fork_opa_mfp_mem : slv3 := "100"; + + -- Note: MSB=0 are 'normal' states, MSB=1 are fatal errors + constant c_cpurust_init : slv4 := "0000"; -- cpu in init state + constant c_cpurust_halt : slv4 := "0001"; -- cpu executed HALT + constant c_cpurust_reset : slv4 := "0010"; -- cpu was reset + constant c_cpurust_stop : slv4 := "0011"; -- cpu was stopped + constant c_cpurust_step : slv4 := "0100"; -- cpu was stepped + constant c_cpurust_susp : slv4 := "0101"; -- cpu was suspended + constant c_cpurust_runs : slv4 := "0111"; -- cpu running + constant c_cpurust_vecfet : slv4 := "1000"; -- vector fetch error halt + constant c_cpurust_recrsv : slv4 := "1001"; -- recursive red-stack halt + constant c_cpurust_sfail : slv4 := "1100"; -- sequencer failure + constant c_cpurust_vfail : slv4 := "1101"; -- vmbox failure + + type cpustat_type is record -- CPU status + cmdbusy : slbit; -- command busy + cmdack : slbit; -- command acknowledge + cmderr : slbit; -- command error + cmdmerr : slbit; -- command memory access error + cpugo : slbit; -- CPU go state + cpustep : slbit; -- CPU step flag + cpuhalt : slbit; -- CPU halt flag + cpuwait : slbit; -- CPU wait flag + cpurust : slv4; -- CPU run status + cpfunc : slv5; -- current control port function + cprnum : slv3; -- current control port register number + waitsusp : slbit; -- WAIT instruction suspended + intvect : slv9_2; -- current interrupt vector + trap_mmu : slbit; -- mmu trace trap pending + trap_ysv : slbit; -- ysv trap pending + prefdone : slbit; -- prefetch done + do_gprwe : slbit; -- pending gpr_we + do_intrsv : slbit; -- active rsv interrupt sequence + end record cpustat_type; + + constant cpustat_init : cpustat_type := ( + '0','0','0','0', -- cmd.. + '0','0','0','0', -- cpu.. + c_cpurust_init, -- cpurust + "00000","000", -- cpfunc, cprnum + '0', -- waitsusp + (others=>'0'), -- intvect + '0','0','0', -- trap_(mmu|ysv), prefdone + '0','0' -- do_gprwe, do_intrsv + ); + + type cpuerr_type is record -- CPU error register + illhlt : slbit; -- illegal halt (in non-kernel mode) + adderr : slbit; -- address error (odd, jmp/jsr reg) + nxm : slbit; -- non-existent memory + iobto : slbit; -- I/O bus timeout (non-exist UB) + ysv : slbit; -- yellow stack violation + rsv : slbit; -- red stack violation + end record cpuerr_type; + + constant cpuerr_init : cpuerr_type := (others=>'0'); + + type vm_cntl_type is record -- virt memory control port + req : slbit; -- request + wacc : slbit; -- write access + macc : slbit; -- modify access (r-m-w sequence) + cacc : slbit; -- console access + bytop : slbit; -- byte operation + dspace : slbit; -- dspace operation + kstack : slbit; -- access through kernel stack + intrsv : slbit; -- active rsv interrupt sequence + mode : slv2; -- mode + trap_done : slbit; -- mmu trap taken (to set ssr0 bit) + end record vm_cntl_type; + + constant vm_cntl_init : vm_cntl_type := ( + '0','0','0','0', -- req, wacc, macc,cacc + '0','0','0', -- bytop, dspace, kstack + '0',"00",'0' -- intrsv, mode, trap_done + ); + + type vm_stat_type is record -- virt memory status port + ack : slbit; -- acknowledge + err : slbit; -- error (see err_xxx for reason) + fail : slbit; -- failure (machine check) + err_odd : slbit; -- abort: odd address error + err_mmu : slbit; -- abort: mmu reject + err_nxm : slbit; -- abort: non-existing memory + err_iobto : slbit; -- abort: non-existing I/O resource + err_rsv : slbit; -- abort: red stack violation + trap_ysv : slbit; -- trap: yellow stack violation + trap_mmu : slbit; -- trap: mmu trace trap + end record vm_stat_type; + + constant vm_stat_init : vm_stat_type := (others=>'0'); + + type em_mreq_type is record -- external memory - master request + req : slbit; -- request + we : slbit; -- write enable + be : slv2; -- byte enables + cancel : slbit; -- cancel request + addr : slv22_1; -- address + din : slv16; -- data in (input to memory) + end record em_mreq_type; + + constant em_mreq_init : em_mreq_type := ( + '0','0',"00",'0', -- req, we, be, cancel + (others=>'0'),(others=>'0') -- addr, din + ); + + type em_sres_type is record -- external memory - slave response + ack_r : slbit; -- acknowledge read + ack_w : slbit; -- acknowledge write + dout : slv16; -- data out (output from memory) + end record em_sres_type; + + constant em_sres_init : em_sres_type := ( + '0','0', -- ack_r, ack_w + (others=>'0') -- dout + ); + + type mmu_cntl_type is record -- mmu control port + req : slbit; -- translate request + wacc : slbit; -- write access + macc : slbit; -- modify access (r-m-w sequence) + cacc : slbit; -- console access (bypass mmu) + dspace : slbit; -- dspace access + mode : slv2; -- processor mode + trap_done : slbit; -- mmu trap taken (set ssr0 bit) + end record mmu_cntl_type; + + constant mmu_cntl_init : mmu_cntl_type := ( + '0','0','0','0', -- req, wacc, macc, cacc + '0',"00",'0' -- dspace, mode, trap_done + ); + + type mmu_stat_type is record -- mmu status port + vaok : slbit; -- virtual address valid + trap : slbit; -- mmu trap request + ena_mmu : slbit; -- mmu enable (ssr0 bit 0) + ena_22bit : slbit; -- mmu in 22 bit mode (ssr3 bit 4) + ena_ubmap : slbit; -- ubmap enable (ssr3 bit 5) + end record mmu_stat_type; + + constant mmu_stat_init : mmu_stat_type := (others=>'0'); + + type mmu_moni_type is record -- mmu monitor port + istart : slbit; -- instruction start + idone : slbit; -- instruction done + pc : slv16; -- PC of new instruction + regmod : slbit; -- register modified + regnum : slv3; -- register number + delta : slv4; -- register offset + isdec : slbit; -- offset to be subtracted + trace_prev : slbit; -- use ssr12 trace state of prev. state + end record mmu_moni_type; + + constant mmu_moni_init : mmu_moni_type := ( + '0','0',(others=>'0'), -- istart, idone, pc + '0',"000","0000", -- regmod, regnum, delta + '0','0' -- isdec, trace_prev + ); + + type mmu_ssr0_type is record -- MMU ssr0 + abo_nonres : slbit; -- abort non resident + abo_length : slbit; -- abort segment length + abo_rdonly : slbit; -- abort read-only + trap_mmu : slbit; -- trap management + ena_trap : slbit; -- enable traps + inst_compl : slbit; -- instruction complete + seg_mode : slv2; -- segement mode + dspace : slbit; -- address space (D=1, I=0) + seg_num : slv3; -- segment number + ena_mmu : slbit; -- enable memory management + trace_prev : slbit; -- ssr12 trace status in prev. state + end record mmu_ssr0_type; + + constant mmu_ssr0_init : mmu_ssr0_type := ( + inst_compl=>'0', seg_mode=>"00", seg_num=>"000", + others=>'0' + ); + + type mmu_ssr1_type is record -- MMU ssr1 + rb_delta : slv5; -- RB: amount change + rb_num : slv3; -- RB: register number + ra_delta : slv5; -- RA: amount change + ra_num : slv3; -- RA: register number + end record mmu_ssr1_type; + + constant mmu_ssr1_init : mmu_ssr1_type := ( + "00000","000", -- rb_... + "00000","000" -- ra_... + ); + + type mmu_ssr3_type is record -- MMU ssr3 + ena_ubmap : slbit; -- enable unibus mapping + ena_22bit : slbit; -- enable 22 bit mapping + dspace_km : slbit; -- enable dspace kernel + dspace_sm : slbit; -- enable dspace supervisor + dspace_um : slbit; -- enable dspace user + end record mmu_ssr3_type; + + constant mmu_ssr3_init : mmu_ssr3_type := (others=>'0'); + +-- control port definitions -------------------------------------------------- + + type cp_cntl_type is record -- control port control + req : slbit; -- request + func : slv5; -- function + rnum : slv3; -- register number + end record cp_cntl_type; + + constant c_cpfunc_noop : slv5 := "00000"; -- noop : no operation + constant c_cpfunc_sta : slv5 := "00001"; -- sta : cpu start + constant c_cpfunc_sto : slv5 := "00010"; -- sto : cpu stop + constant c_cpfunc_cont : slv5 := "00011"; -- cont : cpu continue + constant c_cpfunc_step : slv5 := "00100"; -- step : cpu step + constant c_cpfunc_rst : slv5 := "01111"; -- rst : cpu reset (soft) + constant c_cpfunc_rreg : slv5 := "10000"; -- rreg : read register + constant c_cpfunc_wreg : slv5 := "10001"; -- wreg : write register + constant c_cpfunc_rpsw : slv5 := "10010"; -- rpsw : read psw + constant c_cpfunc_wpsw : slv5 := "10011"; -- wpsw : write psw + constant c_cpfunc_rmem : slv5 := "10100"; -- rmem : read memory + constant c_cpfunc_wmem : slv5 := "10101"; -- wmem : write memory + + constant cp_cntl_init : cp_cntl_type := ('0',c_cpfunc_noop,"000"); + + type cp_stat_type is record -- control port status + cmdbusy : slbit; -- command busy + cmdack : slbit; -- command acknowledge + cmderr : slbit; -- command error + cmdmerr : slbit; -- command memory access error + cpugo : slbit; -- CPU go state + cpustep : slbit; -- CPU step flag + cpuhalt : slbit; -- CPU halt flag + cpuwait : slbit; -- CPU wait flag + cpurust : slv4; -- CPU run status + end record cp_stat_type; + + constant cp_stat_init : cp_stat_type := ( + '0','0','0','0', -- cmd... + '0','0','0','0', -- cpu... + (others=>'0') -- cpurust + ); + + type cp_addr_type is record -- control port address + addr : slv22_1; -- address + racc : slbit; -- ibr access + be : slv2; -- byte enables + ena_22bit : slbit; -- enable 22 bit mode + ena_ubmap : slbit; -- enable unibus mapper + end record cp_addr_type; + + constant cp_addr_init : cp_addr_type := ( + (others=>'0'), -- addr + '0',"00", -- racc, be + '0','0' -- ena_... + ); + +-- debug and monitoring port definitions ------------------------------------- + + type dm_cntl_type is record -- debug and monitor control + dum1 : slbit; -- dummy 1 + dum2 : slbit; -- dummy 2 + end record dm_cntl_type; + + constant dm_cntl_init : dm_cntl_type := (others=>'0'); + + type dm_stat_dp_type is record -- debug and monitor status - dpath + pc : slv16; -- pc + psw : psw_type; -- psw + ireg : slv16; -- ireg + ireg_we : slbit; -- ireg we + dsrc : slv16; -- dsrc register + ddst : slv16; -- ddst register + dtmp : slv16; -- dtmp register + dres : slv16; -- dres bus + gpr_adst : slv3; -- gpr dst regsiter + gpr_mode : slv2; -- gpr mode + gpr_bytop : slbit; -- gpr bytop + gpr_we : slbit; -- gpr we + end record dm_stat_dp_type; + + constant dm_stat_dp_init : dm_stat_dp_type := ( + (others=>'0'), -- pc + psw_init, -- psw + (others=>'0'),'0', -- ireg, ireg_we + (others=>'0'),(others=>'0'), -- dsrc, ddst + (others=>'0'),(others=>'0'), -- dtmp, dres + (others=>'0'),(others=>'0'), -- gpr_adst, gpr_mode + '0','0' -- gpr_bytop, gpr_we + ); + + type dm_stat_vm_type is record -- debug and monitor status - vmbox + ibmreq : ib_mreq_type; -- ibus master request + ibsres : ib_sres_type; -- ibus slave response + end record dm_stat_vm_type; + + constant dm_stat_vm_init : dm_stat_vm_type := (ib_mreq_init,ib_sres_init); + + type dm_stat_co_type is record -- debug and monitor status - core + cpugo : slbit; -- cpugo state flag + cpuhalt : slbit; -- cpuhalt state flag + end record dm_stat_co_type; + + constant dm_stat_co_init : dm_stat_co_type := ('0','0'); + + type dm_stat_sy_type is record -- debug and monitor status - system + emmreq : em_mreq_type; -- external memory: request + emsres : em_sres_type; -- external memory: response + chit : slbit; -- cache hit + end record dm_stat_sy_type; + + constant dm_stat_sy_init : dm_stat_sy_type := (em_mreq_init,em_sres_init,'0'); + +-- rbus interface definitions ------------------------------------------------ + + constant c_rbaddr_conf : slv5 := "00000"; -- R/W configuration reg + constant c_rbaddr_cntl : slv5 := "00001"; -- -/F control reg + constant c_rbaddr_stat : slv5 := "00010"; -- R/- status reg + constant c_rbaddr_psw : slv5 := "00011"; -- R/W psw access + constant c_rbaddr_al : slv5 := "00100"; -- R/W address low reg + constant c_rbaddr_ah : slv5 := "00101"; -- R/W address high reg + constant c_rbaddr_mem : slv5 := "00110"; -- R/W memory access + constant c_rbaddr_memi : slv5 := "00111"; -- R/W memory access; inc addr + + constant c_rbaddr_r0 : slv5 := "01000"; -- R/W gpr 0 + constant c_rbaddr_r1 : slv5 := "01001"; -- R/W gpr 1 + constant c_rbaddr_r2 : slv5 := "01010"; -- R/W gpr 2 + constant c_rbaddr_r3 : slv5 := "01011"; -- R/W gpr 3 + constant c_rbaddr_r4 : slv5 := "01100"; -- R/W gpr 4 + constant c_rbaddr_r5 : slv5 := "01101"; -- R/W gpr 5 + constant c_rbaddr_sp : slv5 := "01110"; -- R/W gpr 6 (sp) + constant c_rbaddr_pc : slv5 := "01111"; -- R/W gpr 7 (pc) + + constant c_rbaddr_ibrb : slv5 := "10000"; -- R/W ibr base address + + subtype c_al_rbf_addr is integer range 15 downto 1; -- al: address + constant c_ah_rbf_ena_ubmap: integer := 7; -- ah: ubmap + constant c_ah_rbf_ena_22bit: integer := 6; -- ah: 22bit + subtype c_ah_rbf_addr is integer range 5 downto 0; -- ah: address + + constant c_stat_rbf_cmderr: integer := 0; -- stat field: cmderr + constant c_stat_rbf_cmdmerr: integer := 1; -- stat field: cmdmerr + constant c_stat_rbf_cpugo: integer := 2; -- stat field: cpugo + constant c_stat_rbf_cpuhalt: integer := 3; -- stat field: cpuhalt + subtype c_stat_rbf_cpurust is integer range 7 downto 4; -- cpurust + + subtype c_ibrb_ibf_base is integer range 12 downto 6; -- ibrb: base addr + subtype c_ibrb_ibf_be is integer range 1 downto 0; -- ibrb: be's + +-- ------------------------------------- + +component pdp11_gpr is -- general purpose registers + port ( + CLK : in slbit; -- clock + DIN : in slv16; -- input data + ASRC : in slv3; -- source register number + ADST : in slv3; -- destination register number + MODE : in slv2; -- processor mode (k=>00,s=>01,u=>11) + RSET : in slbit; -- register set + WE : in slbit; -- write enable + BYTOP : in slbit; -- byte operation (write low byte only) + PCINC : in slbit; -- increment PC + DSRC : out slv16; -- source register data + DDST : out slv16; -- destination register data + PC : out slv16 -- current PC value + ); +end component; + +constant c_gpr_r5 : slv3 := "101"; -- register number of r5 +constant c_gpr_sp : slv3 := "110"; -- register number of SP +constant c_gpr_pc : slv3 := "111"; -- register number of PC + +component pdp11_psr is -- processor status word register + port ( + CLK : in slbit; -- clock + CRESET : in slbit; -- console reset + DIN : in slv16; -- input data + CCIN : in slv4; -- cc input + CCWE : in slbit; -- enable update cc + WE : in slbit; -- write enable (from DIN) + FUNC : in slv3; -- write function (from DIN) + PSW : out psw_type; -- current psw + IB_MREQ : in ib_mreq_type; -- ibus request + IB_SRES : out ib_sres_type -- ibus response + ); +end component; + +constant c_psr_func_wspl : slv3 := "000"; -- SPL mode: set pri +constant c_psr_func_wcc : slv3 := "001"; -- CC mode: set/clear cc +constant c_psr_func_wint : slv3 := "010"; -- interupt mode: pmode=cmode +constant c_psr_func_wrti : slv3 := "011"; -- rti mode: protect modes +constant c_psr_func_wall : slv3 := "100"; -- write all fields + +component pdp11_abox is -- arithmetic unit for addresses (abox) + port ( + DSRC : in slv16; -- 'src' data for port A + DDST : in slv16; -- 'dst' data for port A + DTMP : in slv16; -- 'tmp' data for port A + PC : in slv16; -- PC data for port A + ASEL : in slv2; -- selector for port A + AZERO : in slbit; -- force zero for port A + IREG8 : in slv8; -- 'ireg' data for port B + VMDOUT : in slv16; -- virt. memory data for port B + CONST : in slv9; -- sequencer const data for port B + BSEL : in slv2; -- selector for port B + OPSUB : in slbit; -- operation: 0 add, 1 sub + DOUT : out slv16; -- data output + NZOUT : out slv2 -- NZ condition codes out + ); +end component; + +constant c_abox_asel_ddst : slv2 := "00"; -- A = DDST +constant c_abox_asel_dsrc : slv2 := "01"; -- A = DSRC +constant c_abox_asel_pc : slv2 := "10"; -- A = PC +constant c_abox_asel_dtmp : slv2 := "11"; -- A = DTMP + +constant c_abox_bsel_const : slv2 := "00"; -- B = CONST +constant c_abox_bsel_vmdout : slv2 := "01"; -- B = VMDOUT +constant c_abox_bsel_ireg6 : slv2 := "10"; -- B = 2*IREG(6bit) +constant c_abox_bsel_ireg8 : slv2 := "11"; -- B = 2*IREG(8bit,sign-extend) + +component pdp11_dbox is -- arithmetic unit for data (dbox) + port ( + DSRC : in slv16; -- 'src' data in + DDST : in slv16; -- 'dst' data in + CI : in slbit; -- carry flag in + SRCMOD : in slv2; -- src modifier mode + DSTMOD : in slv2; -- dst modifier mode + CIMOD : in slv2; -- ci modifier mode + CC1OP : in slbit; -- use cc modes (1 op instruction) + CCMODE : in slv3; -- cc mode + BYTOP : in slbit; -- byte operation + DOUT : out slv16; -- data output + CCOUT : out slv4 -- condition codes out + ); +end component; + +constant c_dbox_mod_pass : slv2 := "00"; -- pass data +constant c_dbox_mod_inv : slv2 := "01"; -- invert data +constant c_dbox_mod_zero : slv2 := "10"; -- set to 0 +constant c_dbox_mod_one : slv2 := "11"; -- set to 1 + +-- the c_dbox_ccmode codes follow exactly the opcode format (bit 8:6) +constant c_dbox_ccmode_clr : slv3 := "000"; -- do clr instruction +constant c_dbox_ccmode_com : slv3 := "001"; -- do com instruction +constant c_dbox_ccmode_inc : slv3 := "010"; -- do inc instruction +constant c_dbox_ccmode_dec : slv3 := "011"; -- do dec instruction +constant c_dbox_ccmode_neg : slv3 := "100"; -- do neg instruction +constant c_dbox_ccmode_adc : slv3 := "101"; -- do adc instruction +constant c_dbox_ccmode_sbc : slv3 := "110"; -- do sbc instruction +constant c_dbox_ccmode_tst : slv3 := "111"; -- do tst instruction + +component pdp11_lbox is -- logic unit for data (lbox) + port ( + DSRC : in slv16; -- 'src' data in + DDST : in slv16; -- 'dst' data in + CCIN : in slv4; -- condition codes in + FUNC : in slv4; -- function + BYTOP : in slbit; -- byte operation + DOUT : out slv16; -- data output + CCOUT : out slv4 -- condition codes out + ); +end component; + +constant c_lbox_func_asr : slv4 := "0000"; -- ASR/ASRB ??? recheck coding !! +constant c_lbox_func_asl : slv4 := "0001"; -- ASL/ASLB +constant c_lbox_func_ror : slv4 := "0010"; -- ROR/RORB +constant c_lbox_func_rol : slv4 := "0011"; -- ROL/ROLB +constant c_lbox_func_bis : slv4 := "0100"; -- BIS/BISB +constant c_lbox_func_bic : slv4 := "0101"; -- BIC/BICB +constant c_lbox_func_bit : slv4 := "0110"; -- BIT/BITB +constant c_lbox_func_mov : slv4 := "0111"; -- MOV/MOVB +constant c_lbox_func_sxt : slv4 := "1000"; -- SXT +constant c_lbox_func_swap : slv4 := "1001"; -- SWAB +constant c_lbox_func_xor : slv4 := "1010"; -- XOR + +component pdp11_mbox is -- mul/div unit for data (mbox) + port ( + CLK : in slbit; -- clock + DSRC : in slv16; -- 'src' data in + DDST : in slv16; -- 'dst' data in + DTMP : in slv16; -- 'tmp' data in + GPR_DSRC : in slv16; -- 'src' data from GPR + FUNC : in slv2; -- function + S_DIV : in slbit; -- s_opg_div state + S_DIV_CN : in slbit; -- s_opg_div_cn state + S_DIV_CR : in slbit; -- s_opg_div_cr state + S_ASH : in slbit; -- s_opg_ash state + S_ASH_CN : in slbit; -- s_opg_ash_cn state + S_ASHC : in slbit; -- s_opg_ashc state + S_ASHC_CN : in slbit; -- s_opg_ashc_cn state + SHC_TC : out slbit; -- last shc cycle (shc==0) + DIV_CR : out slbit; -- division: reminder correction needed + DIV_CQ : out slbit; -- division: quotient correction needed + DIV_ZERO : out slbit; -- division: divident or divisor zero + DIV_OVFL : out slbit; -- division: overflow + DOUT : out slv16; -- data output + DOUTE : out slv16; -- data output extra + CCOUT : out slv4 -- condition codes out + ); +end component; + +constant c_mbox_func_mul : slv2 := "00"; -- MUL +constant c_mbox_func_div : slv2 := "01"; -- DIV +constant c_mbox_func_ash : slv2 := "10"; -- ASH +constant c_mbox_func_ashc : slv2 := "11"; -- ASHC + +component pdp11_mmu_sadr is -- mmu SAR/SDR register set + port ( + CLK : in slbit; -- clock + MODE : in slv2; -- mode + ASN : in slv4; -- augmented segment number (1+3 bit) + AIB_WE : in slbit; -- update AIB + AIB_SETA : in slbit; -- set access AIB + AIB_SETW : in slbit; -- set write AIB + SARSDR : out sarsdr_type; -- combined SAR/SDR + IB_MREQ : in ib_mreq_type; -- ibus request + IB_SRES : out ib_sres_type -- ibus response + ); +end component; + +component pdp11_mmu_ssr12 is -- mmu register ssr1 and ssr2 + port ( + CLK : in slbit; -- clock + CRESET : in slbit; -- console reset + TRACE : in slbit; -- trace enable + MONI : in mmu_moni_type; -- MMU monitor port data + IB_MREQ : in ib_mreq_type; -- ibus request + IB_SRES : out ib_sres_type -- ibus response + ); +end component; + +component pdp11_mmu is -- mmu - memory management unit + port ( + CLK : in slbit; -- clock + CRESET : in slbit; -- console reset + BRESET : in slbit; -- ibus reset + CNTL : in mmu_cntl_type; -- control port + VADDR : in slv16; -- virtual address + MONI : in mmu_moni_type; -- monitor port + STAT : out mmu_stat_type; -- status port + PADDRH : out slv16; -- physical address (upper 16 bit) + IB_MREQ : in ib_mreq_type; -- ibus request + IB_SRES : out ib_sres_type -- ibus response + ); +end component; + +component pdp11_vmbox is -- virtual memory + port ( + CLK : in slbit; -- clock + GRESET : in slbit; -- global reset + CRESET : in slbit; -- console reset + BRESET : in slbit; -- ibus reset + CP_ADDR : in cp_addr_type; -- console port address + VM_CNTL : in vm_cntl_type; -- vm control port + VM_ADDR : in slv16; -- vm address + VM_DIN : in slv16; -- vm data in + VM_STAT : out vm_stat_type; -- vm status port + VM_DOUT : out slv16; -- vm data out + EM_MREQ : out em_mreq_type; -- external memory: request + EM_SRES : in em_sres_type; -- external memory: response + MMU_MONI : in mmu_moni_type; -- mmu monitor port + IB_MREQ_M : out ib_mreq_type; -- ibus request (master) + IB_SRES_CPU : in ib_sres_type; -- ibus response (CPU registers) + IB_SRES_EXT : in ib_sres_type; -- ibus response (external devices) + DM_STAT_VM : out dm_stat_vm_type -- debug and monitor status + ); +end component; + +component pdp11_dpath is -- CPU datapath + port ( + CLK : in slbit; -- clock + CRESET : in slbit; -- console reset + CNTL : in dpath_cntl_type; -- control interface + STAT : out dpath_stat_type; -- status interface + CP_DIN : in slv16; -- console port data in + CP_DOUT : out slv16; -- console port data out + PSWOUT : out psw_type; -- current psw + PCOUT : out slv16; -- current pc + IREG : out slv16; -- ireg out + VM_ADDR : out slv16; -- virt. memory address + VM_DOUT : in slv16; -- virt. memory data out + VM_DIN : out slv16; -- virt. memory data in + IB_MREQ : in ib_mreq_type; -- ibus request + IB_SRES : out ib_sres_type; -- ibus response + DM_STAT_DP : out dm_stat_dp_type -- debug and monitor status + ); +end component; + +component pdp11_decode is -- instruction decoder + port ( + IREG : in slv16; -- input instruction word + STAT : out decode_stat_type -- status output + ); +end component; + +component pdp11_sequencer is -- cpu sequencer + port ( + CLK : in slbit; -- clock + GRESET : in slbit; -- global reset + PSW : in psw_type; -- processor status + PC : in slv16; -- program counter + IREG : in slv16; -- IREG + ID_STAT : in decode_stat_type; -- instr. decoder status + DP_STAT : in dpath_stat_type; -- data path status + CP_CNTL : in cp_cntl_type; -- console port control + VM_STAT : in vm_stat_type; -- virtual memory status port + INT_PRI : in slv3; -- interrupt priority + INT_VECT : in slv9_2; -- interrupt vector + CRESET : out slbit; -- console reset + BRESET : out slbit; -- ibus reset + MMU_MONI : out mmu_moni_type; -- mmu monitor port + DP_CNTL : out dpath_cntl_type; -- data path control + VM_CNTL : out vm_cntl_type; -- virtual memory control port + CP_STAT : out cp_stat_type; -- console port status + INT_ACK : out slbit; -- interrupt acknowledge + IB_MREQ : in ib_mreq_type; -- ibus request + IB_SRES : out ib_sres_type -- ibus response + ); +end component; + +component pdp11_irq is -- interrupt requester + port ( + CLK : in slbit; -- clock + BRESET : in slbit; -- ibus reset + INT_ACK : in slbit; -- interrupt acknowledge from CPU + EI_PRI : in slv3; -- external interrupt priority + EI_VECT : in slv9_2; -- external interrupt vector + EI_ACKM : out slbit; -- external interrupt acknowledge + PRI : out slv3; -- interrupt priority + VECT : out slv9_2; -- interrupt vector + IB_MREQ : in ib_mreq_type; -- ibus request + IB_SRES : out ib_sres_type -- ibus response + ); +end component; + +component pdp11_ubmap is -- 11/70 unibus mapper + port ( + CLK : in slbit; -- clock + MREQ : in slbit; -- request mapping + ADDR_UB : in slv18_1; -- UNIBUS address (in) + ADDR_PM : out slv22_1; -- physical memory address (out) + IB_MREQ : in ib_mreq_type; -- ibus request + IB_SRES : out ib_sres_type -- ibus response + ); +end component; + +component pdp11_sys70 is -- 11/70 memory system registers + port ( + CLK : in slbit; -- clock + CRESET : in slbit; -- console reset + IB_MREQ : in ib_mreq_type; -- ibus request + IB_SRES : out ib_sres_type -- ibus response + ); +end component; + +component pdp11_mem70 is -- 11/70 memory system registers + port ( + CLK : in slbit; -- clock + CRESET : in slbit; -- console reset + HM_ENA : in slbit; -- hit/miss enable + HM_VAL : in slbit; -- hit/miss value + CACHE_FMISS : out slbit; -- cache force miss + IB_MREQ : in ib_mreq_type; -- ibus request + IB_SRES : out ib_sres_type -- ibus response + ); +end component; + +component pdp11_cache is -- cache + port ( + CLK : in slbit; -- clock + GRESET : in slbit; -- global reset + EM_MREQ : in em_mreq_type; -- em request + EM_SRES : out em_sres_type; -- em response + FMISS : in slbit; -- force miss + CHIT : out slbit; -- cache hit flag + MEM_REQ : out slbit; -- memory: request + MEM_WE : out slbit; -- memory: write enable + MEM_BUSY : in slbit; -- memory: controller busy + MEM_ACK_R : in slbit; -- memory: acknowledge read + MEM_ADDR : out slv20; -- memory: address + MEM_BE : out slv4; -- memory: byte enable + MEM_DI : out slv32; -- memory: data in (memory view) + MEM_DO : in slv32 -- memory: data out (memory view) + ); +end component; + +component pdp11_core is -- full processor core + port ( + CLK : in slbit; -- clock + RESET : in slbit; -- reset + CP_CNTL : in cp_cntl_type; -- console control port + CP_ADDR : in cp_addr_type; -- console address port + CP_DIN : in slv16; -- console data in + CP_STAT : out cp_stat_type; -- console status port + CP_DOUT : out slv16; -- console data out + EI_PRI : in slv3; -- external interrupt priority + EI_VECT : in slv9_2; -- external interrupt vector + EI_ACKM : out slbit; -- external interrupt acknowledge + EM_MREQ : out em_mreq_type; -- external memory: request + EM_SRES : in em_sres_type; -- external memory: response + BRESET : out slbit; -- ibus reset + IB_MREQ_M : out ib_mreq_type; -- ibus master request (master) + IB_SRES_M : in ib_sres_type; -- ibus slave response (master) + DM_STAT_DP : out dm_stat_dp_type; -- debug and monitor status - dpath + DM_STAT_VM : out dm_stat_vm_type; -- debug and monitor status - vmbox + DM_STAT_CO : out dm_stat_co_type -- debug and monitor status - core + ); +end component; + +component pdp11_tmu is -- trace and monitor unit + port ( + CLK : in slbit; -- clock + ENA : in slbit := '0'; -- enable trace output + DM_STAT_DP : in dm_stat_dp_type; -- DM dpath + DM_STAT_VM : in dm_stat_vm_type; -- DM vmbox + DM_STAT_CO : in dm_stat_co_type; -- DM core + DM_STAT_SY : in dm_stat_sy_type -- DM system + ); +end component; + +component pdp11_tmu_sb is -- trace and mon. unit; simbus wrapper + generic ( + ENAPIN : integer := 13); -- SB_CNTL signal to use for enable + port ( + CLK : in slbit; -- clock + DM_STAT_DP : in dm_stat_dp_type; -- DM dpath + DM_STAT_VM : in dm_stat_vm_type; -- DM vmbox + DM_STAT_CO : in dm_stat_co_type; -- DM core + DM_STAT_SY : in dm_stat_sy_type -- DM system + ); +end component; + +component pdp11_du_drv is -- display unit low level driver + generic ( + CDWIDTH : positive := 3); -- clock divider width + port ( + CLK : in slbit; -- clock + GRESET : in slbit; -- global reset + ROW0 : in slv22; -- led row 0 (22 leds, top) + ROW1 : in slv16; -- led row 1 (16 leds) + ROW2 : in slv16; -- led row 2 (16 leds) + ROW3 : in slv10; -- led row 3 (10 leds, bottom) + SWOPT : out slv8; -- option pattern from du + SWOPT_RDY : out slbit; -- marks update of swopt + DU_CLK : out slbit; -- DU: clk + DU_FRAME : out slbit; -- DU: frame + DU_MOSI : out slbit; -- DU: mosi (master out, slave in) + DU_MISO : in slbit -- DU: miso (master in, slave out) + ); +end component; + +component pdp11_bram is -- BRAM based ext. memory dummy + generic ( + AWIDTH : positive := 14); -- address width + port ( + CLK : in slbit; -- clock + GRESET : in slbit; -- global reset + EM_MREQ : in em_mreq_type; -- em request + EM_SRES : out em_sres_type -- em response + ); +end component; + +component pdp11_core_rri is -- core to rri reg port interface + generic ( + RB_ADDR_CORE : slv8 := conv_std_logic_vector(2#00000000#,8); + RB_ADDR_IBUS : slv8 := conv_std_logic_vector(2#10000000#,8)); + port ( + CLK : in slbit; -- clock + RESET : in slbit; -- reset + RB_MREQ : in rb_mreq_type; -- rbus: request + RB_SRES : out rb_sres_type; -- rbus: response + RB_STAT : out slv3; -- rbus: status flags + RRI_LAM : out slbit; -- remote attention + CPU_RESET : out slbit; -- cpu master reset + CP_CNTL : out cp_cntl_type; -- console control port + CP_ADDR : out cp_addr_type; -- console address port + CP_DIN : out slv16; -- console data in + CP_STAT : in cp_stat_type; -- console status port + CP_DOUT : in slv16 -- console data out + ); +end component; + +-- ----- move later to pdp11_conf -------------------------------------------- + +constant conf_vect_pirq : integer := 8#240#; +constant conf_pri_pirq_1 : integer := 1; +constant conf_pri_pirq_2 : integer := 2; +constant conf_pri_pirq_3 : integer := 3; +constant conf_pri_pirq_4 : integer := 4; +constant conf_pri_pirq_5 : integer := 5; +constant conf_pri_pirq_6 : integer := 6; +constant conf_pri_pirq_7 : integer := 7; + +end package pdp11; diff --git a/rtl/w11a/pdp11_abox.vbom b/rtl/w11a/pdp11_abox.vbom new file mode 100644 index 00000000..9763bb36 --- /dev/null +++ b/rtl/w11a/pdp11_abox.vbom @@ -0,0 +1,5 @@ +# libs +../vlib/slvtypes.vhd +pdp11.vbom +# design +pdp11_abox.vhd diff --git a/rtl/w11a/pdp11_abox.vhd b/rtl/w11a/pdp11_abox.vhd new file mode 100644 index 00000000..e9a04b0c --- /dev/null +++ b/rtl/w11a/pdp11_abox.vhd @@ -0,0 +1,112 @@ +-- $Id: pdp11_abox.vhd 314 2010-07-09 17:38:41Z mueller $ +-- +-- Copyright 2006-2007 by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, 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 complete details. +-- +------------------------------------------------------------------------------ +-- Module Name: pdp11_abox - syn +-- Description: pdp11: arithmetic unit for addresses (abox) +-- +-- Dependencies: - +-- Test bench: tb/tb_pdp11_core (implicit) +-- Target Devices: generic +-- Tool versions: xst 8.1, 8.2, 9.1, 9.2; ghdl 0.18-0.25 +-- Revision History: +-- Date Rev Version Comment +-- 2007-06-14 56 1.0.1 Use slvtypes.all +-- 2007-05-12 26 1.0 Initial version +------------------------------------------------------------------------------ + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; + +use work.slvtypes.all; +use work.pdp11.all; + +-- ---------------------------------------------------------------------------- + +entity pdp11_abox is -- arithmetic unit for addresses (abox) + port ( + DSRC : in slv16; -- 'src' data for port A + DDST : in slv16; -- 'dst' data for port A + DTMP : in slv16; -- 'tmp' data for port A + PC : in slv16; -- PC data for port A + ASEL : in slv2; -- selector for port A + AZERO : in slbit; -- force zero for port A + IREG8 : in slv8; -- 'ireg' data for port B + VMDOUT : in slv16; -- virt. memory data for port B + CONST : in slv9; -- sequencer const data for port B + BSEL : in slv2; -- selector for port B + OPSUB : in slbit; -- operation: 0 add, 1 sub + DOUT : out slv16; -- data output + NZOUT : out slv2 -- NZ condition codes out + ); +end pdp11_abox; + +architecture syn of pdp11_abox is + +-- -------------------------------------- + +begin + + process (DSRC, DDST, DTMP, PC, ASEL, AZERO, + IREG8, VMDOUT, CONST, BSEL, OPSUB) + + variable ma : slv16 := (others=>'0'); -- effective port a data + variable mb : slv16 := (others=>'0'); -- effective port b data + variable sum : slv16 := (others=>'0'); -- sum + variable nzo : slbit := '0'; + + begin + + if AZERO = '0' then + case ASEL is + when c_abox_asel_dsrc => ma := DSRC; + when c_abox_asel_ddst => ma := DDST; + when c_abox_asel_dtmp => ma := DTMP; + when c_abox_asel_pc => ma := PC; + when others => null; + end case; + else + ma := (others=>'0'); + end if; + + case BSEL is + when c_abox_bsel_ireg6 => mb := "000000000" & IREG8(5 downto 0) & "0"; + when c_abox_bsel_ireg8 => mb := IREG8(7) & IREG8(7) & IREG8(7) & + IREG8(7) & IREG8(7) & IREG8(7) & + IREG8(7) & IREG8 & "0"; + when c_abox_bsel_vmdout => mb := VMDOUT; + when c_abox_bsel_const => mb := "0000000" & CONST; + when others => null; + end case; + + if OPSUB = '0' then + sum := unsigned(ma) + unsigned(mb); + else + sum := unsigned(ma) - unsigned(mb); + end if; + + nzo := '0'; + if unsigned(sum) = 0 then + nzo := '1'; + else + nzo := '0'; + end if; + + DOUT <= sum; + NZOUT(1) <= sum(15); + NZOUT(0) <= nzo; + + end process; + +end syn; diff --git a/rtl/w11a/pdp11_bram.vbom b/rtl/w11a/pdp11_bram.vbom new file mode 100644 index 00000000..ec468167 --- /dev/null +++ b/rtl/w11a/pdp11_bram.vbom @@ -0,0 +1,9 @@ +# libs +../vlib/slvtypes.vhd +../vlib/memlib/memlib.vhd +pdp11.vbom +# components +[ghdl,isim]../vlib/memlib/ram_2swsr_rfirst_gen.vbom +[xst]../vlib/memlib/ram_2swsr_rfirst_gen_unisim.vbom +# design +pdp11_bram.vhd diff --git a/rtl/w11a/pdp11_bram.vhd b/rtl/w11a/pdp11_bram.vhd new file mode 100644 index 00000000..19cdfee5 --- /dev/null +++ b/rtl/w11a/pdp11_bram.vhd @@ -0,0 +1,138 @@ +-- $Id: pdp11_bram.vhd 314 2010-07-09 17:38:41Z mueller $ +-- +-- Copyright 2008- by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, 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 complete details. +-- +------------------------------------------------------------------------------ +-- Module Name: pdp11_bram - syn +-- Description: pdp11: BRAM based ext. memory dummy +-- +-- Dependencies: memlib/ram_2swsr_rfirst_gen +-- Test bench: - +-- Target Devices: generic +-- Tool versions: xst 8.1, 8.2, 9.1, 9.2; ghdl 0.18-0.25 +-- Revision History: +-- Date Rev Version Comment +-- 2008-03-01 120 1.0.2 add addrzero constant to avoid XST errors +-- 2008-02-23 118 1.0.1 AWIDTH now a generic port +-- 2008-02-17 117 1.0 Initial version +------------------------------------------------------------------------------ + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; + +use work.slvtypes.all; +use work.memlib.all; +use work.pdp11.all; + +entity pdp11_bram is -- cache + generic ( + AWIDTH : positive := 14); -- address width + port ( + CLK : in slbit; -- clock + GRESET : in slbit; -- global reset + EM_MREQ : in em_mreq_type; -- em request + EM_SRES : out em_sres_type -- em response + ); +end pdp11_bram; + + +architecture syn of pdp11_bram is + + type regs_type is record + req_r : slbit; -- read request + req_w : slbit; -- write request + be : slv2; -- byte enables + addr : slv(AWIDTH-1 downto 1); -- address + end record regs_type; + + constant addrzero : slv(AWIDTH-1 downto 1) := (others=>'0'); + + constant regs_init : regs_type := ( + '0','0', -- req_r,w + (others=>'0'), -- be + addrzero -- addr + ); + + signal R_REGS : regs_type := regs_init; -- state registers + signal N_REGS : regs_type := regs_init; -- next value state regs + + signal MEM_ENB : slbit := '0'; + signal MEM_WEA : slv2 := "00"; + signal MEM_DOA : slv16 := (others=>'0'); +begin + + MEM_BYT0 : ram_2swsr_rfirst_gen + generic map ( + AWIDTH => AWIDTH-1, + DWIDTH => 8) + port map ( + CLKA => CLK, + CLKB => CLK, + ENA => EM_MREQ.req, + ENB => MEM_ENB, + WEA => MEM_WEA(0), + WEB => R_REGS.be(0), + ADDRA => EM_MREQ.addr(AWIDTH-1 downto 1), + ADDRB => R_REGS.addr, + DIA => EM_MREQ.din(7 downto 0), + DIB => MEM_DOA(7 downto 0), + DOA => MEM_DOA(7 downto 0), + DOB => open + ); + + MEM_BYT1 : ram_2swsr_rfirst_gen + generic map ( + AWIDTH => AWIDTH-1, + DWIDTH => 8) + port map ( + CLKA => CLK, + CLKB => CLK, + ENA => EM_MREQ.req, + ENB => MEM_ENB, + WEA => MEM_WEA(1), + WEB => R_REGS.be(1), + ADDRA => EM_MREQ.addr(AWIDTH-1 downto 1), + ADDRB => R_REGS.addr, + DIA => EM_MREQ.din(15 downto 8), + DIB => MEM_DOA(15 downto 8), + DOA => MEM_DOA(15 downto 8), + DOB => open + ); + + proc_regs: process (CLK) + begin + + if CLK'event and CLK='1' then + if GRESET = '1' then + R_REGS <= regs_init; + else + R_REGS <= N_REGS; + end if; + end if; + + end process proc_regs; + + N_REGS.req_r <= EM_MREQ.req and not EM_MREQ.we; + N_REGS.req_w <= EM_MREQ.req and EM_MREQ.we; + N_REGS.be <= EM_MREQ.be; + N_REGS.addr <= EM_MREQ.addr(N_REGS.addr'range); + + MEM_WEA(0) <= EM_MREQ.we and EM_MREQ.be(0); + MEM_WEA(1) <= EM_MREQ.we and EM_MREQ.be(1); + MEM_ENB <= EM_MREQ.cancel and R_REGS.req_w; + + EM_SRES.ack_r <= R_REGS.req_r; + EM_SRES.ack_w <= R_REGS.req_w; + EM_SRES.dout <= MEM_DOA; + +end syn; diff --git a/rtl/w11a/pdp11_cache.vbom b/rtl/w11a/pdp11_cache.vbom new file mode 100644 index 00000000..886867bf --- /dev/null +++ b/rtl/w11a/pdp11_cache.vbom @@ -0,0 +1,9 @@ +# libs +../vlib/slvtypes.vhd +../vlib/memlib/memlib.vhd +pdp11.vbom +# components +[ghdl,isim]../vlib/memlib/ram_2swsr_rfirst_gen.vbom +[xst]../vlib/memlib/ram_2swsr_rfirst_gen_unisim.vbom +# design +pdp11_cache.vhd diff --git a/rtl/w11a/pdp11_cache.vhd b/rtl/w11a/pdp11_cache.vhd new file mode 100644 index 00000000..bfe17a1f --- /dev/null +++ b/rtl/w11a/pdp11_cache.vhd @@ -0,0 +1,446 @@ +-- $Id: pdp11_cache.vhd 314 2010-07-09 17:38:41Z mueller $ +-- +-- Copyright 2008- by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, 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 complete details. +-- +------------------------------------------------------------------------------ +-- Module Name: pdp11_cache - syn +-- Description: pdp11: cache +-- +-- Dependencies: memlib/ram_2swsr_rfirst_gen +-- Test bench: - +-- Target Devices: generic +-- Tool versions: xst 8.1, 8.2, 9.1, 9.2; ghdl 0.18-0.25 +-- Revision History: +-- Date Rev Version Comment +-- 2008-02-23 118 1.0.2 ce cache in s_idle to avoid U's in sim +-- factor invariants out of if's; fix tag rmiss logic +-- 2008-02-17 117 1.0.1 use em_(mreq|sres) interface; use req,we for mem +-- recode, ghdl doesn't like partial vector port maps +-- 2008-02-16 116 1.0 Initial version +------------------------------------------------------------------------------ + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; + +use work.slvtypes.all; +use work.memlib.all; +use work.pdp11.all; + +entity pdp11_cache is -- cache + port ( + CLK : in slbit; -- clock + GRESET : in slbit; -- global reset + EM_MREQ : in em_mreq_type; -- em request + EM_SRES : out em_sres_type; -- em response + FMISS : in slbit; -- force miss + CHIT : out slbit; -- cache hit flag + MEM_REQ : out slbit; -- memory: request + MEM_WE : out slbit; -- memory: write enable + MEM_BUSY : in slbit; -- memory: controller busy + MEM_ACK_R : in slbit; -- memory: acknowledge read + MEM_ADDR : out slv20; -- memory: address + MEM_BE : out slv4; -- memory: byte enable + MEM_DI : out slv32; -- memory: data in (memory view) + MEM_DO : in slv32 -- memory: data out (memory view) + ); +end pdp11_cache; + + +architecture syn of pdp11_cache is + + type state_type is ( + s_idle, -- s_idle: wait for req + s_read, -- s_read: read cycle + s_rmiss, -- s_rmiss: read miss + s_write -- s_write: write cycle + ); + + type regs_type is record + state : state_type; -- state + addr_w : slbit; -- address - word select + addr_l : slv11; -- address - cache line address + addr_t : slv9; -- address - cache tag part + be : slv4; -- byte enables (at 4 byte level) + di : slv16; -- data + end record regs_type; + + constant regs_init : regs_type := ( + s_idle, -- state + '0', -- addr_w + (others=>'0'), -- addr_l + (others=>'0'), -- addr_t + (others=>'0'), -- be + (others=>'0') -- di + ); + + signal R_REGS : regs_type := regs_init; -- state registers + signal N_REGS : regs_type := regs_init; -- next value state regs + + signal CMEM_TAG_CEA : slbit := '0'; + signal CMEM_TAG_CEB : slbit := '0'; + signal CMEM_TAG_WEA : slbit := '0'; + signal CMEM_TAG_WEB : slbit := '0'; + signal CMEM_TAG_DIB : slv9 := (others=>'0'); + signal CMEM_TAG_DOA : slv9 := (others=>'0'); + signal CMEM_DAT_CEA : slbit := '0'; + signal CMEM_DAT_CEB : slbit := '0'; + signal CMEM_DAT_WEA : slv4 := "0000"; + signal CMEM_DAT_WEB : slv4 := "0000"; + signal CMEM_DIA_0 : slv9 := (others=>'0'); + signal CMEM_DIA_1 : slv9 := (others=>'0'); + signal CMEM_DIA_2 : slv9 := (others=>'0'); + signal CMEM_DIA_3 : slv9 := (others=>'0'); + signal CMEM_DIB_0 : slv9 := (others=>'0'); + signal CMEM_DIB_1 : slv9 := (others=>'0'); + signal CMEM_DIB_2 : slv9 := (others=>'0'); + signal CMEM_DIB_3 : slv9 := (others=>'0'); + signal CMEM_DOA_0 : slv9 := (others=>'0'); + signal CMEM_DOA_1 : slv9 := (others=>'0'); + signal CMEM_DOA_2 : slv9 := (others=>'0'); + signal CMEM_DOA_3 : slv9 := (others=>'0'); + +begin + + CMEM_TAG : ram_2swsr_rfirst_gen + generic map ( + AWIDTH => 11, + DWIDTH => 9) + port map ( + CLKA => CLK, + CLKB => CLK, + ENA => CMEM_TAG_CEA, + ENB => CMEM_TAG_CEB, + WEA => CMEM_TAG_WEA, + WEB => CMEM_TAG_WEB, + ADDRA => EM_MREQ.addr(12 downto 2), + ADDRB => R_REGS.addr_l, + DIA => EM_MREQ.addr(21 downto 13), + DIB => CMEM_TAG_DIB, + DOA => CMEM_TAG_DOA, + DOB => open + ); + + CMEM_DAT0 : ram_2swsr_rfirst_gen + generic map ( + AWIDTH => 11, + DWIDTH => 9) + port map ( + CLKA => CLK, + CLKB => CLK, + ENA => CMEM_DAT_CEA, + ENB => CMEM_DAT_CEB, + WEA => CMEM_DAT_WEA(0), + WEB => CMEM_DAT_WEB(0), + ADDRA => EM_MREQ.addr(12 downto 2), + ADDRB => R_REGS.addr_l, + DIA => CMEM_DIA_0, + DIB => CMEM_DIB_0, + DOA => CMEM_DOA_0, + DOB => open + ); + + CMEM_DAT1 : ram_2swsr_rfirst_gen + generic map ( + AWIDTH => 11, + DWIDTH => 9) + port map ( + CLKA => CLK, + CLKB => CLK, + ENA => CMEM_DAT_CEA, + ENB => CMEM_DAT_CEB, + WEA => CMEM_DAT_WEA(1), + WEB => CMEM_DAT_WEB(1), + ADDRA => EM_MREQ.addr(12 downto 2), + ADDRB => R_REGS.addr_l, + DIA => CMEM_DIA_1, + DIB => CMEM_DIB_1, + DOA => CMEM_DOA_1, + DOB => open + ); + + CMEM_DAT2 : ram_2swsr_rfirst_gen + generic map ( + AWIDTH => 11, + DWIDTH => 9) + port map ( + CLKA => CLK, + CLKB => CLK, + ENA => CMEM_DAT_CEA, + ENB => CMEM_DAT_CEB, + WEA => CMEM_DAT_WEA(2), + WEB => CMEM_DAT_WEB(2), + ADDRA => EM_MREQ.addr(12 downto 2), + ADDRB => R_REGS.addr_l, + DIA => CMEM_DIA_2, + DIB => CMEM_DIB_2, + DOA => CMEM_DOA_2, + DOB => open + ); + + CMEM_DAT3 : ram_2swsr_rfirst_gen + generic map ( + AWIDTH => 11, + DWIDTH => 9) + port map ( + CLKA => CLK, + CLKB => CLK, + ENA => CMEM_DAT_CEA, + ENB => CMEM_DAT_CEB, + WEA => CMEM_DAT_WEA(3), + WEB => CMEM_DAT_WEB(3), + ADDRA => EM_MREQ.addr(12 downto 2), + ADDRB => R_REGS.addr_l, + DIA => CMEM_DIA_3, + DIB => CMEM_DIB_3, + DOA => CMEM_DOA_3, + DOB => open + ); + + proc_regs: process (CLK) + begin + + if CLK'event and CLK='1' then + if GRESET = '1' then + R_REGS <= regs_init; + else + R_REGS <= N_REGS; + end if; + end if; + + end process proc_regs; + + proc_next: process (R_REGS, EM_MREQ, FMISS, + CMEM_TAG_DOA, + CMEM_DOA_0, CMEM_DOA_1, CMEM_DOA_2, CMEM_DOA_3, + MEM_BUSY, MEM_ACK_R, MEM_DO) + + variable r : regs_type := regs_init; + variable n : regs_type := regs_init; + + variable iaddr_w : slbit := '0'; + variable iaddr_l : slv11 := (others=>'0'); + variable iaddr_t : slv9 := (others=>'0'); + + variable itagok : slbit := '0'; + variable ivalok : slbit := '0'; + + variable icmem_tag_cea : slbit := '0'; + variable icmem_tag_ceb : slbit := '0'; + variable icmem_tag_wea : slbit := '0'; + variable icmem_tag_web : slbit := '0'; + variable icmem_tag_dib : slv9 := (others=>'0'); + variable icmem_dat_cea : slbit := '0'; + variable icmem_dat_ceb : slbit := '0'; + variable icmem_dat_wea : slv4 := "0000"; + variable icmem_dat_web : slv4 := "0000"; + variable icmem_val_doa : slv4 := "0000"; + variable icmem_dat_doa : slv32 := (others=>'0'); + variable icmem_val_dib : slv4 := "0000"; + variable icmem_dat_dib : slv32 := (others=>'0'); + + variable iackr : slbit := '0'; + variable iackw : slbit := '0'; + variable ichit : slbit := '0'; + variable iosel : slv2 := "11"; + + variable imem_reqr : slbit := '0'; + variable imem_reqw : slbit := '0'; + variable imem_be : slv4 := "0000"; + + begin + + r := R_REGS; + n := R_REGS; + + iaddr_w := EM_MREQ.addr(1); -- get word select + iaddr_l := EM_MREQ.addr(12 downto 2); -- get cache line addr + iaddr_t := EM_MREQ.addr(21 downto 13); -- get cache tag part + + icmem_tag_cea := '0'; + icmem_tag_ceb := '0'; + icmem_tag_wea := '0'; + icmem_tag_web := '0'; + icmem_tag_dib := r.addr_t; -- default, local define whenver used + icmem_dat_cea := '0'; + icmem_dat_ceb := '0'; + icmem_dat_wea := "0000"; + icmem_dat_web := "0000"; + icmem_val_dib := "0000"; + icmem_dat_dib := MEM_DO; -- default, local define whenver used + + icmem_val_doa(0) := CMEM_DOA_0(8); + icmem_dat_doa( 7 downto 0) := CMEM_DOA_0(7 downto 0); + icmem_val_doa(1) := CMEM_DOA_1(8); + icmem_dat_doa(15 downto 8) := CMEM_DOA_1(7 downto 0); + icmem_val_doa(2) := CMEM_DOA_2(8); + icmem_dat_doa(23 downto 16) := CMEM_DOA_2(7 downto 0); + icmem_val_doa(3) := CMEM_DOA_3(8); + icmem_dat_doa(31 downto 24) := CMEM_DOA_3(7 downto 0); + + itagok := '0'; + if CMEM_TAG_DOA = r.addr_t then -- cache tag hit + itagok := '1'; + end if; + ivalok := '0'; + if (icmem_val_doa and r.be) = r.be then + ivalok := '1'; + end if; + + iackr := '0'; + iackw := '0'; + ichit := '0'; + iosel := "11"; -- default to ext. mem data + -- this prevents U's from cache bram's + -- to propagate to dout in beginning... + + imem_reqr := '0'; + imem_reqw := '0'; + imem_be := r.be; + + case r.state is + when s_idle => -- s_idle: wait for req + n.addr_w := iaddr_w; -- capture address: word select + n.addr_l := iaddr_l; -- capture address: cache line addr + n.addr_t := iaddr_t; -- capture address: cache tag part + n.be := "0000"; + icmem_tag_cea := '1'; -- access cache tag port A + icmem_dat_cea := '1'; -- access cache data port A + if iaddr_w = '0' then -- capture byte enables at 4 byte lvl + n.be(1 downto 0) := EM_MREQ.be; + else + n.be(3 downto 2) := EM_MREQ.be; + end if; + n.di := EM_MREQ.din; -- capture data + + if EM_MREQ.req = '1' then -- if access requested + if EM_MREQ.we = '0' then -- if READ requested + n.state := s_read; -- next: read + + else -- if WRITE requested + icmem_tag_wea := '1'; -- write tag + icmem_dat_wea := n.be; -- write cache data + n.state := s_write; -- next: write + end if; + end if; + + when s_read => -- s_read: read cycle + iosel := '0' & r.addr_w; -- output select: cache + imem_be := "1111"; -- mem read: all 4 bytes + if EM_MREQ.cancel = '0' then + if FMISS='0' and itagok='1' and ivalok='1' then -- read tag&val hit + iackr := '1'; -- signal read acknowledge + ichit := '1'; -- signal cache hit + n.state := s_idle; -- next: back to idle + else -- read miss + if MEM_BUSY = '0' then -- if mem not busy + imem_reqr :='1'; -- request mem read + n.state := s_rmiss; -- next: rmiss, wait for mem data + end if; + end if; + else + n.state := s_idle; -- next: back to idle + end if; + + when s_rmiss => -- s_rmiss: read cycle + iosel := '1' & r.addr_w; -- output select: memory + icmem_tag_web := '1'; -- cache update: write tag + icmem_tag_dib := r.addr_t; -- cache update: new tag + icmem_val_dib := "1111"; -- cache update: all valid + icmem_dat_dib := MEM_DO; -- cache update: data from mem + icmem_dat_web := "1111"; -- cache update: write all 4 bytes + if MEM_ACK_R = '1' then -- mem data valid + iackr := '1'; -- signal read acknowledge + icmem_tag_ceb := '1'; -- access cache tag port B + icmem_dat_ceb := '1'; -- access cache data port B + n.state := s_idle; -- next: back to idle + end if; + + when s_write => -- s_write: write cycle + icmem_tag_dib := CMEM_TAG_DOA; -- cache restore: last state + icmem_dat_dib := icmem_dat_doa; -- cache restore: last state + if EM_MREQ.cancel = '0' then -- request ok + if MEM_BUSY = '0' then -- if mem not busy + if itagok = '0' then -- if write tag miss + icmem_dat_ceb := '1'; -- access cache (invalidate) + icmem_dat_web := not r.be; -- write missed bytes + icmem_val_dib := "0000"; -- invalidate missed bytes + end if; + imem_reqw := '1'; -- write back to main memory + iackw := '1'; -- and done + n.state := s_idle; -- next: back to idle + end if; + + else -- request canceled -> restore + icmem_tag_ceb := '1'; -- access cache line + icmem_tag_web := '1'; -- write tag + icmem_dat_ceb := '1'; -- access cache line + icmem_dat_web := "1111"; -- restore cache line + icmem_val_dib := icmem_val_doa; -- cache restore: last state + n.state := s_idle; -- next: back to idle + end if; + + when others => null; + end case; + + N_REGS <= n; + + CMEM_TAG_CEA <= icmem_tag_cea; + CMEM_TAG_CEB <= icmem_tag_ceb; + CMEM_TAG_WEA <= icmem_tag_wea; + CMEM_TAG_WEB <= icmem_tag_web; + CMEM_TAG_DIB <= icmem_tag_dib; + CMEM_DAT_CEA <= icmem_dat_cea; + CMEM_DAT_CEB <= icmem_dat_ceb; + CMEM_DAT_WEA <= icmem_dat_wea; + CMEM_DAT_WEB <= icmem_dat_web; + + CMEM_DIA_0(8) <= '1'; + CMEM_DIA_0(7 downto 0) <= EM_MREQ.din( 7 downto 0); + CMEM_DIA_1(8) <= '1'; + CMEM_DIA_1(7 downto 0) <= EM_MREQ.din(15 downto 8); + CMEM_DIA_2(8) <= '1'; + CMEM_DIA_2(7 downto 0) <= EM_MREQ.din( 7 downto 0); + CMEM_DIA_3(8) <= '1'; + CMEM_DIA_3(7 downto 0) <= EM_MREQ.din(15 downto 8); + + CMEM_DIB_0(8) <= icmem_val_dib(0); + CMEM_DIB_0(7 downto 0) <= icmem_dat_dib(7 downto 0); + CMEM_DIB_1(8) <= icmem_val_dib(1); + CMEM_DIB_1(7 downto 0) <= icmem_dat_dib(15 downto 8); + CMEM_DIB_2(8) <= icmem_val_dib(2); + CMEM_DIB_2(7 downto 0) <= icmem_dat_dib(23 downto 16); + CMEM_DIB_3(8) <= icmem_val_dib(3); + CMEM_DIB_3(7 downto 0) <= icmem_dat_dib(31 downto 24); + + EM_SRES <= em_sres_init; + EM_SRES.ack_r <= iackr; + EM_SRES.ack_w <= iackw; + case iosel is + when "00" => EM_SRES.dout <= icmem_dat_doa(15 downto 0); + when "01" => EM_SRES.dout <= icmem_dat_doa(31 downto 16); + when "10" => EM_SRES.dout <= MEM_DO(15 downto 0); + when "11" => EM_SRES.dout <= MEM_DO(31 downto 16); + when others => null; + end case; + + CHIT <= ichit; + + MEM_REQ <= imem_reqr or imem_reqw; + MEM_WE <= imem_reqw; + MEM_ADDR <= r.addr_t & r.addr_l; + MEM_BE <= imem_be; + MEM_DI <= r.di & r.di; + + end process proc_next; + +end syn; diff --git a/rtl/w11a/pdp11_core.vbom b/rtl/w11a/pdp11_core.vbom new file mode 100644 index 00000000..d9fadc67 --- /dev/null +++ b/rtl/w11a/pdp11_core.vbom @@ -0,0 +1,14 @@ +# libs +../vlib/slvtypes.vhd +../ibus/iblib.vhd +pdp11.vbom +# components +pdp11_vmbox.vbom +pdp11_dpath.vbom +pdp11_decode.vbom +pdp11_sequencer.vbom +pdp11_irq.vbom +pdp11_sys70.vbom +../ibus/ib_sres_or_4.vbom +# design +pdp11_core.vhd diff --git a/rtl/w11a/pdp11_core.vhd b/rtl/w11a/pdp11_core.vhd new file mode 100644 index 00000000..db6ca8bd --- /dev/null +++ b/rtl/w11a/pdp11_core.vhd @@ -0,0 +1,236 @@ +-- $Id: pdp11_core.vhd 314 2010-07-09 17:38:41Z mueller $ +-- +-- Copyright 2006-2010 by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, 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 complete details. +-- +------------------------------------------------------------------------------ +-- Module Name: pdp11_core - syn +-- Description: pdp11: full processor core +-- +-- Dependencies: pdp11_vmbox +-- pdp11_dpath +-- pdp11_decode +-- pdp11_sequencer +-- pdp11_irq +-- pdp11_sys70 +-- ibus/ib_sres_or_4 +-- +-- Test bench: tb/tb_pdp11_core +-- tb/tb_rritba_pdp11core +-- tb/tb_rripdp_pdp11core +-- tb/tb_rriext_pdp11core +-- +-- Target Devices: generic +-- Tool versions: xst 8.1, 8.2, 9.1, 9.2; ghdl 0.18-0.25 +-- Revision History: +-- Date Rev Version Comment +-- 2010-06-13 305 1.3 add CP_ADDR in port; drop R_CPDIN, R_CPOUT; _vmbox +-- CP_ADDR now from in port; dpath CP_DIN now from in +-- port; out port CP_DOUT now from _dpath +-- 2009-05-30 220 1.2.5 final removal of snoopers (were already commented) +-- 2008-08-22 161 1.2.4 rename pdp11_ibres_ -> ib_sres_ +-- 2008-04-25 138 1.2.3 BRESET: add for _vmbox, use for _irq +-- 2008-04-19 137 1.2.2 add DM_STAT_(DP|VM|CO) port; added pdp11_sys70 +-- 2008-03-02 121 1.2.1 remove snoopers +-- 2008-02-17 117 1.2 add em_(mreq|sres) interface for memory +-- 2008-01-20 112 1.1.3 add BRESET port (intbus reset), rename P->BRESET +-- 2008-01-06 111 1.1.2 rename signal EI_ACK->EI_ACKM (master ack) +-- 2008-01-01 109 1.1.1 _vmbox w/ IB_SRES_(CPU|EXT) +-- 2007-12-30 107 1.1 use IB_MREQ/IB_SRES interface now; remove DMA port +-- 2007-07-15 66 1.0.3 rename pdp11_top -> pdp11_core +-- 2007-07-02 63 1.0.2 reordered ports on pdp11_top (by function, not i/o) +-- 2007-06-14 56 1.0.1 Use slvtypes.all +-- 2007-05-12 26 1.0 Initial version +------------------------------------------------------------------------------ + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; + +use work.slvtypes.all; +use work.iblib.all; +use work.pdp11.all; + +-- ---------------------------------------------------------------------------- + +entity pdp11_core is -- full processor core + port ( + CLK : in slbit; -- clock + RESET : in slbit; -- reset + CP_CNTL : in cp_cntl_type; -- console control port + CP_ADDR : in cp_addr_type; -- console address port + CP_DIN : in slv16; -- console data in + CP_STAT : out cp_stat_type; -- console status port + CP_DOUT : out slv16; -- console data out + EI_PRI : in slv3; -- external interrupt priority + EI_VECT : in slv9_2; -- external interrupt vector + EI_ACKM : out slbit; -- external interrupt acknowledge + EM_MREQ : out em_mreq_type; -- external memory: request + EM_SRES : in em_sres_type; -- external memory: response + BRESET : out slbit; -- ibus reset + IB_MREQ_M : out ib_mreq_type; -- inbus master request (master) + IB_SRES_M : in ib_sres_type; -- inbus slave response (master) + DM_STAT_DP : out dm_stat_dp_type; -- debug and monitor status - dpath + DM_STAT_VM : out dm_stat_vm_type; -- debug and monitor status - vmbox + DM_STAT_CO : out dm_stat_co_type -- debug and monitor status - core + ); +end pdp11_core; + +architecture syn of pdp11_core is + + signal GRESET : slbit := '0'; + signal CRESET : slbit := '0'; + signal BRESET_L : slbit := '0'; + signal SEQ_CRESET : slbit := '0'; + signal SEQ_BRESET : slbit := '0'; + signal VM_CNTL : vm_cntl_type := vm_cntl_init; + signal VM_STAT : vm_stat_type := vm_stat_init; + signal MMU_MONI : mmu_moni_type := mmu_moni_init; + signal DP_CNTL : dpath_cntl_type := dpath_cntl_init; + signal DP_STAT : dpath_stat_type := dpath_stat_init; + signal DP_PSW : psw_type := psw_init; + signal DP_PC : slv16 := (others=>'0'); + signal DP_IREG : slv16 := (others=>'0'); + signal VM_DIN : slv16 := (others=>'0'); + signal VM_ADDR : slv16 := (others=>'0'); + signal VM_DOUT : slv16 := (others=>'0'); + signal ID_STAT : decode_stat_type := decode_stat_init; + signal INT_PRI : slv3 := (others=>'0'); + signal INT_VECT : slv9_2 := (others=>'0'); + signal CP_STAT_L : cp_stat_type := cp_stat_init; + signal INT_ACK : slbit := '0'; + + signal IB_SRES_DP : ib_sres_type := ib_sres_init; + signal IB_SRES_SEQ : ib_sres_type := ib_sres_init; + signal IB_SRES_IRQ : ib_sres_type := ib_sres_init; + signal IB_SRES_SYS : ib_sres_type := ib_sres_init; + + signal IB_MREQ : ib_mreq_type := ib_mreq_init; -- ibus request (local) + signal IB_SRES : ib_sres_type := ib_sres_init; -- ibus response (local) + +begin + + GRESET <= RESET; + CRESET <= RESET or SEQ_CRESET; + BRESET_L <= RESET or SEQ_CRESET or SEQ_BRESET; + + VMBOX : pdp11_vmbox + port map ( + CLK => CLK, + GRESET => GRESET, + CRESET => CRESET, + BRESET => BRESET_L, + CP_ADDR => CP_ADDR, + VM_CNTL => VM_CNTL, + VM_ADDR => VM_ADDR, + VM_DIN => VM_DIN, + VM_STAT => VM_STAT, + VM_DOUT => VM_DOUT, + EM_MREQ => EM_MREQ, + EM_SRES => EM_SRES, + MMU_MONI => MMU_MONI, + IB_MREQ_M => IB_MREQ, + IB_SRES_CPU => IB_SRES, + IB_SRES_EXT => IB_SRES_M, + DM_STAT_VM => DM_STAT_VM + ); + + DPATH : pdp11_dpath + port map ( + CLK => CLK, + CRESET => CRESET, + CNTL => DP_CNTL, + STAT => DP_STAT, + CP_DIN => CP_DIN, + CP_DOUT => CP_DOUT, + PSWOUT => DP_PSW, + PCOUT => DP_PC, + IREG => DP_IREG, + VM_ADDR => VM_ADDR, + VM_DOUT => VM_DOUT, + VM_DIN => VM_DIN, + IB_MREQ => IB_MREQ, + IB_SRES => IB_SRES_DP, + DM_STAT_DP => DM_STAT_DP + ); + + IDEC : pdp11_decode + port map ( + IREG => DP_IREG, + STAT => ID_STAT + ); + + SEQ : pdp11_sequencer + port map ( + CLK => CLK, + GRESET => GRESET, + PSW => DP_PSW, + PC => DP_PC, + IREG => DP_IREG, + ID_STAT => ID_STAT, + DP_STAT => DP_STAT, + CP_CNTL => CP_CNTL, + VM_STAT => VM_STAT, + INT_PRI => INT_PRI, + INT_VECT => INT_VECT, + CRESET => SEQ_CRESET, + BRESET => SEQ_BRESET, + MMU_MONI => MMU_MONI, + DP_CNTL => DP_CNTL, + VM_CNTL => VM_CNTL, + CP_STAT => CP_STAT_L, + INT_ACK => INT_ACK, + IB_MREQ => IB_MREQ, + IB_SRES => IB_SRES_SEQ + ); + + IRQ : pdp11_irq + port map ( + CLK => CLK, + BRESET => BRESET_L, + INT_ACK => INT_ACK, + EI_PRI => EI_PRI, + EI_VECT => EI_VECT, + EI_ACKM => EI_ACKM, + PRI => INT_PRI, + VECT => INT_VECT, + IB_MREQ => IB_MREQ, + IB_SRES => IB_SRES_IRQ + ); + + SYS70 : pdp11_sys70 + port map ( + CLK => CLK, + CRESET => CRESET, + IB_MREQ => IB_MREQ, + IB_SRES => IB_SRES_SYS + ); + + IB_SRES_OR : ib_sres_or_4 + port map ( + IB_SRES_1 => IB_SRES_DP, + IB_SRES_2 => IB_SRES_SEQ, + IB_SRES_3 => IB_SRES_IRQ, + IB_SRES_4 => IB_SRES_SYS, + IB_SRES_OR => IB_SRES + ); + + IB_MREQ_M <= IB_MREQ; + + CP_STAT <= CP_STAT_L; + + BRESET <= BRESET_L; + + DM_STAT_CO.cpugo <= CP_STAT_L.cpugo; + DM_STAT_CO.cpuhalt <= CP_STAT_L.cpuhalt; + +end syn; + diff --git a/rtl/w11a/pdp11_core_rri.vbom b/rtl/w11a/pdp11_core_rri.vbom new file mode 100644 index 00000000..319490be --- /dev/null +++ b/rtl/w11a/pdp11_core_rri.vbom @@ -0,0 +1,6 @@ +# libs +../vlib/slvtypes.vhd +../vlib/rri/rrilib.vhd +pdp11.vbom +# design +pdp11_core_rri.vhd diff --git a/rtl/w11a/pdp11_core_rri.vhd b/rtl/w11a/pdp11_core_rri.vhd new file mode 100644 index 00000000..3bc700e9 --- /dev/null +++ b/rtl/w11a/pdp11_core_rri.vhd @@ -0,0 +1,398 @@ +-- $Id: pdp11_core_rri.vhd 314 2010-07-09 17:38:41Z mueller $ +-- +-- Copyright 2007-2010 by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, 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 complete details. +-- +------------------------------------------------------------------------------ +-- Module Name: pdp11_core_rri - syn +-- Description: pdp11: core to rri register port interface +-- +-- Dependencies: - +-- Test bench: tb/tb_rritba_pdp11core +-- tb/tb_rripdp_pdp11core +-- tb/tb_rriext_pdp11core +-- +-- Target Devices: generic +-- Tool versions: xst 8.1, 8.2, 9.1, 9.2, 11.4; ghdl 0.18-0.26 +-- Revision History: - +-- Date Rev Version Comment +-- 2010-06-20 308 1.2.2 use c_ibrb_ibf_ def's +-- 2010-06-18 306 1.2.1 rename RB_ADDR->RB_ADDR_CORE, add RB_ADDR_IBUS; +-- add ibrb register and ibr window logic +-- 2010-06-13 305 1.2 add CP_ADDR in port; mostly rewritten for new +-- rri <-> cp mapping +-- 2010-06-03 299 1.1.2 correct rbus init logic (use we, din, RB_ADDR) +-- 2010-05-02 287 1.1.1 rename RP_STAT->RB_STAT; remove unneeded unsigned() +-- 2010-05-01 285 1.1 port to rri V2 interface, add RB_ADDR generic; +-- rename c_rp_addr_* -> c_rb_addr_* +-- 2008-05-03 143 1.0.8 rename _cpursta->_cpurust +-- 2008-04-27 140 1.0.7 use cpursta interface, remove cpufail +-- 2008-03-02 121 1.0.6 set RP_ERR when cmderr or cmdmerr status seen +-- 2008-02-24 119 1.0.5 support lah,rps,wps cp commands +-- 2008-01-20 113 1.0.4 use single LAM; change to RRI_LAM interface +-- 2007-10-12 88 1.0.3 avoid ieee.std_logic_unsigned, use cast to unsigned +-- 2007-08-16 74 1.0.2 add AP_LAM interface to pdp11_core_rri +-- 2007-08-12 73 1.0.1 use def's; add stat command; wait for step complete +-- 2007-07-08 65 1.0 Initial version +------------------------------------------------------------------------------ +-- +-- rbus registers: +-- +-- Address Bits Name r/w/i Function +-- +-- bbb00000 conf r/w/- cpu configuration (e.g. cpu type) +-- (currently unused, all bits MBZ) +-- bbb00001 cntl -/f/- cpu control +-- 3:0 func function code +-- 0000: noop +-- 0001: start +-- 0010: stop +-- 0011: continue +-- 0100: step +-- 1111: reset (soft) +-- bbb00010 stat r/-/- cpu status +-- 7:04 cpurust r/-/- cp_stat: cpurust +-- 3 cpuhalt r/-/- cp_stat: cpuhalt +-- 2 cpugo r/-/- cp_stat: cpugo +-- 1 cmdmerr r/-/- cp_stat: cmdmerr +-- 0 cmderr r/-/- cp_stat: cmderr +-- bbb00011 psw r/w/- processor status word access +-- bbb00100 al r/w/- address register, low +-- bbb00101 ah r/w/- address register, high +-- bbb00110 mem r/w/- memory access +-- bbb00111 memi r/w/- memory access, inc address +-- bbb01rrr gpr[] r/w/- general purpose regs +-- bbb10000 ibrb r/w/- ibr base address +-- 12:06 base r/w/- ibr window base address +-- 1:00 we r/w/- byte enables (00 equivalent to 11) +-- www----- ibr[] r/w/- ibr window (32 words) +-- + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; + +use work.slvtypes.all; +use work.rrilib.all; +use work.pdp11.all; + +-- ---------------------------------------------------------------------------- + +entity pdp11_core_rri is -- core to rri reg port interface + generic ( + RB_ADDR_CORE : slv8 := conv_std_logic_vector(2#00000000#,8); + RB_ADDR_IBUS : slv8 := conv_std_logic_vector(2#10000000#,8)); + port ( + CLK : in slbit; -- clock + RESET : in slbit; -- reset + RB_MREQ : in rb_mreq_type; -- rbus: request + RB_SRES : out rb_sres_type; -- rbus: response + RB_STAT : out slv3; -- rbus: status flags + RRI_LAM : out slbit; -- remote attention + CPU_RESET : out slbit; -- cpu master reset + CP_CNTL : out cp_cntl_type; -- console control port + CP_ADDR : out cp_addr_type; -- console address port + CP_DIN : out slv16; -- console data in + CP_STAT : in cp_stat_type; -- console status port + CP_DOUT : in slv16 -- console data out + ); +end pdp11_core_rri; + + +architecture syn of pdp11_core_rri is + + type state_type is ( + s_idle, -- s_idle: wait for rp access + s_cpwait, -- s_cpwait: wait for cp port ack + s_cpstep -- s_cpstep: wait for cpustep done + ); + + type regs_type is record + state : state_type; -- state + cpreq : slbit; -- cp request flag + cpfunc : slv5; -- cp function + cpugo_1 : slbit; -- prev cycle cpugo + addr : slv22_1; -- address register + ena_22bit : slbit; -- 22bit enable + ena_ubmap : slbit; -- ubmap enable + ibrbase : slv(c_ibrb_ibf_base); -- ibr base address + ibrbe : slv2; -- ibr byte enables + ibrberet : slv2; -- ibr byte enables (for readback) + doinc : slbit; -- at cmdack: do addr reg inc + waitstep : slbit; -- at cmdack: wait for cpu step complete + end record regs_type; + + constant regs_init : regs_type := ( + s_idle, -- state + '0', -- cpreq + (others=>'0'), -- cpfunc + '0', -- cpugo_1 + (others=>'0'), -- addr + '0','0', -- ena_22bit, ena_ubmap + (others=>'0'),"00","00", -- ibrbase, ibrbe, ibrberet + '0','0' -- doinc, waitstep + ); + + signal R_REGS : regs_type := regs_init; -- state registers + signal N_REGS : regs_type := regs_init; -- next value state regs + + begin + + proc_regs: process (CLK) + begin + + if CLK'event and CLK='1' then + if RESET = '1' then + R_REGS <= regs_init; + else + R_REGS <= N_REGS; + end if; + end if; + + end process proc_regs; + + proc_next: process (R_REGS, RB_MREQ, CP_STAT, CP_DOUT) + + variable r : regs_type := regs_init; + variable n : regs_type := regs_init; + + variable irb_selc : slbit := '0'; + variable irb_seli : slbit := '0'; + variable irb_ack : slbit := '0'; + variable irb_busy : slbit := '0'; + variable irb_err : slbit := '0'; + variable irb_dout : slv16 := (others=>'0'); + variable irb_lam : slbit := '0'; + + variable icpreq : slbit := '0'; + variable icpureset : slbit := '0'; + variable icpaddr : cp_addr_type := cp_addr_init; + + begin + + r := R_REGS; + n := R_REGS; + + irb_selc := '0'; + irb_seli := '0'; + irb_ack := '0'; + irb_busy := '0'; + irb_err := '0'; + irb_dout := (others=>'0'); + irb_lam := '0'; + + icpreq := '0'; + icpureset := '0'; + + if RB_MREQ.req='1' then + if RB_MREQ.addr(7 downto 5)=RB_ADDR_CORE(7 downto 5) then + irb_selc := '1'; + irb_ack := '1'; -- ack all, unless reject or busy + end if; + if RB_MREQ.addr(7 downto 5)=RB_ADDR_IBUS(7 downto 5) then + irb_seli := '1'; + irb_ack := '1'; -- ack all, unless reject or busy + end if; + end if; + + -- look for init's against the rbus base address, generate subsystem resets + if RB_MREQ.init='1' and RB_MREQ.we='1' and RB_MREQ.addr=RB_ADDR_CORE then + icpureset := RB_MREQ.din(0); + end if; + + case r.state is + + when s_idle => -- s_idle: wait for rbus access ------ + + n.doinc := '0'; + n.waitstep := '0'; + + if irb_seli = '1' then + n.cpfunc := c_cpfunc_rmem; + n.cpfunc(0) := RB_MREQ.we; + icpreq := '1'; + + elsif irb_selc = '1' then + + case RB_MREQ.addr(4 downto 0) is + + when c_rbaddr_conf => -- conf ------------------------- + null; -- currently no action + + when c_rbaddr_cntl => -- cntl ------------------------- + n.cpfunc := RB_MREQ.din(n.cpfunc'range); + if RB_MREQ.we = '1' then + icpreq := '1'; + if RB_MREQ.din(3 downto 0) = c_cpfunc_step(3 downto 0) then + n.waitstep := '1'; + end if; + end if; + + when c_rbaddr_stat => -- stat ------------------------- + irb_dout(c_stat_rbf_cmderr) := CP_STAT.cmderr; + irb_dout(c_stat_rbf_cmdmerr) := CP_STAT.cmdmerr; + irb_dout(c_stat_rbf_cpugo) := CP_STAT.cpugo; + irb_dout(c_stat_rbf_cpuhalt) := CP_STAT.cpuhalt; + irb_dout(c_stat_rbf_cpurust) := CP_STAT.cpurust; + + when c_rbaddr_psw => -- psw -------------------------- + n.cpfunc := c_cpfunc_rpsw; + n.cpfunc(0) := RB_MREQ.we; + icpreq := '1'; + + when c_rbaddr_al => -- al --------------------------- + irb_dout(c_al_rbf_addr) := r.addr(c_al_rbf_addr); + if RB_MREQ.we = '1' then + n.addr := (others=>'0'); -- write to al clears ah !! + n.ena_22bit := '0'; + n.ena_ubmap := '0'; + n.addr(c_al_rbf_addr) := RB_MREQ.din(c_al_rbf_addr); + end if; + + when c_rbaddr_ah => -- ah --------------------------- + irb_dout(c_ah_rbf_ena_ubmap) := r.ena_ubmap; + irb_dout(c_ah_rbf_ena_22bit) := r.ena_22bit; + irb_dout(c_ah_rbf_addr) := r.addr(21 downto 16); + if RB_MREQ.we = '1' then + n.addr(21 downto 16) := RB_MREQ.din(c_ah_rbf_addr); + n.ena_22bit := RB_MREQ.din(c_ah_rbf_ena_22bit); + n.ena_ubmap := RB_MREQ.din(c_ah_rbf_ena_ubmap); + end if; + + when c_rbaddr_mem => -- mem ----------------- + n.cpfunc := c_cpfunc_rmem; + n.cpfunc(0) := RB_MREQ.we; + icpreq := '1'; + + when c_rbaddr_memi => -- memi ---------------- + n.cpfunc := c_cpfunc_rmem; + n.cpfunc(0) := RB_MREQ.we; + n.doinc := '1'; + icpreq := '1'; + + when c_rbaddr_r0 | c_rbaddr_r1 | + c_rbaddr_r2 | c_rbaddr_r3 | + c_rbaddr_r4 | c_rbaddr_r5 | + c_rbaddr_sp | c_rbaddr_pc => -- r* ------------------ + n.cpfunc := c_cpfunc_rreg; + n.cpfunc(0) := RB_MREQ.we; + icpreq := '1'; + + when c_rbaddr_ibrb => -- ibrb ---------------- + irb_dout(c_ibrb_ibf_base) := r.ibrbase; + irb_dout(c_ibrb_ibf_be) := r.ibrberet; + if RB_MREQ.we = '1' then + n.ibrbase := RB_MREQ.din(c_ibrb_ibf_base); + n.ibrberet := RB_MREQ.din(c_ibrb_ibf_be); + if RB_MREQ.din(c_ibrb_ibf_be) = "00" then -- both be=0 ? + n.ibrbe := "11"; + else -- otherwise take 2 LSB's + n.ibrbe := RB_MREQ.din(c_ibrb_ibf_be); + end if; + end if; + + when others => + irb_ack := '0'; + + end case; + + end if; + + if icpreq = '1' then + irb_busy := '1'; + n.cpreq := '1'; + n.state := s_cpwait; + end if; + + when s_cpwait => -- s_cpwait: wait for cp port ack ---- + n.cpreq := '0'; -- cpreq only for 1 cycle + + if (irb_selc or irb_seli) = '0' then -- rbus cycle abort + n.state := s_idle; -- quit + else + irb_dout := CP_DOUT; + irb_err := CP_STAT.cmderr or CP_STAT.cmdmerr; + if CP_STAT.cmdack = '1' then -- normal cycle end + if r.doinc = '1' then + n.addr := unsigned(r.addr) + 1; + end if; + if r.waitstep = '1' then + irb_busy := '1'; + n.state := s_cpstep; + else + n.state := s_idle; + end if; + else + irb_busy := '1'; + end if; + end if; + + when s_cpstep => -- s_cpstep: wait for cpustep done --- + if irb_selc = '0' then -- rbus cycle abort + n.state := s_idle; -- quit + else + if CP_STAT.cpustep = '0' then -- cpustep done + n.state := s_idle; + else + irb_busy := '1'; + end if; + end if; + + when others => null; + end case; + + icpaddr := cp_addr_init; + icpaddr.addr := r.addr; + icpaddr.racc := '0'; + icpaddr.be := "11"; + icpaddr.ena_22bit := r.ena_22bit; + icpaddr.ena_ubmap := r.ena_ubmap; + + if irb_seli = '1' then + icpaddr.addr(15 downto 13) := "111"; + icpaddr.addr(c_ibrb_ibf_base) := r.ibrbase; + icpaddr.addr(5 downto 1) := RB_MREQ.addr(4 downto 0); + icpaddr.racc := '1'; + icpaddr.be := r.ibrbe; + icpaddr.ena_22bit := '0'; + icpaddr.ena_ubmap := '0'; + end if; + + n.cpugo_1 := CP_STAT.cpugo; -- delay cpugo + if CP_STAT.cpugo='0' and r.cpugo_1='1' then -- cpugo 1 -> 0 transition ? + irb_lam := '1'; + end if; + + N_REGS <= n; + + RB_SRES.ack <= irb_ack; + RB_SRES.err <= irb_err; + RB_SRES.busy <= irb_busy; + RB_SRES.dout <= irb_dout; + + RB_STAT(0) <= CP_STAT.cpugo; + RB_STAT(1) <= CP_STAT.cpuhalt or CP_STAT.cpurust(CP_STAT.cpurust'left); + RB_STAT(2) <= CP_STAT.cmderr or CP_STAT.cmdmerr; + + RRI_LAM <= irb_lam; + + CPU_RESET <= icpureset; + + CP_CNTL.req <= r.cpreq; + CP_CNTL.func <= r.cpfunc; + CP_CNTL.rnum <= RB_MREQ.addr(2 downto 0); + + CP_ADDR <= icpaddr; + CP_DIN <= RB_MREQ.din; + + end process proc_next; + +end syn; diff --git a/rtl/w11a/pdp11_dbox.vbom b/rtl/w11a/pdp11_dbox.vbom new file mode 100644 index 00000000..d76d68db --- /dev/null +++ b/rtl/w11a/pdp11_dbox.vbom @@ -0,0 +1,5 @@ +# libs +../vlib/slvtypes.vhd +pdp11.vbom +# design +pdp11_dbox.vhd diff --git a/rtl/w11a/pdp11_dbox.vhd b/rtl/w11a/pdp11_dbox.vhd new file mode 100644 index 00000000..a8ae666e --- /dev/null +++ b/rtl/w11a/pdp11_dbox.vhd @@ -0,0 +1,243 @@ +-- $Id: pdp11_dbox.vhd 314 2010-07-09 17:38:41Z mueller $ +-- +-- Copyright 2006-2007 by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, 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 complete details. +-- +------------------------------------------------------------------------------ +-- Module Name: pdp11_dbox - syn +-- Description: pdp11: arithmetic unit for data (dbox) +-- +-- Dependencies: - +-- Test bench: tb/tb_pdp11_core (implicit) +-- Target Devices: generic +-- Tool versions: xst 8.1, 8.2, 9.1, 9.2; ghdl 0.18-0.25 +-- Revision History: +-- Date Rev Version Comment +-- 2007-06-14 56 1.0.1 Use slvtypes.all +-- 2007-05-12 26 1.0 Initial version +------------------------------------------------------------------------------ + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; +use ieee.std_logic_unsigned.all; + +use work.slvtypes.all; +use work.pdp11.all; + +-- ---------------------------------------------------------------------------- + +-- arithmetic unit for data, usage: +-- ADD: SRC + DST + 0 (dst+src) +-- SUB: ~SRC + DST + 1 (dst-src) +-- ADC: 0 + DST + CI (dst+ci) +-- SBC: ~0 + DST + ~CI (dst-ci) +-- CMP: SRC + ~DST + 1 (src-dst) +-- COM: 0 + ~DST + 0 (~dst) +-- NEG: 0 + ~DST + 1 (-dst) +-- INC: 0 + DST + 1 (dst+1) +-- DEC: ~0 + DST + 0 (dst-1) +-- CLR: 0 + 0 + 0 (0) +-- SOB: SRC + ~0 + 0 (src-1) + +entity pdp11_dbox is -- arithmetic unit for data (dbox) + port ( + DSRC : in slv16; -- 'src' data in + DDST : in slv16; -- 'dst' data in + CI : in slbit; -- carry flag in + SRCMOD : in slv2; -- src modifier mode + DSTMOD : in slv2; -- dst modifier mode + CIMOD : in slv2; -- ci modifier mode + CC1OP : in slbit; -- use cc modes (1 op instruction) + CCMODE : in slv3; -- cc mode + BYTOP : in slbit; -- byte operation + DOUT : out slv16; -- data output + CCOUT : out slv4 -- condition codes out + ); +end pdp11_dbox; + +architecture syn of pdp11_dbox is + +-- -------------------------------------- + +begin + + process (DSRC, DDST, CI, CIMOD, CC1OP, CCMODE, SRCMOD, DSTMOD, BYTOP) + + variable msrc : slv16 := (others=>'0'); -- effective src data + variable mdst : slv16 := (others=>'0'); -- effective dst data + variable mci : slbit := '0'; -- effective ci + variable sum : slv16 := (others=>'0'); -- sum + variable co8 : slbit := '0'; -- co 8 bit + variable co16 : slbit := '0'; -- co 16 bit + + variable nno : slbit := '0'; -- local no + variable nzo : slbit := '0'; -- local zo + variable nvo : slbit := '0'; -- local vo + variable nco : slbit := '0'; -- local co + + variable src_msb : slbit := '0'; -- msb from src (bit 15 or 7) + variable dst_msb : slbit := '0'; -- msb from dst (bit 15 or 7) + variable sum_msb : slbit := '0'; -- msb from sum (bit 15 or 7) + + alias NO : slbit is CCOUT(3); + alias ZO : slbit is CCOUT(2); + alias VO : slbit is CCOUT(1); + alias CO : slbit is CCOUT(0); + + -- procedure do_add8_ci_co: 8 bit adder with carry in and carry out + -- implemented following the recommended pattern for XST ISE V8.1 + + procedure do_add8_ci_co ( + variable a : in slv8; -- input a + variable b : in slv8; -- input b + variable ci : in slbit; -- carry in + variable sum : out slv8; -- sum out + variable co : out slbit -- carry out + ) is + + variable tmp: slv9; + + begin + + tmp := conv_std_logic_vector((conv_integer(a) + conv_integer(b) + + conv_integer(ci)),9); + sum := tmp(7 downto 0); + co := tmp(8); + + end procedure do_add8_ci_co; + + begin + + case SRCMOD is + when c_dbox_mod_pass => msrc := DSRC; + when c_dbox_mod_inv => msrc := not DSRC; + when c_dbox_mod_zero => msrc := (others=>'0'); + when c_dbox_mod_one => msrc := (others=>'1'); + when others => null; + end case; + + case DSTMOD is + when c_dbox_mod_pass => mdst := DDST; + when c_dbox_mod_inv => mdst := not DDST; + when c_dbox_mod_zero => mdst := (others=>'0'); + when c_dbox_mod_one => mdst := (others=>'1'); + when others => null; + end case; + + case CIMOD is + when c_dbox_mod_pass => mci := CI; + when c_dbox_mod_inv => mci := not CI; + when c_dbox_mod_zero => mci := '0'; + when c_dbox_mod_one => mci := '1'; + when others => null; + end case; + + do_add8_ci_co(msrc(7 downto 0), mdst(7 downto 0), mci, + sum(7 downto 0), co8); + do_add8_ci_co(msrc(15 downto 8), mdst(15 downto 8), co8, + sum(15 downto 8), co16); + + DOUT <= sum; + +-- V ('overflow) bit set if +-- ADD : both operants of same sign but has result opposite sign +-- SUB : both operants of opposide sign and sign source equals sign result +-- CMP : both operants of opposide sign and sign dest. equals sign result + + nno := '0'; + nzo := '0'; + nvo := '0'; + nco := '0'; + + if BYTOP = '1' then + nno := sum(7); + if unsigned(sum(7 downto 0)) = 0 then + nzo := '1'; + else + nzo := '0'; + end if; + nco := co8; + + src_msb := DSRC(7); + dst_msb := DDST(7); + sum_msb := sum(7); + + else + nno := sum(15); + if unsigned(sum) = 0 then + nzo := '1'; + else + nzo := '0'; + end if; + nco := co16; + + src_msb := DSRC(15); + dst_msb := DDST(15); + sum_msb := sum(15); + end if; + + -- the logic for 2 operand V+C is ugly. It is reverse engineered from + -- the MOD's the operation type. + + if CC1OP = '0' then -- 2 operand cases + if unsigned(CIMOD) = unsigned(c_dbox_mod_zero) then -- case ADD + nvo := not(src_msb xor dst_msb) and (src_msb xor sum_msb); + else + if unsigned(SRCMOD) = unsigned(c_dbox_mod_inv) then -- case SUB + nvo := (src_msb xor dst_msb) and not (src_msb xor sum_msb); + else -- case CMP + nvo := (src_msb xor dst_msb) and not (dst_msb xor sum_msb); + end if; + nco := not nco; -- invert C for SUB and CMP + end if; + + else -- 1 operand cases + case CCMODE is + when c_dbox_ccmode_clr|c_dbox_ccmode_tst => + nvo := '0'; -- force v=0 for tst and clr + nco := '0'; -- force c=0 for tst and clr + + when c_dbox_ccmode_com => + nvo := '0'; -- force v=0 for com + nco := '1'; -- force c=1 for com + + when c_dbox_ccmode_inc => + nvo := sum_msb and not dst_msb; + nco := CI; -- C not affected for INC + + when c_dbox_ccmode_dec => + nvo := not sum_msb and dst_msb; + nco := CI; -- C not affected for DEC + + when c_dbox_ccmode_neg => + nvo := sum_msb and dst_msb; + nco := not nzo; + + when c_dbox_ccmode_adc => + nvo := sum_msb and not dst_msb; + + when c_dbox_ccmode_sbc => + nvo := not sum_msb and dst_msb; + nco := not nco; + + when others => null; + end case; + end if; + + NO <= nno; + ZO <= nzo; + VO <= nvo; + CO <= nco; + + end process; + +end syn; diff --git a/rtl/w11a/pdp11_decode.vbom b/rtl/w11a/pdp11_decode.vbom new file mode 100644 index 00000000..93d14a3e --- /dev/null +++ b/rtl/w11a/pdp11_decode.vbom @@ -0,0 +1,5 @@ +# libs +../vlib/slvtypes.vhd +pdp11.vbom +# design +pdp11_decode.vhd diff --git a/rtl/w11a/pdp11_decode.vhd b/rtl/w11a/pdp11_decode.vhd new file mode 100644 index 00000000..5cb1f1b4 --- /dev/null +++ b/rtl/w11a/pdp11_decode.vhd @@ -0,0 +1,562 @@ +-- $Id: pdp11_decode.vhd 314 2010-07-09 17:38:41Z mueller $ +-- +-- Copyright 2006-2008 by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, 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 complete details. +-- +------------------------------------------------------------------------------ +-- Module Name: pdp11_decode - syn +-- Description: pdp11: instruction decoder +-- +-- Dependencies: - +-- Test bench: tb/tb_pdp11_core (implicit) +-- Target Devices: generic +-- Tool versions: xst 8.1, 8.2, 9.1, 9.2; ghdl 0.18-0.25 +-- Revision History: +-- Date Rev Version Comment +-- 2008-11-30 174 1.0.4 BUGFIX: add updt_dstadsrc; set for MFP(I/D) +-- 2008-05-03 143 1.0.3 get fork_srcr,fork_dstr,fork_dsta assign out of if +-- 2008-04-27 139 1.0.2 BUGFIX: mtp now via do_fork_op; is_dsta logic mods +-- 2007-06-14 56 1.0.1 Use slvtypes.all +-- 2007-05-12 26 1.0 Initial version +------------------------------------------------------------------------------ + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; + +use work.slvtypes.all; +use work.pdp11.all; + +-- ---------------------------------------------------------------------------- + +entity pdp11_decode is -- instruction decoder + port ( + IREG : in slv16; -- input instruction word + STAT : out decode_stat_type -- status output + ); +end pdp11_decode; + +architecture syn of pdp11_decode is + +begin + + proc_idecode: process (IREG) + + alias OPCODE : slv4 is IREG(15 downto 12); -- basic opcode (upper 4 bits) + alias OPPRIM : slv3 is IREG(14 downto 12); -- basic opcode without B bit + alias OPBYTE : slbit is IREG(15); -- byte flag of basic opcode + alias OPEXT1 : slv3 is IREG(11 downto 9); -- extended opcode, part 1 + alias OPEXT2 : slv3 is IREG(8 downto 6); -- extended opcode, part 2 + alias OPEXT3 : slv3 is IREG(5 downto 3); -- extended opcode, part 3 + alias OPEXT4 : slv3 is IREG(2 downto 0); -- extended opcode, part 4 + + alias SRCMODF : slv3 is IREG(11 downto 9); -- src register full mode + alias DSTMODF : slv3 is IREG(5 downto 3); -- dst register full mode + + alias SRCMOD : slv2 is IREG(11 downto 10); -- src register mode high + alias SRCDEF : slbit is IREG(9); -- src register mode defered + alias SRCREG : slv3 is IREG(8 downto 6); -- src register number + alias DSTMOD : slv2 is IREG(5 downto 4); -- dst register mode high + alias DSTDEF : slbit is IREG(3); -- dst register mode defered + alias DSTREG : slv3 is IREG(2 downto 0); -- dst register number + + variable nstat : decode_stat_type; + + variable is_srcr : slbit := '0'; -- source is read + variable is_dstr : slbit := '0'; -- destination is read + variable is_dstm : slbit := '0'; -- destination is modified + variable is_dstw : slbit := '0'; -- destination is written + + variable is_srcmode0 : slbit := '0'; -- source is register mode + variable is_dstmode0notpc : slbit := '0'; -- dest. is register mode, not PC + + begin + + is_srcr := '0'; + is_dstr := '0'; + is_dstm := '0'; + is_dstw := '0'; + + is_srcmode0 := '0'; + is_dstmode0notpc := '0'; + + nstat.is_dstmode0 := '0'; + nstat.is_srcpc := '0'; + nstat.is_srcpcmode1 := '0'; + nstat.is_dstpc := '0'; + nstat.is_dstw_reg := '0'; + nstat.is_dstw_pc := '0'; + nstat.is_rmwop := '0'; + nstat.is_bytop := '0'; + nstat.is_res := '1'; + nstat.op_rtt := '0'; + nstat.op_mov := '0'; + nstat.trap_vec := "000"; + nstat.force_srcsp := '0'; + nstat.updt_dstadsrc := '0'; + + nstat.dbox_srcmod := c_dbox_mod_pass; + nstat.dbox_dstmod := c_dbox_mod_pass; + nstat.dbox_cimod := c_dbox_mod_pass; + nstat.dbox_cc1op := '0'; + nstat.dbox_ccmode := IREG(8 downto 6); -- STATIC + nstat.lbox_func := (others=>'0'); + nstat.mbox_func := (others=>'0'); + nstat.res_sel := c_dpath_res_abox; + + nstat.fork_op := (others=>'0'); + nstat.fork_srcr := (others=>'0'); + nstat.fork_dstr := (others=>'0'); + nstat.fork_dsta := (others=>'0'); + nstat.fork_opg := (others=>'0'); + nstat.fork_opa := (others=>'0'); + + nstat.do_fork_op := '0'; + nstat.do_fork_srcr := '0'; + nstat.do_fork_dstr := '0'; + nstat.do_fork_dsta := '0'; + nstat.do_fork_opg := '0'; + + nstat.do_pref_dec := '0'; + + if SRCMODF = "000" then + is_srcmode0 := '1'; + end if; + + if DSTMODF = "000" then + nstat.is_dstmode0 := '1'; + if DSTREG /= c_gpr_pc then + is_dstmode0notpc := '1'; + end if; + end if; + + if SRCREG = c_gpr_pc then + nstat.is_srcpc := '1'; + if SRCMODF = "001" then + nstat.is_srcpcmode1 := '1'; + end if; + end if; + + if DSTREG = c_gpr_pc then + nstat.is_dstpc := '1'; + end if; + + if OPPRIM = "000" then + + if OPBYTE='0' and OPEXT1="000" then + + if OPEXT2="000" and OPEXT3="000" then -- HALT,...,RTT + nstat.is_res := '0'; + case OPEXT4 is + + when "000" => -- HALT + nstat.fork_op := c_fork_op_halt; + nstat.do_fork_op := '1'; + + when "001" => -- WAIT + nstat.fork_op := c_fork_op_wait; + nstat.do_fork_op := '1'; + + when "010" => -- RTI + nstat.force_srcsp := '1'; + nstat.fork_op := c_fork_op_rtti; + nstat.do_fork_op := '1'; + + when "011" => -- BPT (trap to 14) + nstat.trap_vec := "011"; + nstat.fork_op := c_fork_op_trap; + nstat.do_fork_op := '1'; + + when "100" => -- IOT (trap to 20) + nstat.trap_vec := "100"; + nstat.fork_op := c_fork_op_trap; + nstat.do_fork_op := '1'; + + when "101" => -- RESET + nstat.fork_op := c_fork_op_reset; + nstat.do_fork_op := '1'; + + when "110" => -- RTT + nstat.op_rtt := '1'; + nstat.force_srcsp := '1'; + nstat.fork_op := c_fork_op_rtti; + nstat.do_fork_op := '1'; + + when others => + nstat.is_res := '1'; + + end case; + end if; + + if OPEXT2 = "001" then -- JMP + nstat.is_res := '0'; + nstat.fork_opa := c_fork_opa_jmp; + nstat.do_fork_dsta := '1'; + end if; + + if OPEXT2 = "010" then + if OPEXT3 = "000" then -- RTS + nstat.is_res := '0'; + nstat.force_srcsp := '1'; + nstat.fork_op := c_fork_op_rts; + nstat.do_fork_op := '1'; + end if; + if OPEXT3 = "011" then -- SPL + nstat.is_res := '0'; + nstat.fork_op := c_fork_op_spl; + nstat.do_fork_op := '1'; + end if; + end if; + + if OPEXT2 = "010" then + if OPEXT3(2) = '1' then -- SEx/CLx + nstat.is_res := '0'; + nstat.fork_op := c_fork_op_mcc; + nstat.do_fork_op := '1'; + --!!!nstat.do_pref_dec := '1'; --??? ensure ireg_we .... + end if; + end if; + + if OPEXT2 = "011" then -- SWAP + nstat.is_res := '0'; + is_dstm := '1'; + nstat.fork_opg := c_fork_opg_gen; + nstat.do_fork_opg := '1'; + nstat.do_pref_dec := is_dstmode0notpc; + nstat.lbox_func := c_lbox_func_swap; + nstat.res_sel := c_dpath_res_lbox; + end if; + + end if; -- OPBYTE='0' and OPEXT1="000" + + if OPEXT1(2)='0' and -- BR class instructions + ((OPBYTE='0' and OPEXT2(2)='1') or -- BR + (OPBYTE='0' and (OPEXT1(0)='1' or OPEXT1(1)='1')) or -- BNE,..,BLE + OPBYTE='1') then -- BPL,..,BCS + nstat.is_res := '0'; + nstat.fork_op := c_fork_op_br; + nstat.do_fork_op := '1'; + end if; + + if OPBYTE='0' and OPEXT1="100" then -- JSR + nstat.is_res := '0'; + nstat.fork_opa := c_fork_opa_jsr; + nstat.do_fork_dsta := '1'; + end if; + + if OPBYTE='1' and OPEXT1="100" then -- EMT, TRAP + nstat.is_res := '0'; + if OPEXT2(2) = '0' then -- EMT (trap tp 30) + nstat.trap_vec := "110"; + else -- TRAP (trap to 34) + nstat.trap_vec := "111"; + end if; + nstat.fork_op := c_fork_op_trap; + nstat.do_fork_op := '1'; + end if; + + if OPEXT1 = "101" then -- CLR(B),...,TST(B) + nstat.is_res := '0'; + nstat.res_sel := c_dpath_res_dbox; + if OPBYTE = '1' then + nstat.is_bytop := '1'; + end if; + + nstat.dbox_cc1op := '1'; + + case OPEXT2 is + when "000" => -- CLR: 0 + 0 + 0 (0) + is_dstw := '1'; + nstat.dbox_srcmod := c_dbox_mod_zero; + nstat.dbox_dstmod := c_dbox_mod_zero; + nstat.dbox_cimod := c_dbox_mod_zero; + when "001" => -- COM: 0 + ~DST + 0 (~dst) + is_dstm := '1'; + nstat.dbox_srcmod := c_dbox_mod_zero; + nstat.dbox_dstmod := c_dbox_mod_inv; + nstat.dbox_cimod := c_dbox_mod_zero; + when "010" => -- INC: 0 + DST + 1 (dst+1) + is_dstm := '1'; + nstat.dbox_srcmod := c_dbox_mod_zero; + nstat.dbox_dstmod := c_dbox_mod_pass; + nstat.dbox_cimod := c_dbox_mod_one; + when "011" => -- DEC: ~0 + DST + 0 (dst-1) + is_dstm := '1'; + nstat.dbox_srcmod := c_dbox_mod_one; + nstat.dbox_dstmod := c_dbox_mod_pass; + nstat.dbox_cimod := c_dbox_mod_zero; + when "100" => -- NEG: 0 + ~DST + 1 (-dst) + is_dstm := '1'; + nstat.dbox_srcmod := c_dbox_mod_zero; + nstat.dbox_dstmod := c_dbox_mod_inv; + nstat.dbox_cimod := c_dbox_mod_one; + when "101" => -- ADC: 0 + DST + CI (dst+ci) + is_dstm := '1'; + nstat.dbox_srcmod := c_dbox_mod_zero; + nstat.dbox_dstmod := c_dbox_mod_pass; + nstat.dbox_cimod := c_dbox_mod_pass; + when "110" => -- SBC: ~0 + DST + ~CI (dst-ci) + is_dstm := '1'; + nstat.dbox_srcmod := c_dbox_mod_one; + nstat.dbox_dstmod := c_dbox_mod_pass; + nstat.dbox_cimod := c_dbox_mod_inv; + when "111" => -- TST: 0 + DST + 0 (dst) + is_dstr := '1'; + nstat.dbox_srcmod := c_dbox_mod_zero; + nstat.dbox_dstmod := c_dbox_mod_pass; + nstat.dbox_cimod := c_dbox_mod_zero; + when others => null; + end case; + + nstat.fork_opg := c_fork_opg_gen; + nstat.do_fork_opg := '1'; + nstat.do_pref_dec := is_dstmode0notpc; + + end if; + + if OPEXT1 = "110" then + if OPEXT2(2) = '0' then -- ROR(B),...,ASL(B) + nstat.is_res := '0'; + is_dstm := '1'; + nstat.fork_opg := c_fork_opg_gen; + nstat.do_fork_opg := '1'; + nstat.do_pref_dec := is_dstmode0notpc; + if OPBYTE = '1' then + nstat.is_bytop := '1'; + end if; + nstat.res_sel := c_dpath_res_lbox; + case OPEXT2(1 downto 0) is + when "00" => -- ROR + nstat.lbox_func := c_lbox_func_ror; + when "01" => -- ROL + nstat.lbox_func := c_lbox_func_rol; + when "10" => -- ASR + nstat.lbox_func := c_lbox_func_asr; + when "11" => -- ASL + nstat.lbox_func := c_lbox_func_asl; + when others => null; + end case; + end if; + + if OPBYTE='0' and OPEXT2="100" then -- MARK + nstat.is_res := '0'; + nstat.fork_op := c_fork_op_mark; + nstat.do_fork_op := '1'; + end if; + + if OPEXT2 = "101" then -- MFP(I/D) + nstat.is_res := '0'; + nstat.force_srcsp := '1'; + if DSTREG = c_gpr_sp then -- is dst reg == sp ? + nstat.updt_dstadsrc := '1'; -- ensure DSRC update in dsta flow + end if; + nstat.res_sel := c_dpath_res_abox; + if nstat.is_dstmode0 = '1' then + nstat.fork_opa := c_fork_opa_mfp_reg; + else + nstat.fork_opa := c_fork_opa_mfp_mem; + end if; + nstat.do_fork_dsta := '1'; + end if; + + if OPEXT2 = "110" then -- MTP(I/D) + nstat.is_res := '0'; + nstat.force_srcsp := '1'; + nstat.res_sel := c_dpath_res_abox; + nstat.fork_opa := c_fork_opa_mtp; + nstat.fork_op := c_fork_op_mtp; + nstat.do_fork_op := '1'; + end if; + + if OPBYTE='0' and OPEXT2="111" then -- SXT + nstat.is_res := '0'; + is_dstw := '1'; + nstat.fork_opg := c_fork_opg_gen; + nstat.do_fork_opg := '1'; + nstat.do_pref_dec := is_dstmode0notpc; + nstat.lbox_func := c_lbox_func_sxt; + nstat.res_sel := c_dpath_res_lbox; + end if; + end if; + + end if; -- OPPRIM="000" + + if OPPRIM/="000" and OPPRIM/="111" then + nstat.is_res := '0'; + case OPPRIM is + when "001" => -- MOV + is_srcr := '1'; + is_dstw := '1'; + nstat.op_mov := '1'; + nstat.lbox_func := c_lbox_func_mov; + nstat.res_sel := c_dpath_res_lbox; + nstat.is_bytop := OPBYTE; + when "010" => -- CMP + is_srcr := '1'; + is_dstr := '1'; + nstat.res_sel := c_dpath_res_dbox; + nstat.dbox_srcmod := c_dbox_mod_pass; + nstat.dbox_dstmod := c_dbox_mod_inv; + nstat.dbox_cimod := c_dbox_mod_one; + nstat.is_bytop := OPBYTE; + when "011" => -- BIT + is_srcr := '1'; + is_dstr := '1'; + nstat.lbox_func := c_lbox_func_bit; + nstat.res_sel := c_dpath_res_lbox; + nstat.is_bytop := OPBYTE; + when "100" => -- BIC + is_srcr := '1'; + is_dstm := '1'; + nstat.lbox_func := c_lbox_func_bic; + nstat.res_sel := c_dpath_res_lbox; + nstat.is_bytop := OPBYTE; + when "101" => -- BIS + is_srcr := '1'; + is_dstm := '1'; + nstat.lbox_func := c_lbox_func_bis; + nstat.res_sel := c_dpath_res_lbox; + nstat.is_bytop := OPBYTE; + when "110" => + is_srcr := '1'; + is_dstm := '1'; + nstat.res_sel := c_dpath_res_dbox; + if OPBYTE = '0' then -- ADD + nstat.dbox_srcmod := c_dbox_mod_pass; + nstat.dbox_dstmod := c_dbox_mod_pass; + nstat.dbox_cimod := c_dbox_mod_zero; + else -- SUB + nstat.dbox_srcmod := c_dbox_mod_inv; + nstat.dbox_dstmod := c_dbox_mod_pass; + nstat.dbox_cimod := c_dbox_mod_one; + end if; + when others => null; + end case; + + nstat.fork_opg := c_fork_opg_gen; + nstat.do_fork_opg := '1'; + nstat.do_pref_dec := is_srcmode0 and is_dstmode0notpc; + + end if; + + if OPBYTE='0' and OPPRIM="111" then + case OPEXT1 is + when "000" => -- MUL + nstat.is_res := '0'; + is_dstr := '1'; + nstat.mbox_func := c_mbox_func_mul; + nstat.res_sel := c_dpath_res_mbox; + nstat.fork_opg := c_fork_opg_mul; + nstat.do_fork_opg := '1'; + when "001" => -- DIV + nstat.is_res := '0'; + is_dstr := '1'; + nstat.mbox_func := c_mbox_func_div; + nstat.res_sel := c_dpath_res_mbox; + nstat.fork_opg := c_fork_opg_div; + nstat.do_fork_opg := '1'; + when "010" => -- ASH + nstat.is_res := '0'; + is_dstr := '1'; + nstat.mbox_func := c_mbox_func_ash; + nstat.res_sel := c_dpath_res_mbox; + nstat.fork_opg := c_fork_opg_ash; + nstat.do_fork_opg := '1'; + when "011" => -- ASHC + nstat.is_res := '0'; + is_dstr := '1'; + nstat.mbox_func := c_mbox_func_ashc; + nstat.res_sel := c_dpath_res_mbox; + nstat.fork_opg := c_fork_opg_ashc; + nstat.do_fork_opg := '1'; + when "100" => -- XOR + nstat.is_res := '0'; + is_dstm := '1'; + nstat.lbox_func := c_lbox_func_xor; + nstat.res_sel := c_dpath_res_lbox; + nstat.fork_opg := c_fork_opg_gen; + nstat.do_fork_opg := '1'; + nstat.do_pref_dec := is_dstmode0notpc; + when "111" => -- SOB: SRC + ~0 + 0 (src-1) + nstat.is_res := '0'; + nstat.dbox_srcmod := c_dbox_mod_pass; + nstat.dbox_dstmod := c_dbox_mod_one; + nstat.dbox_cimod := c_dbox_mod_zero; + nstat.res_sel := c_dpath_res_dbox; + nstat.fork_op := c_fork_op_sob; + nstat.do_fork_op := '1'; + when others => null; + end case; + + end if; + + if OPBYTE='1' and OPPRIM="111" then -- FPU + nstat.is_res := '1'; -- ??? FPU not yet handled + end if; + + case SRCMOD is + when "00" => nstat.fork_srcr := c_fork_srcr_def; + when "01" => nstat.fork_srcr := c_fork_srcr_inc; + when "10" => nstat.fork_srcr := c_fork_srcr_dec; + when "11" => nstat.fork_srcr := c_fork_srcr_ind; + when others => null; + end case; + + if is_srcr='1' and SRCMODF /="000" then + nstat.do_fork_srcr := '1'; + end if; + + case DSTMOD is + when "00" => nstat.fork_dstr := c_fork_dstr_def; + when "01" => nstat.fork_dstr := c_fork_dstr_inc; + when "10" => nstat.fork_dstr := c_fork_dstr_dec; + when "11" => nstat.fork_dstr := c_fork_dstr_ind; + when others => null; + end case; + + if (is_dstr or is_dstm)='1' and nstat.is_dstmode0='0' then + nstat.do_fork_dstr := '1'; + end if; + + if is_dstw='1' and nstat.is_dstmode0='0' then + case DSTMOD is + when "00" => nstat.fork_opg := c_fork_opg_wdef; + when "01" => nstat.fork_opg := c_fork_opg_winc; + when "10" => nstat.fork_opg := c_fork_opg_wdec; + when "11" => nstat.fork_opg := c_fork_opg_wind; + when others => null; + end case; + end if; + + if is_dstm='1' and nstat.is_dstmode0='0' then + nstat.is_rmwop := '1'; + end if; + + case DSTMOD is + when "00" => nstat.fork_dsta := c_fork_dsta_def; + when "01" => nstat.fork_dsta := c_fork_dsta_inc; + when "10" => nstat.fork_dsta := c_fork_dsta_dec; + when "11" => nstat.fork_dsta := c_fork_dsta_ind; + when others => null; + end case; + + if (is_dstw or is_dstm)='1' and nstat.is_dstmode0='1' then + nstat.is_dstw_reg := '1'; + if DSTREG = c_gpr_pc then + nstat.is_dstw_pc := '1'; --??? hack rename -> is_dstw_pc + end if; + end if; + + STAT <= nstat; + + end process proc_idecode; + +end syn; diff --git a/rtl/w11a/pdp11_dpath.vbom b/rtl/w11a/pdp11_dpath.vbom new file mode 100644 index 00000000..c198772c --- /dev/null +++ b/rtl/w11a/pdp11_dpath.vbom @@ -0,0 +1,13 @@ +# libs +../vlib/slvtypes.vhd +../ibus/iblib.vhd +pdp11.vbom +# components +pdp11_gpr.vbom +pdp11_psr.vbom +pdp11_abox.vbom +pdp11_dbox.vbom +pdp11_lbox.vbom +pdp11_mbox.vbom +# design +pdp11_dpath.vhd diff --git a/rtl/w11a/pdp11_dpath.vhd b/rtl/w11a/pdp11_dpath.vhd new file mode 100644 index 00000000..bfd18223 --- /dev/null +++ b/rtl/w11a/pdp11_dpath.vhd @@ -0,0 +1,340 @@ +-- $Id: pdp11_dpath.vhd 314 2010-07-09 17:38:41Z mueller $ +-- +-- Copyright 2006-2010 by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, 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 complete details. +-- +------------------------------------------------------------------------------ +-- Module Name: pdp11_dpath - syn +-- Description: pdp11: CPU datapath +-- +-- Dependencies: pdp11_gpr +-- pdp11_psr +-- pdp11_abox +-- pdp11_dbox +-- pdp11_lbox +-- pdp11_mbox +-- +-- Test bench: tb/tb_pdp11_core (implicit) +-- Target Devices: generic +-- Tool versions: xst 8.1, 8.2, 9.1, 9.2; ghdl 0.18-0.25 +-- Revision History: +-- Date Rev Version Comment +-- 2010-06-13 305 1.2 rename CPDIN -> CP_DIN; add CP_DOUT out port; +-- remove CPADDR out port; drop R_CPADDR, proc_cpaddr; +-- added R_CPDOUT, proc_cpdout +-- 2009-05-30 220 1.1.6 final removal of snoopers (were already commented) +-- 2008-12-14 177 1.1.5 fill gpr_* fields in DM_STAT_DP +-- 2008-08-22 161 1.1.4 rename ubf_ -> ibf_; use iblib +-- 2008-04-19 137 1.1.3 add DM_STAT_DP port +-- 2008-03-02 121 1.1.2 remove snoopers +-- 2008-02-24 119 1.1.1 add CPADDR register, remove R_MDIN (not needed) +-- 2007-12-30 107 1.1 use IB_MREQ/IB_SRES interface now (for psr access) +-- 2007-06-14 56 1.0.1 Use slvtypes.all +-- 2007-05-12 26 1.0 Initial version +------------------------------------------------------------------------------ + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; + +use work.slvtypes.all; +use work.iblib.all; +use work.pdp11.all; + +-- ---------------------------------------------------------------------------- + +entity pdp11_dpath is -- CPU datapath + port ( + CLK : in slbit; -- clock + CRESET : in slbit; -- console reset + CNTL : in dpath_cntl_type; -- control interface + STAT : out dpath_stat_type; -- status interface + CP_DIN : in slv16; -- console port data in + CP_DOUT : out slv16; -- console port data out + PSWOUT : out psw_type; -- current psw + PCOUT : out slv16; -- current pc + IREG : out slv16; -- ireg out + VM_ADDR : out slv16; -- virt. memory address + VM_DOUT : in slv16; -- virt. memory data out + VM_DIN : out slv16; -- virt. memory data in + IB_MREQ : in ib_mreq_type; -- ibus request + IB_SRES : out ib_sres_type; -- ibus response + DM_STAT_DP : out dm_stat_dp_type -- debug and monitor status + ); +end pdp11_dpath; + +architecture syn of pdp11_dpath is + + signal R_DSRC : slv16 := (others=>'0'); -- SRC register + signal R_DDST : slv16 := (others=>'0'); -- DST register + signal R_DTMP : slv16 := (others=>'0'); -- TMP register + + signal R_IREG : slv16 := (others=>'0'); -- IREG register + + signal R_CPDOUT : slv16 := (others=>'0'); -- cp dout buffer + + signal GPR_DSRC : slv16 := (others=>'0'); -- + signal GPR_DDST : slv16 := (others=>'0'); -- + signal GPR_PC : slv16 := (others=>'0'); -- + + signal PSW : psw_type := psw_init; -- + signal CCIN : slv4 := (others=>'0'); -- cc input to xbox's + signal CCOUT : slv4 := (others=>'0'); -- cc output from xbox's + + signal DRES : slv16 := (others=>'0'); -- result bus + signal DRESE : slv16 := (others=>'0'); -- result bus extra + + signal ABOX_DOUT : slv16 := (others=>'0'); -- result abox + signal DBOX_DOUT : slv16 := (others=>'0'); -- result dbox + signal LBOX_DOUT : slv16 := (others=>'0'); -- result lbox + signal MBOX_DOUT : slv16 := (others=>'0'); -- result mbox + + signal ABOX_NZOUT : slv2 := (others=>'0'); -- nz flags abox + signal ABOX_CCOUT : slv4 := (others=>'0'); -- cc flags abox + signal DBOX_CCOUT : slv4 := (others=>'0'); -- cc flags dbox + signal LBOX_CCOUT : slv4 := (others=>'0'); -- cc flags lbox + signal MBOX_CCOUT : slv4 := (others=>'0'); -- cc flags mbox + + subtype lal_ibf_addr is integer range 15 downto 1; + subtype lah_ibf_addr is integer range 5 downto 0; + constant lah_ibf_ena_22bit: integer := 6; + constant lah_ibf_ena_ubmap: integer := 7; + +begin + + GPR : pdp11_gpr port map ( + CLK => CLK, + DIN => DRES, + ASRC => CNTL.gpr_asrc, + ADST => CNTL.gpr_adst, + MODE => CNTL.gpr_mode, + RSET => CNTL.gpr_rset, + WE => CNTL.gpr_we, + BYTOP => CNTL.gpr_bytop, + PCINC => CNTL.gpr_pcinc, + DSRC => GPR_DSRC, + DDST => GPR_DDST, + PC => GPR_PC + ); + + PSR : pdp11_psr port map( + CLK => CLK, + CRESET => CRESET, + DIN => DRES, + CCIN => CCOUT, + CCWE => CNTL.psr_ccwe, + WE => CNTL.psr_we, + FUNC => CNTL.psr_func, + PSW => PSW, + IB_MREQ => IB_MREQ, + IB_SRES => IB_SRES + ); + + ABOX : pdp11_abox port map ( + DSRC => R_DSRC, + DDST => R_DDST, + DTMP => R_DTMP, + PC => GPR_PC, + ASEL => CNTL.abox_asel, + AZERO => CNTL.abox_azero, + IREG8 => R_IREG(7 downto 0), + VMDOUT => VM_DOUT, + CONST => CNTL.abox_const, + BSEL => CNTL.abox_bsel, + OPSUB => CNTL.abox_opsub, + DOUT => ABOX_DOUT, + NZOUT => ABOX_NZOUT + ); + + DBOX : pdp11_dbox port map ( + DSRC => R_DSRC, + DDST => R_DDST, + CI => CCIN(0), + SRCMOD => CNTL.dbox_srcmod, + DSTMOD => CNTL.dbox_dstmod, + CIMOD => CNTL.dbox_cimod, + CC1OP => CNTL.dbox_cc1op, + CCMODE => CNTL.dbox_ccmode, + BYTOP => CNTL.dbox_bytop, + DOUT => DBOX_DOUT, + CCOUT => DBOX_CCOUT + ); + + LBOX : pdp11_lbox port map ( + DSRC => R_DSRC, + DDST => R_DDST, + CCIN => CCIN, + FUNC => CNTL.lbox_func, + BYTOP => CNTL.lbox_bytop, + DOUT => LBOX_DOUT, + CCOUT => LBOX_CCOUT + ); + + MBOX : pdp11_mbox port map ( + CLK => CLK, + DSRC => R_DSRC, + DDST => R_DDST, + DTMP => R_DTMP, + GPR_DSRC => GPR_DSRC, + FUNC => CNTL.mbox_func, + S_DIV => CNTL.mbox_s_div, + S_DIV_CN => CNTL.mbox_s_div_cn, + S_DIV_CR => CNTL.mbox_s_div_cr, + S_ASH => CNTL.mbox_s_ash, + S_ASH_CN => CNTL.mbox_s_ash_cn, + S_ASHC => CNTL.mbox_s_ashc, + S_ASHC_CN => CNTL.mbox_s_ashc_cn, + SHC_TC => STAT.shc_tc, + DIV_CR => STAT.div_cr, + DIV_CQ => STAT.div_cq, + DIV_ZERO => STAT.div_zero, + DIV_OVFL => STAT.div_ovfl, + DOUT => MBOX_DOUT, + DOUTE => DRESE, + CCOUT => MBOX_CCOUT + ); + + CCIN <= PSW.cc; + + ABOX_CCOUT <= ABOX_NZOUT & "0" & CCIN(0); -- clear v, keep c + + proc_dres_sel: process (ABOX_DOUT, DBOX_DOUT, LBOX_DOUT, MBOX_DOUT, + VM_DOUT, R_IREG, CP_DIN, CNTL) + begin + case CNTL.dres_sel is + when c_dpath_res_abox => DRES <= ABOX_DOUT; + when c_dpath_res_dbox => DRES <= DBOX_DOUT; + when c_dpath_res_lbox => DRES <= LBOX_DOUT; + when c_dpath_res_mbox => DRES <= MBOX_DOUT; + when c_dpath_res_vmdout => DRES <= VM_DOUT; + when c_dpath_res_fpdout => DRES <= (others=>'0'); + when c_dpath_res_ireg => DRES <= R_IREG; + when c_dpath_res_cpdin => DRES <= CP_DIN; + when others => null; + end case; + end process proc_dres_sel; + + proc_cres_sel: process (ABOX_CCOUT, DBOX_CCOUT, LBOX_CCOUT, MBOX_CCOUT, + CCIN, CNTL) + begin + case CNTL.cres_sel is + when c_dpath_res_abox => CCOUT <= ABOX_CCOUT; + when c_dpath_res_dbox => CCOUT <= DBOX_CCOUT; + when c_dpath_res_lbox => CCOUT <= LBOX_CCOUT; + when c_dpath_res_mbox => CCOUT <= MBOX_CCOUT; + when c_dpath_res_vmdout => CCOUT <= CCIN; + when c_dpath_res_fpdout => CCOUT <= "0000"; + when c_dpath_res_ireg => CCOUT <= CCIN; + when c_dpath_res_cpdin => CCOUT <= CCIN; + when others => null; + end case; + end process proc_cres_sel; + + proc_dregs: process (CLK) + begin + + if CLK'event and CLK='1' then + + if CNTL.dsrc_we = '1' then + if CNTL.dsrc_sel = '0' then + R_DSRC <= GPR_DSRC; + else + R_DSRC <= DRES; + end if; + end if; + + if CNTL.ddst_we = '1' then + if CNTL.ddst_sel = '0' then + R_DDST <= GPR_DDST; + else + R_DDST <= DRES; + end if; + end if; + + if CNTL.dtmp_we = '1' then + case CNTL.dtmp_sel is + when c_dpath_dtmp_dsrc => R_DTMP <= GPR_DSRC; + when c_dpath_dtmp_psw => + R_DTMP <= (others=>'0'); + R_DTMP(psw_ibf_cmode) <= PSW.cmode; + R_DTMP(psw_ibf_pmode) <= PSW.pmode; + R_DTMP(psw_ibf_rset) <= PSW.rset; + R_DTMP(psw_ibf_pri) <= PSW.pri; + R_DTMP(psw_ibf_tflag) <= PSW.tflag; + R_DTMP(psw_ibf_cc) <= PSW.cc; + when c_dpath_dtmp_dres => R_DTMP <= DRES; + when c_dpath_dtmp_drese => R_DTMP <= DRESE; + when others => null; + end case; + end if; + + end if; + + end process proc_dregs; + + proc_mregs: process (CLK) + begin + + if CLK'event and CLK='1' then + + if CNTL.ireg_we = '1' then + R_IREG <= VM_DOUT; + end if; + + end if; + end process proc_mregs; + + proc_cpdout: process (CLK) + begin + if CLK'event and CLK='1'then + if CRESET = '1' then + R_CPDOUT <= (others=>'0'); + else + if CNTL.cpdout_we = '1' then + R_CPDOUT <= DRES; + end if; + end if; + end if; + end process proc_cpdout; + + proc_vmaddr_sel: process (R_DSRC, R_DDST, R_DTMP, GPR_PC, CNTL) + begin + case CNTL.vmaddr_sel is + when c_dpath_vmaddr_dsrc => VM_ADDR <= R_DSRC; + when c_dpath_vmaddr_ddst => VM_ADDR <= R_DDST; + when c_dpath_vmaddr_dtmp => VM_ADDR <= R_DTMP; + when c_dpath_vmaddr_pc => VM_ADDR <= GPR_PC; + when others => null; + end case; + end process proc_vmaddr_sel; + + STAT.ccout_z <= CCOUT(2); -- current Z cc flag + + PSWOUT <= PSW; + PCOUT <= GPR_PC; + IREG <= R_IREG; + VM_DIN <= DRES; + CP_DOUT <= R_CPDOUT; + + DM_STAT_DP.pc <= GPR_PC; + DM_STAT_DP.psw <= PSW; + DM_STAT_DP.ireg <= R_IREG; + DM_STAT_DP.ireg_we <= CNTL.ireg_we; + DM_STAT_DP.dsrc <= R_DSRC; + DM_STAT_DP.ddst <= R_DDST; + DM_STAT_DP.dtmp <= R_DTMP; + DM_STAT_DP.dres <= DRES; + DM_STAT_DP.gpr_adst <= CNTL.gpr_adst; + DM_STAT_DP.gpr_mode <= CNTL.gpr_mode; + DM_STAT_DP.gpr_bytop <= CNTL.gpr_bytop; + DM_STAT_DP.gpr_we <= CNTL.gpr_we; + +end syn; diff --git a/rtl/w11a/pdp11_gpr.vbom b/rtl/w11a/pdp11_gpr.vbom new file mode 100644 index 00000000..9bc38e6d --- /dev/null +++ b/rtl/w11a/pdp11_gpr.vbom @@ -0,0 +1,10 @@ +# libs +../vlib/slvtypes.vhd +../vlib/memlib/memlib.vhd +../ibus/iblib.vhd +pdp11.vbom +# components +[ghdl,isim]../vlib/memlib/ram_1swar_1ar_gen.vbom +[xst]../vlib/memlib/ram_1swar_1ar_gen_unisim.vbom +# design +pdp11_gpr.vhd diff --git a/rtl/w11a/pdp11_gpr.vhd b/rtl/w11a/pdp11_gpr.vhd new file mode 100644 index 00000000..4b6856c4 --- /dev/null +++ b/rtl/w11a/pdp11_gpr.vhd @@ -0,0 +1,159 @@ +-- $Id: pdp11_gpr.vhd 314 2010-07-09 17:38:41Z mueller $ +-- +-- Copyright 2006-2007 by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, 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 complete details. +-- +------------------------------------------------------------------------------ +-- Module Name: pdp11_gpr - syn +-- Description: pdp11: general purpose registers +-- +-- Dependencies: memlib/ram_1swar_1ar_gen +-- +-- Test bench: tb/tb_pdp11_core (implicit) +-- Target Devices: generic +-- Tool versions: xst 8.1, 8.2, 9.1, 9.2; ghdl 0.18-0.25 +-- Revision History: +-- Date Rev Version Comment +-- 2008-08-22 161 1.0.3 rename ubf_ -> ibf_; use iblib +-- 2007-12-30 108 1.0.2 use ubf_byte[01] +-- 2007-06-14 56 1.0.1 Use slvtypes.all +-- 2007-05-12 26 1.0 Initial version +------------------------------------------------------------------------------ + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; + +use work.slvtypes.all; +use work.memlib.all; +use work.iblib.all; +use work.pdp11.all; + +-- ---------------------------------------------------------------------------- + +entity pdp11_gpr is -- general purpose registers + port ( + CLK : in slbit; -- clock + DIN : in slv16; -- input data + ASRC : in slv3; -- source register number + ADST : in slv3; -- destination register number + MODE : in slv2; -- processor mode (k=>00,s=>01,u=>11) + RSET : in slbit; -- register set + WE : in slbit; -- write enable + BYTOP : in slbit; -- byte operation (write low byte only) + PCINC : in slbit; -- increment PC + DSRC : out slv16; -- source register data + DDST : out slv16; -- destination register data + PC : out slv16 -- current PC value + ); +end pdp11_gpr; + +architecture syn of pdp11_gpr is + +-- -------------------------------------- +-- the register map determines the internal register file storage address +-- of a register. The mapping is +-- ADDR RNUM SET MODE +-- 0000 000 0 -- R0 set 0 +-- 0001 001 0 -- R1 set 0 +-- 0010 010 0 -- R2 set 0 +-- 0011 011 0 -- R3 set 0 +-- 0100 100 0 -- R4 set 0 +-- 0101 101 0 -- R5 set 0 +-- 0110 110 - 00 SP kernel mode +-- 0111 110 - 01 SP supervisor mode +-- 1000 000 1 -- R0 set 1 +-- 1001 001 1 -- R1 set 1 +-- 1010 010 1 -- R2 set 1 +-- 1011 011 1 -- R3 set 1 +-- 1100 100 1 -- R4 set 1 +-- 1101 101 1 -- R5 set 1 +-- 1110 111 - -- PC +-- 1111 110 - 11 SP user mode + + procedure do_regmap ( + signal RNUM : in slv3; -- register number + signal MODE : in slv2; -- processor mode (k=>00,s=>01,u=>11) + signal RSET : in slbit; -- register set + signal ADDR : out slv4 -- internal address in regfile + ) is + begin + if RNUM = c_gpr_pc then + ADDR <= "1110"; + elsif RNUM = c_gpr_sp then + ADDR <= MODE(1) & "11" & MODE(0); + else + ADDR <= RSET & RNUM; + end if; + end procedure do_regmap; + +-- -------------------------------------- + + signal MASRC : slv4 := (others=>'0'); -- mapped source register address + signal MADST : slv4 := (others=>'0'); -- mapped destination register address + signal WE1 : slbit := '0'; -- write enable high byte + signal MEMSRC : slv16 := (others=>'0');-- source reg data from memory + signal MEMDST : slv16 := (others=>'0');-- destination reg data from memory + signal R_PC : slv16 := (others=>'0'); -- PC register + +begin + + do_regmap(RNUM => ASRC, MODE => MODE, RSET => RSET, ADDR => MASRC); + do_regmap(RNUM => ADST, MODE => MODE, RSET => RSET, ADDR => MADST); + + WE1 <= WE and not BYTOP; + + GPR_LOW : ram_1swar_1ar_gen + generic map ( + AWIDTH => 4, + DWIDTH => 8) + port map ( + CLK => CLK, + WE => WE, + ADDRA => MADST, + ADDRB => MASRC, + DI => DIN(ibf_byte0), + DOA => MEMDST(ibf_byte0), + DOB => MEMSRC(ibf_byte0)); + + GPR_HIGH : ram_1swar_1ar_gen + generic map ( + AWIDTH => 4, + DWIDTH => 8) + port map ( + CLK => CLK, + WE => WE1, + ADDRA => MADST, + ADDRB => MASRC, + DI => DIN(ibf_byte1), + DOA => MEMDST(ibf_byte1), + DOB => MEMSRC(ibf_byte1)); + + proc_pc : process (CLK) + alias R_PC15 : slv15 is R_PC(15 downto 1); -- upper 15 bit of PC + begin + if CLK'event and CLK='1' then + if WE='1' and ADST=c_gpr_pc then + R_PC(ibf_byte0) <= DIN(ibf_byte0); + if BYTOP = '0' then + R_PC(ibf_byte1) <= DIN(ibf_byte1); + end if; + elsif PCINC = '1' then + R_PC15 <= unsigned(R_PC15) + 1; + end if; + end if; + end process proc_pc; + + DSRC <= R_PC when ASRC=c_gpr_pc else MEMSRC; + DDST <= R_PC when ADST=c_gpr_pc else MEMDST; + PC <= R_PC; + +end syn; diff --git a/rtl/w11a/pdp11_irq.vbom b/rtl/w11a/pdp11_irq.vbom new file mode 100644 index 00000000..ee221009 --- /dev/null +++ b/rtl/w11a/pdp11_irq.vbom @@ -0,0 +1,6 @@ +# libs +../vlib/slvtypes.vhd +../ibus/iblib.vhd +pdp11.vbom +# design +pdp11_irq.vhd diff --git a/rtl/w11a/pdp11_irq.vhd b/rtl/w11a/pdp11_irq.vhd new file mode 100644 index 00000000..1c21c555 --- /dev/null +++ b/rtl/w11a/pdp11_irq.vhd @@ -0,0 +1,137 @@ +-- $Id: pdp11_irq.vhd 314 2010-07-09 17:38:41Z mueller $ +-- +-- Copyright 2007-2008 by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, 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 complete details. +-- +------------------------------------------------------------------------------ +-- Module Name: pdp11_irq - syn +-- Description: pdp11: interrupt requester +-- +-- Dependencies: - +-- Test bench: tb/tb_pdp11_core (implicit) +-- Target Devices: generic +-- Tool versions: xst 8.1, 8.2, 9.1, 9.2; ghdl 0.18-0.25 +-- Revision History: +-- Date Rev Version Comment +-- 2008-08-22 161 1.1.4 use iblib +-- 2008-04-25 138 1.1.3 use BRESET to clear pirq +-- 2008-01-06 111 1.1.2 rename signal EI_ACK->EI_ACKM (master ack) +-- 2008-01-05 110 1.1.1 rename IB_MREQ(ena->req) SRES(sel->ack, hold->busy) +-- 2007-12-30 107 1.1 use IB_MREQ/IB_SRES interface now +-- 2007-10-12 88 1.0.2 avoid ieee.std_logic_unsigned, use cast to unsigned +-- 2007-06-14 56 1.0.1 Use slvtypes.all +-- 2007-05-12 26 1.0 Initial version +------------------------------------------------------------------------------ + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; + +use work.slvtypes.all; +use work.iblib.all; +use work.pdp11.all; + +-- ---------------------------------------------------------------------------- + +entity pdp11_irq is -- interrupt requester + port ( + CLK : in slbit; -- clock + BRESET : in slbit; -- ibus reset + INT_ACK : in slbit; -- interrupt acknowledge from CPU + EI_PRI : in slv3; -- external interrupt priority + EI_VECT : in slv9_2; -- external interrupt vector + EI_ACKM : out slbit; -- external interrupt acknowledge + PRI : out slv3; -- interrupt priority + VECT : out slv9_2; -- interrupt vector + IB_MREQ : in ib_mreq_type; -- ibus request + IB_SRES : out ib_sres_type -- ibus response + ); +end pdp11_irq; + +architecture syn of pdp11_irq is + + constant ibaddr_pirq : slv16 := conv_std_logic_vector(8#177772#,16); + + subtype pirq_ubf_pir is integer range 15 downto 9; + subtype pirq_ubf_pia_h is integer range 7 downto 5; + subtype pirq_ubf_pia_l is integer range 3 downto 1; + + signal IBSEL_PIRQ : slbit := '0'; + signal R_PIRQ : slv8_1 := (others => '0'); -- pirq register + signal PI_PRI : slv3 := (others => '0'); -- prog.int. priority + +-- attribute PRIORITY_EXTRACT : string; +-- attribute PRIORITY_EXTRACT of PI_PRI : signal is "force"; + +begin + + proc_ibsel: process (IB_MREQ) + variable ipirq : slbit := '0'; + begin + ipirq := '0'; + if IB_MREQ.req='1' and IB_MREQ.addr=ibaddr_pirq(12 downto 1) then + ipirq := '1'; + end if; + IBSEL_PIRQ <= ipirq; + IB_SRES.ack <= ipirq; + IB_SRES.busy <= '0'; + end process proc_ibsel; + + proc_ibdout : process (IBSEL_PIRQ, R_PIRQ, PI_PRI) + variable pirqout : slv16 := (others=>'0'); + begin + pirqout := (others=>'0'); + if IBSEL_PIRQ = '1' then + pirqout(pirq_ubf_pir) := R_PIRQ; + pirqout(pirq_ubf_pia_h) := PI_PRI; + pirqout(pirq_ubf_pia_l) := PI_PRI; + end if; + IB_SRES.dout <= pirqout; + end process proc_ibdout; + + proc_pirq : process (CLK) + begin + if CLK'event and CLK='1' then + if BRESET = '1' then + R_PIRQ <= (others => '0'); + elsif IBSEL_PIRQ='1' and IB_MREQ.we='1'and IB_MREQ.be1='1' then + R_PIRQ <= IB_MREQ.din(pirq_ubf_pir); + end if; + end if; + end process proc_pirq; + + PI_PRI <= "111" when R_PIRQ(7)='1' else + "110" when R_PIRQ(6)='1' else + "101" when R_PIRQ(5)='1' else + "100" when R_PIRQ(4)='1' else + "011" when R_PIRQ(3)='1' else + "010" when R_PIRQ(2)='1' else + "001" when R_PIRQ(1)='1' else + "000"; + + proc_irq : process (PI_PRI, EI_PRI, EI_VECT, INT_ACK) + + begin + + EI_ACKM <= '0'; + + if unsigned(EI_PRI) > unsigned(PI_PRI) then + PRI <= EI_PRI; + VECT <= EI_VECT; + EI_ACKM <= INT_ACK; + else + PRI <= PI_PRI; + VECT <= conv_std_logic_vector(8#240#,9)(8 downto 2); + end if; + + end process proc_irq; + +end syn; diff --git a/rtl/w11a/pdp11_lbox.vbom b/rtl/w11a/pdp11_lbox.vbom new file mode 100644 index 00000000..d9c70f4f --- /dev/null +++ b/rtl/w11a/pdp11_lbox.vbom @@ -0,0 +1,5 @@ +# libs +../vlib/slvtypes.vhd +pdp11.vbom +# design +pdp11_lbox.vhd diff --git a/rtl/w11a/pdp11_lbox.vhd b/rtl/w11a/pdp11_lbox.vhd new file mode 100644 index 00000000..8e787659 --- /dev/null +++ b/rtl/w11a/pdp11_lbox.vhd @@ -0,0 +1,231 @@ +-- $Id: pdp11_lbox.vhd 314 2010-07-09 17:38:41Z mueller $ +-- +-- Copyright 2006-2008 by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, 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 complete details. +-- +------------------------------------------------------------------------------ +-- Module Name: pdp11_lbox - syn +-- Description: pdp11: logic unit for data (lbox) +-- +-- Dependencies: - +-- Test bench: tb/tb_pdp11_core (implicit) +-- Target Devices: generic +-- Tool versions: xst 8.1, 8.2, 9.1, 9.2; ghdl 0.18-0.25 +-- Revision History: +-- Date Rev Version Comment +-- 2008-03-30 131 1.0.2 BUGFIX: SXT clears V condition code +-- 2007-06-14 56 1.0.1 Use slvtypes.all +-- 2007-05-12 26 1.0 Initial version +------------------------------------------------------------------------------ + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; + +use work.slvtypes.all; +use work.pdp11.all; + +-- ---------------------------------------------------------------------------- + +entity pdp11_lbox is -- logic unit for data (lbox) + port ( + DSRC : in slv16; -- 'src' data in + DDST : in slv16; -- 'dst' data in + CCIN : in slv4; -- condition codes in + FUNC : in slv4; -- function + BYTOP : in slbit; -- byte operation + DOUT : out slv16; -- data output + CCOUT : out slv4 -- condition codes out + ); +end pdp11_lbox; + +architecture syn of pdp11_lbox is + +-- -------------------------------------- + +begin + + process (DSRC, DDST, CCIN, FUNC, BYTOP) + variable iout : slv16 := (others=>'0'); + variable inzstd : slbit := '0'; + variable ino : slbit := '0'; + variable izo : slbit := '0'; + variable ivo : slbit := '0'; + variable ico : slbit := '0'; + + alias DSRC_L : slv8 is DSRC(7 downto 0); + alias DSRC_H : slv8 is DSRC(15 downto 8); + alias DDST_L : slv8 is DDST(7 downto 0); + alias DDST_H : slv8 is DDST(15 downto 8); + alias NI : slbit is CCIN(3); + alias ZI : slbit is CCIN(2); + alias VI : slbit is CCIN(1); + alias CI : slbit is CCIN(0); + alias iout_l : slv8 is iout(7 downto 0); + alias iout_h : slv8 is iout(15 downto 8); + + begin + + iout := (others=>'0'); + inzstd := '1'; -- use standard logic by default + ino := '0'; + izo := '0'; + ivo := '0'; + ico := '0'; + +-- +-- the decoding of FUNC is done "manually" to get a structure based on +-- a 8->1 pattern. This matches the opcode structure and seems most +-- efficient. +-- + + if FUNC(3) = '0' then + if BYTOP = '0' then + + case FUNC(2 downto 0) is + when "000" => -- ASR + iout := DDST(15) & DDST(15 downto 1); + ico := DDST(0); + ivo := iout(15) xor ico; + + when "001" => -- ASL + iout := DDST(14 downto 0) & '0'; + ico := DDST(15); + ivo := iout(15) xor ico; + + when "010" => -- ROR + iout := CI & DDST(15 downto 1); + ico := DDST(0); + ivo := iout(15) xor ico; + + when "011" => -- ROL + iout := DDST(14 downto 0) & CI; + ico := DDST(15); + ivo := iout(15) xor ico; + + when "100" => -- BIS + iout := DDST or DSRC; + ico := CI; + + when "101" => -- BIC + iout := DDST and not DSRC; + ico := CI; + + when "110" => -- BIT + iout := DDST and DSRC; + ico := CI; + + when "111" => -- MOV + iout := DSRC; + ico := CI; + when others => null; + end case; + + else + + case FUNC(2 downto 0) is + when "000" => -- ASRB + iout_l := DDST_L(7) & DDST_L(7 downto 1); + ico := DDST_L(0); + ivo := iout_l(7) xor ico; + + when "001" => -- ASLB + iout_l := DDST(6 downto 0) & '0'; + ico := DDST(7); + ivo := iout_l(7) xor ico; + + when "010" => -- RORB + iout_l := CI & DDST_L(7 downto 1); + ico := DDST_L(0); + ivo := iout_l(7) xor ico; + + when "011" => -- ROLB + iout_l := DDST_L(6 downto 0) & CI; + ico := DDST_L(7); + ivo := iout_l(7) xor ico; + + when "100" => -- BISB + iout_l := DDST_L or DSRC_L; + ico := CI; + + when "101" => -- BICB + iout_l := DDST_L and not DSRC_L; + ico := CI; + + when "110" => -- BITB + iout_l := DDST_L and DSRC_L; + ico := CI; + + when "111" => -- MOVB + iout_l := DSRC_L; + iout_h := (others=>DSRC_L(7)); + ico := CI; + when others => null; + end case; + end if; + + else + case FUNC(2 downto 0) is + when "000" => -- SXT + iout := (others=>NI); + inzstd := '0'; + ino := NI; + izo := not NI; + ivo := '0'; + ico := CI; + + when "001" => -- SWAP + iout := DDST_L & DDST_H; + inzstd := '0'; + ino := iout(7); + if unsigned(iout(7 downto 0)) = 0 then + izo := '1'; + else + izo := '0'; + end if; + + when "010" => -- XOR + iout := DDST xor DSRC; + ico := CI; + + when others => null; + + end case; + end if; + + DOUT <= iout; + + if inzstd = '1' then + if BYTOP = '1' then + ino := iout(7); + if unsigned(iout(7 downto 0)) = 0 then + izo := '1'; + else + izo := '0'; + end if; + else + ino := iout(15); + if unsigned(iout) = 0 then + izo := '1'; + else + izo := '0'; + end if; + end if; + end if; + + CCOUT(3) <= ino; + CCOUT(2) <= izo; + CCOUT(1) <= ivo; + CCOUT(0) <= ico; + + end process; + +end syn; diff --git a/rtl/w11a/pdp11_mbox.vbom b/rtl/w11a/pdp11_mbox.vbom new file mode 100644 index 00000000..11e07428 --- /dev/null +++ b/rtl/w11a/pdp11_mbox.vbom @@ -0,0 +1,5 @@ +# libs +../vlib/slvtypes.vhd +pdp11.vbom +# design +pdp11_mbox.vhd diff --git a/rtl/w11a/pdp11_mbox.vhd b/rtl/w11a/pdp11_mbox.vhd new file mode 100644 index 00000000..516d9e70 --- /dev/null +++ b/rtl/w11a/pdp11_mbox.vhd @@ -0,0 +1,395 @@ +-- $Id: pdp11_mbox.vhd 314 2010-07-09 17:38:41Z mueller $ +-- +-- Copyright 2006-2007 by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, 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 complete details. +-- +------------------------------------------------------------------------------ +-- Module Name: pdp11_mbox - syn +-- Description: pdp11: mul/div unit for data (mbox) +-- +-- Dependencies: - +-- Test bench: tb/tb_pdp11_core (implicit) +-- Target Devices: generic +-- Tool versions: xst 8.1, 8.2, 9.1, 9.2; ghdl 0.18-0.25 +-- Revision History: +-- Date Rev Version Comment +-- 2007-06-14 56 1.0.1 Use slvtypes.all +-- 2007-05-12 26 1.0 Initial version +------------------------------------------------------------------------------ + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; + +use work.slvtypes.all; +use work.pdp11.all; + +-- ---------------------------------------------------------------------------- + +entity pdp11_mbox is -- mul/div unit for data (mbox) + port ( + CLK : in slbit; -- clock + DSRC : in slv16; -- 'src' data in + DDST : in slv16; -- 'dst' data in + DTMP : in slv16; -- 'tmp' data in + GPR_DSRC : in slv16; -- 'src' data from GPR + FUNC : in slv2; -- function + S_DIV : in slbit; -- s_opg_div state + S_DIV_CN : in slbit; -- s_opg_div_cn state + S_DIV_CR : in slbit; -- s_opg_div_cr state + S_ASH : in slbit; -- s_opg_ash state + S_ASH_CN : in slbit; -- s_opg_ash_cn state + S_ASHC : in slbit; -- s_opg_ashc state + S_ASHC_CN : in slbit; -- s_opg_ashc_cn state + SHC_TC : out slbit; -- last shc cycle (shc==0) + DIV_CR : out slbit; -- division: reminder correction needed + DIV_CQ : out slbit; -- division: quotient correction needed + DIV_ZERO : out slbit; -- division: divident or divisor zero + DIV_OVFL : out slbit; -- division: overflow + DOUT : out slv16; -- data output + DOUTE : out slv16; -- data output extra + CCOUT : out slv4 -- condition codes out + ); +end pdp11_mbox; + +architecture syn of pdp11_mbox is + + signal R_DD_L : slv16 := (others=>'0'); -- divident, low order part + signal R_DDO_LT : slbit := '0'; -- original sign bit of divident + signal R_DIV_V : slbit := '0'; -- V flag for division + signal R_SHC : slv6 := (others=>'0'); -- shift counter for div and ash/c + signal R_C1 : slbit := '0'; -- first cycle indicator + signal R_MSBO : slbit := '0'; -- original sign bit for ash/c + signal R_ASH_V : slbit := '0'; -- V flag for ash/c + signal R_ASH_C : slbit := '0'; -- C flag for ash/c + + signal NEXT_DD_L : slv16 := (others=>'0'); + signal NEXT_DDO_LT : slbit := '0'; + signal NEXT_DIV_V : slbit := '0'; + signal NEXT_SHC : slv6 := (others=>'0'); + signal NEXT_C1 : slbit := '0'; + signal NEXT_MSBO : slbit := '0'; + signal NEXT_ASH_V : slbit := '0'; + signal NEXT_ASH_C : slbit := '0'; + + signal SHC_TC_L : slbit := '0'; + + signal DDST_ZERO : slbit := '0'; + signal DSRC_ZERO : slbit := '0'; + signal DSRC_ONES : slbit := '0'; + signal DTMP_ZERO : slbit := '0'; + + signal DOUT_DIV : slv16 := (others=>'0'); + signal DOUTE_DIV : slv16 := (others=>'0'); + + alias DR : slv16 is DDST; -- divisor (in DDST) + alias DD_H : slv16 is DSRC; -- divident, high order part (in DSRC) + alias Q : slv16 is DTMP; -- quotient (accumulated in DTMP) + +begin + + proc_regs: process (CLK) + begin + if CLK'event and CLK='1' then + R_DD_L <= NEXT_DD_L; + R_DDO_LT <= NEXT_DDO_LT; + R_DIV_V <= NEXT_DIV_V; + R_SHC <= NEXT_SHC; + R_C1 <= NEXT_C1; + R_MSBO <= NEXT_MSBO; + R_ASH_V <= NEXT_ASH_V; + R_ASH_C <= NEXT_ASH_C; + end if; + end process proc_regs; + + proc_comm: process (DDST, DSRC, DTMP) + begin + + DDST_ZERO <= '0'; + DSRC_ZERO <= '0'; + DSRC_ONES <= '0'; + DTMP_ZERO <= '0'; + + if unsigned(DDST) = 0 then + DDST_ZERO <= '1'; + end if; + if unsigned(DSRC) = 0 then + DSRC_ZERO <= '1'; + end if; + if signed(DSRC) = -1 then + DSRC_ONES <= '1'; + end if; + if unsigned(DTMP) = 0 then + DTMP_ZERO <= '1'; + end if; + + end process proc_comm; + + proc_shc: process (DDST, R_SHC, R_C1, + S_DIV, S_DIV_CN, S_ASH, S_ASH_CN, S_ASHC, S_ASHC_CN) + begin + + NEXT_SHC <= R_SHC; + NEXT_C1 <= R_C1; + + if S_ASH='1' or S_ASHC='1' then + NEXT_SHC <= DDST(5 downto 0); + NEXT_C1 <= '1'; + end if; + if S_DIV = '1' then + NEXT_SHC <= "001111"; + NEXT_C1 <= '1'; + end if; + + if S_DIV_CN='1' or S_ASH_CN='1' or S_ASHC_CN='1' then + if R_SHC(5) = '0' then + NEXT_SHC <= unsigned(R_SHC) - 1; + else + NEXT_SHC <= unsigned(R_SHC) + 1; + end if; + NEXT_C1 <= '0'; + end if; + + SHC_TC_L <= '0'; + if unsigned(R_SHC) = 0 then + SHC_TC_L <= '1'; + end if; + + end process proc_shc; + + proc_div: process (DDST, DSRC, DTMP, GPR_DSRC, DR, DD_H, Q, + R_DD_L, R_DDO_LT, R_DIV_V, R_SHC, R_C1, + S_DIV, S_DIV_CN, S_DIV_CR, + DDST_ZERO, DSRC_ZERO, DTMP_ZERO) + + variable shftdd : slbit := '0'; + variable subadd : slbit := '0'; + + variable dd_gt : slbit := '0'; + + variable qbit : slbit := '0'; + variable qbit_1 : slbit := '0'; + variable qbit_n : slbit := '0'; + + variable dd_h_old : slv16 := (others=>'0'); -- dd_h before add/sub + variable dd_h_new : slv16 := (others=>'0'); -- dd_h after add/sub + + begin + + NEXT_DD_L <= R_DD_L; + NEXT_DDO_LT <= R_DDO_LT; + NEXT_DIV_V <= R_DIV_V; + + DIV_ZERO <= '0'; + DIV_OVFL <= '0'; + + qbit_1 := not (DR(15) xor DD_H(15)); -- !(dr<0 ^ dd_h<0) + + shftdd := not S_DIV_CR; + if shftdd = '1' then + dd_h_old := DD_H(14 downto 0) & R_DD_L(15); + else + dd_h_old := DD_H(15 downto 0); + end if; + + if R_C1 = '1' then + subadd := qbit_1; + DIV_ZERO <= DDST_ZERO or + (DSRC_ZERO and DTMP_ZERO); -- note: DTMP here still dd_low ! + else + subadd := Q(0); + end if; + + if subadd = '0' then + dd_h_new := signed(dd_h_old) + signed(DR); + else + dd_h_new := signed(dd_h_old) - signed(DR); + end if; + + dd_gt := '0'; + if dd_h_new(15) = '0' and + (unsigned(dd_h_new(14 downto 0))/=0 or + unsigned(R_DD_L(14 downto 0))/=0) + then + dd_gt := '1'; -- set if dd_new > 0 + end if; + + if R_DDO_LT = '0' then + qbit_n := DR(15) xor not dd_h_new(15); -- b_dr_lt ^ !b_dd_lt + else + qbit_n := DR(15) xor dd_gt; -- b_dr_lt ^ b_dd_gt + end if; + + if S_DIV = '1' then + NEXT_DDO_LT <= DD_H(15); + NEXT_DD_L <= GPR_DSRC; + end if; + + if R_C1 = '1' then + NEXT_DIV_V <= (DD_H(15) xor DD_H(14)) or + (DD_H(15) xor (DR(15) xor qbit_n)); + DIV_OVFL <= (DD_H(15) xor DD_H(14)) or --??? cleanup + (DD_H(15) xor (DR(15) xor qbit_n)); --??? cleanup + end if; + + if S_DIV_CN = '1' then + NEXT_DD_L <= R_DD_L(14 downto 0) & '0'; + end if; + + if S_DIV_CN = '1' then + qbit := qbit_n; + else + qbit := qbit_1; + end if; + + DIV_CR <= not (R_DDO_LT xor + (DR(15) xor Q(0))); --!(b_ddo_lt ^ (b_dr_lt ^ b_qbit)); + DIV_CQ <= R_DDO_LT xor DR(15); -- b_ddo_lt ^ b_dr_lt; + + DOUT_DIV <= dd_h_new; + DOUTE_DIV <= Q(14 downto 0) & qbit; + + end process proc_div; + + proc_ash: process (R_MSBO, R_ASH_V, R_ASH_C, R_SHC, DSRC, DTMP, FUNC, + S_ASH, S_ASH_CN, S_ASHC, S_ASHC_CN, SHC_TC_L) + begin + + NEXT_MSBO <= R_MSBO; + NEXT_ASH_V <= R_ASH_V; + NEXT_ASH_C <= R_ASH_C; + + if S_ASH='1' or S_ASHC='1' then + NEXT_MSBO <= DSRC(15); + NEXT_ASH_V <= '0'; + NEXT_ASH_C <= '0'; + end if; + + if (S_ASH_CN='1' or S_ASHC_CN='1') and SHC_TC_L='0' then + if R_SHC(5) = '0' then -- left shift + if (R_MSBO xor DSRC(14))='1' then + NEXT_ASH_V <= '1'; + end if; + NEXT_ASH_C <= DSRC(15); + else -- right shift + if FUNC = c_mbox_func_ash then + NEXT_ASH_C <= DSRC(0); + else + NEXT_ASH_C <= DTMP(0); + end if; + end if; + end if; + + end process proc_ash; + + proc_omux: process (DSRC, DDST, DTMP, FUNC, + R_ASH_V, R_ASH_C, R_SHC, R_DIV_V, + DOUT_DIV, DOUTE_DIV, + DSRC_ZERO, DSRC_ONES, DTMP_ZERO, DDST_ZERO) + + variable prod : slv32 := (others=>'0'); + variable omux_sel : slv2 := "00"; + variable ash_dout0 : slbit := '0'; + + variable mul_c : slbit := '0'; + + begin + + prod := signed(DSRC) * signed(DDST); + + case FUNC is + when c_mbox_func_mul => + omux_sel := "00"; + when c_mbox_func_div => + omux_sel := "01"; + when c_mbox_func_ash |c_mbox_func_ashc => + if R_SHC(5) = '0' then + omux_sel := "10"; + else + omux_sel := "11"; + end if; + when others => null; + end case; + + if FUNC = c_mbox_func_ash then + ash_dout0 := '0'; + else + ash_dout0 := DTMP(15); + end if; + + case omux_sel is + when "00" => -- MUL + DOUT <= prod(31 downto 16); + DOUTE <= prod(15 downto 0); + when "01" => -- DIV + DOUT <= DOUT_DIV; + DOUTE <= DOUTE_DIV; + when "10" => -- shift left + DOUT <= DSRC(14 downto 0) & ash_dout0; + DOUTE <= DTMP(14 downto 0) & "0"; + when "11" => -- shift right + DOUT <= DSRC(15) & DSRC(15 downto 1); + DOUTE <= DSRC(0) & DTMP(15 downto 1); + when others => null; + end case; + + mul_c := '0'; -- MUL C codes is set if + if DSRC(15) = '0' then + if DSRC_ZERO='0' or DTMP(15)='1' then -- for positive results when + mul_c := '1'; -- product > 2^15-1 + end if; + else -- for negative results when + if DSRC_ONES='0' or DTMP(15)='0' then + mul_c := '1'; -- product < -2^15 + end if; + end if; + + case FUNC is + when c_mbox_func_mul => + CCOUT(3) <= DSRC(15); -- N + CCOUT(2) <= DSRC_ZERO and DTMP_ZERO;-- Z + CCOUT(1) <= '0'; -- V=0 + CCOUT(0) <= mul_c; -- C + + when c_mbox_func_div => + if DDST_ZERO = '1' then + CCOUT(3) <= '0'; -- N=0 if div/0 + CCOUT(2) <= '1'; -- Z=1 if div/0 + elsif R_DIV_V = '1' then + CCOUT(3) <= DSRC(15) xor DDST(15); -- N (from unchanged reg) + CCOUT(2) <= '0'; -- Z (from unchanged reg) ??? veri + else + CCOUT(3) <= DTMP(15); -- N (from Q (DTMP)) + CCOUT(2) <= DTMP_ZERO; -- Z (from Q (DTMP)) ??? verify + end if; + CCOUT(1) <= R_DIV_V or DDST_ZERO; -- V + CCOUT(0) <= DDST_ZERO; -- C (dst=0) + + when c_mbox_func_ash => + CCOUT(3) <= DSRC(15); -- N + CCOUT(2) <= DSRC_ZERO; -- Z + CCOUT(1) <= R_ASH_V; -- V + CCOUT(0) <= R_ASH_C; -- C + + when c_mbox_func_ashc => + CCOUT(3) <= DSRC(15); -- N + CCOUT(2) <= DSRC_ZERO and DTMP_ZERO;-- Z + CCOUT(1) <= R_ASH_V; -- V + CCOUT(0) <= R_ASH_C; -- C + + when others => null; + end case; + + end process proc_omux; + + SHC_TC <= SHC_TC_L; + +end syn; diff --git a/rtl/w11a/pdp11_mem70.vbom b/rtl/w11a/pdp11_mem70.vbom new file mode 100644 index 00000000..b1c3bb63 --- /dev/null +++ b/rtl/w11a/pdp11_mem70.vbom @@ -0,0 +1,8 @@ +# libs +../vlib/slvtypes.vhd +../ibus/iblib.vhd +pdp11.vbom +sys_conf : sys_conf.vhd +# components +# design +pdp11_mem70.vhd diff --git a/rtl/w11a/pdp11_mem70.vhd b/rtl/w11a/pdp11_mem70.vhd new file mode 100644 index 00000000..52f19032 --- /dev/null +++ b/rtl/w11a/pdp11_mem70.vhd @@ -0,0 +1,174 @@ +-- $Id: pdp11_mem70.vhd 314 2010-07-09 17:38:41Z mueller $ +-- +-- Copyright 2008- by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, 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 complete details. +-- +------------------------------------------------------------------------------ +-- Module Name: pdp11_mem70 - syn +-- Description: pdp11: 11/70 memory system registers +-- +-- Dependencies: - +-- Test bench: tb/tb_pdp11_core (implicit) +-- Target Devices: generic +-- Tool versions: xst 8.1, 8.2, 9.1, 9.2; ghdl 0.18-0.25 +-- Revision History: +-- Date Rev Version Comment +-- 2008-08-22 161 1.0.2 rename ubf_ -> ibf_; use iblib +-- 2008-02-23 118 1.0.1 use sys_conf_mem_losize; rename CACHE_ENA->_FMISS +-- 2008-01-27 115 1.0 Initial version +------------------------------------------------------------------------------ + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; + +use work.slvtypes.all; +use work.iblib.all; +use work.pdp11.all; +use work.sys_conf.all; + +-- ---------------------------------------------------------------------------- + +entity pdp11_mem70 is -- 11/70 memory system registers + port ( + CLK : in slbit; -- clock + CRESET : in slbit; -- console reset + HM_ENA : in slbit; -- hit/miss enable + HM_VAL : in slbit; -- hit/miss value + CACHE_FMISS : out slbit; -- cache force miss + IB_MREQ : in ib_mreq_type; -- ibus request + IB_SRES : out ib_sres_type -- ibus response + ); +end pdp11_mem70; + +architecture syn of pdp11_mem70 is + + constant ibaddr_loaddr : slv16 := conv_std_logic_vector(8#177740#,16); + constant ibaddr_hiaddr : slv16 := conv_std_logic_vector(8#177742#,16); + constant ibaddr_syserr : slv16 := conv_std_logic_vector(8#177744#,16); + constant ibaddr_cntl : slv16 := conv_std_logic_vector(8#177746#,16); + constant ibaddr_maint : slv16 := conv_std_logic_vector(8#177750#,16); + constant ibaddr_hm : slv16 := conv_std_logic_vector(8#177752#,16); + constant ibaddr_losize : slv16 := conv_std_logic_vector(8#177760#,16); + constant ibaddr_hisize : slv16 := conv_std_logic_vector(8#177762#,16); + + subtype cntl_ibf_frep is integer range 5 downto 4; + subtype cntl_ibf_fmiss is integer range 3 downto 2; + constant cntl_ibf_disutrap : integer := 1; + constant cntl_ibf_distrap : integer := 0; + + type regs_type is record -- state registers + hm_data : slv6; -- hit/miss: data + cr_frep : slv2; -- cntl: force replacement bits + cr_fmiss : slv2; -- cntl: force miss bits + cr_disutrap: slbit; -- cntl: disable unibus trap + cr_distrap: slbit; -- cntl: disable traps + end record regs_type; + + constant regs_init : regs_type := ( + (others=>'0'), -- hm_data + "00","00", -- cr_freq,_fmiss + '0','0' -- dis(u)trap + ); + + signal R_REGS : regs_type := regs_init; + signal N_REGS : regs_type := regs_init; + +begin + + proc_regs: process (CLK) + begin + if CLK'event and CLK='1' then + if CRESET = '1' then + R_REGS <= regs_init; + else + R_REGS <= N_REGS; + end if; + end if; + end process proc_regs; + + proc_next: process (R_REGS, HM_ENA, HM_VAL, IB_MREQ) + variable r : regs_type := regs_init; + variable n : regs_type := regs_init; + variable ibsel_cr : slbit := '0'; -- control reg + variable ibsel_hm : slbit := '0'; -- hit/miss reg + variable ibsel_ls : slbit := '0'; -- low size reg + variable ibsel_nn : slbit := '0'; -- all other + variable ibsel : slbit := '0'; + variable idout : slv16 := (others=>'0'); + begin + + r := R_REGS; + n := R_REGS; + + ibsel_cr := '0'; + ibsel_hm := '0'; + ibsel_ls := '0'; + ibsel_nn := '0'; + ibsel := '0'; + idout := (others=>'0'); + + if IB_MREQ.req = '1' then + if IB_MREQ.addr = ibaddr_cntl(12 downto 1) then + ibsel_cr := '1'; + end if; + if IB_MREQ.addr = ibaddr_hm(12 downto 1) then + ibsel_hm := '1'; + end if; + if IB_MREQ.addr = ibaddr_losize(12 downto 1) then + ibsel_ls := '1'; + end if; + if IB_MREQ.addr=ibaddr_loaddr(12 downto 1) or + IB_MREQ.addr=ibaddr_hiaddr(12 downto 1) or + IB_MREQ.addr=ibaddr_syserr(12 downto 1) or + IB_MREQ.addr=ibaddr_maint(12 downto 1) or + IB_MREQ.addr=ibaddr_hisize(12 downto 1) then + ibsel_nn := '1'; + end if; + end if; + + ibsel := ibsel_cr or ibsel_hm or ibsel_ls or ibsel_nn; + + if ibsel_cr = '1' then + idout(cntl_ibf_frep) := r.cr_frep; + idout(cntl_ibf_fmiss) := r.cr_fmiss; + idout(cntl_ibf_disutrap) := r.cr_disutrap; + idout(cntl_ibf_distrap) := r.cr_distrap; + end if; + if ibsel_hm = '1' then + idout(r.hm_data'range) := r.hm_data; + end if; + if ibsel_ls = '1' then + idout := conv_std_logic_vector(sys_conf_mem_losize,16); + end if; + + if ibsel_cr='1' and IB_MREQ.we='1' and IB_MREQ.be0='1' then + n.cr_frep := IB_MREQ.din(cntl_ibf_frep); + n.cr_fmiss := IB_MREQ.din(cntl_ibf_fmiss); + n.cr_disutrap := IB_MREQ.din(cntl_ibf_disutrap); + n.cr_distrap := IB_MREQ.din(cntl_ibf_distrap); + end if; + + if HM_ENA = '1' then + n.hm_data := r.hm_data(r.hm_data'left-1 downto 0) & HM_VAL; + end if; + + N_REGS <= n; + + IB_SRES.ack <= ibsel; + IB_SRES.busy <= '0'; + IB_SRES.dout <= idout; + + end process proc_next; + + CACHE_FMISS <= (R_REGS.cr_fmiss(1) or R_REGS.cr_fmiss(0)); + +end syn; diff --git a/rtl/w11a/pdp11_mmu.vbom b/rtl/w11a/pdp11_mmu.vbom new file mode 100644 index 00000000..ef8f89eb --- /dev/null +++ b/rtl/w11a/pdp11_mmu.vbom @@ -0,0 +1,10 @@ +# libs +../vlib/slvtypes.vhd +../ibus/iblib.vhd +pdp11.vbom +# components +pdp11_mmu_sadr.vbom +pdp11_mmu_ssr12.vbom +../ibus/ib_sres_or_3.vbom +# design +pdp11_mmu.vhd diff --git a/rtl/w11a/pdp11_mmu.vhd b/rtl/w11a/pdp11_mmu.vhd new file mode 100644 index 00000000..13f0c437 --- /dev/null +++ b/rtl/w11a/pdp11_mmu.vhd @@ -0,0 +1,406 @@ +-- $Id: pdp11_mmu.vhd 314 2010-07-09 17:38:41Z mueller $ +-- +-- Copyright 2006-2010 by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, 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 complete details. +-- +------------------------------------------------------------------------------ +-- Module Name: pdp11_mmu - syn +-- Description: pdp11: mmu - memory management unit +-- +-- Dependencies: pdp11_mmu_sadr +-- pdp11_mmu_ssr12 +-- ibus/ib_sres_or_3 +-- +-- Test bench: tb/tb_pdp11_core (implicit) +-- Target Devices: generic +-- Tool versions: xst 8.1, 8.2, 9.1, 9.2; ghdl 0.18-0.25 +-- Revision History: +-- Date Rev Version Comment +-- 2010-06-20 307 1.3.7 rename cpacc to cacc in mmu_cntl_type +-- 2009-05-30 220 1.3.6 final removal of snoopers (were already commented) +-- 2009-05-09 213 1.3.5 BUGFIX: tie inst_compl permanentely '0' +-- BUGFIX: set ssr0 trap_mmu even when traps disabled +-- 2008-08-22 161 1.3.4 rename pdp11_ibres_ -> ib_sres_, ubf_ -> ibf_ +-- 2008-04-27 139 1.3.3 allow ssr1/2 tracing even with mmu_ena=0 +-- 2008-04-25 138 1.3.2 add BRESET port, clear ssr0/3 with BRESET +-- 2008-03-02 121 1.3.1 remove snoopers +-- 2008-02-24 119 1.3 return always mapped address in PADDRH; remove +-- cpacc handling; PADDR generation now on _vmbox +-- 2008-01-05 110 1.2.1 rename _mmu_regs -> _mmu_sadr +-- rename IB_MREQ(ena->req) SRES(sel->ack, hold->busy) +-- 2008-01-01 109 1.2 use pdp11_mmu_regs (rather than _regset) +-- 2007-12-31 108 1.1.1 remove SADR memory address mux (-> _mmu_regfile) +-- 2007-12-30 107 1.1 use IB_MREQ/IB_SRES interface now +-- 2007-06-14 56 1.0.1 Use slvtypes.all +-- 2007-05-12 26 1.0 Initial version +------------------------------------------------------------------------------ + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; + +use work.slvtypes.all; +use work.iblib.all; +use work.pdp11.all; + +-- ---------------------------------------------------------------------------- + +entity pdp11_mmu is -- mmu - memory management unit + port ( + CLK : in slbit; -- clock + CRESET : in slbit; -- console reset + BRESET : in slbit; -- ibus reset + CNTL : in mmu_cntl_type; -- control port + VADDR : in slv16; -- virtual address + MONI : in mmu_moni_type; -- monitor port + STAT : out mmu_stat_type; -- status port + PADDRH : out slv16; -- physical address (upper 16 bit) + IB_MREQ: in ib_mreq_type; -- ibus request + IB_SRES: out ib_sres_type -- ibus response + ); +end pdp11_mmu; + +architecture syn of pdp11_mmu is + + constant ibaddr_ssr0 : slv16 := conv_std_logic_vector(8#177572#,16); + constant ibaddr_ssr3 : slv16 := conv_std_logic_vector(8#172516#,16); + + constant ssr0_ibf_abo_nonres : integer := 15; + constant ssr0_ibf_abo_length : integer := 14; + constant ssr0_ibf_abo_rdonly : integer := 13; + constant ssr0_ibf_trap_mmu : integer := 12; + constant ssr0_ibf_ena_trap : integer := 9; + constant ssr0_ibf_inst_compl : integer := 7; + subtype ssr0_ibf_seg_mode is integer range 6 downto 5; + constant ssr0_ibf_dspace : integer := 4; + subtype ssr0_ibf_seg_num is integer range 3 downto 1; + constant ssr0_ibf_ena_mmu : integer := 0; + + constant ssr3_ibf_ena_ubmap : integer := 5; + constant ssr3_ibf_ena_22bit : integer := 4; + constant ssr3_ibf_dspace_km : integer := 2; + constant ssr3_ibf_dspace_sm : integer := 1; + constant ssr3_ibf_dspace_um : integer := 0; + + signal IBSEL_SSR0 : slbit := '0'; -- ibus select SSR0 + signal IBSEL_SSR3 : slbit := '0'; -- ibus select SSR3 + + signal R_SSR0 : mmu_ssr0_type := mmu_ssr0_init; + signal N_SSR0 : mmu_ssr0_type := mmu_ssr0_init; + + signal R_SSR3 : mmu_ssr3_type := mmu_ssr3_init; + + signal ASN : slv4 := "0000"; -- augmented segment number (1+3 bit) + signal AIB_WE : slbit := '0'; -- update AIB + signal AIB_SETA : slbit := '0'; -- set A bit in access information bits + signal AIB_SETW : slbit := '0'; -- set W bit in access information bits + + signal TRACE : slbit := '0'; -- enable tracing in ssr1/2 + signal DSPACE : slbit := '0'; -- use dspace + + signal IB_SRES_SADR : ib_sres_type := ib_sres_init; + signal IB_SRES_SSR12 : ib_sres_type := ib_sres_init; + signal IB_SRES_SSR03 : ib_sres_type := ib_sres_init; + + signal SARSDR : sarsdr_type := sarsdr_init; + +begin + + SADR : pdp11_mmu_sadr port map ( + CLK => CLK, + MODE => CNTL.mode, + ASN => ASN, + AIB_WE => AIB_WE, + AIB_SETA => AIB_SETA, + AIB_SETW => AIB_SETW, + SARSDR => SARSDR, + IB_MREQ => IB_MREQ, + IB_SRES => IB_SRES_SADR); + + SSR12 : pdp11_mmu_ssr12 port map ( + CLK => CLK, + CRESET => CRESET, + TRACE => TRACE, + MONI => MONI, + IB_MREQ => IB_MREQ, + IB_SRES => IB_SRES_SSR12); + + IB_SRES_OR : ib_sres_or_3 + port map ( + IB_SRES_1 => IB_SRES_SADR, + IB_SRES_2 => IB_SRES_SSR12, + IB_SRES_3 => IB_SRES_SSR03, + IB_SRES_OR => IB_SRES); + + proc_ibsel: process (IB_MREQ) + variable issr0 : slbit := '0'; + variable issr3 : slbit := '0'; + begin + issr0 := '0'; + issr3 := '0'; + if IB_MREQ.req = '1' then + if IB_MREQ.addr = ibaddr_ssr0(12 downto 1) then issr0 := '1'; end if; + if IB_MREQ.addr = ibaddr_ssr3(12 downto 1) then issr3 := '1'; end if; + end if; + IBSEL_SSR0 <= issr0; + IBSEL_SSR3 <= issr3; + IB_SRES_SSR03.ack <= issr0 or issr3; + IB_SRES_SSR03.busy <= '0'; + end process proc_ibsel; + + proc_ibdout : process (IBSEL_SSR0, IBSEL_SSR3, R_SSR0, R_SSR3) + + variable ssr0out : slv16 := (others=>'0'); + variable ssr3out : slv16 := (others=>'0'); + + begin + + ssr0out := (others=>'0'); + if IBSEL_SSR0 = '1' then + ssr0out(ssr0_ibf_abo_nonres) := R_SSR0.abo_nonres; + ssr0out(ssr0_ibf_abo_length) := R_SSR0.abo_length; + ssr0out(ssr0_ibf_abo_rdonly) := R_SSR0.abo_rdonly; + ssr0out(ssr0_ibf_trap_mmu) := R_SSR0.trap_mmu; + ssr0out(ssr0_ibf_ena_trap) := R_SSR0.ena_trap; + ssr0out(ssr0_ibf_inst_compl) := R_SSR0.inst_compl; + ssr0out(ssr0_ibf_seg_mode) := R_SSR0.seg_mode; + ssr0out(ssr0_ibf_dspace) := R_SSR0.dspace; + ssr0out(ssr0_ibf_seg_num) := R_SSR0.seg_num; + ssr0out(ssr0_ibf_ena_mmu) := R_SSR0.ena_mmu; + end if; + + ssr3out := (others=>'0'); + if IBSEL_SSR3 = '1' then + ssr3out(ssr3_ibf_ena_ubmap) := R_SSR3.ena_ubmap; + ssr3out(ssr3_ibf_ena_22bit) := R_SSR3.ena_22bit; + ssr3out(ssr3_ibf_dspace_km) := R_SSR3.dspace_km; + ssr3out(ssr3_ibf_dspace_sm) := R_SSR3.dspace_sm; + ssr3out(ssr3_ibf_dspace_um) := R_SSR3.dspace_um; + end if; + + IB_SRES_SSR03.dout <= ssr0out or ssr3out; + + end process proc_ibdout; + + proc_ssr0 : process (CLK) + begin + if CLK'event and CLK='1' then + if BRESET = '1' then + R_SSR0 <= mmu_ssr0_init; + else + R_SSR0 <= N_SSR0; + end if; + end if; + end process proc_ssr0; + + proc_ssr3 : process (CLK) + begin + if CLK'event and CLK='1' then + if BRESET = '1' then + R_SSR3 <= mmu_ssr3_init; + elsif IB_MREQ.we='1' and IBSEL_SSR3='1' then + if IB_MREQ.be0 = '1' then + R_SSR3.ena_ubmap <= IB_MREQ.din(ssr3_ibf_ena_ubmap); + R_SSR3.ena_22bit <= IB_MREQ.din(ssr3_ibf_ena_22bit); + R_SSR3.dspace_km <= IB_MREQ.din(ssr3_ibf_dspace_km); + R_SSR3.dspace_sm <= IB_MREQ.din(ssr3_ibf_dspace_sm); + R_SSR3.dspace_um <= IB_MREQ.din(ssr3_ibf_dspace_um); + end if; + end if; + end if; + end process proc_ssr3; + + proc_paddr : process (R_SSR0, R_SSR3, CNTL, SARSDR, VADDR) + + variable ipaddrh : slv16 := (others=>'0'); + variable dspace_ok : slbit := '0'; + variable dspace_en : slbit := '0'; + variable asf : slv3 := (others=>'0'); -- va: active segment field + variable bn : slv7 := (others=>'0'); -- va: block number + variable iasn : slv4 := (others=>'0');-- augmented segment number + + begin + + asf := VADDR(15 downto 13); + bn := VADDR(12 downto 6); + + dspace_en := '0'; + case CNTL.mode is + when "00" => dspace_en := R_SSR3.dspace_km; + when "01" => dspace_en := R_SSR3.dspace_sm; + when "11" => dspace_en := R_SSR3.dspace_um; + when others => null; + end case; + dspace_ok := CNTL.dspace and dspace_en; + + iasn(3) := dspace_ok; + iasn(2 downto 0) := asf; + + ipaddrh := unsigned("000000000"&bn) + unsigned(SARSDR.saf); + + DSPACE <= dspace_ok; + ASN <= iasn; + PADDRH <= ipaddrh; + + end process proc_paddr; + + proc_nssr0 : process (R_SSR0, R_SSR3, IB_MREQ, IBSEL_SSR0, DSPACE, + CNTL, MONI, SARSDR, VADDR) + + variable nssr0 : mmu_ssr0_type := mmu_ssr0_init; + variable asf : slv3 := (others=>'0'); + variable bn : slv7 := (others=>'0'); + variable abo_nonres : slbit := '0'; + variable abo_length : slbit := '0'; + variable abo_rdonly : slbit := '0'; + variable ssr_freeze : slbit := '0'; + variable doabort : slbit := '0'; + variable dotrap : slbit := '0'; + variable dotrace : slbit := '0'; + + begin + + nssr0 := R_SSR0; + + AIB_WE <= '0'; + AIB_SETA <= '0'; + AIB_SETW <= '0'; + + ssr_freeze := R_SSR0.abo_nonres or R_SSR0.abo_length or R_SSR0.abo_rdonly; + dotrace := not(CNTL.cacc or ssr_freeze); + + asf := VADDR(15 downto 13); + bn := VADDR(12 downto 6); + + abo_nonres := '0'; + abo_length := '0'; + abo_rdonly := '0'; + doabort := '0'; + dotrap := '0'; + + if SARSDR.ed = '0' then -- ed=0: upward expansion + if unsigned(bn) > unsigned(SARSDR.slf) then + abo_length := '1'; + end if; + else -- ed=0: downward expansion + if unsigned(bn) < unsigned(SARSDR.slf) then + abo_length := '1'; + end if; + end if; + + case SARSDR.acf is -- evaluate accecc control field + + when "000" => -- segment non-resident + abo_nonres := '1'; + + when "001" => -- read-only; trap on read + if CNTL.wacc='1' or CNTL.macc='1' then + abo_rdonly := '1'; + end if; + dotrap := '1'; + + when "010" => -- read-only + if CNTL.wacc='1' or CNTL.macc='1' then + abo_rdonly := '1'; + end if; + + when "100" => -- read/write; trap on read&write + dotrap := '1'; + + when "101" => -- read/write; trap on write + dotrap := CNTL.wacc or CNTL.macc; + + when "110" => null; -- read/write; + + when others => -- unused codes: abort access + abo_nonres := '1'; + end case; + + if IB_MREQ.we='1' and IBSEL_SSR0='1' then + + if IB_MREQ.be1 = '1' then + nssr0.abo_nonres := IB_MREQ.din(ssr0_ibf_abo_nonres); + nssr0.abo_length := IB_MREQ.din(ssr0_ibf_abo_length); + nssr0.abo_rdonly := IB_MREQ.din(ssr0_ibf_abo_rdonly); + nssr0.trap_mmu := IB_MREQ.din(ssr0_ibf_trap_mmu); + nssr0.ena_trap := IB_MREQ.din(ssr0_ibf_ena_trap); + end if; + if IB_MREQ.be0 = '1' then + nssr0.ena_mmu := IB_MREQ.din(ssr0_ibf_ena_mmu); + end if; + + elsif nssr0.ena_mmu='1' and CNTL.cacc='0' then + + if dotrace = '1' then + if MONI.istart = '1' then + nssr0.inst_compl := '0'; + elsif MONI.idone = '1' then + nssr0.inst_compl := '0'; -- disable instr.compl logic + end if; + end if; + + if CNTL.req = '1' then + AIB_WE <= '1'; + if ssr_freeze = '0' then + nssr0.abo_nonres := abo_nonres; + nssr0.abo_length := abo_length; + nssr0.abo_rdonly := abo_rdonly; + end if; + doabort := abo_nonres or abo_length or abo_rdonly; + + if doabort = '0' then + AIB_SETA <= '1'; + AIB_SETW <= CNTL.wacc or CNTL.macc; + end if; + + if ssr_freeze = '0' then + nssr0.dspace := DSPACE; + nssr0.seg_num := asf; + nssr0.seg_mode := CNTL.mode; + end if; + end if; + end if; + + if CNTL.req='1' and R_SSR0.ena_mmu='1' and CNTL.cacc='0' and + dotrap='1' then + nssr0.trap_mmu := '1'; + end if; + + nssr0.trace_prev := dotrace; + + if MONI.trace_prev = '0' then + TRACE <= dotrace; + else + TRACE <= R_SSR0.trace_prev; + end if; + + N_SSR0 <= nssr0; + + if R_SSR0.ena_mmu='1' and CNTL.cacc='0' then + STAT.vaok <= not doabort; + else + STAT.vaok <= '1'; + end if; + + if R_SSR0.ena_mmu='1' and CNTL.cacc='0' and doabort='0' and + R_SSR0.ena_trap='1' and R_SSR0.trap_mmu='0' and dotrap='1' then + STAT.trap <= '1'; + else + STAT.trap <= '0'; + end if; + + STAT.ena_mmu <= R_SSR0.ena_mmu; + STAT.ena_22bit <= R_SSR3.ena_22bit; + STAT.ena_ubmap <= R_SSR3.ena_ubmap; + + end process proc_nssr0; + +end syn; diff --git a/rtl/w11a/pdp11_mmu_sadr.vbom b/rtl/w11a/pdp11_mmu_sadr.vbom new file mode 100644 index 00000000..696da376 --- /dev/null +++ b/rtl/w11a/pdp11_mmu_sadr.vbom @@ -0,0 +1,10 @@ +# libs +../vlib/slvtypes.vhd +../vlib/memlib/memlib.vhd +../ibus/iblib.vhd +pdp11.vbom +# components +[ghdl,isim]../vlib/memlib/ram_1swar_gen.vbom +[xst]../vlib/memlib/ram_1swar_gen_unisim.vbom +# design +pdp11_mmu_sadr.vhd diff --git a/rtl/w11a/pdp11_mmu_sadr.vhd b/rtl/w11a/pdp11_mmu_sadr.vhd new file mode 100644 index 00000000..6ced955a --- /dev/null +++ b/rtl/w11a/pdp11_mmu_sadr.vhd @@ -0,0 +1,264 @@ +-- $Id: pdp11_mmu_sadr.vhd 314 2010-07-09 17:38:41Z mueller $ +-- +-- Copyright 2006-2008 by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, 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 complete details. +-- +------------------------------------------------------------------------------ +-- Module Name: pdp11_mmu_sadr - syn +-- Description: pdp11: mmu SAR/SDR register set +-- +-- Dependencies: memlib/ram_1swar_gen +-- +-- Test bench: tb/tb_pdp11_core (implicit) +-- Target Devices: generic +-- Tool versions: xst 8.1, 8.2, 9.1, 9.2; ghdl 0.18-0.25 +-- Revision History: +-- Date Rev Version Comment +-- 2008-08-22 161 1.2.2 rename ubf_ -> ibf_; use iblib +-- 2008-01-05 110 1.2.1 rename _mmu_regs -> _mmu_sadr +-- rename IB_MREQ(ena->req) SRES(sel->ack, hold->busy) +-- 2008-01-01 109 1.2 renamed from _mmu_regfile. +-- redesign of _mmu register file, use one large dram. +-- logic from _mmu_regfile, interface from _mmu_regset +-- 2007-12-30 108 1.1.1 use ubf_byte[01]; move SADR memory address mux here +-- 2007-12-30 107 1.1 use IB_MREQ/IB_SRES interface now +-- 2007-06-14 56 1.0.1 Use slvtypes.all +-- 2007-05-12 26 1.0 Initial version +------------------------------------------------------------------------------ + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; + +use work.slvtypes.all; +use work.memlib.all; +use work.iblib.all; +use work.pdp11.all; + +-- ---------------------------------------------------------------------------- + +entity pdp11_mmu_sadr is -- mmu SAR/SDR register set + port ( + CLK : in slbit; -- clock + MODE : in slv2; -- mode + ASN : in slv4; -- augmented segment number (1+3 bit) + AIB_WE : in slbit; -- update AIB + AIB_SETA : in slbit; -- set access AIB + AIB_SETW : in slbit; -- set write AIB + SARSDR : out sarsdr_type; -- combined SAR/SDR + IB_MREQ : in ib_mreq_type; -- ibus request + IB_SRES : out ib_sres_type -- ibus response + ); +end pdp11_mmu_sadr; + +architecture syn of pdp11_mmu_sadr is + + -- bit 1 111 1 + -- bit 5 432 109 876 543 210 + -- + -- kmdr 172300 -> 1 111 010 011 000 000 + -- kmar 172340 -> 1 111 010 011 100 000 + -- smdr 172200 -> 1 111 010 010 000 000 + -- smar 172240 -> 1 111 010 010 100 000 + -- umdr 177600 -> 1 111 111 110 000 000 + -- umar 177640 -> 1 111 111 110 100 000 + -- + -- mode => (addr(8), not addr(6)) [Note: km "00" sm "01" um "11"] + + constant ibaddr_kmdar : slv16 := conv_std_logic_vector(8#172300#,16); + constant ibaddr_smdar : slv16 := conv_std_logic_vector(8#172200#,16); + constant ibaddr_umdar : slv16 := conv_std_logic_vector(8#177600#,16); + + subtype sdr_ibf_slf is integer range 14 downto 8; + subtype sdr_ibf_aib is integer range 7 downto 6; + subtype sdr_ibf_acf is integer range 3 downto 0; + + signal SADR_ADDR : slv6 := (others=>'0'); -- address (from mmu or ibus) + + signal SAR_HIGH_WE : slbit := '0'; -- write enables + signal SAR_LOW_WE : slbit := '0'; -- ... + signal SDR_SLF_WE : slbit := '0'; -- ... + signal SDR_AIB_WE : slbit := '0'; -- ... + signal SDR_LOW_WE : slbit := '0'; -- ... + + signal IBSEL_DR : slbit := '0'; + signal IBSEL_AR : slbit := '0'; + + signal SAF : slv16 := (others=>'0'); -- current SAF + signal SLF : slv7 := (others=>'0'); -- current SLF + signal AIB : slv2 := "00"; -- current AIB flags + signal NEXT_AIB : slv2 := "00"; -- next AIB flags + signal ED_ACF : slv4 := "0000"; -- current ED & ACF + +begin + + SAR_HIGH : ram_1swar_gen + generic map ( + AWIDTH => 6, + DWIDTH => 8) + port map ( + CLK => CLK, + WE => SAR_HIGH_WE, + ADDR => SADR_ADDR, + DI => IB_MREQ.din(ibf_byte1), + DO => SAF(ibf_byte1)); + + SAR_LOW : ram_1swar_gen + generic map ( + AWIDTH => 6, + DWIDTH => 8) + port map ( + CLK => CLK, + WE => SAR_LOW_WE, + ADDR => SADR_ADDR, + DI => IB_MREQ.din(ibf_byte0), + DO => SAF(ibf_byte0)); + + SDR_SLF : ram_1swar_gen + generic map ( + AWIDTH => 6, + DWIDTH => 7) + port map ( + CLK => CLK, + WE => SDR_SLF_WE, + ADDR => SADR_ADDR, + DI => IB_MREQ.din(sdr_ibf_slf), + DO => SLF); + + SDR_AIB : ram_1swar_gen + generic map ( + AWIDTH => 6, + DWIDTH => 2) + port map ( + CLK => CLK, + WE => SDR_AIB_WE, + ADDR => SADR_ADDR, + DI => NEXT_AIB, + DO => AIB); + + SDR_LOW : ram_1swar_gen + generic map ( + AWIDTH => 6, + DWIDTH => 4) + port map ( + CLK => CLK, + WE => SDR_LOW_WE, + ADDR => SADR_ADDR, + DI => IB_MREQ.din(sdr_ibf_acf), + DO => ED_ACF); + + -- determibe IBSEL's and the address for accessing the SADR's + + proc_ibsel: process (IB_MREQ, MODE, ASN) + variable iaddr : slv6 := (others=>'0'); + variable idr : slbit := '0'; + variable iar : slbit := '0'; + begin + + iaddr := MODE & ASN; + idr := '0'; + iar := '0'; + + if IB_MREQ.req = '1' then + iaddr(5) := IB_MREQ.addr(8); + iaddr(4) := not IB_MREQ.addr(6); + iaddr(3 downto 0) := IB_MREQ.addr(4 downto 1); + if IB_MREQ.addr(12 downto 6)=ibaddr_kmdar(12 downto 6) or + IB_MREQ.addr(12 downto 6)=ibaddr_smdar(12 downto 6) or + IB_MREQ.addr(12 downto 6)=ibaddr_umdar(12 downto 6) then + if IB_MREQ.addr(5) = '0' then + idr := '1'; + else + iar := '1'; + end if; + end if; + end if; + + SADR_ADDR <= iaddr; +-- SADR_ADDR <= iaddr(3) & iaddr(5 downto 4) & iaddr(2 downto 0); + IBSEL_DR <= idr; + IBSEL_AR <= iar; + IB_SRES.ack <= idr or iar; + IB_SRES.busy <= '0'; + + end process proc_ibsel; + + proc_ubdout : process (IBSEL_DR, IBSEL_AR, SAF, SLF, AIB, ED_ACF) + variable sarout : slv16 := (others=>'0'); -- IB sar out + variable sdrout : slv16 := (others=>'0'); -- IB sdr out + begin + + sarout := (others=>'0'); + if IBSEL_AR = '1' then + sarout := SAF; + end if; + + sdrout := (others=>'0'); + if IBSEL_DR = '1' then + sdrout(sdr_ibf_slf) := SLF; + sdrout(sdr_ibf_aib) := AIB; + sdrout(sdr_ibf_acf) := ED_ACF; + end if; + + IB_SRES.dout <= sarout or sdrout; + + end process proc_ubdout; + + proc_comb : process (IBSEL_AR, IBSEL_DR, IB_MREQ, AIB_WE, AIB_SETA, AIB_SETW, + SAF, SLF, AIB, ED_ACF) + begin + + NEXT_AIB <= "00"; + SAR_HIGH_WE <= '0'; + SAR_LOW_WE <= '0'; + SDR_SLF_WE <= '0'; + SDR_AIB_WE <= '0'; + SDR_LOW_WE <= '0'; + + if IB_MREQ.we = '1' then + if IBSEL_AR = '1' then + if IB_MREQ.be1 = '1' then + SAR_HIGH_WE <= '1'; + end if; + if IB_MREQ.be0 = '1' then + SAR_LOW_WE <= '1'; + end if; + end if; + + if IBSEL_DR = '1' then + if IB_MREQ.be1 = '1' then + SDR_SLF_WE <= '1'; + end if; + if IB_MREQ.be0 = '1' then + SDR_LOW_WE <= '1'; + end if; + end if; + + if (IBSEL_AR or IBSEL_DR)='1' then + NEXT_AIB <= "00"; + SDR_AIB_WE <= '1'; + end if; + end if; + + if AIB_WE = '1' then + NEXT_AIB(0) <= AIB(0) or AIB_SETW; + NEXT_AIB(1) <= AIB(1) or AIB_SETA; + SDR_AIB_WE <= '1'; + end if; + + SARSDR.saf <= SAF; + SARSDR.slf <= SLF; + SARSDR.ed <= ED_ACF(3); + SARSDR.acf <= ED_ACF(2 downto 0); + + end process proc_comb; + +end syn; diff --git a/rtl/w11a/pdp11_mmu_ssr12.vbom b/rtl/w11a/pdp11_mmu_ssr12.vbom new file mode 100644 index 00000000..c06f6c92 --- /dev/null +++ b/rtl/w11a/pdp11_mmu_ssr12.vbom @@ -0,0 +1,6 @@ +# libs +../vlib/slvtypes.vhd +../ibus/iblib.vhd +pdp11.vbom +# design +pdp11_mmu_ssr12.vhd diff --git a/rtl/w11a/pdp11_mmu_ssr12.vhd b/rtl/w11a/pdp11_mmu_ssr12.vhd new file mode 100644 index 00000000..94444d72 --- /dev/null +++ b/rtl/w11a/pdp11_mmu_ssr12.vhd @@ -0,0 +1,185 @@ +-- $Id: pdp11_mmu_ssr12.vhd 314 2010-07-09 17:38:41Z mueller $ +-- +-- Copyright 2006-2009 by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, 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 complete details. +-- +------------------------------------------------------------------------------ +-- Module Name: pdp11_mmu_ssr12 - syn +-- Description: pdp11: mmu register ssr1 and ssr2 +-- +-- Dependencies: - +-- Test bench: tb/tb_pdp11_core (implicit) +-- Target Devices: generic +-- Tool versions: xst 8.1, 8.2, 9.1, 9.2; ghdl 0.18-0.25 +-- Revision History: +-- Revision History: +-- Date Rev Version Comment +-- 2009-05-30 220 1.1.4 final removal of snoopers (were already commented) +-- 2008-08-22 161 1.1.3 rename ubf_ -> ibf_; use iblib +-- 2008-03-02 121 1.1.2 remove snoopers +-- 2008-01-05 110 1.1.1 rename IB_MREQ(ena->req) SRES(sel->ack, hold->busy) +-- 2007-12-30 107 1.1 use IB_MREQ/IB_SRES interface now +-- 2007-06-14 56 1.0.1 Use slvtypes.all +-- 2007-05-12 26 1.0 Initial version +------------------------------------------------------------------------------ + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; + +use work.slvtypes.all; +use work.iblib.all; +use work.pdp11.all; + +-- ---------------------------------------------------------------------------- + +entity pdp11_mmu_ssr12 is -- mmu register ssr1 and ssr2 + port ( + CLK : in slbit; -- clock + CRESET : in slbit; -- console reset + TRACE : in slbit; -- trace enable + MONI : in mmu_moni_type; -- MMU monitor port data + IB_MREQ : in ib_mreq_type; -- ibus request + IB_SRES : out ib_sres_type -- ibus response + ); +end pdp11_mmu_ssr12; + +architecture syn of pdp11_mmu_ssr12 is + + constant ibaddr_ssr1 : slv16 := conv_std_logic_vector(8#177574#,16); + constant ibaddr_ssr2 : slv16 := conv_std_logic_vector(8#177576#,16); + + subtype ssr1_ibf_rb_delta is integer range 15 downto 11; + subtype ssr1_ibf_rb_num is integer range 10 downto 8; + subtype ssr1_ibf_ra_delta is integer range 7 downto 3; + subtype ssr1_ibf_ra_num is integer range 2 downto 0; + + signal IBSEL_SSR1 : slbit := '0'; + signal IBSEL_SSR2 : slbit := '0'; + signal R_SSR1 : mmu_ssr1_type := mmu_ssr1_init; + signal R_SSR2 : slv16 := (others=>'0'); + signal NEXT_SSR1 : mmu_ssr1_type := mmu_ssr1_init; + signal NEXT_SSR2 : slv16 := (others=>'0'); + +begin + + proc_ibsel: process (IB_MREQ) + variable issr1 : slbit := '0'; + variable issr2 : slbit := '0'; + begin + issr1 := '0'; + issr2 := '0'; + if IB_MREQ.req = '1' then + if IB_MREQ.addr = ibaddr_ssr1(12 downto 1) then issr1 := '1'; end if; + if IB_MREQ.addr = ibaddr_ssr2(12 downto 1) then issr2 := '1'; end if; + end if; + IBSEL_SSR1 <= issr1; + IBSEL_SSR2 <= issr2; + IB_SRES.ack <= issr1 or issr2; + IB_SRES.busy <= '0'; + end process proc_ibsel; + + proc_ubdout : process (IBSEL_SSR1, IBSEL_SSR2, R_SSR1, R_SSR2) + variable ssr1out : slv16 := (others=>'0'); + variable ssr2out : slv16 := (others=>'0'); + begin + + ssr1out := (others=>'0'); + if IBSEL_SSR1 = '1' then + ssr1out(ssr1_ibf_rb_delta) := R_SSR1.rb_delta; + ssr1out(ssr1_ibf_rb_num) := R_SSR1.rb_num; + ssr1out(ssr1_ibf_ra_delta) := R_SSR1.ra_delta; + ssr1out(ssr1_ibf_ra_num) := R_SSR1.ra_num; + end if; + + ssr2out := (others=>'0'); + if IBSEL_SSR2 = '1' then + ssr2out := R_SSR2; + end if; + + IB_SRES.dout <= ssr1out or ssr2out; + + end process proc_ubdout; + + proc_regs : process (CLK) + begin + if CLK'event and CLK='1' then + R_SSR1 <= NEXT_SSR1; + R_SSR2 <= NEXT_SSR2; + end if; + end process proc_regs; + + proc_comb : process (CRESET, IBSEL_SSR1, IB_MREQ, + R_SSR1, R_SSR2, TRACE, MONI) + + variable nssr1 : mmu_ssr1_type := mmu_ssr1_init; + variable nssr2 : slv16 := (others=>'0'); + variable delta : slv5 := (others=>'0'); + variable use_rb : slbit := '0'; + + begin + + nssr1 := R_SSR1; + nssr2 := R_SSR2; + delta := "0" & MONI.delta; + + use_rb := '0'; + if MONI.regnum/=nssr1.ra_num and unsigned(nssr1.ra_delta)/=0 then + use_rb := '1'; + end if; + + if CRESET = '1' then + nssr1 := mmu_ssr1_init; + nssr2 := (others=>'0'); + + elsif IBSEL_SSR1='1' and IB_MREQ.we='1' then + + if IB_MREQ.be1 = '1' then + nssr1.rb_delta := IB_MREQ.din(ssr1_ibf_rb_delta); + nssr1.rb_num := IB_MREQ.din(ssr1_ibf_rb_num); + end if; + if IB_MREQ.be0 = '1' then + nssr1.ra_delta := IB_MREQ.din(ssr1_ibf_ra_delta); + nssr1.ra_num := IB_MREQ.din(ssr1_ibf_ra_num); + end if; + + elsif TRACE = '1' then + + if MONI.istart = '1' then + nssr1 := mmu_ssr1_init; + nssr2 := MONI.pc; + + elsif MONI.regmod = '1' then + if use_rb = '0' then + nssr1.ra_num := MONI.regnum; + if MONI.isdec = '0' then + nssr1.ra_delta := signed(nssr1.ra_delta) + signed(delta); + else + nssr1.ra_delta := signed(nssr1.ra_delta) - signed(delta); + end if; + else + nssr1.rb_num := MONI.regnum; + if MONI.isdec = '0' then + nssr1.rb_delta := signed(nssr1.rb_delta) + signed(delta); + else + nssr1.rb_delta := signed(nssr1.rb_delta) - signed(delta); + end if; + end if; + end if; + + end if; + + NEXT_SSR1 <= nssr1; + NEXT_SSR2 <= nssr2; + + end process proc_comb; + +end syn; diff --git a/rtl/w11a/pdp11_psr.vbom b/rtl/w11a/pdp11_psr.vbom new file mode 100644 index 00000000..e852fa37 --- /dev/null +++ b/rtl/w11a/pdp11_psr.vbom @@ -0,0 +1,6 @@ +# libs +../vlib/slvtypes.vhd +../ibus/iblib.vhd +pdp11.vbom +# design +pdp11_psr.vhd diff --git a/rtl/w11a/pdp11_psr.vhd b/rtl/w11a/pdp11_psr.vhd new file mode 100644 index 00000000..b7866d43 --- /dev/null +++ b/rtl/w11a/pdp11_psr.vhd @@ -0,0 +1,167 @@ +-- $Id: pdp11_psr.vhd 314 2010-07-09 17:38:41Z mueller $ +-- +-- Copyright 2006-2009 by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, 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 complete details. +-- +------------------------------------------------------------------------------ +-- Module Name: pdp11_psr - syn +-- Description: pdp11: processor status word register +-- +-- Dependencies: - +-- Test bench: tb/tb_pdp11_core (implicit) +-- Target Devices: generic +-- Tool versions: xst 8.1, 8.2, 9.1, 9.2; ghdl 0.18-0.25 +-- Revision History: +-- Date Rev Version Comment +-- 2009-05-30 220 1.1.4 final removal of snoopers (were already commented) +-- 2008-08-22 161 1.1.3 rename ubf_ -> ibf_; use iblib +-- 2008-03-02 121 1.1.2 remove snoopers +-- 2008-01-05 110 1.1.1 rename IB_MREQ(ena->req) SRES(sel->ack, hold->busy) +-- 2007-12-30 107 1.1 use IB_MREQ/IB_SRES interface now +-- 2007-06-14 56 1.0.1 Use slvtypes.all +-- 2007-05-12 26 1.0 Initial version +------------------------------------------------------------------------------ + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; + +use work.slvtypes.all; +use work.iblib.all; +use work.pdp11.all; + +-- ---------------------------------------------------------------------------- + +entity pdp11_psr is -- processor status word register + port ( + CLK : in slbit; -- clock + CRESET : in slbit; -- console reset + DIN : in slv16; -- input data + CCIN : in slv4; -- cc input + CCWE : in slbit; -- enable update cc + WE : in slbit; -- write enable (from DIN) + FUNC : in slv3; -- write function (from DIN) + PSW : out psw_type; -- current psw + IB_MREQ : in ib_mreq_type; -- ibus request + IB_SRES : out ib_sres_type -- ibus response + ); +end pdp11_psr; + +architecture syn of pdp11_psr is + + constant ibaddr_psr : slv16 := conv_std_logic_vector(8#177776#,16); + + signal IBSEL_PSR : slbit := '0'; + signal R_PSW : psw_type := psw_init; -- ps register + +begin + + proc_ibsel: process (IB_MREQ) + variable ipsr : slbit := '0'; + begin + ipsr := '0'; + if IB_MREQ.req='1' and IB_MREQ.addr=ibaddr_psr(12 downto 1) then + ipsr := '1'; + end if; + IBSEL_PSR <= ipsr; + IB_SRES.ack <= ipsr; + IB_SRES.busy <= '0'; + end process proc_ibsel; + + proc_ibdout: process (IBSEL_PSR, R_PSW) + variable pswout : slv16 := (others=>'0'); + begin + pswout := (others=>'0'); + if IBSEL_PSR = '1' then + pswout(psw_ibf_cmode) := R_PSW.cmode; + pswout(psw_ibf_pmode) := R_PSW.pmode; + pswout(psw_ibf_rset) := R_PSW.rset; + pswout(psw_ibf_pri) := R_PSW.pri; + pswout(psw_ibf_tflag) := R_PSW.tflag; + pswout(psw_ibf_cc) := R_PSW.cc; + end if; + IB_SRES.dout <= pswout; + end process proc_ibdout; + + proc_psw : process (CLK) + begin + + if CLK'event and CLK='1' then + + if CRESET = '1' then + R_PSW <= psw_init; + + else + + if CCWE = '1' then + R_PSW.cc <= CCIN; + end if; + + if WE = '1' then + case FUNC is + when c_psr_func_wspl => -- wspl + R_PSW.pri <= DIN(2 downto 0); + + when c_psr_func_wcc => -- wcc + if DIN(4) = '1' then -- set cc opcodes + R_PSW.cc <= R_PSW.cc or DIN(3 downto 0); + else -- clear cc opcodes + R_PSW.cc <= R_PSW.cc and not DIN(3 downto 0); + end if; + + when c_psr_func_wint => -- wint (interupt handling) + R_PSW.cmode <= DIN(psw_ibf_cmode); + R_PSW.pmode <= R_PSW.cmode; -- save current mode + R_PSW.rset <= DIN(psw_ibf_rset); + R_PSW.pri <= DIN(psw_ibf_pri); + R_PSW.tflag <= DIN(psw_ibf_tflag); + R_PSW.cc <= DIN(psw_ibf_cc); + + when c_psr_func_wrti => -- wrti (rti/rtt in non-kernel mode) + R_PSW.cmode <= R_PSW.cmode or DIN(psw_ibf_cmode); + R_PSW.pmode <= R_PSW.pmode or DIN(psw_ibf_pmode) or + R_PSW.cmode or DIN(psw_ibf_cmode); + R_PSW.rset <= R_PSW.rset or DIN(psw_ibf_rset); + R_PSW.tflag <= DIN(psw_ibf_tflag); + R_PSW.cc <= DIN(psw_ibf_cc); + + when c_psr_func_wall => -- wall (rti/rtt kernel mode) + R_PSW.cmode <= DIN(psw_ibf_cmode); + R_PSW.pmode <= DIN(psw_ibf_pmode); + R_PSW.rset <= DIN(psw_ibf_rset); + R_PSW.pri <= DIN(psw_ibf_pri); + R_PSW.tflag <= DIN(psw_ibf_tflag); + R_PSW.cc <= DIN(psw_ibf_cc); + + when others => null; + end case; + end if; + end if; + + if IBSEL_PSR='1' and IB_MREQ.we='1' then + if IB_MREQ.be1 = '1' then + R_PSW.cmode <= IB_MREQ.din(psw_ibf_cmode); + R_PSW.pmode <= IB_MREQ.din(psw_ibf_pmode); + R_PSW.rset <= IB_MREQ.din(psw_ibf_rset); + end if; + if IB_MREQ.be0 = '1' then + R_PSW.pri <= IB_MREQ.din(psw_ibf_pri); + R_PSW.cc <= IB_MREQ.din(psw_ibf_cc); + end if; + end if; + + end if; + + end process proc_psw; + + PSW <= R_PSW; + +end syn; diff --git a/rtl/w11a/pdp11_sequencer.vbom b/rtl/w11a/pdp11_sequencer.vbom new file mode 100644 index 00000000..188b6f35 --- /dev/null +++ b/rtl/w11a/pdp11_sequencer.vbom @@ -0,0 +1,6 @@ +# libs +../vlib/slvtypes.vhd +../ibus/iblib.vhd +pdp11.vbom +# design +pdp11_sequencer.vhd diff --git a/rtl/w11a/pdp11_sequencer.vhd b/rtl/w11a/pdp11_sequencer.vhd new file mode 100644 index 00000000..c997c72a --- /dev/null +++ b/rtl/w11a/pdp11_sequencer.vhd @@ -0,0 +1,2274 @@ +-- $Id: pdp11_sequencer.vhd 314 2010-07-09 17:38:41Z mueller $ +-- +-- Copyright 2006-2010 by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, 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 complete details. +-- +------------------------------------------------------------------------------ +-- Module Name: pdp11_sequencer - syn +-- Description: pdp11: CPU sequencer +-- +-- Dependencies: - +-- Test bench: tb/tb_pdp11_core (implicit) +-- Target Devices: generic +-- Tool versions: xst 8.1, 8.2, 9.1, 9.2; ghdl 0.18-0.25 +-- Revision History: +-- Date Rev Version Comment +-- 2010-06-20 307 1.3.1 rename cpacc to cacc in vm_cntl_type +-- 2010-06-13 305 1.3 remove CPDIN_WE, CPDOUT_WE out ports; set +-- CNTL.cpdout_we instead of CPDOUT_WE +-- 2010-06-12 304 1.2.8 signal cpuwait when spinning in s_op_wait +-- 2009-05-30 220 1.2.7 final removal of snoopers (were already commented) +-- 2009-05-09 213 1.2.6 BUGFIX: use is_dstkstack1246, stklim for mode=6 +-- 2009-05-02 211 1.2.5 BUGFIX: 11/70 spl semantics again in kernel mode +-- 2009-04-26 209 1.2.4 BUGFIX: give interrupts priority over trap handling +-- 2008-12-14 177 1.2.3 BUGFIX: use is_dstkstack124, fix stklim check bug +-- 2008-12-13 176 1.2.2 BUGFIX: use is_pci in s_dstw_inc if DSTDEF='1' +-- 2008-11-30 174 1.2.1 BUGFIX: add updt_dstadsrc; prevent stale DSRC +-- 2008-08-22 161 1.2 rename ubf_ -> ibf_; use iblib +-- 2008-05-03 143 1.1.9 rename _cpursta->_cpurust; cp reset sets now +-- c_cpurust_reset; proper c_cpurust_vfail handling +-- 2008-04-27 140 1.1.8 BUGFIX: halt cpu in case of a vector fetch error +-- use cpursta to encode why cpu halts, remove cpufail +-- 2008-04-27 139 1.1.7 BUGFIX: correct bytop handling for address fetches; +-- BUGFIX: redo mtp flow; add fork_dsta fork and ddst +-- reload in s_opa_mtp_pop_w; +-- 2008-04-19 137 1.1.6 BUGFIX: fix loop state in s_rti_getpc_w +-- 2008-03-30 131 1.1.5 BUGFIX: inc/dec by 2 for byte mode -(sp),(sp)+ +-- inc/dec by 2 for @(R)+ and @-(R) also for bytop's +-- 2008-03-02 121 1.1.4 remove snoopers; add waitsusp, redo WAIT handling +-- 2008-02-24 119 1.1.3 add lah,rps,wps command; revamp cp memory access +-- change WAIT logic, now also bails out on cp command +-- 2008-01-20 112 1.1.2 rename PRESET->BRESET +-- 2008-01-05 110 1.1.1 rename IB_MREQ(ena->req) SRES(sel->ack, hold->busy) +-- 2007-12-30 107 1.1 use IB_MREQ/IB_SRES interface now +-- 2007-06-14 56 1.0.1 Use slvtypes.all +-- 2007-05-12 26 1.0 Initial version +------------------------------------------------------------------------------ + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; + +use work.slvtypes.all; +use work.iblib.all; +use work.pdp11.all; + +-- ---------------------------------------------------------------------------- + +entity pdp11_sequencer is -- CPU sequencer + port ( + CLK : in slbit; -- clock + GRESET : in slbit; -- global reset + PSW : in psw_type; -- processor status + PC : in slv16; -- program counter + IREG : in slv16; -- IREG + ID_STAT : in decode_stat_type; -- instr. decoder status + DP_STAT : in dpath_stat_type; -- data path status + CP_CNTL : in cp_cntl_type; -- console port control + VM_STAT : in vm_stat_type; -- virtual memory status port + INT_PRI : in slv3; -- interrupt priority + INT_VECT : in slv9_2; -- interrupt vector + CRESET : out slbit; -- console reset + BRESET : out slbit; -- ibus reset + MMU_MONI : out mmu_moni_type; -- mmu monitor port + DP_CNTL : out dpath_cntl_type; -- data path control + VM_CNTL : out vm_cntl_type; -- virtual memory control port + CP_STAT : out cp_stat_type; -- console port status + INT_ACK : out slbit; -- interrupt acknowledge + IB_MREQ : in ib_mreq_type; -- ibus request + IB_SRES : out ib_sres_type -- ibus response + ); +end pdp11_sequencer; + +architecture syn of pdp11_sequencer is + + constant ibaddr_cpuerr : slv16 := conv_std_logic_vector(8#177766#,16); + + constant cpuerr_ibf_illhlt : integer := 7; + constant cpuerr_ibf_adderr : integer := 6; + constant cpuerr_ibf_nxm : integer := 5; + constant cpuerr_ibf_iobto : integer := 4; + constant cpuerr_ibf_ysv : integer := 3; + constant cpuerr_ibf_rsv : integer := 2; + + type state_type is ( + s_idle, + s_cp_regread, + s_cp_rps, + s_cp_memr_w, + s_cp_memw_w, + s_ifetch, + s_ifetch_w, + s_idecode, + + s_srcr_def, + s_srcr_def_w, + s_srcr_inc, + s_srcr_inc_w, + s_srcr_dec, + s_srcr_dec1, + s_srcr_ind, + s_srcr_ind1_w, + s_srcr_ind2, + s_srcr_ind2_w, + + s_dstr_def, + s_dstr_def_w, + s_dstr_inc, + s_dstr_inc_w, + s_dstr_dec, + s_dstr_dec1, + s_dstr_ind, + s_dstr_ind1_w, + s_dstr_ind2, + s_dstr_ind2_w, + + s_dstw_def, + s_dstw_def_w, + s_dstw_inc, + s_dstw_inc_w, + s_dstw_incdef_w, + s_dstw_dec, + s_dstw_dec1, + s_dstw_ind, + s_dstw_ind_w, + s_dstw_def246, + + s_dsta_inc, + s_dsta_incdef_w, + s_dsta_dec, + s_dsta_dec1, + s_dsta_ind, + s_dsta_ind_w, + + s_op_halt, + s_op_wait, + s_op_trap, + s_op_reset, + s_op_rts, + s_op_rts_pop, + s_op_rts_pop_w, + s_op_spl, + s_op_mcc, + s_op_br, + s_op_mark, + s_op_mark1, + s_op_mark_pop, + s_op_mark_pop_w, + s_op_sob, + s_op_sob1, + + s_opg_gen, + s_opg_gen_rmw_w, + s_opg_mul, + s_opg_mul1, + s_opg_div, + s_opg_div_cn, + s_opg_div_cr, + s_opg_div_sq, + s_opg_div_sr, + s_opg_div_zero, + s_opg_ash, + s_opg_ash_cn, + s_opg_ashc, + s_opg_ashc_cn, + s_opg_ashc_wl, + + s_opa_jsr, + s_opa_jsr1, + s_opa_jsr_push, + s_opa_jsr_push_w, + s_opa_jsr2, + s_opa_jmp, + s_opa_mtp, + s_opa_mtp_pop_w, + s_opa_mtp_reg, + s_opa_mtp_mem, + s_opa_mtp_mem_w, + s_opa_mfp_reg, + s_opa_mfp_mem, + s_opa_mfp_mem_w, + s_opa_mfp_dec, + s_opa_mfp_push, + s_opa_mfp_push_w, + + s_trap_4, + s_trap_10, + s_trap_disp, + + s_int_ext, + + s_int_getpc, + s_int_getpc_w, + s_int_getps, + s_int_getps_w, + s_int_getsp, + s_int_decsp, + s_int_pushps, + s_int_pushps_w, + s_int_pushpc, + s_int_pushpc_w, + + s_rti_getpc, + s_rti_getpc_w, + s_rti_getps, + s_rti_getps_w, + s_rti_newpc, + + s_vmerr, + s_cpufail + ); + + signal R_STATE : state_type := s_idle; -- state register + signal N_STATE : state_type := s_idle; + + signal R_STATUS : cpustat_type := cpustat_init; + signal N_STATUS : cpustat_type := cpustat_init; + signal R_CPUERR : cpuerr_type := cpuerr_init; + signal N_CPUERR : cpuerr_type := cpuerr_init; + + signal R_IDSTAT : decode_stat_type := decode_stat_init; + signal N_IDSTAT : decode_stat_type := decode_stat_init; + + signal R_VMSTAT : vm_stat_type := vm_stat_init; + + signal IBSEL_CPUERR : slbit := '0'; + +begin + + proc_ibsel: process (IB_MREQ) + variable icpuerr : slbit := '0'; + begin + icpuerr := '0'; + if IB_MREQ.req='1' and IB_MREQ.addr=ibaddr_cpuerr(12 downto 1) then + icpuerr := '1'; + end if; + IBSEL_CPUERR <= icpuerr; + IB_SRES.ack <= icpuerr; + IB_SRES.busy <= '0'; + end process proc_ibsel; + + proc_ibdout : process (IBSEL_CPUERR, R_CPUERR) + variable cpuerrout : slv16 := (others=>'0'); + begin + cpuerrout := (others=>'0'); + if IBSEL_CPUERR = '1' then + cpuerrout(cpuerr_ibf_illhlt) := R_CPUERR.illhlt; + cpuerrout(cpuerr_ibf_adderr) := R_CPUERR.adderr; + cpuerrout(cpuerr_ibf_nxm) := R_CPUERR.nxm; + cpuerrout(cpuerr_ibf_iobto) := R_CPUERR.iobto; + cpuerrout(cpuerr_ibf_ysv) := R_CPUERR.ysv; + cpuerrout(cpuerr_ibf_rsv) := R_CPUERR.rsv; + end if; + IB_SRES.dout <= cpuerrout; + end process proc_ibdout; + + proc_status: process (CLK) + begin + if CLK'event and CLK='1' then + if GRESET = '1' then + R_STATUS <= cpustat_init; + R_CPUERR <= cpuerr_init; + R_IDSTAT <= decode_stat_init; + R_VMSTAT <= vm_stat_init; + else + R_STATUS <= N_STATUS; + R_CPUERR <= N_CPUERR; + R_IDSTAT <= N_IDSTAT; + R_VMSTAT <= VM_STAT; + end if; + end if; + end process proc_status; + + proc_state: process (CLK) + begin + if CLK'event and CLK='1' then + if GRESET = '1' then + R_STATE <= s_idle; + else + R_STATE <= N_STATE; + end if; + end if; + end process proc_state; + + proc_next: process (R_STATE, R_STATUS, PSW, PC, CP_CNTL, + ID_STAT, R_IDSTAT, IREG, VM_STAT, DP_STAT, + R_CPUERR, R_VMSTAT, IB_MREQ, IBSEL_CPUERR, + INT_PRI, INT_VECT) + + variable nstate : state_type; + variable nstatus : cpustat_type := cpustat_init; + variable ncpuerr : cpuerr_type := cpuerr_init; + + variable ncreset : slbit := '0'; + variable nbreset : slbit := '0'; + variable nintack : slbit := '0'; + + variable ndpcntl : dpath_cntl_type := dpath_cntl_init; + variable nvmcntl : vm_cntl_type := vm_cntl_init; + variable nidstat : decode_stat_type := decode_stat_init; + variable nmmumoni : mmu_moni_type := mmu_moni_init; + + variable imemok : boolean; + variable bytop : slbit := '0'; -- local bytop access flag + variable macc : slbit := '0'; -- local modify access flag + + variable lvector : slv9_2 := (others=>'0'); -- local trap/interrupt vector + + variable brcode : slv4 := (others=>'0'); -- reduced br opcode (15,10-8) + variable brcond : slbit := '0'; -- br condition value + + variable is_kmode : slbit := '0'; -- cmode is kernel mode + variable is_dstkstack1246 : slbit := '0'; -- dest is k-stack & mode= 1,2,4,6 + + variable int_pending : slbit := '0'; -- an interrupt is pending + + alias SRCMOD : slv2 is IREG(11 downto 10); -- src register mode high + alias SRCDEF : slbit is IREG(9); -- src register mode defered + alias SRCREG : slv3 is IREG(8 downto 6); -- src register number + alias DSTMODF : slv3 is IREG(5 downto 3); -- dst register full mode + alias DSTMOD : slv2 is IREG(5 downto 4); -- dst register mode high + alias DSTDEF : slbit is IREG(3); -- dst register mode defered + alias DSTREG : slv3 is IREG(2 downto 0); -- dst register number + + procedure do_memread_i(nstate : inout state_type; + ndpcntl : inout dpath_cntl_type; + nvmcntl : inout vm_cntl_type; + wstate : in state_type) is + begin + ndpcntl.vmaddr_sel := c_dpath_vmaddr_pc; -- VA = PC + nvmcntl.dspace := '0'; + nvmcntl.req := '1'; + ndpcntl.gpr_pcinc := '1'; -- (pc)++ + nstate := wstate; + end procedure do_memread_i; + + procedure do_memread_d(nstate : inout state_type; + nvmcntl : inout vm_cntl_type; + wstate : in state_type; + bytop : in slbit := '0'; + macc : in slbit := '0'; + is_pci : in slbit := '0') is + begin + nvmcntl.dspace := not is_pci; -- ispace if pc immediate modes +-- bytop := R_IDSTAT.is_bytop and not is_addr; + nvmcntl.bytop := bytop; + nvmcntl.macc := macc; + nvmcntl.req := '1'; + nstate := wstate; + end procedure do_memread_d; + + procedure do_memread_srcinc(nstate : inout state_type; + ndpcntl : inout dpath_cntl_type; + nvmcntl : inout vm_cntl_type; + wstate : in state_type; + nmmumoni : inout mmu_moni_type; + updt_sp : in slbit := '0') is + begin + ndpcntl.abox_asel := c_abox_asel_dsrc; -- ABOX A=DSRC + ndpcntl.abox_const := "000000010"; -- ABOX const=2 + ndpcntl.abox_bsel := c_abox_bsel_const; -- ABOX B=const + ndpcntl.dres_sel := c_dpath_res_abox; -- DRES = ABOX + ndpcntl.dsrc_sel := c_dpath_dsrc_res; -- DSRC = DRES + ndpcntl.dsrc_we := '1'; -- update DSRC + if updt_sp = '1' then + nmmumoni.regmod := '1'; + nmmumoni.isdec := '0'; + ndpcntl.gpr_adst := c_gpr_sp; -- update SP too + ndpcntl.gpr_we := '1'; + end if; + ndpcntl.vmaddr_sel := c_dpath_vmaddr_dsrc; -- VA = DSRC + nvmcntl.dspace := '1'; + nvmcntl.req := '1'; + nstate := wstate; + end procedure do_memread_srcinc; + + procedure do_memwrite(nstate : inout state_type; + nvmcntl : inout vm_cntl_type; + wstate : in state_type; + macc : in slbit :='0') is + begin + nvmcntl.dspace := '1'; + nvmcntl.bytop := R_IDSTAT.is_bytop; + nvmcntl.wacc := '1'; + nvmcntl.macc := macc; + nvmcntl.req := '1'; + nstate := wstate; + end procedure do_memwrite; + + procedure do_memcheck(nstate : inout state_type; + nstatus : inout cpustat_type; + mok : out boolean) is + begin + mok := false; + if VM_STAT.ack = '1' then + mok := true; + nstatus.trap_mmu := VM_STAT.trap_mmu; + if R_CPUERR.ysv = '0' then -- ysv trap when cpuerr not yet set + nstatus.trap_ysv := VM_STAT.trap_ysv; + end if; + elsif VM_STAT.err='1' or VM_STAT.fail='1' then + nstate := s_vmerr; + end if; + end procedure do_memcheck; + + procedure do_const_opsize(ndpcntl : inout dpath_cntl_type; + bytop : in slbit; + isdef : in slbit; + regnum : in slv3) is + begin + if bytop='0' or isdef='1' or + regnum=c_gpr_pc or regnum=c_gpr_sp then + ndpcntl.abox_const := "000000010"; + else + ndpcntl.abox_const := "000000001"; + end if; + end procedure do_const_opsize; + + procedure do_fork_dstr(nstate : inout state_type; + idstat : in decode_stat_type) is + begin + case idstat.fork_dstr is + when c_fork_dstr_def => nstate := s_dstr_def; + when c_fork_dstr_inc => nstate := s_dstr_inc; + when c_fork_dstr_dec => nstate := s_dstr_dec; + when c_fork_dstr_ind => nstate := s_dstr_ind; + when others => nstate := s_cpufail; + end case; + end procedure do_fork_dstr; + + procedure do_fork_opg(nstate : inout state_type; + idstat : in decode_stat_type) is + begin + case idstat.fork_opg is + when c_fork_opg_gen => nstate := s_opg_gen; + when c_fork_opg_wdef => nstate := s_dstw_def; + when c_fork_opg_winc => nstate := s_dstw_inc; + when c_fork_opg_wdec => nstate := s_dstw_dec; + when c_fork_opg_wind => nstate := s_dstw_ind; + when c_fork_opg_mul => nstate := s_opg_mul; + when c_fork_opg_div => nstate := s_opg_div; + when c_fork_opg_ash => nstate := s_opg_ash; + when c_fork_opg_ashc => nstate := s_opg_ashc; + when others => nstate := s_cpufail; + end case; + end procedure do_fork_opg; + + procedure do_fork_opa(nstate : inout state_type; + idstat : in decode_stat_type) is + begin + case idstat.fork_opa is + when c_fork_opa_jmp => nstate := s_opa_jmp; + when c_fork_opa_jsr => nstate := s_opa_jsr; + when c_fork_opa_mtp => nstate := s_opa_mtp_mem; + when c_fork_opa_mfp_reg => nstate := s_opa_mfp_reg; + when c_fork_opa_mfp_mem => nstate := s_opa_mfp_mem; + when others => nstate := s_cpufail; + end case; + end procedure do_fork_opa; + + procedure do_fork_next(nstate : inout state_type; + nstatus : inout cpustat_type; + nmmumoni : inout mmu_moni_type) is + begin + nmmumoni.idone := '1'; + if unsigned(INT_PRI) > unsigned(PSW.pri) then + nstate := s_idle; + elsif R_STATUS.trap_mmu='1' or nstatus.trap_mmu='1' or + R_STATUS.trap_ysv='1' or nstatus.trap_ysv='1' or + PSW.tflag='1' then + nstate := s_trap_disp; + elsif R_STATUS.cpugo='1' and not R_STATUS.cmdbusy='1' then + nstate := s_ifetch; + else + nstate := s_idle; + end if; + end procedure do_fork_next; + + procedure do_fork_next_pref(nstate : inout state_type; + nstatus : inout cpustat_type; + ndpcntl : inout dpath_cntl_type; + nvmcntl : inout vm_cntl_type; + nmmumoni : inout mmu_moni_type) is + begin + nmmumoni.idone := '1'; + if unsigned(INT_PRI) > unsigned(PSW.pri) then + nstate := s_idle; + elsif R_STATUS.trap_mmu='1' or nstatus.trap_mmu='1' or + R_STATUS.trap_ysv='1' or nstatus.trap_ysv='1' or + PSW.tflag='1' then + nstate := s_trap_disp; + elsif R_STATUS.cpugo='1' and not R_STATUS.cmdbusy='1' then + nvmcntl.req := '1'; + ndpcntl.gpr_pcinc := '1'; + nmmumoni.istart := '1'; + nstate := s_ifetch_w; + else + nstate := s_idle; + end if; + end procedure do_fork_next_pref; + + procedure do_start_int(nstate : inout state_type; + ndpcntl : inout dpath_cntl_type; + vector : in slv9_2) is + begin + ndpcntl.dtmp_sel := c_dpath_dtmp_psw; -- DTMP = PSW + ndpcntl.dtmp_we := '1'; + ndpcntl.abox_azero := '1'; -- ABOX A = 0 + ndpcntl.abox_const := vector & "00"; -- vector + ndpcntl.abox_bsel := c_abox_bsel_const; -- ABOX B=const(vector) + ndpcntl.dres_sel := c_dpath_res_abox; -- DRES = ABOX + ndpcntl.dsrc_sel := c_dpath_dsrc_res; -- DSRC = DRES + ndpcntl.dsrc_we := '1'; -- DSRC = vector + nstate := s_int_getpc; + end procedure do_start_int; + + begin + + nstate := R_STATE; + nstatus := R_STATUS; + ncpuerr := R_CPUERR; + + nstatus.cpuwait := '0'; -- wait flag 0 unless set in s_op_wait + + ncreset := '0'; + nbreset := '0'; + nintack := '0'; + + nidstat := R_IDSTAT; + + if IB_MREQ.we='1' and IBSEL_CPUERR='1' then -- write to CPUERR clears it !! + ncpuerr := cpuerr_init; + end if; + + int_pending := '0'; + if unsigned(INT_PRI) > unsigned(PSW.pri) then + int_pending := '1'; + end if; + + imemok := false; + + nmmumoni := mmu_moni_init; + nmmumoni.pc := PC; + + macc := '0'; + bytop := '0'; + brcode := IREG(15) & IREG(10 downto 8); + brcond := '1'; + + is_kmode := '0'; + is_dstkstack1246 := '0'; + + if PSW.cmode = c_psw_kmode then + is_kmode := '1'; + if DSTREG = c_gpr_sp and + (DSTMODF="001" or DSTMODF="010" or + DSTMODF="100" or DSTMODF="110") then + is_dstkstack1246 := '1'; + end if; + end if; + + lvector := (others=>'0'); + + nvmcntl := vm_cntl_init; + nvmcntl.dspace := '1'; -- DEFAULT + nvmcntl.mode := PSW.cmode; -- DEFAULT + nvmcntl.intrsv := R_STATUS.do_intrsv; -- DEFAULT + + ndpcntl := dpath_cntl_init; + ndpcntl.gpr_asrc := SRCREG; -- DEFAULT + ndpcntl.gpr_adst := DSTREG; -- DEFAULT + ndpcntl.gpr_mode := PSW.cmode; -- DEFAULT + ndpcntl.gpr_rset := PSW.rset; -- DEFAULT + ndpcntl.gpr_we := '0'; -- DEFAULT + ndpcntl.gpr_bytop := '0'; -- DEFAULT + ndpcntl.gpr_pcinc := '0'; -- DEFAULT + + ndpcntl.psr_ccwe := '0'; -- DEFAULT + ndpcntl.psr_we := '0'; -- DEFAULT + ndpcntl.psr_func := "000"; -- DEFAULT + + ndpcntl.dsrc_sel := c_dpath_dsrc_src; + ndpcntl.dsrc_we := '0'; + ndpcntl.ddst_sel := c_dpath_ddst_dst; + ndpcntl.ddst_we := '0'; + ndpcntl.dtmp_sel := c_dpath_dtmp_dsrc; + ndpcntl.dtmp_we := '0'; + + ndpcntl.abox_asel := c_abox_asel_ddst; + ndpcntl.abox_azero := '0'; -- DEFAULT + ndpcntl.abox_const := (others=>'0'); -- DEFAULT + ndpcntl.abox_bsel := c_abox_bsel_const; + ndpcntl.abox_opsub := '0'; -- DEFAULT + + ndpcntl.dbox_srcmod := R_IDSTAT.dbox_srcmod; -- STATIC + ndpcntl.dbox_dstmod := R_IDSTAT.dbox_dstmod; -- STATIC + ndpcntl.dbox_cimod := R_IDSTAT.dbox_cimod; -- STATIC + ndpcntl.dbox_cc1op := R_IDSTAT.dbox_cc1op; -- STATIC + ndpcntl.dbox_ccmode := R_IDSTAT.dbox_ccmode; -- STATIC + ndpcntl.dbox_bytop := R_IDSTAT.is_bytop; -- STATIC + + ndpcntl.lbox_func := R_IDSTAT.lbox_func; -- STATIC + ndpcntl.lbox_bytop := R_IDSTAT.is_bytop; -- STATIC + + ndpcntl.mbox_func := R_IDSTAT.mbox_func; -- STATIC + + ndpcntl.ireg_we := '0'; + + ndpcntl.cres_sel := R_IDSTAT.res_sel; -- DEFAULT + ndpcntl.dres_sel := c_dpath_res_abox; + ndpcntl.vmaddr_sel := c_dpath_vmaddr_dsrc; + + if CP_CNTL.req='1' and R_STATUS.cmdbusy='0' then + nstatus.cmdbusy := '1'; + nstatus.cpfunc := CP_CNTL.func; + nstatus.cprnum := CP_CNTL.rnum; + end if; + + if R_STATUS.cmdack = '1' then + nstatus.cmdack := '0'; + nstatus.cmderr := '0'; + nstatus.cmdmerr := '0'; + end if; + + case R_STATE is + + -- idle and command port states --------------------------------------------- + + -- Note: s_idle was entered from suspended WAIT when waitsusp='1' + -- --> all exits must check this and either return to s_op_wait + -- or abort the WAIT and set waitsusp='0' + + when s_idle => + + ndpcntl.vmaddr_sel := c_dpath_vmaddr_ddst; -- VA = DDST (do mux early) + nstatus.cpustep := '0'; + + if R_STATUS.cmdbusy = '1' then + case R_STATUS.cpfunc is + + when c_cpfunc_noop => -- noop : no operation -------- + nstatus.cmdack := '1'; + nstate := s_idle; + + when c_cpfunc_sta => -- sta : cpu start ----------- + ncreset := '1'; + nstatus.cmdack := '1'; + nstatus.cpugo := '1'; + nstatus.cpuhalt := '0'; + nstatus.cpurust := c_cpurust_runs; + nstatus.waitsusp := '0'; + nstate := s_idle; + + when c_cpfunc_sto => -- sto : cpu stop ------------ + nstatus.cmdack := '1'; + nstatus.cpugo := '0'; + nstatus.cpurust := c_cpurust_stop; + nstatus.waitsusp := '0'; + nstate := s_idle; + + when c_cpfunc_cont => -- cont : cpu continue -------- + nstatus.cmdack := '1'; + nstatus.cpugo := '1'; + nstatus.cpuhalt := '0'; + nstatus.cpurust := c_cpurust_runs; + nstatus.waitsusp := '0'; + nstate := s_idle; + + when c_cpfunc_step => -- step : cpu step ------------ + nstatus.cmdack := '1'; + nstatus.cpustep := '1'; + nstatus.cpuhalt := '0'; + nstatus.cpurust := c_cpurust_step; + nstatus.waitsusp := '0'; + if int_pending = '1' then + nintack := '1'; + nstatus.intvect := INT_VECT; + nstate := s_int_ext; + else + nstate := s_ifetch; + end if; + + when c_cpfunc_rst => -- rst : cpu reset (soft) ---- + ncreset := '1'; + nstatus.cmdack := '1'; + nstatus.cpugo := '0'; + nstatus.cpuhalt := '0'; + nstatus.cpurust := c_cpurust_reset; + nstatus.waitsusp := '0'; + nstate := s_idle; + + when c_cpfunc_rreg => -- rreg : read register ------ + ndpcntl.gpr_adst := R_STATUS.cprnum; + ndpcntl.ddst_sel := c_dpath_ddst_dst; + ndpcntl.ddst_we := '1'; + nstate := s_cp_regread; + + when c_cpfunc_wreg => -- wreg : write register ----- + ndpcntl.dres_sel := c_dpath_res_cpdin; -- DRES = CPDIN + ndpcntl.gpr_adst := R_STATUS.cprnum; + ndpcntl.gpr_we := '1'; + nstatus.cmdack := '1'; + nstate := s_idle; + + when c_cpfunc_rpsw => -- rpsw : read psw ----------- + ndpcntl.dtmp_sel := c_dpath_dtmp_psw; -- DTMP = PSW + ndpcntl.dtmp_we := '1'; + nstate := s_cp_rps; + + when c_cpfunc_wpsw => -- wpsw : write psw ---------- + ndpcntl.dres_sel := c_dpath_res_cpdin; -- DRES = CPDIN + ndpcntl.psr_func := c_psr_func_wall; -- write all fields + ndpcntl.psr_we := '1'; -- load new PS + nstatus.cmdack := '1'; + nstate := s_idle; + + when c_cpfunc_rmem => -- rmem : read memory -------- + nvmcntl.cacc := '1'; + nvmcntl.req := '1'; + nstate := s_cp_memr_w; + + when c_cpfunc_wmem => -- wmem : write memory ------- + ndpcntl.dres_sel := c_dpath_res_cpdin; -- DRES = CPDIN + nvmcntl.wacc := '1'; -- write mem + nvmcntl.cacc := '1'; + nvmcntl.req := '1'; + nstate := s_cp_memw_w; + + when others => + nstatus.cmdack := '1'; + nstatus.cmderr := '1'; + nstate := s_idle; + + end case; + + elsif R_STATUS.waitsusp = '1' then + nstatus.waitsusp := '0'; + nstate := s_op_wait; + + elsif R_STATUS.cpugo = '1' then + if int_pending = '1' then + nintack := '1'; + nstatus.intvect := INT_VECT; + nstate := s_int_ext; + else + nstate := s_ifetch; + end if; + + end if; + + when s_cp_regread => + ndpcntl.abox_asel := c_abox_asel_ddst; -- ABOX A = DDST + ndpcntl.abox_bsel := c_abox_bsel_const; -- ABOX B = const(0) + ndpcntl.dres_sel := c_dpath_res_abox; -- DRES = ABOX + nstatus.cmdack := '1'; + nstate := s_idle; + + when s_cp_rps => + ndpcntl.abox_asel := c_abox_asel_dtmp; -- ABOX A = DTMP + ndpcntl.abox_bsel := c_abox_bsel_const; -- ABOX B = const(0) + ndpcntl.dres_sel := c_dpath_res_abox; -- DRES = ABOX + nstatus.cmdack := '1'; + nstate := s_idle; + + when s_cp_memr_w => + nstate := s_cp_memr_w; + ndpcntl.dres_sel := c_dpath_res_vmdout; -- DRES = VMDOUT + if (VM_STAT.ack or VM_STAT.err or VM_STAT.fail)='1' then + nstatus.cmdack := '1'; + nstatus.trap_ysv := '0'; -- suppress traps on console + nstatus.trap_mmu := '0'; + nstatus.cmdmerr := VM_STAT.err or VM_STAT.fail; + nstate := s_idle; + end if; + + when s_cp_memw_w => + nstate := s_cp_memw_w; + if (VM_STAT.ack or VM_STAT.err or VM_STAT.fail)='1' then + nstatus.cmdack := '1'; + nstatus.trap_ysv := '0'; -- suppress traps on console + nstatus.trap_mmu := '0'; + nstatus.cmdmerr := VM_STAT.err or VM_STAT.fail; + nstate := s_idle; + end if; + + -- instruction fetch and decode --------------------------------------------- + + when s_ifetch => + nmmumoni.istart := '1'; -- do here; memread_i inc PC ! + do_memread_i(nstate, ndpcntl, nvmcntl, s_ifetch_w); + + when s_ifetch_w => + nstate := s_ifetch_w; + do_memcheck(nstate, nstatus, imemok); + if imemok then + ndpcntl.ireg_we := '1'; + nstate := s_idecode; + end if; + + when s_idecode => + nidstat := ID_STAT; -- register decode status + if ID_STAT.force_srcsp = '1' then + ndpcntl.gpr_asrc := c_gpr_sp; + end if; + ndpcntl.dsrc_sel := c_dpath_dsrc_src; + ndpcntl.dsrc_we := '1'; + ndpcntl.ddst_sel := c_dpath_ddst_dst; + ndpcntl.ddst_we := '1'; + + nvmcntl.dspace := '0'; + ndpcntl.vmaddr_sel := c_dpath_vmaddr_pc; -- VA = PC + + if ID_STAT.do_pref_dec='1' and PSW.tflag='0' and int_pending='0' and + R_STATUS.cpugo='1' and not R_STATUS.cmdbusy='1' + then + nvmcntl.req := '1'; + ndpcntl.gpr_pcinc := '1'; -- (pc)++ + nmmumoni.istart := '1'; + nstatus.prefdone := '1'; + end if; + + if ID_STAT.do_fork_op = '1' then + case ID_STAT.fork_op is + when c_fork_op_halt => nstate := s_op_halt; + when c_fork_op_wait => nstate := s_op_wait; + when c_fork_op_rtti => nstate := s_rti_getpc; + when c_fork_op_trap => nstate := s_op_trap; + when c_fork_op_reset=> nstate := s_op_reset; + when c_fork_op_rts => nstate := s_op_rts; + when c_fork_op_spl => nstate := s_op_spl; + when c_fork_op_mcc => nstate := s_op_mcc; + when c_fork_op_br => nstate := s_op_br; + when c_fork_op_mark => nstate := s_op_mark; + when c_fork_op_sob => nstate := s_op_sob; + when c_fork_op_mtp => nstate := s_opa_mtp; + when others => nstate := s_cpufail; + end case; + elsif ID_STAT.do_fork_srcr = '1' then + case ID_STAT.fork_srcr is + when c_fork_srcr_def => nstate := s_srcr_def; + when c_fork_srcr_inc => nstate := s_srcr_inc; + when c_fork_srcr_dec => nstate := s_srcr_dec; + when c_fork_srcr_ind => nstate := s_srcr_ind; + when others => nstate := s_cpufail; + end case; + elsif ID_STAT.do_fork_dstr = '1' then + do_fork_dstr(nstate, ID_STAT); + elsif ID_STAT.do_fork_dsta = '1' then + case ID_STAT.fork_dsta is -- 2nd dsta fork in s_opa_mtp_pop_w + when c_fork_dsta_def => do_fork_opa(nstate, ID_STAT); + when c_fork_dsta_inc => nstate := s_dsta_inc; + when c_fork_dsta_dec => nstate := s_dsta_dec; + when c_fork_dsta_ind => nstate := s_dsta_ind; + when others => nstate := s_cpufail; + end case; + elsif ID_STAT.do_fork_opg = '1' then + do_fork_opg(nstate, ID_STAT); + elsif ID_STAT.is_res = '1' then + nstate := s_trap_10; -- do trap 10; + else + nstate := s_cpufail; -- catch mistakes here... + end if; + + -- source read states ------------------------------------------------------- + -- flows: + -- 1 (r) s_srcr_def req (r) + -- s_srcr_def_w get (r) + -- -> do_fork_dstr or do_fork_opg + -- + -- 2 (r)+ s_srcr_inc req (r); r+=s + -- s_srcr_inc_w get (r) + -- -> do_fork_dstr or do_fork_opg + -- + -- 3 @(r)+ s_srcr_inc req (r); r+=s + -- s_srcr_inc_w get (r) + -- s_srcr_def req @(r) + -- s_srcr_def_w get @(r) + -- -> do_fork_dstr or do_fork_opg + -- + -- 4 -(r) s_srcr_dec r-=s + -- s_srcr_dec1 req (r) + -- s_srcr_inc_w get (r) + -- -> do_fork_dstr or do_fork_opg + -- + -- 5 @-(r) s_srcr_dec r-=s + -- s_srcr_dec1 req (r) + -- s_srcr_inc_w get (r) + -- s_srcr_def req @(r) + -- s_srcr_def_w get @(r) + -- -> do_fork_dstr or do_fork_opg + -- + -- 6 n(r) s_srcr_ind req n + -- s_srcr_ind1_w get n; ea=r+n + -- s_srcr_ind2 req n(r) + -- s_srcr_ind2_w get n(r) + -- -> do_fork_dstr or do_fork_opg + -- + -- 7 @n(r) s_srcr_ind req n + -- s_srcr_ind1_w get n; ea=r+n + -- s_srcr_ind2 req n(r) + -- s_srcr_ind2_w get n(r) + -- s_srcr_def req @n(r) + -- s_srcr_def_w get @n(r) + -- -> do_fork_dstr or do_fork_opg + + when s_srcr_def => + ndpcntl.vmaddr_sel := c_dpath_vmaddr_dsrc; -- VA = DSRC + do_memread_d(nstate, nvmcntl, s_srcr_def_w, + bytop=>R_IDSTAT.is_bytop, + is_pci=>R_IDSTAT.is_srcpcmode1); + + when s_srcr_def_w => + nstate := s_srcr_def_w; + do_memcheck(nstate, nstatus, imemok); + ndpcntl.dres_sel := c_dpath_res_vmdout; -- DRES = VMDOUT + ndpcntl.dsrc_sel := c_dpath_dsrc_res; -- DSRC = DRES + if imemok then + ndpcntl.dsrc_we := '1'; -- update DSRC + if R_IDSTAT.do_fork_dstr = '1' then + do_fork_dstr(nstate, R_IDSTAT); + else + do_fork_opg(nstate, R_IDSTAT); + end if; + end if; + + when s_srcr_inc => + ndpcntl.abox_asel := c_abox_asel_dsrc; -- ABOX A=DSRC + do_const_opsize(ndpcntl, R_IDSTAT.is_bytop, SRCDEF, SRCREG); + ndpcntl.abox_bsel := c_abox_bsel_const; -- ABOX B=const + ndpcntl.dres_sel := c_dpath_res_abox; -- DRES = ABOX + ndpcntl.gpr_adst := SRCREG; + ndpcntl.gpr_we := '1'; + nmmumoni.regmod := '1'; + nmmumoni.isdec := '0'; + ndpcntl.ddst_sel := c_dpath_ddst_res; -- DDST = DRES (for if) + if DSTREG = SRCREG then -- prevent stale DDST copy + ndpcntl.ddst_we := '1'; -- update DDST + end if; + ndpcntl.vmaddr_sel := c_dpath_vmaddr_dsrc; -- VA = DSRC + bytop := R_IDSTAT.is_bytop and not SRCDEF; + do_memread_d(nstate, nvmcntl, s_srcr_inc_w, + bytop=>bytop, is_pci=>R_IDSTAT.is_srcpc); + + when s_srcr_inc_w => + nstate := s_srcr_inc_w; + ndpcntl.dres_sel := c_dpath_res_vmdout; -- DRES = VMDOUT + ndpcntl.dsrc_sel := c_dpath_dsrc_res; -- DSRC = DRES + do_memcheck(nstate, nstatus, imemok); + if imemok then + ndpcntl.dsrc_we := '1'; -- update DSRC + if SRCDEF = '1' then + nstate := s_srcr_def; + else + if R_IDSTAT.do_fork_dstr = '1' then + do_fork_dstr(nstate, R_IDSTAT); + else + do_fork_opg(nstate, R_IDSTAT); + end if; + end if; + end if; + + when s_srcr_dec => + ndpcntl.abox_asel := c_abox_asel_dsrc; -- ABOX A=DSRC + do_const_opsize(ndpcntl, R_IDSTAT.is_bytop, SRCDEF, SRCREG); + ndpcntl.abox_bsel := c_abox_bsel_const; -- ABOX B=const + ndpcntl.abox_opsub := '1'; -- ABOX = A-B + ndpcntl.dres_sel := c_dpath_res_abox; -- DRES = ABOX + ndpcntl.dsrc_sel := c_dpath_dsrc_res; -- DSRC = DRES + ndpcntl.dsrc_we := '1'; -- update DSRC + ndpcntl.gpr_adst := SRCREG; + ndpcntl.gpr_we := '1'; + nmmumoni.regmod := '1'; + nmmumoni.isdec := '1'; + ndpcntl.ddst_sel := c_dpath_ddst_res; -- DDST = DRES (for if) + if DSTREG = SRCREG then -- prevent stale DDST copy + ndpcntl.ddst_we := '1'; -- update DDST + end if; + nstate := s_srcr_dec1; + + when s_srcr_dec1 => + ndpcntl.vmaddr_sel := c_dpath_vmaddr_dsrc; -- VA = DSRC + bytop := R_IDSTAT.is_bytop and not SRCDEF; + do_memread_d(nstate, nvmcntl, s_srcr_inc_w, bytop=>bytop); + + when s_srcr_ind => + do_memread_i(nstate, ndpcntl, nvmcntl, s_srcr_ind1_w); + + when s_srcr_ind1_w => + nstate := s_srcr_ind1_w; + if R_IDSTAT.is_srcpc = '0' then + ndpcntl.abox_asel := c_abox_asel_dsrc; -- ABOX A = DSRC + else + ndpcntl.abox_asel := c_abox_asel_pc; -- ABOX A = PC (for nn(pc)) + end if; + ndpcntl.abox_bsel := c_abox_bsel_vmdout; -- ABOX B = VMDOUT + ndpcntl.dres_sel := c_dpath_res_abox; -- DRES = ABOX + ndpcntl.dsrc_sel := c_dpath_dsrc_res; -- DSRC = DRES + ndpcntl.ddst_sel := c_dpath_ddst_dst; -- DDST = R(DST) + do_memcheck(nstate, nstatus, imemok); + if imemok then + ndpcntl.dsrc_we := '1'; -- update DSRC + ndpcntl.ddst_we := '1'; -- update DDST (to reload PC) + nstate := s_srcr_ind2; + end if; + + when s_srcr_ind2 => + ndpcntl.vmaddr_sel := c_dpath_vmaddr_dsrc; -- VA = DSRC + bytop := R_IDSTAT.is_bytop and not SRCDEF; + do_memread_d(nstate, nvmcntl, s_srcr_ind2_w, bytop=>bytop); + + when s_srcr_ind2_w => + nstate := s_srcr_ind2_w; + ndpcntl.dres_sel := c_dpath_res_vmdout; -- DRES = VMDOUT + ndpcntl.dsrc_sel := c_dpath_dsrc_res; -- DSRC = DRES + do_memcheck(nstate, nstatus, imemok); + if imemok then + ndpcntl.dsrc_we := '1'; -- update DSRC + if SRCDEF = '1' then + nstate := s_srcr_def; + else + if R_IDSTAT.do_fork_dstr = '1' then + do_fork_dstr(nstate, R_IDSTAT); + else + do_fork_opg(nstate, R_IDSTAT); + end if; + end if; + end if; + + -- destination read states -------------------------------------------------- + -- flows: + -- 1 (r) s_dstr_def req (r) (rmw if rmw op) + -- s_dstr_def_w get (r) + -- -> do_fork_opg + -- + -- 2 (r)+ s_dstr_inc req (r); r+=s (rmw if rmw op) + -- s_dstr_inc_w get (r) + -- -> do_fork_opg + -- + -- 3 @(r)+ s_dstr_inc req (r); r+=s + -- s_dstr_inc_w get (r) + -- s_dstr_def req @(r) (rmw if rmw op) + -- s_dstr_def_w get @(r) + -- -> do_fork_opg + -- + -- 4 -(r) s_dstr_dec r-=s + -- s_dstr_dec1 req (r) (rmw if rmw op) + -- s_dstr_inc_w get (r) + -- -> do_fork_opg + -- + -- 5 @-(r) s_dstr_dec r-=s + -- s_dstr_dec1 req (r) + -- s_dstr_inc_w get (r) + -- s_dstr_def req @(r) (rmw if rmw op) + -- s_dstr_def_w get @(r) + -- -> do_fork_opg + -- + -- 6 n(r) s_dstr_ind req n + -- s_dstr_ind1_w get n; ea=r+n + -- s_dstr_ind2 req n(r) (rmw if rmw op) + -- s_dstr_ind2_w get n(r) + -- -> do_fork_opg + -- + -- 7 @n(r) s_dstr_ind req n + -- s_dstr_ind1_w get n; ea=r+n + -- s_dstr_ind2 req n(r) + -- s_dstr_ind2_w get n(r) + -- s_dstr_def req @n(r) (rmw if rmw op) + -- s_dstr_def_w get @n(r) + -- -> do_fork_opg + + when s_dstr_def => + ndpcntl.vmaddr_sel := c_dpath_vmaddr_ddst; -- VA = DDST + do_memread_d(nstate, nvmcntl, s_dstr_def_w, + bytop=>R_IDSTAT.is_bytop, macc=>R_IDSTAT.is_rmwop); + + when s_dstr_def_w => + nstate := s_dstr_def_w; + do_memcheck(nstate, nstatus, imemok); + ndpcntl.dres_sel := c_dpath_res_vmdout; -- DRES = VMDOUT + ndpcntl.ddst_sel := c_dpath_ddst_res; -- DDST = DRES + if imemok then + ndpcntl.ddst_we := '1'; -- update DDST + do_fork_opg(nstate, R_IDSTAT); + end if; + + when s_dstr_inc => + ndpcntl.abox_asel := c_abox_asel_ddst; -- ABOX A=DDST + do_const_opsize(ndpcntl, R_IDSTAT.is_bytop, DSTDEF, DSTREG); + ndpcntl.abox_bsel := c_abox_bsel_const; -- ABOX B=const + ndpcntl.dres_sel := c_dpath_res_abox; -- DRES = ABOX + ndpcntl.gpr_adst := DSTREG; + ndpcntl.gpr_we := '1'; + nmmumoni.regmod := '1'; + nmmumoni.isdec := '0'; + ndpcntl.vmaddr_sel := c_dpath_vmaddr_ddst; -- VA = DDST + macc := R_IDSTAT.is_rmwop and not DSTDEF; + bytop := R_IDSTAT.is_bytop and not DSTDEF; + do_memread_d(nstate, nvmcntl, s_dstr_inc_w, + bytop=>bytop, macc=>macc, is_pci=>R_IDSTAT.is_dstpc); + + when s_dstr_inc_w => + nstate := s_dstr_inc_w; + ndpcntl.dres_sel := c_dpath_res_vmdout; -- DRES = VMDOUT + ndpcntl.ddst_sel := c_dpath_ddst_res; -- DDST = DRES + do_memcheck(nstate, nstatus, imemok); + if imemok then + ndpcntl.ddst_we := '1'; -- update DDST + if DSTDEF = '1' then + nstate := s_dstr_def; + else + do_fork_opg(nstate, R_IDSTAT); + end if; + end if; + + when s_dstr_dec => + ndpcntl.abox_asel := c_abox_asel_ddst; -- ABOX A=DDST + do_const_opsize(ndpcntl, R_IDSTAT.is_bytop, DSTDEF, DSTREG); + ndpcntl.abox_bsel := c_abox_bsel_const; -- ABOX B=const + ndpcntl.abox_opsub := '1'; -- ABOX = A-B + ndpcntl.dres_sel := c_dpath_res_abox; -- DRES = ABOX + ndpcntl.ddst_sel := c_dpath_ddst_res; -- DDST = DRES + ndpcntl.ddst_we := '1'; -- update DDST + ndpcntl.gpr_adst := DSTREG; + ndpcntl.gpr_we := '1'; + nmmumoni.regmod := '1'; + nmmumoni.isdec := '1'; + nstate := s_dstr_dec1; + + when s_dstr_dec1 => + ndpcntl.vmaddr_sel := c_dpath_vmaddr_ddst; -- VA = DDST + macc := R_IDSTAT.is_rmwop and not DSTDEF; + bytop := R_IDSTAT.is_bytop and not DSTDEF; + do_memread_d(nstate, nvmcntl, s_dstr_inc_w, + bytop=>bytop, macc=>macc); + + when s_dstr_ind => + do_memread_i(nstate, ndpcntl, nvmcntl, s_dstr_ind1_w); + + when s_dstr_ind1_w => + nstate := s_dstr_ind1_w; + if R_IDSTAT.is_dstpc = '0' then + ndpcntl.abox_asel := c_abox_asel_ddst; -- ABOX A = DDST + else + ndpcntl.abox_asel := c_abox_asel_pc; -- ABOX A = PC (for nn(pc)) + end if; + ndpcntl.abox_bsel := c_abox_bsel_vmdout; -- ABOX B = VMDOUT + ndpcntl.dres_sel := c_dpath_res_abox; -- DRES = ABOX + ndpcntl.ddst_sel := c_dpath_ddst_res; -- DDST = DRES + do_memcheck(nstate, nstatus, imemok); + if imemok then + ndpcntl.ddst_we := '1'; -- update DDST + nstate := s_dstr_ind2; + end if; + + when s_dstr_ind2 => + ndpcntl.vmaddr_sel := c_dpath_vmaddr_ddst; -- VA = DDST + macc := R_IDSTAT.is_rmwop and not DSTDEF; + bytop := R_IDSTAT.is_bytop and not DSTDEF; + do_memread_d(nstate, nvmcntl, s_dstr_ind2_w, + bytop=>bytop, macc=>macc); + + when s_dstr_ind2_w => + nstate := s_dstr_ind2_w; + ndpcntl.dres_sel := c_dpath_res_vmdout; -- DRES = VMDOUT + ndpcntl.ddst_sel := c_dpath_ddst_res; -- DDST = DRES + do_memcheck(nstate, nstatus, imemok); + if imemok then + ndpcntl.ddst_we := '1'; -- update DDST + if DSTDEF = '1' then + nstate := s_dstr_def; + else + do_fork_opg(nstate, R_IDSTAT); + end if; + end if; + + -- destination write states ------------------------------------------------- + -- flows: + -- 1 (r) s_dstw_def wreq (r) check kstack + -- s_dstw_def_w ack (r) + -- -> do_fork_next + -- + -- 2 (r)+ s_dstw_inc wreq (r) check kstack + -- s_dstw_inc_w ack (r); r+=s + -- -> do_fork_next + -- + -- 3 @(r)+ s_dstw_inc rreq (r); r+=s + -- s_dstw_incdef_w get (r) + -- s_dstw_def246 wreq @(r) + -- s_dstw_def_w ack @(r) + -- -> do_fork_next + -- + -- 4 -(r) s_dstw_dec r-=s + -- s_dstw_dec1 wreq (r) check kstack + -- s_dstw_def_w ack (r) + -- -> do_fork_next + -- + -- 5 @-(r) s_dstw_dec r-=s + -- s_dstw_dec1 rreq (r) + -- s_dstw_incdef_w get (r) + -- s_dstw_def246 wreq @(r) + -- s_dstw_def_w ack @(r) + -- -> do_fork_next + -- + -- 6 n(r) s_dstw_ind rreq n + -- s_dstw_ind_w get n; ea=r+n + -- s_dstw_dec1 wreq n(r) check kstack + -- s_dstw_def_w ack n(r) + -- -> do_fork_next + -- + -- 7 @n(r) s_dstw_ind rreq n + -- s_dstw_ind_w get n; ea=r+n + -- s_dstw_dec1 rreq n(r) + -- s_dstw_incdef_w get n(r) + -- s_dstw_def246 wreq @n(r) + -- s_dstw_def_w ack @n(r) + -- -> do_fork_next + + when s_dstw_def => + ndpcntl.psr_ccwe := '1'; + ndpcntl.dres_sel := R_IDSTAT.res_sel; -- DRES = choice of idec + ndpcntl.vmaddr_sel := c_dpath_vmaddr_ddst; -- VA = DDST + nvmcntl.kstack := is_dstkstack1246; + do_memwrite(nstate, nvmcntl, s_dstw_def_w); + + when s_dstw_def_w => + nstate := s_dstw_def_w; + do_memcheck(nstate, nstatus, imemok); + if imemok then + do_fork_next(nstate, nstatus, nmmumoni); + end if; + + when s_dstw_inc => + ndpcntl.psr_ccwe := '1'; + ndpcntl.vmaddr_sel := c_dpath_vmaddr_ddst; -- VA = DDST + ndpcntl.abox_asel := c_abox_asel_ddst; -- ABOX A=DDST (for else) + do_const_opsize(ndpcntl, R_IDSTAT.is_bytop, DSTDEF, DSTREG); --(...) + ndpcntl.abox_bsel := c_abox_bsel_const; -- ABOX B=const (for else) + if DSTDEF = '0' then + ndpcntl.dres_sel := R_IDSTAT.res_sel; -- DRES = choice of idec + nvmcntl.kstack := is_dstkstack1246; + do_memwrite(nstate, nvmcntl, s_dstw_inc_w); + nstatus.do_gprwe := '1'; + else + ndpcntl.dres_sel := c_dpath_res_abox; -- DRES = ABOX + ndpcntl.gpr_adst := DSTREG; + ndpcntl.gpr_we := '1'; + nmmumoni.regmod := '1'; + nmmumoni.isdec := '0'; + do_memread_d(nstate, nvmcntl, s_dstw_incdef_w, + is_pci=>R_IDSTAT.is_dstpc); + end if; + + when s_dstw_inc_w => + nstate := s_dstw_inc_w; + ndpcntl.abox_asel := c_abox_asel_ddst; -- ABOX A=DDST + do_const_opsize(ndpcntl, R_IDSTAT.is_bytop, DSTDEF, DSTREG); + ndpcntl.abox_bsel := c_abox_bsel_const; -- ABOX B=const + ndpcntl.dres_sel := c_dpath_res_abox; -- DRES = ABOX + ndpcntl.gpr_adst := DSTREG; + if R_STATUS.do_gprwe = '1' then + nmmumoni.regmod := '1'; + nmmumoni.isdec := '0'; + nmmumoni.trace_prev := '1'; -- ssr freeze of prev state + ndpcntl.gpr_we := '1'; -- update DST reg + end if; + nstatus.do_gprwe := '0'; + do_memcheck(nstate, nstatus, imemok); + if imemok then + do_fork_next(nstate, nstatus, nmmumoni); + end if; + + when s_dstw_incdef_w => + nstate := s_dstw_incdef_w; + ndpcntl.dres_sel := c_dpath_res_vmdout; -- DRES = VMDOUT + ndpcntl.ddst_sel := c_dpath_ddst_res; -- DDST = DRES + do_memcheck(nstate, nstatus, imemok); + if imemok then + ndpcntl.ddst_we := '1'; -- update DDST + nstate := s_dstw_def246; + end if; + + when s_dstw_dec => + ndpcntl.psr_ccwe := '1'; + ndpcntl.abox_asel := c_abox_asel_ddst; -- ABOX A=DDST + do_const_opsize(ndpcntl, R_IDSTAT.is_bytop, DSTDEF, DSTREG); + ndpcntl.abox_bsel := c_abox_bsel_const; -- ABOX B=const + ndpcntl.abox_opsub := '1'; -- ABOX = A-B + ndpcntl.dres_sel := c_dpath_res_abox; -- DRES = ABOX + ndpcntl.ddst_sel := c_dpath_ddst_res; -- DDST = DRES + ndpcntl.ddst_we := '1'; -- update DDST + ndpcntl.gpr_adst := DSTREG; + ndpcntl.gpr_we := '1'; + nmmumoni.regmod := '1'; + nmmumoni.isdec := '1'; + nstate := s_dstw_dec1; + + when s_dstw_dec1 => + ndpcntl.vmaddr_sel := c_dpath_vmaddr_ddst; -- VA = DDST + ndpcntl.dres_sel := R_IDSTAT.res_sel; -- DRES = from idec (for if) + if DSTDEF = '0' then + nvmcntl.kstack := is_dstkstack1246; + do_memwrite(nstate, nvmcntl, s_dstw_def_w); + else + do_memread_d(nstate, nvmcntl, s_dstw_incdef_w); + end if; + + when s_dstw_ind => + ndpcntl.psr_ccwe := '1'; + do_memread_i(nstate, ndpcntl, nvmcntl, s_dstw_ind_w); + + when s_dstw_ind_w => + nstate := s_dstw_ind_w; + if R_IDSTAT.is_dstpc = '0' then + ndpcntl.abox_asel := c_abox_asel_ddst; -- ABOX A = DDST + else + ndpcntl.abox_asel := c_abox_asel_pc; -- ABOX A = PC (for nn(pc)) + end if; + ndpcntl.abox_bsel := c_abox_bsel_vmdout; -- ABOX B = VMDOUT + ndpcntl.dres_sel := c_dpath_res_abox; -- DRES = ABOX + ndpcntl.ddst_sel := c_dpath_ddst_res; -- DDST = DRES + do_memcheck(nstate, nstatus, imemok); + if imemok then + ndpcntl.ddst_we := '1'; -- update DDST + nstate := s_dstw_dec1; + end if; + + when s_dstw_def246 => + ndpcntl.dres_sel := R_IDSTAT.res_sel; -- DRES = choice of idec + ndpcntl.vmaddr_sel := c_dpath_vmaddr_ddst; -- VA = DDST + do_memwrite(nstate, nvmcntl, s_dstw_def_w); + + -- destination address states ----------------------------------------------- + -- flows: + -- 1 (r) -> do_fork_opa + -- + -- 2 (r)+ s_dsta_inc r+=2 + -- -> do_fork_opa + -- + -- 3 @(r)+ s_dsta_inc req (r); r+=s + -- s_dsta_incdef_w get (r) + -- -> do_fork_opa + -- + -- 4 -(r) s_dsta_dec r-=s + -- s_dsta_dec1 ?? FIXME ?? what is done here ?? + -- -> do_fork_opa + -- + -- 5 @-(r) s_dsta_dec r-=s + -- s_dsta_dec1 req (r) + -- s_dsta_incdef_w get (r) + -- -> do_fork_opa + -- + -- 6 n(r) s_dsta_ind req n + -- s_dsta_ind_w get n; ea=r+n + -- s_dsta_dec1 ?? FIXME ?? what is done here ?? + -- -> do_fork_opa + -- + -- 7 @n(r) s_dsta_ind req n + -- s_dsta_ind_w get n; ea=r+n + -- s_dsta_dec1 req n(r) + -- s_dsta_incdef_w get n(r) + -- -> do_fork_opa + + when s_dsta_inc => + ndpcntl.abox_asel := c_abox_asel_ddst; -- ABOX A=DDST + ndpcntl.abox_const := "000000010"; + ndpcntl.abox_bsel := c_abox_bsel_const; -- ABOX B=const(2) + ndpcntl.dres_sel := c_dpath_res_abox; -- DRES = ABOX + ndpcntl.gpr_adst := DSTREG; + ndpcntl.gpr_we := '1'; + nmmumoni.regmod := '1'; + nmmumoni.isdec := '0'; + ndpcntl.dsrc_sel := c_dpath_dsrc_res; -- DSRC = DRES (for if) + if R_IDSTAT.updt_dstadsrc = '1' then -- prevent stale DSRC copy + ndpcntl.dsrc_we := '1'; -- update DSRC + end if; + ndpcntl.vmaddr_sel := c_dpath_vmaddr_ddst; -- VA = DDST + if DSTDEF = '0' then + do_fork_opa(nstate, R_IDSTAT); + else + do_memread_d(nstate, nvmcntl, s_dsta_incdef_w, + is_pci=>R_IDSTAT.is_dstpc); + end if; + + when s_dsta_incdef_w => + nstate := s_dsta_incdef_w; + ndpcntl.dres_sel := c_dpath_res_vmdout; -- DRES = VMDOUT + ndpcntl.ddst_sel := c_dpath_ddst_res; -- DDST = DRES + do_memcheck(nstate, nstatus, imemok); + if imemok then + ndpcntl.ddst_we := '1'; -- update DDST + do_fork_opa(nstate, R_IDSTAT); + end if; + + when s_dsta_dec => + ndpcntl.abox_asel := c_abox_asel_ddst; -- ABOX A=DDST + ndpcntl.abox_const := "000000010"; + ndpcntl.abox_bsel := c_abox_bsel_const; -- ABOX B=const(2) + ndpcntl.abox_opsub := '1'; -- ABOX = A-B + ndpcntl.dres_sel := c_dpath_res_abox; -- DRES = ABOX + ndpcntl.ddst_sel := c_dpath_ddst_res; -- DDST = DRES + ndpcntl.ddst_we := '1'; -- update DDST + ndpcntl.gpr_adst := DSTREG; + ndpcntl.gpr_we := '1'; + nmmumoni.regmod := '1'; + nmmumoni.isdec := '1'; + ndpcntl.dsrc_sel := c_dpath_dsrc_res; -- DSRC = DRES (for if) + if R_IDSTAT.updt_dstadsrc = '1' then -- prevent stale DSRC copy + ndpcntl.dsrc_we := '1'; -- update DSRC + end if; + nstate := s_dsta_dec1; + + when s_dsta_dec1 => + ndpcntl.vmaddr_sel := c_dpath_vmaddr_ddst; -- VA = DDST + if DSTDEF = '0' then -- check here used also by + do_fork_opa(nstate, R_IDSTAT); -- s_dsta_ind flow !! + else + do_memread_d(nstate, nvmcntl, s_dsta_incdef_w); + end if; + + when s_dsta_ind => + do_memread_i(nstate, ndpcntl, nvmcntl, s_dsta_ind_w); + + when s_dsta_ind_w => + nstate := s_dsta_ind_w; + if R_IDSTAT.is_dstpc = '0' then + ndpcntl.abox_asel := c_abox_asel_ddst; -- ABOX A = DDST + else + ndpcntl.abox_asel := c_abox_asel_pc; -- ABOX A = PC (for nn(pc)) + end if; + ndpcntl.abox_bsel := c_abox_bsel_vmdout; -- ABOX B = VMDOUT + ndpcntl.dres_sel := c_dpath_res_abox; -- DRES = ABOX + ndpcntl.ddst_sel := c_dpath_ddst_res; -- DDST = DRES + do_memcheck(nstate, nstatus, imemok); + if imemok then + ndpcntl.ddst_we := '1'; -- update DDST + nstate := s_dsta_dec1; + end if; + + -- instruction operate states ----------------------------------------------- + + when s_op_halt => -- HALT + if is_kmode = '1' then -- if in kernel mode execute + nmmumoni.idone := '1'; + nstatus.cpugo := '0'; + nstatus.cpuhalt := '1'; + nstatus.cpurust := c_cpurust_halt; + nstate := s_idle; + else -- otherwise trap + ncpuerr.illhlt := '1'; + nstate := s_trap_4; -- trap 4 like 11/70 + end if; + + when s_op_wait => -- WAIT + nstate := s_op_wait; -- spin here + if is_kmode = '0' then -- but act as nop if not in kernel + nstate := s_idle; + elsif int_pending = '1' or -- bail out if pending interrupt + R_STATUS.cpustep='1' then -- or the instruction is only stepped + nstate := s_idle; + elsif R_STATUS.cmdbusy = '1' then -- suspend if a cp command is pending + nstatus.waitsusp := '1'; + nstate := s_idle; + else + nstatus.cpuwait := '1'; -- if spinning here, signal with cpuwait + end if; + + when s_op_trap => -- traps + lvector := "0000" & R_IDSTAT.trap_vec; -- vector + do_start_int(nstate, ndpcntl, lvector); + + when s_op_reset => -- RESET + if is_kmode = '1' then -- if in kernel mode execute + nbreset := '1'; + end if; + nstate := s_idle; + + when s_op_rts => -- RTS + ndpcntl.abox_asel := c_abox_asel_ddst; -- ABOX A=DDST + ndpcntl.abox_bsel := c_abox_bsel_const; -- ABOX B=const(0) + ndpcntl.dres_sel := c_dpath_res_abox; -- DRES = ABOX + ndpcntl.gpr_adst := c_gpr_pc; + ndpcntl.gpr_we := '1'; -- load PC with reg(dst) + nstate := s_op_rts_pop; + + when s_op_rts_pop => + do_memread_srcinc(nstate, ndpcntl, nvmcntl, s_op_rts_pop_w, + nmmumoni, updt_sp=>'1'); + + when s_op_rts_pop_w => + nstate := s_op_rts_pop_w; + ndpcntl.dres_sel := c_dpath_res_vmdout; -- DRES = VMDOUT + ndpcntl.gpr_adst := DSTREG; + do_memcheck(nstate, nstatus, imemok); + if imemok then + ndpcntl.gpr_we := '1'; -- load R with (SP)+ + do_fork_next(nstate, nstatus, nmmumoni); + end if; + + when s_op_spl => -- SPL + ndpcntl.dres_sel := c_dpath_res_ireg; -- DRES = IREG + ndpcntl.psr_func := c_psr_func_wspl; + if is_kmode = '1' then -- active only in kernel mode + ndpcntl.psr_we := '1'; + nstate := s_ifetch; -- unconditionally fetch next + -- instruction like a 11/70 + -- no interrupt recognition ! + else + do_fork_next(nstate, nstatus, nmmumoni); -- in non-kernel, noop + end if; + + when s_op_mcc => -- CLx/SEx + ndpcntl.dres_sel := c_dpath_res_ireg; -- DRES = IREG + ndpcntl.psr_func := c_psr_func_wcc; + ndpcntl.psr_we := '1'; + do_fork_next(nstate, nstatus, nmmumoni); + + when s_op_br => -- BR + nvmcntl.dspace := '0'; -- prepare do_fork_next_pref + ndpcntl.vmaddr_sel := c_dpath_vmaddr_pc; -- VA = PC + ndpcntl.abox_asel := c_abox_asel_pc; -- ABOX A = PC + ndpcntl.abox_bsel := c_abox_bsel_ireg8; -- ABOX B = IREG8 + ndpcntl.dres_sel := c_dpath_res_abox; -- DRES = ABOX + -- note: cc are NZVC + case brcode(3 downto 1) is + when "000" => -- BR + brcond := '1'; + when "001" => -- BNE/BEQ: if Z = x + brcond := PSW.cc(2); + when "010" => -- BGE/BLT: if N xor V = x + brcond := PSW.cc(3) xor PSW.cc(1); + when "011" => -- BGT/BLE: if Z or (N xor V) = x + brcond := PSW.cc(2) or (PSW.cc(3) xor PSW.cc(1)); + when "100" => -- BPL/BMI: if N = x + brcond := PSW.cc(3); + when "101" => -- BHI/BLOS:if C or Z = x + brcond := PSW.cc(2) or PSW.cc(0); + when "110" => -- BVC/BVS: if V = x + brcond := PSW.cc(1); + when "111" => -- BCC/BCS: if C = x + brcond := PSW.cc(0); + when others => null; + end case; + + ndpcntl.gpr_adst := c_gpr_pc; + if brcond = brcode(0) then -- this coding creates redundant code + ndpcntl.gpr_we := '1'; -- but synthesis optimizes this way ! + do_fork_next(nstate, nstatus, nmmumoni); + else + do_fork_next_pref(nstate, nstatus, ndpcntl, nvmcntl, nmmumoni); + end if; + + when s_op_mark => -- MARK + ndpcntl.abox_asel := c_abox_asel_pc; -- ABOX A = PC + ndpcntl.abox_bsel := c_abox_bsel_ireg6; -- ABOX B = IREG6 + ndpcntl.dres_sel := c_dpath_res_abox; -- DRES = ABOX + ndpcntl.dsrc_sel := c_dpath_dsrc_res; -- DSRC = DRES + ndpcntl.dsrc_we := '1'; -- update DSRC (with PC+2*nn) + ndpcntl.gpr_adst := c_gpr_r5; -- fetch r5 + ndpcntl.ddst_sel := c_dpath_ddst_dst; + ndpcntl.ddst_we := '1'; + nstate := s_op_mark1; + + when s_op_mark1 => + ndpcntl.abox_asel := c_abox_asel_ddst; -- ABOX A = DDST + ndpcntl.abox_bsel := c_abox_bsel_const; -- ABOX B = const(0) + ndpcntl.dres_sel := c_dpath_res_abox; -- DRES = ABOX + ndpcntl.gpr_adst := c_gpr_pc; + ndpcntl.gpr_we := '1'; -- load PC with r5 + nstate := s_op_mark_pop; + + when s_op_mark_pop => + do_memread_srcinc(nstate, ndpcntl, nvmcntl, s_op_mark_pop_w, + nmmumoni, updt_sp=>'1'); + + when s_op_mark_pop_w => + nstate := s_op_mark_pop_w; + ndpcntl.dres_sel := c_dpath_res_vmdout; -- DRES = VMDOUT + ndpcntl.gpr_adst := c_gpr_r5; + do_memcheck(nstate, nstatus, imemok); + if imemok then + ndpcntl.gpr_we := '1'; -- load R5 with (sp)+ + do_fork_next(nstate, nstatus, nmmumoni); + end if; + + when s_op_sob => -- SOB (dec) + -- comment fork_next_pref out (blog 2006-10-02) due to synthesis impact + --nvmcntl.dspace := '0'; -- prepare do_fork_next_pref + --ndpcntl.vmaddr_sel := c_dpath_vmaddr_pc; -- VA = PC + ndpcntl.dres_sel := R_IDSTAT.res_sel; + ndpcntl.gpr_adst := SRCREG; + ndpcntl.gpr_we := '1'; + + if DP_STAT.ccout_z = '0' then -- if z=0 branch, if z=1 fall thru + nstate := s_op_sob1; + else + --do_fork_next_pref(nstate, ndpcntl, nvmcntl, nmmumoni); + do_fork_next(nstate, nstatus, nmmumoni); + end if; + + when s_op_sob1 => -- SOB (br) + ndpcntl.abox_asel := c_abox_asel_pc; -- ABOX A = PC + ndpcntl.abox_bsel := c_abox_bsel_ireg6; -- ABOX B = IREG6 + ndpcntl.abox_opsub := '1'; -- ABOX = A - B + ndpcntl.dres_sel := c_dpath_res_abox; -- DRES = ABOX + ndpcntl.gpr_adst := c_gpr_pc; + ndpcntl.gpr_we := '1'; + do_fork_next(nstate, nstatus, nmmumoni); + + when s_opg_gen => + nvmcntl.dspace := '0'; -- prepare do_fork_next_pref + ndpcntl.vmaddr_sel := c_dpath_vmaddr_pc; -- VA = PC + ndpcntl.gpr_bytop := R_IDSTAT.is_bytop; + ndpcntl.dres_sel := R_IDSTAT.res_sel; -- DRES = choice of idec + + if R_IDSTAT.op_mov = '1' then -- in case of MOV xx,R + ndpcntl.gpr_bytop := '0'; -- no bytop, do sign extend + end if; + + ndpcntl.psr_ccwe := '1'; + + if R_IDSTAT.is_dstw_reg = '1' then + ndpcntl.gpr_we := '1'; + end if; + + if R_IDSTAT.is_rmwop = '1' then + do_memwrite(nstate, nvmcntl, s_opg_gen_rmw_w, macc=>'1'); + else + if R_STATUS.prefdone = '1' then + nstatus.prefdone :='0'; + nstate := s_ifetch_w; + do_memcheck(nstate, nstatus, imemok); + if imemok then + ndpcntl.ireg_we := '1'; + nstate := s_idecode; + end if; + else + if R_IDSTAT.is_dstw_pc = '1' then + nstate := s_idle; + else + do_fork_next_pref(nstate, nstatus, ndpcntl, nvmcntl, nmmumoni); + end if; + end if; + end if; + + when s_opg_gen_rmw_w => + nstate := s_opg_gen_rmw_w; + do_memcheck(nstate, nstatus, imemok); + if imemok then + do_fork_next(nstate, nstatus, nmmumoni); + end if; + + when s_opg_mul => -- MUL (oper) + ndpcntl.dres_sel := R_IDSTAT.res_sel; -- DRES = choice of idec + ndpcntl.gpr_adst := SRCREG; -- write high order result + ndpcntl.gpr_we := '1'; + ndpcntl.dsrc_sel := c_dpath_dsrc_res; -- DSRC = DRES + ndpcntl.dsrc_we := '1'; -- capture high order part + ndpcntl.dtmp_sel := c_dpath_dtmp_drese; -- DTMP = DRESE + ndpcntl.dtmp_we := '1'; -- capture low order part + nstate := s_opg_mul1; + + when s_opg_mul1 => -- MUL (write odd reg) + ndpcntl.abox_asel := c_abox_asel_dtmp; -- ABOX A = DTMP + ndpcntl.abox_bsel := c_abox_bsel_const; -- ABOX B = const(0) + ndpcntl.dres_sel := c_dpath_res_abox; -- DRES = ABOX + ndpcntl.gpr_adst := SRCREG(2 downto 1) & "1";-- write odd reg ! + ndpcntl.gpr_we := '1'; + ndpcntl.psr_ccwe := '1'; + do_fork_next(nstate, nstatus, nmmumoni); + + when s_opg_div => -- DIV (load dd_low) + ndpcntl.mbox_s_div := '1'; + ndpcntl.gpr_asrc := SRCREG(2 downto 1) & "1";-- read odd reg ! + ndpcntl.dtmp_sel := c_dpath_dtmp_dsrc; + ndpcntl.dtmp_we := '1'; + nstate := s_opg_div_cn; + + when s_opg_div_cn => -- DIV (1st...16th cycle) + ndpcntl.mbox_s_div_cn := '1'; + ndpcntl.dres_sel := R_IDSTAT.res_sel; -- DRES = choice of idec + ndpcntl.dsrc_sel := c_dpath_dsrc_res; -- DSRC = DRES + ndpcntl.dtmp_sel := c_dpath_dtmp_drese; -- DTMP = DRESE + nstate := s_opg_div_cn; + if DP_STAT.div_zero='1' or DP_STAT.div_ovfl='1' then + nstate := s_opg_div_zero; + else + ndpcntl.dsrc_we := '1'; -- update DSRC + ndpcntl.dtmp_we := '1'; -- update DTMP + end if; + if DP_STAT.shc_tc = '1' then + nstate := s_opg_div_cr; + end if; + + when s_opg_div_cr => -- DIV (reminder correction) + ndpcntl.mbox_s_div_cr := '1'; + ndpcntl.dres_sel := R_IDSTAT.res_sel; -- DRES = choice of idec + ndpcntl.dsrc_sel := c_dpath_dsrc_res; -- DSRC = DRES + ndpcntl.dsrc_we := DP_STAT.div_cr; -- update DSRC + nstate := s_opg_div_sq; + + when s_opg_div_sq => -- DIV (store quotient) + ndpcntl.abox_asel := c_abox_asel_dtmp; -- ABOX A=DTMP + ndpcntl.abox_const := "00000000"&DP_STAT.div_cq;-- ABOX const = Q corr. + ndpcntl.abox_bsel := c_abox_bsel_const; -- ABOX B=const (q cor) + ndpcntl.dres_sel := c_dpath_res_abox; -- DRES = ABOX + ndpcntl.gpr_adst := SRCREG; -- write result + ndpcntl.gpr_we := '1'; + ndpcntl.dtmp_sel := c_dpath_dtmp_dres; -- DTMP = DRES + ndpcntl.dtmp_we := '1'; -- update DTMP (Q) + nstate := s_opg_div_sr; + + when s_opg_div_sr => -- DIV (store reminder) + ndpcntl.abox_asel := c_abox_asel_dsrc; -- ABOX A=DSRC + ndpcntl.abox_bsel := c_abox_bsel_const; -- ABOX B=const (0) + ndpcntl.dres_sel := c_dpath_res_abox; -- DRES = ABOX + ndpcntl.gpr_adst := SRCREG(2 downto 1) & "1";-- write odd reg ! + ndpcntl.gpr_we := '1'; + ndpcntl.psr_ccwe := '1'; + do_fork_next(nstate, nstatus, nmmumoni); + + when s_opg_div_zero => -- DIV (/0 or 0/ abort) + ndpcntl.psr_ccwe := '1'; + do_fork_next(nstate, nstatus, nmmumoni); + + when s_opg_ash => -- ASH (load shc) + ndpcntl.mbox_s_ash := '1'; + nstate := s_opg_ash_cn; + + when s_opg_ash_cn => -- ASH (shift cycles) + nvmcntl.dspace := '0'; -- prepare do_fork_next_pref + ndpcntl.dsrc_sel := c_dpath_dsrc_res; -- DSRC = DRES + ndpcntl.abox_asel := c_abox_asel_dsrc; -- ABOX A=DSRC + ndpcntl.abox_bsel := c_abox_bsel_const; -- ABOX B=const(0) + ndpcntl.gpr_adst := SRCREG; -- write result + ndpcntl.mbox_s_ash_cn := '1'; + ndpcntl.vmaddr_sel := c_dpath_vmaddr_pc; -- VA = PC + nstate := s_opg_ash_cn; + if DP_STAT.shc_tc = '0' then + ndpcntl.dres_sel := R_IDSTAT.res_sel; -- DRES = choice of idec + ndpcntl.dsrc_we := '1'; -- update DSRC + else + ndpcntl.dres_sel := c_dpath_res_abox; -- DRES = ABOX + ndpcntl.gpr_we := '1'; + ndpcntl.psr_ccwe := '1'; + do_fork_next_pref(nstate, nstatus, ndpcntl, nvmcntl, nmmumoni); + end if; + + when s_opg_ashc => -- ASHC (load low, load shc) + ndpcntl.gpr_asrc := SRCREG(2 downto 1) & "1";-- read odd reg ! + ndpcntl.dtmp_sel := c_dpath_dtmp_dsrc; + ndpcntl.dtmp_we := '1'; + ndpcntl.mbox_s_ashc := '1'; + nstate := s_opg_ashc_cn; + + when s_opg_ashc_cn => -- ASHC (shift cycles) + ndpcntl.dsrc_sel := c_dpath_dsrc_res; -- DSRC = DRES + ndpcntl.dtmp_sel := c_dpath_dtmp_drese; -- DTMP = DRESE + ndpcntl.abox_asel := c_abox_asel_dsrc; -- ABOX A=DSRC + ndpcntl.abox_bsel := c_abox_bsel_const; -- ABOX B=const(0) + ndpcntl.gpr_adst := SRCREG; -- write result + ndpcntl.mbox_s_ashc_cn := '1'; + nstate := s_opg_ashc_cn; + if DP_STAT.shc_tc = '0' then + ndpcntl.dres_sel := R_IDSTAT.res_sel; -- DRES = choice of idec + ndpcntl.dsrc_we := '1'; -- update DSRC + ndpcntl.dtmp_we := '1'; -- update DTMP + else + ndpcntl.dres_sel := c_dpath_res_abox; -- DRES = ABOX + ndpcntl.gpr_we := '1'; + ndpcntl.psr_ccwe := '1'; + nstate := s_opg_ashc_wl; + end if; + + when s_opg_ashc_wl => -- ASHC (write low) + ndpcntl.abox_asel := c_abox_asel_dtmp; -- ABOX A = DTMP + ndpcntl.abox_bsel := c_abox_bsel_const; -- ABOX B = const(0) + ndpcntl.dres_sel := c_dpath_res_abox; -- DRES = ABOX + ndpcntl.gpr_adst := SRCREG(2 downto 1) & "1";-- write odd reg ! + ndpcntl.gpr_we := '1'; + do_fork_next(nstate, nstatus, nmmumoni); + + -- dsta mode operations ----------------------------------------------------- + + when s_opa_jsr => + ndpcntl.gpr_asrc := c_gpr_sp; -- (for else) + ndpcntl.dsrc_sel := c_dpath_dsrc_src; -- DSRC = regfile (for else) + if R_IDSTAT.is_dstmode0 = '1' then + nstate := s_trap_10; -- trap 10 like 11/70 + else + ndpcntl.dsrc_we := '1'; + nstate := s_opa_jsr1; + end if; + + when s_opa_jsr1 => + ndpcntl.gpr_asrc := SRCREG; + ndpcntl.dtmp_sel := c_dpath_dtmp_dsrc; -- DTMP = regfile + ndpcntl.dtmp_we := '1'; + + ndpcntl.abox_asel := c_abox_asel_dsrc; -- ABOX A=DSRC + ndpcntl.abox_const := "000000010"; + ndpcntl.abox_bsel := c_abox_bsel_const; -- ABOX B=const(2) + ndpcntl.abox_opsub := '1'; -- ABOX = A-B + ndpcntl.dres_sel := c_dpath_res_abox; -- DRES = ABOX + ndpcntl.dsrc_sel := c_dpath_dsrc_res; -- DDST = DRES + ndpcntl.dsrc_we := '1'; -- update DDST + ndpcntl.gpr_adst := c_gpr_sp; + ndpcntl.gpr_we := '1'; -- update SP + nmmumoni.regmod := '1'; + nmmumoni.isdec := '1'; + nstate := s_opa_jsr_push; + + when s_opa_jsr_push => + ndpcntl.abox_asel := c_abox_asel_dtmp; -- ABOX A=DTMP + ndpcntl.abox_bsel := c_abox_bsel_const; -- ABOX B=const(0) + ndpcntl.dres_sel := c_dpath_res_abox; -- DRES = ABOX + ndpcntl.vmaddr_sel := c_dpath_vmaddr_dsrc; -- VA = DSRC + nvmcntl.dspace := '1'; + nvmcntl.kstack := is_kmode; + nvmcntl.wacc := '1'; + nvmcntl.req := '1'; + nstate := s_opa_jsr_push_w; + + when s_opa_jsr_push_w => + nstate := s_opa_jsr_push_w; + ndpcntl.abox_asel := c_abox_asel_pc; -- ABOX A=PC + ndpcntl.abox_bsel := c_abox_bsel_const; -- ABOX B=const(0) + ndpcntl.dres_sel := c_dpath_res_abox; -- DRES = ABOX + ndpcntl.gpr_adst := SRCREG; + do_memcheck(nstate, nstatus, imemok); + if imemok then + ndpcntl.gpr_we := '1'; -- load R with PC + nstate := s_opa_jsr2; + end if; + + when s_opa_jsr2 => + ndpcntl.abox_asel := c_abox_asel_ddst; -- ABOX A=DDST + ndpcntl.abox_bsel := c_abox_bsel_const; -- ABOX B=const(0) + ndpcntl.dres_sel := c_dpath_res_abox; -- DRES = ABOX + ndpcntl.gpr_adst := c_gpr_pc; + ndpcntl.gpr_we := '1'; -- load PC with dsta + do_fork_next(nstate, nstatus, nmmumoni); + + when s_opa_jmp => + ndpcntl.abox_asel := c_abox_asel_ddst; -- ABOX A=DDST + ndpcntl.abox_bsel := c_abox_bsel_const; -- ABOX B=const(0) + ndpcntl.dres_sel := c_dpath_res_abox; -- DRES = ABOX + ndpcntl.gpr_adst := c_gpr_pc; + if R_IDSTAT.is_dstmode0 = '1' then + nstate := s_trap_10; -- trap 10 like 11/70 + else + ndpcntl.gpr_we := '1'; -- load PC with dsta + do_fork_next(nstate, nstatus, nmmumoni); + end if; + + when s_opa_mtp => + do_memread_srcinc(nstate, ndpcntl, nvmcntl, s_opa_mtp_pop_w, + nmmumoni, updt_sp=>'1'); + + when s_opa_mtp_pop_w => + nstate := s_opa_mtp_pop_w; + ndpcntl.dres_sel := c_dpath_res_vmdout; -- DRES = VMDOUT + ndpcntl.dtmp_sel := c_dpath_dtmp_dres; -- DTMP = DRES + do_memcheck(nstate, nstatus, imemok); + if imemok then + ndpcntl.dtmp_we := '1'; -- load DTMP + if R_IDSTAT.is_dstmode0 = '1' then -- handle register access + nstate := s_opa_mtp_reg; + else + case R_IDSTAT.fork_dsta is -- 2nd dsta fork in s_idecode + when c_fork_dsta_def => nstate := s_opa_mtp_mem; + when c_fork_dsta_inc => nstate := s_dsta_inc; + when c_fork_dsta_dec => nstate := s_dsta_dec; + when c_fork_dsta_ind => nstate := s_dsta_ind; + when others => nstate := s_cpufail; + end case; + end if; + end if; + ndpcntl.ddst_sel := c_dpath_ddst_dst; -- DDST = R(DST) + ndpcntl.ddst_we := '1'; -- update DDST (needed for sp) + + when s_opa_mtp_reg => + ndpcntl.abox_asel := c_abox_asel_dtmp; -- ABOX A = DTMP + ndpcntl.abox_bsel := c_abox_bsel_const; -- ABOX B = const(0) + ndpcntl.dres_sel := c_dpath_res_abox; -- DRES = ABOX + ndpcntl.psr_ccwe := '1'; -- set cc (from abox too) + ndpcntl.gpr_mode := PSW.pmode; -- load reg in pmode + ndpcntl.gpr_we := '1'; + do_fork_next(nstate, nstatus, nmmumoni); + + when s_opa_mtp_mem => + ndpcntl.abox_asel := c_abox_asel_dtmp; -- ABOX A = DTMP + ndpcntl.abox_bsel := c_abox_bsel_const; -- ABOX B = const(0) + ndpcntl.dres_sel := c_dpath_res_abox; -- DRES = ABOX + ndpcntl.psr_ccwe := '1'; -- set cc (from abox too) + ndpcntl.vmaddr_sel := c_dpath_vmaddr_ddst;-- VA = DDST + nvmcntl.dspace := IREG(15); -- msb indicates I/D: 0->I, 1->D + nvmcntl.mode := PSW.pmode; + nvmcntl.wacc := '1'; + nvmcntl.req := '1'; + nstate := s_opa_mtp_mem_w; + + when s_opa_mtp_mem_w => + nstate := s_opa_mtp_mem_w; + do_memcheck(nstate, nstatus, imemok); + if imemok then + do_fork_next(nstate, nstatus, nmmumoni); + end if; + + when s_opa_mfp_reg => + ndpcntl.gpr_mode := PSW.pmode; -- fetch reg in pmode + ndpcntl.ddst_sel := c_dpath_ddst_dst; -- DDST = reg(dst) + ndpcntl.ddst_we := '1'; + nstate := s_opa_mfp_dec; + + when s_opa_mfp_mem => + ndpcntl.vmaddr_sel := c_dpath_vmaddr_ddst; -- VA = DDST + if PSW.cmode=c_psw_umode and -- if cm=pm=user then + PSW.cmode=c_psw_umode then -- MFPI works like it + nvmcntl.dspace := '1'; -- were MFPD + else + nvmcntl.dspace := IREG(15); -- msb indicates I/D: 0->I, 1->D + end if; + nvmcntl.mode := PSW.pmode; + nvmcntl.req := '1'; + nstate := s_opa_mfp_mem_w; + + when s_opa_mfp_mem_w => + nstate := s_opa_mfp_mem_w; + do_memcheck(nstate, nstatus, imemok); + ndpcntl.dres_sel := c_dpath_res_vmdout; -- DRES = VMDOUT + ndpcntl.ddst_sel := c_dpath_ddst_res; -- DDST = DRES + if imemok then + ndpcntl.ddst_we := '1'; + nstate := s_opa_mfp_dec; + end if; + + when s_opa_mfp_dec => + ndpcntl.abox_asel := c_abox_asel_dsrc; -- ABOX A=DSRC + ndpcntl.abox_const := "000000010"; + ndpcntl.abox_bsel := c_abox_bsel_const; -- ABOX B=const(2) + ndpcntl.abox_opsub := '1'; -- ABOX = A-B + ndpcntl.dres_sel := c_dpath_res_abox; -- DRES = ABOX + ndpcntl.dsrc_sel := c_dpath_dsrc_res; -- DSRC = DRES + ndpcntl.dsrc_we := '1'; -- update DSRC + ndpcntl.gpr_adst := c_gpr_sp; + ndpcntl.gpr_we := '1'; -- update SP + nmmumoni.regmod := '1'; + nmmumoni.isdec := '1'; + nstate := s_opa_mfp_push; + + when s_opa_mfp_push => + ndpcntl.abox_asel := c_abox_asel_ddst; -- ABOX A=DDST + ndpcntl.abox_bsel := c_abox_bsel_const; -- ABOX B=const(0) + ndpcntl.dres_sel := c_dpath_res_abox; -- DRES = ABOX + ndpcntl.psr_ccwe := '1'; -- set cc (from abox too) + ndpcntl.vmaddr_sel := c_dpath_vmaddr_dsrc; -- VA = DSRC + nvmcntl.dspace := '1'; + nvmcntl.kstack := is_kmode; + nvmcntl.wacc := '1'; + nvmcntl.req := '1'; + nstate := s_opa_mfp_push_w; + + when s_opa_mfp_push_w => + nstate := s_opa_mfp_push_w; + do_memcheck(nstate, nstatus, imemok); + if imemok then + do_fork_next(nstate, nstatus, nmmumoni); + end if; + + -- trap and interrupt handling states --------------------------------------- + + when s_trap_4 => + lvector := "0000001"; -- vector (4) + do_start_int(nstate, ndpcntl, lvector); + + when s_trap_10 => + lvector := "0000010"; -- vector (10) + do_start_int(nstate, ndpcntl, lvector); + + when s_trap_disp => + if R_STATUS.trap_mmu = '1' then + nvmcntl.trap_done := '1'; -- mmu trap taken: set ssr0 trap bit + lvector := "0101010"; -- mmu trap: vector (250) + elsif R_STATUS.trap_ysv = '1' then + lvector := "0000001"; -- ysv trap: vector (4) + ncpuerr.ysv := '1'; + else + lvector := "0000011"; -- trace trap: vector (14) + end if; + nstatus.trap_mmu := '0'; -- clear pending trap flags + nstatus.trap_ysv := '0'; -- + do_start_int(nstate, ndpcntl, lvector); + + when s_int_ext => + lvector := R_STATUS.intvect; -- external vector + do_start_int(nstate, ndpcntl, lvector); + + when s_int_getpc => + nvmcntl.mode := c_psw_kmode; -- fetch PC from kernel D space + do_memread_srcinc(nstate, ndpcntl, nvmcntl, s_int_getpc_w, nmmumoni); + + when s_int_getpc_w => + nstate := s_int_getpc_w; + ndpcntl.dres_sel := c_dpath_res_vmdout; -- DRES = VMDOUT + ndpcntl.ddst_sel := c_dpath_ddst_res; -- DDST = DRES + do_memcheck(nstate, nstatus, imemok); + if VM_STAT.err = '1' then -- in case of vm-err + nstatus.cpugo := '0'; -- non-recoverable error + nstatus.cpurust := c_cpurust_vecfet; -- halt CPU + nstate := s_idle; + end if; + if imemok then + ndpcntl.ddst_we := '1'; -- DDST = new PC + nstate := s_int_getps; + end if; + + when s_int_getps => + nvmcntl.mode := c_psw_kmode; -- fetch PS from kernel D space + do_memread_srcinc(nstate, ndpcntl, nvmcntl, s_int_getps_w, nmmumoni); + + when s_int_getps_w => + nstate := s_int_getps_w; + ndpcntl.dres_sel := c_dpath_res_vmdout; -- DRES = VMDOUT + ndpcntl.psr_func := c_psr_func_wint; -- interupt mode write + do_memcheck(nstate, nstatus, imemok); + if VM_STAT.err = '1' then -- in case of vm-err + nstatus.cpugo := '0'; -- non-recoverable error + nstatus.cpurust := c_cpurust_vecfet; -- halt CPU + nstate := s_idle; + end if; + if imemok then + ndpcntl.psr_we := '1'; -- store new PS + nstate := s_int_getsp; + end if; + + when s_int_getsp => + ndpcntl.gpr_asrc := c_gpr_sp; + ndpcntl.dsrc_we := '1'; -- DSRC = SP (in new mode) + nstate := s_int_decsp; + + when s_int_decsp => + ndpcntl.abox_asel := c_abox_asel_dsrc; -- ABOX A=DSRC + ndpcntl.abox_const := "000000010"; -- ABOX const=2 + ndpcntl.abox_bsel := c_abox_bsel_const; -- ABOX B=const + ndpcntl.abox_opsub := '1'; -- ABOX = A-B + ndpcntl.dres_sel := c_dpath_res_abox; -- DRES = ABOX + ndpcntl.dsrc_sel := c_dpath_dsrc_res; -- DSRC = DRES + ndpcntl.dsrc_we := '1'; -- update DSRC + ndpcntl.gpr_adst := c_gpr_sp; + ndpcntl.gpr_we := '1'; -- update SP too + nstate := s_int_pushps; + + when s_int_pushps => + ndpcntl.abox_asel := c_abox_asel_dtmp; -- ABOX A=DTMP (old PS) + ndpcntl.abox_bsel := c_abox_bsel_const; -- ABOX B=const (0) + ndpcntl.dres_sel := c_dpath_res_abox; -- DRES = ABOX + ndpcntl.vmaddr_sel := c_dpath_vmaddr_dsrc; -- VA = DSRC + nvmcntl.wacc := '1'; -- write mem + nvmcntl.dspace := '1'; + nvmcntl.kstack := is_kmode; + nvmcntl.req := '1'; + nstate := s_int_pushps_w; + + when s_int_pushps_w => + ndpcntl.abox_asel := c_abox_asel_dsrc; -- ABOX A=DSRC + ndpcntl.abox_const := "000000010"; -- ABOX const=2 + ndpcntl.abox_bsel := c_abox_bsel_const; -- ABOX B=const + ndpcntl.abox_opsub := '1'; -- ABOX = A-B + ndpcntl.dres_sel := c_dpath_res_abox; -- DRES = ABOX + ndpcntl.dsrc_sel := c_dpath_dsrc_res; -- DSRC = DRES + ndpcntl.gpr_adst := c_gpr_sp; + + nstate := s_int_pushps_w; + do_memcheck(nstate, nstatus, imemok); + if imemok then + ndpcntl.dsrc_we := '1'; -- update DSRC + ndpcntl.gpr_we := '1'; -- update SP too + nstate := s_int_pushpc; + end if; + + when s_int_pushpc => + ndpcntl.abox_asel := c_abox_asel_pc; -- ABOX A=PC + ndpcntl.abox_bsel := c_abox_bsel_const; -- ABOX B=const (0) + ndpcntl.dres_sel := c_dpath_res_abox; -- DRES = ABOX + ndpcntl.vmaddr_sel := c_dpath_vmaddr_dsrc; -- VA = DSRC + nvmcntl.wacc := '1'; -- write mem + nvmcntl.dspace := '1'; + nvmcntl.kstack := is_kmode; + nvmcntl.req := '1'; + nstate := s_int_pushpc_w; + + when s_int_pushpc_w => + ndpcntl.abox_asel := c_abox_asel_ddst; -- ABOX A=DDST + ndpcntl.abox_bsel := c_abox_bsel_const; -- ABOX B=const (0) + ndpcntl.dres_sel := c_dpath_res_abox; -- DRES = ABOX + ndpcntl.gpr_adst := c_gpr_pc; + + nstate := s_int_pushpc_w; + do_memcheck(nstate, nstatus, imemok); + if imemok then + nstatus.do_intrsv := '0'; -- signal end of rsv + ndpcntl.gpr_we := '1'; -- load new PC + do_fork_next(nstate, nstatus, nmmumoni); -- ??? + end if; + + -- return from trap or interrupt handling states ---------------------------- + + when s_rti_getpc => + do_memread_srcinc(nstate, ndpcntl, nvmcntl, s_rti_getpc_w, + nmmumoni, updt_sp=>'1'); + + when s_rti_getpc_w => + nstate := s_rti_getpc_w; + ndpcntl.dres_sel := c_dpath_res_vmdout; -- DRES = VMDOUT + ndpcntl.ddst_sel := c_dpath_ddst_res; -- DDST = DRES + do_memcheck(nstate, nstatus, imemok); + if imemok then + ndpcntl.ddst_we := '1'; -- DDST = new PC + nstate := s_rti_getps; + end if; + + when s_rti_getps => + do_memread_srcinc(nstate, ndpcntl, nvmcntl, s_rti_getps_w, + nmmumoni, updt_sp=>'1'); + + when s_rti_getps_w => + nstate := s_rti_getps_w; + do_memcheck(nstate, nstatus, imemok); + ndpcntl.dres_sel := c_dpath_res_vmdout; -- DRES = VMDOUT + if is_kmode = '1' then -- if in kernel mode + ndpcntl.psr_func := c_psr_func_wall; -- write all fields + else + ndpcntl.psr_func := c_psr_func_wrti; -- otherwise filter + end if; + if imemok then + ndpcntl.psr_we := '1'; -- load new PS + nstate := s_rti_newpc; + end if; + + when s_rti_newpc => + ndpcntl.abox_asel := c_abox_asel_ddst; -- ABOX A=DDST + ndpcntl.abox_bsel := c_abox_bsel_const; -- ABOX B=const (0) + ndpcntl.dres_sel := c_dpath_res_abox; -- DRES = ABOX + ndpcntl.gpr_adst := c_gpr_pc; + ndpcntl.gpr_we := '1'; -- load new PC + if R_IDSTAT.op_rtt = '1' then -- if RTT instruction + nstate := s_ifetch; -- force fetch + else -- otherwise RTI + do_fork_next(nstate, nstatus, nmmumoni); + end if; + + -- exception abort states --------------------------------------------------- + + when s_vmerr => + nstate := s_cpufail; + + -- setup for R_VMSTAT.err_rsv='1' + ndpcntl.abox_azero := '1'; -- ABOX A = 0 + ndpcntl.abox_const := "000000100"; -- emergency stack pointer + ndpcntl.abox_bsel := c_abox_bsel_const; -- ABOX B=const(vector) + ndpcntl.dres_sel := c_dpath_res_abox; -- DRES = ABOX + ndpcntl.gpr_mode := c_psw_kmode; -- set kmode SP to 4 + ndpcntl.gpr_adst := c_gpr_sp; + + nstatus.trap_mmu :='0'; -- drop pending mmu trap + + if R_VMSTAT.fail = '1' then -- vmbox failure + nstatus.cpugo := '0'; -- halt cpu + nstatus.cpurust := c_cpurust_vfail; + nstate := s_idle; + + elsif R_STATUS.do_intrsv = '1' then -- double error + nstatus.cpugo := '0'; -- give up, HALT cpu + nstatus.cpurust := c_cpurust_recrsv; + nstate := s_idle; + + elsif R_VMSTAT.err = '1' then -- normal vm errors + if R_VMSTAT.err_rsv = '1' then + nstatus.do_intrsv := '1'; -- signal start of rsv + ndpcntl.gpr_we := '1'; + + if R_VMSTAT.err_odd='1' or R_VMSTAT.err_mmu='1' then + ncpuerr.adderr := '1'; + elsif R_VMSTAT.err_nxm = '1' then + ncpuerr.nxm := '1'; + elsif R_VMSTAT.err_iobto = '1' then + ncpuerr.iobto := '1'; + end if; + ncpuerr.rsv := '1'; + nstate := s_trap_4; + + elsif R_VMSTAT.err_odd = '1' then + ncpuerr.adderr := '1'; + nstate := s_trap_4; + elsif R_VMSTAT.err_nxm = '1' then + ncpuerr.nxm := '1'; + nstate := s_trap_4; + elsif R_VMSTAT.err_iobto = '1' then + ncpuerr.iobto := '1'; + nstate := s_trap_4; + + elsif R_VMSTAT.err_mmu = '1' then + lvector := "0101010"; -- vector (250) + do_start_int(nstate, ndpcntl, lvector); + end if; + end if; + + when s_cpufail => + nstatus.cpugo := '0'; + nstatus.cpurust := c_cpurust_sfail; + nstate := s_idle; + + when others => + nstate := s_cpufail; --!!! catch undefined states !!! + + end case; + + if nstatus.cmdack = '1' then -- cmdack in next cycle ? Yes we test + -- nstatus here !! + nstatus.cmdbusy := '0'; + ndpcntl.cpdout_we := '1'; + end if; + + N_STATE <= nstate; + N_STATUS <= nstatus; + N_CPUERR <= ncpuerr; + N_IDSTAT <= nidstat; + + CRESET <= ncreset; + BRESET <= nbreset; + INT_ACK <= nintack; + + DP_CNTL <= ndpcntl; + VM_CNTL <= nvmcntl; + + nmmumoni.regnum := ndpcntl.gpr_adst; + nmmumoni.delta := ndpcntl.abox_const(3 downto 0); + MMU_MONI <= nmmumoni; + + end process proc_next; + + proc_cpstat : process (R_STATUS) + begin + CP_STAT <= cp_stat_init; + CP_STAT.cmdbusy <= R_STATUS.cmdbusy; + CP_STAT.cmdack <= R_STATUS.cmdack; + CP_STAT.cmderr <= R_STATUS.cmderr; + CP_STAT.cmdmerr <= R_STATUS.cmdmerr; + CP_STAT.cpugo <= R_STATUS.cpugo; + CP_STAT.cpustep <= R_STATUS.cpustep; + CP_STAT.cpuhalt <= R_STATUS.cpuhalt; + CP_STAT.cpuwait <= R_STATUS.cpuwait; + CP_STAT.cpurust <= R_STATUS.cpurust; + end process proc_cpstat; + +end syn; + diff --git a/rtl/w11a/pdp11_sim.vhd b/rtl/w11a/pdp11_sim.vhd new file mode 100644 index 00000000..b5a45cba --- /dev/null +++ b/rtl/w11a/pdp11_sim.vhd @@ -0,0 +1,40 @@ +-- $Id: pdp11_sim.vhd 314 2010-07-09 17:38:41Z mueller $ +-- +-- Copyright 2006-2007 by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, 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 complete details. +-- +------------------------------------------------------------------------------ +-- Package Name: pdp11_sim +-- Description: Definitions for simulations +-- +-- Dependencies: - +-- Tool versions: xst 8.1, 8.2, 9.1, 9.2; ghdl 0.18-0.25 +-- Revision History: +-- Date Rev Version Comment +-- 2007-10-12 88 1.0.2 avoid ieee.std_logic_unsigned, use cast to unsigned +-- 2007-06-14 56 1.0.1 Use slvtypes.all +-- 2007-05-12 26 1.0 Initial version +------------------------------------------------------------------------------ + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_textio.all; +use std.textio.all; + +package pdp11_sim is + + constant clock_period : time := 20 ns; + constant clock_offset : time := 200 ns; + constant setup_time : time := 5 ns; + constant c2out_time : time := 5 ns; + +end package pdp11_sim; + diff --git a/rtl/w11a/pdp11_sys70.vbom b/rtl/w11a/pdp11_sys70.vbom new file mode 100644 index 00000000..6f3aa9a4 --- /dev/null +++ b/rtl/w11a/pdp11_sys70.vbom @@ -0,0 +1,8 @@ +# libs +../vlib/slvtypes.vhd +../ibus/iblib.vhd +pdp11.vbom +sys_conf : sys_conf.vhd +# components +# design +pdp11_sys70.vhd diff --git a/rtl/w11a/pdp11_sys70.vhd b/rtl/w11a/pdp11_sys70.vhd new file mode 100644 index 00000000..ef134d08 --- /dev/null +++ b/rtl/w11a/pdp11_sys70.vhd @@ -0,0 +1,124 @@ +-- $Id: pdp11_sys70.vhd 314 2010-07-09 17:38:41Z mueller $ +-- +-- Copyright 2008- by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, 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 complete details. +-- +------------------------------------------------------------------------------ +-- Module Name: pdp11_sys70 - syn +-- Description: pdp11: 11/70 system registers +-- +-- Dependencies: - +-- Test bench: tb/tb_pdp11_core (implicit) +-- Target Devices: generic +-- Tool versions: xst 8.1, 8.2, 9.1, 9.2; ghdl 0.18-0.25 +-- Revision History: +-- Date Rev Version Comment +-- 2008-08-22 161 1.0.1 use iblib +-- 2008-04-20 137 1.0 Initial version +------------------------------------------------------------------------------ + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; + +use work.slvtypes.all; +use work.pdp11.all; +use work.iblib.all; +use work.sys_conf.all; + +-- ---------------------------------------------------------------------------- + +entity pdp11_sys70 is -- 11/70 memory system registers + port ( + CLK : in slbit; -- clock + CRESET : in slbit; -- console reset + IB_MREQ : in ib_mreq_type; -- ibus request + IB_SRES : out ib_sres_type -- ibus response + ); +end pdp11_sys70; + +architecture syn of pdp11_sys70 is + + constant ibaddr_mbrk : slv16 := conv_std_logic_vector(8#177770#,16); + constant ibaddr_sysid : slv16 := conv_std_logic_vector(8#177764#,16); + + type regs_type is record -- state registers + mbrk : slv8; -- status of mbrk register + end record regs_type; + + constant regs_init : regs_type := ( + mbrk=>(others=>'0') -- mbrk + ); + + signal R_REGS : regs_type := regs_init; + signal N_REGS : regs_type := regs_init; + +begin + + proc_regs: process (CLK) + begin + if CLK'event and CLK='1' then + if CRESET = '1' then + R_REGS <= regs_init; + else + R_REGS <= N_REGS; + end if; + end if; + end process proc_regs; + + proc_next: process (R_REGS, IB_MREQ) + variable r : regs_type := regs_init; + variable n : regs_type := regs_init; + variable ibsel_mbrk : slbit := '0'; -- mbrk + variable ibsel_sysid : slbit := '0'; -- sysid + variable ibsel : slbit := '0'; + variable idout : slv16 := (others=>'0'); + begin + + r := R_REGS; + n := R_REGS; + + ibsel_mbrk := '0'; + ibsel_sysid := '0'; + ibsel := '0'; + idout := (others=>'0'); + + if IB_MREQ.req = '1' then + if IB_MREQ.addr = ibaddr_mbrk(12 downto 1) then + ibsel_mbrk := '1'; + end if; + if IB_MREQ.addr = ibaddr_sysid(12 downto 1) then + ibsel_sysid := '1'; + end if; + end if; + + ibsel := ibsel_mbrk or ibsel_sysid; + + if ibsel_mbrk = '1' then + idout(r.mbrk'range) := r.mbrk; + end if; + if ibsel_sysid = '1' then + idout := conv_std_logic_vector(8#123456#,16); + end if; + + if ibsel_mbrk='1' and IB_MREQ.we='1' and IB_MREQ.be0='1' then + n.mbrk := IB_MREQ.din(n.mbrk'range); + end if; + + N_REGS <= n; + + IB_SRES.ack <= ibsel; + IB_SRES.busy <= '0'; + IB_SRES.dout <= idout; + + end process proc_next; + +end syn; diff --git a/rtl/w11a/pdp11_tmu.vbom b/rtl/w11a/pdp11_tmu.vbom new file mode 100644 index 00000000..9e440b7e --- /dev/null +++ b/rtl/w11a/pdp11_tmu.vbom @@ -0,0 +1,8 @@ +# libs +../vlib/slvtypes.vhd +../vlib/simlib/simlib.vhd +../vlib/simlib/simbus.vhd +pdp11.vbom +# components +# design +pdp11_tmu.vhd diff --git a/rtl/w11a/pdp11_tmu.vhd b/rtl/w11a/pdp11_tmu.vhd new file mode 100644 index 00000000..7b790e02 --- /dev/null +++ b/rtl/w11a/pdp11_tmu.vhd @@ -0,0 +1,220 @@ +-- $Id: pdp11_tmu.vhd 314 2010-07-09 17:38:41Z mueller $ +-- +-- Copyright 2008-2010 by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, 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 complete details. +-- +------------------------------------------------------------------------------ +-- Module Name: pdp11_tmu - sim +-- Description: pdp11: trace and monitor unit +-- +-- Dependencies: - +-- +-- Test bench: tb/tb_pdp11_core (implicit) +-- Target Devices: generic +-- Tool versions: ghdl 0.18-0.25 +-- Revision History: +-- Date Rev Version Comment +-- 2010-06-26 309 1.0.5 add ibmreq.dip,.cacc,.racc to trace +-- 2009-05-10 214 1.0.4 add ENA signal (trace enable) +-- 2008-12-14 177 1.0.3 write gpr_* of DM_STAT_DP and dp_ireg_we_last +-- 2008-12-13 176 1.0.2 write only cycle currently used by tmu_conf +-- 2008-08-22 161 1.0.1 rename ubf_ -> ibf_ +-- 2008-04-19 137 1.0 Initial version +------------------------------------------------------------------------------ + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; +use ieee.std_logic_textio.all; +use std.textio.all; + +use work.slvtypes.all; +use work.simlib.all; +use work.simbus.all; +use work.pdp11.all; + +-- ---------------------------------------------------------------------------- + +entity pdp11_tmu is -- trace and monitor unit + port ( + CLK : in slbit; -- clock + ENA : in slbit := '0'; -- enable trace output + DM_STAT_DP : in dm_stat_dp_type; -- DM dpath + DM_STAT_VM : in dm_stat_vm_type; -- DM vmbox + DM_STAT_CO : in dm_stat_co_type; -- DM core + DM_STAT_SY : in dm_stat_sy_type -- DM system + ); +end pdp11_tmu; + + +architecture sim of pdp11_tmu is + + signal R_FIRST : slbit := '1'; + +begin + + proc_tm: process (CLK) + variable oline : line; + variable ipsw : slv16 := (others=>'0'); + variable ibaddr : slv16 := (others=>'0'); + variable emaddr : slv22 := (others=>'0'); + variable dp_ireg_we_last : slbit := '0'; + variable vm_ibsres_busy_last : slbit := '0'; + variable vm_ibsres_ack_last : slbit := '0'; + variable wcycle : boolean := false; + file ofile : text open write_mode is "tmu_ofile"; + begin + + + if CLK'event and CLK='1' then + + if R_FIRST = '1' then + R_FIRST <= '0'; + write(oline, string'("#")); + write(oline, string'(" clkcycle:d")); + write(oline, string'(" cpu:o")); + write(oline, string'(" dp.pc:o")); + write(oline, string'(" dp.psw:o")); + write(oline, string'(" dp.ireg:o")); + write(oline, string'(" dp.ireg_we:b")); + write(oline, string'(" dp.ireg_we_last:b")); -- is ireg_we last cycle + write(oline, string'(" dp.dsrc:o")); + write(oline, string'(" dp.ddst:o")); + write(oline, string'(" dp.dtmp:o")); + write(oline, string'(" dp.dres:o")); + write(oline, string'(" dp.gpr_adst:o")); + write(oline, string'(" dp.gpr_mode:o")); + write(oline, string'(" dp.gpr_bytop:b")); + write(oline, string'(" dp.gpr_we:b")); + + write(oline, string'(" vm.ibmreq.req:b")); + write(oline, string'(" vm.ibmreq.we:b")); + write(oline, string'(" vm.ibmreq.be0:b")); + write(oline, string'(" vm.ibmreq.be1:b")); + write(oline, string'(" vm.ibmreq.dip:b")); + write(oline, string'(" vm.ibmreq.cacc:b")); + write(oline, string'(" vm.ibmreq.racc:b")); + write(oline, string'(" vm.ibmreq.addr:o")); + write(oline, string'(" vm.ibmreq.din:o")); + write(oline, string'(" vm.ibsres.ack:b")); + write(oline, string'(" vm.ibsres.busy:b")); + write(oline, string'(" vm.ibsres.dout:o")); + + write(oline, string'(" co.cpugo:b")); + write(oline, string'(" co.cpuhalt:b")); + + write(oline, string'(" sy.emmreq.req:b")); + write(oline, string'(" sy.emmreq.we:b")); + write(oline, string'(" sy.emmreq.be:b")); + write(oline, string'(" sy.emmreq.cancel:b")); + write(oline, string'(" sy.emmreq.addr:o")); + write(oline, string'(" sy.emmreq.din:o")); + write(oline, string'(" sy.emsres.ack_r:b")); + write(oline, string'(" sy.emsres.ack_w:b")); + write(oline, string'(" sy.emsres.dout:o")); + write(oline, string'(" sy.chit:b")); + + writeline(ofile, oline); + end if; + + ipsw := (others=>'0'); + ipsw(psw_ibf_cmode) := DM_STAT_DP.psw.cmode; + ipsw(psw_ibf_pmode) := DM_STAT_DP.psw.pmode; + ipsw(psw_ibf_rset) := DM_STAT_DP.psw.rset; + ipsw(psw_ibf_pri) := DM_STAT_DP.psw.pri; + ipsw(psw_ibf_tflag) := DM_STAT_DP.psw.tflag; + ipsw(psw_ibf_cc) := DM_STAT_DP.psw.cc; + + ibaddr := "1110000000000000"; + ibaddr(DM_STAT_VM.ibmreq.addr'range) := DM_STAT_VM.ibmreq.addr; + + emaddr := (others=>'0'); + emaddr(DM_STAT_SY.emmreq.addr'range) := DM_STAT_SY.emmreq.addr; + + wcycle := false; + if dp_ireg_we_last='1' or + DM_STAT_DP.gpr_we='1' or + DM_STAT_SY.emmreq.req='1' or + DM_STAT_SY.emsres.ack_r='1' or + DM_STAT_SY.emsres.ack_w='1' or + DM_STAT_SY.emmreq.cancel='1' or + DM_STAT_VM.ibmreq.req='1' or + DM_STAT_VM.ibsres.ack='1' + then + wcycle := true; + end if; + + if DM_STAT_VM.ibsres.busy='0' and + (vm_ibsres_busy_last='1' and vm_ibsres_ack_last='0') + then + wcycle := true; + end if; + + if ENA = '0' then -- if not enabled + wcycle := false; -- force to not logged... + end if; + + if wcycle then + write(oline, conv_integer(unsigned(SB_CLKCYCLE)), right, 9); + write(oline, string'(" 0")); + writeoct(oline, DM_STAT_DP.pc, right, 7); + writeoct(oline, ipsw, right, 7); + writeoct(oline, DM_STAT_DP.ireg, right, 7); + write(oline, DM_STAT_DP.ireg_we, right, 2); + write(oline, dp_ireg_we_last, right, 2); + writeoct(oline, DM_STAT_DP.dsrc, right, 7); + writeoct(oline, DM_STAT_DP.ddst, right, 7); + writeoct(oline, DM_STAT_DP.dtmp, right, 7); + writeoct(oline, DM_STAT_DP.dres, right, 7); + writeoct(oline, DM_STAT_DP.gpr_adst, right, 2); + writeoct(oline, DM_STAT_DP.gpr_mode, right, 2); + write(oline, DM_STAT_DP.gpr_bytop, right, 2); + write(oline, DM_STAT_DP.gpr_we, right, 2); + + write(oline, DM_STAT_VM.ibmreq.req, right, 2); + write(oline, DM_STAT_VM.ibmreq.we, right, 2); + write(oline, DM_STAT_VM.ibmreq.be0, right, 2); + write(oline, DM_STAT_VM.ibmreq.be1, right, 2); + write(oline, DM_STAT_VM.ibmreq.dip, right, 2); + write(oline, DM_STAT_VM.ibmreq.cacc, right, 2); + write(oline, DM_STAT_VM.ibmreq.racc, right, 2); + writeoct(oline, ibaddr, right, 7); + writeoct(oline, DM_STAT_VM.ibmreq.din, right, 7); + write(oline, DM_STAT_VM.ibsres.ack, right, 2); + write(oline, DM_STAT_VM.ibsres.busy, right, 2); + writeoct(oline, DM_STAT_VM.ibsres.dout, right, 7); + + write(oline, DM_STAT_CO.cpugo, right, 2); + write(oline, DM_STAT_CO.cpuhalt, right, 2); + + write(oline, DM_STAT_SY.emmreq.req, right, 2); + write(oline, DM_STAT_SY.emmreq.we, right, 2); + write(oline, DM_STAT_SY.emmreq.be, right, 3); + write(oline, DM_STAT_SY.emmreq.cancel, right, 2); + writeoct(oline, emaddr, right, 9); + writeoct(oline, DM_STAT_SY.emmreq.din, right, 7); + write(oline, DM_STAT_SY.emsres.ack_r, right, 2); + write(oline, DM_STAT_SY.emsres.ack_w, right, 2); + writeoct(oline, DM_STAT_SY.emsres.dout, right, 7); + write(oline, DM_STAT_SY.chit, right, 2); + + writeline(ofile, oline); + end if; + + dp_ireg_we_last := DM_STAT_DP.ireg_we; + vm_ibsres_busy_last := DM_STAT_VM.ibsres.busy; + vm_ibsres_ack_last := DM_STAT_VM.ibsres.ack; + + end if; + + end process proc_tm; + +end sim; diff --git a/rtl/w11a/pdp11_tmu_sb.vbom b/rtl/w11a/pdp11_tmu_sb.vbom new file mode 100644 index 00000000..2646ae46 --- /dev/null +++ b/rtl/w11a/pdp11_tmu_sb.vbom @@ -0,0 +1,9 @@ +# libs +../vlib/slvtypes.vhd +../vlib/simlib/simlib.vhd +../vlib/simlib/simbus.vhd +pdp11.vbom +# components +pdp11_tmu.vbom +# design +pdp11_tmu_sb.vhd diff --git a/rtl/w11a/pdp11_tmu_sb.vhd b/rtl/w11a/pdp11_tmu_sb.vhd new file mode 100644 index 00000000..cd26fb65 --- /dev/null +++ b/rtl/w11a/pdp11_tmu_sb.vhd @@ -0,0 +1,68 @@ +-- $Id: pdp11_tmu_sb.vhd 314 2010-07-09 17:38:41Z mueller $ +-- +-- Copyright 2009- by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, 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 complete details. +-- +------------------------------------------------------------------------------ +-- Module Name: pdp11_tmu - sim +-- Description: pdp11: trace and monitor unit; simbus wrapper +-- +-- Dependencies: simbus +-- Test bench: - +-- Tool versions: xst 8.1, 8.2, 9.1, 9.2; ghdl 0.18-0.25 +-- Revision History: +-- Date Rev Version Comment +-- 2009-05-10 214 1.0 Initial version +------------------------------------------------------------------------------ + +library ieee; +use ieee.std_logic_1164.all; + +use work.slvtypes.all; +use work.simlib.all; +use work.simbus.all; +use work.pdp11.all; + +entity pdp11_tmu_sb is -- trace and mon. unit; simbus wrapper + generic ( + ENAPIN : integer := 13); -- SB_CNTL signal to use for enable + port ( + CLK : in slbit; -- clock + DM_STAT_DP : in dm_stat_dp_type; -- DM dpath + DM_STAT_VM : in dm_stat_vm_type; -- DM vmbox + DM_STAT_CO : in dm_stat_co_type; -- DM core + DM_STAT_SY : in dm_stat_sy_type -- DM system + ); +end pdp11_tmu_sb; + + +architecture sim of pdp11_tmu_sb is + + signal ENA : slbit := '0'; + +begin + + assert ENAPIN>=SB_CNTL'low and ENAPIN<=SB_CNTL'high + report "assert(ENAPIN in SB_CNTL'range)" severity failure; + + ENA <= to_x01(SB_CNTL(ENAPIN)); + + CPMON : pdp11_tmu + port map ( + CLK => CLK, + ENA => ENA, + DM_STAT_DP => DM_STAT_DP, + DM_STAT_VM => DM_STAT_VM, + DM_STAT_CO => DM_STAT_CO, + DM_STAT_SY => DM_STAT_SY + ); + +end sim; diff --git a/rtl/w11a/pdp11_ubmap.vbom b/rtl/w11a/pdp11_ubmap.vbom new file mode 100644 index 00000000..23bd1332 --- /dev/null +++ b/rtl/w11a/pdp11_ubmap.vbom @@ -0,0 +1,10 @@ +# libs +../vlib/slvtypes.vhd +../vlib/memlib/memlib.vhd +../ibus/iblib.vhd +pdp11.vbom +# components +[ghdl,isim]../vlib/memlib/ram_1swar_gen.vbom +[xst]../vlib/memlib/ram_1swar_gen_unisim.vbom +# design +pdp11_ubmap.vhd diff --git a/rtl/w11a/pdp11_ubmap.vhd b/rtl/w11a/pdp11_ubmap.vhd new file mode 100644 index 00000000..2f299fae --- /dev/null +++ b/rtl/w11a/pdp11_ubmap.vhd @@ -0,0 +1,163 @@ +-- $Id: pdp11_ubmap.vhd 314 2010-07-09 17:38:41Z mueller $ +-- +-- Copyright 2008- by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, 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 complete details. +-- +------------------------------------------------------------------------------ +-- Module Name: pdp11_ubmap - syn +-- Description: pdp11: 11/70 unibus mapper +-- +-- Dependencies: - +-- Test bench: tb/tb_pdp11_core (implicit) +-- Target Devices: generic +-- Tool versions: xst 8.1, 8.2, 9.1, 9.2; ghdl 0.18-0.25 +-- Revision History: +-- Date Rev Version Comment +-- 2008-08-22 161 1.0.1 use iblib +-- 2008-01-27 115 1.0 Initial version +------------------------------------------------------------------------------ + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; + +use work.slvtypes.all; +use work.memlib.all; +use work.iblib.all; +use work.pdp11.all; + +-- ---------------------------------------------------------------------------- + +entity pdp11_ubmap is -- 11/70 unibus mapper + port ( + CLK : in slbit; -- clock + MREQ : in slbit; -- request mapping + ADDR_UB : in slv18_1; -- UNIBUS address (in) + ADDR_PM : out slv22_1; -- physical memory address (out) + IB_MREQ : in ib_mreq_type; -- ibus request + IB_SRES : out ib_sres_type -- ibus response + ); +end pdp11_ubmap; + +architecture syn of pdp11_ubmap is + + constant ibaddr_ubmap : slv16 := conv_std_logic_vector(8#170200#,16); + + signal MAP_2_WE : slbit := '0'; + signal MAP_1_WE : slbit := '0'; + signal MAP_0_WE : slbit := '0'; + signal MAP_ADDR : slv5 := (others => '0'); -- map regs address + signal MAP_DOUT : slv22_1 := (others => '0'); -- map regs output + +begin + + MAP_2 : ram_1swar_gen -- bit 21:16 of map regs + generic map ( + AWIDTH => 5, + DWIDTH => 6) + port map ( + CLK => CLK, + WE => MAP_2_WE, + ADDR => MAP_ADDR, + DI => IB_MREQ.din(5 downto 0), + DO => MAP_DOUT(21 downto 16)); + + MAP_1 : ram_1swar_gen -- bit 15:08 of map regs + generic map ( + AWIDTH => 5, + DWIDTH => 8) + port map ( + CLK => CLK, + WE => MAP_1_WE, + ADDR => MAP_ADDR, + DI => IB_MREQ.din(15 downto 8), + DO => MAP_DOUT(15 downto 8)); + + MAP_0 : ram_1swar_gen -- bit 07:01 of map regs + generic map ( + AWIDTH => 5, + DWIDTH => 7) + port map ( + CLK => CLK, + WE => MAP_0_WE, + ADDR => MAP_ADDR, + DI => IB_MREQ.din(7 downto 1), + DO => MAP_DOUT(7 downto 1)); + + proc_comb: process (MREQ, ADDR_UB, IB_MREQ, MAP_DOUT) + variable ibsel : slbit := '0'; + variable ibusy : slbit := '0'; + variable idout : slv16 := (others=>'0'); + variable iwe2 : slbit := '0'; + variable iwe1 : slbit := '0'; + variable iwe0 : slbit := '0'; + variable iaddr : slv5 := (others=>'0'); + begin + + ibsel := '0'; + ibusy := '0'; + idout := (others=>'0'); + iwe2 := '0'; + iwe1 := '0'; + iwe0 := '0'; + iaddr := (others=>'0'); + + if IB_MREQ.req = '1' and + IB_MREQ.addr(12 downto 7)=ibaddr_ubmap(12 downto 7) then + ibsel := '1'; + end if; + + if ibsel = '1' then + if IB_MREQ.addr(1) = '1' then + idout(5 downto 0) := MAP_DOUT(21 downto 16); + else + idout(15 downto 1) := MAP_DOUT(15 downto 1); + end if; + if MREQ = '1' then -- if map request, stall ib cycle + ibusy := '1'; + end if; + end if; + + if ibsel='1' and IB_MREQ.we='1' then + if IB_MREQ.addr(1)='1' then + if IB_MREQ.be0 = '1' then + iwe2 := '1'; + end if; + else + if IB_MREQ.be1 = '1' then + iwe1 := '1'; + end if; + if IB_MREQ.be0 = '1' then + iwe0 := '1'; + end if; + end if; + end if; + + if MREQ = '1' then + iaddr := ADDR_UB(17 downto 13); + else + iaddr := IB_MREQ.addr(6 downto 2); + end if; + + MAP_ADDR <= iaddr; + MAP_2_WE <= iwe2; + MAP_1_WE <= iwe1; + MAP_0_WE <= iwe0; + + ADDR_PM <= unsigned(MAP_DOUT) + unsigned("000000000"&ADDR_UB(12 downto 1)); + + IB_SRES.ack <= ibsel; + IB_SRES.busy <= ibusy; + IB_SRES.dout <= idout; + + end process proc_comb; + +end syn; diff --git a/rtl/w11a/pdp11_vmbox.vbom b/rtl/w11a/pdp11_vmbox.vbom new file mode 100644 index 00000000..ccb820cd --- /dev/null +++ b/rtl/w11a/pdp11_vmbox.vbom @@ -0,0 +1,12 @@ +# libs +../vlib/slvtypes.vhd +../ibus/iblib.vhd +pdp11.vbom +sys_conf : sys_conf.vhd +# components +pdp11_mmu.vbom +pdp11_ubmap.vbom +../ibus/ib_sres_or_4.vbom +../ibus/ib_sres_or_2.vbom +# design +pdp11_vmbox.vhd diff --git a/rtl/w11a/pdp11_vmbox.vhd b/rtl/w11a/pdp11_vmbox.vhd new file mode 100644 index 00000000..8ac2a534 --- /dev/null +++ b/rtl/w11a/pdp11_vmbox.vhd @@ -0,0 +1,649 @@ +-- $Id: pdp11_vmbox.vhd 314 2010-07-09 17:38:41Z mueller $ +-- +-- Copyright 2006-2010 by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, 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 complete details. +-- +------------------------------------------------------------------------------ +-- Module Name: pdp11_vmbox - syn +-- Description: pdp11: virtual memory +-- +-- Dependencies: pdp11_mmu +-- pdp11_ubmap +-- ibus/ib_sres_or_4 +-- ibus/ib_sres_or_2 +-- +-- Test bench: tb/tb_pdp11_core (implicit) +-- Target Devices: generic +-- Tool versions: xst 8.1, 8.2, 9.1, 9.2, 12.1; ghdl 0.18-0.29 +-- Revision History: +-- Date Rev Version Comment +-- 2010-06-27 310 1.5 redo ibus driver logic, now ibus driven from flops +-- 2010-06-20 307 1.4.2 rename cpacc to cacc in vm_cntl_type, mmu_cntl_type +-- 2010-06-18 306 1.4.1 for cpacc: set cacc in ib_mreq, forward racc,be +-- from CP_ADDR; now all ibr handling via vmbox +-- 2010-06-13 305 1.4 rename CPADDR -> CP_ADDR +-- 2009-06-01 221 1.3.8 add dip signal in ib_mreq (set in s_ib) +-- 2009-05-30 220 1.3.7 final removal of snoopers (were already commented) +-- 2009-05-01 211 1.3.6 BUGFIX: add 177776 stack protect (SCCE) +-- 2008-08-22 161 1.3.5 rename pdp11_ibres_ -> ib_sres_, ubf_ -> ibf_ +-- 2008-04-25 138 1.3.4 add BRESET port, clear stklim with BRESET +-- 2008-04-20 137 1.3.3 add DM_STAT_VM port +-- 2008-03-19 127 1.3.2 ignore ack state when waiting on a busy IB in s_ib +-- 2008-03-02 121 1.3.1 remove snoopers +-- 2008-02-24 119 1.3 revamp paddr generation; add _ubmap +-- 2008-02-23 118 1.2.1 use sys_conf_mem_losize +-- 2008-02-17 117 1.2 use em_(mreq|sres) interface for external memory +-- 2008-01-26 114 1.1.4 rename 'ubus' to 'ib' (proper name of intbus now) +-- 2008-01-05 110 1.1.3 update snooper. +-- rename IB_MREQ(ena->req) SRES(sel->ack, hold->busy) +-- 2008-01-01 109 1.1.2 Use IB_SRES_(CPU|EXT); use r./n. coding style, move +-- all status into regs_type. add intbus HOLD support. +-- 2007-12-30 108 1.1.1 use ubf_byte[01] +-- 2007-12-30 107 1.1 Use IB_MREQ/IB_SRES interface now; remove DMA port +-- 2007-09-16 83 1.0.2 Use ram_1swsr_wfirst_gen, not ram_2swsr_wfirst_gen +-- 2nd port was unused, connected ADDR caused slow net +-- 2007-06-14 56 1.0.1 Use slvtypes.all +-- 2007-05-12 26 1.0 Initial version +------------------------------------------------------------------------------ + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; + +use work.slvtypes.all; +use work.iblib.all; +use work.pdp11.all; +use work.sys_conf.all; + +-- ---------------------------------------------------------------------------- + +entity pdp11_vmbox is -- virtual memory + port ( + CLK : in slbit; -- clock + GRESET : in slbit; -- global reset + CRESET : in slbit; -- console reset + BRESET : in slbit; -- ibus reset + CP_ADDR : in cp_addr_type; -- console port address + VM_CNTL : in vm_cntl_type; -- vm control port + VM_ADDR : in slv16; -- vm address + VM_DIN : in slv16; -- vm data in + VM_STAT : out vm_stat_type; -- vm status port + VM_DOUT : out slv16; -- vm data out + EM_MREQ : out em_mreq_type; -- external memory: request + EM_SRES : in em_sres_type; -- external memory: response + MMU_MONI : in mmu_moni_type; -- mmu monitor port + IB_MREQ_M : out ib_mreq_type; -- ibus request (master) + IB_SRES_CPU : in ib_sres_type; -- ibus response (CPU registers) + IB_SRES_EXT : in ib_sres_type; -- ibus response (external devices) + DM_STAT_VM : out dm_stat_vm_type -- debug and monitor status + ); +end pdp11_vmbox; + +architecture syn of pdp11_vmbox is + + constant ibaddr_slim : slv16 := conv_std_logic_vector(8#177774#,16); + constant atowidth : natural := 5; -- size of access timeout counter + + type state_type is ( + s_idle, -- s_idle: wait for vm_cntl request + s_mem_w, -- s_mem_w: check mmu, wait for memory + s_ib_w, -- s_ib_w: wait for ibus + s_ib_wend, -- s_ib_wend: ibus write completion + s_ib_rend, -- s_ib_rend: ibus read completion + s_idle_mw_ib, -- s_idle_mw_ib: wait macc write (ibus) + s_idle_mw_mem, -- s_idle_mw_mem: wait macc write (mem) + s_mem_mw_w, -- s_mem_mw_w: wait for memory (macc) + s_fail, -- s_fail: vmbox fatal error catcher + s_errrsv, -- s_errrsv: red stack violation + s_errib -- s_errib: ibus error handler + ); + + type regs_type is record -- state registers + state : state_type; -- state + wacc : slbit; -- write access + macc : slbit; -- modify access (r-m-w sequence) + cacc : slbit; -- console access + bytop : slbit; -- byte operation + kstack : slbit; -- access through kernel stack + ysv : slbit; -- yellow stack violation detected + vaok : slbit; -- virtual address valid (from MMU) + trap_mmu : slbit; -- mmu trace trap requested + mdin : slv16; -- data input (memory order) + paddr : slv22; -- physical address register + atocnt : slv(atowidth-1 downto 0); -- access timeout counter + ibreq : slbit; -- ibus req signal + ibwe : slbit; -- ibus we signal + ibbe : slv2; -- ibus be0,be1 signals + ibdip : slbit; -- ibus dip signal + ibcacc : slbit; -- ibus cacc signal + ibracc : slbit; -- ibus racc signal + ibaddr : slv13_1; -- ibus addr signal + ibdout : slv16; -- ibus dout register + end record regs_type; + + constant atocnt_init : slv(atowidth-1 downto 0) := (others=>'1'); + constant regs_init : regs_type := ( + s_idle, -- state + '0','0','0','0', -- wacc,macc,cacc,bytop + '0','0','0','0', -- kstack,ysv,vaok,trap_mmu + (others=>'0'), -- mdin + (others=>'0'), -- paddr + atocnt_init, -- atocnt + '0','0',"00", -- ibreq,ibwe,ibbe + '0','0','0', -- ibdip,ibcacc,ibracc + (others=>'0'), -- ibaddr + (others=>'0') -- ibdout + ); + + signal R_REGS : regs_type := regs_init; + signal N_REGS : regs_type := regs_init; + + signal R_SLIM : slv8 := (others=>'0'); -- stack limit register + + signal MMU_CNTL : mmu_cntl_type := mmu_cntl_init; + signal MMU_STAT : mmu_stat_type := mmu_stat_init; + signal PADDRH : slv16 := (others=>'0'); + + signal IBSEL_SLIM :slbit := '0'; -- select stack limit reg + signal IB_SRES_SLIM : ib_sres_type := ib_sres_init; + signal IB_SRES_MMU : ib_sres_type := ib_sres_init; + signal IB_SRES_UBMAP : ib_sres_type := ib_sres_init; + + signal UBMAP_MREQ : slbit := '0'; + signal UBMAP_ADDR_PM : slv22_1 := (others=>'0'); + + signal IB_MREQ : ib_mreq_type := ib_mreq_init; -- ibus request (local) + signal IB_SRES : ib_sres_type := ib_sres_init; -- ibus response (local) + signal IB_SRES_INT : ib_sres_type := ib_sres_init; -- ibus response (cpu) + +begin + + MMU : pdp11_mmu + port map ( + CLK => CLK, + CRESET => CRESET, + BRESET => BRESET, + CNTL => MMU_CNTL, + VADDR => VM_ADDR, + MONI => MMU_MONI, + STAT => MMU_STAT, + PADDRH => PADDRH, + IB_MREQ => IB_MREQ, + IB_SRES => IB_SRES_MMU + ); + + UBMAP : pdp11_ubmap + port map ( + CLK => CLK, + MREQ => UBMAP_MREQ, + ADDR_UB => CP_ADDR.addr(17 downto 1), + ADDR_PM => UBMAP_ADDR_PM, + IB_MREQ => IB_MREQ, + IB_SRES => IB_SRES_UBMAP + ); + + IB_SRES_OR_INT : ib_sres_or_4 + port map ( + IB_SRES_1 => IB_SRES_CPU, + IB_SRES_2 => IB_SRES_SLIM, + IB_SRES_3 => IB_SRES_MMU, + IB_SRES_4 => IB_SRES_UBMAP, + IB_SRES_OR => IB_SRES_INT + ); + + IB_SRES_OR_ALL : ib_sres_or_2 + port map ( + IB_SRES_1 => IB_SRES_INT, + IB_SRES_2 => IB_SRES_EXT, + IB_SRES_OR => IB_SRES + ); + + proc_ibsel: process (IB_MREQ) + variable islim : slbit := '0'; + begin + islim := '0'; + if IB_MREQ.req='1' and IB_MREQ.addr=ibaddr_slim(12 downto 1) then + islim := '1'; + end if; + IBSEL_SLIM <= islim; + IB_SRES_SLIM.ack <= islim; + IB_SRES_SLIM.busy <= '0'; + end process proc_ibsel; + + proc_ibdout : process (IBSEL_SLIM, R_SLIM) + variable slimout : slv16 := (others=>'0'); + begin + slimout := (others=>'0'); + if IBSEL_SLIM = '1' then + slimout(ibf_byte1) := R_SLIM; + end if; + IB_SRES_SLIM.dout <= slimout; + end process proc_ibdout; + + proc_slim: process (CLK) + begin + if CLK'event and CLK='1' then + if BRESET = '1' then + R_SLIM <= (others=>'0'); + elsif IB_MREQ.we='1' and IBSEL_SLIM='1' then + if IB_MREQ.be1 = '1' then + R_SLIM <= IB_MREQ.din(ibf_byte1); + end if; + end if; + end if; + end process proc_slim; + + proc_regs: process (CLK) + begin + if CLK'event and CLK='1' then + if GRESET = '1' then + R_REGS <= regs_init; + else + R_REGS <= N_REGS; + end if; + end if; + end process proc_regs; + + proc_next: process (R_REGS, R_SLIM, CP_ADDR, VM_CNTL, VM_DIN, VM_ADDR, + IB_SRES, UBMAP_ADDR_PM, + EM_SRES, MMU_STAT, PADDRH) + + variable r : regs_type := regs_init; + variable n : regs_type := regs_init; + + variable ivm_stat : vm_stat_type := vm_stat_init; + variable ivm_dout : slv16 := (others=>'0'); + variable ipaddr : slv22 := (others=>'0'); + variable iem_mreq : em_mreq_type := em_mreq_init; + variable immu_cntl : mmu_cntl_type := mmu_cntl_init; + + variable ato_go : slbit := '0'; + variable ato_end : slbit := '0'; + + variable is_stackyellow : slbit := '1'; -- VM_ADDR in yellow stack zone + variable is_stackred : slbit := '1'; -- VM_ADDR in red stack zone + + variable iubmap_mreq : slbit := '0'; + variable paddr_mmu : slbit := '0'; + variable paddr_sel : slv2 := "00"; + constant c_paddr_sel_vmaddr : slv2 := "00"; + constant c_paddr_sel_rpaddr : slv2 := "01"; + constant c_paddr_sel_cacc : slv2 := "10"; + constant c_paddr_sel_ubmap : slv2 := "11"; + + variable paddr_iopage : slv9 := (others=>'0'); + + begin + + r := R_REGS; + n := R_REGS; + + n.state := s_fail; + + ivm_stat := vm_stat_init; + ivm_dout := EM_SRES.dout; + immu_cntl := mmu_cntl_init; + + iem_mreq := em_mreq_init; + iem_mreq.din := VM_DIN; + + if VM_CNTL.bytop = '0' then -- if word access + iem_mreq.be := "11"; -- both be's + else + if VM_ADDR(0) = '0' then -- if low byte + iem_mreq.be := "01"; + else -- if high byte + iem_mreq.be := "10"; + iem_mreq.din(ibf_byte1) := VM_DIN(ibf_byte0); + end if; + end if; + + iubmap_mreq :='0'; + + paddr_mmu := '1'; -- ipaddr selector, used in s_idle + -- and overwritten in s_idle_mw_mem + paddr_sel := "00"; + if MMU_STAT.ena_mmu='0' or VM_CNTL.cacc='1' then + paddr_mmu := '0'; + paddr_sel := c_paddr_sel_vmaddr; + if VM_CNTL.cacc = '1' then + if CP_ADDR.ena_ubmap='1' and MMU_STAT.ena_ubmap='1' then + paddr_sel := c_paddr_sel_ubmap; + else + paddr_sel := c_paddr_sel_cacc; + end if; + end if; + end if; + + paddr_iopage := "111111111"; -- iopage match pattern (for 22 bit) + if r.cacc = '1' then + if CP_ADDR.ena_22bit = '0' then + paddr_iopage := "000000111"; -- 16 bit cacc + end if; + else + if MMU_STAT.ena_mmu = '0' then + paddr_iopage := "000000111"; -- 16 bit mode + else + if MMU_STAT.ena_22bit = '0' then + paddr_iopage := "000011111"; -- 18 bit mode + end if; + end if; + end if; + + ato_go := '0'; -- default: keep access timeout in reset + ato_end := '0'; + if unsigned(r.atocnt) = 0 then -- if access timeout count at zero + ato_end := '1'; -- signal expiration + end if; + + is_stackyellow := '0'; + is_stackred := '0'; + if unsigned(VM_ADDR(15 downto 8)) <= unsigned(R_SLIM) then + is_stackyellow := '1'; + if unsigned(VM_ADDR(7 downto 5)) /= 7 then -- below 340 + is_stackred := '1'; + end if; + end if; + + if VM_ADDR(15 downto 1) = "111111111111111" then -- vaddr == 177776 + is_stackred := '1'; + end if; + + immu_cntl.wacc := VM_CNTL.wacc; + immu_cntl.macc := VM_CNTL.macc; + immu_cntl.cacc := VM_CNTL.cacc; + immu_cntl.dspace := VM_CNTL.dspace; + immu_cntl.mode := VM_CNTL.mode; + immu_cntl.trap_done := VM_CNTL.trap_done; + + case r.state is + when s_idle => -- s_idle: wait for vm_cntl request -- + n.state := s_idle; + iubmap_mreq := '1'; -- activate ubmap always in s_idle + + if VM_CNTL.req = '1' then + n.wacc := VM_CNTL.wacc; + n.macc := VM_CNTL.macc; + n.cacc := VM_CNTL.cacc; + n.bytop := VM_CNTL.bytop; + n.kstack := VM_CNTL.kstack; + n.ysv := '0'; + n.vaok := MMU_STAT.vaok; + n.trap_mmu := MMU_STAT.trap; + n.mdin := iem_mreq.din; + -- n.paddr assignment handled separately in 'if state=s_idle' at the + -- end. + + immu_cntl.req := '1'; + + if VM_CNTL.wacc='1' and VM_CNTL.macc='1' then + n.state := s_fail; + + elsif VM_CNTL.kstack='1' and VM_CNTL.intrsv='0' and + is_stackred='1' then + n.state := s_errrsv; + + else + iem_mreq.req := '1'; + iem_mreq.we := VM_CNTL.wacc; + if VM_CNTL.kstack='1'and VM_CNTL.intrsv='0' then + n.ysv := is_stackyellow; + end if; + n.state := s_mem_w; + end if; + end if; + + when s_mem_w => -- s_mem_w: check mmu, wait for memory + + if r.bytop='0' and r.paddr(0)='1' then -- odd address ? + ivm_stat.err := '1'; + ivm_stat.err_odd := '1'; + ivm_stat.err_rsv := r.kstack; -- escalate to rsv if kstack + iem_mreq.cancel := '1'; -- cancel pending mem request + n.state := s_idle; + + elsif r.vaok = '0' then -- MMU abort ? + ivm_stat.err := '1'; + ivm_stat.err_mmu := '1'; + ivm_stat.err_rsv := r.kstack; -- escalate to rsv if kstack + iem_mreq.cancel := '1'; -- cancel pending mem request + n.state := s_idle; + + else + if r.paddr(21 downto 13) = paddr_iopage then + -- I/O page decoded + iem_mreq.cancel := '1'; -- cancel pending mem request + n.ibreq := '1'; -- setup ibus request + n.ibwe := r.wacc; + n.ibcacc := r.cacc; + n.ibracc := r.cacc and CP_ADDR.racc; + n.ibbe := "11"; + if r.cacc = '1' then -- console access ? + n.ibbe := CP_ADDR.be; + else -- cpu access ? + if r.bytop = '1' then + if r.paddr(0) = '0' then + n.ibbe(1) := '0'; + else + n.ibbe(0) := '0'; + end if; + end if; + end if; + n.ibdip := r.macc; + n.ibaddr := r.paddr(12 downto 1); + n.state := s_ib_w; + + else + if unsigned(r.paddr(21 downto 6)) > sys_conf_mem_losize then + ivm_stat.err := '1'; + ivm_stat.err_nxm := '1'; + ivm_stat.err_rsv := r.kstack; -- escalate to rsv if kstack + iem_mreq.cancel := '1'; -- cancel pending mem request + n.state := s_idle; + + else + + if EM_SRES.ack_r='1' or EM_SRES.ack_w='1' then + ivm_stat.ack := '1'; + ivm_stat.trap_ysv := r.ysv; + ivm_stat.trap_mmu := r.trap_mmu; + if r.macc='1' and r.wacc='0' then + n.state := s_idle_mw_mem; + else + n.state := s_idle; + end if; + else + n.state := s_mem_w; -- keep waiting + end if; + + end if; + end if; + end if; + + when s_ib_w => -- s_ib_w: wait for ibus ------------- + ato_go := '1'; -- activate timeout counter + + n.ibreq := '0'; -- end cycle, unless busy seen + n.ibwe := '0'; + + if IB_SRES.ack='1' and IB_SRES.busy='0' then -- ibus cycle finished + if r.wacc = '1' then + n.state := s_ib_wend; + else + n.ibdout := IB_SRES.dout; + n.state := s_ib_rend; + end if; + elsif IB_SRES.busy='1' and ato_end='0' then + n.ibreq := r.ibreq; -- continue ibus cycle + n.ibwe := r.ibwe; + n.state := s_ib_w; + else + n.state := s_errib; + end if; + + when s_ib_wend => -- s_ib_wend: ibus write completion -- + ivm_stat.ack := '1'; + n.state := s_idle; + + when s_ib_rend => -- s_ib_rend: ibus read completion --- + ivm_stat.ack := '1'; + ivm_dout := r.ibdout; + if r.macc='1' and r.wacc='0' then -- first part of read-mod-write + n.state := s_idle_mw_ib; + else + n.state := s_idle; + end if; + + when s_idle_mw_ib => -- s_idle_mw_ib: wait macc write (ibus) + n.state := s_idle_mw_ib; + if r.ibbe = "10" then + iem_mreq.din(ibf_byte1) := VM_DIN(ibf_byte0); + end if; + if VM_CNTL.req = '1' then + n.wacc := VM_CNTL.wacc; + n.macc := VM_CNTL.macc; + n.mdin := iem_mreq.din; + if VM_CNTL.wacc='0' or VM_CNTL.macc='0' then + n.state := s_fail; + else + n.ibreq := '1'; -- start ibus write cycle + n.ibwe := '1'; -- Note: all other ibus drivers + -- already set in 1st part + n.state := s_ib_w; + end if; + end if; + + when s_idle_mw_mem => -- s_idle_mw_mem: wait macc write (mem) + n.state := s_idle_mw_mem; + + paddr_mmu := '0'; + paddr_sel := c_paddr_sel_rpaddr; + + if VM_CNTL.bytop = '0' then -- if word access + iem_mreq.be := "11"; -- both be's + else + if r.paddr(0) = '0' then -- if low byte + iem_mreq.be := "01"; + else -- if high byte + iem_mreq.be := "10"; + iem_mreq.din(ibf_byte1) := VM_DIN(ibf_byte0); + end if; + end if; + + if VM_CNTL.req = '1' then + n.wacc := VM_CNTL.wacc; + n.macc := VM_CNTL.macc; + n.bytop := VM_CNTL.bytop; + n.mdin := iem_mreq.din; + + if VM_CNTL.wacc='0' or VM_CNTL.macc='0' then + n.state := s_fail; + else + iem_mreq.req := '1'; + iem_mreq.we := '1'; + n.state := s_mem_mw_w; + end if; + end if; + + when s_mem_mw_w => -- s_mem_mw_w: wait for memory (macc) + if EM_SRES.ack_w = '1' then + ivm_stat.ack := '1'; + n.state := s_idle; + else + n.state := s_mem_mw_w; -- keep waiting + end if; + + when s_fail => -- s_fail: vmbox fatal error catcher + ivm_stat.fail := '1'; + n.state := s_idle; + + when s_errrsv => -- s_errrsv: red stack violation ----- + ivm_stat.err := '1'; + ivm_stat.err_rsv := '1'; + n.state := s_idle; + + when s_errib => -- s_errib: ibus error handler ------- + ivm_stat.err := '1'; + ivm_stat.err_iobto := '1'; + ivm_stat.err_rsv := r.kstack; -- escalate to rsv if kstack + n.state := s_idle; + + when others => null; + end case; + + if r.bytop='1' and r.paddr(0)='1' then + ivm_dout(ibf_byte0) := ivm_dout(ibf_byte1); + end if; + + if ato_go = '0' then -- handle access timeout counter + n.atocnt := atocnt_init; -- if ato_go=0, keep in reset + else + n.atocnt := unsigned(r.atocnt) - 1;-- otherwise count down + end if; + + ipaddr := (others=>'0'); + if paddr_mmu = '1' then + ipaddr( 5 downto 0) := VM_ADDR(5 downto 0); + ipaddr(21 downto 6) := PADDRH; + if MMU_STAT.ena_22bit = '0' then + ipaddr(21 downto 18) := (others=>'0'); + end if; + else + case paddr_sel is + when c_paddr_sel_vmaddr => + ipaddr(15 downto 0) := VM_ADDR(15 downto 0); + when c_paddr_sel_rpaddr => + ipaddr := r.paddr; + when c_paddr_sel_cacc => + ipaddr := CP_ADDR.addr & '0'; + if CP_ADDR.ena_22bit = '0' then + ipaddr(21 downto 16) := (others=>'0'); + end if; + when c_paddr_sel_ubmap => + ipaddr := UBMAP_ADDR_PM & '0'; + when others => null; + end case; + end if; + + if r.state = s_idle then + n.paddr := ipaddr; + end if; + + iem_mreq.addr := ipaddr(21 downto 1); + + N_REGS <= n; + + UBMAP_MREQ <= iubmap_mreq; + + IB_MREQ.req <= r.ibreq; + IB_MREQ.we <= r.ibwe; + IB_MREQ.be0 <= r.ibbe(0); + IB_MREQ.be1 <= r.ibbe(1); + IB_MREQ.dip <= r.ibdip; + IB_MREQ.cacc <= r.ibcacc; + IB_MREQ.racc <= r.ibracc; + IB_MREQ.addr <= r.ibaddr; + IB_MREQ.din <= r.mdin; + + VM_DOUT <= ivm_dout; + VM_STAT <= ivm_stat; + MMU_CNTL <= immu_cntl; + + EM_MREQ <= iem_mreq; + + end process proc_next; + + IB_MREQ_M <= IB_MREQ; -- external drive master port + + DM_STAT_VM.ibmreq <= IB_MREQ; + DM_STAT_VM.ibsres <= IB_SRES; + +end syn; diff --git a/rtl/w11a/sys_conf.vhd b/rtl/w11a/sys_conf.vhd new file mode 100644 index 00000000..cb0ceba8 --- /dev/null +++ b/rtl/w11a/sys_conf.vhd @@ -0,0 +1,47 @@ +-- $Id: sys_conf.vhd 314 2010-07-09 17:38:41Z mueller $ +-- +-- Copyright 2007-2008 by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, 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 complete details. +-- +------------------------------------------------------------------------------ +-- Package Name: sys_conf +-- Description: Default definitions for pdp11core (for simple test benches) +-- +-- Dependencies: - +-- Tool versions: xst 8.1, 8.2, 9.1, 9.2; ghdl 0.18-0.25 +-- Revision History: +-- Date Rev Version Comment +-- 2008-02-23 118 1.0 Initial version +------------------------------------------------------------------------------ + +library ieee; +use ieee.std_logic_1164.all; + +use work.slvtypes.all; + +package sys_conf is + + constant sys_conf_bram_awidth : integer := 15; -- 32 kB BRAM + constant sys_conf_mem_losize : integer := 8#000777#;-- 32 kByte +-- constant sys_conf_bram_awidth : integer := 14; -- 16 kB BRAM +-- constant sys_conf_mem_losize : integer := 8#000377#;-- 16 kByte + +end package sys_conf; + +-- Note: mem_losize holds 16 MSB of the PA of the addressable memory +-- 2 211 111 111 110 000 000 000 +-- 1 098 765 432 109 876 543 210 +-- +-- 0 000 000 011 111 111 000 000 -> 00037777 --> 14bit --> 16 kByte +-- 0 000 000 011 111 111 000 000 -> 00077777 --> 15bit --> 32 kByte +-- 0 011 111 111 111 111 000 000 -> 03777777 --> 20bit --> 1 MByte +-- 1 110 111 111 111 111 000 000 -> 16777777 --> 22bit --> 4 MByte +-- upper 256 kB excluded for 11/70 UB diff --git a/rtl/w11a/tb/.cvsignore b/rtl/w11a/tb/.cvsignore new file mode 100644 index 00000000..c7ccb067 --- /dev/null +++ b/rtl/w11a/tb/.cvsignore @@ -0,0 +1,22 @@ +tb_pdp11_core +tb_pdp11_core_stim +tb_pdp11_core_[sft]sim +tb_pdp11_core_ISim +tb_pdp11_core_ISim_[sft]sim +tb_rritba_pdp11core +tb_rritba_pdp11core_[sft]sim +tb_rritba_pdp11core_ISim +tb_rritba_pdp11core_ISim_[sft]sim +tb_rritba_stim +tb_rripdp_pdp11core +tb_rripdp_pdp11core_[sft]sim +tb_rripdp_pdp11core_ISim +tb_rripdp_pdp11core_ISim_[sft]sim +tb_rripdp_stim +tb_rriext_pdp11core +tb_rriext_pdp11core_[sft]sim +tb_rriext_fifo_rx +tb_rriext_fifo_tx +tb_rriext_conf +tb_pdp11_core_stim.scmd +tmu_ofile diff --git a/rtl/w11a/tb/Makefile b/rtl/w11a/tb/Makefile new file mode 100644 index 00000000..ba5d1cb5 --- /dev/null +++ b/rtl/w11a/tb/Makefile @@ -0,0 +1,57 @@ +# $Id: Makefile 311 2010-06-30 17:52:37Z mueller $ +# +# Revision History: +# Date Rev Version Comment +# 2009-11-22 252 1.2 add ISim support +# 2007-09-16 83 1.1.1 add include *.o.dep_ghdl +# 2007-07-06 64 1.1 use vbom's +# 2007-06-17 58 1.0 Initial version +# +EXE_all = tb_pdp11_core tb_rritba_pdp11core tb_rripdp_pdp11core \ + tb_rriext_pdp11core +# +# +.phony : all all_ssim all_tsim clean +# +all : $(EXE_all) +all_ssim : $(EXE_all:=_ssim) +all_tsim : $(EXE_all:=_tsim) +# +clean : ise_clean ghdl_clean isim_clean +# +#----- +# +include $(RETROBASE)/rtl/vlib/Makefile.ghdl +include $(RETROBASE)/rtl/vlib/Makefile.isim +include $(RETROBASE)/rtl/vlib/Makefile.xflow +# +VBOM_all = $(wildcard *.vbom) +# +include $(VBOM_all:.vbom=.dep_xst) +include $(VBOM_all:.vbom=.dep_ghdl) +include $(VBOM_all:.vbom=.dep_isim) +include $(wildcard *.o.dep_ghdl) +# +#----- +# time ~/misc_walter/p11_util/bin/pdp11 $*.scmd > $*.simh_raw_log +%.simh_log: %.dat + tbdat2simh $*.dat > $*.scmd + time pdp11 $*.scmd > $*.simh_raw_log + simdat_check $*.simh_raw_log > $*.simh_log + grep FAIL $*.simh_log + +check_dsim: tb_pdp11_core tb_pdp11_core_stim.dat + time tbw tb_pdp11_core |\ + tee tb_pdp11_core_dsim.log |\ + egrep "(FAIL|DONE)" || true + @ echo "# diff to reference" + diff tb_pdp11_core_out_ref.dat tb_pdp11_core_dsim.log + +check_ssim: tb_pdp11_core_ssim tb_pdp11_core_stim.dat + time tbw tb_pdp11_core_ssim |\ + tee tb_pdp11_core_ssim.log |\ + egrep "(FAIL|DONE)" || true + @ echo "# diff to reference" + diff tb_pdp11_core_out_ref.dat tb_pdp11_core_ssim.log + +check_simh: tb_pdp11_core_stim.simh_log diff --git a/rtl/w11a/tb/tb_pdp11_core.vbom b/rtl/w11a/tb/tb_pdp11_core.vbom new file mode 100644 index 00000000..7c98753a --- /dev/null +++ b/rtl/w11a/tb/tb_pdp11_core.vbom @@ -0,0 +1,11 @@ +# libs +../../vlib/slvtypes.vhd +../../vlib/simlib/simlib.vhd +../../vlib/simlib/simbus.vhd +../pdp11_sim.vhd +../pdp11.vbom +# components +../../vlib/simlib/simclk.vbom +tbd_pdp11_core : tbd_pdp11_core.vbom +# design +tb_pdp11_core.vhd diff --git a/rtl/w11a/tb/tb_pdp11_core.vhd b/rtl/w11a/tb/tb_pdp11_core.vhd new file mode 100644 index 00000000..47186020 --- /dev/null +++ b/rtl/w11a/tb/tb_pdp11_core.vhd @@ -0,0 +1,668 @@ +-- $Id: tb_pdp11_core.vhd 314 2010-07-09 17:38:41Z mueller $ +-- +-- Copyright 2006-2010 by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, 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 complete details. +-- +------------------------------------------------------------------------------ +-- Module Name: tb_pdp11_core - sim +-- Description: Test bench for pdp11_core +-- +-- Dependencies: simlib/simclk +-- tbd_pdp11_core [UUT] +-- pdp11_intmap +-- +-- To test: pdp11_core +-- +-- Target Devices: generic +-- Tool versions: ghdl 0.18-0.29; ISim 11.3 +-- +-- Verified (with tb_pdp11_core_stim.dat): +-- Date Rev Code ghdl ise Target Comment +-- 2010-06-20 308 - 0.29 - - u:ok +-- 2009-11-22 252 - 0.26 - - u:ok +-- 2007-12-30 107 - 0.25 - - u:ok +-- 2007-10-26 92 _tsim 0.26 8.1.03 I27 xc3s1000 c:fail -> blog_ghdl +-- 2007-10-26 92 _tsim 0.26 9.2.02 J39 xc3s1000 d:ok (full tsim!) +-- 2007-10-26 92 _tsim 0.26 9.1 J30 xc3s1000 d:ok (full tsim!) +-- 2007-10-26 92 _tsim 0.26 8.2.03 I34 xc3s1000 d:ok (full tsim!) +-- 2007-10-26 92 _fsim 0.26 8.2.03 I34 xc3s1000 d:ok +-- 2007-10-26 92 _ssim 0.26 8.2.03 I34 xc3s1000 d:ok +-- 2007-10-08 88 _ssim 0.18 8.2.03 I34 xc3s1000 d:ok +-- 2007-10-08 88 _ssim 0.18 9.1 J30 xc3s1000 d:ok +-- 2007-10-08 88 _ssim 0.18 9.2.02 J39 xc3s1000 d:ok +-- 2007-10-07 88 _ssim 0.26 8.1.03 I27 xc3s1000 c:ok +-- 2007-10-07 88 _ssim 0.26 8.1 I24 xc3s1000 c:fail -> blog_webpack +-- 2007-10-07 88 - 0.26 - - c:ok +-- +-- Revision History: +-- Date Rev Version Comment +-- 2010-06-20 308 1.2.2 add wibrb, ribr, wibr commands for ibr accesses +-- 2010-06-20 307 1.2.1 add CP_ADDR_racc, CP_ADDR_be to tbd interface +-- 2010-06-13 305 1.2 add CP_CNTL_rnum and CP_ADDR_...; emulate old +-- 'sta' behaviour with new 'stapc' command; rename +-- lal,lah -> wal,wah and implement locally; new +-- output format with cpfunc name +-- 2010-06-05 301 1.1.14 renamed .rpmon -> .rbmon +-- 2010-04-24 281 1.1.13 use direct instatiation for tbd_ +-- 2009-11-28 253 1.1.12 add hack for ISim 11.3 +-- 2009-05-10 214 1.1.11 add .scntl command (set/clear SB_CNTL bits) +-- 2008-08-29 163 1.1.10 allow, but ignore, the wtlam command +-- 2008-05-03 143 1.1.9 rename _cpursta->_cpurust +-- 2008-04-27 140 1.1.8 use cpursta interface, remove cpufail +-- 2008-04-19 137 1.1.7 use SB_CLKCYCLE now +-- 2008-03-24 129 1.1.6 CLK_CYCLE now 31 bits +-- 2008-03-02 121 1.1.5 redo sta,cont,wtgo commands; sta,cont now wait for +-- command completion, wtgo waits for CPU to halt. +-- added .cerr,.merr directive, check cmd(m)err state +-- added .sdef as ignored directive +-- 2008-02-24 119 1.1.4 added lah,rps,wps command +-- 2008-01-26 114 1.1.3 add handling of d=val,msk +-- 2008-01-06 111 1.1.2 remove .eireq, EI's now handled in tbd_pdp11_core +-- 2007-10-26 92 1.0.2 use DONE timestamp at end of execution +-- 2007-10-12 88 1.0.1 avoid ieee.std_logic_unsigned, use cast to unsigned +-- 2007-09-02 79 1.0 Initial version +------------------------------------------------------------------------------ + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; +use ieee.std_logic_textio.all; +use std.textio.all; + +use work.slvtypes.all; +use work.simlib.all; +use work.simbus.all; +use work.pdp11_sim.all; +use work.pdp11.all; + +entity tb_pdp11_core is +end tb_pdp11_core; + +architecture sim of tb_pdp11_core is + + signal CLK : slbit := '0'; + signal RESET : slbit := '0'; + signal UNUSEDSIGNAL : slbit := '0'; -- FIXME: hack to make ISim 11.3 happy + signal CP_CNTL_req : slbit := '0'; + signal CP_CNTL_func : slv5 := (others=>'0'); + signal CP_CNTL_rnum : slv3 := (others=>'0'); + signal CP_ADDR_addr : slv22_1 := (others=>'0'); + signal CP_ADDR_racc : slbit := '0'; + signal CP_ADDR_be : slv2 := "11"; + signal CP_ADDR_ena_22bit : slbit := '0'; + signal CP_ADDR_ena_ubmap : slbit := '0'; + signal CP_DIN : slv16 := (others=>'0'); + signal CP_STAT_cmdbusy : slbit := '0'; + signal CP_STAT_cmdack : slbit := '0'; + signal CP_STAT_cmderr : slbit := '0'; + signal CP_STAT_cmdmerr : slbit := '0'; + signal CP_STAT_cpugo : slbit := '0'; + signal CP_STAT_cpustep : slbit := '0'; + signal CP_STAT_cpuhalt : slbit := '0'; + signal CP_STAT_cpurust : slv4 := (others=>'0'); + signal CP_DOUT : slv16 := (others=>'0'); + + signal CLK_STOP : slbit := '0'; + + signal R_CHKDAT : slv16 := (others=>'0'); + signal R_CHKMSK : slv16 := (others=>'0'); + signal R_CHKREQ : slbit := '0'; + + signal R_WAITCMD : slbit := '0'; + signal R_WAITSTEP : slbit := '0'; + signal R_WAITGO : slbit := '0'; + signal R_WAITOK : slbit := '0'; + signal R_CP_STAT : cp_stat_type := cp_stat_init; + signal R_CP_DOUT : slv16 := (others=>'0'); + +begin + + SYSCLK : simclk + generic map ( + PERIOD => clock_period, + OFFSET => clock_offset) + port map ( + CLK => CLK, + CLK_CYCLE => SB_CLKCYCLE, + CLK_STOP => CLK_STOP + ); + + UUT: entity work.tbd_pdp11_core + port map ( + CLK => CLK, + RESET => RESET, + CP_CNTL_req => CP_CNTL_req, + CP_CNTL_func => CP_CNTL_func, + CP_CNTL_rnum => CP_CNTL_rnum, + CP_ADDR_addr => CP_ADDR_addr, + CP_ADDR_racc => CP_ADDR_racc, + CP_ADDR_be => CP_ADDR_be, + CP_ADDR_ena_22bit => CP_ADDR_ena_22bit, + CP_ADDR_ena_ubmap => CP_ADDR_ena_ubmap, + CP_DIN => CP_DIN, + CP_STAT_cmdbusy => CP_STAT_cmdbusy, + CP_STAT_cmdack => CP_STAT_cmdack, + CP_STAT_cmderr => CP_STAT_cmderr, + CP_STAT_cmdmerr => CP_STAT_cmdmerr, + CP_STAT_cpugo => CP_STAT_cpugo, + CP_STAT_cpustep => CP_STAT_cpustep, + CP_STAT_cpuhalt => CP_STAT_cpuhalt, + CP_STAT_cpurust => CP_STAT_cpurust, + CP_DOUT => CP_DOUT + ); + + proc_stim: process + file ifile : text open read_mode is "tb_pdp11_core_stim"; + variable iline : line; + variable oline : line; + variable idelta : integer := 0; + variable idummy : integer := 0; + variable dcycle : integer := 0; + variable irqline : integer := 0; + variable ireq : boolean := false; + variable ifunc : slv5 := (others=>'0'); + variable irnum : slv3 := (others=>'0'); + variable idin : slv16 := (others=>'0'); + variable imsk : slv16 := (others=>'1'); + variable ichk : boolean := false; + variable idosta: slbit := '0'; + + variable ok : boolean; + variable dname : string(1 to 6) := (others=>' '); + variable rind : integer := 0; + variable nblk : integer := 0; + variable xmicmd : string(1 to 3) := (others=>' '); + variable iwtstp : boolean := false; + variable iwtgo : boolean := false; + variable icerr : integer := 0; + variable imerr : integer := 0; + variable to_cmd : integer := 50; + variable to_stp : integer := 100; + variable to_go : integer := 5000; + variable ien : slbit := '0'; + variable ibit : integer := 0; + variable imemi : boolean := false; + variable ioff : slv6 := (others=>'0'); + variable idoibr : boolean := false; + + variable r_addr : slv22_1 := (others=>'0'); + variable r_ena_22bit : slbit := '0'; + variable r_ena_ubmap : slbit := '0'; + variable r_ibrbase : slv(c_ibrb_ibf_base) := (others=>'0'); + variable r_ibrbe : slv2 := (others=>'0'); + + + begin + + SB_CNTL <= (others=>'L'); + + wait for clock_offset - setup_time; + + RESET <= '1'; + wait for clock_period; + + RESET <= '0'; + wait for 9*clock_period; + + file_loop: while not endfile(ifile) loop + + -- this logic is a quick hack to implement the 'stapc' command + if idosta = '0' then + readline (ifile, iline); + + iwtstp := false; + iwtgo := false; + + if nblk>0 and -- outstanding [rw]mi lines ? + iline'length>=3 and -- and 3 leading blanks + iline(iline'left to iline'left+2)=" " then + nblk := nblk - 1; -- than fill [rw]mi command in again + iline(iline'left to iline'left+2) := xmicmd; + end if; + + readcomment(iline, ok); + next file_loop when ok; + + readword(iline, dname, ok); + + else + idosta := '0'; + dname := "sta "; + ok := true; + end if; + + if ok then + + case dname is + when "rsp " => dname := "rr6 "; -- rsp -> rr6 + when "rpc " => dname := "rr7 "; -- rpc -> rr7 + when "wsp " => dname := "wr6 "; -- wsp -> wr6 + when "wpc " => dname := "wr7 "; -- wpc -> wr7 + when others => null; + end case; + + rind := character'pos(dname(3)) - character'pos('0'); + + if (dname(1)='r' or dname(1)='w') and -- check for [rw]r[0-7] + dname(2)='r' and + (rind>=0 and rind<=7) then + dname(3) := '|'; -- replace with [rw]r| + end if; + + if dname(1) = '.' then + case dname is + when ".mode " => -- .mode + readword_ea(iline, dname); + assert dname="pdpcp " + report "assert .mode == pdpcp" severity failure; + + when ".reset" => -- .reset + write(oline, string'(".reset")); + writeline(output, oline); + RESET <= '1'; + wait for clock_period; + + RESET <= '0'; + wait for 9*clock_period; + + when ".wait " => -- .wait + read_ea(iline, idelta); + wait for idelta*clock_period; + + when ".tocmd" => -- .tocmd + read_ea(iline, idelta); + to_cmd := idelta; + + when ".tostp" => -- .tostp + read_ea(iline, idelta); + to_stp := idelta; + + when ".togo " => -- .togo + read_ea(iline, idelta); + to_go := idelta; + + when ".sdef " => -- .sdef (ignore it) + readempty(iline); + + when ".cerr " => -- .cerr + read_ea(iline, icerr); + when ".merr " => -- .merr + read_ea(iline, imerr); + + when ".anena" => -- .anena (ignore it) + readempty(iline); + when ".cpmon" => -- .cpmon (ignore it) + readempty(iline); + when ".rbmon" => -- .rbmon (ignore it) + readempty(iline); + + when ".scntl" => -- .scntl + read_ea(iline, ibit); + read_ea(iline, ien); + assert (ibit>=SB_CNTL'low and ibit<=SB_CNTL'high) + report "assert bit number in range of SB_CNTL" + severity failure; + if ien = '1' then + SB_CNTL(ibit) <= 'H'; + else + SB_CNTL(ibit) <= 'L'; + end if; + + when others => -- bad directive + write(oline, string'("?? unknown directive: ")); + write(oline, dname); + writeline(output, oline); + report "aborting" severity failure; + end case; + + testempty_ea(iline); + next file_loop; + + else + + ireq := true; + ifunc := c_cpfunc_noop; + irnum := "000"; + ichk := false; + idin := (others=>'0'); + imsk := (others=>'1'); + imemi := false; + idoibr := false; + + case dname is + when "brm " => -- brm + read_ea(iline, nblk); + xmicmd := "rmi"; + next file_loop; + when "bwm " => -- bwm + read_ea(iline, nblk); + xmicmd := "wmi"; + next file_loop; + + when "rr| " => -- rr[0-7] + ifunc := c_cpfunc_rreg; + irnum := conv_std_logic_vector(rind, 3); + readtagval2_ea(iline, "d", ichk, idin, imsk, 8); + + when "wr| " => -- wr[0-7] + ifunc := c_cpfunc_wreg; + irnum := conv_std_logic_vector(rind, 3); + readoct_ea(iline, idin); + + -- Note: there are no field definitions for wal, wah, wibrb because + -- there is no corresponding cp command. Therefore the + -- rbus field definitions are used here + when "wal " => -- wal + readoct_ea(iline, idin); + r_addr := (others=>'0'); -- write to al clears ah !! + r_ena_22bit := '0'; + r_ena_ubmap := '0'; + r_addr(c_al_rbf_addr) := idin(c_al_rbf_addr); + testempty_ea(iline); + next file_loop; + + when "wah " => -- wah + readoct_ea(iline, idin); + r_addr(21 downto 16) := idin(c_ah_rbf_addr); + r_ena_22bit := idin(c_ah_rbf_ena_22bit); + r_ena_ubmap := idin(c_ah_rbf_ena_ubmap); + testempty_ea(iline); + next file_loop; + + when "wibrb " => -- wibrb + readoct_ea(iline, idin); + r_ibrbase := idin(c_ibrb_ibf_base); + if idin(c_ibrb_ibf_be) /= "00" then + r_ibrbe := idin(c_ibrb_ibf_be); + else + r_ibrbe := "11"; + end if; + testempty_ea(iline); + next file_loop; + + when "rm " => -- rm + ifunc := c_cpfunc_rmem; + readtagval2_ea(iline, "d", ichk, idin, imsk, 8); + when "rmi " => -- rmi + ifunc := c_cpfunc_rmem; + imemi := true; + readtagval2_ea(iline, "d", ichk, idin, imsk, 8); + + when "wm " => -- wm + ifunc := c_cpfunc_wmem; + readoct_ea(iline, idin); + when "wmi " => -- wmi + ifunc := c_cpfunc_wmem; + imemi := true; + readoct_ea(iline, idin); + + when "ribr " => -- ribr + ifunc := c_cpfunc_rmem; + idoibr := true; + readoct_ea(iline, ioff); + readtagval2_ea(iline, "d", ichk, idin, imsk, 8); + when "wibr " => -- wibr + ifunc := c_cpfunc_wmem; + idoibr := true; + readoct_ea(iline, ioff); + readoct_ea(iline, idin); + + when "rps " => -- rps + ifunc := c_cpfunc_rpsw; + readtagval2_ea(iline, "d", ichk, idin, imsk, 8); + when "wps " => -- wps + ifunc := c_cpfunc_wpsw; + readoct_ea(iline, idin); + + -- Note: in old version 'sta addr' was an atomic operation, loading + -- the pc and starting the cpu. Now this is action is two step + -- first a wpc followed by a 'sta'. + when "stapc " => -- stapc + ifunc := c_cpfunc_wreg; + irnum := c_gpr_pc; + readoct_ea(iline, idin); + idosta := '1'; -- request 'sta' to be done next + + when "sta " => -- sta + ifunc := c_cpfunc_sta; + when "sto " => -- sto + ifunc := c_cpfunc_sto; + when "cont " => -- cont + ifunc := c_cpfunc_cont; + when "step " => -- step + ifunc := c_cpfunc_step; + iwtstp := true; + when "rst " => -- rst + ifunc := c_cpfunc_rst; + + when "wtgo " => -- wtgo + iwtgo := true; + ireq := false; -- no cp request ! + + when "wtlam " => -- wtlam (ignore it) + readempty(iline); + next file_loop; + + when others => -- bad directive + write(oline, string'("?? unknown directive: ")); + write(oline, dname); + writeline(output, oline); + report "aborting" severity failure; + end case; + + end if; + testempty_ea(iline); + + end if; + + if idoibr then + CP_ADDR_addr(15 downto 13) <= "111"; + CP_ADDR_addr(c_ibrb_ibf_base) <= r_ibrbase; + CP_ADDR_addr(5 downto 1) <= ioff(5 downto 1); + CP_ADDR_racc <= '1'; + CP_ADDR_be <= r_ibrbe; + CP_ADDR_ena_22bit <= '0'; + CP_ADDR_ena_ubmap <= '0'; + else + CP_ADDR_addr <= r_addr; + CP_ADDR_racc <= '0'; + CP_ADDR_be <= "11"; + CP_ADDR_ena_22bit <= r_ena_22bit; + CP_ADDR_ena_ubmap <= r_ena_ubmap; + end if; + + if ireq then + CP_CNTL_req <= '1'; + CP_CNTL_func <= ifunc; + CP_CNTL_rnum <= irnum; + end if; + + if ichk then + CP_DIN <= (others=>'0'); + R_CHKDAT <= idin; + R_CHKMSK <= imsk; + R_CHKREQ <= '1'; + else + CP_DIN <= idin; + R_CHKREQ <= '0'; + end if; + + R_WAITCMD <= '0'; + R_WAITSTEP <= '0'; + R_WAITGO <= '0'; + if iwtgo then + idelta := to_go; + R_WAITGO <= '1'; + elsif iwtstp then + idelta := to_stp; + R_WAITSTEP <= '1'; + else + idelta := to_cmd; + R_WAITCMD <= '1'; + end if; + + wait for clock_period; + CP_CNTL_req <= '0'; + + dcycle := 1; + while idelta>0 and R_WAITOK='0' loop + wait for clock_period; + dcycle := dcycle + 1; + idelta := idelta - 1; + end loop; + + if imemi then -- rmi or wmi seen ? then inc ar + r_addr := unsigned(r_addr) + 1; + end if; + + write(oline, dcycle, right, 4); + write(oline, string'(" ")); + if ireq then + case ifunc is + when c_cpfunc_rreg => write(oline, string'("rreg")); + when c_cpfunc_wreg => write(oline, string'("wreg")); + when c_cpfunc_rpsw => write(oline, string'("rpsw")); + when c_cpfunc_wpsw => write(oline, string'("wpsw")); + when c_cpfunc_rmem => + if idoibr then + write(oline, string'("ribr")); + else + write(oline, string'("rmem")); + end if; + when c_cpfunc_wmem => + if idoibr then + write(oline, string'("wibr")); + else + write(oline, string'("wmem")); + end if; + when c_cpfunc_sta => write(oline, string'("sta ")); + when c_cpfunc_sto => write(oline, string'("sto ")); + when c_cpfunc_cont => write(oline, string'("cont")); + when c_cpfunc_step => write(oline, string'("step")); + when c_cpfunc_rst => write(oline, string'("rst ")); + when others => + write(oline, string'("?")); + writeoct(oline, ifunc, right, 2); + write(oline, string'("?")); + end case; + writeoct(oline, irnum, right, 2); + writeoct(oline, idin, right, 8); + else + write(oline, string'("---- - ------")); + end if; + + write(oline, R_CP_STAT.cmdbusy, right, 3); + write(oline, R_CP_STAT.cmdack, right, 2); + write(oline, R_CP_STAT.cmderr, right, 2); + write(oline, R_CP_STAT.cmdmerr, right, 2); + writeoct(oline, R_CP_DOUT, right, 8); + write(oline, R_CP_STAT.cpugo, right, 3); + write(oline, R_CP_STAT.cpustep, right, 2); + write(oline, R_CP_STAT.cpuhalt, right, 2); + writeoct(oline, R_CP_STAT.cpurust, right, 3); + + if R_WAITOK = '1' then + if R_CP_STAT.cmderr='1' or icerr=1 then + if R_CP_STAT.cmderr='1' and icerr=0 then + write(oline, string'(" FAIL CMDERR")); + elsif R_CP_STAT.cmderr='1' and icerr=1 then + write(oline, string'(" CHECK CMDERR SEEN")); + elsif R_CP_STAT.cmderr='0' and icerr=1 then + write(oline, string'(" FAIL CMDERR EXPECTED,MISSED")); + end if; + elsif R_CP_STAT.cmdmerr='1' or imerr=1 then + if R_CP_STAT.cmdmerr='1' and imerr=0 then + write(oline, string'(" FAIL CMDMERR")); + elsif R_CP_STAT.cmdmerr='1' and imerr=1 then + write(oline, string'(" CHECK CMDMERR SEEN")); + elsif R_CP_STAT.cmdmerr='0' and imerr=1 then + write(oline, string'(" FAIL CMDMERR EXPECTED,MISSED")); + end if; + elsif R_CHKREQ='1' then + if unsigned((R_CP_DOUT xor R_CHKDAT) and (not R_CHKMSK))=0 then + write(oline, string'(" CHECK OK")); + else + write(oline, string'(" CHECK FAILED, d=")); + writeoct(oline, R_CHKDAT, right, 7); + if unsigned(R_CHKMSK)/=0 then + write(oline, string'(",")); + writeoct(oline, R_CHKMSK, right, 7); + end if; + end if; + end if; + + if iwtgo then + write(oline, string'(" WAIT GO OK ")); + elsif iwtstp then + write(oline, string'(" WAIT STEP OK")); + end if; + + else + write(oline, string'(" WAIT FAILED (will reset)")); + RESET <= '1'; + wait for clock_period; + + RESET <= '0'; + wait for 9*clock_period; + + end if; + writeline(output, oline); + + end loop; + + wait for 4*clock_period; + CLK_STOP <= '1'; + + writetimestamp(oline, SB_CLKCYCLE, ": DONE "); + writeline(output, oline); + + wait; -- suspend proc_stim forever + -- clock is stopped, sim will end + + end process proc_stim; + + proc_moni: process + begin + + loop + wait until CLK'event and CLK='1'; + wait for c2out_time; + + R_WAITOK <= '0'; + if R_WAITCMD = '1' then + if CP_STAT_cmdack = '1' then + R_WAITOK <= '1'; + end if; + elsif R_WAITGO = '1' then + if CP_STAT_cmdbusy='0' and CP_STAT_cpugo='0' then + R_WAITOK <= '1'; + end if; + elsif R_WAITSTEP = '1' then + if CP_STAT_cmdbusy='0' and CP_STAT_cpustep='0' then + R_WAITOK <= '1'; + end if; + end if; + + R_CP_STAT.cmdbusy <= CP_STAT_cmdbusy; + R_CP_STAT.cmdack <= CP_STAT_cmdack; + R_CP_STAT.cmderr <= CP_STAT_cmderr; + R_CP_STAT.cmdmerr <= CP_STAT_cmdmerr; + R_CP_STAT.cpugo <= CP_STAT_cpugo; + R_CP_STAT.cpustep <= CP_STAT_cpustep; + R_CP_STAT.cpuhalt <= CP_STAT_cpuhalt; + R_CP_STAT.cpurust <= CP_STAT_cpurust; + R_CP_DOUT <= CP_DOUT; + + end loop; + + end process proc_moni; + +end sim; diff --git a/rtl/w11a/tb/tb_pdp11_core_ssim.vbom b/rtl/w11a/tb/tb_pdp11_core_ssim.vbom new file mode 100644 index 00000000..84ccaef3 --- /dev/null +++ b/rtl/w11a/tb/tb_pdp11_core_ssim.vbom @@ -0,0 +1,4 @@ +# configure for _*sim case +tbd_pdp11_core = tbd_pdp11_core_ssim.vhd +tb_pdp11_core.vbom +@top:tb_pdp11_core diff --git a/rtl/w11a/tb/tb_pdp11_core_stim.dat b/rtl/w11a/tb/tb_pdp11_core_stim.dat new file mode 100644 index 00000000..7ee4dae8 --- /dev/null +++ b/rtl/w11a/tb/tb_pdp11_core_stim.dat @@ -0,0 +1,8569 @@ +# $Id: tb_pdp11_core_stim.dat 311 2010-06-30 17:52:37Z mueller $ +# +# Revision History: +# Date Rev Version Comment +# 2010-06-20 308 2.2.1 add wibrb, ribr, wibr based tests +# 2010-06-13 305 2.2 adopt to new rri address and function semantics +# 2009-11-22 252 2.1.14 change SSR0 expects, adapt to ECO-021. +# 2009-05-02 211 2.1.13 add nop after spl in pirq test, 11/70 spl now !! +# 2008-08-29 163 2.1.12 add wtlam to harvest attn after sto in test 13 +# 2008-04-27 139 2.1.11 adapt expected ssr1 after mtpi/d after ECO-009 fix +# 2008-03-15 125 2.1.10 exclude some tests from simh ([[off/on]] +# 2008-03-09 124 2.1.9 fixed addr-mode in code 34, shifted 47+50 +# 2008-03-02 121 2.1.8 add meory access error tests +# add Code 13, testing WAIT and bwm/brm while CPU runs +# 2008-02-24 119 2.1.7 add tests for lah,rps,wps; use rps,wps +# use 22bit mode for nxm test (now needed!) +# 2008-02-23 118 2.1.6 for nxm tests use mmu and page below i/o-page +# in code 35 use access to 160000 to test trap +# 2007-09-23 84 2.1.5 use .reset to make it re-executable +# 2007-09-16 83 2.1.4 clear CPUERR in beginning of test 20 {runs in FPGA} +# 2007-09-02 79 2.1.3 add .mode command (for pi_rri use) +# 2007-08-25 75 2.1.2 add .cpmon/.rpmon (for use with rri) +# 2007-08-16 74 2.1.1 adapt to changed LAM handling +# 2007-08-12 73 2.1 use wtgo (revised conv_stim) +# 2007-08-03 71 2.0 convert to command mode with conv_stim +# 2007-07-08 65 1.2 removed 1st 'delay' parameter; use .to_(cmd|stp|go) +# 2007-06-10 51 1.1 consolidate w11a test bench +# 2007-05-13 29 1.0 initial version (imported) +# +.mode pdpcp +.tocmd 50 +.tostp 100 +.togo 5000 +.cpmon 0 +.rbmon 0 +.scntl 13 0 +# +.reset +.wait 10 +.anena 1 +# +C "Code 0" Some elementary initial tests +C write registers +# +wr0 000001 -- set r0,..,r7 +wr1 000101 -- +wr2 000201 -- +wr3 000301 -- +wr4 000401 -- +wr5 000501 -- +wsp 000601 -- +wpc 000701 -- +# +C read registers +# +rr0 d=000001 -- ! r0 +rr1 d=000101 -- ! r1 +rr2 d=000201 -- ! r2 +rr3 d=000301 -- ! r3 +rr4 d=000401 -- ! r4 +rr5 d=000501 -- ! r5 +rsp d=000601 -- ! sp +rpc d=000701 -- ! pc +# +C write memory +# +wal 002000 -- write mem(2000,...,2006) +bwm 4 + 007700 -- + 007710 -- + 007720 -- + 007730 -- +# +C read memory +# +wal 002000 +brm 4 + d=007700 -- ! mem(2000) + d=007710 -- ! mem(2002) + d=007720 -- ! mem(2004) + d=007730 -- ! mem(2006) +# +C write/read PSW via various mechanisms +C via wps/rps +# +wps 000017 +rps d=000017 +wps 000000 +rps d=000000 +# +C via 16bit cp addressing (wal 177776) +# +wal 177776 +wm 000017 -- set all cc flags in psw +rm d=000017 -- ! psw +rps d=000017 +wm 000000 -- clear psw +rm d=000000 -- ! psw +rps d=000000 +# +C via 22bit cp addressing (wal 177776; wah 177) +# +wal 177776 +wah 000177 +wm 000017 -- set all cc flags in psw +rm d=000017 -- ! psw +rps d=000017 +wm 000000 -- clear psw +rm d=000000 -- ! psw +rps d=000000 +# +C via ibr (ibrb 177700) +# +wibrb 177700 +wibr 76 000017 -- set all cc flags in psw +ribr 76 d=000017 -- ! psw +rps d=000017 +wibr 76 000000 -- set all cc flags in psw +ribr 76 d=000000 -- ! psw +rps d=000000 +# +C write register set 1, sm,um stack +# +wps 004000 -- psw: cm=kernel, set=1 +wr0 010001 -- set r0,..,r5 [[r10]] +wr1 010101 -- [[r11]] +wr2 010201 -- [[r12]] +wr3 010301 -- [[r13]] +wr4 010401 -- [[r14]] +wr5 010501 -- [[r15]] +wps 044000 -- psw: cm=super(01),set=1 +wsp 010601 -- set ssp [[ssp]] +wps 144000 -- psw: cm=user(11),set=1 +wsp 110601 -- set usp [[usp]] +# +C read all registers set 0/1, km,sm,um stack +# +wps 000000 -- psw: cm=kernel(00),set=0 +rr0 d=000001 -- ! r0 +rr1 d=000101 -- ! r1 +rr2 d=000201 -- ! r2 +rr3 d=000301 -- ! r3 +rr4 d=000401 -- ! r4 +rr5 d=000501 -- ! r5 +rsp d=000601 -- ! ksp +rpc d=000701 -- ! pc +wps 040000 -- psw: cm=super(01),set=0 +rsp d=010601 -- ! ssp [[ssp]] +wps 140000 -- psw: cm=user(11),set=0 +rsp d=110601 -- ! usp [[usp]] +wps 144000 -- psw: cm=user(11),set=1 +rr0 d=010001 -- ! r0 [[r10]] +rr1 d=010101 -- ! r1 [[r11]] +rr2 d=010201 -- ! r2 [[r12]] +rr3 d=010301 -- ! r3 [[r13]] +rr4 d=010401 -- ! r4 [[r14]] +rr5 d=010501 -- ! r5 [[r15]] +# +C write IB space: MMU SAR supervisor mode (16 bit regs) +# +wal 172240 -- set first three SM I space address regs +bwm 3 + 012340 + 012342 + 012344 +# +C read IB space: MMU SAR supervisor mode (16 bit regs) +# +wal 172240 -- ! verify first three SM I space address regs +brm 3 + d=012340 + d=012342 + d=012344 +# +C read IB space via ibr: MMU SAR supervisor mode (16 bit regs) +# +wibrb 172200 +ribr 40 d=012340 +ribr 42 d=012342 +ribr 44 d=012344 +# +C byte write IB space via ibr: MMU SAR supervisor mode (16 bit regs) +# +wibrb 172201 -- write low byte +wibr 40 177000 +wibr 42 177002 +wibr 44 177004 +wal 172240 -- ! verify +brm 3 + d=012000 + d=012002 + d=012004 +# +wibrb 172202 -- write high byte +wibr 40 000377 +wibr 42 022377 +wibr 44 044377 +wal 172240 -- ! verify +brm 3 + d=000000 + d=022002 + d=044004 +# +wibrb 172203 -- write high and low byte (both be set) +wibr 40 012340 +wibr 42 012342 +wibr 44 012344 +wal 172240 -- ! verify +brm 3 + d=012340 + d=012342 + d=012344 +# +#[[off]] - this tests cp not the cpu - meaningless in simh +# +C test access error handling to memory (use 17740000) +C with wm/rm +# +wal 140000 +wah 000177 +.merr 1 +.sdef s=10000001 +wm 000000 +rm d=- +.merr 0 +.sdef s=00000000,01110000 +# +C with bwm/brm +# +wal 140000 +wah 000177 +.merr 1 +.sdef s=10000001 +bwm 2 + 000000 + 000000 +.merr 0 +.sdef s=00000000,01110000 +# +wal 140000 +wah 000177 +.merr 1 +.sdef s=10000001 +brm 2 + d=- + d=- +.merr 0 +.sdef s=00000000,01110000 +# +C test access error handling to IB space (use 00160000) +C with wm/rm +wal 160000 +.merr 1 +.sdef s=10000001 +wm 000000 +rm d=- +.merr 0 +.sdef s=00000000,01110000 +C with bwm/brm +# +wal 160000 +.merr 1 +.sdef s=10000001 +bwm 2 + 000000 + 000000 +.merr 0 +.sdef s=00000000,01110000 +# +wal 160000 +.merr 1 +.sdef s=10000001 +brm 2 + d=- + d=- +.merr 0 +.sdef s=00000000,01110000 +#[[on]] +#----------------------------------------------------------------------------- +C Setup trap catchers +# +wal 000004 -- vectors: 4...34 (trap catcher) +bwm 14 + 000006 -- PC:06 ; vector 4 + 000000 -- PS:0 + 000012 -- PC:12 ; vector 10 + 000000 -- PS:0 + 000016 -- PC:16 ; vector 14 (T bit; BPT) + 000000 -- PS:0 + 000022 -- PC:22 ; vector 20 (IOT) + 000000 -- PS:0 + 000026 -- PC:26 ; vector 24 (Power fail, not used) + 000000 -- PS:0 + 000032 -- PC:32 ; vector 30 (EMT) + 000000 -- PS:0 + 000036 -- PC:36 ; vector 34 (TRAP) + 000000 -- PS:0 +wal 000240 -- vectors: 240,244,250 (trap catcher) +bwm 6 + 000242 -- PC:242 ; vector 240 (PIRQ) + 000000 -- PS:0 + 000246 -- PC:246 ; vector 244 (FPU) + 000000 -- PS:0 + 000252 -- PC:252 ; vector 250 (MMU) + 000000 -- PS:0 +# +C Setup MMU +# +wal 172300 -- kernel I space DR +bwm 8 + 077406 -- slf=127; ed=0(up); acf=6(w/r) + 077406 -- slf=127; ed=0(up); acf=6(w/r) + 077406 -- slf=127; ed=0(up); acf=6(w/r) + 077406 -- slf=127; ed=0(up); acf=6(w/r) + 077406 -- slf=127; ed=0(up); acf=6(w/r) + 077406 -- slf=127; ed=0(up); acf=6(w/r) + 077406 -- slf=127; ed=0(up); acf=6(w/r) + 077406 -- slf=127; ed=0(up); acf=6(w/r) +wal 172340 -- kernel I space AR +bwm 8 + 000000 -- 0 + 000200 -- 200 020000 base + 000400 -- 400 040000 base + 000600 -- 600 060000 base + 001000 -- 1000 100000 base + 001200 -- 1200 120000 base + 001400 -- 1400 140000 base + 177600 -- 176000 (map to I/O page) +#----------------------------------------------------------------------------- +C Setup code 1 [base 2100] (very basics: cont,start; 'simple' instructions) +# +wal 002100 -- code test 1: (sec+clc+halt) +bwm 3 + 000261 -- sec + 000250 -- cln + 000000 -- halt +#----- +wal 002120 -- code test 2: (4 *inc R2, starting from -2) +bwm 5 + 005202 -- inc r2 + 005202 -- inc r2 + 005202 -- inc r2 + 005202 -- inc r2 +#2130 + 000000 -- halt +#----- +wal 002140 -- code test 3: (dec r3; bne -2; halt) +bwm 3 + 005303 -- dec r3 + 001376 -- bne -2 + 000000 -- halt +#----- +wal 002160 -- code test 4: (inc r1; sob r0,-2; halt) +bwm 3 + 005201 -- inc r1 + 077002 -- sob r0,-2 + 000000 -- halt +# +C Exec code 1 (very basics: cont,start; 'simple' instructions) +C Exec test 1.1 (sec+clc+halt) +# +wpc 002100 -- pc=2100 +wps 000010 -- psw: set N flag +cont -- cont @ 2100 +wtgo +rpc d=002106 -- ! pc +rps d=000001 -- ! N cleared, C set now +# +C Exec test 1.2 (4 *inc R2, starting from -2) +# +wr2 177776 -- r2=-2 +stapc 002120 -- start @ 2120 +wtgo +rr2 d=000002 -- ! r2=2 +rpc d=002132 -- ! pc +# +C Exec test 1.3 (dec r3; bne -2; halt) +# +wr3 000002 -- r3=2 +stapc 002140 -- start @ 2140 +wtgo +rr3 d=000000 -- ! r3=0 +rpc d=002146 -- ! pc +# +C Exec test 1.4 (inc r1; sob r0,-2; halt) +# +wr0 000002 -- r0=2 +wr1 000000 -- r1=0 +stapc 002160 -- start @ 2160 +wtgo +rr0 d=000000 -- ! r0=0 +rr1 d=000002 -- ! r1=2 +rpc d=002166 -- ! pc +#----------------------------------------------------------------------------- +C Setup code 2 [base 2200] (bpt against trap catcher @14) +# +wal 002200 -- code: +bwm 4 + 000257 -- cl(nzvc) + 000261 -- sec + 000003 -- bpt + 000000 -- halt +# +C Exec code 2 (bpt against trap catcher @14) +# +wsp 001400 -- sp=1400 +stapc 002200 -- start @ 2200 +wtgo +rsp d=001374 -- ! sp +rpc d=000020 -- ! pc +wal 001374 +brm 2 + d=002206 -- ! (sp) old pc + d=000341 -- ! 2(sp) old ps +#----------------------------------------------------------------------------- +C Setup code 3 [base 2300] (bpt against trap handler doing inc r0; rtt) +# +wal 002300 -- code: +bwm 4 + 000257 -- cl(nzvc) + 000003 -- bpt + 005201 -- inc r1 + 000000 -- halt +wal 000014 -- vector: 14 +bwm 2 + 002320 -- PC:2320 + 000002 -- PS:2 +wal 002320 -- code (trap 14): +bwm 3 + 005200 -- inc r0 + 000006 -- rtt + 000000 -- halt +# +C Exec code 3 (bpt against trap handler doing inc r0; rtt) +# +wr0 000000 -- r0=0 +wr1 000000 -- r1=0 +wsp 001400 -- sp=1400 +stapc 002300 -- start @ 2300 +wtgo +rr0 d=000001 -- ! r0 +rr1 d=000001 -- ! r1 +rsp d=001400 -- ! sp +rpc d=002310 -- ! pc +#----------------------------------------------------------------------------- +C Setup code 4 [base 2400] (enable T-trap on handler of code 3; run 2* inc r1) +# +wal 002400 +bwm 4 + 000006 -- rtt + 005201 -- inc r1 + 005201 -- inc r1 + 000000 -- halt +# +C Exec code 4 (enable T-trap on handler of code 3; run 2* inc r1) +# +wr0 000000 -- r0=0 +wr1 000000 -- r1=0 +wsp 001374 -- sp=1374 +wal 001374 -- setup stack with rtt return frame setting T flag +bwm 2 + 002402 -- start address + 000020 -- set T flag in PSW +stapc 002400 -- start @ 2400 -> rtt -> 2402 from stack +wtgo +rr0 d=000002 -- ! r0 +rr1 d=000002 -- ! r1 +rsp d=001400 -- ! sp +rpc d=002410 -- ! pc +# +rst -- console reset (to clear T flag) +wal 000014 -- vector: 14 -> trap catcher again +bwm 2 + 000016 -- PC:16 + 000000 -- PS:0 +#----------------------------------------------------------------------------- +C Setup code 5 [base 2500] (srcr modes: mov xxx,rn: (r0),(r0)+,-(r0),@(r0)) +# +wal 002500 -- code: +bwm 6 + 011001 -- mov (r0),r1 + 012002 -- mov (r0)+,r2 + 012003 -- mov (r0)+,r3 + 014004 -- mov -(r0),r4 + 013005 -- mov @(r0)+,r5 + 000000 -- halt +# +wal 002540 -- data: +bwm 2 + 000070 -- + 002550 -- +wal 002550 -- data: +bwm 2 + 000072 -- + 000074 -- +# +C Exec code 5 (srcr modes: mov xxx,rn: (r0),(r0)+,-(r0),@(r0)) +# +wr0 002540 -- r0=2540 +wr1 000000 -- r1=0 +wr2 000000 -- r2=0 +wr3 000000 -- r3=0 +wr4 000000 -- r4=0 +wr5 000000 -- r5=0 +wsp 001400 -- sp=1400 +stapc 002500 -- start @ 2500 +wtgo +rr0 d=002544 -- ! r0 +rr1 d=000070 -- ! r1 +rr2 d=000070 -- ! r2 +rr3 d=002550 -- ! r3 +rr4 d=002550 -- ! r4 +rr5 d=000072 -- ! r5 +rsp d=001400 -- ! sp +rpc d=002514 -- ! pc +#----------------------------------------------------------------------------- +C Setup code 6 [base 2600] (srcr modes: mov xxx,rn: x(r0),@x(r0), pc modes) +# +wal 002600 -- code: +bwm 11 + 016001 -- mov 2(r0),r1 + 000002 + 017002 -- mov @2(r0),r2 + 000002 + 012703 -- mov (pc)+,r3 ; #377 + 000377 + 013704 -- mov @(pc)+,r4 ; @#2552 (in previous code !) + 002552 +#2620 + 112705 -- movb (pc)+,r5 ; #377 + 000377 + 000000 -- halt +# +C Exec code 6 (srcr modes: mov xxx,rn: x(r0),@x(r0), pc modes) +# +wr0 002540 -- r0=2540 (in previous code !) +wr1 000000 -- r1=0 +wr2 000000 -- r2=0 +wr3 000000 -- r3=0 +wr4 000000 -- r4=0 +wr5 000000 -- r5=0 +wsp 001400 -- sp=1400 +stapc 002600 -- start @ 2600 +wtgo +rr0 d=002540 -- ! r0 +rr1 d=002550 -- ! r1 +rr2 d=000072 -- ! r2 +rr3 d=000377 -- ! r3 +rr4 d=000074 -- ! r4 +rr5 d=177777 -- ! r5 +rsp d=001400 -- ! sp +rpc d=002626 -- ! pc +#----------------------------------------------------------------------------- +C Setup code 7 [base 2700] (dstw modes: mov rn,xxx: all non-r modes) +# +wal 002700 -- code: +bwm 18 + 012710 -- mov #110,(r0) (to 2750) + 000110 + 012721 -- mov #120,(r1)+ (to 2752) + 000120 + 012732 -- mov #130,@(r2)+ (to 2754) + 000130 + 012743 -- mov #140,-(r3) (to 2756) + 000140 +#2720 + 012754 -- mov #150,@-(r4) (to 2760) + 000150 + 012760 -- mov #160,12(r0) (to 2762) + 000160 + 000012 + 012770 -- mov #170,@24(r0) (to 2764) + 000170 + 000024 +#2740 + 010546 -- mov r5,-(r6) + 000000 -- halt +# +wal 002770 -- data: +bwm 3 + 002754 -- mem(2770)=2754 + 002760 -- mem(2772)=2760 + 002764 -- mem(2774)=2764 +# +C Exec code 7 (dstw modes: mov rn,xxx: all non-r modes) +# +wr0 002750 -- r0=2750 +wr1 002752 -- r1=2752 +wr2 002770 -- r2=2770 +wr3 002760 -- r3=2760 +wr4 002774 -- r4=2774 +wr5 000666 -- r5=666 +wsp 001400 -- sp=1400 +stapc 002700 -- start @ 2700 +wtgo +rr0 d=002750 -- ! r0 +rr1 d=002754 -- ! r1 +rr2 d=002772 -- ! r2 +rr3 d=002756 -- ! r3 +rr4 d=002772 -- ! r4 +rr5 d=000666 -- ! r5 +rsp d=001376 -- ! sp +rpc d=002744 -- ! pc +wal 002750 +brm 7 + d=000110 -- ! mem(2750)=110 + d=000120 -- ! mem(2752)=120 + d=000130 -- ! mem(2754)=130 + d=000140 -- ! mem(2756)=140 + d=000150 -- ! mem(2760)=150 + d=000160 -- ! mem(2762)=160 + d=000170 -- ! mem(2764)=170 +wal 001376 +rmi d=000666 -- ! mem(sp)=666 +#----------------------------------------------------------------------------- +C Setup code 10 [base 3000] (dstm modes: inc xxx: all non-r modes) +# +wal 003000 -- code: +bwm 10 + 005210 -- inc (r0) (to 3050) + 005221 -- inc (r1)+ (to 3052) + 005232 -- inc @(r2)+ (to 3054) + 005243 -- inc -(r3) (to 3056) + 005254 -- inc @-(r4) (to 3060) + 005260 -- inc 12(r0) (to 3062) + 000012 + 005270 -- inc @24(r0) (to 3064) +#3020 + 000024 + 000000 -- halt +# +wal 003050 -- data: +bwm 7 + 000110 -- mem(3050)=110 + 000120 -- mem(3052)=120 + 000130 -- mem(3054)=130 + 000140 -- mem(3056)=140 + 000150 -- mem(3060)=150 + 000160 -- mem(3062)=160 + 000170 -- mem(3064)=170 +wal 003070 -- data: +bwm 3 + 003054 -- mem(3070)=3054 + 003060 -- mem(3072)=3060 + 003064 -- mem(3074)=3064 +# +C Exec code 10 (dstm modes: inc xxx: all non-r modes) +# +wr0 003050 -- r0=3050 +wr1 003052 -- r1=3052 +wr2 003070 -- r2=3070 +wr3 003060 -- r3=3060 +wr4 003074 -- r4=3074 +wsp 001400 -- sp=1400 +stapc 003000 -- start @ 3000 +wtgo +rr0 d=003050 -- ! r0 +rr1 d=003054 -- ! r1 +rr2 d=003072 -- ! r2 +rr3 d=003056 -- ! r3 +rr4 d=003072 -- ! r4 +rpc d=003024 -- ! pc +wal 003050 +brm 7 + d=000111 -- ! mem(3050)=111 + d=000121 -- ! mem(3052)=121 + d=000131 -- ! mem(3054)=131 + d=000141 -- ! mem(3056)=141 + d=000151 -- ! mem(3060)=151 + d=000161 -- ! mem(3062)=161 + d=000171 -- ! mem(3064)=171 +#----------------------------------------------------------------------------- +C Setup code 11 [base 3100; use 31-32] (dsta modes: jsr pc,xxx: all non-r modes) +# +wal 003100 -- code: +bwm 10 + 004710 -- jsr pc,(r0) (to 3210) r0->3210 + 004721 -- jsr pc,(r1)+ (to 3220) r1->3220 + 004732 -- jsr pc,@(r2)+ (to 3230) r2->3140->3230 + 004743 -- jsr pc,-(r3) (to 3240) r3->3242 + 004754 -- jsr pc,@-(r4) (to 3250) r4->3142->3250 + 004760 -- jsr pc,50(r0) (to 3260) r0->3210+50->3260 + 000050 + 004770 -- jsr pc,@-44(r0) (to 3270) r0->3210-44->3144->3270 +#3120 + 177734 + 000000 -- halt +# +wal 003140 -- data: +bwm 3 + 003230 -- mem(3140)=3230 + 003250 -- mem(3142)=3250 + 003270 -- mem(3144)=3270 +# +wal 003210 -- code: +bwm 28 + 012725 -- mov #110,(r5)+ + 000110 + 000207 -- rts pc + 000000 -- halt +#3220 + 012725 -- mov #120,(r5)+ + 000120 + 000207 -- rts pc + 000000 -- halt + 012725 -- mov #130,(r5)+ + 000130 + 000207 -- rts pc + 000000 -- halt +#3240 + 012725 -- mov #140,(r5)+ + 000140 + 000207 -- rts pc + 000000 -- halt + 012725 -- mov #150,(r5)+ + 000150 + 000207 -- rts pc + 000000 -- halt +#3260 + 012725 -- mov #160,(r5)+ + 000160 + 000207 -- rts pc + 000000 -- halt + 012725 -- mov #170,(r5)+ + 000170 + 000207 -- rts pc + 000000 -- halt +# +C Exec code 11 (dsta modes: jsr pc,xxx: all non-r modes) +# +wr0 003210 -- r0=3210 +wr1 003220 -- r1=3220 +wr2 003140 -- r2=3140 +wr3 003242 -- r3=3242 +wr4 003144 -- r4=3144 +wr5 003160 -- r5=3160 +wsp 001400 -- sp=1400 +stapc 003100 -- start @ 3100 +wtgo +rr0 d=003210 -- ! r0=3210 +rr1 d=003222 -- ! r1=3222 +rr2 d=003142 -- ! r2=3142 +rr3 d=003240 -- ! r3=3240 +rr4 d=003142 -- ! r4=3142 +rr5 d=003176 -- ! r5=3176 +rsp d=001400 -- ! sp +rpc d=003124 -- ! pc +wal 003160 +brm 7 + d=000110 -- ! mem(3160)=110 + d=000120 -- ! mem(3162)=120 + d=000130 -- ! mem(3164)=130 + d=000140 -- ! mem(3166)=140 + d=000150 -- ! mem(3170)=150 + d=000160 -- ! mem(3172)=160 + d=000170 -- ! mem(3174)=170 +#----------------------------------------------------------------------------- +C Setup code 12 [base 3300; use 33-34] (PSW access via sex,clx,spl,mov, and clr) +# +wal 003300 -- code: +bwm 23 + 011025 -- mov (r0),(r5)+ + 012710 -- mov #030000,(r0) ; write full PSW: pmode=um + 030000 + 011025 -- mov (r0),(r5)+ + 000263 -- se(v,c) + 011025 -- mov (r0),(r5)+ + 000237 -- spl 7 + 011025 -- mov (r0),(r5)+ +#3320 + 000274 -- se(n,z) + 011025 -- mov (r0),(r5)+ + 000233 -- spl 3 + 011025 -- mov (r0),(r5)+ + 000241 -- clc + 011025 -- mov (r0),(r5)+ + 112710 -- movb #40,(r0) ; write PSW_low (set pri=1) + 000040 +#3340 + 011025 -- mov (r0),(r5)+ + 112711 -- movb #20,(r1) ; write PSW_high: pmode=sm + 000020 + 011025 -- mov (r0),(r5)+ + 005010 -- clr (r0) + 011025 -- mov (r0),(r5)+ + 000000 -- halt +# +C Exec code 12 (PSW access via sex,clx,spl,mov, and clr) +# +wps 000017 -- psw: set all condition codes (to check psw clear @ start) +# +wr0 177776 -- r0=177776 +wr1 177777 -- r1=177777 +wr5 003400 -- r5=3400 +wsp 001400 -- sp=1400 +stapc 003300 -- start @ 3300 +wtgo +rr5 d=003424 -- ! r5=3424 +rpc d=003356 -- ! pc +wal 003400 +brm 10 + d=000340 -- ! mem(3400) after start + d=030000 -- ! mem(3402) after mov #030000,(r0) + d=030003 -- ! mem(3404) after se(v,c) (VC) + d=030341 -- ! mem(3406) after spl 7 (pri=7,C) + d=030355 -- ! mem(3410) after se(n,z) (pri=7,NZC) + d=030141 -- ! mem(3412) after spl 3 (pri=3,C) + d=030140 -- ! mem(3414) after clc (pri=3) + d=030040 -- ! mem(3416) after movb #40,(r0) (pri=1) + d=010040 -- ! mem(3420) after movb #20,(r1) pmode=sm + d=000000 -- ! mem(3422) after clr (r0) +#----------------------------------------------------------------------------- +C Setup code 13 [base 3500] (test WAIT and rdma (bwm/rwm while CPU running) +# +#[[off]] - can't emulate 'sto' command in simh, rdma meaningless in simh +# +wal 003500 -- code 13.1 (to be stepped) +bwm 4 + 000001 -- wait + 000001 -- wait + 000001 -- wait + 000000 -- halt +# +wal 003520 -- code 13.2 (busy loop) +bwm 3 + 005700 -- tst r0 + 001776 -- beq .-1 + 000000 -- halt +# +wal 003540 -- code 13.3 (just a WAIT) +bwm 2 + 000001 -- wait + 000000 -- halt +# +C Exec code 13.1a (run WAIT) +# +stapc 003500 -- start @ 3500 +.wait 20 -- let it go +rpc d=003502 -- ! should hang here ... +.wait 20 -- let it go +rpc d=003502 -- ! should hang here ... +sto +wtlam d=000001 -- harvest attn due to go 1->0 transition of sto command +rpc d=003502 -- ! should stay there ... +# +C Exec code 13.1b (step WAIT) +wpc 003500 -- pc=3500 +step -- step over 1st WAIT +rpc d=003502 -- ! +step -- step over 2nd WAIT +rpc d=003504 -- ! +step -- step over 3rd WAIT +rpc d=003506 -- ! +step -- step over HALT +rpc d=003510 -- ! +# +C Exec code 13.2 (test bwm/brm while CPU busy looping) +wr0 000000 -- r0=0 +stapc 003520 -- start @ 3520 +# +wal 003560 -- write data while CPU active +bwm 8 + 003560 + 003562 + 003564 + 003566 + 003570 + 003572 + 003574 + 003576 +wal 003560 -- read data while CPU active +brm 8 + d=003560 + d=003562 + d=003564 + d=003566 + d=003570 + d=003572 + d=003574 + d=003576 +# +wr0 000001 -- r0=1 --> should end loop +wtgo +rpc d=003526 -- ! +# +C Exec code 13.3 (test bwm/brm while CPU on WAIT) +# +stapc 003540 -- start @ 3540 +# +wal 003560 -- write data while CPU active +bwm 8 + 073560 + 073562 + 073564 + 073566 + 073570 + 073572 + 073574 + 073576 +wal 003560 -- read data while CPU active +brm 8 + d=073560 + d=073562 + d=073564 + d=073566 + d=073570 + d=073572 + d=073574 + d=073576 +# +sto +wtlam d=000001 -- harvest attn due to go 1->0 transition of sto command +rpc d=003542 -- ! +#[[on]] +#----------------------------------------------------------------------------- +# Setup code 14 --- code 14 doesn't exist anymore... +#----------------------------------------------------------------------------- +C Setup code 15 [base 3600; use 36-37] (test 4 traps) +# +wal 003600 -- code: +bwm 5 + 000003 -- bpt (to 14) + 000004 -- iot (to 20) + 104077 -- emt 77 (to 30) + 104477 -- trap 77 (to 34) + 000000 -- halt +# +wal 003620 -- code: trap handlers +bwm 11 + 010025 -- mov r0,(r5)+ (@ 3620) + 000405 -- br .+10 + 010125 -- mov r1,(r5)+ (@ 3624) + 000403 -- br .+6 + 010225 -- mov r2,(r5)+ (@ 3630) + 000401 -- br .+2 + 010325 -- mov r3,(r5)+ (@ 3634) +#3640 + 011604 -- mov (sp),r4 ; r4 points after instruction + 016425 -- mov -2(r4),(r5)+ ; load instruction + 177776 + 000002 -- rti +# +wal 000014 -- vector: 14+20 +bwm 4 + 003620 -- PC:3620 + 000000 -- PS:0 + 003624 -- PC:3624 + 000000 -- PS:0 +wal 000030 -- vector: 30+34 +bwm 4 + 003630 -- PC:3630 + 000000 -- PS:0 + 003634 -- PC:3634 + 000000 -- PS:0 +# +C Exec code 15 (test 4 traps) +# +wr0 000011 -- r0=11 +wr1 000022 -- r1=22 +wr2 000033 -- r2=33 +wr3 000044 -- r3=44 +wr5 003700 -- r5=3700 +wsp 001400 -- sp=140 +stapc 003600 -- start @ 3600 +wtgo +rr5 d=003720 -- ! r5=3720 +rsp d=001400 -- ! sp +rpc d=003612 -- ! pc +wal 003700 +brm 8 + d=000011 -- ! mem(3700)=11 + d=000003 -- ! mem(3702)=3 + d=000022 -- ! mem(3704)=22 + d=000004 -- ! mem(3706)=4 + d=000033 -- ! mem(3710)=33 + d=104077 -- ! mem(3712)=104077 + d=000044 -- ! mem(3714)=44 + d=104477 -- ! mem(3716)=104477 +wal 000014 -- vector: 14+20 -> trap catcher again +bwm 4 + 000016 -- PC:16 + 000000 -- PS:0 + 000022 -- PC:22 + 000000 -- PS:0 +wal 000030 -- vector: 30+34 -> trap catcher again +bwm 4 + 000032 -- PC:32 + 000000 -- PS:0 + 000036 -- PC:36 + 000000 -- PS:0 +#----------------------------------------------------------------------------- +C Setup code 16 [base 4000] (enable MMU, check ssr1, ssr2 response) +# +wal 172516 -- SSR3 +wmi 000002 -- I/D enabled for sm only (to check CRESET) +wal 177572 -- SSR0 +wmi 000001 -- set enable bit +# +wal 004000 -- code (to be single stepped...) +bwm 7 + 011105 -- mov (r1),r5 + 012105 -- mov (r1)+,r5 + 014105 -- mov -(r1),r5 + 012122 -- mov (r1)+,(r2)+ + 112105 -- movb (r1)+,r5 + 112721 -- movb #200,(r1)+ + 000200 +# +wal 004030 -- code test 1: +wmi 000000 -- halt +# +wal 004040 -- data: +bwm 2 + 000001 + 000300 +# +C Exec code 16 (enable MMU, check ssr1, ssr2 response) +# +wr1 004040 -- r1=4040 +wr2 004060 -- r2=4060 +wsp 001400 -- sp=1400 +wpc 004000 -- pc=4000 +step -- step (mov (r1),r5) +wal 177572 -- check SSR0/1/2 +brm 3 + d=000001 -- ! SSR0: (ena=1) + d=000000 -- ! SSR1: + d=004000 -- ! SSR2: 4000 (eff. PC) +rr1 d=004040 -- ! r1 +rr5 d=000001 -- ! r5 +step -- step (mov (r1)+,r5) +wal 177572 -- check SSR0/1/2 +brm 3 + d=000001 -- ! SSR0: (ena=1) + d=000021 -- ! SSR1: rb none; ra=1,+2 + d=004002 -- ! SSR2: 4002 (eff. PC) +rr1 d=004042 -- ! r1 +rr5 d=000001 -- ! r5 +step -- step (mov -(r1),r5) +wal 177572 -- check SSR0/1/2 +brm 3 + d=000001 -- ! SSR0: (ena=1) + d=000361 -- ! SSR1: rb none; ra=1,-2 + d=004004 -- ! SSR2: 4004 (eff. PC) +rr1 d=004040 -- ! r1 +rr5 d=000001 -- ! r5 +step -- step (mov (r1)+,(r2)+) +wal 177572 -- check SSR0/1/2 +brm 3 + d=000001 -- ! SSR0: (ena=1) + d=011021 -- ! SSR1: rb=2,2; ra=1,2 + d=004006 -- ! SSR2: 4006 (eff. PC) +rr1 d=004042 -- ! r1 +rr2 d=004062 -- ! r2 +step -- step (movb (r1)+,r5) +wal 177572 -- check SSR0/1/2 +brm 3 + d=000001 -- ! SSR0: (ena=1) + d=000011 -- ! SSR1: rb=none; ra=1,1 + d=004010 -- ! SSR2: 4010 (eff. PC) +rr1 d=004043 -- ! r1 +rr5 d=177700 -- ! r5 +step -- step (movb #200,(r1)+) +wal 177572 -- check SSR0/1/2 +brm 3 + d=000001 -- ! SSR0: (ena=1) + d=004427 -- ! SSR1: rb=1,1; ra=7,2 + d=004012 -- ! SSR2: 4012 (eff. PC) +rr1 d=004044 -- ! r1 +# +C Exec test 16.1 (check CRESET of PSW, SSR0, SSR3 after start) +# +wps 000000 -- psw: set pri=0 +stapc 004030 -- start @ 4030 (just HALT, testing console reset) +wtgo +rpc d=004032 -- ! pc=4032 +rps d=000340 -- ! psw: reset by CRESET +wal 172516 -- SSR3 +rmi d=000000 -- ! cleared by CRESET +wal 177572 -- SSR0 +rmi d=000000 -- ! cleared by CRESET +#----------------------------------------------------------------------------- +C Setup code 17 [base 4100; use 41-46] (basic instruction and cc test) +# +wal 004100 -- code: (length 70) +bwm 32 + 010124 -- mov r1,(r4)+ (#4711, #123456) + 020124 -- cmp r1,(r4)+ (#4711, #123456) + 020224 -- cmp r2,(r4)+ (#123456,#4711) + 020124 -- cmp r1,(r4)+ (#4711, #4711) + 005024 -- clr (r4)+ (#123456) + 030124 -- bit r1,(r4)+ (#4711, #11) + 030124 -- bit r1,(r4)+ (#4711, #66) + 040124 -- bic r1,(r4)+ (#4711, #123456) +#4120 + 050124 -- bis r1,(r4)+ (#4711, #123456) + 060124 -- add r1,(r4)+ (#4711, #123456) + 160124 -- sub r1,(r4)+ (#4711, #123456) + 005124 -- com (r4)+ (#123456) + 005224 -- inc (r4)+ (#123456) + 005324 -- dec (r4)+ (#123456) + 005424 -- neg (r4)+ (#123456) + 005724 -- tst (r4)+ (#123456) +#4140 + 006024 -- ror (r4)+ (#100201) Cin=0; Cout=1 + 006024 -- ror (r4)+ (#002201) Cin=1; Cout=1 + 006124 -- rol (r4)+ (#100200) Cin=1; Cout=1 + 006224 -- asr (r4)+ (#200) + 006224 -- asr (r4)+ (#100200) + 006324 -- asl (r4)+ (#200) + 006324 -- asl (r4)+ (#100200) + 060124 -- add r1,(r4)+ (#4711, #077777) +#4160 + 005524 -- adc (r4)+ (#200) + 160124 -- sub r1,(r4)+ (#4711, #4700) + 005624 -- sbc (r4)+ (#200) + 000324 -- swap (r4)+ (#111000) + 006724 -- sxt (r4)+ (#111111 with N=1) + 074124 -- xor r1,(r4)+ (#070707,#4711) + 006724 -- sxt (r4)+ (#111111 with N=0) + 000000 -- halt +# +wal 000014 -- vector: 14 +bwm 2 + 004270 -- PC:4270 + 000000 -- PS:0 +#----- +wal 004270 -- code: (trap 14): +bwm 3 + 016625 -- mov 2(sp),(r5)+ + 000002 + 000006 -- rtt +#----- +wal 004300 -- data 1: (length 66) +bwm 31 + 123456 -- + 123456 -- + 004711 -- + 004711 -- + 123456 -- + 000011 -- + 000066 -- + 123456 -- +#4320 + 123456 -- + 123456 -- + 123456 -- + 123456 -- + 123456 -- + 123456 -- + 123456 -- + 123456 -- +#4340 + 100201 -- + 002201 -- + 100200 -- + 000200 -- + 100200 -- + 000200 -- + 100200 -- + 177000 -- +#4360 + 000200 -- + 004701 -- + 000200 -- + 111000 -- + 111111 -- + 070707 -- + 111111 -- +# +C Exec code 17 (basic instruction and cc test) +# +wr1 004711 -- r1=4711 +wr2 123456 -- r2=123456 +wr4 004300 -- r4=4300 +wr5 004500 -- r5=4500 +wsp 001374 -- sp=1374 +wal 001374 -- setup stack with rtt return frame setting T flag +bwm 2 + 004100 -- start address (code 17 @ 4100) + 000020 -- set T flag in PSW +stapc 004274 -- start @ 4274 -> rtt -> 4100 from stack +wtgo +rr1 d=004711 -- ! r1=4711 +rr2 d=123456 -- ! r2=123456 +rr4 d=004376 -- ! r4=4376 +rr5 d=004576 -- ! r5=4576 +rsp d=001400 -- ! sp=1400 +rpc d=004200 -- ! pc=4200 +wal 004300 +brm 31 + d=004711 -- ! mem(4300)=004711; mov r1,(r4)+ (#4711, #123456) + d=123456 -- ! mem(4302)=123456; cmp r1,(r4)+ (#4711, #123456) + d=004711 -- ! mem(4304)=004711; cmp r1,(r4)+ (#123456,#4711) + d=004711 -- ! mem(4306)=004711; cmp r1,(r4)+ (#4711, #4711) + d=000000 -- ! mem(4310)=000000; clr (r4)+ (#123456) + d=000011 -- ! mem(4312)=000011; bit r1,(r4)+ (#4711, #11) + d=000066 -- ! mem(4314)=000066; bit r1,(r4)+ (#4711, #66) + d=123046 -- ! mem(4316)=123046; bic r1,(r4)+ (#4711, #123456) + d=127757 -- ! mem(4320)=127757; bis r1,(r4)+ (#4711, #123456) + d=130367 -- ! mem(4322)=130367; add r1,(r4)+ (#4711, #123456) + d=116545 -- ! mem(4324)=116545; sub r1,(r4)+ (#4711, #123456) + d=054321 -- ! mem(4326)=054321; com (r4)+ (#123456) + d=123457 -- ! mem(4330)=123457; inc (r4)+ (#123456) + d=123455 -- ! mem(4332)=123455; dec (r4)+ (#123456) + d=054322 -- ! mem(4334)=054322; neg (r4)+ (#123456) + d=123456 -- ! mem(4336)=123456; tst (r4)+ (#123456) + d=040100 -- ! mem(4340)=040100; ror (r4)+ (#100201) + d=101100 -- ! mem(4342)=101100; ror (r4)+ (#002201) + d=000401 -- ! mem(4344)=000401; rol (r4)+ (#100200) + d=000100 -- ! mem(4346)=000100; asr (r4)+ (#200) + d=140100 -- ! mem(4350)=140100; asr (r4)+ (#100200) + d=000400 -- ! mem(4352)=000400; asl (r4)+ (#200) + d=000400 -- ! mem(4354)=000400; asl (r4)+ (#100200) + d=003711 -- ! mem(4356)=003711; add r1,(r4)+ (#4711, ,#177000) + d=000201 -- ! mem(4360)=000201; adc (r4)+ (#200) + d=177770 -- ! mem(4362)=177770; sub r1,(r4)+ (#4711, #4701) + d=000177 -- ! mem(4364)=000177; sbc (r4)+ (#200) + d=000222 -- ! mem(4366)=000222; swap (r4)+ (#111000) + d=177777 -- ! mem(4370)=177777; sxt (r4)+ (#111111) + d=074016 -- ! mem(4372)=074016; xor r1,(r4)+ (#070707) + d=000000 -- ! mem(4374)=000000; sxt (r4)+ (#111111) +# +wal 004500 -- NZVC +brm 31 + d=000020 -- ! mem(4500)=0000; mov r1,(r4)+ (#4711, #123456) + d=000021 -- ! mem(4502)=000C; cmp r1,(r4)+ (#4711, #123456) + d=000030 -- ! mem(4504)=N000; cmp r1,(r4)+ (#123456,#4711) + d=000024 -- ! mem(4506)=0Z00; cmp r1,(r4)+ (#4711, #4711) + d=000024 -- ! mem(4510)=0Z00; clr (r4)+ (#123456) + d=000020 -- ! mem(4512)=0000; bit r1,(r4)+ (#4711, #11) + d=000024 -- ! mem(4514)=0Z00; bit r1,(r4)+ (#4711, #66) + d=000030 -- ! mem(4516)=N000; bic r1,(r4)+ (#4711, #123456) + d=000030 -- ! mem(4520)=N000; bis r1,(r4)+ (#4711, #123456) + d=000030 -- ! mem(4522)=N000; add r1,(r4)+ (#4711, #123456) + d=000030 -- ! mem(4524)=N000; sub r1,(r4)+ (#4711, #123456) + d=000021 -- ! mem(4526)=000C; com (r4)+ (#123456) + d=000031 -- ! mem(4530)=N00C; inc (r4)+ (#123456) keep C! + d=000031 -- ! mem(4532)=N00C; dec (r4)+ (#123456) keep C! + d=000021 -- ! mem(4534)=000C; neg (r4)+ (#123456) + d=000030 -- ! mem(4536)=N000; tst (r4)+ (#123456) + d=000023 -- ! mem(4540)=00VC; ror (r4)+ (#100201) + d=000031 -- ! mem(4542)=N00C; ror (r4)+ (#002201) + d=000023 -- ! mem(4544)=00VC; rol (r4)+ (#100200) + d=000020 -- ! mem(4546)=0000; asr (r4)+ (#200) + d=000032 -- ! mem(4550)=N0V0; asr (r4)+ (#100200) + d=000020 -- ! mem(4552)=0000; asl (r4)+ (#200) + d=000023 -- ! mem(4554)=00VC; asl (r4)+ (#100200) + d=000021 -- ! mem(4556)=000C; add r1,(r4)+ (#4711, ,#177000) + d=000020 -- ! mem(4560)=0000; adc (r4)+ (#200) + d=000031 -- ! mem(4562)=N00C; sub r1,(r4)+ (#4711, #4701) + d=000020 -- ! mem(4564)=0000; sbc (r4)+ (#200) + d=000030 -- ! mem(4566)=N000; swap (r4)+ (#111000) + d=000030 -- ! mem(4570)=N000; sxt (r4)+ (#111111 with N=1) + d=000020 -- ! mem(4572)=0000; xor r1,(r4)+ (#4711, #070707) + d=000024 -- ! mem(4574)=0Z00; sxt (r4)+ (#111111 with N=0) +# +rst -- console reset (to clear T flag) +wal 000014 -- vector: 14 -> trap catcher again +bwm 2 + 000016 -- PC:16 + 000000 -- PS:0 +#----------------------------------------------------------------------------- +C Setup code 20 [base 4700] (check CPUERR and error handling) +#[[off]] +wal 004700 -- code (to be single stepped...) +bwm 11 + 010025 -- mov r0,(r5)+ (@ 4777) + 010025 -- mov r0,(r5)+ (@ 150000) + 010025 -- mov r0,(r5)+ (@ 160000) + 000101 -- jmp r1 + 004701 -- jsr pc,r1 + 000000 -- halt + 014321 -- mov -(r3),(r1)+ (@ 20000) + 024321 -- cmp -(r3),(r1)+ (@ 20400) +#4720 + 064321 -- add -(r3),(r1)+ (@ 20000) + 010046 -- mov r0,-(sp) (@ 340) + 000004 -- iot (with sp=342,...) +# +wal 000004 -- vector: 4+10 (trap catch) +bwm 4 + 000006 -- PC:6 + 000000 -- PS:0 + 000012 -- PC:12 + 000000 -- PS:0 +#---------- +C Exec code 20 (check CPUERR and error handling) +C Exec test 20.1 (odd address abort) +rst -- console reset +wps 000000 -- psw: clear +wal 001374 -- clean stack +bwm 2 + 000000 -- + 000000 -- +wal 177766 -- check initial CPUERR (=0!) +rm d=000000 -- ! +wr0 000011 -- r0=11 +wr5 004775 -- r5=4775 +wsp 001400 -- sp=1400 +wpc 004700 -- pc=4700 +step -- step (mov r0,(r5)+): trap 4 + CPUERR.adderr set [[s:2]] +rpc d=000006 -- ! pc=6 (trap 4 catch) +rsp d=001374 -- ! sp=1374 +wal 001374 -- check stack +brm 2 + d=004702 -- ! pc=4702 + d=000000 -- ! ps=0 +wal 177766 -- check CPUERR +rm d=000100 -- ! CPUERR: (adderr=1) +wm 000000 -- any write access will clear CPUERR +rm d=000000 -- ! CPUERR: 0 +#---------- +C Exec test 20.2 (non-existent memory abort) +wal 172354 -- kernel I space AR(6) +wm 177400 -- (map to 8 k below I/O page, never available in w11a) +wal 177572 -- SSR0 +wmi 000001 -- enable +wal 172516 -- SSR3 +wmi 000020 -- ena_22bit=1 +# +wr5 140000 -- r5=140000 +wsp 001400 -- sp=1400 +wpc 004702 -- pc=4702 +step -- step (mov r0,(r5)+): trap 4 + CPUERR.nxm set [[s:2]] +rpc d=000006 -- ! pc= 6 (trap 4 catch) +rsp d=001374 -- ! sp=1374 +wal 177766 -- check CPUERR +rm d=000040 -- ! CPUERR: (nxm=1) +wm 000000 -- any write access will clear CPUERR +rm d=000000 -- ! CPUERR: 0 +# +wal 177572 -- SSR0 +wmi 000000 -- disable +wal 172354 -- kernel I space AR(6) +wm 001400 -- 1400 140000 base (default 1-to-1 map) +#---------- +C Exec test 20.3 (I/O bus timeout abort) +wr5 160000 -- r5=160000 +wsp 001400 -- sp=1400 +wpc 004704 -- pc=4704 +step -- step (mov r0,(r5)+): trap 4 + CPUERR.iobto set [[s:2]] +rpc d=000006 -- ! pc= 6 (trap 4 catch) +rsp d=001374 -- ! sp=1374 +wal 177766 -- check CPUERR +rm d=000020 -- ! CPUERR: (iobto=1) +wm 000000 -- clear CPUERR +#---------- +C Exec test 20.4 (address error abort after jmp r1) +wsp 001400 -- sp=1400 +wpc 004706 -- pc=4706 +step -- step (jmp r1): trap 10 [[s:2]] +rpc d=000012 -- ! pc=12 (trap 10 catch) +rsp d=001374 -- ! sp=1374 +wal 177766 -- check CPUERR +rm d=000000 -- ! CPUERR: none +wm 000000 -- clear CPUERR +#---------- +C Exec test 20.5 (address error abort after jsr pc,r1) +wsp 001400 -- sp=1400 +wpc 004710 -- pc=4710 +step -- step (jsr pc,r1): trap 10 [[s:2]] +rpc d=000012 -- ! pc=12 (trap 10 catch) +rsp d=001374 -- ! sp=1374 +wal 177766 -- check CPUERR +rm d=000000 -- ! CPUERR: none +wm 000000 -- clear CPUERR +#---------- +C Exec test 20.6 (halt in user mode) +wsp 001400 -- sp=1400 (kernel) +wpc 004712 -- pc=4712 +wps 170000 -- psw: cmode=pmode=11 (user) +step -- step (halt): trap 4 + CPUERR.illhlt set [[s:2]] +rpc d=000006 -- ! pc=6 (trap 4 catch) +rsp d=001374 -- ! sp=1374 (now kernel again...) +wal 001374 -- check stack +brm 2 + d=004714 -- ! + d=170000 -- ! +wal 177766 -- check CPUERR +rm d=000200 -- ! CPUERR: (illhlt=1) +wm 000000 -- clear CPUERR +# +wps 000000 -- psw: cmode=pmode=0 (kernel) +#---------- +# +# test mmu aborts +# +wal 000250 -- vector: 250 -> trap catcher +bwm 2 + 000252 -- PC:252 + 000000 -- PS:0 +# +wal 177572 -- SSR0 +wmi 000001 -- enable +wal 172302 -- kernel I space DR segment 1 (base 20000) +wmi 077400 -- slf=127; ed=0(up); acf=0 (non-resident) +#---------- +C Exec test 20.7 (non resident abort) +wr1 020000 -- r1=20000 +wr3 000016 -- r3=16 ; the -(r3) fetches the mem(14)=16 +wsp 001400 -- sp=1400 +wpc 004714 -- pc=4714 +step -- step (mov -(r3),(r1)+): abort to 250 [[s:2]] +rr1 d=020002 -- ! r1=20002 (inc done before trap (here dstw)) +rr3 d=000014 -- ! r3=16 (dec done before trap) +rpc d=000252 -- ! pc=252 (trap 250 catch) +rsp d=001374 -- ! sp=1374 +wal 177572 -- check SSR0/1/2 +brm 3 + d=100003 -- ! SSR0: (abo_nonres=1,seg=1,ena=1) + d=010763 -- ! SSR1: rb=1,2; ra=3,-2 + d=004714 -- ! SSR2: 4714 (eff. PC) +# +wal 177572 -- SSR0 +wmi 000001 -- enable and clear error bits +#---------- +C Exec test 20.8 (segment length violation abort) +wal 172302 -- kernel I space DR segment 1 (base 20000) +wmi 001406 -- slf=3; ed=0(up); acf=6 (w/r) +# +wr1 020400 -- r1=20400 +wr3 000016 -- r3=16 ; the -(r3) fetches the mem(14)=16 +wsp 001400 -- sp=1400 +wpc 004716 -- pc=4716 +step -- step (cmp -(r3),(r1)+): abort to 250 [[s:2]] +rr1 d=020402 -- ! r1=20402 (inc done before trap (here dstr)) +rr3 d=000014 -- ! r3=16 (dec done before trap) +rpc d=000252 -- ! pc=252 (trap 250 catch) +rsp d=001374 -- ! sp=1374 +wal 177572 -- check SSR0/1/2 +brm 3 + d=040003 -- ! SSR0: (abo_length=1,seg=1,ena=1) + d=010763 -- ! SSR1: rb=1,2; ra=3,-2 + d=004716 -- ! SSR2: 4716 (eff. PC) +# +wal 177572 -- SSR0 +wmi 000001 -- enable and clear error bits +#---------- +C Exec test 20.9 (read-only abort) +wal 172302 -- kernel I space DR segment 1 (base 20000) +wmi 077402 -- slf=127; ed=0(up); acf=2 (read-only) +# +wr1 020000 -- r1=20000 +wr3 000016 -- r3=16 ; the -(r3) fetches the mem(14)=16 +wsp 001400 -- sp=1400 +wpc 004720 -- pc=4720 +step -- step (add -(r3),(r1)+): abort to 250 [[s:2]] +rr1 d=020002 -- ! r1=20000 (inc done before trap (here dstm)) +rr3 d=000014 -- ! r3=16 (dec done before trap) +rpc d=000252 -- ! pc=252 (trap 250 catch) +rsp d=001374 -- ! sp=1374 +wal 177572 -- check SSR0/1/2 +brm 3 + d=020003 -- ! SSR0: (abo_rdonly=1,seg=1,ena=1) + d=010763 -- ! SSR1: rb=1,2; ra=3,-2 + d=004720 -- ! SSR2: 4720 (eff. PC) +# +# mmu back to default setup, disable +wal 172302 -- kernel I space DR segment 1 (base 20000) +wmi 077406 -- slf=127; ed=0(up); acf=6 (r/w) +wal 177572 -- SSR0 +wmi 000000 -- disable +#---------- +# +# test mmu trap +# +wal 177572 -- SSR0 +wmi 001001 -- enable, trap enable +wal 172302 -- kernel I space DR segment 1 (base 20000) +wmi 077404 -- slf=127; ed=0(up); acf=4 (r/w, trap on r/w) +#---------- +C Exec test 20.10 (trap on write) +wr1 020000 -- r1=20000 +wr3 000016 -- r3=16 ; the -(r3) fetches the mem(14)=16 +wsp 001400 -- sp=1400 +wpc 004714 -- pc=4714 +step -- step (mov -(r3),(r1)+): trap to 250 [[s:2]] +rr1 d=020002 -- ! r1=20002 (inc done before trap) +rr3 d=000014 -- ! r3=16 (dec done before trap) +rpc d=000252 -- ! pc=252 (trap 250 catch) +rsp d=001374 -- ! sp=1374 +wal 020000 -- check target area +rm d=000016 -- ! mem(20000)=16 +wm 000000 -- clean tainted memory +wal 177572 -- check SSR0 +brm 3 + d=011001 -- ! SSR0: (trap_mmu=1,ena_trap=1,seg=0,ena=1) + d=010763 -- ! SSR1: rb=1,2; ra=3,-2 + d=004714 -- ! SSR2: 4714 (eff. PC) +#---------- +C Exec test 20.11 (2nd write, should not trap again) +wr1 020002 -- r1=20002 +wr3 000016 -- r3=16 ; the -(r3) fetches the mem(14)=16 +wsp 001400 -- sp=1400 +wpc 004714 -- pc=4714 +step -- step (mov -(r3),(r1)+): no trap [[s:2]] +rr1 d=020004 -- ! r1=20004 (inc done before trap) +rr3 d=000014 -- ! r3=16 (dec done before trap) +rpc d=004716 -- ! pc=252 (trap 250 catch) +rsp d=001400 -- ! sp=1374 +wal 020002 -- check target area +rm d=000016 -- ! mem(20002)=16 +wm 000000 -- clean tainted memory +wal 177572 -- check SSR0 +brm 3 + d=011003 -- ! SSR0: (trap_mmu=1,ena_trap=1,seg=1,ena=1) + d=010763 -- ! SSR1: rb=1,2; ra=3,-2 + d=004714 -- ! SSR2: 4714 (eff. PC) +# +# mmu back to default setup, disable +wal 172302 -- kernel I space DR segment 1 (base 20000) +wmi 077406 -- slf=127; ed=0(up); acf=6 (r/w) +wal 177572 -- SSR0 +wmi 000000 -- disable +#---------- +# +# now test stack limit logic +# +C Exec test 20.12 (red stack abort when pushing data to stack) +wr0 123456 -- r0=123456 +wsp 000340 -- sp=340 +wpc 004722 -- pc=4722 +step -- step (mov r0,-(sp)): abort to 4 [[s:2]] +rpc d=000006 -- ! pc=6 (trap 4 catch) +rsp d=000000 -- ! sp=0 +wal 000336 -- check that stack wasn't written +rm d=000000 -- ! mem(336) untainted +wal 000000 -- check emergency stack at 0,2 +brm 2 + d=004724 -- ! mem(0): PC + d=000010 -- ! mem(2): PS +wal 177766 -- check CPUERR +rm d=000004 -- ! CPUERR: (rsv=1) +wm 000000 -- clear CPUERR +#---------- +C Exec test 20.13 (red stack abort on 2nd word of interrupt/trap push) +wps 000017 -- psw: set all cc flags +wsp 000342 -- sp=342 +wpc 004724 -- pc=4724 +step -- step (iot): abort to 4 [[s:2]] +rpc d=000006 -- ! pc=6 (trap 4 catch) +rsp d=000000 -- ! sp=0 +wal 000336 -- check stack +brm 2 + d=000000 -- ! mem(336) untainted + d=000017 -- ! mem(340) PS of 1st attempt +wal 000000 -- check emergency stack at 0,2 +brm 2 + d=004726 -- ! mem(0): PC + d=000000 -- ! mem(2): PS (will be 0, orgininal PS lost !!) +wal 177766 -- check CPUERR +rm d=000004 -- ! CPUERR: (rsv=1) +wm 000000 -- clear CPUERR +#---------- +C Exec test 20.14 (yellow stack trap when pushing data to stack; sp=400) +wps 000017 -- psw: set all cc flags +wr0 123456 -- r0=123456 +wsp 000400 -- sp=400 +wpc 004722 -- pc=4722 +step -- step (mov r0,-(sp)): trap to 4 +rpc d=000006 -- ! pc=6 (trap 4 catch) +rsp d=000372 -- ! sp=372 +wal 000372 -- check stack +brm 3 + d=004724 -- ! mem(372) PC of trapped instruction + d=000011 -- ! mem(374) PS of trapped instruction + d=123456 -- ! mem(376) pushed word +wal 177766 -- check CPUERR +rm d=000010 -- ! CPUERR: (ysv=1) +wm 000000 -- clear CPUERR +#---------- +C Exec test 20.15 (yellow stack trap on 2nd word of interrupt/trap push; sp=402) +wps 000017 -- psw: set all cc flags +wsp 000402 -- sp=402 +wpc 004724 -- pc=4724 +step -- step (iot): abort to 4 [[s:2]] +rpc d=000006 -- ! pc=6 (trap 4 catch) +rsp d=000372 -- ! sp=372 +wal 000372 -- check stack +brm 4 + d=000022 -- ! mem(372) PC of IOT handler + d=000000 -- ! mem(374) PS of IOT handler + d=004726 -- ! mem(376) PC of IOT trap + d=000017 -- ! mem(400) PS of IOT trap +wal 177766 -- check CPUERR +rm d=000010 -- ! CPUERR: (ysv=1) +wm 000000 -- clear CPUERR +#---------- +# now test red stack escalation +# +C Exec test 20.16 (red stack escalation: abort kernel stack odd; sp=1001) +wr0 123456 -- r0=123456 +wsp 001001 -- sp=1001 +wpc 004722 -- pc=4722 +step -- step (mov r0,-(sp)): abort to 4 [[s:2]] +rpc d=000006 -- ! pc=6 (trap 4 catch) +rsp d=000000 -- ! sp=0 +wal 000000 -- check emergency stack at 0,2 +brm 2 + d=004724 -- ! mem(0): PC + d=000010 -- ! mem(2): PS +wal 177766 -- check CPUERR +rm d=000104 -- ! CPUERR: (rsv=1,adderr=1) +wm 000000 -- clear CPUERR +#---------- +C Exec test 20.17 (red stack escalation: abort kernel stack in non-mem) +wal 172354 -- kernel I space AR(6) +wm 177400 -- (map to 8 k below I/O page, never available in w11a) +wal 177572 -- SSR0 +wmi 000001 -- enable +wal 172516 -- SSR3 +wmi 000020 -- ena_22bit=1 +# +wr0 123456 -- r0=123456 +wsp 140004 -- sp=140004 +wpc 004722 -- pc=4722 +step -- step (mov r0,-(sp)): abort to 4 [[s:2]] +rpc d=000006 -- ! pc=6 (trap 4 catch) +rsp d=000000 -- ! sp=0 +wal 000000 -- check emergency stack at 0,2 +brm 2 + d=004724 -- ! mem(0): PC + d=000010 -- ! mem(2): PS +wal 177766 -- check CPUERR +rm d=000044 -- ! CPUERR: (rsv=1,nxm=1) +wm 000000 -- clear CPUERR +# +wal 177572 -- SSR0 +wmi 000000 -- disable +wal 172354 -- kernel I space AR(6) +wm 001400 -- 1400 140000 base (default 1-to-1 map) +#---------- +C Exec test 20.18 (red stack escalation: abort kernel stack iob-to;sp=160004) +wr0 123456 -- r0=123456 +wsp 160004 -- sp=160004 +wpc 004722 -- pc=4722 +step -- step (mov r0,-(sp)): abort to 4 [[s:2]] +rpc d=000006 -- ! pc=6 (trap 4 catch) +rsp d=000000 -- ! sp=0 +wal 000000 -- check emergency stack at 0,2 +brm 2 + d=004724 -- ! mem(0): PC + d=000010 -- ! mem(2): PS +wal 177766 -- check CPUERR +rm d=000024 -- ! CPUERR: (rsv=1,iobto=1) +wm 000000 -- clear CPUERR +#---------- +C Exec test 20.19 (red stack escalation: abort kernel stack mmu abort;sp=020004) +# +wal 177572 -- SSR0 +wmi 000001 -- enable +wal 172302 -- kernel I space DR segment 1 (base 20000) +wmi 077400 -- slf=127; ed=0(up); acf=0 (non-resident) +# +wr0 123456 -- r0=123456 +wsp 020004 -- sp=020004 +wpc 004722 -- pc=4722 +step -- step (mov r0,-(sp)): abort to 4 [[s:2]] +rpc d=000006 -- ! pc=6 (trap 4 catch) +rsp d=000000 -- ! sp=0 +wal 020002 -- check that stack wasn't written +rm d=000000 -- ! mem(20002) untainted +wal 000000 -- check emergency stack at 0,2 +brm 2 + d=004724 -- ! mem(0): PC + d=000010 -- ! mem(2): PS +wal 177766 -- check CPUERR +rm d=000104 -- ! CPUERR: (rsv=1,adderr=1) +wm 000000 -- clear CPUERR +# mmu back to default setup +wal 172302 -- kernel I space DR segment 1 (base 20000) +wmi 077406 -- slf=127; ed=0(up); acf=6 (r/w) +wal 177572 -- SSR0 +wmi 000000 -- disable +wal 172516 -- SSR3 +wmi 000000 -- disable +# +#[[on]] +#----------------------------------------------------------------------------- +C Setup code 21 [base 4740] (MTPx/MFPx; MMU for user mode with I/D) +# +#use setting as for test 22 +wal 177600 -- user I space DR +wmi 077406 -- slf=127; ed=0(up); acf=6(w/r) +wal 177620 -- user D space DR +wmi 077406 -- slf=127; ed=0(up); acf=6(w/r) +wal 177640 -- user I space AR +wmi 000053 -- 53 -> maps 0 -> 5300 +wal 177660 -- user D space AR +wmi 000055 -- 55 -> maps 0 -> 5500 +wal 177572 -- SSR0 +wmi 000001 -- set enable bit +wal 172516 -- SSR3 +wmi 000001 -- enable D space for user mode +# +wal 004740 -- code (to be single stepped...) +bwm 6 + 006610 -- mtpi (r0) + 106610 -- mtpd (r0) + 006606 -- mtpi r6 + 006510 -- mfpi (r0) + 106510 -- mfpd (r0) + 006506 -- mfpi r6 +# +C Exec code 21 (MTPx/MFPx; MMU for user mode with I/D) +# +wps 030000 -- psw: cmode=0, pmode=11 +wal 001372 -- setup kernel stack +bwm 3 + 012300 -- + 001230 -- + 000666 -- +wr0 000002 -- r0=2 +wsp 001372 -- sp=1372 +# +wpc 004740 -- pc=4740 +step -- step (mtpi (r0)) +rpc d=004742 -- ! pc=next +rsp d=001374 -- ! sp=1374 (one popped) +wal 005302 -- user I base +rm d=012300 -- ! mem_ui(2) = 012300 +# +step -- step (mtpd (r0)) +rpc d=004744 -- ! pc=next +rsp d=001376 -- ! sp=1376 (one popped) +wal 005502 -- user D base +rm d=001230 -- ! mem_ud(2) = 001230 +# +step -- step (mtpi r6) +rpc d=004746 -- ! pc=next +rsp d=001400 -- ! sp=1400 (one popped) +wps 170000 -- psw: cmode=11, pmode=11 +rsp d=000666 -- ! sp_um=666 [[usp]] +wps 030000 -- psw: cmode=0, pmode=11 +# +wal 001374 -- clear stack +bwm 3 + 000000 -- + 000000 -- + 000000 -- +# +step -- step (mfpi (r0)) +rpc d=004750 -- ! pc=next +rsp d=001376 -- ! sp=1376 (one pushed) +wal 001376 -- top of stack +rm d=012300 -- ! +# +step -- step (mfpd (r0)) +rpc d=004752 -- ! pc=next +rsp d=001374 -- ! sp=1374 (one pushed) +wal 001374 -- top of stack +rm d=001230 -- ! +# +step -- step (mtpi r6) +rpc d=004754 -- ! pc=next +rsp d=001372 -- ! sp=1372 (one pushed) +wal 001372 -- top of stack +rm d=000666 -- ! +# +wal 005302 -- clean tainted memory +wm 000000 -- +wal 005502 -- +wm 000000 -- +# +wps 000000 -- psw: cmode=pmode=0 (kernel) +#----------------------------------------------------------------------------- +C Setup code 22 [base 5000, use 50-57] (MMU ; run user mode code with I/D) +# +wal 177600 -- user I space DR +wmi 000002 -- slf=0; ed=0(up); acf=2(read-only) +wal 177620 -- user D space DR +wmi 000006 -- slf=0; ed=0(up); acf=6(w/r) +wal 177640 -- user I space AR +wmi 000053 -- 53 -> maps 0 -> 5300 +wal 177660 -- user D space AR +wmi 000055 -- 55 -> maps 0 -> 5500 +wal 177572 -- SSR0 +wmi 000001 -- set enable bit +wal 172516 -- SSR3 +wmi 000001 -- enable D space for user mode +# +wal 005000 -- code (kernel): +bwm 5 + 012746 -- mov #144000,-(sp) ;PS for RTI + 174000 -- cmode=11,pmode=11,rset=1 + 012746 -- mov #0,-(sp) ;PC for RTI + 000000 -- + 000002 -- rti +#----- +wal 000034 -- vector: 34 (TRAP) +bwm 2 + 005020 -- PC:5020 + 000340 -- PS: pri=7 +#----- +wal 005020 -- code (kernel, trap 34): +bwm 4 + 011600 -- mov (sp),r0 + 006560 -- mfpi -2(r0) + 177776 + 000000 -- halt +#----- +wal 000250 -- vector: 250 (MMU) +bwm 2 + 005040 -- PC:5040 + 000340 -- PS: pri=7 +#----- +wal 005040 -- code (kernel, trap 4): +bwm 68 + 005337 -- dec @#5256 + 005256 + 001001 -- bne .+2 + 000000 -- halt + 013700 -- mov ssr0,r0 + 177572 + 042700 -- bic #177741,r0 ; clear all but id+asn fields + 177741 +#5060 + 062700 -- add #177600,r0 ; user DR address base + 177600 +# 5 23 062710 0 -- add #400,(r0) +# 5 23 000400 0 + 105260 -- incb 1(r0) ; odd address IB access fails !! + 000001 + 010025 -- mov r0,(r5)+ + 012025 -- mov (r0),(r5)+ + 013700 -- mov ssr1,r0 + 177574 +#5100 + 010025 -- mov r0,(r5)+ + 012701 -- mov #2,r1 + 000002 + 052737 -- bis #004000,psw + 004000 + 177776 + 005046 -- clr -(sp) + 106506 -- mfpd sp +#5120 + 010546 -- mov r5,-(sp) + 010446 -- mov r4,-(sp) + 010346 -- mov r3,-(sp) + 010246 -- mov r2,-(sp) + 010146 -- mov r1,-(sp) + 010046 -- mov r0,-(sp) + 042737 -- bic #004000,psw + 004000 +#5140 + 177776 + 010002 -- L1: mov r0,r2 + 110003 -- movb r0,r3 + 042702 -- bic #177770,r2 ; mask regnum field + 177770 + 006302 -- asl r2 + 060602 -- add sp,r2 ; address of reg on stack + 006203 -- asr r3 ; shift delta field down 3 bit +#5160 + 006203 -- asr r3 + 006203 -- asr r3 + 160312 -- sub r3,(r2) ; correct register contents + 000300 -- swap r0 + 077114 -- sob r1,L1 (.-12) + 052737 -- bis #004000,psw + 004000 + 177776 +#5200 + 012600 -- mov (sp)+,r0 + 012601 -- mov (sp)+,r1 + 012602 -- mov (sp)+,r2 + 012603 -- mov (sp)+,r3 + 012604 -- mov (sp)+,r4 + 012605 -- mov (sp)+,r5 + 106606 -- mtpd sp + 005726 -- tst (sp)+ +#5220 + 042737 -- bic #004000,psw + 004000 + 177776 + 013700 -- mov ssr2,r0 + 177576 + 010025 -- mov r0,(r5)+ + 010016 -- mov r0,(sp) + 042737 -- bic #160000,ssr0 ; clear abort bits +#5240 + 160000 + 177572 + 000002 -- rti + 000000 -- halt +#----- +wal 005256 -- data (kernel): +wmi 000003 -- stop at 3rd call of MMU handler +#----- +wal 005300 -- code (user): +bwm 8 + 012706 -- mov #100,sp + 000100 + 005000 -- clr r0 + 012701 -- mov #074,r1 + 000074 + 062021 -- add (r0)+,(r1)+ ; r1 = 74 + 000137 -- jmp @#74 + 000074 +# +wal 005374 -- .=5374 +bwm 4 + 062021 -- add (r0)+,(r1)+ ; r1 = 76 + 062021 -- add (r0)+,(r1)+ ; r1 = 100 +#5400 + 062021 -- add (r0)+,(r1)+ ; r1 = 102 + 104417 -- trap 17 +# +wal 005500 -- data (user): +bwm 4 + 002001 -- mem_ud(0)=02001 + 002002 -- mem_ud(2)=02002 + 002003 -- mem_ud(4)=02003 + 002004 -- mem_ud(6)=02004 +wal 005574 -- data (user): +bwm 4 + 000300 -- mem_ud(074)=0300 + 000300 -- mem_ud(076)=0300 + 000300 -- mem_ud(100)=0300 + 000300 -- mem_ud(102)=0300 +# +C Exec code 22 (MMU ; run user mode code with I/D) +wr5 005260 -- r5=5260 +wsp 001400 -- sp=1400 +wpc 005000 -- pc=5000 +cont -- cont @ 5000 +wtgo +rsp d=001372 -- ! sp +rpc d=005030 -- ! pc (halt in TRAP handler) +wal 001372 -- check stack (1372) +brm 3 + d=104417 -- ! TRAP instruction + d=000104 -- ! PC trap + d=174000 -- ! PS trap +# +wal 005256 -- +brm 9 + d=000001 -- ! mem(5256) (mmu 3 - trap count) + d=177620 -- ! mem(5260) (1st trap: address fixed DR) + d=000406 -- ! mem(5262) (1st trap: new content of DR) + d=010420 -- ! mem(5264) (1st trap: ssr1: ra=0,2;rb=1,2) + d=000076 -- ! mem(5266) (1st trap: ssr2: pc) + d=177600 -- ! mem(5270) (2nd trap: address fixed DR) + d=000402 -- ! mem(5272) (2nd trap: new content of DR) + d=000000 -- ! mem(5274) (2nd trap: ssr1: none) + d=000100 -- ! mem(5276) (2nd trap: ssr2: pc) +# +wal 005574 +brm 4 + d=002301 -- ! mem(5574)=02301 was mem_ud(074) + d=002302 -- ! mem(5576)=02302 was mem_ud(076) + d=002303 -- ! mem(5600)=02303 was mem_ud(100) + d=002304 -- ! mem(5602)=02304 was mem_ud(102) +# +wal 000034 -- vector: 34 -> trap catcher again +bwm 2 + 000036 -- PC:36 + 000000 -- PS:0 +wal 000250 -- vector: 250 -> trap catcher again +bwm 2 + 000252 -- PC:252 + 000000 -- PS:0 +# +wps 000000 -- psw: cmode=pmode=0 (kernel) +#----------------------------------------------------------------------------- +C Setup code 23 [base 5700; use 57-63] (test cmp and conditional branch) +# +wal 005700 -- code test 1: +bwm 5 + 012012 -- mov (r0)+,(r2) ; load PSW from table + 004737 -- jsr pc,@#6000 + 006000 + 077104 -- sob r1,-4 + 000000 -- halt +# +wal 005720 -- code test 2: +bwm 6 + 000230 -- spl 0 + 005720 -- tst (r0)+ ; verify tst response + 004737 -- jsr pc,@#6000 + 006000 + 077104 -- sob r1,-4 + 000000 -- halt +# +wal 005740 -- code test 3: +bwm 6 + 000230 -- spl 0 + 022020 -- cmp (r0+),(r0)+ ; verify cmp response + 004737 -- jsr pc,@#6000 + 006000 + 077104 -- sob r1,-4 + 000000 -- halt +# +# test 1 test 2 test 3 +# - C V Z N < = > < = > +# code branch condition mask 1 2 3 4 5 1 2 3 1 2 3 4 5 6 7 +# BNE if Z = 0 000004 y y y y y y y y y y y y +# BEQ if Z = 1 000010 y y y +# BGE if (N xor V) = 0 000020 y y y y y y y y y +# BLT if (N xor V) = 1 000040 y y y y y y +# BGT if (Z or (N xor V)) = 0 000100 y y y y y y +# BLE if (Z or (N xor V)) = 1 000200 y y y y y y y y y +# BPL if N = 0 000400 y y y y y y y y y y +# BMI if N = 1 001000 y y y y y +# BHI if (C or Z) = 0 002000 y y y y y y y y +# BLOS if (C or Z) = 1 004000 y y y y y y y +# BVC if V = 0 010000 y y y y y y y y y y y y +# BVS if V = 1 020000 y y y +# BCC if C = 0 (aka BHIS) 040000 y y y y y y y y y y y +# BCS if C = 1 (aka BLO) 100000 y y y y +# +wal 006000 -- code check: +bwm 63 + 011203 -- mov (r2),r3 ; save PSW + 012704 -- mov #177774,r4 ; set pattern store + 177774 -- + 010312 -- mov r3,(r2) ; restore PSW + 001003 -- bne .+3 + 042704 -- bic #000004,r4 + 000004 -- + 010312 -- mov r3,(r2) +#6020 + 001403 -- beq .+3 + 042704 -- bic #000010,r4 + 000010 -- + 010312 -- mov r3,(r2) + 002003 -- bge .+3 + 042704 -- bic #000020,r4 + 000020 -- + 010312 -- mov r3,(r2) +#6040 + 002403 -- blt .+3 + 042704 -- bic #000040,r4 + 000040 -- + 010312 -- mov r3,(r2) + 003003 -- bgt .+3 + 042704 -- bic #000100,r4 + 000100 -- + 010312 -- mov r3,(r2) +#6060 + 003403 -- ble .+3 + 042704 -- bic #000200,r4 + 000200 -- + 010312 -- mov r3,(r2) + 100003 -- bpl .+3 + 042704 -- bic #000400,r4 + 000400 -- + 010312 -- mov r3,(r2) +#6100 + 100403 -- bmi .+3 + 042704 -- bic #001000,r4 + 001000 -- + 010312 -- mov r3,(r2) + 101003 -- bhi .+3 + 042704 -- bic #002000,r4 + 002000 -- + 010312 -- mov r3,(r2) +#6120 + 101403 -- blos .+3 + 042704 -- bic #004000,r4 + 004000 -- + 010312 -- mov r3,(r2) + 102003 -- bvc .+3 + 042704 -- bic #010000,r4 + 010000 -- + 010312 -- mov r3,(r2) +#6140 + 102403 -- bvs .+3 + 042704 -- bic #020000,r4 + 020000 -- + 010312 -- mov r3,(r2) + 103003 -- bcc .+3 + 042704 -- bic #040000,r4 + 040000 -- + 010312 -- mov r3,(r2) +#6160 + 103403 -- bcs .+3 + 042704 -- bic #100000,r4 + 100000 -- + 010312 -- mov r3,(r2) + 010325 -- mov r3,(r5)+ + 010425 -- mov r4,(r5)+ + 000207 -- rts pc +# +wal 006200 -- data test 1: +bwm 5 + 000000 -- PSW - no cc + 000001 -- PSW - C=1 + 000002 -- PSW - V=1 + 000004 -- PSW - Z=1 + 000010 -- PSW - N=1 +# +wal 006220 -- data test 2: +bwm 3 + 177777 -- tst -1 + 000000 -- tst 0 + 000001 -- tst 1 +# +wal 006230 -- data test 3: +bwm 14 + 000001 -- cmp 1,2 + 000002 + 000001 -- cmp 1,1 + 000001 +#6240 + 000002 -- cmp 2,1 + 000001 + 177777 -- cmp -1,2 + 000002 + 000002 -- cmp 2,-1 + 177777 + 100000 -- cmp 100000,077777 + 077777 +#6260 + 077777 -- cmp 077777,100000 + 100000 +# +C Exec code 23 (test cmp and conditional branch) +C Exec test 23.1 (explict cc setting) +# +wr0 006200 -- r0=6200 (input data) +wr1 000005 -- r1=5 +wr2 177776 -- r2=177776 (PS address) +wr5 006300 -- r5=6300 (output data) +wsp 001400 -- sp=1400 +stapc 005700 -- start @ 5700 +wtgo +rr0 d=006212 -- ! r0 +rr1 d=000000 -- ! r1 +rr5 d=006324 -- ! r5 +rsp d=001400 -- ! sp +rpc d=005712 -- ! pc +wal 006300 -- use BCC/BCS naming below +brm 10 + d=000000 -- ! mem(6300) 1 PS: none + d=052524 -- ! mem(6302) 1 BNE,BGE,BGT,BPL,BHI,BVC,BCC + d=000001 -- ! mem(6304) 2 PS: C=1 + d=114524 -- ! mem(6306) 2 BNE,BGE,BGT,BPL,BLOS,BVC,BCS + d=000002 -- ! mem(6310) 3 PS: V=1 + d=062644 -- ! mem(6312) 3 BNE,BLT,BLE,BPL,BHI,BVS,BCC + d=000004 -- ! mem(6314) 4 PS: Z=1 + d=054630 -- ! mem(6316) 4 BEQ,BGE,BLE,BPL,BLOS,BVC,BCC + d=000010 -- ! mem(6320) 5 PS: N=1 + d=053244 -- ! mem(6322) 5 BNE,BLT,BLE,BMI,BHI,BVC,BCC +# +C Exec test 23.2 (tst testing) +# +wr0 006220 -- r0=6220 (input data) +wr1 000003 -- r1=3 +wr2 177776 -- r2=177776 (PS address) +wr5 006330 -- sp=6330 (output data) +wsp 001400 -- sp=1400 +stapc 005720 -- start @ 5720 +wtgo +rr0 d=006226 -- ! r0 +rr1 d=000000 -- ! r1 +rr5 d=006344 -- ! r5 +rsp d=001400 -- ! sp +rpc d=005734 -- ! pc +wal 006330 -- use BHIS(BCC)/BLO(BLO) naming below +brm 6 + d=000010 -- ! mem(6330) 1 PS: tst -1: N=1 + d=053244 -- ! mem(6332) 1 BNE,BLT,BLE,BMI,BHI,BVC,BHIS + d=000004 -- ! mem(6334) 2 PS: tst 0: Z=1 + d=054630 -- ! mem(6336) 2 BEQ,BGE,BLE,BPL,BLOS,BVC,BHIS + d=000000 -- ! mem(6340) 3 PS: tst 1: all 0 + d=052524 -- ! mem(6342) 3 BNE,BGE,BGT,BPL,BHI,BVC,BHIS +# +C Exec test 23.3 (cmp testing) +# +wr0 006230 -- r0=6230 (input data) +wr1 000007 -- r1=7 +wr2 177776 -- r2=177776 (PS address) +wr5 006344 -- sp=6344 (output data) +wsp 001400 -- sp=1400 +stapc 005740 -- start @ 5740 +wtgo +rr0 d=006264 -- ! r0 +rr1 d=000000 -- ! r1 +rr5 d=006400 -- ! r5 +rsp d=001400 -- ! sp +rpc d=005754 -- ! pc +wal 006344 -- cmp= S-D ! +brm 14 + d=000011 -- ! mem(6344) 1 PS: cmp 1,2: N=1,C=1 ok + d=115244 -- ! mem(6346) 1 BNE,BLT,BLE,BMI,BLOS,BVC,BLO + d=000004 -- ! mem(6350) 2 PS: cmp 1,1: Z=1 ok + d=054630 -- ! mem(6352) 2 BEQ,BGE,BLE,BPL,BLOS,BVC,BHIS + d=000000 -- ! mem(6354) 3 PS: cmp 2,1: none ok + d=052524 -- ! mem(6356) 3 BNE,BGE,BGT,BPL,BHI,BVC,BHIS + d=000010 -- ! mem(6360) 4 PS: cmp -1,2: N=1 + d=053244 -- ! mem(6362) 4 BNE,BLT,BLE,BMI,BHI,BVC,BHIS ok + d=000001 -- ! mem(6364) 5 PS: cmp 2,-1: C=1 + d=114524 -- ! mem(6366) 5 BNE,BGE,BGT,BPL,BLOS,BVC,BLO ok + d=000002 -- ! mem(6370) 6 PS: cmp 10..,07..: V=1 + d=062644 -- ! mem(6372) 6 BNE,BLT,BLE,BPL,BHI,BVS,BHIS ok + d=000013 -- ! mem(6374) 7 PS: cmp 07..,10..: N=1,V=1,C=1 + d=125124 -- ! mem(6376) 7 BNE,BGE,BGT,BMI,BLOS,BVS,BLO ok +# +#----------------------------------------------------------------------------- +C Setup code 24 [base 6400] (test MARK instruction) +# +wal 006400 -- code (main): +bwm 13 + 010546 -- mov r5,-(sp) ; push old r5 on stack + 012746 -- mov #101,-(sp) ; push 1st parameter + 000101 + 012746 -- mov #102,-(sp) ; push 2nd parameter + 000102 + 012746 -- mov #103,-(sp) ; push 3rd parameter + 000103 + 012746 -- mov #mark3,-(sp) ; push MARK 3 +#6420 + 006403 + 010605 -- mov sp,r5 ; address of MARK N + 004737 -- jsr pc,@#6440 ; call procedure + 006440 + 000000 -- halt +# +# stack of procedure when called: +# addr content +# 576 12(sp) 10(r5) old r5 +# 574 10(sp) 6(r5) param1 +# 572 6(sp) 4(r5) param2 +# 570 4(sp) 2(r5) param3 +# 566 2(sp) (r5) mark 3 +# 564 (sp) return pc +# +wal 006440 -- code (procedure): +bwm 7 + 016520 -- mov 6(r5),(r0)+ ; get 1st param + 000006 + 016520 -- mov 4(r5),(r0)+ ; get 2nd param + 000004 + 016520 -- mov 2(r5),(r0)+ ; get 3rd param + 000002 + 000205 -- rts r5 +# +C Exec code 24 (test MARK instruction) +# +wr0 006470 -- r0=6470 +wr5 123456 -- r5=123456 +wsp 001400 -- sp=1400 +stapc 006400 -- start @ 6400 +wtgo +rr0 d=006476 -- ! r0=6476 (3 words written) +rr5 d=123456 -- ! r5 (restored) +rsp d=001400 -- ! sp +rpc d=006432 -- ! pc +wal 001364 -- check stack +brm 6 + d=006430 -- ! mem(1364) + d=006403 -- ! mem(1366) + d=000103 -- ! mem(1370) + d=000102 -- ! mem(1372) + d=000101 -- ! mem(1374) + d=123456 -- ! mem(1376) +wal 006470 -- check stored values +brm 3 + d=000101 -- ! mem(6470) (1st param) + d=000102 -- ! mem(6472) (2nd param) + d=000103 -- ! mem(6474) (3rd param) +# +# probably first and last time MARK is used. It's a bastard anyway. +# +#----------------------------------------------------------------------------- +C Setup code 25 [base 6500; use 65-66] (basic byte instruction and cc test) +# +wal 006500 -- code: +bwm 22 + 110124 -- movb r1,(r4)+ (#123, #333) + 120124 -- cmpb r1,(r4)+ (#123, #333) + 120224 -- cmpb r2,(r4)+ (#321, #111) + 120124 -- cmpb r1,(r4)+ (#123, #123) + 105024 -- clrb (r4)+ (#333) + 130124 -- bitb r1,(r4)+ (#123, #11) + 130124 -- bitb r1,(r4)+ (#123, #44) + 140124 -- bicb r1,(r4)+ (#123, #333) +#6520 + 150124 -- bisb r1,(r4)+ (#123, #111) + 105124 -- comb (r4)+ (#321) + 105224 -- incb (r4)+ (#321) + 105324 -- decb (r4)+ (#321) + 105424 -- negb (r4)+ (#321) + 105724 -- tstb (r4)+ (#321) + 106024 -- rorb (r4)+ (#201) Cin=0; Cout=1 + 106024 -- rorb (r4)+ (#021) Cin=1; Cout=1 +#6540 + 106124 -- rolb (r4)+ (#210) Cin=1; Cout=1 + 106224 -- asrb (r4)+ (#020) + 106224 -- asrb (r4)+ (#220) + 106324 -- aslb (r4)+ (#020) + 106324 -- aslb (r4)+ (#220) + 000000 -- halt +# +wal 000014 -- vector: 14 +bwm 2 + 006560 -- PC:6560 + 000000 -- PS:0 +# +wal 006560 -- code: (trap 14): +bwm 3 + 016625 -- mov 2(sp),(r5)+ + 000002 + 000006 -- rtt +# +wal 006600 -- data 1: +bwm 11 + 155733 -- (#333,#333) + 051511 -- (#123,#111) + 044333 -- (#11 ,#333) + 155444 -- (#333,#44) + 150511 -- (#321,#111) + 150721 -- (#321,#321) + 150721 -- (#321,#321) + 010601 -- (#021,#201) +#6620 + 010210 -- (#020,#210) + 010220 -- (#020,#220) + 000220 -- (....,#220) +# +C Exec code 25 (basic byte instruction and cc test) +# +wr1 000123 -- r1=123 +wr2 000321 -- r2=321 +wr4 006600 -- r4=6600 +wr5 006626 -- r5=6626 +wsp 001374 -- sp=1374 +wal 001374 -- setup stack with rtt return frame setting T flag +bwm 2 + 006500 -- start address (code 25 @ 6500) + 000020 -- set T flag in PSW +stapc 006564 -- start @ 6564 -> rtt -> 6500 from stack +wtgo +rr1 d=000123 -- ! r1=123 +rr2 d=000321 -- ! r2=321 +rr4 d=006625 -- ! r4=6625 +rr5 d=006700 -- ! r5=6700 +rsp d=001400 -- ! sp=1400 +rpc d=006554 -- ! pc=6554 +wal 006600 +brm 11 + d=155523 -- ! mem(6600)=123; movb r1,(r4)+ (#123, #333) +# ! mem(6601)=333; cmpb r1,(r4)+ (#123, #333) + d=051511 -- ! mem(6602)=111; cmpb r1,(r4)+ (#321, #111) +# ! mem(6603)=123; cmpb r1,(r4)+ (#123, #123) + d=044000 -- ! mem(6604)=000; clrb (r4)+ (#333) +# ! mem(6605)=011; bitb r1,(r4)+ (#123, #11) + d=104044 -- ! mem(6606)=044; bitb r1,(r4)+ (#123, #44) +# ! mem(6607)=210; bicb r1,(r4)+ (#123, #333) + d=027133 -- ! mem(6610)=133; bisb r1,(r4)+ (#123, #111) +# ! mem(6611)=056; comb (r4)+ (#321) + d=150322 -- ! mem(6612)=322; incb (r4)+ (#321) +# ! mem(6613)=320; decb (r4)+ (#321) + d=150457 -- ! mem(6614)=057; negb (r4)+ (#321) +# ! mem(6615)=321; tstb (r4)+ (#321) + d=104100 -- ! mem(6616)=100; rorb (r4)+ (#201) Cout=1 +# ! mem(6617)=210; rorb (r4)+ (#021) Cout=1 + d=004021 -- ! mem(6620)=021; rolb (r4)+ (#210) Cout=1 +# ! mem(6621)=010; asrb (r4)+ (#020) + d=020310 -- ! mem(6622)=310; asrb (r4)+ (#220) +# ! mem(6623)=040; aslb (r4)+ (#020) + d=000040 -- ! mem(6624)=040; aslb (r4)+ (#220) +# +wal 006626 -- NZVC +brm 21 + d=000020 -- ! mem(6626)=0000; movb r1,(r4)+ (#123, #333) + d=000021 -- ! mem(6630)=000C; cmpb r1,(r4)+ (#123, #333) + d=000030 -- ! mem(6632)=N000; cmpb r1,(r4)+ (#321, #111) + d=000024 -- ! mem(6634)=0Z00; cmpb r1,(r4)+ (#123, #123) + d=000024 -- ! mem(6636)=0Z00; clrb (r4)+ (#333) + d=000020 -- ! mem(6640)=0000; bitb r1,(r4)+ (#123, #11) + d=000024 -- ! mem(6642)=0Z00; bitb r1,(r4)+ (#123, #44) + d=000030 -- ! mem(6644)=N000; bicb r1,(r4)+ (#123, #333) + d=000020 -- ! mem(6646)=0000; bisb r1,(r4)+ (#123, #111) + d=000021 -- ! mem(6650)=000C; comb (r4)+ (#321) + d=000031 -- ! mem(6652)=N00C; incb (r4)+ (#321) keep C! + d=000031 -- ! mem(6654)=N00C; decb (r4)+ (#321) keep C! + d=000021 -- ! mem(6656)=000C; negb (r4)+ (#321) + d=000030 -- ! mem(6660)=N000; tstb (r4)+ (#321) + d=000023 -- ! mem(6662)=00VC; rorb (r4)+ (#201) + d=000031 -- ! mem(6664)=N00C; rorb (r4)+ (#021) + d=000023 -- ! mem(6666)=00VC; rolb (r4)+ (#210) + d=000020 -- ! mem(6670)=0000; asrb (r4)+ (#020) + d=000032 -- ! mem(6672)=N0V0; asrb (r4)+ (#220) + d=000020 -- ! mem(6674)=0000; aslb (r4)+ (#020) + d=000023 -- ! mem(6676)=00VC; aslb (r4)+ (#220) +# +rst -- console reset (to clear T flag) +wal 000014 -- vector: 14 -> trap catcher again +bwm 2 + 000016 -- PC:16 + 000000 -- PS:0 +#----------------------------------------------------------------------------- +C Setup code 26 [base 6700; use 67-70] (address modes torture tests) +# +wal 006700 -- code test 1: +bwm 5 + 012020 -- mov (r0)+,(r0)+ + 062020 -- add (r0)+,(r0)+ + 014141 -- mov -(r1),-(r1) + 064141 -- add -(r1),-(r1) +#6710 + 000000 -- halt +#----- +wal 006720 -- code test 2: +bwm 8 + 016767 -- mov a(pc),b(pc) + 000014 -- here pc=6724, target@6740 --> index=14 + 000014 -- here pc=6726, target@6742 --> index=14 + 066767 -- add c(pc),d(pc) +#6730 + 000012 -- here pc=6732, target@6744 --> index=12 + 000012 -- here pc=6734, target@6746 --> index=12 + 000000 -- halt + 000000 -- halt +# +wal 006740 -- data (pc relative) for test 2: +bwm 4 + 006740 -- target for mov a(pc) + 006742 -- target for ,b(pc) + 000011 -- target for add c(pc) + 006746 -- target for ,d(pc) +#----- +wal 006750 -- code test 3: +bwm 12 + 012727 -- mov #1,#0 + 000001 + 000000 + 062727 -- add #1,#2 +#6760 + 000001 + 000002 + 016767 -- mov -14(pc),2(pc) + 177764 -- pc here: 6770: read dst of mov #1,#0 (@6754) + 000002 -- pc here: 6772: write src of add #0,r0 (@6774) + 062700 -- add #0,r0 + 000000 + 000000 -- halt +#----- +wal 007000 -- code test 4: +bwm 8 + 005200 -- inc r0 + 010001 -- mov r0,r1 + 010702 -- mov pc,r2 + 005007 -- clr pc + 000000 -- halt + 000000 -- halt + 005203 -- L1: inc r3 + 000000 -- halt +#----- +wal 000000 -- code test 4 (handler at address=0): +bwm 2 + 000137 -- jmp @#L1 + 007014 +#----- +wal 007020 -- code test 5: +bwm 11 + 012707 -- mov #L2,pc + 007032 + 000000 -- halt + 000000 -- halt + 000000 -- halt + 062707 -- L2: add #2,pc + 000002 + 005201 -- inc r1 +#7040 + 005201 -- inc r1 + 005201 -- inc r1 + 000000 -- halt +#----- +wal 007060 -- data for test 1 (r0)+ part: +bwm 4 + 000111 + 000222 + 000333 + 000444 +wal 007070 -- data for test 1 -(r1) part: +bwm 4 + 000111 + 000222 + 000333 + 000444 +C Exec code 26 (address modes torture tests) +C Exec test 26.1 (test src-dst update hazards with (r0)+,(r0)+ ect): +# +wr0 007060 -- r0=7060 (input data for (r0)+...) +wr1 007100 -- r1=7100 (input data for -(r1)...) +wsp 001400 -- sp=1400 +stapc 006700 -- start @ 6700 +wtgo +rr0 d=007070 -- ! r0 +rr1 d=007070 -- ! r1 +rpc d=006712 -- ! pc +wal 007060 -- +brm 4 + d=000111 -- ! mem(7060) + d=000111 -- ! mem(7062) + d=000333 -- ! mem(7064) + d=000777 -- ! mem(7066) +wal 007070 -- +brm 4 + d=000333 -- ! mem(7070) + d=000222 -- ! mem(7072) + d=000444 -- ! mem(7074) + d=000444 -- ! mem(7076) +C Exec test 26.2 (test indexed mode with pc (mode 67)): +# +wsp 001400 -- sp=1400 +stapc 006720 -- start @ 6720 +wtgo +rpc d=006736 -- ! pc +wal 006740 -- +brm 4 + d=006740 -- ! mem(6740) + d=006740 -- ! mem(6742) + d=000011 -- ! mem(6744) + d=006757 -- ! mem(6746) +C Exec test 26.3 (test (pc)+ as dst): +# +wr0 000111 -- r0=0111 +wsp 001400 -- sp=1400 +stapc 006750 -- start @ 6750 +wtgo +rr0 d=000112 -- ! r0 +rpc d=007000 -- ! pc +wal 006752 -- +brm 2 + d=000001 -- ! mem(6752) src mov #1,#0 + d=000001 -- ! mem(6754) dst mov #1,#0 +wal 006760 -- +brm 2 + d=000001 -- ! mem(6760) src add #1,#2 + d=000003 -- ! mem(6762) dst add #1,#2 +wal 006774 -- ! +rmi d=000001 -- ! mem(6774) dst mov -12(pc),2(pc) +C Exec test 26.4 (test pc as dst in clr): +# +wr0 000100 -- r0=0100 +wr1 000110 -- r1=0110 +wr2 000120 -- r2=0120 +wr3 000130 -- r3=0130 +wsp 001400 -- sp=1400 +stapc 007000 -- start @ 7000 +wtgo +rr0 d=000101 -- ! r0 +rr1 d=000101 -- ! r1 +rr2 d=007006 -- ! r2 (pc after mov pc,r2) +rr3 d=000131 -- ! r3 +rpc d=007020 -- ! pc +# cleanup 'vector 0': +wal 000000 +bwm 2 + 000000 + 000000 +C Exec test 26.5 (test pc as dst in mov and add): +# +wr1 000000 -- r1=0 +wsp 001400 -- sp=1400 +stapc 007020 -- start @ 7020 +wtgo +rr1 d=000002 -- ! r1 +rpc d=007046 -- ! pc +#----------------------------------------------------------------------------- +C Setup code 27 [base 7100; use 71-101] (test ASH/ASHC instruction) +# +wal 007100 -- code test 1 (ash) +bwm 7 + 000230 -- spl 0 + 012004 -- L1: mov (r0)+,r4 -- load low + 072420 -- ash (r0)+,r4 -- shift + 011321 -- mov (r3),(r1)+ -- store psw + 010421 -- mov r4,(r1)+ -- store low + 077205 -- sob r2,L1 (.-5) + 000000 -- halt +#----- +wal 007120 -- code test 2 (ashc even) +bwm 9 + 000230 -- spl 0 + 012004 -- L1: mov (r0)+,r4 -- load high + 012005 -- mov (r0)+,r5 -- load low + 073420 -- ashc (r0)+,r4 -- shift + 011321 -- mov (r3),(r1)+ -- store psw + 010421 -- mov r4,(r1)+ -- store high + 010521 -- mov r5,(r1)+ -- store low + 077207 -- sob r2,L1 (.-7) +#7140 + 000000 -- halt +#----- +wal 007150 -- code test 3 (ashc odd) +bwm 7 + 000230 -- spl 0 + 012005 -- L1: mov (r0)+,r5 -- load low + 073520 -- ashc (r0)+,r5 -- shift + 011321 -- mov (r3),(r1)+ -- store psw +#7160 + 010521 -- mov r5,(r1)+ -- store low + 077205 -- sob r2,L1 (.-5) + 000000 -- halt +#----- +wal 007200 -- data 1: +bwm 24 + 000200 -- (000200, +1) + 000001 -- + 000200 -- (000200, -1) + 177777 -- + 000200 -- (000200, +7) + 000007 -- + 000200 -- (000200, +8) + 000010 -- +#7220 + 000200 -- (000200, +9) + 000011 -- + 000200 -- (000200, -7) + 177771 -- + 100000 -- (100000, 0) + 000000 -- + 000000 -- (000000, 0) + 000000 -- +#7240 + 000200 -- (000200, -8) + 177770 -- + 000200 -- (000200, 0) + 000000 -- + 100000 -- (100000, -6) + 177772 -- + 040000 -- (040000, +1) + 000001 -- +#----- +wal 007300 -- data 2: +bwm 30 + 000020 -- (000020,000200, +1) + 000200 -- + 000001 -- + 000020 -- (000020,000200, -1) + 000200 -- + 177777 -- + 000020 -- (000020,000200, +7) + 000200 -- +#7320 + 000007 -- + 000020 -- (000020,000200, +8) + 000200 -- + 000010 -- + 000020 -- (000020,000200, +9) + 000200 -- + 000011 -- + 000000 -- (000000,000200, +23) +#7340 + 000200 -- + 000027 -- + 000000 -- (000000,000200, +24) + 000200 -- + 000030 -- + 000000 -- (000000,000200, +25) + 000200 -- + 000031 -- +#7360 + 000020 -- (000020,000200, -5) + 000200 -- + 177773 -- + 000020 -- (000020,000200, -8) + 000200 -- + 177770 -- +#----- +wal 007440 -- data 3: +bwm 6 + 000200 -- (000200, +1) + 000001 -- + 000200 -- (000200, -1) + 177777 -- + 000201 -- (000201, -1) + 177777 -- +# +C Exec code 27 (test ASH/ASHC instruction) +C Exec test 27.1 (test ash) +# +wr0 007200 -- r0=7200 (input data) +wr1 007500 -- r1=7500 (output data) +wr2 000014 -- r2=14 (test count) +wr3 177776 -- r3=177776 (#PSW) +wsp 001400 -- sp=1400 +stapc 007100 -- start @ 7100 +wtgo +rr0 d=007260 -- ! r0 +rr1 d=007560 -- ! r1 +rpc d=007116 -- ! pc +wal 007500 -- +brm 24 + d=000000 -- ! mem(7500) ash +1, 000200 -> nzvc=0 + d=000400 -- ! mem(7502) + d=000000 -- ! mem(7504) ash -1, 000200 -> nzvc=0 + d=000100 -- ! mem(7506) + d=000000 -- ! mem(7510) ash +7, 000200 -> nzvc=0 + d=040000 -- ! mem(7512) + d=000012 -- ! mem(7514) ash +8, 000200 -> n1,z0,v1,c0 + d=100000 -- ! mem(7516) + d=000007 -- ! mem(7520) ash +9, 000200 -> n0,z1,v1,c1 + d=000000 -- ! mem(7522) + d=000000 -- ! mem(7524) ash -7, 000200 -> nzvc=0 + d=000001 -- ! mem(7526) + d=000010 -- ! mem(7530) ash 0, 100000 -> n1,z0,v0,c0 + d=100000 -- ! mem(7532) + d=000004 -- ! mem(7534) ash 0, 000000 -> n0,z1,v0,c0 + d=000000 -- ! mem(7536) + d=000005 -- ! mem(7540) ash -8, 000200 -> n1,z1,v0,c1 + d=000000 -- ! mem(7542) + d=000000 -- ! mem(7544) ash 0, 000200 -> n0,z0,v0,c0 + d=000200 -- ! mem(7546) + d=000010 -- ! mem(7550) ash -6, 100000 -> n1,z0,v0,c0 + d=177000 -- ! mem(7552) + d=000012 -- ! mem(7554) ash +1, 040000 -> n1,z0,v1,c0 + d=100000 -- ! mem(7556) +#---- +C Exec test 27.2 (test ashc even) +# +wr0 007300 -- r0=7300 (input data) +wr1 007600 -- r1=7600 (output data) +wr2 000012 -- r2=12 (test count) +wr3 177776 -- r3=177776 (#PSW) +wsp 001400 -- sp=1400 +stapc 007120 -- start @ 7120 +wtgo +rr0 d=007374 -- ! r0 +rr1 d=007674 -- ! r1 +rpc d=007142 -- ! pc +wal 007600 -- +brm 30 + d=000000 -- ! mem(7600) ashc +1, 000020,000200 -> nzvc=0 + d=000040 -- ! mem(7602) + d=000400 -- ! mem(7604) + d=000000 -- ! mem(7606) ashc -1, 000020,000200 -> nzvc=0 + d=000010 -- ! mem(7610) + d=000100 -- ! mem(7612) + d=000000 -- ! mem(7614) ashc +7, 000020,000200 -> nzvc=0 + d=004000 -- ! mem(7616) + d=040000 -- ! mem(7620) + d=000000 -- ! mem(7622) ashc +8, 000020,000200 -> nzvc=0 + d=010000 -- ! mem(7624) + d=100000 -- ! mem(7626) + d=000000 -- ! mem(7630) ashc +9, 000020,000200 -> nzvc=0 + d=020001 -- ! mem(7632) + d=000000 -- ! mem(7634) + d=000000 -- ! mem(7636) ashc +23, 000000,000200 -> nzvc=0 + d=040000 -- ! mem(7640) + d=000000 -- ! mem(7642) + d=000012 -- ! mem(7644) ashc +24, 000000,000200 -> n1z0v1c0 + d=100000 -- ! mem(7646) + d=000000 -- ! mem(7650) + d=000007 -- ! mem(7652) ashc +25, 000000,000200 -> n0z1v1c1 + d=000000 -- ! mem(7654) + d=000000 -- ! mem(7656) + d=000000 -- ! mem(7660) ashc -5, 000020,000200 -> nzvc=0 + d=000000 -- ! mem(7662) + d=100004 -- ! mem(7664) + d=000001 -- ! mem(7666) ashc -8, 000020,000200 -> n0z0v0c1 + d=000000 -- ! mem(7670) + d=010000 -- ! mem(7672) +#---- +C Exec test 27.3 (test ashc odd) +# +wr0 007440 -- r0=7440 (input data) +wr1 007740 -- r1=7740 (output data) +wr2 000003 -- r2=3 (test count) +wr3 177776 -- r3=177776 (#PSW) +wsp 001400 -- sp=1400 +stapc 007150 -- start @ 7150 +wtgo +rr0 d=007454 -- ! r0 +rr1 d=007754 -- ! r1 +rpc d=007166 -- ! pc +wal 007740 -- +brm 6 + d=000000 -- ! mem(7740) ashc +1, 000200 -> nzvc=0 + d=000400 -- ! mem(7742) + d=000000 -- ! mem(7744) ashc -1, 000200 -> nzvc=0 + d=000100 -- ! mem(7746) + d=000001 -- ! mem(7750) ashc -1, 000201 -> n0z0v0c1 + d=100100 -- ! mem(7752) +#----------------------------------------------------------------------------- +C Setup code 30 [base 10200; use 102-103] (test MUL instruction) +# +wal 010200 -- code test 1 (mul even) +bwm 8 + 000230 -- spl 0 + 012004 -- L1: mov (r0)+,r4 -- load p1 + 070420 -- mul (r0)+,r4 -- mul + 011321 -- mov (r3),(r1)+ -- store psw + 010421 -- mov r4,(r1)+ -- store p_high + 010521 -- mov r5,(r1)+ -- store p_low + 077206 -- sob r2,L1 (.-6) + 000000 -- halt +#----- +wal 010220 -- code test 2 (mul odd) +bwm 7 + 000230 -- spl 0 + 012005 -- L1: mov (r0)+,r5 -- load p1 + 070520 -- mul (r0)+,r5 -- mul + 010521 -- mov r5,(r1)+ -- store p_low + 060403 -- add r4,r3 -- check r4 + 077205 -- sob r2,L1 (.-5) + 000000 -- halt +# +# 31022 074456 * 9562 022532 -> 296632364 010656,040054 +# 18494 044076 * -24041 121027 -> -444614254 162577,134622 +# -12549 147373 * 2397 004535 -> -30079953 177065,002057 +# -20493 127763 * -23858 121316 -> 488921994 016444,055612 +# +# 105 000151 * 198 000306 -> 20790 000000,050466 +# 233 000351 * -94 177642 -> -21902 177777,125162 +# 186 000272 * -205 177463 -> -38130 177777,065416 +# +wal 010240 -- data 1: +bwm 16 + 074456 -- + 022532 -- + 044076 -- + 121027 -- + 147373 -- + 004535 -- + 127763 -- + 121316 -- +#10260 + 000151 -- + 000306 -- + 000351 -- + 177642 -- + 000272 -- + 177463 -- + 000000 -- + 000272 -- +# +C Exec code 30 (test MUL instruction) +C Exec test 30.1 (test mul even) +# +wr0 010240 -- r0=10240 (input data) +wr1 010300 -- r1=10300 (output data) +wr2 000010 -- r2=10 (test count) +wr3 177776 -- r3=177776 (#PSW) +wsp 001400 -- sp=1400 +stapc 010200 -- start @ 10200 +wtgo +rr0 d=010300 -- ! r0 +rr1 d=010360 -- ! r1 +rpc d=010220 -- ! pc +wal 010300 -- +brm 24 + d=000001 -- ! mem(10300) mul 074456,022532 -> n0z0v0c1 + d=010656 -- ! mem(10302) + d=040054 -- ! mem(10304) + d=000011 -- ! mem(10306) mul 044076,121027 -> n1z0v0c1 + d=162577 -- ! mem(10310) + d=134622 -- ! mem(10312) + d=000011 -- ! mem(10314) mul 147373,004535 -> n1z0v0c1 + d=177065 -- ! mem(10316) + d=002057 -- ! mem(10320) + d=000001 -- ! mem(10322) mul 127763,121316 -> n0z0v0c1 + d=016444 -- ! mem(10324) + d=055612 -- ! mem(10326) + d=000000 -- ! mem(10330) mul 000151,000306 -> n0z0v0c0 + d=000000 -- ! mem(10332) + d=050466 -- ! mem(10334) + d=000010 -- ! mem(10336) mul 000351,177642 -> n1z0v0c0 + d=177777 -- ! mem(10340) + d=125162 -- ! mem(10342) + d=000011 -- ! mem(10344) mul 000272,177463 -> n1z0v0c1 + d=177777 -- ! mem(10346) + d=065416 -- ! mem(10350) + d=000004 -- ! mem(10352) mul 000000,000272 -> n0z1v0c0 + d=000000 -- ! mem(10354) + d=000000 -- ! mem(10356) +#---- +C Exec test 30.2 (test mul odd) +# +wr0 010240 -- r0=10240 (input data) +wr1 010360 -- r1=10300 (output data) +wr2 000010 -- r2=10 (test count) +wr3 000000 -- r3=0 +wr4 000000 -- r4=0 +wsp 001400 -- sp=1400 +stapc 010220 -- start @ 10220 +wtgo +rr0 d=010300 -- ! r0 +rr1 d=010400 -- ! r1 +rr3 d=000000 -- ! r3 +rpc d=010236 -- ! pc +wal 010360 -- +brm 8 + d=040054 -- ! mem(10360) + d=134622 -- ! mem(10362) + d=002057 -- ! mem(10364) + d=055612 -- ! mem(10366) + d=050466 -- ! mem(10370) + d=125162 -- ! mem(10372) + d=065416 -- ! mem(10374) + d=000000 -- ! mem(10376) +# +#----------------------------------------------------------------------------- +C Setup code 31 [base 10400; use 104-110] (test DIV instruction, also ADC,SXT) +# Note: test 2 uses sbc too, but if div/div work correctly we have always +# C=0 for sbc, so sbc isn't tested. adc has C=0 or C=1 though. +# +wal 010400 -- code test 1 +bwm 8 + 012004 -- L1: mov (r0)+,r4 -- load dd high + 012005 -- mov (r0)+,r5 -- load dd low + 071420 -- div (r0)+,r4 -- div + 011321 -- mov (r3),(r1)+ -- store psw + 010421 -- mov r4,(r1)+ -- store q + 010521 -- mov r5,(r1)+ -- store r + 077207 -- sob r2,L1 (.-7) + 000000 -- halt +#----- +wal 010420 -- code test 2 +bwm 24 + 012146 -- L1: mov (r1)+,-(sp) -- save psw on stack + 016002 -- mov 4(r0),r2 -- load divisor + 000004 + 070221 -- mul (r1)+,r2 -- multiply with quotient + 061103 -- add (r1),r3 -- add reminder + 005502 -- adc r2 + 005721 -- tst (r1)+ + 006704 -- sxt r4 +#10440 + 060402 -- add r4,r2 + 166003 -- sub 2(r0),r3 -- subtract divident + 000002 + 005602 -- sbc r2 + 161002 -- sub (r0),r2 + 001002 -- bne L2 (.+2) -- error if !=0 + 005703 -- tst r3 + 001404 -- beq L3 (.+4) -- error if !=0 +#10460 + 032726 -- L2: bit #3,(sp)+ -- check V,C bits + 000003 + 001001 -- bne L3 (.+1) -- if V or C =1, ignore + 000000 -- halt + 062700 -- L3: add #6,r0 -- + 000006 -- + 077527 -- sob r5,L1 (.-23) + 000000 -- halt +# r q +# 6249 014151 * 9158 021706 + 4989 011575 -> 57233331 001551,047663 y n +# 5194 012112 * -23807 121401 + -3990 170152 -> -123657548 174241,021264 n y +# -19943 131031 * 27112 064750 + -16037 140533 -> -540710653 157705,064403 y n +# -20493 127763 * -23858 121316 + 10744 024770 -> 488932738 016444,102602 y y +# +# -12549 147373 * 2397 004535 + -11187 152115 -> -30091140 177064,154174 n n +# 22620 054134 * -9272 155710 + -19907 131075 -> -209752547 171577,067035 y y +# 10723 024743 * 7931 017373 + 9824 023140 -> 85053937 002421,150761 n n +# -3548 171044 * -15677 141303 + 3019 005713 -> 55625015 001520,142467 n y +# +## 1 000001 * -32767 100001 + 0 000000 -> -32767 177777,100001 V=0 +## -1 177777 * 32767 077777 + 0 000000 -> -32767 177777,100001 V=0 +# 1 000001 * -32768 100000 + 0 000000 -> -32768 177777,100000 V=1 +# -1 177777 * ...... ...... + 0 000000 -> -32768 177777,100000 V=1 +# +# 32767 077777 * 32767 077777 + 32766 077776 -> 1073709055 037777,077777 V=0 +# 32767 077777 * ............ + ............ -> 1073709056 037777,100000 V=1 +# 32767 077777 * -32767 100001 + -32766 100002 ->-1073709055 140000,100001 V=0 +# 32767 077777 * ............ + ............ ->-1073709056 140000,100000 V=1 +# +# 32767 077777 * ............ + ............ -> 1073741824 040000,000000 V=1 +##32767 077777 * ............ + ............ ->-2147483648 100000,000000 V=1 +# +# +wal 010500 -- data 1: +bwm 63 + 000000 -- (000000,000042, 000005) 34/ 5 -> q: 6 r: 4 + 000042 -- + 000005 -- + 000000 -- (000000,000042, 177773) 34/-5 -> q:-6 r: 4 + 000042 -- + 177773 -- + 177777 -- (177777,177736, 000005) -34/ 5 -> q:-6 r:-4 + 177736 -- +#010520 + 000005 -- + 177777 -- (177777,177736, 177773) -34/-5 -> q: 6 r:-4 + 177736 -- + 177773 -- + 001551 -- (001551,047663, 014151) 57233331 / 6249 + 047663 -- -> q: 9158 r: 4989 + 014151 -- + 174241 -- (174241,021264, 012112) -123657548 / 5194 +#010540 + 021264 -- -> q: -23807 r: -3990 + 012112 -- + 157705 -- (157705,064403, 131031) -540710653 / -19943 + 064403 -- -> q: 27112 r: -16037 + 131031 -- + 016444 -- (016444,102602, 127763) 488932738 / -20493 + 102602 -- -> q: -23858 r: 10744 + 127763 -- +#010560 + 177064 -- (177064,154174, 147373) -30091140 / -12549 + 154174 -- -> q: 2397 r: -11187 + 147373 -- + 171577 -- (171577,067035, 054134) -209752547 / 22620 + 067035 -- -> q: -9272 r: -19907 + 054134 -- + 002421 -- (002421,150761, 024743) 85053937 / 10723 + 150761 -- -> q: 7931 r: 9824 +#010600 + 024743 -- + 001520 -- (001520,142467, 171044) 55625015 / -3548 + 142467 -- -> q: -15677 r: 3019 + 171044 -- + 001520 -- (001520,142467,000000) 55625015 / 0 + 142467 -- + 000000 -- + 000000 -- (000000,000000,021706) 0 / 9158 +#010620 + 000000 -- + 021706 -- + 177777 -- (177777,100000,000001) -32768 / 1 + 100000 -- + 000001 -- + 177777 -- (177777,100000,177777) -32768 / -1 + 100000 -- + 177777 -- +#010640 + 037777 -- (037777,077777,077777) 1073709055 / 32767 + 077777 -- + 077777 -- + 037777 -- (037777,100000,077777) 1073709056 / 32767 + 100000 -- + 077777 -- + 140000 -- (140000,100001,077777) -1073709055 / 32767 + 100001 -- +#010660 + 077777 -- + 140000 -- (140000,100000,077777) -1073709056 / 32767 + 100000 -- + 077777 -- + 040000 -- (040000,000000,077777) 1073741824 / 32767 + 000000 -- + 077777 -- +# +C Exec code 31 (test DIV instruction, also ADC,SXT) +C Exec test 31.1 (test div) +# +wr0 010500 -- r0=10500 (input data) +wr1 010700 -- r1=10700 (output data) +wr2 000025 -- r2=25 (test count) +wr3 177776 -- r3=177776 (#PSW) +wsp 001400 -- sp=1400 +rst -- console reset ; do reset; cont to start with +wps 000000 -- clear psw ; psw cc code dump below +wpc 010400 -- pc=10400 +cont -- cont @ 10400 +wtgo +rr0 d=010676 -- ! r0 +rr1 d=011076 -- ! r1 +rpc d=010420 -- ! pc +wal 010700 -- +brm 63 + d=000000 -- ! mem(10700) div 000000, 000042,000005 -> n0z0v0c0 + d=000006 -- ! mem(10702) 34/ 5 -> 6,4 + d=000004 -- ! mem(10704) + d=000010 -- ! mem(10706) div 000000,000042, 177773 -> n1z0v0c0 + d=177772 -- ! mem(10710) 34/-5 -> -6,4 + d=000004 -- ! mem(10712) + d=000010 -- ! mem(10714) div 177777,177736, 000005 -> n1z0v0c0 + d=177772 -- ! mem(10716) -34/ 5 -> -6,-4 + d=177774 -- ! mem(10720) + d=000000 -- ! mem(10722) div 177777,177736, 177773 -> n0z0v0c0 + d=000006 -- ! mem(10724) -34/-5 -> 6,-4 + d=177774 -- ! mem(10726) + d=000000 -- ! mem(10730) div 001551,047663, 014151 -> n0z0v0c0 + d=021706 -- ! mem(10732) 57233331/6249 -> 9158,4989 + d=011575 -- ! mem(10734) + d=000010 -- ! mem(10736) div 174241,021264, 012112 -> n1z0v0c0 + d=121401 -- ! mem(10740) -123657548/5194 -> -23807,-3990 + d=170152 -- ! mem(10742) + d=000000 -- ! mem(10744) div 157705,064403, 131031 -> n0z0v0c0 + d=064750 -- ! mem(10746) -540710653/-19943 -> 27112,-16037 + d=140533 -- ! mem(10750) + d=000010 -- ! mem(10752) div 016444,102602, 127763 -> n1z0v0c0 + d=121316 -- ! mem(10754) 488932738/-20493 -> -23858, 10744 + d=024770 -- ! mem(10756) + d=000000 -- ! mem(10760) div 177064,154174, 147373 -> n0z0v0c0 + d=004535 -- ! mem(10762) -30091140/-12549 -> 2397,-11187 + d=152115 -- ! mem(10764) + d=000010 -- ! mem(10766) div 171577,067035, 054134 -> n1z0v0c0 + d=155710 -- ! mem(10770) -209752547/22620 -> -9272,-19907 + d=131075 -- ! mem(10772) + d=000000 -- ! mem(10774) div 002421,150761, 024743 -> n0z0v0c0 + d=017373 -- ! mem(10776) 85053937/10723 -> 7931,9824 + d=023140 -- ! mem(11000) + d=000010 -- ! mem(11002) div 001520,142467, 171044 -> n1z0v0c0 + d=141303 -- ! mem(11004) 55625015/-3548 -> -15677,3019 + d=005713 -- ! mem(11006) + d=000007 -- ! mem(11010) div 001520,142467,000000 -> n0z1v1c1 + d=001520 -- ! mem(11012) 55625015/0 -> V=1, keep regs + d=142467 -- ! mem(11014) + d=000004 -- ! mem(11016) div 000000,000000,021706 -> n0z1v1c0 + d=000000 -- ! mem(11020) 0/9158 -> 0,0 + d=000000 -- ! mem(11022) + d=000012 -- ! mem(11024) div 177777,100000,000001->n1z0v1c0 [[s:10]] + d=177777 -- ! mem(11026) -32768/1 -> overflow [[s:100000]] + d=100000 -- ! mem(11030) [[s:000000]] + d=000002 -- ! mem(11032) div 177777,100000,177777 -> n0z0v1c0 ?? 2 + d=177777 -- ! mem(11034) -32768/-1 -> overflow + d=100000 -- ! mem(11036) + d=000000 -- ! mem(11040) div 037777,077777,077777 -> n0z0v0c0 + d=077777 -- ! mem(11042) 1073709055/32767 -> 32767,32766 + d=077776 -- ! mem(11044) + d=000002 -- ! mem(11046) div 037777,100000,077777 -> n0z0v1c0 + d=037777 -- ! mem(11050) 1073709056/32767 -> overflow + d=100000 -- ! mem(11052) + d=000010 -- ! mem(11054) div 140000,100001,077777 -> n1z0v0c0 + d=100001 -- ! mem(11056) -1073709055/32767 -> -32767,-32766 + d=100002 -- ! mem(11060) + d=000012 -- ! mem(11062) div 140000,100000,077777->n1z0v1c0 [[s:10]] + d=140000 -- ! mem(11064) -1073709056/32767 -> overflow [[s:100000]] + d=100000 -- ! mem(11066) [[s:000000]] + d=000002 -- ! mem(11070) div 040000,000000,077777 -> n0z0v1c0 + d=040000 -- ! mem(11072) 1073741824/32767 -> overflow + d=000000 -- ! mem(11074) +# +# simh notes: +# 1. a quotient of 100000 leads to an overflow (V=1) on the W11 +# simh will not indicate overflow and returns q=100000 +# +#---- +C Exec test 31.2 (test mul after div) +# +wr0 010500 -- r0=10500 (input data from DIV) +wr1 010700 -- r1=10700 (output data from DIV) +wr5 000016 -- r5=16 (test count) +wsp 001400 -- sp=1400 +stapc 010420 -- start @ 10420 +wtgo +rr0 d=010624 -- ! r0 +rr1 d=011024 -- ! r1 +rr2 d=000000 -- ! r2 +rr3 d=000000 -- ! r3 +rr5 d=000000 -- ! r5 +rpc d=010500 -- ! pc +#----------------------------------------------------------------------------- +C Setup code 32 [base 11100; use 111-112] (PIRQ test) +# The code will exercise all 7 pirq interrupt levels: +# set 1+3 -> handle 3, set 7 -> handle 7, set 6+4 -> handle 6 +# -> handle 4, set 5+2 -> handle 5 -> handle 2 > handle 1 +# +wal 011100 -- code: +bwm 14 + 000237 -- spl 7 + 011425 -- mov (r4),(r5)+ ; save PSW + 012713 -- mov #1000,(r3) ; set PIRQ 1 + 001000 + 011325 -- mov (r3),(r5)+ ; save PIRQ + 112763 -- movb #12,1(r3) ; set PIRQ 1+3 + 000012 + 000001 +#11120 + 011325 -- mov (r3),(r5)+ ; save PIRQ + 000232 -- spl 2 ; now pri=2 + 000240 -- nop ; allow interrupt to happen + 000230 -- spl 0 ; now pri=0 +#11130 + 000240 -- nop ; allow interrupt to happen + 000000 -- halt +#----- +wal 000240 -- vector: 240 +bwm 2 + 011134 -- PC:11134 + 000340 -- PS:pri=7 +#----- +wal 011134 -- code: (vector 240) +bwm 18 + 011300 -- mov (r3),r0 ; get pirq + 010625 -- mov sp,(r5)+ ; save sp +#11140 + 010025 -- mov r0,(r5)+ ; save pirq + 110014 -- movb r0,(r4) ; PSW=PIRQ (sets priority) + 042700 -- bic #177761,r0 ; mask out index bits + 177761 + 010001 -- mov r0,r1 ; r0 is word index (pri*2) + 006201 -- asr r1 ; r1 is byte index (pri*1) + 012702 -- mov #400,r2 + 000400 +#11160 + 072201 -- ash r1,r2 ; r2 = 1<<(pri) + 040213 -- bic r2,(r3) ; clear current level in pirq + 010246 -- mov r2,-(sp) ; save pirq level mask + 056013 -- bis 11200(r0),(r3) ; trigger new pirq's + 011200 + 000240 -- noop + 012625 -- mov (sp)+,(r5)+ ; save pirq level mask + 000002 -- rti +#11200 +#----- +wal 011200 -- data: +bwm 8 + 000000 -- mem(11200)=0 ; new pirq @ level 0 + 000000 -- mem(11202)=0 ; new pirq @ level 1 + 000000 -- mem(11204)=0 ; new pirq @ level 2 + 100000 -- mem(11206)=100000 ; new pirq @ level 3 -> 7 + 022000 -- mem(11210)=022000 ; new pirq @ level 4 -> 5+2 + 000000 -- mem(11212)=0 ; new pirq @ level 5 + 000000 -- mem(11214)=0 ; new pirq @ level 6 + 050000 -- mem(11216)=050000 ; new pirq @ level 7 -> 6+4 +# +C Exec code 32 (PIRQ test) +# +wr3 177772 -- r3=177772 (#PIRQ) +wr4 177776 -- r4=177776 (#PSW) +wr5 011220 -- r1=11220 (output data) +wsp 001400 -- sp=1400 +stapc 011100 -- start @ 11100 +wtgo +rr5 d=011300 -- ! r5 +rsp d=001400 -- ! sp +rpc d=011134 -- ! pc +rps d=000000 -- ! PSW +wal 177772 -- +rmi d=000000 -- ! PIRQ +wal 011220 -- +brm 24 + d=000340 -- ! mem(11220) PSW after SPL 7 + d=001042 -- ! mem(11222) PIRQ when 1 set + d=005146 -- ! mem(11224) PIRQ when 1+3 set + d=001374 -- ! mem(11226) -> PI:3 SP + d=005146 -- ! mem(11230) PIRQ (3+1 pending) + d=001366 -- ! mem(11232) -> PI:7 SP + d=101356 -- ! mem(11234) PIRQ (7+1 pending) + d=100000 -- ! mem(11236) <- PI:7 mask + d=001366 -- ! mem(11240) -> PI:6 SP + d=051314 -- ! mem(11242) PIRQ (6+4+1 pending) + d=040000 -- ! mem(11244) <- PI:6 mask + d=001366 -- ! mem(11246) -> PI:4 SP + d=011210 -- ! mem(11250) PIRQ (4+1 pending) + d=001360 -- ! mem(11252) -> PI:5 SP + d=023252 -- ! mem(11254) PIRQ (5+2+1 pending) + d=020000 -- ! mem(11256) <- PI:5 mask + d=010000 -- ! mem(11260) <- PI:4 mask + d=004000 -- ! mem(11262) <- PI:3 mask + d=001374 -- ! mem(11264) -> PI:2 SP + d=003104 -- ! mem(11266) PIRQ + d=002000 -- ! mem(11270) <- PI:2 mask + d=001374 -- ! mem(11272) -> PI:1 SP + d=001042 -- ! mem(11274) PIRQ + d=001000 -- ! mem(11276) <- PI:1 mask +# +wal 000240 -- vector: 240 -> trap catcher again +bwm 2 + 000242 -- PC:242 + 000000 -- PS:0 +#----------------------------------------------------------------------------- +C Setup code 33 [base 11200; use 112-113] (adc(b) and sbc(b) test) +# +wal 011200 -- code test 1: (adc) +bwm 5 + 006020 -- L1: ror (r0)+ + 005520 -- adc (r0)+ + 006120 -- rol (r0)+ + 077104 -- sob r1,L1 (.-4) + 000000 -- halt +#----- +wal 011220 -- code test 2: (sbc) +bwm 5 + 006020 -- L1: ror (r0)+ + 005620 -- sbc (r0)+ + 006120 -- rol (r0)+ + 077104 -- sob r1,L1 (.-4) + 000000 -- halt +#----- +wal 011240 -- code test 3: (adcb) +bwm 5 + 006020 -- L1: ror (r0)+ + 105520 -- adcb (r0)+ + 106120 -- rolb (r0)+ + 077104 -- sob r1,L1 (.-4) + 000000 -- halt +#----- +wal 011260 -- code test 4: (sbcb) +bwm 5 + 006020 -- L1: ror (r0)+ + 105620 -- sbcb (r0)+ + 106120 -- rolb (r0)+ + 077104 -- sob r1,L1 (.-4) + 000000 -- halt +#----- +wal 011300 -- data test 1: (adc) +bwm 9 + 000000 -- 177776 + 0 -> 177776 + 0 + 177776 + 000000 + 000001 -- 177776 + 1 -> 177777 + 0 + 177776 + 000000 + 000001 -- 177777 + 1 -> 000000 + 1 + 177777 + 000000 +#----- +wal 011324 -- data test 2: (sbc) +bwm 9 + 000000 -- 000002 - 0 -> 000002 - 0 + 000002 + 000000 + 000001 -- 000002 - 1 -> 000001 - 0 + 000002 + 000000 + 000001 -- 000000 - 1 -> 177777 - 1 + 000000 + 000000 +#----- +wal 011350 -- data test 3: (adcb) +bwm 6 + 000000 -- 376 + 0 -> 376 + 0 + 000376 + 000001 -- 376 + 1 -> 377 + 0 + 000376 + 000001 -- 377 + 1 -> 000 + 1 + 000377 +#----- +wal 011364 -- data test 4: (sbcb) +bwm 6 + 000000 -- 002 - 0 -> 002 - 0 + 000002 + 000001 -- 002 - 1 -> 001 - 0 + 000002 + 000001 -- 000 - 1 -> 337 - 1 + 000000 +# +C Exec code 33 (adc and sbc test) +C Exec test 33.1 (adc) +# +wr0 011300 -- r0=11300 +wr1 000003 -- r1=3 +wsp 001400 -- sp=1400 +stapc 011200 -- start @ 11200 +wtgo +rr0 d=011322 -- ! r0=11322 +rpc d=011212 -- ! pc +wal 011300 +brm 9 + d=000000 -- ! mem(11300)=000000 -- 177776 + 0 -> 177776 + 0 + d=177776 -- ! mem(11302)=000000 + d=000000 -- ! mem(11304)=000000 + d=000000 -- ! mem(11306)=000000 -- 177776 + 1 -> 177777 + 0 + d=177777 -- ! mem(11310)=000000 + d=000000 -- ! mem(11312)=000000 + d=000000 -- ! mem(11314)=000000 -- 177777 + 1 -> 000000 + 1 + d=000000 -- ! mem(11316)=000000 + d=000001 -- ! mem(11320)=000000 +#---- +C Exec test 33.2 (sbc) +# +wr0 011324 -- r0=11324 +wr1 000003 -- r1=3 +wsp 001400 -- sp=1400 +stapc 011220 -- start @ 11220 +wtgo +rr0 d=011346 -- ! r0=11346 +rpc d=011232 -- ! pc +wal 011324 +brm 9 + d=000000 -- ! mem(11324)=000000 -- 000002 - 0 -> 000002 - 0 + d=000002 -- ! mem(11326)=000000 + d=000000 -- ! mem(11330)=000000 + d=000000 -- ! mem(11332)=000000 -- 000002 - 1 -> 000001 - 0 + d=000001 -- ! mem(11334)=000000 + d=000000 -- ! mem(11336)=000000 + d=000000 -- ! mem(11340)=000000 -- 000000 - 1 -> 177777 - 1 + d=177777 -- ! mem(11342)=000000 + d=000001 -- ! mem(11344)=000000 +#---- +C Exec test 33.3 (adcb) +# +wr0 011350 -- r0=11350 +wr1 000003 -- r1=3 +wsp 001400 -- sp=1400 +stapc 011240 -- start @ 11240 +wtgo +rr0 d=011364 -- ! r0=11364 +rpc d=011252 -- ! pc +wal 011350 +brm 6 + d=000000 -- ! mem(11350)=000000 -- 376 + 0 -> 376 + 0 + d=000376 -- ! mem(11352)=000000 + d=000000 -- ! mem(11354)=000000 -- 376 + 1 -> 377 + 0 + d=000377 -- ! mem(11356)=000000 + d=000000 -- ! mem(11360)=000000 -- 377 + 1 -> 000 + 1 + d=000400 -- ! mem(11362)=000000 +#---- +C Exec test 33.4 (sbcb) +# +wr0 011364 -- r0=11364 +wr1 000003 -- r1=3 +wsp 001400 -- sp=1400 +stapc 011260 -- start @ 11260 +wtgo +rr0 d=011400 -- ! r0=11400 +rpc d=011272 -- ! pc +wal 011364 +brm 6 + d=000000 -- ! mem(11364)=000000 -- 002 - 0 -> 002 - 0 + d=000002 -- ! mem(11366)=000000 + d=000000 -- ! mem(11370)=000000 -- 002 - 1 -> 001 - 0 + d=000001 -- ! mem(11372)=000000 + d=000000 -- ! mem(11374)=000000 -- 000 - 1 -> 337 - 1 + d=000777 -- ! mem(11377)=000000 +#----------------------------------------------------------------------------- +C Setup code 34 [base 11400; use 114-115] (11/34 self test code) +# code adapted from M9312 23-248F1 console PROM, the 11/04-34 Diagnostic PROM +# +wal 011400 -- code: +bwm 51 + 005000 -- clr r0 ; r0=000000 c=0 + 005200 -- inc r0 ; r0=000001 c=0 + 005100 -- com r0 ; r0=177776 c=1 + 006200 -- asr r0 ; r0=177777 c=0 + 006300 -- asl r0 ; r0=177776 c=1 + 006000 -- ror r0 ; r0=177777 c=0 + 005700 -- tst r0 ; r0=177777 c=0 ?impact unclear? + 005400 -- neg r0 ; r0=000001 c=1 +#11420 + 005300 -- dec r0 ; r0=000000 c=1 + 005600 -- sbc r0 ; r0=177777 c=1 + 006100 -- rol r0 ; r0=177777 c=1 + 005500 -- adc r0 ; r0=000000 c=1 + 000300 -- swab r0 ; r0=000000 c=0 + 001401 -- beq .+1 ; + 000000 -- halt ; + 012702 -- mov #data0,r2 ; r2=011560 +#11440 + 011560 + 011203 -- mov (r2),r3 ; r2=011560 r3=011560 + 022203 -- cmp (r2)+,r3 ; r2=011562 r3=011560 + 001401 -- beq .+1 ; + 000000 -- halt ; + 063203 -- add @(r2)+,r3 ; r2=011564 r3=<2*11560> + 165203 -- sub @-(r2),r3 ; r2=011562 r3=011560 + 044203 -- bic -(r2),r3 ; r2=011560 r3=000000 +#11460 + 056203 -- bis 12(r2),r3 ; r2=011560 r3=011566 + 000012 + 037203 -- bis @12(r2),r3 ; r2=011560 r3=011566 + 000012 + 001001 -- bne .+1 ; + 000000 -- halt ; + 010701 -- mov pc,r1 ; r1=011476 + 000121 -- jmp (r1)+ ; jump 1.self 2. next; r1=011500 +#11500 + 012701 -- mov #L2,r1 ; r1=011510 + 011510 + 000131 -- jmp @(r1)+ ; r1=011512 pc=011506 + 000111 -- L1:jmp (r1) ; r1=011512 pc=011512 + 011506 -- L2:.word L1 + 105737 -- tstb data1 ; + 011564 + 001401 -- beq .+1 ; +#11520 + 000000 -- halt ; + 010204 -- mov r2,r4 ; keep r2 for later check + 022424 -- cmp (r4)+,(r4)+ ; r4=011564 + 105724 -- tstb (r4)+ ; r4=011565 (r4)+=000 + 001401 -- beq .+1 ; + 000000 -- halt ; + 105714 -- tstb (r4) ; r4=011565 (r4)=200 + 100402 -- bmi .+2 ; +#11540 + 000000 -- halt ; + 000000 -- halt ; + 000000 -- halt ; +#----- +wal 011560 -- data: +bwm 8 + 011560 -- data0: .word data0 + 011560 -- .word data0 + 100000 -- data1: .byte 000,200 + 177777 -- data2: .word 177777 + 011566 -- .word data2 + 011566 -- .word data2 + 000700 -- .word mem+0 + 000701 -- .word mem+1 +# +C Exec code 34 (11/34 self test code) +# D RE RQ FU DAT +stapc 011400 -- start @ 11400 +wtgo +rr0 d=000000 -- ! r0 +rr1 d=011512 -- ! r1 +rr2 d=011560 -- ! r2 +rr3 d=011566 -- ! r3 +rr4 d=011565 -- ! r4 +rpc d=011546 -- ! pc +#----------------------------------------------------------------------------- +C Setup code 35 [base 11600; use 116-121] (11/70 self test code) +# code adapted from M9312 23-616F1 console PROM, the 11/60-70 Diagnostic PROM +# +wal 011600 -- code: +bwm 117 + 005006 -- clr sp ; sp=000000 + 100404 -- bmi L3 ; + 102403 -- bvs L3 ; + 101002 -- bhi L3 ; + 002401 -- blt L3 ; + 101401 -- blos L4 ; + 000000 -- L3: halt ; + 005306 -- L3: dec sp ; sp=177777 +#11620 + 100003 -- bpl L5 ; + 001402 -- beq L5 ; + 002001 -- bge L5 ; + 003401 -- ble L6 ; + 000000 -- L5: halt ; + 006006 -- L6: ror sp ; sp=077777 + 102002 -- bvc L7 ; + 103001 -- bcc L7 ; +#11640 + 001001 -- bne L8 ; + 000000 -- L7: halt ; + 012706 -- L8: mov #125252,sp ; sp=125252 + 125252 + 010600 -- mov sp,r0 ; + 010001 -- mov r0,r1 ; + 010102 -- mov r1,r2 ; + 010203 -- mov r2,r3 ; +#11660 + 010304 -- mov r3,r4 ; + 010405 -- mov r4,r5 ; + 160501 -- sub r5,r1 ; r1=00000 + 002401 -- blt L9a ; + 001401 -- beq L9 ; + 000000 -- L9a: halt ; + 006102 -- L9: rol r2 ; r2=052524 c=1 + 103001 -- bcc L10 ; +#11700 + 002401 -- blt L11 ; + 000000 -- L10: halt ; + 060203 -- L11: add r2,r3 ; r3=177776 (125252+052524) + 005203 -- inc r3 ; r3=177777 + 005103 -- com r3 ; r3=000000 + 060301 -- add r3,r1 ; r1=000000 c=0 + 103401 -- bcs L12 ; + 003401 -- ble L13 ; +#11720 + 000000 -- L12: halt ; + 006004 -- L13: ror r4 ; r4=052525 + 050403 -- bis r4,r3 ; r3=052525 (r3 was 0) + 060503 -- add r5,r3 ; r3=177777 c=0 (125252+052525) + 005203 -- inc r3 ; r3=000000 c=0 (kept) + 103402 -- bcs L14 ; + 005301 -- dec r1 ; r1=177777 + 002401 -- blt L15 ; +#11740 + 000000 -- L14: halt ; + 005100 -- L15: com r0 ; r0=052525 + 101401 -- blos L16 ; + 000000 -- halt ; + 040001 -- L16: bic r0,r1 ; r1=125252 + 060101 -- L16: add r1,r1 ; r1=052524 c=1 + 003001 -- bgt L17 ; + 003401 -- ble L18 ; +#11760 + 000000 -- L17: halt ; + 000301 -- L18: swab r1 ; r1=052125 + 020127 -- cmp r1,#052125 ; + 052125 + 001004 -- bne L19 ; + 030405 -- bit r4,r5 ; + 003002 -- bgt L19 ; + 005105 -- com r5 ; r5=052525 +#12000 + 001001 -- bne L20 ; + 000000 -- L19: halt ; + 112700 -- L20: movb #177401,r0 ; + 177401 + 100001 -- bpl L21 ; + 000000 -- L22: halt ; + 077002 -- L21: sob r0,L22 ; + 000261 -- sec ; c=1 +#12020 + 006100 -- rol r0 ; r0=000001 + 006100 -- rol r0 ; r0=000002 + 006100 -- rol r0 ; r0=000004 + 010001 -- mov r0,r1 ; r1=000004 + 005401 -- neg r1 ; r1=177774 + 005201 -- L23: inc r1 ; + 077002 -- sob r0,L23 ; + 005700 -- tst r0 ; here r0=r1=0 +#12040 + 001002 -- bne L24 ; + 005701 -- tst r1 ; + 001401 -- beq L25 ; + 000000 -- L24: halt ; + 012706 -- L25: mov #776,sp ; + 000776 -- + 004767 -- jsr pc,L26 ; + 000002 +#12060 + 000000 -- N2: halt ; + 022716 -- L26: cmp #N2,(sp) ; + 012060 + 001401 -- beq L27 ; + 000000 -- halt ; + 012716 -- L27: mov #N3,(sp) ; + 012102 + 000207 -- rts pc ; +#12100 + 000000 -- halt ; + 005046 -- N3: clr -(sp) ; + 012746 -- mov #N4,-(sp) ; + 012114 + 000002 -- rti ; + 000000 -- halt ; + 000137 -- N4: jmp @#N5 ; + 012122 +#12120 + 000000 -- halt ; + 012705 -- N5: mov #160000,r5 ; r5=160000 + 160000 + 005037 -- clr @#6 ; + 000006 + 012737 -- mov #N6,@#4 ; + 012150 + 000004 +#12140 + 012706 -- mov #776,sp ; sp=776 + 000776 + 005715 -- tst (r5) ; will fail, first word of I/O page + 000000 -- halt ; + 000000 -- N6: halt ; +# +C Exec code 35 (11/70 self test code) +# D RE RQ FU DAT +stapc 011600 -- start @ 11600 +wtgo +rpc d=012152 -- ! pc +wal 000004 -- vector: 4 -> trap catcher again +bwm 2 + 000006 -- PC:6 + 000000 -- PS:0 +#----------------------------------------------------------------------------- +# Up to here code and data (both input and result) occupied 'fresh' memory. +# Easy to debug, but inconvenient when test should be extended later. +# From here on, only code will always occupy fresh memory. +# Data will be put into the upper part of the 16 kbyte memory: +# test vector: 036000 (512 byte area) +# result data: 037000 (512 byte area) +#----------------------------------------------------------------------------- +C Setup code 36 [base 12200] (systematic CMP test) +# +wal 012200 -- code: +bwm 7 + 000230 -- spl 0 + 012400 -- L1: mov (r4)+,r0 + 012401 -- mov (r4)+,r1 + 020001 -- cmp r0,r1 + 011225 -- mov (r2),(r5)+ + 077305 -- sob r3,L1 + 000000 -- halt +# +C Exec code 36 (systematic CMP test) +C Exec test 36.1: data adapted from cmp.s11 code of Begemot p11-2.10c +# +wal 036000 -- setup test vector: +bwm 22 + 000000 -- 000000, 000000 --> nzvc=0100 + 000000 -- + 000001 -- 000001, 000001 --> nzvc=0100 + 000001 -- + 177777 -- 177777, 177777 --> nzvc=0100 + 177777 -- + 000000 -- 000000, 000001 --> nzvc=1001 + 000001 -- + 000000 -- 000000, 177777 --> nzvc=0001 + 177777 -- + 000001 -- 000001, 000000 --> nzvc=0000 + 000000 -- + 177777 -- 177777, 000000 --> nzvc=1000 + 000000 -- + 000001 -- 000001, 177777 --> nzvc=0001 + 177777 -- + 177777 -- 177777, 000001 --> nzvc=1000 + 000001 -- + 077777 -- 077777, 100000 --> nzvc=1011 + 100000 -- + 100000 -- 100000, 077777 --> nzvc=0010 + 077777 -- +#---- +wr2 177776 -- r2=177776 -> psw +wr3 000013 -- r3=13 -> test count +wr4 036000 -- r4=36000 -> input area +wr5 037000 -- r5=37000 -> output area +wsp 001400 -- sp=1400 +stapc 012200 -- start @ 12200 +wtgo +rpc d=012216 -- ! pc +rr3 d=000000 -- ! r3=0 +rr4 d=036054 -- ! r4=12354 +rr5 d=037026 -- ! r5=12426 +wal 037000 -- +brm 11 + d=000004 -- 000000, 000000 --> nzvc=0100 + d=000004 -- 000001, 000001 --> nzvc=0100 + d=000004 -- 177777, 177777 --> nzvc=0100 + d=000011 -- 000000, 000001 --> nzvc=1001 + d=000001 -- 000000, 177777 --> nzvc=0001 + d=000000 -- 000001, 000000 --> nzvc=0000 + d=000010 -- 177777, 000000 --> nzvc=1000 + d=000001 -- 000001, 177777 --> nzvc=0001 + d=000010 -- 177777, 000001 --> nzvc=1000 + d=000013 -- 077777, 100000 --> nzvc=1011 + d=000002 -- 100000, 077777 --> nzvc=0010 +#----------------------------------------------------------------------------- +C Setup code 37 [base 12300] (systematic DIV test) +# +wal 012300 -- code: +bwm 9 + 000230 -- spl 0 + 012400 -- L1: mov (r4)+,r0 + 012401 -- mov (r4)+,r1 + 071024 -- div (r4)+,r0 + 011225 -- mov (r2),(r5)+ + 010025 -- mov r0,(r5)+ + 010125 -- mov r1,(r5)+ + 077307 -- sob r3,L1 +#12520 + 000000 -- halt +# +C Exec code 37 (systematic DIV test) +C Exec test 37.1: data adapted from div.s11 code of Begemot p11-2.10c +# +wal 036000 -- setup test vector: +bwm 57 + 000000 -- 0, 4, 0, 7, 0, 4# 4/ 0 -> 0111 0 4 + 000004 -- + 000000 -- + 000000 -- 0, 4, 2, 0, 2, 0# 4/ 2 -> 0000 2 0 + 000004 -- + 000002 -- + 000000 -- 0, 6, 2, 0, 3, 0# 6/ 2 -> 0000 3 0 + 000006 -- + 000002 -- + 000000 -- 0, 4, -2, 10, -2, 0# 4/-2 ->1000 -2 0 + 000004 -- + 177776 -- +#36030 + 000002 -- 2, 0, 1, 2, 2, 0# 0x20000 / 1 + 000000 -- + 000001 -- + 000002 -- 2, 0, -2, 12, 2, 0# 0x20000 / -2 + 000000 -- + 177776 -- + 100000 -- 100000, 0, 1, 12,100000, 0# 0x80000000 / 1 + 000000 -- + 000001 -- + 177776 -- 177776,177777, -1, 2,177776,177777# -0x10001 / -1 + 177777 -- + 177777 -- +#36060 + 177777 -- 177777,177773, 2, 10, -2, -1# -5 / 2 + 177773 -- + 000002 -- + 177777 -- 177777,177773, -2, 0, 2, -1# -5 / -2 + 177773 -- + 177776 -- + 177776 -- 177776, 0, 40000, 10, -10, 0# -0x20000/0x4000 + 000000 -- + 040000 -- + 000100 -- 100, 200,177601, 12, 100, 200# 0x400080 / -0x7f + 000200 -- + 177601 -- +#36110 + 000000 -- 0, 1, 0, 7, 0, 1 # zero divide + 000001 -- + 000000 -- + 177777 -- -1, -1, 0, 7, -1, -1 # zero divide + 177777 -- + 000000 -- + 000000 -- 0, 0, 0, 7, 0, 0 # zero divide + 000000 -- + 000000 -- + 000001 -- 1, 1, 1, 2, 1, 1 # overflow + 000001 -- + 000001 -- +#36140 + 000001 -- 1, 1, -1, 012, 1, 1 # overflow + 000001 -- + 177777 -- + 177777 -- -1, -1, 1, 010, -1, 0 # wfjm corrected, not overflow + 177777 -- + 000001 -- + 177777 -- -1, -1, -1, 0, 1, 0 # wfjm corrected, not overflow + 177777 -- + 177777 -- +#---- +wr2 177776 -- r2=177776 -> psw +wr3 000023 -- r3=23 -> test count +wr4 036000 -- r4=36000 -> input area +wr5 037000 -- r5=37000 -> output area +wsp 001400 -- sp=1400 +stapc 012300 -- start @ 12300 +wtgo +rpc d=012322 -- ! pc +rr3 d=000000 -- ! r3=0 +rr4 d=036162 -- ! r4=36162 +rr5 d=037162 -- ! r5=37162 +wal 037000 -- +brm 57 + d=000007 --! 0, 4, 0, 7, 0, 4# 4/ 0 -> 0111 0 4 + d=000000 --! + d=000004 --! + d=000000 --! 0, 4, 2, 0, 2, 0# 4/ 2 -> 0000 2 0 + d=000002 --! + d=000000 --! + d=000000 --! 0, 6, 2, 0, 3, 0# 6/ 2 -> 0000 3 0 + d=000003 --! + d=000000 --! + d=000010 --! 0, 4, -2, 10, -2, 0# 4/-2 ->1000 -2 0 + d=177776 --! + d=000000 --! +#37030 + d=000002 --! 2, 0, 1, 2, 2, 0# 0x20000 / 1 + d=000002 --! + d=000000 --! + d=000012 --! 2, 0, -2, 12, 2, 0# 0x20000 / -2 + d=000002 --! + d=000000 --! + d=000012 --!100000, 0, 1, 12,100000, 0# 0x80000000 / 1 + d=100000 --! + d=000000 --! + d=000002 --!177776,177777, -1, 2,177776,177777# -0x10001 / -1 + d=177776 --! + d=177777 --! +#37060 + d=000010 --!177777,177773, 2, 10, -2, -1# -5 / 2 + d=177776 --! + d=177777 --! + d=000000 --!177777,177773, -2, 0, 2, -1# -5 / -2 + d=000002 --! + d=177777 --! + d=000010 --!177776, 0, 40000, 10, -10, 0# -0x20000/0x4000 + d=177770 --! + d=000000 --! + d=000012 --! 100, 200,177601, 12, 100, 200# 0x400080 / -0x7f + d=000100 --! + d=000200 --! +#37110 + d=000007 --! 0, 1, 0, 7, 0, 1 # zero divide + d=000000 --! + d=000001 --! + d=000007 --! -1, -1, 0, 7, -1, -1 # zero divide + d=177777 --! + d=177777 --! + d=000007 --! 0, 0, 0, 7, 0, 0 # zero divide + d=000000 --! + d=000000 --! + d=000002 --! 1, 1, 1, 2, 1, 1 # overflow + d=000001 --! + d=000001 --! +#13740 + d=000012 --! 1, 1, -1, 012, 1, 1 # overflow + d=000001 --! + d=000001 --! + d=000010 --! -1, -1, 1, 010, -1, 0 # wfjm corrected, not overflow + d=177777 --! + d=000000 --! + d=000000 --! -1, -1, -1, 0, 1, 0 # wfjm corrected, not overflow + d=000001 --! + d=000000 --! +#-------- +C Exec test 37.2: data adapted from KDJ11.MAC, test 213, p. 139-141 +# D RE RQ FU DAT +wal 036000 -- setup test vector: +bwm 51 + 177777 -- 177777,177777,177777, 0, 1, 0# + 177777 -- + 177777 -- + 000000 -- 0,177777,177777,12, 0,177777# + 177777 -- + 177777 -- + 177777 -- 177777, 0,177777, 2,177777, 0# + 000000 -- + 177777 -- + 000000 -- 0, 7642, 7643, 4, 0, 7642# + 007642 -- + 007643 -- + 000000 -- 0, 137,177543, 4, 0, 137# + 000137 -- + 177543 -- + 000000 -- 0, 7643, 7643, 0, 1, 0# + 007643 -- + 007643 -- + 100000 -- 100000, 4376, 10021,12,100000, 4376# + 004376 -- + 010021 -- + 177700 -- 177700,170033, 10021,10,176024,171307# + 170033 -- + 010021 -- + 177700 -- 177700,170033,167757, 0, 1754,171307# + 170033 -- + 167757 -- + 000000 -- 0,177777, 1, 2, 0,177777# + 177777 -- + 000001 -- + 177777 -- 177777, 45716, 1,12,177777, 45716# + 045716 -- + 000001 -- + 000000 -- 0, 2,177770, 4, 0, 2# + 000002 -- + 177770 -- + 177777 -- 177777,177776, 10, 4, 0,177776# + 177776 -- + 000010 -- + 000001 -- 1,177777, 1, 2, 1,177777# + 177777 -- + 000001 -- + 000001 -- 1, 0, 2, 2, 1, 0# + 000000 -- + 000002 -- + 000001 -- 1, 0, 3, 0, 52525, 1# + 000000 -- + 000003 -- + 000023 -- 23, 16054, 16537, 0, 246, 10222# + 016054 -- + 016537 -- +#---- +wr2 177776 -- r2=177776 -> psw +wr3 000021 -- r3=21 (17.) -> test count +wr4 036000 -- r4=36000 -> input area +wr5 037000 -- r5=37000 -> output area +wsp 001400 -- sp=1400 +stapc 012300 -- start @ 12300 +wtgo +rpc d=012322 -- ! pc +rr3 d=000000 -- ! r3=0 +rr4 d=036146 -- ! r4=36146 +rr5 d=037146 -- ! r5=37146 +wal 037000 -- +brm 51 + d=000000 --!177777,177777,177777, 0, 1, 0# + d=000001 --! + d=000000 --! + d=000012 --! 0,177777,177777,12, 0,177777# + d=000000 --! + d=177777 --! + d=000002 --!177777, 0,177777, 2,177777, 0# + d=177777 --! + d=000000 --! + d=000004 --! 0, 7642, 7643, 4, 0, 7642# + d=000000 --! + d=007642 --! + d=000004 --! 0, 137,177543, 4, 0, 137# + d=000000 --! + d=000137 --! + d=000000 --! 0, 7643, 7643, 0, 1, 0# + d=000001 --! + d=000000 --! + d=000012 --!100000, 4376, 10021,12,100000, 4376# + d=100000 --! + d=004376 --! + d=000010 --!177700,170033, 10021,10,176024,171307# + d=176024 --! + d=171307 --! + d=000000 --!177700,170033,167757, 0, 1754,171307# + d=001754 --! + d=171307 --! + d=000002 --! 0,177777, 1, 2, 0,177777# + d=000000 --! + d=177777 --! + d=000012 --!177777, 45716, 1,12,177777, 45716# + d=177777 --! + d=045716 --! + d=000004 --! 0, 2,177770, 4, 0, 2# + d=000000 --! + d=000002 --! + d=000004 --!177777,177776, 10, 4, 0,177776# + d=000000 --! + d=177776 --! + d=000002 --! 1,177777, 1, 2, 1,177777# + d=000001 --! + d=177777 --! + d=000002 --! 1, 0, 2, 2, 1, 0# + d=000001 --! + d=000000 --! + d=000000 --! 1, 0, 3, 0, 52525, 1# + d=052525 --! + d=000001 --! + d=000000 --! 23, 16054, 16537, 0, 246, 10222# + d=000246 --! + d=010222 --! +#----------------------------------------------------------------------------- +C Setup code 40 [base 12400] (systematic ASH test) +# +wal 012400 -- code: +bwm 15 + 000230 -- spl 0 + 016400 -- L1: mov 2(r4),r0 + 000002 + 011412 -- mov (r4),(r2) + 072064 -- ash 4(r4),r0 + 000004 + 011265 -- mov (r2),2(r5) + 000002 +#12420 + 010015 -- mov r0,(r5) + 062704 -- add #6,r4 + 000006 + 062705 -- add #4,r5 + 000004 + 077315 -- sob r3,L1 + 000000 -- halt +# +C Exec code 40 (systematic ASH test) +C Exec test 40.1: data adapted from ash.s11 code of Begemot p11-2.10c +# +# The {} comments are original comments from Harti Brandt +# Annotations starting with !! indicated mods for W11 +# Note, that the W11 does not have the microcode bugs of the J11 ! +# +wal 036000 -- setup test vector: +# test shift amount 0 +bwm 150 + 000000 -- 00, 000000, 000000, 000000, 04 + 000000 -- + 000000 -- + 000017 -- 17, 000000, 000000, 000000, 04 + 000000 -- + 000000 -- + 000017 -- 17, 100001, 000000, 100001, 10 + 100001 -- + 000000 -- + 000017 -- 17, 040001, 000000, 040001, 00 + 040001 -- + 000000 -- + 000017 -- 17, 040001, 177700, 040001, 00 + 040001 -- + 177700 -- +# right shift positive values + 000000 -- 00, 000000, 000077, 000000, 04 + 000000 -- + 000077 -- + 000017 -- 17, 000000, 000077, 000000, 04 + 000000 -- + 000077 -- + 000000 -- 00, 000002, 000077, 000001, 00 + 000002 -- + 000077 -- + 000000 -- 00, 000001, 000077, 000000, 05 + 000001 -- + 000077 -- + 000000 -- 00, 000003, 000076, 000000, 05 + 000003 -- + 000076 -- + 000000 -- 00, 000001, 000076, 000000, 04 + 000001 -- + 000076 -- + 000000 -- 00, 040000, 000062, 000001, 00 + 040000 -- + 000062 -- + 000000 -- 00, 040000, 000061, 000000, 05 + 040000 -- + 000061 -- + 000000 -- 00, 040000, 000060, 000000, 04 + 040000 -- + 000060 -- + 000000 -- 00, 040000, 000042, 000000, 04 + 040000 -- + 000042 -- + 000000 -- 00, 040000, 000041, 000000, 04 + 040000 -- + 000041 -- + 000000 -- 00, 040000, 000040, 000000, 04 + 040000 -- + 000040 -- + 000000 -- 00, 040000, 100037, 000000, 04 + 040000 -- + 100037 -- +# right shift negative numbers + 000000 -- 00, 100002, 000077, 140001, 10 + 100002 -- + 000077 -- + 000000 -- 00, 100002, 000076, 160000, 11 + 100002 -- + 000076 -- + 000000 -- 00, 100002, 000075, 170000, 10 + 100002 -- + 000075 -- + 000000 -- 00, 100002, 000062, 177776, 10 + 100002 -- + 000062 -- + 000000 -- 00, 100002, 000061, 177777, 10 + 100002 -- + 000061 -- + 000000 -- 00, 100002, 000060, 177777, 11 + 100002 -- + 000060 -- + 000000 -- 00, 100002, 000057, 177777, 11 + 100002 -- + 000057 -- + 000000 -- 00, 100002, 000056, 177777, 11 + 100002 -- + 000056 -- + 000000 -- 00, 100002, 000041, 177777, 11 + 100002 -- + 000041 -- + 000000 -- 00, 100002, 000040, 177777, 11 + 100002 -- + 000040 -- + 000000 -- 00, 100002, 040037, 177777, 11 + 100002 -- + 040037 -- +# left shift positive numbers + 000000 -- 00, 000000, 000001, 000000, 04 + 000000 -- + 000001 -- + 000017 -- 17, 000000, 000001, 000000, 04 + 000000 -- + 000001 -- + 000000 -- 00, 000001, 000007, 000200, 00 + 000001 -- + 000007 -- + 000000 -- 00, 000001, 000016, 040000, 00 + 000001 -- + 000016 -- + 000000 -- 00, 000001, 000017, 100000, 12 + 000001 -- + 000017 -- + 000000 -- 00, 000001, 000020, 000000, 07 + 000001 -- + 000020 -- + 000000 -- 00, 000001, 000021, 000000, 06 + 000001 -- + 000021 -- + 000000 -- 00, 000001, 000036, 000000, 06 + 000001 -- + 000036 -- + 000000 -- 00, 000001, 000037, 000000, 04 {????} + 000001 -- + 000037 -- + 000000 -- 00, 000001, 000040, 000000, 04 {right shift!} + 000001 -- + 000040 -- + 000000 -- 00, 000001, 010037, 000000, 04 {right shift!} + 000001 -- + 010037 -- +# left shift negative numbers + 000000 -- 00, 100001, 000001, 000002, 03 + 100001 -- + 000001 -- + 000000 -- 00, 140001, 000001, 100002, 11 + 140001 -- + 000001 -- + 000000 -- 00, 140001, 000002, 000004, 03 + 140001 -- + 000002 -- + 000000 -- 00, 140001, 000016, 040000, 02 + 140001 -- + 000016 -- + 000000 -- 00, 140001, 000017, 100000, 12 + 140001 -- + 000017 -- + 000000 -- 00, 140001, 000020, 000000, 07 + 140001 -- + 000020 -- + 000000 -- 00, 140001, 000021, 000000, 06 + 140001 -- + 000021 -- + 000000 -- 00, 140002, 000035, 000000, 06 + 140002 -- + 000035 -- + 000000 -- 00, 140002, 000036, 000000, 06 + 140002 -- + 000036 -- + 000000 -- 00, 140002, 000037, 177777, 11 {????} + 140002 -- + 000037 -- +#---- +wr2 177776 -- r2=177776 -> psw +wr3 000062 -- r3=62 -> test count +wr4 036000 -- r4=36000 -> input area +wr5 037000 -- r5=37000 -> output area +wsp 001400 -- sp=1400 +stapc 012400 -- start @ 12400 +wtgo +rpc d=012436 -- ! pc +rr3 d=000000 -- ! r3=0 +rr4 d=036454 -- ! r4=36454 +rr5 d=037310 -- ! r5=37310 +wal 037000 -- +# test shift amount 0 +brm 100 + d=000000 -- 00, 000000, 000000, 000000, 04 + d=000004 -- + d=000000 -- 17, 000000, 000000, 000000, 04 + d=000004 -- + d=100001 -- 17, 100001, 000000, 100001, 10 + d=000010 -- + d=040001 -- 17, 040001, 000000, 040001, 00 + d=000000 -- + d=040001 -- 17, 040001, 177700, 040001, 00 + d=000000 -- +#37024 # right shift positive values + d=000000 -- 00, 000000, 000077, 000000, 04 + d=000004 -- + d=000000 -- 17, 000000, 000077, 000000, 04 + d=000004 -- + d=000001 -- 00, 000002, 000077, 000001, 00 + d=000000 -- +#37040 + d=000000 -- 00, 000001, 000077, 000000, 05 + d=000005 -- + d=000000 -- 00, 000003, 000076, 000000, 05 + d=000005 -- + d=000000 -- 00, 000001, 000076, 000000, 04 + d=000004 -- + d=000001 -- 00, 040000, 000062, 000001, 00 + d=000000 -- +#37060 + d=000000 -- 00, 040000, 000061, 000000, 05 + d=000005 -- + d=000000 -- 00, 040000, 000060, 000000, 04 + d=000004 -- + d=000000 -- 00, 040000, 000042, 000000, 04 + d=000004 -- + d=000000 -- 00, 040000, 000041, 000000, 04 + d=000004 -- +#37100 + d=000000 -- 00, 040000, 000040, 000000, 04 + d=000004 -- + d=000000 -- 00, 040000, 100037, 000000, 04 + d=000006 -- !!04->06 +#37110 # right shift negative numbers + d=140001 -- 00, 100002, 000077, 140001, 10 + d=000010 -- + d=160000 -- 00, 100002, 000076, 160000, 11 + d=000011 -- +#37120 + d=170000 -- 00, 100002, 000075, 170000, 10 + d=000010 -- + d=177776 -- 00, 100002, 000062, 177776, 10 + d=000010 -- + d=177777 -- 00, 100002, 000061, 177777, 10 + d=000010 -- + d=177777 -- 00, 100002, 000060, 177777, 11 + d=000011 -- +#37140 + d=177777 -- 00, 100002, 000057, 177777, 11 + d=000011 -- + d=177777 -- 00, 100002, 000056, 177777, 11 + d=000011 -- + d=177777 -- 00, 100002, 000041, 177777, 11 + d=000011 -- + d=177777 -- 00, 100002, 000040, 177777, 11 + d=000011 -- see Note below [[s:10]] + d=000000 -- 00, 100002, 040037, 177777, 11 !!-1->0 + d=000006 -- !!11->06 +#37164 # left shift positive numbers + d=000000 -- 00, 000000, 000001, 000000, 04 + d=000004 -- + d=000000 -- 17, 000000, 000001, 000000, 04 + d=000004 -- + d=000200 -- 00, 000001, 000007, 000200, 00 + d=000000 -- +#37200 + d=040000 -- 00, 000001, 000016, 040000, 00 + d=000000 -- + d=100000 -- 00, 000001, 000017, 100000, 12 + d=000012 -- + d=000000 -- 00, 000001, 000020, 000000, 07 + d=000007 -- + d=000000 -- 00, 000001, 000021, 000000, 06 + d=000006 -- +#37220 + d=000000 -- 00, 000001, 000036, 000000, 06 + d=000006 -- + d=000000 -- 00, 000001, 000037, 000000, 04 {????} + d=000006 -- !!04->06 + d=000000 -- 00, 000001, 000040, 000000, 04 {right shift!} + d=000004 -- + d=000000 -- 00, 000001, 010037, 000000, 04 {right shift!} + d=000006 -- !!04->06 +#37240 # left shift negative numbers + d=000002 -- 00, 100001, 000001, 000002, 03 + d=000003 -- + d=100002 -- 00, 140001, 000001, 100002, 11 + d=000011 -- + d=000004 -- 00, 140001, 000002, 000004, 03 + d=000003 -- + d=040000 -- 00, 140001, 000016, 040000, 02 + d=000002 -- +#37260 + d=100000 -- 00, 140001, 000017, 100000, 12 + d=000012 -- + d=000000 -- 00, 140001, 000020, 000000, 07 + d=000007 -- + d=000000 -- 00, 140001, 000021, 000000, 06 + d=000006 -- + d=000000 -- 00, 140002, 000035, 000000, 06 + d=000006 -- +#37300 + d=000000 -- 00, 140002, 000036, 000000, 06 + d=000006 -- + d=000000 -- 00, 140002, 000037, 177777, 11 {????} !!-1->0 + d=000006 -- !!11->06 +# +# simh notes: +# 1. ash dst=100002,src=040 sets C=0 in simh. PSW is: s:10 b:11 W11:11 +# +#----------------------------------------------------------------------------- +C Setup code 41 [base 12500] (systematic ASHC even test) +# +wal 012500 -- code: +bwm 19 + 000230 -- spl 0 + 016400 -- L1: mov 2(r4),r0 + 000002 + 016401 -- mov 4(r4),r1 + 000004 + 011412 -- mov (r4),(r2) + 073064 -- ashc 6(r4),r0 + 000006 +#12520 + 011265 -- mov (r2),4(r5) + 000004 + 010015 -- mov r0,(r5) + 010165 -- mov r1,2(r5) + 000002 + 062704 -- add #10,r4 + 000010 + 062705 -- add #6,r5 +#12540 + 000006 + 077321 -- sob r3,L1 + 000000 -- halt +# +C Exec code 41 (systematic ASHC even test) +C Exec test 41.1: data adapted from ashc.s11 code of Begemot p11-2.10c +# +# The {} comments are original comments from Harti Brandt +# Annotations starting with !! indicated mods for W11 +# Note, that the W11 does not have the microcode bugs of the J11 ! +# +wal 036000 -- setup test vector: +# test when no shift at all, cc must be correctly set +bwm 188 + 000000 -- 00, 000000, 000000, 000000, 000000, 000000, 04 + 000000 -- + 000000 -- + 000000 -- + 000017 -- 17, 000000, 000000, 000000, 000000, 000000, 04 + 000000 -- + 000000 -- + 000000 -- + 000017 -- 17, 040000, 000001, 000000, 040000, 000001, 00 + 040000 -- + 000001 -- + 000000 -- + 000017 -- 17, 100000, 000001, 000000, 100000, 000001, 10 + 100000 -- + 000001 -- + 000000 -- + 000017 -- 17, 100000, 000001, 177700, 100000, 000001, 10 + 100000 -- + 000001 -- + 177700 -- +# right shifts of positive numbers + 000000 -- 00, 000000, 000000, 000077, 000000, 000000, 04 + 000000 -- + 000000 -- + 000077 -- + 000017 -- 17, 000000, 000000, 000077, 000000, 000000, 04 + 000000 -- + 000000 -- + 000077 -- + 000000 -- 00, 040000, 000000, 000077, 020000, 000000, 00 + 040000 -- + 000000 -- + 000077 -- + 000000 -- 00, 040000, 000000, 177777, 020000, 000000, 00 + 040000 -- + 000000 -- + 000077 -- + 000000 -- 00, 040000, 000000, 000060, 000000, 040000, 00 + 040000 -- + 000000 -- + 000060 -- + 000000 -- 00, 040000, 000000, 000042, 000000, 000001, 00 + 040000 -- + 000000 -- + 000042 -- + 000000 -- 00, 040000, 000000, 000041, 000000, 000000, 05 + 040000 -- + 000000 -- + 000041 -- + 000000 -- 00, 040000, 000000, 000040, 000000, 000000, 04 + 040000 -- + 000000 -- + 000040 -- + 000000 -- 00, 040000, 000000, 177737, 000000, 000000, 04 + 040000 -- + 000000 -- + 177737 -- + 000000 -- 00, 000000, 000001, 177737, 000000, 000000, 04 + 000000 -- + 000001 -- + 177737 -- +# right shifts of negative numbers + 000000 -- 00, 100000, 000002, 000077, 140000, 000001, 10 + 100000 -- + 000002 -- + 000077 -- + 000000 -- 00, 100020, 000001, 000077, 140010, 000000, 11 + 100020 -- + 000001 -- + 000077 -- + 000000 -- 00, 177777, 177776, 000077, 177777, 177777, 10 + 177777 -- + 177776 -- + 000077 -- + 000000 -- 00, 177777, 177777, 000077, 177777, 177777, 11 + 177777 -- + 177777 -- + 000077 -- + 000000 -- 00, 100000, 100000, 000060, 177777, 100000, 11 + 100000 -- + 100000 -- + 000060 -- + 000000 -- 00, 100000, 000000, 000060, 177777, 100000, 10 + 100000 -- + 000000 -- + 000060 -- + 000000 -- 00, 100000, 000001, 000042, 177777, 177776, 10 + 100000 -- + 000001 -- + 000042 -- + 000000 -- 00, 100000, 000001, 000041, 177777, 177777, 10 + 100000 -- + 000001 -- + 000041 -- + 000000 -- 00, 100000, 000001, 000040, 177777, 177777, 11 + 100000 -- + 000001 -- + 000040 -- + 000000 -- 00, 100000, 000001, 177737, 177777, 177777, 11 + 100000 -- + 000001 -- + 177737 -- +# left shifts of positive numbers + 000000 -- 00, 000000, 000000, 000001, 000000, 000000, 04 + 000000 -- + 000000 -- + 000001 -- + 000017 -- 17, 000000, 000000, 000001, 000000, 000000, 04 + 000000 -- + 000000 -- + 000001 -- + 000000 -- 00, 000002, 000001, 000001, 000004, 000002, 00 + 000002 -- + 000001 -- + 000001 -- + 000000 -- 00, 000002, 100000, 000001, 000005, 000000, 00 + 000002 -- + 100000 -- + 000001 -- + 000000 -- 00, 040000, 000000, 000001, 100000, 000000, 12 + 040000 -- + 000000 -- + 000001 -- + 000000 -- 00, 040000, 000000, 000002, 000000, 000000, 07 + 040000 -- + 000000 -- + 000002 -- + 000000 -- 00, 040000, 000000, 000003, 000000, 000000, 06 + 040000 -- + 000000 -- + 000003 -- + 000000 -- 00, 000000, 000001, 177701, 000000, 000002, 00 + 000000 -- + 000001 -- + 177701 -- + 000000 -- 00, 000000, 000001, 177735, 020000, 000000, 00 + 000000 -- + 000001 -- + 177735 -- + 000000 -- 00, 000000, 000001, 177736, 040000, 000000, 00 + 000000 -- + 000001 -- + 177736 -- + 000000 -- 00, 000000, 000001, 000037, 100000, 000000, 12 {left shift!} + 000000 -- + 000001 -- + 000037 -- + 000000 -- 00, 000000, 000001, 177737, 000000, 000000, 04 {right shift!} + 000000 -- + 000001 -- + 177737 -- + 000000 -- 00, 000000, 000001, 020037, 000000, 000000, 04 {right shift!} + 000000 -- + 000001 -- + 020037 -- +# left shifts of negative numbers + 000000 -- 00, 177777, 177777, 000001, 177777, 177776, 11 + 177777 -- + 177777 -- + 000001 -- + 000000 -- 00, 177777, 177777, 000002, 177777, 177774, 11 + 177777 -- + 177777 -- + 000002 -- + 000000 -- 00, 177777, 177777, 000036, 140000, 000000, 11 + 177777 -- + 177777 -- + 000036 -- + 000000 -- 00, 177777, 177777, 000037, 100000, 000000, 11 + 177777 -- + 177777 -- + 000037 -- + 000000 -- 00, 177777, 177776, 000037, 000000, 000000, 07 + 177777 -- + 177776 -- + 000037 -- + 000000 -- 00, 177777, 177774, 000037, 000000, 000000, 06 + 177777 -- + 177774 -- + 000037 -- + 000000 -- 00, 177777, 177777, 177701, 177777, 177776, 11 + 177777 -- + 177777 -- + 177701 -- + 000000 -- 00, 177777, 177777, 001037, 177777, 177777, 11 {right shift!} + 177777 -- + 177777 -- + 001037 -- + 000000 -- 00, 177777, 177777, 001036, 140000, 000000, 11 + 177777 -- + 177777 -- + 001036 -- +#---- +wr2 177776 -- r2=177776 +wr3 000057 -- r3=57 (47.) +wr4 036000 -- r4=36000 +wr5 037000 -- r5=37000 +wsp 001400 -- sp=1400 +stapc 012500 -- start @ 12500 +wtgo +rpc d=012546 -- ! pc +rr3 d=000000 -- ! r3=0 +rr4 d=036570 -- ! r4=36570 +rr5 d=037432 -- ! r5=37432 +wal 037000 -- +# test when no shift at all, cc must be correctly set +brm 141 + d=000000 --!00, 000000, 000000, 000000, 000000, 000000, 04 + d=000000 --! + d=000004 --! + d=000000 --!17, 000000, 000000, 000000, 000000, 000000, 04 + d=000000 --! + d=000004 --! + d=040000 --!17, 040000, 000001, 000000, 040000, 000001, 00 + d=000001 --! + d=000000 --! + d=100000 --!17, 100000, 000001, 000000, 100000, 000001, 10 + d=000001 --! + d=000010 --! +#37030 + d=100000 --!17, 100000, 000001, 177700, 100000, 000001, 10 + d=000001 --! + d=000010 --! +# right shifts of positive numbers + d=000000 --!00, 000000, 000000, 000077, 000000, 000000, 04 + d=000000 --! + d=000004 --! + d=000000 --!17, 000000, 000000, 000077, 000000, 000000, 04 + d=000000 --! + d=000004 --! + d=020000 --!00, 040000, 000000, 000077, 020000, 000000, 00 + d=000000 --! + d=000000 --! +#37060 + d=020000 --!00, 040000, 000000, 177777, 020000, 000000, 00 + d=000000 --! + d=000000 --! + d=000000 --!00, 040000, 000000, 000060, 000000, 040000, 00 + d=040000 --! + d=000000 --! + d=000000 --!00, 040000, 000000, 000042, 000000, 000001, 00 + d=000001 --! + d=000000 --! + d=000000 --!00, 040000, 000000, 000041, 000000, 000000, 05 + d=000000 --! + d=000005 --! +#37110 + d=000000 --!00, 040000, 000000, 000040, 000000, 000000, 04 + d=000000 --! + d=000004 --! + d=000000 --!00, 040000, 000000, 177737, 000000, 000000, 04 + d=000000 --! + d=000006 --! !!04->06 + d=100000 --!00, 000000, 000001, 177737, 000000, 000000, 04!!->100000 + d=000000 --! + d=000012 --! !!04->12 +# right shifts of negative numbers + d=140000 --!00, 100000, 000002, 000077, 140000, 000001, 10 + d=000001 --! + d=000010 --! +#37140 + d=140010 --!00, 100020, 000001, 000077, 140010, 000000, 11 + d=000000 --! + d=000011 --! + d=177777 --!00, 177777, 177776, 000077, 177777, 177777, 10 + d=177777 --! + d=000010 --! + d=177777 --!00, 177777, 177777, 000077, 177777, 177777, 11 + d=177777 --! + d=000011 --! + d=177777 --!00, 100000, 100000, 000060, 177777, 100000, 11 + d=100000 --! + d=000011 --! +#37170 + d=177777 --!00, 100000, 000000, 000060, 177777, 100000, 10 + d=100000 --! + d=000010 --! + d=177777 --!00, 100000, 000001, 000042, 177777, 177776, 10 + d=177776 --! + d=000010 --! + d=177777 --!00, 100000, 000001, 000041, 177777, 177777, 10 + d=177777 --! + d=000010 --! + d=177777 --!00, 100000, 000001, 000040, 177777, 177777, 11 + d=177777 --! + d=000011 --! +#37220 + d=100000 --!00, 100000, 000001, 177737, 177777, 177777, 11!!->100000 + d=000000 --! !!->000000 + d=000012 --! !!11->12 +# left shifts of positive numbers + d=000000 --!00, 000000, 000000, 000001, 000000, 000000, 04 + d=000000 --! + d=000004 --! + d=000000 --!17, 000000, 000000, 000001, 000000, 000000, 04 + d=000000 --! + d=000004 --! + d=000004 --!00, 000002, 000001, 000001, 000004, 000002, 00 + d=000002 --! + d=000000 --! +#37250 + d=000005 --!00, 000002, 100000, 000001, 000005, 000000, 00 + d=000000 --! + d=000000 --! + d=100000 --!00, 040000, 000000, 000001, 100000, 000000, 12 + d=000000 --! + d=000012 --! + d=000000 --!00, 040000, 000000, 000002, 000000, 000000, 07 + d=000000 --! + d=000007 --! + d=000000 --!00, 040000, 000000, 000003, 000000, 000000, 06 + d=000000 --! + d=000006 --! +#37300 + d=000000 --!00, 000000, 000001, 177701, 000000, 000002, 00 + d=000002 --! + d=000000 --! + d=020000 --!00, 000000, 000001, 177735, 020000, 000000, 00 + d=000000 --! + d=000000 --! + d=040000 --!00, 000000, 000001, 177736, 040000, 000000, 00 + d=000000 --! + d=000000 --! + d=100000 --!00, 000000, 000001, 000037, 100000, 000000, 12 {left shift!} + d=000000 --! + d=000012 --! +#37330 + d=100000 --!00, 000000, 000001, 177737, 000000, 000000, 04 {right shift!} !!->100000 + d=000000 --! + d=000012 --! !!04->12 + d=100000 --!00, 000000, 000001, 020037, 000000, 000000, 04 {right shift!} !!->100000 + d=000000 --! + d=000012 --! !!04->12 +# left shifts of negative numbers + d=177777 --!00, 177777, 177777, 000001, 177777, 177776, 11 + d=177776 --! + d=000011 --! + d=177777 --!00, 177777, 177777, 000002, 177777, 177774, 11 + d=177774 --! + d=000011 --! +#37360 + d=140000 --!00, 177777, 177777, 000036, 140000, 000000, 11 + d=000000 --! + d=000011 --! + d=100000 --!00, 177777, 177777, 000037, 100000, 000000, 11 + d=000000 --! + d=000011 --! + d=000000 --!00, 177777, 177776, 000037, 000000, 000000, 07 + d=000000 --! + d=000007 --! + d=000000 --!00, 177777, 177774, 000037, 000000, 000000, 06 + d=000000 --! + d=000006 --! +#37410 + d=177777 --!00, 177777, 177777, 177701, 177777, 177776, 11 + d=177776 --! + d=000011 --! + d=100000 --!00, 177777, 177777, 001037, 177777, 177777, 11 {right shift!} !!->100000 + d=000000 --! !!->00000 + d=000011 --! + d=140000 --!00, 177777, 177777, 001036, 140000, 000000, 11 + d=000000 --! + d=000011 --! +#----------------------------------------------------------------------------- +C Setup code 42 [base 12600] (systematic ASHC odd test) +# +wal 012600 -- code: +bwm 15 + 000230 -- spl 0 + 016401 -- L1: mov 2(r4),r1 + 000002 + 011412 -- mov (r4),(r2) + 073164 -- ashc 4(r4),r1 + 000004 + 011265 -- mov (r2),2(r5) + 000002 +#12620 + 010115 -- mov r1,(r5) + 062704 -- add #6,r4 + 000006 + 062705 -- add #4,r5 + 000004 + 077315 -- sob r3,L1 + 000000 -- halt +# +C Exec code 42 (systematic ASHC odd test) +C Exec test 42.1: data adapted from ashc.s11 code of Begemot p11-2.10c +# +# The {} comments are original comments from Harti Brandt +# Annotations starting with !! indicated mods for W11 +# Note, that the W11 does not have the microcode bugs of the J11 ! +# +wal 036000 -- setup test vector: +# test shift amount 0 +bwm 165 + 000000 -- 00, 000000, 000000, 000000, 04 + 000000 -- + 000000 -- + 000017 -- 17, 000000, 000000, 000000, 04 + 000000 -- + 000000 -- + 000017 -- 17, 100001, 000000, 100001, 10 + 100001 -- + 000000 -- + 000017 -- 17, 040001, 000000, 040001, 00 + 040001 -- + 000000 -- + 000017 -- 17, 040001, 177700, 040001, 00 + 040001 -- + 177700 -- +# right rotate positive values + 000000 -- 00, 000000, 000077, 000000, 04 + 000000 -- + 000077 -- + 000017 -- 17, 000000, 000077, 000000, 04 + 000000 -- + 000077 -- + 000000 -- 00, 000002, 000077, 000001, 00 + 000002 -- + 000077 -- + 000000 -- 00, 000001, 000077, 100000, 01 {cc is funny!} + 000001 -- + 000077 -- + 000000 -- 00, 000003, 000076, 140000, 01 + 000003 -- + 000076 -- + 000000 -- 00, 000001, 000076, 040000, 00 + 000001 -- + 000076 -- + 000000 -- 00, 040000, 000060, 040000, 00 + 040000 -- + 000060 -- + 000000 -- 00, 040000, 000043, 000002, 00 + 040000 -- + 000043 -- + 000000 -- 00, 040000, 000042, 000001, 00 + 040000 -- + 000042 -- + 000000 -- 00, 040000, 000041, 000000, 05 + 040000 -- + 000041 -- + 000000 -- 00, 040000, 000040, 000000, 04 + 040000 -- + 000040 -- + 000000 -- 00, 040000, 100037, 000000, 04 + 040000 -- + 100037 -- + 000000 -- 00, 020000, 000043, 000001, 00 + 020000 -- + 000043 -- + 000000 -- 00, 020000, 000042, 000000, 05 + 020000 -- + 000042 -- + 000000 -- 00, 020000, 000041, 000000, 04 + 020000 -- + 000041 -- +# right rotate negative numbers + 000000 -- 00, 100002, 000077, 040001, 10 + 100002 -- + 000077 -- + 000000 -- 00, 100002, 000076, 120000, 11 + 100002 -- + 000076 -- + 000000 -- 00, 100002, 000075, 050000, 10 + 100002 -- + 000075 -- + 000000 -- 00, 100002, 000061, 000005, 10 + 100002 -- + 000061 -- + 000000 -- 00, 100002, 000060, 100002, 11 + 100002 -- + 000060 -- + 000000 -- 00, 100002, 000057, 140001, 10 + 100002 -- + 000057 -- + 000000 -- 00, 100002, 000056, 160000, 11 + 100002 -- + 000056 -- + 000000 -- 00, 100002, 000055, 170000, 10 + 100002 -- + 000055 -- + 000000 -- 00, 100002, 000042, 177776, 10 + 100002 -- + 000042 -- + 000000 -- 00, 100002, 000041, 177777, 10 + 100002 -- + 000041 -- + 000000 -- 00, 100002, 000040, 177777, 11 + 100002 -- + 000040 -- + 000000 -- 00, 100002, 040037, 177777, 11 + 100002 -- + 040037 -- +# left rotate positive numbers + 000000 -- 00, 000000, 000001, 000000, 04 + 000000 -- + 000001 -- + 000000 -- 17, 000000, 000001, 000000, 04 + 000000 -- + 000001 -- + 000000 -- 00, 000001, 000007, 000200, 00 + 000001 -- + 000007 -- + 000000 -- 00, 000001, 000016, 040000, 00 + 000001 -- + 000016 -- + 000000 -- 00, 000001, 000017, 100000, 12 + 000001 -- + 000017 -- + 000000 -- 00, 000001, 000020, 000000, 03 + 000001 -- + 000020 -- + 000000 -- 00, 000001, 000021, 000000, 02 + 000001 -- + 000021 -- + 000000 -- 00, 000001, 000036, 000000, 02 + 000001 -- + 000036 -- + 000000 -- 00, 000001, 000037, 000000, 12 + 000001 -- + 000037 -- + 000000 -- 00, 000001, 000040, 000000, 04 {right shift!} + 000001 -- + 000040 -- + 000000 -- 00, 000001, 010037, 000000, 04 {right shift!} + 000001 -- + 010037 -- +# left rotate negative numbers + 000000 -- 00, 100001, 000001, 000002, 03 + 100001 -- + 000001 -- + 000000 -- 00, 140001, 000001, 100002, 11 + 140001 -- + 000001 -- + 000000 -- 00, 140001, 000002, 000004, 03 + 140001 -- + 000002 -- + 000000 -- 00, 140001, 000016, 040000, 02 + 140001 -- + 000016 -- + 000000 -- 00, 140001, 000017, 100000, 12 + 140001 -- + 000017 -- + 000000 -- 00, 140001, 000020, 000000, 13 + 140001 -- + 000020 -- + 000000 -- 00, 140001, 000021, 000000, 13 + 140001 -- + 000021 -- + 000000 -- 00, 140001, 000022, 000000, 03 + 140001 -- + 000022 -- + 000000 -- 00, 140001, 000023, 000000, 02 + 140001 -- + 000023 -- + 000000 -- 00, 140002, 000035, 000000, 02 + 140002 -- + 000035 -- + 000000 -- 00, 140002, 000036, 000000, 12 + 140002 -- + 000036 -- + 000000 -- 00, 140002, 000037, 000000, 07 + 140002 -- + 000037 -- +#---- +wr2 177776 -- r2=177776 -> psw +wr3 000067 -- r3=67 (55.) -> test count +wr4 036000 -- r4=36000 -> input area +wr5 037000 -- r5=37000 -> output area +wsp 001400 -- sp=1400 +stapc 012600 -- start @ 12600 +wtgo +rpc d=012636 -- ! pc +rr3 d=000000 -- ! r3=0 +rr4 d=036512 -- ! r4=36512 +rr5 d=037334 -- ! r5=37334 +wal 037000 -- +# test shift amount 0 +brm 110 + d=000000 --!00, 000000, 000000, 000000, 04 + d=000004 --! + d=000000 --!17, 000000, 000000, 000000, 04 + d=000004 --! + d=100001 --!17, 100001, 000000, 100001, 10 + d=000010 --! + d=040001 --!17, 040001, 000000, 040001, 00 + d=000000 --! +#37020 + d=040001 --!17, 040001, 177700, 040001, 00 + d=000000 --! +# right rotate positive values + d=000000 --!00, 000000, 000077, 000000, 04 + d=000004 --! + d=000000 --!17, 000000, 000077, 000000, 04 + d=000004 --! + d=000001 --!00, 000002, 000077, 000001, 00 + d=000000 --! +#37040 + d=100000 --!00, 000001, 000077, 100000, 01 {cc is funny!} + d=000001 --! + d=140000 --!00, 000003, 000076, 140000, 01 + d=000001 --! + d=040000 --!00, 000001, 000076, 040000, 00 + d=000000 --! + d=040000 --!00, 040000, 000060, 040000, 00 + d=000000 --! +#37060 + d=000002 --!00, 040000, 000043, 000002, 00 + d=000000 --! + d=000001 --!00, 040000, 000042, 000001, 00 + d=000000 --! + d=000000 --!00, 040000, 000041, 000000, 05 + d=000005 --! + d=000000 --!00, 040000, 000040, 000000, 04 + d=000004 --! +#37100 + d=000000 --!00, 040000, 100037, 000000, 04 + d=000006 --! !!04->06 + d=000001 --!00, 020000, 000043, 000001, 00 + d=000000 --! + d=000000 --!00, 020000, 000042, 000000, 05 + d=000005 --! + d=000000 --!00, 020000, 000041, 000000, 04 + d=000004 --! +#37120 # right rotate negative numbers + d=040001 --!00, 100002, 000077, 040001, 10 + d=000010 --! + d=120000 --!00, 100002, 000076, 120000, 11 + d=000011 --! + d=050000 --!00, 100002, 000075, 050000, 10 + d=000010 --! + d=000005 --!00, 100002, 000061, 000005, 10 + d=000010 --! +#37140 + d=100002 --!00, 100002, 000060, 100002, 11 + d=000011 --! + d=140001 --!00, 100002, 000057, 140001, 10 + d=000010 --! + d=160000 --!00, 100002, 000056, 160000, 11 + d=000011 --! + d=170000 --!00, 100002, 000055, 170000, 10 + d=000010 --! +#37160 + d=177776 --!00, 100002, 000042, 177776, 10 + d=000010 --! + d=177777 --!00, 100002, 000041, 177777, 10 + d=000010 --! + d=177777 --!00, 100002, 000040, 177777, 11 + d=000011 --! + d=000000 --!00, 100002, 040037, 177777, 11 !!->000000 + d=000007 --! !!11->07 +#37200 # left rotate positive numbers + d=000000 --!00, 000000, 000001, 000000, 04 + d=000004 --! + d=000000 --!17, 000000, 000001, 000000, 04 + d=000004 --! + d=000200 --!00, 000001, 000007, 000200, 00 + d=000000 --! + d=040000 --!00, 000001, 000016, 040000, 00 + d=000000 --! +#37220 + d=100000 --!00, 000001, 000017, 100000, 12 + d=000012 --! + d=000000 --!00, 000001, 000020, 000000, 03 + d=000003 --! + d=000000 --!00, 000001, 000021, 000000, 02 + d=000002 --! + d=000000 --!00, 000001, 000036, 000000, 02 + d=000002 --! +#37240 + d=000000 --!00, 000001, 000037, 000000, 12 + d=000012 --! + d=000000 --!00, 000001, 000040, 000000, 04 {right shift!} + d=000004 --! + d=000000 --!00, 000001, 010037, 000000, 04 {right shift!} + d=000012 --! !!04->12 +# left rotate negative numbers + d=000002 --!00, 100001, 000001, 000002, 03 + d=000003 --! +#37260 + d=100002 --!00, 140001, 000001, 100002, 11 + d=000011 --! + d=000004 --!00, 140001, 000002, 000004, 03 + d=000003 --! + d=040000 --!00, 140001, 000016, 040000, 02 + d=000002 --! + d=100000 --!00, 140001, 000017, 100000, 12 + d=000012 --! +#37300 + d=000000 --!00, 140001, 000020, 000000, 13 + d=000013 --! + d=000000 --!00, 140001, 000021, 000000, 13 + d=000013 --! + d=000000 --!00, 140001, 000022, 000000, 03 + d=000003 --! + d=000000 --!00, 140001, 000023, 000000, 02 + d=000002 --! +#37320 + d=000000 --!00, 140002, 000035, 000000, 02 + d=000002 --! + d=000000 --!00, 140002, 000036, 000000, 12 + d=000012 --! + d=000000 --!00, 140002, 000037, 000000, 07 + d=000007 --! +#----------------------------------------------------------------------------- +C Setup code 43 [base 12700] (Begemot MARK instruction test) +# test data and code adapted from Mark.s11 code of Begemot p11-2.10c +# +wal 012700 -- code test 1: (basics) +bwm 14 + 012705 -- mov #77077,r5 ; cookie + 077077 + 010546 -- mov r5,-(sp) ; push r5 + 012746 -- mov #12,-(sp) ; parameter 1 + 000012 + 012746 -- mov #23,-(sp) ; parameter 2 + 000023 + 012746 -- mov #mark+2,-(sp) ; now the mark instruction +#12720 + 006402 + 010605 -- mov sp,r5 ; let r5 point to mark instruction + 004737 -- jsr pc,subr ; call subroutine + 012770 + 000240 -- noop + 000000 -- halt +#----- +wal 012740 -- code test 2: (MARK with max. # of args) +bwm 10 + 010546 -- mov r5, -(sp) ; push r5 + 162706 -- sub #2*77, sp ; max number + 000176 + 012746 -- mov #mark+77, -(sp) ; the mark instruction + 006477 + 010605 -- mov sp, r5 ; let r5 point to mark instruction + 004737 -- jsr pc, subr ; call subroutine + 012770 +#12760 + 000240 -- noop + 000000 -- halt +#----- +wal 012770 -- code (procedure): +wmi 000205 -- subr: rts r5 +#----- +C Exec code 43 (Begemot MARK test) +C Exec test 43.1 (basics) +# D RE RQ FU DAT +wsp 001400 -- sp=1400 +stapc 012700 -- start @ 12700 +wtgo +rpc d=012734 -- ! pc +rr5 d=077077 -- ! r5 +rsp d=001400 -- ! sp +wal 001366 -- +brm 5 + d=012730 -- ! mem(1366) + d=006402 -- ! mem(1370) + d=000023 -- ! mem(1372) + d=000012 -- ! mem(1374) + d=077077 -- ! mem(1376) +#---- +C Exec test 43.2 (MARK with max. # of args) +# D RE RQ FU DAT +wsp 001400 -- sp=1400 +stapc 012740 -- start @ 12740 +wtgo +rpc d=012764 -- ! pc +rr5 d=077077 -- ! r5 +rsp d=001400 -- ! sp +#----------------------------------------------------------------------------- +C Setup code 44 [base 13000] (Implementation variations) +# test various PDP11 implementation variations (DCJ11 user guide, table C-1) +# +wal 013000 -- code: (to be single stepped mostly) +bwm 22 + 010424 -- mov r4,(r4)+ ; case 1 and 2 + 010444 -- mov r4,-(r4) + 010764 -- mov pc,2(r4) + 000002 + 000124 -- jmp (r4)+ + 000104 -- jmp r4 + 000304 -- swab r4 + 005214 -- inc (r4) +#13020 + 000006 -- rtt + 000000 -- halt + 000002 -- rti + 000000 -- halt + 010011 -- mov r0,(r1) + 010046 -- mov r0,-(sp) + 000114 -- jmp (r4) + 010021 -- mov r0,(r1)+ +#13040 + 012100 -- mov (r1)+,r0 + 005221 -- inc (r1)+ + 106621 -- mtpd (r1)+ + 106506 -- mfpd sp + 106606 -- mtpd sp + 000003 -- bpt +#----- +wal 013070 -- code: (target for rtt,rti tests) +bwm 2 + 000240 -- noop + 000000 -- halt +#----- +C Exec code 44 (Implementation variations) +C test 44.1: OPR R,(R)+ : incremented before {J11} or after {70} use as source +# +rst -- console reset +wps 000000 -- clear psw +wr4 001600 -- r4=1600 +wsp 001400 -- sp=1400 +wpc 013000 -- pc=13000 +step -- step (mov r4,(r4)+) +rpc d=013002 -- ! pc=13002 +rr4 d=001602 -- ! r4=1602 +wal 001600 -- check target location +rmi d=001600 -- ! ; initial content of R expected for 11/70 +# +C test 44.2: OPR R,-(R) : decremented before {J11} or after {70} use as source +# +wr4 001600 -- r4=1600 +wsp 001400 -- sp=1400 +wpc 013002 -- pc=13002 +step -- step (mov r4,-(r4)) +rpc d=013004 -- ! pc=13004 +rr4 d=001576 -- ! r4=1576 +wal 001600 -- check target location +rmi d=001600 -- ! ; initial content of R expected for 11/70 +# +C test 44.3: OPR PC,A(R) : store PC+2 {70} or PC+4 {J11} +# +wr4 001600 -- r4=1600 +wsp 001400 -- sp=1400 +wpc 013004 -- pc=13004 +step -- step (mov pc,2(r4)) +rpc d=013010 -- ! pc=13010 +wal 001602 -- check target location +rmi d=013006 -- ! ; PC+2 expected for 11/70 +# +C test 44.4: JMP (R)+ : R used {70;J11} or R+2 used {05,10,15,20} +# +wr4 013074 -- r4=13074 +wsp 001400 -- sp=1400 +wpc 013010 -- pc=13010 +step -- step (jmp (r4)+) +rpc d=013074 -- ! pc=13074 ; R expected for 11/70 +rr4 d=013076 -- ! r4=13076 +# +C test 44.5: JMP R : traps to 10 {44,45,70;J11} or 4 {all others} +C Note: J11 doc is wrong, 11/70 traps 10, not 4, as stated +# +wal 177766 -- clear CPUERR +wm 000000 -- +wr4 000000 -- r4=0 +wsp 001400 -- sp=1400 +wpc 013012 -- pc=13012 +step -- step (jmp r4) [[s:2]] +rpc d=000012 -- ! pc=12 ; trap 10 expected for 11/70 [[s:10]] +rsp d=001374 -- ! sp=1374 +wal 177766 -- check CPUERR +rm d=000000 -- ! CPUERR: no bit set +wm 000000 -- clear CPUERR +# +C test 44.6: SWAB does not change V {15,20} or clears V {all others} +# +wr4 000300 -- r4=3000 +wsp 001400 -- sp=1400 +wpc 013014 -- pc=13014 +wps 000017 -- psw: set all cc flags in psw +step -- step (swab r4) +rpc d=013016 -- ! pc=13074 +rr4 d=140000 -- ! r4=140000 +rps d=000004 -- ! psw: Z=1 ; clear V expected for 11/70 +# +C test 44.7: CPU access to 177700-177717 (regs) timesout {70,J11} or not {05,10} +# +wr4 177700 -- r4=177700 +wsp 001400 -- sp=1400 +wpc 013016 -- pc=13016 +step -- step (inc (r4)) [[s:2]] +rpc d=000006 -- ! pc=6 ; trap 4 expected for 11/70 [[s:10]] +rsp d=001374 -- ! sp=1374 +wal 177766 -- check CPUERR +rm d=000020 -- ! CPUERR: (iobto=1) +wm 000000 -- clear CPUERR +# +C test 44.10: If RTT sets T bit, trap occurs after instr. following RTT {70,J11} +# +wal 001374 -- setup stack with rtt return frame setting T flag +bwm 2 + 013070 -- start address (points to: noop, halt) + 000020 -- set T flag in PSW +wsp 001374 -- sp=1374 +wpc 013020 -- pc=13020 +cont -- cont (rtt) +wtgo +rpc d=000020 -- ! pc=20 ; T-trap executed +rsp d=001374 -- ! sp=1374 +wal 001374 -- check stack +brm 2 + d=013072 -- trap address: address after noop expected for 11/70 + d=000020 -- PSW +rst -- console reset (to clear T flag) +# +C test 44.11: If RTI sets T bit, T trap occurs immediately {70,J11} +# +wal 001374 -- setup stack with rtt return frame setting T flag +bwm 2 + 013070 -- start address (points to: noop, halt) + 000020 -- set T flag in PSW +wsp 001374 -- sp=1374 +wpc 013024 -- pc=13024 +cont -- cont (rti) +wtgo +rpc d=000020 -- ! pc=20 ; T-trap executed +rsp d=001374 -- ! sp=1374 +wal 001374 -- check stack +brm 2 + d=013070 -- trap address: address of noop expected for 11/70 + d=000020 -- PSW +rst -- console reset (to clear T flag) +# +C test 44.14: Direct access to PSW can {05..20} / cannot {others} set T bit +# +wr0 000030 -- r0=30 (set T bit, N also) +wr1 177776 -- r1=177776 (PSW address) +wsp 001400 -- sp=1400 +wpc 013030 -- pc=13030 +step -- step (mov r0,(r1)) +rpc d=013032 -- ! pc=13032 +rps d=000010 -- ! psw: T bit not set expected for 11/70 +# +C test 44.15: odd address using SP causes HALT {<=20} or emmergency stack {>35} +# +wsp 001401 -- sp=1401 +wpc 013032 -- pc=13032 +step -- step (mov r0,-(sp)) [[s:2]] +rpc d=000006 -- ! pc=6 ; trap 4 [[s:13034]] +rsp d=000000 -- ! sp=0 ; emergency stack expected for 11/70 [[s:4]] +wal 000000 -- check emergency stack +brm 2 + d=013034 -- ! PC of abort [[s:0]] + d=000000 -- ! PS of abort (currently gets lost...) +rst -- console reset (to clear CPUERR reg) +wal 000000 -- clean tainted memory +bwm 2 + 000000 -- + 000000 -- +# +# simh notes: +# 1. apparently not consistently implemented in simh. SP is set to 4, but +# interrupt/trap sequence isn't executed. Effectively, simh halt's. +# +# for the test 28/29/30x enable MMU and make address 100000 unavailable +# +wal 172310 -- kernel I space DR segment 4 (base 100000) +wmi 077400 -- slf=127; ed=0(up); acf=0 (non resident) +# +C test 44.28: If PC->bad memory, PC incremented {others} / not inc'ed {35,40} +# +wal 177572 -- SSR0 +wmi 000001 -- set enable bit +wr4 100000 -- r4=100000 +wsp 001400 -- sp=1400 +wpc 013034 -- pc=13034 +cont -- cont (jmp (r4)) +wtgo +rpc d=000254 -- ! pc=254 ; trap 240 ; Note: halt is executed, was cont ! +rsp d=001374 -- ! sp=1374 +wal 001374 -- check stack +brm 2 + d=100002 -- trap address: PC inc'ed expected for 11/70 [[s:100000]] + d=000340 -- PSW +rst -- console reset (to clear CPUERR reg) +# +# simh notes: +# 1. simh reads instruction, later increments PC. Thus PC not inc'ed in simh. +# +C test 44.29/30a: If R->bad in mode 2, R inc'ed {others} / or not {4,34,44} +C test for dstw chain (mov r0,(r1)+) +# +wal 177572 -- SSR0 +wmi 000001 -- set enable bit +wr1 100000 -- r1=100000 +wsp 001400 -- sp=1400 +wpc 013036 -- pc=13036 +step -- step (mov r0,(r1)+) [[s:2]] +rpc d=000252 -- ! pc=252 ; trap 250 [[s:254]] +rsp d=001374 -- ! sp=1374 +rr1 d=100002 -- ! r1=100002 +wal 177572 -- check SSR0/1 +brm 2 + d=100011 -- ! SSR0: (abo_nonres=1,seg=4,ena=1) see note [[s:100211]] + d=000021 -- ! SSR1: ra=1,2 +rst -- console reset (to clear CPUERR reg) +# +C test 44.29/30b: If R->bad in mode 2, R inc'ed {others} / or not {4,34,44} +C test for srcr chain (mov (r1)+,r0) +# +wal 177572 -- SSR0 +wmi 000001 -- set enable bit +wr1 100000 -- r1=100000 +wsp 001400 -- sp=1400 +wpc 013040 -- pc=13040 +step -- step ((mov (r1)+,r0) [[s:2]] +rpc d=000252 -- ! pc=252 ; trap 250 [[s:254]] +rsp d=001374 -- ! sp=1374 +rr1 d=100002 -- ! r1=100002 +wal 177572 -- check SSR0/1 +brm 2 + d=100011 -- ! SSR0: (abo_nonres=1,seg=4,ena=1) see note [[s:100211]] + d=000021 -- ! SSR1: ra=1,2 +rst -- console reset (to clear CPUERR reg) +# +C test 44.29/30c: If R->bad in mode 2, R inc'ed {others} / or not {4,34,44} +C test for dstr chain (inc (r1)+) +# +wal 177572 -- SSR0 +wmi 000001 -- set enable bit +wr1 100000 -- r1=100000 +wsp 001400 -- sp=1400 +wpc 013042 -- pc=13042 +step -- step (inc (r1)+) [[s:2]] +rpc d=000252 -- ! pc=252 ; trap 250 [[s:254]] +rsp d=001374 -- ! sp=1374 +rr1 d=100002 -- ! r1=100002 +wal 177572 -- check SSR0/1 +brm 2 + d=100011 -- ! SSR0: (abo_nonres=1,seg=4,ena=1) see note [[s:100211]] + d=000021 -- ! SSR1: ra=1,2 +rst -- console reset (to clear CPUERR reg) +C test 44.29/30d: If R->bad in mode 2, R inc'ed {others} / or not {4,34,44} +C test for dsta chain (mtpd (r1)+) +# +wal 177572 -- SSR0 +wmi 000001 -- set enable bit +wr1 100000 -- r1=100000 +wsp 001376 -- sp=1376 +wpc 013044 -- pc=13044 +wal 001376 -- push a word on stack for mtpd +wmi 123456 -- +step -- step (mtpd (r1)+) [[s:2]] +rpc d=000252 -- ! pc=252 ; trap 250 [[s:254]] +rsp d=001374 -- ! sp=1374 +rr1 d=100002 -- ! r1=100002 +wal 177572 -- check SSR0/1 +brm 2 + d=100011 -- ! SSR0: (abo_nonres=1,seg=4,ena=1) see note [[s:100211]] + d=010426 -- ! SSR1: rb=1,2; ra=6,2 +rst -- console reset (to clear CPUERR reg) +# +# simh notes: +# 1. simh first pops, than writes to destination, reversing ra,rb in SSR1 +# +# now reset MMU to default +# +wal 172310 -- kernel I space DR segment 4 (base 100000) +wmi 077406 -- slf=127; ed=0(up); acf=6 (r/w) +# +C test 44.39: cmode=10 will cause abort {70,J11}, treated as kmode {23,24} +# +wal 177572 -- SSR0 +wmi 000001 -- set enable bit +wr1 001400 -- r1=1400 +wsp 001400 -- sp=1400 +wps 100000 -- psw: set cm=10, pm=00 +wpc 013042 -- pc=13042 +step -- step (inc (r1)+) [[s:2]] +rpc d=000252 -- ! pc=252 ; trap 250; as expected for 11/70 [[s:254]] +rsp d=001374 -- ! sp=1374 +rr1 d=001400 -- ! r1=1400 +wal 177572 -- check SSR0/1 +brm 3 + d=140101 -- ! SSR0: (abo_nr=1,abo_l=1,m=10,seg=0,ena=1) [[s:140301]] + d=000000 -- ! SSR1: ra=none + d=013042 -- ! SSR2: PC of failed instruction +wal 001374 -- check stack +brm 2 + d=013044 -- ! PC after failed instruction [[s:013042]] + d=100000 -- ! PS +rst -- console reset (to clear CPUERR reg, PSW) +# +# simh notes: +# 1. simh saves PC of failed instruction on stack, not PC after instruction +# +C test 44.43: user mode HALT: trap 4 {70} or 10 {others} +# +wal 177766 -- check CPUERR ;??? remove if console reset fixed +wm 000000 -- clear +wsp 001400 -- sp=1400 +wps 170000 -- psw: set cm=11, pm=11 +wpc 013022 -- pc=13022 +step -- step (halt in user mode) [[s:2]] +rpc d=000006 -- ! pc=6 ; trap 4; as expected for 11/70 [[s:10]] +rsp d=001374 -- ! sp=1374 +wal 001374 -- check stack +brm 2 + d=013024 -- ! PC after failed instruction + d=170000 -- ! PS +wal 177766 -- check CPUERR +rm d=000200 -- ! CPUERR: (illhalt=1) +rst -- console reset (to clear CPUERR reg, PSW) +# +C test 44.44: PDR bit<0> implemented {70} or not {others} +# +wal 172310 -- kernel I space DR, segment 4 +wm 077401 -- set acf bit 0: slf=127; ed=0(up); acf=1 (r+trap) +rm d=077401 -- ! check; works as expected for 11/70 +wm 077406 -- restore: slf=127; ed=0(up); acf=6(w/r) +# +C test 44.45: PDR bit<7>(AIB any access) implemented {70} or not {others} +# +wal 172300 -- kernel I space DR, reset segment 0 and 1 +bwm 2 + 077404 -- slf=127; ed=0(up); acf=4(w/r and trap) + 077404 -- slf=127; ed=0(up); acf=4(w/r and trap) +wal 172300 -- check kernel I space DR, segment 0 and 1 +brm 2 + d=077404 -- ! + d=077404 -- ! +wal 177572 -- SSR0 +wmi 000001 -- set enable bit +wr0 123456 -- r0=123456 +wr1 030000 -- r1=30000 +wsp 001400 -- sp=1400 +wpc 013030 -- pc=13030 +step -- step (mov r0,(r1)) +rpc d=013032 -- ! pc=next +rsp d=001400 -- ! sp=1400 +wal 030000 -- check target memory, untaint +rm d=123456 -- ! +wm 000000 -- +wal 172300 -- check kernel I space DR, segment 0 and 1 +brm 2 + d=077604 -- ! slf=127; ed=0(up); acf=4(w/r+trap); aib=10 (A=1,W=0) + d=077704 -- ! slf=127; ed=0(up); acf=4(w/r+trap); aib=11 (A=1,W=1) +wal 172300 -- kernel I space DR, reset segment 0 and 1 +bwm 2 + 077406 -- slf=127; ed=0(up); acf=6(w/r) + 077406 -- slf=127; ed=0(up); acf=6(w/r) +rst -- console reset (to clear CPUERR reg) +# +C test 44.46: Full PAR implemented {44,70,J11} or not {others} +# +wal 172350 -- kernel I space AR, segment 4 +wm 177777 -- set all bits +rm d=177777 -- ! check; works as expected for 11/70 +wm 001000 -- restore: 1000 100000 base +# +C test 44.47: MMR0<9>(mmu trap) implemented {70} or not {others} +# +wal 177572 -- SSR0 +wm 001000 -- set trap enable +rm d=001000 -- ! check; works as expected for 11/70 +wm 000000 -- restore +# +C test 44.48: MMR3<2:0>(D space) implemented {44,70,J11} or not {others} +# +wal 172516 -- SSR3 +wm 000007 -- set D space bis +rm d=000007 -- ! check; works as expected for 11/70 +wm 000000 -- restore +# +C test 44.49: MMR3<5:4>(UMAP, 22 bit) implemented {44,70,J11} or not {others} +# +wal 172516 -- SSR3 +wm 000060 -- set D space bits +rm d=000060 -- ! check; available, as expected for 11/70 +wm 000000 -- restore +# +C test 44.50: MMR3<3>(CSM enable) implemented {44,J11} or not {others} +# +wal 172516 -- SSR3 +wm 000010 -- set D space bit +rm d=000000 -- ! check; not available, as expected for 11/70 +wm 000000 -- restore +# +C test 44.51: MMR2 tracks fetches {70} or instructions only {others} +C here W11 behaves like {others}, fetches are not tracked in SSR2 +C Also: instruction complete flag set in SSR0 after bpt. +# +wal 177572 -- SSR0 +wmi 000001 -- set enable bit +wsp 001400 -- sp=1400 +wpc 013052 -- pc=13052 +step -- step (bpt) +rpc d=000016 -- ! pc=16; trap 14 see note [[s:13054]] +wal 177572 -- check SSR0/1/2 +brm 3 + d=000001 -- ! SSR0: (ena=1) + d=000000 -- ! SSR1: ra=none + d=013052 -- ! SSR2: PC of bpt +step -- step (halt) +rpc d=000020 -- ! pc=20 (after halt) +wal 177572 -- check SSR0/1/2 +brm 3 + d=000001 -- ! SSR0: (ena=1) + d=000000 -- ! SSR1: ra=none + d=000016 -- ! SSR2: PC of halt +rst -- console reset (to clear CPUERR reg, PSW) +# +# simh notes: +# 1. when simh steps over a BPT,IOT,..., the PC is pointing after the +# instruction. The trap sequence together with first instruction is +# executed in next step. +# +C test 44.52: MT/FPx SP for pmode=10 unpredictable {others} / user SP {J11} +# write registers +# +wr0 000001 -- set r0,..,r7 +wr1 000101 -- +wr2 000201 -- +wr3 000301 -- +wr4 000401 -- +wr5 000501 -- +wsp 001400 -- +wpc 000701 -- +# write register set 1, sm,um stack +# +wps 004000 -- psw: cm=kernel, set=1 +wr0 010001 -- set r0,..,r5 [[r10]] +wr1 010101 -- [[r11]] +wr2 010201 -- [[r12]] +wr3 010301 -- [[r13]] +wr4 010401 -- [[r14]] +wr5 010501 -- [[r15]] +wps 044000 -- psw: cm=super(01),set=1 +wsp 010601 -- set ssp [[ssp]] +wps 144000 -- psw: cm=user(11),set=1 +wsp 110601 -- set usp [[usp]] +# +C 52a: MFPS for pmode=10 +# +wps 020000 -- psw: set cm=00, pm=10 +wpc 013046 -- pc=13046 +step -- step (mfpd sp) +rpc d=013050 -- ! pc=next +rsp d=001376 -- ! sp=1376 +wal 001376 -- check stack +rmi d=013046 -- ! it returns PC like 11/70 unpredictable [[s:0]] +rst -- console reset (to clear CPUERR reg) +# +# simh note: +# 1. simh returns 0 here, just unpredictable in a different way ... +# +C 52a: MTPS for pmode=10 +# +wal 001376 -- setup stack with value for mtpd +wmi 123446 -- +wps 020000 -- psw: set cm=00, pm=10 +wpc 013050 -- pc=13050 +step -- step (mtpd sp) +rpc d=013052 -- ! pc=next +rsp d=001400 -- ! sp=1400 +# check registers +# +rr0 d=000001 -- ! r0,..,r7 +rr1 d=000101 -- ! +rr2 d=000201 -- ! +rr3 d=000301 -- ! +rr4 d=000401 -- ! +rr5 d=000501 -- ! +# check register set 1, sm,um stack +# +wps 004000 -- psw: cm=kernel, set=1 +rr0 d=010001 -- ! r0,..,r5 [[r10]] +rr1 d=010101 -- ! [[r11]] +rr2 d=010201 -- ! [[r12]] +rr3 d=010301 -- ! [[r13]] +rr4 d=010401 -- ! [[r14]] +rr5 d=010501 -- ! [[r15]] +wps 044000 -- psw: cm=super(01),set=1 +rsp d=010601 -- ! ssp [[ssp]] +wps 144000 -- psw: cm=user(11),set=1 +rsp d=110601 -- ! usp [[usp]] +# --> all preset values intact; -> mtpd thus noop --> like 11/70 unpredictable +# +rst -- console reset (to clear CPUERR reg) +# +# simh notes on MMR0: +# 1. simh doesn't freeze MMR0 bit 7, the instr.compl. bit is set again after +# executing first instruction of trap handler. +# +#----------------------------------------------------------------------------- +C Setup code 45 [base 13100] (mmr1 and instructions with implicit stack push/pop +# +wal 013100 -- code: (to be single stepped mostly) +bwm 5 + 106621 -- mtpd (r1)+ + 106521 -- mfpd (r1)+ + 004721 -- jsr pc,(r1)+ + 000000 -- halt +#13110 + 000207 -- rts pc +#----- +C Exec code 45 (mmr1 and instructions with implicit stack push/pop) +C test 45.1: mtpd (r1)+ +# +wal 177572 -- SSR0 +wmi 000001 -- set enable bit +wal 001376 -- setup stack with value for mtpd +wmi 123456 -- +wr1 030000 -- r1=30000 +wsp 001376 -- sp=1376 +wpc 013100 -- pc=13100 +step -- step (mtpd (r1)+) +rpc d=013102 -- ! pc=next +rsp d=001400 -- ! sp=1400 +rr1 d=030002 -- ! r1=30002 +wal 177572 -- check SSR0/1/2 +brm 3 + d=000003 -- ! SSR0: (seg=1,ena=1) + d=010426 -- ! SSR1: rb=1,2; ra=6,2 + d=013100 -- ! SSR2: PC of mtpd +wal 030000 -- check target memory +rm d=123456 -- ! +rst -- console reset +# +C test 45.2: mfpd (r1)+ +# +wal 177572 -- SSR0 +wmi 000001 -- set enable bit +wr1 030000 -- r1=30000 +wsp 001400 -- sp=1400 +wpc 013102 -- pc=13102 +step -- step (mfpd (r1)+) +rpc d=013104 -- ! pc=next +rsp d=001376 -- ! sp=1376 +rr1 d=030002 -- ! r1=30002 +wal 177572 -- check SSR0/1/2 +brm 3 + d=000001 -- ! SSR0: (seg=0,ena=1) + d=173021 -- ! SSR1: rb=6,-2; ra=1,2 + d=013102 -- ! SSR2: PC of mtpd +wal 001376 -- check stack +rmi d=123456 -- ! +wal 030000 -- clear tainted target memory +wm 000000 -- +rst -- console reset +# +C test 45.3: jsr pc,(r1)+ and rts pc +# +wal 177572 -- SSR0 +wmi 000001 -- set enable bit +wr1 013110 -- r1=13110 +wsp 001400 -- sp=1400 +wpc 013104 -- pc=13104 +step -- step (jsr pc,(r1)+) +rpc d=013110 -- ! pc=target +rsp d=001376 -- ! sp=1376 +rr1 d=013112 -- ! r1=13112 +wal 177572 -- check SSR0/1/2 +brm 3 + d=000001 -- ! SSR0: (seg=0,ena=1) + d=173021 -- ! SSR1: rb=6,-2; ra=1,2 + d=013104 -- ! SSR2: PC of jsr +wal 001376 -- check stack +rmi d=013106 -- ! PC after jsr +step -- step (rts pc) +rpc d=013106 -- ! pc=target +rsp d=001400 -- ! sp=1400 +wal 177572 -- check SSR0/1/2 +brm 3 + d=000001 -- ! SSR0: (seg=0,ena=1) + d=000026 -- ! SSR1: ra=6,2 [[s:0]] + d=013110 -- ! SSR2: PC of rts +rst -- console reset +# +# simh notes: +# 1. simh reads stack and incremets sp later. In case of an MMU abort on +# stack read, simh SSR1 will be 0, while W11 shows the sp increment +# +#----------------------------------------------------------------------------- +C Setup code 46 [base 13200] (systematic result+cc test of 1+2op instructions) +# the following codes expect: +# r0-> psw +# r1-> loop count +# r2-> input ptr +# r3-> output ptr +# r4-> src reg +# r5-> dst reg +# +wal 013200 -- code 1: test 1op register +bwm 8 + 000230 -- spl 0 + 012205 -- L1: mov (r2)+,r5 ; load dst + 000000 -- halt ; ccmov set cc's + 000000 -- halt ; iut instr. under test + 011023 -- mov (r0),(r3)+ ; save psw + 010523 -- mov r5,(r3)+ ; save dst + 077106 -- sob r1,L1 (.-6) + 000000 -- halt +#---- +wal 013220 -- code 2: test 1op memory +bwm 8 + 000230 -- spl 0 + 012215 -- L1: mov (r2)+,(r5) ; load dst + 000000 -- halt ; ccmov set cc's + 000000 -- halt ; iut instr. under test + 011023 -- mov (r0),(r3)+ ; save psw + 011523 -- mov (r5),(r3)+ ; save dst + 077106 -- sob r1,L1 (.-6) + 000000 -- halt +#----- +wal 013240 -- code 3: test 2op register +bwm 9 + 000230 -- spl 0 + 012204 -- L1: mov (r2)+,r4 ; load src + 012205 -- mov (r2)+,r5 ; load dst + 000000 -- halt ; ccmov set cc's + 000000 -- halt ; iut instr. under test + 011023 -- mov (r0),(r3)+ ; save psw + 010523 -- mov r5,(r3)+ ; save dst + 077107 -- sob r1,L1 (.-7) +#13260 + 000000 -- halt +#----- +wal 013270 -- code 4: test 2op memory +bwm 9 + 000230 -- spl 0 + 012214 -- L1: mov (r2)+,(r4) ; load src + 012215 -- mov (r2)+,(r5) ; load dst + 000000 -- halt ; ccmov set cc's +#13300 + 000000 -- halt ; iut instr. under test + 011023 -- mov (r0),(r3)+ ; save psw + 011523 -- mov (r5),(r3)+ ; save dst + 077107 -- sob r1,L1 (.-7) + 000000 -- halt +#---- +C Exec code 46 pass 1 (systematic result+cc test of 1+2op instructions; word) +C Exec test 46.1wr: COM - reg +# +wal 036000 -- setup test vector: for com,inc,dec,neg,adc,sbc,tst +bwm 5 + 000000 -- com 000000 + 000001 -- com 000001 + 077777 -- com 077777 + 100000 -- com 100000 + 177777 -- com 177777 +wal 013204 -- setup test instructions: +bwm 2 + 000241 -- ccmov= clc + 005105 -- iut= com r5 +wr0 177776 -- r0=177776 +wr1 000005 -- r1=5 +wr2 036000 -- r2=36000 +wr3 037000 -- r3=37000 +wr4 000000 -- r4=0 +wr5 000000 -- r5=0 +wsp 001400 -- sp=1400 +stapc 013200 -- start @ 13200 (1op reg) +wtgo +rpc d=013220 -- ! pc=halt +rr1 d=000000 -- ! r1=0 +wal 037000 -- check result area +brm 10 + d=000011 -- ! com 000000 -> n1z0v0c1; 177777 + d=177777 -- ! + d=000011 -- ! com 000001 -> n1z0v0c1; 177776 + d=177776 -- ! + d=000011 -- ! com 077777 -> n1z0v0c1; 100000 + d=100000 -- ! + d=000001 -- ! com 100000 -> n0z0v0c1; 077777 + d=077777 -- ! + d=000005 -- ! com 177777 -> n0z1v0c1; 000000 + d=000000 -- ! +#-------- +C Exec test 46.1wm: COM - mem +# +wal 013224 -- setup test instructions: +bwm 2 + 000241 -- ccmov= clc + 005115 -- iut= com (r5) +wr0 177776 -- r0=177776 +wr1 000005 -- r1=5 +wr2 036000 -- r2=36000 +wr3 037000 -- r3=37000 +wr4 001400 -- r4=1400 +wr5 001402 -- r5=1402 +wsp 001400 -- sp=1400 +stapc 013220 -- start @ 13220 (1op mem) +wtgo +rpc d=013240 -- ! pc=halt +rr1 d=000000 -- ! r1=0 +wal 037000 -- check result area +brm 10 + d=000011 -- ! com 000000 -> n1z0v0c1; 177777 + d=177777 -- ! + d=000011 -- ! com 000001 -> n1z0v0c1; 177776 + d=177776 -- ! + d=000011 -- ! com 077777 -> n1z0v0c1; 100000 + d=100000 -- ! + d=000001 -- ! com 100000 -> n0z0v0c1; 077777 + d=077777 -- ! + d=000005 -- ! com 177777 -> n0z1v0c1; 000000 + d=000000 -- ! +#-------- +C Exec test 46.2wrc0: INC - reg,C=0 +# +wal 013204 -- setup test instructions: +bwm 2 + 000241 -- ccmov= clc + 005205 -- iut= inc r5 +wr0 177776 -- r0=177776 +wr1 000005 -- r1=5 +wr2 036000 -- r2=36000 +wr3 037000 -- r3=37000 +wr4 000000 -- r4=0 +wr5 000000 -- r5=0 +wsp 001400 -- sp=1400 +stapc 013200 -- start @ 13200 (1op reg) +wtgo +rpc d=013220 -- ! pc=halt +rr1 d=000000 -- ! r1=0 +wal 037000 -- check result area +brm 10 + d=000000 -- ! inc 000000 -> n0z0v0c0; 000001 + d=000001 -- ! + d=000000 -- ! inc 000001 -> n0z0v0c0; 000002 + d=000002 -- ! + d=000012 -- ! inc 077777 -> n1z0v1c0; 100000 + d=100000 -- ! + d=000010 -- ! inc 100000 -> n1z0v0c0; 100001 + d=100001 -- ! + d=000004 -- ! inc 177777 -> n0z1v0c0; 000000 + d=000000 -- ! +#-------- +C Exec test 46.2wrc1: INC - reg,C=1 +# +wal 013204 -- setup test instructions: +bwm 2 + 000261 -- ccmov= sec + 005205 -- iut= inc r5 +wr0 177776 -- r0=177776 +wr1 000005 -- r1=5 +wr2 036000 -- r2=36000 +wr3 037000 -- r3=37000 +wr4 000000 -- r4=0 +wr5 000000 -- r5=0 +wsp 001400 -- sp=1400 +stapc 013200 -- start @ 13200 (1op reg) +wtgo +rpc d=013220 -- ! pc=halt +rr1 d=000000 -- ! r1=0 +wal 037000 -- check result area +brm 10 + d=000001 -- ! inc 000000 -> n0z0v0c1; 000001 + d=000001 -- ! + d=000001 -- ! inc 000001 -> n0z0v0c1; 000002 + d=000002 -- ! + d=000013 -- ! inc 077777 -> n1z0v1c1; 100000 + d=100000 -- ! + d=000011 -- ! inc 100000 -> n1z0v0c1; 100001 + d=100001 -- ! + d=000005 -- ! inc 177777 -> n0z1v0c1; 000000 + d=000000 -- ! +#-------- +C Exec test 46.3wrc0: DEC - reg,C=0 +# +wal 013204 -- setup test instructions: +bwm 2 + 000241 -- ccmov= clc + 005305 -- iut= dec r5 +wr0 177776 -- r0=177776 +wr1 000005 -- r1=5 +wr2 036000 -- r2=36000 +wr3 037000 -- r3=37000 +wr4 000000 -- r4=0 +wr5 000000 -- r5=0 +wsp 001400 -- sp=1400 +stapc 013200 -- start @ 13200 (1op reg) +wtgo +rpc d=013220 -- ! pc=halt +rr1 d=000000 -- ! r1=0 +wal 037000 -- check result area +brm 10 + d=000010 -- ! dec 000000 -> n1z0v0c0; 177777 + d=177777 -- ! + d=000004 -- ! dec 000001 -> n0z1v0c0; 000000 + d=000000 -- ! + d=000000 -- ! dec 077777 -> n0z0v0c0; 077776 + d=077776 -- ! + d=000002 -- ! dec 100000 -> n0z0v1c0; 077777 + d=077777 -- ! + d=000010 -- ! dec 177777 -> n1z0v0c0; 177776 + d=177776 -- ! +#-------- +C Exec test 46.3wrc1: DEC - reg,C=1 +# +wal 013204 -- setup test instructions: +bwm 2 + 000261 -- ccmov= sec + 005305 -- iut= dec r5 +wr0 177776 -- r0=177776 +wr1 000005 -- r1=5 +wr2 036000 -- r2=36000 +wr3 037000 -- r3=37000 +wr4 000000 -- r4=0 +wr5 000000 -- r5=0 +wsp 001400 -- sp=1400 +stapc 013200 -- start @ 13200 (1op reg) +wtgo +rpc d=013220 -- ! pc=halt +rr1 d=000000 -- ! r1=0 +wal 037000 -- check result area +brm 10 + d=000011 -- ! dec 000000 -> n1z0v0c1; 177777 + d=177777 -- ! + d=000005 -- ! dec 000001 -> n0z1v0c1; 000000 + d=000000 -- ! + d=000001 -- ! dec 077777 -> n0z0v0c1; 077776 + d=077776 -- ! + d=000003 -- ! dec 100000 -> n0z0v1c1; 077777 + d=077777 -- ! + d=000011 -- ! dec 177777 -> n1z0v0c1; 177776 + d=177776 -- ! +#-------- +C Exec test 46.4wr: NEG - reg +# +wal 013204 -- setup test instructions: +bwm 2 + 000241 -- ccmov= clc + 005405 -- iut= neg r5 +wr0 177776 -- r0=177776 +wr1 000005 -- r1=5 +wr2 036000 -- r2=36000 +wr3 037000 -- r3=37000 +wr4 000000 -- r4=0 +wr5 000000 -- r5=0 +wsp 001400 -- sp=1400 +stapc 013200 -- start @ 13200 (1op reg) +wtgo +rpc d=013220 -- ! pc=halt +rr1 d=000000 -- ! r1=0 +wal 037000 -- check result area +brm 10 + d=000004 -- ! neg 000000 -> n0z1v0c0; 000000 + d=000000 -- ! + d=000011 -- ! neg 000001 -> n1z0v0c1; 177777 + d=177777 -- ! + d=000011 -- ! neg 077777 -> n1z0v0c1; 100001 + d=100001 -- ! + d=000013 -- ! neg 100000 -> n1z0v1c1; 100000 + d=100000 -- ! + d=000001 -- ! neg 177777 -> n0z0v0c1; 000001 + d=000001 -- ! +#-------- +C Exec test 46.5wrc0: ADC - reg,C=0 +# +wal 013204 -- setup test instructions: +bwm 2 + 000241 -- ccmov= clc + 005505 -- iut= adc r5 +wr0 177776 -- r0=177776 +wr1 000005 -- r1=5 +wr2 036000 -- r2=36000 +wr3 037000 -- r3=37000 +wr4 000000 -- r4=0 +wr5 000000 -- r5=0 +wsp 001400 -- sp=1400 +stapc 013200 -- start @ 13200 (1op reg) +wtgo +rpc d=013220 -- ! pc=halt +rr1 d=000000 -- ! r1=0 +wal 037000 -- check result area +brm 10 + d=000004 -- ! adc 000000 -> n0z1v0c0; 000000 + d=000000 -- ! + d=000000 -- ! adc 000001 -> n0z0v0c0; 000001 + d=000001 -- ! + d=000000 -- ! adc 077777 -> n0z0v0c0; 077777 + d=077777 -- ! + d=000010 -- ! adc 100000 -> n1z0v0c0; 100000 + d=100000 -- ! + d=000010 -- ! adc 177777 -> n1z0v0c0; 177777 + d=177777 -- ! +#-------- +C Exec test 46.5wrc1: ADC - reg,C=1 +# +wal 013204 -- setup test instructions: +bwm 2 + 000261 -- ccmov= sec + 005505 -- iut= adc r5 +wr0 177776 -- r0=177776 +wr1 000005 -- r1=5 +wr2 036000 -- r2=36000 +wr3 037000 -- r3=37000 +wr4 000000 -- r4=0 +wr5 000000 -- r5=0 +wsp 001400 -- sp=1400 +stapc 013200 -- start @ 13200 (1op reg) +wtgo +rpc d=013220 -- ! pc=halt +rr1 d=000000 -- ! r1=0 +wal 037000 -- check result area +brm 10 + d=000000 -- ! adc 000000 -> n0z0v0c0; 000001 + d=000001 -- ! + d=000000 -- ! adc 000001 -> n0z0v0c0; 000002 + d=000002 -- ! + d=000012 -- ! adc 077777 -> n1z0v1c0; 100000 + d=100000 -- ! + d=000010 -- ! adc 100000 -> n1z0v0c0; 100001 + d=100001 -- ! + d=000005 -- ! adc 177777 -> n0z1v0c1; 000000 + d=000000 -- ! +#-------- +C Exec test 46.6wrc0: SBC - reg,C=0 +# +wal 013204 -- setup test instructions: +bwm 2 + 000241 -- ccmov= clc + 005605 -- iut= sbc r5 +wr0 177776 -- r0=177776 +wr1 000005 -- r1=5 +wr2 036000 -- r2=36000 +wr3 037000 -- r3=37000 +wr4 000000 -- r4=0 +wr5 000000 -- r5=0 +wsp 001400 -- sp=1400 +stapc 013200 -- start @ 13200 (1op reg) +wtgo +rpc d=013220 -- ! pc=halt +rr1 d=000000 -- ! r1=0 +wal 037000 -- check result area +brm 10 + d=000004 -- ! sbc 000000 -> n0z1v0c0; 000000 + d=000000 -- ! + d=000000 -- ! sbc 000001 -> n0z0v0c0; 000001 + d=000001 -- ! + d=000000 -- ! sbc 077777 -> n0z0v0c0; 077777 + d=077777 -- ! + d=000010 -- ! sbc 100000 -> n1z0v0c0; 100000 + d=100000 -- ! + d=000010 -- ! sbc 177777 -> n1z0v0c0; 177777 + d=177777 -- ! +#-------- +C Exec test 46.6wrc1: SBC - reg,C=1 +# +wal 013204 -- setup test instructions: +bwm 2 + 000261 -- ccmov= sec + 005605 -- iut= sbc r5 +wr0 177776 -- r0=177776 +wr1 000005 -- r1=5 +wr2 036000 -- r2=36000 +wr3 037000 -- r3=37000 +wr4 000000 -- r4=0 +wr5 000000 -- r5=0 +wsp 001400 -- sp=1400 +stapc 013200 -- start @ 13200 (1op reg) +wtgo +rpc d=013220 -- ! pc=halt +rr1 d=000000 -- ! r1=0 +wal 037000 -- check result area +brm 10 + d=000011 -- ! sbc 000000 -> n1z0v0c1; 177777 + d=177777 -- ! + d=000004 -- ! sbc 000001 -> n0z1v0c0; 000000 + d=000000 -- ! + d=000000 -- ! sbc 077777 -> n0z0v0c0; 077776 + d=077776 -- ! + d=000002 -- ! sbc 100000 -> n0z0v1c0; 077777 + d=077777 -- ! + d=000010 -- ! sbc 177777 -> n1z0v0c0; 177776 + d=177776 -- ! +#-------- +C Exec test 46.7wr: TST - reg +# +wal 013204 -- setup test instructions: +bwm 2 + 000261 -- ccmov= sec + 005705 -- iut= tst r5 +wr0 177776 -- r0=177776 +wr1 000005 -- r1=5 +wr2 036000 -- r2=36000 +wr3 037000 -- r3=37000 +wr4 000000 -- r4=0 +wr5 000000 -- r5=0 +wsp 001400 -- sp=1400 +stapc 013200 -- start @ 13200 (1op reg) +wtgo +rpc d=013220 -- ! pc=halt +rr1 d=000000 -- ! r1=0 +wal 037000 -- check result area +brm 10 + d=000004 -- ! tst 000000 -> n0z1v0c0; + d=000000 -- ! + d=000000 -- ! tst 000001 -> n0z0v0c0; + d=000001 -- ! + d=000000 -- ! tst 077777 -> n0z0v0c0; + d=077777 -- ! + d=000010 -- ! tst 100000 -> n1z0v0c0; + d=100000 -- ! + d=000010 -- ! tst 177777 -> n1z0v0c0; + d=177777 -- ! +#-------- +C Exec test 46.7wm: TST - mem +# +wal 013224 -- setup test instructions: +bwm 2 + 000261 -- ccmov= sec + 005715 -- iut= tst (r5) +wr0 177776 -- r0=177776 +wr1 000005 -- r1=5 +wr2 036000 -- r2=36000 +wr3 037000 -- r3=37000 +wr4 001400 -- r4=1400 +wr5 001402 -- r5=1402 +wsp 001400 -- sp=1400 +stapc 013220 -- start @ 13220 (1op mem) +wtgo +rpc d=013240 -- ! pc=halt +rr1 d=000000 -- ! r1=0 +wal 037000 -- check result area +brm 10 + d=000004 -- ! tst 000000 -> n0z1v0c0; + d=000000 -- ! + d=000000 -- ! tst 000001 -> n0z0v0c0; + d=000001 -- ! + d=000000 -- ! tst 077777 -> n0z0v0c0; + d=077777 -- ! + d=000010 -- ! tst 100000 -> n1z0v0c0; + d=100000 -- ! + d=000010 -- ! tst 177777 -> n1z0v0c0; + d=177777 -- ! +#-------- +C Exec test 46.8wrc0: ROR - reg, C=0 +# +wal 036000 -- setup test vector: for ror,rol,ars,asl +bwm 7 + 000000 -- ror 000000 + 000001 -- ror 000001 + 100000 -- ror 100000 + 000100 -- ror 000100 + 000101 -- ror 000101 + 040100 -- ror 040100 + 100100 -- ror 100100 +wal 013204 -- setup test instructions: +bwm 2 + 000241 -- ccmov= clc + 006005 -- iut= ror r5 +wr0 177776 -- r0=177776 +wr1 000007 -- r1=7 +wr2 036000 -- r2=36000 +wr3 037000 -- r3=37000 +wr4 000000 -- r4=0 +wr5 000000 -- r5=0 +wsp 001400 -- sp=1400 +stapc 013200 -- start @ 13200 (1op reg) +wtgo +rpc d=013220 -- ! pc=halt +rr1 d=000000 -- ! r1=0 +wal 037000 -- check result area (Note: V = N xor C !) +brm 14 + d=000004 -- ! ror 000000 -> n0z1v0c0; 000000 + d=000000 -- ! + d=000007 -- ! ror 000001 -> n0z1v1c1; 000000 + d=000000 -- ! + d=000000 -- ! ror 100000 -> n0z0v0c0; 040000 + d=040000 -- ! + d=000000 -- ! ror 000100 -> n0z0v0c0; 000040 + d=000040 -- ! + d=000003 -- ! ror 000101 -> n0z0v1c1; 000040 + d=000040 -- ! + d=000000 -- ! ror 040100 -> n0z0v0c0; 020040 + d=020040 -- ! + d=000000 -- ! ror 100100 -> n0z0v0c0; 040040 + d=040040 -- ! +#-------- +C Exec test 46.8wrc1: ROR - reg, C=1 +# +wal 013204 -- setup test instructions: +bwm 2 + 000261 -- ccmov= sec + 006005 -- iut= ror r5 +wr0 177776 -- r0=177776 +wr1 000007 -- r1=7 +wr2 036000 -- r2=36000 +wr3 037000 -- r3=37000 +wr4 000000 -- r4=0 +wr5 000000 -- r5=0 +wsp 001400 -- sp=1400 +stapc 013200 -- start @ 13200 (1op reg) +wtgo +rpc d=013220 -- ! pc=halt +rr1 d=000000 -- ! r1=0 +wal 037000 -- check result area (Note: V = N xor C !) +brm 14 + d=000012 -- ! ror 000000 -> n1z0v1c0; 100000 + d=100000 -- ! + d=000011 -- ! ror 000001 -> n1z0v0c1; 100000 + d=100000 -- ! + d=000012 -- ! ror 100000 -> n1z0v1c0; 140000 + d=140000 -- ! + d=000012 -- ! ror 000100 -> n1z0v1c0; 100040 + d=100040 -- ! + d=000011 -- ! ror 000101 -> n1z0v0c1; 100040 + d=100040 -- ! + d=000012 -- ! ror 040100 -> n1z0v1c0; 120040 + d=120040 -- ! + d=000012 -- ! ror 100100 -> n1z0v1c0; 140040 + d=140040 -- ! +#-------- +C Exec test 46.9wrc0: ROL - reg, C=0 +# +wal 013204 -- setup test instructions: +bwm 2 + 000241 -- ccmov= clc + 006105 -- iut= rol r5 +wr0 177776 -- r0=177776 +wr1 000007 -- r1=7 +wr2 036000 -- r2=36000 +wr3 037000 -- r3=37000 +wr4 000000 -- r4=0 +wr5 000000 -- r5=0 +wsp 001400 -- sp=1400 +stapc 013200 -- start @ 13200 (1op reg) +wtgo +rpc d=013220 -- ! pc=halt +rr1 d=000000 -- ! r1=0 +wal 037000 -- check result area (Note: V = N xor C !) +brm 14 + d=000004 -- ! rol 000000 -> n0z1v0c0; 000000 + d=000000 -- ! + d=000000 -- ! rol 000001 -> n0z0v0c0; 000002 + d=000002 -- ! + d=000007 -- ! rol 100000 -> n0z1v1c1; 000000 + d=000000 -- ! + d=000000 -- ! rol 000100 -> n0z0v0c0; 000200 + d=000200 -- ! + d=000000 -- ! rol 000101 -> n0z0v0c0; 000202 + d=000202 -- ! + d=000012 -- ! rol 040100 -> n1z0v1c0; 100200 + d=100200 -- ! + d=000003 -- ! rol 100100 -> n0z0v1c1; 000200 + d=000200 -- ! +#-------- +C Exec test 46.9wrc1: ROL - reg, C=1 +# +wal 013204 -- setup test instructions: +bwm 2 + 000261 -- ccmov= sec + 006105 -- iut= rol r5 +wr0 177776 -- r0=177776 +wr1 000007 -- r1=7 +wr2 036000 -- r2=36000 +wr3 037000 -- r3=37000 +wr4 000000 -- r4=0 +wr5 000000 -- r5=0 +wsp 001400 -- sp=1400 +stapc 013200 -- start @ 13200 (1op reg) +wtgo +rpc d=013220 -- ! pc=halt +rr1 d=000000 -- ! r1=0 +wal 037000 -- check result area (Note: V = N xor C !) +brm 14 + d=000000 -- ! rol 000000 -> n0z0v0c0; 000001 + d=000001 -- ! + d=000000 -- ! rol 000001 -> n0z0v0c0; 000003 + d=000003 -- ! + d=000003 -- ! rol 100000 -> n0z0v1c1; 000001 + d=000001 -- ! + d=000000 -- ! rol 000100 -> n0z0v0c0; 000201 + d=000201 -- ! + d=000000 -- ! rol 000101 -> n0z0v0c0; 000203 + d=000203 -- ! + d=000012 -- ! rol 040100 -> n1z0v1c0; 100201 + d=100201 -- ! + d=000003 -- ! rol 100100 -> n0z0v1c1; 000201 + d=000201 -- ! +#-------- +C Exec test 46.10wrc0: ASR - reg, C=0 +# +wal 013204 -- setup test instructions: +bwm 2 + 000241 -- ccmov= clc + 006205 -- iut= asr r5 +wr0 177776 -- r0=177776 +wr1 000007 -- r1=7 +wr2 036000 -- r2=36000 +wr3 037000 -- r3=37000 +wr4 000000 -- r4=0 +wr5 000000 -- r5=0 +wsp 001400 -- sp=1400 +stapc 013200 -- start @ 13200 (1op reg) +wtgo +rpc d=013220 -- ! pc=halt +rr1 d=000000 -- ! r1=0 +wal 037000 -- check result area (Note: V = N xor C !) +brm 14 + d=000004 -- ! asr 000000 -> n0z1v0c0; 000000 + d=000000 -- ! + d=000007 -- ! asr 000001 -> n0z1v1c1; 000000 + d=000000 -- ! + d=000012 -- ! asr 100000 -> n1z0v1c0; 140000 + d=140000 -- ! + d=000000 -- ! asr 000100 -> n0z0v0c0; 000040 + d=000040 -- ! + d=000003 -- ! asr 000101 -> n0z0v1c1; 000040 + d=000040 -- ! + d=000000 -- ! asr 040100 -> n0z0v0c0; 020040 + d=020040 -- ! + d=000012 -- ! asr 100100 -> n1z0v1c0; 140040 + d=140040 -- ! +#-------- +C Exec test 46.10wrc1: ASR - reg, C=1 +# +wal 013204 -- setup test instructions: +bwm 2 + 000261 -- ccmov= sec + 006205 -- iut= asr r5 +wr0 177776 -- r0=177776 +wr1 000007 -- r1=7 +wr2 036000 -- r2=36000 +wr3 037000 -- r3=37000 +wr4 000000 -- r4=0 +wr5 000000 -- r5=0 +wsp 001400 -- sp=1400 +stapc 013200 -- start @ 13200 (1op reg) +wtgo +rpc d=013220 -- ! pc=halt +rr1 d=000000 -- ! r1=0 +wal 037000 -- check result area (Note: V = N xor C !) +brm 14 + d=000004 -- ! asr 000000 -> n0z1v0c0; 000000 + d=000000 -- ! + d=000007 -- ! asr 000001 -> n0z1v1c1; 000000 + d=000000 -- ! + d=000012 -- ! asr 100000 -> n1z0v1c0; 140000 + d=140000 -- ! + d=000000 -- ! asr 000100 -> n0z0v0c0; 000040 + d=000040 -- ! + d=000003 -- ! asr 000101 -> n0z0v1c1; 000040 + d=000040 -- ! + d=000000 -- ! asr 040100 -> n0z0v0c0; 020040 + d=020040 -- ! + d=000012 -- ! asr 100100 -> n1z0v1c0; 140040 + d=140040 -- ! +#-------- +C Exec test 46.11wrc0: ASL - reg, C=0 +# +wal 013204 -- setup test instructions: +bwm 2 + 000241 -- ccmov= clc + 006305 -- iut= asl r5 +wr0 177776 -- r0=177776 +wr1 000007 -- r1=7 +wr2 036000 -- r2=36000 +wr3 037000 -- r3=37000 +wr4 000000 -- r4=0 +wr5 000000 -- r5=0 +wsp 001400 -- sp=1400 +stapc 013200 -- start @ 13200 (1op reg) +wtgo +rpc d=013220 -- ! pc=halt +rr1 d=000000 -- ! r1=0 +wal 037000 -- check result area (Note: V = N xor C !) +brm 14 + d=000004 -- ! asl 000000 -> n0z1v0c0; 000000 + d=000000 -- ! + d=000000 -- ! asl 000001 -> n0z0v0c0; 000002 + d=000002 -- ! + d=000007 -- ! asl 100000 -> n0z1v1c1; 000000 + d=000000 -- ! + d=000000 -- ! asl 000100 -> n0z0v0c0; 000200 + d=000200 -- ! + d=000000 -- ! asl 000101 -> n0z0v0c0; 000202 + d=000202 -- ! + d=000012 -- ! asl 040100 -> n1z0v1c0; 100200 + d=100200 -- ! + d=000003 -- ! asl 100100 -> n0z0v1c1; 000200 + d=000200 -- ! +#-------- +C Exec test 46.11wrc1: ASL - reg, C=1 +# +wal 013204 -- setup test instructions: +bwm 2 + 000261 -- ccmov= sec + 006305 -- iut= asl r5 +wr0 177776 -- r0=177776 +wr1 000007 -- r1=7 +wr2 036000 -- r2=36000 +wr3 037000 -- r3=37000 +wr4 000000 -- r4=0 +wr5 000000 -- r5=0 +wsp 001400 -- sp=1400 +stapc 013200 -- start @ 13200 (1op reg) +wtgo +rpc d=013220 -- ! pc=halt +rr1 d=000000 -- ! r1=0 +wal 037000 -- check result area (Note: V = N xor C !) +brm 14 + d=000004 -- ! asl 000000 -> n0z1v0c0; 000000 + d=000000 -- ! + d=000000 -- ! asl 000001 -> n0z0v0c0; 000002 + d=000002 -- ! + d=000007 -- ! asl 100000 -> n0z1v1c1; 000000 + d=000000 -- ! + d=000000 -- ! asl 000100 -> n0z0v0c0; 000200 + d=000200 -- ! + d=000000 -- ! asl 000101 -> n0z0v0c0; 000202 + d=000202 -- ! + d=000012 -- ! asl 040100 -> n1z0v1c0; 100200 + d=100200 -- ! + d=000003 -- ! asl 100100 -> n0z0v1c1; 000200 + d=000200 -- ! +#-------- +C Exec test 46.12wrc0: MOV - reg, C=0 +# +wal 036000 -- setup test vector: for mov +bwm 6 + 000000 -- mov 000000,000000 + 000000 -- + 000001 -- mov 000001,000000 + 000000 -- + 100000 -- mov 100000,000000 + 000000 -- +wal 013246 -- setup test instructions: +bwm 2 + 000241 -- ccmov= clc + 010405 -- iut= mov r4,r5 +wr0 177776 -- r0=177776 +wr1 000003 -- r1=3 +wr2 036000 -- r2=36000 +wr3 037000 -- r3=37000 +wr4 000000 -- r4=0 +wr5 000000 -- r5=0 +wsp 001400 -- sp=1400 +stapc 013240 -- start @ 13240 (2op reg) +wtgo +rpc d=013262 -- ! pc=halt +rr1 d=000000 -- ! r1=0 +wal 037000 -- check result area +brm 6 + d=000004 -- ! mov 000000,000000 -> n0z1v0c0; 000000 + d=000000 -- ! + d=000000 -- ! mov 000001,000000 -> n0z0v0c0; 000001 + d=000001 -- ! + d=000010 -- ! mov 100000,000000 -> n1z0v0c0; 100000 + d=100000 -- ! +#-------- +C Exec test 46.12wrc1: MOV - reg, C=1 +# +wal 013246 -- setup test instructions: +bwm 2 + 000261 -- ccmov= sec + 010405 -- iut= mov r4,r5 +wr0 177776 -- r0=177776 +wr1 000003 -- r1=3 +wr2 036000 -- r2=36000 +wr3 037000 -- r3=37000 +wr4 000000 -- r4=0 +wr5 000000 -- r5=0 +wsp 001400 -- sp=1400 +stapc 013240 -- start @ 13240 (2op reg) +wtgo +rpc d=013262 -- ! pc=halt +rr1 d=000000 -- ! r1=0 +wal 037000 -- check result area +brm 6 + d=000005 -- ! mov 000000,000000 -> n0z1v0c1; 000000 + d=000000 -- ! + d=000001 -- ! mov 000001,000000 -> n0z0v0c1; 000001 + d=000001 -- ! + d=000011 -- ! mov 100000,000000 -> n1z0v0c1; 100000 + d=100000 -- ! +#-------- +C Exec test 46.12mc0: MOV - mem, C=0 +# +wal 013276 -- setup test instructions: +bwm 2 + 000241 -- ccmov= clc + 011415 -- iut= mov (r4),(r5) +wr0 177776 -- r0=177776 +wr1 000003 -- r1=3 +wr2 036000 -- r2=36000 +wr3 037000 -- r3=37000 +wr4 001400 -- r4=1400 +wr5 001402 -- r5=1402 +wsp 001400 -- sp=1400 +stapc 013270 -- start @ 13270 (2op mem) +wtgo +rpc d=013312 -- ! pc=halt +rr1 d=000000 -- ! r1=0 +wal 037000 -- check result area +brm 6 + d=000004 -- ! mov 000000,000000 -> n0z1v0c0; 000000 + d=000000 -- ! + d=000000 -- ! mov 000001,000000 -> n0z0v0c0; 000001 + d=000001 -- ! + d=000010 -- ! mov 100000,000000 -> n1z0v0c0; 100000 + d=100000 -- ! +#-------- +C Exec test 46.13wrc0: BIT - reg, C=0 +# +wal 036000 -- setup test vector: for bit,bic,bis,xor +bwm 12 + 000000 -- bit 000000,000000 + 000000 -- + 000011 -- bit 000011,000000 + 000000 -- + 000011 -- bit 000011,000110 + 000110 -- + 000011 -- bit 000011,001100 + 001100 -- + 110000 -- bit 110000,011000 + 011000 -- + 110000 -- bit 110000,110000 + 110000 -- +wal 013246 -- setup test instructions: +bwm 2 + 000241 -- ccmov= clc + 030405 -- iut= bit r4,r5 +wr0 177776 -- r0=177776 +wr1 000006 -- r1=6 +wr2 036000 -- r2=36000 +wr3 037000 -- r3=37000 +wr4 000000 -- r4=0 +wr5 000000 -- r5=0 +wsp 001400 -- sp=1400 +stapc 013240 -- start @ 13240 (2op reg) +wtgo +rpc d=013262 -- ! pc=halt +rr1 d=000000 -- ! r1=0 +wal 037000 -- check result area +brm 12 + d=000004 -- ! bit 000000,000000 -> n0z1v0c0; (000000) + d=000000 -- ! + d=000004 -- ! bit 000011,000000 -> n0z1v0c0; (000000) + d=000000 -- ! + d=000000 -- ! bit 000011,000110 -> n0z0v0c0; (000010) + d=000110 -- ! + d=000004 -- ! bit 000011,001100 -> n0z1v0c0; (000000) + d=001100 -- ! + d=000000 -- ! bit 110000,011000 -> n0z0v0c0; (010000) + d=011000 -- ! + d=000010 -- ! bit 110000,110000 -> n1z0v0c0; (100000) + d=110000 -- ! +#-------- +C Exec test 46.13wrc1: BIT - reg, C=1 +# +wal 013246 -- setup test instructions: +bwm 2 + 000261 -- ccmov= sec + 030405 -- iut= bit r4,r5 +wr0 177776 -- r0=177776 +wr1 000006 -- r1=6 +wr2 036000 -- r2=36000 +wr3 037000 -- r3=37000 +wr4 000000 -- r4=0 +wr5 000000 -- r5=0 +wsp 001400 -- sp=1400 +stapc 013240 -- start @ 13240 (2op reg) +wtgo +rpc d=013262 -- ! pc=halt +rr1 d=000000 -- ! r1=0 +wal 037000 -- check result area +brm 12 + d=000005 -- ! bit 000000,000000 -> n0z1v0c1; (000000) + d=000000 -- ! + d=000005 -- ! bit 000011,000000 -> n0z1v0c1; (000000) + d=000000 -- ! + d=000001 -- ! bit 000011,000110 -> n0z0v0c1; (000010) + d=000110 -- ! + d=000005 -- ! bit 000011,001100 -> n0z1v0c1; (000000) + d=001100 -- ! + d=000001 -- ! bit 110000,011000 -> n0z0v0c1; (010000) + d=011000 -- ! + d=000011 -- ! bit 110000,110000 -> n1z0v0c1; (100000) + d=110000 -- ! +#-------- +C Exec test 46.13wmc0: BIT - mem, C=0 +# +wal 013276 -- setup test instructions: +bwm 2 + 000241 -- ccmov= clc + 031415 -- iut= bit (r4),(r5) +wr0 177776 -- r0=177776 +wr1 000006 -- r1=6 +wr2 036000 -- r2=36000 +wr3 037000 -- r3=37000 +wr4 001400 -- r4=1400 +wr5 001402 -- r5=1402 +wsp 001400 -- sp=1400 +stapc 013270 -- start @ 13270 (2op mem) +wtgo +rpc d=013312 -- ! pc=halt +rr1 d=000000 -- ! r1=0 +wal 037000 -- check result area +brm 12 + d=000004 -- ! bit 000000,000000 -> n0z1v0c0; (000000) + d=000000 -- ! + d=000004 -- ! bit 000011,000000 -> n0z1v0c0; (000000) + d=000000 -- ! + d=000000 -- ! bit 000011,000110 -> n0z0v0c0; (000010) + d=000110 -- ! + d=000004 -- ! bit 000011,001100 -> n0z1v0c0; (000000) + d=001100 -- ! + d=000000 -- ! bit 110000,011000 -> n0z0v0c0; (010000) + d=011000 -- ! + d=000010 -- ! bit 110000,110000 -> n1z0v0c0; (100000) + d=110000 -- ! +#-------- +C Exec test 46.14wrc0: BIC - reg, C=0 +# +wal 013246 -- setup test instructions: +bwm 2 + 000241 -- ccmov= clc + 040405 -- iut= bic r4,r5 +wr0 177776 -- r0=177776 +wr1 000006 -- r1=6 +wr2 036000 -- r2=36000 +wr3 037000 -- r3=37000 +wr4 000000 -- r4=0 +wr5 000000 -- r5=0 +wsp 001400 -- sp=1400 +stapc 013240 -- start @ 13240 (2op reg) +wtgo +rpc d=013262 -- ! pc=halt +rr1 d=000000 -- ! r1=0 +wal 037000 -- check result area +brm 12 + d=000004 -- ! bic 000000,000000 -> n0z1v0c0; 000000 + d=000000 -- ! + d=000004 -- ! bic 000011,000000 -> n0z1v0c0; 000000 + d=000000 -- ! + d=000000 -- ! bic 000011,000110 -> n0z0v0c0; 000100 + d=000100 -- ! + d=000000 -- ! bic 000011,001100 -> n0z0v0c0; 001100 + d=001100 -- ! + d=000000 -- ! bic 110000,011000 -> n0z0v0c0; 001000 + d=001000 -- ! + d=000004 -- ! bic 110000,110000 -> n0z1v0c0; 000000 + d=000000 -- ! +#-------- +C Exec test 46.14wrc1: BIC - reg, C=1 +# +wal 013246 -- setup test instructions: +bwm 2 + 000261 -- ccmov= sec + 040405 -- iut= bic r4,r5 +wr0 177776 -- r0=177776 +wr1 000006 -- r1=6 +wr2 036000 -- r2=36000 +wr3 037000 -- r3=37000 +wr4 000000 -- r4=0 +wr5 000000 -- r5=0 +wsp 001400 -- sp=1400 +stapc 013240 -- start @ 13240 (2op reg) +wtgo +rpc d=013262 -- ! pc=halt +rr1 d=000000 -- ! r1=0 +wal 037000 -- check result area +brm 12 + d=000005 -- ! bic 000000,000000 -> n0z1v0c1; 000000 + d=000000 -- ! + d=000005 -- ! bic 000011,000000 -> n0z1v0c1; 000000 + d=000000 -- ! + d=000001 -- ! bic 000011,000110 -> n0z0v0c1; 000100 + d=000100 -- ! + d=000001 -- ! bic 000011,001100 -> n0z0v0c1; 001100 + d=001100 -- ! + d=000001 -- ! bic 110000,011000 -> n0z0v0c1; 001000 + d=001000 -- ! + d=000005 -- ! bic 110000,110000 -> n0z1v0c1; 000000 + d=000000 -- ! +#-------- +C Exec test 46.14wrc0: BIC - mem, C=0 +# +wal 013276 -- setup test instructions: +bwm 2 + 000241 -- ccmov= clc + 041415 -- iut= bic (r4),(r5) +wr0 177776 -- r0=177776 +wr1 000006 -- r1=6 +wr2 036000 -- r2=36000 +wr3 037000 -- r3=37000 +wr4 001400 -- r4=1400 +wr5 001402 -- r5=1402 +wsp 001400 -- sp=1400 +stapc 013270 -- start @ 13270 (2op mem) +wtgo +rpc d=013312 -- ! pc=halt +rr1 d=000000 -- ! r1=0 +wal 037000 -- check result area +brm 12 + d=000004 -- ! bic 000000,000000 -> n0z1v0c0; 000000 + d=000000 -- ! + d=000004 -- ! bic 000011,000000 -> n0z1v0c0; 000000 + d=000000 -- ! + d=000000 -- ! bic 000011,000110 -> n0z0v0c0; 000100 + d=000100 -- ! + d=000000 -- ! bic 000011,001100 -> n0z0v0c0; 001100 + d=001100 -- ! + d=000000 -- ! bic 110000,011000 -> n0z0v0c0; 001000 + d=001000 -- ! + d=000004 -- ! bic 110000,110000 -> n0z1v0c0; 000000 + d=000000 -- ! +#-------- +C Exec test 46.15wrc0: BIS - reg, C=0 +# +wal 013246 -- setup test instructions: +bwm 2 + 000241 -- ccmov= clc + 050405 -- iut= bis r4,r5 +wr0 177776 -- r0=177776 +wr1 000006 -- r1=6 +wr2 036000 -- r2=36000 +wr3 037000 -- r3=37000 +wr4 000000 -- r4=0 +wr5 000000 -- r5=0 +wsp 001400 -- sp=1400 +stapc 013240 -- start @ 13240 (2op reg) +wtgo +rpc d=013262 -- ! pc=halt +rr1 d=000000 -- ! r1=0 +wal 037000 -- check result area +brm 12 + d=000004 -- ! bis 000000,000000 -> n0z1v0c0; 000000 + d=000000 -- ! + d=000000 -- ! bis 000011,000000 -> n0z0v0c0; 000011 + d=000011 -- ! + d=000000 -- ! bis 000011,000110 -> n0z0v0c0; 000111 + d=000111 -- ! + d=000000 -- ! bis 000011,001100 -> n0z0v0c0; 001111 + d=001111 -- ! + d=000010 -- ! bis 110000,011000 -> n1z0v0c0; 111000 + d=111000 -- ! + d=000010 -- ! bis 110000,110000 -> n1z0v0c0; 110000 + d=110000 -- ! +#-------- +C Exec test 46.15wrc1: BIS - reg, C=1 +# +wal 013246 -- setup test instructions: +bwm 2 + 000261 -- ccmov= sec + 050405 -- iut= bis r4,r5 +wr0 177776 -- r0=177776 +wr1 000006 -- r1=6 +wr2 036000 -- r2=36000 +wr3 037000 -- r3=37000 +wr4 000000 -- r4=0 +wr5 000000 -- r5=0 +wsp 001400 -- sp=1400 +stapc 013240 -- start @ 13240 (2op reg) +wtgo +rpc d=013262 -- ! pc=halt +rr1 d=000000 -- ! r1=0 +wal 037000 -- check result area +brm 12 + d=000005 -- ! bis 000000,000000 -> n0z1v0c1; 000000 + d=000000 -- ! + d=000001 -- ! bis 000011,000000 -> n0z0v0c1; 000011 + d=000011 -- ! + d=000001 -- ! bis 000011,000110 -> n0z0v0c1; 000111 + d=000111 -- ! + d=000001 -- ! bis 000011,001100 -> n0z0v0c1; 001111 + d=001111 -- ! + d=000011 -- ! bis 110000,011000 -> n1z0v0c1; 111000 + d=111000 -- ! + d=000011 -- ! bis 110000,110000 -> n1z0v0c1; 110000 + d=110000 -- ! +#-------- +C Exec test 46.16wrc0: XOR - reg, C=0 +# +wal 013246 -- setup test instructions: +bwm 2 + 000241 -- ccmov= clc + 074405 -- iut= xor r4,r5 +wr0 177776 -- r0=177776 +wr1 000006 -- r1=6 +wr2 036000 -- r2=36000 +wr3 037000 -- r3=37000 +wr4 000000 -- r4=0 +wr5 000000 -- r5=0 +wsp 001400 -- sp=1400 +stapc 013240 -- start @ 13240 (2op reg) +wtgo +rpc d=013262 -- ! pc=halt +rr1 d=000000 -- ! r1=0 +wal 037000 -- check result area +brm 12 + d=000004 -- ! xor 000000,000000 -> n0z1v0c0; 000000 + d=000000 -- ! + d=000000 -- ! xor 000011,000000 -> n0z0v0c0; 000011 + d=000011 -- ! + d=000000 -- ! xor 000011,000110 -> n0z0v0c0; 000101 + d=000101 -- ! + d=000000 -- ! xor 000011,001100 -> n0z0v0c0; 001111 + d=001111 -- ! + d=000010 -- ! xor 110000,011000 -> n1z0v0c0; 101000 + d=101000 -- ! + d=000004 -- ! xor 110000,110000 -> n1z0v0c0; 000000 + d=000000 -- ! +#-------- +C Exec test 46.16wrc1: XOR - reg, C=1 +# +wal 013246 -- setup test instructions: +bwm 2 + 000261 -- ccmov= sec + 074405 -- iut= xor r4,r5 +wr0 177776 -- r0=177776 +wr1 000006 -- r1=6 +wr2 036000 -- r2=36000 +wr3 037000 -- r3=37000 +wr4 000000 -- r4=0 +wr5 000000 -- r5=0 +wsp 001400 -- sp=1400 +stapc 013240 -- start @ 13240 (2op reg) +wtgo +rpc d=013262 -- ! pc=halt +rr1 d=000000 -- ! r1=0 +wal 037000 -- check result area +brm 12 + d=000005 -- ! xor 000000,000000 -> n0z1v0c1; 000000 + d=000000 -- ! + d=000001 -- ! xor 000011,000000 -> n0z0v0c1; 000011 + d=000011 -- ! + d=000001 -- ! xor 000011,000110 -> n0z0v0c1; 000101 + d=000101 -- ! + d=000001 -- ! xor 000011,001100 -> n0z0v0c1; 001111 + d=001111 -- ! + d=000011 -- ! xor 110000,011000 -> n1z0v0c1; 101000 + d=101000 -- ! + d=000005 -- ! xor 110000,110000 -> n1z0v0c1; 000000 + d=000000 -- ! +#-------- +C Exec test 46.17wr: CMP - reg +# +wal 036000 -- setup test vector: for cmp,add,sub +bwm 38 + 000000 -- cmp 000000,000000 + 000000 -- + 000001 -- cmp 000001,000000 + 000000 -- + 177777 -- cmp 177777,000000 + 000000 -- + 000000 -- cmp 000000,000001 + 000001 -- + 000001 -- cmp 000001,000001 + 000001 -- + 177777 -- cmp 177777,000001 + 000001 -- + 077776 -- cmp 077776,077777 + 077777 -- + 077777 -- cmp 077777,077777 + 077777 -- + 100000 -- cmp 100000,077777 + 077777 -- + 000001 -- cmp 000001,077777 + 077777 -- + 177777 -- cmp 177777,077777 + 077777 -- + 077777 -- cmp 077777,100000 + 100000 -- + 100000 -- cmp 100000,100000 + 100000 -- + 100001 -- cmp 100001,100000 + 100000 -- + 000001 -- cmp 000001,100000 + 100000 -- + 177777 -- cmp 177777,100000 + 100000 -- + 000000 -- cmp 000000,177777 + 177777 -- + 000001 -- cmp 000001,177777 + 177777 -- + 177777 -- cmp 177777,177777 + 177777 -- +wal 013246 -- setup test instructions: +bwm 2 + 000241 -- ccmov= clc + 020405 -- iut= cmp r4,r5 +wr0 177776 -- r0=177776 +wr1 000023 -- r1=23 (19.) +wr2 036000 -- r2=36000 +wr3 037000 -- r3=37000 +wr4 000000 -- r4=0 +wr5 000000 -- r5=0 +wsp 001400 -- sp=1400 +stapc 013240 -- start @ 13240 (2op reg) +wtgo +rpc d=013262 -- ! pc=halt +rr1 d=000000 -- ! r1=0 (Note: C=1 if dst > src unsigned) +wal 037000 -- check result area (Note: V=1 if s xor d and r eq d) +brm 38 + d=000004 -- ! cmp 000000,000000 -> n0z1v0c0; (000000) + d=000000 -- ! + d=000000 -- ! cmp 000001,000000 -> n0z0v0c0; (000001) + d=000000 -- ! + d=000010 -- ! cmp 177777,000000 -> n1z0v0c0; (177777) + d=000000 -- ! + d=000011 -- ! cmp 000000,000001 -> n1z0v0c1; (177777+C) + d=000001 -- ! + d=000004 -- ! cmp 000001,000001 -> n0z1v0c0; (000000) + d=000001 -- ! + d=000010 -- ! cmp 177777,000001 -> n1z0v0c0; (177776) + d=000001 -- ! + d=000011 -- ! cmp 077776,077777 -> n1z0v0c1; (177777+C) + d=077777 -- ! + d=000004 -- ! cmp 077777,077777 -> n0z1v0c0; (000000) + d=077777 -- ! + d=000002 -- ! cmp 100000,077777 -> n0z0v1c0; (000001) + d=077777 -- ! + d=000011 -- ! cmp 000001,077777 -> n1z0v0c1; (100002+C) + d=077777 -- ! + d=000010 -- ! cmp 177777,077777 -> n1z0v0c0; (100000) + d=077777 -- ! + d=000013 -- ! cmp 077777,100000 -> n1z0v1c1; (177777+C) + d=100000 -- ! + d=000004 -- ! cmp 100000,100000 -> n0z1v0c0; (000000) + d=100000 -- ! + d=000000 -- ! cmp 100001,100000 -> n0z0v0c0; (000001) + d=100000 -- ! + d=000013 -- ! cmp 000001,100000 -> n1z0v1c1; (100001+C) + d=100000 -- ! + d=000000 -- ! cmp 177777,100000 -> n0z0v0c0; (077777) + d=100000 -- ! + d=000001 -- ! cmp 000000,177777 -> n0z0v0c1; (000001+C) + d=177777 -- ! + d=000001 -- ! cmp 000001,177777 -> n0z0v0c1; (000002+C) + d=177777 -- ! + d=000004 -- ! cmp 177777,177777 -> n0z1v0c0; (000000) + d=177777 -- ! +#-------- +C Exec test 46.18r: ADD - reg +# +wal 013246 -- setup test instructions: +bwm 2 + 000241 -- ccmov= clc + 060405 -- iut= add r4,r5 +wr0 177776 -- r0=177776 +wr1 000023 -- r1=23 (19.) +wr2 036000 -- r2=36000 +wr3 037000 -- r3=37000 +wr4 000000 -- r4=0 +wr5 000000 -- r5=0 +wsp 001400 -- sp=1400 +stapc 013240 -- start @ 13240 (2op reg) +wtgo +rpc d=013262 -- ! pc=halt +rr1 d=000000 -- ! r1=0 +wal 037000 -- check result area (Note: V=1 if s eq d and r neq d) +brm 38 + d=000004 -- ! add 000000,000000 -> n0z1v0c0; 000000 + d=000000 -- ! + d=000000 -- ! add 000001,000000 -> n0z0v0c0; 000001 + d=000001 -- ! + d=000010 -- ! add 177777,000000 -> n1z0v0c0; 177777 + d=177777 -- ! + d=000000 -- ! add 000000,000001 -> n0z0v0c0; 000001 + d=000001 -- ! + d=000000 -- ! add 000001,000001 -> n0z0v0c0; 000002 + d=000002 -- ! + d=000005 -- ! add 177777,000001 -> n0z1v0c1; 000000+C + d=000000 -- ! + d=000012 -- ! add 077776,077777 -> n1z0v1c0; 177775 + d=177775 -- ! + d=000012 -- ! add 077777,077777 -> n1z0v1c0; 177776 + d=177776 -- ! + d=000010 -- ! add 100000,077777 -> n1z0v0c0; 177777 + d=177777 -- ! + d=000012 -- ! add 000001,077777 -> n1z0v1c0; 100000 + d=100000 -- ! + d=000001 -- ! add 177777,077777 -> n0z0v0c1; 077776+C + d=077776 -- ! + d=000010 -- ! add 077777,100000 -> n1z0v0c1; 177777+C + d=177777 -- ! + d=000007 -- ! add 100000,100000 -> n0z1v1c1; 000000+C + d=000000 -- ! + d=000003 -- ! add 100001,100000 -> n0z0v1c1; 000001+C + d=000001 -- ! + d=000010 -- ! add 000001,100000 -> n1z0v0c0; 100001 + d=100001 -- ! + d=000003 -- ! add 177777,100000 -> n0z0v1c1; 077777+C + d=077777 -- ! + d=000010 -- ! add 000000,177777 -> n1z0v0c0; 177777 + d=177777 -- ! + d=000005 -- ! add 000001,177777 -> n0z1v0c1; 000000+C + d=000000 -- ! + d=000011 -- ! add 177777,177777 -> n1z0v0c1; 177776+C + d=177776 -- ! +#-------- +C Exec test 46.19r: SUB - reg +# +wal 013246 -- setup test instructions: +bwm 2 + 000241 -- ccmov= clc + 160405 -- iut= sub r4,r5 +wr0 177776 -- r0=177776 +wr1 000023 -- r1=23 (19.) +wr2 036000 -- r2=36000 +wr3 037000 -- r3=37000 +wr4 000000 -- r4=0 +wr5 000000 -- r5=0 +wsp 001400 -- sp=1400 +stapc 013240 -- start @ 13240 (2op reg) +wtgo +rpc d=013262 -- ! pc=halt +rr1 d=000000 -- ! r1=0 (Note: C=1 if src > dst unsigned) +wal 037000 -- check result area (Note: V=1 if s xor d and r eq s) +brm 38 + d=000004 -- ! sub 000000,000000 -> n0z1v0c0; 000000 + d=000000 -- ! + d=000011 -- ! sub 000001,000000 -> n1z0v0c1; 177777+C + d=177777 -- ! + d=000001 -- ! sub 177777,000000 -> n0z0v0c1; 000001+C + d=000001 -- ! + d=000000 -- ! sub 000000,000001 -> n0z0v0c0; 000001 + d=000001 -- ! + d=000004 -- ! sub 000001,000001 -> n0z1v0c0; 000000 + d=000000 -- ! + d=000001 -- ! sub 177777,000001 -> n0z0v0c1; 000002+C + d=000002 -- ! + d=000000 -- ! sub 077776,077777 -> n0z0v0c0; 000001 + d=000001 -- ! + d=000004 -- ! sub 077777,077777 -> n0z1v0c0; 000000 + d=000000 -- ! + d=000013 -- ! sub 100000,077777 -> n1z0v1c1; 177777+C + d=177777 -- ! + d=000000 -- ! sub 000001,077777 -> n0z0v0c0; 077776 + d=077776 -- ! + d=000013 -- ! sub 177777,077777 -> n1z0v1c1; 100000+C + d=100000 -- ! + d=000002 -- ! sub 077777,100000 -> n0z0v1c0; 000001 + d=000001 -- ! + d=000004 -- ! sub 100000,100000 -> n0z1v0c0; 000000 + d=000000 -- ! + d=000011 -- ! sub 100001,100000 -> n1z0v0c1; 177777+C + d=177777 -- ! + d=000002 -- ! sub 000001,100000 -> n0z0v1c0; 077777 + d=077777 -- ! + d=000011 -- ! sub 177777,100000 -> n1z0v0c1: 100001+C + d=100001 -- ! + d=000010 -- ! sub 000000,177777 -> n1z0v0c0; 177777 + d=177777 -- ! + d=000010 -- ! sub 000001,177777 -> n1z0v0c0; 177776 + d=177776 -- ! + d=000004 -- ! sub 177777,177777 -> n0z1v0c0; 000000 + d=000000 -- ! +# +C Exec test 46.20r: SWAP - reg +# +wal 036000 -- setup test vector: for swap +bwm 9 + 000000 -- swap 000000 + 000001 -- swap 000001 + 000200 -- swap 000200 + 000400 -- swap 000400 + 100000 -- swap 100000 + 000401 -- swap 000401 + 000600 -- swap 000600 + 100001 -- swap 100001 + 100200 -- swap 100200 +wal 013204 -- setup test instructions: +bwm 2 + 000241 -- ccmov= clc + 000305 -- iut= swap r5 +wr0 177776 -- r0=177776 +wr1 000011 -- r1=11 (9.) +wr2 036000 -- r2=36000 +wr3 037000 -- r3=37000 +wr4 000000 -- r4=0 +wr5 000000 -- r5=0 +wsp 001400 -- sp=1400 +stapc 013200 -- start @ 13200 (1op reg) +wtgo +rpc d=013220 -- ! pc=halt +rr1 d=000000 -- ! r1=0 +wal 037000 -- check result area (Note: N,Z from lsb of result) +brm 18 + d=000004 -- ! swap 000000 -> n0z1v0c0; 000000 + d=000000 -- ! + d=000004 -- ! swap 000001 -> n0z1v0c0; 000400 + d=000400 -- ! + d=000004 -- ! swap 000200 -> n0z1v0c0; 100000 + d=100000 -- ! + d=000000 -- ! swap 000400 -> n0z0v0c0; 000001 + d=000001 -- ! + d=000010 -- ! swap 100000 -> n1z0v0c0; 000200 + d=000200 -- ! + d=000000 -- ! swap 000401 -> n0z0v0c0; 000401 + d=000401 -- ! + d=000000 -- ! swap 000600 -> n0z0v0c0; 100001 + d=100001 -- ! + d=000010 -- ! swap 100001 -> n1z0v0c0; 000600 + d=000600 -- ! + d=000010 -- ! swap 100200 -> n1z0v0c0; 100200 + d=100200 -- ! +#-------- +C Exec code 46 pass 2 (systematic result+cc test of 1+2op instructions; byte) +C Exec test 46.1br: COMB - reg +# +wal 036000 -- setup test vector: for com,inc,dec,neg,adc,sbc,tst (b) +bwm 5 + 000000 -- comb 000000 + 000001 -- comb 000001 + 000177 -- comb 000177 + 000200 -- comb 000200 + 000377 -- comb 000377 +wal 013204 -- setup test instructions: +bwm 2 + 000241 -- ccmov= clc + 105105 -- iut= comb r5 +wr0 177776 -- r0=177776 +wr1 000005 -- r1=5 +wr2 036000 -- r2=36000 +wr3 037000 -- r3=37000 +wr4 000000 -- r4=0 +wr5 000000 -- r5=0 +wsp 001400 -- sp=1400 +stapc 013200 -- start @ 13200 (1op reg) +wtgo +rpc d=013220 -- ! pc=halt +rr1 d=000000 -- ! r1=0 +wal 037000 -- check result area +brm 10 + d=000011 -- ! comb 000000 -> n1z0v0c1; 000377 + d=000377 -- ! + d=000011 -- ! comb 000001 -> n1z0v0c1; 000376 + d=000376 -- ! + d=000011 -- ! comb 000177 -> n1z0v0c1; 000200 + d=000200 -- ! + d=000001 -- ! comb 000200 -> n0z0v0c1; 000177 + d=000177 -- ! + d=000005 -- ! comb 000377 -> n0z1v0c1; 000000 + d=000000 -- ! +#-------- +C Exec test 46.1bm: COMB - mem +# +wal 013224 -- setup test instructions: +bwm 2 + 000241 -- ccmov= clc + 105115 -- iut= comb (r5) +wr0 177776 -- r0=177776 +wr1 000005 -- r1=5 +wr2 036000 -- r2=36000 +wr3 037000 -- r3=37000 +wr4 001400 -- r4=1400 +wr5 001402 -- r5=1402 +wsp 001400 -- sp=1400 +stapc 013220 -- start @ 13220 (1op mem) +wtgo +rpc d=013240 -- ! pc=halt +rr1 d=000000 -- ! r1=0 +wal 037000 -- check result area +brm 10 + d=000011 -- ! comb 000000 -> n1z0v0c1; 000377 + d=000377 -- ! + d=000011 -- ! comb 000001 -> n1z0v0c1; 000376 + d=000376 -- ! + d=000011 -- ! comb 000177 -> n1z0v0c1; 000200 + d=000200 -- ! + d=000001 -- ! comb 000200 -> n0z0v0c1; 000177 + d=000177 -- ! + d=000005 -- ! comb 000377 -> n0z1v0c1; 000000 + d=000000 -- ! +#-------- +C Exec test 46.2brc0: INCB - reg,C=0 +# +wal 013204 -- setup test instructions: +bwm 2 + 000241 -- ccmov= clc + 105205 -- iut= incb r5 +wr0 177776 -- r0=177776 +wr1 000005 -- r1=5 +wr2 036000 -- r2=36000 +wr3 037000 -- r3=37000 +wr4 000000 -- r4=0 +wr5 000000 -- r5=0 +wsp 001400 -- sp=1400 +stapc 013200 -- start @ 13200 (1op reg) +wtgo +rpc d=013220 -- ! pc=halt +rr1 d=000000 -- ! r1=0 +wal 037000 -- check result area +brm 10 + d=000000 -- ! incb 000000 -> n0z0v0c0; 000001 + d=000001 -- ! + d=000000 -- ! incb 000001 -> n0z0v0c0; 000002 + d=000002 -- ! + d=000012 -- ! incb 000177 -> n1z0v1c0; 000200 + d=000200 -- ! + d=000010 -- ! incb 000200 -> n1z0v0c0; 000201 + d=000201 -- ! + d=000004 -- ! incb 000377 -> n0z1v0c0; 000000 + d=000000 -- ! +#-------- +C Exec test 46.2brc1: INCB - reg,C=1 +# +wal 013204 -- setup test instructions: +bwm 2 + 000261 -- ccmov= sec + 105205 -- iut= incb r5 +wr0 177776 -- r0=177776 +wr1 000005 -- r1=5 +wr2 036000 -- r2=36000 +wr3 037000 -- r3=37000 +wr4 000000 -- r4=0 +wr5 000000 -- r5=0 +wsp 001400 -- sp=1400 +stapc 013200 -- start @ 13200 (1op reg) +wtgo +rpc d=013220 -- ! pc=halt +rr1 d=000000 -- ! r1=0 +wal 037000 -- check result area +brm 10 + d=000001 -- ! incb 000000 -> n0z0v0c1; 000001 + d=000001 -- ! + d=000001 -- ! incb 000001 -> n0z0v0c1; 000002 + d=000002 -- ! + d=000013 -- ! incb 000177 -> n1z0v1c1; 000200 + d=000200 -- ! + d=000011 -- ! incb 000200 -> n1z0v0c1; 000201 + d=000201 -- ! + d=000005 -- ! incb 000377 -> n0z1v0c1; 000000 + d=000000 -- ! +#-------- +C Exec test 46.3brc0: DECB - reg,C=0 +# +wal 013204 -- setup test instructions: +bwm 2 + 000241 -- ccmov= clc + 105305 -- iut= decb r5 +wr0 177776 -- r0=177776 +wr1 000005 -- r1=5 +wr2 036000 -- r2=36000 +wr3 037000 -- r3=37000 +wr4 000000 -- r4=0 +wr5 000000 -- r5=0 +wsp 001400 -- sp=1400 +stapc 013200 -- start @ 13200 (1op reg) +wtgo +rpc d=013220 -- ! pc=halt +rr1 d=000000 -- ! r1=0 +wal 037000 -- check result area +brm 10 + d=000010 -- ! decb 000000 -> n1z0v0c0; 000377 + d=000377 -- ! + d=000004 -- ! decb 000001 -> n0z1v0c0; 000000 + d=000000 -- ! + d=000000 -- ! decb 000177 -> n0z0v0c0; 000176 + d=000176 -- ! + d=000002 -- ! decb 000200 -> n0z0v1c0; 000177 + d=000177 -- ! + d=000010 -- ! decb 000377 -> n1z0v0c0; 000376 + d=000376 -- ! +#-------- +C Exec test 46.3brc1: DECB - reg,C=1 +# +wal 013204 -- setup test instructions: +bwm 2 + 000261 -- ccmov= sec + 105305 -- iut= decb r5 +wr0 177776 -- r0=177776 +wr1 000005 -- r1=5 +wr2 036000 -- r2=36000 +wr3 037000 -- r3=37000 +wr4 000000 -- r4=0 +wr5 000000 -- r5=0 +wsp 001400 -- sp=1400 +stapc 013200 -- start @ 13200 (1op reg) +wtgo +rpc d=013220 -- ! pc=halt +rr1 d=000000 -- ! r1=0 +wal 037000 -- check result area +brm 10 + d=000011 -- ! decb 000000 -> n1z0v0c1; 000377 + d=000377 -- ! + d=000005 -- ! decb 000001 -> n0z1v0c1; 000000 + d=000000 -- ! + d=000001 -- ! decb 000177 -> n0z0v0c1; 000176 + d=000176 -- ! + d=000003 -- ! decb 000200 -> n0z0v1c1; 000177 + d=000177 -- ! + d=000011 -- ! decb 000377 -> n1z0v0c1; 000376 + d=000376 -- ! +#-------- +C Exec test 46.4br: NEGB - reg +# +wal 013204 -- setup test instructions: +bwm 2 + 000241 -- ccmov= clc + 105405 -- iut= negb r5 +wr0 177776 -- r0=177776 +wr1 000005 -- r1=5 +wr2 036000 -- r2=36000 +wr3 037000 -- r3=37000 +wr4 000000 -- r4=0 +wr5 000000 -- r5=0 +wsp 001400 -- sp=1400 +stapc 013200 -- start @ 13200 (1op reg) +wtgo +rpc d=013220 -- ! pc=halt +rr1 d=000000 -- ! r1=0 +wal 037000 -- check result area +brm 10 + d=000004 -- ! negb 000000 -> n0z1v0c0; 000000 + d=000000 -- ! + d=000011 -- ! negb 000001 -> n1z0v0c1; 000377 + d=000377 -- ! + d=000011 -- ! negb 000177 -> n1z0v0c1; 000201 + d=000201 -- ! + d=000013 -- ! negb 000200 -> n1z0v1c1; 000200 + d=000200 -- ! + d=000001 -- ! negb 000377 -> n0z0v0c1; 000001 + d=000001 -- ! +#-------- +C Exec test 46.5brc0: ADCB - reg,C=0 +# +wal 013204 -- setup test instructions: +bwm 2 + 000241 -- ccmov= clc + 105505 -- iut= adcb r5 +wr0 177776 -- r0=177776 +wr1 000005 -- r1=5 +wr2 036000 -- r2=36000 +wr3 037000 -- r3=37000 +wr4 000000 -- r4=0 +wr5 000000 -- r5=0 +wsp 001400 -- sp=1400 +stapc 013200 -- start @ 13200 (1op reg) +wtgo +rpc d=013220 -- ! pc=halt +rr1 d=000000 -- ! r1=0 +wal 037000 -- check result area +brm 10 + d=000004 -- ! adcb 000000 -> n0z1v0c0; 000000 + d=000000 -- ! + d=000000 -- ! adcb 000001 -> n0z0v0c0; 000001 + d=000001 -- ! + d=000000 -- ! adcb 000177 -> n0z0v0c0; 000177 + d=000177 -- ! + d=000010 -- ! adcb 000200 -> n1z0v0c0; 000200 + d=000200 -- ! + d=000010 -- ! adcb 000377 -> n1z0v0c0; 000377 + d=000377 -- ! +#-------- +C Exec test 46.5brc1: ADCB - reg,C=1 +# +wal 013204 -- setup test instructions: +bwm 2 + 000261 -- ccmov= sec + 105505 -- iut= adcb r5 +wr0 177776 -- r0=177776 +wr1 000005 -- r1=5 +wr2 036000 -- r2=36000 +wr3 037000 -- r3=37000 +wr4 000000 -- r4=0 +wr5 000000 -- r5=0 +wsp 001400 -- sp=1400 +stapc 013200 -- start @ 13200 (1op reg) +wtgo +rpc d=013220 -- ! pc=halt +rr1 d=000000 -- ! r1=0 +wal 037000 -- check result area +brm 10 + d=000000 -- ! adcb 000000 -> n0z0v0c0; 000001 + d=000001 -- ! + d=000000 -- ! adcb 000001 -> n0z0v0c0; 000002 + d=000002 -- ! + d=000012 -- ! adcb 000177 -> n1z0v1c0; 000200 + d=000200 -- ! + d=000010 -- ! adcb 000200 -> n1z0v0c0; 000201 + d=000201 -- ! + d=000005 -- ! adcb 000377 -> n0z1v0c1; 000000 + d=000000 -- ! +#-------- +C Exec test 46.6brc0: SBCB - reg,C=0 +# +wal 013204 -- setup test instructions: +bwm 2 + 000241 -- ccmov= clc + 105605 -- iut= sbcb r5 +wr0 177776 -- r0=177776 +wr1 000005 -- r1=5 +wr2 036000 -- r2=36000 +wr3 037000 -- r3=37000 +wr4 000000 -- r4=0 +wr5 000000 -- r5=0 +wsp 001400 -- sp=1400 +stapc 013200 -- start @ 13200 (1op reg) +wtgo +rpc d=013220 -- ! pc=halt +rr1 d=000000 -- ! r1=0 +wal 037000 -- check result area +brm 10 + d=000004 -- ! sbcb 000000 -> n0z1v0c0; 000000 + d=000000 -- ! + d=000000 -- ! sbcb 000001 -> n0z0v0c0; 000001 + d=000001 -- ! + d=000000 -- ! sbcb 000177 -> n0z0v0c0; 000177 + d=000177 -- ! + d=000010 -- ! sbcb 000200 -> n1z0v0c0; 000200 + d=000200 -- ! + d=000010 -- ! sbcb 000377 -> n1z0v0c0; 000377 + d=000377 -- ! +#-------- +C Exec test 46.6brc1: SBCB - reg,C=1 +# +wal 013204 -- setup test instructions: +bwm 2 + 000261 -- ccmov= sec + 105605 -- iut= sbcb r5 +wr0 177776 -- r0=177776 +wr1 000005 -- r1=5 +wr2 036000 -- r2=36000 +wr3 037000 -- r3=37000 +wr4 000000 -- r4=0 +wr5 000000 -- r5=0 +wsp 001400 -- sp=1400 +stapc 013200 -- start @ 13200 (1op reg) +wtgo +rpc d=013220 -- ! pc=halt +rr1 d=000000 -- ! r1=0 +wal 037000 -- check result area +brm 10 + d=000011 -- ! sbcb 000000 -> n1z0v0c1; 000377 + d=000377 -- ! + d=000004 -- ! sbcb 000001 -> n0z1v0c0; 000000 + d=000000 -- ! + d=000000 -- ! sbcb 000177 -> n0z0v0c0; 000176 + d=000176 -- ! + d=000002 -- ! sbcb 000200 -> n0z0v1c0; 000177 + d=000177 -- ! + d=000010 -- ! sbcb 000377 -> n1z0v0c0; 000376 + d=000376 -- ! +#-------- +C Exec test 46.7br: TSTB - reg +# +wal 013204 -- setup test instructions: +bwm 2 + 000261 -- ccmov= sec + 105705 -- iut= tstb r5 +wr0 177776 -- r0=177776 +wr1 000005 -- r1=5 +wr2 036000 -- r2=36000 +wr3 037000 -- r3=37000 +wr4 000000 -- r4=0 +wr5 000000 -- r5=0 +wsp 001400 -- sp=1400 +stapc 013200 -- start @ 13200 (1op reg) +wtgo +rpc d=013220 -- ! pc=halt +rr1 d=000000 -- ! r1=0 +wal 037000 -- check result area +brm 10 + d=000004 -- ! tstb 000000 -> n0z1v0c0; + d=000000 -- ! + d=000000 -- ! tstb 000001 -> n0z0v0c0; + d=000001 -- ! + d=000000 -- ! tstb 000177 -> n0z0v0c0; + d=000177 -- ! + d=000010 -- ! tstb 000200 -> n1z0v0c0; + d=000200 -- ! + d=000010 -- ! tstb 000377 -> n1z0v0c0; + d=000377 -- ! +#-------- +C Exec test 46.7bm: TSTB - mem +# +wal 013224 -- setup test instructions: +bwm 2 + 000261 -- ccmov= sec + 105715 -- iut= tstb (r5) +wr0 177776 -- r0=177776 +wr1 000005 -- r1=5 +wr2 036000 -- r2=36000 +wr3 037000 -- r3=37000 +wr4 001400 -- r4=1400 +wr5 001402 -- r5=1402 +wsp 001400 -- sp=1400 +stapc 013220 -- start @ 13220 (1op mem) +wtgo +rpc d=013240 -- ! pc=halt +rr1 d=000000 -- ! r1=0 +wal 037000 -- check result area +brm 10 + d=000004 -- ! tstb 000000 -> n0z1v0c0; + d=000000 -- ! + d=000000 -- ! tstb 000001 -> n0z0v0c0; + d=000001 -- ! + d=000000 -- ! tstb 000177 -> n0z0v0c0; + d=000177 -- ! + d=000010 -- ! tstb 000200 -> n1z0v0c0; + d=000200 -- ! + d=000010 -- ! tstb 000377 -> n1z0v0c0; + d=000377 -- ! +#-------- +C Exec test 46.8brc0: RORB - reg, C=0 +# +wal 036000 -- setup test vector: for ror,rol,ars,asl (b) +bwm 7 + 000000 -- ror 000000 + 000001 -- ror 000001 + 000200 -- ror 000200 + 000010 -- ror 000010 + 000011 -- ror 000011 + 000110 -- ror 000110 + 000210 -- ror 000210 +wal 013204 -- setup test instructions: +bwm 2 + 000241 -- ccmov= clc + 106005 -- iut= rorb r5 +wr0 177776 -- r0=177776 +wr1 000007 -- r1=7 +wr2 036000 -- r2=36000 +wr3 037000 -- r3=37000 +wr4 000000 -- r4=0 +wr5 000000 -- r5=0 +wsp 001400 -- sp=1400 +stapc 013200 -- start @ 13200 (1op reg) +wtgo +rpc d=013220 -- ! pc=halt +rr1 d=000000 -- ! r1=0 +wal 037000 -- check result area (Note: V = N xor C !) +brm 14 + d=000004 -- ! rorb 000000 -> n0z1v0c0; 000000 + d=000000 -- ! + d=000007 -- ! rorb 000001 -> n0z1v1c1; 000000 + d=000000 -- ! + d=000000 -- ! rorb 000200 -> n0z0v0c0; 000100 + d=000100 -- ! + d=000000 -- ! rorb 000010 -> n0z0v0c0; 000004 + d=000004 -- ! + d=000003 -- ! rorb 000011 -> n0z0v1c1; 000004 + d=000004 -- ! + d=000000 -- ! rorb 000110 -> n0z0v0c0; 000044 + d=000044 -- ! + d=000000 -- ! rorb 000210 -> n0z0v0c0; 000104 + d=000104 -- ! +#-------- +C Exec test 46.8brc1: RORB - reg, C=1 +# +wal 013204 -- setup test instructions: +bwm 2 + 000261 -- ccmov= sec + 106005 -- iut= rorb r5 +wr0 177776 -- r0=177776 +wr1 000007 -- r1=7 +wr2 036000 -- r2=36000 +wr3 037000 -- r3=37000 +wr4 000000 -- r4=0 +wr5 000000 -- r5=0 +wsp 001400 -- sp=1400 +stapc 013200 -- start @ 13200 (1op reg) +wtgo +rpc d=013220 -- ! pc=halt +rr1 d=000000 -- ! r1=0 +wal 037000 -- check result area (Note: V = N xor C !) +brm 14 + d=000012 -- ! rorb 000000 -> n1z0v1c0; 000200 + d=000200 -- ! + d=000011 -- ! rorb 000001 -> n1z0v0c1; 000200 + d=000200 -- ! + d=000012 -- ! rorb 000200 -> n1z0v1c0; 000300 + d=000300 -- ! + d=000012 -- ! rorb 000010 -> n1z0v1c0; 000204 + d=000204 -- ! + d=000011 -- ! rorb 000011 -> n1z0v0c1; 000204 + d=000204 -- ! + d=000012 -- ! rorb 000110 -> n1z0v1c0; 000244 + d=000244 -- ! + d=000012 -- ! rorb 000210 -> n1z0v1c0; 000304 + d=000304 -- ! +#-------- +C Exec test 46.9brc0: ROLB - reg, C=0 +# +wal 013204 -- setup test instructions: +bwm 2 + 000241 -- ccmov= clc + 106105 -- iut= rolb r5 +wr0 177776 -- r0=177776 +wr1 000007 -- r1=7 +wr2 036000 -- r2=36000 +wr3 037000 -- r3=37000 +wr4 000000 -- r4=0 +wr5 000000 -- r5=0 +wsp 001400 -- sp=1400 +stapc 013200 -- start @ 13200 (1op reg) +wtgo +rpc d=013220 -- ! pc=halt +rr1 d=000000 -- ! r1=0 +wal 037000 -- check result area (Note: V = N xor C !) +brm 14 + d=000004 -- ! rolb 000000 -> n0z1v0c0; 000000 + d=000000 -- ! + d=000000 -- ! rolb 000001 -> n0z0v0c0; 000002 + d=000002 -- ! + d=000007 -- ! rolb 000200 -> n0z1v1c1; 000000 + d=000000 -- ! + d=000000 -- ! rolb 000010 -> n0z0v0c0; 000020 + d=000020 -- ! + d=000000 -- ! rolb 000011 -> n0z0v0c0; 000022 + d=000022 -- ! + d=000012 -- ! rolb 000110 -> n1z0v1c0; 000220 + d=000220 -- ! + d=000003 -- ! rolb 000210 -> n0z0v1c1; 000020 + d=000020 -- ! +#-------- +C Exec test 46.9brc1: ROLB - reg, C=1 +# +wal 013204 -- setup test instructions: +bwm 2 + 000261 -- ccmov= sec + 106105 -- iut= rolb r5 +wr0 177776 -- r0=177776 +wr1 000007 -- r1=7 +wr2 036000 -- r2=36000 +wr3 037000 -- r3=37000 +wr4 000000 -- r4=0 +wr5 000000 -- r5=0 +wsp 001400 -- sp=1400 +stapc 013200 -- start @ 13200 (1op reg) +wtgo +rpc d=013220 -- ! pc=halt +rr1 d=000000 -- ! r1=0 +wal 037000 -- check result area (Note: V = N xor C !) +brm 14 + d=000000 -- ! rolb 000000 -> n0z0v0c0; 000001 + d=000001 -- ! + d=000000 -- ! rolb 000001 -> n0z0v0c0; 000003 + d=000003 -- ! + d=000003 -- ! rolb 000200 -> n0z0v1c1; 000001 + d=000001 -- ! + d=000000 -- ! rolb 000010 -> n0z0v0c0; 000021 + d=000021 -- ! + d=000000 -- ! rolb 000011 -> n0z0v0c0; 000023 + d=000023 -- ! + d=000012 -- ! rolb 000110 -> n1z0v1c0; 000221 + d=000221 -- ! + d=000003 -- ! rolb 000210 -> n0z0v1c1; 000021 + d=000021 -- ! +#-------- +C Exec test 46.10brc0: ASRB - reg, C=0 +# +wal 013204 -- setup test instructions: +bwm 2 + 000241 -- ccmov= clc + 106205 -- iut= asrb r5 +wr0 177776 -- r0=177776 +wr1 000007 -- r1=7 +wr2 036000 -- r2=36000 +wr3 037000 -- r3=37000 +wr4 000000 -- r4=0 +wr5 000000 -- r5=0 +wsp 001400 -- sp=1400 +stapc 013200 -- start @ 13200 (1op reg) +wtgo +rpc d=013220 -- ! pc=halt +rr1 d=000000 -- ! r1=0 +wal 037000 -- check result area (Note: V = N xor C !) +brm 14 + d=000004 -- ! asrb 000000 -> n0z1v0c0; 000000 + d=000000 -- ! + d=000007 -- ! asrb 000001 -> n0z1v1c1; 000000 + d=000000 -- ! + d=000012 -- ! asrb 000200 -> n1z0v1c0; 000300 + d=000300 -- ! + d=000000 -- ! asrb 000010 -> n0z0v0c0; 000004 + d=000004 -- ! + d=000003 -- ! asrb 000011 -> n0z0v1c1; 000004 + d=000004 -- ! + d=000000 -- ! asrb 000110 -> n0z0v0c0; 000044 + d=000044 -- ! + d=000012 -- ! asrb 000210 -> n1z0v1c0; 000304 + d=000304 -- ! +#-------- +C Exec test 46.10brc1: ASRB - reg, C=1 +# +wal 013204 -- setup test instructions: +bwm 2 + 000261 -- ccmov= sec + 106205 -- iut= asrb r5 +wr0 177776 -- r0=177776 +wr1 000007 -- r1=7 +wr2 036000 -- r2=36000 +wr3 037000 -- r3=37000 +wr4 000000 -- r4=0 +wr5 000000 -- r5=0 +wsp 001400 -- sp=1400 +stapc 013200 -- start @ 13200 (1op reg) +wtgo +rpc d=013220 -- ! pc=halt +rr1 d=000000 -- ! r1=0 +wal 037000 -- check result area (Note: V = N xor C !) +brm 14 + d=000004 -- ! asrb 000000 -> n0z1v0c0; 000000 + d=000000 -- ! + d=000007 -- ! asrb 000001 -> n0z1v1c1; 000000 + d=000000 -- ! + d=000012 -- ! asrb 000200 -> n1z0v1c0; 000300 + d=000300 -- ! + d=000000 -- ! asrb 000010 -> n0z0v0c0; 000004 + d=000004 -- ! + d=000003 -- ! asrb 000011 -> n0z0v1c1; 000004 + d=000004 -- ! + d=000000 -- ! asrb 000110 -> n0z0v0c0; 000044 + d=000044 -- ! + d=000012 -- ! asrb 000210 -> n1z0v1c0; 000304 + d=000304 -- ! +#-------- +C Exec test 46.11brc0: ASLB - reg, C=0 +# +wal 013204 -- setup test instructions: +bwm 2 + 000241 -- ccmov= clc + 106305 -- iut= aslb r5 +wr0 177776 -- r0=177776 +wr1 000007 -- r1=7 +wr2 036000 -- r2=36000 +wr3 037000 -- r3=37000 +wr4 000000 -- r4=0 +wr5 000000 -- r5=0 +wsp 001400 -- sp=1400 +stapc 013200 -- start @ 13200 (1op reg) +wtgo +rpc d=013220 -- ! pc=halt +rr1 d=000000 -- ! r1=0 +wal 037000 -- check result area (Note: V = N xor C !) +brm 14 + d=000004 -- ! aslb 000000 -> n0z1v0c0; 000000 + d=000000 -- ! + d=000000 -- ! aslb 000001 -> n0z0v0c0; 000002 + d=000002 -- ! + d=000007 -- ! aslb 000200 -> n0z1v1c1; 000000 + d=000000 -- ! + d=000000 -- ! aslb 000010 -> n0z0v0c0; 000020 + d=000020 -- ! + d=000000 -- ! aslb 000011 -> n0z0v0c0; 000022 + d=000022 -- ! + d=000012 -- ! aslb 000110 -> n1z0v1c0; 000220 + d=000220 -- ! + d=000003 -- ! aslb 000210 -> n0z0v1c1; 000020 + d=000020 -- ! +#-------- +C Exec test 46.11brc1: ASLB - reg, C=1 +# +wal 013204 -- setup test instructions: +bwm 2 + 000261 -- ccmov= sec + 106305 -- iut= aslb r5 +wr0 177776 -- r0=177776 +wr1 000007 -- r1=7 +wr2 036000 -- r2=36000 +wr3 037000 -- r3=37000 +wr4 000000 -- r4=0 +wr5 000000 -- r5=0 +wsp 001400 -- sp=1400 +stapc 013200 -- start @ 13200 (1op reg) +wtgo +rpc d=013220 -- ! pc=halt +rr1 d=000000 -- ! r1=0 +wal 037000 -- check result area (Note: V = N xor C !) +brm 14 + d=000004 -- ! aslb 000000 -> n0z1v0c0; 000000 + d=000000 -- ! + d=000000 -- ! aslb 000001 -> n0z0v0c0; 000002 + d=000002 -- ! + d=000007 -- ! aslb 000200 -> n0z1v1c1; 000000 + d=000000 -- ! + d=000000 -- ! aslb 000010 -> n0z0v0c0; 000020 + d=000020 -- ! + d=000000 -- ! aslb 000011 -> n0z0v0c0; 000022 + d=000022 -- ! + d=000012 -- ! aslb 000110 -> n1z0v1c0; 000220 + d=000220 -- ! + d=000003 -- ! aslb 000210 -> n0z0v1c1; 000020 + d=000020 -- ! +#-------- +C Exec test 46.12brc0: MOVB - reg, C=0 +# +wal 036000 -- setup test vector: for mov +bwm 6 + 000000 -- movb 000000,000000 + 000000 -- + 000001 -- movb 000001,000000 + 000000 -- + 000200 -- movb 000200,000000 + 000000 -- +wal 013246 -- setup test instructions: +bwm 2 + 000241 -- ccmov= clc + 110405 -- iut= movb r4,r5 +wr0 177776 -- r0=177776 +wr1 000003 -- r1=3 +wr2 036000 -- r2=36000 +wr3 037000 -- r3=37000 +wr4 000000 -- r4=0 +wr5 000000 -- r5=0 +wsp 001400 -- sp=1400 +stapc 013240 -- start @ 13240 (2op reg) +wtgo +rpc d=013262 -- ! pc=halt +rr1 d=000000 -- ! r1=0 +wal 037000 -- check result area +brm 6 + d=000004 -- ! movb 000000,000000 -> n0z1v0c0; 000000 + d=000000 -- ! + d=000000 -- ! movb 000001,000000 -> n0z0v0c0; 000001 + d=000001 -- ! + d=000010 -- ! movb 000200,000000 -> n1z0v0c0; 177600 + d=177600 -- ! +#-------- +C Exec test 46.12brc1: MOVB - reg, C=1 +# +wal 013246 -- setup test instructions: +bwm 2 + 000261 -- ccmov= sec + 110405 -- iut= movb r4,r5 +wr0 177776 -- r0=177776 +wr1 000003 -- r1=3 +wr2 036000 -- r2=36000 +wr3 037000 -- r3=37000 +wr4 000000 -- r4=0 +wr5 000000 -- r5=0 +wsp 001400 -- sp=1400 +stapc 013240 -- start @ 13240 (2op reg) +wtgo +rpc d=013262 -- ! pc=halt +rr1 d=000000 -- ! r1=0 +wal 037000 -- check result area +brm 6 + d=000005 -- ! movb 000000,000000 -> n0z1v0c1; 000000 + d=000000 -- ! + d=000001 -- ! movb 000001,000000 -> n0z0v0c1; 000001 + d=000001 -- ! + d=000011 -- ! movb 000200,000000 -> n1z0v0c1; 177600 + d=177600 -- ! +#-------- +C Exec test 46.12bmc0: MOVB - mem, C=0 +# +wal 013276 -- setup test instructions: +bwm 2 + 000241 -- ccmov= clc + 111415 -- iut= movb (r4),(r5) +wr0 177776 -- r0=177776 +wr1 000003 -- r1=3 +wr2 036000 -- r2=36000 +wr3 037000 -- r3=37000 +wr4 001400 -- r4=1400 +wr5 001402 -- r5=1402 +wsp 001400 -- sp=1400 +stapc 013270 -- start @ 13270 (2op mem) +wtgo +rpc d=013312 -- ! pc=halt +rr1 d=000000 -- ! r1=0 +wal 037000 -- check result area +brm 6 + d=000004 -- ! movb 000000,000000 -> n0z1v0c0; 000000 + d=000000 -- ! + d=000000 -- ! movb 000001,000000 -> n0z0v0c0; 000001 + d=000001 -- ! + d=000010 -- ! movb 000200,000000 -> n1z0v0c0; 000200 + d=000200 -- ! +#-------- +C Exec test 46.13brc0: BITB - reg, C=0 +# +wal 036000 -- setup test vector: for bit,bic,bis (b) +bwm 12 + 000000 -- bitb 000000,000000 + 000000 -- + 000003 -- bitb 000003,000000 + 000000 -- + 000003 -- bitb 000003,000006 + 000006 -- + 000003 -- bitb 000003,000014 + 000014 -- + 000300 -- bitb 000300,000140 + 000140 -- + 000300 -- bitb 000300,000300 + 000300 -- +wal 013246 -- setup test instructions: +bwm 2 + 000241 -- ccmov= clc + 130405 -- iut= bitb r4,r5 +wr0 177776 -- r0=177776 +wr1 000006 -- r1=6 +wr2 036000 -- r2=36000 +wr3 037000 -- r3=37000 +wr4 000000 -- r4=0 +wr5 000000 -- r5=0 +wsp 001400 -- sp=1400 +stapc 013240 -- start @ 13240 (2op reg) +wtgo +rpc d=013262 -- ! pc=halt +rr1 d=000000 -- ! r1=0 +wal 037000 -- check result area +brm 12 + d=000004 -- ! bitb 000000,000000 -> n0z1v0c0; (000000) + d=000000 -- ! + d=000004 -- ! bitb 000003,000000 -> n0z1v0c0; (000000) + d=000000 -- ! + d=000000 -- ! bitb 000003,000006 -> n0z0v0c0; (000002) + d=000006 -- ! + d=000004 -- ! bitb 000003,000014 -> n0z1v0c0; (000000) + d=000014 -- ! + d=000000 -- ! bitb 000300,000140 -> n0z0v0c0; (000100) + d=000140 -- ! + d=000010 -- ! bitb 000300,000300 -> n1z0v0c0; (000300) + d=000300 -- ! +#-------- +C Exec test 46.13brc1: BITB - reg, C=1 +# +wal 013246 -- setup test instructions: +bwm 2 + 000261 -- ccmov= sec + 130405 -- iut= bitb r4,r5 +wr0 177776 -- r0=177776 +wr1 000006 -- r1=6 +wr2 036000 -- r2=36000 +wr3 037000 -- r3=37000 +wr4 000000 -- r4=0 +wr5 000000 -- r5=0 +wsp 001400 -- sp=1400 +stapc 013240 -- start @ 13240 (2op reg) +wtgo +rpc d=013262 -- ! pc=halt +rr1 d=000000 -- ! r1=0 +wal 037000 -- check result area +brm 12 + d=000005 -- ! bitb 000000,000000 -> n0z1v0c1; (000000) + d=000000 -- ! + d=000005 -- ! bitb 000003,000000 -> n0z1v0c1; (000000) + d=000000 -- ! + d=000001 -- ! bitb 000003,000006 -> n0z0v0c1; (000002) + d=000006 -- ! + d=000005 -- ! bitb 000003,000014 -> n0z1v0c1; (000000) + d=000014 -- ! + d=000001 -- ! bitb 000300,000140 -> n0z0v0c1; (000100) + d=000140 -- ! + d=000011 -- ! bitb 000300,000300 -> n1z0v0c1; (000300) + d=000300 -- ! +#-------- +C Exec test 46.13bmc0: BITB - mem, C=0 +# +wal 013276 -- setup test instructions: +bwm 2 + 000241 -- ccmov= clc + 131415 -- iut= bitb (r4),(r5) +wr0 177776 -- r0=177776 +wr1 000006 -- r1=6 +wr2 036000 -- r2=36000 +wr3 037000 -- r3=37000 +wr4 001400 -- r4=1400 +wr5 001402 -- r5=1402 +wsp 001400 -- sp=1400 +stapc 013270 -- start @ 13270 (2op mem) +wtgo +rpc d=013312 -- ! pc=halt +rr1 d=000000 -- ! r1=0 +wal 037000 -- check result area +brm 12 + d=000004 -- ! bitb 000000,000000 -> n0z1v0c0; (000000) + d=000000 -- ! + d=000004 -- ! bitb 000003,000000 -> n0z1v0c0; (000000) + d=000000 -- ! + d=000000 -- ! bitb 000003,000006 -> n0z0v0c0; (000002) + d=000006 -- ! + d=000004 -- ! bitb 000003,000014 -> n0z1v0c0; (000000) + d=000014 -- ! + d=000000 -- ! bitb 000300,000140 -> n0z0v0c0; (000100) + d=000140 -- ! + d=000010 -- ! bitb 000300,000300 -> n1z0v0c0; (000300) + d=000300 -- ! +#-------- +C Exec test 46.14brc0: BICB - reg, C=0 +# +wal 013246 -- setup test instructions: +bwm 2 + 000241 -- ccmov= clc + 140405 -- iut= bicb r4,r5 +wr0 177776 -- r0=177776 +wr1 000006 -- r1=6 +wr2 036000 -- r2=36000 +wr3 037000 -- r3=37000 +wr4 000000 -- r4=0 +wr5 000000 -- r5=0 +wsp 001400 -- sp=1400 +stapc 013240 -- start @ 13240 (2op reg) +wtgo +rpc d=013262 -- ! pc=halt +rr1 d=000000 -- ! r1=0 +wal 037000 -- check result area +brm 12 + d=000004 -- ! bicb 000000,000000 -> n0z1v0c0; 000000 + d=000000 -- ! + d=000004 -- ! bicb 000003,000000 -> n0z1v0c0; 000000 + d=000000 -- ! + d=000000 -- ! bicb 000003,000006 -> n0z0v0c0; 000004 + d=000004 -- ! + d=000000 -- ! bicb 000003,000014 -> n0z0v0c0; 000014 + d=000014 -- ! + d=000000 -- ! bicb 000300,000140 -> n0z0v0c0; 000040 + d=000040 -- ! + d=000004 -- ! bicb 000300,000300 -> n0z1v0c0; 000000 + d=000000 -- ! +#-------- +C Exec test 46.14brc1: BICB - reg, C=1 +# +wal 013246 -- setup test instructions: +bwm 2 + 000261 -- ccmov= sec + 140405 -- iut= bicb r4,r5 +wr0 177776 -- r0=177776 +wr1 000006 -- r1=6 +wr2 036000 -- r2=36000 +wr3 037000 -- r3=37000 +wr4 000000 -- r4=0 +wr5 000000 -- r5=0 +wsp 001400 -- sp=1400 +stapc 013240 -- start @ 13240 (2op reg) +wtgo +rpc d=013262 -- ! pc=halt +rr1 d=000000 -- ! r1=0 +wal 037000 -- check result area +brm 12 + d=000005 -- ! bicb 000000,000000 -> n0z1v0c1; 000000 + d=000000 -- ! + d=000005 -- ! bicb 000003,000000 -> n0z1v0c1; 000000 + d=000000 -- ! + d=000001 -- ! bicb 000003,000006 -> n0z0v0c1; 000004 + d=000004 -- ! + d=000001 -- ! bicb 000003,000014 -> n0z0v0c1; 000014 + d=000014 -- ! + d=000001 -- ! bicb 000300,000140 -> n0z0v0c1; 000040 + d=000040 -- ! + d=000005 -- ! bicb 000300,000300 -> n0z1v0c1; 000000 + d=000000 -- ! +#-------- +C Exec test 46.14bmrc0: BICB - mem, C=0 +# +wal 013276 -- setup test instructions: +bwm 2 + 000241 -- ccmov= clc + 141415 -- iut= bicb (r4),(r5) +wr0 177776 -- r0=177776 +wr1 000006 -- r1=6 +wr2 036000 -- r2=36000 +wr3 037000 -- r3=37000 +wr4 001400 -- r4=1400 +wr5 001402 -- r5=1402 +wsp 001400 -- sp=1400 +stapc 013270 -- start @ 13270 (2op mem) +wtgo +rpc d=013312 -- ! pc=halt +rr1 d=000000 -- ! r1=0 +wal 037000 -- check result area +brm 12 + d=000004 -- ! bicb 000000,000000 -> n0z1v0c0; 000000 + d=000000 -- ! + d=000004 -- ! bicb 000003,000000 -> n0z1v0c0; 000000 + d=000000 -- ! + d=000000 -- ! bicb 000003,000006 -> n0z0v0c0; 000004 + d=000004 -- ! + d=000000 -- ! bicb 000003,000014 -> n0z0v0c0; 000014 + d=000014 -- ! + d=000000 -- ! bicb 000300,000140 -> n0z0v0c0; 000040 + d=000040 -- ! + d=000004 -- ! bicb 000300,000300 -> n0z1v0c0; 000000 + d=000000 -- ! +#-------- +C Exec test 46.15brc0: BISB - reg, C=0 +# +wal 013246 -- setup test instructions: +bwm 2 + 000241 -- ccmov= clc + 150405 -- iut= bisb r4,r5 +wr0 177776 -- r0=177776 +wr1 000006 -- r1=6 +wr2 036000 -- r2=36000 +wr3 037000 -- r3=37000 +wr4 000000 -- r4=0 +wr5 000000 -- r5=0 +wsp 001400 -- sp=1400 +stapc 013240 -- start @ 13240 (2op reg) +wtgo +rpc d=013262 -- ! pc=halt +rr1 d=000000 -- ! r1=0 +wal 037000 -- check result area +brm 12 + d=000004 -- ! bisb 000000,000000 -> n0z1v0c0; 000000 + d=000000 -- ! + d=000000 -- ! bisb 000003,000000 -> n0z0v0c0; 000003 + d=000003 -- ! + d=000000 -- ! bisb 000003,000006 -> n0z0v0c0; 000007 + d=000007 -- ! + d=000000 -- ! bisb 000003,000014 -> n0z0v0c0; 000017 + d=000017 -- ! + d=000010 -- ! bisb 000300,000140 -> n1z0v0c0; 000340 + d=000340 -- ! + d=000010 -- ! bisb 000300,000300 -> n1z0v0c0; 000300 + d=000300 -- ! +#-------- +C Exec test 46.15brc1: BISB - reg, C=1 +# +wal 013246 -- setup test instructions: +bwm 2 + 000261 -- ccmov= sec + 150405 -- iut= bisb r4,r5 +wr0 177776 -- r0=177776 +wr1 000006 -- r1=6 +wr2 036000 -- r2=36000 +wr3 037000 -- r3=37000 +wr4 000000 -- r4=0 +wr5 000000 -- r5=0 +wsp 001400 -- sp=1400 +stapc 013240 -- start @ 13240 (2op reg) +wtgo +rpc d=013262 -- ! pc=halt +rr1 d=000000 -- ! r1=0 +wal 037000 -- check result area +brm 12 + d=000005 -- ! bisb 000000,000000 -> n0z1v0c1; 000000 + d=000000 -- ! + d=000001 -- ! bisb 000003,000000 -> n0z0v0c1; 000003 + d=000003 -- ! + d=000001 -- ! bisb 000003,000006 -> n0z0v0c1; 000007 + d=000007 -- ! + d=000001 -- ! bisb 000003,000014 -> n0z0v0c1; 000017 + d=000017 -- ! + d=000011 -- ! bisb 000300,000140 -> n1z0v0c1; 000340 + d=000340 -- ! + d=000011 -- ! bisb 000300,000300 -> n1z0v0c1; 000300 + d=000300 -- ! +#-------- +C Exec test 46.17br: CMPB - reg +# +wal 036000 -- setup test vector: for cmp (b) +bwm 38 + 000000 -- cmpb 000000,000000 + 000000 -- + 000001 -- cmpb 000001,000000 + 000000 -- + 000377 -- cmpb 000377,000000 + 000000 -- + 000000 -- cmpb 000000,000001 + 000001 -- + 000001 -- cmpb 000001,000001 + 000001 -- + 000377 -- cmpb 000377,000001 + 000001 -- + 000176 -- cmpb 000176,000177 + 000177 -- + 000177 -- cmpb 000177,000177 + 000177 -- + 000200 -- cmpb 000200,000177 + 000177 -- + 000001 -- cmpb 000001,000177 + 000177 -- + 000377 -- cmpb 000377,000177 + 000177 -- + 000177 -- cmpb 000177,000200 + 000200 -- + 000200 -- cmpb 000200,000200 + 000200 -- + 000201 -- cmpb 000201,000200 + 000200 -- + 000001 -- cmpb 000001,000200 + 000200 -- + 000377 -- cmpb 000377,000200 + 000200 -- + 000000 -- cmpb 000000,000377 + 000377 -- + 000001 -- cmpb 000001,000377 + 000377 -- + 000377 -- cmpb 000377,000377 + 000377 -- +wal 013246 -- setup test instructions: +bwm 2 + 000241 -- ccmov= clc + 120405 -- iut= cmpb r4,r5 +wr0 177776 -- r0=177776 +wr1 000023 -- r1=23 (19.) +wr2 036000 -- r2=36000 +wr3 037000 -- r3=37000 +wr4 000000 -- r4=0 +wr5 000000 -- r5=0 +wsp 001400 -- sp=1400 +stapc 013240 -- start @ 13240 (2op reg) +wtgo +rpc d=013262 -- ! pc=halt +rr1 d=000000 -- ! r1=0 (Note: C=1 if dst > src unsigned) +wal 037000 -- check result area (Note: V=1 if s xor d and r eq d) +brm 38 + d=000004 -- ! cmpb 000000,000000 -> n0z1v0c0; (000000) + d=000000 -- ! + d=000000 -- ! cmpb 000001,000000 -> n0z0v0c0; (000001) + d=000000 -- ! + d=000010 -- ! cmpb 000377,000000 -> n1z0v0c0; (000377) + d=000000 -- ! + d=000011 -- ! cmpb 000000,000001 -> n1z0v0c1; (000377+C) + d=000001 -- ! + d=000004 -- ! cmpb 000001,000001 -> n0z1v0c0; (000000) + d=000001 -- ! + d=000010 -- ! cmpb 000377,000001 -> n1z0v0c0; (000376) + d=000001 -- ! + d=000011 -- ! cmpb 000176,000177 -> n1z0v0c1; (000377+C) + d=000177 -- ! + d=000004 -- ! cmpb 000177,000177 -> n0z1v0c0; (000000) + d=000177 -- ! + d=000002 -- ! cmpb 000200,000177 -> n0z0v1c0; (000001) + d=000177 -- ! + d=000011 -- ! cmpb 000001,000177 -> n1z0v0c1; (000202+C) + d=000177 -- ! + d=000010 -- ! cmpb 000377,000177 -> n1z0v0c0; (000200) + d=000177 -- ! + d=000013 -- ! cmpb 000177,000200 -> n1z0v1c1; (000377+C) + d=000200 -- ! + d=000004 -- ! cmpb 000200,000200 -> n0z1v0c0; (000000) + d=000200 -- ! + d=000000 -- ! cmpb 000201,000200 -> n0z0v0c0; (000001) + d=000200 -- ! + d=000013 -- ! cmpb 000001,000200 -> n1z0v1c1; (000201+C) + d=000200 -- ! + d=000000 -- ! cmpb 000377,000200 -> n0z0v0c0; (000177) + d=000200 -- ! + d=000001 -- ! cmpb 000000,000377 -> n0z0v0c1; (000001+C) + d=000377 -- ! + d=000001 -- ! cmpb 000001,000377 -> n0z0v0c1; (000002+C) + d=000377 -- ! + d=000004 -- ! cmpb 000377,000377 -> n0z1v0c0; (000000) + d=000377 -- ! +#----------------------------------------------------------------------------- +C Setup code 47 [base 13400] (pipeline torture tests) +# +wal 013400 -- data: +wmi 000077 -- marker +wal 013402 -- code 1: +bwm 13 + 016727 -- mov -6(pc),(pc)+ ; + 177772 + 000000 -- halt ; will be overwritten + 016737 -- mov -10(pc),@(pc)+ ; + 177770 + 013400 + 005200 -- inc r0 ; +#13420 + 010317 -- mov r3,(pc) ; will overwrite next instruction + 000000 -- halt ; will be overwritten + 005200 -- inc r0 ; + 010447 -- mov r4,-(pc) ; will overwrite itself + 005200 -- inc r0 ; + 000000 -- halt ; +# +wal 013440 -- code 2: (pipeline tester adapted from KDJ11A.MAC) +bwm 15 + 012717 -- mov (pc)+,(pc) ; will replace jmp (r1) with nop + 000240 -- nop + 000111 -- jmp (r1) + 012717 -- mov (pc)+,(pc) ; will replace jmp (r1) with nop + 000240 -- nop + 000111 -- jmp (r1) + 012717 -- mov (pc)+,(pc) ; will replace jmp (r1) with nop + 000240 -- nop +#13460 + 000111 -- jmp (r1) + 012717 -- mov (pc)+,(pc) ; will replace jmp (r1) with nop + 000240 -- nop + 000111 -- jmp (r1) + 000000 -- halt ; should halt here ! + 000000 -- halt ; + 000000 -- halt ; should not jmp here ! +# +C Exec code 47 (pipeline torture tests) +C Exec test 47.1 (some self-modifying code, use (pc)+, (pc), -(pc)): +# +wr0 000000 -- r0=0 +wr1 000000 -- r1=0 +wr2 000000 -- r2=0 +wr3 005201 -- r3= inc r1 +wr4 005202 -- r4= inc r2 +stapc 013402 -- start @ 13402 +wtgo +rpc d=013434 -- ! pc +rr0 d=000003 -- ! r0 +rr1 d=000001 -- ! r1 +rr2 d=000001 -- ! r2 +rr3 d=005201 -- ! r3 +rr4 d=005202 -- ! r4 +# +wal 013400 -- check data area: +rmi d=177772 -- ! new marker ; written by mov -10(pc),@(pc)+ +wal 013402 -- check code area: +brm 13 + d=016727 -- ! mov -6(pc),(pc)+ ; + d=177772 -- ! + d=000077 -- ! ; written by mov -6(pc),(pc)+ + d=016737 -- ! mov -10(pc),@(pc)+; + d=177770 -- ! + d=013400 -- ! + d=005200 -- ! inc r0 ; +#13320 + d=010317 -- ! mov r3,(pc) ; + d=005201 -- ! inc r1 ; written by mov r3,(pc); executed + d=005200 -- ! inc r0 ; + d=005202 -- ! inc r2 ; written by mov r4,-(pc); executed + d=005200 -- ! inc r0 ; + d=000000 -- ! halt ; +# +C Exec test 47.1 (pipeline tester adapted from KDJ11A.MAC, test 121, p. 70) +# +wr1 013474 -- r1=13474 (alternate halt) +stapc 013440 -- start @ 13440 +wtgo +rpc d=013472 -- ! pc +wal 013440 -- check code area: +brm 13 + d=012717 -- ! mov (pc)+,(pc) ; + d=000240 -- ! nop + d=000240 -- ! nop ; written; executed + d=012717 -- ! mov (pc)+,(pc) ; + d=000240 -- ! nop + d=000240 -- ! nop ; written; executed + d=012717 -- ! mov (pc)+,(pc) ; + d=000240 -- ! nop +#13360 + d=000240 -- ! nop ; written; executed + d=012717 -- ! mov (pc)+,(pc) ; + d=000240 -- ! nop + d=000240 -- ! nop ; written; executed + d=000000 -- ! halt ; +#----------------------------------------------------------------------------- +C Setup code 50 [base 13500] (check that all reserved instructions trap to 10) +# +wal 013500 -- code (to be single stepped...) +bwm 17 + 000007 -- 000007 + 000010 -- 000010-000077 + 000077 -- + 000210 -- 000210-000227 + 000227 -- + 007000 -- 007000-007777 + 007777 -- + 075000 -- 075000-076777 +#13420 + 076777 -- + 106400 -- 106400-106477 + 106477 -- + 106700 -- 106700-106777 + 106777 -- + 107000 -- 107000-107777 + 107777 -- + 170000 -- 170000-177777 (no FPU) +#13440 + 177777 -- +# +C Exec code 50 (check that all reserved instructions trap to 10) +C Test odd address abort +# +rst -- console reset +wps 000000 -- clear psw +wal 001374 -- clean stack +bwm 2 + 000000 -- + 000000 -- +wsp 001400 -- sp=1400 +wpc 013500 -- pc=13500 +step -- step (000007): trap 10 [[s:2]] +rpc d=000012 -- ! pc=12 (trap 12 catch) [[s:14]] +rsp d=001374 -- ! sp=1374 +# +wsp 001400 -- sp=1400 +wpc 013502 -- pc=13502 +step -- step (000010): trap 10 [[s:2]] +rpc d=000012 -- ! pc=12 (trap 12 catch) [[s:14]] +rsp d=001374 -- ! sp=1374 +# +wsp 001400 -- sp=1400 +wpc 013504 -- pc=13504 +step -- step (000077): trap 10 [[s:2]] +rpc d=000012 -- ! pc=12 (trap 12 catch) [[s:14]] +rsp d=001374 -- ! sp=1374 +# +wsp 001400 -- sp=1400 +wpc 013506 -- pc=13506 +step -- step (000210): trap 10 [[s:2]] +rpc d=000012 -- ! pc=12 (trap 12 catch) [[s:14]] +rsp d=001374 -- ! sp=1374 +# +wsp 001400 -- sp=1400 +wpc 013510 -- pc=13510 +step -- step (000227): trap 10 [[s:2]] +rpc d=000012 -- ! pc=12 (trap 12 catch) [[s:14]] +rsp d=001374 -- ! sp=1374 +# +wsp 001400 -- sp=1400 +wpc 013512 -- pc=13512 +step -- step (007000): trap 10 [[s:2]] +rpc d=000012 -- ! pc=12 (trap 12 catch) [[s:14]] +rsp d=001374 -- ! sp=1374 +# +wsp 001400 -- sp=1400 +wpc 013514 -- pc=13514 +step -- step (007777): trap 10 [[s:2]] +rpc d=000012 -- ! pc=12 (trap 12 catch) [[s:14]] +rsp d=001374 -- ! sp=1374 +# +wsp 001400 -- sp=1400 +wpc 013516 -- pc=13516 +step -- step (075000): trap 10 [[s:2]] +rpc d=000012 -- ! pc=12 (trap 12 catch) [[s:14]] +rsp d=001374 -- ! sp=1374 +# +wsp 001400 -- sp=1400 +wpc 013520 -- pc=13520 +step -- step (076777): trap 10 [[s:2]] +rpc d=000012 -- ! pc=12 (trap 12 catch) [[s:14]] +rsp d=001374 -- ! sp=1374 +# +wsp 001400 -- sp=1400 +wpc 013522 -- pc=13522 +step -- step (106400): trap 10 [[s:2]] +rpc d=000012 -- ! pc=12 (trap 12 catch) [[s:14]] +rsp d=001374 -- ! sp=1374 +# +wsp 001400 -- sp=1400 +wpc 013524 -- pc=13524 +step -- step (106477): trap 10 [[s:2]] +rpc d=000012 -- ! pc=12 (trap 12 catch) [[s:14]] +rsp d=001374 -- ! sp=1374 +# +wsp 001400 -- sp=1400 +wpc 013526 -- pc=13526 +step -- step (106700): trap 10 [[s:2]] +rpc d=000012 -- ! pc=12 (trap 12 catch) [[s:14]] +rsp d=001374 -- ! sp=1374 +# +wsp 001400 -- sp=1400 +wpc 013530 -- pc=13530 +step -- step (106777): trap 10 [[s:2]] +rpc d=000012 -- ! pc=12 (trap 12 catch) [[s:14]] +rsp d=001374 -- ! sp=1374 +# +wsp 001400 -- sp=1400 +wpc 013532 -- pc=13532 +step -- step (107000): trap 10 [[s:2]] +rpc d=000012 -- ! pc=12 (trap 12 catch) [[s:14]] +rsp d=001374 -- ! sp=1374 +# +wsp 001400 -- sp=1400 +wpc 013534 -- pc=13534 +step -- step (107777): trap 10 [[s:2]] +rpc d=000012 -- ! pc=12 (trap 12 catch) [[s:14]] +rsp d=001374 -- ! sp=1374 +# +wsp 001400 -- sp=1400 +wpc 013536 -- pc=13536 +step -- step (170000): trap 10 [[s:2]] +rpc d=000012 -- ! pc=12 (trap 12 catch) [[s:14]] +rsp d=001374 -- ! sp=1374 +# +wsp 001400 -- sp=1400 +wpc 013540 -- pc=13540 +step -- step (177777): trap 10 [[s:2]] +rpc d=000012 -- ! pc=12 (trap 12 catch) [[s:14]] +rsp d=001374 -- ! sp=1374 +#----------------------------------------------------------------------------- +# +C Verify trap catchers integrity +# +wal 000004 -- vectors: 4...34 (trap catcher) +brm 14 + d=000006 -- ! PC:06 ; vector 4 + d=000000 -- ! PS:0 + d=000012 -- ! PC:12 ; vector 10 + d=000000 -- ! PS:0 + d=000016 -- ! PC:16 ; vector 14 (T bit; BPT) + d=000000 -- ! PS:0 + d=000022 -- ! PC:22 ; vector 20 (IOT) + d=000000 -- ! PS:0 + d=000026 -- ! PC:26 ; vector 24 (Power fail, not used) + d=000000 -- ! PS:0 + d=000032 -- ! PC:32 ; vector 30 (EMT) + d=000000 -- ! PS:0 + d=000036 -- ! PC:36 ; vector 34 (TRAP) + d=000000 -- ! PS:0 +wal 000240 -- vectors: 240,244,250 (trap catcher) +brm 6 + d=000242 -- ! PC:242 ; vector 240 (PIRQ) + d=000000 -- ! PS:0 + d=000246 -- ! PC:246 ; vector 244 (FPU) + d=000000 -- ! PS:0 + d=000252 -- ! PC:252 ; vector 250 (MMU) + d=000000 -- ! PS:0 +# +C Verify setup MMU +# to avoid seeing AIB bits: +# 1. check ARs; 2. re-write ARs to clear AIBs in DRs; 3. check DRs +# +wal 172340 -- kernel I space AR +brm 8 + d=000000 -- ! 0 + d=000200 -- ! 200 020000 base + d=000400 -- ! 400 040000 base + d=000600 -- ! 600 060000 base + d=001000 -- ! 1000 100000 base + d=001200 -- ! 1200 120000 base + d=001400 -- ! 1400 140000 base + d=177600 -- !176000 (map to I/O page) +# +wal 172340 -- kernel I space AR +bwm 8 + 000000 -- 0 + 000200 -- 200 020000 base + 000400 -- 400 040000 base + 000600 -- 600 060000 base + 001000 -- 1000 100000 base + 001200 -- 1200 120000 base + 001400 -- 1400 140000 base + 177600 -- 176000 (map to I/O page) +# +wal 172300 -- kernel I space DR +brm 8 + d=077406 -- ! slf=127; ed=0(up); acf=6(w/r) + d=077406 -- ! slf=127; ed=0(up); acf=6(w/r) + d=077406 -- ! slf=127; ed=0(up); acf=6(w/r) + d=077406 -- ! slf=127; ed=0(up); acf=6(w/r) + d=077406 -- ! slf=127; ed=0(up); acf=6(w/r) + d=077406 -- ! slf=127; ed=0(up); acf=6(w/r) + d=077406 -- ! slf=127; ed=0(up); acf=6(w/r) + d=077406 -- ! slf=127; ed=0(up); acf=6(w/r) +# +wal 000000 -- last cmd shouldn't be 21 or 23 ... diff --git a/rtl/w11a/tb/tbd_pdp11_core.vbom b/rtl/w11a/tb/tbd_pdp11_core.vbom new file mode 100644 index 00000000..16a58662 --- /dev/null +++ b/rtl/w11a/tb/tbd_pdp11_core.vbom @@ -0,0 +1,15 @@ +# libs +../../vlib/slvtypes.vhd +../../vlib/genlib/genlib.vhd +../../ibus/iblib.vhd +../../ibus/ibdlib.vhd +../pdp11.vbom +sys_conf : ../sys_conf.vhd +# components +../../vlib/genlib/clkdivce.vbom +../pdp11_core.vbom +../pdp11_bram.vbom +../../ibus/ibdr_minisys.vbom +[ghdl,isim]../pdp11_tmu_sb.vbom +# design +tbd_pdp11_core.vhd diff --git a/rtl/w11a/tb/tbd_pdp11_core.vhd b/rtl/w11a/tb/tbd_pdp11_core.vhd new file mode 100644 index 00000000..5ddb18aa --- /dev/null +++ b/rtl/w11a/tb/tbd_pdp11_core.vhd @@ -0,0 +1,222 @@ +-- $Id: tbd_pdp11_core.vhd 314 2010-07-09 17:38:41Z mueller $ +-- +-- Copyright 2007-2010 by Walter F.J. Mueller +-- +-- This program is free software; you may redistribute and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation, either version 2, 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 complete details. +-- +------------------------------------------------------------------------------ +-- Module Name: tbd_pdp11_core - syn +-- Description: Wrapper for pdp11_core to avoid records. It has a port +-- interface which will not be modified by xst synthesis +-- (no records, no generic port). +-- +-- Dependencies: genlib/clkdivce +-- pdp11_core +-- pdp11_bram +-- ibus/ibdr_minisys +-- pdp11_tmu_sb [sim only] +-- +-- To test: pdp11_core +-- +-- Target Devices: generic +-- Tool versions: xst 8.1, 8.2, 9.1, 9.2; ghdl 0.18-0.25 +-- +-- Synthesized (xst): +-- Date Rev ise Target flop lutl lutm slic t peri +-- 2010-06-13 305 11.4 L68 xc3s1000-4 601 2504 206 1428 s 18.6 +-- 2008-03-01 120 8.2.03 I34 xc3s1000-4 679 2562 206 1465 s 18.5 +-- 2008-01-06 111 8.2.03 I34 xc3s1000-4 605 2324 164 1297 s 18.7 +-- 2007-12-30 107 8.2.03 I34 xc3s1000-4 536 2119 119 1184 s 19.3 +-- 2007-10-27 92 9.2.02 J39 xc3s1000-4 INTERNAL_ERROR -> blog_webpack +-- 2007-10-27 92 9.1 J30 xc3s1000-4 503 2021 119 - t 18.7 +-- 2007-10-27 92 8.2.03 I34 xc3s1000-4 534 2091 119 1170 s 19.3 +-- 2007-10-27 92 8.1.03 I27 xc3s1000-4 557 2186 119 - s 18.6 +-- +-- Revision History: +-- Date Rev Version Comment +-- 2010-06-20 307 1.4.1 add CP_ADDR_racc, CP_ADDR_be port +-- 2010-06-13 305 1.4 add CP_ADDR_... in ports; add CP_CNTL_rnum in port +-- 2010-06-11 303 1.3.9 use IB_MREQ.racc instead of RRI_REQ +-- 2009-07-12 233 1.3.8 adapt to ibdr_minisys interface changes +-- 2009-05-10 214 1.3.7 use pdp11_tmu_sb instead of pdp11_tmu +-- 2008-08-22 161 1.3.6 use iblib, ibdlib +-- 2008-05-03 143 1.3.5 rename _cpursta->_cpurust +-- 2008-04-27 140 1.3.4 use cpursta interface, remove cpufail +-- 2008-04-19 137 1.3.3 add DM_STAT_(DP|VM|CO|SY) signals, add pdp11_tmu +-- 2008-04-18 136 1.3.2 add RESET for ibdr_minisys +-- 2008-02-23 118 1.3.1 use sys_conf for bram size +-- 2008-02-17 117 1.3 adapt to em_ core interface; use pdp11_bram +-- 2008-01-20 112 1.2.1 rename clkgen->clkdivce; use ibdr_minisys, BRESET; +-- 2008-01-06 111 1.2 add some external devices: KW11L, DL11, RK11 +-- 2007-12-30 107 1.1 use IB_MREQ/IB_SRES interface now; remove DMA port +-- 2007-09-23 85 1.0 Initial version +------------------------------------------------------------------------------ + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; + +use work.slvtypes.all; +use work.genlib.all; +use work.iblib.all; +use work.ibdlib.all; +use work.pdp11.all; +use work.sys_conf.all; + +entity tbd_pdp11_core is -- full core [no records] + port ( + CLK : in slbit; -- clock + RESET : in slbit; -- reset + CP_CNTL_req : in slbit; -- console control port + CP_CNTL_func : in slv5; -- console control port + CP_CNTL_rnum : in slv3; -- console control port + CP_ADDR_addr : in slv22_1; -- console address port + CP_ADDR_racc : in slbit; -- console address port + CP_ADDR_be : in slv2; -- console address port + CP_ADDR_ena_22bit : in slbit; -- console address port + CP_ADDR_ena_ubmap : in slbit; -- console address port + CP_DIN : in slv16; -- console data in + CP_STAT_cmdbusy : out slbit; -- console status port + CP_STAT_cmdack : out slbit; -- console status port + CP_STAT_cmderr : out slbit; -- console status port + CP_STAT_cmdmerr : out slbit; -- console status port + CP_STAT_cpugo : out slbit; -- console status port + CP_STAT_cpuhalt : out slbit; -- console status port + CP_STAT_cpustep : out slbit; -- console status port + CP_STAT_cpurust : out slv4; -- console status port + CP_DOUT : out slv16 -- console data out + ); +end tbd_pdp11_core; + + +architecture syn of tbd_pdp11_core is + + signal CE_USEC : slbit := '0'; + + signal EI_PRI : slv3 := (others=>'0'); + signal EI_VECT : slv9_2 := (others=>'0'); + signal EI_ACKM : slbit := '0'; + + signal CP_CNTL : cp_cntl_type := cp_cntl_init; + signal CP_ADDR : cp_addr_type := cp_addr_init; + signal CP_STAT : cp_stat_type := cp_stat_init; + + signal EM_MREQ : em_mreq_type := em_mreq_init; + signal EM_SRES : em_sres_type := em_sres_init; + + signal BRESET : slbit := '0'; + signal IB_MREQ_M : ib_mreq_type := ib_mreq_init; + signal IB_SRES_M : ib_sres_type := ib_sres_init; + + signal DM_STAT_DP : dm_stat_dp_type := dm_stat_dp_init; + signal DM_STAT_VM : dm_stat_vm_type := dm_stat_vm_init; + signal DM_STAT_CO : dm_stat_co_type := dm_stat_co_init; + signal DM_STAT_SY : dm_stat_sy_type := dm_stat_sy_init; + +begin + + CP_CNTL.req <= CP_CNTL_req; + CP_CNTL.func <= CP_CNTL_func; + CP_CNTL.rnum <= CP_CNTL_rnum; + + CP_ADDR.addr <= CP_ADDR_addr; + CP_ADDR.racc <= CP_ADDR_racc; + CP_ADDR.be <= CP_ADDR_be; + CP_ADDR.ena_22bit <= CP_ADDR_ena_22bit; + CP_ADDR.ena_ubmap <= CP_ADDR_ena_ubmap; + + CP_STAT_cmdbusy <= CP_STAT.cmdbusy; + CP_STAT_cmdack <= CP_STAT.cmdack; + CP_STAT_cmderr <= CP_STAT.cmderr; + CP_STAT_cmdmerr <= CP_STAT.cmdmerr; + CP_STAT_cpugo <= CP_STAT.cpugo; + CP_STAT_cpuhalt <= CP_STAT.cpuhalt; + CP_STAT_cpustep <= CP_STAT.cpustep; + CP_STAT_cpurust <= CP_STAT.cpurust; + + CLKDIV : clkdivce + generic map ( + CDUWIDTH => 6, + USECDIV => 50, + MSECDIV => 1000) + port map ( + CLK => CLK, + CE_USEC => CE_USEC, + CE_MSEC => open + ); + + PDP11 : pdp11_core + port map ( + CLK => CLK, + RESET => RESET, + CP_CNTL => CP_CNTL, + CP_ADDR => CP_ADDR, + CP_DIN => CP_DIN, + CP_STAT => CP_STAT, + CP_DOUT => CP_DOUT, + EI_PRI => EI_PRI, + EI_VECT => EI_VECT, + EI_ACKM => EI_ACKM, + EM_MREQ => EM_MREQ, + EM_SRES => EM_SRES, + BRESET => BRESET, + IB_MREQ_M => IB_MREQ_M, + IB_SRES_M => IB_SRES_M, + DM_STAT_DP => DM_STAT_DP, + DM_STAT_VM => DM_STAT_VM, + DM_STAT_CO => DM_STAT_CO + ); + + MEM : pdp11_bram + generic map ( + AWIDTH => sys_conf_bram_awidth) + port map ( + CLK => CLK, + GRESET => RESET, + EM_MREQ => EM_MREQ, + EM_SRES => EM_SRES + ); + + IBDR_SYS : ibdr_minisys + port map ( + CLK => CLK, + CE_USEC => CE_USEC, + CE_MSEC => CE_USEC, -- !! in test benches msec = usec !! + RESET => RESET, + BRESET => BRESET, + RRI_LAM => open, + IB_MREQ => IB_MREQ_M, + IB_SRES => IB_SRES_M, + EI_ACKM => EI_ACKM, + EI_PRI => EI_PRI, + EI_VECT => EI_VECT, + DISPREG => open + ); + +-- synthesis translate_off + + DM_STAT_SY.emmreq <= EM_MREQ; + DM_STAT_SY.emsres <= EM_SRES; + DM_STAT_SY.chit <= '0'; + + TMU : pdp11_tmu_sb + generic map ( + ENAPIN => 13) + port map ( + CLK => CLK, + DM_STAT_DP => DM_STAT_DP, + DM_STAT_VM => DM_STAT_VM, + DM_STAT_CO => DM_STAT_CO, + DM_STAT_SY => DM_STAT_SY + ); + +-- synthesis translate_on + +end syn; diff --git a/rtl/w11a/tb/tbw.dat b/rtl/w11a/tb/tbw.dat new file mode 100644 index 00000000..0389b247 --- /dev/null +++ b/rtl/w11a/tb/tbw.dat @@ -0,0 +1,12 @@ +# $Id: tbw.dat 311 2010-06-30 17:52:37Z mueller $ +# +[tb_rritba_pdp11core] +tb_rritba_stim = tb_rritba_pdp11core_stim.dat +# +[tb_rripdp_pdp11core] +tb_rripdp_stim = tb_pdp11_core_stim.dat +# +[tb_rriext_pdp11core] +tb_rriext_fifo_rx = +tb_rriext_fifo_tx = +tb_rriext_conf = diff --git a/tools/bin/impact_wrapper b/tools/bin/impact_wrapper new file mode 100755 index 00000000..3f9cad56 --- /dev/null +++ b/tools/bin/impact_wrapper @@ -0,0 +1,113 @@ +#!/usr/bin/perl -w +# $Id: impact_wrapper 314 2010-07-09 17:38:41Z mueller $ +# +# Copyright 2010- by Walter F.J. Mueller +# +# This program is free software; you may redistribute and/or modify it under +# the terms of the GNU General Public License as published by the Free +# Software Foundation, either version 2, 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 complete details. +# +# Revision History: +# Date Rev Version Comment +# 2010-05-24 294 1.0.2 support nexys2/xc3s1200e +# 2010-04-24 282 1.0.1 proper error exit for GetOptions() +# 2010-04-24 281 1.0 Initial version +# + +use 5.005; # require Perl 5.005 or higher +use strict; # require strict checking +use FileHandle; + +use Getopt::Long; + +my %opts = (); + +$opts{board} = "s3board"; +$opts{path} = "xc3s1000"; + +GetOptions(\%opts, "help", "board=s", "path=s") or exit 1; + +sub print_help; + +autoflush STDOUT 1 if (-p STDOUT); # autoflush if output into pipe + +if (exists $opts{help}) { + print_help; + exit 0; +} + +my $board = $opts{board}; +my $ipath = $opts{path}; + +$ipath =~ s/-.*$//; # trim all after first '-' + +# at this point just support Digilent s3board with xc3s200 or xc3s1000 + +my $part2; + +if ($board eq "s3board" && $ipath eq "xc3s200") { + $part2 = "xcf02s"; +} elsif ($board eq "s3board" && $ipath eq "xc3s1000") { + $part2 = "xcf04s"; +} elsif ($board eq "nexys2" && $ipath eq "xc3s1200e") { + $part2 = "xcf04s"; +} else { + print STDERR "impact_wrapper-E: only s3board/nexys2 supported\n"; + exit 1; +} + +my $file = shift @ARGV; + +if (! defined $file) { + print STDERR "impact_wrapper-E: no bit file specified\n"; + exit 1; +} +if (! -r $file) { + print STDERR "impact_wrapper-E: input file not found or readable\n"; + exit 1; +} + +my $tmpfile = "tmp_impact_wrapper.cmd"; + +open (OFILE, ">$tmpfile") or die "Couldn't open tmp cmd file: $!"; + +print OFILE "setMode -bs\n"; +print OFILE "setCable -p auto\n"; +print OFILE "addDevice -p 1 -part $ipath\n"; +print OFILE "addDevice -p 2 -part $part2\n"; +print OFILE "assignFile -p 1 -file $file\n"; +print OFILE "program -p 1 -verify\n"; +print OFILE "quit\n"; + +close (OFILE) or die "Couldn't close tmp cmd file: $!"; + +my $wrc = system "/bin/sh", "-c", "impact -batch $tmpfile"; +my $rc = 0; +if ($wrc != 0) { + my $rc = int($wrc/256); + if ($rc == 0) { + my $sig = $wrc % 256; + print STDERR "impact_wrapper-I impact aborted by signal $sig\n"; + $rc = 1; + } else { + print STDERR "impact_wrapper-I impact failed (rc=$rc) $?\n"; + } +} + +unlink $tmpfile or die "Couldn't delete tmp cmd file: $!"; + +exit $rc; + +#------------------------------------------------------------------------------- + +sub print_help { + print "usage: impact_wrapper [--help] [--board=b] [--path=p] file\n"; + print " --help this message\n"; + print " --board=b type of board\n"; + print " --path=p type of fpga\n"; +} diff --git a/tools/bin/pi_rri b/tools/bin/pi_rri new file mode 100755 index 00000000..00d9a3b8 --- /dev/null +++ b/tools/bin/pi_rri @@ -0,0 +1,7197 @@ +#!/usr/bin/perl -w +# $Id: pi_rri 314 2010-07-09 17:38:41Z mueller $ +# +# Copyright 2007-2010 by Walter F.J. Mueller +# +# This program is free software; you may redistribute and/or modify it under +# the terms of the GNU General Public License as published by the Free +# Software Foundation, either version 2, 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 complete details. +# +# Revision History: +# Date Rev Version Comment +# 2010-06-27 310 1.6.2 fix autoflush for fh_log; duplicate exec err to log +# 2010-06-18 306 1.6.1 PDPCP_ADDR_IBRB now 020, PDPCP_ADDR_IBR now 0200; +# ibrbase now just drops the 6 lsb's; pdpcp mode: +# rename librb -> wibrb; finished cp/rri overhaul +# 2010-06-13 305 1.6 change PDPCP_ADDR_ assignments, add PDPCP_FUNC_ +# constants; adapt pdpcp mode to changed rri addr and +# stim file format; emulate old 'sta' behaviour with +# new 'stapc' command; rename lal,lah -> wal,wah and +# implement locally; adapt serv11 mode to new rri +# 2010-06-11 303 1.5.1 add cmd_inter; flush{"line"} after interactive cmd +# added readline support. +# 2010-06-07 302 1.5 use sop/eop framing instead of soc+chaining +# 2010-06-06 301 1.4.18 rename .rpmon->.rbmon; NCOMM=4 (new eop,nak commas) +# 2010-06-03 299 1.4.17 adapt .reset to new rbus init decode +# 2010-05-05 288 1.4.16 first preliminary implementation of eval based +# perl macro's via @@pmac; add ^C signal handler; +# added optional min/max check for cget_gdat() and +# cget_tagval_gdat(). +# 2010-05-02 287 1.4.15 enable hardware flow control in termios +# 2010-05-01 286 1.4.14 add .sinit command for rri and pdpcp modes; +# add 500k,1M,2M,3M baudrates, check value now +# 2010-04-26 284 1.4.13 add error check for GetOptions +# 2010-04-25 283 1.4.12 raw_rcv9_to: handle undef as return value correctly +# 2009-10-11 244 1.4.11 support > 115kbaud speed; new stat output in log; +# use nxbuf_max=8 as default; +# 2009-09-27 242 1.4.10 add "ERR --" messages in log file; fix usage of +# uninitialized vars in serv11_exec_probe(); +# 2009-09-25 241 1.4.9 BUGFIX: serv11_server_attn_get() now or's attn bits +# 2009-09-20 240 1.4.8 serv11_rri_uset cache under $ctl, not in unittbl +# 2009-09-13 238 1.4.7 add ctlname for DL11 log entries; only TTA output +# written to stdout when no terminal attached. +# 2009-07-26 236 1.4.6 fix cpraw mode and .mode error handling; +# 2009-07-12 233 1.4.5 add attach/detach support for term; telnet support; +# 2009-07-05 232 1.4.4 add cchk_number(), cget_regrange(); rename _atdt_ to +# _attdet_; serv11: add exa/dep command; removed +# rr[0-7], wr[0-7], rmem, and wmem commands; new probe +# handling, use {probe_[ir]val} and {probemask}; +# serv11: command parser supports abbeviations; +# serv11: add set/sho command, reorganize ls* cmds; +# serv11: add {trace} parameter; rri_sideband() flush; +# 2009-07-04 231 1.4.3 first reglist definitions; add CPU in _ctltbl; +# add serv11_probe_cpu(); +# 2009-06-28 230 1.4.2 use serv11_atdt_pc11(), remove atdt via ucb hack; +# add serv11_rri_uset(); pc11 now fully supported; +# attn log message now gives device; use -e as file +# test; add ptape boot mode support; lsconf output +# sorted by ibus address; +# 2009-06-21 228 1.4.1 BUGFIX: correct typo in RK6 ucb; reorganize init +# handling, introduce usethdl; reorganize attach; +# add atdthdl at ctl or ucb level; add det command; +# 2009-06-20 227 1.4 nxbuf_min,max,inc now a ctl property; +# 2009-06-14 226 1.3.31 add very preliminary lp11 device handling +# 2009-06-11 225 1.3.30 quick hack to add dl11 log files. +# 2009-05-30 220 1.3.29 add papertape boot code; +# 2009-05-24 219 1.3.28 add papertape hook as dev "PC" units "PTR" and "PTP" +# 2009-05-21 217 1.3.27 rk11: now error message when init not done +# 2009-05-17 216 1.3.26 BUGFIX:rk11: fix read/write logic for short sectors; +# BUGFIX:rk11: re-work the seek complete handling +# add read/write check support; add PGE error support; +# 2009-05-13 215 1.3.25 dl11: drop parity bit in transmit path; +# rk11: add read/write format; set SOK at init time; +# 2009-05-10 214 1.3.24 BUGFIX: in serv11_attn_rk11() RKER was written +# instead of RKMR for RKCS_DRESET, _WLOCK, _SEEK +# 2009-04-11 206 1.3.23 add --int to force interactive mode +# fix handling of odd length records in lsabs +# 2008-12-14 177 1.3.22 correct DL11_BASE_B to 176500 (was RL address) +# 2008-11-28 173 1.3.21 serv11_rri_lalh(): allow now mode =0,1,2 and 3; +# serv11_rdma_rk11(): use mode=3 in rri_lalh, thus +# enable 22bit and ubmap simultaneously. +# add proper MEX update for RKCS in rdma_rk11. +# add proper DRSEL propagation for RKDA in rdma_rk11. +# 2008-05-30 151 1.3.20 BUGFIX: corrected @que_rcv logic in serv11 input +# loop, TT0 output will not longer hang sometimes; +# disable the attn+ioto(16 or 63 ms) hack; +# 2008-05-23 150 1.3.19 tio[89b] messages: to $fh_log now, add delta-time; +# fixes in disk extend logic and messages; add the +# (^c form of ( command; add adaptive read vector +# in serv11_attn_dl11; +# 2008-05-22 149 1.3.18 add term_tios_print, fixes for --term under cygwin; +# 2008-05-22 148 1.3.17 add (,< short-cut commands +# 2008-05-18 147 1.3.16 ATTN comma drop now warning, -W (was -I); +# 2008-05-12 145 1.3.15 rename ldpta -> ldabs +# 2008-05-09 144 1.3.14 disable call in attn_dispatch(1) (needs busy logic) +# 2008-05-01 142 1.3.13 serv11: add stop,cont,reset; add $force for attn +# handlers; use attn+ioto(16ms) to avoid TTO hangs +# 2008-05-01 141 1.3.12 write TTO char-by-char now to STDOUT +# 2008-04-25 138 1.3.11 show ccc/scc for code 000257/000277 in disassembler +# 2008-04-19 137 1.3.10 minor fix disassembler: use f reg prefix for f4,f5 +# 2008-04-18 136 1.3.9 hack in a poor man's output to console... +# 2008-04-13 135 1.3.8 substitute environment variables in cmd file names +# 2008-04-11 134 1.3.7 allow line comments starting with ";" (for simh) +# 2008-04-06 133 1.3.6 fix file check in serv11_cexec_ldpta; fix wrong +# opcode for mfps; fixed bug in disassembling mode=77 +# add -a for lsmem; +# 2008-04-04 132 1.3.5 add in disassembler non-11/70 and fpp codes; +# add (>|>>)file option for lsmem (redirect to file) +# 2008-03-39 131 1.3.4 lsmem -m: use now wide (3 word) symbolic dump format +# add ldpta command (load paper tape abs format) +# add start and step command +# 2008-03-24 129 1.3.3 allow comments when in serv11 server mode. +# check attach file size; zero-fill after partial +# block write; reorganize dsk file and rdma handling +# leading blanks now ignored in commands +# 2008-03-22 128 1.3.2 fully functional server mode (todo: TT <-> telnet) +# 2008-03-19 127 1.3.1 very preliminary server mode now working +# 2008-03-09 124 1.3 add serv11 mode; add PDP11 disamssebler +# 2008-03-02 121 1.2.5 the default .sdef now checks for hard errors. +# the _open handlers for rri and pdpcp setup default +# Add .cerr, .merr as ignored directives for pdpcp +# 2008-02-24 119 1.2.4 added lah,rps,wps command in .pdpcp mode +# 2008-02-16 116 1.2.3 add librb,[rw]ibr,and wtlam to pdpcp command set +# 2007-12-25 105 1.2.2 for rri mode add .dbas[io] (set base for data vals) +# add ${par}, ${par:=val}, ${par:-val} substitution +# allow parameter definition via par=val lines +# add $[..perl code..] escape to embed perl code +# allow @file(arg1,arg2,arg3,...); print .wtlam wait +# 2007-11-24 98 1.2.1 adapt to new rri internal init handling +# 2007-11-18 96 1.2 add 'read before write' logic to avoid deadlocks +# under cygwin broken fifo (size=1 !) implementation +# 2007-10-12 88 1.1.4 fix some -w issues +# 2007-09-23 84 1.1.3 .reset command in pdpcp mode; keep-alive in --fifo +# 2007-09-16 83 1.1.2 add --cmax; full --term implemented +# 2007-09-09 80 1.1.1 add --run; modularize I/O handling; initial --term +# proper return code / retry loop for sysread/write +# 2007-09-09 80 1.1 new non-blocking/blocking handling; ignore IDLE's +# and unexpected ATTN commas; add _flush; add +# data check handling, command chaining, 'pdpcp' mode. +# 2007-09-02 79 1.0.1 implement 'rri' mode +# 2007-09-01 78 1.0 Initial version + +use 5.005; # require Perl 5.005 or higher +use strict; # require strict checking + +use FileHandle; +use POSIX qw(mkfifo isatty :termios_h); +use Fcntl qw(O_WRONLY O_RDONLY O_NOCTTY); +use Errno qw(EINTR); +use Time::HiRes qw(gettimeofday); +use Socket; +use Term::ReadLine; + +use constant CPREF => 0x80; +use constant NCOMM => 4; +use constant CESC => CPREF|0x0f ; +use constant CEN1 => (~CPREF)&0xf0; +use constant D9IDLE => 0x100; +use constant D9SOP => 0x101; +use constant D9EOP => 0x102; +use constant D9NAK => 0x103; +use constant D9ATTN => 0x104; + +use constant PDPCP_ADDR_CONF => 000; +use constant PDPCP_ADDR_CNTL => 001; +use constant PDPCP_ADDR_STAT => 002; +use constant PDPCP_ADDR_PSW => 003; +use constant PDPCP_ADDR_AL => 004; +use constant PDPCP_ADDR_AH => 005; +use constant PDPCP_ADDR_MEM => 006; +use constant PDPCP_ADDR_MEMI => 007; +use constant PDPCP_ADDR_R0 => 010; +use constant PDPCP_ADDR_PC => 017; +use constant PDPCP_ADDR_IBRB => 020; +use constant PDPCP_ADDR_IBR => 0200; + +use constant PDPCP_FUNC_NOOP => 000; +use constant PDPCP_FUNC_STA => 001; +use constant PDPCP_FUNC_STO => 002; +use constant PDPCP_FUNC_CONT => 003; +use constant PDPCP_FUNC_STEP => 004; +use constant PDPCP_FUNC_RST => 017; + +use constant LINUX_B57600 => 0010001; # B57600 not part of POSIX package ! +use constant LINUX_B115200 => 0010002; # in linux these values are in +use constant LINUX_B230400 => 0010003; # termios.h, specifically in +use constant LINUX_B460800 => 0010004; # /usr/include/bits/termios.h +use constant LINUX_B500000 => 0010005; +use constant LINUX_B576000 => 0010006; +use constant LINUX_B921600 => 0010007; +use constant LINUX_B1000000 => 0010010; +use constant LINUX_B2000000 => 0010013; +use constant LINUX_B3000000 => 0010015; + +use constant LINUX_CRTSCTS => 020000000000; # ! Not part of POSIX !! + +use Getopt::Long; + +my %opts = (); + +GetOptions(\%opts, "help", "int", "trace", + "tio8", "tio9", "tiob", + "dserv", "tserv", "log:s", + "fifo:s", "term:s", + "timeout=f", "cmax=i", + "run=s", + ) + or die "bad options"; + +sub init_regtbl; # initialize regtbl from reglist +sub get_command; +sub do_command; +sub read_command; +sub setpar_command; +sub nomode_open; +sub nomode_flush; +sub nomode_close; +sub nomode_cexec; +sub cpraw_open; +sub cpraw_flush; +sub cpraw_close; +sub cpraw_cexec; +sub do_cprx; +sub do_cptx; +sub cpraw_tx_match_now; +sub cpraw_tx_match; +sub rri_open; +sub rri_flush; +sub rri_close; +sub rri_cexec; +sub rri_cget_stat; +sub rri_cget_addr; +sub rri_cget_nblk; +sub rri_sideband; +sub rri_cmdlist_do; +sub rri_cmdlist_dump; +sub rri_cmdlist_exec; +sub rri_cmdlist_check_stat; +sub rri_cmdlist_get_rval; +sub rri_cmdlist_conv_rval; +sub rri_ref_check; # check reference data (1=err) +sub pdpcp_open; +sub pdpcp_flush; +sub pdpcp_close; +sub pdpcp_cexec; +sub pdpcp_cmd_rreg; +sub pdpcp_cmd_wreg; +sub serv11_open; +sub serv11_flush; +sub serv11_close; +sub serv11_cexec; +sub serv11_cexec_shoreg; +sub serv11_cexec_shommu_ssrx; +sub serv11_cexec_shommu_sadr; +sub serv11_cexec_ldabs; +sub serv11_cexec_shoconf; +sub serv11_cexec_shoatt; +sub serv11_cexec_attdet; +sub serv11_cexec_boot; +sub serv11_cexec_exa; +sub serv11_cexec_dep; +sub serv11_config; +sub serv11_init_dispatch; +sub serv11_server; +sub serv11_server_attn_get; +sub serv11_server_attn_dispatch; +sub serv11_probe_gen; # generic probe handler +sub serv11_init_gen; # generic controller init handler +sub serv11_detach_gen; # generic detach handler +sub serv11_attdet_disk; # generic disk att/det handler +sub serv11_attdet_ronly; # generic in only att/det handler +sub serv11_attdet_wonly; # generic out only att/det handler +sub serv11_attdet_term; # generic term att/det handler +sub serv11_probe_cpu; # cpu: probe handler +sub serv11_attn_cpu; # cpu: attention handler +sub serv11_exadep_cpu; # cpu: exa/dep handler +sub serv11_ichr_dl11; +sub serv11_attn_dl11; +sub serv11_uset_lp11; +sub serv11_attn_lp11; +sub serv11_uset_pc11; +sub serv11_attdet_pc11; +sub serv11_attn_pc11; +sub serv11_uset_rk11; +sub serv11_attn_rk11; +sub serv11_attn_rk11_logerr; +sub serv11_rdma_rk11; +sub serv11_icb_disk_read; # read one dsk file block +sub serv11_icb_disk_write; # write one dsk file block +sub serv11_rri_init; # issue rri init command +sub serv11_rri_attn; # issue rri attn command +sub serv11_rri_stat; # issue rri stat command +sub serv11_rri_rreg; # issue rri rreg command +sub serv11_rri_wreg; # issue rri wreg command +sub serv11_rri_rblk; # issue rri rblk command +sub serv11_rri_wblk; # issue rri wblk command +sub serv11_rri_lalh; # issue pdpcp lal and lah commands +sub serv11_rri_ibrb; # issue rbus set base address +sub serv11_rri_ribr; # issue rbus read +sub serv11_rri_wibr; # issue rbus write +sub serv11_rri_clear; +sub serv11_rri_exec; +sub serv11_rri_uset; # issue rbus uset writes +sub serv11_exec_rblk; +sub serv11_exec_wblk; +sub serv11_exec_probe; +sub next_nxbuf; # calculate next nxbuf value +sub telnet_readhdl; # telnet: socket read handler +sub telnet_writehdl; # telnet: write handler +sub pdp11_disassemble; # simple PDP11 disassembler +sub pdp11_disassemble_regmod; # helper +sub file_seek; # fseek wrapper +sub file_read; # fread wrapper +sub file_seek_read; # fseek+fread wrapper +sub file_write; # fwrite wrapper +sub file_seek_write; # fseek+fwrite wrapper +sub raw_get9_crc_16bit; # read 16 bit value +sub raw_get9_crc_8bit; # read 8bit value +sub raw_get9_crc_check; # get 9bit, block, crc, ref value +sub raw_get9_check; # get 9bit, block, expect ref value +sub raw_get9_checksop; # get 9bit, block, expect 'sop' +sub raw_get9_checkeop; # get 9bit, block, expect 'eop' +sub raw_get9_crc; # get 9bit, block, update crc +sub raw_get9; # get 9bit, block +sub raw_snd9_crc; # put 9bit to RX, update crc +sub raw_snd9; # put 9bit to RX +sub raw_snd8; # put 8bit to RX +sub raw_rcv9; # get 9bit from TX, non-blocking +sub raw_rcv8; # get 8bit from TX, non-blocking +sub raw_rcv9_to; # get 9bit from TX, expl. time-out +sub raw_rcv8_to; # get 8bit from TX, expl. time-out +sub wait_sel_filercv; # poll/wait for RCV to be ready +sub fifo_open; # chan fifo: open handler +sub fifo_close; # chan fifo: close handler +sub term_open; # chan term: open handler +sub term_close; # chan term: close handler +sub term_tios_print; # chan term: print termios state +sub genio_read; # generic io: read handler +sub genio_write; # generic io: write handler +sub cget_chkblank; # check for unused chars in cmd line +sub cget_tagval2_gdat; # get tag=v1[,v2], generic base +sub cget_tagval_gdat; # get tag=val, generic base +sub cget_gdat; # get generic base value +sub cget_name; # get name \w+ +sub cget_bool; # get boolean [01] +sub cget_file; # get filename [\w\/.]+ +sub cget_ucb; # get ucb (read name, return ucb) +sub cget_opt; # get option +sub cget_optset; # get option set +sub cget_regrange; # get register/memory range +sub cchk_number; # check for number. any gdat value +sub sget_bdat; # convert 01 string -> binary value +sub conv_etime; # generate timestamp string +sub conv_dat9; +sub conv_dat8; +sub conv_str2bytes; # string to bytelist; handle \n +sub conv_buf2wlist; # string buffer -> word list +sub conv_wlist2buf; # word list -> string buffer +sub conv_byte2ascii2; # byte -> 2 charcter ASCII display +sub gconv_dat16; +sub hdl_sigint; # SIGINT handler +sub get_time; +sub get_timestamp; +sub filename_expand; # expand $nnn in name +sub print_fatal; +sub print_help; + +my %stat_tab = ( obyte => 0., + oesc => 0., + osop => 0., + ibyte => 0., + iesc => 0., + att => 0., + xreg => 0., + xblk => 0., + rdisk => 0., + wdisk => 0.); +my %stat_tab_last = %stat_tab; + +my %mode_tab = (nomode => {open => \&nomode_open, + flush => \&nomode_flush, + close => \&nomode_close, + cmd => \&nomode_cexec}, + cpraw => {open => \&cpraw_open, + flush => \&cpraw_flush, + close => \&cpraw_close, + cmd => \&cpraw_cexec}, + rri => {open => \&rri_open, + flush => \&rri_flush, + close => \&rri_close, + cmd => \&rri_cexec}, + pdpcp => {open => \&pdpcp_open, + flush => \&pdpcp_flush, + close => \&pdpcp_close, + cmd => \&pdpcp_cexec}, + serv11 => {open => \&serv11_open, + flush => \&serv11_flush, + close => \&serv11_close, + cmd => \&serv11_cexec} + ); + +my %chan_tab = (fifo => {open => \&fifo_open, + close => \&fifo_close, + read => \&genio_read, + write => \&genio_write}, + term => {open => \&term_open, + close => \&term_close, + read => \&genio_read, + write => \&genio_write} + ); + +my $curmode = "nomode"; +my $curcmd = \&nomode_cexec; +my $curchan = undef; +my @cmdfh; +my @cmdfn; +my @cmdargs; +my $time0 = -1; +my $tlast_tio8 = 0; +my $tlast_tio9 = 0; +my $tlast_tiob = 0; + +my @que_rcv; +my @que_snd; + +my @cpraw_tx_read; +my @cpraw_tx_expt; + +my $fh_log = *STDOUT; +my $fh_snd; +my $fh_rcv; +my $fdset_filercv; +my $fifo_keep; +my $term_oldtios; +my $raw_rcv_esc = 0; +my $raw_timeout = 1.; +my $cmax = 16; + +my $cmd_line; +my $cmd_rest; +my $cmd_bad; +my $cmd_inter; # interactive cmd flag + +my $term; +if (-t STDIN) { + $term = new Term::ReadLine 'pi_rri'; +} + +my %par; # params for command line substitution +my $sigint_count = 0; # SIGINT counter + +use constant TELNET_CODE_NULL => 0; +use constant TELNET_CODE_LF => 10; +use constant TELNET_CODE_CR => 13; +use constant TELNET_CODE_ESC => 27; +use constant TELNET_CODE_SE => 240; +use constant TELNET_CODE_NOP => 241; +use constant TELNET_CODE_IP => 244; +use constant TELNET_CODE_GA => 249; +use constant TELNET_CODE_SB => 250; +use constant TELNET_CODE_WILL => 251; +use constant TELNET_CODE_WONT => 252; +use constant TELNET_CODE_DO => 253; +use constant TELNET_CODE_DONT => 254; +use constant TELNET_CODE_IAC => 255; + +use constant TELNET_OPT_BIN => 0; +use constant TELNET_OPT_ECHO => 1; +use constant TELNET_OPT_SGA => 3; +use constant TELNET_OPT_TTYP => 24; +use constant TELNET_OPT_LINE => 34; + +use constant TELNET_STATE_LISTEN => -1; +use constant TELNET_STATE_STREAM => 0; +use constant TELNET_STATE_IAC => 1; +use constant TELNET_STATE_CMD => 2; +use constant TELNET_STATE_SUBNEG => 3; +use constant TELNET_STATE_SUBIAC => 4; + +# +# %telnettbl->{snum} --> telnet session table, hash of hashes, key'ed by port +# -> {port} port number (int) +# -> {state} state: (_LISTEN|_STREAM|_IAC|_CMD|_SUBNEG|_SUBIAC) +# -> {fh_port} file handle of port socket (for listen) +# -> {fh_data} file handle of data socket +# -> {ucb} ucb the port is attached to +# + +my %telnettbl; + +my $rri_ref_sdef = 0x00; # by default check for 'hard' errors +my $rri_msk_sdef = 0xf0; # ignore the status bits + attn flag +my %rri_amtbl; +my @rri_cmdlist; +my $rri_rvalcnt = 0; +my $rri_ncmdmax = undef; +my $rri_dbasi = 2; # default input base +my $rri_dbaso = 8; # default output base +my $rri_nodfill = " " x 5; # filler string for "d=-" stanzas + +my %rri_cname2cmd = (rreg => 0, # c_rri_cmd_rreg : slv3 := "000"; + rblk => 1, # c_rri_cmd_rblk : slv3 := "001"; + wreg => 2, # c_rri_cmd_wreg : slv3 := "010"; + wblk => 3, # c_rri_cmd_wblk : slv3 := "011"; + stat => 4, # c_rri_cmd_stat : slv3 := "100"; + attn => 5, # c_rri_cmd_attn : slv3 := "101"; + init => 6); # c_rri_cmd_init : slv3 := "110"; + +my @crc8_tbl = ( 0, 29, 58, 39, 116, 105, 78, 83, # from gen_crc8_tbl + 232, 245, 210, 207, 156, 129, 166, 187, + 205, 208, 247, 234, 185, 164, 131, 158, + 37, 56, 31, 2, 81, 76, 107, 118, + 135, 154, 189, 160, 243, 238, 201, 212, + 111, 114, 85, 72, 27, 6, 33, 60, + 74, 87, 112, 109, 62, 35, 4, 25, + 162, 191, 152, 133, 214, 203, 236, 241, + 19, 14, 41, 52, 103, 122, 93, 64, + 251, 230, 193, 220, 143, 146, 181, 168, + 222, 195, 228, 249, 170, 183, 144, 141, + 54, 43, 12, 17, 66, 95, 120, 101, + 148, 137, 174, 179, 224, 253, 218, 199, + 124, 97, 70, 91, 8, 21, 50, 47, + 89, 68, 99, 126, 45, 48, 23, 10, + 177, 172, 139, 150, 197, 216, 255, 226, + 38, 59, 28, 1, 82, 79, 104, 117, + 206, 211, 244, 233, 186, 167, 128, 157, + 235, 246, 209, 204, 159, 130, 165, 184, + 3, 30, 57, 36, 119, 106, 77, 80, + 161, 188, 155, 134, 213, 200, 239, 242, + 73, 84, 115, 110, 61, 32, 7, 26, + 108, 113, 86, 75, 24, 5, 34, 63, + 132, 153, 190, 163, 240, 237, 202, 215, + 53, 40, 15, 18, 65, 92, 123, 102, + 221, 192, 231, 250, 169, 180, 147, 142, + 248, 229, 194, 223, 140, 145, 182, 171, + 16, 13, 42, 55, 100, 121, 94, 67, + 178, 175, 136, 149, 198, 219, 252, 225, + 90, 71, 96, 125, 46, 51, 20, 9, + 127, 98, 69, 88, 11, 22, 49, 44, + 151, 138, 173, 176, 227, 254, 217, 196); + +my $ocrc = 0; +my $icrc = 0; +my $kpid = -1; + +my @pdp11_opcode_tbl = ( + {code=>0000000, mask=>0000000, name=>"halt", type=>"0arg"}, + {code=>0000001, mask=>0000000, name=>"wait", type=>"0arg"}, + {code=>0000002, mask=>0000000, name=>"rti ", type=>"0arg"}, + {code=>0000003, mask=>0000000, name=>"bpt ", type=>"0arg"}, + {code=>0000004, mask=>0000000, name=>"iot ", type=>"0arg"}, + {code=>0000005, mask=>0000000, name=>"reset",type=>"0arg"}, + {code=>0000006, mask=>0000000, name=>"rtt ", type=>"0arg"}, + {code=>0000007, mask=>0000000, name=>"!!mfpt", type=>"0arg"}, + {code=>0000100, mask=>0000077, name=>"jmp ", type=>"1arg"}, + {code=>0000200, mask=>0000007, name=>"rts ", type=>"1reg"}, + {code=>0000230, mask=>0000007, name=>"spl ", type=>"spl"}, + {code=>0000240, mask=>0000017, name=>"cl", type=>"ccop"}, + {code=>0000260, mask=>0000017, name=>"se", type=>"ccop"}, + {code=>0000300, mask=>0000077, name=>"swap", type=>"1arg"}, + {code=>0000400, mask=>0000377, name=>"br ", type=>"br"}, + {code=>0001000, mask=>0000377, name=>"bne ", type=>"br"}, + {code=>0001400, mask=>0000377, name=>"beq ", type=>"br"}, + {code=>0002000, mask=>0000377, name=>"bge ", type=>"br"}, + {code=>0002400, mask=>0000377, name=>"blt ", type=>"br"}, + {code=>0003000, mask=>0000377, name=>"bgt ", type=>"br"}, + {code=>0003400, mask=>0000377, name=>"ble ", type=>"br"}, + {code=>0004000, mask=>0000777, name=>"jsr ", type=>"jsr"}, + {code=>0005000, mask=>0000077, name=>"clr ", type=>"1arg"}, + {code=>0005100, mask=>0000077, name=>"com ", type=>"1arg"}, + {code=>0005200, mask=>0000077, name=>"inc ", type=>"1arg"}, + {code=>0005300, mask=>0000077, name=>"dec ", type=>"1arg"}, + {code=>0005400, mask=>0000077, name=>"neg ", type=>"1arg"}, + {code=>0005500, mask=>0000077, name=>"adc ", type=>"1arg"}, + {code=>0005600, mask=>0000077, name=>"sbc ", type=>"1arg"}, + {code=>0005700, mask=>0000077, name=>"tst ", type=>"1arg"}, + {code=>0006000, mask=>0000077, name=>"ror ", type=>"1arg"}, + {code=>0006100, mask=>0000077, name=>"rol ", type=>"1arg"}, + {code=>0006200, mask=>0000077, name=>"asr ", type=>"1arg"}, + {code=>0006300, mask=>0000077, name=>"asl ", type=>"1arg"}, + {code=>0006400, mask=>0000077, name=>"mark", type=>"mark"}, + {code=>0006500, mask=>0000077, name=>"mfpi", type=>"1arg"}, + {code=>0006600, mask=>0000077, name=>"mtpi", type=>"1arg"}, + {code=>0006700, mask=>0000077, name=>"sxt ", type=>"1arg"}, + {code=>0007000, mask=>0000077, name=>"!!csm", type=>"1arg"}, + {code=>0007200, mask=>0000077, name=>"!!tstset",type=>"1arg"}, + {code=>0007300, mask=>0000077, name=>"!!wrtlck",type=>"1arg"}, + {code=>0010000, mask=>0007777, name=>"mov ", type=>"2arg"}, + {code=>0020000, mask=>0007777, name=>"cmp ", type=>"2arg"}, + {code=>0030000, mask=>0007777, name=>"bit ", type=>"2arg"}, + {code=>0040000, mask=>0007777, name=>"bic ", type=>"2arg"}, + {code=>0050000, mask=>0007777, name=>"bis ", type=>"2arg"}, + {code=>0060000, mask=>0007777, name=>"add ", type=>"2arg"}, + {code=>0070000, mask=>0000777, name=>"mul ", type=>"rdst"}, + {code=>0071000, mask=>0000777, name=>"div ", type=>"rdst"}, + {code=>0072000, mask=>0000777, name=>"ash ", type=>"rdst"}, + {code=>0073000, mask=>0000777, name=>"ashc", type=>"rdst"}, + {code=>0074000, mask=>0000777, name=>"xor ", type=>"rdst"}, + {code=>0077000, mask=>0000777, name=>"sob ", type=>"sob"}, + {code=>0100000, mask=>0000377, name=>"bpl ", type=>"br"}, + {code=>0100400, mask=>0000377, name=>"bmi ", type=>"br"}, + {code=>0101000, mask=>0000377, name=>"bhi ", type=>"br"}, + {code=>0101400, mask=>0000377, name=>"blos", type=>"br"}, + {code=>0102000, mask=>0000377, name=>"bvc ", type=>"br"}, + {code=>0102400, mask=>0000377, name=>"bvs ", type=>"br"}, + {code=>0103000, mask=>0000377, name=>"bcc ", type=>"br"}, + {code=>0103400, mask=>0000377, name=>"bcs ", type=>"br"}, + {code=>0104000, mask=>0000377, name=>"emt ", type=>"trap"}, + {code=>0104400, mask=>0000377, name=>"trap", type=>"trap"}, + {code=>0105000, mask=>0000077, name=>"clrb", type=>"1arg"}, + {code=>0105100, mask=>0000077, name=>"comb", type=>"1arg"}, + {code=>0105200, mask=>0000077, name=>"incb", type=>"1arg"}, + {code=>0105300, mask=>0000077, name=>"decb", type=>"1arg"}, + {code=>0105400, mask=>0000077, name=>"negb", type=>"1arg"}, + {code=>0105500, mask=>0000077, name=>"adcb", type=>"1arg"}, + {code=>0105600, mask=>0000077, name=>"sbcb", type=>"1arg"}, + {code=>0105700, mask=>0000077, name=>"tstb", type=>"1arg"}, + {code=>0106000, mask=>0000077, name=>"rorb", type=>"1arg"}, + {code=>0106100, mask=>0000077, name=>"rolb", type=>"1arg"}, + {code=>0106200, mask=>0000077, name=>"asrb", type=>"1arg"}, + {code=>0106300, mask=>0000077, name=>"aslb", type=>"1arg"}, + {code=>0106400, mask=>0000077, name=>"!!mtps", type=>"1arg"}, + {code=>0106500, mask=>0000077, name=>"mfpd", type=>"1arg"}, + {code=>0106600, mask=>0000077, name=>"mtpd", type=>"1arg"}, + {code=>0106700, mask=>0000077, name=>"!!mfps", type=>"1arg"}, + {code=>0110000, mask=>0007777, name=>"movb", type=>"2arg"}, + {code=>0120000, mask=>0007777, name=>"cmpb", type=>"2arg"}, + {code=>0130000, mask=>0007777, name=>"bitb", type=>"2arg"}, + {code=>0140000, mask=>0007777, name=>"bicb", type=>"2arg"}, + {code=>0150000, mask=>0007777, name=>"bisb", type=>"2arg"}, + {code=>0160000, mask=>0007777, name=>"sub ", type=>"2arg"}, + {code=>0170000, mask=>0000000, name=>"!!cfcc", type=>"0arg"}, + {code=>0170001, mask=>0000000, name=>"!!setf", type=>"0arg"}, + {code=>0170011, mask=>0000000, name=>"!!setd", type=>"0arg"}, + {code=>0170002, mask=>0000000, name=>"!!seti", type=>"0arg"}, + {code=>0170012, mask=>0000000, name=>"!!setl", type=>"0arg"}, + {code=>0170100, mask=>0000077, name=>"!!ldfps",type=>"1fpp"}, + {code=>0170200, mask=>0000077, name=>"!!stfps",type=>"1fpp"}, + {code=>0170300, mask=>0000077, name=>"!!stst", type=>"1fpp"}, + {code=>0170400, mask=>0000077, name=>"!!clrf", type=>"1fpp"}, + {code=>0170500, mask=>0000077, name=>"!!tstf", type=>"1fpp"}, + {code=>0170600, mask=>0000077, name=>"!!absf", type=>"1fpp"}, + {code=>0170700, mask=>0000077, name=>"!!negf", type=>"1fpp"}, + {code=>0171000, mask=>0000377, name=>"!!mulf", type=>"rfpp"}, + {code=>0171400, mask=>0000377, name=>"!!modf", type=>"rfpp"}, + {code=>0172000, mask=>0000377, name=>"!!addf", type=>"rfpp"}, + {code=>0172400, mask=>0000377, name=>"!!ldf", type=>"rfpp"}, + {code=>0173000, mask=>0000377, name=>"!!subf", type=>"rfpp"}, + {code=>0173400, mask=>0000377, name=>"!!cmpf", type=>"rfpp"}, + {code=>0174000, mask=>0000377, name=>"!!stf", type=>"rfpp"}, + {code=>0174400, mask=>0000377, name=>"!!divf", type=>"rfpp"}, + {code=>0175000, mask=>0000377, name=>"!!stexp",type=>"rfpp"}, + {code=>0175400, mask=>0000377, name=>"!!stcif",type=>"rfpp"}, + {code=>0176000, mask=>0000377, name=>"!!stcfd",type=>"rfpp"}, + {code=>0176400, mask=>0000377, name=>"!!ldexp",type=>"rfpp"}, + {code=>0177000, mask=>0000377, name=>"!!ldcif",type=>"rfpp"}, + {code=>0177400, mask=>0000377, name=>"!!ldcdf",type=>"rfpp"} + ); + +use constant BIT00 => 0000001; +use constant BIT01 => 0000002; +use constant BIT02 => 0000004; +use constant BIT03 => 0000010; +use constant BIT04 => 0000020; +use constant BIT05 => 0000040; +use constant BIT06 => 0000100; +use constant BIT07 => 0000200; +use constant BIT08 => 0000400; +use constant BIT09 => 0001000; +use constant BIT10 => 0002000; +use constant BIT11 => 0004000; +use constant BIT12 => 0010000; +use constant BIT13 => 0020000; +use constant BIT14 => 0040000; +use constant BIT15 => 0100000; + +use constant REGATTR_RBMBOX => 0000001; # rbus is mailbox, skip on exa loop +use constant REGATTR_RBRD => 0000002; # by default read on rbus +use constant REGATTR_RBWR => 0000004; # by default write on rbus +use constant REGATTR_IBMBOX => 0000010; # ibus is mailbox, skip on exa loop + +# some common defs + +my @partbl_nxbuf = ( nxbuf_min => { type => "hval:d" }, + nxbuf_inc => { type => "hval:d" }, + nxbuf_max => { type => "hval:d" }, + nxbuf => { type => "hval:d" } ); + +# CPU general defs + +use constant CPU_MMR3 => 0172516; +use constant CPU_SDREG => 0177570; +use constant CPU_MMR0 => 0177572; +use constant CPU_MMR1 => 0177574; +use constant CPU_MMR2 => 0177576; +use constant CPU_LOSIZE => 0177760; +use constant CPU_HISIZE => 0177762; +use constant CPU_SYSID => 0177764; +use constant CPU_CPUERR => 0177766; +use constant CPU_MBRK => 0177770; +use constant CPU_PIRQ => 0177772; +use constant CPU_STKLIM => 0177774; +use constant CPU_PSW => 0177776; + +# DL11 general defs +use constant DL11_BASE_A => 0177560; +use constant DL11_BASE_B => 0176500; + +# DL11 address offsets +use constant DL11_RCSR => 00; +use constant DL11_RBUF => 02; +use constant DL11_XCSR => 04; +use constant DL11_XBUF => 06; + +# DL11 register defs +use constant DL11_RCSR_M_RDONE => BIT07; +use constant DL11_XCSR_M_XRDY => BIT07; +use constant DL11_XBUF_M_RRDY => BIT09; +use constant DL11_XBUF_M_XVAL => BIT08; +use constant DL11_XBUF_M_XBUF => 0377; + +my @reglist_dl11 = ({name => "rcsr", + offset => DL11_RCSR}, + {name => "rbuf", + offset => DL11_RBUF, + attr => REGATTR_IBMBOX}, + {name => "xcsr", + offset => DL11_XCSR}, + {name => "xbuf", + offset => DL11_XBUF, + attr => REGATTR_RBMBOX}); + +my %partbl_dl11 = ( trace => { type => "hval:b" }, + @partbl_nxbuf ); + +# LP11 general defs +use constant LP11_BASE => 0177514; + +# LP11 address offsets +use constant LP11_CSR => 00; +use constant LP11_BUF => 02; + +# LP11 register defs +use constant LP11_CSR_M_ERR => BIT15; +use constant LP11_BUF_M_VAL => BIT08; +use constant LP11_BUF_M_BUF => 0177; + +my @reglist_lp11 = ({name => "csr", + offset => LP11_CSR}, + {name => "buf", + offset => LP11_BUF, + attr => REGATTR_RBMBOX}); +my %partbl_lp11 = ( trace => { type => "hval:b" }, + @partbl_nxbuf ); + +# PC11 address offsets +use constant PC11_RCSR => 00; +use constant PC11_RBUF => 02; +use constant PC11_PCSR => 04; +use constant PC11_PBUF => 06; + +# PC11 register defs +use constant PC11_RCSR_M_ERR => BIT15; +use constant PC11_PCSR_M_ERR => BIT15; +use constant PC11_PBUF_M_RBUSY => BIT09; +use constant PC11_PBUF_M_PVAL => BIT08; +use constant PC11_PBUF_M_PBUF => 0377; + +my @reglist_pc11 = ({name => "rcsr", + offset => PC11_RCSR}, + {name => "rbuf", + offset => PC11_RBUF, + attr => REGATTR_IBMBOX}, + {name => "pcsr", + offset => PC11_PCSR}, + {name => "pbuf", + offset => PC11_PBUF, + attr => REGATTR_RBMBOX}); +my %partbl_pc11 = ( trace => { type => "hval:b" }, + @partbl_nxbuf ); + +# RK11 general defs +use constant RK11_BASE => 0177400; +use constant RK11_NUMSE => 12; # number of sectors +use constant RK11_NUMHD => 2; # number of heads +use constant RK11_NUMCY => 203; # number of cylinders +use constant RK11_NUMDR => 8; # number of drives +use constant RK11_NUMBL => RK11_NUMSE * RK11_NUMHD * RK11_NUMCY; +use constant RK11_BLKSIZE => 512; # disk block size +use constant RK11_VOLSIZE => RK11_BLKSIZE * RK11_NUMBL; # disk volume size + +# RK11 address offsets +use constant RK11_RKDS => 00; +use constant RK11_RKER => 02; +use constant RK11_RKCS => 04; +use constant RK11_RKWC => 06; +use constant RK11_RKBA => 010; +use constant RK11_RKDA => 012; +use constant RK11_RKMR => 014; + +# RK11 register defs + +use constant RKDS_M_ID => 0160000; # ID: drive number +use constant RKDS_V_ID => 13; +use constant RKDS_B_ID => 0007; +use constant RKDS_M_HDEN => BIT11; # HDEN: high density drive (rk05) +use constant RKDS_M_DRU => BIT10; # DRU: drive unsafe +use constant RKDS_M_SIN => BIT09; # SIN: seek incomplete +use constant RKDS_M_SOK => BIT08; # SOK: sector counter OK +use constant RKDS_M_DRY => BIT07; # DRY: drive ready +use constant RKDS_M_ADRY => BIT06; # ADRY: access ready +use constant RKDS_M_WPS => BIT05; # WPS: write protect +use constant RKDS_B_SC => 0017; # SC: sector counter + +use constant RKER_M_DRE => BIT15; # DRE: drive error +use constant RKER_M_OVR => BIT14; # OVR: overrun +use constant RKER_M_WLO => BIT13; # WLO: write lock violation +use constant RKER_M_PGE => BIT11; # PGE: programming error +use constant RKER_M_NXM => BIT10; # NXM: non existent memory +use constant RKER_M_NXD => BIT07; # NXD: non existent drive +use constant RKER_M_NXC => BIT06; # NXC: non existent cylinder +use constant RKER_M_NXS => BIT05; # NXS: non existent sector +use constant RKER_M_CSE => BIT01; # CSE: check sum error +use constant RKER_M_WCE => BIT00; # WCE: write check error + +use constant RKCS_M_MAINT => BIT12; # MAINT: maintenance mode +use constant RKCS_M_IBA => BIT11; # IBA: inhibit increment RKBA +use constant RKCS_M_FMT => BIT10; # FMT: format +use constant RKCS_M_RWA => BIT09; # RWA: read-write all +use constant RKCS_M_SSE => BIT08; # SSE: stop on soft errors +use constant RKCS_M_MEX => 0000060; # MEX: memory extension +use constant RKCS_V_MEX => 4; +use constant RKCS_B_MEX => 0003; +use constant RKCS_V_FUNC => 1; # FUNC: function +use constant RKCS_B_FUNC => 0007; +use constant RKCS_CRESET => 0; +use constant RKCS_WRITE => 1; +use constant RKCS_READ => 2; +use constant RKCS_WCHK => 3; +use constant RKCS_SEEK => 4; +use constant RKCS_RCHK => 5; +use constant RKCS_DRESET => 6; +use constant RKCS_WLOCK => 7; +use constant RKCS_M_GO => BIT00; # GO: go bit + +use constant RKDA_M_DRSEL => 0160000; # DRSEL: drive number +use constant RKDA_V_DRSEL => 13; +use constant RKDA_B_DRSEL => 0007; +use constant RKDA_M_CYL => 0017740; # CYL: cyclinder address +use constant RKDA_V_CYL => 5; +use constant RKDA_B_CYL => 0377; +use constant RKDA_M_SUR => 0000020; # SUR: surface +use constant RKDA_V_SUR => 4; +use constant RKDA_B_SUR => 0001; +use constant RKDA_B_SC => 0017; # SC: sector address + +use constant RKMR_M_RID => 0160000; # RID: drive id for RKDS RB read +use constant RKMR_V_RID => 13; +use constant RKMR_V_CRDONE => 11; # CRDONE: control reset done +use constant RKMR_V_SBCLR => 10; # SBCLR: clear SBUSY's with SDONE +use constant RKMR_V_CRESET => 9; # CRESET: initiate control reset +use constant RKMR_V_FDONE => 8; # FDONE: initiate function done + +my @reglist_rk11 = ({name => "rkds", + offset => RK11_RKDS}, + {name => "rker", + offset => RK11_RKER}, + {name => "rkcs", + offset => RK11_RKCS}, + {name => "rkwc", + offset => RK11_RKWC}, + {name => "rkba", + offset => RK11_RKBA}, + {name => "rkda", + offset => RK11_RKDA}, + {name => "rkmr", + offset => RK11_RKMR}); + +my %partbl_rk11 = ( trace => { type => "hval:b" } ); + +# KWP general defs + +my @reglist_kwp = ({name => "csr", + offset => 0}, + {name => "csb", + offset => 2}, + {name => "ctr", + offset => 4}); + +# KWL general defs + +my @reglist_kwl = ({name => "csr", + offset => 0}); + +# IIST general defs + +my @reglist_iist = ({name => "acr", + offset => 0}, + {name => "adr", + offset => 2}); + +use constant BOOT_START => 02000; + +my $serv11_fds_update = 1; +my $serv11_config_done = 0; +my $serv11_init_pending = 1; +my $serv11_rdma_chunk = 256; + +my $serv11_init_anena = 0x8000; # enable attn +#my $serv11_init_anena = 0xC03f; # enable attn+ioto(63ms) + +# +# %serv11_ctltbl->{dev} --> controller table; is hash of hashes +# -> {ctlname} controller name +# -> {ctltype} controller type (e.g. DL11) +# -> {devname} device name +# -> {type} device type: term, lpr, ptap, disk, tape, eth +# -> {units} array of unit names +# -> {base} controller base address +# -> {ibrb} controller base mapping for remote ib access +# -> {csroff} csr offset from base (for probing) +# -> {lam} lam number used by controller +# -> {nxbuf_min} nxbuf: minimal vector size +# -> {nxbuf_inc} nxbuf: vector size increment +# -> {nxbuf_max} nxbuf: maximal vector size +# -> {probehdl} address of probe handler +# -> {probemask} sides to be tested (set to "ir" if missing) +# -> {ichrhdl} address of input character handler +# -> {inithdl} address of controler init handler +# -> {usethdl} address of unit setup handler +# -> {attdethdl} address of attach/detach handler +# -> {attnhdl} address og attention handler +# -> {reglist} register list (array of regdsc's) +# -> {regtbl} register table (by name, created by ...) +# -> {partbl} parameter table (array of pardsc's) +# -> {blksize} block size (in bytes) {for disk} +# -> {volsize} volume size (in bytes) {for disk} +# -> {boot_mode} boot mode: "ptape" undef +# -> {boot_base} base address for boot code if not BOOT_START {for ptap} +# -> {boot_mode} boot mode: "ptape" undef +# -> {boot_entry} boot code entry point, relative to BOOT_START +# -> {boot_unit} offset from BOOT_START where unit number is stored +# -> {boot_code} array with boot loader code +# +# -> {memsize} memory size {for cpu} +# +# -> {nxbuf} nxbuf: current value +# -> {probe_ival} defined if cpu side probing ok +# -> {probe_rval} defined if rem side probing ok +# -> {probe_ok} true if required sides available (see probe_mask) +# -> {probe_text} text for "sho conf" generated during probe + +my %serv11_ctltbl = ( + CPU => + { ctlname => "CPU", + ctltype => "W11A", + type => "cpu", + base => CPU_PSW, # use psw to get it to top of list + lam => 0, + probehdl => \&serv11_probe_cpu, + probemask => "i", + attnhdl => \&serv11_attn_cpu, + reglist => [ ], + partbl => { } + }, + + TTA => + { ctlname => "TTA", + ctltype => "DL11", + devname => "TT", + type => "term", + units => ["TT0"], + base => DL11_BASE_A, + ibrb => DL11_BASE_A & ~(077), + csroff => 0, + lam => 1, + nxbuf_min => 2, # to disable nxbuf mechanism use + nxbuf_inc => 2, # min=1, inc=0, max=1 + nxbuf_max => 8, # otherwise: min=2,inc=2,max=8 + trace => 1, + probehdl => \&serv11_probe_gen, + ichrhdl => \&serv11_ichr_dl11, + attdethdl => \&serv11_attdet_term, + attnhdl => \&serv11_attn_dl11, + reglist => [ @reglist_dl11 ], + partbl => { %partbl_dl11 } + }, + + TTB => + { ctlname => "TTB", + ctltype => "DL11", + devname => "TT", + type => "term", + units => ["TT1"], + base => DL11_BASE_B, + ibrb => DL11_BASE_B & ~(077), + csroff => 0, + lam => 2, + nxbuf_min => 2, + nxbuf_inc => 2, + nxbuf_max => 8, + trace => 1, + probehdl => \&serv11_probe_gen, + ichrhdl => \&serv11_ichr_dl11, + attdethdl => \&serv11_attdet_term, + attnhdl => \&serv11_attn_dl11, + reglist => [ @reglist_dl11 ], + partbl => { %partbl_dl11 } + }, + + DZ => + { ctlname => "DZ", + ctltype => "DZ11", + devname => "DZ", + type => "term", + units => ["DZ0","DZ1","DZ2","DZ3","DZ4","DZ5","DZ6","DZ7"], + base => 0160100, + ibrb => 0160100 & ~(077), + csroff => 0, + lam => 3, + probehdl => \&serv11_probe_gen + }, + + LP => + { ctlname => "LP", + ctltype => "LP11", + devname => "LP", + type => "lpr", + units => ["LP0"], + base => 0177514, + ibrb => 0177514 & ~(077), + csroff => 0, + lam => 8, + nxbuf_min => 2, # to disable nxbuf mechanism use + nxbuf_inc => 2, # min=1, inc=0, max=1 + nxbuf_max => 8, # otherwise: min=2,inc=2,max=8 + trace => 1, + probehdl => \&serv11_probe_gen, + inithdl => \&serv11_init_gen, + usethdl => \&serv11_uset_lp11, + attdethdl => \&serv11_attdet_wonly, + attnhdl => \&serv11_attn_lp11, + reglist => [ @reglist_lp11 ], + partbl => { %partbl_lp11 } + }, + + PC => + { ctlname => "PC", + ctltype => "PC11", + devname => "PC", + type => "ptap", + units => ["PTR","PTP"], + base => 0177550, + ibrb => 0177550 & ~(077), + csroff => 0, + lam => 10, + nxbuf_min => 2, + nxbuf_inc => 2, + nxbuf_max => 8, + trace => 1, + probehdl => \&serv11_probe_gen, + usethdl => \&serv11_uset_pc11, + attdethdl => \&serv11_attdet_pc11, + attnhdl => \&serv11_attn_pc11, + reglist => [ @reglist_pc11 ], + partbl => { %partbl_pc11 }, + boot_mode => "ptape", + boot_base => 0017476, + boot_entry=> 0017500, + boot_code => [ # papertape lda loader, from dec-11-l2pc-po + 0000000, # C000: halt + 0010706, # astart: mov pc,sp + 0024646, # cmp -(sp),-(sp) + 0010705, # mov pc,r5 + 0062705, 0000112, # add #000112,r5 + 0005001, # clr r1 + 0013716, 0177570, # B000: mov @#cp.dsr,(sp) + 0006016, # ror (sp) + 0103402, # bcs B001 + 0005016, # clr (sp) + 0000403, # br B002 + 0006316, # B001: asl (sp) + 0001001, # bne B002 + 0010116, # mov r1,(sp) + 0005000, # B002: clr r0 + 0004715, # jsr pc,(r5) + 0105303, # decb r3 + 0001374, # bne B002 + 0004715, # jsr pc,(r5) + 0004767, 0000074, # jsr pc,R000 + 0010402, # mov r4,r2 + 0162702, 0000004, # sub #000004,r2 + 0022702, 0000002, # cmp #000002,r2 + 0001441, # beq B007 + 0004767, 0000054, # jsr pc,R000 + 0061604, # add (sp),r4 + 0010401, # mov r4,r1 + 0004715, # B003: jsr pc,(r5) + 0002004, # bge B005 + 0105700, # tstb r0 + 0001753, # beq B002 + 0000000, # B004: halt + 0000751, # br B002 + 0110321, # B005: movb r3,(r1)+ + 0000770, # br B003 + 0016703, 0000152, # ldchr: mov p.prcs,r3 + 0105213, # incb (r3) + 0105713, # B006: tstb (r3) + 0100376, # bpl B006 + 0116303, 0000002, # movb 000002(r3),r3 + 0060300, # add r3,r0 + 0042703, 0177400, # bic #177400,r3 + 0005302, # dec r2 + 0000207, # rts pc + 0012667, 0000046, # R000: mov (sp)+,D000 + 0004715, # jsr pc,(r5) + 0010304, # mov r3,r4 + 0004715, # jsr pc,(r5) + 0000303, # swap r3 + 0050304, # bis r3,r4 + 0016707, 0000030, # mov D000,pc + 0004767, 0177752, # B007: jsr pc,R000 + 0004715, # jsr pc,(r5) + 0105700, # tstb r0 + 0001342, # bne B004 + 0006204, # asr r4 + 0103002, # bcc B008 + 0000000, # halt + 0000700, # br B000 + 0006304, # B008: asl r4 + 0061604, # add (sp),r4 + 0000114, # jmp (r4) + 0000000, # D000: .word 000000 + 0012767, 0000352, 0000020, # L000: mov #000352,B009+2 + 0012767, 0000765, 0000034, # mov #000765,D001 + 0000167, 0177532, # jmp C000 + 0016701, 0000026, # bstart: mov p.prcs,r1 + 0012702, 0000352, # B009: mov #000352,r2 + 0005211, # inc (r1) + 0105711, # B010: tstb (r1) + 0100376, # bpl B010 + 0116162, 0000002, 0157400, # movb 000002(r1),157400(r2) + 0005267, 0177756, # inc B009+2 + 0000765, # D001: br B009 + 0177550 # p.prcs: .word 177550 + ] + }, + + RK => + { ctlname => "RK", + ctltype => "RK11/RK05", + devname => "RK", + type => "disk", + units => ["RK0","RK1","RK2","RK3","RK4","RK5","RK6","RK7"], + base => RK11_BASE, + ibrb => RK11_BASE & ~(077), + csroff => 4, + lam => 4, + trace => 1, + probehdl => \&serv11_probe_gen, + inithdl => \&serv11_init_gen, + usethdl => \&serv11_uset_rk11, + attdethdl => \&serv11_attdet_disk, + attnhdl => \&serv11_attn_rk11, + reglist => [ @reglist_rk11 ], + partbl => { %partbl_rk11 }, + blksize => RK11_BLKSIZE, + volsize => RK11_VOLSIZE, + boot_entry=> BOOT_START + 002, + boot_unit => BOOT_START + 010, + boot_code => [ # rk05 boot loader - from simh pdp11_rk.c + 0042113, # "KD" + 0012706, BOOT_START, # MOV #boot_start, SP + 0012700, 0000000, # MOV #unit, R0 ; unit number + 0010003, # MOV R0, R3 + 0000303, # SWAB R3 + 0006303, # ASL R3 + 0006303, # ASL R3 + 0006303, # ASL R3 + 0006303, # ASL R3 + 0006303, # ASL R3 + 0012701, 0177412, # MOV #RKDA, R1 ; rkda + 0010311, # MOV R3, (R1) ; load da + 0005041, # CLR -(R1) ; clear ba + 0012741, 0177000, # MOV #-256.*2, -(R1) ; load wc + 0012741, 0000005, # MOV #READ+GO, -(R1) ; read & go + 0005002, # CLR R2 + 0005003, # CLR R3 + 0012704, BOOT_START+020, # MOV #START+20, R4 + 0005005, # CLR R5 + 0105711, # TSTB (R1) + 0100376, # BPL .-2 + 0105011, # CLRB (R1) + 0005007 # CLR PC (5007) + ] + }, + + RL => + { ctlname => "RL", + ctltype => "RL11/RL02", + devname => "RL", + type => "disk", + units => ["RL0","RL1","RL2","RL3"], + base => 0174400, + ibrb => 0174400 & ~(077), + csroff => 0, # ???CHECK-ME??? + lam => 5, + probehdl => \&serv11_probe_gen, + boot_entry=> BOOT_START + 002, + boot_unit => BOOT_START + 010, + boot_code => [ # rl02 boot loader - from simh pdp11_rl.c + 0042114, # "LD" + 0012706, BOOT_START, # MOV #boot_start, SP + 0012700, 0000000, # MOV #unit, R0 + 0010003, # MOV R0, R3 + 0000303, # SWAB R3 + 0012701, 0174400, # MOV #RLCS, R1 ; csr + 0012761, 0000013, 0000004, # MOV #13, 4(R1) ; clr err + 0052703, 0000004, # BIS #4, R3 ; unit+gstat + 0010311, # MOV R3, (R1) ; issue cmd + 0105711, # TSTB (R1) ; wait + 0100376, # BPL .-2 + 0105003, # CLRB R3 + 0052703, 0000010, # BIS #10, R3 ; unit+rdhdr + 0010311, # MOV R3, (R1) ; issue cmd + 0105711, # TSTB (R1) ; wait + 0100376, # BPL .-2 + 0016102, 0000006, # MOV 6(R1), R2 ; get hdr + 0042702, 0000077, # BIC #77, R2 ; clr sector + 0005202, # INC R2 ; magic bit + 0010261, 0000004, # MOV R2, 4(R1) ; seek to 0 + 0105003, # CLRB R3 + 0052703, 0000006, # BIS #6, R3 ; unit+seek + 0010311, # MOV R3, (R1) ; issue cmd + 0105711, # TSTB (R1) ; wait + 0100376, # BPL .-2 + 0005061, 0000002, # CLR 2(R1) ; clr ba + 0005061, 0000004, # CLR 4(R1) ; clr da + 0012761, 0177000, 0000006, # MOV #-512., 6(R1) ; set wc + 0105003, # CLRB R3 + 0052703, 0000014, # BIS #14, R3 ; unit+read + 0010311, # MOV R3, (R1) ; issue cmd + 0105711, # TSTB (R1) ; wait + 0100376, # BPL .-2 + 0042711, 0000377, # BIC #377, (R1) + 0005002, # CLR R2 + 0005003, # CLR R3 + 0012704, BOOT_START+020, # MOV #START+20, R4 + 0005005, # CLR R5 + 0005007 # CLR PC + ] + }, + + + RP => + { ctlname => "RP", + ctltype => "RH70/RP06", + devname => "RP", + type => "disk", + units => ["RP0","RP1","RP2","RP3"], + base => 0176700, + ibrb => 0176700 & ~(077), + csroff => 0, # ???CHECK-ME??? + lam => 6, + probehdl => \&serv11_probe_gen, + boot_entry=> BOOT_START + 002, + boot_unit => BOOT_START + 010, + boot_code => [ # rp/rm boot loader - from simh pdp11_rp.c + 0042102, # "BD" + 0012706, BOOT_START, # mov #boot_start, sp + 0012700, 0000000, # mov #unit, r0 + 0012701, 0176700, # mov #RPCS1, r1 + 0012761, 0000040, 0000010, # mov #CS2_CLR, 10(r1) ; reset + 0010061, 0000010, # mov r0, 10(r1) ; set unit + 0012711, 0000021, # mov #RIP+GO, (r1) ; pack ack + 0012761, 0010000, 0000032, # mov #FMT16B, 32(r1) ; 16b mode + 0012761, 0177000, 0000002, # mov #-512., 2(r1) ; set wc + 0005061, 0000004, # clr 4(r1) ; clr ba + 0005061, 0000006, # clr 6(r1) ; clr da + 0005061, 0000034, # clr 34(r1) ; clr cyl + 0012711, 0000071, # mov #READ+GO, (r1) ; read + 0105711, # tstb (r1) ; wait + 0100376, # bpl .-2 + 0005002, # clr R2 + 0005003, # clr R3 + 0012704, BOOT_START+020, # mov #start+020, r4 + 0005005, # clr R5 + 0105011, # clrb (r1) + 0005007 # clr PC + ] + }, + + TM => + { ctlname => "TM", + ctltype => "TM11", + devname => "TM", + type => "tape", + units => ["TM0","TM1","TM2","TM3","TM4","TM5","TM6","TM7"], + base => 0172520, + ibrb => 0172520 & ~(077), + csroff => 2, + lam => 7, + probehdl => \&serv11_probe_gen, + boot_entry=> BOOT_START + 002, + boot_unit => BOOT_START + 010, + boot_code => [ # tm11 boot2 (skip 1st record) - from simh pdp11_tm.c + 0046524, # boot_start: "TM" + 0012706, BOOT_START, # mov #boot_start, sp + 0012700, 0000000, # mov #unit_num, r0 + 0012701, 0172526, # mov #172526, r1 ; mtcma + 0005011, # clr (r1) + 0012741, 0177777, # mov #-1, -(r1) ; mtbrc + 0010002, # mov r0,r2 + 0000302, # swab r2 + 0062702, 0060011, # add #60011, r2 + 0010241, # mov r2, -(r1) ; space + go + 0105711, # tstb (r1) ; mtc + 0100376, # bpl .-2 + 0010002, # mov r0,r2 + 0000302, # swab r2 + 0062702, 0060003, # add #60003, r2 + 0010211, # mov r2, (r1) ; read + go + 0105711, # tstb (r1) ; mtc + 0100376, # bpl .-2 + 0005002, # clr r2 + 0005003, # clr r3 + 0012704, BOOT_START+020, # mov #boot_start+20, r4 + 0005005, # clr r5 + 0005007 # clr r7 + ] + }, + + XU => + { ctlname => "XU", + ctltype => "DENUA", + devname => "XU", + type => "eth", + units => ["XU0"], + base => 0174510, + ibrb => 0174510 & ~(077), + csroff => 0, + lam => 9, + probehdl => \&serv11_probe_gen + }, + + KWP => + { ctlname => "KWP", + ctltype => "KW11-P", + devname => "--", + type => "misc", + base => 0172540, + probehdl => \&serv11_probe_gen, + probemask => "i", + reglist => [ @reglist_kwp ] + }, + + KWL => + { ctlname => "KWL", + ctltype => "KW11-L", + devname => "--", + type => "misc", + base => 0177546, + probehdl => \&serv11_probe_gen, + probemask => "i", + reglist => [ @reglist_kwl ] + }, + + IIS => + { ctlname => "IIS", + ctltype => "IIST", + devname => "--", + type => "misc", + base => 0177500, + probehdl => \&serv11_probe_gen, + probemask => "i", + reglist => [ @reglist_iist ] + } + + ); + +# +# %serv11_unittbl->{unit} --> unit table; is hash of hashes +# -> {unitname} unit name +# -> {ctlname} controller name +# -> {ctlunit} unit number of controller {ctlname} +# -> {devunit} device number for device $ucb->{ctlname}->{devname} +# -> {rcvque} receive queue {for term} +# -> {sndque} send queue {for term} +# -> {rcv7bit} use only 7 bits in receive {for term} +# -> {logfile} name of logfile +# -> {logfh} file handle for logfile +# + +my %serv11_unittbl = ( + TT0 => { unitname => "TT0", + ctlname => "TTA", + ctlunit => 0, + devunit => 0, + rcvque => [], + sndque => [], + rcv7bit => 1, + logfile => "pi_tt0.log", + logfh => undef + }, + TT1 => { unitname => "TT1", + ctlname => "TTB", + ctlunit => 0, + devunit => 1, + rcvque => [], + sndque => [], + rcv7bit => 1, + logfile => "pi_tt1.log", + logfh => undef + }, + + DZ0 => { unitname => "DZ0", + ctlname => "DZ", + ctlunit => 0, + devunit => 0, + rcvque => [], + sndque => [] + }, + DZ1 => { unitname => "DZ1", + ctlname => "DZ", + ctlunit => 1, + devunit => 1, + rcvque => [], + sndque => [] + }, + DZ2 => { unitname => "DZ2", + ctlname => "DZ", + ctlunit => 2, + devunit => 2, + rcvque => [], + sndque => [] + }, + DZ3 => { unitname => "DZ3", + ctlname => "DZ", + ctlunit => 3, + devunit => 3, + rcvque => [], + sndque => [] + }, + DZ4 => { unitname => "DZ4", + ctlname => "DZ", + ctlunit => 4, + devunit => 4, + rcvque => [], + sndque => [] + }, + DZ5 => { unitname => "DZ5", + ctlname => "DZ", + ctlunit => 5, + devunit => 5, + rcvque => [], + sndque => [] + }, + DZ6 => { unitname => "DZ6", + ctlname => "DZ", + ctlunit => 6, + devunit => 6, + rcvque => [], + sndque => [] + }, + DZ7 => { unitname => "DZ7", + ctlname => "DZ", + ctlunit => 7, + devunit => 7, + rcvque => [], + sndque => [] + }, + + LP0 => { unitname => "LP0", + ctlname => "LP", + ctlunit => 0, + devunit => 0, + logfile => "pi_lp0.log", + logfh => undef + }, + + PTR => { unitname => "PTR", + ctlname => "PC", + ctlunit => 0, + devunit => 0 + }, + + PTP => { unitname => "PTP", + ctlname => "PC", + ctlunit => 1, + devunit => 1 + }, + + RK0 => { unitname => "RK0", + ctlname => "RK", + ctlunit => 0, + devunit => 0 + }, + RK1 => { unitname => "RK1", + ctlname => "RK", + ctlunit => 1, + devunit => 1 + }, + RK2 => { unitname => "RK2", + ctlname => "RK", + ctlunit => 2, + devunit => 2 + }, + RK3 => { unitname => "RK3", + ctlname => "RK", + ctlunit => 3, + devunit => 3 + }, + RK4 => { unitname => "RK4", + ctlname => "RK", + ctlunit => 4, + devunit => 4 + }, + RK5 => { unitname => "RK5", + ctlname => "RK", + ctlunit => 5, + devunit => 5 + }, + RK6 => { unitname => "RK6", + ctlname => "RK", + ctlunit => 6, + devunit => 6 + }, + RK7 => { unitname => "RK7", + ctlname => "RK", + ctlunit => 7, + devunit => 7 + }, + + RL0 => { unitname => "RL0", + ctlname => "RL", + ctlunit => 0, + devunit => 0 + }, + RL1 => { unitname => "RL1", + ctlname => "RL", + ctlunit => 1, + devunit => 1 + }, + RL2 => { unitname => "RL2", + ctlname => "RL", + ctlunit => 2, + devunit => 2 + }, + RL3 => { unitname => "RL3", + ctlname => "RL", + ctlunit => 3, + devunit => 3 + }, + + RP0 => { unitname => "RP0", + ctlname => "RP", + ctlunit => 0, + devunit => 0 + }, + RP1 => { unitname => "RP1", + ctlname => "RP", + ctlunit => 1, + devunit => 1 + }, + RP2 => { unitname => "RP2", + ctlname => "RP", + ctlunit => 2, + devunit => 2 + }, + RP3 => { unitname => "RP3", + ctlname => "RP", + ctlunit => 3, + devunit => 3 + }, + + TM0 => { unitname => "TM0", + ctlname => "TM", + ctlunit => 0, + devunit => 0 + }, + TM1 => { unitname => "TM1", + ctlname => "TM", + ctlunit => 1, + devunit => 1 + }, + TM2 => { unitname => "TM2", + ctlname => "TM", + ctlunit => 2, + devunit => 2 + }, + TM3 => { unitname => "TM3", + ctlname => "TM", + ctlunit => 3, + devunit => 3 + }, + TM4 => { unitname => "TM4", + ctlname => "TM", + ctlunit => 4, + devunit => 4 + }, + TM5 => { unitname => "TM5", + ctlname => "TM", + ctlunit => 5, + devunit => 5 + }, + TM6 => { unitname => "TM6", + ctlname => "TM", + ctlunit => 6, + devunit => 6 + }, + TM7 => { unitname => "TM7", + ctlname => "TM", + ctlunit => 7, + devunit => 7 + }, + + XU0 => { unitname => "XU0", + ctlname => "XU", + ctlunit => 0, + devunit => 0 + } + + ); + +my @serv11_attntbl; + +my $serv11_active = 0; +my $serv11_attn_mask = 0; +my $serv11_attn_seen = 0; + +my @serv11_icbque = (); + +my $only_argv = 0; +$only_argv = 1 if scalar(@ARGV) > 0; +$only_argv = 0 if exists $opts{int}; + +# +# -- Main program starts here ------------------------------------------------ +# + +autoflush STDOUT 1 if (-p STDOUT); # autoflush if output into pipe +autoflush STDOUT 1 if (-t STDOUT); # autoflush if output into term + +if (exists $opts{help}) { + print_help(); + exit 0; +} + +$SIG{INT} = 'hdl_sigint'; # install ^C (SIGINT) handler + +if (exists $opts{log} && $opts{log} ne "") { + my $fh = new FileHandle; + my $filename = $opts{log}; + $fh->open(">$filename") or die "couldn't open log file"; + $fh_log = $fh; + autoflush $fh_log if (-t $fh); + printf $fh_log "==== opened log file on %s\n", get_timestamp(); +} + +$raw_timeout = $opts{timeout} if exists $opts{timeout}; +$cmax = $opts{cmax} if exists $opts{cmax}; + +if (exists $opts{run}) { + if (not defined ($kpid=fork())) { + die "cannot fork: $!"; + } elsif ($kpid == 0) { # in child + exec "/bin/sh", "-c", $opts{run}; + die "failed to exec /bin/sh -c $opts{run}: $!"; + } else { # in parent + } +} + +fifo_open($opts{fifo}) if (exists $opts{fifo}); +$time0 = get_time(); # do T0 after fifo open +term_open($opts{term}) if (exists $opts{term}); + +while(1) { + my $cmd = get_command(); + if (defined $cmd) { + do_command($cmd); + } else { + do_command(".mode nomode"); + last; + } +} + +if ($curchan) { + &{$chan_tab{$curchan}{write}}(); # flush write queue before close + &{$chan_tab{$curchan}{close}}(); +} + +if (exists $opts{run}) { + waitpid($kpid, 0); + print "pi_rri($curmode)-I: exit status: $?\n" if $?; +} +0; + +#------------------------------------------------------------------------------- + +sub init_regtbl { # initialize regtbl from reglist + foreach my $ctlname (sort keys %serv11_ctltbl) { + my $ctl = $serv11_ctltbl{$ctlname}; + next unless defined $ctl->{reglist}; + + $ctl->{regtbl} = {}; + my $nregs = scalar (@{$ctl->{reglist}}); + + for (my $i = 0; $i<$nregs; $i++) { + my $name = $ctl->{reglist}->[$i]->{name}; + $ctl->{regtbl}->{$name} = $i; + $ctl->{reglist}->[$i]->{rank} = $i; + ##print "+++ 1a $ctl->{ctlname} $name $i\n"; + } + } +} + +#------------------------------------------------------------------------------- + +sub get_command { + my $cmd; + while (1) { + + $cmd = read_command; + return $cmd if (not defined $cmd); # quit if EOF + + print "$cmd\n" if exists $opts{trace}; + + if ($cmd =~ m/^C/) { # ignore, but print "C ..." lines + &{$mode_tab{$curmode}{flush}}("comm"); + print "$cmd\n" unless exists $opts{trace}; + next; + } + + $cmd =~ s{^\s*}{}; # remove leading blanks + + next if $cmd =~ m/^#/; # ignore "# ...." lines + next if $cmd =~ m/^;/; # ignore "; ...." lines + + $cmd =~ s{--.*}{}; # remove comments after -- + $cmd =~ s{\s*$}{}; # remove trailing blanks + next if $cmd eq ""; # ignore empty lines + + return $cmd; + } +} + +#------------------------------------------------------------------------------- + +sub do_command { + my ($cmd) = @_; + + if ($cmd =~ /^\.mode\s*(\w*)/) { # .mode command + if (exists $mode_tab{$1}) { + &{$mode_tab{$curmode}{flush}}("mode"); + &{$mode_tab{$curmode}{close}}(); + print "pi_rri($curmode)-I: closed mode\n" unless $curmode eq "nomode"; + $curmode = $1; + $curcmd = $mode_tab{$curmode}{cmd}; + print "pi_rri($curmode)-I: open mode\n" unless $curmode eq "nomode"; + &{$mode_tab{$curmode}{open}}(); + + } else { + printf "pi_rri($curmode)-E: mode '%s' doesn't exist\n", $1; + printf "pi_rri($curmode)-E: use %s\n", join ",", (sort keys %mode_tab); + } + + } else { # any other command + $sigint_count = 0; # clear pending ^C's + &$curcmd($cmd); + &{$mode_tab{$curmode}{flush}}("line") if $cmd_inter; + } +} + +#------------------------------------------------------------------------------- + +sub read_command { + my $cmd; + + $cmd_inter = 0; + + while (1) { + +# read command line + + if (scalar(@cmdfh)==0 && scalar(@ARGV)>0) { + $cmd = shift @ARGV; + } else { + if (scalar(@cmdfh)) { + my $fh = $cmdfh[$#cmdfh]; + $cmd = <$fh>; + chomp $cmd if defined $cmd; + if (defined $cmd && $cmd =~ /\\$/) { # continuation line ? + $cmd = $`; + my $cline = <$fh>; + chomp $cline; + $cmd .= $cline if defined $cline; + } + unless (defined $cmd) { + $fh->close(); + pop @cmdfh; + print "pi_rri($curmode)-I: close " . pop(@cmdfn) . "\n"; + &{$mode_tab{$curmode}{flush}}("file"); + pop @cmdargs; + setpar_command($cmdargs[-1]) if scalar(@cmdargs); + next; + } + } else { + return undef if $only_argv; + if (defined $term) { + $cmd = $term->readline('>'); + } else { + $cmd = ; + } + if (-t STDIN && -t STDOUT) { + $cmd_inter = 1; # signal that cmd interactive + } + chomp $cmd if defined $cmd; + return undef if not defined $cmd; + if (defined $cmd && $cmd =~ /\\$/) { # continuation line ? + $cmd = $`; + my $cline = ; + chomp $cline; + $cmd .= $cline if defined $cline; + } + } + } + +# preprocess command line +# handle substitutions + + while ($cmd =~ /\$\{(\w*):([-=])(.*?)\}/) { # ${name:[-=]val} seen + my $name = $1; + my $typ = $2; + my $val = $3; + if (exists $par{$name}) { + $cmd = $` . $par{$name} . $'; + } else { + $cmd = $` . $val . $'; + $par{$name} = $val if ($typ eq "="); + } + } + + while ($cmd =~ /\$\{(\w*)\}/) { # ${name} seen + my $name = $1; + if (exists $par{$name}) { + $cmd = $` . $par{$name} . $'; + } else { + print "pi_rri($curmode)-E: variable \"$name\" not defined\n"; + $cmd = $` . "\$?$name?" . $'; + } + } + + while ($cmd =~ /\$\[(.*)\]/) { # $[name] seen + my $evalstr = $1; + my $evalval = eval $evalstr; + if ($@) { + print "pi_rri($curmode)-E: eval error for \"$evalstr\"\n"; + print "pi_rri($curmode)-E: $@\n"; + $cmd = $` . "\$?$evalstr?" . $'; + } else { + $evalval = "" unless defined $evalval; + $cmd = $` . $evalval . $'; + } + } + +# handle asignments + + if ($cmd =~ /^(\w*)=/) { + my $name = $1; + my $val = $'; + $val =~ s/--.*$//; + $val =~ s/\s*$//; + $par{$name} = $val; + next; + } + +# handle @@xxx lines (pmac perl macros) + + if ($cmd =~ /^\s*\@\@(\S*)\s*(.*)$/) { # is it a "@@xxx" macro call ? + my $file = $1; + my $args = $2; + my $fileexp = filename_expand($file); + + print_fatal "pmac file $fileexp not found" unless -r $fileexp; + open (PMACFILE, "<$fileexp") or die "failed to open $fileexp: $!"; + my @code = ; + close PMACFILE; + my $code = join "", @code; + ##printf "+++1 code to execute from $fileexp:\n$code---\n"; + + $cmd_line = $cmd; + $cmd_rest = $args; + $cmd_bad = 0; + + $sigint_count = 0; # clear pending ^C's + { eval $code; } + if ($@) { + print STDERR "pi_rri-E: compile error in $fileexp:\n"; + print STDERR $@; + } + next; + } + +# handle @xxx lines (pcmd command lists) + + if ($cmd =~ /^\s*\@(.*)$/) { # is it a "@xxx" command ? + my $file = $1; + my $args = ""; + if ($file =~ /\((.*)\)$/) { # is it a "@xxx(args)" command ? + $file = $`; + $args = $1; + } + + my $fileexp = filename_expand($file); + + print_fatal "pcmd file $fileexp not found" unless -r $fileexp; + my $fh = new FileHandle; + $fh->open("<$fileexp") or die "failed to open $fileexp: $!"; + print "pi_rri($curmode)-I: open $fileexp\n"; + push @cmdfh, $fh; + push @cmdfn, $fileexp; + push @cmdargs, $args; + setpar_command($args); + } else { + return $cmd; + } + } +} + +#------------------------------------------------------------------------------- + +sub setpar_command { + my ($args) = @_; + my @arglist = split /,/,$args; + for (my $i=scalar(@arglist); $i<8; $i++) { + $arglist[$i] = ""; + } + for (my $i=0; $i0 && + scalar(@cpraw_tx_read)>0) { + my $dat_e = shift @cpraw_tx_expt; + my $dat_r = shift @cpraw_tx_read; + + print conv_etime(), "cptx ", conv_dat9($dat_r), " CHECK "; + if ($dat_e == $dat_r) { + print "OK"; + } else { + print "FAIL exp=", conv_dat9($dat_e); + } + print "\n"; + } + +} + +#------------------------------------------------------------------------------- + +sub rri_open { + $rri_ref_sdef = 0x00; # by default check for 'hard' errors + $rri_msk_sdef = 0xf0; # ignore the status bits + attn flag +} + +#------------------------------------------------------------------------------- + +sub rri_flush { + my ($case) = @_; + rri_cmdlist_do(); +} + +#------------------------------------------------------------------------------- + +sub rri_close { +} + +#------------------------------------------------------------------------------- +# .cpmon 0|1 +# .rbmon 0|1 +# .scntl n 0|1 +# .sinit g8 g16 +# .sdef [s=g8] +# .amclr +# .amdef name g8 +# .reset +# .wait n +# .wtlam n +# .cclst +# rreg [d=g16] [s=g8] +# rblk n [s=g8] +# followed by n d=g16 data check values +# wreg g16 [s=g8] +# wblk n [s=g8] +# followed by n g16 data values +# stat [d=g16] [s=d8] +# attn [d=g16] [s=d8] +# init g16 [s=g8] + +sub rri_cexec { + my ($cmd) = @_; + + $cmd_line = $cmd; + $cmd_rest = ""; + $cmd_bad = 0; + + if ($cmd =~ /^(\.cpmon|\.rbmon)\s+([01])/) { # .cpmon, .rbmon ------------- + my $ind = ($1 eq ".cpmon") ? 15 : 14; + $cmd_rest = $'; + rri_sideband(0x00, ($ind<<8) + $2); + + } elsif ($cmd =~ /^\.scntl\s+(\d+)\s([01])/) { # .scntl ------------------ + $cmd_rest = $'; + rri_sideband(0x00, ($1<<8) + $2); + + } elsif ($cmd =~ /^\.sinit/) { # .sinit ------------------ + $cmd_rest = $'; + my $addr = cget_gdat(8,$rri_dbasi); + my $data = cget_gdat(16,$rri_dbasi); + rri_sideband($addr, $data) if (not $cmd_bad); + + } elsif ($cmd =~ /^\.sdef/) { # .sdef ------------------------- + $cmd_rest = $'; + ($rri_ref_sdef,$rri_msk_sdef) = cget_tagval2_gdat("s",8,2); + + } elsif ($cmd =~ /^\.amclr/) { # .amclr ------------------------ + $cmd_rest = $'; + %rri_amtbl = (); + + } elsif ($cmd =~ /^\.amdef\s+([a-zA-Z][a-zA-Z0-9]*)/) {# .amdef ------------ + $cmd_rest = $'; + my $name = $1; + my $addr = cget_gdat(8,2); + if (defined $addr) { + $rri_amtbl{$name} = $addr; + } else { + $cmd_bad = 1; + } + + } elsif ($cmd =~ /^\.dbasi\s+(\d+)/) { # .dbasi ----------------------- + $cmd_rest = $'; + my $dbase = int $1; + $rri_dbasi = $dbase; + } elsif ($cmd =~ /^\.dbaso\s+(\d+)/) { # .dbaso ----------------------- + $cmd_rest = $'; + my $dbase = int $1; + $rri_dbaso = $dbase; + if ($rri_dbaso == 2) { + $rri_nodfill = " " x 15; + } elsif ($rri_dbaso == 8) { + $rri_nodfill = " " x 5; + } elsif ($rri_dbaso == 16) { + $rri_nodfill = " " x 3; + } else { + $rri_nodfill = "???"; + } + + } elsif ($cmd =~ /^\.reset/) { # .reset ------------------------ + $cmd_rest = $'; + print "pi_rri($curmode)-I: $cmd currently ignored\n"; + + } elsif ($cmd =~ /^\.wait\s+(\d+)/) { # .wait ------------------------ + $cmd_rest = $'; + my $delay = int $1; + rri_cmdlist_do(); # flush before waiting + for (my $i = 0; $i < $delay; $i++) { + raw_snd9(D9IDLE); + } + + } elsif ($cmd =~ /^\.wtlam\s+(\d+)/) { # .wtlam ------------------------ + $cmd_rest = $'; + rri_cmdlist_do(); # flush before wait for ATTN + my $tstart = get_time(); + raw_get9_check(D9ATTN, "wtlam"); # ???FIXME this is a hack... + printf "-- .wtlam # wait for %7.3f sec\n", get_time()-$tstart; + + } elsif ($cmd =~ /^\.cclst/) { # .cclst ------------------------ + $cmd_rest = $'; + $rri_ncmdmax = scalar(@rri_cmdlist) + 1; # force exec after next cmd + + } elsif ($cmd =~ /^rreg/) { # rreg -------------------------- + $cmd_rest = $'; + my $addr = rri_cget_addr; + my ($ref_data, $msk_data) = cget_tagval2_gdat("d",16,$rri_dbasi); + my ($ref_stat, $msk_stat) = rri_cget_stat; + if (not $cmd_bad) { + push @rri_cmdlist, {cname => "rreg", + addr => $addr, + ref_data => $ref_data, + msk_data => $msk_data, + ref_stat => $ref_stat, + msk_stat => $msk_stat}; + } + + } elsif ($cmd =~ /^rblk/) { # rblk -------------------------- + $cmd_rest = $'; + my $addr = rri_cget_addr; + my $nblk = rri_cget_nblk; + my ($ref_stat, $msk_stat) = rri_cget_stat; + my @ref_rblk; + my @msk_rblk; + my $i; + cget_chkblank(); + for ($i = 0; $i < $nblk; $i++) { + $cmd_rest = get_command() if ($cmd_rest eq ""); + $cmd_rest =~ s/^\s*//; + my ($ref,$msk) = cget_tagval2_gdat("d",16,$rri_dbasi); + push @ref_rblk, $ref; + push @msk_rblk, $msk; + } + cget_chkblank(); + if (not $cmd_bad) { + push @rri_cmdlist, {cname => "rblk", + addr => $addr, + nblk => $nblk, + ref_rblk => [@ref_rblk], + msk_rblk => [@msk_rblk], + ref_stat => $ref_stat, + msk_stat => $msk_stat}; + } + + } elsif ($cmd =~ /^wreg/) { # wreg -------------------------- + $cmd_rest = $'; + my $addr = rri_cget_addr; + my $data = cget_gdat(16,$rri_dbasi); + my ($ref_stat, $msk_stat) = rri_cget_stat; + if (not $cmd_bad) { + push @rri_cmdlist, {cname => "wreg", + addr => $addr, + data => $data, + ref_stat => $ref_stat, + msk_stat => $msk_stat}; + } + + } elsif ($cmd =~ /^wblk/) { # wblk -------------------------- + $cmd_rest = $'; + my $addr = rri_cget_addr; + my $nblk = rri_cget_nblk; + my ($ref_stat, $msk_stat) = rri_cget_stat; + my @dat_wblk; + my $i; + cget_chkblank(); + for ($i = 0; $i < $nblk; $i++) { + $cmd_rest = get_command() if ($cmd_rest eq ""); + $cmd_rest =~ s/^\s*//; + push @dat_wblk, cget_gdat(16,$rri_dbasi); + } + cget_chkblank(); + if (not $cmd_bad) { + push @rri_cmdlist, {cname => "wblk", + addr => $addr, + nblk => $nblk, + dat_wblk => [@dat_wblk], + ref_stat => $ref_stat, + msk_stat => $msk_stat}; + } + + } elsif ($cmd =~ /^stat/) { # stat -------------------------- + $cmd_rest = $'; + my ($ref_data, $msk_data) = cget_tagval_gdat("d",16,2); + my ($ref_stat, $msk_stat) = rri_cget_stat; + if (not $cmd_bad) { + push @rri_cmdlist, {cname => "stat", + ref_data => $ref_data, + msk_data => $msk_data, + ref_stat => $ref_stat, + msk_stat => $msk_stat}; + } + + } elsif ($cmd =~ /^attn/) { # attn -------------------------- + $cmd_rest = $'; + my ($ref_data, $msk_data) = cget_tagval_gdat("d",16,$rri_dbasi); + my ($ref_stat, $msk_stat) = rri_cget_stat; + if (not $cmd_bad) { + push @rri_cmdlist, {cname => "attn", + ref_data => $ref_data, + msk_data => $msk_data, + ref_stat => $ref_stat, + msk_stat => $msk_stat}; + } + + } elsif ($cmd =~ /^init/) { # init -------------------------- + $cmd_rest = $'; + my $addr = rri_cget_addr; + my $data = cget_gdat(16,$rri_dbasi); + my ($ref_stat, $msk_stat) = rri_cget_stat; + if (not $cmd_bad) { + push @rri_cmdlist, {cname => "init", + addr => $addr, + data => $data, + ref_stat => $ref_stat, + msk_stat => $msk_stat}; + } + + } else { + print "pi_rri($curmode)-E: unknown command: \"$cmd_line\"\n"; + } + + cget_chkblank() unless $cmd_bad; + if ($cmd_bad) { + print "pi_rri($curmode)-E: parse error, command ignored: \"$cmd_line\"\n"; + } else { + if (scalar(@rri_cmdlist) >= $cmax || + ($rri_ncmdmax && scalar(@rri_cmdlist) >= $rri_ncmdmax)) { + $rri_ncmdmax = undef; + rri_cmdlist_do(); + } + } +} + +#------------------------------------------------------------------------------- + +sub rri_cget_stat { + my ($dat, $msk) = cget_tagval2_gdat("s",8,2); + if (defined $dat) { + return ($dat, $msk); + } else { + return ($rri_ref_sdef, $rri_msk_sdef); + } +} + +#------------------------------------------------------------------------------- + +sub rri_cget_addr { + my $odat; + $cmd_rest =~ s/^\s*//; + if ($cmd_rest =~ /^\.([a-zA-Z][a-zA-Z0-9]*)/) { + $cmd_rest = $'; + if (exists $rri_amtbl{$1}) { + $odat = $rri_amtbl{$1}; + if ($cmd_rest =~ /^\|/) { + $cmd_rest = $'; + $odat |= cget_gdat(8,2); + } + } else { + print "pi_rri($curmode)-E: undefined address mnemo: \"$1\"\n"; + $cmd_bad = 1; + } + } else { + $odat = cget_gdat(8,2); + } + return $odat; +} + +#------------------------------------------------------------------------------- + +sub rri_cget_nblk { + my $odat; + $cmd_rest =~ s/^\s*//; + if ($cmd_rest =~ /^(\d*)/) { + $cmd_rest = $'; + $odat = int $1; + if ($odat <= 0 || $odat > 256) { + print "pi_rri($curmode)-E: block length <0 or >256\n"; + $cmd_bad = 1; + } + } else { + $cmd_bad = 1; + } + return $odat; +} + +#------------------------------------------------------------------------------- + +sub rri_cmdlist_dump { + my ($href,$dblk,$fh) = @_; + my $fh_old; + + $fh_old = select($fh) if defined $fh; + + foreach my $ele (@$href) { + + printf "-- %-4s",$ele->{cname}; + + printf " %-7s","[$ele->{aname}]" if exists $ele->{aname}; + + printf " c=%1.1x%1d%1d", $ele->{cmd}>>4, ($ele->{cmd}>>3)&0x1, + $ele->{cmd}&0x7 if exists $ele->{cmd}; + + printf " a=%s",conv_dat8($ele->{addr}) if exists $ele->{addr}; + + printf " n=%d", $ele->{nblk} if exists $ele->{nblk}; + + printf " d=%s", gconv_dat16($ele->{data},$rri_dbaso) if exists $ele->{data}; + + if (exists $ele->{ref_data}) { + if ((defined $ele->{msk_data} && $ele->{msk_data} == 0xffff) + || not defined $ele->{ref_data}) { + printf " d=-%s", $rri_nodfill; + } else { + printf " d=%s", gconv_dat16($ele->{ref_data},$rri_dbaso); + printf ",%s", gconv_dat16($ele->{msk_data},$rri_dbaso) if $ele->{msk_data}; + } + } + + if (defined $ele->{rcv_data}) { + printf " D=%s%s", gconv_dat16($ele->{rcv_data},$rri_dbaso), + ($ele->{err_data} ? "(#)" : " "); + } + + if (exists $ele->{ref_stat}) { + if ((defined $ele->{msk_stat} && $ele->{msk_stat} == 0xffff) + || not defined $ele->{ref_stat}) { + printf " s=-"; + } else { + printf " s=%s", conv_dat8($ele->{ref_stat}); + printf ",%s", conv_dat8($ele->{msk_stat}) if $ele->{msk_stat}; + } + } + + if (defined $ele->{rcv_stat}) { + printf " S=%s%s", conv_dat8($ele->{rcv_stat}), + ($ele->{err_stat} ? "(#)" : " "); + } + + if (exists $ele->{ok}) { + print ($ele->{ok} ? " OK" : "FAIL"); + } else { + print " PEND"; + } + + if (exists $ele->{dat_wblk} && $dblk) { + my $i = 0; + foreach ( @{$ele->{dat_wblk}} ) { + printf "\n-- " if ($i % 8 == 0); + printf " %s", gconv_dat16($_,$rri_dbaso); + $i += 1; + } + } + + if (exists $ele->{ref_rblk} && $dblk && scalar(@{$ele->{ref_rblk}}) ) { + my $i; + my $nblk = $ele->{nblk}; + for ($i = 0; $i < $nblk; $i++) { + printf "\n-- " if ($i % 4 == 0); + if ((defined $ele->{msk_rblk}[$i] && $ele->{msk_rblk}[$i] == 0xffff) + || not defined $ele->{ref_rblk}[$i]){ + printf " d=-%s %s", $rri_nodfill, $rri_nodfill; + } else { + printf " d=%s", gconv_dat16($ele->{ref_rblk}[$i],$rri_dbaso); + if ($ele->{msk_rblk}[$i]) { + printf ",%s", gconv_dat16($ele->{msk_rblk}[$i],$rri_dbaso); + } else { + print " "; + } + } + } + } + + if (exists $ele->{rcv_rblk} && $dblk) { + my $i; + my $nblk = $ele->{nblk}; + for ($i = 0; $i < $nblk; $i++) { + printf "\n-- " if ($i % 4 == 0); + printf " D=%s%s ", gconv_dat16($ele->{rcv_rblk}[$i],$rri_dbaso), + ($ele->{err_rblk}[$i] ? "(#)" : " "); + } + } + + printf "\n"; + } + + select($fh_old) if defined $fh_old; + +} + +#------------------------------------------------------------------------------- + +sub rri_sideband { + my ($addr,$data) = @_; + my $dl = $data & 0xff; + my $dh = ($data>>8) & 0xff; + rri_cmdlist_do(); + raw_snd8(CESC); + raw_snd8(CESC); + raw_snd8($addr); # ADDR + raw_snd8($dl); # DL + raw_snd8($dh); # DH + &{$chan_tab{$curchan}{write}}(); # flush write queue +} + +#------------------------------------------------------------------------------- + +sub rri_cmdlist_do { + if (scalar(@rri_cmdlist)) { + rri_cmdlist_exec(\@rri_cmdlist); + rri_cmdlist_dump(\@rri_cmdlist, 1); + @rri_cmdlist = (); + } +} + +#------------------------------------------------------------------------------- + +sub rri_cmdlist_exec { + my ($href) = @_; + my $seq = 0; + my $nele = scalar(@$href); + + return unless $nele; + + $ocrc = 0; + $icrc = 0; + + raw_snd9(D9SOP); + + foreach my $ele (@$href) { + my $cname = $ele->{cname}; + my $cmd; + + $cmd = $rri_cname2cmd{$cname}; + $cmd |= 0x08 if $seq < $nele-1; # set chain bit + $cmd |= ($seq & 0xf) << 4; # set sequence number field + $ele->{cmd} = $cmd; + raw_snd9_crc($cmd); + $seq += 1; + + if ($cname eq "rreg") { + $stat_tab{xreg} += 1; + raw_snd9_crc($ele->{addr}); + raw_snd9($ocrc); + } elsif ($cname eq "rblk") { + $stat_tab{xblk} += 1; + raw_snd9_crc($ele->{addr}); + raw_snd9_crc($ele->{nblk}-1); + raw_snd9($ocrc); + } elsif ($cname eq "wreg") { + $stat_tab{xreg} += 1; + raw_snd9_crc($ele->{addr}); + raw_snd9_crc( $ele->{data} & 0xff); + raw_snd9_crc(($ele->{data}>>8) & 0xff); + raw_snd9($ocrc); + } elsif ($cname eq "wblk") { + $stat_tab{xblk} += 1; + raw_snd9_crc($ele->{addr}); + raw_snd9_crc($ele->{nblk}-1); + raw_snd9($ocrc); + foreach ( @{$ele->{dat_wblk}} ) { + raw_snd9_crc( $_ & 0xff); + raw_snd9_crc(($_>>8) & 0xff); + } + raw_snd9($ocrc); + } elsif ($cname eq "stat") { + raw_snd9($ocrc); + } elsif ($cname eq "attn") { + raw_snd9($ocrc); + } elsif ($cname eq "init") { + raw_snd9_crc($ele->{addr}); + raw_snd9_crc( $ele->{data} & 0xff); + raw_snd9_crc(($ele->{data}>>8) & 0xff); + raw_snd9($ocrc); + } + } + + raw_snd9(D9EOP); + + raw_get9_checksop() or return 0; + + foreach my $ele (@$href) { + my $cname = $ele->{cname}; + my $idat; + my $ok = 1; + + raw_get9_crc_check($ele->{cmd}, "cmd") or return 0; + + if ($cname eq "rreg") { + raw_get9_crc_16bit(\$ele->{rcv_data}) or return 0; + raw_get9_crc_8bit(\$ele->{rcv_stat}) or return 0; + raw_get9_check($icrc, "crc") or return 0; + } elsif ($cname eq "rblk") { + raw_get9_crc_check($ele->{nblk}-1, "nblk") or return 0; + for (my $i=0; $i<$ele->{nblk}; $i++) { + my $data; + my $err; + raw_get9_crc_16bit(\$data) or return 0; + push @{$ele->{rcv_rblk}}, $data; + $err = rri_ref_check($data, $ele->{ref_rblk}[$i], $ele->{msk_rblk}[$i]); + push @{$ele->{err_rblk}}, $err; + $ok = 0 if $err; + } + raw_get9_crc_8bit(\$ele->{rcv_stat}) or return 0; + raw_get9_check($icrc, "crc") or return 0; + } elsif ($cname eq "wreg") { + raw_get9_crc_8bit(\$ele->{rcv_stat}) or return 0; + raw_get9_check($icrc, "crc") or return 0; + } elsif ($cname eq "wblk") { + raw_get9_crc_8bit(\$ele->{rcv_stat}) or return 0; + raw_get9_check($icrc, "crc") or return 0; + } elsif ($cname eq "stat") { + raw_get9_crc_8bit(\$ele->{rcv_ccmd}) or return 0; + raw_get9_crc_16bit(\$ele->{rcv_data}) or return 0; + raw_get9_crc_8bit(\$ele->{rcv_stat}) or return 0; + raw_get9_check($icrc, "crc") or return 0; + } elsif ($cname eq "attn") { + raw_get9_crc_16bit(\$ele->{rcv_data}) or return 0; + raw_get9_crc_8bit(\$ele->{rcv_stat}) or return 0; + raw_get9_check($icrc, "crc") or return 0; + } elsif ($cname eq "init") { + raw_get9_crc_8bit(\$ele->{rcv_stat}) or return 0; + raw_get9_check($icrc, "crc") or return 0; + } + + if (defined $ele->{rcv_data}) { + $ele->{err_data} = rri_ref_check($ele->{rcv_data}, + $ele->{ref_data}, $ele->{msk_data}); + $ok = 0 if $ele->{err_data}; + } + if (defined $ele->{rcv_stat}) { + $ele->{err_stat} = rri_ref_check($ele->{rcv_stat}, + $ele->{ref_stat}, $ele->{msk_stat}); + $ok = 0 if $ele->{err_stat}; + } + + $ele->{ok} = $ok; + + } + + raw_get9_checkeop() or return 0; + + return 1; +} + +#------------------------------------------------------------------------------- + +sub rri_cmdlist_check_stat { + my ($href) = @_; + + foreach my $ele (@$href) { + return 1 if not exists $ele->{rcv_stat}; + return 1 if $ele->{err_stat}; + } + + return 0; +} + +#------------------------------------------------------------------------------- + +sub rri_cmdlist_get_rval { + my ($href,$ind) = @_; + my $nele = scalar(@$href); + + return (undef, "#ind?#") if ($ind >= $nele); + + return (undef, "#sta?#") if not exists $$href[$ind]->{rcv_stat}; + + return (undef, sprintf "#s=%2.2x#",$$href[$ind]->{rcv_stat}) + if $$href[$ind]->{err_stat}; + + return (undef, "#dat?#") if (not exists $$href[$ind]->{rcv_data}); + + return ($$href[$ind]->{rcv_data}, sprintf "%6.6o",$$href[$ind]->{rcv_data}); +} + +#------------------------------------------------------------------------------- + +sub rri_cmdlist_conv_rval { + my ($href,$ind) = @_; + my ($val,$str) = rri_cmdlist_get_rval($href, $ind); + return $str; +} + +#------------------------------------------------------------------------------- + +sub rri_ref_check { # check reference data (1=err) + my ($rcv,$ref,$msk) = @_; + if (defined $ref) { + my $mask = (defined $msk) ? $msk : 0; + my $mrcv = $rcv | $mask; + my $mref = $ref | $mask; + return 1 if $mrcv != $mref; + } + return 0; +} + +#------------------------------------------------------------------------------- + +sub pdpcp_open { + $rri_ref_sdef = 0x00; # by default check for 'hard' errors + $rri_msk_sdef = 0x70; # ignore cpuhalt,cpugo and attn +} + +#------------------------------------------------------------------------------- + +sub pdpcp_flush { + my ($case) = @_; + rri_cmdlist_do(); +} + +#------------------------------------------------------------------------------- + +sub pdpcp_close { +} + +#------------------------------------------------------------------------------- +# .tocmd n +# .tostp n +# .togo n +# .anena 0|1 +# .cpmon 0|1 +# .rbmon 0|1 +# .scntl n 0|1 +# .sinit g8 g16 +# .sdef [s=g8] +# .cerr 0|1 +# .merr 0|1 +# .reset +# .wait n +# .cclst +# rr* [d=g16] [s=g8] +# wr* g16 [s=g8] +# brm n [s=g8] +# followed by n d=g16 data check values +# bwm n [s=g8] +# followed by n g16 data values +# wal g16 [s=g8] +# wah g16 [s=g8] +# rps [d=g16] [s=g8] +# wps g16 [s=g8] +# rm [d=g16] [s=g8] +# rmi [d=g16] [s=g8] +# wm g16 [s=g8] +# wmi g16 [s=g8] +# stapc g16 [s=g8] +# sta [s=g8] +# sto [s=g8] +# cont [s=g8] +# step [s=g8] +# rst [s=g8] +# wibrb g16 +# ribr g6 [d=g16] [s=g8] +# wibr g6 g16 +# wtgo +# wtlam [d=g16] +# + +sub pdpcp_cexec { + my ($cmd) = @_; + my $cclast; + my $aname; + if ($cmd =~ /^([a-z0-9]*)/) { + $aname = $1; + } + + $cmd =~ s/^rsp/rr6/; # rsp -> rr6 + $cmd =~ s/^rpc/rr7/; # rsp -> rr7 + $cmd =~ s/^wsp/wr6/; # wsp -> wr6 + $cmd =~ s/^wpc/wr7/; # wsp -> wr7 + + $cmd_line = $cmd; + $cmd_rest = ""; + $cmd_bad = 0; + + if ($cmd =~ /^\.to(cmd|stp|go)\s+(\d*)/) {# .tocmd, .tostp, .togo + $cmd_rest = $'; + print "pi_rri($curmode)-I: $cmd currently ignored\n"; + + } elsif ($cmd =~ /^\.anena\s+([01])/) { # .anena ------------------------ + $cmd_rest = $'; + my $ena = int $1; + my $ena_data = ($ena==0) ? 0x0000 : 0x8000; + rri_cmdlist_do(); + push @rri_cmdlist, {cname => "init", + aname => ".anena", + addr => 0xff, + data => $ena_data}; + rri_cmdlist_do(); + + } elsif ($cmd =~ /^(\.cpmon|\.rbmon)\s+([01])/) { # .cpmon, .rbmon --------- + $cmd_rest = $'; + my $ind = ($1 eq ".cpmon") ? 15 : 14; + $cmd_rest = $'; + rri_sideband(0x00, ($ind<<8) + $2); + + } elsif ($cmd =~ /^\.scntl\s+(\d+)\s([01])/) { # .scntl ------------------ + $cmd_rest = $'; + rri_sideband(0x00, ($1<<8) + $2); + + } elsif ($cmd =~ /^\.sinit/) { # .sinit ------------------ + $cmd_rest = $'; + my $addr = cget_gdat(8,$rri_dbasi); + my $data = cget_gdat(16,$rri_dbasi); + rri_sideband($addr, $data) if (not $cmd_bad); + + } elsif ($cmd =~ /^\.sdef/) { # .sdef ------------------------- + $cmd_rest = $'; + ($rri_ref_sdef,$rri_msk_sdef) = cget_tagval2_gdat("s",8,2); + + } elsif ($cmd =~ /^\.[cm]err\s*[01]/) { # .[cm]err + # ignore, no action + + } elsif ($cmd =~ /^\.reset/) { # .reset ------------------------ + $cmd_rest = $'; + rri_cmdlist_do(); # flush before reset + push @rri_cmdlist, {cname => "init", + aname => ".reset", + addr => 0x00, + data => 0x01}; + rri_cmdlist_do(); # flush after reset + + } elsif ($cmd =~ /^\.wait\s+(\d+)/) { # .wait ------------------------ + $cmd_rest = $'; + my $delay = int $1; + rri_cmdlist_do(); # flush before waiting + for (my $i = 0; $i < $delay; $i++) { + raw_snd9(D9IDLE); + } + + } elsif ($cmd =~ /^\.cclst/) { # .cclst ------------------------ + $cmd_rest = $'; + $rri_ncmdmax = scalar(@rri_cmdlist) + 1; # force exec after next cmd + + } elsif ($cmd =~ /^rr([0-7])/) { # rr* --------------------------- + $cmd_rest = $'; + my $rnum = int $1; + pdpcp_cmd_rreg($aname, PDPCP_ADDR_R0+$rnum); + + } elsif ($cmd =~ /^wr([0-7])/) { # wr* --------------------------- + $cmd_rest = $'; + my $rnum = int $1; + pdpcp_cmd_wreg($aname, PDPCP_ADDR_R0+$rnum); + + } elsif ($cmd =~ /^brm/) { # brm --------------------------- + $cmd_rest = $'; + my $addr = PDPCP_ADDR_MEMI; + my $nblk = rri_cget_nblk; + my ($ref_stat, $msk_stat) = rri_cget_stat; + my @ref_rblk; + my @msk_rblk; + my $i; + cget_chkblank(); + for ($i = 0; $i < $nblk; $i++) { + $cmd_rest = get_command() if ($cmd_rest eq ""); + $cmd_rest =~ s/^\s*//; + my ($ref,$msk) = cget_tagval2_gdat("d",16,8); + push @ref_rblk, $ref; + push @msk_rblk, $msk; + } + cget_chkblank(); + if (not $cmd_bad) { + push @rri_cmdlist, {cname => "rblk", + aname => $aname, + addr => $addr, + nblk => $nblk, + ref_rblk => [@ref_rblk], + msk_rblk => [@msk_rblk], + ref_stat => $ref_stat, + msk_stat => $msk_stat}; + } + + } elsif ($cmd =~ /^bwm/) { # bwm --------------------------- + $cmd_rest = $'; + my $addr = PDPCP_ADDR_MEMI; + my $nblk = rri_cget_nblk; + my ($ref_stat, $msk_stat) = rri_cget_stat; + my @dat_wblk; + my $i; + cget_chkblank(); + for ($i = 0; $i < $nblk; $i++) { + $cmd_rest = get_command() if ($cmd_rest eq ""); + $cmd_rest =~ s/^\s*//; + push @dat_wblk, cget_gdat(16,8); + } + cget_chkblank(); + if (not $cmd_bad) { + push @rri_cmdlist, {cname => "wblk", + aname => $aname, + addr => $addr, + nblk => $nblk, + dat_wblk => [@dat_wblk], + ref_stat => $ref_stat, + msk_stat => $msk_stat}; + } + + } elsif ($cmd =~ /^wal/) { # wal --------------------------- + $cmd_rest = $'; + pdpcp_cmd_wreg($aname, PDPCP_ADDR_AL); + + } elsif ($cmd =~ /^wah/) { # wah --------------------------- + $cmd_rest = $'; + pdpcp_cmd_wreg($aname, PDPCP_ADDR_AH); + + } elsif ($cmd =~ /^rps/) { # rps --------------------------- + $cmd_rest = $'; + pdpcp_cmd_rreg($aname, PDPCP_ADDR_PSW); + + } elsif ($cmd =~ /^wps/) { # wps --------------------------- + $cmd_rest = $'; + pdpcp_cmd_wreg($aname, PDPCP_ADDR_PSW); + + } elsif ($cmd =~ /^rmi/) { # rmi --------------------------- + $cmd_rest = $'; + pdpcp_cmd_rreg($aname, PDPCP_ADDR_MEMI); + + } elsif ($cmd =~ /^rm/) { # rm ---------------------------- + $cmd_rest = $'; + pdpcp_cmd_rreg($aname, PDPCP_ADDR_MEM); + + } elsif ($cmd =~ /^wmi/) { # wmi --------------------------- + $cmd_rest = $'; + pdpcp_cmd_wreg($aname, PDPCP_ADDR_MEMI); + + } elsif ($cmd =~ /^wm/) { # wm ---------------------------- + $cmd_rest = $'; + pdpcp_cmd_wreg($aname, PDPCP_ADDR_MEM); + + } elsif ($cmd =~ /^stapc/) { # stapc ------------------------- + $cmd_rest = $'; + pdpcp_cmd_wreg($aname, PDPCP_ADDR_PC); + pdpcp_cmd_wreg($aname, PDPCP_ADDR_CNTL, PDPCP_FUNC_STA); + + } elsif ($cmd =~ /^sta/) { # sta --------------------------- + $cmd_rest = $'; + pdpcp_cmd_wreg($aname, PDPCP_ADDR_CNTL, PDPCP_FUNC_STA); + + } elsif ($cmd =~ /^sto/) { # sto --------------------------- + $cmd_rest = $'; + pdpcp_cmd_wreg($aname, PDPCP_ADDR_CNTL, PDPCP_FUNC_STO); + + } elsif ($cmd =~ /^cont/) { # cont -------------------------- + $cmd_rest = $'; + pdpcp_cmd_wreg($aname, PDPCP_ADDR_CNTL, PDPCP_FUNC_CONT); + + } elsif ($cmd =~ /^step/) { # step -------------------------- + $cmd_rest = $'; + pdpcp_cmd_wreg($aname, PDPCP_ADDR_CNTL, PDPCP_FUNC_STEP); + + } elsif ($cmd =~ /^rst/) { # rst --------------------------- + $cmd_rest = $'; + pdpcp_cmd_wreg($aname, PDPCP_ADDR_CNTL, PDPCP_FUNC_RST); + + } elsif ($cmd =~ /^wibrb/) { # wibrb ------------------------- + $cmd_rest = $'; + pdpcp_cmd_wreg($aname, PDPCP_ADDR_IBRB); + + } elsif ($cmd =~ /^ribr/) { # ribr -------------------------- + $cmd_rest = $'; + my $off = cget_gdat(6,8); + pdpcp_cmd_rreg($aname, PDPCP_ADDR_IBR+int($off/2)); + + } elsif ($cmd =~ /^wibr/) { # wibr -------------------------- + $cmd_rest = $'; + my $off = cget_gdat(6,8); + pdpcp_cmd_wreg($aname, PDPCP_ADDR_IBR+int($off/2)); + + } elsif ($cmd =~ /^wtgo/) { # wtgo -------------------------- + $cmd_rest = $'; + rri_cmdlist_do(); + my $tstart = get_time(); + raw_get9_check(D9ATTN, "wtgo"); # ???FIXME this is a hack... + printf "-- wtgo # wait for %7.3f sec\n", get_time()-$tstart; + push @rri_cmdlist, {cname => "attn", + aname => ".wtgo"}; + + } elsif ($cmd =~ /^wtlam/) { # wtlam ------------------------- + $cmd_rest = $'; + my ($ref_data, $msk_data) = cget_tagval2_gdat("d",16,8); + rri_cmdlist_do(); + my $tstart = get_time(); + raw_get9_check(D9ATTN, "wtgo"); # ???FIXME this is a hack... + printf "-- wtlam # wait for %7.3f sec\n", get_time()-$tstart; + push @rri_cmdlist, {cname => "attn", + aname => ".wtlam", + ref_data => $ref_data, + msk_data => $msk_data}; + + } else { + print "pi_rri($curmode)-E: unknown command: \"$cmd_line\"\n"; + } + + cget_chkblank() unless $cmd_bad; + if ($cmd_bad) { + print "pi_rri($curmode)-E: parse error, command ignored: \"$cmd_line\"\n"; + } else { + if (scalar(@rri_cmdlist) >= $cmax || $cclast || + ($rri_ncmdmax && scalar(@rri_cmdlist) >= $rri_ncmdmax)) { + $rri_ncmdmax = undef; + rri_cmdlist_do(); + } + } +} + +#------------------------------------------------------------------------------- + +sub pdpcp_cmd_rreg { + my ($aname,$addr) = @_; + my ($ref_data,$msk_data) = cget_tagval2_gdat("d",16,8); + my ($ref_stat,$msk_stat) = rri_cget_stat; + if (not $cmd_bad) { + push @rri_cmdlist, {cname => "rreg", + aname => $aname, + addr => $addr, + ref_data => $ref_data, + msk_data => $msk_data, + ref_stat => $ref_stat, + msk_stat => $msk_stat}; + } +} + +#------------------------------------------------------------------------------- + +sub pdpcp_cmd_wreg { + my ($aname,$addr,$data) = @_; + my $ldata = (defined $data) ? $data : cget_gdat(16,8); + my ($ref_stat,$msk_stat) = rri_cget_stat; + if (not $cmd_bad) { + push @rri_cmdlist, {cname => "wreg", + aname => $aname, + addr => $addr, + data => $ldata, + ref_stat => $ref_stat, + msk_stat => $msk_stat}; + } +} + +#------------------------------------------------------------------------------- + +sub serv11_open { + $rri_ref_sdef = 0x00; # by default check for 'hard' errors + $rri_msk_sdef = 0x70; # ignore cpuhalt,cpugo and attn + + serv11_config() unless $serv11_config_done; +} + +#------------------------------------------------------------------------------- + +sub serv11_flush { + my ($case) = @_; +} + +#------------------------------------------------------------------------------- + +sub serv11_close { +} + +#------------------------------------------------------------------------------- +# |>>)file} +# ldabs {-s} file +# exa +# dep g16 +# set ... +# sho conf +# sho att +# sho regs +# sho mmu +# sho ubm[ap] +# wtt "string" +# attn +# att file +# det |all +# init +# boot +# start g16 +# step +# stop +# cont +# reset +# server +# + +sub serv11_cexec { + my ($cmd) = @_; + + $cmd_line = $cmd; + $cmd_rest = ""; + $cmd_bad = 0; + +# +# First handle 'special syntax commands: ( and < +# + + if ($cmd =~ /^([<(])/) { # < and ( short hands ----------- + my $str = $'; + my $ucb = cget_ucb("term", "tt0"); + return if $cmd_bad or cget_chkblank(); + + my @bytes; + if ($1 eq "<") { # < command + conv_str2bytes($str, \@bytes); + push @bytes, 0015; + } else { # ( command + if ($str =~ /^\\([0-7]{3})$/) { # (\ooo escape + push @bytes, oct $1; + } elsif ($str =~ /^\\\^(.)$/) { # (^c escape + my $byt = ord($1); # to byte value + $byt -= 040 if ($byt >= 040); # map to control char + $byt -= 040 if ($byt >= 040); + $byt -= 040 if ($byt >= 040); + push @bytes, $byt; + } else { + conv_str2bytes($str, \@bytes, 1); + } + } + my $ctl = $serv11_ctltbl{$ucb->{ctlname}}; + &{$ctl->{ichrhdl}}($ucb, \@bytes); + + return; + } + +# +# Now prepare normal syntax commands +# + + if ($cmd =~ /^(\w+)\b/) { # get command name + $cmd = $1; + $cmd_rest = $'; + $cmd_rest =~ s/^\s*//; + } + + if ($cmd =~ /^lspc/) { # dump pc/ps ----------------- + return if cget_chkblank(); + serv11_cexec_shoreg(0); + + } elsif ($cmd =~ /^lsmem/) { # dump memory -------------------- + my $opt_m = cget_opt("-m"); + my $opt_a = cget_opt("-a"); + my $abeg = cget_gdat(22, 8); + return if $cmd_bad; + my $aend = $abeg+64; + my $fh = *STDOUT; + my $redi = 0; + if ($cmd_rest =~ /^:n(\d*)/) { + $cmd_rest = $'; + $aend = $abeg + 2*(int $1); + } elsif ($cmd_rest =~ /^:/) { + $cmd_rest = $'; + $aend = cget_gdat(22, 8); + return if $cmd_bad; + } + if ($cmd_rest =~ /^\s*(>{1,2})([\w\/.-]+)/) { + $cmd_rest = $'; + my $oper = $1; + my $file = $2; + my $fh_new = new FileHandle; + if ($fh_new->open("$oper$file")) { + $fh = $fh_new; + $redi = 1; + } else { + print "pi_rri($curmode)-E: failed to open output file $file\n"; + } + } + + $abeg &= 0xfffffffe; + $aend &= 0xfffffffe; + my $nword = int (($aend - $abeg)/2); + $nword = 1 if $nword <= 1; + + return if cget_chkblank(); + + my @data; + my $rc = serv11_exec_rblk($abeg, 1, \@data, $nword); + + my $inst_nw = 0; + my $inst_str = ""; + printf $fh "Memory %8.8o:%8.8o:\n", $abeg, $aend; + for (my $i=0; $i<$nword; $i++) { + if ($opt_m) { + ($inst_str, $inst_nw) = + pdp11_disassemble($abeg+2*$i, $data[$i],$data[$i+1],$data[$i+2]); + printf $fh " %6.6o :", $abeg+2*$i; + for (my $j=0; $j<3; $j++) { + if ($j < $inst_nw) { + printf $fh " %6.6o", (defined $data[$i+$j]) ? $data[$i+$j] : 0; + } else { + print $fh " "; + } + } + printf $fh " # %s\n", $inst_str; + $i += $inst_nw-1; + + } elsif ($opt_a) { + my $nline = $nword - $i; + my $ascbuf; + $nline = 4 if $nline > 4; + printf $fh " %6.6o :", $abeg+2*$i; + for (my $j=0; $j<$nline; $j++) { + my $word = $data[$i+$j]; + my $bl = $word & 0377; + my $bh = ($word>>8) & 0377; + printf $fh " %3.3o %3.3o", $bl, $bh; + $ascbuf .= " " . conv_byte2ascii2($bl); + $ascbuf .= " " . conv_byte2ascii2($bh); + } + print $fh " " x (8*(4-$nline)+4); + print $fh $ascbuf; + print $fh "\n"; + $i += $nline-1; + + } else { + printf $fh " %6.6o : %6.6o\n", $abeg+2*$i, $data[$i]; + } + } + $fh->close() if $redi; + + } elsif ($cmd =~ /^ldabs/) { # load absolute loader format ---- + my $opt_s = cget_opt("-s"); + my $file = cget_file(); + return if cget_chkblank(); + serv11_cexec_ldabs($file, $opt_s); + + } elsif ($cmd =~ /^exa/) { # examine register or memory ----- + my $optset = cget_optset("ir"); + my ($ctl, $beg, $end) = cget_regrange(); + return if cget_chkblank(); + serv11_cexec_exa($optset, $ctl, $beg, $end); + + + } elsif ($cmd =~ /^dep/) { # deposit register or memory ----- + my $optset = cget_optset("ir"); + my ($ctl, $beg, $end) = cget_regrange(); + my $data = cget_gdat(16, 8); + return if cget_chkblank(); + serv11_cexec_dep($optset, $ctl, $beg, $end, $data); + + + } elsif ($cmd =~ /^set/) { # set parameter ------------------ + my $what = cget_name(); + return if $cmd_bad; + + if ($what =~ /^sim/) { # set sim[ulator] ------ + my $pnam = cget_name(); + my $val = cget_bool(); + return if $cmd_bad or cget_chkblank(); + my $ind; + $ind = 15 if $pnam eq "cpmon"; + $ind = 14 if $pnam eq "rbmon"; + $ind = 13 if $pnam eq "tmu"; + if (defined $ind) { + rri_sideband(0x00, ($ind<<8) + $val); + } else { + printf "pi_rri($curmode)-E: Invalid parameter '$pnam' for set sim\n"; + } + + } else { # set --------- + my $ctl = $serv11_ctltbl{uc($what)}; + if (defined $ctl) { + my $partbl = $ctl->{partbl}; + if (defined $partbl) { + my $pnam = cget_name(); + return if $cmd_bad; + + my $pdsc = $partbl->{$pnam}; + if (defined $pdsc) { + my $type = $pdsc->{type}; + if ($type =~ /^hval:([bdos])$/) { + my $cnv = $1; + my $val; + if ($cnv eq "b") { + $val = cget_bool(); + } elsif ($cnv eq "d") { + $val = cget_gdat(32, 10); + } elsif ($cnv eq "o") { + $val = cget_gdat(32, 8); + } elsif ($cnv eq "s") { + $val = $cmd_rest; + $val =~ s/^\s*//; + $val =~ s/\s*$//; + $cmd_rest = ""; + } + return if $cmd_bad or cget_chkblank(); + $ctl->{$pnam} = $val; + } else { + print "pi_rri($curmode)-E: unexpected type $type in partbl\n"; + } + } else { + print "pi_rri($curmode)-E: '$pnam' not valid for 'set $what'\n"; + } + } else { + print "pi_rri($curmode)-I: nothing to set for '$what'\n"; + } + } else { + print "pi_rri($curmode)-E: unknown entity for 'set': \"$what\"\n"; + } + } + + } elsif ($cmd =~ /^sho/) { # show parameters ---------------- + my $what = cget_name(); + return if $cmd_bad; + + if ($what =~ /^conf/) { # sho conf[iguration] -- + return if cget_chkblank(); + serv11_cexec_shoconf(); + + } elsif ($what =~ /^att/) { # sho att -------------- + return if cget_chkblank(); + serv11_cexec_shoatt(); + + } elsif ($what =~ /^regs/) { # sho regs ------------- + return if cget_chkblank(); + serv11_cexec_shoreg(1); + + } elsif ($what =~ /^mmu/) { # sho mmu -------------- + return if cget_chkblank(); + serv11_cexec_shommu_ssrx; + serv11_cexec_shommu_sadr(0172300, "KM"); + serv11_cexec_shommu_sadr(0172200, "SM"); + serv11_cexec_shommu_sadr(0177600, "UM"); + + } elsif ($what =~ /^ubm/) { # sho ubmap ------------ + return if cget_chkblank(); + + my @data; + my $rc = serv11_exec_rblk(0170200, 0, \@data, 64); + print "UNIBUS mapping registers:\n"; + for (my $i=0; $i<32; $i++) { + printf " [%2d]: %2.2o,%6.6o\n", $i, $data[2*$i+1], $data[2*$i]; + } + + } else { # sho --------- + my $ctl = $serv11_ctltbl{uc($what)}; + if (defined $ctl) { + my $partbl = $ctl->{partbl}; + if (defined $partbl) { + foreach my $pnam (sort keys %{$partbl}) { + my $pdsc = $partbl->{$pnam}; + my $type = $pdsc->{type}; + if ($type =~ /^hval:([bdos])$/) { + my $cnv = $1; + my $val = $ctl->{$pnam}; + my $val_str = $val; + if (defined $val) { + $val_str = ($val) ? "1 (yes)" : "0 (no)" if $cnv eq "b"; + $val_str = sprintf("%6d.", $val) if $cnv eq "d"; + $val_str = sprintf("%6.6o", $val) if $cnv eq "o"; + } else { + $val_str = ""; + } + printf "%4s %10s : %s\n", uc($what), $pnam, $val_str; + } else { + print "pi_rri($curmode)-E: unexpected type $type in partbl\n"; + } + } + } else { + print "pi_rri($curmode)-I: nothing to show for '$what'\n"; + } + } else { + print "pi_rri($curmode)-E: unknown entity for 'sho': \"$what\"\n"; + } + } + + } elsif ($cmd =~ /^wtt/) { # write to TT decives ------------- + my $ucb = cget_ucb("term"); + my $str = "\\n"; + if ($cmd_rest =~ /^\s*"(.*)"\s*/) { + $cmd_rest = $'; + $str = $1; + } + return if $cmd_bad or cget_chkblank(); + + my $ctl = $serv11_ctltbl{$ucb->{ctlname}}; + my @bytes; + conv_str2bytes($str, \@bytes, 1); + &{$ctl->{ichrhdl}}($ucb, \@bytes) + + } elsif ($cmd =~ /^attn/) { # attn -------------------------- + return if cget_chkblank(); + serv11_server_attn_get(); + + } elsif ($cmd =~ /^att/) { # attach ------------------------ + my $ucb = cget_ucb(); + return if $cmd_bad; + serv11_cexec_attdet(0,$ucb); + + } elsif ($cmd =~ /^det/) { # detach ------------------------ + my $ucb = cget_ucb(); + return if cget_chkblank(); + serv11_cexec_attdet(1,$ucb); + + } elsif ($cmd =~ /^init/) { # init -------------------------- + return if cget_chkblank(); + serv11_init_dispatch() if $serv11_init_pending; + + } elsif ($cmd =~ /^boot/) { # boot -------------------------- + my $ucb = cget_ucb(); + return if $cmd_bad or cget_chkblank(); + serv11_cexec_boot($ucb); + + } elsif ($cmd =~ /^start/) { # start -------------------------- + my $addr = cget_gdat(16, 8); + return if cget_chkblank(); + my @rval; + my $rc; + serv11_rri_init(".anena", 0xff, $serv11_init_anena);# enable attn+ioto + serv11_rri_attn("attn"); # discard old attn's + serv11_rri_wreg("wpc", PDPCP_ADDR_PC, $addr); + serv11_rri_wreg("sta", PDPCP_ADDR_CNTL, PDPCP_FUNC_STA); + $rc = serv11_rri_exec(\@rval); + + } elsif ($cmd =~ /^step/) { # step -------------------------- + my @rval; + my $rc; + serv11_rri_wreg("sta", PDPCP_ADDR_CNTL, PDPCP_FUNC_STEP); + $rc = serv11_rri_exec(\@rval); + serv11_cexec_shoreg(1); + + } elsif ($cmd =~ /^stop/) { # stop -------------------------- + my @rval; + my $rc; + serv11_rri_wreg("sto", PDPCP_ADDR_CNTL, PDPCP_FUNC_STO); + $rc = serv11_rri_exec(\@rval); + serv11_cexec_shoreg(1); + + } elsif ($cmd =~ /^cont/) { # cont -------------------------- + my @rval; + my $rc; + serv11_rri_wreg("sto", PDPCP_ADDR_CNTL, PDPCP_FUNC_CONT); + $rc = serv11_rri_exec(\@rval); + + } elsif ($cmd =~ /^reset/) { # reset ------------------------- + my @rval; + my $rc; + serv11_rri_wreg("rst", PDPCP_ADDR_CNTL, PDPCP_FUNC_RST); + $rc = serv11_rri_exec(\@rval); + + } elsif ($cmd =~ /^server/) { # enter server mode -------------- + return if cget_chkblank(); + serv11_server(); + + } else { + print "pi_rri($curmode)-E: unknown command: \"$cmd_line\"\n"; + } +} + + +#------------------------------------------------------------------------------- + +sub serv11_cexec_shoreg { + my ($mode) = @_; + my $ipc; + my $ips; + my @rval; + + if ($mode > 0) { + serv11_rri_rreg("rr0", PDPCP_ADDR_R0+0); + serv11_rri_rreg("rr1", PDPCP_ADDR_R0+1); + serv11_rri_rreg("rr2", PDPCP_ADDR_R0+2); + serv11_rri_rreg("rr3", PDPCP_ADDR_R0+3); + serv11_rri_rreg("rr4", PDPCP_ADDR_R0+4); + serv11_rri_rreg("rr5", PDPCP_ADDR_R0+5); + serv11_rri_rreg("rr6", PDPCP_ADDR_R0+6); + } + $ipc = serv11_rri_rreg("rr7", PDPCP_ADDR_R0+7); + $ips = serv11_rri_rreg("rps", PDPCP_ADDR_PSW); + + my $rc = serv11_rri_exec(\@rval); + + print "Processor registers and status:\n" if ($mode > 0); + + my $ps_bin = gconv_dat16($rval[$ips],2); + + printf " PC: %6.6o ", $rval[$ipc] if ($mode == 0); + printf " PS: %6.6o", $rval[$ips]; + printf " cmo=%s",substr($ps_bin,0,2); # bit 15:14 -> 0,2 + printf " pmo=%s",substr($ps_bin,2,2); # bit 13:12 -> 2,2 + printf " set=%s",substr($ps_bin,4,1); # bit 11 -> 4 + printf " pri=%d",($rval[$ips]>>5)&0x7; # bit 07:05 + printf " t=%s", substr($ps_bin,11,1); # bit 04 -> 11,1 + printf " NZVC=%s", substr($ps_bin,12,4); # bit 03:00 -> 12,4 + print "\n"; + + if ($mode > 0) { + printf " R0: %6.6o", $rval[0]; + printf " R1: %6.6o", $rval[1]; + printf " R2: %6.6o", $rval[2]; + printf " R3: %6.6o\n", $rval[3]; + printf " R4: %6.6o", $rval[4]; + printf " R5: %6.6o", $rval[5]; + printf " SP: %6.6o", $rval[6]; + printf " PC: %6.6o\n", $rval[$ipc]; + } +} + +#------------------------------------------------------------------------------- +# ssr0 177572 +# ssr1 177574 +# ssr2 177576 +# ssr3 172516 + +sub serv11_cexec_shommu_ssrx { + my @rval; + + serv11_rri_wreg("wal", PDPCP_ADDR_AL, 0177572); + my $issr0 = serv11_rri_rreg("rmi", PDPCP_ADDR_MEMI); + my $issr1 = serv11_rri_rreg("rmi", PDPCP_ADDR_MEMI); + my $issr2 = serv11_rri_rreg("rmi", PDPCP_ADDR_MEMI); + serv11_rri_wreg("lal", PDPCP_ADDR_AL, 0172516); + my $issr3 = serv11_rri_rreg("rmi", PDPCP_ADDR_MEMI); + + my $rc = serv11_rri_exec(\@rval); + + print "MMU registers:\n"; + printf " SSR0: %6.6o\n", $rval[$issr0]; + printf " SSR1: %6.6o\n", $rval[$issr1]; + printf " SSR2: %6.6o\n", $rval[$issr2]; + printf " SSR3: %6.6o\n", $rval[$issr3]; + +} + +#------------------------------------------------------------------------------- +# +# Note: The ptape maindec's have even size records, except possibly for the +# last one, and always start at an even address. +# The lda's extracted with UPD2 PIP from the xxdp22 disk have often +# records with 503 byte payload, starting at even and odd addresses. +# Since blkw only handles even sized transfers on even addresses some +# magic with the %oddbyt hash is needed to handle this correctly. +# +sub serv11_cexec_ldabs { + my ($file,$opt_s) = @_; + if (not -r $file) { + print "pi_rri($curmode)-E: file $file not found or readable\n"; + return; + } + my $fh = new FileHandle; + + $fh->open("<$file") or die "unexpected open failure"; + + my $chrnum = 0; # char number in block + my $blknum = 0; # block number + my $bytcnt = 0; # byte count + my $ldaddr = 0; # load address + my $chksum = 0; # check sum + my $addr = 0; # current address + my @data; # data array for transfer + my %oddbyt; # odd byte cache + my $word; + + while (1) { + my $buf; + my $rc = $fh->read($buf,1); + if ($rc == 0) { + print "pi_rri($curmode)-E: unexpected EOF in $file\n" unless $chrnum == 0; + return; + } + + return if $rc != 1; + my $byt = ord($buf); + $chksum = ($chksum + $byt) & 0377; + + if ($chrnum == 0) { # in blank tape + if ($byt == 0) { + next; + } elsif ($byt == 1) { + $chrnum += 1; + } else { + printf "pi_rri($curmode)-E: unexpected start-of-block %3.3o in $file\n", + $byt; + return; + } + + } elsif ($chrnum == 1) { # 001 frame seen + if ($byt == 0) { + $chrnum += 1; + } else { + printf "pi_rri($curmode)-E: unexpected 2nd char %3.3o in $file\n", + $byt; + return; + } + + } elsif ($chrnum == 2) { # byte count low + $bytcnt = $byt & 0377; + $chrnum += 1; + } elsif ($chrnum == 3) { # byte count high + $bytcnt |= ($byt & 0377)<<8; + $chrnum += 1; + + } elsif ($chrnum == 4) { # load address low + $ldaddr = $byt & 0377; + $chrnum += 1; + } elsif ($chrnum == 5) { # load address high + $ldaddr |= ($byt & 0377)<<8; + $chrnum += 1; + printf "pi_rri($curmode)-I: block %3d, length %5d byte,". + " address %6.6o:%6.6o\n", + $blknum, ($bytcnt-6), $ldaddr, $ldaddr+($bytcnt-6)-1; + + $addr = $ldaddr; # setup current address + $word = 0; + if (($addr & 01) == 1 && $bytcnt > 6) { # setup even byte if known... + $word = $oddbyt{sprintf("%6.6o",$addr)}; + if (not defined $word) { + printf "pi_rri($curmode)-W: no low byte data for %6.6o\n", $addr; + $word = 0; + } + } + + } elsif ($chrnum == $bytcnt) { # check sum byte + if ($chksum != 0) { + printf "pi_rri($curmode)-E: check sum error %3.3o in $file\n", + $chksum; + return; + } + if ($chrnum == 6) { + printf "pi_rri($curmode)-I: start address %6.6o\n", $ldaddr; + return; + } else { + if (($addr & 01) == 1) { # high byte not yet seen + push @data, $word; # zero fill high byte + $oddbyt{sprintf("%6.6o",$addr)} = $word; # store even byte for later + # note that address is odd here + } + serv11_exec_wblk($ldaddr, 0, \@data); + @data = (); + } + $chrnum = 0; + $blknum += 1; + + } else { # in data + if (($addr & 01) == 0) { # low byte + $word = $byt & 0377; + $addr += 1; + } else { # high byte + $word |= ($byt & 0377)<<8; + push @data, $word; + $addr += 1; + } + $chrnum += 1; + } + } + + $fh->close(); +} + +#------------------------------------------------------------------------------- +# sadr format: +# offset 0: DR[0] I space +# offset 20: DR[0] D space +# offset 40: AR[0] I space +# offset 60: AR[0] D space +# +sub serv11_cexec_shommu_sadr { + my ($base,$mode) = @_; + my @data; + my $rc = serv11_exec_rblk($base, 0, \@data, 32); + + for (my $i=0; $i<16; $i++) { + my $space = ($i<8) ? "I" : "D"; + my $ind = $i%8; + my $dr = $data[$i]; + my $ar = $data[$i+16]; + my $dr_bin = gconv_dat16($dr,2); + my $dr_acf = $dr&0xf; # bit 3:0 + + printf " %s-%s[%d]: %6.6o,%6.6o", $mode,$space,$ind, $dr, $ar; + printf " slf=%3d", ($dr>>8)&0xff; + printf " aib=%s", substr($dr_bin,8,2); # bit 7:6 -> 8,2 + printf " acf=%d", $dr_acf; + print "\n"; + } + +} + +#------------------------------------------------------------------------------- + +sub serv11_cexec_shoconf { + foreach my $ctlname (sort { $serv11_ctltbl{$b}->{base} <=> + $serv11_ctltbl{$a}->{base} } + keys %serv11_ctltbl) { + my $ctl = $serv11_ctltbl{$ctlname}; + my $mask = $ctl->{probemask}; + my $ival = $ctl->{probe_ival}; + my $rval = $ctl->{probe_rval}; + my $ib_str = ($mask =~ /i/) ? ( (defined $ival) ? "y" : "n" ) : "-"; + my $rb_str = ($mask =~ /r/) ? ( (defined $rval) ? "y" : "n" ) : "-"; + printf "%-3s %-9s %4s: %s ib=%s rb=%s lam=%s boot=%s", $ctlname, + $ctl->{ctltype}, $ctl->{type}, + ($ctl->{base} ? sprintf("%6.6o", $ctl->{base}) : "......"), + $ib_str, $rb_str, + (exists $ctl->{lam} ? sprintf("%2d",$ctl->{lam}) : " -"), + (exists $ctl->{boot_code} ? "y" : "n"); + printf " %s",$ctl->{probe_text} if $ctl->{probe_text}; + print "\n"; + } +} + +#------------------------------------------------------------------------------- + +sub serv11_cexec_shoatt { + foreach my $unitname (sort keys %serv11_unittbl) { + my $ucb = $serv11_unittbl{$unitname}; + my $ctl = $serv11_ctltbl{$ucb->{ctlname}}; + next unless $ctl->{probe_ok}; + next unless $ucb->{att_ok}; + printf "%-3s : ", $unitname; + if ($ctl->{type} eq "disk") { + printf "nblk=%6d wp=%s file=%s", + $ucb->{att_nblk}, + ($ucb->{att_wpro} ? "y" : "n"), + $ucb->{att_file}; + } elsif ($ctl->{type} eq "tape") { + printf "wp=%s file=%s", + ($ucb->{att_wpro} ? "y" : "n"), + $ucb->{att_file}; + } elsif ($ctl->{type} eq "term") { + printf "port=%s", + $ucb->{att_port}; + } + print "\n"; + } +} + +#------------------------------------------------------------------------------- + +sub serv11_cexec_attdet { + my ($det,$ucb) = @_; + my $ctl = $serv11_ctltbl{$ucb->{ctlname}}; + + my $attdethdl = $ctl->{attdethdl}; + + if (not defined $attdethdl) { + printf "pi_rri($curmode)-E: attach/detach not supported for %s\n", + $ucb->{unitname}; + return; + } + + &{$attdethdl}($det, $ucb); # call handler + +} + +#------------------------------------------------------------------------------- + +sub serv11_cexec_boot { + my ($ucb) = @_; + my @rval; + my $rc; + + my $unitname = $ucb->{unitname}; + my $ctl = $serv11_ctltbl{$ucb->{ctlname}}; + + if (not exists $ctl->{boot_code}) { + print "pi_rri($curmode)-E: device $unitname not bootable\n"; + return; + } + + serv11_init_dispatch() if $serv11_init_pending; + + my @boot_code = @{$ctl->{boot_code}}; + my $boot_length = scalar(@boot_code); + my $boot_mode = $ctl->{boot_mode}; + my $boot_entry = $ctl->{boot_entry}; + + $boot_mode = "disk" unless defined $boot_mode; + + if ($boot_mode eq "disk") { + my $boot_unit = $ctl->{boot_unit}; + $boot_code[int (($boot_unit-(BOOT_START))/2)] = + $ucb->{ctlunit}; # patch in unit num + $rc = serv11_exec_wblk(BOOT_START, 0, \@boot_code, $boot_length); + + } elsif ($boot_mode eq "ptape") { + my $boot_base = $ctl->{boot_base}; + my $memsize = 56 * 1024; # FIXME: check memtop !!! + $memsize = 56*1024 if ($memsize > 56*1024); + my $nblk8k = $memsize/020000; + my $offset = ($nblk8k-1) * 020000; + $boot_base += $offset; + $boot_entry += $offset; + $rc = serv11_exec_wblk($boot_base, 0, \@boot_code, $boot_length); + + } else { + print_fatal("unsupported boot mode '$boot_mode' in serv11_cexec_boot"); + } + + serv11_rri_init(".anena", 0xff, $serv11_init_anena); # enable attn+ioto + serv11_rri_attn("attn"); # discard old attn's + serv11_rri_wreg("wpc", PDPCP_ADDR_PC, $boot_entry); + serv11_rri_wreg("sta", PDPCP_ADDR_CNTL, PDPCP_FUNC_STA); + + $rc = serv11_rri_exec(\@rval); +} + +#------------------------------------------------------------------------------- + +sub serv11_cexec_exa { + my ($optset,$ctl,$beg,$end) = @_; + + if (not defined $ctl) { # numerical address + for (my $addr=$beg; $addr<=$end; $addr+=2) { + my @rval; + serv11_rri_wreg("wal", PDPCP_ADDR_AL, $addr); + serv11_rri_rreg("rm", PDPCP_ADDR_MEM); + my $rc = serv11_rri_exec(\@rval); + printf "mem %6.6o : %6.6o\n", $addr, $rval[0]; + } + + } else { + + my $reglist = $ctl->{reglist}; + for (my $i=$beg; $i<=$end; $i++) { + my $dsc = $reglist->[$i]; + last if not defined $reglist->[$i]; + my $name = $dsc->{name}; + my $addr = $dsc->{addr}; + my $offset = $dsc->{offset}; + my $attr = $dsc->{attr}; + my $val; + my $addr_str = "......"; + my $acs_str = "ib"; + my $val_str = "......"; + my $com_str = ""; + + $addr = $ctl->{base} + $offset if defined $offset; + + $attr = 0 unless defined $attr; + + $acs_str = "rb" if ($attr & REGATTR_RBRD); + $acs_str = "ib" if $optset =~ /i/; + $acs_str = "rb" if $optset =~ /r/; + + if ($end > $beg && + ( ( ($attr & REGATTR_IBMBOX) && $acs_str eq "ib" ) || + ( ($attr & REGATTR_RBMBOX) && $acs_str eq "rb" ) + ) ) { + $com_str = "mailbox skipped"; + + } else { + + my $exadethdl = $dsc->{hdl}; + if (defined $dsc->{hdl}) { + $acs_str = " "; + $val = &{$dsc->{hdl}}(0, $dsc); + + } else { + if ($acs_str eq "rb") { + my $ibrbase = $addr & ~(077); + my $ibroff = $addr - $ibrbase; + serv11_rri_wreg("wibrb", PDPCP_ADDR_IBRB, $ibrbase); + serv11_rri_rreg("ribr", PDPCP_ADDR_IBR + int($ibroff/2)); + $acs_str = "rb"; + } else { + serv11_rri_wreg("wal", PDPCP_ADDR_AL, $addr); + serv11_rri_rreg("rm", PDPCP_ADDR_MEM); + $acs_str = "ib"; + } + my @rval; + my $rc = serv11_rri_exec(\@rval); + $val = $rval[0]; + } + } + + $addr_str = sprintf("%6.6o", $addr) if defined $addr; + $val_str = sprintf("%6.6o", $val) if defined $val; + printf "%4s %6s %2s %6s : %6s", $ctl->{ctlname}, $name, + $acs_str, $addr_str, $val_str; + print " $com_str" if defined $com_str; + print "\n"; + } + + } +} + +#------------------------------------------------------------------------------- + +sub serv11_cexec_dep { + my ($optset,$ctl,$beg,$end,$data) = @_; + + if (not defined $ctl) { # numerical address + for (my $addr=$beg; $addr<=$end; $addr+=2) { + my @rval; + serv11_rri_wreg("wal", PDPCP_ADDR_AL, $addr); + serv11_rri_wreg("wm", PDPCP_ADDR_MEM, $data); + my $rc = serv11_rri_exec(\@rval); + } + + } else { + + my $reglist = $ctl->{reglist}; + for (my $i=$beg; $i<=$end; $i++) { + my $dsc = $reglist->[$i]; + last if not defined $reglist->[$i]; + my $name = $dsc->{name}; + my $addr = $dsc->{addr}; + my $offset = $dsc->{offset}; + my $attr = $dsc->{attr}; + my $acs_str = "ib"; + + $addr = $ctl->{base} + $offset if defined $offset; + + $attr = 0 unless defined $attr; + + $acs_str = "rb" if ($attr & REGATTR_RBWR); + $acs_str = "ib" if $optset =~ /i/; + $acs_str = "rb" if $optset =~ /r/; + + my $exadethdl = $dsc->{hdl}; + if (defined $dsc->{hdl}) { + $acs_str = " "; + &{$dsc->{hdl}}(1, $dsc, $data); + + } else { + if ($acs_str eq "rb") { + my $ibrbase = $addr & ~(077); + my $ibroff = $addr - $ibrbase; + serv11_rri_wreg("wibrb", PDPCP_ADDR_IBRB, $ibrbase); + serv11_rri_wreg("wibr", PDPCP_ADDR_IBR + int($ibroff/2), $data); + $acs_str = "rb"; + } else { + serv11_rri_wreg("wal", PDPCP_ADDR_AL, $addr); + serv11_rri_wreg("wm", PDPCP_ADDR_MEM, $data); + $acs_str = "ib"; + } + my @rval; + my $rc = serv11_rri_exec(\@rval); + } + + } + + } + +} + +#------------------------------------------------------------------------------- +# config is called once on the first entering of serv11 mode +# +sub serv11_config { + $serv11_config_done = 1; + + foreach my $ctlname (sort keys %serv11_ctltbl) { + my $ctl = $serv11_ctltbl{$ctlname}; + $ctl->{probemask} = "ir" unless defined $ctl->{probemask}; + &{$ctl->{probehdl}}($ctl) if exists $ctl->{probehdl}; + } + + if (not $serv11_ctltbl{CPU}->{probe_ok}) { + print_fatal("probe of CPU failed in serv11_open()"); + } + + init_regtbl(); + serv11_cexec_shoconf(); +} + +#------------------------------------------------------------------------------- + +sub serv11_init_dispatch { + foreach my $ctlname (sort keys %serv11_ctltbl) { + my $ctl = $serv11_ctltbl{$ctlname}; + &{$ctl->{inithdl}}($ctl) if (exists $ctl->{inithdl} && $ctl->{probe_ok}); + } + $serv11_init_pending = 0; +} + +#------------------------------------------------------------------------------- + +sub serv11_server { + my $old_timeout = $raw_timeout; + my $nfound; + my $fds_rd_act = ""; + my $fds_rd; + my $stat_delta = 10.; + my $stat_count = 0; + + my $fno_rcv = fileno($fh_rcv); + my $fno_stdin = fileno(STDIN); + + my @telfno2dsc; + + @serv11_attntbl = (); + foreach my $ctlname (sort keys %serv11_ctltbl) { + my $ctl = $serv11_ctltbl{$ctlname}; + if ($ctl->{probe_ok} && exists $ctl->{lam} && exists $ctl->{attnhdl}) { + push @serv11_attntbl, [1<<($ctl->{lam}), $ctl->{attnhdl}, $ctl]; + } + } + + $raw_timeout = 30.; + $serv11_active = 1; + print "pi_rri($curmode)-I: entering server mode\n"; + + my $time_stat = get_time() + $stat_delta; + + while ($serv11_active) { + my $time_now = get_time(); + if ($time_now >= $time_stat) { + ##serv11_server_attn_dispatch(1); + if ($stat_count % 20 == 0) { + printf $fh_log "stat -- "; + printf $fh_log " obyte oesc osop ibyte iesc att"; + printf $fh_log " xreg xblk rdisk wdisk"; + printf $fh_log "\n"; + } + $stat_count += 1; + my $dt = $stat_delta; + + printf $fh_log "stat -- %s", get_timestamp(); + printf $fh_log " %6.0f", ($stat_tab{obyte} - $stat_tab_last{obyte})/$dt; + printf $fh_log " %4.0f", ($stat_tab{oesc} - $stat_tab_last{oesc})/$dt; + printf $fh_log " %4.0f", ($stat_tab{osop} - $stat_tab_last{osop})/$dt; + printf $fh_log " %6.0f", ($stat_tab{ibyte} - $stat_tab_last{ibyte})/$dt; + printf $fh_log " %4.0f", ($stat_tab{iesc} - $stat_tab_last{iesc})/$dt; + printf $fh_log " %3.0f", ($stat_tab{att} - $stat_tab_last{att})/$dt; + printf $fh_log " %5.0f", ($stat_tab{xreg} - $stat_tab_last{xreg})/$dt; + printf $fh_log " %4.0f", ($stat_tab{xblk} - $stat_tab_last{xblk})/$dt; + printf $fh_log " %6.0f", ($stat_tab{rdisk} - $stat_tab_last{rdisk})/$dt; + printf $fh_log " %6.0f", ($stat_tab{wdisk} - $stat_tab_last{wdisk})/$dt; + printf $fh_log "\n"; + %stat_tab_last = %stat_tab; + + while ($time_stat < $time_now) { + $time_stat += $stat_delta; + } + } + + my $timeout = $time_stat - $time_now; + + # set timeout=0 if some unfinished business is still pending + + $timeout = 0. if $serv11_attn_mask != 0; # attn mask not yet worked down + $timeout = 0. if scalar(@serv11_icbque); # icb queue non empty + $timeout = 0. if scalar(@que_rcv); # still input chars in buffer + + if ($serv11_fds_update) { + $fds_rd_act = ""; + vec($fds_rd_act, $fno_rcv, 1) = 1; + vec($fds_rd_act, $fno_stdin, 1) = 1; + + @telfno2dsc = (); + foreach my $port_str (keys %telnettbl) { + my $teldsc = $telnettbl{$port_str}; + my $fno; + if ($teldsc->{state} == TELNET_STATE_LISTEN) { + $fno = fileno($teldsc->{fh_port}); + } else { + $fno = fileno($teldsc->{fh_data}); + } + vec($fds_rd_act, $fno, 1) = 1; + push @telfno2dsc, [$fno, $teldsc]; + } + $serv11_fds_update = 0; + } + + ##printf $fh_log "+++1 select $timeout, rcvq=%d\n", scalar(@que_rcv); + $nfound = select($fds_rd=$fds_rd_act, undef, undef, $timeout); + ##printf $fh_log "+++2 select $nfound\n"; + + if (vec($fds_rd, $fno_stdin, 1)) { + my $cmd = ; + if (defined $cmd) { + chomp $cmd; + + $cmd = "lspc" unless $cmd ne ""; + + $cmd =~ s{^\s*}{}; # remove leading blanks + $cmd =~ s{--.*}{}; # remove comments after -- + $cmd =~ s{\s*$}{}; # remove trailing blanks + + + if ($cmd eq "quit") { + $serv11_active = 0; + } else { + if ($cmd =~ m/^C/) { # ignore, but log "C ..." lines + print $fh_log "$cmd\n"; + } elsif ($cmd =~ m/^#/) { # ignore "# ...." lines + } elsif ($cmd =~ m/^;/) { # ignore "; ...." lines + } else { # otherwise execute + serv11_cexec($cmd); + } + } + } else { # handle ^D + $serv11_active = 0; + } + } + + # process next input char if read will not block (either fd ready for + # input, or still chars in queue). + + if (vec($fds_rd, $fno_rcv, 1) || scalar(@que_rcv)) { + my $dat = raw_rcv9_to(0.); + if (not defined $dat) { + print "pi_rri($curmode)-I: spurious select on rcv channel\n"; + next; + } elsif ($dat == D9IDLE) { + next; + } elsif ($dat == D9ATTN) { + serv11_server_attn_get(); + } else { + printf "pi_rri($curmode)-I: spurious char on server wait: %3.3x\n", + $dat; + next; + } + } + + # process telnet sessions + foreach (@telfno2dsc) { + my $fno = $_->[0]; + if (vec($fds_rd, $fno, 1)) { + my $teldsc = $_->[1]; + telnet_readhdl($teldsc); + } + } + + if ($serv11_attn_mask != 0) { + serv11_server_attn_dispatch(0); + } + + if (scalar(@serv11_icbque)) { + my $icb = shift @serv11_icbque; + &{$icb->{rdmahdl}}($icb); + } + + if ($serv11_attn_mask == 0 && $serv11_attn_seen) { + $serv11_attn_seen = 0; + serv11_server_attn_get(); + } + + } + + $raw_timeout = $old_timeout; + $serv11_active = 0; + print "pi_rri($curmode)-I: leaving server mode\n"; +} + +#------------------------------------------------------------------------------- + +sub serv11_server_attn_get { + my @rval; + my $rc; + + serv11_rri_attn("attn"); + $rc = serv11_rri_exec(\@rval); + + my $mask_old = $serv11_attn_mask; + $serv11_attn_mask |= $rval[0]; # or-in new attn flags + + if (exists $opts{tserv}) { + printf $fh_log "serv -- attn %s :", gconv_dat16($serv11_attn_mask, 2); + foreach my $adsc (@serv11_attntbl) { + my $msk = $adsc->[0]; + my $ctl = $adsc->[2]; + if ($serv11_attn_mask & $msk) { + my $pref = ""; + my $suff = ""; + if ($mask_old & $msk) { # old flags are in () + $pref = "("; + $suff = ")"; + } + printf $fh_log " %s%s%s", $pref, $ctl->{ctlname}, $suff; + } + } + printf $fh_log "\n"; + } + +} + +#------------------------------------------------------------------------------- + +sub serv11_server_attn_dispatch { + my ($force) = @_; + foreach my $adsc (@serv11_attntbl) { + my $msk = $adsc->[0]; + my $hdl = $adsc->[1]; + my $ctl = $adsc->[2]; + if (($serv11_attn_mask & $msk) || $force) { + $serv11_attn_mask &= ~$msk; + &{$hdl}($ctl,$force); + } + } +} + +#------------------------------------------------------------------------------- + +sub serv11_probe_gen { # generic probe handler + my ($ctl) = @_; + my $mask = $ctl->{probemask}; + my $addr = $ctl->{base}; + $addr += $ctl->{csroff} if defined $ctl->{csroff}; + my ($ival,$rval) = serv11_exec_probe($addr, $mask); + $ctl->{probe_ival} = $ival; + $ctl->{probe_rval} = $rval; + $ctl->{probe_ok} = 1; + $ctl->{probe_ok} = 0 if ($mask =~ /i/ && ! defined $ival); + $ctl->{probe_ok} = 0 if ($mask =~ /r/ && ! defined $rval); +} + +#------------------------------------------------------------------------------- + +sub serv11_init_gen { # generic controller init handler + my ($ctl) = @_; + + if (exists $ctl->{usethdl}) { + foreach my $unitname (@{$ctl->{units}}) { + my $ucb = $serv11_unittbl{$unitname}; + &{$ctl->{usethdl}}($ucb); + } + } else { + printf "pi_rri($curmode)-E: usethdl not defined for %s\n", $ctl->{ctlname}; + } +} + +#------------------------------------------------------------------------------- + +sub serv11_detach_gen { # generic detach handler + my ($ucb) = @_; + my $ctl = $serv11_ctltbl{$ucb->{ctlname}}; + + if ($ucb->{att_ok}) { + my $fh = $ucb->{att_fh}; + $fh->close() or die "Unexpected close error"; + $ucb->{att_ok} = 0; + delete $ucb->{att_file}; + delete $ucb->{att_nbyt}; + delete $ucb->{att_nblk}; + delete $ucb->{att_wpro}; + delete $ucb->{att_fh}; + delete $ucb->{att_eof}; + &{$ctl->{usethdl}}($ucb); # setup unit registers + + } else { + printf "pi_rri($curmode)-E: no file attached for %s\n", $ucb->{unitname}; + } +} + +#------------------------------------------------------------------------------- + +sub serv11_attdet_disk { # generic disk att/det handler + my ($det,$ucb) = @_; + my $ctl = $serv11_ctltbl{$ucb->{ctlname}}; + + if ($det) { # detach handling + serv11_detach_gen($ucb); + + } else { # attach handling + if (cget_opt("-w")) { # -w remount + return if $cmd_bad or cget_chkblank(); + my $fh = $ucb->{att_fh}; + if ($fh) { # mounted and open ? + if (-w $fh) { # file writable ? + $ucb->{att_wpro} = 0; # remove write protect + &{$ctl->{usethdl}}($ucb); # setup unit registers + } else { + printf "pi_rri($curmode)-E: file %s (for %s) is write protected\n", + $ucb->{att_file}, $ucb->{unitname}; + return; + } + } else { + printf "pi_rri($curmode)-E: no file attached for %s\n", + $ucb->{unitname}; + return; + } + + } else { # normal (non -w) handling + my $opt_r = cget_opt("-r"); + my $filename = cget_file(); + return if $cmd_bad or cget_chkblank(); + + if (not -e $filename) { + print "pi_rri($curmode)-E: file $filename not found\n"; + return; + } + if (not -r $filename) { + print "pi_rri($curmode)-E: file $filename is not readable\n"; + return; + } + + my $wpro = $opt_r; + if (! $wpro && ! -w $filename) { + print "pi_rri($curmode)-I: file $filename is write protected\n"; + $wpro = 1; + } + + my $filesize = -s $filename; + + if (defined $ctl->{volsize}) { + if ($filesize < $ctl->{volsize}) { + printf "pi_rri($curmode)-W: dsk file too small, %s requires %d". + " file $filename has %d bytes\n", + $ucb->{unitname}, $ctl->{volsize}, $filesize; + } + } + + my $fh = new FileHandle; + sysopen ($fh, $filename, $wpro ? O_RDONLY : O_RDWR) + or die "Unexpected sysopen error"; + + $ucb->{att_ok} = 1; + $ucb->{att_file} = $filename; + $ucb->{att_nbyt} = $filesize; + $ucb->{att_wpro} = $wpro; + $ucb->{att_fh} = $fh; + + $ucb->{att_nblk} = int ($ucb->{att_nbyt}/512); + if ($ucb->{att_nbyt}%512 != 0) { + print "pi_rri($curmode)-I: size $filename not multiple of 512\n"; + } + &{$ctl->{usethdl}}($ucb); # setup unit registers + } + } +} + +#------------------------------------------------------------------------------- + +sub serv11_attdet_ronly { # generic in only att/det handler + my ($det,$ucb) = @_; + my $ctl = $serv11_ctltbl{$ucb->{ctlname}}; + + if ($det) { # detach handling + serv11_detach_gen($ucb); + + } else { # attach handling + my $filename = cget_file(); + return if $cmd_bad or cget_chkblank(); + + if (not -e $filename) { + print "pi_rri($curmode)-E: file $filename not found\n"; + return; + } + if (not -r $filename) { + print "pi_rri($curmode)-E: file $filename is not readable\n"; + return; + } + + my $fh = new FileHandle; + my $rc = $fh->open("<$filename"); + if (not $rc) { + print "pi_rri($curmode)-E: failed to open file $filename\n"; + return; + } + + $ucb->{att_ok} = 1; + $ucb->{att_file} = $filename; + $ucb->{att_fh} = $fh; + delete $ucb->{att_eof}; + + &{$ctl->{usethdl}}($ucb); # setup unit registers + } +} + +#------------------------------------------------------------------------------- + +sub serv11_attdet_wonly { # generic out only att/det handler + my ($det,$ucb) = @_; + my $ctl = $serv11_ctltbl{$ucb->{ctlname}}; + + if ($det) { # detach handling + serv11_detach_gen($ucb); + + } else { # attach handling + my $filename = cget_file(); + return if $cmd_bad or cget_chkblank(); + + if (not -e $filename) { + print STDERR "pi_rri($curmode)-I: file $filename will be created\n"; + } elsif (not -w $filename) { + print STDERR "pi_rri($curmode)-E: file $filename is not writeable\n"; + return; + } + + my $fh = new FileHandle; + my $rc = $fh->open(">$filename"); + if (not $rc) { + print STDERR "pi_rri($curmode)-E: failed to open file $filename\n"; + return; + } + + autoflush $fh; + + $ucb->{att_ok} = 1; + $ucb->{att_file} = $filename; + $ucb->{att_fh} = $fh; + delete $ucb->{att_eof}; + + &{$ctl->{usethdl}}($ucb); # setup unit registers + } +} + +#------------------------------------------------------------------------------- + +sub serv11_attdet_term { # generic term att/det handler + my ($det,$ucb) = @_; + my $ctl = $serv11_ctltbl{$ucb->{ctlname}}; + + if ($det) { # detach handling + my $port_str = $ucb->{att_port}; + my $teldsc = $telnettbl{$port_str}; + close $teldsc->{fh_data} if defined $teldsc->{fh_data}; + close $teldsc->{fh_port} if defined $teldsc->{fh_port}; + delete $telnettbl{$port_str}; + delete $ucb->{att_port}; + $ucb->{att_ok} = 0; + $serv11_fds_update = 1; # request update of select mask + + } else { # attach handling + my $port = cget_gdat(16, 10); + return if $cmd_bad or cget_chkblank(); + my $port_str = sprintf("%6.6d", $port); + if (exists $telnettbl{$port_str}) { + printf STDERR "pi_rri($curmode)-E: port %d already attached\n", $port; + return; + } + my $fh_port = new FileHandle; + my $proto = getprotobyname('tcp'); + if (not socket($fh_port, PF_INET, SOCK_STREAM, $proto)) { + printf STDERR "pi_rri($curmode)-E: error in socket(): $!\n"; + return; + } + if (not setsockopt($fh_port, SOL_SOCKET, SO_REUSEADDR, 1)) { + printf STDERR "pi_rri($curmode)-E: error in setsocketopt(): $!\n"; + return; + } + + my $host = pack('C4', 0,0,0,0); + my $addr = pack('S n a4 x8', 2, $port, $host); + if (not bind($fh_port, $addr)) { + printf STDERR "pi_rri($curmode)-E: error in bind(): $!\n"; + return; + } + + if (not listen($fh_port, 1)) { + printf STDERR "pi_rri($curmode)-E: error in listen(): $!\n"; + return; + } + + $telnettbl{$port_str} = {}; + $telnettbl{$port_str}->{port} = $port; + $telnettbl{$port_str}->{state} = TELNET_STATE_LISTEN; + $telnettbl{$port_str}->{fh_port} = $fh_port; + $telnettbl{$port_str}->{ucb} = $ucb; + + $ucb->{att_ok} = 1; + $ucb->{att_port} = $port_str; + + $serv11_fds_update = 1; # request update of select mask + + } + +} + +#------------------------------------------------------------------------------- + +sub serv11_probe_cpu { # cpu: probe handler + my ($ctl) = @_; + + serv11_probe_gen($ctl); + return unless $ctl->{probe_ok}; + + my $reglist = $ctl->{reglist}; + my $partbl = $ctl->{partbl}; + my $text = ""; + + my $exadep = \&serv11_exadep_cpu; + + push @{$reglist}, {name => "r0", hdl => \&serv11_exadep_cpu}; + push @{$reglist}, {name => "r1", hdl => \&serv11_exadep_cpu}; + push @{$reglist}, {name => "r2", hdl => \&serv11_exadep_cpu}; + push @{$reglist}, {name => "r3", hdl => \&serv11_exadep_cpu}; + push @{$reglist}, {name => "r4", hdl => \&serv11_exadep_cpu}; + push @{$reglist}, {name => "r5", hdl => \&serv11_exadep_cpu}; + push @{$reglist}, {name => "sp", hdl => \&serv11_exadep_cpu}; + push @{$reglist}, {name => "pc", hdl => \&serv11_exadep_cpu}; + push @{$reglist}, {name => "psw", hdl => \&serv11_exadep_cpu}; + + push @{$reglist}, {name => "stklim", addr => CPU_STKLIM}; + push @{$reglist}, {name => "pirq" , addr => CPU_PIRQ}; + push @{$reglist}, {name => "mbrk" , addr => CPU_MBRK}; + push @{$reglist}, {name => "cpuerr", addr => CPU_CPUERR}; + push @{$reglist}, {name => "hisize", addr => CPU_HISIZE}; + push @{$reglist}, {name => "losize", addr => CPU_LOSIZE}; + + my ($ival,$rval) = serv11_exec_probe(CPU_SDREG, "ir"); + if (defined $ival && defined $rval) { + push @{$reglist}, {name => "sr", addr => CPU_SDREG, attr => REGATTR_RBWR}; + push @{$reglist}, {name => "dr", addr => CPU_SDREG, attr => REGATTR_RBRD}; + } + + push @{$reglist}, {name => "mmr0" , addr => CPU_MMR0}; + push @{$reglist}, {name => "mmr1" , addr => CPU_MMR1}; + push @{$reglist}, {name => "mmr2" , addr => CPU_MMR2}; + push @{$reglist}, {name => "mmr3" , addr => CPU_MMR3}; + + my @rval; + serv11_rri_wreg("wal", PDPCP_ADDR_AL, CPU_LOSIZE); # i/o page in 16 bit mode + serv11_rri_rreg("rm", PDPCP_ADDR_MEM); + my $rc = serv11_rri_exec(\@rval); + my $memsize = ($rval[0]+1)<<6; # memsize in bytes + $ctl->{memsize} = $memsize; + + $text .= ($text)?";":"" . sprintf("mem=%dkb",$memsize/1024.); + + $ctl->{probe_text} = $text; + +} + +#------------------------------------------------------------------------------- + +sub serv11_attn_cpu { # cpu: attention handler + my ($ctl,$force) = @_; + return if $force; + print "CPU halted\n"; + $serv11_active = 0; + serv11_cexec_shoreg(1); +} + +#------------------------------------------------------------------------------- + +sub serv11_exadep_cpu { # cpu: exa/dep handler + my ($dep,$dsc,$val) = @_; + my $name = $dsc->{name}; + my $rrireg; + + $name =~ s/^sp$/r6/; + $name =~ s/^pc$/r7/; + + if ($dep) { + if ($name =~ /^r([0-7])$/) { + $rrireg = PDPCP_ADDR_R0 + int $1; + } elsif ($name eq "psw") { + $rrireg = PDPCP_ADDR_PSW; + } else { + print_fatal("serv11_exadep_cpu() called with bad name '$name'"); + } + my @rval; + serv11_rri_wreg("r$name", $rrireg, $val); + my $rc = serv11_rri_exec(\@rval); + return; + + } else { + if ($name =~ /^r([0-7])$/) { + $rrireg = PDPCP_ADDR_R0 + int $1; + } elsif ($name eq "psw") { + $rrireg = PDPCP_ADDR_PSW; + } else { + print_fatal("serv11_exadep_cpu() called with bad name '$name'"); + } + my @rval; + serv11_rri_rreg("r$name", $rrireg); + my $rc = serv11_rri_exec(\@rval); + return $rval[0]; + } + +} + +#------------------------------------------------------------------------------- + +sub serv11_ichr_dl11 { + my ($ucb,$dref) = @_; + my $ctl = $serv11_ctltbl{$ucb->{ctlname}}; + my @rval; + my $rc; + + my $que_old = scalar( @{$ucb->{rcvque}} ); + push @{$ucb->{rcvque}}, @$dref; + my $que_new = scalar( @{$ucb->{rcvque}} ); + + if ($que_old == 0 && $que_new > 0) { + serv11_rri_ibrb($ctl); + serv11_rri_ribr("RCSR", $ctl, DL11_RCSR); + $rc = serv11_rri_exec(\@rval); + if (($rval[0] & DL11_RCSR_M_RDONE) == 0) { # RBUF not full + my $data = shift @{$ucb->{rcvque}}; + serv11_rri_wibr("RBUF", $ctl, DL11_RBUF, $data & 0377); + $rc = serv11_rri_exec(\@rval); + } + } +} + +#------------------------------------------------------------------------------- + +sub serv11_attn_dl11 { + my ($ctl,$force) = @_; + my $ucb = $serv11_unittbl{$ctl->{units}[0]}; + my @rval; + my $rc; + my $nxbuf = $ctl->{nxbuf_min}; + my $nxbuf_val = 0; + + $nxbuf = $ctl->{nxbuf} if defined $ctl->{nxbuf}; + + serv11_rri_ibrb($ctl); + for (my $i=0; $i<$nxbuf; $i++) { + serv11_rri_ribr("XBUF", $ctl, DL11_XBUF); + } + + # select(undef, undef, undef, 5.0); # ! hack + # printf $fh_log "HACK -- wait on DL11 attn\n"; # ! hack + + $rc = serv11_rri_exec(\@rval); + + my $rrdy; + for (my $i=0; $i<$nxbuf; $i++) { + my $ochr = $rval[$i] & DL11_XBUF_M_XBUF; + my $xval = $rval[$i] & DL11_XBUF_M_XVAL; + $rrdy = $rval[$i] & DL11_XBUF_M_RRDY; + $ochr = $ochr & 0177 if $ucb->{rcv7bit}; # drop parity bit + my $chr = chr($ochr); + my $str = ($ochr>=040 && $ochr<0177) ? "$chr" : sprintf "\\%3.3o",$ochr; + if (exists $opts{tserv} && $ctl->{trace} && + ($xval || not $force)) { + printf $fh_log + "serv -- DL11.%s xbuf=%6.6o xval=%s rrdy=%s rcvq=%3d sndq=%3d", + $ctl->{ctlname}, $rval[$i], + ($xval ? "y" : "n"), ($rrdy ? "y" : "n"), + scalar( @{$ucb->{rcvque}} ), scalar( @{$ucb->{sndque}} ); + printf $fh_log " char=\"%s\"", $str if $xval; + print $fh_log "\n"; + } + + if ($xval) { + $nxbuf_val += 1; + my $sndqueref = $ucb->{sndque}; + my $ochr_last = 0; + $ochr_last = $$sndqueref[-1] if scalar(@$sndqueref) > 0; + + push @{$ucb->{sndque}}, $ochr; + + if ($ucb->{att_ok}) { + telnet_writehdl($ucb); + } else { + if ($ctl->{ctlname} eq "TTA") { # for console + while (scalar( @{$ucb->{sndque}} )) { + my $byte = shift @{$ucb->{sndque}}; + my $str = ""; + if ($byte>=040 && $byte<0177) { + $str = chr($byte); + } elsif ($byte==011) { + $str = "\t"; + } elsif ($byte==012) { + $str = "\n"; + } elsif ($byte==015) { + $str = "\r"; + } else { + $str = sprintf "<%3.3o>", $byte if $byte!=000; + } + print $str; + } + } + + if ($ucb->{logfile}) { + my $fh = $ucb->{logfh}; + if (not defined $ucb->{logfh}) { + my $logfile = $ucb->{logfile}; + my $rc; + $fh = $ucb->{logfh} = new FileHandle; + $rc = $ucb->{logfh}->open(">$logfile"); + if (not $rc) { + printf STDERR "pi_rri-E: failed to open $logfile for write\n"; + $fh = undef; + } else { + autoflush $fh; + } + } + print $fh $str if $fh; + } + } + +# if ($ochr_last == 015 && $ochr == 012) { +# while (scalar( @{$ucb->{sndque}} )) { +# my $byte = shift @{$ucb->{sndque}}; +# my $chr = chr($byte); +# if ($byte>=040 && $byte <=177) { +# print $chr +# } else { +# if ($byte != 000 && $byte != 012 && $byte != 015) { +# printf "<%3.3o>", $byte +# } +# } +# } +# print "\n"; +# } + } + } + + if ($rrdy && scalar( @{$ucb->{rcvque}} ) ) { + my $data = shift @{$ucb->{rcvque}}; + serv11_rri_wibr("RBUF", $ctl, DL11_RBUF, $data & 0377); + $rc = serv11_rri_exec(\@rval); + } + + $ctl->{nxbuf} = next_nxbuf($ctl, $nxbuf, $nxbuf_val); +} + +#------------------------------------------------------------------------------- + +sub serv11_uset_lp11 { + my ($ucb) = @_; + my @rval; + + my $lpcs = ($ucb->{att_ok}) ? 0 : LP11_CSR_M_ERR; + + serv11_rri_uset($ucb, "LPCS", LP11_CSR, $lpcs); + + my $rc = serv11_rri_exec(\@rval); +} + +#------------------------------------------------------------------------------- + +sub serv11_attn_lp11 { + my ($ctl,$force) = @_; + my $ucb = $serv11_unittbl{$ctl->{units}[0]}; + my @rval; + my $rc; + my $nxbuf = $ctl->{nxbuf_min}; + my $nxbuf_val = 0; + + $nxbuf = $ctl->{nxbuf} if defined $ctl->{nxbuf}; + + serv11_rri_ibrb($ctl); + for (my $i=0; $i<$nxbuf; $i++) { + serv11_rri_ribr("LPBU", $ctl, LP11_BUF); + } + + $rc = serv11_rri_exec(\@rval); + + for (my $i=0; $i<$nxbuf; $i++) { + my $ochr = $rval[$i] & LP11_BUF_M_BUF; + my $oval = $rval[$i] & LP11_BUF_M_VAL; + my $chr = chr($ochr); + my $str = "$chr"; + if (exists $opts{tserv} && $ctl->{trace} && + ($oval || not $force)) { + printf $fh_log + "serv -- LP11 buf=%6.6o val=%s ", + $rval[$i], ($oval ? "y" : "n"); + printf $fh_log " char=\"%s\"", $str if $oval; + print $fh_log "\n"; + } + + if ($oval) { + $nxbuf_val += 1; + my $fh = $ucb->{att_fh}; + if ($fh) { + print $fh $str; + } else { + printf STDERR "pi_rri($curmode)-E: spurious output '%s' for %s\n", + $str, $ucb->{unitname}; + } + } + } + + $ctl->{nxbuf} = next_nxbuf($ctl, $nxbuf, $nxbuf_val); +} + +#------------------------------------------------------------------------------- + +sub serv11_uset_pc11 { + my ($ucb) = @_; + my @rval; + my $text; + my $addr; + my $data; + + if ($ucb->{unitname} eq "PTR") { # if reader + $text = "PRCS"; + $addr = PC11_RCSR; + $data = ($ucb->{att_ok}) ? 0 : PC11_RCSR_M_ERR; + } else { # if puncher + $text = "PPCS"; + $addr = PC11_PCSR; + $data = ($ucb->{att_ok}) ? 0 : PC11_PCSR_M_ERR; + } + + serv11_rri_uset($ucb, $text, $addr, $data); + + my $rc = serv11_rri_exec(\@rval); +} + +#------------------------------------------------------------------------------- + +sub serv11_attdet_pc11 { # pc11 att/det handler + my ($det,$ucb) = @_; + + if ($ucb->{unitname} eq "PTR") { # if reader + serv11_attdet_ronly($det, $ucb); # use read-only file + } else { # if puncher + serv11_attdet_wonly($det, $ucb); # use write-only file + } + +} + +#------------------------------------------------------------------------------- + +sub serv11_attn_pc11 { + my ($ctl,$force) = @_; + + my $ucb_ptr = $serv11_unittbl{$ctl->{units}[0]}; + my $ucb_ptp = $serv11_unittbl{$ctl->{units}[1]}; + my @rval; + my $rc; + my $nxbuf = $ctl->{nxbuf_min}; + my $nxbuf_val = 0; + + $nxbuf = $ctl->{nxbuf} if defined $ctl->{nxbuf}; + + serv11_rri_ibrb($ctl); + for (my $i=0; $i<$nxbuf; $i++) { + serv11_rri_ribr("PPBUF", $ctl, PC11_PBUF); + } + + $rc = serv11_rri_exec(\@rval); + + my $rrdy; + for (my $i=0; $i<$nxbuf; $i++) { + my $ochr = $rval[$i] & PC11_PBUF_M_PBUF; + my $pval = $rval[$i] & PC11_PBUF_M_PVAL; + $rrdy = $rval[$i] & PC11_PBUF_M_RBUSY; + + if (exists $opts{tserv} && $ctl->{trace} && + ($pval || not $force)) { + printf $fh_log + "serv -- PC11 pbuf=%6.6o pval=%s rrdy=%s \n", + $rval[$i], ($pval ? "y" : "n"), ($rrdy ? "y" : "n"); + } + + if ($pval) { + $nxbuf_val += 1; + my $fh = $ucb_ptp->{att_fh}; + if ($fh) { + print $fh chr($ochr); + } else { + printf STDERR "pi_rri($curmode)-E: spurious output '%3.3o' for %s\n", + $ochr, $ucb_ptp->{unitname}; + } + } + } + + if ($rrdy) { + my $fh = $ucb_ptr->{att_fh}; + if ($fh && (not $ucb_ptr->{att_eof}) ) { + my $char = getc($fh); + if (defined $char) { + serv11_rri_wibr("PRBUF", $ctl, PC11_RBUF, ord($char) & 0377); + $rc = serv11_rri_exec(\@rval); + } else { + serv11_rri_uset($ucb_ptr, "PRCS", PC11_RCSR, PC11_RCSR_M_ERR); + $rc = serv11_rri_exec(\@rval); + $ucb_ptr->{att_eof} = 1; + } + } else { + printf STDERR "pi_rri($curmode)-E: spurious reader busy for %s\n", + $ucb_ptr->{unitname}; + } + } + + $ctl->{nxbuf} = next_nxbuf($ctl, $nxbuf, $nxbuf_val); + +} + +#------------------------------------------------------------------------------- + +sub serv11_uset_rk11 { + my ($ucb) = @_; + my @rval; + + my $rkds = 0; + + $rkds = $ucb->{ctlunit}<<(RKDS_V_ID); + if ($ucb->{att_ok}) { # drive available + $rkds |= RKDS_M_HDEN; # always high density + $rkds |= RKDS_M_SOK; # always sector counter OK ?FIXME? + $rkds |= RKDS_M_DRY; # drive available + $rkds |= RKDS_M_ADRY; # access available + $rkds |= RKDS_M_WPS if $ucb->{att_wpro}; # in case write protected + } + $ucb->{rkds} = $rkds; + + serv11_rri_uset($ucb, "RKDS", RK11_RKDS, $rkds); + my $rc = serv11_rri_exec(\@rval); +} + +#------------------------------------------------------------------------------- +# geometry: c=203;h=2;s=12 ==> 4872 blocks ==> 2 494 464 bytes +# +# several error conditions are only approximately handled: +# OVR: when detected, no transfer done (should trim size) + +sub serv11_attn_rk11 { + my ($ctl,$force) = @_; + my @rval; + my $blksize = $ctl->{blksize}; + + serv11_rri_ibrb($ctl); + serv11_rri_ribr("RKWC", $ctl, RK11_RKWC); + serv11_rri_ribr("RKBA", $ctl, RK11_RKBA); + serv11_rri_ribr("RKDA", $ctl, RK11_RKDA); + serv11_rri_ribr("RKMR", $ctl, RK11_RKMR); # read to monitor CRDONE + serv11_rri_ribr("RKCS", $ctl, RK11_RKCS); + + my $rc = serv11_rri_exec(\@rval); + + my $rkwc = $rval[0]; + my $rkba = $rval[1]; + my $rkda = $rval[2]; + my $rkmr = $rval[3]; + my $rkcs = $rval[4]; + + my $se = $rkda & RKDA_B_SC; + my $hd = ($rkda>>RKDA_V_SUR ) & RKDA_B_SUR; + my $cy = ($rkda>>RKDA_V_CYL ) & RKDA_B_CYL; + my $dr = ($rkda>>RKDA_V_DRSEL) & RKDA_B_DRSEL; + + my $go = ($rkcs & RKCS_M_GO) != 0; + my $fu = ($rkcs>>RKCS_V_FUNC) & RKCS_B_FUNC; + my $mex = ($rkcs>>RKCS_V_MEX ) & RKCS_B_MEX; + + my $nwrd = ((~$rkwc) & 0xffff) + 1; # transfer size in words + my $nbyt = 2*$nwrd; # transfer size in bytes + my $nblk = int (($nbyt+$blksize-1)/$blksize);# transfer size in blocks + + my $addr = $mex<<16 | $rkba; # 18 bit memory address + my $lbn = $se + RK11_NUMSE*$hd + RK11_NUMSE*RK11_NUMHD*$cy; + + my $ucb = $serv11_unittbl{$ctl->{units}[$dr]}; + + my $rkds = $ucb->{rkds}; + if (not defined $rkds) { + printf $fh_log + "serv -- RK11 ERROR: no rri device init, assume ds=0 for drive %d\n", $dr; + $rkds = $ucb->{rkds} = $rkds = 0; + } + + if ($go == 0) { # quit here if no go bit set + if (exists $opts{tserv} && $ctl->{trace}) { + if (not $force) { + printf $fh_log "serv -- RK11 cs=%6.6o go=0, spurious attn\n", $rkcs; + } + } + return; + } + + my $rker = 0; + my $msg = ""; + + if ($fu != RKCS_CRESET && # function not control reset + (not $ucb->{att_ok})) { # and drive not attached + $rker = RKER_M_NXD; # --> abort with NXD error + serv11_rri_wibr("RKER", $ctl, RK11_RKER, $rker); + if ($fu == RKCS_SEEK || $fu == RKCS_DRESET) { + serv11_rri_wibr("RKMR", $ctl, RK11_RKMR, 1<<(RKMR_V_SBCLR) | 1<<($dr)); + } + serv11_rri_wibr("RKMR", $ctl, RK11_RKMR, 1<<(RKMR_V_FDONE)); + serv11_attn_rk11_logerr($ctl, $rker); + + } elsif ($fu != RKCS_WRITE && # function neither read + $fu != RKCS_READ && # nor write + ($rkcs & RKCS_M_FMT)) { # and FMT set + $rker = RKER_M_PGE; # --> abort with PGE error + serv11_rri_wibr("RKER", $ctl, RK11_RKER, $rker); + if ($fu == RKCS_SEEK || $fu == RKCS_DRESET) { + serv11_rri_wibr("RKMR", $ctl, RK11_RKMR, 1<<(RKMR_V_SBCLR) | 1<<($dr)); + } + serv11_rri_wibr("RKMR", $ctl, RK11_RKMR, 1<<(RKMR_V_FDONE)); + serv11_attn_rk11_logerr($ctl, $rker); + + } else { + + if ($fu == RKCS_CRESET) { # Control reset ------------------- + serv11_rri_wibr("RKMR", $ctl, RK11_RKMR, 1<<(RKMR_V_CRESET)); + + } elsif ($fu == RKCS_WRITE) { # Write --------------------------- + # Note: WRITE+FMT is just like WRITE + $rker |= RKER_M_NXS if $se >= RK11_NUMSE; + $rker |= RKER_M_NXC if $cy >= RK11_NUMCY; + $rker |= RKER_M_WLO if $ucb->{att_wpro}; + $rker |= RKER_M_DRE if $rkcs & RKCS_M_IBA; # not yet supported ! FIXME ! + $rker |= RKER_M_DRE if $rkcs & RKCS_M_RWA; # will never be supported + if ($rker) { + serv11_rri_wibr("RKER", $ctl, RK11_RKER, $rker); + serv11_rri_wibr("RKMR", $ctl, RK11_RKMR, 1<<(RKMR_V_FDONE)); + serv11_attn_rk11_logerr($ctl, $rker); + } else { + my $icb = {rdmahdl => \&serv11_rdma_rk11, + func => "write", + ctl => $ctl, + ucb => $ucb, + lbn => $lbn, + nblk => $nblk, + nwrd => $nwrd, + addr => $addr, + nwdone => 0, + rkcs => $rkcs, # later needed for MEX update + rkda => $rkda # later needed in RKDA update + }; + push @serv11_icbque, $icb; + } + + } elsif ($fu == RKCS_READ) { # Read ---------------------------- + $rker |= RKER_M_NXS if ($se >= RK11_NUMSE); + $rker |= RKER_M_NXC if ($cy >= RK11_NUMCY); + $rker |= RKER_M_DRE if $rkcs & RKCS_M_IBA; # not yet supported ! FIXME ! + $rker |= RKER_M_DRE if $rkcs & RKCS_M_RWA; # will never be supported + if ($rker) { + serv11_rri_wibr("RKER", $ctl, RK11_RKER, $rker); + serv11_rri_wibr("RKMR", $ctl, RK11_RKMR, 1<<(RKMR_V_FDONE)); + serv11_attn_rk11_logerr($ctl, $rker); + } else { + + if ($rkcs & RKCS_M_FMT) { + my $icb = {rdmahdl => \&serv11_rdma_rk11, + func => "rdfmt", + ctl => $ctl, + ucb => $ucb, + lbn => $lbn, + nblk => $nwrd, # #blocks == #words for RD FMT !! + nwrd => $nwrd, + addr => $addr, + nwdone => 0, + rkcs => $rkcs, # later needed for MEX update + rkda => $rkda # later needed in RKDA update + }; + push @serv11_icbque, $icb; + } else { + my $icb = {rdmahdl => \&serv11_rdma_rk11, + func => "read", + ctl => $ctl, + ucb => $ucb, + lbn => $lbn, + nblk => $nblk, + nwrd => $nwrd, + addr => $addr, + nwdone => 0, + rkcs => $rkcs, # later needed for MEX update + rkda => $rkda # later needed in RKDA update + }; + push @serv11_icbque, $icb; + } + } + + } elsif ($fu == RKCS_WCHK) { # Write Check --------------------- + $rker |= RKER_M_NXS if $se >= RK11_NUMSE; + $rker |= RKER_M_NXC if $cy >= RK11_NUMCY; + $rker |= RKER_M_DRE if $rkcs & RKCS_M_IBA; # not yet supported ! FIXME ! + $rker |= RKER_M_DRE if $rkcs & RKCS_M_RWA; # will never be supported + if ($rker) { + serv11_rri_wibr("RKER", $ctl, RK11_RKER, $rker); + serv11_rri_wibr("RKMR", $ctl, RK11_RKMR, 1<<(RKMR_V_FDONE)); + serv11_attn_rk11_logerr($ctl, $rker); + } else { + my $icb = {rdmahdl => \&serv11_rdma_rk11, + func => "wrcheck", + ctl => $ctl, + ucb => $ucb, + lbn => $lbn, + nblk => $nblk, + nwrd => $nwrd, + addr => $addr, + nwdone => 0, + rkcs => $rkcs, # later needed for MEX update + rkda => $rkda # later needed in RKDA update + }; + push @serv11_icbque, $icb; + } + + } elsif ($fu == RKCS_SEEK) { # Seek ---------------------------- + $rker |= RKER_M_NXS if ($se >= RK11_NUMSE); + $rker |= RKER_M_NXC if ($cy >= RK11_NUMCY); + if ($rker) { + serv11_rri_wibr("RKER", $ctl, RK11_RKER, $rker); + serv11_rri_wibr("RKMR", $ctl, RK11_RKMR, 1<<(RKMR_V_SBCLR) | 1<<($dr)); + serv11_rri_wibr("RKMR", $ctl, RK11_RKMR, 1<<(RKMR_V_FDONE)); + serv11_attn_rk11_logerr($ctl, $rker); + } else { + serv11_rri_wibr("RKMR", $ctl, RK11_RKMR, 1<<(RKMR_V_FDONE)); + $rkds &= ~(RKDS_B_SC); # replace current sector number + $rkds |= $se; + $ucb->{rkds} = $rkds; + serv11_rri_wibr("RKDS", $ctl, RK11_RKDS, $rkds); + serv11_rri_wibr("RKMR", $ctl, RK11_RKMR, 1<<($dr)); # issue seek done + } + + } elsif ($fu == RKCS_RCHK) { # Read Check ---------------------- + $rker |= RKER_M_NXS if $se >= RK11_NUMSE; + $rker |= RKER_M_NXC if $cy >= RK11_NUMCY; + $rker |= RKER_M_DRE if $rkcs & RKCS_M_IBA; # not yet supported ! FIXME ! + $rker |= RKER_M_DRE if $rkcs & RKCS_M_RWA; # will never be supported + if ($rker) { + serv11_rri_wibr("RKER", $ctl, RK11_RKER, $rker); + serv11_rri_wibr("RKMR", $ctl, RK11_RKMR, 1<<(RKMR_V_FDONE)); + serv11_attn_rk11_logerr($ctl, $rker); + } else { + my $icb = {rdmahdl => \&serv11_rdma_rk11, + func => "rdcheck", + ctl => $ctl, + ucb => $ucb, + lbn => $lbn, + nblk => $nblk, + nwrd => $nwrd, + addr => $addr, + nwdone => 0, + rkcs => $rkcs, # later needed for MEX update + rkda => $rkda # later needed in RKDA update + }; + push @serv11_icbque, $icb; + } + + } elsif ($fu == RKCS_DRESET) { # Drive Reset --------------------- + serv11_rri_wibr("RKMR", $ctl, RK11_RKMR, 1<<(RKMR_V_FDONE)); + serv11_rri_wibr("RKMR", $ctl, RK11_RKMR, 1<<($dr)); # issue seek done + + } elsif ($fu == RKCS_WLOCK) { # Write Lock ---------------------- + $ucb->{rkds} |= RKDS_M_WPS; # set RKDS write protect flag + $ucb->{att_wpro} = 1; # set UCB write protect flag + serv11_rri_wibr("RKDS", $ctl, RK11_RKDS, $ucb->{rkds}); + serv11_rri_wibr("RKMR", $ctl, RK11_RKMR, 1<<(RKMR_V_FDONE)); + } + + } + + if (exists $opts{tserv} && $ctl->{trace}) { + printf $fh_log "serv -- RK11 cs=%6.6o da=%6.6o wc=%6.6o", + $rkcs, $rkda, $rkwc; + printf $fh_log " ad=%6.6o", $addr; + printf $fh_log " fu=%d dchs=%d,%3d,%d,%2d", $fu, $dr, $cy, $hd, $se; + printf $fh_log " lbn=%4d nw,nb=%5d,%2d", $lbn, $nwrd, $nblk; + print $fh_log "\n"; + } + + $rc = serv11_rri_exec(\@rval); + +} + +#------------------------------------------------------------------------------- + +sub serv11_attn_rk11_logerr { + my ($ctl,$rker) = @_; + if (exists $opts{tserv}) { + printf $fh_log "serv -- RK11 er=%6.6o ERROR ABORT\n", $rker; + } +} + +#------------------------------------------------------------------------------- + +sub serv11_rdma_rk11 { + my ($icb) = @_; + my $ctl = $icb->{ctl}; + my $ucb = $icb->{ucb}; + my $addr = $icb->{addr}; + my $blksize = $ctl->{blksize}; + my @rval; + my $rc = 1; # default ok, make code below shorter FIXME + my $rker = 0; + +# printf "+++x1 func=%5s addr=%6.6o nblk=%2d nwdone=%3d\n", +# $icb->{func}, $addr, $icb->{nblk}, $icb->{nwdone}; + + if ($icb->{func} eq "read") { # --- read function -------------- + if ($icb->{nwdone} == 0) { # new block ? + $rker |= RKER_M_OVR if $icb->{lbn} >= RK11_NUMBL; + $rc = serv11_icb_disk_read($icb) if not $rker; + $rker |= RKER_M_CSE if not $rc; # forward disk I/O error + } + + if (not $rker) { + my $nwdma = int($blksize/2) - $icb->{nwdone}; + $nwdma = $icb->{nwrd} if $nwdma > $icb->{nwrd}; + $nwdma = $serv11_rdma_chunk if $nwdma > $serv11_rdma_chunk; + my $beg = $icb->{nwdone}; + my $end = $beg + $nwdma - 1; + my $buf = $icb->{buf}; + + serv11_rri_lalh($icb->{addr}, 3); + serv11_rri_wblk($nwdma, [ @$buf[$beg..$end] ]); + $rc = serv11_rri_exec(\@rval); # FIXME: handle dma I/O error + $stat_tab{rdisk} += 2*$nwdma; + + $icb->{nwdone} += $nwdma; + $icb->{nwrd} -= $nwdma; + $icb->{addr} += 2*$nwdma; + + if ((not $rker) && # no error and + ($icb->{nwdone} == int($blksize/2) || # block done or + $icb->{nwrd} == 0) ) { # all done + $icb->{nwdone} = 0; + $icb->{lbn} += 1; + $icb->{nblk} -= 1; + } + } + + if ((not $rker) && $icb->{nwrd}) { # if no error found and not done yet + push @serv11_icbque, $icb; # requeue + return; + } + + } elsif ($icb->{func} eq "rdfmt") { # --- read format function ------- + $rker |= RKER_M_OVR if $icb->{lbn} >= RK11_NUMBL; + + if (not $rker) { + my $cy = $icb->{lbn}/(RK11_NUMHD*RK11_NUMSE); + my $da = $cy<<(RKDA_V_CYL); + my @buf = ($da); + + serv11_rri_lalh($icb->{addr}, 3); + serv11_rri_wblk(1, [ @buf ]); + $rc = serv11_rri_exec(\@rval); # FIXME: handle dma I/O error + $stat_tab{rdisk} += 2; + + $icb->{nwrd} -= 1; + $icb->{addr} += 2; + $icb->{lbn} += 1; + $icb->{nblk} -= 1; + } + + if ((not $rker) && $icb->{nwrd}) { # if no error found and not done yet + push @serv11_icbque, $icb; # requeue + return; + } + + } elsif ($icb->{func} eq "write") { # --- write function ------------- + $icb->{buf} = [] if $icb->{nwdone} == 0; + my $nwdma = int($blksize/2) - $icb->{nwdone}; + $nwdma = $icb->{nwrd} if $nwdma > $icb->{nwrd}; + $nwdma = $serv11_rdma_chunk if $nwdma > $serv11_rdma_chunk; + + serv11_rri_lalh($icb->{addr}, 3); + serv11_rri_rblk($nwdma); + $rc = serv11_rri_exec(\@rval); # FIXME: handle dma I/O error + $stat_tab{wdisk} += 2*$nwdma; + + $icb->{nwdone} += $nwdma; + $icb->{nwrd} -= $nwdma; + $icb->{addr} += 2*$nwdma; + + push @{$icb->{buf}}, @{$rval[0]}; + + if ((not $rker) && # no error and + ($icb->{nwdone} == int($blksize/2) || # block done or + $icb->{nwrd} == 0) ) { # all done + $rc = serv11_icb_disk_write($icb); # FIXME: handle file I/O error + $icb->{nwdone} = 0; + $icb->{lbn} += 1; + $icb->{nblk} -= 1; + $rker |= RKER_M_OVR if $icb->{nblk} && $icb->{lbn} >= RK11_NUMBL; + } + + if ((not $rker) && $icb->{nwrd}) { # if no error found and not done yet + push @serv11_icbque, $icb; # requeue + return; + } + + } elsif ($icb->{func} eq "wrcheck") { # --- write check function ------- + if ($icb->{nwdone} == 0) { # new block ? + $rker |= RKER_M_OVR if $icb->{lbn} >= RK11_NUMBL; + $rc = serv11_icb_disk_read($icb) if not $rker; + $rker |= RKER_M_CSE if not $rc; # forward disk I/O error + if ((not $rker)) { + $icb->{bufdsk} = $icb->{buf}; + $icb->{buf} = []; + } + } + + my $nwdma = int($blksize/2) - $icb->{nwdone}; + $nwdma = $icb->{nwrd} if $nwdma > $icb->{nwrd}; + $nwdma = $serv11_rdma_chunk if $nwdma > $serv11_rdma_chunk; + + serv11_rri_lalh($icb->{addr}, 3); + serv11_rri_rblk($nwdma); + $rc = serv11_rri_exec(\@rval); # FIXME: handle dma I/O error + $stat_tab{wdisk} += 2*$nwdma; + + $icb->{nwdone} += $nwdma; + $icb->{nwrd} -= $nwdma; + $icb->{addr} += 2*$nwdma; + + push @{$icb->{buf}}, @{$rval[0]}; + + if ((not $rker) && # no error and + ($icb->{nwdone} == int($blksize/2) || # block done or + $icb->{nwrd} == 0)) { # all done + my $bufdsk = $icb->{bufdsk}; + my $bufmem = $icb->{buf}; + my $nwmem = scalar(@{$bufmem}); + for (my $i=0; $i<$nwmem; $i++) { + $rker |= RKER_M_WCE if $bufdsk->[$i] != $bufmem->[$i]; + } + $icb->{nwdone} = 0; + $icb->{lbn} += 1; + $icb->{nblk} -= 1; + $rker |= RKER_M_OVR if $icb->{nblk} && $icb->{lbn} >= RK11_NUMBL; + } + + my $stop = ($rker & ~RKER_M_WCE) != 0 || # any hard error + (($rker & RKER_M_WCE) && $icb->{rkcs} & RKCS_M_SSE); + if ((not $stop) && $icb->{nwrd}) { # if no error found and not done yet + push @serv11_icbque, $icb; # requeue + return; + } + + } elsif ($icb->{func} eq "rdcheck") { # --- read check function -------- + $rker |= RKER_M_OVR if $icb->{lbn} >= RK11_NUMBL; + + if (not $rker) { + my $nwdma = int($blksize/2); + $nwdma = $icb->{nwrd} if $nwdma > $icb->{nwrd}; + + # Note: rkwc is decremented; rkba is untouched, no DMA transfer done + $icb->{nwrd} -= $nwdma; + $icb->{lbn} += 1; + $icb->{nblk} -= 1; + } + + if ((not $rker) && $icb->{nwrd}) { # if no error found and not done yet + push @serv11_icbque, $icb; # requeue + return; + } + + + } else { # --- unkown function ------------ + printf "pi_rri-E: unknown func=%s for serv11_rdma_rk11\n", $icb->{func}; + } + +# common handling for dma transfer completion + + my $ba = $icb->{addr} &0177776; # get lower 16 bits + my $mex = ($icb->{addr} >> 16) & 03; # get upper 2 bits + my $lbn = $icb->{lbn}; + my $nwrd = $icb->{nwrd}; + my $end = $lbn; + my $se = $end % RK11_NUMSE; + $end = int ($end / RK11_NUMSE); + my $hd = $end % RK11_NUMHD; + $end = int ($end / RK11_NUMHD); + my $cy = $end; + my $da = ($icb->{rkda} & RKDA_M_DRSEL) | + $se | $hd<<(RKDA_V_SUR) | $cy<<(RKDA_V_CYL); + my $cs = ($icb->{rkcs} & (~RKCS_M_MEX)) | ($mex << RKCS_V_MEX); + + serv11_rri_ibrb($ctl); + serv11_rri_wibr("RKER", $ctl, RK11_RKER, $rker) if $rker; + serv11_rri_wibr("RKWC", $ctl, RK11_RKWC, (-$nwrd)&0177777); + serv11_rri_wibr("RKBA", $ctl, RK11_RKBA, $ba); + serv11_rri_wibr("RKDA", $ctl, RK11_RKDA, $da); + serv11_rri_wibr("RKCS", $ctl, RK11_RKCS, $cs) if ($cs != $icb->{rkcs}); + serv11_rri_wibr("RKMR", $ctl, RK11_RKMR, 1<<(RKMR_V_FDONE)); + serv11_attn_rk11_logerr($ctl, $rker) if $rker; + $rc = serv11_rri_exec(\@rval); +} + +#------------------------------------------------------------------------------- +# read one disk block at lbn, returns $icb->{buf} + +sub serv11_icb_disk_read { # read one dsk file block + my ($icb) = @_; + my $ucb = $icb->{ucb}; + my $ctl = $icb->{ctl}; + my $fh = $ucb->{att_fh}; + my $fsize = $ucb->{att_nbyt}; + my $lbn = $icb->{lbn}; + my $blksize = $ctl->{blksize}; + my $seekpos = $lbn*$blksize; + my $sysbuf; + my $msg = ""; + my $rc = 0; + + $icb->{buf} = undef; + + if ($seekpos < $fsize) { + ($rc,$sysbuf) = file_seek_read($fh, $seekpos, $blksize); + $icb->{buf} = conv_buf2wlist($sysbuf); + } else { + $rc = $blksize; # setup good rc + $msg = " past eof zero buf"; + $icb->{buf} = []; + while ($blksize > 0) { + push @{$icb->{buf}}, 0; + $blksize -= 2; + } + } + + if (exists $opts{tserv} && $ctl->{trace}) { + printf $fh_log "disk -- %3s read lbn=%5d rc=%d%s\n", + $ucb->{unitname}, $lbn, $rc, $msg; + } + + return $rc; +} + +#------------------------------------------------------------------------------- +# write one disk block at lbn, takes data from $icb->{buf} + +sub serv11_icb_disk_write { # write one dsk file block + my ($icb) = @_; + my $ucb = $icb->{ucb}; + my $ctl = $icb->{ctl}; + my $fh = $ucb->{att_fh}; + my $fsize = $ucb->{att_nbyt}; + my $lbn = $icb->{lbn}; + my $blksize = $ctl->{blksize}; + my $seekpos = $lbn*$blksize; + my $sysbuf = ""; + my $rc; + + if (scalar(@{$icb->{buf}}) > int($blksize/2)) { + print_fatal "serv11_icb_disk_write: buf too long"; + } + + while (scalar(@{$icb->{buf}}) < int($blksize/2)) { # zero pad to block size + push @{$icb->{buf}}, 0; + } + + if ($fsize <= $seekpos) { # extend dsk file ? + my $zerobuf = chr(0) x $blksize; + my $cnt = 0; + file_seek($fh, $fsize); + while ($fsize <= $seekpos) { + file_write($fh, $zerobuf); + $fsize += $blksize; + $cnt += 1; + } + if (exists $opts{tserv} && $ctl->{trace}) { + printf $fh_log "disk -- %3s extended by %d blocks\n", + $ucb->{unitname}, $cnt; + } + $ucb->{att_nbyt} = $fsize; + } + + $sysbuf = conv_wlist2buf($icb->{buf}); + $rc = file_seek_write($fh, $seekpos, $sysbuf); + + if (exists $opts{tserv} && $ctl->{trace}) { + printf $fh_log "disk -- %3s write lbn=%5d rc=%d\n", + $ucb->{unitname}, $lbn, $rc; + } + + return $rc; +} + +#------------------------------------------------------------------------------- + +sub serv11_rri_init { # issue rri init command + my ($aname,$addr,$data) = @_; + push @rri_cmdlist, {cname => "init", + aname => $aname, + addr => $addr, + data => $data, + ref_stat => $rri_ref_sdef, + msk_stat => $rri_msk_sdef}; + return undef; +} + +#------------------------------------------------------------------------------- + +sub serv11_rri_attn { # issue rri attn command + my ($aname) = @_; + push @rri_cmdlist, {cname => "attn", + aname => $aname, + ref_stat => $rri_ref_sdef, + msk_stat => $rri_msk_sdef}; + $rri_cmdlist[$#rri_cmdlist]->{get_data} = 1; + return $rri_rvalcnt++; +} + +#------------------------------------------------------------------------------- + +sub serv11_rri_stat { # issue rri stat command + my ($aname) = @_; + push @rri_cmdlist, {cname => "stat", + aname => $aname, + ref_stat => $rri_ref_sdef, + msk_stat => $rri_msk_sdef}; + $rri_cmdlist[$#rri_cmdlist]->{get_data} = 1; + return $rri_rvalcnt++; +} + +#------------------------------------------------------------------------------- + +sub serv11_rri_rreg { # issue rri rreg command + my ($aname,$addr) = @_; + push @rri_cmdlist, {cname => "rreg", + aname => $aname, + addr => $addr, + ref_stat => $rri_ref_sdef, + msk_stat => $rri_msk_sdef}; + $rri_cmdlist[$#rri_cmdlist]->{get_data} = 1; + return $rri_rvalcnt++; +} + +#------------------------------------------------------------------------------- + +sub serv11_rri_wreg { # issue rri wreg command + my ($aname,$addr,$data) = @_; + push @rri_cmdlist, {cname => "wreg", + aname => $aname, + addr => $addr, + data => $data, + ref_stat => $rri_ref_sdef, + msk_stat => $rri_msk_sdef}; + return undef; +} + +#------------------------------------------------------------------------------- + +sub serv11_rri_rblk { # issue rri rblk command + my ($nblk) = @_; + push @rri_cmdlist, {cname => "rblk", + aname => "brm", + addr => PDPCP_ADDR_MEMI, + nblk => $nblk, + ref_stat => $rri_ref_sdef, + msk_stat => $rri_msk_sdef}; + $rri_cmdlist[$#rri_cmdlist]->{get_rblk} = 1; + return $rri_rvalcnt++; +} + +#------------------------------------------------------------------------------- + +sub serv11_rri_wblk { # issue rri wblk command + my ($nblk,$dref) = @_; + push @rri_cmdlist, {cname => "wblk", + aname => "bwm", + addr => PDPCP_ADDR_MEMI, + nblk => $nblk, + dat_wblk => $dref, + ref_stat => $rri_ref_sdef, + msk_stat => $rri_msk_sdef}; + return undef; +} + +#------------------------------------------------------------------------------- + +sub serv11_rri_lalh { # issue pdpcp lal and lah commands + my ($addr,$mode) = @_; + + serv11_rri_wreg("wal", PDPCP_ADDR_AL, $addr&0xffff); # lower 16 bits + if ($mode>=1 and $mode<=3) { + my $data = ($addr>>16)&0x3f | $mode<<6; + serv11_rri_wreg("wah", PDPCP_ADDR_AH, $data); # upper 6 bits + } + if ($mode<0 or $mode>3) { + print STDERR "pi_rri($curmode)-E: bad mode $mode in serv11_exec_rblk()\n"; + } +} + +#------------------------------------------------------------------------------- + +sub serv11_rri_ibrb { # issue rbus set base address + my ($ctl) = @_; + serv11_rri_wreg("wibrb", PDPCP_ADDR_IBRB, $ctl->{ibrb}); + return undef; +} + +#------------------------------------------------------------------------------- + +sub serv11_rri_ribr { # issue rbus read + my ($aname,$ctl,$off) = @_; + my $ibroff = $ctl->{base} + $off - $ctl->{ibrb}; + return serv11_rri_rreg($aname, PDPCP_ADDR_IBR+int($ibroff/2)); +} + +#------------------------------------------------------------------------------- + +sub serv11_rri_wibr { # issue rbus write + my ($aname,$ctl,$off,$data) = @_; + my $ibroff = $ctl->{base} + $off - $ctl->{ibrb}; + return serv11_rri_wreg($aname, PDPCP_ADDR_IBR+int($ibroff/2), $data); +} + +#------------------------------------------------------------------------------- + +sub serv11_rri_clear { + @rri_cmdlist = (); + $rri_rvalcnt = 0; +} + +#------------------------------------------------------------------------------- + +sub serv11_rri_exec { + my ($dref) = @_; + my $rc = 0; + + return $rc if scalar(@rri_cmdlist) == 0; + + rri_cmdlist_exec(\@rri_cmdlist); + $rc = rri_cmdlist_check_stat(\@rri_cmdlist); + + if ($rc) { + print "pi_rri($curmode)-E: serv11_rri_exec error - dump follows\n"; + if (exists $opts{log} && $opts{log} ne "") { + print $fh_log "pi_rri($curmode)-E: serv11_rri_exec error - dump follows\n"; + } + } + if ($rc || exists $opts{dserv}) { + rri_cmdlist_dump(\@rri_cmdlist, 0, $fh_log); + } + + @{$dref} = (); + foreach my $ele (@rri_cmdlist) { + push @{$dref}, $ele->{rcv_data} if $ele->{get_data}; + push @{$dref}, $ele->{rcv_rblk} if $ele->{get_rblk}; + } + + @rri_cmdlist = (); + $rri_rvalcnt = 0; + + return $rc; +} + +#------------------------------------------------------------------------------- + +sub serv11_rri_uset { # issue rbus uset writes + my $ucb = shift @_; + my $ctl = $serv11_ctltbl{$ucb->{ctlname}}; + my $first = 1; + + while (scalar(@_)) { + my $text = shift @_; + my $addr = shift @_; + my $data = shift @_; + my $key = "uset_" . $text; + + if ((not defined $ctl->{$key}) || $ctl->{$key} != $data) { + + serv11_rri_ibrb($ctl) if $first; + $first = 0; + + serv11_rri_wibr($text, $ctl, $addr, $data); + $ctl->{$key} = $data; + + if (exists $opts{tserv} && $ctl->{trace}) { + printf $fh_log "uset -- %s %s %6.6o\n", + $ctl->{ctltype}, $ucb->{unitname}, $data; + } + } + } + +} + +#------------------------------------------------------------------------------- + +sub serv11_exec_rblk { + my ($addr,$mode,$dref,$nword) = @_; + my @rval; + + serv11_rri_lalh($addr,$mode); + + while ($nword>0) { + my $nblk = $nword; + $nblk = 256 if $nblk > 256; + $nword -= $nblk; + + my $idref = serv11_rri_rblk($nblk); + + my $rc = serv11_rri_exec(\@rval); + return $rc if $rc; + + push @$dref, @{$rval[$idref]}; + } + + return 0; +} + +#------------------------------------------------------------------------------- + +sub serv11_exec_wblk { + my ($addr,$mode,$dref) = @_; + my @rval; + + serv11_rri_lalh($addr,$mode); + + my $nword = scalar(@$dref); + my $offset = 0; + + if ($nword == 0) { + print "pi_rri($curmode)-W: spurious serv11_exec_wblk() with 0 data length\n"; + return; + } + + while ($nword>0) { + my $nblk = $nword; + $nblk = 256 if $nblk > 256; + my $beg = $offset; + my $end = $offset+$nblk-1; + + serv11_rri_wblk($nblk, [ @$dref[$beg..$end] ]); + + $nword -= $nblk; + $offset += $nblk; + + my $rc = serv11_rri_exec(\@rval); + return $rc if $rc; + } + + return 0; +} + +#------------------------------------------------------------------------------- + +sub serv11_exec_probe { + my ($addr,$mode) = @_; + my $iib; + my $irb; + + if ($mode =~ /i/) { + serv11_rri_wreg("wal", PDPCP_ADDR_AL, $addr); # i/o page in 16 bit mode + serv11_rri_rreg("rm", PDPCP_ADDR_MEM); + $iib = $#rri_cmdlist; + } + if ($mode =~ /r/) { + my $ibrbase = $addr & ~(077); # ibr-base => drop last 6 bits + my $ibroff = $addr & (077); # ibr-offset => take last 6 bits + + serv11_rri_wreg("wibrb", PDPCP_ADDR_IBRB, $ibrbase); + serv11_rri_rreg("ribr", PDPCP_ADDR_IBR + int($ibroff/2)); + $irb = $#rri_cmdlist; + } + + rri_cmdlist_exec(\@rri_cmdlist); + rri_cmdlist_dump(\@rri_cmdlist, 0) if exists $opts{dserv}; + + my $ival; + my $rval; + if (defined $iib) { + $ival =$rri_cmdlist[$iib]->{rcv_data} if not $rri_cmdlist[$iib]->{err_stat}; + } + if (defined $irb) { + $rval =$rri_cmdlist[$irb]->{rcv_data} if not $rri_cmdlist[$irb]->{err_stat}; + } + serv11_rri_clear(); + + return ($ival, $rval); +} + +#------------------------------------------------------------------------------- + +sub next_nxbuf { # calculate next nxbuf value + my ($ctl,$nxbuf,$nxbuf_val) = @_; + + if ($nxbuf_val <= $nxbuf/2) { + $nxbuf -= $ctl->{nxbuf_inc}; + } else { + $nxbuf += $ctl->{nxbuf_inc}; + } + $nxbuf = $ctl->{nxbuf_min} if $nxbuf < $ctl->{nxbuf_min}; + $nxbuf = $ctl->{nxbuf_max} if $nxbuf > $ctl->{nxbuf_max}; + + return $nxbuf; +} + +#------------------------------------------------------------------------------- + +sub telnet_readhdl { # telnet: socket read handler + my ($teldsc) = @_; + my $ucb = $teldsc->{ucb}; + + if ($teldsc->{state} == TELNET_STATE_LISTEN) { + my $fh_data = new FileHandle; + if (not accept($fh_data, $teldsc->{fh_port})) { + printf STDERR "pi_rri($curmode)-E: erro in accept(): $!\n"; + return; # FIXME: error handling ?? + } + printf "connect on port %s for %s\n", $teldsc->{port}, $ucb->{unitname}; + my $buf; + my $rc; + $buf = pack("C3", TELNET_CODE_IAC, TELNET_CODE_WILL, TELNET_OPT_LINE); + $rc = syswrite($fh_data, $buf, length($buf)); + $buf = pack("C3", TELNET_CODE_IAC, TELNET_CODE_WILL, TELNET_OPT_SGA); + $rc = syswrite($fh_data, $buf, length($buf)); + $buf = pack("C3", TELNET_CODE_IAC, TELNET_CODE_WILL, TELNET_OPT_ECHO); + $rc = syswrite($fh_data, $buf, length($buf)); + $buf = pack("C3", TELNET_CODE_IAC, TELNET_CODE_WILL, TELNET_OPT_BIN); + $rc = syswrite($fh_data, $buf, length($buf)); + $buf = pack("C3", TELNET_CODE_IAC, TELNET_CODE_DO, TELNET_OPT_BIN); + $rc = syswrite($fh_data, $buf, length($buf)); + + $teldsc->{state} = TELNET_STATE_STREAM; + $teldsc->{fh_data} = $fh_data; + + $buf = sprintf("\r\nconnect on port %s for %s\r\n\r\n", + $teldsc->{port}, $ucb->{unitname}); + $rc = syswrite($fh_data, $buf, length($buf)); + + telnet_writehdl($ucb); + + $serv11_fds_update = 1; + + } else { + + my $buf; + my $rc; + $rc = sysread($teldsc->{fh_data}, $buf, 64); + + if ($rc == 0) { + printf "disconnect on port %s for %s\n", $teldsc->{port}, $ucb->{unitname}; + close ($teldsc->{fh_data}); + delete $teldsc->{fh_data}; + $teldsc->{state} = TELNET_STATE_LISTEN; + $serv11_fds_update = 1; + + } else { + my @int = unpack("C*", $buf); + foreach my $byt (@int) { + if ($teldsc->{state} == TELNET_STATE_STREAM) { # state: stream + if ($byt == TELNET_CODE_IAC) { + $teldsc->{state} = TELNET_STATE_IAC; + } else { + my $ctl = $serv11_ctltbl{$ucb->{ctlname}}; + my @bytes; + push @bytes, $byt; + &{$ctl->{ichrhdl}}($ucb, \@bytes); # call ichr handler + } + } elsif ($teldsc->{state} == TELNET_STATE_IAC) { # state: IAC seen + if ($byt == TELNET_CODE_WILL || + $byt == TELNET_CODE_WONT || + $byt == TELNET_CODE_DO || + $byt == TELNET_CODE_DONT) { + $teldsc->{state} = TELNET_STATE_CMD; + } elsif ($byt == TELNET_CODE_SB) { + $teldsc->{state} = TELNET_STATE_SUBNEG; + } else { + $teldsc->{state} = TELNET_STATE_STREAM; + } + } elsif ($teldsc->{state} == TELNET_STATE_CMD) { # state: cmd seen + $teldsc->{state} = 0; + } elsif ($teldsc->{state} == TELNET_STATE_SUBNEG) { # state: subneg + if ($byt == TELNET_CODE_IAC) { + $teldsc->{state} = TELNET_STATE_SUBIAC; + } + } elsif ($teldsc->{state} == TELNET_STATE_SUBIAC) { # state: subneg+IAC + $teldsc->{state} = TELNET_STATE_STREAM; + } + } + } + } +} + +#------------------------------------------------------------------------------- + +sub telnet_writehdl { # telnet: write handler + my ($ucb) = @_; + + my $teldsc = $telnettbl{$ucb->{att_port}}; + return if $teldsc->{state} == TELNET_STATE_LISTEN; + + while (scalar( @{$ucb->{sndque}} )) { + my $byte = shift @{$ucb->{sndque}}; + syswrite($teldsc->{fh_data}, pack("C1",$byte), 1); +## FIXME: escape IAC !! +## if ($byte == TELNET_CODE_CR) { +## syswrite($teldsc->{fh_data}, pack("C1",TELNET_CODE_LF), 1); +## } + } + +} + +#------------------------------------------------------------------------------- + +sub pdp11_disassemble { + my ($pc,$d0,$d1,$d2) = @_; + my @mem = ($d0,0,0); + $mem[1] = $d1 if defined $d1; + $mem[2] = $d2 if defined $d2; + + my $code = shift @mem; + + foreach my $ele (@pdp11_opcode_tbl) { + if (($code & (~($ele->{mask})) ) == $ele->{code}) { + my $name = $ele->{name}; + my $type = $ele->{type}; + my $str = $name; + if ($type eq "0arg") { + return ($name,1); + + } elsif ($type eq "1arg" or $type eq "1fpp") { + my $dst = $code & 077; + my $pref = ($type eq "1fpp") ? "f" : "r"; + my ($dst_str,$dst_nw,$dst_ta) = + pdp11_disassemble_regmod($dst, $mem[0], $pc+2, $pref); + shift @mem if ($dst_nw); + $str = "$name $dst_str"; + if ($dst_ta) { + $str .= " " x (27-length($str)) if length($str)<27; + $str .= "; $dst_ta"; + } + return ($str, 1+$dst_nw); + + } elsif ($type eq "2arg") { + my $src = ($code>>6) & 077; + my $dst = $code & 077; + my ($src_str,$src_nw,$src_ta) = + pdp11_disassemble_regmod($src, $mem[0], $pc+2); + shift @mem if ($src_nw); + my ($dst_str,$dst_nw,$dst_ta) = + pdp11_disassemble_regmod($dst, $mem[0], $pc+2+2*$src_nw); + shift @mem if ($dst_nw); + $str = "$name $src_str,$dst_str"; + if ($src_ta or $dst_ta) { + $str .= " " x (27-length($str)) if length($str)<27; + $str .= ";"; + $str .= " $src_ta" if $src_ta; + $str .= " $dst_ta" if $dst_ta; + } + return ($str, 1+$src_nw+$dst_nw); + + } elsif ($type eq "rdst") { + my $reg = ($code>>6) & 07; + my $src = $code & 077; + my ($src_str,$src_nw,$src_ta) = + pdp11_disassemble_regmod($src, $mem[0], $pc+2); + shift @mem if ($src_nw); + $str = "$name $src_str,r$reg"; + if ($src_ta) { + $str .= " " x (27-length($str)) if length($str)<27; + $str .= "; $src_ta"; + } + return ($str, 1+$src_nw); + + } elsif ($type eq "1reg") { + my $reg = $code & 07; + my $reg_str = "r$reg"; + $reg_str = "sp" if $reg == 6; + $reg_str = "pc" if $reg == 7; + return ("$name $reg_str", 1); + + } elsif ($type eq "br") { + my $off = $code & 0177; + my $sign = "+"; + if ($code & 0200) { + $off = -(((~$off) & 0177)+1); + $sign = "-"; + } + my $str = sprintf "$name .%s%d.", $sign, abs(2*$off); + $str .= " " x (27-length($str)) if length($str)<27; + $str .= sprintf "; -> %6.6o", (($pc+2)+2*$off)&0177777; + return ($str, 1); + + } elsif ($type eq "sob") { + my $reg = ($code>>6) & 07; + my $off = $code & 077; + my $str = sprintf "$name r%d,.-%d.", $reg, 2*$off; + $str .= " " x (27-length($str)) if length($str)<27; + $str .= sprintf "; -> %6.6o", ($pc+2)-2*$off; + return ($str, 1); + + } elsif ($type eq "trap") { + my $off = $code & 0377; + my $str = sprintf "$name %3.3o", $off; + return ($str, 1); + + } elsif ($type eq "spl") { + my $off = $code & 07; + my $str = sprintf "$name %d", $off; + return ($str, 1); + + } elsif ($type eq "ccop") { + my $cc = $code & 017; + return ("nop",1) if ($cc == 0); + return ("ccc",1) if ($code == 0257); + return ("scc",1) if ($code == 0277); + my $str = ""; + my $del = ""; + if ($code & 010) { $str .= $del . $name . "n", $del = "+" } + if ($code & 004) { $str .= $del . $name . "z", $del = "+" } + if ($code & 002) { $str .= $del . $name . "v", $del = "+" } + if ($code & 001) { $str .= $del . $name . "c", $del = "+" } + return ($str, 1); + + } elsif ($type eq "jsr") { + my $reg = ($code>>6) & 07; + my $dst = $code & 077; + my ($dst_str,$dst_nw,$dst_ta) = + pdp11_disassemble_regmod($dst, $mem[0], $pc+2); + shift @mem if ($dst_nw); + $str = "$name r$reg,$dst_str"; + if ($dst_ta) { + $str .= " " x (27-length($str)) if length($str)<27; + $str .= "; $dst_ta"; + } + return ($str, 1+$dst_nw); + + } elsif ($type eq "mark") { + my $off = $code & 077; + my $str = sprintf "$name %3.3o", $off; + return ($str, 1); + + } elsif ($type eq "rfpp") { + my $reg = ($code>>6) & 03; + my $dst = $code & 077; + my ($dst_str,$dst_nw,$dst_ta) = + pdp11_disassemble_regmod($dst, $mem[0], $pc+2, "f"); + shift @mem if ($dst_nw); + $str = "$name f$reg,$dst_str"; + if ($dst_ta) { + $str .= " " x (27-length($str)) if length($str)<27; + $str .= "; $dst_ta"; + } + return ($str, 1+$dst_nw); + + } else { + return ("?type?",1); + } + } + } + return ("=inval=",1); +} + +#------------------------------------------------------------------------------- + +sub pdp11_disassemble_regmod { + my ($regmod,$data,$pc,$pref) = @_; + my $mod = ($regmod>>3) & 07; + my $reg = $regmod & 07; + + $pref = "r" if not defined $pref or $reg>5; + + my $reg_str = "r$reg"; + $reg_str = "sp" if $reg == 6; + $reg_str = "pc" if $reg == 7; + + if ($mod == 0) { # mode 0: Rx { Fx for float } + $reg_str = "f$reg" if defined $pref && $pref eq "f" && $reg<=5; + return ($reg_str, 0, ""); + } elsif ($mod == 1) { # mode 1: (Rx) + return ("($reg_str)", 0, ""); + } elsif ($mod == 2 || $mod == 3) { # mode 2/3: (Rx)+ @(Rx)+ + my $ind = ($mod == 3) ? "@" : ""; + if ($reg != 7) { # if reg != pc + return ("$ind($reg_str)+", 0, ""); + } else { # if reg == pc + my $str = sprintf "$ind#%6.6o", $data; # 27 -> #nnn; 37 -> @#nnn + return ($str, 1, ""); + } + } elsif ($mod == 4 || $mod == 5) { # mode 4/5: -(Rx) @-(Rx) + my $ind = ($mod == 5) ? "@" : ""; + return ("$ind-($reg_str)", 0, ""); + } elsif ($mod == 6 || $mod == 7) { # mode 6/7: nn(Rx) @nn(Rx) + my $ind = ($mod == 7) ? "@" : ""; + my $data_str = sprintf "%o", $data; + my $ta_str = ""; + $ta_str = sprintf "%6.6o",($pc+2+$data)&0177777 if ($reg==7); + return ("$ind$data_str($reg_str)", 1, $ta_str); + } +} + +#------------------------------------------------------------------------------- + +sub file_seek { # fseek wrapper + my ($fh,$pos) = @_; + my $rc; + my $offset = $pos; + my $whence = 0; + if ($pos < 0) { # if offset<0 -> seek to EOF + $offset = 0; + $whence = 2; + } + $rc = $fh->seek($offset, $whence); + if (not $rc) { + print "pi_rri($curmode)-E: file_seek failed\n"; + $rc = 0; + } + return $rc; +} + +#------------------------------------------------------------------------------- + +sub file_read { # fread wrapper + my ($fh,$nbyte) = @_; + my $rc; + my $buf = ""; + + $rc = $fh->read($buf, $nbyte); + if ($rc != $nbyte) { + print "pi_rri($curmode)-E: file_read failed, got $rc, expectd $nbyte\n"; + $rc = 0; + } + return ($rc, $buf); +} + +#------------------------------------------------------------------------------- + +sub file_seek_read { # fseek+fread wrapper + my ($fh,$pos,$nbyte) = @_; + my $rc; + my $buf; + $rc = file_seek($fh, $pos); + ($rc,$buf) = file_read($fh, $nbyte) if $rc; + return ($rc, $buf); +} + +#------------------------------------------------------------------------------- + +sub file_write { # fwrite wrapper + my ($fh,$buf) = @_; + my $rc; + $rc = print $fh $buf; + if (not $rc) { + print "pi_rri($curmode)-E: file_write failed\n"; + $rc = 0; + } + return $rc; +} + +#------------------------------------------------------------------------------- + +sub file_seek_write { # fseek+fwrite wrapper + my ($fh,$pos,$buf) = @_; + my $rc; + $rc = file_seek($fh, $pos); + $rc = file_write($fh, $buf) if $rc; + return $rc; +} + +#------------------------------------------------------------------------------- + +sub raw_get9_crc_16bit { # read 16 bit value + my ($dref) = @_; + my $idl = raw_get9_crc(); + my $idh = undef; + $idh = raw_get9_crc() if defined $idl; + + if (defined $idh) { + my $idat = $idl | ($idh<<8); + $$dref = $idat; + return 1; + } + print "pi_rri($curmode)-E: receive time out\n"; + print $fh_log "ERR -- receive time out in raw_get9_crc_16bit\n"; + return 0; +} + +#------------------------------------------------------------------------------- + +sub raw_get9_crc_8bit { # read 8bit value + my ($dref) = @_; + my $idat = raw_get9_crc(); + if (defined $idat) { + $$dref = $idat; + return 1; + } + return 0; +} + +#------------------------------------------------------------------------------- + +sub raw_get9_crc_check { # get 9bit, block, crc, ref value + my ($ref,$case) = @_; + my $dat = raw_get9_crc(); + if (defined $dat) { + return 1 if ($dat == $ref); + printf "pi_rri($curmode)-E: receive $case mismatch" . + " found=0x%3.3x expect=0x%3.3x\n", + $dat, $ref; + return 0; + } + return 0; +} + +#------------------------------------------------------------------------------- + +sub raw_get9_check { # get 9bit, block, expect ref value + my ($ref,$case) = @_; + my $dat = raw_get9(); + if (defined $dat) { + return 1 if ($dat == $ref); + printf "pi_rri($curmode)-E: receive $case mismatch" . + " found=0x%3.3x expect=0x%3.3x\n", + $dat, $ref; + return 0; + } + return 0; +} + +#------------------------------------------------------------------------------- + +sub raw_get9_checksop { # get 9bit, block, expect SOP + my $dat; + while(1) { + $dat = raw_get9(); + last unless defined $dat; + last if ($dat != D9ATTN); + if ($serv11_active) { + $serv11_attn_seen = 1; + } else { + printf "pi_rri($curmode)-W: unexpected ATTN comma dropped\n"; + } + } + if (defined $dat) { + return 1 if ($dat == D9SOP); + printf "pi_rri($curmode)-E: expect sop, but found=0x%3.3x\n", $dat; + } + return 0; +} + +#------------------------------------------------------------------------------- + +sub raw_get9_checkeop { # get 9bit, block, expect EOP + my $dat; + $dat = raw_get9(); + if (defined $dat) { + return 1 if ($dat == D9EOP); + printf "pi_rri($curmode)-E: expect eop, but found=0x%3.3x\n", $dat; + } + return 0; +} + +#------------------------------------------------------------------------------- + +sub raw_get9_crc { # get 9bit, block, update crc + my $dat = raw_get9(); + $icrc = $crc8_tbl[$icrc ^ $dat] if (defined $dat && $dat < 0x100); + return $dat; +} + +#------------------------------------------------------------------------------- + +sub raw_get9 { # get 9bit, block + my $nidle = 0; + my $dat = undef; + while (1) { + $dat = raw_rcv9_to($raw_timeout); + last unless defined $dat; + last if $dat != D9IDLE; + $nidle += 1; + } +## print "pi_rri($curmode)-I: dropped $nidle idle commas\n" if $nidle; + print "pi_rri($curmode)-E: receive time out\n" unless defined $dat; + print $fh_log "ERR -- receive time out in raw_get9\n" unless defined $dat; + return $dat; +} + +#------------------------------------------------------------------------------- + +sub raw_snd9_crc { # put 9bit to RX, update crc + my ($dat) = @_; + raw_snd9($dat); + $ocrc = $crc8_tbl[$ocrc ^ $dat] if ($dat < 0x100); +} + +#------------------------------------------------------------------------------- + +sub raw_snd9 { # put 9bit to RX + my ($dat) = @_; + + if (exists $opts{tio9}) { + print $fh_log conv_etime(\$tlast_tio9), + "[$curchan] snd9 ", conv_dat9($dat); + printf $fh_log " sndq=%3d", scalar(@que_snd); + print $fh_log " -- idle" if $dat == D9IDLE; + print $fh_log " -- sop " if $dat == D9SOP; + print $fh_log " -- eop " if $dat == D9EOP; + print $fh_log " -- nak " if $dat == D9NAK; + print $fh_log " -- attn" if $dat == D9ATTN; + print $fh_log "\n"; + } + $stat_tab{osop} += 1 if $dat == D9SOP; + + if ($dat >= 0x100) { + raw_snd8(CPREF | ($dat & 0x0f)); + } else { + if ( $dat == CESC || + ($dat >= CPREF && $dat <= (CPREF+NCOMM)) ) { + raw_snd8(CESC); + raw_snd8(CEN1 | ($dat & 0x0f)); + $stat_tab{oesc} += 1; + } else { + raw_snd8($dat); + } + } +} + +#------------------------------------------------------------------------------- + +sub raw_snd8 { # put 8bit to RX + my ($dat) = @_; + if (exists $opts{tio8}) { + print $fh_log conv_etime(\$tlast_tio8), + "[$curchan] snd8 ", conv_dat8($dat),"\n"; + } + $stat_tab{obyte} += 1; + + push @que_snd, int $dat; +} + +#------------------------------------------------------------------------------- + +sub raw_rcv9 { # get 9bit from TX, non-blocking + return raw_rcv9_to(0.); +} + +#------------------------------------------------------------------------------- + +sub raw_rcv8 { # get 8bit from TX, non-blocking + return raw_rcv8_to(0.); +} + +#------------------------------------------------------------------------------- + +sub raw_rcv9_to { + my ($timeout) = @_; + my $dat8 = raw_rcv8_to($timeout); + my $dat9 = undef; + + if (defined $dat8) { + if ($dat8 == CESC) { + $stat_tab{iesc} += 1; + $raw_rcv_esc = 1; + $dat8 = raw_rcv8_to($timeout); + return $dat8 unless defined $dat8; + } + if ($raw_rcv_esc) { + $dat9 = CPREF | ($dat8 & 0x0f); + $raw_rcv_esc = 0; + } else { + if ($dat8>= CPREF && $dat8<=(CPREF+NCOMM) ) { + $dat9 = 0x100 | ($dat8 & 0x0f); + } else { + $dat9 = $dat8; + } + } + } + + if (defined $dat9) { + $stat_tab{att} += 1 if $dat9 == D9ATTN; + ##print "+++9 attn seen\n" if $dat9==D9ATTN; + + if (exists $opts{tio9}) { + print $fh_log conv_etime(\$tlast_tio9), + "[$curchan] rcv9 ", conv_dat9($dat9); + printf $fh_log " rcvq=%3d", scalar(@que_rcv); + print $fh_log " -- idle" if $dat9 == D9IDLE; + print $fh_log " -- sop " if $dat9 == D9SOP; + print $fh_log " -- eop " if $dat9 == D9EOP; + print $fh_log " -- nak " if $dat9 == D9NAK; + print $fh_log " -- attn" if $dat9 == D9ATTN; + print $fh_log "\n"; + } + } + + return $dat9; +} + +#------------------------------------------------------------------------------- + +sub raw_rcv8_to { # get 8bit from TX, expl. time-out + my ($timeout) = @_; + my $buf; + my $dat; + + &{$chan_tab{$curchan}{write}}(); # flush write queue before read + + &{$chan_tab{$curchan}{read}}($timeout) unless @que_rcv; + $dat = shift @que_rcv; + + if (exists $opts{tio8} and defined $dat) { + print $fh_log conv_etime(\$tlast_tio8), + "[$curchan] rcv8 ", conv_dat8($dat),"\n"; + } + $stat_tab{ibyte} += 1; + + return $dat; +} + +#------------------------------------------------------------------------------- + +sub wait_sel_filercv { # poll/wait for TX to be ready + my ($timeout) = @_; + my $nfound=-1; + my $fds_rd; + + while ($nfound<0) { + $nfound = select($fds_rd=$fdset_filercv, undef, undef, $timeout); + next if ($nfound == -1) and $! == EINTR; + die "select error: $!" unless $nfound >= 0; + } + return $nfound; + } + +#------------------------------------------------------------------------------- + +sub fifo_open { # chan fifo: open handler + my ($arg) = @_; + my ($file,$keep) = split /,/,$arg; + my $file_base = $file ? $file : "tb_rriext_fifo"; + my $file_snd = $file_base . "_rx"; + my $file_rcv = $file_base . "_tx"; + + $fifo_keep = $keep; + $fdset_filercv = ""; + + print_fatal("I/O mode already set to --$curchan") if ($curchan); + + if (-e $file_snd) { + print_fatal("$file_snd exists but is not a pipe") unless (-p $file_snd); + } else { + mkfifo($file_snd, 0666) || die "can't mkfifo $file_snd: $!"; + print "pi_rri[fifo]-I: created fifo $file_snd\n"; + } + + if (-e $file_rcv) { + print_fatal("$file_rcv exists but is not a pipe") unless (-p $file_rcv); + } else { + mkfifo($file_rcv, 0666) || die "can't mkfifo $file_rcv: $!"; + print "pi_rri[fifo]-I: created fifo $file_rcv\n"; + } + + $fh_snd = new FileHandle; + $fh_rcv = new FileHandle; + + print "pi_rri[fifo]-I: wait to connect to $file_snd\n"; + sysopen ($fh_snd, $file_snd, O_WRONLY) || die "can't open $file_snd: $!"; + print "pi_rri[fifo]-I: connected to $file_snd\n"; + sysopen ($fh_rcv, $file_rcv, O_RDONLY) || die "can't open $file_rcv: $!"; + print "pi_rri[fifo]-I: connected to $file_rcv\n"; + vec($fdset_filercv, fileno($fh_rcv), 1) = 1; + + $curchan = "fifo"; +} + +#------------------------------------------------------------------------------- + +sub fifo_close { # chan fifo: close handler + if ($fifo_keep) { + print "pi_rri[fifo]-I: signal 'keep-alive' to tb\n"; + raw_snd8(CESC); + raw_snd8(CESC); + &{$chan_tab{$curchan}{write}}(); + } + close $fh_snd; + close $fh_rcv; + $fh_snd = undef; + $fh_rcv = undef; + $curchan = undef; +} + +#------------------------------------------------------------------------------- + +sub term_open { # term fifo: open handler + my ($arg) = @_; + my ($dev,$baud,$break) = split /,/,$arg; + $dev = "/dev/ttyS0" unless $dev; + $baud = 115200 unless $baud; + $break = 0 unless $break; + + $fdset_filercv = ""; + + print_fatal("I/O mode already set to --$curchan") if ($curchan); + + $fh_snd = new FileHandle; + $fh_rcv = $fh_snd; # same file handle for read and write + + sysopen ($fh_snd, $dev, O_RDWR|O_NOCTTY) || # read/write, not control TTY + die "can't open $dev: $!"; + my $fd = fileno($fh_snd); + vec($fdset_filercv, $fd, 1) = 1; + $curchan = "term"; + + print_fatal("$dev is not a TTY") unless isatty($fd); + + $term_oldtios = new POSIX::Termios; + $term_oldtios->getattr($fd) || die "getattr failed: $!"; + +## term_tios_print($term_oldtios); + + my $newtios = new POSIX::Termios; + $newtios->getattr($fd) || die "getattr failed: $!"; ## hack for cygwin !! + + my $c_iflag = &POSIX::BRKINT; # ignore parity errors + my $c_oflag = 0; + my $c_cflag = &POSIX::CS8 | # 8 bit chars + &POSIX::CSTOPB | # 2 stop bits + &POSIX::CREAD | # enable receiver + &POSIX::CLOCAL | # ignore modem control + LINUX_CRTSCTS; # enable hardware flow control + my $c_lflag = 0; + my $speed = 0; + + $speed = &POSIX::B9600 if $baud == 9600; + $speed = &POSIX::B19200 if $baud == 19200; + $speed = &POSIX::B38400 if $baud == 38400; + $speed = LINUX_B57600 if $baud == 57600; # hack, only for linux + $speed = LINUX_B115200 if $baud == 115200; # hack, only for linux + $speed = LINUX_B230400 if $baud == 230400; # hack, only for linux + $speed = LINUX_B460800 if $baud == 460800; # hack, only for linux + $speed = LINUX_B500000 if $baud == 500000; # hack, only for linux + $speed = LINUX_B921600 if $baud == 921600; # hack, only for linux + $speed = LINUX_B1000000 if $baud ==1000000; # hack, only for linux + $speed = LINUX_B2000000 if $baud ==2000000; # hack, only for linux + $speed = LINUX_B3000000 if $baud ==3000000; # hack, only for linux + + print_fatal("speed $baud not supported") unless $speed != 0; + + $c_cflag |= $speed; + + $newtios->setiflag($c_iflag); + $newtios->setoflag($c_oflag); + $newtios->setcflag($c_cflag); + $newtios->setlflag($c_lflag); + $newtios->setcc(&POSIX::VEOF, 0); # undef + $newtios->setcc(&POSIX::VEOL, 0); # undef + $newtios->setcc(&POSIX::VERASE, 0); # undef + $newtios->setcc(&POSIX::VINTR, 0); # undef + $newtios->setcc(&POSIX::VKILL, 0); # undef + $newtios->setcc(&POSIX::VQUIT, 0); # undef + $newtios->setcc(&POSIX::VSUSP, 0); # undef + $newtios->setcc(&POSIX::VSTART, 0); # undef + $newtios->setcc(&POSIX::VSTOP, 0); # undef + $newtios->setcc(&POSIX::VMIN, 1); # wait for 1 char + $newtios->setcc(&POSIX::VTIME, 0); # + +## term_tios_print($newtios); + + $newtios->setattr($fd) || die "setattr failed: $!"; + + if ($break) { + tcsendbreak($fd, 0) || die "tcsendbreak failed: $!"; + raw_snd8 (0x80); + &{$chan_tab{$curchan}{write}}(); # write 10000000 for autobaud + } + +} + +#------------------------------------------------------------------------------- + +sub term_close { # chan term: close handler + $term_oldtios->setattr(fileno($fh_snd)) || die "setattr failed: $!"; + close $fh_snd; + $fh_snd = undef; + $fh_rcv = undef; + $curchan = undef; +} + +#------------------------------------------------------------------------------- + +sub term_tios_print { + my ($tios) = @_; + + my $iflag = $tios->getiflag; + my $oflag = $tios->getoflag; + my $cflag = $tios->getcflag; + my $lflag = $tios->getlflag; + + printf "iflag = %8.8x:", $iflag; + print " BRKINT" if $iflag & &POSIX::BRKINT; + print " ICRNL " if $iflag & &POSIX::ICRNL; + print " IGNBRK" if $iflag & &POSIX::IGNBRK; + print " IGNCR " if $iflag & &POSIX::IGNCR; + print " IGNPAR" if $iflag & &POSIX::IGNPAR; + print " INLCR " if $iflag & &POSIX::INLCR; + print " INPCK " if $iflag & &POSIX::INPCK; + print " ISTRIP" if $iflag & &POSIX::ISTRIP; + print " IXOFF " if $iflag & &POSIX::IXOFF; + print " IXON " if $iflag & &POSIX::IXON; + print " PARMRK" if $iflag & &POSIX::PARMRK; + print "\n"; + printf "oflag = %8.8x:", $oflag; + print " OPOST " if $oflag & &POSIX::OPOST; + print "\n"; + + printf "cflag = %8.8x:", $cflag; + print " CLOCAL" if $cflag & &POSIX::CLOCAL; + print " CREAD " if $cflag & &POSIX::CREAD; + print " CS5 " if ($cflag & &POSIX::CSIZE) == &POSIX::CS5; + print " CS6 " if ($cflag & &POSIX::CSIZE) == &POSIX::CS6; + print " CS7 " if ($cflag & &POSIX::CSIZE) == &POSIX::CS7; + print " CS8 " if ($cflag & &POSIX::CSIZE) == &POSIX::CS8; + print " CSTOPB" if $cflag & &POSIX::CSTOPB; + print " HUPCL " if $cflag & &POSIX::HUPCL; + print " PARENB" if $cflag & &POSIX::PARENB; + print " PARODD" if $cflag & &POSIX::PARODD; + + my $sbits = &POSIX::B50 | &POSIX::B75 | &POSIX::B110 | &POSIX::B134 | + &POSIX::B150 | &POSIX::B200 | &POSIX::B300 | &POSIX::B600 | + &POSIX::B1200 | &POSIX::B1800 | &POSIX::B2400 | &POSIX::B4800 | + &POSIX::B9600 | &POSIX::B19200 | &POSIX::B38400; + print " B0 " if ($cflag & $sbits) == &POSIX::B0; + print " B50 " if ($cflag & $sbits) == &POSIX::B50; + print " B75 " if ($cflag & $sbits) == &POSIX::B75; + print " B110 " if ($cflag & $sbits) == &POSIX::B110; + print " B134 " if ($cflag & $sbits) == &POSIX::B134; + print " B150 " if ($cflag & $sbits) == &POSIX::B150; + print " B200 " if ($cflag & $sbits) == &POSIX::B200; + print " B300 " if ($cflag & $sbits) == &POSIX::B300; + print " B600 " if ($cflag & $sbits) == &POSIX::B600; + print " B1200 " if ($cflag & $sbits) == &POSIX::B1200; + print " B1800 " if ($cflag & $sbits) == &POSIX::B1800; + print " B2400 " if ($cflag & $sbits) == &POSIX::B2400; + print " B4800 " if ($cflag & $sbits) == &POSIX::B4800; + print " B9600 " if ($cflag & $sbits) == &POSIX::B9600; + print " B19200" if ($cflag & $sbits) == &POSIX::B19200; + print " B38400" if ($cflag & $sbits) == &POSIX::B38400; + print "\n"; + + printf "lflag = %8.8x:", $lflag; + print " ECHO " if $lflag & &POSIX::ECHO; + print " ECHOE " if $lflag & &POSIX::ECHOE; + print " ECHOK " if $lflag & &POSIX::ECHOK; + print " ECHONL" if $lflag & &POSIX::ECHONL; + print " ICANON" if $lflag & &POSIX::ICANON; + print " IEXTEN" if $lflag & &POSIX::IEXTEN; + print " ISIG " if $lflag & &POSIX::ISIG; + print " NOFLSH" if $lflag & &POSIX::NOFLSH; + print " TOSTOP" if $lflag & &POSIX::TOSTOP; + print "\n"; + + printf "cc(VEOF) = %3.3o\n", $tios->getcc(&POSIX::VEOF); + printf "cc(VEOL) = %3.3o\n", $tios->getcc(&POSIX::VEOL); + printf "cc(VERASE)= %3.3o\n", $tios->getcc(&POSIX::VERASE); + printf "cc(VINTR) = %3.3o\n", $tios->getcc(&POSIX::VINTR); + printf "cc(VKILL) = %3.3o\n", $tios->getcc(&POSIX::VKILL); + printf "cc(VQUIT) = %3.3o\n", $tios->getcc(&POSIX::VQUIT); + printf "cc(VSUSP) = %3.3o\n", $tios->getcc(&POSIX::VSUSP); + printf "cc(VSTART)= %3.3o\n", $tios->getcc(&POSIX::VSTART); + printf "cc(VSTOP) = %3.3o\n", $tios->getcc(&POSIX::VSTOP); + printf "cc(VMIN) = %3.3o\n", $tios->getcc(&POSIX::VMIN); + printf "cc(VTIME) = %3.3o\n", $tios->getcc(&POSIX::VTIME); +# printf "cc(NCCS) = %3.3o\n", $tios->getcc(&POSIX::NCCS); +} + +#------------------------------------------------------------------------------- + +sub genio_read { # generic io: read handler + my ($timeout) = @_; + my $tstart; + my $rc; + + $tstart = get_time() if exists $opts{tiob}; + if (wait_sel_filercv($timeout)) { + my $buf; + + while (not defined $rc) { + $rc = sysread($fh_rcv, $buf, 64); + next if (not defined $rc) and $! == EINTR; + die "sysread fifo error: $!" unless defined $rc; + } + + if (exists $opts{tiob}) { + printf $fh_log "%s[$curchan] read %3d bytes in %8.6f sec\n", + conv_etime(\$tlast_tiob), $rc, get_time()-$tstart; + } + if ($rc) { + push @que_rcv, unpack("C*", $buf); + } + } +### if (defined $rc) { +### printf "+++1 _read $timeout rc=%d\n", $rc; +### } else { +### printf "+++1 _read $timeout rc=undef\n"; +### } + return $rc; +} + +#------------------------------------------------------------------------------- + +sub genio_write { # generic io: write handler +## printf "+++2 _write q=%d\n", scalar @que_snd; + if (scalar @que_snd) { + + my $buf = pack("C*", @que_snd); + while (length($buf)) { + while(1) { # read rcv fifo before writing + my $rc = genio_read(0.); # to avoid blocking under cygwin + last unless defined $rc and $rc > 0; + } + my $nwrite = length($buf); +### $nwrite = 1; # <-- when is this really needed ??? +### printf "+++2a _write nw=%d\n", $nwrite; + my $rc = syswrite($fh_snd, $buf, $nwrite); + next if (not defined $rc) and $! == EINTR; + die "syswrite fifo error: $!" unless defined $rc; + if (exists $opts{tiob}) { + printf $fh_log "%s[$curchan] write %3d bytes", conv_etime(\$tlast_tiob), $rc; + printf $fh_log " of %3d in queue", length($buf) if $rc < length($buf); + print $fh_log "\n"; + } + last if $rc == length($buf); + $buf = substr($buf, $rc); + } + + @que_snd = (); + } +} + +#------------------------------------------------------------------------------- + +sub cget_chkblank { # check for unused chars in cmd line + $cmd_rest =~ s/^\s*//; + if ($cmd_rest ne "") { + print "pi_rri($curmode)-E: extra data ignored: \"$cmd_rest\"\n"; + print " for command: \"$cmd_line\"\n"; + $cmd_bad = 1; + } + return $cmd_bad; +} + +#------------------------------------------------------------------------------- + +sub cget_tagval2_gdat { # get tag=v1[,v2], generic base + my ($tag,$nbit,$dbase) = @_; + my $dat; + my $msk = undef; + $cmd_rest =~ s/^\s*//; +### print "+++2 |$cmd_rest|$tag|$nbit|$dbase|\n"; + if ($cmd_rest =~ /^$tag=/) { + $cmd_rest = $'; + if ($cmd_rest =~ /^-/) { + $cmd_rest = $'; + return (0,0xffff); + } else { + $dat = cget_gdat($nbit, $dbase); + if ($cmd_rest =~ /^,/) { + $cmd_rest = $'; + $msk = cget_gdat($nbit, $dbase); + } + return ($dat, $msk); + } + } + return (undef, undef); +} + +#------------------------------------------------------------------------------- + +sub cget_tagval_gdat { # get tag=val, generic base + my ($tag,$nbit,$dbase,$min,$max) = @_; + $cmd_rest =~ s/^\s*//; + if ($cmd_rest =~ /^$tag=/) { + $cmd_rest = $'; + return cget_gdat($nbit, $dbase,$min,$max); + } + return undef; +} + +#------------------------------------------------------------------------------- + +sub cget_gdat { # get generic base value + my ($nbit,$dbase,$min,$max) = @_; + my $dat; + + $cmd_rest =~ s/^\s*//; +### print "+++1 |$nbit|$dbase|$cmd_rest|\n"; + if ($cmd_rest =~ /^[xXoObBdD]"/) { + if ($cmd_rest =~ /^[xX]"([0-9a-fA-F]+)"/) { + $cmd_rest = $'; + $dat = hex $1; + } elsif ($cmd_rest =~ /^[oO]"([0-7]+)"/) { + $cmd_rest = $'; + $dat = oct $1; + } elsif ($cmd_rest =~ /^[bB]"([01]+)"/) { + $cmd_rest = $'; + my $odat = sget_bdat($nbit, $1); + $dat = $odat if defined $odat; + } elsif ($cmd_rest =~ /^[dD]"([+-]?[0-9]+)"/) { + $cmd_rest = $'; + my $odat = (int $1) & ((1<<$nbit)-1); + $dat = $odat; + } + } else { + if ($cmd_rest =~ /^([+-]?[0-9]+)\./) { + $cmd_rest = $'; + my $odat = (int $1) & ((1<<$nbit)-1); + $dat = $odat; + } elsif ($dbase == 16 && $cmd_rest =~ /^([0-9a-fA-F]+)/) { + $cmd_rest = $'; + $dat = hex $1; + } elsif ($dbase == 8 && $cmd_rest =~ /^([0-7]+)/) { + $cmd_rest = $'; + $dat = oct $1; + } elsif ($dbase == 2 && $cmd_rest =~ /^([01]+)/) { + $cmd_rest = $'; + my $odat = sget_bdat($nbit, $1); + $dat = $odat if defined $odat; + } elsif ($dbase == 10 && $cmd_rest =~ /^([0-9]+)/) { + $cmd_rest = $'; + $dat = int $1; + } + } + + if (not defined $dat) { + $cmd_bad = 1; + print "pi_rri($curmode)-E: cget_gdat error in \"$cmd_rest\" (base=$dbase)\n"; + return undef; + } + + if (defined $min && $dat < $min) { + $cmd_bad = 1; + print "pi_rri($curmode)-E: cget_gdat range error, $dat < $min\n"; + return undef; + } + if (defined $max && $dat > $max) { + $cmd_bad = 1; + print "pi_rri($curmode)-E: cget_gdat range error, $dat > $max\n"; + return undef; + } + + return $dat; +} + +#------------------------------------------------------------------------------- + +sub cget_name { # get name \w+ + + $cmd_rest =~ s/^\s*//; + if ($cmd_rest =~ /^(\w+)/) { + $cmd_rest = $'; + return $1; + } + + $cmd_bad = 1; + print "pi_rri($curmode)-E: cget_name error in \"$cmd_rest\"\n"; + return undef; +} + +#------------------------------------------------------------------------------- + +sub cget_bool { # get boolean [01] + $cmd_rest =~ s/^\s*//; + if ($cmd_rest =~ /^([01])/) { + $cmd_rest = $'; + return int($1); + } + + $cmd_bad = 1; + print "pi_rri($curmode)-E: cget_name error in \"$cmd_rest\"\n"; + return undef; +} + +#------------------------------------------------------------------------------- + +sub cget_file { # get filename [\w\/.]+ + + $cmd_rest =~ s/^\s*//; + if ($cmd_rest =~ /^([\w\/.-]+)/) { + $cmd_rest = $'; + return $1; + } + + $cmd_bad = 1; + print "pi_rri($curmode)-E: cget_file error in \"$cmd_rest\"\n"; + return undef; +} + +#------------------------------------------------------------------------------- + +sub cget_ucb { # get ucb (read name, return ucb) + my ($type,$name) = @_; + + $name = cget_name() unless defined $name; + return undef if not defined $name; + + $name = uc($name); + $name .= "0" if length($name)==2; + if (not exists $serv11_unittbl{$name}) { + $cmd_bad = 1; + print "pi_rri($curmode)-E: unknown device unit $name\n"; + return undef; + } + + my $ucb = $serv11_unittbl{$name}; + my $ctl = $serv11_ctltbl{$ucb->{ctlname}}; + + if (not $ctl->{probe_ok}) { + $cmd_bad = 1; + print "pi_rri($curmode)-E: device controller $name not available\n"; + return undef; + } + + if (defined $type) { + if ($ctl->{type} ne $type) { + $cmd_bad = 1; + print "pi_rri($curmode)-E: $name is not type=$type\n"; + return undef; + } + } + + return $ucb; +} + +#------------------------------------------------------------------------------- + +sub cget_opt { # get option + my ($opt) = @_; + if ($cmd_rest =~ /^\s*$opt\b/) { # opt found, followed by non \w + $cmd_rest = $'; + return 1; + } + return 0; +} + +#------------------------------------------------------------------------------- + +sub cget_optset { # get option set + my ($optset) = @_; + my $optout = ""; + while ($cmd_rest =~ /\s*-([a-zA-Z])\b/) { # any -x found + $cmd_rest = $'; + my $optchar = $1; + if ($optset =~ /$optchar/) { # char in optset ? + $optout .= $optchar; + } else { + $cmd_bad = 1; + print "pi_rri($curmode)-E: unexpected option -$optchar\n"; + } + } + return $optout; +} + +#------------------------------------------------------------------------------- +sub cget_regrange { # get register/memory range + my $ctl; + my $beg; + my $end; + + if (cchk_number()) { # numerical address + $beg = cget_gdat(22,8); + $end = $beg; + if ($cmd_rest =~ m{^:}) { + $cmd_rest =~ s{^:}{}; + $end = cget_gdat(22,8); + } elsif ($cmd_rest =~ m{^/}) { + $cmd_rest =~ s{^/}{}; + $end = $beg + cget_gdat(22,8) - 2; + } + + } else { # symbolical address + my $regtbl; + my $ctlnam = uc(cget_name()); + my $begnam = lc($ctlnam); + my $endnam; + if (exists $serv11_ctltbl{CPU}->{regtbl}->{$begnam}) { + $ctlnam = "CPU"; + $regtbl = $serv11_ctltbl{CPU}->{regtbl}; + } elsif (exists $serv11_ctltbl{$ctlnam}->{regtbl}) { + $regtbl = $serv11_ctltbl{$ctlnam}->{regtbl}; + $begnam = lc(cget_name()); + } else { + print "pi_rri($curmode)-E: '$begnam' neither controller nor" . + " cpu register name\n"; + $cmd_bad = 1; + return (undef, undef, undef); + } + + $ctl = $serv11_ctltbl{$ctlnam}; + + if (not $ctl->{probe_ok}) { + print "pi_rri($curmode)-E: '$ctlnam' not available\n"; + $cmd_bad = 1; + return (undef, undef, undef); + } + + my $reglist = $ctl->{reglist}; + $beg = 0; + $end = scalar @{$reglist}-1; + + if ($begnam ne "state") { + + $endnam = $begnam; + if ($cmd_rest =~ m{^:}) { + $cmd_rest =~ s{^:}{}; + $endnam = lc(cget_name()); + } + + if (not exists $regtbl->{$begnam}) { + print "pi_rri($curmode)-E: '$begnam' not register in '$ctlnam'\n"; + $cmd_bad = 1; + return (undef, undef, undef); + } + if (not exists $regtbl->{$endnam}) { + print "pi_rri($curmode)-E: '$endnam' not register in '$ctlnam'\n"; + $cmd_bad = 1; + return (undef, undef, undef); + } + + $beg = $regtbl->{$begnam}; + $end = $regtbl->{$endnam}; + } + } + + if (defined $beg && defined $end && $beg > $end) { + my $tmp = $beg; + $beg = $end; + $end = $tmp; + } + + return ($ctl, $beg, $end); +} + +#------------------------------------------------------------------------------- + +sub cchk_number { # check for number. any gdat value + # except for plain hex (e.g. 'dead') + return 1 if $cmd_rest =~ /^\s*([0-9]+)/; + return 1 if $cmd_rest =~ /^\s*([+-]?[0-9]+)\./; + return 1 if $cmd_rest =~ /^\s*[xX]"([0-9a-fA-F]+)"/; + return 1 if $cmd_rest =~ /^\s*[oO]"([0-9]+)"/; + return 1 if $cmd_rest =~ /^\s*[bB]"([01]+)"/; + return 1 if $cmd_rest =~ /^\s*[dD]"([+-]?[0-9]+)"/; + return 0; +} + +#------------------------------------------------------------------------------- + +sub sget_bdat { # convert 01 string -> binary value + my ($nbit,$str) = @_; + my $nchar = length($str); + my $odat = 0; + my $i; + + return undef if ($nchar != $nbit); + + for ($i = 0; $i < $nchar; $i++) { + $odat *= 2; + $odat += 1 if substr($str, $i, 1) eq "1"; + } + return $odat; +} + +#------------------------------------------------------------------------------- + +sub conv_etime { # generate timestamp string + my ($ref_elast) = @_; + my $etime = get_time()-$time0; + my $str = sprintf "%12.6f ", $etime; + if (defined $ref_elast) { + my $dt = $etime - $$ref_elast; + $$ref_elast = $etime; + $str .= sprintf "(%10.6f) ", $dt; + } + return $str; +} + +#------------------------------------------------------------------------------- + +sub conv_dat9 { + my ($dat9) = @_; + return (($dat9 & 0x100) ? "1" : "0") . " " . conv_dat8($dat9); +} + +#------------------------------------------------------------------------------- + +sub conv_dat8 { + my ($dat8) = @_; + my $buf = ""; + vec($buf,0,8) = int $dat8; + return unpack("B8",$buf); +} + +#------------------------------------------------------------------------------- + +sub conv_str2bytes { # string to bytelist; handle \n\r + my ($str,$dref,$esc) = @_; + + while (length($str)) { + if ($esc && $str =~ /^\\n/) { + push @{$dref}, 0015; # send CR + $str = $'; + } elsif ($esc && $str =~ /^\\r/) { + push @{$dref}, 0013; # send LF + $str = $'; + } else { + my $chr = substr($str,0,1); + push @{$dref}, ord($chr); + $str = substr($str,1); + } + } +} + +#------------------------------------------------------------------------------- + +sub conv_buf2wlist { # string buffer -> word list + my ($buf) = @_; + my @sysbyt; + my $nw = int(length($buf)/2); + my $dref = []; + my $i; + + push @sysbyt, unpack("C*", $buf); + for ($i=0; $i<$nw; $i++) { + my $bl = shift @sysbyt; # lsb is first + my $bh = shift @sysbyt; + push @{$dref}, 256*$bh + $bl; + } + return $dref; +} + +#------------------------------------------------------------------------------- + +sub conv_wlist2buf { # word list -> string buffer + my ($dref) = @_; + my @sysbyt; + my $buf; + + foreach my $word (@{$dref}) { + my $bl = $word & 0xff; + my $bh = ($word>>8) & 0xff; + push @sysbyt, $bl; # lsb is first + push @sysbyt, $bh; + } + + $buf = pack("C*", @sysbyt); + return $buf; +} + +#------------------------------------------------------------------------------- + +sub conv_byte2ascii2 { # byte -> 2 charcter ASCII display + my ($byte) = @_; + if ($byte >= 32 && $byte < 128) { + return chr($byte) . " "; + } else { + my $str = ".."; + $str = "\\0" if $byte == 000; # NUL 000 -> \0 + $str = "\\a" if $byte == 007; # BEL 007 -> \a + $str = "\\b" if $byte == 010; # BS 010 -> \b + $str = "\\t" if $byte == 011; # TAB 011 -> \t + $str = "\\n" if $byte == 012; # LF 012 -> \n + $str = "\\v" if $byte == 013; # VT 013 -> \v + $str = "\\f" if $byte == 014; # FF 014 -> \f + $str = "\\r" if $byte == 015; # CR 015 -> \r + return $str; + } +} + +#------------------------------------------------------------------------------- + +sub gconv_dat16 { + my ($dat,$dbase) = @_; + if ($dbase == 2) { + my $bufl = ""; + my $bufh = ""; + vec($bufl,0,8) = int ($dat & 0xff); + vec($bufh,0,8) = int (($dat>>8) & 0xff); + return unpack("B8",$bufh) . unpack("B8",$bufl); + } elsif ($dbase == 8) { + return sprintf "%6.6o", int $dat; + } elsif ($dbase == 16) { + return sprintf "%4.4x", int $dat; + } else { + return "??dbase??"; + } +} +#------------------------------------------------------------------------------- + +sub hdl_sigint { # SIGINT handler + if ($sigint_count == 1) { + print STDERR "\a"; # send beep + } elsif ($sigint_count == 2) { + print STDERR "pi_rri($curmode)-W: not responding on ^C, next will abort\n"; + } elsif ($sigint_count == 3) { + print STDERR "pi_rri($curmode)-E: ^C abort\n"; + exit(1); + } + $sigint_count += 1; +} + +#------------------------------------------------------------------------------- + +sub get_time { + my ($sec, $usec) = gettimeofday(); + return $sec + 1.e-6 * $usec; +} + +#------------------------------------------------------------------------------- + +sub get_timestamp { + my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(); + return sprintf "%2.2d:%2.2d:%2.2d", $hour, $min, $sec; +} + +#------------------------------------------------------------------------------- + +sub filename_expand { # expand $nnn in name + my ($file) = @_; + my $fileexp = $file; + + while($fileexp =~ /\$(\w+)/) { + if (exists $ENV{$1}) { + $fileexp = $` . $ENV{$1} . $'; + } else { + printf "pi_rri-E: environment variable \$%s not defined\n", $1; + $fileexp = $` . "\$?" . $1 . "?" . $'; + } + } + + return $fileexp; +} + +#------------------------------------------------------------------------------- + +sub print_fatal { + my ($msg) = @_; + print STDERR "pi_rri($curmode)-F: $msg\n"; + exit 1; +} + +#------------------------------------------------------------------------------- + +sub print_help { + print "usage: pi_rri\n"; + print " --help this message\n"; + print " --int force interactive mode\n"; + print " --trace trace\n"; + + printf "CPREF %2.2x\n", CPREF; + printf "NCOMM %2.2x\n", NCOMM; + printf "CESC %2.2x\n", CESC; + printf "CEN1 %2.2x\n", CEN1; + +} diff --git a/tools/bin/rm_dep b/tools/bin/rm_dep new file mode 100755 index 00000000..d8c8e812 --- /dev/null +++ b/tools/bin/rm_dep @@ -0,0 +1,13 @@ +#!/bin/sh +# $Id: rm_dep 311 2010-06-30 17:52:37Z mueller $ +# +# Revision History: +# Date Rev Version Comment +# 2010-04-26 284 1.1 add xargs -r to prevent rm errors on empty lists +# 2010-04-24 282 1.0 Initial version +# +for ftype in dep_ghdl dep_isim dep_xst dep_ucf_cpp +do + echo "---------- remove *.$ftype ----------------------------------------" + find -name "*.$ftype" | xargs --no-run-if-empty rm -v +done diff --git a/tools/bin/set_ftdi_lat b/tools/bin/set_ftdi_lat new file mode 100755 index 00000000..2a485242 --- /dev/null +++ b/tools/bin/set_ftdi_lat @@ -0,0 +1,34 @@ +#!/bin/sh +# $Id: set_ftdi_lat 311 2010-06-30 17:52:37Z mueller $ +# +# Usage: sudo $HOME/other/retro/trunk/bin/set_ftdi_lat USB0 1 +# +# Revision History: +# Date Rev Version Comment +# 2010-04-24 282 1.0 fix filename for retrieving old latency +# 2010-04-24 281 0.9 Initial version +# + +dev=${1:-USB0} +lat=${2:-1} + +file="/sys/bus/usb-serial/devices/tty$dev/latency_timer" + +if [ ! -r $file ] +then + echo "set_ftdi_lat-E: device $dev not available" + echo " $file not found" + exit 1 +fi + +if [ ! -w $file ] +then + echo "set_ftdi_lat-E: parameters for $dev not writable" + exit 1 +fi + +old=`cat $file` + +echo "Set latency for tty$dev: old=$old new=$lat" + +echo "$lat" > $file diff --git a/tools/bin/svn_set_ignore b/tools/bin/svn_set_ignore new file mode 100755 index 00000000..1aa2c148 --- /dev/null +++ b/tools/bin/svn_set_ignore @@ -0,0 +1,105 @@ +#!/usr/bin/perl -w +# $Id: svn_set_ignore 314 2010-07-09 17:38:41Z mueller $ +# +# Copyright 2007-2010 by Walter F.J. Mueller +# +# This program is free software; you may redistribute and/or modify it under +# the terms of the GNU General Public License as published by the Free +# Software Foundation, either version 2, 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 complete details. +# +# Revision History: +# 2010-04-26 284 1.0.1 add error check for GetOptions +# 2007-06-16 56 1.0 Initial version +# + +use 5.005; # require Perl 5.005 or higher +use strict; # require strict checking + +use Getopt::Long; + +sub do_dir; + +my @dirlist; +my @def_ipat; + +my %opts = (); + +GetOptions(\%opts, "dry-run") + or die "bad options"; + +if (@ARGV) { + push @dirlist, @ARGV; +} else { + @dirlist = `find -type d | grep -v "\.svn"`; + die "bad find|grep" if $?; +} + +open (CVSIG, ".cvsignore") or die "no top level .cvsigore found"; +@def_ipat = grep /.+/, ; +close (CVSIG); + +foreach (@dirlist) { chomp; do_dir($_); } + +#------------------------------------------------------------------------------- + +sub do_dir { + my ($dirname) = @_; + my @cur_ipat; + my @loc_ipat; + my @sum_ipat; + my @new_ipat; + my %ipat; + + return unless -d "$dirname/.svn"; + print "$dirname\n"; + open (SVN, "svn pg svn:ignore $dirname|") or die "failed to open svn pg pipe"; + @cur_ipat = grep /.+/, ; # prop get and drop empty lines + close (SVN); + + if ($dirname ne "." && -r "$dirname/.cvsignore") { + open (CVSIG, "$dirname/.cvsignore") + or die "failed to read local .cvsignore"; + @loc_ipat = grep /.+/, ; + close (CVSIG); + } + + push @sum_ipat, @def_ipat; + push @sum_ipat, @loc_ipat; + + foreach (@sum_ipat) { + if (exists $ipat{$_}) { + my $pat = $_; + chomp $pat; + print "duplicate ignore: $pat in $dirname\n"; + } else { + $ipat{$_} = 1; + push @new_ipat, $_; + } + } + + if (join("",@cur_ipat) ne join("",@new_ipat)) { + print "update svn:ignore for $dirname\n"; + print "old svn:ignore:\n"; + print " ", join " ",@cur_ipat if @cur_ipat; + print "local .cvsignore:\n"; + print " ", join " ",@loc_ipat if @loc_ipat; + print "new svn:ignore:\n"; + print " ", join " ",@new_ipat if @new_ipat; + + if (not exists $opts{"dry-run"}) { + open (TMP, ">/tmp/svn_set_ignore_$$") or die "failed to open tmp file"; + print TMP join "",@new_ipat; + close (TMP); + print `svn ps svn:ignore -F /tmp/svn_set_ignore_$$ $dirname`; + die "bad svn ps" if $?; + unlink "/tmp/svn_set_ignore_$$" or die "failed to delete tmp file"; + } + + } + +} diff --git a/tools/bin/tbw b/tools/bin/tbw new file mode 100755 index 00000000..c2321a34 --- /dev/null +++ b/tools/bin/tbw @@ -0,0 +1,254 @@ +#!/usr/bin/perl -w +# $Id: tbw 314 2010-07-09 17:38:41Z mueller $ +# +# Copyright 2007-2010 by Walter F.J. Mueller +# +# This program is free software; you may redistribute and/or modify it under +# the terms of the GNU General Public License as published by the Free +# Software Foundation, either version 2, 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 complete details. +# +# Revision History: +# Date Rev Version Comment +# 2010-05-23 294 1.2.2 handle tb_code's in non-local directories +# 2010-04-18 279 1.2.1 add -help and more text to print_usage() +# 2009-11-22 252 1.2 add ISim support +# 2007-09-15 82 1.1.1 test for ambigous matches of name arguments; for +# "suff=[l1;l2;..]" style inlines use linkname_tmp.tmp +# as filename +# 2007-09-09 81 1.1 add fifo setup to tbw; allow multiple action lines +# per target; support immediate mode data +# "[line1;line2;...]" values +# 2007-08-03 71 1.0.1 handle redefinition of existing symlink correctly +# 2007-06-30 62 1.0 Initial version +# +# 'test bench wrapper' to setup symlink refering to stimulus file(s) +# +# usage: tbw [file] [args] +# +# will look for file (default is _stim.dat) and setup a symlink +# _stim_dat to refer to it. All args are passed along to +# + +use 5.005; # require Perl 5.005 or higher +use strict; # require strict checking +use POSIX qw(mkfifo); +use FileHandle; + +my $tb_code; +my $is_isim; +my $is_isim_run; + +my @args_pos; # list of positional args +my @args_nam; # list of named args +my @file_dsc; # file descriptors from tbw.dat + +sub print_usage; + +autoflush STDOUT 1; # autoflush, so noting lost on exec later + +if (scalar(@ARGV) && $ARGV[0] =~ /^-*help$/) { # -help or --help given + print_usage; + exit 0; +} + +if (scalar(@ARGV) == 0) { + print "tbw-E: name of test bench code missing\n"; + print_usage; + exit 1; +} + +$tb_code = shift @ARGV; +my $tb_code_path = "."; +my $tb_code_name = $tb_code; +if ($tb_code =~ m|^(.*)/(.*)$|) { + $tb_code_path = $1; + $tb_code_name = $2; +} + +my $tb_code_stem = $tb_code_name; +$tb_code_stem =~ s/_[fst]sim$//; # drop _ssim,_fsim, or _tsim + +if ($tb_code_stem =~ /_ISim$/) { # is it an ISim executable ? + $is_isim = 1; + $tb_code_stem =~ s/_ISim$//; # drop _ISim + if (scalar(@ARGV) && $ARGV[0] eq "-run") { + $is_isim_run = 1; + shift @ARGV; + } +} + +if (not -e $tb_code) { + print "tbw-E: $tb_code not existing or not executable\n"; + print_usage; + exit 1; +} + +# +# read tbw.dat file in current directory or directory of executable +# + +my $tbwdat_file = "tbw.dat"; +$tbwdat_file = "$tb_code_path/tbw.dat" unless (-r "tbw.dat"); + +if (-r $tbwdat_file) { + my $ok = 0; + my $done = 0; + + open (TBW, $tbwdat_file) or die "failed to open $tbwdat_file: $!"; + while () { + chomp; + next if /^#/; + if (/^\s*\[([\.\/a-zA-Z0-9_]*)\]\s*$/) { + last if $done; + $ok = 0; + $ok = 1 if ($1 eq $tb_code || $1 eq $tb_code_stem); + } elsif (/^\s*([a-zA-Z0-9_]*)\s*=\s*([a-zA-Z0-9_.<>]*)\s*$/) { + if ($ok) { + push @file_dsc, {tag=>$1, val=>$2}; + $done = 1; + } + } + } +} + +# +# if no matching stanza found, setup default _stim linkage +# + +unless (scalar (@file_dsc)) { + push @file_dsc, {tag=>$tb_code_stem . "_stim", + val=>$tb_code_stem . "_stim.dat"}; +} + +# +# now process argument list +# + +{ + my $ind = 0; + while (scalar(@ARGV)>0 && not $ARGV[0] =~ /^-/) { + my $arg = shift @ARGV; + my $ok; + if ($arg =~ /([a-zA-Z0-9_]*)=(.*)/) { # named argument + my $tag = $1; + my $val = $2; + foreach my $dsc (@file_dsc) { + if ($dsc->{tag} =~ /$tag$/) { + $dsc->{val} = $val; + $ok += 1; + } + } + if ($ok == 0) { + print STDERR "tbw-F: can't match named argument: $arg\n"; + exit 1; + } elsif ($ok > 1) { + print STDERR "tbw-F: ambiguous match for named argument: $arg\n"; + exit 1; + } + + } else { # positional argument + if ($ind < scalar(@file_dsc)) { + $file_dsc[$ind]->{val} = $arg; + } else { + print STDERR "tbw-F: too many positional arguments: $arg\n"; + exit 1; + } + $ind += 1; + } + } +} + +# +# now handle all specified file descriptors +# + +foreach my $dsc (@file_dsc) { + my $tag = $dsc->{tag}; + my $val = $dsc->{val}; + if ($val eq "") { # handle FIFO's + next if (-p $tag); + print "tbw-I: create FIFO $tag\n"; + mkfifo($tag, 0666) || die "can't mkfifo $tag: $!"; + + } else { # handle link to file cases + + if ($val =~ /^\[(.*)\]$/) { # immediate data case: "[line1;line2;...]" + my @lines = split /;/, $1; + my $fname = "$tag\_tmp.tmp"; + open TFILE,">$fname" or die "can't create temporary file $fname: $!"; + foreach (@lines) { + s/^\s*//; + s/\s*$//; + print TFILE "$_\n"; + } + close TFILE; + $val = $fname; + + } else { + unlink "$tag\_tmp.tmp" if (-e "$tag\_tmp.tmp"); # remove old .tmp file + $val = "/dev/null" if ($val eq ""); # null file case + } + + if (not -r $val) { + print "tbw-F: file for $tag not existing or not readable: $val\n"; + exit 1; + } + if (-l $tag) { + my $cur_link = readlink $tag; + if ($cur_link ne $val) { + print "tbw-I: redefine $tag -> $val\n"; + unlink $tag + or die "failed to unlink: $!"; + symlink $val, $tag + or die "failed to symlink 1: $!"; + } + } else { + if (-e $tag) { + print "tbw-F: $tag exists but is not a symlink\n"; + exit 1; + } else { + print "tbw-I: define $tag -> $val\n"; + symlink $val, $tag + or die "failed to symlink 2: $!"; + } + } + } +} + +# +# here all ok, finally exec test bench +# + +if ($is_isim_run) { # handle for isim 'run all' + my $cmd = $tb_code . " " . join " ",@ARGV; + open (ISIM_RUN, "| $cmd") + or die "failed to open process pipe to isim: $!"; + print ISIM_RUN "run all\n"; + print ISIM_RUN "quit\n"; + close (ISIM_RUN) + or die "failed to close process pipe to isim: $!"; + +} else { # otherwise just exec + exec $tb_code,@ARGV + or die "failed to exec: $!"; +} + +# ---------------------------------------------------------------------------- +sub print_usage { + print "usage: tbw [-run] [filedefs] [opts]\n"; + print " -run for _ISim tb's, runs the tb with a 'run all' command\n"; + print " filedefs define tb input, either filename in tbw.dat order or\n"; + print " tag=name or tag=[] pairs with tag matching one in in\n"; + print " tbw.dat. The [] form allows to give data inline, e.g.\n"; + print " like \"_conf=[.rpmon 1]\"\n"; + print " opts are all other options starting with a '-', they are passed\n"; + print " to the testbench. Some useful ghdl options are:\n"; + print " --wave=x.ghw\n"; + print " --stack-max-size=16384\n"; + print " --stop-time=1ns --disp-time --trace-processes\n"; +} diff --git a/tools/bin/telnet_starter b/tools/bin/telnet_starter new file mode 100755 index 00000000..5c24e52c --- /dev/null +++ b/tools/bin/telnet_starter @@ -0,0 +1,98 @@ +#!/usr/bin/perl -w +# $Id: telnet_starter 314 2010-07-09 17:38:41Z mueller $ +# +# Copyright 2009-2010 by Walter F.J. Mueller +# +# This program is free software; you may redistribute and/or modify it under +# the terms of the GNU General Public License as published by the Free +# Software Foundation, either version 2, 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 complete details. +# +# Revision History: +# 2010-07-04 312 1.0.3 correct telnet_wrapper path +# 2010-04-26 284 1.0.2 add error check for GetOptions +# 2009-11-08 248 1.0.1 proper -h handling & text; add -t support; +# 2009-11-07 247 1.0 Initial version +# + +use 5.005; # require Perl 5.005 or higher +use strict; # require strict checking + +use Getopt::Long; + +my %opts = (); +GetOptions(\%opts, "h", "t:s", "d:s", "s", "w", "l") + or die "bad options"; + +if (exists $opts{h}) { + print "usage: telnet_starter [-h] [-t type] [-d type] [-s] [-w] [-l]\n"; + print " -h help, print this text and quit\n"; + print " -t term set terminal type, vt100 or vt52 (def: vt100)\n"; + print " -d dev set device type, DLx or DZx for x'the line (def: DL0)\n"; + print " -s use simh ports, default is to use rri ports\n"; + print " -w use wide 132 column screen (default 80 columns)\n"; + print " -l use long 48 lines screen (default 24 lines)\n"; + exit 0; +} + +my $emu = "xterm"; +my $telnet = $ENV{"RETROBASE"} . "/tools/bin/telnet_wrapper"; + +my @args; +my $term = "vt100"; +my $dev = "DL"; +my $line = 0; +my $port; +my $title; + +if (exists $opts{t}) { + if ($opts{t} =~ m{^(vt100|vt52)$} ) { + $term = $opts{t}; + } else { + printf "unsupported terminal type: %s\n", $opts{t}; + exit 1; + } +} + +if (exists $opts{d}) { + if ($opts{d} =~ m{^(DL|DZ)(\d*)$}i ) { + $dev = uc $1; + $line = int $2; + } else { + printf "unsupported device type: %s\n", $opts{d}; + exit 1; + } +} + +if (exists $opts{s}) { # simh ports + $port = 5670 if ($dev eq "DL"); + $port = 5671 if ($dev eq "DZ"); + $title = sprintf "\"%s %s\"", $dev, $term; +} else { # rri ports + $port = 8000+$line if ($dev eq "DL"); + $port = 8002+$line if ($dev eq "DZ"); + $title = sprintf "\"%s%d %s\"", $dev, $line, $term; +} + +my $geo_w = 80; +my $geo_l = 24; +$geo_w = 132 if exists $opts{w}; +$geo_l = 48 if exists $opts{l}; + +push @args, "-j", "-rightbar", "-sb", "-sl", "500"; +push @args, "-bg", "gray90", "-fg", "black"; +push @args, "-ti", $term; +push @args, "-geo", sprintf("%dx%d", $geo_w, $geo_l); +push @args, "-T", $title; +push @args, "-e", $telnet, "localhost", sprintf("%d",$port); + +print $emu, " ", join " ",@args, "\n"; + +my $rc = system $emu, @args; +if ($rc != 0) { + print STDERR "xterm failed with rc=$rc\n"; +} diff --git a/tools/bin/telnet_wrapper b/tools/bin/telnet_wrapper new file mode 100755 index 00000000..e1929593 --- /dev/null +++ b/tools/bin/telnet_wrapper @@ -0,0 +1,54 @@ +#!/usr/bin/perl -w +# $Id: telnet_wrapper 314 2010-07-09 17:38:41Z mueller $ +# +# Copyright 2009- by Walter F.J. Mueller +# +# This program is free software; you may redistribute and/or modify it under +# the terms of the GNU General Public License as published by the Free +# Software Foundation, either version 2, 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 complete details. +# +# Revision History: +# 2009-11-07 246 1.0 Initial version +# + +use 5.005; # require Perl 5.005 or higher +use strict; # require strict checking + +if (scalar(@ARGV) != 2) { + print STDERR "usage: telnet_wrapper host port\n"; + exit 1; +} + +my $host = $ARGV[0]; +my $port = $ARGV[1]; + +print "$host $port\n"; + +my $telnet = `which telnet`; +chomp $telnet; + +while(1) { + my $rc = system $telnet, $host, $port; + if ($rc != 0) { + print STDERR "telnet failed with rc=$rc\n"; + } + print "enter q or <^D> to quit, otherwise reconnect: "; + my $buf; + my $nc = read STDIN, $buf, 1; + if (not defined $nc) { + print "\n"; + exit 1; + } + if ($nc == 0) { + print "\n"; + exit 0; + } + if ($buf eq "q") { + exit 0; + } +} diff --git a/tools/bin/tmuconv b/tools/bin/tmuconv new file mode 100755 index 00000000..e34f739e --- /dev/null +++ b/tools/bin/tmuconv @@ -0,0 +1,889 @@ +#!/usr/bin/perl -w +# $Id: tmuconv 314 2010-07-09 17:38:41Z mueller $ +# +# Copyright 2008-2010 by Walter F.J. Mueller +# +# This program is free software; you may redistribute and/or modify it under +# the terms of the GNU General Public License as published by the Free +# Software Foundation, either version 2, 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 complete details. +# +# Revision History: +# Date Rev Version Comment +# 2010-06-26 309 1.0.8 add ibimres.cacc/racc handling +# 2010-04-26 284 1.0.7 add error check for GetOptions +# 2009-09-19 240 1.0.6 add more VFETCH addr defs; add 2nd DL11 defs +# 2009-06-04 223 1.0.5 add IIST and PC11 defs +# 2009-05-03 212 1.0.4 add defs for mmu par/pdr's and some unibus dev's +# 2008-12-14 177 1.0.3 add -t_ru; use dp_ireg_we_last; add ibus names +# 2008-11-30 174 1.0.2 SPUSH and VFETCH tags for em cycles; psw in id lines +# 2008-04-25 138 1.0.1 show ccc/scc for code 000257/000277 in disassembler +# 2008-04-19 137 1.0 Initial version +# +# Current fields in tmu_ofile: +# clkcycle:d +# cpu:o +# dp.pc:o +# dp.psw:o +# dp.ireg:o +# dp.ireg_we:b +# dp.ireg_we_last:b +# dp.dsrc:o +# dp.ddst:o +# dp.dtmp:o +# dp.dres:o +# dp.gpr_adst:o +# dp.gpr_mode:o +# dp.gpr_bytop:b +# dp.gpr_we:b +# vm.ibmreq.req:b +# vm.ibmreq.we:b +# vm.ibmreq.be0:b +# vm.ibmreq.be1:b +# vm.ibmreq.dip:b +# vm.ibmreq.cacc:b +# vm.ibmreq.racc:b +# vm.ibmreq.addr:o +# vm.ibmreq.din:o +# vm.ibsres.ack:b +# vm.ibsres.busy:b +# vm.ibsres.dout:o +# co.cpugo:b +# co.cpuhalt:b +# sy.emmreq.req:b +# sy.emmreq.we:b +# sy.emmreq.be:b +# sy.emmreq.cancel:b +# sy.emmreq.addr:o +# sy.emmreq.din:o +# sy.emsres.ack_r:b +# sy.emsres.ack_w:b +# sy.emsres.dout:o +# sy.chit:b +# + +use 5.005; # require Perl 5.005 or higher +use strict; # require strict checking +use FileHandle; + +use Getopt::Long; + +my %opts = (); + +GetOptions(\%opts, "help", "dump", "cdump", + "t_id", "t_ru", "t_em", "t_ib") + or die "bad options"; + +sub print_help; +sub do_file; +sub code2mnemo; +sub regmod; + +my @var_name; +my @var_type; +my @var_dec; +my @var_oct; +my %name; + +my @val_curr_text; +my @val_curr; +my @val_last; + +my @reg_05 = ("------","------","------","------","------","------", # set 0 + "------","------","------","------","------","------",); # set 1 +my @reg_sp = ("------","------","------","------"); # ksp,ssp,???,usp + +my $ind_dp_pc; +my $ind_dp_psw; +my $ind_dp_ireg; +my $ind_dp_ireg_we; +my $ind_dp_ireg_we_last; +my $ind_dp_dres; +my $ind_dp_gpr_adst; +my $ind_dp_gpr_mode; +my $ind_dp_gpr_bytop; +my $ind_dp_gpr_we; + +my $ind_vm_ibmreq_req; +my $ind_vm_ibmreq_we; +my $ind_vm_ibmreq_be0; +my $ind_vm_ibmreq_be1; +my $ind_vm_ibmreq_cacc; +my $ind_vm_ibmreq_racc; +my $ind_vm_ibmreq_addr; +my $ind_vm_ibmreq_din; +my $ind_vm_ibsres_ack; +my $ind_vm_ibsres_busy; +my $ind_vm_ibsres_dout; + +my $ind_sy_emmreq_req; +my $ind_sy_emmreq_we; +my $ind_sy_emmreq_be; +my $ind_sy_emmreq_cancel; +my $ind_sy_emmreq_addr; +my $ind_sy_emmreq_din; +my $ind_sy_emsres_ack_r; +my $ind_sy_emsres_ack_w; +my $ind_sy_emsres_dout; +my $ind_sy_chit; + +my @pdp11_opcode_tbl = ( + {code=>0000000, mask=>0000000, name=>"halt", type=>"0arg"}, + {code=>0000001, mask=>0000000, name=>"wait", type=>"0arg"}, + {code=>0000002, mask=>0000000, name=>"rti ", type=>"0arg"}, + {code=>0000003, mask=>0000000, name=>"bpt ", type=>"0arg"}, + {code=>0000004, mask=>0000000, name=>"iot ", type=>"0arg"}, + {code=>0000005, mask=>0000000, name=>"reset",type=>"0arg"}, + {code=>0000006, mask=>0000000, name=>"rtt ", type=>"0arg"}, + {code=>0000007, mask=>0000000, name=>"!!mfpt", type=>"0arg"}, + {code=>0000100, mask=>0000077, name=>"jmp ", type=>"1arg"}, + {code=>0000200, mask=>0000007, name=>"rts ", type=>"1reg"}, + {code=>0000230, mask=>0000007, name=>"spl ", type=>"spl"}, + {code=>0000240, mask=>0000017, name=>"cl", type=>"ccop"}, + {code=>0000260, mask=>0000017, name=>"se", type=>"ccop"}, + {code=>0000300, mask=>0000077, name=>"swap", type=>"1arg"}, + {code=>0000400, mask=>0000377, name=>"br ", type=>"br"}, + {code=>0001000, mask=>0000377, name=>"bne ", type=>"br"}, + {code=>0001400, mask=>0000377, name=>"beq ", type=>"br"}, + {code=>0002000, mask=>0000377, name=>"bge ", type=>"br"}, + {code=>0002400, mask=>0000377, name=>"blt ", type=>"br"}, + {code=>0003000, mask=>0000377, name=>"bgt ", type=>"br"}, + {code=>0003400, mask=>0000377, name=>"ble ", type=>"br"}, + {code=>0004000, mask=>0000777, name=>"jsr ", type=>"jsr"}, + {code=>0005000, mask=>0000077, name=>"clr ", type=>"1arg"}, + {code=>0005100, mask=>0000077, name=>"com ", type=>"1arg"}, + {code=>0005200, mask=>0000077, name=>"inc ", type=>"1arg"}, + {code=>0005300, mask=>0000077, name=>"dec ", type=>"1arg"}, + {code=>0005400, mask=>0000077, name=>"neg ", type=>"1arg"}, + {code=>0005500, mask=>0000077, name=>"adc ", type=>"1arg"}, + {code=>0005600, mask=>0000077, name=>"sbc ", type=>"1arg"}, + {code=>0005700, mask=>0000077, name=>"tst ", type=>"1arg"}, + {code=>0006000, mask=>0000077, name=>"ror ", type=>"1arg"}, + {code=>0006100, mask=>0000077, name=>"rol ", type=>"1arg"}, + {code=>0006200, mask=>0000077, name=>"asr ", type=>"1arg"}, + {code=>0006300, mask=>0000077, name=>"asl ", type=>"1arg"}, + {code=>0006400, mask=>0000077, name=>"mark", type=>"mark"}, + {code=>0006500, mask=>0000077, name=>"mfpi", type=>"1arg"}, + {code=>0006600, mask=>0000077, name=>"mtpi", type=>"1arg"}, + {code=>0006700, mask=>0000077, name=>"sxt ", type=>"1arg"}, + {code=>0007000, mask=>0000077, name=>"!!csm", type=>"1arg"}, + {code=>0007200, mask=>0000077, name=>"!!tstset",type=>"1arg"}, + {code=>0007300, mask=>0000077, name=>"!!wrtlck",type=>"1arg"}, + {code=>0010000, mask=>0007777, name=>"mov ", type=>"2arg"}, + {code=>0020000, mask=>0007777, name=>"cmp ", type=>"2arg"}, + {code=>0030000, mask=>0007777, name=>"bit ", type=>"2arg"}, + {code=>0040000, mask=>0007777, name=>"bic ", type=>"2arg"}, + {code=>0050000, mask=>0007777, name=>"bis ", type=>"2arg"}, + {code=>0060000, mask=>0007777, name=>"add ", type=>"2arg"}, + {code=>0070000, mask=>0000777, name=>"mul ", type=>"rdst"}, + {code=>0071000, mask=>0000777, name=>"div ", type=>"rdst"}, + {code=>0072000, mask=>0000777, name=>"ash ", type=>"rdst"}, + {code=>0073000, mask=>0000777, name=>"ashc", type=>"rdst"}, + {code=>0074000, mask=>0000777, name=>"xor ", type=>"rdst"}, + {code=>0077000, mask=>0000777, name=>"sob ", type=>"sob"}, + {code=>0100000, mask=>0000377, name=>"bpl ", type=>"br"}, + {code=>0100400, mask=>0000377, name=>"bmi ", type=>"br"}, + {code=>0101000, mask=>0000377, name=>"bhi ", type=>"br"}, + {code=>0101400, mask=>0000377, name=>"blos", type=>"br"}, + {code=>0102000, mask=>0000377, name=>"bvc ", type=>"br"}, + {code=>0102400, mask=>0000377, name=>"bvs ", type=>"br"}, + {code=>0103000, mask=>0000377, name=>"bcc ", type=>"br"}, + {code=>0103400, mask=>0000377, name=>"bcs ", type=>"br"}, + {code=>0104000, mask=>0000377, name=>"emt ", type=>"trap"}, + {code=>0104400, mask=>0000377, name=>"trap", type=>"trap"}, + {code=>0105000, mask=>0000077, name=>"clrb", type=>"1arg"}, + {code=>0105100, mask=>0000077, name=>"comb", type=>"1arg"}, + {code=>0105200, mask=>0000077, name=>"incb", type=>"1arg"}, + {code=>0105300, mask=>0000077, name=>"decb", type=>"1arg"}, + {code=>0105400, mask=>0000077, name=>"negb", type=>"1arg"}, + {code=>0105500, mask=>0000077, name=>"adcb", type=>"1arg"}, + {code=>0105600, mask=>0000077, name=>"sbcb", type=>"1arg"}, + {code=>0105700, mask=>0000077, name=>"tstb", type=>"1arg"}, + {code=>0106000, mask=>0000077, name=>"rorb", type=>"1arg"}, + {code=>0106100, mask=>0000077, name=>"rolb", type=>"1arg"}, + {code=>0106200, mask=>0000077, name=>"asrb", type=>"1arg"}, + {code=>0106300, mask=>0000077, name=>"aslb", type=>"1arg"}, + {code=>0106400, mask=>0000077, name=>"!!mtps", type=>"1arg"}, + {code=>0106500, mask=>0000077, name=>"mfpd", type=>"1arg"}, + {code=>0106600, mask=>0000077, name=>"mtpd", type=>"1arg"}, + {code=>0106700, mask=>0000077, name=>"!!mfps", type=>"1arg"}, + {code=>0110000, mask=>0007777, name=>"movb", type=>"2arg"}, + {code=>0120000, mask=>0007777, name=>"cmpb", type=>"2arg"}, + {code=>0130000, mask=>0007777, name=>"bitb", type=>"2arg"}, + {code=>0140000, mask=>0007777, name=>"bicb", type=>"2arg"}, + {code=>0150000, mask=>0007777, name=>"bisb", type=>"2arg"}, + {code=>0160000, mask=>0007777, name=>"sub ", type=>"2arg"}, + {code=>0170000, mask=>0000000, name=>"!!cfcc", type=>"0arg"}, + {code=>0170001, mask=>0000000, name=>"!!setf", type=>"0arg"}, + {code=>0170011, mask=>0000000, name=>"!!setd", type=>"0arg"}, + {code=>0170002, mask=>0000000, name=>"!!seti", type=>"0arg"}, + {code=>0170012, mask=>0000000, name=>"!!setl", type=>"0arg"}, + {code=>0170100, mask=>0000077, name=>"!!ldfps",type=>"1fpp"}, + {code=>0170200, mask=>0000077, name=>"!!stfps",type=>"1fpp"}, + {code=>0170300, mask=>0000077, name=>"!!stst", type=>"1fpp"}, + {code=>0170400, mask=>0000077, name=>"!!clrf", type=>"1fpp"}, + {code=>0170500, mask=>0000077, name=>"!!tstf", type=>"1fpp"}, + {code=>0170600, mask=>0000077, name=>"!!absf", type=>"1fpp"}, + {code=>0170700, mask=>0000077, name=>"!!negf", type=>"1fpp"}, + {code=>0171000, mask=>0000377, name=>"!!mulf", type=>"rfpp"}, + {code=>0171400, mask=>0000377, name=>"!!modf", type=>"rfpp"}, + {code=>0172000, mask=>0000377, name=>"!!addf", type=>"rfpp"}, + {code=>0172400, mask=>0000377, name=>"!!ldf", type=>"rfpp"}, + {code=>0173000, mask=>0000377, name=>"!!subf", type=>"rfpp"}, + {code=>0173400, mask=>0000377, name=>"!!cmpf", type=>"rfpp"}, + {code=>0174000, mask=>0000377, name=>"!!stf", type=>"rfpp"}, + {code=>0174400, mask=>0000377, name=>"!!divf", type=>"rfpp"}, + {code=>0175000, mask=>0000377, name=>"!!stexp",type=>"rfpp"}, + {code=>0175400, mask=>0000377, name=>"!!stcif",type=>"rfpp"}, + {code=>0176000, mask=>0000377, name=>"!!stcfd",type=>"rfpp"}, + {code=>0176400, mask=>0000377, name=>"!!ldexp",type=>"rfpp"}, + {code=>0177000, mask=>0000377, name=>"!!ldcif",type=>"rfpp"}, + {code=>0177400, mask=>0000377, name=>"!!ldcdf",type=>"rfpp"} + ); + +my %pdp11_regs = ( # use simh naming convention + 177776=> "psw", + 177774=> "stklim", + 177772=> "pirq", + 177770=> "mbrk", + 177766=> "cpuerr", + 177764=> "sysid", + 177600=> "uipdr0", + 177602=> "uipdr1", + 177604=> "uipdr2", + 177606=> "uipdr3", + 177610=> "uipdr4", + 177612=> "uipdr5", + 177614=> "uipdr6", + 177616=> "uipdr7", + 177620=> "udpdr0", + 177622=> "udpdr1", + 177624=> "udpdr2", + 177626=> "udpdr3", + 177630=> "udpdr4", + 177632=> "udpdr5", + 177634=> "udpdr6", + 177636=> "udpdr7", + 177640=> "uipar0", + 177642=> "uipar1", + 177644=> "uipar2", + 177646=> "uipar3", + 177650=> "uipar4", + 177652=> "uipar5", + 177654=> "uipar6", + 177656=> "uipar7", + 177660=> "udpar0", + 177662=> "udpar1", + 177664=> "udpar2", + 177666=> "udpar3", + 177670=> "udpar4", + 177672=> "udpar5", + 177674=> "udpar6", + 177676=> "udpar7", + 177576=> "mmr2", + 177574=> "mmr1", + 177572=> "mmr0", + 177570=> "sdreg", # not a simh name !! + 177560=> "ti.csr", + 177562=> "ti.buf", + 177564=> "to.csr", + 177566=> "to.buf", + 177550=> "pr.csr", + 177552=> "pr.buf", + 177554=> "pp.csr", + 177556=> "pp.buf", + 177546=> "kl.csr", + 177514=> "lp.csr", + 177516=> "lp.buf", + 177500=> "ii.acr", + 177502=> "ii.adr", + 177400=> "rk.ds ", + 177402=> "rk.er ", + 177404=> "rk.cs ", + 177406=> "rk.wc ", + 177410=> "rk.ba ", + 177412=> "rk.da ", + 177414=> "rk.mr ", + 177416=> "rk.db ", + 177060=> "xor.cs", # XOR Tester + 176500=> "ti2.cs", + 176502=> "ti2.bu", + 176504=> "to2.cs", + 176506=> "to2.bu", + 174400=> "rl.cs ", + 174402=> "rl.ba ", + 174404=> "rl.da ", + 174406=> "rl.mp ", + 172540=> "kp.csr", + 172542=> "kp.buf", + 172544=> "kp.cnt", + 172520=> "tm.mts", + 172522=> "tm.mtc", + 172524=> "tm.brc", + 172526=> "tm.cma", + 172530=> "tm.mtd", + 172532=> "tm.rda", + 172516=> "mmr3", + 172200=> "sipdr0", + 172202=> "sipdr1", + 172204=> "sipdr2", + 172206=> "sipdr3", + 172210=> "sipdr4", + 172212=> "sipdr5", + 172214=> "sipdr6", + 172216=> "sipdr7", + 172220=> "sdpdr0", + 172222=> "sdpdr1", + 172224=> "sdpdr2", + 172226=> "sdpdr3", + 172230=> "sdpdr4", + 172232=> "sdpdr5", + 172234=> "sdpdr6", + 172236=> "sdpdr7", + 172240=> "sipar0", + 172242=> "sipar1", + 172244=> "sipar2", + 172246=> "sipar3", + 172250=> "sipar4", + 172252=> "sipar5", + 172254=> "sipar6", + 172256=> "sipar7", + 172260=> "sdpar0", + 172262=> "sdpar1", + 172264=> "sdpar2", + 172266=> "sdpar3", + 172270=> "sdpar4", + 172272=> "sdpar5", + 172274=> "sdpar6", + 172276=> "sdpar7", + 172300=> "kipdr0", + 172302=> "kipdr1", + 172304=> "kipdr2", + 172306=> "kipdr3", + 172310=> "kipdr4", + 172312=> "kipdr5", + 172314=> "kipdr6", + 172316=> "kipdr7", + 172320=> "kdpdr0", + 172322=> "kdpdr1", + 172324=> "kdpdr2", + 172326=> "kdpdr3", + 172330=> "kdpdr4", + 172332=> "kdpdr5", + 172334=> "kdpdr6", + 172336=> "kdpdr7", + 172340=> "kipar0", + 172342=> "kipar1", + 172344=> "kipar2", + 172346=> "kipar3", + 172350=> "kipar4", + 172352=> "kipar5", + 172354=> "kipar6", + 172356=> "kipar7", + 172360=> "kdpar0", + 172362=> "kdpar1", + 172364=> "kdpar2", + 172366=> "kdpar3", + 172370=> "kdpar4", + 172372=> "kdpar5", + 172374=> "kdpar6", + 172376=> "kdpar7", + 160100=> "dz.csr", + 160102=> "dz.mp2", + 160104=> "dz.tcr", + 160106=> "dz.mp6" +); + +autoflush STDOUT 1 if (-p STDOUT); # autoflush if output into pipe + +if (exists $opts{help}) { + print_help; + exit 0; +} + +foreach my $file (@ARGV) { + do_file($file); +} + + +#------------------------------------------------------------------------------- + +sub do_file { + my ($file) = @_; + + open IFILE,"<$file" or die "failed to open $file"; + + my $idec_cyc = 0; + my $change_cyc = 0; + my $emreq_cyc = 0; + my $emreq_str = ""; + my $ibreq_cyc = 0; + my $ibreq_typ = ""; + my $ibreq_str = ""; + my $ibreq_nam = ""; + + my $emcurr_we = 0; # curr em write enable (or undef) + my $emcurr_addr = undef; # curr em address + my $emlast_we = 0; # prev em write enable (or undef) + my $emlast_addr = undef; # prev em address + + while () { + chomp; + if (/^#\s+/) { + @var_name = (); + @var_type = (); + my $dsc_str = $'; + my @dsc_list = split /\s+/,$dsc_str; + foreach my $dsc (@dsc_list) { + if ($dsc =~ /^(.*):([bdo])$/) { + my $ind = scalar(@var_name); + $name{$1} = {ind=>$ind, + typ=>$2}; + push @var_name, $1; + push @var_type, $2; + push @var_dec, $ind if $2 eq "d"; + push @var_oct, $ind if $2 eq "o"; + } else { + print "tmuconv-E: bad descriptor $dsc\n"; + } + } + + $ind_dp_pc = $name{'dp.pc'}->{ind}; + $ind_dp_psw = $name{'dp.psw'}->{ind}; + $ind_dp_ireg = $name{'dp.ireg'}->{ind}; + $ind_dp_ireg_we = $name{'dp.ireg_we'}->{ind}; + $ind_dp_ireg_we_last = $name{'dp.ireg_we_last'}->{ind}; + $ind_dp_dres = $name{'dp.dres'}->{ind}; + $ind_dp_gpr_adst = $name{'dp.gpr_adst'}->{ind}; + $ind_dp_gpr_mode = $name{'dp.gpr_mode'}->{ind}; + $ind_dp_gpr_bytop = $name{'dp.gpr_bytop'}->{ind}; + $ind_dp_gpr_we = $name{'dp.gpr_we'}->{ind}; + + $ind_vm_ibmreq_req = $name{'vm.ibmreq.req'}->{ind}; + $ind_vm_ibmreq_we = $name{'vm.ibmreq.we'}->{ind}; + $ind_vm_ibmreq_be0 = $name{'vm.ibmreq.be0'}->{ind}; + $ind_vm_ibmreq_be1 = $name{'vm.ibmreq.be1'}->{ind}; + $ind_vm_ibmreq_cacc = $name{'vm.ibmreq.cacc'}->{ind}; + $ind_vm_ibmreq_racc = $name{'vm.ibmreq.racc'}->{ind}; + $ind_vm_ibmreq_addr = $name{'vm.ibmreq.addr'}->{ind}; + $ind_vm_ibmreq_din = $name{'vm.ibmreq.din'}->{ind}; + $ind_vm_ibsres_ack = $name{'vm.ibsres.ack'}->{ind}; + $ind_vm_ibsres_busy = $name{'vm.ibsres.busy'}->{ind}; + $ind_vm_ibsres_dout = $name{'vm.ibsres.dout'}->{ind}; + + $ind_sy_emmreq_req = $name{'sy.emmreq.req'}->{ind}; + $ind_sy_emmreq_we = $name{'sy.emmreq.we'}->{ind}; + $ind_sy_emmreq_be = $name{'sy.emmreq.be'}->{ind}; + $ind_sy_emmreq_cancel = $name{'sy.emmreq.cancel'}->{ind}; + $ind_sy_emmreq_addr = $name{'sy.emmreq.addr'}->{ind}; + $ind_sy_emmreq_din = $name{'sy.emmreq.din'}->{ind}; + $ind_sy_emsres_ack_r = $name{'sy.emsres.ack_r'}->{ind}; + $ind_sy_emsres_ack_w = $name{'sy.emsres.ack_w'}->{ind}; + $ind_sy_emsres_dout = $name{'sy.emsres.dout'}->{ind}; + $ind_sy_chit = $name{'sy.chit'}->{ind}; + + } else { + @val_last = @val_curr; + my $notfirst = scalar(@val_last) > 0; + + $_ =~ s/^\s*//; + $_ =~ s/\s*$//; + @val_curr = split /\s+/,$_; + if (scalar(@val_curr) != scalar(@var_name)) { + printf "tmuconv-E: value list length mismatch, seen %d, expected %d\n", + scalar(@val_curr), scalar(@var_name); + for (my $i=0; $i>11 & 01; + $ru_str = sprintf "%o %o%o %6.6o", $bytop, $rset, $adst, $dres; + $ru_str .= " "; + if ($adst eq "7") { + $ru_str .= "pc"; + } elsif ($adst eq "6") { + $reg_sp[$mode] = sprintf "%6.6o",$dres; + $ru_str .= $reg_sp[0]; + $ru_str .= ($mode == 0) ? "*" : " "; + $ru_str .= $reg_sp[1]; + $ru_str .= ($mode == 1) ? "*" : " "; + $ru_str .= $reg_sp[3]; + $ru_str .= ($mode == 3) ? "*" : " "; + $ru_str .= " ksp" if $mode eq "0"; + $ru_str .= " ssp" if $mode eq "1"; + $ru_str .= " usp" if $mode eq "3"; + } else { + my $rbase = ($rset==0) ? 0 : 6; + $reg_05[$rbase+$adst] = sprintf "%6.6o",$dres; + for (my $i=0; $i<6; $i++) { + $ru_str .= $reg_05[$rbase+$i]; + $ru_str .= ($adst==$i) ? "*" : " "; + } + $ru_str .= sprintf " r%o%o", $rset, $adst; + } + } + } +# +# handle t_em +# uses cycles with sy_emmreq_req = '1' +# sy_emsres_ack_r = '1' +# sy_emsres_ack_w = '1' +# sy_emsreq_cancel = '1' +# + if (exists $opts{t_em}) { + if ($val_curr[$ind_sy_emmreq_req]) { + $emreq_cyc = $cyc_curr; + $emreq_str = sprintf "%s %s %8.8o", + ($val_curr[$ind_sy_emmreq_we] ? "w" : "r"), + $val_curr[$ind_sy_emmreq_be], + $val_curr[$ind_sy_emmreq_addr]; + $emcurr_we = $val_curr[$ind_sy_emmreq_we]; + $emcurr_addr = $val_curr[$ind_sy_emmreq_addr]; + if ($emcurr_we) { + $emreq_str .= sprintf " %6.6o", $val_curr[$ind_sy_emmreq_din]; + } else { + $emreq_str .= " " x 7; + } + } + if ($val_curr[$ind_sy_emsres_ack_r] || + $val_curr[$ind_sy_emsres_ack_w] || + $val_curr[$ind_sy_emmreq_cancel]) { + $emres_str = sprintf "%s%s%s%s", + $val_curr[$ind_sy_emmreq_cancel], + $val_curr[$ind_sy_emsres_ack_r], + $val_curr[$ind_sy_emsres_ack_w], + $val_curr[$ind_sy_chit]; + if ($val_curr[$ind_sy_emmreq_cancel]) { + $emreq_str .= " cancel"; + $emcurr_we = undef; + } else { + if ($val_curr[$ind_sy_emsres_ack_r]) { + $emreq_str .= sprintf " %6.6o", $val_curr[$ind_sy_emsres_dout]; + } else { + $emreq_str .= " " x 7; + } + if (defined $emlast_we && $emcurr_we == $emlast_we) { + if ($emcurr_we && $emcurr_addr == $emlast_addr-2) { + $emtyp_str = "SPUSH"; + } elsif ((not $emcurr_we) && $emcurr_addr == $emlast_addr+2 && + $emcurr_addr < 0400 && ($emcurr_addr % 04) == 02) { + $emtyp_str = "VFETCH"; + $emtyp_str .= " 004 ill.inst" if ($emlast_addr == 0004); + $emtyp_str .= " 010 res.inst" if ($emlast_addr == 0010); + $emtyp_str .= " 014 BPT" if ($emlast_addr == 0014); + $emtyp_str .= " 020 IOT" if ($emlast_addr == 0020); + $emtyp_str .= " 030 EMT" if ($emlast_addr == 0030); + $emtyp_str .= " 034 TRAP" if ($emlast_addr == 0034); + $emtyp_str .= " 060 DL11-TTI" if ($emlast_addr == 0060); + $emtyp_str .= " 064 DL11-TTO" if ($emlast_addr == 0064); + $emtyp_str .= " 070 PC11-PTR" if ($emlast_addr == 0070); + $emtyp_str .= " 074 PC11-PTP" if ($emlast_addr == 0074); + $emtyp_str .= " 100 KW11-L" if ($emlast_addr == 0100); + $emtyp_str .= " 104 KW11-P" if ($emlast_addr == 0104); + $emtyp_str .= " 160 RL11" if ($emlast_addr == 0160); + $emtyp_str .= " 200 LP11" if ($emlast_addr == 0200); + $emtyp_str .= " 220 RK11" if ($emlast_addr == 0220); + $emtyp_str .= " 224 TM11" if ($emlast_addr == 0224); + $emtyp_str .= " 240 PIRQ" if ($emlast_addr == 0240); + $emtyp_str .= " 244 FPP exp" if ($emlast_addr == 0244); + $emtyp_str .= " 250 MMU trap" if ($emlast_addr == 0250); + $emtyp_str .= " 260 IIST" if ($emlast_addr == 0260); + $emtyp_str .= " 300 DL11-2-TTI" if ($emlast_addr == 0300); + $emtyp_str .= " 304 DL11-2-TTO" if ($emlast_addr == 0304); + } + } + } + $emlast_we = $emcurr_we; + $emlast_addr = $emcurr_addr; + } + } +# +# handle t_ib +# uses cycles with sy_ibmreq_req = '1' +# sy_ibsres_ack = '1' +# vm_ibsres_busy '1' -> '0' transition +# + if (exists $opts{t_ib}) { + if ($val_curr[$ind_vm_ibmreq_req]) { + my $addr_str = sprintf "%6.6o", $val_curr[$ind_vm_ibmreq_addr]; + $ibreq_cyc = $cyc_curr; + $ibreq_typ = sprintf "%s%s", + ($val_curr[$ind_vm_ibmreq_cacc] ? "c" : "-"), + ($val_curr[$ind_vm_ibmreq_racc] ? "r" : "-"); + $ibreq_str = sprintf "%s %s%s %s", + ($val_curr[$ind_vm_ibmreq_we] ? "w" : "r"), + $val_curr[$ind_vm_ibmreq_be1], + $val_curr[$ind_vm_ibmreq_be0], + $addr_str; + $ibreq_we = $val_curr[$ind_vm_ibmreq_we]; + $ibreq_act = 1; + if ($ibreq_we) { + $ibreq_str .= sprintf " %6.6o", $val_curr[$ind_vm_ibmreq_din]; + } else { + $ibreq_str .= " " x 7; + } + $ibreq_nam = $pdp11_regs{$addr_str}; + $ibreq_nam = "" if not defined $ibreq_nam; + } + + if ($val_curr[$ind_vm_ibsres_ack]) { + $ibreq_act = 0; + $ibres_str .= sprintf " %s", $val_curr[$ind_vm_ibsres_ack]; + if (not $ibreq_we) { + $ibreq_str .= sprintf " %6.6o", $val_curr[$ind_vm_ibsres_dout]; + } else { + $ibreq_str .= " " x 7; + } + } + + if ($ibreq_act && $val_curr[$ind_vm_ibsres_busy]==0) { + $ibres_str .= "no ACK, no BUSY"; + $ibreq_act = 0; + } + } + + print "$cyc_str id $id_str\n" if $id_str; + print "$cyc_str ru $ru_str\n" if $ru_str; + if ($emres_str) { + printf "$cyc_str em $emreq_str $emres_str (%d) $emtyp_str\n", + $cyc_curr-$emreq_cyc; + } + if ($ibres_str) { + printf "$cyc_str ib %s $ibreq_str $ibres_str (%d) $ibreq_nam\n", + $ibreq_typ, $cyc_curr-$ibreq_cyc; + } + } + } + + close IFILE; +} + +#------------------------------------------------------------------------------- + +sub code2mnemo { + my ($code) = @_; + + foreach my $ele (@pdp11_opcode_tbl) { + if (($code & (~($ele->{mask})) ) == $ele->{code}) { + my $name = $ele->{name}; + my $type = $ele->{type}; + my $str = $name; + if ($type eq "0arg") { + return $name; + + } elsif ($type eq "1arg" or $type eq "1fpp") { + my $dst = $code & 077; + my $dst_str = regmod($dst); + return "$name $dst_str"; + + } elsif ($type eq "2arg") { + my $src = ($code>>6) & 077; + my $dst = $code & 077; + my $src_str = regmod($src); + my $dst_str = regmod($dst); + return "$name $src_str,$dst_str"; + + } elsif ($type eq "rdst") { + my $reg = ($code>>6) & 07; + my $src = $code & 077; + my $src_str = regmod($src); + return "$name $src_str,r$reg"; + + } elsif ($type eq "1reg") { + my $reg = $code & 07; + my $reg_str = "r$reg"; + $reg_str = "sp" if $reg == 6; + $reg_str = "pc" if $reg == 7; + return "$name $reg_str"; + + } elsif ($type eq "br") { + my $off = $code & 0177; + my $sign = "+"; + if ($code & 0200) { + $off = -(((~$off) & 0177)+1); + $sign = "-"; + } + return sprintf "$name .%s%d.", $sign, abs(2*$off); + + } elsif ($type eq "sob") { + my $reg = ($code>>6) & 07; + my $off = $code & 077; + return sprintf "$name r%d,.-%d.", $reg, 2*$off; + + } elsif ($type eq "trap") { + my $off = $code & 0377; + return sprintf "$name %3.3o", $off; + + } elsif ($type eq "spl") { + my $off = $code & 07; + return sprintf "$name %d", $off; + + } elsif ($type eq "ccop") { + my $cc = $code & 017; + return "nop" if ($cc == 0); + return "ccc" if ($code == 0257); + return "scc" if ($code == 0277); + my $str = ""; + my $del = ""; + if ($code & 010) { $str .= $del . $name . "n", $del = "+" } + if ($code & 004) { $str .= $del . $name . "z", $del = "+" } + if ($code & 002) { $str .= $del . $name . "v", $del = "+" } + if ($code & 001) { $str .= $del . $name . "c", $del = "+" } + return $str; + + } elsif ($type eq "jsr") { + my $reg = ($code>>6) & 07; + my $dst = $code & 077; + my $dst_str = regmod($dst); + return "$name r$reg,$dst_str"; + + } elsif ($type eq "mark") { + my $off = $code & 077; + return sprintf "$name %3.3o", $off; + + } elsif ($type eq "rfpp") { + my $reg = ($code>>6) & 03; + my $dst = $code & 077; + my $dst_str = regmod($dst,"f"); + return "$name f$reg,$dst_str"; + + } else { + return "?type?"; + } + } + } + return "=inval="; +} + +#------------------------------------------------------------------------------- +sub regmod { + my ($regmod,$pref) = @_; + my $mod = ($regmod>>3) & 07; + my $reg = $regmod & 07; + + $pref = "r" if not defined $pref or $reg>5; + + my $reg_str = "r$reg"; + $reg_str = "sp" if $reg == 6; + $reg_str = "pc" if $reg == 7; + + if ($mod == 0) { # mode 0: Rx { Fx for float } + $reg_str = "f$reg" if defined $pref && $pref eq "f" && $reg<=5; + return $reg_str; + } elsif ($mod == 1) { # mode 1: (Rx) + return "($reg_str)"; + } elsif ($mod == 2 || $mod == 3) { # mode 2/3: (Rx)+ @(Rx)+ + my $ind = ($mod == 3) ? "@" : ""; + if ($reg != 7) { # if reg != pc + return "$ind($reg_str)+"; + } else { # if reg == pc + my $str = sprintf "$ind#nnn"; # 27 -> #nnn; 37 -> @#nnn + return $str; + } + } elsif ($mod == 4 || $mod == 5) { # mode 4/5: -(Rx) @-(Rx) + my $ind = ($mod == 5) ? "@" : ""; + return "$ind-($reg_str)"; + } elsif ($mod == 6 || $mod == 7) { # mode 6/7: nn(Rx) @nn(Rx) + my $ind = ($mod == 7) ? "@" : ""; + return "${ind}nnn($reg_str)"; + } +} + +#------------------------------------------------------------------------------- + +sub print_help { + print "usage: tmuconf file\n"; + print " --help this message\n"; + print " --dump dump all information\n"; + print " --cdump dump only changes relative to prev cycle\n"; + print " --t_id trace instruction decodes\n"; + print " --t_ru trace register updates\n"; + print " --t_em trace em transactions\n"; + print " --t_ib trace ib transactions\n"; +} diff --git a/tools/bin/vbomconv b/tools/bin/vbomconv new file mode 100755 index 00000000..c6633853 --- /dev/null +++ b/tools/bin/vbomconv @@ -0,0 +1,763 @@ +#!/usr/bin/perl -w +# $Id: vbomconv 314 2010-07-09 17:38:41Z mueller $ +# +# Copyright 2007-2010 by Walter F.J. Mueller +# +# This program is free software; you may redistribute and/or modify it under +# the terms of the GNU General Public License as published by the Free +# Software Foundation, either version 2, 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 complete details. +# +# Revision History: +# Date Rev Version Comment +# 2010-07-03 312 1.8.5 add --flist action +# 2010-06-03 299 1.8.4 generate ucf->ncd dependencies in dep_xst +# 2010-04-26 284 1.8.3 add _[sft]sim support for ISim +# 2009-11-28 253 1.8.2 fixup print_help...; +# 2009-11-22 252 1.8.1 add (export|dep)_isim, full ISim support; +# add [isim] [sim], allow tag lists like [ghdl,isim]; +# --trace and messages to STDERR; +# 2009-11-20 251 1.8 add isim_prj, first ISim support +# 2008-03-09 124 1.7.3 add in .dep_(ghdl|xst) all dep on vbom dependencies +# target now also dependant on .dep_ file +# 2008-03-02 122 1.7.2 add @lib: directive to include UNISIM +# 2007-12-17 102 1.7.1 fix @ucf_cpp logic. +# 2007-12-16 101 1.7 add @ucf_cpp pseudo tag (handle cpp'ed ucf files) +# 2007-11-25 98 1.6.1 drop trailing blanks on input lines +# 2007-11-02 94 1.6 added (xst|ghdl)_export +# 2007-10-26 92 1.5.1 emit '--no-vital-checks' for --ghdl_m for _[sft]sim +# 2007-10-14 98 1.5 handle .exe files under cycwin properly +# 2007-09-15 82 1.4 handle C source objects properly +# 2007-08-10 72 1.3 add [xst], [ghdl] prefix support +# 2007-07-22 68 1.2 add "tag = val"; list files in 'ready to analyse' +# order; add --ghdl_a option +# 2007-07-08 65 1.1 add "tag : names"; inferral of _[ft]sim vboms +# 2007-07-06 64 1.0 Initial version + +use 5.005; # require Perl 5.005 or higher +use strict; # require strict checking +use FileHandle; + +use Getopt::Long; + +my %opts = (); + +GetOptions(\%opts, "help", "trace", + "dep_xst", "dep_ghdl", "dep_isim", + "xst_prj", "isim_prj", + "ghdl_a", "ghdl_a_cmd", + "ghdl_i", "ghdl_i_cmd", + "ghdl_m", "ghdl_m_cmd", + "xst_export=s", + "ghdl_export=s", + "isim_export=s", + "flist") || exit 1; + +sub print_help; +sub read_vbom; +sub scan_vbom; +sub copy_edir; +sub write_vbomdep; + +my @vbom_list; +my @file_list; +my %vbom_tbl; +my %file_tbl; +my %read_tbl; +my %conf_tbl; +my @ucf_cpp_list; +my $is_xst = 0; # XST synthesis target +my $is_ghdl = 0; # ghdl simulation target +my $is_isim = 0; # ISim simulation target +my $is_sim = 0; # simulation target (generic) +my $is_any = 0; +my $nactions = 0; +my $top_vbom; +my $stem; +my $top; +my $top_done = 0; +my $has_unisim; +my $has_simprim; +my $is_ssim; +my $is_fsim; +my $is_tsim; +my $do_trace = exists $opts{trace}; +my $level; + +autoflush STDOUT 1; # autoflush, so noting lost on exec later + +if (exists $opts{help}) { + print_help; + exit 0; +} + +# ensure that one and only one vbom is specified + +if (scalar(@ARGV) != 1) { + print STDERR "%vbomconv-E: only one vbom file name allowed\n\n"; + print_help; + exit 1; +} + +# check that only one action is defined, mark xst, gdhl, or isim class + +foreach (keys %opts) { + $nactions += 1 unless ($_ eq "trace"); + $is_xst = 1 if ($_ eq "dep_xst"); + $is_ghdl = 1 if ($_ eq "dep_ghdl"); + $is_isim = 1 if ($_ eq "dep_isim"); + $is_xst = 1 if ($_ =~ /^xst_/); + $is_ghdl = 1 if ($_ =~ /^ghdl_/); + $is_isim = 1 if ($_ =~ /^isim_/); + $is_any = 1 if ($_ eq "flist"); +} + +$is_sim = $is_ghdl | $is_isim; + +print STDERR "-- [xst] active\n" if $do_trace && $is_xst; +print STDERR "-- [ghdl] active\n" if $do_trace && $is_ghdl; +print STDERR "-- [isim] active\n" if $do_trace && $is_isim; +print STDERR "-- [sim] active\n" if $do_trace && $is_sim; + +if ($nactions > 1) { + print STDERR "%vbomconv-E: only one action qualifier allowed\n\n"; + print_help; + exit 1; +} + +$top_vbom = $ARGV[0]; + +$top_vbom .= ".vbom" unless $top_vbom =~ m{\.vbom$}; + +$stem = $top_vbom; +$stem =~ s{\..*$}{}; + +$top = $stem; +$top =~ s{^.*/}{}; + +# now prepare virtual _fsim and _tsim vbom's +# they are inferred from the _ssim vbom's + +if ($top_vbom =~ m{_ssim\.vbom$}) { # detect _ssim + $is_ssim = 1; +} +if ($top_vbom =~ m{_fsim\.vbom$}) { # map _fsim -> _ssim + $is_fsim = 1; + $top_vbom =~ s{_fsim\.vbom$}{_ssim.vbom}; +} +if ($top_vbom =~ m{_tsim\.vbom$}) { # map _tsim -> _ssim + $is_tsim = 1; + $top_vbom =~ s{_tsim\.vbom$}{_ssim.vbom}; +} + +# traverse all vbom's start with command line argument + +push @vbom_list, $top_vbom; + +while (@vbom_list) { + my $cur_vbom = shift @vbom_list; + read_vbom($cur_vbom); +} + +# traverse internal vbom representation to build file table + +scan_vbom($top_vbom); + +# sort file table, build file list (decreasing rank) + +my @pair_list; +foreach (keys %file_tbl) { + push @pair_list, [$file_tbl{$_}, $_]; +} + +@file_list = map {$_->[1]} sort {$b->[0] <=> $a->[0]} @pair_list; + +# now generate output and actions, depending on options given + +# --trace ------------------------------------------------------------ + +if ($do_trace) { + print STDERR "\n"; + print STDERR "configuration table:\n"; + foreach (sort keys %conf_tbl) { + print STDERR " $_ = $conf_tbl{$_}\n"; + } + print STDERR "final file_list:\n"; + foreach (@file_list) { + print STDERR " $_\n"; + } + print STDERR "properties:\n"; + print STDERR " \@top: $top\n"; +} + +# --ghdh_a -- ghdl analysis command ---------------------------------- + +if (exists $opts{ghdl_a} || exists $opts{ghdl_a_cmd}) { + foreach (@file_list) { + my $file = $_; + my $cmd = "ghdl -a"; + $cmd .= ' -P$XILINX/ghdl/unisim' if $has_unisim; + $cmd .= ' -P$XILINX/ghdl/simprim' if $has_simprim; + $cmd .= " --ieee=synopsys"; + $cmd .= " $file"; + print "$cmd\n"; + if (exists $opts{ghdl_a}) { + my $wrc = system "/bin/sh", "-c", $cmd; + if ($wrc != 0) { + my $rc = int($wrc/256); + if ($rc == 0) { + my $sig = $wrc % 256; + print STDERR "%vbomconv-I compilation aborted by signal $sig\n"; + exit(1); + } else { + print STDERR "%vbomconv-I compilation failed (rc=$rc) $?\n"; + exit($rc); + } + } + } + } +} + +# --ghdh_i -- ghdl inspection command -------------------------------- + +if (exists $opts{ghdl_i} || exists $opts{ghdl_i_cmd}) { + my %ghdl_work; + + # read ghdl "work-obj93.cf" file. It has the format + # file . "" "" "ghdl -i or -a date>": + # entity at nn( nn) + nn on nn; + # architecture of at nn( nn) + nn on nn; + + if (-r "work-obj93.cf") { + open (WFILE, "work-obj93.cf") or + die "can't open for read work-obj93.cf: $!"; + while () { + if (m{^file \. \"(.*?)\"}) { + $ghdl_work{$1} = 1; + } + } + close (WFILE); + } + + my $cmd = "ghdl -i"; + my $nfile = 0; + + foreach (@file_list) { + next if /\.c$/; # skip C sources, only vhd handled + if (not exists $ghdl_work{$_}) { + $cmd .= " \\\n $_"; + $nfile += 1; + } + } + + if ($nfile) { + print "$cmd\n"; + if (exists $opts{ghdl_i}) { + exec "/bin/sh", "-c", $cmd; + die "failed to exec /bin/sh -c $cmd: $!"; + } + } else { + print "# $cmd ## all files already inspected\n"; + } +} + +# --ghdh_m -- ghdl make command -------------------------------------- +# Note: the 'buildin' make used by the -m option of ghdl does not +# check for object files linked with -Wl, e.g. vhpi objects. +# To force a re-elaboration the old executable is deleted first. +# If used from make with proper dependencies, this will just do +# the right thing. + +if (exists $opts{ghdl_m} || exists $opts{ghdl_m_cmd} ) { + my $cmd = ""; + + if (-r "$stem.exe") { # check for .exe, in case we are in cygwin + $cmd .= "rm $stem.exe\n"; # rm old executable to force elaboration + } elsif (-r $stem) { # otherwise + $cmd .= "rm $stem\n" ; # rm old executable to force elaboration + } + + $cmd .= "ghdl -m"; + $cmd .= " -o $stem"; + $cmd .= ' -P$XILINX/ghdl/unisim' if $has_unisim; + $cmd .= ' -P$XILINX/ghdl/simprim' if $has_simprim; + $cmd .= " --ieee=synopsys"; + $cmd .= " --no-vital-checks" if $is_ssim or $is_fsim or $is_tsim; + + foreach (@file_list) { + next unless /\.c$/; # C source ? + my $ofile = $_; # copy to break alias for following s/// + $ofile =~ s{^.*/}{}; # remove directory path + $ofile =~ s/\.c$/.o/; # add clause to link C source object file + $cmd .= " -Wl,$ofile"; + } + $cmd .= " $top"; + print "$cmd\n"; + if (exists $opts{ghdl_m}) { + exec "/bin/sh", "-c", $cmd; + die "failed to exec /bin/sh -c $cmd: $!"; + } +} + +# --xst_prj ---------------------------------------------------------- + +if (exists $opts{xst_prj}) { + foreach (@file_list) { + print "vhdl work $_\n"; +# print "work $_\n"; # for ISE 11.2 S-6/V-6 compilations + } +} + +# --isim_prj --------------------------------------------------------- + +if (exists $opts{isim_prj}) { + foreach (@file_list) { + print "vhdl work $_\n"; + } +} + +# --dep_xst ---------------------------------------------------------- + +if (exists $opts{dep_xst}) { + print "#\n"; + print "$stem.ngc : $stem.dep_xst\n"; + print "#\n"; + foreach (@file_list) { + print "$stem.ngc : $_\n"; + } + # handle cpp preprocessed ucf's + foreach (@ucf_cpp_list) { + my $file = $_; + $file =~ s/\.ucf$//; + print "#\n"; + print "$file.ncd : $file.ucf\n"; + print "include $file.dep_ucf_cpp\n"; + } + # handle plain ucf's + if (scalar(@ucf_cpp_list)==0 && -r "$stem.ucf") { + print "#\n"; + print "$stem.ncd : $stem.ucf\n"; + } + write_vbomdep("$stem.dep_xst"); +} + +# --dep_ghdl --------------------------------------------------------- + +if (exists $opts{dep_ghdl}) { + + my $stem_fsim = $stem; + my $stem_tsim = $stem; + $stem_fsim =~ s/_ssim$/_fsim/; + $stem_tsim =~ s/_ssim$/_tsim/; + + print "#\n"; + print "$stem : $stem.dep_ghdl\n"; + if ($is_ssim) { + print "$stem_fsim : $stem.dep_ghdl\n"; + print "$stem_tsim : $stem.dep_ghdl\n"; + } + print "#\n"; + + foreach (@file_list) { + if (/\.c$/) { + my $ofile = $_; # copy to break alias for following s/// + $ofile =~ s{^.*/}{}; # remove directory path + $ofile =~ s/\.c$/.o/; # object file name + print "$stem : $ofile\n"; # depend on C source object file + # C source object compilation dependence + open (ODEPFILE, ">$ofile.dep_ghdl") or + die "can't write $ofile.dep_ghdl: $!"; + print ODEPFILE "$ofile : $_\n"; + print ODEPFILE "\t\$(COMPILE.c) \$(OUTPUT_OPTION) \$<\n"; + close ODEPFILE; + } else { + print "$stem : $_\n"; + } + } + + if ($is_ssim) { + + foreach (@file_list) { + my $file = $_; # copy to break alias for following s/// + if (/\.c$/) { + $file =~ s{^.*/}{}; # remove directory path + $file =~ s/\.c$/.o/; # depend on object file for C sources + } else { + $file =~ s/_ssim\.vhd$/_fsim.vhd/; + } + print "$stem_fsim : $file\n"; + } + + foreach (@file_list) { + my $file = $_; # copy to break alias for following s/// + if (/\.c$/) { + $file =~ s{^.*/}{}; # remove directory path + $file =~ s/\.c$/.o/; # depend on object file for C sources + } else { + $file =~ s/_ssim\.vhd$/_tsim.vhd/; + } + print "$stem_tsim : $file\n"; + } + + } + + write_vbomdep("$stem.dep_ghdl"); + +} + +# --dep_isim --------------------------------------------------------- + +if (exists $opts{dep_isim}) { + my $stem_isim = $stem . "_ISim"; + + $stem_isim =~ s/_ssim_ISim$/_ISim_ssim/ if ($is_ssim); + + my $stem_fsim_isim = $stem_isim; + my $stem_tsim_isim = $stem_isim; + $stem_fsim_isim =~ s/_ssim$/_fsim/; + $stem_tsim_isim =~ s/_ssim$/_tsim/; + + print "#\n"; + print "$stem_isim : $stem.dep_isim\n"; + if ($is_ssim) { + print "$stem_fsim_isim : $stem.dep_isim\n"; + print "$stem_tsim_isim : $stem.dep_isim\n"; + } + print "#\n"; + + foreach (@file_list) { + print "$stem_isim : $_\n"; + } + + if ($is_ssim) { + + foreach (@file_list) { + my $file = $_; # copy to break alias for following s/// + $file =~ s/_ssim\.vhd$/_fsim.vhd/; + print "$stem_fsim_isim : $file\n"; + } + + foreach (@file_list) { + my $file = $_; # copy to break alias for following s/// + $file =~ s/_ssim\.vhd$/_tsim.vhd/; + print "$stem_tsim_isim : $file\n"; + } + + } + + write_vbomdep("$stem.dep_isim"); +} + +# --xst_export or ghdl_export or isim_export ------------------------- + +if (exists $opts{xst_export} or + exists $opts{ghdl_export} or + exists $opts{isim_export}) { + my $edir; + $edir = $opts{xst_export} if exists $opts{xst_export}; + $edir = $opts{ghdl_export} if exists $opts{ghdl_export}; + $edir = $opts{isim_export} if exists $opts{isim_export}; + + if (not -d $edir) { + print STDERR "%vbomconv-I: create target directory $edir\n"; + system("mkdir -p $edir") == 0 or die "mkdir failed: $?"; + } else { + print STDERR "%vbomconv-I: target directory $edir already exists\n"; + } + + open(PFILE, ">$edir/$stem.prj") or die "can't write open $edir/$stem.prj: $!"; + + foreach (@file_list) { + my $fname = $_; + my $fdpath = "."; + if (m{(.*)/(.*)}) { + $fname = $2; + $fdpath = $1; + } + copy_edir($_, $edir); + print PFILE "vhdl work $fname\n"; + } + + close(PFILE); + + if (exists $opts{xst_export}) { + copy_edir($ENV{RETROBASE}."/vlib/xst_vhdl.opt", $edir) + if (defined $ENV{RETROBASE} || -r $ENV{RETROBASE}."/vlib/xst_vhdl.opt"); + + copy_edir("xst_vhdl.opt", $edir) if (-r "xst_vhdl.opt"); + + open(XFILE, ">$edir/$stem.xcf") or + die "can't write open $edir/$stem.xcf: $!"; + close(XFILE); + foreach(glob("*.xcf")) { copy_edir($_, $edir); } + + foreach(glob("*.ucf")) { copy_edir($_, $edir); } + } + +} + +# --flist ------------------------------------------------------------ + +if (exists $opts{flist}) { + + my @flist; + + push @flist, @file_list; + push @flist, sort keys %read_tbl; + + if (scalar(@ucf_cpp_list)) { + foreach (@ucf_cpp_list) { + push @flist, $_."_cpp"; + } + } else { + if (-r "$stem.ucf") { + push @flist, "$stem.ucf"; + } + } + + foreach (sort @flist) { + my $fname = $_; + my $fdpath = "."; + if (m{(.*)/(.*)}) { + $fname = $2; + $fdpath = $1; + } + print "$fdpath/$fname\n"; + } + +} + +#------------------------------------------------------------------------------- + +sub read_vbom { + my ($vbom) = @_; + + print STDERR "-- open $vbom\n" if $do_trace; + + open (IFILE, $vbom) or die "can't open for read $vbom: $!"; + + my $vbom_path = ""; + my $vbom_file = $vbom; + if ($vbom =~ m{^(.*)/([a-zA-Z0-9_.]*)$}) { + $vbom_path = $1; + $vbom_file = $2; + } + + $read_tbl{$vbom} += 1; # mark this vbom already read + + while () { + chomp; + next if /^\s*#/; # drop comments + next if /^\s*$/; # drop empty lines + + s/\s*$//; # drop trailing blanks + + if (/^\[([a-z,]+)\]\s*(.+)$/) { # [xxx,yyy] tag seen + my $qual = $1; + my $name = $2; + my $keep = $is_any; + ## print STDERR "+++1 |$qual|$name|$vbom|\n"; + foreach my $pref (split /,/,$qual) { + if ($pref =~ /^(xst|ghdl|isim|sim)$/) { + $keep = 1 if ($pref eq "xst" && $is_xst); + $keep = 1 if ($pref eq "ghdl" && $is_ghdl); + $keep = 1 if ($pref eq "isim" && $is_isim); + $keep = 1 if ($pref eq "sim" && $is_sim); + } else { + print STDERR "%vbomconv-W: unknown tag [$pref] in $vbom_file\n"; + } + } + if (not $keep) { + print STDERR "--- drop \"$_\"\n" if $do_trace; + next; + } + $_ = $name; # remove [xxx] tag + } + + my $tag; + my $val = $_; + my $del; + + # detect tag=val or tag:val lines + if (m{^\s*(.*?)\s*([=:])\s*(.*?)\s*$}) { + $tag = $1; + $del = $2; + $val = $3; + } + + # process @top: lines + if (defined $del && $del eq ":" && $tag eq '@top') { + $top = $val unless $top_done; + next; + } + + # process @ucf_cpp: lines + if (defined $del && $del eq ":" && $tag eq '@ucf_cpp') { + push @ucf_cpp_list, $val; + next; + } + + # process @lib: lines + if (defined $del && $del eq ":" && $tag eq '@lib') { + if ($val eq 'unisim') { + $has_unisim = 1; + } elsif ($val eq 'simprim') { + $has_simprim = 1; + } else { + die "unknown library type: $val"; + } + next; + } + + # now do _fsim, _tsim mapping + $val =~ s{_ssim\.vhd$}{_fsim.vhd} if $is_fsim; + $val =~ s{_ssim\.vhd$}{_tsim.vhd} if $is_tsim; + + # process normal .vhd or .vbom file lines + # get full relative file name (relative to cwd) + + my $fname = $val; + $fname = "$vbom_path/$fname" if $vbom_path ne ""; + + # remove 'inner' .., e.g. ../x/../y --> ../y + # this will also canonize the file names, thus same file same name + + my @flist; + foreach (split "/",$fname) { + if (scalar(@flist) && $flist[$#flist] ne ".." && $_ eq "..") { + pop @flist; + } else { + push @flist, $_; + } + } + + my $fullname = join "/", @flist; + + # determine whether additional libs needed + if ($fullname =~ m{_ssim\.vhd$}) { # ends in _ssim.vhd + $has_unisim = 1; + } + if ($fullname =~ m{_[ft]sim\.vhd$}) { # ends in _fsim.vhd or _tsim.vhd + $has_simprim = 1; + } + + # handle configuration statements (tag=val) + if (defined $del && $del eq "=") { + if (exists $conf_tbl{$tag}) { + print STDERR "--- ignore $tag = $fullname\n" if $do_trace; + } else { + $conf_tbl{$tag} = $fullname; + print STDERR "--- config $tag = $fullname\n" if $do_trace; + } + next; + } + + # handle configurable lines (tag:val) + if (defined $del && $del eq ":") { + if (exists $conf_tbl{$tag}) { + $fullname = $conf_tbl{$tag}; + print STDERR "--- use $tag = $fullname\n" if $do_trace; + } else { + print STDERR "--- use $tag = $fullname (default)\n" if $do_trace; + } + } + + # build vbom table + push @{$vbom_tbl{$vbom}}, $fullname; + print STDERR "--- add $fullname\n" if $do_trace; + + # if a vbom, queue if not not already read + if ($fullname =~ m{\.vbom$} && not exists $read_tbl{$fullname} ) { + push @vbom_list, $fullname; + print STDERR "--- queue $fullname\n" if $do_trace; + } + + } + + $top_done = 1; + + close (IFILE); +} + +#------------------------------------------------------------------------------- + +sub scan_vbom { + my ($vbom) = @_; + + $level += 1; + my $rank = 1000*$level + scalar(@{$vbom_tbl{$vbom}}); + print STDERR "--> $level: $vbom\n" if $do_trace; + + die "%vbomcov-E excessive vbom stack depth \n" if $level>=1000; + + foreach (@{$vbom_tbl{$vbom}}) { + my $file = $_; + $rank -= 1; + if (m{\.vbom$}) { + scan_vbom($file); + } else { + if (exists $file_tbl{$file}) { + if ($rank > $file_tbl{$file}) { + print STDERR " $file $file_tbl{$file} -> $rank\n" if $do_trace; + $file_tbl{$file} = $rank; + } else { + print STDERR " $file $file_tbl{$file} (keep)\n" if $do_trace; + } + } else { + $file_tbl{$file} = $rank; + print STDERR " $file $file_tbl{$file} (new)\n" if $do_trace; + } + } + } + + print STDERR "<-- $level: $vbom\n" if $do_trace; + $level -= 1; + +} + +#------------------------------------------------------------------------------- + +sub copy_edir { + my ($file, $edir) = @_; + print "cp -p $file $edir\n"; + system("cp -p $file $edir")==0 or die "cp -p failed: $?"; +} + +#------------------------------------------------------------------------------- + +sub write_vbomdep { + my ($target) = @_; + print "#\n"; + print "# .dep_ on .vbom dependencies\n"; + print "#\n"; + foreach (sort keys %read_tbl) { + print "$target : $_\n"; + } +} + +#------------------------------------------------------------------------------- + +sub print_help { + print "usage: vbomconf file.vbom\n"; + print " --help this message\n"; + print " --trace trace recursive processing of vbom's\n"; + print " --dep_xst generate xst dependencies for make (on stdout)\n"; + print " --dep_ghdl generate ghdl dependencies for make (on stdout)\n"; + print " --dep_isim generate isim dependencies for make (on stdout)\n"; + print " --xst_prj generate xst project file (on stdout)\n"; + print " --isim_prj generate isim project file (on stdout)\n"; + print " --ghdl_a generate and execute ghdl -a (analyse)\n"; + print " --ghdl_a_cmd like ghdl_a, but only print command, no exec\n"; + print " --ghdl_i generate and execute ghdl -i (inspect)\n"; + print " --ghdl_i_cmd like ghdl_i, but only print command, no exec\n"; + print " --ghdl_m generate and execute ghdl -m (make)\n"; + print " --ghdl_m_cmd like ghdl_m, but only print command, no exec\n"; + print " --xst_export=s export all xst source files into directory s\n"; + print " --ghdl_export=s export all ghdl source files into directory s\n"; + print " --isim_export=s export all isim source files into directory s\n"; + print " --flist list all files touched by vbom for all tags\n"; +} diff --git a/tools/bin/xilinx_ghdl_simprim b/tools/bin/xilinx_ghdl_simprim new file mode 100755 index 00000000..4d4826df --- /dev/null +++ b/tools/bin/xilinx_ghdl_simprim @@ -0,0 +1,73 @@ +#!/bin/sh +# $Id: xilinx_ghdl_simprim 311 2010-06-30 17:52:37Z mueller $ +# +# Revision History: +# 2009-11-08 248 1.1 adopt to ISE 11.1, use VITAL models from ./primitive +# 2007-10-26 92 1.0 Initial version +# + +if [ -z "$XILINX" ] +then + echo "XILINX not defined" + exit 1 +fi +# +cd $XILINX +echo "============================================================" +echo "* Build ghdl SIMPRIM libs for $XILINX" +echo "============================================================" +# +if [ ! -d ghdl ] +then + mkdir ghdl +fi +# +cd $XILINX/ghdl +if [ ! -d simprim ] +then + mkdir simprim +fi +# +cd $XILINX/ghdl/simprim +cp $XILINX/vhdl/src/simprims/simprim_Vcomponents.vhd . +cp $XILINX/vhdl/src/simprims/simprim_Vpackage.vhd . +# +# for ISE 11.1 the VITAL models are individually in sub-dir primitives +# and vhdl_analyze_order is a file with best compilation order +# for ISE 10 and before all VITAL models are in one concatenetaed file +# in this case xilinx_vhdl_chop will chop this into individual model files +# +if [ ! -d primitive ] +then + mkdir primitive +fi +cd primitive +# +if [ -d $XILINX/vhdl/src/simprims/primitive ] +then + cp -p $XILINX/vhdl/src/simprims/primitive/other/*.vhd . + cp -p $XILINX/vhdl/src/simprims/primitive/other/vhdl_analyze_order . +else + xilinx_vhdl_chop $XILINX/vhdl/src/simprims/simprim_VITAL.vhd + find . -maxdepth 1 -name "*.vhd" | perl -p -e 's|\./||' > vhdl_analyze_order +fi +# +xilinx_vhdl_memcolltype_fix +# +cd .. +echo "# ghdl ... simprim_Vcomponents.vhd" +ghdl -a --ieee=synopsys --work=simprim --no-vital-checks simprim_Vcomponents.vhd +echo "# ghdl ... simprim_Vpackage.vhd" +ghdl -a --ieee=synopsys --work=simprim --no-vital-checks simprim_Vpackage.vhd + +for file in `cat primitive/vhdl_analyze_order` +do + echo "# ghdl ... primitive/$file" + ghdl -a -fexplicit --ieee=synopsys --work=simprim \ + --no-vital-checks primitive/$file 2>&1 |\ + tee primitive/$file.ghdl.log +done +# +echo "--- scan for compilation errors:" +find primitive -name "*.ghdl.log" | xargs grep error +# diff --git a/tools/bin/xilinx_ghdl_unisim b/tools/bin/xilinx_ghdl_unisim new file mode 100755 index 00000000..422807c2 --- /dev/null +++ b/tools/bin/xilinx_ghdl_unisim @@ -0,0 +1,73 @@ +#!/bin/sh +# $Id: xilinx_ghdl_unisim 311 2010-06-30 17:52:37Z mueller $ +# +# Revision History: +# 2009-11-08 248 1.1 adopt to ISE 11.1, use VITAL models from ./primitive +# 2007-10-26 92 1.0 Initial version +# + +if [ -z "$XILINX" ] +then + echo "XILINX not defined" + exit 1 +fi +# +cd $XILINX +echo "============================================================" +echo "* Build ghdl UNISIM libs for $XILINX" +echo "============================================================" +# +if [ ! -d ghdl ] +then + mkdir ghdl +fi +# +cd $XILINX/ghdl +if [ ! -d unisim ] +then + mkdir unisim +fi +# +cd $XILINX/ghdl/unisim +cp $XILINX/vhdl/src/unisims/unisim_VCOMP.vhd . +cp $XILINX/vhdl/src/unisims/unisim_VPKG.vhd . +# +# for ISE 11.1 the VITAL models are individually in sub-dir primitives +# and vhdl_analyze_order is a file with best compilation order +# for ISE 10 and before all VITAL models are in one concatenetaed file +# in this case xilinx_vhdl_chop will chop this into individual model files +# +if [ ! -d primitive ] +then + mkdir primitive +fi +cd primitive +# +if [ -d $XILINX/vhdl/src/unisims/primitive ] +then + cp -p $XILINX/vhdl/src/unisims/primitive/*.vhd . + cp -p $XILINX/vhdl/src/unisims/primitive/vhdl_analyze_order . +else + xilinx_vhdl_chop $XILINX/vhdl/src/unisims/unisim_VITAL.vhd + find . -maxdepth 1 -name "*.vhd" | perl -p -e 's|\./||' > vhdl_analyze_order +fi +# +xilinx_vhdl_memcolltype_fix +# +cd .. +echo "# ghdl ... unisim_VCOMP.vhd" +ghdl -a --ieee=synopsys --work=unisim unisim_VCOMP.vhd +echo "# ghdl ... unisim_VPKG.vhd" +ghdl -a --ieee=synopsys --work=unisim unisim_VPKG.vhd + +for file in `cat primitive/vhdl_analyze_order` +do + echo "# ghdl ... primitive/$file" + ghdl -a -fexplicit --ieee=synopsys --work=unisim \ + --no-vital-checks primitive/$file 2>&1 |\ + tee primitive/$file.ghdl.log +done +# +echo "--- scan for compilation errors:" +find primitive -name "*.ghdl.log" | xargs grep error +# diff --git a/tools/bin/xilinx_tsim_xon b/tools/bin/xilinx_tsim_xon new file mode 100755 index 00000000..1d5c4c63 --- /dev/null +++ b/tools/bin/xilinx_tsim_xon @@ -0,0 +1,99 @@ +#!/usr/bin/perl -w +# $Id: xilinx_tsim_xon 314 2010-07-09 17:38:41Z mueller $ +# +# Copyright 2010- by Walter F.J. Mueller +# +# This program is free software; you may redistribute and/or modify it under +# the terms of the GNU General Public License as published by the Free +# Software Foundation, either version 2, 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 complete details. +# +# Revision History: +# Date Rev Version Comment +# 2010-05-06 289 1.0 Initial version +# +# +# Add "XON => false," defs in X_FF and X_SFF instances when name of the +# instance is matched by a regexp found in a descriptor file. +# +# Logic: +# looks for lines like +# : X_FF +# generic map( +# and adds +# XON => false, -- added by xilinx_tsim_xon tool -- +# if is matched by a regexp found in file stem..tsim_xon_dat +# +# all old 'XON => false' lines in input file are removed first, so this +# tool can be rerun with changing desciptor files. +# + +use strict; + +my $stem = shift; + +if (not defined $stem) { + print "xilinx_tsim_xon-E: call with file stem\n"; + exit 1; +} + +my $file_vhd = $stem . "_tsim.vhd"; +my $file_dsc = $stem . ".tsim_xon_dat"; + +if (! -r $file_vhd) { + print "xilinx_tsim_xon-E: $file_vhd not found or readable\n"; + exit 1; +} +if (! -r $file_dsc) { + print "xilinx_tsim_xon-E: $file_dsc not found or readable\n"; + exit 1; +} + +my @dsc_list; +open(DFILE, "<$file_dsc") || die ("Can't open descriptor file $file_dsc: $!"); +while () { + chomp; + s/^\s*//; + s/\s*$//; + next if m/^#/; + next if m/^$/; + push @dsc_list, $_; +} +close(DFILE); + +my $file_tmp = $stem . "_tsim_new.vhd"; +open(OFILE, ">$file_tmp") || die ("Can't open output file $file_tmp: $!"); +open(IFILE, "<$file_vhd") || die ("Can't open input file $file_vhd: $!"); + +my $match_1 = 0; +my $name_1; + +while () { + my $line = $_; + next if m/-- added by xilinx_tsim_xon tool --$/; + print OFILE $line; + my $match = 0; + my $name; + if ($line =~ m/\s*([a-zA-Z0-9_]+)\s*:\s*(X_FF|X_SFF)/) { + $name = $1; + foreach my $pat (@dsc_list) { + $match = 1 if ($name =~ m/^$pat$/); + } + } + if ($match_1 && $line =~ m/generic map/) { + ## print "xilinx_tsim_xon-I: XON=>false for $name_1\n"; + print OFILE + " XON => false, -- added by xilinx_tsim_xon tool --\n"; + } + $match_1 = $match; + $name_1 = $name; +} + +close(IFILE); +close(OFILE); + +rename $file_tmp, $file_vhd or die ("Can't rename $file_tmp: $!"); diff --git a/tools/bin/xilinx_vhdl_chop b/tools/bin/xilinx_vhdl_chop new file mode 100755 index 00000000..78b04455 --- /dev/null +++ b/tools/bin/xilinx_vhdl_chop @@ -0,0 +1,40 @@ +#!/usr/bin/perl -w +# $Id: xilinx_vhdl_chop 314 2010-07-09 17:38:41Z mueller $ +# +# Copyright 2007- by Walter F.J. Mueller +# +# This program is free software; you may redistribute and/or modify it under +# the terms of the GNU General Public License as published by the Free +# Software Foundation, either version 2, 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 complete details. +# +# Revision History: +# Date Rev Vers Comment +# 2007-06-06 50 1.0 Initial version +# +# splits a xilinx unisim_VITAL.vhd file along separators looking like: +# +# -- $Header: /and5b1.vhd,v 1.4 2004/04/08 18:46:23 patrickp Exp $ +# + +use 5.003; # require Perl 5.003 or higher +use strict; # require strict checking + +while (<>) { + chomp; + my @line = split; + if (/^-- \$Header/) { + my @file = split(/\//,$line[2]); + my $name = $file[$#file]; + $name =~ s/,v//; + print "writing $name \n"; + close(OFILE); + open(OFILE, "> $name") or die "Couldn't open output file: $!\n"; + } + print OFILE $_,"\n"; +} +close(OFILE); diff --git a/tools/bin/xilinx_vhdl_memcolltype_fix b/tools/bin/xilinx_vhdl_memcolltype_fix new file mode 100755 index 00000000..5d3f4cb9 --- /dev/null +++ b/tools/bin/xilinx_vhdl_memcolltype_fix @@ -0,0 +1,21 @@ +#!/bin/sh +# $Id: xilinx_vhdl_memcolltype_fix 311 2010-06-30 17:52:37Z mueller $ +# +# remove the lines +# +# variable Write_A_Write_B : memory_collision_type := Write_A_Write_B; +# variable Read_A_Write_B : memory_collision_type := Read_A_Write_B; +# variable Write_A_Read_B : memory_collision_type := Write_A_Read_B; +# variable Write_B_Write_A : memory_collision_type := Write_B_Write_A; +# variable Read_B_Write_A : memory_collision_type := Read_B_Write_A; +# variable Write_B_Read_A : memory_collision_type := Write_B_Read_A; +# +# from vhd sources. These self-referencial init are wrong and cause ghdl to +# choke. The awk script checks quite closely for this patterns. + +for file in `egrep -l 'variable.*(Read|Write)_(A|B)_(Read|Write)_(A|B)' *.vhd` +do + echo "# strip 'variable.. memory_collision_type..' in $file" + mv $file $file.old + awk '! /variable.*(Read|Write)_(A|B)_(Read|Write)_(A|B).*memory_collision_type.*(Read|Write)_(A|B)_(Read|Write)_(A|B)/ {print $0}' $file.old > $file +done diff --git a/tools/bin/xst_count_bels b/tools/bin/xst_count_bels new file mode 100755 index 00000000..65a6de91 --- /dev/null +++ b/tools/bin/xst_count_bels @@ -0,0 +1,106 @@ +#!/usr/bin/perl -w +# $Id: xst_count_bels 314 2010-07-09 17:38:41Z mueller $ +# +# Copyright 2007-2010 by Walter F.J. Mueller +# +# This program is free software; you may redistribute and/or modify it under +# the terms of the GNU General Public License as published by the Free +# Software Foundation, either version 2, 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 complete details. +# +# Revision History: +# Date Rev Version Comment +# 2010-04-26 284 1.2.1 add error check for GetOptions +# 2007-10-28 93 1.2 added -xsts (_ssim based device summary) +# 2007-06-30 62 1.1 fixed parser, now all bels counted +# 2007-06-16 57 1.0 Initial version + +use 5.005; # require Perl 5.005 or higher +use strict; # require strict checking + +use Getopt::Long; + +sub do_file; + +my %opts = (); + +GetOptions(\%opts, "xstl", "xsts") + or die "bad options"; + +my $do_xstl = defined $opts{xstl}; +my $do_xsts = defined $opts{xsts}; +my $do_plain = not ($do_xstl or $do_xsts); + +foreach (@ARGV) { do_file($_); } + +#------------------------------------------------------------------------------- + +sub do_file { + my ($filename) = @_; + my %bels; + my $cur_bel; + + open (IFILE, $filename) or die "can't open for read $filename"; + while() { + chomp; + if (m{^\s*[a-zA-Z0-9_]+\s*:\s*([a-zA-Z0-9_]+)\s*$}) { + $cur_bel = $1; + } elsif (m{\s*(generic|port)\s+map\s*\(\s*}) { + $bels{$cur_bel} += 1 if $cur_bel; + } else { + $cur_bel = ""; + } + } + close (IFILE); + + if ($do_plain) { + foreach (sort keys %bels) { + printf "%16s : %5d\n", $_, $bels{$_}; + } + } + + if ($do_xsts) { + my $n_flop = 0; + my $n_luts = 0; + my $n_luts_log = 0; + my $n_luts_ram = 0; + my $n_bram = 0; + my $n_mult = 0; + my $n_iob = 0; + + foreach (sort keys %bels) { + if (/^FD/) { + $n_flop += $bels{$_}; + } elsif (/^LUT/) { + $n_luts += $bels{$_}; + $n_luts_log += $bels{$_}; + } elsif (/^RAMB/) { + $n_bram += $bels{$_}; + } elsif (/^RAM\d*X.*D$/) { + $n_luts += 2 * $bels{$_}; + $n_luts_ram += 2 * $bels{$_}; + } elsif (/^RAM\d*X.*S$/) { + $n_luts += $bels{$_}; + $n_luts_ram += $bels{$_}; + } elsif (/^[IO]BUF$/) { + $n_iob += $bels{$_}; + } elsif (/^MULT/) { + $n_mult += $bels{$_}; + } + } + + print "Device utilization summary (_ssim BELS scan):\n"; + print "---------------------------------------------\n"; + printf " Number of Flip Flops: %5d\n", $n_flop; + printf " Number of LUTs: %5d\n", $n_luts; + printf " Number used as logic: %5d\n", $n_luts_log; + printf " Number used as RAMs: %5d\n", $n_luts_ram; + printf " Number of bonded IOBs: %5d\n", $n_iob; + printf " Number of BRAMs: %5d\n", $n_bram; + printf " Number of MULT18X18s: %5d\n", $n_mult; + } +}