rtl: add static branch predict unit
Signed-off-by: liangkangnan <liangkangnan@163.com>pull/4/head
parent
e26dda807e
commit
7196d33074
|
@ -21,6 +21,7 @@
|
||||||
../rtl/core/rst_gen.sv
|
../rtl/core/rst_gen.sv
|
||||||
../rtl/core/tinyriscv_core.sv
|
../rtl/core/tinyriscv_core.sv
|
||||||
../rtl/core/tracer.sv
|
../rtl/core/tracer.sv
|
||||||
|
../rtl/core/bpu.sv
|
||||||
|
|
||||||
../rtl/debug/jtag_def.sv
|
../rtl/debug/jtag_def.sv
|
||||||
../rtl/debug/jtag_tap.sv
|
../rtl/debug/jtag_tap.sv
|
||||||
|
|
|
@ -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
|
|
@ -77,6 +77,8 @@ module exu(
|
||||||
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
wire[31:0] next_pc = dec_pc_i + 4'h4;
|
||||||
|
|
||||||
// dispatch to ALU
|
// dispatch to ALU
|
||||||
wire[31:0] alu_op1_o;
|
wire[31:0] alu_op1_o;
|
||||||
wire[31:0] alu_op2_o;
|
wire[31:0] alu_op2_o;
|
||||||
|
@ -106,6 +108,7 @@ module exu(
|
||||||
wire bjp_op_bltu_o;
|
wire bjp_op_bltu_o;
|
||||||
wire bjp_op_bge_o;
|
wire bjp_op_bge_o;
|
||||||
wire bjp_op_bgeu_o;
|
wire bjp_op_bgeu_o;
|
||||||
|
wire bjp_op_jalr_o;
|
||||||
// dispatch to MULDIV
|
// dispatch to MULDIV
|
||||||
wire req_muldiv_o;
|
wire req_muldiv_o;
|
||||||
wire[31:0] muldiv_op1_o;
|
wire[31:0] muldiv_op1_o;
|
||||||
|
@ -184,6 +187,7 @@ module exu(
|
||||||
.bjp_op_bltu_o(bjp_op_bltu_o),
|
.bjp_op_bltu_o(bjp_op_bltu_o),
|
||||||
.bjp_op_bge_o(bjp_op_bge_o),
|
.bjp_op_bge_o(bjp_op_bge_o),
|
||||||
.bjp_op_bgeu_o(bjp_op_bgeu_o),
|
.bjp_op_bgeu_o(bjp_op_bgeu_o),
|
||||||
|
.bjp_op_jalr_o(bjp_op_jalr_o),
|
||||||
// dispatch to MULDIV
|
// dispatch to MULDIV
|
||||||
.req_muldiv_o(req_muldiv_o),
|
.req_muldiv_o(req_muldiv_o),
|
||||||
.muldiv_op1_o(muldiv_op1_o),
|
.muldiv_op1_o(muldiv_op1_o),
|
||||||
|
@ -357,7 +361,7 @@ module exu(
|
||||||
.csr_reg_wdata_i(csr_rdata_i),
|
.csr_reg_wdata_i(csr_rdata_i),
|
||||||
.req_bjp_i(req_bjp_o),
|
.req_bjp_i(req_bjp_o),
|
||||||
.bjp_reg_we_i(bjp_op_jump_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),
|
.bjp_reg_waddr_i(rd_waddr_i),
|
||||||
.rd_we_i(rd_we_i),
|
.rd_we_i(rd_we_i),
|
||||||
.rd_waddr_i(rd_waddr_i),
|
.rd_waddr_i(rd_waddr_i),
|
||||||
|
@ -369,10 +373,21 @@ module exu(
|
||||||
|
|
||||||
assign reg_we_o = commit_reg_we_o & (~int_stall_i);
|
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;
|
// jal
|
||||||
assign jump_flag_o = (inst_jump & (~int_stall_i)) | int_assert_i;
|
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:
|
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;
|
bjp_res_o;
|
||||||
assign hold_flag_o = muldiv_stall_o | mem_stall_o;
|
assign hold_flag_o = muldiv_stall_o | mem_stall_o;
|
||||||
|
|
||||||
|
|
|
@ -58,6 +58,7 @@ module exu_dispatch(
|
||||||
output wire bjp_op_bltu_o,
|
output wire bjp_op_bltu_o,
|
||||||
output wire bjp_op_bge_o,
|
output wire bjp_op_bge_o,
|
||||||
output wire bjp_op_bgeu_o,
|
output wire bjp_op_bgeu_o,
|
||||||
|
output wire bjp_op_jalr_o,
|
||||||
|
|
||||||
// dispatch to MULDIV
|
// dispatch to MULDIV
|
||||||
output wire req_muldiv_o,
|
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_bge_o = bjp_info[`DECINFO_BJP_BGE];
|
||||||
assign bjp_op_bgeu_o = bjp_info[`DECINFO_BJP_BGEU];
|
assign bjp_op_bgeu_o = bjp_info[`DECINFO_BJP_BGEU];
|
||||||
assign req_bjp_o = op_bjp;
|
assign req_bjp_o = op_bjp;
|
||||||
|
assign bjp_op_jalr_o = bjp_op1_rs1;
|
||||||
|
|
||||||
// MULDIV info
|
// MULDIV info
|
||||||
wire op_muldiv = (disp_info_grp == `DECINFO_GRP_MULDIV);
|
wire op_muldiv = (disp_info_grp == `DECINFO_GRP_MULDIV);
|
||||||
|
|
|
@ -48,6 +48,8 @@ module ifu(
|
||||||
|
|
||||||
reg[1:0] state;
|
reg[1:0] state;
|
||||||
reg[1:0] next_state;
|
reg[1:0] next_state;
|
||||||
|
wire prdt_taken;
|
||||||
|
wire[31:0] prdt_addr;
|
||||||
|
|
||||||
always @ (posedge clk or negedge rst_n) begin
|
always @ (posedge clk or negedge rst_n) begin
|
||||||
if (!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]);
|
wire fetch_addr_en = instr_req_o & instr_gnt_i & (~stall_i[`STALL_PC]);
|
||||||
|
|
||||||
assign fetch_addr_d = flush_i? flush_addr_i:
|
assign fetch_addr_d = flush_i? flush_addr_i:
|
||||||
|
prdt_taken? prdt_addr:
|
||||||
stall_i[`STALL_PC]? fetch_addr_q:
|
stall_i[`STALL_PC]? fetch_addr_q:
|
||||||
inst_valid? fetch_addr_q + 4'h4:
|
inst_valid? fetch_addr_q + 4'h4:
|
||||||
fetch_addr_q;
|
fetch_addr_q;
|
||||||
|
@ -106,4 +109,14 @@ module ifu(
|
||||||
assign instr_addr_o = {fetch_addr_d[31:2], 2'b00};
|
assign instr_addr_o = {fetch_addr_d[31:2], 2'b00};
|
||||||
assign pc_o = fetch_addr_q;
|
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
|
endmodule
|
||||||
|
|
Loading…
Reference in New Issue