There appears to be either a bug with or undocumented changes to the bitwise negation operator between chisel2 and chisel3.
Chisel3 code not working
import chisel3._
class bitwise_neg extends Module {
val io = new Bundle {
val in = Input(UInt(4.W))
val out = Output(UInt(4.W))
}
io.out := ~io.in
}
Error message generated for line containing "~":
type mismatch; found : ()chisel3.core.Bits required: chisel3.core.Data
Chisel2 working code
import Chisel._
class bitwise_neg extends Module {
val io = new Bundle {
val in = UInt(INPUT, 4)
val out = UInt(OUTPUT, 4)
}
io.out := ~io.in
}
Any ideas on the new Chisel3 syntax or if this is a bug?
The problem is not related to the ~, you will get the same error even if you remove the ~. Just as jkoenig said, chisel3 requires that you wrap the io bundle in an IO() like this:
class bitwise_neg extends Module {
val io = IO(new Bundle {
val in = Input(UInt(4.W))
val out = Output(UInt(4.W))
})
io.out := ~io.in
}
If you want (but I wouldn't recommend it) you can use chisel2 notation using the compatibility layer in chisel3 with capital chisel import import Chisel._
import Chisel._
class bitwise_neg extends Module {
val io = new Bundle {
val in = UInt(INPUT, 4.W)
val out = UInt(OUTPUT, 4.W)
}
io.out := io.in
}
Related
I have a question on pack zeros into bundles. For example consider the next code:
class CmplxNum(val bitwidth: Int) extends Bundle {
val real = SInt(INPUT,bitwidth.W)
val imag = SInt(INPUT,bitwidth.W)
}
class MyClass extends Module {
val io = IO(new Bundle {
val in = new CmplxNum(16)
val load = Bool(INPUT)
val clr = Bool(INPUT)
...
})
...
val sample = RegEnable(io.in,0.S,io.load) // <-- how do i set the reset value
When(io.clr) {
sample <> sample.fromBits(0.S) // <-- I tried this it compiles, but dont know if it is correct
}
}
How do I pack zeros into this Bundle in the RegEnable & clr cases ?
For RegEnable I've got elaboration error of type miss-match which make sense
Here is one way. It relies on the relatively new BundleLiterals (new CmplxNum(16)).Lit(_.real -> 0.S, _.imag -> 0.S). I have also refactored your code a little bit to use the current chisel3 idioms. Without a specific need I would not recommend placing your Input/Output in Bundle. Also the more modern way is to wrap the IO fields in Input() or Output()
import chisel3._
import chisel3.util.RegEnable
import chisel3.experimental.BundleLiterals._
class CmplxNum(val bitwidth: Int) extends Bundle {
val real = SInt(bitwidth.W)
val imag = SInt(bitwidth.W)
}
class MyClass extends Module {
val io = IO(new Bundle {
val in = Input(new CmplxNum(16))
val load = Input(Bool())
val clr = Input(Bool())
...
})
...
val sample = RegEnable(
io.in,
init = (new CmplxNum(16)).Lit(_.real -> 0.S, _.imag -> 0.S),
enable = io.load
)
when(io.clr) {
sample <> sample.fromBits(0.S) // <-- I tried this it compiles, but dont know if it is correct
}
}
I'm just starting out with Akka HTTP and I'm having a bit of trouble with the routing DSL and marshaling. The tilde in the 'route' setup results in the error:
value ~ is not a member of akka.http.scaladsl.server.RequestContext ⇒
scala.concurrent.Future[akka.http.scaladsl.server.RouteResult]
possible cause: maybe a semicolon is missing before 'value ~'?
Also, the JSON marshaling in the 'get' clause causing the error:
◾Cannot find JsonWriter or JsonFormat type class for
scala.collection.immutable.Map[String,scala.collection.mutable.Map[String,Tweet]]
◾not enough arguments for method toJson: (implicit writer:
spray.json.JsonWriter[scala.collection.immutable.Map[String,scala.collection> .mutable.Map[String,Tweet]]])spray.json.JsValue.
Unspecified value parameter writer.
I've followed the documentation examples fairly closely, so I'd appreciate help in understanding these errors and how to resolve them. Thanks.
API
import akka.actor.ActorSystem
import scala.concurrent.Future
import akka.stream.ActorMaterializer
import akka.http.scaladsl.Http
import akka.http.scaladsl.server.Directives.path
import akka.http.scaladsl.server.Directives.pathPrefix
import akka.http.scaladsl.server.Directives.post
import akka.http.scaladsl.server.Directives.get
import akka.http.scaladsl.server.Directives.complete
import akka.http.scaladsl.unmarshalling.Unmarshal
import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport._
import akka.http.scaladsl.server.Directives.{entity, as}
import akka.http.scaladsl.model.StatusCodes.{Created, OK}
import spray.json._
import DefaultJsonProtocol._
import akka.stream.Materializer
import scala.concurrent.ExecutionContext
trait RestApi {
import TweetProtocol._
import TweetDb._
implicit val system: ActorSystem
implicit val materializer: Materializer
implicit val execCtx: ExecutionContext
val route =
pathPrefix("tweets") {
(post & entity(as[Tweet])) { tweet =>
complete {
Created -> Map("id" -> TweetDb.save(tweet)).toJson
}
} ~
(get) {
complete {
OK -> Map("tweets" -> TweetDb.find()).toJson
}
}
}
}
object TweetApi extends App with RestApi {
implicit val system = ActorSystem("webapi")
implicit val materializer = ActorMaterializer()
implicit val execCtx = system.dispatcher
val bindingFuture = Http().bindAndHandle(route, "localhost", 8080)
println(s"Server online at http://localhost:8080/\nPress RETURN to stop...")
Console.readLine()
bindingFuture.flatMap(_.unbind()).onComplete { _ => system.shutdown() }
}
Protocol
import spray.json.DefaultJsonProtocol
case class Tweet(author: String, body: String)
object TweetProtocol extends DefaultJsonProtocol {
implicit val TweetFormat = jsonFormat2(Tweet.apply)
}
Pseudo-database
import scala.collection.mutable.Map
object TweetDb {
private var tweets = Map[String, Tweet]()
def save(tweet: Tweet) = {
val id: String = java.util.UUID.randomUUID().toString()
tweets += (id -> tweet)
id
}
def find() = tweets
def findById(id: String) = tweets.get(id)
}
For your 1st error, try the suggestion from the comment, ie. import all from Directives
For second part
◾Cannot find JsonWriter or JsonFormat type class for scala.collection.immutable.Map[String,scala.collection.mutable.Map[String,Tweet]]
◾not enough arguments for method toJson: (implicit writer: spray.json.JsonWriter[scala.collection.immutable.Map[String,scala.collection> .mutable.Map[String,Tweet]]])spray.json.JsValue. Unspecified value parameter writer.
You need to define JsonFormat for Map[String, mutable.Map[String, Tweet]]
By creating an object in your TweetProtocol, extending RootJsonFormat
eg.
type DBEntry = Map[String, mutable.Map[String, Tweet]]
object TweetProtocol extends DefaultJsonProtocol {
implicit object DBEntryJsonFormat extends RootJsonFormat[DBEntry] {
override def read(json: JSValue) {
// your implementation
}
override def write(dbEntry: DBEntry) {
// implementation
}
}
}
I am trying to wire a BlackBox to an arbitrary Bundle, but width inference does not seem to work with the fromBits function. The following compiles fine:
class testBundle extends Bundle {
val io1 = Bool(INPUT)
val io2 = UInt(INPUT,10)
}
class testBox extends BlackBox {
val io = new Bundle {
val in = Bits(INPUT) # Width inference works fine here
val out = Bits(OUTPUT,(new testBundle).getWidth) # But it doesn't work here!
}
}
class test extends Module {
val io = new Bundle {
val in = new testBundle
val out = (new testBundle).flip()
}
val testbox = Module(new testBox)
testbox.io.in := io.in.toBits
io.out := io.out.fromBits(testbox.io.out)
}
But if I remove the (new testBundle).getWidth argument, Chisel cannot infer the width of the output port and errors out. How can I get testBox to connect to arbitrary bundles?
For now I am solving this by passing in the bundle as an argument to the BlackBox:
class testBox(b:Bundle) extends BlackBox {
val w = b.getWidth
val io = new Bundle {
val in = Bits(INPUT,w)
val out = Bits(OUTPUT,w)
}
}
class test extends Module {
val io = new Bundle {
val in = new testBundle
val out = (new testBundle).flip()
}
val testbox = Module(new testBox(io.in))
testbox.io.in := io.in.toBits
io.out := io.out.fromBits(testbox.io.out)
}
I'd welcome a cleaner solution, though.
I'm on a quest to create a JSON API where some of the models could be nicely generalized. I'm a newbie in Spray, so I started out a spike with an over simplified example.
However I can't figure out what is going on with the bellow code...
I have imported both
my custom implicits and
spray.httpx.SprayJsonSupport._
As I understand this is what I have to do in order to have an implicit in scope that can convert from JsonFormat to Marshaller.
Compiler error:
TestService.scala:15: could not find implicit value for parameter um: spray.httpx.unmarshalling.FromRequestUnmarshaller[my.company.Test[my.company.X]]
Code:
package my.company
import spray.routing.HttpService
import spray.json.{JsValue, JsObject, JsonFormat, DefaultJsonProtocol}
trait TestService extends HttpService {
import my.company.TestImplicits._
import spray.httpx.SprayJsonSupport._
val test =
path("test") {
post {
entity(as[Test[X]]) {
test => {
complete(s"type: ${test.common}")
}
}
}
}
}
trait Common {
def commonData: String
}
case class X(id: Long, commonData: String) extends Common
case class Y(commonData: String) extends Common
case class Test[T <: Common](comment: String, common: T)
object TestImplicits extends DefaultJsonProtocol {
implicit val xFormat = jsonFormat2(X)
implicit val yFormat = jsonFormat1(Y)
implicit val yTestFormat: JsonFormat[Test[Y]] = new JsonFormat[Test[Y]] {
def write(test: Test[Y]) = JsObject()
def read(js: JsValue) = Test("test", Y("y"))
}
implicit val xTestFormat: JsonFormat[Test[X]] = new JsonFormat[Test[X]] {
def write(test: Test[X]) = JsObject()
def read(js: JsValue) = Test("test", X(1L, "y"))
}
}
I would appreciate any help. Thanks in advance.
SOLVED
Solution was (as #jrudolp suggested) both to:
Move implicit definitions on top of the file (surprising)
Create RootJsonFormat rather than JsonFormat.
I have this:
package models
import play.api.libs.json._
import play.api.libs.functional.syntax._
object ModelWrites {
implicit val tmoWrites= Json.writes[TestModelObject]
implicit val ihWrites = Json.writes[IntHolder]
}
case class TestModelObject(s1:String, s2:String)
case class IntHolder(i1:Int, i2:Int)
trait HasInts {
val ints: List[IntHolder]
}
When I do this:
scala> val tmo = new TestModelObject("hello", "world") with HasInts {
val ints = List(IntHolder(1,2), IntHolder(3,4))
}
scala> Json.toJson(tmo)
res0: play.api.libs.json.JsValue = {"s1":"hello","s2":"world"}
how can I implicity serialize the mixed-in val 'ints'? Like:
scala> val someInts = List(IntHolder(8,9), IntHolder(10,11))
someInts: List[models.IntHolder] = List(IntHolder(8,9), IntHolder(10,11))
scala> Json.toJson(someInts)
res1: play.api.libs.json.JsValue = [{"i1":8,"i2":9},{"i1":10,"i2":11}]
Note: if I try: implicit val hasIntsWrites = Json.writes[HasInts] I (expectedly?) get:
[error] Models.scala:10: No unapply function found
[error] implicit val hasIntsWrites = Json.writes[HasInts]
[error] ^
You're not going to be able to use the experimental "Inception" feature (Json.writes[...]) directly here, since that only works on case classes. You can, however, build on the Writes instances that Inception can provide to accomplish what you want with only a very little boilerplate.
Note that I'm ignoring the question of whether mixing in a trait when instantiating a case class like this is a good idea—it probably isn't—but the approach I give here will work in the more general case as well.
First for the classes and imports (no changes here):
case class TestModelObject(s1: String, s2: String)
case class IntHolder(i1: Int, i2: Int)
trait HasInts { val ints: List[IntHolder] }
import play.api.libs.json._
import play.api.libs.functional.syntax._
Now we need to put all our lower-priority instances into a trait to make sure that the compiler will pick the right one, since TestModelObject with HasInts is a subtype of both TestModelObject and HasInts:
trait LowPriorityWritesInstances {
implicit val tmoWrites = Json.writes[TestModelObject]
implicit val ihWrites = Json.writes[IntHolder]
implicit object hiWrites extends OWrites[HasInts] {
def writes(hi: HasInts) = Json.obj("ints" -> hi.ints)
}
}
And now the main event:
object WritesInstances extends LowPriorityWritesInstances {
implicit val tmowhiWrites = new Writes[TestModelObject with HasInts] {
def writes(o: TestModelObject with HasInts) =
tmoWrites.writes(o) ++ implicitly[OWrites[HasInts]].writes(o)
}
}
And we're done:
scala> import WritesInstances._
import WritesInstances._
scala> val tmo = new TestModelObject("hello", "world") with HasInts {
| val ints = List(IntHolder(1, 2), IntHolder(3, 4))
| }
scala> println(Json.toJson(tmo))
{"s1":"hello","s2":"world","ints":[{"i1":1,"i2":2},{"i1":3,"i2":4}]}
As desired.