HN user

1024bees

61 karma
Posts2
Comments9
View on HN

Oops, I assumed maybe too much familiarity with the problem. The premise of the problem is this:

You're designing a CPU, either for your job or for fun, in your favourite hardware description language. Systemverilog, vhdl, hell maybe you went to Berkeley/ work at sifive and you use chisel. if you aren't familiar with HDLs or digital logic design, you should look into them, it is fun.

to test your CPU, you use a simulator, and give your simulated CPU a program to execute. But shit -- you have a bug, and some instruction is producing the wrong value. It would be really nice to step through the code and see what was happening inside your CPU to pinpoint where the bug is.

At this point, you can tell the simulator to generate a waveform (some call it a dump, maybe there are other names). The waveform will contain every signal inside of your design -- every clock, every control signal, you name it. This is typically a MASSIVE amount of data, and people analyze these waveforms. And worse yet, you just have "raw signals". To find out what PC is being executed, you have to pull up the PC signal in the waveform viewer, and then all of the register signals, and then cross correlate that with the disassembly; in short, you get very intimate information about the design, but organizing that information is the responsibility of the person using the waveform viewer, and it can be tedious.

The insight this tool makes is that all of the data you need to have a gdb-like interface when debugging a simulated CPU is already in the waveform, jpdb just organizes and presents the data in a way that is easy for the developer to parse.

It's nice to see a microarchitecture take a risk, and getting perspective on how this design performs with respect to performance, power and area would be interesting.

Very unlikely to me that this design would have comparable "raw" performance to a design that implements something closer to tomasulo's algorithm. The assumption that the latency of a load will be a l1 hit is a load bearing abstraction; I can imagine scenarios where this acts as a "double jeopardy" causing scheduling to lock up because the latency was mispredicted, but one could also speculate that isn't important because the workload is already memory bound.

There's an intuition in computer architecture that designs that lean on "static" instruction scheduling mechanisms are less performant than more dynamic mechanisms for general purpose compute, but we've had decades of compiler development since itanium "proved" this. Efficient computer (or whatever their name is) is doing something cool too, it's exciting to see where this will go

A point of frustration for newer languages, that sus continues, is the lack of thought towards simulation and testbench design, and how it integrates with the language.

While it would be nice to have more elegant support for "modern" codegen in the sv/verilog/vhdl, the real unergonomic experiences are test bench design and integration. The only real options are (for sv, verilog, I have less experience with vhdl): use verilator and write your tb in cpp, use verilator and then write your testbench in cocotb, or you work at a chip design company and use one of the big 3's compilers and maybe you use UVM or cocotb. Verilator and cocotb are okay, but you're crossing a language boundar(ies) and referencing generated code -- it is both mechanical and complex to get any design working with it.

If sus had first class interfaces to create testbenches that could map to UVM or verilator, it would be much more interesting. Spade does some interesting things by having its own package manager, but doesn't (afaik) expose a ton within the language itself

There is a natural tension between developing an API that is nice to use and having a full fledged graph compiler. Most graph compilers, and the hardware that requires them will be complex and difficult to approach. The "original sin" was pytorch vs tensorflow -- tensorflow capturing the entire graph and then compiling it with XLA (or whatever it was before, I'm probably mixing up tf1 and tf2 here) was such an intractable mess to actually hack on (also the runtime had unapproachable complexity, from what I recall). This has probably changed, but pytorch won out because it was both nice to use and develop.

There are clear reasons why a hardware company would use a graph compiler -- they think such an approach is higher performance, and makes tenstorrent look better on price per dollar when compared to competitors (read: nvda).

There is some legitimate criticism of TT here, their hardware is composed or simple blocks that compose into a complex system (5 separate CPUs being programmed per tensix tile, many tiles per chip), and that complexity has to be wrangled in the software stack -- paying that complexity in hardware so there is less of a VLIW model in software might remove a few abstractions.

Smelt is build system agnostic, but it seeks to be the "invoker" so to speak -- we've used it with a many build systems including make, cmake and bazel.

There are a few reasons to separate build and test systems:

build systems struggle to express constrained random testing, and some build systems even struggle to express directed testing sweeps, which are common patterns in design verification.

The other reason is that testing is often treated as a "leaf node" in a build graph, and it's not possible to describe tests depending on other tests.

Overall, testing is a different problem than building, and circuit design often requires complex testing flows that build systems aren't designed for.

Thanks for checking out smelt!

Reproducible seeding, and more generically having "test list arguments" are definitely something we have in our view, and wouldn't be outside the scope of the project

Tagging is an interesting problem -- do you find that you use any querying schemes emerge when trying to run a specific set of tests, or is running a test group named "A" normally suffice? Test tagging should be on the roadmap, thanks for calling it out.

Re:test weighting, unsure what you're describing exactly -- would you like to have a mechanism to describe how many times a "root test" has been duplicated with some sampling of random input parameters?

I appreciate the code snippets they put in the pub; when HW papers abstract that out, the system doesn't feel grounded in reality. Still, the open problem for this class of architecture IMO is programmability. A composable, well designed API for many core machines would be worth it's weight in gold.