rtl: add static branch predict unit

Signed-off-by: liangkangnan <liangkangnan@163.com>
pull/4/head
liangkangnan 2021-06-11 09:44:26 +08:00
parent e26dda807e
commit 7196d33074
5 changed files with 97 additions and 4 deletions

View File

@ -21,6 +21,7 @@
../rtl/core/rst_gen.sv
../rtl/core/tinyriscv_core.sv
../rtl/core/tracer.sv
../rtl/core/bpu.sv
../rtl/debug/jtag_def.sv
../rtl/debug/jtag_tap.sv

62
rtl/core/bpu.sv Normal file
View File

@ -0,0 +1,62 @@
/*
Copyright 2021 Blue Liang, liangkangnan@163.com
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
`include "defines.sv"
// 静态分支预测模块
module bpu(
input wire clk,
input wire rst_n,
input wire[31:0] inst_i,
input wire inst_valid_i,
input wire[31:0] pc_i,
output wire prdt_taken_o,
output wire[31:0] prdt_addr_o
);
wire[6:0] opcode = inst_i[6:0];
wire opcode_1100011 = (opcode == 7'b1100011);
wire opcode_1101111 = (opcode == 7'b1101111);
wire inst_type_branch = opcode_1100011;
wire inst_jal = opcode_1101111;
wire[31:0] inst_b_type_imm = {{20{inst_i[31]}}, inst_i[7], inst_i[30:25], inst_i[11:8], 1'b0};
wire[31:0] inst_j_type_imm = {{12{inst_i[31]}}, inst_i[19:12], inst_i[20], inst_i[30:21], 1'b0};
wire prdt_taken = (inst_type_branch & inst_b_type_imm[31]) | inst_jal;
reg[31:0] prdt_imm;
always @ (*) begin
prdt_imm = inst_b_type_imm;
case (1'b1)
inst_type_branch: prdt_imm = inst_b_type_imm;
inst_jal: prdt_imm = inst_j_type_imm;
default: ;
endcase
end
assign prdt_taken_o = inst_valid_i ? prdt_taken : 1'b0;
assign prdt_addr_o = pc_i + prdt_imm;
endmodule

View File

@ -77,6 +77,8 @@ module exu(
);
wire[31:0] next_pc = dec_pc_i + 4'h4;
// dispatch to ALU
wire[31:0] alu_op1_o;
wire[31:0] alu_op2_o;
@ -106,6 +108,7 @@ module exu(
wire bjp_op_bltu_o;
wire bjp_op_bge_o;
wire bjp_op_bgeu_o;
wire bjp_op_jalr_o;
// dispatch to MULDIV
wire req_muldiv_o;
wire[31:0] muldiv_op1_o;
@ -184,6 +187,7 @@ module exu(
.bjp_op_bltu_o(bjp_op_bltu_o),
.bjp_op_bge_o(bjp_op_bge_o),
.bjp_op_bgeu_o(bjp_op_bgeu_o),
.bjp_op_jalr_o(bjp_op_jalr_o),
// dispatch to MULDIV
.req_muldiv_o(req_muldiv_o),
.muldiv_op1_o(muldiv_op1_o),
@ -357,7 +361,7 @@ module exu(
.csr_reg_wdata_i(csr_rdata_i),
.req_bjp_i(req_bjp_o),
.bjp_reg_we_i(bjp_op_jump_o),
.bjp_reg_wdata_i(next_pc_i),
.bjp_reg_wdata_i(next_pc),
.bjp_reg_waddr_i(rd_waddr_i),
.rd_we_i(rd_we_i),
.rd_waddr_i(rd_waddr_i),
@ -369,10 +373,21 @@ module exu(
assign reg_we_o = commit_reg_we_o & (~int_stall_i);
wire inst_jump = bjp_cmp_res_o | bjp_op_jump_o | sys_op_fence_o;
assign jump_flag_o = (inst_jump & (~int_stall_i)) | int_assert_i;
// jal
wire prdt_taken = ((~bjp_op_jalr_o) & bjp_op_jump_o) |
// bxx & imm[31]
(req_bjp_o & (~bjp_op_jump_o) & dec_imm_i[31]);
// bxx分支预测错误
wire prdt_taken_error = prdt_taken & (~bjp_cmp_res_o) & req_bjp_o & (~bjp_op_jump_o);
wire inst_jump = (bjp_cmp_res_o & (~prdt_taken)) |
(bjp_op_jump_o & (~prdt_taken)) |
sys_op_fence_o;
assign jump_flag_o = ((inst_jump | prdt_taken_error) & (~int_stall_i)) | int_assert_i;
assign jump_addr_o = int_assert_i? int_addr_i:
sys_op_fence_o? next_pc_i:
sys_op_fence_o? next_pc:
prdt_taken_error? next_pc:
bjp_res_o;
assign hold_flag_o = muldiv_stall_o | mem_stall_o;

View File

@ -58,6 +58,7 @@ module exu_dispatch(
output wire bjp_op_bltu_o,
output wire bjp_op_bge_o,
output wire bjp_op_bgeu_o,
output wire bjp_op_jalr_o,
// dispatch to MULDIV
output wire req_muldiv_o,
@ -152,6 +153,7 @@ module exu_dispatch(
assign bjp_op_bge_o = bjp_info[`DECINFO_BJP_BGE];
assign bjp_op_bgeu_o = bjp_info[`DECINFO_BJP_BGEU];
assign req_bjp_o = op_bjp;
assign bjp_op_jalr_o = bjp_op1_rs1;
// MULDIV info
wire op_muldiv = (disp_info_grp == `DECINFO_GRP_MULDIV);

View File

@ -48,6 +48,8 @@ module ifu(
reg[1:0] state;
reg[1:0] next_state;
wire prdt_taken;
wire[31:0] prdt_addr;
always @ (posedge clk or negedge rst_n) begin
if (!rst_n) begin
@ -90,6 +92,7 @@ module ifu(
wire fetch_addr_en = instr_req_o & instr_gnt_i & (~stall_i[`STALL_PC]);
assign fetch_addr_d = flush_i? flush_addr_i:
prdt_taken? prdt_addr:
stall_i[`STALL_PC]? fetch_addr_q:
inst_valid? fetch_addr_q + 4'h4:
fetch_addr_q;
@ -106,4 +109,14 @@ module ifu(
assign instr_addr_o = {fetch_addr_d[31:2], 2'b00};
assign pc_o = fetch_addr_q;
bpu u_bpu(
.clk(clk),
.rst_n(rst_n),
.inst_i(instr_rdata_i),
.inst_valid_i(inst_valid),
.pc_i(fetch_addr_q),
.prdt_taken_o(prdt_taken),
.prdt_addr_o(prdt_addr)
);
endmodule