基于FPGA的计算器设计---第一版
欢迎各位朋友关注“郝旭帅电子设计团队”,本篇为各位朋友介绍基于FPGA的计算器设计---第一版。
功能说明:
1. 计算器的显示屏幕为数码管。
2. 4x4矩阵键盘作为计算器的输入设备。
3. 计算任意两位正整数的加减乘除。
4. 当减法结果出现负数时(一个小的数字减去一个大的数字),数码管需要显示负数。
5. 除法计算时,结果只输出商的整数,小数自动抹去。
注:矩阵键盘输入0-9,表示0-9;10表示加号(数码管显示A);11表示减号(数码管显示b);12表示乘号(数码管显示C);13表示除号(数码管显示d);14表示等于号。
使用平台:本次设计应用Altera的平台设计(芯片:EP4CE10F17C8N)。
作者QQ:746833924
说明:本篇设计中不涉及到IP和原语,代码在其他平台依然可以适用;当其他板卡电路不同时,会导致不同的现象出现,如有需要修改代码请联系作者;如需作者使用的板卡,请联系作者;
设计思想如下:

keyboard4x4_drive模块为4x4矩阵键盘的驱动模块,负责检测4x4矩阵键盘被按下的按键信息;cal_logic模块为计算逻辑和控制显示信息的逻辑,负责根据矩阵键盘传递的按键信息进行计算,根据计算的过程控制输出需要显示的信息;seven_tube_drive(七段数码管驱动)模块负责将产生的数字逻辑显示到数码管上。
keyboard4x4_drive模块的设计思想和具体设计可以参考本公众号,获取方式:关注本公众号,发送“FPGA矩阵键盘驱动第一版”。
cal_logic模块的设计思想:利用状态机设计进行实现。共有八个状态。
localparam STATE_IDLE = 8'b0000_0001;
localparam STATE_NUM1_1 = 8'b0000_0010;
localparam STATE_NUM1_2 = 8'b0000_0100;
localparam STATE_OPCODE = 8'b0000_1000;
localparam STATE_NUM2_1 = 8'b0001_0000;
localparam STATE_NUM2_2 = 8'b0010_0000;
localparam STATE_EQUAL = 8'b0100_0000;
localparam STATE_RESULT = 8'b1000_0000;
STATE_IDLE :空闲初始化状态;
STATE_NUM1_1 :输入第一个操作数的第一位。
STATE_NUM1_2 :输入第一个操作数的第二位。
STATE_OPCODE :输入操作符。
STATE_NUM2_1 :输入第二个操作数的第一位。
STATE_NUM2_2 :输入第二个操作数的第二位。
STATE_EQUAL :输入等于号。
STATE_RESULT :计算输出结果。

