summaryrefslogtreecommitdiff
path: root/rtl/gfx/mat_mat_mul.sv
blob: 7c2124998e837edb581150f0a2e9d71305b317f0 (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
73
74
75
76
77
`include "gfx/gfx_defs.sv"

module mat_mat_mul
(
	input  logic clk,
	             rst_n,

	input  mat4  a,
	             b,
	input  logic in_valid,
	             out_ready,

	output mat4  q,
	output logic in_ready,
	             out_valid
);

	mat4 a_hold, b_hold, b_transpose, q_hold, mul_b;
	vec4 mul_q;
	logic mul_in_ready, mul_in_valid, mul_out_ready, mul_out_valid;
	index4 in_index, out_index;

	assign in_ready = mul_in_ready && in_index == `INDEX4_MIN;
	assign out_valid = mul_out_valid && out_index == `INDEX4_MAX;

	assign mul_in_valid = in_valid || in_index != `INDEX4_MIN;
	assign mul_out_ready = out_ready || out_index != `INDEX4_MAX;

	transpose transpose
	(
		.in(b),
		.out(b_transpose)
	);

	mat_vec_mul mul
	(
		.a(in_index == `INDEX4_MIN ? a : a_hold),
		.x(mul_b[in_index]),
		.q(mul_q),
		.in_ready(mul_in_ready),
		.in_valid(mul_in_valid),
		.out_ready(mul_out_ready),
		.out_valid(mul_out_valid),
		.*
	);

	always_comb begin
		mul_b = b_hold;
		mul_b[0] = b_transpose[0];

		q = q_hold;
		q[`VECS_PER_MAT - 1] = mul_q;
	end

	always_ff @(posedge clk or negedge rst_n)
		if (!rst_n) begin
			in_index <= `INDEX4_MIN;
			out_index <= `INDEX4_MIN;
		end else begin
			if (mul_in_ready && mul_in_valid)
				in_index <= in_index + 1;

			if (mul_out_ready && mul_out_valid)
				out_index <= out_index + 1;
		end

	always_ff @(posedge clk) begin
		if (in_ready) begin
			a_hold <= a;
			b_hold <= b_transpose;
		end

		if (mul_out_ready && mul_out_valid)
			q_hold[out_index] <= mul_q;
	end

endmodule