Set/Reset latches are quite common building blocks. They are also known as bi-stable multivibrators since they maintain two stable states. On the hardware level the implementation involves wiring two NOR gates in such a way that the output of each one acts as an input of the other. In the software world it involves two assignment statements consuming each other's results.
The truth table of this component looks like this:
The outputs are inverted in the case of S or R being active.
If both S and R are active outputs are reset.
If both S and R are reset the outputs preserve their previous state.
Here is the code:
FUNCTION_BLOCK "SR_LATCH"
VERSION:1.0
VAR_INPUT
S : BOOL; // Set input
R : BOOL; // Reset input
END_VAR
VAR_OUTPUT
Q : BOOL; // Output Q
Q1 : BOOL; // Output Q1
END_VAR
BEGIN
#Q := not #R and not #Q1; // NOR
#Q1 := not #S and not #Q; // NOR
END_FUNCTION_BLOCK
The main FB looks like this:
FUNCTION_BLOCK "MAIN"
VERSION:1.0
VAR_INPUT
S : BOOL;
R : BOOL;
END_VAR
VAR_OUTPUT
Q : BOOL;
Q1 : BOOL;
END_VAR
VAR
latch : "SR_LATCH";
END_VAR
BEGIN
#latch(S:=#S, R:=#R, Q=>#Q, Q1=>#Q1); // call the S-R latch
if #Q then
; // do something
end_if;
END_FUNCTION_BLOCK
Cool! Now you have a FB that can be easily reused in any context.
Import it in PS, wire some signals and try it.
Something to be aware of: It is most likely that neither S or R will be active when the simulation starts. The truth table tells us that in this case the latch will do its job but what values will be provided on output? With this implementation the Q output will be active which might not be a desired result. If so you should make sure the initial state of the inputs is set.
An alternative form of the S-R Latch (known as Gated S-R Latch) allows you to change the set/reset inputs only when a specific condition is met. This latch has an additional enable input (E). When E = False the S/R inputs are ignored. When E = True the S/R inputs work as before.
Here is the code:
FUNCTION_BLOCK "SR_LATCH"
VERSION:1.0
VAR_INPUT
S : BOOL; // Set input
R : BOOL; // Reset input
E : BOOL; // Enable input
END_VAR
VAR_OUTPUT
Q : BOOL; // Output Q
Q1 : BOOL; // Output Q1
END_VAR
BEGIN
#Q := not (#R and #E) and not #Q1; // NOR (R AND E), Q1
#Q1 := not (#S and #E) and not #Q; // NOR (S AND E), Q END_FUNCTION_BLOCK
Isn't it lovely how easy it is to change the behavior? Just edit the code and run the simulation again. No complex workflows, no ambiguity of any type. That is the power behind the script!
See you!
Comments