2024寒假在家一起练-基于小脚丫FPGA核心板实现秒表功能
该项目使用了基于Lattice MXO2的小脚丫FPGA核心板,实现了具有启动、停止、递增和清除功能的秒表的设计,它的主要功能为:1. 设计一个2位数秒表,显示范围从0.0到9.9秒,计时溢出后重新从0.0秒开始计时。 2. 使用七段数码管作为输出设备,用于在秒表上显示实时计时数值,精确度为0.1秒。 3. 提供四个按钮输入功能:开始、停止、增量和清除。按键控制秒表的启动、暂停、增量和清零功能。。
标签
FPGA
开发板
Walnut
更新2024-04-02
北京理工大学
82

   2024寒假在家一起练-基于Lattice MXO2的小脚丫FPGA核心板实现具有启动、停止、递增和清除功能的秒表

一、项目宗旨

1. 结合数字电路书本知识,深刻理解数字逻辑的功能实现及设计流程

2. 培养工程化设计理念、规范化的设计流程及解决未知问题的能力

3. 探索使用行业新工具在项目研发中存在的问题和解决方法

二、项目需求

本项目旨在利用小脚丫FPGA核心板上的两个数码管和轻触按键,设计并实现一个秒表功能。具体需求包括:

1. 设计一个2位数秒表,显示范围从0.0到9.9秒,计时溢出后重新从0.0秒开始计时。

2. 使用七段数码管作为输出设备,用于在秒表上显示实时计时数值,精确度为0.1秒。

3. 提供四个按钮输入功能:开始、停止、增量和清除。按键控制秒表的启动、暂停、增量和清零功能。

 

三、需求分析

1. 显示要求:数码管显示的秒表数值应准确到0.1秒,即每0.1秒更新一次显示值。

按键功能说明:

2. 开始按钮:按下开始按钮后,秒表以10Hz的速率递增,即每0.1秒更新一次计数值。

3. 停止按钮:按下停止按钮后,暂停秒表的递增,但数码管继续显示当前计数值。

4. 增量按钮:每次按下增量按钮,计数值增加1,无论按键按下时间长短。

5. 清除按钮:按下清除按钮后,强制将计数值重置为0.0秒。

通过以上需求分析,我们明确了秒表系统的功能需求,包括显示范围、数码管精度、按键功能等,为后续设计和实现提供了明确的指导方向。

 

四、项目设计思路

1. 时钟模块设计:首先设计一个时钟模块,用于产生稳定的时钟信号。

2. 计时模块设计:设计一个计时模块,用于实现秒表功能。这个模块需要接收时钟信号,并能够根据开始、停止、重置、增加时间等按钮信号来控制计时逻辑。

3. 按钮控制模块设计:设计一个按钮控制模块,用于接收外部按钮信号并对其进行去抖动处理。通过检测按钮状态的变化,控制计时模块的操作。

4. 数码管显示模块设计:最后设计一个数码管显示模块,用于将计时模块中的时间信息显示在7段数码管上。

5. 综合与仿真:将上述模块进行综合并进行时序仿真,验证整个秒表设计的功能正确性和稳定性。

通过以上设计思路,可以实现一个具有启动、停止、递增和清除功能的秒表设计,实现基本的计时功能并通过按钮来控制操作。

 

五、实现方式

1. 秒表模块(watch.v):

(1)定义了输入信号:时钟信号(clk)、重置按钮信号(reset_btn)、开始按钮信号(start_btn)、停止按钮信号(stop_btn)、增量按钮信号(inc_btn);输出信号:两个数码管段控制信号(seg_display11、seg_display22)。

(2)使用寄存器存储秒数(seconds)和亚秒数(subSeconds),运行标志(run),以及计数器(counters)和毫秒计数器(counterms)。

(3)初始化数码管显示模式数组(seg)。

(4)根据按键信号进行操作:重置按钮置零秒表、开始按钮启动计数、停止按钮停止计数、增量按钮每按一次增加计数。

(5)计算秒数和毫秒数,更新数码管显示值。

(6)使用按钮防抖模块(debounce)对按键信号进行去抖处理。

 

2. 按钮防抖模块(btns.v):

(1)定义了输入信号:时钟信号(clk)、复位信号(rst)、按键信号(key);输出信号:去抖后的按键脉冲信号(key_pulse)。

(2)使用寄存器存储前一个和当前的按键值,以及计数器进行延迟检测。

(3)检测按键信号的上升沿,生成去抖后的按键脉冲信号。

(4)生成20ms延迟,用于去抖处理。

(5)在延迟后检测按键信号的上升沿并生成按键脉冲信号。

 

六、硬件介绍

1. LCMXO2-4000HC-4MG132C

