Skip to content

Commit

Permalink
Add support for an unsynthesizable ROB to produce a TracedInstruction…
Browse files Browse the repository at this point in the history
… stream from Rocket with wdata
  • Loading branch information
jerryz123 committed May 10, 2023
1 parent 62162c5 commit d6c09c9
Show file tree
Hide file tree
Showing 10 changed files with 426 additions and 7 deletions.
1 change: 1 addition & 0 deletions build.sc
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,7 @@ class Emulator(top: String, config: String) extends Module {
Seq(
"SimDTM.cc",
"SimJTAG.cc",
"debug_rob.cc",
"emulator.cc",
"remote_bitbang.cc",
).map(c => PathRef(csrcDir().path / c))
Expand Down
2 changes: 1 addition & 1 deletion emulator/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ output_dir = $(sim_dir)/output

include $(base_dir)/Makefrag

CXXSRCS := emulator SimDTM SimJTAG remote_bitbang
CXXSRCS := emulator SimDTM SimJTAG remote_bitbang debug_rob
CXXFLAGS := $(CXXFLAGS) -std=c++17 -I$(RISCV)/include
LDFLAGS := $(LDFLAGS) -L$(RISCV)/lib -Wl,-rpath,$(RISCV)/lib -L$(abspath $(sim_dir)) -lfesvr -lpthread

Expand Down
125 changes: 125 additions & 0 deletions src/main/resources/csrc/debug_rob.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
#include <map>
#include <deque>
#include <stdint.h>
#include <cstring>

#define WDATA_BITS (512)
#define WDATA_BYTES (WDATA_BITS / 8)

typedef struct tagged_wb_data_t {
uint64_t tag;
uint8_t data[WDATA_BYTES];
};

typedef struct tagged_traced_insn_t {
uint64_t iaddr;
uint64_t insn;
uint8_t priv;
bool exception;
bool interrupt;
uint64_t cause;
uint64_t tval;
uint8_t wdata[WDATA_BYTES];

bool waiting;
uint64_t wb_tag;
};

typedef struct debug_rob_t {
std::deque<tagged_traced_insn_t*> rob;
std::deque<tagged_wb_data_t*> wb_datas;
};

std::map<int, debug_rob_t*> debug_robs;

extern "C" void debug_rob_push_trace(int hartid,
char should_wb,
char has_wb,
long long int wb_tag,
char trace_valid,
long long int trace_iaddr,
long long int trace_insn,
int trace_priv,
char trace_exception,
char trace_interrupt,
long long int trace_cause,
long long int trace_tval,
long long int* trace_wdata) {

if (debug_robs.find(hartid) == debug_robs.end())
debug_robs[hartid] = new debug_rob_t;

if (!trace_valid) return;

tagged_traced_insn_t* insn = new tagged_traced_insn_t;
insn->iaddr = trace_iaddr;
insn->insn = trace_insn;
insn->priv = trace_priv;
insn->exception = trace_exception;
insn->interrupt = trace_interrupt;
insn->cause = trace_cause;
insn->tval = trace_tval;
insn->waiting = should_wb && !has_wb;
insn->wb_tag = wb_tag;
memcpy(insn->wdata, trace_wdata, WDATA_BYTES);

debug_robs[hartid]->rob.push_back(insn);
}

extern "C" void debug_rob_push_wb(int hartid,
char valid,
long long int wb_tag,
long long int* wb_data) {
if (debug_robs.find(hartid) == debug_robs.end())
debug_robs[hartid] = new debug_rob_t;

if (!valid) return;

tagged_wb_data_t* data = new tagged_wb_data_t;
data->tag = wb_tag;
memcpy(data->data, wb_data, WDATA_BYTES);
debug_robs[hartid]->wb_datas.push_back(data);
}

extern "C" void debug_rob_pop_trace(int hartid,
char* trace_valid,
long long int* trace_iaddr,
long long int* trace_insn,
int* trace_priv,
char* trace_exception,
char* trace_interrupt,
long long int* trace_cause,
long long int* trace_tval,
long long int* trace_wdata) {
*trace_valid = 0;
if (debug_robs.find(hartid) == debug_robs.end()) return;
if (debug_robs[hartid]->rob.empty()) return;

tagged_traced_insn_t* front = debug_robs[hartid]->rob.front();
std::deque<tagged_wb_data_t*> &wb_datas = debug_robs[hartid]->wb_datas;
if (front->waiting) {
for (auto it = wb_datas.begin(); it != wb_datas.end(); it++) {
if ((*it)->tag == front->wb_tag) {
memcpy(front->wdata, (*it)->data, WDATA_BYTES);
front->waiting = false;
wb_datas.erase(it);
break;
}
}
}

if (front->waiting) return;

*trace_valid = true;
*trace_iaddr = front->iaddr;
*trace_insn = front->insn;
*trace_priv = front->priv;
*trace_exception = front->exception;
*trace_interrupt = front->interrupt;
*trace_cause = front->cause;
*trace_tval = front->tval;
memcpy(trace_wdata, front->wdata, WDATA_BYTES);
debug_robs[hartid]->rob.pop_front();
}


156 changes: 156 additions & 0 deletions src/main/resources/vsrc/debug_rob.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
import "DPI-C" function void debug_rob_push_trace(input int hartid,
input bit should_wb,
input bit has_wb,
input longint wb_tag,
input bit trace_valid,
input longint trace_iaddr,
input longint trace_insn,
input int trace_priv,
input bit trace_exception,
input bit trace_interrupt,
input longint trace_cause,
input longint trace_tval,
input longint trace_wdata[8]);

import "DPI-C" function void debug_rob_push_wb(input int hartid,
input bit valid,
input longint wb_tag,
input longint wb_data[8]);

import "DPI-C" function void debug_rob_pop_trace(input int hartid,
output bit trace_valid,
output longint trace_iaddr,
output longint trace_insn,
output int trace_priv,
output bit trace_exception,
output bit trace_interrupt,
output longint trace_cause,
output longint trace_tval,
output longint trace_wdata[8]);


module DebugROBPushTrace (
input clock,
input reset,
input [31:0] hartid,
input should_wb,
input has_wb,
input [63:0] wb_tag,
input trace_valid,
input [63:0] trace_iaddr,
input [63:0] trace_insn,
input [2:0] trace_priv,
input trace_exception,
input trace_interrupt,
input [63:0] trace_cause,
input [63:0] trace_tval,
input [511:0] trace_wdata);

longint __trace_wdata[8];
genvar i;

for (i = 0; i < 8; i = i + 1)
assign __trace_wdata[i] = trace_wdata[(i+1)*64-1:i*64];

always @(posedge clock) begin
if (!reset) begin
debug_rob_push_trace(hartid,
should_wb, has_wb, wb_tag,
trace_valid, trace_iaddr, trace_insn,
trace_priv, trace_exception, trace_interrupt,
trace_cause, trace_tval, __trace_wdata);
end
end
endmodule; // DebugROBPushTrace

module DebugROBPushWb (
input clock,
input reset,
input [31:0] hartid,
input valid,
input [63:0] wb_tag,
input [511:0] wb_data);

longint __wb_data[8];
genvar i;

for (i = 0; i < 8; i = i + 1)
assign __wb_data[i] = wb_data[(i+1)*64-1:i*64];

always @(posedge clock) begin
if (!reset) begin
debug_rob_push_wb(hartid, valid, wb_tag, __wb_data);
end
end
endmodule; // DebugROBPushWb

module DebugROBPopTrace (
input clock,
input reset,
input [31:0] hartid,
output trace_valid,
output [63:0] trace_iaddr,
output [63:0] trace_insn,
output [2:0] trace_priv,
output trace_exception,
output trace_interrupt,
output [63:0] trace_cause,
output [63:0] trace_tval,
output [511:0] trace_wdata);

bit r_reset;

bit __trace_valid;
longint __trace_iaddr;
longint __trace_insn;
int __trace_priv;
bit __trace_exception;
bit __trace_interrupt;
longint __trace_cause;
longint __trace_tval;
longint __trace_wdata[8];

reg __trace_valid_reg;
reg [63:0] __trace_iaddr_reg;
reg [63:0] __trace_insn_reg;
reg [2:0] __trace_priv_reg;
reg __trace_exception_reg;
reg __trace_interrupt_reg;
reg [63:0] __trace_cause_reg;
reg [63:0] __trace_tval_reg;
reg [511:0] __trace_wdata_reg;

always @(posedge clock) begin
__trace_valid_reg <= __trace_valid;
__trace_iaddr_reg <= __trace_iaddr;
__trace_insn_reg <= __trace_insn;
__trace_priv_reg <= __trace_priv;
__trace_exception_reg <= __trace_exception;
__trace_interrupt_reg <= __trace_interrupt;
__trace_cause_reg <= __trace_cause;
__trace_tval_reg <= __trace_tval;
__trace_wdata_reg <= {__trace_wdata[7], __trace_wdata[6], __trace_wdata[5], __trace_wdata[4],
__trace_wdata[3], __trace_wdata[2], __trace_wdata[1], __trace_wdata[0]};
end // always @ (posedge clock)

assign trace_valid = __trace_valid_reg;
assign trace_iaddr = __trace_iaddr_reg;
assign trace_insn = __trace_insn_reg;
assign trace_priv = __trace_priv_reg;
assign trace_exception = __trace_exception_reg;
assign trace_interrupt = __trace_interrupt_reg;
assign trace_cause = __trace_cause_reg;
assign trace_tval = __trace_tval_reg;
assign trace_wdata = __trace_wdata_reg;

always @(negedge clock) begin
r_reset <= reset;
if (!reset && !r_reset) begin
debug_rob_pop_trace(hartid,
__trace_valid, __trace_iaddr, __trace_insn,
__trace_priv, __trace_exception, __trace_interrupt,
__trace_cause, __trace_tval, __trace_wdata);
end
end
endmodule; // DebugROBPopTrace

1 change: 1 addition & 0 deletions src/main/scala/rocket/CSR.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1527,6 +1527,7 @@ class CSRFile(
t.cause := cause
t.interrupt := cause(xLen-1)
t.tval := io.tval
t.wdata.foreach(_ := DontCare)
}

def chooseInterrupt(masksIn: Seq[UInt]): (Bool, UInt) = {
Expand Down
Loading

0 comments on commit d6c09c9

Please sign in to comment.