Introduction

With the continuous development of computers, the failure of a system is hard to avoid, and about 90% of which is due to the transient faults and intermittent faults, which are extremely difficult to handle manually. In this case, the reliability in system design is getting more and more attention. At present, the most common reliability design technologies are mainly time redundancy, spatial redundancy, the sequential circuit reliability design, the combinatorial circuit reliability design, the control flow detection and real-time on-site protection and restoration mechanisms and so on. Memory error is a common form in processor faults. At present the commonly used reliability techniques in memory are the redundant backup and Error Detection and Correction (EDAC) related to memory storage1.

Self-detection is an important measure to improve the reliability of the system. A necessary condition to work properly for the system is that every subsystem system can work normally. The function of self-detection is automatically verifying and monitoring the working status of each subsystem and giving users error message or error debugging automatically so that users can discover faults and keep the system in good working condition.

Berger code2, named after its inventors J. M. Berger, is a common self-detection technology, which is the Hamming weight of a code-word in nature. In the two-valued logic, the weight of a code-word is the number of "1" (or "0") in the code-word, and denoted by N1 (or N0). So there are two coding modes of Berger code, which are referred to as N0 and N1 modes. N0 and N1 are usually represented as binary encoding forms (or its inverted-bit forms), one of which is added after the code-word to form a redundant code, which is called Berger code of the code-word. The common form is to append N1 to the end of the code-word. Therefore, if A = “110010”, then N1(A) = 3 = (011)2, The Berger code of A is 110010011. Berger code can be used to detect errors. The detection is actually limited to the error that the number of "0" or "1" in the code-word of the Berger code is equal to the actual number of "0" or "1" in the original code-word, but it cannot detect the error with the same number of "1" and "0" in different positions. Another limitation of Berger code is that it is not capable of error correction.

A lot of researches were carried out in error detection of logic operations, arithmetic operations, DRAM and SRAM etc. based on Berger code. For the error detection and correction of logical operations and arithmetic operations, two-rail code2 and Reed-Muller code3 were presented. The two-rail code is also widely used in the concurrent-error-detecting ALU’s. Jien-Chung Lo etc.4,5 proposed an approach to designing concurrent-error-detecting arithmetic and logic units using Berger code and obtained some results on Berger check predictions for arithmetic and logical operations. In error detection of processor, Vincenzo Piuri6 proposed and evaluated a data coding technique based upon Berger codes to introduce concurrent error detection and fault localization in WSI array processors, which is particularly suited to VLSI, ULSI and WSI implementations. Rao etc.7 presented a totally self-checking (TSC) Berger code checker designs and proved that a TSC Berger code checker can be constructed from a TSC m-out-of-n checker. In memory error detection, the researches8 showed that the types of fault in SRAM are mainly of unidirectional type because when the high energy particles in terrestrial cosmic rays strike the SRAM cells they either change all the logic from 0 to 1 or 1 to 0, but not both at the same time. Hence a unidirectional error detection scheme provides good fault coverage against SEUs in SRAM cells of FPGA. Jeong-A Lee etc.9,10 presented an error detection scheme for detecting errors in SRAM cells of FPGA. This proposed scalable error detection coding (SEDC) scheme is capable of detecting 100% unidirectional errors. The technique achieves significant improvement in area as well as speed over Berger and simple TMR technique for the same application. Mădălin Neagu etc.11 presented a modification of the classical Berger code which can be used to detect, localize and correct single or multi-bit errors at the expense of more check bits and while having a lower delay. The check bits are generated by several layers or levels of full adders: the intermediate levels generate partial check bits, while the highest (last) level generates the Berger code check bits.

