diff options
| author | Alejandro Soto <alejandro@34project.org> | 2022-11-07 17:20:38 -0600 |
|---|---|---|
| committer | Alejandro Soto <alejandro@34project.org> | 2022-11-07 17:25:11 -0600 |
| commit | cc7ed6bd05b8143ed4250caf97798c8bbfc6b748 (patch) | |
| tree | 4fef961873f1a52020ee2cb7c49b59c3fc842c10 /rtl | |
| parent | 280cb5bb42f56d13ae2043b955a7bf286022b0b7 (diff) | |
Rework regfile in order to remove negedge trigger
Diffstat (limited to 'rtl')
| -rw-r--r-- | rtl/core/arm810.sv | 2 | ||||
| -rw-r--r-- | rtl/core/control/select.sv | 34 | ||||
| -rw-r--r-- | rtl/core/control/writeback.sv | 108 | ||||
| -rw-r--r-- | rtl/core/regs/file.sv | 40 | ||||
| -rw-r--r-- | rtl/core/regs/regs.sv | 45 | ||||
| -rw-r--r-- | rtl/core/uarch.sv | 3 |
6 files changed, 127 insertions, 105 deletions
diff --git a/rtl/core/arm810.sv b/rtl/core/arm810.sv index 3f237aa..5525f95 100644 --- a/rtl/core/arm810.sv +++ b/rtl/core/arm810.sv @@ -19,7 +19,7 @@ module arm810 core_fetch #(.PREFETCH_ORDER(2)) fetch ( - .branch(explicit_branch | wr_pc), + .branch(explicit_branch || wr_pc), .flush(0), //TODO .target(wr_pc ? wr_value[31:2] : branch_target), .addr(insn_addr), diff --git a/rtl/core/control/select.sv b/rtl/core/control/select.sv index cedf3cf..3c0ec6c 100644 --- a/rtl/core/control/select.sv +++ b/rtl/core/control/select.sv @@ -22,36 +22,44 @@ module core_control_select output psr_mode reg_mode ); - reg_num r_shift; + reg_num r_shift, last_ra, last_rb; assign reg_mode = `MODE_SVC; //TODO - always_ff @(posedge clk) + always_comb begin + ra = last_ra; + rb = last_rb; + unique case(next_cycle) ISSUE: if(issue) begin - ra <= dec_data.rn; - rb <= dec_snd.r; - r_shift <= dec_snd.r_shift; + ra = dec_data.rn; + rb = dec_snd.r; end - RD_INDIRECT_SHIFT: - rb <= r_shift; - TRANSFER: if(cycle != TRANSFER || mem_ready) // final_rd viene de dec_ldst.rd - rb <= pop_valid ? popped : final_rd; + rb = pop_valid ? popped : final_rd; MUL_ACC_LD: begin - ra <= mul_r_add_hi; - rb <= mul_r_add_lo; + ra = mul_r_add_hi; + rb = mul_r_add_lo; end endcase + end + + always_ff @(posedge clk) begin + last_ra <= ra; + last_rb <= rb; + + if(next_cycle == ISSUE && issue) + r_shift <= dec_snd.r_shift; + end initial begin - ra = {$bits(ra){1'b0}}; - rb = {$bits(rb){1'b0}}; + last_ra = {$bits(ra){1'b0}}; + last_rb = {$bits(rb){1'b0}}; r_shift = {$bits(r_shift){1'b0}}; end diff --git a/rtl/core/control/writeback.sv b/rtl/core/control/writeback.sv index 733881c..a4465ff 100644 --- a/rtl/core/control/writeback.sv +++ b/rtl/core/control/writeback.sv @@ -35,53 +35,91 @@ module core_control_writeback output psr_flags wb_alu_flags ); - always_ff @(posedge clk) begin - wb_alu_flags <= alu_flags; + reg_num last_rd; + always_comb begin + rd = last_rd; unique case(next_cycle) TRANSFER: if(mem_ready) - rd <= final_rd; + rd = final_rd; ISSUE, BASE_WRITEBACK: - rd <= final_rd; + rd = final_rd; EXCEPTION: - rd <= `R15; + rd = `R15; MUL_HI_WB: - rd <= mul_r_add_hi; + rd = mul_r_add_hi; endcase unique case(next_cycle) ISSUE: - if(issue) - final_rd <= dec_data.rd; + writeback = final_writeback; TRANSFER: - if((cycle != TRANSFER || mem_ready) && pop_valid) - final_rd <= popped; + writeback = mem_ready && !mem_write; BASE_WRITEBACK: - final_rd <= ra; + writeback = !mem_write; + + EXCEPTION, MUL_HI_WB: + writeback = 1; + + default: + writeback = 0; + endcase + + unique case(cycle) + TRANSFER: + 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: - final_rd <= `R14; + wr_value = vector; + + MUL_HI_WB: + wr_value = mul_q_hi; endcase + end + + always_ff @(posedge clk) begin + last_rd <= rd; + wb_alu_flags <= alu_flags; - writeback <= 0; unique case(next_cycle) ISSUE: - writeback <= final_writeback; + if(issue) + final_rd <= dec_data.rd; TRANSFER: - writeback <= mem_ready && !mem_write; + if((cycle != TRANSFER || mem_ready) && pop_valid) + final_rd <= popped; BASE_WRITEBACK: - writeback <= !mem_write; + final_rd <= ra; - EXCEPTION, MUL_HI_WB: - writeback <= 1; + EXCEPTION: + final_rd <= `R14; endcase unique case(next_cycle) @@ -108,48 +146,16 @@ module core_control_writeback EXCEPTION: final_update_flags <= 0; endcase - - unique case(cycle) - TRANSFER: - wr_value <= mem_data_rd; - - BASE_WRITEBACK: - wr_value <= saved_base; - - MUL, MUL_HI_WB: - wr_value <= mul_q_lo; - - default: - 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 initial begin - rd = 0; + last_rd = 0; final_rd = 0; - - writeback = 0; final_writeback = 0; update_flags = 0; final_update_flags = 0; - wr_value = 0; wb_alu_flags = {$bits(wb_alu_flags){1'b0}}; end diff --git a/rtl/core/regs/file.sv b/rtl/core/regs/file.sv index e0f9b4c..38c3301 100644 --- a/rtl/core/regs/file.sv +++ b/rtl/core/regs/file.sv @@ -3,27 +3,47 @@ module core_reg_file ( input logic clk, - input reg_index rd_index, - wr_index, + input psr_mode rd_mode, + input reg_num rd_r, + input reg_index wr_index, input logic wr_enable, + wr_enable_file, input word wr_value, + wr_current, + pc_word, output word rd_value ); // Ver comentario en uarch.sv - word file[30] /*verilator public*/; + word file[`NUM_GPREGS] /*verilator public*/; + word rd_actual; + logic rd_pc, hold_rd_pc, forward; + reg_index rd_index; + + core_reg_map map_rd + ( + .r(rd_r), + .mode(rd_mode), + .is_pc(rd_pc), + .index(rd_index) + ); + + assign rd_value = hold_rd_pc ? pc_word : forward ? wr_current : rd_actual; - //FIXME: Esto claramente no sirve -`ifdef VERILATOR - always_ff @(negedge clk) begin -`else always_ff @(posedge clk) begin -`endif - if(wr_enable) + forward <= wr_enable && rd_index == wr_index; + hold_rd_pc <= rd_pc; + + if(wr_enable_file) file[wr_index] <= wr_value; - rd_value <= file[rd_index]; + rd_actual <= file[rd_index]; + end + + initial begin + forward = 0; + hold_rd_pc = 0; end endmodule diff --git a/rtl/core/regs/regs.sv b/rtl/core/regs/regs.sv index 9b9ba57..b25a122 100644 --- a/rtl/core/regs/regs.sv +++ b/rtl/core/regs/regs.sv @@ -23,48 +23,28 @@ module core_regs * sincronizadas del archivo de registros. */ - logic rd_pc_a, rd_pc_b, wr_pc, file_wr_enable; - reg_index rd_index_a, rd_index_b, wr_index; - word pc_word, file_rd_value_a, file_rd_value_b; + word pc_word, wr_current; + logic wr_pc, wr_enable_file; + reg_index wr_index; + assign branch = wr_enable && wr_pc; assign pc_word = {pc_visible, 2'b00}; - assign rd_value_a = rd_pc_a ? pc_word : (wr_enable && rd_index_a == wr_index) ? wr_value : file_rd_value_a; - assign rd_value_b = rd_pc_b ? pc_word : (wr_enable && rd_index_b == wr_index) ? wr_value : file_rd_value_b; - assign file_wr_enable = wr_enable & ~wr_pc; - assign branch = wr_enable & wr_pc; + assign wr_enable_file = wr_enable && !wr_pc; core_reg_file a ( - .rd_index(rd_index_a), - .rd_value(file_rd_value_a), - .wr_enable(file_wr_enable), + .rd_r(rd_r_a), + .rd_value(rd_value_a), .* ); core_reg_file b ( - .rd_index(rd_index_b), - .rd_value(file_rd_value_b), - .wr_enable(file_wr_enable), + .rd_r(rd_r_b), + .rd_value(rd_value_b), .* ); - core_reg_map map_rd_a - ( - .r(rd_r_a), - .mode(rd_mode), - .is_pc(rd_pc_a), - .index(rd_index_a) - ); - - core_reg_map map_rd_b - ( - .r(rd_r_b), - .mode(rd_mode), - .is_pc(rd_pc_b), - .index(rd_index_b) - ); - core_reg_map map_wr ( .r(wr_r), @@ -73,4 +53,11 @@ module core_regs .index(wr_index) ); + always_ff @(posedge clk) + if(wr_enable) + wr_current <= wr_value; + + initial + wr_current = 0; + endmodule diff --git a/rtl/core/uarch.sv b/rtl/core/uarch.sv index 2b3c55a..d4654a7 100644 --- a/rtl/core/uarch.sv +++ b/rtl/core/uarch.sv @@ -22,7 +22,8 @@ typedef logic[29:0] ptr; * registers are 32 bits wide and are described in General-purpose registers on * page A2-6. */ -typedef logic[4:0] reg_index; +`define NUM_GPREGS 30 +typedef logic[$clog2(`NUM_GPREGS) - 1:0] reg_index; typedef logic[3:0] alu_op; |
