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

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

3天内不再提示

如何用小脚丫FPGA核心板实现4位加法器功能

电子森林 来源:电子森林 作者:苏老师 2021-10-11 09:21 次阅读

在上次的文章 - 浅谈“数字电路”的学习(8)- 编码器、译码器、多路复用器、解复用器的关系和应用 - 中,我梳理了一下数字电路教程中组合逻辑部分的一些典型逻辑应用和他们之间的关系,并通过一个简单的2:4译码器、3:8译码器来学习了一下用Verilog代码如何实现这些逻辑。

作为组合逻辑部分的总结篇,我们用小脚丫FPGA核心板来实现一个4位加法器的功能,正巧小脚丫板上有:

4个开关 - 可以做加法器的4位二进制的加数,可以实现十进制0、1、2.。.15的输入;

4个按键 - 可以做加法器的4位二进制的加数,在组合逻辑部分还没有涉及到按键的消抖功能,且同时按多个键相对于开关困难一些,因此我们至少可以用这4个按键的任意一个实现十进制的0、1、2、4、8的输入;

2个数码管 - 即便4个按键同时按下,最大输入的值也就15,因此此加法器能够产生的最大输出值为30,用一个数码管显示个位数,会显示0-9;另一个数码管显示十位数,会显示0-3;

8个分立的LED - 可以选择其中的4个作为4位二进制加法器的进位显示,发生进位的时候相应的LED就会亮。

板上的硬件条件齐全,就要用Verilog代码来实现逻辑了。

相对于前期我们讲述的例子,这个项目复杂的地方在于它包含了以下几个部分的知识点:

加法器 - 如何使用1位的全加器、1位的半加器构成一个4位的二进制加法器;

二进制转BCD码的解码 - 我们用4位二进制加法器实现的结果,在我们人类的认知里其实是十进制的,要用数码管以十进制的方式在两个数码管上将结果显示出来,这就需要我们先将二进制的加法结果(加上进位共5位二进制数据)转换为两个十进制的数值来表示;

7段(加上小数点8段)数码管的显示驱动 - 点亮数码管上的7根LED,通过这7根LED的组合生成我们认知的数字0、1、2、3、4、5、6、7、8、9,将要显示的数字映射到这7段LED上就需要一个编码的过程,有的文章也说是解码(decoder),总之是码制的转换过程

所以,这算是一个综合性的项目,用FPGA通过Verilog编程来实现也能体会到由一个项目由多个Module构成的方式,并能够理解我们常说的“并行”处理的含义

代码的架构如下面的框图所示:

d50dfa04-2a06-11ec-82a8-dac502259ad0.png

顶层功能模块add_4bits调用其它的几个并行执行的module,并定义了与外界打交道的输入输出管脚。代码如下:

module adder_4bits(sw,key,seg_led_1,seg_led_2,led_carry);input [3:0] sw;input [3:0] key;output [8:0] seg_led_1;output [8:0] seg_led_2;output [3:0] led_carry;

wire [3:0] input1;wire [3:0] input2;wire [3:0] answer;

wire carry_out;wire [3:0] carry; assign input1 = sw;assign input2 = ~key; genvar i;generate for(i=0;i《4;i=i+1) begin: generate_N_bit_Adder if(i==0) half_adder f(input1[0],input2[0],answer[0],carry[0]);

else full_adder f(input1[i],input2[i],carry[i-1],answer[i],carry[i]); end assign carry_out = carry[3];

endgenerate assign led_carry = ~carry; wire [4:0] sum;assign sum = {carry_out,answer};

wire [3:0] seg1_input;

wire [3:0] seg2_input; binary2bcd b2b(sum,seg1_input,seg2_input); LED display_answer(seg1_input,seg2_input,seg_led_1,seg_led_2); endmodule module half_adder(x,y,s,c);input x,y;output s,c;

assign s=x^y;assign c=x&y;endmodule // half adder module full_adder(x,y,c_in,s,c_out);input x,y,c_in;output s,c_out;

assign s = (x^y) ^ c_in;assign c_out = (y&c_in)| (x&y) | (x&c_in);endmodule // full_adder

