<_whitenotifier-f>
[nmigen-boards] benx45h synchronize pull request #113: Added support for the Cyclone IV de0_nano board - https://git.io/JUBIJ
<_whitenotifier-f>
[nmigen-boards] benx45h synchronize pull request #113: Added support for the Cyclone IV de0_nano board - https://git.io/JUBIJ
Degi has quit [Ping timeout: 246 seconds]
Degi has joined #nmigen
futarisIRCcloud has joined #nmigen
peepsalot has quit [Read error: Connection reset by peer]
peepsalot has joined #nmigen
electronic_eel has quit [Ping timeout: 256 seconds]
electronic_eel has joined #nmigen
PyroPeter_ has joined #nmigen
PyroPeter has quit [Ping timeout: 256 seconds]
PyroPeter_ is now known as PyroPeter
FFY00 has quit [Ping timeout: 260 seconds]
FFY00 has joined #nmigen
emeb_mac has quit [Quit: Leaving.]
jjeanthom has joined #nmigen
chipmuenk has joined #nmigen
futarisIRCcloud has quit [Quit: Connection closed for inactivity]
peepsalot has quit [Read error: Connection reset by peer]
peepsalot has joined #nmigen
m4ssi has joined #nmigen
jjeanthom has quit [Ping timeout: 256 seconds]
Shari2 has joined #nmigen
electronic_eel has quit [Ping timeout: 246 seconds]
electronic_eel has joined #nmigen
chipmuenk has quit [Quit: chipmuenk]
chipmuenk has joined #nmigen
just_another_dev has joined #nmigen
<just_another_dev>
Hi there, I recently discovered nmigen and I've been trying to implement all the components described in nandgame.com in nmigen. Basically I want to implement a simple cpu starting from just nand gates. To do this in nmigen I tried creating a Nand Elaboratable class with the elaborate function containing the single statement "m.d.comb +=
<just_another_dev>
self.c.eq(~(self.a & self.b))". Trying to simulate this sample truth table test inputs throws out a "ValueError: Domain 'sync' is not present in simulation" error message. So, I was wondering if I was doing something wrong or if there's a better way to simulate a Nand Gate...? PS. Sorry for the wall of text.
<agg>
when you run the simulation, you might be missing `sim.add_clock(1e-9)` or similar
<agg>
it should be something like: `nand = Nand(); def testbench(): yield nand.a.eq(1); yield nand.b.eq(0); assert (yield nand.c) == 1;; sim = Simulator(nand); sim.add_clock(1e-9); sim.add_sync_process(testbench); sim.run();`
<just_another_dev>
Hi agg, thanks for replying... Yeah, I followed the tutorial Counter example and have added the "sim.add_clock(1e-6)" statement.
<agg>
(to be clear, the ;; is the end of that function, it's not valid python)
<agg>
you need some sort of register/synchronous element to run a simulation, you could add one to your testbench instead
<agg>
something like: m = Module(); nand = m.submodules.nand = Nand(); c = Signal(); m.d.sync += c.eq(nand.c);`
<agg>
then in your testbench, you can have a plain `yield` to advance one clock cycle, and check the value of `c` (or possibly just nand.c anyway...)
<agg>
(presumably your elaborate method also creates a Module and returns it, by the way?)
<just_another_dev>
Yes, I'm returning the module object in the elaborate method...
<just_another_dev>
Got it... So, If I understood correctly, I'll need to create another Elaboratable subclasss (called maybe NandRunner). Then I'll need to add Nand as a submodule inside its elaborate method as shown in your example, right?
<vup>
(if you only have combinatorial logic you can't add a clock, as the design has no clock and furthermore can't add a synchronous simulation process, as you again have to clock that would clock the synchronous logic)
<vup>
*again have no clock
<just_another_dev>
Thanks vup, yeah that look good too... I was using add_sync_process, didn't know about add_process. Thanks a lot vup. :)
<vup>
oh and of course you could just do `sim.run()` instead of the `sim.run_until(...)`, I just forgot to replace that :)
<d1b2>
<OmniTechnoMancer> I don't think nmigen will be happy about you trying to describe a latch as nand gates though
<d1b2>
<dub_dub_11> noo
<d1b2>
<OmniTechnoMancer> since technically a latch is not described that way and only works due to the physical realisation of those nand gates
emeb has joined #nmigen
<just_another_dev>
@d1b2 Yeah, I guessed using nmigen's inbuilt constructs would be more efficient.... I just wanted to do this using nand's for educational purposes.... I might switch over to the inbuilt constructs for the later parts after I get the logic and arithmetic modules working... But yeah, thanks for the heads up... (y)
sakirious has joined #nmigen
m4ssi has quit [Remote host closed the connection]
chipmuenk has quit [Quit: chipmuenk]
just_another_dev has quit [Remote host closed the connection]
<d1b2>
<dub_dub_11> hacking basic Virtex 5 support into the Spartan3/6 tools was very easy
<whitequark>
which tools?
<d1b2>
<dub_dub_11> into vendor.xilinx_spartan_3_6
<whitequark>
ohh
<whitequark>
the naming would get pretty unwieldy, heh
<d1b2>
<dub_dub_11> Yess it would lol
<d1b2>
<dub_dub_11> but I tried using the generated verilog+constraint file on my ML505 that I wrote a platform file for and didn't brick it so that's a win
<d1b2>
<dub_dub_11> now I should actually use the STARTUP_VIRTEX5 primitive like the spartan6 one does
Shari2 has quit [Remote host closed the connection]
<d1b2>
<dub_dub_11> the primitives look basically identical, I heard that the virtex 5 was the ancestor of the later families so that makes sense
<d1b2>
<dub_dub_11> also I'm a moron who cannot use the right branch in git to save my life 😓
<d1b2>
<dub_dub_11> I'm not really sure how to tell if the startup primitive is... doing anything
<d1b2>
<dub_dub_11> at least, in comparison to just using the nmigen resetSynchroniser
jjeanthom has quit [Ping timeout: 256 seconds]
d1b2 has quit [Remote host closed the connection]
d1b2 has joined #nmigen
<d1b2>
<dub_dub_11> it seems to be using the startup primitive, and it's using the eos output to enable the global clock buffer which looks right to me
<whitequark>
sgtm
<d1b2>
<dub_dub_11> not sure about naming scheme 😄
<whitequark>
maybe mwk can offer some ideas? surely there's some kind of internal "generation" thing we can use instead
<d1b2>
<dub_dub_11> it does look like what's existing could quite simply be extended for basically everything supported by ISE, with considerations for the different types of startups as that appears to be the only difference
<mwk>
whitequark: ?
<mwk>
you mean, better FPGA codenames than "Virtex 5"?
<whitequark>
mwk: we need a file for spartan 3, spartan 6, and virttex 5
<mwk>
sorry, no; the naming is actually surprisingly reasonable for a vendor
<mwk>
just call it xilinx_ise
<whitequark>
uhh
<whitequark>
what happens when there's an open-source toolchain for s6?
<mwk>
then call it xilinx_whatever
<whitequark>
...
<mwk>
also, you know
<d1b2>
<dub_dub_11> the current class name was XilinxSpartan3Or6Platform
<mwk>
if my thing ever gets published, it won't just support s6
<mwk>
xilinx *really* hasn't changed all that much between Virtex 2 and ultrascale
<d1b2>
<dub_dub_11> so it seems like xilinx_ise would be a better name than xilinx_spartan_3_6
<whitequark>
that... won't fly
<mwk>
I mean, I could tell you that Virtex 5 is actually internally called Rainier, and Virtex 6 is Blanc, and Spartan 6 is St. Andrews
<mwk>
but it doesn't really help, does it
<whitequark>
no, i'm looking for basically a way to group all pre-7-series chips
<d1b2>
<dub_dub_11> yeah
<mwk>
why pre-series-7?
<d1b2>
<dub_dub_11> oh ofc cause they are all named by family not toolchain
<d1b2>
<dub_dub_11> vivado doesn't support pre-7 series
<mwk>
then you're grouping by toolchain
<d1b2>
<dub_dub_11> that is how it is currently organised
<whitequark>
i'm not, 7series and ultrascale are separate
<mwk>
then separate it all, and have stuff inherit from older generations / from common base?
<whitequark>
determining the exact way to slice vendor.* modules is a massive PITA
<whitequark>
mwk: that's kinda even worse
<whitequark>
the reason there are so many individual files with lots of copy/paste is that it is obviously unrealistic to expect everyone making changes to any xilinx platform to be able to test on *all* of them
<whitequark>
(or "any newer platform" rather than "all")
<mwk>
tbh I'd rather have one platform class, where you give a chip name and tool selection and it has all required conditionals
<whitequark>
i very specifically decided against that early on
<whitequark>
because it just means everyone will add a fix for their particular xilinx series while probably breaking the rest of them in a subtle way
<whitequark>
no. screw that. duplication is great because it makes code more resilient through redundancy
<mwk>
*shrug* then you're just attempting completely arbitrary split according to what stuff people happen to submit patches for, and my input is completely irrelevant
<whitequark>
it's not completely arbitrary though
<mwk>
if you want to merge virtex 5 with spartan 3 but not with series 7? yes, it is
<whitequark>
hmm
<whitequark>
which IO primitives does virtex 5 use?
<mwk>
IO?
<mwk>
which ones?
<mwk>
IO buffers are the same as, well, all xilinx parts
<mwk>
DDR are IDDR, ODDR [same as 7series]
<whitequark>
there are three different IO buffers already supported by nmigen
<whitequark>
so i don't understand why you say "all xilinx parts"...
<whitequark>
IDDR, IDDR2, IDDRE1
<mwk>
oh, these are not IO buffers, they're DDR registers
<d1b2>
<dub_dub_11> I should have datasheet here
<whitequark>
right, i usually think of those as a part of the IOB
<mwk>
xilinx calls that part "IOI"
<whitequark>
what's the second I for?
<mwk>
the tile where there are I/O FFs, DDR FFs, or serdes primitives
<mwk>
io interface, I think
<mwk>
IOB is just bare buffer
<whitequark>
okay, makes sense
<mwk>
... and this very much matters on bitstream level, IOBs are really kind of separated from the grid on some families
<whitequark>
so basically right now i segregate by the IOI, and this *also* happens to segregate things by toolchain
<whitequark>
but only coincidentally
<mwk>
yes
<mwk>
btw the "spartan 3" part is misnamed
<mwk>
actual spartan 3 uses IDDR/ODDR; IDDR2/ODDR2 is used on spartan 3e, 3a, 3adsp, 6
<whitequark>
*facepalm*
<whitequark>
okay
<d1b2>
<dub_dub_11> hmm
<mwk>
so
<d1b2>
<dub_dub_11> then actual Spartan 3 and Virtex 5 should probably be in their own file
<mwk>
I'm reasonably sure I could sit down for a few hours and come up with a platform class that supports *every* xilinx FPGA starting from, say, first Virtex
<mwk>
I already know way too much about strange I/O primitives
<whitequark>
this wouldn't be how we do things currently, but then again, how we do things currently is clearly unable to properly support xilinx
<whitequark>
so i'm open to considering vendor.xilinx
<whitequark>
or should it be called vendor.amd now? :D
<d1b2>
<dub_dub_11> 😄
<mwk>
I did pretty much decide to go that way with `synth_xilinx`
<whitequark>
completely serious question btw
<mwk>
just pass a -family option and it handles everything from OG Virtex to ultrascale+
<d1b2>
<dub_dub_11> I mean given that there is vendor.intel
<whitequark>
yes
<daveshah>
Well, vendor.intel exists because Altera actually rebranded
<mwk>
sure it's a *bit* misnamed given that it doesn't (and cannot) support xilinx CPLDs or very old FPGAs, but eh, it supports a big supermajority of xilinx stuff
<daveshah>
I'm not sure if Xilinx are going to rebrand so quickly
<d1b2>
<dub_dub_11> true, xilinx haven't... yet
<whitequark>
ok, that's fair
<mwk>
whitequark: anyway, if you think a unified platform is reasonable, I can do the work sometime later this week
<mwk>
(and you can assign bugs to me)
<whitequark>
mwk: i think that if someone can pull off an unified xilinx platform, it is probably you
<whitequark>
so let's try that, it is unlikely to work worse in the long term than the current approach
<mwk>
okay
<whitequark>
and seems to have the potential to work better
<d1b2>
<dub_dub_11> I feel bad, my naive statement of "that worked better than I thought" has resulted in a lot of work 😐
<mwk>
FYI I do consider it the proper way to deal with xilinx in yosys, nextpnr, and bitstream emitter
<mwk>
for everything from at least virtex 2, and maybe even OG virtex
<whitequark>
yes, that's also a good argument for making it work that way in nmigen
<whitequark>
rules are made to be broken, as they say...
<whitequark>
so let's break ours for this
<d1b2>
<dub_dub_11> think I just was fortunate enough to not run into issues with IDDR2 primitives