在线咨询 切换到宽版
eetop公众号 创芯大讲堂 创芯人才网

 找回密码
 注册

手机号码,快捷登录

手机号码,快捷登录

搜全文
楼主: songzijian87

[求助] [求助]自己做的除法器

[复制链接]
发表于 2011-6-15 00:11:50 | 显示全部楼层
贴一个MIPS789里面用到的乘除法器。还有一个是 UCORE里面用的 ,下 一帖子上。

module muldiv(ready,rst,op1,op2,clk,dout,func);
    input         clk,rst;
    wire       sign;
    input [4:0] func ;
    input [31:0] op2, op1;
    output [31:0] dout;
    output        ready;
    reg [31:0]    quotient, quotient_temp;
    reg [63:0]    dividend_copy, divider_copy, diff;
    reg           negative_output;

    reg [63:0]    product, product_temp;

    reg [31:0]    multiplier_copy;
    reg [63:0]    multiplicand_copy;

    reg [6:0]     mul_bit,div_bit;
    wire          ready = ((mul_bit==0)&&(div_bit==0));

    wire  [31:0]  dividend, divider;

    wire [31:0]  remainder;
    wire [31:0] multiplier,multiplicand;

    reg [31:0] hi,lo;

    assign dout = (func==`ALU_MFHI)?hifunc==`ALU_MFLO)?lo:0;

    assign  remainder = (!negative_output) ?
            dividend_copy[31:0] :
            ~dividend_copy[31:0] + 1'b1;

    assign multiplier=op2;
    assign multiplicand=op1;
    assign dividend=op1;
    assign  divider = op2;
    assign sign = ((func==`ALU_MULT)||(func==`ALU_DIV));

    initial
    begin
        hi=0;
        lo=0;
    end
    always @( posedge clk /*or negedge rst */)
        if (~rst)
        begin
            mul_bit=0;
            div_bit=0;
            /*
            hi=0;
            lo=0;
            */
            negative_output = 0;
        end
        else
        begin
            if((ready)&&((func==`ALU_MULT)||(func==`ALU_MULTTU)))
            begin
                mul_bit               = 33;
                product           = 0;
                product_temp      = 0;
                multiplicand_copy = (!sign || !multiplicand[31]) ?
                                  { 32'd0, multiplicand } :
                                  { 32'd0, ~multiplicand + 1'b1};
                multiplier_copy   = (!sign || !multiplier[31]) ?multiplier :~multiplier + 1'b1;

                negative_output = sign &&
                                ((multiplier[31] && !multiplicand[31])
                                 ||(!multiplier[31] && multiplicand[31]));
            end
            if ( mul_bit > 1 )
            begin

                if( multiplier_copy[0] == 1'b1 )
                    product_temp = product_temp +multiplicand_copy;


                product = (!negative_output) ?
                        product_temp :
                        ~product_temp + 1'b1;

                multiplier_copy = multiplier_copy >> 1;
                multiplicand_copy = multiplicand_copy << 1;
                mul_bit = mul_bit - 1'b1;
            end
            else if (mul_bit == 1)
            begin
                hi =  product[63:32];
                lo =  product[31:0];
                mul_bit=0;
            end

            if((ready)&&((func==`ALU_DIV)||(func==`ALU_DIVU)))
            begin
                div_bit = 33;
                quotient = 0;
                quotient_temp = 0;
                dividend_copy = (!sign || !dividend[31]) ?
                              {32'd0,dividend} :
                              {32'd0,~dividend + 1'b1};

                divider_copy = (!sign || !divider[31]) ?
                             {1'b0,divider,31'd0} :
                             {1'b0,~divider + 1'b1,31'd0};

                negative_output = sign &&
                                ((divider[31] && !dividend[31])
                                 ||(!divider[31] && dividend[31]));
            end
            else if (div_bit > 1)
            begin
                diff = dividend_copy - divider_copy;
                quotient_temp = quotient_temp << 1;
                if( !diff[63] )
                begin
                    dividend_copy = diff;
                    quotient_temp[0] = 1'd1;
                end
                quotient = (!negative_output) ?quotient_temp :~quotient_temp + 1'b1;
                divider_copy = divider_copy >> 1;
                div_bit = div_bit - 1'b1;
            end
            else if (div_bit == 1)
            begin
                lo =  quotient;
                hi =  remainder;
                div_bit=0;
            end
        end

endmodule
回复 支持 反对

使用道具 举报

 楼主| 发表于 2011-6-17 22:49:22 | 显示全部楼层
回复 10# acgoal


抱歉,最近有考试所以没上网
   
谢谢,我发现问题了,因为计数器number改变时number的第一个值没有赋给quotient[number],所以才会出警告。已经修改完毕
回复 支持 反对

使用道具 举报

 楼主| 发表于 2011-6-18 15:16:26 | 显示全部楼层
回复 11# mcupro


    谢谢,参考了,不过好像算法差不多
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

站长推荐 上一条 /1 下一条


手机版| 小黑屋| 关于我们| 联系我们| 隐私声明| EETOP 创芯网
( 京ICP备:10050787号 京公网安备:11010502037710 )

GMT+8, 2025-9-14 16:11 , Processed in 0.015047 second(s), 3 queries , Gzip On, Redis On.

eetop公众号 创芯大讲堂 创芯人才网
快速回复 返回顶部 返回列表