从最简的条指令CPU实现了解CPU设计_第1页
从最简的条指令CPU实现了解CPU设计_第2页
从最简的条指令CPU实现了解CPU设计_第3页
从最简的条指令CPU实现了解CPU设计_第4页
从最简的条指令CPU实现了解CPU设计_第5页
已阅读5页,还剩76页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第二章CPU设计概论2.0.0从最简的4条指令CPU,看CPU的设计与测试验证▲步骤:==>指令集

==>CPU架构(冯/哈/流水)

==>周期微操作流程表

==>选定EDA设计系统和HDL语言(如QuartusII…,.v)

==>CPU核设计描述(HDL/图形)

==>测试程序设计

==>逻辑模拟仿真(顶层图形/描述文件:CPU核+装入测试程序[.mif] 的内部RAM)

==>FPGA平台下载测试(平台顶层文件调用CPU核+装载测试程序 [.bin]的外部主存或调用仿真顶层文件)

--实验设计到此

==>版图设计

==>CPU的ASIC芯片生产与测试

==>CPU主板的全面测试验证包括BOOTOS。--科研设计必须的后续

还有CPU预研时的模拟仿真机(虚拟机,C语言)设计四条指令CPU指令集

ADD

整数加法STA

存数LDA

取数JNC

非进位转移时序固定2周期架构冯诺曼型、数据地址不复用

特点8bit数据地址复位启动最简的4条指令CPU设计2.0.14条指令CPU的指令格式与功能:自定义

controlmodecombinationlogicir[7:0]InstructionRegister单字节指令

ir[7],ir[6]2bitoperationcode(I7,I6)ir[5:0]6bitaddress直接寻址

Acc[7:0]accumulatorregister

ir[7]ir[6]instructionoperation00ADDAcc,addrAcc<=(Acc)+(addr)要先取数到Acc

01LDAAcc,addrAcc<=(addr)10STAaddr,Accaddr<=Acc11JNCaddrpc<=addr,whenCy=0CyCarryofAdderPC[7:0]programcountert[1:0]2cycleck分频之后的clock信号2.0.24条指令CPU的外特性

CPU4条:

resetclk

o_a[7:0]

外部地址总线

(也有读写地址分开的)

o_d[7:0]

外部数据总线(双向,也有读写数据分开的)wc

写存贮器信号(高有效,也有非写即读的)rc

读存贮器信号(高有效)

到存贮器写命令wr=!(wc&ck),读允许!rc

到同步存贮器还需要时钟,DRAM还有刷新控制2.0.34条指令CPU的周期时序:

固定

2周期时序波形图clk3Tt1t0ckTT=1/fTfMHzf

/3f

/6f

/6取决指令中操作所需的最多周期的指令本时序用二次移位式3,2分频实现,保证CPU的工作脉冲CK在周期中部,可使用CK的↑/↓。属于早期的保守型取指2.0.4

4条指令CPU的描述框图(行为对象)sel_pc_in复位启动首地址o_a[7:0]reset!ckpc_ldpc[7:0]pc_add_1sel_to_oasel_acc_inir_enir[7:0]!ckacc[7:0]acc_en!ckALU[7:0]ADDABFcn8o_d[7:0]wc3态门resetckclkt[1:0]Timer!ckDQcyADD指令部件2’b00,ir[5:0]!ckrcwrController

Combinationlogicir[7:6]cyir_enpc_ldsel_pc_inADDpc_add_1sel_to_oasel_acc_inacc_enwc5’bxx01x

!(wc&ck)

5’bxx01x

5’b0x10x

5’b11100

5’b0x10x

5’b0110x

5’b0010x

5’b1001x

的非

casex={ir[7:6],t,cy}

运算器外部数据总线转移取数外部地址总线存贮器低有效wr

rc2.0.5

4条指令CPU的指令微操作流程图取指令指令汇编符指令码地址(6位)指令功能指令执行周期微操作及其控制信号与CLKt[0]操作76543210t[1]说明CASEX=5’bxx01xsel_pc_insel_to_oapc→o_a

发rcM→o_d

ir_en,!cko_d→irpc_add_1,!ckpc+1→pc加法ADDaddr00xxxxxx(acc)+(addr)=>acc

注:作加法要先将第一操作数取到累加器CASEX=5’b0010x!sel_to_oa

发rc{2’b00,ir[5:0]}→o_a,M→o_dADD,!sel_acc_in,en_acc,!ck{1’b0,acc}+{1’b0,o_d}→{cy,acc}

取数LDAaddr01xxxxxx(addr)=>accCASEX=5’b0110x

sel_to_oa

