summaryrefslogtreecommitdiff
path: root/rtl/core/control
diff options
context:
space:
mode:
authorAlejandro Soto <alejandro@34project.org>2024-01-21 06:23:46 -0600
committerAlejandro Soto <alejandro@34project.org>2024-02-20 11:11:17 -0600
commitf3b18ead59ae02f95dabbf0a1dea40873a816975 (patch)
tree8979e50f2a37f66a4cd27e937b480efe60d72cf7 /rtl/core/control
parenta8bc5a353ea997f73209b39377ee15a73e471237 (diff)
rtl: refactor filenames and directory hierarchy
Diffstat (limited to 'rtl/core/control')
-rw-r--r--rtl/core/control/branch.sv30
-rw-r--r--rtl/core/control/control.sv183
-rw-r--r--rtl/core/control/coproc.sv32
-rw-r--r--rtl/core/control/cycles.sv148
-rw-r--r--rtl/core/control/data.sv117
-rw-r--r--rtl/core/control/debug.sv25
-rw-r--r--rtl/core/control/exception.sv70
-rw-r--r--rtl/core/control/issue.sv80
-rw-r--r--rtl/core/control/ldst/ldst.sv129
-rw-r--r--rtl/core/control/ldst/pop.sv56
-rw-r--r--rtl/core/control/ldst/sizes.sv46
-rw-r--r--rtl/core/control/mul_fu.sv67
-rw-r--r--rtl/core/control/select.sv80
-rw-r--r--rtl/core/control/stall.sv42
-rw-r--r--rtl/core/control/status.sv81
-rw-r--r--rtl/core/control/writeback.sv128
16 files changed, 0 insertions, 1314 deletions
diff --git a/rtl/core/control/branch.sv b/rtl/core/control/branch.sv
deleted file mode 100644
index 0298b95..0000000
--- a/rtl/core/control/branch.sv
+++ /dev/null
@@ -1,30 +0,0 @@
-`include "core/uarch.sv"
-
-module core_control_branch
-(
- input logic clk,
- rst_n,
-
- input insn_decode dec,
-
- input ctrl_cycle next_cycle,
- input logic issue,
- input ptr next_pc_visible,
-
- output logic branch,
- output ptr branch_target
-);
-
- always_ff @(posedge clk or negedge rst_n)
- if(!rst_n) begin
- branch <= 1;
- branch_target <= {$bits(branch_target){1'b0}};
- end else begin
- branch <= 0;
- if(next_cycle.issue && issue) begin
- branch <= dec.ctrl.branch;
- branch_target <= next_pc_visible + dec.branch.offset;
- end
- end
-
-endmodule
diff --git a/rtl/core/control/control.sv b/rtl/core/control/control.sv
deleted file mode 100644
index 27be940..0000000
--- a/rtl/core/control/control.sv
+++ /dev/null
@@ -1,183 +0,0 @@
-`include "core/uarch.sv"
-
-module core_control
-(
- input logic clk,
- rst_n,
-
- input logic irq,
- halt,
- step,
-
- input insn_decode dec,
- input ptr insn_pc,
- input logic issue_abort,
- input psr_mode mode,
- input psr_intmask intmask,
- input psr_flags flags,
- alu_flags,
- input word cpsr_rd,
- spsr_rd,
- rd_value_a,
- rd_value_b,
- q_alu,
- q_shifter,
- input logic c_shifter,
- mem_ready,
- mem_fault,
- mem_ex_fail,
- input word mem_data_rd,
- input logic mul_ready,
- input word mul_q_hi,
- mul_q_lo,
- coproc_read,
- input logic high_vectors,
-
-`ifdef VERILATOR
- input word insn,
-`endif
-
- output logic halted,
- stall,
- branch,
- writeback,
- breakpoint,
- update_flags,
- c_logic,
- output reg_num rd,
- ra,
- rb,
- output ptr branch_target,
- pc_visible,
- output psr_mode rd_mode,
- wr_mode,
- output alu_op alu,
- output word alu_a,
- alu_b,
- wr_value,
- output shifter_control shifter,
- output word shifter_base,
- output logic[7:0] shifter_shift,
- output ptr mem_addr,
- output word mem_data_wr,
- output logic[3:0] mem_data_be,
- output logic mem_start,
- mem_write,
- mem_ex_lock,
- mem_user,
- output word mul_a,
- mul_b,
- mul_c_hi,
- mul_c_lo,
- output logic mul_add,
- mul_long,
- mul_start,
- mul_signed,
- coproc,
- escalating,
- psr_saved,
- psr_write,
- psr_wr_flags,
- psr_wr_control,
- output word psr_wr,
- output coproc_decode coproc_ctrl
-);
-
- ctrl_cycle cycle, next_cycle;
-
- core_control_cycles ctrl_cycles
- (
- .*
- );
-
- logic bubble, next_bubble;
-
- core_control_stall ctrl_stall
- (
- .*
- );
-
- ptr pc /*verilator public*/, next_pc_visible;
- logic issue, undefined, prefetch_abort;
-
- core_control_issue ctrl_issue
- (
- .*
- );
-
- logic rd_user;
-
- core_control_select ctrl_select
- (
- .*
- );
-
- 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;
-
- core_control_ldst ctrl_ldst
- (
- .*
- );
-
- core_control_branch ctrl_branch
- (
- .*
- );
-
- word saved_base;
- logic trivial_shift, data_snd_shift_by_reg;
-
- core_control_data ctrl_data
- (
- .*
- );
-
- logic mul;
- reg_num mul_r_add_hi, mul_r_add_lo;
-
- core_control_mul ctrl_mul
- (
- .*
- );
-
- word psr_wb;
- logic psr, final_psr_write, final_restore_spsr;
-
- core_control_psr ctrl_psr
- (
- .*
- );
-
- logic final_writeback, final_update_flags;
- reg_num final_rd;
-
- core_control_writeback ctrl_wb
- (
- .*
- );
-
- word exception_vector;
- logic exception, exception_offset_pc;
- psr_mode exception_mode;
-
- core_control_exception ctrl_exc
- (
- .*
- );
-
- word coproc_wb;
-
- core_control_coproc ctrl_cp
- (
- .*
- );
-
- core_control_debug ctrl_dbg
- (
- .*
- );
-
-endmodule
diff --git a/rtl/core/control/coproc.sv b/rtl/core/control/coproc.sv
deleted file mode 100644
index 05ac655..0000000
--- a/rtl/core/control/coproc.sv
+++ /dev/null
@@ -1,32 +0,0 @@
-`include "core/uarch.sv"
-
-module core_control_coproc
-(
- input logic clk,
- rst_n,
-
- input insn_decode dec,
- input word coproc_read,
-
- input ctrl_cycle next_cycle,
- input logic issue,
-
- output logic coproc,
- output word coproc_wb,
- output coproc_decode coproc_ctrl
-);
-
- always_ff @(posedge clk or negedge rst_n)
- if(!rst_n) begin
- coproc <= 0;
- coproc_wb <= 0;
- coproc_ctrl <= {$bits(coproc_ctrl){1'b0}};
- end else if(next_cycle.issue && issue) begin
- coproc <= dec.ctrl.coproc;
- coproc_ctrl <= dec.coproc;
- end else if(next_cycle.coproc) begin
- coproc <= 0;
- coproc_wb <= coproc_read;
- end
-
-endmodule
diff --git a/rtl/core/control/cycles.sv b/rtl/core/control/cycles.sv
deleted file mode 100644
index 772697d..0000000
--- a/rtl/core/control/cycles.sv
+++ /dev/null
@@ -1,148 +0,0 @@
-`include "core/uarch.sv"
-
-module core_control_cycles
-(
- input logic clk,
- rst_n,
- halt,
- mul,
- psr,
- ldst,
- bubble,
- coproc,
- exception,
- mem_ready,
- mem_fault,
- mul_add,
- mul_long,
- mul_ready,
- pop_valid,
- trivial_shift,
- ldst_reject,
- ldst_writeback,
- data_snd_shift_by_reg,
-
- output ctrl_cycle cycle,
- next_cycle
-);
-
- /* qts-qii51007-recommended-hdl.pdf, p. 66
- * In Quartus II integrated synthesis, the enumerated type that defines the states for the
- * state machine must be of an unsigned integer type as in Example 13–52. If you do not
- * specify the enumerated type as int unsigned, a signed int type is used by default. In
- * this case, the Quartus II integrated synthesis synthesizes the design, but does not infer
- * or optimize the logic as a state machine.
- */
- enum int unsigned
- {
- ISSUE,
- RD_INDIRECT_SHIFT,
- WITH_SHIFT,
- TRANSFER,
- BASE_WRITEBACK,
- ESCALATE,
- EXCEPTION,
- MUL,
- MUL_ACC_LD,
- MUL_HI_WB,
- PSR,
- COPROC
- } state, next_state;
-
- // TODO: debe estar escrito de tal forma que Quartus infiera una FSM
-
- assign cycle.issue = state == ISSUE;
- assign cycle.rd_indirect_shift = state == RD_INDIRECT_SHIFT;
- assign cycle.with_shift = state == WITH_SHIFT;
- assign cycle.transfer = state == TRANSFER;
- assign cycle.base_writeback = state == BASE_WRITEBACK;
- assign cycle.escalate = state == ESCALATE;
- assign cycle.exception = state == EXCEPTION;
- assign cycle.mul = state == MUL;
- assign cycle.mul_acc_ld = state == MUL_ACC_LD;
- assign cycle.mul_hi_wb = state == MUL_HI_WB;
- assign cycle.psr = state == PSR;
- assign cycle.coproc = state == COPROC;
-
- assign next_cycle.issue = next_state == ISSUE;
- assign next_cycle.rd_indirect_shift = next_state == RD_INDIRECT_SHIFT;
- assign next_cycle.with_shift = next_state == WITH_SHIFT;
- assign next_cycle.transfer = next_state == TRANSFER;
- assign next_cycle.base_writeback = next_state == BASE_WRITEBACK;
- assign next_cycle.escalate = next_state == ESCALATE;
- assign next_cycle.exception = next_state == EXCEPTION;
- assign next_cycle.mul = next_state == MUL;
- assign next_cycle.mul_acc_ld = next_state == MUL_ACC_LD;
- assign next_cycle.mul_hi_wb = next_state == MUL_HI_WB;
- assign next_cycle.psr = next_state == PSR;
- assign next_cycle.coproc = next_state == COPROC;
-
- always_comb begin
- next_state = ISSUE;
-
- unique case(state)
- ISSUE:
- if(exception)
- next_state = ESCALATE;
- else if(halt)
- next_state = ISSUE;
- else if(mul)
- next_state = mul_add ? MUL_ACC_LD : MUL;
- else if(data_snd_shift_by_reg)
- next_state = RD_INDIRECT_SHIFT;
- else if(!trivial_shift)
- next_state = WITH_SHIFT;
- else if(coproc)
- next_state = COPROC;
-
- RD_INDIRECT_SHIFT:
- if(!trivial_shift)
- next_state = WITH_SHIFT;
-
- ESCALATE:
- next_state = EXCEPTION;
-
- TRANSFER: begin
- if(!mem_ready || pop_valid)
- next_state = TRANSFER;
- else if(ldst_writeback)
- next_state = BASE_WRITEBACK;
-
- if(mem_ready && mem_fault)
- next_state = ESCALATE;
-
- if(ldst_reject)
- next_state = ISSUE;
- end
-
- MUL:
- if(!mul_ready)
- next_state = MUL;
- else if(mul_long)
- next_state = MUL_HI_WB;
-
- MUL_ACC_LD:
- next_state = MUL;
-
- /* Este default evita problemas de sintetizado, ya que Quartus
- * asume que los casos mencionados son exhaustivos, provocando
- * bugs muy difíciles de depurar. No es lo mismo que si se quita
- * default.
- */
- default: ;
- endcase
-
- if(bubble)
- next_state = ISSUE;
- else if(next_state == ISSUE) begin
- if(ldst)
- next_state = TRANSFER;
- else if(psr)
- next_state = PSR;
- end
- end
-
- always_ff @(posedge clk or negedge rst_n)
- state <= !rst_n ? ISSUE : next_state;
-
-endmodule
diff --git a/rtl/core/control/data.sv b/rtl/core/control/data.sv
deleted file mode 100644
index 3174ee1..0000000
--- a/rtl/core/control/data.sv
+++ /dev/null
@@ -1,117 +0,0 @@
-`include "core/uarch.sv"
-
-module core_control_data
-(
- input logic clk,
- rst_n,
-
- input insn_decode dec,
- input word rd_value_a,
- rd_value_b,
- input logic mem_ready,
- mem_write,
- input word mem_data_rd,
- q_alu,
- q_shifter,
- input logic c_shifter,
-
- input ctrl_cycle cycle,
- next_cycle,
- input ptr pc_visible,
- input logic ldst_next,
- input logic[1:0] ldst_shift,
- input word mem_offset,
- input psr_flags flags,
- input logic exception_offset_pc,
-
- output alu_op alu,
- output word alu_a,
- alu_b,
- saved_base,
- output shifter_control shifter,
- output word shifter_base,
- output logic[7:0] shifter_shift,
- output logic c_logic,
- trivial_shift,
- data_snd_shift_by_reg
-);
-
- logic data_snd_is_imm;
- logic[5:0] data_shift_imm;
- logic[11:0] data_imm;
-
- assign trivial_shift = shifter_shift == 0;
-
- always_comb begin
- if(cycle.rd_indirect_shift)
- shifter_shift = rd_value_b[7:0];
- else if(cycle.transfer)
- shifter_shift = {3'b000, ldst_shift, 3'b000};
- else
- shifter_shift = {2'b00, data_shift_imm};
-
- if(cycle.transfer)
- alu_a = saved_base;
- else if(cycle.exception)
- alu_a = {pc_visible, 2'b00};
- else
- alu_a = rd_value_a;
-
- if(cycle.rd_indirect_shift || cycle.with_shift)
- alu_b = saved_base;
- else if(cycle.transfer)
- alu_b = mem_offset;
- else if(data_snd_is_imm)
- alu_b = {{20{1'b0}}, data_imm};
- else
- alu_b = rd_value_b;
-
- if(cycle.transfer)
- shifter_base = mem_write ? rd_value_b : mem_data_rd;
- else
- shifter_base = alu_b;
- end
-
- always_ff @(posedge clk or negedge rst_n)
- if(!rst_n) begin
- alu <= {$bits(alu){1'b0}};
- c_logic <= 0;
- shifter <= {$bits(shifter){1'b0}};
- data_imm <= {$bits(data_imm){1'b0}};
- saved_base <= 0;
- data_shift_imm <= {$bits(data_shift_imm){1'b0}};
- data_snd_is_imm <= 0;
- data_snd_shift_by_reg <= 0;
- end else if(next_cycle.issue) begin
- alu <= dec.data.op;
- c_logic <= 0;
-
- data_imm <= dec.snd.imm;
- data_shift_imm <= dec.snd.shift_imm;
- data_snd_is_imm <= dec.snd.is_imm;
- data_snd_shift_by_reg <= dec.snd.shift_by_reg;
-
- shifter.shr <= dec.snd.shr;
- shifter.ror <= dec.snd.ror;
- shifter.put_carry <= dec.snd.put_carry;
- shifter.sign_extend <= dec.snd.sign_extend;
- end else if(next_cycle.rd_indirect_shift) begin
- saved_base <= rd_value_b;
- data_snd_shift_by_reg <= 0;
- end else if(next_cycle.with_shift) begin
- c_logic <= c_shifter;
- saved_base <= q_shifter;
- end else if(next_cycle.transfer) begin
- if(ldst_next)
- saved_base <= q_alu;
-
- shifter.ror <= 0;
- shifter.shr <= !mem_write;
- end else if(next_cycle.exception) begin
- alu <= `ALU_SUB;
- // Either pc_visible - 0 (pc + 8) or pc_visible - 4 (pc + 4)
- data_imm <= {9'd0, exception_offset_pc, 2'b00};
- data_snd_is_imm <= 1;
- end
-
-endmodule
diff --git a/rtl/core/control/debug.sv b/rtl/core/control/debug.sv
deleted file mode 100644
index 35b1334..0000000
--- a/rtl/core/control/debug.sv
+++ /dev/null
@@ -1,25 +0,0 @@
-`include "core/uarch.sv"
-
-module core_control_debug
-(
- input logic clk,
- rst_n,
- step,
-
- input ctrl_cycle next_cycle,
- input logic issue,
- next_bubble,
- input insn_decode dec,
-
- output logic breakpoint
-);
-
- logic stable, step_trigger;
-
- assign stable = next_cycle.issue && !dec.ctrl.nop && !next_bubble;
- assign breakpoint = stable && (dec.ctrl.bkpt || step_trigger);
-
- always @(posedge clk or negedge rst_n)
- step_trigger <= !rst_n ? 0 : step && (step_trigger || stable) && !breakpoint;
-
-endmodule
diff --git a/rtl/core/control/exception.sv b/rtl/core/control/exception.sv
deleted file mode 100644
index 387e9c1..0000000
--- a/rtl/core/control/exception.sv
+++ /dev/null
@@ -1,70 +0,0 @@
-`include "core/uarch.sv"
-
-module core_control_exception
-(
- input logic clk,
- rst_n,
-
- input ctrl_cycle cycle,
- next_cycle,
- input insn_decode dec,
- input psr_intmask intmask,
- input logic issue,
- irq,
- high_vectors,
- undefined,
- prefetch_abort,
- mem_fault,
-
- output logic escalating,
- exception,
- exception_offset_pc,
- output psr_mode exception_mode,
- output word exception_vector
-);
-
- logic pending_irq, syscall;
- logic[2:0] vector_offset;
-
- //TODO: fiq
-
- assign exception = undefined || syscall || prefetch_abort || mem_fault || pending_irq;
- assign escalating = cycle.escalate;
- assign exception_vector = {{16{high_vectors}}, 11'b0, vector_offset, 2'b00};
-
- always @(posedge clk or negedge rst_n)
- if(!rst_n) begin
- syscall <= 0;
- pending_irq <= 0;
- vector_offset <= 0;
- exception_mode <= 0;
- exception_offset_pc <= 0;
- end else begin
- if(next_cycle.issue) begin
- syscall <= issue && dec.ctrl.swi;
- pending_irq <= issue && irq && !intmask.i;
- end
-
- // A2.6.10 Exception priorities
- if(mem_fault) begin
- vector_offset <= 3'b100;
- exception_mode <= `MODE_ABT;
- end else if(pending_irq) begin
- vector_offset <= 3'b110;
- exception_mode <= `MODE_IRQ;
- end else if(prefetch_abort) begin
- vector_offset <= 3'b011;
- exception_mode <= `MODE_ABT;
- end else if(undefined) begin
- vector_offset <= 3'b001;
- exception_mode <= `MODE_UND;
- end else if(syscall) begin
- vector_offset <= 3'b010;
- exception_mode <= `MODE_SVC;
- end
-
- if(next_cycle.escalate)
- exception_offset_pc <= !mem_fault;
- end
-
-endmodule
diff --git a/rtl/core/control/issue.sv b/rtl/core/control/issue.sv
deleted file mode 100644
index 5bd03e1..0000000
--- a/rtl/core/control/issue.sv
+++ /dev/null
@@ -1,80 +0,0 @@
-`include "core/uarch.sv"
-
-module core_control_issue
-(
- input logic clk,
- rst_n,
-
- input logic halt,
- irq,
-
- input insn_decode dec,
- input ptr insn_pc,
- input logic issue_abort,
-
- input ctrl_cycle next_cycle,
- input logic next_bubble,
-
-`ifdef VERILATOR
- input word insn,
-`endif
-
- output logic issue,
- undefined,
- prefetch_abort,
- output ptr pc,
- pc_visible,
- next_pc_visible
-);
-
- logic valid;
-
-`ifdef VERILATOR
- word bh0 /*verilator public*/,
- bh1 /*verilator public*/,
- bh2 /*verilator public*/,
- bh3 /*verilator public*/;
-`endif
-
- assign valid = !next_bubble && !halt;
- assign issue = next_cycle.issue && dec.ctrl.execute && valid;
- assign next_pc_visible = insn_pc + 2;
-
- always_ff @(posedge clk or negedge rst_n)
- if(!rst_n) begin
- pc <= 0;
- undefined <= 0;
- pc_visible <= 2;
- prefetch_abort <= 0;
-
-`ifdef VERILATOR
- bh0 <= 0;
- bh1 <= 0;
- bh2 <= 0;
- bh3 <= 0;
-`endif
- end else if(next_cycle.issue) begin
- if(valid) begin
- undefined <= dec.ctrl.undefined;
- prefetch_abort <= issue_abort;
-
-`ifdef VERILATOR
- if(dec.ctrl.undefined && !issue_abort)
- $display("[core] undefined insn: [0x%08x] %08x", insn_pc << 2, insn);
-`endif
- end
-
- pc <= insn_pc;
- pc_visible <= next_pc_visible;
-
-`ifdef VERILATOR
- if(insn_pc != pc && insn_pc != pc + 1) begin
- bh0 <= {pc, 2'b00};
- bh1 <= bh0;
- bh2 <= bh1;
- bh3 <= bh2;
- end
-`endif
- end
-
-endmodule
diff --git a/rtl/core/control/ldst/ldst.sv b/rtl/core/control/ldst/ldst.sv
deleted file mode 100644
index aa5c957..0000000
--- a/rtl/core/control/ldst/ldst.sv
+++ /dev/null
@@ -1,129 +0,0 @@
-`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
diff --git a/rtl/core/control/ldst/pop.sv b/rtl/core/control/ldst/pop.sv
deleted file mode 100644
index 64dc04d..0000000
--- a/rtl/core/control/ldst/pop.sv
+++ /dev/null
@@ -1,56 +0,0 @@
-`include "core/uarch.sv"
-
-module core_control_ldst_pop
-(
- input reg_list regs,
-
- output logic valid,
- output reg_list next_upper,
- next_lower,
- output reg_num pop_upper,
- pop_lower
-);
-
- assign valid = regs != 16'b0;
-
- always_comb begin
- unique casez(regs)
- 16'b???????????????1: begin pop_lower = 4'h0; next_lower = {regs[15:1], 1'b0}; end
- 16'b??????????????10: begin pop_lower = 4'h1; next_lower = {regs[15:2], 2'b0}; end
- 16'b?????????????100: begin pop_lower = 4'h2; next_lower = {regs[15:3], 3'b0}; end
- 16'b????????????1000: begin pop_lower = 4'h3; next_lower = {regs[15:4], 4'b0}; end
- 16'b???????????10000: begin pop_lower = 4'h4; next_lower = {regs[15:5], 5'b0}; end
- 16'b??????????100000: begin pop_lower = 4'h5; next_lower = {regs[15:6], 6'b0}; end
- 16'b?????????1000000: begin pop_lower = 4'h6; next_lower = {regs[15:7], 7'b0}; end
- 16'b????????10000000: begin pop_lower = 4'h7; next_lower = {regs[15:8], 8'b0}; end
- 16'b???????100000000: begin pop_lower = 4'h8; next_lower = {regs[15:9], 9'b0}; end
- 16'b??????1000000000: begin pop_lower = 4'h9; next_lower = {regs[15:10], 10'b0}; end
- 16'b?????10000000000: begin pop_lower = 4'ha; next_lower = {regs[15:11], 11'b0}; end
- 16'b????100000000000: begin pop_lower = 4'hb; next_lower = {regs[15:12], 12'b0}; end
- 16'b???1000000000000: begin pop_lower = 4'hc; next_lower = {regs[15:13], 13'b0}; end
- 16'b??10000000000000: begin pop_lower = 4'hd; next_lower = {regs[15:14], 14'b0}; end
- 16'b?100000000000000: begin pop_lower = 4'he; next_lower = {regs[15], 15'b0}; end
- default: begin pop_lower = 4'hf; next_lower = 16'b0; end
- endcase
-
- unique casez(regs)
- 16'b1???????????????: begin pop_upper = 4'hf; next_upper = { 1'b0, regs[14:0]}; end
- 16'b01??????????????: begin pop_upper = 4'he; next_upper = { 2'b0, regs[13:0]}; end
- 16'b001?????????????: begin pop_upper = 4'hd; next_upper = { 3'b0, regs[12:0]}; end
- 16'b0001????????????: begin pop_upper = 4'hc; next_upper = { 4'b0, regs[11:0]}; end
- 16'b00001???????????: begin pop_upper = 4'hb; next_upper = { 5'b0, regs[10:0]}; end
- 16'b000001??????????: begin pop_upper = 4'ha; next_upper = { 6'b0, regs[9:0]}; end
- 16'b0000001?????????: begin pop_upper = 4'h9; next_upper = { 7'b0, regs[8:0]}; end
- 16'b00000001????????: begin pop_upper = 4'h8; next_upper = { 8'b0, regs[7:0]}; end
- 16'b000000001???????: begin pop_upper = 4'h7; next_upper = { 9'b0, regs[6:0]}; end
- 16'b0000000001??????: begin pop_upper = 4'h6; next_upper = {10'b0, regs[5:0]}; end
- 16'b00000000001?????: begin pop_upper = 4'h5; next_upper = {11'b0, regs[4:0]}; end
- 16'b000000000001????: begin pop_upper = 4'h4; next_upper = {12'b0, regs[3:0]}; end
- 16'b0000000000001???: begin pop_upper = 4'h3; next_upper = {13'b0, regs[2:0]}; end
- 16'b00000000000001??: begin pop_upper = 4'h2; next_upper = {14'b0, regs[1:0]}; end
- 16'b000000000000001?: begin pop_upper = 4'h1; next_upper = {15'b0, regs[0]}; end
- default: begin pop_upper = 4'h0; next_upper = 16'b0; end
- endcase
- end
-
-endmodule
diff --git a/rtl/core/control/ldst/sizes.sv b/rtl/core/control/ldst/sizes.sv
deleted file mode 100644
index dff4662..0000000
--- a/rtl/core/control/ldst/sizes.sv
+++ /dev/null
@@ -1,46 +0,0 @@
-`include "core/uarch.sv"
-
-module core_control_ldst_sizes
-(
- input word base,
- q_shifter,
- input ldst_size size,
- input logic sign_extend,
-
- output ptr addr,
- output word read,
- output logic[1:0] shift,
- output logic[3:0] byteenable,
- output logic fault
-);
-
- assign {addr, shift} = base;
-
- always_comb
- unique case(size)
- LDST_BYTE: begin
- read = {{24{q_shifter[7] && sign_extend}}, q_shifter[7:0]};
- fault = 0;
-
- unique case(shift)
- 2'b00: byteenable = 4'b0001;
- 2'b01: byteenable = 4'b0010;
- 2'b10: byteenable = 4'b0100;
- 2'b11: byteenable = 4'b1000;
- endcase
- end
-
- LDST_HALF: begin
- read = {{16{q_shifter[15] && sign_extend}}, q_shifter[15:0]};
- fault = shift[0];
- byteenable = shift[1] ? 4'b1100 : 4'b0011;
- end
-
- LDST_WORD: begin
- read = q_shifter;
- fault = shift[1] || shift[0];
- byteenable = 4'b1111;
- end
- endcase
-
-endmodule
diff --git a/rtl/core/control/mul_fu.sv b/rtl/core/control/mul_fu.sv
deleted file mode 100644
index 8352435..0000000
--- a/rtl/core/control/mul_fu.sv
+++ /dev/null
@@ -1,67 +0,0 @@
-`include "core/uarch.sv"
-
-module core_control_mul
-(
- input logic clk,
- rst_n,
-
- input insn_decode dec,
- input logic mul_ready,
- input word rd_value_a,
- rd_value_b,
-
- input ctrl_cycle cycle,
- next_cycle,
- input logic issue,
-
- output word mul_a,
- mul_b,
- mul_c_hi,
- mul_c_lo,
- output reg_num mul_r_add_hi,
- mul_r_add_lo,
- output logic mul,
- mul_add,
- mul_long,
- mul_start,
- mul_signed
-);
-
- word hold_a, hold_b;
-
- assign {mul_c_hi, mul_c_lo} = {rd_value_a, rd_value_b};
- assign {mul_a, mul_b} = mul_add ? {hold_a, hold_b} : {rd_value_a, rd_value_b};
-
- always_ff @(posedge clk or negedge rst_n)
- if(!rst_n) begin
- mul <= 0;
- mul_add <= 0;
- mul_long <= 0;
- mul_start <= 0;
- mul_signed <= 0;
- mul_r_add_hi <= {$bits(mul_r_add_hi){1'b0}};
- mul_r_add_lo <= {$bits(mul_r_add_lo){1'b0}};
-
- hold_a <= 0;
- hold_b <= 0;
- end else begin
- mul_start <= 0;
-
- if(next_cycle.issue) begin
- mul <= issue && dec.ctrl.mul;
- mul_add <= dec.mul.add;
- mul_long <= dec.mul.long_mul;
- mul_signed <= dec.mul.signed_mul;
- mul_r_add_hi <= dec.mul.r_add_hi;
- mul_r_add_lo <= dec.mul.r_add_lo;
- end else if(next_cycle.mul)
- mul_start <= !cycle.mul;
- else if(next_cycle.mul_acc_ld) begin
- hold_a <= rd_value_a;
- hold_b <= rd_value_b;
- end
- end
-
- //TODO: mul update_flags
-
-endmodule
diff --git a/rtl/core/control/select.sv b/rtl/core/control/select.sv
deleted file mode 100644
index dc04282..0000000
--- a/rtl/core/control/select.sv
+++ /dev/null
@@ -1,80 +0,0 @@
-`include "core/uarch.sv"
-
-module core_control_select
-(
- input logic clk,
- rst_n,
-
- input insn_decode dec,
-
- input ctrl_cycle next_cycle,
- input psr_mode mode,
- input logic issue,
- mem_ready,
- pop_valid,
- ldst_next,
- input reg_num popped,
- final_rd,
- mul_r_add_lo,
- mul_r_add_hi,
-
- output reg_num ra,
- rb,
- output psr_mode rd_mode,
- wr_mode,
- output logic rd_user
-);
-
- logic wr_user;
- reg_num r_shift, last_ra, last_rb;
-
- assign rd_mode = rd_user ? `MODE_USR : mode;
- assign wr_mode = wr_user ? `MODE_USR : mode;
-
- always_comb begin
- ra = last_ra;
- rb = last_rb;
-
- if(next_cycle.issue) begin
- ra = dec.data.rn;
- rb = dec.snd.r;
- end else if(next_cycle.rd_indirect_shift)
- rb = r_shift;
- else if(next_cycle.transfer) begin
- if(ldst_next)
- // final_rd viene de dec.ldst.rd
- rb = pop_valid ? popped : final_rd;
- end else if(next_cycle.mul_acc_ld) begin
- ra = mul_r_add_hi;
- rb = mul_r_add_lo;
- end
- end
-
- always_ff @(posedge clk or negedge rst_n)
- if(!rst_n) begin
- last_ra <= {$bits(ra){1'b0}};
- last_rb <= {$bits(rb){1'b0}};
- r_shift <= {$bits(r_shift){1'b0}};
-
- rd_user <= 0;
- wr_user <= 0;
- end else begin
- last_ra <= ra;
- last_rb <= rb;
-
- if(rd_user && next_cycle.transfer)
- wr_user <= 1;
-
- if(rd_user && !next_cycle.transfer)
- rd_user <= 0;
-
- if(wr_user && !next_cycle.transfer)
- wr_user <= 0;
-
- if(next_cycle.issue) begin
- r_shift <= dec.snd.r_shift;
- rd_user <= issue && dec.ctrl.ldst && dec.ldst.user_regs;
- end
- end
-
-endmodule
diff --git a/rtl/core/control/stall.sv b/rtl/core/control/stall.sv
deleted file mode 100644
index 02a7552..0000000
--- a/rtl/core/control/stall.sv
+++ /dev/null
@@ -1,42 +0,0 @@
-`include "core/uarch.sv"
-
-module core_control_stall
-(
- input logic clk,
- rst_n,
- halt,
-
- input insn_decode dec,
-
- input ctrl_cycle next_cycle,
- input logic rd_user,
- final_update_flags,
- final_restore_spsr,
- final_psr_write,
- final_writeback,
- input reg_num final_rd,
-
- output logic halted,
- stall,
- bubble,
- next_bubble
-);
-
- logic pc_rd_hazard, pc_wr_hazard, rn_pc_hazard, snd_pc_hazard, psr_hazard, flags_hazard;
-
- assign stall = !next_cycle.issue || next_bubble || halt;
- assign halted = halt && !next_bubble && next_cycle.issue;
- assign next_bubble = pc_rd_hazard || pc_wr_hazard || flags_hazard || psr_hazard || rd_user;
-
- //FIXME: pc_rd_hazard no debería definirse sin final_writeback?
- assign psr_hazard = final_psr_write || final_restore_spsr;
- assign pc_rd_hazard = final_writeback && (rn_pc_hazard || snd_pc_hazard);
- assign pc_wr_hazard = final_writeback && final_rd == `R15;
- assign rn_pc_hazard = dec.data.uses_rn && dec.data.rn == `R15;
- assign flags_hazard = dec.ctrl.conditional && final_update_flags;
- assign snd_pc_hazard = !dec.snd.is_imm && dec.snd.r == `R15;
-
- always_ff @(posedge clk or negedge rst_n)
- bubble <= !rst_n ? 0 : next_cycle.issue && next_bubble;
-
-endmodule
diff --git a/rtl/core/control/status.sv b/rtl/core/control/status.sv
deleted file mode 100644
index 6616bc9..0000000
--- a/rtl/core/control/status.sv
+++ /dev/null
@@ -1,81 +0,0 @@
-`include "core/uarch.sv"
-
-module core_control_psr
-(
- input logic clk,
- rst_n,
-
- input insn_decode dec,
- input word cpsr_rd,
- spsr_rd,
- alu_b,
- input psr_mode exception_mode,
-
- input ctrl_cycle cycle,
- next_cycle,
- input logic issue,
-
- output logic psr,
- psr_saved,
- psr_write,
- psr_wr_flags,
- psr_wr_control,
- final_psr_write,
- final_restore_spsr,
- output word psr_wb,
- psr_wr
-);
-
- word exception_spsr;
-
- assign psr_wb = psr_saved ? spsr_rd : cpsr_rd;
-
- always_comb begin
- psr_write = 0;
-
- if(next_cycle.issue)
- psr_write = final_psr_write || final_restore_spsr;
-
- if(cycle.escalate || cycle.exception)
- psr_write = 1;
-
- if(cycle.escalate)
- //TODO: F (FIQ) no cambia siempre
- psr_wr = {24'b0, 3'b110, exception_mode};
- else if(cycle.exception)
- psr_wr = exception_spsr;
- else
- psr_wr = final_restore_spsr ? spsr_rd : alu_b;
- end
-
- always_ff @(posedge clk or negedge rst_n)
- if(!rst_n) begin
- psr <= 0;
- psr_saved <= 0;
- psr_wr_flags <= 0;
- psr_wr_control <= 0;
-
- exception_spsr <= 0;
- final_psr_write <= 0;
- final_restore_spsr <= 0;
- end else if(next_cycle.issue) begin
- psr <= issue && dec.ctrl.psr;
- psr_saved <= dec.psr.saved;
- psr_wr_flags <= dec.psr.wr_flags;
- psr_wr_control <= dec.psr.wr_control;
-
- final_psr_write <= issue && dec.psr.write;
- final_restore_spsr <= issue && dec.psr.restore_spsr;
- end else if(next_cycle.escalate) begin
- psr_saved <= 0;
- psr_wr_flags <= 0;
- psr_wr_control <= 1;
- exception_spsr <= cpsr_rd;
- end else if(next_cycle.exception) begin
- psr <= 0;
- psr_saved <= 1;
- psr_wr_flags <= 1;
- end else if(next_cycle.psr)
- psr <= 0;
-
-endmodule
diff --git a/rtl/core/control/writeback.sv b/rtl/core/control/writeback.sv
deleted file mode 100644
index 027a7d7..0000000
--- a/rtl/core/control/writeback.sv
+++ /dev/null
@@ -1,128 +0,0 @@
-`include "core/uarch.sv"
-
-module core_control_writeback
-(
- input logic clk,
- rst_n,
-
- input insn_decode dec,
- input psr_flags alu_flags,
- 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,
- input word saved_base,
- exception_vector,
- psr_wb,
- coproc_wb,
- input reg_num ra,
- popped,
- mul_r_add_hi,
- input logic issue,
- pop_valid,
- ldst_next,
- ldst_reject,
-
- output reg_num rd,
- final_rd,
- output logic writeback,
- final_writeback,
- update_flags,
- final_update_flags,
- output word wr_value
-);
-
- reg_num last_rd;
-
- always_comb begin
- rd = last_rd;
- if(next_cycle.transfer) begin
- if(mem_ready)
- rd = final_rd;
- end else if(next_cycle.issue || next_cycle.base_writeback)
- rd = final_rd;
- else if(next_cycle.exception)
- rd = `R15;
- else if(next_cycle.mul_hi_wb)
- rd = mul_r_add_hi;
-
- if(next_cycle.issue)
- writeback = final_writeback;
- else if(next_cycle.transfer)
- writeback = mem_ready && !mem_write;
- else if(next_cycle.base_writeback)
- writeback = !mem_write;
- else if(next_cycle.exception || next_cycle.mul_hi_wb)
- writeback = 1;
- else
- writeback = 0;
-
- if(cycle.transfer)
- 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)
- wr_value = mul_q_lo;
- else if(cycle.psr)
- wr_value = psr_wb;
- else if(cycle.coproc)
- wr_value = coproc_wb;
- else
- // Ruta combinacional larga
- wr_value = q_alu;
-
- if(next_cycle.transfer) begin
- if(mem_ready)
- wr_value = ldst_read;
- end else if(next_cycle.base_writeback)
- wr_value = ldst_read;
- else if(next_cycle.exception)
- wr_value = exception_vector;
- else if(next_cycle.mul_hi_wb)
- wr_value = mul_q_hi;
-
- update_flags = 0;
- if(next_cycle.issue)
- update_flags = final_update_flags;
- else if(next_cycle.exception)
- update_flags = 0;
- end
-
- always_ff @(posedge clk or negedge rst_n)
- if(!rst_n) begin
- last_rd <= 0;
- final_rd <= 0;
- final_writeback <= 0;
- final_update_flags <= 0;
- end else begin
- last_rd <= rd;
-
- if(next_cycle.issue)
- final_rd <= dec.data.rd;
- else if(next_cycle.transfer) begin
- if(ldst_next && pop_valid)
- final_rd <= popped;
- end else if(next_cycle.base_writeback)
- final_rd <= ra;
- else if(next_cycle.exception)
- final_rd <= `R14;
-
- if(next_cycle.issue)
- final_writeback <= issue && dec.ctrl.writeback;
- else if(next_cycle.exception)
- final_writeback <= 1;
-
- if(next_cycle.issue)
- final_update_flags <= issue && dec.psr.update_flags;
- else if(next_cycle.exception)
- final_update_flags <= 0;
- end
-
-endmodule