<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def sdram_alloc(self, size, tag=0, x=Required, y=Required, app_id=Required, clear=False):
 """Allocate a region of SDRAM for an application. Requests SARK to allocate a block of SDRAM for an application and raises a :py:exc:`.SpiNNakerMemoryError` on failure. This allocation will be freed when the application is stopped. Parameters size : int Number of bytes to attempt to allocate in SDRAM. tag : int 8-bit tag that can be looked up by a SpiNNaker application to discover the address of the allocated block. The tag must be unique for this ``app_id`` on this chip. Attempting to allocate two blocks on the same chip and for the same ``app_id`` will fail. If ``0`` (the default) then no tag is applied. For example, if some SDRAM is allocated with ``tag=12``, a SpiNNaker application can later discover the address using:: void *allocated_data = sark_tag_ptr(12, 0); A common convention is to allocate one block of SDRAM per application core and give each allocation the associated core number as its tag. This way the underlying SpiNNaker applications can simply call:: void *allocated_data = sark_tag_ptr(sark_core_id(), 0); clear : bool If True the requested memory will be filled with zeros before the pointer is returned. If False (the default) the memory will be left as-is. Returns ------- int Address of the start of the region. The allocated SDRAM remains valid until either the 'stop' signal is sent to the application ID associated with the allocation or :py:meth:`.sdram_free` is called on the address returned. Raises ------ rig.machine_control.machine_controller.SpiNNakerMemoryError If the memory cannot be allocated, the tag is already taken or it is invalid. """

        assert 0 <= tag < 256

        # Construct arg1 (app_id << 8) | op code
        arg1 = app_id << 8 | consts.AllocOperations.alloc_sdram

        # Send the packet and retrieve the address
        rv = self._send_scp(x, y, 0, SCPCommands.alloc_free, arg1, size, tag)
        if rv.arg1 == 0:  # Allocation failed
            tag_in_use = False
            if tag != 0:
                # If a tag was specified then read the allocation table to see
                # if the tag was already in use or whether we ran out of
                # memory.
                alloc_tags = self.read_struct_field("sv", "alloc_tag", x, y)
                index = (app_id << 8) + tag
                entry = self.read(alloc_tags + index, 4, x, y)
                tag_in_use = (entry != 0)

            raise SpiNNakerMemoryError(size, x, y, tag, tag_in_use)

        # Get the address
        address = rv.arg1

        if clear:
            # Clear the memory if so desired
            self.fill(address, 0, size, x, y, 0)

        return address