aboutsummaryrefslogtreecommitdiff
path: root/src/main/scala/midas/Utils.scala
blob: e9c68201788962aae14ada3145a367e7c256f807 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
package midas

import firrtl._

object Utils {

  // Takes a set of strings or ints and returns equivalent expression node
  //   Strings correspond to subfields/references, ints correspond to indexes
  // eg. Seq(io, port, ready)    => io.port.ready
  //     Seq(io, port, 5, valid) => io.port[5].valid
  //     Seq(3)                  => UInt("h3")
  def buildExp(names: Seq[Any]): Exp = {
    def rec(names: Seq[Any]): Exp = {
      names.head match {
        // Useful for adding on indexes or subfields
        case head: Exp => head 
        // Int -> UInt/SInt/Index
        case head: Int => 
          if( names.tail.isEmpty ) // Is the UInt/SInt inference good enough?
            if( head > 0 ) UIntValue(head, UnknownWidth) else SIntValue(head, UnknownWidth)
          else Index(rec(names.tail), head, UnknownType)
        // String -> Ref/Subfield
        case head: String => 
          if( names.tail.isEmpty ) Ref(head, UnknownType)
          else Subfield(rec(names.tail), head, UnknownType)
        case _ => throw new Exception("Invalid argument type to buildExp! " + names)
      }
    }
    rec(names.reverse) // Let user specify in more natural format
  }
  def buildExp(name: Any): Exp = buildExp(Seq(name))

  def genPrimopReduce(op: Primop, args: Seq[Exp]): DoPrimop = {
    if( args.length == 2 ) DoPrimop(op, Seq(args.head, args.last), Seq(), UnknownType)
    else DoPrimop(op, Seq(args.head, genPrimopReduce(op, args.tail)), Seq(), UnknownType)
  }

  // For a port that is known to be of type BundleType, return the fields of that bundle
  def getFields(port: Port): Seq[Field] = {
    port.tpe match {
      case b: BundleType => b.fields
      case _ => throw new Exception("getFields called on invalid port " + port)
    }
  }

  // Queue
  /*
   module Queue :
    input clock : Clock
    input reset : UInt<1>
    output io : {flip enq : {flip ready : UInt<1>, valid : UInt<1>, bits : UInt<32>}, deq : {flip ready : UInt<1>, valid : UInt<1>, bits : UInt<32>}, count : UInt<3>}

    io.count := UInt<1>("h00")
    io.deq.bits := UInt<1>("h00")
    io.deq.valid := UInt<1>("h00")
    io.enq.ready := UInt<1>("h00")
    cmem ram : UInt<32>[4], clock
    reg T_26 : UInt<2>, clock, reset
    onreset T_26 := UInt<2>("h00")
    reg T_28 : UInt<2>, clock, reset
    onreset T_28 := UInt<2>("h00")
    reg maybe_full : UInt<1>, clock, reset
    onreset maybe_full := UInt<1>("h00")
    node ptr_match = eq(T_26, T_28)
    node T_33 = eq(maybe_full, UInt<1>("h00"))
    node empty = and(ptr_match, T_33)
    node full = and(ptr_match, maybe_full)
    node maybe_flow = and(UInt<1>("h00"), empty)
    node do_flow = and(maybe_flow, io.deq.ready)
    node T_39 = and(io.enq.ready, io.enq.valid)
    node T_41 = eq(do_flow, UInt<1>("h00"))
    node do_enq = and(T_39, T_41)
    node T_43 = and(io.deq.ready, io.deq.valid)
    node T_45 = eq(do_flow, UInt<1>("h00"))
    node do_deq = and(T_43, T_45)
    when do_enq :
      infer accessor T_47 = ram[T_26]
      T_47 := io.enq.bits
      node T_49 = eq(T_26, UInt<2>("h03"))                                                                                                                                                                                                    
      node T_51 = and(UInt<1>("h00"), T_49)
      node T_54 = addw(T_26, UInt<1>("h01"))
      node T_55 = mux(T_51, UInt<1>("h00"), T_54)
      T_26 := T_55
      skip
    when do_deq :
      node T_57 = eq(T_28, UInt<2>("h03"))
      node T_59 = and(UInt<1>("h00"), T_57)
      node T_62 = addw(T_28, UInt<1>("h01"))
      node T_63 = mux(T_59, UInt<1>("h00"), T_62)
      T_28 := T_63
      skip
    node T_64 = neq(do_enq, do_deq)
    when T_64 :
      maybe_full := do_enq
      skip
    node T_66 = eq(empty, UInt<1>("h00"))
    node T_68 = and(UInt<1>("h00"), io.enq.valid)
    node T_69 = or(T_66, T_68)
    io.deq.valid := T_69
    node T_71 = eq(full, UInt<1>("h00"))
    node T_73 = and(UInt<1>("h00"), io.deq.ready)
    node T_74 = or(T_71, T_73)
    io.enq.ready := T_74
    infer accessor T_75 = ram[T_28]
    node T_76 = mux(maybe_flow, io.enq.bits, T_75)
    io.deq.bits := T_76
    node ptr_diff = subw(T_26, T_28)
    node T_78 = and(maybe_full, ptr_match)
    node T_79 = cat(T_78, ptr_diff)
    io.count := T_79
  */ 

}