summaryrefslogtreecommitdiff
path: root/rtl
diff options
context:
space:
mode:
Diffstat (limited to 'rtl')
-rw-r--r--rtl/core/control/control.sv53
-rw-r--r--rtl/core/control/writeback.sv109
2 files changed, 122 insertions, 40 deletions
diff --git a/rtl/core/control/control.sv b/rtl/core/control/control.sv
index ee0fb72..faba1c1 100644
--- a/rtl/core/control/control.sv
+++ b/rtl/core/control/control.sv
@@ -54,7 +54,7 @@ module core_control
coproc
);
- logic final_writeback, final_update_flags, ldst, ldst_pre, ldst_increment,
+ logic final_update_flags, ldst, ldst_pre, ldst_increment,
ldst_writeback, pop_valid, data_snd_is_imm, data_snd_shift_by_reg,
trivial_shift, undefined, exception, high_vectors;
@@ -62,7 +62,7 @@ module core_control
logic[5:0] data_shift_imm;
logic[11:0] data_imm;
word saved_base, mem_offset, vector;
- reg_num r_shift, final_rd, popped_upper, popped_lower, popped;
+ reg_num r_shift, popped_upper, popped_lower, popped;
reg_list mem_regs, next_regs_upper, next_regs_lower;
assign reg_mode = `MODE_SVC; //TODO
@@ -111,24 +111,24 @@ module core_control
.*
);
+ logic final_writeback;
+ reg_num final_rd;
+
+ core_control_writeback ctrl_wb
+ (
+ .*
+ );
+
always_comb
vector_offset = 3'b001; //TODO
always_ff @(posedge clk) begin
branch <= 0;
- writeback <= 0;
update_flags <= 0;
wb_alu_flags <= alu_flags;
- unique case(cycle)
- TRANSFER: wr_value <= mem_data_rd;
- BASE_WRITEBACK: wr_value <= saved_base;
- default: wr_value <= q_alu;
- endcase
-
unique case(next_cycle)
ISSUE: begin
- final_writeback <= 0;
final_update_flags <= 0;
if(issue) begin
@@ -169,15 +169,10 @@ module core_control
mem_regs <= dec_ldst.regs;
mem_write <= !dec_ldst.load;
- final_rd <= dec_data.rd;
- final_writeback <= dec.writeback;
final_update_flags <= dec.update_flags;
end
update_flags <= final_update_flags;
- writeback <= final_writeback;
-
- rd <= final_rd;
end
RD_INDIRECT_SHIFT: begin
@@ -197,49 +192,31 @@ module core_control
mem_offset <= alu_b;
end
- writeback <= mem_ready && !mem_write;
- if(mem_ready) begin
- rd <= final_rd;
- wr_value <= mem_data_rd;
- end
-
if(cycle != TRANSFER || mem_ready) begin
mem_regs <= ldst_increment ? next_regs_lower : next_regs_upper;
mem_addr <= ldst_pre ? q_alu[31:2] : alu_a[31:2];
saved_base <= q_alu;
- if(pop_valid) begin
+ if(pop_valid)
rb <= popped;
- final_rd <= popped;
- end else
+ else
rb <= final_rd; // Viene de dec_ldst.rd
end
mem_start <= cycle != TRANSFER || (mem_ready && pop_valid);
end
- BASE_WRITEBACK: begin
- rd <= final_rd;
- wr_value <= mem_data_rd;
- writeback <= !mem_write;
- final_rd <= ra;
- end
+ BASE_WRITEBACK: ;
EXCEPTION: begin
//TODO: spsr_<mode> = cpsr
//TODO: actualizar modo
//TODO: deshabilitar IRQs/FIQs dependiendo de modo
//TODO: Considerar que data abort usa + 8, no + 4
- rd <= `R15;
- wr_value <= vector;
- writeback <= 1;
-
alu <= `ALU_ADD;
data_imm <= 12'd4;
data_snd_is_imm <= 1;
- final_rd <= `R14;
- final_writeback <= 1;
final_update_flags <= 0;
end
endcase
@@ -248,7 +225,6 @@ module core_control
initial begin
c_in = 0;
branch = 1;
- writeback = 0;
branch_target = 30'd0;
data_snd_shift_by_reg = 0;
@@ -264,9 +240,6 @@ module core_control
mem_start = 0;
mem_regs = 16'b0;
mem_offset = 0;
-
- final_rd = 0;
- final_writeback = 0;
end
endmodule
diff --git a/rtl/core/control/writeback.sv b/rtl/core/control/writeback.sv
new file mode 100644
index 0000000..2ba0845
--- /dev/null
+++ b/rtl/core/control/writeback.sv
@@ -0,0 +1,109 @@
+`include "core/uarch.sv"
+
+module core_control_writeback
+(
+ input logic clk,
+
+ input datapath_decode dec,
+ input data_decode dec_data,
+
+ input ctrl_cycle cycle,
+ next_cycle,
+ input word saved_base,
+ mem_data_rd,
+ vector,
+ q_alu,
+ input reg_num ra,
+ popped,
+ input logic pop_valid,
+ issue,
+ mem_ready,
+ mem_write,
+
+ output reg_num rd,
+ final_rd,
+ output logic writeback,
+ final_writeback,
+ output word wr_value
+);
+
+ always @(posedge clk) begin
+ unique0 case(next_cycle)
+ TRANSFER:
+ if(mem_ready)
+ rd <= final_rd;
+
+ ISSUE, BASE_WRITEBACK:
+ rd <= final_rd;
+
+ EXCEPTION:
+ rd <= `R15;
+ endcase
+
+ unique0 case(next_cycle)
+ ISSUE:
+ if(issue)
+ final_rd <= dec_data.rd;
+
+ TRANSFER:
+ if((cycle != TRANSFER || mem_ready) && pop_valid)
+ final_rd <= popped;
+
+ BASE_WRITEBACK:
+ final_rd <= ra;
+
+ EXCEPTION:
+ final_rd <= `R14;
+ endcase
+
+ writeback <= 0;
+ unique0 case(next_cycle)
+ ISSUE:
+ writeback <= final_writeback;
+
+ TRANSFER:
+ writeback <= mem_ready && !mem_write;
+
+ BASE_WRITEBACK:
+ writeback <= !mem_write;
+
+ EXCEPTION:
+ writeback <= 1;
+ endcase
+
+ unique0 case(next_cycle)
+ ISSUE:
+ final_writeback <= issue && dec.writeback;
+
+ EXCEPTION:
+ final_writeback <= 1;
+ endcase
+
+ unique case(cycle)
+ TRANSFER: wr_value <= mem_data_rd;
+ BASE_WRITEBACK: wr_value <= saved_base;
+ default: wr_value <= q_alu;
+ endcase
+
+ unique0 case(next_cycle)
+ TRANSFER:
+ if(mem_ready)
+ wr_value <= mem_data_rd;
+
+ BASE_WRITEBACK:
+ wr_value <= mem_data_rd;
+
+ EXCEPTION:
+ wr_value <= vector;
+ endcase
+ end
+
+ initial begin
+ rd = 0;
+ final_rd = 0;
+ wr_value = 0;
+ writeback = 0;
+ final_writeback = 0;
+ end
+
+endmodule