cpuxiong.docx

上传人:b****7 文档编号:23355933 上传时间:2023-05-16 格式:DOCX 页数:20 大小:103.14KB
下载 相关 举报
cpuxiong.docx_第1页
第1页 / 共20页
cpuxiong.docx_第2页
第2页 / 共20页
cpuxiong.docx_第3页
第3页 / 共20页
cpuxiong.docx_第4页
第4页 / 共20页
cpuxiong.docx_第5页
第5页 / 共20页
点击查看更多>>
下载资源
资源描述

cpuxiong.docx

《cpuxiong.docx》由会员分享,可在线阅读,更多相关《cpuxiong.docx(20页珍藏版)》请在冰豆网上搜索。

cpuxiong.docx

cpuxiong

CPU设计实验报告(受陈超同学指点)

1设计目的:

1)初步学习硬件逻辑电路建模,并用HDL语言描述硬件电路。

2)掌握应用quarter环境进行开发的流程,学会使用maxplus进行操作。

3)掌握基本verilog语言,可以编写基本的程序。

4)掌握cpu的组成原理,懂得运行过程,实现相应的编码。

2设计目标:

设计一简单的CPU模型,可以实现基本的运算,跳转,装入,读出等功能,通过微指令和机器指令的编写来实现相应的功能。

3模块设计规格及输入输出端变量说明:

1)简单cpu模型,通过微指令和机器指令的编写来实现传输、运算和读写

等基本功能。

2)模块原理框图

3)CPU指令格式:

1.单字节指令:

操作码OP4位

目的寄存器Rd2位

源寄存器Rs2位

操作码OP4位

相对转移偏移量,4位补码,含一位符号位

2.双字节指令

操作码OP4位

目的寄存器Rd2位

2位

立即数字段8位

 

举例:

LDI操作

3.CPU设计指令集

序号

指令助记符

实现的功能

操作码

指令举例

二进制机器码

1

LDIRd,data

立即数传输

Rd←data

0000

LDIR2,78H

00001000

01111000

2

LDRd,(Rs)

读内存

Rd←M(Rs)

0001

LDR2,(R1)

00011001

3

STR(Rd),Rs

写内存

M(Rd)←Rs

0010

STR(R2),R1

00101001

4

ADDRd,Rs

加运算

Rd←Rs+Rd

并设置Cy,Zero标志

0011

ADDR3,R0

00111100

5

ANDRd,Rs

与运算

Rd←Rs&Rd

并设置Zero标志

0100

ANDR1,R0

01000100

6

MOVRd,Rs

寄存器传输

Rd←Rs

0101

MOVR1,R2

01010110

7

JPtarget

相对转移

PC←PC+target

0110

JP-5

01101011

JP6

01100110

8

JCtarget

条件相对转移、有进位时相对转移

如果Cy==1’b1,

那么PC←PC+target,程序实现转移。

否则不修改PC,程序顺序执行。

0111

JC-5

01111011

-5的补码为1011

JC6

01110110

6的补码为0110

9

HLT

停机

1000

HLT

10000000

6)具体器件功能描述:

1.总线:

当XXX_B为1时,XXX部件输出到总线上,否则为高阻态。

LDYYY为1时,当T2上升沿到来时,将总线上的数据输入到YYY部件。

2.ALU运算器:

当ALU_B为1时,ALU输出,否则处于高阻态S2、S1、S0控制ALU进行何

种运算,本设计主要有加运算和与运算。

3.寄存器R3~R0:

以R0为例:

当R0_B为1时,R0输出,否则处于高阻态。

当LDR0为1时,

在时钟上升沿,接收数据。

由于主存中方的是RD和RS的值,所以通过程

序解码来选择相应的R寄存器。

4.寄存器PC:

当LDPC为1时,在时钟上升沿,接收数据。

当PCINC为1时,在时钟

上升沿,实现PC+1。

