or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

binary-types.mdclock-generation.mdindex.mdlogging-utilities.mdsignal-handling.mdtask-management.mdtest-framework.mdtriggers-timing.md

test-framework.mddocs/

0

# Test Framework

1

2

The cocotb test framework provides decorators and infrastructure for defining, discovering, and executing HDL testbenches using Python's async/await syntax. Tests are automatically discovered and can be configured with timeouts, failure expectations, and execution stages.

3

4

## Capabilities

5

6

### Test Decorator

7

8

Marks async functions as tests with optional configuration for timeouts, failure expectations, and execution control.

9

10

```python { .api }

11

@test(timeout_time=None, timeout_unit="step", expect_fail=False, expect_error=(), skip=False, stage=0)

12

def test_decorator(func):

13

"""

14

Decorator to mark a Callable which returns a Coroutine as a test.

15

16

Parameters:

17

- timeout_time (numbers.Real or decimal.Decimal, optional): Simulation time duration before timeout

18

- timeout_unit (str, optional): Units of timeout_time, accepts any units that Timer does

19

- expect_fail (bool, optional): If True, test passes when it fails a functional check

20

- expect_error (exception type or tuple, optional): Test passes only if specified exception types are raised

21

- skip (bool, optional): Don't execute this test as part of regression

22

- stage (int): Order tests logically into stages, defaults to 0

23

24

Returns:

25

Test coroutine decorator

26

"""

27

```

28

29

**Usage Examples:**

30

31

```python

32

@cocotb.test()

33

async def basic_test(dut):

34

"""Simple test without configuration."""

35

await Timer(100, units="ns")

36

assert dut.output.value == 1

37

38

@cocotb.test(timeout_time=1000, timeout_unit="ns")

39

async def timed_test(dut):

40

"""Test with timeout protection."""

41

# Long-running test operations

42

await Timer(500, units="ns")

43

44

@cocotb.test(expect_fail=True)

45

async def failing_test(dut):

46

"""Test that expects to fail."""

47

assert False, "This test is expected to fail"

48

49

@cocotb.test(expect_error=ValueError)

50

async def error_test(dut):

51

"""Test that expects specific exception."""

52

raise ValueError("Expected error")

53

54

@cocotb.test(skip=True)

55

async def skipped_test(dut):

56

"""Test that will be skipped."""

57

pass

58

59

@cocotb.test(stage=1)

60

async def staged_test(dut):

61

"""Test in execution stage 1."""

62

await Timer(50, units="ns")

63

```

64

65

### Coroutine Decorator

66

67

Transforms functions into coroutines with logging capabilities and join functionality for creating reusable testbench components.

68

69

```python { .api }

70

@coroutine

71

def coroutine_decorator(func):

72

"""

73

Decorator class that provides common coroutine mechanisms.

74

75

Features:

76

- log methods will log to cocotb.coroutine.name

77

- join method returns event which fires when coroutine exits

78

79

Returns:

80

Coroutine with enhanced capabilities

81

"""

82

```

83

84

**Usage Examples:**

85

86

```python

87

@cocotb.coroutine

88

async def stimulus_generator(dut, data_list):

89

"""Reusable stimulus generation coroutine."""

90

for data in data_list:

91

dut.input_data.value = data

92

await RisingEdge(dut.clk)

93

stimulus_generator.log.info(f"Applied stimulus: {data}")

94

95

@cocotb.coroutine

96

async def response_checker(dut, expected_list):

97

"""Reusable response checking coroutine."""

98

for expected in expected_list:

99

await RisingEdge(dut.clk)

100

actual = dut.output_data.value

101

assert actual == expected, f"Expected {expected}, got {actual}"

102

response_checker.log.info(f"Verified response: {actual}")

103

104

@cocotb.test()

105

async def coordinated_test(dut):

106

"""Test using coroutine components."""

107

stim_task = cocotb.start_soon(stimulus_generator(dut, [1, 2, 3, 4]))

108

check_task = cocotb.start_soon(response_checker(dut, [1, 2, 3, 4]))

109

110

await stim_task.join()

111

await check_task.join()

112

```

113

114

### External Decorator

115

116

Wraps functions to run in separate threads, enabling blocking operations without stopping simulation time progression.

117

118

