Add benchmark
This commit is contained in:
parent
030068f36f
commit
5ebaa7017c
@ -23,3 +23,8 @@ sv-parser-syntaxtree = {version = "0.1.0", path = "../sv-parser-syntaxtree"}
|
|||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
structopt = "0.3.2"
|
structopt = "0.3.2"
|
||||||
|
criterion = "0.3"
|
||||||
|
|
||||||
|
[[bench]]
|
||||||
|
name = "parse_sv"
|
||||||
|
harness = false
|
||||||
|
52
sv-parser/benches/parse_sv.rs
Normal file
52
sv-parser/benches/parse_sv.rs
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
use criterion::{criterion_group, criterion_main, Criterion, Throughput};
|
||||||
|
use std::collections::HashMap;
|
||||||
|
use std::path::{Path, PathBuf};
|
||||||
|
use std::time::Duration;
|
||||||
|
use std::{env, fs};
|
||||||
|
use sv_parser::parse_sv;
|
||||||
|
|
||||||
|
fn get_path(s: &str) -> PathBuf {
|
||||||
|
PathBuf::from(format!(
|
||||||
|
"{}/testcases/{}",
|
||||||
|
env::var("CARGO_MANIFEST_DIR").unwrap(),
|
||||||
|
s
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_size(p: &Path) -> u64 {
|
||||||
|
let metadata = fs::metadata(p).unwrap();
|
||||||
|
metadata.len()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn gen_benchmark_group(c: &mut Criterion, s: &str) {
|
||||||
|
let defines = HashMap::new();
|
||||||
|
let includes: Vec<PathBuf> = Vec::new();
|
||||||
|
let path = get_path(s);
|
||||||
|
let size = get_size(&path);
|
||||||
|
let mut group = c.benchmark_group(s);
|
||||||
|
group.throughput(Throughput::Bytes(size));
|
||||||
|
group.bench_function(s, |b| {
|
||||||
|
b.iter_with_large_drop(|| parse_sv(&path, &defines, &includes))
|
||||||
|
});
|
||||||
|
group.finish();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn config() -> Criterion {
|
||||||
|
Criterion::default()
|
||||||
|
.sample_size(30)
|
||||||
|
.measurement_time(Duration::new(30, 0))
|
||||||
|
//Criterion::default().measurement_time(Duration::new(90, 0))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn criterion_benchmark(c: &mut Criterion) {
|
||||||
|
gen_benchmark_group(c, "test1.sv");
|
||||||
|
gen_benchmark_group(c, "test2.sv");
|
||||||
|
}
|
||||||
|
|
||||||
|
criterion_group! {
|
||||||
|
name = benches;
|
||||||
|
config = config();
|
||||||
|
targets = criterion_benchmark
|
||||||
|
}
|
||||||
|
|
||||||
|
criterion_main!(benches);
|
64
sv-parser/testcases/test1.sv
Normal file
64
sv-parser/testcases/test1.sv
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
module dimm(addr, ba, rasx, casx, csx, wex, cke, clk, dqm, data, dev_id);
|
||||||
|
parameter [31:0] MEM_WIDTH = 16, MEM_SIZE = 8; // in mbytes
|
||||||
|
input [10:0] addr;
|
||||||
|
input ba, rasx, casx, csx, wex, cke, clk;
|
||||||
|
input [ 7:0] dqm;
|
||||||
|
inout [63:0] data;
|
||||||
|
input [ 4:0] dev_id;
|
||||||
|
genvar i;
|
||||||
|
|
||||||
|
case ({MEM_SIZE, MEM_WIDTH})
|
||||||
|
{32'd8, 32'd16}: // 8Meg x 16 bits wide
|
||||||
|
begin: memory
|
||||||
|
for (i=0; i<4; i=i+1) begin:word16
|
||||||
|
sms_08b216t0 p(.clk(clk), .csb(csx), .cke(cke),.ba(ba),
|
||||||
|
.addr(addr), .rasb(rasx), .casb(casx),
|
||||||
|
.web(wex), .udqm(dqm[2*i+1]), .ldqm(dqm[2*i]),
|
||||||
|
.dqi(data[15+16*i:16*i]), .dev_id(dev_id));
|
||||||
|
// The hierarchical instance names are:
|
||||||
|
// memory.word16[3].p, memory.word16[2].p,
|
||||||
|
// memory.word16[1].p, memory.word16[0].p,
|
||||||
|
// and the task memory.read_mem
|
||||||
|
end
|
||||||
|
task read_mem;
|
||||||
|
input [31:0] address;
|
||||||
|
output [63:0] data;
|
||||||
|
begin // call read_mem in sms module
|
||||||
|
word16[3].p.read_mem(address, data[63:48]);
|
||||||
|
word16[2].p.read_mem(address, data[47:32]);
|
||||||
|
word16[1].p.read_mem(address, data[31:16]);
|
||||||
|
word16[0].p.read_mem(address, data[15: 0]);
|
||||||
|
end
|
||||||
|
endtask
|
||||||
|
end
|
||||||
|
{32'd16, 32'd8}: // 16Meg x 8 bits wide
|
||||||
|
begin: memory
|
||||||
|
for (i=0; i<8; i=i+1) begin:word8
|
||||||
|
sms_16b208t0 p(.clk(clk), .csb(csx), .cke(cke),.ba(ba),
|
||||||
|
.addr(addr), .rasb(rasx), .casb(casx),
|
||||||
|
.web(wex), .dqm(dqm[i]),
|
||||||
|
.dqi(data[7+8*i:8*i]), .dev_id(dev_id));
|
||||||
|
// The hierarchical instance names are
|
||||||
|
// memory.word8[7].p, memory.word8[6].p,
|
||||||
|
// ...
|
||||||
|
// memory.word8[1].p, memory.word8[0].p,
|
||||||
|
// and the task memory.read_mem
|
||||||
|
end
|
||||||
|
task read_mem;
|
||||||
|
input [31:0] address;
|
||||||
|
output [63:0] data;
|
||||||
|
begin // call read_mem in sms module
|
||||||
|
word8[7].p.read_mem(address, data[63:56]);
|
||||||
|
word8[6].p.read_mem(address, data[55:48]);
|
||||||
|
word8[5].p.read_mem(address, data[47:40]);
|
||||||
|
word8[4].p.read_mem(address, data[39:32]);
|
||||||
|
word8[3].p.read_mem(address, data[31:24]);
|
||||||
|
word8[2].p.read_mem(address, data[23:16]);
|
||||||
|
word8[1].p.read_mem(address, data[15: 8]);
|
||||||
|
word8[0].p.read_mem(address, data[ 7: 0]);
|
||||||
|
end
|
||||||
|
endtask
|
||||||
|
end
|
||||||
|
// Other memory cases ...
|
||||||
|
endcase
|
||||||
|
endmodule
|
104
sv-parser/testcases/test2.sv
Normal file
104
sv-parser/testcases/test2.sv
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
interface simple_bus (input logic clk); // Define the interface
|
||||||
|
logic req, gnt;
|
||||||
|
logic [7:0] addr, data;
|
||||||
|
logic [1:0] mode;
|
||||||
|
logic start, rdy;
|
||||||
|
int slaves = 0;
|
||||||
|
|
||||||
|
// tasks executed concurrently as a fork-join block
|
||||||
|
extern forkjoin task countSlaves();
|
||||||
|
extern forkjoin task Read (input logic [7:0] raddr);
|
||||||
|
extern forkjoin task Write (input logic [7:0] waddr);
|
||||||
|
|
||||||
|
modport slave (input req,addr, mode, start, clk,
|
||||||
|
output gnt, rdy,
|
||||||
|
ref data, slaves,
|
||||||
|
export Read, Write, countSlaves);
|
||||||
|
// export from module that uses the modport
|
||||||
|
|
||||||
|
modport master ( input gnt, rdy, clk,
|
||||||
|
output req, addr, mode, start,
|
||||||
|
ref data,
|
||||||
|
import task Read(input logic [7:0] raddr),
|
||||||
|
task Write(input logic [7:0] waddr));
|
||||||
|
// import requires the full task prototype
|
||||||
|
|
||||||
|
initial begin
|
||||||
|
slaves = 0;
|
||||||
|
countSlaves;
|
||||||
|
$display ("number of slaves = %d", slaves);
|
||||||
|
end
|
||||||
|
endinterface: simple_bus
|
||||||
|
|
||||||
|
module memMod #(parameter int minaddr=0, maxaddr=0) (interface a);
|
||||||
|
logic avail = 1;
|
||||||
|
logic [7:0] mem[255:0];
|
||||||
|
|
||||||
|
task a.countSlaves();
|
||||||
|
a.slaves++;
|
||||||
|
endtask
|
||||||
|
|
||||||
|
task a.Read(input logic [7:0] raddr); // Read method
|
||||||
|
if (raddr >= minaddr && raddr <= maxaddr) begin
|
||||||
|
avail = 0;
|
||||||
|
#10 a.data = mem[raddr];
|
||||||
|
avail = 1;
|
||||||
|
end
|
||||||
|
endtask
|
||||||
|
|
||||||
|
task a.Write(input logic [7:0] waddr); // Write method
|
||||||
|
if (waddr >= minaddr && waddr <= maxaddr) begin
|
||||||
|
avail = 0;
|
||||||
|
#10 mem[waddr] = a.data;
|
||||||
|
avail = 1;
|
||||||
|
end
|
||||||
|
endtask
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module cpuMod(interface b);
|
||||||
|
typedef enum {read, write} instr;
|
||||||
|
instr inst;
|
||||||
|
logic [7:0] raddr;
|
||||||
|
integer seed;
|
||||||
|
|
||||||
|
always @(posedge b.clk) begin
|
||||||
|
inst = instr'($dist_uniform(seed, 0, 1));
|
||||||
|
raddr = $dist_uniform(seed, 0, 3);
|
||||||
|
if (inst == read) begin
|
||||||
|
$display("%t begin read %h @ %h", $time, b.data, raddr);
|
||||||
|
callr:b.Read(raddr);
|
||||||
|
$display("%t end read %h @ %h", $time, b.data, raddr);
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
$display("%t begin write %h @ %h", $time, b.data, raddr);
|
||||||
|
b.data = raddr;
|
||||||
|
callw:b.Write(raddr);
|
||||||
|
$display("%t end write %h @ %h", $time, b.data, raddr);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module top;
|
||||||
|
logic clk = 0;
|
||||||
|
|
||||||
|
function void interrupt();
|
||||||
|
disable mem1.a.Read; // task via module instance
|
||||||
|
disable sb_intf.Write; // task via interface instance
|
||||||
|
if (mem1.avail == 0) $display ("mem1 was interrupted");
|
||||||
|
if (mem2.avail == 0) $display ("mem2 was interrupted");
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
always #5 clk++;
|
||||||
|
|
||||||
|
initial begin
|
||||||
|
#28 interrupt();
|
||||||
|
#10 interrupt();
|
||||||
|
#100 $finish;
|
||||||
|
end
|
||||||
|
|
||||||
|
simple_bus sb_intf(clk);
|
||||||
|
|
||||||
|
memMod #(0, 127) mem1(sb_intf.slave);
|
||||||
|
memMod #(128, 255) mem2(sb_intf.slave);
|
||||||
|
cpuMod cpu(sb_intf.master);
|
||||||
|
endmodule
|
Loading…
x
Reference in New Issue
Block a user