《数字逻辑电路》实验七 数字系统设计(二)
目录
一、实验目的
通过实验,使学生能够用上面所设计的各种电路,组合成一个小的系统,掌握复杂电路的设计方法。
二、实验内容
(1)出租车计费器 :
计费器应有如下功能:
1)实现计费功能,计费标准为:按行驶里程计费,起步价为7.0元,并在车行3km后按2元/km计费,当计费器达到或超过20元时,每千米加收50%的车费,车停止不计费。
2)现场模拟功能:以开关键模拟千米计数,能模拟汽车启动、停止、暂停等状态。
3)将车费和路程分别以十进制形式显示出来。
三、代码与截图
源代码:taxi_204.v
`timescale 1ns / 1ps
module taxi_204(
output [7:0] an,
output [6:0] segs,
input clk,
input k1,
input k2,
input reset
);
wire [3:0] valuse1,valuse2,valuse3,valuse4,valuse5,valuse6,valuse7,valuse8,valuse9,valuse10,valuse0;
hexseg8_204 uut(.clk(clk),.reset(reset),.en(8'b00000000),
.hex0(valuse6),.hex1(valuse7),.hex2(valuse8),.hex3(valuse9),
.hex4(valuse0),.hex5(valuse1),.hex6(valuse2),.hex7(valuse3),
.an(an),.segs(segs));
control c1_z(
.k1(k1), //启动-停止
.k2(k2), //暂停-重启
.clk(clk),
.reset(reset),
.valuse0(valuse0),
.valuse1(valuse1),
.valuse2(valuse2),
.valuse3(valuse3),
.valuse6(valuse6),
.valuse7(valuse7),
.valuse8(valuse8),
.valuse9(valuse9)
);
endmodule
//**********************************************************
module control(
input k1, //启动停止
input k2, //暂停,重启
input clk,
input reset,
output reg[3:0]valuse0,
output reg[3:0]valuse1,
output reg[3:0]valuse2,
output reg[3:0]valuse3,
output reg[3:0]valuse6,
output reg[3:0]valuse7,
output reg[3:0]valuse8,
output reg[3:0]valuse9
);
reg [31:0] num1; //里程
reg clkout;
reg [25:0] div_counter = 0;
always @(posedge clk,posedge reset)
begin
if (reset) begin
div_counter <= 0;
clkout <= 0;
end
else begin
if (div_counter == 50000000-1) begin
div_counter <= 0;
clkout <= ~clkout;
end
else div_counter <= div_counter + 1;
end
end
always @(posedge clkout or posedge reset)begin//费用
if(reset||k2==1'b0)begin
num1<=0;
end
else if(k1)//暂停
num1=num1;
else if(k2==1'b1 ||k1==1'b0) //开始
num1=num1+50;
end
reg [7:0] c1;
always @(posedge clkout or posedge reset)begin//费用
if(reset)begin
c1=0;
end
else if(num1<3000)
c1=7;
else if(num1>=3000&&c1<20)
c1=7+(num1-3000)*2/1000;
else
c1=20+(num1-9500)*3/1000;
end
always @(posedge clkout)begin
valuse0 <= num1/1000% 10;
valuse1 <= num1/1000% 100/10;
valuse2 <= num1/1000% 1000 / 100;
valuse3 <= num1/1000% 10000 / 1000;
valuse6 <= c1 % 10;
valuse7 <= c1 % 100 / 10;
valuse8 <= c1 % 1000 / 100;
valuse9 <= c1 % 10000 / 1000;
end
endmodule
//**********************************************************
module hexseg8_204(
input clk,
input reset,
input [7:0] en,
input [3:0] hex0,
input [3:0] hex1,
input [3:0] hex2,
input [3:0] hex3,
input [3:0] hex4,
input [3:0] hex5,
input [3:0] hex6,
input [3:0] hex7,
output [7:0] an,
output [6:0] segs
);
wire [17:0] cnt18;
wire [ 2:0] cntSel;
wire [ 7:0] en0, en1, en2, en3, en4, en5, en6, en7;
wire [ 3:0] numout;
assign en0 = (en | 8'b11111110); //设置数码管 0 是否显示
assign en1 = (en | 8'b11111101); //设置数码管 1 是否显示
assign en2 = (en | 8'b11111011); //设置数码管 2 是否显示
assign en3 = (en | 8'b11110111); //设置数码管 3 是否显示
assign en4 = (en | 8'b11101111); //设置数码管 4 是否显示
assign en5 = (en | 8'b11011111); //设置数码管 5 是否显示
assign en6 = (en | 8'b10111111); //设置数码管 6 是否显示 ;1和0或为1,1和1或为1
assign en7 = (en | 8'b01111111); //设置数码管 7 是否显示 ;0和0或为0,0和1或为1; en低电平有效
//实例化改造后的 hexseg
hexseg sevensegdec(.hex(numout), .segs(segs));
counter counterSel(clk, reset, cntSel);//2ms counter counterSel(clk, reset, cntSel);//2ms
mux8 #(8) mux8_7segen(en0, en1, en2, en3, en4, en5, en6, en7,
cntSel, an); //8 位数据的 8 选 1
mux8 #(4) mux8_7segval(hex0, hex1, hex2, hex3, hex4,
hex5,hex6,hex7, cntSel, numout);// 8 位数据的 8 选 1
endmodule
module hexseg(
input [3:0] hex,
output reg [6:0] segs
);
always @(*)
case(hex)
4'h0: segs = 7'b0000001; //0
4'h1: segs = 7'b1001111; //1
4'h2: segs = 7'b0010010; //2
4'h3: segs = 7'b000110; //3
4'h4: segs = 7'b1001100; //4
4'h5: segs = 7'b0100100; //5
4'h6: segs = 7'b0100000; //6
4'h7: segs = 7'b0001111; //7
4'h8: segs = 7'b00000000; //8
4'h9: segs = 7'b0001100; //9
4'ha: segs = 7'b0001000; //10
4'hb: segs = 7'b1100000; //11
4'hc: segs = 7'b1110010; //12
4'hd: segs = 7'b1000010; //13
4'he: segs = 7'b0110000; //14
4'hf: segs = 7'b0111000; //15
default: segs = 7'b1111111;
endcase
endmodule
module counter // 两毫秒计数器
( input clk,
input reset,
output reg [2:0] cnt);
reg [26:0] count=0;
always @(posedge clk, posedge reset)
begin
if(reset)begin
count<=0;
cnt <= 3'b000;
end
else begin
count<=count+1;
if(count==200000)begin//两毫秒计数为二十万
count<=0;
cnt<=cnt+1;
if(cnt==3'b111)
cnt<=3'b000;
end
end
end
endmodule
module mux8 #(parameter WIDTH = 8) //8 选 1 选择器
(input [WIDTH-1:0] d0, d1, d2, d3,
d4, d5, d6, d7,
input [2:0] s,
output reg [WIDTH-1:0] y);
always @(*)
begin
case(s)
3'b000:y<=d0;
3'b001:y<=d1;
3'b010:y<=d2;
3'b011:y<=d3;
3'b100:y<=d4;
3'b101:y<=d5;
3'b110:y<=d6;
3'b111:y<=d7;
default y<=0;
endcase
end
endmodule
引脚约束:taxi_204.xdc
set_property IOSTANDARD LVCMOS33 [get_ports {an[7]}]
set_property IOSTANDARD LVCMOS33 [get_ports {an[6]}]
set_property IOSTANDARD LVCMOS33 [get_ports {an[5]}]
set_property IOSTANDARD LVCMOS33 [get_ports {an[4]}]
set_property IOSTANDARD LVCMOS33 [get_ports {an[3]}]
set_property IOSTANDARD LVCMOS33 [get_ports {an[2]}]
set_property IOSTANDARD LVCMOS33 [get_ports {an[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {an[0]}]
set_property IOSTANDARD LVCMOS33 [get_ports {segs[6]}]
set_property IOSTANDARD LVCMOS33 [get_ports {segs[5]}]
set_property IOSTANDARD LVCMOS33 [get_ports {segs[4]}]
set_property IOSTANDARD LVCMOS33 [get_ports {segs[3]}]
set_property IOSTANDARD LVCMOS33 [get_ports {segs[2]}]
set_property IOSTANDARD LVCMOS33 [get_ports {segs[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {segs[0]}]
set_property IOSTANDARD LVCMOS33 [get_ports k2]
set_property IOSTANDARD LVCMOS33 [get_ports k1]
set_property IOSTANDARD LVCMOS33 [get_ports clk]
set_property IOSTANDARD LVCMOS33 [get_ports reset]
set_property PACKAGE_PIN A18 [get_ports {an[7]}]
set_property PACKAGE_PIN A20 [get_ports {an[6]}]
set_property PACKAGE_PIN B20 [get_ports {an[5]}]
set_property PACKAGE_PIN E18 [get_ports {an[4]}]
set_property PACKAGE_PIN F18 [get_ports {an[3]}]
set_property PACKAGE_PIN D19 [get_ports {an[2]}]
set_property PACKAGE_PIN E19 [get_ports {an[1]}]
set_property PACKAGE_PIN C19 [get_ports {an[0]}]
set_property PACKAGE_PIN F15 [get_ports {segs[6]}]
set_property PACKAGE_PIN F13 [get_ports {segs[5]}]
set_property PACKAGE_PIN F14 [get_ports {segs[4]}]
set_property PACKAGE_PIN F16 [get_ports {segs[3]}]
set_property PACKAGE_PIN E17 [get_ports {segs[2]}]
set_property PACKAGE_PIN C14 [get_ports {segs[1]}]
set_property PACKAGE_PIN C15 [get_ports {segs[0]}]
set_property PACKAGE_PIN Y18 [get_ports clk]
set_property PACKAGE_PIN P20 [get_ports reset]
set_property PACKAGE_PIN R4 [get_ports k1]
set_property PACKAGE_PIN W4 [get_ports k2]
引脚锁定:
RTL 分析 (RTL ANALYSIS) 的原理图:
运行完成:
四、下板验证结果
(1)将比特流文件下载后,拨动k1再拨动k2,计数器开始计数,即开始计费,数码管高四位会显示出当前的里程数,低四位显示对应的费用。
(2)再次拨动k2,计数器暂停技术,即暂停计费,再次拨动k2,计数器继续计数。
(3)拨动k1,数器停止计数,即停止计费。数码管高四位清零(即里程数归零),低四位为7(即回到起步价)。