大侠好,欢迎来到FPGA技术江湖,江湖偌大,相见即是缘分。大侠可以关注FPGA技术江湖,在“闯荡江湖”、"行侠仗义"栏里获取其他感兴趣的资源,或者一起煮酒言欢。
今天给大侠带来“FPGA学习系列 altera"系列,持续更新。此学习心得是本人之前所写,所用设计软件为Quartus II 13.1,现Quartus II 新版本已更新到19 ,以下仅供初学者学习参考。后续会更新其他系列,敬请关注。话不多说,上货。
对于每一个的小实验,我们都可以把它看作是一个小项目,逐步的去分析,设计,调试,最后完成功能。下面我们就开始我们的“小项目”。
项目名称:二进制转BCD
具体要求:将8位的二进制转成BCD码。
项目分析:
1. 二进制
二进制中只有0和1两个状态,可以表示0、1两种状态的电子器件很多,如开关的接通和断开,晶体管的导通和截止、磁元件的正负剩磁、电位电平的低与高等都可表示0、1两个数码。使用二进制,电子器件具有实现的可行性。
二进制数的运算法则少,运算简单,使计算机运算器的硬件结构大大简化。由于二进制0和1正好和逻辑代数的假(false)和真(true)相对应,有逻辑代数的理论基础,用二进制表示二值逻辑很自然。
电子器件中,所有的数据都是用二进制来表示的。
2. BCD码
BCD码(Binary-Coded Decimal)亦称二进码十进数或二-十进制代码。用4位二进制数来表示1位十进制数中的0~9这10个数码。BCD码是一种二进制的数字编码形式,用二进制编码的十进制代码。BCD码这种编码形式利用了四个位元来储存一个十进制的数码,使二进制和十进制之间的转换得以快捷的进行。
3. 实现方法
1) 对10求余法
将需要转换的数字除以“权”,然后对10求余,得出数字各个位上的数字。例如:8’b1000_0000(10进制中的128),将此数字对10求余,得出个位“8”,然后将“8”赋给最低的4位。将此数字(128)除以10,得出12(在FPGA计算中,自动取整),对10求余,然后得出十位“2”,把“2”赋给次低的4位。将此数字(128)除以100,得出1,对10求余,然后得出百位“1”,把“1”赋给另外的4位。这样就转换出了BCD码。
这类方法中,利用了大量的除法和求余,占用了大量的逻辑资源。但是,实现比较简单,如果芯片的逻辑资源足够的话,可以采取使用这种方法。
2) 大四加三法
进行移位,然后进行判断。如果大于四,则加三。最后得出我们想要的BCD码(下述是按照转换7位讲解的原理)。
架构图如下:
bin_data[7:0]:输入的二进制数据。
bin_data[11:0]:输出的BCD码(输入的二进制数据为8位,最大为8’b1111_1111(255),每四位二进制表示一个BCD码,故而12位)。
系统设计:
1. 工程的名称:bin_to_bcd
2. 实现方法:使用组合逻辑实现。
设计代码如下:
代码语言:javascript复制/*
模块名称:bin_to_bcd
模块功能:将8位的二进制转成BCD码(对10求余法)。
作者:郝旭帅
邮箱:746833924@qq.com
*/
module bin_to_bcd (bin_data, bcd_data);
input [7:0] bin_data;
output reg [11:0] bcd_data;
always @ (*)
begin
bcd_data[3:0] = bin_data % 10;
bcd_data[7:4] = (bin_data / 10 ) % 10;
bcd_data[11:8] = (bin_data / 100) % 10;
end
endmodule
激励代码如下:
代码语言:javascript复制/*
模块名称:bin_to_bcd_tb
模块功能:为bin_to_bcd模块提供激励信号
作者:郝旭帅
邮箱:746833924@qq.com
*/
`timescale 1ns/1ps
module bin_to_bcd_tb;
reg [7:0] bin_data;
wire [11:0] bcd_data;
initial begin
bin_data = 8'd147;
# 200
bin_data = 8'd58;
# 200
bin_data = 8'd169;
# 200
$stop;
end
bin_to_bcd bin_to_bcd_dut(
.bin_data(bin_data),
.bcd_data(bcd_data)
);
endmodule
代码解析:
bin_data赋值时,不要大于255,因为8位的二进制数据最大就是255,若超过255,将出现不正确的赋值。
仿真波形如下:
将bin_data设置成无符号位,将bcd_data设置成十六进制,4位的二进制正好一位十六进制。
通过仿真,证明设计正确。
下面是大四加三法的设计代码以及仿真:在设计中,我们使用层次化设计的方法,逐步完成。
设计代码如下:
代码语言:javascript复制 /*
模块名称:bin_to_bcd
模块功能:将8位的二进制转成BCD码(大四加三法)。
作者:郝旭帅
邮箱:746833924@qq.com
*/
module bin_to_bcd (bin_data, bcd_data);
input [7:0] bin_data;
output [11:0] bcd_data;
wire [19:0] shift_data[7:0];//位宽20,深度8的shift_data
assign shift_data[0] = {18'd0,bin_data,1'b0};//左移
bcd_modify bcd_modify_0(
.in_data(shift_data[0]),
.out_data(shift_data[1])
);//第一次调整并左移
bcd_modify bcd_modify_1(
.in_data(shift_data[1]),
.out_data(shift_data[2])
); //第二次调整并左移
bcd_modify bcd_modify_2(
.in_data(shift_data[2]),
.out_data(shift_data[3])
); //第三次调整并左移
bcd_modify bcd_modify_3(
.in_data(shift_data[3]),
.out_data(shift_data[4])
); //第四次调整并左移
bcd_modify bcd_modify_4(
.in_data(shift_data[4]),
.out_data(shift_data[5])
); //第五次调整并左移
bcd_modify bcd_modify_5(
.in_data(shift_data[5]),
.out_data(shift_data[6])
); //第六次调整并左移
bcd_modify bcd_modify_6(
.in_data(shift_data[6]),
.out_data(shift_data[7])
); //第七次调整并左移
assign bcd_data = shift_data[7] [19:8];
endmodule
代码语言:javascript复制/*
模块名称:bcd_modify
模块功能:调整并且进行左移。
作者:郝旭帅
邮箱:746833924@qq.com
*/
module bcd_modify (in_data, out_data);
input [19:0] in_data;
output [19:0] out_data;
wire [19:0] reg_data;
bcd_singel bcd_singel_0(
.in_data(in_data[19:16]),
.out_data(reg_data[19:16])
);//调整
bcd_singel bcd_singel_1(
.in_data(in_data[15:12]),
.out_data(reg_data[15:12])
); //调整
bcd_singel bcd_singel_2(
.in_data(in_data[11:8]),
.out_data(reg_data[11:8])
); //调整
assign reg_data[7:0] = in_data[7:0];
assign out_data = {reg_data[18:0],1'b0};//左移
endmodule
代码语言:javascript复制/*
模块名称:bcd_singel
模块功能:调整(大四加三)。
作者:郝旭帅
邮箱:746833924@qq.com
*/
module bcd_singel (in_data, out_data);
input [3:0] in_data;
output [3:0] out_data;
assign out_data = (in_data > 4) ? in_data 4'd3 : in_data;
//如果大于4,则加四,否则,原值输出。
endmodule
激励代码如下:
代码语言:javascript复制/*
模块名称:bin_to_bcd_tb
模块功能:为bin_to_bcd模块提供激励信号
作者:郝旭帅
邮箱:746833924@qq.com
*/
`timescale 1ns/1ps
module bin_to_bcd_tb;
reg [7:0] bin_data;
wire [11:0] bcd_data;
initial begin
bin_data = 8'd147;
# 200
bin_data = 8'd58;
# 200
bin_data = 8'd169;
# 200
$stop;
end
bin_to_bcd bin_to_bcd_dut(
.bin_data(bin_data),
.bcd_data(bcd_data)
);
endmodule
代码解析:
bin_data赋值时,不要大于255,因为8位的二进制数据最大就是255,若超过255,将出现不正确的赋值。
仿真波形如下:
将bin_data设置成无符号位,将bcd_data设置成十六进制,4位的二进制正好一位十六进制。通过仿真,证明设计正确。
如果设计要求或者本地晶振与笔者的设计不同,请自行更改设计,以保证设计的正确性。如果还是有不明白的读者可以发邮件到我邮箱或者加群询问。
END