实战项目——多功能电子时钟

一,项目要求

在这里插入图片描述

二,理论原理

通过按键来控制状态机的状态,在将状态值传送到各个模块进行驱动,在空闲状态下,数码管显示基础时钟,基础时钟是由7个计数器组合而成,当在ADJUST状态下可以调整时间,并且基础时间会随基础时钟的改变而改变,同过位置使能来确定更改的值在按下确定来更改基础时钟的时间,ALARM状态下可以设置闹钟的时间,设定方法和更改时钟方法一致,随后设置了一个beep_flag来驱动beep,当beep_flag为1且到达设定时间就响,若beep_flag不为1则停止响动,最后的秒表功能不多做赘述,之后通过状态机传出来的值,驱动数码管显示那个模块的输出值.

三,系统架构分析

本次系统架构分为:状态机模块,数码管驱动模块,基础时钟模块,调时模块,闹钟模块,秒表模块
在这里插入图片描述

三,状态转移图

在这里插入图片描述

四,源码展示

首先是状态机模块的实现,这里对应上边的状态转移图,通过传出的使能信号state来控制各个模块

/**************************************功能介绍***********************************
Date	: 
Author	: WZY.
Version	: 
Description: 这是一个状态机模块用来控制不同状态的转换
*********************************************************************************///---------<模块及端口声名>------------------------------------------------------
module state_change( input 	wire				clk		,input 	wire				rst_n	,input   wire    [3:0]       key_in  ,//按键输入input   wire                beep    ,output  reg     [1:0]       led_on  ,//led灯显示用来判断当前在什么状态output  reg     [1:0]       state    //状态输出
);								 
//---------<参数定义>--------------------------------------------------------- 
parameter IDLE = 4'b0001,   //空闲状态表示显示基础时钟ADJUST = 4'b0010,//更改状态可以更改时钟的值ALARM  = 4'b0100,//闹钟状态,可以制定闹钟STOP   = 4'b1000;
//---------<内部信号定义>-----------------------------------------------------
reg     [3:0]   cstate;//现态
reg     [3:0]   nstate;//次态//****************************************************************
//状态机
//****************************************************************
//三段式状态机第一段时序逻辑
always @(posedge clk or negedge rst_n) beginif (!rst_n) begincstate <= IDLE;endelse begincstate <= nstate;end
end//三段式状态机第二段组合逻辑
always @(*) begincase (cstate)IDLE    :beginif (!key_in[0]) begin //当按键0按下时转到调时状态nstate = ADJUST;endelse if (!key_in[1]||!beep) beginnstate = ALARM;endelse if (!key_in[2]) beginnstate = STOP ;endelse beginnstate = cstate; endend ADJUST  :beginif (!key_in[0]||!key_in[3]) begin//当按下按键0时转到基础时钟nstate = IDLE;  endelse if (!beep) begin//当蜂鸣器响立刻跳转到闹钟状态nstate = ALARM;endelse beginnstate = cstate;endendALARM   :beginif (!key_in[0]) begin//当按下按键0时转到基础时钟nstate = IDLE;  endelse beginnstate = cstate;endendSTOP    :beginif (!key_in[0]) beginnstate = IDLE;endelse if (!beep) begin//当蜂鸣器响立刻跳转到闹钟状态nstate = ALARM;endelse beginnstate = cstate;endenddefault: nstate = IDLE;endcase
end //三段式状态机第三段时序逻辑
always @(posedge clk or  negedge rst_n) beginif (!rst_n) beginstate <= 2'b00;endelse case (cstate)IDLE    : state <= 2'b00;ADJUST  : state <= 2'b01;ALARM   : state <= 2'b10;STOP    : state <= 2'b11;default: state <= 2'b00;endcase
end//****************************************************************
//led显示状态,通过led的亮灭状态来看处在什么状态
//****************************************************************
always @(posedge clk or negedge rst_n) beginif (!rst_n) beginled_on <= 2'b00;endelse case (cstate)IDLE    : led_on <= 2'b00;ADJUST  : led_on <= 2'b01;ALARM   : led_on <= 2'b10;STOP    : led_on <= 2'b11;default: led_on <= 2'b00;endcase
end
endmodule

接下来是基础时钟模块,这个模块我为了后边的修改时钟模块方便所以我选择了使用七个计数器来实现。

