util: add a CRC calculator
This commit is contained in:
parent
d794218ec3
commit
6aeec673f2
35
src/main/scala/util/CRC.scala
Normal file
35
src/main/scala/util/CRC.scala
Normal 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
|
||||
}
|
Loading…
Reference in New Issue
Block a user