-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathicache_control.sv
executable file
·166 lines (131 loc) · 3.13 KB
/
icache_control.sv
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
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
import lc3b_types::*; /* Import types defined in lc3b_types.sv */
module icache_control
(
input clk,
/* Datapath controls */
input lru,
input hit_A, hit_B,
input valid_A_dataout, valid_B_dataout,
output logic valid_A_write, valid_B_write,
output logic valid_A_datain, valid_B_datain,
output logic tag_A_write, tag_B_write,
output logic data_A_write, data_B_write,
output logic lru_datain,
output logic lru_write,
/* Memory signals */
input icache_read,
output logic icache_resp,
input L2_resp,//L2_resp,
output logic L2_read//L2_read,
);
enum int unsigned {
HIT,
MISS,
SET_STATUS_MISS
} state, next_state;
always_comb
begin : state_actions
/* Default assignments */
lru_datain = 1'b0;
lru_write = 1'b0;
valid_A_write = 1'b0;
valid_B_write = 1'b0;
valid_A_datain = 1'b0;
valid_B_datain = 1'b0;
tag_A_write = 1'b0;
tag_B_write = 1'b0;
data_A_write = 1'b0;
data_B_write = 1'b0;
L2_read = 1'b0;
icache_resp = 1'b0;
case(state)
HIT: begin
if (hit_A || hit_B && icache_read)
begin
icache_resp = 1'b1;
if (hit_A && valid_A_dataout)
begin
/* should be taken care of by hardware wire-y stuff */
// data_write = 1'b1; // write dat data
lru_write = 1'b1;
lru_datain = 1'b0; // wrote to A, least recent is now B
end
else if (hit_B && valid_B_dataout)
begin
/* should be taken care of by hardware wire-y stuff */
// data_write = 1'b1; // write dat data
lru_write = 1'b1;
lru_datain = 1'b1; // wrote to B, least recent is now A
end
end
end
MISS: begin
L2_read = 1'b1; // we want to read the new and exciting stuff from L2
if (lru == 1'b1)
begin
data_A_write = 1'b1; // write the data...
tag_A_write = 1'b1; // and the tag
end
if (lru == 1'b0)
begin
data_B_write = 1'b1; // write the data...
tag_B_write = 1'b1; // and the tag
end
end
SET_STATUS_MISS: begin
if (lru == 1'b1)
begin
valid_A_write = 1'b1; // set valid bit of least recently used
valid_A_datain = 1'b1;
end
if (lru == 1'b0)
begin
valid_B_write = 1'b1; // set valid bit of least recently used
valid_B_datain = 1'b1;
end
end
default: /* Do nothing */;
endcase
end
always_comb
begin : next_state_logic
next_state = state;
case(state)
HIT: begin
if (lru == 1'b1 && !hit_B && icache_read) // if we messed with B last...
begin
if (!hit_A) // if there's no hit on A
begin
next_state = MISS; // It's a MISS
end
end
else if (lru == 1'b0 && !hit_A && icache_read) // if we messed with A last...
begin
if (!hit_B)
begin // if there's no hit on B
next_state = MISS; // It's a MISS
end
end
else next_state = HIT;
end
MISS: begin
if (L2_resp)
begin
next_state = SET_STATUS_MISS;
end
else
begin
next_state = MISS;
end
end
SET_STATUS_MISS: begin
next_state = HIT;
end
default: begin next_state = HIT; end
endcase
end
always_ff @(posedge clk)
begin : next_state_assignment
state <= next_state;
end
endmodule : icache_control