//寄存器解码模块,解析指令,提取寄存器、立即数等信息,并控制流水线寄存器是否读写。它还产生分支条件和跳转地址等控制信号 module RegDec(clk,start,outOverflow,outRegWr,rw,result,instruct,branch,jump,RegDst,ALUSrc,MemtoReg,RegWr,MemWr,ExtOp,AluCtr,busA,busB,rs,rt,rd,target,imm16); input start,clk; //输入开始信号和时钟信号 input outOverflow,outRegWr; //输入溢出信号和寄存器写使能信号 input[31:0] instruct,result; //输入指令和执行结果 input[4:0] rw; //输入寄存器编号 output branch,jump,RegDst,ALUSrc,MemtoReg,RegWr,MemWr,ExtOp; //输出分支信号、跳转信号、寄存器写入选择信号、ALU源选择信号、 //内存读取选择信号、寄存器写使能信号、内存写入使能信号、扩展操作信号 reg branch,jump,RegDst,ALUSrc,MemtoReg,RegWr,MemWr,ExtOp; //分支信号、跳转信号、寄存器写入选择信号、ALU源选择信号、 //内存读取选择信号、寄存器写使能信号、内存写入使能信号、扩展操作信号的寄存器 output[2:0] AluCtr; //输出ALU控制信号 reg[2:0] AluCtr; //ALU控制信号寄存器 output[31:0] busA,busB; //输出操作数A、B output[4:0] rs,rt,rd; //输出操作数rs、rt、rd reg [31:0]busA,busB; //操作数A、B寄存器 reg [31:0]mem[63:0]; //寄存器模拟的内存,大小为64字节 wire[5:0] op,func; //操作码和函数码 wire[4:0] rs,rt,rd,shamt; //操作数rs、rt、rd和移位量 output[15:0] imm16; //输出16位立即数 wire[15:0] imm16; //16位立即数 output[26:0] target; //输出跳转目标地址 wire[25:0] target; //跳转目标地址

//根据指令获取操作码等数据
assign op=instruct[31:26];             //获取操作码
assign rs=instruct[25:21];             //获取操作数rs
assign rt=instruct[20:16];             //获取操作数rt
assign rd=instruct[15:11];             //获取操作数rd
assign shamt=instruct[10:6];           //获取移位量
assign func=instruct[5:0];             //获取函数码
assign imm16=instruct[15:0];           //获取16位立即数
assign target=instruct[25:0];          //获取跳转目标地址

