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 · play https://amaranth-lang.org/play/ · code https://github.com/amaranth-lang · logs https://libera.catirclogs.org/amaranth-lang · Matrix #amaranth-lang:matrix.org
<whitequark[cis]> how do you handle power on reset?
<conventia[m]> I started with https://github.com/bl0x/learn-fpga-amaranth so I'm not entirely sure how it handles power on reset.
<whitequark[cis]> can you post your complete (non-minimized) code?
<conventia[m]> It seems like yosys doesn't infer memories for the registers or the memory when defined using amaranth `Array`, so when I ran out of space with step 15, I figured I'd try to use `Memory` explicitly. Unfortunately, that's the step that adds support for load instructions so it's likely that the timing is off.
<whitequark[cis]> Amaranth is designed to avoid the error prone "inference" step for memories
<whitequark[cis]> if you want a memory, use the lib.Memory class
<whitequark[cis]> * the lib.memory.Memory class
<conventia[m]> I thought I did use that. I was just pointing out that the original code didn't and it wasn't inferred. (I prefer this design decision.)
<whitequark[cis]> oh, I misunderstood then
<whitequark[cis]> and yeah, reading your code I see you using the Memory class
<conventia[m]> I mean, I prefer that Amaranth uses explicit objects rather than inference. 🙂
<whitequark[cis]> okay, now that i'm at my desk, let's take a look
<whitequark[cis]> I'm a bit confused, you say you have a problem on icebreaker, but the platform (in blink.py) is arty a7?
<conventia[m]> I'm running it using `board/icebreaker.py` which I added in the last commit.
<whitequark[cis]> okay, i see
<whitequark[cis]> i've checked your code and it seems that you're just using the default sync clock domain as defined by the platform code, which is good: iCE40 FPGAs have a silicon bug which affects BRAMs and the platform code contains a workaround for it
<conventia[m]> It didn't support icebreaker before, but with Amaranth, that's trivial.
<whitequark[cis]> from a cursory look at the code you wrote, i don't see anything that stands out to me as obviously wrong
<whitequark[cis]> oh, i notice you've commented this line: https://github.com/ahmedcharles/learn-fpga-amaranth/blob/tmp/15_load/memory.py#L71
<whitequark[cis]> depending on how the CPU is designed, it might break it
<conventia[m]> I suspect that it's reading when the memory isn't enabled or something.
<whitequark[cis]> what do you mean by "the memory isn't enabled"?
<whitequark[cis]> oh wait
<conventia[m]> Oh, I tested without that commented out. That was just a "try it and see" change.
<whitequark[cis]> ok, so this module isn't really written the way it should be https://github.com/ahmedcharles/learn-fpga-amaranth/blob/4084affd5d0490988aacdd105686945cf0e388c1/lib/clockworks.py
<whitequark[cis]> try adding some logic that asserts ResetSignal("slow") for, let's say, 1000 cycles after startup
<whitequark[cis]> actually I think just doing m.d.comb += ResetSignal("slow").eq(ResetSignal("sync"))
<whitequark[cis]> would be enough
<conventia[m]> It's possible that I uploaded the wrong code. Sorry. I thought I had removed the Clockworks class from this.
<conventia[m]> But I'll try that.
<whitequark[cis]> here's the code in amaranth that works around the ice40 silicon errata: https://github.com/amaranth-lang/amaranth/blob/main/amaranth/vendor/_siliconblue.py#L350-L427
<conventia[m]> Thanks.
<conventia[m]> My plan was to add Memory to each step individually and see which one starts failing and then debug that. It's probably still useful to do that.
<ydnatag[m]> One question regarding hw limitations and erratas, I'm having some troubles with ecp5 reset. I've read that ecp5 cant implement sync reset but yosis can synthesize async reset for the register. Is that right? I haven't tested that yet but i'ce seen that the default reset for missing domains for ecp5 is done by the globar reset and generating the domain as reset less
<ydnatag[m]> With the current reset, i'm having issues with some validated cores i designed, they dont use any hw specific resource, i think it is only because of the reset values of the registers (for example, the tx of a uart core keeps in 0 until i send a byte, then it behaves as expected)
<whitequark[cis]> "I've read that ecp5 cant implement sync reset but yosis can synthesize async reset for the register. Is that right?" i don't think this is right
<whitequark[cis]> you can implement sync reset if the only thing you have is a plain DFF by adding a mux in front of the D input
<whitequark[cis]> so it doesn't really matter whether the hardware supports it or not (I don't remember the ECP5 FF capabilities offhand, but it also doesn't matter)
<whitequark[cis]> there isn't any very strong reason to use the SGSR primitive over an explicit reset on ECP5, this is just what the people working on ECP5 have told me at the time
<whitequark[cis]> without seeing the core I can't comment further, but also you could always add your own "sync" domain reset in whichever way you think would be most appropriate for your design
<ydnatag[m]> <whitequark[cis]> "there isn't any very strong..." <- I tried to create a top level not using "create_missing_domain", but it does not work as expected (i can't remember the behaviour in hw). And with the domain created by the platform i had the issue that init values were ignored. I will try again on Monday and confirm (or not, maybe i'm completly wrong xD) what I'm saying
<whitequark[cis]> were you using nextpnr-ecp5 or diamond?
<ydnatag[m]> Nextpnr
<ydnatag[m]> Yowasp yosys and nextpnr :)
<whitequark[cis]> that's pretty odd, yeah
<whitequark[cis]> if you can make a small reproducer demonstrating that init values are ignored (really this would be down to lighting a single LED with an undriven flop...) then that would go a long way towards fixing this
<ydnatag[m]> Sure! Will do!
<ydnatag[m]> One thing with the current created domain is that, it has a reset, but i cant acces to the reset signal because it is created as reset less, so i cant propagate the reset signal to other domains. I think that it is not an issue because i think sgsr is the global reset but it breaks many othee cores i have that access to the parent reset and adds more logic to the local reset, something like:
<ydnatag[m]> ResetSignal('local').eq(ResetSignal('sync') | other_signal)
<whitequark[cis]> oh, yeah, this is actually a good point
<whitequark[cis]> I think it might be worth it to alter the Lattice create_missing_domain method to use a normal domain reset instead of SGSR
<whitequark[cis]> I think no other platform works the same way even
<ydnatag[m]> I will try it with the current project I'm working. I'll let you know if i have any update
<whitequark[cis]> thanks!
Raito_Bezarius has quit [Changing host]
Raito_Bezarius has joined #amaranth-lang
<conventia[m]> Just a note, that's the wrong commit, I removed that code such that it should use the normal sync domain. https://github.com/ahmedcharles/learn-fpga-amaranth/blob/tmp/15_load/soc.py
duskwuff[m] has joined #amaranth-lang
<duskwuff[m]> Doesn't that (i.e. sync reset with a fabric signal) cause routing / fanout issues in large designs? Or is this not a serious issue on ECP5?
<whitequark[cis]> it's the same as for clocks: global routing is used for high fanout signals
Degi has quit [Ping timeout: 244 seconds]
Degi has joined #amaranth-lang
anubis has quit [Ping timeout: 248 seconds]
<galibert[m]> Do you people know of a way to compute 2**x with x in [0, 1[ ? 12 bits for x, 1.12 for the result
<zyp[m]> if your x is effectively y/4096 where y is an integer, you could theoretically precalculate k=21/4096 with sufficient resolution and then just do ky
<zyp[m]> * if your x is effectively y/4096 where y is an integer, you could theoretically precalculate k=2**1/4096 with sufficient resolution and then just do k**y
<zyp[m]> since a**(b/c) == (a**(1/b)**c
<zyp[m]> s//`/, s/b/c/, s/c/b`/
<zyp[m]> * since a**(b/c) == (a**(1/c))**b
<ydnatag[m]> Maybe I'm wrong, but I think it can be resolved using cordic.
<tpw_rules> yes that's what cordic is for but it might be unnecessary for this particular case. depends how big k is i suppose
<galibert[m]> I think you'd lose precision way too fast
<galibert[m]> x is 0.10 (not 12, sorry) so yeah y/1024
<galibert[m]> anyway, I found a different solution I think :-)
urja has quit [Ping timeout: 245 seconds]
urja has joined #amaranth-lang
Guest96 has joined #amaranth-lang
Guest96 has quit [Client Quit]