基于FPGA的简单RISC_CUP设计.doc

上传人:爱问知识人 文档编号:5020523 上传时间:2020-01-29 格式:DOC 页数:16 大小:195KB
返回 下载 相关 举报
基于FPGA的简单RISC_CUP设计.doc_第1页
第1页 / 共16页
基于FPGA的简单RISC_CUP设计.doc_第2页
第2页 / 共16页
基于FPGA的简单RISC_CUP设计.doc_第3页
第3页 / 共16页
基于FPGA的简单RISC_CUP设计.doc_第4页
第4页 / 共16页
基于FPGA的简单RISC_CUP设计.doc_第5页
第5页 / 共16页
点击查看更多>>
资源描述

《基于FPGA的简单RISC_CUP设计.doc》由会员分享,可在线阅读,更多相关《基于FPGA的简单RISC_CUP设计.doc(16页珍藏版)》请在三一文库上搜索。

1、基于FPGA的简单RISC_CUP设计 计算机科学学院 计算机科学与计算专业 09061059 蓝潇莹摘要:CPU即中央处理单元,它是计算机的核心部件。RISC即精减指令集计算机。它是一种20世纪80年代才出现的CPU,与一般的CPU相比不仅仅是简化了指令系统,而且还通过简化指令系统使计算机结果更加简单合理,从而提高了运算速度。关键字:FPGA RISC_CPU 取指令 分析指令 执行指令一、总体概述计算机进行信息处理可分为两个步骤:(1) 将数据和程序(即指令序列)输入到计算机的存储器中;(2) 从第一条指令的地址起开始执行该程序,得到程序所需的结果,结束运行。它必须具有以下基本功能:取指令

2、当程序已在存储器中时,首先根据程序入口地址取出一条程序,为此发出指令地址及控制信号。分析指令即指令译码,这是对当前取得的指令进行分析,指出它要求什么操作,并产生相应的操作控制命令。执行指令根据分析指令时产生的“操作命令”形成相应的操作控制信号序列,通过运算器、存储器及输入/输出设备的执行,实现每条指令的功能,其中包括对运算结果的处理以及下条指令的形成。RISC_CPU是一个复杂的数字逻辑电路,但他的基本部件的逻辑并不复杂。我们可以把它分成8个基本部件来考虑:(1) 时钟发生器;(2) 指令寄存器;(3) 累加器;(4) RISC_CPU算术逻辑运算单元;(5) 数据控制器;(6) 状态控制器;

3、(7) 程序计数器;(8) 地址多路器。三、总体框图 RISC_CPU中部件的相互连接关系三、各模块功能说明及主要程序代码(1) 时钟发生器 时钟发生器clk_gen利用外来的时钟信号clk生成一系列时钟信号clk1、fetch、alu_clk,并送往CPU其他部件。其中,fetch是外来时钟clk的8分频信号,利用fetch的上升沿来触发CPU控制器来执行一条指令,同时fetch信号还将控制地址多路器输出指令地址和数据地址;clk1信号用于指令寄存器、累加器、状态控制器的时钟信号;alu_clk则用于触发算术逻辑运算单元。如下为时钟发生器原理图: 其主要的verilog代码见下面模块:mod

4、ule CLC_GEN(clk,reset,clk1,clk2,clk4,fetch,alu_clk);input clk,reset;output clk1,clk2,clk4,fetch,alu_clk;wire clk,reset;reg clk2,clk4,fetch,alu_clk;reg7:0 state;parameter s1=8b00000001, s2=8b00000010, s3=8b00000100, s4=8b00001000, s5=8b00010000, s6=8b00100000, s7=8b01000000, s8=8b10000000, idle=8b000

5、00000;assign clk1=clk;always (negedge clk) if(reset) begin clk2=0;clk4=1;fetch=0;alu_clk=0;state=idle;end else begin case(state) s1: begin clk2=clk2; alu_clk=alu_clk; state=s2;end s2: begin clk2=clk2; clk4=clk4; alu_clk=alu_clk; state=s3;end s3: begin clk2=clk2; state=s4;end s4: begin clk2=clk2; clk

