Skip to content

Commit

Permalink
Add decision to latency.md
Browse files Browse the repository at this point in the history
  • Loading branch information
VonTum committed Mar 7, 2024
1 parent caabc42 commit 9ccf9c6
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 8 deletions.
2 changes: 1 addition & 1 deletion philosophy/interfaces.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

A module can have one or more interfaces, each of which consists of multiple input and output ports.

Interfaces form the only method by which one can cross latency and clock domains. Each interface has with it it's associated hardware, that operates within the same clock and latency counting domain. Wires which belong to the same latency counting group should be placed in the same interface.
Interfaces form the only method by which one can cross latency and clock domains. Each interface has with it its associated hardware, that operates within the same clock and latency counting domain. Wires which belong to the same latency counting group should be placed in the same interface.

The code in one interface can read wires from other interfaces, provided the proper clock domain crossing method is used, in case of a clock domain crossing. Writes however, can naturally only be done by the interface that owns that wire.

Expand Down
26 changes: 19 additions & 7 deletions philosophy/latency.md
Original file line number Diff line number Diff line change
Expand Up @@ -94,12 +94,12 @@ On the edges are noted the minimum latency offsets in black. These are given. Th
Sadly, while it appears reasonable to think it's possible to assign a determinable latency. Observe this contrived example:

```Verilog
// timeline is omitted here, not important
module NonDeterminable : int a, int b -> int x, int y {
module NonDeterminableLatency : int a, int b -> int x, int y {
reg int a_d = a;
reg int t = a_d + b;
reg reg reg int a_ddd = a;
x = t + a_ddd;
int t = a_d + b;
reg reg reg int a_dd = a;
reg int t_d = t;
x = t_d + a_dd;
y = t;
}
```
Expand All @@ -113,8 +113,20 @@ One may think the solution would simply be to prefer inputs over outputs or some

To this problem I only really see three options:
- Still perform full latency computation when compiling each module separately. In the case of non-determinable latency assignment, reject the code and require the programmer to add explicit latency annotations. The benefit is better encapsulation, the programmer requires only the module itself to know what latencies are. The downside is of course less flexible modules. Though is this flexibility _really_ needed?
- Infer absolute latencies on the inputs and outputs of submodules using templates which can be inferred. This would be really handy to allow latency information to flow back into the templating system, thus allowing a FIFO that alters its almostFull threshold based on its input latency. Of course, this makes absolute latency information flow from top-down instead of bottom up, so now getting the latency information back from the module would be impossible. The issue is that templates can't be instantiated partially. Either the submodule takes all of its port latencies from the calling module, or it determines its latencies itself.
- Perform latency computation at integration level, we don't define the absolute latencies on the ports of a module, unless the programmer explicitly does so. For simlpicity, this requires that every single module instantiation now compiles to its own Verilog module though, which is less than ideal for debugging.
~~- Infer absolute latencies on the inputs and outputs of submodules using templates which can be inferred. This would be really handy to allow latency information to flow back into the templating system, thus allowing a FIFO that alters its almostFull threshold based on its input latency. Of course, this makes absolute latency information flow from top-down instead of bottom up, so now getting the latency information back from the module would be impossible. The issue is that templates can't be instantiated partially. Either the submodule takes all of its port latencies from the calling module, or it determines its latencies itself. ~~
~~- Perform latency computation at integration level, we don't define the absolute latencies on the ports of a module, unless the programmer explicitly does so. For simlpicity, this requires that every single module instantiation now compiles to its own Verilog module though, which is less than ideal for debugging. ~~

Simply solve the above module by explicitly specifying latencies to the two inputs:
```Verilog
module NonDeterminableLatency : int a'0, int b'1 -> int x, int y {
reg int a_d = a;
int t = a_d + b;
reg reg reg int a_dd = a;
reg int t_d = t;
x = t_d + a_dd;
y = t;
}
```

### Latency Graph Cycles are the key
So assigning absolute latencies is difficult, and no good solution can be found in isolated cases. Perhaps another approach would work better.
Expand Down

0 comments on commit 9ccf9c6

Please sign in to comment.