一种FPGA整数除法器

假设被除数与除数都是八位数据,这里的算法是:
将被除数,扩展成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;
//end

parameter 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
     end
end             


//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 ps
module divison_my_vlg_tst();
// constants                                           
// general purpose registers
// test vector input registers
reg 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;  //一直开启计算

end

initial begin
    #200 $stop;

end

endmodule

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

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值