aluRes = 0; endcase end endmodule
5. ALU控制设计
ALU单元对应以上5种操作的编码如表所示: 输入信号 操作类型 0000 与 0001 或 0010 加 0110 减 0111 小于设置 通过2位操作类型码以及6位指令功能码就可以产生ALU单元的4位控制信号。它们之间的对应关系如表所示:
因此该模块的主要功能就是根据译码控制单元产生2位操作码以及6位功能码产生4位ALU控制信号,接口为: 输入:aluop(2bit),funt(6bit) 输出:aluctr(4bit) 代码为: module aluctr(
input [1:0] ALUOp, input [5:0] funct, output [3:0] ALUCtr );
reg[3:0] ALUCtr;
always @(ALUOp or funct) casex({ALUOp,funct}) 8'b00xxxxxx:ALUCtr=4'b0010; 8'b01xxxxxx:ALUCtr=4'b0110; 8'b11xxxxxx:ALUCtr=4'b0000;
8'b10xx0000:ALUCtr=4'b0010; 8'b10xx0010:ALUCtr=4'b0110; 8'b10xx0100:ALUCtr=4'b0000; 8'b10xx0101:ALUCtr=4'b0001; 8'b10xx1010:ALUCtr=4'b0111; endcase endmodule
6. 控制器设计
控制器输入为指令的opCode字段,即操作码。操作码经过主控制单元的译码,给ALUCtr、Data、Memory、Registers、Muxs等部件输出正的控制信号。
微处理器在执行不同指令时,哥哥控制信号相对应的状态表如下:
因此该模块的接口为: 输入:opcode(6bit) 输出:alusrc,memtoreg,regwrite,memread,memwrite,branch,,aluop[1:0],jmp 代码为:
module ctr(
input [5:0] opCode, output regDst, output aluSrc,
output memToReg, output regWrite, output memRead, output memWrite, output branch, output [1:0] aluop, output jmp ); reg regDst; reg aluSrc; reg memToReg; reg regWrite; reg memRead; reg memWrite;
reg branch; reg[1:0] aluop; reg jmp;
always @(opCode) begin
case(opCode) 6'b000010://jmp begin regDst=0; aluSrc=0; memToReg=0; regWrite=0; memRead=0; memWrite=0; branch=0; aluop=2'b00; jmp=1; end 6'b000000://R begin regDst=1; aluSrc=0; memToReg=0; regWrite=1; memRead=0; memWrite=0; branch=0; aluop=2'b10; jmp=0; end 6'b100011://lw begin regDst=0; aluSrc=1; memToReg=1; regWrite=1; memRead=1; memWrite=0; branch=0; aluop=2'b00; jmp=0; end
6'b101011://sw begin regDst=0; aluSrc=1;
memToReg=0; regWrite=0; memRead=0; memWrite=1; branch=0; aluop=2'b00; jmp=0; end
6'b000100://beq begin regDst=0; aluSrc=0;
memToReg=0; regWrite=0; memRead=0; memWrite=0; branch=1; aluop=2'b01; jmp=0; end
6'b001100://andi begin regDst=0; aluSrc=1;
memToReg=0; regWrite=1; memRead=0; memWrite=0; branch=0; aluop=2'b11; jmp=0; end
default: begin regDst=0; aluSrc=0;
memToReg=0; regWrite=0; memRead=0; memWrite=0; branch=0; aluop=2'b00; jmp=0; end endcase end endmodule
7. 符号数扩展
将16位有符号扩展为32位有符号数。带符号扩展只需要在前面补足符号即可。 代码为:
module signext(
input [15:0] inst, output [31:0] data );
assign data=inst[15:15]?{16'hffff,inst}:{16'h0000,inst}; endmodule
8. 顶层模块
顶层模块需要将前面多个模块实例化,通过导线以及多路复用器将各个部件连接起来,并且在时钟的控制下修改PC的值,PC是一个32位的寄存器,每个时钟沿自动增加4。
多路复用器MUX直接通过三目运算符实现: Assign OUT = SEL?INPUT1:INPUT2;
其中,OUT、SEL、INPUT1、INPUT2都是预先定义的信号。 代码如下: module top(
input clkin, input reset );
reg[31:0] pc,add4; wire choose4;
wire[31:0] expand2,mux2,mux3,mux4,mux5,address,jmpaddr,inst; wire[4:0] mux1; //wire for controller
wire reg_dst,jmp,branch,memread,memwrite,memtoreg; wire[1:0] aluop;
wire alu_src,regwrite;