chipsalliance / firrtl

Flexible Intermediate Representation for RTL
https://www.chisel-lang.org/firrtl/
Apache License 2.0
729 stars 177 forks source link

MatchError during RemoveCHIRRTL #121

Closed colinschmidt closed 8 years ago

colinschmidt commented 8 years ago

This is too vague of a report right now but I'm pasting this here so I don't lose it or forget about it: Will update later today.

/scratch/colins/rocket-chip/firrtl/utils/bin/firrtl -i /scratch/colins/rocket-chip/vsim/generated-src/Top.ISCA2016Config.fir -o /scratch/colins/rocket-chip/vsim/generated-src/Top.ISCA2016Config.v -X verilog
Exception in thread "main" scala.MatchError: (UnknownType(),UnknownType()) (of class scala.Tuple2)
        at firrtl.Utils$.get_valid_points(Utils.scala:326)
        at firrtl.passes.RemoveCHIRRTL$.firrtl$passes$RemoveCHIRRTL$$remove_chirrtl_s$1(Passes.scala:1952)
        at firrtl.passes.RemoveCHIRRTL$$anonfun$firrtl$passes$RemoveCHIRRTL$$remove_chirrtl_s$1$3.apply(Passes.scala:1966)
        at firrtl.passes.RemoveCHIRRTL$$anonfun$firrtl$passes$RemoveCHIRRTL$$remove_chirrtl_s$1$3.apply(Passes.scala:1966)
        at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:245)
        at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:245)
        at scala.collection.mutable.ResizableArray$class.foreach(ResizableArray.scala:59)
        at scala.collection.mutable.ArrayBuffer.foreach(ArrayBuffer.scala:48)
        at scala.collection.TraversableLike$class.map(TraversableLike.scala:245)
        at scala.collection.AbstractTraversable.map(Traversable.scala:104)
        at firrtl.Mappers$StmtMagnet$$anon$4.map(Mappers.scala:42)
        at firrtl.Mappers$StmtMap.map(Mappers.scala:95)
        at firrtl.passes.RemoveCHIRRTL$.firrtl$passes$RemoveCHIRRTL$$remove_chirrtl_s$1(Passes.scala:1966)
        at firrtl.passes.RemoveCHIRRTL$$anonfun$firrtl$passes$RemoveCHIRRTL$$remove_chirrtl_s$1$3.apply(Passes.scala:1966)
        at firrtl.passes.RemoveCHIRRTL$$anonfun$firrtl$passes$RemoveCHIRRTL$$remove_chirrtl_s$1$3.apply(Passes.scala:1966)
        at firrtl.Mappers$StmtMagnet$$anon$4.map(Mappers.scala:41)
        at firrtl.Mappers$StmtMap.map(Mappers.scala:95)
        at firrtl.passes.RemoveCHIRRTL$.firrtl$passes$RemoveCHIRRTL$$remove_chirrtl_s$1(Passes.scala:1966)
        at firrtl.passes.RemoveCHIRRTL$$anonfun$firrtl$passes$RemoveCHIRRTL$$remove_chirrtl_s$1$3.apply(Passes.scala:1966)
        at firrtl.passes.RemoveCHIRRTL$$anonfun$firrtl$passes$RemoveCHIRRTL$$remove_chirrtl_s$1$3.apply(Passes.scala:1966)
        at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:245)
        at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:245)
        at scala.collection.mutable.ResizableArray$class.foreach(ResizableArray.scala:59)
        at scala.collection.mutable.ArrayBuffer.foreach(ArrayBuffer.scala:48)
        at scala.collection.TraversableLike$class.map(TraversableLike.scala:245)
        at scala.collection.AbstractTraversable.map(Traversable.scala:104)
        at firrtl.Mappers$StmtMagnet$$anon$4.map(Mappers.scala:42)
        at firrtl.Mappers$StmtMap.map(Mappers.scala:95)
        at firrtl.passes.RemoveCHIRRTL$.firrtl$passes$RemoveCHIRRTL$$remove_chirrtl_s$1(Passes.scala:1966)
        at firrtl.passes.RemoveCHIRRTL$.firrtl$passes$RemoveCHIRRTL$$remove_chirrtl_m$1(Passes.scala:1971)
        at firrtl.passes.RemoveCHIRRTL$$anonfun$103.apply(Passes.scala:1975)
        at firrtl.passes.RemoveCHIRRTL$$anonfun$103.apply(Passes.scala:1973)
        at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:245)
        at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:245)
        at scala.collection.mutable.ResizableArray$class.foreach(ResizableArray.scala:59)
        at scala.collection.mutable.ArrayBuffer.foreach(ArrayBuffer.scala:48)
        at scala.collection.TraversableLike$class.map(TraversableLike.scala:245)
        at scala.collection.AbstractTraversable.map(Traversable.scala:104)
        at firrtl.passes.RemoveCHIRRTL$.run(Passes.scala:1973)
        at firrtl.passes.PassUtils$.executePasses(Passes.scala:89)
        at firrtl.VerilogCompiler$.run(Compiler.scala:93)
        at firrtl.Driver$.compile(Driver.scala:53)
        at firrtl.Driver$.main(Driver.scala:94)
        at firrtl.Driver.main(Driver.scala)
