summaryrefslogtreecommitdiff
path: root/hdl/mem_cache.sv
diff options
context:
space:
mode:
authorJulian Blake Kongslie2022-06-05 15:34:23 -0700
committerJulian Blake Kongslie2022-06-05 15:42:26 -0700
commit9ce65b7d3573d92e1d98a13b58a5d5763ba073c5 (patch)
tree7486552ff9428dcb76e22593f445a657b121f443 /hdl/mem_cache.sv
parentSMC micro. (diff)
downloadmultipdp8-9ce65b7d3573d92e1d98a13b58a5d5763ba073c5.tar.xz
Working L1 cache.
Diffstat (limited to '')
-rw-r--r--hdl/mem_cache.sv108
1 files changed, 108 insertions, 0 deletions
diff --git a/hdl/mem_cache.sv b/hdl/mem_cache.sv
new file mode 100644
index 0000000..5f3db73
--- /dev/null
+++ b/hdl/mem_cache.sv
@@ -0,0 +1,108 @@
1`include "defs.svh"
2
3module mem_cache
4 #( SET_BITS = 8
5 )
6 ( input bit clock
7 , input bit reset
8
9 , output bit core_command_ready
10 , input bit core_command_valid
11 , input pdp_command_t core_command_data
12
13 , input bit ram_command_ready
14 , output bit ram_command_valid
15 , output pdp_command_t ram_command_data
16
17 , output bit ram_response_ready
18 , input bit ram_response_valid
19 , input pdp_read_response_t ram_response_data
20
21 , input bit core_response_ready
22 , output bit core_response_valid
23 , output pdp_read_response_t core_response_data
24 );
25
26 localparam ADDRESS_TAG_LO = $clog2(`RAM_LINE_WORDS)+SET_BITS;
27
28 typedef bit [`PDP_ADDRESS_BITS-1:ADDRESS_TAG_LO] address_tag_t;
29 typedef bit [ADDRESS_TAG_LO-1:$clog2(`RAM_LINE_WORDS)] set_t;
30
31 typedef struct packed {
32 bit valid;
33 address_tag_t address;
34 } tag_t;
35
36 typedef struct packed {
37 tag_t tag;
38 ram_line_t data;
39 } cache_entry_t;
40
41 (* ramstyle = "no_rw_check, M9K" *) cache_entry_t cache [(1<<SET_BITS)-1:0];
42
43 bit outstanding_fill;
44
45 bit [SET_BITS:0] reset_entry;
46
47 always @(posedge clock) begin
48 if (reset) begin
49 core_command_ready = 0;
50 ram_command_valid = 0;
51 ram_response_ready = 0;
52 core_response_valid = 0;
53 outstanding_fill = 0;
54 reset_entry = 0;
55 end else if (reset_entry < (1<<SET_BITS)) begin
56 cache[reset_entry] = 0;
57 ++reset_entry;
58 end else begin
59 if (ram_command_ready && ram_command_valid)
60 ram_command_valid = 0;
61 if (core_response_ready && core_response_valid)
62 core_response_valid = 0;
63
64 if (ram_response_ready && ram_response_valid) begin
65 automatic address_tag_t tag;
66 automatic set_t set;
67 automatic cache_entry_t entry;
68 {tag, set} = ram_response_data.address;
69 entry.tag.valid = 1;
70 entry.tag.address = tag;
71 entry.data = ram_response_data.data;
72 cache[set] = entry;
73 core_response_valid = 1;
74 core_response_data = ram_response_data;
75 outstanding_fill = 0;
76 end else if (core_command_ready && core_command_valid) begin
77 automatic address_tag_t tag;
78 automatic set_t set;
79 {tag, set} = core_command_data.address;
80 if (core_command_data.write) begin
81 automatic cache_entry_t entry;
82 entry.tag.valid = 1;
83 entry.tag.address = tag;
84 // FIXME masked stores
85 entry.data = core_command_data.data;
86 cache[set] = entry;
87 ram_command_valid = 1;
88 ram_command_data = core_command_data;
89 end else begin
90 automatic cache_entry_t entry = cache[set];
91 if (entry.tag.valid && entry.tag.address == tag) begin
92 core_response_valid = 1;
93 core_response_data.address = {tag, set};
94 core_response_data.data = entry.data;
95 end else begin
96 ram_command_valid = 1;
97 ram_command_data = core_command_data;
98 outstanding_fill = 1;
99 end
100 end
101 end
102
103 core_command_ready = !ram_command_valid && !core_response_valid && !outstanding_fill;
104 ram_response_ready = !core_response_valid;
105 end
106 end
107
108endmodule