[GA]Verilog 60s stopwatch timer
1. Citation
This experiment is based on an optional topic during my undergraduate course Number of Junctions.Since the upload was post-perception and the school had recycled the toe plates, it was impossible to post an effect picture of the code results in this article, but the final effect has been tested and can be safely eaten.Then the code will be pasted and explained for your reference.
2. Frequency division module
We want to implement a stopwatch. Naturally, we want to divide the clk frequency of the clock pulse in the experimental board into a pulse with a period of 1s, and the crystal vibration of the lamb is known to be 12MHz.Paste the code of the crossover module below.
module divide # ( //parameter yes verilog Definition of internal parameters parameter WIDTH = 24, //The number of bits in the counter, with a maximum count of 2**(WIDTH-1) parameter N = 12_000_000 //Crossover factor, make sure N<2**(WIDTH-1),Otherwise the count will overflow ) ( input clk, //clk Frequency 12 MHz input rst_n, //Reset signal, low effective, output clkout //Output signal, which can be connected to LED Clock for frequency division ); reg [WIDTH-1:0] cnt_p,cnt_n; //cnt_p For the counter when the rise edge is triggered, cnt_n Counter when triggered for descent edge reg clk_p,clk_n; //clk_p To trigger a time-frequency clock for the rising edge, clk_n Time-frequency clock triggered for drop edge //Control of counter when rise edge triggers always @(posedge clk or negedge rst_n) begin if(!rst_n) cnt_p <= 1'b0; else if(cnt_p == (N-1)) cnt_p <= 1'b0; else cnt_p <= cnt_p + 1'b1; //The counter keeps counting and clears when it reaches N-1, which is a counter of modulo N end //Rise-edge triggered crossover clock output,If N Clock duty cycle for odd number is not 50%;If N Clock Duty Cycle for Even Number is 50% always @(posedge clk or negedge rst_n) begin if(!rst_n) clk_p <= 1'b0; else if(cnt_p < (N>>1)) //N>>1 Means to move one bit to the right, equal to dividing by two to take a quotient clk_p <= 1'b0; else clk_p <= 1'b1; //The positive cycle of the crossover clock is one more clk clock than the negative cycle end //Counter control when drop edge triggers always @(negedge clk or negedge rst_n) begin if(!rst_n) cnt_n <= 1'b0; else if(cnt_n == (N-1)) cnt_n <= 1'b0; else cnt_n <= cnt_n + 1'b1; end //Decrease the frequency division clock output along the trigger, and clk_p Half difference clk Clock always @(negedge clk or negedge rst_n) begin if(!rst_n) clk_n <= 1'b0; else if(cnt_n < (N>>1)) clk_n <= 1'b0; else clk_n <= 1'b1; //The positive cycle of the crossover clock is one more clk clock than the negative cycle end wire clk1 = clk; //When N=1 When, direct output clk wire clk2 = clk_p; //When N Even number means N The lowest bit is 0, N[0]=0,output clk_p wire clk3 = clk_p & clk_n; //When N For odd numbers that is N The lowest bit is 1, N[0]=1,output clk_p&clk_n. Positive periods are many, so they are phase and assign clkout = (N==1)? clk1:(N[0]? clk3:clk2); //Conditional judgment expression endmodule
3.8-digit tube display module
There are two eight-digit digital tubes on the little foot yam board, which are used to display the display from 00s to 59s in this experiment.Paste the code of the display module of the digital tube below.
module segment ( input wire [3:0] seg_data_1, //Four-bit Input Data Signal input wire [3:0] seg_data_2, //Four-bit Input Data Signal output wire [8:0] segment_led_1, //Digital tube 1, MSB~LSB = SEG,DP,G,F,E,D,C,B,A output wire [8:0] segment_led_2 //Digital Control 2, MSB~LSB = SEG,DP,G,F,E,D,C,B,A ); reg[8:0] seg [15:0]; //Store 7 segments of digital tube decoding data initial begin seg[0] = 9'h3f; // 0 seg[1] = 9'h06; // 1 seg[2] = 9'h5b; // 2 seg[3] = 9'h4f; // 3 seg[4] = 9'h66; // 4 seg[5] = 9'h6d; // 5 seg[6] = 9'h7d; // 6 seg[7] = 9'h07; // 7 seg[8] = 9'h7f; // 8 seg[9] = 9'h6f; // 9 seg[10]= 9'h77; // A seg[11]= 9'h7C; // b seg[12]= 9'h39; // C seg[13]= 9'h5e; // d seg[14]= 9'h79; // E seg[15]= 9'h71; // F end assign segment_led_1 = seg[seg_data_1]; assign segment_led_2 = seg[seg_data_2]; endmodule
4. Functional explanation
In the main module, in addition to instantiating the above two modules, you need to add some bricks to this stopwatch!It is mentioned in the title that this is a 60s stopwatch, and our digital tube display only goes from 00 to 59, but the maximum time range reaches 9 minutes. What can I do about it?Here we use a row of eight-bit LED lights on the little foot. When 59s is counted, the next second the digital tube returns to 00 and lights up one of the eight-bit LED lights to indicate that one minute has been counted.There are eight LED lights. When all eight lights are on, the tube has another chance to display from 00 to 59, so we get a stopwatch with a maximum timer of 9 minutes!Paste the code for the display part of the eight-digit LED light below.
always@(posedge clk) if(cnt1==4'b0) LED[7:0]<=8'b11111111; else if(cnt1==4'b0001) LED[7:0]<=8'b11111110; else if(cnt1==4'b0010) LED[7:0]<=8'b11111100; else if(cnt1==4'b0011) LED[7:0]<=8'b11111000; else if(cnt1==4'b0100) LED[7:0]<=8'b11110000; else if(cnt1==4'b0101) LED[7:0]<=8'b11100000; else if(cnt1==4'b0110) LED[7:0]<=8'b11000000; else if(cnt1<=4'b0111) LED[7:0]<=8'b10000000; else if(cnt1<=4'b1000) LED[7:0]<=8'b00000000;
In addition, as a stopwatch you naturally have the ability to pause and start the timer (and of course the zeroing function is also!The main module is implemented by rst reset key, which is not described here.)Pause and start timing I use the same key here.There are also two RGB tricolor lights on the little foot lamp board. Now that such good resources exist, we should make the most of them!When the start key is pressed, the stopwatch starts to time and the display on the digital tube starts to change. Here we let one of the RGB tricolor lights turn green equally to indicate that it is in the normal timing state. When the start key is pressed again, the stopwatch pauses and we let the other RGB tricolor light turn red to indicate that it is in the pausing state.Paste the code below which contains the three-color lights.
always @(posedge clk1h or negedge rst) //Generate a 60-bit counter begin //Digital tube display should be displayed in decimal mode if(!rst) begin cnt <= 8'h00; //Reset Initial Display 00 cnt1<=4'b0; end else if(flag) begin G_LED2<=1'b0; R_LED1<=1'b1; if(cnt[3:0] == 4'd9) //Nine seats full? begin cnt[3:0] <= 4'd0; //Bit Zeroing if(cnt[7:4] == 4'd5 ) //Ten to five? begin cnt[7:4] <= 4'd0; //Ten-digit Zeroing cnt1<=cnt1+1; end else begin cnt[7:4] <= cnt[7:4] + 1'b1; //Ten plus one cnt1<=cnt1; end end else cnt[3:0] <= cnt[3:0] + 1'b1; //Bits plus one end else begin cnt <= cnt; G_LED2<=1'b1; R_LED1<=1'b0; end end
5. Main Module
Finally, paste the code of the main module to complete the implementation of the entire stopwatch.
module counter60 ( input clk,rst, //Clock and Reset Input input key, //Start pause button output wire [8:0] segment_led_1,segment_led_2, //Digital tube output output reg [7:0] LED, //Eight digits LED lamp output reg R_LED1,G_LED2 //RGB Tri-color light, where red means paused and green means normal timing ); wire clk1h; //1 Seconds clock reg [7:0] cnt; //Timing Counter reg [3:0] cnt1; //Minute counter reg flag; //Start pause flag divide # //Instantiate frequency divider to generate 1 second clock signal ( .WIDTH(24), .N(12_000_000) ) u1 ( .clk(clk), .rst_n(rst), .clkout(clk1h) ); segment u2 //Instantiate Digital Tube Display Module ( .seg_data_1 (cnt[7:4]), //seg_data input .seg_data_2 (cnt[3:0]), //seg_data input .segment_led_1 (segment_led_1), //MSB~LSB = SEG,DP,G,F,E,D,C,B,A .segment_led_2 (segment_led_2) //MSB~LSB = SEG,DP,G,F,E,D,C,B,A ); always @(posedge clk or negedge rst) //Generate a flag signal begin if(!rst) flag = 1'b0; else if(!key) begin flag = ~flag; end else begin flag = flag; end end always @(posedge clk1h or negedge rst) //Generate a 60-bit counter begin //Digital tube display should be displayed in decimal mode if(!rst) begin cnt <= 8'h00; //Reset Initial Display 00 cnt1<=4'b0; end else if(flag) begin G_LED2<=1'b0; R_LED1<=1'b1; if(cnt[3:0] == 4'd9) //Nine seats full? begin cnt[3:0] <= 4'd0; //Bit Zeroing if(cnt[7:4] == 4'd5 ) //Ten to five? begin cnt[7:4] <= 4'd0; //Ten-digit Zeroing cnt1<=cnt1+1; end else begin cnt[7:4] <= cnt[7:4] + 1'b1; //Ten plus one cnt1<=cnt1; end end else cnt[3:0] <= cnt[3:0] + 1'b1; //Bits plus one end else begin cnt <= cnt; G_LED2<=1'b1; R_LED1<=1'b0; end end always@(posedge clk) if(cnt1==4'b0) LED[7:0]<=8'b11111111; else if(cnt1==4'b0001) LED[7:0]<=8'b11111110; else if(cnt1==4'b0010) LED[7:0]<=8'b11111100; else if(cnt1==4'b0011) LED[7:0]<=8'b11111000; else if(cnt1==4'b0100) LED[7:0]<=8'b11110000; else if(cnt1==4'b0101) LED[7:0]<=8'b11100000; else if(cnt1==4'b0110) LED[7:0]<=8'b11000000; else if(cnt1<=4'b0111) LED[7:0]<=8'b10000000; else if(cnt1<=4'b1000) LED[7:0]<=8'b00000000; endmodule module divide # ( //parameter yes verilog Definition of internal parameters parameter WIDTH = 24, //The number of bits in the counter, with a maximum count of 2**(WIDTH-1) parameter N = 12_000_000 //Crossover factor, make sure N<2**(WIDTH-1),Otherwise the count will overflow ) ( input clk, //clk Frequency 12 MHz input rst_n, //Reset signal, low effective, output clkout //Output signal, which can be connected to LED Clock for frequency division ); reg [WIDTH-1:0] cnt_p,cnt_n; //cnt_p For the counter when the rise edge is triggered, cnt_n Counter when triggered for descent edge reg clk_p,clk_n; //clk_p To trigger a time-frequency clock for the rising edge, clk_n Time-frequency clock triggered for drop edge //Control of counter when rise edge triggers always @(posedge clk or negedge rst_n) begin if(!rst_n) cnt_p <= 1'b0; else if(cnt_p == (N-1)) cnt_p <= 1'b0; else cnt_p <= cnt_p + 1'b1; //The counter keeps counting and clears when it reaches N-1, which is a counter of modulo N end //Rise-edge triggered crossover clock output,If N Clock duty cycle for odd number is not 50%;If N Clock Duty Cycle for Even Number is 50% always @(posedge clk or negedge rst_n) begin if(!rst_n) clk_p <= 1'b0; else if(cnt_p < (N>>1)) //N>>1 Means to move one bit to the right, equal to dividing by two to take a quotient clk_p <= 1'b0; else clk_p <= 1'b1; //The positive cycle of the crossover clock is one more clk clock than the negative cycle end //Counter control when drop edge triggers always @(negedge clk or negedge rst_n) begin if(!rst_n) cnt_n <= 1'b0; else if(cnt_n == (N-1)) cnt_n <= 1'b0; else cnt_n <= cnt_n + 1'b1; end //Decrease the frequency division clock output along the trigger, and clk_p Half difference clk Clock always @(negedge clk or negedge rst_n) begin if(!rst_n) clk_n <= 1'b0; else if(cnt_n < (N>>1)) clk_n <= 1'b0; else clk_n <= 1'b1; //The positive cycle of the crossover clock is one more clk clock than the negative cycle end wire clk1 = clk; //When N=1 When, direct output clk wire clk2 = clk_p; //When N Even number means N The lowest bit is 0, N[0]=0,output clk_p wire clk3 = clk_p & clk_n; //When N For odd numbers that is N The lowest bit is 1, N[0]=1,output clk_p&clk_n. Positive periods are many, so they are phase and assign clkout = (N==1)? clk1:(N[0]? clk3:clk2); //Conditional judgment expression endmodule module segment ( input wire [3:0] seg_data_1, //Four-bit Input Data Signal input wire [3:0] seg_data_2, //Four-bit Input Data Signal output wire [8:0] segment_led_1, //Digital tube 1, MSB~LSB = SEG,DP,G,F,E,D,C,B,A output wire [8:0] segment_led_2 //Digital Control 2, MSB~LSB = SEG,DP,G,F,E,D,C,B,A ); reg[8:0] seg [15:0]; //Store 7 segments of digital tube decoding data initial begin seg[0] = 9'h3f; // 0 seg[1] = 9'h06; // 1 seg[2] = 9'h5b; // 2 seg[3] = 9'h4f; // 3 seg[4] = 9'h66; // 4 seg[5] = 9'h6d; // 5 seg[6] = 9'h7d; // 6 seg[7] = 9'h07; // 7 seg[8] = 9'h7f; // 8 seg[9] = 9'h6f; // 9 seg[10]= 9'h77; // A seg[11]= 9'h7C; // b seg[12]= 9'h39; // C seg[13]= 9'h5e; // d seg[14]= 9'h79; // E seg[15]= 9'h71; // F end assign segment_led_1 = seg[seg_data_1]; assign segment_led_2 = seg[seg_data_2]; endmodule
6. Summary
The whole stopwatch is done here.Finally, I apologize to the readers again for not being able to attach the experimental results.Readers with lab boards can burn code into the board to see the phenomenon.I have limited programming level and time, this article is about to end here, welcome readers to comment on the message, and more welcome you to point out my shortcomings, I hope to improve through communication.Finally, thank you for your patience!