实验一:CPU指令运算器设计 实验报告

实验一:CPU指令运算器设计


一、实验目的

(1) 掌握QuartusII等实验工具的输入、综合、仿真、下载的使用方法
(2) 掌握DE2开发版的器件功能特性和使用方法
(3) 掌握Verilog HDL组合逻辑系统设计的主要方法和技术
(4) 掌握并应用设计的方法和流程

二、预习要求

(1) 了解QuartusII等管教分配、下载的方法和流程
(2) 了解开发板输入、输出显示资源的工作特性
(3) 了解开发板设计、开发和测试的方法和流程


三、实验要求

设计一个简单的CPU指令运算器,指令格式如下。

操作类型1操作数据(16位)
操作类型2操作数据1(8位)操作数据2(8位)

完成的具体功能定义如下:
(1) 操作类型1:将操作数1作为一个无符号二进制数,在七段管以十进制显示二进制序列等效值。
(2) 操作类型2:实现操作数3、操作数4之间相加、减、乘的操作,在七段管以十/十六进制进制显示操作数和结果。操作数3和4为BCD码表示的2位十进制数(表示的值为00-99)。
注意:
(1) 操作类型2中,减法逻辑中出现负数,则显示“-”,正数可以不显示符号
(2) 操作类型2中,加、减、乘操作数和结果都用十进制显示,可以在七段管上进行循环显示来实现。
(3) 注意操作数3、4以BCD码输入,超过9的BCD码输出处理问题。
(4) 尝试加法运算采用流水线方式实现。注意有效位数。
(5) 如果感觉七段管显示能力弱,可以查询LCD1602的控制模块代码,采用LCD显示。

四、实验分析和设计

1、 功能定义
 (1) 设计完成了16位显示,实现加减乘的功能。
 (2) 越界采用报错的新式完成,以”_”指出错误位,同时亮起指示灯。

五、综合代码

主模块 Calculator

