274 karma · joined November 20, 2018
Building a custom CPU commits you to writing an assembler and listing generator - which is a good hobby-project job for one person who's handy with Python. After stumbling through those foothills, though, I found myself at the base of some very steep, scary GCC/binutils cliffs wondering how I could have gotten so lost, so far from home.
Even if all RISC-V does is offer a bunch of arbitrary answers to arbitrary design questions, I consider it a massive win.
At a certain scale, it's conventional for hardware designs to become complex enough that it's necessary to structure them in hierarchies, just to maintain control. This design is small enough that none of the extra structure is essential.
It's possible to be incredibly expressive in Verilog and VHDL. This implementation is written in VHDL, which has an outdated reputation for being long-winded.
Also worth a look: FemtoRV32 Quark [0], which is written in Verilog.
[0]: https://github.com/BrunoLevy/learn-fpga/blob/master/FemtoRV/...
The retrocomputing scene looks like a ton of fun and I'd be delighted if any of my work is used there.
A narrower data bus would allow a 2-cycle execution path, and would likely split the longest combinatorial path in the current design (which certainly goes through the adder tree.) This could be either an 0.5 instruction-per-clock (IPC) design, or a pipelined design that maintains 1 IPC at the expense of extra pipeline hazards and corresponding bubbles.
A narrower address seems like it's only helpful as a knock-on to a split data bus.
Gut feeling: I doubt that splitting the data or address buses into additional phases would actually save resources. You would certainly need more flip-flops to maintain state, and more LUTs to manage combinational paths across the two execution stages. While you can sometimes add complexity and "win back" gates, it's an approach with limits. If you compare SERV's resource usage to FemtoRV32-Quark's, it's notable how much additional state (flip-flops) SERV "spends" to reduce its combinatorial logic (LUT) footprint.
With that in mind: the single instruction-per-clock design is for simplicity's sake, not performance's sake. If the execution stage were pipelined, it'd be a different core. If performance is the goal, I'd start by ripping out some of the details that distinguish this core from other (excellent) RISC-V cores.
1. Clearly, he's upset about inappropriate treatment of Ukrainian citizens. (Fine - so am I.)
2. He's also upset at being forced to use Azure IoT frameworks when most FPGA applications don't need (or can't use) them.
For some reason, he's chosen to bury (1) until the end of the post, and amplified (2) to compensate. However, (2) may be completely moot: the current InnovateFPGA rules have an "OR" where he claims an "AND". The rules state:
"Solution submission must use content platforms including Analog Devices plug-in boards, Azure IoT Central *OR* Azure IoT Hub"
The author writes: "Also, among the requirements there was: 'Contestants will utilize the Terasic DE10-Nano FPGA Cloud Connectivity Kit, with Analog Devices plug-in cards, *AND* connected to the cloud using selected Microsoft Azure Cloud Services.'"
The "AND" vs. "OR" make all the difference. (This may have been a recent rules change: the "AND" text exists on-line, but is not currently on the official contest rules.)The whole post seems to rest on pretty shaky territory, and I wouldn't be surprised to see it disappear. After all, if InnovateFPGA is the wrong venue for "ugly political antics", how is blog@CACM any better?
In this system, I write a given function in C and surround it with a macro wrapper. This wrapper generates a JSON-RPC equivalent of the C function using the Jansson JSON library [1], complete with argument typechecking and error management. My C code can call the function normally, and an embedded webserver [2] can export it across the network where it's used fairly transparently by a Python stack on a control PC.
All three of these "embedded software" elements (the embedded webserver, the JSON library, and the FPGA interface) are very well suited to C. I have recently dabbled in moving parts of it to C++, and have found a few surprising impedance mismatches. (As I mentioned above, C++ still lacks reflection.)
The macros, here, are not for "elegance" or any other abstract purpose. They have allowed a ~80% reduction in boilerplate and an equally impressive reduction in the bugs and hassles associated with this kind of low-density, high-sprawl code.
Even in c++20, there are things you can do with macros you can't do in the language. This may change when reflection lands in c++2x, but I won't be able to use it for years and widespread adoption won't be possible for another decade.
On the boost front, I should have noted the difference between VMD [1] and boost::preprocessor [2]. I think VMD [1] trades some backwards compatibility for coherence and consistency and is a better starting point for new code.
[1]: https://www.boost.org/doc/libs/1_70_0/libs/vmd/doc/html/inde...
[2]: https://www.boost.org/doc/libs/1_76_0/libs/preprocessor/doc/...
It is basically impossible to provide a "kind" development environment using deep macro trickery. The error messages you get from this kind of library are a major handicap. This failing is intrinsic to the landscape and not something you can really fix.
Historically, macro processors in major compilers were inconsistent, limited, and arbitrary, making heavy macro use frustrating, limited, non-portable. I think this is mostly historical now.
IMO people should prefer boost::preprocessor for purposes like this (even in pure C), since it is battle-tested and more polished than "little" metaprogramming libraries will likely ever be. (This is advice to possible users, and not a knock on the author. Props for exploring the space and building something useful.)
This idiom worked well in Python 2.x with Tornado. Python 3's batteries-included async unfortunately broke it partway (event loops are not reentrant [3], deliberately). However, in this Rust post's "turn-that-frown-upside-down" spirit, the Python 3.x port of tworoutines enforces a more deliberate coding style since it doesn't allow you to remain ignorant of asynchronous calls within an asynchronous context. This (arguably) mandates better code.
I don't claim Python is superior to Rust, or that hiding red/blue functions is a great idea everywhere. I did want to point out that dynamic languages allow some interesting alternatives to compiled languages. This is worth musing over here because of the author's stated bias for compiled languages (I think I agree), and his claim that red/blue unification would only be enabled by sophisticated compilers (not necessarily).
[1]: http://threespeedlogic.com/python-tworoutines.html [2]: https://news.ycombinator.com/item?id=18516121 [3]: https://bugs.python.org/issue22239
Tagged YAML allowed us to replace an older system that had ten times as much code. Now, there are far fewer, much warmer code paths, and it's easier to use and far less scary to maintain as a result.
Other markups are not the only alternative to this kind of thing. I expect many developers would reach for a database (SQLite?) as a storage medium. However, keeping our data accessible in plain text has been a huge benefit.
You know what's really interesting about YAML? !Tags (https://yaml.org/spec/1.2/spec.html#id2805019), when used as type hints.
In YAML, you can write: (forgive the contrived example)
!Person
name: Joe
login: joe
In Python, you can use "yaml.add_constructor" to automatically dispatch specific Python code when !Person tags are encountered in the YAML. You can transform text into an object tree (edit: graph, actually -- don't forget about anchors and aliases) automatically.In the right places, this is extremely handy. It's a middle ground between the "duck typing" you normally get with un-validated markup, and the quasi-"static typing" you get with the same inputs after a schema validation. There's an analogy with type annotations in Python.
As always, there are right and wrong places to apply this kind of thing.
By day, I'm an FPGA coder. (The ASIC situation rhymes, more or less.) From the perspective of implementing small CPU architectures: register files are not the problem in the way you'd expect. A modern FPGA has primitives that implement 32- or 64-register files with remarkable efficiency, in 2-, 4-, or 8-port varieties. Midrange FPGAs are now fast enough that a lightly pipelined RISC CPU performs well enough; there's no need to aggressively pipeline a CPU for normal clock rates (100 to 250 MHz) any more, and little motivation for exotic architectures. The MicroBlaze (Xilinx) or NIOS-II (Altera) soft core CPUs are so boringly effective they've forced ARM to license their designs for FPGAs for free. For smaller state-machine-class problems, the PicoBlaze is an interesting, minimal RISC. For most of us, CPUs are solved problems and the frontier has shifted towards cache-coherency, networking and other more interesting arenas.
I love the idea of stack machines in the right contexts (PostScript, FORTH, Java, you name it), but it's hard to disagree with the essay's conclusions.
IMO AsciiDoc's advantage over Markdown, RST, LaTeX and others is its adoption of DocBook XML as an industrial-strength backing format. The combination of a pragmatic markup language and a proven, stable, and relatively media-independent translation target is unique and extremely useful.
I'm an enthusiastic believer in Asciidoc-the-language, but the tooling situation is confusing in parts, fragmented in others, and not really living up to its premises. This is exactly why I'm watching the asciidoc-wg project with great interest.
My personal wish is for a modern and first-class replacement for the various AsciiDoc-to-PDF flows. I'd bet on CSS Paged Media, although it's been a long haul. The current options (FO/XSLT, dblatex, and asciidoctor-pdf) all have pretty severe limitations.
If any of the AsciiDoc/AsciiDoctor devs are reading this, thank you 1,000,000 times for your efforts. It's an extremely complex project and I am grateful there's a community of talented people working on it.
Unfortunately it requires some creativity to support encrypted RTL in an open-source simulator, and both vendors require a way to supply simulation models without exposing source code. Doubly unfortunately, the open-source simulators are all language-specific and any attempts to bridge the gap have been only limited experiments. A brand-new simulator architecture seems necessary but has its oxygen starved by the rest of the ecosystem, open-source and commercial.
I am watching https://github.com/llvm/circt with interest but I don't think this is quite focused on simulators the way I think is necessary.
In EDA, tooling stacks horizontally. At minimum, I need a simulator and a synthesizer, and both need to support the same features for those features to be useful. Every tool or layer I add to my EDA stack erodes the feature set I am able to use for all of them. Encrypted IP? VHDL-2008? SystemVerilog? Only with a commercial simulator. Now you have to start squabbling over licenses, which is the same problem except you've traded technical limitations for economic ones. (edit: and paid 6 figures for the privilege.)
All of this is a huge drag on productivity. It benefits only the big EDA incumbents (not even the FPGA manufacturers). If EDA tooling is going to improve, we need to change this dynamic. Until we do, adding layers to the tooling is a net loss except for a small sliver of the user community. (Typically the people who wrote it.)
In short, no, this doesn't impact the trade-offs and wouldn't even if Google provided this service as a commercial print-on-demand offering. You can get an ASIC fab'd on older nodes for surprisingly cheap, if you have the know-how and access to tools [2].
When power is a first-class design problem (it frequently is), even an "old" 28nm FPGA like Xilinx's 7 series will run rings around an 130nm ASIC. The extra silicon you're powering in the FPGA is more than offset by the economical access it gives you to modern nodes with lower voltages.
[1]: https://ieeexplore.ieee.org/document/7086413 [2]: https://spectrum.ieee.org/tech-talk/computing/hardware/lowbu...
Here's what I mean. I develop a software/firmware stack that is typically delivered to users as a set of large (100M) tarballs and binary images. Even though the vast majority of the payload does not change from release to release, it really has proven necessary to distribute just the final blobs.
Technologically, it's almost identical, but distribution implies a different set of access controls and an Internet-friendly user interface.
I see the idea floating around in e.g. NextCloud forums but this seems like a relatively compact problem without a obvious candidates to solve it.
I understand why vendors ship tools with all of these things. I think (hope?) they're slowly un-bundling more and more of the toolflow so you can avoid them if you want.
That said, a solid, open-source, mixed-language simulator with good SystemVerilog and VHDL-2008 support would change my life. Bonus points if I can embed it in C/C++ code a la Verilator. And, while I'm asking, can it simulate encrypted IP too?
This is one of the places where HLS may sideswipe the traditional RTL market: if you can effectively develop FPGA designs in C++, the entire approach to development/testing/integration changes completely. It may sound like a detail, but it touches every single pain point associated with a complex FPGA design.
A jaded RTL engineer may fairly ask, "what's different this time?" I'm convinced it's two things:
1. These chips have scaled to the point where the toolflow isn't just annoying, it's crippling. (I say that as an RTL designer who likes Vivado, believe it or not.) Making effective use of the largest FPGAs in traditional FPGA applications is difficult enough. Plus, the marginal cost of baking e.g. ARM cores onto an FPGA is now so low that these parts are quickly becoming heterogeneous SoCs and it requires extensive cross-domain knowledge to get a modern design off the ground. More importantly, though, Xilinx is trying to expand FPGAs beyond traditional FPGA markets, and it can't do so without expanding the pool of available talent to program them. Finally, new FPGA applications (e.g. AI) come with their own technical arcana and finding FPGA designers who are proficient in all of these domains is only growing harder. It is necessary for the tools to help, and Xilinx is amply incentivized to pour money into the R&D programs necessary, even if the new tools are simply bundled alongside the old ones.
2. This may be a surprise, but LLVM. Doing HLS correctly is a forced march through every conceivable corner of compiler, language, and RTL design, and to date, that's been much too difficult for EDA companies. I believe that LLVM as an accessible compiler workshop has been instrumental to Xilinx's success to date.
I hope Xilinx does genuinely open-source some of the pieces. (Not the synthesis flow, in this case, but all the stuff built on top of it.) The open-source EDA community is small but motivated and talented, but it's crippled by balkanization caused by the commercial EDA market. This might be an interesting shot in the arm.
http://home.agh.edu.pl/~turcza/sr/Splitting%20the%20Unit%20D...
The effects you're describing (blurring, numerical stability) are readily formalized in DSP jargon. It's a shame this post didn't provoke more discussion here.
I've been watching compressed sensing (CS) from the sidelines for the past decade, while wearing experimental-cosmology, synthetic-aperture RADAR, and instrumentation/FPGA hats. (Not electrodynamics or optics, per your question, but nearby.) Here's my perspective.
If you're doing compressed sensing correctly, it transforms the entire instrument from electrically complex and algorithmically simple, to algorithmically complex and electrically simple. Unfortunately this isn't a strategy you can bolt on to a traditional architecture and turn off as a de-risking strategy if it doesn't work. From the perspective of a team building a tool to accomplish a task, it's an all-or-nothing gamble. Consequently, the challenges to aggressive adoption of CS are both technical (can it work?) and programmatic (is it feasible given human, political, and financial constraints?)
In the fields I've been exposed to, state-of-the-art instrumentation is complex enough that domain experts spend their entire careers understanding the quirks of a few established instrument topologies. Where CS is applicable, it would take a big leap of faith from an entire team to build an instrument around CS. Before that leap of faith is accessible, the team would have to be conversant in CS research and the implementation of CS algorithms in practice. And, after the leap of faith, a successful CS project requires secondary leaps of faith from funding agencies to get these instruments built. These barriers are highest for exactly the kind of complex, expensive projects where CS is supposed to shine.
As an aside, the latest IEEE Signal Processing magazine (https://ieeexplore.ieee.org/document/8653526) has an interesting article on hardware architectures for compressed sensing. As CS progresses, and as CS researchers transition from pure-CS research to applied-CS techniques, the use of CS in physics will probably grow.
Unfortunately, a lot of this research was buried in microfiche in university basements as Bell Labs' legacy was traded from company to company without a viable distribution mechanism. As a result, although this work is now all available on-line (sadly not in open-access form), there are still more forgotten gems in there than many researchers realize.