Skip to content

[prim,doc] Updated the main documentation for the post primgen world #27422

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
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
21 changes: 11 additions & 10 deletions SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -503,16 +503,17 @@
- [Registers](./hw/ip/usbdev/doc/registers.md)
- [Device Interface Functions](./sw/device/lib/dif/dif_usbdev.h)
- [Checklist](./hw/ip/usbdev/doc/checklist.md)
- [lowRISC Hardware Primitives](./hw/ip/prim/README.md)
- [Flash Wrapper](./hw/ip/prim/doc/prim_flash.md)
- [Keccak Permutation](./hw/ip/prim/doc/prim_keccak.md)
- [Linear Feedback Shift Register](./hw/ip/prim/doc/prim_lfsr.md)
- [Packer](./hw/ip/prim/doc/prim_packer.md)
- [Packer FIFO](./hw/ip/prim/doc/prim_packer_fifo.md)
- [Present Scrambler](./hw/ip/prim/doc/prim_present.md)
- [Prince Scrambler](./hw/ip/prim/doc/prim_prince.md)
- [SRAM Scrambler](./hw/ip/prim/doc/prim_ram_1p_scr.md)
- [Pseudo Random Number Generator](./hw/ip/prim/doc/prim_xoshiro256pp.md)

- [lowRISC Hardware Primitives](./hw/ip/prim/README.md)
- [Flash Wrapper](./hw/ip/prim/doc/prim_flash.md)
- [Keccak Permutation](./hw/ip/prim/doc/prim_keccak.md)
- [Linear Feedback Shift Register](./hw/ip/prim/doc/prim_lfsr.md)
- [Packer](./hw/ip/prim/doc/prim_packer.md)
- [Packer FIFO](./hw/ip/prim/doc/prim_packer_fifo.md)
- [Present Scrambler](./hw/ip/prim/doc/prim_present.md)
- [Prince Scrambler](./hw/ip/prim/doc/prim_prince.md)
- [Pseudo Random Number Generator](./hw/ip/prim/doc/prim_xoshiro256pp.md)
- [SRAM Scrambler](./hw/ip/prim/doc/prim_ram_1p_scr.md)

- [Common SystemVerilog and UVM Components](./hw/dv/sv/README.md)
- [ALERT_ESC Agent](./hw/dv/sv/alert_esc_agent/README.md)
Expand Down
297 changes: 132 additions & 165 deletions hw/ip/prim/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,198 +32,165 @@

## Concepts

This directory contains basic building blocks to create a hardware design,
called primitives. A primitive is described by its name, and has a well-defined
list of ports and parameters.
This directory contains basic building blocks to create a hardware design, called primitives.
A primitive is described by its name, and has a well-defined list of ports and parameters.

Under the hood, primitives are slightly special, as they can have multiple
implementations. In contrast to many other modules in a hardware design,
primitives must often be implemented in technology-dependent ways. For example,
a clock multiplexer for a Xilinx FPGA is implemented differently than one for
a specific ASIC technology.
Under the hood, primitives are slightly special, as they can have multiple implementations.
In contrast to many other modules in a hardware design, primitives must often be implemented in technology-dependent ways.
For example, a clock multiplexer for a Xilinx FPGA is implemented differently than one for a specific ASIC technology.

Not all primitives need to have multiple implementations.

* Primitives with a single, generic, implementation are normal SystemVerilog
modules inside the `hw/ip/prim/rtl` directory. We call these primitives
"technology-independent primitives".
* Primitives with multiple implementations have only a FuseSoC core file in the
`hw/ip/prim` directory. The actual implementations are in "technology
libraries". We call these primitives "technology-dependent primitives".

### Abstract primitives

Abstract primitives are wrappers around technology-dependent implementations of
primitives, with the ability to select a specific implementation if needed.

In more technical terms, abstract primitives are SystemVerilog modules. The
example below shows one.

```systemverilog
`ifndef PRIM_DEFAULT_IMPL
`define PRIM_DEFAULT_IMPL prim_pkg::ImplGeneric
`endif

