FPGA experiment 2: modulo variable counter design

Table of contents

1. Purpose of the experiment

2. Experimental requirements

3. Experiment code

1. Experimental source code

2. Analysis of some code design ideas

4. Experimental results and analysis

1. Pin lock

2. Simulation waveform and analysis

3. Download test results and analysis

5. Experimental experience

1. Solve the difficulties encountered in the experiment and solve them

2. The experience after completing the experiment


1. Purpose of the experiment

(1) Master the FPGA implementation methods of combinational logic circuits and sequential circuits;

(2) Familiar with the use of EDA development boards and development software;

(3) Learn the use of static digital tubes and the design of 7-segment digital display decoders;

(4) Master the role of clocks in sequential circuits;

(5) Master the realization method of the frequency division circuit.

2. Experimental requirements

Design a BCD counter, you can choose the size of the modulus (the maximum modulus value is at least 3 digits), the experimental requirements:

(1) The counting result is displayed with a 3-digit digital tube, and the BCD code is displayed;

(2) Give the simulation waveform of this design;

(3) Select the experimental circuit to verify the function of this counter.

(4) Design an input port with a variable modulus value, and change the counter modulus value by inputting the modulus value and setting the signal

(5) The setting involves a switch and a button, the switch is used as an enable control, and the button is used as an asynchronous clear.

(6) With carry output, and the carry output is displayed with LED lights

3. Experiment code

1. Experimental source code

(1) design source file (limited to space, only part of the code is displayed, and the core code is marked)

  1. `timescale 1ns / 1ns
    module final_counter(
        input CLK,          
        input SW1,          
        input KEY1,       
        input [6:0] M_SET,  
        input M_EN,
        output reg [10:0] display_segout,
        output reg LED_OUT          //输出,用于显示进位状态
    );
    
    reg  [6:0] M;       // 计数器模数
    wire [3:0] bw;
    wire [3:0] sw;
    wire [3:0] gw;
    wire [3:0] qw;
    reg [7:0] cnt_count;
    
    //设置模值
    always@(posedge M_EN)
        begin
           M[0]<=M_SET[0];
           M[1]<=M_SET[1];
           M[2]<=M_SET[2];
           M[3]<=M_SET[3];
           M[4]<=M_SET[4];
           M[5]<=M_SET[5];
           M[6]<=M_SET[6];
         end
            
    
    //数码管各位逻辑关系
    assign qw =M/10;
    assign bw =M%10;
    assign sw =cnt_count%100/10;
    assign gw =cnt_count%10;
    
    reg [19:0]count=0; 
    reg [30:0]count2=0; 
    reg [2:0] sel=0; 
    parameter T1MS=50000;
    reg [6:0]t;
    
    //多位数码管显示
    always@(posedge CLK) 
         begin 
            count<=count+1; 
            if(count==T1MS) 
            begin 
                count<=0; 
                sel<=sel+1; 
                if(sel==4) 
                sel<=0; 
             end 
         end
    //板子计数频率
    reg clk1;
    always @(posedge CLK)
     begin 
      if(count2 == 9_999_999) // 9_999_999==100ms
        begin 
            clk1<=1'b1; 
            count2<=0;
        end 
      else
                begin 
                    clk1<=1'b0;
                    count2<=count2+1'b1;
                end
     end
    //板子数码管显示
    always@(posedge CLK) 
     begin 
        case(sel) 
            0:display_segout<={4'b0111,BCD_OUT0};
            1:display_segout<={4'b1011,BCD_OUT1};
            2:display_segout<={4'b1101,BCD_OUT2};
            3:display_segout<={4'b1110,BCD_OUT3};
            default:display_segout<=11'b1111_1111111; 
        endcase 
     end
     //计数器逻辑
    always @(negedge clk1 or posedge KEY1 )
    begin
        if(KEY1 == 1'b1)   // 异步清零
            begin
                cnt_count <= 0;
            end
        else if(t!=M)
            begin
                cnt_count <= 0;
                t=M;
            end
        else if(SW1 == 1'b1)   // 使能控制
            begin
                if(cnt_count<M-1)
                    begin
                        cnt_count<=cnt_count+1;
                        LED_OUT<=1'b0;
                        if(cnt_count == M-2)
                            LED_OUT <=1'b1;
                    end
                else
                    begin 
                        cnt_count<=0;
                        LED_OUT<=1'b0;
                     end
            end
    end
    
    end module

(2) Simulation test file

  1. `timescale 1ns/1ps
    module sim_CNT();
    reg SW1,KEY1;
    reg [6:0]M_SET;
    reg  M_EN;
    wire [10:0] display_segout;   
    wire LED_OUT;
    
    reg clk1;
    
    initial
        begin
        clk1= 1'b0;
        SW1 = 1'b0;
        M_EN=1'b0;
        #2 KEY1 = 1'b1;
           M_EN<=1'b1;
           M_SET<=7'b000_1010;
           M_EN=1'b0;
        #2 M_EN=1'b0;
        
        #2 KEY1 = 1'b1;    //清零
        #2 KEY1 = 1'b0; SW1 = 1'b1;   //复位,准备开始
           #192 
             M_EN<=1'b1;
             M_SET<=7'b001_1111;
           #2 M_EN=1'b0;
           #20
           #2 KEY1 = 1'b1;    //清零
        #2 KEY1 = 1'b0; SW1 = 1'b1;   //复位,准备开始
        end
    always
        begin
        #5 clk1 = ~clk1;
        end
    final_counter uu1(clk1,SW1,KEY1,M_SET,M_EN,display_segout,LED_OUT);
    
    endmodule   

