2024寒假练—基于小脚丫FPGA制作的两位十进制计算器
该项目使用了小脚丫FPGA套件STEP BaseBoard V4.0,实现了两位数加、减、乘、除计算器的设计,它的主要功能为:进行两位数之间的加减乘除运算,并在数码管上显示运算数和结果。
标签
FPGA
2024寒假练
Web IDE
echu
更新2024-04-02
362

1 项目要求

(1)实现一个两位十进制数加、减、乘、除运算的计算器,运算数和运算符(加、减、乘、除)由按键来控制,4×4键盘按键分配如下图所示。

(2)运算数和计算结果通过8个八段数码管显示。每个运算数使用两个数码管显示,左侧显示十位数,右侧显示个位数。输入两位十进制数时,最高位先在右侧显示,然后其跳变到左侧的数码管上,低位在刚才高位占据的数码管上显示。

2 完成的功能介绍

2.1 功能框图

image.png

2.2 数码管显示

项目实现了运算数和结果的显示,具体如下:

(1)刚开机或复位后,显示0

image.png

(2)输入第一个运算数后,显示该运算数

image.png

(3)输入运算符后,不显示任何,等待输入第二个运算数

image.png

(4)输入第二个运算数后,显示该运算数

image.png

(5)点击等于后,显示计算结果,如这个例子中是计算32+68,则结果为100

image.png

(6)在有错误操作时,如连续输入两次运算符、不输入第二个运算数直接按等于号等等,则会显示ERROR

image.png

2.3 运算

​项目实现了加减乘除四种运算,运算数限于两位数以内,其中减法可以得到负数结果,除法为整数除法,即结果去掉了小数点后的部分。

3 整体思路

整个项目可以分成以下几部分:

  • ​数码管显示
  • 状态机编写
  • 运算过程编写
  • 按键输入部分

4 实现过程

4.1 数码管显示

这次活动的板子配置了74HC595,这是一个8位串行输入、并行输出的位移缓存器,以此来控制数码管,资料中提供了驱动的例程,本项目在例程的基础上修改每个数码管显示的值和使能信号,从而显示需要的内容。

值得注意的是,在将数值显示在数码管上时,需要将二进制编码改变为BCD编码方式,BCD码也称为二进码十进数,因为数码管需要显示十进制数据,若不转换编码方式,会对数据显示的正确性产生影响。这个程序在例程中也有相对应的,只需稍作修改。

4.2 状态机编写

为了实现计算过程的正常实现,本项目编写了状态机算法。设定初始(IDLE)、一个运算数(S_1N)、一运算数一运算符(S_1N1S)、两运算数(S_2N)、一结果(S_1R)、错误(ERROR)六种状态,将数入的按键分为数字、运算符、等于号三类,当有按键按下时,根据按键类型和目前状态确定下一状态。具体状态转变过程如下。

always@(posedge clk or negedge rst ) begin
if (!rst) begin
nstate <= 4'd0;end
else if (key_pulse>16'd0)begin
if (key_type==2'd0)//数字
case (cstate)
CAL_IDLE:nstate=S_1N;
S_1N:nstate=S_1N;
S_1N1S:nstate=S_2N;
S_2N:nstate=S_2N;
S_1R:nstate=S_1N;
ERROR:nstate=S_1N;
default:nstate=cstate;
endcase
else if (key_type==2'd1)//运算符
case(cstate)
CAL_IDLE:nstate=ERROR;
S_1N:nstate=S_1N1S;
S_1N1S:
if (key<7'd16)
nstate=ERROR;
else
nstate=S_1N1S;
S_2N:nstate=ERROR;
S_1R:nstate=ERROR;
ERROR:nstate=ERROR;
default:nstate=cstate;
endcase
else if (key_type==2'd2)//等于
case(cstate)
CAL_IDLE:nstate=ERROR;
S_1N:nstate=S_1R;
S_1N1S:nstate=ERROR;
S_2N:nstate=S_1R;
S_1R:nstate=S_1R;
ERROR:nstate=ERROR;
default:nstate=cstate;
endcase
else
nstate=cstate;
end
end

与每个状态对应的,有不同的运算数、运算符、计算信号的变化方式,以及数码管显示的数值和位数等等信息,均在状态机部分进行了设置。

4.3 运算过程编写

运算过程没有什么难点,用正常的+、-、*、/就可以,值得注意的是当减法结果小于0时,需要进行判断,并更新负号显示状态:仅在结果显示时显示负号,一旦开始下一次计算,即一个数字类型按键被按下时,停止显示负号。

always@(posedge clk or negedge rst) begin
if (!rst)
s<=1'b0;//s为负号显示信号
if (cal_pulse==1'b1 & num2>num1 & operator==2'd2)
s<=1'b1;
else if (s_pulse==1'b1)
s<=1'b0;
else
s<=s;
end

4.4 按键输入部分

按键输入也移植了硬禾学堂提供的例程,但由于要编写状态机,选择使用key_pulse作为有输入信号的标志。另外,编写代码以获得按键的值和类型。

//我们把按键信息转换成计算器按键的值,数字按键的值就为0-9,运算符号按键的值为10-14,等于号按键的值为15,无输入时值为16
always@(key_in) begin
case(key_in)
16'h0001: key = 5'd7; //7
16'h0002: key = 5'd8; //8,
16'h0004: key = 5'd9; //9,
16'h0008: key = 5'd10; //除,
16'h0010: key = 5'd4; //4,
16'h0020: key = 5'd5; //5,
16'h0040: key = 5'd6; //6,
16'h0080: key = 5'd11; //x,
16'h0100: key = 5'd3; //3,
16'h0200: key = 5'd2; //2,
16'h0400: key = 5'd1; //1,
16'h0800: key = 5'd12; //-,
16'h1000: key = 5'd0; //0,
16'h2000: key = 5'd14; //.,
16'h4000: key = 5'd15; //=,
16'h8000: key = 5'd13; //+,
default: key = 5'd16; //0
endcase
end
//转换成按键类型的过程与上类似,类型共三种:1:数字(0-9),2:运算符(+、-、x、/),3:等于号(=)


5 FPGA资源占用报告

image.png

6 困难和还可以优化的问题

  • ​这次选择的题目相对来说比较简单,最主要的困难就是状态机的编写,各种信号的变化比较复杂,容易造成时序上的错误。
  • 除法结果可以再添加小数部分。
  • 在LCD上显示运算数和结果

7 未来计划和建议

  • 这块板子的外设非常丰富,让人很心动,之后会进行更多的开发和练习。这次由于报名了教资(完全没想到要背那么多...),选择了较为简单的题目,之后会尝试一下其他的题目。
附件下载
calculator.zip
团队介绍
生物医学工程 大四
评论
0 / 100
查看更多
硬禾服务号
关注最新动态
0512-67862536
info@eetree.cn
江苏省苏州市苏州工业园区新平街388号腾飞创新园A2幢815室
苏州硬禾信息科技有限公司
Copyright © 2024 苏州硬禾信息科技有限公司 All Rights Reserved 苏ICP备19040198号