The above error detection theories and techniques have played a significant role to ensure the reliability of the binary electronic equipment. Over the past decade, great progress has been made in the researches on ternary optical computer. The research on opto-electronic hybrid computer system, which uses liquid crystal to change the polarization direction of the light to achieve the three-state (dull state, vertically polarized light state and horizontally polarized light state which are orthogonal) conversion of light and uses the existing devices for storing information, becomes a very promising research branch. Jin Yi etc. proposed a conception and structure of ternary optical computer by using three states to represent ternary information and using liquid crystals and polaroids to construct optical processor12. Afterwards, they presented a reconfigurable ternary optical processor and designed a new reconfigurable circuit using small-scale FPGA chip13. Based on decrease-radix design principle for optical processor14 and the data editing techniques as well as the water-flow computing technology, a MSD addition principle for ternary optical computer is proposed15 and a SJ-MSD adder for ternary optical computer is implemented16. In 2018, a programming model for ternary optical computer is implemented17. In 2020, a three-lane CA traffic flow model on ternary optical computer is implemented18. In 2021, a SRT integer divider is implemented19 and a parallel radix-4 MSD iterative division is implemented20. In 2022, A fine-grained fast parallel genetic algorithm based on a ternary optical computer is designed and implemented21. In 2023, Tri-State Optical Signal Detectors for Ternary Optical Computers and key theories and technologies and implementation mechanism of parallel computing for ternary optical computer are implemented22,23. In 2024, the dual-center programming platform for ternary optical computer and electronic computer and the R4-MSD square root algorithm in ternary optical computer are implemented24,25. At present, the optical computer processor has such characteristics as bitwise reconfigurability, huge-bit data, reconfigurable computing function at any time, and carry-free adder with no time delay. For performance analysis of a TOC, literature26 already has related research. For ternary data, the author proposed the conception of extended ternary Hamming code and a principle of single-error-correction and double-error-detection (SEC-DED)27,28. But the self-detection technology for logic operations and MSD arithmetic is not setup yet.

The paper mainly concerns the ternary Berger code and the self-check of ternary data. "Ternary Berger code and its application in error detection" presents some conception about ternary Berger code and related principle of error detection. "Error detection design and implementation for ternary Berger code" discusses error detection design and implementation for ternary Berger code. Section "Error detection ability and computation complexity" analyzes the error detection ability and computation complexity about the error detection. In "Conclusion", we summarize the whole work of the paper.

Ternary Berger code and its application in error detection

Modified signed-digit representation

Modified Signed-Digit (MSD) redundancy representation was first proposed by Avizienis etc. in 196129. In 1986 MSD was applied to optical computing by Drake etc.30. Now MSD representation is widely used in carry-free parallel computation.

MSD redundancy representation is a number system of radix 2 with symbol set {0, 1, \(\overline{1}\)}, whose bit weight in bit i is 2i. Hence, it is actually a binary representation with redundancy. For any real number of A, its MSD representation \(A = a_{n} a_{n - 1} ...a_{1} a_{0} .a_{ - 1} ...a_{ - r}\) is as follows.

$$A = \sum\limits_{i = - r}^{n} {a_{i} 2^{i} },$$

where \(a_{i} \in \{ 0,1,\overline{1} \}\), i is an integer, and \(\overline{1}\) represents – 1. Any non-zero real number has multiple MSD representations.

Ternary Berger code of ternary code-word

For ternary code-word m = mnmn−1m2m1 consisting of symbol \(0,1,\overline{1}\), the numbers of 0’s, 1's and \(\overline{1}\)'s in code-word m are denoted by N0(m), N1(m), Nī(m) respectively. For example, let m = \({11}\overline{1}{00}\overline{1}10\). Then N0(m) = 3, N1(m) = 3, Nī(m) = 2. Denote k = \(\left\lceil {{\text{log}}_{{2}} \left( {\text{n}} \right)} \right\rceil\) . Now we can represent the length of N0(m), N1(m) and \(N_{{\overline{1} }} (m)\) in binary codes or their inverse forms and append them to the code-word m to form a new code. The new code B is called a ternary Berger code.