```python { .api }

119

@external

120

def external_decorator(func):

121

"""

122

Decorator to apply to an external function to enable calling from cocotb.

123

124

Converts normal function into blocking coroutine that runs in separate thread.

125

Currently creates new execution thread for each function call.

126

127

Returns:

128

Blocking coroutine that yields until thread completion

129

"""

130

```

131

132

**Usage Examples:**

133

134

```python

135

@cocotb.external

136

def file_operation(filename):

137

"""External function for file I/O."""

138

with open(filename, 'r') as f:

139

data = f.read()

140

time.sleep(1) # Simulate slow operation

141

return data.strip()

142

143

@cocotb.external

144

def network_request(url):

145

"""External function for network operations."""

146

import requests

147

response = requests.get(url)

148

return response.json()

149

150

@cocotb.test()

151

async def external_test(dut):

152

"""Test using external functions."""

153

# These operations run in threads and don't block simulation

154

config_data = await file_operation("config.txt")

155

api_data = await network_request("http://api.example.com/data")

156

157

# Use the data in simulation

158

dut.config.value = int(config_data)

159

dut.api_value.value = api_data['value']

160

161

await Timer(100, units="ns")

162

```

163

164

### Function Decorator

165

166

Creates functions that can block simulation time while being called from external threads, bridging threaded code back to simulation context.

167

168

```python { .api }

169

@function

170

def function_decorator(func):

171

"""

172

Decorator for functions that can block and consume simulation time.

173

174

Allows coroutine that consumes simulation time to be called by thread

175

started with @external. Function internally blocks while externally

176

appears to yield.

177

178

Returns:

179

Function that can be called from external threads

180

"""

181

```

182

183

**Usage Examples:**

184

185

```python

186

@cocotb.function

187

async def wait_for_condition(dut, signal, value, timeout_ns=1000):

188

"""Function that waits for signal condition."""

189

start_time = get_sim_time("ns")

190

191

while dut._id(signal, extended=False).value != value:

192

await Timer(10, units="ns")

193

current_time = get_sim_time("ns")

194

195

if current_time - start_time > timeout_ns:

196

raise TimeoutError(f"Signal {signal} never reached {value}")

197

198

return current_time - start_time

199

200

@cocotb.external

201

def threaded_test_sequence(dut):

202

"""External function that calls back into simulation."""

203

import threading

204

205

# This external function can call @function decorated functions

206

duration = wait_for_condition(dut, "ready", 1, 500)

207

print(f"Ready signal asserted after {duration} ns")

208

209

return "sequence_complete"

210

211

@cocotb.test()

212

async def hybrid_test(dut):

213

"""Test combining external and function decorators."""

214

# Start external thread that will call back into simulation

215

result = await threaded_test_sequence(dut)

216

assert result == "sequence_complete"

217

```

218

219

## Public Utility Function

220

221

### Public Decorator

222

223

Utility decorator for marking functions as part of the public API.

224

225

```python { .api }

226

def public(f):

227

"""

228

Use decorator to avoid retyping function/class names.

229

230

Adds function name to module's __all__ list to mark as public API.

231

232

Parameters:

233

- f: Function to mark as public

234

235

Returns:

236

The original function unchanged

237

"""

238

```

239

240

## Test Execution Context

241

242

### Global Test Variables

243

244

During test execution, cocotb provides access to test context through global variables:

245

246

```python { .api }

247

# Available during test execution

248

cocotb.regression_manager # Access to test execution manager

249

cocotb.scheduler # Access to coroutine scheduler

250

cocotb.top # Handle to top-level design entity (DUT)

251

cocotb.argv # Command-line arguments from simulator

252

cocotb.plusargs # Plus-args from simulator command line

253

```

254

255

**Usage Examples:**

256

257

```python

258

@cocotb.test()

259

async def context_test(dut):

260

"""Test accessing execution context."""

261

# Access top-level design directly

262

assert cocotb.top is dut # They reference the same object

263

264

# Check simulator arguments

265

if "debug" in cocotb.plusargs:

266

cocotb.log.info("Debug mode enabled")

267

268

# Access scheduler for advanced operations

269

current_time = cocotb.scheduler.sim_time

270

cocotb.log.info(f"Test started at {current_time}")

271

```