Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 27 additions & 52 deletions Design/BIQ.sv
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,16 @@ module BIQ #(
parameter GHR_SIZE = 9,
parameter RAS_ADDRESS = 3
) (
input logic CLK, reset, biq_dealloc, flush, pred_valid1, pred_valid2, biq_alloc1, biq_alloc2, pred_taken1, pred_taken2,
input logic [BIQ_ADDRESS:0] biq_id, // biq id(5 bits) + slot id (1bit)=6
input logic [XLEN-1:0] pred_target1, pred_target2,
input logic [PHT_ADDRESS-1:0] pht_index1, pht_index2,
input logic CLK, reset, biq_dealloc, flush, biq_alloc, pred_taken,
input logic [XLEN-1:0] pred_target,
input logic [BIQ_ADDRESS-1:0] biq_id,
input logic [PHT_ADDRESS-1:0] pht_index,
input logic [GHR_SIZE-1:0] prev_ghr,
input logic [RAS_ADDRESS-1:0] sp_snap,
input logic [2*XLEN-1:0] ras_snap,
output logic [BIQ_ADDRESS-1:0] biq_address, //without slot id cuz 2 slots combined
output logic biq_valid, biq_pred_taken, stall_frontend,

output logic biq_pred_taken, stall_frontend,
output logic [BIQ_ADDRESS-1:0] biq_address,
output logic [XLEN-1:0] biq_pred_target,
output logic [GHR_SIZE-1:0] biq_restore_ghr,
output logic [RAS_ADDRESS-1:0] biq_sp_snap,
Expand All @@ -22,27 +23,20 @@ module BIQ #(
);

typedef struct packed {
logic predicted_valid;
logic predicted_taken;
logic [XLEN-1:0] predicted_target;
logic [PHT_ADDRESS-1:0] pht_table_index;
} biq_bank_organization;

typedef struct packed {
logic [GHR_SIZE-1:0] previous_ghr;
logic [2*XLEN-1:0] ras_snapshot;
logic [RAS_ADDRESS-1:0] sp_snapshot;
} biq_shared_organization;

(* ram_style = "distributed" *) biq_bank_organization BIQ_BANK0 [0:(1<<BIQ_ADDRESS)-1];
(* ram_style = "distributed" *) biq_bank_organization BIQ_BANK1 [0:(1<<BIQ_ADDRESS)-1];
(* ram_style = "distributed" *) biq_shared_organization BIQ_SHARED [0:(1<<BIQ_ADDRESS)-1];
} biq_organization;

(* ram_style = "distributed" *) biq_organization BIQ [0:(1<<BIQ_ADDRESS)-1];
logic [BIQ_ADDRESS-1:0] biq_read_address;
logic [BIQ_ADDRESS:0] biq_head_ptr, biq_tail_ptr;
logic biq_full;

assign biq_read_address = biq_id[BIQ_ADDRESS:1];
assign biq_read_address = biq_id;
assign biq_full = (biq_head_ptr[BIQ_ADDRESS-1:0] == biq_tail_ptr[BIQ_ADDRESS-1:0]) && (biq_head_ptr[BIQ_ADDRESS]!= biq_tail_ptr[BIQ_ADDRESS]);
assign biq_address = biq_tail_ptr[BIQ_ADDRESS-1:0];
assign stall_frontend = biq_full;
Expand All @@ -59,44 +53,25 @@ module BIQ #(
if (biq_dealloc) begin
biq_head_ptr <= biq_head_ptr + 1;
end
if(!biq_full) begin
if (biq_alloc1) begin
BIQ_BANK0[biq_tail_ptr[BIQ_ADDRESS-1:0]].predicted_valid <= pred_valid1;
BIQ_BANK0[biq_tail_ptr[BIQ_ADDRESS-1:0]].predicted_taken <= pred_taken1;
BIQ_BANK0[biq_tail_ptr[BIQ_ADDRESS-1:0]].predicted_target <= pred_target1;
BIQ_BANK0[biq_tail_ptr[BIQ_ADDRESS-1:0]].pht_table_index <= pht_index1;
end
if (biq_alloc2) begin
BIQ_BANK1[biq_tail_ptr[BIQ_ADDRESS-1:0]].predicted_valid <= pred_valid2;
BIQ_BANK1[biq_tail_ptr[BIQ_ADDRESS-1:0]].predicted_taken <= pred_taken2;
BIQ_BANK1[biq_tail_ptr[BIQ_ADDRESS-1:0]].predicted_target <= pred_target2;
BIQ_BANK1[biq_tail_ptr[BIQ_ADDRESS-1:0]].pht_table_index <= pht_index2;
end
if (biq_alloc1 || biq_alloc2) begin
biq_tail_ptr <= biq_tail_ptr + 1;
BIQ_SHARED[biq_tail_ptr[BIQ_ADDRESS-1:0]].previous_ghr <= prev_ghr;
BIQ_SHARED[biq_tail_ptr[BIQ_ADDRESS-1:0]].ras_snapshot <= ras_snap;
BIQ_SHARED[biq_tail_ptr[BIQ_ADDRESS-1:0]].sp_snapshot <= sp_snap;
end
if ((!biq_full || biq_dealloc) && biq_alloc) begin
BIQ[biq_address].predicted_taken <= pred_taken;
BIQ[biq_address].predicted_target <= pred_target;
BIQ[biq_address].pht_table_index <= pht_index;
BIQ[biq_address].previous_ghr <= prev_ghr;
BIQ[biq_address].ras_snapshot <= ras_snap;
BIQ[biq_address].sp_snapshot <= sp_snap;
biq_tail_ptr <= biq_tail_ptr + 1;
end
end
end
end
end

