For the following fragment Chisel synthesized none:
import Chisel._
import Node._
import scala.collection.mutable.HashMap
class PseudoLRU(val num_ways: Int) extends Module
{
val num_levels = log2Up(num_ways)
val io = new Bundle {
val last_used_cline = UInt(INPUT, width = num_levels)
val update_state = Bool(INPUT)
}
val state = Reg(Vec.fill(num_ways-1){Bool()})
private val msb = num_levels - 1
when (io.update_state) {
// process level 0
state(0) := !io.last_used_cline(msb, msb) // get the most significant bit
// process other levels
for (level <- 1 until num_levels) {
val offset = UInt((1 << level) - 1, width = log2Up(num_ways-1))
val bit_index = io.last_used_cline(msb, msb - level + 1) + offset
val pos = msb - level
val bit = io.last_used_cline(pos, pos)
state(bit_index) := !bit
}
}
}
object test_driver {
def main(args: Array[String]): Unit = {
val plru_inst = () => Module(new PseudoLRU(num_ways = 16))
chiselMain(args, plru_inst)
}
}
The same behavior if manually unroll the loop for (level <- 1 until num_levels) and fold constants:
when (io.update_state) {
state( 0 ) := !io.last_used_cline(3, 3)
state( io.last_used_cline(3, 3) + UInt(1, width = 3) ) := !io.last_used_cline(2, 2)
state( io.last_used_cline(3, 2) + UInt(3, width = 3) ) := !io.last_used_cline(1, 1)
state( io.last_used_cline(3, 1) + UInt(7, width = 3) ) := !io.last_used_cline(0, 0)
}
The generated verilog (and similar C++ code) for both snippets (original and unrolled/instantiated for 16 ways case):
module PseudoLRU(input reset,
input [3:0] io_last_used_cline,
input io_update_state
);
wire T0;
wire[151:0] T1;
assign T0 = ! reset;
endmodule
Don't quite get why there are only dummy constructs What should I do to enforce synthesis of the logic? Thanks!
Chisel will aggressively prune signals in your design if they are not hooked up to anything.
It looks like in your case you have no OUTPUTS from PsuedoLRU, only inputs "last_used_cline" and "update_state". It's just like writing a function in C/C++ and not doing anything with a function's results.
Now in C, you can tag the variable(s) as "volatile" to trick the compiler into keeping your code around (you're promising that somebody else is going to use the value of that variable). In Chisel, you can use "debug()" to force signals to exist.
I believe to force your Vec of Regs to exist, you can do this:
for (i <- 0 until num_ways)
debug(state(i))