P2P interface Booth multiplier design description principle code realization

P2P interface Booth multiplier design description principle code realization

-

description

Booth multiplier is a kind of multiplier implemented by shifting, the implementation process is as follows, for multiplication:

The number of digits of extended A is n+1 digits, add

, Then A becomes:

Start from i=0 and end at i=n-1, and then investigate in turn

Do the following:

  • If

, Do nothing

  • If

,

  • If

,

Finally, discard the rightmost 1 bit of R to obtain

principle

The principle is relatively easy to understand. For the above multiplication, it can be decomposed into:

The above is the principle of the displacement multiplier, so for the booth multiplier, add one:

That is:

In the principle formula of the shift multiplier

The continuous 1 part is replaced by two subtractions to form a booth multiplier

Code

This time, a booth multiplier based on the P2P interface is implemented, and the bit width is configurable.

module booth_mul #(
    parameter DIN_WIDTH_LOG = 3
)(
    input clk,//Clock
    input rst_n,//Asynchronous reset active low

    input din_valid,
    output din_busy,
    input [2 ** DIN_WIDTH_LOG-1:0] din_data_a,
    input [2 ** DIN_WIDTH_LOG-1:0] din_data_b,

    output reg dout_valid,
    input dout_busy,
    output [2 ** (DIN_WIDTH_LOG + 1)-1:0]dout_data
);

First define the control flow, the control flow is a state machine, respectively:

  • INIT: Silent state, waiting for input, turn to WORKstate when input is received
  • WORK: Working state, booth multiplication is performed, the din_busysignal is pulled high during the process , when the operation is completed, turn toTRAN
  • TRAN: Transmission status, P2P output, turn to INITstatus after output is completed
parameter INIT = 2'b00;
parameter WORK = 2'b01;
parameter TRAN = 2'b11;

reg [DIN_WIDTH_LOG-1:0]shifter_counter;
reg [1:0] status,next_status;
always @(posedge clk or negedge rst_n) begin: proc_status
    if(~rst_n) begin
        status <='b0;
    end else begin
        status <= next_status;
    end
end

wire is_computed = (shifter_counter == 2 ** DIN_WIDTH_LOG-1);
wire is_traned = dout_valid && !dout_busy;
always @(*) begin
    case (status)
        INIT:begin
            if(din_valid) begin
                next_status = WORK;
            end else begin
                next_status = INIT;
            end
        end
        WORK:begin
            if(is_computed) begin
                next_status = TRAN;
            end else begin
                next_status = WORK;
            end
        end
        TRAN:begin
            if(is_traned) begin
                next_status = INIT;
            end else begin
                next_status = TRAN;
            end
        end
        default : next_status = INIT;
    endcase
end
assign din_busy = status[0];

always @(posedge clk or negedge rst_n) begin
    if(~rst_n) begin
        shifter_counter <= 'b0;
    end else if(status == WORK) begin
        shifter_counter <= shifter_counter + 1'b1;
    end else begin
        shifter_counter <= 'b0;
    end
end

always @(posedge clk or negedge rst_n) begin
    if(~rst_n) begin
        dout_valid <= 'b0;
    end else if(is_computed) begin
        dout_valid <= 1'b1;
    end else if(is_traned) begin
        dout_valid <= 'b0;
    end
end

下面是数据流的部分,该部分实现了上述的booth乘法操作

reg [2 ** DIN_WIDTH_LOG:0]a_data;
wire is_read = !din_busy && din_valid;
always @(posedge clk or negedge rst_n) begin : proc_a_data
    if(~rst_n) begin
        a_data <= 0;
    end else if(is_read) begin
        a_data <= {din_data_a,1'b0};
    end else if(status == WORK) begin
        a_data <= a_data >> 1;
    end
end

reg [2 ** (DIN_WIDTH_LOG + 1) - 1:0]b_data;
always @(posedge clk or negedge rst_n) begin : proc_b_data
    if(~rst_n) begin
        b_data <= 0;
    end else if(is_read)begin
        b_data <= {(2 ** DIN_WIDTH_LOG)'(0),din_data_b};
    end else if(status == WORK) begin
        b_data <= b_data << 1;
    end
end

reg [2 ** (DIN_WIDTH_LOG + 1):0]temp_data,result_data;
always @(*) begin
    case (a_data[1:0])
        2'b01:temp_data = dout_data + b_data;
        2'b10:temp_data = dout_data - b_data;
        default:temp_data = dout_data;
    endcase
end

always @(posedge clk or negedge rst_n) begin : proc_dout_data
    if(~rst_n) begin
        result_data <= 0;
    end else if(is_read) begin
        result_data <='b0;
    end else if(status == WORK) begin
        result_data <= temp_data;
    end
end
assign dout_data = result_data;

endmodule
Reference: https://cloud.tencent.com/developer/article/1371358 P2P interface Booth multiplier design description principle code implementation-Cloud + Community-Tencent Cloud