【FPGA实验1】FPGA点灯工程师养成记

这篇具有很好参考价值的文章主要介绍了【FPGA实验1】FPGA点灯工程师养成记。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

对于FPGA几个与LED相关的实验(包括按键点灯、流水灯、呼吸灯等)的记录,方便日后查看。这世界上就又多了一个FPGA点灯工程师了😏

一、按键点灯

按键点灯程序比较简单,就不搞仿真了,直接上机

1、按键点灯程序
module led(input wire key_1,
		output reg led_1);
						
 always@*
  led_1=!key_1;
 

endmodule

由程序得到的RTL图:

【FPGA实验1】FPGA点灯工程师养成记

2、硬件实现

(1)引脚分配与接线
引脚分配如下,记得引脚分配后再编译一次,不然可能没有现象。

【FPGA实验1】FPGA点灯工程师养成记

上述引脚分配对应的接线:JX22连接到JP5,JX5连接到JP1。
为什么要这样接线可以参考《【FPGA实验2】二进制转为格雷码》中的【三、实验箱实验】➡️【3、引脚分配】。

【FPGA实验1】FPGA点灯工程师养成记

(2)实验现象

具体的实验现象可观看下方的视频😏

二、流水灯

学了点状态机的内容,决定用状态机来写一下这个流水灯的代码。
感谢正点原子的视频,用了一个很好理解的例子讲了状态机是怎么样的一个东西,并总结了写状态机主要有四个步骤(也称四段论):
(1)状态空间定义(定义各个状态)
(2)状态跳转(告诉FPGA:你要跳转。让FPGA知道在什么条件下,你要从现在状态跳转到下一个状态)
(3)下个状态的判断(告诉FPGA:你要怎么跳。给FPGA一个地图,判断现在的情况是什么,然后根据地图确定下一个要跳转的状态)
(4)各个状态下的动作(我理解为状态对应信息的输出)

1、流水灯程序
module WaterLED(input wire clk,
				input wire rst_n,
				output wire [7:0]led_data);
		
		//空间状态定义
		parameter S1=8'b10000000;
		parameter S2=8'b01000000;
		parameter S3=8'b00100000;
		parameter S4=8'b00010000;
		parameter S5=8'b00001000;
		parameter S6=8'b00000100;
		parameter S7=8'b00000010;
		parameter S8=8'b00000001;
		
		reg [7:0]current_state;
		reg[7:0]next_state;
		
		//状态跳转
		always @(posedge clk or negedge rst_n) begin
			if(! rst_n)   current_state<=S1;  //复位,从状态S1开始
			else current_state<=next_state; //不是复位的情况下,到达时钟的上升沿就转到下一个状态
		end
		
		//状态判断
		always @(current_state) begin
			case(current_state) 
				S1:next_state=S2;
				S2:next_state=S3;
				S3:next_state=S4;
				S4:next_state=S5;
				S5:next_state=S6;
				S6:next_state=S7;
				S7:next_state=S8;
				default:next_state=S1;
			endcase
		end
		
	//各个状态下的动作
	assign led_data=current_state;
	
endmodule

得到的RTL图如下:
【FPGA实验1】FPGA点灯工程师养成记

2、仿真

流水灯的仿真程序如下:

