用触发器或寄存器实现8位加法器的verilog 单稳态触发器代码,有没有大神会做

《EDA技术实用教程(第五版)》习题答案(第1~10章)--潘_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
评价文档:
喜欢此文档的还喜欢
《EDA技术实用教程(第五版)》习题答案(第1~10章)--潘
21年​度​最​新​的​教​材​答​案​(―0​章​)​,​老​师​给​的​,​希​望​可​以​给​师​弟​师​妹​带​来​福​音​!
阅读已结束,如果下载本文需要使用
想免费下载本文?
把文档贴到Blog、BBS或个人站等:
普通尺寸(450*500pix)
较大尺寸(630*500pix)
你可能喜欢verilog 8位触发器_搜索_中华文本库
四选一信号选择器同步复位D触发器8位数据寄器分频器的Verilog HDL设计_信息与通信_工程科技_专业资料。四选一信号选择器同步复位D触发器8位数据寄器分频器的Veril...
Verilog 实验报告——8 位全加器 8 位全加器一、 实验目的 用 verilog 语言编写一个 8 位全加器,并在 modelsim 软件上进行仿真。 二、代码 1、源代码: ...
Verilog实现Jk触发器_工学_高等教育_教育专区。文档编号: 文档编号:BAN_HW_0001...veilog触发器 2页 免费 Verilog实现的8位超前进... 2页 免费...
Verilog数字系统设计异步清零上升沿D触发器_信息与通信_工程科技_专业资料。Verilog数字系统设计异步清零上升沿D触发器Verilog 数字系统设计异步清零上升沿 D 触发器 mo...
基于verilog的8位加法器设计验证_信息与通信_工程科技_专业资料 暂无评价|0人阅读|0次下载|举报文档 基于verilog的8位加法器设计验证_信息与通信_工程科技_专业...
时序逻辑电路的 Verilog HDL 实现 一.实验要求 (1):编写 JK 触发器、8 位数据锁存器、数据寄存器的 Verilog HDL 程序,并实现其仿真及 其测试程序; (2):在...
verilog8位全加器实验报告_工学_高等教育_教育专区。Verilog 8位全加器Verilog...块只在信号进入模块后 执行 1 次而 always 块是由敏感事件作为中断来触发执行...
(D) 寄存器级 8.在 verilog 语言中,a=4b'1011,那么 &a=(D ) (A) 4b...试用verilog语言描述:图示为一个4位移位寄存器,是由四个D触发器 (分别设为U1...
Verilog实现的8位超前进位加法器_工学_高等教育_教育专区。Verilog实现的8位超前进位加法器Verilog 实现的 8 位超前进位加法器。 经过 modelsim 验证正确可用,在 DC...
EDA verilog JK触发器实验 7页 2财富值 《EDA技术_Verilog版》实验... 6页 1财富值 EDA技术与Verilog HDL实验... 3页 8财富值搜...用Verilog hdl语言计一个八位双向移位寄存器电路。-中国学网-中国IT综合门户网站
> 用Verilog hdl语言计一个八位双向移位寄存器电路。
用Verilog hdl语言计一个八位双向移位寄存器电路。
转载 编辑:李强
为了帮助网友解决“用Verilog hdl语言计一个八位双”相关的问题,中国学网通过互联网对“用Verilog hdl语言计一个八位双”相关的解决方案进行了整理,用户详细问题包括:<,具体解决方案如下:解决方案1: module fifo(clr,clk,din,LorR,dout)input clr,clk,input LorR;output [7:0]reg [7:0]assign dout=always@( posedge clk)if(clr) fifo&=0;else if(LorR) fifo&={fifo[6:0],din}; else fifo&={din,fifo[7:1]};endmodule if通过对数据库的索引,我们还为您准备了:问:用Verilog hdl语言计一个八位双向移位寄存器电路。 设计要求:要求实现8...答:module fifo(clr,clk,din,LorR,dout) input clr,clk, input LorR; output [7:0] reg [7:0] assign dout= always@( posedge clk) if(clr) fifo===========================================问:用Verilog HDL语言设计8位三态缓冲器,不愿浪费时间,所以厚着脸皮求代码答:module three_t(in, en, out); input [7:0] output [7:0] assign out = (en == 1) ? in : 8' endmodule===========================================问:其输入为两个4位操作变量a和b,以及一个3位选择信号select,输出为5位变...答:给你个参考,没有的功能自己想吧,这些很简单。 module alu ( input [2:0] a, input [2:0] b, input [2:0] sel, output reg [7:0] y ); always@(a or b or sel) begin case(sel) 3'b000: y = a + 3'b001: y = a - 3'b010: y = a * 3'b0...===========================================问:其输入为两个4位操作变量a和b,以及一个3位选择信号select,输出为5位变...答:可以这样写: module divider_4(clkin,clkout) reg[2:0] always @(posedge clkin) begin temp===========================================问:其输入为两个4位操作变量a和b,以及一个3位选择信号select,输出为5位变...答:我写的一个十进制计数,可以复位,置数,使能,双向计数,请参考 `timescale 1ns/100ps module count( clk, nrst, ncs, s, load, load_data, q ); input [3:0] load_ output [3:0]...===========================================问:1.计数器电路设计。 设计一个0~9的简单计数器。要求用Verilog HDL语言...答:上楼给的是计数器埃不是0~9计数埃我给你改改。 1、计数器 module counter (count, clk, reset); output [4:0] input clk, reg [4:0] always @ (posedge clk or posedge reset) if (reset) count ===========================================问:另有一个辅助进位AF,when A[3]+B[3] 产生进位,AF=1,else AF=0。答:不太明白你想做什么。 module adder( input wire [7:0] a1, input wire [7:0] a2; output wire [7:0] out ); assign out = asc? (a1 - a2) : (a1 + a2); endmodule===========================================问:另有一个辅助进位AF,when A[3]+B[3] 产生进位,AF=1,else AF=0。答:module add8(a,b,ci,sum,co); input [7:0] a,b; output [7:0] assign {co,sum}=a+b+ endmodule===========================================问:另有一个辅助进位AF,when A[3]+B[3] 产生进位,AF=1,else AF=0。答:Verilog HDL语言 请用行为描述方式设 我知道的肯定好 大=========================================== 不太明白你想做什么。 module adder(input wire [7:0] a1,input wire [7:0] a2;output wire [7:0] out );assign out = asc? (a1 - a2) : (a1 + a2);endmodule=========================================== module three_t(in, en, out); input [7:0] output [7:0] assign out = (en == 1) ? in : 8&#39; endmodule===========================================,结果仍然8位的话就错了,变成了+4,所以需要进行最高位补偿。但是用补码进行加减运算... 然后再将结果转化为补码。或者直接设计一个补码乘法器,用它来完成补码的乘法。 pa...===========================================--时钟上升沿触发 IF D = &000&带同步复位的D触发器: use ieee.std_logic_1164. use 下一个是带同步置位&#47;复位的D===========================================
本文欢迎转载,转载请注明:转载自中国学网: []
用户还关注
可能有帮助2.6.3 常用数字处理算法的Verilog实现
1.加法器的Verilog实现
串行加法器
组合逻辑的加法器可以利用真值表,通过与门和非门简单地实现。假设 和 表示两个加数, 表示和, 表示来自低位的进位, 表示向高位的进位。每个全加器都执行如下的逻辑表达式:&
这样可以得到加法器的一种串行结构。因此,式(2.1)所示的加法器也被称为串行加法器。如图2-20给出了一个4位串行加法器的结构示意图。
&图2-20 串行加法器的结构示意图
在无线通信的信号处理中,常常要用到多位数字量的加法运算。如果用串行加法器实现,速度较慢,而并行加法器就能满足要求,并且结构并不复杂。现在普遍使用的并性加法器是超前进位加法器,只是在几个全加器的基础上增加了一个超前进位形成逻辑,以减少由于逐步进位信号的传递所造成的时延。图2-21给出了一个4位并行加法器的结构示意图。
图2-21 串行加法器的示意图
在4位并行加法器的基础上,可以递推出16位、32位和64位的快速并行加法器。
流水线加法器
在使用了并行加法器后,仍旧只有在输出稳定后才能输入新的数进行下一次计算,即计算的节拍必须大于运算电路的延迟;此外,许多门级电路和布线的延迟会随着位数的增加而累加,因此加法器的频率还是受到了限制。但如果采用流水线,就有可能将一个算术操作分解为一些小规模的基本操作,将进位和中间值存储在寄存器中,并在下一个时钟周期内继续运算,这样就可以提高电路的利用效率。将流水线规则应用于FPGA中,只需要很少或根本不需要额外的成本。这是因为每个逻辑单元都包含两个触发器,大多数情况下这两个触发器或者没有用到,或者用于存储布线资源,那么就可以利用其来实现流水线结构。如果采用了流水线后,加法器的速度仍然不能满足需要的话,可以采用第3章中将会提到的串并转换来进一步提高计算的并行度。&&&&&&&&&由于一个slice中有两个触发器,还需要有1个触发器来作为进位输出,那么采用 级流水线,就可以构造一个最大位数为 位的加法器。&下面给出一个16位流水线加法器的代码。例2-24 16位2级流水线加法器的Verilog设计&module adder16_2(cout ,sum ,clk ,cina ,cinb ,cin) ;&&&&&&&&& input [15 :0 ]cina ,&&&&&&&&& input clk ,&&&&&&&&& output [15 :0 ]&&&&&&&&&&&&&&&&&&&&&&&&&&& reg cout1 ;&&&&&&&&& reg[7 :0 ] sum1 ;&&&&&&&&& reg[15 :0 ]&&&&&&&&& always @(posedge clk) begin // 低8 位相加;&&&&&&&&&&&&&&& {cout1 , sum1} = {cina [7], cina [ 7 : 0 ]} + {cinb[7], cinb [ 7 : 0 ]} +&&&&&&&&& end&&&&&&&&& always @(posedge clk) begin // 高8 位相加,并连成16位&&&&&&&&&&&&&&& {cout ,sum} = {{cina [15], cina [15 :8 ] }+ {cinb [15], cinb[15 :8]} + cout1 , sum1} ;&&&&&&&&& end&endmodule&上述程序经过synplify Pro综合后,得到如图2-22所示的RTL级结构图。
2-22 16位加法器的RTL结构图
在ModelSim 6.2b中完成仿真,其结果如图2-23所示,正确地实现了16比特加法。
图2-23 16位加法器的RTL结构图
2.乘法器的Verilog实现
串行乘法器
两个N位二进制数x 、y 的乘积,最简单的方法就是利用移位操作来实现,用公式可以表示为:&
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& (2.3)
这样输入量随着k的位置连续地变化,然后累加&。&例2-25 用Verilog实现一个8位串行乘法器&module ade (clk, x, y, p);&&input [7:0] x,&output [15:0]&&&&& reg [15:0]&&parameter s0=0, s1=1, s2=2;&reg [2:0]&reg [1:0]&reg [15:0] p1, // 比特位加倍&&&&& reg [7:0] y_&always @(posedge clk) begin&&&&&&&&&&&&&&&&&& case (state)&&&&&&&&&&&&&&&&&&&&&&&s0 : begin // 初始化&&&&&&&&&&&&&&&&&&&&&&&&&&&&& y_reg &=&&&&&&&&&&&&&&&&&&&&&&&&&&&&& state &= s1;&&&&&&&&&&&&&&&&&&&&&&&&&&&&& count = 0;&&&&&&&&&&&&&&&&&&&&&&&&&&&&& p1 &= 0;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&t &= {{8{x[7]}},x};&&&&&&&&&&&&&&&&&&&end&&&&&&&&&&&&&&&&&& s1 : begin // 处理步骤&&&&&&&&&&&&&&&&&&&&&& if (count == 7) //判断是否处理结束&&&&&&&&&&&&&&&&&&&&&&&&&& state &= s2;&&&&&&&&&&&&&&&&&&&&&&&else begin&&&&&&&&&&&&&&&&&&&&&&&&&& if (y_reg[0] == 1)&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& p1 &= p1 +&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& y_reg &= y_reg && 1; //移位&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&t &= t && 1;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& count &= count + 1;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& state &= s1;&&&&&&&&&&&&&&&&&&&&&&&&&& end&&&&&&&&&&&&&&&&&&&&&& end&&&&&&&&&&&&&&&&&&&&&&&s2 : begin&&&&&&&&&&&&&&&&&&&&&&&&&&& p &= p1;&&&&&&&&&&&&&&&&&&&&&&&&&&& state &= s0;&&&&&&&&&&&&&&&&&&&&&&&&end&&&&&&&&&&&&&&&&&&&&& endcase&&&&&&&&&&& end&endmodule&上述程序在Synplify Pro中综合后,得到如图2-24所示的RTL级结构示意图。
图2-24 串行乘法器的RTL结构图
图2-25给出了串行乘法器模块在ModelSim中的仿真结果,验证了功能的正确性。
&图2-25 串行乘法器的局部仿真结果示意图
从仿真结果可以看出,上述串行乘法器,速度比较慢,时延很大,但这种乘法器的优点是所占用的资源是所有类型乘法器中最少的,在低速的信号处理中有着广泛的应用。
流水线乘法器
一般的快速乘法器通常采用逐位并行的迭代阵列结构,将每个操作数的N位都并行地提交给乘法器。但是一般对于FPGA来讲,进位的速度快于加法的速度,这种阵列结构并不是最优的。所以可以采用多级流水线的形式,将相邻的两个部分乘积结果再加到最终的输出乘积上,即排成一个二叉树形式的结构,这样对于N位乘法器需要log2(N)级来实现。一个8位乘法器,如图2-26所示。
图2-26流水线乘法器结构图
例2-26 用Verilog HDL实现一个4位的流水线乘法器&module mul_addtree(mul_a, mul_b, mul_out, clk, rst_n);&&&&&&&&&&parameter MUL_WIDTH = 4;&&&&&&&&& parameter MUL_RESULT = 8;&&&&&&&&& input [MUL_WIDTH-1 : 0] mul_a;&&&&&&&&& input [MUL_WIDTH-1 : 0] mul_b;&&&&&&&&&&&&&&&&&& input rst_n;&&&&&&&&& output [MUL_RESULT-1 : 0] mul_&&&&&&&&& reg [MUL_RESULT-1 : 0] mul_&&&&&&&&& reg [MUL_RESULT-1 : 0] stored0;&&&&&&&&& reg [MUL_RESULT-1 : 0] stored1;&&&&&&&&& reg [MUL_RESULT-1 : 0] stored2;&&&&&&&&& reg [MUL_RESULT-1 : 0] stored3;&&&&&&&&& reg [MUL_RESULT-1 : 0] add01;&&&&&&&&& reg [MUL_RESULT-1 : 0] add23;&&&&&&&&& always @ (posedge clk or negedge rst_n)&&&&&&&&& begin&&&&&&&&&&&&&&& if(!rst_n)&&&&&&&&&&&&&&&&&&& begin //初始化寄存器变量&&&&&&&&&&&&&&&&&&&&&&&mul_out &= 8'b;&&&&&&&&&&&&&&&&&&&&&& stored0 &= 8'b;&&&&&&&&&&&&&&&&&&&&&& stored1 &= 8'b;&&&&&&&&&&&&&&&&&&&&&& stored2 &= 8'b;&&&&&&&&&&&&&&&&&&&&&& stored3 &= 8'b;&&&&&&&&&&&&&&&&&&&&&& add01 &= 8'b;&&&&&&&&&&&&&&&&&&&&&& add23 &= 8'b;&&&&&&&&&&&&&&&&&&& end&&&&&&&&&&&&&&& else&&&&&&&&&&&&&&&&&&& begin //实现移位相加&&&&&&&&&&&&&&&&&&&&&&& stored3 &= mul_b[3]?{1'b0,mul_a,3'b0}: 8'b0;&&&&&&&&&&&&&&&&&&&&&&& stored2 &= mul_b[2]?{2'b0,mul_a,2'b0}: 8'b0;&&&&&&&&&&&&&&&&&&&&&&&&stored1 &= mul_b[1]?{3'b0,mul_a,1'b0}: 8'b0;&&&&&&&&&&&&&&&&&&&&&&& stored0 &= mul_b[0]?{4'b0,mul_a}: 8'b0;&&&&&&&&&&&&&&&&&&&&&&& add01 &= stored1 + stored0;&&&&&&&&&&&&&&&&&&&&&&&&add23 &= stored3 + stored2;&&&&&&&&&&&&&&&&&&&&&&& mul_out &= add01 + add23;&&&&&&&&&&&&&&&&&& end&&&&&&&&&&&&&& end&endmodule&上述程序在Synplify Pro软件中综合后,得到如图2-27所示的RTL级结构示意图。
图2-27 流水线乘法器的RTL结构示意图
&图2-28给出了流水线乘法器模块在ModelSim中的仿真结果,验证了功能的正确性。&
图2-28 流水线乘法器的局部仿真结果示意图
从仿真结果可以看出,上述流水线乘法器比串行加法器的速度快很多,在非高速的信号处理中有着广泛的应用。至于高速信号的乘法一般需要利用FPGA芯片中内嵌的硬核DSP单元来实现。&3.无符号除法器的Verilog实现&两个无符号二进制数(如正整数)相除的时序算法是通过&减并移位&的思想来实现的,即从被除数中重复地减去除数,直到已检测到余数小于除数。这样可以通过累计减法运算的次数而得到商;而余数是在减法运算结束时被除数中的剩余值。当除数较小时,这种基本电路都必须进行多次减法,因此效率都不高。图2-29给出了一种更加高效的除法器基本结构[3]。在进行两个数相除的运算时,通常采用的步骤是调整除数与被除数使其最高位相对齐,然后反复地从被除数中减去除数,并将除数向被除数的最低位移动,且在高效除法器结构中可以并行运行这些操作步骤。而在具体的硬件实现中,是通过将被除数寄存器的内容不断地向除数的最高位移动来完成除法运算的。&
图2-29 8位被除数,4位除数的无符号二进制字自调整除法器
在设计除法器结构的过程中应特别小心。在图中的减法运算步骤中,必须要将除数和被除数对齐,这取决于它们的相应大小和每个字的最高一位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位的高效除法器module divider(clock,reset,word1,word2,Start,quotient,remainder,Ready,Error);&&&&&&&&& parameter L_divn = 8;&&&&&&&&& parameter L_divr = 4;&&&&&&&&&&parameter S_idle = 0, S_Adivr = 1, S_Adivn = 2, S_div = 3, S_Err =4;&&&&&&&&& parameter L_state = 3, L_cnt = 4, Max_cnt = L_divn - L_&&&&&&&&&&input [L_divn-1 : 0] word1; //被除数数据通道&&&&&&&&&&input [L_divr-1 : 0] word2; //除数数据通道&&&&&&&&& input Start, clock,&&&&&&&&& output [L_divn-1 : 0] //商&&&&&&&&& output [L_divn-1 : 0] //余数&&&&&&&&&&output Ready, E&&&&&&&&& reg [L_state-1 : 0] state, next_&&&&&&&&& reg Load_words, Subtract, Shift_dividend, Shift_&&&&&&&&&&reg [L_divn-1 : 0]&&&&&&&&& reg [L_divn : 0] //扩展的被除数&&&&&&&&& reg [L_divr-1 : 0]&&&&&&&&&&reg [L_cnt-1 : 0] num_shift_dividend, num_shift_&&&&&&&&& reg [L_divr : 0]&&&&&&&&& wire MSB_divr = divisor[L_divr-1];&&&&&&&&& wire Ready = ((state == S_idle) && !reset);&&&&&&&&& wire Error = (state == S_Err);&&&&&&&& &wire Max = (num_shift_dividend== Max_cnt + num_shift_divisor);&&&&&&&&& wire sign_bit = comparison[L_divr];&&&&&&&&&&& or dividend or divisor or MSB_divr) begin //从被除数中减去除数&&&&&&&&&&&&&&& case(state)&&&&&&&&&&&&&&&&&&&&&& S_Adivr: if(MSB_divr == 0)&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& &comparison = dividend[L_divn : L_divn - L_divr] +&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& && {1'b1, ~(divisor && 1)} + 1'b1;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& else&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& comparison = dividend[L_divn : L_divn - L_divr] +&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& {1'b1, ~divisor[L_divr-1 : 0]} + 1'b1;&&&&&&&&&&&&&&&&&&&&&&&default: comparison = dividend[L_divn : L_divn - L_divr] +&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& {1'b1, ~divisor[L_divr-1 : 0]} + 1'b1;&&&&&&&&&&&&&& endcase&end&//将余数移位来对应于整体的移位&assign remainder = (dividend[L_divn-1 : L_divn-L_divr]) - num_shift_&always@(posedge clock) begin&&&&&&&& if(reset)&&&&&&&&&&&&&&&&&&& state &= S_&&&&&&&&& else&&&&&&&&&&&&&&&&&&& state &= next_&end&//次态与控制逻辑&always@(state or word1 or word2 or state or comparison or sign_bit or Max) begin&&&&&&&&&&&&&& Load_words = 0;&&&&&&&&&&&&&& Shift_dividend = 0;&&&&&&&&&&&&&& Shift_divisor = 0;&&&&&&&&&&&&&& Subtract = 0;&&&&&&&&&&&&&&&case(state)&&&&&&&&&&&&&&&&&&&&&&& S_idle: case(Start)&&&&&&&&&&&&&&&&&&&&&&&&&&&&& &0: next_state = S_&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&1: if(word2 == 0)&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& next_state = S_E&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& else if(word1) begin&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& next_state = S_A&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& Load_words = 1;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&end&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& else&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& next_state = S_&&&&&&&&&&&&&&&&&&&&&&& endcase&&&&&&&&&&&&&&&&&& S_Adivr: case(MSB_divr)&&&&&&&&&&&&&&&&&&&&&&&&&& 0: if(sign_bit == 0) begin&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& next_state = S_A&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& Shift_divisor = 1; //可移动除数&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& end&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& else if(sign_bit == 1) begin&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& next_state = S_A //不可移动除数&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& end&&&&&&&&&&&&&&&&&&&&&&&&&&&1: next_state = S_&&&&&&&&&&&&&&&&&&&&&&&& endcase&&&&&&&&&&&&&&&&&& S_Adivn: case({Max, sign_bit})&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& 2'b00: next_state = S_&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&2'b01: begin&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& next_state = S_A&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& Shift_dividend = 1;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& end&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& 2'b10: begin&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& next_state = S_&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& Subtract = 1;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& end&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& 2'b11: next_state = S_&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& endcase&&&&&&&&&&&&&&&&&&& S_div: case({Max, sign_bit})&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& 2'b00: begin&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& next_state = S_&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& Subtract = 1;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& end&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& 2'b01: next_state = S_A&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& 2'b10: begin&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& next_state = S_&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& Subtract = 1;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& end&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& 2'b11: begin&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& next_state = S_&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& Shift_dividend = 1;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& end&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& endcase&&&&&&&&&&&&&&&&&&&&&&&&&& default: next_state = S_E&&&&&&&&&&&&&&&&&&&endcase&&&&&&&&&&& end&&&&&&&&&&&&&clock)begin //寄存器,数据通道操作&&&&&&&&&&&&&&&&&&&&&&&& if(reset)begin&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& divisor &= 0;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& dividend &= 0;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& quotient &= 0;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& num_shift_dividend &= 0;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& num_shift_divisor &= 0;&&&&&&&&&&&&&&&&&&&&&&&&&&end&&&&&&&&&&&&&&&&&&&&&&&&& else if(Load_words == 1) begin&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& dividend &= word1;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& divisor &= word2;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& quotient &= 0;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& num_shift_dividend &= 0;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& num_shift_divisor &= 0;&&&&&&&&&&&&&&&&&&&&&&&&&&end&&&&&&&&&&&&&&&&&&&&&&&&& else if(Shift_divisor) begin&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&divisor &= divisor && 1;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& num_shift_divisor &= num_shift_divisor + 1;&&&&&&&&&&&&&&&&&&&&&&&& end&&&&&&&&&&&&&&&&&&&&&&&& else if(Shift_dividend) begin&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&dividend &= dividend && 1;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&quotient &= quotient && 1;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& num_shift_dividend &= num_shift_dividend + 1;&&&&&&&&&&&&&&&&&&&&&&&&& end&&&&&&&&&&&&&&&&&&&&&&&&& else if(Subtract) begin&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& dividend[L_divn : L_divn-L_divr] &=&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& quotient[0] &= 1;&&&&&&&&&&&&&&&&&&&&&&&&& end&&&&&&&&&&&&&&&&&end&endmodule&上述程序经过Synplify综合后得到如图2-31所示的RTL级结构。&
图2-31 无符号高效除法器的RTL级结构图
在ModelSim中经过仿真,其仿真结果如图2-31所示。仿真中输入了两组数据,且在输出信号Ready为高时输出相应的商和余数。当被除数为57,除数为6时,可以看到商和余数分别为9和3;当被除数为98,除数为9时,可以看到商和余数分别为10和8。这表明上述程序的正确性。&
图2-32 无符号高效除法器的仿真波形
4. CORDIC算法的Verilog实现
CORDIC算法的原理
CORDIC算法可以将多种难以用硬件电路直接实现的复杂运算分解为统一的简单的移位、加迭代运算,而且结构规则、运算周期可以预测、适合于VLSI实现。许多数字信号处理算法,如DXT、FFT、复数滤波器、格形滤波器、基于Givens旋转的QR分解、奇异值/特征值分解、最小二乘求解以及线性系统求解等,都很容易用圆周旋转或双曲旋转来描述其基本的操作,因此都可以用CORDIC算法得到很好地实现。因此以CORDIC为核心的FPGA应用日益受到人们的重视。&&&&&&&&&CORDIC是用于计算广义矢量旋转的一种迭代方法。由J.D.Volder于1959年提出的[6],主要用于三角函数、双曲函数、指数和对数的运算[7,8]。该算法使得矢量的旋转和定向运算不需要三角函数表以及乘法、开方、反三角函数等复杂的运算,仅需要进行加减和移位即可。1971年,Walther提出了统一的CORDIC算法[9],引入了参数m将CORDIC实现的三种迭代模式:三角运算、双曲运算和线性运算统一于一个表达式下,形成目前所用到的CORDIC算法最基本的数学基础。该算法的基本思想是通过一系列固定的、与运算基数相关的角度不断偏摆以逼近所需的旋转角度,可由下列等式进行描述:&
&&&&&&&&&&&&&&&&&&&&&&&&(2.4)&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& (2.5)
X(n),Y(n) 和Z(n)为所期望得到的函数。根据m=1 、-1或0,可以将上面的运算分别称为圆周旋转运算、双曲旋转运算或线形旋转运算。&其中:
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& (2.6)
使结果Z(n)的旋转称为旋转模式(rotation mode),使结果Y(n)=0的旋转称为向量模式(vector mode)。为了能达到所要求的结果,各旋转角 要满足下列条件:
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& (2.7)&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& (2.8)
&&&&&&&&=0或1,&和&是非负整数值。&&&&&&&& 最通常的微转角选择方法为:&&&&&&&& 当m=1 时,&;当m=-1 时&;当m=0时&。&&&&&&&& 此时每一级迭代运算可以简化为:
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& (2.9)&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& (2.10)&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& (2.11)
可以仅由加法、减法和移位来实现,本级的微转角旋转方向&由上一级运算结果和所处的旋转模式决定。&在所有级旋转之后须执行一次模校正运算,即乘以模校正因子&,一旦如上旋转一系列微转角之后,无论每个微转角的方向如何,对于确定的m值,当n趋向无穷大时,模校正因子趋近于一个极限值km&。因为CORDIC算法本身是一种逐位逼近算法,所以一般不论旋转级数n是多少,都直接应用其极限的二进制码作为模校正因子。&对于不同的m值、工作模式和初始值,可以产生不同的结果,如表2-3所示。
表2-3 CORDIC在不同情况下的输出
CORDIC算法的Verilog实现
CORDIC算法的实现方式有两种:简单状态机法和高速全流水线处理器,前者主要采用折叠/迭代方式,后者采用展开/流水线式。&1. 简单状态机结构&如果计算时间不严格的话,可以采用图2-33所示的状态机。在每个周期内都将精确地计算一次式(2.9) ~ 式(2.11)所示的迭代。其中最复杂的就是两个筒形移位器。
图2-33 CORDIC算法状态机
2. 流水线CORDIC结构&流水线CORDIC虽然占用的硬件资源较多,但是流水结构可以提高数据的吞吐率(Throughput)。对于大多数的DSP算法来说,存在很多同一条指令连续处理很长一段数据的情况,此时高吞吐率更有意义。从当前VLSI的发展趋势上来看,芯片内的门资源相对富裕,对流水线CORDIC的实现规模约束很小。此外,流水线CORDIC不存在迭代式CORDIC的反馈回路,使得单元结构更加规则,有利于VLSI实现。&图2-34给出CORDIC算法的一般流水线结构:
图2-34 CORDIC算法的一般流水线结构
(原文地址:)
阅读(...) 评论()

我要回帖

更多关于 verilog 单稳态触发器 的文章

 

随机推荐