当前位置:   article > 正文

16路彩灯控制器 FPGA-Verilog_基于verilog的16路彩灯控制器

基于verilog的16路彩灯控制器

#16路彩灯控制器 FPGA-Verilog#

1、Verilog代码编写

1.1输入输出信号确定

题目要求多路彩灯控制器通过对应的开关按钮,能够控制多个彩灯的输出状态,组合多种变幻的灯光效果。

彩灯控制器的功能描述为:

设计一个多路彩灯控制器,能够使花型循环变化,具有复位清零功能,并可以选择花型变化节奏。具体要求如下:

  1. 彩灯控制器由16路发光二极管构成,当控制开关打开时,能够自动在6种不同的花型之间循环变化。

  2. 控制器具有复位清零功能,当复位信号有效时,不管花型状态如何,都会立即清零,恢复到初始状态。

  3. 设置节拍控制开关,控制多路彩灯的花型以快慢两种节奏变化。

通过功能描述可以知道,该系统需要有4个输入–时钟信号clk、复位开关、开启开关以及节奏变化开关,和1个输出–16位LED输出。

1.2模块确定

由于板载的时钟信号为50MHz,即时间间隔为20ns,如果直接使用肉眼无法观察到现象,因此需要对系统时钟进行分频,得到彩灯的时钟控制。

因为需要设置节奏控制开关,控制多路彩灯的花型以快慢两种节奏变化,需要一个2选1的数据选择器,当节奏控制开关置“0”时,以慢节奏显示花型,当置为“1”时,以快节奏显示花型,从而实现不同节奏的得到。

核心模块需要实现在节奏开关的控制下LED6种花型循环显示,则需要使用到状态机的知识,6种不同花型对应6个状态机,在正确的控制信号上实现LED的显示。

1.3模块代码编写

由模块确定可知,该设计由分频、选择、花型循环控制以及顶层4个模块组成。

1.3.1分频器设计

分频器可以直接调用IP核实现,也可以直接编写代码,在此设计中选用直接编写代码来进行。

module divide(clk,m,clk_out);
	input clk;
	input [31:0] m;
	output clk_out;

	reg [31:0] cnt;
	reg clk_out;
	
	initial
	begin
		cnt<=32'b0000_0000_0000_0000_0000_0000_0000_0000;
		clk_out<=1'b0;
	end

	always @(posedge clk)
	begin
		if(cnt==m) begin
			clk_out<=~clk_out;
			cnt<=32'b0000_0000_0000_0000_0000_0000_0000_0000;
		end
		else
			cnt<=cnt+1;
	end
endmodule
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

由代码段可知,只要确定了m值就可以得到对应的分频时钟信号,例如需要得到1MHz的时钟信号,因为1*25*2=50,则需要将m设置为25,即

m = 2*f1/f0
  • 1

1.3.2二选一数据选择器设计

该部分主要是对节奏控制开关的实现,选择板子上的拨码开关,当开关拨到“1”时,以快节奏显示LED,当开关拨回“0”时,以慢节奏显示LED。同时,要产生两种不同快慢的节奏,即要产生两种频率不一的时钟信号,需要用到上面的分频器设计。

module mux2_1(speed_key,clk,cclk);
	input speed_key,clk;
	output cclk;
	
	reg cclk;
	
	wire clk1,clk2;
	divide divide1(clk,2500,clk1);%快节奏
	divide divide2(clk,500000,clk2)%慢节奏
	
	always @(posedge clk)
	begin
		if(speed_key)
			cclk<=clk1;
		else
			cclk<=clk2;
	end
endmodule
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

其中例化调用了分频器的设计,产生了10kHz的快节奏信号和1Hz的慢节奏信号。

1.3.3花型循环显示设计

前文提到该部分需要用到状态机,先掌握状态机的基本原理和编写流程。

1.3.3.1有限状态机

有限状态机(FSM)是按照设定好的顺序实现状态转移并产生相应输出的特定机制,是组合逻辑和寄存器逻辑的一种特殊组合:寄存器用于存储状态[包括现态current state和次态next state],组合逻辑用于状态译码并产生输出逻辑。在状态机设计中,主要包含以下3个要素:

  • 当前状态,即现态(CS);
  • 下一个状态,即次态(NS);
  • 输出逻辑(OL)

Verilog描述状态机有三段式描述、两段式描述以及单端式描述方法。三段式描述即三要素各用一个always过程描述;两段式描述使用两个always过程描述,一个过程描述现态和次态时序逻辑,另一个过程描述输出逻辑;单端式描述将三要素放在一个always过程描述。
####1.3.3.2 代码实现 ####

