summaryrefslogtreecommitdiff
path: root/rtl
diff options
context:
space:
mode:
authorJulianCamacho <jjulian.341@gmail.com>2022-10-30 21:08:41 -0600
committerJulianCamacho <jjulian.341@gmail.com>2022-10-30 21:08:41 -0600
commitc0f8b1eabfaa3e8f5004fcca6a5078e770e50eee (patch)
tree7f4efda46516b0597b3505f3d53e814628da2f9a /rtl
parenta4032f626746f3af2a7fdd03faf4596d32601d47 (diff)
Se agregan test de mul
Diffstat (limited to 'rtl')
-rw-r--r--rtl/core/mul/mul.sv155
-rw-r--r--rtl/top/mul_test.sv33
2 files changed, 114 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*/
+*/
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
+
+
+