基于MIPS指令集的简单CPU设计(20条指令)代码及注释
数据通路图:
自底向下,一个模块一个模块来
ALU:
alu.v
module alu (a,b,aluc,r,z);
input [31:0] a,b; //源操作数
input [3:0] aluc; //操作控制码
output [31:0] r; //零标志位
output z;
wire [31:0] d_and = a & b; //x 0 0 1 AND
wire [31:0] d_or = a | b; //x 1 0 1 0R
wire [31:0] d_xor = a ^ b; //x 0 1 0 XOR
wire [31:0] d_lui = {b[15:0],16'h0}; //x 1 1 0 LUI 高16是所给数据b得低16位,低16位补零
wire [31:0] d_and_or = aluc[2]?d_or : d_and; //选择获取按位与还是按位或运算
wire [31:0] d_xor_1ui= aluc[2]?d_lui : d_xor; //选择获取异或还是LUI运算
wire [31:0] d_as,d_sh;
addsub32 as32 (a,b,aluc[2],d_as); //x 0 0 0 ADD
//x 1 0 0 SUB
shift shifter (b,a[4:0],aluc[2],aluc[3],d_sh) ; //0 0 1 1 SLL
//0 1 1 1 SRL
//1 1 1 1 SRA
mux4x32 se1ect (d_as,d_and_or, d_xor_1ui, d_sh, aluc[1:0],r);
assign z = ~|r;
endmodule
//alu运算逻辑单元
addsub32.v
module addsub32(a,b,sub,s);
input [31:0] a,b;
input sub;
output [31:0] s;
cla32 as32 (a,b^{32{sub}},sub,s);
endmodule
//减法相当于加上一个负数
//加减法运算模块,加减取决于sub,加法运算0,减法运算1
//若sub为0, 任何-一个数b异或0为本身, 此时b" {32 {sub}=b, 加法;
//若sub为1, 任何一个数b异或I为其取反,此时b^ {32{sub}=~b, 减法。
cla32.v
//先行进位加法器,能够快速产生进位位,用到了一种树形进位产生算法
//产生32位加法结果和进位输出
module cla32 (a,b,ci,s,co);
input [31:0] a,b;
input ci;
output [31:0] s;
output co;
wire g_out,p_out;
cla_32 cla (a,b, ci,g_out,p_out, s);
assign co = g_out| p_out & ci;
endmodule
//一位加法器的代码
//g为进位产生函数,p为进位传递函数
module add(a,b,c,g,p,s);
input a,b,c;
output g,p,s;
assign s = a^b^c;
assign g = a & b;
assign p = a | b;
endmodule
//gp生成器
module g_p (g,p,c_in,g_out,p_out,c_out);
input [1:0] g,p;
input c_in;
output g_out, p_out, c_out;
assign g_out = g[1]|p[1] & g[0];
assign p_out = p[1] & p[0];
assign c_out = g[0] | p[0] & c_in;
endmodule
//2位先行进位加法器,用了两个一位加法器和一个GP生成器
module cla_2 (a,b,c_in,g_out,p_out,s) ;
input [1:0] a,b;
input c_in;
output g_out, p_out;
output [1:0] s;
wire [1:0] g,p;
wire c_out;
add add0 (a[0],b[0],c_in, g[0],p[0],s[0]);
add add1 (a[1],b[1],c_out, g[1],p[1],s[1]);
g_p g_p0 (g,p,c_in, g_out,p_out,c_out);
endmodule
module cla_4 (a,b, c_in,g_out,p_out,s);
inpu