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
25 changes: 17 additions & 8 deletions bi/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,13 @@ use crate::signal_trace::*;
#[derive(Parser, Debug)]
#[command(version, about, long_about = None, disable_version_flag = true)]
struct Cli {
/// Path to a Protocol (.prot) file
#[arg(short, long, value_name = "PROTOCOLS_FILE")]
protocol: String,
#[arg(
short,
long,
value_name = "PROTOCOLS_FILE",
help = "One or several protocol files."
)]
protocol: Vec<String>,

/// Path to a waveform trace (.fst, .vcd, .ghw) file
#[arg(short, long, value_name = "WAVE_FILE")]
Expand Down Expand Up @@ -94,9 +98,9 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
let show_warnings = false;
let skip_static_step_fork_checks = false;
let mut d = DiagnosticHandler::new(ColorChoice::Auto, false, show_warnings, false);
let (st, protos) = frontend(cli.protocol, &mut d, skip_static_step_fork_checks)?;
let ast = frontend(&cli.protocol, &mut d, skip_static_step_fork_checks)?;

let designs = find_designs(&st, &protos);
let designs = find_designs(&ast);

// try to find instances that we care about
if cli.instances.is_empty() {
Expand Down Expand Up @@ -124,7 +128,12 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
let exclude_from_trace = if cli.include_idle {
FxHashSet::default()
} else {
FxHashSet::from_iter(protos.iter().filter(|p| p.is_idle).map(|p| p.name.clone()))
FxHashSet::from_iter(
ast.protos
.iter()
.filter(|p| p.is_idle)
.map(|p| p.name.clone()),
)
};

let bi_protos: Vec<Vec<_>> = instances
Expand All @@ -133,7 +142,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
designs[&inst.design]
.protocols
.iter()
.map(|(id, _)| protos[*id].clone())
.map(|(id, _)| ast.protos[*id].clone())
.collect()
})
.collect();
Expand All @@ -143,7 +152,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
.enumerate()
.zip(bi_protos.iter())
.map(|((inst_id, inst), protos)| {
BackwardsInterpreter::new(&st, protos, inst_id as u32, cli.include_in_progress)
BackwardsInterpreter::new(&ast.st, protos, inst_id as u32, cli.include_in_progress)
})
.collect();

Expand Down
42 changes: 19 additions & 23 deletions cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,19 @@ use std::path::Path;

use clap::*;
use protocols::backends::{PinAnnotation, to_verilog};
use protocols::frontend::ast::Protocol;
use protocols::frontend::ast::Ast;
use protocols::frontend::diagnostic::DiagnosticHandler;
use protocols::frontend::symbol::SymbolTable;
use protocols::{Value, frontend, transaction_frontend};

#[derive(Parser, Debug)]
struct Args {
#[arg(short, long, value_name = "PROTOCOLS_FILE")]
protocol: String,
#[arg(
short,
long,
value_name = "PROTOCOLS_FILE",
help = "One or several protocol files."
)]
protocol: Vec<String>,

#[command(subcommand)]
command: Option<Cmds>,
Expand Down Expand Up @@ -45,14 +49,10 @@ enum Cmds {
},
}

