1
0

util: add a CRC calculator

This commit is contained in:
Wesley W. Terpstra 2017-04-14 13:14:10 -07:00
parent d794218ec3
commit 6aeec673f2

View File

@ -0,0 +1,35 @@
// See LICENSE.SiFive for license details.
package util
import Chisel._
object CRC
{
// A divisor of 0x1d5 is interpretted to be x^8 + x^7 + x^6 + x^4 + x^2 + 1
// Let n be the highest term in the divisor; n=8 in 0x1d5.
// Then, this function calculates c mod d, returning an n-bit UInt.
// coefficient.width must be <= width
def apply(divisor: BigInt, coefficient: UInt, width: Integer): UInt = {
require (divisor > 0 && divisor.testBit(0))
require (width > 0)
assert (coefficient >> width === UInt(0))
val n = log2Floor(divisor)
val m = width
if (m <= n) return coefficient
// Initialize the reduction matrix
val array = Array.tabulate(m) { BigInt(1) << _ }
// Reduce the matrix of terms larger than n
for {
i <- (n until m).reverse
j <- 0 to n
if divisor.testBit(j)
} array(i-(n-j)) ^= array(i)
// Construct the circuit
Cat(Seq.tabulate(n) { i => (UInt(array(i)) & coefficient).xorR } .reverse)
}
// Find more great CRC polynomials here: https://users.ece.cmu.edu/~koopman/crc/
val CRC_16F_4_2 = BigInt(0x1a2eb) // HD=4 for <32751 bits and HD=6 for <93 bits
}