Skip to content
Open
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
393 changes: 393 additions & 0 deletions pnpm-lock.yaml

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions understand-anything-plugin/packages/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
"tree-sitter-python": "^0.25.0",
"tree-sitter-ruby": "^0.23.1",
"tree-sitter-rust": "^0.24.0",
"tree-sitter-systemverilog": "^0.3.1",
"tree-sitter-typescript": "^0.23.2",
"web-tree-sitter": "^0.26.6",
"yaml": "^2.8.3",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,10 @@ describe("LanguageRegistry", () => {
});

describe("createDefault", () => {
it("registers all 40 built-in language configs", () => {
it("registers all 41 built-in language configs", () => {
const registry = LanguageRegistry.createDefault();
const all = registry.getAllLanguages();
expect(all.length).toBe(40);
expect(all.length).toBe(41);
});

it("maps all expected extensions", () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -609,10 +609,11 @@ describe("EnvParser edge cases", () => {
});

describe("registerAllParsers", () => {
it("registers all 12 parsers with a PluginRegistry", () => {
it("registers all 13 parsers with a PluginRegistry", () => {
const registry = new PluginRegistry();
registerAllParsers(registry);
expect(registry.getPlugins()).toHaveLength(12);
expect(registry.getPlugins()).toHaveLength(13);
expect(registry.getSupportedLanguages()).toContain("systemverilog");
expect(registry.getSupportedLanguages()).toContain("markdown");
expect(registry.getSupportedLanguages()).toContain("yaml");
expect(registry.getSupportedLanguages()).toContain("json");
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { describe, it, expect } from "vitest";
import { LanguageRegistry } from "../languages/language-registry.js";

describe("systemverilog language config", () => {
const reg = LanguageRegistry.createDefault();
it.each([
["rtl/fifo.sv", "systemverilog"],
["rtl/cpu.v", "systemverilog"],
["tb/types_pkg.svh", "systemverilog"],
["tb/defs.vh", "systemverilog"],
])("detects %s as %s", (path, id) => {
expect(reg.getForFile(path)?.id).toBe(id);
});

it("exposes HDL/UVM concepts", () => {
const cfg = reg.getForFile("x.sv");
expect(cfg?.displayName).toBe("SystemVerilog");
expect(cfg?.concepts).toContain("uvm");
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { describe, it, expect } from "vitest";
import { PluginRegistry } from "../plugins/registry.js";
import { registerAllParsers } from "../plugins/parsers/index.js";

describe("SystemVerilog AnalyzerPlugin", () => {
const reg = new PluginRegistry();
registerAllParsers(reg);

it("routes .sv files to the sv parser", () => {
expect(reg.getPluginForFile("rtl/alu.sv")?.name).toBe("systemverilog-parser");
});
it("routes .v files to the sv parser", () => {
expect(reg.getPluginForFile("rtl/cpu.v")?.name).toBe("systemverilog-parser");
});
it("emits module definitions and UVM classes", () => {
const a = reg.analyzeFile("tb/d.sv", "module top; endmodule\nclass d extends uvm_driver; endclass")!;
expect(a.definitions?.some((d) => d.kind === "module" && d.name === "top")).toBe(true);
expect(a.classes.some((c) => c.name === "d")).toBe(true);
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// alu — minimal ALU using dut_pkg::op_e
module alu #(parameter int W = 8) (
input logic clk,
input logic [W-1:0] a,
input logic [W-1:0] b,
output logic [W-1:0] y
);
import dut_pkg::*;
op_e op;

always_comb begin
unique case (op)
OP_ADD: y = a + b;
OP_SUB: y = a - b;
OP_AND: y = a & b;
OP_OR: y = a | b;
default: y = '0;
endcase
end
endmodule
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// arbiter — fixed-priority N-request arbiter
module arbiter #(parameter int N = 4) (
input logic clk,
input logic rst_n,
input logic [N-1:0] reqs,
output logic [N-1:0] grants
);
always_comb begin
grants = '0;
for (int i = 0; i < N; i++) begin
if (reqs[i]) begin
grants[i] = 1'b1;
break;
end
end
end
endmodule
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// dut_pkg — shared types for the demo DUT
package dut_pkg;
typedef enum logic [1:0] { OP_ADD, OP_SUB, OP_AND, OP_OR } op_e;
typedef struct packed {
logic [7:0] addr;
logic [7:0] data;
} bus_t;
parameter int BUS_WIDTH = 8;
endpackage
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// fifo — simple synchronous FIFO
module fifo #(parameter int W = 8, parameter int DEPTH = 16) (
input logic clk,
input logic rst_n,
input logic push,
input logic pop,
input logic [W-1:0] din,
output logic [W-1:0] dout,
output logic full,
output logic empty
);
logic [W-1:0] mem [0:DEPTH-1];
logic [$clog2(DEPTH):0] count;

assign full = (count == DEPTH);
assign empty = (count == 0);

always_ff @(posedge clk) begin
if (!rst_n) count <= '0;
else count <= count + (push & ~full) - (pop & ~empty);
end
endmodule
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// top — design top that instantiates the RTL submodules
module top #(parameter int W = 8) (
input logic clk,
input logic rst_n
);
import dut_pkg::*;

logic [W-1:0] a, b, y, din, dout;
logic [3:0] reqs, grants;
logic push, pop, full, empty;

alu #(.W(W)) u_alu (.clk(clk), .a(a), .b(b), .y(y));
fifo #(.W(W), .DEPTH(16)) u_fifo (.clk(clk), .rst_n(rst_n), .push(push),
.pop(pop), .din(din), .dout(dout),
.full(full), .empty(empty));
arbiter #(.N(4)) u_arbiter (.clk(clk), .rst_n(rst_n),
.reqs(reqs), .grants(grants));
endmodule
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// dut_agent — wraps driver + monitor + sequencer
class dut_agent extends uvm_agent;
`uvm_component_utils(dut_agent)

dut_driver drv;
dut_monitor mon;
dut_sequencer sqr;

function new(string name, uvm_component parent);
super.new(name, parent);
endfunction

function void build_phase(uvm_phase phase);
super.build_phase(phase);
drv = dut_driver::type_id::create("drv", this);
mon = dut_monitor::type_id::create("mon", this);
sqr = dut_sequencer::type_id::create("sqr", this);
endfunction

function void connect_phase(uvm_phase phase);
drv.seq_item_port.connect(sqr.seq_item_export);
endfunction
endclass
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// dut_base_test — base UVM test: builds the env and runs the sequence
class dut_base_test extends uvm_test;
`uvm_component_utils(dut_base_test)

dut_env env;

function new(string name = "dut_base_test", uvm_component parent = null);
super.new(name, parent);
endfunction

function void build_phase(uvm_phase phase);
super.build_phase(phase);
env = dut_env::type_id::create("env", this);
endfunction

task run_phase(uvm_phase phase);
dut_sequence seq;
phase.raise_objection(this);
seq = dut_sequence::type_id::create("seq");
seq.start(env.agt.sqr);
phase.drop_objection(this);
endtask
endclass
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// dut_driver — drives transactions onto the DUT interface
class dut_driver extends uvm_driver #(dut_seq_item);
`uvm_component_utils(dut_driver)

virtual dut_if vif;

function new(string name, uvm_component parent);
super.new(name, parent);
endfunction

task run_phase(uvm_phase phase);
forever begin
seq_item_port.get_next_item(req);
// drive req.data onto vif.cb ...
seq_item_port.item_done();
end
endtask
endclass
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// dut_env — top-level UVM environment (agent + scoreboard)
class dut_env extends uvm_env;
`uvm_component_utils(dut_env)

dut_agent agt;
dut_scoreboard sb;

function new(string name, uvm_component parent);
super.new(name, parent);
endfunction

function void build_phase(uvm_phase phase);
super.build_phase(phase);
agt = dut_agent::type_id::create("agt", this);
sb = dut_scoreboard::type_id::create("sb", this);
endfunction

function void connect_phase(uvm_phase phase);
agt.mon.ap.connect(sb.imp);
endfunction
endclass
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// dut_if — DUT interface with a clocking block
interface dut_if (input logic clk);
logic rst_n;
logic [7:0] data;
logic valid;
logic ready;

clocking cb @(posedge clk);
output data, valid;
input ready;
endclocking
endinterface
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// dut_monitor — samples the interface and publishes observed items
class dut_monitor extends uvm_monitor;
`uvm_component_utils(dut_monitor)

virtual dut_if vif;
uvm_analysis_port #(dut_seq_item) ap;

function new(string name, uvm_component parent);
super.new(name, parent);
ap = new("ap", this);
endfunction

task run_phase(uvm_phase phase);
// sample vif.cb, build dut_seq_item, ap.write(item) ...
endtask
endclass
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// dut_scoreboard — checks observed transactions against a reference model
class dut_scoreboard extends uvm_scoreboard;
`uvm_component_utils(dut_scoreboard)

uvm_analysis_imp #(dut_seq_item, dut_scoreboard) imp;

function new(string name, uvm_component parent);
super.new(name, parent);
imp = new("imp", this);
endfunction

function void write(dut_seq_item item);
// compare item against the reference model ...
endfunction
endclass
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// dut_seq_item — UVM transaction (sequence item)
class dut_seq_item extends uvm_sequence_item;
rand bit [7:0] addr;
rand bit [7:0] data;

`uvm_object_utils_begin(dut_seq_item)
`uvm_field_int(addr, UVM_ALL_ON)
`uvm_field_int(data, UVM_ALL_ON)
`uvm_object_utils_end

function new(string name = "dut_seq_item");
super.new(name);
endfunction
endclass
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// dut_sequence — produces a stream of transactions
class dut_sequence extends uvm_sequence #(dut_seq_item);
`uvm_object_utils(dut_sequence)

function new(string name = "dut_sequence");
super.new(name);
endfunction

task body();
dut_seq_item req;
repeat (8) begin
req = dut_seq_item::type_id::create("req");
start_item(req);
assert (req.randomize());
finish_item(req);
end
endtask
endclass
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// dut_sequencer — arbitrates sequences onto the driver
class dut_sequencer extends uvm_sequencer #(dut_seq_item);
`uvm_component_utils(dut_sequencer)

function new(string name, uvm_component parent);
super.new(name, parent);
endfunction
endclass
Loading