module prim_pad_wrapper
#(
parameter int unsigned AttrDw = 6
) (
inout wire inout_io, // bidirectional pad
output logic in_o, // input data
input out_i, // output data
input oe_i, // output enable
// additional attributes {drive strength, keeper, pull-up, pull-down, open-drain, invert}
input [AttrDw-1:0] attr_i
);
parameter prim_pkg::impl_e Impl = `PRIM_DEFAULT_IMPL;

if (Impl == prim_pkg::ImplGeneric) begin : gen_generic
prim_generic_pad_wrapper u_impl_generic (
.*
);
end else if (Impl == prim_pkg::ImplXilinx) begin : gen_xilinx
prim_xilinx_pad_wrapper u_impl_xilinx (
.*
);
end else begin : gen_failure
// TODO: Find code that works across tools and causes a compile failure
end

endmodule
```
* Primitives with a single, generic, implementation are normal SystemVerilog modules inside the `hw/ip/prim/rtl` directory.
We call these primitives *technology-independent primitives*.
* Primitives with multiple implementations are called *technology-dependent primitives*.
Each implementation has it's own directory within `hw/ip/` with the prefix `prim`, e.g. `hw/ip/prim_generic/` or `hw/ip/prim_xilinx/`.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit:

Suggested change
Each implementation has it's own directory within `hw/ip/` with the prefix `prim`, e.g. `hw/ip/prim_generic/` or `hw/ip/prim_xilinx/`.
Each implementation has its own directory within `hw/ip/` with the prefix `prim`, e.g. `hw/ip/prim_generic/` or `hw/ip/prim_xilinx/`.


As seen from the source code snippet, abstract primitives have the following
properties:
Collections of technology-dependent primitives are called technology libraries.
The *generic* technology library contains a pure-SystemVerilog implementation of primitives' functionality.
It's is commonly used for simulations and as functional reference.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit:

Suggested change
It's is commonly used for simulations and as functional reference.
This library is commonly used for simulations and as functional reference.

It also serves as a definition of a technology-dependent primitive's interface.
However, other technology libraries can be supersets of the generic technology library.

- They have an `Impl` parameter which can be set to choose a specific
implementation of the primitive.
- The `Impl` parameter is set to a system-wide default determined by the
`PRIM_DEFAULT_IMPL` define.
- All ports and parameters of the abstract primitive are forwarded to the
implementations.

### Technology libraries
### Virtual primitives

Technology libraries collect implementations of primitives.
To allow hardware blocks to be generic across implementations of *technology-dependent primitives*, a feature of FuseSoC called *[virtual cores][]* are used.*
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: feature is singular

Suggested change
To allow hardware blocks to be generic across implementations of *technology-dependent primitives*, a feature of FuseSoC called *[virtual cores][]* are used.*
To allow hardware blocks to be generic across implementations of *technology-dependent primitives*, a feature of FuseSoC called *[virtual cores][]* is used.*

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍, and I think the * at the end should be removed.

These can be thought of as similar to virtual methods in C++ or SystemVerilog.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Before this line, we might want to describe what it means to a hardware design engineer, hehe. For example...

Suggested change
These can be thought of as similar to virtual methods in C++ or SystemVerilog.
Any implementation of a virtual core must provide the same functionality and interface.
The module name must be the same, and the parameter and port lists must include all the required members of the interface.
For an analog, virtual cores can be thought of as similar to virtual methods in C++ or SystemVerilog.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe 'analogy' or 'analogon'? ('Analog' always feels itchy to the digital designer in me 😉)

A hardware block can depend on a virtual core, which can then be substituted for a *concrete* implementation by the user.

At least one technology library must exist: the `generic` technology library,
which contains a pure-SystemVerilog implementation of the functionality. This
library is commonly used for simulations and as functional reference. The
`generic` technology library is contained in the `hw/ip/prim_generic` directory.
To find the interface of a given virtual primitive look at it's generic implementation in `hw/prim_generic/`.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit:

