package jazz.circuit;

///////////////////////////////////////////////////////////////////////////////
//
//                           Streams (array of nets)
//
///////////////////////////////////////////////////////////////////////////////

final public class Stream implements BooleanAlgebra {
  // The nets of that stream
  public nets: Net[];

  // The delay operator on streams
  public static reg(s: Stream): Stream;

  // The constant generator on streams
  public static constant(c: per): Stream;
}


///////////////////////////////////////////////////////////////////////////////
//
//                               Implementation
//
///////////////////////////////////////////////////////////////////////////////

// The delay and boolean operators on streams
Stream.reg(s: Stream) = new Stream(nets = [i -> Net.reg(s.nets[i])]);
Stream.constant(c: per) = new Stream(nets = [i -> Net.constant(c)]);

// Implement all the boolean algebra operators on streams
Builtin.(&)(x@Stream, y@Stream) =
  new Stream(nets = [i -> x.nets[i] & y.nets[i]]);

Builtin.(|)(x@Stream, y@Stream) =
  new Stream(nets = [i -> x.nets[i] | y.nets[i]]);

Builtin.(^)(x@Stream, y@Stream) =
  new Stream(nets = [i -> x.nets[i] ^ y.nets[i]]);

Builtin.(~)(x@Stream) =
  new Stream(nets = [i -> ~x.nets[i]]);

Builtin.cond(c@Stream, x@Stream, y@Stream) =
  new Stream(nets = [i -> Net.mux(c.nets[i], x.nets[i], y.nets[i])]);