How to Initialize a Register of Vectors? - chisel

I have defined a register of vectors like this
val my_reg = Reg(Vec(n, Bits(32.W)))
and I access the elements of this register in a for loop using my_reg(i).
Now, I like to initialize this register to zero, so I change the variable definition to this
val my_reg = Reg(Vec(n, Bits(32.W)), init = UInt(0))
However, I get the following compilation error when I want to access the elements of this register
chisel3.core.Data does not take parameters
my_reg(i) := io.a(i)
How can I define a register of vectors and properly initialize them synchronously?

Use RegInit instead. I believe the following statement will do what you want
val my_reg = RegInit(Vec(Seq.fill(n)(0.U(32.W))))
The Vector is initialized by a Seq of UInt zeros that are 32 bits wide

Looks like in Chisel 3 this should be VecInit instead of Vec:
val initRegOfVec = RegInit(VecInit(Seq.fill(4)(0.U(32.W))))
Source: https://github.com/freechipsproject/chisel3/wiki/Cookbook#how-do-i-create-a-reg-of-type-vec

Related

Error while passing values using peekpoketester

I am trying to pass some random integers (which I have stored in an array) to my hardware as an Input through the poke method in peekpoketester. But I am getting this error:
chisel3.internal.ChiselException: Error: Not in a UserModule. Likely cause: Missed Module() wrap, bare chisel API call, or attempting to construct hardware inside a BlackBox.
What could be the reason? I don't think I need a module wrap here as this is not hardware.
class TesterSimple (dut: DeviceUnderTest)(parameter1 : Int)(parameter2 : Int) extends
PeekPokeTester (dut) {
var x = Array[Int](parameter1)
var y = Array[Int](parameter2)
var z = 1
poke(dut.io.IP1, z.asUInt)
for(i <- 0 until parameter1){poke(dut.io.IP2(i), x(i).asUInt)}
for(j <- 0 until parameter2){poke(dut.io.IP3(j), y(j).asUInt)}
}
object TesterSimple extends App {
implicit val parameter1 = 2
implicit val parameter2 = 2
chisel3.iotesters.Driver (() => DeviceUnderTest(parameter1 :Int, parameter2 :Int)) { c =>
new TesterSimple (c)(parameter1, parameter2)}
}
I'd suggest a couple of things.
Main problem, I think you are not initializing your arrays properly
Try using Array.fill or Array.tabulate to create and initialize arrays
val rand = scala.util.Random
var x = Array.fill(parameter1)(rand.nextInt(100))
var y = Array.fill(parameter2)(rand.nextInt(100))
You don't need the .asUInt in the poke, it accepts Ints or BigInts
When defining hardware constants, use .U instead of .asUInt, the latter is a way of casting other chisel types, it does work but it a backward compatibility thing.
It's better to not start variables or methods with capital letters
I suggest us class DutName(val parameter1: Int, val parameter2: Int) or class DutName(val parameter1: Int)(val parameter2: Int) if you prefer.
This will allow to use the dut's paremeters when you are writing your test.
E.g. for(i <- 0 until dut.parameter1){poke(dut.io.IP2(i), x(i))}
This will save you have to duplicate parameter objects on your DUT and your Tester
Good luck!
Could you also share your DUT?
I believe the most likely case is your DUT does not extend Module

How to Paramatrized vector of registers in chisel

