├── LICENSE
├── README.md
├── img
├── alu.png
├── overall.png
├── pipeline.png
└── uart.png
└── src
├── ALU
├── ALU.v
├── ALU_satisfied_requirements.v
└── ALU_超前进位.v
├── Assembler
├── BinaryCode.txt
├── MIPS_complier.py
└── MIPS_program.asm
├── Pipeline_CPU
├── ALU.v
├── Control.v
├── DataMem.v
├── Digitube_scan.v
├── EX_MEM_Reg.v
├── Forward_Unit.v
├── Hazard_Unit.v
├── ID_EX_Reg.v
├── IF_ID_Reg.v
├── MEM_WB_Reg.v
├── Peripheral.v
├── PipeLine_Core.v
├── PipelineCPU.v
├── Pipeline_CPU_tb.v
├── ROM.v
├── ROM_tb.v
├── RegFile.v
└── UART.v
└── Single_Cycle_CPU
├── ALU.v
├── CPU.v
├── CPU_clk.v
├── CPU_tb.v
├── Control.v
├── DataMem.v
├── Digitube_scan.v
├── Peripheral.v
├── ROM.v
├── ROM_tb.v
├── RegFile.v
└── UART.v
/LICENSE:
--------------------------------------------------------------------------------
1 | GNU AFFERO GENERAL PUBLIC LICENSE
2 | Version 3, 19 November 2007
3 |
4 | Copyright (C) 2007 Free Software Foundation, Inc.
5 | Everyone is permitted to copy and distribute verbatim copies
6 | of this license document, but changing it is not allowed.
7 |
8 | Preamble
9 |
10 | The GNU Affero General Public License is a free, copyleft license for
11 | software and other kinds of works, specifically designed to ensure
12 | cooperation with the community in the case of network server software.
13 |
14 | The licenses for most software and other practical works are designed
15 | to take away your freedom to share and change the works. By contrast,
16 | our General Public Licenses are intended to guarantee your freedom to
17 | share and change all versions of a program--to make sure it remains free
18 | software for all its users.
19 |
20 | When we speak of free software, we are referring to freedom, not
21 | price. Our General Public Licenses are designed to make sure that you
22 | have the freedom to distribute copies of free software (and charge for
23 | them if you wish), that you receive source code or can get it if you
24 | want it, that you can change the software or use pieces of it in new
25 | free programs, and that you know you can do these things.
26 |
27 | Developers that use our General Public Licenses protect your rights
28 | with two steps: (1) assert copyright on the software, and (2) offer
29 | you this License which gives you legal permission to copy, distribute
30 | and/or modify the software.
31 |
32 | A secondary benefit of defending all users' freedom is that
33 | improvements made in alternate versions of the program, if they
34 | receive widespread use, become available for other developers to
35 | incorporate. Many developers of free software are heartened and
36 | encouraged by the resulting cooperation. However, in the case of
37 | software used on network servers, this result may fail to come about.
38 | The GNU General Public License permits making a modified version and
39 | letting the public access it on a server without ever releasing its
40 | source code to the public.
41 |
42 | The GNU Affero General Public License is designed specifically to
43 | ensure that, in such cases, the modified source code becomes available
44 | to the community. It requires the operator of a network server to
45 | provide the source code of the modified version running there to the
46 | users of that server. Therefore, public use of a modified version, on
47 | a publicly accessible server, gives the public access to the source
48 | code of the modified version.
49 |
50 | An older license, called the Affero General Public License and
51 | published by Affero, was designed to accomplish similar goals. This is
52 | a different license, not a version of the Affero GPL, but Affero has
53 | released a new version of the Affero GPL which permits relicensing under
54 | this license.
55 |
56 | The precise terms and conditions for copying, distribution and
57 | modification follow.
58 |
59 | TERMS AND CONDITIONS
60 |
61 | 0. Definitions.
62 |
63 | "This License" refers to version 3 of the GNU Affero General Public License.
64 |
65 | "Copyright" also means copyright-like laws that apply to other kinds of
66 | works, such as semiconductor masks.
67 |
68 | "The Program" refers to any copyrightable work licensed under this
69 | License. Each licensee is addressed as "you". "Licensees" and
70 | "recipients" may be individuals or organizations.
71 |
72 | To "modify" a work means to copy from or adapt all or part of the work
73 | in a fashion requiring copyright permission, other than the making of an
74 | exact copy. The resulting work is called a "modified version" of the
75 | earlier work or a work "based on" the earlier work.
76 |
77 | A "covered work" means either the unmodified Program or a work based
78 | on the Program.
79 |
80 | To "propagate" a work means to do anything with it that, without
81 | permission, would make you directly or secondarily liable for
82 | infringement under applicable copyright law, except executing it on a
83 | computer or modifying a private copy. Propagation includes copying,
84 | distribution (with or without modification), making available to the
85 | public, and in some countries other activities as well.
86 |
87 | To "convey" a work means any kind of propagation that enables other
88 | parties to make or receive copies. Mere interaction with a user through
89 | a computer network, with no transfer of a copy, is not conveying.
90 |
91 | An interactive user interface displays "Appropriate Legal Notices"
92 | to the extent that it includes a convenient and prominently visible
93 | feature that (1) displays an appropriate copyright notice, and (2)
94 | tells the user that there is no warranty for the work (except to the
95 | extent that warranties are provided), that licensees may convey the
96 | work under this License, and how to view a copy of this License. If
97 | the interface presents a list of user commands or options, such as a
98 | menu, a prominent item in the list meets this criterion.
99 |
100 | 1. Source Code.
101 |
102 | The "source code" for a work means the preferred form of the work
103 | for making modifications to it. "Object code" means any non-source
104 | form of a work.
105 |
106 | A "Standard Interface" means an interface that either is an official
107 | standard defined by a recognized standards body, or, in the case of
108 | interfaces specified for a particular programming language, one that
109 | is widely used among developers working in that language.
110 |
111 | The "System Libraries" of an executable work include anything, other
112 | than the work as a whole, that (a) is included in the normal form of
113 | packaging a Major Component, but which is not part of that Major
114 | Component, and (b) serves only to enable use of the work with that
115 | Major Component, or to implement a Standard Interface for which an
116 | implementation is available to the public in source code form. A
117 | "Major Component", in this context, means a major essential component
118 | (kernel, window system, and so on) of the specific operating system
119 | (if any) on which the executable work runs, or a compiler used to
120 | produce the work, or an object code interpreter used to run it.
121 |
122 | The "Corresponding Source" for a work in object code form means all
123 | the source code needed to generate, install, and (for an executable
124 | work) run the object code and to modify the work, including scripts to
125 | control those activities. However, it does not include the work's
126 | System Libraries, or general-purpose tools or generally available free
127 | programs which are used unmodified in performing those activities but
128 | which are not part of the work. For example, Corresponding Source
129 | includes interface definition files associated with source files for
130 | the work, and the source code for shared libraries and dynamically
131 | linked subprograms that the work is specifically designed to require,
132 | such as by intimate data communication or control flow between those
133 | subprograms and other parts of the work.
134 |
135 | The Corresponding Source need not include anything that users
136 | can regenerate automatically from other parts of the Corresponding
137 | Source.
138 |
139 | The Corresponding Source for a work in source code form is that
140 | same work.
141 |
142 | 2. Basic Permissions.
143 |
144 | All rights granted under this License are granted for the term of
145 | copyright on the Program, and are irrevocable provided the stated
146 | conditions are met. This License explicitly affirms your unlimited
147 | permission to run the unmodified Program. The output from running a
148 | covered work is covered by this License only if the output, given its
149 | content, constitutes a covered work. This License acknowledges your
150 | rights of fair use or other equivalent, as provided by copyright law.
151 |
152 | You may make, run and propagate covered works that you do not
153 | convey, without conditions so long as your license otherwise remains
154 | in force. You may convey covered works to others for the sole purpose
155 | of having them make modifications exclusively for you, or provide you
156 | with facilities for running those works, provided that you comply with
157 | the terms of this License in conveying all material for which you do
158 | not control copyright. Those thus making or running the covered works
159 | for you must do so exclusively on your behalf, under your direction
160 | and control, on terms that prohibit them from making any copies of
161 | your copyrighted material outside their relationship with you.
162 |
163 | Conveying under any other circumstances is permitted solely under
164 | the conditions stated below. Sublicensing is not allowed; section 10
165 | makes it unnecessary.
166 |
167 | 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
168 |
169 | No covered work shall be deemed part of an effective technological
170 | measure under any applicable law fulfilling obligations under article
171 | 11 of the WIPO copyright treaty adopted on 20 December 1996, or
172 | similar laws prohibiting or restricting circumvention of such
173 | measures.
174 |
175 | When you convey a covered work, you waive any legal power to forbid
176 | circumvention of technological measures to the extent such circumvention
177 | is effected by exercising rights under this License with respect to
178 | the covered work, and you disclaim any intention to limit operation or
179 | modification of the work as a means of enforcing, against the work's
180 | users, your or third parties' legal rights to forbid circumvention of
181 | technological measures.
182 |
183 | 4. Conveying Verbatim Copies.
184 |
185 | You may convey verbatim copies of the Program's source code as you
186 | receive it, in any medium, provided that you conspicuously and
187 | appropriately publish on each copy an appropriate copyright notice;
188 | keep intact all notices stating that this License and any
189 | non-permissive terms added in accord with section 7 apply to the code;
190 | keep intact all notices of the absence of any warranty; and give all
191 | recipients a copy of this License along with the Program.
192 |
193 | You may charge any price or no price for each copy that you convey,
194 | and you may offer support or warranty protection for a fee.
195 |
196 | 5. Conveying Modified Source Versions.
197 |
198 | You may convey a work based on the Program, or the modifications to
199 | produce it from the Program, in the form of source code under the
200 | terms of section 4, provided that you also meet all of these conditions:
201 |
202 | a) The work must carry prominent notices stating that you modified
203 | it, and giving a relevant date.
204 |
205 | b) The work must carry prominent notices stating that it is
206 | released under this License and any conditions added under section
207 | 7. This requirement modifies the requirement in section 4 to
208 | "keep intact all notices".
209 |
210 | c) You must license the entire work, as a whole, under this
211 | License to anyone who comes into possession of a copy. This
212 | License will therefore apply, along with any applicable section 7
213 | additional terms, to the whole of the work, and all its parts,
214 | regardless of how they are packaged. This License gives no
215 | permission to license the work in any other way, but it does not
216 | invalidate such permission if you have separately received it.
217 |
218 | d) If the work has interactive user interfaces, each must display
219 | Appropriate Legal Notices; however, if the Program has interactive
220 | interfaces that do not display Appropriate Legal Notices, your
221 | work need not make them do so.
222 |
223 | A compilation of a covered work with other separate and independent
224 | works, which are not by their nature extensions of the covered work,
225 | and which are not combined with it such as to form a larger program,
226 | in or on a volume of a storage or distribution medium, is called an
227 | "aggregate" if the compilation and its resulting copyright are not
228 | used to limit the access or legal rights of the compilation's users
229 | beyond what the individual works permit. Inclusion of a covered work
230 | in an aggregate does not cause this License to apply to the other
231 | parts of the aggregate.
232 |
233 | 6. Conveying Non-Source Forms.
234 |
235 | You may convey a covered work in object code form under the terms
236 | of sections 4 and 5, provided that you also convey the
237 | machine-readable Corresponding Source under the terms of this License,
238 | in one of these ways:
239 |
240 | a) Convey the object code in, or embodied in, a physical product
241 | (including a physical distribution medium), accompanied by the
242 | Corresponding Source fixed on a durable physical medium
243 | customarily used for software interchange.
244 |
245 | b) Convey the object code in, or embodied in, a physical product
246 | (including a physical distribution medium), accompanied by a
247 | written offer, valid for at least three years and valid for as
248 | long as you offer spare parts or customer support for that product
249 | model, to give anyone who possesses the object code either (1) a
250 | copy of the Corresponding Source for all the software in the
251 | product that is covered by this License, on a durable physical
252 | medium customarily used for software interchange, for a price no
253 | more than your reasonable cost of physically performing this
254 | conveying of source, or (2) access to copy the
255 | Corresponding Source from a network server at no charge.
256 |
257 | c) Convey individual copies of the object code with a copy of the
258 | written offer to provide the Corresponding Source. This
259 | alternative is allowed only occasionally and noncommercially, and
260 | only if you received the object code with such an offer, in accord
261 | with subsection 6b.
262 |
263 | d) Convey the object code by offering access from a designated
264 | place (gratis or for a charge), and offer equivalent access to the
265 | Corresponding Source in the same way through the same place at no
266 | further charge. You need not require recipients to copy the
267 | Corresponding Source along with the object code. If the place to
268 | copy the object code is a network server, the Corresponding Source
269 | may be on a different server (operated by you or a third party)
270 | that supports equivalent copying facilities, provided you maintain
271 | clear directions next to the object code saying where to find the
272 | Corresponding Source. Regardless of what server hosts the
273 | Corresponding Source, you remain obligated to ensure that it is
274 | available for as long as needed to satisfy these requirements.
275 |
276 | e) Convey the object code using peer-to-peer transmission, provided
277 | you inform other peers where the object code and Corresponding
278 | Source of the work are being offered to the general public at no
279 | charge under subsection 6d.
280 |
281 | A separable portion of the object code, whose source code is excluded
282 | from the Corresponding Source as a System Library, need not be
283 | included in conveying the object code work.
284 |
285 | A "User Product" is either (1) a "consumer product", which means any
286 | tangible personal property which is normally used for personal, family,
287 | or household purposes, or (2) anything designed or sold for incorporation
288 | into a dwelling. In determining whether a product is a consumer product,
289 | doubtful cases shall be resolved in favor of coverage. For a particular
290 | product received by a particular user, "normally used" refers to a
291 | typical or common use of that class of product, regardless of the status
292 | of the particular user or of the way in which the particular user
293 | actually uses, or expects or is expected to use, the product. A product
294 | is a consumer product regardless of whether the product has substantial
295 | commercial, industrial or non-consumer uses, unless such uses represent
296 | the only significant mode of use of the product.
297 |
298 | "Installation Information" for a User Product means any methods,
299 | procedures, authorization keys, or other information required to install
300 | and execute modified versions of a covered work in that User Product from
301 | a modified version of its Corresponding Source. The information must
302 | suffice to ensure that the continued functioning of the modified object
303 | code is in no case prevented or interfered with solely because
304 | modification has been made.
305 |
306 | If you convey an object code work under this section in, or with, or
307 | specifically for use in, a User Product, and the conveying occurs as
308 | part of a transaction in which the right of possession and use of the
309 | User Product is transferred to the recipient in perpetuity or for a
310 | fixed term (regardless of how the transaction is characterized), the
311 | Corresponding Source conveyed under this section must be accompanied
312 | by the Installation Information. But this requirement does not apply
313 | if neither you nor any third party retains the ability to install
314 | modified object code on the User Product (for example, the work has
315 | been installed in ROM).
316 |
317 | The requirement to provide Installation Information does not include a
318 | requirement to continue to provide support service, warranty, or updates
319 | for a work that has been modified or installed by the recipient, or for
320 | the User Product in which it has been modified or installed. Access to a
321 | network may be denied when the modification itself materially and
322 | adversely affects the operation of the network or violates the rules and
323 | protocols for communication across the network.
324 |
325 | Corresponding Source conveyed, and Installation Information provided,
326 | in accord with this section must be in a format that is publicly
327 | documented (and with an implementation available to the public in
328 | source code form), and must require no special password or key for
329 | unpacking, reading or copying.
330 |
331 | 7. Additional Terms.
332 |
333 | "Additional permissions" are terms that supplement the terms of this
334 | License by making exceptions from one or more of its conditions.
335 | Additional permissions that are applicable to the entire Program shall
336 | be treated as though they were included in this License, to the extent
337 | that they are valid under applicable law. If additional permissions
338 | apply only to part of the Program, that part may be used separately
339 | under those permissions, but the entire Program remains governed by
340 | this License without regard to the additional permissions.
341 |
342 | When you convey a copy of a covered work, you may at your option
343 | remove any additional permissions from that copy, or from any part of
344 | it. (Additional permissions may be written to require their own
345 | removal in certain cases when you modify the work.) You may place
346 | additional permissions on material, added by you to a covered work,
347 | for which you have or can give appropriate copyright permission.
348 |
349 | Notwithstanding any other provision of this License, for material you
350 | add to a covered work, you may (if authorized by the copyright holders of
351 | that material) supplement the terms of this License with terms:
352 |
353 | a) Disclaiming warranty or limiting liability differently from the
354 | terms of sections 15 and 16 of this License; or
355 |
356 | b) Requiring preservation of specified reasonable legal notices or
357 | author attributions in that material or in the Appropriate Legal
358 | Notices displayed by works containing it; or
359 |
360 | c) Prohibiting misrepresentation of the origin of that material, or
361 | requiring that modified versions of such material be marked in
362 | reasonable ways as different from the original version; or
363 |
364 | d) Limiting the use for publicity purposes of names of licensors or
365 | authors of the material; or
366 |
367 | e) Declining to grant rights under trademark law for use of some
368 | trade names, trademarks, or service marks; or
369 |
370 | f) Requiring indemnification of licensors and authors of that
371 | material by anyone who conveys the material (or modified versions of
372 | it) with contractual assumptions of liability to the recipient, for
373 | any liability that these contractual assumptions directly impose on
374 | those licensors and authors.
375 |
376 | All other non-permissive additional terms are considered "further
377 | restrictions" within the meaning of section 10. If the Program as you
378 | received it, or any part of it, contains a notice stating that it is
379 | governed by this License along with a term that is a further
380 | restriction, you may remove that term. If a license document contains
381 | a further restriction but permits relicensing or conveying under this
382 | License, you may add to a covered work material governed by the terms
383 | of that license document, provided that the further restriction does
384 | not survive such relicensing or conveying.
385 |
386 | If you add terms to a covered work in accord with this section, you
387 | must place, in the relevant source files, a statement of the
388 | additional terms that apply to those files, or a notice indicating
389 | where to find the applicable terms.
390 |
391 | Additional terms, permissive or non-permissive, may be stated in the
392 | form of a separately written license, or stated as exceptions;
393 | the above requirements apply either way.
394 |
395 | 8. Termination.
396 |
397 | You may not propagate or modify a covered work except as expressly
398 | provided under this License. Any attempt otherwise to propagate or
399 | modify it is void, and will automatically terminate your rights under
400 | this License (including any patent licenses granted under the third
401 | paragraph of section 11).
402 |
403 | However, if you cease all violation of this License, then your
404 | license from a particular copyright holder is reinstated (a)
405 | provisionally, unless and until the copyright holder explicitly and
406 | finally terminates your license, and (b) permanently, if the copyright
407 | holder fails to notify you of the violation by some reasonable means
408 | prior to 60 days after the cessation.
409 |
410 | Moreover, your license from a particular copyright holder is
411 | reinstated permanently if the copyright holder notifies you of the
412 | violation by some reasonable means, this is the first time you have
413 | received notice of violation of this License (for any work) from that
414 | copyright holder, and you cure the violation prior to 30 days after
415 | your receipt of the notice.
416 |
417 | Termination of your rights under this section does not terminate the
418 | licenses of parties who have received copies or rights from you under
419 | this License. If your rights have been terminated and not permanently
420 | reinstated, you do not qualify to receive new licenses for the same
421 | material under section 10.
422 |
423 | 9. Acceptance Not Required for Having Copies.
424 |
425 | You are not required to accept this License in order to receive or
426 | run a copy of the Program. Ancillary propagation of a covered work
427 | occurring solely as a consequence of using peer-to-peer transmission
428 | to receive a copy likewise does not require acceptance. However,
429 | nothing other than this License grants you permission to propagate or
430 | modify any covered work. These actions infringe copyright if you do
431 | not accept this License. Therefore, by modifying or propagating a
432 | covered work, you indicate your acceptance of this License to do so.
433 |
434 | 10. Automatic Licensing of Downstream Recipients.
435 |
436 | Each time you convey a covered work, the recipient automatically
437 | receives a license from the original licensors, to run, modify and
438 | propagate that work, subject to this License. You are not responsible
439 | for enforcing compliance by third parties with this License.
440 |
441 | An "entity transaction" is a transaction transferring control of an
442 | organization, or substantially all assets of one, or subdividing an
443 | organization, or merging organizations. If propagation of a covered
444 | work results from an entity transaction, each party to that
445 | transaction who receives a copy of the work also receives whatever
446 | licenses to the work the party's predecessor in interest had or could
447 | give under the previous paragraph, plus a right to possession of the
448 | Corresponding Source of the work from the predecessor in interest, if
449 | the predecessor has it or can get it with reasonable efforts.
450 |
451 | You may not impose any further restrictions on the exercise of the
452 | rights granted or affirmed under this License. For example, you may
453 | not impose a license fee, royalty, or other charge for exercise of
454 | rights granted under this License, and you may not initiate litigation
455 | (including a cross-claim or counterclaim in a lawsuit) alleging that
456 | any patent claim is infringed by making, using, selling, offering for
457 | sale, or importing the Program or any portion of it.
458 |
459 | 11. Patents.
460 |
461 | A "contributor" is a copyright holder who authorizes use under this
462 | License of the Program or a work on which the Program is based. The
463 | work thus licensed is called the contributor's "contributor version".
464 |
465 | A contributor's "essential patent claims" are all patent claims
466 | owned or controlled by the contributor, whether already acquired or
467 | hereafter acquired, that would be infringed by some manner, permitted
468 | by this License, of making, using, or selling its contributor version,
469 | but do not include claims that would be infringed only as a
470 | consequence of further modification of the contributor version. For
471 | purposes of this definition, "control" includes the right to grant
472 | patent sublicenses in a manner consistent with the requirements of
473 | this License.
474 |
475 | Each contributor grants you a non-exclusive, worldwide, royalty-free
476 | patent license under the contributor's essential patent claims, to
477 | make, use, sell, offer for sale, import and otherwise run, modify and
478 | propagate the contents of its contributor version.
479 |
480 | In the following three paragraphs, a "patent license" is any express
481 | agreement or commitment, however denominated, not to enforce a patent
482 | (such as an express permission to practice a patent or covenant not to
483 | sue for patent infringement). To "grant" such a patent license to a
484 | party means to make such an agreement or commitment not to enforce a
485 | patent against the party.
486 |
487 | If you convey a covered work, knowingly relying on a patent license,
488 | and the Corresponding Source of the work is not available for anyone
489 | to copy, free of charge and under the terms of this License, through a
490 | publicly available network server or other readily accessible means,
491 | then you must either (1) cause the Corresponding Source to be so
492 | available, or (2) arrange to deprive yourself of the benefit of the
493 | patent license for this particular work, or (3) arrange, in a manner
494 | consistent with the requirements of this License, to extend the patent
495 | license to downstream recipients. "Knowingly relying" means you have
496 | actual knowledge that, but for the patent license, your conveying the
497 | covered work in a country, or your recipient's use of the covered work
498 | in a country, would infringe one or more identifiable patents in that
499 | country that you have reason to believe are valid.
500 |
501 | If, pursuant to or in connection with a single transaction or
502 | arrangement, you convey, or propagate by procuring conveyance of, a
503 | covered work, and grant a patent license to some of the parties
504 | receiving the covered work authorizing them to use, propagate, modify
505 | or convey a specific copy of the covered work, then the patent license
506 | you grant is automatically extended to all recipients of the covered
507 | work and works based on it.
508 |
509 | A patent license is "discriminatory" if it does not include within
510 | the scope of its coverage, prohibits the exercise of, or is
511 | conditioned on the non-exercise of one or more of the rights that are
512 | specifically granted under this License. You may not convey a covered
513 | work if you are a party to an arrangement with a third party that is
514 | in the business of distributing software, under which you make payment
515 | to the third party based on the extent of your activity of conveying
516 | the work, and under which the third party grants, to any of the
517 | parties who would receive the covered work from you, a discriminatory
518 | patent license (a) in connection with copies of the covered work
519 | conveyed by you (or copies made from those copies), or (b) primarily
520 | for and in connection with specific products or compilations that
521 | contain the covered work, unless you entered into that arrangement,
522 | or that patent license was granted, prior to 28 March 2007.
523 |
524 | Nothing in this License shall be construed as excluding or limiting
525 | any implied license or other defenses to infringement that may
526 | otherwise be available to you under applicable patent law.
527 |
528 | 12. No Surrender of Others' Freedom.
529 |
530 | If conditions are imposed on you (whether by court order, agreement or
531 | otherwise) that contradict the conditions of this License, they do not
532 | excuse you from the conditions of this License. If you cannot convey a
533 | covered work so as to satisfy simultaneously your obligations under this
534 | License and any other pertinent obligations, then as a consequence you may
535 | not convey it at all. For example, if you agree to terms that obligate you
536 | to collect a royalty for further conveying from those to whom you convey
537 | the Program, the only way you could satisfy both those terms and this
538 | License would be to refrain entirely from conveying the Program.
539 |
540 | 13. Remote Network Interaction; Use with the GNU General Public License.
541 |
542 | Notwithstanding any other provision of this License, if you modify the
543 | Program, your modified version must prominently offer all users
544 | interacting with it remotely through a computer network (if your version
545 | supports such interaction) an opportunity to receive the Corresponding
546 | Source of your version by providing access to the Corresponding Source
547 | from a network server at no charge, through some standard or customary
548 | means of facilitating copying of software. This Corresponding Source
549 | shall include the Corresponding Source for any work covered by version 3
550 | of the GNU General Public License that is incorporated pursuant to the
551 | following paragraph.
552 |
553 | Notwithstanding any other provision of this License, you have
554 | permission to link or combine any covered work with a work licensed
555 | under version 3 of the GNU General Public License into a single
556 | combined work, and to convey the resulting work. The terms of this
557 | License will continue to apply to the part which is the covered work,
558 | but the work with which it is combined will remain governed by version
559 | 3 of the GNU General Public License.
560 |
561 | 14. Revised Versions of this License.
562 |
563 | The Free Software Foundation may publish revised and/or new versions of
564 | the GNU Affero General Public License from time to time. Such new versions
565 | will be similar in spirit to the present version, but may differ in detail to
566 | address new problems or concerns.
567 |
568 | Each version is given a distinguishing version number. If the
569 | Program specifies that a certain numbered version of the GNU Affero General
570 | Public License "or any later version" applies to it, you have the
571 | option of following the terms and conditions either of that numbered
572 | version or of any later version published by the Free Software
573 | Foundation. If the Program does not specify a version number of the
574 | GNU Affero General Public License, you may choose any version ever published
575 | by the Free Software Foundation.
576 |
577 | If the Program specifies that a proxy can decide which future
578 | versions of the GNU Affero General Public License can be used, that proxy's
579 | public statement of acceptance of a version permanently authorizes you
580 | to choose that version for the Program.
581 |
582 | Later license versions may give you additional or different
583 | permissions. However, no additional obligations are imposed on any
584 | author or copyright holder as a result of your choosing to follow a
585 | later version.
586 |
587 | 15. Disclaimer of Warranty.
588 |
589 | THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
590 | APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
591 | HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
592 | OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
593 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
594 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
595 | IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
596 | ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
597 |
598 | 16. Limitation of Liability.
599 |
600 | IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
601 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
602 | THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
603 | GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
604 | USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
605 | DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
606 | PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
607 | EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
608 | SUCH DAMAGES.
609 |
610 | 17. Interpretation of Sections 15 and 16.
611 |
612 | If the disclaimer of warranty and limitation of liability provided
613 | above cannot be given local legal effect according to their terms,
614 | reviewing courts shall apply local law that most closely approximates
615 | an absolute waiver of all civil liability in connection with the
616 | Program, unless a warranty or assumption of liability accompanies a
617 | copy of the Program in return for a fee.
618 |
619 | END OF TERMS AND CONDITIONS
620 |
621 | How to Apply These Terms to Your New Programs
622 |
623 | If you develop a new program, and you want it to be of the greatest
624 | possible use to the public, the best way to achieve this is to make it
625 | free software which everyone can redistribute and change under these terms.
626 |
627 | To do so, attach the following notices to the program. It is safest
628 | to attach them to the start of each source file to most effectively
629 | state the exclusion of warranty; and each file should have at least
630 | the "copyright" line and a pointer to where the full notice is found.
631 |
632 | MIPS CPU
633 | Copyright (C) 2016 Xavier Lin
634 |
635 | This program is free software: you can redistribute it and/or modify
636 | it under the terms of the GNU Affero General Public License as published
637 | by the Free Software Foundation, either version 3 of the License, or
638 | (at your option) any later version.
639 |
640 | This program is distributed in the hope that it will be useful,
641 | but WITHOUT ANY WARRANTY; without even the implied warranty of
642 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
643 | GNU Affero General Public License for more details.
644 |
645 | You should have received a copy of the GNU Affero General Public License
646 | along with this program. If not, see .
647 |
648 | Also add information on how to contact you by electronic and paper mail.
649 |
650 | If your software can interact with users remotely through a computer
651 | network, you should also make sure that it provides a way for users to
652 | get its source. For example, if your program is a web application, its
653 | interface could display a "Source" link that leads users to an archive
654 | of the code. There are many ways you could offer source, and different
655 | solutions will be better for different programs; see section 13 for the
656 | specific requirements.
657 |
658 | You should also get your employer (if you work as a programmer) or school,
659 | if any, to sign a "copyright disclaimer" for the program, if necessary.
660 | For more information on this, and how to apply and follow the GNU AGPL, see
661 | .
662 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 | 32-Bit MIPS CPU (Classic RISC Pipeline)
3 | ==================
4 | (Latest update: 2016/07/30)
5 |
6 | 整体设计
7 | --------
8 |
9 | 我们将CPU分为如下功能单元:指令存储器、寄存器堆、控制单元、ALU、数据存储器、UART外设、普通外设、转发单元(流水线CPU)、冒险单元(流水线CPU)等。在CPU模块中实例化各功能单元,建立数据通路。整体设计框架如图,蓝色模块为通用模块,红色模块为流水线CPU新增模块。
10 |
11 | 
12 |
13 |
14 | ALU
15 | ---
16 |
17 | ALU模块分为四个子模块,分别是加减运算模块,比较模块,逻辑模块和移位模块,通过ALUFun最高两位多路选择,决定最后的输出。详细的模块设计如图所示。
18 |
19 | 
20 |
21 | 对于加减法模块,我们通过实验发现如果采用超前进位加法,可以使得ALU模块的组合逻辑延时更小,但是当使用超前进位模块的ALU放入流水线CPU进行整体综合时,反而会使得流水线的工作频率降低。这可能是由于quartus在综合流水线的时候自身的优化机制可以使得直接使用加号和减号进行运算的方式优化的更好,因此我们最后没有采用超前进位而是直接使用A+B和A-B的方式来实现加减法计算。
22 |
23 | 对于移位模块,我们通过实验发现直接采用“<<”和“>>”运算符的方式可以让流水线的频率更高。因此最后没有采用实验指导书上的1,2,4,8位移位串联的方式。
24 |
25 | 对于最后的四路选择(选择输出的结果是采用四个模块中哪一个的结果),我们发现由于各个模块的组合逻辑延时不同,调换各个模块之间的顺序使得延时长的模块先被分支出执行可以使得最长的组合逻辑通路变短,因此我们最后通过实验改变条件运算的先后次序,使得ALU的最大延时变短。
26 |
27 | 对于另外一些组合逻辑的运算,我们发现有时相同语义的语句采用不同的写法会影响组合逻辑的延时。例如当判断A是否为0时,我们采用A的所有位做或运算(|A)可以比直接判断A是否等于0(A==0)更快。另外,条件运算符冒号两侧是固定的数值时运算比两侧是逻辑表达式要快(这可能是由于FPGA内部结构是查找表造成的)。例如,假设a,b,c是三个一位二进制数,
28 | 对于以下两行代码
29 |
30 | assign a = b ? c : ~c;
31 | assign a = (b & c) ? 1 : 0;
32 |
33 |
34 | 第一行代码执行需要的延时就比第二行代码要大。
35 |
36 | 根据以上这几条规律,我们对ALU的代码进行优化以提升流水线CPU的时钟频率。
37 |
38 | 数据交互模块
39 | ------------
40 |
41 | ### 寄存器堆
42 |
43 | 使用 reg\[31:0\] RF\_DATA\[31:0\]
44 | 实现。同时,寄存器堆初始化时包括\$0,使用判断语句来控制寄存器的写入,即保证\$0其值只为0。在流水线CPU中,为保证读写正确,我们令寄存器堆在时钟下降沿时写入。这样,在读取寄存器数据时不做判断,就减少读取的组合逻辑;同时由于\$0不可被改变,因此各单元内是否写入\$0的判断均可删去,简化逻辑。
45 |
46 | 
47 |
48 | ### UART外设
49 |
50 | UART串口收发模块采用春季学期第四次实验代码实现,其数据通路如图。UART控制模块在UART接收模块产生接收完成信号脉冲Rx\_Status时,置位UART外设存储器的控制数据相应位(接收中断控制位),同时返回信号Rx\_LoadFinish指示UART控制模块结束信号Rx\_Status;UART控制模块在写入UART外设存储器的发送地址后,将产生发送使能信号Tx\_En给UART发送模块;读取UART外设存储器的控制数据后,将复位其接收中断状态位、发送中断状态位。
51 |
52 | 流水线CPU数据通路
53 | -----------------
54 |
55 | 
56 |
57 | ### 转发单元
58 |
59 | **ForwardA | ForwardB**
60 |
61 | 最常见的冒险来自EX段,也就是ALU的操作数需要用到上一条或者倒数第二条的指令时可能产生的冒险,即有可能用到EX/MEM寄存器内的数据,或者是MEM/WB寄存器内的数据,判定伪码如下:
62 |
63 | EX/MEM
64 | 段的转发需要判定的是前一条指令写入非\$0寄存器,且写入地址与需要读取的地址相等
65 |
66 | if ( EX/MEM.RegWrite
67 | and ( EX/MEM.RegisterRd != 0 )
68 | and ( EX/MEM.RegisterRd == ID/EX.RegisterRs ))
69 | ForwardA = 10
70 |
71 |
72 | MEM/WB 段的转发需要增加一个判定,就是要求不能从EX/MEM就近转发
73 |
74 | if ( MEM/WB.RegWrite
75 | and ( MEM/WB.RegisterRd != 0 )
76 | and not ( EX/MEM.RegWrite and (EX/MEM.RegisterRd != 0 )
77 | and ( EX/MEM.RegisterRd != ID/EX.RegisterRd ))
78 | and ( MEM/EX.RegisterRd == ID/EX.RegisterRs ))
79 | ForwardA = 01
80 |
81 |
82 | 将上述的Rs全部改为Rt就得到了ForwardB的转发条件,verilog代码如下。
83 |
84 | 先获得控制信号
85 |
86 | // ForwardA, strategy here same as the textbook
87 | if(EX_MEM_RegWrite && EX_MEM_AddrC != 5'h00
88 | && EX_MEM_AddrC == ID_EX_Rs) begin
89 | ForwardA = 2'b10;
90 | end
91 | else if(MEM_WB_RegWrite && MEM_WB_AddrC != 5'h00
92 | && MEM_WB_AddrC == ID_EX_Rs) begin
93 | ForwardA = 2'b01;
94 | end
95 | else
96 | ForwardA = 2'b00;
97 | // Only replace Rt with Rs of ForwardA and we get ForwardB
98 |
99 |
100 | 根据控制信号选择前传的数据
101 |
102 | assign ForwardAData = (ForwardA==2'b00) ? EX_DataBusA :
103 | (ForwardA==2'b01) ? WB_DataBusC : MEM_ALUOut;
104 | assign ForwardBData = (ForwardB==2'b00) ? EX_DataBusB :
105 | (ForwardB==2'b01) ? WB_DataBusC : MEM_ALUOut;
106 | assign ForwardJData = (ForwardJ == 2'b00) ? ID_DataBusA :
107 | (ForwardJ == 2'b01) ? EX_ALUOut :
108 | (ForwardJ == 2'b10) ? WB_MemReadData : WB_DataBusC;
109 |
110 |
111 | **ForwardJ**
112 |
113 | 注意到当我们的CPU中增加了jr指令的支持后,ID段也是有可能需要转发的,这使得我们在教材的基础上增加了ForwardJ信号,用于前向转发jr指令需要的寄存器值。此时转发可能来自ID/EX,EX/MEM,MEM/WB三个寄存器。如果检测到jr指令跳转位置的寄存器号与ID/EX段的写入寄存器相同,那么需要从ALUOut转发;如果和EX/MEM段的写入寄存器相同,那需要从ReadData处转发;若同MEM/WB的写入寄存器相同,那就转发将要写回的DatabusC。
114 |
115 | if ( ID.PCSrc == 3 && ID/EX.RegWrite
116 | and ( ID/EX.RegisterRd != 0 )
117 | and ( ID/EX.RegisterRd == IF/ID.Rs))
118 | ForwardJ = 01
119 |
120 |
121 | if ( ID.PCSrc == 3 && EX/MEM.RegWrite
122 | and ( EX/MEM.RegisterRd != 0 )
123 | and ( EX/MEM.RegisterRd == IF/ID.Rs))
124 | ForwardJ = 10
125 |
126 |
127 | if ( ID.PCSrc == 3 && MEM/WB.RegWrite
128 | and ( MEM/WB.RegisterRd != 0 )
129 | and ( MEM/WB.RegisterRd == IF/ID.Rs))
130 | ForwardJ = 11
131 |
132 |
133 | verilog代码如下。先生成控制信号
134 |
135 | // Forward strategy for JR
136 | if(ID_PCSrc == 3'b011 && ID_EX_RegWrite && ID_EX_AddrC != 5'h00
137 | && ID_EX_AddrC == IF_ID_Rs) begin
138 | ForwardJ = 2'b01;
139 | end
140 | else if(ID_PCSrc == 3'b011 && EX_MEM_RegWrite && EX_MEM_AddrC != 5'h00
141 | && EX_MEM_AddrC == IF_ID_Rs) begin
142 | ForwardJ = 2'b10;
143 | end
144 | else if(ID_PCSrc == 3'b011 && MEM_WB_RegWrite && MEM_WB_AddrC != 5'h00
145 | && MEM_WB_AddrC == IF_ID_Rs) begin
146 | ForwardJ = 2'b11;
147 | end
148 | else
149 | ForwardJ = 2'b00;
150 |
151 |
152 |
153 | 根据控制信号选择前传的数据
154 |
155 | assign ForwardJData = (ForwardJ == 2'b00) ? ID_DataBusA :
156 | (ForwardJ == 2'b01) ? EX_ALUOut :
157 | (ForwardJ == 2'b10) ? WB_MemReadData : WB_DataBusC;
158 |
159 |
160 | ### 冒险单元
161 |
162 | 冒险检测单元主要解决load-use,beq类指令和jump类指令的三种冒险。为了实现冒险控制,我们添加PC.write和IF/ID.write两个寄存器写入控制信号和IF/ID.flush和ID/EX.flush两个寄存器清空的控制信号。其中只有write信号为1时对应寄存器在上升沿才能被写入新值,一旦flush信号取1,时钟上升沿时直接清空整个寄存器。我们通过这四个控制信号完成冒险控制。
163 |
164 | **load-use**
165 |
166 | 当ID/EX段发现是load指令,且读取寄存器号与下一条指令的将要读取的寄存器号相同时,CPU知道会触发load-use冒险,这意味着下一条必须stall一个周期,即我们要禁止PC、IF/ID寄存器的写入,同时下个上升沿到来后的ID/EX内的指令是不能用的,应该flush掉。伪码如下:
167 |
168 | if ( ID/EX.MemRead && ( ID/EX.Rt == IF/ID.Rs || ID/EX.Rt == IF/ID.Rt))
169 | PC.write = 0
170 | IF/ID.write = 0
171 | IF/ID.flush = 0
172 | ID/EX.flush = 1
173 |
174 |
175 | verilog代码如下。
176 |
177 | // Load use
178 | if(ID_EX_MemRead && (ID_EX_Rt == IF_ID_Rs || ID_EX_Rt == IF_ID_Rt )) begin
179 | PCWrite_mark[2] = 1'b0;
180 | IF_ID_write_mark[2] = 1'b0;
181 | IF_ID_flush_mark[2] = 1'b0;
182 | ID_EX_flush_mark[2] = 1'b1;
183 | end
184 |
185 |
186 | **beq类冒险**
187 |
188 | 这类冒险只有当判断到Branch结果时才能够知道,即在EX段才能被发现。一旦发现Branch将成功跳转,那么进入流水线的后两条指令都是不能用的,必须flush掉,伪码如下:
189 |
190 | if ( EX.PCSrc == 1 && EX.ALUOut[0] == 1 )
191 | PC.write = 1
192 | IF/ID.write = 1
193 | IF/ID.flush = 1
194 | ID/EX.flush = 1
195 |
196 |
197 | verilog代码如下。
198 |
199 | // Branch
200 | if (EX_PCSrc == 3'd1 && EX_ALUOut_0) begin
201 | PCWrite_mark[0] = 1'b1;
202 | IF_ID_write_mark[0] = 1'b1;
203 | IF_ID_flush_mark[0] = 1'b1;
204 | ID_EX_flush_mark[0] = 1'b1;
205 | end
206 |
207 |
208 | **jump类冒险**
209 |
210 | 这类冒险在ID段被发现,进入流水线后一条指令是没有用的,必须flush掉,伪码如下:
211 |
212 | if ( ID.PCSrc != 0 )
213 | PC.write = 1
214 | IF/ID.write = 1
215 | IF/ID.flush = 1
216 | ID/EX.flush = 0
217 |
218 |
219 | verilog代码如下。
220 |
221 | // Jump
222 | if(ID_PCSrc[2:1]!=2'b00) begin
223 | PCWrite_mark[1] = 1'b1;
224 | IF_ID_write_mark[1] = 1'b1;
225 | IF_ID_flush_mark[1] = 1'b1;
226 | ID_EX_flush_mark[1] = 1'b0;
227 | end
228 |
229 |
230 | **flush与中断**
231 |
232 | 还有一点值得交代的是中断遇到flush指令的问题。在我们的实现中,中断的实现就是强行将ID段的执行指令的控制信号改为中断的控制信号,同时将当前指令的PC+4存入对应寄存器。而当中断恰好遇到一个flush的信号时,我们需要保存的不是当前这条指令对应的PC+4(已经被flush了),而是更前面的那条,对应的情况有三种。
233 |
234 | 1. ID/EX.flush == 1: ID/EX.PCadd4 -= 4
235 |
236 | 2. IF/ID.flush == 1: IF/ID.PCadd4 -= 4
237 |
238 | 3. ID/EX.flush == 1 && ID/EX.flush == 1: IF/ID.PCadd4 -= 8
239 | ID/EX.PCadd4 -= 4
240 |
241 | verilog代码如下。
242 |
243 | if(IF_ID_flush) begin
244 | if(ID_EX_flush) begin
245 | PC_add_4_out <= PC_add_4_in - 8;
246 | end
247 | else begin
248 | PC_add_4_out <= PC_add_4_in - 4;
249 | end
250 | Instruct_out <= 32'h0000_0000;
251 | end
252 |
253 |
254 | MIPS汇编代码
255 | ------------
256 |
257 | ### MIPS汇编代码设计
258 |
259 | MIPS汇编代码由初始化部分,UART部分,计算最大公约数部分以及中断处理这四个部分组成。
260 |
261 | #### 初始化部分
262 |
263 | 初始化部分先是将PC置为全0以允许中断,然后再是对计时器进行设置,将周期置为0.5ms,也就是数码管刷新的频率为2kHz。
264 |
265 | #### UART部分
266 |
267 | UART部分采用轮询方式,因此首先需要禁用UART中断。UART分为发送和接收两个部分,接收部分在收到数据后判断是否为0,当收到两个非零数据后把数据传入计算最大公约数部分,并将结果再通过UART传到电脑。
268 |
269 | #### 计算最大公约数部分
270 |
271 | 计算最大公约数部分采用更相减损术,始终用两个数中的较大数减去较小数,并用该差值替代原来较大那个数。直到两个数中有一个为0为止,此时另一个数及为他们的最大公约数。
272 |
273 | #### 中断处理部分
274 |
275 | 中断处理部分的逻辑为:禁止中断,然后保护现场,处理中断,恢复现场,使能中断,退出中断服务程序。这里因为寄存器总量足够,因此为了提高代码执行效率,并没有在中断和主程序中采用相同的寄存器,这样就不需要保护现场和恢复现场这两个部分了。
276 |
277 | 在中断处理程序部分,我们需要通过数码管显示输入的两个数值。首先,我们读取当前数码管的状态,也就是现在是哪个数码管在显示,通过当前状态判断下一个需要显示的数码管的编号。然后读取需要输出的数值,将该数值通过软件译码后再与需要显示的数码管编号结合并存储到控制数码管的寄存器中实现数码管显示。
278 |
279 | ### 优化MIPS代码
280 |
281 | 在CPU中,MIPS代码是以二进制的方式存储在ROM中,并且使用多路选择器选择需要执行的语句的。经实验发现代码越短,多路选择的选择信号输入使用的位数越少,CPU流水线最后的主频会越高。因此,我们最后将MIPS代码的长度控制在了128行,这样使用7位即可对代码进行多路选择,相比用8位对代码多路选择要快一些,即减少了指令存储器取指的时间,缩短了关键路径上的延时。
282 |
283 | 另一方面,我们调整MIPS代码顺序,来减少转发和冒险的发生。因此,在缩短了MIPS代码的长度之后,我们再在Quartus中研究了流水线的Critical
284 | Path。我们发现最长路径对应MIPS代码中beq语句采用寄存器值在beq上两条语句被写入的情况。也就是如下面的代码所示的情况。
285 |
286 | addi $s6, $zero, 1 #decode of '1'
287 | addi $s2, $zero, 0xf9
288 | beq $s6, $s5, DECODE_COMPLETE
289 |
290 |
291 | 对于这种情况,我们可以调整代码顺序,变为如下代码,从而避免长数据通路发生。
292 |
293 | addi $s2, $zero, 0xf9 #decode of '1'
294 | addi $s6, $zero, 1
295 | beq $s6, $s5, DECODE_COMPLETE
296 |
297 |
298 | 优化CPU
299 | ------------
300 |
301 | 我们为了提高流水线CPU的时钟频率,主要通过了几条途径:
302 |
303 | 1. 观察最长延时路径(关键路径),缩短关键路径上的延时
304 |
305 | 我们第一次时序报告分析指出关键路径为beq等指令所用寄存器数据从上两条的MEM段转发得到后,经过beq等指令的EX段,在经过冒险单元,最后得到要分支的PC的值。因此,我们通过观察RTL级结构,优化了该路径上所有的组合逻辑。例如,我们修改了寄存器堆模块,使之初始化时包括\$0,并且禁止写入\$0,在读取寄存器数据时不做判断,这样就减少读取的组合逻辑;同时由于\$0不可被改变,因此各单元内是否写入\$0的判断均可删去,简化逻辑。再例如,我们使用或运算代替判等0的运算,优化多路选择的对应关系等,来简化一些组合逻辑,减少电路延时。
306 |
307 | 2. 优化MIPS程序,减少指令存储器获取指令的延时
308 |
309 | 我们发现CPU最大时钟频率与ROM有关,即与所设计MIPS代码有关。同上关键路径,我们通过调整MIPS代码顺序,一方面使CPU不会经过上述关键路径,另一方面,减少了其他转发与冒险的发生。与此同时,我们适当减少MIPS代码量,使ROM综合出的组合逻辑减少,即使获取指令的延时减少。
310 |
311 | 3. 优化QUARTUS综合设置,提高布线合理度,减少延时
312 |
313 | 我们根据Quartus自带功能Timing Optimization
314 | Adivisor优化了Quartus综合设置,提高了综合器综合、布线、分析的合理度,提高了时钟频率。
315 |
316 | 综合情况
317 | ------------
318 |
319 | | Item | Value |
320 | | ------------------------------- | ---------------------: |
321 | | Total logic elements | 4,423 / 33,216 (13%) |
322 | | Total combinational functions | 3,878 / 33,216 (12%) |
323 | | Dedicated logic registers | 1,932 / 33,216 (6%) |
324 | | Max Frequency | 80.10 MHz |
325 |
--------------------------------------------------------------------------------
/img/alu.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/synxlin/mips-cpu/23831238a24d61373bac7149eaab26c898dae2cd/img/alu.png
--------------------------------------------------------------------------------
/img/overall.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/synxlin/mips-cpu/23831238a24d61373bac7149eaab26c898dae2cd/img/overall.png
--------------------------------------------------------------------------------
/img/pipeline.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/synxlin/mips-cpu/23831238a24d61373bac7149eaab26c898dae2cd/img/pipeline.png
--------------------------------------------------------------------------------
/img/uart.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/synxlin/mips-cpu/23831238a24d61373bac7149eaab26c898dae2cd/img/uart.png
--------------------------------------------------------------------------------
/src/ALU/ALU.v:
--------------------------------------------------------------------------------
1 | module ALU(A, B, ALUFun, Sign, Z);
2 | input Sign;
3 | input [5:0] ALUFun;
4 | input [31:0] A, B;
5 | output [31:0] Z;
6 | wire zero,neg;
7 | wire [31:0] S0, S1, S2, S3;
8 |
9 | AddSub AddSub(.A(A), .B(B), .ALUFun(ALUFun), .Sign(Sign), .Z(zero), .N(neg), .S(S0));
10 | Cmp Cmp(.ALUFun(ALUFun), .Sign(Sign), .Z(zero), .N(neg), .S(S1));
11 | Logic Logic(.A(A), .B(B), .ALUFun(ALUFun), .S(S2));
12 | Shift Shift(.A(A), .B(B), .ALUFun(ALUFun), .S(S3));
13 |
14 | // Choose the type of calculation
15 | assign Z =
16 | (ALUFun[5:4] == 2'b00)? S0:
17 | (ALUFun[5:4] == 2'b10)? S3:
18 | (ALUFun[5:4] == 2'b01)? S2: S1;
19 |
20 | endmodule
21 |
22 |
23 |
24 | // add or sub calculation
25 | module AddSub(A, B, ALUFun, Sign, Z, N, S);
26 | input Sign;
27 | input [5:0] ALUFun;
28 | input [31:0] A, B;
29 | output Z, N;
30 | output [32:0] S;
31 |
32 | // Choose which number to compare when determining Z
33 | assign Z =
34 | (ALUFun[3] && |A)? 0:
35 | (~ALUFun[3] && |S)? 0: 1;
36 |
37 | // Choose to perform add or sub
38 | assign S =
39 | (ALUFun[0])? ({1'b0, A} - {1'b0, B}): ({1'b0, A} + {1'b0, B});
40 |
41 | // Determine N according to the Sign signal and carryin
42 | assign N =
43 | (ALUFun[3] && Sign && A[31])? 1:
44 | (~ALUFun[3] && Sign && S[31])? 1:
45 | (~ALUFun[3] && ~Sign && S[32])? 1: 0;
46 |
47 | endmodule
48 |
49 |
50 |
51 | // comparation calculation
52 | module Cmp(ALUFun, Sign, Z, N, S);
53 | input Sign, Z, N;
54 | input [5:0] ALUFun;
55 | output [31:0] S;
56 |
57 | // Determine output according to N and Z
58 | assign S[0] =
59 | (ALUFun[3:1] == 3'b001)? Z:
60 | (ALUFun[3:1] == 3'b000)? ~Z:
61 | (ALUFun[3:1] == 3'b010)? N:
62 | (ALUFun[3:1] == 3'b110)? (N || Z):
63 | (ALUFun[3:1] == 3'b101)? N: (~N && ~Z);
64 | assign S[31:1]=0;
65 |
66 | endmodule
67 |
68 |
69 | // logical calculation
70 | module Logic(A, B, ALUFun, S);
71 | input [5:0] ALUFun;
72 | input [31:0] A, B;
73 | output [31:0] S;
74 |
75 | // result of logical calculation
76 | assign S =
77 | (ALUFun[3:0] == 4'b0001)? ~(A | B):
78 | (ALUFun[3:0] == 4'b1110)? (A | B):
79 | (ALUFun[3:0] == 4'b1000)? (A & B):
80 | (ALUFun[3:0] == 4'b0110)? (A ^ B): A;
81 |
82 | endmodule
83 |
84 |
85 |
86 | // shift calculation
87 | module Shift(A, B, ALUFun, S);
88 | input [5:0] ALUFun;
89 | input [31:0] A, B;
90 | output [31:0] S;
91 |
92 | assign S =
93 |
94 | // srl or sra with the msb being '0'
95 | (ALUFun[1:0] == 2'b01 || (ALUFun[1:0] == 2'b11 && B[31] == 0))? B >> A[4:0]:
96 |
97 | // sra with the msb being '1'
98 | (ALUFun[1:0] == 2'b11 && B[31] == 1)? ({32'hFFFFFFFF, B} >> A[4:0]):
99 |
100 | // sll
101 | (ALUFun[1:0] == 2'b00)? B << A[4:0]: 0;
102 |
103 | endmodule
--------------------------------------------------------------------------------
/src/ALU/ALU_satisfied_requirements.v:
--------------------------------------------------------------------------------
1 | module ALU(A, B, ALUFun, Sign, Z);
2 | input Sign;
3 | input [5:0] ALUFun;
4 | input [31:0] A, B;
5 | output [31:0] Z;
6 | wire zero,neg;
7 | wire [31:0] S0, S1, S2, S3;
8 |
9 | AddSub AddSub(.A(A), .B(B), .ALUFun(ALUFun), .Sign(Sign), .Z(zero), .N(neg), .S(S0));
10 | Cmp Cmp(.ALUFun(ALUFun), .Sign(Sign), .Z(zero), .N(neg), .S(S1));
11 | Logic Logic(.A(A), .B(B), .ALUFun(ALUFun), .S(S2));
12 | Shift Shift(.A(A), .B(B), .ALUFun(ALUFun), .S(S3));
13 |
14 | assign Z =
15 | (ALUFun[5:4] == 2'b00)? S0:
16 | (ALUFun[5:4] == 2'b10)? S3:
17 | (ALUFun[5:4] == 2'b01)? S2: S1;
18 |
19 | endmodule
20 |
21 |
22 |
23 | module AddSub(A, B, ALUFun, Sign, Z, N, S);
24 | input Sign;
25 | input [5:0] ALUFun;
26 | input [31:0] A, B;
27 | output Z, N;
28 | output [32:0] S;
29 |
30 | assign Z =
31 | (ALUFun[3] && |A)? 0:
32 | (~ALUFun[3] && |S)? 0: 1;
33 | assign S =
34 | (ALUFun[0])? ({1'b0, A} - {1'b0, B}): ({1'b0, A} + {1'b0, B});
35 | assign N =
36 | (ALUFun[3] && Sign && A[31])? 1:
37 | (~ALUFun[3] && Sign && S[31])? 1:
38 | (~ALUFun[3] && ~Sign && S[32])? 1: 0;
39 |
40 | endmodule
41 |
42 |
43 |
44 | module Cmp(ALUFun, Sign, Z, N, S);
45 | input Sign, Z, N;
46 | input [5:0] ALUFun;
47 | output [31:0] S;
48 |
49 | assign S[0] =
50 | (ALUFun[3:1] == 3'b001)? Z:
51 | (ALUFun[3:1] == 3'b000)? ~Z:
52 | (ALUFun[3:1] == 3'b010)? N:
53 | (ALUFun[3:1] == 3'b110)? (N || Z):
54 | (ALUFun[3:1] == 3'b101)? N: (~N && ~Z);
55 | assign S[31:1]=0;
56 |
57 | endmodule
58 |
59 |
60 |
61 | module Logic(A, B, ALUFun, S);
62 | input [5:0] ALUFun;
63 | input [31:0] A, B;
64 | output [31:0] S;
65 |
66 | assign S =
67 | (ALUFun[3:0] == 4'b0001)? ~(A | B):
68 | (ALUFun[3:0] == 4'b1110)? (A | B):
69 | (ALUFun[3:0] == 4'b1000)? (A & B):
70 | (ALUFun[3:0] == 4'b0110)? (A ^ B): A;
71 |
72 | endmodule
73 |
74 |
75 |
76 | module Shift(A, B, ALUFun, S);
77 | input [5:0] ALUFun;
78 | input [31:0] A, B;
79 | output [31:0] S;
80 | /*
81 | assign S =
82 | (ALUFun[1:0] == 2'b01 || (ALUFun[1:0] == 2'b11 && B[31] == 0))? B >> A[4:0]:
83 | (ALUFun[1:0] == 2'b11 && B[31] == 1)? ({32'hFFFFFFFF, B} >> A[4:0]):
84 | (ALUFun[1:0] == 2'b00)? B << A[4:0]: 0;
85 | */
86 | wire [31:0] S0, S1, S2;
87 | Sll Sll(.A(A), .B(B), .S(S0));
88 | Srl Srl(.A(A), .B(B), .S(S1));
89 | Sra Sra(.A(A), .B(B), .S(S2));
90 |
91 | assign S =
92 | (ALUFun[1:0] == 2'b00)? S0:
93 | (ALUFun[1:0] == 2'b01)? S1:
94 | (ALUFun[1:0] == 2'b11)? S2: 0;
95 |
96 | endmodule
97 |
98 |
99 |
100 | module Sll(A, B, S);
101 | input [31:0] A, B;
102 | output [31:0] S;
103 |
104 | wire [31:0] sll_1, sll_2, sll_4, sll_8;
105 |
106 | assign sll_1 = A[0]? (B << 1'd1): B;
107 | assign sll_2 = A[1]? (sll_1 << 2'd2): sll_1;
108 | assign sll_4 = A[2]? (sll_2 << 3'd4): sll_2;
109 | assign sll_8 = A[3]? (sll_4 << 4'd8): sll_4;
110 | assign S = A[4]? (sll_8 << 5'd16): sll_8;
111 |
112 | endmodule
113 |
114 |
115 |
116 | module Srl(A, B, S);
117 | input [31:0] A, B;
118 | output [31:0] S;
119 |
120 | wire [31:0] srl_1, srl_2, srl_4, srl_8;
121 |
122 | assign srl_1 = A[0]? (B >> 1'd1): B;
123 | assign srl_2 = A[1]? (srl_1 >> 2'd2): srl_1;
124 | assign srl_4 = A[2]? (srl_2 >> 3'd4): srl_2;
125 | assign srl_8 = A[3]? (srl_4 >> 4'd8): srl_4;
126 | assign S = A[4]? (srl_8 >> 5'd16): srl_8;
127 |
128 | endmodule
129 |
130 |
131 |
132 | module Sra(A, B, S);
133 | input [31:0] A, B;
134 | output [31:0] S;
135 |
136 | wire [31:0] sra_1, sra_2, sra_4, sra_8;
137 |
138 | assign sra_1 = A[0]? ({1'h1, B} >> 1'd1): B;
139 | assign sra_2 = A[1]? ({2'h3, sra_1} >> 2'd2): sra_1;
140 | assign sra_4 = A[2]? ({4'hf, sra_2} >> 3'd4): sra_2;
141 | assign sra_8 = A[3]? ({8'hff, sra_4} >> 4'd8): sra_4;
142 | assign S = A[4]? ({16'hffff, sra_8} >> 5'd16): sra_8;
143 |
144 | endmodule
145 |
--------------------------------------------------------------------------------
/src/ALU/ALU_超前进位.v:
--------------------------------------------------------------------------------
1 | module ALU(A, B, ALUFun, Sign, Z);
2 | input Sign;
3 | input [5:0] ALUFun;
4 | input [31:0] A, B;
5 | output [31:0] Z;
6 | wire zero,neg;
7 | wire [31:0] S0, S1, S2, S3;
8 |
9 | AddSub AddSub(.A(A), .B(B), .ALUFun(ALUFun), .Sign(Sign), .Z(zero), .N(neg), .S(S0));
10 | Cmp Cmp(.ALUFun(ALUFun), .Sign(Sign), .Z(zero), .N(neg), .S(S1));
11 | Logic Logic(.A(A), .B(B), .ALUFun(ALUFun), .S(S2));
12 | Shift Shift(.A(A), .B(B), .ALUFun(ALUFun), .S(S3));
13 |
14 | assign Z =
15 | (ALUFun[5:4] == 2'b00)? S0:
16 | (ALUFun[5:4] == 2'b10)? S3:
17 | (ALUFun[5:4] == 2'b01)? S2: S1;
18 |
19 | endmodule
20 |
21 | module AddSub(A, B, ALUFun, Sign, Z, N, S);
22 | input Sign;
23 | input [5:0] ALUFun;
24 | input [31:0] A, B;
25 | output Z, N;
26 | output [32:0] S;
27 | wire [31:0] S1,S2;
28 | wire Co1, Co2;
29 | adder_32 adder_32_1(A,B,S1,1'b0,Co1);
30 | adder_32 adder_32_2(A,~B,S2,1'b0,Co2);
31 |
32 |
33 | assign Z =
34 | (ALUFun[3] && |A)? 0:
35 | (~ALUFun[3] && |S)? 0: 1;
36 |
37 |
38 | assign S =
39 | (ALUFun[0])? ({Co2,S2}): ({Co1,S1});
40 | assign N =
41 | (ALUFun[3] && Sign && A[31])? 1:
42 | (~ALUFun[3] && Sign && S[31])? 1:
43 | (~ALUFun[3] && ~Sign && S[32])? 1: 0;
44 |
45 | endmodule
46 |
47 | module Cmp(ALUFun, Sign, Z, N, S);
48 | input Sign, Z, N;
49 | input [5:0] ALUFun;
50 | output [31:0] S;
51 |
52 | assign S[0] =
53 | (ALUFun[3:1] == 3'b001)? Z:
54 | (ALUFun[3:1] == 3'b000)? ~Z:
55 | (ALUFun[3:1] == 3'b010)? N:
56 | (ALUFun[3:1] == 3'b110)? (N || Z):
57 | (ALUFun[3:1] == 3'b101)? N: (~N && ~Z);
58 | assign S[31:1]=0;
59 |
60 | endmodule
61 |
62 |
63 |
64 | module Logic(A, B, ALUFun, S);
65 | input [5:0] ALUFun;
66 | input [31:0] A, B;
67 | output [31:0] S;
68 |
69 | assign S =
70 | (ALUFun[3:0] == 4'b0001)? ~(A | B):
71 | (ALUFun[3:0] == 4'b1110)? (A | B):
72 | (ALUFun[3:0] == 4'b1000)? (A & B):
73 | (ALUFun[3:0] == 4'b0110)? (A ^ B): A;
74 |
75 | endmodule
76 |
77 |
78 |
79 | module Shift(A, B, ALUFun, S);
80 | input [5:0] ALUFun;
81 | input [31:0] A, B;
82 | output [31:0] S;
83 |
84 | assign S =
85 | (ALUFun[1:0] == 2'b01 || (ALUFun[1:0] == 2'b11 && B[31] == 0))? B >> A[4:0]:
86 | (ALUFun[1:0] == 2'b11 && B[31] == 1)? ({32'hFFFFFFFF, B} >> A[4:0]):
87 | (ALUFun[1:0] == 2'b00)? B << A[4:0]: 0;
88 |
89 | endmodule
90 |
91 | module adder_32(a,b,s,cin,cout);
92 | input [31:0]a,b;
93 | input cin;
94 | output [31:0]s;
95 | output cout;
96 |
97 |
98 | adder_16 adder_16_1 (a[15:0],b[15:0],s[15:0],cin,co1);
99 | adder_16 adder_16_2 (a[31:16],b[31:16],s[31:16],co1,cout);
100 |
101 | endmodule
102 |
103 |
104 | module adder_16 (a,b,s,cin,gg5);
105 | input [15:0] a, b;
106 | input cin;
107 | output [15:0] s;
108 | output gg5;
109 |
110 | wire pp4, pp3, pp2, pp1;
111 | wire gg4, gg3, gg2, gg1;
112 | wire [14:0] Cp;
113 | wire [15:0] p, g;
114 |
115 |
116 | claslice i1 (p[3], p[2], p[1], p[0], g[3], g[2], g[1], g[0], cin, Cp[2], Cp[1], Cp[0], pp1, gg1);
117 | claslice i2 (p[7], p[6], p[5], p[4], g[7], g[6], g[5], g[4], Cp[3], Cp[6], Cp[5], Cp[4], pp2, gg2);
118 | claslice i3 (p[11], p[10], p[9], p[8], g[11], g[10], g[9], g[8], Cp[7], Cp[10], Cp[9], Cp[8], pp3, gg3);
119 | claslice i4 (p[15], p[14], p[13], p[12], g[15], g[14], g[13], g[12], Cp[11], Cp[14], Cp[13], Cp[12], pp4, gg4);
120 | claslice i5 (pp4, pp3, pp2, pp1, gg4, gg3, gg2, gg1, cin, Cp[11], Cp[7], Cp[3], pp5, gg5);
121 |
122 | pg i0(a[15:0], b[15:0], p[15:0], g[15:0]);
123 |
124 | assign s[0] = p[0] ^ cin;
125 | assign s[1] = p[1] ^ Cp[0];
126 | assign s[2] = p[2] ^ Cp[1];
127 | assign s[3] = p[3] ^ Cp[2];
128 | assign s[4] = p[4] ^ Cp[3];
129 | assign s[5] = p[5] ^ Cp[4];
130 | assign s[6] = p[6] ^ Cp[5];
131 | assign s[7] = p[7] ^ Cp[6];
132 | assign s[8] = p[8] ^ Cp[7];
133 | assign s[9] = p[9] ^ Cp[8];
134 | assign s[10] = p[10] ^ Cp[9];
135 | assign s[11] = p[11] ^ Cp[10];
136 | assign s[12] = p[12] ^ Cp[11];
137 | assign s[13] = p[13] ^ Cp[12];
138 | assign s[14] = p[14] ^ Cp[13];
139 | assign s[15] = p[15] ^ Cp[14];
140 |
141 | endmodule
142 |
143 | module claslice(p[3], p[2], p[1], p[0], g[3], g[2], g[1], g[0], Co, Cp[2], Cp[1], Cp[0], pp, gg);
144 |
145 | input [3:0] p, g;
146 | input Co;
147 | output [2:0] Cp;
148 | output pp, gg;
149 | assign Cp[0] = g[0] | p[0] & Co;
150 | assign Cp[1] = g[1] | p[1] & Cp[0];
151 | assign Cp[2] = g[2] | p[2] & Cp[1];
152 | assign pp = p[3] & p[2] & p[1] & p[0];
153 | assign gg = g[3] | (p[3] & (g[2] | p[2] & (g[1] | p[1] & g[0])));
154 | endmodule
155 |
156 | module pg(a, b, p, g);
157 | input [15:0] a, b;
158 | output [15:0] p, g;
159 | assign p = a ^ b;
160 | assign g = a & b;
161 | endmodule
162 |
163 |
--------------------------------------------------------------------------------
/src/Assembler/BinaryCode.txt:
--------------------------------------------------------------------------------
1 | // j INIT
2 | 0: data <= 32'b00001000000000000000000000000011;
3 | // j INTER
4 | 1: data <= 32'b00001000000000000000000000101100;
5 | // j EXCEPT
6 | 2: data <= 32'b00001000000000000000000010000000;
7 | //INIT:
8 | // addi $t0, $zero, 0x0014
9 | 3: data <= 32'b00100000000010000000000000010100;
10 | // jr $t0
11 | 4: data <= 32'b00000001000000000000000000001000;
12 | // lui $s0, 0x4000
13 | 5: data <= 32'b00111100000100000100000000000000;
14 | // sw $zero, 8($s0)
15 | 6: data <= 32'b10101110000000000000000000001000;
16 | // addi $s1, $zero, -25000
17 | 7: data <= 32'b00100000000100011001111001011000;
18 | // sw $s1, 0($s0)
19 | 8: data <= 32'b10101110000100010000000000000000;
20 | // addi $s1, $zero, -1
21 | 9: data <= 32'b00100000000100011111111111111111;
22 | // sw $s1, 4($s0)
23 | 10: data <= 32'b10101110000100010000000000000100;
24 | // addi $s1, $zero, 3
25 | 11: data <= 32'b00100000000100010000000000000011;
26 | // sw $s1, 8($s0)
27 | 12: data <= 32'b10101110000100010000000000001000;
28 | // sw $t0, 32($s0)
29 | 13: data <= 32'b10101110000010000000000000100000;
30 | //UART_START:
31 | // addi $s1, $zero, -1
32 | 14: data <= 32'b00100000000100011111111111111111;
33 | //UART_LOOP:
34 | // lw $t0, 32($s0)
35 | 15: data <= 32'b10001110000010000000000000100000;
36 | // andi $t0, $t0, 0x08
37 | 16: data <= 32'b00110001000010000000000000001000;
38 | // beq $t0, $zero, UART_LOOP
39 | 17: data <= 32'b00010001000000001111111111111101;
40 | // lw $v1, 28($s0)
41 | 18: data <= 32'b10001110000000110000000000011100;
42 | // beq $v1, $zero, UART_LOOP
43 | 19: data <= 32'b00010000011000001111111111111011;
44 | // beq $s1, $zero, LOAD_2
45 | 20: data <= 32'b00010010001000000000000000000011;
46 | // addi $s4, $v1, 0
47 | 21: data <= 32'b00100000011101000000000000000000;
48 | // addi $s1, $s1, 1
49 | 22: data <= 32'b00100010001100010000000000000001;
50 | // j UART_LOOP
51 | 23: data <= 32'b00001000000000000000000000001111;
52 | //LOAD_2:
53 | // addi $s3, $v1, 0
54 | 24: data <= 32'b00100000011100110000000000000000;
55 | // addi $v0, $s4, 0
56 | 25: data <= 32'b00100010100000100000000000000000;
57 | //GCD:
58 | // beq $v0, $zero, ANS1
59 | 26: data <= 32'b00010000010000000000000000001000;
60 | // beq $v1, $zero, ANS2
61 | 27: data <= 32'b00010000011000000000000000001001;
62 | // sub $t3, $v0, $v1
63 | 28: data <= 32'b00000000010000110101100000100010;
64 | // bgtz $t3, LOOP1
65 | 29: data <= 32'b00011101011000000000000000000001;
66 | // bltz $t3, LOOP2
67 | 30: data <= 32'b00000101011000000000000000000010;
68 | //LOOP1:
69 | // sub $v0, $v0, $v1
70 | 31: data <= 32'b00000000010000110001000000100010;
71 | // j GCD
72 | 32: data <= 32'b00001000000000000000000000011010;
73 | //LOOP2:
74 | // sub $v1, $v1, $v0
75 | 33: data <= 32'b00000000011000100001100000100010;
76 | // j GCD
77 | 34: data <= 32'b00001000000000000000000000011010;
78 | //ANS1:
79 | // add $a0, $v1, $zero
80 | 35: data <= 32'b00000000011000000010000000100000;
81 | // j RESULT_DISPLAY
82 | 36: data <= 32'b00001000000000000000000000100110;
83 | //ANS2:
84 | // add $a0, $v0, $zero
85 | 37: data <= 32'b00000000010000000010000000100000;
86 | //RESULT_DISPLAY:
87 | // sw $a0, 12($s0)
88 | 38: data <= 32'b10101110000001000000000000001100;
89 | //UART_SEND_BACK:
90 | // lw $t0, 32($s0)
91 | 39: data <= 32'b10001110000010000000000000100000;
92 | // andi $t0, $t0, 0x10
93 | 40: data <= 32'b00110001000010000000000000010000;
94 | // bne $t0, $zero, UART_SEND_BACK
95 | 41: data <= 32'b00010101000000001111111111111101;
96 | // sw $a0, 24($s0)
97 | 42: data <= 32'b10101110000001000000000000011000;
98 | // j UART_START
99 | 43: data <= 32'b00001000000000000000000000001110;
100 | //INTER:
101 | // lw $t7, 8($s0)
102 | 44: data <= 32'b10001110000011110000000000001000;
103 | // andi $t7, $t7, 0xfff9
104 | 45: data <= 32'b00110001111011111111111111111001;
105 | // sw $t7, 8($s0)
106 | 46: data <= 32'b10101110000011110000000000001000;
107 | // addi $t3, $zero, 1
108 | 47: data <= 32'b00100000000010110000000000000001;
109 | // addi $t4, $zero, 2
110 | 48: data <= 32'b00100000000011000000000000000010;
111 | // addi $t5, $zero, 4
112 | 49: data <= 32'b00100000000011010000000000000100;
113 | // addi $t6, $zero, 8
114 | 50: data <= 32'b00100000000011100000000000001000;
115 | // lw $t7, 20($s0)
116 | 51: data <= 32'b10001110000011110000000000010100;
117 | // andi $t7, $t7, 0xf00
118 | 52: data <= 32'b00110001111011110000111100000000;
119 | // srl $t7, $t7, 8
120 | 53: data <= 32'b00000000000011110111101000000010;
121 | // beq $t7, $t3, DIGITAL_TUBE_1
122 | 54: data <= 32'b00010001111010110000000000000110;
123 | // beq $t7, $t4, DIGITAL_TUBE_2
124 | 55: data <= 32'b00010001111011000000000000001010;
125 | // beq $t7, $t5, DIGITAL_TUBE_3
126 | 56: data <= 32'b00010001111011010000000000001101;
127 | //DIGITAL_TUBE_0:
128 | // andi $s5, $s3, 0x0f
129 | 57: data <= 32'b00110010011101010000000000001111;
130 | // jal DECODE
131 | 58: data <= 32'b00001100000000000000000001001011;
132 | // addi $s5, $s2, 0x100
133 | 59: data <= 32'b00100010010101010000000100000000;
134 | // j DIGITAL_TUBE_DISPLAY
135 | 60: data <= 32'b00001000000000000000000001111001;
136 | //DIGITAL_TUBE_1:
137 | // andi $s5, $s3, 0xf0
138 | 61: data <= 32'b00110010011101010000000011110000;
139 | // srl $s5, $s5, 4
140 | 62: data <= 32'b00000000000101011010100100000010;
141 | // jal DECODE
142 | 63: data <= 32'b00001100000000000000000001001011;
143 | // addi $s5, $s2, 0x200
144 | 64: data <= 32'b00100010010101010000001000000000;
145 | // j DIGITAL_TUBE_DISPLAY
146 | 65: data <= 32'b00001000000000000000000001111001;
147 | //DIGITAL_TUBE_2:
148 | // andi $s5, $s4, 0x0f
149 | 66: data <= 32'b00110010100101010000000000001111;
150 | // jal DECODE
151 | 67: data <= 32'b00001100000000000000000001001011;
152 | // addi $s5, $s2, 0x400
153 | 68: data <= 32'b00100010010101010000010000000000;
154 | // j DIGITAL_TUBE_DISPLAY
155 | 69: data <= 32'b00001000000000000000000001111001;
156 | //DIGITAL_TUBE_3:
157 | // andi $s5, $s4, 0xf0
158 | 70: data <= 32'b00110010100101010000000011110000;
159 | // srl $s5, $s5, 4
160 | 71: data <= 32'b00000000000101011010100100000010;
161 | // jal DECODE
162 | 72: data <= 32'b00001100000000000000000001001011;
163 | // addi $s5, $s2, 0x800
164 | 73: data <= 32'b00100010010101010000100000000000;
165 | // j DIGITAL_TUBE_DISPLAY
166 | 74: data <= 32'b00001000000000000000000001111001;
167 | //DECODE:
168 | // addi $s2, $zero, 0xc0
169 | 75: data <= 32'b00100000000100100000000011000000;
170 | // beq $zero, $s5, DECODE_COMPLETE
171 | 76: data <= 32'b00010000000101010000000000101011;
172 | // addi $s2, $zero, 0xf9
173 | 77: data <= 32'b00100000000100100000000011111001;
174 | // addi $s6, $zero, 1
175 | 78: data <= 32'b00100000000101100000000000000001;
176 | // beq $s6, $s5, DECODE_COMPLETE
177 | 79: data <= 32'b00010010110101010000000000101000;
178 | // addi $s2, $zero, 0xa4
179 | 80: data <= 32'b00100000000100100000000010100100;
180 | // addi $s6, $zero, 2
181 | 81: data <= 32'b00100000000101100000000000000010;
182 | // beq $s6, $s5, DECODE_COMPLETE
183 | 82: data <= 32'b00010010110101010000000000100101;
184 | // addi $s2, $zero, 0xb0
185 | 83: data <= 32'b00100000000100100000000010110000;
186 | // addi $s6, $zero, 3
187 | 84: data <= 32'b00100000000101100000000000000011;
188 | // beq $s6, $s5, DECODE_COMPLETE
189 | 85: data <= 32'b00010010110101010000000000100010;
190 | // addi $s2, $zero, 0x99
191 | 86: data <= 32'b00100000000100100000000010011001;
192 | // addi $s6, $zero, 4
193 | 87: data <= 32'b00100000000101100000000000000100;
194 | // beq $s6, $s5, DECODE_COMPLETE
195 | 88: data <= 32'b00010010110101010000000000011111;
196 | // addi $s2, $zero, 0x92
197 | 89: data <= 32'b00100000000100100000000010010010;
198 | // addi $s6, $zero, 5
199 | 90: data <= 32'b00100000000101100000000000000101;
200 | // beq $s6, $s5, DECODE_COMPLETE
201 | 91: data <= 32'b00010010110101010000000000011100;
202 | // addi $s2, $zero, 0x82
203 | 92: data <= 32'b00100000000100100000000010000010;
204 | // addi $s6, $zero, 6
205 | 93: data <= 32'b00100000000101100000000000000110;
206 | // beq $s6, $s5, DECODE_COMPLETE
207 | 94: data <= 32'b00010010110101010000000000011001;
208 | // addi $s2, $zero, 0xf8
209 | 95: data <= 32'b00100000000100100000000011111000;
210 | // addi $s6, $zero, 7
211 | 96: data <= 32'b00100000000101100000000000000111;
212 | // beq $s6, $s5, DECODE_COMPLETE
213 | 97: data <= 32'b00010010110101010000000000010110;
214 | // addi $s2, $zero, 0x80
215 | 98: data <= 32'b00100000000100100000000010000000;
216 | // addi $s6, $zero, 8
217 | 99: data <= 32'b00100000000101100000000000001000;
218 | // beq $s6, $s5, DECODE_COMPLETE
219 | 100: data <= 32'b00010010110101010000000000010011;
220 | // addi $s2, $zero, 0x90
221 | 101: data <= 32'b00100000000100100000000010010000;
222 | // addi $s6, $zero, 9
223 | 102: data <= 32'b00100000000101100000000000001001;
224 | // beq $s6, $s5, DECODE_COMPLETE
225 | 103: data <= 32'b00010010110101010000000000010000;
226 | // addi $s2, $zero, 0x88
227 | 104: data <= 32'b00100000000100100000000010001000;
228 | // addi $s6, $zero, 0x0a
229 | 105: data <= 32'b00100000000101100000000000001010;
230 | // beq $s6, $s5, DECODE_COMPLETE
231 | 106: data <= 32'b00010010110101010000000000001101;
232 | // addi $s2, $zero, 0x83
233 | 107: data <= 32'b00100000000100100000000010000011;
234 | // addi $s6, $zero, 0x0b
235 | 108: data <= 32'b00100000000101100000000000001011;
236 | // beq $s6, $s5, DECODE_COMPLETE
237 | 109: data <= 32'b00010010110101010000000000001010;
238 | // addi $s2, $zero, 0xc6
239 | 110: data <= 32'b00100000000100100000000011000110;
240 | // addi $s6, $zero, 0x0c
241 | 111: data <= 32'b00100000000101100000000000001100;
242 | // beq $s6, $s5, DECODE_COMPLETE
243 | 112: data <= 32'b00010010110101010000000000000111;
244 | // addi $s2, $zero, 0xa1
245 | 113: data <= 32'b00100000000100100000000010100001;
246 | // addi $s6, $zero, 0x0d
247 | 114: data <= 32'b00100000000101100000000000001101;
248 | // beq $s6, $s5, DECODE_COMPLETE
249 | 115: data <= 32'b00010010110101010000000000000100;
250 | // addi $s2, $zero, 0x86
251 | 116: data <= 32'b00100000000100100000000010000110;
252 | // addi $s6, $zero, 0x0e
253 | 117: data <= 32'b00100000000101100000000000001110;
254 | // beq $s6, $s5, DECODE_COMPLETE
255 | 118: data <= 32'b00010010110101010000000000000001;
256 | // addi $s2, $zero, 0x8e
257 | 119: data <= 32'b00100000000100100000000010001110;
258 | //DECODE_COMPLETE:
259 | // jr $ra
260 | 120: data <= 32'b00000011111000000000000000001000;
261 | //DIGITAL_TUBE_DISPLAY:
262 | // sw $s5, 20($s0)
263 | 121: data <= 32'b10101110000101010000000000010100;
264 | // lw $t3, 8($s0)
265 | 122: data <= 32'b10001110000010110000000000001000;
266 | // addi $t4, $zero, 2
267 | 123: data <= 32'b00100000000011000000000000000010;
268 | // or $t3, $t3, $t4
269 | 124: data <= 32'b00000001011011000101100000100101;
270 | // sw $t3, 8($s0)
271 | 125: data <= 32'b10101110000010110000000000001000;
272 | // addi $26, $26, -4
273 | 126: data <= 32'b00100011010110101111111111111100;
274 | // jr $26
275 | 127: data <= 32'b00000011010000000000000000001000;
276 | //EXCEPT:
277 | // nop
278 | 128: data <= 32'b00000000000000000000000000000000;
279 |
--------------------------------------------------------------------------------
/src/Assembler/MIPS_complier.py:
--------------------------------------------------------------------------------
1 | import re
2 |
3 | TAG = {}
4 | TAG_C = {}
5 | PROGRAM = []
6 | COMMAND = ['add', 'addi', 'addiu', 'nop', 'lw', 'sw', 'lui', 'addu', 'sub', 'subu', 'and', 'or', 'xor', 'nor', 'andi', 'sll', 'srl', 'sra', 'slt', 'slti', 'ori', 'sltiu', 'beq', 'bne', 'blez', 'bgtz', 'bltz', 'j', 'jal', 'jr', 'jalr']
7 | OPCODE = {'add': '000000', 'addi': '001000', 'addiu': '001001', 'nop': '000000', 'lw': '100011', 'sw': '101011', 'lui': '001111', 'addu': '000000', 'sub': '000000', 'subu': '000000', 'and': '000000', 'or': '000000', 'xor': '000000', 'nor': '000000', 'andi': '001100', 'sll': '000000', 'srl': '000000', 'sra': '000000', 'slt': '000000', 'slti': '001010', 'ori': '001101', 'sltiu': '001011', 'beq': '000100', 'bne': '000101', 'blez': '000110', 'bgtz': '000111', 'bltz': '000001', 'j': '000010', 'jal': '000011', 'jr': '000000', 'jalr': '000000'}
8 | FUNCTION = {'add': '100000', 'nop': '000000', 'addu': '100001', 'sub': '100010', 'subu': '100011', 'and': '100100', 'or': '100101', 'xor': '100110', 'nor': '100111', 'sll': '000000', 'srl': '000010', 'sra': '000011', 'slt': '101010', 'jr': '001000', 'jalr': '001001'}
9 | REGISTER = {'zero': '00000', 'at': '00001', 'v0': '00010', 'v1': '00011', 'a0': '00100', 'a1': '00101', 'a2': '00110', 'a3': '00111', 't0': '01000', 't1': '01001', 't2': '01010', 't3': '01011', 't4': '01100', 't5': '01101', 't6': '01110', 't7': '01111', 's0': '10000', 's1': '10001', 's2': '10010', 's3': '10011', 's4': '10100', 's5': '10101', 's6': '10110', 's7': '10111', 't8': '11000', 't9': '11001', 'k0': '11010', 'k1': '11011', 'gp': '11100', 'sp': '11101', 'fp': '11110', 'ra': '11111', '0': '00000', '1': '00001', '2': '00010', '3': '000011', '4': '00100', '5': '00101', '6': '00110', '7': '00111', '8': '01000', '9': '01001', '10': '01010', '11': '01011', '12': '01100', '13': '01101', '14': '01110', '15': '01111', '16': '10000', '17': '10001', '18': '10010', '19': '10011', '20': '10100', '21': '10101', '22': '10110', '23': '10111', '24': '11000', '25': '11001', '26': '11010', '27': '11011', '28': '11100', '29': '11101', '30': '11110', '31': '11111'}
10 | TYPE = {'add': 'r', 'addi': 'i', 'addiu': 'i', 'nop': 'nop', 'lw': 'lw', 'sw': 'sw', 'lui': 'lui', 'addu': 'r', 'sub': 'r', 'subu': 'r', 'and': 'r', 'or': 'r', 'xor': 'r', 'nor': 'r', 'andi': 'i', 'ori': 'i', 'sll': 'shamt', 'srl': 'shamt', 'sra': 'shamt', 'slt': 'r', 'slti': 'i', 'sltiu': 'i', 'beq': 'br', 'bne': 'br', 'blez': 'bz', 'bgtz': 'bz', 'bltz': 'bz', 'j': 'j', 'jal': 'j', 'jr': 'jr', 'jalr': 'jalr'}
11 |
12 |
13 | #convert numbers into binary
14 | def ToBin(num, length):
15 | sign = 1
16 | base = [0, 1]
17 | num = int(num)
18 | mid = []
19 | if num < 0:
20 | sign = 0
21 | num += 65536
22 | while True:
23 | if num == 0: break
24 | num, rem = divmod(num, 2)
25 | mid.append(base[rem])
26 | while len(mid) < length:
27 | mid.append(0)
28 | if sign == 0: mid[length - 1] = 1
29 | return ''.join([str(x) for x in mid[::-1]])
30 |
31 |
32 | #read mips program file
33 | def ReadFile():
34 | commandCount = 0
35 | f = open('MIPS_program.asm', 'r')
36 | str = f.readline()
37 | while str != '':
38 | if str.find('#') != -1: str = str[0:str.find('#')]
39 | str = str.replace('(', ' ')
40 | str = str.replace(')', ' ')
41 | str = str.replace(',', ' ')
42 | str = str.replace('$', '')
43 | Instruction = str.split()
44 | if len(Instruction) > 0:
45 | if Instruction[0] in COMMAND:
46 | PROGRAM.append(Instruction)
47 | commandCount += 1
48 | elif Instruction[0].find(':') != -1:
49 | TAG[Instruction[0]] = commandCount
50 | TAG_C[commandCount] = Instruction[0]
51 | str = f.readline()
52 | f.close()
53 |
54 |
55 | ReadFile()
56 | count = 0
57 | f = open('BinaryCode.txt', 'w')
58 | for Instruction in PROGRAM:
59 | if count in TAG_C:
60 | f.write('\t\t' + '//' + TAG_C[count] + '\n')
61 | count = count + 1
62 | Command = Instruction[0]
63 |
64 | #normal R-type instruction
65 | if (TYPE[Command] == 'r'):
66 | Rd = Instruction[1]
67 | Rs = Instruction[2]
68 | Rt = Instruction[3]
69 | Shamt = '00000'
70 | BinCode = OPCODE[Command] + REGISTER[Rs] + REGISTER[Rt] + REGISTER[Rd] + Shamt + FUNCTION[Command]
71 | f.write('\t\t' + '// ' + Command + ' $' + Rd + ', $' + Rs + ', $' + Rt + '\n')
72 | f.write('\t\t' + str(count - 1) + ': data <= 32\'b' + BinCode + ';\n')
73 |
74 | #normal I-type instruction
75 | if (TYPE[Command] == 'i'):
76 | Rt = Instruction[1]
77 | Rs = Instruction[2]
78 | Imm = Instruction[3]
79 | if (Imm.find('0x') == -1):
80 | BinCode = OPCODE[Command] + REGISTER[Rs] + REGISTER[Rt] + ToBin(Imm, 16)
81 | else:
82 | BinCode = OPCODE[Command] + REGISTER[Rs] + REGISTER[Rt] + ToBin(int(Imm, 16), 16)
83 | f.write('\t\t' + '// ' + Command + ' $' + Rt + ', $' + Rs + ', ' + Imm + '\n')
84 | f.write('\t\t' + str(count - 1) + ': data <= 32\'b' + BinCode + ';\n')
85 |
86 | #nop type instruction
87 | if (TYPE[Command] == 'nop'):
88 | BinCode = '00000000000000000000000000000000'
89 | f.write('\t\t' + '// nop\n')
90 | f.write('\t\t' + str(count - 1) + ': data <= 32\'b' + BinCode + ';\n')
91 |
92 | #lw or sw type instruction
93 | if (TYPE[Command] == 'lw' or TYPE[Command] == 'sw'):
94 | Rs = Instruction[3]
95 | Rt = Instruction[1]
96 | Imm = Instruction[2]
97 | #if the immediate is a hex number
98 | if (Imm.find('0x') == -1):
99 | BinCode = OPCODE[Command] + REGISTER[Rs] + REGISTER[Rt] + ToBin(Imm, 16)
100 | #if the immediate is a oct number
101 | else:
102 | BinCode = OPCODE[Command] + REGISTER[Rs] + REGISTER[Rt] + ToBin(int(Imm, 16), 16)
103 | f.write('\t\t' + '// ' + Command + ' $' + Rt + ', ' + Imm + '(' + '$' + Rs + ')' + '\n')
104 | f.write('\t\t' + str(count - 1) + ': data <= 32\'b' + BinCode + ';\n')
105 |
106 | #lui type instruction
107 | if (TYPE[Command] == 'lui'):
108 | Rt = Instruction[1]
109 | Imm = Instruction[2]
110 | #if the immediate is a hex number
111 | if (Imm.find('0x') == -1):
112 | BinCode = OPCODE[Command] + '00000' + REGISTER[Rt] + ToBin(Imm, 16)
113 | #if the immediate is a oct number
114 | else:
115 | BinCode = OPCODE[Command] + '00000' + REGISTER[Rt] + ToBin(int(Imm, 16), 16)
116 | f.write('\t\t' + '// ' + Command + ' $' + Rt + ', ' + Imm + '\n')
117 | f.write('\t\t' + str(count - 1) + ': data <= 32\'b' + BinCode + ';\n')
118 |
119 | #shamt type instruction
120 | if (TYPE[Command] == 'shamt'):
121 | Rt = Instruction[2]
122 | Rd = Instruction[1]
123 | Shamt = Instruction[3]
124 | BinCode = OPCODE[Command] + '00000' + REGISTER[Rt] + REGISTER[Rd] + ToBin(Shamt, 5) + FUNCTION[Command]
125 | f.write('\t\t' + '// ' + Command + ' $' + Rd + ', $' + Rt + ', ' + Shamt + '\n')
126 | f.write('\t\t' + str(count - 1) + ': data <= 32\'b' + BinCode + ';\n')
127 |
128 | #br type instruction
129 | if (TYPE[Command] == 'br'):
130 | Rs = Instruction[1]
131 | Rt = Instruction[2]
132 | Label = Instruction[3]
133 | Imm = TAG[(Label + ':')] - count
134 | BinCode = OPCODE[Command] + REGISTER[Rs] + REGISTER[Rt] + ToBin(Imm, 16)
135 | f.write('\t\t' + '// ' + Command + ' $' + Rs + ', $' + Rt + ', ' + Label + '\n')
136 | f.write('\t\t' + str(count - 1) + ': data <= 32\'b' + BinCode + ';\n')
137 |
138 | #j type instruction
139 | if (TYPE[Command] == 'j'):
140 | Target = Instruction[1]
141 | Imm = TAG[(Target + ':')]
142 | BinCode = OPCODE[Command] + ToBin(Imm, 26)
143 | f.write('\t\t' + '// ' + Command + ' ' + Target + '\n')
144 | f.write('\t\t' + str(count - 1) + ': data <= 32\'b' + BinCode + ';\n')
145 |
146 | #jr type instruction
147 | if (TYPE[Command] == 'jr'):
148 | Rs = Instruction[1]
149 | BinCode = OPCODE[Command] + REGISTER[Rs] + '000000000000000' + FUNCTION[Command]
150 | f.write('\t\t' + '// ' + Command + ' $' + Rs + '\n')
151 | f.write('\t\t' + str(count - 1) + ': data <= 32\'b' + BinCode + ';\n')
152 |
153 | #jalr type instruction
154 | if (TYPE[Command] == 'jalr'):
155 | Rs = Instruction[2]
156 | Rd = Instruction[1]
157 | BinCode = OPCODE[Command] + REGISTER[Rs] + '00000' + REGISTER[Rd] + '00000' + FUNCTION[Command]
158 | f.write('\t\t' + '// ' + Command + ' $' + Rs + ', $' + Rd + '\n')
159 | f.write('\t\t' + str(count - 1) + ': data <= 32\'b' + BinCode + ';\n')
160 |
161 | #bz type instruction
162 | if (TYPE[Command] == 'bz'):
163 | Rs = Instruction[1]
164 | Label = Instruction[2]
165 | Imm = TAG[(Label + ':')] - count
166 | BinCode = OPCODE[Command] + REGISTER[Rs] + '00000' + ToBin(Imm, 16)
167 | f.write('\t\t' + '// ' + Command + ' $' + Rs + ', ' + Label + '\n')
168 | f.write('\t\t' + str(count - 1) + ': data <= 32\'b' + BinCode + ';\n')
169 | f.close()
170 |
--------------------------------------------------------------------------------
/src/Assembler/MIPS_program.asm:
--------------------------------------------------------------------------------
1 | j INIT
2 | j INTER
3 | j EXCEPT
4 |
5 | #########################INIT#########################
6 | INIT:
7 | addi $t0, $zero, 0x0014
8 | jr $t0 #clear PC to enable interrupt
9 | ######################################################
10 |
11 | ########################Timer#########################
12 | lui $s0, 0x4000 #s0 base address of peripheral
13 | sw, $zero, 8($s0) #initialize the timer
14 | addi $s1, $zero, -25000
15 | sw $s1, 0($s0) #initialize the timer
16 | addi $s1, $zero, -1
17 | sw $s1, 4($s0) #initialize the timer
18 | addi $s1, $zero, 3
19 | sw $s1, 8($s0) #turned on the timer
20 | ######################################################
21 |
22 | #####################UART RECEIVE#####################
23 | sw $t0, 32($s0) #initialize uart
24 | UART_START:
25 | addi $s1, $zero, -1
26 |
27 | UART_LOOP:
28 | lw $t0, 32($s0)
29 | andi $t0, $t0, 0x08
30 | beq $t0, $zero, UART_LOOP
31 | lw $v1, 28($s0) #read UART data
32 | beq $v1, $zero, UART_LOOP
33 | beq $s1, $zero LOAD_2
34 | addi $s4, $v1, 0 #get the first number
35 | addi $s1, $s1, 1
36 | j UART_LOOP
37 |
38 | LOAD_2:
39 | addi $s3, $v1, 0 #get the second number
40 | addi $v0, $s4, 0
41 | ######################################################
42 |
43 | #########################GCD##########################
44 | GCD:
45 | beq $v0, $zero, ANS1
46 | beq $v1, $zero, ANS2
47 | sub $t3, $v0, $v1
48 | bgtz $t3 LOOP1
49 | bltz $t3 LOOP2
50 |
51 | LOOP1:
52 | sub $v0, $v0, $v1
53 | j GCD
54 |
55 | LOOP2:
56 | sub $v1, $v1, $v0
57 | j GCD
58 |
59 | ANS1:
60 | add $a0, $v1, $zero
61 | j RESULT_DISPLAY
62 |
63 | ANS2:
64 | add $a0, $v0, $zero
65 |
66 | RESULT_DISPLAY:
67 | sw $a0, 12($s0) #LED display of result
68 | ######################################################
69 |
70 | ######################UART SEND BACK##################
71 | UART_SEND_BACK:
72 | lw $t0, 32($s0)
73 | andi $t0, $t0, 0x10
74 | bne $t0, $zero, UART_SEND_BACK
75 | sw $a0, 24($s0)
76 | j UART_START
77 | ########################################################
78 |
79 | #######################INTERRUPTON######################
80 | INTER:
81 | lw $t7, 8($s0)
82 | andi $t7, $t7, 0xfff9
83 | sw $t7, 8($s0) #clear interrupt status and disable interrupt
84 | addi $t3, $zero 1
85 | addi $t4, $zero 2
86 | addi $t5, $zero 4
87 | addi $t6, $zero 8
88 | lw $t7, 20($s0)
89 | andi $t7, $t7, 0xf00
90 | srl $t7, $t7, 8 #read the current status of digital_tube
91 | beq $t7, $t3, DIGITAL_TUBE_1
92 | beq $t7, $t4, DIGITAL_TUBE_2
93 | beq $t7, $t5, DIGITAL_TUBE_3
94 |
95 | DIGITAL_TUBE_0: #prepare data for digital tube 0
96 | andi $s5, $s3, 0x0f
97 | jal DECODE
98 | addi $s5, $s2, 0x100
99 | j DIGITAL_TUBE_DISPLAY
100 |
101 | DIGITAL_TUBE_1: #prepare data for digital tube 1
102 | andi $s5, $s3, 0xf0
103 | srl $s5, $s5, 4
104 | jal DECODE
105 | addi $s5, $s2, 0x200
106 | j DIGITAL_TUBE_DISPLAY
107 |
108 | DIGITAL_TUBE_2: #prepare data for digital tube 2
109 | andi $s5, $s4, 0x0f
110 | jal DECODE
111 | addi $s5, $s2, 0x400
112 | j DIGITAL_TUBE_DISPLAY
113 |
114 | DIGITAL_TUBE_3: #prepare data for digital tube 3
115 | andi $s5, $s4, 0xf0
116 | srl $s5, $s5, 4
117 | jal DECODE
118 | addi $s5, $s2, 0x800
119 | j DIGITAL_TUBE_DISPLAY
120 |
121 | DECODE: #decode of '0'
122 | addi $s2, $zero, 0xc0
123 | beq $zero, $s5, DECODE_COMPLETE
124 | addi $s2, $zero, 0xf9 #decode of '1'
125 | addi $s6, $zero, 1
126 | beq $s6, $s5, DECODE_COMPLETE
127 | addi $s2, $zero, 0xa4 #decode of '2'
128 | addi $s6, $zero, 2
129 | beq $s6, $s5, DECODE_COMPLETE
130 | addi $s2, $zero, 0xb0 #decode of '3'
131 | addi $s6, $zero, 3
132 | beq $s6, $s5, DECODE_COMPLETE
133 | addi $s2, $zero, 0x99 #decode of '4'
134 | addi $s6, $zero, 4
135 | beq $s6, $s5, DECODE_COMPLETE
136 | addi $s2, $zero, 0x92 #decode of '5'
137 | addi $s6, $zero, 5
138 | beq $s6, $s5, DECODE_COMPLETE
139 | addi $s2, $zero, 0x82 #decode of '6'
140 | addi $s6, $zero, 6
141 | beq $s6, $s5, DECODE_COMPLETE
142 | addi $s2, $zero, 0xf8 #decode of '7'
143 | addi $s6, $zero, 7
144 | beq $s6, $s5, DECODE_COMPLETE
145 | addi $s2, $zero, 0x80 #decode of '8'
146 | addi $s6, $zero, 8
147 | beq $s6, $s5, DECODE_COMPLETE
148 | addi $s2, $zero, 0x90 #decode of '9'
149 | addi $s6, $zero, 9
150 | beq $s6, $s5, DECODE_COMPLETE
151 | addi $s2, $zero, 0x88 #decode of 'A'
152 | addi $s6, $zero, 0x0a
153 | beq $s6, $s5, DECODE_COMPLETE
154 | addi $s2, $zero, 0x83 #decode of 'B'
155 | addi $s6, $zero, 0x0b
156 | beq $s6, $s5, DECODE_COMPLETE
157 | addi $s2, $zero, 0xc6 #decode of 'C'
158 | addi $s6, $zero, 0x0c
159 | beq $s6, $s5, DECODE_COMPLETE
160 | addi $s2, $zero, 0xa1 #decode of 'D'
161 | addi $s6, $zero, 0x0d
162 | beq $s6, $s5, DECODE_COMPLETE
163 | addi $s2, $zero, 0x86 #decode of 'E'
164 | addi $s6, $zero, 0x0e
165 | beq $s6, $s5, DECODE_COMPLETE
166 | addi $s2, $zero, 0x8e #decode of 'F'
167 |
168 |
169 | DECODE_COMPLETE:
170 | jr $ra
171 |
172 |
173 | DIGITAL_TUBE_DISPLAY:
174 | sw $s5, 20($s0)
175 | lw $t3, 8($s0)
176 | addi $t4, $zero, 2
177 | or $t3, $t3, $t4
178 | sw $t3, 8($s0) # TCON |= 0x00000002
179 | addi $26, $26, -4
180 | jr $26
181 |
182 |
183 | ######################EXCEPTION#########################
184 | EXCEPT:
185 | nop
--------------------------------------------------------------------------------
/src/Pipeline_CPU/ALU.v:
--------------------------------------------------------------------------------
1 | module ALU(A, B, ALUFun, Sign, Z);
2 | input Sign;
3 | input [5:0] ALUFun;
4 | input [31:0] A, B;
5 | output [31:0] Z;
6 | wire zero,neg;
7 | wire [31:0] S0, S1, S2, S3;
8 |
9 | AddSub AddSub(.A(A), .B(B), .ALUFun(ALUFun), .Sign(Sign), .Z(zero), .N(neg), .S(S0));
10 | Cmp Cmp(.ALUFun(ALUFun), .Sign(Sign), .Z(zero), .N(neg), .S(S1));
11 | Logic Logic(.A(A), .B(B), .ALUFun(ALUFun), .S(S2));
12 | Shift Shift(.A(A), .B(B), .ALUFun(ALUFun), .S(S3));
13 |
14 | // Choose the type of calculation
15 | assign Z =
16 | (ALUFun[5:4] == 2'b00)? S0:
17 | (ALUFun[5:4] == 2'b10)? S3:
18 | (ALUFun[5:4] == 2'b01)? S2: S1;
19 |
20 | endmodule
21 |
22 |
23 |
24 | // add or sub calculation
25 | module AddSub(A, B, ALUFun, Sign, Z, N, S);
26 | input Sign;
27 | input [5:0] ALUFun;
28 | input [31:0] A, B;
29 | output Z, N;
30 | output [32:0] S;
31 |
32 | // Choose which number to compare when determining Z
33 | assign Z =
34 | (ALUFun[3] && |A)? 0:
35 | (~ALUFun[3] && |S)? 0: 1;
36 |
37 | // Choose to perform add or sub
38 | assign S =
39 | (ALUFun[0])? ({1'b0, A} - {1'b0, B}): ({1'b0, A} + {1'b0, B});
40 |
41 | // Determine N according to the Sign signal and carryin
42 | assign N =
43 | (ALUFun[3] && Sign && A[31])? 1:
44 | (~ALUFun[3] && Sign && S[31])? 1:
45 | (~ALUFun[3] && ~Sign && S[32])? 1: 0;
46 |
47 | endmodule
48 |
49 |
50 |
51 | // comparation calculation
52 | module Cmp(ALUFun, Sign, Z, N, S);
53 | input Sign, Z, N;
54 | input [5:0] ALUFun;
55 | output [31:0] S;
56 |
57 | // Determine output according to N and Z
58 | assign S[0] =
59 | (ALUFun[3:1] == 3'b001)? Z:
60 | (ALUFun[3:1] == 3'b000)? ~Z:
61 | (ALUFun[3:1] == 3'b010)? N:
62 | (ALUFun[3:1] == 3'b110)? (N || Z):
63 | (ALUFun[3:1] == 3'b101)? N: (~N && ~Z);
64 | assign S[31:1]=0;
65 |
66 | endmodule
67 |
68 |
69 | // logical calculation
70 | module Logic(A, B, ALUFun, S);
71 | input [5:0] ALUFun;
72 | input [31:0] A, B;
73 | output [31:0] S;
74 |
75 | // result of logical calculation
76 | assign S =
77 | (ALUFun[3:0] == 4'b0001)? ~(A | B):
78 | (ALUFun[3:0] == 4'b1110)? (A | B):
79 | (ALUFun[3:0] == 4'b1000)? (A & B):
80 | (ALUFun[3:0] == 4'b0110)? (A ^ B): A;
81 |
82 | endmodule
83 |
84 |
85 |
86 | // shift calculation
87 | module Shift(A, B, ALUFun, S);
88 | input [5:0] ALUFun;
89 | input [31:0] A, B;
90 | output [31:0] S;
91 |
92 | assign S =
93 |
94 | // srl or sra with the msb being '0'
95 | (ALUFun[1:0] == 2'b01 || (ALUFun[1:0] == 2'b11 && B[31] == 0))? B >> A[4:0]:
96 |
97 | // sra with the msb being '1'
98 | (ALUFun[1:0] == 2'b11 && B[31] == 1)? ({32'hFFFFFFFF, B} >> A[4:0]):
99 |
100 | // sll
101 | (ALUFun[1:0] == 2'b00)? B << A[4:0]: 0;
102 |
103 | endmodule
--------------------------------------------------------------------------------
/src/Pipeline_CPU/Control.v:
--------------------------------------------------------------------------------
1 | module Control(Instruct, IRQ, PC31, PCSrc, RegWr, RegDst, MemRd, MemWr, MemToReg, ALUSrc1, ALUSrc2, EXTOp, LUOp, ALUFun, Sign);
2 | input [31:0] Instruct;
3 | input IRQ, PC31;
4 | output reg [2:0] PCSrc;
5 | output reg RegWr;
6 | output reg [1:0] RegDst;
7 | output reg MemRd;
8 | output reg MemWr;
9 | output reg [1:0] MemToReg;
10 | output reg ALUSrc1;
11 | output reg ALUSrc2;
12 | output reg EXTOp;
13 | output reg LUOp;
14 | output reg [5:0] ALUFun;
15 | output reg Sign;
16 |
17 | always @(*) begin
18 |
19 | /* Default Set
20 | PCSrc = 3'd0;
21 | RegWr = 0;
22 | RegDst = 2'd0;
23 | MemRd = 0;
24 | MemWr = 0;
25 | MemToReg = 2'd0;
26 | ALUSrc1 = 0;
27 | ALUSrc2 = 0;
28 | ALUFun = 6'b000000;
29 | Sign = 1;
30 | EXTOp = 1;
31 | LUOp = 0;
32 | */
33 |
34 | if(~IRQ) begin
35 | case(Instruct[31:26])
36 | 6'b10_0011: begin //lw 0x23
37 | PCSrc = 3'd0;
38 | RegWr = 1;
39 | RegDst = 2'd1;
40 | MemRd = 1;
41 | MemWr = 0;
42 | MemToReg = 2'd1;
43 | ALUSrc1 = 0;
44 | ALUSrc2 = 1;
45 | ALUFun = 6'b000000;
46 | Sign = 1;
47 | EXTOp = 1;
48 | LUOp = 0;
49 | end
50 | 6'b10_1011: begin //sw 0x2b
51 | PCSrc = 3'd0;
52 | RegWr = 0;
53 | RegDst = 2'd0;
54 | MemRd = 0;
55 | MemWr = 1;
56 | MemToReg = 2'd0;
57 | ALUSrc1 = 0;
58 | ALUSrc2 = 1;
59 | ALUFun = 6'b000000;
60 | Sign = 1;
61 | EXTOp = 1;
62 | LUOp = 0;
63 | end
64 | 6'b00_1111: begin //lui 0x0f
65 | PCSrc = 3'd0;
66 | RegWr = 1;
67 | RegDst = 2'd1;
68 | MemRd = 0;
69 | MemWr = 1;
70 | MemToReg = 2'd0;
71 | ALUSrc1 = 0;
72 | ALUSrc2 = 1;
73 | ALUFun = 6'b011110;
74 | Sign = 1;
75 | EXTOp = 1;
76 | LUOp = 1;
77 | end
78 | 6'b00_1000: begin //addi 0x08
79 | PCSrc = 3'd0;
80 | RegWr = 1;
81 | RegDst = 2'd1;
82 | MemRd = 0;
83 | MemWr = 0;
84 | MemToReg = 2'd0;
85 | ALUSrc1 = 0;
86 | ALUSrc2 = 1;
87 | ALUFun = 6'b000000;
88 | Sign = 1;
89 | EXTOp = 1;
90 | LUOp = 0;
91 | end
92 | 6'b00_1001: begin //addiu 0x09
93 | PCSrc = 3'd0;
94 | RegWr = 1;
95 | RegDst = 2'd1;
96 | MemRd = 0;
97 | MemWr = 0;
98 | MemToReg = 2'd0;
99 | ALUSrc1 = 0;
100 | ALUSrc2 = 1;
101 | ALUFun = 6'b000000;
102 | Sign = 1;
103 | EXTOp = 1;
104 | LUOp = 0;
105 | end
106 | 6'b00_1100: begin //andi 0x0c
107 | PCSrc = 3'd0;
108 | RegWr = 1;
109 | RegDst = 2'd1;
110 | MemRd = 0;
111 | MemWr = 0;
112 | MemToReg = 2'd0;
113 | ALUSrc1 = 0;
114 | ALUSrc2 = 1;
115 | ALUFun = 6'b011000;
116 | Sign = 1;
117 | EXTOp = 0;
118 | LUOp = 0;
119 | end
120 | /*
121 | 6'b00_1101: begin //ori 0x0d
122 | PCSrc = 3'd0;
123 | RegWr = 1;
124 | RegDst = 2'd1;
125 | MemRd = 0;
126 | MemWr = 0;
127 | MemToReg = 2'd0;
128 | ALUSrc1 = 0;
129 | ALUSrc2 = 1;
130 | ALUFun = 6'b011110;
131 | Sign = 1;
132 | EXTOp = 0;
133 | LUOp = 0;
134 | end
135 | */
136 | 6'b00_1010: begin //slti 0x0a
137 | PCSrc = 3'd0;
138 | RegWr = 1;
139 | RegDst = 2'd1;
140 | MemRd = 0;
141 | MemWr = 0;
142 | MemToReg = 2'd0;
143 | ALUSrc1 = 0;
144 | ALUSrc2 = 1;
145 | ALUFun = 6'b110101;
146 | Sign = 1;
147 | EXTOp = 1;
148 | LUOp = 0;
149 | end
150 | 6'b00_1011: begin //sltiu 0x0b
151 | PCSrc = 3'd0;
152 | RegWr = 1;
153 | RegDst = 2'd1;
154 | MemRd = 0;
155 | MemWr = 0;
156 | MemToReg = 2'd0;
157 | ALUSrc1 = 0;
158 | ALUSrc2 = 1;
159 | ALUFun = 6'b110101;
160 | Sign = 0;
161 | EXTOp = 1;
162 | LUOp = 0;
163 | end
164 | 6'b00_0100: begin //beq 0x04
165 | PCSrc = 3'd1;
166 | RegWr = 0;
167 | RegDst = 2'd0;
168 | MemRd = 0;
169 | MemWr = 0;
170 | MemToReg = 2'd0;
171 | ALUSrc1 = 0;
172 | ALUSrc2 = 0;
173 | ALUFun = 6'b110011;
174 | Sign = 1;
175 | EXTOp = 1;
176 | LUOp = 0;
177 | end
178 | 6'b00_0101: begin //bne 0x05
179 | PCSrc = 3'd1;
180 | RegWr = 0;
181 | RegDst = 2'd0;
182 | MemRd = 0;
183 | MemWr = 0;
184 | MemToReg = 2'd0;
185 | ALUSrc1 = 0;
186 | ALUSrc2 = 0;
187 | ALUFun = 6'b110001;
188 | Sign = 1;
189 | EXTOp = 1;
190 | LUOp = 0;
191 | end
192 | 6'b00_0110: begin //blez 0x06
193 | PCSrc = 3'd1;
194 | RegWr = 0;
195 | RegDst = 2'd0;
196 | MemRd = 0;
197 | MemWr = 0;
198 | MemToReg = 2'd0;
199 | ALUSrc1 = 0;
200 | ALUSrc2 = 0;
201 | ALUFun = 6'b111101;
202 | Sign = 1;
203 | EXTOp = 1;
204 | LUOp = 0;
205 | end
206 | 6'b00_0111: begin //bgtz 0x07
207 | PCSrc = 3'd1;
208 | RegWr = 0;
209 | RegDst = 2'd0;
210 | MemRd = 0;
211 | MemWr = 0;
212 | MemToReg = 2'd0;
213 | ALUSrc1 = 0;
214 | ALUSrc2 = 0;
215 | ALUFun = 6'b111111;
216 | Sign = 1;
217 | EXTOp = 1;
218 | LUOp = 0;
219 | end
220 | 6'b00_0001: begin //bltz 0x01
221 | PCSrc = 3'd1;
222 | RegWr = 0;
223 | RegDst = 2'd0;
224 | MemRd = 0;
225 | MemWr = 0;
226 | MemToReg = 2'd0;
227 | ALUSrc1 = 0;
228 | ALUSrc2 = 0;
229 | ALUFun = 6'b111011;
230 | Sign = 1;
231 | EXTOp = 1;
232 | LUOp = 0;
233 | end
234 | 6'b00_0010: begin //j 0x02
235 | PCSrc = 3'd2;
236 | RegWr = 0;
237 | RegDst = 2'd0;
238 | MemRd = 0;
239 | MemWr = 0;
240 | MemToReg = 2'd0;
241 | ALUSrc1 = 0;
242 | ALUSrc2 = 0;
243 | ALUFun = 6'b000000;
244 | Sign = 1;
245 | EXTOp = 1;
246 | LUOp = 0;
247 | end
248 | 6'b00_0011: begin //jal 0x03
249 | PCSrc = 3'd2;
250 | RegWr = 1;
251 | RegDst = 2'd2;
252 | MemRd = 0;
253 | MemWr = 0;
254 | MemToReg = 2'd2;
255 | ALUSrc1 = 0;
256 | ALUSrc2 = 0;
257 | ALUFun = 6'b000000;
258 | Sign = 1;
259 | EXTOp = 1;
260 | LUOp = 0;
261 | end
262 | 6'b00_0000: begin //R型 0x00
263 | case(Instruct[5:0])
264 | 6'b10_0000: begin //add 0x20
265 | PCSrc = 3'd0;
266 | RegWr = 1;
267 | RegDst = 2'd0;
268 | MemRd = 0;
269 | MemWr = 0;
270 | MemToReg = 2'd0;
271 | ALUSrc1 = 0;
272 | ALUSrc2 = 0;
273 | ALUFun = 6'b000000;
274 | Sign = 1;
275 | EXTOp = 1;
276 | LUOp = 0;
277 | end
278 | 6'b10_0001: begin //addu 0x21
279 | PCSrc = 3'd0;
280 | RegWr = 1;
281 | RegDst = 2'd0;
282 | MemRd = 0;
283 | MemWr = 0;
284 | MemToReg = 2'd0;
285 | ALUSrc1 = 0;
286 | ALUSrc2 = 0;
287 | ALUFun = 6'b000000;
288 | Sign = 1;
289 | EXTOp = 1;
290 | LUOp = 0;
291 | end
292 | 6'b10_0010: begin //sub 0x22
293 | PCSrc = 3'd0;
294 | RegWr = 1;
295 | RegDst = 2'd0;
296 | MemRd = 0;
297 | MemWr = 0;
298 | MemToReg = 2'd0;
299 | ALUSrc1 = 0;
300 | ALUSrc2 = 0;
301 | ALUFun = 6'b000001;
302 | Sign = 1;
303 | EXTOp = 1;
304 | LUOp = 0;
305 | end
306 | 6'b10_0011: begin //subu 0x23
307 | PCSrc = 3'd0;
308 | RegWr = 1;
309 | RegDst = 2'd0;
310 | MemRd = 0;
311 | MemWr = 0;
312 | MemToReg = 2'd0;
313 | ALUSrc1 = 0;
314 | ALUSrc2 = 0;
315 | ALUFun = 6'b000001;
316 | Sign = 1;
317 | EXTOp = 1;
318 | LUOp = 0;
319 | end
320 | 6'b10_0100: begin //and 0x24
321 | PCSrc = 3'd0;
322 | RegWr = 1;
323 | RegDst = 2'd0;
324 | MemRd = 0;
325 | MemWr = 0;
326 | MemToReg = 2'd0;
327 | ALUSrc1 = 0;
328 | ALUSrc2 = 0;
329 | ALUFun = 6'b011000;
330 | Sign = 1;
331 | EXTOp = 1;
332 | LUOp = 0;
333 | end
334 | 6'b10_0101: begin //or 0x25
335 | PCSrc = 3'd0;
336 | RegWr = 1;
337 | RegDst = 2'd0;
338 | MemRd = 0;
339 | MemWr = 0;
340 | MemToReg = 2'd0;
341 | ALUSrc1 = 0;
342 | ALUSrc2 = 0;
343 | ALUFun = 6'b011110;
344 | Sign = 1;
345 | EXTOp = 1;
346 | LUOp = 0;
347 | end
348 | 6'b10_0110: begin //xor 0x26
349 | PCSrc = 3'd0;
350 | RegWr = 1;
351 | RegDst = 2'd0;
352 | MemRd = 0;
353 | MemWr = 0;
354 | MemToReg = 2'd0;
355 | ALUSrc1 = 0;
356 | ALUSrc2 = 0;
357 | ALUFun = 6'b010110;
358 | Sign = 1;
359 | EXTOp = 1;
360 | LUOp = 0;
361 | end
362 | 6'b10_0111: begin //nor 0x27
363 | PCSrc = 3'd0;
364 | RegWr = 1;
365 | RegDst = 2'd0;
366 | MemRd = 0;
367 | MemWr = 0;
368 | MemToReg = 2'd0;
369 | ALUSrc1 = 0;
370 | ALUSrc2 = 0;
371 | ALUFun = 6'b010001;
372 | Sign = 1;
373 | EXTOp = 1;
374 | LUOp = 0;
375 | end
376 | 6'b00_0000: begin //sll 0x00
377 | PCSrc = 3'd0;
378 | RegWr = 1;
379 | RegDst = 2'd0;
380 | MemRd = 0;
381 | MemWr = 0;
382 | MemToReg = 2'd0;
383 | ALUSrc1 = 1;
384 | ALUSrc2 = 0;
385 | ALUFun = 6'b100000;
386 | Sign = 1;
387 | EXTOp = 1;
388 | LUOp = 0;
389 | end
390 | 6'b00_0010: begin //srl 0x02
391 | PCSrc = 3'd0;
392 | RegWr = 1;
393 | RegDst = 2'd0;
394 | MemRd = 0;
395 | MemWr = 0;
396 | MemToReg = 2'd0;
397 | ALUSrc1 = 1;
398 | ALUSrc2 = 0;
399 | ALUFun = 6'b100001;
400 | Sign = 1;
401 | EXTOp = 1;
402 | LUOp = 0;
403 | end
404 | 6'b00_0011: begin //sra 0x03
405 | PCSrc = 3'd0;
406 | RegWr = 1;
407 | RegDst = 2'd0;
408 | MemRd = 0;
409 | MemWr = 0;
410 | MemToReg = 2'd0;
411 | ALUSrc1 = 1;
412 | ALUSrc2 = 0;
413 | ALUFun = 6'b100011;
414 | Sign = 1;
415 | EXTOp = 1;
416 | LUOp = 0;
417 | end
418 | 6'b10_1010: begin //slt 0x2a
419 | PCSrc = 3'd0;
420 | RegWr = 1;
421 | RegDst = 2'd0;
422 | MemRd = 0;
423 | MemWr = 0;
424 | MemToReg = 2'd0;
425 | ALUSrc1 = 0;
426 | ALUSrc2 = 0;
427 | ALUFun = 6'b110101;
428 | Sign = 1;
429 | EXTOp = 1;
430 | LUOp = 0;
431 | end
432 | /*
433 | 6'b10_1011: begin //sltu 0x2b
434 | PCSrc = 3'd0;
435 | RegWr = 1;
436 | RegDst = 2'd0;
437 | MemRd = 0;
438 | MemWr = 0;
439 | MemToReg = 2'd0;
440 | ALUSrc1 = 0;
441 | ALUSrc2 = 0;
442 | ALUFun = 6'b110101;
443 | Sign = 0;
444 | EXTOp = 1;
445 | LUOp = 0;
446 | end
447 | */
448 | 6'b00_1000: begin //jr 0x08
449 | PCSrc = 3'd3;
450 | RegWr = 0;
451 | RegDst = 2'd0;
452 | MemRd = 0;
453 | MemWr = 0;
454 | MemToReg = 2'd0;
455 | ALUSrc1 = 0;
456 | ALUSrc2 = 0;
457 | ALUFun = 6'b000000;
458 | Sign = 1;
459 | EXTOp = 1;
460 | LUOp = 0;
461 | end
462 | 6'b00_1001: begin //jalr 0x09
463 | PCSrc = 3'd3;
464 | RegWr = 1;
465 | RegDst = 2'd0;
466 | MemRd = 0;
467 | MemWr = 0;
468 | MemToReg = 2'd2;
469 | ALUSrc1 = 0;
470 | ALUSrc2 = 0;
471 | ALUFun = 6'b000000;
472 | Sign = 1;
473 | EXTOp = 1;
474 | LUOp = 0;
475 | end
476 | default: begin //exception
477 | if(~PC31) begin
478 | PCSrc = 3'd5;
479 | RegWr = 1;
480 | RegDst = 2'd3;
481 | MemRd = 0;
482 | MemWr = 0;
483 | MemToReg = 2'd2;
484 | ALUSrc1 = 0;
485 | ALUSrc2 = 0;
486 | ALUFun = 6'b000000;
487 | Sign = 1;
488 | EXTOp = 1;
489 | LUOp = 0;
490 | end
491 | else begin
492 | PCSrc = 3'd0;
493 | RegWr = 0;
494 | RegDst = 2'd0;
495 | MemRd = 0;
496 | MemWr = 0;
497 | MemToReg = 2'd0;
498 | ALUSrc1 = 0;
499 | ALUSrc2 = 0;
500 | ALUFun = 6'b000000;
501 | Sign = 1;
502 | EXTOp = 1;
503 | LUOp = 0;
504 | end
505 | end
506 | endcase
507 | end
508 | default: begin //exception
509 | if(~PC31) begin
510 | PCSrc = 3'd5;
511 | RegWr = 1;
512 | RegDst = 2'd3;
513 | MemRd = 0;
514 | MemWr = 0;
515 | MemToReg = 2'd2;
516 | ALUSrc1 = 0;
517 | ALUSrc2 = 0;
518 | ALUFun = 6'b000000;
519 | Sign = 1;
520 | EXTOp = 1;
521 | LUOp = 0;
522 | end
523 | else begin
524 | PCSrc = 3'd0;
525 | RegWr = 0;
526 | RegDst = 2'd0;
527 | MemRd = 0;
528 | MemWr = 0;
529 | MemToReg = 2'd0;
530 | ALUSrc1 = 0;
531 | ALUSrc2 = 0;
532 | ALUFun = 6'b000000;
533 | Sign = 1;
534 | EXTOp = 1;
535 | LUOp = 0;
536 | end
537 | end
538 | endcase
539 | end
540 | else begin //Interruption
541 | PCSrc = 3'd4;
542 | RegWr = 1;
543 | RegDst = 2'd3;
544 | MemRd = 0;
545 | MemWr = 0;
546 | MemToReg = 2'd2;
547 | ALUSrc1 = 0;
548 | ALUSrc2 = 0;
549 | ALUFun = 6'b000000;
550 | Sign = 1;
551 | EXTOp = 1;
552 | LUOp = 0;
553 | end
554 | end
555 |
556 | endmodule
--------------------------------------------------------------------------------
/src/Pipeline_CPU/DataMem.v:
--------------------------------------------------------------------------------
1 | `timescale 1ns/1ps
2 |
3 | module DataMem (reset,clk,rd,wr,addr,wdata,rdata);
4 | input reset,clk;
5 | input rd,wr;
6 | input [31:0] addr; //Address Must be Word Aligned
7 | input [31:0] wdata;
8 | output [31:0] rdata;
9 |
10 | parameter RAM_SIZE = 256;
11 | reg [31:0] RAMDATA [RAM_SIZE-1:0];
12 |
13 | assign rdata = (rd && (addr[31:2] < RAM_SIZE)) ? RAMDATA[addr[31:2]] : 32'b0;
14 |
15 | always@(posedge clk) begin
16 | if(wr && (addr[31:2] < RAM_SIZE))
17 | RAMDATA[addr[31:2]] <= wdata;
18 | end
19 |
20 | endmodule
--------------------------------------------------------------------------------
/src/Pipeline_CPU/Digitube_scan.v:
--------------------------------------------------------------------------------
1 | `timescale 1ns/1ps
2 |
3 | //For Altera DE2: Trans non-scanning Digital tube to scanning Digital tube
4 |
5 | module Digitube_scan(digi_in,digi_out1,digi_out2,digi_out3,digi_out4);
6 | input [11:0] digi_in; //AN3,AN2,AN1,AN0,DP,CG,CF,CE,CD,CC,CB,CA
7 | output [6:0] digi_out1; //0: CG,CF,CE,CD,CC,CB,CA
8 | output [6:0] digi_out2; //1: CG,CF,CE,CD,CC,CB,CA
9 | output [6:0] digi_out3; //2: CG,CF,CE,CD,CC,CB,CA
10 | output [6:0] digi_out4; //3: CG,CF,CE,CD,CC,CB,CA
11 |
12 | assign digi_out1 = (digi_in[11:8] == 4'b0001) ? digi_in[6:0] : 7'b111_1111;
13 | assign digi_out2 = (digi_in[11:8] == 4'b0010) ? digi_in[6:0] : 7'b111_1111;
14 | assign digi_out3 = (digi_in[11:8] == 4'b0100) ? digi_in[6:0] : 7'b111_1111;
15 | assign digi_out4 = (digi_in[11:8] == 4'b1000) ? digi_in[6:0] : 7'b111_1111;
16 |
17 | endmodule
18 |
19 |
--------------------------------------------------------------------------------
/src/Pipeline_CPU/EX_MEM_Reg.v:
--------------------------------------------------------------------------------
1 | module EX_MEM_Reg(clk ,reset, PC_add_4_in, ALUOut_in, DataBusB_in, Rt_in, Rd_in, RegDst_in, MemRead_in,
2 | MemWrite_in, MemToReg_in, RegWrite_in, AddrC_in, PC_add_4_out, ALUOut_out, DataBusB_out, Rt_out, Rd_out, RegDst_out,
3 | MemRead_out, MemWrite_out, MemToReg_out, RegWrite_out, AddrC_out);
4 |
5 | input clk;
6 | input reset;
7 | input [31:0] PC_add_4_in;
8 | input [31:0] DataBusB_in;
9 | input [31:0] ALUOut_in;
10 |
11 | input [4:0] Rt_in;
12 | input [4:0] Rd_in;
13 | input [1:0] RegDst_in;
14 | input MemRead_in;
15 | input MemWrite_in;
16 | input [1:0] MemToReg_in;
17 | input RegWrite_in;
18 | input [4:0] AddrC_in;
19 |
20 | output reg [31:0] PC_add_4_out;
21 | output reg [31:0] DataBusB_out;
22 | output reg [31:0] ALUOut_out;
23 |
24 | output reg [4:0] Rt_out;
25 | output reg [4:0] Rd_out;
26 | output reg [1:0] RegDst_out;
27 | output reg MemRead_out;
28 | output reg MemWrite_out;
29 | output reg [1:0] MemToReg_out;
30 | output reg RegWrite_out;
31 | output reg [4:0] AddrC_out;
32 |
33 | always @(posedge clk or negedge reset) begin
34 | if (~reset) begin
35 | PC_add_4_out <= 32'h0000_0000;
36 | DataBusB_out <= 32'h0000_0000;
37 | ALUOut_out <= 32'h0000_0000;
38 | Rt_out <= 5'h00;
39 | Rd_out <= 5'h00;
40 | RegDst_out <= 2'h0;
41 | MemRead_out <= 1'b0;
42 | MemWrite_out <= 1'b0;
43 | MemToReg_out <= 2'h0;
44 | RegWrite_out <= 1'b0;
45 | AddrC_out <= 5'h0;
46 | end
47 | else begin
48 | PC_add_4_out <= PC_add_4_in;
49 | DataBusB_out <= DataBusB_in;
50 | ALUOut_out <= ALUOut_in;
51 | Rt_out <= Rt_in;
52 | Rd_out <= Rd_in;
53 | RegDst_out <= RegDst_in;
54 | MemRead_out <= MemRead_in;
55 | MemWrite_out <= MemWrite_in;
56 | MemToReg_out <= MemToReg_in;
57 | RegWrite_out <= RegWrite_in;
58 | AddrC_out <= AddrC_in;
59 | end
60 | end
61 | endmodule
--------------------------------------------------------------------------------
/src/Pipeline_CPU/Forward_Unit.v:
--------------------------------------------------------------------------------
1 | module Forward_Unit(IF_ID_Rs, ID_EX_Rs, ID_EX_Rt, ID_PCSrc, ID_EX_RegWrite, ID_EX_AddrC, EX_MEM_RegWrite, EX_MEM_AddrC,
2 | MEM_WB_RegWrite, MEM_WB_AddrC, ForwardA, ForwardB, ForwardJ);
3 |
4 | input [4:0] IF_ID_Rs;
5 | input [4:0] ID_EX_Rs;
6 | input [4:0] ID_EX_Rt;
7 | input [2:0] ID_PCSrc;
8 | input ID_EX_RegWrite;
9 | input [4:0] ID_EX_AddrC;
10 | input EX_MEM_RegWrite;
11 | input [4:0] EX_MEM_AddrC;
12 | input MEM_WB_RegWrite;
13 | input [4:0] MEM_WB_AddrC;
14 |
15 | output reg [1:0] ForwardA;
16 | output reg [1:0] ForwardB;
17 | output reg [1:0] ForwardJ;
18 |
19 | always @(*) begin
20 | // Strategy here same as the textbook
21 | if(EX_MEM_RegWrite && EX_MEM_AddrC != 5'h00
22 | && EX_MEM_AddrC == ID_EX_Rs) begin
23 | ForwardA = 2'b10;
24 | end
25 | else if(MEM_WB_RegWrite && MEM_WB_AddrC != 5'h00
26 | && MEM_WB_AddrC == ID_EX_Rs) begin
27 | ForwardA = 2'b01;
28 | end
29 | else
30 | ForwardA = 2'b00;
31 |
32 | // Only replace Rt with Rs for ForwardA
33 | if(EX_MEM_RegWrite && EX_MEM_AddrC != 5'h00
34 | && EX_MEM_AddrC == ID_EX_Rt) begin
35 | ForwardB = 2'b10;
36 | end
37 | else if(MEM_WB_RegWrite && MEM_WB_AddrC != 5'h00
38 | && MEM_WB_AddrC == ID_EX_Rt) begin
39 | ForwardB = 2'b01;
40 | end
41 | else
42 | ForwardB = 2'b00;
43 |
44 | // Forward strategy for JR
45 | if(ID_PCSrc == 3'b011 && ID_EX_RegWrite && ID_EX_AddrC != 5'h00
46 | && ID_EX_AddrC == IF_ID_Rs) begin
47 | ForwardJ = 2'b01;
48 | end
49 | else if(ID_PCSrc == 3'b011 && EX_MEM_RegWrite && EX_MEM_AddrC != 5'h00
50 | && EX_MEM_AddrC == IF_ID_Rs) begin
51 | ForwardJ = 2'b10;
52 | end
53 | else if(ID_PCSrc == 3'b011 && MEM_WB_RegWrite && MEM_WB_AddrC != 5'h00
54 | && MEM_WB_AddrC == IF_ID_Rs) begin
55 | ForwardJ = 2'b11;
56 | end
57 | else
58 | ForwardJ = 2'b00;
59 |
60 | end
61 |
62 | endmodule
--------------------------------------------------------------------------------
/src/Pipeline_CPU/Hazard_Unit.v:
--------------------------------------------------------------------------------
1 | module Hazard_Unit(IF_ID_Rs, IF_ID_Rt, ID_PCSrc, EX_PCSrc, ID_EX_MemRead, ID_EX_Rt, EX_ALUOut_0, PCWrite, IF_ID_write, IF_ID_flush, ID_EX_flush);
2 |
3 | input [4:0] IF_ID_Rs;
4 | input [4:0] IF_ID_Rt;
5 | input [2:0] ID_PCSrc;
6 | input [2:0] EX_PCSrc;
7 | input ID_EX_MemRead;
8 | input [4:0] ID_EX_Rt;
9 | input EX_ALUOut_0;
10 |
11 | output PCWrite;
12 | output IF_ID_write;
13 | output IF_ID_flush;
14 | output ID_EX_flush;
15 |
16 | reg [2:0] PCWrite_mark;
17 | reg [2:0] IF_ID_write_mark;
18 | reg [2:0] IF_ID_flush_mark;
19 | reg [2:0] ID_EX_flush_mark;
20 |
21 | always @(*) begin
22 | // Branch
23 | if (EX_PCSrc == 3'd1 && EX_ALUOut_0) begin
24 | PCWrite_mark[0] = 1'b1;
25 | IF_ID_write_mark[0] = 1'b1;
26 | IF_ID_flush_mark[0] = 1'b1;
27 | ID_EX_flush_mark[0] = 1'b1;
28 | end
29 | else begin
30 | PCWrite_mark[0] = 1'b1;
31 | IF_ID_write_mark[0] = 1'b1;
32 | IF_ID_flush_mark[0] = 1'b0;
33 | ID_EX_flush_mark[0] = 1'b0;
34 | end
35 | // Jump
36 | if(ID_PCSrc[2:1]==2'b00) begin
37 | PCWrite_mark[1] = 1'b1;
38 | IF_ID_write_mark[1] = 1'b1;
39 | IF_ID_flush_mark[1] = 1'b0;
40 | ID_EX_flush_mark[1] = 1'b0;
41 | end
42 | else begin
43 | PCWrite_mark[1] = 1'b1;
44 | IF_ID_write_mark[1] = 1'b1;
45 | IF_ID_flush_mark[1] = 1'b1;
46 | ID_EX_flush_mark[1] = 1'b0;
47 | end
48 | // Load use
49 | if(ID_EX_MemRead && (ID_EX_Rt == IF_ID_Rs || ID_EX_Rt == IF_ID_Rt)) begin
50 | PCWrite_mark[2] = 1'b0;
51 | IF_ID_write_mark[2] = 1'b0;
52 | IF_ID_flush_mark[2] = 1'b0;
53 | ID_EX_flush_mark[2] = 1'b1;
54 | end
55 | else begin
56 | PCWrite_mark[2] = 1'b1;
57 | IF_ID_write_mark[2] = 1'b1;
58 | IF_ID_flush_mark[2] = 1'b0;
59 | ID_EX_flush_mark[2] = 1'b0;
60 | end
61 | end
62 |
63 | assign PCWrite = PCWrite_mark[0] & PCWrite_mark[1] & PCWrite_mark[2];
64 | assign IF_ID_write = IF_ID_write_mark[0] & IF_ID_write_mark[1] & IF_ID_write_mark[2];
65 | assign IF_ID_flush = IF_ID_flush_mark[0] | IF_ID_flush_mark[1] | IF_ID_flush_mark[2];
66 | assign ID_EX_flush = ID_EX_flush_mark[0] | ID_EX_flush_mark[1] | ID_EX_flush_mark[2];
67 |
68 | endmodule
--------------------------------------------------------------------------------
/src/Pipeline_CPU/ID_EX_Reg.v:
--------------------------------------------------------------------------------
1 | module ID_EX_Reg(clk, reset, ID_EX_flush, PC_add_4_in, DataBusA_in, DataBusB_in, LUOut_in, Rs_in, Rt_in, Rd_in, Shamt_in,
2 | RegDst_in, PCSrc_in, MemRead_in, MemWrite_in, MemToReg_in, ALUFun_in,
3 | ALUSrc1_in, ALUSrc2_in, RegWrite_in, Sign_in, PC_add_4_out, DataBusA_out, DataBusB_out, LUOut_out, Rs_out,
4 | Rt_out, Rd_out, Shamt_out, RegDst_out, PCSrc_out, MemRead_out, MemWrite_out,
5 | MemToReg_out, ALUFun_out, ALUSrc1_out, ALUSrc2_out, RegWrite_out, Sign_out);
6 |
7 | input clk;
8 | input reset;
9 | input ID_EX_flush;
10 | input [31:0] PC_add_4_in;
11 | input [31:0] DataBusA_in;
12 | input [31:0] DataBusB_in;
13 | input [31:0] LUOut_in;
14 |
15 | input [4:0] Rs_in;
16 | input [4:0] Rt_in;
17 | input [4:0] Rd_in;
18 | input [4:0] Shamt_in;
19 | input [1:0] RegDst_in;
20 | input [2:0] PCSrc_in;
21 | input MemRead_in;
22 | input MemWrite_in;
23 | input [1:0] MemToReg_in;
24 | input [5:0] ALUFun_in;
25 | input ALUSrc1_in;
26 | input ALUSrc2_in;
27 | input RegWrite_in;
28 | input Sign_in;
29 |
30 | output reg [31:0] PC_add_4_out;
31 | output reg [31:0] DataBusA_out;
32 | output reg [31:0] DataBusB_out;
33 | output reg [31:0] LUOut_out;
34 |
35 | output reg [4:0] Rs_out;
36 | output reg [4:0] Rt_out;
37 | output reg [4:0] Rd_out;
38 | output reg [4:0] Shamt_out;
39 | output reg [1:0] RegDst_out;
40 | output reg [2:0] PCSrc_out;
41 | output reg MemRead_out;
42 | output reg MemWrite_out;
43 | output reg [1:0] MemToReg_out;
44 | output reg [5:0] ALUFun_out;
45 | output reg ALUSrc1_out;
46 | output reg ALUSrc2_out;
47 | output reg RegWrite_out;
48 | output reg Sign_out;
49 |
50 |
51 | always @(posedge clk or negedge reset) begin
52 | if (~reset) begin
53 | PC_add_4_out <= 32'h8000_0000;
54 | DataBusA_out <= 32'h0000_0000;
55 | DataBusB_out <= 32'h0000_0000;
56 | LUOut_out <= 32'h0000_0000;
57 | Rs_out <= 5'h00;
58 | Rt_out <= 5'h00;
59 | Rd_out <= 5'h00;
60 | Shamt_out <= 5'h00;
61 | RegDst_out <= 2'h0;
62 | PCSrc_out <= 3'h0;
63 | MemRead_out <= 1'h0;
64 | MemWrite_out <= 1'h0;
65 | MemToReg_out <= 2'h0;
66 | ALUFun_out <= 6'h00;
67 | ALUSrc1_out <= 1'h0;
68 | ALUSrc2_out <= 1'h0;
69 | RegWrite_out <= 1'h0;
70 | Sign_out <= 1'h0;
71 | end
72 | else begin
73 | // Again, we do not flush PC to cope with IRQ hazard
74 | if(ID_EX_flush) begin
75 | PC_add_4_out <= PC_add_4_in - 4;
76 | DataBusA_out <= 32'h0000_0000;
77 | DataBusB_out <= 32'h0000_0000;
78 | LUOut_out <= 32'h0000_0000;
79 | Rs_out <= 5'h00;
80 | Rt_out <= 5'h00;
81 | Rd_out <= 5'h00;
82 | Shamt_out <= 5'h00;
83 | RegDst_out <= 2'h0;
84 | PCSrc_out <= 3'h0;
85 | MemRead_out <= 1'h0;
86 | MemWrite_out <= 1'h0;
87 | MemToReg_out <= 2'h0;
88 | ALUFun_out <= 6'h00;
89 | ALUSrc1_out <= 1'h0;
90 | ALUSrc2_out <= 1'h0;
91 | RegWrite_out <= 1'h0;
92 | Sign_out <= 1'h0;
93 | end
94 | else begin
95 | PC_add_4_out <= PC_add_4_in;
96 | DataBusA_out <= DataBusA_in;
97 | DataBusB_out <= DataBusB_in;
98 | LUOut_out <= LUOut_in;
99 | Rs_out <= Rs_in;
100 | Rt_out <= Rt_in;
101 | Rd_out <= Rd_in;
102 | Shamt_out <= Shamt_in;
103 | RegDst_out <= RegDst_in;
104 | PCSrc_out <= PCSrc_in;
105 | MemRead_out <= MemRead_in;
106 | MemWrite_out <= MemWrite_in;
107 | MemToReg_out <= MemToReg_in;
108 | ALUFun_out <= ALUFun_in;
109 | ALUSrc1_out <= ALUSrc1_in;
110 | ALUSrc2_out <= ALUSrc2_in;
111 | RegWrite_out <= RegWrite_in;
112 | Sign_out <= Sign_in;
113 | end
114 | end
115 | end
116 |
117 | endmodule
--------------------------------------------------------------------------------
/src/Pipeline_CPU/IF_ID_Reg.v:
--------------------------------------------------------------------------------
1 | module IF_ID_Reg(clk, reset, IF_ID_flush, ID_EX_flush, IF_ID_write, PC_add_4_in, Instruct_in,
2 | PC_add_4_out, Instruct_out);
3 |
4 | input clk;
5 | input reset;
6 | input IF_ID_flush;
7 | input ID_EX_flush;
8 | input IF_ID_write;
9 | input [31:0] PC_add_4_in;
10 | input [31:0] Instruct_in;
11 | output reg [31:0] PC_add_4_out;
12 | output reg [31:0] Instruct_out;
13 |
14 | always @(posedge clk or negedge reset) begin
15 | if (~reset) begin
16 | PC_add_4_out <= 32'h8000_0000;
17 | Instruct_out <= 32'h0000_0000;
18 | end
19 | else begin
20 | if(IF_ID_flush) begin
21 | // Here we do not flush PC to zeor to cope with IRQ hazard
22 | if(ID_EX_flush) begin
23 | PC_add_4_out <= PC_add_4_in - 8;
24 | end
25 | else begin
26 | PC_add_4_out <= PC_add_4_in - 4;
27 | end
28 | Instruct_out <= 32'h0000_0000;
29 | end
30 | else begin
31 | if (IF_ID_write) begin
32 | PC_add_4_out <= PC_add_4_in;
33 | Instruct_out <= Instruct_in;
34 | end
35 | end
36 | end
37 | end
38 |
39 | endmodule
--------------------------------------------------------------------------------
/src/Pipeline_CPU/MEM_WB_Reg.v:
--------------------------------------------------------------------------------
1 | module MEM_WB_Reg(clk, reset, PC_add_4_in, ALUOut_in, MemReadData_in, Rt_in, Rd_in, RegDst_in, MemToReg_in, RegWrite_in,
2 | AddrC_in, PC_add_4_out, ALUOut_out, MemReadData_out, Rt_out, Rd_out, RegDst_out, MemToReg_out, RegWrite_out, AddrC_out);
3 |
4 | input clk;
5 | input reset;
6 | input [31:0] PC_add_4_in;
7 | input [31:0] ALUOut_in;
8 | input [31:0] MemReadData_in;
9 | input [4:0] Rt_in;
10 | input [4:0] Rd_in;
11 | input [1:0] RegDst_in;
12 | input [1:0] MemToReg_in;
13 | input RegWrite_in;
14 | input [4:0] AddrC_in;
15 |
16 | output reg [31:0] PC_add_4_out;
17 | output reg [31:0] ALUOut_out;
18 | output reg [31:0] MemReadData_out;
19 | output reg [4:0] Rt_out;
20 | output reg [4:0] Rd_out;
21 | output reg [1:0] RegDst_out;
22 | output reg [1:0] MemToReg_out;
23 | output reg RegWrite_out;
24 | output reg [4:0] AddrC_out;
25 |
26 | always @(posedge clk or negedge reset) begin
27 | if (~reset) begin
28 | PC_add_4_out <= 32'h0000_0000;
29 | ALUOut_out <= 32'h0000_0000;
30 | MemReadData_out <= 32'h0000_0000;
31 | Rt_out <= 5'h00;
32 | Rd_out <= 5'h00;
33 | RegDst_out <= 2'h0;
34 | MemToReg_out <= 2'h0;
35 | RegWrite_out <= 1'h0;
36 | AddrC_out <= 5'h0;
37 | end
38 | else begin
39 | PC_add_4_out <= PC_add_4_in;
40 | ALUOut_out <= ALUOut_in;
41 | MemReadData_out <= MemReadData_in;
42 | Rt_out <= Rt_in;
43 | Rd_out <= Rd_in;
44 | RegDst_out <= RegDst_in;
45 | MemToReg_out <= MemToReg_in;
46 | RegWrite_out <= RegWrite_in;
47 | AddrC_out <= AddrC_in;
48 | end
49 | end
50 |
51 | endmodule
--------------------------------------------------------------------------------
/src/Pipeline_CPU/Peripheral.v:
--------------------------------------------------------------------------------
1 | `timescale 1ns/1ps
2 |
3 | module Peripheral (reset,clk,rd,wr,addr,wdata,rdata,led,switch,digi,irqout);
4 | input reset,clk;
5 | input rd,wr;
6 | input [31:0] addr;
7 | input [31:0] wdata;
8 | output [31:0] rdata;
9 | reg [31:0] rdata;
10 |
11 | output [7:0] led;
12 | reg [7:0] led;
13 | input [7:0] switch;
14 | output [11:0] digi;
15 | reg [11:0] digi;
16 | output irqout;
17 |
18 | reg [31:0] TH,TL;
19 | reg [2:0] TCON;
20 | assign irqout = TCON[2];
21 |
22 | always@(*) begin
23 | if(rd) begin
24 | case(addr)
25 | 32'h40000000: rdata <= TH;
26 | 32'h40000004: rdata <= TL;
27 | 32'h40000008: rdata <= {29'b0,TCON};
28 | 32'h4000000C: rdata <= {24'b0,led};
29 | 32'h40000010: rdata <= {24'b0,switch};
30 | 32'h40000014: rdata <= {20'b0,digi};
31 | default: rdata <= 32'b0;
32 | endcase
33 | end
34 | else
35 | rdata <= 32'b0;
36 | end
37 |
38 | always@(negedge reset or posedge clk) begin
39 | if(~reset) begin
40 | TH <= 32'b0;
41 | TL <= 32'b0;
42 | TCON <= 3'b0;
43 | end
44 | else begin
45 | if(TCON[0]) begin //timer is enabled
46 | if(TL==32'hffffffff) begin
47 | TL <= TH;
48 | if(TCON[1]) TCON[2] <= 1'b1; //irq is enabled
49 | end
50 | else TL <= TL + 1;
51 | end
52 |
53 | if(wr) begin
54 | case(addr)
55 | 32'h40000000: TH <= wdata;
56 | 32'h40000004: TL <= wdata;
57 | 32'h40000008: TCON <= wdata[2:0];
58 | 32'h4000000C: led <= wdata[7:0];
59 | 32'h40000014: digi <= wdata[11:0];
60 | default: ;
61 | endcase
62 | end
63 | end
64 | end
65 | endmodule
66 |
67 |
--------------------------------------------------------------------------------
/src/Pipeline_CPU/PipeLine_Core.v:
--------------------------------------------------------------------------------
1 | module Pipeline_Core(clk, reset, MemAddr, WriteData, ReadData, MemWrite, MemRead, IRQ_in);
2 |
3 | /************************IO*************************/
4 | input clk;
5 | input reset;
6 | input IRQ_in;
7 | input [31:0] ReadData;
8 | output [31:0] MemAddr;
9 | output [31:0] WriteData;
10 | output MemWrite;
11 | output MemRead;
12 |
13 | /************************IF*************************/
14 | wire IRQ;
15 | wire [2:0] IF_PCSrc;
16 | reg [31:0] IF_PC;
17 | wire [31:0] IF_PC_add;
18 | wire [31:0] IF_PC_add_4;
19 | wire [31:0] IF_Instruct;
20 |
21 | /************************ID*************************/
22 | wire [31:0] ID_PC_add_4;
23 | wire [31:0] ID_Instruct;
24 | wire [4:0] ID_Rs;
25 | wire [4:0] ID_Rt;
26 | wire [4:0] ID_Rd;
27 | wire [4:0] ID_Shamt;
28 | wire [15:0] ID_Immediate;
29 | wire [25:0] ID_JumpAddr;
30 | wire [31:0] ID_JT;
31 | wire [31:0] ID_DataBusA;
32 | wire [31:0] ID_DataBusB;
33 | wire [31:0] ID_EXTOut;
34 | wire [31:0] ID_LUOut;
35 |
36 | wire [1:0] ID_RegDst;
37 | wire [2:0] ID_PCSrc;
38 | wire ID_MemRead;
39 | wire ID_MemWrite;
40 | wire [1:0] ID_MemToReg;
41 | wire [5:0] ID_ALUFun;
42 | wire ID_EXTOp;
43 | wire ID_LUOp;
44 | wire ID_ALUSrc1;
45 | wire ID_ALUSrc2;
46 | wire ID_RegWrite;
47 | wire ID_Sign;
48 |
49 | /************************EX*************************/
50 | wire [31:0] EX_PC_add_4;
51 | wire [4:0] EX_Rs;
52 | wire [4:0] EX_Rt;
53 | wire [4:0] EX_Rd;
54 | wire [4:0] EX_Shamt;
55 | wire [4:0] EX_AddrC;
56 | wire [31:0] EX_ALU_A;
57 | wire [31:0] EX_ALU_B;
58 | wire [31:0] EX_ALUOut;
59 | wire [31:0] EX_DataBusA;
60 | wire [31:0] EX_DataBusB;
61 | wire [31:0] EX_LUOut;
62 | wire [31:0] EX_BT;
63 |
64 | wire EX_Sign;
65 | wire [1:0] EX_RegDst;
66 | wire [2:0] EX_PCSrc;
67 | wire EX_MemRead;
68 | wire EX_MemWrite;
69 | wire [1:0] EX_MemToReg;
70 | wire [5:0] EX_ALUFun;
71 | wire EX_ALUSrc1;
72 | wire EX_ALUSrc2;
73 | wire EX_RegWrite;
74 |
75 | /************************MEM************************/
76 | wire [31:0] MEM_PC_add_4;
77 | wire [4:0] MEM_Rt;
78 | wire [4:0] MEM_Rd;
79 | wire [31:0] MEM_DataBusB;
80 | wire [4:0] MEM_AddrC;
81 | wire [31:0] MEM_MemReadData;
82 | wire [31:0] MEM_ALUOut;
83 |
84 | wire [1:0] MEM_RegDst;
85 | wire MEM_MemRead;
86 | wire MEM_MemWrite;
87 | wire [1:0] MEM_MemToReg;
88 | wire MEM_RegWrite;
89 |
90 | /*************************WB**************************/
91 | wire [31:0] WB_PC_add_4;
92 | wire [4:0] WB_Rt;
93 | wire [4:0] WB_Rd;
94 | wire [31:0] WB_DataBusC;
95 | wire [31:0] WB_MemReadData;
96 | wire [4:0] WB_AddrC;
97 | wire [31:0] WB_ALUOut;
98 |
99 | wire [1:0] WB_RegDst;
100 | wire [1:0] WB_MemToReg;
101 | wire WB_RegWrite;
102 |
103 | /************************Forward**********************/
104 | wire [1:0] ForwardA;
105 | wire [1:0] ForwardB;
106 | wire [1:0] ForwardJ;
107 | wire [31:0] ForwardAData;
108 | wire [31:0] ForwardBData;
109 | wire [31:0] ForwardJData;
110 |
111 | /************************Hazard**********************/
112 | wire PCWrite;
113 | wire IF_ID_write;
114 | wire IF_ID_flush;
115 | wire ID_EX_flush;
116 | // -----------------------------------------------------
117 | // -----------------------------------------------------
118 |
119 | /************************IF**************************/
120 | assign IRQ = (~IF_PC[31]) & IRQ_in;
121 |
122 | // Strategy for branch: execute next line directly, flush it if branch do happens
123 | assign IF_PCSrc = (EX_PCSrc == 3'b001 && EX_ALUOut[0]) ? 3'b001 : (ID_PCSrc == 3'b001 ? 3'b000 : ID_PCSrc);
124 |
125 | // PC Reg
126 | parameter ILLOP = 32'h8000_0004;
127 | parameter XADR = 32'h8000_0008;
128 | assign IF_PC_add = IF_PC + 32'h4;
129 | assign IF_PC_add_4 = {IF_PC[31], IF_PC_add[30:0]};
130 |
131 | always@(posedge clk or negedge reset)
132 | if(~reset)
133 | IF_PC <= 32'h8000_0000;
134 | else if(PCWrite)
135 | case(IF_PCSrc)
136 | 3'h0: IF_PC <= IF_PC_add_4;
137 | 3'h1: IF_PC <= EX_BT;
138 | 3'h2: IF_PC <= ID_JT;
139 | 3'h3: IF_PC <= ForwardJData;
140 | 3'h4: IF_PC <= ILLOP;
141 | 3'h5: IF_PC <= XADR;
142 | default: IF_PC <= 32'h8000_0000;
143 | endcase
144 |
145 | // Instruction Fetch
146 | ROM ROM_1(.addr(IF_PC), .data(IF_Instruct));
147 |
148 | /************************IF_ID_Reg*************************/
149 | IF_ID_Reg IF_ID_Reg_0(.clk(clk), .reset(reset), .IF_ID_flush(IF_ID_flush), .ID_EX_flush(ID_EX_flush), .IF_ID_write(IF_ID_write),
150 | .PC_add_4_in(IF_PC_add_4), .Instruct_in(IF_Instruct), .PC_add_4_out(ID_PC_add_4), .Instruct_out(ID_Instruct));
151 |
152 | /************************ID&WB***************************/
153 | parameter Xp = 5'd26;
154 | parameter Ra = 5'd31;
155 | assign ID_Rs = ID_Instruct[25:21];
156 | assign ID_Rt = ID_Instruct[20:16];
157 | assign ID_Rd = ID_Instruct[15:11];
158 | assign ID_Shamt = ID_Instruct[10:6];
159 | assign ID_Immediate = ID_Instruct[15:0];
160 | assign ID_JumpAddr = ID_Instruct[25:0];
161 |
162 | assign WB_DataBusC = (WB_MemToReg == 2'b00)? WB_ALUOut: (WB_MemToReg == 2'b01)? WB_MemReadData: WB_PC_add_4;
163 |
164 | // Register File
165 | RegFile RegFile_1(.reset(reset), .clk(clk), .addr1(ID_Rs), .data1(ID_DataBusA), .addr2(ID_Rt), .data2(ID_DataBusB), .wr(WB_RegWrite),
166 | .addr3(WB_AddrC), .data3(WB_DataBusC));
167 |
168 | assign ID_EXTOut = {ID_EXTOp? {16{ID_Immediate[15]}}: 16'h0000, ID_Immediate[15:0]};
169 | assign ID_LUOut = ID_LUOp? {ID_Immediate[15:0], 16'h0000}: ID_EXTOut;
170 | assign ID_JT = {IF_PC_add_4[31:28], ID_JumpAddr, 2'b00};
171 |
172 | /************************ID_EX_Reg*************************/
173 | ID_EX_Reg ID_EX_Reg_1(.clk(clk), .reset(reset), .ID_EX_flush(ID_EX_flush), .PC_add_4_in(ID_PC_add_4), .DataBusA_in(ID_DataBusA),
174 | .DataBusB_in(ID_DataBusB), .LUOut_in(ID_LUOut), .Rs_in(ID_Rs), .Rt_in(ID_Rt), .Rd_in(ID_Rd),
175 | .Shamt_in(ID_Shamt), .RegDst_in(ID_RegDst), .PCSrc_in(ID_PCSrc), .MemRead_in(ID_MemRead), .MemWrite_in(ID_MemWrite),
176 | .MemToReg_in(ID_MemToReg), .ALUFun_in(ID_ALUFun), .ALUSrc1_in(ID_ALUSrc1), .ALUSrc2_in(ID_ALUSrc2), .RegWrite_in(ID_RegWrite), .Sign_in(ID_Sign),
177 | .PC_add_4_out(EX_PC_add_4), .DataBusA_out(EX_DataBusA), .DataBusB_out(EX_DataBusB), .LUOut_out(EX_LUOut),
178 | .Rs_out(EX_Rs), .Rt_out(EX_Rt), .Rd_out(EX_Rd), .Shamt_out(EX_Shamt), .RegDst_out(EX_RegDst), .PCSrc_out(EX_PCSrc), .MemRead_out(EX_MemRead),
179 | .MemWrite_out(EX_MemWrite), .MemToReg_out(EX_MemToReg), .ALUFun_out(EX_ALUFun), .ALUSrc1_out(EX_ALUSrc1), .ALUSrc2_out(EX_ALUSrc2), .RegWrite_out(EX_RegWrite), .Sign_out(EX_Sign));
180 |
181 | /************************EX***************************/
182 | // ALU Input
183 | assign EX_ALU_A = EX_ALUSrc1? {17'h00000, EX_Shamt}: ForwardAData;
184 | assign EX_ALU_B = EX_ALUSrc2? EX_LUOut: ForwardBData;
185 | // Jump dst for branch instruction
186 | assign EX_BT = (EX_ALUOut[0])? EX_PC_add_4 + {EX_LUOut[29:0], 2'b00}: EX_PC_add_4;
187 | // AddrC will be used in WB, so it will flow to the next state
188 | assign EX_AddrC = (EX_RegDst == 2'b00)? EX_Rd: (EX_RegDst == 2'b01)? EX_Rt: (EX_RegDst == 2'b10)? Ra : Xp;
189 |
190 | ALU ALU_1(.A(EX_ALU_A), .B(EX_ALU_B), .ALUFun(EX_ALUFun), .Sign(EX_Sign), .Z(EX_ALUOut));
191 |
192 | /************************EX_MEM_Reg*************************/
193 | EX_MEM_Reg EX_MEM_Reg_1(.clk(clk), .reset(reset), .PC_add_4_in(EX_PC_add_4), .ALUOut_in(EX_ALUOut), .DataBusB_in(ForwardBData), .Rt_in(EX_Rt), .Rd_in(EX_Rd), .RegDst_in(EX_RegDst),
194 | .MemRead_in(EX_MemRead), .MemWrite_in(EX_MemWrite), .MemToReg_in(EX_MemToReg), .RegWrite_in(EX_RegWrite), .AddrC_in(EX_AddrC),.PC_add_4_out(MEM_PC_add_4), .ALUOut_out(MEM_ALUOut), .DataBusB_out(MEM_DataBusB),
195 | .Rt_out(MEM_Rt), .Rd_out(MEM_Rd), .RegDst_out(MEM_RegDst), .MemRead_out(MEM_MemRead), .MemWrite_out(MEM_MemWrite), .MemToReg_out(MEM_MemToReg), .RegWrite_out(MEM_RegWrite), .AddrC_out(MEM_AddrC));
196 |
197 | /************************MEM*************************/
198 | assign MemAddr = MEM_ALUOut;
199 | assign MemWrite = MEM_MemWrite;
200 | assign MemRead = MEM_MemRead;
201 | assign MEM_MemReadData = ReadData;
202 | assign WriteData = MEM_DataBusB;
203 |
204 | /************************MEM_WB*************************/
205 | MEM_WB_Reg MEM_WB_Reg_1(.clk(clk), .reset(reset), .PC_add_4_in(MEM_PC_add_4), .ALUOut_in(MEM_ALUOut), .MemReadData_in(MEM_MemReadData), .Rt_in(MEM_Rt),
206 | .Rd_in(MEM_Rd), .RegDst_in(MEM_RegDst), .MemToReg_in(MEM_MemToReg), .RegWrite_in(MEM_RegWrite), .AddrC_in(MEM_AddrC), .PC_add_4_out(WB_PC_add_4), .ALUOut_out(WB_ALUOut),
207 | .MemReadData_out(WB_MemReadData), .Rt_out(WB_Rt), .Rd_out(WB_Rd), .RegDst_out(WB_RegDst), .MemToReg_out(WB_MemToReg), .RegWrite_out(WB_RegWrite), .AddrC_out(WB_AddrC));
208 |
209 | /************************Control*************************/
210 | Control Control_1(.Instruct(ID_Instruct), .IRQ(IRQ), .PC31(ID_PC_add_4[31]), .PCSrc(ID_PCSrc), .RegWr(ID_RegWrite), .RegDst(ID_RegDst), .MemRd(ID_MemRead), .MemWr(ID_MemWrite),
211 | .MemToReg(ID_MemToReg), .ALUSrc1(ID_ALUSrc1), .ALUSrc2(ID_ALUSrc2), .EXTOp(ID_EXTOp), .LUOp(ID_LUOp), .ALUFun(ID_ALUFun), .Sign(ID_Sign));
212 |
213 | /************************Forward*************************/
214 | Forward_Unit Forward_Unit_1(.IF_ID_Rs(ID_Rs), .ID_EX_Rs(EX_Rs), .ID_EX_Rt(EX_Rt), .ID_PCSrc(ID_PCSrc), .ID_EX_RegWrite(EX_RegWrite), .ID_EX_AddrC(EX_AddrC),
215 | .EX_MEM_RegWrite(MEM_RegWrite), .EX_MEM_AddrC(MEM_AddrC), .MEM_WB_RegWrite(WB_RegWrite), .MEM_WB_AddrC(WB_AddrC), .ForwardA(ForwardA), .ForwardB(ForwardB),
216 | .ForwardJ(ForwardJ));
217 |
218 | assign ForwardAData = (ForwardA==2'b00) ? EX_DataBusA : (ForwardA==2'b01) ? WB_DataBusC : MEM_ALUOut;
219 | assign ForwardBData = (ForwardB==2'b00) ? EX_DataBusB : (ForwardB==2'b01) ? WB_DataBusC : MEM_ALUOut;
220 | assign ForwardJData = (ForwardJ == 2'b00) ? ID_DataBusA : (ForwardJ == 2'b01) ? EX_ALUOut :
221 | (ForwardJ == 2'b10) ? WB_MemReadData : WB_DataBusC;
222 |
223 | /************************Hazard*************************/
224 | Hazard_Unit Hazard_Unit_1(.IF_ID_Rs(ID_Rs), .IF_ID_Rt(ID_Rt), .ID_PCSrc(ID_PCSrc),.EX_PCSrc(EX_PCSrc), .ID_EX_MemRead(EX_MemRead), .ID_EX_Rt(EX_Rt), .EX_ALUOut_0(EX_ALUOut[0]),
225 | .PCWrite(PCWrite), .IF_ID_write(IF_ID_write),.IF_ID_flush(IF_ID_flush), .ID_EX_flush(ID_EX_flush));
226 |
227 | endmodule
228 |
--------------------------------------------------------------------------------
/src/Pipeline_CPU/PipelineCPU.v:
--------------------------------------------------------------------------------
1 | `timescale 1ns/1ps
2 |
3 | module PipelineCPU(reset, sysclk, UART_RX, UART_TX, switch, led, digi_1, digi_2, digi_3, digi_4);
4 |
5 | /************************IO*************************/
6 | input reset, sysclk, UART_RX;
7 | input [7:0] switch;
8 | output UART_TX;
9 | output [7:0] led;
10 | output [6:0] digi_1, digi_2, digi_3, digi_4;
11 |
12 | wire irq, per_irq, rx_irq, tx_irq;
13 | wire [11:0] digi;
14 | wire [31:0] memRdData;
15 | wire [31:0] periRdData;
16 | wire [31:0] uartRdData;
17 | wire [31:0] ReadData;
18 | wire [31:0] WriteData;
19 | wire [31:0] MemAddr;
20 | wire MemRead;
21 | wire MemWrite;
22 | /************************Clk*************************/
23 | wire clk;
24 | assign clk = sysclk;
25 |
26 | /************************Core*************************/
27 | Pipeline_Core Pipeline_Core_1(.clk(clk), .reset(reset), .MemAddr(MemAddr), .WriteData(WriteData),
28 | .ReadData(ReadData), .MemWrite(MemWrite), .MemRead(MemRead), .IRQ_in(irq));
29 |
30 | /***********************Peripheral********************/
31 | DataMem DataMem_1(.reset(reset), .clk(clk), .rd(MemRead), .wr(MemWrite), .addr(MemAddr), .wdata(WriteData), .rdata(memRdData));
32 |
33 | assign irq = per_irq | rx_irq | tx_irq;
34 | assign ReadData = memRdData | periRdData | uartRdData;
35 | Peripheral Peripheral_1(.reset(reset), .clk(clk), .rd(MemRead), .wr(MemWrite), .addr(MemAddr), .wdata(WriteData), .rdata(periRdData), .led(led), .switch(switch), .digi(digi), .irqout(per_irq));
36 | Digitube_scan Digitube_scan(.digi_in(digi), .digi_out1(digi_1), .digi_out2(digi_2), .digi_out3(digi_3), .digi_out4(digi_4));
37 | UART UART_1(.reset(reset), .sysclk(sysclk), .clk(clk), .rd(MemRead), .wr(MemWrite), .addr(MemAddr), .wdata(WriteData), .rdata(uartRdData), .UART_RX(UART_RX), .UART_TX(UART_TX), .RX_IRQ(rx_irq), .TX_IRQ(tx_irq));
38 |
39 | endmodule
--------------------------------------------------------------------------------
/src/Pipeline_CPU/Pipeline_CPU_tb.v:
--------------------------------------------------------------------------------
1 | `timescale 1ns/1ns
2 |
3 | module baudrate_generator(sysclk, reset, brclk, brclk16);
4 | input sysclk,reset;
5 | output reg brclk, brclk16;
6 | reg [11:0] cnt;
7 | reg [7:0] cnt16;
8 |
9 | always @(posedge sysclk or negedge reset)
10 | begin
11 | if(~reset) begin
12 | cnt <= 12'd0;
13 | cnt16 <= 8'd0;
14 | brclk <= 1;
15 | brclk16 <= 1;
16 | end
17 | else begin
18 | if(cnt16 == 8'd162) begin
19 | cnt16 <= 8'd0;
20 | brclk16 <= ~brclk16;
21 | end
22 | else
23 | cnt16 <= cnt16 + 8'd1;
24 | if(cnt == 12'd2603) begin
25 | cnt <= 12'd0;
26 | brclk <= ~brclk;
27 | end
28 | else
29 | cnt <= cnt + 12'd1;
30 | end
31 | end
32 |
33 | endmodule
34 |
35 |
36 |
37 | module CPU_tb;
38 | reg reset, sysclk;
39 | reg [7:0] switch;
40 | reg [36:0] tmprx;
41 | wire UART_RX, UART_TX, brclk9600, brclk153600;
42 | wire [7:0] led;
43 | wire [6:0] digi_1;
44 | wire [6:0] digi_2;
45 | wire [6:0] digi_3;
46 | wire [6:0] digi_4;
47 |
48 | initial begin
49 | reset <= 0;
50 | sysclk <= 0;
51 | reset <= 0;
52 | switch <= 8'b01001010;
53 | tmprx <= 37'b11_0_0000_0101_1_0_0001_1001_1111_1111_1111_1111;
54 | end
55 |
56 | initial fork
57 | #13 reset <= 1;
58 | forever #10 sysclk = ~sysclk;
59 | join
60 |
61 | baudrate_generator baudrate_generator_1(.sysclk(sysclk), .reset(reset), .brclk(brclk9600), .brclk16(brclk153600));
62 |
63 | always @(posedge brclk9600)
64 | begin
65 | tmprx <= tmprx<<1;
66 | end
67 |
68 | assign UART_RX = tmprx[36];
69 |
70 | PipelineCPU PipelineCPU_1(reset, sysclk, UART_RX, UART_TX, switch, led, digi_1, digi_2, digi_3, digi_4);
71 |
72 | endmodule
--------------------------------------------------------------------------------
/src/Pipeline_CPU/ROM.v:
--------------------------------------------------------------------------------
1 | `timescale 1ns/1ps
2 |
3 | module ROM (addr,data);
4 | input [31:0] addr;
5 | output [31:0] data;
6 | reg [31:0] data;
7 | localparam ROM_size = 32;
8 | reg [31:0] ROM_data[ROM_size-1:0];
9 |
10 | always@(*)
11 | case(addr[8:2]) //Address Must Be Word Aligned.
12 | // j INIT
13 | 0: data <= 32'b00001000000000000000000000000011;
14 | // j INTER
15 | 1: data <= 32'b00001000000000000000000000101100;
16 | // j EXCEPT
17 | 2: data <= 32'b00001000000000000000000010000000;
18 | //INIT:
19 | // addi $t0, $zero, 0x0014
20 | 3: data <= 32'b00100000000010000000000000010100;
21 | // jr $t0
22 | 4: data <= 32'b00000001000000000000000000001000;
23 | // lui $s0, 0x4000
24 | 5: data <= 32'b00111100000100000100000000000000;
25 | // sw $zero, 8($s0)
26 | 6: data <= 32'b10101110000000000000000000001000;
27 | // addi $s1, $zero, -25000
28 | 7: data <= 32'b00100000000100011001111001011000;
29 | // sw $s1, 0($s0)
30 | 8: data <= 32'b10101110000100010000000000000000;
31 | // addi $s1, $zero, -1
32 | 9: data <= 32'b00100000000100011111111111111111;
33 | // sw $s1, 4($s0)
34 | 10: data <= 32'b10101110000100010000000000000100;
35 | // addi $s1, $zero, 3
36 | 11: data <= 32'b00100000000100010000000000000011;
37 | // sw $s1, 8($s0)
38 | 12: data <= 32'b10101110000100010000000000001000;
39 | // sw $t0, 32($s0)
40 | 13: data <= 32'b10101110000010000000000000100000;
41 | //UART_START:
42 | // addi $s1, $zero, -1
43 | 14: data <= 32'b00100000000100011111111111111111;
44 | //UART_LOOP:
45 | // lw $t0, 32($s0)
46 | 15: data <= 32'b10001110000010000000000000100000;
47 | // andi $t0, $t0, 0x08
48 | 16: data <= 32'b00110001000010000000000000001000;
49 | // beq $t0, $zero, UART_LOOP
50 | 17: data <= 32'b00010001000000001111111111111101;
51 | // lw $v1, 28($s0)
52 | 18: data <= 32'b10001110000000110000000000011100;
53 | // beq $v1, $zero, UART_LOOP
54 | 19: data <= 32'b00010000011000001111111111111011;
55 | // beq $s1, $zero, LOAD_2
56 | 20: data <= 32'b00010010001000000000000000000011;
57 | // addi $s4, $v1, 0
58 | 21: data <= 32'b00100000011101000000000000000000;
59 | // addi $s1, $s1, 1
60 | 22: data <= 32'b00100010001100010000000000000001;
61 | // j UART_LOOP
62 | 23: data <= 32'b00001000000000000000000000001111;
63 | //LOAD_2:
64 | // addi $s3, $v1, 0
65 | 24: data <= 32'b00100000011100110000000000000000;
66 | // addi $v0, $s4, 0
67 | 25: data <= 32'b00100010100000100000000000000000;
68 | //GCD:
69 | // beq $v0, $zero, ANS1
70 | 26: data <= 32'b00010000010000000000000000001000;
71 | // beq $v1, $zero, ANS2
72 | 27: data <= 32'b00010000011000000000000000001001;
73 | // sub $t3, $v0, $v1
74 | 28: data <= 32'b00000000010000110101100000100010;
75 | // bgtz $t3, LOOP1
76 | 29: data <= 32'b00011101011000000000000000000001;
77 | // bltz $t3, LOOP2
78 | 30: data <= 32'b00000101011000000000000000000010;
79 | //LOOP1:
80 | // sub $v0, $v0, $v1
81 | 31: data <= 32'b00000000010000110001000000100010;
82 | // j GCD
83 | 32: data <= 32'b00001000000000000000000000011010;
84 | //LOOP2:
85 | // sub $v1, $v1, $v0
86 | 33: data <= 32'b00000000011000100001100000100010;
87 | // j GCD
88 | 34: data <= 32'b00001000000000000000000000011010;
89 | //ANS1:
90 | // add $a0, $v1, $zero
91 | 35: data <= 32'b00000000011000000010000000100000;
92 | // j RESULT_DISPLAY
93 | 36: data <= 32'b00001000000000000000000000100110;
94 | //ANS2:
95 | // add $a0, $v0, $zero
96 | 37: data <= 32'b00000000010000000010000000100000;
97 | //RESULT_DISPLAY:
98 | // sw $a0, 12($s0)
99 | 38: data <= 32'b10101110000001000000000000001100;
100 | //UART_SEND_BACK:
101 | // lw $t0, 32($s0)
102 | 39: data <= 32'b10001110000010000000000000100000;
103 | // andi $t0, $t0, 0x10
104 | 40: data <= 32'b00110001000010000000000000010000;
105 | // bne $t0, $zero, UART_SEND_BACK
106 | 41: data <= 32'b00010101000000001111111111111101;
107 | // sw $a0, 24($s0)
108 | 42: data <= 32'b10101110000001000000000000011000;
109 | // j UART_START
110 | 43: data <= 32'b00001000000000000000000000001110;
111 | //INTER:
112 | // lw $t7, 8($s0)
113 | 44: data <= 32'b10001110000011110000000000001000;
114 | // andi $t7, $t7, 0xfff9
115 | 45: data <= 32'b00110001111011111111111111111001;
116 | // sw $t7, 8($s0)
117 | 46: data <= 32'b10101110000011110000000000001000;
118 | // addi $t3, $zero, 1
119 | 47: data <= 32'b00100000000010110000000000000001;
120 | // addi $t4, $zero, 2
121 | 48: data <= 32'b00100000000011000000000000000010;
122 | // addi $t5, $zero, 4
123 | 49: data <= 32'b00100000000011010000000000000100;
124 | // addi $t6, $zero, 8
125 | 50: data <= 32'b00100000000011100000000000001000;
126 | // lw $t7, 20($s0)
127 | 51: data <= 32'b10001110000011110000000000010100;
128 | // andi $t7, $t7, 0xf00
129 | 52: data <= 32'b00110001111011110000111100000000;
130 | // srl $t7, $t7, 8
131 | 53: data <= 32'b00000000000011110111101000000010;
132 | // beq $t7, $t3, DIGITAL_TUBE_1
133 | 54: data <= 32'b00010001111010110000000000000110;
134 | // beq $t7, $t4, DIGITAL_TUBE_2
135 | 55: data <= 32'b00010001111011000000000000001010;
136 | // beq $t7, $t5, DIGITAL_TUBE_3
137 | 56: data <= 32'b00010001111011010000000000001101;
138 | //DIGITAL_TUBE_0:
139 | // andi $s5, $s3, 0x0f
140 | 57: data <= 32'b00110010011101010000000000001111;
141 | // jal DECODE
142 | 58: data <= 32'b00001100000000000000000001001011;
143 | // addi $s5, $s2, 0x100
144 | 59: data <= 32'b00100010010101010000000100000000;
145 | // j DIGITAL_TUBE_DISPLAY
146 | 60: data <= 32'b00001000000000000000000001111001;
147 | //DIGITAL_TUBE_1:
148 | // andi $s5, $s3, 0xf0
149 | 61: data <= 32'b00110010011101010000000011110000;
150 | // srl $s5, $s5, 4
151 | 62: data <= 32'b00000000000101011010100100000010;
152 | // jal DECODE
153 | 63: data <= 32'b00001100000000000000000001001011;
154 | // addi $s5, $s2, 0x200
155 | 64: data <= 32'b00100010010101010000001000000000;
156 | // j DIGITAL_TUBE_DISPLAY
157 | 65: data <= 32'b00001000000000000000000001111001;
158 | //DIGITAL_TUBE_2:
159 | // andi $s5, $s4, 0x0f
160 | 66: data <= 32'b00110010100101010000000000001111;
161 | // jal DECODE
162 | 67: data <= 32'b00001100000000000000000001001011;
163 | // addi $s5, $s2, 0x400
164 | 68: data <= 32'b00100010010101010000010000000000;
165 | // j DIGITAL_TUBE_DISPLAY
166 | 69: data <= 32'b00001000000000000000000001111001;
167 | //DIGITAL_TUBE_3:
168 | // andi $s5, $s4, 0xf0
169 | 70: data <= 32'b00110010100101010000000011110000;
170 | // srl $s5, $s5, 4
171 | 71: data <= 32'b00000000000101011010100100000010;
172 | // jal DECODE
173 | 72: data <= 32'b00001100000000000000000001001011;
174 | // addi $s5, $s2, 0x800
175 | 73: data <= 32'b00100010010101010000100000000000;
176 | // j DIGITAL_TUBE_DISPLAY
177 | 74: data <= 32'b00001000000000000000000001111001;
178 | //DECODE:
179 | // addi $s2, $zero, 0xc0
180 | 75: data <= 32'b00100000000100100000000011000000;
181 | // beq $zero, $s5, DECODE_COMPLETE
182 | 76: data <= 32'b00010000000101010000000000101011;
183 | // addi $s2, $zero, 0xf9
184 | 77: data <= 32'b00100000000100100000000011111001;
185 | // addi $s6, $zero, 1
186 | 78: data <= 32'b00100000000101100000000000000001;
187 | // beq $s6, $s5, DECODE_COMPLETE
188 | 79: data <= 32'b00010010110101010000000000101000;
189 | // addi $s2, $zero, 0xa4
190 | 80: data <= 32'b00100000000100100000000010100100;
191 | // addi $s6, $zero, 2
192 | 81: data <= 32'b00100000000101100000000000000010;
193 | // beq $s6, $s5, DECODE_COMPLETE
194 | 82: data <= 32'b00010010110101010000000000100101;
195 | // addi $s2, $zero, 0xb0
196 | 83: data <= 32'b00100000000100100000000010110000;
197 | // addi $s6, $zero, 3
198 | 84: data <= 32'b00100000000101100000000000000011;
199 | // beq $s6, $s5, DECODE_COMPLETE
200 | 85: data <= 32'b00010010110101010000000000100010;
201 | // addi $s2, $zero, 0x99
202 | 86: data <= 32'b00100000000100100000000010011001;
203 | // addi $s6, $zero, 4
204 | 87: data <= 32'b00100000000101100000000000000100;
205 | // beq $s6, $s5, DECODE_COMPLETE
206 | 88: data <= 32'b00010010110101010000000000011111;
207 | // addi $s2, $zero, 0x92
208 | 89: data <= 32'b00100000000100100000000010010010;
209 | // addi $s6, $zero, 5
210 | 90: data <= 32'b00100000000101100000000000000101;
211 | // beq $s6, $s5, DECODE_COMPLETE
212 | 91: data <= 32'b00010010110101010000000000011100;
213 | // addi $s2, $zero, 0x82
214 | 92: data <= 32'b00100000000100100000000010000010;
215 | // addi $s6, $zero, 6
216 | 93: data <= 32'b00100000000101100000000000000110;
217 | // beq $s6, $s5, DECODE_COMPLETE
218 | 94: data <= 32'b00010010110101010000000000011001;
219 | // addi $s2, $zero, 0xf8
220 | 95: data <= 32'b00100000000100100000000011111000;
221 | // addi $s6, $zero, 7
222 | 96: data <= 32'b00100000000101100000000000000111;
223 | // beq $s6, $s5, DECODE_COMPLETE
224 | 97: data <= 32'b00010010110101010000000000010110;
225 | // addi $s2, $zero, 0x80
226 | 98: data <= 32'b00100000000100100000000010000000;
227 | // addi $s6, $zero, 8
228 | 99: data <= 32'b00100000000101100000000000001000;
229 | // beq $s6, $s5, DECODE_COMPLETE
230 | 100: data <= 32'b00010010110101010000000000010011;
231 | // addi $s2, $zero, 0x90
232 | 101: data <= 32'b00100000000100100000000010010000;
233 | // addi $s6, $zero, 9
234 | 102: data <= 32'b00100000000101100000000000001001;
235 | // beq $s6, $s5, DECODE_COMPLETE
236 | 103: data <= 32'b00010010110101010000000000010000;
237 | // addi $s2, $zero, 0x88
238 | 104: data <= 32'b00100000000100100000000010001000;
239 | // addi $s6, $zero, 0x0a
240 | 105: data <= 32'b00100000000101100000000000001010;
241 | // beq $s6, $s5, DECODE_COMPLETE
242 | 106: data <= 32'b00010010110101010000000000001101;
243 | // addi $s2, $zero, 0x83
244 | 107: data <= 32'b00100000000100100000000010000011;
245 | // addi $s6, $zero, 0x0b
246 | 108: data <= 32'b00100000000101100000000000001011;
247 | // beq $s6, $s5, DECODE_COMPLETE
248 | 109: data <= 32'b00010010110101010000000000001010;
249 | // addi $s2, $zero, 0xc6
250 | 110: data <= 32'b00100000000100100000000011000110;
251 | // addi $s6, $zero, 0x0c
252 | 111: data <= 32'b00100000000101100000000000001100;
253 | // beq $s6, $s5, DECODE_COMPLETE
254 | 112: data <= 32'b00010010110101010000000000000111;
255 | // addi $s2, $zero, 0xa1
256 | 113: data <= 32'b00100000000100100000000010100001;
257 | // addi $s6, $zero, 0x0d
258 | 114: data <= 32'b00100000000101100000000000001101;
259 | // beq $s6, $s5, DECODE_COMPLETE
260 | 115: data <= 32'b00010010110101010000000000000100;
261 | // addi $s2, $zero, 0x86
262 | 116: data <= 32'b00100000000100100000000010000110;
263 | // addi $s6, $zero, 0x0e
264 | 117: data <= 32'b00100000000101100000000000001110;
265 | // beq $s6, $s5, DECODE_COMPLETE
266 | 118: data <= 32'b00010010110101010000000000000001;
267 | // addi $s2, $zero, 0x8e
268 | 119: data <= 32'b00100000000100100000000010001110;
269 | //DECODE_COMPLETE:
270 | // jr $ra
271 | 120: data <= 32'b00000011111000000000000000001000;
272 | //DIGITAL_TUBE_DISPLAY:
273 | // sw $s5, 20($s0)
274 | 121: data <= 32'b10101110000101010000000000010100;
275 | // lw $t3, 8($s0)
276 | 122: data <= 32'b10001110000010110000000000001000;
277 | // addi $t4, $zero, 2
278 | 123: data <= 32'b00100000000011000000000000000010;
279 | // or $t3, $t3, $t4
280 | 124: data <= 32'b00000001011011000101100000100101;
281 | // sw $t3, 8($s0)
282 | 125: data <= 32'b10101110000010110000000000001000;
283 | // addi $26, $26, -4
284 | 126: data <= 32'b00100011010110101111111111111100;
285 | // jr $26
286 | 127: data <= 32'b00000011010000000000000000001000;
287 | //EXCEPT:
288 | // nop
289 | //128: data <= 32'b00000000000000000000000000000000;
290 | default: data <= 32'h8000_0000;
291 | endcase
292 | endmodule
293 |
--------------------------------------------------------------------------------
/src/Pipeline_CPU/ROM_tb.v:
--------------------------------------------------------------------------------
1 | `timescale 1ns/1ps
2 |
3 | module ROM (addr,data);
4 | input [31:0] addr;
5 | output [31:0] data;
6 | reg [31:0] data;
7 | localparam ROM_size = 32;
8 | reg [31:0] ROM_data[ROM_size-1:0];
9 |
10 | always@(*)
11 | case(addr[7:2]) //Address Must Be Word Aligned.
12 | // j INIT
13 | 0: data <= 32'b00001000000000000000000000000011;
14 | // j INTER
15 | 1: data <= 32'b00001000000000000000000000101000;
16 | // j EXCEPT
17 | 2: data <= 32'b00001000000000000000000000101001;
18 | //INIT:
19 | // addi $t0, $zero, 0x0014
20 | 3: data <= 32'b00100000000010000000000000010100;
21 | // jr $t0
22 | 4: data <= 32'b00000001000000000000000000001000;
23 | // lui $s0, 0x4000
24 | 5: data <= 32'b00111100000100000100000000000000;
25 | // sw $t0, 32($s0)
26 | 6: data <= 32'b10101110000010000000000000100000;
27 | //UART_START:
28 | // addi $s1, $zero, -1
29 | 7: data <= 32'b00100000000100011111111111111111;
30 | //UART_LOOP:
31 | // lw $t0, 32($s0)
32 | 8: data <= 32'b10001110000010000000000000100000;
33 | // andi $t0, $t0, 0x08
34 | 9: data <= 32'b00110001000010000000000000001000;
35 | // beq $t0, $zero, UART_LOOP
36 | 10: data <= 32'b00010001000000001111111111111101;
37 | // lw $v1, 28($s0)
38 | 11: data <= 32'b10001110000000110000000000011100;
39 | // beq $v1, $zero, UART_LOOP
40 | 12: data <= 32'b00010000011000001111111111111011;
41 | // beq $s1, $zero, LOAD_2
42 | 13: data <= 32'b00010010001000000000000000000011;
43 | // addi $s4, $v1, 0
44 | 14: data <= 32'b00100000011101000000000000000000;
45 | // addi $s1, $s1, 1
46 | 15: data <= 32'b00100010001100010000000000000001;
47 | // j UART_LOOP
48 | 16: data <= 32'b00001000000000000000000000001000;
49 | //LOAD_2:
50 | // addi $s3, $v1, 0
51 | 17: data <= 32'b00100000011100110000000000000000;
52 | // addi $v0, $s4, 0
53 | 18: data <= 32'b00100010100000100000000000000000;
54 | //GCD:
55 | // beq $v0, $zero, ANS1
56 | 19: data <= 32'b00010000010000000000000000001000;
57 | // beq $v1, $zero, ANS2
58 | 20: data <= 32'b00010000011000000000000000001001;
59 | // sub $t3, $v0, $v1
60 | 21: data <= 32'b00000000010000110101100000100010;
61 | // bgtz $t3, LOOP1
62 | 22: data <= 32'b00011101011000000000000000000001;
63 | // bltz $t3, LOOP2
64 | 23: data <= 32'b00000101011000000000000000000010;
65 | //LOOP1:
66 | // sub $v0, $v0, $v1
67 | 24: data <= 32'b00000000010000110001000000100010;
68 | // j GCD
69 | 25: data <= 32'b00001000000000000000000000010011;
70 | //LOOP2:
71 | // sub $v1, $v1, $v0
72 | 26: data <= 32'b00000000011000100001100000100010;
73 | // j GCD
74 | 27: data <= 32'b00001000000000000000000000010011;
75 | //ANS1:
76 | // add $a0, $v1, $zero
77 | 28: data <= 32'b00000000011000000010000000100000;
78 | // j RESULT_DISPLAY
79 | 29: data <= 32'b00001000000000000000000000011111;
80 | //ANS2:
81 | // add $a0, $v0, $zero
82 | 30: data <= 32'b00000000010000000010000000100000;
83 | //RESULT_DISPLAY:
84 | // sw $a0, 12($s0)
85 | 31: data <= 32'b10101110000001000000000000001100;
86 | //UART_SEND_BACK:
87 | // lw $t0, 32($s0)
88 | 32: data <= 32'b10001110000010000000000000100000;
89 | // andi $t0, $t0, 0x10
90 | 33: data <= 32'b00110001000010000000000000010000;
91 | // bne $t0, $zero, UART_SEND_BACK
92 | 34: data <= 32'b00010101000000001111111111111101;
93 | // sw $a0, 24($s0)
94 | 35: data <= 32'b10101110000001000000000000011000;
95 | //AA:
96 | // lw $t0, 32($s0)
97 | 36: data <= 32'b10001110000010000000000000100000;
98 | // andi $t0, $t0, 0x04
99 | 37: data <= 32'b00110001000010000000000000000100;
100 | // beq $t0, $zero, AA
101 | 38: data <= 32'b00010001000000001111111111111101;
102 | // j UART_START
103 | 39: data <= 32'b00001000000000000000000000000111;
104 | //INTER:
105 | // nop
106 | 40: data <= 32'b00000000000000000000000000000000;
107 | //EXCEPT:
108 | // nop
109 | 41: data <= 32'b00000000000000000000000000000000;
110 | default: data <= 32'h8000_0000;
111 | endcase
112 | endmodule
113 |
--------------------------------------------------------------------------------
/src/Pipeline_CPU/RegFile.v:
--------------------------------------------------------------------------------
1 | `timescale 1ns/1ps
2 |
3 | module RegFile (reset,clk,addr1,data1,addr2,data2,wr,addr3,data3);
4 | input reset,clk;
5 | input wr;
6 | input [4:0] addr1,addr2,addr3;
7 | output [31:0] data1,data2;
8 | input [31:0] data3;
9 |
10 | reg [31:0] RF_data[31:0];
11 |
12 | assign data1 = RF_data[addr1];
13 | assign data2 = RF_data[addr2];
14 |
15 | always@(negedge reset or negedge clk) begin
16 | if(~reset) begin
17 | RF_data[0]<=32'b0;
18 | RF_data[1]<=32'b0;
19 | RF_data[2]<=32'b0;
20 | RF_data[3]<=32'b0;
21 | RF_data[4]<=32'b0;
22 | RF_data[5]<=32'b0;
23 | RF_data[6]<=32'b0;
24 | RF_data[7]<=32'b0;
25 | RF_data[8]<=32'b0;
26 | RF_data[9]<=32'b0;
27 | RF_data[10]<=32'b0;
28 | RF_data[11]<=32'b0;
29 | RF_data[12]<=32'b0;
30 | RF_data[13]<=32'b0;
31 | RF_data[14]<=32'b0;
32 | RF_data[15]<=32'b0;
33 | RF_data[16]<=32'b0;
34 | RF_data[17]<=32'b0;
35 | RF_data[18]<=32'b0;
36 | RF_data[19]<=32'b0;
37 | RF_data[20]<=32'b0;
38 | RF_data[21]<=32'b0;
39 | RF_data[22]<=32'b0;
40 | RF_data[23]<=32'b0;
41 | RF_data[24]<=32'b0;
42 | RF_data[25]<=32'b0;
43 | RF_data[26]<=32'b0;
44 | RF_data[27]<=32'b0;
45 | RF_data[28]<=32'b0;
46 | RF_data[29]<=32'b0;
47 | RF_data[30]<=32'b0;
48 | RF_data[31]<=32'b0;
49 | end
50 | else begin
51 | //$0 MUST be all zeros
52 | if(wr && (|addr3))
53 | RF_data[addr3] <= data3;
54 | end
55 | end
56 | endmodule
57 |
--------------------------------------------------------------------------------
/src/Pipeline_CPU/UART.v:
--------------------------------------------------------------------------------
1 | module UART_Receiver(uart_rx, sysclk, rx_data, rx_status, rx_LoadFinish, reset);
2 | input uart_rx, rx_LoadFinish, sysclk, reset;
3 | output reg [7:0] rx_data;
4 | output reg rx_status;
5 |
6 | reg [3:0] cnt_catch; // Sampling count
7 | reg [4:0] cnt_clk; // Count 153600Hz Clock to generate 9600Hz
8 | reg status; // Status of Receiver, 0 - idle & start bit, 1- busy
9 | reg [8:0] brcnt16; // Count sysclk to generate 153600Hz
10 |
11 | always @(posedge sysclk or negedge reset)
12 | begin
13 | if(~reset) begin
14 | brcnt16 <= 9'd0;
15 | cnt_catch <= 4'd0;
16 | cnt_clk <= 5'd0;
17 | status <= 0;
18 | rx_status <= 0;
19 | rx_data <= 8'd0;
20 | end
21 | else begin
22 | if(~status) begin
23 | if(rx_LoadFinish)
24 | rx_status <= 0;
25 | if(~uart_rx) begin
26 | if(cnt_clk==5'd8) begin
27 | cnt_clk <= 5'd0;
28 | status <= 1;
29 | brcnt16 <= 9'd0;
30 | end
31 | else begin
32 | if (brcnt16 == 9'd325) begin
33 | brcnt16 <= 9'd0;
34 | cnt_clk <= cnt_clk + 1;
35 | end
36 | else
37 | brcnt16 <= brcnt16 + 1;
38 | end
39 | end
40 | end
41 | else begin
42 | if(cnt_catch==4'd9) begin
43 | cnt_catch <= 4'd0;
44 | status <= 0;
45 | brcnt16 <= 9'd0;
46 | cnt_clk <= 5'd0;
47 | rx_status <= 1;
48 | end
49 | else begin
50 | if(cnt_clk == 5'd16) begin
51 | cnt_clk <= 5'd0;
52 | brcnt16 <= 9'd0;
53 | cnt_catch <= cnt_catch+1;
54 | if (cnt_catch < 4'd8)
55 | rx_data[cnt_catch]<=uart_rx;
56 | end
57 | else begin
58 | if(brcnt16 == 9'd325) begin
59 | brcnt16 <= 9'd0;
60 | cnt_clk <= cnt_clk + 1;
61 | end
62 | else
63 | brcnt16 <= brcnt16 + 1;
64 | end
65 | end
66 | end
67 | end
68 | end
69 |
70 | endmodule
71 |
72 |
73 | module UART_Sender(tx_data, tx_en, sysclk, tx_status, uart_tx, reset);
74 |
75 | input [7:0] tx_data;
76 | input tx_en, sysclk, reset;
77 | output reg tx_status, uart_tx;
78 |
79 | reg [3:0] cnt; // Count bit
80 | reg [9:0] tmp_data; // Buffer to save data temporily
81 | reg [12:0] brcnt; // Count sysclk to generate 9600Hz Clock
82 |
83 | always @(posedge sysclk or negedge reset)
84 | begin
85 | if (~reset) begin
86 | tx_status <= 1'b1;
87 | uart_tx <= 1'b1;
88 | cnt <= 4'd0;
89 | end
90 | else begin
91 | if(tx_status) begin
92 | uart_tx <= 1'b1;
93 | cnt <= 4'd0;
94 | brcnt <= 13'd5208;
95 | if(tx_en) begin
96 | tmp_data[0] <= 1'b0;
97 | tmp_data[8:1] <= tx_data;
98 | tmp_data[9] <= 1'b1;
99 | tx_status <= 1'b0;
100 | end
101 | end
102 | else begin
103 | if(brcnt == 13'd5208) begin
104 | brcnt <= 13'd0;
105 | if (cnt==4'd10) begin
106 | cnt <= 4'd0;
107 | tx_status <= 1'b1;
108 | end
109 | else
110 | uart_tx <= tmp_data[cnt];
111 | cnt <= cnt + 1;
112 | end
113 | else
114 | brcnt <= brcnt + 12'd1;
115 | end
116 | end
117 | end
118 |
119 | endmodule
120 |
121 | module UART(reset, sysclk, clk, rd, wr, addr, wdata, rdata, UART_RX, UART_TX, RX_IRQ, TX_IRQ);
122 | input sysclk, reset, clk, rd, wr, UART_RX;
123 | input [31:0] addr, wdata;
124 | output UART_TX, RX_IRQ, TX_IRQ;
125 | output reg [31:0] rdata;
126 | wire rx_status, tx_status, tx_over;
127 | wire[7:0] rx_data;
128 | reg[7:0] UART_RXD, UART_TXD;
129 | reg[4:0] UART_CON;
130 | reg tx_en;
131 |
132 | // Read Data
133 | always @(*) begin
134 | if(rd) begin
135 | case(addr)
136 | 32'h4000_0018: rdata = {24'd0, UART_TXD};
137 | 32'h4000_001c: rdata = {24'd0, UART_RXD};
138 | 32'h4000_0020: rdata = {27'd0, UART_CON};
139 | default: rdata = 32'd0;
140 | endcase
141 | end
142 | else
143 | rdata = 32'd0;
144 | end
145 |
146 | always @(posedge clk or negedge reset) begin
147 | if(~reset) begin
148 | UART_RXD <= 8'd0;
149 | UART_TXD <= 8'd0;
150 | UART_CON <= 5'd0;
151 | tx_en <= 0;
152 | end
153 | else begin
154 |
155 | // After receive the data
156 | if(rx_status) begin
157 | UART_RXD <= rx_data;
158 | UART_CON[3] <= 1'b1;
159 | end
160 |
161 | // After send the data
162 | if(UART_CON[4] && tx_status) begin
163 | UART_CON[2] <= 1'b1;
164 | end
165 | UART_CON[4] <= ~tx_status;
166 |
167 | // After read UART_CON
168 | if(rd && (addr == 32'h4000_0020)) begin
169 | UART_CON[2] <= 1'b0;
170 | UART_CON[3] <= 1'b0;
171 | end
172 |
173 | // Write Data
174 | if(wr) begin
175 | case(addr)
176 | 32'h4000_0018: begin
177 | UART_TXD <= wdata[7:0];
178 | tx_en <= 1;
179 | end
180 | 32'h4000_0020: UART_CON[1:0] <= wdata[1:0];
181 | default: ;
182 | endcase
183 | end
184 | if(tx_en)
185 | tx_en <= 0;
186 | end
187 | end
188 |
189 | // Set Interrupt
190 | assign RX_IRQ = UART_CON[1] && UART_CON[3];
191 | assign TX_IRQ = UART_CON[0] && UART_CON[2];
192 |
193 | UART_Receiver UART_Receiver_1(.uart_rx(UART_RX), .sysclk(sysclk), .rx_data(rx_data), .rx_status(rx_status), .rx_LoadFinish(UART_CON[3]), .reset(reset));
194 |
195 | UART_Sender UART_Sender_1(.tx_data(UART_TXD), .tx_en(tx_en), .sysclk(sysclk), .tx_status(tx_status), .uart_tx(UART_TX), .reset(reset));
196 |
197 | endmodule
--------------------------------------------------------------------------------
/src/Single_Cycle_CPU/ALU.v:
--------------------------------------------------------------------------------
1 | module ALU(A, B, ALUFun, Sign, Z);
2 | input Sign;
3 | input [5:0] ALUFun;
4 | input [31:0] A, B;
5 | output [31:0] Z;
6 | wire zero,neg;
7 | wire [31:0] S0, S1, S2, S3;
8 |
9 | AddSub AddSub(.A(A), .B(B), .ALUFun(ALUFun), .Sign(Sign), .Z(zero), .N(neg), .S(S0));
10 | Cmp Cmp(.ALUFun(ALUFun), .Sign(Sign), .Z(zero), .N(neg), .S(S1));
11 | Logic Logic(.A(A), .B(B), .ALUFun(ALUFun), .S(S2));
12 | Shift Shift(.A(A), .B(B), .ALUFun(ALUFun), .S(S3));
13 |
14 | assign Z =
15 | (ALUFun[5:4] == 2'b00)? S0:
16 | (ALUFun[5:4] == 2'b10)? S3:
17 | (ALUFun[5:4] == 2'b01)? S2: S1;
18 |
19 | endmodule
20 |
21 |
22 |
23 | module AddSub(A, B, ALUFun, Sign, Z, N, S);
24 | input Sign;
25 | input [5:0] ALUFun;
26 | input [31:0] A, B;
27 | output Z, N;
28 | output [32:0] S;
29 |
30 | assign Z =
31 | (ALUFun[3] && |A)? 0:
32 | (~ALUFun[3] && |S)? 0: 1;
33 | assign S =
34 | (ALUFun[0])? ({1'b0, A} - {1'b0, B}): ({1'b0, A} + {1'b0, B});
35 | assign N =
36 | (ALUFun[3] && Sign && A[31])? 1:
37 | (~ALUFun[3] && Sign && S[31])? 1:
38 | (~ALUFun[3] && ~Sign && S[32])? 1: 0;
39 |
40 | endmodule
41 |
42 |
43 |
44 | module Cmp(ALUFun, Sign, Z, N, S);
45 | input Sign, Z, N;
46 | input [5:0] ALUFun;
47 | output [31:0] S;
48 |
49 | assign S[0] =
50 | (ALUFun[3:1] == 3'b001)? Z:
51 | (ALUFun[3:1] == 3'b000)? ~Z:
52 | (ALUFun[3:1] == 3'b010)? N:
53 | (ALUFun[3:1] == 3'b110)? (N || Z):
54 | (ALUFun[3:1] == 3'b101)? N: (~N && ~Z);
55 | assign S[31:1]=0;
56 |
57 | endmodule
58 |
59 |
60 |
61 | module Logic(A, B, ALUFun, S);
62 | input [5:0] ALUFun;
63 | input [31:0] A, B;
64 | output [31:0] S;
65 |
66 | assign S =
67 | (ALUFun[3:0] == 4'b0001)? ~(A | B):
68 | (ALUFun[3:0] == 4'b1110)? (A | B):
69 | (ALUFun[3:0] == 4'b1000)? (A & B):
70 | (ALUFun[3:0] == 4'b0110)? (A ^ B): A;
71 |
72 | endmodule
73 |
74 |
75 |
76 | module Shift(A, B, ALUFun, S);
77 | input [5:0] ALUFun;
78 | input [31:0] A, B;
79 | output [31:0] S;
80 |
81 | assign S =
82 | (ALUFun[1:0] == 2'b01 || (ALUFun[1:0] == 2'b11 && B[31] == 0))? B >> A[4:0]:
83 | (ALUFun[1:0] == 2'b11 && B[31] == 1)? ({32'hFFFFFFFF, B} >> A[4:0]):
84 | (ALUFun[1:0] == 2'b00)? B << A[4:0]: 0;
85 |
86 | endmodule
--------------------------------------------------------------------------------
/src/Single_Cycle_CPU/CPU.v:
--------------------------------------------------------------------------------
1 | module CPU(reset, sysclk, UART_RX, UART_TX, switch, led, digi_1, digi_2, digi_3, digi_4);
2 | input reset, sysclk, UART_RX;
3 | input [7:0] switch;
4 | output UART_TX;
5 | output [7:0] led;
6 | output [6:0] digi_1, digi_2, digi_3, digi_4;
7 |
8 | // Generate CPU Clock
9 | wire clk;
10 | CPU_clk CPU_clk_1(.sysclk(sysclk), .reset(reset), .clk(clk));
11 |
12 | // Instruction Fetch
13 | reg [31:0] PC;
14 | wire [31:0] Instruct;
15 | ROM ROM_1(.addr(PC), .data(Instruct));
16 |
17 | // Instruction Decode
18 | wire [2:0] PCSrc;
19 | wire RegWrite, MemRead, MemWrite, ALUSrc1, ALUSrc2, EXTOp, LUOp, Sign, IRQ;
20 | wire [1:0] RegDst, MemToReg;
21 | wire [5:0] ALUFun;
22 |
23 | Control Control_1(.Instruct(Instruct), .IRQ(IRQ), .PC31(PC[31]), .PCSrc(PCSrc), .RegWr(RegWrite), .RegDst(RegDst), .MemRd(MemRead), .MemWr(MemWrite), .MemToReg(MemToReg), .ALUSrc1(ALUSrc1), .ALUSrc2(ALUSrc2), .EXTOp(EXTOp), .LUOp(LUOp), .ALUFun(ALUFun), .Sign(Sign));
24 |
25 | // Instruction Decode (Register File) (& Write Back)
26 | wire [31:0] DataBusA, DataBusB, DataBusC;
27 | wire [4:0] Rs, Rt, Rd, AddrC;
28 | parameter Xp = 5'd26;
29 | parameter Ra = 5'd31;
30 | assign Rs = Instruct[25:21];
31 | assign Rt = Instruct[20:16];
32 | assign Rd = Instruct[15:11];
33 | assign AddrC = (RegDst == 2'd0) ? Rd :
34 | (RegDst == 2'd1) ? Rt :
35 | (RegDst == 2'd2) ? Ra : Xp;
36 | RegFile RegFile_1(.reset(reset), .clk(clk), .addr1(Rs), .data1(DataBusA), .addr2(Rt), .data2(DataBusB), .wr(RegWrite), .addr3(AddrC), .data3(DataBusC));
37 |
38 | // Immediate Extension
39 | wire [31:0] EXTOut;
40 | assign EXTOut = {EXTOp ? {16{Instruct[15]}} : 16'h0000, Instruct[15:0]};
41 |
42 | // Load Upper Immediate
43 | wire [31:0] LUOut;
44 | assign LUOut = LUOp ? {Instruct[15:0], 16'd0} : EXTOut;
45 |
46 | // Execution
47 | wire [31:0] ALU_A, ALU_B, ALUOut;
48 | assign ALU_A = ALUSrc1 ? {27'd0, Instruct[10:6]} : DataBusA;
49 | assign ALU_B = ALUSrc2 ? LUOut : DataBusB;
50 | ALU ALU_1(.A(ALU_A), .B(ALU_B), .ALUFun(ALUFun), .Sign(Sign), .Z(ALUOut));
51 |
52 | // Memory Read
53 | wire[31:0] memRdData;
54 | DataMem DataMem_1(.reset(reset), .clk(clk), .rd(MemRead), .wr(MemWrite), .addr(ALUOut), .wdata(DataBusB), .rdata(memRdData));
55 |
56 | // Write Back
57 | wire [31:0] ReadData, periRdData, uartRdData, PC_add_4;
58 | assign ReadData = memRdData | periRdData | uartRdData;
59 | assign DataBusC = (MemToReg == 2'd0) ? ALUOut :
60 | (MemToReg == 2'd1) ? ReadData : PC_add_4;
61 |
62 | // PC Register
63 | wire [31:0] PC_add, JT, ConBA;
64 | parameter ILLOP = 32'h8000_0004;
65 | parameter XADR = 32'h8000_0008;
66 | assign PC_add = PC + 32'd4;
67 | assign PC_add_4 = {PC[31], PC_add[30:0]};
68 | assign JT = {PC_add_4[31:28], Instruct[25:0], 2'b00};
69 | assign ConBA = PC_add_4 + {LUOut[29:0], 2'b00};
70 | always @(negedge reset or posedge clk) begin
71 | if(~reset)
72 | PC <= 32'h8000_0000;
73 | else begin
74 | case(PCSrc)
75 | 3'd0: PC <= PC_add_4;
76 | 3'd1: PC <= (ALUOut[0]) ? ConBA : (PC + 4);
77 | 3'd2: PC <= JT;
78 | 3'd3: PC <= DataBusA;
79 | 3'd4: PC <= ILLOP;
80 | 3'd5: PC <= XADR;
81 | default: PC <= 32'h8000_0000;
82 | endcase
83 | end
84 | end
85 |
86 | // Peripheral
87 | wire per_irq, rx_irq, tx_irq;
88 | wire [11:0] digi;
89 | Peripheral Peripheral_1(.reset(reset), .clk(clk), .rd(MemRead), .wr(MemWrite), .addr(ALUOut), .wdata(DataBusB), .rdata(periRdData), .led(led), .switch(switch), .digi(digi), .irqout(per_irq));
90 | Digitube_scan Digitube_scan(.digi_in(digi), .digi_out1(digi_1), .digi_out2(digi_2), .digi_out3(digi_3), .digi_out4(digi_4));
91 |
92 | UART UART_1(.reset(reset), .sysclk(sysclk), .clk(clk), .rd(MemRead), .wr(MemWrite), .addr(ALUOut), .wdata(DataBusB), .rdata(uartRdData), .UART_RX(UART_RX), .UART_TX(UART_TX), .RX_IRQ(rx_irq), .TX_IRQ(tx_irq));
93 |
94 | // Interruption
95 | assign IRQ = (~PC[31]) & (per_irq | rx_irq | tx_irq);
96 |
97 | endmodule
--------------------------------------------------------------------------------
/src/Single_Cycle_CPU/CPU_clk.v:
--------------------------------------------------------------------------------
1 | module CPU_clk (sysclk, reset, clk);
2 | input sysclk, reset;
3 | output reg clk;
4 |
5 | // Frequency Divider
6 | always @(posedge sysclk or negedge reset) begin
7 | if(~reset)
8 | clk <= 0;
9 | else
10 | clk <= ~clk;
11 | end
12 |
13 | endmodule
--------------------------------------------------------------------------------
/src/Single_Cycle_CPU/CPU_tb.v:
--------------------------------------------------------------------------------
1 | `timescale 1ns/1ns
2 |
3 | module baudrate_generator(sysclk, reset, brclk, brclk16);
4 | input sysclk,reset;
5 | output reg brclk, brclk16;
6 | reg [11:0] cnt;
7 | reg [7:0] cnt16;
8 |
9 | always @(posedge sysclk or negedge reset)
10 | begin
11 | if(~reset) begin
12 | cnt <= 12'd0;
13 | cnt16 <= 8'd0;
14 | brclk <= 1;
15 | brclk16 <= 1;
16 | end
17 | else begin
18 | if(cnt16 == 8'd162) begin
19 | cnt16 <= 8'd0;
20 | brclk16 <= ~brclk16;
21 | end
22 | else
23 | cnt16 <= cnt16 + 8'd1;
24 | if(cnt == 12'd2603) begin
25 | cnt <= 12'd0;
26 | brclk <= ~brclk;
27 | end
28 | else
29 | cnt <= cnt + 12'd1;
30 | end
31 | end
32 |
33 | endmodule
34 |
35 |
36 |
37 | module CPU_tb;
38 | reg reset, sysclk;
39 | reg [7:0] switch;
40 | reg [36:0] tmprx;
41 | wire UART_RX, UART_TX, brclk9600, brclk153600;
42 | wire [7:0] led;
43 | wire [6:0] digi_1;
44 | wire [6:0] digi_2;
45 | wire [6:0] digi_3;
46 | wire [6:0] digi_4;
47 |
48 | initial begin
49 | reset <= 0;
50 | sysclk <= 0;
51 | reset <= 0;
52 | switch <= 8'b01001010;
53 | tmprx <= 37'b11_0_0000_0101_1_0_0001_1001_1111_1111_1111_1111;
54 | end
55 |
56 | initial fork
57 | #13 reset <= 1;
58 | forever #10 sysclk = ~sysclk;
59 | join
60 |
61 | baudrate_generator baudrate_generator_1(.sysclk(sysclk), .reset(reset), .brclk(brclk9600), .brclk16(brclk153600));
62 |
63 | always @(posedge brclk9600)
64 | begin
65 | tmprx <= tmprx<<1;
66 | end
67 |
68 | assign UART_RX = tmprx[36];
69 |
70 | CPU CPU_1(reset, sysclk, UART_RX, UART_TX, switch, led, digi_1, digi_2, digi_3, digi_4);
71 |
72 | endmodule
73 |
--------------------------------------------------------------------------------
/src/Single_Cycle_CPU/Control.v:
--------------------------------------------------------------------------------
1 | module Control(Instruct, IRQ, PC31, PCSrc, RegWr, RegDst, MemRd, MemWr, MemToReg, ALUSrc1, ALUSrc2, EXTOp, LUOp, ALUFun, Sign);
2 | input [31:0] Instruct;
3 | input IRQ, PC31;
4 | output reg [2:0] PCSrc;
5 | output reg RegWr;
6 | output reg [1:0] RegDst;
7 | output reg MemRd;
8 | output reg MemWr;
9 | output reg [1:0] MemToReg;
10 | output reg ALUSrc1;
11 | output reg ALUSrc2;
12 | output reg EXTOp;
13 | output reg LUOp;
14 | output reg [5:0] ALUFun;
15 | output reg Sign;
16 |
17 | always @(*) begin
18 |
19 | /* Default Set
20 | PCSrc = 3'd0;
21 | RegWr = 0;
22 | RegDst = 2'd0;
23 | MemRd = 0;
24 | MemWr = 0;
25 | MemToReg = 2'd0;
26 | ALUSrc1 = 0;
27 | ALUSrc2 = 0;
28 | ALUFun = 6'b000000;
29 | Sign = 1;
30 | EXTOp = 1;
31 | LUOp = 0;
32 | */
33 |
34 | if(~IRQ) begin
35 | case(Instruct[31:26])
36 | 6'b10_0011: begin //lw 0x23
37 | PCSrc = 3'd0;
38 | RegWr = 1;
39 | RegDst = 2'd1;
40 | MemRd = 1;
41 | MemWr = 0;
42 | MemToReg = 2'd1;
43 | ALUSrc1 = 0;
44 | ALUSrc2 = 1;
45 | ALUFun = 6'b000000;
46 | Sign = 1;
47 | EXTOp = 1;
48 | LUOp = 0;
49 | end
50 | 6'b10_1011: begin //sw 0x2b
51 | PCSrc = 3'd0;
52 | RegWr = 0;
53 | RegDst = 2'd0;
54 | MemRd = 0;
55 | MemWr = 1;
56 | MemToReg = 2'd0;
57 | ALUSrc1 = 0;
58 | ALUSrc2 = 1;
59 | ALUFun = 6'b000000;
60 | Sign = 1;
61 | EXTOp = 1;
62 | LUOp = 0;
63 | end
64 | 6'b00_1111: begin //lui 0x0f
65 | PCSrc = 3'd0;
66 | RegWr = 1;
67 | RegDst = 2'd1;
68 | MemRd = 0;
69 | MemWr = 1;
70 | MemToReg = 2'd0;
71 | ALUSrc1 = 0;
72 | ALUSrc2 = 1;
73 | ALUFun = 6'b011110;
74 | Sign = 1;
75 | EXTOp = 1;
76 | LUOp = 1;
77 | end
78 | 6'b00_1000: begin //addi 0x08
79 | PCSrc = 3'd0;
80 | RegWr = 1;
81 | RegDst = 2'd1;
82 | MemRd = 0;
83 | MemWr = 0;
84 | MemToReg = 2'd0;
85 | ALUSrc1 = 0;
86 | ALUSrc2 = 1;
87 | ALUFun = 6'b000000;
88 | Sign = 1;
89 | EXTOp = 1;
90 | LUOp = 0;
91 | end
92 | 6'b00_1001: begin //addiu 0x09
93 | PCSrc = 3'd0;
94 | RegWr = 1;
95 | RegDst = 2'd1;
96 | MemRd = 0;
97 | MemWr = 0;
98 | MemToReg = 2'd0;
99 | ALUSrc1 = 0;
100 | ALUSrc2 = 1;
101 | ALUFun = 6'b000000;
102 | Sign = 1;
103 | EXTOp = 1;
104 | LUOp = 0;
105 | end
106 | 6'b00_1100: begin //andi 0x0c
107 | PCSrc = 3'd0;
108 | RegWr = 1;
109 | RegDst = 2'd1;
110 | MemRd = 0;
111 | MemWr = 0;
112 | MemToReg = 2'd0;
113 | ALUSrc1 = 0;
114 | ALUSrc2 = 1;
115 | ALUFun = 6'b011000;
116 | Sign = 1;
117 | EXTOp = 0;
118 | LUOp = 0;
119 | end
120 | /*
121 | 6'b00_1101: begin //ori 0x0d
122 | PCSrc = 3'd0;
123 | RegWr = 1;
124 | RegDst = 2'd1;
125 | MemRd = 0;
126 | MemWr = 0;
127 | MemToReg = 2'd0;
128 | ALUSrc1 = 0;
129 | ALUSrc2 = 1;
130 | ALUFun = 6'b011110;
131 | Sign = 1;
132 | EXTOp = 0;
133 | LUOp = 0;
134 | end
135 | */
136 | 6'b00_1010: begin //slti 0x0a
137 | PCSrc = 3'd0;
138 | RegWr = 1;
139 | RegDst = 2'd1;
140 | MemRd = 0;
141 | MemWr = 0;
142 | MemToReg = 2'd0;
143 | ALUSrc1 = 0;
144 | ALUSrc2 = 1;
145 | ALUFun = 6'b110101;
146 | Sign = 1;
147 | EXTOp = 1;
148 | LUOp = 0;
149 | end
150 | 6'b00_1011: begin //sltiu 0x0b
151 | PCSrc = 3'd0;
152 | RegWr = 1;
153 | RegDst = 2'd1;
154 | MemRd = 0;
155 | MemWr = 0;
156 | MemToReg = 2'd0;
157 | ALUSrc1 = 0;
158 | ALUSrc2 = 1;
159 | ALUFun = 6'b110101;
160 | Sign = 0;
161 | EXTOp = 1;
162 | LUOp = 0;
163 | end
164 | 6'b00_0100: begin //beq 0x04
165 | PCSrc = 3'd1;
166 | RegWr = 0;
167 | RegDst = 2'd0;
168 | MemRd = 0;
169 | MemWr = 0;
170 | MemToReg = 2'd0;
171 | ALUSrc1 = 0;
172 | ALUSrc2 = 0;
173 | ALUFun = 6'b110011;
174 | Sign = 1;
175 | EXTOp = 1;
176 | LUOp = 0;
177 | end
178 | 6'b00_0101: begin //bne 0x05
179 | PCSrc = 3'd1;
180 | RegWr = 0;
181 | RegDst = 2'd0;
182 | MemRd = 0;
183 | MemWr = 0;
184 | MemToReg = 2'd0;
185 | ALUSrc1 = 0;
186 | ALUSrc2 = 0;
187 | ALUFun = 6'b110001;
188 | Sign = 1;
189 | EXTOp = 1;
190 | LUOp = 0;
191 | end
192 | 6'b00_0110: begin //blez 0x06
193 | PCSrc = 3'd1;
194 | RegWr = 0;
195 | RegDst = 2'd0;
196 | MemRd = 0;
197 | MemWr = 0;
198 | MemToReg = 2'd0;
199 | ALUSrc1 = 0;
200 | ALUSrc2 = 0;
201 | ALUFun = 6'b111101;
202 | Sign = 1;
203 | EXTOp = 1;
204 | LUOp = 0;
205 | end
206 | 6'b00_0111: begin //bgtz 0x07
207 | PCSrc = 3'd1;
208 | RegWr = 0;
209 | RegDst = 2'd0;
210 | MemRd = 0;
211 | MemWr = 0;
212 | MemToReg = 2'd0;
213 | ALUSrc1 = 0;
214 | ALUSrc2 = 0;
215 | ALUFun = 6'b111111;
216 | Sign = 1;
217 | EXTOp = 1;
218 | LUOp = 0;
219 | end
220 | 6'b00_0001: begin //bltz 0x01
221 | PCSrc = 3'd1;
222 | RegWr = 0;
223 | RegDst = 2'd0;
224 | MemRd = 0;
225 | MemWr = 0;
226 | MemToReg = 2'd0;
227 | ALUSrc1 = 0;
228 | ALUSrc2 = 0;
229 | ALUFun = 6'b111011;
230 | Sign = 1;
231 | EXTOp = 1;
232 | LUOp = 0;
233 | end
234 | 6'b00_0010: begin //j 0x02
235 | PCSrc = 3'd2;
236 | RegWr = 0;
237 | RegDst = 2'd0;
238 | MemRd = 0;
239 | MemWr = 0;
240 | MemToReg = 2'd0;
241 | ALUSrc1 = 0;
242 | ALUSrc2 = 0;
243 | ALUFun = 6'b000000;
244 | Sign = 1;
245 | EXTOp = 1;
246 | LUOp = 0;
247 | end
248 | 6'b00_0011: begin //jal 0x03
249 | PCSrc = 3'd2;
250 | RegWr = 1;
251 | RegDst = 2'd2;
252 | MemRd = 0;
253 | MemWr = 0;
254 | MemToReg = 2'd2;
255 | ALUSrc1 = 0;
256 | ALUSrc2 = 0;
257 | ALUFun = 6'b000000;
258 | Sign = 1;
259 | EXTOp = 1;
260 | LUOp = 0;
261 | end
262 | 6'b00_0000: begin //R型 0x00
263 | case(Instruct[5:0])
264 | 6'b10_0000: begin //add 0x20
265 | PCSrc = 3'd0;
266 | RegWr = 1;
267 | RegDst = 2'd0;
268 | MemRd = 0;
269 | MemWr = 0;
270 | MemToReg = 2'd0;
271 | ALUSrc1 = 0;
272 | ALUSrc2 = 0;
273 | ALUFun = 6'b000000;
274 | Sign = 1;
275 | EXTOp = 1;
276 | LUOp = 0;
277 | end
278 | 6'b10_0001: begin //addu 0x21
279 | PCSrc = 3'd0;
280 | RegWr = 1;
281 | RegDst = 2'd0;
282 | MemRd = 0;
283 | MemWr = 0;
284 | MemToReg = 2'd0;
285 | ALUSrc1 = 0;
286 | ALUSrc2 = 0;
287 | ALUFun = 6'b000000;
288 | Sign = 1;
289 | EXTOp = 1;
290 | LUOp = 0;
291 | end
292 | 6'b10_0010: begin //sub 0x22
293 | PCSrc = 3'd0;
294 | RegWr = 1;
295 | RegDst = 2'd0;
296 | MemRd = 0;
297 | MemWr = 0;
298 | MemToReg = 2'd0;
299 | ALUSrc1 = 0;
300 | ALUSrc2 = 0;
301 | ALUFun = 6'b000001;
302 | Sign = 1;
303 | EXTOp = 1;
304 | LUOp = 0;
305 | end
306 | 6'b10_0011: begin //subu 0x23
307 | PCSrc = 3'd0;
308 | RegWr = 1;
309 | RegDst = 2'd0;
310 | MemRd = 0;
311 | MemWr = 0;
312 | MemToReg = 2'd0;
313 | ALUSrc1 = 0;
314 | ALUSrc2 = 0;
315 | ALUFun = 6'b000001;
316 | Sign = 1;
317 | EXTOp = 1;
318 | LUOp = 0;
319 | end
320 | 6'b10_0100: begin //and 0x24
321 | PCSrc = 3'd0;
322 | RegWr = 1;
323 | RegDst = 2'd0;
324 | MemRd = 0;
325 | MemWr = 0;
326 | MemToReg = 2'd0;
327 | ALUSrc1 = 0;
328 | ALUSrc2 = 0;
329 | ALUFun = 6'b011000;
330 | Sign = 1;
331 | EXTOp = 1;
332 | LUOp = 0;
333 | end
334 | 6'b10_0101: begin //or 0x25
335 | PCSrc = 3'd0;
336 | RegWr = 1;
337 | RegDst = 2'd0;
338 | MemRd = 0;
339 | MemWr = 0;
340 | MemToReg = 2'd0;
341 | ALUSrc1 = 0;
342 | ALUSrc2 = 0;
343 | ALUFun = 6'b011110;
344 | Sign = 1;
345 | EXTOp = 1;
346 | LUOp = 0;
347 | end
348 | 6'b10_0110: begin //xor 0x26
349 | PCSrc = 3'd0;
350 | RegWr = 1;
351 | RegDst = 2'd0;
352 | MemRd = 0;
353 | MemWr = 0;
354 | MemToReg = 2'd0;
355 | ALUSrc1 = 0;
356 | ALUSrc2 = 0;
357 | ALUFun = 6'b010110;
358 | Sign = 1;
359 | EXTOp = 1;
360 | LUOp = 0;
361 | end
362 | 6'b10_0111: begin //nor 0x27
363 | PCSrc = 3'd0;
364 | RegWr = 1;
365 | RegDst = 2'd0;
366 | MemRd = 0;
367 | MemWr = 0;
368 | MemToReg = 2'd0;
369 | ALUSrc1 = 0;
370 | ALUSrc2 = 0;
371 | ALUFun = 6'b010001;
372 | Sign = 1;
373 | EXTOp = 1;
374 | LUOp = 0;
375 | end
376 | 6'b00_0000: begin //sll 0x00
377 | PCSrc = 3'd0;
378 | RegWr = 1;
379 | RegDst = 2'd0;
380 | MemRd = 0;
381 | MemWr = 0;
382 | MemToReg = 2'd0;
383 | ALUSrc1 = 1;
384 | ALUSrc2 = 0;
385 | ALUFun = 6'b100000;
386 | Sign = 1;
387 | EXTOp = 1;
388 | LUOp = 0;
389 | end
390 | 6'b00_0010: begin //srl 0x02
391 | PCSrc = 3'd0;
392 | RegWr = 1;
393 | RegDst = 2'd0;
394 | MemRd = 0;
395 | MemWr = 0;
396 | MemToReg = 2'd0;
397 | ALUSrc1 = 1;
398 | ALUSrc2 = 0;
399 | ALUFun = 6'b100001;
400 | Sign = 1;
401 | EXTOp = 1;
402 | LUOp = 0;
403 | end
404 | 6'b00_0011: begin //sra 0x03
405 | PCSrc = 3'd0;
406 | RegWr = 1;
407 | RegDst = 2'd0;
408 | MemRd = 0;
409 | MemWr = 0;
410 | MemToReg = 2'd0;
411 | ALUSrc1 = 1;
412 | ALUSrc2 = 0;
413 | ALUFun = 6'b100011;
414 | Sign = 1;
415 | EXTOp = 1;
416 | LUOp = 0;
417 | end
418 | 6'b10_1010: begin //slt 0x2a
419 | PCSrc = 3'd0;
420 | RegWr = 1;
421 | RegDst = 2'd0;
422 | MemRd = 0;
423 | MemWr = 0;
424 | MemToReg = 2'd0;
425 | ALUSrc1 = 0;
426 | ALUSrc2 = 0;
427 | ALUFun = 6'b110101;
428 | Sign = 1;
429 | EXTOp = 1;
430 | LUOp = 0;
431 | end
432 | /*
433 | 6'b10_1011: begin //sltu 0x2b
434 | PCSrc = 3'd0;
435 | RegWr = 1;
436 | RegDst = 2'd0;
437 | MemRd = 0;
438 | MemWr = 0;
439 | MemToReg = 2'd0;
440 | ALUSrc1 = 0;
441 | ALUSrc2 = 0;
442 | ALUFun = 6'b110101;
443 | Sign = 0;
444 | EXTOp = 1;
445 | LUOp = 0;
446 | end
447 | */
448 | 6'b00_1000: begin //jr 0x08
449 | PCSrc = 3'd3;
450 | RegWr = 0;
451 | RegDst = 2'd0;
452 | MemRd = 0;
453 | MemWr = 0;
454 | MemToReg = 2'd0;
455 | ALUSrc1 = 0;
456 | ALUSrc2 = 0;
457 | ALUFun = 6'b000000;
458 | Sign = 1;
459 | EXTOp = 1;
460 | LUOp = 0;
461 | end
462 | 6'b00_1001: begin //jalr 0x09
463 | PCSrc = 3'd3;
464 | RegWr = 1;
465 | RegDst = 2'd0;
466 | MemRd = 0;
467 | MemWr = 0;
468 | MemToReg = 2'd2;
469 | ALUSrc1 = 0;
470 | ALUSrc2 = 0;
471 | ALUFun = 6'b000000;
472 | Sign = 1;
473 | EXTOp = 1;
474 | LUOp = 0;
475 | end
476 | default: begin //exception
477 | if(~PC31) begin
478 | PCSrc = 3'd5;
479 | RegWr = 1;
480 | RegDst = 2'd3;
481 | MemRd = 0;
482 | MemWr = 0;
483 | MemToReg = 2'd2;
484 | ALUSrc1 = 0;
485 | ALUSrc2 = 0;
486 | ALUFun = 6'b000000;
487 | Sign = 1;
488 | EXTOp = 1;
489 | LUOp = 0;
490 | end
491 | else begin
492 | PCSrc = 3'd0;
493 | RegWr = 0;
494 | RegDst = 2'd0;
495 | MemRd = 0;
496 | MemWr = 0;
497 | MemToReg = 2'd0;
498 | ALUSrc1 = 0;
499 | ALUSrc2 = 0;
500 | ALUFun = 6'b000000;
501 | Sign = 1;
502 | EXTOp = 1;
503 | LUOp = 0;
504 | end
505 | end
506 | endcase
507 | end
508 | default: begin //exception
509 | if(~PC31) begin
510 | PCSrc = 3'd5;
511 | RegWr = 1;
512 | RegDst = 2'd3;
513 | MemRd = 0;
514 | MemWr = 0;
515 | MemToReg = 2'd2;
516 | ALUSrc1 = 0;
517 | ALUSrc2 = 0;
518 | ALUFun = 6'b000000;
519 | Sign = 1;
520 | EXTOp = 1;
521 | LUOp = 0;
522 | end
523 | else begin
524 | PCSrc = 3'd0;
525 | RegWr = 0;
526 | RegDst = 2'd0;
527 | MemRd = 0;
528 | MemWr = 0;
529 | MemToReg = 2'd0;
530 | ALUSrc1 = 0;
531 | ALUSrc2 = 0;
532 | ALUFun = 6'b000000;
533 | Sign = 1;
534 | EXTOp = 1;
535 | LUOp = 0;
536 | end
537 | end
538 | endcase
539 | end
540 | else begin //Interruption
541 | PCSrc = 3'd4;
542 | RegWr = 1;
543 | RegDst = 2'd3;
544 | MemRd = 0;
545 | MemWr = 0;
546 | MemToReg = 2'd2;
547 | ALUSrc1 = 0;
548 | ALUSrc2 = 0;
549 | ALUFun = 6'b000000;
550 | Sign = 1;
551 | EXTOp = 1;
552 | LUOp = 0;
553 | end
554 | end
555 |
556 | endmodule
--------------------------------------------------------------------------------
/src/Single_Cycle_CPU/DataMem.v:
--------------------------------------------------------------------------------
1 | `timescale 1ns/1ps
2 |
3 | module DataMem (reset,clk,rd,wr,addr,wdata,rdata);
4 | input reset,clk;
5 | input rd,wr;
6 | input [31:0] addr; //Address Must be Word Aligned
7 | input [31:0] wdata;
8 | output [31:0] rdata;
9 |
10 | parameter RAM_SIZE = 256;
11 | reg [31:0] RAMDATA [RAM_SIZE-1:0];
12 |
13 | assign rdata = (rd && (addr[31:2] < RAM_SIZE)) ? RAMDATA[addr[31:2]] : 32'b0;
14 |
15 | always@(posedge clk) begin
16 | if(wr && (addr[31:2] < RAM_SIZE))
17 | RAMDATA[addr[31:2]] <= wdata;
18 | end
19 |
20 | endmodule
--------------------------------------------------------------------------------
/src/Single_Cycle_CPU/Digitube_scan.v:
--------------------------------------------------------------------------------
1 | `timescale 1ns/1ps
2 |
3 | //For Altera DE2: Trans non-scanning Digital tube to scanning Digital tube
4 |
5 | module Digitube_scan(digi_in,digi_out1,digi_out2,digi_out3,digi_out4);
6 | input [11:0] digi_in; //AN3,AN2,AN1,AN0,DP,CG,CF,CE,CD,CC,CB,CA
7 | output [6:0] digi_out1; //0: CG,CF,CE,CD,CC,CB,CA
8 | output [6:0] digi_out2; //1: CG,CF,CE,CD,CC,CB,CA
9 | output [6:0] digi_out3; //2: CG,CF,CE,CD,CC,CB,CA
10 | output [6:0] digi_out4; //3: CG,CF,CE,CD,CC,CB,CA
11 |
12 | assign digi_out1 = (digi_in[11:8] == 4'b0001) ? digi_in[6:0] : 7'b111_1111;
13 | assign digi_out2 = (digi_in[11:8] == 4'b0010) ? digi_in[6:0] : 7'b111_1111;
14 | assign digi_out3 = (digi_in[11:8] == 4'b0100) ? digi_in[6:0] : 7'b111_1111;
15 | assign digi_out4 = (digi_in[11:8] == 4'b1000) ? digi_in[6:0] : 7'b111_1111;
16 |
17 | endmodule
18 |
19 |
--------------------------------------------------------------------------------
/src/Single_Cycle_CPU/Peripheral.v:
--------------------------------------------------------------------------------
1 | `timescale 1ns/1ps
2 |
3 | module Peripheral (reset,clk,rd,wr,addr,wdata,rdata,led,switch,digi,irqout);
4 | input reset,clk;
5 | input rd,wr;
6 | input [31:0] addr;
7 | input [31:0] wdata;
8 | output [31:0] rdata;
9 | reg [31:0] rdata;
10 |
11 | output [7:0] led;
12 | reg [7:0] led;
13 | input [7:0] switch;
14 | output [11:0] digi;
15 | reg [11:0] digi;
16 | output irqout;
17 |
18 | reg [31:0] TH,TL;
19 | reg [2:0] TCON;
20 | assign irqout = TCON[2];
21 |
22 | always@(*) begin
23 | if(rd) begin
24 | case(addr)
25 | 32'h40000000: rdata <= TH;
26 | 32'h40000004: rdata <= TL;
27 | 32'h40000008: rdata <= {29'b0,TCON};
28 | 32'h4000000C: rdata <= {24'b0,led};
29 | 32'h40000010: rdata <= {24'b0,switch};
30 | 32'h40000014: rdata <= {20'b0,digi};
31 | default: rdata <= 32'b0;
32 | endcase
33 | end
34 | else
35 | rdata <= 32'b0;
36 | end
37 |
38 | always@(negedge reset or posedge clk) begin
39 | if(~reset) begin
40 | TH <= 32'b0;
41 | TL <= 32'b0;
42 | TCON <= 3'b0;
43 | end
44 | else begin
45 | if(TCON[0]) begin //timer is enabled
46 | if(TL==32'hffffffff) begin
47 | TL <= TH;
48 | if(TCON[1]) TCON[2] <= 1'b1; //irq is enabled
49 | end
50 | else TL <= TL + 1;
51 | end
52 |
53 | if(wr) begin
54 | case(addr)
55 | 32'h40000000: TH <= wdata;
56 | 32'h40000004: TL <= wdata;
57 | 32'h40000008: TCON <= wdata[2:0];
58 | 32'h4000000C: led <= wdata[7:0];
59 | 32'h40000014: digi <= wdata[11:0];
60 | default: ;
61 | endcase
62 | end
63 | end
64 | end
65 | endmodule
66 |
67 |
--------------------------------------------------------------------------------
/src/Single_Cycle_CPU/ROM.v:
--------------------------------------------------------------------------------
1 | `timescale 1ns/1ps
2 |
3 | module ROM (addr,data);
4 | input [31:0] addr;
5 | output [31:0] data;
6 | reg [31:0] data;
7 | localparam ROM_size = 32;
8 | reg [31:0] ROM_data[ROM_size-1:0];
9 |
10 | always@(*)
11 | case(addr[8:2]) //Address Must Be Word Aligned.
12 | // j INIT
13 | 0: data <= 32'b00001000000000000000000000000011;
14 | // j INTER
15 | 1: data <= 32'b00001000000000000000000000101100;
16 | // j EXCEPT
17 | 2: data <= 32'b00001000000000000000000010000000;
18 | //INIT:
19 | // addi $t0, $zero, 0x0014
20 | 3: data <= 32'b00100000000010000000000000010100;
21 | // jr $t0
22 | 4: data <= 32'b00000001000000000000000000001000;
23 | // lui $s0, 0x4000
24 | 5: data <= 32'b00111100000100000100000000000000;
25 | // sw $zero, 8($s0)
26 | 6: data <= 32'b10101110000000000000000000001000;
27 | // addi $s1, $zero, -25000
28 | 7: data <= 32'b00100000000100011001111001011000;
29 | // sw $s1, 0($s0)
30 | 8: data <= 32'b10101110000100010000000000000000;
31 | // addi $s1, $zero, -1
32 | 9: data <= 32'b00100000000100011111111111111111;
33 | // sw $s1, 4($s0)
34 | 10: data <= 32'b10101110000100010000000000000100;
35 | // addi $s1, $zero, 3
36 | 11: data <= 32'b00100000000100010000000000000011;
37 | // sw $s1, 8($s0)
38 | 12: data <= 32'b10101110000100010000000000001000;
39 | // sw $t0, 32($s0)
40 | 13: data <= 32'b10101110000010000000000000100000;
41 | //UART_START:
42 | // addi $s1, $zero, -1
43 | 14: data <= 32'b00100000000100011111111111111111;
44 | //UART_LOOP:
45 | // lw $t0, 32($s0)
46 | 15: data <= 32'b10001110000010000000000000100000;
47 | // andi $t0, $t0, 0x08
48 | 16: data <= 32'b00110001000010000000000000001000;
49 | // beq $t0, $zero, UART_LOOP
50 | 17: data <= 32'b00010001000000001111111111111101;
51 | // lw $v1, 28($s0)
52 | 18: data <= 32'b10001110000000110000000000011100;
53 | // beq $v1, $zero, UART_LOOP
54 | 19: data <= 32'b00010000011000001111111111111011;
55 | // beq $s1, $zero, LOAD_2
56 | 20: data <= 32'b00010010001000000000000000000011;
57 | // addi $s4, $v1, 0
58 | 21: data <= 32'b00100000011101000000000000000000;
59 | // addi $s1, $s1, 1
60 | 22: data <= 32'b00100010001100010000000000000001;
61 | // j UART_LOOP
62 | 23: data <= 32'b00001000000000000000000000001111;
63 | //LOAD_2:
64 | // addi $s3, $v1, 0
65 | 24: data <= 32'b00100000011100110000000000000000;
66 | // addi $v0, $s4, 0
67 | 25: data <= 32'b00100010100000100000000000000000;
68 | //GCD:
69 | // beq $v0, $zero, ANS1
70 | 26: data <= 32'b00010000010000000000000000001000;
71 | // beq $v1, $zero, ANS2
72 | 27: data <= 32'b00010000011000000000000000001001;
73 | // sub $t3, $v0, $v1
74 | 28: data <= 32'b00000000010000110101100000100010;
75 | // bgtz $t3, LOOP1
76 | 29: data <= 32'b00011101011000000000000000000001;
77 | // bltz $t3, LOOP2
78 | 30: data <= 32'b00000101011000000000000000000010;
79 | //LOOP1:
80 | // sub $v0, $v0, $v1
81 | 31: data <= 32'b00000000010000110001000000100010;
82 | // j GCD
83 | 32: data <= 32'b00001000000000000000000000011010;
84 | //LOOP2:
85 | // sub $v1, $v1, $v0
86 | 33: data <= 32'b00000000011000100001100000100010;
87 | // j GCD
88 | 34: data <= 32'b00001000000000000000000000011010;
89 | //ANS1:
90 | // add $a0, $v1, $zero
91 | 35: data <= 32'b00000000011000000010000000100000;
92 | // j RESULT_DISPLAY
93 | 36: data <= 32'b00001000000000000000000000100110;
94 | //ANS2:
95 | // add $a0, $v0, $zero
96 | 37: data <= 32'b00000000010000000010000000100000;
97 | //RESULT_DISPLAY:
98 | // sw $a0, 12($s0)
99 | 38: data <= 32'b10101110000001000000000000001100;
100 | //UART_SEND_BACK:
101 | // lw $t0, 32($s0)
102 | 39: data <= 32'b10001110000010000000000000100000;
103 | // andi $t0, $t0, 0x10
104 | 40: data <= 32'b00110001000010000000000000010000;
105 | // bne $t0, $zero, UART_SEND_BACK
106 | 41: data <= 32'b00010101000000001111111111111101;
107 | // sw $a0, 24($s0)
108 | 42: data <= 32'b10101110000001000000000000011000;
109 | // j UART_START
110 | 43: data <= 32'b00001000000000000000000000001110;
111 | //INTER:
112 | // lw $t7, 8($s0)
113 | 44: data <= 32'b10001110000011110000000000001000;
114 | // andi $t7, $t7, 0xfff9
115 | 45: data <= 32'b00110001111011111111111111111001;
116 | // sw $t7, 8($s0)
117 | 46: data <= 32'b10101110000011110000000000001000;
118 | // addi $t3, $zero, 1
119 | 47: data <= 32'b00100000000010110000000000000001;
120 | // addi $t4, $zero, 2
121 | 48: data <= 32'b00100000000011000000000000000010;
122 | // addi $t5, $zero, 4
123 | 49: data <= 32'b00100000000011010000000000000100;
124 | // addi $t6, $zero, 8
125 | 50: data <= 32'b00100000000011100000000000001000;
126 | // lw $t7, 20($s0)
127 | 51: data <= 32'b10001110000011110000000000010100;
128 | // andi $t7, $t7, 0xf00
129 | 52: data <= 32'b00110001111011110000111100000000;
130 | // srl $t7, $t7, 8
131 | 53: data <= 32'b00000000000011110111101000000010;
132 | // beq $t7, $t3, DIGITAL_TUBE_1
133 | 54: data <= 32'b00010001111010110000000000000110;
134 | // beq $t7, $t4, DIGITAL_TUBE_2
135 | 55: data <= 32'b00010001111011000000000000001010;
136 | // beq $t7, $t5, DIGITAL_TUBE_3
137 | 56: data <= 32'b00010001111011010000000000001101;
138 | //DIGITAL_TUBE_0:
139 | // andi $s5, $s3, 0x0f
140 | 57: data <= 32'b00110010011101010000000000001111;
141 | // jal DECODE
142 | 58: data <= 32'b00001100000000000000000001001011;
143 | // addi $s5, $s2, 0x100
144 | 59: data <= 32'b00100010010101010000000100000000;
145 | // j DIGITAL_TUBE_DISPLAY
146 | 60: data <= 32'b00001000000000000000000001111001;
147 | //DIGITAL_TUBE_1:
148 | // andi $s5, $s3, 0xf0
149 | 61: data <= 32'b00110010011101010000000011110000;
150 | // srl $s5, $s5, 4
151 | 62: data <= 32'b00000000000101011010100100000010;
152 | // jal DECODE
153 | 63: data <= 32'b00001100000000000000000001001011;
154 | // addi $s5, $s2, 0x200
155 | 64: data <= 32'b00100010010101010000001000000000;
156 | // j DIGITAL_TUBE_DISPLAY
157 | 65: data <= 32'b00001000000000000000000001111001;
158 | //DIGITAL_TUBE_2:
159 | // andi $s5, $s4, 0x0f
160 | 66: data <= 32'b00110010100101010000000000001111;
161 | // jal DECODE
162 | 67: data <= 32'b00001100000000000000000001001011;
163 | // addi $s5, $s2, 0x400
164 | 68: data <= 32'b00100010010101010000010000000000;
165 | // j DIGITAL_TUBE_DISPLAY
166 | 69: data <= 32'b00001000000000000000000001111001;
167 | //DIGITAL_TUBE_3:
168 | // andi $s5, $s4, 0xf0
169 | 70: data <= 32'b00110010100101010000000011110000;
170 | // srl $s5, $s5, 4
171 | 71: data <= 32'b00000000000101011010100100000010;
172 | // jal DECODE
173 | 72: data <= 32'b00001100000000000000000001001011;
174 | // addi $s5, $s2, 0x800
175 | 73: data <= 32'b00100010010101010000100000000000;
176 | // j DIGITAL_TUBE_DISPLAY
177 | 74: data <= 32'b00001000000000000000000001111001;
178 | //DECODE:
179 | // addi $s2, $zero, 0xc0
180 | 75: data <= 32'b00100000000100100000000011000000;
181 | // beq $zero, $s5, DECODE_COMPLETE
182 | 76: data <= 32'b00010000000101010000000000101011;
183 | // addi $s2, $zero, 0xf9
184 | 77: data <= 32'b00100000000100100000000011111001;
185 | // addi $s6, $zero, 1
186 | 78: data <= 32'b00100000000101100000000000000001;
187 | // beq $s6, $s5, DECODE_COMPLETE
188 | 79: data <= 32'b00010010110101010000000000101000;
189 | // addi $s2, $zero, 0xa4
190 | 80: data <= 32'b00100000000100100000000010100100;
191 | // addi $s6, $zero, 2
192 | 81: data <= 32'b00100000000101100000000000000010;
193 | // beq $s6, $s5, DECODE_COMPLETE
194 | 82: data <= 32'b00010010110101010000000000100101;
195 | // addi $s2, $zero, 0xb0
196 | 83: data <= 32'b00100000000100100000000010110000;
197 | // addi $s6, $zero, 3
198 | 84: data <= 32'b00100000000101100000000000000011;
199 | // beq $s6, $s5, DECODE_COMPLETE
200 | 85: data <= 32'b00010010110101010000000000100010;
201 | // addi $s2, $zero, 0x99
202 | 86: data <= 32'b00100000000100100000000010011001;
203 | // addi $s6, $zero, 4
204 | 87: data <= 32'b00100000000101100000000000000100;
205 | // beq $s6, $s5, DECODE_COMPLETE
206 | 88: data <= 32'b00010010110101010000000000011111;
207 | // addi $s2, $zero, 0x92
208 | 89: data <= 32'b00100000000100100000000010010010;
209 | // addi $s6, $zero, 5
210 | 90: data <= 32'b00100000000101100000000000000101;
211 | // beq $s6, $s5, DECODE_COMPLETE
212 | 91: data <= 32'b00010010110101010000000000011100;
213 | // addi $s2, $zero, 0x82
214 | 92: data <= 32'b00100000000100100000000010000010;
215 | // addi $s6, $zero, 6
216 | 93: data <= 32'b00100000000101100000000000000110;
217 | // beq $s6, $s5, DECODE_COMPLETE
218 | 94: data <= 32'b00010010110101010000000000011001;
219 | // addi $s2, $zero, 0xf8
220 | 95: data <= 32'b00100000000100100000000011111000;
221 | // addi $s6, $zero, 7
222 | 96: data <= 32'b00100000000101100000000000000111;
223 | // beq $s6, $s5, DECODE_COMPLETE
224 | 97: data <= 32'b00010010110101010000000000010110;
225 | // addi $s2, $zero, 0x80
226 | 98: data <= 32'b00100000000100100000000010000000;
227 | // addi $s6, $zero, 8
228 | 99: data <= 32'b00100000000101100000000000001000;
229 | // beq $s6, $s5, DECODE_COMPLETE
230 | 100: data <= 32'b00010010110101010000000000010011;
231 | // addi $s2, $zero, 0x90
232 | 101: data <= 32'b00100000000100100000000010010000;
233 | // addi $s6, $zero, 9
234 | 102: data <= 32'b00100000000101100000000000001001;
235 | // beq $s6, $s5, DECODE_COMPLETE
236 | 103: data <= 32'b00010010110101010000000000010000;
237 | // addi $s2, $zero, 0x88
238 | 104: data <= 32'b00100000000100100000000010001000;
239 | // addi $s6, $zero, 0x0a
240 | 105: data <= 32'b00100000000101100000000000001010;
241 | // beq $s6, $s5, DECODE_COMPLETE
242 | 106: data <= 32'b00010010110101010000000000001101;
243 | // addi $s2, $zero, 0x83
244 | 107: data <= 32'b00100000000100100000000010000011;
245 | // addi $s6, $zero, 0x0b
246 | 108: data <= 32'b00100000000101100000000000001011;
247 | // beq $s6, $s5, DECODE_COMPLETE
248 | 109: data <= 32'b00010010110101010000000000001010;
249 | // addi $s2, $zero, 0xc6
250 | 110: data <= 32'b00100000000100100000000011000110;
251 | // addi $s6, $zero, 0x0c
252 | 111: data <= 32'b00100000000101100000000000001100;
253 | // beq $s6, $s5, DECODE_COMPLETE
254 | 112: data <= 32'b00010010110101010000000000000111;
255 | // addi $s2, $zero, 0xa1
256 | 113: data <= 32'b00100000000100100000000010100001;
257 | // addi $s6, $zero, 0x0d
258 | 114: data <= 32'b00100000000101100000000000001101;
259 | // beq $s6, $s5, DECODE_COMPLETE
260 | 115: data <= 32'b00010010110101010000000000000100;
261 | // addi $s2, $zero, 0x86
262 | 116: data <= 32'b00100000000100100000000010000110;
263 | // addi $s6, $zero, 0x0e
264 | 117: data <= 32'b00100000000101100000000000001110;
265 | // beq $s6, $s5, DECODE_COMPLETE
266 | 118: data <= 32'b00010010110101010000000000000001;
267 | // addi $s2, $zero, 0x8e
268 | 119: data <= 32'b00100000000100100000000010001110;
269 | //DECODE_COMPLETE:
270 | // jr $ra
271 | 120: data <= 32'b00000011111000000000000000001000;
272 | //DIGITAL_TUBE_DISPLAY:
273 | // sw $s5, 20($s0)
274 | 121: data <= 32'b10101110000101010000000000010100;
275 | // lw $t3, 8($s0)
276 | 122: data <= 32'b10001110000010110000000000001000;
277 | // addi $t4, $zero, 2
278 | 123: data <= 32'b00100000000011000000000000000010;
279 | // or $t3, $t3, $t4
280 | 124: data <= 32'b00000001011011000101100000100101;
281 | // sw $t3, 8($s0)
282 | 125: data <= 32'b10101110000010110000000000001000;
283 | // addi $26, $26, -4
284 | 126: data <= 32'b00100011010110101111111111111100;
285 | // jr $26
286 | 127: data <= 32'b00000011010000000000000000001000;
287 | //EXCEPT:
288 | // nop
289 | //128: data <= 32'b00000000000000000000000000000000;
290 | default: data <= 32'h8000_0000;
291 | endcase
292 | endmodule
293 |
--------------------------------------------------------------------------------
/src/Single_Cycle_CPU/ROM_tb.v:
--------------------------------------------------------------------------------
1 | `timescale 1ns/1ps
2 |
3 | module ROM (addr,data);
4 | input [31:0] addr;
5 | output [31:0] data;
6 | reg [31:0] data;
7 | localparam ROM_size = 32;
8 | reg [31:0] ROM_data[ROM_size-1:0];
9 |
10 | always@(*)
11 | case(addr[7:2]) //Address Must Be Word Aligned.
12 | // j INIT
13 | 0: data <= 32'b00001000000000000000000000000011;
14 | // j INTER
15 | 1: data <= 32'b00001000000000000000000000101000;
16 | // j EXCEPT
17 | 2: data <= 32'b00001000000000000000000000101001;
18 | //INIT:
19 | // addi $t0, $zero, 0x0014
20 | 3: data <= 32'b00100000000010000000000000010100;
21 | // jr $t0
22 | 4: data <= 32'b00000001000000000000000000001000;
23 | // lui $s0, 0x4000
24 | 5: data <= 32'b00111100000100000100000000000000;
25 | // sw $t0, 32($s0)
26 | 6: data <= 32'b10101110000010000000000000100000;
27 | //UART_START:
28 | // addi $s1, $zero, -1
29 | 7: data <= 32'b00100000000100011111111111111111;
30 | //UART_LOOP:
31 | // lw $t0, 32($s0)
32 | 8: data <= 32'b10001110000010000000000000100000;
33 | // andi $t0, $t0, 0x08
34 | 9: data <= 32'b00110001000010000000000000001000;
35 | // beq $t0, $zero, UART_LOOP
36 | 10: data <= 32'b00010001000000001111111111111101;
37 | // lw $v1, 28($s0)
38 | 11: data <= 32'b10001110000000110000000000011100;
39 | // beq $v1, $zero, UART_LOOP
40 | 12: data <= 32'b00010000011000001111111111111011;
41 | // beq $s1, $zero, LOAD_2
42 | 13: data <= 32'b00010010001000000000000000000011;
43 | // addi $s4, $v1, 0
44 | 14: data <= 32'b00100000011101000000000000000000;
45 | // addi $s1, $s1, 1
46 | 15: data <= 32'b00100010001100010000000000000001;
47 | // j UART_LOOP
48 | 16: data <= 32'b00001000000000000000000000001000;
49 | //LOAD_2:
50 | // addi $s3, $v1, 0
51 | 17: data <= 32'b00100000011100110000000000000000;
52 | // addi $v0, $s4, 0
53 | 18: data <= 32'b00100010100000100000000000000000;
54 | //GCD:
55 | // beq $v0, $zero, ANS1
56 | 19: data <= 32'b00010000010000000000000000001000;
57 | // beq $v1, $zero, ANS2
58 | 20: data <= 32'b00010000011000000000000000001001;
59 | // sub $t3, $v0, $v1
60 | 21: data <= 32'b00000000010000110101100000100010;
61 | // bgtz $t3, LOOP1
62 | 22: data <= 32'b00011101011000000000000000000001;
63 | // bltz $t3, LOOP2
64 | 23: data <= 32'b00000101011000000000000000000010;
65 | //LOOP1:
66 | // sub $v0, $v0, $v1
67 | 24: data <= 32'b00000000010000110001000000100010;
68 | // j GCD
69 | 25: data <= 32'b00001000000000000000000000010011;
70 | //LOOP2:
71 | // sub $v1, $v1, $v0
72 | 26: data <= 32'b00000000011000100001100000100010;
73 | // j GCD
74 | 27: data <= 32'b00001000000000000000000000010011;
75 | //ANS1:
76 | // add $a0, $v1, $zero
77 | 28: data <= 32'b00000000011000000010000000100000;
78 | // j RESULT_DISPLAY
79 | 29: data <= 32'b00001000000000000000000000011111;
80 | //ANS2:
81 | // add $a0, $v0, $zero
82 | 30: data <= 32'b00000000010000000010000000100000;
83 | //RESULT_DISPLAY:
84 | // sw $a0, 12($s0)
85 | 31: data <= 32'b10101110000001000000000000001100;
86 | //UART_SEND_BACK:
87 | // lw $t0, 32($s0)
88 | 32: data <= 32'b10001110000010000000000000100000;
89 | // andi $t0, $t0, 0x10
90 | 33: data <= 32'b00110001000010000000000000010000;
91 | // bne $t0, $zero, UART_SEND_BACK
92 | 34: data <= 32'b00010101000000001111111111111101;
93 | // sw $a0, 24($s0)
94 | 35: data <= 32'b10101110000001000000000000011000;
95 | //AA:
96 | // lw $t0, 32($s0)
97 | 36: data <= 32'b10001110000010000000000000100000;
98 | // andi $t0, $t0, 0x04
99 | 37: data <= 32'b00110001000010000000000000000100;
100 | // beq $t0, $zero, AA
101 | 38: data <= 32'b00010001000000001111111111111101;
102 | // j UART_START
103 | 39: data <= 32'b00001000000000000000000000000111;
104 | //INTER:
105 | // nop
106 | 40: data <= 32'b00000000000000000000000000000000;
107 | //EXCEPT:
108 | // nop
109 | 41: data <= 32'b00000000000000000000000000000000;
110 | default: data <= 32'h8000_0000;
111 | endcase
112 | endmodule
113 |
--------------------------------------------------------------------------------
/src/Single_Cycle_CPU/RegFile.v:
--------------------------------------------------------------------------------
1 | `timescale 1ns/1ps
2 |
3 | module RegFile (reset,clk,addr1,data1,addr2,data2,wr,addr3,data3);
4 | input reset,clk;
5 | input wr;
6 | input [4:0] addr1,addr2,addr3;
7 | output [31:0] data1,data2;
8 | input [31:0] data3;
9 |
10 | reg [31:0] RF_data[31:0];
11 |
12 | assign data1 = RF_data[addr1];
13 | assign data2 = RF_data[addr2];
14 |
15 | always@(negedge reset or posedge clk) begin
16 | if(~reset) begin
17 | RF_data[0]<=32'b0;
18 | RF_data[1]<=32'b0;
19 | RF_data[2]<=32'b0;
20 | RF_data[3]<=32'b0;
21 | RF_data[4]<=32'b0;
22 | RF_data[5]<=32'b0;
23 | RF_data[6]<=32'b0;
24 | RF_data[7]<=32'b0;
25 | RF_data[8]<=32'b0;
26 | RF_data[9]<=32'b0;
27 | RF_data[10]<=32'b0;
28 | RF_data[11]<=32'b0;
29 | RF_data[12]<=32'b0;
30 | RF_data[13]<=32'b0;
31 | RF_data[14]<=32'b0;
32 | RF_data[15]<=32'b0;
33 | RF_data[16]<=32'b0;
34 | RF_data[17]<=32'b0;
35 | RF_data[18]<=32'b0;
36 | RF_data[19]<=32'b0;
37 | RF_data[20]<=32'b0;
38 | RF_data[21]<=32'b0;
39 | RF_data[22]<=32'b0;
40 | RF_data[23]<=32'b0;
41 | RF_data[24]<=32'b0;
42 | RF_data[25]<=32'b0;
43 | RF_data[26]<=32'b0;
44 | RF_data[27]<=32'b0;
45 | RF_data[28]<=32'b0;
46 | RF_data[29]<=32'b0;
47 | RF_data[30]<=32'b0;
48 | RF_data[31]<=32'b0;
49 | end
50 | else begin
51 | // $0 MUST be all zeros
52 | if(wr && (|addr3))
53 | RF_data[addr3] <= data3;
54 | end
55 | end
56 | endmodule
57 |
--------------------------------------------------------------------------------
/src/Single_Cycle_CPU/UART.v:
--------------------------------------------------------------------------------
1 | module UART_Receiver(uart_rx, sysclk, rx_data, rx_status, rx_LoadFinish, reset);
2 | input uart_rx, rx_LoadFinish, sysclk, reset;
3 | output reg [7:0] rx_data;
4 | output reg rx_status;
5 |
6 | reg [3:0] cnt_catch; // Sampling count
7 | reg [4:0] cnt_clk; // Count 153600Hz Clock to generate 9600Hz
8 | reg status; // Status of Receiver, 0 - idle & start bit, 1- busy
9 | reg [8:0] brcnt16; // Count sysclk to generate 153600Hz
10 |
11 | always @(posedge sysclk or negedge reset)
12 | begin
13 | if(~reset) begin
14 | brcnt16 <= 9'd0;
15 | cnt_catch <= 4'd0;
16 | cnt_clk <= 5'd0;
17 | status <= 0;
18 | rx_status <= 0;
19 | rx_data <= 8'd0;
20 | end
21 | else begin
22 | if(~status) begin
23 | if(rx_LoadFinish)
24 | rx_status <= 0;
25 | if(~uart_rx) begin
26 | if(cnt_clk==5'd8) begin
27 | cnt_clk <= 5'd0;
28 | status <= 1;
29 | brcnt16 <= 9'd0;
30 | end
31 | else begin
32 | if (brcnt16 == 9'd325) begin
33 | brcnt16 <= 9'd0;
34 | cnt_clk <= cnt_clk + 1;
35 | end
36 | else
37 | brcnt16 <= brcnt16 + 1;
38 | end
39 | end
40 | end
41 | else begin
42 | if(cnt_catch==4'd9) begin
43 | cnt_catch <= 4'd0;
44 | status <= 0;
45 | brcnt16 <= 9'd0;
46 | cnt_clk <= 5'd0;
47 | rx_status <= 1;
48 | end
49 | else begin
50 | if(cnt_clk == 5'd16) begin
51 | cnt_clk <= 5'd0;
52 | brcnt16 <= 9'd0;
53 | cnt_catch <= cnt_catch+1;
54 | if (cnt_catch < 4'd8)
55 | rx_data[cnt_catch]<=uart_rx;
56 | end
57 | else begin
58 | if(brcnt16 == 9'd325) begin
59 | brcnt16 <= 9'd0;
60 | cnt_clk <= cnt_clk + 1;
61 | end
62 | else
63 | brcnt16 <= brcnt16 + 1;
64 | end
65 | end
66 | end
67 | end
68 | end
69 |
70 | endmodule
71 |
72 |
73 | module UART_Sender(tx_data, tx_en, sysclk, tx_status, uart_tx, reset);
74 |
75 | input [7:0] tx_data;
76 | input tx_en, sysclk, reset;
77 | output reg tx_status, uart_tx;
78 |
79 | reg [3:0] cnt; // Count bit
80 | reg [9:0] tmp_data; // Buffer to save data temporily
81 | reg [12:0] brcnt; // Count sysclk to generate 9600Hz Clock
82 |
83 | always @(posedge sysclk or negedge reset)
84 | begin
85 | if (~reset) begin
86 | tx_status <= 1'b1;
87 | uart_tx <= 1'b1;
88 | cnt <= 4'd0;
89 | end
90 | else begin
91 | if(tx_status) begin
92 | uart_tx <= 1'b1;
93 | cnt <= 4'd0;
94 | brcnt <= 13'd5208;
95 | if(tx_en) begin
96 | tmp_data[0] <= 1'b0;
97 | tmp_data[8:1] <= tx_data;
98 | tmp_data[9] <= 1'b1;
99 | tx_status <= 1'b0;
100 | end
101 | end
102 | else begin
103 | if(brcnt == 13'd5208) begin
104 | brcnt <= 13'd0;
105 | if (cnt==4'd10) begin
106 | cnt <= 4'd0;
107 | tx_status <= 1'b1;
108 | end
109 | else
110 | uart_tx <= tmp_data[cnt];
111 | cnt <= cnt + 1;
112 | end
113 | else
114 | brcnt <= brcnt + 12'd1;
115 | end
116 | end
117 | end
118 |
119 | endmodule
120 |
121 | module UART(reset, sysclk, clk, rd, wr, addr, wdata, rdata, UART_RX, UART_TX, RX_IRQ, TX_IRQ);
122 | input sysclk, reset, clk, rd, wr, UART_RX;
123 | input [31:0] addr, wdata;
124 | output UART_TX, RX_IRQ, TX_IRQ;
125 | output reg [31:0] rdata;
126 | wire rx_status, tx_status, tx_over;
127 | wire[7:0] rx_data;
128 | reg[7:0] UART_RXD, UART_TXD;
129 | reg[4:0] UART_CON;
130 | reg tx_en;
131 |
132 | // Read Data
133 | always @(*) begin
134 | if(rd) begin
135 | case(addr)
136 | 32'h4000_0018: rdata = {24'd0, UART_TXD};
137 | 32'h4000_001c: rdata = {24'd0, UART_RXD};
138 | 32'h4000_0020: rdata = {27'd0, UART_CON};
139 | default: rdata = 32'd0;
140 | endcase
141 | end
142 | else
143 | rdata = 32'd0;
144 | end
145 |
146 | always @(posedge clk or negedge reset) begin
147 | if(~reset) begin
148 | UART_RXD <= 8'd0;
149 | UART_TXD <= 8'd0;
150 | UART_CON <= 5'd0;
151 | tx_en <= 0;
152 | end
153 | else begin
154 |
155 | // After receive the data
156 | if(rx_status) begin
157 | UART_RXD <= rx_data;
158 | UART_CON[3] <= 1'b1;
159 | end
160 |
161 | // After send the data
162 | if(UART_CON[4] && tx_status) begin
163 | UART_CON[2] <= 1'b1;
164 | end
165 | UART_CON[4] <= ~tx_status;
166 |
167 | // After read UART_CON
168 | if(rd && (addr == 32'h4000_0020)) begin
169 | UART_CON[2] <= 1'b0;
170 | UART_CON[3] <= 1'b0;
171 | end
172 |
173 | // Write Data
174 | if(wr) begin
175 | case(addr)
176 | 32'h4000_0018: begin
177 | UART_TXD <= wdata[7:0];
178 | tx_en <= 1;
179 | end
180 | 32'h4000_0020: UART_CON[1:0] <= wdata[1:0];
181 | default: ;
182 | endcase
183 | end
184 | if(tx_en)
185 | tx_en <= 0;
186 | end
187 | end
188 |
189 | // Set Interrupt
190 | assign RX_IRQ = UART_CON[1] && UART_CON[3];
191 | assign TX_IRQ = UART_CON[0] && UART_CON[2];
192 |
193 | UART_Receiver UART_Receiver_1(.uart_rx(UART_RX), .sysclk(sysclk), .rx_data(rx_data), .rx_status(rx_status), .rx_LoadFinish(UART_CON[3]), .reset(reset));
194 |
195 | UART_Sender UART_Sender_1(.tx_data(UART_TXD), .tx_en(tx_en), .sysclk(sysclk), .tx_status(tx_status), .uart_tx(UART_TX), .reset(reset));
196 |
197 | endmodule
--------------------------------------------------------------------------------