2. Analysis of some code design ideas

(1) Carry out frequency division operation, the output is clk1, every two complete clk jumps is equivalent to a complete 

clk1 jumps, every time the rising edge of clk1 arrives (when the enable terminal signal is valid and the asynchronous clear signal is invalid), 

The value of the counter is incremented by one.

 ( 2 ) The counter is designed. The transition of the counter is based on the clk1 clock signal, when the enable terminal is valid, 

When the clear signal is invalid, if the value of the counter is less than the set modulo value when the rising edge of clk1 jumps every time 

model, then its value will continue to increase by 1. If the value of the counter is equal to the set modulo value, then the value of the counter will return to 0 and start counting again. Among them, when the counter is at the maximum number under the modulus value, the out signal will be in a 

When the clock signal becomes 1, it means that the modulo value counting is about to end.

4. Experimental results and analysis

1. Pin lock

set_property PACKAGE_PIN U16 [get_ports {cnt_count[0]}]

set_property PACKAGE_PIN E19 [get_ports {cnt_count[1]}]

set_property PACKAGE_PIN U19 [get_ports {cnt_count[2]}]

set_property PACKAGE_PIN V19 [get_ports {cnt_count[3]}]

set_property PACKAGE_PIN W18 [get_ports {cnt_count[4]}]

set_property PACKAGE_PIN U15 [get_ports {cnt_count[5]}]

set_property PACKAGE_PIN U14 [get_ports {cnt_count[6]}]

set_property PACKAGE_PIN V14 [get_ports {cnt_count[7]}]

set_property PACKAGE_PIN U7 [get_ports {display_segout[0]}]

set_property PACKAGE_PIN V5 [get_ports {display_segout[1]}]

set_property PACKAGE_PIN U5 [get_ports {display_segout[2]}]

set_property PACKAGE_PIN V8 [get_ports {display_segout[3]}]

set_property PACKAGE_PIN U8 [get_ports {display_segout[4]}]

set_property PACKAGE_PIN W6 [get_ports {display_segout[5]}]

set_property PACKAGE_PIN W7 [get_ports {display_segout[6]}]

set_property PACKAGE_PIN W4 [get_ports {display_segout[7]}]

set_property PACKAGE_PIN V4 [get_ports {display_segout[8]}]

set_property PACKAGE_PIN U4 [get_ports {display_segout[9]}]

set_property PACKAGE_PIN U2 [get_ports {display_segout[10]}]

set_property PACKAGE_PIN V17 [get_ports {M_SET[0]}]

set_property PACKAGE_PIN V16 [get_ports {M_SET[1]}]

set_property PACKAGE_PIN W16 [get_ports {M_SET[2]}]

set_property PACKAGE_PIN W17 [get_ports {M_SET[3]}]

set_property PACKAGE_PIN V15 [get_ports {M_SET[5]}]

set_property PACKAGE_PIN W14 [get_ports {M_SET[6]}]

set_property PACKAGE_PIN W15 [get_ports {M_SET[4]}]

set_property PACKAGE_PIN W5 [get_ports CLK]

set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets M_EN_IBUF] 

set_property PACKAGE_PIN L1 [get_ports LED_OUT]

set_property PACKAGE_PIN R2 [get_ports SW1]

