合工大 计算机组成原理.docx
- 文档编号:12246580
- 上传时间:2023-04-17
- 格式:DOCX
- 页数:27
- 大小:220.13KB
合工大 计算机组成原理.docx
《合工大 计算机组成原理.docx》由会员分享,可在线阅读,更多相关《合工大 计算机组成原理.docx(27页珍藏版)》请在冰豆网上搜索。
合工大计算机组成原理
合肥工业大学
计算机与信息学院
课程设计报告
课程:
计算机设计与综合实践
专业班级:
信息安全11-1
学号:
20112914
姓名:
王佳淼
2014年11月
摘 要
本文介绍了一种采用可编程逻辑器件(FPGA(Sparten6))进行出租车计价器的设计思想以及实现方法。
本设计实现了出租车计费器所需的一些基本功能,计价金额包括起步价、里程计费、等待计时计费等。
该设计采用模块化设计,在Xilinx软件平台下,采用VerilogHDL硬件描述语言描述和模拟仿真了分频模块、计程模块、计时模块、计费模块、LED显示模块,完成了出租车计费器仿真设计。
关键词:
FPGA(Spartan6-LX45),出租车计价器,Xilinx,VerilogHDL
目录
一、方案总设计4
1.1设计要求4
1.2设计思想4
二、软件功能单元设计和实现4
2.1分频模块4
2.1.1计数器分频模块(FrequencyDiv1)5
2.1.2数码管显示分频模块(FrequencyDiv2)5
2.2里程模块(Disatance_Cal模块)5
2.3时间模块(Time_Cal模块)5
2.4计费模块(Money_Cal模块)5
2.5数码管显示模块(LED_Display模块)6
2.6顶层模块(Taximeter模块)7
三、问题总结9
四、体会与感想9
附录:
单元模块VerilogHDL源代码10
1.计数器的分频模块(Frequency_Div)10
2.数码管的分频模块(Frequency_Div_2)10
3.里程模块(Distance_Cal)11
4.时间模块(Time_Cal)12
5.计费模块(Money_Cal)13
6.数码管显示模块(LEDDisplay_Cal)16
7.顶层模块(Taximeter)18
8.引脚约束(Taximeter)20
方案总设计
设计要求
设计一个出租车计价器。
该计价器的计费系统:
行程3公里内,且等待累计时间2分钟内,起步费为10元;3公里外以每公里1.6元计费,等待累计时间2分钟外以每分钟以1.5元计费,并能显示行驶公里数、等待累计时间、总费用。
设计有分频模块,控制模块,计量模块,译码模块,显示模块。
设计思想
出租车的一般计费分类:
近路途未停车状况:
车价=起步价【10元】(3>里程数且10>等待时间)
近路途有停车状况:
车价=起步价【10元】+(等待时间-等待累积时间【2分钟】)*1.5(3>里程数且10>等待时间)
远路途未停车状况:
车价=起步价【10元】+(里程数 - 起步里程数【3公里】)*每公里单价【1.6元】 (3<里程数且10>等待时间)
远路途有停车状况:
车价=起步价【14元】+(远程里程标准【10公里】 - 起步里程数【3公里】)*每公里单价【1.6】 + (等待时间-等待累积时间【2分钟】)*1.5 (里程数>10且10<等待时间)
综上所述,完成出租车计费需要,在乘客上车后,需要启动出租车计价器,所以这样就需要一个控制出租车计价器开始工作的使能信号,使得有乘客上车后就要将计价表上显示出起步价10元;而在计价的过程中又需要分两种情况:
一种是按增加的里程来收费,另一种是按照停车的时间来收费,因为在出租车行驶的过程中,有可能会遇到堵车或红绿灯的情况,这样会耽误出租车的时间,所以当超过一定标准时间后,就应当计时收费。
软件功能单元设计和实现
本系统采用层次化、模块化的设计方法,设计顺序为自下向上。
首先实现系统框图中的各子模块,然后由顶层模块调用各子模块来完成整个系统。
为了便于在数码管里显示和演示,这里的路程、时间和费用计数器均用BCD码表示。
我主要做的是里程模块,所以2.2里程模块即Disatance_Cal模块详细说明,其余模块只进行大体描述。
2.1分频模块
这里主要是将实验板上提供的时钟信号进行分频,来得到我们想要的时钟脉冲。
因为我们所使用的实验板是Spartan6-LX45,它可以提供100MHz的时钟信号,而这个信号对于我们来说实在是太快了,所以我们需要对其进行分频。
在本次的设计中,我们需要在两个地方用到不同的分频时钟,一个是在LED显示模块,而另外的几个模块用另一个时钟信号。
2.1.1计数器分频模块(FrequencyDiv1)
此模块的功能是对总的时钟进行分频,分出的频率是让计数器用的,因为我们使用总的时钟频率是100MHz的,所以我们在设计该模块的时候用了一个32位的计数器,当计数器计到25_000000的时候产生一个时钟信号,提供给里程模块,时间模块,计费模块使用。
其实我们是将100MHz分频后变成每一秒计数一次,这也是为了便于实验(在现实生活中不一定是这样)。
2.1.2数码管显示分频模块(FrequencyDiv2)
此模块产生的脉冲信号是提供给数码管的,因为要显示的数据有六位,所以数码管的扫描频率应该要比计数分频模块更快。
我们经过测试后,得到500000这个数值。
当计数到500000这个值时,输出一个脉冲信号,扫描一遍数码管,更新数码管上的数据。
2.2里程模块(Disatance_Cal模块)
此模块的功能是计算出租车行驶的路程。
在出租车启动并行驶的过程中(即复位/启动信号reset为1,行驶/停止信号start为1),当输出时钟信号clk_final是上升沿的时候,系统就对路程计数器distance的里程计数器进行加计数,而当路程超过三公里时,系统将输出一个里程计费使能信号distance_enable(为高电平),再将该信号传给计费模块,就可以实现每增加一公里,费用增加1.6元的操作了。
具体实现如下图所示:
图1
图2
图3
(1)在出租车启动并行驶的过程中(即复位/启动信号reset为1,行驶/停止信号start为1),系统就对路程计数器distance的里程计数器进行加计数,如图1所示。
(2)出租车启动并行驶的过程中(即复位/启动信号reset为1,行驶/停止信号start为1),当路程超过三公里时,系统将输出一个里程计费使能信号distance_enable(为高电平)。
如图2所示。
(3)复位/启动信号reset为1时,里程计费使能信号distance_enable为低电平,意味着出租车已经到达目的地。
如图3所示。
2.3时间模块(Time_Cal模块)
此模块用于计算停车等待的时间。
在出租车行进中,如果车辆停止等待,计数器则在clk_final信号的上升沿进行加计数,每60次产生进位脉冲使分钟计数器位进行加计数,当累计等待时间超过2分钟(即当刚计时到三分钟)时,输出一个时间计费使能脉冲信号time_enable,之后每增加一分种,就会有一个time_enable脉冲信号输出,这样再将信号传到计费模块中,就可以实现每增加一分钟,费用增加1.5元。
而在设计中,我们原本是有分的十位和个位,以及秒的十位和个位,但是由于数码管的个数有限,所以在数码管上只显示分的个位和秒的个位。
2.4计费模块(Money_Cal模块)
费用计数器模块用于出租车启动后,根据行驶路程和等待时间计算费用。
当出租车停车时,时钟reset用于将费用计数器复位为起步价10元;当车处于行驶状态时,出现distans_enable信号,若满3公里后路程每满1公里,费用计数器加1.6元;当出租车处于停止等待状态且时钟满2分钟时,出现time_enable脉冲信号,时间每满1分钟,费用计数器加1.5元。
2.5数码管显示模块(LED_Display模块)
在这个模块中,我们需要将费用,里程,时间给显示出来,就需要用到两个信号,启动/复位信号reset和数码管时钟信号clk_final_1,还需要各种要输出的数据:
即money,distance,min,second。
在这个模块中,主要的问题就是如何译码。
其中我们要用到六个数码管,这六个数码管分别对应着不同的数据。
从左到右,依次是费用的十位和个位,里程的十位和个位,分钟的个位,秒的个位。
而对于本次设计所用的实验箱,这六个数码管可以用0和1表示是否选中(其中1代表选中该数码管),所以我们定义了一个4位译码选择数组,用于数码管的选择,分别是0,1,2,3,4,5号数码管,具体可以参考显示代码和引脚约束代码。
上图是我们此次实验所用八段数码管的原理图,其中显示的数字对应的二进制表示为如下表:
X
A
B
C
D
E
F
G
0
0
1
1
1
1
1
1
1
0
0
0
0
1
1
0
2
1
0
1
1
0
1
1
3
1
0
0
1
1
1
1
4
1
1
0
0
1
1
0
5
1
1
0
1
1
0
1
6
1
1
1
1
1
0
1
7
0
0
0
0
1
1
1
8
1
1
1
1
1
1
1
9
1
1
0
1
1
1
1
因为我们此次只用到了BCD码中的数字,所以其他的如A,B,C,D,E,F都没有在表中写出。
2.6顶层模块(Taximeter模块)
在顶层模块中,主要是要调用其他各个模块的功能,然后来实现我们最终的目的,出租车计价。
其中需要输入和输出的参数如下表所示:
输入输出端口说明
端口
类型
功能定义
Clk_100M
Input
系统时钟。
reset
Input
启动1/复位0键
start
Input
选择计费模式
Start=1,计程计费
Start=0,计时计费
min[7:
0]
Output
分的高四位和低四位
second[7:
0]
Output
秒的高四位和低四位
distance[7:
0]
Output
里程高四位和低四位
Money[11:
0]
Output
总费的十元,元,角位
其仿真结果如下图所示:
上图中当reset和start都为高电平时,开始的是里程计费,超过3公里后,每增加1公里,费用增加1.6元,途中的money显示的三位分别是十元位,元位,和角位;
当start转为低电平时,计费停止,公里计数也停止,开始时间的计数,先是秒针走,分等秒走了60次后才加1;
当计时满两分钟,即刚计到3分钟时,开始时间计费,从图中可看出,money加了1.5元。
问题总结
在本次计算机组成原理课程设计的过程中,由于时间只有两周不到,十分紧张。
再加上小组成员都是初次接触FPGA开发板和VerilogHDL语言,所以刚刚开始课程设计的几天,进展缓慢。
在过程当中,我们遇到了各种问题,例如,如何使各个模块更好的融合,如何实现1.6元和1.5元的加法计算等问题。
为了更好的解决问题,我们小组参加了实验室老师和同学的答疑讲解会,实验室同学演示了VerilogHDL语言的编写和调试,也讲解了关于课设题目的设计思路。
我遇见的问题主要是与设计分频模块的同学、计时计费模块的同学进行沟通,因为里程模块是一个会被计时计费模块调用的模块,输出的参数传递到计时计费模块。
体会与感想
经过计算机组成原理的课程设计,在完成过程中使用FPGA(Spartan6-LX45)开发板、Verilog语言以及Xilinx开发环境,对这些全新的硬件开发工程都有了一定的了解。
这次的课程设计让我更好的了解了软件编程和硬件实现的联系。
正因为有硬件设备的约束,所以这个课程设计大大提升了我的动手实践能力,过这次课程设计后,也我在FPGA硬件平台中基本入了门,对我今后的学习是很大的帮助的。
除此之外,计算机组成原理课程设计是分组完成的。
与他人一起合作完成项目,是需要沟通以便结局出现的一些大大小小的问题。
这给我提供一次良好的机会来检验我的团队合作能力和处理问题的能力,起到了很好锻炼的作用,如果以后我再遇到相同或类似问题的时候,借助本次课设的经验,我一定可以举一反三,独立并迅速的解决遇到的问题。
附录:
单元模块VerilogHDL源代码
1.计数器的分频模块(Frequency_Div)
moduleFrequency_Div(
inputclk_100M,//总的时钟频率
inputreset,//复位键
outputclk_final//分频输出频率
);
regclk_final;
reg[31:
0]count;//32位计数器
always@(posedgeclk_100Mornegedgereset)//异步复位
begin
if(!
reset)//低电平复位
begin
clk_final<='d0;
count<=32'd0;
end
elseif(count==32'd50000000)//判断计时器是否到50000000
begin
count<=32'd0;//计时到50000000,计数器清零
clk_final<=~clk_final;//输出时钟信号取反
end
else
count<=count+1'd1;//没计到50000000,计数器加1
end
endmodule
2.数码管的分频模块(Frequency_Div_2)
moduleFrequency_Div_2(
inputclk_100M,//总的时钟频率
inputreset,//复位键
outputclk_final_1//分频输出频率
);//定义端口
regclk_final_1;
reg[31:
0]count;//32位计数器
always@(posedgeclk_100Mornegedgereset)//异步复位
begin
if(!
reset)//低电平复位
begin
clk_final_1<='d0;
count<=32'd0;
end
elseif(count==32'd50000)//判断计时器是否到50000
begin
count<=32'd0;//计时到50000,计数器清零
clk_final_1<=~clk_final_1;//输出时钟信号取反
end
else
count<=count+1'd1;//没计到50000,计数器加1
end
endmodule
3.里程模块(Distance_Cal)
moduleDistance_Cal(
inputclk_final,//输出的时钟信号
inputstart,
inputreset,
output[7:
0]distance,//里程
outputdistance_enable//里程计费使能信号
);
reg[7:
0]distance;
regdistance_enable;
always@(posedgeclk_finalornegedgereset)//异步信号
begin
if(!
reset)//低电平复位
begin
distance<=8'd0;
end
elseif(start)//start为高电平
begin
if(distance[3:
0]==9)//distance的低四位是否计到9
begin
distance[3:
0]<=4'd0;//如果低四位计到9,就清零
if(distance[7:
4]==9)//distance的高四位是否计到9
distance[7:
4]<=4'd0;//如果计到9,就清零
else//高四位数字<9,就继续加1操作
distance[7:
4]<=distance[7:
4]+4'd1;
end
else//低四位数字<9,就继续加1操作
distance[3:
0]<=distance[3:
0]+4'd1;
end//start结束
end//always结束
always@(posedgeclk_finalornegedgereset)
begin
if(!
reset||start==0)
begin
distance_enable<=1'd0;//复位
end
else
if(distance>3)//公里大于三的时候,修改
begin
distance_enable<=1'd1;//输出distance_enable信号
end
end
endmodule
4.时间模块(Time_Cal)
moduleTime_Cal(
inputclk_final,//最终输出的时钟
inputreset,
inputstart,
output[7:
0]second,//输出时间的秒钟
output[7:
0]min,//输出时间的分钟
outputtime_enable//输出时间的使能信号
);
reg[7:
0]second;
reg[7:
0]min;
wiretime_enable;
always@(posedgeclk_finalornegedgereset)//异步复位
begin//1
if(!
reset)//低电平复位
begin
second<=8'd0;
min<=8'd0;
end
elseif(!
start)
begin
if(second[3:
0]==9)//秒的低四位是9时
begin
second[3:
0]<=4'd0;//清零工作
if(second[7:
4]==5)
begin
second[7:
4]<=4'd0;//清零
if(min[3:
0]==9)//分钟的低四位为9时,需清零
begin
min[3:
0]<=4'd0;
if(min[7:
4]==9)min[7:
4]<=4'd0;
else
min[7:
4]<=min[7:
4]+1'd1;end
else
min[3:
0]<=min[3:
0]+1'd1;
end
else
second[7:
4]<=second[7:
4]+1'd1;end
else
second[3:
0]<=second[3:
0]+1'd1;end
else
begin
second[7:
0]<=0;min[7:
0]<=0;
end
end//endalways
//输出time_enable信号,当计时超过两分钟时,之后每一分钟来一个time_enable信号
assigntime_enable=((min[7:
0]>8'd2)&&(second[7:
0]==8'd0))?
1'd1:
1'd0;//和always并行执行
endmodule
5.计费模块(Money_Cal)
moduleMoney_Cal(
inputclk_final,
inputreset,
inputdistance_enable,
inputtime_enable,
output[3:
0]temp,
output[11:
0]money
);
reg[11:
0]money;
always@(posedgeclk_finalornegedgereset)//异步复位
begin
if(!
reset)//低电平复位
begin
money[11:
0]=12'b000100000000;//起步价为10元
end
elseif(distance_enable==1)//如果是里程计费信号来了,就按里程计费
begin
if(money[3:
0]==4||money[3:
0]==6||money[3:
0]==8)//当低四位(角位)是4,6,8时
begin
money[3:
0]=money[3:
0]+4'd6;//出现上述情况,需要显示十进制,就得这么做
money[3:
0]=money[3:
0]-10;
money[7:
4]=money[7:
4]+4'd1;//费用的"元"位<9,就+1
if(money[7:
4]>=9)//费用的"元"位计到9,
begin
money[7:
4]=money[7:
4]-10;//修改
if(money[11:
8]==4'd9)begin
money[11:
8]=4'd0;//清零
end
else
begin
money[11:
8]=money[11:
8]+4'd1;end
end
else
begin
money[7:
4]=money[7:
4]+4'd1;end
end
else//当末位"角位"是0或2的时候
begin
money[3:
0]=money[3:
0]+4'd6;//角位直接先加6,然后判断高位是否能直接相加
if(money[7:
4]==9)//费用的"元"位计到9,就清零
begin
money[7:
4]=4'd0;//清零
if(money[11:
8]==4'd9)//如果费用的"十元"位计到9,就清零
begin
money[11:
8]=4'd0;//清零
end
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 合工大 计算机组成原理 计算机 组成 原理