quaigh icon indicating copy to clipboard operation
quaigh copied to clipboard

patch: support lut simulation

Open ClSlaid opened this issue 1 year ago • 3 comments

This little patch adds support for simulating LUTs, along with some more unit tests

ClSlaid avatar Oct 06 '24 17:10 ClSlaid

Hi! Thank you for your contribution. The current code is incorrect, as it needs to work on 64-bit values for the general case

Coloquinte avatar Oct 06 '24 21:10 Coloquinte

You mean that signals could be wider than 1 bit? It's troublesome since I don't know where to get the width of signals. In fact, I even don't really understands the current representation of the LUT...

I thought the LUT might expecting multiple inputs, and each input occupies a specific width of bits, like:

i0[1:0] = 0b'11
i1[1:0] = 0b'10

LUT4: .input = {i0[1:0], i1[1:0]} = 0b'1110
// output = 0b'1 when number of '1's are even
// output = 0b'0 otherwise

then LUT.output = 0b'1

Or we just should need to or all inputs

i0[1:0] = 0b'11
i1[1:0] = 0b'10

LUT2: .input = i0|i1 = 0b'11
// output = 0b'1 when number of '1's are even
// output = 0b'0 otherwise

then LUT.output = 0b'1

Can you give me a few examples of what we are expecting?

ClSlaid avatar Oct 07 '24 03:10 ClSlaid

Here await for your suggestions.

ClSlaid avatar Oct 13 '24 04:10 ClSlaid

Sorry for the late answer.

The width of signals is always 64 bits, representing 64 parallel simulations in a u64. For a simple gate, like an and or or, we can just do bitwise computations which are extremeley fast. Luts are more tricky, and would be difficult to make fast.

For a Lut, gt.lut.value returns the value of the Lut for some bit value of the inputs. A simple implementation would be to do that for all 64 values, and pack the results back in a u64.

So :

  • loop on i from 0 to 63
  • access the bit i for each input (val >> i) & 1
  • pack those bits in a usize. Input 0 is bit 0, Input 1 is bit 1... You may just iterate in the inputs and shift by 1 each time
  • compute lut.value for that usize
  • set bit i of the result to that value result |= (val as u64) << i

An example: Lut2(0110) (a xor); input 0 is 010101, input 1 is 000111. Expected result is 010010, the bitwise xor of the two inputs.

Coloquinte avatar Oct 14 '24 19:10 Coloquinte

@Coloquinte PTAL.

ClSlaid avatar Oct 15 '24 13:10 ClSlaid

Nice bit of black magic with fold. Looks good to me, except for the comment I made

Coloquinte avatar Oct 18 '24 20:10 Coloquinte

This would be really cool- nl2bench currently splits complex gates into simpler gates so they can work with Quaigh, but that affects coverage calculation.

donn avatar Oct 20 '24 08:10 donn

@donn This will be dreadfully slow compared to the usual simulation - for ATPG in particular - but at least now it's supported. It's certainly possible to make it a lot faster for small Luts if that becomes an issue.

Coloquinte avatar Oct 20 '24 13:10 Coloquinte