URL
https://opencores.org/ocsvn/marca/marca/trunk
Subversion Repositories marca
Compare Revisions
- This comparison shows the changes necessary to convert path
/
- from Rev 1 to Rev 2
- ↔ Reverse comparison
Rev 1 → Rev 2
/trunk/gpl.txt
0,0 → 1,340
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 Library 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. |
|
<one line to give the program's name and a brief idea of what it does.> |
Copyright (C) <year> <name of author> |
|
This program is free software; you can redistribute it and/or modify |
it under the terms of the GNU General Public License as published by |
the Free Software Foundation; either version 2 of the License, or |
(at your option) any later version. |
|
This program is distributed in the hope that it will be useful, |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
GNU General Public License for more details. |
|
You should have received a copy of the GNU General Public License |
along with this program; if not, write to the Free Software |
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA |
|
|
Also add information on how to contact you by electronic and paper mail. |
|
If the program is interactive, make it output a short notice like this |
when it starts in an interactive mode: |
|
Gnomovision version 69, Copyright (C) year name of author |
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. |
This is free software, and you are welcome to redistribute it |
under certain conditions; type `show c' for details. |
|
The hypothetical commands `show w' and `show c' should show the appropriate |
parts of the General Public License. Of course, the commands you use may |
be called something other than `show w' and `show c'; they could even be |
mouse-clicks or menu items--whatever suits your program. |
|
You should also get your employer (if you work as a programmer) or your |
school, if any, to sign a "copyright disclaimer" for the program, if |
necessary. Here is a sample; alter the names: |
|
Yoyodyne, Inc., hereby disclaims all copyright interest in the program |
`Gnomovision' (which makes passes at compilers) written by James Hacker. |
|
<signature of Ty Coon>, 1 April 1989 |
Ty Coon, President of Vice |
|
This General Public License does not permit incorporating your program into |
proprietary programs. If your program is a subroutine library, you may |
consider it more useful to permit linking proprietary applications with the |
library. If this is what you want to do, use the GNU Lesser General |
Public License instead of this License. |
/trunk/quartus/marca.pin
0,0 → 1,299
-- Copyright (C) 1991-2006 Altera Corporation |
-- Your use of Altera Corporation's design tools, logic functions |
-- and other software and tools, and its AMPP partner logic |
-- functions, and any output files any of the foregoing |
-- (including device programming or simulation files), and any |
-- associated documentation or information are expressly subject |
-- to the terms and conditions of the Altera Program License |
-- Subscription Agreement, Altera MegaCore Function License |
-- Agreement, or other applicable license agreement, including, |
-- without limitation, that your use is for the sole purpose of |
-- programming logic devices manufactured by Altera and sold by |
-- Altera or its authorized distributors. Please refer to the |
-- applicable agreement for further details. |
-- |
-- This is a Quartus II output file. It is for reporting purposes only, and is |
-- not intended for use as a Quartus II input file. This file cannot be used |
-- to make Quartus II pin assignments - for instructions on how to make pin |
-- assignments, please see Quartus II help. |
--------------------------------------------------------------------------------- |
|
|
|
--------------------------------------------------------------------------------- |
-- NC : No Connect. This pin has no internal connection to the device. |
-- VCCINT : Dedicated power pin, which MUST be connected to VCC (1.5V). |
-- VCCIO : Dedicated power pin, which MUST be connected to VCC |
-- of its bank. |
-- Bank 1: 3.3V |
-- Bank 2: 3.3V |
-- Bank 3: 3.3V |
-- Bank 4: 3.3V |
-- GND : Dedicated ground pin. Dedicated GND pins MUST be connected to GND. |
-- It can also be used to report unused dedicated pins. The connection |
-- on the board for unused dedicated pins depends on whether this will |
-- be used in a future design. One example is device migration. When |
-- using device migration, refer to the device pin-tables. If it is a |
-- GND pin in the pin table or if it will not be used in a future design |
-- for another purpose the it MUST be connected to GND. If it is an unused |
-- dedicated pin, then it can be connected to a valid signal on the board |
-- (low, high, or toggling) if that signal is required for a different |
-- revision of the design. |
-- GND+ : Unused input pin. It can also be used to report unused dual-purpose pins. |
-- This pin should be connected to GND. It may also be connected to a |
-- valid signal on the board (low, high, or toggling) if that signal |
-- is required for a different revision of the design. |
-- GND* : Unused I/O pin. This pin can either be left unconnected or |
-- connected to GND. Connecting this pin to GND will improve the |
-- device's immunity to noise. |
-- RESERVED : Unused I/O pin, which MUST be left unconnected. |
-- RESERVED_INPUT : Pin is tri-stated and should be connected to the board. |
-- RESERVED_INPUT_WITH_WEAK_PULLUP : Pin is tri-stated with internal weak pull-up resistor. |
-- RESERVED_INPUT_WITH_BUS_HOLD : Pin is tri-stated with bus-hold circuitry. |
--------------------------------------------------------------------------------- |
|
Quartus II Version 6.0 Build 202 06/20/2006 Service Pack 1 SJ Web Edition |
CHIP "marca" ASSIGNED TO AN: EP1C12Q240C8 |
|
Pin Name/Usage : Location : Dir. : I/O Standard : Voltage : I/O Bank : User Assignment |
------------------------------------------------------------------------------------------------------------- |
RESERVED_INPUT : 1 : : : : 1 : |
RESERVED_INPUT : 2 : : : : 1 : |
RESERVED_INPUT : 3 : : : : 1 : |
RESERVED_INPUT : 4 : : : : 1 : |
RESERVED_INPUT : 5 : : : : 1 : |
RESERVED_INPUT : 6 : : : : 1 : |
RESERVED_INPUT : 7 : : : : 1 : |
RESERVED_INPUT : 8 : : : : 1 : |
VCCIO1 : 9 : power : : 3.3V : 1 : |
GND : 10 : gnd : : : : |
RESERVED_INPUT : 11 : : : : 1 : |
RESERVED_INPUT : 12 : : : : 1 : |
RESERVED_INPUT : 13 : : : : 1 : |
RESERVED_INPUT : 14 : : : : 1 : |
RESERVED_INPUT : 15 : : : : 1 : |
RESERVED_INPUT : 16 : : : : 1 : |
RESERVED_INPUT : 17 : : : : 1 : |
RESERVED_INPUT : 18 : : : : 1 : |
RESERVED_INPUT : 19 : : : : 1 : |
RESERVED_INPUT : 20 : : : : 1 : |
RESERVED_INPUT : 21 : : : : 1 : |
VCCIO1 : 22 : power : : 3.3V : 1 : |
RESERVED_INPUT : 23 : : : : 1 : |
~nCSO~ / RESERVED_INPUT_WITH_WEAK_PULLUP : 24 : input : LVCMOS : : 1 : N |
DATA0 : 25 : input : : : 1 : |
nCONFIG : 26 : : : : 1 : |
VCCA_PLL1 : 27 : power : : 1.5V : : |
ext_in[1] : 28 : input : LVCMOS : : 1 : Y |
GND+ : 29 : : : : 1 : |
GNDA_PLL1 : 30 : gnd : : : : |
GNDG_PLL1 : 31 : gnd : : : : |
nCEO : 32 : : : : 1 : |
nCE : 33 : : : : 1 : |
MSEL0 : 34 : : : : 1 : |
MSEL1 : 35 : : : : 1 : |
DCLK : 36 : bidir : : : 1 : |
~ASDO~ / RESERVED_INPUT_WITH_WEAK_PULLUP : 37 : input : LVCMOS : : 1 : N |
RESERVED_INPUT : 38 : : : : 1 : |
RESERVED_INPUT : 39 : : : : 1 : |
GND : 40 : gnd : : : : |
RESERVED_INPUT : 41 : : : : 1 : |
ext_reset : 42 : input : LVCMOS : : 1 : Y |
RESERVED_INPUT : 43 : : : : 1 : |
RESERVED_INPUT : 44 : : : : 1 : |
RESERVED_INPUT : 45 : : : : 1 : |
RESERVED_INPUT : 46 : : : : 1 : |
RESERVED_INPUT : 47 : : : : 1 : |
RESERVED_INPUT : 48 : : : : 1 : |
RESERVED_INPUT : 49 : : : : 1 : |
RESERVED_INPUT : 50 : : : : 1 : |
VCCIO1 : 51 : power : : 3.3V : 1 : |
GND : 52 : gnd : : : : |
RESERVED_INPUT : 53 : : : : 1 : |
RESERVED_INPUT : 54 : : : : 1 : |
RESERVED_INPUT : 55 : : : : 1 : |
RESERVED_INPUT : 56 : : : : 1 : |
RESERVED_INPUT : 57 : : : : 1 : |
RESERVED_INPUT : 58 : : : : 1 : |
RESERVED_INPUT : 59 : : : : 1 : |
RESERVED_INPUT : 60 : : : : 1 : |
RESERVED_INPUT : 61 : : : : 4 : |
RESERVED_INPUT : 62 : : : : 4 : |
RESERVED_INPUT : 63 : : : : 4 : |
RESERVED_INPUT : 64 : : : : 4 : |
RESERVED_INPUT : 65 : : : : 4 : |
RESERVED_INPUT : 66 : : : : 4 : |
RESERVED_INPUT : 67 : : : : 4 : |
RESERVED_INPUT : 68 : : : : 4 : |
GND : 69 : gnd : : : : |
VCCIO4 : 70 : power : : 3.3V : 4 : |
GND : 71 : gnd : : : : |
VCCINT : 72 : power : : 1.5V : : |
RESERVED_INPUT : 73 : : : : 4 : |
RESERVED_INPUT : 74 : : : : 4 : |
RESERVED_INPUT : 75 : : : : 4 : |
RESERVED_INPUT : 76 : : : : 4 : |
RESERVED_INPUT : 77 : : : : 4 : |
RESERVED_INPUT : 78 : : : : 4 : |
RESERVED_INPUT : 79 : : : : 4 : |
GND : 80 : gnd : : : : |
VCCINT : 81 : power : : 1.5V : : |
RESERVED_INPUT : 82 : : : : 4 : |
RESERVED_INPUT : 83 : : : : 4 : |
RESERVED_INPUT : 84 : : : : 4 : |
RESERVED_INPUT : 85 : : : : 4 : |
RESERVED_INPUT : 86 : : : : 4 : |
RESERVED_INPUT : 87 : : : : 4 : |
RESERVED_INPUT : 88 : : : : 4 : |
GND : 89 : gnd : : : : |
VCCINT : 90 : power : : 1.5V : : |
GND : 91 : gnd : : : : |
VCCIO4 : 92 : power : : 3.3V : 4 : |
RESERVED_INPUT : 93 : : : : 4 : |
RESERVED_INPUT : 94 : : : : 4 : |
RESERVED_INPUT : 95 : : : : 4 : |
GND : 96 : gnd : : : : |
VCCINT : 97 : power : : 1.5V : : |
RESERVED_INPUT : 98 : : : : 4 : |
RESERVED_INPUT : 99 : : : : 4 : |
RESERVED_INPUT : 100 : : : : 4 : |
RESERVED_INPUT : 101 : : : : 4 : |
GND : 102 : gnd : : : : |
VCCINT : 103 : power : : 1.5V : : |
RESERVED_INPUT : 104 : : : : 4 : |
RESERVED_INPUT : 105 : : : : 4 : |
RESERVED_INPUT : 106 : : : : 4 : |
RESERVED_INPUT : 107 : : : : 4 : |
RESERVED_INPUT : 108 : : : : 4 : |
GND : 109 : gnd : : : : |
VCCINT : 110 : power : : 1.5V : : |
GND : 111 : gnd : : : : |
VCCIO4 : 112 : power : : 3.3V : 4 : |
RESERVED_INPUT : 113 : : : : 4 : |
RESERVED_INPUT : 114 : : : : 4 : |
RESERVED_INPUT : 115 : : : : 4 : |
RESERVED_INPUT : 116 : : : : 4 : |
RESERVED_INPUT : 117 : : : : 4 : |
RESERVED_INPUT : 118 : : : : 4 : |
RESERVED_INPUT : 119 : : : : 4 : |
RESERVED_INPUT : 120 : : : : 4 : |
RESERVED_INPUT : 121 : : : : 3 : |
RESERVED_INPUT : 122 : : : : 3 : |
RESERVED_INPUT : 123 : : : : 3 : |
RESERVED_INPUT : 124 : : : : 3 : |
RESERVED_INPUT : 125 : : : : 3 : |
RESERVED_INPUT : 126 : : : : 3 : |
RESERVED_INPUT : 127 : : : : 3 : |
RESERVED_INPUT : 128 : : : : 3 : |
GND : 129 : gnd : : : : |
VCCIO3 : 130 : power : : 3.3V : 3 : |
RESERVED_INPUT : 131 : : : : 3 : |
RESERVED_INPUT : 132 : : : : 3 : |
RESERVED_INPUT : 133 : : : : 3 : |
RESERVED_INPUT : 134 : : : : 3 : |
RESERVED_INPUT : 135 : : : : 3 : |
RESERVED_INPUT : 136 : : : : 3 : |
RESERVED_INPUT : 137 : : : : 3 : |
RESERVED_INPUT : 138 : : : : 3 : |
RESERVED_INPUT : 139 : : : : 3 : |
RESERVED_INPUT : 140 : : : : 3 : |
RESERVED_INPUT : 141 : : : : 3 : |
GND : 142 : gnd : : : : |
RESERVED_INPUT : 143 : : : : 3 : |
RESERVED_INPUT : 144 : : : : 3 : |
CONF_DONE : 145 : : : : 3 : |
nSTATUS : 146 : : : : 3 : |
TCK : 147 : input : : : 3 : |
TMS : 148 : input : : : 3 : |
TDO : 149 : output : : : 3 : |
GNDG_PLL2 : 150 : gnd : : : : |
GNDA_PLL2 : 151 : gnd : : : : |
clock : 152 : input : LVCMOS : : 3 : Y |
ext_in[0] : 153 : input : LVCMOS : : 3 : Y |
VCCA_PLL2 : 154 : power : : 1.5V : : |
TDI : 155 : input : : : 3 : |
RESERVED_INPUT : 156 : : : : 3 : |
VCCIO3 : 157 : power : : 3.3V : 3 : |
RESERVED_INPUT : 158 : : : : 3 : |
RESERVED_INPUT : 159 : : : : 3 : |
RESERVED_INPUT : 160 : : : : 3 : |
RESERVED_INPUT : 161 : : : : 3 : |
RESERVED_INPUT : 162 : : : : 3 : |
RESERVED_INPUT : 163 : : : : 3 : |
RESERVED_INPUT : 164 : : : : 3 : |
RESERVED_INPUT : 165 : : : : 3 : |
RESERVED_INPUT : 166 : : : : 3 : |
RESERVED_INPUT : 167 : : : : 3 : |
RESERVED_INPUT : 168 : : : : 3 : |
RESERVED_INPUT : 169 : : : : 3 : |
RESERVED_INPUT : 170 : : : : 3 : |
GND : 171 : gnd : : : : |
VCCIO3 : 172 : power : : 3.3V : 3 : |
RESERVED_INPUT : 173 : : : : 3 : |
RESERVED_INPUT : 174 : : : : 3 : |
RESERVED_INPUT : 175 : : : : 3 : |
RESERVED_INPUT : 176 : : : : 3 : |
ext_out[1] : 177 : output : LVCMOS : : 3 : Y |
ext_out[0] : 178 : output : LVCMOS : : 3 : Y |
RESERVED_INPUT : 179 : : : : 3 : |
RESERVED_INPUT : 180 : : : : 3 : |
RESERVED_INPUT : 181 : : : : 2 : |
RESERVED_INPUT : 182 : : : : 2 : |
RESERVED_INPUT : 183 : : : : 2 : |
RESERVED_INPUT : 184 : : : : 2 : |
RESERVED_INPUT : 185 : : : : 2 : |
RESERVED_INPUT : 186 : : : : 2 : |
RESERVED_INPUT : 187 : : : : 2 : |
RESERVED_INPUT : 188 : : : : 2 : |
VCCIO2 : 189 : power : : 3.3V : 2 : |
GND : 190 : gnd : : : : |
VCCINT : 191 : power : : 1.5V : : |
GND : 192 : gnd : : : : |
RESERVED_INPUT : 193 : : : : 2 : |
RESERVED_INPUT : 194 : : : : 2 : |
RESERVED_INPUT : 195 : : : : 2 : |
RESERVED_INPUT : 196 : : : : 2 : |
RESERVED_INPUT : 197 : : : : 2 : |
VCCINT : 198 : power : : 1.5V : : |
GND : 199 : gnd : : : : |
RESERVED_INPUT : 200 : : : : 2 : |
RESERVED_INPUT : 201 : : : : 2 : |
RESERVED_INPUT : 202 : : : : 2 : |
RESERVED_INPUT : 203 : : : : 2 : |
VCCINT : 204 : power : : 1.5V : : |
GND : 205 : gnd : : : : |
RESERVED_INPUT : 206 : : : : 2 : |
RESERVED_INPUT : 207 : : : : 2 : |
RESERVED_INPUT : 208 : : : : 2 : |
VCCIO2 : 209 : power : : 3.3V : 2 : |
GND : 210 : gnd : : : : |
VCCINT : 211 : power : : 1.5V : : |
GND : 212 : gnd : : : : |
RESERVED_INPUT : 213 : : : : 2 : |
RESERVED_INPUT : 214 : : : : 2 : |
RESERVED_INPUT : 215 : : : : 2 : |
RESERVED_INPUT : 216 : : : : 2 : |
RESERVED_INPUT : 217 : : : : 2 : |
RESERVED_INPUT : 218 : : : : 2 : |
RESERVED_INPUT : 219 : : : : 2 : |
VCCINT : 220 : power : : 1.5V : : |
GND : 221 : gnd : : : : |
RESERVED_INPUT : 222 : : : : 2 : |
RESERVED_INPUT : 223 : : : : 2 : |
RESERVED_INPUT : 224 : : : : 2 : |
RESERVED_INPUT : 225 : : : : 2 : |
RESERVED_INPUT : 226 : : : : 2 : |
RESERVED_INPUT : 227 : : : : 2 : |
RESERVED_INPUT : 228 : : : : 2 : |
VCCINT : 229 : power : : 1.5V : : |
GND : 230 : gnd : : : : |
VCCIO2 : 231 : power : : 3.3V : 2 : |
GND : 232 : gnd : : : : |
RESERVED_INPUT : 233 : : : : 2 : |
RESERVED_INPUT : 234 : : : : 2 : |
RESERVED_INPUT : 235 : : : : 2 : |
RESERVED_INPUT : 236 : : : : 2 : |
RESERVED_INPUT : 237 : : : : 2 : |
RESERVED_INPUT : 238 : : : : 2 : |
RESERVED_INPUT : 239 : : : : 2 : |
RESERVED_INPUT : 240 : : : : 2 : |
/trunk/quartus/marca.qpf
0,0 → 1,24
# Copyright (C) 1991-2006 Altera Corporation |
# Your use of Altera Corporation's design tools, logic functions |
# and other software and tools, and its AMPP partner logic |
# functions, and any output files any of the foregoing |
# (including device programming or simulation files), and any |
# associated documentation or information are expressly subject |
# to the terms and conditions of the Altera Program License |
# Subscription Agreement, Altera MegaCore Function License |
# Agreement, or other applicable license agreement, including, |
# without limitation, that your use is for the sole purpose of |
# programming logic devices manufactured by Altera and sold by |
# Altera or its authorized distributors. Please refer to the |
# applicable agreement for further details. |
|
|
|
QUARTUS_VERSION = "6.0" |
DATE = "03:27:58 February 02, 2007" |
|
|
# Revisions |
|
PROJECT_REVISION = "marca" |
PROJECT_REVISION = "speed" |
/trunk/quartus/marca.qsf
0,0 → 1,166
# Copyright (C) 1991-2006 Altera Corporation |
# Your use of Altera Corporation's design tools, logic functions |
# and other software and tools, and its AMPP partner logic |
# functions, and any output files any of the foregoing |
# (including device programming or simulation files), and any |
# associated documentation or information are expressly subject |
# to the terms and conditions of the Altera Program License |
# Subscription Agreement, Altera MegaCore Function License |
# Agreement, or other applicable license agreement, including, |
# without limitation, that your use is for the sole purpose of |
# programming logic devices manufactured by Altera and sold by |
# Altera or its authorized distributors. Please refer to the |
# applicable agreement for further details. |
|
|
# The default values for assignments are stored in the file |
# marca_assignment_defaults.qdf |
# If this file doesn't exist, and for assignments not listed, see file |
# assignment_defaults.qdf |
|
# Altera recommends that you do not modify this file. This |
# file is updated automatically by the Quartus II software |
# and any changes you make may be lost or overwritten. |
|
|
|
# Project-Wide Assignments |
# ======================== |
set_global_assignment -name ORIGINAL_QUARTUS_VERSION "6.0 SP1" |
set_global_assignment -name PROJECT_CREATION_TIME_DATE "17:01:50 OCTOBER 25, 2006" |
set_global_assignment -name LAST_QUARTUS_VERSION "6.0 SP1" |
set_global_assignment -name SMART_RECOMPILE ON |
|
# Analysis & Synthesis Assignments |
# ================================ |
set_global_assignment -name FAMILY Cyclone |
set_global_assignment -name TOP_LEVEL_ENTITY marca |
set_global_assignment -name STRATIXII_OPTIMIZATION_TECHNIQUE AREA |
set_global_assignment -name CYCLONE_OPTIMIZATION_TECHNIQUE AREA |
set_global_assignment -name STRATIX_OPTIMIZATION_TECHNIQUE AREA |
set_global_assignment -name MAXII_OPTIMIZATION_TECHNIQUE AREA |
set_global_assignment -name APEX20K_OPTIMIZATION_TECHNIQUE AREA |
set_global_assignment -name MERCURY_OPTIMIZATION_TECHNIQUE AREA |
set_global_assignment -name FLEX10K_OPTIMIZATION_TECHNIQUE AREA |
set_global_assignment -name IGNORE_LCELL_BUFFERS ON |
set_global_assignment -name ADV_NETLIST_OPT_SYNTH_WYSIWYG_REMAP ON |
set_global_assignment -name ADV_NETLIST_OPT_SYNTH_GATE_RETIME ON |
set_global_assignment -name MUX_RESTRUCTURE ON |
|
# Fitter Assignments |
# ================== |
set_global_assignment -name DEVICE EP1C12Q240C8 |
set_global_assignment -name FITTER_EFFORT "AUTO FIT" |
set_global_assignment -name RESERVE_ALL_UNUSED_PINS "AS INPUT TRI-STATED" |
set_global_assignment -name RESERVE_ASDO_AFTER_CONFIGURATION "AS INPUT TRI-STATED" |
set_global_assignment -name PHYSICAL_SYNTHESIS_COMBO_LOGIC ON |
set_global_assignment -name PHYSICAL_SYNTHESIS_REGISTER_DUPLICATION ON |
set_global_assignment -name PHYSICAL_SYNTHESIS_REGISTER_RETIMING ON |
set_global_assignment -name ROUTER_TIMING_OPTIMIZATION_LEVEL MAXIMUM |
set_global_assignment -name STRATIX_DEVICE_IO_STANDARD LVCMOS |
|
# Assembler Assignments |
# ===================== |
set_global_assignment -name RESERVE_ALL_UNUSED_PINS_NO_OUTPUT_GND "AS INPUT TRI-STATED" |
|
# Simulator Assignments |
# ===================== |
set_global_assignment -name VECTOR_INPUT_SOURCE "z:\\mnt\\wolfgang\\marca\\sim\\sim1.vwf" |
set_global_assignment -name SETUP_HOLD_DETECTION ON |
set_global_assignment -name SIMULATION_VDB_RESULT_FLUSH OFF |
|
# ------------------- |
# start ENTITY(marca) |
|
# end ENTITY(marca) |
# ----------------- |
set_global_assignment -name PHYSICAL_SYNTHESIS_EFFORT FAST |
set_global_assignment -name FMAX_REQUIREMENT "20 MHz" |
set_global_assignment -name STATE_MACHINE_PROCESSING "ONE-HOT" |
set_global_assignment -name REMOVE_REDUNDANT_LOGIC_CELLS ON |
set_global_assignment -name ALLOW_ANY_SHIFT_REGISTER_SIZE_FOR_RECOGNITION ON |
set_global_assignment -name ENABLE_DRC_SETTINGS ON |
set_global_assignment -name ENABLE_CLOCK_LATENCY ON |
set_global_assignment -name ENABLE_RECOVERY_REMOVAL_ANALYSIS ON |
set_global_assignment -name FMAX_REQUIREMENT "20 MHz" -section_id dspio_clock |
set_global_assignment -name SIMULATION_MODE TIMING |
set_global_assignment -name EDA_SIMULATION_TOOL "<None>" |
set_global_assignment -name EDA_INCLUDE_VHDL_CONFIGURATION_DECLARATION OFF -section_id eda_simulation |
set_global_assignment -name EDA_OUTPUT_DATA_FORMAT NONE -section_id eda_simulation |
set_global_assignment -name OPTIMIZE_HOLD_TIMING "ALL PATHS" |
set_global_assignment -name GLITCH_DETECTION OFF |
set_global_assignment -name AUTO_RESOURCE_SHARING ON |
set_global_assignment -name REMOVE_DUPLICATE_REGISTERS ON |
set_global_assignment -name REMOVE_DUPLICATE_LOGIC ON |
set_global_assignment -name ALLOW_ANY_ROM_SIZE_FOR_RECOGNITION ON |
set_global_assignment -name ALLOW_ANY_RAM_SIZE_FOR_RECOGNITION ON |
set_global_assignment -name IGNORE_CARRY_BUFFERS ON |
set_global_assignment -name IGNORE_CASCADE_BUFFERS ON |
set_global_assignment -name AUTO_RAM_RECOGNITION ON |
set_global_assignment -name AUTO_SHIFT_REGISTER_RECOGNITION ON |
set_global_assignment -name AUTO_PACKED_REGISTERS_CYCLONE "MINIMIZE AREA WITH CHAINS" |
set_global_assignment -name FITTER_AGGRESSIVE_ROUTABILITY_OPTIMIZATION ALWAYS |
set_global_assignment -name OPTIMIZE_TIMING OFF |
set_global_assignment -name OPTIMIZE_FAST_CORNER_TIMING ON |
set_global_assignment -name DO_COMBINED_ANALYSIS ON |
set_global_assignment -name PHYSICAL_SYNTHESIS_ASYNCHRONOUS_SIGNAL_PIPELINING ON |
set_global_assignment -name SAVE_DISK_SPACE OFF |
set_global_assignment -name OPTIMIZE_POWER_DURING_SYNTHESIS "EXTRA EFFORT" |
set_global_assignment -name CYCLONEII_OPTIMIZATION_TECHNIQUE AREA |
set_global_assignment -name MAX7000_OPTIMIZATION_TECHNIQUE AREA |
set_global_assignment -name VHDL_INPUT_VERSION VHDL93 |
set_global_assignment -name VHDL_SHOW_LMF_MAPPING_MESSAGES OFF |
set_global_assignment -name GENERATE_RBF_FILE ON |
set_global_assignment -name ON_CHIP_BITSTREAM_DECOMPRESSION OFF |
set_location_assignment PIN_152 -to clock |
set_location_assignment PIN_153 -to ext_in[0] |
set_location_assignment PIN_28 -to ext_in[1] |
set_location_assignment PIN_178 -to ext_out[0] |
set_location_assignment PIN_177 -to ext_out[1] |
set_location_assignment PIN_42 -to ext_reset |
set_global_assignment -name FINAL_PLACEMENT_OPTIMIZATION AUTOMATICALLY |
set_global_assignment -name ROUTER_LCELL_INSERTION_AND_LOGIC_DUPLICATION OFF |
set_global_assignment -name ROUTER_REGISTER_DUPLICATION OFF |
set_global_assignment -name PLACEMENT_EFFORT_MULTIPLIER 4.0 |
set_global_assignment -name ROUTER_EFFORT_MULTIPLIER 1.0 |
set_global_assignment -name SIMULATOR_GENERATE_SIGNAL_ACTIVITY_FILE ON |
set_global_assignment -name SIMULATOR_SIGNAL_ACTIVITY_FILE_OUTPUT_DESTINATION marca.saf |
set_global_assignment -name POWER_USE_INPUT_FILES ON |
set_global_assignment -name POWER_INPUT_FILE_NAME marca.saf -section_id marca.saf |
set_global_assignment -name POWER_INPUT_FILE_TYPE SAF -section_id marca.saf |
set_instance_assignment -name POWER_READ_INPUT_FILE marca.saf -to marca |
set_global_assignment -name VHDL_FILE ../vhdl/marca_pkg.vhd |
set_global_assignment -name VHDL_FILE ../vhdl/sc_pkg.vhd |
set_global_assignment -name VHDL_FILE ../vhdl/code_memory.vhd |
set_global_assignment -name VHDL_FILE ../vhdl/fetch_ent.vhd |
set_global_assignment -name VHDL_FILE ../vhdl/fetch.vhd |
set_global_assignment -name VHDL_FILE ../vhdl/regfile_ent.vhd |
set_global_assignment -name VHDL_FILE ../vhdl/regfile.vhd |
set_global_assignment -name VHDL_FILE ../vhdl/decode_ent.vhd |
set_global_assignment -name VHDL_FILE ../vhdl/decode.vhd |
set_global_assignment -name VHDL_FILE ../vhdl/multiplier_ent.vhd |
set_global_assignment -name VHDL_FILE ../vhdl/multiplier.vhd |
set_global_assignment -name VHDL_FILE ../vhdl/divider_ent.vhd |
set_global_assignment -name VHDL_FILE ../vhdl/divider.vhd |
set_global_assignment -name VHDL_FILE ../vhdl/alu_ent.vhd |
set_global_assignment -name VHDL_FILE ../vhdl/alu.vhd |
set_global_assignment -name VHDL_FILE ../vhdl/data_memory.vhd |
set_global_assignment -name VHDL_FILE ../vhdl/data_rom.vhd |
set_global_assignment -name VHDL_FILE ../vhdl/fifo.vhd |
set_global_assignment -name VHDL_FILE ../vhdl/sc_uart.vhd |
set_global_assignment -name VHDL_FILE ../vhdl/mem_ent.vhd |
set_global_assignment -name VHDL_FILE ../vhdl/mem.vhd |
set_global_assignment -name VHDL_FILE ../vhdl/intr_ent.vhd |
set_global_assignment -name VHDL_FILE ../vhdl/intr.vhd |
set_global_assignment -name VHDL_FILE ../vhdl/execute_ent.vhd |
set_global_assignment -name VHDL_FILE ../vhdl/execute.vhd |
set_global_assignment -name VHDL_FILE ../vhdl/writeback_ent.vhd |
set_global_assignment -name VHDL_FILE ../vhdl/writeback.vhd |
set_global_assignment -name VHDL_FILE ../vhdl/marca_ent.vhd |
set_global_assignment -name VHDL_FILE ../vhdl/marca.vhd |
set_global_assignment -name MIF_FILE ../vhdl/code.mif |
set_global_assignment -name MIF_FILE ../vhdl/rom0.mif |
set_global_assignment -name MIF_FILE ../vhdl/rom1.mif |
set_global_assignment -name VECTOR_WAVEFORM_FILE ../sim/sim1.vwf |
set_global_assignment -name AUTO_GLOBAL_MEMORY_CONTROLS ON |
set_global_assignment -name SIMULATION_WITH_GLITCH_FILTERING_IN_NORMAL_FLOW ON |
/trunk/doc/marca.dia
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
trunk/doc/marca.dia
Property changes :
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: trunk/doc/implementation.tex
===================================================================
--- trunk/doc/implementation.tex (nonexistent)
+++ trunk/doc/implementation.tex (revision 2)
@@ -0,0 +1,247 @@
+\documentclass[10pt, twoside, a4paper]{article}
+\usepackage{graphicx}
+\usepackage{listings}
+
+\title{marca - McAdam's RISC Computer Architecture\\Implementation Details}
+\author{Wolfgang Puffitsch}
+
+\begin{document}
+
+ \maketitle
+
+ \section{General}
+
+ \begin{itemize}
+ \item 16 16-bit registers
+ \item 16KB instruction ROM (8192 instructions)
+ \item 8KB data RAM
+ \item 256 byte data ROM
+ \item 75 instructions
+ \item 16 interrupt vectors
+ \end{itemize}
+
+ \section{Internals}
+
+ The processor features a 4-stage pipeline:
+ \begin{itemize}
+ \item instruction fetch
+ \item instruction decode
+ \item execution/memory access
+ \item write back
+ \end{itemize}
+ This scheme is similar to the one used in the MIPS architecture,
+ only execution and write back stage are drawn together. For our
+ architecture does not support indexed addressing, it does not need
+ the ALU's result and can work in parallel, having the advantage of
+ reducing the possible hazards.
+
+ Figure \ref{fig:marca} shows a rough scheme of the internals of the
+ processor.
+ \begin{figure}[ht!]
+ \centering
+ \includegraphics[width=.95\textwidth]{marca}
+ \caption{Internal scheme}
+ \label{fig:marca}
+ \end{figure}
+
+ \subsection{Branches}
+ Branches are not predicted and if executed they stall the the
+ pipeline, leading to a total execution time of 4 cycles. The fetch
+ stage is not stalled, the decode stage however is stalled for two
+ cycles to compensate that.
+
+ \subsection{Instruction fetch}
+ This stage is not spectacular: it simply reads an instruction from
+ the instruction ROM, and extracts the bits for the source and
+ destination registers.
+
+ \subsection{Instruction decode}
+ This stage translates the bit-patterns of the opcodes to the signals
+ used internally for the operations. It also holds the register file
+ and handles access to it. Immediate values are also constructed here.
+
+ \subsection{Execution / Memory access}
+ The execution stage is the heart and soul of the processor: it holds
+ the ALU, the memory/IO unit and a unit for interrupt handling.
+
+ \subsubsection{ALU}
+ The ALU does all arithmetic and logic computations as well as taking
+ care of the processors flags (which are organized as seen in table
+ \ref{tab:flags}).
+
+ \begin{table}[ht!]
+ \centering
+ \begin{tabular}{|p{.75em}|p{.75em}|p{.75em}|p{.75em}
+ |p{.75em}|p{.75em}|p{.75em}|p{.75em}
+ |p{.75em}|p{.75em}|p{.75em}|p{.75em}
+ |p{.75em}|p{.75em}|p{.75em}|p{.75em}|p{.75em}}
+ \multicolumn{16}{c}{Bit 15 \hfill Bit 0} \\
+ \hline
+ & & & & & & & & & & P & I & N & V & C & Z \\
+ \hline
+ \end{tabular}
+ \caption{The flag register}
+ \label{tab:flags}
+ \end{table}
+
+ Operations which need more than one cycle to execute (multiplication,
+ division and modulo) block the rest of the processor until they are
+ finished.
+
+ \subsubsection{Memory/IO unit}
+ The memory/IO unit takes care of the ordinary data memory, the data
+ ROM (which is mapped to the addresses right above the RAM) and the
+ communication to peripheral modules. Peripheral modules are located
+ within the memory/IO unit and mapped to the highest addresses.
+
+ The memories (the instruction ROM too) are Altera specific; we
+ decided not to use generic memories, because \textsl{Quartus} can update the
+ contents of its proprietary ROMs without synthesizing the whole
+ design. Because all memories are single-ported (and thus fairly
+ simple) it should be easy to replace them with memories specific to
+ other vendors.
+
+ We also decided against the use of external memories; larger FPGAs
+ can accommodate all addressable memory on-chip, so the implementation
+ overhead would not have paid off.
+
+ Accesses which take more than one cycle (stores to peripheral
+ modules and all load operations) block the rest of the processor
+ until they are finished.
+
+ \paragraph{Peripheral modules}
+ The peripheral modules use a slightly modified version of the SimpCon
+ interface. The SimpCon specific signals are pulled together to
+ records, and the words which can be read/written are limited to 16
+ bits. For accessing such a module, one may only use \texttt{load}
+ and \texttt{store} instructions which point to aligned addresses.
+
+ \paragraph{UART}
+ The built-in UART is derived from the sc\_uart from Martin
+ Sch\"oberl. Apart from adapting the SimpCon interface, an interrupt
+ line and two bits for enabling/masking receive (bit 3 in the status
+ register) and transmit (bit 2) interrupts. In the current version
+ address 0xFFF8 (-8) correspond to the UART's status register and
+ address 0xFFFA (-6) to the wr\_data/rd\_data register.
+
+ \subsubsection{Interrupt unit}
+ The interrupt unit takes care of the interrupt vectors and, of
+ course, the triggering of interrupts. Interrupts are executed only
+ if the global interrupt flag is set, none of the other units is busy
+ and the instruction in the execution stage is valid (it takes 3
+ cycles after jumps, branches etc. until a new valid instruction is
+ in that stage).
+
+ Instructions which cannot be decoded as well as the ``error''
+ instruction trigger interrupt 0; the ALU can trigger interrupt 1
+ (division by zero), the memory unit can trigger interrupt 2 (invalid
+ memory access). In contrast to all other interrupts, these three
+ interrupts do not repeat the instruction which is executed when they
+ occur.
+
+ \subsection{Write back}
+ The write back stage passes on the result of the execution stage to
+ all other stages.
+
+ \section{Assembler}
+ The assembler \textsl{spar} (SPear Assembler Recycled) uses a syntax
+ quite like usual Unix-style assemblers. It accepts the pseudo-ops
+ \texttt{.file}, \texttt{.text}, \texttt{.data}, \texttt{.bss},
+ \texttt{.align}, \texttt{.comm}, \texttt{.lcomm}, \texttt{.org} and
+ \texttt{.skip} with the usual meanings. The mnemonic \texttt{data}
+ initializes a byte to some constant value. In difference to the
+ instruction set architecture specification, \texttt{mod} and
+ \texttt{umod} accept three operands (if a move is needed, it is
+ silently inserted).
+
+ The assembler produces three files: one file for the instruction
+ ROM, one file for the even bytes of the data ROM and one file for
+ the odd bytes of the instruction ROM. The splitting of the data is
+ necessary, because the data memories internally are split into two
+ 8-bit memories in order to support unaligned memory accesses without
+ delays.
+
+ Three output formats are supported: .mif (Memory Initialization
+ Format), .hex (Intel Hex Format) and a binary format designed for
+ download via UART.
+
+ \section{Resource usage and speed}
+
+ The processor was synthesized with \textsl{Quartus II} for the
+ \textsl{Cyclone EP1C12Q240C8} FPGA with 12060 logic cells and 29952
+ bytes of on-chip memory available.
+
+ The processor needs $\sim$3550 logic cells or 29\% when being
+ compiled for maximum clock frequency, which is $\sim$60 MHz. When
+ optimizing for area, it needs $\sim$2600 logic cells or 22\% at
+ $\sim$25 MHz.
+
+ The processor uses 24832 bytes or 83\% of on-chip memory.
+
+ \section{Example}
+
+ \subsection{Reversing a line}
+
+ In listing \ref{lst:uart} one can see how to interface the uart via
+ interrupts. The program reads in a line from the UART and the writes
+ it back reversed. The lines 1 to 4 show how to instantiate memory
+ (the two bytes defined form the DOS-style end-of-line). The
+ lines 7 to 25 initialize the registers and register the interrupt
+ vectors, line 28 builds a barrier against the rest of the code.
+
+ The lines 32 to 76 form the interrupt service routine. It first
+ checks if it is operating in read or in write mode. When reading, it
+ reads from the UART and stores the result. A mode switch occurs when
+ a newline character is encountered. In write mode the contents of
+ the buffer is written to the UART and switching back to read mode is
+ done when finished.
+
+ In figure \ref{fig:sim} the results of the simulation are presented.
+
+ \lstset{basicstyle=\footnotesize,numbers=left,numberstyle=\tiny}
+ \lstset{caption=Example for the UART and interrupts}
+ \lstset{label=lst:uart}
+ \lstinputlisting{uart_reverse.s}
+
+ \begin{figure}[ht!]
+ \centering
+ \includegraphics[width=.95\textwidth]{uart_sim}
+ \caption{Simulation results}
+ \label{fig:sim}
+ \end{figure}
+
+ \subsection{Computing factorials}
+
+ The example in \ref{lst:fact} computes the factorials of 1 \ldots 9
+ and writes the results to the PC via UART. Note that the last result
+ transmitted will be wrong, because it is truncated to 16 bits.
+
+ \lstset{basicstyle=\footnotesize,numbers=left,numberstyle=\tiny}
+ \lstset{caption=Computing factorials}
+ \lstset{label=lst:fact}
+ \lstinputlisting{factorial.s}
+
+
+ \section{Versions Of This Document}
+
+ 2006-12-14: Draft version \textbf{0.1}
+
+ \noindent
+ 2006-12-29: Draft version \textbf{0.2}
+ \begin{itemize}
+ \item A few refinements.
+ \end{itemize}
+
+ \noindent
+ 2007-01-22: Draft version \textbf{0.3}
+ \begin{itemize}
+ \item Added another example.
+ \end{itemize}
+
+ \noindent
+ 2007-02-02: Draft version \textbf{0.4}
+ \begin{itemize}
+ \item Updated resource usage and speed section.
+ \end{itemize}
+
+\end{document}
Index: trunk/doc/factorial.s
===================================================================
--- trunk/doc/factorial.s (nonexistent)
+++ trunk/doc/factorial.s (revision 2)
@@ -0,0 +1,134 @@
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;; factorial
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;; compute factorials of 1 to 9 and write results to
+;;; the PC via UART
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+.data
+
+;;; the numbers to be written are placed here
+iobuf:
+ data 0x0A
+ data 0x0D
+ data 0
+ data 0
+ data 0
+ data 0
+ data 0
+ data 0
+
+;;; stack for recursive calls of factorial()
+stack:
+
+.text
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;; main()
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+ ldib r15, 1 ; number to start
+ ldib r5, 10 ; number to stop
+
+ ldil r1, lo(stack) ; setup for factorial()
+ ldih r1, hi(stack)
+ ldil r2, lo(factorial)
+ ldih r2, hi(factorial)
+
+ ldib r6, 0x30 ; setup for convert()
+ ldib r7, 10
+ ldil r8, lo(iobuf)
+ ldih r8, hi(iobuf)
+ ldil r9, lo(convert)
+ ldih r9, hi(convert)
+
+ ldib r12, -8 ; enable write interrupts
+ ldib r11, (1 << 2)
+ store r11, r12
+
+ ldil r12, lo(isr) ; register isr() to be called upon
+ ldih r12, hi(isr) ; interrupt #3
+ stvec r12, 3
+
+ ldib r12, -6 ; address where to write data
+ ; to the UART
+
+loop:
+ mov r0, r15 ; r0 is the argument
+ call r2, r3 ; call factorial()
+ call r9, r3 ; call convert()
+
+wait: getfl r13
+ btest r13, 4 ; interrupts still enabled?
+ brnz wait
+
+ addi r15, 1 ; loop
+ cmp r15, r5
+ brnz loop
+
+exit: br exit ; stop here after all
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;; converting content of r4 to a string
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+convert:
+ addi r8, 2
+convert_loop:
+ umod r4, r7, r10 ; the conversion
+ add r10, r6, r10
+ storel r10, r8
+ addi r8, 1
+
+ udiv r4, r7, r4 ; next digit
+
+ cmpi r4, 0
+ brnz convert_loop
+
+ sei ; trigger write
+ jmp r3
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;; write out content of iobuf
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+isr:
+ cmpi r8, iobuf ; reached end?
+ brz written
+
+ addi r8, -1 ; write data to UART
+ loadb r10, r8
+ store r10, r12
+
+ reti
+
+written:
+ getshfl r10
+ bclr r10, 4 ; clear interrupt flag
+ setshfl r10
+ reti
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;; recursively compute factorial
+;;; argument: r0
+;;; return value: r4
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+factorial:
+ cmpi r0, 1 ; reached end?
+ brule fact_leaf
+
+ store r0, r1 ; push argument and return
+ addi r1, 2 ; address onto stack
+ store r3, r1
+ addi r1, 2
+
+ addi r0, -1 ; call factorial(r0-1)
+ call r2, r3
+
+ addi r1, -2 ; pop argument and return
+ load r3, r1 ; address from stack
+ addi r1, -2
+ load r0, r1
+
+ mul r0, r4, r4 ; return r0*factorial(r0-1)
+ jmp r3
+
+fact_leaf: ; factorial(1) = 1
+ ldib r4, 1
+ jmp r3
Index: trunk/doc/marca.png
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: trunk/doc/marca.png
===================================================================
--- trunk/doc/marca.png (nonexistent)
+++ trunk/doc/marca.png (revision 2)
trunk/doc/marca.png
Property changes :
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: trunk/doc/uart_sim.png
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: trunk/doc/uart_sim.png
===================================================================
--- trunk/doc/uart_sim.png (nonexistent)
+++ trunk/doc/uart_sim.png (revision 2)
trunk/doc/uart_sim.png
Property changes :
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: trunk/doc/uart_reverse.s
===================================================================
--- trunk/doc/uart_reverse.s (nonexistent)
+++ trunk/doc/uart_reverse.s (revision 2)
@@ -0,0 +1,79 @@
+.data
+ data 0x0A
+ data 0x0D
+buffer:
+
+.text
+;;; initialization
+ ldib r0, -8 ; config/status
+ ldib r1, -6 ; data
+
+ ldil r2, lo(buffer) ; buffer address
+ ldih r2, hi(buffer) ; buffer address
+
+ ldib r3, 0x0A ; newline character
+ ldib r4, 0x0D ; carriage return
+
+ ldib r5, 0 ; mode
+
+ ldib r7, isr ; register isr
+ stvec r7, 3
+
+ ldib r7, (1 << 3) ; enable receive interrupts
+ store r7, r0
+
+ sei ; enable interrupts
+
+;;; loop forever
+loop: br loop
+
+
+;;; ISR
+isr:
+ cmpi r5, 0 ; check mode
+ brnz write_mode
+
+;;; reading
+read_mode:
+ load r7, r1 ; read data
+
+ cmp r7, r3 ; change mode upon newline
+ brnz read_CR
+
+ ldib r7, (1 << 2) ; do the change
+ store r7, r0
+ ldib r5, 1
+ reti
+
+read_CR:
+ cmp r7, r4 ; ignore carriage return
+ brnz read_cont
+ reti
+
+read_cont:
+ storel r7, r2 ; store date
+ addi r2, 1
+ reti
+
+;;; writing
+write_mode:
+ addi r2, -1
+
+ cmpi r2, -1 ; change mode if there is no more data
+ brnz write_cont
+
+ ldil r2, lo(buffer) ; correct pointer to buffer
+ ldih r2, hi(buffer)
+
+ ldib r7, (1 << 3) ; do the change
+ store r7, r0
+ ldib r5, 0
+ reti
+
+write_cont:
+ loadl r7, r2 ; write data
+ store r7, r1
+ reti
+
+
+
Index: trunk/doc/marca.eps
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: trunk/doc/marca.eps
===================================================================
--- trunk/doc/marca.eps (nonexistent)
+++ trunk/doc/marca.eps (revision 2)
trunk/doc/marca.eps
Property changes :
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: trunk/doc/uart_sim.eps
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: trunk/doc/uart_sim.eps
===================================================================
--- trunk/doc/uart_sim.eps (nonexistent)
+++ trunk/doc/uart_sim.eps (revision 2)
trunk/doc/uart_sim.eps
Property changes :
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: trunk/doc/isa.tex
===================================================================
--- trunk/doc/isa.tex (nonexistent)
+++ trunk/doc/isa.tex (revision 2)
@@ -0,0 +1,245 @@
+\documentclass[10pt, twoside, a4paper]{article}
+\usepackage{longtable}
+
+\newcommand{\shl}{\ensuremath{<\!\!<}}
+\newcommand{\shr}{\ensuremath{>\!\!>\!\!>}}
+\newcommand{\sar}{\ensuremath{>\!\!>}}
+\newcommand{\at}{\ensuremath{\!\!:\!\!}}
+
+\title{marca - McAdam's RISC Computer Architecture\\Instruction Set Architecture}
+\author{Kenan Bilic, Roland Kammerer, Wolfgang Puffitsch}
+
+\begin{document}
+
+ \maketitle
+
+ \section{General}
+
+ \begin{itemize}
+ \item 16 16-bit registers, r0 \ldots r15
+ \item any register as return address
+ \item flags: Z, C, V, N
+ \begin{itemize}
+ \item Z: all bits of the last result are zero
+ \item C: ``17$^{th}$ bit'' of the last result
+ \item N: 16$^{th}$ bit of the last result
+ \item V: overflow, after sub/cmp it is $r1 \at 15 \oplus r2 \at 15
+ \oplus N \oplus C$, the latter two according to the result,
+ other operations accordingly
+ \item I: allow interrupts
+ \item P: parity of the last result
+ \end{itemize}
+ Flags are written where meaningful: P and Z are computed whenever
+ a register is written, arithmetic operations may change C, N and
+ V, interrupts clear I upon entry.
+ \item flags are stored and restored upon interrupt entry and exit
+ to/from ``shflags'' (shadow flags)
+ \item separate registers for interrupt vectors - read and written
+ through ``ldvec'' / ``stvec''
+ \item Some parts come from the Alpha architecture. The handling of
+ branches is inspired by the Intel x86.
+ \item External hardware modules shall be mapped to the highest
+ memory locations.
+ \end{itemize}
+
+ The processor uses a Harvard architecture; although it has not
+ prevailed in mainstream-architectures, it is still used in embedded
+ processors such as the Atmel AVR. The separation of code- and
+ data-memory is not flexible enough for mainstream systems, but with
+ small embedded processors the program code tends to be fixed
+ anyway. A Harvard architecture enables the processor to make use of
+ more memory (which is an issue when the address space is limited to
+ 64k), and the program code can be read from a ROM directly. A
+ transient failure thus cannot destroy the program by overwriting its
+ code section.
+
+ \clearpage
+
+ \section{Instruction Set}
+
+ {\small
+ \begin{longtable}{llp{.62\textwidth}}
+ Instruction & Opcode & Semantics \\
+ add r1, r2, r3 & \texttt{0000} & $r1 + r2 \rightarrow r3$ \\
+ sub r1, r2, r3 & \texttt{0001} & $r1 - r2 \rightarrow r3$ \\
+ addc r1, r2, r3 & \texttt{0010} & $r1 + r2 + C \rightarrow r3$ \\
+ subc r1, r2, r3 & \texttt{0011} & $r1 - r2 - C \rightarrow r3$ \\
+ and r1, r2, r3 & \texttt{0100} & $r1 \wedge r2 \rightarrow r3$ \\
+ or r1, r2, r3 & \texttt{0101} & $r1 \vee r2 \rightarrow r3$ \\
+ xor r1, r2, r3 & \texttt{0110} & $r1 \oplus r2 \rightarrow r3$ \\
+ mul r1, r2, r3 & \texttt{0111} & $r1 * r2 \rightarrow r3$ \\
+ div r1, r2, r3 & \texttt{1000} & $r1 \div r2 \rightarrow r3$ \\
+ udiv r1, r2, r3 & \texttt{1001} & $r1 \div r2 \rightarrow r3, \textnormal{unsigned} $ \\
+ ldil r1, n8 & \texttt{1010} & $(r1 \wedge \texttt{0xff00}) \vee n8 \rightarrow r1, -128 \leq n8 \leq 255 $ \\
+ ldih r1, n8 & \texttt{1011} & $(r1 \wedge \texttt{0x00ff}) \vee (n8 \shl 8) \rightarrow r1, -128 \leq n8 \leq 255 $ \\
+ ldib r1, n8 & \texttt{1100} & $n8 \rightarrow r1, -128 \leq n8 \leq 127$ \\
+ \hline
+ mov r1, r2 & \texttt{11010000} & $r2 \rightarrow r1$ \\
+ mod r1, r2 & \texttt{11010001} & $r1\ \textnormal{mod}\ r2 \rightarrow r1$ \\
+ umod r1, r2 & \texttt{11010010} & $r1\ \textnormal{mod}\ r2 \rightarrow r1, \textnormal{unsigned} $ \\
+ not r1, r2 & \texttt{11010011} & $\lnot r2 \rightarrow r1$ \\
+ neg r1, r2 & \texttt{11010100} & $-r1 \rightarrow r2$ \\
+ cmp r1, r2 & \texttt{11010101} & $r1 - r2, \textnormal{sets flags}$ \\
+ addi r1, n4 & \texttt{11010110} & $r1 + n4 \rightarrow r1, -8 \leq n4 \leq 7$ \\
+ cmpi r1, n4 & \texttt{11010111} & $r1 - n4, \textnormal{sets flags}, -8 \leq n4 \leq 7$ \\
+ shl r1, r2 & \texttt{11011000} & $r1 \shl r2 \rightarrow r1$ \\
+ shr r1, r2 & \texttt{11011001} & $r1 \shr r2 \rightarrow r1$ \\
+ sar r1, r2 & \texttt{11011010} & $r1 \sar r2 \rightarrow r1$ \\
+ rolc r1, r2 & \texttt{11011011} & $(r1 \shl r2) \vee (C \shl (r2-1)) \vee (r1 \shr (16-r2-1))$ \\
+ rorc r1, r2 & \texttt{11011100} & $(r1 \shr r2) \vee (C \shl (16-r2)) \vee (r1 \shl (16-r2-1))$ \\
+ bset r1, n4 & \texttt{11011101} & $r1 \vee (1 \shl n4) \rightarrow r1, 0 \leq n4 \leq 15$ \\
+ bclr r1, n4 & \texttt{11011110} & $r1 \wedge \lnot (1 \shl n4) \rightarrow r1, 0 \leq n4 \leq 15$ \\
+ btest r1, n4 & \texttt{11011111} & $(r1 \shr n4) \wedge 1 \rightarrow Z, 0 \leq n4 \leq 15$ \\
+ \hline
+ load r1, r2 & \texttt{11100000} & $[r2] \at [r2+1] \rightarrow r1$ \\
+ store r1, r2 & \texttt{11100001} & $r1 \rightarrow [r2] \at [r2+1]$ \\
+ loadl r1, r2 & \texttt{11100010} & $(r1 \wedge \texttt{0xff00}) \vee [r2] \rightarrow r1$ \\
+ loadh r1, r2 & \texttt{11100011} & $(r1 \wedge \texttt{0x00ff}) \vee ([r2] \shl 8) \rightarrow r1$ \\
+ loadb r1, r2 & \texttt{11100100} & $[r2] \rightarrow r1, \textnormal{signed}$ \\
+ storel r1, r2 & \texttt{11100101} & $(r1 \wedge \texttt{0x00ff}) \rightarrow [r2]$ \\
+ storeh r1, r2 & \texttt{11100110} & $(r1 \shr 8) \rightarrow [r2]$ \\
+ call r1, r2 & \texttt{11101000} & $r1 \rightarrow pc, pc \rightarrow r2$ \\
+ \hline
+ br n8 & \texttt{11110000} & $pc + n8 \rightarrow pc, -128 \leq n8 \leq 127$ \\
+ brz n8 & \texttt{11110001} & $Z = 1 \Rightarrow pc + n8 \rightarrow pc, -128 \leq n8 \leq 127$ \\
+ brnz n8 & \texttt{11110010} & $Z = 0 \Rightarrow pc + n8 \rightarrow pc, -128 \leq n8 \leq 127$ \\
+ brle n8 & \texttt{11110011} & $(Z = 1) \vee (N \not = V) \Rightarrow pc + n8 \rightarrow pc, -128 \leq n8 \leq 127$ \\
+ brlt n8 & \texttt{11110100} & $(Z = 0) \wedge (N \not = V) \Rightarrow pc + n8 \rightarrow pc, -128 \leq n8 \leq 127$ \\
+ brge n8 & \texttt{11110101} & $(Z = 1) \vee (N = V) \Rightarrow pc + n8 \rightarrow pc, -128 \leq n8 \leq 127$ \\
+ brgt n8 & \texttt{11110110} & $(Z = 0) \wedge (N = V) \Rightarrow pc + n8 \rightarrow pc, -128 \leq n8 \leq 127$ \\
+ brule n8 & \texttt{11110111} & $(Z = 1) \vee (C = 1) \Rightarrow pc + n8 \rightarrow pc, -128 \leq n8 \leq 127$ \\
+ brult n8 & \texttt{11111000} & $(Z = 0) \wedge (C = 1) \Rightarrow pc + n8 \rightarrow pc, -128 \leq n8 \leq 127$ \\
+ bruge n8 & \texttt{11111001} & $(Z = 1) \vee (C = 0) \Rightarrow pc + n8 \rightarrow pc, -128 \leq n8 \leq 127$ \\
+ brugt n8 & \texttt{11111010} & $(Z = 0) \wedge (C = 0) \Rightarrow pc + n8 \rightarrow pc, -128 \leq n8 \leq 127$ \\
+ sext r1, r2 & \texttt{11111011} & $(r1 \shl 8) \sar 8 \rightarrow r2$ \\
+ ldvec r1, n4 & \texttt{11111100} & $\textnormal{interrupt vector}\ n4 \rightarrow r1, 0 \leq n4 \leq 15$ \\
+ stvec r1, n4 & \texttt{11111101} & $r1 \rightarrow \textnormal{interrupt vector}\ n4, 0 \leq n4 \leq 15$ \\
+ \hline
+ jmp r1 & \texttt{111111100000} & $r1 \rightarrow pc$ \\
+ jmpz r1 & \texttt{111111100001} & $Z = 1 \Rightarrow r1 \rightarrow pc$ \\
+ jmpnz r1 & \texttt{111111100010} & $Z = 0 \Rightarrow r1 \rightarrow pc$ \\
+ jmple r1 & \texttt{111111100011} & $(Z = 1) \vee (N \not = V) \Rightarrow r1 \rightarrow pc$ \\
+ jmplt r1 & \texttt{111111100100} & $(Z = 0) \wedge (N \not = V) \Rightarrow r1 \rightarrow pc$ \\
+ jmpge r1 & \texttt{111111100101} & $(Z = 1) \vee (N = V) \Rightarrow r1 \rightarrow pc$ \\
+ jmpgt r1 & \texttt{111111100110} & $(Z = 0) \wedge (N = V) \Rightarrow r1 \rightarrow pc$ \\
+ jmpule r1 & \texttt{111111100111} & $(Z = 1) \vee (C = 1) \Rightarrow r1 \rightarrow pc$ \\
+ jmpult r1 & \texttt{111111101000} & $(Z = 0) \wedge (C = 1) \Rightarrow r1 \rightarrow pc$ \\
+ jmpuge r1 & \texttt{111111101001} & $(Z = 1) \vee (C = 0) \Rightarrow r1 \rightarrow pc$ \\
+ jmpugt r1 & \texttt{111111101010} & $(Z = 0) \wedge (C = 0) \Rightarrow r1 \rightarrow pc$ \\
+ intr n4 & \texttt{111111101011} & $\textnormal{interrupt vector}\ n4 \rightarrow pc, pc \rightarrow ira, flags \rightarrow shflags, 0 \leq n4 \leq 15$ \\
+ getira r1 & \texttt{111111101100} & $ira \rightarrow r1$ \\
+ setira r1 & \texttt{111111101101} & $r1 \rightarrow ira$ \\
+ getfl r1 & \texttt{111111101110} & $flags \rightarrow r1$ \\
+ setfl r1 & \texttt{111111101111} & $r1 \rightarrow flags$ \\
+ getshfl r1 & \texttt{111111110000} & $shflags \rightarrow r1$ \\
+ setshfl r1 & \texttt{111111110001} & $r1 \rightarrow shflags$ \\
+ \hline
+ reti & \texttt{1111111111110000} & $ira \rightarrow pc, shflags \rightarrow flags$ \\
+ nop & \texttt{1111111111110001} & $\textnormal{do nothing}$ \\
+ sei & \texttt{1111111111110010} & $1 \rightarrow I$ \\
+ cli & \texttt{1111111111110011} & $0 \rightarrow I$ \\
+ error & \texttt{1111111111111111} & $\textnormal{invalid operation}$ \\
+ \end{longtable}}
+
+ \subsection{NOTES}
+ \begin{itemize}
+ \item Apart from the standard operators, the following notation is
+ used in the table above:
+ \begin{itemize}
+ \item \shl, \shr, \sar are shifting operators, with semantics as in Java
+ \item $[x]$ means accessing memory location $x$, 8 bits wide
+ \item $x \at y$ means concatenating $x$ and $y$, in the sense of
+ forming a 16-bit value from two 8-bit values
+ \end{itemize}
+ \item Modulo does not follow the patterns for ``div'' and ``udiv'',
+ because there was not enough room for two more 3-operand
+ operations. The assembler accepts the mnemonic with 3 registers as
+ operands and substitute it with the according ``mov'' and ``mod''
+ instructions.
+ \end{itemize}
+
+ \clearpage
+
+ \subsection{Instruction formats}
+
+ The following formats for instructions are to be used:
+
+ \begin{center}
+ \begin{tabular}{|p{1in}|p{1in}|p{1in}|p{1in}|}
+ \hline
+ Bits 15 \ldots 12 & Bits 11 \ldots 8 & Bits 7 \ldots 4 & Bits 3 \ldots 0 \\
+ \hline
+ Opcode & r3 & r2 & r1 \\
+ \hline
+ Opcode & \multicolumn{2}{|l|}{n8} & r1 \\
+ \hline
+ \multicolumn{2}{|l|}{Opcode} & r2 & r1 \\
+ \hline
+ \multicolumn{2}{|l|}{Opcode} & n4 & r1 \\
+ \hline
+ \multicolumn{2}{|l|}{Opcode} & \multicolumn{2}{|l|}{n8} \\
+ \hline
+ \multicolumn{3}{|l|}{Opcode} & r1 \\
+ \hline
+ \multicolumn{3}{|l|}{Opcode} & n4 \\
+ \hline
+ \multicolumn{4}{|l|}{Opcode} \\
+ \hline
+ \end{tabular}
+ \end{center}
+
+ \section{Versions Of This Document}
+
+ 2006-10-04: Draft version \textbf{0.1}
+
+ \noindent
+ 2006-10-05: Draft version \textbf{0.2}
+ \begin{itemize}
+ \item rearrangement of some ops
+ \end{itemize}
+
+ \noindent
+ 2006-10-11: Draft version \textbf{0.3}
+ \begin{itemize}
+ \item replaced ``ror''/``rol'' with ``mod''/``umod''
+ \item refined considerations of direction flag
+ \item proposal for priorities of implementation
+ \end{itemize}
+
+ \noindent
+ 2006-10-28: Draft version \textbf{0.4}
+ \begin{itemize}
+ \item settled to singed loads
+ \item settled to shifts by registers
+ \item dropped ``push''/``pop''; the secondary result would cause a
+ considerable overhead
+ \item specified pipelining
+ \end{itemize}
+
+ \noindent
+ 2006-10-30: Draft version \textbf{0.5}
+ \begin{itemize}
+ \item added shflags to ease interrupt (and stack) handling
+ \item a few refinements
+ \end{itemize}
+
+ \noindent
+ 2006-12-02: Draft version \textbf{0.6}
+ \begin{itemize}
+ \item the first register is the target with ``mov'' and ``not'' now.
+ \item now the second register is always the address when accessing memory
+ \item reversed order with immediate loads
+ \item ``ldvec'' and ``stvec'' use the same order now
+ \item fixed instruction format for immediate loads
+ \end{itemize}
+
+ \noindent
+ 2006-12-14: Draft version \textbf{0.7}
+ \begin{itemize}
+ \item dropped ``ldpgm'' in favor of a ROM which is mapped to the
+ ordinary memory space
+ \item moved section about pipelinign to the implementation document
+ \item removed note about interrupts; they are implemented already
+ \end{itemize}
+
+\end{document}
Index: trunk/doc/Makefile
===================================================================
--- trunk/doc/Makefile (nonexistent)
+++ trunk/doc/Makefile (revision 2)
@@ -0,0 +1,19 @@
+all: isa.ps.gz isa.pdf implementation.ps.gz implementation.pdf
+
+EXTERN_DATA: factorial.s uart_reverse.s marca.eps marca.png uart_sim.eps uart_sim.png
+
+%.dvi: %.tex $(EXTERN_DATA)
+ latex $<
+ latex $<
+
+%.ps: %.dvi
+ dvips $< -o $@
+
+%.ps.gz: %.ps
+ gzip -c < $< > $@
+
+%.pdf: %.tex %.dvi
+ pdflatex $<
+
+clean:
+ rm -f *.ps *.pdf *.dvi *.aux *.log
\ No newline at end of file
Index: trunk/spar/emit.c
===================================================================
--- trunk/spar/emit.c (nonexistent)
+++ trunk/spar/emit.c (revision 2)
@@ -0,0 +1,232 @@
+/* This file is part of the assembler "spar" for marca.
+ Copyright (C) 2007 Wolfgang Puffitsch
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library 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 */
+
+#include
+
+#include
+#include
+
+#include "spar.h"
+#include "optab.h"
+#include "code.h"
+#include "emit.h"
+#include "exprs.h"
+#include "segtab.h"
+
+void emit_op(struct seg *seg, struct op op)
+{
+ adjust_segsize(seg, seg->pos+1);
+ seg->code[seg->pos] = op;
+ seg->pos++;
+}
+
+void emit_nop(struct seg *seg)
+{
+ adjust_segsize(seg, seg->pos+1);
+ set_op(seg, seg->pos, NOP);
+
+ trace_listing(seg, seg->pos, "nop");
+
+ seg->pos++;
+}
+
+void emit_zero(struct seg *seg)
+{
+ adjust_segsize(seg, seg->pos+1);
+ set_op(seg, seg->pos, DATA);
+ set_expr(seg, seg->pos, 0, "0");
+ set_mode(seg, seg->pos, 0, 'n');
+
+ trace_listing(seg, seg->pos, "data 0");
+
+ seg->pos++;
+}
+
+void emit_data(struct seg *seg, char *expr)
+{
+ char *buf = xmalloc(CODE_MAX_LISTLEN);
+
+ adjust_segsize(seg, seg->pos+1);
+ set_op(seg, seg->pos, DATA);
+ set_expr(seg, seg->pos, 0, expr);
+ set_mode(seg, seg->pos, 0, 'n');
+
+ snprintf(buf, CODE_MAX_LISTLEN, "data\t%s", expr);
+ trace_listing(seg, seg->pos, buf);
+
+ seg->pos++;
+
+ free(buf);
+}
+
+void emit_ldil(struct seg *seg, uint16_t reg, char *expr)
+{
+ char *buf = xmalloc(CODE_MAX_LISTLEN);
+
+ adjust_segsize(seg, seg->pos+1);
+ set_op(seg, seg->pos, LDIL);
+ set_regnum(seg, seg->pos, 0, reg);
+ set_mode(seg, seg->pos, 0, 'r');
+ set_expr(seg, seg->pos, 1, expr);
+ set_mode(seg, seg->pos, 1, 'n');
+
+ snprintf(buf, CODE_MAX_LISTLEN, "ldil\tr%d, %s", reg, expr);
+ trace_listing(seg, seg->pos, buf);
+ seg->pos++;
+
+ free(buf);
+}
+
+void emit_ldih(struct seg *seg, uint16_t reg, char *expr)
+{
+ char *buf = xmalloc(CODE_MAX_LISTLEN);
+
+ adjust_segsize(seg, seg->pos+1);
+ set_op(seg, seg->pos, LDIH);
+ set_regnum(seg, seg->pos, 0, reg);
+ set_mode(seg, seg->pos, 0, 'r');
+ set_expr(seg, seg->pos, 1, expr);
+ set_mode(seg, seg->pos, 2, 'n');
+
+ snprintf(buf, CODE_MAX_LISTLEN, "ldih\tr%d, %s", reg, expr);
+ trace_listing(seg, seg->pos, buf);
+ seg->pos++;
+
+ free(buf);
+}
+
+void emit_ldib(struct seg *seg, uint16_t reg, char *expr)
+{
+ char *buf = xmalloc(CODE_MAX_LISTLEN);
+
+ adjust_segsize(seg, seg->pos+1);
+ set_op(seg, seg->pos, LDIB);
+ set_regnum(seg, seg->pos, 0, reg);
+ set_mode(seg, seg->pos, 0, 'r');
+ set_expr(seg, seg->pos, 1, expr);
+ set_mode(seg, seg->pos, 1, 'n');
+
+ snprintf(buf, CODE_MAX_LISTLEN, "ldib\tr%d, %s", reg, expr);
+ trace_listing(seg, seg->pos, buf);
+ seg->pos++;
+
+ free(buf);
+}
+
+void emit_addi(struct seg *seg, uint16_t reg, char *expr)
+{
+ char *buf = xmalloc(CODE_MAX_LISTLEN);
+
+ adjust_segsize(seg, seg->pos+1);
+ set_op(seg, seg->pos, ADDI);
+ set_regnum(seg, seg->pos, 0, reg);
+ set_mode(seg, seg->pos, 0, 'r');
+ set_expr(seg, seg->pos, 1, expr);
+ set_mode(seg, seg->pos, 1, 'n');
+
+ snprintf(buf, CODE_MAX_LISTLEN, "addi\tr%d, %s", reg, expr);
+ trace_listing(seg, seg->pos, buf);
+ seg->pos++;
+
+ free(buf);
+}
+
+void emit_cmp(struct seg *seg, uint16_t reg1, uint16_t reg2)
+{
+ char *buf = xmalloc(CODE_MAX_LISTLEN);
+
+ adjust_segsize(seg, seg->pos+1);
+ set_op(seg, seg->pos, CMP);
+ set_regnum(seg, seg->pos, 0, reg1);
+ set_mode(seg, seg->pos, 0, 'r');
+ set_regnum(seg, seg->pos, 1, reg2);
+ set_mode(seg, seg->pos, 1, 'r');
+
+ snprintf(buf, CODE_MAX_LISTLEN, "cmp\tr%d, r%d", reg1, reg2);
+ trace_listing(seg, seg->pos, buf);
+ seg->pos++;
+
+ free(buf);
+}
+
+void emit_load(struct seg *seg, uint16_t reg1, uint16_t reg2)
+{
+ char *buf = xmalloc(CODE_MAX_LISTLEN);
+
+ adjust_segsize(seg, seg->pos+1);
+ set_op(seg, seg->pos, LOAD);
+ set_regnum(seg, seg->pos, 0, reg1);
+ set_mode(seg, seg->pos, 0, 'r');
+ set_regnum(seg, seg->pos, 1, reg2);
+ set_mode(seg, seg->pos, 1, 'r');
+
+ snprintf(buf, CODE_MAX_LISTLEN, "load\tr%d, r%d", reg1, reg2);
+ trace_listing(seg, seg->pos, buf);
+ seg->pos++;
+
+ free(buf);
+}
+
+void emit_store(struct seg *seg, uint16_t reg1, uint16_t reg2)
+{
+ char *buf = xmalloc(CODE_MAX_LISTLEN);
+
+ adjust_segsize(seg, seg->pos+1);
+ set_op(seg, seg->pos, STORE);
+ set_regnum(seg, seg->pos, 0, reg1);
+ set_mode(seg, seg->pos, 0, 'r');
+ set_regnum(seg, seg->pos, 1, reg2);
+ set_mode(seg, seg->pos, 1, 'r');
+
+ snprintf(buf, CODE_MAX_LISTLEN, "store\tr%d, r%d", reg1, reg2);
+ trace_listing(seg, seg->pos, buf);
+ seg->pos++;
+
+ free(buf);
+}
+
+void emit_jmp(struct seg *seg, uint16_t reg)
+{
+ char *buf = xmalloc(CODE_MAX_LISTLEN);
+
+ adjust_segsize(seg, seg->pos+1);
+ set_op(seg, seg->pos, JMP);
+ set_regnum(seg, seg->pos, 0, reg);
+ set_mode(seg, seg->pos, 0, 'r');
+
+ snprintf(buf, CODE_MAX_LISTLEN, "jmp\tr%d", reg);
+ trace_listing(seg, seg->pos, buf);
+ seg->pos++;
+
+ free(buf);
+}
+
+void emit_brnz(struct seg *seg, char *expr)
+{
+ char *buf = xmalloc(CODE_MAX_LISTLEN);
+
+ adjust_segsize(seg, seg->pos+1);
+ set_op(seg, seg->pos, BRNZ);
+ set_expr(seg, seg->pos, 0, expr);
+ set_mode(seg, seg->pos, 0, 'a');
+
+ snprintf(buf, CODE_MAX_LISTLEN, "brnz\t%s", expr);
+ trace_listing(seg, seg->pos, buf);
+ seg->pos++;
+
+ free(buf);
+}
Index: trunk/spar/test.s
===================================================================
--- trunk/spar/test.s (nonexistent)
+++ trunk/spar/test.s (revision 2)
@@ -0,0 +1,11 @@
+.data
+data 0xaa
+data 0x55
+data 0x12
+data 0x34
+.text
+add r1, r2, r3
+.bss
+data 0
+data 0
+data 0
\ No newline at end of file
Index: trunk/spar/symtab.c
===================================================================
--- trunk/spar/symtab.c (nonexistent)
+++ trunk/spar/symtab.c (revision 2)
@@ -0,0 +1,119 @@
+/* This file is part of the assembler "spar" for marca.
+ Copyright (C) 2007 Wolfgang Puffitsch
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library 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 */
+
+#include
+#include
+#include
+#include
+
+#include "spar.h"
+#include "symtab.h"
+
+static struct sym_info *symtab[SYMTAB_SIZE];
+
+uint32_t hash_string (const char *str)
+{
+ uint32_t hash;
+ const char *ptr = str;
+ size_t len = strlen(str);
+ for (hash = 0; len; len--, ptr++)
+ {
+ hash = 31 * hash + *ptr;
+ }
+ return hash;
+}
+
+char *trim_string (char *str)
+{
+ while ((str[0] == ' ') || (str[0] == '\t'))
+ {
+ str++;
+ }
+ while ((str[strlen(str)-1] == ' ')
+ || (str[strlen(str)-1] == '\t'))
+ {
+ str[strlen(str)-1] = '\0';
+ }
+ return str;
+}
+
+char *localize_string (char *str)
+{
+ if (str[0] == '.')
+ {
+ char *buf = xmalloc(strlen(str)+10);
+ sprintf(buf, "%s@%08lx", str, file_count);
+ return buf;
+ }
+ return str;
+}
+
+void init_symtab(void)
+{
+ int i;
+ for (i = 0; i < SYMTAB_SIZE; i++)
+ {
+ symtab[i] = NULL;
+ }
+}
+
+void push_sym(const char *symbol, uint8_t type, uint32_t addr)
+{
+ uint32_t pos;
+ struct sym_info *sym;
+
+ pos = hash_string(symbol) % SYMTAB_SIZE;
+ sym = xmalloc(sizeof(struct sym_info));
+ sym->symbol = symbol;
+ sym->type = type;
+ sym->addr = addr;
+ sym->next = symtab[pos];
+ symtab[pos] = sym;
+}
+
+struct sym_info *get_sym(const char *symbol)
+{
+ uint32_t pos;
+ struct sym_info *sym;
+
+ pos = hash_string(symbol) % SYMTAB_SIZE;
+ sym = symtab[pos];
+
+ while ((sym != NULL) && (strcmp(sym->symbol, symbol) != 0))
+ {
+ sym = sym->next;
+ }
+
+ return sym;
+}
+
+void reloc_syms(uint8_t type, uint32_t offset)
+{
+ uint32_t pos;
+ struct sym_info *sym;
+
+ for (pos = 0; pos < SYMTAB_SIZE; pos++)
+ {
+ for (sym = symtab[pos]; sym != NULL; sym = sym->next)
+ {
+ if (sym->type == type)
+ {
+ sym->addr += offset;
+ }
+ }
+ }
+}
Index: trunk/spar/output.c
===================================================================
--- trunk/spar/output.c (nonexistent)
+++ trunk/spar/output.c (revision 2)
@@ -0,0 +1,224 @@
+/* This file is part of the assembler "spar" for marca.
+ Copyright (C) 2007 Wolfgang Puffitsch
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library 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 */
+
+#include
+#include
+#include
+
+#include "spar.h"
+#include "ui.h"
+#include "output.h"
+#include "segtab.h"
+#include "code.h"
+
+char *itob(uint32_t val, uint8_t width)
+{
+ char *retval = xmalloc(width+1);
+ retval[width] = '\0';
+ while (width-- > 0)
+ {
+ retval[width] = (val & 1) ? '1' : '0';
+ val >>= 1;
+ }
+ return retval;
+}
+
+void print_download(FILE *f, FILE *r0, FILE *r1)
+{
+ struct seg *seg = get_current_seg();
+ uint32_t pos;
+
+ if (!nostart)
+ {
+ fprintf(f, "%c%c", 'U', '\n');
+ }
+ for (pos = 0; pos < seg->pos; pos++)
+ {
+ uint16_t data = get_code(seg, pos);
+ fprintf(f, "%c%c%c%c%c%c",
+ (uint8_t)((pos >> 8) & 0xFF),
+ (uint8_t)(pos & 0xFF),
+ 0,
+ (uint8_t)((data >> 8) & 0xFF),
+ (uint8_t)(data & 0xFF),
+ '\n');
+ }
+ for ( ; pos < codesize; pos++)
+ {
+ fprintf(f, "%c%c%c%c%c%c",
+ (uint8_t)((pos >> 8) & 0xFF),
+ (uint8_t)(pos & 0xFF),
+ 0,
+ (uint8_t)((filler >> 8) & 0xFF),
+ (uint8_t)(filler & 0xFF),
+ '\n');
+ }
+ if (!noend)
+ {
+ fprintf(f, "%c%c%c", 0x55, 0xFF, 1);
+ }
+}
+
+void print_intel(FILE *f, FILE *r0, FILE *r1)
+{
+ struct seg *seg;
+ uint32_t pos;
+
+ /* instructions */
+ seg = get_seg(SEG_PILE);
+ for (pos = 0; pos < seg->pos; pos++)
+ {
+ uint16_t data = get_code(seg, pos);
+ uint8_t chksum = -(2 + ((pos >> 8) & 0xFF) + (pos & 0xFF)
+ + ((data >> 8) & 0xFF) + (data & 0xFF));
+ fprintf(f, ":%02x%04x%02x%04x%02x%c",
+ 2, (uint16_t)pos, 0, data, chksum, '\n');
+ }
+ for ( ; pos < codesize; pos++)
+ {
+ uint8_t chksum = -(2 + ((pos >> 8) & 0xFF) + (pos & 0xFF)
+ + ((filler >> 8) & 0xFF) + (filler & 0xFF));
+ fprintf(f, ":%02x%04x%02x%04x%02x%c",
+ 2, (uint16_t)pos, 0, filler, chksum, '\n');
+ }
+ fprintf(f, ":00000001ff\n");
+
+ /* even ROM adresses */
+ seg = get_seg(SEG_DATA);
+ for (pos = 0; pos < seg->pos; pos+=2)
+ {
+ uint16_t data = get_code(seg, pos);
+ uint8_t chksum = -(1 + ((pos/2 >> 8) & 0xFF) + (pos/2 & 0xFF)
+ + (data & 0xFF));
+ fprintf(r0, ":%02x%04x%02x%02x%02x%c",
+ 1, (uint16_t)pos/2, 0, data & 0xFF, chksum, '\n');
+ }
+ for ( ; pos < romsize; pos+=2)
+ {
+ uint8_t chksum = -(1 + ((pos/2 >> 8) & 0xFF) + (pos/2 & 0xFF)
+ + (filler & 0xFF));
+ fprintf(r0, ":%02x%04x%02x%02x%02x%c",
+ 1, (uint16_t)pos/2, 0, filler & 0xFF, chksum, '\n');
+ }
+ fprintf(r0, ":00000001ff\n");
+
+ /* odd ROM adresses */
+ seg = get_seg(SEG_DATA);
+ for (pos = 1; pos < seg->pos; pos+=2)
+ {
+ uint16_t data = get_code(seg, pos);
+ uint8_t chksum = -(1 + ((pos/2 >> 8) & 0xFF) + (pos/2 & 0xFF)
+ + (data & 0xFF));
+ fprintf(r1, ":%02x%04x%02x%02x%02x%c",
+ 1, (uint16_t)pos/2, 0, data & 0xFF, chksum, '\n');
+ }
+ for ( ; pos < romsize; pos+=2)
+ {
+ uint8_t chksum = -(1 + ((pos/2 >> 8) & 0xFF) + (pos/2 & 0xFF)
+ + ((filler >> 8) & 0xFF) + (filler & 0xFF));
+ fprintf(r1, ":%02x%04x%02x%02x%02x%c",
+ 1, (uint16_t)pos/2, 0, filler & 0xFF, chksum, '\n');
+ }
+ fprintf(r1, ":00000001ff\n");
+}
+
+void print_mif(FILE *f, FILE *r0, FILE *r1)
+{
+ struct seg *seg;
+ uint32_t pos;
+
+ /* instructions */
+ seg = get_seg(SEG_PILE);
+
+ fprintf(f, "DEPTH=%lu;\n", codesize);
+ fprintf(f, "WIDTH=16;\n");
+ fprintf(f, "ADDRESS_RADIX=HEX;\n");
+ fprintf(f, "DATA_RADIX=BIN;\n\n");
+ fprintf(f, "CONTENT\nBEGIN\n\n");
+
+ fprintf(f, "%% Assembly output\t%%\n");
+
+ for (pos = 0; pos < seg->pos; pos++)
+ {
+ uint16_t data = get_code(seg, pos);
+ fprintf(f, "%4x:\t%s;\t%% %s\t%%\n", (uint16_t)pos,
+ itob(data, 16), get_listing(seg, pos));
+ }
+
+ if (seg->pos < codesize)
+ {
+ fprintf(f, "\n[%4x..%4x]:\t%s;\t%% Filler\t%%\n",
+ (uint16_t)seg->pos, (uint16_t)(codesize-1),
+ itob(filler, 16));
+ }
+
+ fprintf(f, "\nEND;\n");
+
+ /* even ROM addresses */
+ seg = get_seg(SEG_DATA);
+
+ fprintf(r0, "DEPTH=%lu;\n", romsize/2);
+ fprintf(r0, "WIDTH=8;\n");
+ fprintf(r0, "ADDRESS_RADIX=HEX;\n");
+ fprintf(r0, "DATA_RADIX=BIN;\n\n");
+ fprintf(r0, "CONTENT\nBEGIN\n\n");
+
+ fprintf(r0, "%% Assembly output\t%%\n");
+
+ for (pos = 0; pos < seg->pos; pos += 2)
+ {
+ uint16_t data = get_code(seg, pos);
+ fprintf(r0, "%4x:\t%s;\t%% %s\t%%\n", (uint16_t)pos/2,
+ itob(data, 8), get_listing(seg, pos));
+ }
+
+ if (seg->pos < romsize)
+ {
+ fprintf(r0, "\n[%4x..%4x]:\t%s;\t%% Filler\t%%\n",
+ (uint16_t)seg->pos/2, (uint16_t)(romsize/2-1),
+ itob(filler, 8));
+ }
+
+ fprintf(r0, "\nEND;\n");
+
+ /* odd ROM addresses */
+ seg = get_seg(SEG_DATA);
+
+ fprintf(r1, "DEPTH=%lu;\n", romsize/2);
+ fprintf(r1, "WIDTH=8;\n");
+ fprintf(r1, "ADDRESS_RADIX=HEX;\n");
+ fprintf(r1, "DATA_RADIX=BIN;\n\n");
+ fprintf(r1, "CONTENT\nBEGIN\n\n");
+
+ fprintf(r1, "%% Assembly output\t%%\n");
+
+ for (pos = 1; pos < seg->pos; pos += 2)
+ {
+ uint16_t data = get_code(seg, pos);
+ fprintf(r1, "%4x:\t%s;\t%% %s\t%%\n", (uint16_t)pos/2,
+ itob(data, 8), get_listing(seg, pos));
+ }
+
+ if (seg->pos < romsize)
+ {
+ fprintf(r1, "\n[%4x..%4x]:\t%s;\t%% Filler\t%%\n",
+ (uint16_t)seg->pos/2, (uint16_t)(romsize/2-1),
+ itob(filler, 8));
+ }
+
+ fprintf(r1, "\nEND;\n");
+}
Index: trunk/spar/checks.c
===================================================================
--- trunk/spar/checks.c (nonexistent)
+++ trunk/spar/checks.c (revision 2)
@@ -0,0 +1,229 @@
+/* This file is part of the assembler "spar" for marca.
+ Copyright (C) 2007 Wolfgang Puffitsch
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library 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 */
+
+#include
+#include
+
+#include "spar.h"
+#include "ui.h"
+#include "checks.h"
+#include "code.h"
+#include "exprs.h"
+#include "optab.h"
+#include "segtab.h"
+#include "symtab.h"
+
+int check_premature(void)
+{
+ if (args_to_match > 0)
+ {
+ fprintf(stderr, "not enough valid items in line %lu\n", line_count);
+ error_count++;
+ return 1;
+ }
+ return 0;
+}
+
+int check_arg_count(void)
+{
+ if (args_to_match == 0)
+ {
+ fprintf(stderr, "too many items in line %lu\n", line_count);
+ error_count++;
+ return 1;
+ }
+ else if (args_to_match == -1)
+ {
+ fprintf(stderr, "no valid mnemonic in line %lu\n", line_count);
+ args_to_match = -2;
+ error_count++;
+ return 1;
+ }
+ else if ((args_to_match & 1) == 0)
+ {
+ fprintf(stderr, "missing colon in line %lu\n", line_count);
+ error_count++;
+ return 1;
+ }
+
+ return 0;
+}
+
+int check_org_advances(struct seg *seg, uint32_t org)
+{
+ if (seg->pos > org)
+ {
+ fprintf(stderr, "trying to move .org backwards in line %lu\n", line_count);
+ error_count++;
+ return 1;
+ }
+ return 0;
+}
+
+int check_colon_ok(void)
+{
+ if ((args_to_match & 1) != 0)
+ {
+ fprintf(stderr, "superfluous colon in line %lu\n", line_count);
+ error_count++;
+ return 1;
+ }
+
+ return 0;
+}
+
+int check_arg_type(struct seg* seg, uint32_t pos, uint8_t index, char type)
+{
+ if (((type == 'r')
+ && (get_arg_type(seg, pos, index) != 'r'))
+ || ((type == 'n')
+ && (get_arg_type(seg, pos, index) != 'n')
+ && (get_arg_type(seg, pos, index) != 'a')))
+
+ {
+ fprintf(stderr, "wrong argtype `%c' in line %lu\n", type, line_count);
+ error_count++;
+ return 1;
+ }
+ return 0;
+}
+
+int check_sym_dup(const char *s)
+{
+ if (get_sym(s) != NULL)
+ {
+ fprintf(stderr, "duplicate symbol `%s' in line %lu\n", s, line_count);
+ error_count++;
+ return 1;
+ }
+ return 0;
+}
+
+int check_code_size(void)
+{
+ if (get_seg(SEG_TEXT)->pos > codesize)
+ {
+ fprintf(stderr,
+ "code (%lu instrucions) is too large for instruction ROM (%lu instructions)\n",
+ get_seg(SEG_TEXT)->pos, codesize);
+ error_count++;
+ return 1;
+ }
+ return 0;
+}
+
+int check_data_size(void)
+{
+ if (output_mode == MODE_DOWNLOAD
+ && get_seg(SEG_DATA)->pos > 0)
+ {
+ fprintf(stderr,
+ "initialized data (%lu words) not supported for download format\n",
+ get_seg(SEG_DATA)->pos, romsize);
+ error_count++;
+ return 1;
+ }
+
+ if (get_seg(SEG_DATA)->pos > romsize)
+ {
+ fprintf(stderr,
+ "initialized data (%lu words) is too large for data ROM (%lu words)\n",
+ get_seg(SEG_DATA)->pos, romsize);
+ error_count++;
+ return 1;
+ }
+
+ if ((get_seg(SEG_DATA)->pos+get_seg(SEG_BSS)->pos) > datasize)
+ {
+ fprintf(stderr,
+ "data (%lu words) is too large for RAM (%lu words)\n",
+ (get_seg(SEG_DATA)->pos+get_seg(SEG_BSS)->pos), datasize);
+ error_count++;
+ return 1;
+ }
+ return 0;
+}
+
+int check_mnemonic(struct seg* seg, uint32_t pos)
+{
+ if (0)
+ {
+ fprintf(stderr, "mnemonic reserved, but not supported\n");
+ error_count++;
+ return 1;
+ }
+ return 0;
+}
+
+int check_ranges(struct seg* seg, uint32_t pos)
+{
+ uint8_t count = get_arg_count(seg, pos);
+ uint8_t index;
+ int retval = 0;
+
+ for (index = 0; index < count; index++)
+ {
+ switch (get_arg_type(seg, pos, index))
+ {
+ case 'r':
+ if ((get_regnum(seg, pos, index) < get_arg_min(seg, pos, index))
+ || (get_regnum(seg, pos, index) > get_arg_max(seg, pos, index)))
+ {
+ fprintf(stderr, "invalid register: r%d\n", get_regnum(seg, pos, index));
+ error_count++;
+ retval = 1;
+ }
+ break;
+ case 'n':
+ if (get_expr(seg, pos, index) == NULL)
+ {
+ fprintf(stderr, "missing expression, probably confused by prior errors\n");
+ error_count++;
+ retval = 1;
+ }
+ else if ((expr_evaluate(get_expr(seg, pos, index)) < get_arg_min(seg, pos, index))
+ || (expr_evaluate(get_expr(seg, pos, index)) > get_arg_max(seg, pos, index)))
+ {
+ fprintf(stderr, "number out of range [%ld..%ld]: %lld\n",
+ get_arg_min(seg, pos, index), get_arg_max(seg, pos, index),
+ expr_evaluate(get_expr(seg, pos, index)));
+ error_count++;
+ retval = 1;
+ }
+ break;
+ case 'a':
+ if ((expr_evaluate(get_expr(seg, pos, index)) < get_arg_min(seg, pos, index))
+ || (expr_evaluate(get_expr(seg, pos, index)) > get_arg_max(seg, pos, index)))
+ {
+ fprintf(stderr, "relative address out of range [%ld..%ld]: %lld\n",
+ get_arg_min(seg, pos, index), get_arg_max(seg, pos, index),
+ expr_evaluate(get_expr(seg, pos, index)));
+ error_count++;
+ retval = 1;
+ }
+ break;
+ default:
+ fprintf(stderr, "invalid operand constraint: %c\n",
+ get_arg_type(seg, pos, index));
+ error_count++;
+ retval = 1;
+ }
+ }
+
+ return retval;
+}
+
Index: trunk/spar/emit.h
===================================================================
--- trunk/spar/emit.h (nonexistent)
+++ trunk/spar/emit.h (revision 2)
@@ -0,0 +1,43 @@
+/* This file is part of the assembler "spar" for marca.
+ Copyright (C) 2007 Wolfgang Puffitsch
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library 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 */
+
+#ifndef _EMIT_H_
+#define _EMIT_H_
+
+#include
+
+#include "segtab.h"
+
+void emit_op(struct seg*, struct op);
+
+void emit_nop(struct seg *);
+void emit_zero(struct seg *);
+
+void emit_data(struct seg *, char *);
+
+void emit_ldil(struct seg *, uint16_t, char *);
+void emit_ldih(struct seg *, uint16_t, char *);
+void emit_ldib(struct seg *, uint16_t, char *);
+void emit_load(struct seg *, uint16_t, uint16_t);
+void emit_store(struct seg *, uint16_t, uint16_t);
+void emit_cmp(struct seg *, uint16_t, uint16_t);
+void emit_addi(struct seg *, uint16_t, char*);
+void emit_jmp(struct seg *, uint16_t);
+void emit_brnz(struct seg *, char*);
+
+
+#endif /* _EMIT_H_ */
Index: trunk/spar/symtab.h
===================================================================
--- trunk/spar/symtab.h (nonexistent)
+++ trunk/spar/symtab.h (revision 2)
@@ -0,0 +1,43 @@
+/* This file is part of the assembler "spar" for marca.
+ Copyright (C) 2007 Wolfgang Puffitsch
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library 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 */
+
+#ifndef _SYMTAB_H_
+#define _SYMTAB_H_
+
+#include
+
+#define SYMTAB_SIZE 4096
+
+uint32_t hash_string (const char *);
+char *trim_string (char *);
+char *localize_string (char *);
+
+struct sym_info
+{
+ const char *symbol;
+ uint8_t type;
+ uint32_t addr;
+ struct sym_info *next;
+};
+
+void init_symtab(void);
+
+void push_sym(const char *, uint8_t, uint32_t);
+struct sym_info *get_sym(const char *);
+void reloc_syms(uint8_t type, uint32_t offset);
+
+#endif /* _SYMTAB_H_ */
Index: trunk/spar/segtab.c
===================================================================
--- trunk/spar/segtab.c (nonexistent)
+++ trunk/spar/segtab.c (revision 2)
@@ -0,0 +1,74 @@
+/* This file is part of the assembler "spar" for marca.
+ Copyright (C) 2007 Wolfgang Puffitsch
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library 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 */
+
+#include
+
+#include
+#include
+
+#include "spar.h"
+#include "segtab.h"
+
+static struct seg segtab[4];
+static uint8_t current_segnum;
+
+void init_seg(uint8_t segnum, uint32_t size)
+{
+ int i;
+
+ segtab[segnum].max = size;
+ segtab[segnum].code = xmalloc(segtab[segnum].max*sizeof(struct op));
+
+ for (i = 0; i < segtab[segnum].max; i++)
+ set_listing(&segtab[segnum], i, "");
+}
+
+void set_current_segnum(uint8_t segnum)
+{
+ current_segnum = segnum;
+}
+
+uint8_t get_current_segnum(void)
+{
+ return current_segnum;
+}
+
+struct seg *get_current_seg(void)
+{
+ return &segtab[current_segnum];
+}
+
+struct seg *get_seg(uint8_t segnum)
+{
+ return &segtab[segnum];
+}
+
+void adjust_segsize(struct seg *seg, uint32_t size)
+{
+ if (size >= seg->max-1)
+ {
+ uint32_t i;
+
+ seg->code = xrealloc(seg->code, 2*seg->max*sizeof(struct op));
+ for (i = seg->max; i < 2*seg->max; i++)
+ {
+ set_listing(seg, i, "");
+ }
+ seg->max *= 2;
+ }
+}
+
Index: trunk/spar/output.h
===================================================================
--- trunk/spar/output.h (nonexistent)
+++ trunk/spar/output.h (revision 2)
@@ -0,0 +1,29 @@
+/* This file is part of the assembler "spar" for marca.
+ Copyright (C) 2007 Wolfgang Puffitsch
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library 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 */
+
+#ifndef _OUTPUT_H_
+#define _OUTPUT_H_
+
+#include
+#include
+
+char *itob(uint32_t, uint8_t);
+void print_download(FILE *, FILE *, FILE *);
+void print_intel(FILE *, FILE *, FILE *);
+void print_mif(FILE *, FILE *, FILE *);
+
+#endif /* _OUTPUT_H_ */
Index: trunk/spar/checks.h
===================================================================
--- trunk/spar/checks.h (nonexistent)
+++ trunk/spar/checks.h (revision 2)
@@ -0,0 +1,36 @@
+/* This file is part of the assembler "spar" for marca.
+ Copyright (C) 2007 Wolfgang Puffitsch
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library 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 */
+
+#ifndef _CHECKS_H_
+#define _CHECKS_H_
+
+#include
+
+#include "segtab.h"
+
+int check_premature(void);
+int check_arg_count(void);
+int check_arg_type(struct seg *, uint32_t, uint8_t, char);
+int check_org_advances(struct seg *, uint32_t);
+int check_colon_ok(void);
+int check_sym_dup(const char *s);
+int check_code_size(void);
+int check_data_size(void);
+int check_mnemonic(struct seg *, uint32_t);
+int check_ranges(struct seg *, uint32_t);
+
+#endif /* _CHECKS_H_ */
Index: trunk/spar/optab.c
===================================================================
--- trunk/spar/optab.c (nonexistent)
+++ trunk/spar/optab.c (revision 2)
@@ -0,0 +1,221 @@
+/* This file is part of the assembler "spar" for marca.
+ Copyright (C) 2007 Wolfgang Puffitsch
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library 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 */
+
+#include
+
+#include "optab.h"
+#include "segtab.h"
+
+const struct op_info optab [] = {
+
+/* #define DATA 0 */
+ { 0x0000, 1, { { 'n', 8, 0, -0x80, 0xFF } } },
+
+/* #define ADD 1 */
+ { 0x0000, 3, { { 'r', 4, 0, 0, 15 }, { 'r', 4, 4, 0, 15 }, { 'r', 4, 8, 0, 15 } } },
+/* #define SUB 2 */
+ { 0x1000, 3, { { 'r', 4, 0, 0, 15 }, { 'r', 4, 4, 0, 15 }, { 'r', 4, 8, 0, 15 } } },
+/* #define ADDC 3 */
+ { 0x2000, 3, { { 'r', 4, 0, 0, 15 }, { 'r', 4, 4, 0, 15 }, { 'r', 4, 8, 0, 15 } } },
+/* #define SUBC 4 */
+ { 0x3000, 3, { { 'r', 4, 0, 0, 15 }, { 'r', 4, 4, 0, 15 }, { 'r', 4, 8, 0, 15 } } },
+/* #define AND 5 */
+ { 0x4000, 3, { { 'r', 4, 0, 0, 15 }, { 'r', 4, 4, 0, 15 }, { 'r', 4, 8, 0, 15 } } },
+/* #define OR 6 */
+ { 0x5000, 3, { { 'r', 4, 0, 0, 15 }, { 'r', 4, 4, 0, 15 }, { 'r', 4, 8, 0, 15 } } },
+/* #define XOR 7 */
+ { 0x6000, 3, { { 'r', 4, 0, 0, 15 }, { 'r', 4, 4, 0, 15 }, { 'r', 4, 8, 0, 15 } } },
+/* #define MUL 8 */
+ { 0x7000, 3, { { 'r', 4, 0, 0, 15 }, { 'r', 4, 4, 0, 15 }, { 'r', 4, 8, 0, 15 } } },
+/* #define DIV 9 */
+ { 0x8000, 3, { { 'r', 4, 0, 0, 15 }, { 'r', 4, 4, 0, 15 }, { 'r', 4, 8, 0, 15 } } },
+/* #define UDIV 10 */
+ { 0x9000, 3, { { 'r', 4, 0, 0, 15 }, { 'r', 4, 4, 0, 15 }, { 'r', 4, 8, 0, 15 } } },
+/* #define LDIL 11 */
+ { 0xA000, 2, { { 'r', 4, 0, 0, 15 }, { 'n', 8, 4, -128, 255 } } },
+/* #define LDIH 12 */
+ { 0xB000, 2, { { 'r', 4, 0, 0, 15 }, { 'n', 8, 4, -128, 255 } } },
+/* #define LDIB 13 */
+ { 0xC000, 2, { { 'r', 4, 0, 0, 15 }, { 'n', 8, 4, -128, 128 } } },
+
+/* #define MOV 14 */
+ { 0xD000, 2, { { 'r', 4, 0, 0, 15 }, { 'r', 4, 4, 0, 15 } } },
+
+ /* mod an umod are a bit of a kludge and need separate unfolding,
+ they are 2-operand instructions really */
+/* #define MOD 15 */
+ { 0xD100, 3, { { 'r', 4, 0, 0, 15 }, { 'r', 4, 4, 0, 15 }, { 'r', 4, 16, 0, 15 } } },
+/* #define UMOD 16 */
+ { 0xD200, 3, { { 'r', 4, 0, 0, 15 }, { 'r', 4, 4, 0, 15 }, { 'r', 4, 16, 0, 15 } } },
+
+/* #define NOT 17 */
+ { 0xD300, 2, { { 'r', 4, 0, 0, 15 }, { 'r', 4, 4, 0, 15 } } },
+/* #define NEG 18 */
+ { 0xD400, 2, { { 'r', 4, 0, 0, 15 }, { 'r', 4, 4, 0, 15 } } },
+/* #define CMP 19 */
+ { 0xD500, 2, { { 'r', 4, 0, 0, 15 }, { 'r', 4, 4, 0, 15 } } },
+/* #define ADDI 20 */
+ { 0xD600, 2, { { 'r', 4, 0, 0, 15 }, { 'n', 4, 4, -8, 7 } } },
+/* #define CMPI 21 */
+ { 0xD700, 2, { { 'r', 4, 0, 0, 15 }, { 'n', 4, 4, -8, 7 } } },
+/* #define SHL 22 */
+ { 0xD800, 2, { { 'r', 4, 0, 0, 15 }, { 'r', 4, 4, 0, 15 } } },
+/* #define SHR 23 */
+ { 0xD900, 2, { { 'r', 4, 0, 0, 15 }, { 'r', 4, 4, 0, 15 } } },
+/* #define SAR 24 */
+ { 0xDA00, 2, { { 'r', 4, 0, 0, 15 }, { 'r', 4, 4, 0, 15 } } },
+/* #define ROLC 25 */
+ { 0xDB00, 2, { { 'r', 4, 0, 0, 15 }, { 'r', 4, 4, 0, 15 } } },
+/* #define RORC 26 */
+ { 0xDC00, 2, { { 'r', 4, 0, 0, 15 }, { 'r', 4, 4, 0, 15 } } },
+/* #define BSET 27 */
+ { 0xDD00, 2, { { 'r', 4, 0, 0, 15 }, { 'n', 4, 4, 0, 15 } } },
+/* #define BCLR 28 */
+ { 0xDE00, 2, { { 'r', 4, 0, 0, 15 }, { 'n', 4, 4, 0, 15 } } },
+/* #define BTEST 29 */
+ { 0xDF00, 2, { { 'r', 4, 0, 0, 15 }, { 'n', 4, 4, 0, 15 } } },
+
+/* #define LOAD 30 */
+ { 0xE000, 2, { { 'r', 4, 0, 0, 15 }, { 'r', 4, 4, 0, 15 } } },
+/* #define STORE 31 */
+ { 0xE100, 2, { { 'r', 4, 0, 0, 15 }, { 'r', 4, 4, 0, 15 } } },
+/* #define LOADL 32 */
+ { 0xE200, 2, { { 'r', 4, 0, 0, 15 }, { 'r', 4, 4, 0, 15 } } },
+/* #define LOADH 33 */
+ { 0xE300, 2, { { 'r', 4, 0, 0, 15 }, { 'r', 4, 4, 0, 15 } } },
+/* #define LOADB 34 */
+ { 0xE400, 2, { { 'r', 4, 0, 0, 15 }, { 'r', 4, 4, 0, 15 } } },
+/* #define STOREL 35 */
+ { 0xE500, 2, { { 'r', 4, 0, 0, 15 }, { 'r', 4, 4, 0, 15 } } },
+/* #define STOREH 36 */
+ { 0xE600, 2, { { 'r', 4, 0, 0, 15 }, { 'r', 4, 4, 0, 15 } } },
+/* #define CALL 37 */
+ { 0xE800, 2, { { 'r', 4, 4, 0, 15 }, { 'r', 4, 0, 0, 15 } } },
+
+/* #define BR 38 */
+ { 0xF000, 1, { { 'a', 8, 0, -128, 127 } } },
+/* #define BRZ 39 */
+ { 0xF100, 1, { { 'a', 8, 0, -128, 127 } } },
+/* #define BRNZ 40 */
+ { 0xF200, 1, { { 'a', 8, 0, -128, 127 } } },
+/* #define BRLE 41 */
+ { 0xF300, 1, { { 'a', 8, 0, -128, 127 } } },
+/* #define BRLT 42 */
+ { 0xF400, 1, { { 'a', 8, 0, -128, 127 } } },
+/* #define BRGE 43 */
+ { 0xF500, 1, { { 'a', 8, 0, -128, 127 } } },
+/* #define BRGT 44 */
+ { 0xF600, 1, { { 'a', 8, 0, -128, 127 } } },
+/* #define BRULE 45 */
+ { 0xF700, 1, { { 'a', 8, 0, -128, 127 } } },
+/* #define BRULT 46 */
+ { 0xF800, 1, { { 'a', 8, 0, -128, 127 } } },
+/* #define BRUGE 47 */
+ { 0xF900, 1, { { 'a', 8, 0, -128, 127 } } },
+/* #define BRUGT 48 */
+ { 0xFA00, 1, { { 'a', 8, 0, -128, 127 } } },
+/* #define SEXT 49 */
+ { 0xFB00, 2, { { 'r', 4, 4, 0, 15 }, { 'r', 4, 0, 0, 15 } } },
+/* #define LDVEC 50 */
+ { 0xFC00, 2, { { 'r', 4, 0, 0, 15 }, { 'n', 4, 4, 0, 15 } } },
+/* #define STVEC 51 */
+ { 0xFD00, 2, { { 'r', 4, 0, 0, 15 }, { 'n', 4, 4, 0, 15 } } },
+
+/* #define JMP 52 */
+ { 0xFE00, 1, { { 'r', 4, 0, 0, 15 } } },
+/* #define JMPZ 53 */
+ { 0xFE10, 1, { { 'r', 4, 0, 0, 15 } } },
+/* #define JMPNZ 54 */
+ { 0xFE20, 1, { { 'r', 4, 0, 0, 15 } } },
+/* #define JMPLE 55 */
+ { 0xFE30, 1, { { 'r', 4, 0, 0, 15 } } },
+/* #define JMPLT 56 */
+ { 0xFE40, 1, { { 'r', 4, 0, 0, 15 } } },
+/* #define JMPGE 57 */
+ { 0xFE50, 1, { { 'r', 4, 0, 0, 15 } } },
+/* #define JMPGT 58 */
+ { 0xFE60, 1, { { 'r', 4, 0, 0, 15 } } },
+/* #define JMPULE 59 */
+ { 0xFE70, 1, { { 'r', 4, 0, 0, 15 } } },
+/* #define JMPULT 60 */
+ { 0xFE80, 1, { { 'r', 4, 0, 0, 15 } } },
+/* #define JMPUGE 61 */
+ { 0xFE90, 1, { { 'r', 4, 0, 0, 15 } } },
+/* #define JMPUGT 62 */
+ { 0xFEA0, 1, { { 'r', 4, 0, 0, 15 } } },
+
+/* #define INTR 63 */
+ { 0xFEB0, 1, { { 'n', 4, 0, 0, 15 } } },
+/* #define GETIRA 64 */
+ { 0xFEC0, 1, { { 'r', 4, 0, 0, 15 } } },
+/* #define SETIRA 65 */
+ { 0xFED0, 1, { { 'r', 4, 0, 0, 15 } } },
+/* #define GETFL 66 */
+ { 0xFEE0, 1, { { 'r', 4, 0, 0, 15 } } },
+/* #define SETFL 67 */
+ { 0xFEF0, 1, { { 'r', 4, 0, 0, 15 } } },
+/* #define GETSHFL 68 */
+ { 0xFF00, 1, { { 'r', 4, 0, 0, 15 } } },
+/* #define SETSHFL 69 */
+ { 0xFF10, 1, { { 'r', 4, 0, 0, 15 } } },
+
+/* #define RETI 70 */
+ { 0xFFF0, 0 },
+/* #define NOP 71 */
+ { 0xFFF1, 0 },
+/* #define SEI 72 */
+ { 0xFFF2, 0 },
+/* #define CLI 73 */
+ { 0xFFF3, 0 },
+/* #define ERROR 74 */
+ { 0xFFFF, 0 },
+
+/* #define ALIGN 75 */
+ { 0x0000 }
+};
+
+uint16_t get_op_code(struct seg *seg, uint32_t pos)
+{
+ return optab[seg->code[pos].op].opcode;
+}
+
+int8_t get_arg_count(struct seg *seg, uint32_t pos)
+{
+ return optab[seg->code[pos].op].argc;
+}
+
+char get_arg_type(struct seg *seg, uint32_t pos, uint8_t index)
+{
+ return optab[seg->code[pos].op].argv[index].type;
+}
+
+uint8_t get_arg_width(struct seg *seg, uint32_t pos, uint8_t index)
+{
+ return optab[seg->code[pos].op].argv[index].width;
+}
+uint8_t get_arg_offset(struct seg *seg, uint32_t pos, uint8_t index)
+{
+ return optab[seg->code[pos].op].argv[index].offset;
+}
+int32_t get_arg_min(struct seg *seg, uint32_t pos, uint8_t index)
+{
+ return optab[seg->code[pos].op].argv[index].min;
+}
+int32_t get_arg_max(struct seg *seg, uint32_t pos, uint8_t index)
+{
+ return optab[seg->code[pos].op].argv[index].max;
+}
Index: trunk/spar/exprs.h
===================================================================
--- trunk/spar/exprs.h (nonexistent)
+++ trunk/spar/exprs.h (revision 2)
@@ -0,0 +1,28 @@
+/* This file is part of the assembler "spar" for marca.
+ Copyright (C) 2007 Wolfgang Puffitsch
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library 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 */
+
+#ifndef _EXPRS_H_
+#define _EXPRS_H_
+
+#include
+
+char * expr_localize(const char *);
+int64_t expr_symcount(const char *) __attribute__((const));
+int64_t expr_nevaluate(const char *) __attribute__((const));
+int64_t expr_evaluate(const char *) __attribute__((const));
+
+#endif
Index: trunk/spar/segtab.h
===================================================================
--- trunk/spar/segtab.h (nonexistent)
+++ trunk/spar/segtab.h (revision 2)
@@ -0,0 +1,49 @@
+/* This file is part of the assembler "spar" for marca.
+ Copyright (C) 2007 Wolfgang Puffitsch
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library 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 */
+
+#ifndef _SEGTAB_H_
+#define _SEGTAB_H_
+
+#include
+
+#define SEG_INITSIZE 1024
+
+struct seg
+{
+ struct op *code;
+ uint32_t max;
+ uint32_t pos;
+};
+
+#include "code.h"
+
+#define SEG_TEXT 0
+#define SEG_DATA 1
+#define SEG_BSS 2
+#define SEG_PILE 3
+
+void init_seg(uint8_t, uint32_t);
+
+void set_current_segnum(uint8_t);
+uint8_t get_current_segnum(void);
+
+struct seg *get_current_seg(void);
+struct seg *get_seg(uint8_t);
+
+void adjust_segsize(struct seg *, uint32_t);
+
+#endif /* _SEGTAB_H_ */
Index: trunk/spar/code.c
===================================================================
--- trunk/spar/code.c (nonexistent)
+++ trunk/spar/code.c (revision 2)
@@ -0,0 +1,101 @@
+/* This file is part of the assembler "spar" for marca.
+ Copyright (C) 2007 Wolfgang Puffitsch
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library 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 */
+
+#include
+#include
+#include
+#include
+
+#include "code.h"
+#include "segtab.h"
+
+void set_op(struct seg *seg, uint32_t pos, uint16_t op)
+{
+ seg->code[pos].op = op;
+}
+
+uint16_t get_op(struct seg *seg, uint32_t pos)
+{
+ return seg->code[pos].op;
+}
+
+void set_mode(struct seg *seg, uint32_t pos, uint8_t index, char mode)
+{
+ seg->code[pos].args[index].mode = mode;
+}
+
+char get_mode(struct seg *seg, uint32_t pos, uint8_t index)
+{
+ return seg->code[pos].args[index].mode;
+}
+
+void set_regnum(struct seg *seg, uint32_t pos, uint8_t index, uint16_t regnum)
+{
+ seg->code[pos].args[index].val.regnum = regnum;
+}
+
+uint16_t get_regnum(struct seg *seg, uint32_t pos, uint8_t index)
+{
+ return seg->code[pos].args[index].val.regnum;
+}
+
+void set_expr(struct seg *seg, uint32_t pos, uint8_t index, char * expr)
+{
+ seg->code[pos].args[index].val.expr = expr;
+}
+
+char *get_expr(struct seg *seg, uint32_t pos, uint8_t index)
+{
+ return seg->code[pos].args[index].val.expr;
+}
+
+void set_code(struct seg *seg, uint32_t pos, uint16_t code)
+{
+ seg->code[pos].code = code;
+}
+
+uint16_t get_code(struct seg *seg, uint32_t pos)
+{
+ return seg->code[pos].code;
+}
+
+void set_listing(struct seg *seg, uint32_t pos, const char *listing)
+{
+ if (listing != NULL)
+ {
+ strncpy(seg->code[pos].listing, listing, CODE_MAX_LISTLEN);
+ seg->code[pos].listing[CODE_MAX_LISTLEN-1] = '\0';
+ }
+ else
+ {
+ seg->code[pos].listing[0] = '\0';
+ }
+}
+
+void trace_listing(struct seg *seg, uint32_t pos, const char *text)
+{
+ if (text != NULL)
+ {
+ strncat(seg->code[pos].listing, text, CODE_MAX_LISTLEN);
+ seg->code[pos].listing[CODE_MAX_LISTLEN-1] = '\0';
+ }
+}
+
+const char *get_listing(struct seg *seg, uint32_t pos)
+{
+ return seg->code[pos].listing;
+}
Index: trunk/spar/exprs.l
===================================================================
--- trunk/spar/exprs.l (nonexistent)
+++ trunk/spar/exprs.l (revision 2)
@@ -0,0 +1,227 @@
+/* This file is part of the assembler "spar" for marca.
+ Copyright (C) 2007 Wolfgang Puffitsch
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library 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 */
+
+%option nounput
+
+%{
+
+#include
+#include
+
+#include "exprs.h"
+#include "exprs.tab.h"
+#include "spar.h"
+#include "symtab.h"
+
+int exprsparse(int64_t *, int64_t *);
+
+static int allow_syms = 1;
+static int resolve_syms = 1;
+static int localize_syms = 0;
+static char *localized_expr = NULL;
+
+#define YY_USER_ACTION \
+do { \
+ if (localize_syms) { \
+ localized_expr = xrealloc(localized_expr, \
+ strlen(localized_expr) \
+ + yyleng + 1); \
+ strcat(localized_expr, yytext); \
+ } \
+} while(0);
+
+%}
+
+BNUM (0b[0-1]+)
+ONUM (0[0-7]*)
+DNUM ([1-9][0-9]*)
+XNUM (0x[0-9a-fA-F]+)
+SYM (\.?[_\.a-zA-Z0-9@]+)
+
+%%
+
+"hi" return HI;
+"lo" return LO;
+
+"(" return '(';
+")" return ')';
+
+"+" return '+';
+"-" return '-';
+"~" return '~';
+"!" return '!';
+"*" return '*';
+"/" return '/';
+"|/|" return CUDIV;
+"%" return '%';
+"|%|" return CUMOD;
+">>" return CSHR;
+"<<" return CSHL;
+">>>" return CSLR;
+"<" return '<';
+">" return '>';
+"<=" return CLE;
+">=" return CGE;
+"|<|" return CULT;
+"|>|" return CUGT;
+"|<=|" return CULE;
+"|>=|" return CUGE;
+"==" return CEQU;
+"!=" return CNEQ;
+"&" return '&';
+"^" return '^';
+"|" return '|';
+"&&" return CLAND;
+"||" return CLOR;
+"?" return '?';
+":" return ':';
+"" return CMIN;
+">?" return CMAX;
+"||" return CUMIN;
+"|>?|" return CUMAX;
+
+{BNUM} {
+ exprslval.intval = strtol(yytext+2, NULL, 2);
+ return NUM;
+ }
+
+{ONUM} {
+ exprslval.intval = strtol(yytext, NULL, 8);
+ return NUM;
+ }
+
+{DNUM} {
+ exprslval.intval = strtol(yytext, NULL, 10);
+ return NUM;
+ }
+
+{XNUM} {
+ exprslval.intval = strtol(yytext+2, NULL, 16);
+ return NUM;
+ }
+
+{SYM} {
+ char *s = yytext;
+
+ if (localize_syms)
+ {
+ s = localize_string(yytext);
+ localized_expr = xrealloc(localized_expr,
+ strlen(localized_expr)
+ + strlen(s)
+ - yyleng + 1);
+ strcpy(localized_expr
+ + strlen(localized_expr)
+ - yyleng, s);
+ }
+ else if (!allow_syms)
+ {
+ exprslval.intval = 0;
+ fprintf(stderr, "no symbol allowed here: `%s'\n", s);
+ error_count++;
+ }
+ else if (!resolve_syms)
+ {
+ exprslval.intval = 0;
+ }
+ else if (get_sym(s) == NULL)
+ {
+ exprslval.intval = 0;
+ fprintf(stderr, "symbol in expression not found: `%s'\n", s);
+ error_count++;
+ }
+ else
+ {
+ exprslval.intval = get_sym(s)->addr;
+ }
+
+ return IDENT;
+ }
+
+[ \t\r\n]+ { /* ignore whitespace */ }
+
+%%
+
+int yywrap()
+{
+ return 1;
+}
+
+char *expr_localize(const char *expr)
+{
+ int64_t value = 0;
+ int64_t symcount = 0;
+
+ allow_syms = 1;
+ resolve_syms = 0;
+ localize_syms = 1;
+ localized_expr = xmalloc(1);
+ localized_expr[0] = '\0';
+
+ exprs_scan_string(expr);
+ exprsparse(&value, &symcount);
+
+ return localized_expr;
+}
+
+int64_t expr_symcount(const char *expr)
+{
+ int64_t value = 0;
+ int64_t symcount = 0;
+
+ allow_syms = 1;
+ resolve_syms = 0;
+ localize_syms = 0;
+ localized_expr = NULL;
+
+ exprs_scan_string(expr);
+ exprsparse(&value, &symcount);
+
+ return symcount;
+}
+
+int64_t expr_nevaluate(const char *expr)
+{
+ int64_t value = 0;
+ int64_t symcount = 0;
+
+ allow_syms = 0;
+ resolve_syms = 0;
+ localize_syms = 0;
+ localized_expr = NULL;
+
+ exprs_scan_string(expr);
+ exprsparse(&value, &symcount);
+
+ return value;
+}
+
+int64_t expr_evaluate(const char *expr)
+{
+ int64_t value = 0;
+ int64_t symcount = 0;
+
+ allow_syms = 1;
+ resolve_syms = 1;
+ localize_syms = 0;
+ localized_expr = NULL;
+
+ exprs_scan_string(expr);
+ exprsparse(&value, &symcount);
+
+ return value;
+}
Index: trunk/spar/optab.h
===================================================================
--- trunk/spar/optab.h (nonexistent)
+++ trunk/spar/optab.h (revision 2)
@@ -0,0 +1,140 @@
+/* This file is part of the assembler "spar" for marca.
+ Copyright (C) 2007 Wolfgang Puffitsch
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library 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 */
+
+#ifndef _OPTAB_H_
+#define _OPTAB_H_
+
+#include
+
+#include "code.h"
+#include "segtab.h"
+
+struct arg_info
+{
+ char type;
+ uint8_t width;
+ uint8_t offset;
+ int32_t min;
+ int32_t max;
+};
+
+struct op_info
+{
+ uint16_t opcode;
+ int8_t argc;
+ struct arg_info argv [CODE_MAX_ARGS];
+};
+
+uint16_t get_op_code(struct seg *, uint32_t);
+int8_t get_arg_count(struct seg *, uint32_t);
+char get_arg_type(struct seg *, uint32_t, uint8_t);
+uint8_t get_arg_width(struct seg *, uint32_t, uint8_t);
+uint8_t get_arg_offset(struct seg *, uint32_t, uint8_t);
+int32_t get_arg_min(struct seg *, uint32_t, uint8_t);
+int32_t get_arg_max(struct seg *, uint32_t, uint8_t);
+
+extern const struct op_info optab [];
+
+#define DATA 0
+#define ADD 1
+#define SUB 2
+#define ADDC 3
+#define SUBC 4
+#define AND 5
+#define OR 6
+#define XOR 7
+#define MUL 8
+#define DIV 9
+#define UDIV 10
+#define LDIL 11
+#define LDIH 12
+#define LDIB 13
+
+#define MOV 14
+#define MOD 15
+#define UMOD 16
+#define NOT 17
+#define NEG 18
+#define CMP 19
+#define ADDI 20
+#define CMPI 21
+#define SHL 22
+#define SHR 23
+#define SAR 24
+#define ROLC 25
+#define RORC 26
+#define BSET 27
+#define BCLR 28
+#define BTEST 29
+
+#define LOAD 30
+#define STORE 31
+#define LOADL 32
+#define LOADH 33
+#define LOADB 34
+#define STOREL 35
+#define STOREH 36
+#define CALL 37
+
+#define BR 38
+#define BRZ 39
+#define BRNZ 40
+#define BRLE 41
+#define BRLT 42
+#define BRGE 43
+#define BRGT 44
+#define BRULE 45
+#define BRULT 46
+#define BRUGE 47
+#define BRUGT 48
+#define SEXT 49
+#define LDVEC 50
+#define STVEC 51
+
+#define JMP 52
+#define JMPZ 53
+#define JMPNZ 54
+#define JMPLE 55
+#define JMPLT 56
+#define JMPGE 57
+#define JMPGT 58
+#define JMPULE 59
+#define JMPULT 60
+#define JMPUGE 61
+#define JMPUGT 62
+
+#define INTR 63
+#define GETIRA 64
+#define SETIRA 65
+#define GETFL 66
+#define SETFL 67
+#define GETSHFL 68
+#define SETSHFL 69
+
+#define RETI 70
+#define NOP 71
+#define SEI 72
+#define CLI 73
+#define ERROR 74
+
+#define ALIGN 75
+#define COMM 76
+#define LCOMM 77
+#define ORG 78
+#define SKIP 79
+
+#endif /* _OPTAB_H_ */
Index: trunk/spar/spar.h
===================================================================
--- trunk/spar/spar.h (nonexistent)
+++ trunk/spar/spar.h (revision 2)
@@ -0,0 +1,38 @@
+/* This file is part of the assembler "spar" for marca.
+ Copyright (C) 2007 Wolfgang Puffitsch
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library 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 */
+
+#ifndef _SPAR_H_
+#define _SPAR_H_
+
+#include
+#include
+
+extern char *command;
+
+extern uint32_t line_count;
+extern uint32_t file_count;
+extern uint32_t error_count;
+
+extern int seen_op;
+extern int8_t args_to_match;
+
+void *xmalloc(size_t) __attribute__((malloc));
+void *xrealloc(void *, size_t) __attribute__((malloc));
+char *xstrdup(const char *) __attribute__((malloc));
+char *xsprintf(const char *, ...) __attribute__((malloc));
+
+#endif /* _SPAR_H_ */
Index: trunk/spar/ui.c
===================================================================
--- trunk/spar/ui.c (nonexistent)
+++ trunk/spar/ui.c (revision 2)
@@ -0,0 +1,40 @@
+/* This file is part of the assembler "spar" for marca.
+ Copyright (C) 2007 Wolfgang Puffitsch
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library 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 */
+
+#include
+
+#include "ui.h"
+
+const char * const options = "hvo:0:1:c:d:r:f:inlmse";
+
+const struct option long_options [] = {
+ { "help", no_argument, 0, 'h' },
+ { "version", no_argument, 0, 'v' },
+ { "output", required_argument, 0, 'o' },
+ { "rom0file", required_argument, 0, '0' },
+ { "rom1file", required_argument, 0, '1' },
+ { "codesize", required_argument, 0, 'c' },
+ { "datasize", required_argument, 0, 'd' },
+ { "romsize", required_argument, 0, 'r' },
+ { "filler", required_argument, 0, 'f' },
+ { "intel", no_argument, 0, 'i' },
+ { "dryrun", no_argument, 0, 'n' },
+ { "download", no_argument, 0, 'l' },
+ { "nointel", no_argument, 0, 'm' },
+ { "nostart", no_argument, 0, 's' },
+ { "noend", no_argument, 0, 'e' }
+};
Index: trunk/spar/fixes.c
===================================================================
--- trunk/spar/fixes.c (nonexistent)
+++ trunk/spar/fixes.c (revision 2)
@@ -0,0 +1,76 @@
+/* This file is part of the assembler "spar" for marca.
+ Copyright (C) 2007 Wolfgang Puffitsch
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library 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 */
+
+#include
+
+#include
+
+#include "spar.h"
+#include "ui.h"
+#include "code.h"
+#include "exprs.h"
+#include "fixes.h"
+#include "optab.h"
+#include "segtab.h"
+#include "symtab.h"
+
+int fix_operands(struct seg *seg, uint32_t pos)
+{
+ uint8_t count = get_arg_count(seg, pos);
+ uint8_t index;
+ int retval = 0;
+
+ for (index = 0; index < count; index++)
+ {
+ if (get_arg_type(seg, pos, index) == 'a')
+ {
+ set_expr(seg, pos, index,
+ xsprintf("(%s)-%d", get_expr(seg, pos, index), pos));
+ }
+ }
+
+ return retval;
+}
+
+int fix_code(struct seg *seg, uint32_t pos)
+{
+ uint8_t count = get_arg_count(seg, pos);
+ uint8_t index;
+ uint16_t data;
+
+ data = get_op_code(seg, pos);
+ for (index = 0; index < count; index++)
+ {
+ switch (get_arg_type(seg, pos, index))
+ {
+ case 'r':
+ data |= (get_regnum(seg, pos, index)
+ & ((uint16_t)0xFFFF >> (16-get_arg_width(seg, pos, index))))
+ << get_arg_offset(seg, pos, index);
+ break;
+ case 'n':
+ case 'a':
+ data |= (expr_evaluate(get_expr(seg, pos, index))
+ & ((uint16_t)0xFFFF >> (16-get_arg_width(seg, pos, index))))
+ << get_arg_offset(seg, pos, index);
+ break;
+ }
+ }
+ set_code(seg, pos, data);
+
+ return 0;
+}
Index: trunk/spar/spar.l
===================================================================
--- trunk/spar/spar.l (nonexistent)
+++ trunk/spar/spar.l (revision 2)
@@ -0,0 +1,844 @@
+/* This file is part of the assembler "spar" for marca.
+ Copyright (C) 2007 Wolfgang Puffitsch
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library 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 */
+
+%option nounput
+
+%{
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "spar.h"
+#include "ui.h"
+#include "checks.h"
+#include "code.h"
+#include "emit.h"
+#include "expand.h"
+#include "exprs.h"
+#include "fixes.h"
+#include "optab.h"
+#include "output.h"
+#include "segtab.h"
+#include "symtab.h"
+
+char *command = NULL;
+
+int8_t output_mode = DEFAULT_MODE;
+FILE *output_file = NULL;
+FILE *rom0_file = NULL;
+FILE *rom1_file = NULL;
+
+uint32_t codesize = DEFAULT_CODESIZE;
+uint32_t datasize = DEFAULT_DATASIZE;
+uint32_t romsize = DEFAULT_ROMSIZE;
+uint16_t filler = DEFAULT_FILLER;
+
+int nostart = 0;
+int noend = 0;
+
+uint32_t line_count = 1;
+uint32_t file_count = 0;
+uint32_t error_count = 0;
+
+int seen_op = 0;
+int8_t args_to_match = -1;
+
+/***************** WHAT TO DO ****************/
+int initialize(void);
+int merge(void);
+int postprocess(void);
+
+/* this does not really fit anywhere */
+void expand_mod(void);
+
+/***************** SHORTCUT ****************/
+#define MATCH_OP(X) \
+do { \
+ struct seg *seg = get_current_seg(); \
+ adjust_segsize(seg, seg->pos+1); \
+ set_op(seg, seg->pos, (X)); \
+ trace_listing(seg, seg->pos, yytext); \
+ trace_listing(seg, seg->pos, "\t"); \
+ seen_op = 1; \
+ args_to_match = get_arg_count(seg, seg->pos)*2 - 1; \
+} while(0)
+
+%}
+
+REG (r[0-9]+)
+NUM ((-?0[0-7]*)|(-?[1-9][0-9]*)|(-?0x[0-9a-fA-F]+))
+BNUM (0b[0-1]+)
+SYM (\.?[_\.a-zA-Z0-9]+)
+EXPR (([^ \t\r\n,;])|([^ \t\r\n,;][^,;\n]*[^ \t\r\n,;]))
+
+%%
+
+\.file[ \t]*\r?\n file_count++;
+
+\.text[ \t]*\r?\n set_current_segnum(SEG_TEXT);
+\.data[ \t]*\r?\n set_current_segnum(SEG_DATA);
+\.bss[ \t]*\r?\n set_current_segnum(SEG_BSS);
+
+\.align[ \t]{EXPR}\r?\n {
+ struct seg *seg = get_current_seg();
+ char *s = xstrdup(yytext+7);
+ int32_t a = 1 << expr_nevaluate(s);
+
+ while ((seg->pos % a) != 0)
+ {
+ if (get_current_segnum() == SEG_TEXT)
+ {
+ emit_nop(seg);
+ }
+ else
+ {
+ emit_zero(seg);
+ }
+ }
+ }
+
+\.comm[ \t]{SYM}[ \t]*,[ \t]*{EXPR}\r?\n {
+ int32_t i;
+ char *s = xstrdup(yytext+6);
+ char *t = s;
+
+ t = strpbrk(s, ",");
+ *t++ = '\0';
+
+ s = localize_string(s);
+ check_sym_dup(s);
+ push_sym(s, SEG_BSS, get_seg(SEG_BSS)->pos);
+ trace_listing(get_seg(SEG_BSS), get_seg(SEG_BSS)->pos, s);
+ trace_listing(get_seg(SEG_BSS), get_seg(SEG_BSS)->pos, ":\t");
+
+ for (i=0; i < expr_nevaluate(t); i++)
+ {
+ emit_zero(get_seg(SEG_BSS));
+ }
+ }
+
+\.lcomm[ \t]{SYM}[ \t]*,[ \t]*{EXPR}\r?\n {
+ int32_t i;
+ char *s = xstrdup(yytext+7);
+ char *t = s;
+
+ t = strpbrk(s, ",");
+ *t++ = '\0';
+
+ s = localize_string(s);
+ check_sym_dup(s);
+ push_sym(s, SEG_BSS, get_seg(SEG_BSS)->pos);
+ trace_listing(get_seg(SEG_BSS), get_seg(SEG_BSS)->pos, s);
+ trace_listing(get_seg(SEG_BSS), get_seg(SEG_BSS)->pos, ":\t");
+
+ for (i=0; i < expr_nevaluate(t); i++)
+ {
+ emit_zero(get_seg(SEG_BSS));
+ }
+ }
+
+\.org[ \t]{EXPR}\r?\n {
+ struct seg *seg = get_current_seg();
+ char *s = xstrdup(yytext+6);
+ int32_t o = expr_nevaluate(s);
+
+ check_org_advances(seg, o);
+
+ while (seg->pos < o)
+ {
+ if (get_current_segnum() == SEG_TEXT)
+ {
+ emit_nop(seg);
+ }
+ else
+ {
+ emit_zero(seg);
+ }
+ }
+ }
+
+\.skip[ \t]{EXPR}\r?\n {
+ struct seg *seg = get_current_seg();
+ char *s = xstrdup(yytext+6);
+ int32_t i;
+
+ for (i = 0; i < expr_nevaluate(s); i++)
+ {
+ if (get_current_segnum() == SEG_TEXT)
+ {
+ emit_nop(seg);
+ }
+ else
+ {
+ emit_zero(seg);
+ }
+ }
+ }
+
+{SYM}: {
+ char *s;
+ struct seg *seg = get_current_seg();
+ s = xstrdup(yytext);
+ s[yyleng-1] = '\0';
+ s = localize_string(s);
+ check_sym_dup(s);
+ push_sym(s, get_current_segnum(), seg->pos);
+ trace_listing(seg, seg->pos, s);
+ trace_listing(seg, seg->pos, ":\t");
+ }
+
+data MATCH_OP(DATA);
+add MATCH_OP(ADD);
+addc MATCH_OP(ADDC);
+sub MATCH_OP(SUB);
+subc MATCH_OP(SUBC);
+and MATCH_OP(AND);
+or MATCH_OP(OR);
+xor MATCH_OP(XOR);
+mul MATCH_OP(MUL);
+div MATCH_OP(DIV);
+udiv MATCH_OP(UDIV);
+ldil MATCH_OP(LDIL);
+ldih MATCH_OP(LDIH);
+ldib MATCH_OP(LDIB);
+mov MATCH_OP(MOV);
+not MATCH_OP(NOT);
+neg MATCH_OP(NEG);
+cmp MATCH_OP(CMP);
+addi MATCH_OP(ADDI);
+cmpi MATCH_OP(CMPI);
+shl MATCH_OP(SHL);
+shr MATCH_OP(SHR);
+sar MATCH_OP(SAR);
+mod MATCH_OP(MOD);
+umod MATCH_OP(UMOD);
+rolc MATCH_OP(ROLC);
+rorc MATCH_OP(RORC);
+bset MATCH_OP(BSET);
+bclr MATCH_OP(BCLR);
+btest MATCH_OP(BTEST);
+load MATCH_OP(LOAD);
+store MATCH_OP(STORE);
+loadl MATCH_OP(LOADL);
+loadh MATCH_OP(LOADH);
+loadb MATCH_OP(LOADB);
+storel MATCH_OP(STOREL);
+storeh MATCH_OP(STOREH);
+call MATCH_OP(CALL);
+
+br MATCH_OP(BR);
+brz MATCH_OP(BRZ);
+brnz MATCH_OP(BRNZ);
+brle MATCH_OP(BRLE);
+brlt MATCH_OP(BRLT);
+brge MATCH_OP(BRGE);
+brgt MATCH_OP(BRGT);
+brule MATCH_OP(BRULE);
+brult MATCH_OP(BRULT);
+bruge MATCH_OP(BRUGE);
+brugt MATCH_OP(BRUGT);
+sext MATCH_OP(SEXT);
+ldvec MATCH_OP(LDVEC);
+stvec MATCH_OP(STVEC);
+
+jmp MATCH_OP(JMP);
+jmpz MATCH_OP(JMPZ);
+jmpnz MATCH_OP(JMPNZ);
+jmple MATCH_OP(JMPLE);
+jmplt MATCH_OP(JMPLT);
+jmpge MATCH_OP(JMPGE);
+jmpgt MATCH_OP(JMPGT);
+jmpule MATCH_OP(JMPULE);
+jmpult MATCH_OP(JMPULT);
+jmpuge MATCH_OP(JMPUGE);
+jmpugt MATCH_OP(JMPUGT);
+intr MATCH_OP(INTR);
+getira MATCH_OP(GETIRA);
+setira MATCH_OP(SETIRA);
+getfl MATCH_OP(GETFL);
+setfl MATCH_OP(SETFL);
+getshfl MATCH_OP(GETSHFL);
+setshfl MATCH_OP(SETSHFL);
+
+reti MATCH_OP(RETI);
+nop MATCH_OP(NOP);
+sei MATCH_OP(SEI);
+cli MATCH_OP(CLI);
+error MATCH_OP(ERROR);
+
+{REG} {
+ struct seg *seg = get_current_seg();
+ int arg_index = get_arg_count(seg, seg->pos) - (args_to_match+1)/2;
+
+ if (check_arg_count() || check_arg_type(seg, seg->pos, arg_index, 'r'))
+ YY_BREAK;
+
+ set_regnum(seg, seg->pos, arg_index, strtol(yytext+1, NULL, 10));
+ set_mode(seg, seg->pos, arg_index, 'r');
+ trace_listing(seg, seg->pos, yytext);
+ args_to_match--;
+ }
+
+{EXPR} {
+ struct seg *seg = get_current_seg();
+ int arg_index;
+
+ if (!seen_op)
+ {
+ REJECT;
+ }
+
+ arg_index = get_arg_count(seg, seg->pos) - (args_to_match+1)/2;
+
+ if (check_arg_count() || check_arg_type(seg, seg->pos, arg_index, 'n'))
+ YY_BREAK;
+
+ set_expr(seg, seg->pos, arg_index, expr_localize(yytext));
+ set_mode(seg, seg->pos, arg_index, 'n');
+ trace_listing(seg, seg->pos, yytext);
+ args_to_match--;
+ }
+
+, {
+ check_colon_ok();
+ trace_listing(get_current_seg(), get_current_seg()->pos, ", ");
+ args_to_match--;
+ }
+
+;.* { /* ignore comments */ }
+
+[ \t\r]+ { /* ignore whitespace */ }
+
+\n+ {
+ check_premature();
+ expand_mod();
+ if (seen_op)
+ {
+ get_current_seg()->pos++;
+ seen_op = 0;
+ args_to_match = -1;
+ }
+ line_count += yyleng;
+ }
+
+<> {
+ check_premature();
+ expand_mod();
+ if (seen_op)
+ {
+ get_current_seg()->pos++;
+ seen_op = 0;
+ args_to_match = -1;
+ }
+ yyterminate();
+ }
+
+. {
+ fprintf(stderr, "invalid input `%c' in line %lu\n", yytext[0], line_count);
+ error_count++;
+ }
+
+%%
+
+int initialize(void)
+{
+ init_symtab();
+
+ init_seg(SEG_DATA, SEG_INITSIZE/2);
+ init_seg(SEG_BSS, SEG_INITSIZE/2);
+ init_seg(SEG_TEXT, SEG_INITSIZE);
+
+ set_current_segnum(SEG_TEXT);
+
+ return 0;
+}
+
+int merge(void)
+{
+ uint32_t pos;
+ int retval = 0;
+
+ init_seg(SEG_PILE, SEG_INITSIZE);
+
+ /* align .data to word boundary */
+ if ((get_seg(SEG_DATA)->pos % 2) != 0)
+ {
+ emit_zero(get_seg(SEG_DATA));
+ }
+
+ /* align .bss to word boundary */
+ if ((get_seg(SEG_BSS)->pos % 2) != 0)
+ {
+ emit_zero(get_seg(SEG_BSS));
+ }
+
+ /* check .data */
+ for (pos = 0; pos < get_seg(SEG_DATA)->pos; pos += 2)
+ {
+ if ((get_op(get_seg(SEG_DATA), pos) != DATA)
+ || (get_op(get_seg(SEG_DATA), pos+1) != DATA))
+ {
+ fprintf(stderr, "cannot initialize anything but `data' in .data\n");
+ error_count++;
+ retval = 1;
+ }
+ }
+
+ /* check .bss */
+ for (pos = 0; pos < get_seg(SEG_BSS)->pos; pos++)
+ {
+ if ((get_op(get_seg(SEG_BSS), pos) != DATA)
+ || (expr_symcount(get_expr(get_seg(SEG_BSS), pos, 0)) > 0)
+ || (expr_evaluate(get_expr(get_seg(SEG_BSS), pos, 0)) != 0))
+ {
+ fprintf(stderr, "cannot put anything but `data 0' in .bss\n");
+ error_count++;
+ retval = 1;
+ }
+ }
+
+ /* copy data from ROM */
+ if (get_seg(SEG_DATA)->pos != 0)
+ {
+ emit_ldil(get_seg(SEG_PILE), 0,
+ xsprintf("lo(%d)", get_seg(SEG_DATA)->pos));
+ emit_ldih(get_seg(SEG_PILE), 0,
+ xsprintf("hi(%d)", get_seg(SEG_DATA)->pos));
+
+ emit_ldil(get_seg(SEG_PILE), 1,
+ xsprintf("lo(%d)", datasize));
+ emit_ldih(get_seg(SEG_PILE), 1,
+ xsprintf("hi(%d)", datasize));
+
+ emit_ldib(get_seg(SEG_PILE), 2, "0");
+ push_sym("__init_data_loop__", SEG_PILE, get_seg(SEG_PILE)->pos);
+ trace_listing(get_seg(SEG_PILE), get_seg(SEG_PILE)->pos,
+ "__init_data_loop__:\t");
+ emit_load(get_seg(SEG_PILE), 3, 1);
+ emit_store(get_seg(SEG_PILE), 3, 2);
+ emit_addi(get_seg(SEG_PILE), 1, "2");
+ emit_addi(get_seg(SEG_PILE), 2, "2");
+ emit_cmp(get_seg(SEG_PILE), 0, 2);
+ emit_brnz(get_seg(SEG_PILE), "__init_data_loop__");
+ }
+
+ /* clear .bss */
+ if (get_seg(SEG_BSS)->pos != 0)
+ {
+ emit_ldil(get_seg(SEG_PILE), 0,
+ xsprintf("lo(%d+%d)", get_seg(SEG_DATA)->pos,
+ get_seg(SEG_BSS)->pos));
+ emit_ldih(get_seg(SEG_PILE), 0,
+ xsprintf("hi(%d+%d)", get_seg(SEG_DATA)->pos,
+ get_seg(SEG_BSS)->pos));
+ emit_ldib(get_seg(SEG_PILE), 3, "0");
+ push_sym("__init_bss_loop__", SEG_PILE, get_seg(SEG_PILE)->pos);
+ trace_listing(get_seg(SEG_PILE), get_seg(SEG_PILE)->pos,
+ "__init_bss_loop__:\t");
+ emit_store(get_seg(SEG_PILE), 3, 2);
+ emit_addi(get_seg(SEG_PILE), 2, "2");
+ emit_cmp(get_seg(SEG_PILE), 0, 2);
+ emit_brnz(get_seg(SEG_PILE), "__init_bss_loop__");
+ }
+
+ reloc_syms(SEG_BSS, get_seg(SEG_DATA)->pos);
+ reloc_syms(SEG_TEXT, get_seg(SEG_PILE)->pos);
+
+ for(pos = 0; pos < get_seg(SEG_TEXT)->pos; pos++)
+ {
+ emit_op(get_seg(SEG_PILE), get_seg(SEG_TEXT)->code[pos]);
+ }
+
+ set_current_segnum(SEG_PILE);
+
+ return retval;
+}
+
+int postprocess(void)
+{
+ struct seg *seg;
+ uint32_t pos;
+ int retval = 0;
+
+ if ((output_mode != MODE_DRYRUN)
+ && (check_code_size()
+ || check_data_size()))
+ {
+ retval = 1;
+ }
+
+ seg = get_seg(SEG_PILE);
+ for (pos = 0; pos < seg->pos; pos++)
+ {
+ if (check_mnemonic(seg, pos))
+ {
+ retval = 1;
+ }
+ if ((output_mode != MODE_DRYRUN)
+ && (fix_operands(seg, pos)
+ || check_ranges(seg, pos)
+ || fix_code(seg, pos)))
+ {
+ retval = 1;
+ }
+ }
+
+ seg = get_seg(SEG_DATA);
+ for (pos = 0; pos < seg->pos; pos++)
+ {
+ if (check_mnemonic(seg, pos))
+ {
+ retval = 1;
+ }
+ if ((output_mode != MODE_DRYRUN)
+ && (fix_operands(seg, pos)
+ || check_ranges(seg, pos)
+ || fix_code(seg, pos)))
+ {
+ retval = 1;
+ }
+ }
+
+ return retval;
+}
+
+/***************** LIB *****************/
+
+void *xmalloc(size_t size)
+{
+ void *retval = malloc(size);
+ if (retval == NULL)
+ {
+ fprintf(stderr, "run out of memory\n");
+ exit(EXIT_FAILURE);
+ }
+ return retval;
+}
+
+void *xrealloc(void *ptr, size_t size)
+{
+ void *retval = realloc(ptr, size);
+ if (retval == NULL)
+ {
+ fprintf(stderr, "run out of memory\n");
+ exit(EXIT_FAILURE);
+ }
+ return retval;
+}
+
+char *xstrdup(const char *str)
+{
+ size_t len = strlen(str);
+ void *retval = xmalloc(len+1);
+ memcpy(retval, str, len+1);
+ return retval;
+}
+
+char *xsprintf(const char *fmt, ...)
+{
+ va_list ap;
+ char *retval;
+
+ va_start(ap, fmt);
+ vasprintf(&retval, fmt, ap);
+ va_end(ap);
+
+ if (retval == NULL)
+ {
+ fprintf(stderr, "run out of memory\n");
+ exit(EXIT_FAILURE);
+ }
+
+ return retval;
+}
+
+/***************** MAIN *****************/
+
+int yywrap()
+{
+ return 1;
+}
+
+int main(int argc, char **argv)
+{
+ int opt;
+
+ int opterr = 0;
+
+ int hopt = 0;
+ int vopt = 0;
+
+ command = argv[0];
+
+ while (optind < argc)
+ {
+ if (strcmp(argv[optind], "-") == 0 || (argv[optind][0] != '-'))
+ {
+ opt = -1;
+ }
+ else
+ {
+ opt = getopt_long(argc, argv, options, long_options, 0);
+ }
+
+ switch(opt)
+ {
+ case 'h': hopt++; break;
+ case 'v': vopt++; break;
+ case 'o': case '0': case '1':
+ case 'c': case 'd': case 'r':
+ case 'f': case 'i': case 'n': case 'l':
+ case 'm': case 's': case 'e':
+ break;
+ case '?': opterr = 1; break;
+ case -1: optind++; break;
+ }
+ }
+
+ if (opterr)
+ {
+ printf("Usage:\n"
+ " %s [--intel|--nointel|--download|--dryrun]\n"
+ " [--codesize=*n*] [--datasize=*n*] [--romsize=*n*]\n"
+ " [--filler=*n*] [--output=file] [--rom0file=file] [--rom1file=file]\n"
+ " [--nostart] [--noend] file ...\n", command);
+ return EXIT_FAILURE;
+ }
+
+ if (vopt)
+ {
+ printf("spar 0.2\n");
+ return EXIT_SUCCESS;
+ }
+
+ if (hopt)
+ {
+ printf("Usage:\n"
+ " %s [--intel|--nointel|--download|--dryrun]\n"
+ " [--codesize=*n*] [--datasize=*n*] [--romsize=*n*]\n"
+ " [--filler=*n*] [--output=file] [--rom0file=file] [--rom1file=file]\n"
+ " [--nostart] [--noend] file ...\n", command);
+ return EXIT_SUCCESS;
+ }
+
+ optind = 1;
+
+ initialize();
+
+ while (optind < argc)
+ {
+ if (strcmp(argv[optind], "-") == 0 || (argv[optind][0] != '-'))
+ {
+ opt = -1;
+ }
+ else
+ {
+ opt = getopt_long(argc, argv, options, long_options, 0);
+ }
+
+ switch (opt)
+ {
+ case 'h': case 'v':
+ break;
+ case 'o':
+ if (strcmp(optarg, "-") == 0)
+ {
+ output_file = stdout;
+ }
+ else
+ {
+ output_file = fopen(optarg, "w");
+ if (output_file == NULL)
+ {
+ fprintf(stderr, "cannot open file %s\n", optarg);
+ return EXIT_FAILURE;
+ }
+ }
+ break;
+ case '0':
+ if (strcmp(optarg, "-") == 0)
+ {
+ rom0_file = stdout;
+ }
+ else
+ {
+ rom0_file = fopen(optarg, "w");
+ if (rom0_file == NULL)
+ {
+ fprintf(stderr, "cannot open file %s\n", optarg);
+ return EXIT_FAILURE;
+ }
+ }
+ break;
+ case '1':
+ if (strcmp(optarg, "-") == 0)
+ {
+ rom1_file = stdout;
+ }
+ else
+ {
+ rom1_file = fopen(optarg, "w");
+ if (rom1_file == NULL)
+ {
+ fprintf(stderr, "cannot open file %s\n", optarg);
+ return EXIT_FAILURE;
+ }
+ }
+ break;
+ case 'c':
+ {
+ char * errptr = NULL;
+ romsize = strtol(optarg, &errptr, 0);
+ if (*errptr != '\0')
+ {
+ fprintf(stderr, "invalid codesize %s\n", optarg);
+ return EXIT_FAILURE;
+ }
+ }
+ break;
+ case 'd':
+ {
+ char * errptr = NULL;
+ romsize = strtol(optarg, &errptr, 0);
+ if (*errptr != '\0')
+ {
+ fprintf(stderr, "invalid datasize %s\n", optarg);
+ return EXIT_FAILURE;
+ }
+ }
+ break;
+ case 'r':
+ {
+ char * errptr = NULL;
+ romsize = strtol(optarg, &errptr, 0);
+ if (*errptr != '\0')
+ {
+ fprintf(stderr, "invalid romsize %s\n", optarg);
+ return EXIT_FAILURE;
+ }
+ }
+ break;
+ case 'f':
+ {
+ char * errptr = NULL;
+ filler = strtol(optarg, &errptr, 0);
+ if (*errptr != '\0')
+ {
+ fprintf(stderr, "invalid filler %s\n", optarg);
+ return EXIT_FAILURE;
+ }
+ }
+ break;
+ case 'i': output_mode = MODE_INTEL; break;
+ case 'n': output_mode = MODE_DRYRUN; break;
+ case 'l': output_mode = MODE_DOWNLOAD; break;
+ case 'm': output_mode = MODE_MIF; break;
+ case 's': nostart = 1; break;
+ case 'e': noend = 1; break;
+ case '?': break;
+ case -1:
+ if (argv[optind] == NULL)
+ break;
+ if (strcmp(argv[optind], "-") == 0)
+ {
+ yyin = stdin;
+ }
+ else
+ {
+ yyin = fopen(argv[optind], "r");
+ if (yyin == NULL)
+ {
+ fprintf(stderr, "cannot open file %s\n", argv[optind]);
+ return EXIT_FAILURE;
+ }
+ }
+ yylex();
+ file_count++;
+
+ optind++;
+ break;
+ }
+ }
+
+ if (output_file == NULL)
+ {
+ output_file = stdout;
+ }
+ if (rom0_file == NULL)
+ {
+ rom0_file = stdout;
+ }
+ if (rom1_file == NULL)
+ {
+ rom1_file = stdout;
+ }
+
+ if (file_count == 0)
+ {
+ yyin = stdin;
+ yylex();
+ }
+
+ merge();
+
+ postprocess();
+
+ if (error_count != 0)
+ {
+ fprintf(stderr, "found %lu error(s)\n", error_count);
+ return EXIT_FAILURE;
+ }
+
+ if (output_file == NULL)
+ {
+ output_file = stdout;
+ }
+ if (rom0_file == NULL)
+ {
+ rom0_file = stdout;
+ }
+ if (rom1_file == NULL)
+ {
+ rom1_file = stdout;
+ }
+
+ switch (output_mode)
+ {
+ case MODE_DRYRUN: break;
+ case MODE_DOWNLOAD: print_download(output_file, rom0_file, rom1_file); break;
+ case MODE_INTEL: print_intel(output_file, rom0_file, rom1_file); break;
+ case MODE_MIF: print_mif(output_file, rom0_file, rom1_file); break;
+ }
+
+ if (output_file != stdout)
+ {
+ fclose(output_file);
+ }
+ if (rom0_file != stdout)
+ {
+ fclose(rom0_file);
+ }
+ if (rom1_file != stdout)
+ {
+ fclose(rom1_file);
+ }
+
+ return EXIT_SUCCESS;
+}
Index: trunk/spar/expand.c
===================================================================
--- trunk/spar/expand.c (nonexistent)
+++ trunk/spar/expand.c (revision 2)
@@ -0,0 +1,59 @@
+/* This file is part of the assembler "spar" for marca.
+ Copyright (C) 2007 Wolfgang Puffitsch
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library 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 */
+
+#include "spar.h"
+#include "expand.h"
+#include "code.h"
+#include "optab.h"
+
+void expand_mod(void)
+{
+ struct op o = get_current_seg()->code[get_current_seg()->pos];
+
+ if ((o.op == MOD) || (o.op == UMOD))
+ {
+ if (o.args[0].val.regnum != o.args[2].val.regnum)
+ {
+ struct seg* seg = get_current_seg();
+
+ set_op(seg, seg->pos, MOV);
+ set_mode(seg, seg->pos, 0, 'r');
+ set_regnum(seg, seg->pos, 0, o.args[2].val.regnum);
+ set_mode(seg, seg->pos, 1, 'r');
+ set_regnum(seg, seg->pos, 1, o.args[0].val.regnum);
+ set_listing(seg, seg->pos, xsprintf("mov\tr%d, r%d",
+ o.args[2].val.regnum,
+ o.args[0].val.regnum));
+
+ seg->pos++;
+ adjust_segsize(seg, seg->pos+1);
+
+ set_op(seg, seg->pos, o.op);
+ set_mode(seg, seg->pos, 0, 'r');
+ set_regnum(seg, seg->pos, 0, o.args[2].val.regnum);
+ set_mode(seg, seg->pos, 1, 'r');
+ set_regnum(seg, seg->pos, 1, o.args[1].val.regnum);
+ set_mode(seg, seg->pos, 2, 'r');
+ set_regnum(seg, seg->pos, 2, 0); /* this should never be used */
+ set_listing(seg, seg->pos, xsprintf("%s\tr%d, r%d, r%d",
+ o.op == MOD ? "mod" : "umod",
+ o.args[2].val.regnum,
+ o.args[1].val.regnum,
+ o.args[2].val.regnum));
+ }
+ }
+}
Index: trunk/spar/code.h
===================================================================
--- trunk/spar/code.h (nonexistent)
+++ trunk/spar/code.h (revision 2)
@@ -0,0 +1,60 @@
+/* This file is part of the assembler "spar" for marca.
+ Copyright (C) 2007 Wolfgang Puffitsch
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library 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 */
+
+#ifndef _CODE_H_
+#define _CODE_H_
+
+#include
+
+#define CODE_MAX_ARGS 3
+#define CODE_MAX_LISTLEN 32
+
+struct arg
+{
+ char mode;
+ union
+ {
+ uint16_t regnum;
+ char *expr;
+ } val;
+};
+
+struct op
+{
+ uint16_t op;
+ struct arg args [CODE_MAX_ARGS];
+ uint16_t code;
+ char listing [CODE_MAX_LISTLEN];
+};
+
+#include "segtab.h"
+
+void set_op(struct seg *, uint32_t, uint16_t);
+uint16_t get_op(struct seg *, uint32_t);
+void set_mode(struct seg *, uint32_t, uint8_t, char);
+char get_mode(struct seg *, uint32_t, uint8_t);
+void set_regnum(struct seg *, uint32_t, uint8_t, uint16_t);
+uint16_t get_regnum(struct seg *, uint32_t, uint8_t);
+void set_expr(struct seg *, uint32_t, uint8_t, char *);
+char * get_expr(struct seg *, uint32_t, uint8_t);
+void set_code(struct seg *, uint32_t, uint16_t);
+uint16_t get_code(struct seg *, uint32_t);
+void set_listing(struct seg *, uint32_t, const char *);
+void trace_listing(struct seg *, uint32_t, const char *);
+const char *get_listing(struct seg *, uint32_t);
+
+#endif /* _CODE_H_ */
Index: trunk/spar/ui.h
===================================================================
--- trunk/spar/ui.h (nonexistent)
+++ trunk/spar/ui.h (revision 2)
@@ -0,0 +1,49 @@
+/* This file is part of the assembler "spar" for marca.
+ Copyright (C) 2007 Wolfgang Puffitsch
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library 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 */
+
+#ifndef _UI_H_
+#define _UI_H_
+
+#include
+#include
+#include
+
+#define MODE_DRYRUN 0
+#define MODE_DOWNLOAD 1
+#define MODE_INTEL 2
+#define MODE_MIF 3
+
+extern int8_t output_mode;
+
+extern uint32_t codesize;
+extern uint32_t datasize;
+extern uint32_t romsize;
+extern uint16_t filler;
+
+extern int nostart;
+extern int noend;
+
+#define DEFAULT_MODE MODE_MIF
+#define DEFAULT_CODESIZE 8192
+#define DEFAULT_DATASIZE 8192
+#define DEFAULT_ROMSIZE 256
+#define DEFAULT_FILLER 0xFFFF
+
+extern const char * const options;
+extern const struct option long_options [];
+
+#endif /* _UI_H_ */
Index: trunk/spar/fixes.h
===================================================================
--- trunk/spar/fixes.h (nonexistent)
+++ trunk/spar/fixes.h (revision 2)
@@ -0,0 +1,28 @@
+/* This file is part of the assembler "spar" for marca.
+ Copyright (C) 2007 Wolfgang Puffitsch
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library 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 */
+
+#ifndef _FIXES_H_
+#define _FIXES_H_
+
+#include
+
+#include "segtab.h"
+
+int fix_operands(struct seg *, uint32_t);
+int fix_code(struct seg *, uint32_t);
+
+#endif /* _FIXES_H_ */
Index: trunk/spar/expand.h
===================================================================
--- trunk/spar/expand.h (nonexistent)
+++ trunk/spar/expand.h (revision 2)
@@ -0,0 +1,23 @@
+/* This file is part of the assembler "spar" for marca.
+ Copyright (C) 2007 Wolfgang Puffitsch
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library 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 */
+
+#ifndef _EXPAND_H_
+#define _EXPAND_H_
+
+void expand_mod(void);
+
+#endif /* _EXPAND_H_ */
Index: trunk/spar/exprs.y
===================================================================
--- trunk/spar/exprs.y (nonexistent)
+++ trunk/spar/exprs.y (revision 2)
@@ -0,0 +1,260 @@
+/* This file is part of the assembler "spar" for marca.
+ Copyright (C) 2007 Wolfgang Puffitsch
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library 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 */
+
+%{
+
+#include
+#include
+
+#include "exprs.h"
+
+int exprslex(void);
+void yyerror(int64_t *, const char *);
+
+%}
+
+%union {
+ int64_t intval;
+}
+
+%parse-param {
+ int64_t *retval, int64_t *symcount
+}
+
+%token NUM IDENT
+
+%token CUMOD CEQU CUGT CSHR CUMIN CLE CNEQ CMIN CLAND
+%token CGE CUDIV CUGE CULE CLOR CULT CSHL CMAX CUMAX CSLR
+%token HI LO
+
+%type PrimaryExpr UnaryExpr MultExpr AddExpr ShiftExpr
+%type RelatExpr EqualExpr AndExpr XorExpr OrExpr
+%type LAndExpr LOrExpr CondExpr MinMaxExpr HiLoExpr Expr
+
+%start Expr
+
+%%
+
+PrimaryExpr : NUM
+ { $$ = $1;
+ }
+ | IDENT
+ { (*symcount)++;
+ $$ = $1;
+ }
+ | '(' Expr ')'
+ { $$ = $2;
+ }
+;
+
+UnaryExpr : PrimaryExpr
+ | '+' UnaryExpr
+ { $$ = $2;
+ }
+ | '-' UnaryExpr
+ { $$ = -$2;
+ }
+ | '~' UnaryExpr
+ { $$ = ~$2;
+ }
+ | '!' UnaryExpr
+ { $$ = !$2;
+ }
+;
+
+MultExpr : UnaryExpr
+ | MultExpr '*' UnaryExpr
+ { $$ = $1 * $3;
+ }
+ | MultExpr '/' UnaryExpr
+ {
+ if ($3 == 0)
+ {
+ fprintf(stderr, "division by zero");
+ $$ = 0;
+ }
+ else
+ {
+ $$ = $1 / $3;
+ }
+ }
+ | MultExpr CUDIV UnaryExpr
+ {
+ if ($3 == 0)
+ {
+ fprintf(stderr, "division by zero");
+ $$ = 0;
+ }
+ else
+ {
+ $$ = (uint64_t)$1 / (uint64_t)$3;
+ }
+ }
+ | MultExpr '%' UnaryExpr
+ {
+ if ($3 == 0)
+ {
+ fprintf(stderr, "modulo zero");
+ $$ = 0;
+ }
+ else
+ {
+ $$ = $1 % $3;
+ }
+ }
+ | MultExpr CUMOD UnaryExpr
+ {
+ if ($3 == 0)
+ {
+ fprintf(stderr, "modulo zero");
+ $$ = 0;
+ }
+ else
+ {
+ $$ = (uint64_t)$1 % (uint64_t)$3;
+ }
+ }
+;
+
+AddExpr : MultExpr
+ | AddExpr '+' MultExpr
+ { $$ = $1 + $3;
+ }
+ | AddExpr '-' MultExpr
+ { $$ = $1 - $3;
+ }
+;
+
+ShiftExpr : AddExpr
+ | ShiftExpr CSHR AddExpr
+ { $$ = $1 >> $3;
+ }
+ | ShiftExpr CSHL AddExpr
+ { $$ = $1 << $3;
+ }
+ | ShiftExpr CSLR AddExpr
+ { $$ = (uint64_t)$1 >> $3;
+ }
+;
+
+RelatExpr : ShiftExpr
+ | RelatExpr '<' ShiftExpr
+ { $$ = $1 < $3;
+ }
+ | RelatExpr '>' ShiftExpr
+ { $$ = $1 > $3;
+ }
+ | RelatExpr CLE ShiftExpr
+ { $$ = $1 <= $3;
+ }
+ | RelatExpr CGE ShiftExpr
+ { $$ = $1 >= $3;
+ }
+ | RelatExpr CULT ShiftExpr
+ { $$ = (uint64_t)$1 < (uint64_t)$3;
+ }
+ | RelatExpr CUGT ShiftExpr
+ { $$ = (uint64_t)$1 > (uint64_t)$3;
+ }
+ | RelatExpr CULE ShiftExpr
+ { $$ = (uint64_t)$1 <= (uint64_t)$3;
+ }
+ | RelatExpr CUGE ShiftExpr
+ { $$ = (uint64_t)$1 >= (uint64_t)$3;
+ }
+;
+
+EqualExpr : RelatExpr
+ | EqualExpr CEQU RelatExpr
+ { $$ = $1 == $3;
+ }
+ | EqualExpr CNEQ RelatExpr
+ { $$ = $1 != $3;
+ }
+;
+
+AndExpr : EqualExpr
+ | AndExpr '&' EqualExpr
+ { $$ = $1 & $3;
+ }
+;
+
+XorExpr : AndExpr
+ | XorExpr '^' AndExpr
+ { $$ = $1 ^ $3;
+ }
+;
+
+OrExpr : XorExpr
+ | OrExpr '|' XorExpr
+ { $$ = $1 | $3;
+ }
+;
+
+LAndExpr : OrExpr
+ | LAndExpr CLAND OrExpr
+ { $$ = $1 && $3;
+ }
+;
+
+LOrExpr : LAndExpr
+ | LOrExpr CLOR LAndExpr
+ { $$ = $1 || $3;
+ }
+;
+
+CondExpr : LOrExpr
+ | LOrExpr '?' Expr ':' CondExpr
+ { $$ = $1 ? $3 : $5;
+ }
+;
+
+MinMaxExpr : CondExpr
+ | MinMaxExpr CMIN CondExpr
+ { $$ = $1 < $3 ? $1 : $3;
+ }
+ | MinMaxExpr CMAX CondExpr
+ { $$ = $1 > $3 ? $1 : $3;
+ }
+ | MinMaxExpr CUMIN CondExpr
+ { $$ = (uint64_t)$1 < (uint64_t)$3 ? $1 : $3;
+ }
+ | MinMaxExpr CUMAX CondExpr
+ { $$ = (uint64_t)$1 > (uint64_t)$3 ? $1 : $3;
+ }
+;
+
+HiLoExpr : MinMaxExpr
+ | HI '(' MinMaxExpr ')'
+ { $$ = ($3 >> 8) & 0xFF;
+ }
+ | LO '(' MinMaxExpr ')'
+ { $$ = $3 & 0xFF;
+ }
+
+Expr: HiLoExpr
+ { *retval = $1;
+ }
+;
+
+%%
+
+void yyerror(int64_t *r, const char *msg)
+{
+ fprintf(stderr, "within expression: %s\n", msg);
+}
+
Index: trunk/spar/Makefile
===================================================================
--- trunk/spar/Makefile (nonexistent)
+++ trunk/spar/Makefile (revision 2)
@@ -0,0 +1,43 @@
+CC=gcc
+LEX=flex -l
+YACC=bison -y
+
+CFLAGS = -ansi -pedantic -D_GNU_SOURCE -Wall -Wno-format -g
+LFLAGS = -Ce -8
+YFLAGS = -d
+
+all: as1
+
+as1: checks.o code.o emit.o expand.o fixes.o optab.o output.o segtab.o \
+ spar.o symtab.o ui.o lex.exprs.o exprs.tab.o
+ $(CC) -o $@ $^
+
+spar.o: spar.c spar.h ui.h checks.h segtab.h code.h emit.h exprs.h \
+ fixes.h optab.h output.h symtab.h
+spar.o: spar.c exprs.h exprs.tab.h spar.h symtab.h
+spar.c: spar.l
+
+checks.o: checks.c spar.h ui.h checks.h segtab.h code.h exprs.h optab.h \
+ symtab.h
+code.o: code.c code.h segtab.h
+emit.o: emit.c spar.h optab.h code.h segtab.h emit.h exprs.h
+expand.o: expand.c spar.h expand.h code.h segtab.h optab.h
+fixes.o: fixes.c spar.h ui.h code.h segtab.h exprs.h fixes.h optab.h \
+ symtab.h
+optab.o: optab.c optab.h code.h segtab.h
+output.o: output.c spar.h ui.h output.h segtab.h code.h
+segtab.o: segtab.c spar.h segtab.h code.h
+symtab.o: symtab.c spar.h symtab.h
+ui.o: ui.c ui.h
+
+lex.exprs.o: lex.exprs.c exprs.h exprs.tab.h spar.h symtab.h
+lex.exprs.c: exprs.l exprs.tab.h exprs.h
+ $(LEX) $(LFLAGS) -Pexprs exprs.l
+
+exprs.tab.o: exprs.tab.c
+exprs.tab.c exprs.tab.h: exprs.y exprs.h
+ $(YACC) $(YFLAGS) -b exprs -p exprs exprs.y
+ sed -i '/^yydestruct (/ N; s/\n[ \t]*int64_t \*retval,//' exprs.tab.c
+
+clean:
+ rm -f as1 *.o exprs.tab.h exprs.tab.c lex.exprs.c spar.c
Index: trunk/sim/sim1.vwf
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: trunk/sim/sim1.vwf
===================================================================
--- trunk/sim/sim1.vwf (nonexistent)
+++ trunk/sim/sim1.vwf (revision 2)
trunk/sim/sim1.vwf
Property changes :
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: trunk/Makefile
===================================================================
--- trunk/Makefile (nonexistent)
+++ trunk/Makefile (revision 2)
@@ -0,0 +1,26 @@
+all: marca spar doc
+
+marca::
+ echo "You have to build marca from within quartus."
+
+spar::
+ cd spar && make
+
+doc::
+ cd doc && make
+
+dist::
+ tar -czvf marca.tar.gz vhdl/ sim/ spar/ \
+ quartus/marca.qpf quartus/marca.qsf \
+ quartus/marca.pin \
+ doc/isa.tex doc/implementation.tex \
+ doc/factorial.s doc/uart_reverse.s \
+ doc/marca.dia doc/marca.eps doc/marca.png \
+ doc/uart_sim.eps doc/uart_sim.png \
+ doc/Makefile \
+ Makefile gpl.txt \
+ --exclude '*~'
+
+clean::
+ make -C spar clean
+ make -C doc clean
\ No newline at end of file
Index: trunk/vhdl/fetch_ent.vhd
===================================================================
--- trunk/vhdl/fetch_ent.vhd (nonexistent)
+++ trunk/vhdl/fetch_ent.vhd (revision 2)
@@ -0,0 +1,51 @@
+-- This file is part of the marca processor.
+-- Copyright (C) 2007 Wolfgang Puffitsch
+
+-- This program is free software; you can redistribute it and/or modify it
+-- under the terms of the GNU Library 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
+-- Library General Public License for more details.
+
+-- You should have received a copy of the GNU Library 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
+
+-------------------------------------------------------------------------------
+-- MARCA fetch stage
+-------------------------------------------------------------------------------
+-- entity definition for the instruction-fetch pipeline stage
+-------------------------------------------------------------------------------
+
+-------------------------------------------------------------------------------
+-- Wolfgang Puffitsch
+-- Computer Architecture Lab, Group 3
+-------------------------------------------------------------------------------
+
+library IEEE;
+use IEEE.std_logic_1164.all;
+
+use work.marca_pkg.all;
+
+entity fetch is
+
+ port (
+ clock : in std_logic;
+ reset : in std_logic;
+
+ hold : in std_logic;
+
+ pcena : in std_logic;
+ pc_in : in std_logic_vector(REG_WIDTH-1 downto 0);
+ pc_out : out std_logic_vector(REG_WIDTH-1 downto 0);
+
+ src1 : out std_logic_vector(REG_COUNT_LOG-1 downto 0);
+ src2 : out std_logic_vector(REG_COUNT_LOG-1 downto 0);
+ dest : out std_logic_vector(REG_COUNT_LOG-1 downto 0);
+ instr : out std_logic_vector(PDATA_WIDTH-1 downto 0));
+
+end fetch;
Index: trunk/vhdl/data_memory.vhd
===================================================================
--- trunk/vhdl/data_memory.vhd (nonexistent)
+++ trunk/vhdl/data_memory.vhd (revision 2)
@@ -0,0 +1,182 @@
+-- megafunction wizard: %RAM: 1-PORT%
+-- GENERATION: STANDARD
+-- VERSION: WM1.0
+-- MODULE: altsyncram
+
+-- ============================================================
+-- File Name: data_memory.vhd
+-- Megafunction Name(s):
+-- altsyncram
+-- ============================================================
+-- ************************************************************
+-- THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE!
+--
+-- 6.0 Build 202 06/20/2006 SP 1 SJ Web Edition
+-- ************************************************************
+
+
+--Copyright (C) 1991-2006 Altera Corporation
+--Your use of Altera Corporation's design tools, logic functions
+--and other software and tools, and its AMPP partner logic
+--functions, and any output files any of the foregoing
+--(including device programming or simulation files), and any
+--associated documentation or information are expressly subject
+--to the terms and conditions of the Altera Program License
+--Subscription Agreement, Altera MegaCore Function License
+--Agreement, or other applicable license agreement, including,
+--without limitation, that your use is for the sole purpose of
+--programming logic devices manufactured by Altera and sold by
+--Altera or its authorized distributors. Please refer to the
+--applicable agreement for further details.
+
+
+LIBRARY ieee;
+USE ieee.std_logic_1164.all;
+
+LIBRARY altera_mf;
+USE altera_mf.all;
+
+ENTITY data_memory IS
+ PORT
+ (
+ address : IN STD_LOGIC_VECTOR (11 DOWNTO 0);
+ clken : IN STD_LOGIC ;
+ clock : IN STD_LOGIC ;
+ data : IN STD_LOGIC_VECTOR (7 DOWNTO 0);
+ wren : IN STD_LOGIC ;
+ q : OUT STD_LOGIC_VECTOR (7 DOWNTO 0)
+ );
+END data_memory;
+
+
+ARCHITECTURE SYN OF data_memory IS
+
+ SIGNAL sub_wire0 : STD_LOGIC_VECTOR (7 DOWNTO 0);
+
+
+
+ COMPONENT altsyncram
+ GENERIC (
+ address_aclr_a : STRING;
+ indata_aclr_a : STRING;
+ intended_device_family : STRING;
+ lpm_hint : STRING;
+ lpm_type : STRING;
+ numwords_a : NATURAL;
+ operation_mode : STRING;
+ outdata_aclr_a : STRING;
+ outdata_reg_a : STRING;
+ power_up_uninitialized : STRING;
+ widthad_a : NATURAL;
+ width_a : NATURAL;
+ width_byteena_a : NATURAL;
+ wrcontrol_aclr_a : STRING
+ );
+ PORT (
+ clocken0 : IN STD_LOGIC ;
+ wren_a : IN STD_LOGIC ;
+ clock0 : IN STD_LOGIC ;
+ address_a : IN STD_LOGIC_VECTOR (11 DOWNTO 0);
+ q_a : OUT STD_LOGIC_VECTOR (7 DOWNTO 0);
+ data_a : IN STD_LOGIC_VECTOR (7 DOWNTO 0)
+ );
+ END COMPONENT;
+
+BEGIN
+ q <= sub_wire0(7 DOWNTO 0);
+
+ altsyncram_component : altsyncram
+ GENERIC MAP (
+ address_aclr_a => "NONE",
+ indata_aclr_a => "NONE",
+ intended_device_family => "Cyclone",
+ lpm_hint => "ENABLE_RUNTIME_MOD=NO",
+ lpm_type => "altsyncram",
+ numwords_a => 4096,
+ operation_mode => "SINGLE_PORT",
+ outdata_aclr_a => "NONE",
+ outdata_reg_a => "UNREGISTERED",
+ power_up_uninitialized => "FALSE",
+ widthad_a => 12,
+ width_a => 8,
+ width_byteena_a => 1,
+ wrcontrol_aclr_a => "NONE"
+ )
+ PORT MAP (
+ clocken0 => clken,
+ wren_a => wren,
+ clock0 => clock,
+ address_a => address,
+ data_a => data,
+ q_a => sub_wire0
+ );
+
+
+
+END SYN;
+
+-- ============================================================
+-- CNX file retrieval info
+-- ============================================================
+-- Retrieval info: PRIVATE: ADDRESSSTALL_A NUMERIC "0"
+-- Retrieval info: PRIVATE: AclrAddr NUMERIC "0"
+-- Retrieval info: PRIVATE: AclrByte NUMERIC "0"
+-- Retrieval info: PRIVATE: AclrData NUMERIC "0"
+-- Retrieval info: PRIVATE: AclrOutput NUMERIC "0"
+-- Retrieval info: PRIVATE: BYTE_ENABLE NUMERIC "0"
+-- Retrieval info: PRIVATE: BYTE_SIZE NUMERIC "8"
+-- Retrieval info: PRIVATE: BlankMemory NUMERIC "1"
+-- Retrieval info: PRIVATE: CLOCK_ENABLE_INPUT_A NUMERIC "1"
+-- Retrieval info: PRIVATE: CLOCK_ENABLE_OUTPUT_A NUMERIC "0"
+-- Retrieval info: PRIVATE: Clken NUMERIC "1"
+-- Retrieval info: PRIVATE: DataBusSeparated NUMERIC "1"
+-- Retrieval info: PRIVATE: IMPLEMENT_IN_LES NUMERIC "0"
+-- Retrieval info: PRIVATE: INIT_FILE_LAYOUT STRING "PORT_A"
+-- Retrieval info: PRIVATE: INIT_TO_SIM_X NUMERIC "0"
+-- Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "Cyclone"
+-- Retrieval info: PRIVATE: JTAG_ENABLED NUMERIC "0"
+-- Retrieval info: PRIVATE: JTAG_ID STRING "NONE"
+-- Retrieval info: PRIVATE: MAXIMUM_DEPTH NUMERIC "0"
+-- Retrieval info: PRIVATE: MIFfilename STRING ""
+-- Retrieval info: PRIVATE: NUMWORDS_A NUMERIC "4096"
+-- Retrieval info: PRIVATE: RAM_BLOCK_TYPE NUMERIC "0"
+-- Retrieval info: PRIVATE: RegAddr NUMERIC "1"
+-- Retrieval info: PRIVATE: RegData NUMERIC "1"
+-- Retrieval info: PRIVATE: RegOutput NUMERIC "0"
+-- Retrieval info: PRIVATE: SingleClock NUMERIC "1"
+-- Retrieval info: PRIVATE: UseDQRAM NUMERIC "1"
+-- Retrieval info: PRIVATE: WRCONTROL_ACLR_A NUMERIC "0"
+-- Retrieval info: PRIVATE: WidthAddr NUMERIC "12"
+-- Retrieval info: PRIVATE: WidthData NUMERIC "8"
+-- Retrieval info: CONSTANT: ADDRESS_ACLR_A STRING "NONE"
+-- Retrieval info: CONSTANT: INDATA_ACLR_A STRING "NONE"
+-- Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone"
+-- Retrieval info: CONSTANT: LPM_HINT STRING "ENABLE_RUNTIME_MOD=NO"
+-- Retrieval info: CONSTANT: LPM_TYPE STRING "altsyncram"
+-- Retrieval info: CONSTANT: NUMWORDS_A NUMERIC "4096"
+-- Retrieval info: CONSTANT: OPERATION_MODE STRING "SINGLE_PORT"
+-- Retrieval info: CONSTANT: OUTDATA_ACLR_A STRING "NONE"
+-- Retrieval info: CONSTANT: OUTDATA_REG_A STRING "UNREGISTERED"
+-- Retrieval info: CONSTANT: POWER_UP_UNINITIALIZED STRING "FALSE"
+-- Retrieval info: CONSTANT: WIDTHAD_A NUMERIC "12"
+-- Retrieval info: CONSTANT: WIDTH_A NUMERIC "8"
+-- Retrieval info: CONSTANT: WIDTH_BYTEENA_A NUMERIC "1"
+-- Retrieval info: CONSTANT: WRCONTROL_ACLR_A STRING "NONE"
+-- Retrieval info: USED_PORT: address 0 0 12 0 INPUT NODEFVAL address[11..0]
+-- Retrieval info: USED_PORT: clken 0 0 0 0 INPUT NODEFVAL clken
+-- Retrieval info: USED_PORT: clock 0 0 0 0 INPUT NODEFVAL clock
+-- Retrieval info: USED_PORT: data 0 0 8 0 INPUT NODEFVAL data[7..0]
+-- Retrieval info: USED_PORT: q 0 0 8 0 OUTPUT NODEFVAL q[7..0]
+-- Retrieval info: USED_PORT: wren 0 0 0 0 INPUT NODEFVAL wren
+-- Retrieval info: CONNECT: @address_a 0 0 12 0 address 0 0 12 0
+-- Retrieval info: CONNECT: q 0 0 8 0 @q_a 0 0 8 0
+-- Retrieval info: CONNECT: @clock0 0 0 0 0 clock 0 0 0 0
+-- Retrieval info: CONNECT: @clocken0 0 0 0 0 clken 0 0 0 0
+-- Retrieval info: CONNECT: @data_a 0 0 8 0 data 0 0 8 0
+-- Retrieval info: CONNECT: @wren_a 0 0 0 0 wren 0 0 0 0
+-- Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all
+-- Retrieval info: GEN_FILE: TYPE_NORMAL data_memory.vhd TRUE
+-- Retrieval info: GEN_FILE: TYPE_NORMAL data_memory.inc FALSE
+-- Retrieval info: GEN_FILE: TYPE_NORMAL data_memory.cmp FALSE
+-- Retrieval info: GEN_FILE: TYPE_NORMAL data_memory.bsf TRUE FALSE
+-- Retrieval info: GEN_FILE: TYPE_NORMAL data_memory_inst.vhd FALSE
Index: trunk/vhdl/code_memory.vhd
===================================================================
--- trunk/vhdl/code_memory.vhd (nonexistent)
+++ trunk/vhdl/code_memory.vhd (revision 2)
@@ -0,0 +1,166 @@
+-- megafunction wizard: %ROM: 1-PORT%
+-- GENERATION: STANDARD
+-- VERSION: WM1.0
+-- MODULE: altsyncram
+
+-- ============================================================
+-- File Name: code_memory.vhd
+-- Megafunction Name(s):
+-- altsyncram
+-- ============================================================
+-- ************************************************************
+-- THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE!
+--
+-- 6.0 Build 202 06/20/2006 SP 1 SJ Web Edition
+-- ************************************************************
+
+
+--Copyright (C) 1991-2006 Altera Corporation
+--Your use of Altera Corporation's design tools, logic functions
+--and other software and tools, and its AMPP partner logic
+--functions, and any output files any of the foregoing
+--(including device programming or simulation files), and any
+--associated documentation or information are expressly subject
+--to the terms and conditions of the Altera Program License
+--Subscription Agreement, Altera MegaCore Function License
+--Agreement, or other applicable license agreement, including,
+--without limitation, that your use is for the sole purpose of
+--programming logic devices manufactured by Altera and sold by
+--Altera or its authorized distributors. Please refer to the
+--applicable agreement for further details.
+
+
+LIBRARY ieee;
+USE ieee.std_logic_1164.all;
+
+LIBRARY altera_mf;
+USE altera_mf.all;
+
+ENTITY code_memory IS
+ GENERIC
+ (
+ init_file : STRING
+ );
+ PORT
+ (
+ address : IN STD_LOGIC_VECTOR (12 DOWNTO 0);
+ clken : IN STD_LOGIC ;
+ clock : IN STD_LOGIC ;
+ q : OUT STD_LOGIC_VECTOR (15 DOWNTO 0)
+ );
+END code_memory;
+
+
+ARCHITECTURE SYN OF code_memory IS
+
+ SIGNAL sub_wire0 : STD_LOGIC_VECTOR (15 DOWNTO 0);
+
+
+
+ COMPONENT altsyncram
+ GENERIC (
+ address_aclr_a : STRING;
+ init_file : STRING;
+ intended_device_family : STRING;
+ lpm_hint : STRING;
+ lpm_type : STRING;
+ numwords_a : NATURAL;
+ operation_mode : STRING;
+ outdata_aclr_a : STRING;
+ outdata_reg_a : STRING;
+ widthad_a : NATURAL;
+ width_a : NATURAL;
+ width_byteena_a : NATURAL
+ );
+ PORT (
+ clocken0 : IN STD_LOGIC ;
+ clock0 : IN STD_LOGIC ;
+ address_a : IN STD_LOGIC_VECTOR (12 DOWNTO 0);
+ q_a : OUT STD_LOGIC_VECTOR (15 DOWNTO 0)
+ );
+ END COMPONENT;
+
+BEGIN
+ q <= sub_wire0(15 DOWNTO 0);
+
+ altsyncram_component : altsyncram
+ GENERIC MAP (
+ address_aclr_a => "NONE",
+ init_file => init_file,
+ intended_device_family => "Cyclone",
+ lpm_hint => "ENABLE_RUNTIME_MOD=NO",
+ lpm_type => "altsyncram",
+ numwords_a => 8192,
+ operation_mode => "ROM",
+ outdata_aclr_a => "NONE",
+ outdata_reg_a => "UNREGISTERED",
+ widthad_a => 13,
+ width_a => 16,
+ width_byteena_a => 1
+ )
+ PORT MAP (
+ clocken0 => clken,
+ clock0 => clock,
+ address_a => address,
+ q_a => sub_wire0
+ );
+
+
+
+END SYN;
+
+-- ============================================================
+-- CNX file retrieval info
+-- ============================================================
+-- Retrieval info: PRIVATE: ADDRESSSTALL_A NUMERIC "0"
+-- Retrieval info: PRIVATE: AclrAddr NUMERIC "0"
+-- Retrieval info: PRIVATE: AclrByte NUMERIC "0"
+-- Retrieval info: PRIVATE: AclrOutput NUMERIC "0"
+-- Retrieval info: PRIVATE: BYTE_ENABLE NUMERIC "0"
+-- Retrieval info: PRIVATE: BYTE_SIZE NUMERIC "8"
+-- Retrieval info: PRIVATE: BlankMemory NUMERIC "0"
+-- Retrieval info: PRIVATE: CLOCK_ENABLE_INPUT_A NUMERIC "1"
+-- Retrieval info: PRIVATE: CLOCK_ENABLE_OUTPUT_A NUMERIC "1"
+-- Retrieval info: PRIVATE: Clken NUMERIC "1"
+-- Retrieval info: PRIVATE: IMPLEMENT_IN_LES NUMERIC "0"
+-- Retrieval info: PRIVATE: INIT_FILE_LAYOUT STRING "PORT_A"
+-- Retrieval info: PRIVATE: INIT_TO_SIM_X NUMERIC "0"
+-- Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "Cyclone"
+-- Retrieval info: PRIVATE: JTAG_ENABLED NUMERIC "0"
+-- Retrieval info: PRIVATE: JTAG_ID STRING "NONE"
+-- Retrieval info: PRIVATE: MAXIMUM_DEPTH NUMERIC "0"
+-- Retrieval info: PRIVATE: MIFfilename STRING "src/code.mif"
+-- Retrieval info: PRIVATE: NUMWORDS_A NUMERIC "8192"
+-- Retrieval info: PRIVATE: RAM_BLOCK_TYPE NUMERIC "0"
+-- Retrieval info: PRIVATE: RegAddr NUMERIC "1"
+-- Retrieval info: PRIVATE: RegOutput NUMERIC "0"
+-- Retrieval info: PRIVATE: SingleClock NUMERIC "1"
+-- Retrieval info: PRIVATE: UseDQRAM NUMERIC "0"
+-- Retrieval info: PRIVATE: WidthAddr NUMERIC "13"
+-- Retrieval info: PRIVATE: WidthData NUMERIC "16"
+-- Retrieval info: CONSTANT: ADDRESS_ACLR_A STRING "NONE"
+-- Retrieval info: CONSTANT: INIT_FILE STRING "src/code.mif"
+-- Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone"
+-- Retrieval info: CONSTANT: LPM_HINT STRING "ENABLE_RUNTIME_MOD=NO"
+-- Retrieval info: CONSTANT: LPM_TYPE STRING "altsyncram"
+-- Retrieval info: CONSTANT: NUMWORDS_A NUMERIC "8192"
+-- Retrieval info: CONSTANT: OPERATION_MODE STRING "ROM"
+-- Retrieval info: CONSTANT: OUTDATA_ACLR_A STRING "NONE"
+-- Retrieval info: CONSTANT: OUTDATA_REG_A STRING "UNREGISTERED"
+-- Retrieval info: CONSTANT: WIDTHAD_A NUMERIC "13"
+-- Retrieval info: CONSTANT: WIDTH_A NUMERIC "16"
+-- Retrieval info: CONSTANT: WIDTH_BYTEENA_A NUMERIC "1"
+-- Retrieval info: USED_PORT: address 0 0 12 0 INPUT NODEFVAL address[12..0]
+-- Retrieval info: USED_PORT: clken 0 0 0 0 INPUT NODEFVAL clken
+-- Retrieval info: USED_PORT: clock 0 0 0 0 INPUT NODEFVAL clock
+-- Retrieval info: USED_PORT: q 0 0 16 0 OUTPUT NODEFVAL q[15..0]
+-- Retrieval info: CONNECT: @address_a 0 0 13 0 address 0 0 13 0
+-- Retrieval info: CONNECT: q 0 0 16 0 @q_a 0 0 16 0
+-- Retrieval info: CONNECT: @clock0 0 0 0 0 clock 0 0 0 0
+-- Retrieval info: CONNECT: @clocken0 0 0 0 0 clken 0 0 0 0
+-- Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all
+-- Retrieval info: GEN_FILE: TYPE_NORMAL code_memory.vhd TRUE
+-- Retrieval info: GEN_FILE: TYPE_NORMAL code_memory.inc FALSE
+-- Retrieval info: GEN_FILE: TYPE_NORMAL code_memory.cmp FALSE
+-- Retrieval info: GEN_FILE: TYPE_NORMAL code_memory.bsf TRUE
+-- Retrieval info: GEN_FILE: TYPE_NORMAL code_memory_inst.vhd FALSE
Index: trunk/vhdl/execute.vhd
===================================================================
--- trunk/vhdl/execute.vhd (nonexistent)
+++ trunk/vhdl/execute.vhd (revision 2)
@@ -0,0 +1,291 @@
+-- This file is part of the marca processor.
+-- Copyright (C) 2007 Wolfgang Puffitsch
+
+-- This program is free software; you can redistribute it and/or modify it
+-- under the terms of the GNU Library 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
+-- Library General Public License for more details.
+
+-- You should have received a copy of the GNU Library 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
+
+-------------------------------------------------------------------------------
+-- MARCA execution stage
+-------------------------------------------------------------------------------
+-- architecture of the execution pipeline stage
+-------------------------------------------------------------------------------
+
+-------------------------------------------------------------------------------
+-- Wolfgang Puffitsch
+-- Computer Architecture Lab, Group 3
+-------------------------------------------------------------------------------
+
+library IEEE;
+use IEEE.std_logic_1164.all;
+use IEEE.numeric_std.all;
+
+use work.marca_pkg.all;
+
+architecture behaviour of execute is
+
+component alu is
+ port (
+ clock : in std_logic;
+ reset : in std_logic;
+ busy : out std_logic;
+ op : in ALU_OP;
+ a : in std_logic_vector(REG_WIDTH-1 downto 0);
+ b : in std_logic_vector(REG_WIDTH-1 downto 0);
+ i : in std_logic_vector(REG_WIDTH-1 downto 0);
+ pc : in std_logic_vector(REG_WIDTH-1 downto 0);
+ intr : in std_logic;
+ exc : out std_logic;
+ iena : out std_logic;
+ pcchg : out std_logic;
+ result : out std_logic_vector(REG_WIDTH-1 downto 0));
+end component;
+
+component mem is
+ port (
+ clock : in std_logic;
+ reset : in std_logic;
+ op : in MEM_OP;
+ address : in std_logic_vector(REG_WIDTH-1 downto 0);
+ data : in std_logic_vector(REG_WIDTH-1 downto 0);
+ exc : out std_logic;
+ busy : out std_logic;
+ result : out std_logic_vector(REG_WIDTH-1 downto 0);
+ intrs : out std_logic_vector(VEC_COUNT-1 downto 3);
+ ext_in : in std_logic_vector(IN_BITS-1 downto 0);
+ ext_out : out std_logic_vector(OUT_BITS-1 downto 0));
+end component;
+
+component intr is
+ port (
+ clock : in std_logic;
+ reset : in std_logic;
+ enable : in std_logic;
+ trigger : in std_logic_vector(VEC_COUNT-1 downto 1);
+ op : in INTR_OP;
+ a : in std_logic_vector(REG_WIDTH-1 downto 0);
+ i : in std_logic_vector(REG_WIDTH-1 downto 0);
+ pc : in std_logic_vector(REG_WIDTH-1 downto 0);
+ exc : out std_logic;
+ pcchg : out std_logic;
+ result : out std_logic_vector(REG_WIDTH-1 downto 0));
+end component;
+
+signal any_busy : std_logic;
+
+signal alu_iena : std_logic;
+signal alu_exc : std_logic;
+signal alu_busy : std_logic;
+signal alu_pcchg : std_logic;
+signal alu_result : std_logic_vector(REG_WIDTH-1 downto 0);
+
+signal mem_exc : std_logic;
+signal mem_busy : std_logic;
+signal mem_result : std_logic_vector(REG_WIDTH-1 downto 0);
+signal mem_intrs : std_logic_vector(VEC_COUNT-1 downto 3);
+
+signal intr_enable : std_logic;
+signal intr_exc : std_logic;
+signal intr_pcchg : std_logic;
+signal intr_result : std_logic_vector(REG_WIDTH-1 downto 0);
+
+signal pc_reg : std_logic_vector(REG_WIDTH-1 downto 0);
+
+signal src1_reg : std_logic_vector(REG_COUNT_LOG-1 downto 0);
+signal src2_reg : std_logic_vector(REG_COUNT_LOG-1 downto 0);
+signal dest_reg : std_logic_vector(REG_COUNT_LOG-1 downto 0);
+
+signal op1_reg : std_logic_vector(REG_WIDTH-1 downto 0);
+signal op2_reg : std_logic_vector(REG_WIDTH-1 downto 0);
+signal imm_reg : std_logic_vector(REG_WIDTH-1 downto 0);
+
+signal op1_fwed : std_logic_vector(REG_WIDTH-1 downto 0);
+signal op2_fwed : std_logic_vector(REG_WIDTH-1 downto 0);
+
+signal aop_reg : ALU_OP;
+signal mop_reg : MEM_OP;
+signal iop_reg : INTR_OP;
+
+signal unit_reg : UNIT_SELECTOR;
+signal target_reg : TARGET_SELECTOR;
+
+signal stall_cnt : std_logic_vector(1 downto 0); -- prohibiting
+signal next_stall_cnt : std_logic_vector(1 downto 0); -- interrupts during reti
+
+begin -- behaviour
+
+ -- interrupts do not work while jumping
+ intr_enable <= alu_iena and zero(stall_cnt) and not any_busy;
+
+ alu_unit : alu
+ port map (
+ clock => clock,
+ reset => reset,
+ op => aop_reg,
+ a => op1_fwed,
+ b => op2_fwed,
+ i => imm_reg,
+ pc => pc_reg,
+ intr => intr_exc,
+ exc => alu_exc,
+ busy => alu_busy,
+ iena => alu_iena,
+ pcchg => alu_pcchg,
+ result => alu_result);
+
+ mem_unit : mem
+ port map (
+ clock => clock,
+ reset => reset,
+ op => mop_reg,
+ address => op2_fwed,
+ data => op1_fwed,
+ exc => mem_exc,
+ busy => mem_busy,
+ result => mem_result,
+ intrs => mem_intrs,
+ ext_in => ext_in,
+ ext_out => ext_out);
+
+ intr_unit : intr
+ port map (
+ clock => clock,
+ reset => reset,
+ enable => intr_enable,
+ trigger(EXC_ALU) => alu_exc,
+ trigger(EXC_MEM) => mem_exc,
+ trigger(VEC_COUNT-1 downto 3) => mem_intrs,
+ op => iop_reg,
+ a => op1_fwed,
+ i => imm_reg,
+ pc => pc_reg,
+ exc => intr_exc,
+ pcchg => intr_pcchg,
+ result => intr_result);
+
+ syn_proc: process (clock, reset)
+ begin -- process syn_proc
+ if reset = RESET_ACTIVE then -- asynchronous reset (active low)
+ stall_cnt <= (others => '0');
+ pc_reg <= (others => '0');
+ src1_reg <= (others => '0');
+ src2_reg <= (others => '0');
+ dest_reg <= (others => '0');
+ aop_reg <= ALU_NOP;
+ mop_reg <= MEM_NOP;
+ iop_reg <= INTR_NOP;
+ op1_reg <= (others => '0');
+ op2_reg <= (others => '0');
+ imm_reg <= (others => '0');
+ unit_reg <= UNIT_ALU;
+ target_reg <= TARGET_NONE;
+ elsif clock'event and clock = '1' then -- rising clock edge
+ if any_busy = '0' then
+ stall_cnt <= next_stall_cnt;
+ if stall = '1' then
+ pc_reg <= (others => '0');
+ src1_reg <= (others => '0');
+ src2_reg <= (others => '0');
+ dest_reg <= (others => '0');
+ aop_reg <= ALU_NOP;
+ mop_reg <= MEM_NOP;
+ iop_reg <= INTR_NOP;
+ op1_reg <= (others => '0');
+ op2_reg <= (others => '0');
+ imm_reg <= (others => '0');
+ unit_reg <= UNIT_ALU;
+ target_reg <= TARGET_NONE;
+ else
+ pc_reg <= pc_in;
+ dest_reg <= dest_in;
+ src1_reg <= src1;
+ src2_reg <= src2;
+ aop_reg <= aop;
+ mop_reg <= mop;
+ iop_reg <= iop;
+ op1_reg <= op1;
+ op2_reg <= op2;
+ imm_reg <= imm;
+ unit_reg <= unit;
+ target_reg <= target_in;
+ end if;
+ end if;
+ end if;
+ end process syn_proc;
+
+ stalling: process (stall, stall_cnt)
+ begin -- process hold_pc
+
+ next_stall_cnt <= std_logic_vector(unsigned(stall_cnt) - 1);
+ if zero(stall_cnt) = '1' then
+ next_stall_cnt <= "00";
+ end if;
+ if stall = '1' then
+ next_stall_cnt <= "11";
+ end if;
+
+ end process stalling;
+
+ business: process (any_busy, alu_busy, mem_busy)
+ begin -- process business
+ any_busy <= alu_busy or mem_busy;
+ busy <= any_busy;
+ end process business;
+
+ feedthrough: process (pc_reg, dest_reg, unit_reg, target_reg, op2_fwed, intr_exc)
+ begin -- process feedthrough
+ if unit_reg /= UNIT_CALL then
+ pc_out <= pc_reg;
+ else
+ pc_out <= op2_fwed;
+ end if;
+ dest_out <= dest_reg;
+ if intr_exc = '1' then
+ target_out <= TARGET_PC;
+ else
+ target_out <= target_reg;
+ end if;
+ end process feedthrough;
+
+ forward: process (src1_reg, src2_reg, op1_reg, op2_reg, fw_ena, fw_dest, fw_val)
+ begin -- process forward
+ op1_fwed <= op1_reg;
+ op2_fwed <= op2_reg;
+ if fw_ena = '1' then
+ if src1_reg = fw_dest then
+ op1_fwed <= fw_val;
+ end if;
+ if src2_reg = fw_dest then
+ op2_fwed <= fw_val;
+ end if;
+ end if;
+ end process forward;
+
+ select_result: process(unit_reg, alu_result, mem_result, intr_result, pc_reg,
+ alu_pcchg, intr_pcchg,
+ intr_exc)
+ begin -- process select_result
+ case unit_reg is
+ when UNIT_ALU => result <= alu_result;
+ when UNIT_MEM => result <= mem_result;
+ when UNIT_INTR => result <= intr_result;
+ when UNIT_CALL => result <= std_logic_vector(unsigned(pc_reg) + 1);
+ when others => null;
+ end case;
+ if intr_exc = '1' then
+ result <= intr_result;
+ end if;
+ pcchg <= alu_pcchg or intr_pcchg;
+ end process select_result;
+
+end behaviour;
Index: trunk/vhdl/marca.vht
===================================================================
--- trunk/vhdl/marca.vht (nonexistent)
+++ trunk/vhdl/marca.vht (revision 2)
@@ -0,0 +1,492 @@
+-- Copyright (C) 1991-2006 Altera Corporation
+-- Your use of Altera Corporation's design tools, logic functions
+-- and other software and tools, and its AMPP partner logic
+-- functions, and any output files any of the foregoing
+-- (including device programming or simulation files), and any
+-- associated documentation or information are expressly subject
+-- to the terms and conditions of the Altera Program License
+-- Subscription Agreement, Altera MegaCore Function License
+-- Agreement, or other applicable license agreement, including,
+-- without limitation, that your use is for the sole purpose of
+-- programming logic devices manufactured by Altera and sold by
+-- Altera or its authorized distributors. Please refer to the
+-- applicable agreement for further details.
+
+-- *****************************************************************************
+-- This file contains a Vhdl test bench with test vectors .The test vectors
+-- are exported from a vector file in the Quartus Waveform Editor and apply to
+-- the top level entity of the current Quartus project .The user can use this
+-- testbench to simulate his design using a third-party simulation tool .
+-- *****************************************************************************
+-- Generated on "12/14/2006 19:48:14"
+
+-- Vhdl Self-Checking Test Bench (with test vectors) for design : marca
+--
+-- Simulation tool : 3rd Party
+--
+
+LIBRARY ieee;
+USE ieee.std_logic_1164.all;
+
+LIBRARY STD;
+USE STD.textio.ALL;
+
+PACKAGE marca_vhd_tb_types IS
+-- input port types
+SUBTYPE i1_type IS STD_LOGIC;
+SUBTYPE i2_type IS STD_LOGIC_VECTOR(1 DOWNTO 0);
+SUBTYPE i3_type IS STD_LOGIC;
+-- output port types
+SUBTYPE o1_type IS STD_LOGIC_VECTOR(1 DOWNTO 0);
+-- output port names
+CONSTANT o1_name : STRING (1 TO 7) := "ext_out";
+-- n(outputs)
+CONSTANT o_num : INTEGER := 1;
+-- mismatches vector type
+TYPE mmvec IS ARRAY (0 to (o_num - 1)) OF INTEGER;
+-- exp o/ first change track vector type
+TYPE trackvec IS ARRAY (1 to o_num) OF BIT;
+-- sampler type
+SUBTYPE sample_type IS STD_LOGIC;
+-- utility functions
+FUNCTION std_logic_to_char (a: STD_LOGIC) RETURN CHARACTER;
+FUNCTION std_logic_vector_to_string (a: STD_LOGIC_VECTOR) RETURN STRING;
+PROCEDURE write (l:INOUT LINE; value:IN STD_LOGIC; justified: IN SIDE:= RIGHT; field:IN WIDTH:=0);
+PROCEDURE write (l:INOUT LINE; value:IN STD_LOGIC_VECTOR; justified: IN SIDE:= RIGHT; field:IN WIDTH:=0);
+PROCEDURE throw_error(output_port_name: IN STRING; expected_value : IN STD_LOGIC; real_value : IN STD_LOGIC);
+PROCEDURE throw_error(output_port_name: IN STRING; expected_value : IN STD_LOGIC_VECTOR; real_value : IN STD_LOGIC_VECTOR);
+
+END marca_vhd_tb_types;
+
+PACKAGE BODY marca_vhd_tb_types IS
+ FUNCTION std_logic_to_char (a: STD_LOGIC)
+ RETURN CHARACTER IS
+ BEGIN
+ CASE a IS
+ WHEN 'U' =>
+ RETURN 'U';
+ WHEN 'X' =>
+ RETURN 'X';
+ WHEN '0' =>
+ RETURN '0';
+ WHEN '1' =>
+ RETURN '1';
+ WHEN 'Z' =>
+ RETURN 'Z';
+ WHEN 'W' =>
+ RETURN 'W';
+ WHEN 'L' =>
+ RETURN 'L';
+ WHEN 'H' =>
+ RETURN 'H';
+ WHEN '-' =>
+ RETURN 'D';
+ END CASE;
+ END;
+
+ FUNCTION std_logic_vector_to_string (a: STD_LOGIC_VECTOR)
+ RETURN STRING IS
+ VARIABLE result : STRING(1 TO a'LENGTH);
+ VARIABLE j : NATURAL := 1;
+ BEGIN
+ FOR i IN a'RANGE LOOP
+ result(j) := std_logic_to_char(a(i));
+ j := j + 1;
+ END LOOP;
+ RETURN result;
+ END;
+
+ PROCEDURE write (l:INOUT LINE; value:IN STD_LOGIC; justified: IN SIDE:=RIGHT; field:IN WIDTH:=0) IS
+ BEGIN
+ write(L,std_logic_to_char(VALUE),JUSTIFIED,field);
+ END;
+
+ PROCEDURE write (l:INOUT LINE; value:IN STD_LOGIC_VECTOR; justified: IN SIDE:= RIGHT; field:IN WIDTH:=0) IS
+ BEGIN
+ write(L,std_logic_vector_to_string(VALUE),JUSTIFIED,field);
+ END;
+
+ PROCEDURE throw_error(output_port_name: IN STRING; expected_value : IN STD_LOGIC; real_value : IN STD_LOGIC) IS
+ VARIABLE txt : LINE;
+ BEGIN
+ write(txt,string'("ERROR! Vector Mismatch for output port "));
+ write(txt,output_port_name);
+ write(txt,string'(" :: @time = "));
+ write(txt,NOW);
+ write(txt,string'(", Expected value = "));
+ write(txt,expected_value);
+ write(txt,string'(", Real value = "));
+ write(txt,real_value);
+ writeline(output,txt);
+ END;
+
+ PROCEDURE throw_error(output_port_name: IN STRING; expected_value : IN STD_LOGIC_VECTOR; real_value : IN STD_LOGIC_VECTOR) IS
+ VARIABLE txt : LINE;
+ BEGIN
+ write(txt,string'("ERROR! Vector Mismatch for output port "));
+ write(txt,output_port_name);
+ write(txt,string'(" :: @time = "));
+ write(txt,NOW);
+ write(txt,string'(", Expected value = "));
+ write(txt,expected_value);
+ write(txt,string'(", Real value = "));
+ write(txt,real_value);
+ writeline(output,txt);
+ END;
+
+END marca_vhd_tb_types;
+
+LIBRARY ieee;
+USE ieee.std_logic_1164.all;
+
+USE WORK.marca_vhd_tb_types.ALL;
+
+ENTITY marca_vhd_sample_tst IS
+PORT (
+ s1 : IN i1_type;
+ s2 : IN i2_type;
+ s3 : IN i3_type;
+ sampler : OUT sample_type
+ );
+END marca_vhd_sample_tst;
+
+ARCHITECTURE sample_arch OF marca_vhd_sample_tst IS
+SIGNAL clk : sample_type := '1';
+BEGIN
+t_prcs_sample : PROCESS ( s1 , s2 , s3 )
+BEGIN
+ IF (NOW > 0 ps) AND (NOW < 850000000 ps) THEN
+ clk <= NOT clk ;
+ END IF;
+END PROCESS t_prcs_sample;
+sampler <= clk;
+END sample_arch;
+
+LIBRARY ieee;
+USE ieee.std_logic_1164.all;
+
+LIBRARY STD;
+USE STD.textio.ALL;
+
+USE WORK.marca_vhd_tb_types.ALL;
+
+ENTITY marca_vhd_check_tst IS
+GENERIC (
+ debug_tbench : BIT := '0'
+);
+PORT (
+ o1 : IN o1_type;
+ sampler : IN sample_type
+);
+END marca_vhd_check_tst;
+ARCHITECTURE ovec_arch OF marca_vhd_check_tst IS
+SIGNAL t_sig_o1_expected,t_sig_o1_expected_prev,t_sig_o1_prev : o1_type;
+
+SIGNAL trigger : BIT := '0';
+SIGNAL trigger_e : BIT := '0';
+SIGNAL trigger_r : BIT := '0';
+SIGNAL trigger_i : BIT := '0';
+SIGNAL num_mismatches : mmvec := (OTHERS => 0);
+
+BEGIN
+
+-- Update history buffers expected /o
+t_prcs_update_o_expected_hist : PROCESS (trigger)
+BEGIN
+ t_sig_o1_expected_prev <= t_sig_o1_expected;
+END PROCESS t_prcs_update_o_expected_hist;
+
+
+-- Update history buffers real /o
+t_prcs_update_o_real_hist : PROCESS (trigger)
+BEGIN
+ t_sig_o1_prev <= o1;
+END PROCESS t_prcs_update_o_real_hist;
+
+
+-- expected ext_out[1]
+t_prcs_ext_out_1: PROCESS
+BEGIN
+ t_sig_o1_expected(1) <= '0';
+ WAIT FOR 93383521 ps;
+ t_sig_o1_expected(1) <= '1';
+ WAIT FOR 100000 ps;
+ t_sig_o1_expected(1) <= '0';
+ WAIT FOR 95600000 ps;
+ t_sig_o1_expected(1) <= '1';
+ WAIT FOR 100000 ps;
+ t_sig_o1_expected(1) <= '0';
+ WAIT FOR 95050000 ps;
+ t_sig_o1_expected(1) <= '1';
+ WAIT FOR 100000 ps;
+ t_sig_o1_expected(1) <= '0';
+ WAIT FOR 95600000 ps;
+ t_sig_o1_expected(1) <= '1';
+ WAIT FOR 100000 ps;
+ t_sig_o1_expected(1) <= '0';
+WAIT;
+END PROCESS t_prcs_ext_out_1;
+-- expected ext_out[0]
+t_prcs_ext_out_0: PROCESS
+BEGIN
+ t_sig_o1_expected(0) <= '1';
+ WAIT FOR 387433530 ps;
+ t_sig_o1_expected(0) <= '0';
+ WAIT FOR 8800000 ps;
+ FOR i IN 1 TO 3
+ LOOP
+ t_sig_o1_expected(0) <= '1';
+ WAIT FOR 17600000 ps;
+ t_sig_o1_expected(0) <= '0';
+ WAIT FOR 17600000 ps;
+ END LOOP;
+ t_sig_o1_expected(0) <= '1';
+ WAIT FOR 8800000 ps;
+ FOR i IN 1 TO 2
+ LOOP
+ t_sig_o1_expected(0) <= '0';
+ WAIT FOR 17600000 ps;
+ t_sig_o1_expected(0) <= '1';
+ WAIT FOR 17600000 ps;
+ END LOOP;
+ t_sig_o1_expected(0) <= '0';
+ WAIT FOR 8800000 ps;
+ t_sig_o1_expected(0) <= '1';
+ WAIT FOR 8800000 ps;
+ t_sig_o1_expected(0) <= '0';
+ WAIT FOR 26400000 ps;
+ FOR i IN 1 TO 2
+ LOOP
+ t_sig_o1_expected(0) <= '1';
+ WAIT FOR 17600000 ps;
+ t_sig_o1_expected(0) <= '0';
+ WAIT FOR 17600000 ps;
+ END LOOP;
+ t_sig_o1_expected(0) <= '1';
+ WAIT FOR 8800000 ps;
+ t_sig_o1_expected(0) <= '0';
+ WAIT FOR 8800000 ps;
+ t_sig_o1_expected(0) <= '1';
+ WAIT FOR 8800000 ps;
+ t_sig_o1_expected(0) <= '0';
+ WAIT FOR 35200000 ps;
+ t_sig_o1_expected(0) <= '1';
+WAIT;
+END PROCESS t_prcs_ext_out_0;
+
+-- Set trigger on real/expected o/ pattern changes
+
+t_prcs_trigger_e : PROCESS(t_sig_o1_expected)
+BEGIN
+ trigger_e <= NOT trigger_e;
+END PROCESS t_prcs_trigger_e;
+
+t_prcs_trigger_r : PROCESS(o1)
+BEGIN
+ trigger_r <= NOT trigger_r;
+END PROCESS t_prcs_trigger_r;
+
+
+t_prcs_selfcheck : PROCESS
+VARIABLE i : INTEGER := 1;
+VARIABLE txt : LINE;
+
+VARIABLE last_o1_exp : o1_type := (OTHERS => 'U');
+
+VARIABLE on_first_change : trackvec := "1";
+BEGIN
+
+WAIT UNTIL (sampler'LAST_VALUE = '1'OR sampler'LAST_VALUE = '0')
+ AND sampler'EVENT;
+IF (debug_tbench = '1') THEN
+ write(txt,string'("Scanning pattern "));
+ write(txt,i);
+ writeline(output,txt);
+ write(txt,string'("| expected "));write(txt,o1_name);write(txt,string'(" = "));write(txt,t_sig_o1_expected_prev);
+ writeline(output,txt);
+ write(txt,string'("| real "));write(txt,o1_name);write(txt,string'(" = "));write(txt,t_sig_o1_prev);
+ writeline(output,txt);
+ i := i + 1;
+END IF;
+IF ( t_sig_o1_expected_prev /= "XX" ) AND (t_sig_o1_expected_prev /= "UU" ) AND (t_sig_o1_prev /= t_sig_o1_expected_prev) AND (
+ (t_sig_o1_expected_prev /= last_o1_exp) OR
+ (on_first_change(1) = '1')
+ ) THEN
+ throw_error("ext_out",t_sig_o1_expected_prev,t_sig_o1_prev);
+ num_mismatches(0) <= num_mismatches(0) + 1;
+ on_first_change(1) := '0';
+ last_o1_exp := t_sig_o1_expected_prev;
+END IF;
+ trigger_i <= NOT trigger_i;
+END PROCESS t_prcs_selfcheck;
+
+
+t_prcs_trigger_res : PROCESS(trigger_e,trigger_i,trigger_r)
+BEGIN
+ trigger <= trigger_i XOR trigger_e XOR trigger_r;
+END PROCESS t_prcs_trigger_res;
+
+t_prcs_endsim : PROCESS
+VARIABLE txt : LINE;
+VARIABLE total_mismatches : INTEGER := 0;
+BEGIN
+WAIT FOR 850000000 ps;
+total_mismatches := num_mismatches(0);
+IF (total_mismatches = 0) THEN
+ write(txt,string'("Simulation passed !"));
+ writeline(output,txt);
+ELSE
+ write(txt,total_mismatches);
+ write(txt,string'(" mismatched vectors : Simulation failed !"));
+ writeline(output,txt);
+END IF;
+WAIT;
+END PROCESS t_prcs_endsim;
+
+END ovec_arch;
+
+LIBRARY ieee;
+USE ieee.std_logic_1164.all;
+
+LIBRARY STD;
+USE STD.textio.ALL;
+
+USE WORK.marca_vhd_tb_types.ALL;
+
+ENTITY marca_vhd_vec_tst IS
+END marca_vhd_vec_tst;
+ARCHITECTURE marca_arch OF marca_vhd_vec_tst IS
+-- constants
+-- signals
+SIGNAL t_sig_clock : STD_LOGIC;
+SIGNAL t_sig_ext_in : STD_LOGIC_VECTOR(1 DOWNTO 0);
+SIGNAL t_sig_ext_out : STD_LOGIC_VECTOR(1 DOWNTO 0);
+SIGNAL t_sig_ext_reset : STD_LOGIC;
+SIGNAL t_sig_sampler : sample_type;
+
+COMPONENT marca
+ PORT (
+ clock : IN STD_LOGIC;
+ ext_in : IN STD_LOGIC_VECTOR(1 DOWNTO 0);
+ ext_out : OUT STD_LOGIC_VECTOR(1 DOWNTO 0);
+ ext_reset : IN STD_LOGIC
+ );
+END COMPONENT;
+COMPONENT marca_vhd_check_tst
+PORT (
+ o1 : IN o1_type;
+ sampler : IN sample_type
+);
+END COMPONENT;
+COMPONENT marca_vhd_sample_tst
+PORT (
+ s1 : IN i1_type;
+ s2 : IN i2_type;
+ s3 : IN i3_type;
+ sampler : OUT sample_type
+ );
+END COMPONENT;
+BEGIN
+ i1 : marca
+ PORT MAP (
+-- list connections between master ports and signals
+ clock => t_sig_clock,
+ ext_in => t_sig_ext_in,
+ ext_out => t_sig_ext_out,
+ ext_reset => t_sig_ext_reset
+ );
+
+-- clock
+t_prcs_clock: PROCESS
+BEGIN
+LOOP
+ t_sig_clock <= '0';
+ WAIT FOR 25000 ps;
+ t_sig_clock <= '1';
+ WAIT FOR 25000 ps;
+ IF (NOW >= 850000000 ps) THEN WAIT; END IF;
+END LOOP;
+END PROCESS t_prcs_clock;
+
+-- ext_reset
+t_prcs_ext_reset: PROCESS
+BEGIN
+ t_sig_ext_reset <= '0';
+ WAIT FOR 100000 ps;
+ t_sig_ext_reset <= '1';
+WAIT;
+END PROCESS t_prcs_ext_reset;
+-- ext_in[1]
+t_prcs_ext_in_1: PROCESS
+BEGIN
+ t_sig_ext_in(1) <= '0';
+WAIT;
+END PROCESS t_prcs_ext_in_1;
+-- ext_in[0]
+t_prcs_ext_in_0: PROCESS
+BEGIN
+ t_sig_ext_in(0) <= '1';
+ WAIT FOR 8680000 ps;
+ t_sig_ext_in(0) <= '0';
+ WAIT FOR 8680000 ps;
+ t_sig_ext_in(0) <= '1';
+ WAIT FOR 8680000 ps;
+ t_sig_ext_in(0) <= '0';
+ WAIT FOR 26040000 ps;
+ t_sig_ext_in(0) <= '1';
+ WAIT FOR 17360000 ps;
+ t_sig_ext_in(0) <= '0';
+ WAIT FOR 17360000 ps;
+ t_sig_ext_in(0) <= '1';
+ WAIT FOR 17360000 ps;
+ t_sig_ext_in(0) <= '0';
+ WAIT FOR 17360000 ps;
+ t_sig_ext_in(0) <= '1';
+ WAIT FOR 8680000 ps;
+ t_sig_ext_in(0) <= '0';
+ WAIT FOR 17360000 ps;
+ t_sig_ext_in(0) <= '1';
+ WAIT FOR 17360000 ps;
+ t_sig_ext_in(0) <= '0';
+ WAIT FOR 17360000 ps;
+ t_sig_ext_in(0) <= '1';
+ WAIT FOR 17360000 ps;
+ t_sig_ext_in(0) <= '0';
+ WAIT FOR 8680000 ps;
+ t_sig_ext_in(0) <= '1';
+ WAIT FOR 17360000 ps;
+ t_sig_ext_in(0) <= '0';
+ WAIT FOR 17360000 ps;
+ t_sig_ext_in(0) <= '1';
+ WAIT FOR 17360000 ps;
+ t_sig_ext_in(0) <= '0';
+ WAIT FOR 17360000 ps;
+ t_sig_ext_in(0) <= '1';
+ WAIT FOR 17360000 ps;
+ t_sig_ext_in(0) <= '0';
+ WAIT FOR 17360000 ps;
+ t_sig_ext_in(0) <= '1';
+ WAIT FOR 8680000 ps;
+ t_sig_ext_in(0) <= '0';
+ WAIT FOR 8680000 ps;
+ t_sig_ext_in(0) <= '1';
+ WAIT FOR 8680000 ps;
+ t_sig_ext_in(0) <= '0';
+ WAIT FOR 34720000 ps;
+ t_sig_ext_in(0) <= '1';
+WAIT;
+END PROCESS t_prcs_ext_in_0;
+tb_sample : marca_vhd_sample_tst
+PORT MAP (
+ s1 => t_sig_clock,
+ s2 => t_sig_ext_in,
+ s3 => t_sig_ext_reset,
+ sampler => t_sig_sampler
+ );
+
+tb_out : marca_vhd_check_tst
+PORT MAP (
+ o1 => t_sig_ext_out,
+ sampler => t_sig_sampler
+ );
+END marca_arch;
Index: trunk/vhdl/code.mif
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: trunk/vhdl/code.mif
===================================================================
--- trunk/vhdl/code.mif (nonexistent)
+++ trunk/vhdl/code.mif (revision 2)
trunk/vhdl/code.mif
Property changes :
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: trunk/vhdl/sc_pkg.vhd
===================================================================
--- trunk/vhdl/sc_pkg.vhd (nonexistent)
+++ trunk/vhdl/sc_pkg.vhd (revision 2)
@@ -0,0 +1,91 @@
+-- This file is part of the marca processor.
+-- Copyright (C) 2007 Wolfgang Puffitsch
+
+-- This program is free software; you can redistribute it and/or modify it
+-- under the terms of the GNU Library 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
+-- Library General Public License for more details.
+
+-- You should have received a copy of the GNU Library 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
+
+-------------------------------------------------------------------------------
+-- Package SC
+-------------------------------------------------------------------------------
+-- definitions for the SimpCon interface
+-------------------------------------------------------------------------------
+
+-------------------------------------------------------------------------------
+-- Wolfgang Puffitsch
+-- Computer Architecture Lab, Group 3
+-------------------------------------------------------------------------------
+
+library IEEE;
+use IEEE.std_logic_1164.all;
+use IEEE.numeric_std.all;
+
+use work.marca_pkg.all;
+
+package sc_pkg is
+
+ -----------------------------------------------------------------------------
+ -- general configuration
+ -----------------------------------------------------------------------------
+ constant SC_ADDR_WIDTH : integer := 2;
+ constant SC_REG_WIDTH : integer := 16;
+
+ -----------------------------------------------------------------------------
+ -- where to access SimCon modules
+ -----------------------------------------------------------------------------
+ constant SC_MIN_ADDR : std_logic_vector := "1111111111111000";
+ constant SC_MAX_ADDR : std_logic_vector := "1111111111111111";
+
+ -----------------------------------------------------------------------------
+ -- records for simpler interfacing
+ -----------------------------------------------------------------------------
+ type SC_IN is record
+ address : std_logic_vector(SC_ADDR_WIDTH-1 downto 0);
+ wr : std_logic;
+ wr_data : std_logic_vector(SC_REG_WIDTH-1 downto 0);
+ rd : std_logic;
+ end record;
+
+ constant SC_IN_NULL : SC_IN := ((others => '0'), '0', (others => '0'), '0');
+
+ type SC_OUT is record
+ rd_data : std_logic_vector(SC_REG_WIDTH-1 downto 0);
+ rdy_cnt : unsigned(1 downto 0);
+ end record;
+
+ constant SC_OUT_NULL : SC_OUT := ((others => '0'), "00");
+
+ -----------------------------------------------------------------------------
+ -- output bits
+ -----------------------------------------------------------------------------
+ constant UART_TXD : integer := 0;
+ constant UART_NRTS : integer := 1;
+
+ -----------------------------------------------------------------------------
+ -- input bits
+ -----------------------------------------------------------------------------
+ constant UART_RXD : integer := 0;
+ constant UART_NCTS : integer := 1;
+
+ -----------------------------------------------------------------------------
+ -- interrupt numbers, >= 3
+ -----------------------------------------------------------------------------
+ constant UART_INTR : integer := 3;
+
+ -----------------------------------------------------------------------------
+ -- UART configuration
+ -----------------------------------------------------------------------------
+ constant UART_BASE_ADDR : std_logic_vector(REG_WIDTH-1 downto SC_ADDR_WIDTH+1) := "1111111111111";
+ constant UART_BAUD_RATE : integer := 115200;
+
+end sc_pkg;
Index: trunk/vhdl/execute_ent.vhd
===================================================================
--- trunk/vhdl/execute_ent.vhd (nonexistent)
+++ trunk/vhdl/execute_ent.vhd (revision 2)
@@ -0,0 +1,74 @@
+-- This file is part of the marca processor.
+-- Copyright (C) 2007 Wolfgang Puffitsch
+
+-- This program is free software; you can redistribute it and/or modify it
+-- under the terms of the GNU Library 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
+-- Library General Public License for more details.
+
+-- You should have received a copy of the GNU Library 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
+
+-------------------------------------------------------------------------------
+-- MARCA execution stage
+-------------------------------------------------------------------------------
+-- entity for the execution pipeline stage
+-------------------------------------------------------------------------------
+
+-------------------------------------------------------------------------------
+-- Wolfgang Puffitsch
+-- Computer Architecture Lab, Group 3
+-------------------------------------------------------------------------------
+
+library IEEE;
+use IEEE.std_logic_1164.all;
+
+use work.marca_pkg.all;
+
+entity execute is
+
+ port (
+ clock : in std_logic;
+ reset : in std_logic;
+
+ busy : out std_logic;
+ stall : in std_logic;
+
+ pc_in : in std_logic_vector(REG_WIDTH-1 downto 0);
+ pcchg : out std_logic;
+ pc_out : out std_logic_vector(REG_WIDTH-1 downto 0);
+
+ dest_in : in std_logic_vector(REG_COUNT_LOG-1 downto 0);
+ dest_out : out std_logic_vector(REG_COUNT_LOG-1 downto 0);
+
+ src1 : in std_logic_vector(REG_COUNT_LOG-1 downto 0);
+ src2 : in std_logic_vector(REG_COUNT_LOG-1 downto 0);
+
+ aop : in ALU_OP;
+ mop : in MEM_OP;
+ iop : in INTR_OP;
+
+ op1 : in std_logic_vector(REG_WIDTH-1 downto 0);
+ op2 : in std_logic_vector(REG_WIDTH-1 downto 0);
+ imm : in std_logic_vector(REG_WIDTH-1 downto 0);
+
+ unit : in UNIT_SELECTOR;
+ target_in : in TARGET_SELECTOR;
+ target_out : out TARGET_SELECTOR;
+
+ result : out std_logic_vector(REG_WIDTH-1 downto 0);
+
+ fw_ena : in std_logic;
+ fw_dest : in std_logic_vector(REG_COUNT_LOG-1 downto 0);
+ fw_val : in std_logic_vector(REG_WIDTH-1 downto 0);
+
+ ext_in : in std_logic_vector(IN_BITS-1 downto 0);
+ ext_out : out std_logic_vector(OUT_BITS-1 downto 0));
+
+end execute;
Index: trunk/vhdl/writeback.vhd
===================================================================
--- trunk/vhdl/writeback.vhd (nonexistent)
+++ trunk/vhdl/writeback.vhd (revision 2)
@@ -0,0 +1,93 @@
+-- This file is part of the marca processor.
+-- Copyright (C) 2007 Wolfgang Puffitsch
+
+-- This program is free software; you can redistribute it and/or modify it
+-- under the terms of the GNU Library 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
+-- Library General Public License for more details.
+
+-- You should have received a copy of the GNU Library 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
+
+-------------------------------------------------------------------------------
+-- MARCA write-back stage
+-------------------------------------------------------------------------------
+-- architecture of the write-back pipeline stage
+-------------------------------------------------------------------------------
+
+-------------------------------------------------------------------------------
+-- Wolfgang Puffitsch
+-- Computer Architecture Lab, Group 3
+-------------------------------------------------------------------------------
+
+library IEEE;
+use IEEE.std_logic_1164.all;
+
+use work.marca_pkg.all;
+
+architecture behaviour of writeback is
+
+signal pcchg_reg : std_logic;
+signal pc_reg : std_logic_vector(REG_WIDTH-1 downto 0);
+signal dest_reg : std_logic_vector(REG_COUNT_LOG-1 downto 0);
+signal result_reg : std_logic_vector(REG_WIDTH-1 downto 0);
+signal target_reg : TARGET_SELECTOR;
+
+begin -- behaviour
+
+ syn_proc: process (clock, reset)
+ begin -- process syn_proc
+ if reset = RESET_ACTIVE then -- asynchronous reset (active low)
+ pcchg_reg <= '0';
+ pc_reg <= (others => '0');
+ dest_reg <= (others => '0');
+ result_reg <= (others => '0');
+ target_reg <= TARGET_NONE;
+ elsif clock'event and clock = '1' then -- rising clock edge
+ if hold = '0' then
+ pcchg_reg <= pcchg;
+ pc_reg <= pc_in;
+ dest_reg <= dest_in;
+ target_reg <= target;
+ result_reg <= result;
+ end if;
+ end if;
+ end process syn_proc;
+
+ dispatch: process (target_reg, pcchg_reg, pc_reg, result_reg, dest_reg)
+ begin -- process dispatch
+
+ pcena <= '0';
+ pc_out <= pc_reg;
+
+ ena <= '0';
+ dest_out <= dest_reg;
+ val <= result_reg;
+
+ case target_reg is
+
+ when TARGET_REGISTER =>
+ ena <= '1';
+
+ when TARGET_PC =>
+ if pcchg_reg = '1' then
+ pcena <= '1';
+ pc_out <= result_reg;
+ end if;
+
+ when TARGET_BOTH =>
+ pcena <= '1';
+ ena <= '1';
+
+ when others => null;
+ end case;
+
+ end process dispatch;
+
+end behaviour;
Index: trunk/vhdl/intr.vhd
===================================================================
--- trunk/vhdl/intr.vhd (nonexistent)
+++ trunk/vhdl/intr.vhd (revision 2)
@@ -0,0 +1,105 @@
+-- This file is part of the marca processor.
+-- Copyright (C) 2007 Wolfgang Puffitsch
+
+-- This program is free software; you can redistribute it and/or modify it
+-- under the terms of the GNU Library 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
+-- Library General Public License for more details.
+
+-- You should have received a copy of the GNU Library 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
+
+-------------------------------------------------------------------------------
+-- MARCA interrupt unit
+-------------------------------------------------------------------------------
+-- architecture for the interrupt unit
+-------------------------------------------------------------------------------
+
+-------------------------------------------------------------------------------
+-- Wolfgang Puffitsch
+-- Computer Architecture Lab, Group 3
+-------------------------------------------------------------------------------
+
+library IEEE;
+use IEEE.std_logic_1164.all;
+use IEEE.numeric_std.all;
+
+use work.marca_pkg.all;
+
+architecture behaviour of intr is
+
+type vectors is array (VEC_COUNT-1 downto 0) of std_logic_vector(REG_WIDTH-1 downto 0);
+signal vecs, next_vecs : vectors;
+
+signal ira, next_ira : std_logic_vector(REG_WIDTH-1 downto 0);
+
+begin -- behaviour
+
+ syn_proc: process (clock, reset)
+ begin -- process syn_proc
+ if reset = RESET_ACTIVE then -- asynchronous reset (active low)
+ vecs <= (others => (others => '0'));
+ ira <= (others => '0');
+ elsif clock'event and clock = '1' then -- rising clock edge
+ vecs <= next_vecs;
+ ira <= next_ira;
+ end if;
+ end process syn_proc;
+
+ compute: process (op, a, i, pc, vecs, ira, enable, trigger)
+ begin -- process compute
+
+ next_vecs <= vecs;
+ next_ira <= ira;
+
+ exc <= '0';
+ pcchg <= '0';
+ result <= (others => '0');
+
+ case op is
+ when INTR_INTR =>
+ if enable = '1' then
+ pcchg <= '1';
+ result <= vecs(to_integer(unsigned(i)));
+ next_ira <= std_logic_vector(unsigned(pc) + 1);
+ end if;
+ when INTR_RETI =>
+ pcchg <= '1';
+ result <= ira;
+ when INTR_SETIRA =>
+ next_ira <= a;
+ when INTR_GETIRA =>
+ result <= ira;
+ when INTR_STVEC =>
+ next_vecs(to_integer(unsigned(i))) <= a;
+ when INTR_LDVEC =>
+ result <= vecs(to_integer(unsigned(i)));
+ when others => null;
+ end case;
+
+ if enable = '1' then
+ for v in VEC_COUNT-1 downto 1 loop
+ if trigger(v) = '1' then
+ exc <= '1';
+ pcchg <= '1';
+ result <= vecs(v);
+ if v = EXC_ALU or v = EXC_MEM then
+ -- don't repeat division by zero and ill memory access
+ next_ira <= std_logic_vector(unsigned(pc) + 1);
+ else
+ -- repeat the instruction if interrupted
+ next_ira <= pc;
+ end if;
+ end if;
+ end loop;
+ end if;
+
+ end process compute;
+
+end behaviour;
Index: trunk/vhdl/mem.vhd
===================================================================
--- trunk/vhdl/mem.vhd (nonexistent)
+++ trunk/vhdl/mem.vhd (revision 2)
@@ -0,0 +1,485 @@
+-- This file is part of the marca processor.
+-- Copyright (C) 2007 Wolfgang Puffitsch
+
+-- This program is free software; you can redistribute it and/or modify it
+-- under the terms of the GNU Library 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
+-- Library General Public License for more details.
+
+-- You should have received a copy of the GNU Library 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
+
+-------------------------------------------------------------------------------
+-- MARCA fetch stage
+-------------------------------------------------------------------------------
+-- architecture for the instruction-fetch pipeline stage
+-------------------------------------------------------------------------------
+
+-------------------------------------------------------------------------------
+-- Wolfgang Puffitsch
+-- Computer Architecture Lab, Group 3
+-------------------------------------------------------------------------------
+
+library IEEE;
+use IEEE.std_logic_1164.all;
+use IEEE.numeric_std.all;
+
+use work.marca_pkg.all;
+use work.sc_pkg.all;
+
+architecture behaviour of mem is
+
+type WAIT_STATE is (WAIT_LOAD_EVEN, WAIT_LOAD_ODD,
+ WAIT_LOADL_EVEN, WAIT_LOADL_ODD,
+ WAIT_LOADH_EVEN, WAIT_LOADH_ODD,
+ WAIT_LOADB_EVEN, WAIT_LOADB_ODD,
+ WAIT_STORE,
+ WAIT_NONE);
+
+signal state : WAIT_STATE;
+signal next_state : WAIT_STATE;
+
+signal old_data : std_logic_vector(REG_WIDTH-1 downto 0);
+signal next_data : std_logic_vector(REG_WIDTH-1 downto 0);
+
+component data_memory
+ port (
+ clken : in std_logic;
+ clock : in std_logic;
+ wren : in std_logic;
+ address : in std_logic_vector (ADDR_WIDTH-2 downto 0);
+ data : in std_logic_vector (DATA_WIDTH-1 downto 0);
+ q : out std_logic_vector (DATA_WIDTH-1 downto 0));
+end component;
+
+signal ram_enable : std_logic;
+
+signal wren0 : std_logic;
+signal a0 : std_logic_vector(ADDR_WIDTH-2 downto 0);
+signal d0 : std_logic_vector(DATA_WIDTH-1 downto 0);
+signal q0 : std_logic_vector(DATA_WIDTH-1 downto 0);
+
+signal wren1 : std_logic;
+signal a1 : std_logic_vector(ADDR_WIDTH-2 downto 0);
+signal d1 : std_logic_vector(DATA_WIDTH-1 downto 0);
+signal q1 : std_logic_vector(DATA_WIDTH-1 downto 0);
+
+component data_rom
+ generic (
+ init_file : string);
+ port (
+ clken : in std_logic;
+ clock : in std_logic;
+ address : in std_logic_vector (RADDR_WIDTH-2 downto 0);
+ q : out std_logic_vector (RDATA_WIDTH-1 downto 0));
+end component;
+
+signal rom_enable : std_logic;
+
+signal ra0 : std_logic_vector(RADDR_WIDTH-2 downto 0);
+signal rq0 : std_logic_vector(RDATA_WIDTH-1 downto 0);
+
+signal ra1 : std_logic_vector(RADDR_WIDTH-2 downto 0);
+signal rq1 : std_logic_vector(RDATA_WIDTH-1 downto 0);
+
+
+signal sc_input : SC_IN;
+signal sc_output : SC_OUT;
+
+component sc_uart
+ generic (
+ clock_freq : integer;
+ baud_rate : integer;
+ txf_depth : integer; txf_thres : integer;
+ rxf_depth : integer; rxf_thres : integer);
+ port (
+ clock : in std_logic;
+ reset : in std_logic;
+ input : in SC_IN;
+ output : out SC_OUT;
+ intr : out std_logic;
+ txd : out std_logic;
+ rxd : in std_logic;
+ nrts : out std_logic;
+ ncts : in std_logic);
+end component;
+
+signal uart_input : SC_IN;
+signal uart_output : SC_OUT;
+
+begin -- behaviour
+
+ intrs(VEC_COUNT-1 downto 4) <= (others => '0');
+
+ data_memory_0_unit : data_memory
+ port map (
+ clken => ram_enable,
+ clock => clock,
+ wren => wren0,
+ address => a0,
+ data => d0,
+ q => q0);
+
+ data_memory_1_unit : data_memory
+ port map (
+ clken => ram_enable,
+ clock => clock,
+ wren => wren1,
+ address => a1,
+ data => d1,
+ q => q1);
+
+ data_rom_0_unit : data_rom
+ generic map (
+ init_file => "../vhdl/rom0.mif")
+ port map (
+ clken => rom_enable,
+ clock => clock,
+ address => ra0,
+ q => rq0);
+
+ data_rom_1_unit : data_rom
+ generic map (
+ init_file => "../vhdl/rom1.mif")
+ port map (
+ clken => rom_enable,
+ clock => clock,
+ address => ra1,
+ q => rq1);
+
+ uart_unit : sc_uart
+ generic map (
+ clock_freq => CLOCK_FREQ,
+ baud_rate => UART_BAUD_RATE,
+ txf_depth => 2, txf_thres => 1,
+ rxf_depth => 2, rxf_thres => 1)
+ port map (
+ clock => clock,
+ reset => reset,
+ input => uart_input,
+ output => uart_output,
+ intr => intrs(UART_INTR),
+ txd => ext_out(UART_TXD),
+ rxd => ext_in(UART_RXD),
+ nrts => ext_out(UART_NRTS),
+ ncts => ext_in(UART_NCTS));
+
+ syn_proc: process (clock, reset)
+ begin -- process syn_proc
+ if reset = RESET_ACTIVE then -- asynchronous reset (active low)
+ state <= WAIT_NONE;
+ old_data <= (others => '0');
+ elsif clock'event and clock = '1' then -- rising clock edge
+ state <= next_state;
+ old_data <= next_data;
+ end if;
+ end process syn_proc;
+
+ business: process (next_state)
+ begin -- process business
+ if next_state /= WAIT_NONE then
+ busy <= '1';
+ else
+ busy <= '0';
+ end if;
+ end process business;
+
+ sc_mux: process (address, sc_input,
+ uart_output)
+ begin -- process sc_mux
+
+ uart_input <= SC_IN_NULL;
+ sc_output <= SC_OUT_NULL;
+
+ case address(REG_WIDTH-1 downto SC_ADDR_WIDTH+1) is
+ when UART_BASE_ADDR =>
+ uart_input <= sc_input;
+ sc_output <= uart_output;
+ when others => null;
+ end case;
+
+ end process sc_mux;
+
+ readwrite: process (state, op, address, data, old_data, q0, q1, rq0, rq1, sc_output)
+ begin -- process readwrite
+ exc <= '0';
+
+ ram_enable <= '0';
+
+ wren0 <= '0';
+ wren1 <= '0';
+
+ a0 <= (others => '0');
+ d0 <= (others => '0');
+
+ a1 <= (others => '0');
+ d1 <= (others => '0');
+
+ rom_enable <= '0';
+
+ ra0 <= (others => '0');
+ ra1 <= (others => '0');
+
+ sc_input <= SC_IN_NULL;
+
+ result <= (others => '0');
+
+ next_state <= WAIT_NONE;
+ next_data <= data;
+
+ if unsigned(address) >= unsigned(MEM_MIN_ADDR)
+ and unsigned(address) <= unsigned(MEM_MAX_ADDR) then
+
+ -- regular memory access
+ if op /= MEM_NOP then
+ ram_enable <= '1';
+ end if;
+
+ case state is
+ when WAIT_LOAD_EVEN => result(REG_WIDTH-1 downto REG_WIDTH/2) <= q1;
+ result(REG_WIDTH/2-1 downto 0) <= q0;
+ next_state <= WAIT_NONE;
+
+ when WAIT_LOAD_ODD => result(REG_WIDTH-1 downto REG_WIDTH/2) <= q0;
+ result(REG_WIDTH/2-1 downto 0) <= q1;
+ next_state <= WAIT_NONE;
+
+ when WAIT_LOADL_EVEN => result(REG_WIDTH-1 downto REG_WIDTH/2) <= old_data(REG_WIDTH-1 downto REG_WIDTH/2);
+ result(REG_WIDTH/2-1 downto 0) <= q0;
+ next_state <= WAIT_NONE;
+
+ when WAIT_LOADL_ODD => result(REG_WIDTH-1 downto REG_WIDTH/2) <= old_data(REG_WIDTH-1 downto REG_WIDTH/2);
+ result(REG_WIDTH/2-1 downto 0) <= q1;
+ next_state <= WAIT_NONE;
+
+ when WAIT_LOADH_EVEN => result(REG_WIDTH-1 downto REG_WIDTH/2) <= q0;
+ result(REG_WIDTH/2-1 downto 0) <= old_data(REG_WIDTH/2-1 downto 0);
+ next_state <= WAIT_NONE;
+
+ when WAIT_LOADH_ODD => result(REG_WIDTH-1 downto REG_WIDTH/2) <= q1;
+ result(REG_WIDTH/2-1 downto 0) <= old_data(REG_WIDTH/2-1 downto 0);
+ next_state <= WAIT_NONE;
+
+ when WAIT_LOADB_EVEN => result <= std_logic_vector(resize(signed(q0), REG_WIDTH));
+ next_state <= WAIT_NONE;
+
+ when WAIT_LOADB_ODD => result <= std_logic_vector(resize(signed(q1), REG_WIDTH));
+ next_state <= WAIT_NONE;
+
+ when WAIT_NONE =>
+ case op is
+ when MEM_LOAD => if address(0) = '0' then
+ a0 <= address(ADDR_WIDTH-1 downto 1);
+ a1 <= address(ADDR_WIDTH-1 downto 1);
+ next_state <= WAIT_LOAD_EVEN;
+ else
+ a1 <= address(ADDR_WIDTH-1 downto 1);
+ a0 <= std_logic_vector(unsigned(address(ADDR_WIDTH-1 downto 1)) + 1);
+ next_state <= WAIT_LOAD_ODD;
+ end if;
+ when MEM_LOADL => if address(0) = '0' then
+ a0 <= address(ADDR_WIDTH-1 downto 1);
+ next_state <= WAIT_LOADL_EVEN;
+ else
+ a1 <= address(ADDR_WIDTH-1 downto 1);
+ next_state <= WAIT_LOADL_ODD;
+ end if;
+ when MEM_LOADH => if address(0) = '0' then
+ a0 <= address(ADDR_WIDTH-1 downto 1);
+ next_state <= WAIT_LOADH_EVEN;
+ else
+ a1 <= address(ADDR_WIDTH-1 downto 1);
+ next_state <= WAIT_LOADH_ODD;
+ end if;
+ when MEM_LOADB => if address(0) = '0' then
+ a0 <= address(ADDR_WIDTH-1 downto 1);
+ next_state <= WAIT_LOADB_EVEN;
+ else
+ a1 <= address(ADDR_WIDTH-1 downto 1);
+ next_state <= WAIT_LOADB_ODD;
+ end if;
+ when MEM_STORE => if address(0) = '0' then
+ wren0 <= '1';
+ wren1 <= '1';
+ a0 <= address(ADDR_WIDTH-1 downto 1);
+ a1 <= address(ADDR_WIDTH-1 downto 1);
+ d0 <= data(REG_WIDTH/2-1 downto 0);
+ d1 <= data(REG_WIDTH-1 downto REG_WIDTH/2);
+ next_state <= WAIT_NONE;
+ else
+ wren0 <= '1';
+ wren1 <= '1';
+ a1 <= address(ADDR_WIDTH-1 downto 1);
+ a0 <= std_logic_vector(unsigned(address(ADDR_WIDTH-1 downto 1)) + 1);
+ d1 <= data(REG_WIDTH/2-1 downto 0);
+ d0 <= data(REG_WIDTH-1 downto REG_WIDTH/2);
+ next_state <= WAIT_NONE;
+ end if;
+ when MEM_STOREL => if address(0) = '0' then
+ wren0 <= '1';
+ a0 <= address(ADDR_WIDTH-1 downto 1);
+ d0 <= data(REG_WIDTH/2-1 downto 0);
+ next_state <= WAIT_NONE;
+ else
+ wren1 <= '1';
+ a1 <= address(ADDR_WIDTH-1 downto 1);
+ d1 <= data(REG_WIDTH/2-1 downto 0);
+ next_state <= WAIT_NONE;
+ end if;
+ when MEM_STOREH => if address(0) = '0' then
+ wren0 <= '1';
+ a0 <= address(ADDR_WIDTH-1 downto 1);
+ d0 <= data(REG_WIDTH-1 downto REG_WIDTH/2);
+ next_state <= WAIT_NONE;
+ else
+ wren1 <= '1';
+ a1 <= address(ADDR_WIDTH-1 downto 1);
+ d1 <= data(REG_WIDTH-1 downto REG_WIDTH/2);
+ next_state <= WAIT_NONE;
+ end if;
+ when MEM_NOP => next_state <= WAIT_NONE;
+ when others => null;
+ end case;
+ when others => null;
+ end case;
+
+ elsif unsigned(address) >= unsigned(ROM_MIN_ADDR)
+ and unsigned(address) <= unsigned(ROM_MAX_ADDR) then
+
+ -- accessing the ROM
+ if op /= MEM_NOP then
+ rom_enable <= '1';
+ end if;
+
+ case state is
+ when WAIT_LOAD_EVEN => result(REG_WIDTH-1 downto REG_WIDTH/2) <= rq1;
+ result(REG_WIDTH/2-1 downto 0) <= rq0;
+ next_state <= WAIT_NONE;
+
+ when WAIT_LOAD_ODD => result(REG_WIDTH-1 downto REG_WIDTH/2) <= rq0;
+ result(REG_WIDTH/2-1 downto 0) <= rq1;
+ next_state <= WAIT_NONE;
+
+ when WAIT_LOADL_EVEN => result(REG_WIDTH-1 downto REG_WIDTH/2) <= old_data(REG_WIDTH-1 downto REG_WIDTH/2);
+ result(REG_WIDTH/2-1 downto 0) <= rq0;
+ next_state <= WAIT_NONE;
+
+ when WAIT_LOADL_ODD => result(REG_WIDTH-1 downto REG_WIDTH/2) <= old_data(REG_WIDTH-1 downto REG_WIDTH/2);
+ result(REG_WIDTH/2-1 downto 0) <= rq1;
+ next_state <= WAIT_NONE;
+
+ when WAIT_LOADH_EVEN => result(REG_WIDTH-1 downto REG_WIDTH/2) <= rq0;
+ result(REG_WIDTH/2-1 downto 0) <= old_data(REG_WIDTH/2-1 downto 0);
+ next_state <= WAIT_NONE;
+
+ when WAIT_LOADH_ODD => result(REG_WIDTH-1 downto REG_WIDTH/2) <= rq1;
+ result(REG_WIDTH/2-1 downto 0) <= old_data(REG_WIDTH/2-1 downto 0);
+ next_state <= WAIT_NONE;
+
+ when WAIT_LOADB_EVEN => result <= std_logic_vector(resize(signed(rq0), REG_WIDTH));
+ next_state <= WAIT_NONE;
+
+ when WAIT_LOADB_ODD => result <= std_logic_vector(resize(signed(rq1), REG_WIDTH));
+ next_state <= WAIT_NONE;
+
+ when WAIT_NONE =>
+ case op is
+ when MEM_LOAD => if address(0) = '0' then
+ ra0 <= address(RADDR_WIDTH-1 downto 1);
+ ra1 <= address(RADDR_WIDTH-1 downto 1);
+ next_state <= WAIT_LOAD_EVEN;
+ else
+ ra1 <= address(RADDR_WIDTH-1 downto 1);
+ ra0 <= std_logic_vector(unsigned(address(RADDR_WIDTH-1 downto 1)) + 1);
+ next_state <= WAIT_LOAD_ODD;
+ end if;
+ when MEM_LOADL => if address(0) = '0' then
+ ra0 <= address(RADDR_WIDTH-1 downto 1);
+ next_state <= WAIT_LOADL_EVEN;
+ else
+ ra1 <= address(RADDR_WIDTH-1 downto 1);
+ next_state <= WAIT_LOADL_ODD;
+ end if;
+ when MEM_LOADH => if address(0) = '0' then
+ ra0 <= address(RADDR_WIDTH-1 downto 1);
+ next_state <= WAIT_LOADH_EVEN;
+ else
+ ra1 <= address(RADDR_WIDTH-1 downto 1);
+ next_state <= WAIT_LOADH_ODD;
+ end if;
+ when MEM_LOADB => if address(0) = '0' then
+ ra0 <= address(RADDR_WIDTH-1 downto 1);
+ next_state <= WAIT_LOADB_EVEN;
+ else
+ ra1 <= address(RADDR_WIDTH-1 downto 1);
+ next_state <= WAIT_LOADB_ODD;
+ end if;
+ when MEM_NOP => next_state <= WAIT_NONE;
+ when others => exc <= '1'; -- inhibit invalid operations
+ end case;
+ when others => null;
+ end case;
+
+ elsif unsigned(address) >= unsigned(SC_MIN_ADDR)
+ and unsigned(address) <= unsigned(SC_MAX_ADDR)
+ and address(0) = '0' then
+
+ -- access via SimpCon interface
+ case state is
+
+ when WAIT_LOAD_EVEN =>
+ if sc_output.rdy_cnt /= "00" then
+ next_state <= WAIT_LOAD_EVEN;
+ else
+ result <= sc_output.rd_data;
+ next_state <= WAIT_NONE;
+ end if;
+
+ when WAIT_STORE =>
+ if sc_output.rdy_cnt /= "00" then
+ next_state <= WAIT_STORE;
+ else
+ next_state <= WAIT_NONE;
+ end if;
+
+ when WAIT_NONE =>
+ case op is
+
+ when MEM_LOAD =>
+ sc_input.address <= address(SC_ADDR_WIDTH downto 1);
+ sc_input.wr <= '0';
+ sc_input.wr_data <= (others => '0');
+ sc_input.rd <= '1';
+ next_state <= WAIT_LOAD_EVEN;
+
+ when MEM_STORE =>
+ sc_input.address <= address(SC_ADDR_WIDTH downto 1);
+ sc_input.wr <= '1';
+ sc_input.wr_data <= data;
+ sc_input.rd <= '0';
+ next_state <= WAIT_STORE;
+
+ when MEM_NOP => next_state <= WAIT_NONE;
+
+ when others => exc <= '1'; -- inhibit invalid operations
+
+ end case;
+ when others => null;
+ end case;
+
+ else
+ -- invalid address and/or alignment
+ if op /= MEM_NOP then
+ exc <= '1';
+ end if;
+ end if;
+
+ end process readwrite;
+
+end behaviour;
Index: trunk/vhdl/data_rom.bsf
===================================================================
--- trunk/vhdl/data_rom.bsf (nonexistent)
+++ trunk/vhdl/data_rom.bsf (revision 2)
@@ -0,0 +1,74 @@
+/*
+WARNING: Do NOT edit the input and output ports in this file in a text
+editor if you plan to continue editing the block that represents it in
+the Block Editor! File corruption is VERY likely to occur.
+*/
+/*
+Copyright (C) 1991-2006 Altera Corporation
+Your use of Altera Corporation's design tools, logic functions
+and other software and tools, and its AMPP partner logic
+functions, and any output files any of the foregoing
+(including device programming or simulation files), and any
+associated documentation or information are expressly subject
+to the terms and conditions of the Altera Program License
+Subscription Agreement, Altera MegaCore Function License
+Agreement, or other applicable license agreement, including,
+without limitation, that your use is for the sole purpose of
+programming logic devices manufactured by Altera and sold by
+Altera or its authorized distributors. Please refer to the
+applicable agreement for further details.
+*/
+(header "symbol" (version "1.1"))
+(symbol
+ (rect 0 0 216 152)
+ (text "data_rom" (rect 81 1 144 17)(font "Arial" (font_size 10)))
+ (text "inst" (rect 8 136 25 148)(font "Arial" ))
+ (port
+ (pt 0 32)
+ (input)
+ (text "address[6..0]" (rect 0 0 75 14)(font "Arial" (font_size 8)))
+ (text "address[6..0]" (rect 4 19 63 32)(font "Arial" (font_size 8)))
+ (line (pt 0 32)(pt 88 32)(line_width 3))
+ )
+ (port
+ (pt 0 112)
+ (input)
+ (text "clock" (rect 0 0 29 14)(font "Arial" (font_size 8)))
+ (text "clock" (rect 4 99 29 112)(font "Arial" (font_size 8)))
+ (line (pt 0 112)(pt 80 112)(line_width 1))
+ )
+ (port
+ (pt 0 128)
+ (input)
+ (text "clken" (rect 0 0 29 14)(font "Arial" (font_size 8)))
+ (text "clken" (rect 4 115 29 128)(font "Arial" (font_size 8)))
+ (line (pt 0 128)(pt 16 128)(line_width 1))
+ )
+ (port
+ (pt 216 32)
+ (output)
+ (text "q[7..0]" (rect 0 0 35 14)(font "Arial" (font_size 8)))
+ (text "q[7..0]" (rect 183 19 213 32)(font "Arial" (font_size 8)))
+ (line (pt 216 32)(pt 136 32)(line_width 3))
+ )
+ (drawing
+ (text "8 bits" (rect 108 48 120 71)(font "Arial" )(vertical))
+ (text "128 words" (rect 121 39 133 81)(font "Arial" )(vertical))
+ (text "Block type: AUTO" (rect 41 132 117 144)(font "Arial" ))
+ (line (pt 104 24)(pt 136 24)(line_width 1))
+ (line (pt 136 24)(pt 136 96)(line_width 1))
+ (line (pt 136 96)(pt 104 96)(line_width 1))
+ (line (pt 104 96)(pt 104 24)(line_width 1))
+ (line (pt 118 58)(pt 123 63)(line_width 1))
+ (line (pt 118 62)(pt 123 57)(line_width 1))
+ (line (pt 88 27)(pt 96 27)(line_width 1))
+ (line (pt 96 27)(pt 96 39)(line_width 1))
+ (line (pt 96 39)(pt 88 39)(line_width 1))
+ (line (pt 88 39)(pt 88 27)(line_width 1))
+ (line (pt 88 34)(pt 90 36)(line_width 1))
+ (line (pt 90 36)(pt 88 38)(line_width 1))
+ (line (pt 80 36)(pt 88 36)(line_width 1))
+ (line (pt 96 32)(pt 104 32)(line_width 3))
+ (line (pt 80 112)(pt 80 36)(line_width 1))
+ )
+)
Index: trunk/vhdl/writeback_ent.vhd
===================================================================
--- trunk/vhdl/writeback_ent.vhd (nonexistent)
+++ trunk/vhdl/writeback_ent.vhd (revision 2)
@@ -0,0 +1,58 @@
+-- This file is part of the marca processor.
+-- Copyright (C) 2007 Wolfgang Puffitsch
+
+-- This program is free software; you can redistribute it and/or modify it
+-- under the terms of the GNU Library 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
+-- Library General Public License for more details.
+
+-- You should have received a copy of the GNU Library 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
+
+-------------------------------------------------------------------------------
+-- MARCA write-back stage
+-------------------------------------------------------------------------------
+-- entity for the write-back pipeline stage
+-------------------------------------------------------------------------------
+
+-------------------------------------------------------------------------------
+-- Wolfgang Puffitsch
+-- Computer Architecture Lab, Group 3
+-------------------------------------------------------------------------------
+
+library IEEE;
+use IEEE.std_logic_1164.all;
+
+use work.marca_pkg.all;
+
+entity writeback is
+
+ port (
+ clock : in std_logic;
+ reset : in std_logic;
+
+ hold : in std_logic;
+
+ pc_in : in std_logic_vector(REG_WIDTH-1 downto 0);
+ pcchg : in std_logic;
+ pc_out : out std_logic_vector(REG_WIDTH-1 downto 0);
+
+ pcena : out std_logic;
+
+ dest_in : in std_logic_vector(REG_COUNT_LOG-1 downto 0);
+ dest_out : out std_logic_vector(REG_COUNT_LOG-1 downto 0);
+
+ target : in TARGET_SELECTOR;
+ result : in std_logic_vector(REG_WIDTH-1 downto 0);
+
+ ena : out std_logic;
+ val : out std_logic_vector(REG_WIDTH-1 downto 0)
+ );
+
+end writeback;
Index: trunk/vhdl/intr_ent.vhd
===================================================================
--- trunk/vhdl/intr_ent.vhd (nonexistent)
+++ trunk/vhdl/intr_ent.vhd (revision 2)
@@ -0,0 +1,52 @@
+-- This file is part of the marca processor.
+-- Copyright (C) 2007 Wolfgang Puffitsch
+
+-- This program is free software; you can redistribute it and/or modify it
+-- under the terms of the GNU Library 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
+-- Library General Public License for more details.
+
+-- You should have received a copy of the GNU Library 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
+
+-------------------------------------------------------------------------------
+-- MARCA interrupt unit
+-------------------------------------------------------------------------------
+-- entity for the interrupt unit
+-------------------------------------------------------------------------------
+
+-------------------------------------------------------------------------------
+-- Wolfgang Puffitsch
+-- Computer Architecture Lab, Group 3
+-------------------------------------------------------------------------------
+
+library IEEE;
+use IEEE.std_logic_1164.all;
+
+use work.marca_pkg.all;
+
+entity intr is
+
+ port (
+ clock : in std_logic;
+ reset : in std_logic;
+ enable : in std_logic;
+
+ trigger : in std_logic_vector(VEC_COUNT-1 downto 1);
+
+ op : in INTR_OP;
+ a : in std_logic_vector(REG_WIDTH-1 downto 0);
+ i : in std_logic_vector(REG_WIDTH-1 downto 0);
+ pc : in std_logic_vector(REG_WIDTH-1 downto 0);
+
+ exc : out std_logic;
+ pcchg : out std_logic;
+ result : out std_logic_vector(REG_WIDTH-1 downto 0));
+
+end intr;
Index: trunk/vhdl/fifo.vhd
===================================================================
--- trunk/vhdl/fifo.vhd (nonexistent)
+++ trunk/vhdl/fifo.vhd (revision 2)
@@ -0,0 +1,155 @@
+--
+-- fifo.vhd
+--
+-- simple fifo
+--
+-- uses FF and every rd or wr has to 'bubble' through the hole fifo.
+--
+-- Author: Martin Schoeberl martin.schoeberl@chello.at
+--
+--
+-- resources on ACEX1K
+--
+-- (width+2)*depth-1 LCs
+--
+--
+-- 2002-01-06 first working version
+-- 2002-11-03 a signal for reaching threshold
+-- 2005-02-20 change entity order for modelsim vcom
+--
+
+library ieee;
+use ieee.std_logic_1164.all;
+
+use work.marca_pkg.all;
+
+entity fifo_elem is
+
+ generic (width : integer);
+ port (
+ clk : in std_logic;
+ reset : in std_logic;
+
+ din : in std_logic_vector(width-1 downto 0);
+ dout : out std_logic_vector(width-1 downto 0);
+
+ rd : in std_logic;
+ wr : in std_logic;
+
+ rd_prev : out std_logic;
+ full : out std_logic
+ );
+end fifo_elem;
+
+architecture rtl of fifo_elem is
+
+ signal buf : std_logic_vector(width-1 downto 0);
+ signal f : std_logic;
+
+begin
+
+ dout <= buf;
+
+ process(clk, reset, f)
+
+ begin
+
+ full <= f;
+
+ if reset = RESET_ACTIVE then
+
+ buf <= (others => '0');
+ f <= '0';
+ rd_prev <= '0';
+
+ elsif rising_edge(clk) then
+
+ rd_prev <= '0';
+ if f='0' then
+ if wr='1' then
+ rd_prev <= '1';
+ buf <= din;
+ f <= '1';
+ end if;
+ else
+ if rd='1' then
+ f <= '0';
+ end if;
+ end if;
+
+ end if;
+
+ end process;
+
+end rtl;
+
+library ieee;
+use ieee.std_logic_1164.all;
+
+entity fifo is
+
+ generic (width : integer := 8; depth : integer := 4; thres : integer := 2);
+ port (
+ clk : in std_logic;
+ reset : in std_logic;
+
+ din : in std_logic_vector(width-1 downto 0);
+ dout : out std_logic_vector(width-1 downto 0);
+
+ rd : in std_logic;
+ wr : in std_logic;
+
+ empty : out std_logic;
+ full : out std_logic;
+ half : out std_logic
+ );
+end fifo ;
+
+architecture rtl of fifo is
+
+ component fifo_elem is
+ generic (width : integer);
+ port (
+ clk : in std_logic;
+ reset : in std_logic;
+
+ din : in std_logic_vector(width-1 downto 0);
+ dout : out std_logic_vector(width-1 downto 0);
+
+ rd : in std_logic;
+ wr : in std_logic;
+
+ rd_prev : out std_logic;
+ full : out std_logic);
+ end component;
+
+ signal r, w, rp, f : std_logic_vector(depth-1 downto 0);
+ type d_array is array (0 to depth-1) of std_logic_vector(width-1 downto 0);
+ signal di, do : d_array;
+
+begin
+
+ g1: for i in 0 to depth-1 generate
+
+ f1: fifo_elem generic map (width)
+ port map (clk, reset, di(i), do(i), r(i), w(i), rp(i), f(i));
+
+ x: if i '0');
+ reg_operand2 <= (others => '0');
+ reg_product <= (others => '0');
+ reg_hotbit <= (others => '0');
+ reg_hotbit(0) <= '1';
+
+ elsif clock'event and clock = '1' then -- rising clock edge
+
+ if trigger = '1' then
+ reg_operand1 <= operand1;
+ reg_operand2 <= operand2;
+ reg_product <= (others => '0');
+ reg_hotbit(width-1) <= '1';
+ reg_hotbit(width-2 downto 0) <= (others => '0');
+ reg_busy <= '1';
+ else
+ reg_operand1 <= next_operand1;
+ reg_operand2 <= next_operand2;
+ reg_product(width-1 downto 0) <= next_product(width-1 downto 0);
+ -- sticky "carry"-bit
+ reg_product(width) <= reg_product(width) or next_product(width);
+ reg_hotbit <= next_hotbit;
+ reg_busy <= next_busy;
+ end if;
+
+ end if;
+ end process syn_proc;
+
+ compute: process (reg_operand1, reg_operand2, reg_product, reg_hotbit)
+ begin -- process compute
+
+ next_operand1 <= reg_operand1(width-2 downto 0) & '0';
+ next_operand2 <= '0' & reg_operand2(width-1 downto 1);
+ next_hotbit <= '0' & reg_hotbit(width-1 downto 1);
+
+ if reg_hotbit(0) = '1' then
+ next_hotbit <= reg_hotbit;
+ next_busy <= '0';
+ else
+ next_busy <= '1';
+ end if;
+
+ if reg_operand2(0) = '1' then
+ next_product <= std_logic_vector(unsigned(reg_product) + unsigned(reg_operand1(width-1 downto 0)));
+ else
+ next_product <= reg_product;
+ end if;
+
+ end process compute;
+
+end behaviour;
Index: trunk/vhdl/uart_reverse.s
===================================================================
--- trunk/vhdl/uart_reverse.s (nonexistent)
+++ trunk/vhdl/uart_reverse.s (revision 2)
@@ -0,0 +1,79 @@
+.data
+ data 0x0A
+ data 0x0D
+buffer:
+
+.text
+;;; initialization
+ ldib r0, -8 ; config/status
+ ldib r1, -6 ; data
+
+ ldil r2, lo(buffer) ; buffer address
+ ldih r2, hi(buffer) ; buffer address
+
+ ldib r3, 0x0A ; newline character
+ ldib r4, 0x0D ; carriage return
+
+ ldib r5, 0 ; mode
+
+ ldib r7, isr ; register isr
+ stvec r7, 3
+
+ ldib r7, (1 << 3) ; enable receive interrupts
+ store r7, r0
+
+ sei ; enable interrupts
+
+;;; loop forever
+loop: br loop
+
+
+;;; ISR
+isr:
+ cmpi r5, 0 ; check mode
+ brnz write_mode
+
+;;; reading
+read_mode:
+ load r7, r1 ; read data
+
+ cmp r7, r3 ; change mode upon newline
+ brnz read_CR
+
+ ldib r7, (1 << 2) ; do the change
+ store r7, r0
+ ldib r5, 1
+ reti
+
+read_CR:
+ cmp r7, r4 ; ignore carriage return
+ brnz read_cont
+ reti
+
+read_cont:
+ storel r7, r2 ; store date
+ addi r2, 1
+ reti
+
+;;; writing
+write_mode:
+ addi r2, -1
+
+ cmpi r2, -1 ; change mode if there is no more data
+ brnz write_cont
+
+ ldil r2, lo(buffer) ; correct pointer to buffer
+ ldih r2, hi(buffer)
+
+ ldib r7, (1 << 3) ; do the change
+ store r7, r0
+ ldib r5, 0
+ reti
+
+write_cont:
+ loadl r7, r2 ; write data
+ store r7, r1
+ reti
+
+
+
Index: trunk/vhdl/data_memory.bsf
===================================================================
--- trunk/vhdl/data_memory.bsf (nonexistent)
+++ trunk/vhdl/data_memory.bsf (revision 2)
@@ -0,0 +1,104 @@
+/*
+WARNING: Do NOT edit the input and output ports in this file in a text
+editor if you plan to continue editing the block that represents it in
+the Block Editor! File corruption is VERY likely to occur.
+*/
+/*
+Copyright (C) 1991-2006 Altera Corporation
+Your use of Altera Corporation's design tools, logic functions
+and other software and tools, and its AMPP partner logic
+functions, and any output files any of the foregoing
+(including device programming or simulation files), and any
+associated documentation or information are expressly subject
+to the terms and conditions of the Altera Program License
+Subscription Agreement, Altera MegaCore Function License
+Agreement, or other applicable license agreement, including,
+without limitation, that your use is for the sole purpose of
+programming logic devices manufactured by Altera and sold by
+Altera or its authorized distributors. Please refer to the
+applicable agreement for further details.
+*/
+(header "symbol" (version "1.1"))
+(symbol
+ (rect 0 0 216 152)
+ (text "data_memory" (rect 69 1 162 17)(font "Arial" (font_size 10)))
+ (text "inst" (rect 8 136 25 148)(font "Arial" ))
+ (port
+ (pt 0 32)
+ (input)
+ (text "data[7..0]" (rect 0 0 53 14)(font "Arial" (font_size 8)))
+ (text "data[7..0]" (rect 4 19 49 32)(font "Arial" (font_size 8)))
+ (line (pt 0 32)(pt 88 32)(line_width 3))
+ )
+ (port
+ (pt 0 48)
+ (input)
+ (text "wren" (rect 0 0 30 14)(font "Arial" (font_size 8)))
+ (text "wren" (rect 4 35 26 48)(font "Arial" (font_size 8)))
+ (line (pt 0 48)(pt 88 48)(line_width 1))
+ )
+ (port
+ (pt 0 64)
+ (input)
+ (text "address[11..0]" (rect 0 0 82 14)(font "Arial" (font_size 8)))
+ (text "address[11..0]" (rect 4 51 69 64)(font "Arial" (font_size 8)))
+ (line (pt 0 64)(pt 88 64)(line_width 3))
+ )
+ (port
+ (pt 0 112)
+ (input)
+ (text "clock" (rect 0 0 29 14)(font "Arial" (font_size 8)))
+ (text "clock" (rect 4 99 29 112)(font "Arial" (font_size 8)))
+ (line (pt 0 112)(pt 80 112)(line_width 1))
+ )
+ (port
+ (pt 0 128)
+ (input)
+ (text "clken" (rect 0 0 29 14)(font "Arial" (font_size 8)))
+ (text "clken" (rect 4 115 29 128)(font "Arial" (font_size 8)))
+ (line (pt 0 128)(pt 16 128)(line_width 1))
+ )
+ (port
+ (pt 216 32)
+ (output)
+ (text "q[7..0]" (rect 0 0 35 14)(font "Arial" (font_size 8)))
+ (text "q[7..0]" (rect 183 19 213 32)(font "Arial" (font_size 8)))
+ (line (pt 216 32)(pt 136 32)(line_width 3))
+ )
+ (drawing
+ (text "8 bits" (rect 108 48 120 71)(font "Arial" )(vertical))
+ (text "4096 words" (rect 121 36 133 83)(font "Arial" )(vertical))
+ (text "Block type: AUTO" (rect 41 132 117 144)(font "Arial" ))
+ (line (pt 104 24)(pt 136 24)(line_width 1))
+ (line (pt 136 24)(pt 136 96)(line_width 1))
+ (line (pt 136 96)(pt 104 96)(line_width 1))
+ (line (pt 104 96)(pt 104 24)(line_width 1))
+ (line (pt 118 58)(pt 123 63)(line_width 1))
+ (line (pt 118 62)(pt 123 57)(line_width 1))
+ (line (pt 88 27)(pt 96 27)(line_width 1))
+ (line (pt 96 27)(pt 96 39)(line_width 1))
+ (line (pt 96 39)(pt 88 39)(line_width 1))
+ (line (pt 88 39)(pt 88 27)(line_width 1))
+ (line (pt 88 34)(pt 90 36)(line_width 1))
+ (line (pt 90 36)(pt 88 38)(line_width 1))
+ (line (pt 80 36)(pt 88 36)(line_width 1))
+ (line (pt 96 32)(pt 104 32)(line_width 3))
+ (line (pt 88 43)(pt 96 43)(line_width 1))
+ (line (pt 96 43)(pt 96 55)(line_width 1))
+ (line (pt 96 55)(pt 88 55)(line_width 1))
+ (line (pt 88 55)(pt 88 43)(line_width 1))
+ (line (pt 88 50)(pt 90 52)(line_width 1))
+ (line (pt 90 52)(pt 88 54)(line_width 1))
+ (line (pt 80 52)(pt 88 52)(line_width 1))
+ (line (pt 96 48)(pt 104 48)(line_width 1))
+ (line (pt 88 59)(pt 96 59)(line_width 1))
+ (line (pt 96 59)(pt 96 71)(line_width 1))
+ (line (pt 96 71)(pt 88 71)(line_width 1))
+ (line (pt 88 71)(pt 88 59)(line_width 1))
+ (line (pt 88 66)(pt 90 68)(line_width 1))
+ (line (pt 90 68)(pt 88 70)(line_width 1))
+ (line (pt 80 68)(pt 88 68)(line_width 1))
+ (line (pt 96 64)(pt 104 64)(line_width 3))
+ (line (pt 80 112)(pt 80 36)(line_width 1))
+ )
+)
Index: trunk/vhdl/code_memory.bsf
===================================================================
--- trunk/vhdl/code_memory.bsf (nonexistent)
+++ trunk/vhdl/code_memory.bsf (revision 2)
@@ -0,0 +1,74 @@
+/*
+WARNING: Do NOT edit the input and output ports in this file in a text
+editor if you plan to continue editing the block that represents it in
+the Block Editor! File corruption is VERY likely to occur.
+*/
+/*
+Copyright (C) 1991-2006 Altera Corporation
+Your use of Altera Corporation's design tools, logic functions
+and other software and tools, and its AMPP partner logic
+functions, and any output files any of the foregoing
+(including device programming or simulation files), and any
+associated documentation or information are expressly subject
+to the terms and conditions of the Altera Program License
+Subscription Agreement, Altera MegaCore Function License
+Agreement, or other applicable license agreement, including,
+without limitation, that your use is for the sole purpose of
+programming logic devices manufactured by Altera and sold by
+Altera or its authorized distributors. Please refer to the
+applicable agreement for further details.
+*/
+(header "symbol" (version "1.1"))
+(symbol
+ (rect 0 0 216 152)
+ (text "code_memory" (rect 67 1 163 17)(font "Arial" (font_size 10)))
+ (text "inst" (rect 8 136 25 148)(font "Arial" ))
+ (port
+ (pt 0 32)
+ (input)
+ (text "address[11..0]" (rect 0 0 82 14)(font "Arial" (font_size 8)))
+ (text "address[11..0]" (rect 4 19 69 32)(font "Arial" (font_size 8)))
+ (line (pt 0 32)(pt 88 32)(line_width 3))
+ )
+ (port
+ (pt 0 112)
+ (input)
+ (text "clock" (rect 0 0 29 14)(font "Arial" (font_size 8)))
+ (text "clock" (rect 4 99 29 112)(font "Arial" (font_size 8)))
+ (line (pt 0 112)(pt 80 112)(line_width 1))
+ )
+ (port
+ (pt 0 128)
+ (input)
+ (text "clken" (rect 0 0 29 14)(font "Arial" (font_size 8)))
+ (text "clken" (rect 4 115 29 128)(font "Arial" (font_size 8)))
+ (line (pt 0 128)(pt 16 128)(line_width 1))
+ )
+ (port
+ (pt 216 32)
+ (output)
+ (text "q[15..0]" (rect 0 0 42 14)(font "Arial" (font_size 8)))
+ (text "q[15..0]" (rect 177 19 213 32)(font "Arial" (font_size 8)))
+ (line (pt 216 32)(pt 136 32)(line_width 3))
+ )
+ (drawing
+ (text "16 bits" (rect 108 46 120 74)(font "Arial" )(vertical))
+ (text "4096 words" (rect 121 36 133 83)(font "Arial" )(vertical))
+ (text "Block type: AUTO" (rect 41 132 117 144)(font "Arial" ))
+ (line (pt 104 24)(pt 136 24)(line_width 1))
+ (line (pt 136 24)(pt 136 96)(line_width 1))
+ (line (pt 136 96)(pt 104 96)(line_width 1))
+ (line (pt 104 96)(pt 104 24)(line_width 1))
+ (line (pt 118 58)(pt 123 63)(line_width 1))
+ (line (pt 118 62)(pt 123 57)(line_width 1))
+ (line (pt 88 27)(pt 96 27)(line_width 1))
+ (line (pt 96 27)(pt 96 39)(line_width 1))
+ (line (pt 96 39)(pt 88 39)(line_width 1))
+ (line (pt 88 39)(pt 88 27)(line_width 1))
+ (line (pt 88 34)(pt 90 36)(line_width 1))
+ (line (pt 90 36)(pt 88 38)(line_width 1))
+ (line (pt 80 36)(pt 88 36)(line_width 1))
+ (line (pt 96 32)(pt 104 32)(line_width 3))
+ (line (pt 80 112)(pt 80 36)(line_width 1))
+ )
+)
Index: trunk/vhdl/multiplier_ent.vhd
===================================================================
--- trunk/vhdl/multiplier_ent.vhd (nonexistent)
+++ trunk/vhdl/multiplier_ent.vhd (revision 2)
@@ -0,0 +1,48 @@
+-- This file is part of the marca processor.
+-- Copyright (C) 2007 Wolfgang Puffitsch
+
+-- This program is free software; you can redistribute it and/or modify it
+-- under the terms of the GNU Library 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
+-- Library General Public License for more details.
+
+-- You should have received a copy of the GNU Library 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
+
+-------------------------------------------------------------------------------
+-- MARCA multiplier
+-------------------------------------------------------------------------------
+-- entity of a bit-serial multiplier
+-------------------------------------------------------------------------------
+
+-------------------------------------------------------------------------------
+-- Wolfgang Puffitsch
+-- Computer Architecture Lab, Group 3
+-------------------------------------------------------------------------------
+
+library IEEE;
+use IEEE.std_logic_1164.all;
+
+use work.marca_pkg.all;
+
+entity multiplier is
+
+ generic (
+ width : integer := REG_WIDTH);
+
+ port (
+ clock : in std_logic;
+ reset : in std_logic;
+ trigger : in std_logic;
+ operand1 : in std_logic_vector(width-1 downto 0);
+ operand2 : in std_logic_vector(width-1 downto 0);
+ busy : out std_logic;
+ product : out std_logic_vector(width downto 0));
+
+end multiplier;
Index: trunk/vhdl/Makefile
===================================================================
--- trunk/vhdl/Makefile (nonexistent)
+++ trunk/vhdl/Makefile (revision 2)
@@ -0,0 +1,2 @@
+program: factorial.s
+ ../../spar/as1 --output=code.mif --rom0file=rom0.mif --rom1file=rom1.mif factorial.s
Index: trunk/vhdl/sc_uart.vhd
===================================================================
--- trunk/vhdl/sc_uart.vhd (nonexistent)
+++ trunk/vhdl/sc_uart.vhd (revision 2)
@@ -0,0 +1,367 @@
+--
+-- sc_uart.vhd
+--
+-- 8-N-1 serial interface
+--
+-- wr, rd should be one cycle long => trde, rdrf goes 0 one cycle later
+--
+-- Author: Martin Schoeberl martin@jopdesign.com
+--
+--
+-- resources on ACEX1K30-3
+--
+-- 100 LCs, max 90 MHz
+--
+-- resetting rts with fifo_full-1 works with C program on pc
+-- but not with javax.comm: sends some more bytes after deassert
+-- of rts (16 byte blocks regardless of rts).
+-- Try to stop with half full fifo.
+--
+-- todo:
+--
+--
+-- 2000-12-02 first working version
+-- 2002-01-06 changed tdr and rdr to fifos.
+-- 2002-05-15 changed clkdiv calculation
+-- 2002-11-01 don't wait if read fifo is full, just drop the byte
+-- 2002-11-03 use threshold in fifo to reset rts
+-- don't send if cts is '0'
+-- 2002-11-08 rx fifo to 20 characters and stop after 4
+-- 2003-07-05 new IO standard, change cts/rts to neg logic
+-- 2003-09-19 sync ncts in!
+-- 2004-03-23 two stop bits
+-- 2005-11-30 change interface to SimpCon
+-- 2006-08-07 rxd input register with clk to avoid Quartus tsu violation
+-- 2006-08-13 use 3 FFs for the rxd input at clk
+--
+
+
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+use work.marca_pkg.all;
+use work.sc_pkg.all;
+
+entity sc_uart is
+
+ generic (clock_freq : integer;
+ baud_rate : integer;
+ txf_depth : integer; txf_thres : integer;
+ rxf_depth : integer; rxf_thres : integer);
+
+ port (clock : in std_logic;
+ reset : in std_logic;
+
+-- SimpCon interface
+ input : in SC_IN;
+ output : out SC_OUT;
+
+ intr : out std_logic;
+
+ txd : out std_logic;
+ rxd : in std_logic;
+ ncts : in std_logic;
+ nrts : out std_logic);
+
+end sc_uart;
+
+architecture rtl of sc_uart is
+
+ component fifo is
+
+ generic (width : integer;
+ depth : integer;
+ thres : integer);
+
+ port (clk : in std_logic;
+ reset : in std_logic;
+
+ din : in std_logic_vector(width-1 downto 0);
+ dout : out std_logic_vector(width-1 downto 0);
+
+ rd : in std_logic;
+ wr : in std_logic;
+
+ empty : out std_logic;
+ full : out std_logic;
+ half : out std_logic);
+ end component;
+
+--
+-- signals for uart connection
+--
+ signal ua_dout : std_logic_vector(7 downto 0);
+ signal ua_wr, tdre : std_logic;
+ signal ua_rd, rdrf : std_logic;
+
+ type uart_tx_state_type is (s0, s1);
+ signal uart_tx_state : uart_tx_state_type;
+
+ signal tf_dout : std_logic_vector(7 downto 0); -- fifo out
+ signal tf_rd : std_logic;
+ signal tf_empty : std_logic;
+ signal tf_full : std_logic;
+ signal tf_half : std_logic;
+
+ signal ncts_buf : std_logic_vector(2 downto 0); -- sync in
+ signal tsr : std_logic_vector(9 downto 0); -- tx shift register
+ signal tx_clk : std_logic;
+
+ type uart_rx_state_type is (s0, s1, s2);
+ signal uart_rx_state : uart_rx_state_type;
+
+ signal rf_wr : std_logic;
+ signal rf_empty : std_logic;
+ signal rf_full : std_logic;
+ signal rf_half : std_logic;
+
+ signal rxd_reg : std_logic_vector(2 downto 0);
+ signal rx_buf : std_logic_vector(2 downto 0); -- sync in, filter
+ signal rx_d : std_logic; -- rx serial data
+ signal rsr : std_logic_vector(9 downto 0); -- rx shift register
+ signal rx_clk : std_logic;
+ signal rx_clk_ena : std_logic;
+
+ signal rdrf_iena : std_logic;
+ signal tdre_iena : std_logic;
+
+ constant clk16_cnt : integer := (clock_freq/baud_rate+8)/16-1;
+
+begin
+
+ output.rdy_cnt <= "00"; -- no wait states
+ output.rd_data(SC_REG_WIDTH-1 downto 8) <= std_logic_vector(to_unsigned(0, SC_REG_WIDTH-8));
+
+--
+-- The registered MUX is all we need for a SimpCon read.
+-- The read data is stored in registered rd_data.
+--
+ process(clock, reset)
+ begin
+
+ if reset = RESET_ACTIVE then
+ output.rd_data(7 downto 0) <= (others => '0');
+ elsif rising_edge(clock) then
+
+ ua_rd <= '0';
+ if input.rd='1' then
+ -- that's our very simple address decoder
+ if input.address(0)='0' then
+ output.rd_data(7 downto 0) <= "0000" & rdrf_iena & tdre_iena & rdrf & tdre;
+ else
+ output.rd_data(7 downto 0) <= ua_dout;
+ ua_rd <= input.rd;
+ end if;
+ end if;
+
+ if input.wr='1' then
+ if input.address(0)='0' then
+ rdrf_iena <= input.wr_data(3);
+ tdre_iena <= input.wr_data(2);
+ end if;
+ end if;
+
+ end if;
+
+ end process;
+
+ ua_wr <= input.wr and input.address(0);
+
+ intr <= (rdrf and rdrf_iena) or (tdre and tdre_iena);
+
+--
+-- serial clock
+--
+ process(clock, reset)
+
+ variable clk16 : integer range 0 to clk16_cnt;
+ variable clktx : unsigned(3 downto 0);
+ variable clkrx : unsigned(3 downto 0);
+
+ begin
+ if reset = RESET_ACTIVE then
+ clk16 := 0;
+ clktx := "0000";
+ clkrx := "0000";
+ tx_clk <= '0';
+ rx_clk <= '0';
+ rx_buf <= "111";
+
+ elsif rising_edge(clock) then
+
+ rxd_reg(0) <= rxd; -- to avoid setup timing error in Quartus
+ rxd_reg(1) <= rxd_reg(0);
+ rxd_reg(2) <= rxd_reg(1);
+
+ if (clk16=clk16_cnt) then -- 16 x serial clock
+ clk16 := 0;
+--
+-- tx clock
+--
+ clktx := clktx + 1;
+ if (clktx="0000") then
+ tx_clk <= '1';
+ else
+ tx_clk <= '0';
+ end if;
+--
+-- rx clock
+--
+ if (rx_clk_ena='1') then
+ clkrx := clkrx + 1;
+ if (clkrx="1000") then
+ rx_clk <= '1';
+ else
+ rx_clk <= '0';
+ end if;
+ else
+ clkrx := "0000";
+ end if;
+--
+-- sync in filter buffer
+--
+ rx_buf(0) <= rxd_reg(2);
+ rx_buf(2 downto 1) <= rx_buf(1 downto 0);
+ else
+ clk16 := clk16 + 1;
+ tx_clk <= '0';
+ rx_clk <= '0';
+ end if;
+
+ end if;
+
+ end process;
+
+--
+-- transmit fifo
+--
+ cmp_tf: fifo generic map (8, txf_depth, txf_thres)
+ port map (clock, reset, input.wr_data(7 downto 0), tf_dout, tf_rd, ua_wr, tf_empty, tf_full, tf_half);
+
+ txd <= tsr(0);
+ tdre <= not tf_full;
+
+--
+-- state machine for actual shift out
+--
+ process(clock, reset)
+
+ variable i : integer range 0 to 11;
+
+ begin
+
+ if reset = RESET_ACTIVE then
+ uart_tx_state <= s0;
+ tsr <= "1111111111";
+ tf_rd <= '0';
+ ncts_buf <= "111";
+
+ elsif rising_edge(clock) then
+
+ ncts_buf(0) <= ncts;
+ ncts_buf(2 downto 1) <= ncts_buf(1 downto 0);
+
+ case uart_tx_state is
+
+ when s0 =>
+ i := 0;
+ if (tf_empty='0' and ncts_buf(2)='0') then
+ uart_tx_state <= s1;
+ tsr <= tf_dout & '0' & '1';
+ tf_rd <= '1';
+ end if;
+
+ when s1 =>
+ tf_rd <= '0';
+ if (tx_clk='1') then
+ tsr(9) <= '1';
+ tsr(8 downto 0) <= tsr(9 downto 1);
+ i := i+1;
+ if (i=11) then -- two stop bits
+ uart_tx_state <= s0;
+ end if;
+ end if;
+
+ end case;
+ end if;
+
+ end process;
+
+--
+-- receive fifo
+--
+ cmp_rf: fifo generic map (8, rxf_depth, rxf_thres)
+ port map (clock, reset, rsr(8 downto 1), ua_dout, ua_rd, rf_wr, rf_empty, rf_full, rf_half);
+
+ rdrf <= not rf_empty;
+ nrts <= rf_half; -- glitches even on empty fifo!
+
+--
+-- filter rxd
+--
+ with rx_buf select
+ rx_d <= '0' when "000",
+ '0' when "001",
+ '0' when "010",
+ '1' when "011",
+ '0' when "100",
+ '1' when "101",
+ '1' when "110",
+ '1' when "111",
+ 'X' when others;
+
+--
+-- state machine for actual shift in
+--
+ process(clock, reset)
+
+ variable i : integer range 0 to 10;
+
+ begin
+
+ if reset = RESET_ACTIVE then
+ uart_rx_state <= s0;
+ rsr <= "0000000000";
+ rf_wr <= '0';
+ rx_clk_ena <= '0';
+
+ elsif rising_edge(clock) then
+
+ case uart_rx_state is
+
+ when s0 =>
+ i := 0;
+ rf_wr <= '0';
+ if (rx_d='0') then
+ rx_clk_ena <= '1';
+ uart_rx_state <= s1;
+ else
+ rx_clk_ena <= '0';
+ end if;
+
+ when s1 =>
+ if (rx_clk='1') then
+ rsr(9) <= rx_d;
+ rsr(8 downto 0) <= rsr(9 downto 1);
+ i := i+1;
+ if (i=10) then
+ uart_rx_state <= s2;
+ end if;
+ end if;
+
+ when s2 =>
+ rx_clk_ena <= '0';
+ if rsr(0)='0' and rsr(9)='1' then
+ if rf_full='0' then -- if full just drop it
+ rf_wr <= '1';
+ end if;
+ end if;
+ uart_rx_state <= s0;
+
+ end case;
+ end if;
+
+ end process;
+
+end rtl;
Index: trunk/vhdl/rom0.mif
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: trunk/vhdl/rom0.mif
===================================================================
--- trunk/vhdl/rom0.mif (nonexistent)
+++ trunk/vhdl/rom0.mif (revision 2)
trunk/vhdl/rom0.mif
Property changes :
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: trunk/vhdl/ChangeLog
===================================================================
--- trunk/vhdl/ChangeLog (nonexistent)
+++ trunk/vhdl/ChangeLog (revision 2)
@@ -0,0 +1,47 @@
+2007-02-02 Wolfgang Puffitsch
+
+ Version to be published on opencores.org ``Cement and aluminium.''
+
+2007-01-31 Wolfgang Puffitsch
+
+ * decode.vhd: restuctured decoder, saving a few LCs
+
+2007-01-29 Wolfgang Puffitsch
+
+ * alu.vhd: simplified logic to use only one adder/subtractor
+
+ * mem.vhd: removed extra state for SimpCon access
+
+2007-01-28 Wolfgang Puffitsch
+
+ * mem.vhd: introduced enable-signals for the memories to reduce
+ power consumption
+
+2007-01-20 Wolfgang Puffitsch
+
+ * mem.vhd: fixed condition for raising memory interrupt
+
+2006-12-31 Wolfgang Puffitsch
+
+ * multiplier.vhd: "predicting" unconditional branches now
+
+ * execute.vhd: fixing a bug with calls
+
+ * mem.vhd: fixing a bug with stores to odd addresses
+
+2006-12-29 Wolfgang Puffitsch
+
+ * intr.vhd: EXC_ERR is triggered by an instruction itself, so it's
+ wire is left out in the "trigger" signal
+
+ * decode.vhd: now triggering interrupt upon invalid instructions
+
+ * marca_pkg.vhd: introduced constant RESET_ACTIVE for easy
+ adaption to low-active reset buttons
+
+ * fetch.vhd: reorganized this stage to fix an off-by-one flaw with
+ the program counter
+
+2006-12-14 Wolfgang Puffitsch
+
+ First working version ``Starving hysterical naked.''
\ No newline at end of file
Index: trunk/vhdl/rom1.mif
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: trunk/vhdl/rom1.mif
===================================================================
--- trunk/vhdl/rom1.mif (nonexistent)
+++ trunk/vhdl/rom1.mif (revision 2)
trunk/vhdl/rom1.mif
Property changes :
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: trunk/vhdl/regfile.vhd
===================================================================
--- trunk/vhdl/regfile.vhd (nonexistent)
+++ trunk/vhdl/regfile.vhd (revision 2)
@@ -0,0 +1,77 @@
+-- This file is part of the marca processor.
+-- Copyright (C) 2007 Wolfgang Puffitsch
+
+-- This program is free software; you can redistribute it and/or modify it
+-- under the terms of the GNU Library 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
+-- Library General Public License for more details.
+
+-- You should have received a copy of the GNU Library 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
+
+-------------------------------------------------------------------------------
+-- MARCA decode stage
+-------------------------------------------------------------------------------
+-- architecture for the instruction-decode pipeline stage
+-------------------------------------------------------------------------------
+
+-------------------------------------------------------------------------------
+-- Wolfgang Puffitsch
+-- Computer Architecture Lab, Group 3
+-------------------------------------------------------------------------------
+
+library IEEE;
+use IEEE.std_logic_1164.all;
+use IEEE.numeric_std.all;
+
+use work.marca_pkg.all;
+
+architecture behaviour of regfile is
+
+type registers is array (REG_COUNT-1 downto 0) of std_logic_vector(REG_WIDTH-1 downto 0);
+
+signal regs, next_regs : registers;
+
+begin -- behaviour
+
+ syn_proc: process (clock, reset)
+ begin -- process syn_proc
+ if reset = RESET_ACTIVE then -- asynchronous reset (active low)
+ regs <= (others => (others => '0'));
+ elsif clock'event and clock = '1' then -- rising clock edge
+ if hold = '0' then
+ regs <= next_regs;
+ end if;
+ end if;
+ end process syn_proc;
+
+ forward: process(rd1_addr, rd2_addr, wr_ena, wr_addr, wr_val, regs)
+ begin -- process forward
+
+ next_regs <= regs;
+
+ if wr_ena = '1' then
+ next_regs(to_integer(unsigned(wr_addr))) <= wr_val;
+ end if;
+
+ if rd1_addr /= wr_addr or wr_ena = '0' then
+ rd1_val <= regs(to_integer(unsigned(rd1_addr)));
+ else
+ rd1_val <= wr_val;
+ end if;
+
+ if rd2_addr /= wr_addr or wr_ena = '0' then
+ rd2_val <= regs(to_integer(unsigned(rd2_addr)));
+ else
+ rd2_val <= wr_val;
+ end if;
+
+ end process forward;
+
+end behaviour;
Index: trunk/vhdl/alu.vhd
===================================================================
--- trunk/vhdl/alu.vhd (nonexistent)
+++ trunk/vhdl/alu.vhd (revision 2)
@@ -0,0 +1,613 @@
+-- This file is part of the marca processor.
+-- Copyright (C) 2007 Wolfgang Puffitsch
+
+-- This program is free software; you can redistribute it and/or modify it
+-- under the terms of the GNU Library 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
+-- Library General Public License for more details.
+
+-- You should have received a copy of the GNU Library 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
+
+-------------------------------------------------------------------------------
+-- MARCA ALU
+-------------------------------------------------------------------------------
+-- architecture for the ALU
+-------------------------------------------------------------------------------
+
+-------------------------------------------------------------------------------
+-- Wolfgang Puffitsch
+-- Computer Architecture Lab, Group 3
+-------------------------------------------------------------------------------
+
+library IEEE;
+use IEEE.std_logic_1164.all;
+use IEEE.numeric_std.all;
+
+use work.marca_pkg.all;
+
+architecture behaviour of alu is
+
+ type WAIT_STATE is (WAIT_NONE, WAIT_MULT, WAIT_DIV, WAIT_UDIV, WAIT_MOD, WAIT_UMOD);
+ signal state : WAIT_STATE;
+ signal next_state : WAIT_STATE;
+
+ signal flags : std_logic_vector(REG_WIDTH-1 downto 0);
+ signal next_flags : std_logic_vector(REG_WIDTH-1 downto 0);
+
+ signal shflags : std_logic_vector(REG_WIDTH-1 downto 0);
+ signal next_shflags : std_logic_vector(REG_WIDTH-1 downto 0);
+
+ signal old_sgna, old_sgnb : std_logic;
+ signal sgna, sgnb : std_logic;
+
+ component multiplier is
+ generic (
+ width : integer := REG_WIDTH);
+ port (
+ clock : in std_logic;
+ reset : in std_logic;
+ trigger : in std_logic;
+ operand1 : in std_logic_vector(width-1 downto 0);
+ operand2 : in std_logic_vector(width-1 downto 0);
+ busy : out std_logic;
+ product : out std_logic_vector(width downto 0));
+ end component;
+
+ signal mult_op1 : std_logic_vector(REG_WIDTH-1 downto 0);
+ signal mult_op2 : std_logic_vector(REG_WIDTH-1 downto 0);
+ signal mult_trigger : std_logic;
+ signal mult_busy : std_logic;
+ signal mult_result : std_logic_vector(REG_WIDTH downto 0);
+
+
+ component divider is
+ generic (
+ width : integer := REG_WIDTH);
+ port (
+ clock : in std_logic;
+ reset : in std_logic;
+ trigger : in std_logic;
+ denom : in std_logic_vector(width-1 downto 0);
+ numer : in std_logic_vector(width-1 downto 0);
+ exc : out std_logic;
+ busy : out std_logic;
+ quotient : out std_logic_vector(width-1 downto 0);
+ remain : out std_logic_vector(width-1 downto 0));
+ end component;
+
+ signal udiv_op1 : std_logic_vector(REG_WIDTH-1 downto 0);
+ signal udiv_op2 : std_logic_vector(REG_WIDTH-1 downto 0);
+ signal udiv_trigger : std_logic;
+ signal udiv_exc : std_logic;
+ signal udiv_busy : std_logic;
+ signal udiv_result : std_logic_vector(REG_WIDTH-1 downto 0);
+ signal umod_result : std_logic_vector(REG_WIDTH-1 downto 0);
+
+
+ signal adder_op1 : std_logic_vector(REG_WIDTH downto 0);
+ signal adder_op2 : std_logic_vector(REG_WIDTH downto 0);
+ signal adder_op3 : std_logic;
+ signal adder_result : std_logic_vector(REG_WIDTH downto 0);
+
+
+ function shift_left (a : std_logic_vector;
+ b : std_logic_vector)
+ return std_logic_vector is
+ variable result : std_logic_vector(a'length-1 downto 0);
+ variable i : integer;
+ begin
+ for i in 0 to a'length-1 loop
+ if i < to_integer(unsigned(b)) then
+ result(i) := '0';
+ else
+ result(i) := a(i - to_integer(unsigned(b)));
+ end if;
+ end loop;
+ return result;
+ end;
+
+ function shift_right (a : std_logic_vector;
+ b : std_logic_vector)
+ return std_logic_vector is
+ variable result : std_logic_vector(a'length-1 downto 0);
+ variable i : integer;
+ begin
+ for i in 0 to a'length-1 loop
+ if i < to_integer(unsigned(b)) then
+ result(i) := a(i + to_integer(unsigned(b)));
+ elsif i < a'length-1 then
+ result(i) := '0';
+ else
+ result(i) := a(to_integer(unsigned(b)) - 1);
+ end if;
+ end loop;
+ return result;
+ end;
+
+ function shift_aright (a : std_logic_vector;
+ b : std_logic_vector)
+ return std_logic_vector is
+ variable result : std_logic_vector(a'length-1 downto 0);
+ variable i : integer;
+ begin
+ for i in 0 to a'length-1 loop
+ if i < to_integer(unsigned(b)) then
+ result(i) := a(i + to_integer(unsigned(b)));
+ elsif i < a'length-1 then
+ result(i) := a(a'length-1);
+ else
+ result(i) := a(to_integer(unsigned(b)) - 1);
+ end if;
+ end loop;
+ return result;
+ end;
+
+ function rotate_left (a : std_logic_vector;
+ b : std_logic_vector;
+ c : std_logic)
+ return std_logic_vector is
+ variable result : std_logic_vector(a'length-1 downto 0);
+ variable i : integer;
+ begin
+ for i in 0 to a'length-1 loop
+ if i < to_integer(unsigned(b)) - 1 then
+ result(i) := a(a'length - to_integer(unsigned(b)) + i);
+ elsif i = to_integer(unsigned(b)) - 1 then
+ result(i) := c;
+ else
+ result(i) := a(i - to_integer(unsigned(b)));
+ end if;
+ end loop;
+ return result;
+ end;
+
+ function rotate_right(a : std_logic_vector;
+ b : std_logic_vector;
+ c : std_logic)
+ return std_logic_vector is
+ variable result : std_logic_vector(a'length-1 downto 0);
+ variable i : integer;
+ begin
+ for i in 0 to a'length-1 loop
+ if i < a'length - to_integer(unsigned(b)) then
+ result(i) := a(to_integer(unsigned(b)) + i);
+ elsif i = a'length - to_integer(unsigned(b)) - 1 then
+ result(i) := c;
+ else
+ result(i) := a(i - a'length - to_integer(unsigned(b)));
+ end if;
+ end loop;
+ return result;
+ end;
+
+ function to_unsigned(a : std_logic)
+ return unsigned is
+ variable result : unsigned(0 downto 0);
+ begin -- to_unsigned
+ if a = '1' then
+ result := "1";
+ else
+ result := "0";
+ end if;
+ return result;
+ end to_unsigned;
+
+ function parity(a : std_logic_vector)
+ return std_logic is
+ variable result : std_logic;
+ variable i : integer;
+ begin
+ result := '1';
+ for i in a'low to a'high loop
+ result := result xor a(i);
+ end loop;
+ return result;
+ end;
+
+begin -- behaviour
+
+ -- hardwire the interrupt enable flag
+ iena <= flags(FLAG_I);
+ -- and the exception signal to the divider
+ exc <= udiv_exc;
+
+ mult_unit : multiplier
+ port map (
+ clock => clock,
+ reset => reset,
+ trigger => mult_trigger,
+ operand1 => mult_op1,
+ operand2 => mult_op2,
+ busy => mult_busy,
+ product => mult_result);
+
+ udiv_unit : divider
+ port map (
+ clock => clock,
+ reset => reset,
+ trigger => udiv_trigger,
+ numer => udiv_op1,
+ denom => udiv_op2,
+ exc => udiv_exc,
+ busy => udiv_busy,
+ quotient => udiv_result,
+ remain => umod_result);
+
+ syn_proc: process (clock, reset)
+ begin -- process syn_proc
+ if reset = RESET_ACTIVE then -- asynchronous reset (active low)
+ flags <= (others => '0');
+ shflags <= (others => '0');
+ state <= WAIT_NONE;
+ old_sgna <= '0';
+ old_sgnb <= '0';
+ elsif clock'event and clock = '1' then -- rising clock edge
+ flags <= next_flags;
+ shflags <= next_shflags;
+ state <= next_state;
+ old_sgna <= sgna;
+ old_sgnb <= sgnb;
+ end if;
+ end process syn_proc;
+
+ business: process(next_state)
+ begin -- process business
+ if next_state /= WAIT_NONE then
+ busy <= '1';
+ else
+ busy <= '0';
+ end if;
+ end process business;
+
+ adder: process (adder_op1, adder_op2, adder_op3)
+ begin -- process adder
+ adder_result <= std_logic_vector(unsigned(adder_op1) + unsigned(adder_op2)
+ + to_unsigned(adder_op3));
+ end process adder;
+
+ compute: process (state, op, a, b, i, pc, flags, shflags,
+ intr,
+ sgna, sgnb, old_sgna, old_sgnb,
+ mult_busy, mult_result,
+ udiv_busy, udiv_result, umod_result,
+ adder_result)
+
+ variable wr_flags : std_logic;
+ variable tmp : std_logic_vector(REG_WIDTH downto 0);
+
+ begin
+ wr_flags := '1';
+ tmp := (others => '0');
+
+ next_flags <= flags;
+ next_shflags <= shflags;
+ next_state <= state;
+
+ sgna <= a(REG_WIDTH-1);
+ sgnb <= b(REG_WIDTH-1);
+
+ mult_op1 <= (others => '0');
+ mult_op2 <= (others => '0');
+ mult_trigger <= '0';
+
+ udiv_op1 <= (others => '0');
+ udiv_op2 <= (others => '0');
+ udiv_trigger <= '0';
+
+ adder_op1 <= (others => '0');
+ adder_op2 <= (others => '0');
+ adder_op3 <= '0';
+
+ pcchg <= '0';
+
+ case state is
+ when WAIT_MULT =>
+ sgna <= old_sgna;
+ sgnb <= old_sgnb;
+ tmp := mult_result;
+ if mult_busy = '0' then
+ next_state <= WAIT_NONE;
+ end if;
+ when WAIT_DIV =>
+ sgna <= old_sgna;
+ sgnb <= old_sgnb;
+ if sgna = sgnb then
+ tmp(REG_WIDTH-1 downto 0) := udiv_result;
+ else
+ tmp(REG_WIDTH-1 downto 0) := std_logic_vector(-signed(udiv_result));
+ end if;
+ if udiv_busy = '0' then
+ next_state <= WAIT_NONE;
+ end if;
+ when WAIT_UDIV =>
+ sgna <= old_sgna;
+ sgnb <= old_sgnb;
+ tmp(REG_WIDTH-1 downto 0) := udiv_result;
+ if udiv_busy = '0' then
+ next_state <= WAIT_NONE;
+ end if;
+ when WAIT_MOD =>
+ sgna <= old_sgna;
+ sgnb <= old_sgnb;
+ if sgna = sgnb then
+ tmp(REG_WIDTH-1 downto 0) := umod_result;
+ else
+ tmp(REG_WIDTH-1 downto 0) := std_logic_vector(-signed(umod_result));
+ end if;
+ if udiv_busy = '0' then
+ next_state <= WAIT_NONE;
+ end if;
+ when WAIT_UMOD =>
+ sgna <= old_sgna;
+ sgnb <= old_sgnb;
+ tmp(REG_WIDTH-1 downto 0) := umod_result;
+ if udiv_busy = '0' then
+ next_state <= WAIT_NONE;
+ end if;
+ when WAIT_NONE =>
+ case op is
+ when ALU_ADD => adder_op1 <= std_logic_vector(resize(unsigned(a), REG_WIDTH+1));
+ adder_op2 <= std_logic_vector(resize(unsigned(b), REG_WIDTH+1));
+ tmp := adder_result;
+ when ALU_SUB => adder_op1 <= std_logic_vector(resize(unsigned(a), REG_WIDTH+1));
+ adder_op2 <= not std_logic_vector(resize(unsigned(b), REG_WIDTH+1));
+ adder_op3 <= '1';
+ tmp := adder_result;
+ when ALU_ADDC => adder_op1 <= std_logic_vector(resize(unsigned(a), REG_WIDTH+1));
+ adder_op2 <= std_logic_vector(resize(unsigned(b), REG_WIDTH+1));
+ adder_op3 <= flags(FLAG_C);
+ tmp := adder_result;
+ when ALU_SUBC => adder_op1 <= std_logic_vector(resize(unsigned(a), REG_WIDTH+1));
+ adder_op2 <= not std_logic_vector(resize(unsigned(b), REG_WIDTH+1));
+ adder_op3 <= not flags(FLAG_C);
+ tmp := adder_result;
+ when ALU_AND => tmp(REG_WIDTH-1 downto 0) := a and b;
+ when ALU_OR => tmp(REG_WIDTH-1 downto 0) := a or b;
+ when ALU_XOR => tmp(REG_WIDTH-1 downto 0) := a xor b;
+-------------------------------------------------------------------------------
+ when ALU_MUL => mult_trigger <= '1';
+ mult_op1 <= a;
+ mult_op2 <= b;
+ next_state <= WAIT_MULT;
+ when ALU_DIV => udiv_trigger <= '1';
+ udiv_op1 <= std_logic_vector(abs(signed(a)));
+ udiv_op2 <= std_logic_vector(abs(signed(b)));
+ next_state <= WAIT_DIV;
+ when ALU_UDIV => udiv_trigger <= '1';
+ udiv_op1 <= a;
+ udiv_op2 <= b;
+ next_state <= WAIT_UDIV;
+ when ALU_MOD => udiv_trigger <= '1';
+ udiv_op1 <= std_logic_vector(abs(signed(a)));
+ udiv_op2 <= std_logic_vector(abs(signed(b)));
+ next_state <= WAIT_MOD;
+ when ALU_UMOD => udiv_trigger <= '1';
+ udiv_op1 <= a;
+ udiv_op2 <= b;
+ next_state <= WAIT_UMOD;
+-------------------------------------------------------------------------------
+ when ALU_LDIL => tmp(REG_WIDTH-1 downto 0) := a(REG_WIDTH-1 downto REG_WIDTH/2) & i(REG_WIDTH/2-1 downto 0);
+ when ALU_LDIH => tmp(REG_WIDTH-1 downto 0) := i(REG_WIDTH/2-1 downto 0) & a(REG_WIDTH/2-1 downto 0);
+ when ALU_LDIB => tmp(REG_WIDTH-1 downto 0) := i;
+-------------------------------------------------------------------------------
+ when ALU_MOV => tmp(REG_WIDTH-1 downto 0) := b;
+ when ALU_NOT => tmp(REG_WIDTH-1 downto 0) := not b;
+ when ALU_NEG => adder_op1 <= (others => '0');
+ adder_op2 <= not std_logic_vector(resize(unsigned(b), REG_WIDTH+1));
+ adder_op3 <= '1';
+ tmp := adder_result;
+ when ALU_ADDI => adder_op1 <= std_logic_vector(resize(unsigned(a), REG_WIDTH+1));
+ adder_op2 <= std_logic_vector(resize(unsigned(i), REG_WIDTH+1));
+ tmp := adder_result;
+ sgnb <= i(REG_WIDTH-1);
+ when ALU_CMPI => adder_op1 <= std_logic_vector(resize(unsigned(a), REG_WIDTH+1));
+ adder_op2 <= not std_logic_vector(resize(unsigned(i), REG_WIDTH+1));
+ adder_op3 <= '1';
+ tmp := adder_result;
+ sgnb <= i(REG_WIDTH-1);
+ when ALU_SHL => tmp := shift_left (std_logic_vector(resize(unsigned(a), REG_WIDTH+1)), b);
+ when ALU_SHR => tmp := shift_right (std_logic_vector(resize(unsigned(a), REG_WIDTH+1)), b);
+ when ALU_SAR => tmp := shift_aright (std_logic_vector(resize( signed(a), REG_WIDTH+1)), b);
+ when ALU_ROLC => tmp := rotate_left (std_logic_vector(resize(unsigned(a), REG_WIDTH+1)), b(REG_WIDTH_LOG-1 downto 0), flags(FLAG_C));
+ when ALU_RORC => tmp := rotate_right (std_logic_vector(resize(unsigned(a), REG_WIDTH+1)), b(REG_WIDTH_LOG-1 downto 0), flags(FLAG_C));
+ when ALU_BSET => tmp(REG_WIDTH-1 downto 0) := a; tmp(to_integer(unsigned(i))) := '1';
+ when ALU_BCLR => tmp(REG_WIDTH-1 downto 0) := a; tmp(to_integer(unsigned(i))) := '0';
+ when ALU_BTEST => tmp := (others => '0'); tmp(0) := a(to_integer(unsigned(i)));
+ when ALU_SEXT => tmp(REG_WIDTH-1 downto 0) := std_logic_vector(resize(signed(a(REG_WIDTH/2-1 downto 0)), REG_WIDTH));
+-------------------------------------------------------------------------------
+ when ALU_BRZ => adder_op1 <= std_logic_vector(resize(unsigned(pc), REG_WIDTH+1));
+ if flags(FLAG_Z) = '1' then
+ adder_op2 <= std_logic_vector(resize(unsigned(i), REG_WIDTH+1));
+ pcchg <= '1';
+ end if;
+ tmp := adder_result;
+ wr_flags := '0';
+ when ALU_BRNZ => adder_op1 <= std_logic_vector(resize(unsigned(pc), REG_WIDTH+1));
+ if flags(FLAG_Z) = '0' then
+ adder_op2 <= std_logic_vector(resize(unsigned(i), REG_WIDTH+1));
+ pcchg <= '1';
+ end if;
+ tmp := adder_result;
+ wr_flags := '0';
+ when ALU_BRLE => adder_op1 <= std_logic_vector(resize(unsigned(pc), REG_WIDTH+1));
+ if flags(FLAG_Z) = '1' or flags(FLAG_N) /= flags(FLAG_V) then
+ adder_op2 <= std_logic_vector(resize(unsigned(i), REG_WIDTH+1));
+ pcchg <= '1';
+ end if;
+ tmp := adder_result;
+ wr_flags := '0';
+ when ALU_BRLT => adder_op1 <= std_logic_vector(resize(unsigned(pc), REG_WIDTH+1));
+ if flags(FLAG_Z) = '0' and flags(FLAG_N) /= flags(FLAG_V) then
+ adder_op2 <= std_logic_vector(resize(unsigned(i), REG_WIDTH+1));
+ pcchg <= '1';
+ end if;
+ tmp := adder_result;
+ wr_flags := '0';
+ when ALU_BRGE => adder_op1 <= std_logic_vector(resize(unsigned(pc), REG_WIDTH+1));
+ if flags(FLAG_Z) = '1' or flags(FLAG_N) = flags(FLAG_V) then
+ adder_op2 <= std_logic_vector(resize(unsigned(i), REG_WIDTH+1));
+ pcchg <= '1';
+ end if;
+ tmp := adder_result;
+ wr_flags := '0';
+ when ALU_BRGT => adder_op1 <= std_logic_vector(resize(unsigned(pc), REG_WIDTH+1));
+ if flags(FLAG_Z) = '0' and flags(FLAG_N) = flags(FLAG_V) then
+ adder_op2 <= std_logic_vector(resize(unsigned(i), REG_WIDTH+1));
+ pcchg <= '1';
+ end if;
+ tmp := adder_result;
+ wr_flags := '0';
+ when ALU_BRULE => adder_op1 <= std_logic_vector(resize(unsigned(pc), REG_WIDTH+1));
+ if flags(FLAG_Z) = '1' or flags(FLAG_C) = '1' then
+ adder_op2 <= std_logic_vector(resize(unsigned(i), REG_WIDTH+1));
+ pcchg <= '1';
+ end if;
+ tmp := adder_result;
+ wr_flags := '0';
+ when ALU_BRULT => adder_op1 <= std_logic_vector(resize(unsigned(pc), REG_WIDTH+1));
+ if flags(FLAG_Z) = '0' and flags(FLAG_C) = '1' then
+ adder_op2 <= std_logic_vector(resize(unsigned(i), REG_WIDTH+1));
+ pcchg <= '1';
+ end if;
+ tmp := adder_result;
+ wr_flags := '0';
+ when ALU_BRUGE => adder_op1 <= std_logic_vector(resize(unsigned(pc), REG_WIDTH+1));
+ if flags(FLAG_Z) = '1' or flags(FLAG_C) = '0' then
+ adder_op2 <= std_logic_vector(resize(unsigned(i), REG_WIDTH+1));
+ pcchg <= '1';
+ end if;
+ tmp := adder_result;
+ wr_flags := '0';
+ when ALU_BRUGT => adder_op1 <= std_logic_vector(resize(unsigned(pc), REG_WIDTH+1));
+ if flags(FLAG_Z) = '0' and flags(FLAG_C) = '0' then
+ adder_op2 <= std_logic_vector(resize(unsigned(i), REG_WIDTH+1));
+ pcchg <= '1';
+ end if;
+ tmp := adder_result;
+ wr_flags := '0';
+-------------------------------------------------------------------------------
+ when ALU_JMP => tmp(REG_WIDTH-1 downto 0) := a;
+ pcchg <= '1';
+ wr_flags := '0';
+ when ALU_JMPZ => if flags(FLAG_Z) = '1' then
+ tmp(REG_WIDTH-1 downto 0) := a;
+ pcchg <= '1';
+ else
+ tmp(REG_WIDTH-1 downto 0) := pc;
+ end if;
+ wr_flags := '0';
+ when ALU_JMPNZ => if flags(FLAG_Z) = '0' then
+ tmp(REG_WIDTH-1 downto 0) := a;
+ pcchg <= '1';
+ else
+ tmp(REG_WIDTH-1 downto 0) := pc;
+ end if;
+ wr_flags := '0';
+ when ALU_JMPLE => if flags(FLAG_Z) = '1' or flags(FLAG_N) /= flags(FLAG_V) then
+ tmp(REG_WIDTH-1 downto 0) := a;
+ pcchg <= '1';
+ else
+ tmp(REG_WIDTH-1 downto 0) := pc;
+ end if;
+ wr_flags := '0';
+ when ALU_JMPLT => if flags(FLAG_Z) = '0' and flags(FLAG_N) /= flags(FLAG_V) then
+ tmp(REG_WIDTH-1 downto 0) := a;
+ pcchg <= '1';
+ else
+ tmp(REG_WIDTH-1 downto 0) := pc;
+ end if;
+ wr_flags := '0';
+ when ALU_JMPGE => if flags(FLAG_Z) = '1' or flags(FLAG_N) = flags(FLAG_V) then
+ tmp(REG_WIDTH-1 downto 0) := a;
+ pcchg <= '1';
+ else
+ tmp(REG_WIDTH-1 downto 0) := pc;
+ end if;
+ wr_flags := '0';
+ when ALU_JMPGT => if flags(FLAG_Z) = '0' and flags(FLAG_N) = flags(FLAG_V) then
+ tmp(REG_WIDTH-1 downto 0) := a;
+ pcchg <= '1';
+ else
+ tmp(REG_WIDTH-1 downto 0) := pc;
+ end if;
+ wr_flags := '0';
+ when ALU_JMPULE => if flags(FLAG_Z) = '1' or flags(FLAG_C) = '1' then
+ tmp(REG_WIDTH-1 downto 0) := a;
+ pcchg <= '1';
+ else
+ tmp(REG_WIDTH-1 downto 0) := pc;
+ end if;
+ wr_flags := '0';
+ when ALU_JMPULT => if flags(FLAG_Z) = '0' and flags(FLAG_C) = '1' then
+ tmp(REG_WIDTH-1 downto 0) := a;
+ pcchg <= '1';
+ else
+ tmp(REG_WIDTH-1 downto 0) := pc;
+ end if;
+ wr_flags := '0';
+ when ALU_JMPUGE => if flags(FLAG_Z) = '1' or flags(FLAG_C) = '0' then
+ tmp(REG_WIDTH-1 downto 0) := a;
+ pcchg <= '1';
+ else
+ tmp(REG_WIDTH-1 downto 0) := pc;
+ end if;
+ wr_flags := '0';
+ when ALU_JMPUGT => if flags(FLAG_Z) = '0' and flags(FLAG_C) = '0' then
+ tmp(REG_WIDTH-1 downto 0) := a;
+ pcchg <= '1';
+ else
+ tmp(REG_WIDTH-1 downto 0) := pc;
+ end if;
+ wr_flags := '0';
+-------------------------------------------------------------------------------
+ when ALU_GETFL => tmp(REG_WIDTH-1 downto 0) := flags;
+ wr_flags := '0';
+ when ALU_SETFL => next_flags <= a;
+ wr_flags := '0';
+ when ALU_GETSHFL => tmp(REG_WIDTH-1 downto 0) := shflags;
+ wr_flags := '0';
+ when ALU_SETSHFL => next_shflags <= a;
+ wr_flags := '0';
+ when ALU_INTR => next_shflags <= flags;
+ next_flags(FLAG_I) <= '0';
+ wr_flags := '0';
+ when ALU_RETI => next_flags <= shflags;
+ wr_flags := '0';
+ when ALU_SEI => next_flags(FLAG_I) <= '1';
+ wr_flags := '0';
+ when ALU_CLI => next_flags(FLAG_I) <= '0';
+ wr_flags := '0';
+-------------------------------------------------------------------------------
+ when ALU_NOP => wr_flags := '0';
+ when others => null;
+ end case;
+ when others => null;
+ end case;
+
+ -- if the result is to be ignored, it will be ignored in the write-back stage
+ result <= tmp(REG_WIDTH-1 downto 0);
+
+ -- the flags do not make sense with all instructions yet
+ if wr_flags = '1' then
+ next_flags(FLAG_C) <= tmp(REG_WIDTH);
+ next_flags(FLAG_N) <= tmp(REG_WIDTH-1);
+ next_flags(FLAG_Z) <= zero(tmp(REG_WIDTH-1 downto 0));
+ next_flags(FLAG_V) <= sgna xor sgnb xor tmp(REG_WIDTH) xor tmp(REG_WIDTH-1);
+ next_flags(FLAG_P) <= parity(tmp(REG_WIDTH-1 downto 0));
+ end if;
+
+ if intr = '1' then
+ next_shflags <= flags;
+ next_flags(FLAG_I) <= '0';
+ end if;
+
+ end process compute;
+
+end behaviour;
Index: trunk/vhdl/decode.vhd
===================================================================
--- trunk/vhdl/decode.vhd (nonexistent)
+++ trunk/vhdl/decode.vhd (revision 2)
@@ -0,0 +1,690 @@
+-- This file is part of the marca processor.
+-- Copyright (C) 2007 Wolfgang Puffitsch
+
+-- This program is free software; you can redistribute it and/or modify it
+-- under the terms of the GNU Library 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
+-- Library General Public License for more details.
+
+-- You should have received a copy of the GNU Library 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
+
+-------------------------------------------------------------------------------
+-- MARCA decode stage
+-------------------------------------------------------------------------------
+-- architecture for the instruction-decode pipeline stage
+-------------------------------------------------------------------------------
+
+-------------------------------------------------------------------------------
+-- Wolfgang Puffitsch
+-- Computer Architecture Lab, Group 3
+-------------------------------------------------------------------------------
+
+library IEEE;
+use IEEE.std_logic_1164.all;
+use IEEE.numeric_std.all;
+
+use work.marca_pkg.all;
+
+architecture behaviour of decode is
+
+signal pc_reg : std_logic_vector(REG_WIDTH-1 downto 0);
+signal dest_reg : std_logic_vector(REG_COUNT_LOG-1 downto 0);
+signal instr_reg : std_logic_vector(PDATA_WIDTH-1 downto 0);
+
+signal src1_reg : std_logic_vector(REG_COUNT_LOG-1 downto 0);
+signal src2_reg : std_logic_vector(REG_COUNT_LOG-1 downto 0);
+
+component regfile is
+ port (
+ clock : in std_logic;
+ reset : in std_logic;
+ hold : in std_logic;
+ rd1_addr : in std_logic_vector(REG_COUNT_LOG-1 downto 0);
+ rd2_addr : in std_logic_vector(REG_COUNT_LOG-1 downto 0);
+ rd1_val : out std_logic_vector(REG_WIDTH-1 downto 0);
+ rd2_val : out std_logic_vector(REG_WIDTH-1 downto 0);
+ wr_ena : in std_logic;
+ wr_addr : in std_logic_vector(REG_COUNT_LOG-1 downto 0);
+ wr_val : in std_logic_vector(REG_WIDTH-1 downto 0));
+end component;
+
+begin -- behaviour
+
+ regfile_unit : regfile
+ port map (
+ clock => clock,
+ reset => reset,
+ hold => hold,
+ rd1_addr => src1_reg,
+ rd2_addr => src2_reg,
+ rd1_val => op1,
+ rd2_val => op2,
+ wr_ena => wr_ena,
+ wr_addr => wr_dest,
+ wr_val => wr_val);
+
+ syn_proc: process (clock, reset)
+ begin -- process syn_proc
+ if reset = RESET_ACTIVE then -- asynchronous reset (active low)
+ pc_reg <= (others => '0');
+ dest_reg <= (others => '0');
+ instr_reg <= OPC_PFX_C & OPC_PFX_C2 & OPC_PFX_C2a & OPC_NOP;
+ src1_reg <= (others => '0');
+ src2_reg <= (others => '0');
+ elsif clock'event and clock = '1' then -- rising clock edge
+ if hold = '0' then
+ if stall = '1' then
+ pc_reg <= (others => '0');
+ dest_reg <= (others => '0');
+ instr_reg <= OPC_PFX_C & OPC_PFX_C2 & OPC_PFX_C2a & OPC_NOP;
+ src1_reg <= (others => '0');
+ src2_reg <= (others => '0');
+ else
+ pc_reg <= pc_in;
+ dest_reg <= dest_in;
+ instr_reg <= instr;
+ src1_reg <= src1_in;
+ src2_reg <= src2_in;
+ end if;
+ end if;
+ end if;
+ end process syn_proc;
+
+ feedthrough: process (pc_reg, src1_reg, src2_reg)
+ begin -- process feedthrough
+ pc_out <= pc_reg;
+ src1_out <= src1_reg;
+ src2_out <= src2_reg;
+ end process feedthrough;
+
+ do_decode: process (instr_reg, src1_reg, src2_reg, dest_reg)
+ begin -- process
+
+ -- all unknown opcodes trigger interrupt EXC_ERR
+ imm <= std_logic_vector(to_unsigned(EXC_ERR, REG_WIDTH));
+ dest_out <= dest_reg;
+ aop <= ALU_INTR;
+ mop <= MEM_NOP;
+ iop <= INTR_INTR;
+ unit <= UNIT_INTR;
+ target <= TARGET_PC;
+
+ case instr_reg(PDATA_WIDTH-1 downto PDATA_WIDTH-4) is
+ when
+ OPC_ADD => aop <= ALU_ADD;
+ mop <= MEM_NOP;
+ iop <= INTR_NOP;
+ unit <= UNIT_ALU;
+ target <= TARGET_REGISTER;
+ dest_out <= dest_reg;
+ when
+ OPC_SUB => aop <= ALU_SUB;
+ mop <= MEM_NOP;
+ iop <= INTR_NOP;
+ unit <= UNIT_ALU;
+ target <= TARGET_REGISTER;
+ dest_out <= dest_reg;
+ when
+ OPC_ADDC => aop <= ALU_ADDC;
+ mop <= MEM_NOP;
+ iop <= INTR_NOP;
+ unit <= UNIT_ALU;
+ target <= TARGET_REGISTER;
+ dest_out <= dest_reg;
+ when
+ OPC_SUBC => aop <= ALU_SUBC;
+ mop <= MEM_NOP;
+ iop <= INTR_NOP;
+ unit <= UNIT_ALU;
+ target <= TARGET_REGISTER;
+ dest_out <= dest_reg;
+ when
+ OPC_AND => aop <= ALU_AND;
+ mop <= MEM_NOP;
+ iop <= INTR_NOP;
+ unit <= UNIT_ALU;
+ target <= TARGET_REGISTER;
+ dest_out <= dest_reg;
+ when
+ OPC_OR => aop <= ALU_OR;
+ mop <= MEM_NOP;
+ iop <= INTR_NOP;
+ unit <= UNIT_ALU;
+ target <= TARGET_REGISTER;
+ dest_out <= dest_reg;
+ when
+ OPC_XOR => aop <= ALU_XOR;
+ mop <= MEM_NOP;
+ iop <= INTR_NOP;
+ unit <= UNIT_ALU;
+ target <= TARGET_REGISTER;
+ dest_out <= dest_reg;
+ when
+ OPC_MUL => aop <= ALU_MUL;
+ mop <= MEM_NOP;
+ iop <= INTR_NOP;
+ unit <= UNIT_ALU;
+ target <= TARGET_REGISTER;
+ dest_out <= dest_reg;
+ when
+ OPC_DIV => aop <= ALU_DIV;
+ mop <= MEM_NOP;
+ iop <= INTR_NOP;
+ unit <= UNIT_ALU;
+ target <= TARGET_REGISTER;
+ dest_out <= dest_reg;
+ when
+ OPC_UDIV => aop <= ALU_UDIV;
+ mop <= MEM_NOP;
+ iop <= INTR_NOP;
+ unit <= UNIT_ALU;
+ target <= TARGET_REGISTER;
+ dest_out <= dest_reg;
+ when
+ OPC_LDIL => imm <= std_logic_vector(resize(signed(dest_reg & src2_reg), REG_WIDTH));
+ aop <= ALU_LDIL;
+ mop <= MEM_NOP;
+ iop <= INTR_NOP;
+ unit <= UNIT_ALU;
+ target <= TARGET_REGISTER;
+ dest_out <= src1_reg;
+ when
+ OPC_LDIH => imm <= std_logic_vector(resize(signed(dest_reg & src2_reg), REG_WIDTH));
+ aop <= ALU_LDIH;
+ mop <= MEM_NOP;
+ iop <= INTR_NOP;
+ unit <= UNIT_ALU;
+ target <= TARGET_REGISTER;
+ dest_out <= src1_reg;
+ when
+ OPC_LDIB => imm <= std_logic_vector(resize(signed(dest_reg & src2_reg), REG_WIDTH));
+ aop <= ALU_LDIB;
+ mop <= MEM_NOP;
+ iop <= INTR_NOP;
+ unit <= UNIT_ALU;
+ target <= TARGET_REGISTER;
+ dest_out <= src1_reg;
+
+ when
+ OPC_PFX_A =>
+ case instr_reg(PDATA_WIDTH-5 downto PDATA_WIDTH-8) is
+ when
+ OPC_MOV => aop <= ALU_MOV;
+ mop <= MEM_NOP;
+ iop <= INTR_NOP;
+ unit <= UNIT_ALU;
+ target <= TARGET_REGISTER;
+ dest_out <= src1_reg;
+ when
+ OPC_MOD => aop <= ALU_MOD;
+ mop <= MEM_NOP;
+ iop <= INTR_NOP;
+ unit <= UNIT_ALU;
+ target <= TARGET_REGISTER;
+ dest_out <= src1_reg;
+ when
+ OPC_UMOD => aop <= ALU_UMOD;
+ mop <= MEM_NOP;
+ iop <= INTR_NOP;
+ unit <= UNIT_ALU;
+ target <= TARGET_REGISTER;
+ dest_out <= src1_reg;
+ when
+ OPC_NOT => aop <= ALU_NOT;
+ mop <= MEM_NOP;
+ iop <= INTR_NOP;
+ unit <= UNIT_ALU;
+ target <= TARGET_REGISTER;
+ dest_out <= src1_reg;
+ when
+ OPC_NEG => aop <= ALU_NEG;
+ mop <= MEM_NOP;
+ iop <= INTR_NOP;
+ unit <= UNIT_ALU;
+ target <= TARGET_REGISTER;
+ dest_out <= src1_reg;
+ when
+ OPC_CMP => aop <= ALU_SUB; -- it's the same
+ mop <= MEM_NOP;
+ iop <= INTR_NOP;
+ unit <= UNIT_ALU;
+ target <= TARGET_NONE;
+ dest_out <= src1_reg;
+ when
+ OPC_ADDI => imm <= std_logic_vector(resize(signed(src2_reg), REG_WIDTH));
+ aop <= ALU_ADDI;
+ mop <= MEM_NOP;
+ iop <= INTR_NOP;
+ unit <= UNIT_ALU;
+ target <= TARGET_REGISTER;
+ dest_out <= src1_reg;
+ when
+ OPC_CMPI => imm <= std_logic_vector(resize(signed(src2_reg), REG_WIDTH));
+ aop <= ALU_CMPI;
+ mop <= MEM_NOP;
+ iop <= INTR_NOP;
+ unit <= UNIT_ALU;
+ target <= TARGET_NONE;
+ dest_out <= src1_reg;
+ when
+ OPC_SHL => aop <= ALU_SHL;
+ mop <= MEM_NOP;
+ iop <= INTR_NOP;
+ unit <= UNIT_ALU;
+ target <= TARGET_REGISTER;
+ dest_out <= src1_reg;
+ when
+ OPC_SHR => aop <= ALU_SHR;
+ mop <= MEM_NOP;
+ iop <= INTR_NOP;
+ unit <= UNIT_ALU;
+ target <= TARGET_REGISTER;
+ dest_out <= src1_reg;
+ when
+ OPC_SAR => aop <= ALU_SAR;
+ mop <= MEM_NOP;
+ iop <= INTR_NOP;
+ unit <= UNIT_ALU;
+ target <= TARGET_REGISTER;
+ dest_out <= src1_reg;
+ when
+ OPC_ROLC => aop <= ALU_ROLC;
+ mop <= MEM_NOP;
+ iop <= INTR_NOP;
+ unit <= UNIT_ALU;
+ target <= TARGET_REGISTER;
+ dest_out <= src1_reg;
+ when
+ OPC_RORC => aop <= ALU_RORC;
+ mop <= MEM_NOP;
+ iop <= INTR_NOP;
+ unit <= UNIT_ALU;
+ target <= TARGET_REGISTER;
+ dest_out <= src1_reg;
+ when
+ OPC_BSET => imm <= std_logic_vector(resize(unsigned(src2_reg), REG_WIDTH));
+ aop <= ALU_BSET;
+ mop <= MEM_NOP;
+ iop <= INTR_NOP;
+ unit <= UNIT_ALU;
+ target <= TARGET_REGISTER;
+ dest_out <= src1_reg;
+ when
+ OPC_BCLR => imm <= std_logic_vector(resize(unsigned(src2_reg), REG_WIDTH));
+ aop <= ALU_BCLR;
+ mop <= MEM_NOP;
+ iop <= INTR_NOP;
+ unit <= UNIT_ALU;
+ target <= TARGET_REGISTER;
+ dest_out <= src1_reg;
+ when
+ OPC_BTEST => imm <= std_logic_vector(resize(unsigned(src2_reg), REG_WIDTH));
+ aop <= ALU_BTEST;
+ mop <= MEM_NOP;
+ iop <= INTR_NOP;
+ unit <= UNIT_ALU;
+ target <= TARGET_NONE;
+ dest_out <= src1_reg;
+ when others => null;
+ end case;
+
+ when OPC_PFX_B =>
+ case instr_reg(PDATA_WIDTH-5 downto PDATA_WIDTH-8) is
+ when
+ OPC_LOAD => mop <= MEM_LOAD;
+ aop <= ALU_NOP;
+ iop <= INTR_NOP;
+ unit <= UNIT_MEM;
+ target <= TARGET_REGISTER;
+ dest_out <= src1_reg;
+ when
+ OPC_LOADL => mop <= MEM_LOADL;
+ aop <= ALU_NOP;
+ iop <= INTR_NOP;
+ unit <= UNIT_MEM;
+ target <= TARGET_REGISTER;
+ dest_out <= src1_reg;
+ when
+ OPC_LOADH => mop <= MEM_LOADH;
+ aop <= ALU_NOP;
+ iop <= INTR_NOP;
+ unit <= UNIT_MEM;
+ target <= TARGET_REGISTER;
+ dest_out <= src1_reg;
+ when
+ OPC_LOADB => mop <= MEM_LOADB;
+ aop <= ALU_NOP;
+ iop <= INTR_NOP;
+ unit <= UNIT_MEM;
+ target <= TARGET_REGISTER;
+ dest_out <= src1_reg;
+ when
+ OPC_STORE => mop <= MEM_STORE;
+ aop <= ALU_NOP;
+ iop <= INTR_NOP;
+ unit <= UNIT_MEM;
+ target <= TARGET_NONE;
+ dest_out <= src1_reg;
+ when
+ OPC_STOREL => mop <= MEM_STOREL;
+ aop <= ALU_NOP;
+ iop <= INTR_NOP;
+ unit <= UNIT_MEM;
+ target <= TARGET_NONE;
+ dest_out <= src1_reg;
+ when
+ OPC_STOREH => mop <= MEM_STOREH;
+ aop <= ALU_NOP;
+ iop <= INTR_NOP;
+ unit <= UNIT_MEM;
+ target <= TARGET_NONE;
+ dest_out <= src1_reg;
+ when
+ OPC_CALL => aop <= ALU_JMP; -- force alu_pcchg
+ mop <= MEM_NOP;
+ iop <= INTR_NOP;
+ unit <= UNIT_CALL;
+ target <= TARGET_BOTH;
+ dest_out <= src1_reg;
+ when others => null;
+ end case;
+
+ when OPC_PFX_C =>
+ case instr_reg(PDATA_WIDTH-5 downto PDATA_WIDTH-8) is
+ when
+ OPC_BR => aop <= ALU_NOP;
+ mop <= MEM_NOP;
+ iop <= INTR_NOP;
+ unit <= UNIT_ALU;
+ target <= TARGET_NONE;
+ dest_out <= src1_reg;
+ when
+ OPC_BRZ => imm <= std_logic_vector(resize(signed(src2_reg & src1_reg), REG_WIDTH));
+ aop <= ALU_BRZ;
+ mop <= MEM_NOP;
+ iop <= INTR_NOP;
+ unit <= UNIT_ALU;
+ target <= TARGET_PC;
+ dest_out <= src1_reg;
+ when
+ OPC_BRNZ => imm <= std_logic_vector(resize(signed(src2_reg & src1_reg), REG_WIDTH));
+ aop <= ALU_BRNZ;
+ mop <= MEM_NOP;
+ iop <= INTR_NOP;
+ unit <= UNIT_ALU;
+ target <= TARGET_PC;
+ dest_out <= src1_reg;
+ when
+ OPC_BRLE => imm <= std_logic_vector(resize(signed(src2_reg & src1_reg), REG_WIDTH));
+ aop <= ALU_BRLE;
+ mop <= MEM_NOP;
+ iop <= INTR_NOP;
+ unit <= UNIT_ALU;
+ target <= TARGET_PC;
+ dest_out <= src1_reg;
+ when
+ OPC_BRLT => imm <= std_logic_vector(resize(signed(src2_reg & src1_reg), REG_WIDTH));
+ aop <= ALU_BRLT;
+ mop <= MEM_NOP;
+ iop <= INTR_NOP;
+ unit <= UNIT_ALU;
+ target <= TARGET_PC;
+ dest_out <= src1_reg;
+ when
+ OPC_BRGE => imm <= std_logic_vector(resize(signed(src2_reg & src1_reg), REG_WIDTH));
+ aop <= ALU_BRGE;
+ mop <= MEM_NOP;
+ iop <= INTR_NOP;
+ unit <= UNIT_ALU;
+ target <= TARGET_PC;
+ dest_out <= src1_reg;
+ when
+ OPC_BRGT => imm <= std_logic_vector(resize(signed(src2_reg & src1_reg), REG_WIDTH));
+ aop <= ALU_BRGT;
+ mop <= MEM_NOP;
+ iop <= INTR_NOP;
+ unit <= UNIT_ALU;
+ target <= TARGET_PC;
+ dest_out <= src1_reg;
+ when
+ OPC_BRULE => imm <= std_logic_vector(resize(signed(src2_reg & src1_reg), REG_WIDTH));
+ aop <= ALU_BRULE;
+ mop <= MEM_NOP;
+ iop <= INTR_NOP;
+ unit <= UNIT_ALU;
+ target <= TARGET_PC;
+ dest_out <= src1_reg;
+ when
+ OPC_BRULT => imm <= std_logic_vector(resize(signed(src2_reg & src1_reg), REG_WIDTH));
+ aop <= ALU_BRULT;
+ mop <= MEM_NOP;
+ iop <= INTR_NOP;
+ unit <= UNIT_ALU;
+ target <= TARGET_PC;
+ dest_out <= src1_reg;
+ when
+ OPC_BRUGE => imm <= std_logic_vector(resize(signed(src2_reg & src1_reg), REG_WIDTH));
+ aop <= ALU_BRUGE;
+ mop <= MEM_NOP;
+ iop <= INTR_NOP;
+ unit <= UNIT_ALU;
+ target <= TARGET_PC;
+ dest_out <= src1_reg;
+ when
+ OPC_BRUGT => imm <= std_logic_vector(resize(signed(src2_reg & src1_reg), REG_WIDTH));
+ aop <= ALU_BRUGT;
+ mop <= MEM_NOP;
+ iop <= INTR_NOP;
+ unit <= UNIT_ALU;
+ target <= TARGET_PC;
+ dest_out <= src1_reg;
+ when
+ OPC_SEXT => aop <= ALU_SEXT;
+ mop <= MEM_NOP;
+ iop <= INTR_NOP;
+ unit <= UNIT_ALU;
+ target <= TARGET_REGISTER;
+ dest_out <= src1_reg;
+ when
+ OPC_LDVEC => imm <= std_logic_vector(resize(unsigned(src2_reg), REG_WIDTH));
+ iop <= INTR_LDVEC;
+ aop <= ALU_NOP;
+ mop <= MEM_NOP;
+ unit <= UNIT_INTR;
+ target <= TARGET_REGISTER;
+ dest_out <= src1_reg;
+ when
+ OPC_STVEC => imm <= std_logic_vector(resize(unsigned(src2_reg), REG_WIDTH));
+ iop <= INTR_STVEC;
+ aop <= ALU_NOP;
+ mop <= MEM_NOP;
+ unit <= UNIT_INTR;
+ target <= TARGET_NONE;
+ dest_out <= src1_reg;
+ when
+ OPC_PFX_C1 =>
+ case instr_reg(PDATA_WIDTH-9 downto PDATA_WIDTH-12) is
+ when
+ OPC_JMP => aop <= ALU_JMP;
+ mop <= MEM_NOP;
+ iop <= INTR_NOP;
+ unit <= UNIT_ALU;
+ target <= TARGET_PC;
+ dest_out <= src1_reg;
+ when
+ OPC_JMPZ => aop <= ALU_JMPZ;
+ mop <= MEM_NOP;
+ iop <= INTR_NOP;
+ unit <= UNIT_ALU;
+ target <= TARGET_PC;
+ dest_out <= src1_reg;
+ when
+ OPC_JMPNZ => aop <= ALU_JMPNZ;
+ mop <= MEM_NOP;
+ iop <= INTR_NOP;
+ unit <= UNIT_ALU;
+ target <= TARGET_PC;
+ dest_out <= src1_reg;
+ when
+ OPC_JMPLE => aop <= ALU_JMPLE;
+ mop <= MEM_NOP;
+ iop <= INTR_NOP;
+ unit <= UNIT_ALU;
+ target <= TARGET_PC;
+ dest_out <= src1_reg;
+ when
+ OPC_JMPLT => aop <= ALU_JMPLT;
+ mop <= MEM_NOP;
+ iop <= INTR_NOP;
+ unit <= UNIT_ALU;
+ target <= TARGET_PC;
+ dest_out <= src1_reg;
+ when
+ OPC_JMPGE => aop <= ALU_JMPGE;
+ mop <= MEM_NOP;
+ iop <= INTR_NOP;
+ unit <= UNIT_ALU;
+ target <= TARGET_PC;
+ dest_out <= src1_reg;
+ when
+ OPC_JMPGT => aop <= ALU_JMPGT;
+ mop <= MEM_NOP;
+ iop <= INTR_NOP;
+ unit <= UNIT_ALU;
+ target <= TARGET_PC;
+ dest_out <= src1_reg;
+ when
+ OPC_JMPULE => aop <= ALU_JMPULE;
+ mop <= MEM_NOP;
+ iop <= INTR_NOP;
+ unit <= UNIT_ALU;
+ target <= TARGET_PC;
+ dest_out <= src1_reg;
+ when
+ OPC_JMPULT => aop <= ALU_JMPULT;
+ mop <= MEM_NOP;
+ iop <= INTR_NOP;
+ unit <= UNIT_ALU;
+ target <= TARGET_PC;
+ dest_out <= src1_reg;
+ when
+ OPC_JMPUGE => aop <= ALU_JMPUGE;
+ mop <= MEM_NOP;
+ iop <= INTR_NOP;
+ unit <= UNIT_ALU;
+ target <= TARGET_PC;
+ dest_out <= src1_reg;
+ when
+ OPC_JMPUGT => aop <= ALU_JMPUGT;
+ mop <= MEM_NOP;
+ iop <= INTR_NOP;
+ unit <= UNIT_ALU;
+ target <= TARGET_PC;
+ dest_out <= src1_reg;
+ when
+ OPC_INTR => imm <= std_logic_vector(resize(unsigned(src1_reg), REG_WIDTH));
+ aop <= ALU_INTR;
+ iop <= INTR_INTR;
+ mop <= MEM_NOP;
+ unit <= UNIT_INTR;
+ target <= TARGET_PC;
+ dest_out <= src1_reg;
+ when
+ OPC_GETFL => aop <= ALU_GETFL;
+ mop <= MEM_NOP;
+ iop <= INTR_NOP;
+ unit <= UNIT_ALU;
+ target <= TARGET_REGISTER;
+ dest_out <= src1_reg;
+ when
+ OPC_SETFL => aop <= ALU_SETFL;
+ mop <= MEM_NOP;
+ iop <= INTR_NOP;
+ unit <= UNIT_ALU;
+ target <= TARGET_NONE;
+ dest_out <= src1_reg;
+ when
+ OPC_GETIRA => iop <= INTR_GETIRA;
+ aop <= ALU_NOP;
+ mop <= MEM_NOP;
+ unit <= UNIT_INTR;
+ target <= TARGET_REGISTER;
+ dest_out <= src1_reg;
+
+ when
+ OPC_SETIRA => iop <= INTR_SETIRA;
+ aop <= ALU_NOP;
+ mop <= MEM_NOP;
+ unit <= UNIT_INTR;
+ target <= TARGET_NONE;
+ dest_out <= src1_reg;
+ when others => null;
+ end case;
+
+ when
+ OPC_PFX_C2 =>
+ case instr_reg(PDATA_WIDTH-9 downto PDATA_WIDTH-12) is
+ when
+ OPC_GETSHFL => aop <= ALU_GETSHFL;
+ mop <= MEM_NOP;
+ iop <= INTR_NOP;
+ unit <= UNIT_ALU;
+ target <= TARGET_REGISTER;
+ dest_out <= src1_reg;
+ when
+ OPC_SETSHFL => aop <= ALU_SETSHFL;
+ mop <= MEM_NOP;
+ iop <= INTR_NOP;
+ unit <= UNIT_ALU;
+ target <= TARGET_NONE;
+ dest_out <= src1_reg;
+ when
+ OPC_PFX_C2a =>
+ case instr_reg(PDATA_WIDTH-13 downto PDATA_WIDTH-16) is
+ when
+ OPC_RETI => aop <= ALU_RETI;
+ iop <= INTR_RETI;
+ mop <= MEM_NOP;
+ unit <= UNIT_INTR;
+ target <= TARGET_PC;
+ dest_out <= src1_reg;
+ when
+ OPC_NOP => aop <= ALU_NOP;
+ mop <= MEM_NOP;
+ iop <= INTR_NOP;
+ unit <= UNIT_ALU;
+ target <= TARGET_NONE;
+ dest_out <= src1_reg;
+ when
+ OPC_SEI => aop <= ALU_SEI;
+ mop <= MEM_NOP;
+ iop <= INTR_NOP;
+ unit <= UNIT_ALU;
+ target <= TARGET_NONE;
+ dest_out <= src1_reg;
+ when
+ OPC_CLI => aop <= ALU_CLI;
+ mop <= MEM_NOP;
+ iop <= INTR_NOP;
+ unit <= UNIT_ALU;
+ target <= TARGET_NONE;
+ dest_out <= src1_reg;
+ when others => null;
+ end case;
+ when others => null;
+ end case;
+ when others => null;
+ end case;
+ when others => null;
+ end case;
+
+ end process;
+
+end behaviour;
Index: trunk/vhdl/marca.vhd
===================================================================
--- trunk/vhdl/marca.vhd (nonexistent)
+++ trunk/vhdl/marca.vhd (revision 2)
@@ -0,0 +1,288 @@
+-- This file is part of the marca processor.
+-- Copyright (C) 2007 Wolfgang Puffitsch
+
+-- This program is free software; you can redistribute it and/or modify it
+-- under the terms of the GNU Library 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
+-- Library General Public License for more details.
+
+-- You should have received a copy of the GNU Library 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
+
+-------------------------------------------------------------------------------
+-- MARCA top level architecture
+-------------------------------------------------------------------------------
+-- architecture of the processor itself
+-------------------------------------------------------------------------------
+
+-------------------------------------------------------------------------------
+-- Wolfgang Puffitsch
+-- Computer Architecture Lab, Group 3
+-------------------------------------------------------------------------------
+
+library IEEE;
+use IEEE.std_logic_1164.all;
+
+use work.marca_pkg.all;
+
+architecture behaviour of marca is
+
+component fetch
+ port (
+ clock : in std_logic;
+ reset : in std_logic;
+
+ hold : in std_logic;
+
+ pcena : in std_logic;
+ pc_in : in std_logic_vector(REG_WIDTH-1 downto 0);
+ pc_out : out std_logic_vector(REG_WIDTH-1 downto 0);
+
+ src1 : out std_logic_vector(REG_COUNT_LOG-1 downto 0);
+ src2 : out std_logic_vector(REG_COUNT_LOG-1 downto 0);
+ dest : out std_logic_vector(REG_COUNT_LOG-1 downto 0);
+ instr : out std_logic_vector(PDATA_WIDTH-1 downto 0));
+end component;
+
+signal fetch_pc : std_logic_vector(REG_WIDTH-1 downto 0);
+signal fetch_src1 : std_logic_vector(REG_COUNT_LOG-1 downto 0);
+signal fetch_src2 : std_logic_vector(REG_COUNT_LOG-1 downto 0);
+signal fetch_dest : std_logic_vector(REG_COUNT_LOG-1 downto 0);
+signal fetch_instr : std_logic_vector(PDATA_WIDTH-1 downto 0);
+
+component decode
+ port (
+ clock : in std_logic;
+ reset : in std_logic;
+
+ hold : in std_logic;
+ stall : in std_logic;
+
+ pc_in : in std_logic_vector(REG_WIDTH-1 downto 0);
+ pc_out : out std_logic_vector(REG_WIDTH-1 downto 0);
+
+ instr : in std_logic_vector(PDATA_WIDTH-1 downto 0);
+
+ src1_in : in std_logic_vector(REG_COUNT_LOG-1 downto 0);
+ src1_out : out std_logic_vector(REG_COUNT_LOG-1 downto 0);
+ src2_in : in std_logic_vector(REG_COUNT_LOG-1 downto 0);
+ src2_out : out std_logic_vector(REG_COUNT_LOG-1 downto 0);
+
+ dest_in : in std_logic_vector(REG_COUNT_LOG-1 downto 0);
+ dest_out : out std_logic_vector(REG_COUNT_LOG-1 downto 0);
+
+ aop : out ALU_OP;
+ mop : out MEM_OP;
+ iop : out INTR_OP;
+
+ op1 : out std_logic_vector(REG_WIDTH-1 downto 0);
+ op2 : out std_logic_vector(REG_WIDTH-1 downto 0);
+ imm : out std_logic_vector(REG_WIDTH-1 downto 0);
+
+ unit : out UNIT_SELECTOR;
+ target : out TARGET_SELECTOR;
+
+ wr_ena : in std_logic;
+ wr_dest : in std_logic_vector(REG_COUNT_LOG-1 downto 0);
+ wr_val : in std_logic_vector(REG_WIDTH-1 downto 0));
+end component;
+
+signal decode_pc : std_logic_vector(REG_WIDTH-1 downto 0);
+signal decode_op1 : std_logic_vector(REG_WIDTH-1 downto 0);
+signal decode_op2 : std_logic_vector(REG_WIDTH-1 downto 0);
+signal decode_imm : std_logic_vector(REG_WIDTH-1 downto 0);
+signal decode_src1 : std_logic_vector(REG_COUNT_LOG-1 downto 0);
+signal decode_src2 : std_logic_vector(REG_COUNT_LOG-1 downto 0);
+signal decode_dest : std_logic_vector(REG_COUNT_LOG-1 downto 0);
+signal decode_aop : ALU_OP;
+signal decode_mop : MEM_OP;
+signal decode_iop : INTR_OP;
+signal decode_unit : UNIT_SELECTOR;
+signal decode_target : TARGET_SELECTOR;
+signal decode_instr : std_logic_vector(PDATA_WIDTH-1 downto 0);
+
+component execute is
+ port (
+ clock : in std_logic;
+ reset : in std_logic;
+
+ busy : out std_logic;
+ stall : in std_logic;
+
+ pc_in : in std_logic_vector(REG_WIDTH-1 downto 0);
+ pcchg : out std_logic;
+ pc_out : out std_logic_vector(REG_WIDTH-1 downto 0);
+
+ dest_in : in std_logic_vector(REG_COUNT_LOG-1 downto 0);
+ dest_out : out std_logic_vector(REG_COUNT_LOG-1 downto 0);
+
+ src1 : in std_logic_vector(REG_COUNT_LOG-1 downto 0);
+ src2 : in std_logic_vector(REG_COUNT_LOG-1 downto 0);
+
+ aop : in ALU_OP;
+ mop : in MEM_OP;
+ iop : in INTR_OP;
+
+ op1 : in std_logic_vector(REG_WIDTH-1 downto 0);
+ op2 : in std_logic_vector(REG_WIDTH-1 downto 0);
+ imm : in std_logic_vector(REG_WIDTH-1 downto 0);
+
+ unit : in UNIT_SELECTOR;
+ target_in : in TARGET_SELECTOR;
+ target_out : out TARGET_SELECTOR;
+
+ result : out std_logic_vector(REG_WIDTH-1 downto 0);
+
+ fw_ena : in std_logic;
+ fw_dest : in std_logic_vector(REG_COUNT_LOG-1 downto 0);
+ fw_val : in std_logic_vector(REG_WIDTH-1 downto 0);
+
+ ext_in : in std_logic_vector(IN_BITS-1 downto 0);
+ ext_out : out std_logic_vector(OUT_BITS-1 downto 0));
+end component;
+
+signal exec_busy : std_logic;
+signal exec_pcchg : std_logic;
+signal exec_pc : std_logic_vector(REG_WIDTH-1 downto 0);
+signal exec_dest : std_logic_vector(REG_COUNT_LOG-1 downto 0);
+signal exec_target : TARGET_SELECTOR;
+signal exec_result : std_logic_vector(REG_WIDTH-1 downto 0);
+
+component writeback is
+ port (
+ clock : in std_logic;
+ reset : in std_logic;
+
+ hold : in std_logic;
+
+ pc_in : in std_logic_vector(REG_WIDTH-1 downto 0);
+ pcchg : in std_logic;
+ pc_out : out std_logic_vector(REG_WIDTH-1 downto 0);
+ pcena : out std_logic;
+
+ dest_in : in std_logic_vector(REG_COUNT_LOG-1 downto 0);
+ dest_out : out std_logic_vector(REG_COUNT_LOG-1 downto 0);
+
+ target : in TARGET_SELECTOR;
+ result : in std_logic_vector(REG_WIDTH-1 downto 0);
+
+ ena : out std_logic;
+ val : out std_logic_vector(REG_WIDTH-1 downto 0));
+end component;
+
+signal wb_pc : std_logic_vector(REG_WIDTH-1 downto 0);
+signal wb_pcena : std_logic;
+signal wb_dest : std_logic_vector(REG_COUNT_LOG-1 downto 0);
+signal wb_ena : std_logic;
+signal wb_val : std_logic_vector(REG_WIDTH-1 downto 0);
+
+signal decode_stall : std_logic;
+
+signal reset : std_logic;
+signal meta_reset : std_logic;
+
+begin -- behaviour
+
+ -- in the decode and execution stage we need to stall a little earlier
+ decode_stall <= exec_pcchg or wb_pcena;
+
+ fetch_stage : fetch
+ port map (
+ clock => clock,
+ reset => reset,
+ hold => exec_busy,
+ pcena => wb_pcena,
+ pc_in => wb_pc,
+ pc_out => fetch_pc,
+ src1 => fetch_src1,
+ src2 => fetch_src2,
+ dest => fetch_dest,
+ instr => fetch_instr);
+
+ decode_stage : decode
+ port map (
+ clock => clock,
+ reset => reset,
+ hold => exec_busy,
+ stall => decode_stall,
+ pc_in => fetch_pc,
+ pc_out => decode_pc,
+ instr => fetch_instr,
+ src1_in => fetch_src1,
+ src1_out => decode_src1,
+ src2_in => fetch_src2,
+ src2_out => decode_src2,
+ dest_in => fetch_dest,
+ dest_out => decode_dest,
+ aop => decode_aop,
+ mop => decode_mop,
+ iop => decode_iop,
+ op1 => decode_op1,
+ op2 => decode_op2,
+ imm => decode_imm,
+ unit => decode_unit,
+ target => decode_target,
+ wr_ena => wb_ena,
+ wr_dest => wb_dest,
+ wr_val => wb_val);
+
+ execution_stage : execute
+ port map (
+ clock => clock,
+ reset => reset,
+ busy => exec_busy,
+ stall => exec_pcchg,
+ pc_in => decode_pc,
+ pcchg => exec_pcchg,
+ pc_out => exec_pc,
+ dest_in => decode_dest,
+ dest_out => exec_dest,
+ src1 => decode_src1,
+ src2 => decode_src2,
+ aop => decode_aop,
+ mop => decode_mop,
+ iop => decode_iop,
+ op1 => decode_op1,
+ op2 => decode_op2,
+ imm => decode_imm,
+ unit => decode_unit,
+ target_in => decode_target,
+ target_out => exec_target,
+ result => exec_result,
+ fw_ena => wb_ena,
+ fw_dest => wb_dest,
+ fw_val => wb_val,
+ ext_in => ext_in,
+ ext_out => ext_out);
+
+ writeback_stage : writeback
+ port map (
+ clock => clock,
+ reset => reset,
+ hold => exec_busy,
+ pc_in => exec_pc,
+ pcchg => exec_pcchg,
+ pc_out => wb_pc,
+ pcena => wb_pcena,
+ dest_in => exec_dest,
+ dest_out => wb_dest,
+ target => exec_target,
+ result => exec_result,
+ ena => wb_ena,
+ val => wb_val);
+
+ synchronize: process (clock, ext_reset, meta_reset)
+ begin
+ if clock'event and clock = '1' then
+ meta_reset <= ext_reset;
+ reset <= meta_reset;
+ end if;
+ end process synchronize;
+
+end behaviour;
Index: trunk/vhdl/regfile_ent.vhd
===================================================================
--- trunk/vhdl/regfile_ent.vhd (nonexistent)
+++ trunk/vhdl/regfile_ent.vhd (revision 2)
@@ -0,0 +1,48 @@
+-- This file is part of the marca processor.
+-- Copyright (C) 2007 Wolfgang Puffitsch
+
+-- This program is free software; you can redistribute it and/or modify it
+-- under the terms of the GNU Library 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
+-- Library General Public License for more details.
+
+-- You should have received a copy of the GNU Library 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
+
+-------------------------------------------------------------------------------
+-- MARCA decode stage
+-------------------------------------------------------------------------------
+-- entity of the instruction-decode pipeline stage
+-------------------------------------------------------------------------------
+
+-------------------------------------------------------------------------------
+-- Wolfgang Puffitsch
+-- Computer Architecture Lab, Group 3
+-------------------------------------------------------------------------------
+
+library IEEE;
+use IEEE.std_logic_1164.all;
+
+use work.marca_pkg.all;
+
+entity regfile is
+
+ port (
+ clock : in std_logic;
+ reset : in std_logic;
+ hold : in std_logic;
+ rd1_addr : in std_logic_vector(REG_COUNT_LOG-1 downto 0);
+ rd2_addr : in std_logic_vector(REG_COUNT_LOG-1 downto 0);
+ rd1_val : out std_logic_vector(REG_WIDTH-1 downto 0);
+ rd2_val : out std_logic_vector(REG_WIDTH-1 downto 0);
+ wr_ena : in std_logic;
+ wr_addr : in std_logic_vector(REG_COUNT_LOG-1 downto 0);
+ wr_val : in std_logic_vector(REG_WIDTH-1 downto 0));
+
+end regfile;
Index: trunk/vhdl/data_rom.vhd
===================================================================
--- trunk/vhdl/data_rom.vhd (nonexistent)
+++ trunk/vhdl/data_rom.vhd (revision 2)
@@ -0,0 +1,166 @@
+-- megafunction wizard: %ROM: 1-PORT%
+-- GENERATION: STANDARD
+-- VERSION: WM1.0
+-- MODULE: altsyncram
+
+-- ============================================================
+-- File Name: data_rom.vhd
+-- Megafunction Name(s):
+-- altsyncram
+-- ============================================================
+-- ************************************************************
+-- THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE!
+--
+-- 6.0 Build 202 06/20/2006 SP 1 SJ Web Edition
+-- ************************************************************
+
+
+--Copyright (C) 1991-2006 Altera Corporation
+--Your use of Altera Corporation's design tools, logic functions
+--and other software and tools, and its AMPP partner logic
+--functions, and any output files any of the foregoing
+--(including device programming or simulation files), and any
+--associated documentation or information are expressly subject
+--to the terms and conditions of the Altera Program License
+--Subscription Agreement, Altera MegaCore Function License
+--Agreement, or other applicable license agreement, including,
+--without limitation, that your use is for the sole purpose of
+--programming logic devices manufactured by Altera and sold by
+--Altera or its authorized distributors. Please refer to the
+--applicable agreement for further details.
+
+
+LIBRARY ieee;
+USE ieee.std_logic_1164.all;
+
+LIBRARY altera_mf;
+USE altera_mf.all;
+
+ENTITY data_rom IS
+ GENERIC
+ (
+ init_file : STRING
+ );
+ PORT
+ (
+ address : IN STD_LOGIC_VECTOR (6 DOWNTO 0);
+ clken : IN STD_LOGIC ;
+ clock : IN STD_LOGIC ;
+ q : OUT STD_LOGIC_VECTOR (7 DOWNTO 0)
+ );
+END data_rom;
+
+
+ARCHITECTURE SYN OF data_rom IS
+
+ SIGNAL sub_wire0 : STD_LOGIC_VECTOR (7 DOWNTO 0);
+
+
+
+ COMPONENT altsyncram
+ GENERIC (
+ address_aclr_a : STRING;
+ init_file : STRING;
+ intended_device_family : STRING;
+ lpm_hint : STRING;
+ lpm_type : STRING;
+ numwords_a : NATURAL;
+ operation_mode : STRING;
+ outdata_aclr_a : STRING;
+ outdata_reg_a : STRING;
+ widthad_a : NATURAL;
+ width_a : NATURAL;
+ width_byteena_a : NATURAL
+ );
+ PORT (
+ clocken0 : IN STD_LOGIC ;
+ clock0 : IN STD_LOGIC ;
+ address_a : IN STD_LOGIC_VECTOR (6 DOWNTO 0);
+ q_a : OUT STD_LOGIC_VECTOR (7 DOWNTO 0)
+ );
+ END COMPONENT;
+
+BEGIN
+ q <= sub_wire0(7 DOWNTO 0);
+
+ altsyncram_component : altsyncram
+ GENERIC MAP (
+ address_aclr_a => "NONE",
+ init_file => init_file,
+ intended_device_family => "Cyclone",
+ lpm_hint => "ENABLE_RUNTIME_MOD=NO",
+ lpm_type => "altsyncram",
+ numwords_a => 128,
+ operation_mode => "ROM",
+ outdata_aclr_a => "NONE",
+ outdata_reg_a => "UNREGISTERED",
+ widthad_a => 7,
+ width_a => 8,
+ width_byteena_a => 1
+ )
+ PORT MAP (
+ clocken0 => clken,
+ clock0 => clock,
+ address_a => address,
+ q_a => sub_wire0
+ );
+
+
+
+END SYN;
+
+-- ============================================================
+-- CNX file retrieval info
+-- ============================================================
+-- Retrieval info: PRIVATE: ADDRESSSTALL_A NUMERIC "0"
+-- Retrieval info: PRIVATE: AclrAddr NUMERIC "0"
+-- Retrieval info: PRIVATE: AclrByte NUMERIC "0"
+-- Retrieval info: PRIVATE: AclrOutput NUMERIC "0"
+-- Retrieval info: PRIVATE: BYTE_ENABLE NUMERIC "0"
+-- Retrieval info: PRIVATE: BYTE_SIZE NUMERIC "8"
+-- Retrieval info: PRIVATE: BlankMemory NUMERIC "0"
+-- Retrieval info: PRIVATE: CLOCK_ENABLE_INPUT_A NUMERIC "1"
+-- Retrieval info: PRIVATE: CLOCK_ENABLE_OUTPUT_A NUMERIC "0"
+-- Retrieval info: PRIVATE: Clken NUMERIC "1"
+-- Retrieval info: PRIVATE: IMPLEMENT_IN_LES NUMERIC "0"
+-- Retrieval info: PRIVATE: INIT_FILE_LAYOUT STRING "PORT_A"
+-- Retrieval info: PRIVATE: INIT_TO_SIM_X NUMERIC "0"
+-- Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "Cyclone"
+-- Retrieval info: PRIVATE: JTAG_ENABLED NUMERIC "0"
+-- Retrieval info: PRIVATE: JTAG_ID STRING "NONE"
+-- Retrieval info: PRIVATE: MAXIMUM_DEPTH NUMERIC "0"
+-- Retrieval info: PRIVATE: MIFfilename STRING "src/rom.mif"
+-- Retrieval info: PRIVATE: NUMWORDS_A NUMERIC "128"
+-- Retrieval info: PRIVATE: RAM_BLOCK_TYPE NUMERIC "0"
+-- Retrieval info: PRIVATE: RegAddr NUMERIC "1"
+-- Retrieval info: PRIVATE: RegOutput NUMERIC "0"
+-- Retrieval info: PRIVATE: SingleClock NUMERIC "1"
+-- Retrieval info: PRIVATE: UseDQRAM NUMERIC "0"
+-- Retrieval info: PRIVATE: WidthAddr NUMERIC "7"
+-- Retrieval info: PRIVATE: WidthData NUMERIC "8"
+-- Retrieval info: CONSTANT: ADDRESS_ACLR_A STRING "NONE"
+-- Retrieval info: CONSTANT: INIT_FILE STRING "src/rom.mif"
+-- Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone"
+-- Retrieval info: CONSTANT: LPM_HINT STRING "ENABLE_RUNTIME_MOD=NO"
+-- Retrieval info: CONSTANT: LPM_TYPE STRING "altsyncram"
+-- Retrieval info: CONSTANT: NUMWORDS_A NUMERIC "128"
+-- Retrieval info: CONSTANT: OPERATION_MODE STRING "ROM"
+-- Retrieval info: CONSTANT: OUTDATA_ACLR_A STRING "NONE"
+-- Retrieval info: CONSTANT: OUTDATA_REG_A STRING "UNREGISTERED"
+-- Retrieval info: CONSTANT: WIDTHAD_A NUMERIC "7"
+-- Retrieval info: CONSTANT: WIDTH_A NUMERIC "8"
+-- Retrieval info: CONSTANT: WIDTH_BYTEENA_A NUMERIC "1"
+-- Retrieval info: USED_PORT: address 0 0 7 0 INPUT NODEFVAL address[6..0]
+-- Retrieval info: USED_PORT: clken 0 0 0 0 INPUT NODEFVAL clken
+-- Retrieval info: USED_PORT: clock 0 0 0 0 INPUT NODEFVAL clock
+-- Retrieval info: USED_PORT: q 0 0 8 0 OUTPUT NODEFVAL q[7..0]
+-- Retrieval info: CONNECT: @address_a 0 0 7 0 address 0 0 7 0
+-- Retrieval info: CONNECT: q 0 0 8 0 @q_a 0 0 8 0
+-- Retrieval info: CONNECT: @clock0 0 0 0 0 clock 0 0 0 0
+-- Retrieval info: CONNECT: @clocken0 0 0 0 0 clken 0 0 0 0
+-- Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all
+-- Retrieval info: GEN_FILE: TYPE_NORMAL data_rom.vhd TRUE
+-- Retrieval info: GEN_FILE: TYPE_NORMAL data_rom.inc FALSE
+-- Retrieval info: GEN_FILE: TYPE_NORMAL data_rom.cmp FALSE
+-- Retrieval info: GEN_FILE: TYPE_NORMAL data_rom.bsf TRUE FALSE
+-- Retrieval info: GEN_FILE: TYPE_NORMAL data_rom_inst.vhd FALSE
Index: trunk/vhdl/divider.vhd
===================================================================
--- trunk/vhdl/divider.vhd (nonexistent)
+++ trunk/vhdl/divider.vhd (revision 2)
@@ -0,0 +1,119 @@
+-- This file is part of the marca processor.
+-- Copyright (C) 2007 Wolfgang Puffitsch
+
+-- This program is free software; you can redistribute it and/or modify it
+-- under the terms of the GNU Library 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
+-- Library General Public License for more details.
+
+-- You should have received a copy of the GNU Library 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
+
+-------------------------------------------------------------------------------
+-- MARCA divider
+-------------------------------------------------------------------------------
+-- architecture for a bit-serial divider
+-------------------------------------------------------------------------------
+
+-------------------------------------------------------------------------------
+-- Wolfgang Puffitsch
+-- Computer Architecture Lab, Group 3
+-------------------------------------------------------------------------------
+
+library IEEE;
+use IEEE.std_logic_1164.all;
+use IEEE.numeric_std.all;
+
+use work.marca_pkg.all;
+
+architecture behaviour of divider is
+
+signal reg_busy : std_logic;
+signal reg_denom : std_logic_vector(2*width-2 downto 0);
+signal reg_remain : std_logic_vector(width-1 downto 0);
+signal reg_quotient : std_logic_vector(width-1 downto 0);
+signal reg_hotbit : std_logic_vector(width-1 downto 0);
+
+signal next_busy : std_logic;
+signal next_denom : std_logic_vector(2*width-2 downto 0);
+signal next_remain : std_logic_vector(width-1 downto 0);
+signal next_quotient : std_logic_vector(width-1 downto 0);
+signal next_hotbit : std_logic_vector(width-1 downto 0);
+
+begin -- behaviour
+
+ busy <= reg_busy;
+ quotient <= reg_quotient;
+ remain <= reg_remain;
+
+ syn_proc: process (clock, reset)
+ begin -- process sync
+
+ if reset = RESET_ACTIVE then -- asynchronous reset (active low)
+
+ reg_busy <= '0';
+ reg_denom <= (others => '0');
+ reg_remain <= (others => '0');
+ reg_quotient <= (others => '0');
+ reg_hotbit <= (others => '0');
+ reg_hotbit(0) <= '1';
+
+ elsif clock'event and clock = '1' then -- rising clock edge
+
+ if trigger = '1' then
+ reg_denom(2*width-2 downto width-1) <= denom;
+ reg_denom(width-2 downto 0) <= (others => '0');
+ reg_remain <= numer;
+ reg_quotient <= (others => '0');
+ reg_hotbit(width-1) <= '1';
+ reg_hotbit(width-2 downto 0) <= (others => '0');
+ if zero(denom) = '1' then
+ exc <= '1';
+ reg_busy <= '0';
+ else
+ exc <= '0';
+ reg_busy <= '1';
+ end if;
+ else
+ reg_denom <= next_denom;
+ reg_remain <= next_remain;
+ reg_quotient <= next_quotient;
+ reg_hotbit <= next_hotbit;
+ reg_busy <= next_busy;
+ exc <= '0';
+ end if;
+
+ end if;
+ end process syn_proc;
+
+ compute: process (reg_denom, reg_remain, reg_quotient, reg_hotbit)
+ variable tmp_remain : std_logic_vector(2*width-2 downto 0);
+ begin -- process compute
+
+ next_denom <= '0' & reg_denom(2*width-2 downto 1);
+ next_remain <= reg_remain;
+ next_quotient <= reg_quotient;
+ next_hotbit <= '0' & reg_hotbit(width-1 downto 1);
+
+ if reg_hotbit(0) = '1' then
+ next_hotbit <= reg_hotbit;
+ next_busy <= '0';
+ else
+ next_busy <= '1';
+ end if;
+
+ tmp_remain := std_logic_vector(resize(unsigned(reg_remain), 2*width-1) - unsigned(reg_denom));
+ if tmp_remain(2*width-2) = '0' then
+ next_remain <= tmp_remain(width-1 downto 0);
+ next_quotient <= reg_quotient or reg_hotbit;
+ end if;
+
+ end process compute;
+
+end behaviour;
Index: trunk/vhdl/alu_ent.vhd
===================================================================
--- trunk/vhdl/alu_ent.vhd (nonexistent)
+++ trunk/vhdl/alu_ent.vhd (revision 2)
@@ -0,0 +1,56 @@
+-- This file is part of the marca processor.
+-- Copyright (C) 2007 Wolfgang Puffitsch
+
+-- This program is free software; you can redistribute it and/or modify it
+-- under the terms of the GNU Library 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
+-- Library General Public License for more details.
+
+-- You should have received a copy of the GNU Library 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
+
+-------------------------------------------------------------------------------
+-- MARCA ALU
+-------------------------------------------------------------------------------
+-- entity for the ALU
+-------------------------------------------------------------------------------
+
+-------------------------------------------------------------------------------
+-- Wolfgang Puffitsch
+-- Computer Architecture Lab, Group 3
+-------------------------------------------------------------------------------
+
+library IEEE;
+use IEEE.std_logic_1164.all;
+
+use work.marca_pkg.all;
+
+entity alu is
+
+ port (
+ clock : in std_logic;
+ reset : in std_logic;
+
+ op : in ALU_OP;
+
+ a : in std_logic_vector(REG_WIDTH-1 downto 0);
+ b : in std_logic_vector(REG_WIDTH-1 downto 0);
+ i : in std_logic_vector(REG_WIDTH-1 downto 0);
+ pc : in std_logic_vector(REG_WIDTH-1 downto 0);
+
+ intr : in std_logic;
+
+ exc : out std_logic;
+
+ iena : out std_logic;
+ pcchg : out std_logic;
+ busy : out std_logic;
+ result : out std_logic_vector(REG_WIDTH-1 downto 0));
+
+end alu;
Index: trunk/vhdl/marca_ent.vhd
===================================================================
--- trunk/vhdl/marca_ent.vhd (nonexistent)
+++ trunk/vhdl/marca_ent.vhd (revision 2)
@@ -0,0 +1,42 @@
+-- This file is part of the marca processor.
+-- Copyright (C) 2007 Wolfgang Puffitsch
+
+-- This program is free software; you can redistribute it and/or modify it
+-- under the terms of the GNU Library 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
+-- Library General Public License for more details.
+
+-- You should have received a copy of the GNU Library 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
+
+-------------------------------------------------------------------------------
+-- MARCA top level entity
+-------------------------------------------------------------------------------
+-- entity definition for the processor itself
+-------------------------------------------------------------------------------
+
+-------------------------------------------------------------------------------
+-- Wolfgang Puffitsch
+-- Computer Architecture Lab, Group 3
+-------------------------------------------------------------------------------
+
+library IEEE;
+use IEEE.std_logic_1164.all;
+
+use work.marca_pkg.all;
+
+entity marca is
+
+ port (
+ clock : in std_logic;
+ ext_reset : in std_logic;
+ ext_in : in std_logic_vector(IN_BITS-1 downto 0);
+ ext_out : out std_logic_vector(OUT_BITS-1 downto 0));
+
+end marca;
Index: trunk/vhdl/fetch.vhd
===================================================================
--- trunk/vhdl/fetch.vhd (nonexistent)
+++ trunk/vhdl/fetch.vhd (revision 2)
@@ -0,0 +1,121 @@
+-- This file is part of the marca processor.
+-- Copyright (C) 2007 Wolfgang Puffitsch
+
+-- This program is free software; you can redistribute it and/or modify it
+-- under the terms of the GNU Library 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
+-- Library General Public License for more details.
+
+-- You should have received a copy of the GNU Library 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
+
+-------------------------------------------------------------------------------
+-- MARCA fetch stage
+-------------------------------------------------------------------------------
+-- architecture for the instruction-fetch pipeline stage
+-------------------------------------------------------------------------------
+
+-------------------------------------------------------------------------------
+-- Wolfgang Puffitsch
+-- Computer Architecture Lab, Group 3
+-------------------------------------------------------------------------------
+
+library IEEE;
+use IEEE.std_logic_1164.all;
+use IEEE.numeric_std.all;
+
+use work.marca_pkg.all;
+
+architecture behaviour of fetch is
+
+component code_memory
+ generic (
+ init_file : string);
+ port (
+ clken : in std_logic;
+ clock : in std_logic;
+ address : in std_logic_vector (PADDR_WIDTH-1 downto 0);
+ q : out std_logic_vector (PDATA_WIDTH-1 downto 0));
+end component;
+
+signal enable : std_logic;
+
+signal address : std_logic_vector(PADDR_WIDTH-1 downto 0);
+signal data : std_logic_vector(PDATA_WIDTH-1 downto 0);
+
+signal pc_reg : std_logic_vector(REG_WIDTH-1 downto 0);
+signal next_pc : std_logic_vector(REG_WIDTH-1 downto 0);
+
+signal next_pc_out : std_logic_vector(REG_WIDTH-1 downto 0);
+
+begin -- behaviour
+
+ enable <= not hold;
+ pc_out <= pc_reg;
+
+ code_memory_unit : code_memory
+ generic map (
+ init_file => "../vhdl/code.mif")
+ port map (
+ address => address(PADDR_WIDTH-1 downto 0),
+ clken => enable,
+ clock => clock,
+ q => data);
+
+ syn_proc: process (clock, reset)
+ begin -- process syn_proc
+ if reset = RESET_ACTIVE then -- asynchronous reset (active low)
+ pc_reg <= (others => '0');
+ elsif clock'event and clock = '1' then -- rising clock edge
+ if hold = '0' then
+ pc_reg <= next_pc;
+ end if;
+ end if;
+ end process syn_proc;
+
+ increment: process (pc_reg, pc_in, pcena, data)
+ begin -- process increment
+ if pcena = '1' then
+ next_pc <= pc_in;
+ else
+ -- "predict" hard branches
+ if data(PDATA_WIDTH-1 downto PDATA_WIDTH-8) = OPC_PFX_C & OPC_BR then
+ next_pc <= std_logic_vector(signed(pc_reg) + signed(data(7 downto 0)));
+ else
+ next_pc <= std_logic_vector(unsigned(pc_reg) + 1);
+ end if;
+ end if;
+ end process increment;
+
+ forward: process (pc_reg, pc_in, pcena, data, reset)
+ begin -- process forward
+ if reset = RESET_ACTIVE then
+ address <= (others => '0');
+ else
+ if pcena = '1' then
+ address <= pc_in(PADDR_WIDTH-1 downto 0);
+ else
+ if data(PDATA_WIDTH-1 downto PDATA_WIDTH-8) = OPC_PFX_C & OPC_BR then
+ address <= std_logic_vector(signed(pc_reg) + signed(data(7 downto 0)))(PADDR_WIDTH-1 downto 0);
+ else
+ address <= std_logic_vector(unsigned(pc_reg) + 1)(PADDR_WIDTH-1 downto 0);
+ end if;
+ end if;
+ end if;
+ end process forward;
+
+ spread: process (data)
+ begin -- process spread
+ src1 <= data(3 downto 0);
+ src2 <= data(7 downto 4);
+ dest <= data(11 downto 8);
+ instr <= data;
+ end process spread;
+
+end behaviour;
Index: trunk/vhdl/decode_ent.vhd
===================================================================
--- trunk/vhdl/decode_ent.vhd (nonexistent)
+++ trunk/vhdl/decode_ent.vhd (revision 2)
@@ -0,0 +1,71 @@
+-- This file is part of the marca processor.
+-- Copyright (C) 2007 Wolfgang Puffitsch
+
+-- This program is free software; you can redistribute it and/or modify it
+-- under the terms of the GNU Library 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
+-- Library General Public License for more details.
+
+-- You should have received a copy of the GNU Library 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
+
+-------------------------------------------------------------------------------
+-- MARCA decode stage
+-------------------------------------------------------------------------------
+-- entity definition for the instruction-decode pipeline stage
+-------------------------------------------------------------------------------
+
+-------------------------------------------------------------------------------
+-- Wolfgang Puffitsch
+-- Computer Architecture Lab, Group 3
+-------------------------------------------------------------------------------
+
+library IEEE;
+use IEEE.std_logic_1164.all;
+
+use work.marca_pkg.all;
+
+entity decode is
+
+ port (
+ clock : in std_logic;
+ reset : in std_logic;
+
+ hold : in std_logic;
+ stall : in std_logic;
+
+ pc_in : in std_logic_vector(REG_WIDTH-1 downto 0);
+ pc_out : out std_logic_vector(REG_WIDTH-1 downto 0);
+
+ instr : in std_logic_vector(PDATA_WIDTH-1 downto 0);
+
+ src1_in : in std_logic_vector(REG_COUNT_LOG-1 downto 0);
+ src1_out : out std_logic_vector(REG_COUNT_LOG-1 downto 0);
+ src2_in : in std_logic_vector(REG_COUNT_LOG-1 downto 0);
+ src2_out : out std_logic_vector(REG_COUNT_LOG-1 downto 0);
+
+ dest_in : in std_logic_vector(REG_COUNT_LOG-1 downto 0);
+ dest_out : out std_logic_vector(REG_COUNT_LOG-1 downto 0);
+
+ aop : out ALU_OP;
+ mop : out MEM_OP;
+ iop : out INTR_OP;
+
+ op1 : out std_logic_vector(REG_WIDTH-1 downto 0);
+ op2 : out std_logic_vector(REG_WIDTH-1 downto 0);
+ imm : out std_logic_vector(REG_WIDTH-1 downto 0);
+
+ unit : out UNIT_SELECTOR;
+ target : out TARGET_SELECTOR;
+
+ wr_ena : in std_logic;
+ wr_dest : in std_logic_vector(REG_COUNT_LOG-1 downto 0);
+ wr_val : in std_logic_vector(REG_WIDTH-1 downto 0));
+
+end decode;
Index: trunk/vhdl/divider_ent.vhd
===================================================================
--- trunk/vhdl/divider_ent.vhd (nonexistent)
+++ trunk/vhdl/divider_ent.vhd (revision 2)
@@ -0,0 +1,50 @@
+-- This file is part of the marca processor.
+-- Copyright (C) 2007 Wolfgang Puffitsch
+
+-- This program is free software; you can redistribute it and/or modify it
+-- under the terms of the GNU Library 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
+-- Library General Public License for more details.
+
+-- You should have received a copy of the GNU Library 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
+
+-------------------------------------------------------------------------------
+-- MARCA divider
+-------------------------------------------------------------------------------
+-- entity of a bit-serial divider
+-------------------------------------------------------------------------------
+
+-------------------------------------------------------------------------------
+-- Wolfgang Puffitsch
+-- Computer Architecture Lab, Group 3
+-------------------------------------------------------------------------------
+
+library IEEE;
+use IEEE.std_logic_1164.all;
+
+use work.marca_pkg.all;
+
+entity divider is
+
+ generic (
+ width : integer := REG_WIDTH);
+
+ port (
+ clock : in std_logic;
+ reset : in std_logic;
+ trigger : in std_logic;
+ denom : in std_logic_vector(width-1 downto 0);
+ numer : in std_logic_vector(width-1 downto 0);
+ exc : out std_logic;
+ busy : out std_logic;
+ quotient : out std_logic_vector(width-1 downto 0);
+ remain : out std_logic_vector(width-1 downto 0));
+
+end divider;