clash-lang / clash-compiler

Haskell to VHDL/Verilog/SystemVerilog compiler
https://clash-lang.org/
Other
1.44k stars 154 forks source link

Unify blockram primitives #822

Open rowanG077 opened 5 years ago

rowanG077 commented 5 years ago

Currently I think the BlockRam part of the Clash API could really use some kind of overhaul.

I see a few issues with the current situation:

  1. Too many different functions to create a BlockRam sometimes with confusing names (blockRAM1 for instance).
  2. Clash is only able to create the most basic blockRAM. A blockRAM with a single read and write port which have the same data width and works with a single clock domain. Ideally I would like a user to be able to specify two clock domains and also that the input type and output type don't necessarily need to match. Clash would then need be able to pick the right primitive based on the types. This would allow the creation of asymmetric blockRAMS which can be used as a synchronization primitive.

I think we could move towards a situation where we have a single blockRAM function. And the actual implementation is inferred based on the types and parameters.

At least I know that Intel Quartus and the Cyclone V FPGA would support such a situation on the hardware level but I'm unfamiliar with other platform to make a call in that direction.

christiaanb commented 5 years ago

Simulation will have to match the synthesized RAMs, so this "picking" based on types will have to be done at the Haskell-level.

martijnbastiaan commented 5 years ago

Agreed @rowanG077. I'd additionally like to see the ability to reset blockrams. I've written some thoughts about that over here.

This would allow the creation of asymmetric blockRAMS which can be used as a synchronization primitive.

Would this be what you're looking for?

christiaanb commented 5 years ago

@martijnbastiaan That fifo sync uses asynchronous read ports, so might not synthesize to a blockRAM, which only have synchronous read ports.

christiaanb commented 5 years ago

@martijnbastiaan Although the address generator for the read port is based register-backed, which the synthesis tools might merge into the RAM; thus allowing synthesis to a blockRAM.

Only one way to find out: run it through a couple of synthesis tools

adamwalker commented 4 years ago

Just adding a few more (possibly Xilinx centric) features I would like blockRams to have:

I'm happy to help out writing templates and testing, especially on Xilinx devices.