├── .gitignore ├── README.md ├── p0 ├── CRC.circ ├── fsm.circ ├── ftoi.circ ├── grf.circ └── navigation.circ ├── p1 ├── BlockChecker.v ├── BlockChecker2.v ├── alu.v ├── ext.v ├── gray.v ├── splitter.v └── string.v ├── p2 ├── convolution.asm ├── factorial.asm ├── matrix.asm ├── maze.asm ├── palindrome.asm └── permutation.asm ├── p3 ├── cpu.circ ├── grf.circ ├── mips1.asm ├── mips2.asm ├── mips3.asm ├── mips4.asm ├── mips5.asm ├── mips6.asm ├── test1 ├── test2 ├── test3 ├── test4 ├── test5 └── test6 ├── p4 ├── ALU.v ├── CMP.v ├── CU.v ├── DASM.v ├── DM.v ├── EXT.v ├── GRF.v ├── IFU.v ├── NPC.v ├── const.v ├── mips.v ├── tb.v ├── test.asm ├── test1.asm └── testproducer-P5fullversion.cpp ├── p5 ├── D_CMP.v ├── D_EXT.v ├── D_GRF.v ├── D_NPC.v ├── D_REG.v ├── E_ALU.v ├── E_HILO.v ├── E_REG.v ├── F_IFU.v ├── M_DM.v ├── M_REG.v ├── W_REG.v ├── _CU.v ├── _DASM.v ├── _FU.v ├── _SU.v ├── _tb.v ├── const.v └── mips.v ├── p6 ├── D_CMP.v ├── D_EXT.v ├── D_GRF.v ├── D_NPC.v ├── D_REG.v ├── E_ALU.v ├── E_HILO.v ├── E_REG.v ├── F_IFU.v ├── M_DM.v ├── M_REG.v ├── W_REG.v ├── _CU.v ├── _DASM.v ├── _FU.v ├── _SU.v ├── _tb.v ├── const.v └── mips.v ├── p7 ├── D_CMP.v ├── D_EXT.v ├── D_GRF.v ├── D_NPC.v ├── D_REG.v ├── E_ALU.v ├── E_HILO.v ├── E_REG.v ├── F_IFU.v ├── M_DM.v ├── M_REG.v ├── W_REG.v ├── _CP0.v ├── _CU.v ├── _DASM.v ├── _SU.v ├── const.v ├── cpu.v ├── mips.v ├── mips_tb.v ├── tb.v └── timer.v └── partial-pre ├── 4bit_sort.circ ├── cpu_checker.v ├── fib.circ ├── fib_int32.circ ├── mod5.circ └── swap.circ /.gitignore: -------------------------------------------------------------------------------- 1 | out/ 2 | test-rand-logs/ 3 | venv/ 4 | *.vcd 5 | *.zip 6 | code.asm 7 | code.txt 8 | code_handler.asm 9 | code_handler.txt 10 | test.asm 11 | 12 | # Xilinx ISE 13 | _xmsgs/ 14 | iseconfig/ 15 | isim/ 16 | *_isim_beh.exe 17 | *_isim_beh.wdb 18 | *_summary.html 19 | *.gise 20 | *.prj 21 | *.xise 22 | *.xmsgs 23 | fuse.log 24 | fuseRelaunch.cmd 25 | isim.cmd 26 | isim.log 27 | xilinxsim.ini -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # BUAA CO 2 | 3 | ## P0:Logisim 4 | 5 | 课下测试:搭建 CRC 校验码计算电路,ALU,正则表达式匹配 6 | 7 | 课上测试:Logisim 完成部件及 FSM 设计 8 | 9 | ## P1:Verilog-HDL 10 | 11 | 课下测试:实现 splitter, ALU,格雷码计数器,合法表达式识别,走迷宫 12 | 13 | 课上测试:Verilog-HDL 完成部件及 FSM 设计 14 | 15 | ## P2:MIPS 16 | 17 | 课下测试:矩阵乘法、排序、回文串判断 18 | 19 | 课上测试:选择题+编程题 20 | 21 | ## P3:Logisim 单周期 CPU 22 | 23 | 课下测试:完成支持 7 条指令的单周期 CPU 设计 24 | 25 | 课上测试:新增指令 26 | 27 | ## P4:Verilog 单周期 CPU 28 | 29 | 课下测试:完成支持 7 条指令的单周期 CPU 设计 30 | 31 | 课上测试:新增指令 32 | 33 | ## P5:Verilog 流水线 CPU(1) 34 | 35 | 课下测试:完成支持 10 指令流水线 CPU 设计 36 | 37 | 课上测试:流水线工程化方法 38 | 39 | ## P6:Verilog 流水线 CPU(2) 40 | 41 | 课下测试:完成支持 50 指令流水线 CPU 设计 42 | 43 | 课上测试:流水线工程化方法 44 | 45 | ## P7:异常中断支持 46 | 47 | 课下测试:完成微型 MIPS 系统设计,开发简单 I/O,验证中断 48 | 49 | 课上测试:现场测试 50 | 51 | ## P8:FPGA 52 | 53 | 2020 级取消 P8(悲) 54 | 55 | # 后记 56 | 57 | 具体教程可参考我的博客:[计算机组成实验](https://roife.github.io/archive/?tag=BUAA+-+计算机组成实验%40C) 58 | 59 | 这里有我写的一个 Verilog 反编译器:[DASM](https://github.com/roife/dasm) 60 | 61 | 其中我先做了 P6 再做 P5,避免了做 P6 时大规模的重构。 62 | -------------------------------------------------------------------------------- /p1/BlockChecker.v: -------------------------------------------------------------------------------- 1 | `define sEmpty 4'b0000 2 | `define sBegin1 4'b0001 3 | `define sBegin2 4'b0010 4 | `define sBegin3 4'b0011 5 | `define sBegin4 4'b0100 6 | `define sBegin5 4'b0101 7 | `define sEnd1 4'b0110 8 | `define sEnd2 4'b0111 9 | `define sEnd3 4'b1000 10 | `define sInvalid 4'b1001 11 | `define sChar 4'b1010 12 | 13 | module BlockChecker ( 14 | input clk, 15 | input reset, 16 | input [7:0] in, 17 | output result 18 | ); 19 | 20 | reg [31:0] cur1; 21 | reg [4:0] cur; 22 | 23 | function [7:0] tolower; 24 | input [7:0] c; 25 | begin 26 | tolower = (c >= "A" && c <= "Z") ? (c - "A" + "a") : c; 27 | end 28 | endfunction 29 | 30 | initial begin 31 | cur1 <= 0; 32 | cur <= `sEmpty; 33 | end 34 | 35 | always @(posedge clk, posedge reset) begin 36 | if (reset) begin 37 | cur1 <= 0; 38 | cur <= `sEmpty; 39 | end else begin 40 | case (cur) 41 | `sEmpty: begin 42 | if (tolower(in) == "b") cur <= `sBegin1; 43 | else if (tolower(in) == "e") cur <= `sEnd1; 44 | else if (tolower(in) >= "a" && tolower(in) <= "z") cur <= `sChar; 45 | else cur <= `sEmpty; 46 | end 47 | 48 | `sBegin1: begin 49 | if (tolower(in) == "e") cur <= `sBegin2; 50 | else if (tolower(in) >= "a" && tolower(in) <= "z") cur <= `sChar; 51 | else cur <= `sEmpty; 52 | end 53 | 54 | `sBegin2: begin 55 | if (tolower(in) == "g") cur <= `sBegin3; 56 | else if (tolower(in) >= "a" && tolower(in) <= "z") cur <= `sChar; 57 | else cur <= `sEmpty; 58 | end 59 | 60 | `sBegin3: begin 61 | if (tolower(in) == "i") cur <= `sBegin4; 62 | else if (tolower(in) >= "a" && tolower(in) <= "z") cur <= `sChar; 63 | else cur <= `sEmpty; 64 | end 65 | 66 | `sBegin4: begin 67 | if (tolower(in) == "n") begin 68 | cur <= `sBegin5; 69 | cur1 <= cur1 + 1; 70 | end 71 | else if (tolower(in) >= "a" && tolower(in) <= "z") cur <= `sChar; 72 | else cur <= `sEmpty; 73 | end 74 | 75 | `sBegin5: begin 76 | if (tolower(in) >= "a" && tolower(in) <= "z") begin 77 | cur <= `sChar; 78 | cur1 <= cur1 - 1; 79 | end else begin 80 | cur <= `sEmpty; 81 | end 82 | end 83 | 84 | `sEnd1: begin 85 | if (tolower(in) == "n") cur <= `sEnd2; 86 | else if (tolower(in) >= "a" && tolower(in) <= "z") cur <= `sChar; 87 | else cur <= `sEmpty; 88 | end 89 | 90 | `sEnd2: begin 91 | if (tolower(in) == "d") begin 92 | cur1 <= cur1 - 1; 93 | cur <= `sEnd3; 94 | end 95 | else if (tolower(in) >= "a" && tolower(in) <= "z") cur <= `sChar; 96 | else cur <= `sEmpty; 97 | end 98 | 99 | `sEnd3: begin 100 | if (tolower(in) >= "a" && tolower(in) <= "z") begin 101 | cur <= `sChar; 102 | cur1 <= cur1 + 1; 103 | end else 104 | if (cur1[31]) cur <= `sInvalid; 105 | else cur <= `sEmpty; 106 | end 107 | 108 | `sInvalid: begin 109 | 110 | end 111 | 112 | `sChar: begin 113 | if (tolower(in) >= "a" && tolower(in) <= "z") cur <= `sChar; 114 | else cur <= `sEmpty; 115 | end 116 | endcase 117 | end 118 | end 119 | 120 | assign result = (cur1 == 0); 121 | 122 | endmodule 123 | -------------------------------------------------------------------------------- /p1/BlockChecker2.v: -------------------------------------------------------------------------------- 1 | `timescale 1 ns / 100 ps 2 | module BlockChecker ( 3 | input clk, 4 | input reset, 5 | input [7:0] in, 6 | output result 7 | ); 8 | 9 | reg [31:0] cnt; 10 | reg valid; 11 | reg [255:0] bfr; 12 | 13 | initial begin 14 | cnt <= 0; 15 | valid <= 1'b1; 16 | bfr = ""; 17 | end 18 | 19 | always @(posedge clk, posedge reset) begin 20 | if (reset) begin 21 | cnt <= 0; 22 | valid <= 1'b1; 23 | bfr = ""; 24 | end else begin 25 | bfr = (bfr << 8) | in | 8'h20; 26 | 27 | if (valid) begin 28 | if (bfr[47:0] == " begin") cnt <= cnt + 1; 29 | else if (bfr[55:8] == " begin" && bfr[7:0] != " ") cnt <= cnt - 1; 30 | else if (bfr[31:0] == " end") cnt <= cnt - 1; 31 | else if (bfr[39:8] == " end" && bfr[7:0] != " ") cnt <= cnt + 1; 32 | else if (bfr[39:8] == " end" && bfr[7:0] == " " && cnt[31]) valid <= 1'b0; 33 | end 34 | end 35 | end 36 | 37 | assign result = ((cnt == 0) && valid); 38 | 39 | endmodule 40 | -------------------------------------------------------------------------------- /p1/alu.v: -------------------------------------------------------------------------------- 1 | module alu( 2 | input [31:0] A, 3 | input [31:0] B, 4 | input [2:0] ALUOp, 5 | output reg [31:0] C 6 | ); 7 | always @(*) begin 8 | case (ALUOp) 9 | 3'b000: C <= A + B; 10 | 3'b001: C <= A - B; 11 | 3'b010: C <= A & B; 12 | 3'b011: C <= A | B; 13 | 3'b100: C <= A >> B; 14 | 3'b101: C <= $signed(A) >>> B; 15 | default: C <= 0; 16 | endcase 17 | end 18 | endmodule 19 | -------------------------------------------------------------------------------- /p1/ext.v: -------------------------------------------------------------------------------- 1 | module ext( 2 | input [15:0] imm, 3 | input [1:0] EOp, 4 | output reg [31:0] ext 5 | ); 6 | always @(*) begin 7 | case (EOp) 8 | 2'b00: ext <= $signed({imm, 16'b0}) >>> 16; 9 | 2'b01: ext <= {16'b0, imm}; 10 | 2'b10: ext <= {imm, 16'b0}; 11 | 2'b11: ext <= $signed({imm, 16'b0}) >>> 14; 12 | endcase 13 | end 14 | endmodule 15 | -------------------------------------------------------------------------------- /p1/gray.v: -------------------------------------------------------------------------------- 1 | `define SIZE 3 2 | module gray ( 3 | input Clk, 4 | input Reset, 5 | input En, 6 | output reg [`SIZE - 1:0] Output, 7 | output reg Overflow 8 | ); 9 | 10 | reg [`SIZE - 1:0] cnt; 11 | reg flag; 12 | 13 | parameter ZERO = {`SIZE{1'b0}}; 14 | parameter ONE = {{(`SIZE - 1){1'b0}}, 1'b1}; 15 | parameter INF = {`SIZE{1'b1}}; 16 | 17 | initial begin 18 | Output <= ZERO; 19 | cnt <= ZERO; 20 | Overflow <= 1'b0; 21 | flag <= 1'b0; 22 | end 23 | 24 | always @(posedge Clk) begin 25 | if (Reset) begin 26 | Output <= ZERO; 27 | cnt <= ZERO; 28 | Overflow <= 1'b0; 29 | flag <= 1'b0; 30 | end else if (En) begin 31 | if (cnt == INF) begin 32 | Output <= ZERO; 33 | cnt <= ZERO; 34 | Overflow <= 1'b1; 35 | flag <= 1'b0; 36 | end else begin 37 | if (flag) begin 38 | flag <= ~flag; 39 | Output <= Output ^ (((Output & ((~Output) + 1))) << 1); 40 | cnt <= cnt + 1; 41 | end else begin 42 | flag <= ~flag; 43 | Output <= Output ^ ONE; 44 | cnt <= cnt + 1; 45 | end 46 | end 47 | end 48 | end 49 | 50 | endmodule 51 | -------------------------------------------------------------------------------- /p1/splitter.v: -------------------------------------------------------------------------------- 1 | module splitter( 2 | input [31:0] A, 3 | output [7:0] O1, 4 | output [7:0] O2, 5 | output [7:0] O3, 6 | output [7:0] O4 7 | ); 8 | assign O1 = A[31:24]; 9 | assign O2 = A[23:16]; 10 | assign O3 = A[15:8]; 11 | assign O4 = A[7:0]; 12 | endmodule 13 | -------------------------------------------------------------------------------- /p1/string.v: -------------------------------------------------------------------------------- 1 | `define sEmpty 2'b00 2 | `define sNum 2'b01 3 | `define sOp 2'b10 4 | `define sInvalid 2'b11 5 | 6 | module string ( 7 | input clk, 8 | input clr, 9 | input [7:0] in, 10 | output out 11 | ); 12 | 13 | reg [1:0] cur; 14 | 15 | initial begin 16 | cur <= `sEmpty; 17 | end 18 | 19 | always @(posedge clk, posedge clr) begin 20 | if (clr) begin 21 | cur <= `sEmpty; 22 | end else begin 23 | case (cur) 24 | `sEmpty: begin 25 | if (in >= "0" && in <= "9") cur <= `sNum; 26 | else cur <= `sInvalid; 27 | end 28 | 29 | `sNum: begin 30 | if (in >= "0" && in <= "9") cur <= `sInvalid; 31 | else if (in == "+" || in == "*") cur <= `sOp; 32 | else cur <= `sInvalid; 33 | end 34 | 35 | `sOp: begin 36 | if (in >= "0" && in <= "9") cur <= `sNum; 37 | else cur <= `sInvalid; 38 | end 39 | 40 | default: cur <= `sInvalid; 41 | endcase 42 | end 43 | end 44 | 45 | assign out = (cur == `sNum); 46 | 47 | endmodule 48 | -------------------------------------------------------------------------------- /p2/convolution.asm: -------------------------------------------------------------------------------- 1 | .data 2 | mat1: .space 400 3 | mat2: .space 400 4 | str_space: .asciiz " " 5 | str_enter: .asciiz "\n" 6 | 7 | .macro INDEX(%ans, %i, %j, %rank) 8 | multu %i, %rank 9 | mflo %ans 10 | add %ans, %ans, %j 11 | sll %ans, %ans, 2 12 | .end_macro 13 | 14 | .macro RI(%n) 15 | li $v0, 5 16 | syscall 17 | move %n, $v0 18 | .end_macro 19 | 20 | .macro PI(%n) 21 | li $v0, 1 22 | move $a0, %n 23 | syscall 24 | .end_macro 25 | 26 | .text 27 | RI($s0) # m1 28 | RI($s1) # n1 29 | RI($s2) # m2 30 | RI($s3) # n2 31 | li $t0, 0 32 | FOR_i1: 33 | beq $t0, $s0, END_FOR_i1 34 | li $t1, 0 35 | FOR_j1: 36 | beq $t1, $s1, END_FOR_j1 37 | li $t2, 10 38 | INDEX($t3, $t0, $t1, $t2) 39 | RI($t4) 40 | sw $t4, mat1($t3) 41 | addi $t1, $t1, 1 42 | j FOR_j1 43 | END_FOR_j1: 44 | addi $t0, $t0, 1 45 | j FOR_i1 46 | END_FOR_i1: 47 | 48 | li $t0, 0 49 | FOR_i2: 50 | beq $t0, $s2, END_FOR_i2 51 | li $t1, 0 52 | FOR_j2: 53 | beq $t1, $s3, END_FOR_j2 54 | li $t2, 10 55 | INDEX($t3, $t0, $t1, $t2) 56 | RI($t4) 57 | sw $t4, mat2($t3) 58 | addi $t1, $t1, 1 59 | j FOR_j2 60 | END_FOR_j2: 61 | addi $t0, $t0, 1 62 | j FOR_i2 63 | END_FOR_i2: 64 | 65 | li $t0, 0 # i 66 | sub $s0, $s0, $s2 67 | addi $s0, $s0, 1 68 | sub $s1, $s1, $s3 69 | addi $s1, $s1, 1 70 | FOR_i3: 71 | beq $t0, $s0, END_FOR_i3 72 | li $t1, 0 # j 73 | FOR_j3: 74 | beq $t1, $s1, END_FOR_j3 75 | li $t3, 0 # sum 76 | 77 | li $t4, 0 # k 78 | FOR_k3: 79 | beq $t4, $s2, END_FOR_k3 80 | li $t5, 0 # l 81 | 82 | FOR_l3: 83 | beq $t5, $s3, END_FOR_l3 84 | add $t6, $t0, $t4 85 | add $t7, $t1, $t5 86 | li $t8, 10 87 | INDEX($t9, $t6, $t7, $t8) 88 | lw $s4, mat1($t9) 89 | 90 | li $t8, 10 91 | INDEX($t9, $t4, $t5, $t8) 92 | lw $s5, mat2($t9) 93 | 94 | mult $s4, $s5 95 | mflo $s6 96 | 97 | add $t3, $t3, $s6 98 | 99 | addi $t5, $t5, 1 100 | j FOR_l3 101 | END_FOR_l3: 102 | 103 | addi $t4, $t4, 1 104 | j FOR_k3 105 | END_FOR_k3: 106 | 107 | PI($t3) 108 | 109 | la $a0, str_space 110 | li $v0, 4 111 | syscall 112 | 113 | addi $t1, $t1, 1 114 | j FOR_j3 115 | END_FOR_j3: 116 | 117 | la $a0, str_enter 118 | li $v0, 4 119 | syscall 120 | addi $t0, $t0, 1 121 | j FOR_i3 122 | END_FOR_i3: 123 | 124 | li $v0, 10 125 | syscall 126 | -------------------------------------------------------------------------------- /p2/factorial.asm: -------------------------------------------------------------------------------- 1 | .macro RI(%n) 2 | li $v0, 5 3 | syscall 4 | move %n, $v0 5 | .end_macro 6 | 7 | .macro PI(%n) 8 | li $v0, 1 9 | move $a0, %n 10 | syscall 11 | .end_macro 12 | 13 | .data 14 | a: .space 800 15 | 16 | .text 17 | RI($s0) # read(n) 18 | li $t1, 1 19 | sw $t1, a($zero) # a[0] = 0 20 | li $s1, 1 # end = 0 21 | li $t0, 2 # i = 2 22 | FORi1: 23 | bgt $t0, $s0, END_FOR_i1 24 | 25 | lw $t1, a($zero) # $t2 = a[0] 26 | mult $t1, $t0 27 | mflo $t1 28 | sw $t1, a($zero) 29 | 30 | li $t2, 1 # j = 1 31 | FORj1: 32 | bgt $t2, $s1, END_FORj1 33 | 34 | sll $t5, $t2, 2 35 | lw $t1, a($t5) 36 | mult $t1, $t0 37 | mflo $t1 # t1 = a[j]*i 38 | 39 | subi $t2, $t2, 1 40 | sll $t5, $t2, 2 41 | lw $t3, a($t5) # t3 = a[j-1] 42 | div $t3, $t3, 1000000 43 | 44 | mflo $t3 # a[j-1]/1000000 45 | add $t1, $t1, $t3 46 | mfhi $t3 # a[j-1]%1000000 47 | sll $t5, $t2, 2 48 | sw $t3, a($t5) # a[j-1] 49 | addi $t2, $t2, 1 50 | sll $t5, $t2, 2 51 | sw $t1, a($t5) # a[j] 52 | 53 | addi $t2, $t2, 1 54 | j FORj1 55 | END_FORj1: 56 | 57 | sll $t5, $s1, 2 58 | lw $t1, a($t5) # a[end+1] 59 | beqz $t1, ELSE_END 60 | addi $s1, $s1, 1 61 | ELSE_END: 62 | 63 | addi $t0, $t0, 1 64 | j FORi1 65 | END_FOR_i1: 66 | 67 | subi $s1, $s1, 1 68 | move $s2, $s1 69 | WHILE: 70 | sll $t5, $s1, 2 71 | lw $t0, a($t5) 72 | li $t1, 0 73 | beq $s1, $s2, END_P 74 | bgt $t0, 100000, END_P 75 | PI($t1) 76 | bgt $t0, 10000, END_P 77 | PI($t1) 78 | bgt $t0, 1000, END_P 79 | PI($t1) 80 | bgt $t0, 100, END_P 81 | PI($t1) 82 | bgt $t0, 10, END_P 83 | PI($t1) 84 | END_P: 85 | 86 | PI($t0) 87 | beq $s1, 0, END_WHILE 88 | subi $s1, $s1, 1 89 | j WHILE 90 | END_WHILE: 91 | 92 | li $v0, 10 93 | syscall -------------------------------------------------------------------------------- /p2/matrix.asm: -------------------------------------------------------------------------------- 1 | .data 2 | mat1: .space 256 3 | mat2: .space 256 4 | str_space: .asciiz " " 5 | str_enter: .asciiz "\n" 6 | 7 | .macro INDEX(%ans, %i, %j, %rank) 8 | multu %i, %rank 9 | mflo %ans 10 | add %ans, %ans, %j 11 | sll %ans, %ans, 2 12 | .end_macro 13 | 14 | .macro RI(%n) 15 | li $v0, 5 16 | syscall 17 | move %n, $v0 18 | .end_macro 19 | 20 | .macro PI(%n) 21 | li $v0, 1 22 | move $a0, %n 23 | syscall 24 | .end_macro 25 | 26 | .text 27 | RI($s0) 28 | li $t0, 0 29 | FOR_i1: 30 | beq $t0, $s0, END_FOR_i1 31 | li $t1, 0 32 | FOR_j1: 33 | beq $t1, $s0, END_FOR_j1 34 | li $t2, 8 35 | INDEX($t3, $t0, $t1, $t2) 36 | RI($t4) 37 | sw $t4, mat1($t3) 38 | addi $t1, $t1, 1 39 | j FOR_j1 40 | END_FOR_j1: 41 | addi $t0, $t0, 1 42 | j FOR_i1 43 | END_FOR_i1: 44 | 45 | li $t0, 0 46 | FOR_i2: 47 | beq $t0, $s0, END_FOR_i2 48 | li $t1, 0 49 | FOR_j2: 50 | beq $t1, $s0, END_FOR_j2 51 | li $t2, 8 52 | INDEX($t3, $t0, $t1, $t2) 53 | RI($t4) 54 | sw $t4, mat2($t3) 55 | addi $t1, $t1, 1 56 | j FOR_j2 57 | END_FOR_j2: 58 | addi $t0, $t0, 1 59 | j FOR_i2 60 | END_FOR_i2: 61 | 62 | li $t0, 0 63 | FOR_i3: 64 | beq $t0, $s0, END_FOR_i3 65 | li $t1, 0 66 | FOR_j3: 67 | beq $t1, $s0, END_FOR_j3 68 | li $t2, 8 69 | INDEX($t3, $t0, $t1, $t2) 70 | li $t4, 0 71 | li $t5, 0 72 | FOR_k3: 73 | beq $t4, $s0, END_FOR_k3 74 | INDEX($t6, $t0, $t4, $t2) 75 | lw $t7, mat1($t6) 76 | INDEX($t6, $t4, $t1, $t2) 77 | lw $t8, mat2($t6) 78 | 79 | mult $t7, $t8 80 | mflo $t7 81 | add $t5, $t5, $t7 82 | addi $t4, $t4, 1 83 | j FOR_k3 84 | END_FOR_k3: 85 | PI($t5) 86 | 87 | la $a0, str_space 88 | li $v0, 4 89 | syscall 90 | 91 | addi $t1, $t1, 1 92 | j FOR_j3 93 | END_FOR_j3: 94 | 95 | la $a0, str_enter 96 | li $v0, 4 97 | syscall 98 | addi $t0, $t0, 1 99 | j FOR_i3 100 | END_FOR_i3: 101 | -------------------------------------------------------------------------------- /p2/maze.asm: -------------------------------------------------------------------------------- 1 | .macro RI(%n) 2 | li $v0, 5 3 | syscall 4 | move %n, $v0 5 | .end_macro 6 | 7 | .macro PI(%n) 8 | li $v0, 1 9 | move $a0, %n 10 | syscall 11 | .end_macro 12 | 13 | .macro INDEX(%ans, %i, %j) 14 | sll %ans, %i, 3 15 | add %ans, %ans, %j 16 | sll %ans, %ans, 2 17 | .end_macro 18 | 19 | .macro LOAD_LOCAL(%n) 20 | addi $sp, $sp, 4 21 | lw %n, 0($sp) 22 | .end_macro 23 | 24 | .macro SAVE_LOCAL(%n) 25 | sw %n, 0($sp) 26 | subi $sp, $sp, 4 27 | .end_macro 28 | 29 | .data 30 | a: .space 200 31 | 32 | .text 33 | RI($s0) # n 34 | RI($s1) # m 35 | li $t0, 0 # i 36 | FORi1: 37 | beq $t0, $s0, END_FORi1 38 | li $t1, 0 # j 39 | FORj1: 40 | beq $t1, $s1, END_FORj1 41 | INDEX($t2, $t0, $t1) 42 | RI($t3) 43 | sw $t3, a($t2) 44 | addi $t1, $t1, 1 45 | j FORj1 46 | END_FORj1: 47 | addi $t0, $t0, 1 48 | j FORi1 49 | END_FORi1: 50 | 51 | RI($s2) # start_i 52 | RI($s3) # start_j 53 | RI($s4) # end_i 54 | RI($s5) # end_j 55 | subi $s2, $s2, 1 56 | subi $s3, $s3, 1 57 | subi $s4, $s4, 1 58 | subi $s5, $s5, 1 59 | 60 | li $s6, 0 # ans 61 | move $a0, $s2 # a 62 | move $a1, $s3 # b 63 | INDEX($t0, $s2, $s3) 64 | li $t1, 2 65 | sw $t1, a($t0) 66 | jal DFS 67 | 68 | PI($s6) 69 | 70 | li $v0, 10 71 | syscall 72 | DFS: 73 | bne $a0, $s4, ELSE1 74 | bne $a1, $s5, ELSE1 75 | li $t0, 0 76 | addi $s6, $s6, 1 77 | jr $ra 78 | ELSE1: 79 | INDEX($t0, $a0, $a1) 80 | li $t1, 2 81 | sw $t1, a($t0) 82 | # left 83 | beqz $a1, ELSE_LEFT2 84 | subi $a1, $a1, 1 85 | INDEX($t0, $a0, $a1) 86 | lw $t1, a($t0) 87 | bne $t1, 0, ELSE_LEFT1 88 | 89 | SAVE_LOCAL($a0) 90 | SAVE_LOCAL($a1) 91 | SAVE_LOCAL($ra) 92 | 93 | jal DFS 94 | 95 | LOAD_LOCAL($ra) 96 | LOAD_LOCAL($a1) 97 | LOAD_LOCAL($a0) 98 | 99 | ELSE_LEFT1: 100 | addi $a1, $a1, 1 101 | ELSE_LEFT2: 102 | 103 | # right 104 | addi $a1, $a1, 1 105 | beq $a1, $s1, ELSE_RIGHT1 106 | INDEX($t0, $a0, $a1) 107 | lw $t1, a($t0) 108 | bne $t1, 0, ELSE_RIGHT1 109 | 110 | SAVE_LOCAL($a0) 111 | SAVE_LOCAL($a1) 112 | SAVE_LOCAL($ra) 113 | 114 | jal DFS 115 | 116 | LOAD_LOCAL($ra) 117 | LOAD_LOCAL($a1) 118 | LOAD_LOCAL($a0) 119 | 120 | ELSE_RIGHT1: 121 | subi $a1, $a1, 1 122 | 123 | # up 124 | beqz $a0, ELSE_UP2 125 | subi $a0, $a0, 1 126 | INDEX($t0, $a0, $a1) 127 | lw $t1, a($t0) 128 | bne $t1, 0, ELSE_UP1 129 | 130 | SAVE_LOCAL($a0) 131 | SAVE_LOCAL($a1) 132 | SAVE_LOCAL($ra) 133 | 134 | jal DFS 135 | 136 | LOAD_LOCAL($ra) 137 | LOAD_LOCAL($a1) 138 | LOAD_LOCAL($a0) 139 | 140 | ELSE_UP1: 141 | addi $a0, $a0, 1 142 | ELSE_UP2: 143 | 144 | # down 145 | addi $a0, $a0, 1 146 | beq $a0, $s0, ELSE_DOWN1 147 | INDEX($t0, $a0, $a1) 148 | lw $t1, a($t0) 149 | bne $t1, 0, ELSE_DOWN1 150 | 151 | SAVE_LOCAL($a0) 152 | SAVE_LOCAL($a1) 153 | SAVE_LOCAL($ra) 154 | 155 | jal DFS 156 | 157 | LOAD_LOCAL($ra) 158 | LOAD_LOCAL($a1) 159 | LOAD_LOCAL($a0) 160 | 161 | ELSE_DOWN1: 162 | subi $a0, $a0, 1 163 | 164 | INDEX($t0, $a0, $a1) 165 | li $t1, 0 166 | sw $t1, a($t0) 167 | jr $ra 168 | END_DFS: 169 | -------------------------------------------------------------------------------- /p2/palindrome.asm: -------------------------------------------------------------------------------- 1 | .macro RI(%n) 2 | li $v0, 5 3 | syscall 4 | move %n, $v0 5 | .end_macro 6 | 7 | .macro RC(%c) 8 | li $v0, 12 9 | syscall 10 | move %c, $v0 11 | .end_macro 12 | 13 | .macro PI(%n) 14 | move $a0, %n 15 | li $v0, 1 16 | syscall 17 | .end_macro 18 | 19 | .data 20 | str: .byte 20 21 | 22 | .text 23 | RI($s0) 24 | li $t0, 0 25 | 26 | FOR_i1: 27 | beq $t0, $s0, END_FOR_i1 28 | RC($t1) 29 | sb $t1, str($t0) 30 | addi $t0, $t0, 1 31 | j FOR_i1 32 | END_FOR_i1: 33 | 34 | li $t0, 0 35 | subi $t1, $s0, 1 36 | 37 | WHILE: 38 | bge $t0, $t1, END_WHILE_OK 39 | lb $t2, str($t0) 40 | lb $t3, str($t1) 41 | bne $t2, $t3, END_WHILE 42 | addi $t0, $t0, 1 43 | subi $t1, $t1, 1 44 | j WHILE 45 | END_WHILE: 46 | li $t0, 0 47 | PI($t0) 48 | li $v0, 10 49 | syscall 50 | 51 | END_WHILE_OK: 52 | li $t0, 1 53 | PI($t0) 54 | li $v0, 10 55 | syscall -------------------------------------------------------------------------------- /p2/permutation.asm: -------------------------------------------------------------------------------- 1 | .macro RI(%n) 2 | li $v0, 5 3 | syscall 4 | move %n, $v0 5 | .end_macro 6 | 7 | .macro SAVE_LOCAL(%var) 8 | sw %var 0($sp) 9 | subi $sp, $sp, 4 10 | .end_macro 11 | 12 | .macro LOAD_LOCAL(%var) 13 | addi $sp, $sp, 4 14 | lw %var 0($sp) 15 | .end_macro 16 | 17 | .macro PI(%n) 18 | li $v0, 1 19 | move $a0, %n 20 | syscall 21 | .end_macro 22 | 23 | .macro PSPACE 24 | la $a0, str_space 25 | li $v0, 4 26 | syscall 27 | .end_macro 28 | 29 | .macro PENTER 30 | la $a0, str_enter 31 | li $v0, 4 32 | syscall 33 | .end_macro 34 | 35 | 36 | .data 37 | arr: .space 24 38 | sym: .space 24 39 | str_space: .asciiz " " 40 | str_enter: .asciiz "\n" 41 | 42 | .text 43 | RI($s0) 44 | li $a0, 0 45 | jal FullArray 46 | li $v0, 10 47 | syscall 48 | 49 | FullArray: 50 | IF1: 51 | bne $a0, $s0, ELSE1 52 | li $t0, 0 53 | FOR_i1: 54 | beq $t0, $s0, END_FOR_i1 55 | sll $t1, $t0, 2 56 | lw $t2, arr($t1) 57 | PI($t2) 58 | PSPACE 59 | addi $t0, $t0, 1 60 | j FOR_i1 61 | END_FOR_i1: 62 | PENTER 63 | jr $ra 64 | ELSE1: 65 | li $t0, 0 66 | FOR_i2: 67 | beq $t0, $s0, END_FOR_i2 68 | sll $t1, $t0, 2 69 | lw $t2, sym($t1) 70 | bnez $t2, ELSE2 71 | sll $t3, $a0, 2 72 | addi $t4, $t0, 1 73 | sw $t4, arr($t3) 74 | li $t2, 1 75 | sw $t2, sym($t1) 76 | 77 | SAVE_LOCAL($a0) 78 | SAVE_LOCAL($t2) 79 | SAVE_LOCAL($t0) 80 | SAVE_LOCAL($t1) 81 | SAVE_LOCAL($ra) 82 | 83 | addi $a0, $a0, 1 84 | jal FullArray 85 | 86 | LOAD_LOCAL($ra) 87 | LOAD_LOCAL($t1) 88 | LOAD_LOCAL($t0) 89 | LOAD_LOCAL($a2) 90 | LOAD_LOCAL($a0) 91 | 92 | li $t2, 0 93 | sw $t2, sym($t1) 94 | ELSE2: 95 | addi $t0, $t0, 1 96 | j FOR_i2 97 | END_FOR_i2: 98 | jr $ra 99 | END_FullArray: -------------------------------------------------------------------------------- /p3/mips1.asm: -------------------------------------------------------------------------------- 1 | .data 2 | arr:.space 40 3 | .text 4 | addi $t0, $t0, -5 5 | ori $s0,10 6 | loop: 7 | beq $t0,$s0,loop_out 8 | subu $t1,$t1,$t1 9 | subu $t4,$t4,$t4 10 | lj: 11 | beq $t1,$s0,ljout 12 | lw $t3,arr($t4) 13 | addu $t4,$t4,4 14 | addu $t3,$t3,$t1 15 | sw $t3,arr($t4) 16 | addu $t1,$t1,1 17 | j lj 18 | ljout: 19 | addu $t0,$t0,1 20 | j loop 21 | loop_out: 22 | -------------------------------------------------------------------------------- /p3/mips2.asm: -------------------------------------------------------------------------------- 1 | .text 2 | FOR: 3 | beq $a0, 10, END_FOR 4 | addi $a0, 1 5 | j FOR 6 | END_FOR: -------------------------------------------------------------------------------- /p3/mips3.asm: -------------------------------------------------------------------------------- 1 | .data 2 | a:.space 40 3 | .text 4 | jal F 5 | ori $a0, $zero, 0 6 | 7 | F: 8 | beq $a0, 10, END_F 9 | addi $a0, $a0, 1 10 | sw $ra, a($t0) 11 | addi $t0, $t0, 4 12 | jal F 13 | addi $t0, $t0, -4 14 | lw $ra, a($t0) 15 | END_F: 16 | jr $ra -------------------------------------------------------------------------------- /p3/mips4.asm: -------------------------------------------------------------------------------- 1 | .text 2 | ori $t0, $zero, 0 3 | ori $t1, $zero, 0xffff 4 | sh $t1, 0($t0) 5 | ori $t1, $zero, 9 6 | sh $t1, 2($t0) 7 | lw $t2, 0($t0) 8 | lh $t2, 0($t0) 9 | lhu $t3, 2($t0) 10 | -------------------------------------------------------------------------------- /p3/mips5.asm: -------------------------------------------------------------------------------- 1 | .text 2 | ori $t1, 10 3 | LABEL: 4 | beq $t0, $t1, END 5 | addi $t0, $t0, 1 6 | j LABEL 7 | END: 8 | jal TEST 9 | 10 | TEST: 11 | lui $t1, 0xffff 12 | jr $ra 13 | 14 | #ori $t0, $zero, 0 15 | #ori $t1, $zero, 0xffff 16 | #sh $t1, 0($t0) 17 | #ori $t1, $zero, 9 18 | #sh $t1, 2($t0) 19 | #lw $t2, 0($t0) 20 | #lh $t2, 0($t0) 21 | #lhu $t3, 2($t0) 22 | 23 | #lui $t0, 0xffff 24 | #addi $t0, $t0, 0xffff 25 | #addi $t0, $t0, 0xffff 26 | #addi $t0, $t0, 0xffff 27 | #lui $t0, 0 28 | #ori $t0, $t0 0xffff 29 | 30 | #lui $t0, 0xffff 31 | #ori $t0, $zero, 0xf 32 | #ori $t1, $zero, 0xf 33 | #subu $t0, $t0, $t1 34 | #addu $t0, $t0, $t1 35 | #addu $t0, $t0, $t1 36 | #subu $t0, $t0, $t1 37 | #subu $t0, $t0, $t1 38 | #or $t0, $t0, $t1 39 | #subu $t0, $t0, $t1 40 | #sll $t0, $t0, 2 41 | #lui $t0, 0 42 | #and $t0, $zero, $zero 43 | #slt $t0, $t0, $t1 44 | #slt $t1, $t0, $t1 -------------------------------------------------------------------------------- /p3/mips6.asm: -------------------------------------------------------------------------------- 1 | .text 2 | ori $t0, $zero, 1 3 | sll $t0, $t0, 2 -------------------------------------------------------------------------------- /p3/test1: -------------------------------------------------------------------------------- 1 | 35080000 2 | 3610000a 3 | 11100011 4 | 01294823 5 | 018c6023 6 | 1130000a 7 | 8d8b0000 8 | 3c010000 9 | 34210004 10 | 01816021 11 | 01695821 12 | ad8b0000 13 | 3c010000 14 | 34210001 15 | 01214821 16 | 08000c05 17 | 3c010000 18 | 34210001 19 | 01014021 20 | 08000c02 21 | 114affff 22 | -------------------------------------------------------------------------------- /p3/test2: -------------------------------------------------------------------------------- 1 | v2.0 raw 2 | 34080000 3 | 34090001 4 | ad090000 5 | 34080004 6 | ad090000 7 | 34080002 8 | 340a0008 9 | 20010005 10 | 1028000f 11 | 2108ffff 12 | 2108ffff 13 | 214afffc 14 | 214afffc 15 | 8d4b0000 16 | 21080001 17 | 214a0004 18 | 8d4c0000 19 | 21080001 20 | 214a0004 21 | 016c4821 22 | ad490000 23 | 21080001 24 | 214a0004 25 | 08000007 26 | -------------------------------------------------------------------------------- /p3/test3: -------------------------------------------------------------------------------- 1 | v2.0 raw 2 | 0c000002 3 | 34040000 4 | 2001000a 5 | 10240006 6 | 20840001 7 | ad1f0000 8 | 21080004 9 | 0c000002 10 | 2108fffc 11 | 8d1f0000 12 | 03e00008 13 | -------------------------------------------------------------------------------- /p3/test4: -------------------------------------------------------------------------------- 1 | v2.0 raw 2 | 34080000 3 | 3409ffff 4 | a5090000 5 | 34090009 6 | a5090002 7 | 8d0a0000 8 | 850a0000 9 | 950b0002 10 | -------------------------------------------------------------------------------- /p3/test5: -------------------------------------------------------------------------------- 1 | v2.0 raw 2 | 3529000a 3 | 11090002 4 | 21080001 5 | 08000c01 6 | 0c000c05 7 | 3c09ffff 8 | 03e00008 9 | -------------------------------------------------------------------------------- /p3/test6: -------------------------------------------------------------------------------- 1 | v2.0 raw 2 | 34080001 3 | 00084080 4 | -------------------------------------------------------------------------------- /p4/ALU.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | `include "const.v" 3 | 4 | module ALU ( 5 | input [3:0] ALUControl, 6 | input [31:0] A, 7 | input [31:0] B, 8 | input [5:0] shamt, 9 | output [31:0] ALUout 10 | ); 11 | 12 | assign ALUout = (ALUControl == `ALU_add) ? A + B : 13 | (ALUControl == `ALU_sub) ? A - B : 14 | (ALUControl == `ALU_and) ? A & B : 15 | (ALUControl == `ALU_or) ? A | B : 16 | (ALUControl == `ALU_sll) ? B << shamt : 17 | (ALUControl == `ALU_slt) ? A < B : 18 | (ALUControl == `ALU_lui) ? B << 16 : 19 | (ALUControl == `ALU_sllv) ? B << A[4:0] : 20 | 32'b0; 21 | 22 | endmodule -------------------------------------------------------------------------------- /p4/CMP.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | `include "const.v" 3 | 4 | module CMP ( 5 | input [31:0] RD1, 6 | input [31:0] RD2, 7 | input [31:0] type, 8 | output jump 9 | ); 10 | 11 | assign jump = (type == `I_beq && RD1 == RD2); 12 | 13 | endmodule -------------------------------------------------------------------------------- /p4/CU.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | `include "const.v" 3 | 4 | module CU ( 5 | input [5:0] opcode, 6 | input [5:0] func, 7 | output [31:0] type, 8 | output [2:0] DMType, 9 | output [2:0] Br, 10 | output [2:0] A3Sel, 11 | output [2:0] WDSel, 12 | output RFWr, 13 | output EXTOp, 14 | output ALUBSelImm, 15 | output DMWr, 16 | output [3:0] ALUControl 17 | ); 18 | 19 | wire _rtype, _load, _store, _branch; 20 | wire beq, blez, j, jal, lb, lbu, lh, lhu, lui, lw, ori, sw, sh, sb, slti, addu, And, jalr, jr, Or, sll, sllv, slt, subu; 21 | 22 | assign _rtype = (opcode == `OP_rtype); 23 | assign _load = lw || lh || lhu || lbu || lb; 24 | assign _store = sw || sh || sb; 25 | assign _branch = beq || blez; 26 | 27 | assign type = (opcode == `OP_beq) ? `I_beq : 28 | (opcode == `OP_blez) ? `I_blez : 29 | (opcode == `OP_j ) ? `I_j : 30 | (opcode == `OP_jal) ? `I_jal : 31 | (opcode == `OP_lb) ? `I_lb : 32 | (opcode == `OP_lbu) ? `I_lbu : 33 | (opcode == `OP_lh) ? `I_lh : 34 | (opcode == `OP_lhu) ? `I_lhu : 35 | (opcode == `OP_lui) ? `I_lui : 36 | (opcode == `OP_lw) ? `I_lw : 37 | (opcode == `OP_ori) ? `I_ori : 38 | (opcode == `OP_sw) ? `I_sw : 39 | (opcode == `OP_sh) ? `I_sh : 40 | (opcode == `OP_sb) ? `I_sb : 41 | (opcode == `OP_slti) ? `I_slti : 42 | (func == `FUNC_addu) ? `I_addu : 43 | (func == `FUNC_and) ? `I_and : 44 | (func == `FUNC_jalr) ? `I_jalr : 45 | (func == `FUNC_jr) ? `I_jr : 46 | (func == `FUNC_or) ? `I_or : 47 | (func == `FUNC_sll) ? `I_sll : 48 | (func == `FUNC_sllv) ? `I_sllv : 49 | (func == `FUNC_slt) ? `I_slt : 50 | (func == `FUNC_subu) ? `I_subu : 51 | 0; 52 | 53 | assign beq = (type == `I_beq); 54 | assign blez = (type == `I_blez); 55 | assign j = (type == `I_j); 56 | assign jal = (type == `I_jal); 57 | assign lb = (type == `I_lb); 58 | assign lbu = (type == `I_lbu); 59 | assign lh = (type == `I_lh); 60 | assign lhu = (type == `I_lhu); 61 | assign lui = (type == `I_lui); 62 | assign lw = (type == `I_lw); 63 | assign ori = (type == `I_ori); 64 | assign sw = (type == `I_sw); 65 | assign sh = (type == `I_sh); 66 | assign sb = (type == `I_sb); 67 | assign slti = (type == `I_slti); 68 | assign addu = (type == `I_addu); 69 | assign And = (type == `I_and); 70 | assign jalr = (type == `I_jalr); 71 | assign jr = (type == `I_jr); 72 | assign Or = (type == `I_or); 73 | assign sllv = (type == `I_sllv); 74 | assign sll = (type == `I_sll); 75 | assign slt = (type == `I_slt); 76 | assign subu = (type == `I_subu); 77 | 78 | assign ALUControl = (subu) ? `ALU_sub : 79 | (And) ? `ALU_and : 80 | (Or || ori) ? `ALU_or : 81 | (sll) ? `ALU_sll : 82 | (slt || slti) ? `ALU_slt : 83 | (lui) ? `ALU_lui : 84 | (sllv) ? `ALU_sllv : 85 | `ALU_add; 86 | assign Br = (_branch) ? `BR_beq : 87 | (j || jal || jalr) ? `BR_j : 88 | (jr) ? `BR_jr : 89 | `BR_pc4; 90 | assign A3Sel = (_rtype) ? `A3Sel_rd : 91 | (jr || jalr) ? `A3Sel_ra : 92 | `A3Sel_rt; 93 | assign WDSel = (_load) ? `WDSel_DMout : 94 | (jal || jalr) ? `WDSel_PC4 : 95 | `WDSel_ALUout; 96 | // 不写 reg 的指令 97 | assign RFWr = !_store && !_branch && !j && !jr; 98 | assign EXTOp = _store; 99 | // 不用 imm 的指令 100 | assign ALUBSelImm = !_rtype && !_branch && !j && !jal && !jalr; 101 | assign DMWr = _store; 102 | assign DMType = (lw || sw) ? `DM_w : 103 | (lh || sh) ? `DM_h : 104 | (lhu) ? `DM_hu : 105 | (lb || sb) ? `DM_b : 106 | (lbu) ? `DM_bu : 107 | `DM_w; 108 | 109 | endmodule -------------------------------------------------------------------------------- /p4/DASM.v: -------------------------------------------------------------------------------- 1 | `define lb 6'b100000 2 | `define lbu 6'b100100 3 | `define lh 6'b100001 4 | `define lhu 6'b100101 5 | `define lw 6'b100011 6 | `define sb 6'b101000 7 | `define sh 6'b101001 8 | `define sw 6'b101011 9 | `define addop 6'b000000 10 | `define addfu 6'b100000 11 | `define addi 6'b001000 12 | `define addiu 6'b001001 13 | `define adduop 6'b000000 14 | `define addufu 6'b100001 15 | `define andop 6'b000000 16 | `define andfu 6'b100100 17 | `define andi 6'b001100 18 | `define beq 6'b000100 19 | `define bgezop 6'b000001 20 | `define bgezrt 5'b00001 21 | `define bgtz 6'b000111 22 | `define blez 6'b000110 23 | `define bltzop 6'b000001 24 | `define bltzrt 5'b00000 25 | `define bne 6'b000101 26 | `define divop 6'b000000 27 | `define divfu 6'b011010 28 | `define divuop 6'b000000 29 | `define divufu 6'b011011 30 | `define j 6'b000010 31 | `define jal 6'b000011 32 | `define jalrop 6'b000000 33 | `define jalrfu 6'b001001 34 | `define jrop 6'b000000 35 | `define jrfu 6'b001000 36 | `define Lui 6'b001111 37 | `define mfhiop 6'b000000 38 | `define mfhifu 6'b010000 39 | `define mfloop 6'b000000 40 | `define mflofu 6'b010010 41 | `define mthiop 6'b000000 42 | `define mthifu 6'b010001 43 | `define mtloop 6'b000000 44 | `define mtlofu 6'b010011 45 | `define multop 6'b000000 46 | `define multfu 6'b011000 47 | `define multuop 6'b000000 48 | `define multufu 6'b011001 49 | `define norop 6'b000000 50 | `define norfu 6'b100111 51 | `define orop 6'b000000 52 | `define orfu 6'b100101 53 | `define ori 6'b001101 54 | `define sllop 6'b000000 55 | `define sllfu 6'b000000 56 | `define sllvop 6'b000000 57 | `define sllvfu 6'b000100 58 | `define sltop 6'b000000 59 | `define sltfu 6'b101010 60 | `define slti 6'b001010 61 | `define sltiu 6'b001011 62 | `define sltuop 6'b000000 63 | `define sltufu 6'b101011 64 | `define sraop 6'b000000 65 | `define srafu 6'b000011 66 | `define sravop 6'b000000 67 | `define sravfu 6'b000111 68 | `define srlop 6'b000000 69 | `define srlfu 6'b000010 70 | `define srlvop 6'b000000 71 | `define srlvfu 6'b000110 72 | `define subop 6'b000000 73 | `define subfu 6'b100010 74 | `define subuop 6'b000000 75 | `define subufu 6'b100011 76 | `define sw 6'b101011 77 | `define xorop 6'b000000 78 | `define xorfu 6'b100110 79 | `define xori 6'b001110 80 | 81 | module DASM ( 82 | input [31:0] pc, 83 | input [31:0] instr, 84 | input reg_name, 85 | input imm_as_dec, 86 | output [32*8-1:0] asm 87 | ); 88 | 89 | wire [5:0]func=instr[5:0], op=instr[31:26]; 90 | wire [4:0]rs=instr[25:21], rt=instr[20:16], rd=instr[15:11], sha=instr[10:6]; 91 | wire [15:0] imm=instr[15:0]; 92 | wire [25:0] target=instr[25:0]; 93 | 94 | wire beq=(op==`beq); 95 | wire bgez=(op==`bgezop)&(rt==`bgezrt); 96 | wire bgtz=(op==`bgtz); 97 | wire blez=(op==`blez); 98 | wire bltz=(op==`bltzop)&(rt==`bltzrt); 99 | wire bne=(op==`bne); 100 | 101 | wire j=(op==`j); 102 | wire jal=(op==`jal); 103 | wire jalr=(op==`jalrop)&(func==`jalrfu); 104 | wire jr=(op==`jrop)&(func==`jrfu); 105 | 106 | wire lb=(op==`lb); 107 | wire lbu=(op==`lbu); 108 | wire lh=(op==`lh); 109 | wire lhu=(op==`lhu); 110 | wire lw=(op==`lw); 111 | wire sb=(op==`sb); 112 | wire sh=(op==`sh); 113 | wire sw=(op==`sw); 114 | 115 | wire lui=(op==`Lui); 116 | 117 | wire add=(op==`addop)&(func==`addfu); 118 | wire addi=(op==`addi); 119 | wire addiu=(op==`addiu); 120 | wire addu=(op==`adduop)&(func==`addufu); 121 | wire And=(op==`andop)&(func==`andfu); 122 | wire andi=(op==`andi); 123 | wire div=(op==`divop)&(func==`divfu); 124 | wire divu=(op==`divuop)&(func==`divufu); 125 | wire mfhi=(op==`mfhiop)&(func==`mfhifu); 126 | wire mflo=(op==`mfloop)&(func==`mflofu); 127 | wire mthi=(op==`mthiop)&(func==`mthifu); 128 | wire mtlo=(op==`mtloop)&(func==`mtlofu); 129 | wire mult=(op==`multop)&(func==`multfu); 130 | wire multu=(op==`multuop)&(func==`multufu); 131 | wire Nor=(op==`norop)&(func==`norfu); 132 | wire Or=(op==`orop)&(func==`orfu); 133 | wire ori=(op==`ori); 134 | wire sll=(op==6'b000000)&(func==6'b000000)&(|rd); 135 | wire sllv=(op==`sllvop)&(func==`sllvfu); 136 | wire slt=(op==`sltop)&(func==`sltfu); 137 | wire slti=(op==`slti); 138 | wire sltiu=(op==`sltiu); 139 | wire sltu=(op==`sltuop)&(func==`sltufu); 140 | wire sra=(op==`sraop)&(func==`srafu); 141 | wire srav=(op==`sravop)&(func==`sravfu); 142 | wire srl=(op==`srlop)&(func==`srlfu); 143 | wire srlv=(op==`srlvop)&(func==`srlvfu); 144 | wire sub=(op==`subop)&(func==`subfu); 145 | wire subu=(op==`subuop)&(func==`subufu); 146 | wire Xor=(op==`xorop)&(func==`xorfu); 147 | wire xori=(op==`xori); 148 | 149 | function [8*3-1:0] get_reg; 150 | input [4:0] num; 151 | begin 152 | case (num) 153 | 5'b00000: get_reg = reg_name ? "$00" : "$00"; 154 | 5'b00001: get_reg = reg_name ? "$at" : "$01"; 155 | 5'b00010: get_reg = reg_name ? "$v0" : "$02"; 156 | 5'b00011: get_reg = reg_name ? "$v1" : "$03"; 157 | 5'b00100: get_reg = reg_name ? "$a0" : "$04"; 158 | 5'b00101: get_reg = reg_name ? "$a1" : "$05"; 159 | 5'b00110: get_reg = reg_name ? "$a2" : "$06"; 160 | 5'b00111: get_reg = reg_name ? "$a3" : "$07"; 161 | 5'b01000: get_reg = reg_name ? "$t0" : "$08"; 162 | 5'b01001: get_reg = reg_name ? "$t1" : "$09"; 163 | 5'b01010: get_reg = reg_name ? "$t2" : "$10"; 164 | 5'b01011: get_reg = reg_name ? "$t3" : "$11"; 165 | 5'b01100: get_reg = reg_name ? "$t4" : "$12"; 166 | 5'b01101: get_reg = reg_name ? "$t5" : "$13"; 167 | 5'b01110: get_reg = reg_name ? "$t6" : "$14"; 168 | 5'b01111: get_reg = reg_name ? "$t7" : "$15"; 169 | 5'b10000: get_reg = reg_name ? "$s0" : "$16"; 170 | 5'b10001: get_reg = reg_name ? "$s1" : "$17"; 171 | 5'b10010: get_reg = reg_name ? "$s2" : "$18"; 172 | 5'b10011: get_reg = reg_name ? "$s3" : "$19"; 173 | 5'b10100: get_reg = reg_name ? "$s4" : "$20"; 174 | 5'b10101: get_reg = reg_name ? "$s5" : "$21"; 175 | 5'b10110: get_reg = reg_name ? "$s6" : "$22"; 176 | 5'b10111: get_reg = reg_name ? "$s7" : "$23"; 177 | 5'b11000: get_reg = reg_name ? "$t8" : "$24"; 178 | 5'b11001: get_reg = reg_name ? "$t9" : "$25"; 179 | 5'b11010: get_reg = reg_name ? "$s8" : "$26"; 180 | 5'b11011: get_reg = reg_name ? "$s9" : "$27"; 181 | 5'b11100: get_reg = reg_name ? "$gp" : "$28"; 182 | 5'b11101: get_reg = reg_name ? "$sp" : "$29"; 183 | 5'b11110: get_reg = reg_name ? "$fp" : "$30"; 184 | 5'b11111: get_reg = reg_name ? "$ra" : "$31"; 185 | endcase 186 | end 187 | endfunction 188 | 189 | function [7:0] get_hex; 190 | input [3:0] num; 191 | begin 192 | case (num) 193 | 4'b0000: get_hex = "0"; 194 | 4'b0001: get_hex = "1"; 195 | 4'b0010: get_hex = "2"; 196 | 4'b0011: get_hex = "3"; 197 | 4'b0100: get_hex = "4"; 198 | 4'b0101: get_hex = "5"; 199 | 4'b0110: get_hex = "6"; 200 | 4'b0111: get_hex = "7"; 201 | 4'b1000: get_hex = "8"; 202 | 4'b1001: get_hex = "9"; 203 | 4'b1010: get_hex = "A"; 204 | 4'b1011: get_hex = "B"; 205 | 4'b1100: get_hex = "C"; 206 | 4'b1101: get_hex = "D"; 207 | 4'b1110: get_hex = "E"; 208 | 4'b1111: get_hex = "F"; 209 | endcase 210 | end 211 | endfunction 212 | 213 | wire [7:0] sp = 8'b0010_0000; 214 | 215 | wire [4*8-1:0] srs = {sp, get_reg(rs)}, srd = {sp, get_reg(rd)}, srt = {sp, get_reg(rt)}; 216 | wire [4*8-1:0] soff = {get_hex(imm[15:12]), get_hex(imm[11:8]), get_hex(imm[7:4]), get_hex(imm[3:0])}; 217 | wire [5*8-1:0] simm = {sp, get_hex(imm[15:12]), get_hex(imm[11:8]), get_hex(imm[7:4]), get_hex(imm[3:0])}; 218 | wire [31:0] imm32_signed = imm[15] ? -{{16{imm[15]}}, imm} : {16'b0, imm}; 219 | wire [6*8-1:0] simm_dec = {sp, get_hex(imm/10000%10), get_hex(imm/1000%10), get_hex(imm/100%10), get_hex(imm/10%10), get_hex(imm%10)}; 220 | wire [7*8-1:0] simm_dec_signed = {sp, imm[15] ? "-" : " ", 221 | get_hex(imm32_signed/10000%10), get_hex(imm32_signed/1000%10), 222 | get_hex(imm32_signed/100%10), get_hex(imm32_signed/10%10), get_hex(imm32_signed%10)}; 223 | 224 | wire [4*8-1:0] ssha = {sp, get_hex(sha)}; 225 | // wire [10*8-1:0] saddr = {sp, get_, "_"} 226 | // wire _rdrsrt = {} 227 | 228 | wire [16*8-1:0] _rd_rs_rt = {srd, srs, srt}; 229 | wire [16*8-1:0] _rd_rt_rs = {srd, srt, srs}; 230 | wire [16*8-1:0] _rd_rt_sha = {srd, srt, ssha}; 231 | wire [16*8-1:0] _rt_rs_imm = {srt, srs, imm_as_dec ? simm_dec : simm}; 232 | wire [16*8-1:0] _rt_rs_imm_signed = {srt, srs, imm_as_dec ? simm_dec_signed : simm}; 233 | wire [31:0] branch_npc = pc + 4 + {{14{imm[15]}}, imm, 2'b0}; 234 | wire [24*8-1:0] _rs_rt_imm = {srs, srt, imm_as_dec ? simm_dec : simm, "[", 235 | get_hex(branch_npc[31:28]), get_hex(branch_npc[27:24]), 236 | get_hex(branch_npc[23:20]), get_hex(branch_npc[19:16]), 237 | get_hex(branch_npc[15:12]), get_hex(branch_npc[11:8]), 238 | get_hex(branch_npc[7:4]), get_hex(branch_npc[3:0]), "]"}; 239 | wire [20*8-1:0] _rs_imm = {srs, imm_as_dec ? simm_dec : simm, "[", 240 | get_hex(branch_npc[31:28]), get_hex(branch_npc[27:24]), 241 | get_hex(branch_npc[23:20]), get_hex(branch_npc[19:16]), 242 | get_hex(branch_npc[15:12]), get_hex(branch_npc[11:8]), 243 | get_hex(branch_npc[7:4]), get_hex(branch_npc[3:0]), "]"}; // branch 244 | wire [16*8-1:0] _rt_imm = {srt, imm_as_dec ? simm_dec : simm}; 245 | wire [16*8-1:0] _rs_rt = {srs, srt}; 246 | wire [16*8-1:0] _target = {" 0", get_hex(target[25:22]), get_hex(target[21:18]), 247 | get_hex(target[17:14]), get_hex(target[13:10]), 248 | get_hex(target[9:6]), get_hex(target[5:2]), get_hex({target[1:0], 2'b0})}; 249 | wire [16*8-1:0] _rd_rs = {srd, srs}; 250 | wire [16*8-1:0] _rs = {srs}; 251 | wire [16*8-1:0] _rd = {srd}; 252 | wire [16*8-1:0] _rt_off_base = {srt, " ", soff, "(", srs[3*8-1:0], ")"}; 253 | wire [16*8-1:0] _rt_rd = {srd}; 254 | 255 | assign asm = 256 | beq ? {"beq", _rs_rt_imm} : 257 | bgez ? {"bgez", _rs_imm} : 258 | bgtz ? {"bgtz", _rs_imm} : 259 | blez ? {"blez", _rs_imm} : 260 | bltz ? {"bltz", _rs_imm} : 261 | bne ? {"bne", _rs_rt_imm} : 262 | j ? {"j", _target} : 263 | jal ? {"jal", _target} : 264 | jalr ? {"jalr", _rd_rs} : 265 | jr ? {"jr", _rs} : 266 | lb ? {"lb", _rt_off_base} : 267 | lbu ? {"lbu", _rt_off_base} : 268 | lh ? {"lh", _rt_off_base} : 269 | lhu ? {"lhu", _rt_off_base} : 270 | lw ? {"lw", _rt_off_base} : 271 | sb ? {"sb", _rt_off_base} : 272 | sh ? {"sh", _rt_off_base} : 273 | sw ? {"sw", _rt_off_base} : 274 | lui ? {"lui", _rt_imm} : 275 | add ? {"add", _rd_rs_rt} : 276 | addi ? {"addi", _rt_rs_imm_signed} : 277 | addiu ? {"addiu", _rt_rs_imm_signed} : 278 | addu ? {"addu", _rd_rs_rt} : 279 | And ? {"And", _rd_rs_rt} : 280 | andi ? {"andi", _rt_rs_imm} : 281 | div ? {"div", _rs_rt} : 282 | divu ? {"divu", _rs_rt} : 283 | mfhi ? {"mfhi", _rd} : 284 | mflo ? {"mflo", _rd} : 285 | mthi ? {"mthi", _rd} : 286 | mtlo ? {"mtlo", _rd} : 287 | mult ? {"mult", _rs_rt} : 288 | multu ? {"multu", _rs_rt} : 289 | Nor ? {"Nor", _rd_rs_rt} : 290 | Or ? {"Or", _rd_rs_rt} : 291 | ori ? {"ori", _rt_rs_imm} : 292 | sll ? {"sll", _rd_rt_sha} : 293 | sllv ? {"sllv", _rd_rt_rs} : 294 | slt ? {"slt", _rd_rs_rt} : 295 | slti ? {"slti", _rt_rs_imm_signed} : 296 | sltiu ? {"sltiu", _rt_rs_imm_signed} : 297 | sltu ? {"sltu", _rd_rs_rt} : 298 | sra ? {"sra", _rd_rt_sha} : 299 | srav ? {"srav", _rd_rt_rs} : 300 | srl ? {"srl", _rd_rt_sha} : 301 | srlv ? {"srlv", _rd_rt_rs} : 302 | sub ? {"sub", _rd_rs_rt} : 303 | subu ? {"subu", _rd_rs_rt} : 304 | Xor ? {"Xor", _rd_rs_rt} : 305 | xori ? {"xori", _rt_rs_imm} : 306 | "No Instr"; 307 | 308 | endmodule -------------------------------------------------------------------------------- /p4/DM.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | `include "const.v" 3 | `define word memory[waddr] 4 | `define half `word[15 + 16 * addr[1] -:16] 5 | `define byte `word[7 + 8 * addr[1:0] -:8] 6 | 7 | module DM ( 8 | input [31:0] pc, // for debugging 9 | input clk, 10 | input reset, 11 | input DMWr, 12 | input [2:0] DMType, 13 | input [31:0] addr, 14 | input [31:0] WD, 15 | output [31:0] DMout 16 | ); 17 | 18 | function [31:0] sign_ext16; 19 | input [15:0] in; 20 | begin 21 | sign_ext16 = {{16{in[15]}}, in}; 22 | end 23 | endfunction 24 | 25 | function [31:0] unsign_ext16; 26 | input [15:0] in; 27 | begin 28 | unsign_ext16 = {{16{1'b0}}, in}; 29 | end 30 | endfunction 31 | 32 | function [31:0] sign_ext8; 33 | input [7:0] in; 34 | begin 35 | sign_ext8 = {{24{in[7]}}, in}; 36 | end 37 | endfunction 38 | 39 | function [31:0] unsign_ext8; 40 | input [7:0] in; 41 | begin 42 | unsign_ext8 = {{24{1'b0}}, in}; 43 | end 44 | endfunction 45 | 46 | reg [31:0] memory [1023:0]; 47 | integer i; 48 | 49 | wire [9:0] waddr; 50 | assign waddr = addr[11:2]; 51 | 52 | assign DMout = (DMType == `DM_w) ? `word : 53 | (DMType == `DM_h) ? sign_ext16(`half) : 54 | (DMType == `DM_hu) ? unsign_ext16(`half) : 55 | (DMType == `DM_b) ? sign_ext8(`byte) : 56 | (DMType == `DM_bu) ? unsign_ext8(`byte) : 57 | 32'b0; 58 | 59 | initial begin 60 | for (i=0; i<1023; i=i+1) memory[i] <= 0; 61 | end 62 | 63 | always @(posedge clk) begin 64 | if (reset) begin 65 | for (i=0; i<1023; i=i+1) memory[i] <= 0; 66 | end 67 | else if (DMWr) begin 68 | if (DMType == `DM_w) `word <= WD; 69 | else if (DMType == `DM_h) `half <= WD[15:0]; 70 | else if (DMType == `DM_b) `byte <= WD[7:0]; 71 | 72 | $display("@%h: *%h <= %h", pc, addr, WD); 73 | end 74 | end 75 | 76 | endmodule -------------------------------------------------------------------------------- /p4/EXT.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | `include "const.v" 3 | 4 | module EXT ( 5 | input [15:0] imm, 6 | input EXTOp, 7 | output [31:0] EXTout 8 | ); 9 | 10 | function [31:0] sign_ext16; 11 | input [15:0] in; 12 | begin 13 | sign_ext16 = {{16{in[15]}}, in}; 14 | end 15 | endfunction 16 | 17 | function [31:0] unsign_ext16; 18 | input [15:0] in; 19 | begin 20 | unsign_ext16 = {{16{1'b0}}, in}; 21 | end 22 | endfunction 23 | 24 | assign EXTout = EXTOp? unsign_ext16(imm) : sign_ext16(imm); 25 | 26 | endmodule -------------------------------------------------------------------------------- /p4/GRF.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | `include "const.v" 3 | 4 | module GRF ( 5 | input [31:0] pc, // for debugging 6 | input clk, 7 | input reset, 8 | input RFWr, 9 | input [4:0] A1, 10 | input [4:0] A2, 11 | input [4:0] A3, 12 | input [31:0] WD, 13 | output [31:0] RD1, 14 | output [31:0] RD2 15 | ); 16 | 17 | reg [31:0] grf [31:0]; 18 | 19 | assign RD1 = grf[A1]; 20 | assign RD2 = grf[A2]; 21 | 22 | integer i; 23 | 24 | initial begin 25 | for (i=0; i<32; i=i+1) grf[i] <= 0; 26 | end 27 | 28 | always @(posedge clk) begin 29 | if (reset) begin 30 | for (i=0; i<32; i=i+1) grf[i] <= 0; 31 | end 32 | else if (RFWr) begin 33 | if (A3) begin 34 | grf[A3] <= WD; 35 | $display("@%h: $%d <= %h", pc, A3, WD); 36 | end 37 | end 38 | end 39 | 40 | endmodule -------------------------------------------------------------------------------- /p4/IFU.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | `include "const.v" 3 | 4 | module IFU ( 5 | input clk, 6 | input reset, 7 | input [31:0] npc, 8 | output [31:0] instr, 9 | output reg [31:0] pc, 10 | output [4:0] rs, 11 | output [4:0] rt, 12 | output [4:0] rd, 13 | output [15:0] imm, 14 | output [25:0] imm26, 15 | output [5:0] func, 16 | output [5:0] opcode, 17 | output [5:0] shamt 18 | ); 19 | 20 | reg [31:0] im [0:1023]; 21 | 22 | assign instr = im[pc[11:2]]; 23 | 24 | assign opcode = instr[31:26]; 25 | assign func = instr[5:0]; 26 | assign imm26 = instr[25:0]; 27 | assign imm = instr[15:0]; 28 | assign rs = instr[25:21]; 29 | assign rt = instr[20:16]; 30 | assign rd = instr[15:11]; 31 | assign shamt = instr[10:6]; 32 | 33 | DASM Dasm( 34 | .pc(pc), 35 | .instr(instr), 36 | .imm_as_dec(1'b1), 37 | .reg_name(1'b0), 38 | .asm() 39 | ); 40 | 41 | initial begin 42 | pc <= 32'h0000_3000; 43 | $readmemh("code.txt", im); 44 | $display("%h", im[pc]); 45 | end 46 | 47 | always @(posedge clk) begin 48 | if (reset) pc <= 32'h0000_3000; 49 | else pc <= npc; 50 | 51 | end 52 | endmodule -------------------------------------------------------------------------------- /p4/NPC.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | `include "const.v" 3 | 4 | module NPC ( 5 | input [31:0] pc, 6 | input [25:0] imm26, 7 | input [31:0] RD2, 8 | input [2:0] Br, 9 | input jump, 10 | output [31:0] PC4, 11 | output [31:0] npc 12 | ); 13 | assign PC4 = pc + 4; 14 | assign npc = (Br == `BR_pc4) ? pc + 4 : 15 | (Br == `BR_j) ? {pc[31:28], imm26, 2'b0} : 16 | (Br == `BR_jr) ? RD2 : 17 | (Br == `BR_beq && jump) ? pc + 4 + {{14{imm26[15]}}, imm26[15:0], 2'b0} : 18 | pc + 4; 19 | endmodule -------------------------------------------------------------------------------- /p4/const.v: -------------------------------------------------------------------------------- 1 | `default_nettype none 2 | 3 | //// FUNCcode & nc 4 | `define OP_rtype 6'b000000 5 | `define OP_beq 6'b000100 6 | `define OP_blez 6'b000110 7 | `define OP_j 6'b000010 8 | `define OP_jal 6'b000011 9 | `define OP_lb 6'b100000 10 | `define OP_lbu 6'b100100 11 | `define OP_lh 6'b100001 12 | `define OP_lhu 6'b100101 13 | `define OP_lui 6'b001111 14 | `define OP_lw 6'b100011 15 | `define OP_ori 6'b001101 16 | `define OP_sw 6'b101011 17 | `define OP_sh 6'b101001 18 | `define OP_sb 6'b101000 19 | 20 | `define OP_slti 6'b001010 21 | 22 | `define FUNC_addu 6'b100001 23 | `define FUNC_and 6'b100100 24 | `define FUNC_jalr 6'b001001 25 | `define FUNC_jr 6'b001000 26 | `define FUNC_or 6'b100101 27 | `define FUNC_sll 6'b000000 28 | `define FUNC_sllv 6'b000100 29 | `define FUNC_slt 6'b101010 30 | `define FUNC_subu 6'b100011 31 | 32 | //// instructions 33 | `define I_beq 0 34 | `define I_blez 1 35 | `define I_j 2 36 | `define I_jal 3 37 | `define I_lb 4 38 | `define I_lbu 5 39 | `define I_lh 6 40 | `define I_lhu 7 41 | `define I_lui 8 42 | `define I_lw 9 43 | `define I_ori 10 44 | `define I_sw 11 45 | `define I_sh 12 46 | `define I_sb 13 47 | 48 | `define I_slti 14 49 | 50 | `define I_addu 15 51 | `define I_and 16 52 | `define I_jalr 17 53 | `define I_jr 18 54 | `define I_or 19 55 | `define I_sllv 20 56 | `define I_slt 21 57 | `define I_subu 22 58 | `define I_sll 23 59 | 60 | //// CU Signal 61 | 62 | // ALU 63 | `define ALU_add 5'b00000 64 | `define ALU_sub 5'b00001 65 | `define ALU_and 5'b00010 66 | `define ALU_or 5'b00011 67 | `define ALU_sll 5'b00100 68 | `define ALU_slt 5'b00101 69 | `define ALU_lui 5'b00110 70 | `define ALU_sllv 5'b00111 71 | 72 | // DM 73 | `define DM_w 3'b000 74 | `define DM_h 3'b001 75 | `define DM_hu 3'b010 76 | `define DM_b 3'b011 77 | `define DM_bu 3'b100 78 | 79 | // Branch 80 | `define BR_pc4 3'b000 81 | `define BR_j 3'b001 82 | `define BR_jr 3'b010 83 | `define BR_beq 3'b011 84 | 85 | // A3Sel 86 | `define A3Sel_rt 3'b000 87 | `define A3Sel_rd 3'b001 88 | `define A3Sel_ra 3'b010 89 | 90 | // WDSel 91 | `define WDSel_ALUout 3'b000 92 | `define WDSel_DMout 3'b001 93 | `define WDSel_PC4 3'b010 94 | -------------------------------------------------------------------------------- /p4/mips.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | `include "const.v" 3 | 4 | module mips ( 5 | input clk, 6 | input reset 7 | ); 8 | 9 | wire [31:0] pc, instr, npc; 10 | wire [31:0] PC4, RD1, RD2, EXTout, type, DMout, ALUout; 11 | wire [4:0] rs, rt, rd; 12 | wire [15:0] imm; 13 | wire [25:0] imm26; 14 | wire [5:0] func, opcode, shamt; 15 | 16 | wire [2:0] DMType, Br, A3Sel, WDSel; 17 | wire RFWr, EXTOp, ALUBSel, DMWr, ALUBSelImm; 18 | wire [3:0] ALUControl; 19 | wire jump; 20 | 21 | IFU Ifu(.clk(clk), 22 | .reset(reset), 23 | .npc(npc), 24 | .instr(instr), 25 | .pc(pc), 26 | .rs(rs), 27 | .rt(rt), 28 | .rd(rd), 29 | .imm(imm), 30 | .imm26(imm26), 31 | .func(func), 32 | .opcode(opcode), 33 | .shamt(shamt)); 34 | 35 | NPC Npc(.pc(pc), 36 | .imm26(imm26), 37 | .RD2(RD2), 38 | .Br(Br), 39 | .jump(jump), 40 | .PC4(PC4), 41 | .npc(npc)); 42 | 43 | EXT Ext(.imm(imm), 44 | .EXTOp(EXTOp), 45 | .EXTout(EXTout)); 46 | 47 | CMP Cmp(.RD1(RD1), 48 | .RD2(RD2), 49 | .type(type), 50 | .jump(jump)); 51 | 52 | GRF Grf(.pc(pc), 53 | .clk(clk), 54 | .reset(reset), 55 | .RFWr(RFWr), 56 | .A1(rs), 57 | .A2(rt), 58 | .A3((A3Sel == `A3Sel_rd) ? rd : 59 | (A3Sel == `A3Sel_rt) ? rt : 60 | (A3Sel == `A3Sel_ra) ? 5'd31 : 61 | 5'd0), 62 | .WD((WDSel == `WDSel_ALUout) ? ALUout : 63 | (WDSel == `WDSel_DMout) ? DMout : 64 | (WDSel == `WDSel_PC4) ? PC4 : 65 | 0), 66 | .RD1(RD1), 67 | .RD2(RD2)); 68 | 69 | ALU Alu(.ALUControl(ALUControl), 70 | .A(RD1), 71 | .B(ALUBSelImm ? EXTout : RD2), 72 | .shamt(shamt), 73 | .ALUout(ALUout)); 74 | 75 | DM Dm(.pc(pc), 76 | .clk(clk), 77 | .reset(reset), 78 | .DMWr(DMWr), 79 | .DMType(DMType), 80 | .addr(ALUout), 81 | .WD(RD2), 82 | .DMout(DMout)); 83 | 84 | CU Cu(.opcode(opcode), 85 | .func(func), 86 | .type(type), 87 | .DMType(DMType), 88 | .Br(Br), 89 | .A3Sel(A3Sel), 90 | .WDSel(WDSel), 91 | .RFWr(RFWr), 92 | .EXTOp(EXTOp), 93 | .ALUBSelImm(ALUBSelImm), 94 | .DMWr(DMWr), 95 | .ALUControl(ALUControl)); 96 | 97 | endmodule -------------------------------------------------------------------------------- /p4/tb.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | 3 | module tb; 4 | reg clk; 5 | reg reset; 6 | 7 | mips uut ( 8 | .clk(clk), 9 | .reset(reset) 10 | ); 11 | 12 | initial begin 13 | $dumpfile("tb.vcd"); 14 | $dumpvars(0,tb); 15 | 16 | clk = 0; 17 | reset = 1; 18 | 19 | #10; 20 | reset = 0; 21 | end 22 | 23 | always #5 clk=~clk; 24 | 25 | endmodule 26 | 27 | -------------------------------------------------------------------------------- /p4/test1.asm: -------------------------------------------------------------------------------- 1 | .data 2 | 3 | arr: .space 32 4 | 5 | .text 6 | 7 | ori $s0,10 8 | 9 | ori $s7,$s0,10 10 | 11 | loop: 12 | 13 | beq $t0,$s0,loopout 14 | 15 | lw $s1,arr($t1) 16 | 17 | addu $t1,$t1,4 18 | 19 | lw $s2,arr($t1) 20 | 21 | addu $s3,$s1,$s7 22 | 23 | addu $s2,$s2,$s3 24 | 25 | sw $s2,arr($t1) 26 | 27 | addu $t0,$t0,1 28 | 29 | jal loop 30 | 31 | loopout: 32 | 33 | beq $t0,$t0,loopout -------------------------------------------------------------------------------- /p4/testproducer-P5fullversion.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | typedef long long ll; 13 | using namespace std; 14 | unsigned int grf[32]; 15 | int reg[] = {0, 1, 2, 3, 31}; 16 | int dm[1024]; 17 | #define R reg[rand() % 5] 18 | #define I (rand() + rand()) 19 | #define B (rand() % 650) 20 | void addu(int rs, int rt, int rd) 21 | { 22 | printf("addu $%d,$%d,$%d\n", rd, rt, rs); 23 | if (rd) 24 | grf[rd] = grf[rs] + grf[rt]; 25 | } 26 | void subu(int rs, int rt, int rd) 27 | { 28 | printf("subu $%d,$%d,$%d\n", rd, rt, rs); 29 | if (rd) 30 | grf[rd] = grf[rs] - grf[rt]; 31 | } 32 | void ori(int rs, int rt, int imm) 33 | { 34 | printf("ori $%d,$%d,%d\n", rt, rs, imm); 35 | if (rt) 36 | grf[rt] = grf[rs] | imm; 37 | } 38 | void lui(int rs, int rt, int imm) 39 | { 40 | printf("lui $%d,%d\n", rs, imm); 41 | if (rs) 42 | grf[rs] = 1u * imm << 16; 43 | } 44 | void lw(int rs, int rt) 45 | { 46 | int imm = rand() % 1024 * 4; 47 | printf("lw $%d,%d($0)\n", rt, imm); 48 | grf[rt] = dm[imm / 4]; 49 | } 50 | void sw(int rs, int rt) 51 | { 52 | int imm = rand() % 1024 * 4; 53 | printf("sw $%d,%d($0)\n", rt, imm); 54 | dm[imm / 4] = grf[rt]; 55 | } 56 | int jump[1010]; 57 | void beq(int rs, int rt) 58 | { 59 | int jaddr = B; 60 | while (jump[jaddr]) 61 | jaddr = B; 62 | printf("beq $%d,$%d,label%d\n", rs, rt, jaddr); 63 | } 64 | void j() 65 | { 66 | int jaddr = B; 67 | while (jump[jaddr]) 68 | jaddr = B; 69 | printf("j label%d\n", jaddr); 70 | } 71 | void jal() 72 | { 73 | int jaddr = B; 74 | while (jump[jaddr]) 75 | jaddr = B; 76 | printf("jal label%d\n", jaddr); 77 | } 78 | int jr(int rs, int rt) 79 | { 80 | int i; 81 | vector can; 82 | can.clear(); 83 | for (i = 0; i < 5; i++) 84 | if (reg[i] > 0x3000 && reg[i] <= 0x3700) 85 | can.push_back(reg[i]); 86 | if (can.size() == 0) 87 | { 88 | beq(rs, rt); 89 | return 0; 90 | } 91 | rs = can[rand() % can.size()]; 92 | printf("jr $%d\n", rs); 93 | return 1; 94 | } 95 | void nop() 96 | { 97 | printf("nop\n"); 98 | } 99 | int main() 100 | { 101 | int i; 102 | srand(time(NULL)); 103 | freopen("test.asm", "w", stdout); 104 | printf("subu $31,$31,$31\n"); //���$sp 105 | int last = -1; 106 | for (i = 0; i < 700; i++) 107 | { 108 | printf("label%d: ", i); 109 | int instr = rand() % 11; 110 | while ((i < 300 || last == 1) && instr >= 6 && instr <= 9) 111 | { //j+j 112 | instr = rand() % 11; 113 | } 114 | int rs = R, rt = R, rd = R, imm = I; 115 | if (instr == 0) 116 | addu(rs, rt, rd); 117 | else if (instr == 1) 118 | subu(rs, rt, rd); 119 | else if (instr == 2) 120 | ori(rs, rt, imm); 121 | else if (instr == 3) 122 | lui(rs, 0, imm); 123 | else if (instr == 4) 124 | lw(rs, rt); 125 | else if (instr == 5) 126 | sw(rs, rt); 127 | else if (instr == 6) 128 | beq(rs, rt); 129 | else if (instr == 7) 130 | j(); 131 | else if (instr == 8) 132 | jal(); 133 | else if (instr == 9) 134 | { 135 | int yes = jr(rs, rt); 136 | if (!yes) 137 | instr = 6; //beq 138 | } 139 | else 140 | nop(); 141 | jump[i] = last = (instr >= 6 && instr <= 9); 142 | } 143 | printf("label:\n beq $0,$0,label\nnop"); 144 | return 0; 145 | } 146 | -------------------------------------------------------------------------------- /p5/D_CMP.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | `include "const.v" 3 | 4 | module D_CMP ( 5 | input [31:0] rs, 6 | input [31:0] rt, 7 | input [2:0] type, 8 | output b_jump 9 | ); 10 | wire equal = (rs == rt); 11 | wire eq0 = !(|rs); 12 | wire gt0 = (!rs[31]) && !eq0; 13 | wire le0 = (rs[31]) && !eq0; 14 | 15 | assign b_jump = (type == `B_beq && equal) || 16 | (type == `B_bne && !equal) || 17 | (type == `B_blez && (le0 || eq0)) || 18 | (type == `B_bgez && (gt0 || eq0)) || 19 | (type == `B_bgtz && gt0) || 20 | (type == `B_bltz && le0); 21 | 22 | endmodule -------------------------------------------------------------------------------- /p5/D_EXT.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | `include "const.v" 3 | 4 | module D_EXT ( 5 | input [15:0] imm, 6 | input [2:0] EXTOp, 7 | output [31:0] EXTout 8 | ); 9 | 10 | assign EXTout = (EXTOp == `EXT_signed) ? {{16{imm[15]}}, imm} : 11 | (EXTOp == `EXT_lui) ? {imm, 16'b0} : 12 | {{16{1'b0}}, imm}; 13 | 14 | endmodule -------------------------------------------------------------------------------- /p5/D_GRF.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | `include "const.v" 3 | 4 | module D_GRF ( 5 | input [31:0] WPC, // for debugging 6 | input clk, 7 | input reset, 8 | input WE, 9 | input [4:0] A1, 10 | input [4:0] A2, 11 | input [4:0] A3, 12 | input [31:0] WD, 13 | output [31:0] RD1, 14 | output [31:0] RD2 15 | ); 16 | 17 | reg [31:0] grf [31:0]; 18 | 19 | assign RD1 = (A3 == A1 && A3 && WE) ? WD : grf[A1]; // 内部转发 20 | assign RD2 = (A3 == A2 && A3 && WE) ? WD : grf[A2]; 21 | 22 | integer i; 23 | 24 | initial begin 25 | for (i=0; i<32; i=i+1) grf[i] <= 0; 26 | end 27 | 28 | always @(posedge clk) begin 29 | if (reset) begin 30 | for (i=0; i<32; i=i+1) grf[i] <= 0; 31 | end 32 | else if (WE && A3) begin 33 | grf[A3] <= WD; 34 | $display("%d@%h: $%d <= %h", $time, WPC, A3, WD); 35 | end 36 | end 37 | 38 | endmodule -------------------------------------------------------------------------------- /p5/D_NPC.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | `include "const.v" 3 | 4 | module D_NPC ( 5 | input [31:0] D_pc, 6 | input [31:0] F_pc, 7 | input [25:0] imm26, 8 | input [31:0] rs, 9 | input [2:0] Br, 10 | input b_jump, 11 | output [31:0] npc 12 | ); 13 | assign npc = (Br == `BR_pc4) ? F_pc + 4 : 14 | (Br == `BR_addr) ? {D_pc[31:28], imm26, 2'b0} : 15 | (Br == `BR_reg) ? rs : 16 | (Br == `BR_branch && b_jump) ? D_pc + 4 + {{14{imm26[15]}}, imm26[15:0], 2'b0} : 17 | F_pc + 4; 18 | endmodule -------------------------------------------------------------------------------- /p5/D_REG.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | `include "const.v" 3 | 4 | module D_REG ( 5 | input clk, 6 | input reset, 7 | input WE, 8 | input [31:0] instr_in, 9 | input [31:0] pc_in, 10 | output reg [31:0] instr_out, 11 | output reg [31:0] pc_out 12 | ); 13 | 14 | always @(posedge clk) begin 15 | if (reset) begin 16 | instr_out <= 0; 17 | pc_out <= 0; 18 | end else if(WE) begin 19 | instr_out <= instr_in; 20 | pc_out <= pc_in; 21 | end 22 | end 23 | 24 | endmodule -------------------------------------------------------------------------------- /p5/E_ALU.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | `include "const.v" 3 | 4 | module E_ALU ( 5 | input [3:0] ALUControl, 6 | input [31:0] A, 7 | input [31:0] B, 8 | output [31:0] ALUout 9 | ); 10 | 11 | wire [31:0] res_sra = $signed($signed(A) >>> B); 12 | wire [31:0] res_slt = $signed(A) < $signed(B) ? 32'b1 : 32'b0; 13 | 14 | assign ALUout = (ALUControl == `ALU_add ) ? A + B : 15 | (ALUControl == `ALU_sub ) ? A - B : 16 | (ALUControl == `ALU_and ) ? A & B : 17 | (ALUControl == `ALU_or ) ? A | B : 18 | (ALUControl == `ALU_xor ) ? A ^ B : 19 | (ALUControl == `ALU_nor ) ? ~(A | B) : 20 | (ALUControl == `ALU_sll ) ? A << B : 21 | (ALUControl == `ALU_srl ) ? A >> B : 22 | (ALUControl == `ALU_sra ) ? res_sra : 23 | (ALUControl == `ALU_slt ) ? res_slt : 24 | (ALUControl == `ALU_sltu) ? A < B : 25 | 0; 26 | 27 | endmodule -------------------------------------------------------------------------------- /p5/E_HILO.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | `include "const.v" 3 | 4 | module E_HILO ( 5 | input clk, 6 | input reset, 7 | input [31:0] rs, 8 | input [31:0] rt, 9 | input [3:0] HILOtype, 10 | output HILObusy, 11 | output [31:0] HILOout 12 | ); 13 | 14 | integer state = 0; 15 | reg [31:0] hi, lo, temp_hi, temp_lo; 16 | wire mult = (HILOtype == `HILO_mult), 17 | multu = (HILOtype == `HILO_multu), 18 | div = (HILOtype == `HILO_div), 19 | divu = (HILOtype == `HILO_divu), 20 | mflo = (HILOtype == `HILO_mflo), 21 | mfhi = (HILOtype == `HILO_mfhi), 22 | mtlo = (HILOtype == `HILO_mtlo), 23 | mthi = (HILOtype == `HILO_mthi); 24 | 25 | wire start = mult | multu | div | divu; 26 | reg busy; 27 | 28 | assign HILObusy = start | busy; 29 | assign HILOout = mflo ? lo: 30 | mfhi ? hi: 31 | 0; 32 | 33 | initial begin 34 | state <= 0; 35 | busy <= 0; 36 | hi <= 0; 37 | lo <= 0; 38 | end 39 | 40 | always @(posedge clk) begin 41 | if (reset) begin 42 | state <= 0; 43 | busy <= 0; 44 | hi <= 0; 45 | lo <= 0; 46 | end else begin 47 | if (state == 0) begin 48 | if (mtlo) lo <= rs; 49 | else if (mthi) hi <= rs; 50 | else if (mult) begin 51 | busy <= 1; 52 | state <= 5; 53 | {temp_hi, temp_lo} <= $signed(rs) * $signed(rt); 54 | end else if (multu) begin 55 | busy <= 1; 56 | state <= 5; 57 | {temp_hi, temp_lo} <= rs * rt; 58 | end else if (div) begin 59 | busy <= 1; 60 | state <= 10; 61 | temp_lo <= $signed(rs) / $signed(rt); 62 | temp_hi <= $signed(rs) % $signed(rt); 63 | end else if (divu) begin 64 | busy <= 1; 65 | state <= 10; 66 | temp_lo <= rs / rt; 67 | temp_hi <= rs % rt; 68 | end 69 | end else if (state == 1) begin 70 | state <= 0; 71 | busy <= 0; 72 | hi <= temp_hi; 73 | lo <= temp_lo; 74 | end else begin 75 | state <= state - 1; 76 | end 77 | end 78 | end 79 | 80 | endmodule 81 | -------------------------------------------------------------------------------- /p5/E_REG.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | `include "const.v" 3 | 4 | module E_REG ( 5 | input clk, 6 | input reset, 7 | input WE, 8 | input [31:0] instr_in, 9 | input [31:0] pc_in, 10 | input [31:0] EXT_in, 11 | input [31:0] rs_in, 12 | input [31:0] rt_in, 13 | output reg [31:0] instr_out, 14 | output reg [31:0] pc_out, 15 | output reg [31:0] EXT_out, 16 | output reg [31:0] rs_out, 17 | output reg [31:0] rt_out 18 | ); 19 | 20 | always @(posedge clk) begin 21 | if (reset) begin 22 | instr_out <= 0; 23 | pc_out <= 0; 24 | EXT_out <= 0; 25 | rs_out <= 0; 26 | rt_out <= 0; 27 | end else if(WE) begin 28 | instr_out <= instr_in; 29 | pc_out <= pc_in; 30 | EXT_out <= EXT_in; 31 | rs_out <= rs_in; 32 | rt_out <= rt_in; 33 | end 34 | end 35 | 36 | endmodule -------------------------------------------------------------------------------- /p5/F_IFU.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | `include "const.v" 3 | `define N 4096 4 | 5 | module F_IFU ( 6 | input clk, 7 | input reset, 8 | input WE, 9 | input [31:0] npc, 10 | output [31:0] instr, 11 | output reg [31:0] pc 12 | ); 13 | 14 | reg [31:0] im [0:`N-1]; 15 | 16 | assign instr = im[pc[15:2] - 13'HC00]; 17 | 18 | initial begin 19 | pc <= 32'h0000_3000; 20 | $readmemh("code.txt", im); 21 | end 22 | 23 | always @(posedge clk) begin 24 | if (reset) pc <= 32'h0000_3000; 25 | else if(WE) pc <= npc; 26 | 27 | end 28 | 29 | _DASM Dasm( 30 | .pc(pc), 31 | .instr(instr), 32 | .imm_as_dec(1'b1), 33 | .reg_name(1'b0), 34 | .asm() 35 | ); 36 | endmodule -------------------------------------------------------------------------------- /p5/M_DM.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | `include "const.v" 3 | `define HIGH_BYTE 15 4 | `define DM_SIZE (1<<`HIGH_BYTE) 5 | 6 | `define word memory[addr[`HIGH_BYTE:2]] 7 | 8 | `define half `word[15 + 16 * addr[1] -:16] 9 | `define half_sign `word[15 + 16 * addr[1] -:1] 10 | `define byte `word[7 + 8 * addr[1:0] -:8] 11 | `define byte_sign `word[7 + 8 * addr[1:0] -:1] 12 | 13 | module M_DM ( 14 | input [31:0] pc, // for debugging 15 | input clk, 16 | input reset, 17 | input WE, 18 | input [2:0] DMType, 19 | input [31:0] addr, 20 | input [31:0] WD, 21 | output [31:0] DMout 22 | ); 23 | reg [31:0] memory [`DM_SIZE - 1:0]; 24 | 25 | assign DMout = (DMType == `DM_w) ? `word : 26 | (DMType == `DM_h) ? {{16{`half_sign}}, `half} : 27 | (DMType == `DM_hu) ? {{16{1'b0}}, `half} : 28 | (DMType == `DM_b) ? {{24{`byte_sign}}, `byte} : 29 | (DMType == `DM_bu) ? {{24{1'b0}}, `byte} : 30 | 32'b0; 31 | 32 | integer i; 33 | 34 | initial begin 35 | for (i=0; i<`DM_SIZE; i=i+1) memory[i] <= 0; 36 | end 37 | 38 | function [31:0] F_H_OUT; 39 | input [31:0] WD; 40 | input [31:0] word; 41 | begin 42 | F_H_OUT = word; 43 | F_H_OUT[15 + 16 * addr[1] -:16] = WD[15:0]; 44 | end 45 | endfunction 46 | 47 | function [31:0] F_B_OUT; 48 | input [31:0] WD; 49 | input [31:0] word; 50 | begin 51 | F_B_OUT = word; 52 | F_B_OUT[7 + 8 * addr[1:0] -:8] = WD[7:0]; 53 | end 54 | endfunction 55 | 56 | always @(posedge clk) begin 57 | if (reset) begin 58 | for (i=0; i<`DM_SIZE; i=i+1) memory[i] <= 0; 59 | end 60 | else if (WE) begin 61 | if (DMType == `DM_w) begin 62 | `word <= WD; 63 | $display("%d@%h: *%h <= %h", $time, pc, addr&(`DM_SIZE-1), WD); 64 | end else if (DMType == `DM_h) begin 65 | `half <= WD[15:0]; 66 | $display("%d@%h: *%h <= %h", $time, pc, {addr[31:2], 2'b00}&(`DM_SIZE-1), F_H_OUT(WD, memory[addr[`HIGH_BYTE:2]])); 67 | end else if (DMType == `DM_b) begin 68 | `byte <= WD[7:0]; 69 | $display("%d@%h: *%h <= %h", $time, pc, {addr[31:2], 2'b00}&(`DM_SIZE-1), F_B_OUT(WD, memory[addr[`HIGH_BYTE:2]])); 70 | end 71 | end 72 | end 73 | 74 | endmodule -------------------------------------------------------------------------------- /p5/M_REG.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | `include "const.v" 3 | 4 | module M_REG ( 5 | input clk, 6 | input reset, 7 | input WE, 8 | input [31:0] instr_in, 9 | input [31:0] pc_in, 10 | input [31:0] ALU_in, 11 | input [31:0] rt_in, 12 | input [31:0] HILO_in, 13 | input [31:0] EXT_in, 14 | output reg [31:0] instr_out, 15 | output reg [31:0] pc_out, 16 | output reg [31:0] ALU_out, 17 | output reg [31:0] rt_out, 18 | output reg [31:0] HILO_out, 19 | output reg [31:0] EXT_out 20 | ); 21 | 22 | always @(posedge clk) begin 23 | if (reset) begin 24 | instr_out <= 0; 25 | pc_out <= 0; 26 | ALU_out <= 0; 27 | rt_out <= 0; 28 | HILO_out <= 0; 29 | EXT_out <= 0; 30 | end else if(WE) begin 31 | instr_out <= instr_in; 32 | pc_out <= pc_in; 33 | ALU_out <= ALU_in; 34 | rt_out <= rt_in; 35 | HILO_out <= HILO_in; 36 | EXT_out <= EXT_in; 37 | end 38 | end 39 | 40 | endmodule -------------------------------------------------------------------------------- /p5/W_REG.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | `include "const.v" 3 | 4 | module W_REG ( 5 | input clk, 6 | input reset, 7 | input WE, 8 | input [31:0] instr_in, 9 | input [31:0] pc_in, 10 | input [31:0] ALU_in, 11 | input [31:0] DM_in, 12 | input [31:0] HILO_in, 13 | input [31:0] EXT_in, 14 | output reg [31:0] instr_out, 15 | output reg [31:0] pc_out, 16 | output reg [31:0] ALU_out, 17 | output reg [31:0] DM_out, 18 | output reg [31:0] HILO_out, 19 | output reg [31:0] EXT_out 20 | ); 21 | 22 | always @(posedge clk) begin 23 | if (reset) begin 24 | instr_out <= 0; 25 | pc_out <= 0; 26 | ALU_out <= 0; 27 | DM_out <= 0; 28 | HILO_out <= 0; 29 | EXT_out <= 0; 30 | end else if(WE) begin 31 | instr_out <= instr_in; 32 | pc_out <= pc_in; 33 | ALU_out <= ALU_in; 34 | DM_out <= DM_in; 35 | HILO_out <= HILO_in; 36 | EXT_out <= EXT_in; 37 | end 38 | end 39 | 40 | endmodule -------------------------------------------------------------------------------- /p5/_CU.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | `include "const.v" 3 | 4 | module _CU ( 5 | input [31:0] instr, 6 | // decode 7 | output [4:0] rs_addr, 8 | output [4:0] rt_addr, 9 | output [4:0] rd_addr, 10 | output [15:0] imm, 11 | output [25:0] addr, 12 | // classify 13 | output load, 14 | output store, 15 | output calc_r, 16 | output calc_i, 17 | output lui, 18 | output shiftS, 19 | output shiftV, 20 | output branch, 21 | output j_r, 22 | output j_addr, 23 | output j_l, 24 | output md, 25 | output mt, 26 | output mf, 27 | // signals 28 | output [2:0] Br, 29 | output [2:0] B_type, 30 | output [2:0] EXTOp, 31 | 32 | output [3:0] ALUControl, 33 | output [1:0] ALUASrc, 34 | output [2:0] ALUBSrc, 35 | output [3:0] HILO_type, 36 | 37 | output [2:0] DMType, 38 | output DMWr, 39 | 40 | output [4:0] RFDst, 41 | output RFWr, 42 | output [2:0] RFWDSrc 43 | ); 44 | 45 | wire [5:0] opcode = instr[31:26], 46 | func = instr[5:0]; 47 | assign rs_addr = instr[25:21], 48 | rt_addr = instr[20:16], 49 | rd_addr = instr[15:11]; 50 | assign imm = instr[15:0]; 51 | assign addr = instr[25:0]; 52 | 53 | wire lb = (opcode == `OP_lb ); 54 | wire lbu = (opcode == `OP_lbu ); 55 | wire lh = (opcode == `OP_lh ); 56 | wire lhu = (opcode == `OP_lhu ); 57 | wire lw = (opcode == `OP_lw ); 58 | wire sb = (opcode == `OP_sb ); 59 | wire sh = (opcode == `OP_sh ); 60 | wire sw = (opcode == `OP_sw ); 61 | wire addi = (opcode == `OP_addi ); 62 | wire addiu = (opcode == `OP_addiu); 63 | wire andi = (opcode == `OP_andi ); 64 | wire beq = (opcode == `OP_beq ); 65 | wire bgtz = (opcode == `OP_bgtz ); 66 | wire blez = (opcode == `OP_blez ); 67 | wire bgez = (opcode == `OP_bgez && rt_addr == `RT_bgez); 68 | wire bltz = (opcode == `OP_bltz && rt_addr == `RT_bltz); 69 | wire bne = (opcode == `OP_bne ); 70 | wire j = (opcode == `OP_j ); 71 | wire jal = (opcode == `OP_jal ); 72 | wire ori = (opcode == `OP_ori ); 73 | wire slti = (opcode == `OP_slti ); 74 | wire sltiu = (opcode == `OP_sltiu); 75 | wire xori = (opcode == `OP_xori ); 76 | assign lui = (opcode == `OP_lui ); 77 | 78 | wire add = (opcode == `OP_rtype && func == `FUNC_add ); 79 | wire addu = (opcode == `OP_rtype && func == `FUNC_addu ); 80 | wire And = (opcode == `OP_rtype && func == `FUNC_and ); 81 | wire div = (opcode == `OP_rtype && func == `FUNC_div ); 82 | wire divu = (opcode == `OP_rtype && func == `FUNC_divu ); 83 | wire jalr = (opcode == `OP_rtype && func == `FUNC_jalr ); 84 | wire jr = (opcode == `OP_rtype && func == `FUNC_jr ); 85 | wire mfhi = (opcode == `OP_rtype && func == `FUNC_mfhi ); 86 | wire mflo = (opcode == `OP_rtype && func == `FUNC_mflo ); 87 | wire mthi = (opcode == `OP_rtype && func == `FUNC_mthi ); 88 | wire mtlo = (opcode == `OP_rtype && func == `FUNC_mtlo ); 89 | wire mult = (opcode == `OP_rtype && func == `FUNC_mult ); 90 | wire multu = (opcode == `OP_rtype && func == `FUNC_multu); 91 | wire Nor = (opcode == `OP_rtype && func == `FUNC_nor ); 92 | wire Or = (opcode == `OP_rtype && func == `FUNC_or ); 93 | wire sll = (opcode == `OP_rtype && func == `FUNC_sll && (|rd_addr)); 94 | wire sllv = (opcode == `OP_rtype && func == `FUNC_sllv ); 95 | wire slt = (opcode == `OP_rtype && func == `FUNC_slt ); 96 | wire sltu = (opcode == `OP_rtype && func == `FUNC_sltu ); 97 | wire sra = (opcode == `OP_rtype && func == `FUNC_sra ); 98 | wire srav = (opcode == `OP_rtype && func == `FUNC_srav ); 99 | wire srl = (opcode == `OP_rtype && func == `FUNC_srl ); 100 | wire srlv = (opcode == `OP_rtype && func == `FUNC_srlv ); 101 | wire sub = (opcode == `OP_rtype && func == `FUNC_sub ); 102 | wire subu = (opcode == `OP_rtype && func == `FUNC_subu ); 103 | wire Xor = (opcode == `OP_rtype && func == `FUNC_xor ); 104 | 105 | assign load = lw | lh | lhu | lbu | lb; 106 | assign store = sw | sh | sb; 107 | assign branch = beq | bne | blez | bgtz | bgez | bltz; 108 | 109 | assign calc_r = add | addu | sub | subu | slt | sltu | 110 | sll | sllv | srl | srlv | sra | srav | 111 | And | Or | Xor | Nor; // exclude jr & jalr & mt/mf/md 112 | assign calc_i = addi | addiu | andi | ori | xori | 113 | slti | sltiu; // exclude lui 114 | 115 | assign md = mult | multu | div | divu; 116 | assign mt = mtlo | mthi; 117 | assign mf = mflo | mfhi; 118 | 119 | assign shiftS = sll | srl | sra; 120 | assign shiftV = sllv | srlv | srav; 121 | 122 | assign j_r = jr | jalr; 123 | assign j_addr = j | jal; 124 | assign j_l = jal | jalr; 125 | 126 | 127 | ////////////StageD 128 | assign EXTOp = (addi | addiu | slti | sltiu | load | store) ? `EXT_signed : 129 | lui ? `EXT_lui : 130 | `EXT_unsigned; 131 | // wire unsigned_ext = andi | ori | xori; 132 | assign Br = branch ? `BR_branch : 133 | j_addr ? `BR_addr : 134 | j_r ? `BR_reg : 135 | `BR_pc4; 136 | assign B_type = beq ? `B_beq : 137 | bne ? `B_bne : 138 | blez ? `B_blez : 139 | bgez ? `B_bgez : 140 | bgtz ? `B_bgtz : 141 | bltz ? `B_bltz : 142 | `B_beq; 143 | 144 | ////////////StageE 145 | assign ALUControl = (sub | subu) ? `ALU_sub : 146 | (And | andi) ? `ALU_and : 147 | (Or | ori) ? `ALU_or : 148 | (Xor | xori) ? `ALU_xor : 149 | (Nor) ? `ALU_nor : 150 | (sll | sllv) ? `ALU_sll : 151 | (srl | srlv) ? `ALU_srl : 152 | (sra | srav) ? `ALU_sra : 153 | (slt | slti) ? `ALU_slt : 154 | (sltu | sltiu) ? `ALU_sltu : 155 | `ALU_add; 156 | assign ALUASrc = (shiftS | shiftV) ? `ALUASrcRT : `ALUASrcRS; 157 | assign ALUBSrc = shiftS ? `ALUBSrcShamt : 158 | shiftV ? `ALUBSrcRS_4_0 : 159 | (calc_r && !shiftS && !shiftV) ? `ALUBSrcRT : 160 | (calc_i | lui | load | store) ? `ALUBSrcExt : 161 | `ALUBSrcRT; 162 | assign HILO_type = mult ? `HILO_mult : 163 | multu ? `HILO_multu : 164 | div ? `HILO_div : 165 | divu ? `HILO_divu : 166 | mflo ? `HILO_mflo : 167 | mfhi ? `HILO_mfhi : 168 | mtlo ? `HILO_mtlo : 169 | mthi ? `HILO_mthi : 170 | `HILO_none; 171 | 172 | ////////////StageM 173 | assign DMType = (lw || sw) ? `DM_w : 174 | (lh || sh) ? `DM_h : 175 | (lhu) ? `DM_hu : 176 | (lb || sb) ? `DM_b : 177 | (lbu) ? `DM_bu : 178 | `DM_w; 179 | assign DMWr = store; 180 | 181 | ////////////StageW 182 | assign RFDst = (calc_r | jalr | mf) ? rd_addr : 183 | (calc_i | lui | load) ? rt_addr : 184 | (jal) ? 5'd31 : 185 | 5'd0; 186 | assign RFWr = !(!RFDst); 187 | assign RFWDSrc = load ? `RFWD_DMout : 188 | (jal | jalr) ? `RFWD_PC8 : 189 | lui ? `RFWD_EXTout : 190 | mf ? `RFWD_HILOout : 191 | `RFWD_ALUout; 192 | endmodule -------------------------------------------------------------------------------- /p5/_DASM.v: -------------------------------------------------------------------------------- 1 | `define lb 6'b100000 2 | `define lbu 6'b100100 3 | `define lh 6'b100001 4 | `define lhu 6'b100101 5 | `define lw 6'b100011 6 | `define sb 6'b101000 7 | `define sh 6'b101001 8 | `define sw 6'b101011 9 | `define addop 6'b000000 10 | `define addfu 6'b100000 11 | `define addi 6'b001000 12 | `define addiu 6'b001001 13 | `define adduop 6'b000000 14 | `define addufu 6'b100001 15 | `define andop 6'b000000 16 | `define andfu 6'b100100 17 | `define andi 6'b001100 18 | `define beq 6'b000100 19 | `define bgezop 6'b000001 20 | `define bgezrt 5'b00001 21 | `define bgtz 6'b000111 22 | `define blez 6'b000110 23 | `define bltzop 6'b000001 24 | `define bltzrt 5'b00000 25 | `define bne 6'b000101 26 | `define divop 6'b000000 27 | `define divfu 6'b011010 28 | `define divuop 6'b000000 29 | `define divufu 6'b011011 30 | `define j 6'b000010 31 | `define jal 6'b000011 32 | `define jalrop 6'b000000 33 | `define jalrfu 6'b001001 34 | `define jrop 6'b000000 35 | `define jrfu 6'b001000 36 | `define Lui 6'b001111 37 | `define mfhiop 6'b000000 38 | `define mfhifu 6'b010000 39 | `define mfloop 6'b000000 40 | `define mflofu 6'b010010 41 | `define mthiop 6'b000000 42 | `define mthifu 6'b010001 43 | `define mtloop 6'b000000 44 | `define mtlofu 6'b010011 45 | `define multop 6'b000000 46 | `define multfu 6'b011000 47 | `define multuop 6'b000000 48 | `define multufu 6'b011001 49 | `define norop 6'b000000 50 | `define norfu 6'b100111 51 | `define orop 6'b000000 52 | `define orfu 6'b100101 53 | `define ori 6'b001101 54 | `define sllop 6'b000000 55 | `define sllfu 6'b000000 56 | `define sllvop 6'b000000 57 | `define sllvfu 6'b000100 58 | `define sltop 6'b000000 59 | `define sltfu 6'b101010 60 | `define slti 6'b001010 61 | `define sltiu 6'b001011 62 | `define sltuop 6'b000000 63 | `define sltufu 6'b101011 64 | `define sraop 6'b000000 65 | `define srafu 6'b000011 66 | `define sravop 6'b000000 67 | `define sravfu 6'b000111 68 | `define srlop 6'b000000 69 | `define srlfu 6'b000010 70 | `define srlvop 6'b000000 71 | `define srlvfu 6'b000110 72 | `define subop 6'b000000 73 | `define subfu 6'b100010 74 | `define subuop 6'b000000 75 | `define subufu 6'b100011 76 | `define sw 6'b101011 77 | `define xorop 6'b000000 78 | `define xorfu 6'b100110 79 | `define xori 6'b001110 80 | 81 | module _DASM ( 82 | input [31:0] pc, 83 | input [31:0] instr, 84 | input reg_name, 85 | input imm_as_dec, 86 | output [32*8-1:0] asm 87 | ); 88 | 89 | wire [5:0]func=instr[5:0], op=instr[31:26]; 90 | wire [4:0]rs=instr[25:21], rt=instr[20:16], rd=instr[15:11], sha=instr[10:6]; 91 | wire [15:0] imm=instr[15:0]; 92 | wire [25:0] target=instr[25:0]; 93 | 94 | wire beq=(op==`beq); 95 | wire bgez=(op==`bgezop)&(rt==`bgezrt); 96 | wire bgtz=(op==`bgtz); 97 | wire blez=(op==`blez); 98 | wire bltz=(op==`bltzop)&(rt==`bltzrt); 99 | wire bne=(op==`bne); 100 | 101 | wire j=(op==`j); 102 | wire jal=(op==`jal); 103 | wire jalr=(op==`jalrop)&(func==`jalrfu); 104 | wire jr=(op==`jrop)&(func==`jrfu); 105 | 106 | wire lb=(op==`lb); 107 | wire lbu=(op==`lbu); 108 | wire lh=(op==`lh); 109 | wire lhu=(op==`lhu); 110 | wire lw=(op==`lw); 111 | wire sb=(op==`sb); 112 | wire sh=(op==`sh); 113 | wire sw=(op==`sw); 114 | 115 | wire lui=(op==`Lui); 116 | 117 | wire add=(op==`addop)&(func==`addfu); 118 | wire addi=(op==`addi); 119 | wire addiu=(op==`addiu); 120 | wire addu=(op==`adduop)&(func==`addufu); 121 | wire And=(op==`andop)&(func==`andfu); 122 | wire andi=(op==`andi); 123 | wire div=(op==`divop)&(func==`divfu); 124 | wire divu=(op==`divuop)&(func==`divufu); 125 | wire mfhi=(op==`mfhiop)&(func==`mfhifu); 126 | wire mflo=(op==`mfloop)&(func==`mflofu); 127 | wire mthi=(op==`mthiop)&(func==`mthifu); 128 | wire mtlo=(op==`mtloop)&(func==`mtlofu); 129 | wire mult=(op==`multop)&(func==`multfu); 130 | wire multu=(op==`multuop)&(func==`multufu); 131 | wire Nor=(op==`norop)&(func==`norfu); 132 | wire Or=(op==`orop)&(func==`orfu); 133 | wire ori=(op==`ori); 134 | wire sll=(op==6'b000000)&(func==6'b000000)&(|rd); 135 | wire sllv=(op==`sllvop)&(func==`sllvfu); 136 | wire slt=(op==`sltop)&(func==`sltfu); 137 | wire slti=(op==`slti); 138 | wire sltiu=(op==`sltiu); 139 | wire sltu=(op==`sltuop)&(func==`sltufu); 140 | wire sra=(op==`sraop)&(func==`srafu); 141 | wire srav=(op==`sravop)&(func==`sravfu); 142 | wire srl=(op==`srlop)&(func==`srlfu); 143 | wire srlv=(op==`srlvop)&(func==`srlvfu); 144 | wire sub=(op==`subop)&(func==`subfu); 145 | wire subu=(op==`subuop)&(func==`subufu); 146 | wire Xor=(op==`xorop)&(func==`xorfu); 147 | wire xori=(op==`xori); 148 | 149 | function [8*3-1:0] get_reg; 150 | input [4:0] num; 151 | begin 152 | case (num) 153 | 5'b00000: get_reg = reg_name ? "$00" : "$00"; 154 | 5'b00001: get_reg = reg_name ? "$at" : "$01"; 155 | 5'b00010: get_reg = reg_name ? "$v0" : "$02"; 156 | 5'b00011: get_reg = reg_name ? "$v1" : "$03"; 157 | 5'b00100: get_reg = reg_name ? "$a0" : "$04"; 158 | 5'b00101: get_reg = reg_name ? "$a1" : "$05"; 159 | 5'b00110: get_reg = reg_name ? "$a2" : "$06"; 160 | 5'b00111: get_reg = reg_name ? "$a3" : "$07"; 161 | 5'b01000: get_reg = reg_name ? "$t0" : "$08"; 162 | 5'b01001: get_reg = reg_name ? "$t1" : "$09"; 163 | 5'b01010: get_reg = reg_name ? "$t2" : "$10"; 164 | 5'b01011: get_reg = reg_name ? "$t3" : "$11"; 165 | 5'b01100: get_reg = reg_name ? "$t4" : "$12"; 166 | 5'b01101: get_reg = reg_name ? "$t5" : "$13"; 167 | 5'b01110: get_reg = reg_name ? "$t6" : "$14"; 168 | 5'b01111: get_reg = reg_name ? "$t7" : "$15"; 169 | 5'b10000: get_reg = reg_name ? "$s0" : "$16"; 170 | 5'b10001: get_reg = reg_name ? "$s1" : "$17"; 171 | 5'b10010: get_reg = reg_name ? "$s2" : "$18"; 172 | 5'b10011: get_reg = reg_name ? "$s3" : "$19"; 173 | 5'b10100: get_reg = reg_name ? "$s4" : "$20"; 174 | 5'b10101: get_reg = reg_name ? "$s5" : "$21"; 175 | 5'b10110: get_reg = reg_name ? "$s6" : "$22"; 176 | 5'b10111: get_reg = reg_name ? "$s7" : "$23"; 177 | 5'b11000: get_reg = reg_name ? "$t8" : "$24"; 178 | 5'b11001: get_reg = reg_name ? "$t9" : "$25"; 179 | 5'b11010: get_reg = reg_name ? "$s8" : "$26"; 180 | 5'b11011: get_reg = reg_name ? "$s9" : "$27"; 181 | 5'b11100: get_reg = reg_name ? "$gp" : "$28"; 182 | 5'b11101: get_reg = reg_name ? "$sp" : "$29"; 183 | 5'b11110: get_reg = reg_name ? "$fp" : "$30"; 184 | 5'b11111: get_reg = reg_name ? "$ra" : "$31"; 185 | endcase 186 | end 187 | endfunction 188 | 189 | function [7:0] get_hex; 190 | input [3:0] num; 191 | begin 192 | case (num) 193 | 4'b0000: get_hex = "0"; 194 | 4'b0001: get_hex = "1"; 195 | 4'b0010: get_hex = "2"; 196 | 4'b0011: get_hex = "3"; 197 | 4'b0100: get_hex = "4"; 198 | 4'b0101: get_hex = "5"; 199 | 4'b0110: get_hex = "6"; 200 | 4'b0111: get_hex = "7"; 201 | 4'b1000: get_hex = "8"; 202 | 4'b1001: get_hex = "9"; 203 | 4'b1010: get_hex = "A"; 204 | 4'b1011: get_hex = "B"; 205 | 4'b1100: get_hex = "C"; 206 | 4'b1101: get_hex = "D"; 207 | 4'b1110: get_hex = "E"; 208 | 4'b1111: get_hex = "F"; 209 | endcase 210 | end 211 | endfunction 212 | 213 | wire [7:0] sp = 8'b0010_0000; 214 | 215 | wire [4*8-1:0] srs = {sp, get_reg(rs)}, srd = {sp, get_reg(rd)}, srt = {sp, get_reg(rt)}; 216 | wire [4*8-1:0] soff = {get_hex(imm[15:12]), get_hex(imm[11:8]), get_hex(imm[7:4]), get_hex(imm[3:0])}; 217 | wire [5*8-1:0] simm = {sp, get_hex(imm[15:12]), get_hex(imm[11:8]), get_hex(imm[7:4]), get_hex(imm[3:0])}; 218 | wire [31:0] imm32_signed = imm[15] ? -{{16{imm[15]}}, imm} : {16'b0, imm}; 219 | wire [6*8-1:0] simm_dec = {sp, get_hex(imm/10000%10), get_hex(imm/1000%10), get_hex(imm/100%10), get_hex(imm/10%10), get_hex(imm%10)}; 220 | wire [7*8-1:0] simm_dec_signed = {sp, imm[15] ? "-" : " ", 221 | get_hex(imm32_signed/10000%10), get_hex(imm32_signed/1000%10), 222 | get_hex(imm32_signed/100%10), get_hex(imm32_signed/10%10), get_hex(imm32_signed%10)}; 223 | 224 | wire [4*8-1:0] ssha = {sp, get_hex(sha)}; 225 | // wire [10*8-1:0] saddr = {sp, get_, "_"} 226 | // wire _rdrsrt = {} 227 | 228 | wire [12*8-1:0] _rd_rs_rt = {srd, srs, srt}; 229 | wire [12*8-1:0] _rd_rt_rs = {srd, srt, srs}; 230 | wire [12*8-1:0] _rd_rt_sha = {srd, srt, ssha}; 231 | wire [15*8-1:0] _rt_rs_imm = {srt, srs, imm_as_dec ? simm_dec : simm}; 232 | wire [15*8-1:0] _rt_rs_imm_signed = {srt, srs, imm_as_dec ? simm_dec_signed : simm}; 233 | wire [31:0] branch_npc = pc + 4 + {{14{imm[15]}}, imm, 2'b0}; 234 | wire [24*8-1:0] _rs_rt_imm = {srs, srt, imm_as_dec ? simm_dec : simm, "[", 235 | get_hex(branch_npc[31:28]), get_hex(branch_npc[27:24]), 236 | get_hex(branch_npc[23:20]), get_hex(branch_npc[19:16]), 237 | get_hex(branch_npc[15:12]), get_hex(branch_npc[11:8]), 238 | get_hex(branch_npc[7:4]), get_hex(branch_npc[3:0]), "]"}; 239 | wire [20*8-1:0] _rs_imm = {srs, imm_as_dec ? simm_dec : simm, "[", 240 | get_hex(branch_npc[31:28]), get_hex(branch_npc[27:24]), 241 | get_hex(branch_npc[23:20]), get_hex(branch_npc[19:16]), 242 | get_hex(branch_npc[15:12]), get_hex(branch_npc[11:8]), 243 | get_hex(branch_npc[7:4]), get_hex(branch_npc[3:0]), "]"}; // branch 244 | wire [10*8-1:0] _rt_imm = {srt, imm_as_dec ? simm_dec : simm}; 245 | wire [8*8-1:0] _rs_rt = {srs, srt}; 246 | wire [9*8-1:0] _target = {" 0", get_hex(target[25:22]), get_hex(target[21:18]), 247 | get_hex(target[17:14]), get_hex(target[13:10]), 248 | get_hex(target[9:6]), get_hex(target[5:2]), get_hex({target[1:0], 2'b0})}; 249 | wire [8*8-1:0] _rd_rs = {srd, srs}; 250 | wire [4*8-1:0] _rs = {srs}; 251 | wire [4*8-1:0] _rd = {srd}; 252 | wire [14*8-1:0] _rt_off_base = {srt, " ", soff, "(", srs[3*8-1:0], ")"}; 253 | wire [4*8-1:0] _rt_rd = {srd}; 254 | 255 | function [32*8-1:0] asm_ll; 256 | input [32*8-1:0] str; 257 | begin 258 | asm_ll = str; 259 | while (!asm_ll[32*8-1 -:8]) asm_ll = asm_ll << 8; 260 | end 261 | endfunction 262 | 263 | assign asm = asm_ll( 264 | beq ? {"beq", _rs_rt_imm} : 265 | bgez ? {"bgez", _rs_imm} : 266 | bgtz ? {"bgtz", _rs_imm} : 267 | blez ? {"blez", _rs_imm} : 268 | bltz ? {"bltz", _rs_imm} : 269 | bne ? {"bne", _rs_rt_imm} : 270 | j ? {"j", _target} : 271 | jal ? {"jal", _target} : 272 | jalr ? {"jalr", _rd_rs} : 273 | jr ? {"jr", _rs} : 274 | lb ? {"lb", _rt_off_base} : 275 | lbu ? {"lbu", _rt_off_base} : 276 | lh ? {"lh", _rt_off_base} : 277 | lhu ? {"lhu", _rt_off_base} : 278 | lw ? {"lw", _rt_off_base} : 279 | sb ? {"sb", _rt_off_base} : 280 | sh ? {"sh", _rt_off_base} : 281 | sw ? {"sw", _rt_off_base} : 282 | lui ? {"lui", _rt_imm} : 283 | add ? {"add", _rd_rs_rt} : 284 | addi ? {"addi", _rt_rs_imm_signed} : 285 | addiu ? {"addiu", _rt_rs_imm_signed} : 286 | addu ? {"addu", _rd_rs_rt} : 287 | And ? {"And", _rd_rs_rt} : 288 | andi ? {"andi", _rt_rs_imm} : 289 | div ? {"div", _rs_rt} : 290 | divu ? {"divu", _rs_rt} : 291 | mfhi ? {"mfhi", _rd} : 292 | mflo ? {"mflo", _rd} : 293 | mthi ? {"mthi", _rd} : 294 | mtlo ? {"mtlo", _rd} : 295 | mult ? {"mult", _rs_rt} : 296 | multu ? {"multu", _rs_rt} : 297 | Nor ? {"Nor", _rd_rs_rt} : 298 | Or ? {"Or", _rd_rs_rt} : 299 | ori ? {"ori", _rt_rs_imm} : 300 | sll ? {"sll", _rd_rt_sha} : 301 | sllv ? {"sllv", _rd_rt_rs} : 302 | slt ? {"slt", _rd_rs_rt} : 303 | slti ? {"slti", _rt_rs_imm_signed} : 304 | sltiu ? {"sltiu", _rt_rs_imm_signed} : 305 | sltu ? {"sltu", _rd_rs_rt} : 306 | sra ? {"sra", _rd_rt_sha} : 307 | srav ? {"srav", _rd_rt_rs} : 308 | srl ? {"srl", _rd_rt_sha} : 309 | srlv ? {"srlv", _rd_rt_rs} : 310 | sub ? {"sub", _rd_rs_rt} : 311 | subu ? {"subu", _rd_rs_rt} : 312 | Xor ? {"Xor", _rd_rs_rt} : 313 | xori ? {"xori", _rt_rs_imm} : 314 | "No Instr"); 315 | 316 | endmodule -------------------------------------------------------------------------------- /p5/_FU.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | `include "const.v" 3 | 4 | module _FU ( 5 | input [31:0] D_instr, 6 | input [31:0] E_instr, 7 | input [31:0] M_instr, 8 | input [31:0] W_instr, 9 | output forwardE, 10 | output forwardM, 11 | output forwardW 12 | ); 13 | 14 | wire E_j_l; 15 | _CU _EInterp ( 16 | .instr(E_instr), 17 | .j_l(E_j_l) 18 | ); 19 | 20 | wire M_j_l, M_calc_r, M_calc_i, M_mf; 21 | _CU _MInterp ( 22 | .instr(M_instr), 23 | .calc_r(M_calc_r), 24 | .calc_i(M_calc_i), 25 | .j_l(M_j_l), 26 | .mf(M_mf) 27 | ); 28 | 29 | wire W_j_l, W_calc_r, W_calc_i, W_load, W_mf; 30 | _CU _WInterp ( 31 | .instr(W_instr), 32 | .calc_r(W_calc_r), 33 | .calc_i(W_calc_i), 34 | .j_l(W_j_l), 35 | .load(W_load), 36 | .mf(W_mf) 37 | ); 38 | 39 | assign forwardE = E_j_l; 40 | assign forwardM = M_j_l | M_calc_r | M_calc_i | M_mf; 41 | assign forwardW = W_j_l | W_calc_r | W_calc_i | W_load | W_mf; 42 | 43 | endmodule -------------------------------------------------------------------------------- /p5/_SU.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | `include "const.v" 3 | 4 | module _SU ( 5 | input [31:0] D_instr, 6 | input [31:0] E_instr, 7 | input [31:0] M_instr, 8 | input E_HILObusy, 9 | output stall 10 | ); 11 | /////////////////////// StageD 12 | wire D_calc_r, D_calc_i, D_load, D_store, D_shiftS, D_j_r, D_j_noreg, D_branch, D_mt, D_mf, D_md; 13 | wire [4:0] D_rs_addr, D_rt_addr; 14 | wire [31:0] D_type; 15 | _CU _DInterp ( 16 | .instr(D_instr), 17 | .rs_addr(D_rs_addr), 18 | .rt_addr(D_rt_addr), 19 | .calc_r(D_calc_r), 20 | .calc_i(D_calc_i), 21 | .load(D_load), 22 | .store(D_store), 23 | .j_r(D_j_r), 24 | .shiftS(D_shiftS), 25 | .branch(D_branch), 26 | .md(D_md), 27 | .mt(D_mt), 28 | .mf(D_mf) 29 | ); 30 | 31 | wire [2:0] TuseRS = (D_branch | D_j_r) ? 3'd0 : 32 | ((D_calc_r & !D_shiftS) | D_calc_i | D_load | D_store | D_md | D_mt) ? 3'd1 : 33 | 3'd3; 34 | wire [2:0] TuseRT = D_branch ? 3'd0 : 35 | (D_calc_r | D_md) ? 3'd1 : 36 | D_store ? 3'd2 : 37 | 3'd3; 38 | 39 | /////////////////////// StageE 40 | wire [31:0] E_type; 41 | wire E_calc_r, E_calc_i, E_load, E_mf; 42 | wire [4:0] E_RFDst; 43 | _CU _EInterp ( 44 | .instr(E_instr), 45 | .calc_r(E_calc_r), 46 | .calc_i(E_calc_i), 47 | .load(E_load), 48 | .RFDst(E_RFDst), 49 | .mf(E_mf) 50 | ); 51 | 52 | wire [2:0] TnewE = E_calc_r | E_calc_i | E_mf ? 3'd1 : 53 | E_load ? 3'd2 : 54 | 3'd0; 55 | 56 | /////////////////////// StageM 57 | wire [31:0] M_type; 58 | wire M_load, M_calc_r, M_calc_i; 59 | wire [4:0] M_RFDst; 60 | _CU _MInterp ( 61 | .instr(M_instr), 62 | .load(M_load), 63 | .calc_r(M_calc_r), 64 | .calc_i(M_calc_i), 65 | .RFDst(M_RFDst) 66 | ); 67 | 68 | wire [2:0] TnewM = M_load ? 3'd1 : 69 | 3'd0; 70 | 71 | // Tuse < Tnew 72 | wire stall_rs_e = (TuseRS < TnewE) && (D_rs_addr && D_rs_addr == E_RFDst); 73 | wire stall_rs_m = (TuseRS < TnewM) && (D_rs_addr && D_rs_addr == M_RFDst); 74 | wire stall_rs = stall_rs_e | stall_rs_m; 75 | 76 | wire stall_rt_e = (TuseRT < TnewE) && (D_rt_addr && D_rt_addr == E_RFDst); 77 | wire stall_rt_m = (TuseRT < TnewM) && (D_rt_addr && D_rt_addr == M_RFDst); 78 | wire stall_rt = stall_rt_e | stall_rt_m; 79 | 80 | wire stall_HILO = E_HILObusy & (D_md | D_mt | D_mf); 81 | 82 | assign stall = stall_rs | stall_rt | stall_HILO; 83 | 84 | endmodule -------------------------------------------------------------------------------- /p5/_tb.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | 3 | module _tb; 4 | reg clk; 5 | reg reset; 6 | 7 | mips uut ( 8 | .clk(clk), 9 | .reset(reset) 10 | ); 11 | 12 | initial begin 13 | clk = 0; 14 | reset = 1; 15 | 16 | #10; 17 | reset = 0; 18 | end 19 | 20 | always #5 clk=~clk; 21 | 22 | endmodule 23 | 24 | -------------------------------------------------------------------------------- /p5/const.v: -------------------------------------------------------------------------------- 1 | //// Instr 2 | `define OP_rtype 6'b000000 3 | `define OP_lb 6'b100000 4 | `define OP_lbu 6'b100100 5 | `define OP_lh 6'b100001 6 | `define OP_lhu 6'b100101 7 | `define OP_lw 6'b100011 8 | `define OP_sb 6'b101000 9 | `define OP_sh 6'b101001 10 | `define OP_sw 6'b101011 11 | `define OP_addi 6'b001000 12 | `define OP_addiu 6'b001001 13 | `define OP_andi 6'b001100 14 | `define OP_beq 6'b000100 15 | `define OP_bgez 6'b000001 16 | `define OP_bgtz 6'b000111 17 | `define OP_blez 6'b000110 18 | `define OP_bltz 6'b000001 19 | `define OP_bne 6'b000101 20 | `define OP_j 6'b000010 21 | `define OP_jal 6'b000011 22 | `define OP_lui 6'b001111 23 | `define OP_ori 6'b001101 24 | `define OP_slti 6'b001010 25 | `define OP_sltiu 6'b001011 26 | `define OP_xori 6'b001110 27 | 28 | `define FUNC_add 6'b100000 29 | `define FUNC_addu 6'b100001 30 | `define FUNC_and 6'b100100 31 | `define FUNC_div 6'b011010 32 | `define FUNC_divu 6'b011011 33 | `define FUNC_jalr 6'b001001 34 | `define FUNC_jr 6'b001000 35 | `define FUNC_mfhi 6'b010000 36 | `define FUNC_mflo 6'b010010 37 | `define FUNC_mthi 6'b010001 38 | `define FUNC_mtlo 6'b010011 39 | `define FUNC_mult 6'b011000 40 | `define FUNC_multu 6'b011001 41 | `define FUNC_nor 6'b100111 42 | `define FUNC_or 6'b100101 43 | `define FUNC_sll 6'b000000 44 | `define FUNC_sllv 6'b000100 45 | `define FUNC_slt 6'b101010 46 | `define FUNC_sltu 6'b101011 47 | `define FUNC_sra 6'b000011 48 | `define FUNC_srav 6'b000111 49 | `define FUNC_srl 6'b000010 50 | `define FUNC_srlv 6'b000110 51 | `define FUNC_sub 6'b100010 52 | `define FUNC_subu 6'b100011 53 | `define FUNC_xor 6'b100110 54 | 55 | `define RT_bltz 5'b00000 56 | `define RT_bgez 5'b00001 57 | 58 | //// CU Signal 59 | 60 | // ALU 61 | `define ALU_add 4'd0 62 | `define ALU_sub 4'd1 63 | `define ALU_and 4'd2 64 | `define ALU_or 4'd3 65 | `define ALU_xor 4'd4 66 | `define ALU_nor 4'd5 67 | `define ALU_sll 4'd6 68 | `define ALU_srl 4'd7 69 | `define ALU_sra 4'd8 70 | `define ALU_slt 4'd9 71 | `define ALU_sltu 4'd10 72 | `define ALU_lui 4'd11 73 | 74 | // DM 75 | `define DM_w 3'b000 76 | `define DM_h 3'b001 77 | `define DM_hu 3'b010 78 | `define DM_b 3'b011 79 | `define DM_bu 3'b100 80 | 81 | // Branch 82 | `define BR_pc4 3'b000 83 | `define BR_addr 3'b001 84 | `define BR_reg 3'b010 85 | `define BR_branch 3'b011 86 | 87 | // B_type 88 | `define B_beq 3'd0 89 | `define B_bne 3'd1 90 | `define B_blez 3'd2 91 | `define B_bgtz 3'd3 92 | `define B_bgez 3'd4 93 | `define B_bltz 3'd5 94 | 95 | // RFWDSel 96 | `define RFWD_ALUout 3'b000 97 | `define RFWD_DMout 3'b001 98 | `define RFWD_PC8 3'b010 99 | `define RFWD_HILOout 3'b011 100 | `define RFWD_EXTout 3'b100 101 | 102 | // ALUASrc 103 | `define ALUASrcRT 2'b00 104 | `define ALUASrcRS 2'b01 105 | 106 | // ALUBSrc 107 | `define ALUBSrcShamt 3'd0 108 | `define ALUBSrcRS_4_0 3'd1 109 | `define ALUBSrcRT 3'd2 110 | `define ALUBSrcExt 3'd3 111 | 112 | // HILOType 113 | `define HILO_none 4'd0 114 | `define HILO_mult 4'd1 115 | `define HILO_multu 4'd2 116 | `define HILO_div 4'd3 117 | `define HILO_divu 4'd4 118 | `define HILO_mflo 4'd5 119 | `define HILO_mfhi 4'd6 120 | `define HILO_mtlo 4'd7 121 | `define HILO_mthi 4'd8 122 | 123 | // EXT 124 | `define EXT_unsigned 3'd0 125 | `define EXT_signed 3'd1 126 | `define EXT_lui 3'd2 -------------------------------------------------------------------------------- /p5/mips.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | `include "const.v" 3 | 4 | module mips ( 5 | input clk, 6 | input reset 7 | ); 8 | wire stall; 9 | wire F_pc_en = !stall, D_reg_en = !stall, E_reg_en = 1'b1, M_reg_en = 1'b1, W_reg_en = 1'b1; // Reg En 10 | wire D_reg_reset = 1'b0, E_reg_reset = stall, M_reg_reset = 1'b0, W_reg_reset = 1'b0; 11 | 12 | wire [31:0] F_instr, D_instr, E_instr, M_instr, W_instr; 13 | wire E_HILObusy; 14 | _SU _su( 15 | .D_instr(D_instr), 16 | .E_instr(E_instr), 17 | .M_instr(M_instr), 18 | .E_HILObusy(E_HILObusy), 19 | .stall(stall) 20 | ); 21 | 22 | wire [31:0] E_RFWD, M_RFWD, W_RFWD; 23 | wire [4:0] E_RFDst, M_RFDst, W_RFDst; 24 | wire [2:0] E_RFWDSrc, M_RFWDSrc, W_RFWDSrc; 25 | wire W_RFWE; 26 | 27 | assign E_RFWD = // (E_RFWDSrc == `RFWD_ALUout) ? E_ALUout : 28 | // (E_RFWDSrc == `RFWD_DMout) ? E_DMout : 29 | // (E_RFWDSrc == `RFWD_HILOout) ? E_HILOout : 30 | (E_RFWDSrc == `RFWD_EXTout) ? E_EXTout : 31 | (E_RFWDSrc == `RFWD_PC8) ? E_pc + 8 : 32 | 0; // don't forward 33 | 34 | assign M_RFWD = (M_RFWDSrc == `RFWD_ALUout) ? M_ALUout : 35 | (M_RFWDSrc == `RFWD_HILOout) ? M_HILOout : 36 | (M_RFWDSrc == `RFWD_EXTout) ? M_EXTout : 37 | // (M_RFWDSrc == `RFWD_DMout) ? M_DMout : 38 | (M_RFWDSrc == `RFWD_PC8) ? M_pc + 8 : 39 | 0; 40 | 41 | assign W_RFWD = (W_RFWDSrc == `RFWD_ALUout) ? W_ALUout : 42 | (W_RFWDSrc == `RFWD_HILOout) ? W_HILOout : 43 | (W_RFWDSrc == `RFWD_EXTout) ? W_EXTout : 44 | (W_RFWDSrc == `RFWD_DMout) ? W_DMout : 45 | (W_RFWDSrc == `RFWD_PC8) ? W_pc + 8 : 46 | 0; 47 | 48 | /// StageF 49 | wire [31:0] F_pc, npc; 50 | F_IFU F_ifu( 51 | .clk(clk), 52 | .reset(reset), 53 | .WE(F_pc_en), 54 | .npc(npc), 55 | .instr(F_instr), 56 | .pc(F_pc) 57 | ); 58 | 59 | /// StageD 60 | wire [31:0] D_pc; 61 | D_REG D_reg ( 62 | .clk(clk), 63 | .reset(reset || D_reg_reset), 64 | .WE(D_reg_en), 65 | 66 | .instr_in(F_instr), 67 | .pc_in(F_pc), 68 | 69 | .instr_out(D_instr), 70 | .pc_out(D_pc) 71 | ); 72 | 73 | wire [4:0] D_rs_addr, D_rt_addr; 74 | wire [15:0] D_imm; 75 | wire [25:0] D_addr; 76 | wire D_b_jump; 77 | wire [2:0] D_EXTOp; 78 | wire [2:0] D_Br, D_B_type; 79 | wire [31:0] D_rs, D_rt, D_EXTout, D_type; 80 | 81 | _CU D_cu( 82 | .instr(D_instr), 83 | .rs_addr(D_rs_addr), 84 | .rt_addr(D_rt_addr), 85 | .imm(D_imm), 86 | .addr(D_addr), 87 | .EXTOp(D_EXTOp), 88 | .Br(D_Br), 89 | .B_type(D_B_type) 90 | ); 91 | 92 | wire [31:0] W_pc; 93 | 94 | D_GRF D_grf ( 95 | .WPC(W_pc), 96 | .clk(clk), 97 | .reset(reset), 98 | .WE(W_RFWE), 99 | .A1(D_rs_addr), 100 | .A2(D_rt_addr), 101 | .A3(W_RFDst), 102 | .WD(W_RFWD), 103 | .RD1(D_rs), 104 | .RD2(D_rt) 105 | ); 106 | 107 | D_EXT D_ext ( 108 | .imm(D_imm), 109 | .EXTOp(D_EXTOp), 110 | .EXTout(D_EXTout) 111 | ); 112 | // FORWARD 113 | wire [31:0] FWD_D_RS = (D_rs_addr == 0) ? 0 : 114 | (D_rs_addr == E_RFDst) ? E_RFWD : 115 | (D_rs_addr == M_RFDst) ? M_RFWD : 116 | D_rs; 117 | // W has been forwarded inside 118 | 119 | wire [31:0] FWD_D_RT = (D_rt_addr == 0) ? 0 : 120 | (D_rt_addr == E_RFDst) ? E_RFWD : 121 | (D_rt_addr == M_RFDst) ? M_RFWD : 122 | D_rt; 123 | // W has been forwarded inside 124 | 125 | D_CMP D_cmp ( 126 | .rs(FWD_D_RS), 127 | .rt(FWD_D_RT), 128 | .type(D_B_type), 129 | .b_jump(D_b_jump) 130 | ); 131 | 132 | D_NPC D_npc ( 133 | .D_pc(D_pc), 134 | .F_pc(F_pc), 135 | .imm26(D_addr), 136 | .rs(FWD_D_RS), 137 | .Br(D_Br), 138 | .b_jump(D_b_jump), 139 | .npc(npc) 140 | ); 141 | 142 | /// StageE 143 | wire [31:0] E_pc, E_EXTout, E_rs, E_rt; 144 | E_REG E_reg ( 145 | .clk(clk), 146 | .reset(reset || E_reg_reset), 147 | .WE(E_reg_en), 148 | 149 | .instr_in(D_instr), 150 | .pc_in(D_pc), 151 | .EXT_in(D_EXTout), 152 | .rs_in(FWD_D_RS), 153 | .rt_in(FWD_D_RT), 154 | .instr_out(E_instr), 155 | 156 | .pc_out(E_pc), 157 | .EXT_out(E_EXTout), 158 | .rs_out(E_rs), 159 | .rt_out(E_rt) 160 | ); 161 | 162 | 163 | wire [3:0] E_ALUControl, E_HILOType; 164 | wire [1:0] E_ALUASrc; 165 | wire [2:0] E_ALUBSrc; 166 | wire [4:0] E_rs_addr, E_rt_addr; 167 | 168 | _CU E_cu ( 169 | .instr(E_instr), 170 | .rs_addr(E_rs_addr), 171 | .rt_addr(E_rt_addr), 172 | .ALUControl(E_ALUControl), 173 | .ALUASrc(E_ALUASrc), 174 | .ALUBSrc(E_ALUBSrc), 175 | .RFDst(E_RFDst), 176 | .RFWDSrc(E_RFWDSrc), 177 | .HILO_type(E_HILOType) 178 | ); 179 | 180 | wire [31:0] E_ALUA, E_ALUB, E_ALUout; 181 | 182 | // FORWARD 183 | wire [31:0] FWD_E_RS = (E_rs_addr == 0) ? 0 : 184 | (E_rs_addr == M_RFDst) ? M_RFWD : 185 | (E_rs_addr == W_RFDst) ? W_RFWD : 186 | E_rs; 187 | 188 | wire [31:0] FWD_E_RT = (E_rt_addr == 0) ? 0 : 189 | (E_rt_addr == M_RFDst) ? M_RFWD : 190 | (E_rt_addr == W_RFDst) ? W_RFWD : 191 | E_rt; 192 | 193 | assign E_ALUA = (E_ALUASrc == `ALUASrcRT) ? FWD_E_RT : 194 | (E_ALUASrc == `ALUASrcRS) ? FWD_E_RS : 195 | 0; 196 | 197 | assign E_ALUB = (E_ALUBSrc == `ALUBSrcShamt) ? {27'b0, E_instr[10:6]} : 198 | (E_ALUBSrc == `ALUBSrcRS_4_0) ? {27'b0, FWD_E_RS[4:0]} : 199 | (E_ALUBSrc == `ALUBSrcRT) ? FWD_E_RT : 200 | (E_ALUBSrc == `ALUBSrcExt) ? E_EXTout : 201 | 0; 202 | 203 | E_ALU E_alu ( 204 | .ALUControl(E_ALUControl), 205 | .A(E_ALUA), 206 | .B(E_ALUB), 207 | .ALUout(E_ALUout) 208 | ); 209 | 210 | wire [31:0] E_HILOout; 211 | 212 | E_HILO E_hilo ( 213 | .clk(clk), 214 | .reset(reset), 215 | .rs(FWD_E_RS), 216 | .rt(FWD_E_RT), 217 | .HILOtype(E_HILOType), 218 | .HILObusy(E_HILObusy), 219 | .HILOout(E_HILOout) 220 | ); 221 | 222 | /// StageM 223 | wire [31:0] M_pc, M_ALUout, M_rt, M_HILOout, M_EXTout; 224 | M_REG M_reg( 225 | .clk(clk), 226 | .reset(reset || M_reg_reset), 227 | .WE(M_reg_en), 228 | 229 | .instr_in(E_instr), 230 | .pc_in(E_pc), 231 | .ALU_in(E_ALUout), 232 | .HILO_in(E_HILOout), 233 | .rt_in(FWD_E_RT), 234 | .EXT_in(E_EXTout), 235 | 236 | .instr_out(M_instr), 237 | .pc_out(M_pc), 238 | .ALU_out(M_ALUout), 239 | .HILO_out(M_HILOout), 240 | .rt_out(M_rt), 241 | .EXT_out(M_EXTout) 242 | ); 243 | 244 | wire [4:0] M_rt_addr; 245 | wire [2:0] M_DMType; 246 | wire M_WE; 247 | 248 | _CU M_cu ( 249 | .instr(M_instr), 250 | .rt_addr(M_rt_addr), 251 | .DMType(M_DMType), 252 | .DMWr(M_WE), 253 | .RFDst(M_RFDst), 254 | .RFWDSrc(M_RFWDSrc) 255 | ); 256 | 257 | // FORWARD 258 | wire [31:0] M_DMout; 259 | 260 | wire [31:0] FWD_M_RT = (M_rt_addr == 0) ? 0 : 261 | (M_rt_addr == W_RFDst) ? W_RFWD : 262 | M_rt; 263 | 264 | M_DM M_dm ( 265 | .pc(M_pc), 266 | .clk(clk), 267 | .reset(reset), 268 | .WE(M_WE), 269 | .DMType(M_DMType), 270 | .addr(M_ALUout), 271 | .WD(FWD_M_RT), 272 | .DMout(M_DMout) 273 | ); 274 | 275 | /// StageW 276 | wire [31:0] W_ALUout, W_DMout, W_HILOout, W_EXTout; 277 | W_REG W_reg( 278 | .clk(clk), 279 | .reset(reset || W_reg_reset), 280 | .WE(W_reg_en), 281 | 282 | .instr_in(M_instr), 283 | .pc_in(M_pc), 284 | .ALU_in(M_ALUout), 285 | .DM_in(M_DMout), 286 | .HILO_in(M_HILOout), 287 | .EXT_in(M_EXTout), 288 | 289 | .instr_out(W_instr), 290 | .pc_out(W_pc), 291 | .ALU_out(W_ALUout), 292 | .DM_out(W_DMout), 293 | .HILO_out(W_HILOout), 294 | .EXT_out(W_EXTout) 295 | ); 296 | 297 | _CU W_cu( 298 | .instr(W_instr), 299 | .RFDst(W_RFDst), 300 | .RFWr(W_RFWE), 301 | .RFWDSrc(W_RFWDSrc) 302 | ); 303 | 304 | /// Write Back To D_GRF 305 | 306 | endmodule -------------------------------------------------------------------------------- /p6/D_CMP.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | `include "const.v" 3 | 4 | module D_CMP ( 5 | input [31:0] rs, 6 | input [31:0] rt, 7 | input [2:0] type, 8 | output b_jump 9 | ); 10 | wire equal = (rs == rt); 11 | wire eq0 = !(|rs); 12 | wire gt0 = (!rs[31]) && !eq0; 13 | wire le0 = (rs[31]) && !eq0; 14 | 15 | assign b_jump = (type == `B_beq && equal) || 16 | (type == `B_bne && !equal) || 17 | (type == `B_blez && (le0 || eq0)) || 18 | (type == `B_bgez && (gt0 || eq0)) || 19 | (type == `B_bgtz && gt0) || 20 | (type == `B_bltz && le0); 21 | 22 | endmodule -------------------------------------------------------------------------------- /p6/D_EXT.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | `include "const.v" 3 | 4 | module D_EXT ( 5 | input [15:0] imm, 6 | input [2:0] EXTOp, 7 | output [31:0] EXTout 8 | ); 9 | 10 | assign EXTout = (EXTOp == `EXT_signed) ? {{16{imm[15]}}, imm} : 11 | (EXTOp == `EXT_lui) ? {imm, 16'b0} : 12 | {{16{1'b0}}, imm}; 13 | 14 | endmodule -------------------------------------------------------------------------------- /p6/D_GRF.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | `include "const.v" 3 | 4 | module D_GRF ( 5 | input [31:0] WPC, // for debugging 6 | input clk, 7 | input reset, 8 | input WE, 9 | input [4:0] A1, 10 | input [4:0] A2, 11 | input [4:0] A3, 12 | input [31:0] WD, 13 | output [31:0] RD1, 14 | output [31:0] RD2 15 | ); 16 | 17 | reg [31:0] grf [31:0]; 18 | 19 | assign RD1 = (A3 == A1 && A3 && WE) ? WD : grf[A1]; // 内部转发 20 | assign RD2 = (A3 == A2 && A3 && WE) ? WD : grf[A2]; 21 | 22 | integer i; 23 | 24 | initial begin 25 | for (i=0; i<32; i=i+1) grf[i] <= 0; 26 | end 27 | 28 | always @(posedge clk) begin 29 | if (reset) begin 30 | for (i=0; i<32; i=i+1) grf[i] <= 0; 31 | end 32 | else if (WE && A3) begin 33 | grf[A3] <= WD; 34 | $display("%d@%h: $%d <= %h", $time, WPC, A3, WD); 35 | end 36 | end 37 | 38 | endmodule -------------------------------------------------------------------------------- /p6/D_NPC.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | `include "const.v" 3 | 4 | module D_NPC ( 5 | input [31:0] D_pc, 6 | input [31:0] F_pc, 7 | input [25:0] imm26, 8 | input [31:0] rs, 9 | input [2:0] Br, 10 | input b_jump, 11 | output [31:0] npc 12 | ); 13 | assign npc = (Br == `BR_pc4) ? F_pc + 4 : 14 | (Br == `BR_addr) ? {D_pc[31:28], imm26, 2'b0} : 15 | (Br == `BR_reg) ? rs : 16 | (Br == `BR_branch && b_jump) ? D_pc + 4 + {{14{imm26[15]}}, imm26[15:0], 2'b0} : 17 | F_pc + 4; 18 | endmodule -------------------------------------------------------------------------------- /p6/D_REG.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | `include "const.v" 3 | 4 | module D_REG ( 5 | input clk, 6 | input reset, 7 | input WE, 8 | input [31:0] instr_in, 9 | input [31:0] pc_in, 10 | output reg [31:0] instr_out, 11 | output reg [31:0] pc_out 12 | ); 13 | 14 | always @(posedge clk) begin 15 | if (reset) begin 16 | instr_out <= 0; 17 | pc_out <= 0; 18 | end else if(WE) begin 19 | instr_out <= instr_in; 20 | pc_out <= pc_in; 21 | end 22 | end 23 | 24 | endmodule -------------------------------------------------------------------------------- /p6/E_ALU.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | `include "const.v" 3 | 4 | module E_ALU ( 5 | input [3:0] ALUControl, 6 | input [31:0] A, 7 | input [31:0] B, 8 | output [31:0] ALUout 9 | ); 10 | 11 | wire [31:0] res_sra = $signed($signed(A) >>> B); 12 | wire [31:0] res_slt = $signed(A) < $signed(B) ? 32'b1 : 32'b0; 13 | 14 | assign ALUout = (ALUControl == `ALU_add ) ? A + B : 15 | (ALUControl == `ALU_sub ) ? A - B : 16 | (ALUControl == `ALU_and ) ? A & B : 17 | (ALUControl == `ALU_or ) ? A | B : 18 | (ALUControl == `ALU_xor ) ? A ^ B : 19 | (ALUControl == `ALU_nor ) ? ~(A | B) : 20 | (ALUControl == `ALU_sll ) ? A << B : 21 | (ALUControl == `ALU_srl ) ? A >> B : 22 | (ALUControl == `ALU_sra ) ? res_sra : 23 | (ALUControl == `ALU_slt ) ? res_slt : 24 | (ALUControl == `ALU_sltu) ? A < B : 25 | 0; 26 | 27 | endmodule -------------------------------------------------------------------------------- /p6/E_HILO.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | `include "const.v" 3 | 4 | module E_HILO ( 5 | input clk, 6 | input reset, 7 | input [31:0] rs, 8 | input [31:0] rt, 9 | input [3:0] HILOtype, 10 | output HILObusy, 11 | output [31:0] HILOout 12 | ); 13 | 14 | integer state = 0; 15 | reg [31:0] hi, lo, temp_hi, temp_lo; 16 | wire mult = (HILOtype == `HILO_mult), 17 | multu = (HILOtype == `HILO_multu), 18 | div = (HILOtype == `HILO_div), 19 | divu = (HILOtype == `HILO_divu), 20 | mflo = (HILOtype == `HILO_mflo), 21 | mfhi = (HILOtype == `HILO_mfhi), 22 | mtlo = (HILOtype == `HILO_mtlo), 23 | mthi = (HILOtype == `HILO_mthi); 24 | 25 | wire start = mult | multu | div | divu; 26 | reg busy; 27 | 28 | assign HILObusy = start | busy; 29 | assign HILOout = mflo ? lo: 30 | mfhi ? hi: 31 | 0; 32 | 33 | initial begin 34 | state <= 0; 35 | busy <= 0; 36 | hi <= 0; 37 | lo <= 0; 38 | end 39 | 40 | always @(posedge clk) begin 41 | if (reset) begin 42 | state <= 0; 43 | busy <= 0; 44 | hi <= 0; 45 | lo <= 0; 46 | end else begin 47 | if (state == 0) begin 48 | if (mtlo) lo <= rs; 49 | else if (mthi) hi <= rs; 50 | else if (mult) begin 51 | busy <= 1; 52 | state <= 5; 53 | {temp_hi, temp_lo} <= $signed(rs) * $signed(rt); 54 | end else if (multu) begin 55 | busy <= 1; 56 | state <= 5; 57 | {temp_hi, temp_lo} <= rs * rt; 58 | end else if (div) begin 59 | busy <= 1; 60 | state <= 10; 61 | temp_lo <= $signed(rs) / $signed(rt); 62 | temp_hi <= $signed(rs) % $signed(rt); 63 | end else if (divu) begin 64 | busy <= 1; 65 | state <= 10; 66 | temp_lo <= rs / rt; 67 | temp_hi <= rs % rt; 68 | end 69 | end else if (state == 1) begin 70 | state <= 0; 71 | busy <= 0; 72 | hi <= temp_hi; 73 | lo <= temp_lo; 74 | end else begin 75 | state <= state - 1; 76 | end 77 | end 78 | end 79 | 80 | endmodule 81 | -------------------------------------------------------------------------------- /p6/E_REG.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | `include "const.v" 3 | 4 | module E_REG ( 5 | input clk, 6 | input reset, 7 | input WE, 8 | input [31:0] instr_in, 9 | input [31:0] pc_in, 10 | input [31:0] EXT_in, 11 | input [31:0] rs_in, 12 | input [31:0] rt_in, 13 | output reg [31:0] instr_out, 14 | output reg [31:0] pc_out, 15 | output reg [31:0] EXT_out, 16 | output reg [31:0] rs_out, 17 | output reg [31:0] rt_out 18 | ); 19 | 20 | always @(posedge clk) begin 21 | if (reset) begin 22 | instr_out <= 0; 23 | pc_out <= 0; 24 | EXT_out <= 0; 25 | rs_out <= 0; 26 | rt_out <= 0; 27 | end else if(WE) begin 28 | instr_out <= instr_in; 29 | pc_out <= pc_in; 30 | EXT_out <= EXT_in; 31 | rs_out <= rs_in; 32 | rt_out <= rt_in; 33 | end 34 | end 35 | 36 | endmodule -------------------------------------------------------------------------------- /p6/F_IFU.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | `include "const.v" 3 | `define N 4096 4 | 5 | module F_IFU ( 6 | input clk, 7 | input reset, 8 | input WE, 9 | input [31:0] npc, 10 | output [31:0] instr, 11 | output reg [31:0] pc 12 | ); 13 | 14 | reg [31:0] im [0:`N-1]; 15 | 16 | assign instr = im[pc[15:2] - 13'HC00]; 17 | 18 | initial begin 19 | pc <= 32'h0000_3000; 20 | $readmemh("code.txt", im); 21 | end 22 | 23 | always @(posedge clk) begin 24 | if (reset) pc <= 32'h0000_3000; 25 | else if(WE) pc <= npc; 26 | 27 | end 28 | 29 | _DASM Dasm( 30 | .pc(pc), 31 | .instr(instr), 32 | .imm_as_dec(1'b1), 33 | .reg_name(1'b0), 34 | .asm() 35 | ); 36 | endmodule -------------------------------------------------------------------------------- /p6/M_DM.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | `include "const.v" 3 | `define HIGH_BYTE 15 4 | `define DM_SIZE (1<<`HIGH_BYTE) 5 | 6 | `define word memory[addr[`HIGH_BYTE:2]] 7 | 8 | `define half `word[15 + 16 * addr[1] -:16] 9 | `define half_sign `word[15 + 16 * addr[1] -:1] 10 | `define byte `word[7 + 8 * addr[1:0] -:8] 11 | `define byte_sign `word[7 + 8 * addr[1:0] -:1] 12 | 13 | module M_DM ( 14 | input [31:0] pc, // for debugging 15 | input clk, 16 | input reset, 17 | input WE, 18 | input [2:0] DMType, 19 | input [31:0] addr, 20 | input [31:0] WD, 21 | output [31:0] DMout 22 | ); 23 | reg [31:0] memory [`DM_SIZE - 1:0]; 24 | 25 | assign DMout = (DMType == `DM_w) ? `word : 26 | (DMType == `DM_h) ? {{16{`half_sign}}, `half} : 27 | (DMType == `DM_hu) ? {{16{1'b0}}, `half} : 28 | (DMType == `DM_b) ? {{24{`byte_sign}}, `byte} : 29 | (DMType == `DM_bu) ? {{24{1'b0}}, `byte} : 30 | 32'b0; 31 | 32 | integer i; 33 | 34 | initial begin 35 | for (i=0; i<`DM_SIZE; i=i+1) memory[i] <= 0; 36 | end 37 | 38 | function [31:0] F_H_OUT; 39 | input [31:0] WD; 40 | input [31:0] word; 41 | begin 42 | F_H_OUT = word; 43 | F_H_OUT[15 + 16 * addr[1] -:16] = WD[15:0]; 44 | end 45 | endfunction 46 | 47 | function [31:0] F_B_OUT; 48 | input [31:0] WD; 49 | input [31:0] word; 50 | begin 51 | F_B_OUT = word; 52 | F_B_OUT[7 + 8 * addr[1:0] -:8] = WD[7:0]; 53 | end 54 | endfunction 55 | 56 | always @(posedge clk) begin 57 | if (reset) begin 58 | for (i=0; i<`DM_SIZE; i=i+1) memory[i] <= 0; 59 | end 60 | else if (WE) begin 61 | if (DMType == `DM_w) begin 62 | `word <= WD; 63 | $display("%d@%h: *%h <= %h", $time, pc, addr&(`DM_SIZE-1), WD); 64 | end else if (DMType == `DM_h) begin 65 | `half <= WD[15:0]; 66 | $display("%d@%h: *%h <= %h", $time, pc, {addr[31:2], 2'b00}&(`DM_SIZE-1), F_H_OUT(WD, memory[addr[`HIGH_BYTE:2]])); 67 | end else if (DMType == `DM_b) begin 68 | `byte <= WD[7:0]; 69 | $display("%d@%h: *%h <= %h", $time, pc, {addr[31:2], 2'b00}&(`DM_SIZE-1), F_B_OUT(WD, memory[addr[`HIGH_BYTE:2]])); 70 | end 71 | end 72 | end 73 | 74 | endmodule -------------------------------------------------------------------------------- /p6/M_REG.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | `include "const.v" 3 | 4 | module M_REG ( 5 | input clk, 6 | input reset, 7 | input WE, 8 | input [31:0] instr_in, 9 | input [31:0] pc_in, 10 | input [31:0] ALU_in, 11 | input [31:0] rt_in, 12 | input [31:0] HILO_in, 13 | input [31:0] EXT_in, 14 | output reg [31:0] instr_out, 15 | output reg [31:0] pc_out, 16 | output reg [31:0] ALU_out, 17 | output reg [31:0] rt_out, 18 | output reg [31:0] HILO_out, 19 | output reg [31:0] EXT_out 20 | ); 21 | 22 | always @(posedge clk) begin 23 | if (reset) begin 24 | instr_out <= 0; 25 | pc_out <= 0; 26 | ALU_out <= 0; 27 | rt_out <= 0; 28 | HILO_out <= 0; 29 | EXT_out <= 0; 30 | end else if(WE) begin 31 | instr_out <= instr_in; 32 | pc_out <= pc_in; 33 | ALU_out <= ALU_in; 34 | rt_out <= rt_in; 35 | HILO_out <= HILO_in; 36 | EXT_out <= EXT_in; 37 | end 38 | end 39 | 40 | endmodule -------------------------------------------------------------------------------- /p6/W_REG.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | `include "const.v" 3 | 4 | module W_REG ( 5 | input clk, 6 | input reset, 7 | input WE, 8 | input [31:0] instr_in, 9 | input [31:0] pc_in, 10 | input [31:0] ALU_in, 11 | input [31:0] DM_in, 12 | input [31:0] HILO_in, 13 | input [31:0] EXT_in, 14 | output reg [31:0] instr_out, 15 | output reg [31:0] pc_out, 16 | output reg [31:0] ALU_out, 17 | output reg [31:0] DM_out, 18 | output reg [31:0] HILO_out, 19 | output reg [31:0] EXT_out 20 | ); 21 | 22 | always @(posedge clk) begin 23 | if (reset) begin 24 | instr_out <= 0; 25 | pc_out <= 0; 26 | ALU_out <= 0; 27 | DM_out <= 0; 28 | HILO_out <= 0; 29 | EXT_out <= 0; 30 | end else if(WE) begin 31 | instr_out <= instr_in; 32 | pc_out <= pc_in; 33 | ALU_out <= ALU_in; 34 | DM_out <= DM_in; 35 | HILO_out <= HILO_in; 36 | EXT_out <= EXT_in; 37 | end 38 | end 39 | 40 | endmodule -------------------------------------------------------------------------------- /p6/_CU.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | `include "const.v" 3 | 4 | module _CU ( 5 | input [31:0] instr, 6 | // decode 7 | output [4:0] rs_addr, 8 | output [4:0] rt_addr, 9 | output [4:0] rd_addr, 10 | output [15:0] imm, 11 | output [25:0] addr, 12 | // classify 13 | output load, 14 | output store, 15 | output calc_r, 16 | output calc_i, 17 | output lui, 18 | output shiftS, 19 | output shiftV, 20 | output branch, 21 | output j_r, 22 | output j_addr, 23 | output j_l, 24 | output md, 25 | output mt, 26 | output mf, 27 | // signals 28 | output [2:0] Br, 29 | output [2:0] B_type, 30 | output [2:0] EXTOp, 31 | 32 | output [3:0] ALUControl, 33 | output [1:0] ALUASrc, 34 | output [2:0] ALUBSrc, 35 | output [3:0] HILO_type, 36 | 37 | output [2:0] DMType, 38 | output DMWr, 39 | 40 | output [4:0] RFDst, 41 | output RFWr, 42 | output [2:0] RFWDSrc 43 | ); 44 | 45 | wire [5:0] opcode = instr[31:26], 46 | func = instr[5:0]; 47 | assign rs_addr = instr[25:21], 48 | rt_addr = instr[20:16], 49 | rd_addr = instr[15:11]; 50 | assign imm = instr[15:0]; 51 | assign addr = instr[25:0]; 52 | 53 | wire lb = (opcode == `OP_lb ); 54 | wire lbu = (opcode == `OP_lbu ); 55 | wire lh = (opcode == `OP_lh ); 56 | wire lhu = (opcode == `OP_lhu ); 57 | wire lw = (opcode == `OP_lw ); 58 | wire sb = (opcode == `OP_sb ); 59 | wire sh = (opcode == `OP_sh ); 60 | wire sw = (opcode == `OP_sw ); 61 | wire addi = (opcode == `OP_addi ); 62 | wire addiu = (opcode == `OP_addiu); 63 | wire andi = (opcode == `OP_andi ); 64 | wire beq = (opcode == `OP_beq ); 65 | wire bgtz = (opcode == `OP_bgtz ); 66 | wire blez = (opcode == `OP_blez ); 67 | wire bgez = (opcode == `OP_bgez && rt_addr == `RT_bgez); 68 | wire bltz = (opcode == `OP_bltz && rt_addr == `RT_bltz); 69 | wire bne = (opcode == `OP_bne ); 70 | wire j = (opcode == `OP_j ); 71 | wire jal = (opcode == `OP_jal ); 72 | wire ori = (opcode == `OP_ori ); 73 | wire slti = (opcode == `OP_slti ); 74 | wire sltiu = (opcode == `OP_sltiu); 75 | wire xori = (opcode == `OP_xori ); 76 | assign lui = (opcode == `OP_lui ); 77 | 78 | wire add = (opcode == `OP_rtype && func == `FUNC_add ); 79 | wire addu = (opcode == `OP_rtype && func == `FUNC_addu ); 80 | wire And = (opcode == `OP_rtype && func == `FUNC_and ); 81 | wire div = (opcode == `OP_rtype && func == `FUNC_div ); 82 | wire divu = (opcode == `OP_rtype && func == `FUNC_divu ); 83 | wire jalr = (opcode == `OP_rtype && func == `FUNC_jalr ); 84 | wire jr = (opcode == `OP_rtype && func == `FUNC_jr ); 85 | wire mfhi = (opcode == `OP_rtype && func == `FUNC_mfhi ); 86 | wire mflo = (opcode == `OP_rtype && func == `FUNC_mflo ); 87 | wire mthi = (opcode == `OP_rtype && func == `FUNC_mthi ); 88 | wire mtlo = (opcode == `OP_rtype && func == `FUNC_mtlo ); 89 | wire mult = (opcode == `OP_rtype && func == `FUNC_mult ); 90 | wire multu = (opcode == `OP_rtype && func == `FUNC_multu); 91 | wire Nor = (opcode == `OP_rtype && func == `FUNC_nor ); 92 | wire Or = (opcode == `OP_rtype && func == `FUNC_or ); 93 | wire sll = (opcode == `OP_rtype && func == `FUNC_sll && (|rd_addr)); 94 | wire sllv = (opcode == `OP_rtype && func == `FUNC_sllv ); 95 | wire slt = (opcode == `OP_rtype && func == `FUNC_slt ); 96 | wire sltu = (opcode == `OP_rtype && func == `FUNC_sltu ); 97 | wire sra = (opcode == `OP_rtype && func == `FUNC_sra ); 98 | wire srav = (opcode == `OP_rtype && func == `FUNC_srav ); 99 | wire srl = (opcode == `OP_rtype && func == `FUNC_srl ); 100 | wire srlv = (opcode == `OP_rtype && func == `FUNC_srlv ); 101 | wire sub = (opcode == `OP_rtype && func == `FUNC_sub ); 102 | wire subu = (opcode == `OP_rtype && func == `FUNC_subu ); 103 | wire Xor = (opcode == `OP_rtype && func == `FUNC_xor ); 104 | 105 | assign load = lw | lh | lhu | lbu | lb; 106 | assign store = sw | sh | sb; 107 | assign branch = beq | bne | blez | bgtz | bgez | bltz; 108 | 109 | assign calc_r = add | addu | sub | subu | slt | sltu | 110 | sll | sllv | srl | srlv | sra | srav | 111 | And | Or | Xor | Nor; // exclude jr & jalr & mt/mf/md 112 | assign calc_i = addi | addiu | andi | ori | xori | 113 | slti | sltiu; // exclude lui 114 | 115 | assign md = mult | multu | div | divu; 116 | assign mt = mtlo | mthi; 117 | assign mf = mflo | mfhi; 118 | 119 | assign shiftS = sll | srl | sra; 120 | assign shiftV = sllv | srlv | srav; 121 | 122 | assign j_r = jr | jalr; 123 | assign j_addr = j | jal; 124 | assign j_l = jal | jalr; 125 | 126 | 127 | ////////////StageD 128 | assign EXTOp = (addi | addiu | slti | sltiu | load | store) ? `EXT_signed : 129 | lui ? `EXT_lui : 130 | `EXT_unsigned; 131 | // wire unsigned_ext = andi | ori | xori; 132 | assign Br = branch ? `BR_branch : 133 | j_addr ? `BR_addr : 134 | j_r ? `BR_reg : 135 | `BR_pc4; 136 | assign B_type = beq ? `B_beq : 137 | bne ? `B_bne : 138 | blez ? `B_blez : 139 | bgez ? `B_bgez : 140 | bgtz ? `B_bgtz : 141 | bltz ? `B_bltz : 142 | `B_beq; 143 | 144 | ////////////StageE 145 | assign ALUControl = (sub | subu) ? `ALU_sub : 146 | (And | andi) ? `ALU_and : 147 | (Or | ori) ? `ALU_or : 148 | (Xor | xori) ? `ALU_xor : 149 | (Nor) ? `ALU_nor : 150 | (sll | sllv) ? `ALU_sll : 151 | (srl | srlv) ? `ALU_srl : 152 | (sra | srav) ? `ALU_sra : 153 | (slt | slti) ? `ALU_slt : 154 | (sltu | sltiu) ? `ALU_sltu : 155 | `ALU_add; 156 | assign ALUASrc = (shiftS | shiftV) ? `ALUASrcRT : `ALUASrcRS; 157 | assign ALUBSrc = shiftS ? `ALUBSrcShamt : 158 | shiftV ? `ALUBSrcRS_4_0 : 159 | (calc_r && !shiftS && !shiftV) ? `ALUBSrcRT : 160 | (calc_i | lui | load | store) ? `ALUBSrcExt : 161 | `ALUBSrcRT; 162 | assign HILO_type = mult ? `HILO_mult : 163 | multu ? `HILO_multu : 164 | div ? `HILO_div : 165 | divu ? `HILO_divu : 166 | mflo ? `HILO_mflo : 167 | mfhi ? `HILO_mfhi : 168 | mtlo ? `HILO_mtlo : 169 | mthi ? `HILO_mthi : 170 | `HILO_none; 171 | 172 | ////////////StageM 173 | assign DMType = (lw || sw) ? `DM_w : 174 | (lh || sh) ? `DM_h : 175 | (lhu) ? `DM_hu : 176 | (lb || sb) ? `DM_b : 177 | (lbu) ? `DM_bu : 178 | `DM_w; 179 | assign DMWr = store; 180 | 181 | ////////////StageW 182 | assign RFDst = (calc_r | jalr | mf) ? rd_addr : 183 | (calc_i | lui | load) ? rt_addr : 184 | (jal) ? 5'd31 : 185 | 5'd0; 186 | assign RFWr = !(!RFDst); 187 | assign RFWDSrc = load ? `RFWD_DMout : 188 | (jal | jalr) ? `RFWD_PC8 : 189 | lui ? `RFWD_EXTout : 190 | mf ? `RFWD_HILOout : 191 | `RFWD_ALUout; 192 | endmodule -------------------------------------------------------------------------------- /p6/_DASM.v: -------------------------------------------------------------------------------- 1 | `define lb 6'b100000 2 | `define lbu 6'b100100 3 | `define lh 6'b100001 4 | `define lhu 6'b100101 5 | `define lw 6'b100011 6 | `define sb 6'b101000 7 | `define sh 6'b101001 8 | `define sw 6'b101011 9 | `define addop 6'b000000 10 | `define addfu 6'b100000 11 | `define addi 6'b001000 12 | `define addiu 6'b001001 13 | `define adduop 6'b000000 14 | `define addufu 6'b100001 15 | `define andop 6'b000000 16 | `define andfu 6'b100100 17 | `define andi 6'b001100 18 | `define beq 6'b000100 19 | `define bgezop 6'b000001 20 | `define bgezrt 5'b00001 21 | `define bgtz 6'b000111 22 | `define blez 6'b000110 23 | `define bltzop 6'b000001 24 | `define bltzrt 5'b00000 25 | `define bne 6'b000101 26 | `define divop 6'b000000 27 | `define divfu 6'b011010 28 | `define divuop 6'b000000 29 | `define divufu 6'b011011 30 | `define j 6'b000010 31 | `define jal 6'b000011 32 | `define jalrop 6'b000000 33 | `define jalrfu 6'b001001 34 | `define jrop 6'b000000 35 | `define jrfu 6'b001000 36 | `define Lui 6'b001111 37 | `define mfhiop 6'b000000 38 | `define mfhifu 6'b010000 39 | `define mfloop 6'b000000 40 | `define mflofu 6'b010010 41 | `define mthiop 6'b000000 42 | `define mthifu 6'b010001 43 | `define mtloop 6'b000000 44 | `define mtlofu 6'b010011 45 | `define multop 6'b000000 46 | `define multfu 6'b011000 47 | `define multuop 6'b000000 48 | `define multufu 6'b011001 49 | `define norop 6'b000000 50 | `define norfu 6'b100111 51 | `define orop 6'b000000 52 | `define orfu 6'b100101 53 | `define ori 6'b001101 54 | `define sllop 6'b000000 55 | `define sllfu 6'b000000 56 | `define sllvop 6'b000000 57 | `define sllvfu 6'b000100 58 | `define sltop 6'b000000 59 | `define sltfu 6'b101010 60 | `define slti 6'b001010 61 | `define sltiu 6'b001011 62 | `define sltuop 6'b000000 63 | `define sltufu 6'b101011 64 | `define sraop 6'b000000 65 | `define srafu 6'b000011 66 | `define sravop 6'b000000 67 | `define sravfu 6'b000111 68 | `define srlop 6'b000000 69 | `define srlfu 6'b000010 70 | `define srlvop 6'b000000 71 | `define srlvfu 6'b000110 72 | `define subop 6'b000000 73 | `define subfu 6'b100010 74 | `define subuop 6'b000000 75 | `define subufu 6'b100011 76 | `define sw 6'b101011 77 | `define xorop 6'b000000 78 | `define xorfu 6'b100110 79 | `define xori 6'b001110 80 | 81 | module _DASM ( 82 | input [31:0] pc, 83 | input [31:0] instr, 84 | input reg_name, 85 | input imm_as_dec, 86 | output [32*8-1:0] asm 87 | ); 88 | 89 | wire [5:0]func=instr[5:0], op=instr[31:26]; 90 | wire [4:0]rs=instr[25:21], rt=instr[20:16], rd=instr[15:11], sha=instr[10:6]; 91 | wire [15:0] imm=instr[15:0]; 92 | wire [25:0] target=instr[25:0]; 93 | 94 | wire beq=(op==`beq); 95 | wire bgez=(op==`bgezop)&(rt==`bgezrt); 96 | wire bgtz=(op==`bgtz); 97 | wire blez=(op==`blez); 98 | wire bltz=(op==`bltzop)&(rt==`bltzrt); 99 | wire bne=(op==`bne); 100 | 101 | wire j=(op==`j); 102 | wire jal=(op==`jal); 103 | wire jalr=(op==`jalrop)&(func==`jalrfu); 104 | wire jr=(op==`jrop)&(func==`jrfu); 105 | 106 | wire lb=(op==`lb); 107 | wire lbu=(op==`lbu); 108 | wire lh=(op==`lh); 109 | wire lhu=(op==`lhu); 110 | wire lw=(op==`lw); 111 | wire sb=(op==`sb); 112 | wire sh=(op==`sh); 113 | wire sw=(op==`sw); 114 | 115 | wire lui=(op==`Lui); 116 | 117 | wire add=(op==`addop)&(func==`addfu); 118 | wire addi=(op==`addi); 119 | wire addiu=(op==`addiu); 120 | wire addu=(op==`adduop)&(func==`addufu); 121 | wire And=(op==`andop)&(func==`andfu); 122 | wire andi=(op==`andi); 123 | wire div=(op==`divop)&(func==`divfu); 124 | wire divu=(op==`divuop)&(func==`divufu); 125 | wire mfhi=(op==`mfhiop)&(func==`mfhifu); 126 | wire mflo=(op==`mfloop)&(func==`mflofu); 127 | wire mthi=(op==`mthiop)&(func==`mthifu); 128 | wire mtlo=(op==`mtloop)&(func==`mtlofu); 129 | wire mult=(op==`multop)&(func==`multfu); 130 | wire multu=(op==`multuop)&(func==`multufu); 131 | wire Nor=(op==`norop)&(func==`norfu); 132 | wire Or=(op==`orop)&(func==`orfu); 133 | wire ori=(op==`ori); 134 | wire sll=(op==6'b000000)&(func==6'b000000)&(|rd); 135 | wire sllv=(op==`sllvop)&(func==`sllvfu); 136 | wire slt=(op==`sltop)&(func==`sltfu); 137 | wire slti=(op==`slti); 138 | wire sltiu=(op==`sltiu); 139 | wire sltu=(op==`sltuop)&(func==`sltufu); 140 | wire sra=(op==`sraop)&(func==`srafu); 141 | wire srav=(op==`sravop)&(func==`sravfu); 142 | wire srl=(op==`srlop)&(func==`srlfu); 143 | wire srlv=(op==`srlvop)&(func==`srlvfu); 144 | wire sub=(op==`subop)&(func==`subfu); 145 | wire subu=(op==`subuop)&(func==`subufu); 146 | wire Xor=(op==`xorop)&(func==`xorfu); 147 | wire xori=(op==`xori); 148 | 149 | function [8*3-1:0] get_reg; 150 | input [4:0] num; 151 | begin 152 | case (num) 153 | 5'b00000: get_reg = reg_name ? "$00" : "$00"; 154 | 5'b00001: get_reg = reg_name ? "$at" : "$01"; 155 | 5'b00010: get_reg = reg_name ? "$v0" : "$02"; 156 | 5'b00011: get_reg = reg_name ? "$v1" : "$03"; 157 | 5'b00100: get_reg = reg_name ? "$a0" : "$04"; 158 | 5'b00101: get_reg = reg_name ? "$a1" : "$05"; 159 | 5'b00110: get_reg = reg_name ? "$a2" : "$06"; 160 | 5'b00111: get_reg = reg_name ? "$a3" : "$07"; 161 | 5'b01000: get_reg = reg_name ? "$t0" : "$08"; 162 | 5'b01001: get_reg = reg_name ? "$t1" : "$09"; 163 | 5'b01010: get_reg = reg_name ? "$t2" : "$10"; 164 | 5'b01011: get_reg = reg_name ? "$t3" : "$11"; 165 | 5'b01100: get_reg = reg_name ? "$t4" : "$12"; 166 | 5'b01101: get_reg = reg_name ? "$t5" : "$13"; 167 | 5'b01110: get_reg = reg_name ? "$t6" : "$14"; 168 | 5'b01111: get_reg = reg_name ? "$t7" : "$15"; 169 | 5'b10000: get_reg = reg_name ? "$s0" : "$16"; 170 | 5'b10001: get_reg = reg_name ? "$s1" : "$17"; 171 | 5'b10010: get_reg = reg_name ? "$s2" : "$18"; 172 | 5'b10011: get_reg = reg_name ? "$s3" : "$19"; 173 | 5'b10100: get_reg = reg_name ? "$s4" : "$20"; 174 | 5'b10101: get_reg = reg_name ? "$s5" : "$21"; 175 | 5'b10110: get_reg = reg_name ? "$s6" : "$22"; 176 | 5'b10111: get_reg = reg_name ? "$s7" : "$23"; 177 | 5'b11000: get_reg = reg_name ? "$t8" : "$24"; 178 | 5'b11001: get_reg = reg_name ? "$t9" : "$25"; 179 | 5'b11010: get_reg = reg_name ? "$s8" : "$26"; 180 | 5'b11011: get_reg = reg_name ? "$s9" : "$27"; 181 | 5'b11100: get_reg = reg_name ? "$gp" : "$28"; 182 | 5'b11101: get_reg = reg_name ? "$sp" : "$29"; 183 | 5'b11110: get_reg = reg_name ? "$fp" : "$30"; 184 | 5'b11111: get_reg = reg_name ? "$ra" : "$31"; 185 | endcase 186 | end 187 | endfunction 188 | 189 | function [7:0] get_hex; 190 | input [3:0] num; 191 | begin 192 | case (num) 193 | 4'b0000: get_hex = "0"; 194 | 4'b0001: get_hex = "1"; 195 | 4'b0010: get_hex = "2"; 196 | 4'b0011: get_hex = "3"; 197 | 4'b0100: get_hex = "4"; 198 | 4'b0101: get_hex = "5"; 199 | 4'b0110: get_hex = "6"; 200 | 4'b0111: get_hex = "7"; 201 | 4'b1000: get_hex = "8"; 202 | 4'b1001: get_hex = "9"; 203 | 4'b1010: get_hex = "A"; 204 | 4'b1011: get_hex = "B"; 205 | 4'b1100: get_hex = "C"; 206 | 4'b1101: get_hex = "D"; 207 | 4'b1110: get_hex = "E"; 208 | 4'b1111: get_hex = "F"; 209 | endcase 210 | end 211 | endfunction 212 | 213 | wire [7:0] sp = 8'b0010_0000; 214 | 215 | wire [4*8-1:0] srs = {sp, get_reg(rs)}, srd = {sp, get_reg(rd)}, srt = {sp, get_reg(rt)}; 216 | wire [4*8-1:0] soff = {get_hex(imm[15:12]), get_hex(imm[11:8]), get_hex(imm[7:4]), get_hex(imm[3:0])}; 217 | wire [5*8-1:0] simm = {sp, get_hex(imm[15:12]), get_hex(imm[11:8]), get_hex(imm[7:4]), get_hex(imm[3:0])}; 218 | wire [31:0] imm32_signed = imm[15] ? -{{16{imm[15]}}, imm} : {16'b0, imm}; 219 | wire [6*8-1:0] simm_dec = {sp, get_hex(imm/10000%10), get_hex(imm/1000%10), get_hex(imm/100%10), get_hex(imm/10%10), get_hex(imm%10)}; 220 | wire [7*8-1:0] simm_dec_signed = {sp, imm[15] ? "-" : " ", 221 | get_hex(imm32_signed/10000%10), get_hex(imm32_signed/1000%10), 222 | get_hex(imm32_signed/100%10), get_hex(imm32_signed/10%10), get_hex(imm32_signed%10)}; 223 | 224 | wire [4*8-1:0] ssha = {sp, get_hex(sha)}; 225 | // wire [10*8-1:0] saddr = {sp, get_, "_"} 226 | // wire _rdrsrt = {} 227 | 228 | wire [12*8-1:0] _rd_rs_rt = {srd, srs, srt}; 229 | wire [12*8-1:0] _rd_rt_rs = {srd, srt, srs}; 230 | wire [12*8-1:0] _rd_rt_sha = {srd, srt, ssha}; 231 | wire [15*8-1:0] _rt_rs_imm = {srt, srs, imm_as_dec ? simm_dec : simm}; 232 | wire [15*8-1:0] _rt_rs_imm_signed = {srt, srs, imm_as_dec ? simm_dec_signed : simm}; 233 | wire [31:0] branch_npc = pc + 4 + {{14{imm[15]}}, imm, 2'b0}; 234 | wire [24*8-1:0] _rs_rt_imm = {srs, srt, imm_as_dec ? simm_dec : simm, "[", 235 | get_hex(branch_npc[31:28]), get_hex(branch_npc[27:24]), 236 | get_hex(branch_npc[23:20]), get_hex(branch_npc[19:16]), 237 | get_hex(branch_npc[15:12]), get_hex(branch_npc[11:8]), 238 | get_hex(branch_npc[7:4]), get_hex(branch_npc[3:0]), "]"}; 239 | wire [20*8-1:0] _rs_imm = {srs, imm_as_dec ? simm_dec : simm, "[", 240 | get_hex(branch_npc[31:28]), get_hex(branch_npc[27:24]), 241 | get_hex(branch_npc[23:20]), get_hex(branch_npc[19:16]), 242 | get_hex(branch_npc[15:12]), get_hex(branch_npc[11:8]), 243 | get_hex(branch_npc[7:4]), get_hex(branch_npc[3:0]), "]"}; // branch 244 | wire [10*8-1:0] _rt_imm = {srt, imm_as_dec ? simm_dec : simm}; 245 | wire [8*8-1:0] _rs_rt = {srs, srt}; 246 | wire [9*8-1:0] _target = {" 0", get_hex(target[25:22]), get_hex(target[21:18]), 247 | get_hex(target[17:14]), get_hex(target[13:10]), 248 | get_hex(target[9:6]), get_hex(target[5:2]), get_hex({target[1:0], 2'b0})}; 249 | wire [8*8-1:0] _rd_rs = {srd, srs}; 250 | wire [4*8-1:0] _rs = {srs}; 251 | wire [4*8-1:0] _rd = {srd}; 252 | wire [14*8-1:0] _rt_off_base = {srt, " ", soff, "(", srs[3*8-1:0], ")"}; 253 | wire [4*8-1:0] _rt_rd = {srd}; 254 | 255 | function [32*8-1:0] asm_ll; 256 | input [32*8-1:0] str; 257 | begin 258 | asm_ll = str; 259 | while (!asm_ll[32*8-1 -:8]) asm_ll = asm_ll << 8; 260 | end 261 | endfunction 262 | 263 | assign asm = asm_ll( 264 | beq ? {"beq", _rs_rt_imm} : 265 | bgez ? {"bgez", _rs_imm} : 266 | bgtz ? {"bgtz", _rs_imm} : 267 | blez ? {"blez", _rs_imm} : 268 | bltz ? {"bltz", _rs_imm} : 269 | bne ? {"bne", _rs_rt_imm} : 270 | j ? {"j", _target} : 271 | jal ? {"jal", _target} : 272 | jalr ? {"jalr", _rd_rs} : 273 | jr ? {"jr", _rs} : 274 | lb ? {"lb", _rt_off_base} : 275 | lbu ? {"lbu", _rt_off_base} : 276 | lh ? {"lh", _rt_off_base} : 277 | lhu ? {"lhu", _rt_off_base} : 278 | lw ? {"lw", _rt_off_base} : 279 | sb ? {"sb", _rt_off_base} : 280 | sh ? {"sh", _rt_off_base} : 281 | sw ? {"sw", _rt_off_base} : 282 | lui ? {"lui", _rt_imm} : 283 | add ? {"add", _rd_rs_rt} : 284 | addi ? {"addi", _rt_rs_imm_signed} : 285 | addiu ? {"addiu", _rt_rs_imm_signed} : 286 | addu ? {"addu", _rd_rs_rt} : 287 | And ? {"And", _rd_rs_rt} : 288 | andi ? {"andi", _rt_rs_imm} : 289 | div ? {"div", _rs_rt} : 290 | divu ? {"divu", _rs_rt} : 291 | mfhi ? {"mfhi", _rd} : 292 | mflo ? {"mflo", _rd} : 293 | mthi ? {"mthi", _rd} : 294 | mtlo ? {"mtlo", _rd} : 295 | mult ? {"mult", _rs_rt} : 296 | multu ? {"multu", _rs_rt} : 297 | Nor ? {"Nor", _rd_rs_rt} : 298 | Or ? {"Or", _rd_rs_rt} : 299 | ori ? {"ori", _rt_rs_imm} : 300 | sll ? {"sll", _rd_rt_sha} : 301 | sllv ? {"sllv", _rd_rt_rs} : 302 | slt ? {"slt", _rd_rs_rt} : 303 | slti ? {"slti", _rt_rs_imm_signed} : 304 | sltiu ? {"sltiu", _rt_rs_imm_signed} : 305 | sltu ? {"sltu", _rd_rs_rt} : 306 | sra ? {"sra", _rd_rt_sha} : 307 | srav ? {"srav", _rd_rt_rs} : 308 | srl ? {"srl", _rd_rt_sha} : 309 | srlv ? {"srlv", _rd_rt_rs} : 310 | sub ? {"sub", _rd_rs_rt} : 311 | subu ? {"subu", _rd_rs_rt} : 312 | Xor ? {"Xor", _rd_rs_rt} : 313 | xori ? {"xori", _rt_rs_imm} : 314 | "No Instr"); 315 | 316 | endmodule -------------------------------------------------------------------------------- /p6/_FU.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | `include "const.v" 3 | 4 | module _FU ( 5 | input [31:0] D_instr, 6 | input [31:0] E_instr, 7 | input [31:0] M_instr, 8 | input [31:0] W_instr, 9 | output forwardE, 10 | output forwardM, 11 | output forwardW 12 | ); 13 | 14 | wire E_j_l; 15 | _CU _EInterp ( 16 | .instr(E_instr), 17 | .j_l(E_j_l) 18 | ); 19 | 20 | wire M_j_l, M_calc_r, M_calc_i, M_mf; 21 | _CU _MInterp ( 22 | .instr(M_instr), 23 | .calc_r(M_calc_r), 24 | .calc_i(M_calc_i), 25 | .j_l(M_j_l), 26 | .mf(M_mf) 27 | ); 28 | 29 | wire W_j_l, W_calc_r, W_calc_i, W_load, W_mf; 30 | _CU _WInterp ( 31 | .instr(W_instr), 32 | .calc_r(W_calc_r), 33 | .calc_i(W_calc_i), 34 | .j_l(W_j_l), 35 | .load(W_load), 36 | .mf(W_mf) 37 | ); 38 | 39 | assign forwardE = E_j_l; 40 | assign forwardM = M_j_l | M_calc_r | M_calc_i | M_mf; 41 | assign forwardW = W_j_l | W_calc_r | W_calc_i | W_load | W_mf; 42 | 43 | endmodule -------------------------------------------------------------------------------- /p6/_SU.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | `include "const.v" 3 | 4 | module _SU ( 5 | input [31:0] D_instr, 6 | input [31:0] E_instr, 7 | input [31:0] M_instr, 8 | input E_HILObusy, 9 | output stall 10 | ); 11 | /////////////////////// StageD 12 | wire D_calc_r, D_calc_i, D_load, D_store, D_shiftS, D_j_r, D_j_noreg, D_branch, D_mt, D_mf, D_md; 13 | wire [4:0] D_rs_addr, D_rt_addr; 14 | wire [31:0] D_type; 15 | _CU _DInterp ( 16 | .instr(D_instr), 17 | .rs_addr(D_rs_addr), 18 | .rt_addr(D_rt_addr), 19 | .calc_r(D_calc_r), 20 | .calc_i(D_calc_i), 21 | .load(D_load), 22 | .store(D_store), 23 | .j_r(D_j_r), 24 | .shiftS(D_shiftS), 25 | .branch(D_branch), 26 | .md(D_md), 27 | .mt(D_mt), 28 | .mf(D_mf) 29 | ); 30 | 31 | wire [2:0] TuseRS = (D_branch | D_j_r) ? 3'd0 : 32 | ((D_calc_r & !D_shiftS) | D_calc_i | D_load | D_store | D_md | D_mt) ? 3'd1 : 33 | 3'd3; 34 | wire [2:0] TuseRT = D_branch ? 3'd0 : 35 | (D_calc_r | D_md) ? 3'd1 : 36 | D_store ? 3'd2 : 37 | 3'd3; 38 | 39 | /////////////////////// StageE 40 | wire [31:0] E_type; 41 | wire E_calc_r, E_calc_i, E_load, E_mf; 42 | wire [4:0] E_RFDst; 43 | _CU _EInterp ( 44 | .instr(E_instr), 45 | .calc_r(E_calc_r), 46 | .calc_i(E_calc_i), 47 | .load(E_load), 48 | .RFDst(E_RFDst), 49 | .mf(E_mf) 50 | ); 51 | 52 | wire [2:0] TnewE = E_calc_r | E_calc_i | E_mf ? 3'd1 : 53 | E_load ? 3'd2 : 54 | 3'd0; 55 | 56 | /////////////////////// StageM 57 | wire [31:0] M_type; 58 | wire M_load, M_calc_r, M_calc_i; 59 | wire [4:0] M_RFDst; 60 | _CU _MInterp ( 61 | .instr(M_instr), 62 | .load(M_load), 63 | .calc_r(M_calc_r), 64 | .calc_i(M_calc_i), 65 | .RFDst(M_RFDst) 66 | ); 67 | 68 | wire [2:0] TnewM = M_load ? 3'd1 : 69 | 3'd0; 70 | 71 | // Tuse < Tnew 72 | wire stall_rs_e = (TuseRS < TnewE) && (D_rs_addr && D_rs_addr == E_RFDst); 73 | wire stall_rs_m = (TuseRS < TnewM) && (D_rs_addr && D_rs_addr == M_RFDst); 74 | wire stall_rs = stall_rs_e | stall_rs_m; 75 | 76 | wire stall_rt_e = (TuseRT < TnewE) && (D_rt_addr && D_rt_addr == E_RFDst); 77 | wire stall_rt_m = (TuseRT < TnewM) && (D_rt_addr && D_rt_addr == M_RFDst); 78 | wire stall_rt = stall_rt_e | stall_rt_m; 79 | 80 | wire stall_HILO = E_HILObusy & (D_md | D_mt | D_mf); 81 | 82 | assign stall = stall_rs | stall_rt | stall_HILO; 83 | 84 | endmodule -------------------------------------------------------------------------------- /p6/_tb.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | 3 | module _tb; 4 | reg clk; 5 | reg reset; 6 | 7 | mips uut ( 8 | .clk(clk), 9 | .reset(reset) 10 | ); 11 | 12 | initial begin 13 | clk = 0; 14 | reset = 1; 15 | 16 | #10; 17 | reset = 0; 18 | end 19 | 20 | always #5 clk=~clk; 21 | 22 | endmodule 23 | 24 | -------------------------------------------------------------------------------- /p6/const.v: -------------------------------------------------------------------------------- 1 | //// Instr 2 | `define OP_rtype 6'b000000 3 | `define OP_lb 6'b100000 4 | `define OP_lbu 6'b100100 5 | `define OP_lh 6'b100001 6 | `define OP_lhu 6'b100101 7 | `define OP_lw 6'b100011 8 | `define OP_sb 6'b101000 9 | `define OP_sh 6'b101001 10 | `define OP_sw 6'b101011 11 | `define OP_addi 6'b001000 12 | `define OP_addiu 6'b001001 13 | `define OP_andi 6'b001100 14 | `define OP_beq 6'b000100 15 | `define OP_bgez 6'b000001 16 | `define OP_bgtz 6'b000111 17 | `define OP_blez 6'b000110 18 | `define OP_bltz 6'b000001 19 | `define OP_bne 6'b000101 20 | `define OP_j 6'b000010 21 | `define OP_jal 6'b000011 22 | `define OP_lui 6'b001111 23 | `define OP_ori 6'b001101 24 | `define OP_slti 6'b001010 25 | `define OP_sltiu 6'b001011 26 | `define OP_xori 6'b001110 27 | 28 | `define FUNC_add 6'b100000 29 | `define FUNC_addu 6'b100001 30 | `define FUNC_and 6'b100100 31 | `define FUNC_div 6'b011010 32 | `define FUNC_divu 6'b011011 33 | `define FUNC_jalr 6'b001001 34 | `define FUNC_jr 6'b001000 35 | `define FUNC_mfhi 6'b010000 36 | `define FUNC_mflo 6'b010010 37 | `define FUNC_mthi 6'b010001 38 | `define FUNC_mtlo 6'b010011 39 | `define FUNC_mult 6'b011000 40 | `define FUNC_multu 6'b011001 41 | `define FUNC_nor 6'b100111 42 | `define FUNC_or 6'b100101 43 | `define FUNC_sll 6'b000000 44 | `define FUNC_sllv 6'b000100 45 | `define FUNC_slt 6'b101010 46 | `define FUNC_sltu 6'b101011 47 | `define FUNC_sra 6'b000011 48 | `define FUNC_srav 6'b000111 49 | `define FUNC_srl 6'b000010 50 | `define FUNC_srlv 6'b000110 51 | `define FUNC_sub 6'b100010 52 | `define FUNC_subu 6'b100011 53 | `define FUNC_xor 6'b100110 54 | 55 | `define RT_bltz 5'b00000 56 | `define RT_bgez 5'b00001 57 | 58 | //// CU Signal 59 | 60 | // ALU 61 | `define ALU_add 4'd0 62 | `define ALU_sub 4'd1 63 | `define ALU_and 4'd2 64 | `define ALU_or 4'd3 65 | `define ALU_xor 4'd4 66 | `define ALU_nor 4'd5 67 | `define ALU_sll 4'd6 68 | `define ALU_srl 4'd7 69 | `define ALU_sra 4'd8 70 | `define ALU_slt 4'd9 71 | `define ALU_sltu 4'd10 72 | `define ALU_lui 4'd11 73 | 74 | // DM 75 | `define DM_w 3'b000 76 | `define DM_h 3'b001 77 | `define DM_hu 3'b010 78 | `define DM_b 3'b011 79 | `define DM_bu 3'b100 80 | 81 | // Branch 82 | `define BR_pc4 3'b000 83 | `define BR_addr 3'b001 84 | `define BR_reg 3'b010 85 | `define BR_branch 3'b011 86 | 87 | // B_type 88 | `define B_beq 3'd0 89 | `define B_bne 3'd1 90 | `define B_blez 3'd2 91 | `define B_bgtz 3'd3 92 | `define B_bgez 3'd4 93 | `define B_bltz 3'd5 94 | 95 | // RFWDSel 96 | `define RFWD_ALUout 3'b000 97 | `define RFWD_DMout 3'b001 98 | `define RFWD_PC8 3'b010 99 | `define RFWD_HILOout 3'b011 100 | `define RFWD_EXTout 3'b100 101 | 102 | // ALUASrc 103 | `define ALUASrcRT 2'b00 104 | `define ALUASrcRS 2'b01 105 | 106 | // ALUBSrc 107 | `define ALUBSrcShamt 3'd0 108 | `define ALUBSrcRS_4_0 3'd1 109 | `define ALUBSrcRT 3'd2 110 | `define ALUBSrcExt 3'd3 111 | 112 | // HILOType 113 | `define HILO_none 4'd0 114 | `define HILO_mult 4'd1 115 | `define HILO_multu 4'd2 116 | `define HILO_div 4'd3 117 | `define HILO_divu 4'd4 118 | `define HILO_mflo 4'd5 119 | `define HILO_mfhi 4'd6 120 | `define HILO_mtlo 4'd7 121 | `define HILO_mthi 4'd8 122 | 123 | // EXT 124 | `define EXT_unsigned 3'd0 125 | `define EXT_signed 3'd1 126 | `define EXT_lui 3'd2 -------------------------------------------------------------------------------- /p6/mips.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | `include "const.v" 3 | 4 | module mips ( 5 | input clk, 6 | input reset 7 | ); 8 | wire stall; 9 | wire F_pc_en = !stall, D_reg_en = !stall, E_reg_en = 1'b1, M_reg_en = 1'b1, W_reg_en = 1'b1; // Reg En 10 | wire D_reg_reset = 1'b0, E_reg_reset = stall, M_reg_reset = 1'b0, W_reg_reset = 1'b0; 11 | 12 | wire [31:0] F_instr, D_instr, E_instr, M_instr, W_instr; 13 | wire E_HILObusy; 14 | _SU _su( 15 | .D_instr(D_instr), 16 | .E_instr(E_instr), 17 | .M_instr(M_instr), 18 | .E_HILObusy(E_HILObusy), 19 | .stall(stall) 20 | ); 21 | 22 | wire [31:0] E_RFWD, M_RFWD, W_RFWD; 23 | wire [4:0] E_RFDst, M_RFDst, W_RFDst; 24 | wire [2:0] E_RFWDSrc, M_RFWDSrc, W_RFWDSrc; 25 | wire W_RFWE; 26 | 27 | assign E_RFWD = // (E_RFWDSrc == `RFWD_ALUout) ? E_ALUout : 28 | // (E_RFWDSrc == `RFWD_DMout) ? E_DMout : 29 | // (E_RFWDSrc == `RFWD_HILOout) ? E_HILOout : 30 | (E_RFWDSrc == `RFWD_EXTout) ? E_EXTout : 31 | (E_RFWDSrc == `RFWD_PC8) ? E_pc + 8 : 32 | 0; // don't forward 33 | 34 | assign M_RFWD = (M_RFWDSrc == `RFWD_ALUout) ? M_ALUout : 35 | (M_RFWDSrc == `RFWD_HILOout) ? M_HILOout : 36 | (M_RFWDSrc == `RFWD_EXTout) ? M_EXTout : 37 | // (M_RFWDSrc == `RFWD_DMout) ? M_DMout : 38 | (M_RFWDSrc == `RFWD_PC8) ? M_pc + 8 : 39 | 0; 40 | 41 | assign W_RFWD = (W_RFWDSrc == `RFWD_ALUout) ? W_ALUout : 42 | (W_RFWDSrc == `RFWD_HILOout) ? W_HILOout : 43 | (W_RFWDSrc == `RFWD_EXTout) ? W_EXTout : 44 | (W_RFWDSrc == `RFWD_DMout) ? W_DMout : 45 | (W_RFWDSrc == `RFWD_PC8) ? W_pc + 8 : 46 | 0; 47 | 48 | /// StageF 49 | wire [31:0] F_pc, npc; 50 | F_IFU F_ifu( 51 | .clk(clk), 52 | .reset(reset), 53 | .WE(F_pc_en), 54 | .npc(npc), 55 | .instr(F_instr), 56 | .pc(F_pc) 57 | ); 58 | 59 | /// StageD 60 | wire [31:0] D_pc; 61 | D_REG D_reg ( 62 | .clk(clk), 63 | .reset(reset || D_reg_reset), 64 | .WE(D_reg_en), 65 | 66 | .instr_in(F_instr), 67 | .pc_in(F_pc), 68 | 69 | .instr_out(D_instr), 70 | .pc_out(D_pc) 71 | ); 72 | 73 | wire [4:0] D_rs_addr, D_rt_addr; 74 | wire [15:0] D_imm; 75 | wire [25:0] D_addr; 76 | wire D_b_jump; 77 | wire [2:0] D_EXTOp; 78 | wire [2:0] D_Br, D_B_type; 79 | wire [31:0] D_rs, D_rt, D_EXTout, D_type; 80 | 81 | _CU D_cu( 82 | .instr(D_instr), 83 | .rs_addr(D_rs_addr), 84 | .rt_addr(D_rt_addr), 85 | .imm(D_imm), 86 | .addr(D_addr), 87 | .EXTOp(D_EXTOp), 88 | .Br(D_Br), 89 | .B_type(D_B_type) 90 | ); 91 | 92 | wire [31:0] W_pc; 93 | 94 | D_GRF D_grf ( 95 | .WPC(W_pc), 96 | .clk(clk), 97 | .reset(reset), 98 | .WE(W_RFWE), 99 | .A1(D_rs_addr), 100 | .A2(D_rt_addr), 101 | .A3(W_RFDst), 102 | .WD(W_RFWD), 103 | .RD1(D_rs), 104 | .RD2(D_rt) 105 | ); 106 | 107 | D_EXT D_ext ( 108 | .imm(D_imm), 109 | .EXTOp(D_EXTOp), 110 | .EXTout(D_EXTout) 111 | ); 112 | // FORWARD 113 | wire [31:0] FWD_D_RS = (D_rs_addr == 0) ? 0 : 114 | (D_rs_addr == E_RFDst) ? E_RFWD : 115 | (D_rs_addr == M_RFDst) ? M_RFWD : 116 | D_rs; 117 | // W has been forwarded inside 118 | 119 | wire [31:0] FWD_D_RT = (D_rt_addr == 0) ? 0 : 120 | (D_rt_addr == E_RFDst) ? E_RFWD : 121 | (D_rt_addr == M_RFDst) ? M_RFWD : 122 | D_rt; 123 | // W has been forwarded inside 124 | 125 | D_CMP D_cmp ( 126 | .rs(FWD_D_RS), 127 | .rt(FWD_D_RT), 128 | .type(D_B_type), 129 | .b_jump(D_b_jump) 130 | ); 131 | 132 | D_NPC D_npc ( 133 | .D_pc(D_pc), 134 | .F_pc(F_pc), 135 | .imm26(D_addr), 136 | .rs(FWD_D_RS), 137 | .Br(D_Br), 138 | .b_jump(D_b_jump), 139 | .npc(npc) 140 | ); 141 | 142 | /// StageE 143 | wire [31:0] E_pc, E_EXTout, E_rs, E_rt; 144 | E_REG E_reg ( 145 | .clk(clk), 146 | .reset(reset || E_reg_reset), 147 | .WE(E_reg_en), 148 | 149 | .instr_in(D_instr), 150 | .pc_in(D_pc), 151 | .EXT_in(D_EXTout), 152 | .rs_in(FWD_D_RS), 153 | .rt_in(FWD_D_RT), 154 | .instr_out(E_instr), 155 | 156 | .pc_out(E_pc), 157 | .EXT_out(E_EXTout), 158 | .rs_out(E_rs), 159 | .rt_out(E_rt) 160 | ); 161 | 162 | 163 | wire [3:0] E_ALUControl, E_HILOType; 164 | wire [1:0] E_ALUASrc; 165 | wire [2:0] E_ALUBSrc; 166 | wire [4:0] E_rs_addr, E_rt_addr; 167 | 168 | _CU E_cu ( 169 | .instr(E_instr), 170 | .rs_addr(E_rs_addr), 171 | .rt_addr(E_rt_addr), 172 | .ALUControl(E_ALUControl), 173 | .ALUASrc(E_ALUASrc), 174 | .ALUBSrc(E_ALUBSrc), 175 | .RFDst(E_RFDst), 176 | .RFWDSrc(E_RFWDSrc), 177 | .HILO_type(E_HILOType) 178 | ); 179 | 180 | wire [31:0] E_ALUA, E_ALUB, E_ALUout; 181 | 182 | // FORWARD 183 | wire [31:0] FWD_E_RS = (E_rs_addr == 0) ? 0 : 184 | (E_rs_addr == M_RFDst) ? M_RFWD : 185 | (E_rs_addr == W_RFDst) ? W_RFWD : 186 | E_rs; 187 | 188 | wire [31:0] FWD_E_RT = (E_rt_addr == 0) ? 0 : 189 | (E_rt_addr == M_RFDst) ? M_RFWD : 190 | (E_rt_addr == W_RFDst) ? W_RFWD : 191 | E_rt; 192 | 193 | assign E_ALUA = (E_ALUASrc == `ALUASrcRT) ? FWD_E_RT : 194 | (E_ALUASrc == `ALUASrcRS) ? FWD_E_RS : 195 | 0; 196 | 197 | assign E_ALUB = (E_ALUBSrc == `ALUBSrcShamt) ? {27'b0, E_instr[10:6]} : 198 | (E_ALUBSrc == `ALUBSrcRS_4_0) ? {27'b0, FWD_E_RS[4:0]} : 199 | (E_ALUBSrc == `ALUBSrcRT) ? FWD_E_RT : 200 | (E_ALUBSrc == `ALUBSrcExt) ? E_EXTout : 201 | 0; 202 | 203 | E_ALU E_alu ( 204 | .ALUControl(E_ALUControl), 205 | .A(E_ALUA), 206 | .B(E_ALUB), 207 | .ALUout(E_ALUout) 208 | ); 209 | 210 | wire [31:0] E_HILOout; 211 | 212 | E_HILO E_hilo ( 213 | .clk(clk), 214 | .reset(reset), 215 | .rs(FWD_E_RS), 216 | .rt(FWD_E_RT), 217 | .HILOtype(E_HILOType), 218 | .HILObusy(E_HILObusy), 219 | .HILOout(E_HILOout) 220 | ); 221 | 222 | /// StageM 223 | wire [31:0] M_pc, M_ALUout, M_rt, M_HILOout, M_EXTout; 224 | M_REG M_reg( 225 | .clk(clk), 226 | .reset(reset || M_reg_reset), 227 | .WE(M_reg_en), 228 | 229 | .instr_in(E_instr), 230 | .pc_in(E_pc), 231 | .ALU_in(E_ALUout), 232 | .HILO_in(E_HILOout), 233 | .rt_in(FWD_E_RT), 234 | .EXT_in(E_EXTout), 235 | 236 | .instr_out(M_instr), 237 | .pc_out(M_pc), 238 | .ALU_out(M_ALUout), 239 | .HILO_out(M_HILOout), 240 | .rt_out(M_rt), 241 | .EXT_out(M_EXTout) 242 | ); 243 | 244 | wire [4:0] M_rt_addr; 245 | wire [2:0] M_DMType; 246 | wire M_WE; 247 | 248 | _CU M_cu ( 249 | .instr(M_instr), 250 | .rt_addr(M_rt_addr), 251 | .DMType(M_DMType), 252 | .DMWr(M_WE), 253 | .RFDst(M_RFDst), 254 | .RFWDSrc(M_RFWDSrc) 255 | ); 256 | 257 | // FORWARD 258 | wire [31:0] M_DMout; 259 | 260 | wire [31:0] FWD_M_RT = (M_rt_addr == 0) ? 0 : 261 | (M_rt_addr == W_RFDst) ? W_RFWD : 262 | M_rt; 263 | 264 | M_DM M_dm ( 265 | .pc(M_pc), 266 | .clk(clk), 267 | .reset(reset), 268 | .WE(M_WE), 269 | .DMType(M_DMType), 270 | .addr(M_ALUout), 271 | .WD(FWD_M_RT), 272 | .DMout(M_DMout) 273 | ); 274 | 275 | /// StageW 276 | wire [31:0] W_ALUout, W_DMout, W_HILOout, W_EXTout; 277 | W_REG W_reg( 278 | .clk(clk), 279 | .reset(reset || W_reg_reset), 280 | .WE(W_reg_en), 281 | 282 | .instr_in(M_instr), 283 | .pc_in(M_pc), 284 | .ALU_in(M_ALUout), 285 | .DM_in(M_DMout), 286 | .HILO_in(M_HILOout), 287 | .EXT_in(M_EXTout), 288 | 289 | .instr_out(W_instr), 290 | .pc_out(W_pc), 291 | .ALU_out(W_ALUout), 292 | .DM_out(W_DMout), 293 | .HILO_out(W_HILOout), 294 | .EXT_out(W_EXTout) 295 | ); 296 | 297 | _CU W_cu( 298 | .instr(W_instr), 299 | .RFDst(W_RFDst), 300 | .RFWr(W_RFWE), 301 | .RFWDSrc(W_RFWDSrc) 302 | ); 303 | 304 | /// Write Back To D_GRF 305 | 306 | endmodule -------------------------------------------------------------------------------- /p7/D_CMP.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | `include "const.v" 3 | 4 | module D_CMP ( 5 | input [31:0] rs, 6 | input [31:0] rt, 7 | input [2:0] type, 8 | output b_jump 9 | ); 10 | wire equal = (rs == rt); 11 | wire eq0 = !(|rs); 12 | wire gt0 = (!rs[31]) && !eq0; 13 | wire le0 = (rs[31]) && !eq0; 14 | 15 | assign b_jump = (type == `B_beq && equal) || 16 | (type == `B_bne && !equal) || 17 | (type == `B_blez && (le0 || eq0)) || 18 | (type == `B_bgez && (gt0 || eq0)) || 19 | (type == `B_bgtz && gt0) || 20 | (type == `B_bltz && le0); 21 | 22 | endmodule -------------------------------------------------------------------------------- /p7/D_EXT.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | `include "const.v" 3 | 4 | module D_EXT ( 5 | input [15:0] imm, 6 | input [2:0] EXTOp, 7 | output [31:0] EXTout 8 | ); 9 | 10 | assign EXTout = (EXTOp == `EXT_signed) ? {{16{imm[15]}}, imm} : 11 | (EXTOp == `EXT_lui) ? {imm, 16'b0} : 12 | {{16{1'b0}}, imm}; 13 | 14 | endmodule -------------------------------------------------------------------------------- /p7/D_GRF.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | `include "const.v" 3 | 4 | module D_GRF ( 5 | input [31:0] WPC, // for debugging 6 | input clk, 7 | input reset, 8 | input WE, 9 | input [4:0] A1, 10 | input [4:0] A2, 11 | input [4:0] A3, 12 | input [31:0] WD, 13 | output [31:0] RD1, 14 | output [31:0] RD2 15 | ); 16 | 17 | reg [31:0] grf [31:0]; 18 | 19 | assign RD1 = (A3 == A1 && A3 && WE) ? WD : grf[A1]; // 内部转发 20 | assign RD2 = (A3 == A2 && A3 && WE) ? WD : grf[A2]; 21 | 22 | integer i; 23 | 24 | initial begin 25 | for (i=0; i<32; i=i+1) grf[i] <= 0; 26 | end 27 | 28 | always @(posedge clk) begin 29 | if (reset) begin 30 | for (i=0; i<32; i=i+1) grf[i] <= 0; 31 | end 32 | else if (WE && A3) begin 33 | grf[A3] <= WD; 34 | $display("%d@%h: $%d <= %h", $time, WPC, A3, WD); 35 | end 36 | end 37 | 38 | endmodule -------------------------------------------------------------------------------- /p7/D_NPC.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | `include "const.v" 3 | 4 | module D_NPC ( 5 | input req, 6 | input eret, 7 | input [31:0] EPC, 8 | 9 | input [31:0] D_pc, 10 | input [31:0] F_pc, 11 | input [25:0] imm26, 12 | input [31:0] rs, 13 | input [2:0] Br, 14 | input b_jump, 15 | output [31:0] npc 16 | ); 17 | assign npc = req ? 32'h0000_4180 : 18 | eret ? EPC + 4 : 19 | (Br == `BR_pc4) ? F_pc + 4 : 20 | (Br == `BR_addr) ? {D_pc[31:28], imm26, 2'b0} : 21 | (Br == `BR_reg) ? rs : 22 | (Br == `BR_branch && b_jump) ? D_pc + 4 + {{14{imm26[15]}}, imm26[15:0], 2'b0} : 23 | F_pc + 4; 24 | wire [31:28] test1 = D_pc[31:28]; 25 | endmodule -------------------------------------------------------------------------------- /p7/D_REG.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | `include "const.v" 3 | 4 | module D_REG ( 5 | input req, 6 | input stall, 7 | input [4:0] excCode_in, 8 | input bd_in, 9 | output reg [4:0] excCode_out, 10 | output reg bd_out, 11 | 12 | input clk, 13 | input reset, 14 | input WE, 15 | input [31:0] instr_in, 16 | input [31:0] pc_in, 17 | output reg [31:0] instr_out, 18 | output reg [31:0] pc_out 19 | ); 20 | 21 | always @(posedge clk) begin 22 | if (reset | req) begin 23 | instr_out <= 0; 24 | pc_out <= req ? 32'h0000_4180 : 0; 25 | excCode_out <= 0; 26 | bd_out <= 0; 27 | end else if(WE) begin 28 | instr_out <= instr_in; 29 | pc_out <= pc_in; 30 | excCode_out <= excCode_in; 31 | bd_out <= bd_in; 32 | end 33 | end 34 | 35 | endmodule -------------------------------------------------------------------------------- /p7/E_ALU.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | `include "const.v" 3 | 4 | module E_ALU ( 5 | input ALUAriOverflow, 6 | input ALUDMOverflow, 7 | output excOvAri, 8 | output excOvDM, 9 | 10 | input [3:0] ALUControl, 11 | input [31:0] A, 12 | input [31:0] B, 13 | output [31:0] ALUout 14 | ); 15 | 16 | wire [31:0] res_sra = $signed($signed(A) >>> B); 17 | wire [31:0] res_slt = $signed(A) < $signed(B) ? 32'b1 : 32'b0; 18 | 19 | assign ALUout = (ALUControl == `ALU_add ) ? A + B : 20 | (ALUControl == `ALU_sub ) ? A - B : 21 | (ALUControl == `ALU_and ) ? A & B : 22 | (ALUControl == `ALU_or ) ? A | B : 23 | (ALUControl == `ALU_xor ) ? A ^ B : 24 | (ALUControl == `ALU_nor ) ? ~(A | B) : 25 | (ALUControl == `ALU_sll ) ? A << B : 26 | (ALUControl == `ALU_srl ) ? A >> B : 27 | (ALUControl == `ALU_sra ) ? res_sra : 28 | (ALUControl == `ALU_slt ) ? res_slt : 29 | (ALUControl == `ALU_sltu) ? A < B : 30 | 0; 31 | 32 | wire [32:0] exA = {A[31], A}, exB = {B[31], B}; 33 | wire [32:0] exAdd = exA + exB, exSub = exA - exB; 34 | assign excOvAri = ALUAriOverflow && ( 35 | ((ALUControl == `ALU_add) && (exAdd[32] != exAdd[31])) || 36 | ((ALUControl == `ALU_sub) && (exSub[32] != exSub[31])) 37 | ); 38 | assign excOvDM = ALUDMOverflow && ( 39 | ((ALUControl == `ALU_add) && (exAdd[32] != exAdd[31])) || 40 | ((ALUControl == `ALU_sub) && (exSub[32] != exSub[31])) 41 | ); 42 | 43 | endmodule -------------------------------------------------------------------------------- /p7/E_HILO.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | `include "const.v" 3 | 4 | module E_HILO ( 5 | input req, 6 | input clk, 7 | input reset, 8 | input [31:0] rs, 9 | input [31:0] rt, 10 | input [3:0] HILOtype, 11 | output HILObusy, 12 | output [31:0] HILOout 13 | ); 14 | 15 | integer state = 0; 16 | reg [31:0] hi, lo, temp_hi, temp_lo; 17 | wire mult = (HILOtype == `HILO_mult), 18 | multu = (HILOtype == `HILO_multu), 19 | div = (HILOtype == `HILO_div), 20 | divu = (HILOtype == `HILO_divu), 21 | mflo = (HILOtype == `HILO_mflo), 22 | mfhi = (HILOtype == `HILO_mfhi), 23 | mtlo = (HILOtype == `HILO_mtlo), 24 | mthi = (HILOtype == `HILO_mthi); 25 | 26 | wire start = mult | multu | div | divu; 27 | reg busy; 28 | 29 | assign HILObusy = start | busy; 30 | assign HILOout = mflo ? lo: 31 | mfhi ? hi: 32 | 0; 33 | 34 | initial begin 35 | state <= 0; 36 | busy <= 0; 37 | hi <= 0; 38 | lo <= 0; 39 | end 40 | 41 | always @(posedge clk) begin 42 | if (reset) begin 43 | state <= 0; 44 | busy <= 0; 45 | hi <= 0; 46 | lo <= 0; 47 | end else if (!req) begin 48 | if (state == 0) begin 49 | if (mtlo) lo <= rs; 50 | else if (mthi) hi <= rs; 51 | else if (mult) begin 52 | busy <= 1; 53 | state <= 5; 54 | {temp_hi, temp_lo} <= $signed(rs) * $signed(rt); 55 | end else if (multu) begin 56 | busy <= 1; 57 | state <= 5; 58 | {temp_hi, temp_lo} <= rs * rt; 59 | end else if (div) begin 60 | busy <= 1; 61 | state <= 10; 62 | if (rt) begin 63 | temp_lo <= $signed(rs) / $signed(rt); 64 | temp_hi <= $signed(rs) % $signed(rt); 65 | end else begin 66 | temp_lo <= lo; 67 | temp_hi <= hi; 68 | end 69 | end else if (divu) begin 70 | busy <= 1; 71 | state <= 10; 72 | temp_lo <= rt ? rs / rt : lo; 73 | temp_hi <= rt ? rs % rt : hi; 74 | end 75 | end else if (state == 1) begin 76 | state <= 0; 77 | busy <= 0; 78 | hi <= temp_hi; 79 | lo <= temp_lo; 80 | end else begin // state > 0 81 | state <= state - 1; 82 | end 83 | end 84 | end 85 | 86 | endmodule 87 | -------------------------------------------------------------------------------- /p7/E_REG.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | `include "const.v" 3 | 4 | module E_REG ( 5 | input req, 6 | input [4:0] excCode_in, 7 | input bd_in, 8 | output reg [4:0] excCode_out, 9 | output reg bd_out, 10 | 11 | input clk, 12 | input reset, 13 | input stall, 14 | input WE, 15 | input [31:0] instr_in, 16 | input [31:0] pc_in, 17 | input [31:0] EXT_in, 18 | input [31:0] rs_in, 19 | input [31:0] rt_in, 20 | output reg [31:0] instr_out, 21 | output reg [31:0] pc_out, 22 | output reg [31:0] EXT_out, 23 | output reg [31:0] rs_out, 24 | output reg [31:0] rt_out 25 | ); 26 | 27 | always @(posedge clk) begin 28 | if (reset || stall || req) begin 29 | instr_out <= 0; 30 | pc_out <= stall ? pc_in : (req ? 32'h0000_4180 : 0); 31 | EXT_out <= 0; 32 | rs_out <= 0; 33 | rt_out <= 0; 34 | excCode_out <= 0; 35 | bd_out <= stall ? bd_in : 0; 36 | end else if(WE) begin 37 | instr_out <= instr_in; 38 | pc_out <= pc_in; 39 | EXT_out <= EXT_in; 40 | rs_out <= rs_in; 41 | rt_out <= rt_in; 42 | excCode_out <= excCode_in; 43 | bd_out <= bd_in; 44 | end 45 | end 46 | 47 | endmodule -------------------------------------------------------------------------------- /p7/F_IFU.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | `include "const.v" 3 | `define N 4096 4 | `define StartInstr 32'h0000_3000 5 | `define EndInstr 32'h0000_4fff 6 | 7 | module F_IFU ( 8 | input req, 9 | input D_eret, 10 | input [31:0] EPC, 11 | output excAdEL, 12 | 13 | input clk, 14 | input reset, 15 | input WE, 16 | input [31:0] npc, 17 | output [31:0] instr, 18 | output [31:0] pc 19 | ); 20 | 21 | reg [31:0] im [0:`N-1]; 22 | reg [31:0] tempPC; 23 | 24 | integer i; 25 | initial begin 26 | for (i=0; i<`N; i=i+1) im[i] = 0; 27 | tempPC = 32'h0000_3000; 28 | $readmemh("code.txt", im); 29 | $readmemh("code_handler.txt", im, 1120, 2047); 30 | end 31 | 32 | // ??????????????? Different 33 | assign excAdEL = ((|pc[1:0]) | (pc < `StartInstr) | (pc > `EndInstr)) && !D_eret; 34 | assign pc = D_eret ? EPC : tempPC; 35 | assign instr = (excAdEL) ? 0 : im[pc[14:2] - 12'hc00]; 36 | 37 | always @(posedge clk) begin 38 | if (reset) tempPC <= 32'h0000_3000; 39 | else if(req | WE) tempPC <= npc; 40 | end 41 | 42 | _DASM Dasm( 43 | .pc(pc), 44 | .instr(instr), 45 | .imm_as_dec(1'b1), 46 | .reg_name(1'b0), 47 | .asm() 48 | ); 49 | endmodule -------------------------------------------------------------------------------- /p7/M_DM.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | `include "const.v" 3 | `define HIGH_BYTE 15 4 | `define DM_SIZE (1<<`HIGH_BYTE) 5 | 6 | `define word memory[addr[`HIGH_BYTE:2]] 7 | `define half `word[15 + 16 * addr[1] -:16] 8 | `define half_sign `word[15 + 16 * addr[1] -:1] 9 | `define byte `word[7 + 8 * addr[1:0] -:8] 10 | `define byte_sign `word[7 + 8 * addr[1:0] -:1] 11 | 12 | `define StartAddrDM 32'h0000_0000 13 | `define EndAddrDM 32'h0000_2fff 14 | `define StartAddrTC1 32'h0000_7f00 15 | `define EndAddrTC1 32'h0000_7f0b 16 | `define StartAddrTC2 32'h0000_7f10 17 | `define EndAddrTC2 32'h0000_7f1b 18 | 19 | module M_DM ( 20 | input excOvDM, 21 | output excAdEL, 22 | output excAdES, 23 | 24 | input [31:0] pc, // for debugging 25 | input clk, 26 | input reset, 27 | input WE, 28 | input load, 29 | input store, 30 | input [2:0] DMType, 31 | input [31:0] addr, 32 | input [31:0] WD, 33 | output [31:0] DMout 34 | ); 35 | reg [31:0] memory [`DM_SIZE - 1:0]; 36 | 37 | assign DMout = (DMType == `DM_w) ? `word : 38 | (DMType == `DM_h) ? {{16{`half_sign}}, `half} : 39 | (DMType == `DM_hu) ? {{16{1'b0}}, `half} : 40 | (DMType == `DM_b) ? {{24{`byte_sign}}, `byte} : 41 | (DMType == `DM_bu) ? {{24{1'b0}}, `byte} : 42 | 32'b0; 43 | 44 | 45 | ////// Exceptions 46 | wire ErrAlign = ((DMType == `DM_w) && (|addr[1:0])) || 47 | (((DMType == `DM_h) || (DMType == `DM_hu)) && (addr[0])); 48 | wire ErrOutOfRange = !( ((addr >= `StartAddrDM) && (addr <= `EndAddrDM)) || 49 | ((addr >= `StartAddrTC1) && (addr <= `EndAddrTC1)) || 50 | ((addr >= `StartAddrTC2) && (addr <= `EndAddrTC2))); 51 | wire ErrTimer = (DMType != `DM_w) && (addr >= `StartAddrTC1); 52 | wire ErrSaveTimer = (addr >= 32'h0000_7f08 && addr <= 32'h0000_7f0b) || 53 | (addr >= 32'h0000_7f18 && addr <= 32'h0000_7f1b); 54 | assign excAdEL = load && (ErrAlign || ErrOutOfRange || ErrTimer || excOvDM); 55 | assign excAdES = store && (ErrAlign || ErrOutOfRange || ErrTimer || ErrSaveTimer || excOvDM); 56 | ////// EndExceptions 57 | 58 | integer i; 59 | initial begin 60 | for (i=0; i<`DM_SIZE; i=i+1) memory[i] <= 0; 61 | end 62 | 63 | function [31:0] F_H_OUT; 64 | input [31:0] WD; 65 | input [31:0] word; 66 | begin 67 | F_H_OUT = word; 68 | F_H_OUT[15 + 16 * addr[1] -:16] = WD[15:0]; 69 | end 70 | endfunction 71 | 72 | function [31:0] F_B_OUT; 73 | input [31:0] WD; 74 | input [31:0] word; 75 | begin 76 | F_B_OUT = word; 77 | F_B_OUT[7 + 8 * addr[1:0] -:8] = WD[7:0]; 78 | end 79 | endfunction 80 | 81 | always @(posedge clk) begin 82 | if (reset) begin 83 | for (i=0; i<`DM_SIZE; i=i+1) memory[i] <= 0; 84 | end 85 | else if (WE && (addr >= `StartAddrDM) && (addr <= `EndAddrDM)) begin 86 | if (DMType == `DM_w) begin 87 | `word <= WD; 88 | $display("%d@%h: *%h <= %h", $time, pc, addr&(`DM_SIZE-1), WD); 89 | end else if (DMType == `DM_h) begin 90 | `half <= WD[15:0]; 91 | $display("%d@%h: *%h <= %h", $time, pc, {addr[31:2], 2'b00}&(`DM_SIZE-1), F_H_OUT(WD, memory[addr[`HIGH_BYTE:2]])); 92 | end else if (DMType == `DM_b) begin 93 | `byte <= WD[7:0]; 94 | $display("%d@%h: *%h <= %h", $time, pc, {addr[31:2], 2'b00}&(`DM_SIZE-1), F_B_OUT(WD, memory[addr[`HIGH_BYTE:2]])); 95 | end 96 | end 97 | end 98 | 99 | endmodule -------------------------------------------------------------------------------- /p7/M_REG.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | `include "const.v" 3 | 4 | module M_REG ( 5 | input req, 6 | input [4:0] excCode_in, 7 | input bd_in, 8 | input excOvDM_in, 9 | output reg [4:0] excCode_out, 10 | output reg bd_out, 11 | output reg excOvDM_out, 12 | 13 | input clk, 14 | input reset, 15 | input WE, 16 | input [31:0] instr_in, 17 | input [31:0] pc_in, 18 | input [31:0] ALU_in, 19 | input [31:0] rt_in, 20 | input [31:0] HILO_in, 21 | input [31:0] EXT_in, 22 | output reg [31:0] instr_out, 23 | output reg [31:0] pc_out, 24 | output reg [31:0] ALU_out, 25 | output reg [31:0] rt_out, 26 | output reg [31:0] HILO_out, 27 | output reg [31:0] EXT_out 28 | ); 29 | 30 | always @(posedge clk) begin 31 | if (reset || req) begin 32 | instr_out <= 0; 33 | pc_out <= req ? 32'h0000_4180 : 0; 34 | ALU_out <= 0; 35 | rt_out <= 0; 36 | HILO_out <= 0; 37 | EXT_out <= 0; 38 | excCode_out <= 0; 39 | bd_out <= 0; 40 | excOvDM_out <= 0; 41 | end else if(WE) begin 42 | instr_out <= instr_in; 43 | pc_out <= pc_in; 44 | ALU_out <= ALU_in; 45 | rt_out <= rt_in; 46 | HILO_out <= HILO_in; 47 | EXT_out <= EXT_in; 48 | excCode_out <= excCode_in; 49 | bd_out <= bd_in; 50 | excOvDM_out <= excOvDM_in; 51 | end 52 | end 53 | 54 | endmodule -------------------------------------------------------------------------------- /p7/W_REG.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | `include "const.v" 3 | 4 | module W_REG ( 5 | input req, 6 | input [31:0] CP0_in, 7 | output reg [31:0] CP0_out, 8 | 9 | input clk, 10 | input reset, 11 | input WE, 12 | input [31:0] instr_in, 13 | input [31:0] pc_in, 14 | input [31:0] ALU_in, 15 | input [31:0] DM_in, 16 | input [31:0] HILO_in, 17 | input [31:0] EXT_in, 18 | output reg [31:0] instr_out, 19 | output reg [31:0] pc_out, 20 | output reg [31:0] ALU_out, 21 | output reg [31:0] DM_out, 22 | output reg [31:0] HILO_out, 23 | output reg [31:0] EXT_out 24 | ); 25 | 26 | always @(posedge clk) begin 27 | if (reset || req) begin 28 | instr_out <= 0; 29 | pc_out <= req ? 32'h0000_4180 : 0; 30 | ALU_out <= 0; 31 | DM_out <= 0; 32 | HILO_out <= 0; 33 | EXT_out <= 0; 34 | CP0_out <= 0; 35 | end else if(WE) begin 36 | instr_out <= instr_in; 37 | pc_out <= pc_in; 38 | ALU_out <= ALU_in; 39 | DM_out <= DM_in; 40 | HILO_out <= HILO_in; 41 | EXT_out <= EXT_in; 42 | CP0_out <= CP0_in; 43 | end 44 | end 45 | 46 | endmodule -------------------------------------------------------------------------------- /p7/_CP0.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | `define IM SR[15:10] // allow 6 hardware ints 3 | `define EXL SR[1] // in int (cannot int/exc) 4 | `define IE SR[0] // allow int 5 | `define BD Cause[31] 6 | `define hwint_pend Cause[15:10] 7 | `define ExcCode Cause[6:2] 8 | 9 | module CP0( 10 | input [4:0] A1, // read reg addr (mfc0) 11 | input [4:0] A2, // write reg addr (mtc0) 12 | input bdIn, // exc happens in branch delay slot 13 | input [31:0] DIn, // write data (mfc0 - grf) 14 | input [31:2] PC, // affected pc 15 | input [4:0] ExcCodeIn, // int|excn code 16 | input [5:0] HWInt, // 6 hardware int 17 | input WE, 18 | // input EXLSet, // sr.exl <= 1 (M stage) 19 | input EXLClr, // sr.exl <= 0 (eret) 20 | input clk, 21 | input reset, 22 | output Req, 23 | output [31:0] EPCout, // EPC 24 | output [31:0] Dout // read from cp0 25 | ); 26 | 27 | //////////// Reg 28 | reg [31:0] SR; 29 | reg [31:0] Cause; 30 | reg [31:2] EPCreg; 31 | reg [31:0] PrID; 32 | //////////// EndReg 33 | 34 | wire IntReq = (|(HWInt & `IM)) & !`EXL & `IE; 35 | wire ExcReq = (|ExcCodeIn) & !`EXL; 36 | assign Req = IntReq | ExcReq; 37 | 38 | wire [31:2] tempEPC = (Req) ? (bdIn ? PC[31:2]-1 : PC[31:2]) 39 | : EPCreg; 40 | 41 | assign EPCout = {tempEPC, 2'b0}; 42 | 43 | initial begin 44 | SR <= 0; 45 | Cause <= 0; 46 | EPCreg <= 0; 47 | PrID <= 32'h1937_3189; 48 | end 49 | 50 | assign Dout = (A1 == 12) ? SR: 51 | (A1 == 13) ? Cause: 52 | (A1 == 14) ? EPCout: 53 | (A1 == 15) ? PrID: 54 | 0; 55 | 56 | always@(posedge clk or posedge reset)begin 57 | if(reset)begin 58 | SR <= 0; 59 | Cause <= 0; 60 | EPCreg <= 0; 61 | PrID <= 32'h1937_3189; 62 | end else begin 63 | if (EXLClr) `EXL <= 1'b0; 64 | 65 | if (Req) begin // int|exc 66 | `ExcCode <= IntReq ? 5'b0 : ExcCodeIn; 67 | `EXL <= 1'b1; 68 | EPCreg <= tempEPC; 69 | `BD <= bdIn; 70 | end else if (WE) begin // mtc0 & !(int|exc) 71 | if (A2 == 12) SR <= DIn; 72 | else if (A2 == 14) EPCreg <= DIn[31:2]; 73 | end 74 | `hwint_pend <= HWInt; 75 | end 76 | end 77 | 78 | endmodule 79 | -------------------------------------------------------------------------------- /p7/_CU.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | `include "const.v" 3 | 4 | module _CU ( 5 | input [31:0] instr, 6 | // decode 7 | output [4:0] rs_addr, 8 | output [4:0] rt_addr, 9 | output [4:0] rd_addr, 10 | output [15:0] imm, 11 | output [25:0] addr, 12 | // classify 13 | output load, 14 | output store, 15 | output calc_r, 16 | output calc_i, 17 | output lui, 18 | output shiftS, 19 | output shiftV, 20 | output branch, 21 | output j_r, 22 | output j_addr, 23 | output j_l, 24 | output md, 25 | output mt, 26 | output mf, 27 | // signals 28 | output [2:0] Br, 29 | output [2:0] B_type, 30 | output [2:0] EXTOp, 31 | 32 | output ALUAriOverflow, 33 | output ALUDMOverflow, 34 | output [3:0] ALUControl, 35 | output [1:0] ALUASrc, 36 | output [2:0] ALUBSrc, 37 | output [3:0] HILO_type, 38 | 39 | output [2:0] DMType, 40 | output DMWr, 41 | 42 | output [4:0] RFDst, 43 | output RFWr, 44 | output [2:0] RFWDSrc, 45 | 46 | // CP0 & exceptions 47 | output excRI, 48 | output CP0Wr, 49 | output mfc0, 50 | output mtc0, 51 | output eret 52 | ); 53 | 54 | wire [5:0] opcode = instr[31:26], 55 | func = instr[5:0]; 56 | assign rs_addr = instr[25:21], 57 | rt_addr = instr[20:16], 58 | rd_addr = instr[15:11]; 59 | assign imm = instr[15:0]; 60 | assign addr = instr[25:0]; 61 | 62 | wire lb = (opcode == `OP_lb ); 63 | wire lbu = (opcode == `OP_lbu ); 64 | wire lh = (opcode == `OP_lh ); 65 | wire lhu = (opcode == `OP_lhu ); 66 | wire lw = (opcode == `OP_lw ); 67 | wire sb = (opcode == `OP_sb ); 68 | wire sh = (opcode == `OP_sh ); 69 | wire sw = (opcode == `OP_sw ); 70 | wire addi = (opcode == `OP_addi ); 71 | wire addiu = (opcode == `OP_addiu); 72 | wire andi = (opcode == `OP_andi ); 73 | wire beq = (opcode == `OP_beq ); 74 | wire bgtz = (opcode == `OP_bgtz ); 75 | wire blez = (opcode == `OP_blez ); 76 | wire bgez = (opcode == `OP_bgez && rt_addr == `RT_bgez); 77 | wire bltz = (opcode == `OP_bltz && rt_addr == `RT_bltz); 78 | wire bne = (opcode == `OP_bne ); 79 | wire j = (opcode == `OP_j ); 80 | wire jal = (opcode == `OP_jal ); 81 | wire ori = (opcode == `OP_ori ); 82 | wire slti = (opcode == `OP_slti ); 83 | wire sltiu = (opcode == `OP_sltiu); 84 | wire xori = (opcode == `OP_xori ); 85 | assign lui = (opcode == `OP_lui ); 86 | 87 | wire add = (opcode == `OP_rtype && func == `FUNC_add ); 88 | wire addu = (opcode == `OP_rtype && func == `FUNC_addu ); 89 | wire And = (opcode == `OP_rtype && func == `FUNC_and ); 90 | wire div = (opcode == `OP_rtype && func == `FUNC_div ); 91 | wire divu = (opcode == `OP_rtype && func == `FUNC_divu ); 92 | wire jalr = (opcode == `OP_rtype && func == `FUNC_jalr ); 93 | wire jr = (opcode == `OP_rtype && func == `FUNC_jr ); 94 | wire mfhi = (opcode == `OP_rtype && func == `FUNC_mfhi ); 95 | wire mflo = (opcode == `OP_rtype && func == `FUNC_mflo ); 96 | wire mthi = (opcode == `OP_rtype && func == `FUNC_mthi ); 97 | wire mtlo = (opcode == `OP_rtype && func == `FUNC_mtlo ); 98 | wire mult = (opcode == `OP_rtype && func == `FUNC_mult ); 99 | wire multu = (opcode == `OP_rtype && func == `FUNC_multu); 100 | wire Nor = (opcode == `OP_rtype && func == `FUNC_nor ); 101 | wire Or = (opcode == `OP_rtype && func == `FUNC_or ); 102 | wire sll = (opcode == `OP_rtype && func == `FUNC_sll && (|rd_addr)); 103 | wire sllv = (opcode == `OP_rtype && func == `FUNC_sllv ); 104 | wire slt = (opcode == `OP_rtype && func == `FUNC_slt ); 105 | wire sltu = (opcode == `OP_rtype && func == `FUNC_sltu ); 106 | wire sra = (opcode == `OP_rtype && func == `FUNC_sra ); 107 | wire srav = (opcode == `OP_rtype && func == `FUNC_srav ); 108 | wire srl = (opcode == `OP_rtype && func == `FUNC_srl ); 109 | wire srlv = (opcode == `OP_rtype && func == `FUNC_srlv ); 110 | wire sub = (opcode == `OP_rtype && func == `FUNC_sub ); 111 | wire subu = (opcode == `OP_rtype && func == `FUNC_subu ); 112 | wire Xor = (opcode == `OP_rtype && func == `FUNC_xor ); 113 | 114 | assign mtc0 = (instr[31:21] == `OP_mtc0); 115 | assign mfc0 = (instr[31:21] == `OP_mfc0); 116 | assign eret = (instr == `OP_eret); 117 | 118 | assign load = lw | lh | lhu | lbu | lb; 119 | assign store = sw | sh | sb; 120 | assign branch = beq | bne | blez | bgtz | bgez | bltz; 121 | 122 | assign calc_r = add | addu | sub | subu | slt | sltu | 123 | sll | sllv | srl | srlv | sra | srav | 124 | And | Or | Xor | Nor; // exclude jr & jalr & mt/mf/md 125 | assign calc_i = addi | addiu | andi | ori | xori | 126 | slti | sltiu; // exclude lui 127 | 128 | assign md = mult | multu | div | divu; 129 | assign mt = mtlo | mthi; 130 | assign mf = mflo | mfhi; 131 | 132 | assign shiftS = sll | srl | sra; 133 | assign shiftV = sllv | srlv | srav; 134 | 135 | assign j_r = jr | jalr; 136 | assign j_addr = j | jal; 137 | assign j_l = jal | jalr; 138 | 139 | //////////// Exception 140 | assign excRI = !( beq | bne | bgez | bgtz | blez | bltz | 141 | j | jal | jalr | jr | 142 | lb | lbu | lh | lhu | lw | sb | sh | sw | 143 | lui | addi | addiu | andi | ori | xori | slti | sltiu | 144 | add | addu | sub | subu | And | Nor | Or | Xor | ori | slt | sltu | 145 | sll | sllv | sra | srav | srl | srlv | 146 | ((opcode == 6'b000000) && (func==6'b000000)) | 147 | div | divu | mfhi | mflo | mthi | mtlo | mult | multu | 148 | mtc0 | mfc0 | eret); 149 | assign CP0Wr = mtc0; 150 | 151 | ////////////StageD 152 | assign EXTOp = (addi | addiu | slti | sltiu | load | store) ? `EXT_signed : 153 | lui ? `EXT_lui : 154 | `EXT_unsigned; 155 | // wire unsigned_ext = andi | ori | xori; 156 | assign Br = branch ? `BR_branch : 157 | j_addr ? `BR_addr : 158 | j_r ? `BR_reg : 159 | `BR_pc4; 160 | assign B_type = beq ? `B_beq : 161 | bne ? `B_bne : 162 | blez ? `B_blez : 163 | bgez ? `B_bgez : 164 | bgtz ? `B_bgtz : 165 | bltz ? `B_bltz : 166 | `B_beq; 167 | 168 | ////////////StageE 169 | assign ALUAriOverflow = add | addi | sub; 170 | assign ALUDMOverflow = lb | lbu | lh | lhu | lw | sb | sh | sw; 171 | assign ALUControl = (sub | subu) ? `ALU_sub : 172 | (And | andi) ? `ALU_and : 173 | (Or | ori) ? `ALU_or : 174 | (Xor | xori) ? `ALU_xor : 175 | (Nor) ? `ALU_nor : 176 | (sll | sllv) ? `ALU_sll : 177 | (srl | srlv) ? `ALU_srl : 178 | (sra | srav) ? `ALU_sra : 179 | (slt | slti) ? `ALU_slt : 180 | (sltu | sltiu) ? `ALU_sltu : 181 | `ALU_add; 182 | assign ALUASrc = (shiftS | shiftV) ? `ALUASrcRT : `ALUASrcRS; 183 | assign ALUBSrc = shiftS ? `ALUBSrcShamt : 184 | shiftV ? `ALUBSrcRS_4_0 : 185 | (calc_r && !shiftS && !shiftV) ? `ALUBSrcRT : 186 | (calc_i | lui | load | store) ? `ALUBSrcExt : 187 | `ALUBSrcRT; 188 | assign HILO_type = mult ? `HILO_mult : 189 | multu ? `HILO_multu : 190 | div ? `HILO_div : 191 | divu ? `HILO_divu : 192 | mflo ? `HILO_mflo : 193 | mfhi ? `HILO_mfhi : 194 | mtlo ? `HILO_mtlo : 195 | mthi ? `HILO_mthi : 196 | `HILO_none; 197 | 198 | ////////////StageM 199 | assign DMType = (lw || sw) ? `DM_w : 200 | (lh || sh) ? `DM_h : 201 | (lhu) ? `DM_hu : 202 | (lb || sb) ? `DM_b : 203 | (lbu) ? `DM_bu : 204 | `DM_err; 205 | assign DMWr = store; 206 | 207 | ////////////StageW 208 | assign RFDst = (calc_r | jalr | mf) ? rd_addr : 209 | (calc_i | lui | load | mfc0) ? rt_addr : 210 | (jal) ? 5'd31 : 211 | 5'd0; 212 | assign RFWr = !(!RFDst); 213 | assign RFWDSrc = load ? `RFWD_DMout : 214 | (jal | jalr) ? `RFWD_PC8 : 215 | lui ? `RFWD_EXTout : 216 | mf ? `RFWD_HILOout : 217 | mfc0 ? `RFWD_CP0 : 218 | `RFWD_ALUout; 219 | endmodule -------------------------------------------------------------------------------- /p7/_SU.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | `include "const.v" 3 | 4 | module _SU ( 5 | input [31:0] D_instr, 6 | input [31:0] E_instr, 7 | input [31:0] M_instr, 8 | input E_HILObusy, 9 | output stall 10 | ); 11 | /////////////////////// StageD 12 | wire D_calc_r, D_calc_i, D_load, D_store, D_shiftS, D_j_r, D_j_noreg, D_branch, D_mt, D_mf, D_md; 13 | wire D_mfc0, D_mtc0, D_eret, E_mfc0, E_mtc0, E_eret, M_mfc0, M_mtc0, M_eret; 14 | wire [4:0] D_rs_addr, D_rt_addr; 15 | wire [31:0] D_type; 16 | _CU _DInterp ( 17 | .instr(D_instr), 18 | .rs_addr(D_rs_addr), 19 | .rt_addr(D_rt_addr), 20 | .calc_r(D_calc_r), 21 | .calc_i(D_calc_i), 22 | .load(D_load), 23 | .store(D_store), 24 | .j_r(D_j_r), 25 | .shiftS(D_shiftS), 26 | .branch(D_branch), 27 | .md(D_md), 28 | .mt(D_mt), 29 | .mf(D_mf), 30 | .mfc0(D_mfc0), 31 | .mtc0(D_mtc0), 32 | .eret(D_eret) 33 | ); 34 | 35 | wire [2:0] TuseRS = (D_branch | D_j_r) ? 3'd0 : 36 | ((D_calc_r & !D_shiftS) | D_calc_i | D_load | D_store | D_md | D_mt) ? 3'd1 : 37 | 3'd3; 38 | wire [2:0] TuseRT = D_branch ? 3'd0 : 39 | (D_calc_r | D_md) ? 3'd1 : 40 | (D_store | D_mtc0) ? 3'd2 : 41 | 3'd3; 42 | 43 | /////////////////////// StageE 44 | wire [31:0] E_type; 45 | wire E_calc_r, E_calc_i, E_load, E_mf; 46 | wire [4:0] E_RFDst, E_rd_addr; 47 | _CU _EInterp ( 48 | .instr(E_instr), 49 | .rd_addr(E_rd_addr), 50 | .calc_r(E_calc_r), 51 | .calc_i(E_calc_i), 52 | .load(E_load), 53 | .RFDst(E_RFDst), 54 | .mf(E_mf), 55 | .mfc0(E_mfc0), 56 | .mtc0(E_mtc0), 57 | .eret(E_eret) 58 | ); 59 | 60 | wire [2:0] TnewE = E_calc_r | E_calc_i | E_mf ? 3'd1 : 61 | (E_load | E_mfc0) ? 3'd2 : 62 | 3'd0; 63 | 64 | /////////////////////// StageM 65 | wire [31:0] M_type; 66 | wire M_load, M_calc_r, M_calc_i; 67 | wire [4:0] M_RFDst, M_rd_addr; 68 | _CU _MInterp ( 69 | .instr(M_instr), 70 | .load(M_load), 71 | .calc_r(M_calc_r), 72 | .calc_i(M_calc_i), 73 | .RFDst(M_RFDst), 74 | .mfc0(M_mfc0), 75 | .mtc0(M_mtc0), 76 | .eret(M_eret), 77 | .rd_addr(M_rd_addr) 78 | ); 79 | 80 | wire [2:0] TnewM = (M_load | M_mfc0) ? 3'd1 : 81 | 3'd0; 82 | 83 | // Tuse < Tnew 84 | wire stall_rs_e = (TuseRS < TnewE) && (D_rs_addr && D_rs_addr == E_RFDst); 85 | wire stall_rs_m = (TuseRS < TnewM) && (D_rs_addr && D_rs_addr == M_RFDst); 86 | wire stall_rs = stall_rs_e | stall_rs_m; 87 | 88 | wire stall_rt_e = (TuseRT < TnewE) && (D_rt_addr && D_rt_addr == E_RFDst); 89 | wire stall_rt_m = (TuseRT < TnewM) && (D_rt_addr && D_rt_addr == M_RFDst); 90 | wire stall_rt = stall_rt_e | stall_rt_m; 91 | 92 | wire stall_HILO = E_HILObusy & (D_md | D_mt | D_mf); 93 | 94 | wire stall_eret = D_eret & ((E_mtc0 & (E_rd_addr == 5'd14)) || (M_mtc0 & (M_rd_addr == 5'd14))); 95 | 96 | assign stall = stall_rs | stall_rt | stall_HILO | stall_eret; 97 | 98 | endmodule -------------------------------------------------------------------------------- /p7/const.v: -------------------------------------------------------------------------------- 1 | //// Instr 2 | `define OP_rtype 6'b000000 3 | `define OP_lb 6'b100000 4 | `define OP_lbu 6'b100100 5 | `define OP_lh 6'b100001 6 | `define OP_lhu 6'b100101 7 | `define OP_lw 6'b100011 8 | `define OP_sb 6'b101000 9 | `define OP_sh 6'b101001 10 | `define OP_sw 6'b101011 11 | `define OP_addi 6'b001000 12 | `define OP_addiu 6'b001001 13 | `define OP_andi 6'b001100 14 | `define OP_beq 6'b000100 15 | `define OP_bgez 6'b000001 16 | `define OP_bgtz 6'b000111 17 | `define OP_blez 6'b000110 18 | `define OP_bltz 6'b000001 19 | `define OP_bne 6'b000101 20 | `define OP_j 6'b000010 21 | `define OP_jal 6'b000011 22 | `define OP_lui 6'b001111 23 | `define OP_ori 6'b001101 24 | `define OP_slti 6'b001010 25 | `define OP_sltiu 6'b001011 26 | `define OP_xori 6'b001110 27 | 28 | `define FUNC_add 6'b100000 29 | `define FUNC_addu 6'b100001 30 | `define FUNC_and 6'b100100 31 | `define FUNC_div 6'b011010 32 | `define FUNC_divu 6'b011011 33 | `define FUNC_jalr 6'b001001 34 | `define FUNC_jr 6'b001000 35 | `define FUNC_mfhi 6'b010000 36 | `define FUNC_mflo 6'b010010 37 | `define FUNC_mthi 6'b010001 38 | `define FUNC_mtlo 6'b010011 39 | `define FUNC_mult 6'b011000 40 | `define FUNC_multu 6'b011001 41 | `define FUNC_nor 6'b100111 42 | `define FUNC_or 6'b100101 43 | `define FUNC_sll 6'b000000 44 | `define FUNC_sllv 6'b000100 45 | `define FUNC_slt 6'b101010 46 | `define FUNC_sltu 6'b101011 47 | `define FUNC_sra 6'b000011 48 | `define FUNC_srav 6'b000111 49 | `define FUNC_srl 6'b000010 50 | `define FUNC_srlv 6'b000110 51 | `define FUNC_sub 6'b100010 52 | `define FUNC_subu 6'b100011 53 | `define FUNC_xor 6'b100110 54 | 55 | `define RT_bltz 5'b00000 56 | `define RT_bgez 5'b00001 57 | 58 | `define OP_mtc0 11'b010000_00100 59 | `define OP_mfc0 11'b010000_00000 60 | `define OP_eret 32'b010000_1000_0000_0000_0000_0000_011000 61 | 62 | //// CU Signal 63 | 64 | // ALU 65 | `define ALU_add 4'd0 66 | `define ALU_sub 4'd1 67 | `define ALU_and 4'd2 68 | `define ALU_or 4'd3 69 | `define ALU_xor 4'd4 70 | `define ALU_nor 4'd5 71 | `define ALU_sll 4'd6 72 | `define ALU_srl 4'd7 73 | `define ALU_sra 4'd8 74 | `define ALU_slt 4'd9 75 | `define ALU_sltu 4'd10 76 | `define ALU_lui 4'd11 77 | 78 | // DM 79 | `define DM_w 3'b000 80 | `define DM_h 3'b001 81 | `define DM_hu 3'b010 82 | `define DM_b 3'b011 83 | `define DM_bu 3'b100 84 | `define DM_err 3'b101 85 | 86 | // Branch 87 | `define BR_pc4 3'b000 88 | `define BR_addr 3'b001 89 | `define BR_reg 3'b010 90 | `define BR_branch 3'b011 91 | 92 | // B_type 93 | `define B_beq 3'd0 94 | `define B_bne 3'd1 95 | `define B_blez 3'd2 96 | `define B_bgtz 3'd3 97 | `define B_bgez 3'd4 98 | `define B_bltz 3'd5 99 | 100 | // RFWDSel 101 | `define RFWD_ALUout 3'b000 102 | `define RFWD_DMout 3'b001 103 | `define RFWD_PC8 3'b010 104 | `define RFWD_HILOout 3'b011 105 | `define RFWD_EXTout 3'b100 106 | `define RFWD_CP0 3'b101 107 | 108 | // ALUASrc 109 | `define ALUASrcRT 2'b00 110 | `define ALUASrcRS 2'b01 111 | 112 | // ALUBSrc 113 | `define ALUBSrcShamt 3'd0 114 | `define ALUBSrcRS_4_0 3'd1 115 | `define ALUBSrcRT 3'd2 116 | `define ALUBSrcExt 3'd3 117 | 118 | // HILOType 119 | `define HILO_none 4'd0 120 | `define HILO_mult 4'd1 121 | `define HILO_multu 4'd2 122 | `define HILO_div 4'd3 123 | `define HILO_divu 4'd4 124 | `define HILO_mflo 4'd5 125 | `define HILO_mfhi 4'd6 126 | `define HILO_mtlo 4'd7 127 | `define HILO_mthi 4'd8 128 | 129 | // EXT 130 | `define EXT_unsigned 3'd0 131 | `define EXT_signed 3'd1 132 | `define EXT_lui 3'd2 133 | 134 | // Exceptions 135 | `define EXC_INT 5'd0 136 | `define EXC_AdEL 5'd4 137 | `define EXC_AdES 5'd5 138 | `define EXC_RI 5'd10 139 | `define EXC_Ov 5'd12 140 | `define EXC_None 5'd0 -------------------------------------------------------------------------------- /p7/mips.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | `define StartAddrTC1 32'h0000_7f00 3 | `define EndAddrTC1 32'h0000_7f0b 4 | `define StartAddrTC2 32'h0000_7f10 5 | `define EndAddrTC2 32'h0000_7f1b 6 | `define RAddr {PrAddr, 2'b0} 7 | 8 | module mips( 9 | input clk, 10 | input reset, 11 | input interrupt, 12 | output [31:0] addr 13 | ); 14 | 15 | wire PrWE; 16 | wire [31:0] PrWD, PrRD, M_pc; 17 | wire [31:2] PrAddr; 18 | 19 | CPU CPU( 20 | .clk(clk), 21 | .reset(reset), 22 | .HWInt(HWInt), 23 | .PrRD(PrRD), 24 | .PrWE(PrWE), 25 | .PrAddr(PrAddr), 26 | .PrWD(PrWD), 27 | .M_PCout(M_pc) 28 | ); 29 | 30 | assign addr = M_pc; 31 | 32 | // Timer 33 | wire selTC1 = (`RAddr >= `StartAddrTC1) && (`RAddr <= `EndAddrTC1), 34 | selTC2 = (`RAddr >= `StartAddrTC2) && (`RAddr <= `EndAddrTC2); 35 | wire TCwe1 = selTC1 && PrWE, 36 | TCwe2 = selTC2 && PrWE; 37 | wire [31:0] TCout1, TCout2; 38 | wire IRQ1, IRQ2; 39 | assign PrRD = selTC1 ? TCout1 : 40 | selTC2 ? TCout2 : 41 | 0; 42 | wire [5:0] HWInt = {3'b0, interrupt, IRQ2, IRQ1}; 43 | 44 | TC TC1( 45 | .clk(clk), 46 | .reset(reset), 47 | .Addr(PrAddr), 48 | .WE(TCwe1), 49 | .Din(PrWD), 50 | .pc(M_pc), 51 | .Dout(TCout1), 52 | .IRQ(IRQ1) 53 | ); 54 | 55 | TC TC2( 56 | .clk(clk), 57 | .reset(reset), 58 | .Addr(PrAddr), 59 | .WE(TCwe2), 60 | .Din(PrWD), 61 | .pc(M_pc), 62 | .Dout(TCout2), 63 | .IRQ(IRQ2) 64 | ); 65 | 66 | endmodule 67 | -------------------------------------------------------------------------------- /p7/mips_tb.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns/1ps 2 | 3 | module mips_tb; 4 | 5 | wire [31:0] addr; 6 | reg clk,reset,interrupt; 7 | integer interruptCounter; 8 | reg [31:0] interruptAddress[0:63]; 9 | 10 | mips uut( 11 | .clk(clk),.reset(reset), 12 | .interrupt(interrupt), 13 | .addr(addr) 14 | ); 15 | 16 | initial begin 17 | clk<=0; reset<=1; 18 | interruptCounter<=0; interrupt<=0; 19 | interruptAddress[0]<=32'h0000308c; interruptAddress[1]<=32'h000030c0; interruptAddress[2]<=32'h000030f8; 20 | interruptAddress[3]<=32'h0000312c; interruptAddress[4]<=32'h0000315c; interruptAddress[5]<=32'h00003190; 21 | interruptAddress[6]<=32'h000031c0; interruptAddress[7]<=32'h000031f0; interruptAddress[8]<=32'h00003224; 22 | interruptAddress[9]<=32'h00003258; interruptAddress[10]<=32'h00003290; interruptAddress[11]<=32'h000032c8; 23 | interruptAddress[12]<=32'h000032f8; interruptAddress[13]<=32'h00003334; interruptAddress[14]<=32'h0000336c; 24 | interruptAddress[15]<=32'h000041b4; 25 | #10; reset<=0; 26 | end 27 | always @(negedge clk) begin 28 | if (reset) interrupt<=0; 29 | else if (interrupt) begin 30 | if (interruptCounter==0) interrupt<=0; 31 | else interruptCounter<=interruptCounter-1; 32 | end 33 | else if (addr==interruptAddress[0]) begin interruptAddress[0]<=32'h7f7f7f7f; interruptCounter<=5; interrupt<=1; end 34 | else if (addr==interruptAddress[1]) begin interruptAddress[1]<=32'h7f7f7f7f; interruptCounter<=5; interrupt<=1; end 35 | else if (addr==interruptAddress[2]) begin interruptAddress[2]<=32'h7f7f7f7f; interruptCounter<=5; interrupt<=1; end 36 | else if (addr==interruptAddress[3]) begin interruptAddress[3]<=32'h7f7f7f7f; interruptCounter<=5; interrupt<=1; end 37 | else if (addr==interruptAddress[4]) begin interruptAddress[4]<=32'h7f7f7f7f; interruptCounter<=5; interrupt<=1; end 38 | else if (addr==interruptAddress[5]) begin interruptAddress[5]<=32'h7f7f7f7f; interruptCounter<=5; interrupt<=1; end 39 | else if (addr==interruptAddress[6]) begin interruptAddress[6]<=32'h7f7f7f7f; interruptCounter<=5; interrupt<=1; end 40 | else if (addr==interruptAddress[7]) begin interruptAddress[7]<=32'h7f7f7f7f; interruptCounter<=5; interrupt<=1; end 41 | else if (addr==interruptAddress[8]) begin interruptAddress[8]<=32'h7f7f7f7f; interruptCounter<=5; interrupt<=1; end 42 | else if (addr==interruptAddress[9]) begin interruptAddress[9]<=32'h7f7f7f7f; interruptCounter<=5; interrupt<=1; end 43 | else if (addr==interruptAddress[10]) begin interruptAddress[10]<=32'h7f7f7f7f; interruptCounter<=5; interrupt<=1; end 44 | else if (addr==interruptAddress[11]) begin interruptAddress[11]<=32'h7f7f7f7f; interruptCounter<=5; interrupt<=1; end 45 | else if (addr==interruptAddress[12]) begin interruptAddress[12]<=32'h7f7f7f7f; interruptCounter<=5; interrupt<=1; end 46 | else if (addr==interruptAddress[13]) begin interruptAddress[13]<=32'h7f7f7f7f; interruptCounter<=5; interrupt<=1; end 47 | else if (addr==interruptAddress[14]) begin interruptAddress[14]<=32'h7f7f7f7f; interruptCounter<=5; interrupt<=1; end 48 | else if (addr==interruptAddress[15]) begin interruptAddress[15]<=32'h7f7f7f7f; interruptCounter<=5; interrupt<=1; end 49 | else begin end 50 | end 51 | 52 | always #5 clk<=~clk; 53 | 54 | endmodule -------------------------------------------------------------------------------- /p7/tb.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | 3 | module tb; 4 | reg clk; 5 | reg reset; 6 | 7 | wire [31:0] addr; 8 | 9 | mips uut ( 10 | .clk(clk), 11 | .reset(reset), 12 | .interrupt(1'b0), 13 | .addr(addr) 14 | ); 15 | 16 | initial begin 17 | clk = 0; 18 | reset = 1; 19 | #20 reset = 0; 20 | end 21 | always #2 clk = ~clk; 22 | endmodule 23 | 24 | -------------------------------------------------------------------------------- /p7/timer.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | `define IDLE 2'b00 3 | `define LOAD 2'b01 4 | `define CNT 2'b10 5 | `define INT 2'b11 6 | 7 | `define ctrl mem[0] 8 | `define preset mem[1] 9 | `define count mem[2] 10 | 11 | module TC( 12 | input clk, 13 | input reset, 14 | input [31:2] Addr, 15 | input WE, 16 | input [31:0] Din, 17 | input [31:0] pc, 18 | output [31:0] Dout, 19 | output IRQ 20 | ); 21 | 22 | reg [1:0] state; 23 | reg [31:0] mem [2:0]; 24 | 25 | reg _IRQ; 26 | assign IRQ = `ctrl[3] & _IRQ; 27 | 28 | assign Dout = mem[Addr[3:2]]; 29 | 30 | wire [31:0] load = Addr[3:2] == 0 ? {28'h0, Din[3:0]} : Din; 31 | 32 | integer i; 33 | always @(posedge clk) begin 34 | if(reset) begin 35 | state <= 0; 36 | for(i = 0; i < 3; i = i+1) mem[i] <= 0; 37 | _IRQ <= 0; 38 | end 39 | else if(WE) begin 40 | //$display("%d@%h: *%h <= %h", $time, pc, {Addr, 2'b00}, load); 41 | mem[Addr[3:2]] <= load; 42 | end 43 | else begin // changed for test 44 | case(state) 45 | `IDLE : if(`ctrl[0]) begin 46 | state <= `LOAD; 47 | _IRQ <= 1'b0; 48 | end 49 | `LOAD : begin 50 | `count <= `preset; 51 | state <= `CNT; 52 | end 53 | `CNT : 54 | if(`ctrl[0]) begin 55 | if(`count > 1) `count <= `count-1; 56 | else begin 57 | `count <= 0; 58 | state <= `INT; 59 | _IRQ <= 1'b1; 60 | end 61 | end 62 | else state <= `IDLE; 63 | default : begin 64 | if(`ctrl[2:1] == 2'b00) `ctrl[0] <= 1'b0; 65 | else _IRQ <= 1'b0; 66 | state <= `IDLE; 67 | end 68 | endcase 69 | end 70 | end 71 | 72 | endmodule 73 | -------------------------------------------------------------------------------- /partial-pre/cpu_checker.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | `define S0 4'b0000 3 | `define S1 4'b0001 4 | `define S2 4'b0010 5 | `define S3 4'b0011 6 | `define S4 4'b0100 7 | `define S5 4'b0101 8 | `define S6 4'b0110 9 | `define S7 4'b0111 10 | `define S8 4'b1000 11 | `define S9 4'b1001 12 | `define S10 4'b1010 13 | `define S11 4'b1011 14 | `define S12 4'b1100 15 | `define S13 4'b1101 16 | `define S14 4'b1110 17 | `define S15 4'b1111 18 | 19 | `define OERROR 2'b00 20 | `define O1 2'b01 21 | `define O2 2'b10 22 | 23 | `define ERR0 4'b0000 24 | `define ERR1 4'b0001 25 | `define ERR2 4'b0010 26 | `define ERR3 4'b0100 27 | `define ERR4 4'b1000 28 | 29 | module cpu_checker( 30 | input clk, 31 | input reset, 32 | input [7:0] char, 33 | input [15:0] freq, 34 | output reg [1:0] format_type, 35 | output reg [3:0] error_code 36 | ); 37 | 38 | reg [1:0] cur; 39 | reg [3:0] status, reg_error; 40 | reg [31:0] count, num; 41 | 42 | initial begin 43 | format_type <= 2'b00; 44 | count <= 0; 45 | status <= `S0; 46 | cur <= 0; 47 | reg_error <= 0; 48 | error_code <= 0; 49 | num <= 0; 50 | end 51 | 52 | always @(posedge clk) begin 53 | if (reset) begin 54 | format_type <= 2'b00; 55 | count <= 0; 56 | status <= `S0; 57 | cur <= 0; 58 | reg_error <= 0; 59 | error_code <= 0; 60 | num <= 0; 61 | end 62 | else begin 63 | case (status) 64 | `S0: begin 65 | format_type <= `OERROR; 66 | reg_error <= 0; 67 | error_code <= 0; 68 | 69 | if(char == "^") begin 70 | status <= `S15; 71 | num <= 0; 72 | end 73 | else status <= `S0; 74 | end 75 | 76 | `S15: begin 77 | if(char >= "0" && char <= "9") begin 78 | status <= `S1; 79 | count <= 1; 80 | num <= char ^ 48; 81 | end 82 | else status <= `S0; 83 | end 84 | 85 | `S1: begin 86 | if(char >= "0" && char <= "9") begin 87 | count <= count + 1; 88 | num <= (num << 1) + (num << 3) + (char ^ 48); 89 | end 90 | else if(char == "@" && count <= 4) begin 91 | status <= `S2; 92 | 93 | if((num & ((freq >> 1) - 1)) != 0) reg_error <= reg_error | `ERR1; 94 | end 95 | else status <= `S0; 96 | end 97 | 98 | `S2: begin 99 | if((char >= "0" && char <= "9") || (char >= "a" && char <= "f")) begin 100 | status <= `S3; 101 | count <= 1; 102 | if(char >= "0" && char <= "9") num <= char ^ 48; 103 | else num <= (char ^ "`") + 9; 104 | end 105 | else status <= `S0; 106 | end 107 | 108 | `S3: begin 109 | if((char >= "0" && char <= "9") || (char >= "a" && char <= "f")) begin 110 | count = count + 1; 111 | if(char >= "0" && char <= "9") num <= (num << 4) + (char ^ 48); 112 | else num <= (num << 4) + (char ^ "`") + 9; 113 | end 114 | else if(char == ":" && count == 8) begin 115 | status <= `S4; 116 | 117 | if ((num & 2'b11) != 0 || !(num >= 32'h0000_3000 && num <= 32'h0000_4fff)) reg_error <= reg_error | `ERR2; 118 | end 119 | else status <= `S0; 120 | end 121 | 122 | `S4: begin 123 | if(char == " ") begin 124 | status <= `S4; 125 | end 126 | else if(char == "$") begin 127 | cur <= `O1; 128 | status <= `S5; 129 | end 130 | else if(char == 8'd42) begin 131 | cur <= `O2; 132 | status <= `S11; 133 | end 134 | else status <= `S0; 135 | end 136 | 137 | `S5: begin 138 | if(char >= "0" && char <= "9") begin 139 | status <= `S6; 140 | count <= 1; 141 | num <= char ^ 48; 142 | end 143 | else status <= `S0; 144 | end 145 | 146 | `S6: begin 147 | if(char >= "0" && char <= "9") begin 148 | count <= count + 1; 149 | num <= (num << 1) + (num << 3) + (char ^ 48); 150 | end 151 | else if(char == " " && count <= 4) begin 152 | status <= `S7; 153 | 154 | if(!(num >= 0 && num <= 31)) reg_error <= reg_error | `ERR4; 155 | end 156 | else if(char == "<" && count <= 4) begin 157 | status <= `S8; 158 | 159 | if(!(num >= 0 && num <= 31)) reg_error <= reg_error | `ERR4; 160 | end 161 | else status <= `S0; 162 | end 163 | 164 | `S7: begin 165 | if(char == " ") begin 166 | status <= `S7; 167 | end 168 | else if(char == "<") begin 169 | status <= `S8; 170 | end 171 | else status <= `S0; 172 | end 173 | 174 | `S8: begin 175 | if(char == "=") begin 176 | status <= `S9; 177 | end 178 | else status <= `S0; 179 | end 180 | 181 | `S9: begin 182 | if(char == " ") begin 183 | status <= `S9; 184 | end 185 | else if((char >= "0" && char <= "9") || (char >= "a" && char <= "f")) begin 186 | count <= 1; 187 | status <= `S10; 188 | if(char >= "0" && char <= "9") num <= char ^ 48; 189 | else num <= (char ^ "`") + 9; 190 | end 191 | else status <= `S0; 192 | end 193 | 194 | `S10: begin 195 | if((char >= "0" && char <= "9") || (char >= "a" && char <= "f")) begin 196 | count <= count + 1; 197 | if(char >= "0" && char <= "9") num <= (num << 4) + (char ^ 48); 198 | else num <= (num << 4) + (char ^ "`") + 9; 199 | end 200 | else if(char == "#" && count == 8) begin 201 | format_type <= cur; 202 | status <= `S0; 203 | error_code <= reg_error; 204 | end 205 | else status <= `S0; 206 | end 207 | 208 | `S11: begin 209 | if((char >= "0" && char <= "9") || (char >= "a" && char <= "f")) begin 210 | status <= `S12; 211 | count <= 1; 212 | if(char >= "0" && char <= "9") num <= char ^ 48; 213 | else num <= (char ^ "`") + 9; 214 | end 215 | else status <= `S0; 216 | end 217 | 218 | `S12: begin 219 | if((char >= "0" && char <= "9") || (char >= "a" && char <= "f")) begin 220 | count <= count + 1; 221 | if(char >= "0" && char <= "9") num <= (num << 4) + (char ^ 48); 222 | else num <= (num << 4) + (char ^ "`") + 9; 223 | end 224 | else if(char == " " && count == 8) begin 225 | status <= `S7; 226 | 227 | if((num & 3) != 0 || !(num >= 32'h0000_0000 && num <= 32'h0000_2fff)) reg_error <= reg_error | `ERR3; 228 | end 229 | else if(char == "<" && count == 8) begin 230 | status <= `S8; 231 | 232 | if((num & 3) != 0 || !(num >= 32'h0000_0000 && num <= 32'h0000_2fff)) reg_error <= reg_error | `ERR3; 233 | end 234 | else status <= `S0; 235 | end 236 | endcase 237 | end 238 | end 239 | 240 | endmodule 241 | -------------------------------------------------------------------------------- /partial-pre/fib.circ: -------------------------------------------------------------------------------- 1 | 2 | 3 | This file is intended to be loaded by Logisim (http://www.cburch.com/logisim/). 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | -------------------------------------------------------------------------------- /partial-pre/swap.circ: -------------------------------------------------------------------------------- 1 | 2 | 3 | This file is intended to be loaded by Logisim (http://www.cburch.com/logisim/). 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | --------------------------------------------------------------------------------