Implementation of Seven-segment Digital Tube Timer Based on FPGA

Stopwatch timer (2019.7.28)

mistake:
1. Try not to operate the output port in a module, define another reg type data inside the module, operate on this data, and then connect to the output port with assign
2. Instantiate another in the top-level module When a module, pay attention to the stimulus given and the data width defined in the called module to be consistent
. 3. When writing the tb file, the signal valid time should be after the reset signal is inverted.
4. The design idea, the function of each module What is it for, the role of the output and input of this module, and draw the flow chart of the design idea. This is the most important
5. Each module has a clock and reset signal

Design idea:
top-level module top.v(input: key_start key_stop output led1)

Debounce and edge detection module (input key_start key_stop output key_start_neg key_stop_neg)
Debounce method: 1. Beat the signal for three times 2. Use a counter to count to 20ms and consider that the jitter is over

Frequency division: (output en)
Function: divide the frequency of 50M clock (set a counter with output enable) to get an asymmetrical pulse signal

Get six counters to represent six digital tubes: (input:en output: en1,en2,en3,en4,en5,en6)
On the basis of the frequency division module in the previous step, follow the method of full decimal one and self-acoustic zero , Get six pulse signals in turn

State machine: digital tube work mode conversion (IDLE WORK STOP)

Decoding: Decoding the six counters generated in the previous step (you can first make a module to decode, and then instantiate it six times)

Design requirements:
six digital tubes, the highest two digits are seconds, the middle three digits are milliseconds, and the lowest digit is a hundred subtle

Code:
1. The top module
module clock_0(clk,Rst_n,key1,key2,
led1,led2,led3,led4,led5,led6);

input clk;
input Rst_n;
input key1;
input key2;

output [6:0]led1;
output [6:0]led2;
output [6:0]led3;
output [6:0]led4;
output [6:0]led5;
output [6:0]led6;

wire en1_wire;
wire en2_wire;
wire en3_wire;

div div_inst//分频 ok
(
.clk(clk),
.Rst_n(Rst_n),
.en1(en1_wire),
.en2(en2_wire),
.en3(en3_wire)
);

//消抖和采沿 ok
wire key1_neg_wir ;
wire key2_neg_wir ;
pro pro_inst
(
.clk(clk),
.Rst_n(Rst_n),
.key1(key1),
.key2(key2),
.key_start(),
.key_stop(),
.key1_neg(key1_neg_wir),
.key2_neg(key2_neg_wir)
);

//state machine
wire [3:0]count_en1_wire;
st st_inst
(
.clk(clk),
.Rst_n(Rst_n),
.key1_neg(key1_neg_wir),
.key2_neg(key2_neg_wir),
.en1(en1_wire),
.en2(en2_wire),
.en3(en3_wire),
.count_en1(count_en1_wire),
.count_en2( ),
.count_en3( )
);

//分离
wire [3:0] count1_wire;
wire [3:0] count2_wire;
wire [3:0] count3_wire;
wire [3:0] count4_wire;
wire [3:0] count5_wire;
wire [3:0] count6_wire;
fenli fenli_list
(
.clk(clk),
.Rst_n(Rst_n),
.count_en1(count_en1_wire),
.count1(count1_wire),
.count2(count2_wire),
.count3(count3_wire),
.count4(count4_wire),
.count5(count5_wire),
.count6(count6_wire)
);

//译码
decode decode_inst
(
.clk(clk),
.Rst_n(Rst_n),
.output1(count1_wire),
.output2(count2_wire),
.output3(count3_wire),
.output4(count4_wire),
.output5(count5_wire),
.output6(count6_wire),
.out_led1(led1),
.out_led2(led2),
.out_led3(led3),
.out_led4(led4),
.out_led5(led5),
.out_led6(led6)
);
endmodule

2. Frequency division module
module div (clk, Rst_n, en1, en2, en3);

input clk;
input Rst_n;
output reg en1;
output reg en2;
output reg en3;

parameter countus_max=5000;
parameter countms_max=10;
parameter counts_max=1000;

reg[15:0]countus;
reg[3:0]countms;
reg[11:0]counts;

always@(posedge clk or negedge Rst_n)
begin
if(!Rst_n)
countus<=1’b0;
else if(countus==countus_max-1’b1)
countus<=1’b0;
else
countus<=countus+1’b1;
end

always@(posedge clk or negedge Rst_n)
if(!Rst_n)
en1<=1’b0;
else if(countus==countus_max-1’b1)
en1<=1’b1;
else
en1<=1’b0;

always@(posedge clk or negedge Rst_n)
begin
/* The two writing methods are equivalent
if(!Rst_n)
countms<=1'b0;
else if((countmscountms_max-1’b1)&&(countuscountus_max-1’b1))
countms<=1’b0;
else if(countuscountus_max-1’b1)
countms<=countms+1’b1;
*/
if(!Rst_n)
countms<=1’b0;
else if(countus
countus_max-1’b1)
begin
if (countms==countms_max-1’b1)
countms<=1’b0;
else
countms<=countms+1’b1;
end
end

