From 2910a4dfc7e27169628b6b30232067c3c1508fff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabi=C3=A1n=20Montero?= Date: Wed, 19 Oct 2022 23:13:24 -0600 Subject: =?UTF-8?q?mul:=20a=C3=B1ade=20base=20para=20instrucci=C3=B3n=20MU?= =?UTF-8?q?L?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- rtl/core/mul/mul.sv | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 rtl/core/mul/mul.sv (limited to 'rtl') diff --git a/rtl/core/mul/mul.sv b/rtl/core/mul/mul.sv new file mode 100644 index 0000000..0453cad --- /dev/null +++ b/rtl/core/mul/mul.sv @@ -0,0 +1,60 @@ +module core_mul_mul +#(parameter W=32) +( + input logic[W - 1:0] a, + b, + input logic clk, + + output logic[(W*2) - 1:0] q, + output logic z, + n +); + + 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 or negedge rst_n) begin + if (~rst_n) begin + booth = { W{1'b0}, b, 0 } + Q = booth[1:0]; + //A = booth[(W*2):W]; + //B = a; + counter = W; + end + else 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; + end + + always_comb + if(counter == 0) begin + q = booth[(W*2):1] + end + end +endmodule -- cgit v1.2.3 From 2427353289678206a849d67672297e790f396ec2 Mon Sep 17 00:00:00 2001 From: fabian-mv Date: Thu, 20 Oct 2022 10:31:28 -0600 Subject: mul: arregla typos --- rtl/core/mul/mul.sv | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'rtl') diff --git a/rtl/core/mul/mul.sv b/rtl/core/mul/mul.sv index 0453cad..a5ac02f 100644 --- a/rtl/core/mul/mul.sv +++ b/rtl/core/mul/mul.sv @@ -40,7 +40,7 @@ always@(posedge clk or negedge rst_n) begin booth[(W*2):W] = A + B; - 2'b10: + 2'b10: booth[(W*2):W] = A - B; // 2'b11 o 2'b00: -- cgit v1.2.3 From 2dbac6c57c6180adf07dcca598e86a9dad1162ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabi=C3=A1n=20Montero?= Date: Sun, 23 Oct 2022 13:36:30 -0600 Subject: =?UTF-8?q?a=C3=B1ade=20sugerencias=20y=20TODO?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- rtl/core/mul/mul.sv | 38 ++++++++++++++++++++++++-------------- 1 file changed, 24 insertions(+), 14 deletions(-) (limited to 'rtl') diff --git a/rtl/core/mul/mul.sv b/rtl/core/mul/mul.sv index a5ac02f..9abee23 100644 --- a/rtl/core/mul/mul.sv +++ b/rtl/core/mul/mul.sv @@ -1,13 +1,33 @@ -module core_mul_mul +module core_mul_mul // TODO: cambiar nombre a solo core_mul, ya que solo va a haber una operación para esto #(parameter W=32) ( input logic[W - 1:0] a, b, input logic clk, - output logic[(W*2) - 1:0] q, - output logic z, + output logic[(W*2) - 1:0] q, // TODO: cambiar a dos salidas de tamaño de 1 word, independientemente de W. se les puede llamar q_hi y q_lo a las dos partes de la respuesta + output logic z, // no hay C ni V, ya que se dejan unaffected n + + //! TODO: + //! como es una máquina de estados, es necesario tener también: + //! Entradas: + //! logic[w-1:0] c_hi // ya que puede ser a * b + c + //! logic[w-1:0] c_lo // ya que puede ser a * b + c // se necesitan un hi y un lo porque SMLAL lo requiere + //! logic c_big // ya que puede ser de 32bits o 64bits + //! logic add // ya que se tiene que avisar si se va a sumar c o no + //! indicar cuando se inicia la multiplicación en la máquina de estados + //! si la operación es signed o unsigned + //! logic double_word // si la salida es de tamaño word o double word + //! Salidas: + //! indicar en qué ciclo la multiplicación está lista // ya que la multiplicación es de ciclos + //! // variables + //! 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; @@ -23,16 +43,7 @@ module core_mul_mul counter = W; end -always@(posedge clk or negedge rst_n) begin - if (~rst_n) begin - booth = { W{1'b0}, b, 0 } - Q = booth[1:0]; - //A = booth[(W*2):W]; - //B = a; - counter = W; - end - else begin - +always@(posedge clk) begin A = booth[(W*2):W]; unique case(Q) @@ -50,7 +61,6 @@ always@(posedge clk or negedge rst_n) begin booth >>> 1; counter = counter - 1; - end always_comb if(counter == 0) begin -- cgit v1.2.3 From 085dbae65516cfb292482861f12531935e58499c Mon Sep 17 00:00:00 2001 From: fabian-mv Date: Tue, 25 Oct 2022 10:04:20 -0600 Subject: =?UTF-8?q?mul:=20actualiza=20API=20de=20modulo=20de=20multiplicac?= =?UTF-8?q?i=C3=B3n?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- rtl/core/mul/mul.sv | 38 +++++++++++++++++--------------------- 1 file changed, 17 insertions(+), 21 deletions(-) (limited to 'rtl') diff --git a/rtl/core/mul/mul.sv b/rtl/core/mul/mul.sv index 9abee23..5ff7e24 100644 --- a/rtl/core/mul/mul.sv +++ b/rtl/core/mul/mul.sv @@ -1,27 +1,23 @@ -module core_mul_mul // TODO: cambiar nombre a solo core_mul, ya que solo va a haber una operación para esto +module core_mul #(parameter W=32) -( - input logic[W - 1:0] a, - b, - input logic clk, +( // 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 logic[(W*2) - 1:0] q, // TODO: cambiar a dos salidas de tamaño de 1 word, independientemente de W. se les puede llamar q_hi y q_lo a las dos partes de la respuesta - output logic z, // no hay C ni V, ya que se dejan unaffected - n + output logic[31:0] q_hi, // parte más significa tiva del resultado + output logic[31:0] 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: - //! como es una máquina de estados, es necesario tener también: - //! Entradas: - //! logic[w-1:0] c_hi // ya que puede ser a * b + c - //! logic[w-1:0] c_lo // ya que puede ser a * b + c // se necesitan un hi y un lo porque SMLAL lo requiere - //! logic c_big // ya que puede ser de 32bits o 64bits - //! logic add // ya que se tiene que avisar si se va a sumar c o no - //! indicar cuando se inicia la multiplicación en la máquina de estados - //! si la operación es signed o unsigned - //! logic double_word // si la salida es de tamaño word o double word - //! Salidas: - //! indicar en qué ciclo la multiplicación está lista // ya que la multiplicación es de ciclos - //! // variables //! 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? @@ -52,7 +48,7 @@ always@(posedge clk) begin 2'b10: - booth[(W*2):W] = A - B; + booth[(W*2):W] = A - B; // 2'b11 o 2'b00: default: ; -- cgit v1.2.3 From cc123402eeca92c416a4dac4110316e279d41395 Mon Sep 17 00:00:00 2001 From: fabian-mv Date: Tue, 25 Oct 2022 10:09:07 -0600 Subject: mul: pasa a usar tipos definidos en uarch --- rtl/core/mul/mul.sv | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'rtl') diff --git a/rtl/core/mul/mul.sv b/rtl/core/mul/mul.sv index 5ff7e24..f501c9a 100644 --- a/rtl/core/mul/mul.sv +++ b/rtl/core/mul/mul.sv @@ -11,11 +11,11 @@ module core_mul 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 logic[31:0] q_hi, // parte más significa tiva del resultado - output logic[31:0] 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 + 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 -- cgit v1.2.3 From 516fea5c2252f172b18ac9cf2640ea486c71e985 Mon Sep 17 00:00:00 2001 From: fabian-mv Date: Tue, 25 Oct 2022 10:15:14 -0600 Subject: mul: identar con tabs en lugar de espacios --- rtl/core/mul/mul.sv | 105 ++++++++++++++++++++++++++-------------------------- 1 file changed, 53 insertions(+), 52 deletions(-) (limited to 'rtl') diff --git a/rtl/core/mul/mul.sv b/rtl/core/mul/mul.sv index f501c9a..40a48c4 100644 --- a/rtl/core/mul/mul.sv +++ b/rtl/core/mul/mul.sv @@ -1,66 +1,67 @@ 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 + 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? + 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; + //! TODO: + //! Testear que el algoritmo sirva bien @julian + 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 + 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]; + A = booth[(W*2):W]; - unique case(Q) - 2'b01: - booth[(W*2):W] = A + B; - + 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 + 2'b10: + booth[(W*2):W] = A - B; + + // 2'b11 o 2'b00: + default: ; + + endcase - booth >>> 1; - counter = counter - 1; + booth >>> 1; + counter = counter - 1; - always_comb - if(counter == 0) begin - q = booth[(W*2):1] - end - end + always_comb + if(counter == 0) begin + q = booth[(W*2):1] + end + end endmodule -- cgit v1.2.3 From 37e54deaca8dc72efcd862a40c671c6fba508341 Mon Sep 17 00:00:00 2001 From: fabian-mv Date: Tue, 25 Oct 2022 10:50:00 -0600 Subject: mul: define api del multiplicador --- rtl/core/mul/mul.sv | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) (limited to 'rtl') diff --git a/rtl/core/mul/mul.sv b/rtl/core/mul/mul.sv index 40a48c4..0d7f4bb 100644 --- a/rtl/core/mul/mul.sv +++ b/rtl/core/mul/mul.sv @@ -8,22 +8,23 @@ module core_mul 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 + sig // es 1 si a y b son signed, es 0 si son unisgned q_size // si es 1, q es de 2 words, si es 0, q es de 1 word + start // si es 1, se inicia la multiplicacion 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 + q_sig // si es 1, 1 es signed, es 0 si es unsigned 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? + //*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 + // - El valor de start puede cambiar durante la multiplicación, pero va a ser ignorado hasta que rdy sea 1 + // - El valor de q es UNPREDICTABLE hasta que rdy sea 1 + // - Las condiciones para iniciar una multiplicación son que rdy sea 1 y start sea 1 + // - rdy solo no es 1 mientras la multiplicación se está realizando ); //! TODO: -- cgit v1.2.3 From 5b5fa7d8390e21597cdf722a18c3839950797082 Mon Sep 17 00:00:00 2001 From: fabian-mv Date: Tue, 25 Oct 2022 10:54:08 -0600 Subject: mul: refina comentarios y api --- rtl/core/mul/mul.sv | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'rtl') diff --git a/rtl/core/mul/mul.sv b/rtl/core/mul/mul.sv index 0d7f4bb..000ccce 100644 --- a/rtl/core/mul/mul.sv +++ b/rtl/core/mul/mul.sv @@ -5,19 +5,19 @@ module core_mul 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 + 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 - add // si es 1, c se suma. si es 0, no se suma - sig // es 1 si a y b son signed, es 0 si son unisgned - q_size // si es 1, q es de 2 words, si es 0, q es de 1 word - start // si es 1, se inicia la multiplicacion + 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 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 - q_sig // si es 1, 1 es signed, es 0 si es unsigned - rdy // si es 1, la multiplicación está lista + q_sig // 1 si q es signed, cualquier otr 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 -- cgit v1.2.3 From c758d5024361dff121e683d690d784df05130ff9 Mon Sep 17 00:00:00 2001 From: fabian-mv Date: Tue, 25 Oct 2022 11:35:50 -0600 Subject: =?UTF-8?q?a=C3=B1ade=20reset?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- rtl/core/mul/core_mul.sv.tmp | 103 +++++++++++++++++++++++++++++++++++++++++++ rtl/core/mul/mul.sv | 1 + 2 files changed, 104 insertions(+) create mode 100644 rtl/core/mul/core_mul.sv.tmp (limited to 'rtl') diff --git a/rtl/core/mul/core_mul.sv.tmp b/rtl/core/mul/core_mul.sv.tmp new file mode 100644 index 0000000..111e7ce --- /dev/null +++ b/rtl/core/mul/core_mul.sv.tmp @@ -0,0 +1,103 @@ +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, // 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, + 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 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 + q_sig // 1 si q es signed, cualquier otr 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 + // - El valor de start puede cambiar durante la multiplicación, pero va a ser ignorado hasta que rdy sea 1 + // - El valor de q es UNPREDICTABLE hasta que rdy sea 1 + // - Las condiciones para iniciar una multiplicación son que rdy sea 1 y start sea 1 + // - rdy solo no es 1 mientras la multiplicación se está realizando +); + + //! TODO: + //! Testear que el algoritmo sirva bien @julian + +module BoothMul(clk,rst,start,a,b,rdy,p); + + input rst; + input signed [3:0]a,b; + output signed [7:0]p; + output rdy; + + logic signed [7:0] p,next_p,p_temp; + logic next_state, pres_state; + logic [1:0] temp,next_temp; + logic [1:0] count,next_count; + logic rdy, next_rdy; + + parameter IDLE = 1'b0; + parameter START = 1'b1; + + always @ (posedge clk or negedge rst) begin + if(!rst) begin + p <= 8'd0; + rdy <= 1'b0; + pres_state <= 1'b0; + temp <= 2'd0; + count <= 2'd0; + end + else begin + p <= next_p; + rdy <= next_rdy; + pres_state <= next_state; + temp <= next_temp; + count <= next_count; + end + end + + always @ (*) begin + case(pres_state) + IDLE: + begin + next_count = 2'b0; + next_rdy = 1'b0; + if(start) begin + next_state = START; + next_temp = {a[0],1'b0}; + next_p = {4'd0,a}; + end + else begin + next_state = pres_state; + next_temp = 2'd0; + next_p = 8'd0; + end + end + + START: + begin + case(temp) + 2'b10: p_temp = {p[7:4]-b,p[3:0]}; + 2'b01: p_temp = {p[7:4]+b,p[3:0]}; + default: p_temp = {p[7:4],p[3:0]}; + endcase + next_temp = {a[count+1],a[count]}; + next_count = count + 1'b1; + next_p = p_temp >>> 1; + next_rdy = (&count) ? 1'b1 : 1'b0; + next_state = (&count) ? IDLE : pres_state; + end + endcase + end +endmodule + + +endmodule diff --git a/rtl/core/mul/mul.sv b/rtl/core/mul/mul.sv index 000ccce..01237dc 100644 --- a/rtl/core/mul/mul.sv +++ b/rtl/core/mul/mul.sv @@ -7,6 +7,7 @@ module core_mul c_lo, // parte menos significativa de c 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_size // 1 si q es de 2 words, cualquier otro valor si es de 1 word -- cgit v1.2.3 From a4032f626746f3af2a7fdd03faf4596d32601d47 Mon Sep 17 00:00:00 2001 From: JulianCamacho Date: Thu, 27 Oct 2022 11:28:19 -0600 Subject: Se agrega algoritmo de Booth --- rtl/core/mul/mul.sv | 85 ++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 75 insertions(+), 10 deletions(-) (limited to 'rtl') diff --git a/rtl/core/mul/mul.sv b/rtl/core/mul/mul.sv index 01237dc..d450ff6 100644 --- a/rtl/core/mul/mul.sv +++ b/rtl/core/mul/mul.sv @@ -1,23 +1,23 @@ module core_mul #(parameter W=32) -( // realiza la operación a * b + c = q +( // realiresulta 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, // 1 si c es de 2 words, cualquier otro valor si c es de 1 word + input logic c_siresulte, // 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_size // 1 si q es de 2 words, cualquier otro valor si es de 1 word + 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 significa tiva del resultado + output word q_hi, // parte más significativa del resultado output word q_lo, // parte menos significativa del resultado - output logic z, + output logic result, n, // no hay C ni V, ya que se dejan unaffected - q_sig // 1 si q es signed, cualquier otr valor si es unsigned + 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: @@ -25,16 +25,81 @@ module core_mul // - El valor de start puede cambiar durante la multiplicación, pero va a ser ignorado hasta que rdy sea 1 // - El valor de q es UNPREDICTABLE hasta que rdy sea 1 // - Las condiciones para iniciar una multiplicación son que rdy sea 1 y start sea 1 - // - rdy solo no es 1 mientras la multiplicación se está realizando + // - rdy solo no es 1 mientras la multiplicación se está realiresultando ); //! TODO: //! Testear que el algoritmo sirva bien @julian + + logic [(2*W) - 1:0] result, next_result, result_temp; + 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; + + parameter IDLE = 1'b0; + parameter START = 1'b1; + + always @ (posedge clk or negedge rst) begin + if(!rst) begin + result <= W{1'b0}; + rdy <= 1'b0; + current_state <= 1'b0; + temp <= 2'd0; + count <= $clog2(W){1'b0}; + end + else begin + result <= next_result; + rdy <= next_rdy; + current_state <= next_state; + temp <= next_temp; + count <= next_count; + end + end + + always @ (*) begin + unique case(current_state) + IDLE: begin + next_count = $clog2(W){1'b0}; + next_rdy = 1'b0; + if(start) begin + next_state = START; + next_temp = {a[0],1'b0}; + next_result = {4'd0,a}; + end + else begin + next_state = current_state; + next_temp = 2'd0; + next_result = (2*W){1'b0}; + 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]}; + 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; + end + endcase + end + + +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]; @@ -43,7 +108,7 @@ module core_mul counter = W; end -always@(posedge clk) begin + always@(posedge clk) begin A = booth[(W*2):W]; unique case(Q) @@ -66,4 +131,4 @@ always@(posedge clk) begin q = booth[(W*2):1] end end -endmodule +endmodule*/ -- cgit v1.2.3 From c0f8b1eabfaa3e8f5004fcca6a5078e770e50eee Mon Sep 17 00:00:00 2001 From: JulianCamacho Date: Sun, 30 Oct 2022 21:08:41 -0600 Subject: Se agregan test de mul --- rtl/core/mul/mul.sv | 155 +++++++++++++++++++++++++++------------------------- rtl/top/mul_test.sv | 33 +++++++++++ 2 files changed, 114 insertions(+), 74 deletions(-) create mode 100644 rtl/top/mul_test.sv (limited to 'rtl') 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*/ +*/ diff --git a/rtl/top/mul_test.sv b/rtl/top/mul_test.sv new file mode 100644 index 0000000..1395772 --- /dev/null +++ b/rtl/top/mul_test.sv @@ -0,0 +1,33 @@ +`timescale 1 ns / 1 ps + +module mul_test +#(parameter U=32) +( + input logic[U - 1:0] a, // primer sumando + b, // segundo sumando + input logic[U - 1:0] c_hi, // parte más significativa de c + c_lo, // parte menos significativa de c + 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_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 + + +); + core_mul #(.U(U)) DUT (.*); + +endmodule + + + -- cgit v1.2.3