FPGA课设 MIPS CPU模块 基础指令

IF.v

`include "define.v";
//IF ????
//1???PC??????

module IF(
    input wire clk,
    input wire rst,
    input wire [31:0] jAddr,//J?
    input wire jCe,

    output reg ce,   //是否要取指
    output reg [31:0] pc  //32位指令
);
    always@(*)//当有输入信号变化的时候 触发
        if(rst == `RstEnable)//复位信号有效,不能发起只存的片选
            ce = `RomDisable;
        else
            ce = `RomEnable;//否则选中只存

    //???? pc+=4
    always@(posedge clk)//单周期指令 在上一条指令执行完之后 选择清零或者+4
        if(ce == `RomDisable)
            pc = `Zero;
 		else if(jCe == `Valid)//J?
            pc = jAddr;

        else
            pc = pc + 4;
endmodule

ID.v

module  ID (
    input wire rst,    
	input wire [31:0] pc,	//J?
    input wire [31:0] inst,//指令数据
    input wire [31:0] regaData_i,//来自regfile 源数据 寄存器 rt
    input wire [31:0] regbData_i,//来自regfile 源数据 寄存器 rs
    output reg [5:0] op,    //译码后 分析出来的操作码
    output reg [31:0] regaData,//发送给EX模块的rt数据
    output reg [31:0] regbData,//发送给EX模块的rs数据

		// 三种数据的 是否需要读写
    output reg regaRead,
    output reg regbRead,
    output reg regcWrite,
    
    // 地址
    output reg [4:0] regaAddr,//
    output reg [4:0] regbAddr,//    
    output reg [4:0] regcAddr,//
	output reg [31:0] jAddr,	//J?
    output reg jCe//J?

);

    //操作码
    wire [5:0] inst_op = inst[31:26];   
    //经过拓展的32位立即数
    reg [31:0] imm;
	//??R???
    wire[5:0] func = inst[5:0]; 
	//??J???
	wire [31:0] npc = pc + 4;

always@(*)//输入信号发生了变化
        if(rst == `RstEnable)//复位信号有效
          	 begin
            	op = `Nop;//置空            
	            regaRead = `Invalid;
	            regbRead = `Invalid;
	            regcWrite = `Invalid;
	            regaAddr = `Zero;
	            regbAddr = `Zero;
	            regcAddr = `Zero;
	            imm    = `Zero;
				jCe = `Invalid;//J?
	            jAddr = `Zero;//J?
          	 end
		else 
			begin//???end
			    jCe = `Invalid;//J?
		        jAddr = `Zero;//J?
	          	case(inst_op)
	               	`Inst_ori://分析出来op字段是 or 指令
	                 	begin
		                    op = `Or;                    
		                    regaRead = `Valid;
		                    regbRead = `Invalid;
		                    regcWrite = `Valid;
		                    regaAddr = inst[25:21];
		                    regbAddr = `Zero;
		                    regcAddr = inst[20:16];
		                    imm = {16'h0, inst[15:0]};//0拓展 前16位 正数置0
	                  	end
				    			`Inst_andi:
			  		  			begin
		                    op = `And;                    
		                    regaRead = `Valid;
		                    regbRead = `Invalid;
		                    regcWrite = `Valid;
		                    regaAddr = inst[25:21];
		                    regbAddr = `Zero;
		                    regcAddr = inst[20:16];
		                    imm = {16'h0, inst[15:0]};
		                end
	                default://发现都不是
	                  	begin
		                    op = `Nop;                    
		                    regaRead = `Invalid;
		                    regbRead = `Invalid;
		                    regcWrite = `Invalid;
		                    regaAddr = `Zero;
		                    regbAddr = `Zero;
		                    regcAddr = `Zero;
		                    imm = `Zero;
		                end

EX.v

module EX (
        input wire rst,
        //input wire [5:0] op,   
		input wire [5:0] op_i,      
        input wire [31:0] regaData,
        input wire [31:0] regbData,
        input wire regcWrite_i,
        input wire [4:0] regcAddr_i,
        output reg [31:0] regcData,
        output wire regcWrite,
        output wire [4:0] regcAddr,
		output wire [5:0] op,
    	output wire [31:0] memAddr,
    	output wire [31:0] memData
    );   

	assign op = op_i;
    assign memAddr = regaData;
    assign memData = regbData;

	always@(*)
        if(rst == `RstEnable)
              regcData = `Zero;
        else
            //case(op)
            case(op_i)
                `Or:
                    regcData = regaData | regbData;
				`And:
		    		regcData = regaData & regbData;
				`Xor:
		    		regcData = regaData ^ regbData;
				`Add:
		    		regcData = regaData + regbData;
				`Sub:
		    		regcData = regaData - regbData;
				`Lui:
		    		regcData = regaData | regbData;
      
             	`Sll:
                	regcData = regbData << regaData;
              	`Srl:
                	regcData = regbData >> regaData;
				`Sra:
					regcData = ($signed(regbData)) >>> regaData;
				

RegFile.v

module RegFile(
    input wire clk,
    input wire rst,
    input wire we,// 写 信号是否有效
    input wire [4:0] waddr,//写入地址
    input wire [31:0] wdata,//写入数据
    input wire regaRead,
    input wire regbRead,
    input wire [4:0] regaAddr,
    input wire [4:0] regbAddr,
    output reg [31:0] regaData,
    output reg [31:0] regbData
);
    reg [31:0] reg32 [31 : 0];//32个寄存器
    always@(*)
        if(rst == `RstEnable)          
            regaData = `Zero;
        else if(regaAddr == `Zero)
            regaData = `Zero;
        else
            regaData = reg32[regaAddr];
    always@(*)
        if(rst == `RstEnable)          
            regbData = `Zero;
        else if(regbAddr == `Zero)
            regbData = `Zero;
        else	
            regbData = reg32[regbAddr];
    always@(posedge clk)//上升沿
        if(rst == `RstDisable)//不重置
            if((we == `Valid) && (waddr != `Zero))//有写入权限 且 地址为非0
                reg32[waddr] = wdata;//写入
	    	else ;
        else ;
          
endmodule

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值