复位结束后,在IDLE状态,初始化所有的中间变量和输出,之后进入STATE_NUM1_1。
STATE_IDLE : begin
state <= STATE_NUM1_1;
num1 <= 8'd0;
num2 <= 8'd0;
opcode <= 4'd0;
show_data <= 24'hfffff0;
end
在STATE_NUM1_1状态中,当输入的数字0-9,认为是第一个操作数的第一位(显示到最后的数码管),然后进入STATE_NUM1_2,准备接收第一个操作数的第二位;如果输入数字10-13,认为是第一个操作数为0(数码管显示第一个操作数0和操作符),并且存储好操作符,进入STATE_NUM2_1,准备接收第二个操作数的第一位;如果输入为其他数字,则认为无效输入。
STATE_NUM1_1 : begin
if (flag == 1'b1)
if (press_num < 4'd10) begin
state <= STATE_NUM1_2;
num1 <= {4'd0, press_num};
show_data <= {20'hfffff, press_num};
end
else
if (press_num > 4'd9 && press_num < 4'd14) begin
num1 <= 8'd0;
state <= STATE_NUM2_1;
opcode <= press_num;
show_data <= {show_data[19:0], press_num};
end
else
state <= STATE_NUM1_1;
else
state <= STATE_NUM1_1;
end
在STATE_NUM1_2状态中,当输入的数字0-9,认为是第一个操作数的第二位(将第一个操作数的第一位和第二位都显示到数码管上)(计算得出num1),然后进入STATE_OPCODE,准备接收操作符;如果输入数字10-13,认为是第一个操作数为STATE_NUM1_1输入的数字(数码管显示第一个操作数和操作符),并且存储好操作符,进入STATE_NUM2_1,准备接收第二个操作数的第一位;如果输入为其他数字,则认为无效输入。
STATE_NUM1_2 : begin
if (flag == 1'b1)
if (press_num < 4'd10) begin
state <= STATE_OPCODE;
num1 <= num1 * 10 + press_num;
show_data <= {show_data[19:0], press_num};
end
else
if (press_num > 4'd9 && press_num < 4'd14) begin
state <= STATE_NUM2_1;
opcode <= press_num;
show_data <= {show_data[19:0], press_num};
end
else
state <= STATE_NUM1_2;
else
state <= STATE_NUM1_2;
end
在STATE_OPCODE状态中,如果输入数字10-13,认为是第一个操作数为STATE_NUM1_1和STATE_NUM1_2输入的数字(数码管显示第一个操作数和操作符),并且存储好操作符,进入STATE_NUM2_1,准备接收第二个操作数的第一位;如果输入为其他数字,则认为无效输入。
STATE_OPCODE : begin
if (flag == 1'b1)
if (press_num > 4'd9 && press_num < 4'd14) begin
state <= STATE_NUM2_1;
opcode <= press_num;
show_data <= {show_data[19:0], press_num};
end
else
state <= STATE_OPCODE;
else
state <= STATE_OPCODE;
end
在STATE_NUM2_1状态中,如果输入数字0-9,认为是第二个操作数的第一个数字(数码管显示第一个操作数、操作符和第二个操作数的第一个数字),进入STATE_NUM2_2,准备接收第二个操作数的第二位;如果输入为其他数字,则认为无效输入。
STATE_NUM2_1 : begin
if (flag == 1'b1)
if (press_num < 4'd10) begin
state <= STATE_NUM2_2;
num2 <= press_num;
show_data <= {show_data[19:0], press_num};
end
else
state <= STATE_NUM2_1;
else
state <= STATE_NUM2_1;
end
在STATE_NUM2_2状态中,当输入的数字0-9,认为是第二个操作数的第二位(将第一个操作数、操作符和第二个操作数显示到数码管上)(计算得出num2),然后进入STATE_EQUAL,准备接收等于号;如果输入数字14,认为是等于号,进入STATE_RESULT状态。如果输入为其他数字,则认为无效输入。
STATE_NUM2_2 : begin
if (flag == 1'b1)
if (press_num < 4'd10) begin
state <= STATE_EQUAL;
num2 <= num2 * 10 + press_num;
show_data <= {show_data[19:0], press_num};
end
else
if (press_num == 4'd14) begin
state <= STATE_RESULT;
end
else
state <= STATE_NUM2_2;
else
state <= STATE_NUM2_2;
end
在STATE_EQUAL状态中,如果输入数字14,认为是等于号,进入STATE_RESULT状态。如果输入为其他数字,则认为无效输入。
STATE_EQUAL : begin
if (flag == 1'b1)
if (press_num == 4'd14) begin
state <= STATE_RESULT;
end
else
state <= STATE_EQUAL;
else
state <= STATE_EQUAL;
end
在STATE_RESULT状态中,只有按下复位才可以再次进行计算;在本状态中根据第一个操作数、操作符和第二个操作数进行计算,并且将计算的结果作为输出。
STATE_RESULT : begin
state <= STATE_RESULT;
show_data[23:20] <= result[15] ? 4'he : 4'h0;
show_data[19:16] <= result[15] ? (-result)/10000 : result/10000;
show_data[15:12] <= result[15] ? (-result)/1000 % 10 : result/1000 % 10;
show_data[11:8] <= result[15] ? (-result)/100 % 10 : result/100 % 10;
show_data[7:4] <= result[15] ? (-result)/10 % 10 : result/10 % 10;
show_data[3:0] <= result[15] ? (-result) % 10 : result % 10;
end
七段数码管为普通六位一体的共阳极数码,采用动态驱动的方式,在此不再赘述。
仿真时,需要利用4x4矩阵键盘的仿真模型,否则不容易仿真(相关代码,下方链接提供)。
calculator calculator_inst(
.clk (clk ),
.rst_n (rst_n ),
.keyboard4x4_row (keyboard4x4_row),
.keyboard4x4_col (keyboard4x4_col),
.sel (sel ),// 数码管位选信号
.seg (seg ) // 数码管段选信号
);
keyboard4x4 keyboard4x4_inst(
.press_num (press_num ),
.keyboard4x4_col (keyboard4x4_col),
.keyboard4x4_row (keyboard4x4_row)
);
模拟2+8;
press_data(5'd2);
press_data(5'd10);
press_data(5'd8);
press_data(5'd14);



模拟55-8;
press_data(5'd5);
press_data(5'd5);
press_data(5'd11);
press_data(5'd8);
press_data(5'd14);



其他模拟情况,可以根据设计者自由模拟;
注意在计算一次完成后,需要进行一次复位(相当于计算器中的清除),然后才可以进行下一次计算。
讲解和演示视频链接如下:
https://www.bilibili.com/video/BV1ew4m1S7Av/?vd_source=b5405faeab8632f02533bcbfc5e52e55
本设计所有内容(设计代码、设计工程)链接为:
链接:https://pan.baidu.com/s/1WKkfXU7XInPBNCUSvgs5Pw
提取码:s0f8
本篇内容中有部分资源来源于网络,如有侵权,请联系作者。
如果您觉得本公众号还不错的话,可以推给身边的朋友们,感谢并祝好!
基于FPGA的计算器设计---第一版的更多相关文章
- 基于FPGA的DDS设计(一)
最近在学习基于FPGA的DDS设计,借此机会把学习过程记录下来,当作自己的学习笔记也希望能够帮助到学习DDS的小伙伴. DDS(Direct Digital Synthesizer)直接数字合成器,这 ...
- 基于FPGA的DDS设计(二)
在DDS设计中,如果相位累加器每个时钟周期累加1,就会输出频率为195.313KHz的波形.如果每个时钟周期累加2,就会输出频率为2*195.313KHz的波形·······,如果每两个时钟周期累加1 ...
- 38.基于FPGA的FIR设计二
利用fdatool工具生成的滤波器系数与用代码生成的系数不一致,在网上查询得知,fdatool生成的滤波器系数是有符号小数,而且是浮点型,而代码生成的滤波器系数是定点型有符号数,故不一样. 浮点型数据 ...
- 优化基于FPGA的深度卷积神经网络的加速器设计
英文论文链接:http://cadlab.cs.ucla.edu/~cong/slides/fpga2015_chen.pdf 翻译:卜居 转载请注明出处:http://blog.csdn.net/k ...
- 自己动手写CPU(基于FPGA与Verilog)
大三上学期开展了数字系统设计的课程,下学期便要求自己写一个单周期CPU和一个多周期CPU,既然要学,就记录一下学习的过程. CPU--中央处理器,顾名思义,是计算机中最重要的一部分,功能就是周而复始地 ...
- 基于FPGA的XPT2046触摸控制器设计
基于FPGA的XPT2046触摸控制器设计 小梅哥编写,未经许可,文章内容和所涉及代码不得用于其他商业销售的板卡 本实例所涉及代码均可通过向 xiaomeige_fpga@foxmail.com 发 ...
- 基于FPGA的HDMI显示设计(三)
上一篇:基于FPGA的VGA显示设计(二) 10月10日 ~ 20日期间实习,令我万万没想到的是实习题目是 “便携式高清电视显示屏测试系统原型设计” 也就是 “基于FPGA的视频显示”. 实习要求用 ...
- 基于FPGA的VGA显示设计(二)
上一篇:基于FPGA的VGA显示设计(一) 参照 CrazyBingo 的 基于FPGA的VGA可移植模块终极设计代码 的工程代码风格,模块化处理了上一篇的代码,并增加了一点其它图形. 顶层 ...
- 基于FPGA的VGA可移植模块终极设计【转】
本文转载自:http://www.cnblogs.com/lueguo/p/3373643.html 略过天涯 基于FPGA的VGA可移植模块终极设计 一.VGA的诱惑 首先,VGA的驱动,这事, ...
- 基于FPGA的SPI FLASH控制器设计
1.SPI FLASH的基本特征 本文实现用FPGA来设计SPI FLASH,FLASH型号为W25Q128BV.支持3种通信方式,SPI.Dual SPI和Quad SPI.FLASH的存储单元无法 ...
随机推荐
- Godot UI线程,Task异步和消息弹窗通知
目录 前言 线程安全 全局消息IOC注入 消息窗口搭建 最简单的消息提示 简单使用 仿Element UI ElementUI 效果 简单的Label样式 如何快速加载多个相同节点 修改一下,IOC按 ...
- c# 后端与前端时间戳的转换
C# DateTime与时间戳转换 C# DateTime与时间戳的相互转换,包括JavaScript时间戳和Unix的时间戳. 1. 什么是时间戳 首先要清楚JavaScript与Unix的时间戳的 ...
- 前端之多线程 ---webworker
一.啥是workerJavaScript为单线程,worker则为JavaScript创建多线程环境.使用场景如:计算文件hash,计算大于1G的文件hash过程是很慢的,但由于要将hash传给后端, ...
- 《c#高级编程》第4章C#4.0中的更改(六)——动态绑定
一.概念 下面是一些代码示例,说明C#动态绑定的上述特点: 1. 延迟确定类型 ```dynamic obj = GetDynamicObject(); // 获取动态对象obj.DoSomethin ...
- DBJ,DB,CJJ,CECS 标准区别及全套下载教程
DBJ DBJ开头的标准是地方建筑标准:D--地方. B--标准. J--建筑. <中华人民共和国标准化法>将中国标准分为国家标准.行业标准.地方标准(DB).企业标准(Q/)四级.地方标 ...
- 打CS2的时候提示 error:unrec stream cmd 2090 82a
打CS2的时候提示 error:unrec stream cmd 2090 82a 打着打着就卡住,然后提示error:unrec stream cmd 2090 82a 找了一圈,进bios把内存条 ...
- ping的常用方法
ping的常用方法 ping +ip tcping +ip+端口号(例如 tcping 127.0.0.1 8080) telnet +ip+端口号 nc -nzv +ip+端口号(linux用)
- 力扣454(java&python)-四数相加 II(中等)
题目: 给你四个整数数组 nums1.nums2.nums3 和 nums4 ,数组长度都是 n ,请你计算有多少个元组 (i, j, k, l) 能满足: 0 <= i, j, k, l &l ...
- 牛客网-SQL专项训练25
①批处理是指包含一条或多条T-SQL语句的语句组,下列选项中,关于批处理的规则描述正确的是(B) 解析: A选项:不能定义一个check约束后,立即在同一个批处理中使用: C选项:Create def ...
- iofsstat:帮你轻松定位 IO 突高,前因后果一目了然 | 龙蜥技术
简介:磁盘被打满到底是真实的业务需求量上来了呢?还是有什么野进程在占用 IO? iofsstat 帮你精准定位. 编者按:sysAK(system analyse kit),是龙蜥社区系统运维 SI ...