module mled(cclk,rst,start,LED);
	//输入输出定义
	input rst,start,cclk;
	output [15:0] LED;
	//各状态定义,也可以使用一位热码
	parameter IDLE=3'b000;
	parameter s0=3'b001;
	parameter s1=3'b010;
	parameter s2=3'b011;
	parameter s3=3'b100;
	parameter s4=3'b101;
	parameter s5=3'b110;
	//寄存器赋值设置
	reg [15:0] LED;
	reg [2:0] st_cur;//当前状态
	reg [2:0] st_next;//下一状态
	//实现同步状态跳转
	always@(posedge cclk or negedge rst)
	begin
		if(!rst)
			st_cur<=IDLE;
		else
			st_cur<=st_next;
	end
	//组合逻辑判断状态转移条件
	always @(*)
	begin
		case(st_cur)
		IDLE:st_next<=s0;
		s0:st_next<=s1;
		s1:st_next<=s2;
		s2:st_next<=s3;
		s3:st_next<=s4;
		s4:st_next<=s5;
		s5:st_next<=s0;
		default:st_next<=IDLE;
		endcase
	end
	//描述状态输出
	always@(posedge cclk or negedge rst)
	begin
		if(!rst)
			LED<=16'b0000000000000000;
		else if(st_cur==s0&&start)
			LED<=16'b1111111111111111;
		else if(st_cur==s1&&start)
			LED<=16'b0101010101010101;
		else if(st_cur==s2&&start)
			LED<=16'b1010101010101010;
		else if(st_cur==s3&&start)
			LED<=16'b0000111100001111;
		else if(st_cur==s4&&start)
			LED<=16'b1100110000110011;
		else if(st_cur==s5&&start)
			LED<=16'b1001100100111100;
		else
			LED<=16'b0000000000000000;
	end 
endmodule
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59

从代码中可以看到,输出的LED状态只与当前状态(st_cur)有关,与输入状态无关,属于摩尔型状态机。状态机的第一段对应摩尔状态机模型的状态寄存器,用来记忆状态机当前所处的状态;状态机的第二段对应摩尔状态机模型产生下一状态的组合逻辑F;状态机的第三段对应摩尔状态机产生输出的组合逻辑G,因为采用时序电路输出有很大的优势,所以这里第三段状态机是由时序电路输出的。

在这里插入图片描述

由状态机图片可以看到,系统可以实现花型的循环显示。
###1.3.4 顶层模块###

module led_control(clk,rst,start,speed,LED);
//clk--系统时钟,rst--复位控制,start--启动,speed--节奏控制,LED--16路彩灯
	input clk,rst,start,speed;
	output [15:0] LED;

	wire speed1,speed2;
	wire cclk;

	divide divide1(clk,25,speed1);//快节奏
	divide divide2(clk,2500,speed2);//慢节奏
	speed_control speed_control(speed,clk,start,speed1,speed2,cclk);//节奏控制
	mled mled(cclk,rst,start,LED);//花型控制及循环显示

endmodule
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

在这里插入图片描述

通过对上述模块的调用和例化,实现顶层模块的设计,完成复位、启动、快慢开关对LED显示的控制,以及不同花型的LED显示。
##2. 系统仿真##
仿真过程是正确实现设计的关键环节,用来验证设计思想是否正确,及在设计实现过程中各种分布参数引入后,其设计的功能是否依然正确无误。仿真主要分为功能仿真和时序仿真。功能仿真是在设计输入后进行;时序仿真是在逻辑综合后或布局布线后进行。
###2.1 功能仿真###
功能仿真是指在一个设计中, 在设计实现前对所创建的逻辑进行的验证其功能是否正确的过程。 布局布线以前的仿真都称作功能仿真,它包括综合前仿真( Pre-Synthesis Simulation )和综合后仿真( Post-Synthesis Simulation )。 综合前仿真主要针对基于原理框图的设计;综合后仿真既适合原理图设计,也适合基于HDL语言的设计。

在这里插入图片描述

