How to get size of UInt() in chisel? - hdl

Maybe it's easy but I can't simply found how to get the bitsize of an UInt() value in Chisel ?
I know how to set a size by declaration :
val a = UInt(INPUT, 16)
But to get the 'a' size, is there a property like :
val size = a.?
Or :
val size = width(a)

A couple of things. First, looks like you are using Chisel 2 semantics. You should probably be using Chisel 3 semantics which means you should be writing
val a = Input(UInt(16.W))
The quick answer is you can get the width like:
val theWidth = if(io.in0.widthKnown) io.in0.getWidth else -1
or using match
val theWidth = io.in0.widthOption match {
case Some(w) => w
case None => -1 // you decide what you want the unknown case to be.
}
You now have the value of the width in the Scala variable theWidth which is an Int, the if or the match must be used because the width may, in principle, be undefined.
The longer answer is that you should be careful with wanting to do this. theWidth is evaluated at circuit generation time, if width inference is being used (which is usually the case if you are interrogating a chisel type for its width) you won't be able to see it because width inference is done after the circuit is elaborated and it is processed by the Firrtl compiler.
It's possible you should make the width you want to know a parameter to the circuit and use that instead of widthOption. Something like.
class X(ioWidth: Int) extends Module {
val io = IO( new Bundle {
val in0 = Input(UInt(ioWidth.W))
...
})
val reg = Reg(UInt((ioWidth * 2).W)) // using width parameter here.
...
}

Related

How to setup for each loop in Kotlin to avoid out of bounds exception

