FPGA学习(7)-线性序列机原理与应用,不同类型的LED控制开关

news2024/10/23 12:11:55

目录

1.实现1

 2.实现2

 2.1方法1

2.2方法2 

3.实现3

3.1实验现象 

4.实现4

4.1分析

4.2实现过程

4.2.1 counter的计数

4.2.2 en_counter2的判断

4.2.3 en_counter0的判断 

 4.2.4 对case语句加判断条件

4.3仿真结果 

​编辑

4.4实验现象 


1.实现1

1.实现以下图示功能,直接计到1s时,counter清零,在0~0.25s之间高电平,0.25s~1s之间低电平。

 2.仿真波形

3.问题,像C那样写却不行,只能在某个时刻点亮才行。

计数器相当于时间的一把尺子,用计数器的每一个计数值当作一个刻度,能够得到各个需要的时刻,在指定的时刻,执行需要的操作。 

 2.实现2

实现下图方式的方波:

 2.1方法1

跟第一种方式一样,找出每个高低信号跳变的位置。要减小仿真时间,多个参数下如何设定最简便的参数,按照之前的思路需要加4个参数。这里直接用他们都共有的倍数来进行,仿真时间缩小1000倍。

parameter MCNT = 1000;
    
    always@(posedge clk or negedge reset)
    if(!reset)
    counter<=1'b0;
    else if (counter == 125_000*MCNT-1)
    counter<=1'b0;
    else
    counter<=counter+1'd1;
    
    always@(posedge clk or negedge reset)
    if(!reset)
    led<=1'b0;
    else if(counter == 0)
        led<=1'd1;
    else if(counter == 125_00*MCNT)
        led<=1'd0;
    else if(counter == 375_00*MCNT)
        led<=1'd1;
    else if(counter == 75_000*MCNT)
        led<=1'd0;

仿真波形: 

2.2方法2 

把划分成几个区间,取每个时间间隔的最大公约数,分成几段。用一个计数器记到该最大公约数,再用一个计数器记到9,每次对应不同的高低电平。

源文件代码,中间有段if else 没用begin...end为什么也没问题。

module led_light1(
    reset,
    clk,
    led
    );
    
    input reset;
    input clk;
    output reg led;
    reg [26:0]counter;
    parameter MCNT = 12500_000-1;
    
    always@(posedge clk or negedge reset)
    if(!reset)
        counter <= 1'd0;
    else if (counter == MCNT)
        counter <= 1'd0;
    else
        counter <= counter+1'd1;
    
    reg [3:0]counter1;
    always@(posedge clk or negedge reset)
    if(!reset)
        counter1 <= 1'd0;
    else if(counter == MCNT)
        if(counter1 == 9)
            counter1 <= 1'd0;
        else
            counter1 <= counter1+1'd1;   
    else
        counter1=counter1;
    
    always@(posedge clk or negedge reset)
    if(!reset)
        led<=1'd0;
    else begin
        case(counter1)
        0:led <= 1'd1;
        1:led <= 1'd0;
        2:led <= 1'd0;
        3:led <= 1'd1;
        4:led <= 1'd1;
        5:led <= 1'd1;
        6:led <= 1'd0;
        7:led <= 1'd0;
        8:led <= 1'd0;
        9:led <= 1'd0;
        default:led <= led;
        endcase
    end  
endmodule

 仿真结果:

3.实现3

 即直接新建立一个数值,让counter1依次计数,每次计数后,切换到对应的SW状态。

源文件:

module led_light2(
    reset,
    clk,
    led,
    SW
    );
    
    input reset;
    input clk;
    input [7:0]SW;
    output reg led;
    reg [26:0]counter;
    parameter MCNT = 12500_000-1;
    
    always@(posedge clk or negedge reset)
    if(!reset)
        counter <= 1'd0;
    else if (counter == MCNT)
        counter <= 1'd0;
    else
        counter <= counter+1'd1;
    
    reg [2:0]counter1;
    always@(posedge clk or negedge reset)
    if(!reset)
        counter1 <= 1'd0;
    else
        counter1 <= counter1+1'd1;   
    
    always@(posedge clk or negedge reset)
    if(!reset)
        led<=1'd0;
    else begin
        case(counter1)
        0:led <= SW[0];
        1:led <= SW[1];
        2:led <= SW[2];
        3:led <= SW[3];
        4:led <= SW[4];
        5:led <= SW[5];
        6:led <= SW[6];
        7:led <= SW[7];
        default:led <= led;
        endcase
    end  
endmodule

仿真文件:

 改变SW的值,进行延时后,再进行改变。

