当前位置:   article > 正文

RTL 数制与函数_rtl代码 bit文件实现

rtl代码 bit文件实现

本文的目的是阐述如何将算法转化为RTL代码

纸上谈芯 - 知乎
从算法到RTL实现 - 移知


1. 定点数

即所有数据的小数点位置是固定的。通常,将小数点置于最高位之前,就为定点小数or纯小数,将小数点置于最低为之后,就为定点整数or纯整数。

如果小数点在中间,就为浮点数。

在这里插入图片描述

在这里插入图片描述

RTL只能整数运算

注意RTL中没有小数点,无法表示小数,只能作整数运算

那涉及小数运算怎么实现呢?RTL可看作:小数扩 2 n 2^n 2n倍成整数后的运算

例如python模型如下

import math as m
def dut (a, b):
    a_ext = a * m.pow(2,2)
    #...整数运算
    return res
  • 1
  • 2
  • 3
  • 4
  • 5

相应地RTL模型中如下

module	dut(
	input			clk,
	input  [4:0]	a,					//	此处a为 扩4倍后的结果
	input  [5:0]	b,					//	此处b为 扩8倍后的结果
	output [6:0]	res
);
	assign a_ext = {a,1'd0};			// 相同量纲,尾添1'd0
	//...整数运算
endmodule
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

这样就将所有的小数运算转化为整数运算了,在RTL中就可以实现。

1.1. 整数

RTL Arithmetic - 整数数制

1.2. 加减法

加减法系统计算过程是 将减法转变为加上其补码,先扩位再计算

a + b = [ a ] 补 + [ b ] 补 a + b = [a]_补 + [b]_补 a+b=[a]+[b]

a − b = [ a ] 补 + [ − b ] 补 a - b = [a]_补 + [-b]_补 ab=[a]+[b]

注意扩位是不是有signed

溢出保护

如果被赋值变量的位宽能够覆盖所有取值,就不会出现溢出。否则,就可能出现数据溢出,结果为错值,需要做量化处理。

unsigned 溢出检测和保护RTL例程如下

module	u_ovf_chk(
	input	[3:0]	a,
	input	[3:0]	b,
	
	output	[1:0]	res
);
	
	// max(a) = 4'd15, max(b) = 4'd15, 故max(a+b) = 'd30,因此res必溢出,创建不溢出变量res_ext
	wire	[4:0]	res_ext;
		 
	assign res_ext = a + b;
	
	// res_ext[4:2]有1'b1则说明溢出,则res取最大值2'd3
	always@(*) begin
		if(|res_ext[4:2])
			res = 2'b11;
		else
			res = res_ext[1:0];
	end
endmodule
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

unsigned 溢出检测和保护python例程如下

res = a + b;
if(res >3):
	res = 3
  • 1
  • 2
  • 3

如果是有符号数,就要考虑是上溢还是下溢

signed 溢出检测和保护RTL例程如下

module	s_ovf_chk(
	input	signed [4:0]	a,
	input	signed [4:0]	b,
	
	output	signed  [2:0]	res
);

	// a和b均在-16~15,故a+b在-32~30,因此res必溢出,创建不溢出变量res_ext 
	wire signed [5:0]	res_ext;
	
	assign res_ext = a + b;
	
	// 溢出且res_ext为正数,则为上溢,否则为下溢
	always@(*) begin
		if(res_ext > 3) 
			res = 3;
		else if(res_ext < -4)
			res = -4;
		else
			res = res_ext[2:0];
	end

endmodule
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

signed 溢出检测和保护RTL例程如下

res = a + b;
if(res>3):
	res = 3;
elif(res<-4):
	res = -4
  • 1
  • 2
  • 3
  • 4
  • 5

1.3. 乘法

针对乘法算法实现 x [ m − 1 : 0 ] × y [ n − 1 : 0 ] x[m-1:0]×y[n-1:0] x[m1:0]×y[n1:0] ,介绍几种乘法器的实现方式,三种实现对比如下

实现方式 流水线周期操作时间消耗资源数量
查找表1个CLK1个CLK
二叉加法树1个CLK可任意配置max(m,n)个1bit乘法器,max(m,n)-1个加法器,较少触发器
累加器1个CLK可任意配置max(m,n)个1bit乘法器,max(m,n)-1个加法器,较多触发器
补码一位乘(Booth算法)---

查找表

二叉加法树乘法器

RTL基于二叉加法树的乘法器IP设计

4级流水例图如下

在这里插入图片描述

累加乘法器

4级流水例图如下。与加法树对比可知,加法树用了11个触发器,阵列加法器用了14个触发器

在这里插入图片描述

补码一位乘(Radix-2 Booth)

补码一位乘(Radix-2 Booth)

1.4. 除法

查找表

Paper-Pencil Division Algorithm

RTL基于Paper-Pencil Division Algorithm的除法器IP设计

2. IEEE 754 协议

根据之前的讨论,硬件电路中无法表示小数,所有的定点数都要看作是小数×2^n的结果,而且n的选取不同会导致同一个小数有多种不同的表示。

为了各计算机厂商有一个统一的标准,进而相互兼容,推出IEEE 754标准,用于二进制表示十进制浮点数。该标准现已广泛应用于各种CPU等核,即C++、Java等高级语言的floatdouble数据类型均是按照IEEE 754标准映射到底层硬件的。

该标准仅用于统一浮点数表示方法,在作四则运算比较困难,需要统一指数。

2.1. 单精度浮点float & 双精度浮点double

IEEE 754 浮点数标准介绍

2.2. IEEE 754 四则运算

ieee754-top-V3.0.rar

2.3. IEEE 754 与定点数 的转化

3. 函数拟合

3.1. 坐标旋转数字计算法(Coordinate Rotation Digital Computer, CORDIC)

坐标旋转数字计算法(Coordinate Rotation Digital Computer, CORDIC)

3.2. 查找表法

如何使用RTL拟合一个函数呢?例如 y = f ( x ) , x ∈ ( a , b ) y=f(x), x\in(a,b) y=f(x),x(a,b),可以使用基于查找表的方法。

使用ROM拟合,先将输入信号映射为ROM地址,再将ROM地址映射为 ( a , b ) (a,b) (a,b)内的值,再函数值 y y y映射到ROM值,整个映射过程如下

module fx#(
	parameter	N = 16,
	parameter	M
	)(
	input 				clk,
	input	[N-1:0]		x_bin,
	output	[M-1:0]		y_bin
	);
	
	wire [N-1:0] x_bin_addr;
	assign x_bin_addr = x_bin + {1'b1,{(N-1){1'b0}}};

	ROM_fx	U_ROM_FX(					// M × (2^N) ROM
		.clk		(clk		),
		.addr		(x_bin_addr ),
		.dout		(y_bin		)
	);
	
