Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Parsing UVM macros #92

Open
eddygta17 opened this issue Nov 15, 2023 · 4 comments
Open

Parsing UVM macros #92

eddygta17 opened this issue Nov 15, 2023 · 4 comments

Comments

@eddygta17
Copy link

eddygta17 commented Nov 15, 2023

typedef enum {FALSE, TRUE} e_bool;

class Child extends uvm_object;
  string 	 m_name;
  logic[3:0] m_age;
  
  `uvm_object_utils_begin(Child)
  	`uvm_field_string 	(m_name, UVM_ALL_ON)
  	`uvm_field_int 		(m_age, UVM_ALL_ON)
  `uvm_object_utils_end
  
  function new(string name="Child");
    super.new(name);
  endfunction
endclass

class Parent extends uvm_object;
  
  string 	m_name;
  bit[15:0]	m_age;
  int 		m_numbers[$];
  e_bool 	m_employed;
  Child 	m_child;
  
  `uvm_object_utils_begin(Parent)
  	`uvm_field_enum			(e_bool, m_employed, UVM_ALL_ON)
  	`uvm_field_int			(m_age, UVM_ALL_ON)
  	`uvm_field_queue_int 	(m_numbers, UVM_ALL_ON)
  	`uvm_field_string 		(m_name, UVM_ALL_ON)
  	`uvm_field_object 		(m_child, UVM_ALL_ON)
  `uvm_object_utils_end
  
  function new(string name="Parent");
    super.new(name);
  endfunction
  
endclass

module tb;
  initial begin
    Parent p = Parent::type_id::create("Parent");
    p.m_name = "Joey";
    p.m_employed = TRUE;
    p.m_age = 29;
    p.m_numbers = '{1234, 5678, 9011};
    p.m_child = new();
    p.m_child.m_name = "Joey Jr";
    p.m_child.m_age  = 1;
    
    p.print();
  end
endmodule

While parsing the following code, the UVM macros are not parsed as they are not defined in the same file.
Is there any workaround this?
Recognising it as a macro with the macro name as the Token would be enough I assume.

@DaveMcEwan
Copy link

Those UVM macros just need to be defined, usually at the top of the file like:

`include "uvm_macros.svh"

typedef enum {FALSE, TRUE} e_bool;

class Child extends uvm_object;
  string 	 m_name;
...

Just to clarify, and for future readers who come across this thread: UVM is not part of SystemVerilog - UVM is just a (widely used) library of classes and macros written in SystemVerilog. Therefore, UVM classes (like uvm_object) macros (like uvm_object_utils_begin) are not pre-defined in SystemVerilog parser (like this repo).

There is a related issue opened on svlint (dalance/svlint#269) and a PR has been opened (dalance/svlint#271). That will provide a workaround only for svlint, but not other tools based on sv-parser.

@eddygta17
Copy link
Author

use std::collections::HashMap;
use std::env;
use std::path::PathBuf;
use sv_parser::{parse_sv, unwrap_node, Locate, RefNode};

fn main() {
    let args: Vec<String> = env::args().collect();

    // The path of SystemVerilog source file
    let path = PathBuf::from(&args[1]);

    // The list of defined macros
    let defines = HashMap::new();
    // The list of include paths
    let includes: Vec<PathBuf> = vec![PathBuf::from(".\\uvm\\")];


    // Parse
    let result = parse_sv(&path, &defines, &includes, false, false);
}
  • I copied the UVM source into the build directory of the example that's given in the repository and tried building with the above code where I am passing UVM directory to the includes vector.
  • In the SV code the UVM macro and package statements were added.
`include "uvm_macros.svh"
import uvm_pkg::*;
typedef enum {FALSE, TRUE} e_bool;

class Child extends uvm_object;
  string 	 m_name;
  logic[3:0] m_age;
  
  // `uvm_object_utils_begin(Child)
  // 	`uvm_field_string 	(m_name, UVM_ALL_ON)
  // 	`uvm_field_int 		(m_age, UVM_ALL_ON)
  // `uvm_object_utils_end
  
  function new(string name="Child");
    super.new(name);
  endfunction
endclass

class Parent extends uvm_object;
  
  string 	m_name;
  bit[15:0]	m_age;
  int 		m_numbers[$];
  e_bool 	m_employed;
  Child 	m_child;
  
  // `uvm_object_utils_begin(Parent)
  // 	`uvm_field_enum			(e_bool, m_employed, UVM_ALL_ON)
  // 	`uvm_field_int			(m_age, UVM_ALL_ON)
  // 	`uvm_field_queue_int 	(m_numbers, UVM_ALL_ON)
  // 	`uvm_field_string 		(m_name, UVM_ALL_ON)
  // 	`uvm_field_object 		(m_child, UVM_ALL_ON)
  // `uvm_object_utils_end
  
  function new(string name="Parent");
    super.new(name);
  endfunction
  
endclass

module tb;
  initial begin
    Parent p = Parent::type_id::create("Parent");
    p.m_name = "Joey";
    p.m_employed = TRUE;
    p.m_age = 29;
    p.m_numbers = '{1234, 5678, 9011};
    p.m_child = new();
    p.m_child.m_name = "Joey Jr";
    p.m_child.m_age  = 1;
    
    p.print();
  end
endmodule
  • The above SV code is parsed without any errors.
  • But uncommenting uvm_object_utils macro usage results in an overflow.
thread 'main' has overflowed its stack
error: process didn't exit successfully: `target\debug\sv-test.exe .\test.sv` (exit code: 0xc00000fd, STATUS_STACK_OVERFLOW)

@eddygta17
Copy link
Author

Using a macro like:

`uvm_object_utils(Child)

The code is able to be parsed with this workaround. But the CST becomes a tad bit too long due to UVM being included.

@eddygta17
Copy link
Author

eddygta17 commented Dec 13, 2023

I was not able to recreate the stack overflow with the same conditions in an Ubuntu VM. It is still encountered in Windows.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants