diff options
Diffstat (limited to 'rtl')
| -rw-r--r-- | rtl/cache/cache.sv | 26 | ||||
| -rw-r--r-- | rtl/cache/cache_control.sv | 152 | ||||
| -rw-r--r-- | rtl/cache/cache_debug.sv | 71 | ||||
| -rw-r--r-- | rtl/cache/defs.sv | 19 | ||||
| -rw-r--r-- | rtl/cache/monitor.sv | 103 | ||||
| -rw-r--r-- | rtl/core/control/control.sv | 4 | ||||
| -rw-r--r-- | rtl/core/control/cycles.sv | 4 | ||||
| -rw-r--r-- | rtl/core/control/ldst/ldst.sv | 36 | ||||
| -rw-r--r-- | rtl/core/control/writeback.sv | 5 | ||||
| -rw-r--r-- | rtl/core/decode/decode.sv | 10 | ||||
| -rw-r--r-- | rtl/core/decode/isa.sv | 13 | ||||
| -rw-r--r-- | rtl/core/decode/ldst/exclusive.sv | 27 | ||||
| -rw-r--r-- | rtl/core/decode/ldst/misc.sv | 1 | ||||
| -rw-r--r-- | rtl/core/decode/ldst/multiple.sv | 1 | ||||
| -rw-r--r-- | rtl/core/decode/ldst/single.sv | 1 | ||||
| -rw-r--r-- | rtl/core/decode/mux.sv | 20 | ||||
| -rw-r--r-- | rtl/core/uarch.sv | 1 |
17 files changed, 393 insertions, 101 deletions
diff --git a/rtl/cache/cache.sv b/rtl/cache/cache.sv index 29403e2..6d5a204 100644 --- a/rtl/cache/cache.sv +++ b/rtl/cache/cache.sv @@ -16,13 +16,12 @@ module cache output logic[1:0] core_response, output word core_readdata, - //TODO - /*input TODO/ dbg_address, + input logic[2:0] dbg_address, input logic dbg_read, dbg_write, input word dbg_writedata, output logic dbg_waitrequest, - output word dbg_readdata,*/ + output word dbg_readdata, input logic mem_waitrequest, input line mem_readdata, @@ -47,9 +46,6 @@ module cache output logic out_token_valid ); - //TODO - //assign dbg_waitrequest = 1; - logic write_data, write_state; line data_wr, data_rd; addr_tag tag_wr, tag_rd; @@ -63,7 +59,8 @@ module cache word cache_mem_address; line cache_mem_writedata; - logic cache_core_waitrequest, cache_mem_waitrequest, cache_mem_read, cache_mem_write; + logic cache_core_waitrequest, cache_mem_waitrequest, cache_mem_read, cache_mem_write, + debug_ready; cache_control #(.TOKEN_AT_RESET(TOKEN_AT_RESET)) control ( @@ -97,4 +94,19 @@ module cache .* ); + line monitor_update; + logic monitor_acquire, monitor_commit, monitor_fail, monitor_release; + + cache_monitor monitor + ( + .* + ); + + addr_index debug_index; + + cache_debug debug + ( + .* + ); + endmodule diff --git a/rtl/cache/cache_control.sv b/rtl/cache/cache_control.sv index fb7896a..33d380a 100644 --- a/rtl/cache/cache_control.sv +++ b/rtl/cache/cache_control.sv @@ -3,51 +3,60 @@ module cache_control #(parameter TOKEN_AT_RESET=0) ( - input logic clk, - rst_n, + 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 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 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 logic out_data_ready, + output ring_req out_data, + output logic out_data_valid, - input ring_token in_token, - input logic in_token_valid, + input ring_token in_token, + input logic in_token_valid, - output ring_token out_token, - output logic out_token_valid, + output ring_token out_token, + output logic out_token_valid, // Señales para la SRAM - 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 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, + + input logic dbg_write, + input addr_index debug_index, + output logic debug_ready ); enum int unsigned @@ -58,24 +67,15 @@ module cache_control REPLY } 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; + logic accept_snoop, debug, 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, 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; @@ -135,6 +135,7 @@ module cache_control monitor_fail = 0; monitor_acquire = 0; + monitor_release = 0; core_waitrequest = 1; in_data_ready = !in_hold_valid; @@ -146,17 +147,19 @@ module cache_control end_reply = in_hold_valid; // Se termina el paso de ese mensaje in_data_ready = 1; end + // Si no es el último salto y hay reply - if (!last_hop && in_hold.reply) + if (!last_hop && in_hold.reply && !in_hold.inval) in_data_ready = 1; if (accept_snoop) index_rd = in_hold.index; + + if (debug) + index_rd = debug_index; end CORE: begin - monitor_acquire = core_read && core_lock; - if (replace) begin state_wr = INVALID; write_state = 1; @@ -175,8 +178,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 @@ -192,8 +197,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; @@ -201,19 +208,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 @@ -286,6 +302,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 @@ -314,6 +333,7 @@ module cache_control end always_comb begin + debug = 0; next_state = ACCEPT; unique case (state) @@ -322,6 +342,8 @@ module cache_control next_state = SNOOP; else if (in_hold_valid && last_hop && in_hold.read) next_state = REPLY; + else if (dbg_write && !debug_ready) + debug = 1; else if ((core_read || core_write) && !wait_reply && (!locked || may_send)) next_state = CORE; @@ -349,6 +371,8 @@ module cache_control mem_read <= 0; mem_write <= 0; + + debug_ready <= 0; end else begin out_token.e0.tag <= core_tag; out_token.e0.index <= core_index; @@ -384,6 +408,8 @@ module cache_control mem_read <= !writeback; mem_write <= writeback; end + + debug_ready <= debug; end always_ff @(posedge clk) begin @@ -398,14 +424,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/cache_debug.sv b/rtl/cache/cache_debug.sv new file mode 100644 index 0000000..14b73e5 --- /dev/null +++ b/rtl/cache/cache_debug.sv @@ -0,0 +1,71 @@ +`include "cache/defs.sv" + +module cache_debug +( + input logic clk, + rst_n, + + input logic[2:0] dbg_address, + input logic dbg_read, + input word dbg_writedata, + output logic dbg_waitrequest, + output word dbg_readdata, + + input logic debug_ready, + input addr_tag tag_rd, + input line data_rd, + input line_state state_rd, + output addr_index debug_index +); + + struct packed + { + logic[2:0] mbz_0; + addr_tag tag; + addr_index index; + line_state state; + logic cached, + mbz_1; + } status; + + line line_dump; + word word_dump, word_3, word_2, word_1, word_0; + addr_bits debug_addr_bits; + + logic cached; + addr_tag tag; + addr_index index; + line_state state; + + assign debug_index = debug_addr_bits.index; + assign dbg_readdata = dbg_address[2] ? word_dump : status; + assign dbg_waitrequest = !debug_ready && !dbg_read; + + assign status.tag = tag; + assign status.index = index; + assign status.state = state; + assign status.mbz_0 = 3'b000; + assign status.mbz_1 = 0; + assign status.cached = cached; + assign debug_addr_bits = dbg_writedata; + + assign {word_3, word_2, word_1, word_0} = line_dump; + + always_comb + unique case (dbg_address[1:0]) + 2'b00: word_dump = word_0; + 2'b01: word_dump = word_1; + 2'b10: word_dump = word_2; + 2'b11: word_dump = word_3; + endcase + + always @(posedge clk) + if (debug_ready) begin + tag <= tag_rd; + index <= debug_addr_bits.index; + state <= state_rd; + cached <= !(|debug_addr_bits.io); + line_dump <= data_rd; + end + +endmodule diff --git a/rtl/cache/defs.sv b/rtl/cache/defs.sv index e21e587..d7c43dc 100644 --- a/rtl/cache/defs.sv +++ b/rtl/cache/defs.sv @@ -13,21 +13,30 @@ typedef logic[31:0] word; `endif /* Tenemos 512MiB de SDRAM, el resto del espacio es I/O (uncached). Usamos - * 512 líneas direct-mapped de 16 bytes cada una. El core solo realiza + * 4096 líneas direct-mapped de 16 bytes cada una. El core solo realiza * operaciones alineadas. Por tanto, cada dirección de 32 bits consta de: * - 2 bits que siempre son 0 (traducidos a byteenable por core) * - 2 bits de offset (ya que para cache la unidad direccionable es la word) - * - 9 bits de index - * - 16 bits de tag + * - 12 bits de index + * - 13 bits de tag * - 3 bits que son == 0 si cached, != 0 si uncached */ typedef logic[1:0] addr_mbz; typedef logic[1:0] addr_offset; -typedef logic[8:0] addr_index; -typedef logic[15:0] addr_tag; +typedef logic[11:0] addr_index; +typedef logic[12:0] addr_tag; typedef logic[2:0] addr_io_region; typedef logic[26:0] addr_cacheable; +typedef struct packed +{ + addr_io_region io; + addr_tag tag; + addr_index index; + addr_offset offset; + addr_mbz mbz; +} addr_bits; + typedef enum logic[1:0] { INVALID, 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 diff --git a/rtl/core/control/control.sv b/rtl/core/control/control.sv index 6090f2d..27be940 100644 --- a/rtl/core/control/control.sv +++ b/rtl/core/control/control.sv @@ -112,8 +112,8 @@ module core_control .* ); - word mem_offset, ldst_read; - logic ldst, ldst_next, ldst_writeback, pop_valid; + word mem_offset, ldst_read, strex_ok; + logic ldst, ldst_next, ldst_reject, ldst_writeback, pop_valid; reg_num popped; logic[1:0] ldst_shift; diff --git a/rtl/core/control/cycles.sv b/rtl/core/control/cycles.sv index 5779990..772697d 100644 --- a/rtl/core/control/cycles.sv +++ b/rtl/core/control/cycles.sv @@ -18,6 +18,7 @@ module core_control_cycles mul_ready, pop_valid, trivial_shift, + ldst_reject, ldst_writeback, data_snd_shift_by_reg, @@ -109,6 +110,9 @@ module core_control_cycles if(mem_ready && mem_fault) next_state = ESCALATE; + + if(ldst_reject) + next_state = ISSUE; end MUL: diff --git a/rtl/core/control/ldst/ldst.sv b/rtl/core/control/ldst/ldst.sv index 0e0a39c..aa5c957 100644 --- a/rtl/core/control/ldst/ldst.sv +++ b/rtl/core/control/ldst/ldst.sv @@ -29,24 +29,26 @@ module core_control_ldst pop_valid, ldst, ldst_next, + ldst_reject, ldst_writeback, output logic[1:0] ldst_shift, output word ldst_read, + strex_ok, output reg_num popped ); word base; - logic pre, increment, sign_extend; + logic block_strex, increment, pre, sign_extend; reg_num popped_upper, popped_lower; reg_list mem_regs, next_regs_upper, next_regs_lower; ldst_size size; assign popped = increment ? popped_lower : popped_upper; assign ldst_next = !cycle.transfer || mem_ready; - assign mem_data_wr = q_shifter; + assign mem_data_wr = mem_ex_lock ? alu_b : q_shifter; - //TODO - assign mem_ex_lock = 0; + assign strex_ok = {31'd0, mem_ex_fail || block_strex}; + assign ldst_reject = mem_ex_lock && mem_write && block_strex; core_control_ldst_pop pop ( @@ -69,11 +71,12 @@ module core_control_ldst ); always_ff @(posedge clk or negedge rst_n) - if(!rst_n) begin + if (!rst_n) begin pre <= 0; ldst <= 0; size <= LDST_WORD; increment <= 0; + block_strex <= 1; sign_extend <= 0; ldst_writeback <= 0; @@ -83,12 +86,13 @@ module core_control_ldst mem_write <= 0; mem_start <= 0; mem_offset <= 0; + mem_ex_lock <= 0; end else begin - if(mem_start) + if (mem_start) mem_start <= 0; - if(next_cycle.issue) begin - if(issue) begin + if (next_cycle.issue) begin + if (issue) begin ldst <= dec.ctrl.ldst; mem_user <= dec.ldst.unprivileged; end @@ -101,19 +105,25 @@ module core_control_ldst mem_regs <= dec.ldst.regs; mem_write <= !dec.ldst.load; - end else if(next_cycle.transfer) begin - if(!cycle.transfer) begin + mem_ex_lock <= dec.ldst.exclusive; + end else if (next_cycle.transfer) begin + if (!cycle.transfer) begin ldst <= 0; mem_offset <= alu_b; end - if(ldst_next) begin + if (ldst_next) begin base <= pre ? q_alu : alu_a; mem_regs <= increment ? next_regs_lower : next_regs_upper; end - mem_start <= !cycle.transfer || (mem_ready && pop_valid); - end else if(cycle.escalate) + mem_start <= (!cycle.transfer || (mem_ready && pop_valid)) && !ldst_reject; + + if (block_strex) + block_strex <= !mem_ex_lock || mem_write; + end else if (cycle.escalate) begin ldst <= 0; + block_strex <= 1; + end end endmodule diff --git a/rtl/core/control/writeback.sv b/rtl/core/control/writeback.sv index a7738fb..027a7d7 100644 --- a/rtl/core/control/writeback.sv +++ b/rtl/core/control/writeback.sv @@ -10,9 +10,11 @@ module core_control_writeback input word q_alu, ldst_read, input logic mem_ready, + mem_ex_lock, mem_write, input word mul_q_hi, mul_q_lo, + strex_ok, input ctrl_cycle cycle, next_cycle, @@ -26,6 +28,7 @@ module core_control_writeback input logic issue, pop_valid, ldst_next, + ldst_reject, output reg_num rd, final_rd, @@ -62,7 +65,7 @@ module core_control_writeback writeback = 0; if(cycle.transfer) - wr_value = ldst_read; + wr_value = (mem_ex_lock && mem_write) ? strex_ok : ldst_read; else if(cycle.base_writeback) wr_value = saved_base; else if(cycle.mul || cycle.mul_hi_wb) diff --git a/rtl/core/decode/decode.sv b/rtl/core/decode/decode.sv index b00e06f..219f975 100644 --- a/rtl/core/decode/decode.sv +++ b/rtl/core/decode/decode.sv @@ -127,6 +127,16 @@ module core_decode .* ); + reg_num ldst_ex_snd_r; + ldst_decode ldst_exclusive; + + core_decode_ldst_exclusive group_ldst_ex + ( + .snd_r(ldst_ex_snd_r), + .decode(ldst_exclusive), + .* + ); + ldst_decode ldst_addr; data_decode data_ldst; diff --git a/rtl/core/decode/isa.sv b/rtl/core/decode/isa.sv index 2ad5b40..6784eca 100644 --- a/rtl/core/decode/isa.sv +++ b/rtl/core/decode/isa.sv @@ -162,7 +162,18 @@ `define FIELD_LDST_MULT_RN [19:16] `define FIELD_LDST_MULT_LIST [15:0] -// Instrucciones atómicas de intercambio registro-memoria +// Instrucciones para operaciones atómicas optimistas (monitor exclusivo) + +`define INSN_LDREX 28'b0001100_1_????_????_1111_1001_1111 +`define INSN_STREX 28'b0001100_0_????_????_1111_1001_???? +`define GROUP_LDST_EX `INSN_LDREX, `INSN_STREX + +`define FIELD_LDST_EX_LD [20] +`define FIELD_LDST_EX_RN [19:16] +`define FIELD_LDST_EX_RD [15:12] +`define FIELD_LDST_EX_R_OK [3:0] + +// Instrucciones atómicas de intercambio registro-memoria (deprecadas) `define INSN_SWP 28'b00010000_????_????_0000_1001_???? `define INSN_SWPB 28'b00010100_????_????_0000_1001_???? diff --git a/rtl/core/decode/ldst/exclusive.sv b/rtl/core/decode/ldst/exclusive.sv new file mode 100644 index 0000000..7942a04 --- /dev/null +++ b/rtl/core/decode/ldst/exclusive.sv @@ -0,0 +1,27 @@ +`include "core/decode/isa.sv" +`include "core/uarch.sv" + +module core_decode_ldst_exclusive +( + input word insn, + + output ldst_decode decode, + output reg_num snd_r +); + + assign snd_r = insn `FIELD_LDST_EX_R_OK; + + assign decode.rn = insn `FIELD_LDST_EX_RN; + assign decode.rd = insn `FIELD_LDST_EX_RD; + assign decode.size = LDST_WORD; + assign decode.load = insn `FIELD_LDST_EX_LD; + assign decode.increment = 0; + assign decode.writeback = 0; + assign decode.exclusive = 1; + assign decode.sign_extend = 0; + assign decode.pre_indexed = 0; + assign decode.unprivileged = 0; + assign decode.user_regs = 0; + assign decode.regs = 16'b0; + +endmodule diff --git a/rtl/core/decode/ldst/misc.sv b/rtl/core/decode/ldst/misc.sv index 4e4a17e..72d648c 100644 --- a/rtl/core/decode/ldst/misc.sv +++ b/rtl/core/decode/ldst/misc.sv @@ -19,6 +19,7 @@ module core_decode_ldst_misc assign decode.load = insn `FIELD_LDST_LD; assign decode.increment = insn `FIELD_LDST_MISC_U; assign decode.writeback = !p || w; + assign decode.exclusive = 0; assign decode.sign_extend = insn `FIELD_LDST_MISC_S; assign decode.pre_indexed = p; assign decode.unprivileged = 0; diff --git a/rtl/core/decode/ldst/multiple.sv b/rtl/core/decode/ldst/multiple.sv index 0ecd674..c822ab0 100644 --- a/rtl/core/decode/ldst/multiple.sv +++ b/rtl/core/decode/ldst/multiple.sv @@ -18,6 +18,7 @@ module core_decode_ldst_multiple assign decode.load = l; assign decode.increment = insn `FIELD_LDST_MULT_U; assign decode.writeback = insn `FIELD_LDST_MULT_W; + assign decode.exclusive = 0; assign decode.sign_extend = 0; assign decode.pre_indexed = insn `FIELD_LDST_MULT_P; assign decode.unprivileged = 0; diff --git a/rtl/core/decode/ldst/single.sv b/rtl/core/decode/ldst/single.sv index 402c17b..af096a7 100644 --- a/rtl/core/decode/ldst/single.sv +++ b/rtl/core/decode/ldst/single.sv @@ -17,6 +17,7 @@ module core_decode_ldst_single assign decode.load = insn `FIELD_LDST_LD; assign decode.increment = insn `FIELD_LDST_SINGLE_U; assign decode.writeback = !p || w; + assign decode.exclusive = 0; assign decode.sign_extend = 0; assign decode.pre_indexed = p; assign decode.unprivileged = !p && w; diff --git a/rtl/core/decode/mux.sv b/rtl/core/decode/mux.sv index 297ad33..6f0451a 100644 --- a/rtl/core/decode/mux.sv +++ b/rtl/core/decode/mux.sv @@ -18,12 +18,14 @@ module core_decode_mux data_is_imm, data_shift_by_reg_if_reg, - input ldst_decode ldst_single, - ldst_misc, + input ldst_decode ldst_misc, + ldst_single, ldst_multiple, + ldst_exclusive, input logic ldst_single_is_imm, ldst_misc_off_is_imm, - input reg_num ldst_misc_off_reg, + input reg_num ldst_ex_snd_r, + ldst_misc_off_reg, input logic[7:0] ldst_misc_off_imm, input logic ldst_mult_restore_spsr, input data_decode data_ldst, @@ -135,6 +137,14 @@ module core_decode_mux update_flags = mul_update_flags; end + `GROUP_LDST_EX: begin + dec_ldst = ldst_exclusive; + ldst_addr = ldst_exclusive; + + dec_snd.r = ldst_ex_snd_r; + dec_snd.is_imm = ldst_exclusive.load; + end + `GROUP_LDST_MISC: begin dec_ldst = ldst_misc; ldst_addr = ldst_misc; @@ -255,10 +265,10 @@ module core_decode_mux // Codificación coincide con ldst `GROUP_MUL: ; - `GROUP_LDST_SINGLE, `GROUP_LDST_MISC, `GROUP_LDST_MULT: begin + `GROUP_LDST_SINGLE, `GROUP_LDST_MISC, `GROUP_LDST_MULT, `GROUP_LDST_EX: begin ldst = 1; dec_data = data_ldst; - writeback = dec_ldst.writeback || dec_ldst.load; + writeback = dec_ldst.writeback || dec_ldst.load || dec_ldst.exclusive; end default: ; diff --git a/rtl/core/uarch.sv b/rtl/core/uarch.sv index 38b0130..a474274 100644 --- a/rtl/core/uarch.sv +++ b/rtl/core/uarch.sv @@ -150,6 +150,7 @@ typedef struct packed logic load, increment, writeback, + exclusive, sign_extend, pre_indexed, unprivileged, |