当PC_B为1时,输出数据。

否则高阻态。

5.寄存器IR:

当LDIR为1时,在时钟上升沿接收数据,送入微程序控制器,IR_B为1

时,送数据到数据总线。

6.AR地址寄存器、A、B暂存器:

当LDAR为1时,AR在时钟上升沿接收数据,送入主存;LDA为1时,A暂

存器从主线接收数据,B与A相同。

7.Cy进位标志寄存器:

当做加法指令时,进位保存在Cy中。

8.内存:

CE=1WE=0:

读内存

CE=0WE=1:

写内存。

7)输入输出变量详述:

1.T1,T2:

相反的节拍信号。

2.reset:

初始化信号,初始化主存和微存。

3.bus[7:

0]:

数据总线,用来输入和输出数据。

4.UA[4:

0]:

微指令的存放地址。

5.XXX_B[2:

0]:

三位信号,进行译码,选择具体器件,将值送总线。

6.LDYYY[2:

0]:

三位信号,进行译码后,选择具体器件,总线的值送器件。

7.PC_B,ALU_B,Rs_B,Rd_B,IR_B:

信号为1时相应器件的值送总线。

8.LDRs,LDRd,LDPC,LDA,LDB,LDIR,LDAR:

信号为1时总线的值送器件。

9.PCINC:

信号为1时实现PC+1送PC操作。

10.IR,AR,PC,R0,R1,R2,R3,bus,A,B,ALU[7:

0]:

器件定义,为8位。

11.MEM_00到MEM_0F:

主存地址定义。

12.CE,WE:

实现主存的读写操作。

13.s2,s1,s0:

控制运算器进行相关的运算。

8)微指令格式:

微指令设计:

读写内存

2位

运算器

3位

向总线输出

4位

从总线输入

3位

下地址

先暂定5位

/CE/WE

S2S1S0

XXX_B

LDYYY

/CE=1/WE=x,不操作。

/CE=0/WE=0写内存;/CE=0/WE=1读内存

 

运算器指令:

运算类型

S2S1S0

功能

逻辑运算

000

ALU=A

001

ALU=A&B

010

ALU=A|B

011

ALU=~A

移位运算

100

ALU=A逻辑左移一位

算术运算

101

ALU=A+B

110

ALU=A+1

111

ALU=A-1

总线输出:

LDYYY

选择

0

0

0

0

NOP

0

0

0

1

LDA

0

0

1

0

LDB

0

0

1

1

LDRs

0

1

0

0

LDRd

0

1

0

1

LDIR

0

1

1

0

LDAR

0

1

1

1

LDPC

1

0

0

0

LDMDR

总线输入:

XXX_B

选择

0

0

0

NOP

0

0

1

ALU_B

0

1

0

Rs_B

0

1

1

PC_B

1

0

0

IR_B

1

0

1

MDR_B

1

1

0

Rd_B

微指令表:

地址

读写/CE/WE

运算

S2-S0

总线输入

LDxxx

总线输入

xxx_B

PCINC

下一跳

功能

00000

10

000

0000

000

0

00001

NOP

00001

10

000

0110

011

1

00010

PC-AR,PC+1

LDI

00010

01

000

0101

000

0

11111

MEM-IR

00011

10

000

0110

011

1

00100

PC-ARPC+1

00100

01

000

0100

000

0

00001

MEM-Rd

LD

00101

10

000

0110

010

0

00100

Rs-AR

STR

00110

10

000

0110

110

0

00111

Rd-AR

00111

00

000

!

!

1000

010

0

00001

Rs-MEM

ADD

01000

10

000

0001

110

0

01001

Rd-A

01001

10

000

0010

010

0

01010

Rs-B

01010

10

101

0100

001

0

00001

A+B-Rd

AND

01011

10

000

0001

010

0

01100

Rd-A

01100

10

000

0010

010

0

01101

Rs-B

01101

10

001

