预做实验报告3控制器设计与仿真
一、实验目的
理解并掌握CPU控制器的基本电路结构及其设计方法,学会使用Verilog HDL对电路进行行为建模、结构建模以及仿真测试。
二、实验内容
利用Verilog HDL设计一个多周期处理机控制器,并进行仿真测试。要求该处理机能够实现下列指令系统:
31262521201615540指令000000rd rs1rs2and rd,rs1,rs2 000001rd rs1imme andi rd,rs1,imme 000010rd rs1rs2or rd,rs1,rs2 000011rd rs1imme ori rd,rs1,imme 000100rd rs1rs2add rd,rs1,rs2 000101rd rs1imme addi rd,rs1,imme 000110rd rs1rs2sub rd,rs1,rs2 000111rd rs1imme subi rd,rs1,imme 001000rd rs1imme load rd,rs1,imme 001001rd rs1imme store rd,rs1,imme 001010disp bne disp
001011disp beq disp
001100disp branch disp 要求把指令的执行分为以下5个步骤,每个步骤用一个时钟周期。
1、取指令及PC+1周期
2、指令译码、读寄存器及转移周期
3、ALU执行或者存储器地址计算周期
4、ALU指令结束周期或者存储器访问周期
5、写回周期
如何经营一家服装店
该多周期处理机的数据路径如下:
P C
寄存器堆ALU
A
B
ZER 存储器addres
dataou
datain
CS
OE
WE WRITEME
ALUOP
ZER ZER
WRITEZERO
M U X M U
X
M
U X
1
偏移量符号扩展
立即数符号扩展
WRITEREG DI
AD A
A
Q Q
SELLOAD SELST 偏移量
立即数
rd rs1rs2rd
WRITEPC
M U X
I R
M U X
SELLDST SELALUA
hmc
SELALUB
A
B
IM
cd rom是什么WRITEIR
该多周期处理机的数据路径所需要的控制信号定义如下:
WRITEPC:PC 写使能信号,为1时,CLK 上升沿把PC 输入端的数据写入PC;SELLDST:存储器地址输入选择,为1时,选ALU 计算出的地址,为0选PC;WRITEMEM:写存储器使能信号,由store 指令产生;
WRITEIR:IR 写使能信号,为1时,CLK 上升沿把由PC 访问到的指令写入IR;SELLOAD:寄存器堆数据输入选择,为1时选存储器输出,为0选ALU 输出;SELST:执行store 指令时,从寄存器堆Q2端口读出寄存器rd 的内容;WRITEREG:写寄存器堆使能信号;
SELALUA:ALU A 输入端选择,0选寄存器RS1,1选PC;
SELALUB:ALU B 输入端选择,00选寄存器RS2,01选立即数IM,10选1,11选偏移量;
ALUOP:ALU 操作控制码;
WRITEZERO:写标志寄存器ZERO 的使能信号;三、实验环境
PC 机1台、Modelsim 仿真软件1套。四、实验步骤
1、电路结构设计与逻辑设计电路结构图:
下一状态产生模块控制信号产生模块
状态寄存器
CLK
ZERO OPCODE Q3Q2Q1Q0
D3D2D1D0
Q0Q1Q2
Q3
OPCODE D0D1D2D3
Q0Q1Q2Q3
OPCODE
ZERO WRITEPC SELLDST WRITEMEM WRITEIR SELLOAD SELST
WRITEREG SELALUA SELALUB ALUOP
WRITEZERO
状态转移图:
IF (S0)
ID (S1)
ALURR
(S2)
LDWB (S10)
ALURI (S3)
LOAD (S4)
STORE (S5)
LDMEM (S8)
STMEM (S9)
ALURWB (S6)msb
ALUIWB (S7)
ALUR-R
ALUR-I
load store
branch
IFupx
ID
EXE
MEM WB
状态转移表:
当前状态Q3Q2Q1Q0当前输入下个状态D3D2D1D00000(S0)X 0001(S1)0001(S1)BR 0000(S0)0001(S1)RR 0010(S2)0001(S1)RI 0011(S3)0001(S1)load 0100(S4)0001(S1)store 0101(S5)0010(S2)X 0110(S6)0011(S3)
X
double shot0111(S7)
0100(S4)X1000(S8)
0101(S5)X1001(S9)
0110(S6)X0000(S0)
0111(S7)X0000(S0)
1000(S8)X1010(S10)
1001(S9)X0000(S0)
1010(S10)X0000(S0)
其中:RR=and+or+add+sub(寄存器-寄存器操作);
RI=andi+ori+addi+subi(寄存器-立即数操作);
BR=branch+bne+beq(转移指令);X=任意。
根据上述状态转移表,可以得到下一状态产生电路的逻辑表达式:
D0=S0+S1*RI+S1*store+S3+S5;
D1=S1*RR+S1*RI+S2+S3+S8;really
D2=S1*load+S1*store+S2+S3;
D3=S4+S5+S8;
根据上述控制信号取值表,可以得到控制信号产生电路的逻辑表达式:WRITEPC=S0+S1*BT
SELLDST=S4+S5+S8+S9+S10
WRITEMEM=S9
WRITEIR=S0
SELLOAD=S4+S8+S10
SELST=S5+S9
WRITEREG=S6+S7+S10
SELALUA=S0+S1
SELALUB1=S0+S1
SELALUB0=S1+S3+S4+S5+S7+S8+S9+S10
WRITEZERO=S6+S7
ALUOP1=S0+S1+S2*OP1+S3*OP1+S4+S5+S6*OP1+S7*OP1+S8+S9+S10
ALUOP0=S2*OP0+S3*OP0+S6*OP0+S7*OP0
2、建立Verilog模型
module control(clk,start,zero,opcode,writepc,lldst,writemem,writeir,
lload,lst,writereg,lalua,lalub,aluop,writezero);
input clk,start,zero;
input[5:0]opcode;
output writepc,lldst,writemem,writeir,lload,lst,
writereg,lalua,writezero;
雅思托福的区别output[1:0]lalub,aluop;
reg[3:0]q;
wire[3:0]d;
相信英文wire zero;
always@(podge clk)
begin
if(start)
q<=4'd0;
el
q<=d;
end
assign
d[0]=(~q[3]&~q[2]&~q[1]&~q[0])|((~q[3]&~q[2]&~q[1]&q[0])&(~opcode[3]&op code[0]))|((~q[3]&~q[2]&~q[1]&q[0])&(opcode[3]&~opcode[2]&~opcode[1]&op code[0]))|(~q[3]&~q[2]&q[1]&q[0])|(~q[3]&q[2]&~q[1]&q[0]);
assign
d[1]=((~q[3]&~q[2]&~q[1]&q[0])&(~opcode[3]&~opcode[0]))|((~q[3]&~q[2]&~q [1]&q[0])&(~opcode[3]&opcode[0]))|(~q[3]&~q[2]&q[1]&~q[0])|(~q[3]&~q[2]& q[1]&q[0])|(q[3]&~q[2]&~q[1]&~q[0]);
assign
d[2]=((~q[3]&~q[2]&~q[1]&q[0])&(opcode[3]&~opcode[2]&~opcode[1]&~opcod e[0]))|((~q[3]&~q[2]&~q[1]&q[0])&(opcode[3]&~opcode[2]&~opcode[1]&opcod e[0]))|(~q[3]&~q[2]&q[1]&~q[0])|(~q[3]&~q[2]&q[1]&q[0]);
assign
d[3]=(~q[3]&q[2]&~q[1]&~q[0])|(~q[3]&q[2]&~q[1]&q[0])|(q[3]&~q[2]&~q[1]& ~q[0]);
assign
本笃
writepc=(~q[3]&~q[2]&~q[1]&~q[0])|((~q[3]&~q[2]&~q[1]&q[0])&((opcode[3]& opcode[2]&~opcode[1]&~opcode[0])|(opcode[3]&~opcode[2]&opcode[1]&~opco de[0]&~zero)|(opcode[3]&~opcode[2]&opcode[1]&opcode[0]&zero)));
assign
lldst=(~q[3]&q[2]&~q[1]&~q[0])|(~q[3]&q[2]&~q[1]&q[0])|(q[3]&~q[2]&~q[1] &~q[0])|(q[3]&~q[2]&~q[1]&q[0])|(q[3]&~q[2]&q[1]&~q[0]);
assign writemem=q[3]&~q[2]&~q[1]&q[0];
assign writeir=~q[3]&~q[2]&~q[1]&~q[0];
assign
lload=(~q[3]&q[2]&~q[1]&~q[0])|(q[3]&~q[2]&~q[1]&~q[0])|(q[3]&~q[2]&q[1] &~q[0]);
assign lst=(~q[3]&q[2]&~q[1]&q[0])|(q[3]&~q[2]&~q[1]&q[0]);
assign
writereg=(~q[3]&q[2]&q[1]&~q[0])|(~q[3]&q[2]&q[1]&q[0])|(q[3]&~q[2]&q[1] &~q[0]);
assign lalua=(~q[3]&~q[2]&~q[1]&~q[0])|(~q[3]&~q[2]&~q[1]&q[0]); assign lalub[1]=(~q[3]&~q[2]&~q[1]&~q[0])|(~q[3]&~q[2]&~q[1]&q[0]); assign
lalub[0]=(~q[3]&~q[2]&~q[1]&q[0])|(~q[3]&~q[2]&q[1]&q[0])|(~q[3]&q[2]&~ q[1]&~q[0])|(~q[3]&q[2]&~
q[1]&q[0])|(~q[3]&q[2]&q[1]&q[0])|(q[3]&~q[2]&~q [1]&~q[0])|(q[3]&~q[2]&~q[1]&q[0])|(q[3]&~q[2]&q[1]&~q[0]);
assign writezero=(~q[3]&q[2]&q[1]&~q[0])|(~q[3]&q[2]&q[1]&q[0]);
assign
aluop[1]=(~q[3]&~q[2]&~q[1]&~q[0])|(~q[3]&~q[2]&~q[1]&q[0])|((~q[3]&~q[2] &q[1]&~q[0])&(~opcode[3]&opcode[2]))|((~q[3]&~q[2]&q[1]&q[0])&(~opcode[ 3]&opcode[2]))|(~q[3]&q[2]&~q[1]&~q[0])|(~q[3]&q[2]&~q[1]&q[0])|((~q[3]&q[
2]&q[1]&~q[0])&(~opcode[3]&opcode[2]))|((~q[3]&q[2]&q[1]&q[0])&(~opcode[
3]&opcode[2]))|(q[3]&~q[2]&~q[1]&~q[0])|(q[3]&~q[2]&~q[1]&q[0])|(q[3]&~q[ 2]&q[1]&~q[0]);
assign
aluop[0]=((~q[3]&~q[2]&q[1]&~q[0])&(~opcode[3]&opcode[2]))|((~q[3]&~q[2] &q[1]&q[0])&(~opcode[3]&opcode[2]))|((~q[3]&q[2]&q[1]&~q[0])&(~opcode[3] &opcode[2]))|((~q[3]&q[2]&q[1]&q[0])&(~opcode[3]&opcode[2]));
endmodule