Lattice MachXO2系列的可编程逻辑器件(PLD)是一种革命性的器件,具有低成本、低功耗和高性能的特点,适合用于各种应用领域。LCMXO2-4000HC-4MG132C的硬件特性介绍如下:

(1)逻辑单元数:4320

(2)逻辑阵列块数:540

(3)输入/输出引脚:105

(4)电压-供电:2.375V ~ 3.465V

(5)最高工作频率:269MHz

(6)工作温度:0°C ~ 85°C

 

2. LPC11U35FHI33

LPC11U35FHI33是恩智浦(NXP)推出的一款32位ARM Cortex-M0微控制器,针对低功耗、高性能的嵌入式应用而设计。LPC11U35FHI33的硬件特点介绍如下:

(1)处理器核心:基于ARM Cortex-M0 32位处理器核心

(2)存储器:包括64KB的闪存(用于存储程序代码)和8KB的SRAM(用于数据存储)

(3)输入/输出引脚:26

(4)电压-供电:1.8V ~ 3.6V

(5)工作频率:50MHz

(6)工作温度:-40°C ~ +85°C

 

七、代码及解释

1. watch.v

module watch(
input wire clk, // Clock signal
input wire reset_btn, // Reset button signal
input wire start_btn, // Start button signal
input wire stop_btn, // Stop button signal
input wire inc_btn, // Increment button signal
output reg [8:0] seg_display11, // First digit segment control signal
output reg [8:0] seg_display22 // Second digit segment control signal
);

reg [3:0] seconds = 4'd0; // Variable to store seconds
reg [3:0] subSeconds = 4'd0; // Variable to store sub-seconds

reg run = 1'b0; // Run flag
wire reset_btnn; // Debounced reset button signal
wire start_btnn; // Debounced start button signal
wire stop_btnn; // Debounced stop button signal
wire inc_btnn; // Debounced increment button signal

wire rstn; // Inverted reset button signal
assign rstn = ~reset_btn;

reg [27:0] counters = 28'd0; // Main counter
reg [27:0] counterms = 28'd0; // Millisecond counter

