diff options
Diffstat (limited to 'rtl/core/control')
| -rw-r--r-- | rtl/core/control/control.sv | 126 | ||||
| -rw-r--r-- | rtl/core/control/cycles.sv | 56 | ||||
| -rw-r--r-- | rtl/core/control/mux.sv | 50 | ||||
| -rw-r--r-- | rtl/core/control/stall.sv | 44 |
4 files changed, 181 insertions, 95 deletions
diff --git a/rtl/core/control/control.sv b/rtl/core/control/control.sv index 95d3bb9..059cb2d 100644 --- a/rtl/core/control/control.sv +++ b/rtl/core/control/control.sv @@ -3,16 +3,10 @@ module core_control ( input logic clk, - dec_execute, - dec_undefined, - dec_conditional, - dec_uses_rn, - dec_branch, - dec_writeback, - dec_update_flags, - input ptr dec_branch_offset, - input snd_decode dec_snd, + input datapath_decode dec, + input branch_decode dec_branch, input data_decode dec_data, + input snd_decode dec_snd, input ldst_decode dec_ldst, input ptr fetch_insn_pc, input psr_flags flags, @@ -49,17 +43,7 @@ module core_control mem_write ); - enum - { - ISSUE, - RD_INDIRECT_SHIFT, - WITH_SHIFT, - TRANSFER, - BASE_WRITEBACK, - EXCEPTION - } cycle, next_cycle; - - logic bubble, next_bubble, final_writeback, final_update_flags, + logic final_writeback, 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; @@ -72,7 +56,6 @@ module core_control reg_list mem_regs, next_regs_upper, next_regs_lower; ptr pc /*verilator public*/, next_pc_visible; - assign stall = next_cycle != ISSUE || next_bubble; assign reg_mode = `MODE_SVC; //TODO assign trivial_shift = shifter_shift == 0; assign mem_data_wr = rd_value_b; @@ -82,10 +65,19 @@ module core_control assign vector = {{16{high_vectors}}, 11'b0, vector_offset, 2'b00}; assign next_pc_visible = fetch_insn_pc + 2; - assign next_bubble = - ((dec_update_flags || dec_conditional) && (final_update_flags || update_flags)) - || (final_writeback && ((dec_uses_rn && (final_rd == dec_data.rn || dec_data.rn == `R15)) - || final_rd == dec_snd.r || dec_snd.r == `R15)); + ctrl_cycle cycle, next_cycle; + + core_control_cycles cycles + ( + .* + ); + + logic bubble, next_bubble; + + core_control_stall ctrl_stall + ( + .* + ); core_control_ldst_pop ldst_pop ( @@ -97,67 +89,15 @@ module core_control .pop_lower(popped_lower) ); - 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 - - next_cycle = ISSUE; - - unique case(cycle) - ISSUE: - if(exception) - next_cycle = EXCEPTION; - else 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; - - TRANSFER: - if(!mem_ready || pop_valid) - next_cycle = TRANSFER; - else if(ldst_writeback) - next_cycle = BASE_WRITEBACK; - - default: ; - endcase - - if(bubble) - next_cycle = ISSUE; - else if(next_cycle == ISSUE && ldst) - next_cycle = TRANSFER; - - unique case(cycle) - TRANSFER: alu_a = saved_base; - EXCEPTION: alu_a = {pc, 2'b00}; - default: alu_a = rd_value_a; - endcase - - unique case(cycle) - RD_INDIRECT_SHIFT, WITH_SHIFT: - alu_b = saved_base; - - TRANSFER: - alu_b = mem_offset; - - default: - if(data_snd_is_imm) - alu_b = {{20{1'b0}}, data_imm}; - else - alu_b = rd_value_b; - endcase + core_control_mux mux + ( + .* + ); + always_comb vector_offset = 3'b001; //TODO - end always_ff @(posedge clk) begin - cycle <= next_cycle; - bubble <= 0; branch <= 0; writeback <= 0; update_flags <= 0; @@ -174,11 +114,9 @@ module core_control final_writeback <= 0; final_update_flags <= 0; - bubble <= next_bubble; - - if(dec_execute & ~next_bubble) begin - branch <= dec_branch; - branch_target <= next_pc_visible + dec_branch_offset; + if(dec.execute & ~next_bubble) begin + branch <= dec_branch.branch; + branch_target <= next_pc_visible + dec_branch.offset; alu <= dec_data.op; ra <= dec_data.rn; @@ -208,13 +146,13 @@ module core_control mem_write <= !dec_ldst.load; final_rd <= dec_data.rd; - final_writeback <= dec_writeback; - final_update_flags <= dec_update_flags; + final_writeback <= dec.writeback; + final_update_flags <= dec.update_flags; end update_flags <= final_update_flags; writeback <= final_writeback; - undefined <= dec_undefined; + undefined <= dec.undefined; rd <= final_rd; pc <= fetch_insn_pc; @@ -238,9 +176,10 @@ 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; - writeback <= !mem_write; end if(cycle != TRANSFER || mem_ready) begin @@ -249,8 +188,8 @@ module core_control saved_base <= q_alu; if(pop_valid) begin - rd <= popped; rb <= popped; + final_rd <= popped; end else rb <= final_rd; // Viene de dec_ldst.rd end @@ -286,9 +225,6 @@ module core_control end initial begin - cycle = ISSUE; - bubble = 0; - pc = 0; pc_visible = 2; diff --git a/rtl/core/control/cycles.sv b/rtl/core/control/cycles.sv new file mode 100644 index 0000000..f804e93 --- /dev/null +++ b/rtl/core/control/cycles.sv @@ -0,0 +1,56 @@ +`include "core/uarch.sv" + +module core_control_cycles +( + input logic clk, + ldst, + bubble, + exception, + mem_ready, + pop_valid, + trivial_shift, + ldst_writeback, + data_snd_shift_by_reg, + + output ctrl_cycle cycle, + next_cycle +); + + always_comb begin + next_cycle = ISSUE; + + unique case(cycle) + ISSUE: + if(exception) + next_cycle = EXCEPTION; + else 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; + + TRANSFER: + if(!mem_ready || pop_valid) + next_cycle = TRANSFER; + else if(ldst_writeback) + next_cycle = BASE_WRITEBACK; + + default: ; + endcase + + if(bubble) + next_cycle = ISSUE; + else if(next_cycle == ISSUE && ldst) + next_cycle = TRANSFER; + end + + always_ff @(posedge clk) + cycle <= next_cycle; + + initial + cycle = ISSUE; + +endmodule diff --git a/rtl/core/control/mux.sv b/rtl/core/control/mux.sv new file mode 100644 index 0000000..58d2197 --- /dev/null +++ b/rtl/core/control/mux.sv @@ -0,0 +1,50 @@ +`include "core/uarch.sv" + +module core_control_mux +( + input logic clk, + + input word rd_value_a, + rd_value_b, + + input ctrl_cycle cycle, + input logic data_snd_is_imm, + input logic[5:0] data_shift_imm, + input logic[11:0] data_imm, + input ptr pc, + input word saved_base, + mem_offset, + + output word alu_a, + alu_b, + output logic[7:0] shifter_shift +); + + 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 + + unique case(cycle) + TRANSFER: alu_a = saved_base; + EXCEPTION: alu_a = {pc, 2'b00}; + default: alu_a = rd_value_a; + endcase + + unique case(cycle) + RD_INDIRECT_SHIFT, WITH_SHIFT: + alu_b = saved_base; + + TRANSFER: + alu_b = mem_offset; + + default: + if(data_snd_is_imm) + alu_b = {{20{1'b0}}, data_imm}; + else + alu_b = rd_value_b; + endcase + end + +endmodule diff --git a/rtl/core/control/stall.sv b/rtl/core/control/stall.sv new file mode 100644 index 0000000..4dc56e4 --- /dev/null +++ b/rtl/core/control/stall.sv @@ -0,0 +1,44 @@ +`include "core/uarch.sv" + +module core_control_stall +( + input logic clk, + + input datapath_decode dec, + input data_decode dec_data, + input snd_decode dec_snd, + + input ctrl_cycle next_cycle, + input logic final_update_flags, + update_flags, + final_writeback, + writeback, + input reg_num final_rd, + + output logic stall, + bubble, + next_bubble +); + + logic pc_writeback_hazard, flags_hazard, data_hazard, rn_hazard, + snd_hazard, flags_dependency, updating_flags; + + assign stall = next_cycle != ISSUE || next_bubble; + assign next_bubble = pc_writeback_hazard || flags_hazard || data_hazard; + + assign pc_writeback_hazard = final_writeback && final_rd == `R15; + assign flags_hazard = flags_dependency && updating_flags; + assign data_hazard = final_writeback && (rn_hazard || snd_hazard); + assign rn_hazard = dec_data.uses_rn && (final_rd == dec_data.rn || dec_data.rn == `R15); + assign snd_hazard = !dec_snd.is_imm && (dec_snd.r == final_rd || dec_snd.r == `R15); + + assign flags_dependency = dec.update_flags || dec.conditional; + assign updating_flags = final_update_flags || update_flags; + + always_ff @(posedge clk) + bubble <= next_cycle == ISSUE ? next_bubble : 0; + + initial + bubble = 0; + +endmodule |