`timescale 1ns/100ps
module tb_WaterLED;
	reg clk_1;
	reg rst_n_1;
	wire [7:0] led_data_1;
	parameter PERIOD=10;
	
	always #(PERIOD/2) clk_1=~clk_1;

	initial begin
		clk_1=0;
		#200  $stop;
	end
	
	task task_rst;
		begin 
		rst_n_1=0;
		repeat(2) @(negedge clk_1);//两个时钟负跳变之后
		rst_n_1=1;
		end
	endtask

	WaterLED WD_1(.clk(clk_1),.rst_n(rst_n_1),.led_data(led_data_1));
	
	initial begin
	task_rst;
	$display("task_rst ok!!!");
	end
	
	
	endmodule

【如何将仿真程序加入到工程中以及如何仿真可以看上一篇《【FPGA实验0】Quartus建立工程文件以及仿真》)】

仿真结果如下:
在两个时钟下降沿之后,复位线RST置高;之后随着每一个时钟上升沿的到来,开始状态的转换。

【FPGA实验1】FPGA点灯工程师养成记

3、硬件实现

在实际的硬件实现中,需要注意两个点:

(1)时钟信号
在仿真中,两个状态之间的切换是在时钟信号的上升沿,因而,每个状态保持的时间是一个时钟信号周期(在上的仿真中,一个时钟信号的周期是10ns)。而如果在实际中要实现流水灯的效果,这样的间隔太小了,由于眼睛的暂存作用,我们看懂的现象是8个LED灯一直在同时亮着,没有流水灯的效果,因而我们必须将时钟周期改得大一点。
【FPGA实验1】FPGA点灯工程师养成记

选择实验箱最大时钟12MHz(接线的话将左侧12M对应的时钟和右侧的任意一个引脚接起来即可),定义一个计数器,计数2400000个时钟周期,一个时钟频率为12MHz,一个时钟周期为83.33ns,2400000个时钟周期就是0.2秒。

	reg [23:0] counter;	
		
	//计数器对系统时钟计数,计时0.2秒
	always @(posedge clk or negedge rst_n) begin
	 if (!rst_n)
		  counter <= 24'd0;
	 else if (counter < 24'd2400_000)  //仿真的时候可以改为 24'd0000_0010,下同
		  counter <= counter + 1'b1;
	 else
		  counter <= 24'd0;
	end

同时,状态跳变部分增加一个条件,修改为:

//状态跳转
always @(posedge clk or negedge rst_n) begin
	if(! rst_n)   current_state<=S1;  //复位,从状态S1开始
	else if (counter==24'd2400_000) current_state<=next_state; //不是复位的情况下,到达时钟的上升沿就转到下一个状态
	else   ;
end

(2)复位键如何使用

复位键一开始需要置1(打到开的位置);
之后置0(下降沿产生出发条件;同时!rst=0,状态为初始状态S1);
完成复位后置1(使此刻的状态在触发之后能跳转到下一个状态)。

整个硬件实现的程序:

module WaterLED(input wire clk,
												input wire rst_n,
												output wire [7:0]led_data);
			
		
		//空间状态定义
		parameter S1=8'b10000000;
		parameter S2=8'b01000000;
		parameter S3=8'b00100000;
		parameter S4=8'b00010000;
		parameter S5=8'b00001000;
		parameter S6=8'b00000100;
		parameter S7=8'b00000010;
		parameter S8=8'b00000001;

		
		reg [7:0]current_state;
		reg[7:0]next_state;
		reg [23:0] counter;
		
	//计数器对系统时钟计数,计时0.2秒
		always @(posedge clk or negedge rst_n) begin
		 if (!rst_n)
			  counter <= 24'd0;
		 else if (counter < 24'd2400_000)  //仿真的时候可以改为 24'd0000_0010,下同
			  counter <= counter + 1'b1;
		 else
			  counter <= 24'd0;
		end
		
		//状态跳转
		always @(posedge clk or negedge rst_n) begin
			if(! rst_n)   current_state<=S1;  //复位,从状态S1开始
			else if (counter==24'd2400_000) current_state<=next_state; //不是复位的情况下,到达时钟的上升沿就转到下一个状态
			else   ;
		end
		
		//状态判断
		always @(current_state) begin
			case(current_state) 
				S1:next_state=S2;
				S2:next_state=S3;
				S3:next_state=S4;
				S4:next_state=S5;
				S5:next_state=S6;
				S6:next_state=S7;
				S7:next_state=S8;
				default:next_state=S1;
			endcase
		end
		
		//各个状态下的动作
	assign led_data=~current_state;//灯为0时亮起,为1时变暗
	
	
endmodule

对应的RTL图:
【FPGA实验1】FPGA点灯工程师养成记

引脚分配与接线:
【FPGA实验1】FPGA点灯工程师养成记

按之前的接线即可,key8为复位键。

上述引脚分配对应的接线:JX22连接到JP5,JX5连接到JP1。
为什么要这样接线可以参考《【FPGA实验2】二进制转为格雷码》中的【三、实验箱实验】➡️【3、引脚分配】。

时钟引脚:左侧的12M时钟引脚接到右侧任意一个引脚即可。总的接线图如下:

【FPGA实验1】FPGA点灯工程师养成记

具体现象可以看文末的视频😏

三、呼吸灯

呼吸灯,就是灯的亮度由暗变亮再由亮变暗,像人的呼吸一样。

1、先“吸”

(1)代码

module PWM(           
			input wire clk,
			output wire[9:0] pwma,
			output wire pwmb);

	reg [3:0]counter1=0,counter2=0;
	reg [9:0]pwm_1=10'b0000_0000_00;
	reg[0:0] pwm_2;
	
	always@(posedge clk) begin

			if(counter2==4'd9)  begin
			
					if(counter1==4'd9)  begin
						counter1=0;
						pwm_1=10'b0000_0000_00;					
						end
					else  counter1=counter1+1;							
					pwm_1[counter1]=1;
					counter2=0;
				end
				
			else counter2=counter2+1;
			pwm_2=pwm_1[counter2];
	end
	
	assign pwma=pwm_1;
	assign pwmb=pwm_2;
		
endmodule

(2)仿真文件:

`timescale 1ns/100ps
module tb_PWM;
	
	reg clk;
	wire [9:0]pwma;
	wire [0:0]pwmb;
	parameter PERIOD=10;
	
	always #(PERIOD/2) clk=~clk;
	
	initial begin
		clk=0;
		# 3000 $stop;
		end
		