set_property PACKAGE_PIN T1 [get_ports M_EN]

set_property PACKAGE_PIN U18 [get_ports KEY1]

set_property PACKAGE_PIN T1 [get_ports M_EN]

set_property PACKAGE_PIN U18 [get_ports KEY1]

2. Simulation waveform and analysis

SW1 is the enable terminal, M_SET is the set modulus value, R_SET is the reset signal, LED_OUT is the counter output, cnt_count is the counting sequence, clk1 is the clock signal, and SET is the switch for modulus value change

Take the above waveform as an example for analysis

(1) Verification of the enable terminal:

In the first 10ns, the enable terminal is low level, invalid, and the counter does not count. After the enable terminal is at a high level: when the modulus value is 2, every second clock signal LED_OUT generates an output signal.

(2) Verification of the reset function

The experiment requires R_SET to be cleared asynchronously, as shown in the blue line in the figure, when the R_SET signal is 0, the counter 

The value is immediately cleared to zero.

(3) Verification of modulus transformation

Observation shows that the transformation of the modulus value has been realized here. After the SET key is valid, the counter also re-counts with the new modulus value.

After asynchronous clearing, the modulus value becomes 9. When the ninth clock signal arrives, LED_OUT generates an output signal, and the modulo value of the counter continues to change later, and LED_OUT generates an output signal correspondingly.

Waveform simulation can observe the functions of reset, enable, modulo value carry output and set modulo value, so the function of any modulo value counter is realized.

3. Download test results and analysis

The first two digits of the digital tube represent the modulus value, and the last two digits represent the count

The modulus value can be set from 1 to 15, which is set by the four button switches in the lower right corner. The led light pointed by L1 represents the output signal, and it will light up once every time the counting is completed.

The following are the running photos of the development board when the modulus is 12 and 15

(1) The critical situation when the modulus is 12 and the count is 11 (2) When the modulus is 15 

 

analyze:

When the modulus value is 12 and the count value is 11, the led light is on, indicating that a count with a modulus value of 12 is over

When the modulus value is 15 and the count value is 14, the led light is on, and a count with the modulus value of 15 ends.

In summary, it can be seen that the download test phenomenon is consistent with the simulation.

5. Experimental experience

1. Solve the difficulties encountered in the experiment and solve them

(1) The jump of the output signal out at the moment when the count reaches the maximum modulus value is not at the maximum value, but becomes 1 when the counter value returns to 0, that is, the jump time is one clock signal later than the counter. 

Solution: Change a judgment condition in the counter module program of the code file. The original program is written so that as long as the value of the counter is equal to the modulus value, out will output 1, but the result of this judgment condition seems to be displayed only at the next clock signal. So this part of the program is changed, when the counter value is equal to the modulus value, it is judged that a valid result is established, and the out output is 1 immediately. It is found that after changing the code , out can successfully jump at the maximum value .

(2) Why frequency division is required?

This request was put forward when I saw the experimental request, and I was full of doubts at the time, why should frequency division be carried out, and what are the benefits of frequency division? After consulting the information, I learned that the frequency division is to divide the original frequency by the frequency division value to obtain the current frequency. Simply speaking, it is to reduce the frequency by integer multiples. After the frequency division, the input speed can be reduced, otherwise the oscillation frequency is too high, the duration of the signal is too short, and the device cannot respond normally. Moreover, the frequency requirements of some peripheral devices are different, and if there is no frequency division circuit, it cannot be controlled. A certain frequency division can also shorten the simulation time and improve the experimental efficiency.

2. The experience after completing the experiment

In the process of completing this experiment, I encountered some problems and challenges, but through continuous trial and debugging, I finally successfully completed the entire experiment.

I think it is very important to fully understand how the counter works to complete this experiment . When conducting counter experiments, it is necessary to fully understand the working principle of the counter so that appropriate parameter settings and designs can be performed as required. At the beginning, I didn't understand the teacher's requirements , and then I realized that the two digits on the left represent the modulus value and the two digits on the right represent the counting process on the digital tube . But after many times of code debugging, the acceptance of the experiment has been completed .

In general, the modular variable counter design experiment is a very meaningful and useful design practice project. In this experiment, we can learn a lot of basic knowledge of digital circuit design, and at the same time improve our problem solving and thinking ability. At the same time, we also need patience and perseverance. Through continuous debugging and optimization, we will finally complete a stable and reliable counter design !

 

Guess you like

Origin blog.csdn.net/m0_64198455/article/details/131527545