0100

001

0

00001

A&B-Rd

MOV

01110

10

000

0011

110

0

00001

Rd-Rs

HLT

01111

10

000

0000

000

0

01111

HLT

JP

10000

10

000

0001

011

0

10001

PC-A

10001

10

000

0010

100

0

10010

Code[3:

0]-B

10010

10

101

0111

001

0

00001

ALU-PC

JC

4.程序代码(需要注解):

module

cpu(reset,T1,T2,XXX_B,bus,LDYYY,PC_B,ALU_B,Rs_B,Rd_B,IR_B,LDRs,LDRd,UA,LDPC,LDA,LDB,LDIR,LDAR,PCINC,CE,WE,s2,s1,s0);

inputreset,T1,T2;//input变量定义

output[7:

0]bus;//output变量定义

output[4:

0]UA;

output[2:

0]XXX_B,LDYYY;

outputPC_B,ALU_B,Rs_B,Rd_B,IR_B,LDRs,LDRd,LDPC,LDA,LDB,LDIR,LDAR,PCINC,CE,WE,s2,s1,s0;

reg[2:

0]XXX_B,LDYYY,s;//reg型变量定义

regPC_B,ALU_B,Rs_B,Rd_B,IR_B,CE,WE,s2,s1,s0;

regLDRs,LDRd,LDPC,LDA,LDB,LDIR,LDAR,PCINC;

reg[4:

0]UA;

reg[7:

0]IR,AR,PC,R0,R1,R2,R3,bus,A,B,ALU;

reg[7:

0]MEM_00,MEM_01,MEM_02,MEM_03,MEM_04,MEM_05,MEM_06,MEM_07,MEM_08,MEM_09,MEM_0A,MEM_0B,MEM_0C,MEM_0D,MEM_0E,MEM_0F;

regcy;

always@(posedgeT1)

begin

if(reset)//微指令赋初值

begin

{CE,WE}=2'b00;

UA=5'b00000;

XXX_B=3'b000;

LDYYY=3'b000;

{s2,s1,s0}=3'b000;

PCINC=1'b0;

end

case(UA)

5'b00000:

{CE,WE,s2,s1,s0,LDYYY,XXX_B,PCINC,UA}=17'b00000000000000001;

//开始,下条地址00001

5'b00001:

{CE,WE,s2,s1,s0,LDYYY,XXX_B,PCINC,UA}=17'b00000111010100100;

//PC_B,PCINC,LDAR信号为1,实现PC送AR,PC+1送PC,下条地址00100

5'b00010:

{CE,WE,s2,s1,s0,LDYYY,XXX_B,PCINC,UA}=17'b00000111010100101;

//PC_B,PCINC,LDAR信号为1,实现PC送AR,PC+1送PC,下条地址00101

5'b00011:

{CE,WE,s2,s1,s0,LDYYY,XXX_B,PCINC,UA}=17'b00000111011001000;

//Rs_B,LDAR信号为一,实现Rs送AR操作

5'b00100:

{CE,WE,s2,s1,s0,LDYYY,XXX_B,PCINC,UA}=17'b10000110000010011;

//CE,LDIR信号为,读内存送总线,写入IR,下条地址10011

5'b00101:

{CE,WE,s2,s1,s0,LDYYY,XXX_B,PCINC,UA}=17'b10000010000000001;

//CE,LDRD信号为1,读出内存写入Rd,完成LDI,返回00001

5'b00110:

{CE,WE,s2,s1,s0,LDYYY,XXX_B,PCINC,UA}=17'b00000111100001001;

//STR操作,完成RD送AR

5'b00111:

{CE,WE,s2,s1,s0,LDYYY,XXX_B,PCINC,UA}=17'b00000100100001100;

//RD_B,LDA信号为1,实现RD送A,下条地址01100

5'b01000:

{CE,WE,s2,s1,s0,LDYYY,XXX_B,PCINC,UA}=17'b10000010000000001;

