I am trying to make a demuxer using Chisel but the code fails to compile and throw this error shown in the imgur link
[1] https://i.stack.imgur.com/oW0Rv.png)
class Demuxer extends Module {
val io = IO(new Bundle {
val datain = Input(UInt(8.W))
val dataout1 = Output(UInt(8.W))
val dataout2 = Output(UInt(8.W))
val dataout3 = Output(UInt(8.W))
val dataout4 = Output(UInt(8.W))
val dataout5 = Output(UInt(8.W))
val selector = Input((UInt(3.W)))
})
when(io.selector === 1.U){
io.dataout1 := io.datain
}.elsewhen(io.selector === 2.U){
io.dataout2 := io.datain
}.elsewhen(io.selector === 3.U){
io.dataout3 := io.datain
}.elsewhen(io.selector === 4.U){
io.dataout4 := io.datain
}.elsewhen(io.selector === 5.U){
io.dataout5 := io.datain
}.otherwise{
}
}
I read the wiki about unconnected element
https://www.chisel-lang.org/chisel3/docs/wiki-deprecated/unconnected-wires.html
If I use use io.outs <> DontCare on my IO, the code compiles but the generated verilog shorts my inputs to all the outputs, which is not the desired behaviour I want from this module. Can any one suggest I fix to this problem?
Thanks in advance
Chisel and the Scala FIRRTL Compiler require that all outputs are driven in all cases. This helps avoid bugs where a designer forgets to drive some port/wire/reg. The issue is that the code needs to set some default value (or use DontCare) for all of the module outputs.
When you set all the outputs to DontCare usually one of two things will happen:
The default connection will be 0.U.
The default connection will be some other legal value or connection.
(2) is what is happening here. When you write io.dataout1 := DontCare, you're indicating to the compiler that it can set this to anything. The compiler is then choosing to set this to io.dataout1 := io.datain (shorting the input to the output).
Instead of using DontCare you can use something explicit, e.g., 0.U will create a mux for each output. Doing this with one line looks like:
Seq(io.dataout1, io.dataout2, io.dataout3, io.dataout4, io.dataout5).foreach(
_ := 0.U
)
Related
I want to Marshal / Unmarshal Golang object (json) with a custom tag.
Like
type Foo struct {
Bar string `json:"test" es:"bar"`
}
data, _ := json.MarshalWithESTag(Foo{"Bar"})
log.Println(string(data)) // -> {"foo":"bar"}
In other words, I whan to use the encoding/json library with a different tag here: https://github.com/golang/go/blob/master/src/encoding/json/encode.go#L1033
Thanks :)
I think the way you wrote your example might have been a bit incorrect?
When I run your code using Marshal() inplace of MarshalWithESTag() I get {"test":"Bar"} not {"foo":"test"} as I think your example would imply.
Here is that code running in the Go Playground to illustrate the output:
package main
import (
"encoding/json"
"fmt"
)
type Foo struct {
Bar string `json:"test" es:"bar"`
}
func main() {
data, _ := json.Marshal(Foo{"Bar"})
fmt.Println(string(data))
}
Assuming I am correct about what you wanted then that would imply what you really wanted was for your output to be {"bar":"Bar"} when you call json.MarshalWithESTag().
Based on that assumption you could accomplish with the following code — which you can see in the Go Playground — after which I will explain the code. (If my assumption was not correct I will address that too):
You cannot add a MarshalWithESTag() method to the the json package because Go does not allow for safe monkey patching. However, you can add a MarshalWithESTag() method to your Foo struct, and this example also shows you how to call it:
func (f Foo) MarshalWithESTag() ([]byte, error) {
data, err := json.Marshal(f)
return data,err
}
func main() {
f := &Foo{"Bar"}
data, _ := f.MarshalWithESTag()
log.Println(string(data)) // -> {"bar":"Bar"}
}
Next you need to add a MarshalJSON() method to your Foo struct. This will get called when you call json.Marshal() and pass an instance of Foo to it.The following is a simple example that hard-codes a return value of {"hello":"goodbye"} so you can see in the playground how adding a MarshalJSON() to Foo affects json.Marshal(Foo{"Bar"}):
func (f Foo) MarshalJSON() ([]byte, error) {
return []byte(`{"hello":"goodbye"}`),nil
}
The output for this will be:
{"hello":"goodbye"}
Inside the MarshalJSON() method we need to produce JSON with the es tags instead of the json tags meaning we will need to generate JSON within the method because Go does not provide us with the JSON; it expects us to generate it. And the easiest way to generate JSON in Go is to use json.Marshal(). However, if we use json.Marshal(f) where f is an instance of Foo that gets passed as the receiver when calling MarshalJson() it will end up in an infinite recursive loop!The solution is to create a new struct type based on and identical to the existing type of Foo, except for its identity. Creating a new type esFoo based on Foo is as easy as:
type esFoo Foo
Since we have esFoo we can now cast our instance of Foo to be of type esFoo to break the association with our custom MarshalJSON(). This works because our method was specific to the type with the identity of Foo and not with the type esFoo. Passing an instance of esFoo to json.Marshal() allows us to use the default JSON marshalling we get from Go.
To illustrate, here you can see an example that uses esFoo and sets its Bar property to "baz" giving us output of {"test":"baz"} (you can also see it run in the Go playground):
type esFoo Foo
func (f Foo) MarshalJSON() ([]byte, error) {
es := esFoo(f)
es.Bar = "baz"
_json,err := json.Marshal(es)
return _json,err
}
The output for this will be:
{"test":"baz"}
Next we process and manipulate the JSON inside MarshalJSON(). This can be done by using json.Unmarshal() to an interface{} variable which we can then use a type assertion to treat the variable as a map.Here is a standalone example unrelated to the prior examples that illustrates this by printing map[maker:Chevrolet model:Corvette year:2021] (Again you can see it work in the Go Playground):
package main
import (
"encoding/json"
"fmt"
)
type Car struct {
Maker string `json:"maker" es:"fabricante"`
Model string `json:"model" es:"modelo"`
Year int `json:"year" es:"año"`
}
var car = Car{
Maker:"Chevrolet",
Model:"Corvette",
Year:2021,
}
func main() {
_json,_ := json.Marshal(car)
var intf interface{}
_ = json.Unmarshal(_json, &intf)
m := intf.(map[string]interface{})
fmt.Printf("%v",m)
}
The output for this will be:
map[maker:Chevrolet model:Corvette year:2021]
Our next challenge is to access the tags. Tags are accessible using Reflection. Go provides reflection functionality in the standard reflect package.
Using our Car struct from above, here is a simple example that illustrates how to use Reflection. It uses the reflect.TypeOf() function to retrieve the type as a value and then introspects that type to retrieve the tags for each field. The code for retrieving each tag is t.Field(i).Tag.Lookup("es"), which is hopefully somewhat self-explanatory (and again, check it out in the Go Playground):
func main() {
t := reflect.TypeOf(car)
for i:=0; i<t.NumField();i++{
tag, _ := t.Field(i).Tag.Lookup("es")
fmt.Printf("%s\n",tag)
}
}
The output for this will be:
fabricante
modelo
año
Now that we have covered all the building blocks we can bring it all together into a working solution. The only addition worth mentioning are the creation of a new map variable _m of the same length as m to allow us to store the values using the es tags:
func (f Foo) MarshalJSON() ([]byte, error) {
es := esFoo(f)
_json,err := json.Marshal(es)
{
if err != nil {
goto end
}
var intf interface{}
err = json.Unmarshal(_json, &intf)
if err != nil {
goto end
}
m := intf.(map[string]interface{})
_m := make(map[string]interface{},len(m))
t := reflect.TypeOf(f)
i := 0
for _,v := range m {
tag, found := t.Field(i).Tag.Lookup("es")
if !found {
continue
}
_m[tag] = v
i++
}
_json,err = json.Marshal(_m)
}
end:
return _json,err
}
However, there is still one detail left undone. With all the above code f.MarshalWithESTag() will generate JSON for the es tags, but so will json.Marshal(f) and we want the latter to return its use of the json tags.
So address that we just need to:
a. Add a local package variable useESTags with an initial value of false,
b. Modify f.MarshalWithESTag() to set useESTags to true before calling json.Marshal(), and then
c. To set useESTags back to false before returning, and
d. Lastly modify MarshalJSON() to only perform the logic required for the es tags if useESTags is set to true:
Which brings us to the final code — with a second property in Foo to provide a better example (and finally, you can of course see here in the Go Playground):
package main
import (
"encoding/json"
"log"
"reflect"
)
type Foo struct {
Foo string `json:"test" es:"bar"`
Bar string `json:"live" es:"baz"`
}
type esFoo Foo
var useESTags = false
func (f Foo) MarshalWithESTag() ([]byte, error) {
useESTags = true
data, err := json.Marshal(f)
useESTags = false
return data,err
}
func (f Foo) MarshalJSON() ([]byte, error) {
es := esFoo(f)
_json,err := json.Marshal(es)
if useESTags {
if err != nil {
goto end
}
var intf interface{}
err = json.Unmarshal(_json, &intf)
if err != nil {
goto end
}
m := intf.(map[string]interface{})
_m := make(map[string]interface{},len(m))
t := reflect.TypeOf(f)
i := 0
for _,v := range m {
tag, found := t.Field(i).Tag.Lookup("es")
if !found {
continue
}
_m[tag] = v
i++
}
_json,err = json.Marshal(_m)
}
end:
return _json,err
}
func main() {
f := &Foo{"Hello","World"}
data, _ := json.Marshal(f)
log.Println(string(data)) // -> {"test":"Hello","live":"World"}
data, _ = f.MarshalWithESTag()
log.Println(string(data)) // -> {"bar":"Hello","baz":"World"}
}
Epilogue
If my assumption was wrong I think I can at least assume this code I provided gives you enough to achieve your objective. You should be able to swap the keys and values in your output if that is actually what you want given the techniques shown. If not, please comment asking for help.
Finally, I would be remiss not to mention that reflection can be slow and that this example uses reflection multiple times per object to achieve your desired output. For many use-cases the time required to process JSON this way won't be significant. However, for many other use-cases the execution time can be a deal-killer. Several commented that you should approach this a different way; if performance matters and/or using a more idiomatic Go approach is important, you might want to seriously consider their recommendations.
We have transaction log files in which each transaction is a single line in JSON format. We often need to take selected parts of the data, perform a single time conversion, and feed results into another system in a specific format. I wrote a Python script that does this as we need, but I hoped that Go would be faster, and would give me a chance to start learning Go. So, I wrote the following:
package main
import "encoding/json"
import "fmt"
import "time"
import "bufio"
import "os"
func main() {
sep := ","
reader := bufio.NewReader(os.Stdin)
for {
data, _ := reader.ReadString('\n')
byt := []byte(data)
var dat map[string]interface{}
if err := json.Unmarshal(byt, &dat); err != nil {
break
}
status := dat["status"].(string)
a_status := dat["a_status"].(string)
method := dat["method"].(string)
path := dat["path"].(string)
element_uid := dat["element_uid"].(string)
time_local := dat["time_local"].(string)
etime, _ := time.Parse("[02/Jan/2006:15:04:05 -0700]", time_local)
fmt.Print(status, sep, a_status, sep, method, sep, path, sep, element_uid, sep, etime.Unix(), "\n")
}
}
That compiles without complaint, but I'm surprised at the lack of performance improvement. To test, I placed 2,000,000 lines of logs into a tmpfs (to ensure that disk I/O would not be a limitation) and compared the two versions of the script. My results:
$ time cat /mnt/ramdisk/logfile | ./stdin_conv > /dev/null
real 0m51.995s
$ time cat /mnt/ramdisk/logfile | ./stdin_conv.py > /dev/null
real 0m52.471s
$ time cat /mnt/ramdisk/logfile > /dev/null
real 0m0.149s
How can this be made faster? I have made some rudimentary efforts. The ffjson project, for example, proposes to create static functions that make reflection unnecessary; however, I have failed so far to get it to work, getting the error:
Error: Go Run Failed for: /tmp/ffjson-inception810284909.go
STDOUT:
STDERR:
/tmp/ffjson-inception810284909.go:9:2: import "json_parse" is a program, not an importable package
:
Besides, wouldn't what I have above be considered statically typed? Possibly not-- I am positively dripping behind the ears where Go is concerned. I have tried selectively disabling different attributes in the Go code to see if one is especially problematic. None have had an appreciable effect on performance. Any suggestions on improving performance, or is this simply a case where compiled languages have no substantial benefit over others?
Try using a type to remove all this unnecessary assignment and type assertion;
type RenameMe struct {
Status string `json:"status"`
Astatus string `json:"a_status"`
Method string `json:"method"`
Path string `json:"path"`
ElementUid string `json:"element_uid"`
TimeLocal time.Time `json:"time_local"`
Etime time.Time // deal with this after the fact
}
data := &RenameMe{}
if err := json.Unmarshal(byt, data); err != nil {
break
}
data.Etime, _ := time.Parse("[02/Jan/2006:15:04:05 -0700]", time_local)
I'm not going to test this to ensure it outperforms your code but I bet it does by a large margin. Give it a try and let me know please.
http://jsoniter.com/ declares itself to be the fastest json parser, golang and java implementations are provided. Two types of api can be used. And pre-injected json object definition is optional.
Check https://github.com/pquerna/ffjson
I saw 3x improvements over the standard json marshal/unmarshal method employed by the standard lib. It does so by rewrite the source and removing the need for reflection.
Reading the source code of math/floor.go, starting from line 13, I read some code like this:
func Floor(x float64) float64
func floor(x float64) float64 {
if x == 0 || IsNaN(x) || IsInf(x, 0) {
return x
}
if x < 0 {
d, fract := Modf(-x)
if fract != 0.0 {
d = d + 1
}
return -d
}
d, _ := Modf(x)
return d
}
It seems the func Floor has no body. I tried to copy and paste these code in my go file. it doesn't compile. The error message is missing function body. So my question is: is a bodiless function legal in Go's syntax? Thanks.
It's the way how functions are implemented in assembly. You find the assembly implementation in the floor_ARCH.s (e.g.: AMD64) files.
To quote the spec:
A function declaration may omit the body. Such a declaration provides the signature for a function implemented outside Go, such as an assembly routine.
In my case I had "../../../pkg/mod/golang.org/x/tools#v0.0.0-20190814235402-ea4142463bf3/go/ssa/interp/testdata/src/fmt/fmt.go:3:6: missing function body" error!
and it was because I used fmt without importing it so my IDE imported the wrong package.
I fixed it by removing the import (golang.org/x/tools/go/ssa/interp/testdata/src/fmt)
and just importing fmt
Im dealing with some code outside of my immediate control, where I need to encode an option[Thing] where the case is as per normal if Thing exists, however the None case must return 'false' rather than null. Can this be accomplished easily? I'm looking at the docs but not having much success.
My code looks like this:
case class Thing(name: String)
case class BiggerThing(stuff: String, thing: Option[Thing])
implict val ThingEncodeJson: EncodeJson[Thing] =
EncodeJson(t => ("name" := t.name ) ->: jEmptyObject)
and the equivalent for BiggerThing, and the json needs to look like:
For a Some:
"thing":{"name": "bob"}
For a None:
"thing": false
but at present the None case gives:
"thing":null
How do I get it to return false? Could someone point me in the right direction please?
Cheers
You just need a custom CodecJson instance for Option[Thing]:
object Example {
import argonaut._, Argonaut._
case class Thing(name: String)
case class BiggerThing(stuff: String, thing: Option[Thing])
implicit val encodeThingOption: CodecJson[Option[Thing]] =
CodecJson(
(thing: Option[Thing]) => thing.map(_.asJson).getOrElse(jFalse),
json =>
// Adopt the easy approach when parsing, that is, if there's no
// `name` property, assume it was `false` and map it to a `None`.
json.get[Thing]("name").map(Some(_)) ||| DecodeResult.ok(None)
)
implicit val encodeThing: CodecJson[Thing] =
casecodec1(Thing.apply, Thing.unapply)("name")
implicit val encodeBiggerThing: CodecJson[BiggerThing] =
casecodec2(BiggerThing.apply, BiggerThing.unapply)("stuff", "thing")
def main(args: Array[String]): Unit = {
val a = BiggerThing("stuff", Some(Thing("name")))
println(a.asJson.nospaces) // {"stuff":"stuff","thing":{"name":"name"}}
val b = BiggerThing("stuff", None)
println(b.asJson.nospaces) // {"stuff":"stuff","thing":false}
}
}
How to encode a BiggerThing without a thing property when thing is None. You need a custom EncodeJson[BiggerThing] instance then:
implicit val decodeBiggerThing: DecodeJson[BiggerThing] =
jdecode2L(BiggerThing.apply)("stuff", "thing")
implicit val encodeBiggerThing: EncodeJson[BiggerThing] =
EncodeJson { biggerThing =>
val thing = biggerThing.thing.map(t => Json("thing" := t))
("stuff" := biggerThing.stuff) ->: thing.getOrElse(jEmptyObject)
}
Haskell's Text.JSON library uses an abstract data type called Result, it's basically their form of Maybe, but instead of Nothing, there's Error String. Anywho, I need to use liftIO to convert a function call returning an IO thing to a Result thing inside of my implementation of JSON.readJSON. I'm new to monad transformers and can't seem to implement liftIO for Result (I keep trying to construct the infinite type, according to ghci).
Any ideas?
Many thanks
EDIT
Sorry it's taken me so long to elaborate! I appreciate your help guys.
readJSON (JSObject obj) = do text <- getVal obj "text"
user <- getVal obj "from_user"
iden <- getVal obj "id_str"
url <- (do if (length.extractURLs) text == 0
then return ""
else return $ head $ extractURLs text)
title <- liftIO (getSiteTitle url)
return $
Tweet
NewsStory {
title = "Twitter",
desc = text,
url = url,
metric = 0,
sourceURL = "twitter.com/" ++ user ++ "/status/" ++ iden
}
So the last line before return uses getSiteTitle to parse a website at that url for its title. However, that function returns a type of IO String and the compiler tells me it wants the it to be Result. Is this impossible?
Thanks again!
EDIT2
I've decided to eliminate the title from my data type and get it later on when inside an IO monad. Thanks for everyone's help! I've certainly learned from this issue.
You can't use IO inside of readJSON (without resorting to unsafePerformIO). liftIO is used when you have a stack of monad transformers with IO at bottom. Perhaps if you give more concrete information of what you are trying to achieve you'll be able to get a more useful answer :)
What you want is impossible. In the json package, readJSON :: JSValue -> Result a. By definition, this is a pure function. Arguably, you could instantiate the result to something with IO inside, but then it would be impossible to fulfill showJSON :: a -> JSValue.
My solution? I'd give your data type a title :: Maybe String and then have a second pass in IO that filled in titles.
You don't say which particular JSON library your are using and there are dozens of them with similar names and namespaces...
Because you want to use IO to get the url you will have to divide your function into two functions, one in the JSON monad and one in the IO monad. Because you cannot "run" the IO monad, you will have to run the JSON monad within IO, here doAll is a further function to combine the two.
You will have to edit it a little to make it match the JSON library you are using - some of the type signatures are not filled out and I don't know what the "run" function and return types of your JSON monad:
-- This one is in the JSON monad...
-- The type sig needs fixing...
readJSON :: JSObject ?? -> GetJSON (String,String,String,String)
readJSON (JSObject obj) = do
text <- getVal obj "text"
user <- getVal obj "from_user"
iden <- getVal obj "id_str"
url <- (do if (length.extractURLs) text == 0
then return ""
else return $ head $ extractURLs text)
return (text,user,iden,url)
-- This one is in IO...
ioStep :: (String,String,String,String) -> IO TweetNewsStory
ioStep (text,user,iden,url) = do
title <- getSiteTitle url
return $ TweetNewsStory {
title = "Twitter",
desc = text,
url = url,
metric = 0,
sourceURL = "twitter.com/" ++ user ++ "/status/" ++ iden
}
-- Type sig needs fixing...
-- The JSON library will provide something similar to
-- runJSON...
--
doAll :: JSObject ?? -> IO TweetNewsStort
doAll jsobj =
let ans = runJSON $ readJSON jsobj in
case ans of
Left err -> error $ err
Right val -> ioStep val