四位全加器的FPGA实现

前言

这是本人的第一篇博客。这几天翻开曾经大二下学期买的夏雨闻的书,里面有很简单的全加器代码,正好这几天在摸索FPGA,于是有了将全加器移植到FPGA的想法。

环境

1.软件:xilinx vivado(2018.3)
2.FPGA:ZYBO Z7

实现过程

顶层模块连接如下,各个模块均为同步时钟时序电路。

包含了加法器、数据输入、数据显示三个模块。
数据输入模块:在FPGA上通过拨码开关,提供四位高低电平数据。通过按钮,来选择是哪个变量接收输入数据。
数据显示模块:通过LED灯来显示输入数据、求和结果以及进位输出,显示哪种由按钮来决定。

代码

1.四位全加器模块

module adder(
			input clk,
			input rst, //复位使能,高电平有效
			input [3:0] a,
			input [3:0] b,
			output reg[3:0] sum, //求和结果
			output reg carry_out //进位输出
			);
	
	always @(posedge clk or posedge rst)begin
		if( rst)
			begin
				sum <= 0;
				carry_out <= 0;
			end
		else
			begin
				{carry_out,sum} = a+b;
			end
	end
	
endmodule

2.数据输入模块

module data_in(
				input clk,
				input rst,
				input bottom1, 
				input bottom2,
				input [3:0] data, //输入数据,通过开关给入
				output reg[3:0] a=0,
				output reg[3:0] b=0
			);
			
	always @(posedge clk or posedge rst)begin
		if(rst)
			begin
				a <= 0;
				b <= 0;
			end
		else
			begin
				if(bottom1) //bottom1按下时,a接收输入数据
					begin
						a <= data;
					end
				else if(bottom2) //bottom2按下时,b接收输入数据
					begin
						b <= data;
					end
			end
	end
	
endmodule

3.数据显示模块

module display_out(
					input clk,
					input rst,
					input bottom1,
					input bottom2,
					input bottom3,
					input [3:0] data,
					input carry_out,
					input [3:0] result,
					output reg [3:0] display_result,
					output reg display_carry_out
				);
				
	always @(posedge clk or posedge rst)begin
		if(rst)
			begin
				display_result <= 0;
				display_carry_out <= 0;
			end
		else
			begin
				if(bottom3) //bottom3按下时,显示求和结果以及进位输出
					begin
						display_result <= result;
						display_carry_out <= carry_out;
					end
				else if(bottom1) //bottom1按下时,显示输入数据
					begin
						display_result <= data;
						display_carry_out <= 0;
					end
				else if(bottom2)//bottom2按下时,显示输入数据
					begin
						display_result <= data;
						display_carry_out <= 0;
					end
			end
	end
	
endmodule

			
					
					

4.顶层连接

module top(
			input wire clk,
			input wire rst,
			input wire bottom1,
			input wire bottom2,
			input wire bottom3,
			input wire [3:0] data,
			output wire [3:0] display_result,
			output wire display_carry_out
			);
	
	wire [3:0] a;
	wire [3:0] b;
	wire [3:0] result;
	wire carry_out;
	
	data_in data_in(
					.clk(clk),
					.rst(rst),
					.bottom1(bottom1),
					.bottom2(bottom2),
					.data(data),
					.a(a),
					.b(b)
					);
					
	adder adder(
				.clk(clk),
				.rst(rst),
				.a(a),
				.b(b),
				.sum(result),
				.carry_out(carry_out)
				);
	
	display_out display_out(
							.clk(clk),
							.rst(rst),
							.bottom1(bottom1),
							.bottom2(bottom2),
							.bottom3(bottom3),
							.data(data),
							.carry_out(carry_out),
							.result(result),
							.display_result(display_result),
							.display_carry_out(display_carry_out)
							);

endmodule

5.约束文件

##Clock signal
set_property -dict { PACKAGE_PIN K17   IOSTANDARD LVCMOS33 } [get_ports { clk }]; #IO_L12P_T1_MRCC_35 Sch=sysclk
create_clock -add -name sys_clk_pin -period 8.00 -waveform {0 4} [get_ports { clk }];


