How to keep val names under withClock() or withClockAndReset() scopes - chisel

Val names under withClock() & withClockAndReset() scopes tend to lose their coded names in the generated Verilog file.
So far in order to maintain to original names I used suggestName() function to force the original name.
However I wonder if there is a smarter way do it ? is there a way to force all vals to keep their names without adding suggestName() to each val declaration ?

As Kamyar mentioned in his comment, you should use the #chiselName macro
import chisel3._
import chisel3.experimental.chiselName
#chiselName
class MyModule extends Module {
...
withClock(otherClock) {
val importantReg = Reg(...) // <- this will now get a name
}
}
The way #chiselName works is it will automatically add a .suggestName to each val.

Related

Scala & json4s - parsing JSON with fields that start with a numeric character

I've got deeply nested JSON parsers (using json4s.jackson) that I'm trying to simplify using case classes.
My problem is... some of the fields start with numbers, but scala cannot have an arg name that starts with a numeric character.
Example:
import org.json4s.jackson.JsonMethods._
import org.json4s._
implicit val formats = DefaultFormats
val jsonStr = """{"5gLog":{"i":99}}""" // <--- note the field "5gLog"
val jval = parse(jsonStr)
case class Raw5gLog(i: Int)
val raw5gLog = (jval \ "5gLog").extract[Raw5gLog]
This works. But what I need to do, because these fields are nested deep within the JSON... is something like this...
val jsonStr = """{"xgLog":{"i":99}}"""
val jval = parse(jsonStr)
case class RawRecord(xgLog: Raw5gLog)
val rawRecord = jval.extract[RawRecord]
This would work... if the fields were named like xgLog, but the fields are actually named like 5gLog as above, and I can't give an arg name to a class like 5gLog...
case class RawRecord(5gLog: Raw5gLog)
// error: Invalid literal number
I thought about something like
parse(jsonStr.replace("\"5g", "\"fiveg"))
But there's real data, beyond the field names, in the JSON that can be impacted.
The best solution I can figure is to add extra apply methods to the affected case classes...
case class RawRecord(fivegLog: Raw5gLog)
object RawRecord {
def apply(jval: JValue): RawRecord =
RawRecord( (jval \ "5gLog").extract[Raw5gLog] )
}
val rawRecord = RawRecord(jval)
But I feel like every time I make some structurally different workaround like this for an edge case, it's always the beginning of my code turning into a mess. I could give every case class a new apply method and use it for everything, but it seems like a lot of extra code for a small subset of the data.
Is there a better way?
Scala can use any string as a variable name, but you may have to quote it with backticks:
case class RawRecord(`5gLog`: Raw5gLog)
You also need to do this if you have a field called type or any other reserved word. This is how - can be a function name, for example.

how to override/extend chisel signal naming

It seems not an easy thing to do or even impossible, but we are using a naming convention that prefix or postfix signals with "i_" or "o_" for inputs/outputs in verilog.
Is there some method to mess with or override inside the chisel library to to that?
I saw that except for clock and reset, all signals have "io" prefix.
Is is possible to use just "i" for input and "o" for output?
The easiest way to do this is to probably use a MultiIOModule. However, you can also do it with suggestName. Both approaches are shown below.
MultiIOModule
This a more flexible Module that lets you call the IO method to add ports to a module more than once. (Module requires that you define an io member and only allows you to call IO once.)
Because MultiIOModule frees you from the constraints of val io = ... you can use the prefix/postfix naming that you want with the names of your vals. Reflective naming will then get these right in the generated Verilog.
Consider the following Chisel code:
import chisel3._
import chisel3.stage.{ChiselStage, ChiselGeneratorAnnotation}
class Foo extends MultiIOModule {
val i_bar = IO(Input(Bool()))
val o_baz = IO(Output(Bool()))
o_baz := ~i_bar
}
(new ChiselStage).execute(Array.empty, Seq(ChiselGeneratorAnnotation(() => new Foo)))
This produces the following Verilog:
module Foo(
input clock,
input reset,
input i_bar,
output o_baz
);
assign o_baz = ~ i_bar;
endmodule
SuggestName
As an alternative, you can use the suggestName method to change the name to be different from what reflective naming (getting the name from the name of the val) would use.
Using suggestName you can coerce the names to be whatever you want. The following Chisel produces the same Verilog as above:
class Foo extends MultiIOModule {
val a = IO(Input(Bool())).suggestName("i_bar")
val b = IO(Output(Bool())).suggestName("o_baz")
b := ~a
}