Suggested change
To find the interface of a given virtual primitive look at it's generic implementation in `hw/prim_generic/`.
To find the interface of a given virtual primitive look at its generic implementation in `hw/prim_generic/`.

Taking `hw/ip/prim_generic/prim_generic_flop_2sync.core` as an example, you'll see the following at the head of the file.

In addition to the implementation in the `generic` library, primitives may be
implemented by as many other libraries as needed.
```yaml
name: "lowrisc:prim_generic:flop_2sync"
description: "Generic implementation of a flop-based synchronizer"
virtual:
- lowrisc:prim:flop_2sync
```

Technology libraries are referenced by their name.
The VLNV (Vendor Library Name Version) of the core is `lowrisc:prim_generic:flop_2sync`, but it also provides a virtual core with the VLNV of `lowrisc:prim:flop_2sync`.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit:

Suggested change
The VLNV (Vendor Library Name Version) of the core is `lowrisc:prim_generic:flop_2sync`, but it also provides a virtual core with the VLNV of `lowrisc:prim:flop_2sync`.
The VLNV (Vendor Library Name Version) of the core is `lowrisc:prim_generic:flop_2sync`, but it also declares itself a provider of the virtual VLNV of `lowrisc:prim:flop_2sync`.

Hardware blocks should depend on this virtual VLNV, so that the user can change implementations.

### Technology library discovery
If an implementation of a virtual core exists in an invokable core's dependency tree, it will be selected.
You can't have multiple implementations of a virtual core in a core's dependency tree.
*An invokable core is the core who's target is being run by FuseSoC.*
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit:

Suggested change
*An invokable core is the core who's target is being run by FuseSoC.*
*An invokable core is the core with its target being run by FuseSoC.*

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or "[..] core whose target is being run [..]"?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"whose" is technically meant to be used with people, rather than objects, but I'm certainly not going to die on that hill ;)


In many cases, technology libraries contain vendor-specific code which cannot be
shared widely or openly. Therefore, a FuseSoC looks for available technology
libraries at build time, and makes all libraries it finds available.
For this reason, usually an invokable core will have their chosen concrete implementation in their dependency tree.
To reduce the hassle of pulling in a set of implementations into a dependency tree, implementations will provide `:all` core, e.g. `lowrisc:prim_generic:all`.
The invokable core `hw/top_earlgrey/chip_earlgrey_cw310.core`, for example, depends on `lowrisc:prim_xilinx:all`.

The discovery is performed based on the agreed-on naming scheme for primitives.
[virtual cores]: https://fusesoc.readthedocs.io/en/stable/user/build_system/virtual_cores.html
Comment on lines +79 to +83
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: Change to "may," since invokable cores definitely don't need to specify the provider in the core files (e.g. block-level sims would best punt that to command-line args)

Suggested change
For this reason, usually an invokable core will have their chosen concrete implementation in their dependency tree.
To reduce the hassle of pulling in a set of implementations into a dependency tree, implementations will provide `:all` core, e.g. `lowrisc:prim_generic:all`.
The invokable core `hw/top_earlgrey/chip_earlgrey_cw310.core`, for example, depends on `lowrisc:prim_xilinx:all`.
The discovery is performed based on the agreed-on naming scheme for primitives.
[virtual cores]: https://fusesoc.readthedocs.io/en/stable/user/build_system/virtual_cores.html
For this reason, an invokable core may be constructed to have their chosen concrete implementation in their dependency tree.
To reduce the hassle of pulling in a set of implementations into a dependency tree, technology libraries can provide an `:all` core, e.g. `lowrisc:prim_generic:all`.
The invokable core `hw/top_earlgrey/chip_earlgrey_cw310.core`, for example, depends on `lowrisc:prim_xilinx:all`.
However, where it is appropriate to be able to swap prim implementations, it is best to punt this selection to fusesoc mappings, which are described later in this guide.


