Process pipelining in VHDL? - vhdl

For the past few days I have been searching for a method of writing a bit of VHDL for a project that will allow me to trigger the processing of a set of data and transmit the results. The device I am using can begin to collect a second set of data while simultaneously serving up the complete first set for my FPGA to transmit, and I want to take advantage of this via pipelining but I haven't been successful.
To trigger the collection I need to send a specific set of signals in a specific order. After a few clock cycles and a signal from the FPGA, the complete set is then output on several ports from the device. My goal is for the whole process to be started by a simple input pulse, and for it to be possible for a second pulse to occur while the assignments from the first pulse are still occuring. Is there a way for me to send the first set of signals, and then later the signal to output the data while simultaneously sending the first set of signals for the second collection, if that makes sense?
Here's a picture of what I mean.
(clickable)
As you can see, the data from integration 1 is sent during the second and even third integration stage. load_pulse is the signal that requests the data to be output on DATA, and it can occur much later while the second set of signals for integration 2 are sent.
Here's a bit of test VHDL that I wrote to see if it was possible with a simple process:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity test is
port(
x : in STD_LOGIC;
y : out STD_LOGIC := '0';
z : out STD_LOGIC := '0'
);
end test;
architecture test_behav of test is
begin
process(x) is
begin
y <= '0', '1' after 10 NS, '0' after 20 ns;
z <= '0', '1' after 30 NS, '0' after 40 ns;
end process;
end test_behav;
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity testbench is
end testbench;
architecture testbench_behav of testbench is
component test is
port(
x : in STD_LOGIC;
y : out STD_LOGIC;
z : out STD_LOGIC
);
end component test;
signal x : STD_LOGIC := '0';
signal y : STD_LOGIC := '0';
signal z : STD_LOGIC := '0';
begin
testo: component test
port map(
x => x,
y => y,
z => z
);
x <= '1' after 25 ns;
end testbench_behav;
In this example, I trigger the process while its signal assignments are still executing. The result here was that the original signal assignments were interrupted and the new signal assignments completed after x <= '1' after 25 ns, as you can see here:
(clickable)
Is there a way to accomplish this that you can explain to me or point me to an explanation of, or will I need to take another approach?
Thanks

Related

Initializing signals in vhdl componets

I was hoping you could help me with a problem I encountered while trying to design synchronous circuits.
I have a simple D flip-flop in my design, such as the one shown in the figure below. But when I initialize my inputs and set the reset to 1 in the test bench, the output of the D flip-flop is always undefined (as can be seen in the "Objects" view), even though I explicitly define it to be 0 when reset is high (the code for the D flip-flop is shown below).
This causes errors in larger circuits when I use the flip-flops and the outputs as signals to other components that require a defined input. How can I achieve an output of zero when my reset is high during initialization?
library ieee;
use ieee.std_logic_1164.all;
entity Dff_en is
port (
d : in std_logic;
en : in std_logic;
clk : in std_logic;
reset : in std_logic;
q : out std_logic
) ;
end entity;
architecture rtl of Dff_en is
signal q_next, q_reg : std_logic;
begin
--dff logic
process(clk, reset) is
begin
if(reset = '1') then
q_reg <= '0';
elsif(rising_edge(clk)) then
q_reg <= q_next;
end if;
end process;
-- next-state logic
q_next <= d when (en = '1') else q_reg;
--output
q <= q_reg;
end architecture; -- arch
Your code will only update the q_reg output when there are events on the signals in the sensitivity list (clk, reset). VHDL (and Verilog) require events to trigger changes. With signal initialization, then at time 0 the values are set, but there are no further events to simulate.
Even if you did a run 100 ns, there would be no change in outputs since you have not had any events. Change either clk or reset some time after time 0 and try again.

Strange behaviour in VHDL

