FPGA课程设计(拨码控制流水灯)

2023-10-11 14:30

本文主要是介绍FPGA课程设计(拨码控制流水灯),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

基本要求:以十赫兹的频率,点亮实验开发板上的发光二极管,显示过程中各个点亮的发光二极管的亮度呈现出明暗变化,形似呼吸。开关0 向下系统复位,灯全灭。开关0向上,LED呈现呼吸状显示。(利用pwm)

扩展部分:

分组显示两组不同渐变周期的呼吸灯,Key0控制LED4~LED0显示, KEY1 控制LED9~LED5显示,渐变周期由开关1~开关9输入,同时数码管分别显示2组呼吸灯对应周期数。

module  led
(
//数据的输入input   wire            sys_clk     ,input   wire            sys_rst_n   ,  input   wire    [9:0]   sw_in       ,  input   wire            key_in1     ,  input   wire            key_in2     , //led的输出output  wire   [9:0]   led_out      ,//前三个数码管显示频率output  wire    [6:0]   ge1         ,output  wire    [6:0]   shi1        ,output  wire    [6:0]   bai1        ,//后三个数码管显示频率output  wire  [6:0]   ge2         ,output  wire  [6:0]   shi2        ,output  wire  [6:0]   bai2     );wire    [8:0]     data_in1         ;
wire    [8:0]     data_in2         ;
wire    [10: 0]   bcd1              ;
wire    [10: 0]   bcd2              ;//key1和key2 控制输入的频率
ctrl ctrl_inst
(.sys_clk   (sys_clk)  ,.sys_rst_n (sys_rst_n)  ,  .sw_in     (sw_in)  ,  .key_in1   (key_in1)  ,  .key_in2   (key_in2)  ,.data_in1  (data_in1) ,.data_in2  (data_in2) );//开关输入的二进制数,转换为BCD码用于数码管显示
binTobcd binTobcd_inst1
( .bin (data_in1),   // binary.bcd (bcd1)
);binTobcd binTobcd_inst2
( .bin (data_in2),   // binary.bcd (bcd2)
);//led的输出breath_led breath_led_inst1
(.sys_clk     (sys_clk  ),.sys_rst_n   (sys_rst_n),.data      (data_in1),.led_out     (led_out[4:0]  )
);breath_led breath_led_inst2
(.sys_clk     (sys_clk  ),.sys_rst_n   (sys_rst_n),.data      (data_in2),.led_out     (led_out[9:5]  )
);//数码管显示seg seg_int1
(.sys_clk   (sys_clk)  ,.sys_rst_n (sys_rst_n)  ,.sw0       (sw_in[0])  ,.bcd       (bcd1)  ,.ge        (ge1) ,.shi       (shi1) ,.bai       (bai1) 
);seg seg_int2
(.sys_clk   (sys_clk)  ,.sys_rst_n (sys_rst_n)  ,.sw0       (sw_in[0])  ,.bcd       (bcd2)  ,.ge        (ge2) ,.shi       (shi2) ,.bai       (bai2) 
);module  breath_led(input   wire          sys_clk     , //系统时钟50Mhzinput   wire          sys_rst_n   , //key3全局复位input   wire   [8:0]  data        ,//获得控制权寄存的数据output  reg    [4:0]  led_out  //led的输出
);reg     [9:0]   cnt_1s  ;
reg     [9:0]   cnt_1ms ;
reg     [5:0]   cnt_1us ;
reg             cnt_en  ;//PWM脉宽调制呼吸流水,的几个参数来调制,和改变频率
parameter   CNT_1US_MAX = 6'd49 ;
parameter   CNT_1MS_MAX = 10'd999;
parameter   CNT_1S_MAX  = 10'd999 ;//cnt_1us:1us计数器
always@(posedge sys_clk or negedge sys_rst_n)if(sys_rst_n == 1'b0)cnt_1us <=  6'd0;else    if(cnt_1us == CNT_1US_MAX)cnt_1us <=  6'd0;elsecnt_1us <=  cnt_1us + 6'd1;//cnt_1ms:1ms计数器
always@(posedge sys_clk or negedge sys_rst_n)if(sys_rst_n == 1'b0)cnt_1ms <=  10'd0;else    if((cnt_1ms == CNT_1MS_MAX) && (cnt_1us == CNT_1US_MAX))cnt_1ms <=  10'd0;else    if(cnt_1us == CNT_1US_MAX)cnt_1ms <=  cnt_1ms + 10'd1;elsecnt_1ms <=  cnt_1ms;//cnt_1s:1s计数器以及用1S来作为基础,通过1/data来获得新的频率让led的闪亮
always@(posedge sys_clk or negedge sys_rst_n)if(sys_rst_n == 1'b0)cnt_1s  <=  10'd0;else    if(data == 9'd0)cnt_1s  <=  10'd0;else    if((cnt_1s == CNT_1S_MAX / data) && (cnt_1ms == CNT_1MS_MAX) && (cnt_1us == CNT_1US_MAX))cnt_1s  <=  10'd0;else    if((cnt_1ms == CNT_1MS_MAX) && (cnt_1us == CNT_1US_MAX))cnt_1s  <=  cnt_1s + 10'd1;elsecnt_1s  <=  cnt_1s;//cnt_1s:1s计数器以及用1S来作为基础,通过1/data来获得新的频率让led的闪亮的使能信号
always@(posedge sys_clk or negedge sys_rst_n)if(sys_rst_n == 1'b0)cnt_en  <=  1'b0;else    if(data == 9'd0)cnt_en  <=  1'b0;else    if((cnt_1s == CNT_1S_MAX / data) && (cnt_1ms == CNT_1MS_MAX) && (cnt_1us == CNT_1US_MAX))cnt_en  <=  ~cnt_en;elsecnt_en  <=  cnt_en;//利用PWM脉宽调制呼吸流水
always@(posedge sys_clk or negedge sys_rst_n)if(sys_rst_n == 1'b0)led_out <=  5'b00000;else    if(data == 9'd0)led_out <=  5'b00000;else    if(((cnt_en == 1'b0) && (cnt_1ms <= cnt_1s)) || ((cnt_en == 1'b1) && (cnt_1ms > cnt_1s)))led_out <=  5'b00000;elseled_out <=  5'b11111;endmodulemodule  ctrl
(input   wire            sys_clk     ,//输入50mhz的时钟信号input   wire            sys_rst_n   ,  //复位信号input   wire    [9:0]   sw_in       , //拨码开关input   wire            key_in1     , // 按键控制input   wire            key_in2     ,//按键控制output  reg    [8:0]     data_in1   ,//输出的数据output  reg    [8:0]     data_in2    //输出的数据);reg              begin_reg        ;//开始的标志,开始时10hz的频率
reg              sw0_reg          ;//sw[0]的延时一拍
reg              key_in1_reg      ;//按键1控制后面的数据
reg              key_in2_reg      ;  //按键2控制前面的数据wire             sw0_flag          ; //SW[0]拨动了的标志信号//最开SW0拨上去就赋值给数据初始值10hz,按下按键后跳转
always@(posedge sys_clk or negedge sys_rst_n)if(sys_rst_n == 1'b0)sw0_reg <= 1'd0;elsesw0_reg <= sw_in[0];assign  sw0_flag = ((sw_in[0])&&(~ sw0_reg));always@(posedge sys_clk or negedge sys_rst_n)if(sys_rst_n == 1'b0)begin_reg <= 1'd0;else    if(key_in1 == 1'd0 ||key_in2 == 1'd0)begin_reg <= 1'd0;else    if(sw0_flag == 1'd1)begin_reg <= ~ begin_reg;elsebegin_reg <=  begin_reg;// 按下按键获得对前后数据的控制权
always@(posedge sys_clk or negedge sys_rst_n)if(sys_rst_n == 1'b0)key_in1_reg <= 1'd0;else    if(sw_in[0] == 1'd0)key_in1_reg <= 1'd0;else    if(key_in2 == 1'd0)key_in1_reg <= 1'd0;        else    if(sw_in[0] == 1'd1 && key_in1 == 1'd0)key_in1_reg <= 1'd1;elsekey_in1_reg <= key_in1_reg;always@(posedge sys_clk or negedge sys_rst_n)if(sys_rst_n == 1'b0)key_in2_reg <= 1'd0;else    if(sw_in[0] == 1'd0)key_in2_reg <= 1'd0;else    if(key_in1 == 1'd0)key_in2_reg <= 1'd0;else    if(sw_in[0] == 1'd1 && key_in2 == 1'd0)key_in2_reg <= 1'd1;elsekey_in2_reg <= key_in2_reg;//把数据传输给寄存器
always@(posedge sys_clk or negedge sys_rst_n)if(sys_rst_n == 1'b0)data_in1 <= 9'd0;else    if(sw_in[0] == 1'd0)data_in1 <= 9'd0;else    if(sw_in[0] == 1'd1 && begin_reg == 1'd1)data_in1 <= 9'd10;else    if(key_in1_reg == 1'd1)data_in1 <= sw_in[9:1] ;elsedata_in1 <= data_in1;always@(posedge sys_clk or negedge sys_rst_n)if(sys_rst_n == 1'b0)data_in2 <= 9'd0;else    if(sw_in[0] == 1'd0)data_in2 <= 9'd0;else    if(sw_in[0] == 1'd1 && begin_reg == 1'd1)data_in2 <= 9'd10;else    if(key_in2_reg == 1'd1)data_in2 <= sw_in[9:1] ;elsedata_in2 <= data_in2;endmodulemodule  seg
(input   wire            sys_clk     ,//系统时钟50Mhzinput   wire            sys_rst_n   ,//key3全局复位input   wire            sw0         ,//sw0的拨码输入input   wire    [10:0]  bcd         ,//转换后的BCd码output  reg    [6:0]    ge         ,//个位的输出output  reg    [6:0]    shi        ,//十位的输出output  reg    [6:0]    bai        //百位的输出
);//个位的输出
always@(posedge sys_clk or negedge sys_rst_n)if(sys_rst_n == 1'b0)ge <= 7'b1_111_111;else    if(sw0 == 1'd0)ge <= 7'b1_111_111;else    case(bcd[3:0])
4'b0000:ge <= 7'b1_000_000;
4'b0001:   ge <= 7'b1_111_001;
4'b0010:   ge <= 7'b0_100_100;
4'b0011:   ge <= 7'b0_110_000;
4'b0100:   ge <= 7'b0_011_001;
4'b0101:   ge <= 7'b0_010_010;
4'b0110:   ge <= 7'b0_000_010;
4'b0111:   ge <= 7'b1_111_000;
4'b1000:   ge <= 7'b0_000_000;
4'b1001:   ge <= 7'b0_010_000;
default:    ge <= 7'b1_000_000;
endcase//十位的输出
always@(posedge sys_clk or negedge sys_rst_n)if(sys_rst_n == 1'b0)shi <= 7'b1_111_111;else    if(sw0 == 1'd0)shi <= 7'b1_111_111;else    case(bcd[7:4])
4'b0000:shi <= 7'b1_000_000;
4'b0001:shi <= 7'b1_111_001;
4'b0010:shi <= 7'b0_100_100;
4'b0011:shi <= 7'b0_110_000;
4'b0100:shi <= 7'b0_011_001;
4'b0101:shi <= 7'b0_010_010;
4'b0110:shi <= 7'b0_000_010;
4'b0111:shi <= 7'b1_111_000;
4'b1000:shi <= 7'b0_000_000;
4'b1001:shi <= 7'b0_010_000;
default:    shi <= 7'b1_000_000;
endcase//百位的输出
always@(posedge sys_clk or negedge sys_rst_n)if(sys_rst_n == 1'b0)bai <= 7'b1_111_111;else    if(sw0 == 1'd0)bai <= 7'b1_111_111;else    case(bcd[10:8])
3'b000:bai <= 7'b1_000_000;
3'b001:     bai <= 7'b1_111_001;
3'b010:     bai <= 7'b0_100_100;
3'b011:     bai <= 7'b0_110_000;
3'b100:     bai <= 7'b0_011_001;
3'b101:     bai <= 7'b0_010_010;
3'b110:     bai <= 7'b0_000_010;
3'b111:     bai <= 7'b1_111_000;
/* 4'b1000: shi <= 7'b0_000_000;
4'b1001:    shi <= 7'b0_010_000; */
default:    bai <= 7'b1_000_000;
endcaseendmodulemodule binTobcd(input	[8:0]	bin,//二进制数output	[10:0]	bcd//BCD码);reg [3:0] ones;
reg [3:0] tens;
reg [2:0] hundreds;
integer i;//移3进位的算法
always @(*) beginones 		= 4'd0;tens 		= 4'd0;hundreds 	= 3'd0;for(i = 8; i >= 0; i = i - 1) beginif (ones >= 4'd5) 		ones = ones + 4'd3;if (tens >= 4'd5) 		tens = tens + 4'd3;if (hundreds >= 4'd5)	hundreds = hundreds + 4'd3;hundreds = {hundreds[1:0],tens[3]};tens	 = {tens[2:0],ones[3]};ones	 = {ones[2:0],bin[i]};endend	assign bcd = {hundreds, tens, ones};endmodule

测试代码:

`timescale 1ns/1ns //时间参数
module tb_led();reg            sys_clk     ;//模拟时钟信号
reg            sys_rst_n   ; //模拟复位信号
reg    [9:0]   sw_in       ; //模拟拨码
reg            key_in1     ; //模拟按键
reg            key_in2     ;//模拟按键wire    [9:0]led_out      ;//模拟灯的输出wire   [6:0] ge1         ;
wire   [6:0] shi1        ;
wire  [6:0]  bai1        ;wire   [6:0] ge2         ;
wire   [6:0] shi2        ;
wire  [6:0]  bai2     ;//模拟输入
initialbeginsys_clk = 1'b1;//开始的赋值sys_rst_n <= 1'b0;sw_in <= 10'd0;key_in1 <= 1'b1;key_in2 <= 1'b1;#20sys_rst_n <= 1'b1;//复位#5_000_00sw_in[0] <= 1'b1;//SW0拨上#1_000_000_000key_in1 <= 1'b0;//按下按键key0#200key_in1 <= 1'b1;#200    sw_in[9:1] <= 9'b0_0000_0001;//拨码输入1hz#1_000_000_000sw_in[9:1] <= 9'b1_0001_0001;//等1s拨码输入频率#1_000_000_000sw_in[9:1] <= 9'b1_1011_0001;//等1s拨码输入频率#5000key_in2 <= 1'b0;//按下key1#200key_in2 <= 1'b1;#500_000_000key_in1 <= 1'b0;//等0.5s,按下key0#200key_in1 <= 1'b1;#1_000_000_000sw_in[9:1] <= 9'b0_0000_0000;//等1s拨码输入频率#1_000_000_000sw_in[9:1] <= 9'b0_0000_0001;//等1s拨码输入频率#1_000_000_000sw_in[0] <= 1'b0;//等1s拨码sw0拨下endalways #10 sys_clk = ~sys_clk;//时钟生成//调用模块
led led_inst
(.sys_clk   (sys_clk)  ,.sys_rst_n (sys_rst_n)  ,  .sw_in     (sw_in)  ,  .key_in1   (key_in1)  ,  .key_in2   (key_in2)  , .led_out   (led_out)   ,.ge1       (ge1)  ,.shi1      (shi1)  ,.bai1      (bai1)  ,.ge2       (ge2)  ,.shi2      (shi2)  ,.bai2      (bai2));
endmodule

这篇关于FPGA课程设计(拨码控制流水灯)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/188686

相关文章

SpringBoot请求参数接收控制指南分享

《SpringBoot请求参数接收控制指南分享》:本文主要介绍SpringBoot请求参数接收控制指南,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录Spring Boot 请求参数接收控制指南1. 概述2. 有注解时参数接收方式对比3. 无注解时接收参数默认位置

Spring Security+JWT如何实现前后端分离权限控制

《SpringSecurity+JWT如何实现前后端分离权限控制》本篇将手把手教你用SpringSecurity+JWT搭建一套完整的登录认证与权限控制体系,具有很好的参考价值,希望对大家... 目录Spring Security+JWT实现前后端分离权限控制实战一、为什么要用 JWT?二、JWT 基本结构

Android实现两台手机屏幕共享和远程控制功能

《Android实现两台手机屏幕共享和远程控制功能》在远程协助、在线教学、技术支持等多种场景下,实时获得另一部移动设备的屏幕画面,并对其进行操作,具有极高的应用价值,本项目旨在实现两台Android手... 目录一、项目概述二、相关知识2.1 MediaProjection API2.2 Socket 网络

用js控制视频播放进度基本示例代码

《用js控制视频播放进度基本示例代码》写前端的时候,很多的时候是需要支持要网页视频播放的功能,下面这篇文章主要给大家介绍了关于用js控制视频播放进度的相关资料,文中通过代码介绍的非常详细,需要的朋友可... 目录前言html部分:JavaScript部分:注意:总结前言在javascript中控制视频播放

Python异步编程中asyncio.gather的并发控制详解

《Python异步编程中asyncio.gather的并发控制详解》在Python异步编程生态中,asyncio.gather是并发任务调度的核心工具,本文将通过实际场景和代码示例,展示如何结合信号量... 目录一、asyncio.gather的原始行为解析二、信号量控制法:给并发装上"节流阀"三、进阶控制

使用DrissionPage控制360浏览器的完美解决方案

《使用DrissionPage控制360浏览器的完美解决方案》在网页自动化领域,经常遇到需要保持登录状态、保留Cookie等场景,今天要分享的方案可以完美解决这个问题:使用DrissionPage直接... 目录完整代码引言为什么要使用已有用户数据?核心代码实现1. 导入必要模块2. 关键配置(重点!)3.

SpringSecurity 认证、注销、权限控制功能(注销、记住密码、自定义登入页)

《SpringSecurity认证、注销、权限控制功能(注销、记住密码、自定义登入页)》SpringSecurity是一个强大的Java框架,用于保护应用程序的安全性,它提供了一套全面的安全解决方案... 目录简介认识Spring Security“认证”(Authentication)“授权” (Auth

python之流程控制语句match-case详解

《python之流程控制语句match-case详解》:本文主要介绍python之流程控制语句match-case使用,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐... 目录match-case 语法详解与实战一、基础值匹配(类似 switch-case)二、数据结构解构匹

Spring Security注解方式权限控制过程

《SpringSecurity注解方式权限控制过程》:本文主要介绍SpringSecurity注解方式权限控制过程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、摘要二、实现步骤2.1 在配置类中添加权限注解的支持2.2 创建Controller类2.3 Us

Python中如何控制小数点精度与对齐方式

《Python中如何控制小数点精度与对齐方式》在Python编程中,数据输出格式化是一个常见的需求,尤其是在涉及到小数点精度和对齐方式时,下面小编就来为大家介绍一下如何在Python中实现这些功能吧... 目录一、控制小数点精度1. 使用 round() 函数2. 使用字符串格式化二、控制对齐方式1. 使用