diff options
Diffstat (limited to 'rtl/core')
| -rw-r--r-- | rtl/core/arm810.sv | 3 | ||||
| -rw-r--r-- | rtl/core/cycles.sv | 16 | ||||
| -rw-r--r-- | rtl/core/decode/conds.sv | 10 | ||||
| -rw-r--r-- | rtl/core/decode/decode.sv | 1 | ||||
| -rw-r--r-- | rtl/core/mmu/mmu.sv | 2 |
5 files changed, 23 insertions, 9 deletions
diff --git a/rtl/core/arm810.sv b/rtl/core/arm810.sv index 975ce03..c43a832 100644 --- a/rtl/core/arm810.sv +++ b/rtl/core/arm810.sv @@ -29,7 +29,7 @@ module arm810 .* ); - logic dec_execute, dec_undefined, dec_writeback, dec_branch, dec_update_flags; + logic dec_execute, dec_conditional, dec_undefined, dec_writeback, dec_branch, dec_update_flags; ptr dec_branch_offset; snd_decode dec_snd; data_decode dec_data; @@ -38,6 +38,7 @@ module arm810 core_decode decode ( .execute(dec_execute), + .conditional(dec_conditional), .undefined(dec_undefined), .writeback(dec_writeback), .branch(dec_branch), diff --git a/rtl/core/cycles.sv b/rtl/core/cycles.sv index 2302c64..ad35762 100644 --- a/rtl/core/cycles.sv +++ b/rtl/core/cycles.sv @@ -4,6 +4,7 @@ module core_cycles ( input logic clk, dec_execute, + dec_conditional, dec_branch, dec_writeback, dec_update_flags, @@ -53,7 +54,7 @@ module core_cycles BASE_WRITEBACK } cycle, next_cycle; - logic bubble, final_writeback, final_update_flags, + logic bubble, next_bubble, 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; @@ -64,13 +65,17 @@ module core_cycles reg_list mem_regs, next_regs_upper, next_regs_lower; ptr pc, next_pc_visible; - assign stall = (next_cycle != ISSUE) | bubble; + 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; assign popped = ldst_increment ? popped_lower : popped_upper; assign next_pc_visible = fetch_insn_pc + 2; + assign next_bubble = + ((dec_update_flags || dec_conditional) && (final_update_flags || update_flags)) + || (final_writeback && (final_rd == dec_data.rn || final_rd == dec_snd.r)); + core_cycles_ldst_pop ldst_pop ( .regs(mem_regs), @@ -139,6 +144,7 @@ module core_cycles bubble <= 0; branch <= 0; writeback <= 0; + update_flags <= 0; unique case(cycle) TRANSFER: wr_value <= mem_data_rd; @@ -151,11 +157,9 @@ module core_cycles final_writeback <= 0; final_update_flags <= 0; - if(dec_execute & ~bubble) begin - bubble <= - (dec_update_flags & update_flags) - | (final_writeback & ((rd == dec_data.rn) | (rd == dec_snd.r))); + bubble <= next_bubble; + if(dec_execute & ~next_bubble) begin branch <= dec_branch; branch_target <= next_pc_visible + dec_branch_offset; diff --git a/rtl/core/decode/conds.sv b/rtl/core/decode/conds.sv index 652760d..564ed27 100644 --- a/rtl/core/decode/conds.sv +++ b/rtl/core/decode/conds.sv @@ -5,12 +5,15 @@ module core_decode_conds ( input logic[3:0] cond, input psr_flags flags, + output logic execute, + conditional, undefined ); always_comb begin undefined = 0; + conditional = 1; unique case(cond) `COND_EQ: execute = flags.z; @@ -27,10 +30,15 @@ module core_decode_conds `COND_LT: execute = flags.n ^ flags.v; `COND_GT: execute = ~flags.z & (flags.n ~^ flags.v); `COND_LE: execute = flags.z | (flags.n ^ flags.v); - `COND_AL: execute = 1; + + `COND_AL: begin + execute = 1; + conditional = 0; + end `COND_UD: begin execute = 1'bx; + conditional = 1'bx; undefined = 1; end endcase diff --git a/rtl/core/decode/decode.sv b/rtl/core/decode/decode.sv index 16b53d4..73d3b59 100644 --- a/rtl/core/decode/decode.sv +++ b/rtl/core/decode/decode.sv @@ -7,6 +7,7 @@ module core_decode input psr_flags flags, output logic execute, + conditional, undefined, writeback, update_flags, diff --git a/rtl/core/mmu/mmu.sv b/rtl/core/mmu/mmu.sv index 8d3b909..bf37cb0 100644 --- a/rtl/core/mmu/mmu.sv +++ b/rtl/core/mmu/mmu.sv @@ -80,7 +80,7 @@ module core_mmu end end - always @(posedge clk) begin + always_ff @(posedge clk) begin master <= next_master; active <= bus_start || (active && !bus_ready); |
