How to declare a variable size memory - chisel

I'm trying to initialize a memory in such a way that a different memory be made depending on the given parameter. So far, I've implemented the following.
import chisel3._
class Temp(data:Boolean=true) extends Module {
val io = IO(new Bundle{
val addr = Input(UInt(16.W))
val dataIn = if (data) Some(Input(SInt(16.W)))
else None
val storeEn = if (data) Some(Input(Bool()))
else None
val dataOut = Output(UInt(16.W))
})
val mem = if (data) Some(Mem(16, SInt(16.W)))
else Some(Mem(16, UInt(16.W)))
if (data) when (io.storeEn.get) {
mem.get.write(io.addr, io.dataIn.get)
} else None
io.dataOut := mem.get.read(io.addr)
}
But I'm receiving a compile error
type mismatch;
[error] found : chisel3.SInt
[error] required: _1 where type _1 >: chisel3.SInt with chisel3.UInt <: chisel3.Bits with chisel3.Num[_ >: chisel3.SInt with chisel3.UInt <: chisel3.Bits]
[error] mem.get.write(io.addr, io.dataIn.get)
[error] ^

Related

How can I parse the json body from from an Akka Client-Side HttpResponse

I'm using Akka's HTTP client library to request a json, and I want to use Play Framework's play-json to parse the json. After I get Akka's HttpResponse, I don't know how to parse the json from the response body, and I don't know how to pass the json to another function in the onComplete directive. Instead, I get this error
overloaded method value parse with alternatives:
[error] (input: Array[Byte])play.api.libs.json.JsValue <and>
[error] (input: java.io.InputStream)play.api.libs.json.JsValue <and>
[error] (input: String)play.api.libs.json.JsValue
[error] cannot be applied to (scala.concurrent.Future[String])
[error] val usefulInfo = Json.parse(data)
[error] ^
[error] one error found
[error] (Compile / compileIncremental) Compilation failed
What I'm trying right now:
import akka.actor.ActorSystem
import akka.http.scaladsl.Http
import akka.http.scaladsl.model._
import akka.stream.ActorMaterializer
import akka.http.scaladsl.model.HttpRequest
import akka.http.scaladsl.unmarshalling.Unmarshal
import play.api.libs.json._
object Main extends App {
// Boilerplate code from Akka's documentation
implicit val system = ActorSystem()
implicit val materializer = ActorMaterializer()
// needed for the future flatMap/onComplete in the end
implicit val executionContext = system.dispatcher
val request = HttpRequest(
method = HttpMethods.GET,
uri = "http://example.com/somedata.json"
)
var response: Future[HttpResponse] = Http().singleRequest(request)
response.onComplete{
case Success(res) => {
val data = Unmarshal(res).to[String]
val usefulInfo = Json.parse(data)
println(usefulInfo)
}
case Failure(e) => println(e)
}
}
Questions I have are:
How can I parse the json after the Future resolves, with Play Framework's Json.parse()?
How can I store or use this json elsewhere after the response Future resolves? Do I need to do something in the Success case?
The main problem is that Unmarshal returns a Future so you need to process the data inside the Future to get the String value.
If you want to keep the result rather than just print it, use tranformWith on the initial result rather than onComplete:
val result = Http().singleRequest(request)
.transformWith {
case Success(res) =>
val data = Unmarshal(res).to[String]
data.map { d =>
val usefulInfo = Json.parse(d)
println(usefulInfo)
usefulInfo
}
case Failure(e) =>
println(e)
Future.failed(e)
}
Note that this becomes much cleaner if you leave the printing until the end:
val result = Http().singleRequest(request)
.flatMap { res =>
Unmarshal(res).to[String].map { data =>
Json.parse(data)
}
}
result.onComplete {
case Success(js) =>
println(s"Success: $js")
case Failure(e) =>
println(s"Failure: $e")
}

chisel partial bulk connection with "<>" operator

