summaryrefslogtreecommitdiff
path: root/rtl/core/mul/mul.sv
blob: f501c9a7459244674c89796d99a06ed0556e389b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
module core_mul
#(parameter W=32)
(   // realiza la operación a * b + c = q
    input logic[W - 1:0]    a,      // primer sumando
                            b,      // segundo sumando
    input logic[W - 1:0]    c_hi,   // parte más significativa de c
                            c_lo,   // parte menos significativa de c
    input logic             c_size, // si es 1, c es de 2 words, si es 0, c es de 1 word
                            clk,    // clock, ya que es una máquina de estados
                            add     // si es 1, c se suma. si es 0, no se suma
                            sig     // si la suma es signed o unisgned
                            q_size  // si es 1, q es de 2 words, si es 0, q es de 1 word

    output  word    q_hi,    // parte más significa tiva del resultado
    output  word    q_lo,    // parte menos significativa del resultado
    output  logic   z,
                    n,      // no hay C ni V, ya que se dejan unaffected
                    rdy     // si es 1, la multiplicación está lista
    
    //! TODO:
    //! hay que definit un protocolo de cómo se usa este módulo
    //!     Por ejemplo:
    //!         se levanta rdy en algún momento, pero qué pasa al ciclo siguiente? se mantiene o se baja? qué sucede?
    //!         es capaz que se soporte que se haga un ready y un start? esto se define en este módulo, para que contro lo use
    //!         qué pasa si la salida es signed?
    //!         es necesario que las señales de entrada se mantengan constantes durante los ciclos?
);

    logic[(W*2):0] booth;
    logic[1:0] Q; 
    logic[W-1:0] A, B;
    logic[W - 1:0] counter;

    initial begin
        booth = { W{1'b0}, b, 0 }
        Q = booth[1:0];
        A = booth[(W*2):W];
        B = a;
        counter = W;
    end

always@(posedge clk) begin
        A = booth[(W*2):W];

        unique case(Q)
            2'b01:
                booth[(W*2):W] = A + B;
                

            2'b10: 
                booth[(W*2):W] = A - B;
            
            // 2'b11 o 2'b00:
            default: ;
                
        endcase

        booth >>> 1;
        counter = counter - 1;

    always_comb
        if(counter == 0) begin
            q = booth[(W*2):1]
        end
    end
endmodule