{2’b00,ir[5:0]}→o_a,发rc,sel_acc_in,en_acc,!ckM

→o_d

→acc送存STAaddr10xxxxxx(acc)=>addrCASEX=5’b1010x!sel_to_oa

{2’b00,ir[5:0]}→o_a

发wr,wc打开3态,写存贮器acc→o_d→M(wr=wc&ck)非进位转移JNCaddr11xxxxxxcy=0addr=>pcCASEX=5’b11100sel_pc_in,pc_ld,cy=0,!ck{2’b00,ir[5:0]}→

pc设:CASEX={ir[7:6],t[1:0],Cy}

复位启动:ifreset=1,8’h3f→pc2.0.5-1

4条指令CPU的指令操作:Timer描述(定义声明省略)3分频:always@(posedge

clk)

begin

if((q==3'b111)|(q==3'b011)|(q==3'b110)|(q==3'b101)|(q==3‘b000))//非法态恢复

q<=3'b001;

else

begin

//保证CK居中,可使用↑↓

q[0]<=q[2];q[1]<=q[0];q[2]<=q[1];

endendassignck=q[1];//CPU工作脉冲固定2周期:(设计简单)always@(posedgeq[0]or

posedge

reset)

beginif(reset)cyc<=2'b00;

else

if

((cyc==2'b11)|(cyc==2'b00))

cyc<=2'b01;else

begincyc[0]<=cyc[1];cyc[1]<=cyc[0];

endendassignt=cyc;均用移位实现注:周期数与指令长度功能、寄存器传送级数、脉冲↑↓、结构流水相关2.0.5-2

4条指令CPU的指令操作:复位设置启动首地址sel_pc_in复位启动首地址reset!ckpc_ldpc[7:0]pc_add_12’b00,ir[5:0]2’h3f条件:reset=1’b1,(t[1:0]==2’b00).描述:always

@(negedge

ckorposedge

reset)

begin

if(reset)//复位包括:上电开关、复位开关、Ctrl+Alt+Del

pc<=8‘h3f;//firstadderofprogram,or0eh,

else//(3f):放转移指令转到0eh……//PC机复位CS=ffffh,IP=0000h即ffff0h,放必转指令指向程序首地址方法复位:1)

直接设置

如0eh2)

固定设置如

3fh+转移指令到

0eh2)

系虚设置灵活可程序修改真实的启动首地址

OS:根据可执行文件的文件头中的程序首地址,用陷阱指令设置,转移设置Debug:根据可执行文件的文件头中序首地址,

用逻辑设置

设程序的真实启动首地址为

0eh转移2’h0e2.0.5-3

4条指令CPU的指令操作:取指令流程sel_pc_in复位启动首地址reset!ckpc_ldpc[7:0]pc_add_1sel_to_oair_enir[7:0]!cko_d[7:0]指令部件2’b00,ir[5:0]o_a[7:0]casex{ir[7:6],t,cy}

=

5’bxx01x

!ck!rcController

ir[7:6]cyir_enpc_add_1sel_to_oackt[1:0]

sel_to_oa1)pc→o_a发rc

ir_en,!ck2)M→o_d→irpc_add_1,!ck3)pc+1→pc

always

@(ir[7:0]ortorcyorpcoracc)

begin

casex

({ir[7:6],t,cy})

5'bxx01x://t[0]:fetchinstruction

begin

o_a=pc;

rc=1‘b1;

wc=1’b0;//发出读!rc

end

……………..//其它

default:begin

o_a=pc;wc=1'b0;rc=1'b0;

end

endcase

end2.0.5-3

4条指令CPU的指令操作:取指令描述1

向存贮器发取指令的地址与读令组合逻辑2.0.5-3

4条指令CPU的指令操作:取指令描述2

复位首址、取指令到ir、pc+1的微操作时序逻辑always@(negedgeckor

posedge

reset)

begin

if

(reset)

pc<=8'h3f;//firstadderofprogram

else

casex

({ir[7:6],t,cy})

5'bxx01x://t[0]:fetchinstruction

begin

ir<=o_d;

pc<=pc+1;

end

…………….//其它

endcase

end2.0.5-4

4条指令CPU的指令操作:LDA取数流程sel_acc_inacc[7:0]acc_en!ck运算器o_d[7:0]ALU_Acasex{ir[7:6],t,cy}

=

5’b0110x

!ck!rcController

ir[7:6]cysel_to_oackt[1:0]sel_acc_inacc_en

sel_to_oa

1)

{2’b00,ir[5:0]}→o_a,发!rc,sel_acc_in,en_acc,!ck2)M

→o_d

