1. 程式人生 > >P4 - Verilog單週期CPU

P4 - Verilog單週期CPU

 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