diff options
Diffstat (limited to 'rtl')
| -rw-r--r-- | rtl/core/arm810.sv | 15 | ||||
| -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 | ||||
| -rw-r--r-- | rtl/core/decode/data.sv | 6 | ||||
| -rw-r--r-- | rtl/core/decode/decode.sv | 40 | ||||
| -rw-r--r-- | rtl/core/decode/isa.sv | 4 | ||||
| -rw-r--r-- | rtl/core/decode/snd.sv | 18 | ||||
| -rw-r--r-- | rtl/core/shifter.sv | 2 | ||||
| -rw-r--r-- | rtl/core/uarch.sv | 28 |
11 files changed, 247 insertions, 142 deletions
diff --git a/rtl/core/arm810.sv b/rtl/core/arm810.sv index 6d4880f..266832f 100644 --- a/rtl/core/arm810.sv +++ b/rtl/core/arm810.sv @@ -29,23 +29,16 @@ module arm810 .* ); - ptr dec_branch_offset; + datapath_decode dec; + branch_decode dec_branch; snd_decode dec_snd; data_decode dec_data; ldst_decode dec_ldst; - logic dec_execute, dec_conditional, dec_undefined, dec_writeback, - dec_branch, dec_update_flags, dec_uses_rn; core_decode decode ( - .execute(dec_execute), - .conditional(dec_conditional), - .undefined(dec_undefined), - .writeback(dec_writeback), - .uses_rn(dec_uses_rn), - .branch(dec_branch), - .update_flags(dec_update_flags), - .branch_offset(dec_branch_offset), + .ctrl(dec), + .branch_ctrl(dec_branch), .snd_ctrl(dec_snd), .data_ctrl(dec_data), .ldst_ctrl(dec_ldst), 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 diff --git a/rtl/core/decode/data.sv b/rtl/core/decode/data.sv index 103fb14..1bd7ef9 100644 --- a/rtl/core/decode/data.sv +++ b/rtl/core/decode/data.sv @@ -10,16 +10,18 @@ module core_decode_data snd_shift_by_reg_if_reg, writeback, update_flags, - restore_spsr, - uses_rn + restore_spsr ); alu_op op; reg_num rn, rd; + logic uses_rn; assign decode.op = op; assign decode.rn = rn; assign decode.rd = rd; + assign decode.uses_rn = uses_rn; + assign rn = insn `FIELD_DATA_RN; assign rd = insn `FIELD_DATA_RD; assign op = insn `FIELD_DATA_OPCODE; diff --git a/rtl/core/decode/decode.sv b/rtl/core/decode/decode.sv index 9367e6d..2740b70 100644 --- a/rtl/core/decode/decode.sv +++ b/rtl/core/decode/decode.sv @@ -3,22 +3,25 @@ module core_decode ( - input word insn, - input psr_flags flags, - - output logic execute, - conditional, - undefined, - writeback, - update_flags, - uses_rn, - branch, - output ptr branch_offset, - output snd_decode snd_ctrl, - output data_decode data_ctrl, - output ldst_decode ldst_ctrl + input word insn, + input psr_flags flags, + + output datapath_decode ctrl, + output branch_decode branch_ctrl, + output snd_decode snd_ctrl, + output data_decode data_ctrl, + output ldst_decode ldst_ctrl ); + logic execute, undefined, conditional, writeback, update_flags, branch; + + assign ctrl.execute = execute; + assign ctrl.undefined = undefined; + assign ctrl.conditional = conditional; + assign ctrl.writeback = writeback; + assign ctrl.update_flags = update_flags; + assign branch_ctrl.branch = branch; + //TODO logic restore_spsr; @@ -50,13 +53,13 @@ module core_decode core_decode_branch group_branch ( .link(branch_link), - .offset(branch_offset), + .offset(branch_ctrl.offset), .* ); data_decode data; logic data_writeback, data_update_flags, data_restore_spsr, - data_is_imm, data_shift_by_reg_if_reg, data_uses_rn; + data_is_imm, data_shift_by_reg_if_reg; core_decode_data group_data ( @@ -66,7 +69,6 @@ module core_decode .restore_spsr(data_restore_spsr), .snd_is_imm(data_is_imm), .snd_shift_by_reg_if_reg(data_shift_by_reg_if_reg), - .uses_rn(data_uses_rn), .* ); @@ -117,11 +119,11 @@ module core_decode branch = 0; writeback = 0; update_flags = 0; - uses_rn = 1; execute = cond_execute; undefined = cond_undefined; data_ctrl = {($bits(data_ctrl)){1'bx}}; + data_ctrl.uses_rn = 1; snd_ctrl = {$bits(snd_ctrl){1'bx}}; snd_ctrl.shr = 0; @@ -152,7 +154,6 @@ module core_decode end `GROUP_ALU: begin - uses_rn = data_uses_rn; snd_is_imm = data_is_imm; snd_ror_if_imm = 1; snd_shift_by_reg_if_reg = data_shift_by_reg_if_reg; @@ -227,7 +228,6 @@ module core_decode execute = 0; branch = 1'bx; - uses_rn = 1'bx; writeback = 1'bx; conditional = 1'bx; update_flags = 1'bx; diff --git a/rtl/core/decode/isa.sv b/rtl/core/decode/isa.sv index baaf371..98d338e 100644 --- a/rtl/core/decode/isa.sv +++ b/rtl/core/decode/isa.sv @@ -66,7 +66,9 @@ `define INSN_BIC 28'b00_?_1110_?_????_????_???????????? `define INSN_MVN 28'b00_?_1111_?_0000_????_???????????? -`define GROUP_ALU 28'b00_?_????_?_????_????_???????????? +`define GROUP_ALU \ + `INSN_AND, `INSN_EOR, `INSN_SUB, `INSN_RSB, `INSN_ADD, `INSN_ADC, `INSN_SBC, `INSN_RSC, \ + `INSN_TST, `INSN_TEQ, `INSN_CMP, `INSN_CMN, `INSN_ORR, `INSN_MOV, `INSN_BIC, `INSN_MVN `define FIELD_DATA_IMM [25] `define FIELD_DATA_OPCODE [24:21] diff --git a/rtl/core/decode/snd.sv b/rtl/core/decode/snd.sv index 78c5424..264982e 100644 --- a/rtl/core/decode/snd.sv +++ b/rtl/core/decode/snd.sv @@ -41,23 +41,21 @@ module core_decode_snd ror = is_imm; shr = ~is_imm; put_carry = 0; - sign_extend = 1'bx; + sign_extend = 0; - if(is_imm && !ror_if_imm) - shift_imm = 6'b0; - else if(is_imm && !ror_if_imm) - shift_imm = {1'b0, insn `FIELD_SND_ROR8, 1'b0}; + if(is_imm) + shift_imm = ror_if_imm ? {1'b0, insn `FIELD_SND_ROR8, 1'b0} : 6'b0; else begin shift_imm = {1'b0, insn `FIELD_SND_SHIFTIMM}; case(shift_op) `SHIFT_LSL: shr = 0; - `SHIFT_LSR: sign_extend = 0; + `SHIFT_LSR: ; `SHIFT_ASR: sign_extend = 1; - `SHIFT_ROR: ; + `SHIFT_ROR: ror = 1; endcase - if(~shift_by_reg & (shift_imm == 0)) + if(!shift_by_reg && shift_imm == 0) case(shift_op) `SHIFT_LSL: ; @@ -66,13 +64,11 @@ module core_decode_snd `SHIFT_ROR: begin // RRX + ror = 0; shift_imm = 6'd1; put_carry = 1; - sign_extend = 0; end endcase - else if(shift_op == `SHIFT_ROR) - ror = 1; end end diff --git a/rtl/core/shifter.sv b/rtl/core/shifter.sv index 994e76c..2b5739d 100644 --- a/rtl/core/shifter.sv +++ b/rtl/core/shifter.sv @@ -20,7 +20,7 @@ module core_shifter assign sign_mask = {(W + 1){ctrl.sign_extend & base[W - 1]}}; assign {c_shl, q_shl} = {c_in, base} << shift; - assign {q_shr, c_shr} = {base, c_in} >> shift | ~(sign_mask >> shift); + assign {q_shr, c_shr} = {base, c_in} >> shift | (sign_mask & ~(sign_mask >> shift)); logic ror_cycle; logic[LOG - 1:0] ror_shift; diff --git a/rtl/core/uarch.sv b/rtl/core/uarch.sv index 5b4183c..0c46dc7 100644 --- a/rtl/core/uarch.sv +++ b/rtl/core/uarch.sv @@ -59,13 +59,29 @@ typedef logic[4:0] psr_mode; typedef struct packed { + logic execute, + undefined, + conditional, + writeback, + update_flags; +} datapath_decode; + +typedef struct packed +{ alu_op op; reg_num rn, rd; + logic uses_rn; } data_decode; typedef struct packed { + logic branch; + ptr offset; +} branch_decode; + +typedef struct packed +{ reg_num r, r_shift; logic shift_by_reg, @@ -78,7 +94,7 @@ typedef struct packed logic[5:0] shift_imm; } snd_decode; -typedef enum logic[1:0] +typedef enum { LDST_WORD, LDST_BYTE, @@ -107,6 +123,16 @@ typedef struct packed reg_list regs; } ldst_decode; +typedef enum +{ + ISSUE, + RD_INDIRECT_SHIFT, + WITH_SHIFT, + TRANSFER, + BASE_WRITEBACK, + EXCEPTION +} ctrl_cycle; + typedef struct packed { logic shr, |
