(no title)
Lramseyer | 9 months ago
The challenge of a HDL over a regular sequential programming (software) language is that a software language is programmed in time, whereas a HDL is programmed in both space and time. As one HDL theory expert once told me "Too many high level HDLs try to abstract out time, when what they really need to do is expose time."
thezoq2|9 months ago
> The challenge of a HDL over a regular sequential programming (software) language is that a software language is programmed in time, whereas a HDL is programmed in both space and time. As one HDL theory expert once told me "Too many high level HDLs try to abstract out time, when what they really need to do is expose time."
That's an excellent quote, I might steal it :D In general, I think good abstractions are the ones that make important details explicit rather than ones that hide "uninteresting" details.
VonTum|9 months ago
Exactly! It's astounding how often the documentation of some vendor component has in the documentation: "data_out is valid 2 cycles after read_enable is asserted", and NOTHING in the actual module definition makes a mention of this. There's so much dumb and error-prone mental arithmetic designers have to do to synchronize such latencies.
Spade does make a nod at this, with its pipelining notation. The issue I have with it is that it takes a too simplistic approach to said port timings. In a Spade pipeline you separate "pipeline stages" by adding a "reg;" statement on its own line. (It's an approach shared by another language called TL-Verilog.). A consequence of this style is that all inputs arrive at the sime time (say cycle 0), and all results are produced at a second time (say cycle 5). This is irrespective of if an input is actually only ever needed in a final addition in cycle 4. It'll insert the 4 extra registers regardless. Likewise, it leads to unnatural expression of subpipelines, where syntactically you can already see a value, but can only _access_ it 3 pipeline stages later.
With SUS, I have a solution to this: Latency Counting. (Intro here: https://m.youtube.com/watch?v=jJvtZvcimyM&t=937). A similar philosophy is also followed by Filament, though they go a step further with adding validity intervals too.
The gist of Latency Counting is that Instead of explicitly marking and naming "Pipeline stages", you annotate a statement to say that it "takes one cycle", and through exploring the dependency graph between your wires, it assigns a unique "absolute latency" to every wire, and places registers accordingly. (And now it can even infer submodule parameters based on this pipelining, in a bid to do HLS-style design in an RTL language).
sitkack|9 months ago
I have looked at TL-Verilog, I love the language, I am on the fence with the syntax, which arguably, is nearly an inconsequential nit given how far languages and tools need to progress.
https://github.com/TL-X-org/TL-V_Projects
Wow, a TL-Verilog video! https://www.youtube.com/watch?v=o2epusH-fXI
etep|9 months ago