计算机组成原理实验报告 实验三:控制器实验(源码全)
- 实验类型
- 本实验为设计型实验。
- 实验目的
- ① 具有多周期控制器的设计能力。
② 掌握用 Verilog HDL 实现有限状态机的常用方法。
③ 熟悉 Vivado 的设计流程,具备硬件的设计仿真和测试能力。
④ 测试多周期控制器的功能。 - 实验原理
控制器是CPU 的重要组成部分,是整个计算机的控制核心。控制器的功能是按照程序预定的顺序执行每条指令。每条指令都是在控制器的控制下按照取指令、分析指令和执行指令的步骤依次完成的, 这就需要控制器必须在正确的时间准确地产生各部件的控制信号, 使计算机能够有条不紊地完成所有指令的功能。
多周期 CPU 把指令执行分成多个阶段,每个阶段在一个时钟周期内完成,如取指、译码、执行、访存、写回。此时,不同指令所用周期数可以不同,每个周期只做一部分操作。将 CPU 划分为多周期的优势在于,每个时钟周期内 CPU 需要做的工作就变少,因此时钟周期短、时钟频率高;每个部件做的事情单一,如取指部件只负责从指令存储器中取出指令,因此 CPU 可以进行流水工作,相当于一个时钟周期完成一条指令, CPU 可以更快地运行。
多周期 MIPS CPU 的控制部件的状态转移如下图 所示,每个状态对应一个周期。
本实验根据状态及指令直接对控制信号赋值,中间变量 next_state 意为下一状态。在当前状态中,根据指令对 next_state 赋值,并在每个时钟上升沿把 next_state 存入状态寄存器,这是用 Verilog HDL 实现有限状态机时常用的方法。- 实验内容和要求
① 学习 MIPS 指令集,深入理解常用指令的功能和编码,并进行归纳确定处理器各部件的控制码,如使用何种运算、是否写寄存器堆等。
② 参考附录 E,根据本实验准备实现的 20 条 MIPS 指令和最后一行跳转指令的示例,将下表补充填写完整。
指令类型 汇编指令 指令码 源操作数1 源操作数2 目的寄存器 功能描述
R型指令 add rd, rs, rt 000000 rs | rt | rd | 00000|100000
I型指令 addi rt, rs, imm 001000 rs|rt|imm
J型指令 j target 000010 | target PC target PC 跳转
PC={PC[31:28],target,2’b00}
③ 自行设计本实验的方案,多周期 MIPS CPU 的控制部件的大致结构如下图所示。
④ 根据设计的实验方案,使用 Verilog HDL 编写相应代码。
⑤ 对编写的代码进行仿真,得到正确的波形图。
⑥ 将以上设计作为一个单独的模块,设计一个外围模块去调用该模块,如下图所示。
外围模块中需调用封装好的 LCD 触摸屏模块, 观察多周期 CPU 的控制器的状态和各输出控制信号的值等,并且需要利用触摸功能输入指令的操作码、功能码,以达到实时观察控制信号变化的效果。通过这些手段,可以在实验箱上充分验证 CPU 的正确性。
⑦ 将编写的代码进行综合布局布线,并下载到 FPGA 实验箱上进行硬件测试,做好实验记录,验证此设计的功能。
⑧ 参考附录 C 的格式撰写实验报告,实验报告内容包括:程序设计、仿真分析、硬件测试和实验操作步骤,以及源程序代码、仿真波形图、数据记录和实验结果分析等。
源代码
mccu.v:
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,resetn; 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 = 3'b000, sid = 3'b001, sexe = 3'b010, smem = 3'b011, swb = 3'b100; 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,~op[5],~op[4],~op[3],~op[2],~op) ;and(r_type,~op[5],~op[4],~op[3],~op[2],~op[1],~op[0]); and(i_add,r_type,func[5],~func[4],~func[3],~func[2],~func[1],~func[0]); and(i_sub,r_type,func[5],~func[4],~func[3],~func[2],func[1],~func[0]); and(i_and,r_type,func[5],~func[4],~func[3],func[2],~func[1],~func[0]); and(i_or,r_type,func[5],~func[4],~func[3],func[2],~func[1],func[0]); and(i_xor,r_type,func[5],~func[4],~func[3],func[2],func[1],~func[0]); and(i_sll,r_type,~func[5],~func[4],~func[3],~func[2],~func[1],~func[0]); and(i_srl,r_type,~func[5],~func[4],~func[3],~func[2],func[1],~func[0]); and(i_sra,r_type,~func[5],~func[4],~func[3],~func[2],func[1],func[0]); and(i_jr,r_type,~func[5],~func[4],func[3],~func[2],~func[1],~func[0]); and(i_addi,~op[5],~op[4],op[3],~op[2],~op[1],~op[0]); and(i_andi,~op[5],~op[4],op[3],op[2],~op[1],~op[0]); and(i_ori,~op[5],~op[4],op[3],op[2],~op[1],op[0]); and(i_xori,~op[5],~op[4],op[3],op[2],op[1],~op[0]); and(i_lw,op[5],~op[4],~op[3],~op[2],op[1],op[0]); and(i_sw,op[5],~op[4],op[3],~op[2],op[1],op[0]); and(i_beq,~op[5],~op[4],~op[3],op[2],~op[1],~op[0]); and(i_bne,~op[5],~op[4],~op[3],op[2],~op[1],op[0]); and(i_lui,~op[5],~op[4],~op[3],op[2],op[1],op[0]); and(i_j,~op[5],~op[4],~op[3],~op[2],op[1],~op[0]); and(i_jal,~op[5],~op[4],~op[3],~op[2],op[1],op[0]); wire i_shift; or (i_shift,i_sll,i_srl,i_sra); always @ * begin wpc = 0; wir = 0; wmem = 0; wreg = 0; iord = 0; aluc = 4'bx000; alusrca = 0; alusrcb = 2'h0; regrt = 0; m2reg = 0; shift = 0; pcsource = 2'h0; jal = 0; sext = 1; case (state) sif:begin wpc = 1; wir = 1; alusrca = 1; alusrcb = 2'h1; next_state = sid; end sid:begin if(i_j)begin pcsource = 2'h3; wpc = 1; next_state = sif; end else if(i_jal)begin pcsource = 2'h3; wpc = 1; jal = 1; wreg = 1; next_state = sif; end else if(i_jr)begin pcsource = 2'h2; wpc = 1; next_state = sif;
end
mccu_display.v:
//*************************************************************************
// > 文件名: mccu_display.v
// > 描述 :mccu 显示模块,调用 FPGA 板上的 IO 接口和触摸屏
//*************************************************************************
module mccu_display(//时钟与复位信号input clk,input resetn, //后缀"n"代表低电平有效
//脉冲开关,用于产生脉冲 clk,实现单步执行input btn_clk,//拨码开关,用于选择输入数input [1:0] input_sel, //00:输入为控制信号(op)//10:输入为源操作数 1(func)//11:输入为源操作数 2(z)//触摸屏相关接口,不需要更改output lcd_rst,output lcd_cs,output lcd_rs,output lcd_wr,output lcd_rd,inout[15:0] lcd_data_io,output lcd_bl_ctr,inout ct_int,inout ct_sda,output ct_scl,output ct_rstn);//-----{时钟和复位信号}begin
//不需要更改,用于单步调试wire cpu_clk; //多周期 CPU 里使用脉冲开关作为时钟,以实现单步执行
reg btn_clk_r1;
reg btn_clk_r2;always @(posedge clk)beginif (!resetn)beginbtn_clk_r1<= 1'b0;endelsebeginbtn_clk_r1 <= ~btn_clk;endbtn_clk_r2 <= btn_clk_r1;end
wire clk_en;assign clk_en = !resetn || (!btn_clk_r1 && btn_clk_r2);BUFGCE cpu_clk_cg(.I(clk),.CE(clk_en),.O(cpu_clk));
//-----{时钟和复位信号}end
//-----{调用 mccu 模块}beginreg [5:0] op; // 操作码reg [5:0] func; // 功能码//-----{此处省略,请自己编写} ALU 结果为零标志reg z;wire [3:0] aluc; // ALU 控制信号wire [1:0] alusrcb, pcsource;wire shift,alusrca,jal,sext,wpc,wir,wmem,wreg,iord,regrt,m2reg;wire [2:0] state;mccu m(.op(op),.func(func),.z(z),.clock(cpu_clk),.resetn(resetn),.wpc(wpc),.wir(wir),.wmem(wmem),.wreg(wreg),.iord(iord),.regrt(regrt),.m2reg(m2reg),.aluc(aluc),.shift(shift),.alusrca(alusrca),.alusrcb(alusrcb),.pcsource(pcsource),.jal(jal),.sext(sext),.state(state)//-----{此处省略,请自己编写}
);//-----{调用 mccu 模块}end
//---------------------{调用触摸屏模块}begin--------------------//
//-----{实例化触摸屏}begin
//此小节不需要更改reg display_valid;reg [39:0] display_name;reg [31:0] display_value;wire [5 :0] display_number;wire input_valid;wire [31:0] input_value;lcd_module lcd_module(.clk (clk ), //10Mhz.resetn (resetn ),//调用触摸屏的接口.display_valid (display_valid ),.display_name (display_name ),.display_value (display_value ),.display_number (display_number),.input_valid (input_valid ),.input_value (input_value ),//lcd 触摸屏相关接口,不需要更改.lcd_rst (lcd_rst ),.lcd_cs (lcd_cs ),.lcd_rs (lcd_rs ),.lcd_wr (lcd_wr ),.lcd_rd (lcd_rd ),.lcd_data_io (lcd_data_io ),.lcd_bl_ctr (lcd_bl_ctr ),.ct_int (ct_int ),.ct_sda (ct_sda ),.ct_scl (ct_scl ),.ct_rstn (ct_rstn ));
//-----{实例化触摸屏}end
//-----{从触摸屏获取输入}begin
//根据实际需要输入的数修改此小节,
//建议对每一个数的输入,编写单独一个 always 块//当 input_sel 为 00 时,表示输入 opalways @(posedge clk)beginif (!resetn)beginop <= 4'd0;endelse if (input_valid && input_sel==2'b00)beginop <= input_value[5:0];endendalways @(posedge clk)beginif (!resetn)beginfunc <= 4'd0;endelse if (input_valid && input_sel==2'b01)beginfunc <= input_value[5:0];endendalways @(posedge clk)beginif (!resetn)beginz <= 4'd0;endelse if (input_valid && input_sel==2'b11)beginz <= input_value[0];endend//-----{此处省略,请自己编写}
//-----{从触摸屏获取输入}end
//-----{输出到触摸屏显示}begin
//根据需要显示的数修改此小节,
//触摸屏上共有 44 块显示区域,可显示 44 组 32 位数据
//44 块显示区域从 1 开始编号,编号为 1~44,always @(posedge clk)begincase(display_number)6'd1 :begindisplay_valid <= 1'b1;display_name <= "OP";display_value <= op;end6'd2 :begindisplay_valid <= 1'b1;display_name <= "FUNC";display_value <= func;end6'd3 :begindisplay_valid <= 1'b1;display_name <= "Z";display_value <= z;end6'd4 :begindisplay_valid <= 1'b1;display_name <= "STATE";display_value <= state;end6'd5 :begindisplay_valid <= 1'b1;display_name <= "WPC";display_value <= wpc;end6'd6 :begindisplay_valid <= 1'b1;display_name <= "WIR";display_value <= wir;end6'd7 :begindisplay_valid <= 1'b1;display_name <= "WMEM";display_value <= wmem;end6'd8 :begindisplay_valid <= 1'b1;display_name <= "WREG";display_value <= wreg;end6'd9 :begindisplay_valid <= 1'b1;display_name <= "IORG";display_value <= iord;end6'd10 :begindisplay_valid <= 1'b1;display_name <= "REGRT";display_value <= regrt;end6'd11 :begindisplay_valid <= 1'b1;display_name <= "M2REG";display_value <= m2reg;end6'd12 :begindisplay_valid <= 1'b1;display_name <= "ALUC";display_value <= aluc;end6'd13 :begindisplay_valid <= 1'b1;display_name <= "SHIFT";display_value <= shift;end6'd14 :begindisplay_valid <= 1'b1;display_name <= "ALUSRCA";display_value <= alusrca;end6'd15 :begindisplay_valid <= 1'b1;display_name <= "ALUSRVB";display_value <= alusrcb;end6'd16 :begindisplay_valid <= 1'b1;display_name <= "PCSOURCE";display_value <= pcsource;end6'd17 :begindisplay_valid <= 1'b1;display_name <= "JAL";display_value <= jal;end6'd18 :begindisplay_valid <= 1'b1;display_name <= "SEXT";display_value <= sext;
end//-----{此处省略,请自己编写}default :begindisplay_valid <= 1'b0;display_name <= 40'd0;display_value <= 32'd0;endendcaseend
//-----{输出到触摸屏显示}end
//----------------------{调用触摸屏模块}end---------------------//
endmodule
mccu.xdc:
#时钟信号连接
set_property PACKAGE_PIN AC19 [get_ports clk]
set_property IOSTANDARD LVCMOS33 [get_ports clk]#脉冲开关,用于输入作为复位信号,低电平有效
set_property PACKAGE_PIN Y3 [get_ports resetn]
set_property IOSTANDARD LVCMOS33 [get_ports resetn]#脉冲开关,用于输入作为单步执行的clk
set_property PACKAGE_PIN Y5 [get_ports btn_clk]
set_property IOSTANDARD LVCMOS33 [get_ports btn_clk]#拨码开关连接,用于输入
set_property PACKAGE_PIN AC21 [get_ports input_sel[1]]
set_property PACKAGE_PIN AD24 [get_ports input_sel[0]]
set_property IOSTANDARD LVCMOS33 [get_ports input_sel[1]]
set_property IOSTANDARD LVCMOS33 [get_ports input_sel[0]]#触摸屏引脚连接
set_property PACKAGE_PIN J25 [get_ports lcd_rst]
set_property PACKAGE_PIN H18 [get_ports lcd_cs]
set_property PACKAGE_PIN K16 [get_ports lcd_rs]
set_property PACKAGE_PIN L8 [get_ports lcd_wr]
set_property PACKAGE_PIN K8 [get_ports lcd_rd]
set_property PACKAGE_PIN J15 [get_ports lcd_bl_ctr]
set_property PACKAGE_PIN H9 [get_ports {lcd_data_io[0]}]
set_property PACKAGE_PIN K17 [get_ports {lcd_data_io[1]}]
set_property PACKAGE_PIN J20 [get_ports {lcd_data_io[2]}]
set_property PACKAGE_PIN M17 [get_ports {lcd_data_io[3]}]
set_property PACKAGE_PIN L17 [get_ports {lcd_data_io[4]}]
set_property PACKAGE_PIN L18 [get_ports {lcd_data_io[5]}]
set_property PACKAGE_PIN L15 [get_ports {lcd_data_io[6]}]
set_property PACKAGE_PIN M15 [get_ports {lcd_data_io[7]}]
set_property PACKAGE_PIN M16 [get_ports {lcd_data_io[8]}]
set_property PACKAGE_PIN L14 [get_ports {lcd_data_io[9]}]
set_property PACKAGE_PIN M14 [get_ports {lcd_data_io[10]}]
set_property PACKAGE_PIN F22 [get_ports {lcd_data_io[11]}]
set_property PACKAGE_PIN G22 [get_ports {lcd_data_io[12]}]
set_property PACKAGE_PIN G21 [get_ports {lcd_data_io[13]}]
set_property PACKAGE_PIN H24 [get_ports {lcd_data_io[14]}]
set_property PACKAGE_PIN J16 [get_ports {lcd_data_io[15]}]
set_property PACKAGE_PIN L19 [get_ports ct_int]
set_property PACKAGE_PIN J24 [get_ports ct_sda]
set_property PACKAGE_PIN H21 [get_ports ct_scl]
set_property PACKAGE_PIN G24 [get_ports ct_rstn]set_property IOSTANDARD LVCMOS33 [get_ports lcd_rst]
set_property IOSTANDARD LVCMOS33 [get_ports lcd_cs]
set_property IOSTANDARD LVCMOS33 [get_ports lcd_rs]
set_property IOSTANDARD LVCMOS33 [get_ports lcd_wr]
set_property IOSTANDARD LVCMOS33 [get_ports lcd_rd]
set_property IOSTANDARD LVCMOS33 [get_ports lcd_bl_ctr]
set_property IOSTANDARD LVCMOS33 [get_ports {lcd_data_io[0]}]
set_property IOSTANDARD LVCMOS33 [get_ports {lcd_data_io[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {lcd_data_io[2]}]
set_property IOSTANDARD LVCMOS33 [get_ports {lcd_data_io[3]}]
set_property IOSTANDARD LVCMOS33 [get_ports {lcd_data_io[4]}]
set_property IOSTANDARD LVCMOS33 [get_ports {lcd_data_io[5]}]
set_property IOSTANDARD LVCMOS33 [get_ports {lcd_data_io[6]}]
set_property IOSTANDARD LVCMOS33 [get_ports {lcd_data_io[7]}]
set_property IOSTANDARD LVCMOS33 [get_ports {lcd_data_io[8]}]
set_property IOSTANDARD LVCMOS33 [get_ports {lcd_data_io[9]}]
set_property IOSTANDARD LVCMOS33 [get_ports {lcd_data_io[10]}]
set_property IOSTANDARD LVCMOS33 [get_ports {lcd_data_io[11]}]
set_property IOSTANDARD LVCMOS33 [get_ports {lcd_data_io[12]}]
set_property IOSTANDARD LVCMOS33 [get_ports {lcd_data_io[13]}]
set_property IOSTANDARD LVCMOS33 [get_ports {lcd_data_io[14]}]
set_property IOSTANDARD LVCMOS33 [get_ports {lcd_data_io[15]}]
set_property IOSTANDARD LVCMOS33 [get_ports ct_int]
set_property IOSTANDARD LVCMOS33 [get_ports ct_sda]
set_property IOSTANDARD LVCMOS33 [get_ports ct_scl]
set_property IOSTANDARD LVCMOS33 [get_ports ct_rstn]
计算机组成原理实验报告 实验三:控制器实验(源码全)相关推荐
- 计算机组成实验微程序控制器实验,计算机组成原理实验报告3++微程序控制器实验.doc...
文档介绍: 计算机组成原理实验报告3微程序控制器实验计算机组成原理实验报告实验三微程序控制器实验一.实验目的与要求:实验目的:1.理解时序产生器的原理,了解时钟和时序信号的波形;2.掌握微程序控制器的 ...
- python实验报告及源代码-python满分实验报告:红心大战源代码源码程序
python满分实验报告:红心大战源代码/ python满分实验报告:红心大战源代码/python_红心大战游戏_满分原创作业/ python满分实验报告:红心大战源代码/python_红心大战游戏_ ...
- 跑马灯C语言实验报告,51单片机跑马灯实验报告 分析与小结,思考题源码下载
一.实验目的与要求 1.熟悉 Keil C51 集成环境软件的使用方法. 2.熟悉 MCS51 汇编指令,能自己编写简单的程序,控制硬件. 3.熟悉畅学开发平台,掌握单片机最小系统及 IO 口的简单控 ...
- Java语言 实验报告(三)
实验报告(三) 实验目的 熟悉 Java 综合应用程序的开发. 实验任务 编写一个 Java 应用程序,实现图形界面多人聊天室(多线程实现),要求聊天室窗口标题是"欢迎使用 XXX 聊天室应 ...
- 计算机组成原理微控制器实验报告,计算机组成原理实验报告_微控制器.doc
计算机组成原理实验报告_微控制器 计算机组成原理实验报告 题目: 微程序控制器实验 实验目的: (1) 理解时序产生器的原理,了解时钟和时序信号的波形. (2) 掌握微程序控制器的功能.组成知识. ( ...
- 计算机组成原理计数器实验报告,计算机组成原理4位二制计数器实验报告.doc
计算机组成原理4位二制计数器实验报告 计算机组成原理实验一 4位二进制计数器实验 姓名:李云弟 学号:1205110115 网工1201 [实验环境] 1. Windows 2000 或 Window ...
- 计算机组成原理第4位,计算机组成原理4位进制计数器实验报告.doc
计算机组成原理4位进制计数器实验报告 计算机组成原理实验一 4位二进制计数器实验 姓名:李云弟 学号:1座机电话号码5 网工1201 [实验环境] 1. Windows 2000 或 Windows ...
- 计算机组成原理实验报告西华大学,计算机组成原理实验报告算术逻辑运算单元实验...
<计算机组成原理实验报告算术逻辑运算单元实验>由会员分享,可在线阅读,更多相关<计算机组成原理实验报告算术逻辑运算单元实验(6页珍藏版)>请在人人文库网上搜索. 1.西华大学数 ...
- 计算机组成原理硬布线实验心得,计算机组成原理课程设计—硬布线控制器的设计与实现...
计算机组成原理课程设计-硬布线控制器的设计与实现 (13页) 本资源提供全文预览,点击全文预览即可全文预览,如果喜欢文档就下载吧,查找使用更方便哦! 19.90 积分 硬布硬布线线控制器的控制器的设计 ...
- 计算机微程序设计实验报告,模型机综合实验及微程序设计实验报告.docx
文档介绍: 模型机综合实验及微程序设计实验报告.docx成绩:实验报告课程名称:实践名称:姓名:专业:班级:学号:计算机组成原理模型机综合实验及微程序设计计算机科学与技术计算机科学与技术学院实验教学中 ...
最新文章
- arm指令中mov和ldr及ldr伪指令的区别
- 移动端web设计尺寸_移动端页面设计规范尺寸大起底
- java 两个字段排序,如何在Java中按两个字段排序?
- Redis radix tree源码解析
- 蓝桥杯 波动数列 01背包
- 高中计算机编程内容,高中信息技术课程标准
- python 移动文件语句_python移动文件
- 正版python软件多少钱-有奖|这 18 个好用的正版软件、热门的付费教程限时超低价了...
- SoundTouch音频处理库
- 通俗易懂专利分类、专利申请流程
- 蓝队-Windows操作系统
- Kodu吃苹果---Kodu少儿编程第六天
- 微信小程序身份证扫描OCR(信息自动带入)
- 新个人所得税EXCEL计算公式以及税后工资反算税前工资公式
- 俯仰角与横滚角的介绍
- 思考-ML如何产生效益,前景问题
- 原码,反码,补码,傻傻分不清?
- 拆开火火兔,搬起小板凳,听老梁分析最简单最节省成本的锂电池充电电路
- JTAG原理+JTAG烧写FPGA配置芯片
- 发那科机器人示教盒复位键是哪个_发那科示教器专业维修 二手FANUC示教器销售...
热门文章
- 2020.11.01 使用OpenCV进行图像形态学操作(开、闭、梯度)【OpenCV C++】
- SCAU10690 分面包
- pytorch训练的pt模型转换为onnx(nn.DataParallel()、model、model.state_dict())
- 游戏网站搭建实例:黑色沙漠中文wiki站搭建(1)
- Java调用Google Analytics API实现网站统计
- 星起航:抖音正在快速分割传统电商平台的市场份额
- XDOJ 378 正整数的最优分解
- 常用数学符号的 LaTeX 表示方法
- Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
- ENSP的AR40问题解决