summaryrefslogtreecommitdiff
path: root/rtl/gfx/gfx_sp_shuffler.sv
blob: e4c119dad94818de65f22bc76cff021c243cec5a (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
`include "gfx/gfx_defs.sv"

module gfx_sp_shuffler
(
	input  logic     clk,
	                 rst_n,

	input  insn_deco deco,
	input  mat4      a,
	                 b,
	input  logic     in_valid,
	output logic     in_ready,

	output wb_op     wb,
	input  logic     wb_ready,
	output logic     wb_valid
);

	mat4 select_out, swizzle_out;
	wb_op wb_out;
	logic stall, is_swizzle;
	vreg_num hold_dst;

	gfx_pipeline_flow #(.STAGES(2)) flow
	(
		.out_ready(wb_ready),
		.out_valid(wb_valid),
		.*
	);

	gfx_skid_buf #(.WIDTH($bits(wb))) skid
	(
		.in(wb_out),
		.out(wb),
		.*
	);

	genvar gen_i;
	generate
		for (gen_i = 0; gen_i < `VECS_PER_MAT; ++gen_i) begin: lanes
			gfx_sp_select select
			(
				.a(a[gen_i]),
				.b(b[gen_i]),
				.out(select_out[gen_i]),
				.deco(deco.shuffler),
				.*
			);

			gfx_sp_swizzle swizzle
			(
				.in(a[gen_i]),
				.out(swizzle_out[gen_i]),
				.deco(deco.shuffler),
				.*
			);
		end
	endgenerate

	always_ff @(posedge clk)
		if (!stall) begin
			hold_dst <= deco.dst;
			is_swizzle <= deco.shuffler.is_swizzle;

			wb_out.dst <= hold_dst;
			for (integer i = 0; i < `VECS_PER_MAT; ++i)
				wb_out.data[i] <= is_swizzle ? swizzle_out[i] : select_out[i];
		end

endmodule