<Vinalon>
Okay, thanks - sorry, I'm still learning about nMigen and I'm not quite clear on how it translates to Verilog. It looks like their clock initialization code looks like this; is that about what would get generated?
<Degi>
(Oh wait that's for the ECP5 what I just wrote, I think for the ICE40 that's different)
<Vinalon>
(then they use 'int_osc' as the clock, e.g. `always @(posedge int_osc) begin`)
<Degi>
Hm m.submodules += Instance("SB_HFOSC", o_CLKHF=<your clock signal>, i_CLKHFEN=1, i_CLKHFPU=1) should give you the clock signal. Then you can make a clockdomain with that signal
<Vinalon>
Cool, thanks! And does that mean I can do the same thing with 'SB_LFOSC' to get an internal low-speed clock?
<Vinalon>
I can play around with that and make a PR if it works if nobody beats me to it
<Vinalon>
Yeah, that's where I've been getting the acronyms from; thanks for the help and information
<ktemkin>
in short: the arguments to Instance() are mostly equivalent to the elements in the verilog instantiation; but names are prefixed to specify the port/param types
<ktemkin>
instance input ports get an "i_" prefix; instance output ports get a "o_" prefix, and instance parameters get a "p_" prefix
<Vinalon>
It does look like the clock divider can only be 1, 2, 4, or 8...should 'p_DIV' still work for that?
<Vinalon>
And I guess the low-speed oscillator should omit that option since it only has one speed
<ktemkin>
yep; provide the same value you'd provide in the Verilog instantiation (which is 0/1/2/3 for dividers of 1/2/4/8, respectively)
<Vinalon>
ah, that makes sense - thanks
<ktemkin>
oh; and looking at the macro definition, you may also want to provide synth attributes
<ktemkin>
which are <same name as in verilog> prefixed with "a_"
<Degi>
The parameter could be p_CLKHF_DIV instead of p_DIV
<ktemkin>
ah, and yep --- looks like the DIV parameter is named ^
<Degi>
Hm though I don't see a definition for the div parameter anywhere besides in the verilog snippet?
<Vinalon>
Oh, okay - that comes from the code snippet at the end of that document
<Vinalon>
so I'd want 'a_CLKHFEN=1', 'a_CLKHFPU=1', 'a_CLKHF=<divider>', and 'p_CLKHF_DIV=<divider>'?
<Degi>
I think you need i_CLKHFEN and i_CLKHFPU
<Degi>
Because they're signal inputs
<ktemkin>
the first three arguments you have are I/O ports
<Vinalon>
okay, those are inputs not attributes? And it actually looks like 'CLKHF' holds the input clock signal?
<ktemkin>
the first two would be "i_", and the last would be "o_", since those are two inputs and an output
<Degi>
Yes they're input signals, you could wire them to a switch and control the oscillator or so
<Degi>
Tbh that seems to be relatively common that the lattice documents are rather sparse and sometimes seem to be missing parameter definitions and possible values entirely. (Digging around in prjtrellis helps sometimes)
<Vinalon>
ooookay, so 'CLKHF' is the equivalent of the 'OSC' output in the ECP5 platform?
<Degi>
Yes
<Vinalon>
Thanks for the patience explaining this to me
<Degi>
np
<daveshah>
The CLKHF_DIV parameter also has to be a string for obscure lattice reasons
<daveshah>
Like ="0b01"
<Vinalon>
oh, thank you!
<Vinalon>
Okay, I think I should be able to write that into the 'vendor/lattice_ice40.py' file and try it with an Upduino, but we'll see what happens :)
<Vinalon>
It looks like I'll go with, `m.submodules += Instance("SB_HFOSC", p_CLKHF_DIV=<divider exponent as a string>, i_CLKHFEN=1, i_CLKHFPU=1, o_CLKHF=[clock Signal object])
<Degi>
Yes
<Degi>
At the end m.d.comb += ClockSignal("sync").eq(clk_i)
<Degi>
I'm not sure but instead of [clock Signal object] using ClockSignal("sync") might work and save you that statement (though it might be less readable, not sure)
<Vinalon>
Cool, thanks. It looks like the ECP5 patch sets the output to a 'clk_i = Signal()' from the previous line, and has that line adding it to the combinatorial logic near the end
<Degi>
Hm it might be necessary. I had weird problems with nmigen throwing an obscure error and using a new signal for the instance output and assigning it to my signal in the comb domain fixed that.
<whitequark>
Degi: Vinalon: the reason ECP5 platform does that is because it does not directly drive the clock domain from the input
<Degi>
Does m.d.comb += a.eq(b) always make a buffer? Or is it only when driving a signal from an instance?
<whitequark>
you could actually rewrite all that logic to use ClockSignal("sync") rather than clk_i, but it's written in a way that makes it easy to copy-and-paste into your own code if you need to do reset synchronization yourself
<Vinalon>
Hey, it seems to work - I just tried it with a 'blink' example I had for an iCE40UP5K breakout board which has a 12MHz oscillator, and it blinks about 4 times as fast with a divider of 0 and at the same speed with a divider of 2^2=4.
<Degi>
Neat
<whitequark>
in case of iCE40, it's actually necessary to use the clock signal twice
<whitequark>
because it drives a "por" domain and a "sync" domain
<Vinalon>
Is that the 'por' one?
<Vinalon>
oh, guess so
<whitequark>
again you could rewrite it to use ClockSignal("sync") instead of clk_i but it's a bit more clear this way
<whitequark>
it's not an nMigen limitation
<whitequark>
Degi: what do you mean by "buffer"?
<Degi>
Like a signal buffer (to increase fanout etc) (is nMigen even responsible for that or does yosys/nextpnr do that?)
<Vinalon>
Okay - I'll write up an issue or PR in a little bit after I test the low-speed oscillator. Thanks again for all the help everyone!
<whitequark>
nMigen works on the level of abstract priority encoders and netlists
<whitequark>
other than allowing you to instantiate primitives it does not do anything related to the physical devices
<whitequark>
that is the job of the rest of the toolchain
<ktemkin>
generically, it's the PAR tool's job to figure out how to fan signals out through the logic
<whitequark>
you do sometimes have to insert fanout buffers explicitly but only for clocks
<Degi>
Hm okay
<_whitenotifier-3>
[nmigen-boards] x44203 opened pull request #54: Connectors and switches - https://git.io/JvMJJ
<Degi>
Ah yes, now it works. Before I sent a pr to m-labs/nmigen-boards which was the wrong repo.
<cr1901_modern>
You may be able to skip adding fanout buffers by running the yosys clkbufmap pass
<_whitenotifier-3>
[nmigen-boards] whitequark commented on pull request #54: Connectors and switches - https://git.io/JvMJn
* cr1901_modern
is looking into this
<Degi>
whitequark: Should I make a new PR where the resources are done using variable IO standards?
<whitequark>
yes, ideally
<Degi>
Okay
<whitequark>
oh, another thing I forgot to mention
<whitequark>
J32 and J33 should not be added as connectors but rather as resources, since they're single-purpose--you can only use the SERDES over those pins
<Degi>
So as a resource where the pins is an array of diff pairs?
<Degi>
(Also I think they can be used for general purpose? I didn't try that yet)