P4 - Verilog單週期CPU
阿新 • • 發佈:2018-12-31
1 module mips( 2 input clk, 3 input reset 4 ); 5 6 wire [31:0] PC,nPC,PC_4; 7 wire [31:0] Instr; 8 wire [31:0] RD1,RD2,WD; 9 wire [31:0] ALU_B,ALUResult; 10 wire Zero; 11 wire [31:0] EXTResult,DMResult; 12 wire [4:0] WriteReg; 13 14 wire RegWrite,ALUSrc,MemWrite;15 wire [1:0] RegDst; 16 wire [1:0] MemtoReg; 17 wire [1:0] MemDst; 18 wire [1:0] ExtOp; 19 wire [2:0] nPCOp; 20 wire [3:0] ALUOp; 21 22 PC PC_p4 (.Clk(clk), .Reset(reset), .nPC(nPC), .PC(PC)); 23 IM IM_p4 (.PC(PC[11:2]), .Instr(Instr));24 25 ctrl ctrl_p4 (.Op(Instr[31:26]), .Func(Instr[5:0]), 26 .RegDst(RegDst), .ExtOp(ExtOp), .ALUOp(ALUOp), .nPCOp(nPCOp), .MemtoReg(MemtoReg), .MemDst(MemDst), 27 .RegWrite(RegWrite), .ALUSrc(ALUSrc), .MemWrite(MemWrite));28 29 mux_3_5 MUX_RegDst (.a(Instr[20:16]), .b(Instr[15:11]), .c(5'h1f), .select(RegDst), .y(WriteReg)); 30 31 GRF GRF_p4 (.Clk(clk), .Reset(reset), .WE(RegWrite), .A1(Instr[25:21]), .A2(Instr[20:16]), .A3(WriteReg), .WD(WD), .WPC(PC), .RD1(RD1), .RD2(RD2)); 32 33 mux_2_32 MUX_ALUSrc (.a(RD2), .b(EXTResult), .select(ALUSrc), .y(ALU_B)); 34 35 ALU ALU_p4 (.A(RD1), .B(ALU_B), .ALUOp(ALUOp), .Zero(Zero), .Result(ALUResult)); 36 DM DM_p4 (.Clk(clk), .Reset(reset), .WE(MemWrite), .MemDst(MemDst), .A(ALUResult[11:0]), .WD(RD2), .pc(PC), .addr(ALUResult), .RD(DMResult)); 37 38 mux_3_32 MUX_MemtoReg (.a(ALUResult), .b(DMResult), .c(PC_4), .select(MemtoReg), .y(WD)); 39 40 EXT EXT_p4 (.Imm_16(Instr[15:0]), .ExtOp(ExtOp), .Imm_32(EXTResult)); 41 nPC nPC_p4 (.Instr(Instr[25:0]), .pc(PC), .rs(ALUResult), .Zero(Zero), .nPCOp(nPCOp), .npc(nPC), .pc_4(PC_4)); 42 43 endmodule
1 module PC( 2 input Clk, 3 input Reset, 4 input [31:0] nPC, 5 output reg[31:0] PC 6 ); 7 8 initial begin 9 PC <= 32'h0000_3000; 10 end 11 12 always @ (posedge Clk) begin 13 if(Reset == 1) PC <= 32'h0000_3000; 14 else PC <= nPC; 15 end 16 17 endmodule
1 module IM( 2 input [11:2] PC, 3 output [31:0] Instr 4 ); 5 6 reg [31:0] memory [1023:0]; 7 integer i; 8 9 initial begin 10 for(i = 0; i < 1024; i = i + 1) 11 memory[i] = 32'h0; 12 $readmemh("code.txt",memory); 13 end 14 15 assign Instr = memory[PC]; 16 17 endmodule
1 module nPC( 2 input [25:0] Instr, 3 input [31:0] pc, 4 input [31:0] rs, 5 input Zero, 6 input [2:0] nPCOp, 7 output [31:0] npc, 8 output [31:0] pc_4 9 ); 10 11 wire [15:0] offset; 12 parameter other = 3'b000, 13 beq = 3'b001, 14 jal = 3'b010, 15 jr = 3'b011; 16 17 assign offset = Instr[15:0]; 18 19 assign pc_4 = pc + 4; 20 21 assign npc = (nPCOp == other) ? pc_4 : 22 (nPCOp == beq && Zero == 1) ? pc_4 + {{14{offset[15]}},offset,2'b00} : 23 (nPCOp == jal) ? {pc[31:28],Instr,2'b0} : 24 (nPCOp == jr) ? rs : 25 pc_4; 26 27 endmodule
1 module GRF( 2 input Clk, 3 input Reset, 4 input WE, 5 input [4:0] A1, 6 input [4:0] A2, 7 input [4:0] A3, 8 input [31:0] WD, 9 input [31:0] WPC, 10 output [31:0] RD1, 11 output [31:0] RD2 12 ); 13 14 reg [31:0] register[31:0]; 15 integer i; 16 17 assign RD1 = register[A1]; 18 assign RD2 = register[A2]; 19 20 always @ (posedge Clk) begin 21 if(Reset==1) 22 for(i = 0; i < 32; i = i + 1) 23 register[i] <= 32'h0; 24 else if(WE == 1 && A3 != 5'b0) begin 25 register[A3] <= WD; 26 $display("@%h: $%d <= %h", WPC, A3,WD); 27 end 28 end 29 30 endmodule
1 module EXT( 2 input [15:0] Imm_16, 3 input [1:0] ExtOp, 4 output [31:0] Imm_32 5 ); 6 7 parameter sign = 2'b00, 8 zero = 2'b01, 9 high = 2'b10, 10 sign_left_2 = 2'b11; 11 12 assign Imm_32 = (ExtOp == sign) ? {{16{Imm_16[15]}},Imm_16} : 13 (ExtOp == zero) ? {{16'b0}, Imm_16} : 14 (ExtOp == high) ? {Imm_16,{16'b0}} : 15 {{14{Imm_16[15]}},Imm_16,2'b00}; 16 17 endmodule
1 module ALU( 2 input [31:0] A, 3 input [31:0] B, 4 input [3:0] ALUOp, 5 output Zero, 6 output [31:0] Result 7 ); 8 9 parameter addu = 4'b0000, 10 subu = 4'b0001, 11 orr = 4'b0010; 12 13 assign Result = (ALUOp == addu) ? (A + B) : 14 (ALUOp == subu) ? (A - B) : 15 (A | B); 16 17 assign Zero = (A - B == 0) ? 1 : 0; 18 19 20 endmodule
1 module DM( 2 input Clk, 3 input Reset, 4 input WE, 5 input [1:0] MemDst, 6 input [11:0] A, 7 input [31:0] WD, 8 input [31:0] pc, 9 input [31:0] addr, 10 output[31:0] RD 11 ); 12 13 reg [7:0] memory[4095:0]; 14 integer i; 15 parameter w = 2'b00, 16 h = 2'b01, 17 b = 2'b10; 18 19 assign RD = (MemDst == w) ? {memory[A+3],memory[A+2],memory[A+1],memory[A]} : 20 (MemDst == h) ? {{16{memory[A+1][7]}},memory[A+1],memory[A]} : 21 {{24{memory[A][7]}},memory[A]}; 22 23 always @ (posedge Clk) begin 24 if(Reset == 1) 25 for(i = 0; i < 4095; i = i + 1) 26 memory[i] = 7'h0; 27 else if(WE == 1) begin 28 case(MemDst) 29 w: begin 30 {memory[A+3],memory[A+2],memory[A+1],memory[A]} = WD; 31 $display("@%h: *%h <= %h",pc, addr,{memory[A+3],memory[A+2],memory[A+1],memory[A]}); 32 end 33 h: begin 34 {memory[A+1],memory[A]} = WD[15:0]; 35 $display("@%h: *%h <= %h",pc, addr,{memory[A+3],memory[A+2],memory[A+1],memory[A]}); 36 end 37 b: begin 38 memory[A] = WD[7:0]; 39 $display("@%h: *%h <= %h",pc, addr,{memory[A+3],memory[A+2],memory[A+1],memory[A]}); 40 end 41 endcase 42 end 43 end 44 45 endmodule
1 module mux_2_32( 2 input [31:0] a,b, 3 input select, 4 output [31:0] y 5 ); 6 7 assign y = (select == 0) ? a : b; 8 9 endmodule 10 11 12 module mux_3_32( 13 input [31:0] a,b,c, 14 input [1:0] select, 15 output [31:0] y 16 ); 17 18 parameter regs = 2'b00, 19 mem = 2'b01, 20 pc = 2'b10; 21 22 assign y = (select == regs) ? a : 23 (select == mem) ? b : c; 24 25 endmodule 26 27 28 module mux_3_5( 29 input [4:0] a,b,c, 30 input [1:0] select, 31 output [4:0] y 32 ); 33 34 parameter rt = 2'b00, 35 rd = 2'b01, 36 ra = 2'b10; 37 38 assign y = (select == rt) ? a : 39 (select == rd) ? b : c; 40 41 endmodule
1 module ctrl( 2 input [5:0] Op, 3 input [5:0] Func, 4 output [1:0] RegDst, 5 output RegWrite, 6 output ALUSrc, 7 output MemWrite, 8 output [1:0] MemtoReg, 9 output [1:0] MemDst, 10 output [1:0] ExtOp, 11 output [3:0] ALUOp, 12 output [2:0] nPCOp 13 ); 14 15 reg [1:0] regdst; 16 reg regwrite; 17 reg alusrc; 18 reg memwrite; 19 reg [1:0] memtoreg; 20 reg [1:0] memdst; 21 reg [1:0] extop; 22 reg [3:0] aluop; 23 reg [2:0] npcop; 24 25 parameter addu_f = 6'b100001, 26 subu_f = 6'b100011, 27 jr_f = 6'b001000, 28 ori = 6'b001101, 29 lw = 6'b100011, 30 sw = 6'b101011, 31 beq = 6'b000100, 32 lui = 6'b001111, 33 jal = 6'b000011, 34 j = 6'b000010; 35 36 always @ (Op or Func) begin 37 if(Op == 6'b0) begin 38 case(Func) 39 addu_f:begin 40 regdst = 2'b01; 41 regwrite = 1; 42 alusrc = 0; 43 memwrite = 0; 44 memtoreg = 2'b00; 45 memdst = 2'bxx; 46 extop = 2'bxx; 47 aluop = 4'b0000; 48 npcop = 3'b000; 49 end 50 subu_f:begin 51 regdst = 2'b01; 52 regwrite = 1; 53 alusrc = 0; 54 memwrite = 0; 55 memtoreg = 2'b00; 56 memdst = 2'bxx; 57 extop = 2'bxx; 58 aluop = 4'b0001; 59 npcop = 3'b000; 60 end 61 jr_f: begin 62 regdst = 2'bxx; 63 regwrite = 0; 64 alusrc = 0; 65 memwrite = 0; 66 memtoreg = 2'b00; 67 memdst = 2'bxx; 68 extop = 2'bxx; 69 aluop = 4'b0000; 70 npcop = 3'b011; 71 end 72 default:begin 73 regdst = 2'b00; 74 regwrite = 0; 75 alusrc = 0; 76 memwrite = 0; 77 memtoreg = 2'b00; 78 memdst = 2'b00; 79 extop = 2'b00; 80 aluop = 4'b0000; 81 npcop = 3'b000; 82 end 83 endcase 84 end 85 else begin 86 case(Op) 87 ori: begin 88 regdst = 2'b00; 89 regwrite = 1; 90 alusrc = 1; 91 memwrite = 0; 92 memtoreg = 2'b00; 93 memdst = 2'bxx; 94 extop = 2'b01; 95 aluop = 4'b0010; 96 npcop = 3'b000; 97 end 98 lw: begin 99 regdst = 2'b00; 100 regwrite = 1; 101 alusrc = 1; 102 memwrite = 0; 103 memtoreg = 2'b01; 104 memdst = 2'b00; 105 extop = 2'b00; 106 aluop = 4'b0000; 107 npcop = 3'b000; 108 end 109 sw: begin 110 regdst = 2'bxx; 111 regwrite = 0; 112 alusrc = 1; 113 memwrite = 1; 114 memtoreg = 2'b00; 115 memdst = 2'b00; 116 extop = 2'b00; 117 aluop = 4'b0000; 118 npcop = 3'b000; 119 end 120 beq: begin 121 regdst = 2'bxx; 122 regwrite = 0; 123 alusrc = 0; 124 memwrite = 0; 125 memtoreg = 2'b00; 126 memdst = 2'bxx; 127 extop = 2'b00; 128 aluop = 4'b0001; 129 npcop = 3'b001; 130 end 131 lui: begin 132 regdst = 2'b00; 133 regwrite = 1; 134 alusrc = 1; 135 memwrite = 0; 136 memtoreg = 2'b00; 137 memdst = 2'bxx; 138 extop = 2'b10; 139 aluop = 4'b0000; 140 npcop = 3'b000; 141 end 142 jal: begin 143 regdst = 2'b10; 144 regwrite = 1; 145 alusrc = 0; 146 memwrite = 0; 147 memtoreg = 2'b10; 148 memdst = 2'bxx; 149 extop = 2'b11; 150 aluop = 4'b0000; 151 npcop = 3'b010; 152 end 153 j : begin 154 regdst = 2'bxx; 155 regwrite = 0; 156 alusrc = 1'bx; 157 memwrite = 0; 158 memtoreg = 2'bxx; 159 memdst = 2'bxx; 160 extop = 2'bxx; 161 aluop = 4'bxxxx; 162 npcop = 3'b010; 163 end 164 endcase 165 end 166 end 167 168 assign RegDst = regdst; 169 assign RegWrite = regwrite; 170 assign ALUSrc = alusrc; 171 assign MemWrite = memwrite; 172 assign MemtoReg = memtoreg; 173 assign MemDst = memdst; 174 assign ExtOp = extop; 175 assign ALUOp = aluop; 176 assign nPCOp = npcop; 177 178 179 endmodule