summaryrefslogtreecommitdiff
path: root/rtl/core/control/mul.sv
blob: 9e6605394a42b598d429588d7c0324544d2811f1 (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
69
70
71
72
`include "core/uarch.sv"

module core_control_mul
(
	input  logic       clk,
	                   rst_n,

	input  insn_decode dec,
	input  logic       mul_ready,
	input  word        rd_value_a,
	                   rd_value_b,

	input  ctrl_cycle  cycle,
	                   next_cycle,
	input  logic       issue,

	output word        mul_a,
	                   mul_b,
	                   mul_c_hi,
	                   mul_c_lo,
	output reg_num     mul_r_add_hi,
	                   mul_r_add_lo,
	output logic       mul,
	                   mul_add,
	                   mul_long,
	                   mul_start,
	                   mul_signed
);

	word hold_a, hold_b;

	assign {mul_c_hi, mul_c_lo} = {rd_value_a, rd_value_b};
	assign {mul_a, mul_b} = mul_add ? {hold_a, hold_b} : {rd_value_a, rd_value_b};

	always_ff @(posedge clk or negedge rst_n)
		if(!rst_n) begin
			mul <= 0;
			mul_add <= 0;
			mul_long <= 0;
			mul_start <= 0;
			mul_signed <= 0;
			mul_r_add_hi <= {$bits(mul_r_add_hi){1'b0}};
			mul_r_add_lo <= {$bits(mul_r_add_lo){1'b0}};

			hold_a <= 0;
			hold_b <= 0;
		end else begin
			mul_start <= 0;

			unique case(next_cycle)
				ISSUE: begin
					mul <= issue && dec.ctrl.mul;
					mul_add <= dec.mul.add;
					mul_long <= dec.mul.long_mul;
					mul_signed <= dec.mul.signed_mul;
					mul_r_add_hi <= dec.mul.r_add_hi;
					mul_r_add_lo <= dec.mul.r_add_lo;
				end

				MUL:
					mul_start <= cycle != MUL;

				MUL_ACC_LD: begin
					hold_a <= rd_value_a;
					hold_b <= rd_value_b;
				end
			endcase
		end

	//TODO: mul update_flags

endmodule