基于FPGA的时钟(简易版)

 实现功能:

1.上电后从00-00-00开始计时;

2.通过串口可以改变时钟,同时以修改后的数值为基础继续计时;

欢迎大家一起探讨!!!

// -----------------------------------------------------------------------------
// Copyright (c) 2022-2023 All rights reserved
// -----------------------------------------------------------------------------
// Author : tang  [email protected]
// File   : smg_ctrl.v
// Create : 2023-02-11 17:52:16
// Revise : 2023-02-12 09:38:20
// Editor : sublime text3, tab size (4)
// -----------------------------------------------------------------------------
module smg_ctrl(
	input	wire			clk,
	input	wire			rst_n,
	input	wire			rx,
	output	reg 	[2:0]	sel,
	output	reg   	[7:0]	seg
	);

parameter	CNT_S_MAX = 50000000-1;//1000000   50,000,000
reg		[5:0]	shi;
reg		[5:0]	min;
reg		[5:0]	sec;
reg		[25:0]	cnt_s;
reg		[3:0]	shu;
reg   	[5:0]	se_123456; 
reg		[15:0]	cnt_sel;
wire    [23:0]  data_smg;
wire			flag_data_smg;
reg 	[23:0]	data;
wire	[7:0]	po_data;
wire			po_flag;
always @(posedge clk or negedge rst_n) begin
	if (rst_n==1'b0) begin
		cnt_sel	<='d0;
	end
	else if (cnt_sel==49999) begin
		cnt_sel	<='d0;
	end
	else begin
		cnt_sel	<=cnt_sel +1'b1;
	end
end

always @(posedge clk or negedge rst_n) begin
	if (rst_n==1'b0) begin
		sel <= 'd0;
	end
	else if(sel=='d5 && cnt_sel==49999) begin
		sel <= 'd0;
	end
	else  if(cnt_sel==49999)begin
		sel <= sel + 1'b1;
	end
end

always @(posedge clk or negedge rst_n) begin
	if(rst_n==1'b0)begin
		se_123456<=6'b000_001;
	end begin 
		case(sel)
		0:se_123456<=6'b000_001;
		1:se_123456<=6'b000_010;
		2:se_123456<=6'b000_100;
		3:se_123456<=6'b001_000;
		4:se_123456<=6'b010_000;
		5:se_123456<=6'b100_000;
		default se_123456<=6'b000000;
		endcase
	end
end

always @(posedge clk or negedge rst_n) begin
	if (rst_n==1'b0) begin
		cnt_s <='d0;
	end
	else if (cnt_s==CNT_S_MAX) begin
		cnt_s <='d0;
	end
	else begin
		cnt_s<=cnt_s + 1;
	end
end

always @(posedge clk or negedge rst_n) begin
	if (rst_n==1'b0) begin
		sec<='d0;
	end
	else if (sec>=60) begin
		sec<='d0;
	end
	else if (flag_data_smg==1'b1) begin
		sec<=data_smg[7:0];
		end
	else if (sec == 'd59 && cnt_s==CNT_S_MAX) begin
		sec <= 'd0;
	end
	else  if(cnt_s==CNT_S_MAX) begin
		sec <= sec + 1'b1;
	end
end

always @(posedge clk or negedge rst_n) begin
	if (rst_n==1'b0) begin
		min<='d0;
	end
	else if (min>=60) begin
		min<='d0;
	end
	else if (flag_data_smg==1'b1) begin
		min<=data_smg[15:8];
	end
	else if (min == 'd59 && sec == 'd59 && cnt_s==CNT_S_MAX) begin
		min <= 'd0;
	end
	else  if(sec == 'd59 && cnt_s==CNT_S_MAX) begin
		min <= min + 1'b1;
	end
end

always @(posedge clk or negedge rst_n) begin
	if (rst_n==1'b0) begin
		shi<='d0;
	end
	else if (shi>=24) begin
		shi<='d0;
	end
	else if (flag_data_smg==1'b1) begin
		shi<=data_smg[23:16];
	end
	else if (shi == 'd23 && min == 'd59 && sec == 'd59 && cnt_s==CNT_S_MAX) begin
		shi <= 'd0;
	end
	else  if(min == 'd59 && sec == 'd59 && cnt_s==CNT_S_MAX) begin
		shi <= shi + 1'b1;
	end
end

always @(posedge clk or negedge rst_n) begin
	if (rst_n==1'b0) begin
		data<='d0;
	end
	else if (flag_data_smg==1'b1) begin
		data<=data_smg;
	end
	else  begin
		data[7:0]<=sec;
		data[15:8]<=min;
		data[23:16]<=shi;
	end
end


always @(posedge clk or negedge rst_n) begin
	if (rst_n==1'b0) begin
		shu<='d0;
	end
	else begin
		case(se_123456)
		6'b100000:shu<=data[7:0]%10;
		6'b010000:shu<=data[7:0]/10;
		6'b001000:shu<=data[15:8]%10;
		6'b000100:shu<=data[15:8]/10;
		6'b000010:shu<=data[23:16]%10;
		6'b000001:shu<=data[23:16]/10;
		default : shu<='d0;
		endcase
	end
	end

always @(posedge clk or negedge rst_n) begin
	if (rst_n==1'b0) begin
		seg <='d0;
	end
	else   begin
		case(shu)
     		4'd0  : seg  <=  8'b1100_0000;    
            4'd1  : seg  <=  8'b1111_1001;    
            4'd2  : seg  <=  8'b1010_0100;    
            4'd3  : seg  <=  8'b1011_0000;    
            4'd4  : seg  <=  8'b1001_1001;    
            4'd5  : seg  <=  8'b1001_0010;    
            4'd6  : seg  <=  8'b1000_0010;    
            4'd7  : seg  <=  8'b1111_1000;    
            4'd8  : seg  <=  8'b1000_0000;    
            4'd9  : seg  <=  8'b1001_0000;    
            default:seg  <=  8'b1111_1111;
		endcase
	end
end

data_uart_rx inst_data_uart_rx
		(
			.clk           (clk),
			.rst_n         (rst_n),
			.po_data       (po_data),
			.po_flag       (po_flag),
			.data_smg      (data_smg),
			.flag_data_smg (flag_data_smg)
		);


uart_rx  inst_uart_rx (
			.clk     (clk),
			.rst_n   (rst_n),
			.rx      (rx),
			.po_data (po_data),
			.po_flag (po_flag)
		);

endmodule


module uart_rx(
input		wire			clk,
input		wire			rst_n,
input		wire			rx,
output		reg 	[7:0]	po_data,
output		reg 			po_flag					
	);
parameter	CNT_BUAD = 5207;
reg						rx_dly1,rx_dly2,rx_reg;
reg						rx_flag;
reg			[12:0]		cnt_buad;
reg						bit_flag;
reg			[3:0]		bit_cnt;


always @(posedge clk ) begin
	{rx_reg,rx_dly2,rx_dly1}<={rx_dly2,rx_dly1,rx};
end

always @(posedge clk or negedge rst_n) begin
	if (rst_n==1'b0) begin
		rx_flag <= 'd0;
	end
	else if (rx_reg==1'b1 && rx_dly2==1'b0 ) begin
		rx_flag <= 1'b1;
	end
	else if(bit_flag==1'b1 && bit_cnt=='d8)begin
		rx_flag <= 1'b0;
	end
end

always @(posedge clk or negedge rst_n) begin
	if (rst_n==1'b0) begin
		cnt_buad <='d0;
	end
	else if (cnt_buad == CNT_BUAD) begin
		cnt_buad <='d0;
	end
	else if( rx_flag==1'b1 )begin
		cnt_buad <=cnt_buad + 1'b1;
	end
	else begin
		cnt_buad <='d0;
	end
end

always @(posedge clk or negedge rst_n) begin
	if (rst_n==1'b0) begin
		bit_flag <= 'd0;
	end
	else if (cnt_buad == 'd2602) begin
		bit_flag <= 1'b1;
	end
	else begin
		bit_flag <= 1'b0;
	end
end

always @(posedge clk or negedge rst_n) begin
	if (rst_n==1'b0) begin
		bit_cnt <= 'd0;
	end
	else if (bit_cnt=='d8 && bit_flag==1'b1) begin
		bit_cnt <= 'd0;
	end
	else if(bit_flag==1'b1)begin
		bit_cnt <= bit_cnt + 1'b1;
	end
end

always @(posedge clk or negedge rst_n) begin
	if (rst_n==1'b0) begin
		po_data	<='d0;
	end
	else if (bit_cnt>='d1 && bit_cnt<='d8 && bit_flag==1'b1) begin
		po_data <= {rx_reg,po_data[7:1]};
	end
end

always @(posedge clk or negedge rst_n) begin
	if (rst_n==1'b0) begin
		po_flag	<= 'd0;
	end
	else if (bit_flag == 1'b1 && bit_cnt=='d8) begin
		po_flag	<= 1'b1;
	end
	else begin
		po_flag <= 1'b0;
	end
end

endmodule
// -----------------------------------------------------------------------------
// Copyright (c) 2022-2023 All rights reserved
// -----------------------------------------------------------------------------
// Author : tang  [email protected]
// File   : data_uart_rx.v
// Create : 2023-02-11 22:46:13
// Revise : 2023-02-11 23:17:56
// Editor : sublime text3, tab size (4)
// -----------------------------------------------------------------------------
module data_uart_rx(
	input	wire			clk,
	input	wire			rst_n,
	input	wire	[7:0]	po_data,
	input	wire			po_flag,
	output	reg 	[23:0]	data_smg,// 3 byte
	output	reg 			flag_data_smg
	);
reg		[1:0]	cnt_flag;

always @(posedge clk or negedge rst_n) begin
	if (rst_n==1'b0) begin
		cnt_flag <='d0;
	end
	else if (cnt_flag=='d3) begin
		cnt_flag <='d0;
	end
	else if (po_flag==1'b1) begin
		cnt_flag <=cnt_flag +1'b1 ;	
	end
end

always @(posedge clk or negedge rst_n) begin
	if (rst_n==1'b0) begin
		flag_data_smg<='d0;
	end
	else if (cnt_flag=='d3) begin
		flag_data_smg<=1'b1;
	end
	else begin
		flag_data_smg<='d0;
	end
end

always @(posedge clk or negedge rst_n) begin
	if (rst_n==1'b0) begin
		data_smg<='d0;
	end
	else if (po_flag==1'b1) begin
		data_smg<={po_data,data_smg[23:8]};
	end
end



endmodule

 

你可能感兴趣的:(FPGA,fpga开发,学习)