diff --git a/DOCS.md b/DOCS.md index 53e57ac..7a4ee0f 100644 --- a/DOCS.md +++ b/DOCS.md @@ -16,7 +16,9 @@ - [Basic Modules](#basic-modules) - [Input/Output Modules](#inputoutput-modules) - [Gate Modules](#gate-modules) + - [Combinational Modules](#combinational-modules) - [Latch Modules](#latch-modules) + - [Flip Flops](#flip-flops) - [3. Custom Modules](#3-custom-modules) - [Creating a new module](#creating-a-new-module) - [Exporting Modules](#exporting-modules) @@ -104,41 +106,41 @@ LogicRs features several builtin modules available for every project. Here is a - | A | B | Output | - |---|---|--------| - | 0 | 0 | 0 | - | 0 | 1 | 0 | - | 1 | 0 | 0 | - | 1 | 1 | 1 | + | A | B | Output | + | --- | --- | ------ | + | 0 | 0 | 0 | + | 0 | 1 | 0 | + | 1 | 0 | 0 | + | 1 | 1 | 1 | - **`Nand`**: inverse of `And`: - | A | B | Output | - |---|---|--------| - | 0 | 0 | 1 | - | 0 | 1 | 1 | - | 1 | 0 | 1 | - | 1 | 1 | 0 | + | A | B | Output | + | --- | --- | ------ | + | 0 | 0 | 1 | + | 0 | 1 | 1 | + | 1 | 0 | 1 | + | 1 | 1 | 0 | - **`Nor`**: inverse of `Or`: - | A | B | Output | - |---|---|--------| - | 0 | 0 | 1 | - | 0 | 1 | 0 | - | 1 | 0 | 0 | - | 1 | 1 | 0 | + | A | B | Output | + | --- | --- | ------ | + | 0 | 0 | 1 | + | 0 | 1 | 0 | + | 1 | 0 | 0 | + | 1 | 1 | 0 | - **`Not`**: outputs the inverse of the input signal: | Input | Output | - |-------|--------| + | ----- | ------ | | 0 | 1 | | 1 | 0 | @@ -146,34 +148,34 @@ LogicRs features several builtin modules available for every project. Here is a - | A | B | Output | - |---|---|--------| - | 0 | 0 | 0 | - | 0 | 1 | 1 | - | 1 | 0 | 1 | - | 1 | 1 | 1 | + | A | B | Output | + | --- | --- | ------ | + | 0 | 0 | 0 | + | 0 | 1 | 1 | + | 1 | 0 | 1 | + | 1 | 1 | 1 | - **`Xnor`**: inverse of `Xor`: - | A | B | Output | - |---|---|--------| - | 0 | 0 | 1 | - | 0 | 1 | 0 | - | 1 | 0 | 0 | - | 1 | 1 | 1 | + | A | B | Output | + | --- | --- | ------ | + | 0 | 0 | 1 | + | 0 | 1 | 0 | + | 1 | 0 | 0 | + | 1 | 1 | 1 | - **`Xor`**: outputs `1` if either the A *or* (strictly) B input is `1`: - | A | B | Output | - |---|---|--------| - | 0 | 0 | 0 | - | 0 | 1 | 1 | - | 1 | 0 | 1 | - | 1 | 1 | 0 | + | A | B | Output | + | --- | --- | ------ | + | 0 | 0 | 0 | + | 0 | 1 | 1 | + | 1 | 0 | 1 | + | 1 | 1 | 0 | ### Combinational Modules @@ -181,19 +183,19 @@ LogicRs features several builtin modules available for every project. Here is a - | S | Output | - |---|--------| - | 0 | A | - | 1 | B | + | S | Output | + | --- | ------ | + | 0 | A | + | 1 | B | - **`Demux`**: A 1:2 demultiplexer, selecting either the O0 or O1 output based on the S input: - | S | O1 | O0 | - |---|----|----| - | 0 | 0 | A | - | 1 | A | 0 | + | S | O1 | O0 | + | --- | --- | --- | + | 0 | 0 | A | + | 1 | A | 0 | ### Latch Modules @@ -201,34 +203,59 @@ LogicRs features several builtin modules available for every project. Here is a - | A | B | Action | - |---|---|-----------| - | 0 | 0 | No change | - | 0 | 1 | Reset | - | 1 | 0 | Set | - | 1 | 1 | Toggle | + | A | B | Action | + | --- | --- | --------- | + | 0 | 0 | No change | + | 0 | 1 | Reset | + | 1 | 0 | Set | + | 1 | 1 | Toggle | - **`SR Latch`**: Latch used to store a value: - | A | B | Action | - |---|---|-------------| - | 0 | 0 | No change | - | 0 | 1 | Reset | - | 1 | 0 | Set | - | 1 | 1 | Not allowed | + | A | B | Action | + | --- | --- | ----------- | + | 0 | 0 | No change | + | 0 | 1 | Reset | + | 1 | 0 | Set | + | 1 | 1 | Not allowed | - **`SR Nand Latch`**: - | A | B | Action | - |---|---|-------------| - | 0 | 0 | Not allowed | - | 0 | 1 | Store 1 | - | 1 | 0 | Store 0 | - | 1 | 1 | No change | + | A | B | Action | + | --- | --- | ----------- | + | 0 | 0 | Not allowed | + | 0 | 1 | Store 1 | + | 1 | 0 | Store 0 | + | 1 | 1 | No change | + + +### Flip Flops + +- **`D Flip Flop`**: A positive edge triggered flip flop storing D value: + + + + | D | Q(t) | Q(t+1) | + | --- | ---- | ------ | + | 0 | 0 | 0 | + | 0 | 1 | 0 | + | 1 | 0 | 1 | + | 1 | 1 | 1 | + +- **`T Flip Flop`**: A positive edge triggered flip flop toggeling its value: + + + + | T | Q(t) | Q(t+1) | + | --- | ---- | ------ | + | 0 | 0 | 0 | + | 0 | 1 | 1 | + | 1 | 0 | 1 | + | 1 | 1 | 0 | > **Note** > Feel free to submit pull-requests for more module implementations diff --git a/assets/modules/d-flip-flop.png b/assets/modules/d-flip-flop.png new file mode 100644 index 0000000..f60e0cf Binary files /dev/null and b/assets/modules/d-flip-flop.png differ diff --git a/assets/modules/t-flip-flop.png b/assets/modules/t-flip-flop.png index e418be3..21ab9ae 100644 Binary files a/assets/modules/t-flip-flop.png and b/assets/modules/t-flip-flop.png differ diff --git a/examples/4-bit-counter.lrsproj b/examples/4-bit-counter.lrsproj index d1e8cc3..d139673 100644 --- a/examples/4-bit-counter.lrsproj +++ b/examples/4-bit-counter.lrsproj @@ -1 +1 @@ -{"modules":{},"main_plot":{"blocks":{"5354188438588814584":{"id":5354188438588814584,"name":"Lamp","position":[375,225],"size":[75,75],"unique":false,"passthrough":true,"inputs":[10440987279344356270],"outputs":[],"state":{"Direct":0},"output_state":0,"decoration":{"Lamp":true},"color":null},"17585780629157557337":{"id":17585780629157557337,"name":"T Flip-Flop","position":[125,25],"size":[110,75],"unique":false,"passthrough":true,"inputs":[895923654972995817],"outputs":[9271995660626457038],"state":{"Direct":2},"output_state":0,"decoration":{"Label":"T"},"color":null},"7846093778520356818":{"id":7846093778520356818,"name":"Lamp","position":[675,225],"size":[75,75],"unique":false,"passthrough":true,"inputs":[3134920317199890587],"outputs":[],"state":{"Direct":0},"output_state":0,"decoration":{"Lamp":true},"color":null},"17325373593975782801":{"id":17325373593975782801,"name":"T Flip-Flop","position":[275,25],"size":[110,75],"unique":false,"passthrough":true,"inputs":[9271995660626457038],"outputs":[8096273090428741690],"state":{"Direct":0},"output_state":0,"decoration":{"Label":"T"},"color":null},"7433714147185165618":{"id":7433714147185165618,"name":"T Flip-Flop","position":[425,25],"size":[110,75],"unique":false,"passthrough":true,"inputs":[8096273090428741690],"outputs":[6273669149933044936],"state":{"Direct":0},"output_state":0,"decoration":{"Label":"T"},"color":null},"3596810306868589121":{"id":3596810306868589121,"name":"Not","position":[125,125],"size":[75,75],"unique":false,"passthrough":true,"inputs":[895923654972995817],"outputs":[14744021733325809919],"state":{"Direct":0},"output_state":340282366920938463463374607431768211454,"decoration":{"NotLabel":"1"},"color":null},"12911774693485193003":{"id":12911774693485193003,"name":"Not","position":[25,25],"size":[75,75],"unique":false,"passthrough":true,"inputs":[895923654972995817],"outputs":[895923654972995817],"state":{"Direct":0},"output_state":340282366920938463463374607431768211455,"decoration":{"NotLabel":"1"},"color":null},"10497699952113116465":{"id":10497699952113116465,"name":"Not","position":[425,125],"size":[75,75],"unique":false,"passthrough":true,"inputs":[8096273090428741690],"outputs":[7588132761653207674],"state":{"Direct":0},"output_state":340282366920938463463374607431768211455,"decoration":{"NotLabel":"1"},"color":null},"16190443890770760703":{"id":16190443890770760703,"name":"Lamp","position":[525,225],"size":[75,75],"unique":false,"passthrough":true,"inputs":[7588132761653207674],"outputs":[],"state":{"Direct":0},"output_state":0,"decoration":{"Lamp":true},"color":null},"11961212448952297802":{"id":11961212448952297802,"name":"Not","position":[575,125],"size":[75,75],"unique":false,"passthrough":true,"inputs":[6273669149933044936],"outputs":[3134920317199890587],"state":{"Direct":0},"output_state":340282366920938463463374607431768211455,"decoration":{"NotLabel":"1"},"color":null},"13998638750705030997":{"id":13998638750705030997,"name":"Lamp","position":[225,225],"size":[75,75],"unique":false,"passthrough":true,"inputs":[14744021733325809919],"outputs":[],"state":{"Direct":0},"output_state":0,"decoration":{"Lamp":false},"color":null},"2861656550823996258":{"id":2861656550823996258,"name":"Not","position":[275,125],"size":[75,75],"unique":false,"passthrough":true,"inputs":[9271995660626457038],"outputs":[10440987279344356270],"state":{"Direct":0},"output_state":340282366920938463463374607431768211455,"decoration":{"NotLabel":"1"},"color":null}},"connections":{"9271995660626457038":{"id":9271995660626457038,"active":false,"origin":{"Output":[17585780629157557337,0]},"segments":{"4695115420018433688":{"Block":[2861656550823996258,0]},"13156344502743620961":{"Block":[17325373593975782801,0]}}},"3134920317199890587":{"id":3134920317199890587,"active":true,"origin":{"Output":[11961212448952297802,0]},"segments":{"10612020911719657597":{"Block":[7846093778520356818,0]}}},"7588132761653207674":{"id":7588132761653207674,"active":true,"origin":{"Output":[10497699952113116465,0]},"segments":{"18078718082634527518":{"Block":[16190443890770760703,0]}}},"10440987279344356270":{"id":10440987279344356270,"active":true,"origin":{"Output":[2861656550823996258,0]},"segments":{"4827306972552525760":{"Block":[5354188438588814584,0]}}},"6273669149933044936":{"id":6273669149933044936,"active":false,"origin":{"Output":[7433714147185165618,0]},"segments":{"4117633801655392617":{"Block":[11961212448952297802,0]}}},"895923654972995817":{"id":895923654972995817,"active":true,"origin":{"Output":[12911774693485193003,0]},"segments":{"9702505521668695002":{"Block":[12911774693485193003,0]},"7187239749178552577":{"Block":[3596810306868589121,0]},"8965177135727669501":{"Block":[17585780629157557337,0]}}},"14744021733325809919":{"id":14744021733325809919,"active":false,"origin":{"Output":[3596810306868589121,0]},"segments":{"14019196343756079993":{"Block":[13998638750705030997,0]}}},"8096273090428741690":{"id":8096273090428741690,"active":false,"origin":{"Output":[17325373593975782801,0]},"segments":{"6814540146988114983":{"Block":[7433714147185165618,0]},"2534036242052040424":{"Block":[10497699952113116465,0]}}}},"states":[{"blocks":{},"connections":{}}]},"tps":10} \ No newline at end of file +{"modules":{},"main_plot":{"blocks":{"3310398795976558300":{"id":3310398795976558300,"name":"High","position":[271,-7],"size":[75,75],"unique":false,"passthrough":true,"inputs":[],"outputs":[4672615323058003302],"state":{"Direct":0},"output_state":340282366920938463463374607431768211455,"decoration":{"Label":"1"},"color":null},"18193944025558943703":{"id":18193944025558943703,"name":"Lamp","position":[489,252],"size":[75,75],"unique":false,"passthrough":true,"inputs":[17115819071537323242],"outputs":[],"state":{"Direct":0},"output_state":0,"decoration":{"Lamp":false},"color":null},"13764986653674854796":{"id":13764986653674854796,"name":"T Flip-Flop","position":[522,118],"size":[110,100],"unique":false,"passthrough":true,"inputs":[4672615323058003302,13779025196202125909],"outputs":[5266926683341780562,null],"state":{"Direct":2},"output_state":340282366920938463463374607431768211450,"decoration":{"Label":"T"},"color":null},"15743551746034192670":{"id":15743551746034192670,"name":"T Flip-Flop","position":[233,118],"size":[110,100],"unique":false,"passthrough":true,"inputs":[4672615323058003302,11679388001501554237],"outputs":[7635165452054149733,3895035867946493813],"state":{"Direct":2},"output_state":340282366920938463463374607431768211450,"decoration":{"Label":"T"},"color":null},"2185657683087893488":{"id":2185657683087893488,"name":"T Flip-Flop","position":[90,118],"size":[110,100],"unique":false,"passthrough":true,"inputs":[4672615323058003302,9789689151405107917],"outputs":[9676552777124640418,11679388001501554237],"state":{"Direct":0},"output_state":340282366920938463463374607431768211454,"decoration":{"Label":"T"},"color":null},"8129519016779213416":{"id":8129519016779213416,"name":"Button","position":[11,251],"size":[75,75],"unique":false,"passthrough":true,"inputs":[],"outputs":[9789689151405107917],"state":{"Direct":0},"output_state":0,"decoration":{"Button":false},"color":null},"3757203818844583619":{"id":3757203818844583619,"name":"Lamp","position":[345,251],"size":[75,75],"unique":false,"passthrough":true,"inputs":[7635165452054149733],"outputs":[],"state":{"Direct":0},"output_state":0,"decoration":{"Lamp":false},"color":null},"3553480486059670029":{"id":3553480486059670029,"name":"T Flip-Flop","position":[379,118],"size":[110,100],"unique":false,"passthrough":true,"inputs":[4672615323058003302,3895035867946493813],"outputs":[17115819071537323242,13779025196202125909],"state":{"Direct":2},"output_state":340282366920938463463374607431768211450,"decoration":{"Label":"T"},"color":null},"16642788480495327288":{"id":16642788480495327288,"name":"Lamp","position":[633,250],"size":[75,75],"unique":false,"passthrough":true,"inputs":[5266926683341780562],"outputs":[],"state":{"Direct":0},"output_state":0,"decoration":{"Lamp":false},"color":null},"4986905588854076751":{"id":4986905588854076751,"name":"Lamp","position":[200,250],"size":[75,75],"unique":false,"passthrough":true,"inputs":[9676552777124640418],"outputs":[],"state":{"Direct":0},"output_state":0,"decoration":{"Lamp":false},"color":null}},"connections":{"11679388001501554237":{"id":11679388001501554237,"active":true,"origin":{"Output":[2185657683087893488,1]},"segments":{"1959939874093137484":{"Block":[15743551746034192670,1]}}},"7635165452054149733":{"id":7635165452054149733,"active":false,"origin":{"Output":[15743551746034192670,0]},"segments":{"2823241741726666062":{"Block":[3757203818844583619,0]}}},"5266926683341780562":{"id":5266926683341780562,"active":false,"origin":{"Output":[13764986653674854796,0]},"segments":{"16401291941952202028":{"Block":[16642788480495327288,0]}}},"4672615323058003302":{"id":4672615323058003302,"active":true,"origin":{"Output":[3310398795976558300,0]},"segments":{"11400273655492572696":{"Block":[13764986653674854796,0]},"5093895033105929308":{"Block":[3553480486059670029,0]},"4700516162004995735":{"Block":[2185657683087893488,0]},"15591164720030407252":{"Block":[15743551746034192670,0]}}},"3895035867946493813":{"id":3895035867946493813,"active":true,"origin":{"Output":[15743551746034192670,1]},"segments":{"4266020639005941764":{"Block":[3553480486059670029,1]}}},"9789689151405107917":{"id":9789689151405107917,"active":false,"origin":{"Output":[8129519016779213416,0]},"segments":{"10163194800539781641":{"Block":[2185657683087893488,1]}}},"9676552777124640418":{"id":9676552777124640418,"active":false,"origin":{"Output":[2185657683087893488,0]},"segments":{"6387114459403000980":{"Block":[4986905588854076751,0]}}},"13779025196202125909":{"id":13779025196202125909,"active":true,"origin":{"Output":[3553480486059670029,1]},"segments":{"18124619394754504424":{"Block":[13764986653674854796,1]}}},"17115819071537323242":{"id":17115819071537323242,"active":false,"origin":{"Output":[3553480486059670029,0]},"segments":{"14049412917095013675":{"Block":[18193944025558943703,0]}}}},"states":[{"blocks":{},"connections":{}}]},"tps":10} \ No newline at end of file diff --git a/src/simulator/builtin.rs b/src/simulator/builtin.rs index 12ce19e..416084f 100644 --- a/src/simulator/builtin.rs +++ b/src/simulator/builtin.rs @@ -262,6 +262,25 @@ lazy_static! { ), ); + builtins.insert( + "D Latch", + Builtin::new( + Module::new_builtin( + "D Latch", + Category::Latch, + 2, + 1, + Decoration::Label("D L".to_string()), + ), + |input, instance| { + if input & 0b10 > 0 { + instance.set_bytes(input); + } + instance.bytes() + }, + ), + ); + builtins.insert( "SR Nand Latch", Builtin::new( @@ -304,14 +323,28 @@ lazy_static! { ), ); + builtins.insert( + "D Flip-Flop", + Builtin::new( + Module::new_builtin( + "D Flip-Flop", + Category::FlipFlop, + 2, + 2, + Decoration::Label("D".to_string()), + ), + d_flip_flop, + ), + ); + builtins.insert( "T Flip-Flop", Builtin::new( Module::new_builtin( "T Flip-Flop", Category::FlipFlop, - 1, - 1, + 2, + 2, Decoration::Label("T".to_string()), ), t_flip_flop, @@ -363,10 +396,18 @@ fn sr_nand_latch(input: u128, instance: &mut Block) -> u128 { instance.bytes() | (((instance.bytes() == 0) as u128) << 1) } +fn d_flip_flop(input: u128, instance: &mut Block) -> u128 { + if input & 0b10 > 0 && instance.bytes() & 0b10 == 0 { + instance.set_bytes(input); + } + instance.set_bytes(instance.bytes() & !0b10 | (input & 0b10)); + instance.bytes() & 1 | !instance.bytes() << 1 +} + fn t_flip_flop(input: u128, instance: &mut Block) -> u128 { - if input & 1 > 0 && instance.bytes() & 0b10 == 0 { + if input == 0b11 && instance.bytes() & 0b10 == 0 { instance.set_bytes(instance.bytes() ^ 1); } - instance.set_bytes((instance.bytes() & !0b10) | (input << 1)); - instance.bytes() & 1 + instance.set_bytes((instance.bytes() & !0b10) | (input & 0b10)); + instance.bytes() & 1 | !instance.bytes() << 1 }