Creating a GPU With C++ and an FPGA (2021)
youtube.com
youtube.com
While an impressive feat (a complex picture in just a few lines of C++) it's sadly very misleading. His design relies on evaluating one big expensive logic cloud for every pixel. That same design would be only fractionally more complex in an HDL (like SystemVerilog). However this naive approach doesn't scale at all as the time window for the logic window is fixed and there's only so much you can do in each step. You quickly need to start pipelining which Vivado can do, but where the abstraction falls apart completely is when datapaths have loops or the pipeline has complicated control (even a simple five-stage cpu pipeline).
I'm been waiting for a better approach for 20+ years. Examples that I think better handles complex pipelines (without just sticking together the whole thing manually, like Verilog, Chisel, MyHDL, etc) include Handel-C and Silice. I hope some HNers will tell me I'm wrong and share a much better option. (I would love something that fells like Rust but can describe complex pipelines).
See where they show the block diagram in Vivado? That's the difficult part. You had to use the clock wizard to configure the PLL. You had to figure out how to convert the generated Verilog into one of those blocks. You had to choose the I/O standards, assign the pinout and set up timing constraints. You had to figure out how to get the block diagram saved into version control..
That block diagram is stored as, you guessed it, an XML file. But it can also be generated from or saved as a TCL script.. Also it has an associated Verilog wrapper... If it gets messed up, you will be editing the XML file..
If they really want to make Vivado easier to use, that block diagram would be gone.
(* X_INTERFACE_INFO = "xilinx.com:signal:clock:1.0 clk CLK" *)
(* X_INTERFACE_PARAMETER = "ASSOCIATED_BUSIF disp1_tpg_axis:disp2_tpg_axis:ar_tpg_axis:artx0_axis:arrx0_axis:scaletx0_axis:tmrx0_axis:scaler, ASSOCIATED_RESET reset_l, FREQ_HZ 199980011" *)
input clk;
(* X_INTERFACE_INFO = "xilinx.com:signal:reset:1.0 reset_l RST" *)
(* X_INTERFACE_PARAMETER = "POLARITY ACTIVE_LOW" *)
input reset_l;
(* X_INTERFACE_INFO = "xilinx.com:interface:rx_mipi_ppi_if:1.0 cam0_rx_dphy DL3_RXDATAHS" *)
input [7:0] cam0_rx_dphy_dl3_rxdatahs;
It's horrible. Trust me, you will not like when things go wrong in larger block designs.It's clear you have been burned, but I'm genuinely curious as to how. I've always found it to be smooth, and you can write a tcl representation of your bd for safe keeping, and what is generated is very readable (write_bd_tcl)
It's kind of sad how much work programmers create for themselves when they don't understand logic design.
The C++ being written in this example also feels like it has to be very carefully considered (and with a bunch of pragmas) so it doesn't feel like C++, it feels like a C++ syntax on top of Verilog or VHDL. Maybe this could still be quite useful, though. I guess simulating might be easier when you can start out with C++ code.
What I was referring to was standards like SYSCL, which is basically the competition to CUDA nowadays, and is being embraced, if one believes on Khronos updates.
As for HDLs, it is clear it will still take time, however Intel and Xilink seem keen in giving an helping hand.
FGPA using c/c++ for high level design has been in existence for years, not really caught on, and unlikely will make any dent in the near future.