学校FPGA设计结课课设
主要做了出租车计价表,一个比较旧的课题,代码如下:
1.基本代码
分模块编程,按照价目表写代码,具体注释见代码。
module taxi_cost(
input clk,
input rst,
input key_start,
input key_clear,
output reg[3:0] en_seg,
output reg[7:0] sseg
);
reg[0:0] start_flag; //是否开始计费 1为开始计费,0停止计费
reg[1:0] cost_stage; //费用阶段,0 - 2km以内,5元;
// 2 - 10km,每千米2元
// 10km以外,每千米3元
reg[9:0] distance; //行驶的总距离,用于判断在哪个费用阶段
reg[9:0] cost; //计算总费用
reg[6:0] counter; //计算次数
/*
状态初始化,起步价为5元
*/
initial begin
start_flag = 0; //开始标志位清0
cost_stage = 0; //初始化为第一阶段 0-2km以内费用5元
cost = 9'd5; //初始费用5元
distance = 0; //初始距离为0km
counter = 0;
end
always @(key_start) //判断开始计费按键是否按下
if(key_start)
start_flag = 1;
else
start_flag = 0;
always @(key_clear)begin //如果清0按键按下,回到初始状态
cost_stage = 0;
cost = 9'd5;
distance = 0;
counter = 0;
start_flag = 0;
end
/*
路程计算
假设出租车的车速为36km/h,即10m/s
使用的输入时钟为100MHz,则每一周期为1ns,需要计算1_000_000_000才为1s
故定义一个位宽为30的变量M(M的范围为0-2^30,即0-1073741824),每次自加1
当加到1_000_000_000时,counter加1,加到100时,获得10*100 = 1000m = 1km
(仿真时为了更快得出结果,M和counter的数字适当变小)
*/
localparam M = 30;
reg[M-1:0] regM;
always @(posedge clk,posedge rst)
if(rst)
regM <= 0;
else
if(start_flag)
regM <= regM + 1;
always @* begin
if(regM > 'd1_000_000_000)begin // 1s。regM清零,counter加1
counter = counter + 1;
regM = 0;
if(counter == 100) begin //达到1km,路程加1km
distance = distance + 1;
counter = 0;
case(cost_stage) //根据阶段计费
2'b00:begin
cost = 'd5; //第一阶段 保持5元
end
2'b01:begin //第二阶段,每增加1km价格加2元
cost = cost + 'd2;
end
2'b10:begin //第三阶段,每增加1km价格加3元
cost = cost + 'd3;
end
endcase
end
end
end
always @(distance) begin //判断阶段
if(distance > 'd2) begin
cost_stage = 1;
end
if(distance > 'd10) begin
cost_stage = 2;
end
end
/*
数码管显示
设置了sigle、ten、hundred三个变量,每个变量都是4位(范围0-16,实际只用了0-9)
为了营造四个数码管同时点亮的视觉效果,对数码管的片选时间定为1000Hz即可
输入时钟为100MHz,故只要2^17分频即可获得约800Hz,再增加两位用于溢出判断是哪一位被选中
*/
reg [3:0] sigle;
reg [3:0] ten;
reg [3:0] hundred;
localparam N = 17;
reg[N-1:0] regN;
always @(posedge clk,posedge rst)
if(rst)
regN <= 0;
else
if(start_flag)
regN <= regN + 1;
//用于计算每个位的数字
always @* begin
sigle = cost % 10;
ten = cost % 100 / 4'd10;
hundred = cost / 100;
end
//数码管显示
always @*
if(start_flag)
case(regN[N-1:N-2])
2'b00:begin
en_seg = 4'b1110;
sseg = tran_seg(sigle);
end
2'b01:begin
en_seg = 4'b1101;
sseg = tran_seg(ten);
end
2'b10:begin
en_seg = 4'b1011;
sseg = tran_seg(hundred);
end
2'b11:begin
en_seg = 4'b0111;
sseg = tran_seg(10);
end
endcase
//将10进制转换成2禁止,用于数码管输出,选择的是共阴数码管,被选中段为1即输出
function[7:0] tran_seg;
input[3:0] data;
begin
case(data)
4'd0:tran_seg = 8'b0111_1110; //0 -> 0x7e
4'd1:tran_seg = 8'b0011_0000; //1 -> 0x30
4'd2:tran_seg = 8'b0110_1101; //2 -> 0x6d
4'd3:tran_seg = 8'b0111_1001; //3 -> 0x79
4'd4:tran_seg = 8'b0011_0011; //4 -> 0x33
4'd5:tran_seg = 8'b0101_1011; //5 -> 0x5b
4'd6:tran_seg = 8'b0101_1111; //6 -> 0x5f
4'd7:tran_seg = 8'b0111_0000; //7 -> 0x70
4'd8:tran_seg = 8'b0111_1111; //8 -> 0x7f
4'd9:tran_seg = 8'b0111_1011; //9 -> 0x7b
default:tran_seg = 8'b0000_000; //熄灭
endcase
end
endfunction
endmodule
2.不同车流量段判断
在module里新加一个input
变量key_stage
,用key_stage
表示不同车流量段,用以计数文章来源:https://www.toymoban.com/news/detail-762126.html
always @* begin
if(regM > 'd100) begin //时间达到1s。regM清零,couner加1
counter = counter + 1;
regM = 0;
if(counter == 10) begin //达到1km,路程加1km
distance = distance + 1;
counter = 0;
case(cost_stage) //根据阶段计费
2'b00:begin
cost = 'd10; //第一阶段
end
2'b01:begin //第二阶段
if(key_stage)
cost = cost + 'd1;
else
cost = cost + 'd2;
end
2'b10:begin //第三阶段
if(key_stage)
cost = cost + 'd2;
else
cost = cost + 'd3;
end
endcase
end
end
end
3.夜晚白天判断
在module里新增一个变量state
来限定是在白天还是夜间文章来源地址https://www.toymoban.com/news/detail-762126.html
//判断收费阶段
always @(all_dist) begin
if(all_dist < 3) begin
cost_stage = STAGE_1;
end
if(all_dist > 3 & all_dist < 10) begin
cost_stage = STAGE_2;
end
if(all_dist > 10) begin
cost_stage = STAGE_3;
end
case (cost_stage) // 根据收费阶段计算费用
STAGE_1: begin
cost = cost;
end
STAGE_2: begin
if(state) cost = cost + 3;
else cost = cost + 2;
end
STAGE_3: begin
if(state) cost = cost + 4;
else cost = cost + 3;
end
endcase
end
到了这里,关于【Vivado】基于FPGA的出租车计价表设计的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!