- FuseSoC scans all libraries (e.g. as specified by its `--cores-root` command
line argument) for cores.
- All cores with a name matching `lowrisc:prim_TECHLIBNAME:PRIMNAME`
are considered. `TECHLIBNAME` is then added to the list of technology
libraries.

After the discovery process has completed, a script (`primgen`) creates
- an abstract primitive (see above), and
- an entry in the `prim_pkg` package in the form of `prim_pkg::ImplTechlibname`
to identify the technology library by its name.
### Mappings

## User Guide
Some invokable cores are expected to be used with multiple different implementations.
To allow users to change primitive implementations, OpenTitan makes use of a FuseSoC feature called *[mappings][]*.
This can be used to request a substitution of particular virtual cores with the desired implementation.
An example of their use is in `hw/ip/prim_xilinx/prim_xilinx.core`:

### Use primitives

Primitives are normal SystemVerilog modules, and can be used as usual:
* instantiate it like a normal SystemVerilog module, and
* add a dependency in the FuseSoC core file.

Technology-dependent primitives have an additional parameter called `Impl`.
Set this parameter to use a specific implementation of the primitive for this
specific instance. For example:

```systemverilog
prim_ram_2p #(
.Width (TotalWidth),
.Depth (Depth),
// Force the use of the tsmc40lp technology library for this instance, instead
// of using the build-time default.
.Impl(prim_pkg::ImplTsmc40lp)
) u_mem (
.clk_a_i (clk_i),
...
)
```yaml
mapping:
"lowrisc:prim:and2" : lowrisc:prim_xilinx:and2
"lowrisc:prim:buf" : lowrisc:prim_xilinx:buf
"lowrisc:prim:clock_buf" : lowrisc:prim_xilinx:clock_buf
"lowrisc:prim:clock_div" : lowrisc:prim_generic:clock_div
"lowrisc:prim:clock_gating" : lowrisc:prim_xilinx:clock_gating
"lowrisc:prim:clock_inv" : lowrisc:prim_generic:clock_inv
"lowrisc:prim:clock_mux2" : lowrisc:prim_xilinx:clock_mux2
# ...
```

Notice that there aren't xilinx specific implementations for all primitives, so the generic implementation is requested.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Notice that there aren't xilinx specific implementations for all primitives, so the generic implementation is requested.
Notice that there aren't Xilinx specific implementations for all primitives, so the generic implementation is requested.


### Set the default technology library
Beyond primitives, mappings are also used in the top-level core files, e.g. in `hw/top_earlgrey/top_earlgrey.core`, to ask for top specific implementations.

If no specific technology library is chosen for an instantiated primitive the
default library is used. The SystemVerilog define `PRIM_DEFAULT_IMPL` can be
used to set the default for the whole design. Set this define to one of the enum
values in `prim_pkg.sv` in the form `prim_pkg::ImplTechlibname`. `Techlibname`
is the capitalized name of the technology library.
A specific use of mappings is the lints for each block, for example `hw/ip/uart/uart.core`'s lint target.
None of it's dependencies contain concrete primitive implementations.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit:

Suggested change
None of it's dependencies contain concrete primitive implementations.
None of its dependencies contain concrete primitive implementations.

Instead mappings are used when dvsim invokes the core.
This allows the block to be linted for multiple different primitives (and top-level constants).

In the top-level FuseSoC core file the default technology library can be chosen
like this:
[mappings]: https://fusesoc.readthedocs.io/en/stable/user/build_system/mappings.html

```yaml
# my_toplevel.core

# Declare filesets and other things (omitted)

parameters:
# Make the parameter known to FuseSoC to enable overrides from the
# command line. If not overwritten, use the generic technology library.
PRIM_DEFAULT_IMPL:
datatype: str
paramtype: vlogdefine
description: Primitives implementation to use, e.g. "prim_pkg::ImplGeneric".
default: prim_pkg::ImplGeneric

