• FPGA-出租车计价器的实现


    说明:

    本实验是njupt课程设计出租车计价器,只供参考。
    输入时钟是50MHz。
    只使用了一个IP核,在频率计电路中的clk_gen,是输出为100MHz的PLL IP核

    一、课题要求

    1. 车轮转速用输入信号代替,一个信号周期是两米
    2. 3KM之内是起步价,固定九元
    3. 3KM之后如果速度高于1Hz,每公里2元计算,小于0.1元不计费
    4. 3KM之后如果速度低于1Hz,每10s0.1元,小于10s不计费
    5. 显示电路计价范围为000.0~999.9
    6. 按下启动键后,启动灯亮,再次按下启动键,启动灯不亮,显示最终车费
    7. 再次按下,回到初始状态

    二、代码设计

    1. 3KM判断电路

    //
    //  
    //  author : HY_Zhang
    //  name : Three_KM_judge
    //  data : 2022/10/26
    //  clk : 50MHz 
    //  IP : NONE
    //  function : Determine whether the travel is up to 3km
    // 
    //
    
    module Three_KM_judge
    #(
        parameter           TRAVEL_3KM = 11'd1500
    )
    (
        input wire          sys_clk,
        input wire          clk_test,
        input wire          sys_rst_n,
        input wire [1:0]    cstate,
        
        output reg          Three_KM_flag
    );
        reg [10:0]          cnt_Three_KM;      
    
        /*3km计数器,检测接收到的信号上升沿,计数1500次*/
        always @(posedge clk_test or negedge sys_rst_n)
        if(!sys_rst_n)
            cnt_Three_KM <= 1'b0;
        else if(cnt_Three_KM == TRAVEL_3KM || cstate == 2'b00 || cstate == 2'b10)
            cnt_Three_KM <= 1'b0;
        else if(cstate == 2'b01)
            cnt_Three_KM <= cnt_Three_KM + 1'b1;
    
        /*3km标志信号,达到3km发送一个时钟周期的脉冲*/
        always @(posedge sys_clk or negedge sys_rst_n)
        if(!sys_rst_n)
            Three_KM_flag <= 1'b0;
        else if(cnt_Three_KM == TRAVEL_3KM)
            Three_KM_flag <= 1'b1;
        else if(cstate == 2'b00)
            Three_KM_flag <= 1'b0;
        else 
            Three_KM_flag <= Three_KM_flag;
    
    endmodule 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46

    2. 慢速判断电路

    ///
    //
    //  author : HY_Zhang
    //  name : Speed_Slow_judge
    //  date : 2022/10/26
    //  clk : 50MHz
    //  IP : NONE
    //  function : Determine if the speed has reached a slow speed.
    //  slow speed : 12m/min
    // 
    /// 
    
    module Speed_Slow_judge
    #(
        parameter           SLOW_SPEED = 1
    )
    (
        input wire          sys_clk,
        input wire          sys_rst_n,
        input wire [33:0]   freq,
        input wire [1:0]    cstate,
    
        output reg          Slow_speed_flag 
    );
        /*判断速度是否小于阈值*/
        always @(posedge sys_clk or negedge sys_rst_n)
        if(!sys_rst_n)
            Slow_speed_flag <= 1'b0;
        else if(freq <= SLOW_SPEED)
            Slow_speed_flag <= 1'b1;
        else
            Slow_speed_flag <= 1'b0;
    
    endmodule 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34

    3. 频率计

    
    // 
    //  author : HY_Zhang
    //  name : Speed_meter
    //  date : 2022/10/26
    //  clk : 50MHz
    //  IP : PLL -> 100MHz
    //  function : To calculate the speed.
    //
    
    
    module Speed_meter
    #(
    	parameter           CNT_RISE_MAX=28'd12_499_999,
    	parameter           CNT_GATE_S_MAX=28'd74_999_999,
    	parameter           CLK_STAND_FREQ=28'd100_000_000
    )   
    (   
    	input wire          clk,
    	input wire          rst_n,
    	input wire          clk_test,
    	
    	output reg [33:0]   freq
    );
    
    	reg [27:0]          cnt_gate_s;
    	reg                 gate_s;
    	reg                 gate_a;
    	reg                 gate_a_stand;
    	wire                gate_a_fall_s;
    	reg [47:0]          cnt_clk_stand;
    	reg [47:0]          cnt_clk_stand_reg;
    	reg                 gate_a_test;
    	wire                gate_a_fall_t;
    	reg [47:0]          cnt_clk_test;
    	reg [47:0]          cnt_clk_test_reg;
    	reg                 calc_flag;
    	reg [63:0]          freq_reg;
    	reg                 calc_flag_reg;
    	
    	wire                clk_stand; 
    
        //标准时钟设为100MHz
    	clk_gen clk_gen_inst(
    		.areset(~rst_n),
    		.inclk0(clk),
    		.c0(clk_stand)
    	);
    	
    	//闸门计数器
    	always @(posedge clk or negedge rst_n)
    	if(!rst_n)
    		cnt_gate_s<=1'b0;
    	else if(cnt_gate_s==CNT_GATE_S_MAX)
    		cnt_gate_s<=1'b0;
    	else 
    		cnt_gate_s<=cnt_gate_s+1'b1;
    		
    	//闸门控制,
    	always @(posedge clk or negedge rst_n)
    	if(!rst_n)
    		gate_s<=1'b0;
    	else if((cnt_gate_s>=CNT_RISE_MAX) && cnt_gate_s<=(CNT_GATE_S_MAX-CNT_RISE_MAX))
    		gate_s<=1'b1;
    	else 
    		gate_s<=1'b0;
    		
    	//将闸门打一拍,与时钟同步
    	always @(posedge clk or negedge rst_n)
    	if(!rst_n)
    		gate_a<=1'b0;
    	else 
    		gate_a<=gate_s;
    		
    	//将标准时钟闸门再打一拍,以便生成标志信号gate_a_fall_s
    	always @(posedge clk_stand or negedge rst_n)
    	if(!rst_n)
    		gate_a_stand<=1'b0;
    	else 
    		gate_a_stand<=gate_a;
    		
    	//标准频率计数截止信号
    	assign gate_a_fall_s=(gate_a_stand && !gate_a) ? 1'b1:1'b0;
    
    	//标准时钟频率计数器
    	always @(posedge clk_stand or negedge rst_n)
    	if(!rst_n)
    		cnt_clk_stand<=1'b0;
    	else if(!gate_a)
    		cnt_clk_stand<=1'b0;
    	else if(gate_a)
    		cnt_clk_stand<=cnt_clk_stand+1'b1;
    
    	//标准时钟频率周期个数寄存器
    	always @(posedge clk_stand or negedge rst_n)
    	if(!rst_n)
    		cnt_clk_stand_reg<=1'b0;
    	else if(gate_a_fall_s)
    		cnt_clk_stand_reg<=cnt_clk_stand;
    		
    	//将待测时钟打一拍,以便生成gate_a_fall_t
    	always @(posedge clk_test or negedge rst_n)
    	if(!rst_n)
    		gate_a_test<=1'b0;
    	else 
    		gate_a_test<=gate_a;
    	
    	//待测时钟计数截止信号
    	assign gate_a_fall_t=(gate_a_test && !gate_a) ? 1'b1:1'b0;
    		
    	//待测时钟频率计数器
    	always @(posedge clk_test or negedge rst_n)
    	if(!rst_n)
    		cnt_clk_test<=1'b0;
    	else if(!gate_a)
    		cnt_clk_test<=1'b0;
    	else if(gate_a)
    		cnt_clk_test<=cnt_clk_test+1'b1;
    		
    	//待测时钟频率周期个数寄存器
    	always @(posedge clk_test or negedge rst_n)
    	if(!rst_n)
    		cnt_clk_test_reg<=1'b0;
    	else if(gate_a_fall_t)
    		cnt_clk_test_reg<=cnt_clk_test;
    		
    	//频率计算标志信号
    	always @(posedge clk or negedge rst_n)
    	if(!rst_n)
    		calc_flag<=1'b0;
    	else if(cnt_gate_s==CNT_GATE_S_MAX)
    		calc_flag<=1'b1;
    	else
    		calc_flag<=1'b0;
    		
    	//待测时钟频率计算
    	always @(posedge clk or negedge rst_n)
    	if(!rst_n)
    		freq_reg<=1'b0;
    	else if(calc_flag)
    		freq_reg<=(CLK_STAND_FREQ*cnt_clk_test_reg/cnt_clk_stand_reg);
    		
    	//将计算标志信号打一拍,不然freq输出的是计算之前的值
    	always @(posedge clk or negedge rst_n)
    	if(!rst_n)
    		calc_flag_reg<=1'b0;
    	else 
    		calc_flag_reg<=calc_flag;
    		
    	//频率值输出
    	always @(posedge clk or negedge rst_n)
    	if(!rst_n)
    		freq<=1'b0;
    	else if(calc_flag_reg)
    		freq<=freq_reg[33:0];
    	
    
    endmodule 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158

    4. LED控制电路

    ///
    // 
    //  author : HY_Zhang
    //  name : LED
    //  date : 2022/10/27
    //  clk : 50MHz
    //  IP : NONE 
    //  function : Control LED
    // 
    ///
    
    module LED
    (
        input wire          sys_clk,
        input wire          sys_rst_n,
        input wire [1:0]    cstate,
    
        output reg          LED_out
    );
        always @(posedge sys_clk or negedge sys_rst_n)
        if(!sys_rst_n)
            LED_out <= 1'b0;
        else if(cstate == 2'b00 || cstate == 2'b10)
            LED_out <= 1'b0;
        else if(cstate == 2'b01)
            LED_out <= 1'b1;
        else 
            LED_out <= LED_out;
    
    endmodule 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    5.计费电路

    //
    // 
    //  author : HY_Zhang
    //  name : Cost
    //  date : 2022/10/26
    //  clk : 50MHz
    //  IP : NONE
    //  function : Accumulate the fare
    // 
    //
    
    module Cost
    #(
        parameter           Cost_0_1 = 1,
        parameter           CNT_25_MAX = 5'd25,
        parameter           COST_ACC_MAX = 14'd9909,
        parameter           CNT_10S_MAX = 29'd500_000_000
    )
    (
        input wire          sys_clk,
        input wire          sys_rst_n,
        input wire          clk_test,
        input wire          Three_KM_flag,
        input wire          Slow_speed_flag,
        input wire [1:0]    cstate,
        
        output reg [15:0]   Cost_out
    );
        reg [15:0]          Cost_out_reg;
    
        reg                 cstate_t;
        reg                 cstate_po;
    
        reg                 clk_test_t;
        reg                 clk_test_po;
    
        reg [3:0]           Cost_acc_unit;
        reg [3:0]           Cost_acc_ten;
        reg [3:0]           Cost_acc_hun;
        reg [3:0]           Cost_acc_tho;
    
        reg [4:0]           CNT_25;              //一分钱走25圈
    
        reg [28:0]          cnt_10s;             //记十秒
    
        always @(posedge sys_clk or negedge sys_rst_n)
        if(!sys_rst_n)
            clk_test_t <= 1'b0;
        else 
            clk_test_t <= clk_test;
    
        always @(posedge sys_clk or negedge sys_rst_n)
        if(!sys_rst_n)
            clk_test_po <= 1'b0;
        else if(clk_test && !clk_test_t)
            clk_test_po <= 1'b1;
        else
            clk_test_po <= 1'b0;
    
        always @(posedge clk_test or negedge sys_rst_n)
        if(!sys_rst_n)
            cstate_t <= 1'b0;
        else
            cstate_t <= cstate[0];
    
        always @(posedge clk_test or negedge sys_rst_n)
        if(!sys_rst_n)
            cstate_po <= 1'b0;
        else if(cstate[0] && !cstate_t)
            cstate_po <= 1'b1;
        else 
            cstate_po <= 1'b0;
    
        always @(posedge sys_clk or negedge sys_rst_n)
        if(!sys_rst_n)
            cnt_10s <= 29'd0;
        else if(cnt_10s == CNT_10S_MAX && Slow_speed_flag && cstate == 2'b01 && Three_KM_flag)
            cnt_10s <= 29'd0;
        else if(Slow_speed_flag && cstate == 2'b01 && Three_KM_flag)
            cnt_10s <= cnt_10s + 1'b1;
    
        always @(posedge clk_test or negedge sys_rst_n)
        if(!sys_rst_n)
            CNT_25 <= 5'd0;
        else if(CNT_25 == CNT_25_MAX && cstate == 2'b01 && !Slow_speed_flag && Three_KM_flag)
            CNT_25 <= 5'd0;
        else if(cstate == 2'b01 && !Slow_speed_flag && Three_KM_flag)
            CNT_25 <= CNT_25 + 1'b1;
    
    
    
        /*三公里后的车费累加*/
    
        always @(posedge sys_clk or negedge sys_rst_n)
        if(!sys_rst_n)
            Cost_acc_unit <= 4'd0;
        else if(cstate == 2'b00)
            Cost_acc_unit <= 4'd0;
        else if(!Slow_speed_flag && Three_KM_flag && cstate == 2'b01)begin
            if(Cost_acc_unit == 4'd9 && CNT_25 == CNT_25_MAX && clk_test_po)
                Cost_acc_unit <= 4'd0;
            else if(CNT_25 == CNT_25_MAX && clk_test_po)
                Cost_acc_unit <= Cost_acc_unit + 1'b1;
        end
        else if(Slow_speed_flag && Three_KM_flag && cstate == 2'b01)begin
            if(Cost_acc_unit == 4'd9 && cnt_10s == CNT_10S_MAX)
                Cost_acc_unit <= 4'd0;
            else if(cnt_10s == CNT_10S_MAX)
                Cost_acc_unit <= Cost_acc_unit + 1'b1;
        end
        else if(cstate == 2'b10)
            Cost_acc_unit <= Cost_acc_unit;
    
    
    
        always @(posedge sys_clk or negedge sys_rst_n)
        if(!sys_rst_n)
            Cost_acc_ten <= 4'd0;
        else if(cstate_po)
            Cost_acc_ten <= 4'd9;
        else if(cstate == 2'b00)
            Cost_acc_ten <= 4'd0;
        else if(!Slow_speed_flag && Three_KM_flag && cstate == 2'b01)begin
            if(Cost_acc_ten == 4'd9 && Cost_acc_unit == 4'd9 && CNT_25 == CNT_25_MAX && clk_test_po)
                Cost_acc_ten <= 4'd0;
            else if(CNT_25 == CNT_25_MAX && Cost_acc_unit == 4'd9 && clk_test_po)
                Cost_acc_ten <= Cost_acc_ten + 1'b1;
        end
        else if(Slow_speed_flag && Three_KM_flag && cstate == 2'b01)begin
            if(Cost_acc_ten == 4'd9 && Cost_acc_unit == 4'd9 && cnt_10s == CNT_10S_MAX)
                Cost_acc_ten <= 4'd0;
            else if(cnt_10s == CNT_10S_MAX && Cost_acc_unit == 4'd9)
                Cost_acc_ten <= Cost_acc_ten + 1'b1;
        end
        else if(cstate == 2'b10)
            Cost_acc_ten <= Cost_acc_ten;
        
    
        always @(posedge sys_clk or negedge sys_rst_n)
        if(!sys_rst_n)
            Cost_acc_hun <= 4'd0;
        else if(cstate == 2'b00)
            Cost_acc_hun <= 4'd0;
        else if(!Slow_speed_flag && Three_KM_flag && cstate == 2'b01)begin
            if(Cost_acc_hun == 4'd9 && Cost_acc_ten == 4'd9 && Cost_acc_unit == 4'd9 && CNT_25 == CNT_25_MAX && clk_test_po)
                Cost_acc_hun <= 4'd0;
            else if(CNT_25 == CNT_25_MAX && Cost_acc_unit == 4'd9 && Cost_acc_ten == 4'd9 && clk_test_po)
                Cost_acc_hun <= Cost_acc_hun + 1'b1;
        end
        else if(Slow_speed_flag && Three_KM_flag && cstate == 2'b01)begin
            if(Cost_acc_hun == 4'd9 && Cost_acc_ten == 4'd9 && Cost_acc_unit == 4'd9 && cnt_10s == CNT_10S_MAX)
                Cost_acc_hun <= 4'd0;
            else if(cnt_10s == CNT_10S_MAX && Cost_acc_unit == 4'd9 && Cost_acc_ten == 4'd9 && cnt_10s == CNT_10S_MAX)
                Cost_acc_hun <= Cost_acc_hun + 1'b1;
        end
        else if(cstate == 2'b10)
            Cost_acc_hun <= Cost_acc_hun;
        
    
        always @(posedge sys_clk or negedge sys_rst_n)
        if(!sys_rst_n)
            Cost_acc_tho <= 4'd0;
        else if(cstate == 2'b00)
            Cost_acc_tho <= 4'd0;
        else if(!Slow_speed_flag && Three_KM_flag && cstate == 2'b01)begin
            if(Cost_acc_tho == 4'd9 && Cost_acc_hun == 4'd9 && Cost_acc_ten == 4'd9 && Cost_acc_unit == 4'd9 && CNT_25 == CNT_25_MAX && clk_test_po)
                Cost_acc_tho <= 4'd0;
            else if(CNT_25 == CNT_25_MAX && Cost_acc_unit == 4'd9 && Cost_acc_ten == 4'd9 && Cost_acc_hun == 4'd9 && clk_test_po)
                Cost_acc_tho <= Cost_acc_tho + 1'b1;
        end
        else if(Slow_speed_flag && Three_KM_flag && cstate == 2'b01)begin
            if(Cost_acc_tho == 4'd9 && Cost_acc_ten == 4'd9 && Cost_acc_unit == 4'd9 && cnt_10s == CNT_10S_MAX && Cost_acc_hun == 4'd9)
                Cost_acc_tho <= 4'd0;
            else if(cnt_10s == CNT_10S_MAX && Cost_acc_unit == 4'd9 && Cost_acc_ten == 4'd9 && cnt_10s == CNT_10S_MAX && Cost_acc_hun == 4'd9)
                Cost_acc_tho <= Cost_acc_tho + 1'b1;
        end
        else if(cstate == 2'b10)
            Cost_acc_tho <= Cost_acc_tho;
        
    
        /*总车费计算*/
        always @(posedge sys_clk or negedge sys_rst_n)
        if(!sys_rst_n)
            Cost_out_reg <= 14'd0;
        else
            Cost_out_reg <= {Cost_acc_tho,Cost_acc_hun,Cost_acc_ten,Cost_acc_unit};
    
        always @(posedge sys_clk or negedge sys_rst_n)
        if(!sys_rst_n)
            Cost_out <= 14'd0;
        else 
            Cost_out <= Cost_out_reg;
    
    endmodule 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177
    • 178
    • 179
    • 180
    • 181
    • 182
    • 183
    • 184
    • 185
    • 186
    • 187
    • 188
    • 189
    • 190
    • 191
    • 192
    • 193
    • 194

    6.数码管显示电路

    
    // 
    //  author : HY_Zhang
    //  name : Seg
    //  date : 2022/10/27
    //  clk : 50MHz
    //  IP : NONE
    //  function : Digital tube display circuit
    // 
     
    
    module Seg
    (
    	input wire 			clk,
    	input wire 			rst_n,
    	input wire [15:0]	disp_data,
    	input wire 			en,
    	input wire [5:0]	point,
    	
    	output reg[7:0]		seg,
    	output wire[3:0]	sel
    );
    
    	reg [14:0]divder_cnt;
    	
    	reg clk_1K;
    	
    	reg [3:0]sel_r;
    	reg [1:0]cnt_sel;
    	
    	//待显示数据缓存
    	reg [3:0]data_tmp;
    
    	reg dot_disp;
    	
    	parameter disp0=8'b1100_0000;
    	parameter disp1=8'b1111_1001;
    	parameter disp2=8'b1010_0100;
    	parameter disp3=8'b1011_0000;
    	parameter disp4=8'b1001_1001;
    	parameter disp5=8'b1001_0010;
    	parameter disp6=8'b1000_0010;
    	parameter disp7=8'b1111_1000;
    	parameter disp8=8'b1000_0000;
    	parameter disp9=8'b1001_0000;
    	parameter dispa=8'b1000_1000;
    	parameter dispb=8'b1000_0011;
    	parameter dispc=8'b1010_0111;
    	parameter dispd=8'b1010_0001;
    	parameter dispe=8'b1000_0110;
    	parameter dispf=8'b1000_0011;
    
    	
    	//分频计数器
    	always @(posedge clk or negedge rst_n)
    	if(!rst_n)
    		divder_cnt<=15'd0;
    	else if(!en)
    		divder_cnt<=15'd0;
    	else if(divder_cnt==15'd24999)
    		divder_cnt<=15'd0;
    	else
    		divder_cnt<=divder_cnt+15'd1;
    		
    		
    	//1KHz时钟产生模块
    	always @(posedge clk or negedge rst_n)
    	if(!rst_n)
    		clk_1K<=1'b0;
    	else if(divder_cnt==15'd24999)
    		clk_1K<=~clk_1K;
    	else 
    		clk_1K<=clk_1K;
    		
    	//6位循环移位寄存器
    	always @(posedge clk_1K or negedge rst_n)
    	if(!rst_n)
    		sel_r<=4'b0001;
    	else if(sel_r==4'b1000)
    		sel_r<=4'b0001;
    	else 
    		sel_r<=sel_r<<1;
    
    	always @(posedge clk_1K or negedge rst_n)
    	if(!rst_n)
    		cnt_sel <= 1'b0;
    	else if(cnt_sel == 2'b11)
    		cnt_sel <= 1'b0;
    	else 
    		cnt_sel <= cnt_sel + 1'b1;
    
    	always @(posedge clk_1K or negedge rst_n)
    	if(!rst_n)
    		dot_disp <= 1'b1;
    	else 
    		dot_disp <= ~point[cnt_sel];
    
    	always @(*)
    		seg[7] = dot_disp;
    
    	//六选一多路器
    	always @(*)
    		case(sel_r)
    			4'b0001:data_tmp=disp_data[3:0];
    			4'b0010:data_tmp=disp_data[7:4];
    			4'b0100:data_tmp=disp_data[11:8];
    			4'b1000:data_tmp=disp_data[15:12];
    			default:data_tmp=4'b0000;
    		endcase
    	
    	always@(*)
    		case(data_tmp)
    			4'h0:seg[6:0]=7'b100_0000;
    			4'h1:seg[6:0]=7'b111_1001;
    			4'h2:seg[6:0]=7'b010_0100;
    			4'h3:seg[6:0]=7'b011_0000;
    			4'h4:seg[6:0]=7'b001_1001;
    			4'h5:seg[6:0]=7'b001_0010;
    			4'h6:seg[6:0]=7'b000_0010;
    			4'h7:seg[6:0]=7'b111_1000;
    			4'h8:seg[6:0]=7'b000_0000;
    			4'h9:seg[6:0]=7'b001_0000;
    			4'ha:seg[6:0]=7'b000_1000;
    			4'hb:seg[6:0]=7'b000_0011;
    			4'hc:seg[6:0]=7'b100_0110;
    			4'hd:seg[6:0]=7'b010_0001;
    			4'he:seg[6:0]=7'b000_0110;
    			4'hf:seg[6:0]=7'b111_1111;
    			
    		endcase
    		
    		assign sel=~sel_r;
    		
    endmodule 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134

    8.控制电路

    /
    // 
    //  author : HY_Zhang
    //  name : Control
    //  date : 2022/10/27
    //  clk : 50MHz
    //  IP : NONE
    //  function : Controller circuit and key filter
    // 
    / 
    
    module Control
    #(
        parameter           CNT_MAX = 20'd999_999
    )
    (
        input wire          sys_clk,
        input wire          sys_rst_n,
        input wire          key_in,
        input wire          clk_test,
    
        output wire[7:0]    seg,
        output wire         LED_out,
        output wire[3:0]	sel
    );
    
        parameter           STOP = 2'b00,
                            WORK = 2'b01,
                            DISPLAY = 2'b10;
    
        reg [19:0]          cnt_20;
    
        reg                 key_flag;
    
        reg [1:0]           cstate;
        reg [1:0]           nstate;
    
        wire [33:0]         freq;
    
        wire                Three_KM_flag;
    
        wire                Slow_speed_flag;
    
        wire [15:0]         Cost_out;
    
    
        always @(posedge sys_clk or negedge sys_rst_n)
        if(!sys_rst_n)
            cstate <= STOP;
        else 
            cstate <= nstate;
    
        always @(*)
            case (cstate)
                STOP :
                    if(key_flag)
                        nstate <= WORK;
                    else
                        nstate <= STOP;
                WORK : 
                    if(key_flag)
                        nstate <= DISPLAY;
                    else
                        nstate <= WORK;
                DISPLAY :
                    if(key_flag)
                        nstate <= STOP;
                    else
                        nstate <= DISPLAY;
            endcase
    
    	always @(posedge sys_clk or negedge sys_rst_n)
    	if(!sys_rst_n)
    		cnt_20<=1'b0;
    	else if(key_in==1'b1)
    		cnt_20<=1'b0;
    	else if(cnt_20==CNT_MAX &&  key_in==1'b0)
    		cnt_20<=cnt_20;
    	else
    		cnt_20<=cnt_20+1'b1;
    		
    	always @(posedge sys_clk or negedge sys_rst_n)
    	if(!sys_rst_n)
    		key_flag<=1'b0;
    	else if(cnt_20==CNT_MAX-1'b1)
    		key_flag<=1'b1;
    	else 
    		key_flag<=1'b0;
    
        LED
        LED_inst(
            .sys_clk        (sys_clk),
            .sys_rst_n      (sys_rst_n),
            .cstate         (cstate),
    
            .LED_out        (LED_out)
        );
    
        Speed_meter
        #(
            .CNT_RISE_MAX(28'd12_499_999),
            .CNT_GATE_S_MAX(28'd74_999_999),
            .CLK_STAND_FREQ(28'd100_000_000)
        )   
        Speed_meter_inst(   
            .clk            (sys_clk),
            .rst_n          (sys_rst_n),
            .clk_test       (clk_test),
        
            .freq           (freq)
        );
    
        Three_KM_judge
        #(
            .TRAVEL_3KM ( 11'd1500)
        )
        Three_KM_judge_inst(
            .sys_clk        (sys_clk),
            .clk_test       (clk_test),
            .sys_rst_n      (sys_rst_n),
            .cstate         (cstate),
            
            .Three_KM_flag  (Three_KM_flag)
        );
    
        Speed_Slow_judge
        #(
            .SLOW_SPEED (1)
        )
        Speed_Slow_judge_inst(
            .sys_clk            (sys_clk),
            .sys_rst_n          (sys_rst_n),
            .freq               (freq),
    
            .Slow_speed_flag    (Slow_speed_flag)
        );
    
        Cost
        #(
            .Cost_0_1 ( 1),
            .CNT_25_MAX (5'd25),
            .COST_ACC_MAX (14'd9909),
            .CNT_10S_MAX (29'd500_000_000)
        )
        Cost_inst(
            .sys_clk            (sys_clk),
            .sys_rst_n          (sys_rst_n),
            .clk_test           (clk_test),
            .Three_KM_flag      (Three_KM_flag),
            .Slow_speed_flag    (Slow_speed_flag),
            .cstate             (cstate),
            
            .Cost_out           (Cost_out)
        );
    
        Seg
        Seg_inst(
            .clk                (sys_clk),
            .rst_n              (sys_rst_n),
            .disp_data          (Cost_out),
            .en                 (1'b1),
            .point              (4'b0001),
            
            .seg                (seg),
            .sel                (sel)
        );
    
    endmodule 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168

    三、仿真激励测试文件

    `timescale 1ns/1ns
    `define clk_period 20
    `define clk_period_1 1_000
    
    module Control_tb;
    
        reg          sys_clk;
        reg          sys_rst_n;
        reg          key_in;
        reg          clk_test;
    
        wire  [7:0]       seg;
        wire  [3:0]	     sel;
    
        initial sys_clk = 1'b1;
        always #(`clk_period/2) sys_clk = ~sys_clk;
    
        initial clk_test = 1'b1;
        always #(`clk_period_1/2) clk_test = ~clk_test;
    
        initial begin
            sys_rst_n = 1'b0;
            key_in = 1'b1;
            #25;
            sys_rst_n = 1'b1;
            #2000;
            key_in = 1'b0;
            #10000;
            key_in = 1'b1;
            #10000000;
            key_in = 1'b0;
            #50000;
            key_in = 1'b1;
            #10000000;
            key_in = 1'b0;
            #50000;
            key_in = 1'b1;
    
        end
    
        defparam Control_inst.Speed_meter_inst.CNT_GATE_S_MAX = 240;
        defparam Control_inst.Speed_meter_inst.CNT_RISE_MAX = 40;
        defparam Control_inst.Cost_inst.CNT_10S_MAX = 500;
        defparam Control_inst.Speed_Slow_judge_inst.SLOW_SPEED = 200_000_0; //正常速度用这个
        //defparam Control_inst.Speed_Slow_judge_inst.SLOW_SPEED = 200;     //慢速行驶用这个
    
        Control
        #(
            .CNT_MAX (20'd9)
        )
        Control_inst(
            .sys_clk        (sys_clk),
            .sys_rst_n      (sys_rst_n),
            .key_in         (key_in),
            .clk_test       (clk_test),
    
            .seg            (seg),
            .sel            (sel)
        );
    
    
    
    endmodule 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63

    四、仿真波形图

    1. 慢速行驶

    在这里插入图片描述

    1. 正常行驶

    在这里插入图片描述

    注:

    已上板验证过,感兴趣的可以私聊我看看效果

  • 相关阅读:
    【23种设计模式】接口隔离原则
    oracle数据库事务的四大特性与隔离级别与游标
    Spire.Office for Java 8.9.5/Spire.Office 8.9.2 .NET
    JS——经典案例
    如何提高系统的可用性/高可用
    【AntDesign】多环境配置和启动
    使用debezium、kafka-connect将postgres数据实时同步到kafka中
    IBM Spectrum LSF Application Center 以应用程序为中心的工作负载提交和管理
    【机器学习】随机森林
    Centos生命周期,Centos和Centos Stream区别
  • 原文地址:https://blog.csdn.net/qq_52450571/article/details/127586066