要注意的是,在小脚丫FPGA板上,出于让同学们遇到问题才能学习的考虑,我们特别将开关和按键的缺省状态设置成了两种不同的方式,4个开关缺省状态为低电平,开关闭合时该管脚电平拉高;4个按键缺省状态为高电平,按下时该管脚电平为低;故在代码中做了取反~的处理(体会开关的状态以及Verilog对反相信号的处理方式,在使用中体会开关和按键的不同)。

二进制转BCD码在网上有很多文章介绍,常用的方法为移位3的方式,只需要短短几行代码就可以实现,关于其原理大家可以自行搜索一下,我也在下面的代码的注释部分附上了这部分代码供同学们参考。考虑到两个4位加法输出的结果只有5位二进制、对应的最多31种结果,我们要做的就是将这5位二进制映射到2个10进制的数字上,有点类似5-32的译码操作,在这里我们使用查找表的方式来构建,主要也是让同学们体会查找表的灵活性、构建方法和Verilog的语法。要知道的是FPGA内部的逻辑都是基于查找表的方式来实现的。

module binary2bcd(binary_data,tens,ones);input [4:0] binary_data;output reg [3:0] tens;output reg [3:0] ones; always @*case(binary_data) 5‘d0: begin tens = 4’d0; ones = 4‘d0; end 5’d1:

begin tens = 4‘d0; ones = 4’d1; end 5‘d2: begin tens = 4’d0; ones = 4‘d2; end 5’d3:

begin tens = 4‘d0; ones = 4’d3; end 5‘d4: begin tens = 4’d0; ones = 4‘d4; end 5’d5: begin tens = 4‘d0;

ones = 4’d5; end 5‘d6: begin tens = 4’d0; ones = 4‘d6; end 5’d7: begin tens = 4‘d0; ones = 4’d7; end 5‘d8: begin tens = 4’d0; ones = 4‘d8; end 5’d9: begin tens = 4‘d0; ones = 4’d9; end 5‘d10: begin tens = 4’d1; ones = 4‘d0; end 5’d11: begin tens = 4‘d1; ones = 4’d1;

end 5‘d12: begin tens = 4’d1; ones = 4‘d2; end 5’d13: begin tens = 4‘d1; ones = 4’d3;

end 5‘d14: begin tens = 4’d1; ones = 4‘d4; end 5’d15: begin tens = 4‘d1; ones = 4’d5; end 5‘d16: begin tens = 4’d1; ones = 4‘d6; end 5’d17: begin tens = 4‘d1; ones = 4’d7; end 5‘d18: begin tens = 4’d1; ones = 4‘d8; end 5’d19: begin tens = 4‘d1; ones = 4’d9; end 5‘d20: begin tens = 4’d2; ones = 4‘d0; end 5’d21: begin tens = 4‘d2; ones = 4’d1; end 5

‘d22: begin tens = 4’d2; ones = 4‘d2; end 5’d23: begin tens = 4‘d2; ones = 4’d3; end 5

‘d24: begin tens = 4’d2; ones = 4‘d4; end 5’d25: begin tens = 4‘d2; ones = 4’d5; end 5

‘d26: begin tens = 4’d2; ones = 4‘d6; end 5’d27: begin tens = 4‘d2; ones = 4’d7; end 5

‘d28: begin tens = 4’d2; ones = 4‘d8; end 5’d29: begin tens = 4‘d2; ones = 4’d9; end 5

‘d30: begin tens = 4’d3; ones = 4‘d0; end 5’d31: begin tens = 4‘d3; ones = 4’d1; endendcase /*integer i; always @(binary_data)begin tens = 4‘d0; ones = 4’d0; for (i=7; i 》= 0; i=i-1) begin if (tens》=5) tens = tens +3; if (ones 》= 5) ones = ones +3; tens = tens 《《 1; tens[0] = ones[3]; ones = ones 《《 1; ones[0] = binary_data[i]; endend*/ endmodule

至于2个7段数码管的显示驱动,由于小脚丫FPGA核心板上管脚比较富裕,采用了直接映射的方式,在很多管脚受限的应用场景需要用到动态扫描的方式或通过专用的芯片来扩展,在后面时序逻辑部分的示例中会再讲。

2个7段数码管的显示驱动代码如下:

// ********************************************************************// 》》》》》》》》》》》》》》》》》》》》》》》》》 COPYRIGHT NOTICE 《《《《《《《《《《《《《《《《《《《《《《《《《//