In java I got this construction
for (let i = 0; i < x.length-1; I++
And here to avoid outOfBoundsException we are using x.length-1 but how to do the same thing in Kotlin? I got this code so far
x.forEachIndexed { index, _ ->
output.add((x[index+1]-x[index])*10)
}
And it crashes on the last element when we call x[index+1] so I need to handle the last element somehow
Input list
var x = doubleArrayOf(0.0, 0.23, 0.46, 0.69, 0.92, 1.15, 1.38, 1.61)
For a classic Java for loop you got two options in Kotlin.
One would be something like this.
val x = listOf(1,2,3,4)
for (i in 0 .. x.lastIndex){
// ...
}
Using .. you basically go from 0 up to ( and including) the number coresponding to the second item, in this case the last index of the list.( so from 0 <= i <= x.lastIndex)
The second option is using until
val x = listOf(1,2,3,4)
for (i in 0 until x.size){
// ...
}
This is similar to the previous approach, except the fact that until is not inclusive with the last element.(so from 0 <= i < x.size ).
What you probably need is something like this
val x = listOf(1,2,3,4)
for (i in 0 .. x.lastIndex -1){
// ...
}
or alternative, using until, like this
val x = listOf(1,2,3,4)
for (i in 0 until x.size-1){
// ...
}
This should probably avoid the IndexOut of bounds error, since you go just until the second to last item index.
Feel free to ask more if something is not clear.
This is also a great read if you want to learn more about ranges. https://kotlinlang.org/docs/ranges.html#progression
You already have an answer, but this is another option. If you would use a normal list, you would have access to zipWithNext(), and then you don't need to worry about any index, and you can just do:
list.zipWithNext { current, next ->
output.add((next - current)*10)
}
As mentioned by k314159, we can also do asList() to have direct access to zipWithNext and other list methods, without many drawbacks.
array.asList().zipWithNext { current, next ->
output.add(next - current)
}

Kotlin - Type mismatch: inferred type is Any? but Boolean was expected

I'm trying my hands on Kotlin. Being from a Python background is really giving me a tough time to get the knack of the Kotlin syntax. I'm trying to do a simple dictionary (Mutable Map) operation. However, its giving me exceptions.
This is what I tried. Kotlin compiler
Adding the code snippet for reference.
fun main() {
val openActivityMap = mutableMapOf<String, MutableMap<String, Any>>()
val packageName = "amazon"
val currentTime = 23454321234
if(openActivityMap.containsKey(packageName)){
if(openActivityMap[packageName]?.get("isAlreadyApplied")){
if((openActivityMap[packageName]?.get("lastAppliedAt") - currentTime) > 3600){
openActivityMap[packageName]?.put("isAlreadyApplied", false)
}
}
else{
openActivityMap[packageName]?.put("isAlreadyApplied", false)
}
}
}
I'm a bit late to the party, but I'd like to point out another solution here.
As I commented on the OP, heterogeneous maps with fixed string keys like this are usually better expressed with classes in Kotlin. For instance, in your case, the class for your main map's values could be the following:
data class PackageInfo(
var isAlreadyApplied: Boolean,
var lastAppliedAt: Long,
)
(you could obviously add more properties if need be)
This would save you all the casts on the final values.
Another point I'd like to make is that if you access the value for a key anyway, you don't need to check up front the existence of the key with containsKey. Maps return null for keys that are not associated with any value (this is why you need to check for null after getting the value).
The compiler cannot see the correlation between containsKey and the subsequent get or [] access. However, it's smart enough to understand a null check if you simply get the value first and then check for null.
This always applies unless you want to tell the difference between keys that aren't in the map and keys that are in the map but associated null values (which is quite rare).
All in all, I would write something like that:
fun main() {
val openActivityMap = mutableMapOf<String, PackageInfo>()
val packageName = "amazon"
val currentTime = 23454321234
val packageInfo = openActivityMap[packageName]
if (packageInfo != null) { // the key was found and the value is smart cast to non-null in the next block
if (packageInfo.isAlreadyApplied) {
if ((packageInfo.lastAppliedAt - currentTime) > 3600) {
packageInfo.isAlreadyApplied = false
}
} else {
packageInfo.isAlreadyApplied = false
}
}
}
data class PackageInfo(
var isAlreadyApplied: Boolean,
var lastAppliedAt: Long,
)
I would recommend writing tests first and working in small increments, but this should fix your compilation issues:
fun main() {
val openActivityMap = mutableMapOf<String, MutableMap<String, Any>>()
val packageName = "amazon"
val currentTime = 23454321234
if(openActivityMap.containsKey(packageName)){
if(openActivityMap[packageName]?.get("isAlreadyApplied") as Boolean){
if((openActivityMap[packageName]?.get("lastAppliedAt") as Long - currentTime) > 3600){
openActivityMap[packageName]?.put("isAlreadyApplied", false)
}
}
else {
openActivityMap[packageName]?.put("isAlreadyApplied", false)
}
}
}
EDIT: Also I prefer to avoid nullable variables and mutable objects in general, but I suppose there's an exception to every rule.
Couldn't you just declare your Map<String, Any> to return a Boolean instead of Any? So,
val openActivityMap = mutableMapOf<String, MutableMap<String, Boolean>>()
It looks like you're trying to use your second Map to store both Booleans and Ints, which is complicating the logic. You'll need to typecast if you decide to approach it without Typing.
There's a problem with the 2 statement below
if(openActivityMap[packageName]?.get("isAlreadyApplied"))
if((openActivityMap[packageName]?.get("lastAppliedAt") - currentTime) > 3600)
As we all know, an IF statement requires a boolean value for it's param. The types of both statement are unknown at compilation time as they are of a Generic type, Any. As such,
openActivityMap[packageName]?.get("isAlreadyApplied") could be a null or of type Any (Not Boolean).
openActivityMap[packageName]?.get("lastAppliedAt") could be a null or of type Any (an Int was expected here for computation).
This would throw compilation errors as the compiler does not know the types to go with. What could be done is to cast to it's proper types.
Solution
openActivityMap[packageName]?.get("isAlreadyApplied") as Boolean ?: false
((openActivityMap[packageName]?.get("lastAppliedAt") as Int ?: 0) - currentTime)
Giving a default value if it's null.
maybe you can try something like this
if (openActivityMap.containsKey(packageName)) {
val packageMap = openActivityMap[packageName]!!
val applyRequired = (packageMap["lastAppliedAt"] as Long - currentTime) > 3600
packageMap["isAlreadyApplied"] = packageMap.containsKey("isAlreadyApplied") && !applyRequired
}
btw. do you really want to have lastAppliedAt to be in te future? otherewise it will never be > 3600

Extract value out of Kotlin arrow Either type and assign it to const

It would be a basic question, but I couldn't figure out a solution. I need to initialize a constant out of the right-side value of below either type.
val test: Either<String, Int> = 1.right()
I tried something like below but it shrinks the scope of the constant.
when(test) {
is Either.Right -> {val get:Int = test.b}
is Either.Left -> println(test.a)
}
I want that get to be scoped outside of when statement. Is there any way to do it or Arrow Either is not made for this purpose?
The important question is: what should happen if the Either is Left. In this example it is created close to where it's used, so it is obvious to you as a developer. But to the compiler what is inside the Either can be either an Int or a String.
You can extract the value using for example fold:
val x = test.fold({ 0 }, {it}) // provide 0 as default in case the Either was a `Left`
// x = 1
another option is getOrElse
val test = 1.right()
val x = test.getOrElse { 42 } // again, default in case it was a `Left`
// x = 42
You can also work with it without unwrapping it:
val test = 1.right()
val testPlus10 = test.map { it + 10 } // adds 10 to `test` if it is `Right`, does nothing otherwise
val x = testPlus10.getOrElse { 0 } // unwrap by providing a default value
// x = 11
For more example check the official docs.
Recommended reading: How do I get the value out of my Monad

I am getting the val cannot be reassigned compile time error. But I have declared the variable as `var` only

val cannot be reassigned compile time error var variable. Can't we change the array value?
Error
Array.kt:11:3: error: val cannot be reassigned
Code:
import java.util.Scanner
fun main(args: Array< String>){
println("Enter the no")
val scanner = Scanner(System.`in`)
var nos = Array<Int>(5){0}
var i : Int = 1
for (i in 1..3){
nos[i] = scanner.nextInt()
i = i+1
}
println("Given values $nos")
}
The for (i in 1..3) ... statement redefines i for the scope of its body, where it becomes a val (it's actually a separate variable that shadows the i declared outside the loop).
You can fix the code by using different names for these variables, or, in your case, by simply removing var i: Int = 1 and i = i + 1:
val scanner = Scanner(System.`in`)
var nos = Array<Int>(5) { 0 }
for (i in 1..3) {
nos[i] = scanner.nextInt()
}
println("Given values $nos")
UPD (answering to the comment): You can iterate in the opposite direction or using a non-unit step by building a progression with functions downTo and step, both described here in the reference.
var i : Int = 1
for (i in 1..3){
nos[i] = scanner.nextInt()
i = i+1
}
In this code you declared not one, but two variables with the name i because the for header creates its own declaration. Within the loop, only the version declared in the for header is visible, and that one is a val by definition.
Having said that, I'm unclear on what you were trying to achieve since everything looks like it would work just the way you want it without trying to update i in the loop.

How to convert toFixed(2) in Kotlin

What should I write in the place of area.toFixed(2)
fun main(args: Array<String>) {
val a = 20
val h = 30
val area = a * h / 2
println("Triangle area = ${area.toFixed(2)}")
}
I think you really meet a problem that how to convert Javascript code to Kotlin code. You need to ask the question clearly at next time, :). you can use String#format instead, for example:
println("%.2f".format(1.0)) // print "1.00"
println("%.2f".format(1.253)) // print "1.25"
println("%.2f".format(1.255)) // print "1.26"
AND the area is an Int which means it will truncates the precision, Kotlin doesn't like as Javascript use the numeric by default, so you should let a*h divide by a Double, then your code is like as below:
// v--- use a `Double` instead
val area = a * h / 2.0
println("Triangle area = ${"%.2f".format(area)}")