I want to calculate crc32 for the ethernet packet and check if I had received correct data. I want to implement crc as a System Verilog function. I will use online crc value generator to get the code in verilog to calculate crc32 with data width 8 bits. I have the following questions:
In case, of Ethernet 802.3 standard, I believe crc is calculated for data, where data = {destination address, source address, length and payload}. Correct me, if I am missing something in the data.
Theoretically, data is appended with (polynomial_length-1) number of zeros, do I have to append similarly before sending the data message as input to the crc32 function?
Once crc is calculated, now I have to know if my data received is correct. So, do I have to pass the data along with calculated crc value as input to the crc32 function again, to check if I get zeros as function output, so as to ensure I have received correct data, is this correct? If not tell me how to check if I had received correct data. Thanks in advance.
Below is the SV version of crc32 function, which I intend to use.
function nextCRC32_D8(byte unsigned data[]);
bit [7:0] d;
bit [31:0] newcrc, crc,c;
int i;
crc=0;
for (i=0; i<data.size(); i++) begin
d = data[i];
c = crc;
newcrc[0] = d[6] ^ d[0] ^ c[24] ^ c[30];
newcrc[1] = d[7] ^ d[6] ^ d[1] ^ d[0] ^ c[24] ^ c[25] ^ c[30] ^ c[31];
newcrc[2] = d[7] ^ d[6] ^ d[2] ^ d[1] ^ d[0] ^ c[24] ^ c[25] ^ c[26] ^ c[30] ^ c[31];
newcrc[3] = d[7] ^ d[3] ^ d[2] ^ d[1] ^ c[25] ^ c[26] ^ c[27] ^ c[31];
newcrc[4] = d[6] ^ d[4] ^ d[3] ^ d[2] ^ d[0] ^ c[24] ^ c[26] ^ c[27] ^ c[28] ^ c[30];
newcrc[5] = d[7] ^ d[6] ^ d[5] ^ d[4] ^ d[3] ^ d[1] ^ d[0] ^ c[24] ^ c[25] ^ c[27] ^ c[28] ^ c[29] ^ c[30] ^ c[31];
newcrc[6] = d[7] ^ d[6] ^ d[5] ^ d[4] ^ d[2] ^ d[1] ^ c[25] ^ c[26] ^ c[28] ^ c[29] ^ c[30] ^ c[31];
newcrc[7] = d[7] ^ d[5] ^ d[3] ^ d[2] ^ d[0] ^ c[24] ^ c[26] ^ c[27] ^ c[29] ^ c[31];
newcrc[8] = d[4] ^ d[3] ^ d[1] ^ d[0] ^ c[0] ^ c[24] ^ c[25] ^ c[27] ^ c[28];
newcrc[9] = d[5] ^ d[4] ^ d[2] ^ d[1] ^ c[1] ^ c[25] ^ c[26] ^ c[28] ^ c[29];
newcrc[10] = d[5] ^ d[3] ^ d[2] ^ d[0] ^ c[2] ^ c[24] ^ c[26] ^ c[27] ^ c[29];
newcrc[11] = d[4] ^ d[3] ^ d[1] ^ d[0] ^ c[3] ^ c[24] ^ c[25] ^ c[27] ^ c[28];
newcrc[12] = d[6] ^ d[5] ^ d[4] ^ d[2] ^ d[1] ^ d[0] ^ c[4] ^ c[24] ^ c[25] ^ c[26] ^ c[28] ^ c[29] ^ c[30];
newcrc[13] = d[7] ^ d[6] ^ d[5] ^ d[3] ^ d[2] ^ d[1] ^ c[5] ^ c[25] ^ c[26] ^ c[27] ^ c[29] ^ c[30] ^ c[31];
newcrc[14] = d[7] ^ d[6] ^ d[4] ^ d[3] ^ d[2] ^ c[6] ^ c[26] ^ c[27] ^ c[28] ^ c[30] ^ c[31];
newcrc[15] = d[7] ^ d[5] ^ d[4] ^ d[3] ^ c[7] ^ c[27] ^ c[28] ^ c[29] ^ c[31];
newcrc[16] = d[5] ^ d[4] ^ d[0] ^ c[8] ^ c[24] ^ c[28] ^ c[29];
newcrc[17] = d[6] ^ d[5] ^ d[1] ^ c[9] ^ c[25] ^ c[29] ^ c[30];
newcrc[18] = d[7] ^ d[6] ^ d[2] ^ c[10] ^ c[26] ^ c[30] ^ c[31];
newcrc[19] = d[7] ^ d[3] ^ c[11] ^ c[27] ^ c[31];
newcrc[20] = d[4] ^ c[12] ^ c[28];
newcrc[21] = d[5] ^ c[13] ^ c[29];
newcrc[22] = d[0] ^ c[14] ^ c[24];
newcrc[23] = d[6] ^ d[1] ^ d[0] ^ c[15] ^ c[24] ^ c[25] ^ c[30];
newcrc[24] = d[7] ^ d[2] ^ d[1] ^ c[16] ^ c[25] ^ c[26] ^ c[31];
newcrc[25] = d[3] ^ d[2] ^ c[17] ^ c[26] ^ c[27];
newcrc[26] = d[6] ^ d[4] ^ d[3] ^ d[0] ^ c[18] ^ c[24] ^ c[27] ^ c[28] ^ c[30];
newcrc[27] = d[7] ^ d[5] ^ d[4] ^ d[1] ^ c[19] ^ c[25] ^ c[28] ^ c[29] ^ c[31];
newcrc[28] = d[6] ^ d[5] ^ d[2] ^ c[20] ^ c[26] ^ c[29] ^ c[30];
newcrc[29] = d[7] ^ d[6] ^ d[3] ^ c[21] ^ c[27] ^ c[30] ^ c[31];
newcrc[30] = d[7] ^ d[4] ^ c[22] ^ c[28] ^ c[31];
newcrc[31] = d[5] ^ c[23] ^ c[29];
end
return newcrc;
endfunction
Correct.
CRC-32 algorithms, both in software and hardware, can be and are designed to avoid the mathematical artifact of appending zero bits to the message. I have not checked your posted code for that property.
You do exactly what was done on transmission, which is to calculate the CRC on the addresses through payload (and not on the CRC itself), and then compare that to the CRC in the transmitted packet. If you like, you can instead compute all the way through the CRC and check the result against a specific "residue" value, 0xC704DD7B. It is less transparent what's going on there, but it does work.
Related
I already know how to work the "simple formula" in Neural Network as follow:
f = as.formula(paste("logK ~",paste(n[!n %in% "logK"], collapse = " + ")))
But I have a problem with how to apply the polynominal model into the neural network.
n = names(dataset)
f = as.formula(paste("logK ~.-Co-Ru +I(Cr ^ 3)+I(Mo ^ 3)+I(Re ^ 3)+I(Ti ^ 3) +I(Temp ^ 3)+I(Re ^5 )+I(Temp ^ 5)+I(Cr ^ 7)+I(Re ^ 7)+I(Re ^ 9)", paste(n[!n %in% "logK"])))
nn = neuralnet(f, data = trainset, hidden = 10, act.fct = "tanh")
Error in parse(text = x, keep.source = FALSE): :1:121: unexpected symbol
1: logK ~.-Co-Ru +I(Cr ^ 3)+I(Mo ^ 3)+I(Re ^ 3)+I(Ti ^ 3) +I(Temp ^ 3)+I(Re ^5 )+I(Temp ^ 5)+I(Cr ^ 7)+I(Re ^ 7)+I(Re ^ 9) Al
^
Traceback:
as.formula(paste("logK ~.-Co-Ru +I(Cr ^ 3)+I(Mo ^ 3)+I(Re ^ 3)+I(Ti ^ 3) +I(Temp ^ 3)+I(Re ^5 )+I(Temp ^ 5)+I(Cr ^ 7)+I(Re ^ 7)+I(Re ^ 9)",
. paste(n[!n %in% "logK"])))
formula(object, env = baseenv())
formula.character(object, env = baseenv())
formula(eval(parse(text = x, keep.source = FALSE)[[1L]]))
eval(parse(text = x, keep.source = FALSE)[[1L]])
parse(text = x, keep.source = FALSE)
val bb =0
val cc ="%07d"
println(f"$bb$cc") //0%07d
println(f"$bb%07d") //0000000
I expect
println(f"$bb$cc") //0000000
println(f"$bb%07d") //0000000
Why isn't the result the same?
How can I make it the same?
By using f"string" you are declaring that you want to make a formatted string.
with f"$bb$cc" you are using the variables bb and cc, so it accesses the strings for them
with f"$bb%07d" you are telling it to transform bb into a number with 7 decimal places, and 0s if the number isn't large enough
further examples to help understanding:
val bb = 1
println(f"$bb%07d") // 0000001
println(f"$bb%05d") // 00001
val bb = 11
println(f"$bb%05d") //00011
to get the same string, try using s"string"
val bb = 0
println(s"$bb%07d") // 0%07d
to use a string as a formatter:
val cc = "%07d"
val bb = 0
println(cc.format(bb)) //0000000
//for more information http://docs.scala-lang.org/overviews/core/string-interpolation.html
I think that you already know that, but just to be clear:
$ is used for marking of variable references
% is used for formatting the references
Generally you use f interpolator like this: f"$<reference>%<format>"
When you write:
println(f"$bb$cc")
This is what happens:
Parser recognizes $bb with no formatting.
Parser recognizes $cc with no formatting.
Substitutes $bb with 0
Substitutes $bb with "%07d"
But when you write:
println(f"$bb%07d")
This is what happens:
Parser recognizes $bb with formatting 07d
Substitutes $bb with 0 and formats it according to "07d", that is: 7 digits and filling with 0 is number is shorter than 7 digits.
You might have thought of this method as being preprocessing like #define cc "%07d" in C but it's simply not.
I'm not currently aware of a way to store the formatting in a separate string. You might consider using a class-based formatter for doing so.
String interpolation syntax requires a string literal.
The point of the f-interpolator macro is to give compile-time safety.
scala> val x = 0.1
x: Double = 0.1
scala> f"$x"
res0: String = 0.1
scala> f"$x%5.5f"
res1: String = 0.10000
scala> f"$x%5d"
<console>:13: error: type mismatch;
found : Double
required: Int
f"$x%5d"
^
scala> val fmt = "%5d"
fmt: String = %5d
scala> fmt format x
java.util.IllegalFormatConversionException: d != java.lang.Double
at java.util.Formatter$FormatSpecifier.failConversion(Formatter.java:4302)
at java.util.Formatter$FormatSpecifier.printInteger(Formatter.java:2793)
at java.util.Formatter$FormatSpecifier.print(Formatter.java:2747)
at java.util.Formatter.format(Formatter.java:2520)
at java.util.Formatter.format(Formatter.java:2455)
at java.lang.String.format(String.java:2940)
at scala.collection.immutable.StringLike$class.format(StringLike.scala:318)
at scala.collection.immutable.StringOps.format(StringOps.scala:29)
... 32 elided
This isn't convenient, but you can decompose the string constants and roll it by hand:
scala> final val fmt = "%5d"
fmt: String("%5d") = %5d
scala> new StringContext("", fmt).f(x)
<console>:14: error: type mismatch;
found : Double
required: Int
new StringContext("", fmt).f(x)
^
or
scala> final val fmt = "%5.5f"
fmt: String("%5.5f") = %5.5f
scala> new StringContext("", fmt).f(x)
res8: String = 0.10000
scala> final val fmt = "%5.5"
fmt: String("%5.5") = %5.5
scala> new StringContext("", fmt + "f").f(x)
res9: String = 0.10000
scala> new StringContext("", fmt + "d").f(x)
<console>:14: error: precision not allowed
new StringContext("", fmt + "d").f(x)
^
scala> final val fmt = "%5"
fmt: String("%5") = %5
scala> new StringContext("", fmt + "d").f(x)
<console>:14: error: type mismatch;
found : Double
required: Int
new StringContext("", fmt + "d").f(x)
^
The error if you try it with non-constant String:
scala> val fmt = "%5d"
fmt: String = %5d
scala> new StringContext("", fmt).f(x)
<console>:14: error: exception during macro expansion:
java.lang.IllegalArgumentException: internal error: argument parts must be a list of string literals
at scala.tools.reflect.FormatInterpolator.scala$tools$reflect$FormatInterpolator$$copyPart$1(FormatInterpolator.scala:82)
at scala.tools.reflect.FormatInterpolator.interpolated(FormatInterpolator.scala:181)
at scala.tools.reflect.FormatInterpolator.interpolate(FormatInterpolator.scala:38)
at scala.tools.reflect.FastTrack$$anonfun$1$$anonfun$apply$5$$anonfun$applyOrElse$5.apply(FastTrack.scala:54)
at scala.tools.reflect.FastTrack$$anonfun$1$$anonfun$apply$5$$anonfun$applyOrElse$5.apply(FastTrack.scala:54)
at scala.tools.reflect.FastTrack$FastTrackEntry.apply(FastTrack.scala:41)
at scala.tools.reflect.FastTrack$FastTrackEntry.apply(FastTrack.scala:36)
at scala.tools.nsc.typechecker.Macros$class.macroExpandWithRuntime(Macros.scala:763)
new StringContext("", fmt).f(x)
^
In the various Lisps, it's possible for me to create a sequence of functions as if they'd just been normal values:
(def ops [+ - * /])
Which I can then iterate through, again, as if they were just normal values:
(doseq [op ops] // (doseq (op ops) is like for (op <- ops) in scala
(println (op 1 2 3 4)))
Now, I've tried a few things in Scala, all of them failing:
scala> List(+, -, *, /)
<console>:1: error: illegal start of simple expression
List(+, -, *, /)
^
scala> List[Double => Double](+, -, *, /)
<console>:1: error: illegal start of simple expression
List[Double => Double](+, -, *, /)
^
scala> List[Double => Double](+_, -_, *_, /_)
<console>:8: error: not found: value *
List[Double => Double](+_, -_, *_, /_)
^
<console>:8: error: not found: value /
List[Double => Double](+_, -_, *_, /_)
^
So what's the correct procedure of defining a list of functions/operators in Scala?
The problem is that these functions are binary operators, i.e., they take two operands and return one. So you have to use:
List[(Double, Double) => Double](_ + _, _ - _, _ * _, _ / _)
In Scala, most value-level operators are actually unary instance methods (maybe all are, not sure if there are counterexmaples). So when you talk about, say, addition of two values of type Double, you're really referring to a method of the first value that takes the second value as a parameter. The familiar infix operator syntax is just sugar. In other words,
scala> 5.7 + 6.3
res0: Double = 12.0
is really just a nice shorthand for:
scala> 5.7.+(6.3)
res1: Double = 12.0
As #bluenote10 already mentioned, you can capture these operators by creating anonymous function that take both the first instance and its operand as parameters and returns the result of the + method:
scala> (lhs: Double, rhs: Double) => lhs + rhs
res2: (Double, Double) => Double = <function2>
Or as in #bluenote10's example, if the type can be inferred (like in a list with the type provided), you can use the nice underscore syntax:
scala> val doublePlus: (Double, Double) => Double = _ + _
doublePlus: (Double, Double) => Double = <function2>
I have a variable v that is a Vector, and I'm trying to add an element to it using +=. It complains that it expects a String instead of an Int:
Welcome to Scala version 2.10.3 (Java HotSpot(TM) 64-Bit Server VM, Java 1.7.0_45).
Type in expressions to have them evaluated.
Type :help for more information.
scala> var v = Vector[Int]()
v: scala.collection.immutable.Vector[Int] = Vector()
scala> v += 3
<console>:9: error: type mismatch;
found : Int(3)
required: String
v += 3
^
Why does it expect a String? When I give it a String (which is ofcourse wrong), it says it expects a Vector[Int]:
scala> v += "three"
<console>:9: error: type mismatch;
found : String
required: scala.collection.immutable.Vector[Int]
v += "three"
^
And when I give it a Vector[Int], it again expects a String:
scala> v += Vector(3)
<console>:9: error: type mismatch;
found : scala.collection.immutable.Vector[Int]
required: String
v += Vector(3)
^
Why does this happen?
I know I can add an element using +:=. But why can I not use +=, like for a Set?
Let's go through this cases one by one:
scala> v += 3
<console>:9: error: type mismatch;
found : Int(3)
required: String
v += 3
^
Here is the main problem that Vector have no + method, so compiler will default to string concatination (which is highly criticized recently as a design flaw, by the way). The problem is that left side (vector) is convertible automatically to string (via Vector.toString), but right one is not.
scala> v += "three"
<console>:9: error: type mismatch;
found : String
required: scala.collection.immutable.Vector[Int]
v += "three"
^
Here concatenation is ok, but you're trying to put result of type String to variable of type Vector[Int], which is why compiler complains. But if you define v as Any compiler will stop complaining:
var v: Any = Vector[Int]()
v += "foo"
// res1: Any = Vector()foo
Now, next case
scala> v += Vector(3)
<console>:9: error: type mismatch;
found : scala.collection.immutable.Vector[Int]
required: String
v += Vector(3)
^
String concatenation again, and again, result of type String goes to the variable of type Vector.
Now, talking about why Vector does not have the very same + operation: ordinary Set have no notion of order, whereas Vector, and Seq in general have and + would be confusing: do I add to the end or to the start? So instead of implicit rule, you have to explicitly decide whether you use :+ or +:.
Why does the following compile?
scala> val ch1 = 'a' + 'b'
ch1: Int = 195
but the following doesn't?
scala> var ch1 = 'a'
ch1: Char = a
scala> ch1 += 'b'
<console>:9: error: type mismatch;
found : Int
required: Char
ch1 += 'b'
^
scala> ch1 = ch1 + 'b'
<console>:8: error: type mismatch;
found : Int
required: Char
ch1 = ch1 + 'b'
^
And why is the error message so misleading? Why does it say required: Char when what I am passing is clearly a Char?
When you add a Char and another Char, the result is an Int.
scala> 'a' + 'c'
res2: Int = 196
That's the "found" part of the error message.
This might help:
What is the concept of "weak conformance" in Scala?
http://lmazy.verrech.net/wp-content/uploads/2011/02/scala_type_hierarchy.png
Regards,
raichoo
I guess you have to help the compiler here if you annotate the ch1 as Int it works as expected?
The problem is I guess your intend is misread by the compiler :)
How should it know that you declare a Char to get it's int value to add another Int out if it? You are trying to change the type of a variable after assignment , how could , should that work? So start with var ch1:Int='a' and it works.