首页 > 其他分享 >FPGA交通信号灯设计报告(VHDL语言)

FPGA交通信号灯设计报告(VHDL语言)

时间:2024-03-13 23:30:06浏览次数:27  
标签:2display FPGA VHDL clk -- 信号灯 数码管 1display special

FPGA的大作业我选择了交通灯控制系统的设计,此课程只有2个学分,因此只需要在相应软件仿真出结果即可。以下是我的设计报告,当时写的匆忙,没有对代码进行优化改进,但仿真结果是正确的,可以给大家提供一下思路。

一、任务分析

请添加图片描述

分析设计要求可以看出,本系统设计数码管动态显示、译码器、计数器分频方面的知识。

1.输入和输出

  1. 输入

    clk:时钟输入(50MHz)。

    special:特殊情况发生输入。

  2. 输出

    l1、l2:数码管位选。

    display_1、display_2:数码管段选。

    out_1、out_2:红绿灯选择。

2.多进程

  1. reg进程:分频计数

    • 红绿灯的闪烁和数码管显示数字的变化都需要计时,计时单位为s(秒)时,设计最简单。因此,我将50MHz频率的clk驱动分频,这部分运用了计数器知识。

    • 从题目中看出,红绿灯50s为一个循环,我使用信号counter来记录时间,时钟每过1秒钟,counter就加1,counter的值不能超过50。

  2. com进程:红绿灯显示

    • 通过counter的值就可以判断出东西方和南北方的灯为什么颜色。我使用自定义枚举类型来表示红绿灯的三种状态。

    • 在判断红绿灯状态的同时,还应该计算出数码管应该显示的数字为多少。

  3. smg进程:数码管显示

    • 将com进程中计算出的数码管数字在数码管上显示出来。计算数码管十位上的显示数字时用10取模,计算数码管个位上的显示数字时用10取余。
    • 由于数码管位选仅有两个,我使用一个变量的0和1分别表示数码管的十位显示和个位显示。
    • 数码管的段选运用了译码器相关知识。

3.特殊情况

  1. 当bit类型信号special为’1’时,进入特殊情况处理。

  2. 在com进程中,只有当special为’0’时,counter才会加1。目的是在特殊情况时,数码管的数字不会发生变化。

  3. 我额外定义了一个bit类型信号change,时钟每过一秒钟,它就会取反。使用它的目的是在特殊情况时,实现数码管闪烁。

4.注意

需要格外注意的是,reg、com、smg三个进程的敏感信号。

reg:process(clk,special)

com:process(counter,special)

红绿灯显示在每隔1秒钟判断或special特殊情况到来时判断即可

reg:process(clk,change,special)

数码管为动态扫描,只有速度够快,才能使人眼无法察觉数码管的交替显示,因此需要clk时钟信号作为敏感信号。

二、quartus ii 仿真

1.VHDL语言描述

library ieee;
use ieee.std_logic_1164.all;
entity fisrt is
--两组数码管(段选+位选),两组灯
	port(clk:in std_logic;
			special:in bit;
       		--数码管段选
			l1,l2:out std_logic_vector(1 downto 0);
       		--数码管位选
			display_1,display_2:out std_logic_vector(6 downto 0);
       		--红绿灯
			out_1,out_2:out std_logic_vector(2 downto 0));
end fisrt;
architecture behav of fisrt is
	type FSM is (s0,s1,s2);
	signal LED_1,LED_2:FSM;--自定义枚举类型
	signal counter:integer range 0 to 49;--共50s
	signal smg_1,smg_2:integer range 0 to 24;--数码管显示数字
	signal change:bit;--每一秒钟用于变化的量
begin

--进程reg用于分频
	reg:process(counter,special)
		variable clk1:integer range 0 to 9999;--50MHz分频为1Hz
		variable clk2:integer range 0 to 4999;
	begin
		if clk'event and clk='1' then
			if clk1=9999 then
				clk1:=0;
				if clk2=4999 then
					clk2:=0;
					if special='0' then
						change<=not change;
						if counter=49 then
							counter<=0;
						else counter<=counter+1;
						end if;
					end if;
				else clk2:=clk2+1;
				end if;
			else clk1:=clk1+1;
			end if;
	  end if;
	end process reg;


--进程com用于红绿灯显示
	com:process(clk,counter,special)
	begin
		if special='1' then
			out_1<="100";
			out_2<="100";
		else
			if counter<20 then
				LED_1<=s0;smg_1<=20-counter;
				LED_2<=s0;smg_2<=25-counter;
			elsif counter<25 then
				LED_1<=s1;smg_1<=25-counter;
				LED_2<=s0;smg_2<=25-counter;
			elsif counter<45 then
				LED_1<=s2;smg_1<=50-counter;
				LED_2<=s1;smg_2<=45-counter;
			else LED_1<=s2;smg_1<=50-counter;
				   LED_2<=s2;smg_2<=50-counter;
			end if;
			
			case LED_1 is
				when s0=>out_1<="010";--绿灯亮
				when s1=>out_1<="001";--黄灯亮
				when s2=>out_1<="100";--红灯亮
			end case;
			case LED_2 is
				when s0=>out_2<="100";--红灯亮
				when s1=>out_2<="010";--绿灯亮
				when s2=>out_2<="001";--黄灯亮
			end case;
		end if;
	end process com;
	
