You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Also, ensure that the `SKY130_OPEN_PDK_ROOT` environment variable points to the location of the repo you just cloned.
61
61
62
-
Similarly, if you would like to use Spectre, you will need to ensure that the `SKY130_COMMERCIAL_PDK_ROOT` environment variable points to an installation of the commercial SKY130 PDK.
62
+
If you would like to use Spectre, you will also need to ensure that the `SKY130_COMMERCIAL_PDK_ROOT` environment variable points to an installation of the commercial SKY130 PDK.
63
63
64
64
## Interface
65
65
@@ -95,7 +95,7 @@ We'll make our inverter generator have three parameters:
95
95
We're assuming here that the NMOS and PMOS will have the same length.
96
96
97
97
In this tutorial, we store all dimensions as integers in layout database units.
98
-
In the Sky 130 process, the database unit is a nanometer, so supplying an NMOS width
98
+
In the SKY130 process, the database unit is a nanometer, so supplying an NMOS width
99
99
of 1,200 will produce a transistor with a width of 1.2 microns.
100
100
101
101
We'll now define the struct representing our inverter:
@@ -144,7 +144,7 @@ the device being tested, etc.).
144
144
145
145
As a result, creating a testbench is the same as creating a regular block except that we don't have to define an IO.
146
146
All testbenches must declare their IO to be `TestbenchIo`, which has one port, `vss`, that allows
147
-
simulators to identify a global ground (whichthey often assign to node 0).
147
+
simulators to identify a global ground (which they often assign to node 0).
148
148
149
149
Just like regular blocks, testbenches are usually structs containing their parameters.
150
150
We'll make our testbench take two parameters:
@@ -189,9 +189,8 @@ This is how our testbench looks:
Copy file name to clipboardExpand all lines: docs/site/docs/schematics/blocks.md
+1-2Lines changed: 1 addition & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -30,7 +30,6 @@ There are a few things you need to specify when defining a block:
30
30
| Member | Description |
31
31
|---|---|
32
32
|`type Io`| The IO type of the block. See the [IOs section](./io.md) for more details. |
33
-
|`type Kind`| The kind of the block, which must implement [`BlockKind`](https://api.substratelabs.io/substrate/block/trait.BlockKind.html). For now, you should only need the [`Cell`](https://api.substratelabs.io/substrate/block/struct.Cell.html) kind, which describes any block that is composed of other Substrate blocks. The other block kinds are used for interfacing with [SCIR](https://api.substratelabs.io/scir/), which is discussed in a [later section](#TODO). |
34
33
|`fn id() -> ArcStr`| Returns a unique ID of this block within the crate. While this is not used by Substrate as of November 2023, its intended purpose is to allow generators to be called by name, potentially via a CLI. **No two blocks in the same crate should have the same ID string.**|
35
34
|`fn name(&self)`| Returns a name describing a specific instantiation of a block. This is used to create descriptive cell names when netlisting or writing a layout to GDS. |
36
35
|`fn io(&self) -> Self::Io`| Returns an instantiation of the block's IO type, describing the properties of the IO for a specific set of parameters. This allows you to vary bus lengths at runtime based on block parameters. |
@@ -47,7 +46,7 @@ This derived `Eq` implementation is fine, since it checks that both resistors ar
Now, let's say you generate a voltage divider with two 100 ohm resistors. Then, you try to generate a goltage divider with one 100 ohm resistor and one 200 ohm resistor. Since Substrate thinks these are equivalent due to your `Eq` implementation, it will reuse the previously generated voltage divider with two 100 ohm resistors!
49
+
Now, let's say you generate a voltage divider with two 100 ohm resistors. Then, you try to generate a voltage divider with one 100 ohm resistor and one 200 ohm resistor. Since Substrate thinks these are equivalent due to your `Eq` implementation, it will reuse the previously generated voltage divider with two 100 ohm resistors!
51
50
52
51
:::warning
53
52
The moral of the story, make sure that your block struct contains any relevant parameters and has a correct `Eq` implementation. Otherwise, Substrate may incorrectly cache generated versions of your block, leading to errors that are extremely difficult to catch.
Let's look at what each part of the implementation is doing.
59
-
- In the first line, we implement `Schematic<Spice>` for `Vdivider`. `Spice` is a schema, or essentially a specific format in which a block can be defined. Essentially, we are saying that `Vdivider` has a schematic in the `Spice` schema, which allows us to netlist the voltage divider to SPICE and run simulations with it in SPICE simulators. For more details on schemas, see the [SCIR chapter](#TODO).
59
+
- In the first line, we implement `Schematic<Spice>` for `Vdivider`. `Spice` is a schema, or essentially a specific format in which a block can be defined. Essentially, we are saying that `Vdivider` has a schematic in the `Spice` schema, which allows us to netlist the voltage divider to SPICE and run simulations with it in SPICE simulators. For more details on schemas, see the [SCIR chapter](./scir.md).
60
60
-`fn schematic(...)`, which defines our schematic, takes in three arguments:
61
61
-`&self` - the block itself, which should contain parameters to the generator.
62
62
-`io` - the bundle corresponding to the cell's IO.
0 commit comments