Skip to content
Open
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
147 changes: 146 additions & 1 deletion template/python/dut.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,34 +52,101 @@ def __del__(self):
# User APIs #
################################
def InitClock(self, name: str):
"""
Initialize the clock, bind the 'XClock' in the DUT to the corresponding pin

Args:
name(str): the name of 'XClock'
"""
self.xclock.Add(self.xport[name])

def Step(self, i:int = 1):
"""
Push the timing circuit by i clock cycles.

Args:
i(int): Push by i clock cycles(Default is 1)
"""
self.xclock.Step(i)

def StepRis(self, callback, args=(), kwargs={}):
"""
Set a callback function triggered on the rising edge

The callback function will be called every time the clock rises

Args:
callback: the callback function triggered on the rising edge
args: the args of the callback function
kwargs: the keyword args of the callback function
"""
self.xclock.StepRis(callback, args, kwargs)

def StepFal(self, callback, args=(), kwargs={}):
"""
Set a callback function triggered on the falling edge

The callback function will be called every time the clock falls

Args:
callback: the callback function triggered on the falling edge
args: the args of the callback function
kwargs: the keyword args of the callback function
"""
self.xclock.StepFal(callback, args, kwargs)

def ResumeWaveformDump(self):
"""
Restart waveform export and return 1

Returns:
bool: return 1 when restart successfully
"""
return self.dut.ResumeWaveformDump()

def PauseWaveformDump(self):
"""
Pause waveform export and return 1

Returns:
bool: return 1 when pause successfully
"""
return self.dut.PauseWaveformDump()

def WaveformPaused(self) -> int:
""" Returns 1 if waveform export is paused """
"""
Check if the waveform export has been paused

Returns:
bool: return 1 if waveform export is paused
"""
return self.dut.WaveformPaused()

def GetXPort(self):
"""
Get the information of XPort

Returns:
XPort: the XPort of dut
Copy link

Copilot AI Sep 25, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are trailing spaces after 'dut' in the return type description.

Suggested change
XPort: the XPort of dut
XPort: the XPort of dut

Copilot uses AI. Check for mistakes.
"""
return self.xport

def GetXClock(self):
"""
Get the information of XClock

Returns:
XClock: the XClock of dut
Copy link

Copilot AI Sep 25, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is a trailing space after 'dut' in the return type description.

Suggested change
XClock: the XClock of dut
XClock: the XClock of dut

Copilot uses AI. Check for mistakes.
"""
return self.xclock

def SetWaveform(self, filename: str):
"""
Specify the output file for waveform

Args:
filename(str):the name of file
Copy link

Copilot AI Sep 25, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing space after colon and trailing spaces after 'file' in the parameter description.

Copilot uses AI. Check for mistakes.
"""
self.dut.SetWaveform(filename)

def GetWaveFormat(self) -> str:
Expand All @@ -92,9 +159,18 @@ def GetWaveFormat(self) -> str:
return self.dut.GetWaveFormat()

def FlushWaveform(self):
"""
Flush waveform to the file
"""
self.dut.FlushWaveform()

def SetCoverage(self, filename: str):
"""
Specify the output file for coverage

Args:
filename(str):the name of file
Copy link

Copilot AI Sep 25, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing space after colon and trailing spaces after 'file' in the parameter description.

Copilot uses AI. Check for mistakes.
"""
self.dut.SetCoverage(filename)

def GetCovMetrics(self) -> int:
Expand All @@ -113,12 +189,36 @@ def GetCovMetrics(self) -> int:
return self.dut.GetCovMetrics()

def CheckPoint(self, name: str) -> int:
"""
Save current simulation state to a file

Args:
name(str): the name of file
Copy link

Copilot AI Sep 25, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are trailing spaces after 'file' in the parameter description.

Copilot uses AI. Check for mistakes.
"""
self.dut.CheckPoint(name)

def Restore(self, name: str) -> int:
"""
Restore simulation state from a file

Args:
name(str): the name of file
Copy link

Copilot AI Sep 25, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are trailing spaces after 'file' in the parameter description.

Suggested change
name(str): the name of file
name(str): the name of file

Copilot uses AI. Check for mistakes.
"""
self.dut.Restore(name)

def GetInternalSignal(self, name: str, index=-1, is_array=False, use_vpi=False):
"""
Get internal signal objects by variable name

Args:
name(str): the name of the internal signal
index(int):
Copy link

Copilot AI Sep 25, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The parameter description for 'index' is incomplete. It should explain what the index parameter is used for.

Suggested change
index(int):
index(int): the index of the internal signal to retrieve. Use a non-negative value to select a specific element for non-array signals; for array signals or VPI signals, index must be negative (typically -1).

Copilot uses AI. Check for mistakes.
is_array(bool): check if array signal
use_vpi(bool): True if the picker compilation uses VPI

Returns:
list: the internal signal list
"""
if name not in self.internal_signals:
signal = None
if self.dut.GetXSignalCFGBasePtr() != 0 and not use_vpi:
Expand Down Expand Up @@ -148,18 +248,45 @@ def GetInternalSignal(self, name: str, index=-1, is_array=False, use_vpi=False):
return self.internal_signals[name]

def GetInternalSignalList(self, prefix="", deep=99, use_vpi=False):
"""
Get the internal signal list

Args:
prefix(str): the prefix of the internal signals
deep(int): specify the number of hierarchy levels below each top module instance
use_vpi(bool): True if the picker compilation uses VPI

Returns:
list: the internal signal list
"""
if self.dut.GetXSignalCFGBasePtr() != 0 and not use_vpi:
return self.xcfg.GetSignalNames(prefix)
else:
return self.dut.VPIInternalSignalList(prefix, deep)

def VPIInternalSignalList(self, prefix="", deep=99):
"""
Get the internal signal list (requires enabling '--vpi' flag when picker compilation)

Args:
prefix(str): the prefix of the internal signals
deep(int): specify the number of hierarchy levels below each top module instance

Returns:
list: the internal signal list
"""
return self.dut.VPIInternalSignalList(prefix, deep)

def Finish(self):
"""
End the simulation, and keep the result files (waveforms, coverage, etc.).
"""
self.dut.Finish()

def RefreshComb(self):
"""
Refresh the combinational logic state of the circuit
"""
self.dut.RefreshComb()

################################
Expand All @@ -171,12 +298,30 @@ def __getitem__(self, key):

# Async APIs wrapped from XClock
async def AStep(self,i: int):
"""
Asynchronous wait for clock to push i cycle

Args:
i(int): wait for i clock cycles
"""
return await self.xclock.AStep(i)

async def ACondition(self,fc_cheker):
"""
Asynchronous waiting condition is true

Args:
fc_cheker(bool): Asynchronous waiting condition
"""
return await self.xclock.ACondition(fc_cheker)

def RunStep(self,i: int):
"""
Drive clock signal, continuously push clock by i clock cycles

Args:
i(int): push i clock cycles
"""
return self.xclock.RunStep(i)

def __setattr__(self, name, value):
Expand Down