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
33 changes: 17 additions & 16 deletions monitor/src/global_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
// released under MIT License
// author: Ernest Ng <eyn5@cornell.edu>

use crate::Cli;

/// Time unit for displaying waveform times
#[derive(Debug, Clone, Copy)]
pub enum TimeUnit {
Expand Down Expand Up @@ -62,29 +64,28 @@ pub struct GlobalContext {

/// Indicates if there are multiple (more than 1) structs in the source file
pub multiple_structs: bool,

/// Indicates whether to print out thread IDs for each inferred transaction
pub show_thread_ids: bool,
}

impl GlobalContext {
/// Creates a new `GlobalContext` with the provided `design` and configuration flags.
/// The `display_hex` argument indicates whether to print integer literals
/// using hexadecimal (if `false`, we default to using decimal).
pub fn new(
waveform_file: String,
instance_id: u32,
display_hex: bool,
show_waveform_time: bool,
time_unit: TimeUnit,
print_num_steps: bool,
multiple_structs: bool,
) -> Self {
/// Creates a new `GlobalContext` with the provided `design`
/// and configuration flags as specified by the user via the `Cli`.
/// The `display_hex` field indicates whether to print integer literals
/// in hexadecimal (if `false`, we default to using decimal).
/// Note: this function is meant to be called from `main.rs` only
/// upon monitor initialization.
pub fn new(cli: &Cli, instance_id: u32, time_unit: TimeUnit, multiple_structs: bool) -> Self {
Self {
waveform_file,
waveform_file: cli.wave.clone(),
instance_id,
display_hex,
show_waveform_time,
display_hex: cli.display_hex,
show_waveform_time: cli.show_waveform_time,
time_unit,
print_num_steps,
print_num_steps: cli.print_num_steps,
multiple_structs,
show_thread_ids: cli.show_thread_ids,
}
}
}
77 changes: 49 additions & 28 deletions monitor/src/global_scheduler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,23 +112,23 @@ fn process_group_cycles(
/// For a single scheduler group, collects all unique maximal traces
/// (deduplicated on canonical `ProtocolApplication` sequence, excluding idle,
/// with strict-prefix traces filtered out).
/// Returns the list of maximal `OutputEntry` traces for this group.
/// Returns the list of maximal `AugmentedProtocolApplication` traces for this group.
fn collect_maximal_traces(scheduler_group: &SchedulerGroup) -> Vec<AugmentedTrace> {
// Collect all unique traces, deduplicating on the canonical
// `ProtocolApplication` sequence (ignoring timing and thread IDs)
let mut all_entries: Vec<AugmentedTrace> = vec![];
let mut seen_traces: FxHashSet<Trace> = FxHashSet::default();

for scheduler in scheduler_group {
// Sort `OutputEntry`s by increasing cycle no.
// Sort `AugmentedProtocolApplication`s by increasing cycle no.
let mut sorted_output_entries = scheduler.output_buffer.clone();
sorted_output_entries.sort_by_key(|entry| entry.end_cycle_count);
sorted_output_entries.sort_by_key(|prot| prot.end_cycle_count);

// Build canonical trace for dedup, excluding idle entries
let trace: Trace = sorted_output_entries
.iter()
.filter(|entry| !entry.is_idle)
.map(|entry| entry.protocol_application.clone())
.filter(|prot| !prot.is_idle)
.map(|prot| prot.protocol_application.clone())
.collect();

// Only append `sorted_output_entries` to `all_entries`
Expand All @@ -144,11 +144,11 @@ fn collect_maximal_traces(scheduler_group: &SchedulerGroup) -> Vec<AugmentedTrac
// resulting in a shorter trace.
let all_traces: Vec<Trace> = all_entries
.iter()
.map(|entries| {
entries
.map(|augmented_trace| {
augmented_trace
.iter()
.filter(|e| !e.is_idle)
.map(|e| e.protocol_application.clone())
.filter(|prot| !prot.is_idle)
.map(|prot| prot.protocol_application.clone())
.collect()
})
.collect();
Expand All @@ -167,6 +167,15 @@ fn collect_maximal_traces(scheduler_group: &SchedulerGroup) -> Vec<AugmentedTrac
}

impl GlobalScheduler {
fn print_trace_block(trace_index: usize, lines: &[String]) {
println!("// trace {}", trace_index);
println!("trace {{");
for line in lines {
println!(" {}", line);
}
println!("}}");
}

/// Creates an new `GlobalScheduler`.
/// Note: all the `Scheduler`s are expected to be initialized beforehand.
pub fn new(schedulers: Vec<Scheduler>, trace: WaveSignalTrace) -> Self {
Expand Down Expand Up @@ -206,15 +215,15 @@ impl GlobalScheduler {
if scheduler_group_traces.len() == 1 {
let traces = &scheduler_group_traces[0];
for (i, trace) in traces.iter().enumerate() {
if traces.len() > 1 {
println!("Trace {}:", i);
}
let lines: Vec<String> = trace
.iter()
.filter(|entry| !entry.is_idle)
.map(|entry| self.format_output_entry(entry, ctx))
.filter(|prot_application| !prot_application.is_idle)
.map(|entry| self.format_augmented_protocol_application(entry, ctx))
.collect();
println!("{}", lines.join("\n"));
if i > 0 {
println!();
}
Self::print_trace_block(i, &lines);
}
return;
}
Expand All @@ -236,26 +245,38 @@ impl GlobalScheduler {
let lines: Vec<String> = merged
.iter()
.filter(|entry| !entry.is_idle)
.map(|entry| self.format_output_entry(entry, ctx))
.map(|entry| self.format_augmented_protocol_application(entry, ctx))
.collect();
println!("{}", lines.join("\n"));
Self::print_trace_block(0, &lines);
}

/// Formats an `OutputEntry` into a display string
fn format_output_entry(
/// Formats an `AugmentedProtocolApplication` into a display string
fn format_augmented_protocol_application(
&self,
entry: &AugmentedProtocolApplication,
ctx: &GlobalContext,
) -> String {
if ctx.show_waveform_time {
let start_time = self.trace.format_time(entry.start_time_step, ctx.time_unit);
let end_time = self.trace.format_time(entry.end_time_step, ctx.time_unit);
format!(
"{} // [time: {} -> {}] (thread {})",
entry.protocol_application, start_time, end_time, entry.thread_id
)
} else {
entry.protocol_application.to_string()
match (ctx.show_waveform_time, ctx.show_thread_ids) {
(true, true) | (true, false) => {
let start_time = self.trace.format_time(entry.start_time_step, ctx.time_unit);
let end_time = self.trace.format_time(entry.end_time_step, ctx.time_unit);
if ctx.show_thread_ids {
format!(
"{}; // [time: {} -> {}] (thread {})",
entry.protocol_application, start_time, end_time, entry.thread_id
)
} else {
format!(
"{}; // [time: {} -> {}]",
entry.protocol_application, start_time, end_time
)
}
}
(false, true) => format!(
"{}; // (thread {})",
entry.protocol_application, entry.thread_id
),
(false, false) => format!("{};", entry.protocol_application),
}
}

Expand Down
16 changes: 6 additions & 10 deletions monitor/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,10 @@ struct Cli {
#[arg(long, value_name = "SHOW_START_END_WAVEFORM_TIME_FOR_EACH_TRANSACTION")]
show_waveform_time: bool,

/// If enabled, displays the thread ID corresponding to each inferred transaction
#[arg(long, value_name = "SHOW_THREAD_IDS")]
show_thread_ids: bool,

/// Specifies the time unit for displaying waveform times.
/// Can only be used with --show-waveform-time.
/// Valid options: fs, ps, ns, us, ms, s, auto
Expand Down Expand Up @@ -136,7 +140,7 @@ fn main() -> anyhow::Result<()> {
.collect();

// parse waveform
let trace = WaveSignalTrace::open(&cli.wave, &designs, &instances, cli.sample_posedge)
let trace = WaveSignalTrace::open(&cli.wave, &designs, &instances, cli.sample_posedge.clone())
.with_context(|| format!("failed to read waveform file {}", cli.wave))?;

// Support multiple structs & designs
Expand Down Expand Up @@ -167,15 +171,7 @@ fn main() -> anyhow::Result<()> {
let multiple_structs = dut_designs.len() > 1;

// Create a GlobalContext that is shared across all schedulers
let ctx = GlobalContext::new(
cli.wave,
0,
cli.display_hex,
cli.show_waveform_time,
time_unit,
cli.print_num_steps,
multiple_structs,
);
let ctx = GlobalContext::new(&cli, 0, time_unit, multiple_structs);

// Multi-struct mode: create a GlobalScheduler with one scheduler per design
let mut schedulers = vec![];
Expand Down
7 changes: 5 additions & 2 deletions monitor/tests/adders/add_d1.out
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
add(1, 2, 3)
add(4, 5, 9)
// trace 0
trace {
add(1, 2, 3);
add(4, 5, 9);
}
7 changes: 5 additions & 2 deletions monitor/tests/adders/add_d2.out
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
add(1, 2, 3)
add(4, 5, 9)
// trace 0
trace {
add(1, 2, 3);
add(4, 5, 9);
}
13 changes: 8 additions & 5 deletions monitor/tests/alus/alu_d1.out
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
add(1, 2, 3)
add(123, 245, 368)
sub(200, 200, 0)
and(100, 100, 100)
or(0, 230, 230)
// trace 0
trace {
add(1, 2, 3);
add(123, 245, 368);
sub(200, 200, 0);
and(100, 100, 100);
or(0, 230, 230);
}
13 changes: 8 additions & 5 deletions monitor/tests/alus/alu_d2.out
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
add(1, 2, 3)
add(123, 245, 368)
sub(200, 200, 0)
and(100, 100, 100)
or(0, 230, 230)
// trace 0
trace {
add(1, 2, 3);
add(123, 245, 368);
sub(200, 200, 0);
and(100, 100, 100);
or(0, 230, 230);
}
5 changes: 4 additions & 1 deletion monitor/tests/brave_new_world_francis/bit_truncation_fft.out
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
bit_truncation_fft(8386560, 2047)
// trace 0
trace {
bit_truncation_fft(8386560, 2047);
}
5 changes: 4 additions & 1 deletion monitor/tests/brave_new_world_francis/bit_truncation_sha.out
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
bit_truncation_sha(4398046511104, 68719476736)
// trace 0
trace {
bit_truncation_sha(4398046511104, 68719476736);
}
5 changes: 4 additions & 1 deletion monitor/tests/brave_new_world_francis/ftu_sha.out
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
failure_to_update_sha()
// trace 0
trace {
failure_to_update_sha();
}
5 changes: 4 additions & 1 deletion monitor/tests/brave_new_world_francis/signal_async.out
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
signal_async(6, 7)
// trace 0
trace {
signal_async(6, 7);
}
5 changes: 4 additions & 1 deletion monitor/tests/brave_new_world_francis/use_without_valid.out
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
use_without_valid(5, 5)
// trace 0
trace {
use_without_valid(5, 5);
}
15 changes: 9 additions & 6 deletions monitor/tests/fifo/fifo.out
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
reset()
push(3)
push(4)
idle()
pop(3)
pop(4)
// trace 0
trace {
reset();
push(3);
push(4);
idle();
pop(3);
pop(4);
}
15 changes: 9 additions & 6 deletions monitor/tests/fifo/push_pop_identity.out
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
reset()
push(2)
pop(2)
idle()
push(3)
pop(3)
// trace 0
trace {
reset();
push(2);
pop(2);
idle();
push(3);
pop(3);
}
Loading