targets:
fpga_synthesis:
filesets:
- my_rtl_files
parameters:
# Use the xilinx technology library for this target by default.
- PRIM_DEFAULT_IMPL=prim_pkg::ImplXilinx
toplevel: my_toplevel
```

## User Guide
### Using primitives

Primitives are normal SystemVerilog modules, and can be used as usual:
1. Instantiate it like a normal SystemVerilog module.
```systemverilog
prim_fifo_sync #(
.Width (8),
.Pass (1'b0),
.Depth (TxFifoDepth)
) u_uart_txfifo (
.clk_i,
// ..
.err_o ()
)
```
2. Add it as a dependency in the FuseSoC core file.
```yaml
name: "lowrisc:ip:uart:0.1"
description: "uart"
filesets:
files_rtl:
depend:
- lowrisc:virtual_constants:top_pkg
- lowrisc:prim:prim_fifo_sync
```


If you'd like to depend on a specific implementation, you can add the specific implementation's VLNV instead of the virtual VLNV.
For example, you would depend on `lowrisc:prim_xilinx:prim_fifo_sync` instead of `lowrisc:prim:prim_fifo_sync` if you wanted to forcefully use the Xilinx implementation.
**This is not recommended.**
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: Best to provide a reason alongside recommendations.

Suggested change
**This is not recommended.**
Because this method can restrict the flexibility to swap compatible cores, **this is not recommended.**



### Create a technology library

To create a technology library follow these steps:

- Choose a name for the new technology library. Names are all lower-case.
To ease sharing of technology libraries it is encouraged to pick a very
specific name, e.g. `tsmc40lp`, and not `asic`.
- Copy the `prim_generic` folder into an arbitrary location (can be outside
of this repository). Name the folder `prim_YOURLIBRARYNAME`.
- Replace the word `generic` everywhere with the name of your technology
library. This includes
- file and directory names (e.g. `prim_generic_ram1p.sv` becomes
`prim_tsmc40lp_ram1p.sv`),
- module names (e.g. `prim_generic_ram1p` becomes `prim_tsmc40lp_ram1p`), and
- all other references (grep for it!).
- Implement all primitives. Replace the module body of the generic
implementation with a technology-specific implementation as needed. Do *not*
modify the list of ports or parameters in any way!

## Implementation details

Technology-dependent primitives are implemented as a FuseSoC generator. The
core of the primitive (e.g. `lowrisc:prim:rom` in `prim/prim_rom.core`) calls
a FuseSoC generator. This generator is the script `util/primgen.py`. As input,
the script receives a list of all cores found by FuseSoC anywhere in its search
path. The script then looks through the cores FuseSoC discovered and extracts
a list of technology libraries out of it. It then goes on to create the
abstract primitive (copying over the list of parameters and ports from the
generic implementation), and an associated core file, which depends on all
technology-dependent libraries that were found.
1. Choose a name for the new technology library.
Names are all lower-case.
To ease sharing of technology libraries it is encouraged to pick a very specific name, rather than a generic name like `asic`.
`mytech` will be used as a placeholder name in the examples.
2. Create a directory in `hw/ip` with the prefix `prim_` followed by the name of your technology library.
3. Copy `hw/ip/prim_generic/prim_generic.core` into the new directory renaming it to match your primitive library, e.g. `hw/ip/prim_mytech/prim_mytech.core`
Change the vendor and name in this file, e.g. `lowrisc:prim_generic` would become `partner:mytech` where your organisation's name can be used in the place of 'partner'.
Also, edit the description to better describe the specific implementation.
4. For every primitive implemented by your library:
1. Copy across the generic implementation into your library, e.g. `mv hw/ip/prim_generic/rtl/prim_flop.sv hw/ip/prim_mytech/rtl/prim_flop.sv`.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
1. Copy across the generic implementation into your library, e.g. `mv hw/ip/prim_generic/rtl/prim_flop.sv hw/ip/prim_mytech/rtl/prim_flop.sv`.
1. Copy across the generic implementation into your library, e.g. `cp hw/ip/prim_generic/rtl/prim_flop.sv hw/ip/prim_mytech/rtl/prim_flop.sv`.

Unless you've aliased mv to cp? 😉

2. Make your changes to the implementation without modifying the module ports or removing parameters.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
2. Make your changes to the implementation without modifying the module ports or removing parameters.
2. Make your changes to the implementation without modifying the module ports or parameter declarations.

Because I don't think adding parameters would work? And I added "declarations" because otherwise people might be confused that they cannot change parameter values.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding parameters can work in specific circumstances (e.g. somewhere defparam is accepted or where you know there is a specific implementation), but most of the time, it doesn't.

3. Copy the generic primitive's core description into your library, e.g. `mv hw/ip/prim_generic/prim_generic_flop.core hw/ip/prim_mytech/prim_mytech_flop.core`.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
3. Copy the generic primitive's core description into your library, e.g. `mv hw/ip/prim_generic/prim_generic_flop.core hw/ip/prim_mytech/prim_mytech_flop.core`.
3. Copy the generic primitive's core description into your library, e.g. `cp hw/ip/prim_generic/prim_generic_flop.core hw/ip/prim_mytech/prim_mytech_flop.core`.

4. Edit this copied primitive core file so that it has the new primitive library name, e.g. replacing `lowrisc:prim_generic:flop` with `partner:prim_mytech:flop`.
5. Then in the libraries main core file, e.g. `hw/ip/prim_mytech/prim_mytech.core`, replace all instances of the generic implementation with your specific implementation, e.g. replacing `lowrisc:prim_generic:flop` with `partner:prim_mytech:flop` again.

You don't have to have your own implementation for every primitive.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Depending on the use case / requirements of the implementation, there are some requirements on the prim implementation. For example, if you care about security against physical attacks, you need to constrain the tools you're using to not remove a prim_buf. This isn't (and shouldn't be) part of the generic implementation. Should we create an issue to add documentation on this topic?

You can rely on the generic implementation or even another library's implementation for other primitives.

Technology libraries don't have to live in the OpenTitan repository.
If they are not in the OpenTitan repository, you need to make sure the path to them is given to FuseSoC with either an additional `--core-root=` argument or set in `fusesoc.conf`.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit:

Suggested change
If they are not in the OpenTitan repository, you need to make sure the path to them is given to FuseSoC with either an additional `--core-root=` argument or set in `fusesoc.conf`.
If they are not in the OpenTitan repository, you need to make sure the path to them is given to FuseSoC with either an additional `--cores-root=` argument or set in `fusesoc.conf`.

This is useful in cases where technology libraries contain vendor-specific code which cannot be shared widely or openly.


### Selecting a technology library

You can select a technology library one of two ways.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit:

Suggested change
You can select a technology library one of two ways.
You can select a technology library in one of two ways.


If you have your own invokable core which requires a particular primitive, you should add the technology library's VLNV to it's dependencies.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit:

Suggested change
If you have your own invokable core which requires a particular primitive, you should add the technology library's VLNV to it's dependencies.
If you have your own invokable core which requires a particular primitive, you should add the technology library's VLNV to its dependencies.

`hw/top_earlgrey/chip_earlgrey_cw310.core` is an example of an invokable core requiring a particular technology library, namely `lowrisc:prim_xilinx:all`.
You'll notice this VLNV in it's dependencies.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit:

Suggested change
You'll notice this VLNV in it's dependencies.
You'll notice this VLNV in its dependencies.


If you are using an invokable core which is generic across different technology libraries, then you should use mappings to select the technology library you'd like to use.
A default technology library sometimes exists for these invokable cores.
The default technology library needs to be disabled with a flag.
`hw/top_earlgrey/chip_earlgrey_asic.core` is an example of one of these invokable cores.
You provide the `fileset_partner` flag to disable the default implementation as well as your mapping.

```sh
fusesoc --cores-root=$OT_REPO run \
--flag fileset_partner \
--mapping partner:prim_mytech:all
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
--mapping partner:prim_mytech:all
--mapping partner:prim_mytech:all \

lowrisc:systems:chip_earlgrey_asic
```
Loading