Verilog HDL的故事 之 整数除法器
- 格式:pdf
- 大小:1.09 MB
- 文档页数:23
基于Verilog计算精度可调的整数除法器的设计
叶显阳;张海勇;皮代军;秦水介
【期刊名称】《现代电子技术》
【年(卷),期】2009(32)3
【摘要】传统整数除法算法采用多次相减的方法来实现运算,相减的过程耗费了大量时钟脉冲,而且对运算结果的最后一位没有进行处理.针对传统的整数除法器,提出一种基于Verilog计算精度可调的整数除法器的设计方法,运用移位、循环减法和四舍五入的方法对数据进行处理,提高了处理速度和精确度.用Cadence公司的NC-Verilog仿真器对所设计的除法器进行仿真验证,结果显示该除法器达到了预期功能.
【总页数】2页(P146-147)
【作者】叶显阳;张海勇;皮代军;秦水介
【作者单位】贵州省光电子技术及应用重点实验室,贵州,贵阳,550025;贵州省光电子技术及应用重点实验室,贵州,贵阳,550025;贵州省光电子技术及应用重点实验室,贵州,贵阳,550025;贵州省光电子技术及应用重点实验室,贵州,贵阳,550025
【正文语种】中文
【中图分类】TN402
【相关文献】
1.基于Verilog的FPGA整数分频器设计及仿真 [J], 张泽;刘慧慧;田涛;梁天泰;周英杰
2.一种占空比可调的新型整数半整数分频器设计 [J], 靳钊;乔丽萍;王聪华;王江安;郭晨
3.H.264/AVC中整数DCT变换量化模块的Verilog设计 [J], 沈劲桐;张卫
4.可任意设定计算精度的整数除法器的VHDL设计 [J], 朱卫华;郑留平
5.一种非写回整数除法器的并行结构设计 [J], 刘冀
因版权原因,仅展示原文概要,查看原文内容请购买。
Verilog除法器设计(包含单步设计和流水线设计)1.单步设计:单步设计是最简单的一种除法器设计,其原理是将被除数和除数逐位进行比较和计算,直到得到商和余数。
首先,需要定义Verilog模块的输入和输出端口。
输入包括被除数(dividend)和除数(divisor),输出包括商(quotient)和余数(remainder)。
同时,还需要定义一些辅助信号,如计数器和比较器。
```verilogmodule Dividerinput [N-1:0] dividend,input [N-1:0] divisor,output [N-1:0] quotient,output [N-1:0] remainder```在单步设计中,使用一个循环进行逐位比较和计算,直到得到商和余数。
在每一步循环中,被除数向左移动一位,并与除数进行比较。
如果被除数大于或等于除数,则商的对应位为1,否则为0。
然后,将商的对应位赋值给商,并从被除数中减去除数的相应部分。
最后,余数更新为被除数。
```verilogreg [N-1:0] temp_dividend;reg [N-1:0] temp_remainder;reg [N-1:0] temp_quotient;integer i;temp_dividend = dividend;temp_remainder = {N{1'b0}};temp_quotient = {N{1'b0}};for (i = 0; i < N; i = i+1) begintemp_remainder = temp_dividend;if (temp_remainder >= divisor) begin temp_quotient[i] = 1'b1;temp_dividend = temp_remainder - divisor; endtemp_dividend = temp_dividend << 1;endquotient = temp_quotient;remainder = temp_dividend;endendmodule```以上就是单步设计的Verilog除法器代码。
verilog算术运算符除法Verilog算术运算符之除法Verilog语言是一种硬件描述语言(HDL),用于进行数字电路的建模和设计。
在Verilog中,算术运算符用来执行数学运算,其中包括加法、减法、乘法和除法等基本运算。
本文将重点讨论Verilog中的除法运算符以及相关的实现细节。
1.除法运算除法运算是一种基本的算术运算,用于计算两个数的商。
在Verilog中,除法运算符用符号“/”表示,例如a/b。
要注意的是,Verilog中的除法运算符是整数除法运算符,即计算结果将会是一个整数。
2.确定除法运算符的数据类型在Verilog中,除法运算符需要明确操作数的数据类型,以便进行正确的计算。
比如,如果我们要执行一个32位宽的整数除法,我们需要声明操作数的数据类型为32位。
例如:reg[31:0]a,b,result;assign result=a/b;3.整数除法的行为在Verilog中,整数除法是指用除法运算符进行计算时只保留整数部分的结果。
例如,如果a=7,b=2,那么a/b的结果将会是3,而不是3.5。
4.除数为0的情况在Verilog中,对于除数为0的情况,实际行为是不确定的。
这意味着,当除数为0时,计算结果可能是不可预测的,因此应避免除数为0的情况。
5.除法的位宽在Verilog中,除法运算符的行为与操作数的位宽相关。
例如,如果我们对两个32位宽的操作数执行整数除法运算,则结果也将是32位宽的。
换句话说,整数除法的结果位宽与操作数相同。
6.处理除法运算的余数在除法运算中,除法运算符还可以获得除法的余数。
在Verilog中,使用取模(mod)运算符“%”可以获得除法运算的余数。
例如,如果我们想要计算7除以2的余数,则可以使用以下代码进行计算:reg[31:0]a,b,result_rem;assign result_rem=a%b;7.除法运算的优先级在Verilog中,算术运算符的优先级与常规数学运算符的优先级相似。
Verilog代码乘法除法1. 引言Verilog是一种硬件描述语言,用于设计和建模数字电路。
在数字电路中,乘法和除法是常见的运算操作。
本文将介绍如何使用Verilog编写乘法和除法的代码,并提供一些示例来帮助读者更好地理解。
2. 乘法2.1 基本原理乘法是一种基本的算术运算,用于计算两个数的积。
在数字电路中,我们可以使用逻辑门和触发器来实现乘法运算。
2.2 Verilog代码示例下面是一个简单的Verilog代码示例,用于实现两个8位无符号整数的乘法运算:module multiplier (input [7:0] a,input [7:0] b,output reg [15:0] result);always @(*) beginresult = a * b;endendmodule上述代码定义了一个名为multiplier的模块,该模块有两个输入端口a和b,以及一个输出端口result。
在always @(*)块中,我们使用乘法操作符将输入端口a和b相乘,并将结果存储在输出端口result中。
2.3 测试与验证为了测试上述的乘法模块,我们可以编写一个测试台,输入一些测试用例,并验证输出结果是否正确。
module multiplier_test;reg [7:0] a;reg [7:0] b;wire [15:0] result;multiplier dut(.a(a),.b(b),.result(result));initial begin// Test case 1: a = 5, b = 3a = 5;b = 3;#10; // Wait for 10 time unitsif (result !== 15)$display("Test case 1 failed");// Test case 2: a = 10, b = 0a = 10;b = 0;#10; // Wait for 10 time unitsif (result !== 0)$display("Test case 2 failed");// Add more test cases here...endendmodule上述代码定义了一个名为multiplier_test的测试台模块。
基于Verilog计算精度可调的整数除法器的设计除法器是技术领域的基础模块,在电子设计中得到广泛应用。
目前,实现除法器的办法有硬件实现和软件实现两种办法。
硬件实现的办法主要是以硬件的消耗为代价,从而有实现速度快的特点。
用硬件的办法来实现除法器的讨论无数,如利用微处理器实现迅速乘除法运算,实现二进制除法运算,模拟除法器等;而通过软件实现的除法器算法,可以大大提高器件的工作频率和设计的灵便性,可以从总体上提高设计性能,而设计高效有用的算法是除法器的关键,故除法器的算法讨论成为现今热点。
目前,软件方面主要是通过减法算法来实现除法运算,把被除数作为被减数,除数作为减数,作减法,直到被减数小于减数为止,记录能够相减的次数即得到商的整数部分。
将所得的余数乘以10作为被减数,除数作为减数,作减法,差重新置入被减数,反复相减,直到被减数小于减数为止,记录能够相减的次数即得到商的非常位数值。
依此继续下去,可得到商的百分位数值,千分位数值,……,要精确到哪一位,就依次做到哪一位。
此办法的缺点是速度慢,而且最后一位的精度不高,为了克服以上的缺点,这里设计一种算法在软件上改进了除法器运算的精确性和处理速度。
1 设计办法对于随意给定的两个整数fenzi和fenmu,设fenzi为被除数,fenmu 为除数。
为了得到两个数相除的十进制结果,本设计主要通过下面的算法来实现,如果要保留小数点后面的n位有效数字,首先把fenzi 乘以10的n次方,赋值给寄存器变量dataO;接着把fenmu分离乘以10的(n+m),(n+m一1),(n+m一2),…,1,O次方分离赋值给(n+m+1)个不同的变量data(n+m+1),data(n+m),…,datal,其中m是fenzi 和fenmu的位数之差(当fenzi的位数多于fenmu时,m为正,否则为负);先求出商的最高位的值,假如dataO大于data(n+m+1),则计数器自动加1,再把dataO和data(n+m+1)的差值赋给data0,再相减直到data0的值小于data(n+m+1),此时计数器的计数值就是最高位的值;依此用同样的办法继续下去,就可得到各个位上的值。
verilog 乘法除法Verilog是一种硬件描述语言,广泛用于数字电路设计和验证。
在Verilog中,乘法和除法是两个常用的运算操作,用于实现数字电路中的乘法器和除法器。
本文将介绍Verilog中的乘法和除法的实现原理和方法。
一、Verilog中的乘法实现在Verilog中,乘法操作可以通过使用乘法运算符“*”来实现。
乘法运算符可以用于两个整数或两个实数之间的乘法运算。
具体实现乘法操作的方式可以有多种,下面将介绍一种基于加法和移位的乘法实现方法。
1. 基于加法的乘法实现基于加法的乘法实现方法是一种常见的乘法器实现方式。
它的原理是将被乘数和乘数分别拆分成若干个部分,并使用加法器将这些部分进行加法运算,最终得到乘法结果。
具体实现时,可以将被乘数和乘数分别拆分成若干个位数,并使用加法器将对应位数的部分进行加法运算。
每次运算时,先将被乘数的某一位与乘数的每一位相乘,然后将这些乘积通过加法器进行累加。
最终得到的累加结果就是乘法的结果。
2. 基于移位的乘法实现基于移位的乘法实现方法是另一种常见的乘法器实现方式。
它的原理是通过移位和累加的方式进行乘法运算。
具体实现时,先将被乘数和乘数进行位数对齐,然后从最低位开始,逐位地将被乘数与乘数的对应位相乘,并将乘积累加到最终的乘法结果中。
每次乘法运算完成后,将被乘数和乘数向左移位一位,继续进行下一位的乘法运算,直到所有位都计算完毕。
二、Verilog中的除法实现在Verilog中,除法操作可以通过使用除法运算符“/”来实现。
除法运算符可以用于两个整数或两个实数之间的除法运算。
具体实现除法操作的方式可以有多种,下面将介绍一种基于减法和移位的除法实现方法。
1. 基于减法的除法实现基于减法的除法实现方法是一种常见的除法器实现方式。
它的原理是通过多次减法运算来逼近除法的结果。
具体实现时,先将除数与被除数进行比较,如果除数小于被除数,则将除数与被除数相减,并将商的对应位设置为1。
循环整数除法器******学院**级***系姓名:***学号:********指导老师:****目录一、除法器的基本原理与改进第1页二,程序源代码及QuartusII仿真第4页三,测试代码及Modelsim仿真第8页四,DC综合部分第11页五.Astro版图及解释第14页一,除法器的基本原理与改进本设计是基于传统的除法器的基础上改进而来的。
传统除法器的设计:一、先取除数和被除数的正负关系,然后正值化被除数。
传统除法器因为需要递减的关系,所以除数就取负值的补码,方便操作。
二、被除数递减除数,每一次的递减,商数递增。
三、直到被除数小于除数,递减过程剩下的是余数。
四、输出的结果根据除数和被除数的正负关系。
例如:10除以3其操作流程就是:1,10-3 余7>3;2,7-3 余4>3;3,4-3 余1<3。
即经过三次的运算比较,得出10÷3=3并且余1。
此次运算需要三个时钟周期来进行比较运算,显然,随着被除数的增大,其所需的时钟周期会呈递增趋势,加入,被除数过大的话,其过多的时钟消耗将会减慢运算速度。
改进的循环型除法器循环型的除法器,就是位操作的除法器。
循环型的除法器是典型的除法器,假设除数和被除数的位宽为N位,那么除法器就会循环N次的除法操作。
这样时钟消耗就不会随着被除数的增加而增加了,提高了计算的速度。
假设被除数A = 7(0111),除数B = 2 ( 0010 ),它们均为4位位宽。
那么操作空间就是 temp 就是 2 * Width。
temp[ Width - 1 : 0 ]是用来填充被除数,temp[ Width * 2 - 1:Width -1 ] 是用与除数递减操作。
为了方便操作,我们建立 5位位宽的s空间用来寄存除数B的负值补码形式。
此外还要考虑同步操作,temp[ Width * 2 - 1:Width -1 ] 和除数B的递减操作应该发生别的空间,亦即diff空间。
verilog 乘法除法Verilog是一种硬件描述语言,广泛应用于数字电路设计和验证。
本文将介绍Verilog中的乘法和除法原理及其在实际应用中的实现。
一、Verilog乘法器原理与实现1.原理Verilog乘法器的原理是基于位级运算。
输入的两个二进制数按位进行与运算,得到乘积的位级表示。
然后通过移位和加法运算,将位级乘积转换为最终的整数乘积。
2.实现Verilog乘法器的实现主要分为三个部分:全加器、位级乘法器和移位器。
全加器用于处理乘数和被乘数的各位与运算结果;位级乘法器用于计算乘数和被乘数的各位与运算;移位器用于调整位级乘积的位数。
3.实例以下是一个简单的Verilog乘法器实例:```module multiplier(input [7:0] a, b [7:0], output [15:0] result);wire [15:0] partial_product;wire [15:0] temp_result;// 位级乘法器wire [15:0] product [7:0];genvar i;generatefor (i = 0; i < 8; i = i + 1) beginassign product[i] = a * b[i];endendgenerate// 移位器assign partial_product = {product[7], product[6:0]};// 全加器assign temp_result = partial_product + result;assign result = temp_result;endmodule```二、Verilog除法器原理与实现1.原理Verilog除法器的原理是采用迭代算法,将除法问题转化为加法和减法问题。
除数和被除数按位进行与运算,得到余数的位级表示。
然后通过循环移位和加法运算,将余级表示转换为最终的整数商和余数。
Verilog实现加减乘除计算器主要内容: 1. 按键按下后,进⾏加减乘除操作 2. Verilog往TXT⽂本⽂件中写⼊数据 3. 完成计算模块 4. 最终实现加减乘除计算器1. 实现按键按下后,选择option,进⾏加减乘除操作,除法计算结果为商&余数module jsq(clk,rst_n,key,option,x,y,result,quotient,remainder);parameter N = 16; // 输⼊数的位数input clk; // 输⼊时钟input rst_n; // 低电平有效的复位(清零)input key;input [1:0]option;input [N-1:0] x;input [N-1:0] y;output [2*N-1:0] result;output [N-1:0] quotient; //输出计算的商output [N-1:0] remainder; //输出计算的余数reg [2*N-1:0] result_r;reg [N-1:0] quotient_r,remainder_r;always @ (posedge clk or negedge rst_n)beginif (!rst_n)beginresult_r <= 1'b0;quotient_r <= 1'b0;remainder_r <= 1'b0;endelsebeginif (key == 1'b0)begin//按键按下case(option)2'b00: result_r = x + y;2'b01: result_r <= x + (~y + 1'b1);2'b10: result_r = x * y;2'b11: //result_r = x / y;beginquotient_r = x / y;remainder_r = x % y;endendcaseendelsebegin// 按键释放result_r <= 1'b0;quotient_r <= 1'b0;remainder_r <= 1'b0;endendendassign result = result_r ;assign quotient= quotient_r;assign remainder = remainder_r;endmoduleView Code`timescale 1ns/1ps`define clock_period 20module jsq_tb;reg clk;reg rst_n;reg key;reg [1:0]option;reg [15:0] x,y;wire [31:0] result;wire [15:0] quotient;wire [15:0] remainder;initial beginclk = 1'b1;rst_n = 1'b0;key = 1'b1; // 复位时,按键释放# 20//复位20nsrst_n = 1'b1;# 20key = 1'b0;option = 2'b10;# 100key = 1'b1;# 20key = 1'b0;option = 2'b11;# 100// key = 1'b1;// # 20$stop;endalways #(`clock_period/2) clk = ~clk; //50Mjsq #(.N(16)) jsq_0(.clk(clk),.rst_n(rst_n),.key(key),.option(option),.x(x),.y(y),.result(result),.quotient(quotient),.remainder(remainder));initial beginx = 0;repeat(20)#(`clock_period) x = {$random}%100; //通过位拼接操作{}产⽣0—59范围的随机数endinitial beginy = 0;repeat(20)#(`clock_period) y = {$random}%50;end/*integer i;initial beginx = 0;y = 0;for(i = 0; i < 20; i = i + 1)begin//利⽤$random系统函数产⽣随机数。
verilog 乘法除法摘要:一、引言1.介绍Verilog 语言2.Verilog 中的乘法和除法运算二、Verilog 乘法运算1.语法和规则2.举例说明3.注意事项三、Verilog 除法运算1.语法和规则2.举例说明3.注意事项四、乘法和除法运算的比较1.运算速度2.资源消耗3.适用场景五、结论1.Verilog 乘法和除法运算的应用领域2.选择乘法或除法运算的依据正文:一、引言Verilog 是一种硬件描述语言,广泛应用于数字电路设计、验证和仿真。
在Verilog 中,乘法和除法运算是非常基本的操作,对于构建复杂数字电路具有重要意义。
本文将详细介绍Verilog 中的乘法和除法运算。
二、Verilog 乘法运算1.语法和规则在Verilog 中,乘法运算使用“*”符号表示。
乘法操作数可以是数字、变量或者表达式。
例如:```wire [7:0] a, b;a = 8"h12 * 8"h34; // 8 位乘法```2.举例说明以下是一个8 位乘法器的Verilog 代码示例:```module multiplier_8bit(input [7:0] a,input [7:0] b,output [15:0] result);wire [15:0] partial_products [15:0];// 生成partial_productsgen_partial_products: for (genvar i = 0; i < 16; i++) beginassign partial_products[i] = a * b[i];end// 求和wire [15:0] sum0, sum1, sum2, sum3, sum4, sum5, sum6, sum7;wire [15:0] sum8, sum9, sum10, sum11, sum12, sum13, sum14, sum15;assign sum0 = {16"h0, partial_products[0]};assign sum1 = {partial_products[1], 16"h0} + sum0;assign sum2 = {partial_products[2], 16"h0} + sum1;assign sum3 = {partial_products[3], 16"h0} + sum2;assign sum4 = {partial_products[4], 16"h0} + sum3;assign sum5 = {partial_products[5], 16"h0} + sum4;assign sum6 = {partial_products[6], 16"h0} + sum5;assign sum7 = {partial_products[7], 16"h0} + sum6;assign sum8 = {partial_products[8], 16"h0} + sum7;assign sum9 = {partial_products[9], 16"h0} + sum8;assign sum10 = {partial_products[10], 16"h0} + sum9;assign sum11 = {partial_products[11], 16"h0} + sum10;assign sum12 = {partial_products[12], 16"h0} + sum11;assign sum13 = {partial_products[13], 16"h0} + sum12;assign sum14 = {partial_products[14], 16"h0} + sum13;assign sum15 = {partial_products[15], 16"h0} + sum14;assign result = sum15;endmodule```3.注意事项(1)Verilog 中的乘法运算不支持直接对变量或表达式进行溢出处理,需要通过其他方法实现溢出控制。
前言硬件除法器的种类固然很多,如果“减掉”组合逻辑组成的硬件除法器,然后再“除与”整数除法器,最后经过“Verilog HDL的过滤”,剩下的精华就是这些。
整数除法器呀!整数除法器呀!它真的把笔者搞得很伤,说一句老实话整数乘法器和整数除法器的种类相比,正的“一个不如一个”。
为了它笔者还拿起课本...收获还是很少。
在普通的设计下,除法器的出场机会是“几率问题”,但是它作为Verilog HDL语言的练习对象,奉献可真不小。
在硬件除法器哪一篇中,出现了相关的步骤i“时间点”概念和“把大象放进冰箱”概念的区别,为了完善它,笔者又继续追加了这一本笔记。
实际上整数除法器是没有什么东西好写的,因为可以用在整数除法器的原理就除了“传统除法器”和“循环型除法器”以外,其他的都必须涉及小数(笔者很讨厌小数)。
如果硬是要插一直脚进入小数的世界,就不得不面对浮点数的问题。
故,写这本笔记的初衷就本末倒置了。
所以呀,这一本笔记不可能像整数乘法器那一本笔记一样内容丰富。
话说,整数乘法器也好还是整数除法器也好,它们都不是笔者所要的重点。
因为在实际应用中,组合逻辑所建立的乘|法乘法器,效率远远大于笔者所写的东西(参考书看到,好像是30~60ns延迟时间)。
正如整数乘法器那本笔记里,笔者所说的。
笔记的初衷是为了更了解Verilog HDL语言。
坏话当前,如果读者是寻找某个效率的硬件除法器的话,这本笔记非常不适合。
反之,如果读者是一位对Verilog HDL语言有爱的朋友的话,这一本笔记一定会成为好朋友。
akuei26-12-2010上目录前言 (02)目录 (03)第二章整数除法器 (04)2.01传统的除法器 (04)实验八:传统除法器 (05)2.02循环型除法器 (09)实验九:传统乘法器改进 (11)2.03循环除法运算的原理 (15)实验十:从原理到实现的循环除法器 (19)总结 (23)第二章整数除法器2.1传统的除法器整数除法器没有像整数乘法器那样丰富的种类,整数除法器的分类仅有传统型的循环型之分。
老实说笔者也真的有点郁闷,翻了很多文章,论文,参考书,然后再衡量与Verilog HDL语言,笔者得到的都是零碎的线索。
说一句真心话,真的真的有够郁闷“好想抽根烟,看夕阳”这样的心情。
坏话当前,这一章笔记的内容会是非常短......时光又回到笔者的小学时候,在数学这门课中,笔者最喜欢就是减法,最讨厌就是除法。
喜欢减法的原因,因为小学的减法没有整数的概念,任何被减数小于减数都是零,所以笔者特别钟爱。
但是当数学课本出现“除法”的字眼,小学的笔者忽然间觉得“它”很碍眼。
小时候的笔者还记得,老师教我们(笔者小时候的同学)除法是“乘法+减法”。
(估计读者的小时候也是一样)但是那时候的笔者不晓得“只要有减法就能攻略除法”。
传统除法的概念和传统乘法的概念是一样的,乘法是累加过程,反之除法是递减过程,直到减数大于被减数,剩下的就是余数。
先来简单的扫盲:除数Divisor,被除数Dividend,商数Quotient,余数Reminder。
再来是苹果的故事:假设有一只72HP(被除数)的苹果怪兽,勇者akuei2,一次的攻击是减少10HP(除数)。
但是勇者它不杀生,当苹果怪兽余下的HP小于勇者的攻击容量,勇者的攻击结束。
在上面“攻击过程中”,勇者一共攻击了7次,那么苹果怪兽也伤(商数)了7次,苹果怪兽余下(余数)的HP是2。
为什么笔者会说一个就连小朋友也知道的故事?你知道吗,当你翻开任何一本有关除法器的参考书,你就会看到一条非常普遍的除法约束公式:被除数=商数·除数+余数这一条公式就和上面的故事有关系。
实际上这条公式非常的猥琐,笔者非常不喜欢它,笔记也不要讨论它,笔者只是告示读者,有这样“一条”东西的存在。
上面有关勇者大战苹果怪兽的故事就是传统除法器的概念。
反之,和我们小时候所学习的除法方式有莫大的差别,那是一种“查表+心算”的除法方式。
我们必须清楚,计算器是一个笨蛋,硬件比计算机更笨蛋,它什么都不会。
在这里笔者需要强调一点:组合逻辑所组成的硬件除法器效率上远远是超过Verilog HDL语言所“编写”的硬件除法器(虽然Verilog HDL语言也可以以组合逻辑的方式去描述硬件除法器)。
但是这一本笔记的重点是“掌握Verilog HDL语言”。
笔者衷心希望读者们不要会错意,这本笔记确确实实是为Verilog HDL语言量身打造的,硬件除法器是其次。
硬件除法器和硬件乘法器同样也会遇上“除数和被除数的正负关系”的问题。
13/2=商6,余1-13/2=商-6,余113/-2=商-6,余1-13/-2=商6,余14-2=4+2补除数和被除数的正负关系反映了它们是“异或”的关系。
为了设计的方便,在作除法的时候被除数取正值,除数去负值的补码,因为传统的除法就是被除数递减于除数的概念,所以除数取负值的补码的方式可以方便设计。
然而结果是负值还是正值根据原来除数和原来被除数的正负关系再作决定。
实验八:传统除法器传统除法器的设计非常单纯:一、先取除数和被除数的正负关系,然后正值化被除数。
传统除法器因为需要递减的关系,所以除数就取负值的补码,方便操作。
二、被除数递减与除数,每一次的递减,商数递增。
三、直到被除数小于除数,递减过程剩下的是余数。
四、输出的结果根据除数和被除数的正负关系。
divider_module.v第7~13行是该模块的输入和输出,采用仿顺序操作的结构。
第19~25行是该模块所使用的寄存器。
Dend用来寄存被除数的正值,Dsor用来寄存除数负值的补码,Q用来寄存商数,isNeg用来寄存除数和被除数的正负关系。
在步骤0(40~47行),取得被除的正值和除数负值的补码(42~43行),44行取得除数和被除数的正负关系。
清理Q寄存器后(45行),i递增以示下一个步骤。
步骤1(49~51行),第51行表示了,除法的递减操作。
被除数每一次被除数递减,Q 寄存器都会递加。
第50行的if条件表示了,除法操作的结束(当被除数小于除数)。
根据isNeg的逻辑(除数和被除数的正负关系)来决定商数的结果是正值还是负值。
然后步骤i递增。
步骤2~3是产生完成信号(53~57行)。
divider_module.vt.vt文件的写法,笔者就不多说了。
自己看着办吧。
仿真结果:仿真结果如上。
哎~仿真图暴露了传统除法器的弱点。
不一样的被除数,就有不一样的时钟消耗。
实验说明:无论是传统的乘法器还是传统的除法器。
它们都有不好的一面,只要除数(乘数)稍微大了一点,它就要“多吃”时钟。
但是传统的乘法器还好,还可以优化,相反的传统的除法器就有点不妙了...它无法改进也无法优化。
实验结论:传统除法器的好处就是简单,但是实际的用途非常低。
因为它对时钟的消耗是根据除数的“数量”来作决定......2.2循环型除法器循环型的除法器,如果用笔者的话来说,就是位操作的除法器。
循环型的除法器是典型的除法器,假设除数和被除数的位宽为N位,那么除法器就会循环N次的除法操作。
根据每一种除法操作的特点,求商得余。
典型的循环型除法器,有分为可恢复和不可恢复。
我们知道无论是乘法器还是除法器,都有一个操作空间,对吧?所谓可恢复,当它完成某种条件,操作空间的值又恢复到初始化的状态,反之不可恢复的意思则是相反。
循环型的除法器,可恢复也好还是不可恢复也好...这一点也不重要,因为在Verilog HDL语言的眼里,也是几段代码的故事。
最重要的是那一种的循环型的除法器最“养眼”,笔者就选谁。
循环型的除法器的种类在网络上尽是千奇八怪。
笔者在很偶然的情况下,发现其中一种的循环型除法器。
故,是老外的东西,话说老外真的不简单。
为了尊重原创者,就直接引用该除法器的原名字吧!Streamlined divider!来,再说一次!Streamlined divider!"Streamlined"是什么意思?笔者百度,谷歌一下还是搞不清楚那是什么?估计有特别的意义吧!?就像笔者给自己的建模习惯名为低级建模一样。
该除法器的思路很简单:假设被除数A=7(0111),除数B=2(0010),它们均为4位位宽。
那么操作空间就是Temp就是2*Width。
Temp[Width-1:0]是用来填充被除数,Temp[Width*2-1:Width-1]是用与除数递减操作。
为了方便操作,我们建立5位位宽的s空间用来寄存除数B的负值补码形式。
此外还要考虑同步操作,Temp[Width*2-1:Width-1]和除数B的递减操作应该发生别的空间,亦即Diff空间。
Diff空间和Temp操作空间拥有同样的位宽。
reg[7:0]Temp;reg[7:0]Diff;reg[4:0]s;首先初始化Temp空间和s空间。
Temp空间的[Width-1:0]填入被除数A,然而s 空间用于寄存除数B负值的补码形式。
最后顺便清理Diff空间。
Temp<={4'd0,A};s<=B[3]?{B[3],B}?{~B[3],~B+1'b};//如果除数B为负值,就直接填入,//否则转换为负值后填入。
Diff<=8'd0;s空间寄存B的负值的动作,其实是“小空间向大空间转换+B绝对负值化”。
接下来的动作,是核心的部分。
每一次的操作,一、在Diff空间先取Temp[Width*2-1:Width-1]-B或者Temp[7:3]+s二、然后判断Diff空间的“最高位”,亦即符号位,是逻辑1还是逻辑0。
三、如果是逻辑1表示Temp[7:3]的值小于除数B,Temp空间左移一位补0。
反之如果是逻辑0,表示Temp[7:3]的值大于除数B,Temp空间被赋予Diff空间的值,并且左移一位补1。
case(i)......1,2,3,4://因为除数B和被除数A的位宽均为4位,所以循环4次。
beginDiff=Temp+{s,3'b0};//“=”表示当前步骤取得结果if(Diff[7])Temp<={Temp[6:0],1'b0};else Temp<={Diff[6:0],1'b1};i<=i+1'b1;end当经过4次的循环操作后。
Temp空间的[Width-1:0]是商数,[Width*2-1:Width]是余数。
在这里,重点是“=”这一段代码,Diff取得的即时结果是在当前步骤,而不是在该步骤的未来。
assign Quotient=Temp[3:0];assign Reminder=Temp[7:4];初始化Temp=00000111s=11110Diff=00000000;第一次操作Diff<=Temp+{s,3'b0};Diff=00000000+11110000 =11110000判断Diff[7],是逻辑1,Temp左移一位然后补0。