1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
// SPDX-License-Identifier: LGPL-3.0-or-later
// See Notices.txt for copyright information
//! # Connection Semantics
//!
//! Fayalite's connection semantics are unlike assignments in software, so be careful!
//!
//! Fayalite's connection semantics follow [FIRRTL]'s Last-Connect-Semantics and
//! Conditional-Last-Connect-Semantics:
//!
//! Basically, every [wire] behaves as if you ran all connections in a module, and everywhere
//! the wire is read from, it takes on the value it has at the end of the module, with every
//! connect (except those in any kind of [conditional block] where the condition doesn't hold,
//! such as an [`#[hdl] if`][if] with a false condition).
//! overwriting the appropriate portion of the wire.
//!
//! Any other things that are connected to (on the LHS of a
//! [`connect()`] or [`connect_any()`] call) have analogous connection semantics.
//!
//! This description is intended to match [FIRRTL]'s description, so if they conflict with
//! each other, please report it as a bug in Fayalite.
//!
//! Connection Semantics Example:
//!
//! ```
//! # use fayalite::prelude::*;
//! # #[hdl_module]
//! # fn module() {
//! #[hdl]
//! let a: UInt<8> = wire();
//! #[hdl]
//! let b: UInt<8> = m.output();
//!
//! // doesn't actually affect anything, since `a` is completely overwritten later
//! connect(a, 5_hdl_u8);
//!
//! // here `a` has value `7` since the last connection assigns
//! // `7` to `a`, so `b` has value `7` too.
//! connect(b, a);
//!
//! // this is the last `connect` to `a`, so this `connect` determines `a`'s value
//! connect(a, 7_hdl_u8);
//! # }
//! ```
//!
//! # Conditional Connection Semantics
//!
//! ```
//! # use fayalite::prelude::*;
//! # #[hdl_module]
//! # fn module() {
//! #[hdl]
//! let cond: Bool = m.input();
//! #[hdl]
//! let a: UInt<8> = wire();
//! #[hdl]
//! let b: UInt<8> = m.output();
//!
//! // this is the last `connect` to `a` when `cond` is `0`
//! connect(a, 5_hdl_u8);
//!
//! // here `a` has value `7` if `cond` is `1` since the last connection assigns
//! // `7` to `a`, so `b` has value `7` too, otherwise `a` (and therefore `b`)
//! // have value `5` since then the connection assigning `7` is in a
//! // conditional block where the condition doesn't hold.
//! connect(b, a);
//!
//! #[hdl]
//! if cond {
//! // this is the last `connect` to `a` when `cond` is `1`
//! connect(a, 7_hdl_u8);
//! }
//! # }
//! ```
//!
//! [conditional block]: self#conditional-connection-semantics
//! [wire]: crate::_docs::modules::module_bodies::hdl_let_statements::wires
//! [if]: crate::_docs::modules::module_bodies::hdl_if_statements
//! [FIRRTL]: https://github.com/chipsalliance/firrtl-spec
use crate*;