add #[hdl] let destructuring and, while at it, tuple patterns
All checks were successful
/ deps (pull_request) Successful in 11m32s
/ test (pull_request) Successful in 3m44s
/ deps (push) Successful in 15s
/ test (push) Successful in 4m9s

This commit is contained in:
Jacob Lifshay 2025-02-10 22:49:41 -08:00
parent 209d5b5fe1
commit 86a1bb46be
Signed by: programmerjake
SSH key fingerprint: SHA256:HnFTLGpSm4Q4Fj502oCFisjZSoakwEuTsJJMSke63RQ
6 changed files with 454 additions and 13 deletions

View file

@ -2,6 +2,7 @@
// See Notices.txt for copyright information
//! ## `#[hdl] let` statements
pub mod destructuring;
pub mod inputs_outputs;
pub mod instances;
pub mod memories;

View file

@ -0,0 +1,33 @@
// SPDX-License-Identifier: LGPL-3.0-or-later
// See Notices.txt for copyright information
//! ### Destructuring Let
//!
//! You can use `#[hdl] let` to destructure types, similarly to Rust `let` statements with non-trivial patterns.
//!
//! `#[hdl] let` statements can only match one level of struct/tuple pattern for now,
//! e.g. you can match with the pattern `MyStruct { a, b }`, but not `MyStruct { a, b: Struct2 { v } }`.
//!
//! ```
//! # use fayalite::prelude::*;
//! #[hdl]
//! struct MyStruct {
//! a: UInt<8>,
//! b: Bool,
//! }
//!
//! #[hdl_module]
//! fn my_module() {
//! #[hdl]
//! let my_input: MyStruct = m.input();
//! #[hdl]
//! let my_output: UInt<8> = m.input();
//! #[hdl]
//! let MyStruct { a, b } = my_input;
//! #[hdl]
//! if b {
//! connect(my_output, a);
//! } else {
//! connect(my_output, 0_hdl_u8);
//! }
//! }
//! ```

View file

@ -7,5 +7,5 @@
//!
//! `#[hdl] match` statements' bodies must evaluate to type `()` for now.
//!
//! `#[hdl] match` statements can only match one level of struct/enum pattern for now,
//! `#[hdl] match` statements can only match one level of struct/tuple/enum pattern for now,
//! e.g. you can match with the pattern `HdlSome(v)`, but not `HdlSome(HdlSome(_))`.

View file

@ -4345,3 +4345,79 @@ circuit check_cfgs:
",
};
}
#[hdl_module(outline_generated)]
pub fn check_let_patterns() {
#[hdl]
let tuple_in: (UInt<1>, SInt<1>, Bool) = m.input();
#[hdl]
let (tuple_0, tuple_1, tuple_2) = tuple_in;
#[hdl]
let tuple_0_out: UInt<1> = m.output();
connect(tuple_0_out, tuple_0);
#[hdl]
let tuple_1_out: SInt<1> = m.output();
connect(tuple_1_out, tuple_1);
#[hdl]
let tuple_2_out: Bool = m.output();
connect(tuple_2_out, tuple_2);
#[hdl]
let test_struct_in: TestStruct<SInt<8>> = m.input();
#[hdl]
let TestStruct::<_> { a, b } = test_struct_in;
#[hdl]
let test_struct_a_out: SInt<8> = m.output();
connect(test_struct_a_out, a);
#[hdl]
let test_struct_b_out: UInt<8> = m.output();
connect(test_struct_b_out, b);
#[hdl]
let test_struct_2_in: TestStruct2 = m.input();
#[hdl]
let TestStruct2 { v } = test_struct_2_in;
#[hdl]
let test_struct_2_v_out: UInt<8> = m.output();
connect(test_struct_2_v_out, v);
#[hdl]
let test_struct_3_in: TestStruct3 = m.input();
#[hdl]
let TestStruct3 {} = test_struct_3_in;
}
#[test]
fn test_let_patterns() {
let _n = SourceLocation::normalize_files_for_tests();
let m = check_let_patterns();
dbg!(m);
#[rustfmt::skip] // work around https://github.com/rust-lang/rustfmt/issues/6161
assert_export_firrtl! {
m =>
"/test/check_let_patterns.fir": r"FIRRTL version 3.2.0
circuit check_let_patterns:
type Ty0 = {`0`: UInt<1>, `1`: SInt<1>, `2`: UInt<1>}
type Ty1 = {a: SInt<8>, b: UInt<8>}
type Ty2 = {v: UInt<8>}
type Ty3 = {}
module check_let_patterns: @[module-XXXXXXXXXX.rs 1:1]
input tuple_in: Ty0 @[module-XXXXXXXXXX.rs 2:1]
output tuple_0_out: UInt<1> @[module-XXXXXXXXXX.rs 4:1]
output tuple_1_out: SInt<1> @[module-XXXXXXXXXX.rs 6:1]
output tuple_2_out: UInt<1> @[module-XXXXXXXXXX.rs 8:1]
input test_struct_in: Ty1 @[module-XXXXXXXXXX.rs 10:1]
output test_struct_a_out: SInt<8> @[module-XXXXXXXXXX.rs 12:1]
output test_struct_b_out: UInt<8> @[module-XXXXXXXXXX.rs 14:1]
input test_struct_2_in: Ty2 @[module-XXXXXXXXXX.rs 16:1]
output test_struct_2_v_out: UInt<8> @[module-XXXXXXXXXX.rs 18:1]
input test_struct_3_in: Ty3 @[module-XXXXXXXXXX.rs 20:1]
connect tuple_0_out, tuple_in.`0` @[module-XXXXXXXXXX.rs 5:1]
connect tuple_1_out, tuple_in.`1` @[module-XXXXXXXXXX.rs 7:1]
connect tuple_2_out, tuple_in.`2` @[module-XXXXXXXXXX.rs 9:1]
connect test_struct_a_out, test_struct_in.a @[module-XXXXXXXXXX.rs 13:1]
connect test_struct_b_out, test_struct_in.b @[module-XXXXXXXXXX.rs 15:1]
connect test_struct_2_v_out, test_struct_2_in.v @[module-XXXXXXXXXX.rs 19:1]
",
};
}