├── 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 | ![CPU整体设计](img/overall.png) 12 | 13 | 14 | ALU 15 | --- 16 | 17 | ALU模块分为四个子模块,分别是加减运算模块,比较模块,逻辑模块和移位模块,通过ALUFun最高两位多路选择,决定最后的输出。详细的模块设计如图所示。 18 | 19 | ![ALU模块设计](img/alu.png) 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 | ![UART数据通路](img/uart.png) 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 | ![流水线CPU数据通路](img/pipeline.png) 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 --------------------------------------------------------------------------------