湘潭大学计算机原理试验四多周期MIPSCPU存储器试验预习报告解析.docx
《湘潭大学计算机原理试验四多周期MIPSCPU存储器试验预习报告解析.docx》由会员分享,可在线阅读,更多相关《湘潭大学计算机原理试验四多周期MIPSCPU存储器试验预习报告解析.docx(21页珍藏版)》请在冰豆网上搜索。
湘潭大学计算机原理试验四多周期MIPSCPU存储器试验预习报告解析
实验四多周期MIPSCPU+存储器实验
一.实验目的
1、深入理解MIPS—CPU指令系统的功能和工作原理;
2、掌握多周期CPU的工作原理和逻辑功能实现;
3、熟练掌握用VerilogHDL语言设计多周期存储器的方法;
4、熟练掌握对多周期存储器的仿真实验验证和硬件测试两种调试方法;
5、通过对多周期CPU的运行情况进行观察和分析,进一步加深理解。
二.实验设备
硬件:
现代计算机组成原理实验系统(兼)
Nios32位嵌入式系统实验开发平台
EP1C12Q240
Core(TM)i3-3240CPU@3.40GHz3.39GHz1.91GB的内存
软件:
QuartusII13.0sp1
MicrosoftWindowsxp
三.实验内容
1、设计一个32位MIPS多周期CPU:
至少运行下列的6类32条MIPS指令。
(1)and、sub、addi
(2and、0r、xor、andi、ori、xori
(3sll、srl、sra
(4)beq、bne、
(5)j、jr
(6)lw、sw
2.设计一个存储器
四.实验原理与步骤
实现上述原理框图根据功能将其分划分为控制单元(cunit)、执行单元(eunit)、指令单元(iunit)
以及存储单元(munit)四大模块。
(1).控制单元(cunit)
行等工作。
主要由指令译码器控制器(outputscontrol)、算术逻辑运算控制器(ALUcontrol)两个子模块组成。
(2).执行单元(eunit)主要由寄存器堆(registers)和算术逻辑单元(ALU)两个子模块组成。
其MIPS系统的寄存器堆由32个32
ALU等逻辑运算。
指令单元(iunit)的作用是决定下一条指令的地址PC
(3).存储单元(munit)由存储器(memory)、指令寄存器(instructionregister)和存储数据寄存器(memorydataregister)组成。
五.实验源代码
寄存器元件代码:
moduleregfile(rna,rnb,d,wn,we,clk,clrn,qa,qb);
input
[4:
0]
rna,rnb,wn;
input
[31:
0]
d;
input
we,clk,clrn;
output
[31:
0]
qa,qb;
reg
[31:
0]
register[1:
31];
//r1-r31
assign
qa=(rna==
0)?
0:
register[rna];
//read
assign
qb=(rnb==
0)?
0:
register[rnb];
//read
always@(posedgeclkornegedgeclrn)begin
if(clrn==0)begin//reset
integeri;
for(i=1;i<32;i=i+1)register[i]<=0;
end
elsebegin
if((wn!
=0)&&(we==1))//write
register[wn]<=d;
endendendmodule
32位四选一选择器:
modulemux4x32(a0,a1,a2,a3,s,y);
input[31:
0]
a0,a1,a2,a3;
input[1:
0]
s;
output[31:
0]
y;
function[31:
0]
select;
input[31:
0]
a0,a1,a2,a3;
input[1:
0]
s;
case(s)
2'b00:
select
=a0;
2'b01:
select
=a1;
2'b10:
select
=a2;
2'b11:
select
=a3;
endcaseendfunction
5位二选一选择器:
modulemux2x5(a0,a1,s,y);
input[4:
0]a0,a1;
inputs;
output[4:
0]y;
assigny=s?
a1:
a0;
endmodule
32位二选一选择器:
modulemux2x32(a0,a1,s,y);
input
[31:
0]
a0,a1;
input
s;
output
[31:
0]
y;
assign
y=s?
a1:
a0;
endmodule
存储器元件:
modulemcmem(clk,dataout,datain,addr,we,inclk,outclk);
input
[31:
0]
datain;
input
[31:
0]
addr;
input
clk,we,inclk,outclk;
output
[31:
0]
dataout;
wire
write_enable=we&~clk;
lpm_ram
dq
ram
(.data(datain),.address(addr[7:
2]),.we(write_enable),.inclock(inclk),.outclock(outclk),.q(dataout));
defparam
ram.lpm_width
=32;
defparam
ram.lpm_widthad
=6;
defparam
ram.lpm_indata
="registered";
defparam
ram.lpm_outdata
="registered";
defparam
ram.lpm_file
="mcmem.mif";
defparam
ram.lpm_address_control
="registered";
endmodule
控制部件:
modulemccu(op,func,z,clock,resetn,wpc,wir,wmem,wreg,iord,regrt,m2reg,aluc,shift,alusrca,alusrcb,pcsource,jal,sext,state);
input[5:
0]op,func;
inputz,clock,resetn;
outputregwpc,wir,wmem,wreg,iord,regrt,m2reg;
outputreg[3:
0]aluc;
outputreg[1:
0]alusrcb,pcsource;
outputregshift,alusrca,jal,sext;
outputreg[2:
0]state;
reg[2:
0]next_state;
parameter[2:
0]sif=
3'b000,
//IFstate
sid=
3'b001,
//IDstate
sexe=
3'b010,
//EXEstate
smem
=3'b011,
//MEMstate
swb=
3'b100;
//WBstate
wirer_type,i_add,i_sub,i_and,i_or,i_xor,i_sll,i_srl,i_sra,i_jr;
wirei_addi,i_andi,i_ori,i_xori,i_lw,i_sw,i_beq,i_bne,i_lui,i_j,i_jal;and(r_type,~op[5],~op[4],~op[3],~op[2],~op[1],~op[0]);and(i_add,r_type,func[5],~func[4],~func[3],~func[2],~func[1],~func[0]);and(i_sub,r_type,func[5],~func[4],~func[3],~func[2],func[1],~func[0]);and(i_and,r_type,func[5],~func[4],~func[3],func[2],~func[1],~func[0]);and(i_or,r_type,func[5],~func[4],~func[3],func[2],~func[1],func[0]);and(i_xor,r_type,func[5],~func[4],~func[3],func[2],func[1],~func[0]);and(i_sll,r_type,~func[5],~func[4],~func[3],~func[2],~func[1],~func[0]);and(i_srl,r_type,~func[5],~func[4],~func[3],~func[2],func[1],~func[0]);and(i_sra,r_type,~func[5],~func[4],~func[3],~func[2],func[1],func[0]);and(i_jr,r_type,~func[5],~func[4],func[3],~func[2],~func[1],~func[0]);and(i_addi,~op[5],~op[4],op[3],~op[2],~op[1],~op[0]);and(i_andi,~op[5],~op[4],op[3],op[2],~op[1],~op[0]);and(i_ori,~op[5],~op[4],op[3],op[2],~op[1],op[0]);and(i_xori,~op[5],~op[4],op[3],op[2],op[1],~op[0]);and(i_lw,op[5],~op[4],~op[3],~op[2],op[1],op[0]);and(i_sw,op[5],~op[4],op[3],~op[2],op[1],op[0]);and(i_beq,~op[5],~op[4],~op[3],op[2],~op[1],op[0]);and(i_bne,~op[5],~op[4],~op[3],op[2],~op[1],op[0]);and(i_lui,~op[5],~op[4],op[3],op[2],op[1],op[0]);and(i_j,~op[5],~op[4],~op[3],~op[2],op[1],~op[0]);and(i_jal,~op[5],~op[4],~op[3],~op[2],op[1],op[0]);
wirei_shift;
or(i_shift,i_sll,i_srl,i_sra);
always@*begin
//controlsignals'dfaultoutputs:
wpc=
0;
//donotwritepc
wir=
0;
//donotwriteir
wmem
=0;
//donotwritememory
wreg=
0;
//donotwriteregisterfile
iord=
0;
//selectpcasmemoryaddress
aluc=
4'bx000;
//ALUoperation:
add
alusrca=
0;
//ALUinputa:
regaorsa
alusrcb=
2'h0;
//ALUinputb:
regb
regrt=
0;
//regdestno:
rd
m2reg
=0;
//selectregc
shift=
0;
//selectrega
pcsource=
2'h0;
//selectaluoutput
jal=0;
//notajal
sext
=1;
//signextend
case(state)
//---
-IF:
sif:
begin
//IFstate
wpc=
1;
//writepc
wir=
1;
//writeIR
alusrca=
1;
//PC
alusrcb=
2'h1;
//4
next_state=
sid;
//nextstate:
ID
end
//---
-ID:
sid:
begin
//IDstate
if(i_j)begin
//jinstruction
pcsource
=2'h3;
//jumpaddress
wpc
=1;
//writePC
next_state
=sif;
//nextstate:
IF
end
elseif(i_jal)begin
//jalinstruction
pcsource
=2'h3;
//jumpaddress
wpc
=1;
//writePC
jal
=1;
//regno=31
wreg
=1;
//savePC+4
next_state
=sif;
//nextstate:
IF
end
elseif(i_jr)begin
//jrinstruction
pcsource
=2'h2;
//jumpregister
wpc
=1;
//writePC
next_state
=sif;
//nextstate:
IF
end
elsebegin
//otherinstruction
aluc
=4'bx000;
//add
alusrca
=1;
//PC
alusrcb
=2'h3;
//branchoffset
next_state
=sexe;
//nextstate:
EXE
end
end
//EXE:
sexe:
begin//EXEstate
aluc[3]=i_sra;
aluc[2]=i_sub|i_or|i_srl|i_sra|i_ori|i_lui;
aluc[1]
i_xor|i_sll|i_srl|i_sra|i_xori|i_beq|i_bne|
i_lui;
|i_srl|i_sra|i_andi|i_ori;//beqorbneinstruction//branchaddress
//nextstate:
IF
//otherinstruction
//lworswinstruction
//selectoffset
//nextstate:
MEM
//otherinstruction
//shiftinstruction
aluc[0]=i_and|i_or|i_sll
if(i_beq||i_bne)begin
pcsource=2'h1;
wpc=i_beq&z|i_bne&~z;//writePCnext_state=sif;
end
elsebegin
if(i_lw||i_sw)begin
alusrcb=2'h2;
next_state=smem;
end
elsebegin
if(i_shift)
shift=1;
if(i_addi||i_andi||i_ori||i_xori||i_lui)
alusrcb=
2'h2;
//selectimmediate
if(i_andi||i_ori||
i_xori)
sext=
0;
//0-extend
next_state=
swb;
//nextstate:
WB
endendend
//MEM:
smem:
begin//MEMstate
iord=1;//memoryaddress=C
if(i_lw)begin
next_state=swb;//nextstate:
WB
end
elsebegin//storewmem=1;//writememorynext_state=sif;//nextstate:
IF
end
end
//WB:
swb:
begin//WBstate
if(i_lw)
m2reg=1;//selectmemorydata
if(i_lw||i_addi||i_andi||i_ori||i_xori||i_lui)
regrt=1;//regdestno:
rt
wreg=1;//writeregisterfile
next_state=sif;//nextstate:
IF
end
//
END
default:
beginnext_stateend
endcase
end
//stateregisters
always@(posedgeclockornegedgeresetn)beginif(resetn==0)beginstate<=sif;
end
elsebegin
state<=next_state;
end
end
endmodule
32位带使能端触发器:
moduledffe32(d,clk,clrn,e,q);
input[31:
0]d;
inputclk,clrn,e;
output[31:
0]q;
reg[31:
0]q;
always@(negedgeclrnorposedgeclk)
if(clrn==0)begin
q<=0;
end
elsebegin
if(e==1)q<=d;
end
endmodule
32位触发器:
moduledff32(d,clk,clrn,q);
input[31:
0]d;
inputclk,clrn;
output[31:
0]q;
reg[31:
0]q;
always@(negedgeclrnorposedgeclk)
if(clrn==0)begin
q<=0;
endelsebeginq<=d;
end
endmodule
ALU计算部件:
modulealu(a,b,aluc,r,z);
input[31:
0]a,b;input[3:
0]aluc;output[31:
0]r;outputz;
assignr=cal(a,b,aluc);
assignz=~|r;function[31:
0]cal;
input[31:
0]a,b;
input[3:
0]aluc;
casex(aluc)
4'bx000:
cal=a+b;4'bx100:
cal=a-b;4'bx001:
cal=a&b;4'bx101:
cal=a|b;4'bx010:
cal=a^b;4'bx110:
cal={b[15:
0],16'h0};4'bx011:
cal=b<0];4'b0111:
cal=b>>a[4:
0];
4'b1111:
cal=$signed(b)>>>a[4:
0];
endcase
endfunctionendmodule
其他部件:
modulef(reg_dest,jal,wn);
input
[4:
0]
reg_dest;
input
jal;
output
[4:
0]
wn;
assign
wn=
reg_dest|{5{jal}};
endmodule
modulesa(di,dot);input[4:
0]di;output[31:
0]dot;assigndot={27'b0,di};
endmodule
moduleout4(out);output[31:
0]out;assignout=32'h4;
endmodule
modulee(immin,sext,immediate,offset);
input
[15:
0]
immin;
input
sext;
output
[31:
0]
immediate,offset;
wire
e=
sext&immin[15];
wire
[15:
0]
imm=
{16{e}};
assign
offset=
{imm[13:
0],immin[15:
0],1'b0,1'b0};
assign
immediate=
{imm,immin[15:
0]};
endmodule
modulecombine(address,pc,add);
input
[25:
0]
address;
input
[3:
0]
pc;
output
[31:
0]
add;
assign
add=
{pc[3:
0],address[25:
0],1'b0,1'b0};
endmodule
moduleconvert1(dain,sain,op,func,rs,rt,rd,imm,addr);
input
[31:
0]dain;
output
[4:
0]
sain,rs,rt,rd;
output
[5:
0]
op,func;
output
[15:
0]
imm;
output
[25:
0]
addr;
assign
sain=
{dain[10:
6]};
assign
op
={dain[31:
26]};
assign
func