Skip to content

Commit

Permalink
Adds json output for coverage report
Browse files Browse the repository at this point in the history
  • Loading branch information
chaseruskin committed Jul 17, 2024
1 parent b8e977a commit 7f5caae
Show file tree
Hide file tree
Showing 15 changed files with 311 additions and 104 deletions.
2 changes: 1 addition & 1 deletion .orbit/gverb.py
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@
.arg("--loop-limit="+str(MAX_TESTS) if MAX_TESTS != None else None) \
.arg("--dut").arg(dut_data) \
.arg("--tb").arg(tb_data) \
.args(['-g ' + item.to_str() for item in GENERICS]) \
.args(['-g=' + item.to_str() for item in GENERICS]) \
.arg("python") \
.arg("--") \
.arg(py_model) \
Expand Down
1 change: 0 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ Any of the components may have one or more implementations; install the componen
If you are using Linux or macOS, you can install all the components (using `pip`, `orbit`, and `cargo`):
```
curl --proto '=https' --tlsv1.2 -sSf https://github.com/cdotrus/verb/trunk/install.sh | bash -s --
```

## Details
Expand Down
14 changes: 7 additions & 7 deletions examples/add/add_tb.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,9 @@ def eval(self):
self.cout.data = temp[self.width]
return self

def force_carry_out(*p: Signal):
in0 = random.randint(1, p[0].max())
return (in0, p[1].max() + 1 - in0)
def force_carry_out(in0: Signal, in1: Signal):
in0 = random.randint(1, in0.max())
return (in0, in1.max() + 1 - in0)

pass

Expand Down Expand Up @@ -103,16 +103,16 @@ def force_carry_out(*p: Signal):
CoverPoint("in0 and in1 equal 0") \
.goal(1) \
.target(add.in0, add.in1) \
.def_advance(lambda p: (p[0].min(), p[1].min())) \
.def_cover(lambda p: int(p[0]) == 0 and int(p[1]) == 0) \
.def_advance(lambda in0, in1: (in0.min(), in1.min())) \
.def_cover(lambda in0, in1: int(in0) == 0 and int(in1) == 0) \
.apply()

# Check to make sure both inputs are the maximum value at the same time at least once.
CoverPoint("in0 and in1 equal max") \
.goal(1) \
.target(add.in0, add.in1) \
.def_advance(lambda p: (p[0].max(), p[1].max())) \
.def_cover(lambda p: int(p[0]) == p[0].max() and int(p[1]) == p[1].max()) \
.def_advance(lambda in0, in1: (in0.max(), in1.max())) \
.def_cover(lambda in0, in1: int(in0) == in0.max() and int(in1) == in1.max()) \
.apply()

# Cover the case that the carry out is generated at least 10 times.
Expand Down
1 change: 0 additions & 1 deletion src/bin/verb/src/error.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

pub type AnyError = Box<dyn std::error::Error>;

type LastError = String;
Expand Down
6 changes: 2 additions & 4 deletions src/bin/verb/src/events/comment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@ pub struct Comment {

impl From<String> for Comment {
fn from(value: String) -> Self {
Self {
inner: value
}
Self { inner: value }
}
}
}
30 changes: 15 additions & 15 deletions src/bin/verb/src/events/mod.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
use std::{path::PathBuf, str::FromStr};

use timestamp::Timestamp;
use comment::Comment;
use severity::Severity;
use timestamp::Timestamp;
use topic::Topic;
use comment::Comment;

use crate::error::{AnyError, Error};

pub mod timestamp;
pub mod comment;
pub mod severity;
pub mod timestamp;
pub mod topic;
pub mod comment;

#[derive(Debug, PartialEq)]
pub struct Events {
Expand Down Expand Up @@ -52,9 +52,7 @@ impl FromStr for Events {
while let Some(raw_e) = raw_events.next() {
events.push(Event::from_str(raw_e)?);
}
Ok(Self {
inner: events,
})
Ok(Self { inner: events })
}
}

