多周期流水线CPU设计-加减乘运算实现 详细

指令格式以及功能

`define EXE_ADD  		6'b100000
`define EXE_ADDU  		6'b100001
`define EXE_SUB  		6'b100010
`define EXE_SUBU  		6'b100011
`define EXE_SLT  		6'b101010
`define EXE_SLTU  		6'b101011

`define EXE_CLZ  		6'b100000
`define EXE_CLO  		6'b100001

`define EXE_MUL  		6'b000010
`define EXE_MULT  		6'b011000
`define EXE_MULTU  		6'b011001
//R型指令
// 31-26    25-21 20-16 15-11  10-6   5-0
// special  rs    rt    rd     00000  ADD   rd <- rs + rt (溢出检测)
// special  rs    rt    rd     00000  ADDU  rd <- rs + rt (不溢出检测,unsigned)
// special  rs    rt    rd     00000  SUB   rd <- rs - rt (溢出检测)
// special  rs    rt    rd     00000  SUBU  
// special  rs    rt    rd     00000  SLT   rd <- (rs < rt) (有符号数比较)
// special  rs    rt    rd     00000  SLYU  rd <- (rs < rt) (无符号数比较)

// special2 rs    rt    rd     00000  CLZ   rd<- rs从左统计遇到1之前的0的个数
// special2 rs    rt    rd     00000  CLO   rd<- rs从左统计遇到0之前的1的个数
// 011100

// special2 rs    rt    rd     00000  MUL   rd <- rs * rt   rd's low 32 bits
// special  rs    rt    00000  00000  MULT   {hi,lo} <- rs*rt (signed)
// special  rs    rt    00000  00000  MULTU  {hi,lo} <- rs*rt (unsigned)

`define EXE_ADDI  		6'b001000
`define EXE_ADDIU  		6'b001001
`define EXE_SLTI  		6'b001010
`define EXE_SLTIU  		6'b001011 

//I型指令
// 31-26 25-21 20-16 15-0
// ADDI  rs     rt   immediate    // rt <- rs + (signed)imm
// ADDIU						  // rt <- rs + (unsigned)imm
// SLTI                           // rt <- (rs < imm) (rs有符号数比较)
// SLTIU

//aluop
`define EXE_SLT_OP  8'b00101010
`define EXE_SLTU_OP  8'b00101011
`define EXE_SLTI_OP  8'b01010111
`define EXE_SLTIU_OP  8'b01011000   
`define EXE_ADD_OP  8'b00100000
`define EXE_ADDU_OP  8'b00100001
`define EXE_SUB_OP  8'b00100010
`define EXE_SUBU_OP  8'b00100011
`define EXE_ADDI_OP  8'b01010101
`define EXE_ADDIU_OP  8'b01010110
`define EXE_CLZ_OP  8'b10110000
`define EXE_CLO_OP  8'b10110001

`define EXE_MULT_OP  8'b00011000
`define EXE_MULTU_OP  8'b00011001
`define EXE_MUL_OP  8'b10101001

//alusel
`define EXE_RES_ARITHMETIC 3'b100	
`define EXE_RES_MUL 3'b101

译码增加

多周期流水线CPU设计-加减乘运算实现 详细_第1张图片

各程序段修改

多周期流水线CPU设计-加减乘运算实现 详细_第2张图片

ID:
对于add,addu,sub,subu,slt,sltu,mult,multu
wreg_o <= `WriteEnable
wd <= inst_i[15:11] //写rd
aluop <=
alusel <= //对应的指令信息
reg1_read_o = 1'b1
reg2_read_o = 1'b1 //对rs,rt进行读
reg1_addr_o <= inst_i[25:21];
reg2_addr_o <= inst_i[20:16];

对于addi,addiu,slti,sltiu
wreg_o <= `WriteEnable
wd <= inst_i[20:16] //写rt
aluop <=
alusel <= //对应的指令信息
reg1_read_o = 1'b1
reg2_read_o = 1'b0 //对rs进行读
imm <= {{16{inst_i[15]}}+inst_i[15:0]}

对于clz,clo,mul
wreg_o <= `WriteEnable
wd <= inst_i[15:11] //写rd
aluop <=
alusel <= //对应的指令信息
reg1_read_o = 1'b1
reg2_read_o = 1'b0 //对rs进行读

框架:
case (op)
	`EXE_SPECIAL_INST:
			case(op2)
				5'b00000:
					case (op3):
	`EXE_ADDI:
	`EXE_SPECCIAL2_INST:
			case (op3):

EX:

assign reg1_i_not = ~reg1_i;
//注意,verilog有加减乘运算符,溢出通过首位判断
assign reg2_i_mux = ((aluop_i == `EXE_SUB_OP) || (aluop_i == `EXE_SUBU_OP) ||
											 (aluop_i == `EXE_SLT_OP) ) 
											 ? (~reg2_i)+1 : reg2_i;
//如果加法,直接相加,如果减法,reg2取反相加
assign result_sum = reg1_i + reg2_i_mux;	
//判断是否溢出,正正得负,负负得正
assign ov_sum = ((!reg1_i[31] && !reg2_i_mux[31]) && result_sum[31]) ||
    ((reg1_i[31] && reg2_i_mux[31]) && (!result_sum[31]));
//比较大小,如果有符号比较,负<正,正<正(相减为负,所以要取补),负<负(相减为正)
//无符号直接比较
assign reg1_lt_reg2 = ((aluop_i == `EXE_SLT_OP)) ?
	((reg1_i[31] && !reg2_i[31]) ||  (!reg1_i[31] && !reg2_i[31] && result_sum[31])||
	(reg1_i[31] && reg2_i[31] && result_sum[31])) :	(reg1_i < reg2_i);


//乘法,乘数,被乘数有负取补
assign opdata1_mult = (((aluop_i == `EXE_MUL_OP) || (aluop_i == `EXE_MULT_OP))
													&& (reg1_i[31] == 1'b1)) ? (~reg1_i + 1) : reg1_i;

assign opdata2_mult = (((aluop_i == `EXE_MUL_OP) || (aluop_i == `EXE_MULT_OP))
													&& (reg2_i[31] == 1'b1)) ? (~reg2_i + 1) : reg2_i;		

assign hilo_temp = opdata1_mult * opdata2_mult;
//乘数,被乘数一正一负取补码,同号不用改变
if ((aluop_i == `EXE_MULT_OP) || (aluop_i == `EXE_MUL_OP))begin
			if(reg1_i[31] ^ reg2_i[31] == 1'b1) begin
				mulres <= ~hilo_temp + 1;
			end else begin
			  	mulres <= hilo_temp;
			end

仅需改变ID,EX阶段

我写的代码都是大概的内容,是每个阶段的实现难点,完整版放在我的下载中,需要的同学可以参考,参考书籍《自己动手写CPU》

你可能感兴趣的:(CPU设计)