→accir_enir[7:0]!cksel_to_oa指令部件o_a[7:0]2’b00,ir[5:0]非2.0.5-44条指令CPU的指令操作:LDA取数描述组合逻辑:向存贮器发取数的地址与读令5'b0110x://t[1]:LADfetchdata

begin

o_a={2'b00,ir[5:0]};

rc=1‘b1;

//发出读!rc

wc=1'b0;

end注:头、尾省略时序逻辑:取数到acc5'b0110x://t[1]:LDAfetchdata

begin

acc<=o_d;

end注:头、尾省略casex{ir[7:6],t,cy}

=

5’b0010x

2.0.5-5

4条指令CPU的指令操作:ADD加法流程!ck!rcController

ir[7:6]cysel_to_oackt[1:0]sel_acc_inacc_enADDcysel_acc_inacc[7:0]acc_en!ckALU[7:0]ADDABFcn8!ckDQADD运算器

sel_to_oa

1)

{2’b00,ir[5:0]}→o_a

发!rc,2)M

→o_d

→ALU_BADD,!sel_acc_in,en_acc,!ck3){1’b0,acc}+{1’b0,o_d}→{cy,acc}非非ir_enir[7:0]!cko_d[7:0]指令部件2’b00,ir[5:0]sel_to_oao_a[7:0]pco_d2.0.5-54条指令CPU的指令操作:ADD加法描述组合逻辑:向存贮器发取第二操作数的地址与读令5'b0010x://t[1]:ADDfetchdata

begin

o_a={2'b00,ir[5:0]};

rc=1‘b1;

//发出读

!rc

wc=1'b0;

end注:头、尾省略时序逻辑:作加法,结果→acc5'b0010x://t[1]:add

begin

{cy,acc}<={1'b0,acc}+{1'b0,o_d};

end注:头、尾省略,cy--进位2.0.5-54条指令CPU的关键时间:Tmin最小周期确定

本固定周期数的Tmin取决于ADD加法总操作时间Tmin理论波形

!clk的逻辑延迟q[0]!ckclkckq[1]q[2]t[0]t[1]实际波形(延迟+倾斜跳动)Tmin﹥读存贮器时间

+加运算最大时间读存时间=CPU地址、读令到芯片延迟

+存贮芯片标称读写时间

+芯片数据读出到CPU延迟加运算最大时间=最长进位链时间clk!ckt[0]t[1]Tmin时序的另一种设计:只用clk后跳沿单倍时钟移位3分频移位2分频缺点:从前面Tmin最小周期确定,可以看出,因加法指令(取第二操作数+加运算)把CPU的每条指令的周期时间都加大许多,速度也就很大降低,这是固定两周期的缺点。改进:设计变周期时序,加法指令增加一个周期t[2]t[1]:类同LDA取数指令操作,但取到的数送暂存器tmp

tmp<=o_d;

t[2]:作加法运算操作

{cy,acc}<={1'b0,acc}+{1'b0,tmp};Tmin:此时Tmin最小周期确定,在读存贮器时间或加法运算最长进位链时间上

取最大值,估计速度可提高一倍。2.0.5-54条指令CPU的指令操作:ADD的设计缺点与改进时序模块:wire

cyc3=(ir[6:7]==2’b00);always@(posedge

clkor

posedgereset)begin

if(reset==1)t<=3'b000;

else

if(t==3'b000)t<=3'b001;

else

begint[0]<=t[1]&!cyc3|t[2]&cyc3;t[1]<=t[0];t[2]<=t[1]&cyc3;

end

end右边的迁移方式类似状态机时序见后2.0.5-54条指令CPU的指令操作:单倍频

变周期实现迁移方式:可将周期迁移单设模块always@(posedge

clkorposedgereset)begin

if(reset==1)t<=3'b001;

else

case

({ir[7:6],t})

5‘bxx001:

pc<=pc+1;ir<=o_d;

t<=3’b010;5‘b00010:tmp<=o_d;

t<=3’b100;

5‘b00100:{cy,acc}<=acc+tmp

t<=3’b001;

5‘b01010:acc<=o_d;

t<=3’b001;

5‘b10010:t<=3’b001;5‘b11010:if(!cy)pc<={2’b00,ir[5:0]}

t<=3’b001;end2.0.5-64条指令CPU的指令操作:STA存数流程ir_enir[7:0]!cko_d[7:0]指令部件2’b00,ir[5:0]sel_to_oao_a[7:0]acc[7:0]acc_en!ckwc3态门运算器LAU_A!ckwr=!(wc&ck)Controller

ir[7:6]cysel_to_oackt[1:0]

wccasex{ir[7:6],t,cy}

=

5’b1010x

sel_to_oa

1)

{2’b00,ir[5:0]}→o_a

wr,wc打开3态,写存贮器2)acc→o_d