Expand Down Expand Up @@ -108,19 +106,21 @@ impl FromStr for Event {
}
}


#[cfg(test)]
mod tests {
use super::*;

#[test]
fn from_str() {
let ev = "180000000fs INFO ASSERT_EQ sum receives 0110 and expects 0110";
assert_eq!(Event::from_str(ev).unwrap(), Event {
timestamp: Timestamp::with("180000000", "fs"),
severity: Severity::Info,
topic: Topic::from("ASSERT_EQ".to_string()),
comment: Comment::from("sum receives 0110 and expects 0110".to_string()),
})
assert_eq!(
Event::from_str(ev).unwrap(),
Event {
timestamp: Timestamp::with("180000000", "fs"),
severity: Severity::Info,
topic: Topic::from("ASSERT_EQ".to_string()),
comment: Comment::from("sum receives 0110 and expects 0110".to_string()),
}
)
}
}
}
4 changes: 2 additions & 2 deletions src/bin/verb/src/events/severity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ impl FromStr for Severity {
"WARN" => Ok(Self::Warn),
"ERROR" => Ok(Self::Error),
"FATAL" => Ok(Self::Fatal),
_ => Err(Error::UnknownSeverity(s.to_string()))
_ => Err(Error::UnknownSeverity(s.to_string())),
}
}
}
}
5 changes: 2 additions & 3 deletions src/bin/verb/src/events/timestamp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,8 @@ impl FromStr for Timestamp {
time: time.to_string(),
units: unit.to_string(),
})
},
None => return Err(Error::MissingTimeUnits)
}
None => return Err(Error::MissingTimeUnits),
}
}
}

6 changes: 2 additions & 4 deletions src/bin/verb/src/events/topic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@ pub struct Topic {

impl From<String> for Topic {
fn from(value: String) -> Self {
Self {
inner: value
}
Self { inner: value }
}
}
}
2 changes: 1 addition & 1 deletion src/bin/verb/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
pub mod error;
pub mod events;
pub mod generic;
pub mod ops;
pub mod unit;
pub mod verb;
pub mod events;
19 changes: 11 additions & 8 deletions src/bin/verb/src/ops/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ impl Subcommand<()> for Check {
}

