2016-11-30 12 views
0

Для академического упражнения я реализовал 32-разрядный множитель Карацуба, который выполняет 17 циклов, выполняя параллельное умножение по 16 бит и соответствующим образом меняя их.Генерирование неподписанного числа для множителя стенда

У меня возникает проблема, когда частичные продукты должны быть неподписанными, но множитель стендов генерирует подписанный частичный продукт для меня, независимо от типа ввода, который я даю, из-за которого я получаю неправильные частичные продукты. Как я могу это решить?

Для примера. мои два подписанных входа: 0xA000_000A и 0x000A_A000. Итак, первый частичный продукт A000 * 000A должен быть 64000, но я получаю 0xFFFC4000 (FFFF_A000 * 0000_000A). Я поделился своим кодом здесь для стенда и его тестового стенда.

module booth_multiplier 
(
    input logic clk, 
    input logic rst, 
    input logic valid, 
    input logic signed [15:0] Mul_X, 
    input logic signed [15:0] Mul_Y, 
    output logic signed [31:0] product, 
    output logic result_ready 
); 

    logic unsigned Q_1; 
    bit [4:0] count; 
    logic signed [15:0] multiplier; 

    logic signed [15:0] multiplicand; 

    logic [15:0] A, temp_A; 
    logic signed [32:0] partial_product; 
    logic signed [32:0] partial_multiplier; 


    typedef enum {IDLE=0, OPERATE} fsm; 
    fsm state, next_state; 

     parameter ADD = 2'b01, SUB = 2'b10; 

    //assign product = multiplier[16:1]; 


    [email protected](posedge clk or negedge rst) 
    begin 
     if(~rst) 
     begin 
      count <= 0; 
      state <= IDLE; 
      multiplier <= 0; 
       multiplicand <= 0; 
     end 
     else begin 
      count <= count+1; 
      state <= next_state; 
     end 
    end 

    [email protected](*) 
    begin 
     case(state) 

      IDLE : begin 
       Q_1 = 0; 
       A = 0; 
       count = 0; 
       product = 0; 
       temp_A = 0; 
       result_ready = 0; 
       if(valid) begin 
         multiplicand = Mul_X; 
        multiplier = Mul_Y; 
        partial_product = {A, multiplier, Q_1}; 
        partial_multiplier = 0; 
        next_state = OPERATE; 
       end 

        end 

      OPERATE: begin 
       case(partial_product[1:0]) 

        ADD: begin 
         temp_A = A + multiplicand; 
         multiplier = partial_product[16:1]; 
         partial_multiplier = {temp_A, multiplier, Q_1}; 
         partial_product = partial_multiplier >>> 1; 
         Q_1 = partial_product[0]; 
         A = partial_product[32:17]; 
         end 
        SUB: begin 
         temp_A = A - multiplicand; 
         multiplier = partial_product[16:1]; 
         partial_multiplier = {temp_A, multiplier, Q_1}; 
         partial_product = partial_multiplier >>> 1; 
         Q_1 = partial_product[0]; 
         A = partial_product[32:17]; 
         end 
        default: begin 
         temp_A = A; 
         multiplier = partial_product[16:1]; 
          partial_multiplier = {temp_A, multiplier, Q_1}; 
         partial_product = partial_multiplier >>> 1; 
         Q_1 = multiplier[0]; 
         A = partial_product[32:17]; 
         end 
       endcase 

       if(count == 16) begin 
        next_state = IDLE; 
        product = partial_product >> 1; 
        result_ready = 1; 
       end 
       else next_state = OPERATE; 
       end 


     endcase 

    end 

endmodule 

Это я использую, чтобы сделать 4 параллельных умножений в

module fast_multiplier 
(
    input logic clk, 
    input logic rst, 
    input valid, 
    input logic signed [31:0] multiplicand, 
    input logic signed [31:0] multiplier, 
    output logic signed [63:0] product, 
    output logic ready); 

    logic [15:0] X1; 
    logic [15:0] Y1; 
    logic [15:0] Xr; 
    logic [15:0] Yr; 
    logic [31:0] X1_Yr; 
    logic [31:0] Xr_Yr; 
    logic [31:0] X1_Y1; 
    logic [31:0] Xr_Y1; 
    logic ready1, ready2, ready3, ready4; 


    assign X1 = multiplicand[31:16]; 
    assign Y1 = multiplier[31:16]; 
    assign Xr = multiplicand[15:0]; 
    assign Yr = multiplier[15:0]; 


    booth_multiplier X1Y1 
    (
    .clk(clk), 
    .rst(rst), 
    .valid(valid), 
    .Mul_X(X1), 
    .Mul_Y(Y1), 
    .product(X1_Y1), 
    .result_ready(ready1)); 

    booth_multiplier X1Yr 
    (
    .clk(clk), 
    .rst(rst), 
    .valid(valid), 
    .Mul_X(X1), 
    .Mul_Y(Yr), 
    .product(X1_Yr), 
    .result_ready(ready2)); 

    booth_multiplier XrY1 
    (
    .clk(clk), 
    .rst(rst), 
    .valid(valid), 
    .Mul_X(Xr), 
    .Mul_Y(Y1), 
    .product(Xr_Y1), 
    .result_ready(ready3)); 

    booth_multiplier XrYr 
    (
    .clk(clk), 
    .rst(rst), 
    .valid(valid), 
    .Mul_X(Xr), 
    .Mul_Y(Yr), 
    .product(Xr_Yr), 
    .result_ready(ready4)); 

    [email protected](posedge clk or negedge rst) 
    begin 
     if(~rst) 
     begin 
      product <= 0; 
      ready <= 0; 
      X1_Yr <= 0; 
      X1_Y1 <= 0; 
      Xr_Yr <= 0; 
      Xr_Y1 <= 0; 
     end 
     else begin 
      product <= ({32'b0,X1_Y1} << 32) + (({32'b0,X1_Yr} + {32'b0,Xr_Y1}) << 16) + {32'b0,Xr_Yr}; 
      ready <= ready1 & ready2 & ready3 & ready4; 
     end 
    end 

endmodule 

Кроме того, разделив испытательный стенд,

module top_booth_multiplier(); 


    logic clk; 
    logic rst; 
    logic valid;  
    logic signed [31:0] multiplicand; 
    logic signed [31:0] multiplier; 
     logic signed [63:0] product; 
    logic ready; 

    fast_multiplier booth (.*); 

    initial 
    begin 
     clk = 0; 
     forever #10 clk = ~clk; 
    end 




    initial 
    begin 
     rst = 0; 
     #7 rst = 1; 

     @(posedge clk) valid <= 1; 
     multiplier = 32'hA000000A; 
     multiplicand = 32'h000AA000; 
     @(posedge clk) valid <= 0; 
     while(ready == 0) 
     begin 
      @(posedge clk); 
     end 


     repeat (20) @(posedge clk); 
     $finish; 
    end 

endmodule 

ответ

1

Вы должны рассмотреть «подписаны» входы в кабине мультипликатора ТОЛЬКО для Экземпляр X1Y1. Все остальные экземпляры ДОЛЖНЫ использовать «неподписанные» входы. Это изменение должно помочь!

 Смежные вопросы

  • Нет связанных вопросов^_^