reg [8:0] seg [9:0]; // Array to store 7-segment display patterns
initial begin
seg[0] = 9'h3f; // 7-segment display for digit 0
seg[1] = 9'h06; // 7-segment display for digit 1
seg[2] = 9'h5b; // 7-segment display for digit 2
seg[3] = 9'h4f; // 7-segment display for digit 3
seg[4] = 9'h66; // 7-segment display for digit 4
seg[5] = 9'h6d; // 7-segment display for digit 5
seg[6] = 9'h7d; // 7-segment display for digit 6
seg[7] = 9'h07; // 7-segment display for digit 7
seg[8] = 9'h7f; // 7-segment display for digit 8
seg[9] = 9'h6f; // 7-segment display for digit 9
run = 1'b0;
seconds <= 4'd0;
subSeconds <= 4'd0;
seg_display11 <= 9'd0;
seg_display22 <= 9'd0;
seg_display11 <= {seg[seconds][8], 1'b1, seg[seconds][6:0]};
seg_display22 <= seg[subSeconds][8:0];
end

always @(posedge clk) begin
if(reset_btnn == 1'b1) begin
run <= 1'b0;
seconds <= 4'd0;
subSeconds <= 4'd0;
end
else if(start_btnn == 1'b1) begin
run <= 1'b1;
end
else if(stop_btnn == 1'b1) begin
run <= 1'b0;
end
else if(inc_btnn == 1'b1) begin
// Increment by 1
if(subSeconds == 4'd9) begin
subSeconds <= 4'd0;
if(seconds == 4'd9) begin
seconds <= 4'd0;
end else begin
seconds <= seconds + 4'd1;
end
end else begin
subSeconds <= subSeconds + 4'd1;
end
seg_display11 <= {seg[seconds][8], 1'b1, seg[seconds][6:0]};
seg_display22 <= seg[subSeconds][8:0];
end

// Count seconds and milliseconds
if(counterms == 28'd1200000) begin
counterms <= 28'd0;
if(run == 1'b1) begin
if(subSeconds == 4'd9) begin
subSeconds <= 4'd0;
if(seconds == 4'd9) begin
seconds <= 4'd0;
end else begin
seconds <= seconds + 4'd1;
end
end else begin
subSeconds <= subSeconds + 4'd1;
end

seg_display11 <= {seg[seconds][8], 1'b1, seg[seconds][6:0]};
seg_display22 <= seg[subSeconds][8:0];
end
end else begin
counterms <= counterms + 28'd1;
end
seg_display11 <= {seg[seconds][8], 1'b1, seg[seconds][6:0]};
seg_display22 <= seg[subSeconds][8:0];

end

//assign reset_btnn = reset_btn;
//assign start_btnn = start_btn;
//assign stop_btnn = stop_btn;
//assign inc_btnn = inc_btn;

// Debounce circuits for buttons
debounce b1(.clk (clk), .rst(1'b1), .key(reset_btn), .key_pulse(reset_btnn));
debounce b2(.clk (clk), .rst(1'b1), .key(start_btn), .key_pulse(start_btnn));
debounce b3(.clk (clk), .rst(1'b1), .key(stop_btn), .key_pulse(stop_btnn));
debounce b4(.clk (clk), .rst(1'b1), .key(inc_btn), .key_pulse(inc_btnn));

endmodule

 

2. btns.v

module debounce (clk, rst, key, key_pulse);

parameter N = 1; // Number of keys to debounce

input clk;
input rst;
input [N-1:0] key; // Input key signals
output [N-1:0] key_pulse; // Output debounced key pulses

reg [N-1:0] key_rst_pre; // Register to store previous key values
reg [N-1:0] key_rst; // Register to store current key values

wire [N-1:0] key_edge; // Detect rising edge of key signals

// Store key values in two registers on clock rising edge or reset
always @(posedge clk or negedge rst)
begin
if (!rst) begin
key_rst <= {N{1'b1}}; // Initialize key_rst with all 1s
key_rst_pre <= {N{1'b1}};
end
else begin
key_rst <= key; // Update key_rst with current key values
key_rst_pre <= key_rst; // Store key_rst value in key_rst_pre
end
end

assign key_edge = key_rst_pre & (~key_rst);
// Generate pulses when key transitions from high to low

reg [17:0] cnt;
// Counter for generating delay, 20ms delay with 12MHz clock requires at least 18 bits

// Generate 20ms delay, reset counter when key_edge is detected
always @(posedge clk or negedge rst)
begin
if(!rst)
cnt <= 18'h0;
else if(key_edge)
cnt <= 18'h0;
else
cnt <= cnt + 1'h1;
end

reg [N-1:0] key_sec_pre; // Register for delayed key detection
reg [N-1:0] key_sec;

// Delayed key detection, generate key pulses when key transitions from high to low after delay
always @(posedge clk or negedge rst)
begin
if (!rst)
key_sec <= {N{1'b1}}; // Initialize key_sec with all 1s
else if (cnt == 18'h3ffff)
key_sec <= key;
end

always @(posedge clk or negedge rst)
begin
if (!rst)
key_sec_pre <= {N{1'b1}};
else
key_sec_pre <= key_sec;
end

assign key_pulse = key_sec_pre & (~key_sec); // Output debounced key pulses

endmodule


八、使用chatgpt生成代码

基于chatgpt生成的代码进行修改,得出符合实际要求的最终代码。


九、占用资源

  1. 寄存器:132个寄存器,占用了4635个寄存器的3%。
  2. PFU寄存器:132个,占用了4320个PFU寄存器的3%。
  3. PIO寄存器:0个,占用了315个PIO寄存器的0%。
  4. SLICEs数量:93个,占用了2160个SLICEs的4%。
  5. LUT4数量:185个,占用了4320个LUT4的4%。


十、仿真波形图

1.仿真代码(tbs.v):

module tbs;
reg clk;
reg reset_btn;
reg start_btn;
reg stop_btn;
reg inc_btn;
wire [8:0] seg_display11;
wire [8:0] seg_display22;
reg [20:0] counterr = 21'd0;

initial begin
clk = 1'b0;
reset_btn = 1'b0;
start_btn = 1'b0;
stop_btn = 1'b0;
inc_btn = 1'b0;
counterr = 21'd0;
end

always #10 clk <= ~clk;
always @(posedge clk)begin
counterr <= counterr + 21'd1;
if(counterr == 21'd10)begin
start_btn <=1'b1;
end
if(counterr == 21'd11)begin
start_btn <=1'b0;
end

if(counterr == 21'd120)begin
stop_btn <=1'b1;
end
if(counterr == 21'd121)begin
stop_btn <=1'b0;
end

if(counterr == 21'd140)begin
inc_btn <=1'b1;
end
if(counterr == 21'd141)begin
inc_btn <=1'b0;
end
end
watch u1(
.clk (clk),
.reset_btn (reset_btn),
.start_btn (start_btn),
.stop_btn (stop_btn),
.inc_btn (inc_btn), .
.eg_display11 (seg_display11),
.seg_display22 (seg_display22)
);
endmodule

2.仿真截图:

附件下载
archive.zip
团队介绍
姓名:胡晗微 学校:北京理工大学
评论
0 / 100
查看更多
硬禾服务号
关注最新动态
0512-67862536
info@eetree.cn
江苏省苏州市苏州工业园区新平街388号腾飞创新园A2幢815室
苏州硬禾信息科技有限公司
Copyright © 2024 苏州硬禾信息科技有限公司 All Rights Reserved 苏ICP备19040198号