diff options
| author | Alejandro Soto <alejandro@34project.org> | 2023-09-29 19:50:01 -0600 |
|---|---|---|
| committer | Alejandro Soto <alejandro@34project.org> | 2023-09-29 20:51:28 -0600 |
| commit | bc98bc905c2e796f0d587719196f7e4bf344510a (patch) | |
| tree | f5859d0b2f4fd5ab8c785a7cbaffa54dc81bc797 /rtl/cache/control.sv | |
| parent | f06c23ac1327850eeeb390e155bfc6330d302a77 (diff) | |
platform: add CPUs and caches to qsys
Diffstat (limited to 'rtl/cache/control.sv')
| -rw-r--r-- | rtl/cache/control.sv | 373 |
1 files changed, 0 insertions, 373 deletions
diff --git a/rtl/cache/control.sv b/rtl/cache/control.sv deleted file mode 100644 index 73eb644..0000000 --- a/rtl/cache/control.sv +++ /dev/null @@ -1,373 +0,0 @@ -`include "cache/defs.sv" - -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, - 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, - - 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 - { - ACCEPT, - CORE, - SNOOP, - REPLY - } state, next_state; - - logic accept_snoop, in_hold_valid, inval_reply, last_hop, lock_line, locked, - 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; - - 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; - assign mem_address = {3'b000, mem_tag, mem_index, 4'b0000}; - assign mem_read_end = mem_read && !mem_waitrequest; - - /* Desbloquear la línea hasta que la request del core termine garantiza - * avance del sistema completo, en lockstep en el peor caso posible, - * a pesar de retries (una fuerte contención de writes a INVALID - * o SHARED jamás provocará que dos o más nodos queden en deadlock). - */ - assign unlock_line = !core_waitrequest; - - assign replace = tag_rd != core_tag && state_rd != INVALID; - assign last_hop = in_hold.ttl == `TTL_END; - assign snoop_hit = tag_rd == in_hold.tag; - assign accept_snoop = in_hold_valid && !last_hop && (in_hold.inval || !in_hold.reply); - - assign may_send = may_send_if_token_held && in_token_valid; - assign may_send_if_token_held - = (!in_token.e2.valid || in_token.e2.index != core_index || in_token.e2.tag != core_tag) - && (!in_token.e1.valid || in_token.e1.index != core_index || in_token.e1.tag != core_tag) - && (!in_token.e0.valid || in_token.e0.index != core_index || in_token.e0.tag != core_tag); - - assign out_data = out_stall ? stall_data : out_data_next; - assign out_data_next = send ? send_data : fwd_data; - assign out_data_valid = out_stall || send || (in_hold_valid && !last_hop && in_data_ready); - - assign send_data.tag = core_tag; - assign send_data.ttl = `TTL_MAX; - assign send_data.data = fwd_data.data; // Esto evita muchos muxes - assign send_data.read = send_read; - assign send_data.index = core_index; - assign send_data.inval = send_inval; - assign send_data.reply = 0; - - always_comb begin - tag_wr = core_tag; - data_wr = core_data_wr; - index_rd = core_index; - - state_wr = INVALID; //FIXME: debería ser 'bx - write_data = 0; - write_state = 0; - - mem_begin = 0; - writeback = 0; - - send = 0; - send_read = 0; - send_inval = 0; - - set_reply = 0; - inval_reply = 0; - core_waitrequest = 1; - - in_data_ready = !in_hold_valid; - - unique case (state) - ACCEPT: begin - if (last_hop && !in_hold.read) begin - inval_reply = in_hold_valid; - in_data_ready = 1; - end - - if (accept_snoop) - index_rd = in_hold.index; - end - - CORE: - if (replace) begin - state_wr = INVALID; - write_state = 1; - - if (state_rd == MODIFIED) - writeback = 1; - end else unique case ({state_rd, core_write}) - {INVALID, 1'b0}: begin - send = 1; - send_read = 1; - end - - {INVALID, 1'b1}: begin - send = 1; - send_read = 1; - send_inval = 1; - end - - {SHARED, 1'b0}: - core_waitrequest = 0; - - {SHARED, 1'b1}: begin - /* No hacemos write_data ya que reintentaremos el - * write luego, cuando el estado será EXCLUSIVE. - * - * Nótese que esta es la misma razón por la que no - * pasamos directamente a MODIFIED. - */ - state_wr = EXCLUSIVE; - write_state = 1; - - send = 1; - send_inval = 1; - end - - {EXCLUSIVE, 1'b0}: - core_waitrequest = 0; - - {EXCLUSIVE, 1'b1}: begin - state_wr = MODIFIED; - write_data = 1; - write_state = 1; - core_waitrequest = 0; - end - - {MODIFIED, 1'b0}: - core_waitrequest = 0; - - {MODIFIED, 1'b1}: begin - write_data = 1; - core_waitrequest = 0; - end - endcase - - SNOOP: begin - index_rd = in_hold.index; - in_data_ready = 1; - - if (snoop_hit) begin - if (in_hold.read) begin - set_reply = 1; - - unique case (state_rd) - INVALID: - set_reply = 0; - - SHARED: ; - - EXCLUSIVE: begin - state_wr = SHARED; - write_state = 1; - end - - MODIFIED: begin - state_wr = SHARED; - write_state = 1; - - writeback = 1; - end - endcase - end - - if (in_hold.inval) begin - state_wr = INVALID; - write_state = 1; - end - end - end - - REPLY: begin - in_data_ready = 1; - - if (in_hold.reply) begin - data_wr = in_hold.data; - state_wr = SHARED; - write_data = 1; - write_state = 1; - end else - mem_begin = 1; - end - - default: ; - endcase - - if (writeback) - mem_begin = 1; - - // Colisiones de bus - retry = (mem_read_end && (write_data || write_state)) || (mem_wait && mem_begin); - - // Nótese la diferencia con un assign, ya que send puede cambiar más abajo - lock_line = send; - - if (send && !may_send && !locked) - retry = 1; - - if (retry) begin - send = 0; - mem_begin = 0; - write_data = 0; - write_state = 0; - - in_data_ready = !in_hold_valid; - core_waitrequest = 1; - end - - index_wr = index_rd; - if (mem_read_end) begin - tag_wr = mem_tag; - index_wr = mem_index; - - data_wr = mem_readdata; - state_wr = EXCLUSIVE; - - write_data = 1; - write_state = 1; - end - end - - always_comb begin - fwd_data = in_hold; - fwd_data.ttl = in_hold.ttl - 2'b1; - - if (set_reply) begin - fwd_data.data = data_rd; - fwd_data.reply = 1; - end - end - - always_comb begin - next_state = ACCEPT; - - unique case (state) - ACCEPT: begin - if (accept_snoop) - next_state = SNOOP; - else if (in_hold_valid && last_hop && in_hold.read) - next_state = REPLY; - else if ((core_read || core_write) && !wait_reply && (!locked || may_send)) - next_state = CORE; - - if (out_stall && !out_data_ready) - next_state = ACCEPT; - end - - default: ; - endcase - end - - always_ff @(posedge clk or negedge rst_n) - state <= !rst_n ? ACCEPT : next_state; - - always_ff @(posedge clk or negedge rst_n) - if (!rst_n) begin - out_token <= {($bits(out_token)){1'b0}}; - out_token_valid <= TOKEN_AT_RESET; - - in_hold_valid <= 0; - out_stall <= 0; - - locked <= 0; - wait_reply <= 0; - - mem_read <= 0; - mem_write <= 0; - end else begin - out_token.e0.tag <= core_tag; - out_token.e0.index <= core_index; - out_token.e0.valid <= may_send_if_token_held && (send || locked) && !unlock_line; - - out_token.e2 <= in_token.e1; - out_token.e1 <= in_token.e0; - out_token_valid <= in_token_valid; - - if (in_data_ready) - in_hold_valid <= in_data_valid; - - out_stall <= out_data_valid && !out_data_ready; - - if (lock_line) - locked <= 1; - - if (unlock_line) - locked <= 0; - - if (send) - wait_reply <= 1; - - if (inval_reply || mem_read_end) - wait_reply <= 0; - - if (mem_end) begin - mem_read <= 0; - mem_write <= 0; - end - - if (mem_begin) begin - mem_read <= !writeback; - mem_write <= writeback; - end - end - - always_ff @(posedge clk) begin - if (in_data_ready) - in_hold <= in_data; - - if (!out_stall) - stall_data <= out_data_next; - - if (mem_begin) begin - mem_tag <= writeback ? tag_rd : core_tag; - mem_index <= index_wr; - mem_writedata <= data_rd; - end - end - -endmodule |
