除法器逻辑复杂,其特点决定了在FPGA内,甚至CPU(除51外),均无除法器硬核。本节给出实时除法器RT_Divider的完整代码,可不经修改直接使用。
RT_Divider实现通用的定点数除法,功能为:分子÷分母=商…余数。分子与分母的比特宽度可根据实际运用情况合理选取,余数的比特宽同分母。商的比特宽度默认值为分子宽度-分母宽度,也可以根据实际情况自由选取。除法器完成除法运算需要的周期数为商的比特宽度。在除法运算结束后,商和余数同时出现在端口;若分子或分母数值发生改变则触发一次新的运算;若在除法运算期间分子或分母发生改变,将一直等到本次运算结束再触发下一次运算;若运算期间发生多次变化,则先前的变化值均被忽略,最后一次的变化值触发下一轮运算。如果除法实际运算值相对于商的宽度发生溢出,则商和余数的结果无价值。
除法器的使用可固定为如下形式:
① 定义std_vector类型的分子N、分母D、商Q和余数R
② g1: RT_Divider genericmap(NW=>N’length, DW=>D’length, QW=>Q’length)
port map(clock=>clock, numerator=>N, denominator=>D, quotient=>Q, remainder=>R);
由于RT_Divider使用了ucx_2008pkg中大部分函数(function)和过程(procedure),所以把包含将来可能会用到的函数或过程的文件ucx_2008pkg.vhd连同RT_Divider.vhd一起在附近内给出。
为了阐明RT_Divider的设计逻辑,很有必要对ucx_2008pkg的部分函数或过程做一次系统解释。
自定义包ucx_2008pkg主要是一些重载函数和过程的定义。函数(function)和过程(procedure)均类似于C语言的函数,不过是过程更像带指针或引用参数的函数。为行文方便,在不引起混淆的情况下,以后用函数统称函数或过程。
在001贴中,以STDZ函数为例说明本文推荐的编程风格的一个特点是把常用函数统一放在自定义包内,并拷贝到Quartus II按照目录\quartus\libraries\vhdl\ucxLib文件夹下(此文件夹不存在,需要新建)。这样,在以后的设计文件头部加上:
Library ucxLib; Use ucxLib.ucx_2008pkg.all;
即可。从而使vhd文件看起来更像C语言,以减少代码量并提高可读性。
自定义包部分说明列表:语法表述均类似于IncDec
std_vector: 与std_logic_vector相同,修改原因是个人觉得类型名字过长。
STDZ(b) : standardization;把boolean类型转化为std_logic类型。
IncDec(cn, inc, dec):increase decrease;当inc时(inc为boolean型时表示inc=true,为std_logic型时表示inc=’1’,以下关于条件的表述均类同)cn加1计数,否则dec时减1计数;dec默认无效(IncDec(cn, inc)与IncDec(cn, inc, false)或IncDec(cn, inc, ‘0’)等效,以下关于默认无效的表述均与此类似,默认有效则反之)。
DecInc(cn, dec, inc):当dec时减1计数,否则inc时加1计数;inc默认无效。
RstIncDec(cn, rst,inc, dec):reset increase decrease;当rst时cn赋全0值,否则inc时+1,否则dec时-1;dec默认无效。
SetIncDec(cn, set,inc, dec),SetDecInc:当set时cn赋全1值,其余与上述类似。
ResetSet(q, rst, set):当rst时q赋全0值,否则当set时q赋全1值,set默认无效。
SetReset(q, set, rst):当set时q赋全1值,否则当rst时q赋全0值,rst默认无效。
LoadValue(q, v, en):当en时q赋v值。
LoadInc(cn, v, ld,inc):load increase;当ld时cn赋v值,否则inc时+1。inc默认有效。
LoadDec(cn, v, ld,dec):与LoadInc类似。
LOG2(n):n为常整数,返回值为log2(n)的整数部分。此函数主要供编译器使用。
b_and(v):v类型为std_vector,返回std_logic型,是v的所有比特and后的结果;即当输入v为全1时,返回’1’,否则返回’0’。
b_or(v):与b_and类似,不同的是返回v的所有比特or运算的结果。
b_xor(v), b_xnor(v):与上类同。
b_nand(v):等效notb_and(v)。
b_nor(v):等效notb_or(v)。
descend(v):把std_vector型的变量v以降序到0的形式返回。
例:signal v : std_vector(2 to 8);则descend(v)(1)的值为v(7)。
descend(v, n):若n>=v’length,则将v左侧补0到n宽度,以降序形式返回;否则截取v右侧n位以降序形式返回。
ascend(v):把变量v以升序的形式返回。
ascend(v, n):若n>=v’length,则将v右侧补0到n宽度,以升序形式返回;否则截取v左侧n位以升序形式返回。
例:signal v : std_vector(2 to 8);则ascend (v, 10)值为v&”000”; ascend (v, 10)(5 to 9)为v(7) &v(8) &”000”。
OneOf(a, b, sa):二选一逻辑,当sa时返回a,否则返回b。
OneOf(a, b, c, sa, sb):三选一,当sa时返回a,否则sb时返回b,否则返回c。
OneOf(v0,v1,v2,v3,sv):四选一,当sv=0时返回v0,sv=1时返回v1,sv=2时返回v2,其他返回v3。
STDV_INT(v):把std_vector型的v转换为整数返回,常用于索引。
INT_STDV(n, w):把整数n转化为比特宽w的std_vector型返回。 以上函数中,部分完成的功能在包std_logic_unsigned和std_logic_arith中已有定义。在此重新定义是为了简化或清晰。
除法器.rar
(4.42 KB)
|