6、4=clk; fetch=fetch; state=s5;end s5: begin clk2=clk2; state=s5;end s6: begin clk2=clk2; clk4=clk; state=s7;end s7: begin clk2=clk2; state=s8;ends8: begin clk2=clk2; clk4=clk; fetch=fetch; state=s1;end idle: state=s1; default: state=idle; endcase endEndmodule(2) 指令寄存器指令寄存器的触发时钟是clk1,在clk1正沿触发下,寄存器将数据

7、总线送来的指令存入高8位或低8位寄存器中,但并不是每个clk1的上升沿都寄存数据总线的数据,因为数据总线上有时传输指令,有时传输数据。什么时候寄存,什么时候不寄存由CPU状态控制器的load_ir信号控制。而当前取得是高8位还是低8位,由变量state记录。State为0表示取的是高8位,存入高8为寄存器时,同时将变量state置为1.下次再寄存时,由于state为1,可知取的是低8位,存入低8位寄存器中。主要的verilog代码见下面模块:module register(opc_iraddr,data,ena,clk1,rst);output15:0 opc_iraddr;input7:0

8、data;input ena,clk1,rst;reg15:0 opc_iraddr;reg state;always (posedge clk1)begin if(rst) begin opc_iraddr=16b0000000000000000; state=1b0; end else begin if(ena) begin casex(state) 1b0: begin opc_iraddr15:8=data;state=1;end1b1: begin opc_iraddr7:0=data;state=0;end default: begin opc_iraddr15:0=16bxxxx

9、xxxxxxxxxxxx;state=1bx;endendcase endelse state=1b0;endendendmodule(3) 累加器累加器用于存放当前的结果,它也是双目运算中的一个数据来源。复位后,累加器的值是零。当累加器通过ena口收到来自CPU状态控制器load_acc信号时,在clk1时钟正跳沿时就收到来自于数据总线的数据。主要的verilog代码见下面模块:module accum(accum,data,ena,clk1,rst);output7:0 accum;input7:0 data;input ena,clk1,rst;reg7:0 accum;always (

10、posedge clk1) begin if(rst) accum=8b00000000; else if(ena) accum=data; endendmodule(4) 算术运算器 它根据输入得8种不同的操作码分别实现相应的加、与、异或、跳转等基本操作运算。主要的verilog代码见下面模块:module alu(alu_out,zero,data,accum,alu_clk,opcode);output7:0 alu_out;output zero;input7:0 data,accum;input2:0 opcode;input alu_clk;reg7:0 alu_out;param

11、eter HLT=3B000, SKZ=3B001, ADD=3B010, ANDD=3B011, XORR=3B100, LDA=3B101, STO=3B110, JMP=3B111;assign zero=!accum;always (posedge alu_clk) begin casex(opcode) HLT: alu_out=accum; SKZ: alu_out=accum; ADD: alu_out=data+accum; ANDD:alu_out=data&accum; XORR:alu_out=dataaccum; LDA: alu_out=data; STO: alu_

12、out=accum; JMP: alu_out=accum;default: alu_out=8bxxxxxxxx; endcase endendmodule(5) 数据控制器数据控制器的作用是控制累加器的数据输出,由于数据总线是各种操作时传送数据的公共通道,不同情况下传送不同的内容。主要的verilog代码见下面模块:module datactl(data,in,data_ena);output7:0 data;input7:0 in;input data_ena;assign data=(data_ena)?in:8bzzzzzzzz;endmodule(6) 地址多路器地址多路器只要的作

13、用是选择输出的地址是PC地址还是数据/端口地址。地址的选择输出信号由时钟信号的8分频信号fetch提供。主要的verilog代码见下面模块:module adr(addr,fetch,ir_addr,pc_addr);output12:0 addr;input12:0 ir_addr,pc_addr;input fetch;assign addr=fetch?pc_addr:ir_addr;endmodule(7) 程序计数器程序计数器用于提供指令地址,以便读取指令。复位后,指令指针为零,即每次CPU重新启动将从ROM的零地址开始读取指令并执行每条指令执行完需两个时钟,这时pc_addr已被增