module Calculator(a1,a2,b1,b2,calc,sw0,hex0,hex1,hex2,hex3,hex4,hex5,hex6,hex7,err);
	input[3:0] a1,a2,b1,b2;    // 两个操作数 (a1*10 + a2) 和(b1*10 + b2) 
	input[1:0] sw0;            // 表示运算符号位
	input calc;                // 计算指令,相当于计算器上的=号
		   
	output [6:0] hex0, hex1;   // 显示第一个操作数
	output [6:0] hex2, hex3;   // 显示第二个操作数
	output [6:0] hex4, hex5;   // 用于结果显示
	output [6:0] hex6, hex7;   // 用于结果显示
	output err;                // 错误输入标志位
	 
	reg minus;                 // 结果是否负数表示
	reg[15:0] ans;             // 存储运算结果
	
	/** 用于将10进制数转化成七段管可以显示的数 */
	function[6:0] show;
		input [4:0] in5;
		case(in5)
			5'h0: show = 7'b1000000; // 0
			5'h1: show = 7'b1111001; // 1
			5'h2: show = 7'b0100100; // 2
			5'h3: show = 7'b0110000; // 3
			5'h4: show = 7'b0011001; // 4
			5'h5: show = 7'b0010010; // 5
			5'h6: show = 7'b0000010; // 6
			5'h7: show = 7'b1111000; // 7
			5'h8: show = 7'b0000000; // 8
			5'h9: show = 7'b0010000; // 9
			5'hA: show = 7'b0111111; // -
			5'hB: show = 7'b1111111; // 空
			default:show=7'b1110111; // 下滑
		endcase
	endfunction
	
	
	// 点击运算时发生的逻辑 ...下降沿触发
	always @(negedge calc) begin
		minus <= 1'b0;
		case (sw0)
			2'b00: begin // 显示数
				ans<={a1,a2,b1,b2};
			end
			
			2'b01: begin // +
				ans<=(a1*10+a2)+(b1*10+b2);
			end
			
			2'b10: begin // -
				if((a1*10+a2)>=(b1*10+b2)) begin
					ans<=(a1*10+a2)-(b1*10+b2);
				end
				else begin 
					minus <= 1'b1;
					ans<=(b1*10+b2)-(a1*10+a2);
				end
			end
			
			2'b11: begin // *
				ans<=(a1*10+a2)*(b1*10+b2);
			end
		endcase
	end
	
	// 错误标志位
	assign err = (a1>9 || a2>9 || b1>9 || b2>9) ? 1'b0: 1'b1;
	assign hex7 = show((sw0==2'b00)?5'hB:(a1>9?5'hC:a1));
	assign hex6 = show((sw0==2'b00)?5'hB:(a2>9?5'hC:a2));
	assign hex5 = show((sw0==2'b00)?5'hB:(b1>9?5'hC:b1));
	assign hex4 = show((sw0==2'b00)?(ans/10000):(b2>9?5'hC:b2));
	assign hex3 = show(minus ? 5'hA : (ans<1000? 5'hB: ans/1000 %10));
	assign hex2 = show((ans<100)?5'hB:ans/100 %10);
	assign hex1 = show((ans<10)?5'hB:ans/10 %10);
	assign hex0 = show(ans%10);

endmodule

六、测试代码

`timescale 1 ps/ 1 ps
module Ex1_vlg_tst();
reg [3:0] a1,a2,b1,b2;
reg calc;
reg [1:0] sw0;                                        
wire err;
wire [6:0] hex0,hex1,hex2,hex3;
wire [6:0] hex4,hex5,hex6,hex7;
                       
Calculator i1 ( 
	.a1(a1), .a2(a2), .b1(b1), .b2(b2),
	.calc(calc), .err(err),
	.hex0(hex0), .hex1(hex1), .hex2(hex2), .hex3(hex3),
	.hex4(hex4), .hex5(hex5), .hex6(hex6), .hex7(hex7),
	.sw0(sw0)
);

initial
begin
	// 初始化 
	calc = 1;
	// 显示内容
	a1 = 4'b1111; a2 = 4'b1111; b1 = 4'b1111; b2 = 4'b1111; sw0 = 0;
	#1 calc = 0;  #1 calc = 1;  # 100;
	// 内容
	a1 = 2; a2 = 0; b1 = 4; b2 = 0; sw0 = 1;
	#1 calc = 0;  #1 calc = 1; # 100;
	// 显示内容
	a1 = 2; a2 = 0; b1 = 4; b2 = 0; sw0 = 2;
	#1 calc = 0;  #1 calc = 1; # 100;
	// 显示内容
	a1 = 3; a2 = 0; b1 = 4; b2 = 0; sw0 = 3;
	#1 calc = 0;  #1 calc = 1; # 100;
end

function[7:0] tube2int;
		input [6:0] in5;
		case(in5)
			7'b1000000: tube2int = "0"; // 0
			7'b1111001: tube2int = "1"; // 1
			7'b0100100: tube2int = "2"; // 2
			7'b0110000: tube2int = "3"; // 3
			7'b0011001: tube2int = "4"; // 4
			7'b0010010: tube2int = "5"; // 5
			7'b0000010: tube2int = "6"; // 6
			7'b1111000: tube2int = "7"; // 7
			7'b0000000: tube2int = "8"; // 8
			7'b0010000: tube2int = "9"; // 9
			7'b0111111: tube2int = "-"; // -
			7'b1111111: tube2int = " "; // 空
			default:tube2int="_"; // 下滑
		endcase
	endfunction

always @(posedge calc) begin
	$display("%c%c  %c%c  %c%c%c%c",
	tube2int(hex7),
	tube2int(hex6),
	tube2int(hex5),
	tube2int(hex4),
	tube2int(hex3),
	tube2int(hex2),
	tube2int(hex1),
	tube2int(hex0)
	);
end
endmodule

七、仿真和测试效果

仿真波形图片
在这里插入图片描述
计算模块
在这里插入图片描述
真机运行效果

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

八、实验遇到的问题

1、 管脚对应问题:
这是第一次给板子下载程序,在很多地方还比较陌生,在管脚绑定时发生了将高低位绑定反了结果。
解决:认真观察原始表中变量的高低位,对应自己的变量和其变量高低位相同即可。

2、 使用自己电脑无法下载程序:
出现这一问题的原因时缺少驱动程序。只需要将eda 软件安装目录下的驱动安装一下,就可以下载了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值