********************************************************************// File name : segment.v// Module name : segment// Author : STEP// Description : segment initial// Web : www.stepfpga.com// // --------------------------------------------------------------------// Code Revision History : // --------------------------------------------------------------------// Version: |Mod. Date: |Changes Made:// V1.0 |2021/10/08 |Initial ver// --------------------------------------------------------------------// Module Function:数码管的译码模块初始化

module LED (seg_data_1,seg_data_2,seg_led_1,seg_led_2); input [3:0] seg_data_1; //数码管需要显示0~9十个数字,所以最少需要4位输入做译码

input [3:0] seg_data_2; //小脚丫上第二个数码管 output [8:0] seg_led_1; //在小脚丫上控制一个数码管需要9个信号 MSB~LSB=DIG、DP、G、F、E、D、C、B、A output [8:0] seg_led_2; //在小脚丫上第二个数码管的控制信号 MSB~LSB=DIG、DP、G、F、E、D、C、B、A reg [8:0] seg [9:0]; //定义了一个reg型的数组变量,相当于一个10*9的存储器,存储器一共有10个数,每个数有9位宽

initial //在过程块中只能给reg型变量赋值,Verilog中有两种过程块always和initial //initial和always不同,其中语句只执行一次 begin seg[0] = 9‘h3f; //对存储器中第一个数赋值9’b00_0011_1111,相当于共阴极接地,DP点变低不亮,7段显示数字 0 seg[1] = 9‘h06; //7段显示数字 1 seg[2] = 9’h5b; //7段显示数字 2 seg[3] = 9‘h4f;

//7段显示数字 3 seg[4] = 9’h66; //7段显示数字 4 seg[5] = 9‘h6d; //7段显示数字 5 seg[6] = 9’h7d; //7段显示数字 6 seg[7] = 9‘h07; //7段显示数字

7 seg[8] = 9’h7f; //7段显示数字 8 seg[9] = 9‘h6f; //7段显示数字 9 end assign seg_led_1 = seg[seg_data_1]; //连续赋值,这样输入不同四位数,就能输出对于译码的9位输出assign seg_led_2 = seg[seg_data_2]; endmodule

大家看到了这段代码有详细的注释,是不是感觉可读性增加了很多?这是我们Web IDE中的案例代码,可以直接复制到你自己的项目中来使用,作为一种示例,也是希望大家能够体会到注释的重要性,以后在自己的项目中加强这方面的规范性。

** 由于微信的编辑器对Verilog代码的格式识别和支持不够,显示的效果与我们Web IDE上不同。

代码编写完毕,在Web IDE中点击“逻辑综合”,系统会根据你的顶层文件自动提取端口的管脚,让你非常便捷给相应的信号绑定器件的管脚,如下图示。

绑定完管脚,点击保存 - -》 FPGA映射,生成可以下载的jed文件,鼠标指向下载JED文件的图标,右键保存到StepFPGA16的盘里,就完成了对FPGA的编程,你手里的小脚丫FPGA就成了一个4位的加法器。

搞定!

如果你也能够独立完成这个项目,那你:

对数字电路部分的组合逻辑有了非常深刻的认识;

对FPGA的使用,尤其是管脚的配置、外设的状态、显示器件的使用有了深刻的认识;

对Verilog的语法使用有了更多、更深入的体会,包括多module的设计思路、module之间的接口、并行执行等。

来试一试吧。

责任编辑:haq

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

    关注

    172

    文章

    5895

    浏览量

    172107
  • Verilog
    +关注

    关注

    28

    文章

    1351

    浏览量

    110065
  • 加法器
    +关注

    关注

    6

    文章

    183

    浏览量

    30110

原文标题:浅谈“数字电路”的学习(9) - 小脚丫上实现4位加法器并数码管显示结果