For a ternary code-word m = mnmn−1m2m1 of length n, the binary codes of N0(m), N1(m) and Nī(m) are denoted by w = wkwk−1w2w1, v = vkvk−1v2v1 and h = hkhk−1h2h1 respectively. The ternary Berger code B = <m, w, v, h>, the string concatenation of m, w, v and h, has the form mnmn−1m2m1 wkwk−1w2w1 vkvk−1v2v1 hkhk−1h2h1. For example, for m = \({11}\overline{1}{00}\overline{1}10\) of length 8, we have N0(m) = 3 = (0011)2, N1(m) = 3 = (0011)2 and \(N_{{\overline{1} }} (m)\) = 2 = (0010)2. Hence, the ternary Berger code of m is B = \({11}\overline{1}{00}\overline{1}100011{00110010}\). For convenience of expressions, m, w, v and h are called the information code, B0-type check code, B1-type check code and Bī-type check code, respectively. Accordingly, vk, vk−1,…, v2, v1 are called B1-type check bits, or check bits simply. The same is true of B0 and Bī.

Principle of error detection of ternary code-word based on ternary Berger code

The MSD symbols 0, 1 and \(\mathop 1\limits^{ - }\) can establish a mapping relation with the three optical states in any way. Under the (B1, B1, Bī) scheme, the symbols \(0,1,\overline{1}\) have a nice optical meanings: 0, 1 and \(\mathop 1\limits^{ - }\) represent dark state, light with vertical polarization state and horizontal polarization state, respectively. The general common scenario is that the bright state can be changed to dark state, but the dark state (or no light) is generally difficult to become the light state unless by some coding and electrical-optical conversion. In this paper, we consider the errors of the form x → y, where x ≠ y and x, y {\(0,1,\overline{1}\)}.

Now we discuss the error in ternary Berger code. We first give some notations in the following.

