Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
05d77fe
new components: cam and replacement
desmonddak Sep 19, 2025
41bf98e
test/memory added
desmonddak Sep 23, 2025
be4dfbf
smoke test for Cache working
desmonddak Sep 23, 2025
11f056f
cleanup and more file moves
desmonddak Sep 23, 2025
b1771d7
updated code docs for cache
desmonddak Sep 23, 2025
fa52418
updated code docs for cache
desmonddak Sep 23, 2025
26bf9e2
Cache passes a fill then read exhaustive test avoiding evictions
desmonddak Sep 25, 2025
8513ff1
Cache cleanup: still need to figure out TagRF valid bit storage
desmonddak Sep 25, 2025
6bf67b3
Cache cleanup -- use different interfaces for read vs write
desmonddak Sep 25, 2025
e6ead6f
Cache cleanup -- remove vcd generation
desmonddak Sep 25, 2025
ac75a69
updated replacement to be cleaner
desmonddak Sep 27, 2025
22432a1
added valid-bit handling for tags
desmonddak Sep 28, 2025
853afe2
forgot to remove wavedumper
desmonddak Sep 29, 2025
b8a10fa
working with valid bit but not yet invalidating
desmonddak Sep 29, 2025
08727d2
invalidate logic in, needs tests
desmonddak Sep 29, 2025
ff381bd
invalidate working
desmonddak Sep 29, 2025
9ef67c2
write to a hit, double-write tests
desmonddak Sep 29, 2025
5f99bf4
Better SV output, cleaner ROHD
desmonddak Sep 29, 2025
3389438
Cleaner ROHD, should pass CI
desmonddak Sep 30, 2025
104e6aa
Update cache_test.dart
desmonddak Sep 30, 2025
b29d48c
better organization of cache files, cleanup of comments
desmonddak Sep 30, 2025
ad869e5
use flop vs Sequential and reduce loops
desmonddak Oct 1, 2025
0637d7c
better naming for the ReadCache
desmonddak Oct 1, 2025
0021f24
simplified rohd_hcl.dart and udpated cam to remove enable
desmonddak Oct 1, 2025
d8b4a45
proposed Cache interface for handling evictions
desmonddak Oct 2, 2025
79b755b
Merge branch 'main' into cache
desmonddak Oct 4, 2025
fee2be5
prepare for invalidate output
desmonddak Oct 8, 2025
a3391d7
Reproduced combinational RF read issue
desmonddak Oct 9, 2025
aa090f2
working on cache bug fix
desmonddak Oct 10, 2025
0df1d26
overlap read and write testing
desmonddak Oct 13, 2025
a48cc2b
Added Cache and Cam documentation
desmonddak Oct 13, 2025
11c3d95
pull the vcd generation
desmonddak Oct 13, 2025
85a7966
cache componentry
desmonddak Oct 17, 2025
f0a387b
doc update
desmonddak Oct 17, 2025
2194e40
new caching components
desmonddak Oct 29, 2025
98c2d10
minor fixes that blocked CI
desmonddak Oct 29, 2025
e9f01ba
compute cache hit without request.valid
desmonddak Nov 3, 2025
8fe97c3
directory reorg for cache components
desmonddak Nov 4, 2025
a0694a8
updated cache components with eviction, etc
desmonddak Nov 4, 2025
94c195a
add logicstructure components using new addTyped protocol
desmonddak Nov 4, 2025
3aae40a
better docs for caches
desmonddak Nov 5, 2025
10aeb52
new primer on creating a good module
desmonddak Nov 5, 2025
b0e5c84
removed unused module
desmonddak Nov 5, 2025
d3b507f
combinational dependency ready->valid
desmonddak Nov 6, 2025
1e0a5e6
cache configuration
desmonddak Nov 6, 2025
463a48d
cleanup
desmonddak Nov 6, 2025
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
42 changes: 40 additions & 2 deletions confapp/lib/hcl/view/screen/content_widget.dart
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@ class SVGenerator extends StatefulWidget {
State createState() => _SVGeneratorState();
}