由功能仿真得,逻辑设计都是正确的。
###2.2 时序仿真###
时序仿真使用布局布线后器件给出的模块和连线的延时信息,在最坏的情况下对电路的行为作出实际地估价。时序仿真使用的仿真器和功能仿真使用的仿真器是相同的,所需的流程和激励也是相同的;惟一的差别是为时序仿真加载到仿真器的设计包括基于实际布局布线设计的最坏情况的布局布线延时,并且在仿真结果波形图中,时序仿真后的信号加载了时延,而功能仿真没有。
####2.2.1 test bench编写####
编写testbench的主要目的是为了对使用硬件描述语言(HDL)设计的电路进行仿真验证,测试设计电路的功能、部分性能是否与预期的目标相符。
编写testbench进行测试的过程如下:

1) 产生模拟激励(波形);

2) 将产生的激励加入到被测试模块并观察其输出响应;

3) 将输出响应与期望进行比较,从而判断设计的正确性。

`timescale 1ns/1ns
`include "D:/FPGA1/quartus/led_control.v"

module led_control_vlg_tst();
reg clk;
reg rst;
reg start;
reg speed;

wire [15:0] LED;
wire speed1,speed2;
wire cclk;

divide divide1(clk,25,speed1);
divide divide2(clk,2500,speed2);
speed_control speed_control(speed,clk,start,speed1,speed2,cclk);
mled mled(cclk,rst,start,LED);

always
#10 clk=~clk;

initial
begin
	clk=0;rst=0;start=0;speed=1;
	#100 rst=1;
	#100 start=1;
	#100000 speed=0;
	#100000 speed=1;
	#100000 speed=1;
	#100000 speed=1;
	#100000 speed=0;
	#100000 speed=0;
	#100000 speed=1;
	#100000 speed=0;
	#100000 speed=0;
	#100000 speed=0;
	#100000 speed=0;
	#100000 speed=1;
	#100000 speed=0;
	#100000 speed=1;
	#100000 speed=1;
	#100000 speed=1;
	#100000 speed=0;
	#100000 speed=0;
	#100000 speed=1;
	#100000 speed=0;
	#100000 speed=0;
	#100000 speed=0;
	#100000 speed=0;
	#100000 speed=1;
	#100000 speed=0;
	#100000 speed=1;
	#100000 speed=1;
	#100000 speed=1;
	#100000 speed=0;
	#100000 speed=0;
	#100000 speed=1;
	#100000 speed=0;
	#100000 speed=0;
	#100000 speed=0;
	#100000 speed=0;
	#100000 speed=1;
	#100000 $finish;
end
initial $monitor($time,,,"clk=%d LED=%d",clk,LED);
endmodule
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66

由代码可知,时钟信号clk为50MHz,在initial段对相关输入信号进行了赋值。
####2.2.2 时序仿真结果####

在这里插入图片描述

由时序仿真图得,加入延时后的设计都是正确的,LED的花型能够循环显示六种不同的形态,复位、启动以及节奏开关都可以有效控制LED的变化。
###2.3 Signaltap 逻辑分析仪###
在上板之前,利用signaltap进行逻辑分析的正确性验证。

在这里插入图片描述

未开启控制开关LED的状态显示。

在这里插入图片描述

控制开关打开,节奏开关拨置零的LED状态显示。

在这里插入图片描述

控制开关打开,节奏开关拨置一的LED状态显示。

在这里插入图片描述

按下复位开关的LED状态显示。

由逻辑分析仪的结果知,系统能够完整且正确地实现设计功能的需求。
##3. 上板调试##
本设计选用器件Cyclone IV E:EP4CE6E22C8 来实现多路彩灯控制器。
###3.1 外设设计###
由于需要显示16路彩灯,所以需要一个16个LED组成的电路,16路LED阴极共地,每个LED的阳极连接板子上不同的管脚,得到不同高低电平,实现不同花型的显示。由于板子上的高电平设置输出为3.3V,而LED最大耐压值为3V左右,因此需要接16个限流电阻。由于白蓝绿灯的耐压值为3-3.2V,红黄灯的耐压值为1.8-2.0V,电流为15-20mA,所以白蓝绿灯选用47Ω的限流电阻,红黄灯选用200Ω的限流电阻。

在这里插入图片描述

###3.2 布局布板###
由板子管脚分配可知,系统时钟clk在PIN_23,复位信号rst在PIN_25,拨码开关在PIN_88、PIN_89、PIN_90和PIN_91,因此设计中的clk、rst、start以及speed只能分布在这几个管脚,LED的16个管脚分配在可以做普通I/O的管脚。

在这里插入图片描述

###3.3 上板结果

在这里插入图片描述

由上板调试结果知,系统可以很好地完成功能设计的要求,完成多路彩灯控制器系统的设计。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家自动化/article/detail/699646
推荐阅读
相关标签
  

闽ICP备14008679号