杭电计组实验九Word文档格式.docx
《杭电计组实验九Word文档格式.docx》由会员分享,可在线阅读,更多相关《杭电计组实验九Word文档格式.docx(17页珍藏版)》请在冰豆网上搜索。
0]rd;
//rd地址
0]rs_data;
//rs数据
0]rt_data;
//rt数据
0]rd_data;
//rd数据
0]PC;
0]PC_new;
outputZF;
outputOF;
outputWrite_Reg;
//是否写入
0]W_Data;
outputrd_rt_s;
//控制那个作为目的寄存器
0]W_Addr;
//目的操作数地址
output[15:
0]imm;
//立即数
0]imm_data;
//被扩展的立即数
outputimm_s;
//是否需要扩展
outputrt_imm_s;
//B端选择rt或者是imm
0]ALU_B;
//ALU_B端口数据
outputMem_Write;
//是否写入数据rom
0]M_R_Data;
//从数据rom读出来的数据
0]ALU_Data;
//ALU运算出来的结果,根据alu_mem_s选择由M_W_Data或者W_Data来赋值
outputalu_mem_s;
//看上面
//读指令
ex7pc(
.clka(clk),
.douta(inst),
.rst(reset),
.PC(PC),
.PC_new(PC_new)
//解析指令
);
analysis_instanalysis_inst(
.inst(inst),
.ALU_OP(ALU_OP),
.rs(rs),
.rt(rt),
.rd(rd),
.Write_Reg(Write_Reg),
.imm(imm),
.rd_rt_s(rd_rt_s),
.imm_s(imm_s),
.rt_imm_s(rt_imm_s),
.Mem_Write(Mem_Write),
.alu_mem_s(alu_mem_s)
//读取源操作数的值:
assignW_Addr=(rd_rt_s)?
rt:
rd;
assignimm_data=(imm_s)?
{{16{imm[15]}},imm}:
{{16{1'
b0}},imm};
reg1Reg(
.R_Addr_A(rs),
.R_Addr_B(rt),
.Clk(clk),
.W_Addr(W_Addr),
.W_Data(W_Data),
.R_Data_A(rs_data),
.R_Data_B(rt_data),
.Reset(reset),
.Write_Reg(Write_Reg)//不写入
assignALU_B=(rt_imm_s)?
imm_data:
rt_data;
//对源操作数运算,存于目的操作数
ex3ALU(
.ALU_OP(ALU_OP),
.A(rs_data),
.B(ALU_B),
.F(ALU_Data),
.ZF(ZF),
.OF(OF)
//----
wireclk_temp;
wired_outn;
regd_out=0;
assignclk_temp=clk^d_out;
assignd_outn=~d_out;
always@(posedgeclk_temp)
begin
d_out<
=d_outn;
end
//数据存储器
Data_RomDatarom(
.clka(clk_temp),//inputclka
.wea(Mem_Write),//input[0:
0]wea
.addra(ALU_Data[5:
0]),//input[5:
0]addra
.dina(rt_data),//input[31:
0]dina
.douta(M_R_Data)//output[31:
0]douta
);
assignW_Data=alu_mem_s?
M_R_Data:
ALU_Data;
endmodule
pc模块:
moduleex7(clka,douta,rst,PC,PC_new
inputrst;
inputclka;
outputwire[31:
0]douta;
outputreg[31:
wire[31:
0]dina;
reg[0:
0]wea;
assignPC_new=PC+4;
initial
PC=32'
h00000000;
wea=0;
ex77regrom(
.clka(clka),//inputclka
.wea(wea),//input[0:
.addra(PC[7:
2]),//input[5:
.dina(dina),//input[31:
.douta(douta)//output[31:
always@(posedgerstorposedgeclka)
begin
if(rst)
PC<
=32'
else
PC<
=PC_new;
analysis_inst模块:
moduleanalysis_inst(
inst,ALU_OP,rs,rt,rd,Write_Reg,imm,rd_rt_s,imm_s,rt_imm_s,Mem_Write,alu_mem_s
input[31:
outputreg[2:
outputreg[4:
outputregWrite_Reg;
outputreg[15:
outputregrd_rt_s;
outputregimm_s;
outputregrt_imm_s;
outputregMem_Write;
outputregalu_mem_s;
always@(*)
//--------------------处理R型指令----------------------
if(inst[31:
26]==6'
b000000)//判断是否为R型
begin
rd=inst[15:
11];
//rd
rt=inst[20:
16];
//rt
rs=inst[25:
21];
//rs
alu_mem_s=0;
//以alu结果输出
Mem_Write=0;
//是否写入数据存储器
rd_rt_s=0;
//rd作为目的存储器
rt_imm_s=0;
//rt作为源操作数
Write_Reg=(inst[5:
0]==0)?
1'
b0:
b1;
case(inst[5:
0])//映射对应的ALU
6'
b100000:
ALU_OP=3'
B100;
6'
b100010:
B101;
b100100:
B000;
b100101:
B001;
b100110:
B010;
b100111:
B011;
b101011:
B110;
b000100:
B111;
endcase
end
//------------------处理I型立即寻址指令------------------------
29]==3'
b001)
imm=inst[15:
0];
rd_rt_s=1;
//rt作为目的存储器
rt_imm_s=1;
//imm作为源操作数
Write_Reg=1;
//判断属于那条指令
case(inst[31:
26])
b001000:
beginimm_s=1;
ALU_OP=3'
b001100:
beginimm_s=0;
b001110:
b001011:
endcase
//----------------处理I型取数/存数指令------------------
30]==2'
b10&
&
inst[28:
26]==3'
b011)
imm_s=1;
//读取数据时,以mem输出的数据写入,所以alu_mem_s=1;
b100011:
beginalu_mem_s=1;
Write_Reg=1;
beginMem_Write=1;
Write_Reg=0;
Reg模块
modulereg1(R_Addr_A,R_Addr_B,Clk,W_Addr,W_Data,R_Data_A,R_Data_B,Reset,Write_Reg
inputClk,Reset;
inputwireWrite_Reg;
inputwire[4:
0]R_Addr_A;
0]W_Addr;
0]R_Addr_B;
inputwire[31:
reg[31:
0]REG_Files[31:
0]R_Data_A;
0]R_Data_B;
integeri=0;
always@(posedgeClkorposedgeReset)//下降沿存储
if(Reset)//初始化
for(i=0;
i<
=31;
i=i+1)
REG_Files[i]<
else
begin
if(Write_Reg)
REG_Files[W_Addr]<
=W_Data;
end
assignR_Data_A=REG_Files[R_Addr_A];
assignR_Data_B=REG_Files[R_Addr_B];
ALU模块:
moduleex3(ALU_OP,A,B,F,ZF,OF
input[2:
input[31:
0]A,B;
outputreg[31:
0]F;
outputregZF,OF;
regC32,C31;
reg[7:
0]i;
case(ALU_OP)
3'
b000:
F=A&
B;
b001:
F=A|B;
b010:
F=A^B;
b011:
F=~(A|B);
b100:
begin{C32,F}=A+B;
OF=C32^A[31]^B[31]^F[31];
b101:
begin{C32,F}=A-B;
b110:
beginif(A<
B)
F=1;
else
F=0;
b111:
F=B<
<
A;
default:
beginend
ZF=((F==32'
h00000000)?
1:
0);
二、仿真波形
三、电路图
四、引脚配置(约束文件)
五、思考与探索
##MIPS的I型立即数寻址指令和数据通路
为实现`立即数寻址指令`需要以下变化
-
`目的寄存器`的**可选性**
增加以
`rd_rt_s`为判断的二选以**选择器**
若`rd_rt_s=0`
则`rd`作为`目的寄存器`(W_Addr)
若`rd_rt_s=1`
则`rt`作为`目的寄存器`(W_Addr)
`rd_rt_s`
在**指令解析**时赋值。
`assignW_Addr=(rd_rt_s)?
`
立即数`imm`被扩展
增加`imm_s`控制是否**符号扩展**。
`assignimm_data=(imm_s)?
符号扩展
带符号运算指令
`addi`
存数,取数的偏移量`offset`
无符号扩展
无符号运算指令
`addiu`
`sltiu`
逻辑运算指令
`andi`
`xori`
`ALU`运算的扩展
增加以`rt_imm_s`为判断依据选择ALU_B端数据。
`rt_imm_s=0`
读rt
`rt_imm_s=``读imm
解析时的几个新的需要被赋值的变量
`imm_s`
`rd_rt_s`
`rt_imm_s`
增加I型指令的判断
if(inst[31:
imm=inst[15:
rt=inst[20:
//rt
rs=inst[25:
//rs
rd_rt_s=1;
rt_imm_s=1;
//判断属于那条指令
case(inst[31:
6'
endcase
测试指令
>
在00832820指令后(即`add$5,$4,$3`此时`$5=0000_0005`)后加入一条`addi$6$5FFFFFFFF`机器码为(`001000_00101_00110_1111111111111111=20A6FFFF`)
即$5+(-1)=$6,结果`$6=0000_0004`
##处理I型取数/存数指令及其数据通路
新增一个数据存储器RAM
`Mem_Write`控制写入
由译码处确定
`Mem_Addr`控制地址
由`ALU`计算得出
`M_W_Data`写入数据,由寄存器`rt_data`确定
`M_R_Data`读出来的数据,根据`alu_mem_s`来判定这个写进`W_Data`。
有效地址计算
通过ALU实现。
`rt_imm_s`=1;
`imm_s`=1;
使存储器的clk是CPU的clk的两倍
不这样的话,会使CPU还没读指令,存储器已经处理完了,但是结果不正确。
reg
d_out=0;
d_out<
//数据存储器
Data_RomDatarom(
.clka(clk_temp),//inputclka
.wea(Mem_Write),//input[0:
.addra(ALU_Data[5:
.dina(rt_data),//input[31:
.douta(M_R_Data)//output[31:
六、意见和建议
1.无