verilog键盘输入示例代码及分析(摩尔型有限状态机)

这篇具有很好参考价值的文章主要介绍了verilog键盘输入示例代码及分析(摩尔型有限状态机)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

往昔鸳鸯戏水,而今不相依偎,美景良辰纵然抚媚亦徒留伤悲。----《美人画卷》


本代码是一生一芯项目中,南京大学nvboard开源项目键盘扫描示例代码。我们抛开上层连接不谈,分析一下这个代码。同时我自己也理清一下思路,不然总是感觉些许混乱,或者说,明明用51单片机写的时序接收这么好理解,为什么这个程序我没有一眼看出来他在干什么。因为这段代码本身确实蕴含着一个设计思想,请务必读到最后。
南京大学数电实验网站:点此
nvboard GitHub(即本文源码出处):https://github.com/NJU-ProjectN/nvboard.git
源代码著作权归原作者所有。本文完全尊重原作者的著作权,仅引用、注释以供学习,不参与网站创作激励,不具有商业、盈利性质。

0. 源代码

module ps2_keyboard(clk,resetn,ps2_clk,ps2_data);
    input clk,resetn,ps2_clk,ps2_data;

    reg [9:0] buffer;        // ps2_data bits
    reg [3:0] count;  // count ps2_data bits
    reg [2:0] ps2_clk_sync;

    always @(posedge clk) begin
        ps2_clk_sync <=  {ps2_clk_sync[1:0],ps2_clk};
    end

    wire sampling = ps2_clk_sync[2] & ~ps2_clk_sync[1];

    always @(posedge clk) begin
        if (resetn == 0) begin // reset
            count <= 0;
        end
        else begin
            if (sampling) begin
              if (count == 4'd10) begin
                if ((buffer[0] == 0) &&  // start bit
                    (ps2_data)       &&  // stop bit
                    (^buffer[9:1])) begin      // odd  parity
                    $display("receive %x", buffer[8:1]);
                end
                count <= 0;     // for next
              end else begin
                buffer[count] <= ps2_data;  // store ps2_data
                count <= count + 3'b1;
              end
            end
        end
    end

endmodule

1. 相关知识

键盘传输过来的有两个数据,分别是ps2_clk,ps2_data,即键盘的时钟,以及按键的通码断码。
扫描码:被规定的、某键被按下/弹起时所送出的代码。
通码是:约定的、按键按下是键盘送出的编码,现代键盘基本统一。
断码是:F0h加此按键的通码,如释放 W 键时输出的断码为F0h 1Dh,分两帧传输。

下图是键盘扫描表,原图出自南京大学数字电子电路实验课程网站,更多资料可以上网去搜。
verilog键盘输入示例代码及分析(摩尔型有限状态机)

下图是传输时序图,原图出自南京大学数字电子电路实验课程网站,网址点此
verilog键盘输入示例代码及分析(摩尔型有限状态机)
即:一帧数据共9位,最后一位P是奇偶校验(奇校验)。

2.代码分析

代码先定义了一个三位的时钟变量ps2_clk_sync,通过一个死循环,每次把ps2_clk时钟上的采样送入最低位,并丢弃最高位,即形成了一个三位的时间队列。
因为每次最新的采样放入的是最低位0位,所以计算的ps2_clk_sync[2] & ~ps2_clk_sync[1]。若为下降沿,则sampling为1,上升沿为0。

但是读到这里相信都不免有些疑问:
为什么不ps2_clk_sync[1] & ~ps2_clk_sync[0]?这样岂不更加及时?或者直接把ps2_clk设置成always的敏感变量,不是更一步到位?这样做的意义是什么?
请先思考,文末有笔者认为的原因。

reg [2:0] ps2_clk_sync;

always @(posedge clk) begin
        ps2_clk_sync <=  {ps2_clk_sync[1:0],ps2_clk};
    end
    
wire sampling = ps2_clk_sync[2] & ~ps2_clk_sync[1];

如此,则sampling内存放的是当前是否是下降沿;若当前是下降沿,则判断了count == 4'd10,count就是个计数器,每次count <= count + 3'b1;,所以就是判断是否接收到了十位。看清这里是4'd10就好,我之前没看清以为是4'd10卡了半天。然后就是判断首位是否为0、1,并且使用了校验。
这里可以学习一下他写的奇偶校验,^buffer[9:1],需要注意的是这里的^缩减运算符,其运算方式是

ans = ((buffer[1] ^ buffer[2]) ^ buffer[3])^ ······

即从最低位开始向上计算。最后的结果也是一个布尔值。
如果上述判断条件都通过,就输出buffer。

但是你是否有这样的疑问:第十位是stop空位,并且奇偶校验在第九次收到之后就可以进行了,为什么非要等这个空的帧入队之后,第十一次才开始判断呢?

 reg [9:0] buffer;        // ps2_data bits
 reg [3:0] count;  // count ps2_data bits

 always @(posedge clk) begin
        if (resetn == 0) begin // reset
            count <= 0;
        end
        else begin
            if (sampling) begin
              if (count == 4'd10) begin
                if ((buffer[0] == 0) &&  // start bit
                    (ps2_data)       &&  // stop bit
                    (^buffer[9:1])) begin      // odd  parity
                    $display("receive %x", buffer[8:1]);
                end
                count <= 0;     // for next
              end else begin
                buffer[count] <= ps2_data;  // store ps2_data
                count <= count + 3'b1;
              end
            end
        end
    end

3. 摩尔型有限状态机

南大这个网站把状态机和键盘放在一起,让我很是不理解,明明两个风马牛不相及的东西,放一起干什么,但是仔细一想,其实是因为这段代码使用了摩尔型有限状态机的思想。
下面摘录一下摩尔型状态机的知识,同样参考南大的数电实验网站。

Moore 型有限状态机的输出信号只与有限状态机的当前状态有关,与输入信号的当前值无关,输入信号的当前值只会影响到状态机的次态,不会影响状态机当前的输出。即Moore 型有限状态机的输出信号是直接由状态寄存器译码得到。 Moore型有限状态机在时钟CLK信号有效后经过一段时间的延迟,输出达到稳定值。即使在这个时钟周期内输入信号发生变化,输出也会在这个完整的时钟周期内保持稳定值而不变。输入对输出的影响要到下一个时钟周期才能反映出来。Moore有限状态机最重要的特点就是将输入与输出信号隔离开来。

观察这段代码,不难发现使用的就是Moore(摩尔)型有限状态机的思想。因为:

  1. 它对时间序列进行了一个存储,当前时序判断前两个时序是否存在下降沿,而不是接收到时钟信号立即判断下降沿。
  2. 对于buffer也不是收到第十位(count == 9)就立即输出,而是第十位也放入buffer内后才进行校验、输出。如果存在第十一位的话,其实现在已经是第十一位了。

看来前面我们对为什么要存储时间序列的疑问解决了。甚好。

回忆斑驳微醉,叹相思未随,几春几秋几段轮回。----《美人画卷》文章来源地址https://www.toymoban.com/news/detail-467594.html

到了这里,关于verilog键盘输入示例代码及分析(摩尔型有限状态机)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 摩尔状型态机和米利型状态机区别

    摩尔型(Moore):输出只与状态有关与输入无关 米利型(Mealy):输出不仅与状态有关还和输入有关 例如:我们进行检测序列:1101 输入/输出   图 1摩尔型状态机   图 2米利型状态机 总结 :        我们通过对比可以看出,摩尔型状态机要比米利型状态机多一个状态,同时

    2024年02月12日
    浏览(34)
  • uniapp - [微信小程序平台] 实现输入支付密码键盘弹框,uniapp小程序端底部弹起密码输入键盘组件效果,类似电商平台支付密码、弹出支付密码输入框、交易密码(详细示例源码,一键复制开箱即用!)

    在uniapp微信小程序端平台,详细实现底部弹出输入支付密码框组件,自定义密码输入框键盘功能(密码自动带星号、黑点保护隐私,自定义数字键盘),类似电商在付款时输入支付密码的组件。 直接复制组件源码,改下样式就能用了。 复制运行即可查看效果。

    2024年02月03日
    浏览(124)
  • Unity状态机代码示例(ChatGPT生成)

    Q: Unity状态机代码示例,要求至少有四个状态 A: 下面是一个基于Unity引擎实现的简单状态机示例代码,使用C#编写。该状态机包含四个状态:待机、移动、攻击、和受伤。在待机状态下,程序将等待用户按下“空格”键,然后转移到移动状态,并播放移动动画。在移动状态下,

    2023年04月18日
    浏览(39)
  • 前端状态管理与有限状态机

    当下前端流行的框架,都是用状态来描述界面(state = view),可以说前端开发实际上就是在维护各种状态(state),这已经成为目前前端开发的共识。 复制代码 View = ViewModel(Model); 理想情况下,ViewModel 是纯函数,给定相同的 Model,产出相同的 View。 state = view 很好理解,但如何在 vi

    2024年03月15日
    浏览(47)
  • 有限状态机(FSM)

    目录 一、什么是有限状态机 二、如何实现 1、简述原理 2、 具体实现 有限状态机就是一种用来描述对象不同状态之间如何相互转换的模型,这里最简单的例子就是动画状态机 animator 我们每一次都只能处于一个状态,每一个状态又可以通过一定的条件相互转换。 1、简述原理

    2024年02月11日
    浏览(45)
  • 编译原理二:有限状态机

    有限状态机是一种 计算模型 ,它可以 接受一串输入并根据一组状态转移规则进行状态转移,最终输出一个结果 。有限状态机可以分为两种类型: 确定性有限状态机(DFA) 和 非确定性有限状态机(NFA) 。 DFA 是一种状态机,它的 每个状态都有一条出边对应每个输入符号,

    2024年02月11日
    浏览(40)
  • Unity有限状态机

    一、引言 在游戏开发中,经常会遇到游戏角色或实体具有多种状态,并且在不同状态之间需要切换的情况。例如,一个角色可能处于行走、奔跑、跳跃等不同的状态,并且根据玩家的输入或游戏逻辑,在这些状态之间进行切换。为了管理这些状态及其之间的转换,我们可以使

    2024年02月03日
    浏览(50)
  • FPGA设计Verilog基础之数据类型的作用和特点、常量和变量的代码示例详解

    注意:后续技术分享,第一时间更新,以及更多更及时的技术资讯和学习技术资料 ,将在公众号 CTO Plus 发布,请关注公众号: CTO Plus 在Verilog中,有多种数据类型可供使用,包括位向量类型、整数类型、实数类型、布尔型、时间类型和字符串类型等。下面详细介绍Verilog的所

    2024年02月03日
    浏览(42)
  • 探索FSM (有限状态机)应用

    我们是袋鼠云数栈 UED 团队,致力于打造优秀的一站式数据中台产品。我们始终保持工匠精神,探索前端道路,为社区积累并传播经验价值。。 本文作者:木杪 有限状态机(FSM) 是计算机科学中的一种数学模型,可用于表示和控制系统的行为。它由一组状态以及定义在这些

    2023年04月20日
    浏览(35)
  • 在Unity中实现有限状态机

    本文将介绍Unity开发中的有限状态机,给出对应的实现代码。 有限状态机借鉴了图灵机的思想,可以看作是最简单的图灵机。 它包含4要素: 现态 条件 动作 次态 基础的有限状态机不复杂,无非是几个状态定义成类,提供OnEnter/OnExit/OnUpdate方法,这里直接根据需求给出对应的

    2024年02月05日
    浏览(50)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包