//CE,LDRD信号为1,实现主存送bus写入微存的操作,完成LD,返回00001

5'b01001:

{CE,WE,s2,s1,s0,LDYYY,XXX_B,PCINC,UA}=17'b01000000011000001;

//RS送MEM,返回00001

5'b01010:

{CE,WE,s2,s1,s0,LDYYY,XXX_B,PCINC,UA}=17'b00000100100010000;

//与运算,与加运算相同

5'b01011:

{CE,WE,s2,s1,s0,LDYYY,XXX_B,PCINC,UA}=17'b00000010011000001;

5'b01100:

{CE,WE,s2,s1,s0,LDYYY,XXX_B,PCINC,UA}=17'b00000101011001101;

//实现RS送B,下条地址01101

5'b01101:

{CE,WE,s2,s1,s0,LDYYY,XXX_B,PCINC,UA}=17'b00001010001000001;

//s2,s1,s0为001,进行加运算,ALU_B,LDPC为1,实现A+B送回RD,返回00001

5'b01110:

{CE,WE,s2,s1,s0,LDYYY,XXX_B,PCINC,UA}=17'b00000100010010100;

//JP运算入口,实现PC送A,跳到10100

5'b01111:

begin

{CE,WE,s2,s1,s0,LDYYY,XXX_B,PCINC}=12'b000000000000;

