├── README.md ├── assignment1 ├── MIPSassembler.cpp ├── MIPSassembler.h ├── report.pdf └── testfile.asm ├── assignment2 ├── 3.txt ├── 4.txt ├── MIPSassembler.cpp ├── MIPSassembler.h ├── MIPSsimulator.cpp ├── MIPSsimulator.h ├── adder.txt ├── dataHandler.cpp ├── dataHandler.h ├── fibonacii.txt └── report.pdf ├── assignment3 ├── ALU.v ├── report.pdf └── test_ALU.v └── assignment4 ├── CPU.v ├── report.pdf ├── test_CPU_1.v ├── test_CPU_2.v ├── test_CPU_data_hazard.v └── test_CPU_lw_stall.v /README.md: -------------------------------------------------------------------------------- 1 | # CSC3050 Computer Architecture 2 | 3 | [![Security Status](https://s.murphysec.com/badge/MoyuST/CSC3050-Computer-Architecture.svg)](https://www.murphysec.com/p/MoyuST/CSC3050-Computer-Architecture) 4 | 5 | This is my favorite course during my undergraduate university life at CUHK(SZ). 6 | This course kind of is the first CSC course introduces me to some real coding. 7 |
8 | I still remembered how struggling it is to do the homework: I always started doing each assignment once it released and worked on it for three whole weeks till the last sec. 9 | But I always handled in each of them just right before the DDL😂. 10 |
11 | I really appreciated all the help I received from my friends at that time which really saved my life. 12 |
13 | To make the new CS students' lives easier, I decided to share my codes with you! Hope it can give you some hints. 14 |
15 | If you do find it helpful, plz gives me a star👍! 16 |
17 |
18 | The assignments and my scores for them are: 19 | 20 | - MIPS Assembler (100/100) 21 | - MIPS Simulator (100/100) 22 | - ALU (100/100) 23 | - pipeline CPU (with hazard handling) (110/110) 24 |
25 | I guess there may be some bugs in my code🤣. You may need to check carefully when looking at my codes. 26 |
27 | Good luck to all CSers and CEers in CUHK(SZ)! 28 | -------------------------------------------------------------------------------- /assignment1/MIPSassembler.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include "MIPSassembler.h" 7 | 8 | using namespace std; 9 | 10 | //name of the register 11 | const char* Reg[32] = { 12 | "zero", "at", "v0", "v1", "a0", "a1", "a2", "a3", 13 | "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7", 14 | "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", 15 | "t8", "t9", "k0", "k1", "gp", "sp", "fp", "ra" 16 | }; 17 | 18 | // different types of mips code 19 | // xxx rd, rs, rt (notice: the opcode for mul is 0x1c) 20 | const map type1 ={ //(name, funct) 21 | make_pair("add", 0x20), make_pair("addu", 0x21), make_pair("and", 0x24), 22 | make_pair("mul", 2), make_pair("nor", 0x27), make_pair("or", 0x25), 23 | make_pair("sub", 0x22), make_pair("subu", 0x23), make_pair("xor", 0x26), 24 | make_pair("slt", 0x2a), make_pair("sltu", 0x2b) 25 | }; 26 | 27 | //xxx rt, rs, imm 28 | const map type2 ={ //(name, opcode) 29 | make_pair("addi", 8), make_pair("addiu", 9), make_pair("andi", 0xc), 30 | make_pair("ori", 0xd), make_pair("xori", 0xe), make_pair("slti", 0xa), 31 | make_pair("sltiu", 0xb) 32 | }; 33 | 34 | //xxx rd, rs 35 | const map type3 ={ //(name, funct) 36 | make_pair("clo", 0x21), make_pair("clz", 0x20) 37 | }; 38 | 39 | //xxx rs, rt and opcode == 0 40 | const map type4 ={ //(name, funct) 41 | make_pair("div", 0x1a), make_pair("divu", 0x1b), make_pair("mult", 0x18), 42 | make_pair("multu", 0x19), make_pair("teq", 0x34), make_pair("tne", 0x36), 43 | make_pair("tge", 0x30), make_pair("tgeu", 0x31), make_pair("tlt", 0x32), 44 | make_pair("tltu", 0x33) 45 | }; 46 | 47 | //xxx rs, rt and opcode == 0x1c 48 | const map type5 ={ //(name, funct) 49 | make_pair("madd", 0), make_pair("maddu", 1), make_pair("msub", 4), 50 | make_pair("msubu", 5) 51 | }; 52 | 53 | //xxx rd, rt shamt 54 | const map type6 ={ //(name, funct) 55 | make_pair("sll", 0), make_pair("sra", 3), make_pair("srl", 2) 56 | }; 57 | 58 | //xxx rd, rt, rs 59 | const map type7 ={ //(name, funct) 60 | make_pair("sllv", 4), make_pair("srav", 7), make_pair("srlv", 6) 61 | }; 62 | 63 | //xxx rs, rt, label 64 | const map type8 ={ //(name, op) 65 | make_pair("beq", 4), make_pair("bne", 5) 66 | }; 67 | 68 | //xxx rs, label 69 | //since this type of operations have different opcode and rt code 70 | //so use two maps to store them 71 | const map type9 ={ //(name, op) 72 | make_pair("bgez", 1), make_pair("bgezal", 1), make_pair("bgtz", 7), 73 | make_pair("blez", 6), make_pair("bltzal", 1), make_pair("bltz", 1) 74 | }; 75 | 76 | const map type9_2 ={ //(name, rt) 77 | make_pair("bgez", 1), make_pair("bgezal", 0x11), make_pair("bgtz", 0), 78 | make_pair("blez",0), make_pair("bltzal", 0x10), make_pair("bltz", 0) 79 | }; 80 | 81 | //xxx target 82 | const map type10 ={ //(name, op) 83 | make_pair("j", 2), make_pair("jal", 3) 84 | }; 85 | 86 | //xxx rs 87 | const map type11 ={ //(name, funct) 88 | make_pair("jr", 8), make_pair("mthi", 0x11), make_pair("mtlo", 0x13) 89 | }; 90 | 91 | //xxx rd 92 | const map type12 ={ //(name, funct) 93 | make_pair("mfhi", 0x10), make_pair("mflo", 0x12) 94 | }; 95 | 96 | //xxx rs, imm 97 | const map type13 ={ //(name, rt) 98 | make_pair("teqi", 0xc), make_pair("tnei", 0xe), make_pair("tgei", 8), 99 | make_pair("tgeiu", 9), make_pair("tlti", 0xa), make_pair("tltiu", 0xb) 100 | }; 101 | 102 | //xxx rt, address 103 | const map type14 ={ //(name, op) 104 | make_pair("lb", 0x20), make_pair("lbu", 0x24), make_pair("lh", 0x21), 105 | make_pair("lhu", 0x25), make_pair("lw", 0x23), make_pair("lwcl", 0x31), 106 | make_pair("lwl", 0x22), make_pair("lwr", 0x26), make_pair("ll", 0x30), 107 | make_pair("sb", 0x28), make_pair("sh", 0x29), make_pair("sw", 0x2b), 108 | make_pair("swcl", 0x31), make_pair("swl", 0x2a), make_pair("swr", 0x2e), 109 | make_pair("sc", 0x38) 110 | }; 111 | 112 | //xxx rt, imm 113 | //there is only one of this type, only need to store the opcode 114 | const int type15 = 0xf; 115 | 116 | //xxx rs, rd 117 | //there is only one of this type, only need to store the funct code 118 | const int type16 = 9; 119 | 120 | 121 | 122 | int main(int argc, char *argv[]){ 123 | // check the format of input 124 | 125 | if (argc != 3){ 126 | cout << "please enter the names of the input and output files" << endl; 127 | return 0; 128 | } 129 | 130 | //create a map to store the addresses for the labels 131 | map labels; 132 | 133 | //create a map to store the line number of the counter 134 | map numOfCounter; 135 | 136 | string out_path; //the address for the output file 137 | out_path = newaddress(argv[1], argv[2]); //create the address for outfile 138 | 139 | ifstream infile(argv[1]); 140 | 141 | // try to open the file 142 | if(infile.fail()){ 143 | cout << "failed to open the file" << endl; 144 | infile.close(); 145 | return 0; 146 | } 147 | 148 | ofstream outfile(out_path); 149 | 150 | //store the labels and lines of the instruction 151 | firstscan(argv[1], labels, numOfCounter); 152 | 153 | //transfer the MIPS code 154 | mipsToMachinecode(infile, outfile, labels, numOfCounter); 155 | 156 | cout << "Output in " << out_path << endl; 157 | infile.close(); 158 | outfile.close(); 159 | return 0; 160 | } 161 | 162 | //create the address for the outputfile 163 | string newaddress(string input, string output){ 164 | int endposi = -1; 165 | for(int i = input.length()-1; i>=0; i--){ 166 | if(input[i]=='/'){ 167 | endposi=i; 168 | break; 169 | } 170 | } 171 | //if there is no path in the input 172 | if(endposi==-1) return output; 173 | //if there is path in the output 174 | return input.substr(0,endposi+1)+output; 175 | } 176 | 177 | //input the number to the os stream in binary form 178 | void convernum(int num, int size, ostream & os){ 179 | int flag=0; 180 | if(num<0){ 181 | flag=1; 182 | num *= -1; //change num to the absolute value 183 | } 184 | 185 | if(flag){ // conver the negative num to 2's complete form 186 | int mask=1; 187 | mask <<= (size); 188 | mask -= 1; 189 | num = num^mask; 190 | num += 1; 191 | } 192 | 193 | int a = 1; 194 | a = (1<<(size-1)); 195 | 196 | for(int i = 0; i < size ; i++){ 197 | if (num&a) os << 1; 198 | else os << 0; 199 | 200 | num <<= 1; 201 | } 202 | } 203 | 204 | //transfer the register to number 205 | int converReg(char* code, bool end){ 206 | char codeholder[20] = ""; 207 | char *p = code; 208 | 209 | while(*p==' '||*p=='\t') p++; //skip all the space 210 | if(*p == '$') p++; 211 | else return -1; //no register found 212 | 213 | //extract the register out 214 | int i=0; 215 | while(*p!='\0' && (*p !=' '&& *p!='\t')){ 216 | i++; 217 | p++; 218 | } 219 | strncpy(codeholder, p-i, i); 220 | 221 | int num = -1; 222 | //convert the name of register to number 223 | for(int j=0; j<32; j++){ 224 | if(num!=-1) break; 225 | if(!strcmp(codeholder, Reg[j])) num = j; 226 | } 227 | 228 | //check whether there are invalid characters after the register 229 | while (*p == ' '|| *p=='\t') p++; //skip the space after the register 230 | 231 | //check whether there might be comments followed 232 | if(end){ 233 | if(*p=='#') return num; 234 | } 235 | 236 | if (*p != '\0') return -1; 237 | else return num; 238 | 239 | } 240 | 241 | // convert the "imm(register)" 242 | bool converArray(char* code, int & rs, int & imm){ 243 | char codeholder[20]= ""; 244 | char *p = code; 245 | imm = 0; 246 | int sign=1; 247 | 248 | while(*p==' '||*p=='\t') p++; //skip all the space 249 | if(*p=='-'){ 250 | sign=-1; 251 | p++; 252 | } 253 | 254 | // invalid 255 | if(*p<'0'||*p>'9') return false; 256 | 257 | while(*p>='0' && *p<='9'){ 258 | imm = 10*imm + (*p-'0'); 259 | p++; 260 | } 261 | imm *= sign; 262 | 263 | //invalid input 264 | if(*p!='(') return false; 265 | p++; 266 | 267 | int i = 0; 268 | while(*p!='\0' && *p!=')'){ 269 | i++; 270 | p++; 271 | } 272 | 273 | //no value in the bracket 274 | if(*p!=')') return false; 275 | 276 | strncpy(codeholder, p-i, i); 277 | rs = converReg(codeholder, true); 278 | if(rs==-1) return false; 279 | 280 | return true; 281 | } 282 | 283 | //transfer the char[] to num, if failed return false 284 | bool charToNum(char* string, int & num, bool end){ 285 | int p = 0; 286 | int sign = 1; 287 | num = 0; 288 | int length = int(strlen(string)); 289 | 290 | while(p='0'){ 297 | num = 10 * num + (string[p] - '0'); 298 | p++; 299 | } 300 | num *= sign; 301 | 302 | while(p & labels, map & numOfCounter){ 339 | ifstream infile(filename); 340 | string line; 341 | int counter = -1; 342 | int linenum = 0; 343 | while(getline(infile, line)){ 344 | counter++; 345 | linenum++; 346 | 347 | int ps=0; // start of the label 348 | int pe=0; // end of the label 349 | int length = line.length(); 350 | 351 | // skip of the space 352 | while( pssecond += 1; 358 | counter--; 359 | continue; 360 | } 361 | 362 | pe = ps; 363 | while(pe (label, counter)); 381 | 382 | //not followed by instruction 383 | if(line[pe]=='\0' || line[pe]=='#'){ 384 | if(!numOfCounter.count(counter)) numOfCounter.insert(make_pair(counter, linenum+1)); 385 | else numOfCounter.find(counter)->second += 1; 386 | counter--; 387 | } 388 | 389 | } 390 | infile.close(); 391 | 392 | } 393 | 394 | // transfer the mips code to machine code 395 | void mipsToMachinecode(istream & is, ostream & os, map labels, map numOfCounter){ 396 | char ins[50], arg1[150], arg2[150], arg3[150]; //hold the instruction and arguements 397 | int linenum = 0; //count the line number 398 | int counter = -1; 399 | string cache; 400 | 401 | while (is >> ins){ 402 | counter++; 403 | 404 | // skip the label if the label is not followed by instruction 405 | if(ins[strlen(ins)-1]==':'){ 406 | counter--; 407 | continue; 408 | } 409 | 410 | linenum++; 411 | 412 | // skip the line of ".data" and ".text" and comments 413 | if (ins[0]=='.' || ins[0]=='#') { 414 | getline(is, cache); 415 | counter--; 416 | continue; 417 | } 418 | 419 | // update the line number for counter 420 | if(numOfCounter.count(counter)){ 421 | linenum = numOfCounter.find(counter)->second; 422 | } 423 | 424 | //type 1 instruction 425 | // xxx rd, rs, rt (notice: the opcode for mul is 0x1c) 426 | if(type1.count(ins)==1){ 427 | int op = 0; 428 | if(!strcmp(ins, "mul")) op=0x1c; 429 | 430 | // rd 431 | is.getline(arg1, 150, ','); 432 | int rd = converReg(arg1); 433 | if(rd==-1) 434 | cout << "error in line " << linenum << endl; 435 | 436 | // rs 437 | is.getline(arg2, 150, ','); 438 | int rs = converReg(arg2); 439 | if(rs==-1) 440 | cout << "error in line " << linenum << endl; 441 | 442 | // rt 443 | is.getline(arg3, 150); 444 | int rt = converReg(arg3, true); 445 | if(rt==-1) 446 | cout << "error in line " << linenum << endl; 447 | 448 | //funct 449 | int funct = type1.find(ins)->second; 450 | 451 | convernum(op, 6, os); //opcode 452 | convernum(rs, 5, os); //rs 453 | convernum(rt, 5, os); //rt 454 | convernum(rd, 5, os); //rd 455 | convernum(0, 5, os); //shamt 456 | convernum(funct, 6, os); //funct 457 | os << endl; 458 | } 459 | 460 | //type 2 instruction 461 | // xxx rt, rs, imm 462 | else if(type2.count(ins)==1){ 463 | 464 | // rt 465 | is.getline(arg1, 150, ','); 466 | int rt = converReg(arg1); 467 | if(rt==-1) 468 | cout << "error in line " << linenum << endl; 469 | 470 | // rs 471 | is.getline(arg2, 150, ','); 472 | int rs = converReg(arg2); 473 | if(rs==-1) 474 | cout << "error in line " << linenum << endl; 475 | 476 | // imm 477 | is.getline(arg3, 150); 478 | int imm = 0; 479 | if(!charToNum(arg3, imm, true)) 480 | cout << "error in line " << linenum << endl; 481 | 482 | //op 483 | int op = type2.find(ins)->second; 484 | 485 | convernum(op, 6, os); //opcode 486 | convernum(rs, 5, os); //rs 487 | convernum(rt, 5, os); //rt 488 | convernum(imm, 16, os); //imm 489 | 490 | os << endl; 491 | } 492 | 493 | //type 3 instruction 494 | // xxx rd, rs 495 | else if(type3.count(ins)==1){ 496 | 497 | // rd 498 | is.getline(arg1, 150, ','); 499 | int rd = converReg(arg1); 500 | if(rd==-1) 501 | cout << "error in line " << linenum << endl; 502 | // rs 503 | is.getline(arg2, 150); 504 | int rs = converReg(arg2, true); 505 | if(rs==-1) 506 | cout << "error in line " << linenum << endl; 507 | 508 | //funct 509 | int funct = type3.find(ins)->second; 510 | 511 | convernum(0x1c, 6, os); //opcode=0x1c 512 | convernum(rs, 5, os); //rs 513 | convernum(0, 5, os); //rt 514 | convernum(rd, 5, os); //rd 515 | convernum(0, 5, os); //shamt 516 | convernum(funct, 6, os); //funct 517 | os << endl; 518 | } 519 | 520 | //type 4 instruction 521 | // xxx rt, rs with opcode=0 522 | else if(type4.count(ins)==1){ 523 | 524 | // rs 525 | 526 | is.getline(arg1, 150, ','); 527 | int rs = converReg(arg1); 528 | if(rs==-1) 529 | cout << "error in line " << linenum << endl; 530 | 531 | // rt 532 | is.getline(arg2, 150); 533 | int rt = converReg(arg2, true); 534 | if(rt==-1) 535 | cout << "error in line " << linenum << endl; 536 | 537 | //funct 538 | int funct = type4.find(ins)->second; 539 | 540 | convernum(0, 6, os); //opcode=0x1c 541 | convernum(rs, 5, os); //rs 542 | convernum(rt, 5, os); //rt 543 | convernum(0, 10, os); //rd+shamt 544 | convernum(funct, 6, os); //funct 545 | os << endl; 546 | } 547 | 548 | //type 5 instruction 549 | // xxx rt, rs with opcode=0x1c 550 | else if(type5.count(ins)==1){ 551 | 552 | // rs 553 | is.getline(arg1, 150, ','); 554 | int rs = converReg(arg1); 555 | if(rs==-1) 556 | cout << "error in line " << linenum << endl; 557 | 558 | // rt 559 | is.getline(arg2, 150); 560 | int rt = converReg(arg2, true); 561 | if(rt==-1) 562 | cout << "error in line " << linenum << endl; 563 | 564 | //funct 565 | int funct = type5.find(ins)->second; 566 | 567 | convernum(0x1c, 6, os); //opcode=0x1c 568 | convernum(rs, 5, os); //rs 569 | convernum(rt, 5, os); //rt 570 | convernum(0, 10, os); //rd+shamt 571 | convernum(funct, 6, os); //funct 572 | os << endl; 573 | } 574 | 575 | //type 6 instruction 576 | // xxx rd, rt, shamt 577 | else if(type6.count(ins)==1){ 578 | 579 | // rd 580 | is.getline(arg1, 150, ','); 581 | int rd = converReg(arg1); 582 | if(rd ==-1) 583 | cout << "error in line " << linenum << endl; 584 | 585 | // rt 586 | is.getline(arg2, 150, ','); 587 | int rt = converReg(arg2); 588 | if(rt==-1) 589 | cout << "error in line " << linenum << endl; 590 | 591 | // shamt 592 | is.getline(arg3, 150); 593 | int shamt = 0; 594 | if(!charToNum(arg3, shamt, true)) 595 | cout << "error in line " << linenum << endl; 596 | 597 | //funct 598 | int funct = type6.find(ins)->second; 599 | 600 | convernum(0, 6, os); //op 601 | convernum(0, 5, os); //rs 602 | convernum(rt, 5, os); //rt 603 | convernum(rd, 5, os); //rd 604 | convernum(shamt, 5, os); //shamt 605 | convernum(funct, 6, os); //funct 606 | os << endl; 607 | } 608 | 609 | //type 7 instruction 610 | // xxx rd, rt, rs 611 | else if(type7.count(ins)==1){ 612 | 613 | // rd 614 | is.getline(arg1, 150, ','); 615 | int rd = converReg(arg1); 616 | if(rd ==-1) 617 | cout << "error in line " << linenum << endl; 618 | 619 | // rt 620 | is.getline(arg2, 150, ','); 621 | int rt = converReg(arg2); 622 | if(rt==-1) 623 | cout << "error in line " << linenum << endl; 624 | 625 | // rs 626 | is.getline(arg3, 150); 627 | int rs = converReg(arg3, true); 628 | if(rs==-1) 629 | cout << "error in line " << linenum << endl; 630 | 631 | //funct 632 | int funct = type7.find(ins)->second; 633 | 634 | convernum(0, 6, os); //op 635 | convernum(rs, 5, os); //rs 636 | convernum(rt, 5, os); //rt 637 | convernum(rd, 5, os); //rd 638 | convernum(0, 5, os); //shamt 639 | convernum(funct, 6, os); //funct 640 | os << endl; 641 | } 642 | 643 | //type 8 instruction 644 | // xxx rs, rt, label/offset 645 | else if(type8.count(ins)==1){ 646 | 647 | // rs 648 | is.getline(arg1, 150, ','); 649 | int rs = converReg(arg1); 650 | if(rs ==-1) 651 | cout << "error in line " << linenum << endl; 652 | 653 | // rt 654 | is.getline(arg2, 150, ','); 655 | int rt = converReg(arg2); 656 | if(rt==-1) 657 | cout << "error in line " << linenum << endl; 658 | 659 | // label/offset 660 | is.getline(arg3, 150); 661 | int offset; 662 | char labelholder[150] = ""; 663 | char *p =labelholder; 664 | 665 | //it is a label 666 | if(labelextrace(arg3, p)&&labels.count(labelholder)){ 667 | offset = labels.find(labelholder)->second - counter - 1; 668 | } 669 | // it is the offset 670 | else if(charToNum(arg3,offset,true)); 671 | //invalid 672 | else cout << "error in line " << linenum << endl; 673 | 674 | //op 675 | int op = type8.find(ins)->second; 676 | 677 | convernum(op, 6, os); //op 678 | convernum(rs, 5, os); //rs 679 | convernum(rt, 5, os); //rt 680 | convernum(offset, 16, os); //offset 681 | os << endl; 682 | } 683 | 684 | //type 9 instruction 685 | // xxx rs, label 686 | else if(type9.count(ins)==1){ 687 | 688 | // rs 689 | is.getline(arg1, 150, ','); 690 | int rs = converReg(arg1); 691 | if(rs ==-1) cout << "error in line " << linenum << endl; 692 | 693 | // label 694 | is.getline(arg2, 150); 695 | int offset; 696 | char labelholder[150] = ""; 697 | char *p =labelholder; 698 | 699 | //it is a label 700 | if(labelextrace(arg2, p)&&labels.count(labelholder)){ 701 | offset = labels.find(labelholder)->second - counter - 1; 702 | } 703 | // it is the offset 704 | else if(charToNum(arg2,offset,true)); 705 | //invalid 706 | else cout << "error in line " << linenum << endl; 707 | 708 | //op 709 | int op = type9.find(ins)->second; 710 | 711 | //rt 712 | int rt = type9_2.find(ins)->second; 713 | 714 | convernum(op, 6, os); //opcode=0x1c 715 | convernum(rs, 5, os); //rs 716 | convernum(rt, 5, os); //rt 717 | convernum(offset, 16, os); //offset 718 | os << endl; 719 | } 720 | 721 | //type 10 instruction 722 | // xxx target 723 | else if(type10.count(ins)==1){ 724 | 725 | // label 726 | is.getline(arg1, 150); 727 | int target; 728 | char labelholder[150] = ""; 729 | char *p =labelholder; 730 | 731 | //it is a label 732 | if(labelextrace(arg1, p)&&labels.count(labelholder)){ 733 | target = labels.find(labelholder)->second; 734 | } 735 | // it is the address 736 | else if(charToNum(arg1,target,true)); 737 | //invalid 738 | else cout << "error in line " << linenum << endl; 739 | 740 | //remove the first 4 digits of the target and shift right 2 bits 741 | target *= 4; 742 | target = target & 0x0fff; 743 | target >>= 2; 744 | 745 | //op 746 | int op = type10.find(ins)->second; 747 | 748 | convernum(op, 6, os); //opcode=0x1c 749 | convernum(target, 26, os); //target 750 | os << endl; 751 | } 752 | 753 | //type 11 instruction 754 | // xxx rs 755 | else if(type11.count(ins)==1){ 756 | 757 | // rs 758 | is.getline(arg1, 150); 759 | int rs = converReg(arg1, true); 760 | if(rs ==-1) cout << "error in line " << linenum << endl; 761 | 762 | //funct 763 | int funct = type11.find(ins)->second; 764 | 765 | convernum(0, 6, os); //op 766 | convernum(rs, 5, os); //rs 767 | convernum(0, 15, os); //rt+rd+shamt 768 | convernum(funct, 6, os);//funct 769 | os << endl; 770 | } 771 | 772 | //type 12 instruction 773 | // xxx rd 774 | else if(type12.count(ins)==1){ 775 | 776 | // rd 777 | is.getline(arg1, 150); 778 | int rd = converReg(arg1, true); 779 | if(rd ==-1) cout << "error in line " << linenum << endl; 780 | 781 | //funct 782 | int funct = type12.find(ins)->second; 783 | 784 | convernum(0, 6, os); //op 785 | convernum(0, 10, os); //rs+rt 786 | convernum(rd, 5, os); //rd 787 | convernum(0, 5, os); //shamt 788 | convernum(funct, 6, os);//funct 789 | os << endl; 790 | } 791 | 792 | //type 13 instruction 793 | // xxx rs, imm 794 | else if(type13.count(ins)==1){ 795 | 796 | // rs 797 | is.getline(arg1, 150, ','); 798 | int rs = converReg(arg1); 799 | if(rs ==-1) cout << "error in line " << linenum << endl; 800 | // imm 801 | is.getline(arg2, 150); 802 | int imm = 0; 803 | if(!charToNum(arg2, imm, true)) 804 | cout << "error in line " << linenum << endl; 805 | 806 | //rt 807 | int rt = type13.find(ins)->second; 808 | 809 | convernum(1, 6, os); //opcode = 1 810 | convernum(rs, 5, os); //rs 811 | convernum(rt, 5, os); //rt 812 | convernum(imm, 16, os); //imm 813 | os << endl; 814 | } 815 | 816 | //type 14 instruction 817 | // xxx rt, address 818 | else if(type14.count(ins)==1){ 819 | 820 | // rt 821 | is.getline(arg1, 150, ','); 822 | int rt = converReg(arg1); 823 | if(rt ==-1) 824 | cout << "error in line " << linenum << endl; 825 | 826 | // rs, imm 827 | is.getline(arg2, 150); 828 | int rs, imm; 829 | if(!converArray(arg2,rs,imm)) 830 | cout << "error in line " << linenum << endl; 831 | 832 | //op 833 | int op = type14.find(ins)->second; 834 | 835 | convernum(op, 6, os); //op 836 | convernum(rs, 5, os); //rs 837 | convernum(rt, 5, os); //rt 838 | convernum(imm, 16, os); //imm 839 | os << endl; 840 | } 841 | 842 | //type 15 instruction 843 | // lui rt, imm 844 | else if(!strcmp(ins, "lui")){ 845 | 846 | // rt 847 | is.getline(arg1, 150, ','); 848 | int rt = converReg(arg1); 849 | if(rt ==-1) 850 | cout << "error in line " << linenum << endl; 851 | 852 | // imm 853 | is.getline(arg2, 150); 854 | int imm = 0; 855 | if(!charToNum(arg2, imm, true)) 856 | cout << "error in line " << linenum << endl; 857 | 858 | //op 859 | int op = type15; 860 | 861 | convernum(op, 6, os); //op 862 | convernum(0, 5, os); //rs 863 | convernum(rt, 5, os); //rt 864 | convernum(imm, 16, os); //imm 865 | os << endl; 866 | } 867 | 868 | //type 16 instruction 869 | // jalr rs, rd 870 | else if(!strcmp(ins, "jalr")){ 871 | 872 | // rs 873 | is.getline(arg1, 150, ','); 874 | int rs = converReg(arg1); 875 | if(rs ==-1) 876 | cout << "error in line " << linenum << endl; 877 | 878 | // rd 879 | is.getline(arg2, 150); 880 | int rd = converReg(arg2, true); 881 | if(rd==-1) 882 | cout << "error in line " << linenum << endl; 883 | 884 | 885 | //funct 886 | int funct = type16; 887 | 888 | convernum(0, 6, os); //op 889 | convernum(rs, 5, os); //rs 890 | convernum(0, 5, os); //rt 891 | convernum(rd, 5, os); //rd 892 | convernum(0, 5, os); //shamt 893 | convernum(funct, 6, os); //funct 894 | os << endl; 895 | } 896 | 897 | else{ 898 | cout << "error in line " << linenum << endl; 899 | os << endl; 900 | getline(is, cache); 901 | } 902 | } 903 | } 904 | -------------------------------------------------------------------------------- /assignment1/MIPSassembler.h: -------------------------------------------------------------------------------- 1 | #ifndef HEADER_H 2 | #define HEADER_H 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | //create the address for the outputfile 9 | std::string newaddress(std::string input, std::string output); 10 | 11 | //input the number to the os stream in binary form 12 | void convernum(int num, int size, std::ostream & os); 13 | 14 | //transfer the register to number 15 | int converReg(char* code, bool end = false); 16 | 17 | // onvert the "imm(register)" to binary form 18 | int converArray(char* code); 19 | 20 | //transfer the char[] to num 21 | bool charToNum(char* string, int & num, bool end = false); 22 | 23 | //extrace the label 24 | bool labelextrace(char* label, char* & labelholder); 25 | 26 | // scan first to find the label 27 | void firstscan(std::string filename, std::map & labels, std::map & numOfEmpty); 28 | 29 | // transfer the mips code to machine code 30 | void mipsToMachinecode(std::istream & is, std::ostream & os, std::map labels, std::map numOfEmpty); 31 | 32 | 33 | #endif // HEADER_H 34 | -------------------------------------------------------------------------------- /assignment1/report.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MoyuST/CSC3050-Computer-Architecture/e4dc51b0300e825618730de590b45da707f6adf1/assignment1/report.pdf -------------------------------------------------------------------------------- /assignment1/testfile.asm: -------------------------------------------------------------------------------- 1 | R: add $s0, $s1, $s2 #r instruction 2 | add $s0, $s1, $s2 3 | sub s0, $s1, $s2 4 | subu $s0, $s1, $s2 5 | and $s0, $s1, $s2 6 | or $s0, $s1, $s2 7 | nor $s0, $s1, $s2 8 | xor $t0, $t1, $t2 9 | div $t1, $t2 10 | divu $t4, $t2 11 | sll $s0, $s1, 10 12 | srl $s0, $s1, 10 13 | slt $s0, $s1, $s3 14 | sltu $s0, $s1, $s3 15 | jr $ra 16 | mfhi $t3 17 | mflo $s2 18 | mult $t2, $t3 19 | multu $t1, $t0 20 | 21 | 22 | 23 | I: addi $s0, $s1, -100 24 | addiu $s0, $s1, 100 25 | andi $s0, $s1, 100 26 | 27 | 28 | ori $s0, $s1, 100 29 | slti $s0, $s1, 100 30 | sltiu $s0, $s1, 100 31 | beq $s0, $s1, I 32 | bne $s0, $s1, R 33 | bgez $s0, I 34 | bltz $s1, I 35 | lw $s0, 100($s1) 36 | 37 | sw $s0, 100($s1) #123 38 | lui $s0, 100 #2 39 | 40 | 41 | 42 | 43 | J: 44 | j I 45 | jal R -------------------------------------------------------------------------------- /assignment2/3.txt: -------------------------------------------------------------------------------- 1 | .data 2 | 3 | .text 4 | main: 5 | addi $a0, $zero, 4 6 | addi $v0, $zero, 9 7 | syscall 8 | sub $t0, $v0, $zero 9 | addi $a0, $zero, 4 10 | addi $v0, $zero, 9 11 | syscall 12 | sub $a0, $v0, $zero 13 | addi $a1, $zero, 4 14 | addi $v0, $zero, 8 15 | syscall 16 | lw $t1, 0($a0) 17 | sw $t1, 0($t0) 18 | sub $a0, $t0, $zero 19 | addi $v0, $zero, 4 20 | syscall 21 | addi $v0, $zero, 10 22 | syscall 23 | -------------------------------------------------------------------------------- /assignment2/4.txt: -------------------------------------------------------------------------------- 1 | .data 2 | 3 | .text 4 | addi $v0, $zero, 12 5 | syscall 6 | addi $a0, $v0, 1 7 | addi $v0, $zero, 11 8 | syscall 9 | addi $v0, $zero, 10 10 | syscall 11 | 12 | #take input and gets next char in ascii table -------------------------------------------------------------------------------- /assignment2/MIPSassembler.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include "MIPSassembler.h" 7 | 8 | using namespace std; 9 | 10 | //name of the register 11 | const char* Reg[32] = { 12 | "zero", "at", "v0", "v1", "a0", "a1", "a2", "a3", 13 | "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7", 14 | "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", 15 | "t8", "t9", "k0", "k1", "gp", "sp", "fp", "ra" 16 | }; 17 | 18 | // different types of mips code 19 | // xxx rd, rs, rt (notice: the opcode for mul is 0x1c) 20 | map 21 | type1 ={ //(name, funct) 22 | make_pair("add", 0x20), make_pair("addu", 0x21), make_pair("and", 0x24), 23 | make_pair("mul", 2), make_pair("nor", 0x27), make_pair("or", 0x25), 24 | make_pair("sub", 0x22), make_pair("subu", 0x23), make_pair("xor", 0x26), 25 | make_pair("slt", 0x2a), make_pair("sltu", 0x2b) 26 | }, 27 | 28 | //xxx rt, rs, imm 29 | type2 ={ //(name, opcode) 30 | make_pair("addi", 8), make_pair("addiu", 9), make_pair("andi", 0xc), 31 | make_pair("ori", 0xd), make_pair("xori", 0xe), make_pair("slti", 0xa), 32 | make_pair("sltiu", 0xb) 33 | }, 34 | 35 | //xxx rd, rs 36 | type3 ={ //(name, funct) 37 | make_pair("clo", 0x21), make_pair("clz", 0x20) 38 | }, 39 | 40 | //xxx rs, rt and opcode == 0 41 | type4 ={ //(name, funct) 42 | make_pair("div", 0x1a), make_pair("divu", 0x1b), make_pair("mult", 0x18), 43 | make_pair("multu", 0x19), make_pair("teq", 0x34), make_pair("tne", 0x36), 44 | make_pair("tge", 0x30), make_pair("tgeu", 0x31), make_pair("tlt", 0x32), 45 | make_pair("tltu", 0x33) 46 | }, 47 | 48 | //xxx rs, rt and opcode == 0x1c 49 | type5 ={ //(name, funct) 50 | make_pair("madd", 0), make_pair("maddu", 1), make_pair("msub", 4), 51 | make_pair("msubu", 5) 52 | }, 53 | 54 | //xxx rd, rt shamt 55 | type6 ={ //(name, funct) 56 | make_pair("sll", 0), make_pair("sra", 3), make_pair("srl", 2) 57 | }, 58 | //xxx rd, rt, rs 59 | type7 ={ //(name, funct) 60 | make_pair("sllv", 4), make_pair("srav", 7), make_pair("srlv", 6) 61 | }, 62 | 63 | //xxx rs, rt, label 64 | type8 ={ //(name, op) 65 | make_pair("beq", 4), make_pair("bne", 5) 66 | }, 67 | 68 | //xxx rs, label 69 | //since this type of operations have different opcode and rt code 70 | //so use two maps to store them 71 | type9 ={ //(name, op) 72 | make_pair("bgez", 1), make_pair("bgezal", 1), make_pair("bgtz", 7), 73 | make_pair("blez", 6), make_pair("bltzal", 1), make_pair("bltz", 1) 74 | }, 75 | 76 | type9_2 ={ //(name, rt) 77 | make_pair("bgez", 1), make_pair("bgezal", 0x11), make_pair("bgtz", 0), 78 | make_pair("blez",0), make_pair("bltzal", 0x10), make_pair("bltz", 0) 79 | }, 80 | 81 | //xxx target 82 | type10 ={ //(name, op) 83 | make_pair("j", 2), make_pair("jal", 3) 84 | }, 85 | 86 | //xxx rs 87 | type11 ={ //(name, funct) 88 | make_pair("jr", 8), make_pair("mthi", 0x11), make_pair("mtlo", 0x13) 89 | }, 90 | 91 | //xxx rd 92 | type12 ={ //(name, funct) 93 | make_pair("mfhi", 0x10), make_pair("mflo", 0x12) 94 | }, 95 | 96 | //xxx rs, imm 97 | type13 ={ //(name, rt) 98 | make_pair("teqi", 0xc), make_pair("tnei", 0xe), make_pair("tgei", 8), 99 | make_pair("tgeiu", 9), make_pair("tlti", 0xa), make_pair("tltiu", 0xb) 100 | }, 101 | 102 | //xxx rt, address 103 | type14 ={ //(name, op) 104 | make_pair("lb", 0x20), make_pair("lbu", 0x24), make_pair("lh", 0x21), 105 | make_pair("lhu", 0x25), make_pair("lw", 0x23), make_pair("lwcl", 0x31), 106 | make_pair("lwl", 0x22), make_pair("lwr", 0x26), make_pair("ll", 0x30), 107 | make_pair("sb", 0x28), make_pair("sh", 0x29), make_pair("sw", 0x2b), 108 | make_pair("swcl", 0x31), make_pair("swl", 0x2a), make_pair("swr", 0x2e), 109 | make_pair("sc", 0x38) 110 | }; 111 | 112 | //xxx rt, imm 113 | //there is only one of this type, only need to store the opcode 114 | const int type15 = 0xf; 115 | 116 | //xxx rs, rd 117 | //there is only one of this type, only need to store the funct code 118 | const int type16 = 9; 119 | 120 | int mispAssemble(int argc, char argv1[], char argv2[]){ 121 | // check the format of input 122 | 123 | if (argc != 3){ 124 | cout << "please enter the names of the input and output files" << endl; 125 | return -1; 126 | } 127 | 128 | //create a map to store the addresses for the labels 129 | map labels; 130 | 131 | //create a map to store the line number of the counter 132 | map numOfCounter; 133 | 134 | string out_path; //the address for the output file 135 | out_path = newaddress(argv1, argv2); //create the address for outfile 136 | 137 | ifstream infile(argv1); 138 | 139 | // try to open the file 140 | if(infile.fail()){ 141 | cout << "failed to open the file" << endl; 142 | infile.close(); 143 | return -1; 144 | } 145 | 146 | ofstream outfile(out_path); 147 | 148 | //store the labels and lines of the instruction 149 | firstscan(argv1, labels, numOfCounter); 150 | 151 | //transfer the MIPS code 152 | mipsToMachinecode(infile, outfile, labels, numOfCounter); 153 | 154 | cout << "Output in " << out_path << endl; 155 | infile.close(); 156 | outfile.close(); 157 | return 0; 158 | } 159 | 160 | //create the address for the outputfile 161 | string newaddress(string input, string output){ 162 | int endposi = -1; 163 | for(int i = input.length()-1; i>=0; i--){ 164 | if(input[i]=='/'){ 165 | endposi=i; 166 | break; 167 | } 168 | } 169 | //if there is no path in the input 170 | if(endposi==-1) return output; 171 | //if there is path in the output 172 | return input.substr(0,endposi+1)+output; 173 | } 174 | 175 | //input the number to the os stream in binary form 176 | void convernum(int num, int size, ostream & os){ 177 | int flag=0; 178 | if(num<0){ 179 | flag=1; 180 | num *= -1; //change num to the absolute value 181 | } 182 | 183 | if(flag){ // conver the negative num to 2's complete form 184 | int mask=1; 185 | mask <<= (size); 186 | mask -= 1; 187 | num = num^mask; 188 | num += 1; 189 | } 190 | 191 | int a = 1; 192 | a = (1<<(size-1)); 193 | 194 | for(int i = 0; i < size ; i++){ 195 | if (num&a) os << 1; 196 | else os << 0; 197 | 198 | num <<= 1; 199 | } 200 | } 201 | 202 | //transfer the register to number 203 | int converReg(char* code, bool end){ 204 | char codeholder[20] = ""; 205 | char *p = code; 206 | 207 | while(*p==' '||*p=='\t') p++; //skip all the space 208 | if(*p == '$') p++; 209 | else return -1; //no register found 210 | 211 | //extract the register out 212 | int i=0; 213 | while(*p!='\0' && (*p !=' '&& *p!='\t')){ 214 | i++; 215 | p++; 216 | } 217 | strncpy(codeholder, p-i, i); 218 | 219 | int num = -1; 220 | //convert the name of register to number 221 | for(int j=0; j<32; j++){ 222 | if(num!=-1) break; 223 | if(!strcmp(codeholder, Reg[j])) num = j; 224 | } 225 | 226 | //check whether there are invalid characters after the register 227 | while (*p == ' '|| *p=='\t') p++; //skip the space after the register 228 | 229 | //check whether there might be comments followed 230 | if(end){ 231 | if(*p=='#') return num; 232 | } 233 | 234 | if (*p != '\0') return -1; 235 | else return num; 236 | 237 | } 238 | 239 | // convert the "imm(register)" 240 | bool converArray(char* code, int & rs, int & imm){ 241 | char codeholder[20]= ""; 242 | char *p = code; 243 | imm = 0; 244 | int sign=1; 245 | 246 | while(*p==' '||*p=='\t') p++; //skip all the space 247 | if(*p=='-'){ 248 | sign=-1; 249 | p++; 250 | } 251 | 252 | // invalid 253 | if(*p<'0'||*p>'9') return false; 254 | 255 | while(*p>='0' && *p<='9'){ 256 | imm = 10*imm + (*p-'0'); 257 | p++; 258 | } 259 | imm *= sign; 260 | 261 | //invalid input 262 | if(*p!='(') return false; 263 | p++; 264 | 265 | int i = 0; 266 | while(*p!='\0' && *p!=')'){ 267 | i++; 268 | p++; 269 | } 270 | 271 | //no value in the bracket 272 | if(*p!=')') return false; 273 | 274 | strncpy(codeholder, p-i, i); 275 | rs = converReg(codeholder, true); 276 | if(rs==-1) return false; 277 | 278 | return true; 279 | } 280 | 281 | //transfer the char[] to num, if failed return false 282 | bool charToNum(char* string, int & num, bool end){ 283 | int p = 0; 284 | int sign = 1; 285 | num = 0; 286 | int length = int(strlen(string)); 287 | 288 | while(p='0'){ 295 | num = 10 * num + (string[p] - '0'); 296 | p++; 297 | } 298 | num *= sign; 299 | 300 | while(p & labels, map & numOfCounter){ 337 | ifstream infile(filename); 338 | string line; 339 | 340 | //skip the .data and .text 341 | int numOfDot=0; 342 | while(infile >> line){ 343 | if(line[0]=='.') numOfDot++; 344 | if(numOfDot==2) break; 345 | getline(infile, line); 346 | } 347 | 348 | int counter = -1; 349 | int linenum = 0; 350 | while(getline(infile, line)){ 351 | counter++; 352 | linenum++; 353 | 354 | int ps=0; // start of the label 355 | int pe=0; // end of the label 356 | int length = line.length(); 357 | 358 | // skip of the space 359 | while( pssecond += 1; 365 | counter--; 366 | continue; 367 | } 368 | 369 | pe = ps; 370 | while(pe (label, counter)); 388 | 389 | //not followed by instruction 390 | if(line[pe]=='\0' || line[pe]=='#'){ 391 | if(!numOfCounter.count(counter)) numOfCounter.insert(make_pair(counter, linenum+1)); 392 | else numOfCounter.find(counter)->second += 1; 393 | counter--; 394 | } 395 | 396 | } 397 | infile.close(); 398 | 399 | } 400 | 401 | // transfer the mips code to machine code 402 | void mipsToMachinecode(istream & is, ostream & os, map labels, map numOfCounter){ 403 | char ins[50], arg1[150], arg2[150], arg3[150]; //hold the instruction and arguements 404 | int linenum = 0; //count the line number 405 | int counter = -1; 406 | char syscall[] = "syscall"; 407 | string cache; 408 | 409 | //skip the .data and .text 410 | int numOfDot=0; 411 | while(is >> cache){ 412 | if(cache[0]=='.') numOfDot++; 413 | if(numOfDot==2) break; 414 | getline(is, cache); 415 | } 416 | 417 | while (is >> ins){ 418 | counter++; 419 | 420 | // skip the label if the label is not followed by instruction 421 | if(ins[strlen(ins)-1]==':'){ 422 | counter--; 423 | continue; 424 | } 425 | 426 | linenum++; 427 | 428 | // skip the line of the comments 429 | if (ins[0]=='#') { 430 | getline(is, cache); 431 | counter--; 432 | continue; 433 | } 434 | 435 | // update the line number for counter 436 | if(numOfCounter.count(counter)){ 437 | linenum = numOfCounter.find(counter)->second; 438 | } 439 | 440 | //syscall 441 | if(!strcmp(ins, syscall)){ 442 | convernum(0xc, 32, os); 443 | os << endl; 444 | continue; 445 | } 446 | 447 | //type 1 instruction 448 | // xxx rd, rs, rt (notice: the opcode for mul is 0x1c) 449 | if(type1.count(ins)==1){ 450 | int op = 0; 451 | if(!strcmp(ins, "mul")) op=0x1c; 452 | 453 | // rd 454 | is.getline(arg1, 150, ','); 455 | int rd = converReg(arg1); 456 | if(rd==-1) 457 | cout << "error in line " << linenum << endl; 458 | 459 | // rs 460 | is.getline(arg2, 150, ','); 461 | int rs = converReg(arg2); 462 | if(rs==-1) 463 | cout << "error in line " << linenum << endl; 464 | 465 | // rt 466 | is.getline(arg3, 150); 467 | int rt = converReg(arg3, true); 468 | if(rt==-1) 469 | cout << "error in line " << linenum << endl; 470 | 471 | //funct 472 | int funct = type1.find(ins)->second; 473 | 474 | convernum(op, 6, os); //opcode 475 | convernum(rs, 5, os); //rs 476 | convernum(rt, 5, os); //rt 477 | convernum(rd, 5, os); //rd 478 | convernum(0, 5, os); //shamt 479 | convernum(funct, 6, os); //funct 480 | os << endl; 481 | 482 | } 483 | 484 | //type 2 instruction 485 | // xxx rt, rs, imm 486 | else if(type2.count(ins)==1){ 487 | 488 | // rt 489 | is.getline(arg1, 150, ','); 490 | int rt = converReg(arg1); 491 | if(rt==-1) 492 | cout << "error in line " << linenum << endl; 493 | 494 | // rs 495 | is.getline(arg2, 150, ','); 496 | int rs = converReg(arg2); 497 | if(rs==-1) 498 | cout << "error in line " << linenum << endl; 499 | 500 | // imm 501 | is.getline(arg3, 150); 502 | int imm = 0; 503 | if(!charToNum(arg3, imm, true)) 504 | cout << "error in line " << linenum << endl; 505 | 506 | //op 507 | int op = type2.find(ins)->second; 508 | 509 | convernum(op, 6, os); //opcode 510 | convernum(rs, 5, os); //rs 511 | convernum(rt, 5, os); //rt 512 | convernum(imm, 16, os); //imm 513 | os << endl; 514 | 515 | } 516 | 517 | //type 3 instruction 518 | // xxx rd, rs 519 | else if(type3.count(ins)==1){ 520 | 521 | // rd 522 | is.getline(arg1, 150, ','); 523 | int rd = converReg(arg1); 524 | if(rd==-1) 525 | cout << "error in line " << linenum << endl; 526 | // rs 527 | is.getline(arg2, 150); 528 | int rs = converReg(arg2, true); 529 | if(rs==-1) 530 | cout << "error in line " << linenum << endl; 531 | 532 | //funct 533 | int funct = type3.find(ins)->second; 534 | 535 | convernum(0x1c, 6, os); //opcode=0x1c 536 | convernum(rs, 5, os); //rs 537 | convernum(0, 5, os); //rt 538 | convernum(rd, 5, os); //rd 539 | convernum(0, 5, os); //shamt 540 | convernum(funct, 6, os); //funct 541 | os << endl; 542 | 543 | } 544 | 545 | //type 4 instruction 546 | // xxx rt, rs with opcode=0 547 | else if(type4.count(ins)==1){ 548 | 549 | // rs 550 | 551 | is.getline(arg1, 150, ','); 552 | int rs = converReg(arg1); 553 | if(rs==-1) 554 | cout << "error in line " << linenum << endl; 555 | 556 | // rt 557 | is.getline(arg2, 150); 558 | int rt = converReg(arg2, true); 559 | if(rt==-1) 560 | cout << "error in line " << linenum << endl; 561 | 562 | //funct 563 | int funct = type4.find(ins)->second; 564 | 565 | convernum(0, 6, os); //opcode=0 566 | convernum(rs, 5, os); //rs 567 | convernum(rt, 5, os); //rt 568 | convernum(0, 10, os); //rd+shamt 569 | convernum(funct, 6, os); //funct 570 | os << endl; 571 | } 572 | 573 | //type 5 instruction 574 | // xxx rt, rs with opcode=0x1c 575 | else if(type5.count(ins)==1){ 576 | 577 | // rs 578 | is.getline(arg1, 150, ','); 579 | int rs = converReg(arg1); 580 | if(rs==-1) 581 | cout << "error in line " << linenum << endl; 582 | 583 | // rt 584 | is.getline(arg2, 150); 585 | int rt = converReg(arg2, true); 586 | if(rt==-1) 587 | cout << "error in line " << linenum << endl; 588 | 589 | //funct 590 | int funct = type5.find(ins)->second; 591 | 592 | convernum(0x1c, 6, os); //opcode=0x1c 593 | convernum(rs, 5, os); //rs 594 | convernum(rt, 5, os); //rt 595 | convernum(0, 10, os); //rd+shamt 596 | convernum(funct, 6, os); //funct 597 | os << endl; 598 | 599 | } 600 | 601 | //type 6 instruction 602 | // xxx rd, rt, shamt 603 | else if(type6.count(ins)==1){ 604 | 605 | // rd 606 | is.getline(arg1, 150, ','); 607 | int rd = converReg(arg1); 608 | if(rd ==-1) 609 | cout << "error in line " << linenum << endl; 610 | 611 | // rt 612 | is.getline(arg2, 150, ','); 613 | int rt = converReg(arg2); 614 | if(rt==-1) 615 | cout << "error in line " << linenum << endl; 616 | 617 | // shamt 618 | is.getline(arg3, 150); 619 | int shamt = 0; 620 | if(!charToNum(arg3, shamt, true)) 621 | cout << "error in line " << linenum << endl; 622 | 623 | //funct 624 | int funct = type6.find(ins)->second; 625 | 626 | convernum(0, 6, os); //op 627 | convernum(0, 5, os); //rs 628 | convernum(rt, 5, os); //rt 629 | convernum(rd, 5, os); //rd 630 | convernum(shamt, 5, os); //shamt 631 | convernum(funct, 6, os); //funct 632 | os << endl; 633 | 634 | } 635 | 636 | //type 7 instruction 637 | // xxx rd, rt, rs 638 | else if(type7.count(ins)==1){ 639 | 640 | // rd 641 | is.getline(arg1, 150, ','); 642 | int rd = converReg(arg1); 643 | if(rd ==-1) 644 | cout << "error in line " << linenum << endl; 645 | 646 | // rt 647 | is.getline(arg2, 150, ','); 648 | int rt = converReg(arg2); 649 | if(rt==-1) 650 | cout << "error in line " << linenum << endl; 651 | 652 | // rs 653 | is.getline(arg3, 150); 654 | int rs = converReg(arg3, true); 655 | if(rs==-1) 656 | cout << "error in line " << linenum << endl; 657 | 658 | //funct 659 | int funct = type7.find(ins)->second; 660 | 661 | convernum(0, 6, os); //op 662 | convernum(rs, 5, os); //rs 663 | convernum(rt, 5, os); //rt 664 | convernum(rd, 5, os); //rd 665 | convernum(0, 5, os); //shamt 666 | convernum(funct, 6, os); //funct 667 | os << endl; 668 | 669 | } 670 | 671 | //type 8 instruction 672 | // xxx rs, rt, label/offset 673 | else if(type8.count(ins)==1){ 674 | 675 | // rs 676 | is.getline(arg1, 150, ','); 677 | int rs = converReg(arg1); 678 | if(rs ==-1) 679 | cout << "error in line " << linenum << endl; 680 | 681 | // rt 682 | is.getline(arg2, 150, ','); 683 | int rt = converReg(arg2); 684 | if(rt==-1) 685 | cout << "error in line " << linenum << endl; 686 | 687 | // label/offset 688 | is.getline(arg3, 150); 689 | int offset; 690 | char labelholder[150] = ""; 691 | char *p =labelholder; 692 | 693 | //it is a label 694 | if(labelextrace(arg3, p)&&labels.count(labelholder)){ 695 | offset = labels.find(labelholder)->second - counter - 1; 696 | } 697 | // it is the offset 698 | else if(charToNum(arg3,offset,true)); 699 | //invalid 700 | else cout << "error in line " << linenum << endl; 701 | 702 | //op 703 | int op = type8.find(ins)->second; 704 | 705 | convernum(op, 6, os); //op 706 | convernum(rs, 5, os); //rs 707 | convernum(rt, 5, os); //rt 708 | convernum(offset, 16, os); //offset 709 | os << endl; 710 | 711 | } 712 | 713 | //type 9 instruction 714 | // xxx rs, label 715 | else if(type9.count(ins)==1){ 716 | 717 | // rs 718 | is.getline(arg1, 150, ','); 719 | int rs = converReg(arg1); 720 | if(rs ==-1) cout << "error in line " << linenum << endl; 721 | 722 | // label 723 | is.getline(arg2, 150); 724 | int offset; 725 | char labelholder[150] = ""; 726 | char *p =labelholder; 727 | 728 | //it is a label 729 | if(labelextrace(arg2, p)&&labels.count(labelholder)){ 730 | offset = labels.find(labelholder)->second - counter - 1; 731 | } 732 | // it is the offset 733 | else if(charToNum(arg2,offset,true)); 734 | //invalid 735 | else cout << "error in line " << linenum << endl; 736 | 737 | //op 738 | int op = type9.find(ins)->second; 739 | 740 | //rt 741 | int rt = type9_2.find(ins)->second; 742 | 743 | convernum(op, 6, os); //opcode=0x1c 744 | convernum(rs, 5, os); //rs 745 | convernum(rt, 5, os); //rt 746 | convernum(offset, 16, os); //offset 747 | os << endl; 748 | 749 | } 750 | 751 | //type 10 instruction 752 | // xxx target 753 | else if(type10.count(ins)==1){ 754 | 755 | // label 756 | is.getline(arg1, 150); 757 | int target; 758 | char labelholder[150] = ""; 759 | char *p =labelholder; 760 | 761 | //it is a label 762 | if(labelextrace(arg1, p)&&labels.count(labelholder)){ 763 | target = labels.find(labelholder)->second; 764 | } 765 | // it is the address 766 | else if(charToNum(arg1,target,true)); 767 | //invalid 768 | else cout << "error in line " << linenum << endl; 769 | 770 | //remove the first 4 digits of the target and shift right 2 bits 771 | target *= 4; 772 | target += 0x400000; 773 | target = target & 0x0ffffffff; 774 | target >>= 2; 775 | 776 | //op 777 | int op = type10.find(ins)->second; 778 | 779 | convernum(op, 6, os); //opcode=0x1c 780 | convernum(target, 26, os); //target 781 | os << endl; 782 | } 783 | 784 | //type 11 instruction 785 | // xxx rs 786 | else if(type11.count(ins)==1){ 787 | 788 | // rs 789 | is.getline(arg1, 150); 790 | int rs = converReg(arg1, true); 791 | if(rs ==-1) cout << "error in line " << linenum << endl; 792 | 793 | //funct 794 | int funct = type11.find(ins)->second; 795 | 796 | convernum(0, 6, os); //op 797 | convernum(rs, 5, os); //rs 798 | convernum(0, 15, os); //rt+rd+shamt 799 | convernum(funct, 6, os);//funct 800 | os << endl; 801 | 802 | } 803 | 804 | //type 12 instruction 805 | // xxx rd 806 | else if(type12.count(ins)==1){ 807 | 808 | // rd 809 | is.getline(arg1, 150); 810 | int rd = converReg(arg1, true); 811 | if(rd ==-1) cout << "error in line " << linenum << endl; 812 | 813 | //funct 814 | int funct = type12.find(ins)->second; 815 | 816 | convernum(0, 6, os); //op 817 | convernum(0, 10, os); //rs+rt 818 | convernum(rd, 5, os); //rd 819 | convernum(0, 5, os); //shamt 820 | convernum(funct, 6, os);//funct 821 | os << endl; 822 | 823 | } 824 | 825 | //type 13 instruction 826 | // xxx rs, imm 827 | else if(type13.count(ins)==1){ 828 | 829 | // rs 830 | is.getline(arg1, 150, ','); 831 | int rs = converReg(arg1); 832 | if(rs ==-1) cout << "error in line " << linenum << endl; 833 | // imm 834 | is.getline(arg2, 150); 835 | int imm = 0; 836 | if(!charToNum(arg2, imm, true)) 837 | cout << "error in line " << linenum << endl; 838 | 839 | //rt 840 | int rt = type13.find(ins)->second; 841 | 842 | convernum(1, 6, os); //opcode = 1 843 | convernum(rs, 5, os); //rs 844 | convernum(rt, 5, os); //rt 845 | convernum(imm, 16, os); //imm 846 | os << endl; 847 | } 848 | 849 | //type 14 instruction 850 | // xxx rt, address 851 | else if(type14.count(ins)==1){ 852 | 853 | // rt 854 | is.getline(arg1, 150, ','); 855 | int rt = converReg(arg1); 856 | if(rt ==-1) 857 | cout << "error in line " << linenum << endl; 858 | 859 | // rs, imm 860 | is.getline(arg2, 150); 861 | int rs, imm; 862 | if(!converArray(arg2,rs,imm)) 863 | cout << "error in line " << linenum << endl; 864 | 865 | //op 866 | int op = type14.find(ins)->second; 867 | 868 | convernum(op, 6, os); //op 869 | convernum(rs, 5, os); //rs 870 | convernum(rt, 5, os); //rt 871 | convernum(imm, 16, os); //imm 872 | os << endl; 873 | 874 | } 875 | 876 | //type 15 instruction 877 | // lui rt, imm 878 | else if(!strcmp(ins, "lui")){ 879 | 880 | // rt 881 | is.getline(arg1, 150, ','); 882 | int rt = converReg(arg1); 883 | if(rt ==-1) 884 | cout << "error in line " << linenum << endl; 885 | 886 | // imm 887 | is.getline(arg2, 150); 888 | int imm = 0; 889 | if(!charToNum(arg2, imm, true)) 890 | cout << "error in line " << linenum << endl; 891 | 892 | //op 893 | int op = type15; 894 | 895 | convernum(op, 6, os); //op 896 | convernum(0, 5, os); //rs 897 | convernum(rt, 5, os); //rt 898 | convernum(imm, 16, os); //imm 899 | os << endl; 900 | 901 | } 902 | 903 | //type 16 instruction 904 | // jalr rs, rd 905 | else if(!strcmp(ins, "jalr")){ 906 | 907 | // rs 908 | is.getline(arg1, 150, ','); 909 | int rs = converReg(arg1); 910 | if(rs ==-1) 911 | cout << "error in line " << linenum << endl; 912 | 913 | // rd 914 | is.getline(arg2, 150); 915 | int rd = converReg(arg2, true); 916 | if(rd==-1) 917 | cout << "error in line " << linenum << endl; 918 | 919 | 920 | //funct 921 | int funct = type16; 922 | 923 | convernum(0, 6, os); //op 924 | convernum(rs, 5, os); //rs 925 | convernum(0, 5, os); //rt 926 | convernum(rd, 5, os); //rd 927 | convernum(0, 5, os); //shamt 928 | convernum(funct, 6, os); //funct 929 | os << endl; 930 | } 931 | 932 | else{ 933 | cout << "error in line " << linenum << endl; 934 | os << endl; 935 | getline(is, cache); 936 | } 937 | } 938 | } 939 | -------------------------------------------------------------------------------- /assignment2/MIPSassembler.h: -------------------------------------------------------------------------------- 1 | #ifndef MIPSASSEMBLE_H 2 | #define MIPSASSEMBLE_H 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | //assemble the instruction to machine code 9 | int mispAssemble(int argc, char argv1[], char argv2[]); 10 | 11 | //create the address for the outputfile 12 | std::string newaddress(std::string input, std::string output); 13 | 14 | //input the number to the os stream in binary form 15 | void convernum(int num, int size, std::ostream & os); 16 | 17 | //transfer the register to number 18 | int converReg(char* code, bool end = false); 19 | 20 | // onvert the "imm(register)" to binary form 21 | int converArray(char* code); 22 | 23 | //transfer the char[] to num 24 | bool charToNum(char* string, int & num, bool end = false); 25 | 26 | //extrace the label 27 | bool labelextrace(char* label, char* & labelholder); 28 | 29 | // scan first to find the label 30 | void firstscan(std::string filename, std::map & labels, std::map & numOfEmpty); 31 | 32 | // transfer the mips code to machine code 33 | void mipsToMachinecode(std::istream & is, int * pint, std::map labels, std::map numOfEmpty); 34 | 35 | // convert a mips file to machine code and store it in the memory 36 | void mipsToMachinecode(std::istream & is, std::ostream & os, std::map labels, std::map numOfEmpty); 37 | 38 | extern std::map 39 | type1, type2, type3, type3, type5, type6, type7, type8, 40 | type9, type9_2, type10, type11, type12, type13, type14; 41 | 42 | 43 | #endif // MIPSASSEMBLE_H 44 | -------------------------------------------------------------------------------- /assignment2/MIPSsimulator.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | //#include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include "MIPSsimulator.h" 9 | #include "MIPSassembler.h" 10 | #include "dataHandler.h" 11 | 12 | using namespace std; 13 | 14 | unsigned int stringToCodes(string line); 15 | void storeMachindeCode(string filename, int * pdata); 16 | void excute(int & pc, unsigned codes); 17 | void Rins(unsigned int codes); 18 | void Iins(int mark, unsigned int codes, int type); 19 | void Jins(int, unsigned int); 20 | int * excute(int * pc); 21 | bool overflow(int x, int y); 22 | typedef void (*RIns) (int *, int *, int *, int); 23 | typedef void (*IIns) (int *, int *, int); 24 | typedef void (*JIns) (int); 25 | 26 | static map RFunctions={ 27 | {0x20, ADD}, {0x21, ADDU}, {0x24, AND}, {0x1a, DIV}, 28 | {0x1b, DIVU},{0x18, MULT}, {0x19, MULTU}, {0x27, NOR}, 29 | {0x25, OR}, {0, SLL}, {4, SLLV}, {3, SRA}, 30 | {7, SRAV}, {2, SRL}, {6, SRLV}, {0x22, SUB}, 31 | {0x23, SUBU},{0x26, XOR}, {0x2a, SLT}, {0x2b, SLTU}, 32 | {9, JALR}, {8, JR}, {0x34, TEQ}, {0x36, TNE}, 33 | {0x30, TGE}, {0x31, TGEU}, {0x32, TLT}, {0x33, TLTU}, 34 | {0x10, MFHI},{0x12, MFLO}, {0x11, MTHI}, {0x13, MTLO} 35 | }; 36 | 37 | static map IFunctions={ 38 | {0xf, LUI}, {8, ADDI}, {9, ADDIU},{0xc, ANDI}, {0xd, ORI}, 39 | {0x23, LW}, {0xe, XORI},{0xf, LUI},{0xa, SLTI}, 40 | {0xb, SLTIU},{4, BEQ}, {7, BGTZ}, {6, BLEZ}, {5, BNE}, 41 | {0x20, LB}, {0x24, LBU},{0x21, LH},{0x25, LHU}, 42 | {0x23, LW}, {0x22, LWL},{0x26, LWR},{0x30, LL}, 43 | {0x28, SB}, {0x29, SH}, {0x2b, SW}, {0x2a, SWL}, 44 | {0x2e, SWR},{0x38, SC} 45 | }; 46 | 47 | static map IFUNCTIONS_2 = { 48 | {1, BGEZ}, {0x11, BGEZAL}, {0x10, BLTZAL}, {0, BLTZ}, 49 | {0xc, TEQI},{0xe, TNEI}, {8, TGEI}, {9, TGEIU}, 50 | {0xa, TLTI}, {0xb, TLTIU} 51 | }; 52 | 53 | static map JFunctions={ 54 | {3, JAL}, {2, J} 55 | }; 56 | static int * pc; 57 | static int * textStart; 58 | static int flag = 0; 59 | static int * pReg; 60 | static int * hi; 61 | static int * lo; 62 | static int llbit=0; 63 | static int * dynamicdata; 64 | 65 | 66 | int main(int argc, char *argv[]){ 67 | 68 | unsigned int memorysize = 6 * 1024 * 1024; 69 | unsigned int registersize = 32 * 4; 70 | 71 | if (argc != 3){ 72 | cout << "please enter the names of the input and output files" << endl; 73 | return -1; 74 | } 75 | 76 | if(mispAssemble(3, argv[1], argv[2])==-1){ 77 | cout << "error in the instruction" << endl; 78 | return 0; 79 | } 80 | 81 | //allocate the memory 82 | char * p; 83 | p = (char*) malloc(memorysize); 84 | memset(p, 0, memorysize); 85 | 86 | //allocate the register 87 | pReg = (int *) malloc(registersize); 88 | memset(pReg, 0, registersize); 89 | //$sp 90 | pReg[29] = memorysize + 0x400000 - 1; 91 | //$fp 92 | pReg[30] = memorysize + 0x400000 - 1; 93 | //$gp 94 | pReg[28] = 1024*1024 + 0x400000; 95 | 96 | //allocate the hi and lo 97 | int * holder = (int *) malloc(4*2); 98 | hi = holder; 99 | lo = holder+1; 100 | 101 | // pointer for data segment 102 | int * pdataSeg = (int *) (p+1024*1024); 103 | 104 | //store the .data 105 | dynamicdata = dataHandle(argv[1], pdataSeg); 106 | 107 | string newaddr = newaddress(argv[1], argv[2]); 108 | storeMachindeCode(newaddr, (int *) p); 109 | 110 | pc = (int*) p; 111 | textStart = (int*) p; 112 | while((*pc)!=0){ 113 | if(flag) break; 114 | pc = excute(pc); 115 | } 116 | cout << "end address: "<< hex << (pc-textStart)*4+0x400000-4 << endl; 117 | } 118 | 119 | unsigned int stringToCodes(string line){ 120 | unsigned int holder = 0; 121 | unsigned int exp = 0; 122 | int leng = line.length(); 123 | 124 | for(int i = leng-1; i>-1; i--){ 125 | if(exp==0) exp=1; 126 | else exp *= 2; 127 | 128 | holder += (line[i]-'0')*exp; 129 | 130 | } 131 | return holder; 132 | } 133 | 134 | void storeMachindeCode(string filename, int * pdata){ 135 | ifstream infile(filename.c_str()); 136 | unsigned int * codes = (unsigned int *) pdata; 137 | string buffer; 138 | while(getline(infile, buffer)){ 139 | *codes = stringToCodes(buffer); 140 | codes++; 141 | } 142 | } 143 | 144 | int * excute(int * PC){ 145 | unsigned int codes = *PC; 146 | int opcode; 147 | opcode = (0xfc000000)&codes; 148 | opcode >>= 26; 149 | opcode &= 0x0000003f; 150 | 151 | if(codes==0xc){ 152 | SYSCALL(); 153 | return ++pc; 154 | } 155 | 156 | if(opcode == 0){ 157 | Rins(codes); 158 | return ++pc; 159 | } 160 | else if(opcode==2||opcode==3){ 161 | Jins(opcode, codes); 162 | return ++pc; 163 | } 164 | else{ 165 | if(opcode==1){ 166 | int rt; 167 | rt = 0x001f0000&codes; 168 | rt >>= 16; 169 | Iins(rt, codes, 1); 170 | } 171 | else Iins(opcode, codes, 0); 172 | return ++pc; 173 | } 174 | } 175 | 176 | bool overflow(int x, int y){ 177 | long long X = (long long) x; 178 | long long Y = (long long) y; 179 | long long sum = X + Y; 180 | if(sumINT_MAX){ 181 | return true; 182 | } 183 | return false; 184 | } 185 | 186 | void Rins(unsigned int codes){ 187 | int Rs = (codes&0x3e00000); 188 | Rs >>= 21; 189 | int * rs = (pReg+Rs); 190 | 191 | int Rt = (codes&0x1f0000); 192 | Rt >>= 16; 193 | int * rt = (pReg+Rt); 194 | 195 | int Rd = (codes&0xf800); 196 | Rd >>= 11; 197 | int * rd = (pReg+Rd); 198 | 199 | unsigned int shamt = (codes&0x7c0); 200 | shamt >>= 6; 201 | int funct = (codes&0x3f); 202 | RFunctions[funct](rs, rt, rd, shamt); 203 | } 204 | 205 | void Iins(int mark, unsigned int codes, int type){ 206 | int Rs = (codes&0x3e00000); 207 | Rs >>= 21; 208 | int * rs = (pReg+Rs); 209 | 210 | int Rt = (codes&0x1f0000); 211 | Rt >>= 16; 212 | int * rt = (pReg+Rt); 213 | 214 | int imm = (codes&0xffff); 215 | //transfer 2's complement 216 | if(imm&0x8000){ 217 | imm ^= 0xffff; 218 | imm +=1; 219 | imm *= -1; 220 | } 221 | if(type==0) IFunctions[mark](rs, rt, imm); 222 | else IFUNCTIONS_2[mark](rs, rt, imm); 223 | } 224 | 225 | void Jins(int opcode, unsigned int codes){ 226 | int target = (codes&0x3ffffff); 227 | target <<= 2; 228 | int curAddr = (pc-textStart) + 0x400000; 229 | curAddr &= 0xfc000000; 230 | target = curAddr|target; 231 | JFunctions[opcode](target); 232 | } 233 | 234 | //R funct = 0x20 235 | void ADD(int * rs, int * rt, int* rd, int shamt){ 236 | if(overflow(*rs, *rt)){ 237 | cout << "overflow" << endl; 238 | flag = 1; 239 | } 240 | else{ 241 | *rd = *rs + *rt; 242 | } 243 | } 244 | //R 0x21 245 | void ADDU(int * rs, int * rt, int* rd, int shamt){ 246 | *rd = *rs + *rt; 247 | } 248 | 249 | //I op=8 250 | void ADDI(int * rs, int * rt, int imm){ 251 | if(overflow(*rs, imm)){ 252 | cout << "overflow" << endl; 253 | flag = 1; 254 | } 255 | else{ 256 | // cout << "addi " << *rt << " " << *rs << " " << imm <>= 32; 301 | *hi = (int) result; 302 | } 303 | 304 | //R 0x19 305 | void MULTU(int * rs, int * rt, int* rd, int shamt){ 306 | unsigned long long RS = (long long) *rs; 307 | unsigned long long RT = (long long) *rt; 308 | unsigned long long result = RS * RT; 309 | *lo = (int) result; 310 | result >>= 32; 311 | *hi = (int) result; 312 | } 313 | 314 | //R 0x27 315 | void NOR(int * rs, int * rt, int* rd, int shamt){ 316 | *rd = ~(*rs | *rt); 317 | } 318 | 319 | // R 0x25 320 | void OR(int * rs, int * rt, int* rd, int shamt){ 321 | *rd = *rs | *rt; 322 | } 323 | 324 | // I 0xd 325 | void ORI(int * rs, int * rt, int imm){ 326 | // cout << "ORI " << endl; 327 | *rt = *rs | imm; 328 | } 329 | 330 | // R 0 331 | void SLL(int * rs, int * rt, int* rd, int shamt){ 332 | // cout << "rt: " << hex << *rt << " rd: " << *rd << " shamt " << shamt << dec<< endl; 333 | *rd = (*rt)<> shamt; 345 | } 346 | 347 | //R 7 348 | void SRAV(int * rs, int * rt, int* rd, int shamt){ 349 | *rd = (*rt) >> *rs; 350 | } 351 | 352 | // R 2 353 | void SRL(int * rs, int * rt, int* rd, int shamt){ 354 | unsigned RT = (unsigned) *rt; 355 | *rd = (RT >> shamt); 356 | } 357 | 358 | //R 6 359 | void SRLV(int * rs, int * rt, int* rd, int shamt){ 360 | unsigned RT = (unsigned) *rt; 361 | *rd = (RT >> (*rs)); 362 | } 363 | 364 | //R 0x22 365 | void SUB(int * rs, int * rt, int* rd, int shamt){ 366 | if(overflow(*rs, -(*rd))) flag = 1; 367 | else *rd = *rs - *rt; 368 | } 369 | 370 | //R 0x23 371 | void SUBU(int * rs, int * rt, int* rd, int shamt){ 372 | *rd = *rs - *rt; 373 | } 374 | 375 | //R 0x26 376 | void XOR(int * rs, int * rt, int* rd, int shamt){ 377 | *rd = *rs ^ *rt; 378 | } 379 | 380 | //I 0xe 381 | void XORI(int * rs, int * rt, int imm){ 382 | *rt = *rs ^ imm; 383 | } 384 | 385 | //I 0xf 386 | void LUI(int * rs, int * rt, int imm){ 387 | int lower = imm & 0xffff; 388 | lower <<= 16; 389 | *rt = lower; 390 | } 391 | 392 | //R 0x2a 393 | void SLT(int * rs, int * rt, int* rd, int shamt){ 394 | *rd = (*rs < *rt); 395 | } 396 | 397 | //R 0x2b 398 | void SLTU(int * rs, int * rt, int* rd, int shamt){ 399 | unsigned int RS = (unsigned int ) *rs; 400 | unsigned int RT = (unsigned int ) *rt; 401 | *rd = (RS < RT); 402 | } 403 | 404 | //I 0xa 405 | void SLTI(int * rs, int * rt, int imm){ 406 | *rt = (*rs < imm); 407 | } 408 | 409 | //I 0xb 410 | void SLTIU(int * rs, int * rt, int imm){ 411 | unsigned int RS = (unsigned int) *rs; 412 | unsigned int IMM = (unsigned int) imm; 413 | *rt = (RS < IMM); 414 | } 415 | 416 | //I 4 417 | void BEQ(int * rs, int * rt, int imm){ 418 | if(*rs==*rt) pc+= imm; 419 | } 420 | 421 | //? 422 | //B 1 1 423 | void BGEZ(int * rs, int * rt, int imm){ 424 | if(*rs>=0) pc+= imm; 425 | } 426 | 427 | //? ?register 428 | //B 1 0x11 429 | void BGEZAL(int * rs, int * rt, int imm){ 430 | if(*rs>=0){ 431 | pc += imm; 432 | pReg[31] = (pc-textStart)*4+(0x00400000); 433 | } 434 | } 435 | 436 | //? 437 | //B 7 0 438 | void BGTZ(int * rs, int * rt, int imm){ 439 | if(*rs>0) pc+= imm; 440 | } 441 | 442 | //? 443 | //B 6 444 | void BLEZ(int * rs, int * rt, int imm){ 445 | if(*rs<=0) pc+= imm; 446 | } 447 | 448 | //? ?register 449 | //B 1 0x10 450 | void BLTZAL(int * rs, int * rt, int imm){ 451 | if(*rs<0){ 452 | pc += imm; 453 | pReg[31] = (pc-textStart)*4+(0x00400000); 454 | } 455 | } 456 | 457 | //? ? 458 | //B 1 0 459 | void BLTZ(int * rs, int * rt, int imm){ 460 | if(*rs<0) pc += imm; 461 | } 462 | 463 | //I 5 464 | void BNE(int * rs, int * rt, int imm){ 465 | if(*rs != *rt) pc += imm; 466 | } 467 | 468 | //J 2 469 | void J(int target){ 470 | // cout << "J" << endl; 471 | target -= 0x400000; 472 | pc = textStart+(target/4)-1; 473 | } 474 | 475 | //J 3 476 | void JAL(int target){ 477 | // cout << "JAL" << endl; 478 | target -= 0x400000; 479 | pReg[31] = (pc-textStart)*4+0x400000; 480 | pc = textStart+(target/4)-1; 481 | } 482 | 483 | //????default 484 | //R 9 485 | void JALR(int * rs, int * rt, int* rd, int shamt){ 486 | *rd = (pc-textStart)*4+0x400000; 487 | pc = textStart+((*rs)-0x400000)/4-1; 488 | } 489 | 490 | //R 8 491 | void JR(int * rs, int * rt, int* rd, int shamt){ 492 | pc = textStart+((*rs)-(0x400000))/4; 493 | } 494 | 495 | //R 0x34 496 | void TEQ(int * rs, int * rt, int* rd, int shamt){ 497 | if(*rs == *rt) flag = 1; 498 | } 499 | 500 | //I 1 501 | //T 0xc 502 | void TEQI(int * rs, int * rt, int imm){ 503 | if(*rs == imm) flag=1; 504 | } 505 | 506 | //R 0x36 507 | void TNE(int * rs, int * rt, int* rd, int shamt){ 508 | if(*rs != *rt) flag = 1; 509 | } 510 | 511 | //I 1 512 | //T 0xe 513 | void TNEI(int * rs, int * rt, int imm){ 514 | if(*rs != imm) flag = 1; 515 | } 516 | 517 | //R 0x30 518 | void TGE(int * rs, int * rt, int* rd, int shamt){ 519 | if(*rs >= *rt) flag = 1; 520 | } 521 | 522 | //R 0x31 523 | void TGEU(int * rs, int * rt, int* rd, int shamt){ 524 | unsigned int RS = (unsigned int) (*rs); 525 | unsigned int RT = (unsigned int) (*rt); 526 | if(RS >= RT) flag = 1; 527 | } 528 | 529 | //I 1 530 | //T 8 531 | void TGEI(int * rs, int * rt, int imm){ 532 | if(*rs >= imm) flag = 1; 533 | } 534 | 535 | //I 1 536 | //T 9 537 | void TGEIU(int * rs, int * rt, int imm){ 538 | unsigned int RS = (unsigned int) (*rs); 539 | unsigned int IMM = (unsigned int) imm; 540 | if(RS >= IMM) flag = 1; 541 | } 542 | 543 | //R 0x32 544 | void TLT(int * rs, int * rt, int* rd, int shamt){ 545 | if(*rs < *rt) flag = 1; 546 | } 547 | 548 | //R 0x33 549 | void TLTU(int * rs, int * rt, int* rd, int shamt){ 550 | unsigned int RS = (unsigned int) (*rs); 551 | unsigned int RT = (unsigned int) (*rt); 552 | if(RS < RT) flag = 1; 553 | } 554 | 555 | //I 1 556 | //T a 557 | void TLTI(int * rs, int * rt, int imm){ 558 | if(*rs < imm) flag = 1; 559 | } 560 | 561 | //I 1 562 | //T b 563 | void TLTIU(int * rs, int * rt, int imm){ 564 | unsigned int RS = (unsigned int) (*rs); 565 | unsigned int IMM = (unsigned int) (imm); 566 | if(RS < IMM) flag = 1; 567 | } 568 | 569 | //I 0x20 570 | void LB(int * rs, int * rt, int imm){ 571 | int8_t * BYTE; 572 | int8_t * addr = (int8_t *) ((*rs-0x400000)/4+textStart); 573 | BYTE = (int8_t *)(addr+imm); 574 | *rt = *BYTE; 575 | } 576 | 577 | //I 0x24 578 | void LBU(int * rs, int * rt, int imm){ 579 | uint8_t * BYTE; 580 | uint8_t * addr = (uint8_t *) ((*rs-0x400000)/4+textStart); 581 | BYTE = (uint8_t *) (addr+imm); 582 | *rt = *BYTE; 583 | } 584 | 585 | //I 0x21 586 | void LH(int * rs, int * rt, int imm){ 587 | int16_t * halfword; 588 | int8_t * addr = (int8_t *) ((*rs-0x400000)/4+textStart); 589 | halfword = (int16_t *) (addr+imm); 590 | *rt = *halfword; 591 | } 592 | 593 | //I 0x25 594 | void LHU(int * rs, int * rt, int imm){ 595 | uint16_t * halhword; 596 | uint8_t * addr = (uint8_t *) ((*rs-0x400000)/4+textStart); 597 | halhword = (uint16_t *) (addr+imm); 598 | } 599 | 600 | //I 0x23 601 | void LW(int * rs, int * rt, int imm){ 602 | int * NUM; 603 | NUM = ((*rs-0x400000)/4+textStart+imm); 604 | *rt = *NUM; 605 | } 606 | 607 | //I 0x22 608 | void LWL(int * rs, int * rt, int imm){ 609 | int addr = *rs + imm*4; 610 | int remian = addr % 4; 611 | int num = 4 - remian; 612 | uint8_t *textST = (uint8_t *) textStart; 613 | uint8_t * newaddr = (uint8_t *) (addr-0x400000+textST); 614 | uint8_t * RT = (uint8_t *) rt; 615 | for(int i =0; i < num; i++){ 616 | *(RT+i) = * (newaddr+i); 617 | } 618 | } 619 | 620 | //I 0x26 621 | void LWR(int * rs, int * rt, int imm){ 622 | int addr = *rs + imm*4; 623 | int remain = (addr % 4) + 1; 624 | uint8_t * textST = (uint8_t *) textStart; 625 | uint8_t * newaddr = (uint8_t *) (addr-0x400000+textST); 626 | uint8_t * RT = (uint8_t *) rt + 3; 627 | for(int i =0; i < remain; i++){ 628 | *(RT-i) = * (newaddr-i); 629 | } 630 | } 631 | 632 | //I 0x30 633 | void LL(int * rs, int * rt, int imm){ 634 | int * NUM; 635 | NUM = ((*rs-0x400000)/4+textStart+imm); 636 | *rt = *NUM; 637 | llbit = 1; 638 | } 639 | 640 | //I 0x28 641 | //lower byte 642 | void SB(int * rs, int * rt, int imm){ 643 | uint8_t lowerbyte = uint8_t (*rt); 644 | int * addr; 645 | addr = (*rs-0x400000)/4+textStart+imm; 646 | *addr = lowerbyte; 647 | } 648 | 649 | //I 0x29 650 | void SH(int * rs, int * rt, int imm){ 651 | uint16_t lowerbyte = uint16_t (*rt); 652 | int * addr; 653 | addr = (*rs-0x400000)/4+textStart+imm; 654 | *addr = lowerbyte; 655 | } 656 | 657 | //I 0x2b 658 | void SW(int * rs, int * rt, int imm){ 659 | int * NUM; 660 | int off = (*rs-0x400000)/4+imm; 661 | NUM = (textStart+off); 662 | *NUM = *rt; 663 | } 664 | 665 | //I 0x2a 666 | void SWL(int * rs, int * rt, int imm){ 667 | int addr = *rs + imm*4; 668 | int remian = addr % 4; 669 | int num = 4 - remian; 670 | uint8_t *textST = (uint8_t *) textStart; 671 | uint8_t * newaddr = (uint8_t *) (addr-0x400000+textST); 672 | uint8_t * RT = (uint8_t *) rt; 673 | for(int i =0; i < num; i++){ 674 | * (newaddr+i) = *(RT+i) ; 675 | } 676 | } 677 | 678 | //I 0x2e 679 | void SWR(int * rs, int * rt, int imm){ 680 | int addr = *rs + imm*4; 681 | int remain = (addr % 4) + 1; 682 | uint8_t * textST = (uint8_t *) textStart; 683 | uint8_t * newaddr = (uint8_t *) (addr-0x400000+textST); 684 | uint8_t * RT = (uint8_t *) rt + 3; 685 | for(int i =0; i < remain; i++){ 686 | * (newaddr-i) = *(RT-i); 687 | } 688 | } 689 | 690 | //I 0x38 691 | void SC(int * rs, int * rt, int imm){ 692 | if(llbit==1){ 693 | int * NUM; 694 | NUM = ((*rs-0x400000)/4+textStart+imm); 695 | *NUM = *rt; 696 | *rt = 1; 697 | llbit = 0; 698 | } 699 | else{ 700 | *rt = 0; 701 | llbit = 1; 702 | } 703 | } 704 | 705 | //R 0x10 706 | void MFHI(int * rs, int * rt, int* rd, int shamt){ 707 | *rd = *hi; 708 | } 709 | 710 | //R 0x12 711 | void MFLO(int * rs, int * rt, int* rd, int shamt){ 712 | *rd = *lo; 713 | } 714 | 715 | //R 0x11 716 | void MTHI(int * rs, int * rt, int* rd, int shamt){ 717 | *hi = *rs; 718 | } 719 | 720 | //R 0x13 721 | void MTLO(int * rs, int * rt, int* rd, int shamt){ 722 | *lo = *rs; 723 | } 724 | 725 | void SYSCALL(){ 726 | //create a map for file operation 727 | static map filemap; 728 | static map filenamemap; 729 | static int filecount = 0; 730 | 731 | if(pReg[2]==1){ 732 | int * NUM = pReg+4; 733 | cout << "syscall out: "<< *NUM <> num; 744 | pReg[2] = num; 745 | } 746 | else if(pReg[2]==8){ 747 | string holder; 748 | string STR; 749 | char * textST = (char *) textStart; 750 | cout << "syscall: enter a string: "; 751 | cin >> holder; 752 | STR = holder.substr(0, pReg[5]); 753 | char * pchar = (char *) ((pReg[4]-0x400000)+textST); 754 | for(int i=0; i> holder; 776 | pReg[2] = holder; 777 | } 778 | else if(pReg[2]==13){ 779 | string filename; 780 | fstream testfile; 781 | char * textST = (char *) textStart; 782 | char * addr = (char *) ((pReg[4]-0x400000)+textST); 783 | int filedes; 784 | filename = addr; 785 | 786 | if(filenamemap.count(filename)){ 787 | filedes = filenamemap[filename]; 788 | } 789 | else{ 790 | filedes = filecount; 791 | filenamemap[filename] = filecount; 792 | } 793 | 794 | //read only 795 | if(pReg[5]==0) { 796 | filemap[filedes] = new fstream(filename.c_str(), ios::in); 797 | } 798 | //write only 799 | else if(pReg[5]==1){ 800 | filemap[filedes] = new fstream(filename.c_str(), ios::out); 801 | } 802 | //write and read 803 | else { 804 | filemap[filedes] = new fstream(filename.c_str(), ios::out|ios::in);; 805 | } 806 | 807 | if((*filemap[filedes]).fail()){ 808 | cout << "fail to open the file" << endl; 809 | pReg[4] = -1; 810 | return; 811 | } 812 | 813 | pReg[4] = filedes; 814 | filecount++; 815 | } 816 | else if(pReg[2]==14){ 817 | string cache=""; 818 | char holder; 819 | int count = 0; 820 | char * textST = (char *) textStart; 821 | char * pchar = (char *) ((pReg[5]-0x400000)+textST); 822 | 823 | if((*filemap[pReg[4]]).fail()){ 824 | pReg[4] = 0; 825 | cout << "the file is failed to open, unable to read" << endl; 826 | return; 827 | } 828 | 829 | while(((*filemap[pReg[4]]).get(holder))&&(count 5 | #include 6 | #include 7 | 8 | void SYSCALL(); 9 | void ADD(int * rs, int * rt, int* rd, int shamt); 10 | void ADDU(int * rs, int * rt, int* rd, int shamt); 11 | void ADDI(int * rs, int * rt, int imm); 12 | void ADDIU(int * rs, int * rt, int imm); 13 | void AND(int * rs, int * rt, int* rd, int shamt); 14 | void ANDI(int * rs, int * rt, int imm); 15 | void DIV(int * rs, int * rt, int* rd, int shamt); 16 | void DIVU(int * rs, int * rt, int* rd, int shamt); 17 | void MULT(int * rs, int * rt, int* rd, int shamt); 18 | void MULTU(int * rs, int * rt, int* rd, int shamt); 19 | void NOR(int * rs, int * rt, int* rd, int shamt); 20 | void OR(int * rs, int * rt, int* rd, int shamt); 21 | void ORI(int * rs, int * rt, int imm); 22 | void SLL(int * rs, int * rt, int* rd, int shamt); 23 | void SLLV(int * rs, int * rt, int* rd, int shamt); 24 | void SRA(int * rs, int * rt, int* rd, int shamt); 25 | void SRAV(int * rs, int * rt, int* rd, int shamt); 26 | void SRL(int * rs, int * rt, int* rd, int shamt); 27 | void SRLV(int * rs, int * rt, int* rd, int shamt); 28 | void SUB(int * rs, int * rt, int* rd, int shamt); 29 | void SUBU(int * rs, int * rt, int* rd, int shamt); 30 | void XOR(int * rs, int * rt, int* rd, int shamt); 31 | void XORI(int * rs, int * rt, int imm); 32 | void LUI(int * rs, int * rt, int imm); 33 | void SLT(int * rs, int * rt, int* rd, int shamt); 34 | void SLTU(int * rs, int * rt, int* rd, int shamt); 35 | void SLTI(int * rs, int * rt, int imm); 36 | void SLTIU(int * rs, int * rt, int imm); 37 | void BEQ(int * rs, int * rt, int imm); 38 | void BGEZ(int * rs, int * rt, int imm); 39 | void BGEZAL(int * rs, int * rt, int imm); 40 | void BGTZ(int * rs, int * rt, int imm); 41 | void BLEZ(int * rs, int * rt, int imm); 42 | void BLTZAL(int * rs, int * rt, int imm); 43 | void BLTZ(int * rs, int * rt, int imm); 44 | void BNE(int * rs, int * rt, int imm); 45 | void J(int target); 46 | void JAL(int target); 47 | void JALR(int * rs, int * rt, int* rd, int shamt); 48 | void JR(int * rs, int * rt, int* rd, int shamt); 49 | void TEQ(int * rs, int * rt, int* rd, int shamt); 50 | void TEQI(int * rs, int * rt, int imm); 51 | void TNE(int * rs, int * rt, int* rd, int shamt); 52 | void TNEI(int * rs, int * rt, int imm); 53 | void TGE(int * rs, int * rt, int* rd, int shamt); 54 | void TGEU(int * rs, int * rt, int* rd, int shamt); 55 | void TGEI(int * rs, int * rt, int imm); 56 | void TGEIU(int * rs, int * rt, int imm); 57 | void TLT(int * rs, int * rt, int* rd, int shamt); 58 | void TLTU(int * rs, int * rt, int* rd, int shamt); 59 | void TLTI(int * rs, int * rt, int imm); 60 | void TLTIU(int * rs, int * rt, int imm); 61 | void LB(int * rs, int * rt, int imm); 62 | void LBU(int * rs, int * rt, int imm); 63 | void LH(int * rs, int * rt, int imm); 64 | void LHU(int * rs, int * rt, int imm); 65 | void LW(int * rs, int * rt, int imm); 66 | void LWL(int * rs, int * rt, int imm); 67 | void LWR(int * rs, int * rt, int imm); 68 | void LL(int * rs, int * rt, int imm); 69 | void SB(int * rs, int * rt, int imm); 70 | void SH(int * rs, int * rt, int imm); 71 | void SW(int * rs, int * rt, int imm); 72 | void SWL(int * rs, int * rt, int imm); 73 | void SWR(int * rs, int * rt, int imm); 74 | void SC(int * rs, int * rt, int imm); 75 | void MFHI(int * rs, int * rt, int* rd, int shamt); 76 | void MFLO(int * rs, int * rt, int* rd, int shamt); 77 | void MTHI(int * rs, int * rt, int* rd, int shamt); 78 | void MTLO(int * rs, int * rt, int* rd, int shamt); 79 | void SYSCALL(); 80 | bool overflow(int x, int y); 81 | 82 | #endif // HEADER_H 83 | -------------------------------------------------------------------------------- /assignment2/adder.txt: -------------------------------------------------------------------------------- 1 | .data 2 | 3 | .text 4 | addi $v0, $zero, 5 5 | syscall 6 | add $t0, $v0, $zero 7 | addi $v0, $zero, 5 8 | syscall 9 | add $t1, $v0, $zero 10 | add $a0, $t0, $t1 11 | addi $v0, $zero, 1 12 | syscall 13 | addi $v0, $v0, 9 14 | syscall -------------------------------------------------------------------------------- /assignment2/dataHandler.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "dataHandler.h" 6 | 7 | using namespace std; 8 | 9 | int * asciiType(string data, int* pdata, bool ztype); 10 | int * wordType(string data, int * pdata); 11 | int * halfwordType(string data, int * pdata); 12 | int * floatType(string data, int * pdata); 13 | int * byteType(string data, int * pdata); 14 | int * doubleType(string data, int * pdata); 15 | 16 | int* dataHandle(char* filename, int * pdata){ 17 | ifstream infile(filename); 18 | 19 | // try to open the file 20 | if(infile.fail()){ 21 | cout << "failed to open the file" << endl; 22 | infile.close(); 23 | return pdata; 24 | } 25 | 26 | string data; 27 | string data2; 28 | string cache; 29 | 30 | //jump to the .data 31 | while(getline(infile, cache)){ 32 | stringstream cac; 33 | string marker; 34 | cac << cache; 35 | cac >> marker; 36 | 37 | if(marker[0]=='.'){ 38 | break; 39 | } 40 | } 41 | 42 | while(infile>>data){ 43 | if(data[0]=='.'){ 44 | break; 45 | } 46 | 47 | if(data[0]=='#'){ 48 | getline(infile, cache); 49 | continue; 50 | } 51 | 52 | infile >> data; 53 | getline(infile, cache); 54 | stringstream dataflow; 55 | dataflow << cache; 56 | dataflow >> data2; 57 | 58 | if(data==".asciiz"||data==".ascii"){ 59 | int start = 0; 60 | int end = 0; 61 | while(cache[start]!='\0'&&(cache[start]==' '||cache[start]=='\t')) start++; 62 | 63 | // invalid 64 | if(cache[start]!='"'||cache[start]=='\0'){ 65 | cout << "error in .data" << endl; 66 | continue; 67 | } 68 | end = start+1; 69 | 70 | while(cache[end]!='\0'&&cache[end]!='"') end++; 71 | cache = cache.substr(start, end-start+1); 72 | 73 | if(data==".asciiz") pdata = asciiType(cache, pdata, true); 74 | else pdata = asciiType(cache, pdata, false); 75 | 76 | } 77 | else if(data==".word"){ 78 | pdata = wordType(data2, pdata); 79 | } 80 | else if(data==".byte"){ 81 | pdata = byteType(data2, pdata); 82 | } 83 | else if(data==".double"){ 84 | pdata = doubleType(data2,pdata); 85 | } 86 | else if(data==".float"){ 87 | pdata = floatType(data2, pdata); 88 | } 89 | else if(data==".half"){ 90 | pdata = halfwordType(data2, pdata); 91 | } 92 | else continue; 93 | } 94 | infile.close(); 95 | return pdata; 96 | } 97 | 98 | int * asciiType(string data, int* pdata, bool ztype){ // ztype for Asciiz 99 | string holder; 100 | int lenOfWord = 0; 101 | int leng = data.length(); 102 | 103 | if(data[0]!='"'){ 104 | cout << "error1 in the .data" << endl; 105 | return pdata; 106 | } 107 | 108 | for(int i=1; i < leng; i++){ 109 | if(data[i]=='"') break; 110 | lenOfWord++; 111 | } 112 | 113 | holder = data.substr(1, lenOfWord); 114 | 115 | char * pchar = (char *) pdata; 116 | for(int i =0; i> num; 165 | double * pdouble = (double *) pdata; 166 | *pdouble = num; 167 | return (pdata+2); 168 | } 169 | 170 | int * floatType(string data, int * pdata){ 171 | stringstream dataflow; 172 | float num; 173 | dataflow << data; 174 | dataflow >> num; 175 | float * pdouble = (float *) pdata; 176 | *pdouble = num; 177 | return ++pdata; 178 | } 179 | 180 | int * byteType(string data, int * pdata){ 181 | char charholder = ' '; 182 | int intholder = 0; 183 | int count = 0; 184 | char * pchar = (char*) (pdata); 185 | int flag = 0; 186 | 187 | for(int i = 0; data[i]!='\0';i++){ 188 | if(data[i]==','){ 189 | if(!flag) charholder=intholder; 190 | *pchar = charholder; 191 | pchar++; 192 | count++; 193 | intholder = 0; 194 | flag = 0; 195 | } 196 | else{ 197 | if(data[i]=='\'') flag=1; 198 | else{ 199 | if(flag) charholder=data[i]; 200 | else intholder = intholder*10 + (data[i]-'0'); 201 | } 202 | } 203 | } 204 | 205 | //store the last char 206 | if(!flag) charholder=intholder; 207 | *pchar = charholder; 208 | count++; 209 | 210 | int quotient = count/4; 211 | int reminder = count%4; 212 | if(reminder) quotient++; 213 | return pdata+quotient; 214 | } 215 | 216 | int * halfwordType(string data, int * pdata){ 217 | char charholder = ' '; 218 | int intholder = 0; 219 | int count = 0; 220 | uint16_t * pchar = (uint16_t *) (pdata); 221 | int flag = 0; 222 | 223 | for(int i = 0; data[i]!='\0';i++){ 224 | if(data[i]==','){ 225 | if(!flag) charholder=intholder; 226 | *pchar = charholder; 227 | pchar++; 228 | count++; 229 | intholder = 0; 230 | flag = 0; 231 | } 232 | else{ 233 | if(data[i]=='\'') flag=1; 234 | else{ 235 | if(flag) charholder=data[i]; 236 | else intholder = intholder*10 + (data[i]-'0'); 237 | } 238 | } 239 | } 240 | 241 | //store the last char 242 | if(!flag) charholder=intholder; 243 | *pchar = charholder; 244 | count++; 245 | 246 | int quotient = count/2; 247 | int reminder = count%2; 248 | if(reminder) quotient++; 249 | return pdata+quotient; 250 | 251 | } 252 | -------------------------------------------------------------------------------- /assignment2/dataHandler.h: -------------------------------------------------------------------------------- 1 | #ifndef DATAHANDLER_H 2 | #define DATAHANDLER_H 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | int * asciiType(std::string data, int* pdata, bool ztype); 9 | int * wordType(std::string data, int * pdata); 10 | int * halfwordType(std::string data, int * pdata); 11 | int * floatType(std::string data, int * pdata); 12 | int * byteType(std::string data, int * pdata); 13 | int * doubleType(std::string data, int * pdata); 14 | int * dataHandle(char* filename, int * pdata); 15 | 16 | #endif // DATAHANDLER_H 17 | -------------------------------------------------------------------------------- /assignment2/fibonacii.txt: -------------------------------------------------------------------------------- 1 | 00100000000000100000000000000101 2 | 00000000000000000000000000001100 3 | 00000000010000000100000000100000 4 | 00100000000000100000000000000101 5 | 00000000000000000000000000001100 6 | 00000000010000000100100000100000 7 | 00000001000010010010000000100000 8 | 00100000000000100000000000000001 9 | 00000000000000000000000000001100 10 | 00100000010000100000000000001001 11 | 00000000000000000000000000001100 12 | -------------------------------------------------------------------------------- /assignment2/report.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MoyuST/CSC3050-Computer-Architecture/e4dc51b0300e825618730de590b45da707f6adf1/assignment2/report.pdf -------------------------------------------------------------------------------- /assignment3/ALU.v: -------------------------------------------------------------------------------- 1 | module aluSeg(i_datain, gr1, gr2, zero_wire, negative_wire, overflow_wire, c, hi_wire, lo_wire); 2 | 3 | //output result 4 | output signed[31:0] c; 5 | 6 | //flags 7 | output zero_wire, negative_wire, overflow_wire; 8 | 9 | //lo, hi 10 | output [31:0] lo_wire, hi_wire; 11 | 12 | input [31:0] i_datain, gr1, gr2; 13 | 14 | // wire [31:0] imm_wire; 15 | 16 | reg [5:0] opcode, funct; 17 | reg [4:0] shamt; 18 | reg [4:0] aluctr; 19 | reg alusrc; 20 | reg [31:0] reg_A, reg_B; 21 | reg [31:0] imm; 22 | 23 | //ALUcontrol 24 | always @(i_datain, gr1, gr2) 25 | begin 26 | reg_A = gr1; 27 | reg_B = gr2; 28 | // reg_C = c; 29 | opcode = i_datain[31:26]; 30 | funct = i_datain[5:0]; 31 | shamt = i_datain[10:6]; 32 | imm = {{16{i_datain[15]}} ,i_datain[15:0]}; 33 | 34 | if (opcode==6'b00_0000) 35 | begin 36 | 37 | alusrc = 1'b0; 38 | 39 | //add 40 | if(funct==6'h20) 41 | begin 42 | aluctr = 5'b0_0000; 43 | end 44 | 45 | //addu 46 | else if(funct==6'h21) 47 | begin 48 | aluctr = 5'b0_0001; 49 | end 50 | 51 | //sub 52 | else if(funct==6'h22) 53 | begin 54 | aluctr = 5'b0_0010; 55 | end 56 | 57 | //subu 58 | else if(funct==6'h23) 59 | begin 60 | aluctr = 5'b0_0011; 61 | end 62 | 63 | //mult 64 | else if(funct==6'h18) 65 | begin 66 | aluctr = 5'b0_0100; 67 | end 68 | 69 | //multu 70 | else if(funct==6'h19) 71 | begin 72 | aluctr = 5'b0_0101; 73 | end 74 | 75 | //div 76 | else if(funct==6'h1a) 77 | begin 78 | aluctr = 5'b0_0110; 79 | end 80 | 81 | //divu 82 | else if(funct==6'h1b) 83 | begin 84 | aluctr = 5'b0_0111; 85 | end 86 | 87 | //and 88 | else if(funct==6'h24) 89 | begin 90 | aluctr = 5'b0_1000; 91 | end 92 | 93 | //nor 94 | else if(funct==6'h27) 95 | begin 96 | aluctr = 5'b0_1001; 97 | end 98 | 99 | //or 100 | else if(funct==6'h25) 101 | begin 102 | aluctr = 5'b0_1010; 103 | end 104 | 105 | //xor 106 | else if(funct==6'h26) 107 | begin 108 | aluctr = 5'b0_1011; 109 | end 110 | 111 | //slt 112 | else if(funct==6'h2a) 113 | begin 114 | aluctr = 5'b0_1100; 115 | end 116 | 117 | //sltu 118 | else if(funct==6'h2b) 119 | begin 120 | aluctr = 5'b0_1101; 121 | end 122 | 123 | //sll 124 | else if(funct==6'h0) 125 | begin 126 | aluctr = 5'b1_0000; 127 | end 128 | 129 | //sllv 130 | else if(funct==6'h4) 131 | begin 132 | aluctr = 5'b1_0001; 133 | end 134 | 135 | //srl 136 | else if(funct==6'h2) 137 | begin 138 | aluctr = 5'b1_0010; 139 | end 140 | 141 | //srlv 142 | else if(funct==6'h6) 143 | begin 144 | aluctr = 5'b1_0011; 145 | end 146 | 147 | //sra 148 | else if(funct==6'h3) 149 | begin 150 | aluctr = 5'b1_0100; 151 | end 152 | 153 | //srav 154 | else if(funct==6'h7) 155 | begin 156 | aluctr = 5'b1_0101; 157 | end 158 | 159 | else 160 | begin 161 | aluctr = 5'b1_1111; 162 | end 163 | end 164 | 165 | //handle the zero extend instructions 166 | //xori andi ori 167 | else if(opcode==6'he||opcode==6'hc||opcode==6'hd) 168 | begin 169 | 170 | imm = {{16{1'b0}}, i_datain[15:0]}; 171 | 172 | //xori 173 | if(opcode==6'he) 174 | begin 175 | aluctr = 5'b0_1011; 176 | alusrc = 1'b1; 177 | end 178 | 179 | //andi 180 | else if(opcode==6'hc) 181 | begin 182 | aluctr = 5'b0_1000; 183 | alusrc = 1'b1; 184 | end 185 | 186 | //ori 187 | else 188 | begin 189 | aluctr = 5'b0_1010; 190 | alusrc = 1'b1; 191 | end 192 | 193 | end 194 | 195 | //addiu 196 | else if(opcode==6'h9) 197 | begin 198 | aluctr = 5'b0_0001; 199 | alusrc = 1'b1; 200 | end 201 | 202 | //addi 203 | else if(opcode==6'h8) 204 | begin 205 | aluctr = 5'b0_0000; 206 | alusrc = 1'b1; 207 | end 208 | 209 | //beq bne(same as the sub) 210 | else if(opcode==6'h4||opcode==6'h5) 211 | begin 212 | aluctr = 5'b0_0010; 213 | alusrc = 1'b0; 214 | end 215 | 216 | //slti 217 | else if(opcode==6'ha) 218 | begin 219 | aluctr = 5'b0_1100; 220 | alusrc = 1'b1; 221 | end 222 | 223 | //sltiu 224 | else if(opcode==6'hb) 225 | begin 226 | aluctr = 5'b0_1101; 227 | alusrc = 1'b1; 228 | end 229 | 230 | //lw 231 | else if(opcode==6'h23) 232 | begin 233 | aluctr = 5'b0_1110; 234 | alusrc = 1'b1; 235 | end 236 | 237 | //sw 238 | else if(opcode==6'h2b) 239 | begin 240 | aluctr = 5'b0_1111; 241 | alusrc = 1'b1; 242 | end 243 | 244 | //invalid input 245 | else 246 | begin 247 | aluctr = 5'b1_1111; 248 | alusrc = 1'b1; 249 | end 250 | 251 | end 252 | 253 | alu alu0(aluctr, alusrc, gr1, gr2, imm, shamt, zero_wire, negative_wire, overflow_wire, c, hi_wire, lo_wire); 254 | 255 | endmodule 256 | 257 | 258 | module alu(aluctr, alusrc, gr1, gr2, imm, shamt, zero, negative, overflow, c, hi_wire, lo_wire); 259 | 260 | //output result 261 | output signed[31:0] c; 262 | 263 | //flags 264 | output zero, negative, overflow; 265 | 266 | //lo, hi 267 | output signed[31:0]lo_wire, hi_wire; 268 | 269 | input signed[31:0] gr1,gr2; 270 | input [4:0] shamt; 271 | input [31:0] imm; 272 | input [4:0] aluctr; 273 | input alusrc; 274 | 275 | 276 | reg zero, negative, overflow; 277 | reg signed[31:0] reg_C, reg_A, reg_B; 278 | reg [31:0] unsigned_reg_B, unsigned_reg_A; 279 | reg [31:0] lo, hi; 280 | 281 | //used to dectect overflow 282 | reg extra; 283 | 284 | 285 | reg signed [31:0] lo_t, hi_t; 286 | // reg signed[31:0] imm; 287 | // reg[5:0] opcode, func; 288 | 289 | parameter gr0 = 32'h0000_0000; 290 | parameter Width = 32; 291 | parameter MSB = Width - 1; 292 | 293 | always @(aluctr,alusrc,imm,gr1,gr2) 294 | begin 295 | if(alusrc==1'b0) 296 | begin 297 | reg_B = gr2; 298 | unsigned_reg_B = gr2; 299 | end 300 | 301 | else 302 | begin 303 | reg_B = imm; 304 | unsigned_reg_B = imm; 305 | end 306 | 307 | 308 | 309 | //add 310 | if(aluctr==5'b0_0000) 311 | begin 312 | reg_A = gr1; 313 | {extra, reg_C} = {reg_A[MSB], reg_A} + {reg_B[MSB], reg_B}; 314 | zero = reg_C ? 0 : 1; 315 | negative = reg_C[MSB]; 316 | overflow = extra ^ reg_C[MSB]; 317 | end 318 | 319 | //addu 320 | else if(aluctr==5'b0_0001) 321 | begin 322 | reg_A = gr1; 323 | unsigned_reg_A = gr1; 324 | reg_C = unsigned_reg_A + unsigned_reg_B; 325 | zero = reg_C ? 0 :1; 326 | negative = 1'b0; 327 | overflow = 1'b0; 328 | end 329 | 330 | //sub 331 | else if(aluctr==5'b0_0010) 332 | begin 333 | reg_A = gr1; 334 | {extra, reg_C} = {reg_A[MSB], reg_A} - {reg_B[MSB], reg_B}; 335 | zero = reg_C ? 0 : 1; 336 | negative = reg_C[MSB]; 337 | overflow = extra ^ reg_C[MSB]; 338 | end 339 | 340 | //subu 341 | else if(aluctr==5'b0_0011) 342 | begin 343 | reg_A = gr1; 344 | unsigned_reg_A = gr1; 345 | reg_C = unsigned_reg_A - unsigned_reg_B; 346 | zero = reg_C ? 0 :1; 347 | negative = 1'b0; 348 | overflow = 1'b0; 349 | end 350 | 351 | //mult 352 | else if(aluctr==5'b0_0100) 353 | begin 354 | reg_A = gr1; 355 | {hi, lo} = reg_A * reg_B; 356 | zero = {hi, lo} ? 0 :1; 357 | negative = hi[MSB]; 358 | overflow = 1'b0; 359 | end 360 | 361 | //multu 362 | else if(aluctr==5'b0_0101) 363 | begin 364 | reg_A = gr1; 365 | unsigned_reg_A = gr1; 366 | {hi, lo} = unsigned_reg_A * unsigned_reg_B; 367 | zero = {hi, lo} ? 0: 1; 368 | negative = 1'b0; 369 | overflow = 1'b0; 370 | end 371 | 372 | //div 373 | else if(aluctr==5'b0_0110) 374 | begin 375 | reg_A = gr1; 376 | if(reg_A==32'h8000_0000 && reg_B==-1) 377 | overflow = 1; 378 | else 379 | overflow = 0; 380 | 381 | lo = reg_A / reg_B; 382 | hi = reg_A % reg_B; 383 | zero = reg_A ? 0 : 1; 384 | negative = lo[MSB]; 385 | end 386 | 387 | //divu 388 | else if(aluctr==5'b0_0111) 389 | begin 390 | reg_A = gr1; 391 | unsigned_reg_A = gr1; 392 | lo = unsigned_reg_A / unsigned_reg_B; 393 | hi = unsigned_reg_A % unsigned_reg_B; 394 | zero = unsigned_reg_A ? 0 : 1; 395 | negative = 1'b0; 396 | overflow = 1'b0; 397 | end 398 | 399 | //and 400 | else if(aluctr==5'b0_1000) 401 | begin 402 | reg_A = gr1; 403 | reg_C = reg_A & reg_B; 404 | overflow = 1'b0; 405 | negative = reg_C[MSB]; 406 | zero = reg_C ? 0 : 1; 407 | end 408 | 409 | //nor 410 | else if(aluctr==5'b0_1001) 411 | begin 412 | reg_A = gr1; 413 | reg_C = ~(reg_A | reg_B); 414 | overflow = 1'b0; 415 | negative = reg_C[MSB]; 416 | zero = reg_C ? 0 : 1; 417 | end 418 | 419 | //or 420 | else if(aluctr==5'b0_1010) 421 | begin 422 | reg_A = gr1; 423 | reg_C = reg_A | reg_B; 424 | overflow = 1'b0; 425 | negative = reg_C[MSB]; 426 | zero = reg_C ? 0 : 1; 427 | end 428 | 429 | //xor 430 | else if(aluctr==5'b0_1011) 431 | begin 432 | reg_A = gr1; 433 | reg_C = reg_A ^ reg_B; 434 | overflow = 1'b0; 435 | negative = reg_C[MSB]; 436 | zero = reg_C ? 0 : 1; 437 | end 438 | 439 | //slt 440 | else if(aluctr==5'b0_1100) 441 | begin 442 | reg_A = gr1; 443 | reg_C = reg_A < reg_B; 444 | overflow = 1'b0; 445 | negative = 1'b0; 446 | zero = reg_C ? 0 : 1; 447 | end 448 | 449 | //sltu 450 | else if(aluctr==5'b0_1101) 451 | begin 452 | reg_A = gr1; 453 | unsigned_reg_A = gr1; 454 | reg_C = unsigned_reg_A < unsigned_reg_B; 455 | overflow = 1'b0; 456 | negative = 1'b0; 457 | zero = reg_C ? 0 : 1; 458 | end 459 | 460 | //lw 461 | else if(aluctr==5'b0_1110) 462 | begin 463 | reg_A = gr1; 464 | reg_C = reg_A + reg_B; 465 | overflow = 1'b0; 466 | negative = 1'b0; 467 | zero = reg_C ? 0 : 1; 468 | end 469 | 470 | //sw 471 | else if(aluctr==5'b0_1111) 472 | begin 473 | reg_A = gr1; 474 | reg_C = reg_A + reg_B; 475 | overflow = 1'b0; 476 | negative = 1'b0; 477 | zero = reg_C ? 0 : 1; 478 | end 479 | 480 | //sll 481 | else if(aluctr==5'b1_0000) 482 | begin 483 | reg_A = gr1; 484 | reg_B = {{27{1'b0}}, shamt}; 485 | reg_C = reg_A << reg_B; 486 | overflow = 1'b0; 487 | negative = reg_C[MSB]; 488 | zero = reg_C ? 0 : 1; 489 | end 490 | 491 | //sllv 492 | else if(aluctr==5'b1_0001) 493 | begin 494 | reg_A = gr1; 495 | reg_C = reg_A << reg_B; 496 | overflow = 1'b0; 497 | negative = reg_C[MSB]; 498 | zero = reg_C ? 0 : 1; 499 | end 500 | 501 | //srl 502 | else if(aluctr==5'b1_0010) 503 | begin 504 | reg_A = gr1; 505 | reg_B = {{27{1'b0}}, shamt}; 506 | reg_C = reg_A >> reg_B; 507 | overflow = 1'b0; 508 | negative = reg_C[MSB]; 509 | zero = reg_C ? 0 : 1; 510 | end 511 | 512 | //srlv 513 | else if(aluctr==5'b1_0011) 514 | begin 515 | reg_A = gr1; 516 | reg_C = reg_A >> reg_B; 517 | overflow = 1'b0; 518 | negative = reg_C[MSB]; 519 | zero = reg_C ? 0 : 1; 520 | end 521 | 522 | //sra 523 | else if(aluctr==5'b1_0100) 524 | begin 525 | reg_A = gr1; 526 | reg_B = {{27{1'b0}}, shamt}; 527 | reg_C = reg_A >>> reg_B; 528 | overflow = 1'b0; 529 | negative = reg_C[MSB]; 530 | zero = reg_C ? 0 : 1; 531 | end 532 | 533 | //srav 534 | else if(aluctr==5'b1_0101) 535 | begin 536 | reg_A = gr1; 537 | reg_C = reg_A >>> reg_B; 538 | overflow = 1'b0; 539 | negative = reg_C[MSB]; 540 | zero = reg_C ? 0 : 1; 541 | end 542 | 543 | //invalid 544 | else 545 | begin 546 | $display(" invalid input"); 547 | end 548 | 549 | 550 | end 551 | 552 | 553 | assign c = reg_C[31:0]; 554 | assign lo_wire = lo; 555 | assign hi_wire = hi; 556 | endmodule -------------------------------------------------------------------------------- /assignment3/report.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MoyuST/CSC3050-Computer-Architecture/e4dc51b0300e825618730de590b45da707f6adf1/assignment3/report.pdf -------------------------------------------------------------------------------- /assignment3/test_ALU.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns/1ps 2 | 3 | module alu_test; 4 | 5 | reg[31:0] i_datain,gr1,gr2; 6 | wire[31:0] c, lo, hi; 7 | wire zero, negative, overflow; 8 | //wire zero; 9 | //wire overflow; 10 | //wire neg; 11 | 12 | aluSeg testalu(i_datain,gr1, gr2, zero, negative, overflow, c, hi, lo); 13 | 14 | initial 15 | begin 16 | 17 | $display("instruction:op:func:ALUctr:ALUsrc: gr1 : gr2 : c : reg_A : reg_B : reg_C : hi : lo : zero : negative : overflow"); 18 | $monitor(" %h:%h: %h : %h : %h :%h:%h:%h:%h:%h:%h:%h:%h: %h : %h : %h", 19 | i_datain, testalu.opcode, testalu.funct, testalu.aluctr, testalu.alusrc, gr1 , gr2, c, testalu.alu0.reg_A, testalu.alu0.reg_B, testalu.c, 20 | hi, lo, zero, negative, overflow); 21 | 22 | //add 23 | #10 i_datain<=32'b000000_00011_00010_00001_00000_100000; 24 | gr1<=32'b0000_0000_0000_0000_0000_0000_0000_0001; 25 | gr2<=32'b0000_0000_0000_0000_0000_0000_0000_1001; 26 | $display("add"); 27 | $display("instruction:op:func:ALUctr:ALUsrc: gr1 : gr2 : c : reg_A : reg_B : reg_C : hi : lo : zero : negative : overflow"); 28 | #10 i_datain<=32'b000000_00011_00010_00001_00000_100000; 29 | gr1<=32'b1000_0000_0000_0000_0000_0000_0000_0001; 30 | gr2<=32'b1000_0000_0000_0000_0000_0000_0000_0001; 31 | 32 | #10 i_datain<=32'b000000_00011_00010_00001_00000_100000; 33 | gr1<=32'b0100_0000_0000_0000_0000_0000_0000_0001; 34 | gr2<=32'b0100_0000_0000_0000_0000_0000_0000_0001; 35 | 36 | #10 i_datain<=32'b000000_00011_00010_00001_00000_100000; 37 | gr1<=32'b0000_0000_0000_0000_0000_0000_1101_1101; 38 | gr2<=32'b1111_1111_1111_1111_1111_1111_0010_0011; 39 | 40 | #10 i_datain<=32'b000000_00011_00010_00001_00000_100000; 41 | gr1<=32'b0000_0000_0000_0000_0000_0000_0101_1101; 42 | gr2<=32'b1111_1111_1111_1111_1111_1111_0010_0011; 43 | 44 | //addi 45 | #10 i_datain<=32'b001000_00011_00010_1000000000100000; 46 | gr1<=32'b1000_0000_0000_0000_0000_0000_0000_0001; 47 | gr2<=32'b1000_0000_0000_0000_0000_0000_0000_0001; 48 | $display("addi"); 49 | $display("instruction:op:func:ALUctr:ALUsrc: gr1 : gr2 : c : reg_A : reg_B : reg_C : hi : lo : zero : negative : overflow"); 50 | #10 i_datain<=32'b001000_00011_00010_0000000000100010; 51 | gr1<=32'b1000_0000_0000_0000_0000_0000_0000_0001; 52 | gr2<=32'b1000_0000_0000_0000_0000_0000_0000_0001; 53 | 54 | #10 i_datain<=32'b001000_00011_00010_0000000000100000; 55 | gr1<=32'b1000_0000_0000_0000_0000_0000_0000_0001; 56 | gr2<=32'b1000_0000_0000_0000_0000_0000_0000_0001; 57 | 58 | #10 i_datain<=32'b001000_00011_00010_0000000000100000; 59 | gr1<=32'b0000_0000_0000_0000_0000_0000_0010_0001; 60 | gr2<=32'b1000_0000_0000_0000_0000_0000_0000_0001; 61 | 62 | //addu 63 | #10 i_datain<=32'b000000_00011_00010_00001_00000_100001; 64 | gr1<=32'b0000_0000_0000_0000_0000_0000_0000_0001; 65 | gr2<=32'b0000_0000_0000_0000_0000_0000_0000_1001; 66 | $display("addu"); 67 | $display("instruction:op:func:ALUctr:ALUsrc: gr1 : gr2 : c : reg_A : reg_B : reg_C : hi : lo : zero : negative : overflow"); 68 | #10 i_datain<=32'b000000_00011_00010_00001_00000_100001; 69 | gr1<=32'b1000_0000_0000_0000_0000_0000_0000_0001; 70 | gr2<=32'b1000_0000_0000_0000_0000_0000_0000_0001; 71 | 72 | #10 i_datain<=32'b000000_00011_00010_00001_00000_100001; 73 | gr1<=32'b0100_0000_0000_0000_0000_0000_0000_0001; 74 | gr2<=32'b0100_0000_0000_0000_0000_0000_0000_0001; 75 | 76 | #10 i_datain<=32'b000000_00011_00010_00001_00000_100001; 77 | gr1<=32'b0000_0000_0000_0000_0000_0000_1101_1101; 78 | gr2<=32'b1111_1111_1111_1111_1111_1111_0010_0011; 79 | 80 | #10 i_datain<=32'b000000_00011_00010_00001_00000_100001; 81 | gr1<=32'b0000_0000_0000_0000_0000_0000_0101_1101; 82 | gr2<=32'b1111_1111_1111_1111_1111_1111_0010_0011; 83 | 84 | #10 i_datain<=32'b000000_00011_00010_00001_00000_100001; 85 | gr1<=32'b0000_0000_0000_0000_0000_0000_0000_0000; 86 | gr2<=32'b0000_0000_0000_0000_0000_0000_0000_0000; 87 | 88 | //addiu 89 | #10 i_datain<=32'b001001_00011_00010_1000000000100000; 90 | gr1<=32'b1000_0000_0000_0000_0000_0000_0000_0001; 91 | gr2<=32'b1000_0000_0000_0000_0000_0000_0000_0001; 92 | $display("addiu"); 93 | $display("instruction:op:func:ALUctr:ALUsrc: gr1 : gr2 : c : reg_A : reg_B : reg_C : hi : lo : zero : negative : overflow"); 94 | #10 i_datain<=32'b001001_00011_00010_1000000000100000; 95 | gr1<=32'b0000_0000_0000_0000_0000_0000_0000_0001; 96 | gr2<=32'b0000_0000_0000_0000_0000_0000_0000_0011; 97 | 98 | #10 i_datain<=32'b001001_00011_00010_0000000000000000; 99 | gr1<=32'b0000_0000_0000_0000_0000_0000_0000_0000; 100 | gr2<=32'b0000_0000_0000_0000_0000_0000_0000_0000; 101 | 102 | //sub 103 | #10 i_datain<=32'b000000_00011_00010_00001_00000_100010; 104 | gr1<=32'b1111_0000_0000_0000_0000_0000_0101_1101; 105 | gr2<=32'b0000_0000_0000_0000_0000_0000_0000_0001; 106 | $display("sub"); 107 | $display("instruction:op:func:ALUctr:ALUsrc: gr1 : gr2 : c : reg_A : reg_B : reg_C : hi : lo : zero : negative : overflow"); 108 | #10 i_datain<=32'b000000_00011_00010_00001_00000_100010; 109 | gr1<=32'b1000_0000_0000_0000_0000_0000_0000_0001; 110 | gr2<=32'b0111_0000_0000_0000_0000_0000_0101_1101; 111 | 112 | #10 i_datain<=32'b000000_00011_00010_00001_00000_100010; 113 | gr1<=32'b0000_0000_0000_0000_0000_0000_0000_0001; 114 | gr2<=32'b1111_0000_0000_0000_0000_0000_0101_1101; 115 | 116 | #10 i_datain<=32'b000000_00011_00010_00001_00000_100010; 117 | gr1<=32'b0000_0000_0000_0000_0000_0000_0000_0000; 118 | gr2<=32'b0000_0000_0000_0000_0000_0000_0000_0000; 119 | 120 | //subu 121 | #10 i_datain<=32'b000000_00011_00010_00001_00000_100011; 122 | gr1<=32'b0111_0000_0000_0000_0000_0000_0101_1101; 123 | gr2<=32'b1000_0000_0000_0000_0000_0000_0000_0001; 124 | $display("subu"); 125 | $display("instruction:op:func:ALUctr:ALUsrc: gr1 : gr2 : c : reg_A : reg_B : reg_C : hi : lo : zero : negative : overflow"); 126 | #10 i_datain<=32'b000000_00011_00010_00001_00000_100011; 127 | gr1<=32'b1000_0000_0000_0000_0000_0000_0000_0001; 128 | gr2<=32'b0111_0000_0000_0000_0000_0000_0101_1101; 129 | 130 | #10 i_datain<=32'b000000_00011_00010_00001_00000_100011; 131 | gr1<=32'b0000_0000_0000_0000_0000_0000_0000_0001; 132 | gr2<=32'b1111_0000_0000_0000_0000_0000_0101_1101; 133 | 134 | #10 i_datain<=32'b000000_00011_00010_00001_00000_100011; 135 | gr1<=32'b0000_0000_0000_0000_0000_1000_0000_0001; 136 | gr2<=32'b0000_0000_0000_0000_0000_0000_0101_1101; 137 | 138 | #10 i_datain<=32'b000000_00011_00010_00001_00000_100011; 139 | gr1<=32'b0000_0000_0000_0000_0000_0000_0000_0000; 140 | gr2<=32'b0000_0000_0000_0000_0000_0000_0000_0000; 141 | 142 | //mult 143 | #10 i_datain<=32'b000000_00011_00010_00001_00000_011000; 144 | gr1<=32'b0000_0000_0000_0000_0000_0000_0000_0001; 145 | gr2<=32'b1111_0000_0000_0000_0000_0000_0101_1101; 146 | $display("mult"); 147 | $display("instruction:op:func:ALUctr:ALUsrc: gr1 : gr2 : c : reg_A : reg_B : reg_C : hi : lo : zero : negative : overflow"); 148 | #10 i_datain<=32'b000000_00011_00010_00001_00000_011000; 149 | gr1<=32'b0000_0000_0000_0000_0000_0000_0000_0011; 150 | gr2<=32'b0000_0000_0000_0000_0000_0000_0101_1101; 151 | 152 | #10 i_datain<=32'b000000_00011_00010_00001_00000_011000; 153 | gr1<=32'b0000_0000_0000_0000_0000_0000_0000_0001; 154 | gr2<=32'b0000_0000_0000_0000_0000_0000_0000_0000; 155 | 156 | #10 i_datain<=32'b000000_00011_00010_00001_00000_011000; 157 | gr1<=32'b1000_0000_0000_0000_0000_0000_0000_0001; 158 | gr2<=32'b1111_0000_0000_0000_0000_0000_0101_1101; 159 | 160 | //multu 161 | #10 i_datain<=32'b000000_00011_00010_00001_00000_011001; 162 | gr1<=32'b0000_0000_0000_0000_0000_0000_0000_0001; 163 | gr2<=32'b1111_0000_0000_0000_0000_0000_0101_1101; 164 | $display("multu"); 165 | $display("instruction:op:func:ALUctr:ALUsrc: gr1 : gr2 : c : reg_A : reg_B : reg_C : hi : lo : zero : negative : overflow"); 166 | #10 i_datain<=32'b000000_00011_00010_00001_00000_011001; 167 | gr1<=32'b0000_0000_0000_0000_0000_0000_0000_0001; 168 | gr2<=32'b0000_0000_0000_0000_0000_0000_0000_0000; 169 | 170 | #10 i_datain<=32'b000000_00011_00010_00001_00000_011001; 171 | gr1<=32'b1000_0000_0000_0000_0000_0000_0000_0001; 172 | gr2<=32'b0000_0000_0000_0000_0000_0000_0010_0000; 173 | 174 | //div 175 | #10 i_datain<=32'b000000_00011_00010_00001_00000_011010; 176 | gr1<=32'b0000_0000_0000_0000_0000_0000_1100_0001; 177 | gr2<=32'b0000_0000_0000_0000_0000_0000_0011_0010; 178 | $display("div"); 179 | $display("instruction:op:func:ALUctr:ALUsrc: gr1 : gr2 : c : reg_A : reg_B : reg_C : hi : lo : zero : negative : overflow"); 180 | #10 i_datain<=32'b000000_00011_00010_00001_00000_011010; 181 | gr1<=32'b1000_0000_0000_0000_0000_0000_0000_0000; 182 | gr2<=32'b0000_0000_0000_0000_0000_0000_0011_0010; 183 | 184 | #10 i_datain<=32'b000000_00011_00010_00001_00000_011010; 185 | gr1<=32'b1000_0000_0000_0110_0000_0000_0000_0000; 186 | gr2<=32'b0000_0000_0000_0000_0000_0000_0011_0010; 187 | 188 | #10 i_datain<=32'b000000_00011_00010_00001_00000_011010; 189 | gr1<=32'b1000_1100_0010_0000_0000_0000_0000_0000; 190 | gr2<=32'b0000_0000_0000_0000_0000_0000_0000_0000; 191 | 192 | #10 i_datain<=32'b000000_00011_00010_00001_00000_011010; 193 | gr1<=32'b1000_0000_0000_0000_0000_0000_0000_0000; 194 | gr2<=32'b1111_1111_1111_1111_1111_1111_1111_1111; 195 | 196 | #10 i_datain<=32'b000000_00011_00010_00001_00000_011010; 197 | gr1<=32'b0000_0000_0000_0000_0000_0000_0000_0000; 198 | gr2<=32'b0000_0000_1001_0000_1111_0000_0000_0011; 199 | 200 | //divu 201 | #10 i_datain<=32'b000000_00011_00010_00001_00000_011011; 202 | gr1<=32'b0000_0000_0000_0000_0000_0000_1100_0001; 203 | gr2<=32'b0000_0000_0000_0000_0000_0000_0011_0010; 204 | $display("divu"); 205 | $display("instruction:op:func:ALUctr:ALUsrc: gr1 : gr2 : c : reg_A : reg_B : reg_C : hi : lo : zero : negative : overflow"); 206 | #10 i_datain<=32'b000000_00011_00010_00001_00000_011011; 207 | gr1<=32'b1000_0000_0000_0000_0000_0000_0000_0000; 208 | gr2<=32'b0000_0000_0000_0000_0000_0000_0011_0010; 209 | 210 | #10 i_datain<=32'b000000_00011_00010_00001_00000_011011; 211 | gr1<=32'b1000_1100_0010_0000_0000_0000_0000_0000; 212 | gr2<=32'b0000_0000_0000_0000_0000_0000_0011_0010; 213 | 214 | #10 i_datain<=32'b000000_00011_00010_00001_00000_011011; 215 | gr1<=32'b1000_0000_0000_0000_0000_0000_0000_0000; 216 | gr2<=32'b1111_1111_1111_1111_1111_1111_1111_1111; 217 | 218 | #10 i_datain<=32'b000000_00011_00010_00001_00000_011011; 219 | gr1<=32'b0000_0000_0000_0000_0000_0000_0000_0000; 220 | gr2<=32'b1111_1111_1111_1111_1111_1111_1111_1111; 221 | 222 | #10 i_datain<=32'b000000_00011_00010_00001_00000_011011; 223 | gr1<=32'b0100_0000_0000_0000_0000_0000_0000_0000; 224 | gr2<=32'b0000_0000_0000_0000_0000_0000_0000_0000; 225 | 226 | //and 227 | #10 i_datain<=32'b000000_00011_00010_00001_00000_100100; 228 | gr1<=32'b1000_0000_0000_0000_0000_0000_0000_0000; 229 | gr2<=32'b1111_1111_1111_1111_1111_1111_1111_1111; 230 | $display("and"); 231 | $display("instruction:op:func:ALUctr:ALUsrc: gr1 : gr2 : c : reg_A : reg_B : reg_C : hi : lo : zero : negative : overflow"); 232 | #10 i_datain<=32'b000000_00011_00010_00001_00000_100100; 233 | gr1<=32'b1000_0000_1001_0000_0000_0000_0000_0000; 234 | gr2<=32'b0000_0000_1001_0000_0000_0000_0011_0010; 235 | 236 | #10 i_datain<=32'b000000_00011_00010_00001_00000_100100; 237 | gr1<=32'b1000_1100_0010_0000_0000_0000_0000_0000; 238 | gr2<=32'b0000_0000_0000_0000_0000_0000_0011_0010; 239 | 240 | #10 i_datain<=32'b000000_00011_00010_00001_00000_100100; 241 | gr1<=32'b1000_0000_0000_0000_0000_0000_0000_0000; 242 | gr2<=32'b1111_1111_1111_1111_1111_1111_1111_1111; 243 | 244 | //andi 245 | #10 i_datain<=32'b001100_00011_00010_1000000000100000; 246 | gr1<=32'b1000_0000_0000_0000_0000_0000_0000_0001; 247 | gr2<=32'b1000_0000_0000_0000_0000_0000_0000_0001; 248 | $display("andi"); 249 | $display("instruction:op:func:ALUctr:ALUsrc: gr1 : gr2 : c : reg_A : reg_B : reg_C : hi : lo : zero : negative : overflow"); 250 | #10 i_datain<=32'b001100_00011_00010_1000000000100000; 251 | gr1<=32'b1000_0000_0000_0000_0000_0000_0010_0000; 252 | gr2<=32'b1000_0000_0000_0000_0000_0000_0000_0001; 253 | 254 | #10 i_datain<=32'b001100_00011_00010_1000000000100000; 255 | gr1<=32'b0000_0000_0000_0000_0000_0000_0000_0001; 256 | gr2<=32'b0000_0000_0000_0000_0000_0000_0000_0011; 257 | 258 | //nor 259 | #10 i_datain<=32'b000000_00011_00010_00001_00000_100111; 260 | gr1<=32'b1000_0000_0000_0000_0000_0000_0000_0000; 261 | gr2<=32'b1111_1111_1111_1111_1111_1111_1111_1111; 262 | $display("nor"); 263 | $display("instruction:op:func:ALUctr:ALUsrc: gr1 : gr2 : c : reg_A : reg_B : reg_C : hi : lo : zero : negative : overflow"); 264 | #10 i_datain<=32'b000000_00011_00010_00001_00000_100111; 265 | gr1<=32'b1000_0000_0000_0000_0000_0000_0000_0000; 266 | gr2<=32'b0000_0000_0000_0000_0000_0000_0011_0010; 267 | 268 | #10 i_datain<=32'b000000_00011_00010_00001_00000_100111; 269 | gr1<=32'b1000_1100_0010_0000_0000_0000_0000_0000; 270 | gr2<=32'b0000_0000_0000_0000_0000_0000_0011_0010; 271 | 272 | #10 i_datain<=32'b000000_00011_00010_00001_00000_100111; 273 | gr1<=32'b1000_0000_0000_0000_0000_0000_0000_0000; 274 | gr2<=32'b1111_1111_1111_1111_1111_1111_1111_1111; 275 | 276 | //or 277 | #10 i_datain<=32'b000000_00011_00010_00001_11000_100101; 278 | gr1<=32'b1111_1100_0010_0000_0000_0000_0000_0000; 279 | gr2<=32'b0000_0000_0000_0000_0000_0000_0011_0010; 280 | $display("or"); 281 | $display("instruction:op:func:ALUctr:ALUsrc: gr1 : gr2 : c : reg_A : reg_B : reg_C : hi : lo : zero : negative : overflow"); 282 | #10 i_datain<=32'b000000_00011_00010_00001_11000_100101; 283 | gr1<=32'b0100_0000_0000_0000_0000_0000_0000_0000; 284 | gr2<=32'b1111_1111_1111_1111_1111_1111_1111_1111; 285 | 286 | #10 i_datain<=32'b000000_00011_00010_00001_11000_100101; 287 | gr1<=32'b0000_0000_0000_0000_0000_0000_0000_0000; 288 | gr2<=32'b0000_0000_0000_0000_0000_0000_0000_0000; 289 | 290 | //ori 291 | #10 i_datain<=32'b001101_00011_00010_1000000000100000; 292 | gr1<=32'b1000_0000_0000_0000_0000_0000_0000_0001; 293 | gr2<=32'b1000_0000_0000_0000_0000_0000_0000_0001; 294 | $display("ori"); 295 | $display("instruction:op:func:ALUctr:ALUsrc: gr1 : gr2 : c : reg_A : reg_B : reg_C : hi : lo : zero : negative : overflow"); 296 | #10 i_datain<=32'b001101_00011_00010_1000000000100000; 297 | gr1<=32'b1000_0000_0000_0000_0000_0000_0010_0000; 298 | gr2<=32'b1000_0000_0000_0000_0000_0000_0000_0001; 299 | 300 | #10 i_datain<=32'b001101_00011_00010_0000000000000000; 301 | gr1<=32'b0000_0000_0000_0000_0000_0000_0000_0000; 302 | gr2<=32'b0000_0000_0000_0000_0000_0000_0000_0011; 303 | 304 | //xor 305 | #10 i_datain<=32'b000000_00011_00010_00001_00000_100110; 306 | gr1<=32'b1000_0000_0000_0000_0000_0000_0000_0000; 307 | gr2<=32'b1111_1111_1111_1111_1111_1111_1111_1111; 308 | $display("xor"); 309 | $display("instruction:op:func:ALUctr:ALUsrc: gr1 : gr2 : c : reg_A : reg_B : reg_C : hi : lo : zero : negative : overflow"); 310 | #10 i_datain<=32'b000000_00011_00010_00001_00000_100110; 311 | gr1<=32'b1000_0000_0000_0000_0000_0000_0000_0000; 312 | gr2<=32'b0000_0000_0000_0000_0000_0000_0011_0010; 313 | 314 | #10 i_datain<=32'b000000_00011_00010_00001_00000_100110; 315 | gr1<=32'b1000_1100_0010_0000_0000_0000_0000_0000; 316 | gr2<=32'b0000_0000_0000_0000_0000_0000_0011_0010; 317 | 318 | #10 i_datain<=32'b000000_00011_00010_00001_00000_100110; 319 | gr1<=32'b1000_0000_0000_0000_0000_0000_0000_0000; 320 | gr2<=32'b1111_1111_1111_1111_1111_1111_1111_1111; 321 | 322 | //xori 323 | #10 i_datain<=32'b001110_00011_00010_1000000000100000; 324 | gr1<=32'b1000_0000_0000_0000_0000_0000_0000_0001; 325 | gr2<=32'b1000_0000_0000_0000_0000_0000_0000_0001; 326 | $display("xori"); 327 | $display("instruction:op:func:ALUctr:ALUsrc: gr1 : gr2 : c : reg_A : reg_B : reg_C : hi : lo : zero : negative : overflow"); 328 | #10 i_datain<=32'b001110_00011_00010_1000000000100000; 329 | gr1<=32'b1000_0000_0000_0000_0000_0000_0010_0000; 330 | gr2<=32'b1000_0000_0000_0000_0000_0000_0000_0001; 331 | 332 | #10 i_datain<=32'b001110_00011_00010_1000000000100000; 333 | gr1<=32'b0000_0000_0000_0000_0000_0000_0000_0001; 334 | gr2<=32'b0000_0000_0000_0000_0000_0000_0000_0011; 335 | 336 | //beq/bne 337 | #10 i_datain<=32'b000100_00011_00010_1000000000100000; 338 | gr1<=32'b1000_0000_0000_0000_0000_0000_0000_0001; 339 | gr2<=32'b1000_0000_0000_0000_0000_0000_0000_0001; 340 | $display("beq/bne"); 341 | $display("instruction:op:func:ALUctr:ALUsrc: gr1 : gr2 : c : reg_A : reg_B : reg_C : hi : lo : zero : negative : overflow"); 342 | #10 i_datain<=32'b000100_00011_00010_1000000000100000; 343 | gr1<=32'b1000_0000_0000_0000_0000_0000_0010_0000; 344 | gr2<=32'b1000_0000_0000_0000_0000_0000_0000_0001; 345 | 346 | #10 i_datain<=32'b000100_00011_00010_1000000000100000; 347 | gr1<=32'b0000_0000_0000_0000_0000_0000_0000_0001; 348 | gr2<=32'b0000_0000_0000_0000_0000_0000_0000_0011; 349 | 350 | //slt 351 | #10 i_datain<=32'b000000_00011_00010_00001_00000_101010; 352 | gr1<=32'b1000_0000_0000_0000_0000_0000_0000_0000; 353 | gr2<=32'b1111_1111_1111_1111_1111_1111_1111_1111; 354 | $display("slt"); 355 | $display("instruction:op:func:ALUctr:ALUsrc: gr1 : gr2 : c : reg_A : reg_B : reg_C : hi : lo : zero : negative : overflow"); 356 | #10 i_datain<=32'b000000_00011_00010_00001_00000_101010; 357 | gr1<=32'b1000_0000_0000_0000_0000_0000_0000_0000; 358 | gr2<=32'b0000_0000_0000_0000_0000_0000_0011_0010; 359 | 360 | #10 i_datain<=32'b000000_00011_00010_00001_00000_101010; 361 | gr1<=32'b0100_1100_0010_0000_0000_0000_0000_0000; 362 | gr2<=32'b0000_0000_0000_0000_0000_0000_0011_0010; 363 | 364 | #10 i_datain<=32'b000000_00011_00010_00001_00000_101010; 365 | gr1<=32'b1000_0000_0000_0000_0000_0000_0000_0000; 366 | gr2<=32'b1111_1111_1111_1111_1111_1111_1111_1111; 367 | 368 | //slti 369 | #10 i_datain<=32'b001010_00011_00010_1000000000100000; 370 | gr1<=32'b1000_0000_0000_0000_0000_0000_0000_0001; 371 | gr2<=32'b1000_0000_0000_0000_0000_0000_0000_0001; 372 | $display("slti"); 373 | $display("instruction:op:func:ALUctr:ALUsrc: gr1 : gr2 : c : reg_A : reg_B : reg_C : hi : lo : zero : negative : overflow"); 374 | #10 i_datain<=32'b001010_00011_00010_1000000000100000; 375 | gr1<=32'b1000_0000_0000_0000_0000_0000_0010_0000; 376 | gr2<=32'b1000_0000_0000_0000_0000_0000_0000_0001; 377 | 378 | #10 i_datain<=32'b001010_00011_00010_1000000000100000; 379 | gr1<=32'b0000_0000_0000_0000_0000_0000_0000_0001; 380 | gr2<=32'b0000_0000_0000_0000_0000_0000_0000_0011; 381 | 382 | //sltu 383 | #10 i_datain<=32'b000000_00011_00010_00001_00000_101011; 384 | gr1<=32'b1000_0000_0000_0000_0000_0000_0000_0000; 385 | gr2<=32'b1111_1111_1111_1111_1111_1111_1111_1111; 386 | $display("sltu"); 387 | $display("instruction:op:func:ALUctr:ALUsrc: gr1 : gr2 : c : reg_A : reg_B : reg_C : hi : lo : zero : negative : overflow"); 388 | #10 i_datain<=32'b000000_00011_00010_00001_00000_101011; 389 | gr1<=32'b1000_0000_0000_0000_0000_0000_0000_0000; 390 | gr2<=32'b0000_0000_0000_0000_0000_0000_0011_0010; 391 | 392 | #10 i_datain<=32'b000000_00011_00010_00001_00000_101011; 393 | gr1<=32'b1000_1100_0010_0000_0000_0000_0000_0000; 394 | gr2<=32'b0000_0000_0000_0000_0000_0000_0011_0010; 395 | 396 | #10 i_datain<=32'b000000_00011_00010_00001_00000_101011; 397 | gr1<=32'b1000_0000_0000_0000_0000_0000_0000_0000; 398 | gr2<=32'b1111_1111_1111_1111_1111_1111_1111_1111; 399 | 400 | //stliu 401 | #10 i_datain<=32'b001011_00011_00010_0000000000100000; 402 | gr1<=32'b0000_0000_0000_0000_0000_0000_0010_0000; 403 | gr2<=32'b0000_0000_0000_0000_0000_0000_0000_0001; 404 | $display("stliu"); 405 | $display("instruction:op:func:ALUctr:ALUsrc: gr1 : gr2 : c : reg_A : reg_B : reg_C : hi : lo : zero : negative : overflow"); 406 | #10 i_datain<=32'b001011_00011_00010_0000000000010000; 407 | gr1<=32'b0000_0000_0000_0000_0000_0000_0010_0000; 408 | gr2<=32'b0000_0000_0000_0000_0000_0000_0000_0001; 409 | 410 | #10 i_datain<=32'b001011_00011_00010_1000000000100000; 411 | gr1<=32'b1000_0000_0000_0000_0000_0000_0000_0001; 412 | gr2<=32'b1000_0000_0000_0000_0000_0000_0000_0001; 413 | 414 | #10 i_datain<=32'b001011_00011_00010_1000000000100000; 415 | gr1<=32'b0000_0000_0000_0000_0000_0000_0000_0001; 416 | gr2<=32'b0000_0000_0000_0000_0000_0000_0000_0011; 417 | 418 | //sw 419 | #10 i_datain<=32'b101011_00011_00010_1000000000100000; 420 | gr1<=32'b1000_0000_0000_0000_0000_0000_0000_0001; 421 | gr2<=32'b1000_0000_0000_0000_0000_0000_0000_0001; 422 | $display("sw"); 423 | $display("instruction:op:func:ALUctr:ALUsrc: gr1 : gr2 : c : reg_A : reg_B : reg_C : hi : lo : zero : negative : overflow"); 424 | #10 i_datain<=32'b101011_00011_00010_1000000000100000; 425 | gr1<=32'b1000_0000_0000_0000_0000_0000_0010_0000; 426 | gr2<=32'b1000_0000_0000_0000_0000_0000_0000_0001; 427 | 428 | #10 i_datain<=32'b101011_00011_00010_1000000000100000; 429 | gr1<=32'b0000_0000_0000_0000_0000_0000_0000_0001; 430 | gr2<=32'b0000_0000_0000_0000_0000_0000_0000_0011; 431 | 432 | //lw 433 | #10 i_datain<=32'b100011_00011_00010_1000000000100000; 434 | gr1<=32'b1000_0000_0000_0000_0000_0000_0000_0001; 435 | gr2<=32'b1000_0000_0000_0000_0000_0000_0000_0001; 436 | $display("lw"); 437 | $display("instruction:op:func:ALUctr:ALUsrc: gr1 : gr2 : c : reg_A : reg_B : reg_C : hi : lo : zero : negative : overflow"); 438 | #10 i_datain<=32'b100011_00011_00010_1000000000100000; 439 | gr1<=32'b1000_0000_0000_0000_0000_0000_0010_0000; 440 | gr2<=32'b1000_0000_0000_0000_0000_0000_0000_0001; 441 | 442 | #10 i_datain<=32'b100011_00011_00010_1000000000100000; 443 | gr1<=32'b0000_0000_0000_0000_0000_0000_0000_0001; 444 | gr2<=32'b0000_0000_0000_0000_0000_0000_0000_0011; 445 | 446 | //sll 447 | #10 i_datain<=32'b000000_00011_00010_00001_11000_000000; 448 | gr1<=32'b1111_1100_0010_0000_0000_0000_0000_0000; 449 | gr2<=32'b0000_0000_0000_0000_0000_0000_0011_0010; 450 | $display("sll"); 451 | $display("instruction:op:func:ALUctr:ALUsrc: gr1 : gr2 : c : reg_A : reg_B : reg_C : hi : lo : zero : negative : overflow"); 452 | #10 i_datain<=32'b000000_00011_00010_00001_11000_000000; 453 | gr1<=32'b0000_0000_0000_0000_0000_0000_0000_0100; 454 | gr2<=32'b1111_1111_1111_1111_1111_1111_1111_1111; 455 | 456 | //sllv 457 | #10 i_datain<=32'b000000_00011_00010_00001_11000_000100; 458 | gr1<=32'b0000_0000_0000_0000_0000_0000_0010_0000; 459 | gr2<=32'b0000_0000_0000_0000_0000_0000_0011_0010; 460 | $display("sllv"); 461 | $display("instruction:op:func:ALUctr:ALUsrc: gr1 : gr2 : c : reg_A : reg_B : reg_C : hi : lo : zero : negative : overflow"); 462 | #10 i_datain<=32'b000000_00011_00010_00001_11000_000100; 463 | gr1<=32'b0000_0000_0000_0000_0000_0000_0000_0110; 464 | gr2<=32'b0000_0000_0000_0000_0000_0000_0001_0000; 465 | 466 | //srl 467 | #10 i_datain<=32'b000000_00011_00010_00001_11000_000010; 468 | gr1<=32'b1111_1100_0010_0000_0000_0000_0000_0000; 469 | gr2<=32'b0000_0000_0000_0000_0000_0000_0011_0010; 470 | $display("srl"); 471 | $display("instruction:op:func:ALUctr:ALUsrc: gr1 : gr2 : c : reg_A : reg_B : reg_C : hi : lo : zero : negative : overflow"); 472 | #10 i_datain<=32'b000000_00011_00010_00001_11000_000010; 473 | gr1<=32'b0100_0000_0000_0000_0000_0000_0000_0000; 474 | gr2<=32'b1111_1111_1111_1111_1111_1111_1111_1111; 475 | 476 | //srlv 477 | #10 i_datain<=32'b000000_00011_00010_00001_11000_000110; 478 | gr1<=32'b0000_0000_0000_0000_0000_0000_0010_0000; 479 | gr2<=32'b0000_0000_0000_0000_0000_0000_0000_0010; 480 | $display("srlv"); 481 | $display("instruction:op:func:ALUctr:ALUsrc: gr1 : gr2 : c : reg_A : reg_B : reg_C : hi : lo : zero : negative : overflow"); 482 | #10 i_datain<=32'b000000_00011_00010_00001_11000_000110; 483 | gr1<=32'b1000_0000_0000_0000_0000_0000_0000_0110; 484 | gr2<=32'b0000_0000_0000_0000_0000_0000_0000_1000; 485 | 486 | //sra 487 | #10 i_datain<=32'b000000_00011_00010_00001_11000_000011; 488 | gr1<=32'b1111_1100_0010_0000_0000_0000_0000_0000; 489 | gr2<=32'b0000_0000_0000_0000_0000_0000_0011_0010; 490 | $display("sra"); 491 | $display("instruction:op:func:ALUctr:ALUsrc: gr1 : gr2 : c : reg_A : reg_B : reg_C : hi : lo : zero : negative : overflow"); 492 | #10 i_datain<=32'b000000_00011_00010_00001_11000_000011; 493 | gr1<=32'b0100_0000_0000_0000_0000_0000_0000_0000; 494 | gr2<=32'b1111_1111_1111_1111_1111_1111_1111_1111; 495 | 496 | //srav 497 | #10 i_datain<=32'b000000_00011_00010_00001_11000_000111; 498 | gr1<=32'b1000_0000_0000_0000_0000_0000_0010_0000; 499 | gr2<=32'b0000_0000_0000_0000_0000_0000_0001_0010; 500 | $display("srav"); 501 | $display("instruction:op:func:ALUctr:ALUsrc: gr1 : gr2 : c : reg_A : reg_B : reg_C : hi : lo : zero : negative : overflow"); 502 | #10 i_datain<=32'b000000_00011_00010_00001_11000_000111; 503 | gr1<=32'b0000_0000_0000_0000_0001_0000_0000_0110; 504 | gr2<=32'b0000_0000_0000_0000_0000_0000_0001_0000; 505 | 506 | //invalid input 507 | #10 i_datain<=32'b111111_00011_00010_00001_11000_000111; 508 | gr1<=32'b0000_0000_0000_0000_0000_0000_0010_0000; 509 | gr2<=32'b0000_0000_0000_0000_0000_0000_0011_0010; 510 | 511 | #10 i_datain<=32'b101111_00011_00010_00001_11000_000111; 512 | gr1<=32'b0000_0000_0000_0000_0000_0000_0000_0110; 513 | gr2<=32'b1111_1111_1101_1111_1111_1111_1111_1101; 514 | 515 | 516 | 517 | 518 | 519 | 520 | #10 $finish; 521 | end 522 | endmodule -------------------------------------------------------------------------------- /assignment4/CPU.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | module CPU(clock, start, i_datain); 3 | input clock; 4 | input start; 5 | input [319:0] i_datain; 6 | 7 | //general registers 8 | reg [31:0]gr[31:0]; 9 | 10 | //instruction memory 11 | reg [7:0] i_memory[1023:0]; 12 | 13 | //data memory 14 | reg [7:0] d_memory[1023:0]; 15 | 16 | //fetch 17 | reg [31:0] PC; 18 | reg [31:0] PCF; 19 | reg [31:0] PCPlus4F; 20 | reg [31:0] RDF; 21 | 22 | //decoding 23 | 24 | //instruction holder 25 | reg [31:0] InstrD; 26 | reg [31:0] PCPlus4D; 27 | 28 | //registers from control unit 29 | reg RegWriteD; 30 | reg MemtoRegD; 31 | reg MemWriteD; 32 | reg BranchD; 33 | reg [4:0] ALUControlD; 34 | reg ALuSrcD; 35 | reg RegDstD; 36 | reg ShamtD; 37 | reg JumpD; 38 | reg JalD; 39 | reg JrD; 40 | reg MemreadD; 41 | 42 | reg [25:0] TargetD; 43 | reg [31:0] ShamtImmD; 44 | reg [4:0] A1D; 45 | reg [4:0] A2D; 46 | reg [4:0] A3D; 47 | reg [31:0] WD3D; 48 | reg [31:0] RD1D; 49 | reg [31:0] RD2D; 50 | reg [31:0] SignExtend; 51 | reg [4:0] shamt; 52 | reg [4:0] rt; 53 | reg [4:0] rd; 54 | 55 | //execution 56 | reg RegWriteE; 57 | reg MemtoRegE; 58 | reg MemWriteE; 59 | reg BranchE; 60 | reg [4:0] ALUControlE; 61 | reg ALuSrcE; 62 | reg RegDstE; 63 | reg ShamtE; 64 | reg JalE; 65 | reg RsHazardE; 66 | reg RtHazardE; 67 | reg MemreadE; 68 | reg stall; 69 | 70 | reg [31:0] ShamtImmE; 71 | reg [4:0] RtE; 72 | reg [4:0] RdE; 73 | reg [4:0] WriteRegE; 74 | reg [31:0] SignImmE; 75 | reg [31:0] PCPlus4E; 76 | reg [31:0] SrcAE; 77 | reg [31:0] SrcBE; 78 | reg [31:0] WriteDataE; 79 | reg [31:0] ALUOutE; 80 | reg [31:0] PCBranchE; 81 | reg ZeroE; 82 | reg negativeE; 83 | reg overflowE; 84 | 85 | //memory 86 | reg RegWriteM; 87 | reg MemtoRegM; 88 | reg MemWriteM; 89 | reg BranchM; 90 | reg RsHazardM; 91 | reg RtHazardM; 92 | 93 | reg ZeroM; 94 | reg PCSrcM; 95 | reg [31:0] AM; 96 | reg [31:0] WDM; 97 | reg [31:0] ALUOutM; 98 | reg [4:0] WriteRegM; 99 | reg [31:0] PCBranchM; 100 | reg [31:0] RDM; 101 | 102 | //write 103 | reg RegWriteW; 104 | reg MemtoRegW; 105 | 106 | reg [31:0] ALUOutW; 107 | reg [31:0] ResultW; 108 | reg [4:0] WriteRegW; 109 | 110 | always @(start) 111 | begin 112 | gr[0] = 32'h0000_0000; 113 | PC = 32'h0000_0000; 114 | PCSrcM = 1'b0; 115 | JumpD = 1'b0; 116 | PCPlus4F = 32'h0000_0000; 117 | RsHazardE = 1'b0; 118 | RtHazardE = 1'b0; 119 | RsHazardM = 1'b0; 120 | RtHazardM = 1'b0; 121 | stall = 1'b0; 122 | i_memory[0]=i_datain[319:312]; 123 | i_memory[1]=i_datain[311:304]; 124 | i_memory[2]=i_datain[303:296]; 125 | i_memory[3]=i_datain[295:288]; 126 | i_memory[4]=i_datain[287:280]; 127 | i_memory[5]=i_datain[279:272]; 128 | i_memory[6]=i_datain[271:264]; 129 | i_memory[7]=i_datain[263:256]; 130 | i_memory[8]=i_datain[255:248]; 131 | i_memory[9]=i_datain[247:240]; 132 | i_memory[10]=i_datain[239:232]; 133 | i_memory[11]=i_datain[231:224]; 134 | i_memory[12]=i_datain[223:216]; 135 | i_memory[13]=i_datain[215:208]; 136 | i_memory[14]=i_datain[207:200]; 137 | i_memory[15]=i_datain[199:192]; 138 | i_memory[16]=i_datain[191:184]; 139 | i_memory[17]=i_datain[183:176]; 140 | i_memory[18]=i_datain[175:168]; 141 | i_memory[19]=i_datain[167:160]; 142 | i_memory[20]=i_datain[159:152]; 143 | i_memory[21]=i_datain[151:144]; 144 | i_memory[22]=i_datain[143:136]; 145 | i_memory[23]=i_datain[135:128]; 146 | i_memory[24]=i_datain[127:120]; 147 | i_memory[25]=i_datain[119:112]; 148 | i_memory[26]=i_datain[111:104]; 149 | i_memory[27]=i_datain[103:96]; 150 | i_memory[28]=i_datain[95:88]; 151 | i_memory[29]=i_datain[87:80]; 152 | i_memory[30]=i_datain[79:72]; 153 | i_memory[31]=i_datain[71:64]; 154 | i_memory[32]=i_datain[63:56]; 155 | i_memory[33]=i_datain[55:48]; 156 | i_memory[34]=i_datain[47:40]; 157 | i_memory[35]=i_datain[39:32]; 158 | i_memory[36]=i_datain[31:24]; 159 | i_memory[37]=i_datain[23:16]; 160 | i_memory[38]=i_datain[15:8]; 161 | i_memory[39]=i_datain[7:0]; 162 | end 163 | 164 | //the circuit of the PC 165 | always @(PCPlus4F, PCBranchM, PCSrcM, JumpD, TargetD, JalD, JrD, RsHazardE, RsHazardM, A1D, A3D) 166 | begin 167 | if(JrD==1'b1) 168 | begin 169 | if(RsHazardE==1'b1) 170 | begin 171 | PC = ALUOutE; 172 | end 173 | 174 | else if(RsHazardM==1'b1) 175 | begin 176 | PC = MemtoRegM ? {d_memory[ALUOutM],d_memory[ALUOutM+1],d_memory[ALUOutM+2],d_memory[ALUOutM+3]} : ALUOutM; 177 | end 178 | 179 | else if(A1D==A3D) 180 | begin 181 | PC = WD3D; 182 | end 183 | 184 | else 185 | begin 186 | PC = gr[A1D]; 187 | end 188 | end 189 | 190 | else if(JumpD==1'b1||JalD==1'b1) 191 | begin 192 | PC = TargetD; 193 | end 194 | 195 | else if(PCSrcM==1'b1) 196 | begin 197 | PC = PCBranchM; 198 | end 199 | 200 | else 201 | begin 202 | PC = PCPlus4F; 203 | end 204 | end 205 | 206 | //within the fetch part 207 | always @(posedge clock) 208 | begin 209 | if(stall==1'b0) 210 | begin 211 | PCF <= PC; 212 | end 213 | end 214 | 215 | //the circuits of data fectch 216 | always @(PCF) 217 | begin 218 | RDF = {i_memory[PCF], i_memory[PCF+1], i_memory[PCF+2], i_memory[PCF+3]}; 219 | PCPlus4F = PCF + 4; 220 | end 221 | 222 | //fetch/decode 223 | always @(posedge clock) 224 | begin 225 | if(PCSrcM==1'b1) 226 | begin 227 | InstrD <= 32'h0000_0000; 228 | PCPlus4D <= PCPlus4F; 229 | end 230 | 231 | else if(stall==1'b0) 232 | begin 233 | if(JumpD==1'b1||JalD==1'b1||JrD==1'b1) 234 | begin 235 | InstrD <= 32'hx; 236 | end 237 | 238 | else 239 | begin 240 | InstrD <= RDF; 241 | end 242 | PCPlus4D <= PCPlus4F; 243 | end 244 | end 245 | 246 | //the circuits of the data decoding 247 | always @(InstrD, WriteRegW, ResultW) 248 | begin 249 | A1D = InstrD[25:21]; 250 | A2D = InstrD[20:16]; 251 | A3D = WriteRegW; 252 | WD3D = ResultW; 253 | rt = InstrD[20:16]; 254 | rd = InstrD[15:11]; 255 | SignExtend = {{16{InstrD[15]}}, InstrD[15:0]}; 256 | ShamtImmD = {{16{1'b0}}, InstrD[10:6]}; 257 | JumpD = 1'b0; 258 | JalD = 1'b0; 259 | JrD = 1'b0; 260 | MemreadD = 1'b0; 261 | TargetD = {PCPlus4D[31:28], InstrD[25:0], 2'b00}; 262 | 263 | //control unit 264 | if(InstrD[31:26]==6'b00_0000) 265 | begin 266 | ShamtD = 1'b0; 267 | RegDstD = 1'b1; 268 | ALuSrcD = 1'b0; 269 | MemtoRegD = 1'b0; 270 | RegWriteD = 1'b1; 271 | MemWriteD = 1'b0; 272 | BranchD = 1'b0; 273 | 274 | //add 275 | if(InstrD[5:0]==6'h20) 276 | begin 277 | ALUControlD = 5'b0_0000; 278 | end 279 | 280 | //addu 281 | if(InstrD[5:0]==6'h21) 282 | begin 283 | ALUControlD = 5'b0_1011; 284 | end 285 | 286 | //sub 287 | else if(InstrD[5:0]==6'h22||InstrD[5:0]==6'h23) 288 | begin 289 | ALUControlD = 5'b0_0001; 290 | end 291 | 292 | //subu 293 | else if(InstrD[5:0]==6'h23) 294 | begin 295 | ALUControlD = 5'b0_1100; 296 | end 297 | 298 | //and 299 | else if(InstrD[5:0]==6'h24) 300 | begin 301 | ALUControlD = 5'b0_0010; 302 | end 303 | 304 | //or 305 | else if(InstrD[5:0]==6'h25) 306 | begin 307 | ALUControlD = 5'b0_0011; 308 | end 309 | 310 | //nor 311 | else if(InstrD[5:0]==6'h27) 312 | begin 313 | ALUControlD = 5'b0_0100; 314 | end 315 | 316 | //xor 317 | else if(InstrD[5:0]==6'h27) 318 | begin 319 | ALUControlD = 5'b0_0101; 320 | end 321 | 322 | //sll 323 | else if(InstrD[5:0]==6'h0) 324 | begin 325 | ALUControlD = 5'b0_0110; 326 | ShamtD = 1'b1; 327 | end 328 | 329 | //srl 330 | else if(InstrD[5:0]==6'h2) 331 | begin 332 | ALUControlD = 5'b0_0111; 333 | ShamtD = 1'b1; 334 | end 335 | 336 | //sra 337 | else if(InstrD[5:0]==6'h3) 338 | begin 339 | ALUControlD = 5'b0_1000; 340 | ShamtD = 1'b1; 341 | end 342 | 343 | //sllv 344 | else if(InstrD[5:0]==6'h4) 345 | begin 346 | ALUControlD = 5'b0_0110; 347 | end 348 | 349 | //srlv 350 | else if(InstrD[5:0]==6'h6) 351 | begin 352 | ALUControlD = 5'b0_0111; 353 | end 354 | 355 | //srav 356 | else if(InstrD[5:0]==6'h7) 357 | begin 358 | ALUControlD = 5'b0_1000; 359 | end 360 | 361 | //slt 362 | else if(InstrD[5:0]==6'h2a) 363 | begin 364 | ALUControlD = 5'b0_1010; 365 | end 366 | 367 | //jr 368 | else if(InstrD[5:0]==6'h8) 369 | begin 370 | JrD = 1'b1; 371 | RegWriteD = 1'b0; 372 | end 373 | 374 | end 375 | 376 | //addi 377 | else if(InstrD[31:26]==6'h8||InstrD[31:26]==6'h9) 378 | begin 379 | ShamtD = 1'b0; 380 | RegDstD = 1'b0; 381 | ALuSrcD = 1'b1; 382 | MemtoRegD = 1'b0; 383 | RegWriteD = 1'b1; 384 | MemWriteD = 1'b0; 385 | BranchD = 1'b0; 386 | ALUControlD = 5'b0_0000; 387 | end 388 | 389 | //addiu 390 | else if(InstrD[31:26]==6'h9) 391 | begin 392 | ShamtD = 1'b0; 393 | RegDstD = 1'b0; 394 | ALuSrcD = 1'b1; 395 | MemtoRegD = 1'b0; 396 | RegWriteD = 1'b1; 397 | MemWriteD = 1'b0; 398 | BranchD = 1'b0; 399 | ALUControlD = 5'b0_1011; 400 | end 401 | 402 | //andi 403 | else if(InstrD[31:26]==6'hc) 404 | begin 405 | ShamtD = 1'b0; 406 | RegDstD = 1'b0; 407 | ALuSrcD = 1'b1; 408 | MemtoRegD = 1'b0; 409 | RegWriteD = 1'b1; 410 | MemWriteD = 1'b0; 411 | BranchD = 1'b0; 412 | ALUControlD = 5'b1_0010; 413 | end 414 | 415 | //ori 416 | else if(InstrD[31:26]==6'hd) 417 | begin 418 | ShamtD = 1'b0; 419 | RegDstD = 1'b0; 420 | ALuSrcD = 1'b1; 421 | MemtoRegD = 1'b0; 422 | RegWriteD = 1'b1; 423 | MemWriteD = 1'b0; 424 | BranchD = 1'b0; 425 | ALUControlD = 5'b1_0011; 426 | end 427 | 428 | //beq 429 | else if(InstrD[31:26]==6'h4) 430 | begin 431 | ShamtD = 1'b0; 432 | RegDstD = 1'b0; 433 | ALuSrcD = 1'b0; 434 | MemtoRegD = 1'b0; 435 | RegWriteD = 1'b0; 436 | MemWriteD = 1'b0; 437 | BranchD = 1'b1; 438 | ALUControlD = 5'b0_0001; 439 | end 440 | 441 | //bne 442 | else if(InstrD[31:26]==6'h5) 443 | begin 444 | ShamtD = 1'b0; 445 | RegDstD = 1'b0; 446 | ALuSrcD = 1'b0; 447 | MemtoRegD = 1'b0; 448 | RegWriteD = 1'b0; 449 | MemWriteD = 1'b0; 450 | BranchD = 1'b1; 451 | ALUControlD = 5'b0_1001; 452 | end 453 | 454 | //lw 455 | else if(InstrD[31:26]==6'h23) 456 | begin 457 | ShamtD = 1'b0; 458 | RegDstD = 1'b0; 459 | ALuSrcD = 1'b1; 460 | MemtoRegD = 1'b1; 461 | RegWriteD = 1'b1; 462 | MemWriteD = 1'b0; 463 | BranchD = 1'b0; 464 | ALUControlD = 5'b0_0000; 465 | MemreadD = 1'b1; 466 | end 467 | 468 | //sw 469 | else if(InstrD[31:26]==6'h2b) 470 | begin 471 | ShamtD = 1'b0; 472 | RegDstD = 1'b0; 473 | ALuSrcD = 1'b1; 474 | MemtoRegD = 1'b1; 475 | RegWriteD = 1'b0; 476 | MemWriteD = 1'b1; 477 | BranchD = 1'b0; 478 | ALUControlD = 5'b0_0000; 479 | end 480 | 481 | //j 482 | else if(InstrD[31:26]==6'h2) 483 | begin 484 | RegWriteD = 1'b0; 485 | MemWriteD = 1'b0; 486 | BranchD = 1'b0; 487 | JumpD = 1'b1; 488 | end 489 | 490 | //jal 491 | else if(InstrD[31:26]==6'h3) 492 | begin 493 | ALUControlD = 5'b0_0000; 494 | RegWriteD = 1'b1; 495 | MemWriteD = 1'b0; 496 | BranchD = 1'b0; 497 | JalD = 1'b1; 498 | end 499 | 500 | 501 | end 502 | 503 | //registers 504 | always @(negedge clock) 505 | begin 506 | if(RegWriteW) 507 | begin 508 | gr[A3D] <= WD3D; 509 | end 510 | end 511 | 512 | always @(posedge clock) 513 | begin 514 | if(RsHazardE==1'b1) 515 | begin 516 | RD1D <= ALUOutE; 517 | end 518 | 519 | else if(RsHazardM==1'b1) 520 | begin 521 | RD1D <= MemtoRegM ? {d_memory[ALUOutM],d_memory[ALUOutM+1],d_memory[ALUOutM+2],d_memory[ALUOutM+3]} : ALUOutM; 522 | end 523 | 524 | else 525 | begin 526 | RD1D <= gr[A1D]; 527 | end 528 | 529 | if(RtHazardE==1'b1) 530 | begin 531 | RD2D <= ALUOutE; 532 | end 533 | 534 | else if(RtHazardM==1'b1) 535 | begin 536 | RD2D <= MemtoRegM ? {d_memory[ALUOutM],d_memory[ALUOutM+1],d_memory[ALUOutM+2],d_memory[ALUOutM+3]} : ALUOutM; 537 | end 538 | 539 | else 540 | begin 541 | RD2D <= gr[A2D]; 542 | end 543 | end 544 | 545 | //decode/execution 546 | always @(posedge clock) 547 | begin 548 | if(stall==1'b1) 549 | begin 550 | RegWriteE <= 1'b0; 551 | MemtoRegE <= MemtoRegD; 552 | MemWriteE <= 1'b0; 553 | BranchE <= 1'b0; 554 | ALUControlE <= 5'b0; 555 | ALuSrcE <= ALuSrcD; 556 | RegDstE <= RegDstD; 557 | WriteDataE <= RD2D; 558 | RtE <= rt; 559 | RdE <= rd; 560 | SignImmE <= SignExtend; 561 | JalE <= 1'b0; 562 | PCPlus4E <= PCPlus4D; 563 | ShamtE <= ShamtD; 564 | ShamtImmE <= ShamtImmD; 565 | MemreadE <= MemreadD; 566 | end 567 | 568 | else if(PCSrcM==1'b1) 569 | begin 570 | RegWriteE <= 1'b0; 571 | MemtoRegE <= 1'b0; 572 | MemWriteE <= 1'b0; 573 | BranchE <= 1'b0; 574 | ALUControlE <= 5'b0; 575 | ALuSrcE <= 1'b0; 576 | RegDstE <= 1'b0; 577 | WriteDataE <= RD2D; 578 | RtE <= rt; 579 | RdE <= rd; 580 | SignImmE <= SignExtend; 581 | JalE <= 1'b0; 582 | PCPlus4E <= PCPlus4D; 583 | ShamtE <= ShamtD; 584 | ShamtImmE <= ShamtImmD; 585 | MemreadE <= 1'b0; 586 | end 587 | 588 | else 589 | begin 590 | RegWriteE <= RegWriteD; 591 | MemtoRegE <= MemtoRegD; 592 | MemWriteE <= MemWriteD; 593 | BranchE <= BranchD; 594 | ALUControlE <= ALUControlD; 595 | ALuSrcE <= ALuSrcD; 596 | RegDstE <= RegDstD; 597 | WriteDataE <= RD2D; 598 | RtE <= rt; 599 | RdE <= rd; 600 | SignImmE <= SignExtend; 601 | JalE <= JalD; 602 | PCPlus4E <= PCPlus4D; 603 | ShamtE <= ShamtD; 604 | ShamtImmE <= ShamtImmD; 605 | MemreadE <= MemreadD; 606 | end 607 | end 608 | 609 | //circuits of the execution 610 | always @(MemWriteE, ALuSrcE, RegDstE, WriteDataE, RtE, RdE, SignImmE, PCPlus4E, 611 | ShamtE, ShamtImmE, RD1D, RD2D, JalE) 612 | begin 613 | 614 | //SrcAE 615 | if(JalE==1'b1) 616 | begin 617 | SrcAE = PCPlus4E; 618 | end 619 | 620 | else if(ShamtE==1'b1) 621 | begin 622 | SrcAE = ShamtImmE; 623 | end 624 | 625 | else 626 | begin 627 | SrcAE = RD1D; 628 | end 629 | 630 | 631 | //SrcBE 632 | if(JalE==1'b1) 633 | begin 634 | SrcBE = 32'b0; 635 | end 636 | 637 | else if(ALuSrcE==1'b1) 638 | begin 639 | SrcBE = SignImmE; 640 | end 641 | 642 | else 643 | begin 644 | SrcBE = RD2D; 645 | end 646 | 647 | //WriteRegE 648 | if(JalE==1'b1) 649 | begin 650 | WriteRegE = 32'd31; 651 | end 652 | 653 | else if(RegDstE==1'b1) 654 | begin 655 | WriteRegE = RdE; 656 | end 657 | 658 | else 659 | begin 660 | WriteRegE = RtE; 661 | end 662 | 663 | PCBranchE = (SignImmE<<2) + PCPlus4E; 664 | 665 | end 666 | 667 | //Alu circuits 668 | //used to dectect overflowE 669 | reg extra; 670 | 671 | parameter gr0 = 32'h0000_0000; 672 | parameter Width = 32; 673 | parameter MSB = Width - 1; 674 | reg signed [31:0] reg_A; 675 | reg signed [31:0] reg_B; 676 | reg [31:0] unsigned_reg_A; 677 | reg [31:0] unsigned_reg_B; 678 | 679 | 680 | always @(ALUControlE,SrcAE,SrcBE) 681 | begin 682 | reg_A = SrcAE; 683 | unsigned_reg_A = SrcAE; 684 | 685 | reg_B = SrcBE; 686 | unsigned_reg_B = SrcBE; 687 | 688 | 689 | //add/addi 690 | if(ALUControlE==5'b0_0000) 691 | begin 692 | {extra, ALUOutE} = {reg_A[MSB], reg_A} + {reg_B[MSB], reg_B}; 693 | ZeroE = ALUOutE ? 0 : 1; 694 | negativeE = ALUOutE[MSB]; 695 | overflowE = extra ^ ALUOutE[MSB]; 696 | end 697 | 698 | //addu/addiu 699 | else if(ALUControlE==5'b0_1011) 700 | begin 701 | ALUOutE = unsigned_reg_A + unsigned_reg_B; 702 | ZeroE = ALUOutE ? 0 :1; 703 | negativeE = 1'b0; 704 | overflowE = 1'b0; 705 | end 706 | 707 | //sub 708 | else if(ALUControlE==5'b0_0001) 709 | begin 710 | {extra, ALUOutE} = {reg_A[MSB], reg_A} - {reg_B[MSB], reg_B}; 711 | ZeroE = ALUOutE ? 0 : 1; 712 | negativeE = ALUOutE[MSB]; 713 | overflowE = extra ^ ALUOutE[MSB]; 714 | end 715 | 716 | //sub 717 | else if(ALUControlE==5'b0_1001) 718 | begin 719 | {extra, ALUOutE} = {reg_A[MSB], reg_A} - {reg_B[MSB], reg_B}; 720 | ZeroE = ALUOutE ? 1 : 0; 721 | negativeE = ALUOutE[MSB]; 722 | overflowE = extra ^ ALUOutE[MSB]; 723 | end 724 | 725 | //subu 726 | else if(ALUControlE==5'b0_1100) 727 | begin 728 | ALUOutE = unsigned_reg_A - unsigned_reg_B; 729 | ZeroE = ALUOutE ? 0 :1; 730 | negativeE = 1'b0; 731 | overflowE = 1'b0; 732 | end 733 | 734 | //and 735 | else if(ALUControlE==5'b0_0010) 736 | begin 737 | ALUOutE = reg_A & reg_B; 738 | overflowE = 1'b0; 739 | negativeE = ALUOutE[MSB]; 740 | ZeroE = ALUOutE ? 0 : 1; 741 | end 742 | 743 | //andi 744 | else if(ALUControlE==5'b1_0010) 745 | begin 746 | reg_A = {{16{1'b0}}, reg_A[15:0]}; 747 | ALUOutE = reg_A & reg_B; 748 | overflowE = 1'b0; 749 | negativeE = ALUOutE[MSB]; 750 | ZeroE = ALUOutE ? 0 : 1; 751 | end 752 | 753 | //nor 754 | else if(ALUControlE==5'b0_0100) 755 | begin 756 | ALUOutE = ~(reg_A | reg_B); 757 | overflowE = 1'b0; 758 | negativeE = ALUOutE[MSB]; 759 | ZeroE = ALUOutE ? 0 : 1; 760 | end 761 | 762 | //or 763 | else if(ALUControlE==5'b0_0011) 764 | begin 765 | ALUOutE = reg_A | reg_B; 766 | overflowE = 1'b0; 767 | negativeE = ALUOutE[MSB]; 768 | ZeroE = ALUOutE ? 0 : 1; 769 | end 770 | 771 | //ori 772 | else if(ALUControlE==5'b1_0011) 773 | begin 774 | reg_A = {{16{1'b0}}, reg_A[15:0]}; 775 | ALUOutE = reg_A | reg_B; 776 | overflowE = 1'b0; 777 | negativeE = ALUOutE[MSB]; 778 | ZeroE = ALUOutE ? 0 : 1; 779 | end 780 | 781 | //xor 782 | else if(ALUControlE==5'b0_0101) 783 | begin 784 | ALUOutE = reg_A ^ reg_B; 785 | overflowE = 1'b0; 786 | negativeE = ALUOutE[MSB]; 787 | ZeroE = ALUOutE ? 0 : 1; 788 | end 789 | 790 | //slt 791 | else if(ALUControlE==5'b0_1010) 792 | begin 793 | ALUOutE = reg_A < reg_B; 794 | overflowE = 1'b0; 795 | negativeE = ALUOutE ? 1 : 0; 796 | ZeroE = ALUOutE ? 0 : 1; 797 | end 798 | 799 | //sll/sllv 800 | else if(ALUControlE==5'b0_0110) 801 | begin 802 | ALUOutE = reg_B << reg_A; 803 | overflowE = 1'b0; 804 | negativeE = ALUOutE[MSB]; 805 | ZeroE = ALUOutE ? 0 : 1; 806 | end 807 | 808 | //srl/srlv 809 | else if(ALUControlE==5'b0_0111) 810 | begin 811 | ALUOutE = reg_B >> reg_A; 812 | overflowE = 1'b0; 813 | negativeE = ALUOutE[MSB]; 814 | ZeroE = ALUOutE ? 0 : 1; 815 | end 816 | 817 | //sra/srav 818 | else if(ALUControlE==5'b0_1000) 819 | begin 820 | ALUOutE = reg_B >>> reg_A; 821 | overflowE = 1'b0; 822 | negativeE = ALUOutE[MSB]; 823 | ZeroE = ALUOutE ? 0 : 1; 824 | end 825 | 826 | end 827 | 828 | //hazrad for instructions closed together 829 | always @(ALUControlE,SrcAE,SrcBE,MemreadE, PCSrcM, JrD) 830 | begin 831 | if(PCSrcM==1'b1) 832 | begin 833 | RsHazardE = 1'b0; 834 | RtHazardE = 1'b0; 835 | RsHazardM = 1'b0; 836 | RtHazardM = 1'b0; 837 | stall = 1'b0; 838 | end 839 | 840 | else 841 | begin 842 | //hazard for Rs 843 | if((RegWriteE==1'b1)&&(WriteRegE!=5'b0)&&(WriteRegE==InstrD[25:21])) 844 | begin 845 | RsHazardE = 1'b1; 846 | end 847 | else 848 | begin 849 | RsHazardE = 1'b0; 850 | end 851 | 852 | //hazard for Rt 853 | if((RegWriteE==1'b1)&&(WriteRegE!=5'b0)&&(WriteRegE==InstrD[20:16])) 854 | begin 855 | RtHazardE = 1'b1; 856 | end 857 | else 858 | begin 859 | RtHazardE = 1'b0; 860 | end 861 | 862 | if(MemreadE==1'b1&&((RtE==InstrD[25:21])||(RtE==InstrD[20:16]))) 863 | begin 864 | stall = 1'b1; 865 | end 866 | 867 | else 868 | begin 869 | stall = 1'b0; 870 | end 871 | end 872 | 873 | end 874 | 875 | //execution/memory 876 | always @(posedge clock) 877 | begin 878 | if(PCSrcM==1'b1) 879 | begin 880 | RegWriteM <= 1'b0; 881 | MemtoRegM <= 1'b0; 882 | MemWriteM <= 1'b0; 883 | BranchM <= 1'b0; 884 | ZeroM <= ZeroE; 885 | ALUOutM <= ALUOutE; 886 | WriteRegM <= 5'b0; 887 | PCBranchM <= 1'b0; 888 | end 889 | 890 | else 891 | begin 892 | RegWriteM <= RegWriteE; 893 | MemtoRegM <= MemtoRegE; 894 | MemWriteM <= MemWriteE; 895 | BranchM <= BranchE; 896 | ZeroM <= ZeroE; 897 | ALUOutM <= ALUOutE; 898 | WriteRegM <= WriteRegE; 899 | PCBranchM <= PCBranchE; 900 | end 901 | end 902 | 903 | //circuits of the memory 904 | always @(MemWriteM, BranchM, ZeroM, ALUOutM, 905 | WriteDataE) 906 | begin 907 | PCSrcM = BranchM & ZeroM; 908 | AM = ALUOutM; 909 | WDM = WriteDataE; 910 | 911 | //hazard for Rs 912 | if((RegWriteM==1'b1)&&(WriteRegM!=5'b0)&&(WriteRegM==InstrD[25:21])) 913 | begin 914 | RsHazardM = 1'b1; 915 | end 916 | else 917 | begin 918 | RsHazardM = 1'b0; 919 | end 920 | 921 | //hazard for Rt 922 | if((RegWriteM==1'b1)&&(WriteRegM!=5'b0)&&(WriteRegM==InstrD[20:16])) 923 | begin 924 | RtHazardM = 1'b1; 925 | end 926 | else 927 | begin 928 | RtHazardM = 1'b0; 929 | end 930 | 931 | end 932 | 933 | //data memory 934 | always @(posedge clock) 935 | begin 936 | if(MemWriteM) 937 | begin 938 | {d_memory[ALUOutM],d_memory[ALUOutM+1],d_memory[ALUOutM+2],d_memory[ALUOutM+3]} <= WDM; 939 | RDM <= WDM; 940 | end 941 | 942 | else 943 | begin 944 | RDM <= {d_memory[ALUOutM],d_memory[ALUOutM+1],d_memory[ALUOutM+2],d_memory[ALUOutM+3]}; 945 | end 946 | end 947 | 948 | //memory/write 949 | always @(posedge clock) 950 | begin 951 | RegWriteW <= RegWriteM; 952 | MemtoRegW <= MemtoRegM; 953 | ALUOutW <= ALUOutM; 954 | WriteRegW <= WriteRegM; 955 | end 956 | 957 | //circuits of the write 958 | always @(ALUOutW, RDM, MemtoRegW) 959 | begin 960 | ResultW = MemtoRegW ? RDM : ALUOutW; 961 | end 962 | 963 | endmodule -------------------------------------------------------------------------------- /assignment4/report.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MoyuST/CSC3050-Computer-Architecture/e4dc51b0300e825618730de590b45da707f6adf1/assignment4/report.pdf -------------------------------------------------------------------------------- /assignment4/test_CPU_1.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns/1ps 2 | 3 | // general register 4 | `define gr0 5'b00000 5 | `define gr1 5'b00001 6 | `define gr2 5'b00010 7 | `define gr3 5'b00011 8 | `define gr4 5'b00100 9 | `define gr5 5'b00101 10 | `define gr6 5'b00110 11 | `define gr7 5'b00111 12 | 13 | module CPU_test; 14 | 15 | //Inputs 16 | reg clock; 17 | reg start; 18 | reg [319:0] in_instruction; 19 | 20 | CPU a(.clock(clock),.start(start),.i_datain(in_instruction)); 21 | 22 | initial begin 23 | clock=0; 24 | start=0; 25 | 26 | in_instruction[319:288]={6'b001000, `gr0, `gr1, 16'd1};//addi 27 | in_instruction[287:256]={6'b101011, `gr0, `gr0, 16'b0}; //sw 28 | in_instruction[255:224]={6'b001000, `gr0, `gr3, 16'b10};//addi 29 | in_instruction[223:192]={6'b100011, `gr0, `gr2, 16'b0}; //lw 30 | in_instruction[191:160]={6'b0, `gr1, `gr0, `gr4, 5'b0, 6'b100010};//sub 31 | in_instruction[159:128]={6'b100, `gr0, `gr0, 16'b1};//branch 32 | in_instruction[127:96]={6'b0, `gr1, `gr1, `gr1, 5'b0, 6'b100000};//add 33 | in_instruction[95:64]={6'b0, `gr1, `gr1, `gr1, 5'b100, 6'b000000};//sll 34 | 35 | $display(" pc : gr1 : gr2 : gr3 : gr4 : $ra : data memory[0:31] :instruction"); 36 | #period $display("%h:%h:%h:%h:%h:%h: %h :%h",a.PC,a.gr[1],a.gr[2],a.gr[3],a.gr[4],a.gr[31],{a.d_memory[0],a.d_memory[1],a.d_memory[2],a.d_memory[3]},a.InstrD); 37 | #period $display("%h:%h:%h:%h:%h:%h: %h :%h",a.PC,a.gr[1],a.gr[2],a.gr[3],a.gr[4],a.gr[31],{a.d_memory[0],a.d_memory[1],a.d_memory[2],a.d_memory[3]},a.InstrD); 38 | #period $display("%h:%h:%h:%h:%h:%h: %h :%h",a.PC,a.gr[1],a.gr[2],a.gr[3],a.gr[4],a.gr[31],{a.d_memory[0],a.d_memory[1],a.d_memory[2],a.d_memory[3]},a.InstrD); 39 | #period $display("%h:%h:%h:%h:%h:%h: %h :%h",a.PC,a.gr[1],a.gr[2],a.gr[3],a.gr[4],a.gr[31],{a.d_memory[0],a.d_memory[1],a.d_memory[2],a.d_memory[3]},a.InstrD); 40 | #period $display("%h:%h:%h:%h:%h:%h: %h :%h",a.PC,a.gr[1],a.gr[2],a.gr[3],a.gr[4],a.gr[31],{a.d_memory[0],a.d_memory[1],a.d_memory[2],a.d_memory[3]},a.InstrD); 41 | #period $display("%h:%h:%h:%h:%h:%h: %h :%h",a.PC,a.gr[1],a.gr[2],a.gr[3],a.gr[4],a.gr[31],{a.d_memory[0],a.d_memory[1],a.d_memory[2],a.d_memory[3]},a.InstrD); 42 | #period $display("%h:%h:%h:%h:%h:%h: %h :%h",a.PC,a.gr[1],a.gr[2],a.gr[3],a.gr[4],a.gr[31],{a.d_memory[0],a.d_memory[1],a.d_memory[2],a.d_memory[3]},a.InstrD); 43 | #period $display("%h:%h:%h:%h:%h:%h: %h :%h",a.PC,a.gr[1],a.gr[2],a.gr[3],a.gr[4],a.gr[31],{a.d_memory[0],a.d_memory[1],a.d_memory[2],a.d_memory[3]},a.InstrD); 44 | #period $display("%h:%h:%h:%h:%h:%h: %h :%h",a.PC,a.gr[1],a.gr[2],a.gr[3],a.gr[4],a.gr[31],{a.d_memory[0],a.d_memory[1],a.d_memory[2],a.d_memory[3]},a.InstrD); 45 | #period $display("%h:%h:%h:%h:%h:%h: %h :%h",a.PC,a.gr[1],a.gr[2],a.gr[3],a.gr[4],a.gr[31],{a.d_memory[0],a.d_memory[1],a.d_memory[2],a.d_memory[3]},a.InstrD); 46 | #period $display("%h:%h:%h:%h:%h:%h: %h :%h",a.PC,a.gr[1],a.gr[2],a.gr[3],a.gr[4],a.gr[31],{a.d_memory[0],a.d_memory[1],a.d_memory[2],a.d_memory[3]},a.InstrD); 47 | #period $display("%h:%h:%h:%h:%h:%h: %h :%h",a.PC,a.gr[1],a.gr[2],a.gr[3],a.gr[4],a.gr[31],{a.d_memory[0],a.d_memory[1],a.d_memory[2],a.d_memory[3]},a.InstrD); 48 | #period $display("%h:%h:%h:%h:%h:%h: %h :%h",a.PC,a.gr[1],a.gr[2],a.gr[3],a.gr[4],a.gr[31],{a.d_memory[0],a.d_memory[1],a.d_memory[2],a.d_memory[3]},a.InstrD); 49 | #period $display("%h:%h:%h:%h:%h:%h: %h :%h",a.PC,a.gr[1],a.gr[2],a.gr[3],a.gr[4],a.gr[31],{a.d_memory[0],a.d_memory[1],a.d_memory[2],a.d_memory[3]},a.InstrD); 50 | #period $display("%h:%h:%h:%h:%h:%h: %h :%h",a.PC,a.gr[1],a.gr[2],a.gr[3],a.gr[4],a.gr[31],{a.d_memory[0],a.d_memory[1],a.d_memory[2],a.d_memory[3]},a.InstrD); 51 | #period $display("%h:%h:%h:%h:%h:%h: %h :%h",a.PC,a.gr[1],a.gr[2],a.gr[3],a.gr[4],a.gr[31],{a.d_memory[0],a.d_memory[1],a.d_memory[2],a.d_memory[3]},a.InstrD); 52 | #period $finish; 53 | end 54 | 55 | parameter period=10; 56 | always #5clock=~clock; 57 | 58 | endmodule -------------------------------------------------------------------------------- /assignment4/test_CPU_2.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns/1ps 2 | 3 | // general register 4 | `define gr0 5'b00000 5 | `define gr1 5'b00001 6 | `define gr2 5'b00010 7 | `define gr3 5'b00011 8 | `define gr4 5'b00100 9 | `define gr5 5'b00101 10 | `define gr6 5'b00110 11 | `define gr7 5'b00111 12 | 13 | module CPU_test; 14 | 15 | //Inputs 16 | reg clock; 17 | reg start; 18 | reg [319:0] in_instruction; 19 | 20 | CPU a(.clock(clock),.start(start),.i_datain(in_instruction)); 21 | 22 | initial begin 23 | clock=0; 24 | start=0; 25 | 26 | in_instruction[319:288]={6'b001000, `gr0, `gr1, 16'd1};//addi 27 | in_instruction[287:256]={6'b000011, 26'b111}; //jal 28 | in_instruction[255:224]={6'b001000, `gr0, `gr3, 16'b10};//addi 29 | in_instruction[223:192]={6'b100011, `gr0, `gr2, 16'b0}; //lw 30 | in_instruction[191:160]={6'b0, `gr1, `gr0, `gr4, 5'b0, 6'b100010};//sub 31 | in_instruction[159:128]={6'b100, `gr0, `gr0, 16'b1};//branch 32 | in_instruction[127:96]={6'b0, `gr1, `gr1, `gr1, 5'b0, 6'b100000};//add 33 | in_instruction[95:64]={6'b0, `gr1, `gr1, `gr1, 5'b100, 6'b000000};//sll 34 | 35 | $display(" pc : gr1 : gr2 : gr3 : gr4 : $ra : data memory[0:31] :instruction"); 36 | #period $display("%h:%h:%h:%h:%h:%h: %h :%h",a.PC,a.gr[1],a.gr[2],a.gr[3],a.gr[4],a.gr[31],{a.d_memory[0],a.d_memory[1],a.d_memory[2],a.d_memory[3]},a.InstrD); 37 | #period $display("%h:%h:%h:%h:%h:%h: %h :%h",a.PC,a.gr[1],a.gr[2],a.gr[3],a.gr[4],a.gr[31],{a.d_memory[0],a.d_memory[1],a.d_memory[2],a.d_memory[3]},a.InstrD); 38 | #period $display("%h:%h:%h:%h:%h:%h: %h :%h",a.PC,a.gr[1],a.gr[2],a.gr[3],a.gr[4],a.gr[31],{a.d_memory[0],a.d_memory[1],a.d_memory[2],a.d_memory[3]},a.InstrD); 39 | #period $display("%h:%h:%h:%h:%h:%h: %h :%h",a.PC,a.gr[1],a.gr[2],a.gr[3],a.gr[4],a.gr[31],{a.d_memory[0],a.d_memory[1],a.d_memory[2],a.d_memory[3]},a.InstrD); 40 | #period $display("%h:%h:%h:%h:%h:%h: %h :%h",a.PC,a.gr[1],a.gr[2],a.gr[3],a.gr[4],a.gr[31],{a.d_memory[0],a.d_memory[1],a.d_memory[2],a.d_memory[3]},a.InstrD); 41 | #period $display("%h:%h:%h:%h:%h:%h: %h :%h",a.PC,a.gr[1],a.gr[2],a.gr[3],a.gr[4],a.gr[31],{a.d_memory[0],a.d_memory[1],a.d_memory[2],a.d_memory[3]},a.InstrD); 42 | #period $display("%h:%h:%h:%h:%h:%h: %h :%h",a.PC,a.gr[1],a.gr[2],a.gr[3],a.gr[4],a.gr[31],{a.d_memory[0],a.d_memory[1],a.d_memory[2],a.d_memory[3]},a.InstrD); 43 | #period $display("%h:%h:%h:%h:%h:%h: %h :%h",a.PC,a.gr[1],a.gr[2],a.gr[3],a.gr[4],a.gr[31],{a.d_memory[0],a.d_memory[1],a.d_memory[2],a.d_memory[3]},a.InstrD); 44 | #period $display("%h:%h:%h:%h:%h:%h: %h :%h",a.PC,a.gr[1],a.gr[2],a.gr[3],a.gr[4],a.gr[31],{a.d_memory[0],a.d_memory[1],a.d_memory[2],a.d_memory[3]},a.InstrD); 45 | #period $display("%h:%h:%h:%h:%h:%h: %h :%h",a.PC,a.gr[1],a.gr[2],a.gr[3],a.gr[4],a.gr[31],{a.d_memory[0],a.d_memory[1],a.d_memory[2],a.d_memory[3]},a.InstrD); 46 | #period $display("%h:%h:%h:%h:%h:%h: %h :%h",a.PC,a.gr[1],a.gr[2],a.gr[3],a.gr[4],a.gr[31],{a.d_memory[0],a.d_memory[1],a.d_memory[2],a.d_memory[3]},a.InstrD); 47 | #period $display("%h:%h:%h:%h:%h:%h: %h :%h",a.PC,a.gr[1],a.gr[2],a.gr[3],a.gr[4],a.gr[31],{a.d_memory[0],a.d_memory[1],a.d_memory[2],a.d_memory[3]},a.InstrD); 48 | #period $display("%h:%h:%h:%h:%h:%h: %h :%h",a.PC,a.gr[1],a.gr[2],a.gr[3],a.gr[4],a.gr[31],{a.d_memory[0],a.d_memory[1],a.d_memory[2],a.d_memory[3]},a.InstrD); 49 | #period $display("%h:%h:%h:%h:%h:%h: %h :%h",a.PC,a.gr[1],a.gr[2],a.gr[3],a.gr[4],a.gr[31],{a.d_memory[0],a.d_memory[1],a.d_memory[2],a.d_memory[3]},a.InstrD); 50 | #period $display("%h:%h:%h:%h:%h:%h: %h :%h",a.PC,a.gr[1],a.gr[2],a.gr[3],a.gr[4],a.gr[31],{a.d_memory[0],a.d_memory[1],a.d_memory[2],a.d_memory[3]},a.InstrD); 51 | #period $display("%h:%h:%h:%h:%h:%h: %h :%h",a.PC,a.gr[1],a.gr[2],a.gr[3],a.gr[4],a.gr[31],{a.d_memory[0],a.d_memory[1],a.d_memory[2],a.d_memory[3]},a.InstrD); 52 | #period $finish; 53 | end 54 | 55 | parameter period=10; 56 | always #5clock=~clock; 57 | 58 | endmodule -------------------------------------------------------------------------------- /assignment4/test_CPU_data_hazard.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns/1ps 2 | 3 | // general register 4 | `define gr0 5'b00000 5 | `define gr1 5'b00001 6 | `define gr2 5'b00010 7 | `define gr3 5'b00011 8 | `define gr4 5'b00100 9 | `define gr5 5'b00101 10 | `define gr6 5'b00110 11 | `define gr7 5'b00111 12 | 13 | module CPU_test; 14 | 15 | //Inputs 16 | reg clock; 17 | reg start; 18 | reg [319:0] in_instruction; 19 | 20 | CPU a(.clock(clock),.start(start),.i_datain(in_instruction)); 21 | 22 | initial begin 23 | clock=0; 24 | start=0; 25 | 26 | in_instruction[319:288]={6'b001000, `gr0, `gr1, 16'd1};//addi 27 | in_instruction[287:256]={6'b001000, `gr1, `gr2, 16'd1};//addi 28 | in_instruction[255:224]={6'b001000, `gr1, `gr3, 16'b10};//addi 29 | in_instruction[223:192]={6'b001000, `gr1, `gr4, 16'b11}; //addi 30 | in_instruction[191:160]={6'b0, `gr4, `gr1, `gr1, 5'b0, 6'b100010};//sub 31 | in_instruction[159:128]={6'b0, `gr3, `gr1, `gr2, 5'b0, 6'b100000};//add 32 | in_instruction[127:96]={6'b0, `gr1, `gr1, `gr1, 5'b0, 6'b100000};//add 33 | 34 | $display(" pc : gr1 : gr2 : gr3 : gr4 : $ra : data memory[0:31] :instruction"); 35 | #period $display("%h:%h:%h:%h:%h:%h: %h :%h",a.PC,a.gr[1],a.gr[2],a.gr[3],a.gr[4],a.gr[31],{a.d_memory[0],a.d_memory[1],a.d_memory[2],a.d_memory[3]},a.InstrD); 36 | #period $display("%h:%h:%h:%h:%h:%h: %h :%h",a.PC,a.gr[1],a.gr[2],a.gr[3],a.gr[4],a.gr[31],{a.d_memory[0],a.d_memory[1],a.d_memory[2],a.d_memory[3]},a.InstrD); 37 | #period $display("%h:%h:%h:%h:%h:%h: %h :%h",a.PC,a.gr[1],a.gr[2],a.gr[3],a.gr[4],a.gr[31],{a.d_memory[0],a.d_memory[1],a.d_memory[2],a.d_memory[3]},a.InstrD); 38 | #period $display("%h:%h:%h:%h:%h:%h: %h :%h",a.PC,a.gr[1],a.gr[2],a.gr[3],a.gr[4],a.gr[31],{a.d_memory[0],a.d_memory[1],a.d_memory[2],a.d_memory[3]},a.InstrD); 39 | #period $display("%h:%h:%h:%h:%h:%h: %h :%h",a.PC,a.gr[1],a.gr[2],a.gr[3],a.gr[4],a.gr[31],{a.d_memory[0],a.d_memory[1],a.d_memory[2],a.d_memory[3]},a.InstrD); 40 | #period $display("%h:%h:%h:%h:%h:%h: %h :%h",a.PC,a.gr[1],a.gr[2],a.gr[3],a.gr[4],a.gr[31],{a.d_memory[0],a.d_memory[1],a.d_memory[2],a.d_memory[3]},a.InstrD); 41 | #period $display("%h:%h:%h:%h:%h:%h: %h :%h",a.PC,a.gr[1],a.gr[2],a.gr[3],a.gr[4],a.gr[31],{a.d_memory[0],a.d_memory[1],a.d_memory[2],a.d_memory[3]},a.InstrD); 42 | #period $display("%h:%h:%h:%h:%h:%h: %h :%h",a.PC,a.gr[1],a.gr[2],a.gr[3],a.gr[4],a.gr[31],{a.d_memory[0],a.d_memory[1],a.d_memory[2],a.d_memory[3]},a.InstrD); 43 | #period $display("%h:%h:%h:%h:%h:%h: %h :%h",a.PC,a.gr[1],a.gr[2],a.gr[3],a.gr[4],a.gr[31],{a.d_memory[0],a.d_memory[1],a.d_memory[2],a.d_memory[3]},a.InstrD); 44 | #period $display("%h:%h:%h:%h:%h:%h: %h :%h",a.PC,a.gr[1],a.gr[2],a.gr[3],a.gr[4],a.gr[31],{a.d_memory[0],a.d_memory[1],a.d_memory[2],a.d_memory[3]},a.InstrD); 45 | #period $display("%h:%h:%h:%h:%h:%h: %h :%h",a.PC,a.gr[1],a.gr[2],a.gr[3],a.gr[4],a.gr[31],{a.d_memory[0],a.d_memory[1],a.d_memory[2],a.d_memory[3]},a.InstrD); 46 | #period $display("%h:%h:%h:%h:%h:%h: %h :%h",a.PC,a.gr[1],a.gr[2],a.gr[3],a.gr[4],a.gr[31],{a.d_memory[0],a.d_memory[1],a.d_memory[2],a.d_memory[3]},a.InstrD); 47 | #period $display("%h:%h:%h:%h:%h:%h: %h :%h",a.PC,a.gr[1],a.gr[2],a.gr[3],a.gr[4],a.gr[31],{a.d_memory[0],a.d_memory[1],a.d_memory[2],a.d_memory[3]},a.InstrD); 48 | #period $display("%h:%h:%h:%h:%h:%h: %h :%h",a.PC,a.gr[1],a.gr[2],a.gr[3],a.gr[4],a.gr[31],{a.d_memory[0],a.d_memory[1],a.d_memory[2],a.d_memory[3]},a.InstrD); 49 | #period $display("%h:%h:%h:%h:%h:%h: %h :%h",a.PC,a.gr[1],a.gr[2],a.gr[3],a.gr[4],a.gr[31],{a.d_memory[0],a.d_memory[1],a.d_memory[2],a.d_memory[3]},a.InstrD); 50 | #period $display("%h:%h:%h:%h:%h:%h: %h :%h",a.PC,a.gr[1],a.gr[2],a.gr[3],a.gr[4],a.gr[31],{a.d_memory[0],a.d_memory[1],a.d_memory[2],a.d_memory[3]},a.InstrD); 51 | #period $finish; 52 | end 53 | 54 | parameter period=10; 55 | always #5clock=~clock; 56 | 57 | endmodule -------------------------------------------------------------------------------- /assignment4/test_CPU_lw_stall.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns/1ps 2 | 3 | // general register 4 | `define gr0 5'b00000 5 | `define gr1 5'b00001 6 | `define gr2 5'b00010 7 | `define gr3 5'b00011 8 | `define gr4 5'b00100 9 | `define gr5 5'b00101 10 | `define gr6 5'b00110 11 | `define gr7 5'b00111 12 | 13 | module CPU_test; 14 | 15 | //Inputs 16 | reg clock; 17 | reg start; 18 | reg [319:0] in_instruction; 19 | 20 | CPU a(.clock(clock),.start(start),.i_datain(in_instruction)); 21 | 22 | initial begin 23 | clock=0; 24 | start=0; 25 | 26 | in_instruction[319:288]={6'b001000, `gr0, `gr1, 16'd1}; //addi 27 | in_instruction[287:256]={6'b101011, `gr0, `gr1, 16'b0}; //sw 28 | in_instruction[255:224]={6'b001000, `gr1, `gr3, 16'b1}; //addi 29 | in_instruction[223:192]={6'b100011, `gr0, `gr2, 16'b0}; //lw 30 | in_instruction[191:160]={6'b001000, `gr2, `gr1, 16'b1}; //addi 31 | in_instruction[159:128]={6'b0, `gr1, `gr1, `gr1, 5'b100, 6'b000000}; //sll 32 | 33 | $display(" pc : gr1 : gr2 : gr3 : gr4 : $ra : data memory[0:31] :instruction"); 34 | #period $display("%h:%h:%h:%h:%h:%h: %h :%h",a.PC,a.gr[1],a.gr[2],a.gr[3],a.gr[4],a.gr[31],{a.d_memory[0],a.d_memory[1],a.d_memory[2],a.d_memory[3]},a.InstrD); 35 | #period $display("%h:%h:%h:%h:%h:%h: %h :%h",a.PC,a.gr[1],a.gr[2],a.gr[3],a.gr[4],a.gr[31],{a.d_memory[0],a.d_memory[1],a.d_memory[2],a.d_memory[3]},a.InstrD); 36 | #period $display("%h:%h:%h:%h:%h:%h: %h :%h",a.PC,a.gr[1],a.gr[2],a.gr[3],a.gr[4],a.gr[31],{a.d_memory[0],a.d_memory[1],a.d_memory[2],a.d_memory[3]},a.InstrD); 37 | #period $display("%h:%h:%h:%h:%h:%h: %h :%h",a.PC,a.gr[1],a.gr[2],a.gr[3],a.gr[4],a.gr[31],{a.d_memory[0],a.d_memory[1],a.d_memory[2],a.d_memory[3]},a.InstrD); 38 | #period $display("%h:%h:%h:%h:%h:%h: %h :%h",a.PC,a.gr[1],a.gr[2],a.gr[3],a.gr[4],a.gr[31],{a.d_memory[0],a.d_memory[1],a.d_memory[2],a.d_memory[3]},a.InstrD); 39 | #period $display("%h:%h:%h:%h:%h:%h: %h :%h",a.PC,a.gr[1],a.gr[2],a.gr[3],a.gr[4],a.gr[31],{a.d_memory[0],a.d_memory[1],a.d_memory[2],a.d_memory[3]},a.InstrD); 40 | #period $display("%h:%h:%h:%h:%h:%h: %h :%h",a.PC,a.gr[1],a.gr[2],a.gr[3],a.gr[4],a.gr[31],{a.d_memory[0],a.d_memory[1],a.d_memory[2],a.d_memory[3]},a.InstrD); 41 | #period $display("%h:%h:%h:%h:%h:%h: %h :%h",a.PC,a.gr[1],a.gr[2],a.gr[3],a.gr[4],a.gr[31],{a.d_memory[0],a.d_memory[1],a.d_memory[2],a.d_memory[3]},a.InstrD); 42 | #period $display("%h:%h:%h:%h:%h:%h: %h :%h",a.PC,a.gr[1],a.gr[2],a.gr[3],a.gr[4],a.gr[31],{a.d_memory[0],a.d_memory[1],a.d_memory[2],a.d_memory[3]},a.InstrD); 43 | #period $display("%h:%h:%h:%h:%h:%h: %h :%h",a.PC,a.gr[1],a.gr[2],a.gr[3],a.gr[4],a.gr[31],{a.d_memory[0],a.d_memory[1],a.d_memory[2],a.d_memory[3]},a.InstrD); 44 | #period $display("%h:%h:%h:%h:%h:%h: %h :%h",a.PC,a.gr[1],a.gr[2],a.gr[3],a.gr[4],a.gr[31],{a.d_memory[0],a.d_memory[1],a.d_memory[2],a.d_memory[3]},a.InstrD); 45 | #period $display("%h:%h:%h:%h:%h:%h: %h :%h",a.PC,a.gr[1],a.gr[2],a.gr[3],a.gr[4],a.gr[31],{a.d_memory[0],a.d_memory[1],a.d_memory[2],a.d_memory[3]},a.InstrD); 46 | #period $display("%h:%h:%h:%h:%h:%h: %h :%h",a.PC,a.gr[1],a.gr[2],a.gr[3],a.gr[4],a.gr[31],{a.d_memory[0],a.d_memory[1],a.d_memory[2],a.d_memory[3]},a.InstrD); 47 | #period $display("%h:%h:%h:%h:%h:%h: %h :%h",a.PC,a.gr[1],a.gr[2],a.gr[3],a.gr[4],a.gr[31],{a.d_memory[0],a.d_memory[1],a.d_memory[2],a.d_memory[3]},a.InstrD); 48 | #period $display("%h:%h:%h:%h:%h:%h: %h :%h",a.PC,a.gr[1],a.gr[2],a.gr[3],a.gr[4],a.gr[31],{a.d_memory[0],a.d_memory[1],a.d_memory[2],a.d_memory[3]},a.InstrD); 49 | #period $display("%h:%h:%h:%h:%h:%h: %h :%h",a.PC,a.gr[1],a.gr[2],a.gr[3],a.gr[4],a.gr[31],{a.d_memory[0],a.d_memory[1],a.d_memory[2],a.d_memory[3]},a.InstrD); 50 | #period $finish; 51 | end 52 | 53 | parameter period=10; 54 | always #5clock=~clock; 55 | 56 | endmodule --------------------------------------------------------------------------------