diff options
| -rw-r--r-- | cache_hw.tcl | 5 | ||||
| -rw-r--r-- | rtl/cache/cache.sv | 8 | ||||
| -rw-r--r-- | rtl/cache/cache_control.sv | 145 | ||||
| -rw-r--r-- | rtl/cache/monitor.sv | 103 |
4 files changed, 188 insertions, 73 deletions
diff --git a/cache_hw.tcl b/cache_hw.tcl index 4a06546..31aa5af 100644 --- a/cache_hw.tcl +++ b/cache_hw.tcl @@ -1,11 +1,11 @@ # TCL File Generated by Component Editor 20.1 -# Mon Oct 02 07:43:58 GMT 2023 +# Tue Oct 03 10:41:50 GMT 2023 # DO NOT MODIFY # # cache "8KiB 1-way cache w/ controller" v1.0 -# 2023.10.02.07:43:58 +# 2023.10.03.10:41:50 # # @@ -45,6 +45,7 @@ add_fileset_file defs.sv SYSTEM_VERILOG PATH rtl/cache/defs.sv add_fileset_file offsets.sv SYSTEM_VERILOG PATH rtl/cache/offsets.sv add_fileset_file routing.sv SYSTEM_VERILOG PATH rtl/cache/routing.sv add_fileset_file sram.sv SYSTEM_VERILOG PATH rtl/cache/sram.sv +add_fileset_file monitor.sv SYSTEM_VERILOG PATH rtl/cache/monitor.sv # 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 |
