题目:

实验一个多功能数字电路模块
具体要求如下:
1) 输入数据为两个一位十进制数A和B,A和B均为8421码表示,其中数据A由拨动开关SW7-SW4输入(SW7为MSB),数据B由SW3-SW0输入(SW3为MSB);
2) 电路的功能包括求和、比较大小、输出最大值和输出最小值四种;分别由如下图所示的按键开关控制,当按键按下时,电路执行相对应的功能并输出结果。

3) 求和功能描述:当按下求和键时,对A和B两个数相加,相加的结果显示在数码管上,注意相加的结果需要进行BCD码调整,显示模块必须调用实验一中设计的显示译码电路,当十位为0时,需要灭零。

4) 比较大小模块描述:当比较大小功能键按下时,比较A和B的大小,当A<B时显示01(不灭0),当A>B时显示10,A=B时显示11。
5) 输出最大(小)值功能描述:当按下输出最大(小)值功能键时,将A和B中的最大(小)值显示在数码管上。

(出题:北京理工大学 张延军老师)

1. 设计思路

在做本题之前,已经编写好了LED显示模块,这个模块比较简单,我就不多说了.

module decoder_7led(input turn_off,//灭灯信号input test,//测灯信号input zero,//灭零信号input [3:0] number,//输入的四位二进制数output reg [7:0] display,//数码管片选output reg led,//控制LD2的0号灯output reg select=1//段选,恒为1,连接G6管脚。
);
//led变量
always @ *
begin if (turn_off==1'b0)//仍按照优先级顺序判断led=1'b0;else if (test==1'b0)led=1'b0;else if ((zero==1'b0)&&(number==4'b0000))//满足灭零条件led=1'b1;elseled=1'b0;end
//display变量
always @ *
beginif (turn_off==1'b0)//灭灯有效display=8'b00000000;else if (test==1'b0)//测试有效display=8'b11111111;else if ((zero==1'b0)&&(number==4'b0000))//满足灭零条件display=8'b00000000;elsebegincase(number)//情况逐个讨论4'b0000:display=8'b11111100;4'b0001:display=8'b01100000;4'b0010:display=8'b11011010;4'b0011:display=8'b11110010;4'b0100:display=8'b01100110;4'b0101:display=8'b10110110;4'b0110:display=8'b10111110;4'b0111:display=8'b11100000;4'b1000:display=8'b11111110;4'b1001:display=8'b11100110;4'b1010:display=8'b00011010;4'b1011:display=8'b00110010;4'b1100:display=8'b01000110;4'b1101:display=8'b10010110;4'b1110:display=8'b00011110;4'b1111:display=8'b00000000;endcaseend
endendmodule // decoder_7led

首先将整个逻辑模块分为四大功能模块:求和、比较、求最大值和求最小值模块和数码管显示模块,以及起到控制作用的选择模块。本题的关键在于如何将这些模块正确地联系起来。首先分别讨论各自模块的实现:
①求和模块
若要对两个8421数进行求和,且求和结果仍为8421数,则非常关键的一步在于判断是否进位如果产生了进位,那么要在加法结果之后再加6(0000_0110).
本模块的输入是两个4位8421数,为了方便地进行加法,首先拓展为8位二进制数。产生进位,即直接相加的结果大于9,否则就是没有产生进位,直接将结果输出。为此创建bcd_adder模块,输入为两个8421数和控制加法功能的按钮信号,输出为十位数结果和个位数结果,需要中间变量来储存加法结果,利用8位寄存器变量。还有需要注意的一点是当十位数结果为0时要清零。因为最终计算的结果要输入到数码管控制的电路里,且在实验一中当数码管模块的输入为4’b1111时数码管的8个LED全灭。因此与其控制数码管模块的灭零信号,不如直接让十位数对应的输出为4’1111更为简便。代码如下:

 module bcd_adder(input [3:0] numa1,//输入数字1input [3:0] numa2,//输入数字2input button_adder,//按钮output reg [3:0] resulta1,//结果,十位数output reg [3:0] resulta2//结果,个位数
);
reg [7:0] temp;
always @ *
begintemp={4'b0000,numa1}+{4'b0000,numa2};//扩充位数if(temp>8'b00001001)//产生进位begin{resulta1,resulta2}=temp+8'b00000110;//加6endelsebeginresulta1=4'b1111;//十位数为0时要清零resulta2=temp[3:0];end
endendmodule // 加法模块

②比较大小模块
比较大小模块的功能比较简单,主体就是if语句,让对应的输入情形对应正确的输出即可。为此创建compare模块,输入为两个8421数和控制比较功能的按钮信号,输出为十位数结果和个位数结果。代码如下:

 module compare(input [3:0] numc1,input [3:0] numc2,input button_compare,output reg [3:0] resultc1,output reg [3:0] resultc2
);
//resultc1
always @ *
beginif (numc1<numc2)resultc1=4'b0000;else if (numc1>numc2)resultc1=4'b0001;elseresultc1=4'b0001;
end
//resultc2
always @ *
beginif (numc1<numc2)resultc2=4'b0001;else if (numc1>numc2)resultc2=4'b0000;elseresultc2=4'b0001;
end
endmodule // 比较模块

③输出最大/最小值模块
这两个模块在功能上是相似的。由于输入的是两个8421数,二者中的较大/较小者一定是个位数,因此显示十位数的数码管(或说一个数码管)就不需要显示了,如前所述,可以直接用4’b1111来灭灯。为此创建export_max和export_min模块,代码如下:

 module export_max(input [3:0] num_max1,input [3:0] num_max2,input button_max,output reg [3:0] result_max1=4'b1111, //十位是0output reg [3:0] result_max2
);
always @ *
beginif(num_max1>num_max2)result_max2=num_max1;elseresult_max2=num_max2;
endendmodule // 输出最大值模块
module export_min(input [3:0] num_min1,input [3:0] num_min2,input button_min,output reg [3:0] result_min1=4'b1111,//十位是0output reg [3:0] result_min2
);
always @ *
beginif(num_min1<num_min2)result_min2=num_min1;elseresult_min2=num_min2;
end
endmodule // 输出最小值模块

④选择模块
至此实现四个功能的模块已经设计完了,为了避免混乱,四个模块最好独立,不要管脚复用。这时候就需要一个选择器,来选择究竟将哪个模块的输出连接到数码管模块的输入。控制究竟发送哪个数据的信号当然是四个按钮,此外,应将四个模块的输出作为这个模块的输入。为此创建mux模块,输入为四个按钮信号和四个模块的对应输出,输出为控制两个数码管的信号,即显示的第一位数和第二位数对应的信号。代码如下:

 module mux(//四个模块的八个输出input [3:0] add_output_1,input [3:0] add_output_2,input [3:0] cmp_output_1,input [3:0] cmp_output_2,input [3:0] max_output_1,input [3:0] max_output_2,input [3:0] min_output_1,
input [3:0] min_output_2,
//四个按钮input button_a,input button_c,input button_x,
input button_n,
//输出:第一位数和第二位数output reg [3:0] result_1,output reg [3:0] result_2
);
always @ *
beginif (button_a==1)//如果是加法功能{result_1,result_2}={add_output_1,add_output_2};else if (button_c==1)//如果是比较功能{result_1,result_2}={cmp_output_1,cmp_output_2};else if (button_x==1)//如果是求最大值功能{result_1,result_2}={max_output_1,max_output_2};else if(button_n==1)//如果是求最小值功能{result_1,result_2}={min_output_1,min_output_2};else //如果都不是(没有按钮被摁下),就输出两个0.{result_1,result_2}={4'b0000,4'b0000};
end
endmodule // 选择器 对输出信号进行选择送到LED模块

⑤顶层模块
顶层模块的设计是本题的关键。整个电路的架构应当是:有六个输入,分别是两个8421数和4个按钮。有两个数码管,因此有六个输出,每个数码管对应三个输出:片选、位选和LED灯。这里直接利用实验一的数码管模块。六个输入是并行的,同时输入到四个功能模块中。四个模块和选择器的连接关系前面已述,选择器的两个输出直接送给对应的两个数码管模块。数码管的三个信号:灭灯、灭零和测试信号由于用不到,可以直接赋值为无效。代码如下:

//顶层模块
module multiply_top(input [3:0] num1,input [3:0] num2,input B_add,input B_cmp,input B_max,input B_min,output [7:0] display1,output [7:0] display2,output select1,output select2,output led1,output led2
);
//中间连线
wire [3:0] led_number_a_1;
wire [3:0] led_number_a_2;
wire [3:0] led_number_c_1;
wire [3:0] led_number_c_2;
wire [3:0] led_number_max_1;
wire [3:0] led_number_max_2;
wire [3:0] led_number_min_1;
wire [3:0] led_number_min_2;wire [3:0] to_led_1;
wire [3:0] to_led_2;
//将四个功能模块实例化
bcd_adder BCD_ADDER
(.numa1(num1),.numa2(num2),.button_adder(B_add),.resulta1(led_number_a_1),.resulta2(led_number_a_2));
compare CMP
(.numc1(num1),.numc2(num2),.button_compare(B_cmp),.resultc1(led_number_c_1),.resultc2(led_number_c_2));
export_max EPMAX
(.num_max1(num1),.num_max2(num2),.button_max(B_max),.result_max1(led_number_max_1),.result_max2(led_number_max_2));
export_min EPMIN
(.num_min1(num1),.num_min2(num2),.button_min(B_min),.result_min1(led_number_min_1),.result_min2(led_number_min_2));//将选择器实例化
mux MUX1 (.add_output_1(led_number_a_1),.add_output_2(led_number_a_2),//加法输出.cmp_output_1(led_number_c_1),.cmp_output_2(led_number_c_2),//比较输出.max_output_1(led_number_max_1),.max_output_2(led_number_max_2),//最大值输出.min_output_1(led_number_min_1),.min_output_2(led_number_min_2),//最小值输出.button_a(B_add),.button_c(B_cmp),.button_x(B_max),.button_n(B_min),//四个按钮.result_1(to_led_1),.result_2(to_led_2));//输出,传给LED模块//LED模块实例化
decoder_7led LED1
(.turn_off(1'b1),.test(1'b1),.zero(1'b1),.number(to_led_1),.display(display1),.led(led1),.select(select1));
decoder_7led LED2
(.turn_off(1'b1),.test(1'b1),.zero(1'b1),.number(to_led_2),.display(display2),.led(led2),.select(select2));
endmodule

2. 仿真与测试

编写testbench模块,分别测试四个功能。代码如下:

module testbench;
reg [3:0] NUM1;
reg [3:0] NUM2;
reg B_ADD;
reg B_CMP;
reg B_MAX;
reg B_MIN;
wire [7:0] DISPLAY1;
wire [7:0] DISPLAY2;
wire SELECT1;
wire SELECT2;
wire LED1;
wire LED2;
multiply_top TEST (.num1(NUM1),.num2(NUM2),.B_add(B_ADD),.B_cmp(B_CMP),.B_max(B_MAX),.B_min(B_MIN),.display1(DISPLAY1),.display2(DISPLAY2),.select1(SELECT1),.select2(SELECT2),.led1(LED1),.led2(LED2));initial
beginNUM1=4'b0000;NUM2=4'b0000;B_ADD=0;B_CMP=0;B_MAX=0;B_MIN=0;endalways
begin#20 NUM1=4'b0100;NUM2=4'b0001;#20 B_ADD=1;#10 B_ADD=0;#20 B_CMP=1;#10 B_CMP=0;#20 B_MAX=1;#10 B_MAX=0;#20 B_MIN=1;#20 B_MIN=0;#20 NUM1=4'b1000;NUM2=4'b1001;#20 B_ADD=1;#10 B_ADD=0;#20 B_CMP=1;#10 B_CMP=0;#20 B_MAX=1;#10 B_MAX=0;#20 B_MIN=1;#20 B_MIN=0;
end
initial #300 $finish;
endmodule // testbench

仿真结果:

经过验证,输出正确,满足设计要求。

我的Verilog HDL学习历程(二) 组合逻辑电路的一个实例:基于EGO1板子相关推荐

  1. 【Verilog HDL学习之路】第二章 Verilog HDL的设计方法学——层次建模

    2 Verilog HDL的设计方法学--层次建模 重要的思想: 在语文教学中,应该先掌握核心方法论,再用正确的方法论去做题目,这样能够逐渐加深对于方法论的理解,做题的速度和准确率也会越来越高. 在V ...

  2. Verilog HDL 学习笔记3-Latch

    Verilog HDL 学习笔记3-Latch 第一次接触Latch是在大二学习数电的时候,那时候Latch被翻译成锁存器,当时还纠结着锁存器和寄存器的区别(要是当时我知道他俩的英文名叫latch和r ...

  3. Verilog HDL 学习笔记2-blocking and non-blocking assignment

    2013年5月6日 10:42:38 Verilog HDL 学习笔记2-blocking and non-blocking assignment ---学习贵在总结,将学习的心得体会记录 在学习ve ...

  4. (82)Verilog HDL:状态机二段式

    (82)Verilog HDL:状态机二段式 1.1 目录 1)目录 2)FPGA简介 3)Verilog HDL简介 4)Verilog HDL:状态机二段式 5)结语 1.2 FPGA简介 FPG ...

  5. Verilog HDL学习笔记

    目录 1 硬件描述语言简介 1.1 概述 1.2 HDL语言特点 2 程序的基本语法 2.1 Verilog HDL 程序结构 2.1 Verilog HDL 程序规则 模块 连续赋值语句assign ...

  6. 【Verilog HDL学习之路】第一章 Verilog HDL 数字设计总论

    1 Verilog HDL 数字设计总论 1.1 几个重要的概念 EDA(Electronic Design Automation) 电子技术自动化 EDA工具 类似于软件工程中的IDE(集成开发环境 ...

  7. Verilog HDL学习笔记(一)常见错误

    我初学verilog语言,很多细节都没注意,按着自己的思想就写了,编译的时候才发现各种问题.这些都是我在学习中遇到的问题,还是很常见的. 1.Error (10028): Can't resolve ...

  8. 智力竞赛抢答器 Verilog HDL 建模*(二)

    计数模块 计数模块,比赛中要求第一抢答者在规定时间内回答问题,系统开始 30 秒倒计时,倒计时完毕发出响声,若能在规定时间内完成,由主持人按使能开关停止倒计时,不发出响声.计数模块的源程如下: els ...

  9. 记录我的学习历程--二维数组解决平面图形题

    打印出 3           7 2     4    6    8 1            5          9 代码如下 转载于:https://blog.51cto.com/413973 ...

  10. Verilog HDL 学习篇——六位数码管驱动

    根据原理图可知,此处数码管数据时共享的,每个位由片选信号分隔开,考虑人眼的视觉残留,可用扫描的方式更新数据. 这个驱动,有两个比较重要的,就是扫描驱动和二进制转BCD编码了 先说扫描驱动吧,要让第一个 ...

最新文章

  1. error: No curses/termcap library found的解决办法
  2. 响应时登录html,HtmlUnit:单击不响应时登录HtmlElement
  3. AndroidStudio 3.4 自定义注解处理器不起作用
  4. 机器学习笔记:误差的来源(bias variance)
  5. 监听门后德美恢复网监合作
  6. QT中Qpixmap与QImage的转化
  7. springmvc使用freemarker
  8. 客制化键盘编程_指尖运动会,谁是打字冠军,双十一机械键盘推荐
  9. 定制化WordPress后台的6个技巧
  10. 面试-重写基础功能函数
  11. docker mysql 日志在哪里_docker容器启动后日志在哪里
  12. 中国上海量子计算机,首台光量子计算机在上海亮相
  13. 读《Javascript高级程序设计》中的javascript事件处理程序(事件侦听器)心得
  14. React 的慢与快:优化 React 应用实战
  15. FFmpeg和WebRTC
  16. 搜索了才发现,原来这首歌的原唱是她们,SHE歌曲专辑下载,beyond歌曲专辑下载
  17. 微信读书爬虫 wereader
  18. 只需要这三个步骤让你轻松搞定Maya中贴hdr贴图
  19. ICO图标在线生成,php生成ICO图标在线制作源码
  20. FinalShell连接超时解决方法

热门文章

  1. 安装SHARP MX-3618NC PCL6打印机驱动程序
  2. C++ OpenCV实现图像双三次插值算法
  3. matlab画EBSD的极图,EBSD技术原理及系统.PDF
  4. 记账系统推荐金蝶精斗云_金蝶精斗云是免费会计记账软件吗?
  5. 弘辽科技:掌握淘宝直通车的工作原理很有必要!其核心是什么?
  6. 软件项目经理应具备的素质和条件_IT项目经理必须具备的能力
  7. java实现京东登陆界面_java实现京东云第三方登录
  8. SMOTE算法代码实现
  9. PT100温度采集电路设计
  10. 搭建GB28181本次测试步骤-SIP信令服务器