Skip to content

Commit 8f6ec74

Browse files
authored
Add files via upload
1 parent 5a9b9c7 commit 8f6ec74

File tree

6 files changed

+779
-0
lines changed

6 files changed

+779
-0
lines changed

cache.sv

+236
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,236 @@
1+
`include "constants.sv"
2+
3+
module cache(
4+
input int log_stream,
5+
input int cache_stream,
6+
input wire clk, reset, c_dump,
7+
input wire[`ADDR1_BUS_SIZE - 1 : 0] a1_in,
8+
inout wire[`DATA1_BUS_SIZE - 1 : 0] d1_in,
9+
inout wire[`CTR1_BUS_SIZE - 1 : 0] c1_in,
10+
output wire[`ADDR2_BUS_SIZE - 1 : 0] a2_out,
11+
inout wire[`DATA2_BUS_BIT_SIZE - 1 : 0] d2_in,
12+
inout wire[`CTR2_BUS_SIZE - 1 : 0] c2_in
13+
);
14+
reg[`DATA1_BUS_SIZE - 1 : 0] d1_reg = 'z;
15+
reg[`CTR1_BUS_SIZE - 1 : 0] c1_reg = 'z;
16+
reg[`ADDR2_BUS_SIZE - 1 : 0] a2_reg = 'z;
17+
reg[`DATA2_BUS_BIT_SIZE - 1 : 0] d2_reg = 'z;
18+
reg[`CTR2_BUS_SIZE - 1 : 0] c2_reg = NONE;
19+
assign d1_in = d1_reg;
20+
assign c1_in = c1_reg;
21+
assign d2_in = d2_reg;
22+
assign a2_out = a2_reg;
23+
assign c2_in = c2_reg;
24+
25+
reg[`LINE_BIT_SIZE - 1 : 0] cache_memory[`CACHE_WAY_BLOCKS_NUMBER - 1 : 0][`CACHE_WAY - 1 : 0];
26+
reg[`TAG_SIZE - 1 : 0] line_tag[`CACHE_WAY_BLOCKS_NUMBER - 1 : 0][`CACHE_WAY - 1 : 0];
27+
reg modified[`CACHE_WAY_BLOCKS_NUMBER - 1 : 0][`CACHE_WAY - 1 : 0];
28+
reg invalid[`CACHE_WAY_BLOCKS_NUMBER - 1 : 0][`CACHE_WAY - 1 : 0];
29+
reg last_used[`CACHE_WAY_BLOCKS_NUMBER - 1 : 0];
30+
reg[`TAG_SIZE - 1 : 0] requested_tag;
31+
reg[`SET_SIZE - 1 : 0] requested_set;
32+
reg[`OFFSET_SIZE - 1 : 0] requested_offset;
33+
reg[`CTR1_BUS_SIZE - 1 : 0] requested_operation = NONE;
34+
reg[`MAX_WRITE_REQUEST_SIZE - 1 : 0] data_to_write;
35+
36+
task write_to_memory(
37+
input reg[`SET_SIZE - 1 : 0] set,
38+
input int ind_in_way_block
39+
);
40+
c2_reg = WRITE;
41+
a2_reg[`SET_SIZE +: `TAG_SIZE] = line_tag[set][ind_in_way_block];
42+
a2_reg[0 +: `SET_SIZE] = set;
43+
44+
$fdisplay(log_stream, "Time: %0t, cache send write request to memory on a2: %b", $time, a2_out);
45+
46+
for (int i = 0; i < `MEMORY_INTERACTION_TICK_NUMBER; i++) begin
47+
d2_reg = (cache_memory[set][ind_in_way_block] >> i * `DATA2_BUS_BIT_SIZE) & ((1 << `DATA2_BUS_BIT_SIZE) - 1);
48+
`delay(`CLOCK_DELAY, 0)
49+
end
50+
51+
modified[set][ind_in_way_block] = 0;
52+
c2_reg = 'z;
53+
54+
wait(clk == 1 && c2_in == RESPONSE);
55+
//Clock = 1
56+
57+
$fdisplay(log_stream, "Time: %0t, memory answered to cache on write c2: %b", $time, c2_in);
58+
wait(clk == 0);
59+
//Clock = 0
60+
61+
c2_reg = NONE;
62+
$fdisplay(log_stream, "Time: %0t, cache has taken the c2: %b", $time, c2_in);
63+
endtask;
64+
65+
task read_from_memory(
66+
input reg[`TAG_SIZE - 1 : 0] tag,
67+
input reg[`SET_SIZE - 1 : 0] set,
68+
input int ind_in_way_block
69+
);
70+
c2_reg = READ;
71+
a2_reg[`SET_SIZE +: `TAG_SIZE] = tag;
72+
a2_reg[0 +: `SET_SIZE] = set;
73+
74+
$fdisplay(log_stream, "Time: %0t, cache send read request to memory, a2: %b", $time, a2_out);
75+
76+
`delay(`CLOCK_DELAY, 0)
77+
c2_reg = 'z;
78+
d2_reg = 'z;
79+
80+
wait(clk == 1 && c2_in == RESPONSE);
81+
//Clock = 1
82+
83+
cache_memory[set][ind_in_way_block] = 0;
84+
for (int i = 0; i < `MEMORY_INTERACTION_TICK_NUMBER; i++) begin
85+
cache_memory[set][ind_in_way_block][i * `DATA2_BUS_BIT_SIZE +: `DATA2_BUS_BIT_SIZE] = d2_in;
86+
`delay(`CLOCK_DELAY, 1)
87+
end;
88+
89+
invalid[set][ind_in_way_block] = 0;
90+
modified[set][ind_in_way_block] = 0;
91+
line_tag[set][ind_in_way_block] = tag;
92+
$fdisplay(log_stream, "Time: %0t, memory answered to cache on read with data: %b", $time, cache_memory[set][ind_in_way_block]);
93+
94+
wait(clk == 0);
95+
//Clock = 0
96+
97+
c2_reg = NONE;
98+
$fdisplay(log_stream, "Time: %0t, cache has taken the c2: %b", $time, c2_in);
99+
endtask;
100+
101+
task reset_cache;
102+
$fdisplay(log_stream, "Cache reset");
103+
for (int i = 0; i < `CACHE_WAY_BLOCKS_NUMBER; i++) begin
104+
for (int j = 0; j < `CACHE_WAY; j++) begin
105+
cache_memory[i][j] = 0;
106+
invalid[i][j] = 1;
107+
modified[i][j] = 0;
108+
end;
109+
last_used[i] = 0;
110+
end
111+
endtask
112+
113+
task dump_cache;
114+
for (int i = 0; i < `CACHE_WAY_BLOCKS_NUMBER; i++) begin
115+
for (int j = 0; j < `CACHE_WAY; j++) begin
116+
$fdisplay(cache_stream, "tag: %b, set: %b, ind_in_way_block: %b, cache_line: %b", line_tag[i][j], i, j, cache_memory[i][j]);
117+
end
118+
end
119+
endtask
120+
121+
initial reset_cache();
122+
123+
int ind_in_way_block = -1;
124+
int requested_bit_offset;
125+
126+
always @(posedge reset)
127+
reset_cache();
128+
129+
always @(posedge c_dump)
130+
dump_cache();
131+
132+
always @(clk) begin
133+
134+
if (clk == 1 && c1_in != NONE_C1) begin
135+
requested_operation = c1_in;
136+
requested_set = a1_in & ((1 << `SET_SIZE) - 1);
137+
requested_tag = (a1_in >> `SET_SIZE);
138+
if (c1_in == WRITE8)
139+
data_to_write = d1_in & ((1 << 8) - 1);
140+
else if (c1_in == WRITE16 || c1_in == WRITE32_OR_RESPONSE)
141+
data_to_write = d1_in;
142+
143+
if (c1_in != INVALIDATE) begin
144+
`delay(`CLOCK_DELAY, 1)
145+
146+
requested_offset = a1_in & ((1 << `OFFSET_SIZE) - 1);
147+
if (c1_in == WRITE32_OR_RESPONSE)
148+
data_to_write[`DATA1_BUS_SIZE +: `DATA1_BUS_SIZE] = d1_in;
149+
end
150+
151+
$fdisplay(log_stream, "Time: %0t, cache got the request: %0d, tag: %b, set: %b, offset: %b", $time, requested_operation, requested_tag, requested_set, requested_offset);
152+
if (c1_in == WRITE8 || c1_in == WRITE16 || c1_in == WRITE32_OR_RESPONSE)
153+
$fdisplay(log_stream, "with data to write: %b", data_to_write);
154+
end
155+
156+
if (clk == 0 && requested_operation != NONE) begin
157+
c1_reg = NONE_C1;
158+
$fdisplay(log_stream, "Time: %0t, cache has taken the c1 bus and started processing request", $time);
159+
160+
if (requested_operation == INVALIDATE) begin
161+
for (int j = 0; j < `CACHE_WAY; j++) begin
162+
if (invalid[requested_set][j] == 0 && line_tag[requested_set][j] == requested_tag) begin
163+
last_used[requested_set] = !j;
164+
if (modified[requested_set][j])
165+
write_to_memory(requested_set, j);
166+
invalid[requested_set][j] = 1;
167+
end
168+
end
169+
c1_reg = WRITE32_OR_RESPONSE;
170+
end else begin
171+
ind_in_way_block = -1;
172+
for (int j = 0; j < `CACHE_WAY; j++)
173+
if (invalid[requested_set][j] == 0 && line_tag[requested_set][j] == requested_tag)
174+
ind_in_way_block = j;
175+
176+
if (ind_in_way_block == -1) begin
177+
$fdisplay(log_stream, "Time: %0t, cache miss at set: %b at tag: %b", $time, requested_set, requested_tag);
178+
test_simulation.cpu_inst.cache_misses++;
179+
`delay(`CACHE_MISS_RESPONSE_TIME - `CACHE_INTERACTION_TICK_NUMBER * `CLOCK_DELAY, 0)
180+
181+
ind_in_way_block = !last_used[requested_set];
182+
183+
if (modified[requested_set][ind_in_way_block] == 1 && invalid[requested_set][ind_in_way_block] == 0)
184+
write_to_memory(requested_set, ind_in_way_block);
185+
186+
read_from_memory(requested_tag, requested_set, ind_in_way_block);
187+
end else begin
188+
$fdisplay(log_stream, "Time: %0t, cache hit at set: %b at tag: %b", $time, requested_set, requested_tag);
189+
test_simulation.cpu_inst.cache_hits++;
190+
`delay(`CACHE_HIT_RESPONSE_TIME - `CACHE_INTERACTION_TICK_NUMBER * `CLOCK_DELAY, 0)
191+
end
192+
193+
c1_reg = WRITE32_OR_RESPONSE;
194+
requested_bit_offset = requested_offset * 8; //bytes to bits
195+
196+
case (requested_operation)
197+
WRITE8: begin
198+
cache_memory[requested_set][ind_in_way_block][requested_bit_offset +: 8] = data_to_write;
199+
modified[requested_set][ind_in_way_block] = 1;
200+
end
201+
202+
WRITE16: begin
203+
cache_memory[requested_set][ind_in_way_block][requested_bit_offset +: 16] = data_to_write;
204+
modified[requested_set][ind_in_way_block] = 1;
205+
end
206+
207+
WRITE32_OR_RESPONSE: begin
208+
cache_memory[requested_set][ind_in_way_block][requested_bit_offset +: 32] = data_to_write;
209+
modified[requested_set][ind_in_way_block] = 1;
210+
end
211+
212+
READ8: d1_reg = cache_memory[requested_set][ind_in_way_block][requested_bit_offset +: 8];
213+
214+
READ16: d1_reg = cache_memory[requested_set][ind_in_way_block][requested_bit_offset +: 16];
215+
216+
READ32: begin
217+
$fdisplay(log_stream, "Time: %0t, cache_memory: %b", $time, cache_memory[requested_set][ind_in_way_block][requested_bit_offset +: 16]);
218+
d1_reg = cache_memory[requested_set][ind_in_way_block][requested_bit_offset +: 16];
219+
`delay(`CLOCK_DELAY, 0);
220+
$fdisplay(log_stream, "Time: %0t, cache_memory: %b", $time, cache_memory[requested_set][ind_in_way_block][requested_bit_offset + 16 +: 16]);
221+
d1_reg = cache_memory[requested_set][ind_in_way_block][requested_bit_offset + 16 +: 16];
222+
end
223+
endcase
224+
225+
last_used[requested_set] = ind_in_way_block;
226+
end
227+
228+
`delay(`CLOCK_DELAY, 0)
229+
230+
$fdisplay(log_stream, "Time: %0t, cache has given the c1 bus", $time);
231+
c1_reg = 'z;
232+
d1_reg = 'z;
233+
requested_operation = NONE;
234+
end
235+
end;
236+
endmodule;