For any n-bit ternary information code m = mnmn-1m2m1 and its ternary Berger code B =  < m, w, v, h > , denote B’ =  < m', w', v', h' > be a code obtained from a copy of the Berger code B (or transmitted from B), where m’ = m'nm'n−1…m'2 m'1, w' = w'k…w'2w'1, v' = v'k…v'2v'1, h' = h'k…h'2h'1. Denote w’', v'' and h’' be the binary expressions of N0(m'), N1(m') and Nī(m') with length k, respectively.

Generally, the code B’ may be different from B. Errors may occur when the information is taken out after the optical information is decoded and stored in memory or B is picked up and used or transferred to other place because of some unexpected faults. Its correctness of B’ should be checked.

We take m = \({11}\overline{1}{00}\overline{1}10\) as an example to show the encoding scheme with 1 bit error. Here we first calculate its Berger code B = \({11}\overline{1}{00}\overline{1}100011{00110010}\). Denote B’ = m'8m'7m'6m'5m'4m'3m'2m'1w'4w'3w'2w'1v'4v'3v'2v'1h'4h'3h'2h'1. Assume that there is one bit error in B’ from the original B. It may be in information bit or check bit. For simplicity, denote m’ = m'8m'7m'6m'5m'4m'3m'2m'1, w = w'4w'3w'2w'1, v' = v'4v'3v'2v'1 and h’ = h'4h'3h'2h'1. 14 typical error cases are listed in Table 1.

Table 1 Example of encoding schemes for 1 bit error.

Calculate the corresponding N0(m'), N1(m') and Nī(m') for m’, and denote w’', v'', h" be the binary expressions of N0(m'), N1(m') and Nī(m'). We divide them into four cases.

Case 1

1 bit error occurs in information code m’, which are listed as No. 1 ~ 6 in Table 1. Here w’ = w = 0011, v' = v = 0011 and h’ = h = 0010.

No. 1: 1 → 0. Here w’' = 0100, v'' = 0010 and h" = 0010, Hence w’' > w', v'' < v' and h’' = h'.

No. 2: 1 → \(\overline{1}\). Here w’' = 0011, v'' = 0010 and h" = 0011. Hence w’' = w', v'' < v' and h’' > h'.

No. 3: \(\overline{1}\) → 0. Here w’' = 0100, v'' = 0011 and h" = 0001 Hence w’' > w', v'' = v' and h’' < h'.

No. 4: \(\overline{1}\) → 1. Here w’' = 0011, v'' = 0100 and h" = 0001, Hence w’' = w', v'' > v' and h’' < h'.

No. 5: 0 → 1. Here w’' = 0010, v'' = 0100 and h" = 0010, Hence w’' < w', v'' > v' and h’' = h'.

No. 6: 0 → \(\overline{1}\). Here w’' = 0010, v'' = 0011 and h" = 0011, Hence w’' < w', v'' = v' and h’' > h'.

Case 2

1 bit error occurs of 0 → 1, 0 → \(\overline{1}\), 1 → 0, 1 → \(\overline{1}\) in check code w’, which are listed as No. 7–10 in Table 1. Here, w'' = 0011, v'' = 0011, h'' = 0010,

No. 7: w4 = 0 → 1. w' = 1011, v' = 0011, h' = 0010, Hence w’' ≠ w', v'' = v' and h’' = h'.

No. 8: w4 = 0 → \(\overline{1}\). w' = \(\overline{1}\) 011, v' = 0011, h' = 0010,. Hence w’' ≠ w', v'' = v' and h’' = h'.

No. 9: w2 = 1 → 0. w' = 0001, v' = 0011, h' = 0010, Hence w’' ≠ w', v'' = v' and h’' = h'.

No. 10: w2 = 1 → \(\overline{1}\). w' = 00 \(\overline{1}\) 1, v' = 0011, h' = 0010,. Hence w’' ≠ w', v'' = v' and h’' = h'.

Case 3

1 bit error occurs of 0 → 1, 1 → 0 in check code v’, which is the corresponding case of No. 11–12 in Table 1.

No. 11: v4 = 0 → 1. w' = 0011, v' = 1011, h' = 0010,. Hence w’' = w', v' '≠ v' and h’' = h'.

No. 12: v1 = 1 → 0. w' = 0011, v' = 0010, h' = 0010,. Hence w’' = w', v'' ≠ v' and h’' = h'.

Case 4

1 bit it error occurs of 0 → 1 or 0 → \(\overline{1}\) in check code h’, which is the corresponding case of No. 13–14 in Table 1. We have w’' = w', v'' = v' and h’' ≠ h'.

Now we consider the general situation.

Proposition

For any n-bit ternary information code m =mnmn-1m2m1, and the symbols m’, B, B', w, v, h, w', v', h', v'', h" as mentioned above, we have the following results of error detection about the ternary Berger code.

If w’' = w', v'' = v' and h’' = h', then no error is detected.

If w’' = w', v'' < v' and h’' > h', then there is an error of type 1 → \(\overline{1}\) in information code.

If w’' = w', v'' > v' and h’' < h', then there is an error of type \(\overline{1}\) → 1 in information code.

If w’' < w', v'' = v' and h’' > h', then there is an error of type 0 → \(\overline{1}\) in information code.

If w’' > w', v'' = v' and h’' < h', then there is an error of type \(\overline{1}\) → 0 in information code.

If w’' > w', v'' < v' and h’' = h', then there is an error of type 1 → 0 in information code.

If w’' < w', v'' > v' and h’' = h', then there is an error of type 0 → 1 in information code.

If w’' ≠ w', v'' = v' and h’' = h', then there is an error in check code w’.

If w’' = w', v'' ≠ v' and h’' = h', then there is an error in check code v’.

If w’' = w', v'' = v' and h’' ≠ h', then there is an error in check code h’.

Proof

For n-bit ternary information code m = mnmn−1m2m1 and its Berger code B =  <m, w, v, h>, we have two cases need to be discussed.

(1) There is an error at bit mi in m, that is, m'i ≠ mi, but w’ = w, v' = v and h’ = h. Calculate w’', v'' and h’' for m’ from N0(m'), N1(m') and Nī(m') respectively. Now we have 6 cases for mi → m'i and obtain Table 2.

Table 2 An error occurs at information bit mi.

So the results corresponding to the first six cases are correct.

(2) There is an error at check bit w'i in w' or v'i in v' or h'i in h', but m’ = m. We have N0(m') = N0(m), N1(m') = N1(m) and Nī(m') = Nī(m), that is, w" = w, v" = v, h" = h.

According to the definition of ternary Berger code, w, v and h consist of 0 and 1. Without loss of generality, we assume that there is a jump vi → v'i in v. Then we have w" = w', and h" = h', and there are four cases to be discussed for v, that is, 1 → 0, 0 → 1, 1 → \(\overline{1}\) and 0 → \(\overline{1}\),

Case 1: 1 → 0. That is vi = 1 but v'i = 0 for some i and for all other j, v'j = vj, then vkvk-1v1 > v'kv'k-1…v'1, that is, v" ≠ v'.

Case 2: 0 → 1. That is vi = 0 but v'i = 1 for some i but for all other j, v'j = vj, then vkvk-1v1 < v'kv'k-1…v'1, that is, v" ≠ v'.

Case 3: 1 → \(\overline{1}\): That is for some i, vi = 1 but v'i = \(\overline{1}\), we have vkvk-1v1 > v'kv'k-1…v'1. That is, v" ≠ v'.

Case 4: 0 → \(\overline{1}\): That is for some i, vi = 0 but v'i = \(\overline{1}\), we have vkvk-1v1 > v'kv'k-1…v'1. That is, v" ≠ v'.

Combine the four cases, we obtain the results and show them in Table 3.

Table 3 An error occurs at check bit.

According to (1) and (2), it is to see that the proposition for the 12 cases is correct.

Error detection design and implementation for ternary Berger code

Structure of check code generator

Check code generator denoted by CCGen is used to count the number N0(m) of 1’s, the number N1(m) of 1’s and the number Nī(m) of \(\overline{1}\)'s in m respectively. For example, for input m = \({11}\overline{1}{00}\overline{1}10\), CCGen outputs N1(m) = 3 and Nī(m) = 2, N0(m) = n − N1(m) − Nī(m). The structure of CCGen is shown in Fig. 1.

Fig. 1
figure 1

Structure of check code generator CCGen.

In Fig. 1, the diamonds represent polaroids, where the polaroids labeled with V1,…,Vn are vertical polaroids and the polaroids labeled with H1,…,Hn are horizontal polaroids; The thick grey lines with arrows are light signals, the thin black lines with arrows are data lines (or electrical signal lines), the thick black slash lines are pellicle mirror or holographic lenses, and LC1,…,LCn and LC’1,…,LC’n are liquid crystals. The module “VLC Counter” realizes counting the number of liquid crystals which vertical light passes through and the module “HLC Counter” realizes counting the number of liquid crystals which horizontal light passes through.

The sketch function map of module “VLC Counter” is drawn in Fig. 2. The function of it is that it receives the lights passing through the vertical polaroid films V1,…,Vn, and counts the number of lighted states. Its implementation is carried out by measuring the intensity of light collected at the counter. For a liquid crystal of size s × t, we can divide the liquid crystal into T small blocks of size p × q. Then we count the number of liquid crystals through which vertical light passes in these blocks in parallel with scanning or gathering the intensity of light. At last, we count the total number of the T numbers.

Fig. 2
figure 2

Functional graph of VLC counter.

The same is to the module “HLC Counter”. The module “HLC Counter” realizes the counting of number of all horizontal lighted states.

Principle of Berger code generator is described as follows.

The n-bit light signal m = mnmn−1m2m1 is divided into two light beans with optical splitters projecting on the liquid crystals in up and down dotted line frames in Fig. 1, respectively. The upper light beans project on n liquid crystals posted vertical polaroid films. Vertical polaroid light in mnmn−1m2m1 can pass through vertical polaroid film and horizontal polaroid light in mnmn−1m2m1 can’t pass through vertical polaroid film. So the module “VLC Counter” realizes the function of counting the number of all vertical lighted states. Similarly, the lower n light beams project on the liquid crystals posted horizontal polaroid films, where light with horizontal polarization in mnmn−1m2m1 can pass through horizontal polaroid films while light with vertical polarization can not.

Design of Ternary Berger code generator

Ternary Berger code generator denoted by BCGen is given in Fig. 3. It receives n-bit light signals m = mnmn−1m2m1. Then m is divided into two light beams with light spiltters, the left of which goes on passing forward and is denoted by m too, and the right of which generates two group light signals vkvk−1v1 and hkhk−1h1 respectively, where vkvk−1v1 represents the number of 1’s and hkhk−1h1 represents the number of \(\overline{1}\)'s in mnmn−1m2m1. The new ternary Berger code B = mnmn−1m2m1wkwk−1w2w1vkvk−1v2v1 hkhk−1h2h1 is generated by combining the ternary data m with wkwk-1w2w1, vkvk-1v1 and hkhk-1h1.

Fig. 3
figure 3

Ternary Berger code generator BCGen.

Design of photoelectric error detecting structure of ternary Berger code

In order to check a code-word with the Berger code, we need an optical structure to detect the errors that may occur. During the error check, three steps need to be done. The first step is to calculate the ternary Berger code with the check codes w", v" and h" according to the new information code m’. The second step is to compare v" and v’ as well as w" and w’, h" and h’. The third step is to judge if there are some errors by the comparison results Rw, Rv and Rh. Here, Rv is just a comparer obtained by MSD with the follow transformation C in Table 4. The compaison principle likes the lexicographical order for two strings, For example, if v" = 0100 and v’ = 01 \(\overline{1}\) 0, the comparison of v" and v’ is Rv > 0. The same is true of Rw and Rh. If Rv = 0 and Rh = 0, then no errors are detected, otherwise there exists error in information bit or in check bit. The photoelectric structure of error detect of ternary Berger code is shown as Fig. 4.

Table 4 Comparator truth table C.
Fig. 4
figure 4

Photoelectric structure of error detect of ternary Berger code.

In Fig. 4, the dotted line frames are used to represent information code and check codes, the real line frames are used to denote the check or comparing operation components, the real lines with arrows represent output values, and the grey thick lines with arrows represent ternary code data. Comparator_V and Comparator_H are two comparators, which can compare B1 -type data v" and v’ and Bī-type data h" and h’ and obtain the results Rv and Rh, respectively. Table 5 summarizes the actions according to the results (Rw, Rv, Rh).

Table 5 Actions based on the results Rw, Rv, Rh.

Table 6 lists the results of the Berger code simulation for m = 10020110021211122121010 implemented in C language, and the results are correct. Here the number 2 represents the symbol \(\overline{1}\).

Table 6 Simulation results of the Berger code for m = 10020110021211122121010 in C.

Error detection ability and computation complexity

In Fig. 4, we cannot detect multiple errors under the six error forms 0 → 1, 0 → \(\overline{1}\), 1 → 0,\(\overline{1}\) → 0,1 → \(\overline{1}\),\(\overline{1}\) → 1 mentioned above.

For example, let m = \(11\overline{1} 00\overline{1} 1\). Then the corresponding Berger B is \(11\overline{1} 00\overline{1} 1010{011010}\). If there exist two errors in m6 and m2, that is, m6 = 1 → \(\overline{1}\) and m2 = \(\overline{1}\) → 1. Now we obtain m’ = \(1\overline{1} \overline{1} 0011\) from m and B’ = \(1\overline{1} \overline{1} 0011010{011010}\) from B. By calculation, we get w" = w' = 010, v" = v' = 011 and h" = h' = 010. But no errors are detected.

Now we discuss a general case about the multiple errors in information code. Suppose that there are t1 bits of 1 → 0 type error, t2 bits of \(\overline{1}\) → 0 type error, t3 bits of 1 → \(\overline{1}\) type error, t4 bits of \(\overline{1}\) → 1 type error, t5 bits of 0 → 1 type error, t6 bits of 0 → \(\overline{1}\) type error respectively, but w" = w', v" = v' and h" = h'. Now we have that w" = w'  t5  t6 + t1 + t2, v" = v'  t1  t3 + t4 + t5 and h" = h'  t2  t4 + t3 + t6. In order that w" = w', v" = v', h" = h', we must have—t5  t6 + t1 + t2, = 0,—t1  t3 + t4 + t5 = 0 and—t2 − t4 + t3 + t6 = 0. Thus we get t1 + t2 = t5 + t6 and t1 + t3 = t4 + t5. It shows that in these cases we cannot detect more than one error.

The computational complexity of the error detection based on ternary Berger code rests with CCGen, Comparators_W, V, and H. But the two comparators Comparator_W, Comparator_V and Comparator_H comparing the numbers are not greater than s × t. So it will take a fewer clock cycles than CCGen. And the efficiency of BCGen is the same to CCGen. So the computational complexity in error detect based on ternary Berger code rests with CCGen.

We note that the computational complexity of CCGen is equal to that of VLC Counter. We check VLC Counter. As mentioned above, the liquid crystal with size s × t is divided into T small blocks with size p × q. And Comparator_W can be designed with small electronics device. The total number of liquid crystals through which vertical light passing in the large liquid crystal can be counted by counting the T small blocks in parallel. For example, a liquid crystal of size 100 × 100 can be divided into 100 small blocks of size 10 × 10. It needs at most 100 computations in parallel. We then count the total number of 100 numbers for these blocks, which also needs at most 100 computations. Obviously, we just use 200 computations. The time of the counting is 200/10,000 = 0.2 that of the common scanning method. With this method, the efficiency will be improved greatly. For the a liquid crystal of size s × t, let T = [s/p][t/q]. Then it will take p × q + k computations. For suitable p and q, the efficiency will be improved up to 80%. In fact, the efficiency still has room to improve.

Conclusion

This paper presents an error detection mode based on ternary logic Berger code. It can be used to detect errors in data storage and transmission etc. after procession of optical ternary computer. There are six information error types involved: 0 → 1, 0 → \(\overline{1}\), 1 → 0,1 → \(\overline{1}\),\(\overline{1}\) → 0,\(\overline{1}\) → 1. They can occur as soft error form or some hardware error form because of some unexpected fault. With the conception of ternary Berger code proposed in this paper, the error detection principle as well as optical implementation are presented. In optical implementation, it is easy to see that the generation of ternary Berger code is much simpler and faster than that of binary form, and it can produce much bigger bits of data. So the efficiency of error detection is much higher. But we cannot detect multiple errors of other error forms which is a limitation of this error detection. Additionally, If we just append two check codes of three types N0(m), N1(m) and \(N_{{\overline{1} }} (m)\), to m, we cannot detect the error type. Take m = \({11}\overline{1}{00}\overline{1}10\) as an example mentioned above and use N1(m) and \(N_{{\overline{1} }} (m)\) as check codes. We have B =  < \({11}\overline{1}{00}\overline{1}10\),0011,0010 > with v = 0011 and h = 0010. Assume that we receive B’ =  < \({11}\overline{1}{00}\overline{1}00\),0010,0010 > . Now N1(m) = N1(m') = 2 and Nī(m) = N1(m') = 2, but we can not determine which error type of mi → m'j or vj → v'j.