endmodule
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

N位输入→N位ROM地址

ROM地址与输入位宽相同。若存在负数,那么输入值从 N ′ b 100...00 → N ′ b 011...11 N'b100...00→N'b011...11 Nb100...00Nb011...11是从最小到最大线性变化,如果直接作为ROM地址,则ROM地址变化不是线性的,所以作转化。

x_bin_addr [N-1:0] = x_bin[N-1:0] + N’b100…00

在这里插入图片描述

此时x_bin_addr 是 N ′ b 000...00 → N ′ b 111...11 N'b000...00→N'b111...11 Nb000...00Nb111...11也从最小到最大线性变化的

ROM地址→x

即用 N ′ b 000...00 → N ′ b 111...11 N'b000...00→N'b111...11 Nb000...00Nb111...11表示 ( a , b ) (a,b) (a,b)的区间,即采样值。因此有

x = a + b − a 2 N \frac{b-a}{2^N} 2Nba · x_bin_addr,即Nbit输入的精度为 b − a 2 N \frac{b-a}{2^N} 2Nba

在这里插入图片描述

x→y

即y = f(x) = f(a + b − a 2 N \frac{b-a}{2^N} 2Nba · x_bin_addr)

y→ROM数据

y的数据一般为小数

4. CRC校验

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/酷酷是懒虫/article/detail/807908
推荐阅读
相关标签
  

闽ICP备14008679号