Is there a way to make signals in Chisel not defined at module scope visible in waveforms?

If we take for example the following code excerpt (at the top of a module):
val write_indices = WireInit(VecInit(Seq.fill(wordsPerBeat)(0.U((log2Ceil(nWays)+log2Ceil(nSets)+log2Ceil(cacheBlockBytes/wordBytes)).W))))
val write_line_indices = WireInit(VecInit(Seq.fill(wordsPerBeat)(0.U(log2Ceil(cacheBlockBytes/wordBytes).W))))
dontTouch(write_indices)
dontTouch(write_line_indices)
// refill logic
when(mem_response_present) {
for (i <- 0 until wordsPerBeat) {
val beatIdx = i.U(log2Ceil(wordsPerBeat).W)
val write_line_index = Cat(d_refill_cnt(log2Ceil(cacheBlockBytes/wordsPerBeat/wordBytes)-1, 0), beatIdx)
val write_idx = Cat(refill_way, refill_set, write_line_index)
write_indices(i) := write_idx
write_line_indices(i) := write_line_index
cache_line(write_idx) := tl_out.d.bits.data((i + 1) * wordBits - 1, i * wordBits)
}
}
The only reason for the two top level signals is to get lower signals visible in waveforms.
Is there any way to achieve the same effect without having to manually create those signals?
In this example half the code is used just to get the ability to debug.
That seems a bit excessive.
That seems a bit excessive
Completely agreed, fortunately there is a solution. For implementation reasons, Chisel by default is only able to name public fields of the Module class. That is, only the values at the the top-level scope of your Module. However, there is a nifty macro chisel3.experimental.chiselName that can name these vals inside of the for loop. Try annotating your Module like so:
import chisel3._
import chisel3.experimental.chiselName
#chiselName
class MyModule extends Module {
...
}
Please check out this earlier answer discussing naming, it has more information than is relevant to answer this question alone, but it has other useful information about how naming works in Chisel.

Scala - Circe - Case Class Serialization without Class Name

