fpga中 + - * / 怎么用位运算表示

2019-07-16 01:29发布

=-*/在FPGA中占用资源太大,怎么通过位运算实现这些,谢谢
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
3条回答
多瑙河鱼鱼
1楼-- · 2019-07-16 06:03
+-*/在fpga中占用资源太大,怎么通过位运算实现这些,谢谢
zwl773993221
2楼-- · 2019-07-16 10:19
加:判断加数最低位,若为1则被加数加一,为0被加数不变,然后加数右移一位,重复判断最低位;
减:是把减数取反加一后,按加法进行计算;
这样说你也不会明白,我还是用一个乘法的例子给你说明吧;除法也是一样,都是通过移位实现的;称为booth算法移位乘法器:module booth_multiplier_module
(
        input                        clk,
        input                        rstn,
       
        input                        Start_Sig,
        input[7:0]        A,
        input[7:0]        B,
       
        output                Done_Sig,
        output[15:0]Product,
       
        output[7:0]        SQ_a,
        output[7:0]        SQ_s,
        output[16:0]SQ_p
);
/********************************/
reg [3:0]                i;
reg [7:0]                a;//result of A
reg [7:0]                s;//reverse result of A
reg[16:0]                p;//operation register
reg [3:0]                X;
reg                                isDone;

always @(posedge clk or negedge rstn)
        if(!rstn)
                begin
                        i                                <= 4'd0;
                        a                                <= 8'd0;
                        s                                <= 8'd0;
                        p                                <= 17'd0;
                        X                                <= 4'd0;
                        isDone                <= 1'b0;
                end
        else if(Start_Sig)
                case(i)
                        0:
                                begin
                                        a                <= A;
                                        s                <= (~A + 1'b1);
                                        p                <= {8'd0,B,1'b0};
                                        i                <= i + 1'b1;
                                end
                        1:
                                begin
                                        if(p[1:0] == 2'b01)
                                                p        <= {p[16:9] + a,p[8:0]};
                                        else if(p[1:0] == 2'b10)
                                                begin
                                                        p        <= {p[16:9] + s,p[8:0]};
                                                        i        <= i + 1'b1;
                                                end
                                end
                        2:
                                if(X ==8)
                                        begin
                                                X                 <= 4'd0;
                                                i                <= i + 1'b1;
                                        end
                                else
                                        begin
                                                p                <= {p[16],p[16:1]};
                                                X                <= X + 1'b1;
                                                i                <= i - 1'b1;
                                        end
                        3:
                                begin
                                        isDone        <= 1'b1;
                                        i                        <= i + 1'b1;
                                end
                        4:
                                begin
                                        isDone        <= 1'b0;
                                        i                        <= 4'd0;
                                end
                endcase
/*************************************/
assign         Done_Sig                = isDone;
assign        Product                = p[16:1];

/********************/
assign        SQ_a           = a;
assign   SQ_s                = s;
assign        SQ_p          = p;

endmodule
zwl773993221
3楼-- · 2019-07-16 15:20
再给你一个除法器:整两个都是整数除法器,你可以用数试一试:
module streamlined_divider_module
(
        input                        CLK,
        input                        RSTn,
       
        input                        Start_Sig,
        input [7:0]        Dividend,
        input [7:0]        Divisor,
       
        output                Done_Sig,
        output [7:0]Quotient,
        output [7:0]Reminder,
       
        /***************************/
        output[15:0]SQ_Diff,
        output[15:0]SQ_Temp
);
        /****************************/
        reg [3:0]        i;
        reg [8:0]        s;
        reg[15:0]        Temp;
        reg[15:0]        Diff;
        reg                        isNeg;
        reg                        isDone;
       
        always @(posedge CLK or negedge RSTn)
                if(!RSTn)
                        begin       
                                i                                <= 4'd0;
                                s                                <= 9'd0;
                                Temp                        <= 16'd0;
                                Diff                        <= 16'd0;
                                isNeg                        <= 1'b0;
                                isDone                <= 1'b0;
                        end
                else if(Start_Sig)
                        begin
                                case(i)
                                        0:
                                                begin
                                                        isNeg        <= Dividend[7]^Divisor[7];
                                                        s                <= Divisor[7]?{1'b1,Divisor}:{1'b1,~Divisor+1'b1};
                                                        Temp        <= Dividend[7]?{8'd0,~Dividend + 1'b1}:{8'd0,Dividend};
                                                        Diff        <= 16'd0;
                                                        i                <= i + 1'b1;
                                                end
                                        1,2,3,4,5,6,7,8:
                                                begin       
                                                        Diff        =        Temp + {s,7'd0};
                                                       
                                                        if(Diff[15])
                                                                Temp<= {Temp[14:0],1'b0};
                                                        else
                                                                Temp<= {Diff[14:0],1'b1};
                                                                i        <= i + 1'b1;
                                                end
                                        9:
                                                begin
                                                        isDone<= 1'b1;
                                                        i                <= i + 1'b1;
                                                end
                                        10:
                                                begin
                                                        isDone<= 1'b0;
                                                        i                <= 2'd0;
                                                end
                                endcase
        /********************************/
        assign        Done_Sig        = isDone;
        assign        Quotient = isNeg ? (~Temp[7:0] + 1'b1) : Temp[7:0];
        assign        Reminder = Temp[15:8];
        /********************************/
       
        assign        SQ_Diff  = Diff;
        assign        SQ_Temp  = Temp;
       
        /*********************************/
       
endmodule

一周热门 更多>