1、湘 潭 大 学 实 验 报 告 课程名称 计算机原理与设计 实验名称 多周期 CPU与存储器 实验 页数 专业 班级 同组者姓名 无 组别 学号 姓名 实验日期 一、 实验目的 1 了解多周期 CPU 的数据传输通路。 2 了解指令执行的周期划分。 3 掌握用时序电路实现多周期 CPU 的控制部件的方法。 4 了解指令存储器与数据存储器合二为一的 实现方法。 5 按给定数据,测试多周期 CPU 功能 。 二、 实验要求 1、做好实验预习,掌握多周期 CPU + 存储器的总体电路设计和 CPU 的功能特性,并熟悉本实验中所用的控制台开关的作用和使用方法。 2、写出实验报告,内容是: 实验目的;
2、按理论分析值给出对应的仿真波形。 比较实验数据的理论分析值与实验结果值;并对结果进行分析。实验结果与理论分析值比较,有没有不同?为什么 ? 通过本实验,你对多周期 CPU 有何认识,有什么心得体会? 三、 实验原理 多周期 CPU + 存储器的总体电路设计如图 4-1 所示。 本实验模块设计如图 4-2 所示,包含多周期 CPU 模块 mccpu 和存储器模块 mcmem。 四、 实验内容 ( 1)设计元件 在 Quartus II 环境下,用文本输入编辑器 Text Editor 分别输入 mccpu.v 多周期 CPU 单元文件和 mcmem.v 存储器单元文件,编译 Verilog HD
3、L 文件,并将 mccpu.v 与 mcmem.v 文件制作成可调用的原理图元件。 ( 2)以原理图方式建立顶层文件工程选择图形方式。根据图 4-2 输入实验电路图,从 Quartus II 的基本元件库中将各元件调入图形编辑窗口、连线,添加输入输出引脚。将所设计的图形文件 mccomp.bdf 保存到原先建立的文件夹中,将当前文件设置成工程文件,以后的操作就都是对当前工程文件进行的。 ( 3)器件选择 选择 Cyclone 系列,在 Devices 中选择器件 EP1C12QC240C8。编译,引脚锁定,再编译。引脚锁定后需要再次进行编译,才能将锁定信息确定下来,同时生成芯片编程 /配置所需
4、要的各种文件。 ( 4)芯片编程 Programming(可以直接选择光盘中的示例已完成的设计进行验证实验) 打开编程窗口。将配置文件 mccomp.sof 下载进 GW48 系列现代计算机组成原理系统中的 FPGA 中。 ( 5)选择实验系统的电路模式是 NO.0,验证 CPU 的控制和运算功能以及对存储器的访问功能。根据 mcmem.mif 文件初始化存储器,并设置 clock、 resetn、mem_clk 的值,验证 CPU的控制和运算功能以及对存储器的访问功能,记录实验数据。 五、 实验环境与设备 GW48CP+主系统、 pc机 六、 实验代码设计(含符 号说明) module al
5、u (a,b,aluc,r,z); input 31:0 a,b; input 3:0 aluc; output 31:0 r; output z; assign r = cal(a,b,aluc); assign z = |r; function 31:0 cal; input 31:0 a,b; input 3:0 aluc; casex (aluc) 4bx000: cal=a+b; 4bx100: cal=a-b; 4bx001: cal=a 4bx101: cal=a|b; 4bx010: cal=ab; 4bx110: cal=b15:0,16h0; 4bx011: cal=ba4
6、:0; 4b1111: cal=$signed(b)a4:0; endcase endfunction endmodule module dff32 (d,clk,clrn,q); input 31:0 d; input clk,clrn; output 31:0 q; reg 31:0 q; always (negedge clrn or posedge clk) if (clrn = 0) begin q = 0; end else begin q = d; end endmodule module dffe32 (d,clk,clrn,e,q); input 31:0 d; input
7、clk,clrn,e; output 31:0 q; reg 31:0 q; always (negedge clrn or posedge clk) if (clrn = 0) begin q = 0; end else begin if(e = 1) q = d; end endmodule module mccomp (clock,resetn,q,a,b,alu,adr,tom,fromm,pc,ir,mem_clk); input clock,resetn,mem_clk; output 31:0 a,b,alu,adr,tom,fromm,pc,ir; output 2:0 q;
8、wire wmem; mccpu mc_cpu (clock,resetn,fromm,pc,ir,a,b,alu,wmem,adr,tom,q); mcmem memory (clock,fromm,tom,adr,wmem,mem_clk,mem_clk); endmodule module mccpu (clock,resetn,frommem,pc,inst,alua,alub,alu,wmem,madr,tomem,state); input 31:0 frommem; input clock,resetn; output 31:0 pc,inst,alua,alub,alu,mad
9、r,tomem; output 2:0 state; output wmem; wire 3:0 aluc; wire 4:0 reg_dest; wire z,wpc,wir,wmem,wreg,iord,regrt,m2reg,shift,selpc,jal,sext; wire 31:0npc,rega,regb,regc,mem,qa,qb,res,opa,bra,alub,alu_mem; wire 1:0 alusrcb, pcsource; wire 31:0 sa = 27b0,inst10:6; mccu control_unit (inst31:26,inst5:0,z,c
10、lock,resetn,wpc, wir, wmem, wreg, iord, regrt, m2reg, aluc,shift,selpc, alusrcb, pcsource, jal, sext, state); wire e = sext wire 15:0 imm = 16e; wire 31:0 immediate = imm,inst15:0; wire 31:0 offset = imm13:0,inst15:0,1b0,1b0; dffe32 ip (npc,clock,resetn,wpc,pc); dffe32 ir (frommem,clock,resetn,wir,i
11、nst); dff32 dr (frommem,clock,resetn,mem); dff32 ra (qa,clock,resetn,rega); dff32 rb (qb,clock,resetn,regb); dff32 rc (alu,clock,resetn,regc); assign tomem = regb; mux2x5 reg_wn (inst15:11,inst20:16,regrt,reg_dest); wire 4:0 wn = reg_dest | 5jal; / jal: r31 - p4; mux2x32 mem_address (pc,regc,iord,ma
12、dr); mux2x32 result (regc,mem,m2reg,alu_mem); mux2x32 link (alu_mem,pc,jal,res); mux2x32 oprand_a (rega,sa,shift,opa); mux2x32 alu_a (opa,pc,selpc,alua); mux4x32 alu_b (regb,32h4,immediate,offset,alusrcb,alub); mux4x32 nextpc (alu,regc,qa,jpc,pcsource,npc); / next pc regfile rf (inst25:21,inst20:16,
13、res,wn,wreg,clock,resetn,qa,qb); wire 31:0 jpc = pc31:28,inst25:0,1b0,1b0; alu alunit (alua,alub,aluc,alu,z); endmodule module mccu (op, func, z, clock, resetn, wpc, wir, wmem, wreg, iord, regrt, m2reg, aluc, shift, alusrca, alusrcb, pcsource, jal, sext, state); input 5:0 op, func; input z, clock, r
14、esetn; output reg wpc, wir, wmem, wreg, iord, regrt, m2reg; output reg 3:0 aluc; output reg 1:0 alusrcb, pcsource; output reg shift, alusrca, jal, sext; output reg 2:0 state; reg 2:0 next_state; parameter 2:0 sif = 3b000, / IF state sid = 3b001, / ID state sexe = 3b010, / EXE state smem = 3b011, / M
15、EM state swb = 3b100; / WB state wire r_type,i_add,i_sub,i_and,i_or,i_xor,i_sll,i_srl,i_sra,i_jr; wire i_addi,i_andi,i_ori,i_xori,i_lw,i_sw,i_beq,i_bne,i_lui,i_j,i_jal; and(r_type,op5,op4,op3,op2,op1,op0); and(i_add,r_type, func5,func4,func3,func2,func1,func0); and(i_sub,r_type, func5,func4,func3,fu
16、nc2, func1,func0); and(i_and,r_type, func5,func4,func3, func2,func1,func0); and(i_or, r_type, func5,func4,func3, func2,func1, func0); and(i_xor,r_type, func5,func4,func3, func2, func1,func0); and(i_sll,r_type,func5,func4,func3,func2,func1,func0); and(i_srl,r_type,func5,func4,func3,func2, func1,func0
17、); and(i_sra,r_type,func5,func4,func3,func2, func1, func0); and(i_jr, r_type,func5,func4, func3,func2,func1,func0); and(i_addi,op5,op4, op3,op2,op1,op0); and(i_andi,op5,op4, op3, op2,op1,op0); and(i_ori, op5,op4, op3, op2,op1, op0); and(i_xori,op5,op4, op3, op2, op1,op0); and(i_lw, op5,op4,op3,op2,
18、op1, op0); and(i_sw, op5,op4, op3,op2, op1, op0); and(i_beq, op5,op4,op3, op2,op1, op0); and(i_bne, op5,op4,op3, op2,op1, op0); and(i_lui, op5,op4, op3, op2, op1, op0); and(i_j, op5,op4,op3,op2, op1,op0); and(i_jal, op5,op4,op3,op2, op1, op0); wire i_shift; or (i_shift,i_sll,i_srl,i_sra); always * b
19、egin / control signals dfault outputs: wpc = 0; / do not write pc wir = 0; / do not write ir wmem = 0; / do not write memory wreg = 0; / do not write register file iord = 0; / select pc as memory address aluc = 4bx000; / ALU operation: add alusrca = 0; / ALU input a: reg a or sa alusrcb = 2h0; / ALU
20、 input b: reg b regrt = 0; / reg dest no: rd m2reg = 0; / select reg c shift = 0; / select reg a pcsource= 2h0; / select alu output jal = 0; / not a jal sext = 1; / sign extend case (state) /- IF: sif: begin / IF state wpc = 1; / write pc wir = 1; / write IR alusrca = 1; / PC alusrcb = 2h1; / next_s
21、tate = sid; / next state: ID end /- ID: sid: begin / ID state if (i_j) begin / j instruction pcsource = 2h3; / jump address wpc = 1; / write PC next_state = sif; / next state: IF end else if (i_jal) begin / jal instruction pcsource = 2h3; / jump address wpc = 1; / write PC jal = 1; / reg no = 31 wre
22、g = 1; / save PC+4 next_state = sif; / next state: IF end else if (i_jr) begin / jr instruction pcsource = 2h2; / jump register wpc = 1; / write PC next_state = sif; / next state: IF end else begin / other instruction aluc = 4bx000; / add alusrca = 1; / PC alusrcb = 2h3; / branch offset next_state =
23、 sexe; / next state: EXE end end /- EXE: sexe: begin / EXE state aluc3 = i_sra; aluc2 = i_sub | i_or | i_srl | i_sra | i_ori | i_lui ; aluc1 = i_xor | i_sll | i_srl | i_sra | i_xori | i_beq | i_bne | i_lui ; aluc0 = i_and | i_or | i_sll | i_srl | i_sra | i_andi | i_ori ; if (i_beq | i_bne) begin / b
24、eq or bne instruction pcsource = 2h1; / branch address wpc = i_beq / write PC next_state = sif; / next state: IF end else begin / other instruction if(i_lw | i_sw) begin / lw or sw instruction alusrcb = 2h2; / select offset next_state = smem; / next state: MEM end else begin / other instruction if (
25、i_shift) shift = 1; / shift instruction if (i_addi | i_andi | i_ori | i_xori | i_lui) alusrcb = 2h2; / select immediate if (i_andi | i_ori | i_xori) sext = 0; / 0-extend next_state = swb; / next state: WB end end end /- MEM: smem: begin / MEM state iord = 1; / memory address = C if (i_lw) begin next
26、_state = swb; / next state: WB end else begin / store wmem = 1; / write memory next_state = sif; / next state: IF end end /- WB: swb: begin / WB state if (i_lw) m2reg = 1; / select memory data if (i_lw | i_addi | i_andi | i_ori | i_xori | i_lui) regrt = 1; / reg dest no: rt wreg = 1; / write registe
27、r file next_state = sif; / next state: IF end /- ENDdefault: begin next_state = sif; /default state end endcase end always (posedge clock or negedge resetn) begin / state registers if (resetn = 0) begin state = sif; end else begin state = next_state; end end endmodule module mcmem (clk, dataout, dat
28、ain, addr, we, inclk, outclk); input 31:0 datain; input 31:0 addr; input clk, we, inclk, outclk; output 31:0 dataout; wire write_enable = we lpm_ram_dq ram (.data(datain),.address(addr7:2),.we(write_enable),.inclock(inclk),.outclock(outclk),.q(dataout); defparam ram.lpm_width = 32; defparam ram.lpm_
29、widthad = 6; defparam ram.lpm_indata = “registered“; defparam ram.lpm_outdata = “registered“; defparam ram.lpm_file = “mcmem.mif“; defparam ram.lpm_address_control = “registered“; endmodule module mux2x5 (a0,a1,s,y); input 4:0 a0,a1; input s; output 4:0 y; assign y = s ? a1 : a0; endmodule module mu
30、x2x32 (a0,a1,s,y); input 31:0 a0,a1; input s; output 31:0 y; assign y = s ? a1 : a0; endmodule module mux4x32 (a0,a1,a2,a3,s,y); input 31:0 a0,a1,a2,a3; input 1:0 s; output 31:0 y; function 31:0 select; input 31:0 a0,a1,a2,a3; input 1:0 s; case (s) 2b00: select = a0; 2b01: select = a1; 2b10: select
31、= a2; 2b11: select = a3; endcase endfunction assign y = select (a0,a1,a2,a3,s); endmodule module regfile (rna,rnb,d,wn,we,clk,clrn,qa,qb); input 4:0 rna,rnb,wn; input 31:0 d; input we,clk,clrn; output 31:0 qa,qb; reg 31:0 register1:31; /r1-r3 assign qa = (rna = 0) ? 0 : registerrna; /read assign qb
32、= (rnb = 0) ? 0 : registerrnb; always (posedge clk or negedge clrn) begin if (clrn = 0) begin /reset integer i; for (i=1; i32; i=i+1) registeri = 0; end else begin if (wn != 0) end end endmodule 七、 实验检验与测试 仿真结果波形图: 引脚分配截图: 八、 测试数据 编号 数据 1 2302009F 2 0302009F 3 23401493 4 03401493 5 23801493 6 038014
33、94 7 23C01494 8 03601489 9 24001463 10 04001868 九、 实验过程中出现的问题及处理情况(包括实验现象、原因分析、排故障的方法等) 1. 输入代码后,编译程序出现编译错误:反复对照课本,核对代码后修正错误,编译成功; 2. 将电脑连接 GW48CP系统,下载程序时,出现不识别硬件的情况:百度了解到可能是 pc端缺少 usb驱动控件,之后根据网上的教程,利用 Quarstus工具包中只带的驱动包进行驱动安装,安装成功后,硬件识别成功,顺利将源程序下载到 GW48CP系统中; 3. 这是计算机原理与设计的最后一次上机实验,同时也是留给我们难度最大的一次实验,老师鼓励我们积极地进行自主实验设计,给我们提供了一次最佳的实践机会,来巩固学过的知识,虽然在程序设计过程中遇到了不少坎坷和 挑战,但通过与同学的默契协作 研究 和坚持不懈的探索,终于将实验圆满地完成。