class _SVGeneratorState extends State<SVGenerator> {
class _SVGeneratorState extends State<SVGenerator>
with SingleTickerProviderStateMixin {
final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
final ButtonStyle btnStyle =
ElevatedButton.styleFrom(textStyle: const TextStyle(fontSize: 20));
Expand Down Expand Up @@ -148,7 +149,44 @@ class _SVGeneratorState extends State<SVGenerator> {
],
),
for (final (index, subKnob) in knob.knobs.indexed)
_generateKnobControl('$index', subKnob),
// Animate size and add/remove transitions for each generated item.
// AnimatedSize handles height changes; AnimatedSwitcher provides
// a fade/size transition when items are added/removed.
AnimatedSize(
key: ValueKey('${knob.name}-$index-anim'),
duration: const Duration(milliseconds: 250),
curve: Curves.easeInOut,
child: AnimatedSwitcher(
duration: const Duration(milliseconds: 200),
transitionBuilder: (child, animation) => FadeTransition(
opacity: animation,
child: SizeTransition(
sizeFactor: animation,
axisAlignment: 0.0,
child: child,
),
),
child: Container(
key: ValueKey('${knob.name}-$index'),
child: subKnob is GroupOfKnobs
? Column(children: [
_containerOfKnobs(
title: '${subKnob.name} $index',
children: [
for (final subKnobEntry
in subKnob.subKnobs.entries)
_generateKnobControl(
subKnobEntry.key, subKnobEntry.value),
]),
const SizedBox(height: 12),
])
: Column(children: [
_generateKnobControl('${knob.name} $index', subKnob),
const SizedBox(height: 12),
]),
),
),
),
]);
} else if (knob is GroupOfKnobs) {
selector = _containerOfKnobs(title: knob.name, children: [
Expand Down
157 changes: 157 additions & 0 deletions doc/Module.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
# How to Build a Great Component in ROHD

Since ROHD is an extension of the Dart programming language, please follow all
Dart programming and documentation conventions.

The `Module` class is the base class used in ROHD to build components, and
calling the constructor the `Module` instantiates the component and connects it
to signals passed into the constructor.

## Port Construction and Connection

A `Module` constructor takes `Logic` arguments and parameters to generate a
hardware component. The `Logic` arguments are actually the external signals
being connected to by the `Module`, and so internal copies must be constructed
and connected to these arguments by the constructor and only then can other
logic signals be connected to these copies. If you do not do this, a trace error
will occur, but that only happens when this module is instantiated in another --
it will not show up while testing which just instantiates the module in a test
environment. See [Modules](https://intel.github.io/rohd-website/docs/modules/)
for more detail.

A key pattern used in ROHD-HCL is to have the constructor take only input
signals as arguments and generate the output signal widths based on these
signals and other parameters.

## Port Types

Signals can take various forms in ROHD and it is important to consider what form
you want for the API of the `Module` you are building. ROHD supports the basic
`Logic` signal which has its width encode (therefore you should not be using
width as a parameter to a `Module`). ROHD provides basic cloning and accessor
helper functions like `addInput` and `input`.

`LogicArray` is a uniform multi-dimensional array of leaf `Logic` signals. Using
this for input/output will require special routines like `addInputArray` to
connect external and internal signals. Examples of using `LogicArray` are in the
`Serializer` and `Deserializer` components.

`LogicStructure` is a hierarchical concatenation of named `Logic` fields, where
the `FloatingPoint` arithmetic type is an example used in the
`FloatingPointMultiplierSimple` module. We can also pass in `LogicStructure` as
a type for certain components so that the field structure is not lost on input
and output. A good example of this is `Fifo`, which is templatized on
`LogicType` to allow for us to generate a `Fifo` for a particular
`LogicStructure` to use when pushing and popping the data in and out. Here,
`addTypedInput` is a method used to help with creating the internal signals.

`Interface` is similar to `LogicStructure` yet it provides an ability to define
directionality to the internal fields, useful in connecting modules that share a
common protocol such as the `ApbInterface`. See
[Interfaces](https://intel.github.io/rohd-website/docs/interfaces). A few
examples of key general interface types that you can inherit from are the
`PairInterface` and the `DataPortInterface`. the `Memory` module has a good
example of how `DataPortInterface`s are cloned internally using its `connectIO`
method.
The `Fifo` has a good example of using an `Interface` to wrap a `LogicStructure`.

When wrapping `LogicStructure` with `Interface`, don't name the `LogicStructure`
as `Interface` will need to uniquify (a known bug in `Interface`).

An important kind of `Interface` is the `PairInterface` which is designed for
bidirectional communication and provides a `pairConnectIO` method for connecting
external and internal ports based on producer/consumer filtering.

## Logic Internals

Signal logic is constructed in a ROHD component by assignment and simple logic
operations like and (`&`) and or (`|`) as well as multiplexing (`mux`) and
flopping (`flop`). See
[operations](https://intel.github.io/rohd-website/docs/logic-math-compare/) for
more detail.

More complex logic can be constructed using
[`Sequental`](https://intel.github.io/rohd-website/docs/sequentials/) and
[`Combinational`](https://intel.github.io/rohd-website/docs/conditionals/)
blocks similar to SystemVerilog `always` blocks. There is also a
[`FiniteStateMachine`](https://intel.github.io/rohd-website/docs/fsm/)
construct for state machines and a
[`Pipeline`](https://intel.github.io/rohd-website/docs/pipelines/) construct
for assisting with pipelined logic.

Try to minimize the addition of new internal signals, by just reusing the
signals created by the ports or by subcomponents. Use `.named` to create clean
SystemVerilog names.

### Debug

If you want to expose internal signals onto the interface of a `Module` for debug, a simple method is to declare them as a field in the class (Use @protected in case this is exposed so it doesn't become part of the API). This signal will be available in tests as module.field.

## Unit Testing

A good component has unit tests to validate the component and provide examples
of use. We use the Dart testing framework which requires that tests are stored
in the `test/` directory and are named ending in `_test.dart`. An example of
unit tests for a component is shown below. Note that grouping of tests can
reuse a common component built for multiple tests. Also note that each test
with sequential logic will need a `SimpleClockGenerator`, a `Simulator.run()`
and an `endSimulation`. Some helper methods (like `.waitCycles`) are available
in the rohd-fv package.

```dart
void main() {
tearDown(() async {
await Simulator.reset();
});

group('test narrow component', () {
final input = Logic(width: 5);
final component = MyComponent(input);
final output = component.out;

test('MyComponent smoke test', () async {
final clk = SimpleClockGenerator(10).clk;

unawaited(Simulator.run());
reset.inject(1);
await clk.waitCycles(3);
reset.inject(0);
await clk.waitCycles(1);
input.inject(1);
await clk.waitCycles(3);
expect(output.value, equals(Const(1, width: output.width)));

await Simulator.endSimulation();
});

test('MyComponent second test', () async {
final clk = SimpleClockGenerator(10).clk;

unawaited(Simulator.run());
reset.inject(1);
await clk.waitCycles(3);
reset.inject(0);
await clk.waitCycles(1);
input.inject(6);
await clk.waitCycles(3);
expect(output.value, equals(Const(6, width: output.width)));

await Simulator.endSimulation();
});
});
}
```

Prefer using `waitCycles` instead of `nextPosedge` and use `inject` instead of
`put` when working with sequential tests.

When testing a combinational path, and you `inject` inputs after a positive
clock edge, if you sample at the next clock edge, you will miss the
combinational value. Instead, use the output `previousValue` at the next clock
edge, or sample the output at `nextNegEdge` to look at the value mid-way through
the clock cycle.

While creating unit tests, you can just run the tests for your component instead
of running the entire suite of ROHD-HCL tests. The entire regression suite
takes quite a long time and is only necessary if you make changes to some core
functionality.
9 changes: 7 additions & 2 deletions doc/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -109,8 +109,9 @@ Some in-development items will have opened issues, as well. Feel free to create
- Memory
- [Register File](./components/memory.md#register-files)
- [Masking](./components/memory.md#masks)
- Replacement Policies
- LRU
- [Caches](./components/memory.md#caches)
- [Replacement Policies](./components/memory.md#replacement-policy)
- [Cams](./components/memory.md#basic-cam)
- [Memory Model](./components/memory.md#memory-models)
- [Control/Status Registers (CSRs)](./components/csr.md)
- Standard interfaces
Expand All @@ -133,6 +134,10 @@ Some in-development items will have opened issues, as well. Feel free to create
- Gaskets
- [SPI](./components/spi_gaskets.md)

## Adding a New Component

Please refer to [Module](./Module.md) for the best practices for creating new components.

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

Copyright (C) 2023-2025 Intel Corporation
Expand Down
Loading