diff options
Diffstat (limited to 'rtl/core')
| -rw-r--r-- | rtl/core/control/branch.sv | 2 | ||||
| -rw-r--r-- | rtl/core/control/coproc.sv | 2 | ||||
| -rw-r--r-- | rtl/core/control/cycles.sv | 76 | ||||
| -rw-r--r-- | rtl/core/control/data.sv | 107 | ||||
| -rw-r--r-- | rtl/core/control/issue.sv | 4 | ||||
| -rw-r--r-- | rtl/core/control/ldst/ldst.sv | 19 | ||||
| -rw-r--r-- | rtl/core/control/mul.sv | 31 | ||||
| -rw-r--r-- | rtl/core/control/select.sv | 29 | ||||
| -rw-r--r-- | rtl/core/control/stall.sv | 4 | ||||
| -rw-r--r-- | rtl/core/control/writeback.sv | 157 | ||||
| -rw-r--r-- | rtl/core/mmu/mmu.sv | 2 | ||||
| -rw-r--r-- | rtl/core/uarch.sv | 23 |
12 files changed, 220 insertions, 236 deletions
diff --git a/rtl/core/control/branch.sv b/rtl/core/control/branch.sv index 96e6e65..0298b95 100644 --- a/rtl/core/control/branch.sv +++ b/rtl/core/control/branch.sv @@ -21,7 +21,7 @@ module core_control_branch branch_target <= {$bits(branch_target){1'b0}}; end else begin branch <= 0; - if(next_cycle == ISSUE && issue) begin + if(next_cycle.issue && issue) begin branch <= dec.ctrl.branch; branch_target <= next_pc_visible + dec.branch.offset; end diff --git a/rtl/core/control/coproc.sv b/rtl/core/control/coproc.sv index a457b0f..76f0a53 100644 --- a/rtl/core/control/coproc.sv +++ b/rtl/core/control/coproc.sv @@ -16,7 +16,7 @@ module core_control_coproc always_ff @(posedge clk or negedge rst_n) if(!rst_n) coproc <= 0; - else if(next_cycle == ISSUE && issue) + else if(next_cycle.issue && issue) coproc <= dec.ctrl.coproc; endmodule diff --git a/rtl/core/control/cycles.sv b/rtl/core/control/cycles.sv index 0c5d94c..5904a49 100644 --- a/rtl/core/control/cycles.sv +++ b/rtl/core/control/cycles.sv @@ -22,50 +22,92 @@ module core_control_cycles next_cycle ); + /* qts-qii51007-recommended-hdl.pdf, p. 66 + * In Quartus II integrated synthesis, the enumerated type that defines the states for the + * state machine must be of an unsigned integer type as in Example 13–52. If you do not + * specify the enumerated type as int unsigned, a signed int type is used by default. In + * this case, the Quartus II integrated synthesis synthesizes the design, but does not infer + * or optimize the logic as a state machine. + */ + enum int unsigned + { + ISSUE, + RD_INDIRECT_SHIFT, + WITH_SHIFT, + TRANSFER, + BASE_WRITEBACK, + EXCEPTION, + MUL, + MUL_ACC_LD, + MUL_HI_WB + } state, next_state; + + // TODO: debe estar escrito de tal forma que Quartus infiera una FSM + + assign cycle.issue = state == ISSUE; + assign cycle.rd_indirect_shift = state == RD_INDIRECT_SHIFT; + assign cycle.with_shift = state == WITH_SHIFT; + assign cycle.transfer = state == TRANSFER; + assign cycle.base_writeback = state == BASE_WRITEBACK; + assign cycle.exception = state == EXCEPTION; + assign cycle.mul = state == MUL; + assign cycle.mul_acc_ld = state == MUL_ACC_LD; + assign cycle.mul_hi_wb = state == MUL_HI_WB; + + assign next_cycle.issue = next_state == ISSUE; + assign next_cycle.rd_indirect_shift = next_state == RD_INDIRECT_SHIFT; + assign next_cycle.with_shift = next_state == WITH_SHIFT; + assign next_cycle.transfer = next_state == TRANSFER; + assign next_cycle.base_writeback = next_state == BASE_WRITEBACK; + assign next_cycle.exception = next_state == EXCEPTION; + assign next_cycle.mul = next_state == MUL; + assign next_cycle.mul_acc_ld = next_state == MUL_ACC_LD; + assign next_cycle.mul_hi_wb = next_state == MUL_HI_WB; + always_comb begin - next_cycle = ISSUE; + next_state = ISSUE; - unique case(cycle) + unique case(state) ISSUE: if(exception) - next_cycle = EXCEPTION; + next_state = EXCEPTION; else if(halt) - next_cycle = ISSUE; + next_state = ISSUE; else if(mul) - next_cycle = mul_add ? MUL_ACC_LD : MUL; + next_state = mul_add ? MUL_ACC_LD : MUL; else if(data_snd_shift_by_reg) - next_cycle = RD_INDIRECT_SHIFT; + next_state = RD_INDIRECT_SHIFT; else if(!trivial_shift) - next_cycle = WITH_SHIFT; + next_state = WITH_SHIFT; RD_INDIRECT_SHIFT: if(!trivial_shift) - next_cycle = WITH_SHIFT; + next_state = WITH_SHIFT; TRANSFER: if(!mem_ready || pop_valid) - next_cycle = TRANSFER; + next_state = TRANSFER; else if(ldst_writeback) - next_cycle = BASE_WRITEBACK; + next_state = BASE_WRITEBACK; MUL: if(!mul_ready) - next_cycle = MUL; + next_state = MUL; else if(mul_long) - next_cycle = MUL_HI_WB; + next_state = MUL_HI_WB; MUL_ACC_LD: - next_cycle = MUL; + next_state = MUL; endcase if(bubble) - next_cycle = ISSUE; - else if(next_cycle == ISSUE && ldst) begin - next_cycle = TRANSFER; + next_state = ISSUE; + else if(next_state == ISSUE && ldst) begin + next_state = TRANSFER; end end always_ff @(posedge clk or negedge rst_n) - cycle <= !rst_n ? ISSUE : next_cycle; + state <= !rst_n ? ISSUE : next_state; endmodule diff --git a/rtl/core/control/data.sv b/rtl/core/control/data.sv index 0824eac..049cf0e 100644 --- a/rtl/core/control/data.sv +++ b/rtl/core/control/data.sv @@ -37,30 +37,26 @@ module core_control_data assign trivial_shift = shifter_shift == 0; 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 + if(cycle.rd_indirect_shift) + shifter_shift = rd_value_b[7:0]; + else + shifter_shift = {2'b00, data_shift_imm}; + + if(cycle.transfer) + alu_a = saved_base; + else if(cycle.exception) + alu_a = {pc, 2'b00}; + else + alu_a = rd_value_a; + + if(cycle.rd_indirect_shift || cycle.with_shift) + alu_b = saved_base; + else if(cycle.transfer) + alu_b = mem_offset; + else if(data_snd_is_imm) + alu_b = {{20{1'b0}}, data_imm}; + else + alu_b = rd_value_b; end always_ff @(posedge clk or negedge rst_n) @@ -73,41 +69,32 @@ module core_control_data data_shift_imm <= {$bits(data_shift_imm){1'b0}}; data_snd_is_imm <= 0; data_snd_shift_by_reg <= 0; - end else unique case(next_cycle) - ISSUE: begin - alu <= dec.data.op; - c_in <= flags.c; - - data_imm <= dec.snd.imm; - data_shift_imm <= dec.snd.shift_imm; - data_snd_is_imm <= dec.snd.is_imm; - data_snd_shift_by_reg <= dec.snd.shift_by_reg; - - shifter.shr <= dec.snd.shr; - shifter.ror <= dec.snd.ror; - shifter.put_carry <= dec.snd.put_carry; - shifter.sign_extend <= dec.snd.sign_extend; - end - - RD_INDIRECT_SHIFT: begin - saved_base <= rd_value_b; - data_snd_shift_by_reg <= 0; - end - - WITH_SHIFT: begin - c_in <= c_shifter; - saved_base <= q_shifter; - end - - TRANSFER: - if(cycle != TRANSFER || mem_ready) - saved_base <= q_alu; - - EXCEPTION: begin - alu <= `ALU_ADD; - data_imm <= 12'd4; - data_snd_is_imm <= 1; - end - endcase + end else if(next_cycle.issue) begin + alu <= dec.data.op; + c_in <= flags.c; + + data_imm <= dec.snd.imm; + data_shift_imm <= dec.snd.shift_imm; + data_snd_is_imm <= dec.snd.is_imm; + data_snd_shift_by_reg <= dec.snd.shift_by_reg; + + shifter.shr <= dec.snd.shr; + shifter.ror <= dec.snd.ror; + shifter.put_carry <= dec.snd.put_carry; + shifter.sign_extend <= dec.snd.sign_extend; + end else if(next_cycle.rd_indirect_shift) begin + saved_base <= rd_value_b; + data_snd_shift_by_reg <= 0; + end else if(next_cycle.with_shift) begin + c_in <= c_shifter; + saved_base <= q_shifter; + end else if(next_cycle.transfer) begin + if(!cycle.transfer || mem_ready) + saved_base <= q_alu; + end else if(next_cycle.exception) begin + alu <= `ALU_ADD; + data_imm <= 12'd4; + data_snd_is_imm <= 1; + end endmodule diff --git a/rtl/core/control/issue.sv b/rtl/core/control/issue.sv index b2ee6e5..c1c932e 100644 --- a/rtl/core/control/issue.sv +++ b/rtl/core/control/issue.sv @@ -23,7 +23,7 @@ module core_control_issue next_pc_visible ); - assign issue = next_cycle == ISSUE && dec.ctrl.execute && !next_bubble && !halt; + assign issue = next_cycle.issue && dec.ctrl.execute && !next_bubble && !halt; assign next_pc_visible = insn_pc + 2; always_ff @(posedge clk or negedge rst_n) @@ -31,7 +31,7 @@ module core_control_issue pc <= 0; undefined <= 0; pc_visible <= 2; - end else if(next_cycle == ISSUE) begin + end else if(next_cycle.issue) begin undefined <= dec.ctrl.undefined; `ifdef VERILATOR diff --git a/rtl/core/control/ldst/ldst.sv b/rtl/core/control/ldst/ldst.sv index ef91775..cc52864 100644 --- a/rtl/core/control/ldst/ldst.sv +++ b/rtl/core/control/ldst/ldst.sv @@ -56,8 +56,10 @@ module core_control_ldst mem_write <= 0; mem_start <= 0; mem_offset <= 0; - end else unique case(next_cycle) - ISSUE: begin + end else begin + mem_start <= 0; + + if(next_cycle.issue) begin // TODO: dec.ldst.unprivileged/user_regs // TODO: byte/halfword sizes if(issue) @@ -69,21 +71,18 @@ module core_control_ldst mem_regs <= dec.ldst.regs; mem_write <= !dec.ldst.load; - end - - TRANSFER: begin - if(cycle != TRANSFER) begin + end else if(next_cycle.transfer) begin + if(!cycle.transfer) begin ldst <= 0; mem_offset <= alu_b; end - if(cycle != TRANSFER || mem_ready) begin + 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]; end - mem_start <= cycle != TRANSFER || (mem_ready && pop_valid); + mem_start <= !cycle.transfer || (mem_ready && pop_valid); end - endcase - + end endmodule diff --git a/rtl/core/control/mul.sv b/rtl/core/control/mul.sv index 9e66053..8352435 100644 --- a/rtl/core/control/mul.sv +++ b/rtl/core/control/mul.sv @@ -47,24 +47,19 @@ module core_control_mul end else begin mul_start <= 0; - unique case(next_cycle) - ISSUE: begin - mul <= issue && dec.ctrl.mul; - mul_add <= dec.mul.add; - mul_long <= dec.mul.long_mul; - mul_signed <= dec.mul.signed_mul; - mul_r_add_hi <= dec.mul.r_add_hi; - mul_r_add_lo <= dec.mul.r_add_lo; - end - - MUL: - mul_start <= cycle != MUL; - - MUL_ACC_LD: begin - hold_a <= rd_value_a; - hold_b <= rd_value_b; - end - endcase + if(next_cycle.issue) begin + mul <= issue && dec.ctrl.mul; + mul_add <= dec.mul.add; + mul_long <= dec.mul.long_mul; + mul_signed <= dec.mul.signed_mul; + mul_r_add_hi <= dec.mul.r_add_hi; + mul_r_add_lo <= dec.mul.r_add_lo; + end else if(next_cycle.mul) + mul_start <= !cycle.mul; + else if(next_cycle.mul_acc_ld) begin + hold_a <= rd_value_a; + hold_b <= rd_value_b; + end end //TODO: mul update_flags diff --git a/rtl/core/control/select.sv b/rtl/core/control/select.sv index 80a437f..ee63b42 100644 --- a/rtl/core/control/select.sv +++ b/rtl/core/control/select.sv @@ -29,22 +29,17 @@ module core_control_select ra = last_ra; rb = last_rb; - unique case(next_cycle) - ISSUE: begin - ra = dec.data.rn; - rb = dec.snd.r; - end - - TRANSFER: - if(cycle != TRANSFER || mem_ready) - // final_rd viene de dec.ldst.rd - rb = pop_valid ? popped : final_rd; - - MUL_ACC_LD: begin - ra = mul_r_add_hi; - rb = mul_r_add_lo; - end - endcase + if(next_cycle.issue) begin + ra = dec.data.rn; + rb = dec.snd.r; + end else if(next_cycle.transfer) begin + if(!cycle.transfer || mem_ready) + // final_rd viene de dec.ldst.rd + rb = pop_valid ? popped : final_rd; + end else if(next_cycle.mul_acc_ld) begin + ra = mul_r_add_hi; + rb = mul_r_add_lo; + end end always_ff @(posedge clk or negedge rst_n) @@ -56,7 +51,7 @@ module core_control_select last_ra <= ra; last_rb <= rb; - if(next_cycle == ISSUE) + if(next_cycle.issue) r_shift <= dec.snd.r_shift; end diff --git a/rtl/core/control/stall.sv b/rtl/core/control/stall.sv index c2a6ddd..d590325 100644 --- a/rtl/core/control/stall.sv +++ b/rtl/core/control/stall.sv @@ -24,7 +24,7 @@ module core_control_stall logic pc_rd_hazard, pc_wr_hazard, rn_pc_hazard, snd_pc_hazard, flags_hazard, flags_dependency, updating_flags; - assign stall = next_cycle != ISSUE || next_bubble || halt; + assign stall = !next_cycle.issue || next_bubble || halt; assign halted = halt && !next_bubble; assign next_bubble = pc_rd_hazard || pc_wr_hazard || flags_hazard; @@ -40,6 +40,6 @@ module core_control_stall assign flags_dependency = dec.psr.update_flags || dec.ctrl.conditional; always_ff @(posedge clk or negedge rst_n) - bubble <= !rst_n ? 0 : next_cycle == ISSUE && next_bubble; + bubble <= !rst_n ? 0 : next_cycle.issue && next_bubble; endmodule diff --git a/rtl/core/control/writeback.sv b/rtl/core/control/writeback.sv index 74eb47c..a85956f 100644 --- a/rtl/core/control/writeback.sv +++ b/rtl/core/control/writeback.sv @@ -38,67 +38,46 @@ module core_control_writeback always_comb begin rd = last_rd; - unique case(next_cycle) - TRANSFER: - if(mem_ready) - rd = final_rd; - - ISSUE, BASE_WRITEBACK: + if(next_cycle.transfer) begin + if(mem_ready) rd = final_rd; - - EXCEPTION: - rd = `R15; - - MUL_HI_WB: - rd = mul_r_add_hi; - endcase - - unique case(next_cycle) - ISSUE: - writeback = final_writeback; - - TRANSFER: - writeback = mem_ready && !mem_write; - - BASE_WRITEBACK: - writeback = !mem_write; - - EXCEPTION, MUL_HI_WB: - writeback = 1; - - default: - writeback = 0; - endcase - - unique case(cycle) - TRANSFER: + end else if(next_cycle.issue || next_cycle.base_writeback) + rd = final_rd; + else if(next_cycle.exception) + rd = `R15; + else if(next_cycle.mul_hi_wb) + rd = mul_r_add_hi; + + if(next_cycle.issue) + writeback = final_writeback; + else if(next_cycle.transfer) + writeback = mem_ready && !mem_write; + else if(next_cycle.base_writeback) + writeback = !mem_write; + else if(next_cycle.exception || next_cycle.mul_hi_wb) + writeback = 1; + else + writeback = 0; + + if(cycle.transfer) + wr_value = mem_data_rd; + else if(cycle.base_writeback) + wr_value = saved_base; + else if(cycle.mul || cycle.mul_hi_wb) + wr_value = mul_q_lo; + else + // Ruta combinacional larga + wr_value = q_alu; + + if(next_cycle.transfer) begin + if(mem_ready) wr_value = mem_data_rd; - - BASE_WRITEBACK: - wr_value = saved_base; - - MUL, MUL_HI_WB: - wr_value = mul_q_lo; - - default: - // Ruta combinacional larga - wr_value = q_alu; - endcase - - unique case(next_cycle) - TRANSFER: - if(mem_ready) - wr_value = mem_data_rd; - - BASE_WRITEBACK: - wr_value = mem_data_rd; - - EXCEPTION: - wr_value = vector; - - MUL_HI_WB: - wr_value = mul_q_hi; - endcase + end else if(next_cycle.base_writeback) + wr_value = mem_data_rd; + else if(next_cycle.exception) + wr_value = vector; + else if(next_cycle.mul_hi_wb) + wr_value = mul_q_hi; end always_ff @(posedge clk or negedge rst_n) @@ -115,45 +94,31 @@ module core_control_writeback last_rd <= rd; wb_alu_flags <= alu_flags; - unique case(next_cycle) - 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 - - unique case(next_cycle) - ISSUE: - final_writeback <= issue && dec.ctrl.writeback; - - EXCEPTION: - final_writeback <= 1; - endcase + if(next_cycle.issue) + final_rd <= dec.data.rd; + else if(next_cycle.transfer) begin + if((!cycle.transfer || mem_ready) && pop_valid) + final_rd <= popped; + end else if(next_cycle.base_writeback) + final_rd <= ra; + else if(next_cycle.exception) + final_rd <= `R14; + + if(next_cycle.issue) + final_writeback <= issue && dec.ctrl.writeback; + else + final_writeback <= 1; update_flags <= 0; - unique case(next_cycle) - ISSUE: - update_flags <= final_update_flags; - - EXCEPTION: - update_flags <= 0; - endcase - - unique case(next_cycle) - ISSUE: - final_update_flags <= issue && dec.psr.update_flags; - - EXCEPTION: - final_update_flags <= 0; - endcase + if(next_cycle.issue) + update_flags <= final_update_flags; + else if(next_cycle.exception) + update_flags <= 0; + + if(next_cycle.issue) + final_update_flags <= issue && dec.psr.update_flags; + else if(next_cycle.exception) + final_update_flags <= 0; end endmodule diff --git a/rtl/core/mmu/mmu.sv b/rtl/core/mmu/mmu.sv index 51d7f32..5928d00 100644 --- a/rtl/core/mmu/mmu.sv +++ b/rtl/core/mmu/mmu.sv @@ -22,7 +22,7 @@ module core_mmu data_data_rd ); - enum + enum int unsigned { INSN, DATA diff --git a/rtl/core/uarch.sv b/rtl/core/uarch.sv index 5b88559..d553104 100644 --- a/rtl/core/uarch.sv +++ b/rtl/core/uarch.sv @@ -124,7 +124,7 @@ typedef struct packed logic[5:0] shift_imm; } snd_decode; -typedef enum +typedef enum int unsigned { LDST_WORD, LDST_BYTE, @@ -181,17 +181,18 @@ typedef struct packed coproc_decode coproc; } insn_decode; -typedef enum +// Ver comentario en cycles.sv, este diseño es más óptimo +typedef struct packed { - ISSUE, - RD_INDIRECT_SHIFT, - WITH_SHIFT, - TRANSFER, - BASE_WRITEBACK, - EXCEPTION, - MUL, - MUL_ACC_LD, - MUL_HI_WB + logic issue, + rd_indirect_shift, + with_shift, + transfer, + base_writeback, + exception, + mul, + mul_acc_ld, + mul_hi_wb; } ctrl_cycle; typedef struct packed |
