diff options
| author | JulianCamacho <jjulian.341@gmail.com> | 2022-10-30 21:08:41 -0600 |
|---|---|---|
| committer | JulianCamacho <jjulian.341@gmail.com> | 2022-10-30 21:08:41 -0600 |
| commit | c0f8b1eabfaa3e8f5004fcca6a5078e770e50eee (patch) | |
| tree | 7f4efda46516b0597b3505f3d53e814628da2f9a /rtl/core | |
| parent | a4032f626746f3af2a7fdd03faf4596d32601d47 (diff) | |
Se agregan test de mul
Diffstat (limited to 'rtl/core')
| -rw-r--r-- | rtl/core/mul/mul.sv | 155 |
1 files changed, 81 insertions, 74 deletions
diff --git a/rtl/core/mul/mul.sv b/rtl/core/mul/mul.sv index d450ff6..4b0d149 100644 --- a/rtl/core/mul/mul.sv +++ b/rtl/core/mul/mul.sv @@ -1,24 +1,25 @@ module core_mul -#(parameter W=32) -( // realiresulta la operación a * b + c = q - input logic[W - 1:0] a, // primer sumando +#(parameter U=32) +( // realiza la operación a * b + c = q + input logic[U - 1:0] a, // primer sumando b, // segundo sumando - input logic[W - 1:0] c_hi, // parte más significativa de c + input logic[U - 1:0] c_hi, // parte más significativa de c c_lo, // parte menos significativa de c - input logic c_siresulte, // 1 si c es de 2 words, cualquier otro valor si c es de 1 word + input logic c_size, // 1 si c es de 2 words, cualquier otro valor si c es de 1 word clk, // clock, ya que es una máquina de estados rst, // reset - add // 1 si c se suma - sig // 1 si a y b son signed - q_siresulte // 1 si q es de 2 words, cualquier otro valor si es de 1 word - start // 1 indica que se inicie la multiplicacion - - output word q_hi, // parte más significativa del resultado - output word q_lo, // parte menos significativa del resultado - output logic result, - n, // no hay C ni V, ya que se dejan unaffected - q_sig // 1 si q es signed, cualquier otro valor si es unsigned - rdy // 1 cuando la multiplicación está lista + add, // 1 si c se suma + sig, // 1 si a y b son signed + q_size, // 1 si q es de 2 words, cualquier otro valor si es de 1 word + start, // 1 indica que se inicie la multiplicacion + + output logic [U - 1:0] q_hi, // parte más significativa del resultado + output logic [U - 1:0] q_lo, // parte menos significativa del resultado + output logic [2*U-1:0] result, + output logic n, // no hay C ni V, ya que se dejan unaffected + z, + q_sig, // 1 si q es signed, cualquier otro valor si es unsigned + rdy // 1 cuando la multiplicación está lista //*Se asume lo siguiente: // - Las señales de entrada son constantes desde el instante en el que start es 1 hasta que rdy sea 1 @@ -28,28 +29,39 @@ module core_mul // - rdy solo no es 1 mientras la multiplicación se está realiresultando ); - //! TODO: - //! Testear que el algoritmo sirva bien @julian + localparam W = U+1; //U=32 , W=33 + localparam IDLE = 1'b0; + localparam START = 1'b1; - logic [(2*W) - 1:0] result, next_result, result_temp; + logic signed [2*W - 1:0] result_ext, next_result, result_temp; //66 logic next_state, current_state; - logic [1:0] temp, next_temp; //temp es la concatenación de {Q0,Qres} - logic [$clog2(W) - 1:0] count, next_count; - logic rdy, next_rdy; + logic [1:0] temp, next_temp; //temp es la concatenación de {Q0,Qres} + logic [$clog2(U) - 1:0] count, next_count; + logic [2*W - 1:0] c; //66 + logic [2*W - 1:0] a_ext, b_ext; + logic next_rdy; + + assign a_ext = {{(W+1){sig && a[W-1]}}, a}; //65 + assign b_ext = {{(W+1){sig && b[W-1]}}, b}; - parameter IDLE = 1'b0; - parameter START = 1'b1; + always_comb + if (!add) + c = {(2*W){1'b0}}; + else if (c_size) + c = {2'b0, c_hi, c_lo}; + else + c = {{(W+1){sig && c_lo[W-1]}}, c_lo}; always @ (posedge clk or negedge rst) begin if(!rst) begin - result <= W{1'b0}; + result_ext <= {(2*W){1'b0}}; rdy <= 1'b0; current_state <= 1'b0; temp <= 2'd0; - count <= $clog2(W){1'b0}; + count <= {$clog2(U){1'b0}}; end else begin - result <= next_result; + result_ext <= next_result; rdy <= next_rdy; current_state <= next_state; temp <= next_temp; @@ -60,31 +72,36 @@ module core_mul always @ (*) begin unique case(current_state) IDLE: begin - next_count = $clog2(W){1'b0}; + next_count = {$clog2(U){1'b0}}; next_rdy = 1'b0; if(start) begin next_state = START; - next_temp = {a[0],1'b0}; - next_result = {4'd0,a}; + next_temp = {a_ext[0],1'b0}; + next_result = {{(W/2){1'b0}},a_ext}; end else begin next_state = current_state; next_temp = 2'd0; - next_result = (2*W){1'b0}; + next_result = result_ext + c; end end START: begin unique case(temp) - 2'b10: result_temp = {result[W-1 :W>>1]-b,result[(W>>1) - 1:0]}; - 2'b01: result_temp = {result[W-1: W>>1]+b,result[(W>>1) - 1:0]}; - default: result_temp = {result[W-1: W>>1],result[(W>>1) - 1:0]}; + 2'b10: result_temp = {result_ext[2*W-1: U]-b_ext, result_ext[U-1:0]}; + 2'b01: result_temp = {result_ext[2*W-1: U]+b_ext, result_ext[U-1:0]}; + default: result_temp = result_ext; endcase - next_temp = {a[count+1],a[count]}; - next_count = count + 1'b1; - next_result= result_temp >>> 1; - next_rdy = (&count) ? 1'b1 : 1'b0; - next_state = (&count) ? IDLE : current_state; + next_temp = {a_ext[count+1],a_ext[count]}; + next_count = count + 1'b1; + next_result = result_temp >>> 1; + next_rdy = (&count) ? 1'b1 : 1'b0; + next_state = (&count) ? IDLE : current_state; + result = result_ext[2*U-1:0]; + q_hi = result_ext[2*U-1: U]; + q_lo = result_ext[U-1: 0]; + n = result_ext[2*W-1]; + z = (|result_ext) ? 1'b0 : 1'b1; end endcase end @@ -95,40 +112,30 @@ endmodule /* - 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 +module mul_tb(); + + logic clk,rst,start; + logic[7:0]X,Y; + logic[15:0]Z; + logic valid; + + always #5 clk = ~clk; + + core_mul_mul #(.W(8)) inst (.clk(clk),.rst(rst),.start(start),.a(X),.b(Y),.rdy(valid),.result(Z)); + + initial + $monitor($time,"a=%d, b=%d, ready=%d, Z=%d ",X,Y,valid,Z); + initial + begin + X=255;Y=150;clk=1'b1;rst=1'b0;start=1'b0; + #10 rst = 1'b1; + #10 start = 1'b1; + #10 start = 1'b0; + @valid + #10 X=-80;Y=-10;start = 1'b1; + #10 start = 1'b0; + end +endmodule - booth >>> 1; - counter = counter - 1; - always_comb - if(counter == 0) begin - q = booth[(W*2):1] - end - end -endmodule*/ +*/ |
