summaryrefslogtreecommitdiff
path: root/rtl/core/mul/mul.sv
blob: 0d7f4bb7120977a6dd5eeec83b9124c0c2dff9d3 (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
67
68
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		// 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
	
	//*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
	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