fn execute(self, _c: &()) -> proc::Result {

let events = Events::load(&self.events)?;

let mut total_points: Option<usize> = None;
Expand All @@ -34,8 +33,8 @@ impl Subcommand<()> for Check {
// find the coverage lines
let stats = data.split_terminator('\n');
for s in stats {
let is_total_points = s.starts_with("Total points:");
let is_points_covered = s.starts_with("Points covered:");
let is_total_points = s.starts_with("Points:");
let is_points_covered = s.starts_with("Count:");
if is_total_points == true || is_points_covered == true {
let (_name, value) = s.split_once(':').unwrap();
let value = value.trim();
Expand All @@ -49,7 +48,11 @@ impl Subcommand<()> for Check {
}

if self.stats == true {
println!("info: simulation score: {}/{}", events.count_normal(), events.len());
println!(
"info: simulation score: {}/{}",
events.count_normal(),
events.len()
);
}

// check coverage
Expand All @@ -59,7 +62,7 @@ impl Subcommand<()> for Check {
if self.stats == true {
println!("info: coverage score: {}/{}", pc, tp);
}
match tp == pc {
match pc >= tp {
true => (),
false => return Err(Error::FailedCoverage(tp - pc))?,
}
Expand All @@ -73,15 +76,15 @@ impl Subcommand<()> for Check {
}

const HELP: &str = "\
Analyze the simulation's results.
Analyze the output of a hardware simulation.
Usage:
verb check [options] <events>
Args:
<events> file system path to the events log
<events> path to locate the simulation's events log
--stats display summary statistics
Options:
--coverage <file> path to read coverage report
--coverage <file> path to locate the model's coverage report
";
13 changes: 6 additions & 7 deletions src/bin/verb/src/ops/link.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,11 @@ pub struct Link {
bfm: bool,
send: bool,
comp: bool,
// use an 'exclude' list to ignore ports in the bfm
exclude: Vec<String>,
list: bool,
}

// use an 'exclude' list to ignore ports in the bfm

impl Subcommand<()> for Link {
fn interpret(cli: &mut Cli<Memory>) -> cli::Result<Self> {
cli.help(Help::with(HELP))?;
Expand Down Expand Up @@ -91,18 +90,18 @@ impl Subcommand<()> for Link {
}

const HELP: &str = "\
Generate code snippets for hw/sw synchronization.
Generate code snippets for hw/sw coherency.
Usage:
verb link [options] <json>
Args:
<json> hw unit's interface encoded in json format
<json> hw unit's interface encoded in json format
Options:
--bfm print the hw bus functional model interface
--send print the hw function to send inputs to the dut
--comp print the hw function to compare outputs from the dut
--bfm display the hw bus functional model interface
--send display the hw function to send inputs to the dut
--comp display the hw function to compare outputs from the dut
--exclude, -x omit specific ports from the code snippets
--list list the port order and exit
";
Expand Down
34 changes: 17 additions & 17 deletions src/bin/verb/src/ops/model.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,16 +23,16 @@ impl Subcommand<()> for Model {
fn interpret(cli: &mut Cli<Memory>) -> cli::Result<Self> {
cli.help(Help::with(HELP))?;
Ok(Self {
loop_limit: cli.get(Arg::option("loop-limit"))?,
rand_seed: cli.get(Arg::option("seed"))?,
coverage: cli.get(Arg::option("coverage"))?,
dir: cli.get(Arg::option("directory").switch('C'))?,
loop_limit: cli.get(Arg::option("loop-limit").value("num"))?,
rand_seed: cli.get(Arg::option("seed").value("num"))?,
coverage: cli.get(Arg::option("coverage").value("file"))?,
dir: cli.get(Arg::option("directory").switch('C').value("dir"))?,
generics: cli
.get_all(Arg::option("generic").switch('g'))?
.get_all(Arg::option("generic").switch('g').value("key=value"))?
.unwrap_or_default(),
dut: cli.require(Arg::option("dut"))?,
tb: cli.require(Arg::option("tb"))?,
model: cli.require(Arg::positional("model"))?,
dut: cli.require(Arg::option("dut").value("json"))?,
tb: cli.require(Arg::option("tb").value("json"))?,
model: cli.require(Arg::positional("command"))?,
model_args: cli.remainder()?,
})
}
Expand Down Expand Up @@ -103,21 +103,21 @@ impl Subcommand<()> for Model {
}

const HELP: &str = "\
Run the software script for a design's model.
Run a design's software model.
Usage:
verb model [options] --dut <json> --tb <json> <command> [--] [args]...
Args:
<command> file system path used to execute the model
--dut <json> design-under-test's interface encoded in json format
--tb <json> testbench's interface encoded in json format
<command> the command to execute the model
--dut <json> hw design-under-test's interface encoded in json format
--tb <json> hw testbench's interface encoded in json format
Options:
--generic, -g <key=value> override a testbench generic
--seed <num> set the random number generator seed
--coverage <file> path to write coverage report
--loop-limit <num> set the maximum number of iterations when using CDTG
--directory, -C change the working directory where the model will run
args arguments to pass to the model's command
--seed <num> the randomness seed
--coverage <file> destination for the coverage report
--loop-limit <num> the max number of main loop iterations
--directory, -C <dir> the directory where the model will run
args arguments to pass to the model's command
";
6 changes: 3 additions & 3 deletions src/bin/verb/src/verb.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,9 +72,9 @@ Usage:
Commands:
link generate code snippets for hw/sw coherency
model run the software script for a design's model
check analyze the output from a hardware simulation
model run a design's software model
check analyze the output of a hardware simulation
Options:
--version print the version information and exit
--help, -h print this help information and exit
Expand Down
Loading

0 comments on commit 7f5caae

Please sign in to comment.