--进程smg用于数码管显示
	smg:process(clk,change,special)
	variable a,b:bit;
	variable c1,c2:integer range 0 to 10;
	begin
    if clk'event and clk='1' then
		a:=not a;
		b:=not b;
		case a is
			when '0'=> l1<="01";c1:=smg_1 rem 10;--取个位数
			when '1'=> l1<="10";c1:=smg_1 mod 10;--取十位数
		end case;
		case b is
			when '0'=> l2<="01";c2:=smg_2 rem 10;
			when '1'=> l2<="10";c2:=smg_2 mod 10;
		end case;
		
		if special='1' and change='1' then --特殊情况时,数码管1s闪烁一次
			c1:=10;c2:=10;
		end if;
		
		case c1 is
			when 0 =>display_1<="0111111";
			when 1 =>display_1<="0000110";
			when 2 =>display_1<="1011011";
			when 3 =>display_1<="1001111";
			when 4 =>display_1<="1100110";
			when 5 =>display_1<="1101101";
			when 6 =>display_1<="1111101";
			when 7 =>display_1<="0000111";
			when 8 =>display_1<="1111111";
			when 9 =>display_1<="1100011";
			when others=>display_1<="0000000";
		end case;
		case c2 is
			when 0 =>display_2<="0111111";
			when 1 =>display_2<="0000110";
			when 2 =>display_2<="1011011";
			when 3 =>display_2<="1001111";
			when 4 =>display_2<="1100110";
			when 5 =>display_2<="1101101";
			when 6 =>display_2<="1111101";
			when 7 =>display_2<="0000111";
			when 8 =>display_2<="1111111";
			when 9 =>display_2<="1100011";
			when others=>display_2<="0000000";
		end case;
    end if;
	end process smg;
end behav;

2.仿真结果

  • RTL Viewer

请添加图片描述

  • 时序仿真

为了方便仿真,我将clk1和clk2去除,将clk设置为1Hz频率的时钟信号,下图为修改后代码。这样仿真的缺点就是,数码管无法显示出完整数字,在每过一秒钟,交替显示十位数码管和个位数码管。
在这里插入图片描述
仿真结果如下:

请添加图片描述

三、总结

1.收获

设计交通信号灯控制系统,我熟悉了计数器、译码器、动态数码管显示的知识,加深对它们的工作原理的理解,更加熟练的使用case、if等语句。同时,也进一步熟悉EDA软件——quartusii,提高代码构思能力。

2.问题与解决

  1. 编译过程中出现很多语法错误,例如process进程忘记加begin,定义的整型类型忘记加range,变量赋值语句的符号为“ := ”,if语句没有加then,忘记写“end if”…

    这些语法错误在编译后的error中查找并改正。

  2. 构思VHDL代码结构时,最大的困难就是数码管显示数字和特殊情况处理。

    • 我将数码管显示数字的计算和判断红绿灯代码放到了一起,利用counter信号50s一循环,红绿灯50s一循环,在根据红、绿、黄灯的持续时间,就可以将数码管数字计算出来。

    • 特殊情况是最难处理的地方。它不仅要求在此时红灯亮,还需要让数码管闪烁。我将数码管设置为1s闪烁,具体实现方法是,在com进程让change信号每过1s取反,在smg进程中,当special=‘1’ 并且change='1’时,数码管不显示数字。

3.改进与优化

  1. 数码管显示数字部分可以看出,这个程序在显示数字小于10时,两位数码管显示为"0X",也就是说十位上的数码管有数据显示,这是不符合现实的,因此,可以更改为以下代码。

    --smg进程部分
    case a is
    	 when '0'=> l1<="01";c1:=smg_1 rem 10;--取个位数
    	 when '1'=> l1<="10";c1:=smg_1 mod 10;--取十位数
    			if c1=0 then 
            		c1:=10;--此时数码管不显示
    			end if;
    end case;
    case b is
    	 when '0'=> l2<="01";c2:=smg_2 rem 10;
    	 when '1'=> l2<="10";c2:=smg_2 mod 10;
    			if c2=0 then 
            		c2:=10;--此时数码管不显示
    			end if;
    end case;
    
    
  2. 通过理解题目内容可以看出,东西方和南北方的数码管显示和灯颜色的选择是相似的,可以设计子程序,通过函数调用或过程调用优化代码。但因本人能力有限,没有写出具体实现方法。