I'm trying to integrate (sum) a 14-bit signal of ADC at 50 Mhz. The integration starts with rising edge of signal "trigger". If the integral reaches a defined threshold (6000000), a digital signal ("dout") should be set to 0 (which became 1 with "trigger" becoming 1). So far a quite easy task.
Though on the hardware itself (Cyclone V) I realized a strange behaviour. Although I kept the voltage level at the ADC constant, the pulse width of the output signal "dout" is sometimes fluctuating (although it should stay nearly constant for a constant 14-bit value at the ADC, which has a low noise). The pulse width is decreasing with rising voltage level, so the integration itself works fine. But it keeps fluctuating.
Here is my code:
library IEEE;
use IEEE.std_logic_1164.all;
use ieee.numeric_std.all;
entity integrator is
port(
trigger: in std_logic;
adc: in std_logic_vector(13 downto 0);
clk: in std_logic;
dout: out std_logic);
end integrator ;
architecture rtl of integrator is
signal sum : integer;
begin
process(clk) is
begin
if rising_edge(clk) then
if (trigger='1') and (sum<6000000) then
sum<=sum+to_integer(unsigned(adc));
dout<='1';
else
dout<='0';
if (trigger='0') then
sum<=0;
end if;
end if;
end if;
end process;
end rtl;
I checked the signals using SignalTab II of Quartus Prime. I realized that the value of "sum" was rising, but not perfectly correct (compared the sum I calculated manually of the values of "adc".
I used a PLL to phase shift the 50 Mhz clock ("clk") about 90 degrees. The resulting clock served as input for the ADC clock. I left out the PLL and the value of "sum" matched. Nonetheless I see fluctuations in the "dout" signal (oscilloscope).
Even more strange: I changed the type of "sum" to unsigned and finally the fluctuations disappeared. But only without using the PLL! But while making adaptations to the code below the fluctuations came back. Maybe the sum of integer and unsigned leaded to another timing?!?
The questions are now:
- Why the value of "sum" is incorrect when using PLL (I though the value of "adc" should stay constant for half a clock cycle when phase shifting of 90 degrees)?
- Why I see the fluctuations in "dout"? Is there something wrong with the code?
EDIT1: Add testbench
Here is my testbench:
library IEEE;
use IEEE.std_logic_1164.all;
use ieee.numeric_std.all;
entity testbench is
end testbench;
architecture tb of testbench is
component integrator is
port(
trigger: in std_logic;
adc: in std_logic_vector(13 downto 0);
clk: in std_logic;
dout: out std_logic);
end component;
signal trigger_in, clk_in, dout_out: std_logic;
signal adc_in: std_logic_vector(13 downto 0);
begin
DUT: integrator port map(trigger_in, adc_in, clk_in, dout_out);
process
begin
for I in 1 to 4500 loop
clk_in <= '0';
wait for 10 ns;
clk_in <= '1';
wait for 10 ns;
end loop;
wait;
end process;
process
begin
trigger_in <= '0';
wait for 10 us;
trigger_in <= '1';
wait for 30 us;
trigger_in <= '0';
wait for 10 us;
trigger_in <= '1';
wait for 30 us;
trigger_in <= '0';
wait for 10 us;
wait;
end process;
process
begin
adc_in <= (others => '0');
wait for 10 us;
adc_in <= std_logic_vector(to_unsigned(6000, 14));
wait for 30 us;
adc_in <= (others => '0');
wait for 10 us;
adc_in <= std_logic_vector(to_unsigned(6000, 14));
wait for 30 us;
adc_in <= (others => '0');
wait for 10 us;
wait;
end process;
end tb;
And the resulting output:
I asked for a test-bench because your code looks a bit strange. Just as user1155120 I noticed that the summation takes place outside any condition which can cause overflow. You do not see that overflow because you do not test for it in your test bench.
I can make a suggestion to change your code but the problem, lies in the specification:
If the integral reaches a defined threshold (6000000),...
You do not specify what the sum should do in that case. Continue? Hold?
If you let it continue it will at some point warp around and become negative.
A possible solution would be:
if sum<some_maximum_value_you_define then
sum<=sum+to_integer(unsigned(adc));
end if;
A possible maximum value would be 231-214-1.
Alternative you must make sure the the trigger_in comes fast enough that a the sum never overflows. With 50MHz sampling and a 14 bit ADC that means at least 382Hz.
I would add some VHDL code to check the ADC signal. e.g. maximum and minimum values seen. Compare those against the actual (more or less constant) input value. That might give you an idea about the stability/reliability of the sampling.
thanks for all the responses. It helped my to get a bit further. I checked the ADC signal, but there is only noise of around 10 (of 14-Bit) and no unexpected values. Furthermore all the other signals (tried without logic) are fine.
I also found a solution for the inconsistent sum behaviour. I just saved it in temp_adc before the calculations. I tried variable and signal but I go with signal, because i can visualize it in SignalTap (of course there is a delay of one clock cycle now):
library IEEE;
use IEEE.std_logic_1164.all;
use ieee.numeric_std.all;
entity integrator is
port(
trigger: in std_logic;
adc: in std_logic_vector(13 downto 0);
clk: in std_logic;
dout: out std_logic);
end integrator ;
architecture rtl of integrator is
signal sum : integer;
signal temp_adc : unsigned(13 downto 0);
begin
process(clk) is
begin
temp_adc<=unsigned(adc);
if rising_edge(clk) then
if (trigger='1') and (sum<6000000) then
sum<=sum+to_integer(tem_adc);
dout<='1';
else
dout<='0';
if (trigger='0') then
sum<=0;
end if;
end if;
end if;
end process;
end rtl;
In SignalTap now it's fitting well (sum=sum+temp_adc) most of the time. Coming back to the problem: I found a way in SignalTap to trigger unexpected events. I found one very strange behaviour:
Lets t=0 be the cycle in which trigger goes '1'. The output looks like this:
This means dout just goes '1' for a single clock cycle due to the high value in sum. This happens random but with around every 300th pulse.
Looks like there is something like an overflow with a single adc added to sum. Do you have any ideas where this comes from?
Additionally I played around with the PLL for the ADC clock. I tried different phase shifts (0°, 90°, 180°) but the result is more or less the same.
Sorry guys. The problem was a misconfigured Quartus project with wrong

Alternative method for creating low clock frequencies in VHDL

In the past I asked a question about resets, and how to divide a high clock frequency down to a series of lower clock square wave frequencies, where each output is a harmonic of one another e.g. the first output is 10 Hz, second is 20 Hz etc.
I received several really helpful answers recommending what appears to be the convention of using a clock enable pin to create lower frequencies.
An alternative since occurred to me; using a n bit number that is constantly incremented, and taking the last x bits of the number as the clock ouputs, where x is the number of outputs.
It works in synthesis for me - but I'm curious to know - as I've never seen it mentioned anywhere online or on SO, am I missing something that means its actually a terrible idea and I'm simply creating problems for later?
I'm aware that the limitations on this are that I can only produce frequencies that are the input frequency divided by a power of 2, and so most of the time it will only approximate the desired output frequency (but will still be of the right order). Is this limitation the only reason it isn't recommended?
Thanks very much!
David
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
library UNISIM;
use UNISIM.VComponents.all;
use IEEE.math_real.all;
ENTITY CLK_DIVIDER IS
GENERIC(INPUT_FREQ : INTEGER; --Can only divide the input frequency by a power a of 2
OUT1_FREQ : INTEGER
);
PORT(SYSCLK : IN STD_LOGIC;
RESET_N : IN STD_LOGIC;
OUT1 : OUT STD_LOGIC; --Actual divider is 2^(ceiling[log2(input/freq)])
OUT2 : OUT STD_LOGIC); --Actual output is input over value above
END CLK_DIVIDER;
architecture Behavioral of Clk_Divider is
constant divider : integer := INPUT_FREQ / OUT1_FREQ;
constant counter_bits : integer := integer(ceil(log2(real(divider))));
signal counter : unsigned(counter_bits - 1 downto 0) := (others => '0');
begin
proc : process(SYSCLK)
begin
if rising_edge(SYSCLK) then
counter <= counter + 1;
if RESET_N = '0' then
counter <= (others => '0');
end if;
end if;
end process;
OUT1 <= counter(counter'length - 1);
OUT2 <= not counter(counter'length - 2);
end Behavioral;
Functionally the two outputs OUT1 and OUT2 can be used as clocks, but that method of making clocks does not scale and is likely to cause problems in the implementation, so it is a bad habit. However, it is of course important to understand why this is so.
The reason it does not scale, is that every signal used as clock in a FPGA is to be distributed through a special clock net, where the latency and skew is well-defined, so all flip-flops and memories on each clock are updated synchronously. The number of such clock nets is very limited, usually in the range of 10 to 40 in a FPGA device, and some restrictions on use and location makes it typically even more critical to plan the use of clock nets. So it is typically required to reserve clock nets for only real asynchronous clocks, where there is no alternative than to use a clock net.
The reason it is likely to cause problems, is that clocks created based on bits in a counter have no guaranteed timing relation. So if it is required to moved data between these clock domains, it requires additional constrains for synchronization, in order to be sure that the Clock Domain Crossing (CDC) is handled correctly. This is done through constrains for synthesis and/or Static Timing Analysis (STA), and is usually a little tricky to get right, so using a design methodology that simplifies STA is habit that saves design time.
So in designs where it is possible to use a common clock, and then generate synchronous clock enable signals, this should be the preferred approach. For the specific design above, a clock enable can be generated simply by detecting the '0' to '1' transition of the relevant counter bit, and then assert the clock enable in the single cycle where the transition is detected. Then a single clock net can be used, together with 2 clock enables like CE1 and CE2, and no special STA constrains are required.
Morten already pointed out the theory in his answer.
With the aid of two examples, I will demonstrate the problems you encounter when using a generated clock instead of clock enables.
Clock Distribution
At first, one must take care that a clock arrives at (almost) the same time at all destination flip-flops. Otherwise, even a simple shift register with 2 stages like this one would fail:
process(clk_gen)
begin
if rising_edge(clk_gen) then
tmp <= d;
q <= tmp;
end if;
end if;
The intended behavior of this example is that q gets the value of d after two rising edges of the generated clock clock_gen.
If the generated clock is not buffered by a global clock buffer, then the delay will be different for each destination flip-flop because it will be routed via the general-purpose routing.
Thus, the behavior of the shift register can be described as follows with some explicit delays:
library ieee;
use ieee.std_logic_1164.all;
entity shift_reg is
port (
clk_gen : in std_logic;
d : in std_logic;
q : out std_logic);
end shift_reg;
architecture rtl of shift_reg is
signal ff_0_q : std_logic := '0'; -- output of flip-flop 0
signal ff_1_q : std_logic := '0'; -- output of flip-flop 1
signal ff_0_c : std_logic; -- clock input of flip-flop 0
signal ff_1_c : std_logic; -- clock input of flip-flop 1
begin -- rtl
-- different clock delay per flip-flop if general-purpose routing is used
ff_0_c <= transport clk_gen after 500 ps;
ff_1_c <= transport clk_gen after 1000 ps;
-- two closely packed registers with clock-to-output delay of 100 ps
ff_0_q <= d after 100 ps when rising_edge(ff_0_c);
ff_1_q <= ff_0_q after 100 ps when rising_edge(ff_1_c);
q <= ff_1_q;
end rtl;
The following test bench just feeds in a '1' at input d, so that, q should be '0' after 1 clock edge an '1' after two clock edges.
library ieee;
use ieee.std_logic_1164.all;
entity shift_reg_tb is
end shift_reg_tb;
architecture sim of shift_reg_tb is
signal clk_gen : std_logic;
signal d : std_logic;
signal q : std_logic;
begin -- sim
DUT: entity work.shift_reg port map (clk_gen => clk_gen, d => d, q => q);
WaveGen_Proc: process
begin
-- Note: registers inside DUT are initialized to zero
d <= '1'; -- shift in '1'
clk_gen <= '0';
wait for 2 ns;
clk_gen <= '1'; -- just one rising edge
wait for 2 ns;
assert q = '0' report "Wrong output" severity error;
wait;
end process WaveGen_Proc;
end sim;
But, the simulation waveform shows that q already gets '1' after the first clock edge (at 3.1 ns) which is not the intended behavior.
That's because FF 1 already sees the new value from FF 0 when the clock arrives there.
This problem can be solved by distributing the generated clock via a clock tree which has a low skew.
To access one of the clock trees of the FPGA, one must use a global clock buffer, e.g., BUFG on Xilinx FPGAs.
Data Handover
The second problem is the handover of multi-bit signals between two clock domains.
Let's assume we have 2 registers with 2 bits each. Register 0 is clocked by the original clock and register 1 is clocked by the generated clock.
The generated clock is already distributed by clock tree.
Register 1 just samples the output from register 0.
But now, the different wire delays for both register bits in between play an important role. These have been modeled explicitly in the following design:
library ieee;
use ieee.std_logic_1164.all;
library unisim;
use unisim.vcomponents.all;
entity handover is
port (
clk_orig : in std_logic; -- original clock
d : in std_logic_vector(1 downto 0); -- data input
q : out std_logic_vector(1 downto 0)); -- data output
end handover;
architecture rtl of handover is
signal div_q : std_logic := '0'; -- output of clock divider
signal bufg_o : std_logic := '0'; -- output of clock buffer
signal clk_gen : std_logic; -- generated clock
signal reg_0_q : std_logic_vector(1 downto 0) := "00"; -- output of register 0
signal reg_1_d : std_logic_vector(1 downto 0); -- data input of register 1
signal reg_1_q : std_logic_vector(1 downto 0) := "00"; -- output of register 1
begin -- rtl
-- Generate a clock by dividing the original clock by 2.
-- The 100 ps delay is the clock-to-output time of the flip-flop.
div_q <= not div_q after 100 ps when rising_edge(clk_orig);
-- Add global clock-buffer as well as mimic some delay.
-- Clock arrives at (almost) same time on all destination flip-flops.
clk_gen_bufg : BUFG port map (I => div_q, O => bufg_o);
clk_gen <= transport bufg_o after 1000 ps;
-- Sample data input with original clock
reg_0_q <= d after 100 ps when rising_edge(clk_orig);
-- Different wire delays between register 0 and register 1 for each bit
reg_1_d(0) <= transport reg_0_q(0) after 500 ps;
reg_1_d(1) <= transport reg_0_q(1) after 1500 ps;
-- All flip-flops of register 1 are clocked at the same time due to clock buffer.
reg_1_q <= reg_1_d after 100 ps when rising_edge(clk_gen);
q <= reg_1_q;
end rtl;
Now, just feed in the new data value "11" via register 0 with this testbench:
library ieee;
use ieee.std_logic_1164.all;
entity handover_tb is
end handover_tb;
architecture sim of handover_tb is
signal clk_orig : std_logic := '0';
signal d : std_logic_vector(1 downto 0);
signal q : std_logic_vector(1 downto 0);
begin -- sim
DUT: entity work.handover port map (clk_orig => clk_orig, d => d, q => q);
WaveGen_Proc: process
begin
-- Note: registers inside DUT are initialized to zero
d <= "11";
clk_orig <= '0';
for i in 0 to 7 loop -- 4 clock periods
wait for 2 ns;
clk_orig <= not clk_orig;
end loop; -- i
wait;
end process WaveGen_Proc;
end sim;
As can be seen in the following simulation output, the output of register 1 toggles to an intermediate value of "01" at 3.1 ns first because the input of register 1 (reg_1_d) is still changing when the rising edge of the generated clock occurs.
The intermediate value was not intended and can lead to undesired behavior. The correct value is seen not until another rising edge of the generated clock.
To solve this issue, one can use:
special codes, where only one bit flips at a time, e.g., gray code, or
cross-clock FIFOs, or
handshaking with the help of single control bits.

VHDL MUX Test Bench Issue

I'm trying to learn VHDL through P. Ashenden's book: Designer's Guide to VHDL. Chapter one's exercise 10 asks you to write 2-to-1 (I'm assuming 1 bit wide) MUX in VHDL and simulate it. I apologize in advance for being a complete noob. This is my first VHDL code.
My MUX didn't produce any errors or warnings in synthesis. My test bench doesn't produce errors or warnings, either. However, the simulation comes up completely blank, except for the names of the signals.
I've tried looking at a multitude of other MUX examples online (as well as a bench test example from the book), all of which gave errors when I tried sythesizing them, so I wasn't confident enough to use them as guides and didn't get much out of them. I'm not sure what I'm doing wrong here. I'd include an image of the simulation, but I don't have enough rep points :(
Also, I realize that a good MUX should also have cases for when it receives no select input/high impedance values, ect.. In this case, I'm just trying to get the toy model working.
The MUX code is:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity MUXtop is
Port (a, b, sel: in bit;
z: out bit);
end MUXtop;
architecture behav of MUXtop is
begin
choose: process is
begin
if sel = '0' then
z <= b;
else
z <= a;
end if;
end process choose;
end architecture behav;
The test bench code is:
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
ENTITY MUXtest IS
END MUXtest;
ARCHITECTURE behavior OF MUXtest IS
-- Component Declaration for the Unit Under Test (UUT)
COMPONENT MUXtop
PORT(
a : IN bit;
b : IN bit;
sel : IN bit;
z : OUT bit
);
END COMPONENT MUXtop;
--Inputs
signal a : bit := '0';
signal b : bit := '0';
signal sel : bit := '0';
--Outputs
signal z : bit;
BEGIN
-- Instantiate the Unit Under Test (UUT)
uut: MUXtop PORT MAP (
a => a,
b => b,
sel => sel,
z => z
);
-- Stimulus process
stimulus: process
begin
wait for 10 ns;
a <= '1';
wait for 10 ns;
sel <= '1';
wait for 10 ns;
b <= '1';
wait;
end process stimulus;
END architecture behavior;
You don't need a use clause for package std_logic_1164 when using type bit (declared in package standard).
Your process statement choose in MUXtop has no sensitivity clause which cause the process to continually execute in simulation. (It won't do anything until you trip over a delta cycle iteration limit which might be set to infinity).
I added a sensitivity list, commented out the superfluous use clauses in the two design units and added some more stimulus steps as well as a final wait for 10 ns; to allow the last action to be seen in your testbench:
library IEEE;
-- use IEEE.STD_LOGIC_1164.ALL;
entity MUXtop is
Port (a, b, sel: in bit;
z: out bit);
end MUXtop;
architecture behav of MUXtop is
begin
choose: process (a, b, sel) -- is
begin
if sel = '0' then
z <= b;
else
z <= a;
end if;
end process choose;
end architecture behav;
LIBRARY ieee;
-- USE ieee.std_logic_1164.ALL;
ENTITY MUXtest IS
END MUXtest;
ARCHITECTURE behavior OF MUXtest IS
-- Component Declaration for the Unit Under Test (UUT)
COMPONENT MUXtop
PORT(
a : IN bit;
b : IN bit;
sel : IN bit;
z : OUT bit
);
END COMPONENT MUXtop;
--Inputs
signal a : bit := '0';
signal b : bit := '0';
signal sel : bit := '0';
--Outputs
signal z : bit;
BEGIN
-- Instantiate the Unit Under Test (UUT)
uut: MUXtop PORT MAP (
a => a,
b => b,
sel => sel,
z => z
);
-- Stimulus process
stimulus: process
begin
wait for 10 ns;
a <= '1';
wait for 10 ns;
sel <= '1';
wait for 10 ns;
sel <= '0'; -- added
wait for 10 ns; -- added
b <= '1';
wait for 10 ns; -- added
wait;
end process stimulus;
END architecture behavior;
And that gives:
(clickable)

VHDL clock divider works on board but fails in simulation

I'm presently trying to use VHDL to design a traffic light controller, which I'm programming on an Altera EPM240T100C5 with a custom expansion board for displaying the traffic lights. As the slowest clock setting on the board is still faster than I would like, I've needed to write a clock divider which I did as so:
LIBRARY ieee;
USE ieee.std_logic_1164.all;
entity clockdivider is
port
(
clkin : in std_logic;
dividedclk : out std_logic
);
end clockdivider;
architecture divider of clockdivider is
signal J : std_logic;
signal K : std_logic;
begin
J <= '1';
K <= '1';
process(clkin)
variable tempdividedclk : std_logic;
begin
if (rising_edge(clkin)) then
tempdividedclk := (NOT(tempdividedclk) AND J) OR (tempdividedclk AND (NOT(K)));
end if;
dividedclk <= '0';
dividedclk <= tempdividedclk;
end process;
END divider;
This runs fine on the board but in the simulator (ModelSim) the "dividedclk" output fails to ever initialise to anything. I was wondering if anyone had any idea why?
At the beginning of the simulation, "tempdividedclk" is initialized to "unitialized".
When a clock edge occurs, tempdividedclk will be assigned to (not(U) and 1) or (U and 0), which is "undefined". To simulate correctly, tempdividedclk must be initialized either by a reset or just at simulation level. It works find on silicon because the "U" state will be either a 1 or a 0.

Resources