2024寒假在家一起练-基于Lattice MXO2的小脚丫FPGA核心板 - Type C接口设计具有启动、停止、递增和清除功能的秒表
该项目使用了FPGA编程,实现了具有启动、停止、递增和清除功能的秒表的设计,它的主要功能为:具有启动、停止、递增和清除功能的秒表。
标签
FPGA
数字逻辑
2024寒假一起练
碧24可以
更新2024-04-02
北京理工大学
94

基于Lattice MXO2的小脚丫FPGA核心板 - Type C接口的项目实验报告

 

 

 

具有启动、停止、递增和清楚功能的秒表

一、  项目需求

通过小脚丫FPGA核心板上的2个数码管和轻触按键制作一个秒表,通过按键来控制秒表的功能,并在数码管上显示数值。

需要达到以下功能:

1.  使用七段显示器作为输出设备,在小脚丫FPGA核心板上创建一个2位数秒表。

2.  秒表应从 0.0 秒计数到 9.9秒,然后翻转,计数值每0.1秒精确更新一次。

3.秒表使用四个按钮输入:开始、停止、增量和清除(重置)。 开始输入使秒表开始以10Hz时钟速率递增(即每0.1秒计数一次); 停止输入使计数器停止递增,但使数码管显示当前计数器值; 每次按下按钮时,增量输入都会导致显示值增加一次,无论按住增量按钮多长时间; 复位/清除输入强制计数器值为零。

 

二、  需求分析

(一)功能需求:

1. 显示设备:使用小脚丫FPGA核心板上的两个七段数码管作为显示设备,显示秒表的值。

2. 秒表功能:能够实现从0.0秒计数到9.9秒,在达到9.9秒后自动翻转到0.0秒,精确度为0.1秒,即每0.1秒更新一次数值。

3. 按键输入:设计四个按钮用于控制秒表的功能:

- 开始按钮:按下开始时秒表开始计时,每0.1秒递增一次;

- 停止按钮:按下停止时,停止计时但保持当前计数值显示;

- 增量按钮:按下增量时,显示值立即增加一次,按住增量按钮无效;

- 清除按钮:按下清除时,强制将计数器值归零。

(二)系统设计:

1.模块划分:设计秒表模块、按键输入模块和数码管显示模块。

2.秒表计时:通过时钟信号进行计时,实现从0.0秒到9.9秒的计数,达到9.9秒后自动翻转。

3. 按键控制:根据按键输入控制秒表的开始、停止、增量和清除功能。

4. 数码管显示:根据计数值将对应的数字显示在两个七段数码管上,实现秒表数值的实时显示。

(三)性能需求:

1. 稳定性:秒表功能稳定可靠,显示精确度达到0.1秒。

2. 按键响应:按键响应迅速,操作流畅,确保用户体验友好。

3. 节约资源:设计合理,尽量节约FPGA资源,提高系统性能。

(四)验收标准:

1. 功能验证:秒表能够满足从0.0秒到9.9秒的计时要求,并能正确响应按键控制功能。

2. 显示正确:数码管上显示的数值能够准确反映秒表的计时情况。

3. 用户操作:按键操作顺畅,功能实现符合预期,系统稳定可靠。

 

三、  实现的方式

WebIDE环境下进行Verilog代码编程、综合、仿真、生成JED代码并下载到FPGA中进行验证。

每一个功能模块都通过GPT等大模型来生成,进行验证、修改后整合在一起实现所需的功能。

(一)设计方案:

1. 秒表模块设计:

- 使用FPGA内部时钟模块作为计时基准,每0.1秒触发一次计数更新;

- 设计状态机,实现秒表的计数和翻转功能。

2. 按键输入模块设计:

- 使用GPIO接口读取四个轻触按键的状态,分别对应开始、停止、增量和清除功能。

3. 数码管显示模块设计:

- 利用FPGA内部七段数码管驱动器模块控制两个七段数码管的显示;

