《基于FPGA的正整数除法器设计.doc》由会员分享,可在线阅读,更多相关《基于FPGA的正整数除法器设计.doc(5页珍藏版)》请在金锄头文库上搜索。
1、1.顶层模块timescale 1ns / 1ps/ Company: 西安电子科技大学/ Engineer: piger朱/ / Create Date: 16:08:42 05/11/2012 / Design Name: 基于FPGA的正整数除法器设计(被除数8位,除数4位)/ Module Name: div / Project Name: div/ Target Devices: virtex-5/ Tool versions: ISE12.4 modelsim6.5se/ Description: 除法运算的过程就是被除数不断的减去除数,直到二者的差为负数为止/ 但这样做有一个缺点
2、,比如100/100,只需要减一次就能得出结果,/ 而100/1需要减100次才能得出结果,如果一个时钟周期做一次减法的/ 话,100/1需要100个时钟周期,效率太低了!我们可以这样做/ 以23/3为例,23(用a表示)的二进制为0001_0111,3(用b表示)的/ 二进制为0011,首先设置一个16为的寄存器reg16, 用以辅助计算/ 令reg16=8b0,a=0000_0000, 0001_0111, 每个周期令/ reg16左移一位,如果reg16的高8位(reg1615:8)大于b, 则令/ reg1615:8=reg15:8-b,同时令reg16的最低位(reg160)/ 等于
3、1; 如果reg16的高8位小于b,则reg16:8保持不变,同时令/ reg160=0.如此重复8个周期,也就是reg16左移八次之后,/ reg167:0中存储的值就是最终的商,reg1615:81的值就是/ 最终的余数。至于为什么会这样,大家把这个流程走一边自然就能明白了/ Dependencies: / Revision: / Revision 0.01 - File Created/ Additional Comments: /module div(clk, rst, start, dividend, divisor, quotient, remainder, sample, err
4、or);input clk;input rst;input start;input7:0 dividend;input3:0 divisor;output7:0 quotient;output7:0 remainder;output sample;output error;reg15:0 divn;reg3:0 divr;reg1:0 state;reg2:0 counter;reg do_sig;parameter IDLE = 2b00, ERROR = 2b01, SHIFT = 2b10;always (posedge clk)beginif(!rst) begindivn = 0;d
5、ivr = 0;counter = 0;state = IDLE;endelse begincase(state)IDLE: begincase(start)0: state = IDLE;1: begindivn = 8b0, dividend 1;divr = divisor;counter = 0;do_sig = 0;if(divisor = 0)state = ERROR;elsestate = SHIFT;endendcaseendSHIFT: begincounter = divisor) begindivn = divn15:8 - divr, divn7:0 1;divn0
6、= 1;endelse begindivn = divn 1;divn0 = 0;endif(counter = 7) beginstate = IDLE;do_sig = 1;endelsestate = SHIFT;endERROR: begin/state = IDLE;end default: state 1;assign sample = do_sig;assign error = (state = ERROR);endmodule2.测试文件timescale 1ns / 1psmodule div_tb;/ Inputsreg clk;reg rst;reg start;reg
7、7:0 dividend;reg 3:0 divisor;/ Outputswire 7:0 quotient;wire 7:0 remainder;wire sample;wire error;integer i;/ Instantiate the Unit Under Test (UUT)div uut (.clk(clk), .rst(rst), .start(start), .dividend(dividend), .divisor(divisor), .quotient(quotient), .remainder(remainder), .sample(sample), .error
8、(error);initial begin/ Initialize Inputsclk = 0;rst = 1;start = 0;dividend = 23;divisor = 3;i = 0;#30 rst = 0;#100 rst = 1; start = 1;#10000 $stop; endalways #50 clk = clk;always (negedge clk) beginif(!rst) begindividend = 23;divisor = 3;endelse beginif(i = 9) begindividend = $random%256;divisor = $random%16;i = 1;endelsei = i + 1;endendendmodule3.仿真波形(dividend表示被除数,divisor表示除数,quotient表示商,remainder表示余数,sample表示对最终结果的采样,如图中13/13,采样点处的值为商=1,余数=0;101/2,采样点处的值为商=50,余数=1,从而确定了结果的正确性。从结果中还可以看出,不管是多少除以多少,都只需要9个时钟周期就能得出结果))