I have used Circe previously for case class serialization / deserialization, and love how it can be used without the boilerplate code required by other Scala JSON libraries, but I'm running into an issue now I'm not sure how to resolve. I have an ADT (a sealed trait with several case class instances) that I would like to treat (from my Akka Http Service, using akka-http-json) generically (ie, return a List[Foo], where Foo is the trait-type), but when I do so using Circe's auto-deriviation (via Shapeless), it serializes the instances using the specific case class name as a 'discriminator' (eg, if my List[Foo] contains instances of Foo1, then each element in the resulting serialized list will have the key Foo1). I would like to eliminate the type name as a discriminator (ie, so that instead of having each element in the sequence prefixed with the type name-- eg, "Foo1": {"id : "1", name : "First",...}, I just want to serialize the case class instances to contain the fields of the case class: eg, {"id":"1,"name:"First",...}...Essentially, I'd like to eliminate the type name keys (I don't want the front-end to have to know what concrete case class each element belongs to on the back-end).All elements in the list to be serialized will be of the same concrete-type, all of which would be subtypes of my ADT (trait) type. I believe this can be done using Circe's semi-auto derivation, though I haven't had a chance to figure out exactly how. Basically, I would like to use as much of Circe's auto-derivation as possible, but eliminate outer-level class names from appearing in the resulting JSON. Any help / suggestions would be very much appreciated! Thanks!
you can do it following the instruction in the doc: https://circe.github.io/circe/codecs/adt.html
import cats.syntax.functor._
import io.circe.{ Decoder, Encoder }, io.circe.generic.auto._
import io.circe.syntax._
object GenericDerivation {
implicit val encodeEvent: Encoder[Event] = Encoder.instance {
case foo # Foo(_) => foo.asJson
case bar # Bar(_) => bar.asJson
case baz # Baz(_) => baz.asJson
case qux # Qux(_) => qux.asJson
}
implicit val decodeEvent: Decoder[Event] =
List[Decoder[Event]](
Decoder[Foo].widen,
Decoder[Bar].widen,
Decoder[Baz].widen,
Decoder[Qux].widen
).reduceLeft(_ or _)
}
import GenericDerivation._
import io.circe.parser.decode
decode[Event]("""{ "i": 1000 }""")
// res0: Either[io.circe.Error,Event] = Right(Foo(1000))
(Foo(100): Event).asJson.noSpaces
// res1: String = {"i":100}
This may not be the best answer, but after some more searching this is what I've been able to find. Instead of having the class name as a key in the Json produced, it can be serialized as a field as following:
implicit val genDevConfig: Configuration = Configuration.default.withDescriminator("type")
(you can use whatever field name here you'd like; Travis Brown's previous example for a similar issue used a field named what_am_i). So my apologies-- I do not yet know if there is a canonical or widely accepted solution to this problem, especially one that will easily work with Akka Http, using libraries such as akka-http-json, where I still seem to be encountering some issues, though I'm sure I'm probably overlooking something obvious! Anyway, my apologies for asking a question that seems to come up repeatedly!

How to split messages file into multiple files in play 2.0 framework

I have a huge message file which i need to split into multiples files for different languages.
For example :
I created one folder for English locale i.e. en and another for French locale , fr inside conf folder.
en contains messages1_en.properties and messages2_en.properties
fr contains messages1_fr.properties and messages2_fr.properties
How to access these properties files inside my view.
Thanks
The only way to do that without introducing your own alternative implementation and use that instead of the built in Messages is to use hacked locales, so you would do fr_type1, fr_type2 or something like that to select the right alternative.
This is probably a bad idea since it's always risky to use an API in a different way from how it was intended to be used, there is a high risk of unexpected behaviour and it might be brittle since there is no guarantee that you will be able to use made up locales in future versions etc.
If you look at the Messages implementation you could probably get some ideas of how to implement your own without much fuss.
Good luck!
That's an old question, but i had a close issue, and i didn't find a solution anywhere.
This example use a configuration key to load messages from a file with a custom name. But you can easily modify it to load messages file from a subdirectory and/or multiple messages files.
Override play.api.i18n.DefaultMessagesApiProvider
#Singleton
class CustomMessagesApiProvider #Inject() (
environment: Environment,
config: Configuration,
langs: Langs,
httpConfiguration: HttpConfiguration)
extends DefaultMessagesApiProvider(environment, config, langs, httpConfiguration) {
def filename =
config.get[String]("play.i18n.filename")
override protected def loadAllMessages: Map[String, Map[String, String]] = {
langs.availables.map(_.code).map { lang =>
(lang, loadMessages(filename +"." + lang))
}.toMap
.+("default" -> loadMessages(filename))
.+("default.play" -> loadMessages(filename+".default"))
}
}
Add Guice binding in Module.java
#Override
public void configure() {
bind(DefaultMessagesApiProvider.class).to(CustomMessagesApiProvider.class);
}
It's my first Scala class, so maybe it can be improved. But it works.
To load multiple files (it compiles but not tested)
override protected def loadAllMessages: Map[String, Map[String, String]] = {
langs.availables.map(_.code).map { lang =>
(lang,
loadMessageFiles("." + lang))
}.toMap
.+("default" -> loadMessageFiles(""))
.+("default.play" -> loadMessageFiles(".default"))
}
private def loadMessageFiles(suffix: String) = {
loadMessages("messages-1" + suffix) ++ loadMessages("messages-2" + suffix)
}