→M非2.0.5-64条指令CPU的指令操作:STA存数描述组合逻辑:向存贮器发送存的地址,写令打开到o_d

的3态缓冲与写令脉冲wr

5'b1010x://t[1]:STASTOREdata

begin

o_a={2'b00,ir[5:0]};

rc=1'b0;

wc=1'b1;

endassign

wr=!(wc&ck);//异步存贮器须写脉冲

assign

o_d=wc?acc:8’hzz;//数据双向3态注:头、尾省略2.0.5-74条指令CPU的指令操作:JNC非进位转移流程sel_pc_in复位启动首地址reset!ckpc_ldpc[7:0]pc_add_1ir_enir[7:0]!cko_d[7:0]指令部件2’b00,ir[5:0]ir_enir[7:0]!ck!ckController

ir[7:6]Cy=0ckt[1:0]sel_pc_in

pc_ld选ircasex{ir[7:6],t,cy}

=

5’b11100

sel_pc_in,pc_ld,cy=0,!ck

1)

{2’b00,ir[5:0]}→pc

2.0.5-74条指令CPU的指令操作:JNC非进位转移描述时序逻辑:转移地址打入程序计数器pc5'b11100://t[1]:JNC

begin

pc<={2'b00,ir[5:0]};

end注:头、尾省略描述形式:分部件或功能模块,然后分组合与时序分组合逻辑[含always@()型、assign、门原语句]

与时序逻辑[always@(clk跳沿)]描述方法:

行为对象不考虑具体结构,仅从功能描述,如F=A+B

结构细化用“标准单元”结构实现目标描述,用全加器赋值方式:

1)always@()组合、锁存、时序块的if..else、case类等

2)assign、门原语句

3)调库函数、实例(包括TTL电路)4)3态,双向实现2.0.64条指令CPU的逻辑描述-0(VerilogHDL)

描述形式、方法,赋值方式2.0.64条指令CPU的逻辑描述-1(VerilogHDL)module

cpu4_2t(reset,clk,we,rc,o_d,o_a,_acc,_pc,_ir,_t,_cy,_ck);//declare****************要看的内部信号

input

clk,reset;

output

we;//CPUwritepulse

output

rc;//CPUreadorder

inout

[7:0]

o_d;//outsidedatabus

output[7:0]

o_a;//outsideaddressbus

output_ck;//clockofCPUrunandSYNCofRAM_dq

reg

[7:0]i_a;//insideaddressbus

reg

[7:0]i_d;//insidedatabus

reg

[7:0]acc;//Acc_Reg

reg

[7:0]ir;//instruction_Reg

reg

[7:0]pc;//CPUprogramcounterwichload

reg

wc;//CPUwriteorder

reg

rc;//readenable2.0.64条指令CPU的逻辑描述-2

(VerilogHDL)

reg

cy;//carryofADD

wireck;

wire

[1:0]t;//whensimulation,lookatinternalsignalforimmobile

output

_cy;

//lookatckandcy

output

[7:0]_acc;

//lookatacc

output

[7:0]_ir;

//lookatir

output[7:0]_pc;

//lookatpc

output[1:0]_t;

//lookatt

assign

_acc=acc;

assign

_ir=ir;

assign

_pc=pc;

assign

_t=t;

assign

_ck=ck;

assign

_cy=cy;2.0.64条指令CPU的逻辑描述-3

(VerilogHDL)//Timer

****************reg

[2:0]q;reg

[1:0]cyc;always

@(posedge

clk)

begin

if((q==3'b111)|(q==3'b011)|(q==3'b110)|(q==3'b101)|(q==3‘b000))//非法态恢复

q<=3'b001;

elsebeginq[0]<=q[2];q[1]<=q[0];q[2]<=q[1];

end//此设计保证CK居中,

end//可使用↑↓assign

ck=q[1];//assignwe=wc&q[1];//对异步存贮器assignwe=wc;

//对输入同步存贮器wire

ck0=q[0];always@(posedge

ck0

or

posedge

reset)

beginif(reset)

cyc<=2'b00;

else

if

((cyc==2'b11)|(cyc==2'b00))

cyc<=2'b01;elsebegin

cyc[0]<=cyc[1];//|(cyc==2’b00)cyc[1]<=cyc[0];

endendassign

t=cyc;

注:可变周期与指令操作码相关2.0.64条指令CPU的逻辑描述-4

(VerilogHDL)//combinationlogicpart*****************发地址、读或写选通(允许)

always

@(ir[7:0]ortorcyorpc)//所有条件、表达式右边信号

begin

casex

