Another Galois Field Multiply

After completing my Reed-Solomon decoder’s HDL, I decided to see how well it performed.  The results weren’t as good as I expected.  The limiting path was in the field math.  A bit of simple pipelining allowed 250MHz operation on my Virtex-6 -1 platform.  I had seen another snippet of code for a Galois Field multiply, but didn’t want to use it because I didn’t understand how it was derived.  A second look quickly revealed its secrets.

Before continuing, It might be helpful to read previous articles I’ve written about Galois Fields in order to avoid any confusion with the below math.

The thing I noticed in the second look was that the structure for each coefficient was simply a sum of products in GF2.  This was what prompted me to write out the code to generate my own fpga-efficient multiply.  Below is the basic principle, shown for elements a and b in GF8 generated by x^3 + x^2 + 1 would be:

(a_2 x^2 + a_1 x + a_0) * (b_2 x^2 + b_1 +b_0) = (c_2 x^2 + c_1 x + c_0)

The first step is to perform the polynomial multiply directly:

(a_2 b_2) x^4 + (a_2 b_1 + a_1 b_2) x^3 + (a_2 b_0 + a_1 b_1 + a_0 b_2) x^2 + (a_1 b_0 + a_0 b_1) x + (a_0 b_0)

The next step is to find the remainder  modulo x^3 + x^2 + 1.  This can be done using long division.  The first step is to cancel out the first term, a_2 b_2.  This would mean subtracting (a_2 b_2) x^4 + (a_2 b_2) x^3 + (a_2 b_2) x from the above.  In a Galois Field that is a power of two, addition and subtraction are the same.  This gives:

(a_2 b_2 + a_2 b_1 + a_1 b_2) x^3 + (a_2 b_0 + a_1 b_1 + a_0  b_2) x^2 + (a_2 b_2 + a_1 b_0 + a_0 b_1) x + (a_0 b_0)

This process continues.  The next term to subtract is ( a_2 b_2 + a_2 b_1 + a_1 b_2 )*(x^3 + x^2 + 1).  This gives:

(a_2 b_2 + a_2 b_1 + a_2 b_0 + a_1 b_2 + a_1 b_1 + a_0  b_2) x^2  + (a_2 b_2 + a_1 b_0 + a_0 b_1) x + (a_2 b_2 + a_2 b_1 + a_1 b_2 + a_0 b_0)

This gives expressions for the results:

 c_2 = (a_2 b_2 + a_2 b_1 + a_2 b_0 + a_1 b_2 + a_1 b_1 + a_0  b_2)

c_1 = (a_2 b_2 + a_1 b_0 + a_0 b_1 )

c_0 = (a_2 b_2 + a_2 b_1 + a_1 b_2 + a_0 b_0 )

Keep in mind that, though not shown here, it is possible that the same term will appear multiple times in a result.  For a Galois Field of a power of two, addition and subtraction are the same because each element is its own additive inverse.  This means a_m b_n + a_m b_n = 0.  In the above expressions, multiplication of the a and b terms is done using AND, while addition is done using XOR.

The resulting logic is:

c[2] = a[2]&b[2] ^ a[2]&b[1] ^ a[2]&b[0] ^ a[1]&b[2] 

     ^ a[1]&b[1] ^ a[0]&b[2];

c[1] = a[2]&b[2] ^ a[1]&b[0] ^ a[0]&b[1];

c[0] = a[2]&b[2] ^ a[2]&b[1] ^ a[1]&b[2] ^ a[0]&b[0];

This method can be put into a script, to allow for easy generation of a synthesizable Galois Field multiply function.  If my testing with Reed-Solomon decoders is any indication, the improvements can be significant.

I have made a python script that uses the above to generate a package for valid 256 element Galois Fields.  The resulting files are:

This entry was posted in FPGA, Math and tagged , . Bookmark the permalink.

Comments are closed.