0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

FPGA学习系列:26. 计算器的设计

FPGA学习交流 2018-08-13 13:45 次阅读

设计背景:

计算器是设计中经常用到的一个操作软件,设计和学习计算器使我们亲密的联系所学的各模块, 对我们的学习有很大的帮助和提升。希望大家来学习

设计原理:

本次的设计主要通过矩阵键盘来实现按键的加减乘除运算,通过按下有效键值来当被加数或者被除数等等,按下10 -- 13等数字来表示对应的运算符。按键键值15表示等于号。

此次的设计是通过数码管来实现显示的,通过按下对应的按键来显示到数码管上,百位十位个位等等。当按下运算算符的时候显示清0不显示东西,之后通过继续按下别的键值来显示出对应的加数和除数等等,之后通过按下对应的键值15表示等于后,然后数码管清0之后立马显示出对应的等于的数。

这样来完成我们此次的设计。

设计架构图:

image.png

设计代码:

顶层模块

0modulecalc(clk,rst_n,row,col,sel,seg7); //端口列表

1 inputclk; //时钟

2 inputrst_n; //复位

3 input[3:0]row; //信号

4

5 output[3:0]col; //列信号

6 output[2:0]sel; //数码管位选信号

7 output[7:0]seg7; //数码管段选信号

8

9 wire[23:0]data;

10

11 //例化数码管模,和矩阵键盘模块

12 key_borad key_borad_dut(

13 .clk(clk),

14 .rst_n(rst_n),

15 .row(row),

16 .col(col),

17 .data(data)

18 );

19 seg seg_dut(

20 .clk(clk),

21 .rst_n(rst_n),

22 .sel(sel),

23 .seg7(seg7),

24 .data_in(data)

25 );

26

27endmodule

设计模块

0modulekey_borad(clk,rst_n,row,col,data);

1 inputclk; //时钟 50M

2 inputrst_n; //复位

3 input[3:0]row; //输入行信号

4

5 outputreg[3:0]col; //输出列信号

6 outputreg[23:0]data;

7

8 //状态变量,表示

9 parameters0 =3'b00;

10 parameters1 =3'b01;

11 parameters2 =3'b10;

12 parameters3 =3'b11;

13 parameters4 =3'b100;

14 parameters5 =3'b101;

15

16 parameterT1ms =50000;//扫描间隔

17 //parameter T1ms = 2;

18 parameterT10ms=500_000;//按键消抖时间

19 //parameter T10ms = 20;

20

21 wireflag;

22 reg[15:0]count;

23 always@(posedgeclk ornegedgerst_n)

24 if(!rst_n)

25 begin

26 count <=16'd0;

27 end

28 else

29 begin

30 if(count <T1ms -1) //计数1K的频率时间

31 count <=count +1'b1;

32 else

33 begin

34 count <=16'b0;

35 end

36 end

37

38 assignflag =(count ==T1ms -1)?1'b1:1'b0; //计数到了就给一个高脉冲,反之低脉冲

39

40 reg[2:0]state;

41 reg[7:0]row_col;

42 reg[18:0]cnt;

43 regdata_flag;

44 always@(posedgeclk ornegedgerst_n)

45 if(!rst_n)

46 begin

47 state <=3'b0;

48 row_col <=8'b1111_1111;

49 data_flag <=1'b0;

50 col <=4'b0000;

51 cnt <=19'b0;

52 end

53 else

54 begin

55 case(state)

56 s0:begin

