本帖最后由 雾盈 于 2016-9-1 13:59 编辑
六位四则运算计算器(9)移位控制模块(shift)
雾盈 2016-9-1
雾盈FPGA笔记汇总目录
一、写字前面
这是我的计算器项目的最后一个模块,也是核心模块。它就像交通控制枢纽一样,来自四面八方的信号都在它的指挥调度下严格按照预定好的时序规则进行输入输出,并参与其他模块的运行工作。
模块多,信号多的复杂系统设计都应该有这么一个控制模块中心,这样各个模块的工作能够井然有序的进行,整个系统才能完美运行。
二、框图
 
三、功能及代码介绍
这个模块具体有两个功能,数码管移位显示和系统控制核心。
1)先说数码管移位显示功能
因为上一个模块(键盘模块)输进来的就是BCD码,所以要想数码管移位显示很简单,就一句话。
2)再说系统控制核心。
在上面的框图里,我们已经看到了,整个系统几乎所有模块的信号都经过了shift模块。
模块整体思路:用一个状态机将按键输入和计算运行过程表达了出来。
状态机:
用了七个状态,
IDLE:闲置状态。对各寄存器清零。
S0:
检测按键输入
若输入为操作数0-9,则在按键抬起标志key_flag每到来一次时,数据移位寄存器就左移一位。
若输入为操作符a-e,则把数据移位寄存器赋值给操作数(A)输出bcd_data_a,并且通过拉高shift_done 一个电平来告诉下个模块,此次移位已经结束。Flag_ab 赋值低电平,标志着这个操作数为A 。最后,跳入下一状态S1。
S1:
在这个状态里,把该输出的值都输出了,等待操作数A完成BCD转二进制的标志信号(bcd_done)到来,到来后跳入下一状态S2。
S2:
这个状态是为了消去还在数据移位寄存器里的操作符,防止操作符被当做操作数B里的高位参与运算。
S3.S4 里的内容和S0,S1,S2 差不多,直接讲S5。
S5:
在S5状态里,等待bin2bcd(二进制转BCD)转换完毕的信号到来,将结果输出给数码管(smg),最后调回闲置状态IDLE。
主体状态机讲完了。
为了讲的更清楚,我再把经过shift模块的信号和我的代码结合起来讲一下。
对照着框图从左到右,从上到下说。
1.先说按键模块(keyscan_top)输进去的key_flag ,key_real[3:0]
Key_real 就是消抖后的真实按键了。
参与移位及其他信号输出,移位代码如下:
Key_flag 是按键抬起标志位,取按键使能的上升沿。
如果没有这个按键抬起标志,在时钟1kHz的快速扫描频率下,你用手按下的瞬间,它已经检测到了无数次按键使能。于是,你的数码管显示情况就是:按下一个键,六个数码管显示同样的数字,出现同样情况的同学可以检查一下自己程序的这一块。
这个抬起信号的处理是按键模块完成的,代码如下:
其中,key_vld为按键使能,assign语句目的是取按键使能的上升沿
2.输出给smg(数码管)模块的data_dsp[23:0]
这个信号是把移位的结果不经任何处理直接送给数码管去显示,出来的效果,就是你按下一个键数码管就向左移位一次。
相关代码如下:
3.输出给bcd2bin(BCD转二进制)模块的信号:
bcd_data_a , bcd_data_b,shift_done,flag_ab
Bcd2bin模块输进来的信号: bcd_done
Bcd_data_a,bcd_data_b 是移位后的两位操作数 A 和B,相关代码:
至此,整个计算器项目就讲完了。
计算器项目总结:在整个计算器项目设计过程中,我感受最深的是,一定要严格控制系统里各个模块信号的变化,而控制的方法就是多设置一些start或者done信号,在start或done信号到来时,分模块才能启动工作,这样出来的结果都会是正确的,即使错了,也能很快查找到问题出在哪里。
还有就是自顶向下的设计思想和如何快速找到设计思路,这个我在开头已经谈过了。
这次,真的算是讲完了,希望你能设计出功能更完善的计算器,也希望你可以得到些微的来自雾盈FPGA笔记的微小的帮助。
希望我们都越来越好!
附上源代码:
 
|