summaryrefslogtreecommitdiff
path: root/rtl/core/cycles.sv
diff options
context:
space:
mode:
Diffstat (limited to 'rtl/core/cycles.sv')
-rw-r--r--rtl/core/cycles.sv158
1 files changed, 97 insertions, 61 deletions
diff --git a/rtl/core/cycles.sv b/rtl/core/cycles.sv
index 8945bc2..c32bff0 100644
--- a/rtl/core/cycles.sv
+++ b/rtl/core/cycles.sv
@@ -2,77 +2,102 @@
module core_cycles
(
- input logic clk,
- dec_execute,
- dec_branch,
- dec_writeback,
- dec_update_flags,
- input ptr dec_branch_offset,
- input alu_decode dec_alu,
- input ptr fetch_insn_pc,
- input word rd_value_b,
-
- output logic stall,
- branch,
- writeback,
- update_flags,
- output reg_num rd,
- ra,
- rb,
- output ptr branch_target,
- pc,
- pc_visible,
- output psr_mode reg_mode,
- output alu_control alu,
- output word alu_base,
- output logic[7:0] alu_shift
+ input logic clk,
+ dec_execute,
+ dec_branch,
+ dec_writeback,
+ dec_update_flags,
+ input ptr dec_branch_offset,
+ input data_decode dec_data,
+ input ptr fetch_insn_pc,
+ input psr_flags next_flags,
+ input word rd_value_b,
+ q_alu,
+ q_shifter,
+ input logic c_shifter,
+
+ output logic stall,
+ branch,
+ writeback,
+ update_flags,
+ c_in,
+ output reg_num rd,
+ ra,
+ rb,
+ output ptr branch_target,
+ pc_visible,
+ output psr_mode reg_mode,
+ output alu_op alu,
+ output word alu_b,
+ wr_value,
+ output shifter_control shifter,
+ output logic[7:0] shifter_shift
);
enum
{
EXECUTE,
- RD_SHIFT
+ RD_INDIRECT_SHIFT,
+ WITH_SHIFT
} cycle, next_cycle;
- logic final_writeback, data_snd_is_imm, data_snd_shift_by_reg;
+ logic bubble, final_writeback, data_snd_is_imm, data_snd_shift_by_reg, trivial_shift;
logic[5:0] data_shift_imm;
logic[7:0] data_imm;
- logic bubble;
word saved_base;
- reg_num r_shift;
+ reg_num r_shift, final_rd;
+ ptr pc;
assign stall = (next_cycle != EXECUTE) | bubble;
assign pc_visible = pc + 2;
assign reg_mode = `MODE_SVC; //TODO
always_comb begin
+ unique case(cycle)
+ RD_INDIRECT_SHIFT: shifter_shift = rd_value_b[7:0];
+ default: shifter_shift = {2'b00, data_shift_imm};
+ endcase
+
+ trivial_shift = 1;
+ if(final_writeback & (shifter.shl | shifter.shr | shifter.ror))
+ trivial_shift = shifter_shift == 0;
+
next_cycle = EXECUTE;
- if((cycle == EXECUTE) & data_snd_shift_by_reg)
- next_cycle = RD_SHIFT;
+
+ unique case(cycle)
+ EXECUTE:
+ if(data_snd_shift_by_reg)
+ next_cycle = RD_INDIRECT_SHIFT;
+ else if(~trivial_shift)
+ next_cycle = WITH_SHIFT;
+
+ RD_INDIRECT_SHIFT:
+ if(~trivial_shift)
+ next_cycle = WITH_SHIFT;
+
+ default: ;
+ endcase
if(bubble)
next_cycle = EXECUTE;
unique case(cycle)
- RD_SHIFT:
- alu_base = saved_base;
-
- default:
+ EXECUTE:
if(data_snd_is_imm)
- alu_base = {{24{1'b0}}, data_imm};
+ alu_b = {{24{1'b0}}, data_imm};
else
- alu_base = rd_value_b;
- endcase
+ alu_b = rd_value_b;
- unique case(cycle)
- RD_SHIFT: alu_shift = rd_value_b[7:0];
- default: alu_shift = {2'b00, data_shift_imm};
+ RD_INDIRECT_SHIFT, WITH_SHIFT:
+ alu_b = saved_base;
endcase
end
always_ff @(posedge clk) begin
cycle <= next_cycle;
bubble <= 0;
+ writeback <= 0;
+ wr_value <= q_alu;
unique case(next_cycle)
EXECUTE: begin
@@ -84,40 +109,47 @@ module core_cycles
if(dec_execute & ~bubble) begin
bubble <=
(dec_update_flags & update_flags)
- | (final_writeback & ((rd == dec_alu.rn) | (rd == dec_alu.r_snd)));
+ | (final_writeback & ((rd == dec_data.rn) | (rd == dec_data.r_snd)));
branch <= dec_branch;
- final_writeback <= dec_writeback;
update_flags <= dec_update_flags;
branch_target <= pc_visible + dec_branch_offset;
- data_snd_is_imm <= dec_alu.snd_is_imm;
- data_snd_shift_by_reg <= dec_alu.snd_shift_by_reg;
- data_imm <= dec_alu.imm;
- data_shift_imm <= dec_alu.shift_imm;
-
- alu.op <= dec_alu.op;
- alu.shl <= dec_alu.shl;
- alu.shr <= dec_alu.shr;
- alu.ror <= dec_alu.ror;
- alu.put_carry <= dec_alu.put_carry;
- alu.sign_extend <= dec_alu.sign_extend;
-
- rd <= dec_alu.rd;
- ra <= dec_alu.rn;
- rb <= dec_alu.r_snd;
- r_shift <= dec_alu.r_shift;
+ data_snd_is_imm <= dec_data.snd_is_imm;
+ data_snd_shift_by_reg <= dec_data.snd_shift_by_reg;
+ data_imm <= dec_data.imm;
+ data_shift_imm <= dec_data.shift_imm;
+
+ alu <= dec_data.op;
+ shifter.shl <= dec_data.shl;
+ shifter.shr <= dec_data.shr;
+ shifter.ror <= dec_data.ror;
+ shifter.put_carry <= dec_data.put_carry;
+ shifter.sign_extend <= dec_data.sign_extend;
+
+ ra <= dec_data.rn;
+ rb <= dec_data.r_snd;
+ r_shift <= dec_data.r_shift;
+ c_in <= next_flags.c;
+
+ final_rd <= dec_data.rd;
+ final_writeback <= dec_writeback;
end
writeback <= final_writeback;
+ rd <= final_rd;
pc <= fetch_insn_pc;
end
- RD_SHIFT: begin
+ RD_INDIRECT_SHIFT: begin
rb <= r_shift;
data_snd_shift_by_reg <= 0;
saved_base <= rd_value_b;
- writeback <= 0;
+ end
+
+ WITH_SHIFT: begin
+ c_in <= c_shifter;
+ saved_base <= q_shifter;
end
endcase
end
@@ -127,10 +159,14 @@ module core_cycles
bubble = 0;
pc = 0;
+ c_in = 0;
branch = 1;
writeback = 0;
- data_snd_shift_by_reg = 0;
branch_target = 30'd0;
+ data_snd_shift_by_reg = 0;
+
+ final_rd = 0;
+ final_writeback = 0;
end
endmodule