Skip to content

ralgen

RAL Generator.

Classes:

  • HexPP

    Formats integers as Hex.

  • RALGEN

    RAL Generator.

HexPP

Bases: PrettyPrinter

Formats integers as Hex.

Methods:

  • format

    Extends PrettyPrinter's format to support printing numbers in hex.

format

format(obj, context, maxlevels, level)

Extends PrettyPrinter's format to support printing numbers in hex.

Source code in src/peakrdl_cocotb_ralgen/ralgen.py
25
26
27
28
29
def format(self, obj, context, maxlevels, level):
    """Extends PrettyPrinter's format to support printing numbers in hex."""
    if isinstance(obj, int):
        return f"0x{obj:_X}", True, False
    return super().format(obj, context, maxlevels, level)

RALGEN

RALGEN(file, default_regwidth=None)

Bases: RDLListener

RAL Generator.

RAL Test.

RAL Test consists of 1. Reset read test 2. Random Read Write tests

These tests use a mix of front door/backdoor access. e.g.

Write Read
Front Front
Back Front
Front Back
Back Back

For using backdoor access you need to create two functions for reading and writing to hdl signals and pass it to this class

A check function can only check the modified register, or check all registers to ensure that only the desired bit in the desired register is modified.

For every register we need to create 1. A Reset value and Reset mask 2. Write mask 3. Read mask

Methods:

Source code in src/peakrdl_cocotb_ralgen/ralgen.py
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
    def __init__(self, file, default_regwidth=None):
        """Constructor."""
        self.file = file
        self.registers = {}
        self.current_register = ""
        self.map_count = 0
        self.map_offset = []
        self.addressmap = []
        self.not_supported = {"singlepulse": [], "rclr": [], "woclr": []}
        self.default_regwidth = default_regwidth
        print(
            '"""Generated using Cocotb RALGenerator.  Copyright © 2024 Dyumnin Semiconductors."""',
            file=file,
        )
        print(
            """
import random
import cocotb
logger = cocotb.log
              """,
            file=file,
        )
        print(
            f" Cocotb RALGenerator: SystemRDL to RALtest converter version {il.distribution('peakrdl_cocotb_ralgen').version}.",
        )
        print(
            """
        Copyright © 2024 Dyumnin Semiconductors.
        https://dyumnin.com
        """,
        )

enter_Addrmap

enter_Addrmap(node)

Overriding builtin method.

Source code in src/peakrdl_cocotb_ralgen/ralgen.py
93
94
95
96
97
def enter_Addrmap(self, node):
    """Overriding builtin method."""
    self.map_count += 1
    self.addressmap.append(node.get_path_segment())
    self.map_offset.append(node.inst.addr_offset)

enter_Field

enter_Field(node)

Overriding builtin method.

Source code in src/peakrdl_cocotb_ralgen/ralgen.py
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
def enter_Field(self, node):
    """Overriding builtin method."""
    self.registers[self.current_register]["signals"].append(
        {
            "low": node.low,
            "high": node.high,
            "path": [*self.hier_path, node.get_path_segment()],
        },
    )
    if "reset" in node.inst.properties:
        # print(f"{self.current_register}:{node.get_path_segment()}:::{self.registers[self.current_register]['reset_value']} |={node.get_property('reset')} << {node.high}")
        self.registers[self.current_register]["reset_value"] |= (
            node.get_property("reset") << node.low
        )
        self.registers[self.current_register]["reset_mask"] |= (
            int("1" * (node.high - node.low + 1), 2) << node.low
        )
    if node.is_sw_writable:
        self.registers[self.current_register]["write_mask"] |= (
            int("1" * (node.high - node.low + 1), 2) << node.low
        )
    if node.is_sw_readable:
        self.registers[self.current_register]["read_mask"] |= (
            int("1" * (node.high - node.low + 1), 2) << node.low
        )
    if "donttest" in node.inst.properties:
        self.registers[self.current_register]["donttest"] |= (
            int("1" * (node.high - node.low + 1), 2) << node.low
        )
    if "woclr" in node.inst.properties:
        # print("Error: Unsupported feature. Not testing woclr bits")
        self._not_supported(node, "woclr")
        self.registers[self.current_register]["donttest"] |= (
            int("1" * (node.high - node.low + 1), 2) << node.low
        )
    if "rclr" in node.inst.properties:
        # print("Error: Unsupported feature. Not testing rclr bits")
        self._not_supported(node, "rclr")
        self.registers[self.current_register]["donttest"] |= (
            int("1" * (node.high - node.low + 1), 2) << node.low
        )
    if "singlepulse" in node.inst.properties:
        # print("Error: Unsupported feature. Not testing SinglePulse bits")
        self._not_supported(node, "singlepulse")
        self.registers[self.current_register]["donttest"] |= (
            int("1" * (node.high - node.low + 1), 2) << node.low
        )

enter_Reg

enter_Reg(node)

Overriding builtin method.

Source code in src/peakrdl_cocotb_ralgen/ralgen.py
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
def enter_Reg(self, node):
    """Overriding builtin method."""
    self.current_register = "_".join([*self.addressmap, node.get_path_segment()])
    self.hier_path = [*self.addressmap, node.get_path_segment()]
    if "regwidth" in node.inst.properties:
        width = node.inst.properties["regwidth"]
    elif self.default_regwidth is not None:
        width = self.default_regwidth
    self.registers[self.current_register] = {
        "name": node.get_path_segment(),
        "width": width,
        "reset_value": 0,
        "reset_mask": 0,
        "write_mask": 0,
        "read_mask": 0,
        "donttest": 0,
        "address": sum(self.map_offset) + node.inst.addr_offset,
        "offset": node.inst.addr_offset,
        "signals": [],
        "disable": [],
    }

exit_Addrmap

exit_Addrmap(node)

Overriding builtin method.

Source code in src/peakrdl_cocotb_ralgen/ralgen.py
205
206
207
208
209
210
211
212
213
214
215
216
217
218
def exit_Addrmap(self, node):
    """Overriding builtin method."""
    self.map_count -= 1
    self.addressmap.pop()
    self.map_offset.pop()
    if self.map_count == 0:
        self._print_not_supported()
        preg = HexPP().pformat(self.registers)
        env = Environment(
            loader=PackageLoader("peakrdl_cocotb_ralgen"),
            autoescape=select_autoescape(),
        )
        template = env.get_template("ralgen.j2")
        print(template.render(preg=preg, node=node), file=self.file)

exit_Reg

exit_Reg(node)

Overriding builtin method.

Source code in src/peakrdl_cocotb_ralgen/ralgen.py
178
179
180
181
182
183
184
185
186
187
188
def exit_Reg(self, node):
    """Overriding builtin method."""
    width = node.get_property("regwidth")
    if width is None:
        width = self.default_regwidth
    assert width, f"{node=}"
    self.registers[self.current_register]["regwidth"] = width
    if not node.has_sw_writable:
        self.registers[self.current_register]["disable"].append("rw")
    if not node.has_sw_readable:
        self.registers[self.current_register]["disable"].extend(["rw", "reset"])