FPGA按一下按键,对应端口输出单个脉冲

对于FPGA的verilog语言,,,规定一个变量不能在多个always中被赋值.但是可以在多个alway块中做判断--结合状态机思想

module state(key,led,clk);
input key;//输入按键
input clk;//输入时钟48M

output reg led;//输出led

reg state=0;//记录按钮状态
reg[27:0] cnt=0;//计数器

always@(*)
begin
    if(key == 0)//按下了
    state = 1;  //状态置一
    else if(cnt==48000000)//到了计数值
    state = 0;//状态复位
end

always@(posedge clk)
begin
    if(state == 1)//如果状态置一
    cnt<=cnt+1'b1;//开始计数
    else
    cnt<=0;//松开或没有按下,清零
end

always@(posedge clk)
begin
  if(state == 1)//如果状态置一
  led <=1;//灯亮
  else
  led <=0;
end

endmodule

按下按键灯就会亮,如果一直按着灯就会一直亮(

if(key == 0)//按下了
    state = 1;  //状态置一
    else if(cnt==48000000)//到了计数值
    state = 0;//状态复位

),可以改变一下代码,变成按下松开灯亮一秒后灭,就是加一个松手检测,或者做别的修改...

 一开始请教的群里的大神给的代码--状态机思想

module relay(input clk,//输入时钟
             input rst,//输入复位
                 input a,  //输入信号
                 output reg b//输出
                 );

reg[3:0] current_state=0,next_state=0;//现在的状态,下一个状态
reg[27:0] state_cnt=0;//状态计数

localparam sIdle_state=0;//空闲
localparam sInput_high=1;//输入高
localparam sInput_low=2;//输入低
localparam sOutput_pluse=3;//输出

always@(posedge clk or negedge rst)
begin
    if(~rst)
    current_state <= sIdle_state;//复位空闲
    else
    current_state <= next_state;//把下一个状态给它
end

always@(*)
begin
    case(current_state)
    sIdle_state://空闲态
    begin
        if(a==1)//输入为高
        next_state <= sInput_high;//赋为输入高
        else
        next_state <= current_state;//赋为空闲
    end
    
    sInput_high://输入高
    begin
        if(a==0)
        next_state = sInput_low;//赋为输入低
        else
        next_state = current_state;//赋为空
    end
    
    sInput_low://输入低
    begin
        next_state = sOutput_pluse;//赋为端口输出模式
    end
    
    sOutput_pluse:
    begin
        if(state_cnt == 48000000)
        next_state = sIdle_state;
        else
        next_state = current_state;//现在的状态
    end
    
    default: next_state = sIdle_state;
    
    endcase
end


always@(posedge clk or negedge rst)
begin
    if(~rst)
    begin
        b<=0;
    end
    else
    begin
        case(next_state)
        sIdle_state://如果是空闲状态
        begin
        
        end
        sOutput_pluse://如果是输出状态
            b<=1;//输出高
        default:
            b<=0;
        
        endcase
    end
end

always@(posedge clk or negedge rst)
begin
    if(~rst)
        state_cnt <= 0;
        else if(next_state != current_state)//如果上一个状态和现在的不一样
        state_cnt<=0;
    else
        state_cnt<=state_cnt+1'b1;
    
end

endmodule

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏技术博客

编写高质量代码改善C#程序的157个建议[用抛异常替代返回错误、不要在不恰当的场合下引发异常、重新引发异常时使用inner Exception]

  自从.NET出现后,关于CLR异常机制的讨论就几乎从未停止过。迄今为止,CLR异常机制让人关注最多的一点就是“效率”问题。其实,这里存在认识上的误区,因为正...

1142
来自专栏13blog.site

Mybatis-Generator生成Mapper文件中<if test="criteria.valid">的问题解答

写在前面 由于开源了项目的缘故,很多使用了My Blog项目的朋友遇到问题也都会联系我去解决,有的是把问题留在项目的issue里提出,有的是在我的私人博客里留言...

3396
来自专栏C/C++基础

腾讯2016春季校园实习招聘技术岗初试(一面)问题汇总(CC++后台)

2016.4.11日广州参加了腾讯的CC++后台技术一面,安全技术类的面试。面试官人很温和,经历了大概70分钟的问答,特将遇到的面试问题汇总如下,自己总结学习,...

861
来自专栏java一日一条

Java线程面试题 Top 50

不管你是新程序员还是老手,你一定在面试中遇到过有关线程的问题。Java语言一个重要的特点就是内置了对并发的支持,让Java大受企业和程序员的欢迎。大多数待遇丰厚...

1192
来自专栏java一日一条

深入理解 Java 中的 try-with-resource

众所周知,所有被打开的系统资源,比如流、文件或者Socket连接等,都需要被开发者手动关闭,否则随着程序的不断运行,资源泄露将会累积成重大的生产事故。

1602
来自专栏优启梦

渗透测试中的域名伪装原理

今天在《网络渗透测试--保护网络安全的技术、工具、过程》一书中看到了一个关于对恶意链接进行域名伪装的方法,以前从不知道的一个方法,特此记录下来:

2095
来自专栏积累沉淀

Python快速学习第十二天--生成器和协程

yield指令,可以暂停一个函数并返回中间结果。使用该指令的函数将保存执行环境,并且在必要时恢复。 生成器比迭代器更加强大也更加复杂,需要花点功夫好好理解贯...

8275
来自专栏程序你好

C# API中的模型和它们的接口设计

952
来自专栏刘望舒

设计模式(十五)状态模式

前言 建议在阅读本文前先阅读设计模式(十一)策略模式这篇文章,虽说状态模式和策略模式的结构几乎是相同的,但是它们所解决的问题是不同的,读完这两篇文章你就会有了答...

2046
来自专栏Play & Scala 技术分享

Scala之美 - Future & map & flatMap

3758

扫码关注云+社区

领取腾讯云代金券