DFT 3
DFT 3
Abstract—This work presents fault modeling and observation • Input w stuck-at: SA0/SA1 on w (MSB/decoder select).
of stuck-at-0/1 (SA0/SA1) faults on a hierarchical 4→16 one- Global stuck-at moves activations between halves.
hot decoder implemented using two 3→8 decoders. We analyze • Output D3 stuck-at: SA0 forces missing one-hot at
faults on input lines z and w and on output line D3. For each
case we provide nominal and faulty truth tables, outline a VHDL i=3; SA1 breaks one-hot by asserting D3 alongside the
testbench methodology, and reserve space for waveform captures. nominal line for i̸=3.
The results quantify how specific stuck-at locations translate
into predictable output aliasing (e.g., index shifts or decoder-half IV. M ETHODOLOGY
swaps) and violations of the one-hot property. Design
I. O BJECTIVES • Write a synthesizable VHDL for a 3→8 decoder with
enable and instantiate it twice to form a 4→16 decoder.
• Implement a 4→16 decoder (one-hot) using two 3→8
• Expose fault injection via generics or signals (e.g.,
decoders.
fault_z_sa0, fault_z_sa1, fault_w_sa0,
• Model SA0/SA1 faults at: input z, input w, and output
fault_w_sa1, fault_D3_sa0, fault_D3_sa1).
line D3.
• Generate truth tables (nominal vs. faulty) and verify via Verification
VHDL simulation.
• Exhaustively stimulate all 16 input combinations; log
• Capture and annotate timing waveforms that expose
expected and observed one-hot indices.
faulty behavior.
• Capture waveforms (pre/post fault toggling) and annotate
II. C IRCUIT U NDER T EST (CUT) mismatches.
We consider inputs {w, x, y, z} with w as MSB. Index V. VHDL L ISTINGS
mapping: A. 3→8 Decoder (with Enable)
index i = 8w + 4x + 2y + z, Expected high line: Di.
Listing 1: Decoder 3-¿8 (enable)
The 4→16 decoder is realized using two 3→8 decoders. When library ieee;
w=0 the lower 3→8 (outputs D0–D7) is enabled; when w=1 use ieee.std_logic_1164.all;
the upper 3→8 (outputs D8–D15) is enabled. entity decoder_3x8 is
port (
Ctrl1,Ctrl2,Ctrl3 :in std_logic ;
Enable : in std_logic;
Y : out std_logic_vector (7 downto 0)
);
end entity decoder_3x8;
process(sel, Enable)
Fig. 1: 4→16 decoder from two 3→8 blocks; w selects begin
lower/upper half; {x, y, z} go to both 3→8 units. if Enable = ’1’ then
case sel is
when "000" => Y <= "00000001";
when "001" => Y <= "00000010";
III. FAULT M ODELS C ONSIDERED when "010" => Y <= "00000100";
when "011" => Y <= "00001000";
• Input z stuck-at: SA0/SA1 on the global z line (affects when "100" => Y <= "00010000";
both halves). when "101" => Y <= "00100000";
when "110" => Y <= "01000000"; end process;
when "111" => Y <= "10000000";
when others => Y <= (others => ’0’); uut_mux: entity work.mux_special
end case; port map(in_sig => mux_in_sig, sel => CtrlB,
else out_sig => mux_out);
Y <= (others => ’0’);
end if; -- Assign mux output to the appropriate faulted
end process; input based on CtrlA
-- Replace your "Assign mux output..." process
with this
end architecture behavioral; process(CtrlA, mux_out, x, y, z, w)
begin
-- defaults: pass-through when not selected for
B. Top-level 4→16 from Two 3→8 faulting
fx1 <= x; fx2 <= x;
fy1 <= y; fy2 <= y;
Listing 2: Top-level 4-¿16 decoder fz1 <= z; fz2 <= z;
library IEEE; fw1 <= w; fw2 <= w;
use IEEE.STD_LOGIC_1164.ALL;
case CtrlA is
entity test is when "00" => fx1 <= mux_out(0); fx2 <= mux_out
port( (1);
sao : in std_logic; -- output stuck-at enable when "01" => fy1 <= mux_out(0); fy2 <= mux_out
CtrlA : in std_logic_vector(1 downto 0); -- (1);
select which input to fault when "10" => fz1 <= mux_out(0); fz2 <= mux_out
CtrlB : in std_logic_vector(2 downto 0); -- type (1);
of fault at input mux when others => fw1 <= mux_out(0); fw2 <=
CtrlO : in std_logic_vector(4 downto 0); -- mux_out(1);
output fault control (4 bits select + 1 bit end case;
fault value) end process;
x, y, z, w : in std_logic; -- decoder inputs
OutA : out std_logic_vector (15 downto 0) -- nfw1<=not fw1;
decoder outputs
); ------------------------------------------------------------
end test;
-- 4x16 Decoder using two 3x8 decoders
architecture Structural of test is ------------------------------------------------------------
-- Case 1: w=0 -> lower half (bits 15..8) in -- W fan-in SA0 -> fw1=0, fw2=0 => Enable_low
your DUT (dec_low & dec_high) = not 0 = 1, Enable_high = 0
x<=’1’; y<=’0’; z<=’1’; w<=’0’; x<=’0’; y<=’1’; z<=’1’; w<=’1’; -- original w
sao<=’0’; CtrlA<="00"; CtrlB<=PASS_THR; CtrlO irrelevant
<=(others=>’0’); CtrlA<="11"; CtrlB<=BOTH_0; -- select w, force
wait for 10 ns; 0,0
-- Enabled half is dec_low => bit = 8 + idx(z, wait for 10 ns;
y,x) pos := 8 + idx3(z,y,x); -- lower half active
pos := 8 + idx3(z,y,x); assert_one_hot(OutA, pos, "W fan-in SA0 failed
assert_one_hot(OutA, pos, "Baseline w=0 failed ");
");
-- W fan-in SA1 -> fw1=1, fw2=1 => Enable_low
-- Case 2: w=1 -> upper half (bits 7..0) in = 0, Enable_high = 1
your DUT CtrlA<="11"; CtrlB<=BOTH_1;
x<=’0’; y<=’1’; z<=’0’; w<=’1’; wait for 10 ns;
CtrlA<="00"; CtrlB<=PASS_THR; -- any CtrlA OK pos := idx3(z,y,x); -- upper half active
when PASS_THR + patched DUT assert_one_hot(OutA, pos, "W fan-in SA1 failed
wait for 10 ns; ");
pos := idx3(z,y,x);
assert_one_hot(OutA, pos, "Baseline w=1 failed report "====== W FAN-OUT example (both halves
"); may be enabled/disabled) ======";
report "====== Z FAN-IN SA0 and SA1 ======"; -- Lower branch stuck 0, upper follows w
-- CtrlB = in,0 => fw1=’0’, fw2=w
-- Z fan-in SA0 (both branches z=0) -- For w=’1’ -> Enable_low=1 and Enable_high=1
x<=’1’; y<=’1’; z<=’1’; w<=’1’; (both halves active, two ’1’s total)
CtrlA<="10"; CtrlB<=BOTH_0; -- select z, force w<=’1’; CtrlA<="11"; CtrlB<=L0_RIN;
0,0 x<=’1’; y<=’0’; z<=’0’;
wait for 10 ns; wait for 10 ns;
pos := idx3(’0’, y, x); -- w=1 -> upper half assert popcount(OutA) = 2
uses z2, but both 0 anyway report "W fan-out (low stuck 0, w=1) should
assert_one_hot(OutA, pos, "Z fan-in SA0 failed enable both halves -> two ones" severity
(w=1)"); error;
-- Z fan-in SA1 (both branches z=1) report "====== OUTPUT STUCK-AT on OUTA(3)
CtrlA<="10"; CtrlB<=BOTH_1; ======";
wait for 10 ns;
pos := idx3(’1’, y, x); -- Clear any output fault
assert_one_hot(OutA, pos, "Z fan-in SA1 failed sao <= ’0’; CtrlO <= (others => ’0’);
(w=1)"); -- Drive some normal code that would NOT hit
bit 3
-- Also check with w=0 (lower half active) x<=’0’; y<=’0’; z<=’0’; w<=’0’;
w<=’0’; x<=’0’; y<=’1’; CtrlA<="00"; CtrlB<=PASS_THR;
CtrlA<="10"; CtrlB<=BOTH_0; wait for 10 ns;
wait for 10 ns; -- Force OUTA(3) stuck-at 0
pos := 8 + idx3(’0’, y, x); sao <= ’1’; CtrlO <= "00110"; -- select=0011 (
assert_one_hot(OutA, pos, "Z fan-in SA0 failed bit 3), value=0
(w=0)"); wait for 10 ns;
assert OutA(3) = ’0’ report "OUTA(3) SA0
report "====== Z FAN-OUT faults (one branch failed" severity error;
stuck, other follows) ======";
-- Force OUTA(3) stuck-at 1
-- Lower branch stuck 0, upper follows z CtrlO <= "00111"; -- select=0011 (bit 3),
-- (CtrlB = in,0 => fz1=’0’, fz2=z) value=1
x<=’1’; y<=’0’; z<=’1’; wait for 10 ns;
w<=’0’; CtrlA<="10"; CtrlB<=L0_RIN; assert OutA(3) = ’1’ report "OUTA(3) SA1
wait for 10 ns; failed" severity error;
pos := 8 + idx3(’0’, y, x); -- w=0 => lower
half enabled -> uses z1=’0’ -- Done
assert_one_hot(OutA, pos, "Z fan-out (low report "All tests applied.";
stuck 0) failed"); wait;
end process;
-- Upper branch stuck 1, lower follows z
-- (CtrlB = 1,in => fz2=’1’, fz1=z) end architecture;
w<=’1’; CtrlA<="10"; CtrlB<=LIN_R1; .
wait for 10 ns;
pos := idx3(’1’, y, x); -- w=1 => upper half
enabled -> uses z2=’1’
VI. V ERIFICATION OF FAULT-I NJECTABLE 4→16 b) (B) Baseline, pass-through (no faults), w = 1:
D ECODER • Example: x=0, y=1, z=0, w=1.
A. DUT Recap and Output Mapping • idx = 4 · 0 + 2 · 1 + 0 = 2, w = 1 ⇒ pos = 2.
• Observation: OutA has bit 2 high, i.e., 0000 0000
The DUT implements a 4→16 decoder using two 3→8
0000 0100.
blocks with a fault-injection front-end and an output stuck-
at mechanism. Let the inputs be (x, y, z, w) with w selecting c) (C) Z fan-in faults (both branches forced), w = 1:
which 3→8 slice is enabled: • CtrlA=10 selects z. With CtrlB=011 (BOTH 0): z →
0 on both branches ⇒ idx = 4 · 0 + 2 · y + x.
OutA[15 : 8] = lower slice (active when w = 0), (1) • With CtrlB=110 (BOTH 1): z → 1 on both branches
OutA[7 : 0] = upper slice (active when w = 1). (2) ⇒ idx = 4 · 1 + 2 · y + x.
• Observation: hot-bit moves inside the upper half from
Inside the active slice, the one-hot line index is position 3 to position 7 as z is forced from 0 to 1.
idx = 4 · z + 2 · y + x ∈ {0, . . . , 7}. (3) d) (D) Z fan-in with w = 0:
• Forcing z=0 yields idx = 2 · y + x, and since w=0 the
Therefore, the expected hot-bit position is hot-bit is at 8 + idx.
( • Observation: expected one-hot in the lower half (e.g.,
idx, w = 1 (upper half)
pos = (4) bit 10 for y=1, x=0).
8 + idx, w = 0 (lower half).
e) (E) Z fan-out faults (one branch stuck, one follows):
B. Fault Model Controls
Input faults are injected by first selecting a net with CtrlA • CtrlB=001 (in,0): lower branch follows z, upper is
and then applying a two-branch fault pattern with CtrlB via stuck-0.
mux_special. The branches correspond to the two fan-out • CtrlB=101 (1,in): lower stuck-1, upper follows z.
legs feeding the two 3→8 blocks. • Observation: when the active half uses the stuck branch,
Net select (CtrlA): "00"→ x, "01"→ y, "10"→ z, the selected line reflects the forced value of z; otherwise
"11"→ w. it reflects the true z.
Fault pattern (CtrlB): f) (F) W fan-in faults (selects which half is enabled):
• CtrlA=11 selects w. CtrlB=011 (BOTH 0) ⇒
CtrlB Pattern Meaning (low-branch, high-branch)
000 in,in pass-through
f w1=0, f w2=0 so Enablelow =1, Enablehigh =0: only the
001 in,0 lower branch follows input, upper stuck-0 lower half is active.
010 0,in lower stuck-0, upper follows input • CtrlB=110 (BOTH 1) ⇒ f w1=1, f w2=1 so
011 0,0 fan-in SA0 (both branches forced to 0)
100 in,1 lower follows input, upper stuck-1
Enablelow =0, Enablehigh =1: only the upper half is active.
101 1,in lower stuck-1, upper follows input • Observation: the hot-bit cleanly toggles between halves
110 1,1 fan-in SA1 (both branches forced to 1) while (x, y, z) are held.
g) (G) W fan-out (example with both halves enabled):
Output stuck-at (sao, CtrlO): When sao=1, the 5-bit
• CtrlB=001 (in,0): f w1 = 0, f w2 = w. With w=1 this
CtrlO encodes the stuck location and value as
yields Enablelow =1 and Enablehigh =1, so both 3→8 slices
CtrlO[4:1] CtrlO[0], drive one-hot lines.
| {z } | {z } • Observation: two one-hot bits simultaneously (one in each
select (0..15) stuck value (0/1)
half), as expected.
e.g., CtrlO="00110" forces OutA(3) to 0, and "00111" h) (H) Output stuck-at on OutA(3):
forces OutA(3) to 1.
• Enabling output fault (sao=1) with CtrlO="00110"
C. Waveform and Scenario-by-Scenario Explanation forces OutA(3) to 0; with "00111" it forces
OutA(3) to 1.
Figure 2 shows the simulated waveforms driven by the • Observation: OutA(3) ignores the decoder and holds
testbench. Each time window corresponds to a directed test the commanded stuck value. With SA1, the final vector
that exercises one part of the fault model. In all cases, the shows the normal one-hot plus bit 3 high.
observed OutA matches the expected one-hot behavior given
the formulas above. D. Sanity Checks Observed
a) (A) Baseline, pass-through (no faults), w = 0: • Toggling w alone moves the hot-bit between [15:8]
• Example: x=1, y=0, z=1, w=0, CtrlA=00, and [7:0].
CtrlB=000, sao=0. • For fixed (x, y), forcing z from 0 to 1 shifts the hot-bit
• idx = 4 · 1 + 2 · 0 + 1 = 5, w = 0 ⇒ pos = 8 + idx = 13. by +4 inside the active half.
• Observation: OutA has bit 13 high, i.e., 0010 0000 • Under w fan-out (in,0 with w=1), both halves are
0000 0000. enabled ⇒ two ones in OutA.
Fig. 2: Simulation waveform of the fault-injectable 4→16 decoder. Top to bottom: sao, CtrlA, CtrlB, CtrlO, inputs
(x, y, z, w), and output OutA[15:0]. Named rows at bottom show the 3-bit encodings for convenience.
C. w Stuck-at Faults (Global MSB / Half-Select) map i → i−1; all other rows unchanged.
• z SA1 in lower decoder only: rows with w=0 and z=0
D. Output D3 Stuck-at Faults
map i → i+1; all other rows unchanged.
VIII. D ISCUSSION • Analogous definitions for the upper decoder (w=1 rows).
The tables show deterministic aliasing patterns:
• z SA0/SA1 cause ±1 index shifts within each half (only
rows where the faulted bit matters are affected).
• w SA0/SA1 move activations between halves by ∓8 /
±8.
• D3 SA0 removes the one-hot at index 3 entirely; D3 SA1
violates the one-hot property (two highs).
Waveforms should visibly confirm these effects when sweep-
ing all inputs with fault toggles.
TABLE I: Nominal truth table TABLE IV: w SA0 (global): if w=1 behaves as w=0 (i →
i−8 for upper half)
w x y z Expected High Line
0 0 0 0 D0 w x y z Expected Faulty High Line(s)
0 0 0 1 D1 0 0 0 0 D0 D0
0 0 1 0 D2 0 0 0 1 D1 D1
0 0 1 1 D3 0 0 1 0 D2 D2
0 1 0 0 D4 0 0 1 1 D3 D3
0 1 0 1 D5 0 1 0 0 D4 D4
0 1 1 0 D6 0 1 0 1 D5 D5
0 1 1 1 D7 0 1 1 0 D6 D6
1 0 0 0 D8 0 1 1 1 D7 D7
1 0 0 1 D9 1 0 0 0 D8 D0
1 0 1 0 D10 1 0 0 1 D9 D1
1 0 1 1 D11 1 0 1 0 D10 D2
1 1 0 0 D12 1 0 1 1 D11 D3
1 1 0 1 D13 1 1 0 0 D12 D4
1 1 1 0 D14 1 1 0 1 D13 D5
1 1 1 1 D15 1 1 1 0 D14 D6
1 1 1 1 D15 D7