summaryrefslogtreecommitdiff
path: root/rtl/core/core_mul.sv
diff options
context:
space:
mode:
authorAlejandro Soto <alejandro@34project.org>2024-01-21 06:23:46 -0600
committerAlejandro Soto <alejandro@34project.org>2024-02-20 11:11:17 -0600
commitf3b18ead59ae02f95dabbf0a1dea40873a816975 (patch)
tree8979e50f2a37f66a4cd27e937b480efe60d72cf7 /rtl/core/core_mul.sv
parenta8bc5a353ea997f73209b39377ee15a73e471237 (diff)
rtl: refactor filenames and directory hierarchy
Diffstat (limited to 'rtl/core/core_mul.sv')
-rw-r--r--rtl/core/core_mul.sv64
1 files changed, 64 insertions, 0 deletions
diff --git a/rtl/core/core_mul.sv b/rtl/core/core_mul.sv
new file mode 100644
index 0000000..19bbb9a
--- /dev/null
+++ b/rtl/core/core_mul.sv
@@ -0,0 +1,64 @@
+`include "core/uarch.sv"
+
+// Realiza la operación a * b + c = q
+module core_mul
+(
+ input logic clk, // clock, ya que es una máquina de estados
+ rst_n,
+
+ input word a, // primer sumando
+ b, // segundo sumando
+ c_hi, // parte más significativa de c
+ c_lo, // parte menos significativa de c
+ input logic long_mul, // 1 si c es de 2 words, cualquier otro valor si c es de 1 word
+ add, // 1 si c se suma
+ sig, // 1 si a y b son signed
+ start, // 1 indica que se inicie la multiplicacion
+
+ output word q_hi, // parte más significativa del resultado
+ q_lo, // parte menos significativa del resultado
+ output logic n, // no hay C ni V, ya que se dejan unaffected
+ z,
+ ready // 1 cuando la multiplicación está lista
+);
+
+ logic[1:0] wait_state;
+ dword c, q;
+
+ assign ready = !start && wait_state == {$bits(wait_state){1'b0}};
+ assign {q_hi, q_lo} = q;
+ assign n = long_mul ? q_hi[$bits(q_hi) - 1] : q_lo[$bits(q_lo) - 1];
+ assign z = q_lo == 0 && (!long_mul || q_hi == 0);
+
+ //TODO: no está probado cuantos ciclos ocupa esto una vez sintetizado
+ //TODO: trivio?
+ dsp_mul it
+ (
+ .clock0(clk),
+ .aclr0(0), //TODO: parece ser active-high, así que no puede ir a rst_n
+ .ena0(start || !ready),
+ .dataa_0(a),
+ .datab_0(b),
+ .chainin(c),
+ .signa(sig),
+ .signb(sig),
+ .result(q)
+ );
+
+ always_comb
+ if(!add)
+ c = {$bits(c){1'b0}};
+ else if(long_mul)
+ c = {c_hi, c_lo};
+ else
+ c = {{$bits(word){sig && c_lo[$bits(c_lo) - 1]}}, c_lo};
+
+ always_ff @(posedge clk or negedge rst_n)
+ if(!rst_n)
+ wait_state <= 0;
+ else if(wait_state > {$bits(wait_state){1'b0}})
+ wait_state <= wait_state - 1;
+ else if(start)
+ wait_state <= {$bits(wait_state){1'b1}};
+
+endmodule