[HN Gopher] BIO: The Bao I/O Coprocessor
___________________________________________________________________
BIO: The Bao I/O Coprocessor
Author : zdw
Score : 107 points
Date : 2026-03-20 19:20 UTC (3 days ago)
(HTM) web link (www.bunniestudios.com)
(TXT) w3m dump (www.bunniestudios.com)
| dmitrygr wrote:
| > Above is the logic path isolated as one of the longest
| combination paths in the design, and below is a detailed report
| of what the cells are.
|
| which is an argument that "fpga_pio" is badly implemented or that
| PIO is unsuitable for FPGA impls. Real silicon does not need to
| use a shitton of LUT4s to implement this logic and it can be done
| much more efficiently and closes timing at higher clocks (as we
| know since PIO will run near a GHz)
| Retr0id wrote:
| PIO _is_ unsuitable for FPGA impls, that 's what the article
| says.
|
| > If you're thinking about using it in an FPGA, you'd be better
| off skipping the PIO and just implementing whatever peripherals
| you want directly using RTL.
| dmitrygr wrote:
| Yes, my point is that the article throws a lot of shade at
| PIO while the real issue is that the author is trying to
| shove a third-party FPGA reimpl of it into a place it never
| belonged. PIO itself is a perfectly good design for what it
| does and where it does it.
| Retr0id wrote:
| It didn't read that way, to me.
| bunnie wrote:
| Actually, the PIO does what it does very well! There is no
| "worse" or "better" - just different.
|
| Because it does what it does so well, I use the PIO as the
| design study comparison point. This requires taking a
| critical view of its architecture. Such a review doesn't
| mean its design is bad - but we try to take it apart and
| see what we can learn from it. In the end, there are many
| things the PIO can do that the BIO can't do, and vice-
| versa. For example, the BIO can't do the PIO's trick of
| bit-banging DVI video signals; but, the PIO isn't going to
| be able to protocol processing either.
|
| In terms of area, the larger area numbers hold for both an
| ASIC flow as well as the FPGA flow. I ran the design
| through both sets of tools with the same settings, and the
| results are comparable. However, it's easier to share the
| FPGA results because the FPGA tools are NDA-free and
| everyone can replicate it.
|
| That being said, I also acknowledge in the article that
| it's likely there are clever optimizations in the design of
| the actual PIO that I did not implement. Still, barrel
| shifters are a fairly expensive piece of hardware whether
| in FPGA or in ASIC, and the PIO requires several of them,
| whereas the BIO only has one. The upshot is that the PIO
| can do multiple bit-shifts in a single clock cycle, whereas
| the BIO requires several cycles to do the same amount of
| bit-shifting. Again, neither good or bad - just different
| trade-offs.
| raphlinus wrote:
| Thanks btw for saying clearly that BIO is not suitable
| for DVI output. I was curious about this and was planning
| to ask on social media.
|
| I've done some fun stuff in PIO, in particular the NRZI
| bit stuffing for USB (12Mbps max). That's stretching it
| to its limit. Clearly there will be things for which BIO
| is much better.
|
| I suspect that a variant of BIO could probably do DVI by
| optimizing for that specific use case (in particular,
| configuring shifters on the output FIFO), but I'm not
| sure it's worth the lift.
| drob518 wrote:
| Yea, I think the point is that if you're implementing in FPGA
| in any case, a dedicated state machine is going to be a lot
| smaller than PIO or BIO. But if you're making a standard part
| with hardcoded functionality then BIO is going to be smaller
| than PIO.
| bunnie wrote:
| As a side note about speed comparisons - please keep in mind
| the faster speeds cited for the PIO are achieved through
| overclocking.
|
| The BIO should also be able to overclock. It won't overclock as
| well as the PIO, for sure - the PIO stores its code in flip-
| flops, which performance scales very well with elevated
| voltages. The BIO uses a RAM macro, which is essentially an
| analog part at its heart, and responds differently to higher
| voltages.
|
| That being said, I'm pretty confident that the BIO can run at
| 800MHz for most cases. However, as the manufacturer I have to
| be careful about frequency claims. Users can claim a warranty
| return on a BIO that fails to run at 700MHz, but you can't do
| the same for one that fails to run at 800MHz - thus whenever I
| cite the performance of the BIO, I always stick it at the
| number that's explicitly tested and guaranteed by the
| manufacturing process, that is, 700MHz.
|
| Third-party overclockers can do whatever they want to the chip
| - of course, at that point, the warranty is voided!
| bunnie wrote:
| Hello again HN, I'm bunnie! Unfortunately, time zones strike
| again...I'll check back when I can, and respond to your
| questions.
| dmitrygr wrote:
| very cool. tiny processors everywhere. but be nice to PIO. PIO
| is good :)
| bunnie wrote:
| Agreed! The PIO is great at what it does. I drew a lot of
| inspiration from it.
| dmitrygr wrote:
| What are your thoughts on efficiency? BIO vs PIO
| implementing, say, 68k 16-bit-wide bus slave. I know i can
| support 66MHz 68K bus clock with PIO at 300MHz. How much
| clock speed would BIO need?
| bunnie wrote:
| It depends a lot upon where the processing is happening.
| For example, you could do something where all the data is
| pre-processed and you're just blasting bits into a GPIO
| register with a pair of move instructions. In which case
| you could get north of 60MHz, but I think that's sort of
| cheating - you'll run out of pre-processed data pretty
| quickly, and then you have to take a delay to generate
| more data.
|
| The 25MHz number I cite as the performance expectation is
| "relaxed": I don't want to set unrealistic expectations
| on the core's performance, because I want everyone to
| have fun and be happy coding for it - even relatively new
| programmers.
|
| However, with a combination of overclocking and
| optimization, higher speeds are definitely on the
| horizon. Someone on the Baochip Discord thought up a
| clever trick I hadn't considered that could potentially
| get toggle rates into the hundreds of MHz's. So, there's
| likely a lot to be discovered about the core that I don't
| even know about, once it gets into the hands of more
| people.
| dmitrygr wrote:
| I specified slave specifically because slave is a LOT
| harder. Master is always easy. Waiting for someone else's
| clock and then capturing and replying asap is the hard
| part. Especially if as a slave you need to simulate a
| read.
|
| On rp2350 it is pio (wait for clock) -> pio (read address
| bus) -> dma (addr into lower bits of dma source for next
| channel) -> dma (Data from SRAM to PIO) -> pio (write
| data to data bus) chain and it barely keeps up.
| kev009 wrote:
| Have you looked at TI's PRU at all?
| bsder wrote:
| Emulating the RPI PIOs instead of the TI PRUs is really a
| miss.
|
| The PRUs really get a bunch right. Very specifically, the
| ability to broadside dump the _ENTIRE_ register file in a
| single cycle from one PRU to the other is gigantic. It 's the
| single thing that allows you to transition the data from a
| hard real-time domain to a soft real-time domain and enables
| things like the industrial Ethernet protocols or the
| BeagleLogic, for example.
| jauntywundrkind wrote:
| 3 comments on this, from 2d ago,
| https://news.ycombinator.com/item?id=47469744
| mrlambchop wrote:
| I loved this article and had wanted to play with PIO for a long
| time (or at least, learn from it through playing!).
|
| One thing jumped out here - I assumed CISC inside PIO had a
| mental model of "one instruction by cycle" and thus it was pretty
| easy to reason about the underlying machine (including any delay
| slots etc...).
|
| For this RISC model using C, we are now reasoning about compiled
| code which has a somewhat variable instruction timing (1-3
| cycles) and that introduces an uncertainty - the compiler and
| understanding its implementation.
|
| I think this means that the PIO is timing-first, as timing ==
| waveform where BIO is clarity-first with C as the expression and
| then explicit hardware synchronization.
|
| I like both models! I am wondering about the quantum delays
| however that are being used to set the deadlines - here, human
| derived wait delays are utilized knowledge of the compiled
| instructions to set the timing.
|
| Might there not be a model of 'preparing the next hardware
| transaction' and then 'waiting for an external synchronization'
| such as an external signal or internal clock, so we don't need to
| count the instruction cycles so precisely. On the external signal
| side, I guess the instruction is 'wait for GPIO change' or
| something, so the value is immediately ready (int i =
| GPIO_read_wait_high(23) or something) and the external one is
| doing the same, but synchronizing (GPIO_write_wait_clock( 24,
| CLOCK_DEF)) as an alternative to the explicit quantum delays.
|
| This might be a shadow register / latch model in more generic
| terms - prep the work in shadow, latch/commit on trigger.
|
| Anyway, great work Bunnie!
| bunnie wrote:
| The idea of the wait-to-quantum register is that it gets you
| out of cycle-counting hell at the expense of sacrificing a few
| cycles as rounding errors. But yes, for maximum performance you
| would be back to cycle counting.
|
| That being said - one nice thing about the BIO being open
| source is you can run the verilog design in Verilator. The
| simulation shows exactly how many cycles are being used, and
| for what. So for very tight situations, the open source RTL
| nature of the design opens up a new set of tools that were
| previously unavailable to coders. You can see an example of
| what it looks like here:
| https://baochip.github.io/baochip-1x/ch00-00-rtl-overview.ht...
|
| Of course, there's a learning curve to all new tools, and
| Verilator has a pretty steep curve in particular. But, I hope
| people give the Verilator simulations a try. It's kind of neat
| just to be able to poke around inside a CPU and see what it's
| thinking!
| drob518 wrote:
| You could always get around the compiler uncertainty using a RV
| assembler, no? These IO programs are not long or terribly
| sophisticated.
| guenthert wrote:
| I appreciate the intro, motivation and comparison to the PIO of
| the RP2040/2350. How would this compare to the (considerably
| older, slower, but more flexible) Parallax P8X32A ("Propeller")?
| t-3 wrote:
| The Propeller 2 would be an interesting comparison as well,
| with it's own smart pins playing a similar role.
| crest wrote:
| IIRC the Propeller is an eight thread barrel CPU with the same
| number of pipeline stages. So it "retires" just one instruction
| per cycle. All PIO state machines can run every cycle so they
| should be considered very small CPU cores. You can think of
| them as channel I/O co-processors for a microcontroller instead
| of a mainframe.
| alex7o wrote:
| This is actually super cool, you can use those as both math
| accelerators and as io, and them being in lockstep you can kind
| of use them as int only shader units. I don't know how this is
| useful yet.
|
| Btw I am curious what about edge cases. Maybe I have missed that
| from the article but what is the size of the FIFO?
|
| Or the more dangerous part that is you have complex to determine
| timing now for complex cases like each reqd from FIFO is and ISR
| and you have until the next read from the FIFO amount of
| instructions otherwise you would stall the system and that looks
| to me too hard to debug.
| genxy wrote:
| Thanks for making this a blog post!
|
| Have some on the way! Can't wait!
| RS-232 wrote:
| > The build script compiles C code down to a clang intermediate
| assembly, which is then handed off to a Python script that
| translates it into a Rust macro which is checked into Xous as a
| buildable artifact using its pure-Rust toolchain.
|
| Ah yes, the good ol "we solved the C problem by turning it into
| four other problems" pipeline
___________________________________________________________________
(page generated 2026-03-23 23:00 UTC)