//由于书直接给出指令的控制信号取值, //所以可以根据指令类型直接给出控制信号的值 //但是最好的方法是通过op操作码和func来获取控制信号 always @ (op) //根据操作码获取控制信号 case(op) //根据操作码进行分支 //R-型指令 6'b000000: //操作码为000000,即R-型指令 begin {branch, jump, RegDst, ALUSrc, MemtoReg, RegWr, MemWr, ExtOp} = 8'b00100100; //设置分支信号、跳转信号、寄存器写入选择信号、ALU源选择信号、内存读取选择信号、寄存器写使能信号、内存写入使能信号、扩展操作信号的值 case(func) //根据函数码进行分支 6'b100000: AluCtr = 3'b001; //函数码为100000,即add,设置ALU控制信号为001 6'b100010: AluCtr = 3'b101; //函数码为100010,即sub,设置ALU控制信号为101 6'b100011: AluCtr = 3'b100; //函数码为100011,即subu,设置ALU控制信号为100 6'b101010: AluCtr = 3'b111; //函数码为101010,即slt,设置ALU控制信号为111 6'b101011: AluCtr = 3'b110; //函数码为101011,即sltu,设置ALU控制信号为110 endcase //结束case语句 end //结束begin-end语句块 //ori 6'b001101: //操作码为001101,即ori指令 begin {branch, jump, RegDst, ALUSrc, MemtoReg, RegWr, MemWr, ExtOp} = 8'b00010100; //设置分支信号、跳转信号、寄存器写入选择信号、ALU源选择信号、内存读取选择信号、寄存器写使能信号、内存写入使能信号、扩展操作信号的值 AluCtr = 3'b010; //设置ALU控制信号为010 end //结束begin-end语句块 //addiu 6'b001001: //操作码为001001,即addiu指令 begin {branch, jump, RegDst, ALUSrc, MemtoReg, RegWr, MemWr, ExtOp} = 8'b00010101; //设置分支信号、跳转信号、寄存器写入选择信号、ALU源选择信号、内存读取选择信号、寄存器写使能信号、内存写入使能信号、扩展操作信号的值 AluCtr = 3'b000; //设置ALU控制信号为000 end //结束begin-end语句块 //lw 6'b100011: //操作码为100011,即lw指令 begin {branch, jump, RegDst, ALUSrc, MemtoReg, RegWr, MemWr, ExtOp} = 8'b00011101; //设置分支信号、跳转信号、寄存器写入选择信号、ALU源选择信号、内存读取选择信号、寄存器写使能信号、内存写入使能信号、扩展操作信号的值 AluCtr = 3'b000; //设置ALU控制信号为000 end //结束begin-end语句块 //sw 6'b101011: //操作码为101011,即sw指令 begin {branch, jump, ALUSrc, RegWr, MemWr, ExtOp} = 6'b001011; //设置分支信号、跳转信号、ALU源选择信号、寄存器写使能信号、内存写入使能信号、扩展操作信号的值 AluCtr = 3'b000; //设置ALU控制信号为000 end //结束begin-end语句块 //beq 6'b000100: //操作码为000100,即beq指令 begin {branch, jump, ALUSrc, RegWr, MemWr} = 5'b10000; //设置分支信号、跳转信号、ALU源选择信号、寄存器写使能信号、内存写入使能信号的值 AluCtr = 3'b100; //设置ALU控制信号为100 end //结束begin-end语句块 //jump 6'b000010: //操作码为000010,即jump指令 {branch, jump, RegWr, MemWr} = 4'b0100; //设置分支信号、跳转信号、寄存器写使能信号、内存写入使能信号的值 endcase //结束case语句

always@(negedge clk) //采用负边沿触发器 if(start==1) //如果开始信号为1 begin if(outOverflow&!outRegWr==1) //如果出现溢出且寄存器写使能为0 mem[rw]<=result; //将EX阶段计算的结果result保存在寄存器中 end else //如果开始信号为0,则初始化寄存器 begin mem[0]=0; //将0号寄存器初始化为0 mem[1]=1; //将1号寄存器初始化为1 mem[2]=2; //将2号寄存器初始化为2 mem[3]=3; //将3号寄存器初始化为3 mem[4]=4; //将4号寄存器初始化为4 mem[5]=5; //将5号寄存器初始化为5 mem[6]=6; //将6号寄存器初始化为6 mem[7]=7; //将7号寄存器初始化为7 mem[8]=8; //将8号寄存器初始化为8 mem[9]=9; //将9号寄存器初始化为9 mem[10]=10; //将10号寄存器初始化为10 mem[11]=11; //将11号寄存器初始化为11 mem[12]=12; //将12号寄存器初始化为12 mem[13]=13; //将13号寄存器初始化为13 mem[14]=14; //将14号寄存器初始化为14 mem[15]=15; //将15号寄存器初始化为15 end

always @(*) //当任意输入信号发生变化时 if(start==1) //如果开始信号为1 //取数 begin busA=mem[rs]; busB=mem[rt]; end //将rs和rt指向的寄存器值存储在操作数A、B中 else //如果开始信号为0 begin busA=mem[1]; busB=mem[2]; end //将1号寄存器和2号寄存器的值存储在操作数A、B中

endmodul

为下面代码写注释寄存器解码模块解析指令提取寄存器、立即数等信息并控制流水线寄存器是否读写。它还产生分支条件和跳转地址等控制信号module RegDecclkstartoutOverflowoutRegWrrwresultinstructbranchjumpRegDstALUSrcMemtoRegRegWrMemWrExtOpAluCtrbusAbusBrsrtrdtargetimm16;	inp

原文地址: https://www.cveoy.top/t/topic/faO4 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录