浮点数定化--altera 乘除法ip使用
1、浮点数定点化:
--浮点数例子:2.918
3.1415926---小数点不固定。转为定点数要定义小数需求多少位?整数需求多少位?
--第1步:定义。3位整数位宽,12位小数位宽,最高位为符号位1位--16位有符号定点数。【16位有符号数能表示的数值范围:-32768(1000_0000_0000_0000)~
32767】取低15位,其中3位整数位宽[14:12]--最大表示7,小数最大12位能表示多大精度?
--第2步:精度计算。小数是小于1的,将1表示成2^12=4096份(0~4095),那么最大精度就是1/4096=8/32768=0.000244140625(8表示为32768份,1表示成4096份),最大能表示的小数为(1/4096)*(2^12-1)=0.000244140625*4095=0.999755859375(多了一个零)。所以定义的定点数可以表示的范围是-8.999755859375~
7.999755859375。
--第3步:计算。2.918进行定点化:2.918/0.000244140625=11,952.128~=11952-->定点化后的2.918(四舍五入),含有0.128的误差。
3.1415926进行定点化:3.1415926/0.000244140625=12,867.9632896~=12868-->定点化后为12868(四舍五入),含有误差。逆运算回去:12868-->0011
0010 0100 0100,[14:12]位011为整数位3,[11:0]为0010 0100
0100(580)为小数位,实际表示的小数为580/4096=0.1416015625。也就是定点化后最终实际表示的数为3.1416015625--与3.1415926的确存在误差。误差为3.1415926-3.1416015625=。。。
--定点数相乘,符号位1位,整数位扩充为6位,小数位扩充为24位。
浮点结果:3.1415926*2.918=65715.8340068=9.1671672068
定点结果:12868*11952=153798336(000_1001_0010_1010_1100_0110_1100_0000),最高位为0--结果为
,整数位为00_1001即9,小数位为0010_1010_1100_0110_1100_0000即2803392,所表示的小数2803392/2^24=0.167095184326171875。定点乘法结果为9.167095184326171875,与浮点结果存在误差。
2、altera中的LPM
MULT乘法器,如果输出不加延时,那么它使用的是组合逻辑组成的硬件乘法器单元,给数据立即出结果。乘法器ip核引入时钟,可以使乘法器时序更好,芯片能跑的速度等级更高。
3、固定值乘法:a=2,3,6,8--序列 b=5,使用移位可以实现。
a=2,
b=5-->2'd2*3'd5=2'b10*3'b101=2'b10*(2^2
2^0)=2'b10<<2 2'b10<<0=10。
2'b10<<0=4'b1000
2'b10=4'b1010=4'd10。
4、altera器件仿真常用的几个仿真库有:
D:\Altera\quartus\eda\sim_lib路径下的220model.v 、altera_mf.v
、cycloneiii_atoms.v等文件。其中220module.v中就包含乘法器仿真用到的lpm_mult
module.可在这几个文件内查找所需要的模块。
5、a_in <= {$random} % 2; //产生0、1伪随机数
//a_in <= $random % 10; --产生-10...9的伪随机数
//a_in <= {$random} % 10; --产生0...9的伪随机数
6、写run.do文件的时候,不要把ip核的例化文件.inst文件vlog进去,否则会提示错误。
7、altera乘除法器的ip核的使用
//---------
ex_mult.v--------------------------------
module ex_mult(
input wire sclk,
input wire rst_n,
input wire [7:0] in_a,
input wire [15:0] in_b,
output wire [15:0] out_rslt
);
divide_8_16 divide_8_16_inst (
.clock ( sclk ),
.denom ( in_a ),
.numer ( in_b ),
.quotient ( out_rslt),
.remain ( remain_sig ) //余数,不关心就可
);
endmodule
//-------tb_ex_mult.v--------------------------------------
`timescale 1ns/1ns
module tb_ex_mult;
reg sclk;
reg rst_n;
reg [7:0] in_a;
reg [15:0] in_b;
wire [15:0] out_rslt;
initial begin
rst_n = 0;
sclk = 0;
end
initial begin
#40;
gen_data();
end
always #10 sclk <= ~sclk;
ex_mult ex_mult_inst(
.sclk (sclk ),
.rst_n (rst_n ),
.in_a (in_a ),
.in_b (in_b ),
);
task gen_data();
integer i;
begin
for(i=0;i<255;i=i 1)
begin
@(posedge sclk);
in_a = {{$random} % 100};
in_b = {{$random} % 100};
end
end
endtask
endmodule
//---------------------------run.do----------------------------------------
quit -sim
.main clear
vlib work
vlog ./tb_ex_mult.v
vlog ./../design/*.v
vlog ./../quartus_prj/ipcore_dir/*.v
vlog ./altera_lib/*.v
vsim -voptargs= acc work.tb_ex_mult
add wave tb_ex_mult/ex_mult_inst/*
add wave tb_ex_mult/*
run 10us