57 if(row ==4'b1111) //如果没有按下

58 begin

59 data_flag <=1'b0;

60 col <=4'b0000;

61 end

62 else //表示按下,跳转下一个状态

63 begin

64 data_flag <=1'b0;

65 state <=s1;

66 end

67 end

68 s1:begin

69 if(row ==4'b1111) //如果是抖动跳转0状态

70 begin

71 cnt <=19'b0;

72 state <=s0;

73 end

74 else

75 begin

76 if(cnt <T10ms -1) //计数相应的时间,消抖处理

77 begin

78 cnt <=cnt +1'b1;

79 end

80 else

81 begin

82 cnt <=19'b0;

83 state <=s2;

84 col <=4'b0111;//消抖完表示按键有效

85 end

86 end

87 end

88 s2:begin

89 if(row !=4'b1111) //表示导通

90 begin

91 state <=s3; //导通后跳转下一个状态

92 row_col <={row,col}; //拼接行和列信号

93 end

94 else //行信号不导通,开始进行列扫描

95 begin

96 if(flag)

97 begin

98 col <={col[2:0],col[3]}; //1ms进行一次列扫描

99 end

100 else

101 begin

102 col <=col;

103 end

104 end

105 end

106 s3:begin

107 if(row ==4'b1111) //按键抬起

108 begin

109 state <=s0;

110 data_flag <=1'b1; //表示一次成功的按键,输出一个高脉冲

111 end

112 else

113 begin

114 state <=s3;

115 end

116 end

117 default:state <=s0;

118 endcase

119 end

120

121 reg[3:0]key_num;

122 //键值的翻译模块的表示

123 always@(posedgeclk ornegedgerst_n)

124 if(!rst_n)

125 key_num =4'd0;

126 else

127 case({row_col})

128 8'b0111_0111:key_num =4'hf;

129 8'b0111_1011:key_num =4'he;

130 8'b0111_1101:key_num =4'hd;

131 8'b0111_1110:key_num =4'hc;

132

133 8'b1011_0111:key_num =4'hb;

134 8'b1011_1011:key_num =4'ha;

135 8'b1011_1101:key_num =4'h9;

136 8'b1011_1110:key_num =4'h8;

137

138 8'b1101_0111:key_num =4'h7;

139 8'b1101_1011:key_num =4'h6;

140 8'b1101_1101:key_num =4'h5;

141 8'b1101_1110:key_num =4'h4;

142

143 8'b1110_0111:key_num =4'h3;

144 8'b1110_1011:key_num =4'h2;

145 8'b1110_1101:key_num =4'h1;

146 8'b1110_1110:key_num =4'h0;

147 default:;

148 endcase

149

150

151

152 //计算模块的表示

153 reg[2:0]state_s;//状态变量

154 reg[23:0]num1,num2,data_in,data_t; //信号变量

155 reg[3:0]flag_s;//运算符

156 always@(posedgeclk ornegedgerst_n)

157 begin

158 if(!rst_n)

159 begin

160 data <=24'b0;

161 state_s <=s0;

162 num1 <=24'b0;

163 num2 <=24'b0;

164 data_t <=24'b0;

165 flag_s <=4'b0;

166 data_in <=24'b0;

167 end

168 else

169 begin

170 case(state_s)

171 s0:begin

172 if(data_flag) //如果有一次按下

173 begin

174 if(key_num <4'd9)//键值小于9便是有效

175 begin

176 num1 <=num1*10+key_num;//BCD码转为2进制

177 data <={data[19:0],key_num};//数码管移位

178 end

179 if(key_num >4'd9&&key_num <4'd14)//10 -- 13 表示运算符

180 begin

181 data <=24'b0;

182 state_s <=s1;

183 flag_s <=key_num;

184 end

185 else//否则无效信号

186 state_s <=s0;

187 end

188 end

189 s1:begin

190 if(data_flag)//如果有一次按下

191 begin

192 if(key_num <4'd9)//键值小于9便是有效

193 begin

194 num2 <=10*num2 +key_num;//BCD码转为2进制

195 data <={data[19:0],key_num};//数码管移位

196 end

197 if(key_num >4'd9&&key_num <4'd14)//10 -- 13 表示运算符

198 begin

199 state_s <=s1;

200 end

201 if(key_num ==15)//表示等于

202 begin

203 state_s <=s2;

204 end

205 end

206 end

207 s2:begin

208 state_s <=s3;

209 case(flag_s)

210

211 4'd10:begin//加运算

212 data_in <=num1 +num2;

213 state_s <=s3;

214 end

215

216 4'd13:begin//乘运算

217 data_in <=num1 *num2;

218 state_s <=s3;

219 end

220 endcase

221 end

222 s3:begin//二进制转为BCD码显示到对应的数码管上

223 data[3:0]=data_in %10;

224 data[7:4]=data_in /10%10;

225 data[11:8]=data_in /100%10;

226 data[15:12]=data_in /1000%10;

227 data[19:16]=data_in /10000%10;

228 data[23:20]=data_in /100000;

229 state_s <=s0;

230 data_in <=24'b0;

231 end

232 default:state_s <=s0;

233 endcase

234 end

235 end

236

237

258endmodule

测试模块

0`timescale1ns/1ps

1

2modulecalc_tb();

3 regclk;

4 regrst_n;

5 reg[4:0]pressnum;

6 wire[3:0]row;

7

8 wire[3:0]col;

9 wire[3:0]key_num;

10

11 initialbegin

12 clk =1'b1;

13 rst_n =1'b0;

14 pressnum =5'd16;

15

16 #200.1

17 rst_n =1'b1;

18 #2000

19 pressnum =5'd16;

20

21 #1000

22 pressnum =5'd5;

23

24 #1000

25 pressnum =5'd16;

26

27 #1250

28 pressnum =5'd11;

29 #1250

30 pressnum =5'd16;

31 #1250

32 pressnum =5'd2;

33 #1250

34 pressnum =5'd16;

35 #1250

36 pressnum =5'd15;

37 #1250

38 pressnum =5'd16;

39 #2000

40 #2000

41 $stop;

42

43 end

44 always#10clk =~clk;

45

46 calc calc_dut(

47 .clk(clk),

48 .rst_n(rst_n),

49 .row(row),

50 .col(col),

51 .sel(sel),

52 .seg7(seg7)

53 );

54 yingjian yingjian_dut(

55 .clk(clk),

56 .rst_n(rst_n),

57 .col(col),

58 .row(row),

59 .pressnum(pressnum)

60 );

61endmodule

仿真:


从仿真图中可以看出,在放着中我们设置的是先按下5,再10,之后2,然后按下等于15.通过观察仿真正确,之后由于设计中我们10是表示加法,那么5 + 2 = 7 :结果显示正确。


声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • FPGA
    +关注

    关注

    1627

    文章

    21679

    浏览量

    602221
收藏 人收藏

    评论

    相关推荐

    使用DRV421进行设计:系统参数计算器

    电子发烧友网站提供《使用DRV421进行设计:系统参数计算器.pdf》资料免费下载
    发表于 10-26 09:52 0次下载
    使用DRV421进行设计:系统参数<b class='flag-5'>计算器</b>

    基于FPGA计算器设计

    本文通过FPGA实现8位十进制数的加、减、乘、除运算,通过矩阵键盘输入数据和运算符,矩阵键盘的布局图如下所示。该计算器可以进行连续运算,当按下等号后,可以直接按数字进行下次运算,或者按运算符,把上次运算结果作为本次运算的第一个操作数。
    的头像 发表于 10-24 14:28 357次阅读
    基于<b class='flag-5'>FPGA</b>的<b class='flag-5'>计算器</b>设计

    CAN位时序参数计算器

    电子发烧友网站提供《CAN位时序参数计算器.pdf》资料免费下载
    发表于 10-11 09:55 0次下载
    CAN位时序参数<b class='flag-5'>计算器</b>

    色环电阻计算器的研究与应用

    一个理想的色环电阻计算器的界面应该包含一个颜色选择,让用户能够通过点击或下拉菜单选择各个颜色环。而在程序逻辑层面,计算器需要具备实时反馈功能,用户选择颜色环后,系统能够立即计算出电阻
    的头像 发表于 09-18 13:45 270次阅读

    平平无奇计算器:520能对你说多少次?

    5月是一个爱人爱己爱劳动的月份刚刚过去的5月20日小满遇见520,人生小满胜万全情侣们说“爱意恰逢其时”计算器对小白说“520”……哒哒哒本期测评产品为:简易计算器计算器对我说无数次520(bushi本次测评数据已上传
    的头像 发表于 05-25 08:04 501次阅读
    平平无奇<b class='flag-5'>计算器</b>:520能对你说多少次?

    HarmonyOS开发案例:【计算器

    基于基础组件、容器组件,实现一个支持加减乘除混合运算的计算器
    的头像 发表于 05-07 15:31 1287次阅读
    HarmonyOS开发案例:【<b class='flag-5'>计算器</b>】

    苹果将为iPad推出原生计算器应用

    早前,IT之家曾披露,此次苹果还计划对macOS系统内的计算器应用进行功能升级,这是该软件近10年来的首次重大设计变革。据悉,苹果正在内部测试一款名为“GreyParrot”的全新计算器应用。
    的头像 发表于 04-24 14:10 432次阅读

    OpenHarmony开发案例:【分布式计算器

    使用分布式能力实现了一个简单的计算器应用,可以进行简单的数值计算,支持远程拉起另一个设备的计算器应用,两个计算器应用进行协同计算
    的头像 发表于 04-11 15:24 1006次阅读
    OpenHarmony开发案例:【分布式<b class='flag-5'>计算器</b>】

    AWTK 开源串口屏开发(13) - 计算器应用

    计算器是一个常见的应用程序,在AWTK串口屏中,利用fscript表达式计算函数,无需编写一行传统的代码,即可实现一个简单的计算器应用程序。1.功能计算器是一个很常见的应用,比如在电子
    的头像 发表于 03-16 08:23 5289次阅读
    AWTK 开源串口屏开发(13) - <b class='flag-5'>计算器</b>应用

    FPGA图书分享系列-2024.01.31

    Accelerators for Financial Applications》这本书面向金融领域,它探讨了FPGA(现场可编程门阵列)加速的最新方法和成果。 以下是这本书的一些亮点和值得学习的地方: 高性能
    发表于 01-31 21:14

    基于51单片机的简易计算器设计

    电子发烧友网站提供《基于51单片机的简易计算器设计.rar》资料免费下载
    发表于 01-12 10:50 9次下载

    基于51单片机的计算器设计

    电子发烧友网站提供《基于51单片机的计算器设计.rar》资料免费下载
    发表于 01-12 09:17 39次下载

    基于51单片机的计算器设计

    电子发烧友网站提供《基于51单片机的计算器设计.rar》资料免费下载
    发表于 01-03 11:33 21次下载

    基于51单片机的简易计算器设计

    基于51单片机的简易计算器设计(实物)
    发表于 01-02 10:02 9次下载

    pcb过孔电流计算器怎么用

    PCB过孔电流计算器是一种用于计算PCB板上过孔电流的工具。过孔是PCB板上的重要元件,用于连接不同层之间的电路。过孔的电流大小对于PCB板的性能和稳定性具有重要影响。因此,正确使用PCB过孔电流计算器
    的头像 发表于 12-14 16:20 7549次阅读