stanford-ppl / spatial

Spatial: "Specify Parameterized Accelerators Through Inordinately Abstract Language"
https://spatial.stanford.edu
MIT License
274 stars 32 forks source link

Optimize datapath bitwidths #288

Open mattfel1 opened 4 years ago

mattfel1 commented 4 years ago

We can do much better on timing and resource utilization if we make the datapath for a controller like this 3 bits instead of the full 32.

// N is either static or has its bound(N) defined
Foreach(N by 1){ i => F(i) }
kumasento commented 4 years ago

Hi @mattfel1 I'm interested in working on this :) Hope it is possible.

My impression on how to proceed is as follows:

  1. Update the ForeachClass to use Counter[Bits] instead of Counter[I32]
  2. Update OpForeach to take care of the iters parameter in OpForeach

I will try these very soon and see what I'm missing here.

kumasento commented 4 years ago

I think maybe a simpler solution is to implement a new transformer that creates new counters with bitwidth-reduced data type.

One thing I'm not sure about is whether there is an API that counts the least number of bits required for a given input number. I've created my own helper function, but it would be better if there is something in the codebase that I can reuse.

mattfel1 commented 4 years ago

Hi. Thanks so much for the help! I think this optimization will have a big impact on a lot of apps. I'm looking forward to seeing how it goes.

For some of the banking analysis and chisel templates, we call on functions in utils/math/package.scala, which has things like log2Up that is often used to set a bit width. Are these the kinds of things you are looking for?

kumasento commented 4 years ago

Thanks @mattfel1 ! log2Up should be helpful. I will get back to you once I make any progress.

I will create a PR and list all the things to do there.

kumasento commented 4 years ago

Hi @mattfel1 I've got a trivial question about the type system in Spatial.

The parameters in CounterNew are of type Num[T], which makes sense, but I'm struggling to get extract their values to the Java/Scala type system, such that I can calculate the bitwidth.

I'm just wondering is it possible to do that, and if so, is there any code example in this repository? I've searched for quite a lot of examples that uses I32 but I haven't found one that casts I32 to Int yet.

Thanks!

kumasento commented 4 years ago

I just realized I can use .c to access the content of a Const :)

mattfel1 commented 4 years ago

For Const, we often do things like x match {case Const(c:Int) => }. For other situations, if you do bound(x) = 512 in an app, it sets the metadata x.bound to UpperBound(512), which may be useful also. It's a little confusing, but this is different from the "Bound" sym, which refers to iterators and enable signals defined at the boundary of a block (b### symbols)