({ir[7:6],t,cy})

5'bxx01x://t[0]:fetchinstruction

begin

i_a=pc;

rc=1‘b1;//“1”有效,

wc=1‘b0;//无效的也必须“0”

end

5'b0010x://t[1]:ADDfetchdata

begin

i_a={2'b00,ir[5:0]};

rc=1'b1;

wc=1'b0;

end2.0.64条指令CPU的逻辑描述-5

(VerilogHDL)5‘b0110x://t[1]:LDAfetchdata接前combinationlogicpart

begin

i_a={2'b00,ir[5:0]};

rc=1'b1;wc=1'b0;

end5'b1010x://t[1]:STAwritedata

begin

i_a={2'b00,ir[5:0]};

wc=1'b1;rc=1'b0;

end

default://缺省项(不用情况)必须要

begin

i_a=pc;wc=1'b0;rc=1'b0;

end

endcase

end2.0.64条指令CPU的逻辑描述-6(VerilogHDL)//timinglogicpart*****************************always@(negedge

ckorposedge

reset)

//用后沿时序充足,异步复位

begin//用<=赋值符合通常概念,不会出问题

if

(reset)

pc<=8‘h3f;//resetseuupfirstadderofprogramrun

else

casex

({ir[7:6],t,cy})

5'bxx01x://t[0]:fetchinstruction

begin

ir<=o_d;pc<=pc+1;

end

5'b0010x://t[1]:add

begin

{cy,acc}<={1'b0,acc}+{1'b0,o_d};

end2.0.64条指令CPU的逻辑描述-7(VerilogHDL)

5‘b0110x://t[1]:LDAfetchdata接前timinglogicpart

begin

acc<=o_d;

end

5'b11100://t[1]:JNC

begin

pc<={2'b00,ir[5:0]};

end//时序逻辑不要default(缺省项)

endcase

end

assign

o_d=wc?acc:8'hzz;//STAwrite_dataoutput//或调用3态门、函数库MaxII最好用74465

endmodule状态机控制是包括CPU在内的所有控制的控制原理,特别是在“CPU”出现之前,如电梯、机床等各种自动控制技术,就上述最简的4条指令CPU设计,有5个状态迁移:5个状态用3位表示S[2:0]1.复位进入取指令状态S=3’b100,

取指令,CLK1下打入ir[7:0],同时按o_d[7:6]迁移到相应的指令状态2.相应指令的功能操作,CLK2下打入acc或PC[7:0](JNC,cy=0),同时迁移到状态S=3’b100取指可见:无明显周期,实际状态中隐含时序。而确定状态数即有多少不可同时进行的微操作是关键RESETSadd000Sfi100Slda001Sjnc011Ssta010cy=0?取指10取指时o_d[7:6]1101002.0.1A4条指令CPU的状态机控制状态时序2.0.1A4条指令CPU的状态机控制状态时序的集中描述always

@(negedge

clk

orposedge

reset)

beginif

(reset)s<=3'b100;

elseif

((s==3'b100))

begin

ir<=o_d;s<={1'b0,o_d[7:6]};//statetoperinstruction

end

elseif((s[2]==0))

s<=3'b100;//returnstateoffetchinstruction

endalways

@(posedge

clk

orposedge

reset)

beginif

(reset)

begin

pc_o<=8'h0e;s<=4'b100;

endelsecasex

(s)

3'b100://fetchinstruction

begin

irh<=o_d[7:0];

pc_o<=pc_o+1;

s<={1'b0,o_d[7:5]};

end3'b000://add+

begin

{cy,acc}<={1'b0,acc}+{1'b0,o_d[7:0]};s<=3'b100;

end

3'b001://LDAfetchdata

begin

acc<=o_d;s<=3'b100;

end

3'b010://STAwritedata

begin

s<=3'b100;

end

3'b011://JNC

begin

if

(!cy)

pc_o<={2'b00,ir[5:0]};s<=3'b100;

endend

endcase

2.0.1A4条指令CPU的状态机控制状态时序的分散迁移描述2.0.1A4条指令CPU的状态机控制基本规则取指令:首取主操作码(区分不同功能指令的部分)在复位主状态Si,n次指令要据主操作码下的相应n-1辅助状态。每取一次指令,状态迁移到下一次继续取指令状态。取完后据主操作码转移到相应的首次微操作操作状态Sm(前面描述状态后两位使用操作码)。不同时的微操作(见流程表)如读存、送存、地址运算、数据运算、转移、栈操作、读/写寄存器、I/O操作等等确定操作的状态编码。操作:

case({S,OP辅}),分组合、时序逻辑,而状态迁移仅发生在时序逻辑,见下:在某状态下如Sm

,begin同时的多个微操作语句后,状态迁移到下步必须的、且不同时的微操作状态end。每条指令最后的微操作结束,状态迁移到取指令主操作码状态Si,又开始取指令,…(循环)状态时序在并行流水站上不适用,而用于冲突仲裁控制上。参考代码与作业Maxii下面的参考代码:E:\instance\veriloghdl\maxii\cpu4\cpu4_new\cpu4s参考文档:E:\实验教材\6_相关软件使用与手册\QuartusII\自编\1_MiitoQii移植须知.doc作业一:移植代码到quartus

下面,进行仿真(把异步的MEM访问,改成同步时序,注意存储器使用mif文件进行初始化的问题)。作业二:使用状态机设计分散迁移模式编写一个CPU4,仿真结果应与作业一相同。作业三参考E:\Platform_SW\cpu_usb_old\cpu_example\new_design\cpu_chip\cpu8tv.v完成一个8条指令的基于状态机的实现的CPU。基于E:\实验教材\2_计算机原理\实验内容与参考\cpu检测程序或目标码\cputest_8.asm和cputest_8.bin创建一个mif文件。使用该mif文件初始化存储器。参考cpu4s的实现,需要创建一个bdf文件,包含CPU、存储器。运行仿真之后,要求结果与cputest_8.asm中要求的一致(检查仿真的memory)。2.0.7-0仿真与下载的前提有关程序启动首地址问题11.操作系统下的计算机的启动与程序运行在开机时,由上电复位初始化设置程序计数器(PC或CS+IP)为指向BIOS(ROM)内程序启动首地址,随后开始运行BIOS程序,直到引导操作系统(加载OS原理类同下)。在操作系统下,是由操作系统判别要加载的目标程序如.exe文件的文件头和重定位程序映象信息(包括编译产生的加载首地址、启动首地址、长度及其浮动控制等等)进行以下处理:

1)根据当前存贮空间使用情况,分配当前程序所允许加载的内存空间的首地址,并计算编译产生的加载首地址与实际加载的内存空间的首地址的差。

2)调当前程序目标码到OS系统的缓冲区,以进行予处理。

3)计算并修改目标码中依赖“绝对”地址的指令与数据的地址值(通常加或减这个差,或访存前用地址查表法获得需要的地址)。将经过处理的程序目标码加载到允许加载的内存空间。

4)OS通过具有中断和陷进指令(call等)的程序将目标程序的启动首地址设置到程序计数器(PC或CS、IP)

,接着运行目标程序。(程序内转移和返回是通过堆栈弹、压实现)2.0.7-0

仿真与下载的前提有关程序启动首地址问题2

#重新定位信息记录或标记了可执行的目标程序代码在加载内存时依赖“绝对”地址的指令与数据,该“绝对”地址与程序启动首地址相关,而程序启动首地址又与操作系统判别将程序可放在内存的何位置即浮动相关)

#中断和陷进指令可设置程序计数器值的指令,CPU必须有相应的逻辑控制支持。2.CPU设计中的验证的下载测试(仿真类同)CPU设计中的验证下载测试,此时尚没有BIOS和OS,为了运行测试程序,同样必须在启动测试程序前,设置程序计数器PC(或IP)为测试程序的启动首地址。目前使用与上述类似的2种方法:推荐使用下述①,因简单。①复位(在Debug下实际是软复位)初始化设置程序计数器(因仪器电源已打开,不可用上电复位逻辑了),但必须知道CPU测试程序的启动首地址,并注意平台地址是双向的处理。同②1)

例如本例程序可直接是0eH,也可3fH+转移指令到0eH

则将CPU程序计数器的复位初始化语句改为:

pc_o<=8‘h0e;

//

或3fH+转移指令到0eH

推荐使用2.0.7-0

仿真与下载的前提有关程序启动首地址问题32.CPU设计中的验证的下载测试(仿真类同)续1②由实验平台Debug自动判别测试程序文件头信息、设置程序的启动首地址,但需要CPU必须有相应的逻辑控制支持。即:

注意:现此法因复杂已基本不用

1)cpu模块的出入信号表内增加(……run,cp,oa)若在cpu模块的地址o_a属性仅是输出时,必须要oa输入,因顶层模板地址A_[]是双向,所以必须顶层模板必须增加语句:

assignA_[7:0]=run?o_a[7:0]:8’hzz;

调用端口增加:.oa(A_[7:0);

如cpu模块的地址o_a属性是双向,则不用增加oa。

2)属性声明增加input:CPU运行run,脉冲cp,输入地址oa;

run=0允许Debug(PC机)访问主存和设置CPU启动首地址

禁止CPU时钟CLK,禁止CPU访问主存。

run=1打开CPU时钟CLK,允许CPU工作和访问主存,

禁止Debug访问主存。当run=0、cp↑/↓时:pc<=oa;

设置的启动首地址2.0.7-0仿真与下载的前提有关程序启动首地址问题42.CPU设计中的验证的下载测试(仿真类同)续2②由实验平台Debug自动判别测试程序文件头信息、设置程序的启动首地址,但需要CPU必须有相应的逻辑控制支持。续

3)有关程序计数器的初始化部分修改

wire

cpu_ck=ck|cp;

//cp是下降的后沿有效,所以下面是negedge_ck

always@(negedge

cpu_ck

orposedge

reset)//原为ck

beginif

(reset)

pc_o<=8‘h000;//或3f或0e,可删除,时间上先

elseif(run==0)//新增:Debug自动设置启动首地址

pc_o<=oa;//注意等宽时间上后

else

casex

({ir,t,….})……

此法非特殊情况下不使用若程序计数器是74161函数实现,则打入脉冲和装入条件均要合成,2.0.7-14条指令CPU的验证1--逻辑模拟仿真基础

对CPU最适宜的仿真是运行全面检测程序的仿真其条件是:(QuartusII为例)

1)必须设计存贮器调SRAM库、ROM(FPGA)

也可设计寄存器堆、固接高/低多选择电路(CPLD,相当ROM)2)必须设计全面检测程序,须编译为目标码