14、2,指向下一条指令。如果正在执行的指令是跳转语句,这时CPU状态控制器将会输出load_pc信号,通过load口进入程序计数器。程序计数器(pc_addr)将装入目标地址(ir_addr),而不是增2.主要的verilog代码见下面模块:module counter(pc_addr,ir_addr,load,rst);output12:0 pc_addr;input12:0 ir_addr;input load,clock,rst;reg12:0 pc_addr;always (posedge clock or posedge rst) begin if(rst) pc_addr=13b000

15、0000000000; else if(load)pc_addr=ir_addr;else pc_addr=pc_addr+1; endendmodule(8) 状态控制器状态控制器主要由两个部分组成:a 状态机;b 状态控制器。状态控制器接受复位信号RST,当RST有效时,通过信号ena使其为0,输入到状态机中以停止状态机的工作。状态控制器主要的verilog代码见下面模块:module machinectl(ena,fetch,rst);output ena;input fetch,rst;reg ena;always (posedge fetch or posedge rst) begi

16、n if(rst) ena=0; else ena=1; endendmodule状态机是CPU的控制核心,用于产生一系列的控制信号,启动或停止某些部件。CPU何时进行读写指令来读写I/O端口及RAM区等操作,都是由状态机来控制的。状态控制器主要的verilog代码见下面模块:module machine(inc_pc,load_acc,load_pc,rd,wr,load_ir,datactl_ena,halt,clk1,zero,ena,opcode);output inc_pc,load_acc,load_pc,rd,wr,load_ir;output datactl_ena,halt;

17、input clk1,zero,ena;input2:0 opcode;reg inc_pc,load_acc,load_pc,rd,wr,load_ir;reg datactl_ena,halt;reg2:0 state;paremeter HLT=3b000, SKZ=3b001, ADD=3b010, ANDD=3b011, XORR=3b100, LDA=3b101, STO=3b110, JMP=3b111;always (negedge clk1)begin if(!ena) beginstate=3b000;inc_pc,load_acc,load,pc,rd=4b0000;wr

18、,load_ir,datactl_ena,halt=4b0000;endelsetask ctl_cyclebegincasex(state)3b000; beginstate=3b001;inc_pc,load_acc,load,pc,rd=4b0001;wr,load_ir,datactl_ena,halt=4b0100;end3b001; beginstate=3b010;inc_pc,load_acc,load,pc,rd=4b1001;wr,load_ir,datactl_ena,halt=4b0100;end3b010; beginstate=3b011;inc_pc,load_a

19、cc,load,pc,rd=4b0000;wr,load_ir,datactl_ena,halt=4b0000;end3b011; beginif(opcode=HLT)begininc_pc,load_acc,load,pc,rd=4b1000;wr,load_ir,datactl_ena,halt=4b0001;end else begin inc_pc,load_acc,load,pc,rd=4b1000;wr,load_ir,datactl_ena,halt=4b0000; end state=3b100; end3b100; beginif(opcode=JMP)begininc_p

20、c,load_acc,load,pc,rd=4b0010;wr,load_ir,datactl_ena,halt=4b0000;end elseif(opcode=ADD|opcode=ANDD|opcode=XORR|opcode=LDA) begin inc_pc,load_acc,load,pc,rd=4b0001;wr,load_ir,datactl_ena,halt=4b0000; endelseif(opcode=STO) begin inc_pc,load_acc,load,pc,rd=4b0000;wr,load_ir,datactl_ena,halt=4b0010; ende

21、lse begin inc_pc,load_acc,load,pc,rd=4b0000;wr,load_ir,datactl_ena,halt=4b0000; end state=3b101; end3b101; beginif(opcode=ADD|opcode=ANDD|opcode=XORR|opcode=LDA)begininc_pc,load_acc,load,pc,rd=4b0101;wr,load_ir,datactl_ena,halt=4b0000;end elseif(opcode=SKZ&zero=1) begin inc_pc,load_acc,load,pc,rd=4b

22、1000;wr,load_ir,datactl_ena,halt=4b0000; endelseif(opcode=JMP) begin inc_pc,load_acc,load,pc,rd=4b1010;wr,load_ir,datactl_ena,halt=4b0000; endelseif(opcode=STO) begin inc_pc,load_acc,load,pc,rd=4b0000;wr,load_ir,datactl_ena,halt=4b1010; end else begin inc_pc,load_acc,load,pc,rd=4b0000;wr,load_ir,dat

