summaryrefslogtreecommitdiff
path: root/rtl/cache
diff options
context:
space:
mode:
Diffstat (limited to 'rtl/cache')
-rw-r--r--rtl/cache/cache.sv8
-rw-r--r--rtl/cache/cache_control.sv145
-rw-r--r--rtl/cache/monitor.sv103
3 files changed, 185 insertions, 71 deletions
diff --git a/rtl/cache/cache.sv b/rtl/cache/cache.sv
index 29403e2..1b327b4 100644
--- a/rtl/cache/cache.sv
+++ b/rtl/cache/cache.sv
@@ -97,4 +97,12 @@ module cache
.*
);
+ line monitor_update;
+ logic monitor_acquire, monitor_commit, monitor_fail, monitor_release;
+
+ cache_monitor monitor
+ (
+ .*
+ );
+
endmodule
diff --git a/rtl/cache/cache_control.sv b/rtl/cache/cache_control.sv
index 1648ec8..090fba4 100644
--- a/rtl/cache/cache_control.sv
+++ b/rtl/cache/cache_control.sv
@@ -3,50 +3,55 @@
module cache_control
#(parameter TOKEN_AT_RESET=0)
(
- input logic clk,
- rst_n,
-
- input addr_tag core_tag,
- input addr_index core_index,
- input logic core_read,
- core_write,
- core_lock,
- input line core_data_wr,
- output logic core_waitrequest,
- output logic[1:0] core_response,
-
- input ring_req in_data,
- input logic in_data_valid,
- output logic in_data_ready,
-
- input logic out_data_ready,
- output ring_req out_data,
- output logic out_data_valid,
-
- input ring_token in_token,
- input logic in_token_valid,
-
- output ring_token out_token,
- output logic out_token_valid,
-
- input addr_tag tag_rd,
- input line data_rd,
- input line_state state_rd,
-
- output addr_index index_rd,
- index_wr,
- output logic write_data,
- write_state,
- output addr_tag tag_wr,
- output line data_wr,
- output line_state state_wr,
-
- input logic mem_waitrequest,
- input line mem_readdata,
- output word mem_address,
- output logic mem_read,
- mem_write,
- output line mem_writedata
+ input logic clk,
+ rst_n,
+
+ input addr_tag core_tag,
+ input addr_index core_index,
+ input logic core_read,
+ core_write,
+ core_lock,
+ input line core_data_wr,
+ output logic core_waitrequest,
+
+ input ring_req in_data,
+ input logic in_data_valid,
+ output logic in_data_ready,
+
+ input logic out_data_ready,
+ output ring_req out_data,
+ output logic out_data_valid,
+
+ input ring_token in_token,
+ input logic in_token_valid,
+
+ output ring_token out_token,
+ output logic out_token_valid,
+
+ input addr_tag tag_rd,
+ input line data_rd,
+ input line_state state_rd,
+
+ input line monitor_update,
+ input logic monitor_commit,
+ output logic monitor_acquire,
+ monitor_fail,
+ monitor_release,
+
+ output addr_index index_rd,
+ index_wr,
+ output logic write_data,
+ write_state,
+ output addr_tag tag_wr,
+ output line data_wr,
+ output line_state state_wr,
+
+ input logic mem_waitrequest,
+ input line mem_readdata,
+ output word mem_address,
+ output logic mem_read,
+ mem_write,
+ output line mem_writedata
);
enum int unsigned
@@ -58,23 +63,14 @@ module cache_control
} state, next_state;
logic accept_snoop, end_reply, in_hold_valid, last_hop, lock_line, locked,
- may_send, may_send_if_token_held, mem_begin, mem_end, mem_read_end, mem_wait,
- monitor_acquire, monitor_commit, monitor_fail, out_stall, wait_reply, replace,
- retry, send, send_inval, send_read, snoop_hit, set_reply, unlock_line, writeback;
+ may_send, may_send_if_token_held, mem_begin, mem_end, mem_read_end,
+ mem_wait, out_stall, wait_reply, replace, retry, send, send_inval,
+ send_read, snoop_hit, set_reply, unlock_line, writeback;
ring_req in_hold, send_data, fwd_data, stall_data, out_data_next;
- line monitor_data_rd, monitor_data_wr;
- addr_tag mem_tag, monitor_tag;
- addr_index mem_index, monitor_index;
-
- /* Avalon p. 15:
- * - 00: OKAY - Successful response for a transaction.
- * - 10: SLVERR - Error from an endpoint agent. Indicates an unsuccessful transaction.
- */
- assign core_response = {monitor_fail, 1'b0};
- assign monitor_commit = !core_lock || (monitor_tag == core_tag && monitor_index == core_index
- && monitor_data_rd == data_rd);
+ addr_tag mem_tag;
+ addr_index mem_index;
assign mem_end = (mem_read || mem_write) && !mem_waitrequest;
assign mem_wait = (mem_read || mem_write) && mem_waitrequest;
@@ -132,6 +128,7 @@ module cache_control
monitor_fail = 0;
monitor_acquire = 0;
+ monitor_release = 0;
core_waitrequest = 1;
in_data_ready = !in_hold_valid;
@@ -151,8 +148,6 @@ module cache_control
end
CORE: begin
- monitor_acquire = core_read && core_lock;
-
if (replace) begin
state_wr = INVALID;
write_state = 1;
@@ -171,8 +166,10 @@ module cache_control
send_inval = 1;
end
- {SHARED, 1'b0}:
+ {SHARED, 1'b0}: begin
+ monitor_acquire = core_lock;
core_waitrequest = 0;
+ end
{SHARED, 1'b1}: begin
/* No hacemos write_data ya que reintentaremos el
@@ -188,8 +185,10 @@ module cache_control
send_inval = 1;
end
- {EXCLUSIVE, 1'b0}:
+ {EXCLUSIVE, 1'b0}: begin
+ monitor_acquire = core_lock;
core_waitrequest = 0;
+ end
{EXCLUSIVE, 1'b1}: begin
state_wr = MODIFIED;
@@ -197,19 +196,28 @@ module cache_control
write_state = monitor_commit;
monitor_fail = !monitor_commit;
+ monitor_release = core_lock;
+
core_waitrequest = 0;
end
- {MODIFIED, 1'b0}:
+ {MODIFIED, 1'b0}: begin
+ monitor_acquire = core_lock;
core_waitrequest = 0;
+ end
{MODIFIED, 1'b1}: begin
write_data = monitor_commit;
monitor_fail = !monitor_commit;
+ monitor_release = core_lock;
+
core_waitrequest = 0;
end
endcase
+
+ if (monitor_release)
+ data_wr = monitor_update;
end
SNOOP: begin
@@ -282,6 +290,9 @@ module cache_control
write_data = 0;
write_state = 0;
+ monitor_acquire = 0;
+ monitor_release = 0;
+
in_data_ready = !in_hold_valid;
core_waitrequest = 1;
end
@@ -394,14 +405,6 @@ module cache_control
mem_index <= index_wr;
mem_writedata <= data_rd;
end
-
- if (monitor_acquire && !core_waitrequest) begin
- monitor_tag <= core_tag;
- monitor_index <= core_index;
-
- monitor_data_rd <= data_rd;
- monitor_data_wr <= data_rd;
- end
end
endmodule
diff --git a/rtl/cache/monitor.sv b/rtl/cache/monitor.sv
new file mode 100644
index 0000000..b7f0d15
--- /dev/null
+++ b/rtl/cache/monitor.sv
@@ -0,0 +1,103 @@
+`include "cache/defs.sv"
+
+module cache_monitor
+(
+ input logic clk,
+ rst_n,
+
+ input addr_tag core_tag,
+ input addr_index core_index,
+ input addr_offset core_offset,
+ input logic core_lock,
+ input word core_writedata,
+ output logic[1:0] core_response,
+
+ input line data_rd,
+
+ input logic monitor_acquire,
+ monitor_fail,
+ monitor_release,
+ output line monitor_update,
+ output logic monitor_commit
+);
+
+ line monitor_rd, monitor_wr;
+ word update_3, update_2, update_1, update_0;
+ logic dirty, done, hit, known;
+ addr_tag tag;
+ addr_index index;
+
+ logic[3:0] mask, mask_clear, core_ex_mask;
+
+ assign monitor_commit = !core_lock || (hit && known && done);
+ assign monitor_update = {update_3, update_2, update_1, update_0};
+
+ /* Avalon p. 15:
+ * - 00: OKAY - Successful response for a transaction.
+ * - 10: SLVERR - Error from an endpoint agent. Indicates an unsuccessful transaction.
+ */
+ assign core_response = {monitor_fail, 1'b0};
+
+ assign hit = tag == core_tag && index == core_index;
+ assign done = monitor_rd == data_rd && mask_clear == 4'b0000;
+ assign known = mask[core_offset];
+ assign mask_clear = mask & ~core_ex_mask;
+
+ always_comb begin
+ {update_3, update_2, update_1, update_0} = monitor_wr;
+
+ unique case (core_offset)
+ 2'b00: begin
+ update_0 = core_writedata;
+ core_ex_mask = 4'b0001;
+ end
+
+ 2'b01: begin
+ update_1 = core_writedata;
+ core_ex_mask = 4'b0010;
+ end
+
+ 2'b10: begin
+ update_2 = core_writedata;
+ core_ex_mask = 4'b0100;
+ end
+
+ 2'b11: begin
+ update_3 = core_writedata;
+ core_ex_mask = 4'b1000;
+ end
+ endcase
+ end
+
+ always @(posedge clk or negedge rst_n)
+ if (!rst_n) begin
+ mask <= 4'b0000;
+ dirty <= 0;
+ end else begin
+ if (monitor_acquire) begin
+ mask <= hit && !known && !dirty ? mask | core_ex_mask : core_ex_mask;
+ dirty <= 0;
+ end
+
+ if (monitor_release) begin
+ mask <= hit && known ? mask_clear : 4'b0000;
+ dirty <= hit && known;
+ end
+ end
+
+ always_ff @(posedge clk) begin
+ if (monitor_acquire) begin
+ tag <= core_tag;
+ index <= core_index;
+
+ if (!hit || known || dirty || mask == 4'b0000) begin
+ monitor_rd <= data_rd;
+ monitor_wr <= data_rd;
+ end
+ end
+
+ if (monitor_release)
+ monitor_wr <= monitor_update;
+ end
+
+endmodule