Quartus Prime硬件实验开发(DE2-115板)实验一CPU指令运算器设计

实验一 CPU指令运算器设计

  • 实验目的
  1. 掌握QuartusII等实验工具的输入、综合、仿真、下载的使用方法
  2. 掌握DE2开发版的器件功能特性和使用方法
  3. 掌握Verilog HDL组合逻辑系统设计的主要方法和技术
  4. 掌握并应用设计的方法和流程
  • 预习要求
  1. 了解QuartusII等管教分配、下载的方法和流程
  2. 了解开发板输入、输出显示资源的工作特性
  3. 了解开发板设计、开发和测试的方法和流程
  • 实验要求

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

操作类型1

操作数1

操作类型2

操作数3

操作数4

完成的具体功能定义如下:

  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.先把板子插到电脑上(黑线电源,白线电脑)

2.在开始设置板子内,选择Cyclone IV E,随后下方电压选择1.2V(ce115f29系列的板子)的即可

3.完成板子的配置后,输入主文件代码:

module zhiling(key,x2,x3,Hex0,Hex1,Hex2,Hex3,Hex4,Hex5,Hex6,Hex7,x);
input [7:0] x2,x3;
input key;
reg[7:0] x1;
input [1:0] x;//表示七段管的显示模式
output reg[6:0] Hex0,Hex1,Hex2,Hex3,Hex4,Hex5,Hex6,Hex7;
reg[11:0] add;
reg[7:0] sub;
reg[13:0] mul;
wire[7:0] n3,n2;
integer flag;//符号标志位
//加法变量
reg cout1,cout2;
reg [6:0] fh;
reg [3:0] low,low0,mid,mid0;
reg [3:0] a1,a2,a3,a4;//乘法各位表达
reg [3:0] t1,t2,t3;//x1的值
reg [3:0] s1,s2;
assign n2=x2[7:4]*10+x2[3:0];
assign n3=x3[7:4]*10+x3[3:0];
always@(*)
begin
   if(key==1)
	begin
   x1=x2;	
   t1=x1%4'b1010;
	t2=x1/4'b1010%4'b1010;
	t3=x1/4'b1010/4'b1010;
	end
end
//加法,二级流水线方式
always@(*)
begin
{cout1,low0}=x2[3:0]+x3[3:0];
if(cout1==1) begin low=low0+4'b0110; end
else if(low0>9&&cout1==0) begin {cout1,low}=low0+4'b0110;end
else begin low=low0;cout1=0;end
end

always@(*)
begin
{cout2,mid0}=x2[7:4]+x3[7:4]+cout1;
if(cout2==1) begin mid=mid0+4'b0110; end
else if(mid0>9&&cout2==0) begin {cout2,mid}=mid0+4'b0110;end
else begin mid=mid0;cout2=0;end
add={cout2,mid,low};
end
//减法
always@(*)
begin
flag=0;
if(n2>=n3) sub=n2-n3;
else begin flag=1;sub=n3-n2;end
fh=(flag==1)?7'b0111111:7'b1111111;
   s1=sub%4'b1010;  
	s2=sub/4'b1010;
end
//乘法
always@(*)
begin
   mul=n2*n3;
   a1=mul%4'b1010;  
	a2=mul/4'b1010%4'b1010;
	a3=mul/4'b1010/4'b1010%4'b1010;
	a4=mul/4'b1010/4'b1010/4'b1010;
end

always@(x)
begin
case(x)
2'b00:begin {Hex2,Hex1,Hex0}={show(t3),show(t2),show(t1)};Hex3=7'b1111111;Hex4=7'b1111111;Hex5=7'b1111111;Hex6=7'b1111111;Hex7=7'b1111111;end
2'b01:begin {Hex7,Hex6}={show(x2[7:4]),show(x2[3:0])};{Hex5,Hex4}={show(x3[7:4]),show(x3[3:0])};
				{Hex2,Hex1,Hex0}={show(add[11:8]),show(add[7:4]),show(add[3:0])};Hex3=7'b1111111;  end
2'b10:begin {Hex7,Hex6}={show(x2[7:4]),show(x2[3:0])};{Hex5,Hex4}={show(x3[7:4]),show(x3[3:0])};
				{Hex2,Hex1,Hex0}={fh,show(s2),show(s1)};Hex3=7'b1111111;  end
2'b11:begin {Hex7,Hex6}={show(x2[7:4]),show(x2[3:0])};{Hex5,Hex4}={show(x3[7:4]),show(x3[3:0])};
				{Hex3,Hex2,Hex1,Hex0}={show(a4),show(a3),show(a2),show(a1)};  end
endcase
end

