dart-lang / dart-pad

An online Dart editor with support for console, web, and Flutter apps
https://dartpad.dev
BSD 3-Clause "New" or "Revised" License
1.7k stars 552 forks source link

Add `rohd` package #2193

Closed mkorbel1 closed 1 year ago

mkorbel1 commented 2 years ago

Would love to see support for importing the ROHD package in dart pad! https://pub.dev/packages/rohd

domesticmouse commented 2 years ago

Can you please supply a single page sample showing how to use ROHD in a useful way?

We need a proof of life script to make sure it is working as part of an implementation change.

mkorbel1 commented 2 years ago

Sure, here's a slightly modified example from the repo that should work well!

/// Copyright (C) 2021-2022 Intel Corporation
/// SPDX-License-Identifier: BSD-3-Clause
///
/// example.dart
/// A very basic example of a counter module.
///
/// 2021 September 17
/// Author: Max Korbel <max.korbel@intel.com>
///

// Import the ROHD package
import 'package:rohd/rohd.dart';

// Define a class Counter that extends ROHD's abstract Module class
class Counter extends Module {
  // For convenience, map interesting outputs to short variable names for consumers of this module
  Logic get val => output('val');

  // This counter supports any width, determined at run-time
  final int width;
  Counter(Logic en, Logic reset, Logic clk,
      {this.width = 8, String name = 'counter'})
      : super(name: name) {
    // Register inputs and outputs of the module in the constructor.
    // Module logic must consume registered inputs and output to registered outputs.
    en = addInput('en', en);
    reset = addInput('reset', reset);
    clk = addInput('clk', clk);

    var val = addOutput('val', width: width);

    // A local signal named 'nextVal'
    var nextVal = Logic(name: 'nextVal', width: width);

    // Assignment statement of nextVal to be val+1 (<= is the assignment operator)
    nextVal <= val + 1;

    // `Sequential` is like SystemVerilog's always_ff, in this case trigger on the positive edge of clk
    Sequential(clk, [
      // `If` is a conditional if statement, like `if` in SystemVerilog always blocks
      If(reset, then: [
        // the '<' operator is a conditional assignment
        val < 0
      ], orElse: [
        If(en, then: [val < nextVal])
      ])
    ]);
  }
}

// Let's simulate with this counter a little, monitor the output, and take a look at generated SystemVerilog.
Future<void> main() async {
  // Define some local signals.
  var en = Logic(name: 'en'), reset = Logic(name: 'reset');

  // Generate a simple clock.  This will run along by itself as the Simulator goes.
  var clk = SimpleClockGenerator(10).clk;

  // Build a counter.
  var counter = Counter(en, reset, clk);

  // Before we can simulate or generate code with the counter, we need to build it.
  await counter.build();

  // Let's see what this module looks like as SystemVerilog, so we can pass it to other tools.
  var systemVerilogCode = counter.generateSynth(SystemVerilogSynthesizer());
  print('///// Generated SystemVerilog code /////');
  print(systemVerilogCode);
  print('////////////////////////////////////////');

  // Now let's try simulating!

  // Let's start off with a disabled counter and asserting reset.
  en.inject(0);
  reset.inject(1);

  // Drop reset at time 25.
  Simulator.registerAction(25, () => reset.put(0));

  // Raise enable at time 45.
  Simulator.registerAction(45, () => en.put(1));

  // Add a print message triggered when the output changes
  counter.val.changed.listen((event) {
    print('Counter value changed @${Simulator.time}: $event');
  });

  // Print a message when we're done with the simulation!
  Simulator.registerAction(100, () {
    print('Simulation completed!');
  });

  // Set a maximum time for the simulation so it doesn't keep running forever.
  Simulator.setMaxSimTime(100);

  // Kick off the simulation.
  await Simulator.run();
}
johnpryan commented 1 year ago

Closed in #995

domesticmouse commented 1 year ago

Actually, this isn't shipped to production, so I'm re-opening this issue. This package has been shipped to our hidden testing instance https://dartpad.dev/?channel=dev

Please exercise your suggested package on this instance and confirm here that it works as intended. If you do confirm this as working I'll ship it to stable, beta, master, and old channels on dartpad.dev. If you don't confirm, I won't ship it.

domesticmouse commented 1 year ago

Verified with the above sample code.

///// Generated SystemVerilog code /////
/**
 * Generated by ROHD - www.github.com/intel/rohd
 * Generation time: 2023-01-16 17:47:17.686
 * ROHD Version: 0.4.1
 */

module Counter(
input logic en,
input logic reset,
input logic clk,
output logic [7:0] val
);
logic [7:0] nextVal;
//  sequential
always_ff @(posedge clk) begin
  if(reset) begin
      val <= 8'h0;
  end else begin
      if(en) begin
          val <= nextVal;
      end 

  end 

end

assign nextVal = val + 8'h1;  // add
endmodule : Counter
////////////////////////////////////////
Counter value changed @5: 8'bzzzzzzzz  -->  8'h0
Counter value changed @45: 8'h0  -->  8'h1
Counter value changed @55: 8'h1  -->  8'h2
Counter value changed @65: 8'h2  -->  8'h3
Counter value changed @75: 8'h3  -->  8'h4
Counter value changed @85: 8'h4  -->  8'h5
Counter value changed @95: 8'h5  -->  8'h6
Simulation completed!
mkorbel1 commented 1 year ago

I just tried it out and it appears to be working! Thank you!!