文章出处:【微信号:xiaojiaoyafpga,微信公众号:电子森林】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    【基于Lattice MXO2的小脚丫FPGA核心板】工程创建和固件烧录

    基于Lattice MXO2 LPC的小脚丫FPGA核心板 - Type C接口 开发板的硬件规格如下: 核心器件:Lattice LCMXO2-4000HC-
    发表于 01-31 21:01

    【基于Lattice MXO2的小脚丫FPGA核心板】03数码管显示控制

    ] seg_led_1;//在小脚丫上控制一个数码管需要9个信号 MSB~LSB=DIG、DP、G、F、E、D、C、B、A output [8:0] seg_led_2;//在小脚丫上第二个数码管的控制
    发表于 02-29 09:01

    加法器

    请问下大家,,进位选择加法器和进位跳跃加法器的区别是啥啊?我用Verilog实现16他们的加法器有什么样的不同啊?还请知道的大神告诉我一下
    发表于 10-20 20:23

    4并行的BCD加法器电路图

       图二所示为4并行的BCD加法器电路。其中上面加法器的输入来自低一级的BCD数字。下
    发表于 03-28 16:35 1.4w次阅读
    <b class='flag-5'>4</b><b class='flag-5'>位</b>并行的BCD<b class='flag-5'>加法器</b>电路图

    加法器,加法器是什么意思

    加法器,加法器是什么意思 加法器 :  加法器是为了实现加法的。  即是产生数的和的装置。加数
    发表于 03-08 16:48 5543次阅读

    FPU加法器的设计与实现

    浮点运算器的核心运算部件是浮点加法器,它是实现浮点指令各种运算的基础,其设计优化对于提高浮点运算的速度和精度相当关键。文章从浮点加法器算法和电路实现
    发表于 07-06 15:05 47次下载
    FPU<b class='flag-5'>加法器</b>的设计与<b class='flag-5'>实现</b>

    8加法器和减法器设计实习报告

    8加法器和减法器设计实习报告
    发表于 09-04 14:53 134次下载

    基于选择进位32加法器的硬件电路实现

    为了缩短加法电路运行时间,提高FPGA运行效率,利用选择进位算法和差额分组算法用硬件电路实现32加法器,差额分组中的
    发表于 09-18 14:32 33次下载
    基于选择进位32<b class='flag-5'>位</b><b class='flag-5'>加法器</b>的硬件电路<b class='flag-5'>实现</b>

    通过小脚丫板载的两个数码管来显示字符

    今天我们任务是通过小脚丫板载的两个数码管来显示字符,所以首先我们要了解一下数码管的基本工作原理,接下来再研究怎么通过捣鼓小脚丫把数码管给点亮,并且显示出有效信息。   小脚丫板载的数码管是 7 段数
    的头像 发表于 01-06 17:17 5798次阅读
    通过<b class='flag-5'>小脚丫</b>板载的两个数码管来显示字符

    通过小脚丫FPGA搭建实验电路并验证一个二进制比较器

    前一篇文章我们介绍了通过小脚丫FPGA核心开发板来进行门电路的实验过程。当然,我们还可以画出更多复杂的门电路组合,并且通过小脚丫FPGA轻松
    的头像 发表于 01-06 17:19 5227次阅读

    加法器是如何实现

     verilog实现加法器,从底层的门级电路级到行为级,本文对其做出了相应的阐述。
    发表于 02-18 14:53 6236次阅读
    <b class='flag-5'>加法器</b>是如何<b class='flag-5'>实现</b>的

    4加法器开源分享

    电子发烧友网站提供《4加法器开源分享.zip》资料免费下载
    发表于 07-08 09:33 3次下载
    <b class='flag-5'>4</b><b class='flag-5'>位</b><b class='flag-5'>加法器</b>开源分享

    加法器的原理及采用加法器的原因

    有关加法器的知识,加法器是用来做什么的,故名思义,加法器是为了实现加法的,它是一种产生数的和的装置,那么
    的头像 发表于 06-09 18:04 5121次阅读

    4加法器的构建

    电子发烧友网站提供《4加法器的构建.zip》资料免费下载
    发表于 07-04 11:20 0次下载
    <b class='flag-5'>4</b><b class='flag-5'>位</b><b class='flag-5'>加法器</b>的构建

    基于FPGA实现Mem加法器

    前段时间和几个人闲谈,看看在FPGA里面实现一个Mem加法器怎么玩儿
    的头像 发表于 10-17 10:22 602次阅读
    基于<b class='flag-5'>FPGA</b><b class='flag-5'>实现</b>Mem<b class='flag-5'>加法器</b>