常见数字处理算法的Verilog实现Word格式.docx

上传人:b****5 文档编号:17235791 上传时间:2022-11-29 格式:DOCX 页数:12 大小:281.79KB
下载 相关 举报
常见数字处理算法的Verilog实现Word格式.docx_第1页
第1页 / 共12页
常见数字处理算法的Verilog实现Word格式.docx_第2页
第2页 / 共12页
常见数字处理算法的Verilog实现Word格式.docx_第3页
第3页 / 共12页
常见数字处理算法的Verilog实现Word格式.docx_第4页
第4页 / 共12页
常见数字处理算法的Verilog实现Word格式.docx_第5页
第5页 / 共12页
点击查看更多>>
下载资源
资源描述

常见数字处理算法的Verilog实现Word格式.docx

《常见数字处理算法的Verilog实现Word格式.docx》由会员分享,可在线阅读,更多相关《常见数字处理算法的Verilog实现Word格式.docx(12页珍藏版)》请在冰豆网上搜索。

常见数字处理算法的Verilog实现Word格式.docx

output[15:

0]sum;

outputcout;

regcout;

regcout1;

reg[7:

0]sum1;

reg[15:

always(posedgeclk)begin//低8位相加;

{cout1,sum1}={cina[7],cina[7:

0]}+{cinb[7],cinb[7:

0]}+cin;

end 

always(posedgeclk)begin//高8位相加,并连成16位 

{cout,sum}={{cina[15],cina[15:

8]}+{cinb[15],cinb[15:

8]}+cout1,sum1};

endmodule 

上述程序经过synplifyPro综合后,得到如图2-22所示的RTL级结构图。

2-2216位加法器的RTL结构图

在ModelSim6.2b中完成仿真,其结果如图2-23所示,正确地实现了16比特加法。

图2-2316位加法器的RTL结构图

2.乘法器的Verilog实现

∙串行乘法器

两个N位二进制数x、y的乘积,最简单的方法就是利用移位操作来实现,用公式可以表示为:

(2.3)

这样输入量随着k的位置连续地变化,然后累加 

例2-25用Verilog实现一个8位串行乘法器 

moduleade(clk,x,y,p);

inputclk;

input[7:

0]x,y;

output[15:

0]p;

reg[15:

parameters0=0,s1=1,s2=2;

reg[2:

0]count;

reg[1:

0]state;

0]p1,t;

//比特位加倍 

reg[7:

0]y_reg;

always(posedgeclk)begin 

case(state) 

s0:

begin//初始化 

y_reg<

=y;

state<

=s1;

count=0;

p1<

=0;

t<

={{8{x[7]}},x};

end 

s1:

begin//处理步骤 

if(count==7)//判断是否处理结束 

=s2;

elsebegin 

if(y_reg[0]==1) 

p1<

=p1+t;

=y_reg>

>

1;

//移位 

=t<

<

count<

=count+1;

s2:

begin 

p<

=p1;

state<

=s0;

endcase 

上述程序在SynplifyPro中综合后,得到如图2-24所示的RTL级结构示意图。

图2-24串行乘法器的RTL结构图

图2-25给出了串行乘法器模块在ModelSim中的仿真结果,验证了功能的正确性。

图2-25串行乘法器的局部仿真结果示意图

从仿真结果可以看出,上述串行乘法器,速度比较慢,时延很大,但这种乘法器的优点是所占用的资源是所有类型乘法器中最少的,在低速的信号处理中有着广泛的应用。

∙流水线乘法器

一般的快速乘法器通常采用逐位并行的迭代阵列结构,将每个操作数的N位都并行地提交给乘法器。

但是一般对于FPGA来讲,进位的速度快于加法的速度,这种阵列结构并不是最优的。

所以可以采用多级流水线的形式,将相邻的两个部分乘积结果再加到最终的输出乘积上,即排成一个二叉树形式的结构,这样对于N位乘法器需要log2(N)级来实现。

一个8位乘法器,如图2-26所示。

图2-26流水线乘法器结构图

例2-26用VerilogHDL实现一个4位的流水线乘法器 

modulemul_addtree(mul_a,mul_b,mul_out,clk,rst_n);

parameterMUL_WIDTH=4;

parameterMUL_RESULT=8;

input[MUL_WIDTH-1:

0]mul_a;

0]mul_b;