make: *** [/scratch/colins/rocket-chip/vsim/generated-src/Top.ISCA2016Config.v] Error 1
jackkoenig commented 8 years ago

The problem is at line 180755 of hwacha.fir, we have the following chirrtl:

  module Queue_824 :
    ...
      T_6898.lane is invalid
      T_6898.lane[0] <- T_7635
      infer mport T_6898 = ram[T_6884], clk
      T_6898 <- io.enq.bits

T_6898 is being used before it is declared. Also, the ram being referred to is the following (if that's helpful):

    cmem ram : {fn : {union : UInt<10>}, sreg : {ss1 : UInt<64>, ss2 : UInt<64>, ss3 : UInt<64>}, 
base : {vp : {id : UInt<4>, valid : UInt<1>, scalar : UInt<1>, pred : UInt<1>}, vs1 : {id : UInt<8>, 
valid : UInt<1>, scalar : UInt<1>, pred : UInt<1>, prec : UInt<2>}, vs2 : {id : UInt<8>, valid : UInt<1>, 
scalar : UInt<1>, pred : UInt<1>, prec : UInt<2>}, vs3 : {id : UInt<8>, valid : UInt<1>, scalar : UInt<1>, 
pred : UInt<1>, prec : UInt<2>}, vd : {id : UInt<8>, valid : UInt<1>, scalar : UInt<1>, pred : UInt<1>, 
prec : UInt<2>}}, reg : {vp : {id : UInt<8>}, vs1 : {id : UInt<8>}, vs2 : {id : UInt<8>}, vs3 : {id : UInt<8>}, 
vd : {id : UInt<8>}}, active : {vint : UInt<1>, vipred : UInt<1>, vimul : UInt<1>, vidiv : UInt<1>, 
vfma : UInt<1>, vfdiv : UInt<1>, vfcmp : UInt<1>, vfconv : UInt<1>, vrpred : UInt<1>, vrfirst : UInt<1>, 
vamo : UInt<1>, vldx : UInt<1>, vstx : UInt<1>, vld : UInt<1>, vst : UInt<1>}, lane : {active : UInt<1>, 
vlen : UInt<12>}[1]}[2]
jackkoenig commented 8 years ago

It seems to me that in order to catch this, we need some CheckCHIRRTL pass that is analogous to the current CheckHighForm which would've caught this with a more elegant error had it been FIRRTL code

jackkoenig commented 8 years ago

Queue_824 is instantiated in module RPredMaster : with the name inst opq of Queue_824

colinschmidt commented 8 years ago

The queue instantiation looks normal

val opq = Module(new Queue(new IssueOpML, 2))
azidar commented 8 years ago

Ideally, Chisel should never allow a user to generate code that declares something before it is used - that was the assumption used by the CHIRRTL passes. Chisel can't do a good job of this, though, then we should certainly write the CheckHighForm pass on CHIRRTL.

jackkoenig commented 8 years ago

Yeah fair point, I guess we'll see how exactly this is happening. Kind of weird though, it appears to be coming from the implementation of Queue

jackkoenig commented 8 years ago

Just looking at the generated FIRRTL, there's a bunch of weird stuff going on:

  module Queue_824 :
    input clk : Clock
    input reset : UInt<1>
    output io : {flip enq : {flip ready : UInt<1>, valid : UInt<1>, bits : {fn : {union : UInt<10>}, sreg : {ss1 : UInt<64>, ss2 : UInt<64>, ss3 : UInt<64>}, base : {vp : {id : UInt<4>, valid : UInt<1>, scalar : UInt<1>, pred : UInt<1>}, vs1 : {id : UInt<8>, valid : UInt<1>, scalar : UInt<1>, pred : UInt<1>, prec : UInt<2>}, vs2 : {id : UInt<8>, valid : UInt<1>, scalar : UInt<1>, pred : UInt<1>, prec : UInt<2>}, vs3 : {id : UInt<8>, valid : UInt<1>, scalar : UInt<1>, pred : UInt<1>, prec : UInt<2>}, vd : {id : UInt<8>, valid : UInt<1>, scalar : UInt<1>, pred : UInt<1>, prec : UInt<2>}}, reg : {vp : {id : UInt<8>}, vs1 : {id : UInt<8>}, vs2 : {id : UInt<8>}, vs3 : {id : UInt<8>}, vd : {id : UInt<8>}}, active : {vint : UInt<1>, vipred : UInt<1>, vimul : UInt<1>, vidiv : UInt<1>, vfma : UInt<1>, vfdiv : UInt<1>, vfcmp : UInt<1>, vfconv : UInt<1>, vrpred : UInt<1>, vrfirst : UInt<1>, vamo : UInt<1>, vldx : UInt<1>, vstx : UInt<1>, vld : UInt<1>, vst : UInt<1>}, lane : {active : UInt<1>, vlen : UInt<12>}[1]}}, deq : {flip ready : UInt<1>, valid : UInt<1>, bits : {fn : {union : UInt<10>}, sreg : {ss1 : UInt<64>, ss2 : UInt<64>, ss3 : UInt<64>}, base : {vp : {id : UInt<4>, valid : UInt<1>, scalar : UInt<1>, pred : UInt<1>}, vs1 : {id : UInt<8>, valid : UInt<1>, scalar : UInt<1>, pred : UInt<1>, prec : UInt<2>}, vs2 : {id : UInt<8>, valid : UInt<1>, scalar : UInt<1>, pred : UInt<1>, prec : UInt<2>}, vs3 : {id : UInt<8>, valid : UInt<1>, scalar : UInt<1>, pred : UInt<1>, prec : UInt<2>}, vd : {id : UInt<8>, valid : UInt<1>, scalar : UInt<1>, pred : UInt<1>, prec : UInt<2>}}, reg : {vp : {id : UInt<8>}, vs1 : {id : UInt<8>}, vs2 : {id : UInt<8>}, vs3 : {id : UInt<8>}, vd : {id : UInt<8>}}, active : {vint : UInt<1>, vipred : UInt<1>, vimul : UInt<1>, vidiv : UInt<1>, vfma : UInt<1>, vfdiv : UInt<1>, vfcmp : UInt<1>, vfconv : UInt<1>, vrpred : UInt<1>, vrfirst : UInt<1>, vamo : UInt<1>, vldx : UInt<1>, vstx : UInt<1>, vld : UInt<1>, vst : UInt<1>}, lane : {active : UInt<1>, vlen : UInt<12>}[1]}}, count : UInt<2>}

    io is invalid
    node T_80 = cat(T_53.fp, T_53.op)
    node T_81 = cat(T_53.dw, T_80)
    node T_133 = cat(T_107.dw, T_107.op)
    node T_160 = cat(T_134.dw, T_134.op)
    node T_188 = cat(T_161.rm, T_161.op)
    node T_189 = cat(T_161.fp, T_188)
    node T_217 = cat(T_190.rm, T_190.op)
    node T_218 = cat(T_190.fp, T_217)
    node T_246 = cat(T_219.rm, T_219.op)
    node T_247 = cat(T_219.fp, T_246)
    node T_275 = cat(T_248.rm, T_248.op)
    node T_276 = cat(T_248.fp, T_275)                                                                                                                                                                                                                                         
    node T_281 = cat(T_277.cmd, T_277.mt)
    node T_282 = cat(T_277.mode, T_281)
    wire lane : {active : UInt<1>, vlen : UInt<12>}[1]
    T_5.lane is invalid
    T_5.lane[0] <- T_742
    node T_846 = cat(T_819.fp, T_819.op)
    node T_847 = cat(T_819.dw, T_846)
    node T_899 = cat(T_873.dw, T_873.op)
    node T_926 = cat(T_900.dw, T_900.op)
    node T_954 = cat(T_927.rm, T_927.op)
    node T_955 = cat(T_927.fp, T_954)
    node T_983 = cat(T_956.rm, T_956.op)
    node T_984 = cat(T_956.fp, T_983)
    node T_1012 = cat(T_985.rm, T_985.op)
    node T_1013 = cat(T_985.fp, T_1012)
    node T_1041 = cat(T_1014.rm, T_1014.op)
    node T_1042 = cat(T_1014.fp, T_1041)
    node T_1047 = cat(T_1043.cmd, T_1043.mt)    
    node T_1048 = cat(T_1043.mode, T_1047)    
    wire lane : {active : UInt<1>, vlen : UInt<12>}[1]    
    T_771.lane is invalid
...

wire lane is declared multiple times, it's always followed with some T_#.lane is invalid as if its a mem or an instance rather than a wire. What's going on inside of this type?

colinschmidt commented 8 years ago

That bundle has a Vec.fill(n){new InnerBundle} that when corrected, no longer produces the above match error.

jackkoenig commented 8 years ago

I noticed that in the Chisel source code

def apply[T <: Data](n: Int, gen: T): Vec[T] = new Vec(gen.cloneType, n)
...
def fill[T <: Data](n: Int)(gen: => T): Vec[T] = apply(Seq.fill(n)(gen))

Is there a reason why fill can't just call apply(gen, n)?

aswaterman commented 8 years ago

They don't mean the same thing... fill is used for broadcasting a data value across the elements in a Vec (which is mostly only useful for initializing a Reg[Vec]). apply is used to create a type.

jackkoenig commented 8 years ago

Makes sense, and this explains to me why Vec.fill ends up wrapping the Vec in a Wire whereas standard apply does not

azidar commented 8 years ago

See #157.