8000 right alignment behavior by keegandent · Pull Request #39 · eerimoq/bitstruct · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

right alignment behavior #39

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

keegandent
Copy link

I've been strugging with a communication system that expects the bitstream to be "right-aligned". Basically the idea is to perform zero-padding on the left instead of the right. I also make this alter the behavior of Text/Raw so that the struct bytes are aligned based on the rightmost values and left padded from there. The tests illustrate this.

Please let me know your thoughts.

@eerimoq
Copy link
Owner
eerimoq commented Apr 18, 2024

What about just adding padding to the format string? For example p3u77 instead of u77, ..., align_right=True.

@keegandent
Copy link
Author

That’s basically what I’m doing on line 277, but when the raw/text arg width doesn’t exactly match the field width (r7 and b'\x7f' for example) then the bits are still grabbed from the left of the arg instead of the right. See line 868 of the test.

@eerimoq
Copy link
Owner
eerimoq commented Apr 18, 2024

Can you give an example of when the new functionality is needed/useful?

@keegandent
Copy link
Author

So my particular use case may be niche, but there is a co-processor I am communicating with over a serial UART but the underlying packet structure has a dynamic bit-width. It expects those bits to be right-aligned, i.e. there is padding on the left of the most significant byte.

The reason I figured this might be worth a PR is just that the documentation said that the output is right-padded to the nearest byte. That’s a fine default behavior (and to your credit makes more sense regarding memory/disk alignment) but in the interest of symmetry, I thought there might be value in supporting left-padding with a simple flag instead of having the user calculate it into the format string. This is fairly common for communication with hardware over byte-aligned interfaces. And the reason I change the way text/raw operates in this mode is parallelism between the input and outputs.

@keegandent
Copy link
Author

Also, let me know if the name of the flag should be different, like maybe right_aligned or pad_on_left.

@eerimoq
Copy link
Owner
eerimoq commented Apr 18, 2024

Can you give code examples of where the change is this PR is needed? Just want to understand.

@keegandent
Copy link
Author
keegandent commented Apr 18, 2024

Sure thing, let me see if I can make it legible

net_charge_width = charge_width(self._network)
opc_width = _count_to_bitwidth(len(self._Opcode))
inp_names = list()
inp_names.append("opcode")
inp_fmt_str = f"u{opc_width}"
match self._source_type:
    case _IoType.DISPATCH:
        # using stream example
        pass
    case _IoType.STREAM:
        inp_names.extend(range(self._network.num_inputs()))
        inp_fmt_str += "".join(
            [f"s{net_charge_width}" for _ in range(self._network.num_inputs())]
        )
    case _:
        raise ValueError()
self._inp_fmt = bs.compile(inp_fmt_str, inp_names)

out_names = list()
out_fmt_str = ""
match self._sink_type:
    case _IoType.DISPATCH:
        # using stream example
        pass
    case _IoType.STREAM:
        out_names.extend(range(self._network.num_outputs()))
        out_fmt_str += "b1" for _ in range(self._network.num_outputs())
    case _:
        raise ValueError()
self._out_fmt = bs.compile(out_fmt_str, out_names)

So if we take packing a stream input as an example, there is a 1-bit opcode and then num_input x charge_width-bit signed ints to send over serial. However, just because of the way the hardware works, it expects that all to be right-aligned. Same with the stream output, it has num_output x 1-bit fires/no-fires that will come right-aligned in the bytestream. I could manually change the fmt string after I create it the first time, sure, but it seems like there should be an option to left-pad formats that aren't an integer number of bytes. Just my take, but I can work around it.

@eerimoq
Copy link
Owner
eerimoq commented Apr 24, 2024

I think we have to simplify the implementation and also implement it in the C extension. Most likely easiest to have an optional step that just shifts all data to the right after packed with today's right-padded design.

@keegandent
Copy link
Author

So the preference is to not treat the raw/text as right-aligned in that case? I would want to know what the decision on that is before implementing in C. I just think for symmetry we would want raw byte fields to populate from the right on input the same as they would on output in the align_right=True case.

@eerimoq
Copy link
Owner
eerimoq commented May 10, 2024

Sorry, I'm too busy working on my other projects right now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants
0