-
Notifications
You must be signed in to change notification settings - Fork 0
/
checkpointer.sv
115 lines (103 loc) · 4.14 KB
/
checkpointer.sv
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
`timescale 1ns / 1ps
`include "riscv_core.svh"
/*
Module Purpose:
-store data on checkpoints
-output data on recall
-handle logic for checking if checkpointer full
-make checkpointer from ram into fifo with recall
*/
module checkpointer #(
parameter LINE_SIZE = $clog2(`AL_SIZE) + $clog2(`NUM_PR) + $clog2(`NUM_PR)*32 + 64
)(
input clk, reset,
input ext_stall,
//validate checkpoint
input validate [`NUM_BRANCHES_RESOLVED],
input [$clog2(`NUM_CHECKPOINTS)-1:0] validated_id [`NUM_BRANCHES_RESOLVED],
//recall data
input recall_checkpoint,
input [$clog2(`NUM_CHECKPOINTS)-1:0] recall_id,
//create checkpoint
input if_branch [2],
input instrs_valid [2],
input [$clog2(`NUM_PR)-1:0] fl_front,
input [$clog2(`AL_SIZE)-1:0] al_front,
input [$clog2(`NUM_PR)-1:0] RMT_copy [32],
input [`NUM_PR-1:0] bbt,
//outputs
output logic [LINE_SIZE-1:0] recalled_data,
output logic int_stall,
output logic [$clog2(`AL_SIZE)-1:0] oldest_al,
output logic no_checkpoints,
output [$clog2(`NUM_CHECKPOINTS)-1:0] cp_addr
);
logic [$clog2(`NUM_CHECKPOINTS)-1:0] checkpoint_front, checkpoint_back;
logic [$clog2(`NUM_CHECKPOINTS):0] num_checkpoints;
/*(* ram_style = "registers" *) */logic checkpoint_validated [`NUM_CHECKPOINTS];
logic [LINE_SIZE-1:0] din;
assign cp_addr = checkpoint_front;
logic [$clog2(`AL_SIZE)-1:0] al_addresses [`NUM_CHECKPOINTS];
assign din[$clog2(`NUM_PR)-1:0] = fl_front;
assign din[$clog2(`AL_SIZE)-1+$clog2(`NUM_PR):$clog2(`NUM_PR)] = al_front;
assign din[$clog2(`AL_SIZE)+$clog2(`NUM_PR)+`NUM_PR-1:$clog2(`AL_SIZE)+$clog2(`NUM_PR)] = bbt;
genvar i;
generate
for(i = 0; i < 32; i++) begin
assign din[i*$clog2(`NUM_PR)+64+$clog2(`AL_SIZE)+$clog2(`NUM_PR)+:$clog2(`NUM_PR)] = RMT_copy[i];
end
endgenerate
logic stall;
logic we;
assign we = ((if_branch[0] && instrs_valid[0]) || (if_branch[1] && instrs_valid[1]));
assign int_stall = (if_branch[0] && instrs_valid[0] && if_branch[1] && instrs_valid[1]) ||
((num_checkpoints + if_branch[0] && instrs_valid[0] + if_branch[1] && instrs_valid[1]) >= `NUM_CHECKPOINTS);
logic [$clog2(`NUM_CHECKPOINTS)-1:0] addr;
assign addr = recall_checkpoint ? recall_id : checkpoint_front;
distributed_ram #(
.WIDTH(LINE_SIZE),
.DEPTH(`NUM_CHECKPOINTS)
) checkpoints (
.clk,
.addr,
.we,
.din,
.dout(recalled_data)
);
assign oldest_al = al_addresses[checkpoint_back];
assign no_checkpoints = (num_checkpoints == 0);
always_ff @(posedge clk) begin
if(reset) begin
checkpoint_front <= 0;
checkpoint_back <= 0;
num_checkpoints <= 0;
end else if(recall_checkpoint) begin
checkpoint_front <= recall_id;
num_checkpoints <= (recall_id >= checkpoint_back) ? (recall_id - checkpoint_back) : (recall_id - checkpoint_back + `NUM_CHECKPOINTS);
end else if(we && ~int_stall && ~ext_stall) begin
checkpoint_front <= checkpoint_front + 1;
for(int i = 0; i < `NUM_BRANCHES_RESOLVED; i++) begin
if((checkpoint_front != validated_id[i]) && validate[i]) begin
checkpoint_validated[validated_id[i]] <= 1;
end
end
checkpoint_validated[checkpoint_front] <= 0;
al_addresses[checkpoint_front] <= al_front;
if(checkpoint_validated[checkpoint_back]) begin
checkpoint_back <= checkpoint_back + 1;
end else begin
num_checkpoints <= num_checkpoints + 1;
end
end else begin
for(int i = 0; i < `NUM_BRANCHES_RESOLVED; i++) begin
if(validate[i]) begin
checkpoint_validated[validated_id[i]] <= 1;
end
end
if(checkpoint_validated[checkpoint_back]) begin
checkpoint_back <= checkpoint_back + 1;
num_checkpoints <= num_checkpoints - 1;
end
end
end
endmodule