Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/chipsalliance/cde
A Scala library for Context-Dependent Environments
https://github.com/chipsalliance/cde
Last synced: 3 months ago
JSON representation
A Scala library for Context-Dependent Environments
- Host: GitHub
- URL: https://github.com/chipsalliance/cde
- Owner: chipsalliance
- License: apache-2.0
- Created: 2019-08-03T00:21:22.000Z (over 5 years ago)
- Default Branch: master
- Last Pushed: 2024-04-25T19:17:28.000Z (9 months ago)
- Last Synced: 2024-11-01T02:35:43.267Z (3 months ago)
- Language: Scala
- Homepage:
- Size: 67.4 KB
- Stars: 46
- Watchers: 18
- Forks: 21
- Open Issues: 3
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# CDE
A Scala library for Context-Dependent Environments, where a key-value environment is passed down a module hierarchy and each returned value depends on the key and the query’s origin. CDE is provably superior to existing parameterization schemes because it avoids introducing non-local source code changes when a design is modified, while also enabling features for large-scale design space exploration of compositions of generators.## User Guide
The library presents its key-value storage under an abstract class `Parameters`. Values stored in `Parameters` are each associated with a case object extends `Field[T]`.
The main interface for user to create a `Parameters` object is using `Config` object. Its `apply` method takes `(View, View, View) => PartialFunction[Any, Any]` as a lookup table.
```scala
//Field MyKey1 contains value of type Int
case object MyKey1 extends Field[Int]
//Field MyKey2 contains value of type String, with default value "None"
case object MyKey2 extends Field[String]("None")// The meaning of parameter (site, here, up) will be explained later
val p: Parameters = Config((site, here, up) => {
case MyKey1 => 0
case MyKey2 => "MyValue"
})// Apply Paramaters object to Field to query
assert(p(MyKey1) == 0)
```### Parameter Overrides
We can use one `Parameters` to override another. Each single `Config` is like a row in a table, while each `Field` is a column in the table. To concat two table together, we have `alter` and `orElse` methods.
`alter` puts the rhs at bottom of the table and `orElse` puts the rhs at top of the table.A query will inspect the table from bottom to up, row by row, until it finds the first row having the key defined.
For example: `Config1.alter(Config2).alter(Config3)` yields
| | Key1 | Key2 | Key3 |... |
| ---- | ---- | ---- | ---- | ---- |
| `Config1` | V1 | | | |
| `Config2` | V2 | V3 | | |
|`Config3` | | | V4 | |And now `p(Key1) == V2`, `p(Key2) == V3` and `p(Key3) == V4`.
The same `Parameters` can also be defined by `Config3.orElse(Config2).orElse(Config1)`. There is also deprecated shorthand `++` for `orElse`, so `Config3 ++ Config2 ++ Config1` is also valid.
### Environment Reference
Each query contains the entire environment of where the query originates. This is pass to the lookup table of each `Config` by `(site, here, up)` arguments.- `here` dynamically refers to the current row of the table
- `up` dynamically refers to the rows appearing up than the current row
- `site` dynamically refers to the entire table. When it gets called by `here` or `up` queries, it still refers to the **entire** table instead of current row or upper half as indicated by `here` or `up` respectively.For example, in the following `Parameters`
| | Key1 | Key2 | Key3 | Key4 |
| ---- | ---- | ---- | ---- | ---- |
| `Config1` | 1 | `site(Key1)` | | |
| `Config2` | 2 | | `here(Key1)` | `up(Key2)` |
| `Config3` | 3 | | | |The value for each key is
- Key1: 3, given by `Config3`
- Key2: 3, as it is value of `Key1` in the entire table
- Key3: 2, as it is value of `Key1` defined in the current row
- Key4: 3, as it is value of `Key2` defined in the upper row, which is in turn value of `Key1` defined in the table, which should be 3 as overriden by `Config3`.If one config layer does not refer environment at all, `alterMap` and `alterPartial` can be used to avoid create a redundant `Config` object, as they accept `Map` and `PartialFunction` as their parameter.
## Implementation Details
This section discusses the internal data structure used to track environment information. Normal reader can skip the section.`alter` and `orElse` function wraps two operand as `ChainParameters`, which forms a binary tree when `alter` are called multiple times. Query on `ChainParameters` calls `chain` method.
The `chain` method traverses the tree by wrapping the right child in `ChainView`, which records `up` for later reference, and invoking `chain` on the left child. This happens recursively until a leaf node is found. Then if the requested key is not in the node, we can turn to `chain` of currently `up` node.
The following figure illustrates a querying process of `Parameters` constructed by `C1.alter(C2).alter(C3).orElse(C4)`. `chain` is invoked on the node in blue, and `ChainView` generated is in red.
![Query Example](doc/ChainParameters.svg)