rust_hdl_core/
logic.rs

1use crate::ast::{Verilog, VerilogLink};
2use crate::timing::TimingInfo;
3
4pub trait Logic {
5    fn update(&mut self);
6    fn connect(&mut self) {}
7    fn hdl(&self) -> Verilog {
8        Verilog::Empty
9    }
10    fn timing(&self) -> Vec<TimingInfo> {
11        vec![]
12    }
13}
14
15pub fn logic_connect_fn<L: Logic>(x: &mut L) {
16    x.connect();
17}
18
19impl<L: Logic, const P: usize> Logic for [L; P] {
20    fn update(&mut self) {}
21}
22
23impl<L: Logic> Logic for Vec<L> {
24    fn update(&mut self) {}
25}
26
27/*
28 A link is always
29 In --> In
30 Out --> Out
31
32 So if we have a piece of logic with:
33 > In (A)   ---- Link ----    > In(A)
34 < Out (B)  ---- Link ----    < Out(B)
35
36 We want the connections for the internal parts to be
37 handled automatically by RustHDL.  So Dest In should always be
38 driven, and source Out should always be driven.
39
40 When externally connected, we assume that the situationis
41
42 External              Internal
43 >Out (A) --- Link --->In(A)
44 <In (A)  --- Link ---<Out(A)
45*/
46pub trait LogicLink {
47    fn link(&mut self, other: &mut Self);
48    fn link_hdl(my_name: &str, this: &str, that: &str) -> Vec<VerilogLink>;
49    fn link_connect_source(&mut self);
50    fn link_connect_dest(&mut self);
51}
52
53pub fn logic_connect_link_fn<L: LogicLink>(source: &mut L, dest: &mut L) {
54    source.link_connect_source();
55    dest.link_connect_dest();
56}
57
58pub trait LogicJoin {
59    fn join_connect(&mut self) {}
60    fn join_hdl(_my_name: &str, _this: &str, _that: &str) -> Vec<VerilogLink> {
61        vec![]
62    }
63}
64
65pub fn logic_connect_join_fn<L: LogicJoin, K: LogicJoin>(source: &mut L, dest: &mut K) {
66    source.join_connect();
67    dest.join_connect();
68}