- 将秒表的计数值转换为数码管对应的显示码,实时显示在数码管上。

(二)实现步骤:

1. 秒表计时功能实现:

- 使用FPGA内部时钟作为时间基准,每0.1秒触发一次计数,实现秒表的计时功能;

- 设计状态机控制计数递增和翻转。

2. 按键控制功能实现:

- 根据按键输入状态,实现开始、停止、增量和清除功能的响应;

- 开始按钮触发计时递增,停止按钮暂停计时并显示当前计数值,增量按钮使计数值增加一次,清除按钮将计数值归零。

3. 数码管显示实现:

- 将计数值转换为数码管对应的显示码,通过七段数码管驱动器在两个数码管上显示秒表数值;确保数码管显示的值与秒表计数值同步更新,保持显示精确度。

通过以上设计和实现,可以实现使用小脚丫FPGA核心板上的两个七段数码管和轻触按键制作一个秒表,并实现开始、停止、增量和清除功能的控制。同时,在数码管上能够准确显示秒表的计数数值,满足所需功能要求。

四、功能框图

五、代码

top.v
module top(

   input          clk_12M,

   input          reset_n,

   input          stop_n,

   input          start_n,//开始

   input          add_n,//递增

   output [7:0]   seg1,//数码管

   output [7:0]   seg2,//数码管

   output   [1:0] seg_digit

);

assign   seg_digit = 2'b00;

//时钟分频

wire  clk_10;

clk_div i_clk_div(

   .clk_12M    (clk_12M),

   .reset_n    (reset_n),

   .clk_10        (clk_10)

);

 

//按键消抖

wire stop_pulse;

wire start_pulse;  

wire add_pulse; 

debounce i1_debounce(clk_12M, reset_n, stop_n, stop_pulse);

debounce i2_debounce(clk_12M, reset_n, start_n, start_pulse);

debounce i3_debounce(clk_12M, reset_n, add_n, add_pulse);

 

//计时器

wire  [3:0] digit1;

wire  [3:0] digit2;

clock i_clock(

   .clk_12M    (clk_12M),

   .clk_10        (clk_10),

   .reset_n    (reset_n),

   .stop_pulse    (stop_pulse),

   .start_pulse   (start_pulse),

   .add_pulse     (add_pulse),

   .digit1        (digit1),

   .digit2        (digit2)

);

 

//数码管显示

digit_display  i_digit_display(

   .digit1        (digit1),

   .digit2        (digit2),

   .seg1       (seg1),

   .seg2       (seg2)

);

 

endmodule

 

clk_div.v

`timescale 1ns/1ns

 

//时钟分频:12MHz -> 10Hz

module clk_div(

   input clk_12M,

   input reset_n,

   output   clk_10

);

parameter DIVIDER = 12_000_00;

// parameter DIVIDER = 5;//for test

 

reg   [31:0] cnt;

always @(posedge clk_12M) begin

   if(~reset_n)

      cnt <= 0;

   else begin

      if(cnt < DIVIDER - 1)

         cnt <= cnt + 32'd1;

      else

         cnt <= 0;

   end

end

assign clk_10 = (cnt == DIVIDER - 1) ? 1 : 0;

 

endmodule


clock.v

timescale 1ns/1ns

 

module clock(

   input       clk_12M,

   input       clk_10,

   input       reset_n,

   input       stop_pulse,

   input       start_pulse,

   input       add_pulse,

   output reg[3:0]   digit1,  //0.1秒

   output reg[3:0]   digit2   //1秒

);

reg   [31:0]   cnt;

reg         if_stop;

 

always @(posedge clk_12M) begin

   if(~reset_n)

      if_stop <= 1;

   else begin

      if(stop_pulse)

         if_stop <= 1;

      else if(start_pulse)

         if_stop <= 0;

      else

         if_stop <= if_stop;

   end

end
always@(posedge clk_12M)begin

   if(~reset_n)begin

      cnt   <= 0;

      digit1 <= 0;

   end

   else begin

      if(add_pulse || (clk_10 && if_stop == 0))begin

         if(digit1 == 9)

            digit1 <= 0;

         else

            digit1 <= digit1 + 1;

      end

      else

         digit1 <= digit1;

   end

end

 

always @(posedge clk_12M) begin

   if(~reset_n)

      digit2 <= 0;

   else begin

      if((add_pulse || (clk_10 && if_stop == 0)) && digit1 == 9)begin

         if(digit2 == 9)

            digit2 <= 0;

         else

            digit2 <= digit2 + 1;

      end

      else

         digit2 <= digit2;

   end

end

 

 

 

endmodule


 


 


 debounce.v

`timescale 1ns/1ns

 

