ALU_out=1;
else
ALU_out=0;
default:
ALU_out=0;
endcase
end
ALU控制的代码实现:
moduleALU_ctrl(
input[1:
0]ALUOp,
input[5:
0]funct,
outputreg[2:
0]ALU_ctrl
);
always@(ALUOporfunct)
begin
case(ALUOp)
2'b00:
ALU_ctrl=3'b010;
2'b01:
ALU_ctrl=3'b110;
2'b10:
begin
case(funct)
6'b100000:
ALU_ctrl=3'b010;
6'b100010:
ALU_ctrl=3'b110;
6'b100100:
ALU_ctrl=3'b000;
6'b100101:
ALU_ctrl=3'b001;
6'b101010:
ALU_ctrl=3'b111;
default:
ALU_ctrl=0;
endcase
end
endcase
end
endmodule
数据存储单元:
是一个状态单元,有读写控制信号、地址和数据端口。
两个输入是地址和所写数据,一个输出位为出内容,读写控制信号是独立的,任意始终只能激活一个。
存数指令,要从寄存器堆中读出要存的数据;
取数指令,则要将刚从存储器中取出的数放入寄存器堆中指定寄存器中。
实现代码:
begin
case({ctrl_write,ctrl_read})
2'b01:
out=mem[addr];
2'b10:
mem[addr]=data;
default:
$display("error");
endcase
end
MUX:
二选一数据选择器,通过控制信号的值来选择输出。
实现代码:
always@(*)
if(ctrl==0)out=in0;
elseout=in1;
寄存器堆:
实现代码:
always@(in1orin2)
begin
case(in1)
5'b00101:
data1<=32'h001c;
5'b01111:
data1<=32'h0004;
5'b00000:
data1<=32'h0008;
5'b10000:
data1<=32'h000c;
5'b10001:
data1<=32'h000c;
default:
data1<=mem[writeaddr];
endcase
case(in2)
5'b00101:
data2<=32'h001c;
5'b01111:
data2<=32'h0004;
5'b00000:
data2<=32'h0008;
5'b10000:
data2<=32'h000c;
5'b10001:
data2<=32'h000c;
default:
data2<=mem[writeaddr];
endcase
end
always@(RegWriteorwriteaddrorwritedata)begin
mem[writeaddr]<=writedata;
end
endmodule
符号扩展器:
将指令中16位有符号数扩展成32位有符号数
符号代码:
modulesignal_extend(
input[15:
0]in,
output[31:
0]out
);
assignout={16'b0,in};
endmodule
取指部件:
首先要从存储器中将指令取出。
为准备执行。
下一条指令,也必须把程序计数器加到指向下一条指令,即向后移动四字节。
此时所需的取指令以及增加PC以获得下一时序指令的地址相对应的数据通路,图如右:
代码:
always@(posedgeclkorposedgereset)
begin
if(reset)PC<=0;
elsePC<=PCnext;
end
根据分治设计策略,确定模块间的连接关系,端口方向及宽度,将每一模块通过控制信号联系起来,最终形成完整的数据通路。
综合:
moduletop(
inputclk,
inputreset,
output[31:
0]PCnext,
output[4:
0]addr_regwrite,
output[31:
0]data_regwrite,
output[31:
0]signal_extend
);
wire[31:
0]PC;
wire[31:
0]instruction;
wireRegDst,Jump,Branch,MemRead,MemtoReg,MemWrite,ALUSrc,RegWrite,zero;
wire[1:
0]ALUOp;
//wire[4:
0]addr_regwrite;
wire[31:
0]data1,data2,
ALU2,ALUout,memdata,
signal_extend_l,PCnew,add2out,mux4out,
jumpaddr_l;
wire[2:
0]ALUctrl;
wire[31:
0]jumpaddr;
instruction_regins_reg(.pc(PC),.ins(instruction));
controlcon(.in(instruction[31:
26]),.RegDst(RegDst),
.Jump(Jump),.Branch(Branch),
.MemRead(MemRead),.MemtoReg(MemtoReg),
.ALUOp(ALUOp),
.MemWrite(MemWrite),.ALUSrc(ALUSrc),
.RegWrite(RegWrite));
mux#(5)mux1_datareg(.in0(instruction[20:
16]),
.in1(instruction[15:
11]),
.out(addr_regwrite),
.ctrl(RegDst));
data_regdata_reg(.in1(instruction[25:
21]),
.in2(instruction[20:
16]),
.writeaddr(addr_regwrite),
.writedata(data_regwrite),
.data1(data1),.data2(data2),
.RegWrite(RegWrite));
signal_extends_extend(.in(instruction[15:
0]),
.out(signal_extend));
mux#(32)mux2_ALU(.in1(signal_extend),.in0(data2),.out(ALU2),.ctrl(ALUSrc));
ALUALU(.in1(data1),.in2(ALU2),.ALU_out(ALUout),.ctrl(ALUctrl),.zero(zero));
data_memdata_mem(.addr(ALUout),.data(data2),.ctrl_read(MemRead),
.out(memdata),.ctrl_write(MemWrite));
mux#(32)mux3_datareg(.in1(memdata),.in0(ALUout),.out(data_regwrite),.ctrl(MemtoReg));
left_shiftlshift1(.in(signal_extend),.out(signal_extend_l));
left_shiftlshift2(.in(instruction),.out(jumpaddr_l));
addadd1(.in1(PC),.in2(32'b100),.out(PCnew));
addadd2(.in1(signal_extend_l),.in2(PCnew),.out(add2out));
mux#(32)mux4_PCnew(.in0(PCnew),.in1(add2out),.out(mux4out),.ctrl(zero&Branch));
/**/mux#(32)mux5_PCnext(.in0(mux4out),.in1(jumpaddr),.out(PCnext),.ctrl(Jump));
ALU_ctrlALU_ctrl(.ALUOp(ALUOp),.funct(instruction[5:
0]),.ALU_ctrl(ALUctrl));
PCPC0(.clk(clk),.reset(reset),.PCnext(PCnext),.PC(PC));
assignjumpaddr={PCnew[31:
28],jumpaddr_l[27:
0]};
endmodule
第四部分验证方案及结果分析
1、加载存储指令:
lw$s1,immt($t7)
32'h08:
ins={6'b100011,5'b00101,5'b10001,16'h0001};
其中immt($t7)指向的内存地址中存的数为32’b0101
//sw$s0,immt($t7)
32'h04:
ins={6'b101011,5'b00101,5'b00101,16'h0001};
其中$s0寄存器中存的值为32’b1000,$t7存的数据32’h001c
2、算术逻辑运算:
加法指令:
add$s0,$a1,$t7
32'h00:
ins={6'b000000,5'b00101,5'b01111,5'b10000,5'b00000,6'b100000};
其中$a1存的数据是32’h001c,$t7存的数据是32’h0001
减法指令:
sub$s0,$a1,$t7
32'h00:
ins={6'b000000,5'b00101,5'b01111,5'b10000,5'b00000,6'b100010};
其中$a1存的数据是32’h001c,$t7存的数据是32’h0004
与运算:
and$s0,$a1,$t7
32'h00:
ins={6'b000000,5'b00101,5'b01111,5'b10000,5'b00000,6'b100100};
其中$a1存的数据是32’h001c,$t7存的数据是32’h0004
或运算
or$s0,$a1,$t7
32'h00:
ins={6'b000000,5'b00101,5'b01111,5'b10000,5'b00000,6'b100101};
其中$a1存的数据是32’h001c,$t7存的数据是32’h0004
Slt运算:
slt$s0,$a1,$t7
32'h00:
ins={6'b000000,5'b00101,5'b01111,5'b10000,5'b00000,6'b101010};
其中$a1存的数据是32’h001c,$t7存的数据是32’h0004
3、分支指令:
bne$s0,$s1,start
32'h04:
ins={6'b000100,5'b10000,5'b10001,16'b0100};
其中$s0=$s2=32’h000c
4、跳转:
J1000
32'h04:
ins={6'b000010,26'h08};
第五部分性能评估:
综合结果:
面积报告:
****************************************
Report:
area
Design:
top
Version:
C-2009.06
Date:
TueSep415:
27:
352012
****************************************
Library(s)Used:
typical(File:
/export/homeO1/smic018/typical.db)
Numberofports:
103
Numberofnets:
634
Numberofcells:
156
Numberofreferences:
30
Combinationalarea:
73589.947530
Noncombinationalarea:
48009.932091
NetInterconnectarea:
518795.906769
Totalcellarea:
121599.879621
Totalarea:
640395.786390
时序报告:
****************************************
Report:
timing
-pathfull
-delaymax
-max_paths1
Design:
top
Version:
C-2009.06
Date:
TueSep415:
27:
462012
****************************************
OperatingConditions:
typicalLibrary:
typical
WireLoadModelMode:
top
Startpoint:
PC0/PC_reg[21]
(risingedge-triggeredflip-flopclockedbyclk)
Endpoint:
data_regwrite[25]
(outputportclockedbyclk)
PathGroup:
clk
PathType:
max
Des/Clust/PortWireLoadModelLibrary
------------------------------------------------
topsmic18_wl10typical
PointIncrPath
-----------------------------------------------------------
clockclk(riseedge)0.000.00
clocknetworkdelay(ideal)0.000.00
PC0/PC_reg[21]/CK(DFFRHQX4)0.000.00r
PC0/PC_reg[21]/Q(DFFRHQX4)0.220.22r
PC0/PC[21](PC)0.000.22r
ins_reg/pc[21](instruction_reg)0.000.22r
ins_reg/U53/Y(NOR2X4)0.060.28f
ins_reg/U37/Y(NAND4X4)0.110.39r
ins_reg/U55/Y(NOR2X4)0.050.44f
ins_reg/U56/Y(NAND2X4)0.080.52r
ins_reg/U38/Y(BUFX20)0.100.63r
ins_reg/U31/Y(NOR2X4)0.060.69f
ins_reg/ins[28](instruction_reg)0.000.69f
con/in[2](control)0.000.69f
con/U29/Y(NOR2X4)0.090.78r
con/U33/Y(NAND3X4)0.060.84f
con/U34/Y(NOR2X4)0.100.94r
con/RegDst(control)0.000.94r
mux1_datareg/ctrl(mux_N5)0.000.94r
mux1_datareg/U1/Y(BUFX20)0.101.05r
mux1_datareg/U10/Y(OAI2BB2X4)0.131.17r
mux1_datareg/out[1](mux_N5)0.001.17r
U25/Y(BUFX16)0.101.28r
data_reg/writeaddr[1](data_reg)0.001.28r
data_reg/U368/Y(NAND2BX4)0.121.39r
data_reg/U365/Y(INVX8)0.051.44f
data_reg/U362/Y(INVX8)0.061.50r
data_reg/U265/Y(OR2X4)0.091.59r
data_reg/U101/Y(AND2X4)0.101.69r
data_reg/U306/Y(NAND2X4)0.061.74f
data_reg/U377/Y(NOR2X4)0.091.83r