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 

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 

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 

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 

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 

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 

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 

三、仿真激励测试文件

`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. 慢速行驶

在这里插入图片描述

  1. 正常行驶

在这里插入图片描述

注:

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

  • 22
    点赞
  • 79
    收藏
    觉得还不错? 一键收藏
  • 8
    评论
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值