module debounce(

   input clk_12M,

   input reset_n,

   input btn,

   output   pulse

);

parameter   HOLD = 120_000; //10ms

// parameter   HOLD = 3; //1for test

reg   [31:0] cnt;

reg      btn_reg, btn_reg1;

always @(posedge clk_12M) begin

   btn_reg1 <= btn_reg;

   if(~reset_n)begin

      btn_reg <= 1;

      cnt <= 0;

   end

   else begin

      if(btn == 0)begin

         if(cnt < HOLD)

            cnt <= cnt + 1;

         else

            btn_reg <= 0;

      end

      else begin

         cnt <= 0;

         btn_reg <= 1;

      end

   end

end

 

assign   pulse = btn_reg1 & ~btn_reg;

 

 

endmodule

 

digit_display.v

`timescale 1ns/1ns

 

module   digit_display(

   input [3:0] digit1,

   input [3:0] digit2,

   output reg[7:0]   seg1,

   output reg[7:0]   seg2

);

 

 

//个位,无小数点

always@(*)begin

   case(digit1)

      4'd0: seg1  = 8'b1111_1100;

      4'd1: seg1  = 8'b0110_0000;

      4'd2: seg1  = 8'b1101_1010;

      4'd3: seg1  = 8'b1111_0010;

      4'd4: seg1  = 8'b0110_0110;

      4'd5: seg1  = 8'b1011_0110;

      4'd6: seg1  = 8'b1011_1110;

      4'd7: seg1  = 8'b1110_0000;

      4'd8: seg1  = 8'b1111_1110;

      4'd9: seg1  = 8'b1111_0110;

      default: seg1 = 8'b0000_0000;

   endcase

end

 

//十位

always@(*)begin

   case(digit2)

      4'd0: seg2  = 8'b1111_1101;

      4'd1: seg2  = 8'b0110_0001;

      4'd2: seg2  = 8'b1101_1011;

      4'd3: seg2  = 8'b1111_0011;

      4'd4: seg2  = 8'b0110_0111;

      4'd5: seg2  = 8'b1011_0111;

      4'd6: seg2  = 8'b1011_1111;

      4'd7: seg2  = 8'b1110_0001;

      4'd8: seg2  = 8'b1111_1111;

      4'd9: seg2  = 8'b1111_0111;

      default: seg2 = 8'b0000_0000;

   endcase

end

 

endmodule


五、仿 真波形图

进位逻辑

按键效果

七、FPGA的资源利用说明


Design Summary:
Number of registers: 155 out of 4635 (3%)
PFU registers: 155 out of 4320 (4%)
PIO registers: 0 out of 315 (0%)
Number of SLICEs: 163 out of 2160 (8%)
SLICEs as Logic/ROM: 163 out of 2160 (8%)
SLICEs as RAM: 0 out of 1620 (0%)
SLICEs as Carry: 123 out of 2160 (6%)
Number of LUT4s: 326 out of 4320 (8%)
Number used as logic LUTs: 80
Number used as distributed RAM: 0
Number used as ripple logic: 246
Number used as shift registers: 0
Number of PIO sites used: 23 + 4(JTAG) out of 105 (26%)
Number of block RAMs: 0 out of 10 (0%)
Number of GSRs: 0 out of 1 (0%)
EFB used : No
JTAG used : No
Readback used : No
Oscillator used : No
Startup used : No
POR : On
Bandgap : On
Number of Power Controller: 0 out of 1 (0%)
Number of Dynamic Bank Controller (BCINRD): 0 out of 6 (0%)
Number of Dynamic Bank Controller (BCLVDSO): 0 out of 1 (0%)
Number of DCCA: 0 out of 8 (0%)
Number of DCMA: 0 out of 2 (0%)
Number of PLLs: 0 out of 2 (0%)
Number of DQSDLLs: 0 out of 2 (0%)
Number of CLKDIVC: 0 out of 4 (0%)
Number of ECLKSYNCA: 0 out of 4 (0%)
Number of ECLKBRIDGECS: 0 out of 2 (0%)

1. 输入控制:使用轻触按键资源作为输入控制器,通过按键的按下和释放来检测操作员的操作,包括开始、停止、增量和清除功能。

2. 计数器递增:需要使用FPGA内部的计数器模块来实现秒表的计数功能。通过10Hz的时钟信号来控制计数器的递增,实现每0.1秒更新一次计数值的功能。

3. 数码管显示:利用FPGA内部逻辑资源和数码管驱动器模块来实现数码管显示功能。根据计数器的数值,将对应的七段显示编码发送到数码管上,实现秒表值的显示。

4. 按钮状态检测:需要使用FPGAIO资源来读取轻触按键的状态,判断用户是按下按钮还是释放按钮,从而控制相应的功能。

八、实现的结果


 

附件下载
archive.zip
2024寒假在家一起练- 基于Lattice MXO2的小脚丫FPGA核心板 - Type C接口具有启动、停止、递增和清除功能的秒表-乔振宁-1120202792-QQ1106562752
团队介绍
北京理工大学、乔振宁
团队成员
碧24可以
乔振宁
北京理工大学
评论
0 / 100
查看更多
猜你喜欢
2024年寒假练 - 基于Lattice MXO2的小脚丫FPGA核心板 - Type C接口制作具有启动、停止、递增和清除功能的秒表该项目使用了Lattice MXO2的小脚丫FPGA核心板 - Type C接口,实现了具有启动、停止、递增和清除功能的秒表的设计,它的主要功能为:具有启动、停止、递增和清除功能的秒表。
学分+1
117
2024年寒假练-基于Lattice MXO2的小脚丫FPGA核心板 - Type C接口实现具有启动、停止、递增和清除功能的秒表该项目使用了Lattice MXO2的小脚丫FPGA核心板 - Type C接口,实现了具有启动、停止、递增和清除功能的秒表的设计,它的主要功能为:使用七段显示器作为输出设备,在小脚丫FPGA核心板上创建一个2位数秒表。 秒表应从 0.0 秒计数到 9.9秒,然后翻转,计数值每0.1秒精确更新一次。 秒表使用四个按钮输入:开始、停止、增量和清除(重置)。 开始输入使秒表开始以10Hz时钟速率递增(即每0.1秒计数一次); 停止输入使计数器停止递增,但使数码管显示当前计数器值; 每次按下按钮时,增量输入都会导致显示值增加一次,无论按住增量按钮多长时间; 复位/清除输入强制计数器值为零。。
Aurora.
119
基于Lattice MXO2的小脚丫FPGA核心板接口实现具有启动、停止、递增和清除功能的秒表该项目使用了Lattice MXO2的小脚丫FPGA核心板 - Type C接口,实现了具有启动、停止、递增和清除功能的秒表的设计,它的主要功能为:通过按键来控制秒表的功能,并在数码管上显示数值。。
kkkk21111
75
硬禾服务号
关注最新动态
0512-67862536
info@eetree.cn
江苏省苏州市苏州工业园区新平街388号腾飞创新园A2幢815室
苏州硬禾信息科技有限公司
Copyright © 2024 苏州硬禾信息科技有限公司 All Rights Reserved 苏ICP备19040198号