// reading from biq
always_ff @(posedge CLK) begin
if (biq_id[0]) begin //for bank1
biq_valid <= BIQ_BANK1[biq_read_address].predicted_valid;
biq_pred_taken <= BIQ_BANK1[biq_read_address].predicted_taken;
biq_pht_index <= BIQ_BANK1[biq_read_address].pht_table_index;
biq_pred_target <= BIQ_BANK1[biq_read_address].predicted_target;
end
else begin //for bank 0
biq_valid <= BIQ_BANK0[biq_read_address].predicted_valid;
biq_pred_taken <= BIQ_BANK0[biq_read_address].predicted_taken;
biq_pht_index <= BIQ_BANK0[biq_read_address].pht_table_index;
biq_pred_target <= BIQ_BANK0[biq_read_address].predicted_target;
end
biq_restore_ghr <= BIQ_SHARED[biq_read_address].previous_ghr;
biq_ras_snap <= BIQ_SHARED[biq_read_address].ras_snapshot;
biq_sp_snap <= BIQ_SHARED[biq_read_address].sp_snapshot;
biq_pred_taken <= BIQ[biq_read_address].predicted_taken;
biq_pht_index <= BIQ[biq_read_address].pht_table_index;
biq_pred_target <= BIQ[biq_read_address].predicted_target;
biq_restore_ghr <= BIQ[biq_read_address].previous_ghr;
biq_ras_snap <= BIQ[biq_read_address].ras_snapshot;
biq_sp_snap <= BIQ[biq_read_address].sp_snapshot;
end
endmodule
52 changes: 33 additions & 19 deletions Design/BS.sv
Original file line number Diff line number Diff line change
Expand Up @@ -2,62 +2,76 @@ module BS #(
parameter PRF_ADDRESS = 6,
parameter NUM_PHY_REG = 1 << PRF_ADDRESS,
parameter MAX_BRANCHES = 4,
parameter BTAG_SIZE = $clog2(MAX_BRANCHES)
parameter BTAG_SIZE = $clog2(MAX_BRANCHES),
parameter FL_ROWS = NUM_PHY_REG - 32,
parameter FL_INDEX_WIDTH = $clog2(FL_ROWS),
parameter FL_PTR_WIDTH = FL_INDEX_WIDTH + 1
) (
input logic CLK, reset, id_take_snap, ex_branch_resolved,
input logic CLK, reset, flush, id_take_snap, ex_branch_resolved, pop1, pop2,
input logic id_branch1, id_jump1, id_valid1,
input logic [BTAG_SIZE-1:0] ex_btag,
input logic [PRF_ADDRESS-1:0] rmt_snap [0:31],
input logic [NUM_PHY_REG-1:0] busy_table_snap,
input logic [PRF_ADDRESS-1:0] freelist_head_snap,
output logic [PRF_ADDRESS-1:0] bs_rmt_snap [0:31],
output logic [NUM_PHY_REG-1:0] bs_busytable_snap,
output logic [PRF_ADDRESS-1:0] bs_freelist_head_snap,
input logic [31:0][PRF_ADDRESS-1:0] rmt_snap,
input logic [FL_PTR_WIDTH-1:0] freelist_head_snap,

output logic bs_full,
output logic [31:0][PRF_ADDRESS-1:0] bs_rmt_snap,
output logic [FL_PTR_WIDTH-1:0] bs_freelist_head_snap,
output logic [BTAG_SIZE-1:0] bs_branch_tag,
output logic [MAX_BRANCHES-1:0] bs_branch_mask
);