标签:2display,FPGA,VHDL,clk,--,信号灯,数码管,1display,special
From: https://blog.csdn.net/m0_66616115/article/details/136694389

相关文章

  • m基于FPGA的Alamouti编码verilog实现,包含testbench测试文件
    1.算法仿真效果 本系统进行了Vivado2019.2平台的开发,结果如下:   2.算法涉及理论知识概要        在无线通信领域,多天线技术是提高系统容量和可靠性的关键手段之一。Alamouti编码是空时编码(STC)的一种,它为两发射天线的系统提供了一种全速率、全分集的简单编码方......
  • FPGA的FIFO部分的知识点
    看的小梅哥的新视频,FIFO这边讲的不太清楚,换正点原子的fifo听一下。后面的以太网和HDMI有空也看一下正点原子的,主要是想快速看zynq的知识,而且现在学的很多都是模仿抄代码,真正自己来还是得工程中实际应用的时候才会使用学习FIFO,先入先出,像队列。常用于数据的缓存,因为数据的读写带......
  • 从零开始利用MATLAB进行FPGA设计(一):建立脉冲检测模型的Simulink模型2
    目录1.模块的总体结构1.1从工作空间导入输入信号1.2FIR滤波器2.Subsystem3.MATLABFunction文章灵感来源于MATLAB官方免费教程:HDLCoderSelf-GuidedTutorial考虑到MATLAB官网的英文看着慢,再加上视频讲解老印浓浓的咖喱味,我决定记录利用MATLAB&Simulink&SystemGenerat......
  • FPGA的时钟IP核知识点
    IP核在我看来就跟stm32中的一些驱动的库函数一样,可以调用快速使用。不用一步一步的自己写底层原理。可以加速设计,快速设计代码。IP核的PLL还有一个MMCM。PLL是锁相环,对时钟进行管理。也是后面使用中很重要的IP核。不同器件需要不同的时钟。时钟管理单元CMT=PLL+MMCM混合时钟管......
  • 基于FPGA各种视频接口转换的国产化设计
    随着国产化进程推进,现在许多项目需要实现国产化设计,本博主通过器件选型/原理图设计,到视频接口输入,DDR3缓存,再到图像输出,使用者可在此基础实现二次开发,功能实现通过verilog,操作简单,添加功能方便。接口包含lvds/camelink/bt1120/hdmi/sdi等等常用视频接口,也可定制其他接口,带......
  • OMAP-L138 + FPGA开发板(Pin-To-Pin国产FPGA)
    XQ138F-EVM是广州星嵌电子科技有限公司基于TIOMAP-L138(定点/浮点DSPC674x+ARM9)+FPGA处理器研制的开发板;OMAP-L138选用TI德州仪器的TMS320C6748+ARM926EJ-S异构双核处理器,主频456MHz,高达3648MIPS和2746MFLOPS的运算能力;FPGA采用中科亿海微eHiChip6家族EQ6......
  • 提高性能、减小尺寸的1SG250HU3F50E3VG、1SG250HN3F43I3VG、1SG250HN3F43E2VG高性能 S
    概述英特尔®Stratix®10GXFPGA包含多达1020万个LE。它们在单独的收发器块上配备多达96个通用收发器,可提供2666MbpsDDR4外部内存接口性能。这些收发器可提供高达28.3Gbps的短距离和跨背板传输。这些设备针对需要最高收发器带宽和核心结构性能的FPGA应用而优化......
  • XILINX FPGA 1/4/8通道PCIe DMA控制器IP,高性能版本IP介绍应用
    Multi-ChannelPCIeQDMA&RDMAIP1   介绍基于PCIExpressIntegratedBlock,Multi-ChannelPCIeQDMASubsystem实现了使用DMA地址队列的独立多通道、高性能Continous或ScatherGatherDMA,提供FIFO/AXI4-Stream用户接口。基于PCIExpressIntegratedBlock,Multi-ChannelPC......
  • FPGA的DAC转换部分遇到的问题
    利用线性序列机根据时序图和手册中的输出值的对应关系。DAC这边的知识基本相同。在验证的时候发现了问题,反推仿真的时候发现了,子啊lsm_cnt线性序列机计数的33到了之后还有一位,发现是set_en的问题,因为set_en使能才能计数。这边是正确的波形图和代码对应always@(posedgeclko......
  • 基于肤色模型和中值滤波的手部检测算法FPGA实现,包括tb测试文件和MATLAB辅助验证
    1.算法运行效果图预览RTL图:   仿真图:   导入到matlab显示效果如下:   2.算法运行软件版本matlab2022a vivado2019.2 3.算法理论概述      在计算机视觉领域,基于肤色模型和中值滤波的手部检测方法是一种常见的初步定位策略。该方法主要分为......