chisel2-deprecated icon indicating copy to clipboard operation
chisel2-deprecated copied to clipboard

Erro in C++ backend : (error: ‘T54’ was not declared in this scope)

Open Martoni opened this issue 10 years ago • 0 comments

I have a problem with compiling a module that use two domain clock. I'm re-writting the AsyncFifo to include the ability to flush it. Here the code ::

class QueueIOFlush[T <: Data](gen: T, entries: Int) extends Bundle {
  val enq   = Decoupled(gen.cloneType).flip
  val deq   = Decoupled(gen.cloneType)
  val count = UInt(OUTPUT, log2Up(entries + 1))
  val flush = Bool(INPUT)
}

class AsyncFifoFlushable[T<:Data](gen: T, entries: Int, enq_clk: Clock, deq_clk: Clock) extends Module {
  val io = new QueueIOFlush(gen, entries)
  val asize = log2Up(entries)

  val s1_rptr_gray = Reg(init=UInt(0, asize+1), clock=enq_clk)
  val s2_rptr_gray = Reg(init=UInt(0, asize+1), clock=enq_clk)
  val s1_rst_deq = Reg(init=Bool(false), clock=enq_clk)
  val s2_rst_deq = Reg(init=Bool(false), clock=enq_clk)

  val s1_wptr_gray = Reg(init=UInt(0, asize+1), clock=deq_clk)
  val s2_wptr_gray = Reg(init=UInt(0, asize+1), clock=deq_clk)
  val s1_rst_enq = Reg(init=Bool(false), clock=deq_clk)
  val s2_rst_enq = Reg(init=Bool(false), clock=deq_clk)

  val s1_flush = Reg(init=Bool(false), clock=enq_clk)
  val s2_flush = Reg(init=Bool(false), clock=enq_clk)

  val wptr_bin = Reg(init=UInt(0, asize+1), clock=enq_clk)
  val wptr_gray = Reg(init=UInt(0, asize+1), clock=enq_clk)
  val not_full = Reg(init=Bool(false), clock=enq_clk)

  val wptr_bin_next = wptr_bin + (io.enq.valid & not_full)
  val wptr_gray_next = (wptr_bin_next >> UInt(1)) ^ wptr_bin_next
  val not_full_next = !(wptr_gray_next === Cat(~s2_rptr_gray(asize,asize-1), s2_rptr_gray(asize-2,0)))

  val rptr_bin = Reg(init=UInt(0, asize+1), clock=deq_clk)
  val rptr_gray = Reg(init=UInt(0, asize+1), clock=deq_clk)
  val not_empty = Reg(init=Bool(false), clock=deq_clk)

  val rptr_bin_next = rptr_bin + (io.deq.ready & not_empty)
  val rptr_gray_next = (rptr_bin_next >> UInt(1)) ^ rptr_bin_next
  val not_empty_next = !(rptr_gray_next === s2_wptr_gray)

  s2_rptr_gray := s1_rptr_gray; s1_rptr_gray := rptr_gray
  s2_rst_deq := s1_rst_deq; s1_rst_deq := enq_clk.getReset
  s2_wptr_gray := s1_wptr_gray; s1_wptr_gray := wptr_gray
  s2_rst_enq := s1_rst_enq; s1_rst_enq := deq_clk.getReset

  s1_flush := io.flush; s2_flush := s1_flush;
  debug(s2_flush)

  /* flush read pointer (deqclk) */
  when(io.flush) {
    rptr_bin := UInt(0, rptr_bin.getWidth())
  }.otherwise{
  rptr_bin := rptr_bin_next
  }

  /* flush write pointer (enqclk) */
  when(s2_flush) {
    wptr_bin := UInt(0, wptr_bin.getWidth())
  }.otherwise{
    wptr_bin := wptr_bin_next
  }

  wptr_gray := wptr_gray_next
  not_full := not_full_next && !s2_rst_deq

  rptr_gray := rptr_gray_next
  not_empty := not_empty_next && !s2_rst_enq

  io.enq.ready := not_full
  io.deq.valid := not_empty

  val mem = Mem(gen, 1 << asize, clock=enq_clk)
  when (io.enq.valid && io.enq.ready) {
    mem(wptr_bin(asize-1,0)) := io.enq.bits
  }
  io.deq.bits := mem(rptr_bin(asize-1,0))
}

If I instanciate this module in my main application ::

  val thefifo = Module(new AsyncFifoFlushable(Vec(Array(
              UInt(width=16), UInt(width=16), UInt(width=16),
              UInt(width=16), UInt(width=16), UInt(width=16))),
    FifoSize, Driver.implicitClock, serdesClk))

And if I drive the flush signal ::

  def fallingedge(x: Bool, clock: Clock) = !x && Reg(next=x, clock=clock)

  thefifo.io.flush := fallingedge(io.cameralink.fval, clock=serdesClk)

I've got this error when compiling the Cpp backend ::

[info] [0,926] g++ -c -o ./DDRCoeffRead-emulator.o  -I../ -Inull/csrc/  ./DDRCoeffRead-emulator.cpp RET 0
./DDRCoeffRead.cpp: In member function ‘void DDRCoeffRead_t::clock_lo_serdesClk(dat_t<1>)’:
./DDRCoeffRead.cpp:999:10: error: ‘T4’ was not declared in this scope
   { T5 = T4 & DDRCoeffRead__R53.values[0];}
          ^

As I can see in code generated, T4 is effectively not declared in the function ::

[...]
void DDRCoeffRead_t::clock_lo_serdesClk ( dat_t<1> reset ) {
  { DDRCoeffRead_thefifo__io_deq_valid.values[0] = DDRCoeffRead_thefifo__not_empty.values[0];}
  val_t T2;
  { T2 = DDRCoeffRead_thefifo__io_deq_ready.values[0] & DDRCoeffRead_thefifo__not_empty.values[0];}
  val_t T3;
  { T3 = T2 | 0x0L << 1;}
  { DDRCoeffRead_thefifo__rptr_bin_next.values[0] = DDRCoeffRead_thefifo__rptr_bin.values[0]+T3;}
  DDRCoeffRead_thefifo__rptr_bin_next.values[0] = DDRCoeffRead_thefifo__rptr_bin_next.values[0] & 0x3fL;
  val_t T5;
  { T5 = T4 & DDRCoeffRead__R53.values[0];}
[...]

It's seem like a bug in Cpp backend but maybe I wrote a wrong Chisel code ?

Martoni avatar Jul 16 '15 10:07 Martoni