##Switches
set_property -dict { PACKAGE_PIN G15   IOSTANDARD LVCMOS33 } [get_ports { data[0] }]; #IO_L19N_T3_VREF_35 Sch=sw[0]
set_property -dict { PACKAGE_PIN P15   IOSTANDARD LVCMOS33 } [get_ports { data[1] }]; #IO_L24P_T3_34 Sch=sw[1]
set_property -dict { PACKAGE_PIN W13   IOSTANDARD LVCMOS33 } [get_ports { data[2] }]; #IO_L4N_T0_34 Sch=sw[2]
set_property -dict { PACKAGE_PIN T16   IOSTANDARD LVCMOS33 } [get_ports { data[3] }]; #IO_L9P_T1_DQS_34 Sch=sw[3]


##Buttons
set_property -dict { PACKAGE_PIN K18   IOSTANDARD LVCMOS33 } [get_ports { rst }]; #IO_L12N_T1_MRCC_35 Sch=btn[0]
set_property -dict { PACKAGE_PIN P16   IOSTANDARD LVCMOS33 } [get_ports { bottom1 }]; #IO_L24N_T3_34 Sch=btn[1]
set_property -dict { PACKAGE_PIN K19   IOSTANDARD LVCMOS33 } [get_ports { bottom2 }]; #IO_L10P_T1_AD11P_35 Sch=btn[2]
set_property -dict { PACKAGE_PIN Y16   IOSTANDARD LVCMOS33 } [get_ports { bottom3 }]; #IO_L7P_T1_34 Sch=btn[3]


##LEDs
set_property -dict { PACKAGE_PIN M14   IOSTANDARD LVCMOS33 } [get_ports { display_result[0] }]; #IO_L23P_T3_35 Sch=led[0]
set_property -dict { PACKAGE_PIN M15   IOSTANDARD LVCMOS33 } [get_ports { display_result[1] }]; #IO_L23N_T3_35 Sch=led[1]
set_property -dict { PACKAGE_PIN G14   IOSTANDARD LVCMOS33 } [get_ports { display_result[2] }]; #IO_0_35 Sch=led[2]
set_property -dict { PACKAGE_PIN D18   IOSTANDARD LVCMOS33 } [get_ports { display_result[3] }]; #IO_L3N_T0_DQS_AD1N_35 Sch=led[3]


##RGB LED 5 
set_property -dict { PACKAGE_PIN Y11   IOSTANDARD LVCMOS33 } [get_ports { display_carry_out }]; #IO_L18N_T2_13 Sch=led5_r

仿真

testbench文件如下

module top_tb();
		reg clk,rst;
		reg bottom1,bottom2,bottom3;
		reg [3:0] data;
		wire [3:0] display_result;
		wire display_carry_out;
		
		initial begin
			clk <= 0;
			rst <= 1;
			bottom1 <= 0;
			bottom2 <= 0;
			bottom3 <= 0;
			data <= 0;
			
			#5 rst <= 0;
			
			#15;
			bottom1 <= 1;
			data <= 4'b0010;
			
			#15;
			bottom1 <= 0;
			bottom2 <= 1;
			data <= 4'b0110;
			
			#15;
			bottom2 <= 0;
			bottom3 <= 1;
			
			#15;
			bottom3 <= 0;
			bottom1 <= 1;
			data <= 4'b1010;
			
			#15;
			bottom1 <= 0;
			bottom2 <= 1;
			data <= 4'b0110;
			
			#15;
			bottom2 <= 0;
			bottom3 <= 1;
		end
		
		always #5 clk <= ~clk;
		
		top top(
				.clk(clk),
				.rst(rst),
				.bottom1(bottom1),
				.bottom2(bottom2),
				.bottom3(bottom3),
				.data(data),
				.display_result(display_result),
				.display_carry_out(display_carry_out)
				);

endmodule
		
		
		

仿真波形

在这里插入图片描述
可以看到输入数据为 4’h2与4’h6时,display_result = 4’h8 ,display_carry_out = 0; 输入数据为4’ha 与4’h6时,display_result = 4’h0,display_carry_out = 0;

结果

生成比特流文件,并将其下载进开发板。
1.输入数据4’b1000
左下角四个LED灯从右往左为二进制位数的高至低
在这里插入图片描述
2.输入数据4’b1001
在这里插入图片描述
3.输出结果显示
在这里插入图片描述
求和部分为4‘b0001。进位输出为1,用红灯表示。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值