summaryrefslogtreecommitdiff
path: root/rtl/core/control/writeback.sv
blob: 2ba084551a10948cde966d450448b0c892a39e69 (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
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
`include "core/uarch.sv"

module core_control_writeback
(
	input  logic           clk,

	input  datapath_decode dec,
	input  data_decode     dec_data,

	input  ctrl_cycle      cycle,
	                       next_cycle,
	input  word            saved_base,
	                       mem_data_rd,
	                       vector,
	                       q_alu,
	input  reg_num         ra,
	                       popped,
	input  logic           pop_valid,
	                       issue,
	                       mem_ready,
	                       mem_write,

	output reg_num         rd,
	                       final_rd,
	output logic           writeback,
	                       final_writeback,
	output word            wr_value
);

	always @(posedge clk) begin
		unique0 case(next_cycle)
			TRANSFER:
				if(mem_ready)
					rd <= final_rd;

			ISSUE, BASE_WRITEBACK:
				rd <= final_rd;

			EXCEPTION:
				rd <= `R15;
		endcase

		unique0 case(next_cycle)
			ISSUE:
				if(issue)
					final_rd <= dec_data.rd;

			TRANSFER:
				if((cycle != TRANSFER || mem_ready) && pop_valid)
					final_rd <= popped;

			BASE_WRITEBACK:
				final_rd <= ra;

			EXCEPTION:
				final_rd <= `R14;
		endcase

		writeback <= 0;
		unique0 case(next_cycle)
			ISSUE:
				writeback <= final_writeback;

			TRANSFER:
				writeback <= mem_ready && !mem_write;

			BASE_WRITEBACK:
				writeback <= !mem_write;

			EXCEPTION:
				writeback <= 1;
		endcase

		unique0 case(next_cycle)
			ISSUE:
				final_writeback <= issue && dec.writeback;

			EXCEPTION:
				final_writeback <= 1;
		endcase

		unique case(cycle)
			TRANSFER:       wr_value <= mem_data_rd;
			BASE_WRITEBACK: wr_value <= saved_base;
			default:        wr_value <= q_alu;
		endcase

		unique0 case(next_cycle)
			TRANSFER:
				if(mem_ready)
					wr_value <= mem_data_rd;

			BASE_WRITEBACK:
				wr_value <= mem_data_rd;

			EXCEPTION:
				wr_value <= vector;
		endcase
	end

	initial begin
		rd = 0;
		final_rd = 0;
		wr_value = 0;
		writeback = 0;
		final_writeback = 0;
	end

endmodule