用Python写一个比较全面的UVM生成脚本
时间: 2023-10-07 11:08:27 浏览: 247
pyuvm:用Python编写的UVM
UVM是一种用于验证硬件设计的框架,可以帮助验证工程师实现可重用、可扩展和模块化的验证环境。下面是一个用Python编写的比较全面的UVM生成脚本:
```python
import os
class UVMGenerator:
def __init__(self, module_name):
self.module_name = module_name
self.top_env_name = f"{module_name}_top_env"
self.config_db_name = f"{module_name}_config_db"
self.base_test_name = f"{module_name}_base_test"
self.env_name = f"{module_name}_env"
self.agent_name = f"{module_name}_agent"
self.driver_name = f"{module_name}_driver"
self.monitor_name = f"{module_name}_monitor"
self.scoreboard_name = f"{module_name}_scoreboard"
self.sequencer_name = f"{module_name}_sequencer"
self.virtual_seq_name = f"{module_name}_virtual_seq"
self.main_seq_name = f"{module_name}_main_seq"
self.test_name = f"{module_name}_test"
self.tb_name = f"{module_name}_tb"
self.output_dir = f"./{module_name}_uvm"
def generate(self):
# Create the output directory if it doesn't exist
if not os.path.exists(self.output_dir):
os.mkdir(self.output_dir)
# Generate the files
self.generate_top_env()
self.generate_config_db()
self.generate_base_test()
self.generate_env()
self.generate_agent()
self.generate_driver()
self.generate_monitor()
self.generate_scoreboard()
self.generate_sequencer()
self.generate_virtual_seq()
self.generate_main_seq()
self.generate_test()
self.generate_tb()
print(f"UVM code generated successfully in {self.output_dir} directory.")
def generate_top_env(self):
top_env_file = os.path.join(self.output_dir, f"{self.top_env_name}.sv")
with open(top_env_file, "w") as f:
f.write(f"""
class {self.top_env_name} extends uvm_env;
{self.config_db_name} config_db;
{self.base_test_name} base_test;
{self.env_name} env;
function new(string name = "{self.top_env_name}", uvm_component parent);
super.new(name, parent);
endfunction : new
function void build_phase(uvm_phase phase);
super.build_phase(phase);
config_db = {self.config_db_name}::type_id::create("config_db", this);
base_test = {self.base_test_name}::type_id::create("base_test", this);
env = {self.env_name}::type_id::create("env", this);
endfunction : build_phase
function void connect_phase(uvm_phase phase);
super.connect_phase(phase);
base_test.env_port.connect(env.agent_port);
endfunction : connect_phase
endclass : {self.top_env_name}
""")
def generate_config_db(self):
config_db_file = os.path.join(self.output_dir, f"{self.config_db_name}.sv")
with open(config_db_file, "w") as f:
f.write(f"""
class {self.config_db_name} extends uvm_component;
`uvm_component_utils({self.config_db_name})
// TODO: Add configuration parameters here
endclass : {self.config_db_name}
""")
def generate_base_test(self):
base_test_file = os.path.join(self.output_dir, f"{self.base_test_name}.sv")
with open(base_test_file, "w") as f:
f.write(f"""
class {self.base_test_name} extends uvm_test;
{self.env_name} env;
function new(string name = "{self.base_test_name}", uvm_component parent);
super.new(name, parent);
endfunction : new
virtual function void build_phase(uvm_phase phase);
super.build_phase(phase);
env = get_top().env;
endfunction : build_phase
endclass : {self.base_test_name}
""")
def generate_env(self):
env_file = os.path.join(self.output_dir, f"{self.env_name}.sv")
with open(env_file, "w") as f:
f.write(f"""
class {self.env_name} extends uvm_env;
{self.agent_name} agent;
function new(string name = "{self.env_name}", uvm_component parent);
super.new(name, parent);
endfunction : new
function void build_phase(uvm_phase phase);
super.build_phase(phase);
agent = {self.agent_name}::type_id::create("agent", this);
endfunction : build_phase
endclass : {self.env_name}
""")
def generate_agent(self):
agent_file = os.path.join(self.output_dir, f"{self.agent_name}.sv")
with open(agent_file, "w") as f:
f.write(f"""
class {self.agent_name} extends uvm_agent;
{self.driver_name} driver;
{self.monitor_name} monitor;
{self.scoreboard_name} scoreboard;
{self.sequencer_name} sequencer;
function new(string name = "{self.agent_name}", uvm_component parent);
super.new(name, parent);
endfunction : new
function void build_phase(uvm_phase phase);
super.build_phase(phase);
driver = {self.driver_name}::type_id::create("driver", this);
monitor = {self.monitor_name}::type_id::create("monitor", this);
scoreboard = {self.scoreboard_name}::type_id::create("scoreboard", this);
sequencer = {self.sequencer_name}::type_id::create("sequencer", this);
endfunction : build_phase
endclass : {self.agent_name}
""")
def generate_driver(self):
driver_file = os.path.join(self.output_dir, f"{self.driver_name}.sv")
with open(driver_file, "w") as f:
f.write(f"""
class {self.driver_name} extends uvm_driver;
// TODO: Add driver code here
endclass : {self.driver_name}
""")
def generate_monitor(self):
monitor_file = os.path.join(self.output_dir, f"{self.monitor_name}.sv")
with open(monitor_file, "w") as f:
f.write(f"""
class {self.monitor_name} extends uvm_monitor;
// TODO: Add monitor code here
endclass : {self.monitor_name}
""")
def generate_scoreboard(self):
scoreboard_file = os.path.join(self.output_dir, f"{self.scoreboard_name}.sv")
with open(scoreboard_file, "w") as f:
f.write(f"""
class {self.scoreboard_name} extends uvm_scoreboard;
// TODO: Add scoreboard code here
endclass : {self.scoreboard_name}
""")
def generate_sequencer(self):
sequencer_file = os.path.join(self.output_dir, f"{self.sequencer_name}.sv")
with open(sequencer_file, "w") as f:
f.write(f"""
class {self.sequencer_name} extends uvm_sequencer;
// TODO: Add sequencer code here
endclass : {self.sequencer_name}
""")
def generate_virtual_seq(self):
virtual_seq_file = os.path.join(self.output_dir, f"{self.virtual_seq_name}.sv")
with open(virtual_seq_file, "w") as f:
f.write(f"""
class {self.virtual_seq_name} extends uvm_sequence;
// TODO: Add virtual sequence code here
endclass : {self.virtual_seq_name}
""")
def generate_main_seq(self):
main_seq_file = os.path.join(self.output_dir, f"{self.main_seq_name}.sv")
with open(main_seq_file, "w") as f:
f.write(f"""
class {self.main_seq_name} extends uvm_sequence;
{self.sequencer_name} sequencer;
{self.virtual_seq_name} virtual_seq;
function new(string name = "{self.main_seq_name}");
super.new(name);
endfunction : new
virtual task body();
`uvm_info(get_type_name(), "Starting main sequence", UVM_MEDIUM)
virtual_seq = {self.virtual_seq_name}::type_id::create("virtual_seq");
sequencer = get_sequencer_by_type({self.sequencer_name}::type_id::get());
seq_item_port.write(virtual_seq);
endtask : body
endclass : {self.main_seq_name}
""")
def generate_test(self):
test_file = os.path.join(self.output_dir, f"{self.test_name}.sv")
with open(test_file, "w") as f:
f.write(f"""
class {self.test_name} extends {self.base_test_name};
{self.main_seq_name} main_seq;
function new(string name = "{self.test_name}", uvm_component parent);
super.new(name, parent);
endfunction : new
virtual function void build_phase(uvm_phase phase);
super.build_phase(phase);
main_seq = {self.main_seq_name}::type_id::create("main_seq");
endfunction : build_phase
endclass : {self.test_name}
""")
def generate_tb(self):
tb_file = os.path.join(self.output_dir, f"{self.tb_name}.sv")
with open(tb_file, "w") as f:
f.write(f"""
module {self.tb_name};
{self.top_env_name} top_env;
{self.test_name} test;
initial begin
uvm_config_db#(int)::set(null, "*", "is_running", 1);
uvm_config_db#(string)::set(null, "*", "run_time", $sformatf("%t", $time));
uvm_config_db#(string)::set(null, "*", "test_name", "{self.test_name}");
run_test();
end
task run_test();
uvm_config_db#(int)::set(null, "*", "seed", 1);
uvm_config_db#(string)::set(null, "*", "output", "uvm_test_output.txt");
uvm_config_db#(string)::set(null, "*", "verbosity", "UVM_MEDIUM");
top_env = {self.top_env_name}::type_id::create("top_env");
test = {self.test_name}::type_id::create("test");
run_test(test);
endtask : run_test
endmodule : {self.tb_name}
""")
# Example usage:
uvm_generator = UVMGenerator("my_module")
uvm_generator.generate()
```
上面的代码可以生成一个包含UVM环境中所有组件的文件,并且还包括一个测试台文件和一个顶层模块文件。你可以根据自己的需要修改生成代码。
阅读全文