whitequark[cis] changed the topic of #amaranth-lang to: Amaranth hardware definition language · weekly meetings: Amaranth each Mon 1700 UTC, Amaranth SoC each Fri 1700 UTC · code https://github.com/amaranth-lang · logs https://libera.irclog.whitequark.org/amaranth-lang · Matrix #amaranth-lang:matrix.org
notgull has quit [Ping timeout: 260 seconds]
notgull has joined #amaranth-lang
jwise0[m] has quit [Quit: Idle timeout reached: 172800s]
lf has quit [Ping timeout: 240 seconds]
lf has joined #amaranth-lang
Wanda[cis] has quit [Quit: Idle timeout reached: 172800s]
jn_ has quit [Ping timeout: 248 seconds]
jn has joined #amaranth-lang
jn has joined #amaranth-lang
Degi_ has joined #amaranth-lang
Degi has quit [Ping timeout: 258 seconds]
Degi_ is now known as Degi
ravenslofty[m] has quit [Quit: Idle timeout reached: 172800s]
<_whitenotifier> [amaranth-boards] maispy commented on pull request #235: Limited Documentation Update - https://github.com/amaranth-lang/amaranth-boards/pull/235#issuecomment-1793785722
RobTaylor[m] has quit [Quit: Idle timeout reached: 172800s]
jfng[m] has quit [Quit: Idle timeout reached: 172800s]
lofty has quit [Quit: ZNC - https://znc.in]
lofty has joined #amaranth-lang
iposthuman[m] has quit [Quit: Idle timeout reached: 172800s]
jjsuperpower has joined #amaranth-lang
iposthuman[m] has joined #amaranth-lang
<iposthuman[m]> Hi, I'm porting Bruno's Femto cpu and I looking at converting his funct3 one-hot approach to Amaranth. I think it would convert from ```wire [7:0] funct3Is = 8'b00000001 << instr[14:12];``` to:
<iposthuman[m]> Would this be correct?
<iposthuman[m]> Just noticed I think I'm missing the initial value for the encoder
<iposthuman[m]> More like this?:
<iposthuman[m]> funct3Is = Encoder()
<iposthuman[m]> funct3Is.i(Signal(8),funct3.shift_left(instr[12:15]))
<iposthuman[m]> # One-hot version
Wanda[cis] has joined #amaranth-lang
<Wanda[cis]> Encoder does the opposite, though
<Wanda[cis]> it converts one-hot to binary
<Wanda[cis]> <iposthuman[m]> "Hi, I'm porting Bruno's Femto..." <- that can be translated as just `funct3Is = 1 << instr[12:15]`
<galibert[m]> Isn't that usually called multiplexer/demultiplexer?
<Wanda[cis]> galibert[m]: no?
<Wanda[cis]> <iposthuman[m]> " # One-hot version..." <- > <@_discord_272536403496402945:catircservices.org> ```... (full message at <https://catircservices.org/_matrix/media/v3/download/catircservices.org/eBjapUSyvmoKRhBRtPCxUEKu>)
<iposthuman[m]> Sorry, the verilog is from Bruno Levy's Femto RISC-V processor intermissum variant.
<galibert[m]> looks like the other way around is often called "priority encoder"
<iposthuman[m]> Later in the code it is used as:
<iposthuman[m]> Isn't this onehot usage?
<iposthuman[m]> So I thought this was an equivalent:
<iposthuman[m]> funct3Is.i(Signal(8, reset=0b00000001).shift_left(funct3.value))
<iposthuman[m]> Then I would use it as:
<galibert[m]> why so complex?
<iposthuman[m]> Not really trying to be complex as much as I'm still learning Amaranth 😉
<galibert[m]> Also, given it's all comb, I don't think doing the one-hot in the middle is supposed to matter in the first place
<galibert[m]> In the sense that the synth is not going to see a difference between one-hotting and selecting on it and a switch
<Wanda[cis]> that sounds like someone really likes outsmarting the optimizer
<Wanda[cis]> this generally doesn't end well
<iposthuman[m]> I'm just learning Amaranth and saw the encoder and thought that was an appropriate way, not really trying to out smart anthing other than myself 🙂
<Wanda[cis]> once again, encoder is for going one-hot -> binary
<Wanda[cis]> you want to go binary -> one-hot here
<Wanda[cis]> which is a much simpler operation
<galibert[m]> add all the self. and whatever that are needed :-)
<galibert[m]> The optimizer can be way dumber than your optimizations are ;-)
<iposthuman[m]> Wanda, so your suggestion ```funct3Is = 1 << instr[12:15]``` is "better" approach?
<iposthuman[m]> Perhaps I'll study the encoder more to see what I'm missing.
<galibert[m]> Also, think a little about what the code means. You get a 3-bit selector, then you expand it to a one-hot selector, then you use each bit of the one-hot as a mask, then or all the results to turn that into a selector
<galibert[m]> that's a fucklot of code for a simple 8-way selector, and more amusingly the synth is going to take all that pile, reduce it to the final boolean expressions, and along to way will have dropped all those subtleties
<iposthuman[m]> galibert, your saying the verilog code is good usage but my Amaranth approach is wacky?
<iposthuman[m]> So your "Switch" example will not produce higher LUT usage as was the intention of the verilog code?
<galibert[m]> I'm saying the verilog code is wacky, extremely dependent on a specific version of a specific toolchain, and way more complex than it should
<galibert[m]> and on another version or another toolchain, if you're lucky it just won't have any impact compared to the simple natural version
<iposthuman[m]> Interesting.
<iposthuman[m]> Curious, then what is the purpose of the Encoder/Decorder if you say you would do something less complex. Are the encoder's not really used?
<galibert[m]> It entirely depends on what you're using it for
<galibert[m]> pretty much, where it comes to combinatorial expressions, it's the readability for you that's the most important.
<galibert[m]> anything you do will go through the wringer when tackled by the synth
<iposthuman[m]> In my case I was just trying to be more Amaranth idiomatic.
<galibert[m]> problem is, the verilog was not idiomatic in the first place
<galibert[m]> but it's very much "say what you mean". You have a selection between n cases? That a m.Switch(), easy
<iposthuman[m]> What about the case of being more target agnostic. Wouldn't using Amaranth's features provide for a better "future"?
<galibert[m]> easy to write, easy to read, easy to test
<iposthuman[m]> Agreed.
<iposthuman[m]> So I'll go with ```funct3Is = 1 << instr[12:15]``` as an assumption that Amaranth will understand from later usage that it could reduce LUTs by using one-hot. 🤔
<galibert[m]> Hey Wanda, possible Catherine too but she doesn't seem around, ever saw a 16-bit-ish cpu, word-addressable, probably not dsp, probably 24-bits address space, where fdxx xxxx is jsr and ff42 is rts, and where memory accesses seem to go through some kind of ports rather than having normal addressing modes?
<galibert[m]> Oh, little-endian too
<galibert[m]> s/possible/possibly/
<Wanda[cis]> word-addressable?
<Wanda[cis]> as in, byte is 16 bits or something?
<galibert[m]> yes
<galibert[m]> address 0 is the first word, address 1 the second, etc
<tpw_rules> who does that that's not a dsp
<Wanda[cis]> weird
<Wanda[cis]> nothing comes to mind
<galibert[m]> A weird glob cpu used in an atrociously bad handheld
<Wanda[cis]> I'm curious about "some kind of ports"
<galibert[m]> I'm re-ing the cpu from the binary but it's not trivial
<galibert[m]> this is 100% guesses
<galibert[m]> the address is (1c):(02), 1c, 02 and the registers being 16 bits and the address 24
RobTaylor[m] has joined #amaranth-lang
<RobTaylor[m]> Sounds a bit c28x ish
<galibert[m]> Oh, another kink: all opcodes have bit 15 set
<RobTaylor[m]> But fd is sbrk iirc on c28x
<RobTaylor[m]> galibert: any hits on origin?
<RobTaylor[m]> s/hits/hints/
<galibert[m]> What's origin?
<RobTaylor[m]> What country the chip was from
<galibert[m]> og.kervella.org/S29GL032M90TFIR4.U4 for the rom, the current state or the disassembler is in top-of-tree of mame
<RobTaylor[m]> galibert: mid/late 90s?
<galibert[m]> 2007
<galibert[m]> the pcb is a little too smt for mid/late 90s :-)
<RobTaylor[m]> Still feels very ti dsp. Maybe one of One’s with a display controller, c6000 or c5000 series
<galibert[m]> Ah, never heard of those, will check
<RobTaylor[m]> Good luck!
<RobTaylor[m]> Tms320c55x5
skipwich has quit [Ping timeout: 240 seconds]
<RobTaylor[m]> Just to make things complicated, there’s also OMAP1, which had both arm and a c6000 series dsp, but that would have been too expensive I think in 2007 for a kids toy
<galibert[m]> No traces of arm in the code
skipwich has joined #amaranth-lang
<galibert[m]> That was promising but c5x instructions are 1-4 bytes wide, and c6x are 32-bits wide
<RobTaylor[m]> Hmm so 16 bits data bus, word addresses and fixed 16 bit instruction width?
<galibert[m]> Not entirely fixed, jsr/jmp is 32 bits
<galibert[m]> only ones I've encountered at this point (the bit 15 always set makes things quite obvious)
<RobTaylor[m]> Sounds like something custom :(
<galibert[m]> possibly so yeah
<galibert[m]> oh well, I'll just have to keep going on with the RE