I need an example on how to paramtrize Vector of registers in terms of bit-width and initial values which are not '0' and are different for each register.
My use-case is a generic filter coefficients bank with some unique reset values to each, and off course an option to override values.
I thought of something like the below code (not really sure how to write the iteration, so this is kind of pseudo):
class Coeffbank(bitWidth : UInt ,ncoeff : UInt, rstVal : Vec(SInt)) extends Module {
// how do iterate through the reset vector ?? //
val coeffs = Vec.fill(ncoeff) {Reg(init = SInt(rstVal(i),width = bitwidth))
}
Also, when new'ing the above (instantiating this module how do I pass the list of reset value in the argument list?
Hoping to get some help on how to write it properly.
The explanation should probably be a bit more thorough, but basically you need to create a Reg of Vec. Something like should do it:
val coeffs = RegInit(rstVal)
In this case, since you already have the Vec of reset values, you can just pass it to the Reg constructor.
I'm assuming that the size of rstVal is equal to ncoeff, otherwise you'll need to reduce the size of rstVal with something like rstVal.take(ncoeff). Also note that I'm using RegInit which is the preferred way to create a register with a reset value.
Let's start with the easy case. This would be much easier if instead of a Vec of SInts your rstVal array was instead a scala collection (Seq, Array, ...) of regular SInt. When possible it is best to save generation of actual hardware until you directly need them. If rstVal contains Int's. Your code would become
val newRstVals = VecInit(Seq.tabulate(ncoeff) { index => rstVals(index).S(bitWidth.W) })
val reg = RegInit(newRstVals)
If you really need to pass in a Vec then the right approach is to create a separate type instance and use the two argument call to RegInit
val vecType = Vec(ncoeff, SInt(bitWidth.W))
val newRstVals1 = VecInit(Seq.tabulate(ncoeff) { index => newRstVals(index) })
val reg = RegInit(vecType, newRstVals1)
There might be problems if the bitWidth you pass in is not big enough to contain the constants you have passed in. You probably should have some checks for that.

Indexing of elements in a Seq of string with chisel

I have, tab=Array(1.U, 6.U, 5.U, 2.U, 4.U, 3.U) and Y=Seq(b,g,g,g,b,g), tab is an array of UInt.
I want to do a map on tab as follows:
tab.map(case idx=>Y(idx))
But I keep getting the error: found chisel3.core.UInt, required Int.
I tried using the function peek() to convert idx to an Int by doing
tab.map(case idx=>Y(peek(idx).toInt)
but I get peek not found. I also saw that I cannot convert a chisel UInt to an Int here but did not understand the use of peek well with the example given. So please, is there another approach to do the above?
Thanks!
The immediate problem is that you cannot access the elements of scala collections using a hardware construct like UInt or SInt. It should work if you wrap Y in a Vec. Depending on your overall module this would probably look like
val YVec = VecInit(Y)
val mappedY = tab.map { case idx => YVec(idx) }

How do I read the contents of stack variables in IDA?

I notice that a char buffer has been allocated on the stack in a function. It goes like this:
.text:00401xxx Buffer= byte ptr -24h
I know that I can read Dwords at memory addresses by going:
Dword(0x<address>)
But, how do I do the same for stack variables? Specifically here, I'd like to be able to read the whole character buffer...
Yuo could use the idc IDA module, there are many interesting functions.
If you want print dword, this is correct: Dword(0x<address>)
For memory dumping as suggest above you could use follow function:
**GetManyBytes(ea, size, use_dbg=False)<br>**
Parameters:
ea - linear address
size - size of buffer in normal 8-bit bytes
use_dbg - if True, use debugger memory, otherwise just the database
An example:
GetManyBytes(0x<address>, 50, True)
You can call the function runtime, you could use also a simple script like:
from idc import GetManyBytes
from struct import unpack
def simple_dump():
arr = []
for i in xrange(0, 2*SIZE_TO_DUMP, 2):
bytes = GetManyBytes(0x<address>+i,2)
arr.append(unpack("h", bytes)[0])
return arr
def main():
values = simple_dump()
You can also use the IDA Hex-View windows

About the syntax of Chisel

I am new to this.
I have some questions about the code.
What is different between these codes:
val myVec = Vec(5){Fix(width= 23)}
and
val myVec = Vec.fill(5){SInt(width = 23 )}
what does "fill" mean?
thanks
"Fill" is a Scala-ism, for initializing things like lists with elements:
scala> val x = List.fill(3)("foo")
x: List[java.lang.String] = List(foo, foo, foo)
In the same vein, Vec.fill(5){SInt(width=23)} is returning a Chisel Vec where each of the 5 elements is set to a 23b signed integer wire.
However, if you are using Chisel, you should move to Chisel3 (https://github.com/ucb-bar/chisel3/wiki), in which the new syntax is:
val myVec = Wire(Vec(5, SInt(width=23)))
That creates a Wire of a 5-element vector made up of 23b signed integers. (In Chisel3 any wires must be explicitly wrapped).