一种FPGA整数除法器

来源:互联网 发布:mysql增加约束 编辑:程序博客网 时间:2024/04/27 15:25

假设被除数与除数都是八位数据,这里的算法是:
将被除数,扩展成16位的数据,低8位为被除数的值,高八位的值全为0。有开始信号,对16位数据data赋值,然后开始运算。比较data的高八位和除数的值,如果大于0,说明被除数大,将此时商置1,赋值给data的最低位,然后将被除数高八位减去除数。然后将data向左移位一位,继续比较。最终计算8次后。Data的高8位数据就为所求的余数,低八位就为所求的商。
这里写图片描述

具体的代码:

module divison_my#(    parameter W = 16,  //扩展的位敊         parameter N = 8    //输入的除数和被除数的位数    )(    input            clk,    input            rst_n,    input   [N-1:0] dividend,   //输入被除敊     input   [N-1:0] divisor,    //输入除数    input           start,      //输入开始计算信及      output  [N-1:0] quotient,   //输出啊       output  [N-1:0] remainder,  //输出余数    output     reg  ready,      //该信号为1时,才允许开始计箊        output     reg  busy,       //输出忙信及     output     reg  finish      //输出计算借宿信号    );//reg [N-1:0] dividend;//reg [N-1:0] divisor;//always @(posedge clk or negedge rst_n)begin//  dividend<=78;//  divisor<=34;//endparameter idle      = 3'b000;parameter start_div = 3'b001;parameter shift     = 3'b010;parameter done      = 3'b110;reg [2:0]   state;reg [W-1:0] data;reg [W-1:0] data_reg;reg [5:0]   n_reg;  //存储计算的次敊always @(posedge clk or negedge rst_n)begin    if(!rst_n)begin        state<=idle;        ready<=1'b1;    end    else begin    case(state)        idle:begin            if(start==1'b1 && ready==1'b1)begin            data_reg<=data;            finish<=1'b0;            //if(start==1)begin             //只有在空闲状态,开始信号才有效                              state<=shift;                data_reg<={{W-N{1'b0}},dividend}; //赋初倊                             n_reg<=N;            end        end        shift:begin            data_reg={data_reg[W-2:0],1'b0}; //注意这里是阻塞赋值=            n_reg<=n_reg-1'b1;            if(data_reg[W-1:N]>=divisor)begin                data_reg[0]<=1'b1;                data_reg[W-1:N]<=data_reg[W-1:N]-divisor;                  end            if(n_reg=='d1)  //移位结束后,状态跳转                state<=done;                                                                        end        done:begin            finish<=1'b1;            ready<=1'b0;            state<=idle;      end           endcase     endend             //assign quotient  =  data_reg[N-1:0];//assign remainder =  data_reg[W-1:N];assign quotient  = finish ? data_reg[N-1:0] : quotient;assign remainder = finish ? data_reg[W-1:N] : remainder;endmodule

测试文件是:

`timescale 1 ps/ 1 psmodule divison_my_vlg_tst();// constants                                           // general purpose registers// test vector input registersreg clk;reg [39:0] dividend;reg [39:0] divisor;reg rst_n;reg start;// wires                                               wire busy;wire finish;wire [39:0]  quotient;wire ready;wire [39:0]  remainder;// assign statements (if any)                          divison_my i1 (// port map - connection between master ports and signals/registers       .busy(busy),    .clk(clk),    .dividend(dividend),    .divisor(divisor),    .finish(finish),    .quotient(quotient),    .ready(ready),    .remainder(remainder),    .rst_n(rst_n),    .start(start));always #1 clk = ~clk;       //产生时钟initial begin    clk = 0;     rst_n = 0;//   dividend = 40'd7681245184;  //   divisor = 40'd5732674;   dividend = 8'd78;     divisor = 8'd34;   start = 0;   #100  rst_n = 1;     start = 1;  //一直开启计算endinitial begin    #200 $stop;endendmodule

最终的仿真结果:
这里写图片描述

0 0
原创粉丝点击