always@(posedge clk or negedge Rst_n)
if(!Rst_n)
en2<=1’b0;
else if(countms==countms_max-1’b1)
en2<=1’b1;
else
en2<=1’b0;

always@(posedge clk or negedge Rst_n)
begin
if(!Rst_n)
counts<=1’b0;
else if(countscounts_max-1’b1)
counts<=1’b0;
else if(countms
countms_max-1’b1)
counts<=counts+1’b1;
end

always@(posedge clk or negedge Rst_n)
if(!Rst_n)
en3<=1’b0;
else if(countms==countms_max-1’b1)
en3<=1’b1;
else
en3<=1’b0;

endmodule

3. Debounce and edge picking
// Debounce and pick edge
module pro(clk,Rst_n,key1,key2,key_start,key_stop,key1_neg,key2_neg);
input clk;
input Rst_n;
input key1;
input key2;

output reg key_start;
output reg key_stop;
output key1_neg;
output key2_neg;

reg key1_1;
reg key1_2;
reg key1_3;
reg key1_4;

reg key2_1;
reg key2_2;
reg key2_3;
reg key2_4;

always@(posedge clk or negedge Rst_n)
begin
if(!Rst_n)begin

key1_1<=1’b0;
key1_2<=1’b0;
key1_3<=1’b0;
end
else begin
key1_1<=key1;
key1_2<=key1_1;
key1_3<=key1_2;
key_start<=key1_3;
end
end

always@(posedge clk or negedge Rst_n)
begin
if(!Rst_n)begin
key2_1<=1’b0;
key2_2<=1’b0;
key2_3<=1’b0;
end
else begin
key2_1<=key2;
key2_2<=key2_1;
key2_3<=key2_2;
key_stop<=key2_3;
end
end

always@(posedge clk or negedge Rst_n)
begin
if(!Rst_n)
key1_4<=1'b0;//operate on a data
else
key1_4<=key1_3;
end

assign key1_neg=(~key1_3)&key1_4;

always@(posedge clk or negedge Rst_n)
begin
if(!Rst_n)
key2_4<=1’b0;
else
key2_4<=key2_3;
end

assign key2_neg=(~key2_3)&key2_4;

endmodule

4状态机
module st(clk,Rst_n,key1_neg,key2_neg,en1,en2,en3,count_en1,count_en2,count_en3);

input clk;
input Rst_n;
input key1_neg;
input key2_neg;
input en1;
input en2;
input en3;

output reg [3:0]count_en1;
output reg [11:0]count_en2;
output reg [7:0]count_en3;

parameter IDLE=3’b001;
parameter WORK=3’b010;
parameter STOP=3’b100;

reg [2:0]current_state;
reg [2:0]next_state;

always@(posedge clk or negedge Rst_n)
if(!Rst_n)
current_state<=IDLE;
else
current_state<=next_state;

always@(*)
if(!Rst_n)
next_state=IDLE;
else
case(current_state)
IDLE: if(key1_neg)
next_state=WORK;
else
next_state=IDLE;
WORK: if(key2_neg)
next_state=STOP;
else
next_state=WORK;
STOP: if(key1_neg)
next_state=WORK;
else
next_state=STOP;
default: next_state=IDLE;
endcase