typedef struct {
logic [PRF_ADDRESS-1:0] rmt_snapshot [0:31];
logic [NUM_PHY_REG-1:0] busy_table_snapshot;
logic [PRF_ADDRESS-1:0] freelist_head_snapshot;
typedef struct packed{
logic [31:0][PRF_ADDRESS-1:0] rmt_snapshot;
logic [FL_PTR_WIDTH-1:0] freelist_head_snapshot;
logic [MAX_BRANCHES-1:0] bmr_snapshot;
} bs_organization;

bs_organization BS [0:MAX_BRANCHES-1];

logic [MAX_BRANCHES-1:0] BMR;
logic [BTAG_SIZE-1:0] current_btag;

always_comb begin
current_btag = '0;
for (int i = 0; i < MAX_BRANCHES; i++) begin
if (!BMR[i]) begin
current_btag = i;
current_btag = BTAG_SIZE'(i);
break;
end
end
end
//to dispatch stage
assign bs_branch_tag = current_btag;
assign bs_branch_mask = BMR;

//to rename map table
assign bs_rmt_snap = BS[ex_btag].rmt_snapshot;
assign bs_busytable_snap = BS[ex_btag].busy_table_snapshot;
assign bs_freelist_head_snap = BS[ex_btag].freelist_head_snapshot;
assign bs_full = &BMR;
//to dispatch stage
assign bs_branch_tag = current_btag;
assign bs_branch_mask = BMR;

always_ff @(posedge CLK) begin
if (reset) begin
BMR <= '0;
end
else begin
//when branch is resolved we make the tag bit zero back again
if (flush) begin
BMR <= BS[ex_btag].bmr_snapshot;
end
if (ex_branch_resolved) begin
BMR[ex_btag] <= 1'b0;
//all the branches that took snapshot of BMR should also get 0 because branch is resolved
for (int i = 0; i < MAX_BRANCHES; i++) begin
if (!(id_take_snap && (BTAG_SIZE'(i) == current_btag))) begin
BS[i].bmr_snapshot[ex_btag] <= 1'b0;
end
end
end
if (id_take_snap) begin
BMR[current_btag] <= 1'b1;
BS[current_btag].rmt_snapshot <= rmt_snap;
BS[current_btag].busy_table_snapshot <= busy_table_snap;
BS[current_btag].freelist_head_snapshot <= freelist_head_snap;
BS[current_btag].bmr_snapshot <= (ex_branch_resolved) ? (BMR & ~(1 << ex_btag)) : BMR;
end
end
end
Expand Down
118 changes: 65 additions & 53 deletions Design/BTB.sv
Original file line number Diff line number Diff line change
@@ -1,66 +1,78 @@
//direct-mapped BTB
//direct-mapped cache BTB
module BTB #(
parameter BTB_ADDRESS = 6,
parameter BTB_ROWS = 64,
parameter XLEN = 32,
parameter TAG_SIZE = XLEN - BTB_ADDRESS - 2
parameter BTB_ADDRESS = $clog2(BTB_ROWS),
parameter TAG_SIZE = XLEN - BTB_ADDRESS - 3
) (
input logic CLK, reset, update_btb, ex_is_ret, ex_is_branch,
input logic [XLEN-1:0] pc1, pc2, ex_pc,
input logic [XLEN-1:0] actual_target_address,
output logic btb_hit1, btb_hit2, is_ret1, is_ret2, is_branch1, is_branch2,
output logic [XLEN-1:0] pred_target1, pred_target2
input logic CLK, reset, if_is_jal1, if_is_jal2, ex_is_taken_branch,
input logic ex_is_jalr, ex_is_not_ret,
input logic [XLEN-1:0] pd_pc, if_pc, ex_pc,
input logic [XLEN-3:0] ex_target_address, if_target_address,

output logic btb_hit, squash_instruction, btb_is_branch,
output logic [XLEN-1:0] pred_target_address
);

logic [TAG_SIZE-1:0] pd_tag, if_tag, ex_tag;
logic [BTB_ADDRESS-1:0] btb_read_address, ex_btb_write_address, if_btb_write_address;

typedef struct packed {
logic [TAG_SIZE-1:0] tag;
logic [XLEN-1:0] target_address;
logic valid;
logic is_ret;
logic [TAG_SIZE-1:0] bundled_tag;
logic [XLEN-3:0] target_address; //for bundled pc and not storing the 2 bits cuz they are always zero
logic offset; // which among the bundle is branch so that ahead instruction is squashed
logic valid;
logic is_branch;
} btb_organization;

(* ram_style = "block" *) btb_organization BTB [0:(1<<BTB_ADDRESS)-1];

btb_organization btb_entry1, btb_entry2;
logic tag_matched1, tag_matched2;

//read signals
logic [TAG_SIZE-1:0] btb_tag1, btb_tag2, reg_btb_tag1, reg_btb_tag2;
logic [BTB_ADDRESS-1:0] btb_index1, btb_index2;
//write signals
logic [TAG_SIZE-1:0] ex_tag;
logic [BTB_ADDRESS-1:0] ex_btb_index;

assign btb_tag1 = pc1[XLEN-1:BTB_ADDRESS+2];
assign btb_tag2 = pc2[XLEN-1:BTB_ADDRESS+2];
assign btb_index1 = pc1[BTB_ADDRESS+1:2];
assign btb_index2 = pc2[BTB_ADDRESS+1:2];

assign ex_tag = ex_pc[XLEN-1:BTB_ADDRESS+2];
assign ex_btb_index = ex_pc[BTB_ADDRESS+1:2];
btb_organization BTB [0:BTB_ROWS-1];

always_comb begin
pd_tag = pd_pc[XLEN-1: BTB_ADDRESS+3];
if_tag = if_pc[XLEN-1: BTB_ADDRESS+3];
ex_tag = ex_pc[XLEN-1: BTB_ADDRESS+3];
btb_read_address = pd_pc[BTB_ADDRESS+2:3];
if_btb_write_address = if_pc[BTB_ADDRESS+2:3];
ex_btb_write_address = ex_pc[BTB_ADDRESS+2:3];
end

always_ff @(posedge CLK) begin
if(update_btb) begin
BTB[ex_btb_index].tag <= ex_tag;
BTB[ex_btb_index].target_address <= actual_target_address;
BTB[ex_btb_index].valid <= update_btb;
BTB[ex_btb_index].is_ret <= ex_is_ret;
BTB[ex_btb_index].is_branch <= ex_is_branch;
if (reset) begin
for (int i = 0; i < BTB_ROWS; i++) begin
BTB[i].valid <= 0;
end
end

else begin
//writing btb from ex stage
if(ex_is_taken_branch || ex_is_jalr && ex_is_not_ret) begin
BTB[ex_btb_write_address].bundled_tag <= ex_tag;
BTB[ex_btb_write_address].target_address <= ex_target_address;
BTB[ex_btb_write_address].valid <= 1;
BTB[ex_btb_write_address].offset <= ex_pc[29];
BTB[ex_btb_write_address].is_branch <= ex_is_taken_branch;
end
//writing btb from fetch stage
if (if_is_jal1 || if_is_jal2) begin
BTB[if_btb_write_address].bundled_tag <= if_tag;
BTB[if_btb_write_address].target_address <= if_target_address;
BTB[if_btb_write_address].valid <= 1;
BTB[ex_btb_write_address].offset <= if_pc[29];
BTB[ex_btb_write_address].is_branch <= 0;
end
end
// read btb
if (BTB[btb_read_address].valid && BTB[btb_read_address].bundled_tag == pd_tag) begin
btb_hit <= 1;
pred_target_address <= {BTB[btb_read_address].target_address, 2'b00};
squash_instruction <= ~BTB[btb_read_address].offset; //if (offset = 0): squash; else: dont squash;
btb_is_branch <= BTB[btb_read_address].is_branch;
end
else begin
btb_hit <= 0;
squash_instruction <= 0;
btb_is_branch <= 0;
end
btb_entry1 <= BTB[btb_index1];
btb_entry2 <= BTB[btb_index2];
reg_btb_tag1 <= btb_tag1;
reg_btb_tag2 <= btb_tag2;
end
always_comb begin
tag_matched1 = btb_entry1.tag == reg_btb_tag1;
tag_matched2 = btb_entry2.tag == reg_btb_tag2;
btb_hit1 = btb_entry1.valid && tag_matched1;
btb_hit2 = btb_entry2.valid && tag_matched2;
pred_target1 = btb_entry1.target_address;
pred_target2 = btb_entry2.target_address;
is_ret1 = btb_hit1 && btb_entry1.is_ret;
is_ret2 = btb_hit2 && btb_entry2.is_ret;
is_branch1 = btb_hit1 && btb_entry1.is_branch;
is_branch2 = btb_hit2 && btb_entry2.is_branch;
end

endmodule
Loading