23、actl_ena,halt=4b0000; end state=3b110; end3b110; beginif(opcode=STO)begininc_pc,load_acc,load,pc,rd=4b0000;wr,load_ir,datactl_ena,halt=4b0010;end elseif(opcode=ADD|opcode=ANDD|opcode=XORR|opcode=LDA) begin inc_pc,load_acc,load,pc,rd=4b0001;wr,load_ir,datactl_ena,halt=4b0000; endelse begin inc_pc,loa

24、d_acc,load,pc,rd=4b0000;wr,load_ir,datactl_ena,halt=4b0000; end state=3b111; end3b111; beginif(opcode=SKZ&zero=1)begininc_pc,load_acc,load,pc,rd=4b1000;wr,load_ir,datactl_ena,halt=4b0000;end else begin inc_pc,load_acc,load,pc,rd=4b0000;wr,load_ir,datactl_ena,halt=4b0000; end state=3b000; enddefault;

25、begininc_pc,load_acc,load,pc,rd=4b1000;wr,load_ir,datactl_ena,halt=4b0000;state=3b000;endendcaseendendtaskendmodule(9) 外围模块为了对RISC_CPU进行测试,需要有存储测试程序的ROM和装载数据的RAM、地址译码器。地址译码器主要的verilog代码见下面模块:module addr_decode(addr,rom_sel,ram_sel);output rom_sel,ram_sel;input12:0 addr;reg rom_sel,ram_sel;always (ad

26、dr)begin casex(addr) 13b11xxxxxxxxxxx:rom_sel,ram_sel=2b01; 13b0xxxxxxxxxxxx:rom_sel,ram_sel=2b10; 13b10xxxxxxxxxxx:rom_sel,ram_sel=2b10; default:rom_sel,ram_sel=2b00; endcaseendendmoduleRAM主要的verilog代码见下面模块:module ram(data,addr,ena,read,write);inout7:0 data;input9:0 addr;input ena;input read,write;

27、reg7:0 ram10h3ff:0;assign data=(read&ena)?ramaddr:8hzz;always (posedge write)begin ramaddr=data;endendmoduleRAM主要的verilog代码见下面模块:module rom(data,addr,read,ena);output7:0 data;input12:0 addr;input read,ena;reg7:0 memory13h1fff:0;wire7:0 data;assign data=(read&ena)?memoryaddr:8bzzzzzzzz;endmodule四、实验分

28、析RISC_CPU的指令系统由8条指令组成:(1) HLT:停机操作。该操作将空一个指令周期,即8个时钟周期。(2) SKZ:若为零跳过下一句语句。该操作先判断当前alu中的结果是否为零,若为零就跳过下一句语句,否则继续执行。(3) ADD:相加。该操作将累加器中的值与地址所指的存储器或端口的数据相加,结果仍送回累加器中。(4) AND:相与。该操作将累加器的值与地址所指的存储器或端口的数据相与,结果仍送回累加器中。(5) XOR:异或。该操作将累加器的值与指令中给出地址的数据异或,结果仍送回累加器中。(6) LDA读数据。该操作将指令中给出地址的数据放入累加器。(7) STO写数据。该操作就

29、爱那个累加器的数据放入指令中给出的地址。(8) JMP无条件跳转语句。该操作将跳转至指令给出的地址。五、结论 复杂的RISC_CPU设计其实是一个从抽象到具体的逐步接近的分析和实现的过程。一个大型的设计应先从概念出发,用Verilog写出抽象的功能块描述,把许多复杂的细节掩盖起来。然后从行为级分析功能块之间饿关系,通过仿真逐步验证,发现问题,改动模块代码使其逐步趋向合理,并最后可以用RTL级verilog源代码模块来表示。接下去就可以通过自动综合工具把RTL级的verilog源代码综合成电路网表,再通过布局布线工具让它们更具体化。在基础器件源语级的基础上的系统精确仿真结果正确,可以使系统电路芯片的制作有90%以上的一次流片成功的把握。

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

当前位置:首页 > 研究报告 > 商业贸易


经营许可证编号:宁ICP备18001539号-1