function [6:0]show;
   input[3:0] a0;
	reg[6:0] b;
	begin
	case(a0)
  4'd0:b=7'b1000000;
  4'd1:b=7'b1111001;
  4'd2:b=7'b0100100;
  4'd3:b=7'b0110000;
  4'd4:b=7'b0011001;
  4'd5:b=7'b0010010;
  4'd6:b=7'b0000010;
  4'd7:b=7'b1111000;  
  4'd8:b=7'b0000000;
  4'd9:b=7'b0011000; 
default:b=7'b1111111;
	endcase 
	show=b;
	end
	endfunction
endmodule

4.点击import assignment

5.导入管脚分配,实验一的数据集下载链接:

fpga硬件实验一CPU指令运算器设计管脚配置-数据集文档类资源-CSDN下载

6.随后打开 Pin Planner,查看管脚是否连接正常 

7.first模块定义的接口和管脚分配文件对应。导入管脚分配文件后,查看 pin planner 中管脚连接情况。如果出现空白行,说明管脚文件出错,需要修改,重新导入。(已测试过,若用上述链接导入管脚,可正常运行,这一步可省略

8.若修改管脚分配文件,需要将原来导入的管脚文件移除,remove assignments。重新打开 pin planer 会发现连接清楚,所有行都变为无色。(已测试过,若用上述链接导入管脚,可正常运行,这一步可省略

 9.正确导入管脚分配表,无错误后。重新综合整个工程

10.综合完毕,无错误后。连接好开发板,开启电源,准备下载。

在 programmer 窗口,可能如框中显示 no hardware,没有硬件。点击 hardware setup 功能。 弹出 hardware setup 窗口,添加硬件。

11.若没有USB驱动,则需要手动更新驱动

右击“我的电脑”图标,选择“管理”

12.选择“手动搜索”,进入Quartus prime安装目录文件,找到“USB”

13.两个“USB”任选一个即可(到时候在硬件115板的插口上选一个插就行)

14.安装完成后,即可

15. 完成驱动更新后,再次点击Programmer 窗口,点击 hardware setup 功能。 弹出 hardware setup 窗口,添加硬件

16.配置完成后直接点击Start即可

随后开始硬件测试,实验一是CPU指令运算器,加减乘的运算

乘法:

加法:

减法:

  • 16
    点赞
  • 45
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 8
    评论
// // Permission: // // Terasic grants permission to use and modify this code for use // in synthesis for all Terasic Development Boards and Altera Development // Kits made by Terasic. Other use of this code, including the selling // ,duplication, or modification of any portion is strictly prohibited. // // Disclaimer: // // This VHDL/Verilog or C/C++ source code is intended as a design reference // which illustrates how these types of functions can be implemented. // It is the user's responsibility to verify their design for // consistency and functionality through the use of formal // verification methods. Terasic provides no warranty regarding the use // or functionality of this code. // // -------------------------------------------------------------------- // // Terasic Technologies Inc // 356 Fu-Shin E. Rd Sec. 1. JhuBei City, // HsinChu County, Taiwan // 302 // // web: http://www.terasic.com/ // email: support@terasic.com // // -------------------------------------------------------------------- // // Major Functions: DE2_115_PS2 Mouse Controller // // -------------------------------------------------------------------- // // Revision History : // -------------------------------------------------------------------- // Ver :| Author :| Mod. Date :| Changes Made: // V1.0 :| Johnny FAN,HdHuang :| 05/16/10 :| Initial Revision // -------------------------------------------------------------------- module ps2( iSTART, //press the button for transmitting instrucions to device; iRST_n, //FSM reset signal; iCLK_50, //clock source; PS2_CLK, //ps2_clock signal inout; PS2_DAT, //ps2_data signal inout; oLEFBUT, //left button press display; oRIGBUT, //right button press display; oMIDBUT, //middle button press display; oX_MOV1, //lower SEG of mouse displacement display for X axis. oX_MOV2, //higher SEG of mouse displacement display for X axis. oY_MOV1, //lower SEG of mouse displacement display for Y axis. oY_MOV2 //higher SEG of mouse displacement display for Y axis. ); //interface; //======================================================= // PORT declarations //======================================================= input iSTART; input iRST_n; input iCLK_50; inout PS2_CLK; inout PS2_DAT; output oLEFBUT; output oRIGBUT; output oMIDBUT; output [6:0] oX_MOV1; output [6:0] oX_MOV2; output [6:0] oY_MOV1; output [6:0] oY_MOV2; //instantiation SEG7_LUT U1(.oSEG(oX_MOV1),.iDIG(x_latch[3:0])); SEG7_LUT U2(.oSEG(oX_MOV2),.iDIG(x_latch[7:4])); SEG7_LUT U3(.oSEG(oY_MOV1),.iDIG(y_latch[3:0])); SEG7_LUT U4(.oSEG(oY_MOV2),.iDIG(y_latch[7:4])); //instruction define, users can charge the instruction byte here for other purpose according to ps/2 mouse datasheet. //the MSB is of parity check bit, that's when there are odd number of 1's with data bits, it's value is '0',otherwise it's '1' instead. parameter enable_byte =9'b011110100; //======================================================= // REG/WIRE declarations //======================================================= reg [1:0] cur_state,nex_state; reg ce,de; reg [3:0] byte_cnt,delay; reg [5:0] ct; reg [7:0] x_latch,y_latch,cnt; reg [8:0] clk_div; reg [9:0] dout_reg; reg [32:0] shift_reg; reg leflatch,riglatch,midlatch; reg ps2_clk_in,ps2_clk_syn1,ps2_dat_in,ps2_dat_syn1; wire clk,ps2_dat_syn0,ps2_clk_syn0,ps2_dat_out,ps2_clk_out,flag; //======================================================= // PARAMETER declarations //======================================================= //state define parameter listen =2'b00, pullclk=2'b01, pulldat=2'b10, trans =2'b11; //======================================================= // Structural coding //======================================================= //clk division, derive a 97.65625KHz clock from the 50MHz source; always@(posedge iCLK_50) begin clk_div <= clk_div+1; end assign clk = clk_div[8]; //tristate output control for PS2_DAT and PS2_CLK; assign PS2_CLK = ce?ps2_clk_out:1'bZ; assign PS2_DAT = de?ps2_dat_out:1'bZ; assign ps2_clk_out = 1'b0; assign ps2_dat_out = dout_reg[0]; assign ps2_clk_syn0 = ce?1'b1:PS2_CLK; assign ps2_dat_syn0 = de?1'b1:PS2_DAT; // assign oLEFBUT = leflatch; assign oRIGBUT = riglatch; assign oMIDBUT = midlatch; //multi-clock region simple synchronization always@(posedge clk) begin ps2_clk_syn1 <= ps2_clk_syn0; ps2_clk_in <= ps2_clk_syn1; ps2_dat_syn1 <= ps2_dat_syn0; ps2_dat_in <= ps2_dat_syn1; end //FSM shift always@(*) begin case(cur_state) listen :begin if ((!iSTART) && (cnt == 8'b11111111)) nex_state = pullclk; else nex_state = listen; ce = 1'b0; de = 1'b0; end pullclk :begin if (delay == 4'b1100) nex_state = pulldat; else nex_state = pullclk; ce = 1'b1; de = 1'b0; end pulldat :begin nex_state = trans; ce = 1'b1; de = 1'b1; end trans :begin if (byte_cnt == 4'b1010) nex_state = listen; else nex_state = trans; ce = 1'b0; de = 1'b1; end default : nex_state = listen; endcase end //idle counter always@(posedge clk) begin if ({ps2_clk_in,ps2_dat_in} == 2'b11) begin cnt <= cnt+1; end else begin cnt <= 8'd0; end end //periodically reset ct; ct counts the received data length; assign flag = (cnt == 8'hff)?1:0; always@(posedge ps2_clk_in,posedge flag) begin if (flag) ct <= 6'b000000; else ct <= ct+1; end //latch data from shift_reg;outputs is of 2's complement; //Please treat the cnt value here with caution, otherwise wrong data will be latched. always@(posedge clk,negedge iRST_n) begin if (!iRST_n) begin leflatch <= 1'b0; riglatch <= 1'b0; midlatch <= 1'b0; x_latch <= 8'd0; y_latch <= 8'd0; end else if (cnt == 8'b00011110 && (ct[5] == 1'b1 || ct[4] == 1'b1)) begin leflatch <= shift_reg[1]; riglatch <= shift_reg[2]; midlatch <= shift_reg[3]; x_latch <= x_latch+shift_reg[19 : 12]; y_latch <= y_latch+shift_reg[30 : 23]; end end //pull ps2_clk low for 100us before transmit starts; always@(posedge clk) begin if (cur_state == pullclk) delay <= delay+1; else delay <= 4'b0000; end //transmit data to ps2 device;eg. 0xF4 always@(negedge ps2_clk_in) begin if (cur_state == trans) dout_reg <= {1'b0,dout_reg[9:1]}; else dout_reg <= {enable_byte,1'b0}; end //transmit byte length counter always@(negedge ps2_clk_in) begin if (cur_state == trans) byte_cnt <= byte_cnt+1; else byte_cnt <= 4'b0000; end //receive data from ps2 device; always@(negedge ps2_clk_in) begin if (cur_state == listen) shift_reg <= {ps2_dat_in,shift_reg[32:1]}; end //FSM movement always@(posedge clk,negedge iRST_n) begin if (!iRST_n) cur_state <= listen; else cur_state <= nex_state; end endmodule
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

华东设计之美

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值