• 多周期CPU设计


    指令类型

    计算机体系结构中,指令可以分为不同的类型,通常有R-type、I-type和J-type指令。

    1. R-type指令(Register-type指令):
      R-type指令通常用于执行寄存器之间的操作,如加法、减法、逻辑运算等。这些指令通常涉及两个寄存器的操作,其中一个寄存器用于存储操作的结果。R-type指令的操作码字段用于指示要执行的具体操作,例如加法(ADD)或逻辑与(AND)。

    2. I-type指令(Immediate-type指令):
      I-type指令通常用于执行包含立即数(常数)的操作,这些立即数与寄存器之间执行某种操作,如加载、存储、分支等。I-type指令的操作码字段指示要执行的操作类型,并包括一个立即数字段,该字段包含要用于操作的常数值。

    3. J-type指令(Jump-type指令):
      J-type指令通常用于分支和跳转操作,例如跳转到程序的某个地址或执行子例程。这些指令通常不涉及寄存器操作,而是直接影响程序计数器(PC),用于改变程序的控制流。J-type指令的操作码字段用于指示分支或跳转的类型。

    这些不同的指令类型在计算机体系结构中有不同的编码和操作。多周期CPU设计需要考虑如何正确解码和执行这些不同类型的指令。通常,每种指令类型都需要一个不同的控制路径来执行相应的操作。在多周期CPU中,不同的指令类型可能需要不同数量的时钟周期来完成。因此,在设计多周期CPU时,要考虑如何有效地处理这些不同类型的指令。

    clock skew

    “Clock skew”(时钟偏移)是指在一个同步电路中,由于信号传输延迟或其他因素导致时钟信号在不同部分的电路中到达的时间不同。时钟信号用于同步各个电路元件的操作,因此时钟偏移可能导致电路的不正常功能或性能问题。

    时钟偏移可能导致以下问题:

    1. 数据不稳定性:如果时钟信号到达某个电路元件的时间比其他元件晚,可能会导致数据在电路中不稳定。这可能导致数据损坏或不一致。

    2. 时序冲突:时钟偏移可能导致时序冲突,即在某些情况下,数据信号在时钟信号的上升沿或下降沿之间变化,而不是在特定的时钟沿上稳定。这会使电路操作不可预测。

    3. 性能问题:时钟偏移还可能导致电路性能问题,因为某些电路元件可能需要等待时钟信号的到达,从而降低了电路的时钟频率。

    时钟偏移可以由多种因素引起,包括信号传输线的长度、电路板布线的不均匀性、温度变化等。为了解决时钟偏移问题,通常采取以下方法:

    1. 时钟缓冲器(Clock Buffers):时钟缓冲器可以帮助均衡时钟信号的到达时间,确保它们尽量同时到达各个电路元件。

    2. 时钟网络设计:精心设计时钟网络,考虑信号传播时间,以最小化时钟偏移。

    3. 时序分析工具:使用时序分析工具来检测潜在的时钟偏移问题,并对电路进行优化以解决这些问题。

    4. 时钟同步协议:在多个时钟域之间进行数据传输时,使用时钟同步协议,确保数据在不同时钟域之间正确同步。

    时钟偏移是复杂的电子设计中需要考虑的一个重要方面,特别是在高性能或高速电路中。处理时钟偏移问题需要深入了解电子设计和时序分析的原理。

    数据通路图

    在这里插入图片描述

    有限状态机三段式写法

    (1) 状态机第一段,时序逻辑,非阻塞赋值,传递寄存器的状态。
    (2) 状态机第二段,组合逻辑,阻塞赋值,根据当前状态和当前输入,确定下一个状态机的状态。
    (3) 状态机第三代,时序逻辑,非阻塞赋值,因为是 Mealy 型状态机,根据当前状态和当前输入,确定输出信号。
    在这里插入图片描述

    项目文件

    在这里插入图片描述

    multi_cycle_cpu.h
    `ifndef MULTI_CYCLE_CPU_H
    //alu
        `define MULTI_CYCLE_CPU_H
        `define  Add        2'b00
        `define  Sub        2'b01
        `define  Ori        2'b10
    
     
    //ct`define  l
        `define  Ifetch             4'd1
        `define  Rfetch_Decode      4'd2
        `define  BrComplete         4'd3
        `define  OriExec            4'd4
        `define  RExec              4'd5
        `define  AdrCal             4'd6
        `define  OriFinish          4'd7
        `define  Rfinish            4'd8
        `define  SWMem              4'd9
        `define  LWmem              4'd10
        `define  LWwr               4'd11
    
    //if`define  
        `define  RType              6'b000000
        `define  BEQ                6'b000100
        `define  ORI                6'b001101
        `define  SW                 6'b101011
        `define  LW                 6'b100011
        `define  JAL                6'b000011
    
    `endif
    
    • 1
    • 2
    • 3
    • 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
    Alu.v
    `include "multi_cycle_cpu.h"
     //`define  Add        2'b00
     module Alu(	
        input [31:0] A,				
        input [31:0] B,				
    
        input [1:0] ALUOp,			//2位ALU控制信号
        output reg [31:0] ALUOut,	
        output reg zero		//零标志位
    );	
    	//reg [31:0] ALUOut;
    	always@(A,B,ALUOp)	begin
    		case(ALUOp)//决定ALU操作
    			`Add:	
    				begin
    					ALUOut <= A+B;
    				end
    			
    			`Sub:	
    				begin 
    					ALUOut <= A-B;
    				end
    
    			`Ori:	
    				begin
    					ALUOut <= A|B;
    				end
    
    			default:
    				begin
    					ALUOut <= 32'h0000_0000;
    					//$display($time,,"(ALU)(DEFAULT)");
    				end
    		endcase
    	end
    	
    	always @(A,B) begin
    		if (A == B) zero <= 1'b1;
    		else 		zero <= 1'b1;
    	end
    endmodule
    
    • 1
    • 2
    • 3
    • 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
    ctrl.v
    `include "multi_cycle_cpu.h"
    
    module ctrl(
        input           clk,
        input           reset,
        input [5:0]     opcode,
        output  reg     PCWr,
        output  reg     PCWrCond,
    
        output  reg     IorD,
        output  reg     MemWr,
        output  reg     IRWr,
        output  reg     RegDst,
        output  reg     RegWr,
        output  reg     ALUSelA,
        output reg [1:0]     ALUSelB,
        output  reg     PCSrc,
        output  reg     BrWr,
        output reg [1:0]    ExtOp,
        output  reg     MemtoReg,
        output reg [1:0]     ALUOp         
    );
        reg     [3:0]   CurState,NextState;
        
        always @(posedge clk or posedge reset) begin
            if (reset) begin
                CurState <= 4'b0000; // 初始化状态
            end else begin
                CurState <= NextState;
            end
        end
    
    
        always @(CurState,opcode,NextState) begin
            case(CurState)
                4'b0000: NextState <= `Ifetch;
                `Ifetch: begin
                    NextState <= `Rfetch_Decode;
                end
                `Rfetch_Decode:begin
                    if (opcode == `BEQ) begin
                        NextState <= `BrComplete;
                    end else if (opcode == `ORI) begin
                        NextState <= `OriExec;
                    end else if (opcode == `RType) begin
                        NextState <= `RExec;
                    end else if (opcode == `LW || opcode == `SW) begin
                        NextState <= `AdrCal;
                    end
                end
                `BrComplete:
                    NextState <= `Ifetch;
                `OriExec:
                    NextState <= `OriFinish;
                `RExec:
                    NextState <= `Rfinish;
                `AdrCal: begin
                    if (opcode == `SW) 
                        NextState <= `SWMem;
                    else if(opcode == `LW) 
                        NextState <= `LWmem;
                end
                `OriFinish: 
                    NextState <= `Ifetch;
                `Rfinish:
                    NextState <= `Ifetch;
                `SWMem:
                    NextState <= `Ifetch;
                `LWmem:
                    NextState <= `LWwr;
                `LWwr: 
                    NextState <= `Ifetch;
                default:
                    NextState <= CurState;
            endcase
        end
        always @(posedge reset) begin
            if (reset) begin
                ALUOp       <=  2'b00;
                PCWr        <=  1'b0;
                PCWrCond    <=  1'b0;
                IorD        <=  1'b0;
                MemWr       <=  1'b0;
                IRWr        <=  1'b0;
                RegDst      <=  1'b0;
                RegWr       <=  1'b0;
                ALUSelA     <=  1'b0;
                ALUSelB     <=  2'b00;
                PCSrc       <=  1'b0;
                BrWr        <=  1'b0;
                ExtOp       <=  2'b00;
                MemtoReg    <=  1'b0;
                BrWr        <=  1'b0;
            end 
        end
        always @(CurState) begin
            case(CurState)
                `Ifetch: begin
                    ALUOp       <=  `Add;
                    PCWr        <=  1'b1;
                    MemWr       <=  1'b0;
                    RegWr       <=  1'b0;
                    ALUSelA     <=  1'b0;
                    ALUSelB     <=  2'b00;
                    PCSrc       <=  1'b0;
                    IRWr        <=  1'b1;
                    PCWrCond    <=  1'bx;
                    IorD        <=  1'b0;
                    RegDst      <=  1'bx;
                    MemtoReg    <=  1'bx;
                    BrWr        <=  1'b0;
                    ExtOp       <=  2'b00;
                end 
                `Rfetch_Decode: begin
                    PCWr        <=  1'b0;
                    PCWrCond    <=  1'b0;
                    MemWr       <=  1'b0;
                    IRWr        <=  1'b0;
                    RegWr       <=  1'b0;
                    ALUOp       <=  `Add;
                    BrWr        <=  1'b1;
                    ExtOp       <=  1'b1;
                    ALUSelA     <=  1'b0;
                    ALUSelB     <=  2'b10;
                    RegDst      <=  1'bx;
                    PCSrc       <=  1'bx;
                    IorD        <=  1'bx;
                    MemtoReg    <=  1'bx;      
                    BrWr        <=  1'b0;  
                end
                `BrComplete: begin
                    PCWr        <=  1'b0;
                    MemWr       <=  1'b0;
                    IRWr        <=  1'b0;
                    RegWr       <=  1'b0;
                    ALUOp       <=  `Sub;
                    ALUSelB     <=  2'b01;
                    PCWrCond    <=  1'b1;
                    ALUSelA     <=  1'b1;
                    PCSrc       <=  1'b1;
                    IorD        <=  1'bx;
                    MemtoReg     <=  1'bx;
                    RegDst      <=  1'bx;
                    ExtOp       <=  1'bx; 
                    BrWr        <=  1'b0;
                end
                `OriExec: begin
                    PCWr        <=  1'b0;
                    MemWr       <=  1'b0;
                    IRWr        <=  1'b0;
                    RegDst      <=  1'b0;
                    RegWr       <=  1'b0;
                    ALUOp       <=  `Ori;
                    ALUSelA     <=  1'b1;
                    ALUSelB     <=  2'b11;
                    MemtoReg    <=  1'bx;
                    IorD        <=  1'bx;
                    PCSrc       <=  1'bx;
                    PCWrCond    <=  1'b0;
                    BrWr        <=  1'b0;
                    ExtOp       <=  2'b00;
                end 
                `RExec: begin
                    PCWr        <=  1'b0;
                    PCWrCond    <=  1'b0;
                    MemWr       <=  1'b0;
                    RegDst      <=  1'b1;
                    IRWr        <=  1'b0;
                    RegWr       <=  1'b0;
                    ALUSelA     <=  1'b1;
                    ALUSelB     <=  2'b01;
                    ALUOp       <=  `RType;
                    PCSrc       <=  1'bx;
                    IorD        <=  1'bx;
                    MemtoReg    <=  1'bx;
                    ExtOp       <=  1'bx;
                    BrWr        <=  1'b0;
                end
                `AdrCal: begin
                    PCWr        <=  1'b0;
                    MemWr       <=  1'b0;
                    PCWrCond    <=  1'b0;
                    IRWr        <=  1'b0;
                    RegDst      <=  1'b0;
                    RegWr       <=  1'b0;
                    IorD        <=  1'b0;
                    ExtOp       <=  1'b1;
                    ALUSelA     <=  1'b1;
                    ALUSelB     <=  2'b11;
                    ALUOp       <=  `Add;
                    MemtoReg    <=  1'bx;
                    PCSrc       <=  1'bx;
                    BrWr        <=  1'b0;
                end
                `OriFinish: begin
                    PCWr        <=  1'b0;
                    MemWr       <=  1'b0;
                    IRWr        <=  1'b0;
                    RegDst      <=  1'b0;
                    PCWrCond    <=  1'b0;
                    ALUOp       <=  `Ori;
                    IorD        <=  1'bx;
                    PCSrc       <=  1'bx;
                    ALUSelB     <=  2'b11;
                    ALUSelA     <=  1'b1;
                    RegWr       <=  1'b1;
                    BrWr        <=  1'b0;
                    ExtOp       <=  2'b00;
                    MemtoReg    <=  1'b0;
                end
                `Rfinish: begin
                    PCWr        <=  1'b0;
                    PCWrCond    <=  1'b0;
                    MemWr       <=  1'b0;
                    IRWr        <=  1'b0;
                    ALUOp       <=  `RType;
                    RegDst      <=  1'b1;
                    RegWr       <=  1'b1;
                    ALUSelA     <=  1'b1;
                    ALUSelB     <=  2'b01;
                    IorD        <=  1'bx;
                    PCSrc       <=  1'bx;
                    ExtOp       <=  1'bx;
                    BrWr        <=  1'b0;
                    MemtoReg    <=  1'b0;
                end
                `SWMem: begin
                    PCWr        <=  1'b0;
                    PCWrCond    <=  1'b0;
                    IorD        <=  1'b0;
                    IRWr        <=  1'b0;
                    ExtOp       <=  1'b1;
                    MemWr       <=  1'b1;
                    RegWr       <=  1'b0;
                    ALUSelA     <=  1'b1;
                    ALUSelB     <=  2'b11;
                    ALUOp       <=  `Add;
                    PCSrc       <=  1'bx;
                    RegDst      <=  1'bx;
                    MemtoReg    <=  1'bx;
                    BrWr        <=  1'b0;
                end 
                `LWmem: begin
                    PCWr        <=  1'b0;
                    PCWrCond    <=  1'b0;
                    MemWr       <=  1'b0;
                    IRWr        <=  1'b0;
                    RegDst      <=  1'b0;
                    RegWr       <=  1'b0;
                    ExtOp       <=  1'b1;
                    ALUSelA     <=  1'b1;
                    IorD        <=  1'b1;
                    ALUSelB     <=  2'b11;
                    ALUOp       <=  `Add;
                    MemtoReg    <=  1'bx;
                    PCSrc       <=  1'bx;
                    BrWr        <=  1'b0;
                end 
                `LWwr: begin
                    PCWr        <=  1'b0;
                    PCWrCond    <=  1'b0;
                    MemWr       <=  1'b0;
                    IRWr        <=  1'b0;
                    RegDst      <=  1'b0;
                    ALUSelA     <=  1'b1;
                    RegWr       <=  1'b1;
                    ExtOp       <=  1'b1;
                    MemtoReg    <=  1'b1;
                    ALUSelB     <=  2'b11;
                    ALUOp       <=  `Add;
                    PCSrc       <=  1'bx;
                    BrWr        <=  1'b0;
                    IorD        <=  1'bx;
                end
                default: begin
                    ALUOp       <=  `Add;
                    PCWr        <=  1'b0;
                    PCWrCond    <=  1'b0;
                    IorD        <=  1'b0;
                    MemWr       <=  1'b0;
                    IRWr        <=  1'b0;
                    RegDst      <=  1'b0;
                    RegWr       <=  1'b0;
                    ALUSelA     <=  1'b0;
                    ALUSelB     <=  2'b00;
                    PCSrc       <=  1'b0;
                    BrWr        <=  1'b0;
                    ExtOp       <=  2'b00;
                    MemtoReg    <=  1'b0;
                end
                    
            endcase
    
        end
    endmodule
    
    • 1
    • 2
    • 3
    • 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
    • 225
    • 226
    • 227
    • 228
    • 229
    • 230
    • 231
    • 232
    • 233
    • 234
    • 235
    • 236
    • 237
    • 238
    • 239
    • 240
    • 241
    • 242
    • 243
    • 244
    • 245
    • 246
    • 247
    • 248
    • 249
    • 250
    • 251
    • 252
    • 253
    • 254
    • 255
    • 256
    • 257
    • 258
    • 259
    • 260
    • 261
    • 262
    • 263
    • 264
    • 265
    • 266
    • 267
    • 268
    • 269
    • 270
    • 271
    • 272
    • 273
    • 274
    • 275
    • 276
    • 277
    • 278
    • 279
    • 280
    • 281
    • 282
    • 283
    • 284
    • 285
    • 286
    • 287
    • 288
    • 289
    • 290
    • 291
    • 292
    • 293
    • 294
    • 295
    EXT.v
    
    module EXT(
        input   [15:0]      Imm16,
        input   [1 :0]      ExtOp,
        output  reg [31:0]      Imm32
    );
       // wire [1 :0]      ExtOp;
        always @(ExtOp,Imm16) begin
            case (ExtOp)
                2'b00:
                    Imm32 <= {{16{1'b0}},Imm16};
                2'b01://符号扩展
                    Imm32 <= {{16{Imm16[15]}},Imm16};
                2'b10://将立即数扩展到高位
                    Imm32 <= {Imm16,{16{1'b0}}};
                default:
                    Imm32 <= {{16{1'b0}},Imm16};
            endcase
        end          
    endmodule
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    im.v
    module im_4k( clk,RAdr,WrAdr,MemWr,Din,Dout );
        input [11:2]	RAdr;
    	input [11:2]	WrAdr;
    	input			MemWr;
    	input [31:0]	Din;
        input 			clk;
    	output [31:0] 	Dout;
        reg [31:0] imem[1023:0];
    	always @(posedge clk) begin
    		if (MemWr) imem[WrAdr] <= Din;
    	end
        assign Dout = imem[RAdr];
    endmodule    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    IR.v
    module IR(
        input           IRWr,
        input           clk,
        input   [31:0]  in,
        output  reg [31:0]  IRout           
    );
        always @(posedge clk) begin
            if (IRWr)
                IRout <= in;
        end
    endmodule
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    mips.v
    module mips( clk, reset );
       input   clk;
       input   reset;
       
       wire               zero          ;
       wire   [31:0]      PC            ;
       wire   [31:0]      ALUOut        ;
       // wire   [1 :0]      ALUOp         ;
       wire   [31:0]      pc_im_mux_out;
       wire   [4 :0]      ir_reg_mux_out;
       wire   [31:0]      im_reg_mux_out;
       wire   [31:0]      alu_pc_mux_out;
       wire   [31:0]      reg_alu_mux_out;
       wire   [31:0]      reg_alu_mux2_out;
       // wire   [31:0]      muxout1  ;
       wire   [31:0]      im_dout,dm_dout;
       wire   [31:0]      busA,busB;
       wire   [31:0]      in,IRout;
       //wire   [31:0]      rdata1,rdata2;
    
       wire   [31:0]      Imm32   ;
       wire   [2 :0]      opcode  ;   
       wire               PCWr    ;
       wire               PCWrCond;
       wire               IorD    ;
       wire               MemWr   ;
       wire               IRWr    ;
       wire               RegDst  ;
       wire               RegWr   ;
       wire               ALUSelA ;
       wire   [1 :0]      ALUSelB ;
       wire               PCSrc   ;
       wire               BrWr    ;
       wire   [1 :0]      ExtOp   ;
       wire               MemtoReg;
       wire   [1 :0]      ALUOp   ;
       wire   [31:0]      tar_out ;
    
       PC U_PC(
          .PCWr  ( PCWr |( PCWrCond & zero )),
          .NPC   ( alu_pc_mux_out   ),
          .clk   ( clk   ),
          .reset ( reset ),
          .PC    ( PC    )
       );
    
       // im_4k U_IM ( 
       //    .addr(pc_im_mux_out[11:2]), 
       //    .dout(im_dout)
       // );
       im_4k U_IM(
          .clk   ( clk   ),
          .RAdr  ( pc_im_mux_out[11:2]  ),
          .WrAdr ( ALUOut[11:2] ),
          .MemWr ( MemWr ),
          .Din   ( busB   ),
          .Dout  ( im_dout  )
       );
    
       // dm_4k U_DM ( 
       //    .addr(ALUOut[11:2]),
       //    .din(busB), 
       //    .DMWr(MemWr), 
       //    .clk(clk), 
       //    .dout(dm_dout)
       // );
       
       Alu U_Alu(
          .A      ( reg_alu_mux_out      ),
          .B      ( reg_alu_mux2_out      ),
          .ALUOp  ( ALUOp  ),
          .ALUOut ( ALUOut ),
          .zero   ( zero   )
       );
    
       target U_target(
          .clk    ( clk    ),
          .reset  ( reset  ),
          .tar_in ( ALUOut ),
          .BrWr   ( BrWr   ),
          .tar_out  ( tar_out  )
       );
    
    
       IR U_IR(
          .clk  ( clk      ),
          .IRWr ( IRWr     ),
          .in   ( im_dout  ),
          .IRout( IRout    )
       );
    
       regfile U_regfile(
          .clk    ( clk    ),
          .raddr1 ( IRout[25:21] ),
          .rdata1 ( busA ),
          .raddr2 ( IRout[20:16] ),
          .rdata2 ( busB ),
          .RFWr   ( RegWr   ),
          .waddr  ( ir_reg_mux_out ),
          .wdata  ( im_reg_mux_out  )
       );
    
       ctrl U_ctrl(
          .clk      ( clk      ),
          .reset    ( reset    ),
          .opcode   ( IRout[31:26]   ),
          .PCWr     ( PCWr     ),
          .PCWrCond ( PCWrCond ),
          .IorD     ( IorD     ),
          .MemWr    ( MemWr    ),
          .IRWr     ( IRWr     ),
          .RegDst   ( RegDst   ),
          .RegWr    ( RegWr    ),
          .ALUSelA  ( ALUSelA  ),
          .ALUSelB  ( ALUSelB  ),
          .PCSrc    ( PCSrc    ),
          .BrWr     ( BrWr     ),
          .ExtOp    ( ExtOp    ),
          .MemtoReg ( MemtoReg ),
          .ALUOp    ( ALUOp    )
       );
    
       mutiplexer32_1 U_PC_IM(
          .s  ( IorD  ),
          .d0 ( PC ),
          .d1 ( ALUOut ),
          .out32_1  ( pc_im_mux_out )
       );
    
       mutiplexer5_1 U_IR_Regfile(
          .s  ( RegDst  ),
          .d0 ( IRout[20:16] ),
          .d1 ( IRout[15:11] ),
          .out5_1  (  ir_reg_mux_out )
       );
    
       mutiplexer32_1 U_IM_Regfile(
          .s  (  MemtoReg ),
          .d0 ( ALUOut ),
          .d1 ( im_dout ),
          .out32_1  (  im_reg_mux_out )
       );
    
       mutiplexer32_1 U_Regfile_Alu_1(
          .s  ( ALUSelA  ),
          .d0 ( PC ),
          .d1 ( busA ),
          .out32_1  ( reg_alu_mux_out  )
       );
    
       EXT U_EXT(
          .Imm16 ( IRout[15:0] ),
          .ExtOp ( ExtOp ),
          .Imm32 ( Imm32 )
       );
    
       mutiplexer32_1 U_Alu_PC(
          .s  ( PCSrc  ),
          .d0 ( ALUOut ),
          .d1 ( tar_out ),
          .out32_1  ( alu_pc_mux_out  )
       );
    
       mutiplexer32_2 U_Regfile_Alu_2(
          .s  ( ALUSelB  ),
          .d0 ( 32'h4 ),
          .d1 ( busB ),
          .d2 ( {Imm32[29:0],2'b00} ),
          .d3 ( Imm32 ),
          .out32_2  ( reg_alu_mux2_out  )
       );
    
    endmodule
    
    • 1
    • 2
    • 3
    • 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
    PC.v
    module PC(	
    	input PCWr,			//控制PC是否更改
    	input [31:0] NPC,		
    	input clk,				
    	input reset,			
    	output reg [31:0] PC	
    );
    
    	// always@(posedge clk, posedge reset) begin
    	// 	if(reset) PC <= 32'h0000_3000;//PC复位后初值为0x0000_3000
    	// 	else if(PCWr) begin
    	// 		PC <= NPC;
    	// 	end else begin
    	// 		PC <= PC;
    	// 	end
    	// end
    	always @(posedge clk or posedge reset) begin
    		if (reset) PC <= 32'h0000_3000;
    		else if (PCWr)
    			PC <= NPC;
    	end
    endmodule
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    target.v
    
    module target(
        input           clk,
        input           reset,
        input   [31:0]  tar_in,
        input           BrWr,
        output reg[31:0]  tar_out
    );
        always @(posedge clk) begin
            if (!BrWr)
                tar_out <= tar_in;
        end
    
    endmodule
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    regfile.v
    
    module regfile(
        input         clk,
        // READ PORT 1
        input  [ 4:0] raddr1,
        output [31:0] rdata1,
        // READ PORT 2
        input  [ 4:0] raddr2,
        output [31:0] rdata2,
        // WRITE PORT
        input         RFWr,       //write enable, HIGH valid
        input  [ 4:0] waddr,
        input  [31:0] wdata
    );
        reg [31:0] rf[31:0];
    
        //WRITE
        always @(posedge clk) begin
            if (RFWr) rf[waddr] <= wdata;
        end
    
        //READ OUT 1
        assign rdata1 = (raddr1 == 5'b0) ? 32'b0 : rf[raddr1];
    
        //READ OUT 2
        assign rdata2 = (raddr2 == 5'b0) ? 32'b0 : rf[raddr2];
    
    endmodule
    
    • 1
    • 2
    • 3
    • 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
    仿真——mips_tp.v
     module mips_tb();
        
       reg clk, reset;
        
       mips U_MIPS(
          .clk(clk), .reset(reset)
       );
        
       initial begin
          $readmemh( "code.txt" , U_MIPS.U_IM.imem ) ;
          //$monitor("PC = 0x%8X, IR = 0x%8X", U_MIPS.U_PC.PC, U_MIPS.instr ); 
          clk = 1 ;
          reset = 0 ;
          #5 ;
          reset = 1 ;
          #20 ;
          reset = 0 ;
       end
       
       always
    	   #(50) clk = ~clk;
       
    endmodule
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
  • 相关阅读:
    【MySQL学习】常见命令
    使用 C# 创造 ASCII 艺术
    剑指Offer04. 二维数组中的查找【中等】
    银行主动安全纵深防御体系解决方案
    LabVIEW中管理大型数据
    Python闯LeetCode--第2题:两数相加
    设计模式-创建型模式(单例、工厂、建造、原型)
    Python中class内置方法__init__与__new__作用与区别探究
    【斗破年番】火火小医仙幽会,彩鳞吃醋跟随,失身之事终暴露,蛇人族来算账
    在安卓手机上搭建一台微型服务器
  • 原文地址:https://blog.csdn.net/qq_46264636/article/details/133754729