I'm having trouble to do partial bulk connection with <>.
I saw in the book Digital Design with Chisel (4.3 Bulk Connections).
It is allowed to connect two bundles with partially matched signals.
I'm currently working on chisel3.2. and it seems not working, and during elatorating it
reports
chisel3.internal.ChiselException: Connection between left (AnonymousBundle(IO io in Fetch)) and source (AnonymousBundle(IO io in Decode)) failed #.regB: Left Record missing field (regB).
Is this changed at some version?
If it is changed, how do we do partial connection now?
This is the testing code(don't mind the module, it is only to keep the signal from optimization):
class Fetch extends Module {
val io = IO(new Bundle {
val instr = Output(UInt(32.W))
val pc = Output(UInt(32.W))
})
val r = RegInit(0.U(32.W))
r := r + 1.U
io.pc := r
io.instr := r+1.U
}
class Decode extends Module {
val io = IO(new Bundle {
val instr = Input(UInt(32.W))
val pc = Input(UInt(32.W))
val aluOp = Output(UInt(5.W))
val regA = Output(UInt(32.W))
val regB = Output(UInt(32.W))
})
io.aluOp := io.pc
io.regA := io.instr
io.regB := io.instr
}
class Execute extends Module {
val io = IO(new Bundle {
val aluOp = Input(UInt(5.W))
val regA = Input(UInt(32.W))
val regB = Input(UInt(32.W))
val result = Output(UInt(32.W))
})
io.result := io.regA
when(io.aluOp > 10.U){
io.result := io.regB
}
}
object MAIN{
def main(args:Array[String]):Unit = {
Driver.execute(Array(""),()=>new Module{
val io = IO(new Bundle{
val result = Output(UInt(32.W))
})
val fetch = Module(new Fetch())
val decode = Module(new Decode())
val execute = Module(new Execute)
fetch.io <> decode.io
decode.io <> execute.io
io <> execute.io
})
}
}
Link:chisel3-vs-chisel2
In Unsupported constructs Chapter:
In Chisel2, bulk-connects <> with unconnected source components do not update connections from the unconnected components.
In Chisel3, bulk-connects strictly adhere to last connection semantics and unconnected OUTPUTs will be connected to INPUTs resulting in the assignment of random values to those inputs.
I'm sorry that I have not fully understanded how to use <> in Chisel3.In my opinion, you should avoid to use <> in Chisel3.
Here is an example that is avaiable in Chisel3.
Code is from here.
import Chisel.Queue
import chisel3._
import chisel3.stage.{ChiselGeneratorAnnotation, ChiselStage}
import chisel3.util.Decoupled
import layered.stage.ElkStage
class MyQueue extends Module {
// Example circuit using a Queue
val io = IO(new Bundle {
val in = Flipped(Decoupled(UInt(8.W)))
val out = Decoupled(UInt(8.W))
})
val queue = Queue(io.in, 2) // 2-element queue
io.out <> queue
}
object MyQueue extends App{
(new ChiselStage).emitVerilog(new MyQueue,Array("-td", "vout"))
// gengerate graph file and it can be viewed by using IDEA plugin named EasySocHDL
(new ElkStage).execute(
Array("-td", "vout", "--lowFir"),
Seq(ChiselGeneratorAnnotation(() => new MyQueue))
)
}

Multiple option for val in a bundle

I tried to add some generation options to my bundle code:
class myIO (val bitwidth: Int,numOfInstances: Int = 1) extends Bundle {
val en = if (numOfInstances == 1) Bool(INPUT) else Vec(numOfInstances,Bool(INPUT))
val data = UInt(INPUT,bitwidth.W)
...
}
when I tried
val io = IO(new myIO(32)) // use default
I get compilation error "type missmatch" io.en is chisel3.core.Data but chisel3.Bool is required. Also when trying :
val io = IO(new myIO(32,1))
I got the same error

Generic Address Decoder

I'd like to implement a generic addr decoder. This is a follow up question to this post.
class AddrDecoder[T <: Data with Num[T]] (dType:T, n:Int) extends Module {
val io = IO (new Bundle {
val mmap = Map(BigInt, BigInt) // base, size ranges
val addr = Input (dType)
val en = Input (Bool())
//val sel = Output(Vec(n,Bool())) // $onehot0 selector
val sel = Output(Bool():_*) // $onehot0 selector
})
// Curried function which accepts a tuple and an input addr
// Use map to apply it to inputs
def inside (range:(T,T))(addr:T):Bool = {
addr >= range._1 && addr < range._1 + range._2
}
// MUX output
for (i <- 0 until n) {
io.sel(i) := false.B
}
// Check addr range and assert high if matches
var idx = 0 // yes, variable
for ((k,v) <- io.mmap) {
when (io.en) {
io.sel(idx) := (k + v) (inside(_)(io.addr))
idx := idx + 1.U
}
}
// $onehot0 output encoding check
assert (PopCount(io.sel) >= 1.U, "Invalid addr decoding")
}
I get a compile errors:
[error] found : math.BigInt.type
[error] required: (?, ?)
[error] val mmap = Map(BigInt, BigInt) // base, size ranges
...
[error] found : chisel3.core.Bool
[error] required: Seq[?]
[error] val sel = Output(Bool():_*) // $onehot0 selector
Can I use Map and a variable Bool array as IO ports? If not, how to rewrite this correctly?
Thank you!
Okay, here's my solution. Not that generic, since I could not specialize it to BigInt, but works for me now:
class AddrDecoder (addrWidth:Int, mmap:Map[UInt, UInt]) extends Module {
val size = mmap.size
val io = IO (new Bundle {
val addr = Input (UInt(addrWidth.W))
val en = Input (Bool())
val sel = Output(Vec(size,Bool())) // $onehot0 selector
})
// Curried function which accepts a tuple and an input addr
def inside (range:(UInt,UInt))(addr:UInt):Bool = {
addr >= range._1 && addr < range._1 + range._2
}
// MUX output
for (i <- 0 until size) {
io.sel(i) := false.B
}
// Loop thru the Memory Map, pair with index and evaluate logic value for io.sel
mmap.zipWithIndex foreach { case (entry,idx) =>
when (io.en && inside(entry)(io.addr)) {
io.sel(idx) := true.B
} .otherwise {
io.sel(idx) := false.B
}
}
// $onehot0 output encoding check
assert (PopCount(io.sel) <= 1.U, "Invalid addr decoding")
}

illegal start of simple expression Scala

I have two version of Scala compiler 2.11.12 and 2.12.4. I have a code which overrides read and write method of a json protocol. The code is something like this.
implicit lazy val abcJsonProtocol: RootJsonFormat[XYZ] = new
RootJsonFormat[XYZ] {
override def write(obj: XYZ): JsValue = {
val baseJson =
JsObject(
“abc” -> obj.efg.toJson,
“ikj” -> obj.mno.toJson
)
obj
.map(value => JsObject(baseJson.fields + (“wxy” ->
value.toJson)))
.getOrElse(baseJson)
}
override def read(value: JsValue): XYZ = {
val jsObject = value.asJsObject
jsObject.getFields("abc",
"kJ") match {
case Seq(efg, mno) =>
XYZ(
efg = efg.convertTo[String],
mno = mno.convertTo[String],
)
}
}
}
The error is something likes this
illegal start of simple expression
[error] )
[error] ^
')' expected but '}' found.
[error] }
[error] ^
The compilation fails only in 2.11.12 version and passes in the latter version
Thanks in advance.
Your case class
case class XYZ(efg: String, mno: String)
then, define the protocol something like this.
import spray.json._
implicit object XYZFormat extends RootJsonFormat[XYZ] {
// writer function
def write(obj: XYZ): JsValue = JsObject(
"efg" -> JsString(obj.efg),
"mno" -> JsString(obj.mno)
)
// reader function
def read(json: JsValue): XYZ =
json.asJsObject.getFields("efg", "mno") match {
case Seq(JsString(efg), JsString(mno)) => XYZ(efg, mno)
case _ => throw DeserializationException("Not valid XYZ model")
}
}