always@(posedge clk or negedge Rst_n)
if(!Rst_n)begin
count_en1<=1’b0;
count_en2<=1’b0;
count_en3<=1’b0;
end
else
case(next_state)
IDLE: begin
count_en1<=1’b0;
count_en2<=1’b0;
count_en3<=1’b0;
end
WORK: begin
begin
if(count_en1==4’d9)
count_en1<=1’b0;
else if(en1)
count_en1<=count_en1+1’b1;
else
count_en1<=count_en1;
end

	   begin 
	   if(count_en2==10'd999) 
	       count_en2<=1'b0;
	   else if(en2) 
	       count_en2<=count_en2+1'b1;
	   else 
	       count_en2<=count_en2;
	   end
	   
	   begin 
	   if(count_en3==6'd59) 
	       count_en3<=1'b0;
	   else if(en3) 
	       count_en3<=count_en3+1'b1;
	   else 
	       count_en3<=count_en3;
	   end
	   end 
STOP:  
        begin
        count_en1<=count_en1;
		count_en2<=count_en2;
		count_en3<=count_en3;
        end 
default: ;

endcase

endmodule

5. Make six pulse signals
module fenli (clk, Rst_n, count_en1, count1, count2, count3, count4, count5, count6);

input clk;
input Rst_n;
input [3:0]count_en1;

output reg [3:0]count1,count2,count3,count4,count5,count6;
//count1
always@(posedge clk or negedge Rst_n)
if(!Rst_n)
count1<=1’b0;
else
count1<=count_en1;
//count2
always@(posedge clk or negedge Rst_n)
if(!Rst_n)
count2<=1’b0;
else if(count24’d9&&count14’d9)
count2<=1’b0;
else if(count14’d9)
count2<=count2+1’b1;
else
count2<=count2;
//count3
always@(posedge clk or negedge Rst_n)
if(!Rst_n)
count3<=1’b0;
else if(count3
4’d9&&count24’d9&&count14’d9)
count3<=1’b0;
else if(count24’d9&&count14’d9)
count3<=count3+1’b1;
else
count3<=count3;
//count4
always@(posedge clk or negedge Rst_n)
if(!Rst_n)
count4<=1’b0;
else if(count44’d9&&count34’d9&&count24’d9&&count14’d9)
count4<=1’b0;
else if(count34’d9&&count24’d9&&count14’d9)
count4<=count4+1’b1;
else
count4<=count4;
//count5
always@(posedge clk or negedge Rst_n)
if(!Rst_n)
count5<=1’b0;
else if(count5
4’d9&&count44’d9&&count34’d9&&count24’d9&&count14’d9)
count5<=1’b0;
else if(count44’d9&&count34’d9&&count24’d9&&count14’d9)
count5<=count5+1’b1;
else
count5<=count5;
//count6 写法简单 外设一个wire
always@(posedge clk or negedge Rst_n)
if(!Rst_n)
count6<=1’b0;
else if(count64’d5&&count54’d9&&count44’d9&&count34’d9&&count24’d9&&count14’d9)
count6<=1’b0;
else if(count54’d9&&count44’d9&&count34’d9&&count24’d9&&count1==4’d9)
count6<=count6+1’b1;
else
count6<=count6;
endmodule

6.译码器
module decode(clk,Rst_n,output1,output2,output3,output4,output5,output6,
out_led1,out_led2,out_led3,out_led4,out_led5,out_led6);

input clk;
input Rst_n;
input [3:0]output1;
input [3:0]output2;
input [3:0]output3;
input [3:0]output4;
input [3:0]output5;
input [3:0]output6;

output [6:0]out_led1;
output [6:0]out_led2;
output [6:0]out_led3;
output [6:0]out_led4;
output [6:0]out_led5;
output [6:0]out_led6;

wire [6:0]out_led11;
wire [6:0]out_led21;
wire [6:0]out_led31;
wire [6:0]out_led41;
wire [6:0]out_led51;
wire [6:0]out_led61;

led8 decode1_i
(
. clk(clk),
. Rst_n(Rst_n),
. d_cnt(output1),
. seg(out_led11)
);

led8 decode2_i
(
. clk(clk),
. Rst_n(Rst_n),
. d_cnt(output2),
. seg(out_led21)
);

led8 decode3_i
(
. clk(clk),
. Rst_n(Rst_n),
. d_cnt(output3),
. seg(out_led31)
);

led8 decode4_i
(
. clk(clk),
. Rst_n(Rst_n),
. d_cnt(output4),
. seg(out_led41)
);

led8 decode5_i
(
. clk(clk),
. Rst_n(Rst_n),
. d_cnt(output5),
. seg(out_led51)
);

led8 decode6_i
(
. clk(clk),
. Rst_n(Rst_n),
. d_cnt(output6),
. seg(out_led61)
);

assign out_led1=out_led11;
assign out_led2=out_led21;
assign out_led3=out_led31;
assign out_led4=out_led41;
assign out_led5=out_led51;
assign out_led6=out_led61;
endmodule

7. Decoding module
module led8
(
input clk,
input Rst_n,
input [3:0] d_cnt,
output [6:0]seg
);

parameter
S0=7’b100_0000,
S1=7’b111_1001,
S2=7’b010_0100,
S3=7’b011_0000,
S4=7’b001_1001,
S5=7’b001_0010,
S6=7’b000_0010,
S7=7’b111_1000,
S8=7’b000_0000,
S9=7’b001_0000;

reg [6: 0] seg_1;
always @ (posedge clk)
begin
if (~ Rst_n)
seg_1 <= 0;
else
case (d_cnt)
4'b0000: seg_1 <= S0;
4'b0001: seg_1 <= S1;
4'b0010: seg_1 <= S2;
4'b0011: seg_1 <= S4;
4'b0100: seg_1 <= S5;
4'b0101: seg_1 <= S6;
4'b0110: seg_1 <= S7;
4'b0111: seg_1 <= S8;
4'b1000: seg_1 <= S9;
default: seg_1 <= S0;
endcase
end
assign seg = seg_1;

endmodule

Guess you like

Origin blog.csdn.net/jiyishizhe/article/details/97624066