1, Design requirements
A signal frequency detector is designed with FPGA, which requires:
(1) Measuring pulse signal;
(2) Frequency measurement 1-10MHz and duty cycle 10% - 99%, accurate to 1%;
(3) Display the measured frequency and duty cycle on LCD1602;
2, Design scheme
FPGA design is mainly divided into three modules: 1. Measured signal generation module; 2. Tested signal detection module; 3. Digital display module. The design block diagram is shown in Figure 1.
Fig. 1 design block diagram of signal frequency detector based on FPGA
-
Measured signal generation module
The module is mainly used to generate the measured signal. The frequency and duty cycle of the measured signal can be set in the module. The method adopted is to count and divide the system clock to generate the measured signal. This part also uses a PLL to output a 100MHz clock as the sampling clock of the detection module. Module involved in this part: signal_gen module and PLL module. -
Tested signal detection module
The module detects the measured signal by equal precision frequency measurement method:
(1) Frequency detection of measured signal
Detect the frequency of the measured signal. When the external enable signal is valid (i.e. within a period of time), count the number of system clock pulses Ns and the number of measured signal pulses nd. If the system clock frequency is Fs and the measured signal frequency is Fd, then Fs/Ns=Fd/Nd, and finally Fd=(Fs/Ns) · nd.
(2) Duty cycle detection of measured signal:
Detect the duty cycle of the measured signal, use the system clock, count the positive pulse width Np and negative pulse width Nn of the measured signal when the external enable signal is valid (i.e. within a period of time), then the duty cycle ducy=Np/(Np+Nn)*100%.
Module involved in this part: signal_detect module. -
Digital display module
The module is mainly divided into two parts: one part is to convert the detected frequency code into Decimal BCD code. Although this method will improve the operation time, it can greatly save FPGA resources (the tradeoff between area and speed); Another part is to drive LCD1602 for display. Here are some steps to convert binary code into Decimal BCD code (taking 8bit binary code as an example): 1. Shift the binary code one bit to the left (or multiply by 2); 2. Find the ten and hundred bits corresponding to the code shifted to the left; 3. Judge whether the code of one digit, ten digit and hundred digit is greater than or equal to 5; 4. Continue to repeat the above three steps until it stops after 8 shifts; 5. If yes, add 3 to this segment. Modules involved in this part: BCD2to10 module and LCD 1602 module.
Finally, the RTL view of FPGA is shown in Figure 2:
//synopsys translate_off `timescale 1 ns/ 1 ps //synopsys translate_on module BCD2to10( clk_100M, rst_n, d_clk_freq, qw, bw, sw, w, q, b, s, g); input clk_100M; // Sampling clock 100MHz input rst_n; // Reset signal input [31:0] d_clk_freq; // Measured signal frequency output [3:0] qw; // Convert and extract tens of millions of bits output [3:0] bw; // Convert and extract millions of bits output [3:0] sw; // Convert and extract 100000 bits output [3:0] w; // Conversion extraction 10000 bits output [3:0] q; // Conversion extraction thousands output [3:0] b; // Conversion extraction hundredth output [3:0] s; // Convert and extract ten bits output [3:0] g; // Convert extracted bits parameter ST0 = 2'b00; parameter ST1 = 2'b01; parameter ST2 = 2'b10; //------------------------------------------------------------------- // Firstly, several steps of converting binary code into Decimal BCD code are given (taking 8bit binary code as an example) // 1. Shift the binary code one bit to the left (or multiply by 2) // 2. Find the ten or hundred digits corresponding to the code shifted to the left.? // 3. Judge whether the code of one digit, ten digit and hundred digit is greater than or equal to 5 // 4. Continue to repeat the above three steps until it stops after 8 shifts. // 5. If yes, add 3 to this segment. //----------------------------------------------------------------- reg [31:0] d_clk_shift_reg; reg [5:0] shift_count; reg shift_done; reg [31:0] bcd_reg; reg [3:0] qw; reg [3:0] bw; reg [3:0] sw; reg [3:0] w; reg [3:0] q; reg [3:0] b; reg [3:0] s; reg [3:0] g; reg [1:0] state; always@(posedge clk_100M or negedge rst_n) begin if(rst_n == 1'b0) d_clk_shift_reg <= #1 32'b0; else begin if(shift_done == 1'b1) d_clk_shift_reg <= #1 32'b0; else d_clk_shift_reg <= #1 d_clk_freq << shift_count; end end always@(posedge clk_100M or negedge rst_n) begin if(rst_n == 1'b0) shift_done <= #1 1'b0; else begin if(shift_count == 6'd32) shift_done <= #1 1'b1; else shift_done <= #1 1'b0; end end always@(posedge clk_100M or negedge rst_n) begin if(rst_n == 1'b0) begin bcd_reg <= #1 32'b0; shift_count <= #1 6'b0; state <= #1 ST0; end else begin if(shift_done == 1'b0) begin case(state) ST0:begin bcd_reg <= #1 {bcd_reg[31:1],d_clk_shift_reg[31]}; // displacement state <= #1 ST1; end ST1:begin if(bcd_reg[31:28] >= 4'd5) // qw bcd_reg[31:28] <=#1 bcd_reg[31:28] + 4'd3; else bcd_reg[31:28] <=#1 bcd_reg[31:28]; if(bcd_reg[27:24] >= 4'd5) // bw bcd_reg[27:24] <=#1 bcd_reg[27:24] + 4'd3; else bcd_reg[27:24] <=#1 bcd_reg[27:24]; if(bcd_reg[23:20] >= 4'd5) // sw bcd_reg[23:20] <=#1 bcd_reg[23:20] + 4'd3; else bcd_reg[23:20] <=#1 bcd_reg[23:20]; if(bcd_reg[19:16] >= 4'd5) // w bcd_reg[19:16] <=#1 bcd_reg[19:16] + 4'd3; else bcd_reg[19:16] <=#1 bcd_reg[19:16]; if(bcd_reg[15:12] >= 4'd5) // q bcd_reg[15:12] <=#1 bcd_reg[15:12] + 4'd3; else bcd_reg[15:12] <=#1 bcd_reg[15:12]; if(bcd_reg[11:8] >= 4'd5) // b bcd_reg[11:8] <=#1 bcd_reg[11:8] + 4'd3; else bcd_reg[11:8] <=#1 bcd_reg[11:8]; if(bcd_reg[7:4] >= 4'd5) // s bcd_reg[7:4] <=#1 bcd_reg[7:4] + 4'd3; else bcd_reg[7:4] <=#1 bcd_reg[7:4]; if(bcd_reg[3:0] >= 4'd5) // g bcd_reg[3:0] <=#1 bcd_reg[3:0] + 4'd3; else bcd_reg[3:0] <=#1 bcd_reg[3:0]; state <= #1 ST2; end ST2:begin bcd_reg <= #1 bcd_ reg << 1'b1; // displacement shift_count <= #1 shift_count + 1'b1; state <= #1 ST0; end default:bcd_reg <= #1 bcd_reg; endcase end else begin state <= #1 ST0; bcd_reg <= #1 32'b0; shift_count <= #1 6'b0; end end end reg [31:0] bcd_reg2; always@(posedge clk_100M or negedge rst_n) begin if(rst_n == 1'b0) bcd_reg2 <= #1 32'b0; else begin if(shift_count == 6'd32) bcd_reg2 <= #1 bcd_reg; else bcd_reg2 <= #1 bcd_reg2; end end always@(posedge clk_100M or negedge rst_n) begin if(rst_n == 1'b0) qw <= #1 4'b0; else begin if(shift_done == 1'b1) qw <= #1 bcd_reg2[31:28]; else qw <= #1 qw; end end always@(posedge clk_100M or negedge rst_n) begin if(rst_n == 1'b0) bw <= #1 4'b0; else begin if(shift_done == 1'b1) bw <= #1 bcd_reg2[27:24]; else bw <= #1 bw; end end always@(posedge clk_100M or negedge rst_n) begin if(rst_n == 1'b0) sw <= #1 4'b0; else begin if(shift_done == 1'b1) sw <= #1 bcd_reg2[23:20]; else sw <= #1 sw; end end always@(posedge clk_100M or negedge rst_n) begin if(rst_n == 1'b0) w <= #1 4'b0; else begin if(shift_done == 1'b1) w <= #1 bcd_reg2[19:16]; else w <= #1 w; end end always@(posedge clk_100M or negedge rst_n) begin if(rst_n == 1'b0) q <= #1 4'b0; else begin if(shift_done == 1'b1) q <= #1 bcd_reg2[15:12]; else q <= #1 q; end end always@(posedge clk_100M or negedge rst_n) begin if(rst_n == 1'b0) b <= #1 4'b0; else begin if(shift_done == 1'b1) b <= #1 bcd_reg2[11:8]; else b <= #1 b; end end always@(posedge clk_100M or negedge rst_n) begin if(rst_n == 1'b0) s <= #1 4'b0; else begin if(shift_done == 1'b1) s <= #1 bcd_reg2[7:4]; else s <= #1 s; end end always@(posedge clk_100M or negedge rst_n) begin if(rst_n == 1'b0) g <= #1 4'b0; else begin if(shift_done == 1'b1) g <= #1 bcd_reg2[3:0]; else g <= #1 g; end end endmodule
Link: https://pan.baidu.com/s/1AjCw2kyBkggQ5doQ2vNWkg
Extraction code: 1234