Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -303,5 +303,5 @@ await myMod.buildAndGenerateRTL();

----------------

Copyright (C) 2024-2025 Intel Corporation
Copyright (C) 2024-2026 Intel Corporation
SPDX-License-Identifier: BSD-3-Clause
24 changes: 13 additions & 11 deletions lib/src/bridge_module.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (C) 2024-2025 Intel Corporation
// Copyright (C) 2024-2026 Intel Corporation
// SPDX-License-Identifier: BSD-3-Clause
//
// bridge_module.dart
Expand Down Expand Up @@ -943,9 +943,13 @@ class BridgeModule extends Module with SystemVerilog {
}

/// Calls [build] and generates SystemVerilog and a filelist into the
/// [outputPath], with optional logging sent to the [logger].
Future<void> buildAndGenerateRTL(
{Logger? logger, String outputPath = 'output'}) async {
/// [outputPath].
Future<void> buildAndGenerateRTL({
@Deprecated('Leave null to use the default logger') Logger? logger,
String outputPath = 'output',
}) async {
logger ??= RohdBridgeLogger.logger;

var synthResults = <SynthesisResult>{};

// Build
Expand All @@ -956,22 +960,20 @@ class BridgeModule extends Module with SystemVerilog {
final defNames =
synthResults.map((result) => result.module.definitionName);
logger
?..info('Build Complete...\n')
..info('Build Complete...\n')
..info('Found ${synthResults.length} hierarchical instances in '
'design $name')
..info('Synth Results: ${defNames.join(', ')}');
} on Exception catch (e, stackTrace) {
logger != null
? logger.error('Build failed $e, $stackTrace')
: throw RohdBridgeException('Build failed $e, $stackTrace');
logger.error('Build failed $e, $stackTrace');
}

// Write out RTL
final outputGenerationPath = '$outputPath/rtl';
Directory(outputGenerationPath).createSync(recursive: true);

final filelistContents = StringBuffer();
logger?.sectionSeparator('Generating RTL');
logger.sectionSeparator('Generating RTL');
final fileIoFutures = <Future<void>>[];
for (final synthResult in synthResults) {
final fileName = '${synthResult.module.definitionName}.sv';
Expand All @@ -981,14 +983,14 @@ class BridgeModule extends Module with SystemVerilog {
fileIoFutures.add(File(filePath)
.writeAsString(synthResult.toSynthFileContents().join('\n')));

logger?.finer('Generated file ${Directory(filePath).absolute.path}');
logger.finer('Generated file ${Directory(filePath).absolute.path}');
}
await Future.wait(fileIoFutures);

File('$outputPath/filelist.f')
.writeAsStringSync(filelistContents.toString());

logger?.fine('done!');
logger.fine('done!');
}

/// Adds an interface to this module with comprehensive configuration options.
Expand Down
35 changes: 24 additions & 11 deletions lib/src/rohd_bridge_logger.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (C) 2024-2025 Intel Corporation
// Copyright (C) 2024-2026 Intel Corporation
// SPDX-License-Identifier: BSD-3-Clause
//
// rohd_bridge_logger.dart
Expand Down Expand Up @@ -31,26 +31,30 @@ extension LoggerError on Logger {
}
}

/// Loggger for ROHD Bridge tool
/// Logger for ROHD Bridge tool
abstract class RohdBridgeLogger {
/// If set to `true`, then errors will be printed without causing an immediate
/// exception halting execution.
static bool continueOnError = false;

/// If set to`true`, some additional log will be printed
/// which will be helpful for debug
@Deprecated(
'Use other levels and flags in `configureLogger` to control verbosity')
static bool enableDebugMesage = false;

/// The file sink to write to.
static IOSink? fileSink;
@Deprecated('API is moved to be private. Use separate logging if needed.')
static IOSink? get fileSink => _fileSink;
static IOSink? _fileSink;

static late Level _printLevel;

/// logger for rohd_bridge
static final Logger logger = Logger('ROHD Bridge');

/// Sets up logging to dump to [filePath] and print to console based on
/// [printLevel] and [rootLevel].
/// Sets up logging to dump to [filePath] (if provided) and print to console
/// based on [printLevel] and [rootLevel].
///
/// The [rootLevel] will set the level of the [Logger.root] to the given
/// level.
Expand All @@ -62,17 +66,26 @@ abstract class RohdBridgeLogger {
/// If [continueOnError] is set to `false`, then an exception will be thrown
/// immediately upon encountering an error.
static void configureLogger(
String filePath, {
String? filePath, {
Level printLevel = Level.ALL,
Level rootLevel = Level.ALL,
bool continueOnError = false,
@Deprecated('Use other levels and flags to control verbosity')
bool enableDebugMesage = false,
}) {
RohdBridgeLogger.continueOnError = continueOnError;
Logger.root.level = rootLevel;
_printLevel = printLevel;

fileSink = File(filePath).openWrite();
if (filePath != null) {
final file = File(filePath);
final directory = file.parent;
if (!directory.existsSync()) {
directory.createSync(recursive: true);
}

_fileSink = file.openWrite();
}

Logger.root.onRecord.listen((record) {
final message = '${record.time}: ${record.level.name}: '
Expand All @@ -83,7 +96,7 @@ abstract class RohdBridgeLogger {
}

static void _handleMessage(String message, [Level? level]) {
fileSink!.write(message);
_fileSink?.write(message);
if (level != null && level >= _printLevel) {
// We actually want to print for logging purposes based on print level.
// ignore: avoid_print
Expand All @@ -95,13 +108,13 @@ abstract class RohdBridgeLogger {
static Future<void> terminate() async {
Logger.root.clearListeners();
await flush();
await fileSink!.close();
fileSink = null;
await _fileSink?.close();
_fileSink = null;
}

/// Flush the file sink.
static Future<void> flush() async {
await fileSink!.flush();
await _fileSink?.flush();
}

/// Log a section separator
Expand Down
44 changes: 44 additions & 0 deletions test/logger_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// Copyright (C) 2026 Intel Corporation
// SPDX-License-Identifier: BSD-3-Clause
//
// logger_test.dart
// Unit tests for MI (multiple instances).
//
// 2026 January 2
// Author: Max Korbel <max.korbel@intel.com>

import 'dart:io';

import 'package:logging/logging.dart';
import 'package:rohd_bridge/rohd_bridge.dart';
import 'package:test/test.dart';

void main() {
test('unconfigured logger works', () async {
// just make sure no exceptions are thrown

final top = BridgeModule('top');

const outPath = 'tmp_test/unconfigured_logger_test';
await top.buildAndGenerateRTL(outputPath: outPath);

Directory(outPath).deleteSync(recursive: true);
});

test('configured logger works', () async {
const logPath = 'tmp_test/cfg_logger/cfg_logger.log';
RohdBridgeLogger.configureLogger(logPath, printLevel: Level.OFF);

final top = BridgeModule('top');

const outPath = 'tmp_test/cfg_logger/';
await top.buildAndGenerateRTL(outputPath: outPath);

await RohdBridgeLogger.terminate();

expect(File(logPath).existsSync(), isTrue);
expect(File(logPath).readAsStringSync().contains('done!'), isTrue);

Directory(outPath).deleteSync(recursive: true);
});
}