一、 实验目标
熟练掌握 Verilog HDL 硬件描述语言,能够在实际工程中熟练使用Quartus II 软件进行可编程逻辑器件的基本开发, 能够熟练使用 Modelsim 软件进行系统的功能仿真验证, 能够正确的使用实验室各种实验仪器设备如示波器、信号发生器进行问题分析,具备使用合适的实验仪器和仿真软件,对汽车电子信息领域的复杂工程问题能够进行合理的分析、优化、计算和设计,对工程故障能够快速的定位、解决的能力。
二、实验内容
汽车仪表盘是汽车电子的重要组成部分,一个设计合理的汽车仪表盘不仅能够增加汽车内饰的美观程度,增强驾驶体验,还能够直观的获取汽车相关数据,增加汽车的安全性,本实验是一个汽车仪表盘的显示系统设计,包含但不限汽车速度显示、汽车里程显示、汽车故障指示。
三、实验要求
1、 根据 FPGA 开发流程对实验项目课题进行合理分析,设计系统方案;
2、 使用 Verilog HDL 硬件描述语言,设计汽车仪表盘显示系统,主要包括汽车速度显示、汽车里程显示、汽车故障指示等;
3、 对设计的汽车仪表盘显示系统进行整体功能仿真,验证设计正确性,对出现的错误进行记录、分析;
4、 在FPGA 开发平台上进行板上验证,观察实验现象,分析设计合理性。
5、 提出对系统的改进意见,总结实验心得。
6、 按3-5 人成立项目组,明确角色和分工,制作 PPT 进行项目答辩。
四、实验预习(实验原理、整体设计方案等)
(一)、实验基本原理:
本次实验通过控制MINI_FPGA开发板上配有的6个七段数码管 DIG1-DIG6(当正放 MINI_FPGA 开发板时,从左至右依次数过去)模拟显示汽车仪表盘上的行驶里程、汽车故障代码指示以及汽车仪表盘上汽车速度,同时通过多个按键操作,使得数码管上显示出不同数值(汽车里程、汽车速度、故障显示数字),使得按键显示功能可以进行切换。
(二)、整体设计方案:
1.数码管正常显示对应数值
先确定控制动态扫描的周期为:Timex = 8'd200 ,然后通过Count变量重复在动态扫描周期内重复计数、清零产生片选信号cs(由于本次实验仅启用了两个数码管,所以cs的值在0和1之间变换),再将片选信号进行译码,使得所需的对应数码管启用,由此完成数码管的启用。然后将待显示的数据变量SingleNum初始化为零,然后通过片选信号的不断变化,控制由Testbench上的测试文件数据赋给待显示的数据变量SingleNum,再将待显示的数据变量SingleNum译码成共阴极数码管驱动格式,使得启用的数码管显示出对应的数字。
2.按键操作使数码管数值不断增加
首先,为保证按键操作判断的准确性,需要加入按键消抖功能,具体的按键消抖功能操作为:我们首先需要一个模块来检测按键是否抖动,如果抖动,给计时模块一个标志位开始计时,记满20ms,再给输出消抖后按键信号模块一个标志位进行采样。理清思路,整个程序分为三个模块,模块之间相互关联,关联之处需要一个起到连接作用的器件,也就是标志位。比如将flag作为标志位,检测到按键抖动之后,将flag作为计时开始的条件。
然后我们需要用到计数器功能,将数码管显示与按键操作联系起来,使得数码管显示的里程数随着按键的操作能够不断增加,具体的计数器设计为:通过输入变量cycle设定计数周期,然后利用时钟clk进行计数器计数,每一个时钟周期计数器进行一次计数,直到累加到个位(bit)的值达到一个计数周期,然后个位(bit)清零,十位(ten)进一,以此循环进行。
在计数过程中可以通过输入变量rst_n、enable_n进行复位和使能功能。当rst_n值为0时,计数复位为0;值为1时,计数累加。当enable_n值为0时,计数器暂停计数,保留计数的累计值(当然此时也可以通过rst_n值变为1从而使计数器清零);当enable_n值为1时,计数累加。
3.不同按键按下使数码管显示出不同的故障数字
在代码中设置好对应按键按下后六个数码管所显示的对应故障数字,如下图代码:
图4.1
我所设置的三个按键所对应的三个数码管所显示的对应故障数字分别为:222222、333333、444444。
图4.2
由于我们所输入的显示,只与四位二进制变量Result有关,所以在实际的应用中我们也可以根据自己的需要设置自己需要的故障指示数字,仅仅只需要改动代码中的那六个数字即可,无需改动其他代码,这样方便又简单的可以满足自己的需求。
4.不同按键按下使数码管显示的汽车速度发生相应的改变
需要设置两个按键为油门和刹车,分别控制显示管显示汽车速度数值的增加和减少,在没有按键按下时,也需要保持汽车速度(理想情况下,实际情况下汽车速度会由于摩擦阻力的影响逐渐减小),具体如下图:
图4.3
油门功能按键,通过油门功能按键的按下汽车行驶速度不断增加。
图4.4
刹车功能按键,通过刹车功能按键的按下汽车行驶速度不断减少。
同时代码通过key_out变量的选择,使得两个按键的按下逻辑更为准确,且确保,两个按键都未按下时,数码管显示的汽车行驶速度保持原值不变。
5.不同功能按键按下使数码管显示数据进行切换
图4.5
由于本次实验集多个功能于一体,是汽车仪表盘的综合显示系统设计,由于仪表显示器仅由六个数码管组成,所以需要进行功能切换显示,才能够将汽车行驶里程与汽车速度都给切换显示出来,所以需要逻辑代码,将不同功能按键在操作按下时,不发生逻辑错误,能够正确显示出对应功能按键所显示的对应数据(汽车行驶里程、汽车行驶速度、故障显示数字)。上述代码即为按键的功能逻辑切换代码。
五、测试验证(仿真、硬件测试)
仿真测试文件:
图5.1
仿真结果图:
图5.2
通过将仿真文件与仿真结果可以看到,在功能按键切换时,对应的功能显示数据都能够显示在六个数码管上:在汽车里程功能中,汽车里程数据能够显示在数码管上,并且逐渐增加;在汽车故障显示中,故障显示数字能够切换显示在数码管上;在汽车速度显示功能中,汽车行驶速度会根据汽车油门和刹车进行变化,相应的功能切换显示都是正确的,实验仿真结果也与实验仿真测试文件预测结果一致,实验代码符合实验要求。
六、实验小结
本次实验是一次综合实验,综合前六次实验功能,将所有汽车显示功能集于一体,其复杂性也比较高,难度也相对较大,其中最困难的就是需要进行数码管功能显示切换,这需要严密的逻辑代码,否则,功能切换将会出现错误,当然,在不懈的努力之下,还是完成了这一逻辑代码的编写。
汽车仪表盘,在我们的生活中十分的常见,但是其功能的实现却是那么的不易,这是我在此次课程中的最大体会。当然,一切的学习都要服务于生活,服务于社会,为社会带来价值,为生活提供方便。我相信,随着我的不断努力,终会在这门课中有所收获!
七、实验代码
module sy61(
clk ,
rst_n ,
key_in ,
key_in1 ,
key_in2 ,
key_in3 ,
key_in4 ,
key_in5 ,
Digitron_Out ,
DigitronCS_Out
);
// parameter TIME_20MS = 1000000 ;//为了缩短仿真周期,仿真时可适当缩小
parameter TIME_20MS = 100;
//数码管*******************************************************************
parameter Timex = 8'd200 ;//控制动态扫描周期
parameter CS_NUM= 3'd6 ;//需要用到的数码管个数
parameter N_0 = 8'b0011_1111, N_1 = 8'b0000_0110, N_2 = 8'b0101_1011,
N_3 = 8'b0100_1111, N_4 = 8'b0110_0110, N_5 = 8'b0110_1101,
N_6 = 8'b0111_1101, N_7 = 8'b0000_0111, N_8 = 8'b0111_1111,
N_9 = 8'b0110_1111;
//输入信号定义
input clk ;
input rst_n ;
input key_in;
input key_in1;
input key_in2;
input key_in3;
input key_in4;
input key_in5;
//数码管**********************************************************************
output [7:0]Digitron_Out ;//数码管译码显示数据
output [5:0]DigitronCS_Out;//数码管片选
//输出信号reg定义
reg key_out;
reg key_out1;
reg key_out2;
reg key_out3;
reg key_out4;
reg key_out5;
reg uart_txd_d0;
reg uart_txd_d1;
reg uart_txd_d2;
reg uart_txd_d3;
reg uart_txd_d4;
reg uart_txd_d5;
reg key_ff0;
reg key_ff1;
reg key_ff2;
reg key_ff3;
reg key_ff4;
reg key_ff5;
reg key_ff6;
reg key_ff7;
reg key_ff8;
reg key_ff9;
reg key_ff10;
reg key_ff11;
reg flag1;
reg flag2;
reg flag3;
reg flag4;
reg flag5;
reg[15:0] shake_cnt;
wire shake_flag;
reg[15:0] shake_cnt1;
wire shake_flag1;
reg[15:0] shake_cnt2;
wire shake_flag2;
reg[15:0] shake_cnt3;
wire shake_flag3;
wire f;
reg[15:0] shake_cnt4;
wire shake_flag4;
wire f1;
reg[15:0] shake_cnt5;
wire shake_flag5;
wire f2;
//数码管**************************************************************************
reg [7:0]Digitron_Out ;
reg [5:0]DigitronCS_Out;
reg [23:0]Result ;//待显示数据
reg [23:0]Result1 ;
reg [23:0]Result2 ;
reg [7:0]Count ;//控制动态扫描周期
reg [3:0]SingleNum ;//待显示数据
reg [2:0]cs ;//片选相关中间信号
reg [15:0]CK ;//
reg [31:0]CL ;
/*************************
**************************/
always @(posedge clk or negedge rst_n)begin
if(rst_n==1'b0)begin
key_ff0 <= 1'b1;
key_ff1 <= 1'b1;
end
else begin
key_ff0 <= key_in ;
key_ff1 <= key_ff0;
end
end
always @(posedge clk or negedge rst_n)begin
if(rst_n==1'b0)begin
key_ff2 <= 1'b1;
key_ff3 <= 1'b1;
end
else begin
key_ff2 <= key_in1 ;
key_ff3 <= key_ff2;
end
end
always @(posedge clk or negedge rst_n)begin
if(rst_n==1'b0)begin
key_ff4 <= 1'b1;
key_ff5 <= 1'b1;
end
else begin
key_ff4 <= key_in2 ;
key_ff5 <= key_ff4;
end
end
always @(posedge clk or negedge rst_n)begin
if(rst_n==1'b0)begin
key_ff6 <= 1'b1;
key_ff7 <= 1'b1;
end
else begin
key_ff6 <= key_in3 ;
key_ff7 <= key_ff6;
end
end
always @(posedge clk or negedge rst_n)begin
if(rst_n==1'b0)begin
key_ff8 <= 1'b1;
key_ff9 <= 1'b1;
end
else begin
key_ff8 <= key_in4 ;
key_ff9 <= key_ff9;
end
end
always @(posedge clk or negedge rst_n)begin
if(rst_n==1'b0)begin
key_ff10 <= 1'b1;
key_ff11 <= 1'b1;
end
else begin
key_ff10 <= key_in5 ;
key_ff11 <= key_ff10;
end
end
/**************************************************************************************************************
按键设置
***************************************************************************************************************/
/***********************************************************************************
车速控制按键(刹车与加速(K0加速、K1刹车)
************************************************************************************/
//按键一
always @(posedge clk or negedge rst_n)begin
if(rst_n==1'b0)begin
shake_cnt <= 0;
end
else if(key_ff1!=1'h1)begin
if(shake_flag)
shake_cnt <= shake_cnt;
else
shake_cnt <= shake_cnt + 1;
end
else begin
shake_cnt <= 0;
end
end
assign shake_flag = shake_cnt>=TIME_20MS-1;
always @(posedge clk or negedge rst_n)begin
if(rst_n==1'b0)begin
key_out <= 1'b1;
end
else if(shake_flag)begin
key_out <= 1'b0;
end
else begin
key_out <= 1'b1;
end
end
//按键二
always @(posedge clk or negedge rst_n)begin
if(rst_n==1'b0)begin
shake_cnt1 <= 0;
end
else if(key_ff3!=1'h1)begin
if(shake_flag1)
shake_cnt1 <= shake_cnt1;
else
shake_cnt1 <= shake_cnt1 + 1;
end
else begin
shake_cnt1 <= 0;
end
end
assign shake_flag1 = shake_cnt1>=TIME_20MS-1;
always @(posedge clk or negedge rst_n)begin
if(rst_n==1'b0)begin
key_out1 <= 1'b1;
end
else if(shake_flag1)begin
key_out1 <= 1'b0;
end
else begin
key_out1 <= 1'b1;
end
end
/***********************************************************************************
汽车里程显示按键(K2按键)
************************************************************************************/
//按键三
always @(posedge clk or negedge rst_n)begin
if(rst_n==1'b0)begin
shake_cnt2 <= 0;
end
else if(key_ff5!=1'h1)begin
if(shake_flag2)
shake_cnt2 <= shake_cnt2;
else
shake_cnt2 <= shake_cnt2 + 1;
end
else begin
shake_cnt2 <= 0;
end
end
assign shake_flag2 = shake_cnt2>=TIME_20MS-1;
always @(posedge clk or negedge rst_n)begin
if(rst_n==1'b0)begin
key_out2 <= 1'b1;
end
else if(shake_flag2)begin
key_out2 <= 1'b0;
end
else begin
key_out2 <= 1'b1;
end
end
always @( posedge clk )
begin
if(!rst_n)begin
CL <= 32'd0 ;
//flag <= 1'b0;
end
else if(CL == 32'd10000)begin
CL <= 32'd0 ;
//flag <=~flag;
end
else
CL <= CL + 32'd1 ;
end
always @( posedge clk )
begin
if(!rst_n)
begin
Result1 <= 24'd0 ;
end
else
begin
if(CL == 32'd10000)begin
Result1[3:0]<=Result1[3:0]+4'd1;
if(Result1[3:0]==4'd10)begin
Result1[7:4]<=Result1[7:4]+4'd1;//个位进十位
Result1[3:0]<=4'd0;
end
else if(Result1[7:4]==4'd10)begin
Result1[11:8]<=Result1[11:8]+4'd1;//十位进百位
Result1[7:4]<=4'd0;
end
else if(Result1[11:8]==4'd10)begin
Result1[15:12]<=Result1[15:12]+4'd1;//百位进千位
Result1[11:8]<=4'd0;
end
else if(Result1[15:12]==4'd10)begin
Result1[19:16]<=Result1[19:16]+4'd1;//千位进万位
Result1[15:12]<=4'd0;
end
else if(Result1[19:16]==4'd10)begin
Result1[23:20]<=Result1[23:20]+4'd1;//万位进十万位
Result1[19:16]<=4'd0;
end
else if(Result1[23:20]==4'd10)begin
Result1<= Result1; //十万位满清零
end
end
end
end
/*************************************************************************************
汽车故障指示(K3\K4\K5)
***************************************************************************************/
//按键一
always @(posedge clk or negedge rst_n)begin
if(rst_n==1'b0)begin
shake_cnt3 <= 0;
end
else if(key_ff7!=1'h1)begin
if(shake_flag3)
shake_cnt3 <= shake_cnt3;
else
shake_cnt3 <= shake_cnt3 + 1;
end
else begin
shake_cnt3 <= 0;
end
end
assign shake_flag3 = shake_cnt3>=TIME_20MS-1;
always @(posedge clk or negedge rst_n)begin
if(rst_n==1'b0)begin
key_out3 <= 1'b1;
end
else if(shake_flag3)begin
key_out3 <= 1'b0;
end
else begin
key_out3 <= 1'b1;
end
end
assign f = (~uart_txd_d0) && (uart_txd_d1);
always@(posedge clk or negedge rst_n)begin
if(rst_n==1'b0)begin
uart_txd_d0 <= 1'b1;
uart_txd_d1 <= 1'b1;
end
else begin
uart_txd_d0 <= key_out3;
uart_txd_d1 <= uart_txd_d0;
end
end
//按键二
always @(posedge clk or negedge rst_n)begin
if(rst_n==1'b0)begin
shake_cnt4 <= 0;
end
else if(key_ff9!=1'h1)begin
if(shake_flag4)
shake_cnt4 <= shake_cnt4;
else
shake_cnt4 <= shake_cnt4 + 1;
end
else begin
shake_cnt4 <= 0;
end
end
assign shake_flag4 = shake_cnt4>=TIME_20MS-1;
always @(posedge clk or negedge rst_n)begin
if(rst_n==1'b0)begin
key_out4 <= 1'b1;
end
else if(shake_flag4)begin
key_out4 <= 1'b0;
end
else begin
key_out4 <= 1'b1;
end
end
assign f1 = (~uart_txd_d2) && (uart_txd_d3);
always@(posedge clk or negedge rst_n)begin
if(rst_n==1'b0)begin
uart_txd_d2 <= 1'b1;
uart_txd_d3 <= 1'b1;
end
else begin
uart_txd_d2 <= key_out4;
uart_txd_d3 <= uart_txd_d2;
end
end
//按键三
always @(posedge clk or negedge rst_n)begin
if(rst_n==1'b0)begin
shake_cnt5 <= 0;
end
else if(key_ff11!=1'h1)begin
if(shake_flag5)
shake_cnt5 <= shake_cnt5;
else
shake_cnt5 <= shake_cnt5 + 1;
end
else begin
shake_cnt5 <= 0;
end
end
assign shake_flag5 = shake_cnt5>=TIME_20MS-1;
always @(posedge clk or negedge rst_n)begin
if(rst_n==1'b0)begin
key_out5 <= 1'b1;
end
else if(shake_flag5)begin
key_out5 <= 1'b0;
end
else begin
key_out5 <= 1'b1;
end
end
assign f2 = (~uart_txd_d4) && (uart_txd_d5);
always@(posedge clk or negedge rst_n)begin
if(rst_n==1'b0)begin
uart_txd_d4 <= 1'b1;
uart_txd_d5 <= 1'b1;
end
else begin
uart_txd_d4 <= key_out5;
uart_txd_d5 <= uart_txd_d4;
end
end
always @( posedge clk )
begin
if(!rst_n)
begin
Result2<= 24'd0;
end
else
begin
if(f==1'b1)
begin
Result2[3:0]<=4;//个位
Result2[7:4]<=4;//十位
Result2[11:8]<=4;//百位
Result2[15:12]<=4;//千位
Result2[19:16]<=4;//万位
Result2[23:20]<=4;//十万位
end
else if(f1==1'b1)
begin
Result2[3:0]<=5;//个位
Result2[7:4]<=5;//十位
Result2[11:8]<=5;//百位
Result2[15:12]<=5;//千位
Result2[19:16]<=5;//万位
Result2[23:20]<=5;//十万位
end
else if(f2==1'b1)
begin
Result2[3:0]<=2;//个位
Result2[7:4]<=2;//十位
Result2[11:8]<=2;//百位
Result2[15:12]<=2;//千位
Result2[19:16]<=2;//万位
Result2[23:20]<=2;//十万位
end
end
end
//***********************************************************************
//******************************************************************************************************************************************
always @( posedge clk )
begin
if(!rst_n)begin
CK <= 16'd0 ;
//flag <= 1'b0;
end
else if(CK == 16'd10000)begin
CK <= 16'd0 ;
//flag <=~flag;
end
else
CK <= CK + 16'd1 ;
end
//**************************************************************************
always @( posedge clk )
begin
//if(flag==1'b1)begin //*******************************************
if(!rst_n)
begin
Result<= 24'd0;
flag1<= 1'b1;
flag2<= 1'b1;
flag3<= 1'b1;
flag4<= 1'b1;
flag5<= 1'b1;
end
else
begin
if(key_out==1'd0&&key_out1==1'd1&&key_out2==1'd1&&key_out3==1'd1&&key_out4==1'd1&&key_out5==1'd1)
begin
if(CK == 16'd10000)begin //*******************************************
Result[3:0]<=Result[3:0]+4'd1;
if(Result[3:0]==4'd10)begin
Result[7:4]<=Result[7:4]+4'd1;//个位进十位
Result[3:0]<=4'd0;
end
else if(Result[7:4]==4'd10)begin
Result[11:8]<=Result[11:8]+4'd1;//十位进百位
Result[7:4]<=4'd0;
end
else if(Result[11:8]==4'd10)begin
Result[15:12]<=Result[15:12]+4'd1;//百位进千位
Result[11:8]<=4'd0;
end
else if(Result[15:12]==4'd10)begin
Result[19:16]<=Result[19:16]+4'd1;//千位进万位
Result[15:12]<=4'd0;
end
else if(Result[19:16]==4'd10)begin
Result[23:20]<=Result[23:20]+4'd1;//万位进十万位
Result[19:16]<=4'd0;
end
else if(Result[23:20]==4'd10)begin
Result<= Result; //十万位满清零
end
//&&Result[19:16]==4'd9&&Result[15:12]==4'd9&&Result[11:8]==4'd9&&Result[7:4]==4'd9&&Result[3:0]==4'd9
end //**************************
end
else if(key_out==1'd1&&key_out1==1'd0&&key_out2==1'd1&&key_out3==1'd1&&key_out4==1'd1&&key_out5==1'd1)
begin
if(CK == 16'd10000)begin //*******************************************
if(Result!= 24'd0)
begin
Result[3:0]<=Result[3:0]-4'd1;
if(Result[3:0]==4'd0&&Result[23:4]!=4'd0)
flag1<=1'b0;
else if(flag1==1'b0&&Result[23:4]!=4'd0)begin
flag1<=1'b1;
Result[3:0]<=4'd9;
Result[7:4]<=Result[7:4]-4'd1;//个位不足十位减一
if(Result[7:4]==4'd0&&Result[23:8]!=4'd0)
flag2<=1'b0;
end
//*******************************************
else if(flag2==1'b0&&Result[23:8]!=4'd0)begin
//if(Result[23:8]!=4'd0)begin
flag2<=1'b1;
Result[7:4]<=4'd9;
Result[11:8]<=Result[11:8]-4'd1;//十位不足百位减一
if(Result[11:8]==4'd0&&Result[23:12]!=4'd0)
flag3<=1'b0;
/*end
else
Result[7:4]<=4'd0;*/
end
else if(flag3==1'b0&&Result[23:12]!=4'd0)begin
//if(Result[23:12]!=4'd0)begin
flag3<=1'b1;
Result[11:8]<=4'd9;
Result[15:12]<=Result[15:12]-4'd1;//百位不足千位减一
if(Result[15:12]==4'd0&&Result[23:16]!=4'd0)
flag4<=1'b0;
/*end
else
Result[11:8]<=4'd0;*/
end
else if(flag4==1'b0&&Result[23:16]!=4'd0)begin
//if(Result[23:16]!=4'd0)begin
flag4<=1'b1;
Result[15:12]<=4'd9;
Result[19:16]<=Result[19:16]-4'd1;//千位不足万位减一
if(Result[19:16]==4'd0&&Result[23:20]!=4'd0)
flag5<=1'b0;
/*end
else
Result[15:12]<=4'd0;*/
end
else if(flag5==1'b0&&Result[23:20]!=4'd0)begin
//if(Result[23:20]!=4'd0)begin
flag5<=1'b1;
Result[19:16]<=4'd9;
Result[23:20]<=Result[23:20]-4'd1;//万位不足十万位减一
/*end
else
Result[19:16]<=4'd0;*/
end
else if(Result[23:20]==4'd0)begin
Result[23:20]<=4'd0;//万位不足十万
end
else
Result<=Result;
end
else
Result<= 24'd0;
//end//*********************************************************
end
end
end
end
//*******************************************************************************
//数码管**********************************************************************
//-----设置动态扫描周期-------------------
always @( posedge clk )
begin
if(!rst_n)
Count <= 8'd0 ;
else if(Count == Timex)
Count <= 8'd0 ;
else
Count <= Count + 8'd1 ;
end
//---根据扫描周期产生片选信号----------
always @ ( posedge clk )
begin
if(!rst_n)
cs <= 3'd0 ;
else if(Count == Timex)
begin
if(cs == CS_NUM - 3'd1)
cs <= 3'd0 ;
else
cs <= cs + 3'd1 ;
end
end
//------结合电路将片选信号译码---------
always @ ( posedge clk )
begin
if(!rst_n)
DigitronCS_Out <= 6'd0 ;
else
begin
case(cs)
3'd0: DigitronCS_Out <= 6'b11_1110;
3'd1: DigitronCS_Out <= 6'b11_1101;
3'd2: DigitronCS_Out <= 6'b11_1011;
3'd3: DigitronCS_Out <= 6'b11_0111;
3'd4: DigitronCS_Out <= 6'b10_1111;
3'd5: DigitronCS_Out <= 6'b01_1111;
default: DigitronCS_Out <= 6'b11_1111;
endcase
end
end
//---------根据输入将待显示分配到个位、十位----------------
always @ ( posedge clk )
begin
if(!rst_n)
SingleNum <= 4'd0 ;
else
begin
if(key_out2==1'd1&&key_out3==1'd1&&key_out4==1'd1&&key_out5==1'd1)begin
case(cs)
3'd0: SingleNum <= Result[3:0];//个位
3'd1: SingleNum <= Result[7:4];//十位
3'd2: SingleNum <= Result[11:8];//百位
3'd3: SingleNum <= Result[15:12];//千位
3'd4: SingleNum <= Result[19:16];//万位
3'd5: SingleNum <= Result[23:20];//十万位
/*3'd5: SingleNum <= Result2[3:0];//个位
3'd6: SingleNum <= Result2[7:4];//十位*/
//key_out==1'd1&&key_out1==1'd1&&key_out2==1'd0&&key_out3==1'd1&&key_out4==1'd1&&key_out5==1'd1
default: SingleNum <= 4'd0;
endcase
end
else if(key_out==1'd1&&key_out1==1'd1&&key_out2==1'd0&&key_out3==1'd1&&key_out4==1'd1&&key_out5==1'd1)begin
case(cs)
3'd0: SingleNum <= Result1[3:0];//个位
3'd1: SingleNum <= Result1[7:4];//十位
3'd2: SingleNum <= Result1[11:8];//百位
3'd3: SingleNum <= Result1[15:12];//千位
3'd4: SingleNum <= Result1[19:16];//万位
3'd5: SingleNum <= Result1[23:20];//十万位
/*3'd5: SingleNum <= Result2[3:0];//个位
3'd6: SingleNum <= Result2[7:4];//十位*/
default: SingleNum <= 4'd0;
endcase
end
else if(key_out==1'd1&&key_out1==1'd1&&key_out2==1'd1&&(key_out3==1'd0||key_out4==1'd0||key_out5==1'd0))begin
case(cs)
3'd0: SingleNum <= Result2[3:0];//个位
3'd1: SingleNum <= Result2[7:4];//十位
3'd2: SingleNum <= Result2[11:8];//百位
3'd3: SingleNum <= Result2[15:12];//千位
3'd4: SingleNum <= Result2[19:16];//万位
3'd5: SingleNum <= Result2[23:20];//十万位
/*3'd5: SingleNum <= Result2[3:0];//个位
3'd6: SingleNum <= Result2[7:4];//十位*/
default: SingleNum <= 4'd0;
endcase
end
end
end
//---待显示数据译码成共阴极数码管驱动格式-------
always @( posedge clk )
begin
if(!rst_n)
Digitron_Out <= 8'd0 ;
else
begin
case(SingleNum)
4'd0: Digitron_Out <= N_0;//个位
4'd1: Digitron_Out <= N_1;//十位
4'd2: Digitron_Out <= N_2;//个位
4'd3: Digitron_Out <= N_3;//十位
4'd4: Digitron_Out <= N_4;//个位
4'd5: Digitron_Out <= N_5;//十位
4'd6: Digitron_Out <= N_6;//个位
4'd7: Digitron_Out <= N_7;//十位
4'd8: Digitron_Out <= N_8;//个位
4'd9: Digitron_Out <= N_9;//十位
default: Digitron_Out <= 8'd0;
endcase
end
end
endmodule
八、测试代码
// Copyright (C) 1991-2013 Altera Corporation
// Your use of Altera Corporation's design tools, logic functions
// and other software and tools, and its AMPP partner logic
// functions, and any output files from any of the foregoing
// (including device programming or simulation files), and any
// associated documentation or information are expressly subject
// to the terms and conditions of the Altera Program License
// Subscription Agreement, Altera MegaCore Function License
// Agreement, or other applicable license agreement, including,
// without limitation, that your use is for the sole purpose of
// programming logic devices manufactured by Altera and sold by
// Altera or its authorized distributors. Please refer to the
// applicable agreement for further details.
// *****************************************************************************
// This file contains a Verilog test bench template that is freely editable to
// suit user's needs .Comments are provided in each section to help the user
// fill out necessary details.
// *****************************************************************************
// Generated on "11/23/2022 11:35:35"
// Verilog Test Bench template for design : sy61
//
// Simulation tool : ModelSim (Verilog)
//
`timescale 1 ps/ 1 ps
module sy61_vlg_tst();
// constants
// general purpose registers
reg eachvec;
// test vector input registers
reg clk;
reg key_in;
reg key_in1;
reg key_in2;
reg key_in3;
reg key_in4;
reg key_in5;
reg rst_n;
// wires
wire [5:0] DigitronCS_Out;
wire [7:0] Digitron_Out;
// assign statements (if any)
sy61 i1 (
// port map - connection between master ports and signals/registers
.DigitronCS_Out(DigitronCS_Out),
.Digitron_Out(Digitron_Out),
.clk(clk),
.key_in(key_in),
.key_in1(key_in1),
.key_in2(key_in2),
.key_in3(key_in3),
.key_in4(key_in4),
.key_in5(key_in5),
.rst_n(rst_n)
);
initial
begin
clk = 0 ;
rst_n = 0 ;
key_in = 1'b1 ;
key_in1 = 1'b1 ;
key_in2 = 1'b1 ;
key_in3 = 1'b1 ;
key_in4 = 1'b1 ;
key_in5 = 1'b1 ;
#1000000;
rst_n= 1 ;
key_in= 1'b0 ;
#1000000;
key_in = 1'b1 ;
#1000000;
key_in1 = 1'b0 ;
#1000000;
key_in1 = 1'b1 ;
#1000000;
key_in2 = 1'b0 ;
#1000000;
key_in2 = 1'b1 ;
#1000000;
key_in3 = 1'b0 ;
#10000;
key_in3 = 1'b1 ;
#10000;
key_in5 = 1'b0 ;
#10000;
key_in5 = 1'b1 ;
#10000;
$stop;
end
always #10 clk = ~clk ;
endmodule