//子模块control
`timescale 1ns / 1ps
module control(start,distance_enable,time_enable,select_clk);
input start,distance_enable,time_enable;
output select_clk;//榆出选择的时钟信号
wire select_clk;
assign select_clk= start?distance_enable:time_enable;//当start高电平的时候选择公里计费,输出的时钟信号为 distance_enable,当 start 低电平的时候选择时间计费,输出的时钟信号为 time_enable
endmodule//结束控制模块
//子模块jicheng
`timescale 1ns / 1ps
//记录里程数
module jicheng(clk,start,reset,distance,distance_enable); //端口的定义
input clk,start,reset;
output [7:0] distance;// 输出的公里
reg [7:0] distance;
output distance_enable;//控制计费的公里信号
reg distance_enable;
always@(posedge clk or negedge reset)//异步复位
begin
if(!reset)//低电平复位
begin
distance<=8'd0;
end
else if(start)// start 高电平有效
begin
if(distance[3:0]==9)//判断 distance 的低四位计到 了 9 没有
begin
distance[3:0]<=4'd0;//计到 9 清零
if (distance[7:4] ==9) //判断 di stance 的高四位计到了 9 没有
distance [7:4] <=4'd0;//计到9清零
else distance[7:4]<= distance[7:4]+1'd1;// distance 的高四位没有计到 9 的时候加一
end
else distance[3:0]<=distance[3:0]+1'd1;// distance 的低四位没有计到 9 的时候加一
end//end start
end//end always
//产生distance_enable 信号
always@(posedge clk or negedge reset)
begin
if (!reset)
begin
distance_enable<=1'd0; // 复位
end
else
if(distance>8'd2)//大于公里三的时候
begin
distance_enable<=1'd1;//输出 distance_enable 信号
end
end//end always
endmodule//结束计程模块
//子模块jishi
`timescale 1ns / 1ps
//记录时长
module jishi(clk,reset,start,s,m,time_enable) ;// 端口 的定义
input clk,reset,start;
output [7:0]s;//输出的秒
output [7:0]m;//输出的分
output time_enable;//揄出的控制计费的信号
reg [7:0] s;
reg [7:0] m;
wire time_enable;
always@(posedge clk or negedge reset)//异步复位
begin
if (!reset)//低电平有效
begin //复位
s<=8'd0;
m<=8'd0;
end
else if(!start)//start 信号低电平有效
begin
if (s[3:0]==9)//秒的低四位是 9
begin
s[3:0]<=4'd0;//清零
if(s[7:4]==5) //秒的高四位是 5
begin
s[7:4]<=4'd0;//清零
if(m[3:0]==9) //分的低四位是 9
begin
m[3:0]<=4'd0; //清零
if (m[7:4]==9) //分的高四位是 9
m[7:4]<=4'd0;//清零
else m[7:4]<=m[7:4]+1'd1; // 分的高四位不是 9 加一
end
else m[3:0]<=m[3:0]+1'd1;//分的低四位不是 9 加一
end
else s[7:4]<=s[7:4]+1'd1; // 秒的高四位不是 5 加一
end
else s[3:0]<=s[3:0]+1'd1;//秒的低四位不是 9 加一
end
end//end always
assign time_enable=((m[7:0]>8'd2)&&(s[7:0]==8'd0))?1'd1:1'd0;//产生 time_enabIe 信号。
endmodule//结束计时模块
//子模块cost
`timescale 1ns / 1ps
//计费
module cost(select_clk,reset,cost,clk);
input select_clk,reset,clk;
output [7:0] cost;//输出的费用
reg [7:0] cost;
always@(posedge clk or negedge reset)//异步复位
begin
if(!reset) //低电平有效
begin
cost<=8'd8;//起步为八元
end
else if (select_clk==1'd1)
begin
if(cost[3:0]==4'd9) //费用的低四位是不是计到了 9
begin
cost[3:0]<=4'd0;//计到 9 清零
if(cost[7:4]==4'd9)//费用的高四位是不是计到了 9
cost[7:4]<=4'd0; //计到 9 清零
else cost[7:4]<=cost[7:4]+1'd1;//费用的高四位没有计到 9 加 1
end
else cost[3:0]<=cost[3:0]+1'd1;//费用的低四位没有计到 9 加 1
end//end begin
end//end always
endmodule//结束计费模块
//子模块jishuqi
`timescale 1ns / 1ps
//计数器
module jishuqi(clk_50M,clk,reset);// 端口的定义
input clk_50M,reset;//总的时钟是50M
output clk;//分频后输出的时钟
reg clk;
reg [31:0] count ;//32位的计数器
always@(posedge clk_50M or negedge reset)//异步复位
begin
if (!reset)//如果reset是高电平,说明reset低电平有效
begin
clk<='d0;
count=32'd0;
end
else if(count==3'd100)//判断计时器记到了 100 吗?
begin
count<=32'd0;//计到 100 计数器清零
clk<=~clk;//榆出的时钟取反
end//end begin
else count<=count+1'd1;// 没计到 100 计数器加一
end//end always
endmodule //结束分须模块
//顶层模块taxi
`timescale 1ns / 1ps
//整体顶层模块
module taxi(clk_50M,reset,start,distance,s,m,cost) ;//端口的定义
input clk_50M,reset,start;//总的时钟信号,复位信号,开始信号
output [7:0] distance;//公里
output [7:0] s;//秒
output [7:0] m;//分
output[7:0] cost;//费用
wire clk; //计数时钟
wire distance_enable;//公里控制费用的信号
wire time_enable;//时间控制费用的信号
wire select_clk;//控制信号
//模块的调用
jishuqi u0(.clk_50M (cclk_50M),.clk(clk),.reset(reset));//调用计数分频模块
jicheng u1(.clk(clk),.start(start),.reset(reset),.distance(distance),.distance_enable(distance_enable));//调用计程模块
jishi u2(.clk(clk),.reset (reset),.start(start),.s(s),.m(m),.time_enable(time_enable)); //调用计时模块
control u3(.start(start),.distance_enable(distance_enable),.time_enable(time_enable),.select_clk(select_clk));//调用控制模块
cost u4(.reset(reset),.cost(cost),.select_clk(select_clk),.clk(clk)); //调用计费模块
endmodule//结束顶层模块
//测试模块taxi_test
`timescale 1ns / 1ps
`define clk_cycle 50
//顶层模块测试
module taxi_test;
// Inputs
reg clk_50M;
reg reset;
reg start;
// Outputs
wire [7:0] distance;//公里
wire [7:0] s;//秒
wire [7:0] m;//分
wire [7:0] cost;//费用
// Instantiate the Unit Under Test (UUT)
taxi uut (
.clk_50M(clk_50M),
.reset(reset),
.start(start),
.distance(distance),
.s(s),
.m(m),
.cost(cost)
);
always #`clk_cycle clk_50M=~clk_50M;
initial begin
// Initialize Inputs
clk_50M =0;
reset = 0;
start = 1;
#100 reset=1;
#3000 start=0;
#10000 $stop;
end
endmodule
为什么仿真波形中diatance、m、s、cost一直是0?
在顶层模块taxi中声明了输出信号distance、s、m、cost,但没有给它们赋值
在测试模块taxi_test中,你给输入信号clk_50M、reset和start初始化了值,但在仿真过程中没有对它们进行任何更改
在计程模块jicheng、计时模块jishi和控制模块control中,你用了时钟信号clk,但在测试模块中并未给clk信号提供时钟脉冲
仿真时间太短了, start 信号在 3000ns 后才有小,多运行一段时间就行了