Register / Field Access ======================= Once the register definitions have been import :doc:`avl_ral._ral.RAL ` provides two functions to locate registers and fields. - :any:`RAL.find_by_name` - :any:`RAL.find_by_address` These functions return a list of Register and / or field objects that match the given criteria. Full path names (including "." separators) and / or wildcards (including "*") are supported. Front-Door Access ----------------- Front-door accesses are supported via callbacks supplied by the user. These are assigned using the :any:`RAL.assign_callbacks` function. .. code-block:: python # Assign callbacks self.ral.assign_callbacks(read=self.read, write=self.write) async def read(self, addr : int) -> int: await RisingEdge(self.hdl.clk) self.hdl.valid.value = 1 self.hdl.addr.value = addr self.hdl.r_not_w.value = 1 await RisingEdge(self.hdl.clk) self.hdl.valid.value = 0 self.hdl.addr.value = 0 self.hdl.r_not_w.value = 0 await RisingEdge(self.hdl.clk) return int(self.hdl.rdata.value) async def write(self, addr : int, value : int) -> None: await RisingEdge(self.hdl.clk) self.hdl.valid.value = 1 self.hdl.addr.value = addr self.hdl.wdata.value = value self.hdl.r_not_w.value = 0 await RisingEdge(self.hdl.clk) self.hdl.valid.value = 0 self.hdl.addr.value = 0 self.hdl.wdata.value = 0 self.hdl.r_not_w.value = 0 When performed on a register these callbacks are executed exactly as implemented. When performed on a field accesses are performed on the parent register as read-modify-writes. \ This matches how software would implement a field specific update. Implementing front-door access via AVL-AXI or AVL-APB callbacks is trivial. Back-Door Access ---------------- Back-door access are supported by :any:`Field.peek` and :any:`Field.poke` functions. Before these are able to \ be used the user must assign a HDL handle to the field, :any:`Field.assign_hdl` function.` Registers also support :any:`Reg.peek` and :any:`Reg.poke` functions, calling each child fields functions for the give \ bit positions. .. code-block:: python # Connect all field to HDL variables (assume HDL variables name match logical name) fields = self.ral.find_by_name(name="*", types=FieldNode) for f in fields: f.assign_hdl(getattr(self.hdl, f.inst_name)) # Field Poke / Peek Test for f in self.ral.find_by_name(name="*", types=FieldNode): f.poke(0x1) await RisingEdge(self.hdl.clk) assert f.peek() == 0x1, f"{f.inst_name} poke / peek failed expected 0x1 got {f.peek()}" self.info("Field Poke / Peek Test: PASS") # Register Poke / Peek Test for r in self.ral.find_by_name(name="*", types=RegNode): r.poke(0x0) await RisingEdge(self.hdl.clk) assert r.peek() == 0x0, f"{r.inst_name} poke / peek failed expected 0x0 got {r.peek()}" self.info("Register Poke / Peek Test: PASS")