if(cy==1'b1)//有进位,进行JP操作

UA=5'b01110;

else//没有进位,返回00001

UA=5'b00001;

end

5'b10000:

{CE,WE,s2,s1,s0,LDYYY,XXX_B,PCINC,UA}=17'b00000101011010001;

5'b10001:

{CE,WE,s2,s1,s0,LDYYY,XXX_B,PCINC,UA}=17'b00010010001000001;

5'b10010:

{CE,WE,s2,s1,s0,LDYYY,XXX_B,PCINC,UA}=17'b00000000000010010;

//停机操作

5'b10011:

{CE,WE,s2,s1,s0,LDYYY,XXX_B,PCINC,UA}={12'b000000000000,IR[7],IR[6],IR[5],1'b1,IR[4]};

//P<1>改地址,修改下条地址为IR高四位,中间插入1

5'b10100:

{CE,WE,s2,s1,s0,LDYYY,XXX_B,PCINC,UA}=17'b00000101101010101;

//IR送B,跳到10101

5'b10101:

{CE,WE,s2,s1,s0,LDYYY,XXX_B,PCINC,UA}=17'b00001011001000001;

//相加送给PC,返回00001

endcase

end

always@(XXX_B)//XXX_B信号变化执行此模块

begin

case(XXX_B)//给相应的读取信号赋值

3'b000:

{ALU_B,PC_B,Rs_B,Rd_B,IR_B}=5'b00000;

3'b001:

{ALU_B,PC_B,Rs_B,Rd_B,IR_B}=5'b10000;

3'b010:

{ALU_B,PC_B,Rs_B,Rd_B,IR_B}=5'b01000;

3'b011:

{ALU_B,PC_B,Rs_B,Rd_B,IR_B}=5'b00100;

3'b100:

{ALU_B,PC_B,Rs_B,Rd_B,IR_B}=5'b00010;

3'b101:

{ALU_B,PC_B,Rs_B,Rd_B,IR_B}=5'b00001;

endcase

end

always@(LDYYY)//LDYYY信号变化执行此模块

begin

case(LDYYY)//给相应的装入信号赋值

3'b000:

{LDRs,LDRd,LDPC,LDA,LDB,LDIR,LDAR}=7'b0000000;

3'b001:

{LDRs,LDRd,LDPC,LDA,LDB,LDIR,LDAR}=7'b1000000;

3'b010:

{LDRs,LDRd,LDPC,LDA,LDB,LDIR,LDAR}=7'b0100000;

3'b011:

{LDRs,LDRd,LDPC,LDA,LDB,LDIR,LDAR}=7'b0010000;

3'b100:

{LDRs,LDRd,LDPC,LDA,LDB,LDIR,LDAR}=7'b0001000;

3'b101:

{LDRs,LDRd,LDPC,LDA,LDB,LDIR,LDAR}=7'b0000100;

3'b110:

{LDRs,LDRd,LDPC,LDA,LDB,LDIR,LDAR}=7'b0000010;

3'b111:

{LDRs,LDRd,LDPC,LDA,LDB,LDIR,LDAR}=7'b0000001;

endcase

end

always@(posedgeT2)

begin

if(reset)//主存指令初始化

begin

MEM_00=8'b00000000;//LDIR0

MEM_01=8'b00000010;

MEM_02=8'b00000100;//LDIR1

MEM_03=8'b11000011;

MEM_04=8'b00011001;//LDR2<-M(R1)

MEM_05=8'b00101001;//STRM(R2)R1

MEM_06=8'b00110100;//ADDR0+R1->R1

MEM_07=8'b01000100;//ANDR0&R1->R1

MEM_08=8'b01010100;//MOVR0->R1

MEM_0A=8'b00001010;

MEM_0B=8'b01100001;//JP

MEM_0C=8'b01110001;//JCcy=1时,PC+target

MEM_0D=8'b10000000;//HLT

end

end

always@(posedgeT2)//实现总线送入相应的寄存器

begin

case({LDPC,PCINC})//都是装入PC,防止冲突,进行判断

2'b01:

PC=PC+1;

2'b10:

PC=bus;

endcase

case({LDRd,LDRs,LDIR,LDAR,LDA,LDB})//判断送入哪个寄存模块

6'b100000:

begin

case(IR[3:

2])//通过IR的三四位选择目的寄存器

2'b00:

R0=bus;

2'b01:

R1=bus;

2'b10:

R2=bus;

2'b11:

R3=bus;

endcase

end

6'b010000:

begin

case(IR[1:

0])//通过IR的低两位位选择源寄存器

2'b00:

R0=bus;

2'b01:

R1=bus;

2'b10:

R2=bus;

2'b11:

R3=bus;

endcase

end

6'b001000:

IR=bus;

6'b000100:

AR=bus;

6'b000010:

A=bus;

6'b000001:

B=bus;

endcase

end

always@(Rs_BorRd_BorIR_BorPC_BorALU_BorCEorWEorAR)

begin//实现相应的寄存器参数送总线

case({Rs_B,Rd_B,IR_B,PC_B,ALU_B})//判断哪个寄存模块输入总线

5'b10000:

begin

case(IR[1:

0])//通过IR的三四位选择目的寄存器

2'b00:

bus=R0;

2'b01:

bus=R1;

2'b10:

bus=R2;

2'b11:

bus=R3;

endcase

end

5'b01000:

begin//通过IR的低两位位选择源寄存器

case(IR[3:

2])

2'b00:

bus=R0;

2'b01:

bus=R1;

2'b10:

bus=R2;

2'b11:

bus=R3;

endcase

end

5'b00100:

bus={IR[3],IR[3],IR[3],IR[3],IR[3],IR[2],IR[1],IR[0]};

5'b00010:

bus=PC;

5'b00001:

bus=ALU;

endcase

if({CE,WE}==2'b10)////读内存,内存送总线

begin

case(AR[7:

0])

8'b00000000:

bus=MEM_00;

8'b00000001:

bus=MEM_01;

8'b00000010:

bus=MEM_02;

8'b00000011:

bus=MEM_03;

8'b00000100:

bus=MEM_04;

8'b00000101:

bus=MEM_05;

8'b00000110:

bus=MEM_06;

8'b00000111:

bus=MEM_07;

8'b00001000:

bus=MEM_08;

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 小学教育 > 小学作文

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1