constants.sv

+45
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
`ifndef GUARD
2+
`define GUARD
3+
4+
`define delay(TIME, CLOCK) \
5+
for (int i = 0; i < TIME; i++) begin \
6+
wait(clk == (i + !CLOCK) % 2); \
7+
end
8+
9+
`define BYTE 8
10+
`define LINE_BYTE_SIZE 16
11+
`define LINE_BIT_SIZE 16 * `BYTE
12+
13+
`define MEM_BYTE_SIZE (1 << 19)
14+
15+
`define CACHE_LINE_NUMBER 64
16+
`define CACHE_WAY 2
17+
`define CACHE_WAY_BLOCKS_NUMBER (`CACHE_LINE_NUMBER / `CACHE_WAY)
18+
19+
`define CTR1_BUS_SIZE 3
20+
`define CTR2_BUS_SIZE 2
21+
22+
typedef enum int { NONE_C1 = 0, READ8 = 1, READ16 = 2, READ32 = 3, INVALIDATE = 4, WRITE8 = 5, WRITE16 = 6, WRITE32_OR_RESPONSE = 7 } C1_state;
23+
typedef enum int { NONE = 0, RESPONSE = 1, READ = 2, WRITE = 3 } C2_state;
24+
25+
`define DATA1_BUS_SIZE 16
26+
`define DATA2_BUS_BIT_SIZE 16
27+
`define DATA2_BUS_BYTE_SIZE (`DATA2_BUS_BIT_SIZE / `BYTE)
28+
29+
`define ADDR1_BUS_SIZE 15
30+
`define ADDR2_BUS_SIZE 15
31+
32+
`define TAG_SIZE 10
33+
`define SET_SIZE 5
34+
`define OFFSET_SIZE 4
35+
`define MAX_WRITE_REQUEST_SIZE 32
36+
37+
`define CLOCK_DELAY 2
38+
`define MEMORY_RESPONSE_TIME (`CLOCK_DELAY * 100)
39+
`define CACHE_HIT_RESPONSE_TIME (`CLOCK_DELAY * 6)
40+
`define CACHE_MISS_RESPONSE_TIME (`CLOCK_DELAY * 4)
41+
42+
`define MEMORY_INTERACTION_TICK_NUMBER (`LINE_BYTE_SIZE / `DATA2_BUS_BYTE_SIZE)
43+
`define CACHE_INTERACTION_TICK_NUMBER 2
44+
45+
`endif //GUARD

0 commit comments

Comments
 (0)