`timescale 1ns / 1ns
module led_light_tb();
reg clk;
reg reset;
wire led;
reg [7:0]SW;
led_light2 led_light2(
    .reset(reset),
    .clk(clk),
    .led(led),
    .SW(SW)
);

initial clk=1;
always #10 clk=~clk;

initial begin
    reset =0;
    SW=8'b10101010;
    #201;
    reset=1;
    #2000_000_000;
    SW=8'b00000001;
    #2000_000_000;
    $stop;
end
endmodule

前半段符合10101010 

2s后变为00000001,仿真图如下:

代码中counter1的值等每次计数来一次才加一次,不然就不是按照设定的值增加。 将间隔时间设为1s。

3.1实验现象 

开关设置为10101010时,LED灯每间隔1s闪烁。多上拉几个,就多亮会儿。

4.实现4

4.1分析

实现下图所示的动态变化,1s时间是可变的,只是这里指代为1s。学习计数器不是一定要不停的计数,而是要有静有动,中途可暂停。

 需要用到三个计数器,counter1~3。

counter0:用于SW切换的间隔时间0.25s

1.计数最大值:计数的最大值为0.25*10^9/20-1=12500_000-1。

2.计数的条件为前面1s的空闲时间到,8个状态马上开始或已经开始。

3.清零条件:计数到最大值,或还在前1s的空闲状态中。

counter1:计数当前第几个LED的状态计数器

1.计数最大值:7

2.计数条件:counter0计满1次加1

3.清零条件:计数到最大值

counter2:1s的空闲状态计数器

1.计数最大值:1*10^9/20-1=5000_0000-1。

2.计数条件:8个LED状态切换完毕,counter1计满。

3.清零条件:计数至最大值

4.2实现过程

4.2.1 counter的计数

对于counter0来说,需要一会儿计数一会儿停,所以加入一个变量en_counter,当en_counter=1时,开始计数,否则就停下。

always@(posedge clk or negedge reset)
begin
    if(!reset)
        counter0 <= 1'd0;
    else if (en_counter0)
    begin
        if(counter0 == MCNT)
            counter0 <= 1'd0;
        else
            counter0 <= counter0+1'd1;
    end
end

对于counter1,直接counter0计满一次加1,满8次清0。

always@(posedge clk or negedge reset)
    if(!reset)
        counter1 <= 1'd0;
    else if (counter0 == 7)
        counter1 <= 1'd0;   
    else if (counter0 == MCNT)
        counter1 <= counter1+1'd1;   
    else
        counter1 <= counter1;

对于counter2,空闲段计数,8个0.25s内不计数。

always@(posedge clk or negedge reset)
begin
    if(!reset)
        counter2 <= 1'd0;
    else if(en_counter2)
    begin
        if(counter2 == MCNT2)
            counter2 <= 1'd0;
        else
            counter2 <= counter2+1'd1;
    end
end

4.2.2 en_counter2的判断

counter2保持计数的条件有:

(1)从复位到正常运行,需要立即开始计数。

(2)每次LED8个状态切换完,重新开始计数。

counter2停止计数的条件有:

(1)计数满1s

总结:

(1)复位时,让en_counter2置1。

(2)counter1==7 时,让en_counter2置1。

(3)counter2计满时,让en_counter2置0。

 关于第(2)个条件,我认为不附加sw计数也能满足,因为counter1==7已经都记录了8个状态了。

always@(posedge clk or negedge reset)
begin
    if(!reset)
        en_counter2 <= 1'd1;
    else if(counter1 ==7)
        en_counter2 <= 1'd1;
    else if(counter2 <= MCNT2)
        en_counter2 <=1'd0;
    else
        en_counter2 <= en_counter2;
end

4.2.3 en_counter0的判断 

counter0保持计数的条件:

(1)counter2计数计满的时候

counter0停止计数的条件;

(1)程序复位,counter0需要停止。

(2)LED的8个状态完成,counter停止。

总结:

(1)复位时,en_counter0置0;

(2)counter1==7时,en_counter0置0;

(3)counter2计满最大值时,en_counter0置1;

always@(posedge clk or negedge reset)
begin
    if(!reset)
        en_counter0 <= 1'd0;
    else if(counter1 ==7)
        en_counter0 <= 1'd0;
    else if(counter2 <= MCNT2)
        en_counter0 <=1'd1;
    else
        en_counter0 <= en_counter0;
end

 4.2.4 对case语句加判断条件

 led在空闲状态置0,所以要么en_counter1==0,要么en_counter2==1。

always@(posedge clk or negedge reset)
begin
if(!reset)
    led <= 1'd0;
else if(en_counter2 ==1)
    led <= 1'd0;
else begin
    case(counter1)
    0:led <= SW[0];
    1:led <= SW[1];
    2:led <= SW[2];
    3:led <= SW[3];
    4:led <= SW[4];
    5:led <= SW[5];
    6:led <= SW[6];
    7:led <= SW[7];
    default:led <= led;
    endcase
end
end  

4.3仿真结果 

出现问题,并未按预期波形出现。

在en_counter处加入了附加的判断条件,else if((counter1 ==7) && (counter0 == MCNT)),仿真波形还是不对。

 错误1,将这里的判断用了非阻塞符号,修改后,仿真波形仍不对。

 

en_counter0的错误也是如此。仿真波形在第二段开始出现错误,counter2计数一直为0。

问题在于:程序中counter1计数到7时就要清0,而此时在counter1计数到6完成时,counter0就已经记到0.25s了,在下一个时钟脉冲来临时,counter1被清0,所以后面的en_counter2永远不会置1。 

 

最后仿真结果相对应,led显示的波形与SW相反的原因是,在工程文件的case语句,从左到右是对应从低到高。

4.4实验现象 

 SW全部拉低,LED灯不亮;SW全部拉低,LED灯熄1s,亮2s。SW一高一低,LED熄灭一s,闪烁2s。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2221563.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

qt QBuffer详解

QBuffer 是 Qt 提供的一个类&#xff0c;用于在内存中操作二进制数据。它是 QIODevice 的一个子类&#xff0c;允许你将数据读入和写出到一个内存缓冲区&#xff0c;而不需要与文件系统交互。 常用方法 构造函数: QBuffer(QObject *parent nullptr): 创建一个空的 QBuffer 对象…

vue项目启动报错:exit status 1

vue项目启动报错&#xff1a;&#xff08;vite构建&#xff09; npm ERR! code ELIFECYCLE npm ERR! errno 1 npm ERR! Exit status 1 如下图所示&#xff1a; 解决 检查node版本&#xff0c;Vite 需要 Node.js 版本 18 或 20 我之前是 14.16.1&#xff0c;更换成 20.0.0 就可…

Flink 06 聚合操作入门学习,真不难

抛砖引玉 让你统计1小时内每种商品的销售额&#xff0c;用Flink 该怎么实现。 还是让你统计1小时内每种商品的销售额&#xff0c;但是要过滤掉退款的订单&#xff0c;用Flink 该怎么实现。 学了本文两个操作&#xff0c;不信你还不会。 AggregateFunction ❝ 通常用于对数据…

【决策树】- 二分法处理连续值

二分法处理连续值 在决策树算法中&#xff0c;处理连续特征通常采用二分法&#xff0c;将其转化为离散特征。此方法通过寻找最佳分割点&#xff0c;将连续特征划分为两个区间。 1. 原理 二分法的核心思想是将连续值特征转换为离散值&#xff0c;以便于决策树的构建。通过选择…

[Linux#67][IP] 报头详解 | 网络划分 | CIDR无类别 | DHCP动态分配 | NAT转发 | 路由器

目录 一. IP协议头格式 学习任何协议前的两个关键问题 IP 报头与有效载荷分离 分离方法 为什么需要16位总长度 如何交付 二. 网络通信 1.IP地址的划分理念 2. 子网管理 3.网络划分 CIDR&#xff08;无类别域间路由&#xff09; 目的IP & 当前路由器的子网掩码 …

R语言机器学习算法实战系列(九)决策树分类算法 (Decision Trees Classifier)

禁止商业或二改转载,仅供自学使用,侵权必究,如需截取部分内容请后台联系作者! 文章目录 介绍教程下载数据加载R包导入数据数据预处理数据描述数据切割调节参数构建模型模型的决策树预测测试数据评估模型模型准确性混淆矩阵模型评估指标ROC CurvePRC Curve特征的重要性保存模…

TCP协议四次挥手

1.第一次挥手&#xff1a;客户端发送FIN报文&#xff0c;请求断开连接。这一过程为主动关闭。客户端由ESTABLISHED转换为FIN-WAIT-1。 FIN和ACK置为1&#xff0c;表示这是一个请求结束报文。seqU表示在之前客户端已经发送的字节数。ackV则表示服务端向客户端发送确认消息累计的…

磁盘分区工具 DiskGenius Pro v5.5.0.1488 中文汉化版

DiskGenius 是一款专家级数据恢复软件&#xff0c;集数据恢复、硬盘分区、系统备份还原等多种功能于一身的超级工具软件&#xff0c;功能全面&#xff0c;安全可靠。可以提供磁盘的数据找回、备份、分区、修复、删除、格式化等操作&#xff0c;也能帮助用户修复磁盘坏道、彻底删…

从零构建大模型训练流程及原理(一)

这是一个大模型训练的系列文章&#xff0c;将从零开始手把手带大家构建大模型训练全流程。话不多说&#xff0c;开始发车~什么是大语言模型 1. LLMs是什么&#xff1f; 大型语言模型&#xff08;LLMs&#xff09;是基于Transformer架构的深度学习模型&#xff0c;旨在理解、生…

[枚举坤坤]二进制枚举基础

我们都知道数据是以二进制形式存储在计算机中的。当我们使用十进制数进行编程时&#xff08;如a10&#xff09;实际上计算机要先进行一步转码&#xff0c;将其化为二进制的形式进行计算。如果在编程的过程中我们可以直接越过转码这一步去操纵二进制形式进行运算&#xff0c;程序…

EMNLP 2024 个性化/风格化 文本生成 论文汇总(19篇主会论文)

引言&#xff1a;调研&#xff0c;搬砖… &#x1f60a; &#x1f318;&#x1f317;&#x1f316; &#x1f607; ✅ 笔者简介&#xff1a;Wang Linyong&#xff0c;NPU&#xff0c;2023级&#xff0c;计算机技术 研究方向&#xff1a;文本生成、大语言模型 文章目录 1 Perso…

【C++】STL----map和set

&#x1f525;个人主页&#x1f525;&#xff1a;孤寂大仙V &#x1f308;收录专栏&#x1f308;&#xff1a;C从小白到高手 &#x1f339;往期回顾&#x1f339;&#xff1a;[C]二叉搜索树 &#x1f516; 流水不争&#xff0c;争的是滔滔不息 文章目录 一、set和map的简介setm…

Java设计模式梳理:行为型模式(策略,观察者等)

行为型模式 行为型模式关注的是各个类之间的相互作用&#xff0c;将职责划分清楚&#xff0c;使得我们的代码更加地清晰。 策略模式 策略模式太常用了&#xff0c;所以把它放到最前面进行介绍。它比较简单&#xff0c;我就不废话&#xff0c;直接用代码说事吧。 下面设计的…

某ai gpt的bug

某ai gpt的bug 背景 遇到了一个奇怪的现象&#xff1a; 输入内容 2024-10-21 10:09:31,052 ERROR o.a.j.t.JMeterThread: Test failed! java.lang.IllegalArgumentException:输出结果

Android开发教程二维码扫描功能

Android开发教程二维码扫描功能 二维码扫描大一点的app都有的功能&#xff0c;因为扫一下真的很方便 一、思路&#xff1a; 用zxing库 二、效果图&#xff1a; 看视频更加直观点&#xff1a; Android开发教程实战案例源码分享-二维码扫描功能 三、关键代码&#xff1a; c…

音频声音怎么调大?将音频声音调大的几个简单方法

音频声音怎么调大&#xff1f;在现代生活中&#xff0c;音频内容无处不在&#xff0c;从在线课程和播客到音乐和电影&#xff0c;音频已经成为我们获取信息和娱乐的重要方式。然而&#xff0c;许多人在使用音频时可能会遇到一个常见问题&#xff1a;音频声音太小&#xff0c;无…

手机投屏到电脑上的scrcpy软件 scrcpy v2.4

下载&#xff1a;https://drive.uc.cn/s/b1285b1fb9f94?public1 最近的工作需要用到用手机演示一些操作&#xff0c;但是手机屏幕比较小&#xff0c;我就想把手机投到我的电脑上&#xff0c;然后电脑连接投影仪就行了。 scrcpy是一款开源的软件&#xff0c;在githus上可以下…

少儿编程学习,如何走,之点评一二

前言&#xff1a; 不少孩子在少儿机构学习编程的家长跟我反馈&#xff0c;机构学习孩子学了记不住&#xff0c;有些家孩子索性就不去&#xff0c;不愿意再谈编程学习之事。 从一位专业信息学教师出身的老师&#xff0c;稍作点评一二&#xff1a; 【同时也引用了一些主流媒体的…

力扣OJ算法题:合并两个有序链表

—————————————————————————————————————————— 正文开始 OJ算法题&#xff1a;合并两个有序链表 思路 创建一个新的空链表&#xff08;可以用malloc优化&#xff09;和两个指针L1、L2分别指向两个链表&#xff0c;遍历两个链表&am…

python poetry包管理的安装和使用

目录 设置国内(清华)镜像源和升级pip 安装poetry pycharm中使用 常用的poetry命令 本文背景为已经安装好python 设置国内(清华)镜像源和升级pip pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple python -m pip install --upgrade pip 安装po…