/**************************************功能介绍***********************************
Date	: 
Author	: WZY.
Version	: 
Description: 这是一个基础时钟通过用标准的五个计数器实现
*********************************************************************************///---------<模块及端口声名>------------------------------------------------------
module counter( input 	wire				clk		,input 	wire				rst_n	,input   wire    [3:0]       key_in  ,input   wire    [1:0]       state   ,//状态input   wire    [2:0]       flag    ,//位置信号input   wire    [23:0]      adjust_time,     //时间调整output  wire    [23:0]      times       //当前时间寄存区
);								 
//---------<参数定义>--------------------------------------------------------- 
parameter MAX1s = 26'd49_999_999;
reg			[25:0]	cnt_1s	;
wire				add_cnt	;
wire				end_cnt	;//时钟内部参数
reg      [3:0]   sec_low    ;
reg      [3:0]   sec_high   ;
reg      [3:0]   mine_low   ;
reg      [3:0]   mine_high  ;
reg      [3:0]   hour_low   ;
reg      [3:0]   hour_high  ;
wire             add_sec_low;
wire             add_sec_high ;
wire             add_mine_low ;
wire             add_mine_high;
wire             add_hour_low ;
wire             add_hour_high;
wire             end_sec_low  ;
wire             end_sec_high ;
wire             end_mine_low ;
wire             end_mine_high;
wire             end_hour_low ;
wire             end_hour_high;
//---------<内部信号定义>-----------------------------------------------------
//****************************************************************
//1s计时器
//****************************************************************
always @(posedge clk or negedge rst_n)begin if(!rst_n)begincnt_1s <= 26'd0;end else if(add_cnt&&(state != 4'b01))begin if(end_cnt)begin cnt_1s <= 26'd0;endelse begin cnt_1s <= cnt_1s + 1'b1;end end
end assign add_cnt = 1;
assign end_cnt = add_cnt && cnt_1s == MAX1s;//****************************************************************
//时钟计时
//****************************************************************//****************************************************************
//秒钟计时,通过两个计数器来设定秒的个位和十位
//****************************************************************
always @(posedge clk or negedge rst_n ) beginif (!rst_n) beginsec_low <= 4'd0;endelse if (add_sec_low) beginif (end_sec_low) beginsec_low <= 4'd0;endelse beginsec_low <= sec_low + 1'd1;endendelse if ((state == 2'b01)&&(!key_in[3])) beginsec_low <= adjust_time[3:0];endelse beginsec_low <= sec_low;end   
end
assign add_sec_low = end_cnt&&((state != 2'b01)&&(flag != 3'd1));
assign end_sec_low = (sec_low == 4'd9)&&add_sec_low;always @(posedge clk or negedge rst_n ) beginif (!rst_n) beginsec_high <= 4'd0;endelse if (add_sec_high) beginif (end_sec_high) beginsec_high <= 4'd0;endelse beginsec_high <= sec_high + 1'd1;endendelse if ((state == 2'b01)&&(!key_in[3])) beginsec_high <= adjust_time[7:4];endelse beginsec_high <= sec_high;end   
end
assign add_sec_high = end_sec_low&&(flag != 3'd2);
assign end_sec_high = (sec_high == 4'd5)&&add_sec_high;
//****************************************************************
//分钟计时器,通过两个计数器来控制分钟个位和十位
//****************************************************************
always @(posedge clk or negedge rst_n ) beginif (!rst_n) beginmine_low <= 4'd0;endelse if (add_mine_low) beginif (end_mine_low) beginmine_low <= 4'd0;endelse beginmine_low <= mine_low + 1'd1;endendelse if ((state == 2'b01)&&(!key_in[3])) beginmine_low <= adjust_time[11:8];endelse beginmine_low <= mine_low;end   
end
assign add_mine_low = end_sec_high&&(flag != 3'd3);
assign end_mine_low = (mine_low == 4'd9)&& add_mine_low;always @(posedge clk or negedge rst_n ) beginif (!rst_n) beginmine_high <= 4'd0;endelse if (add_mine_high) beginif (end_mine_high) beginmine_high <= 4'd0;endelse beginmine_high <= mine_high + 1'd1;endendelse if ((state == 2'b01)&&(!key_in[3])) beginmine_high <= adjust_time[15:12];endelse beginmine_high <= mine_high;end   
end
assign add_mine_high = end_mine_low &&(flag != 3'd4);
assign end_mine_high = (mine_high == 4'd5)&& add_mine_high;
//****************************************************************
//小时计时器,通过两个计数器来控制小时的个位和十位
//****************************************************************
always @(posedge clk or negedge rst_n ) beginif (!rst_n) beginhour_low <= 4'd0;endelse if (end_hour_high) beginhour_low <= 4'd0;endelse if (add_hour_low) beginif (end_hour_low) beginhour_low <= 4'd0;endelse beginhour_low <= hour_low + 1'd1;endendelse if ((state == 2'b01)&&(!key_in[3])) beginhour_low <= adjust_time[19:16];endelse beginhour_low <= hour_low;end   
end
assign add_hour_low = end_mine_high&&(flag != 3'd5) ;
assign end_hour_low = (hour_low == 4'd9)&& add_hour_low;always @(posedge clk or negedge rst_n ) beginif (!rst_n) beginhour_high <= 4'd0;endelse if (end_hour_high) beginhour_high <= 4'd0;endelse if (add_hour_high) beginhour_high <= hour_high + 1'd1;endelse if ((state == 2'b01)&&(!key_in[3])) beginhour_high <= adjust_time[23:20];endelse beginhour_high <= hour_high;end   
end
assign add_hour_high = end_hour_low&&(flag != 3'd6);
assign end_hour_high = (hour_high == 4'd2)&&(hour_low >= 4'd4);
//拼接输出值
assign times = {hour_high , hour_low , mine_high , mine_low , sec_high , sec_low};
endmodule

接下来是修改时钟模块,这里通过定义了一个位置信号来达到选择到每一位,最后把修改的数值重新赋值给基础时钟

/**************************************功能介绍***********************************
Date	: 
Author	: WZY.
Version	: 
Description: 这是一个调时模块,通过位置信号和按键信号来更改
*********************************************************************************///---------<模块及端口声名>------------------------------------------------------
module adjust_state( input 	wire				clk		,//全局时钟input 	wire				rst_n	,input   wire    [3:0]       key_in  ,//按键输入input   wire    [1:0]       state   ,//状态input   wire    [23:0]      times   ,//基本时钟时间output  wire    [2:0]       flag    ,//位置信号output  wire    [23:0]      adjust_time//调整后时间
);								 
//---------<参数定义>--------------------------------------------------------- 
//调时参数定义
reg [2:0]   flag_r;//位置信号
//时钟参数定义
reg      [3:0]   sec_low    ;
reg      [3:0]   sec_high   ;
reg      [3:0]   mine_low   ;
reg      [3:0]   mine_high  ;
reg      [3:0]   hour_low   ;
reg      [3:0]   hour_high  ;//---------<内部信号定义>-----------------------------------------------------//****************************************************************
//位置信号驱动
//****************************************************************
//控制位置信号
always @(posedge clk or negedge rst_n) beginif (!rst_n) beginflag_r <= 3'd0;endelse if ((state == 2'b01)) beginif (!key_in[1]) beginif (flag_r == 3'd6) beginflag_r <= 3'd1;endelse beginflag_r <= flag_r + 1'b1;endendelse beginflag_r <= flag_r;end endelse beginflag_r <= 3'd0;end
end
assign  flag = flag_r;
//****************************************************************
//调时主要模块,当不在调时状态时使得值一直和时钟保持相等,在调时状态时
//根据位置信号和按键信号来加减值
//****************************************************************
always @(posedge clk or negedge rst_n) beginif (!rst_n) beginsec_low   <= times[3:0];sec_high  <= times[7:4];mine_low  <= times[11:8];mine_high <= times[15:12];hour_low  <= times[19:16];hour_high <= times[23:20];endelse if (state != 2'b01) beginsec_low   <= times[3:0];sec_high  <= times[7:4];mine_low  <= times[11:8];mine_high <= times[15:12];hour_low  <= times[19:16];hour_high <= times[23:20];endelse if (state == 2'b01) beginif (flag_r == 3'd1) beginif (!key_in[2]) begin     //当在调时状态并且位置信号为1时按下按键2使得分钟个位加1,下放同理sec_low <= sec_low + 1'b1;endelse if (sec_low == 4'd10) beginsec_low <= 4'd0;endendelse if (flag_r == 3'd2) beginif (!key_in[2]) beginsec_high <= sec_high + 1'b1;endelse if (sec_high == 4'd6) beginsec_high <= 4'd0;endendelse if (flag_r == 3'd3) beginif (!key_in[2]) beginmine_low <= mine_low + 1'b1;endelse if (mine_low == 4'd10) beginmine_low <= 4'd0;endendelse if (flag_r == 3'd4) beginif (!key_in[2]) beginmine_high <= mine_high + 1'b1;endelse if (mine_high == 4'd6) beginmine_high <= 4'd0;endendelse if (flag_r == 3'd5) beginif (!key_in[2]) beginhour_low <= hour_low + 1'b1;endelse if ((hour_low == 4'd10)&&(hour_high <= 4'd1)) beginhour_low<= 4'd0;endelse if ((hour_low == 4'd4)&&(hour_high == 4'd2)) beginhour_low <= 4'd0;endendelse if (flag_r == 3'd6) beginif (!key_in[2]) beginhour_high <= hour_high + 1'b1;endelse if ((hour_high == 4'd2)&&(hour_low >=4'd4)) beginhour_high <= 4'd0;endelse if ((hour_high == 4'd3)&&(hour_low < 4'd4)) beginhour_high <= 4'd0;endendelse beginsec_low   <= sec_low  ;sec_high  <= sec_high ;mine_low  <= mine_low ;mine_high <= mine_high;hour_low  <= hour_low ;hour_high <= hour_high;endend
end
//调值后的信号输出
assign adjust_time = {hour_high ,hour_low,mine_high , mine_low , sec_high , sec_low} ;
endmodule

下面是对于闹钟模块的介绍,闹钟模块中定时跟修改模块一致,只是会让修改后的值一直保持,只要基础时钟时间跟定时想同就使使能拉高,按下按键或者等待5s使能自动拉低,使能拉高切时间达到就使得蜂鸣器响达到闹钟的效果

/**************************************功能介绍***********************************
Date	: 
Author	: WZY.
Version	: 
Description: 这是一个闹钟模块,在调时模块的基础上,增加了蜂鸣器驱动信号,;来控制定时
*********************************************************************************///---------<模块及端口声名>------------------------------------------------------
module alarm_clock( input 	wire				clk		,input 	wire				rst_n	,input   wire    [3:0]       key_in  ,input   wire    [1:0]       state   ,//状态input   wire    [23:0]      times   ,//基础时钟时间output  reg                 beep    ,//蜂鸣器output  wire    [2:0]       flag_alarm,//闹钟位置信号output  wire    [23:0]      adjust_alarm,//设定闹钟时间output  wire                led_alarm    //定时led);								 
//---------<参数定义>--------------------------------------------------------- 
parameter MAX1S = 26'd49_999_999;//1s;//闹钟参数定义
reg [2:0]   flag_alarm_r;//位置信号
reg         flag_beep_r   ;//蜂鸣器使能
reg      [3:0]   sec_low    ;
reg      [3:0]   sec_high   ;
reg      [3:0]   mine_low   ;
reg      [3:0]   mine_high  ;
reg      [3:0]   hour_low   ;
reg      [3:0]   hour_high  ;//1s计时器参数定义
reg			[25:0]	cnt	   	;
wire				add_cnt	;
wire				end_cnt	;
//5s计数器参数定义
reg			[2:0]	cnt_5s	   	;
wire				add_cnt_5s	;
wire				end_cnt_5s	;reg                 led_r       ;//led信号寄存器
reg                 flag        ;//计时驱动
//---------<内部信号定义>-----------------------------------------------------//****************************************************************
//flag驱动控制计时
//****************************************************************
always @(posedge clk or negedge rst_n) beginif (!rst_n) beginflag <= 0;endelse if (end_cnt_5s) beginflag <= 1'b0;endelse if (adjust_alarm === times&&times!= 0) beginflag <= 1'b1;endelse beginflag <= flag ;endend
//****************************************************************
//1s计时器
//****************************************************************always @(posedge clk or negedge rst_n)begin if(!rst_n)begincnt <= 26'd0;end else if(add_cnt)begin if(end_cnt)begin cnt <= 26'd0;endelse begin cnt <= cnt + 1'b1;end endelse if (state != 2'b10) begincnt <= 26'd0;endelse begincnt <= cnt;end
end assign add_cnt = flag;
assign end_cnt = add_cnt && cnt == MAX1S;//****************************************************************
//5s计时器
//****************************************************************always @(posedge clk or negedge rst_n)begin if(!rst_n)begincnt_5s <= 3'd0;end else if(add_cnt_5s)begin if(end_cnt_5s)begin cnt_5s <= 3'd0;endelse begin cnt_5s <= cnt_5s + 1'b1;end endelse if (state != 2'b10) begincnt_5s<= 3'd0;endelse begincnt_5s <= cnt_5s;end
end assign add_cnt_5s = end_cnt;
assign end_cnt_5s = add_cnt_5s && cnt_5s == 3'd5;//****************************************************************
//位置信号驱动
//****************************************************************
//控制位置信号
always @(posedge clk or negedge rst_n) beginif (!rst_n) beginflag_alarm_r <= 3'd0;endelse if ((state == 2'b10)) beginif (!key_in[1]) beginif (flag_alarm_r == 3'd6) beginflag_alarm_r <= 3'd1;endelse beginflag_alarm_r <= flag_alarm_r + 1'b1;endendelse if (!key_in[3]) beginflag_alarm_r <= 3'd0;endelse beginflag_alarm_r <= flag_alarm_r;end endelse beginflag_alarm_r <= 3'd0;end
end
assign  flag_alarm = flag_alarm_r;
//****************************************************************
//是定闹钟的主要模块,当不在闹钟状态时使得值一直设定的值一样,在闹钟
//时根据位置信号和按键信号来加减值
//****************************************************************
always @(posedge clk or negedge rst_n) beginif (!rst_n) beginsec_low   <= 4'd0;sec_high  <= 4'd0;mine_low  <= 4'd0;mine_high <= 4'd0;hour_low  <= 4'd0;hour_high <= 4'd0;endelse if (state == 2'b10) beginif (flag_alarm_r == 3'd1) beginif (!key_in[2]) beginsec_low <= sec_low + 1'b1;endelse if (sec_low == 4'd10) beginsec_low <= 4'd0;endendelse if (flag_alarm_r == 3'd2) beginif (!key_in[2]) beginsec_high <= sec_high + 1'b1;endelse if (sec_high == 4'd6) beginsec_high <= 4'd0;endendelse if (flag_alarm_r == 3'd3) beginif (!key_in[2]) beginmine_low <= mine_low + 1'b1;endelse if (mine_low == 4'd10) beginmine_low <= 4'd0;endendelse if (flag_alarm_r == 3'd4) beginif (!key_in[2]) beginmine_high <= mine_high + 1'b1;endelse if (mine_high == 4'd6) beginmine_high <= 4'd0;endendelse if (flag_alarm_r == 3'd5) beginif (!key_in[2]) beginhour_low <= hour_low + 1'b1;endelse if ((hour_low == 4'd10)&&(hour_high <= 4'd1)) beginhour_low<= 4'd0;endelse if ((hour_low == 4'd4)&&(hour_high == 4'd2)) beginhour_low <= 4'd0;endendelse if (flag_alarm_r == 3'd6) beginif (!key_in[2]) beginhour_high <= hour_high + 1'b1;endelse if ((hour_high == 4'd2)&&(hour_low >=4'd4)) beginhour_high <= 4'd0;endelse if ((hour_high == 4'd3)&&(hour_low < 4'd4)) beginhour_high <= 4'd0;endendelse beginsec_low   <= sec_low  ;sec_high  <= sec_high ;mine_low  <= mine_low ;mine_high <= mine_high;hour_low  <= hour_low ;hour_high <= hour_high;endend
endassign adjust_alarm = {hour_high ,hour_low,mine_high , mine_low , sec_high , sec_low} ;//****************************************************************
//闹钟判断和蜂鸣器模块
//****************************************************************
always @(posedge clk or negedge rst_n) beginif (!rst_n) beginbeep <= 1'b1;endelse if ((adjust_alarm === times)&&flag_beep_r) begin//当时间达到并且使能为1时beep响beep <= 1'b0;endelse if (!flag_beep_r) begin//当时能为0时beep <= 1'b1;endelse beginbeep <= beep;end
end
always @(posedge clk or negedge rst_n) beginif (!rst_n) beginflag_beep_r <= 1'b0;endelse if (end_cnt_5s) begin//当计时结束后使得使能自动归0停止闹钟flag_beep_r <= 1'b0;endelse if (!key_in[3]&&(state == 2'b10)) begin//当按下第四个按键时翻转用来控制开始和结束flag_beep_r <= ~flag_beep_r;endelse beginflag_beep_r <= flag_beep_r; end
end
//****************************************************************
//led显示
//****************************************************************
always @(posedge clk or negedge rst_n) beginif (!rst_n) beginled_r <= 1'b0;endelse if (flag_beep_r == 1) begin//当使能为1即设定了闹钟led就亮否则不亮led_r <= 1'b1;endelse beginled_r <= 1'b0;end
end
assign led_alarm = led_r;
endmodule    

下面是数码管驱动模块,这里我为了让选择到的哪一位频闪所以采用了一个巧妙的三位运算符的方法来控制,大家可以自己看一下

/**************************************功能介绍***********************************
Date	: 2023.8.2
Author	: WZY.
Version	: 
Description: 这是一个数码管显示模块,用来显示各个功能的值
*********************************************************************************///---------<模块及端口声名>------------------------------------------------------
module seg_dirver( input 	wire				clk		,input 	wire				rst_n	,input   wire    [1:0]       state   ,//状态input   wire    [23:0]      times ,     //基础时钟寄存器input   wire    [5:0]       point   ,//点控制寄存器input   wire    [2:0]       flag    ,//调时位选信号input   wire    [23:0]      adjust_time,//调时显示寄存器input   wire    [2:0]       flag_alarm,//闹钟位选信号input   wire    [23:0]      adjust_alarm,//闹钟显示寄存器input   wire    [23:0]      adjust_clock,//计时器寄存器output  reg     [5:0]       sel     ,//位选output  reg     [7:0]       seg     //段选
);								 
//---------<参数定义>--------------------------------------------------------- 
parameter MAX20US = 10'd999;
parameter MAX_500MS = 25'd24_999_999;//500ms
//数码管译码参数
parameter   ZERO            =   7'b100_0000    ,ONE             =   7'b111_1001    ,TWO             =   7'b010_0100    ,THREE           =   7'b011_0000    ,FOUR            =   7'b001_1001    ,FIVE            =   7'b001_0010    ,SIX             =   7'b000_0010    ,SEVEN           =   7'b111_1000    ,EIGHT           =   7'b000_0000    ,NINE            =   7'b001_0000    ,A               =   7'b000_1000    ,B               =   7'b000_0011    ,C               =   7'b100_0110    ,D               =   7'b010_0001    ,E               =   7'b000_0110    ,F               =   7'b000_1110    ,DARK             =  7'b111_1111     ;//全灭
//---------<内部信号定义>-----------------------------------------------------
//20us计数器
reg			[9:0]	cnt	   	;
wire				add_cnt	;
wire				end_cnt	;
//500ms计数器
reg			[24:0]	cnt_500ms	   	;
wire				add_cnt_500ms	;
wire				end_cnt_500ms	;
reg                 flash;//闪烁信号reg         [23:0]   num     ;//位选赋值寄存器
reg         [4:0]      seg_temp;//seg单位值
reg                 point_r ;//点位控制
//****************************************************************
//20us计数器
//****************************************************************
always @(posedge clk or negedge rst_n)begin if(!rst_n)begincnt <= 10'd0;end else if(add_cnt)begin if(end_cnt)begin cnt <= 10'd0;endelse begin cnt <= cnt + 1'b1;end end
end assign add_cnt = 1'b1;
assign end_cnt = add_cnt && cnt == MAX20US;//****************************************************************
//500ms计数器
//****************************************************************always @(posedge clk or negedge rst_n)begin if(!rst_n)begincnt_500ms <= 25'd0;end else if(add_cnt_500ms)begin if(end_cnt_500ms)begin cnt_500ms <= 25'd0;endelse begin cnt_500ms <= cnt_500ms + 1'b1;end endelse begincnt_500ms <= 25'd0;end
end assign add_cnt_500ms = (state == 2'b01)||(state == 2'b10);
assign end_cnt_500ms = add_cnt_500ms && cnt_500ms == MAX_500MS;
//****************************************************************
//驱动闪烁信号
//****************************************************************
always @(posedge clk or negedge rst_n) beginif (!rst_n) beginflash <= 1'b0;endelse if (end_cnt_500ms) begin//每500ms翻转一次flash <= ~flash;endelse if ((state != 2'b01)&&(state != 2'b10)) begin//当不在调时和闹钟状态归0flash <= 1'b0;endelse beginflash <=flash;end
end
//****************************************************************
//seg显示选择.根据状态选择数码管显示的值
//****************************************************************
always @(posedge clk or negedge rst_n) beginif (!rst_n) beginnum <= 24'd0;endelse if (state == 2'b00) beginnum <=times;endelse if (state == 2'b01) beginnum <= adjust_time;endelse if (state == 2'b10) beginnum <= adjust_alarm;endelse if (state == 2'b11) beginnum <= adjust_clock;endelse  beginnum <= num;end
end
//****************************************************************
//驱动sel
//****************************************************************   
always @(posedge clk or negedge rst_n)begin if(!rst_n)beginsel <= 6'b111_110;end else if(end_cnt)begin sel <= {sel[4:0],sel[5]};end else begin sel <= sel; end 
end
//****************************************************************
//位选赋值,当选择到哪一位哪一位进行频闪
//****************************************************************
always @(*) begincase (sel)6'b011111:begin seg_temp = (flash&&((flag==3'd1||(flag_alarm == 3'd1))))?5'd15 : num[3:0]         ; point_r = point[0];end6'b101111:begin seg_temp = (flash&&((flag==3'd2||(flag_alarm == 3'd2))))?5'd15 : num[7:4]         ; point_r = point[1];end6'b110111:begin seg_temp = (flash&&((flag==3'd3||(flag_alarm == 3'd3))))?5'd15 : num[11:8]        ; point_r = point[2];end6'b111011:begin seg_temp = (flash&&((flag==3'd4||(flag_alarm == 3'd4))))?5'd15 : num[15:12]       ; point_r = point[3];end6'b111101:begin seg_temp = (flash&&((flag==3'd5||(flag_alarm == 3'd5))))?5'd15 : num[19:16]       ; point_r = point[4];end6'b111110:begin seg_temp = (flash&&((flag==3'd6||(flag_alarm == 3'd6))))?5'd15 : num[23:20]       ; point_r = point[5];enddefault: seg_temp = 4'd0;endcase
end
//****************************************************************
//译码
//****************************************************************
always @(*) begincase (seg_temp)4'd0: seg = {point_r,ZERO  };4'd1: seg = {point_r,ONE   };4'd2: seg = {point_r,TWO   };4'd3: seg = {point_r,THREE };4'd4: seg = {point_r,FOUR  };4'd5: seg = {point_r,FIVE  };4'd6: seg = {point_r,SIX   };4'd7: seg = {point_r,SEVEN };4'd8: seg = {point_r,EIGHT };4'd9: seg = {point_r,NINE  };4'd15:seg = {point_r,DARK};default: seg = 8'b1111_1111;endcase
end
endmodule

最后是消抖和秒表比较简单
消抖

module key_debounce (input   wire            clk     ,input   wire            rst_n   ,input   wire    [3:0]   key_in  ,output  wire    [3:0]   key_out 
);parameter MAX20ms = 20'd999_999;wire            add_cnt;//倒计时开始使能
wire            end_cnt;//倒计时结束使能
reg    [19:0]   cnt_20ms;//20ms计数寄存器
reg    [3:0]    key_r0;//同步
reg    [3:0]    key_r1;//打拍
reg             start;//下降沿检测寄存器
reg    [3:0]    flag;
reg    [3:0]    key_out_r;//输出按键信号寄存器
wire            nedge;//下降沿检测
always @(posedge clk or negedge rst_n) beginif (!rst_n) beginkey_r0 <= 4'b1111;key_r1 <= 4'b1111;endelse beginkey_r0 <= key_in;key_r1 <= key_r0;end
endassign nedge = (~key_r0[0]&key_r1[0])||(~key_r0[1]&key_r1[1])||(~key_r0[2]&key_r1[2])||(~key_r0[3]&key_r1[3]);//20ms计时器
always @(posedge clk or negedge rst_n) beginif (!rst_n) begincnt_20ms <= 20'd0;endelse if (nedge) begincnt_20ms <= 20'd0;endelse if (add_cnt) beginif (end_cnt) begincnt_20ms <= 20'd0;endelse begincnt_20ms <= cnt_20ms + 1'b1;endendelse begincnt_20ms <= 20'd0;end
endassign add_cnt = start;
assign end_cnt = add_cnt && (cnt_20ms == MAX20ms);//约束start
always @(posedge clk or negedge rst_n) beginif (!rst_n) beginstart <= 1'b0;endelse if (nedge) beginstart <= 1'b1;endelse if (end_cnt) beginstart <= 1'b0;endelse beginstart <= start ;end
end//约束flag
always @(posedge clk or negedge rst_n) beginif (!rst_n) beginflag <= 4'b1111;endelse if (nedge) beginflag <= 4'b1111;endelse if (end_cnt) beginflag <= key_r0;endelse beginflag <= 4'b1111 ;end
end
//脉冲信号
always @(posedge clk or negedge rst_n) beginif (!rst_n) beginkey_out_r <= 4'b1111;endelse if (!flag[0]) beginkey_out_r <= 4'b1110;endelse if (!flag[1]) beginkey_out_r <= 4'b1101;endelse if (!flag[2]) beginkey_out_r <= 4'b1011;endelse if (!flag[3]) beginkey_out_r <= 4'b0111;endelse beginkey_out_r <= 4'b1111;end
end// //持续信号
// always @(posedge clk or negedge rst_n) begin
//     if (!rst_n) begin
//         key_out_r <= 4'b1111;
//     end
//     else if (!flag[0]) begin
//         key_out_r <= 4'b1110;
//     end
//     else if (!flag[1]) begin
//         key_out_r <= 4'b1101;
//     end
//     else if (!flag[2]) begin
//         key_out_r <= 4'b1011;
//     end
//     else if (!flag[3]) begin
//         key_out_r <= 4'b0111;
//     end
//     else begin
//         key_out_r <= key_out_r;
//     end
// endassign key_out = key_out_r;
endmodule```
秒表```cpp
/**************************************功能介绍***********************************
Date	: 
Author	: WZY.
Version	: 
Description: 这是一个秒表
*********************************************************************************///---------<模块及端口声名>------------------------------------------------------
module stop_watch( input 	wire				clk		,input 	wire				rst_n	,input   wire    [3:0]       key_in  ,input   wire    [1:0]       state   ,output  wire    [23:0]      adjust_clock//秒表寄存器(分钟/秒/毫秒/)
);								 
//---------<参数定义>--------------------------------------------------------- 
parameter   max1ms = 19'd499_999;//100ms
reg  [3:0]  ms_low;
reg  [3:0]  ms_high;
reg  [3:0]  s_low;
reg  [3:0]  s_high;
reg  [3:0]  mine_low;
reg  [3:0]  mine_high;reg			[18:0]	cnt	   	;
wire				add_cnt	;
wire				end_cnt	;wire                add_cnt_ms_low;
wire                end_cnt_ms_low;
wire                add_cnt_ms_high;
wire                end_cnt_ms_high;
wire                add_cnt_s_low;
wire                end_cnt_s_low;
wire                add_cnt_s_high;
wire                end_cnt_s_high;
wire                add_cnt_mine_low;
wire                end_cnt_mine_low;
wire                add_cnt_mine_high;
wire                end_cnt_mine_high;reg                 flag_clock;
//---------<内部信号定义>-----------------------------------------------------//****************************************************************
//秒表使能
//****************************************************************
always @(posedge clk or negedge rst_n) beginif (!rst_n) beginflag_clock <= 1'b0;endelse if ((!key_in[1])&&(state == 2'b11)) beginflag_clock <= ~flag_clock;endelse if ((state != 2'b11)||(!key_in[2])) beginflag_clock <= 1'b0;endelse beginflag_clock <= flag_clock;end
end//****************************************************************
//100ms计数器
//****************************************************************
always @(posedge clk or negedge rst_n)begin if(!rst_n)begincnt <= 19'd0;end else if(add_cnt)begin if(end_cnt)begin cnt <= 19'd0;endelse begin cnt <= cnt + 1'b1;end endelse if ((state != 2'b11)||(!key_in[2])) begincnt <= 19'd0;endelse begincnt <= cnt;end
end assign add_cnt = (state == 2'b11)&&(flag_clock);
assign end_cnt = add_cnt && (cnt == max1ms);//****************************************************************
//秒表模块
//**************************************************************** //ms
always @(posedge clk or negedge rst_n) beginif (!rst_n) beginms_low <= 4'd0;endelse if (add_cnt_ms_low) beginif (end_cnt_ms_low) beginms_low <= 4'd0;endelse beginms_low <= ms_low + 1'd1;endendelse if ((state != 2'b11)||((state == 2'b11)&&(!key_in[2]))) beginms_low <= 4'd0;endelse beginms_low <= ms_low;end
endassign add_cnt_ms_low = end_cnt;
assign end_cnt_ms_low = add_cnt_ms_low&&(ms_low == 9);always @(posedge clk or negedge rst_n) beginif (!rst_n) beginms_high <= 4'd0;endelse if (add_cnt_ms_high) beginif (end_cnt_ms_high) beginms_high <= 4'd0;endelse beginms_high <= ms_high + 1'd1;endendelse if ((state != 2'b11)||((state == 2'b11)&&(!key_in[2]))) beginms_high <= 4'd0;endelse beginms_high <= ms_high;end
endassign add_cnt_ms_high = end_cnt_ms_low;
assign end_cnt_ms_high = add_cnt_ms_high&&(ms_high == 5);//s
always @(posedge clk or negedge rst_n) beginif (!rst_n) begins_low <= 4'd0;endelse if (add_cnt_s_low) beginif (end_cnt_s_low) begins_low <= 4'd0;endelse begins_low <= s_low + 1'd1;endendelse if ((state != 2'b11)||((state == 2'b11)&&(!key_in[2]))) begins_low <= 4'd0;endelse begins_low <= s_low;end
endassign add_cnt_s_low = end_cnt_ms_high;
assign end_cnt_s_low = add_cnt_s_low&&(s_low == 9);always @(posedge clk or negedge rst_n) beginif (!rst_n) begins_high <= 4'd0;endelse if (add_cnt_s_high) beginif (end_cnt_s_high) begins_high <= 4'd0;endelse begins_high <= s_high + 1'd1;endendelse if ((state != 2'b11)||((state == 2'b11)&&(!key_in[2]))) begins_high <= 4'd0;endelse begins_high <= s_high;end
endassign add_cnt_s_high = end_cnt_s_low;
assign end_cnt_s_high = add_cnt_s_high&&(s_high == 5);//mine
always @(posedge clk or negedge rst_n) beginif (!rst_n) beginmine_low <= 4'd0;endelse if (add_cnt_mine_low) beginif (end_cnt_mine_low) beginmine_low <= 4'd0;endelse beginmine_low <= mine_low + 1'd1;endendelse if ((state != 2'b11)||((state == 2'b11)&&(!key_in[2]))) beginmine_low <= 4'd0;endelse beginmine_low <= mine_low;end
endassign add_cnt_mine_low = end_cnt_s_high;
assign end_cnt_mine_low = add_cnt_mine_low&&(mine_low == 9);always @(posedge clk or negedge rst_n) beginif (!rst_n) beginmine_high <= 4'd0;endelse if (add_cnt_mine_high) beginif (end_cnt_mine_high) beginmine_high <= 4'd0;endelse beginmine_high <= mine_high + 1'd1;endendelse if ((state != 2'b11)||((state == 2'b11)&&(!key_in[2]))) beginmine_high <= 4'd0;endelse beginmine_high <= mine_high;end
endassign add_cnt_mine_high = end_cnt_mine_low;
assign end_cnt_mine_high = add_cnt_mine_high&&(mine_high == 5);assign adjust_clock = {mine_high , mine_low ,s_high , s_low , ms_high,ms_low};endmodule

顶层

/**************************************功能介绍***********************************
Date	: 2023.8.2
Author	: WZY.
Version	: 
Description: 这是一个顶层模块
*********************************************************************************///---------<模块及端口声名>------------------------------------------------------
module top( input   wire		clk     ,input   wire		rst_n	,input   wire    [3:0]       key_in  ,output  wire    [3:0]       led_on  ,output  wire                beep    ,output  wire    [5:0]       sel     ,output  wire    [7:0]       seg    
);								 
//---------<参数定义>--------------------------------------------------------- 
wire    [3:0]   key_debounce;
wire    [1:0]   state;
wire    [2:0]   flag;
wire    [23:0]  times;
wire    [23:0]  adjust_time;
wire    [2:0]   flag_alarm;
wire    [23:0]  adjust_alarm;
wire    [23:0]  adjust_clock;
//---------<内部信号定义>-----------------------------------------------------// // ****************************************************************
// // 模块例化
// // ****************************************************************   
// //消抖模块例化
// key_debounce key_debounce_inst(
//                 .clk     (clk),
//                 .rst_n   (rst_n),
//                 .key_in  (key_in),
//                 .key_out (key_debounce)
// );// //状态机例化
// state_change state_change_inst( 
//                 .clk		(clk),
//                 .rst_n	        (rst_n),
//                 .key_in         (key_debounce),//按键输入
//                 .beep           (beep)  ,
//                 .led_on         (led_on[1:0]),//led灯显示用来判断当前在什么状态
//                 .state          (state)  //状态输出
// );// //基础时钟例化
// counter counter_inst( 
//                 .clk		(clk),
//                 .rst_n	        (rst_n),
//                 .key_in         (key_debounce),
//                 .state          (state),
//                 .flag           (flag),
//                 .times          (times),
//                 .adjust_time    (adjust_time)     //时间调整
// );	
// //调时模块例化
// adjust_state adjust_state_inst( 
//                 .clk	        (clk),
//                 .rst_n	        (rst_n),
//                 .key_in         (key_debounce),
//                 .state          (state),
//                 .times          (times),
//                 .flag           (flag),
//                 .adjust_time    (adjust_time)
// );	
// //闹钟模块例化
// alarm_clock alarm_clock_inst( 
//                 .clk		(clk),
//                 .rst_n	        (rst_n),
//                 .key_in         (key_debounce),
//                 .state          (state),
//                 .times          (times),
//                 .beep           (beep),
//                 .flag_alarm     (flag_alarm),
//                 .adjust_alarm   (adjust_alarm),
//                 .led_alarm      (led_on[3])// );
// //秒表模块例化
// stop_watch stop_watch_inst( 
//                 .clk		    (clk),
//                 .rst_n	        (rst_n),
//                 .key_in         (key_debounce),
//                 .state          (state),
//                 .adjust_clock   (adjust_clock)//秒表寄存器(分钟/秒/毫秒/)
// );
// //数码管驱动例化
// seg_dirver seg_dirver_inst( 
//                 .clk		(clk),
//                 .rst_n	        (rst_n),
//                 .state          (state),
//                 .times          (times),
//                 .point          (6'b101011),
//                 .flag           (flag),//调时位选信号
//                 .adjust_time    (adjust_time),//调时显示寄存器
//                 .flag_alarm     (flag_alarm),//闹钟位选信号
//                 .adjust_alarm   (adjust_alarm),//闹钟显示寄存器
//                 .adjust_clock   (adjust_clock),//秒表显示寄存器
//                 .sel            (sel),
//                 .seg            (seg)
// );// ****************************************************************
// 模块例化
// ****************************************************************   
//消抖模块例化
//状态机例化
state_change state_change_inst( .clk		(clk),.rst_n	        (rst_n),.key_in         (key_in),//按键输入.beep           (beep)  ,.led_on         (led_on[1:0]),//led灯显示用来判断当前在什么状态.state          (state)  //状态输出
);//基础时钟例化
counter counter_inst( .clk		(clk),.rst_n	        (rst_n),.key_in         (key_in),.state          (state),.flag           (flag),.times          (times),.adjust_time    (adjust_time)     //时间调整
);	
//调时模块例化
adjust_state adjust_state_inst( .clk	        (clk),.rst_n	        (rst_n),.key_in         (key_),.state          (state),.times          (times),.flag           (flag),.adjust_time    (adjust_time)
);	
//闹钟模块例化
alarm_clock alarm_clock_inst( .clk		(clk),.rst_n	        (rst_n),.key_in         (key_in),.state          (state),.times          (times),.beep           (beep),.flag_alarm     (flag_alarm),.adjust_alarm   (adjust_alarm),.led_alarm      (led_on[3]));
//秒表模块例化
stop_watch stop_watch_inst( .clk		    (clk),.rst_n	        (rst_n),.key_in         (key_in),.state          (state),.adjust_clock   (adjust_clock)//秒表寄存器(分钟/秒/毫秒/)
);
//数码管驱动例化
seg_dirver seg_dirver_inst( .clk		(clk),.rst_n	        (rst_n),.state          (state),.times          (times),.point          (6'b101011),.flag           (flag),//调时位选信号.adjust_time    (adjust_time),//调时显示寄存器.flag_alarm     (flag_alarm),//闹钟位选信号.adjust_alarm   (adjust_alarm),//闹钟显示寄存器.adjust_clock   (adjust_clock),//秒表显示寄存器.sel            (sel),.seg            (seg)
);
endmodule

四,测试文件

`timescale 1ns/1nsmodule top_tb();//激励信号定义 
reg		            clk     ;
reg		            rst_n	;
reg    [3:0]        key_in  ;//输出信号定义	 
wire    [3:0]       led_on ;
wire                beep   ;
wire    [5:0]       sel    ;
wire    [7:0]       seg    ;
//时钟周期参数定义	parameter		CYCLE = 20; defparam        top_inst.counter_inst.MAX1s = 10*CYCLE,top_inst.seg_dirver_inst.MAX20US = CYCLE,top_inst.seg_dirver_inst.MAX_500MS = 5*CYCLE,  top_inst.alarm_clock_inst.MAX1S = 10*CYCLE;//模块例化top top_inst( .clk     (clk),.rst_n	 (rst_n),.key_in  (key_in),.led_on  (led_on),.beep    (beep),.sel     (sel),.seg     (seg)
);	//产生时钟initial 		clk = 1'b0;always #(CYCLE/2) clk = ~clk;//产生激励// //调值模块仿真
//     initial  begin 
//         rst_n = 1'b1;
//         key_in = 4'b1111;
//         #(CYCLE*2);
//         rst_n = 1'b0;
//         #(CYCLE*20);
//        rst_n = 1'b1;
//        #(CYCLE*10000)  //延迟10000个周期来观察基础时钟
//        key_in = 4'b1110;//按下key0进入调时状态
//        #CYCLE
//        key_in = 4'b1111;
//        #(CYCLE*20)
//        key_in = 4'b1101;    //按下key1选择第一位
//        #CYCLE
//        key_in = 4'b1111;
//        #(CYCLE*20)
//        repeat(5)begin
//         key_in = 4'b1011;//连续按下key2使得秒的个位+1
//        #(CYCLE)
//        key_in = 4'b1111;
//        #(CYCLE*20);
//        end
//        #(CYCLE*100)
//        key_in = 4'b0111;//按下key3确定更改时间
//        #(CYCLE)
//        key_in = 4'b1111;
//        #(CYCLE*10000)
//         $stop;
//     end//调值模块仿真initial  begin rst_n = 1'b1;key_in = 4'b1111;#(CYCLE*2);rst_n = 1'b0;#(CYCLE*20);rst_n = 1'b1;key_in = 4'b1101;//按下key1进入闹钟状态#CYCLEkey_in = 4'b1111;#(CYCLE*20)key_in = 4'b1101;    //按下key1选择第一位#CYCLEkey_in = 4'b1111;#(CYCLE*20)key_in = 4'b1101;    //按下key1选择第二位#CYCLEkey_in = 4'b1111;#(CYCLE*20)repeat(5)beginkey_in = 4'b1011;//连续按下key2使得秒的个位+1使得计时50s#(CYCLE)key_in = 4'b1111;#(CYCLE*20);endkey_in = 4'b0111;//按下key3确定设定闹钟#(CYCLE)key_in = 4'b1111;#(CYCLE*10000)  //延迟10000个周期等待闹钟触发#(CYCLE*10000)$stop;endendmodule 

波形:
这是基础时钟的仿真波形,可以看到基础功能实现
在这里插入图片描述

这是修改时间模块的波形,可以看到当按键按下时状态改变并且当按下key1时位置信号变为001表示控制个位,之后按下key2个位数字+1并且按下key3时基础时钟的times变更为更改时间adjust_time的值说明更改成功基本功能实现
在这里插入图片描述

下面是闹钟模块的仿真波形,可以看到当设置闹钟后,等到基础时钟到达设定值,蜂鸣器拉低,开始5s计时,当计时结束蜂鸣器拉高停止响,这里我也同样做了按键停止,但是效果差不多,就只展示计时停止
在这里插入图片描述

六,结果展示

上板验证

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/63700.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

HTML5 Canvas和Svg:哪个简单且好用?

HTML5 Canvas 和 SVG 都是基于标准的 HTML5 技术&#xff0c;可用于创建令人惊叹的图形和视觉体验。 首先&#xff0c;让我们花几句话介绍HTML5 Canvas和SVG。 什么是Canvas? Canvas&#xff08;通过 标签使用&#xff09;是一个 HTML 元素&#xff0c;用于在用户计算机屏幕…

kubernetes中最小组件——Pod

目录 一、Pod简介 二、Pod的使用方式 三、Pause——Pod中底层基础容器 四、为什么kubernetes这样设计Pod 五、Pod的分类 1.自主式Pod 2.控制器管理的Pod 3.静态Pod 六、Pod容器的分类 1. 基础容器&#xff08;infrastructure container&#xff09; 2. 初始化容器&am…

Reinforcement Learning with Code 【Chapter 10. Actor Critic】

Reinforcement Learning with Code 【Chapter 10. Actor Critic】 This note records how the author begin to learn RL. Both theoretical understanding and code practice are presented. Many material are referenced such as ZhaoShiyu’s Mathematical Foundation of …

pc端网页用vue并且实现响应式 vue+bootstrap-vue

1、hbuiler内新建vue项目 在项目文件夹下用npm加载依赖&#xff08;或者用hbuilder内打开命令&#xff09; 2、配置路由 src内新建router文件夹&#xff0c;router内新建index.js index.js内配置重定向到首页 main.js内配置路由 import router from /router/index.js new…

java获取到heapdump文件后,如何快速分析?

简介 在之前的OOM问题复盘之后&#xff0c;本周&#xff0c;又一Java服务出现了内存问题&#xff0c;这次问题不严重&#xff0c;只会触发堆内存占用高报警&#xff0c;没有触发OOM&#xff0c;但好在之前的复盘中总结了dump脚本&#xff0c;会在堆占用高时自动执行jstack与jm…

9.3.2.1网络原理(UDP)

1.UDP的基本特点:无连接,不可靠传输,面向数据报,全双工. 2.1~1024的端口号有特定的含义,不建议使用.比如21:ftp,22:ssh,80:http,443:https. 3.CRC校验算法:循环冗余校验和,把UDP报中的每个字节都依次进行累加,把累加的结果,放到两个字节的变量中,溢出也无所谓,因为都加了一遍.…

基于python+MobileNetV2算法模型实现一个图像识别分类系统

一、目录 算法模型介绍模型使用训练模型评估项目扩展 二、算法模型介绍 图像识别是计算机视觉领域的重要研究方向&#xff0c;它在人脸识别、物体检测、图像分类等领域有着广泛的应用。随着移动设备的普及和计算资源的限制&#xff0c;设计高效的图像识别算法变得尤为重要。…

oracle的管道函数

Oracle管道函数(Pipelined Table Function)oracle管道函数 1、管道函数即是可以返回行集合&#xff08;可以使嵌套表nested table 或数组 varray&#xff09;的函数&#xff0c;我们可以像查询物理表一样查询它或者将其赋值给集合变量。 2、管道函数为并行执行&#xff0c;在…

Python 中的机器学习简介:多项式回归

一、说明 多项式回归可以识别自变量和因变量之间的非线性关系。本文是关于回归、梯度下降和 MSE 系列文章的第三篇。前面的文章介绍了简单线性回归、回归的正态方程和多元线性回归。 二、多项式回归 多项式回归用于最适合曲线拟合的复杂数据。它可以被视为多元线性回归的子集。…

【C语言】小游戏-三字棋

大家好&#xff0c;我是深鱼~ 目录 一、游戏介绍 二、文件分装 三、代码实现步骤 1.制作简易游戏菜单 2.初始化棋盘 3.打印棋盘 4.玩家下棋 5.电脑随机下棋 6.判断输赢 7.判断棋盘是否满了 四、完整代码 game.h(相关函数的声明&#xff0c;整个代码要引用的头文件以及宏…

CSS 中的优先级规则是怎样的?

聚沙成塔每天进步一点点 ⭐ 专栏简介⭐内联样式&#xff08;Inline Styles&#xff09;⭐ID 选择器&#xff08;ID Selectors&#xff09;⭐类选择器、属性选择器和伪类选择器&#xff08;Class, Attribute, and Pseudo-class Selectors&#xff09;⭐元素选择器和伪元素选择器…

如何让ES低成本、高性能?滴滴落地ZSTD压缩算法的实践分享

前文分别介绍了滴滴自研的ES强一致性多活是如何实现的、以及如何提升ES的性能潜力。由于滴滴ES日志场景每天写入量在5PB-10PB量级&#xff0c;写入压力和业务成本压力大&#xff0c;为了提升ES的写入性能&#xff0c;我们让ES支持ZSTD压缩算法&#xff0c;本篇文章详细展开滴滴…