欢迎各位朋友关注“郝旭帅电子设计团队”,本篇为各位朋友介绍基于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模块的设计思想:利用状态机设计进行实现。共有八个状态。

  1. localparam STATE_IDLE = 8'b0000_0001;
  2. localparam STATE_NUM1_1 = 8'b0000_0010;
  3. localparam STATE_NUM1_2 = 8'b0000_0100;
  4. localparam STATE_OPCODE = 8'b0000_1000;
  5. localparam STATE_NUM2_1 = 8'b0001_0000;
  6. localparam STATE_NUM2_2 = 8'b0010_0000;
  7. localparam STATE_EQUAL = 8'b0100_0000;
  8. 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。

  1. STATE_IDLE : begin
  2. state <= STATE_NUM1_1;
  3. num1 <= 8'd0;
  4. num2 <= 8'd0;
  5. opcode <= 4'd0;
  6. show_data <= 24'hfffff0;
  7. end

在STATE_NUM1_1状态中,当输入的数字0-9,认为是第一个操作数的第一位(显示到最后的数码管),然后进入STATE_NUM1_2,准备接收第一个操作数的第二位;如果输入数字10-13,认为是第一个操作数为0(数码管显示第一个操作数0和操作符),并且存储好操作符,进入STATE_NUM2_1,准备接收第二个操作数的第一位;如果输入为其他数字,则认为无效输入。

  1. STATE_NUM1_1 : begin
  2. if (flag == 1'b1)
  3. if (press_num < 4'd10) begin
  4. state <= STATE_NUM1_2;
  5. num1 <= {4'd0, press_num};
  6. show_data <= {20'hfffff, press_num};
  7. end
  8. else
  9. if (press_num > 4'd9 && press_num < 4'd14) begin
  10. num1 <= 8'd0;
  11. state <= STATE_NUM2_1;
  12. opcode <= press_num;
  13. show_data <= {show_data[19:0], press_num};
  14. end
  15. else
  16. state <= STATE_NUM1_1;
  17. else
  18. state <= STATE_NUM1_1;
  19. end

在STATE_NUM1_2状态中,当输入的数字0-9,认为是第一个操作数的第二位(将第一个操作数的第一位和第二位都显示到数码管上)(计算得出num1),然后进入STATE_OPCODE,准备接收操作符;如果输入数字10-13,认为是第一个操作数为STATE_NUM1_1输入的数字(数码管显示第一个操作数和操作符),并且存储好操作符,进入STATE_NUM2_1,准备接收第二个操作数的第一位;如果输入为其他数字,则认为无效输入。

  1. STATE_NUM1_2 : begin
  2. if (flag == 1'b1)
  3. if (press_num < 4'd10) begin
  4. state <= STATE_OPCODE;
  5. num1 <= num1 * 10 + press_num;
  6. show_data <= {show_data[19:0], press_num};
  7. end
  8. else
  9. if (press_num > 4'd9 && press_num < 4'd14) begin
  10. state <= STATE_NUM2_1;
  11. opcode <= press_num;
  12. show_data <= {show_data[19:0], press_num};
  13. end
  14. else
  15. state <= STATE_NUM1_2;
  16. else
  17. state <= STATE_NUM1_2;
  18. end

在STATE_OPCODE状态中,如果输入数字10-13,认为是第一个操作数为STATE_NUM1_1和STATE_NUM1_2输入的数字(数码管显示第一个操作数和操作符),并且存储好操作符,进入STATE_NUM2_1,准备接收第二个操作数的第一位;如果输入为其他数字,则认为无效输入。

  1. STATE_OPCODE : begin
  2. if (flag == 1'b1)
  3. if (press_num > 4'd9 && press_num < 4'd14) begin
  4. state <= STATE_NUM2_1;
  5. opcode <= press_num;
  6. show_data <= {show_data[19:0], press_num};
  7. end
  8. else
  9. state <= STATE_OPCODE;
  10. else
  11. state <= STATE_OPCODE;
  12. end

在STATE_NUM2_1状态中,如果输入数字0-9,认为是第二个操作数的第一个数字(数码管显示第一个操作数、操作符和第二个操作数的第一个数字),进入STATE_NUM2_2,准备接收第二个操作数的第二位;如果输入为其他数字,则认为无效输入。

  1. STATE_NUM2_1 : begin
  2. if (flag == 1'b1)
  3. if (press_num < 4'd10) begin
  4. state <= STATE_NUM2_2;
  5. num2 <= press_num;
  6. show_data <= {show_data[19:0], press_num};
  7. end
  8. else
  9. state <= STATE_NUM2_1;
  10. else
  11. state <= STATE_NUM2_1;
  12. end

在STATE_NUM2_2状态中,当输入的数字0-9,认为是第二个操作数的第二位(将第一个操作数、操作符和第二个操作数显示到数码管上)(计算得出num2),然后进入STATE_EQUAL,准备接收等于号;如果输入数字14,认为是等于号,进入STATE_RESULT状态。如果输入为其他数字,则认为无效输入。

  1. STATE_NUM2_2 : begin
  2. if (flag == 1'b1)
  3. if (press_num < 4'd10) begin
  4. state <= STATE_EQUAL;
  5. num2 <= num2 * 10 + press_num;
  6. show_data <= {show_data[19:0], press_num};
  7. end
  8. else
  9. if (press_num == 4'd14) begin
  10. state <= STATE_RESULT;
  11. end
  12. else
  13. state <= STATE_NUM2_2;
  14. else
  15. state <= STATE_NUM2_2;
  16. end

在STATE_EQUAL状态中,如果输入数字14,认为是等于号,进入STATE_RESULT状态。如果输入为其他数字,则认为无效输入。

  1. STATE_EQUAL : begin
  2. if (flag == 1'b1)
  3. if (press_num == 4'd14) begin
  4. state <= STATE_RESULT;
  5. end
  6. else
  7. state <= STATE_EQUAL;
  8. else
  9. state <= STATE_EQUAL;
  10. end

在STATE_RESULT状态中,只有按下复位才可以再次进行计算;在本状态中根据第一个操作数、操作符和第二个操作数进行计算,并且将计算的结果作为输出。

  1. STATE_RESULT : begin
  2. state <= STATE_RESULT;
  3. show_data[23:20] <= result[15] ? 4'he : 4'h0;
  4. show_data[19:16] <= result[15] ? (-result)/10000 : result/10000;
  5. show_data[15:12] <= result[15] ? (-result)/1000 % 10 : result/1000 % 10;
  6. show_data[11:8] <= result[15] ? (-result)/100 % 10 : result/100 % 10;
  7. show_data[7:4] <= result[15] ? (-result)/10 % 10 : result/10 % 10;
  8. show_data[3:0] <= result[15] ? (-result) % 10 : result % 10;
  9. end

七段数码管为普通六位一体的共阳极数码,采用动态驱动的方式,在此不再赘述。

仿真时,需要利用4x4矩阵键盘的仿真模型,否则不容易仿真(相关代码,下方链接提供)。

  1. calculator calculator_inst(
  2.  
  3. .clk (clk ),
  4. .rst_n (rst_n ),
  5.  
  6. .keyboard4x4_row (keyboard4x4_row),
  7. .keyboard4x4_col (keyboard4x4_col),
  8.  
  9. .sel (sel ),// 数码管位选信号
  10. .seg (seg ) // 数码管段选信号
  11. );
  12.  
  13. keyboard4x4 keyboard4x4_inst(
  14.  
  15. .press_num (press_num ),
  16.  
  17. .keyboard4x4_col (keyboard4x4_col),
  18. .keyboard4x4_row (keyboard4x4_row)
  19. );

模拟2+8;

  1. press_data(5'd2);
  2. press_data(5'd10);
  3. press_data(5'd8);
  4. press_data(5'd14);

模拟55-8;

  1. press_data(5'd5);
  2. press_data(5'd5);
  3. press_data(5'd11);
  4. press_data(5'd8);
  5. press_data(5'd14);

其他模拟情况,可以根据设计者自由模拟;

注意在计算一次完成后,需要进行一次复位(相当于计算器中的清除),然后才可以进行下一次计算。

讲解和演示视频链接如下:
https://www.bilibili.com/video/BV1ew4m1S7Av/?vd_source=b5405faeab8632f02533bcbfc5e52e55
     本设计所有内容(设计代码、设计工程)链接为:

链接:https://pan.baidu.com/s/1WKkfXU7XInPBNCUSvgs5Pw

提取码:s0f8

本篇内容中有部分资源来源于网络,如有侵权,请联系作者。

如果您觉得本公众号还不错的话,可以推给身边的朋友们,感谢并祝好!

基于FPGA的计算器设计---第一版的更多相关文章

  1. 基于FPGA的DDS设计(一)

    最近在学习基于FPGA的DDS设计,借此机会把学习过程记录下来,当作自己的学习笔记也希望能够帮助到学习DDS的小伙伴. DDS(Direct Digital Synthesizer)直接数字合成器,这 ...

  2. 基于FPGA的DDS设计(二)

    在DDS设计中,如果相位累加器每个时钟周期累加1,就会输出频率为195.313KHz的波形.如果每个时钟周期累加2,就会输出频率为2*195.313KHz的波形·······,如果每两个时钟周期累加1 ...

  3. 38.基于FPGA的FIR设计二

    利用fdatool工具生成的滤波器系数与用代码生成的系数不一致,在网上查询得知,fdatool生成的滤波器系数是有符号小数,而且是浮点型,而代码生成的滤波器系数是定点型有符号数,故不一样. 浮点型数据 ...

  4. 优化基于FPGA的深度卷积神经网络的加速器设计

    英文论文链接:http://cadlab.cs.ucla.edu/~cong/slides/fpga2015_chen.pdf 翻译:卜居 转载请注明出处:http://blog.csdn.net/k ...

  5. 自己动手写CPU(基于FPGA与Verilog)

    大三上学期开展了数字系统设计的课程,下学期便要求自己写一个单周期CPU和一个多周期CPU,既然要学,就记录一下学习的过程. CPU--中央处理器,顾名思义,是计算机中最重要的一部分,功能就是周而复始地 ...

  6. 基于FPGA的XPT2046触摸控制器设计

    基于FPGA的XPT2046触摸控制器设计 小梅哥编写,未经许可,文章内容和所涉及代码不得用于其他商业销售的板卡 本实例所涉及代码均可通过向 xiaomeige_fpga@foxmail.com  发 ...

  7. 基于FPGA的HDMI显示设计(三)

    上一篇:基于FPGA的VGA显示设计(二) 10月10日 ~ 20日期间实习,令我万万没想到的是实习题目是 “便携式高清电视显示屏测试系统原型设计” 也就是 “基于FPGA的视频显示”. 实习要求用 ...

  8. 基于FPGA的VGA显示设计(二)

    上一篇:基于FPGA的VGA显示设计(一)     参照 CrazyBingo 的 基于FPGA的VGA可移植模块终极设计代码  的工程代码风格,模块化处理了上一篇的代码,并增加了一点其它图形. 顶层 ...

  9. 基于FPGA的VGA可移植模块终极设计【转】

    本文转载自:http://www.cnblogs.com/lueguo/p/3373643.html 略过天涯   基于FPGA的VGA可移植模块终极设计 一.VGA的诱惑 首先,VGA的驱动,这事, ...

  10. 基于FPGA的SPI FLASH控制器设计

    1.SPI FLASH的基本特征 本文实现用FPGA来设计SPI FLASH,FLASH型号为W25Q128BV.支持3种通信方式,SPI.Dual SPI和Quad SPI.FLASH的存储单元无法 ...

随机推荐

  1. nginx重新整理——————http请求的11个阶段中的find_config[十三]

    前言 简单介绍一下find_config 与 preaccess 阶段. 正文 find_config 很大一部分工作是进行location的匹配. 来一张图看下location指令和merge_sl ...

  2. CentOS 7.9编译安装Python-3.10.13

    目录 查看CentOS版本.系统默认gcc版本.Python版本和pip版本 部署Python-3.10.13 测试 将yum中的Python版本修改为系统原来的2.7.5版本 查看CentOS版本. ...

  3. 国内首家!百度智能云宣布支持Llama3全系列训练推理

    继18日Llama3的8B.70B大模型发布后,百度智能云千帆大模型平台19日宣布在国内首家推出针对Llama3全系列版本的训练推理方案,便于开发者进行再训练,搭建专属大模型,现已开放邀约测试. 目前 ...

  4. echarts使用与踩坑

    0.踩坑点 1.当图表不显示在页面(display:none)执行resize可能会导致图表样式混乱 1. 官网示例 import * as echarts from 'echarts'; // 基于 ...

  5. 这10款VS Code神仙插件,嵌入式程序员必备

    大家好,我是知微! 嵌入式软件开发工程师平时可能更多的是使用Source Insight.Keil.IAR来阅读代码,写代码. VSCode大家都听说过,功能十分强大,而且免费! 或许是因为这款软件上 ...

  6. 蚂蚁一面:GC垃圾回收时,内存分配和回收策略有哪些?

    文章首发于公众号:腐烂的橘子 蚂蚁面试主要为电话面试,期间也会要求使用编辑器手写算法题.作为一线互联网大厂,Java 基础知识是必备的,其中垃圾回收也是面试过程中的重中之重. Java 内存的自动管理 ...

  7. 斩获大奖|阿里云PolarDB-X引领云原生分布式数据库新时代

    简介:阿里云原生分布式数据库PolarDB-X荣获"2021年度最佳分布式数据库". 12月15-16日,以"引领分布式云变革 助力湾区数字经济"为主题的全球分 ...

  8. [FAQ] swagger-php 支持 Authorization Bearer token 校验的用法

    @OA\SecurityScheme 可以是 Controller 层面也可以是 Action 层面. 类型 type="apiKey". in="header" ...

  9. 通过WebRTC简单实现媒体共享

    通过WebRTC简单实现媒体共享 媒体协商 在设置本地描述符(offer/answer)前,我们总是需要将媒体添加到连接中,只有这样在描述符中才能包含需要共享的媒体信息,除非你不需要共享媒体. 在实际 ...

  10. WPF 简单判断主线程界面是否卡顿的方法

    本文来告诉大家如何使用简单的代码判断当前的软件的 UI 线程或界面是否卡顿 在后台线程调用如下代码即可用来判断是否卡顿 private static async Task<bool> Ch ...