diff options
| author | Alejandro Soto <alejandro@34project.org> | 2024-01-21 06:23:46 -0600 |
|---|---|---|
| committer | Alejandro Soto <alejandro@34project.org> | 2024-02-20 11:11:17 -0600 |
| commit | f3b18ead59ae02f95dabbf0a1dea40873a816975 (patch) | |
| tree | 8979e50f2a37f66a4cd27e937b480efe60d72cf7 /rtl/core/core_control_ldst.sv | |
| parent | a8bc5a353ea997f73209b39377ee15a73e471237 (diff) | |
rtl: refactor filenames and directory hierarchy
Diffstat (limited to 'rtl/core/core_control_ldst.sv')
| -rw-r--r-- | rtl/core/core_control_ldst.sv | 129 |
1 files changed, 129 insertions, 0 deletions
diff --git a/rtl/core/core_control_ldst.sv b/rtl/core/core_control_ldst.sv new file mode 100644 index 0000000..aa5c957 --- /dev/null +++ b/rtl/core/core_control_ldst.sv @@ -0,0 +1,129 @@ +`include "core/uarch.sv" + +module core_control_ldst +( + input logic clk, + rst_n, + + input insn_decode dec, + input logic issue, + mem_ready, + mem_ex_fail, + input word rd_value_b, + q_alu, + q_shifter, + + input ctrl_cycle cycle, + next_cycle, + input word alu_a, + alu_b, + + output ptr mem_addr, + output logic[3:0] mem_data_be, + output word mem_data_wr, + mem_offset, + output logic mem_start, + mem_write, + mem_ex_lock, + mem_user, + 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 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 = mem_ex_lock ? alu_b : q_shifter; + + 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 + ( + .regs(mem_regs), + .valid(pop_valid), + .next_upper(next_regs_upper), + .next_lower(next_regs_lower), + .pop_upper(popped_upper), + .pop_lower(popped_lower) + ); + + core_control_ldst_sizes sizes + ( + .addr(mem_addr), + .read(ldst_read), + .shift(ldst_shift), + .fault(), //TODO: alignment check + .byteenable(mem_data_be), + .* + ); + + always_ff @(posedge clk or negedge rst_n) + if (!rst_n) begin + pre <= 0; + ldst <= 0; + size <= LDST_WORD; + increment <= 0; + block_strex <= 1; + sign_extend <= 0; + ldst_writeback <= 0; + + base <= {$bits(base){1'b0}}; + mem_regs <= {$bits(mem_regs){1'b0}}; + mem_user <= 0; + mem_write <= 0; + mem_start <= 0; + mem_offset <= 0; + mem_ex_lock <= 0; + end else begin + if (mem_start) + mem_start <= 0; + + if (next_cycle.issue) begin + if (issue) begin + ldst <= dec.ctrl.ldst; + mem_user <= dec.ldst.unprivileged; + end + + pre <= dec.ldst.pre_indexed; + size <= dec.ldst.size; + increment <= dec.ldst.increment; + sign_extend <= dec.ldst.sign_extend; + ldst_writeback <= dec.ldst.writeback; + + mem_regs <= dec.ldst.regs; + mem_write <= !dec.ldst.load; + 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 + base <= pre ? q_alu : alu_a; + mem_regs <= increment ? next_regs_lower : next_regs_upper; + end + + 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 |