3)必须设计存放程序目标码的*.mif文件

4)必须设计仿真波形初始化文件*.vwf

按需要设置输入,设置输出“0”或无效,设置双向/3态为高阻

5)这种仿真的顶层文件有两种实现方式:

a)以描述文件.v为顶层模板--不推荐

cpucore(如cpu4_2t.v)修改

+

调用SRAM实例文件或直接调存贮库

b)以图形如cpu4_2tb.bdf为顶层模板(推荐),其组成:

cpu4_2t.v符图

+RAM库符图+

脚符图+

连线,名2.0.7-14条指令CPU的验证1--逻辑模拟仿真:顶层描述1a)直接修改cpu4_2t.v为仿真用文件,文件中调用实例:改因—仿真时,CPU访问的存贮器是FPGA芯片内部的SRAM,因此

*.v内部不能设计为3态双向连接,访存数据需读/写分开。

独有:图形文件*.gdf/bdf内的部件可设计为3态双向连接。改法o_d

改为SRAM读出数,acc(累加器输出)是SRAM写入数,同时注销数据3态输出语句。然后调入SRAM实例。a1:调入RAM实例:先用File\MegaWizardPlug-InManager

创建sram_mm.v

文件,步骤如下:(MII,QII类同)1.选Create…(选器件注意:Cyclone

族仅同步型)

