Skip to content

Multiplicadores

1. Códigos

mult.v
// Fixed point multiplier A(a , b ) = A(10,21)
//                        M(ap, bp) = M(21,42)
//                        left_lim  = bp + a = 42 + 10 = 52
//                        right_lim = bp - b = 42 - 21 = 21

module mult #(
   parameter Width = 32
) (
  input  signed [Width-1:0] a_i,
  input  signed [Width-1:0] b_i,
  output signed [Width-1:0] mult_o
);

  wire [Width*2-1:0] temp;

  assign temp = a_i * b_i; 
  assign mult_o = temp[52:21];      

endmodule
mult_reg.v
// Fixed point multiplier A(a , b ) = A(9,22)
//                        M(ap, bp) = M(19,44)
//                        left_lim  = bp + a = 44 + 9 = 53
//                        right_lim = bp - b = 44 - 22 = 22

module mult_reg #(
   parameter Width = 32,
   parameter Ent = 9,
   parameter Frac = 22
) (
  input                         rst_i,
  input                         clk_i,
  input      signed [Width-1:0] a_i,
  input      signed [Width-1:0] b_i,
  output reg signed [Width-1:0] mult_o
);

  wire [Width*2-1:0] temp;
  wire   [Width-1:0] mult_w;

  assign temp = a_i * b_i; 
  assign mult_w = temp[Frac*2+Ent:Frac];

  always @(posedge clk_i, posedge rst_i) begin
    if (rst_i) begin 
      mult_o <= 0;
    end else begin
      mult_o <= mult_w;
    end
  end  

endmodule

2. Verificación

mult_tb.v
`include "mult.v"

module mult_tb #(
  parameter Width = 32 
) ();

  // Definición de señales de entrada y salida
  reg [Width-1:0] a;
  reg [Width-1:0] b;

  wire [Width-1:0] c;

  // Instanciacion del modulo
  mult #(Width) DUT (
    .a_i(a),
    .b_i(b),
    .mult_o(c)
  );

  // Abrir archivo de salida
  integer write_data;
  localparam SF = 2.0**-21.0;
  time t;

  // Estimulo de las entradas
  initial begin
    write_data = $fopen("mult_tb_output.txt","w");
    $dumpfile("mult_tb.vcd");
    $dumpvars(0,mult_tb);
    $timeformat(-9, 2, " ns", 10);
    a = 32'b00000000001000000000000000000000; //  1.0
    b = 32'b00000000001000000000000000000000; //  1.0;
    #100; t = $time;
    $fdisplay(write_data, "Tiempo: %t\ta = %10.7f\tb = %10.7f\tc = %10.7f",t,$itor(a)*SF,$itor(b)*SF,$itor(c)*SF);

    a = 32'b00000000001100000000000000000000; //  1.5
    b = 32'b00000000001100000000000000000000; //  1.5;
    #100; t = $time;
    $fdisplay(write_data, "Tiempo: %t\ta = %10.7f\tb = %10.7f\tc = %10.7f",t,$itor(a)*SF,$itor(b)*SF,$itor(c)*SF);

    a = 32'b00000000001100000000000000000000; //  1.5
    b = 32'b11111111111100000000000000000000; // -0.5;
    #100; t = $time;
    $fdisplay(write_data, "Tiempo: %t\ta = %10.7f\tb = %10.7f\tc = %10.7f",t,$itor(a)*SF,$itor(b)*SF,$itor(c)*SF);

    // Cerrar archivo de salida
    $fclose(write_data);

    // Final de simulacion
    $display("Test completed");
    //$display("a = %2d, b = %2d, result = %2d", a, b, c);  

  end

endmodule