summaryrefslogtreecommitdiff
path: root/rtl/core/control/cycles.sv
blob: 0a70d5e853cdabb746ccc9c32e221ec373cd83b8 (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
`include "core/uarch.sv"

module core_control_cycles
(
	input  logic      clk,
	                  rst_n,
	                  mul,
	                  ldst,
	                  bubble,
	                  exception,
	                  mem_ready,
	                  mul_add,
	                  mul_long,
	                  mul_ready,
	                  pop_valid,
	                  trivial_shift,
	                  ldst_writeback,
	                  data_snd_shift_by_reg,

	output ctrl_cycle cycle,
	                  next_cycle
);

	always_comb begin
		next_cycle = ISSUE;

		unique case(cycle)
			ISSUE:
				if(exception)
					next_cycle = EXCEPTION;
				else if(mul)
					next_cycle = mul_add ? MUL_ACC_LD : MUL;
				else if(data_snd_shift_by_reg)
					next_cycle = RD_INDIRECT_SHIFT;
				else if(!trivial_shift)
					next_cycle = WITH_SHIFT;

			RD_INDIRECT_SHIFT:
				if(!trivial_shift)
					next_cycle = WITH_SHIFT;

			TRANSFER:
				if(!mem_ready || pop_valid)
					next_cycle = TRANSFER;
				else if(ldst_writeback)
					next_cycle = BASE_WRITEBACK;

			MUL:
				if(!mul_ready)
					next_cycle = MUL;
				else if(mul_long)
					next_cycle = MUL_HI_WB;

			MUL_ACC_LD:
				next_cycle = MUL;
		endcase

		if(bubble)
			next_cycle = ISSUE;
		else if(next_cycle == ISSUE && ldst) begin
			next_cycle = TRANSFER;
		end
	end

	always_ff @(posedge clk or negedge rst_n)
		cycle <= !rst_n ? ISSUE : next_cycle;

endmodule