2.选Storage\LPM_RAM_DQ,实例名键入或浏览选择如sram_mmLPM_RAM_DQ系非写即读、读/写数据分开、同/异步可选的

3.数据宽度如8,地址宽度如8,均选不寄存(即异步,不要clock)4.选存贮器初始化文件即测试程序码

如cpu4_bin.mif5.Finishsram_mm.v

已创建,就可在描述中调用如下:

\sram_mmmemory(.address(o_a),.we(wr),//调sram_mm.v.data(o_d),.q(q_in));

2.0.7-14条指令CPU的验证1--逻辑模拟仿真:顶层描述2库//a2:具有RAM可编程芯片FPGA的SRAM库函数//

lpm_ram_dq

(同/异步、入出数据分开、非写即读)功能参数说明//同步均上升沿↑有效,读RAM要时延,注意CPU打入寄存器的时序配合。//FUNCTIONlpm_ram_dq

(address[LPM_WIDTHAD-1..0],we,//inclock,outclock,data[LPM_WIDTH-1..0])//WITH(LPM_WIDTH,//LPM_WIDTHAD,//LPM_NUMWORDS,//LPM_FILE,//LPM_INDATA,//LPM_ADDRESS_CONTROL,//LPM_OUTDATA)//….//RETURNS(q[LPM_WIDTH-1..0]);//we--是写令高有效;data—写入数据;q—读出数据//DATA/ADDRESS不寄存即不要incolck/outclock,是异步方式//a1:

直接调库lpm_ram_dq,输入同步型描述段如下:\lpm_ram_dq

mm(.address(o_a),.we(write),//cpuoutputo_a,o_d.data(o_d),.q(q_in).inclock(ck));//cpuinputq_in

defparam

//“UNREGISTERED”即指不用“UN”时钟打人寄存器

mm.LPM_WIDTH=8,//数据宽度

mm.LPM_WIDTHAD=8,//地址宽度

//mm.LPM_NUMWORD=256,//存贮器单元数

mm.LPM_INDATA="REGISTERED",//数据输入寄存↑

mm.LPM_ADDRESS_CONTROL=“REGISTERED”,//地址输入寄存↑

mm.LPM_OUTDATA="UNREGISTERED",//输出数据不寄

mm.LPM_FILE=“cpu4_bin.mif”,//运行的程序的目标文件hex及路径

mm.LPM_TYPE=“LPM_RAM_DQ”,//类型:入出数据分开

mm.USE_EAB=“ON”;

//FPGA隐藏块使用,也可不用

mm.LPM_HINT="USED",//ENABLE_RUNTIME_MODneed,defaultis"UNUSED"

mm.ENABLE_RUNTIME_MOD="YES",//In-SystemMemoryContent

//Editorenable,"NO"--ban

mm.INSTANCE_NAME="MEM";//InstanceID//如inclock=ck↑寄存数据地址,则CPU用ck↓打入累加器、指令寄存器等2.0.7-14条指令CPU的验证1--逻辑模拟仿真:顶层描述32.0.7-14条指令CPU的验证1--逻辑模拟仿真:b)顶层图形CPU模块存贮器模块入出引脚库符号的调入:1.图中空白处击鼠标右键2.弹出编辑命令对话框-1inserts\Symbol\lib.3,弹出调入符号对话框-2mega…\storage

选符号文件

lpm_ram_dq

OK4.弹出编辑端口/参数对话框选择存贮器数据地址位数,

读写与片选信号,时钟要?其它参数选择等….

初始化文件选择OK该模块由cpu_sim_mm.v创建

该文包括调用

lpm_ram_dq

lpm_rom

及数据双向描述主存+微存3态缓冲Cyclone读/写数据分开转成双向的通用方式cpu4_2tb.bdf图形仿真模板通过编译的cpu4_2t.v,用File\CreateDefaultSymbol创建、调入非写即读输入同步256cell时延约20ns仿真时,常用的FPGA_RAM存贮模块类型--取决芯片与库类及参数设置2.0.7-14条指令CPU的验证1--逻辑模拟仿真:b)顶层图形入/出时钟4.同步读/写数据与地址均分开(dp)型11.上图片的RAM模块是输入寄存同步型,也可据需要设置为是输入输出均寄存同步型3.

同步读/写数据分开(dq)型2.异步数据双向(IO)型输出可寄存/不寄存写/读分开非写即读非写即读非写即读读/写时钟输出可寄存/不寄存dp型没有在系统存贮器内容编辑功能读/写数据分开转成双向的通用方式ep1c12ep1c12o_aep1c12CycloneCycloneCycloneEPF10K系列FPGA5.同步读/写数据与地址均分开(dp)型2为了方便同学,实验时,逻辑模拟仿真的顶层图形模板文件*.gdf/bdf和仿真波形初始化文件*.scf/vwf,目标文件*.qpf,均由实验室提供,使用方法步骤如下:模板文件:cpu_4tg.gdf/cpu4_2tb.bdf

用自己设计的cpu4_2t.v→创建目标→分配引脚足够的器件(最好与平台ep1c12Q240相同,如因仿真输出观察的引脚多而不够时,分配同家族Cyclone多引脚的)→成功编译→创建其符号文件cpu4_2t.bsf。将其与cpu4_2t.v均拷贝到仿真模板文件夹(覆盖原来的,原cpu4_2t.v是空文件)→打开顶层图形文件cpu4_2tb.bdf→选中图中的CPU模块→删除→右击图中空处→选择Insert/Symbol…→打开,Project→选自己的cpu4_2t.v.bsf→调入放原删除处→调整修改(注意:若自设计的输出、名称、排序等可能与模板中CPU不全相同,则需移动或增删输出引脚,修改数组宽度,注意信号类型属性宽度一致性,切勿搞错)→编译目标*.qpf,成功→仿真→看仿真波形→在仿真报告窗口,击

存贮器项,看内容与结果。若结果不正确,则结合程序,从结果与波形分析查找原因,直到排除。通常先看取指令对否?然后,看取数对否?执行对否?2.0.7-14条指令CPU的验证1--逻辑模拟仿真:b)顶层图形顶层图形模板的使用2.0.7-14条指令CPU的验证1CPU检测程序Cpu4_test.asm指令码为高2位:00加,01取数,10存数,11非进位转

文件头参数地址

SAD;0000编译填入装入程序的开始地址二字节,默认0000;0000;0E02编译填入启动程序运行首地

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论