fn load_trace(
st: &SymbolTable,
protos: &[Protocol],
transactions: Option<&str>,
) -> Vec<(String, Vec<Value>)> {
fn load_trace(ast: &Ast, transactions: Option<&str>) -> Vec<(String, Vec<Value>)> {
if let Some(filename) = transactions {
let mut d = DiagnosticHandler::new(ColorChoice::Auto, false, true, false);
let traces = transaction_frontend(filename, st, protos, &mut d).unwrap();
let traces = transaction_frontend(filename, ast, &mut d).unwrap();
if !traces.is_empty() {
if traces.len() > 1 {
log::warn!("More than 1 trace in {filename}. Picking first one.");
Expand All @@ -67,14 +67,13 @@ fn load_trace(
}

fn make_verilog_tb(
st: &SymbolTable,
protos: &[Protocol],
ast: &Ast,
verilog_tb: String,
transactions: Option<String>,
vcd_out: Option<String>,
clock: Option<String>,
) {
let trace = load_trace(st, protos, transactions.as_deref());
let trace = load_trace(ast, transactions.as_deref());
let mut pins = vec![];
if let Some(clock) = clock {
pins.push((clock, PinAnnotation::Clock));
Expand All @@ -84,8 +83,7 @@ fn make_verilog_tb(
let tb_name = "tb";
to_verilog(
tb_name,
st,
protos,
ast,
&pins,
vcd_out.as_deref(),
&trace,
Expand All @@ -95,8 +93,7 @@ fn make_verilog_tb(
}

fn run_verilog_tb(
st: &SymbolTable,
protos: &[Protocol],
ast: &Ast,
run_dir: String,
transactions: Option<String>,
clock: Option<String>,
Expand Down Expand Up @@ -124,8 +121,7 @@ fn run_verilog_tb(
let verilog_tb_str = abs_cwd.join(verilog_tb).to_str().unwrap().to_string();
let vcd_out_rel = "dump.vcd";
make_verilog_tb(
st,
protos,
ast,
verilog_tb_str,
transactions,
Some(vcd_out_rel.to_string()),
Expand Down Expand Up @@ -178,12 +174,12 @@ fn main() {
// we always parse and type check the protocol file
let skip_static_step_fork_checks = false;
let mut d = DiagnosticHandler::new(ColorChoice::Auto, false, true, false);
let (st, protos) = frontend(args.protocol, &mut d, skip_static_step_fork_checks).unwrap();
let ast = frontend(&args.protocol, &mut d, skip_static_step_fork_checks).unwrap();

match args.command {
None => {}
Some(Cmds::Constructs) => {
for p in &protos {
for p in &ast.protos {
println!("{}: {}", p.name, p.used_constructs());
}
}
Expand All @@ -193,15 +189,15 @@ fn main() {
vcd_out,
clock,
}) => {
make_verilog_tb(&st, &protos, verilog_tb, transactions, vcd_out, clock);
make_verilog_tb(&ast, verilog_tb, transactions, vcd_out, clock);
}
Some(Cmds::RunVerilog {
run_dir,
transactions,
clock,
verilog,
}) => {
run_verilog_tb(&st, &protos, run_dir, transactions, clock, verilog);
run_verilog_tb(&ast, run_dir, transactions, clock, verilog);
}
}
}
19 changes: 19 additions & 0 deletions examples/wishbone/antmicro_litex.prot
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// Map common wishbone protocol pins to the Antmicro/Litex implementation

module LitexWishbone : Wishbone {
in clk : clock @posedge,
// "interesting" mappings
in reset : u1 = !Wishbone.RST,
in wishbone_adr : u30 = Wishbone.ADR[31:2] with Wishbone.ADR[1:0] == 2'b00,
// all other pins just map 1:1
out wishbone_dat_r : u32 = Wishbone.DAT_I,
in wishbone_dat_w : u32 = Wishbone.DAT_O,
in wishbone_cyc : u1 = Wishbone.CYC,
in wishbone_stb : u1 = Wishbone.STB,
out wishbone_ack : u1 = Wishbone.ACK,
in wishbone_we : u1 = Wishbone.WE,
in wishbone_sel : u4 = Wishbone.SEL,
in wishbone_cti : u3 = Wishbone.CTI,
in wishbone_bte : u2 = Wishbone.BTE,
out wishbone_err : u1 = Wishbone.ERR,
}
4 changes: 2 additions & 2 deletions examples/wishbone/wishbone.prot
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Wishbone pins for this project from the server (the one servicing requests) perspective
struct Wishbone {
interface Wishbone {
// high active RST pin (the wishbone spec requires all signals to be high active)
in RST: u1,
// acknowledge (from server)
Expand Down Expand Up @@ -28,7 +28,7 @@ struct Wishbone {
// 2: 8-beat wrap burst
// 3: 16-beat wrap burst
in BTE: u2,
// cycle type indentifier
// cycle type identifier
// 0: classic cycle
// 1: constant address burst cycle
// 2: incrementing burst cycle
Expand Down
29 changes: 17 additions & 12 deletions graph-interp/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use std::panic::{AssertUnwindSafe, catch_unwind};

use clap::Parser;
use protocols::ascii_waveform::print_ascii_waveform;
use protocols::frontend::ast::Protocol;
use protocols::frontend::ast::{Ast, Protocol};
use protocols::frontend::design::{Design, find_a_single_design};
use protocols::frontend::diagnostic::DiagnosticHandler;
use protocols::frontend::symbol::SymbolTable;
Expand All @@ -22,9 +22,13 @@ struct Cli {
#[arg(long, value_name = "VERILOG_FILES", value_delimiter = ' ', num_args = 1..)]
verilog: Vec<String>,

/// Path to a Protocol (.prot) file
#[arg(short, long, value_name = "PROTOCOLS_FILE")]
protocol: String,
#[arg(
short,
long,
value_name = "PROTOCOLS_FILE",
help = "One or several protocol files."
)]
protocol: Vec<String>,

/// Path to a Transactions (.tx) file
#[arg(short, long, value_name = "TRANSACTIONS_FILE")]
Expand Down Expand Up @@ -59,7 +63,7 @@ struct Cli {
ascii_waveform: bool,
}

fn load_protocols(cli: &Cli) -> (SymbolTable, Vec<Protocol>) {
fn load_protocols(cli: &Cli) -> Ast {
let mut handler = DiagnosticHandler::new(clap::ColorChoice::Never, false, true, false);
frontend(
&cli.protocol,
Expand All @@ -69,9 +73,9 @@ fn load_protocols(cli: &Cli) -> (SymbolTable, Vec<Protocol>) {
.unwrap()
}

fn load_traces(cli: &Cli, st: &SymbolTable, protos: &[Protocol]) -> Vec<Vec<(String, Vec<Value>)>> {
fn load_traces(cli: &Cli, ast: &Ast) -> Vec<Vec<(String, Vec<Value>)>> {
let mut handler = DiagnosticHandler::new(clap::ColorChoice::Never, false, true, false);
transaction_frontend(&cli.transactions, st, protos, &mut handler).unwrap()
transaction_frontend(&cli.transactions, ast, &mut handler).unwrap()
}

fn build_arg_map<'a>(
Expand Down Expand Up @@ -191,17 +195,18 @@ fn run_respect_forks(

fn main() {
let cli = Cli::parse();
let (st, protos) = load_protocols(&cli);
let traces = load_traces(&cli, &st, &protos);
let design = find_a_single_design(&st, &protos, &cli.protocol).unwrap();
let ast = load_protocols(&cli);
let st = &ast.st;
let traces = load_traces(&cli, &ast);
let design = find_a_single_design(&ast, &cli.protocol).unwrap();

let old_hook = std::panic::take_hook();
std::panic::set_hook(Box::new(|_| {}));
let result = catch_unwind(AssertUnwindSafe(|| {
if cli.respect_forks {
run_respect_forks(&cli, &st, &protos, &design, &traces);
run_respect_forks(&cli, st, &ast.protos, &design, &traces);
} else {
run_classic(&cli, &st, &protos, &design, traces);
run_classic(&cli, st, &ast.protos, &design, traces);
}
}));
std::panic::set_hook(old_hook);
Expand Down
31 changes: 17 additions & 14 deletions interp/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,13 @@ struct Cli {
#[arg(long, value_name = "VERILOG_FILES", value_delimiter = ' ', num_args = 1..)]
verilog: Vec<String>,

/// Path to a Protocol (.prot) file
#[arg(short, long, value_name = "PROTOCOLS_FILE")]
protocol: String,
#[arg(
short,
long,
value_name = "PROTOCOLS_FILE",
help = "One or several protocol files."
)]
protocol: Vec<String>,

/// Path to a Transactions (.tx) file
#[arg(short, long, value_name = "TRANSACTIONS_FILE")]
Expand Down Expand Up @@ -128,15 +132,15 @@ fn main() -> anyhow::Result<()> {
cli.display_hex,
);

let (st, protos) = match frontend(
let ast = match frontend(
&cli.protocol,
&mut protocols_handler,
cli.skip_static_step_fork_checks,
) {
Ok(result) => result,
Err(error) => exit_after_setup_error(error, !protocols_handler.error_string().is_empty()),
};
let design = find_a_single_design(&st, &protos, &cli.protocol)?;
let design = find_a_single_design(&ast, &cli.protocol)?;

// Create a separate `DiagnosticHandler` when parsing the transactions file
let mut transactions_handler = DiagnosticHandler::new(
Expand All @@ -145,13 +149,12 @@ fn main() -> anyhow::Result<()> {
emit_warnings,
cli.display_hex,
);
let traces =
match transaction_frontend(cli.transactions, &st, &protos, &mut transactions_handler) {
Ok(result) => result,
Err(error) => {
exit_after_setup_error(error, !transactions_handler.error_string().is_empty())
}
};
let traces = match transaction_frontend(cli.transactions, &ast, &mut transactions_handler) {
Ok(result) => result,
Err(error) => {
exit_after_setup_error(error, !transactions_handler.error_string().is_empty())
}
};

let mut any_failed = false;
for (trace_index, todos) in traces.into_iter().enumerate() {
Expand All @@ -169,8 +172,8 @@ fn main() -> anyhow::Result<()> {
)?;

let mut scheduler = Scheduler::new(
&st,
&protos,
&ast.st,
&ast.protos,
todos,
sim,
&mut protocols_handler,
Expand Down
Loading
Loading