ReadyValidFifo<LogicType extends LogicStructure> constructor

ReadyValidFifo<LogicType extends LogicStructure>({
  1. required Logic clk,
  2. required Logic reset,
  3. required ReadyValidInterface<LogicType> upstream,
  4. required ReadyValidInterface<LogicType> downstream,
  5. int depth = 8,
  6. String name = 'ready_valid_fifo',
})

Constructs a new ReadyValidFifo.

Implementation

ReadyValidFifo({
  required Logic clk,
  required Logic reset,

  /// Templates describing the shape of the upstream/downstream data
  required ReadyValidInterface<LogicType> upstream,
  required ReadyValidInterface<LogicType> downstream,
  this.depth = 8,
  String name = 'ready_valid_fifo',
}) : super(
          definitionName: 'ReadyValidFifo_${upstream.data.name}',
          name: name) {
  // Build the internal logic
  final writeEnable = Logic(name: '${name}_write_en');
  final readEnable = Logic(name: '${name}_read_en');

  // Add clock/reset ports and capture the module-local signals
  this.clk = addInput('clk', clk);
  this.reset = addInput('reset', reset);

  // Clone and connect the provided interfaces to module-local interfaces
  // (consumer role for upstream, provider role for downstream).
  this.upstream = upstream.clone()
    ..pairConnectIO(this, upstream, PairRole.consumer,
        uniquify: (original) => 'upstream_$original');

  this.downstream = downstream.clone()
    ..pairConnectIO(this, downstream, PairRole.provider,
        uniquify: (original) => 'downstream_$original');

  // Use the upstream data shape as a template for FIFO element.
  final writeData = this.upstream.data.clone() as LogicType;

  fifo = Fifo<LogicType>(this.clk, this.reset,
      writeEnable: writeEnable,
      readEnable: readEnable,
      writeData: writeData,
      depth: depth,
      generateOccupancy: true,
      name: '${name}_fifo');

  // Connect upstream valid/data to FIFO write when not full.
  writeEnable <= this.upstream.valid & ~fifo.full;
  writeData <= this.upstream.data;

  // Drive upstream ready when FIFO can accept
  this.upstream.ready <= ~fifo.full;

  // Downstream side: read when downstream ready and fifo not empty.
  final shouldRead = this.downstream.ready & ~fifo.empty;
  readEnable <= shouldRead;

  // Drive downstream valid and data from FIFO readData.
  this.downstream.valid <= ~fifo.empty;
  final readData = this.upstream.data.clone() as LogicType;
  readData <= fifo.readData;
  this.downstream.data <= readData;
}