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