欢迎各位朋友关注“郝旭帅电子设计团队”,本篇为各位朋友介绍基于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的计算器设计---第一版的更多相关文章

  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. UE4中HTC Vive 手柄如何抓取物体

    想知道 HTC Vive 手柄如何抓取物体? HTC Vive 的手柄有许多功能,在游戏里你可以用手柄射箭,可以用手柄拾取木棍等等,但是这些是如何设置的呢?来看看我们的公开课教程吧. 本期教程为上半部 ...

  2. docker 应用篇————docker开篇[一]

    前言 因为最近看了一些docker 底层,然后希望把docker应用先编写出来,然后进行细节篇讲解,比如说docker 的底层是如何实现的之类的话题. 正文 docker 这东西怎么说呢?有一些东西需 ...

  3. 建设工程工程量清单计价规范2008最新分析报告ppt

    2008版<计价规范>颁布的背景 国务院从2003年起,在全国范围开展清理拖欠工程款.清理拖欠农民工工资的活动.最高人民法院于2004年9月29日发布了<关于审理建设工程施工合同纠纷 ...

  4. 4.CSS层次选择器

    1.后代选择器:在某个元素的后面 1 /*后代选择器*/ 2 body p{ 3 background: crimson; 4 } 2.子选择器:仅一代 1 /*子选择器*/ 2 body>p{ ...

  5. 力扣423(java)-从英文中重建数字(中等)

    题目: 给你一个字符串 s ,其中包含字母顺序打乱的用英文单词表示的若干数字(0-9).按 升序 返回原始的数字. 示例 1: 输入:s = "owoztneoer"输出:&quo ...

  6. P10160 [DTCPC 2024] Ultra 题解

    [题目描述] 给你一个 \(01\) 序列,你可以进行如下操作若干次(或零次): 将序列中形如 \(101\cdots01\) 的一个子串(即 \(1(01)^k\),\(k\ge 1\))替换成等长 ...

  7. Dragonfly 基于 P2P 的文件和镜像分发系统

    简介: 业界软件生态在优化 HTTPS 的性能上也做了诸多探索,传统的软件优化方案在软件层面的优化无法满足流量日益增长的速度,CPU 硬件加速成为业界一个通用的解决方案. 作者:孙景文.吴迪   背景 ...

  8. [FAQ] CodeLlama GGUF 文件下载

    hf-mirror: https://hf-mirror.com/TheBloke/CodeLlama-7B-GGUFmodelscope: https://modelscope.cn/models/ ...

  9. 2019-8-31-C#-如何引用-WshShell-类

    title author date CreateTime categories C# 如何引用 WshShell 类 lindexi 2019-08-31 16:55:58 +0800 2019-3- ...

  10. 实验2 C语言分支与循环基础应用编程 王刚202383310053

    1 #include<stdio.h> 2 #include<stdlib.h> 3 #include<time.h> 4 #define N 5 5 int ma ...