inputclk;

inputrst_n;

output[MUL_RESULT-1:

0]mul_out;

reg[MUL_RESULT-1:

0]stored0;

0]stored1;

0]stored2;

0]stored3;

0]add01;

0]add23;

always(posedgeclkornegedgerst_n) 

if(!

rst_n) 

begin//初始化寄存器变量 

mul_out<

=8'

b0000_0000;

stored0<

stored1<

stored2<

stored3<

add01<

add23<

else 

begin//实现移位相加 

=mul_b[3]?

{1'

b0,mul_a,3'

b0}:

8'

b0;

=mul_b[2]?

{2'

b0,mul_a,2'

=mul_b[1]?

{3'

b0,mul_a,1'

=mul_b[0]?

{4'

b0,mul_a}:

add01<

=stored1+stored0;

add23<

=stored3+stored2;

=add01+add23;

上述程序在SynplifyPro软件中综合后,得到如图2-27所示的RTL级结构示意图。

图2-27流水线乘法器的RTL结构示意图

图2-28给出了流水线乘法器模块在ModelSim中的仿真结果,验证了功能的正确性。

图2-28流水线乘法器的局部仿真结果示意图

从仿真结果可以看出,上述流水线乘法器比串行加法器的速度快很多,在非高速的信号处理中有着广泛的应用。

至于高速信号的乘法一般需要利用FPGA芯片中内嵌的硬核DSP单元来实现。

3.无符号除法器的Verilog实现 

两个无符号二进制数(如正整数)相除的时序算法是通过“减并移位”的思想来实现的,即从被除数中重复地减去除数,直到已检测到余数小于除数。

这样可以通过累计减法运算的次数而得到商;

而余数是在减法运算结束时被除数中的剩余值。

当除数较小时,这种基本电路都必须进行多次减法,因此效率都不高。

图2-29给出了一种更加高效的除法器基本结构[3]。

在进行两个数相除的运算时,通常采用的步骤是调整除数与被除数使其最高位相对齐,然后反复地从被除数中减去除数,并将除数向被除数的最低位移动,且在高效除法器结构中可以并行运行这些操作步骤。

而在具体的硬件实现中,是通过将被除数寄存器的内容不断地向除数的最高位移动来完成除法运算的。

无符号二进制字自调整除法器

在设计除法器结构的过程中应特别小心。

在图中的减法运算步骤中,必须要将除数和被除数对齐,这取决于它们的相应大小和每个字的最高一位1的相对位置。

同样,被除数寄存器也应向左扩展一位,以适应可能出现的已调整的除法寄存器内容初始值超过被除数寄存器中相应4位值的情况,在这种情况下,在进行减法操作之前,应从被除数的最高位移出一个1。

例如(1100)2与(0111)2相除,应首先将被除数向左移,为下一步减法运算调整好被除数。

因此,该机器的控制器会变得更加复杂,而且要包括能使除数和被除数移动的控制信号,如图2-29所示。

该物理结构将调整除数字与被除数的8位数据通道中的最左边4位对齐。

在操作中,被除数字不断地从右向左移动,而且每一步都要从已调整的被除数的相应位中减去除数,这种操作取决于除数是否比被除数选定部分的对应值小。

调整机器使得从被除数中减去的不是除数而是除数与2的幂的最大乘积,这样在当除数较小时就可以消去一些需要重复进行的减法运算。

这种调整被称为是自调整的,因为它在一个除法运算序列的开始就能自动判断是否需要调整除数或被除数,这取决于它们最左非0位的相对位置。

在除法运算中经常性地启动对两个字的调整使得其最高位为1的方法效率较低,因为这可能会需要更多的移位。

所采用的方法是在一开始就将除数移到被除数的最左非0位(而不是被除数的最低位)。

有两种需要对数据通路字进行初始调整的情况:

(1)被除数最左4位的值小于除数的值(例如(1100)2除以(1110)2),

(2)除数的最低位为0,同时除数字节可以向左移动,而且仍然可以去除被除数(例如(1100)2除以(0101)2)。

对于前者,应将被除数依次向左移动1位直到扩展1位的被除数的最左5位等于或大于除数,或者直到不能再移位为止。

而对于后者,则应将除数向左移直到再移动所得到的字节不能去除被除数字节的最左4位为止(不包括扩展位)。

余数位在除法运算序列结束时的物理位置取决于被除数是否进行了移位调整。

因此,可将调整移位记录下来,并用来控制状态机调整在执行序列结束后的余数值。

图2-30给出了自调整除法器的状态转移图[3]。

在一个给定状态下,从一个状态节点出发的支路中所使用的控制标记仅适于该支路,而在其他没有明确使用该标记离开当前状态的支路中被视为是不成立的。

在任何离开一个状态节点的支路中都没有出现的标记被认为是无关紧要的。

只有S_idle状态下才会给出复位信号,而在其他的所有状态上复位信号均被视为是异步动作。

该机器的状态与它的动作有关。

S_Adivr状态下Shift_divisor的动作是将除法调整到被除数的最高非0位;

S_Adivr状态下Shift_dividend的动作将调整被除数寄存器以进行减法运算;

S_div状态下同时进行实际的减法运算和许多移位操作。

状态S_Adivn和S_Adivr下变量Max将检测所允许的最大移位何时发生。

图2-30自调整除法器的状态转移图

例2-27用Verilog实现一个被除数为8位,除数为4位的高效除法器moduledivider(clock,reset,word1,word2,Start,quotient,remainder,Ready,Error);

parameterL_divn=8;

parameterL_divr=4;

parameterS_idle=0,S_Adivr=1,S_Adivn=2,S_div=3,S_Err=4;

parameterL_state=3,L_t=4,Max_t=L_divn-L_divr;

input[L_divn-1:

0]word1;

//被除数数据通道 

input[L_divr-1:

0]word2;

//除数数据通道 

inputStart,clock,reset;

output[L_divn-1:

0]quotient;

//商 

0]remainder;

//余数 

outputReady,Error;

reg[L_state-1:

0]state,next_state;

regLoad_words,Subtract,Shift_dividend,Shift_divisor;

reg[L_divn-1:

reg[L_divn:

0]dividend;

//扩展的被除数 

reg[L_divr-1:

0]divisor;

reg[L_t-1:

0]num_shift_dividend,num_shift_divisor;

reg[L_divr:

0]parison;

wireMSB_divr=divisor[L_divr-1];

wireReady=((state==S_idle)&

&

!

reset);

wireError=(state==S_Err);

 

wireMax=(num_shift_dividend==Max_t+num_shift_divisor);

wiresign_bit=parison[L_divr];

always(state 

ordividendordivisororMSB_divr)begin//从被除数中减去除数 

case(state) 

S_Adivr:

if(MSB_divr==0) 

parison=dividend[L_divn:

L_divn-L_divr]+{1'

b1,~(divisor<

1)}+1'

b1;

L_divn-L_divr]+{1'

b1,~divisor[L_divr-1:

0]}+1'

default:

parison=dividend[L_divn:

b1,~divisor[L_divr-1:

endcase 

//将余数移位来对应于整体的移位 

assignremainder=(dividend[L_divn-1:

L_divn-L_divr])-num_shift_divisor;

always(posedgeclock)begin 

if(reset) 

=S_idle;

=next_state;

//次态与控制逻辑 

always(stateorword1orword2orstateorparisonorsign_bitorMax)begin 

Load_words=0;

Shift_dividend=0;

Shift_divisor=0;

Subtract=0;

case(state) 

S_idle:

case(Start) 

0:

next_state=S_idle;

1:

if(word2==0) 

next_state=S_Err;

elseif(word1)begin 

next_state=S_Adivr;

Load_words=1;

case(MSB_divr) 

0:

if(sign_bit==0)begin 

Shift_divisor=1;

//可移动除数 

elseif(sign_bit==1)begin 

next_state=S_Adivn;

//不可移动除数 

next_state=S_div;

S_Adivn:

case({Max,sign_bit}) 

2'

b00:

b01:

Shift_dividend=1;

b10:

Subtract=1;

b11:

S_div:

2'

next_state=S_div;

next_state=

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高中教育 > 数学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1