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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
|
`include "core/uarch.sv"
module core_control_writeback
(
input logic clk,
rst_n,
input insn_decode dec,
input psr_flags alu_flags,
input word q_alu,
ldst_read,
input logic mem_ready,
mem_write,
input word mul_q_hi,
mul_q_lo,
input ctrl_cycle cycle,
next_cycle,
input word saved_base,
exception_vector,
psr_wb,
coproc_wb,
input reg_num ra,
popped,
mul_r_add_hi,
input logic issue,
pop_valid,
ldst_next,
output reg_num rd,
final_rd,
output logic writeback,
final_writeback,
update_flags,
final_update_flags,
output word wr_value
);
reg_num last_rd;
always_comb begin
rd = last_rd;
if(next_cycle.transfer) begin
if(mem_ready)
rd = final_rd;
end else if(next_cycle.issue || next_cycle.base_writeback)
rd = final_rd;
else if(next_cycle.exception)
rd = `R15;
else if(next_cycle.mul_hi_wb)
rd = mul_r_add_hi;
if(next_cycle.issue)
writeback = final_writeback;
else if(next_cycle.transfer)
writeback = mem_ready && !mem_write;
else if(next_cycle.base_writeback)
writeback = !mem_write;
else if(next_cycle.exception || next_cycle.mul_hi_wb)
writeback = 1;
else
writeback = 0;
if(cycle.transfer)
wr_value = ldst_read;
else if(cycle.base_writeback)
wr_value = saved_base;
else if(cycle.mul || cycle.mul_hi_wb)
wr_value = mul_q_lo;
else if(cycle.psr)
wr_value = psr_wb;
else if(cycle.coproc)
wr_value = coproc_wb;
else
// Ruta combinacional larga
wr_value = q_alu;
if(next_cycle.transfer) begin
if(mem_ready)
wr_value = ldst_read;
end else if(next_cycle.base_writeback)
wr_value = ldst_read;
else if(next_cycle.exception)
wr_value = exception_vector;
else if(next_cycle.mul_hi_wb)
wr_value = mul_q_hi;
update_flags = 0;
if(next_cycle.issue)
update_flags = final_update_flags;
else if(next_cycle.exception)
update_flags = 0;
end
always_ff @(posedge clk or negedge rst_n)
if(!rst_n) begin
last_rd <= 0;
final_rd <= 0;
final_writeback <= 0;
final_update_flags <= 0;
end else begin
last_rd <= rd;
if(next_cycle.issue)
final_rd <= dec.data.rd;
else if(next_cycle.transfer) begin
if(ldst_next && pop_valid)
final_rd <= popped;
end else if(next_cycle.base_writeback)
final_rd <= ra;
else if(next_cycle.exception)
final_rd <= `R14;
if(next_cycle.issue)
final_writeback <= issue && dec.ctrl.writeback;
else if(next_cycle.exception)
final_writeback <= 1;
if(next_cycle.issue)
final_update_flags <= issue && dec.psr.update_flags;
else if(next_cycle.exception)
final_update_flags <= 0;
end
endmodule
|