PWM PWM_1(.clk(clk),.pwma(pwma), .pwmb(pwmb));

endmodule

(3)仿真结果:
【FPGA实验1】FPGA点灯工程师养成记

2、再“呼吸”

(1)代码

module PWM(
						input wire clk,
						output wire[9:0] pwma,
						output wire pwmb);

	reg [4:0]counter1=0;
	reg [3:0]counter2=0;
	reg [9:0]pwm_1=10'b0000_0000_00;
	reg[0:0] pwm_2;
	
	always@(posedge clk) begin

			if(counter2==4'd9)  begin
		
					if(counter1==5'd17)   counter1=0;
					else  counter1=counter1+1;	
					$display("counter1:   ",counter1);
					
					case(counter1)
						5'd0  : pwm_1=10'b0000_0000_01;
						5'd1  : pwm_1=10'b0000_0000_11;
						5'd2  : pwm_1=10'b0000_0001_11;
						5'd3  : pwm_1=10'b0000_0011_11;
						5'd4  : pwm_1=10'b0000_0111_11;
						5'd5  : pwm_1=10'b0000_1111_11;
						5'd6  : pwm_1=10'b0001_1111_11;
						5'd7  : pwm_1=10'b0011_1111_11;
						5'd8  : pwm_1=10'b0111_1111_11;
						5'd9  : pwm_1=10'b1111_1111_11;
						5'd10  : pwm_1=10'b0111_1111_11;
						5'd11  : pwm_1=10'b0011_1111_11;
						5'd12  : pwm_1=10'b0001_1111_11;
						5'd13  : pwm_1=10'b0000_1111_11;
						5'd14  : pwm_1=10'b0000_0111_11;
						5'd15  : pwm_1=10'b0000_0011_11;
						5'd16  : pwm_1=10'b0000_0001_11;
						5'd17  : pwm_1=10'b0000_0000_11;
					endcase
					$display("pwm_1:  ",pwm_1);
					counter2=0;
				end
				
			else counter2=counter2+1;
			pwm_2=pwm_1[counter2];
	end
	
	assign pwma=pwm_1;
	assign pwmb=pwm_2;
		
endmodule

(2)tb文件:

`timescale 1ns/100ps
module tb_PWM;
	
	reg clk;
	wire [9:0]pwma;
	wire [0:0]pwmb;
	parameter PERIOD=10;
	
	always #(PERIOD/2) clk=~clk;
	
	initial begin
		clk=0;
		# 3000 $stop;
		end
		
PWM PWM_1(.clk(clk),.pwma(pwma), .pwmb(pwmb));


endmodule

(3)仿真结果:

【FPGA实验1】FPGA点灯工程师养成记

3、最后大口地呼吸

呼吸灯的硬件实现,和流水灯的硬件实现一样原理,如果每个亮度的时间跟仿真的时候一样的话,那我们是看不出亮度变化,所以在硬件实现的时候需要在每一个亮度延长一定的时间。具体的实现如下:

(1)代码:

module PWM(
						input wire clk,
						output wire led0,
						output wire led1,
						output wire led2,
						output wire led3,
						output wire led4,
						output wire led5,
						output wire led6,
						output wire led7
						);


	reg [4:0]counter1=0;
	reg [3:0]counter2=0;
	reg [9:0]pwm_1=10'b0000_0000_00;
	reg[0:0] pwm_2;
	reg [20:0] cnt_base;
	parameter T_6ms = 21'd2000_000;

 


	always @(posedge clk ) begin
		if(cnt_base < T_6ms - 1'b1)begin
			cnt_base <= cnt_base + 1'b1;
			pwm_2<=pwm_1[cnt_base%10];
		end
		
		else begin
			cnt_base <= 21'd0;
			if(counter1==5'd17)   counter1=0;
			else  counter1=counter1+1;	
			
			case(counter1)
				5'd0  : pwm_1=10'b0000_0000_01;
				5'd1  : pwm_1=10'b0000_0000_11;
				5'd2  : pwm_1=10'b0000_0001_11;
				5'd3  : pwm_1=10'b0000_0011_11;
				5'd4  : pwm_1=10'b0000_0111_11;
				5'd5  : pwm_1=10'b0000_1111_11;
				5'd6  : pwm_1=10'b0001_1111_11;
				5'd7  : pwm_1=10'b0011_1111_11;
				5'd8  : pwm_1=10'b0111_1111_11;
				5'd9  : pwm_1=10'b1111_1111_11;
				5'd10  : pwm_1=10'b0111_1111_11;
				5'd11  : pwm_1=10'b0011_1111_11;
				5'd12  : pwm_1=10'b0001_1111_11;
				5'd13  : pwm_1=10'b0000_1111_11;
				5'd14  : pwm_1=10'b0000_0111_11;
				5'd15  : pwm_1=10'b0000_0011_11;
				5'd16  : pwm_1=10'b0000_0001_11;
				5'd17  : pwm_1=10'b0000_0000_11;
			endcase
		end

	 end
	 
	 	assign led0=pwm_2;
		assign led1=pwm_2;
		assign led2=pwm_2;
		assign led3=pwm_2;
		assign led4=pwm_2;
		assign led5=pwm_2;
		assign led6=pwm_2;
		assign led7=pwm_2;
		
endmodule
		

(2)对应的RTL图:
【FPGA实验1】FPGA点灯工程师养成记
(3)引脚分配与接线
【FPGA实验1】FPGA点灯工程师养成记
接线同上流水灯的接线。

(4)实验现象:
具体实验现象可以看文末😏

FPGA点灯工程师养成记

Forever young,always tearful. 😏文章来源地址https://www.toymoban.com/news/detail-432346.html

到了这里,关于【FPGA实验1】FPGA点灯工程师养成记的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • FPGA硬件工程师Verilog面试题(基础篇一)

    ✅作者简介:大家好我是:嵌入式基地,是一名嵌入式工程师,希望一起努力,一起进步! 📃个人主页:嵌入式基地 🔥系列专栏:FPGA Verilog 习题专栏 微信公众号:嵌入式基地 点击进行在线练习 描述 制作一个四选一的多路选择器,要求输出定义上为线网类型 状态转换:

    2023年04月26日
    浏览(42)
  • 成为一名FPGA工程师:面试题与经验分享

    在现代科技领域,随着数字电子技术的迅猛发展,FPGA(可编程逻辑器件)工程师成为了备受瞩目的职业之一。FPGA工程师不仅需要掌握硬件设计的基本原理,还需要具备良好的编程能力和解决问题的实践经验。面对如此竞争激烈的行业,通过面试成为一名FPGA工程师是一项具有

    2024年02月04日
    浏览(40)
  • FPGA工程师必备技能_Vivado如何清理工程并保证不缺失必要文件

    实际使用vivado的过程中,由于vivado会自动产生一系列文件,有些是不必要时刻保存的中间文件,有些是加快效率的文件(比如编译IP核后产生的文件)。但是在上传svn或者自己做备份的时候希望备份占用尽量少的空间。然而由于vivado不会自动清理,所以这时候就需要我们做手

    2024年02月04日
    浏览(47)
  • 【社招】【中国电信-天翼云】诚聘高级FPGA研发工程师

    基础架构部门介绍: 天翼云是中国电信旗下云计算品牌,致力于成为领先的云计算服务提供商。 基础架构部作为天翼云的核心部门,负责构建天翼云的整个物理基础设施。打造了包括紫金DPU、物理服务器、物理网络、RDMA网络、操作系统、虚拟化、IDC在内的核心底座产品。基

    2024年02月03日
    浏览(47)
  • FPGA目前就业形势咋样?来听听业内工程师的看法

    看到网上有一个问题很火:2023了,FPGA目前就业形势咋样?很多同学也对这个方向比较感兴趣,下面就来一起了解一下吧。 从芯片设计流程来看,FPGA岗位可以分四类 产品开发期:FPGA系统架构师 芯片设计期:数字IC设计工程师、FPGA开发工程师 芯片流片期:FPGA验证工程师 产品

    2024年02月01日
    浏览(33)
  • 【提升FPGA面试技能:40GE、XGE、GE接口详解】——FPGA工程师和网络工程师在实现高速接口时需要了解这些常用的网络接口,本文将深入讲解这些接口的特性和...

    【提升FPGA面试技能:40GE、XGE、GE接口详解】——FPGA工程师和网络工程师在实现高速接口时需要了解这些常用的网络接口,本文将深入讲解这些接口的特性和实现方法。 在网络领域中,传输速率是一个重要的指标,因此在选择网络接口时,需要根据不同的需求选择不同的接口

    2024年01月24日
    浏览(61)
  • Vivado HLS 第1讲 软件工程师该怎么了解FPGA架构

              Vivado HLS是将基于C/C++描述的算法转化成相应的RTL代码,最终在FPGA上实现。这就要求软件工程师对FPGA的内部架构有一些基本的认识,目的在于保证生成的RTL代码在性能和资源上能够达到很好的平衡。实际上,C语言与FPGA是有一些对应关系的。比如: C语言中的数

    2024年02月09日
    浏览(40)
  • AI提示词工程师/AIGC提示词工程师/prompt工程师/AI训练师学习路线图(元壤教育)

    系统学习,公众号搜索【元壤教育】开始学习吧 先窥全貌:Prompt工程师课程概述介绍 Prompt 工程师 优化工作流程 在 GPT 中编写提示词 文本到视觉 Midjourney prompts GPT-3.5/4 概述 GPT的未来 专家访谈 从概念开始:简单理解AIGC发展和产业机遇 AIGC的概念与起源 AIGC的发展三阶段 AIGC的

    2024年02月09日
    浏览(64)
  • 【备考网络工程师】如何备考2023年网络工程师之错题集篇(1)

    上半年试了一下软考的水,没想到居然过了,当然当时考的是初级-网络管理员,但是我觉得应该追求再高一些,正好比王勃说的穷且益坚,不坠青云之志。所以我得时刻保持自己学习的状态,为遇见明天更好的自己而加油,因此我也趁备战之初记录下来,有一起备考的赶紧加

    2024年02月09日
    浏览(39)
  • 【AIGC提示词工程师、AI提示词工程师、Prompts工程师、Midjourney培训】电商行业AIGC图像生成与内容创作学习路线图

    导言 关注【元壤教育】公众号进入平台开始系统学习之路。 AIGC(Stable Diffusion、DALL-E 和 Midjourney)助力电商行业降本增效、提升10倍生产力 一门深入全面的课程,专为对AI图像生成在电商行业应用感兴趣的人士打造,旨在帮助他们从零基础迈向专家级别。无需拥有任何相关经

    2024年02月10日
    浏览(52)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包