_florent_ changed the topic of #litex to: LiteX FPGA SoC builder and Cores / Github : https://github.com/enjoy-digital, https://github.com/litex-hub / Logs: https://freenode.irclog.whitequark.org/litex
tpb has quit [Remote host closed the connection]
<tpearson-mobile> awordnot: It's more than a little strange -- we have a peripheral that uses a 32 bit data bus
<tpearson-mobile> and I don't want to get into a ton of shift/or operations to "fix" each access
tpb has joined #litex
<tpearson-mobile> I'll try the base class approach, though doesn't Python let you override an internal variable of a base class unlike C?
<tpearson-mobile> *C++?
<awordnot> it does, but looking closer, it seems like CSRStorage/Status will split multi-word variables into bus-sized words, which apparently is 8-bit by default for CSR. Looking into how to set CSR to 32-bit...
<tpearson-mobile> and "You can zpecify 32-bit wide CSRs but you’ll probably run into compatibility issues with other IP librariers that have hard-coded the 8-bit assumption." -- I'm just shaking my head here. If 32-bit access is allowed, those libraries should be considered to have a bug, not force all of LiteX into a funky sparse address layout
<somlo> tpearson-mobile, awordnot: on the litex target build command line, add `--csr-data-width=32` :)
<tpearson-mobile> no modern CPU operates at a byte level for bus access; I'm trying to figure out where in the world that idea came from...
<awordnot> aha, thank you somlo
<tpearson-mobile> any way to force it in the target .py file?
<somlo> python then generates a set of "accessors" in <build-directory>/software/include/generated/csr.h
<tpearson-mobile> somlo: yes, I saw that, but those are dozens of instructions each
<tpearson-mobile> on a 75MHz CPU
<tpearson-mobile> in a heavily used transfer path
<somlo> that either gather (via shift and or operations) the 8-bit values scattered all over the address space, or read 32 bits at a time, depending on the csr-data-width used
<tpearson-mobile> doesn't seem like the best idea :)
<somlo> sometimes you have wider-than-32-bit registers, in which case you still have to shift-and-or, but 32 bits at a time instead of 8 :)
<awordnot> tpearson-mobile: add 'csr_data_width=32' as a parameter to SoCCore.__init__ in your SoC class to set the default
<tpearson-mobile> great, thanks!
<tpb> Title: litex/common.h at master · enjoy-digital/litex · GitHub (at github.com)
<tpearson-mobile> somlo: is there some CPU that LiteX uses that has the capacity for byte read/write?
<somlo> there's various declarations of intent to clean that up (e.g., make 32-bit the default instead of 8, tinker with the endianness of how larger-than-8bit CSRs would be stored, etc.)
<somlo> but for now, that's how it works :)
<tpearson-mobile> because it just seems weird -- only microcontrollers and some legacy (really *really* legacy) CPUs like x86 have that functionality
<tpearson-mobile> OK
<tpearson-mobile> (in fact I don't even know if modern x86 still does byte read or if these days it does a 32 bit or higher read discarding the extra bits behind the scenes
<awordnot> I don't think anything in LiteX does native 8-bit CSR reads. As far as I can see all CSR accesses go through a Wishbone bridge with a 32-bit width
<somlo> the wishobone and axi bus protocols support byte strobes, so an 8-bit access would be a 32 or 64 bit access with all but one bytes strobed out
<tpearson-mobile> OK, so it is just as bad / weird as I thought :)
<tpearson-mobile> oh well
<tpearson-mobile> at least it can be overriden
<tpearson-mobile> *overridden
<somlo> the CSR bus did not historically support a strobe, there's another plan in the works to teach it to deal with strobes, which would probably fix a lot of issues, no idea at what expense in terms of added "gateware"
<awordnot> is there any reason that CSR needs to be its own bus instead of just exposing the registers to wishbone? maybe resource utilization?
<somlo> that's a question for _florent_ (I've mostly tried to get how things work in order to use them, don't have the context for how/why they came to be the way they are)
<awordnot> sure, fair enough
<mithro> @awordnot - Resource usage
<mithro> @awordnot Wide buses which run to lots of peripherals inside the FPGA cost a lot of resources
<awordnot> mithro: hm. But if the CSR data width was set to 32-bit then there wouldn't be that much of a difference?
<tpearson-mobile> I have a couple of additional questions if you all don'd mind.... :)
<tpearson-mobile> How are IRQs handled?
<tpearson-mobile> The peripheral I'm gluing in has an IRQ line that I'd like to tie to a distinct IRQ (don't care which number) on the CPU
<tpearson-mobile> Other question is what is the absolute simplest way to run a small C program from internal ROM?
<tpearson-mobile> benh: On the bootloader console for Microwatt, is the CPU running in BE mode?
<tpearson-mobile> either it's BE or I've got the byte ordering swapped in the 32 bit CSR stuff :)
<awordnot> the microwatt doesn't support BE at all yet afaik
<awordnot> it enters at 0x0 with MSR[LE] set
<tpearson-mobile> hrm, so it seems when I put the CSR into 32 bit mode the bytes are swapped around
<awordnot> how are you reading the register? using the generated wrapper?
<tpearson-mobile> no, "mr <address>"
<awordnot> and the resulting byte dump has the most significant byte first?
<tpearson-mobile> LSB first....actually, brain cramp! :D
<awordnot> heh
<tpearson-mobile> sorry, I got real used to debugging some of the IBM hardware that runs in BE mode
<tpearson-mobile> I think we're good
<awordnot> happens to all of us :)
<tpearson-mobile> rubber duck debugging FTW... ;)
<tpearson-mobile> (most of which is restating the "problem" in a way that makes one actually think for a sec)
<awordnot> as for running custom bare-metal C code, this is a good template: https://github.com/litex-hub/fpga_101/tree/master/lab004/firmware
<tpb> Title: fpga_101/lab004/firmware at master · litex-hub/fpga_101 · GitHub (at github.com)
<tpearson-mobile> thanks
<tpearson-mobile> IRQs then are the only other question
<awordnot> that unfortunately I'm not sure about
<tpearson-mobile> I've heard Microwatt may not have IRQ support, but regardless there has to be a way to at least expose them to the Wishbone bus
<tpearson-mobile> (and on that topic, I've heard there is a potential for the interrupt controller to be XIVE compatible -- that would be really nice)
<tpearson-mobile> benh: ^^
<awordnot> it looks like interrupts are done by using the CSR EventManager: https://github.com/enjoy-digital/litex/blob/master/litex/soc/interconnect/csr_eventmanager.py
<tpb> Title: litex/csr_eventmanager.py at master · enjoy-digital/litex · GitHub (at github.com)
<tpb> Title: litex/uart.py at master · enjoy-digital/litex · GitHub (at github.com)
<tpearson-mobile> awordnot: hrm. if my Verilog module has an IRQ line (it could be either level or edge triggered, I don't care), how would I use that then
<tpearson-mobile> ?
<awordnot> tpearson-mobile: so you'd create an EventManager submodule, then add the appropriate EventSource for the type of triggering you want. Then you just pass the source's .trigger property to your verilog to use
<tpearson-mobile> hmmm, OK. No examples online, right? We're dealing with one unknown already (whether Microwatt even has IRQ support), and without a working example that's adding a second unknown that will make debugging quite "fun" ;)
<awordnot> other than the UART I linked, I can't find any more minimal examples
<awordnot> maybe temporarily switch the soc to something that's known to support interrupts (like VexRiscv) to test?
<tpearson-mobile> I guess for a simple test program that's reasonable (ish), though to be honest I have no idea how RISC-V handles interrupts in the first place. Hence why POWER is the target :)
<tpearson-mobile> (well, it's a lot more than that, the IRQ bit is just the tip of the iceberg -- we're very much set up to handle POWER systems with near-zero experience with RISC-V
<awordnot> I believe litex provides a C abstraction layer for that, which should be sufficient for simple tests without having to actually write risc-v specific code
<futarisIRCcloud> 8-bit CSR stuff is a weird one, but done that was to save on resource usage, sort of makes sense.
<awordnot> but yeah, I see where you're coming from
<tpearson-mobile> oh, that'd be useful
<tpearson-mobile> some kind of IRQ test code?
<tpb> Title: litex/uart.c at master · enjoy-digital/litex · GitHub (at github.com)
<awordnot> that example C project I pasted links against those functions, so you can use them to set up ISRs
<tpearson-mobile> OK
<tpearson-mobile> ...thanks! lots to digest
<awordnot> you're welcome :)
<tpearson-mobile> benh: am I correct in assuming the IRQ status is "not working" for Microwatt"?
<futarisIRCcloud> I suspect so. Best to try to get that IRQ stuff working in Renode first...
<tpearson-mobile> what would be needed to add IRQ support? Is it LiteX-specific or more of a general "the CPU doesn't have support"?
<benh> tpearson-mobile: we have embryonic irq support
<benh> we plan to beef it up asap to support liteeth
<benh> at the moment, level interrupts only, we need to add masking support, the problem is Linux requires on FW to do that on xics
<benh> we need to either add a "native" backend to linux or add a mini-fw layer
<tpearson-mobile> benh: I can probably help with at least the firmware bits
<awordnot> OPAL-microwatt :)
<tpearson-mobile> I've done work with OPAL / skiboot alrady
<tpearson-mobile> yeah
<benh> well, I created OPAL :)
<tpearson-mobile> ah, right :D
<tpearson-mobile> my bad
<benh> it would be easier/faster to put a native backend in linux
<awordnot> for OPAL, BE support would need to be added too, yeah?
<benh> also our interrupt controller isn't in LiteX yet, I plan to work on that too
<benh> awordnot: probably... not hard though
<awordnot> yeah, I'd imagine so
<benh> we have the swappers already for the byte-reverse load stores, we need to add them to the icache
<benh> the problem is the icache has tight timing path and so has the decoder
<tpearson-mobile> benh: OPAL gets us some other things though, right?
<benh> depends...
<tpearson-mobile> IIRC all the power management is through OPAL?
<tpearson-mobile> i.e. power off / reboot etc.?
<tpearson-mobile> I don't know if we want to completely lose the abstraction
<awordnot> don't OPAL power management calls just forward to the BMC though?
<tpearson-mobile> at the moment, but the whole point is that it could change behind OPAL without the kernel caring
<awordnot> yeah true - I'm just not sure how closely coupled the API is to the existing implementation
<tpearson-mobile> regardless, it's a published standard sort of like some of the ACPI calls
<benh> there is no such thing as power management in microwatt today :-)
<tpearson-mobile> I dunno -- benh might know more the risks / benefits of Yet Another Interface vs. just extending OPAL
<benh> oh I don't mind doing a mini-opal or a mini-rtas, been thinking about it
<tpearson-mobile> personally I see too much interface bloat in POWER already
<benh> we would need to add BE support or define a LE variant of OPAL
<benh> bbl
<tpearson-mobile> sure
<tpearson-mobile> we have two separate interrupt controllers, OPAL (PowerNV), the older interface before PowerNV
<tpearson-mobile> I'm not sure adding yet another is good for POWER overall :)
<awordnot> i wonder if it'd be feasible to add an opal no-op backend to linux (i.e. all OPAL calls just forward to regular kernel function calls)
<awordnot> not sure how elegant that would be though :P
<tpearson-mobile> awordnot: well, IIRC OPAL at its core is just a set of functions that can be called by the kernel
<tpearson-mobile> how about just a set of functions in the OPAL table that basically don't do much?
<tpearson-mobile> shouldn't be too hard
<awordnot> i'm not sure about ABI differences and you'd have to disable the endian swap but yeah that's basically what i'm envisioning
<tpearson-mobile> well, ABI can be worked around, does the kernel itself do the endian swap?
<tpearson-mobile> regardless it'd be better to just add BE support to Microwatt since it increases compliance in the first place
<awordnot> i think the kernel itself does the swap, yeah
<tpearson-mobile> yeah, so extending Microwatt to add BE is probably the best option
<awordnot> and I agree, BE support needs to be added one way or another eventually
<tpearson-mobile> benh: when you get back....this nascent support, if all I'm wanting to do is make sure an IRQ I'm asserting from a peripheral has made its way over to Microwatt, is it sufficient (i.e. bare metal test program)?
<benh> tpearson-mobile: there's two interrupt controllers on ppc64 today (there was 3 but I think we took out openpic)
<benh> xics and xive
<benh> there are several interfaces on top of them...
<benh> we currently implement a mini-xics (though it's somewhat incomplete)
<benh> xics in linux supports 2 interfaces: via opal FW or via RTAS FW
<benh> but it would be trivial to add a simple native one to the source controller
<tpearson-mobile> benh: right, and to be honest it's quite a mess right now for not much of a good reason. I don't want to see yet another interface added, since we're starting to go toward RISC-V style "each SoC acts completely different and needs its own special kernel" territory
<benh> (we do native for the interrupt presentation, it's for source control that we go through fw)
<benh> yeah but on the other hand, directly poking at a native ICS is about half a page of code
<benh> we could do a mini-opal or a mini-rtas though ... the latter would require adding 32-bit support though :-) let's not go there
<tpearson-mobile> P10 will use OPAL / XICS right?
<benh> adding BE is not hard provided we can make timing in the icache
<tpearson-mobile> like P9 does?
<benh> provided IBM doesn't kill native linux completely
<benh> openpower doesn't look good at the moment... but I don't have insider info
<benh> P10 is XIVE like P9
<tpearson-mobile> XIVE, OK
<benh> but XIVE is a much much bigger beastm we are nowhere near supporting something like that in mw
<benh> xics is a lot simpler
<tpearson-mobile> makes sense
<benh> but linux doesn't care which one you have, it's orthogonal to the CPU ISA
<tpearson-mobile> right
<tpearson-mobile> I know P9 at least does fall back to XICS somehow
<benh> not really
<benh> the hw is just xive
<tpearson-mobile> ah, OK
<benh> I just hacked a "XICS-like" interface in OPAL on top of XIVE :-)
<tpearson-mobile> gotcha
<benh> bcs it took a long time to get full proper XIVE going, it's ... a beast
<benh> powerful but complex
<tpearson-mobile> yeah, I guess the main point is XICS isn't going *anywhere* in the mainline kernel
<tpearson-mobile> it's kind of the equivalent to the legacy IRQ stuff still in x86
<benh> right, but then getting things in mainline isn't hard either :)
<benh> I think long run supporting opal is the way to go
<tpearson-mobile> yeah, same
<benh> so we can use the powernv platform rather than a custom microwatt platform
<tpearson-mobile> exactly
<benh> that said there are bigger issues at hand and we are massively out of topic for #litex :-)
<tpearson-mobile> that was one of the thinks we liked about OpenPOWER/PowerNV
<tpearson-mobile> ah
<tpearson-mobile> recommended place to continue discussion?
<benh> hint: we don't have an FPU or a vector unit :_)
<benh> openpower slack ?
<benh> and our toolchain more/less requires them...
<tpearson-mobile> yeah, so on that topic...there's something in the works to do a major push to fix that stupidity
<tpearson-mobile> toolchain wise
<benh> ok
<benh> I have to go, sunday & sunny, time to get my a** out of the appartment :)
<tpearson-mobile> basically we all got sloppy with IBM as the only vendor making parts, and it has to be corrected for ... reasons ... not just Raptor desires
<tpearson-mobile> sure
<tpearson-mobile> can we set up a time to chat more?
<tpearson-mobile> I'm CDT here
<tpearson-mobile> so it's basically 9PM
<benh> use slack, we can find times or just leave messages for async rpelies
<tpearson-mobile> OK
<tpearson-mobile> will ping there
<tpearson-mobile> thanks!
<benh> np
tpearson-mobile has quit [Remote host closed the connection]
Degi has quit [Ping timeout: 264 seconds]
Degi has joined #litex
CarlFK has quit [Quit: Leaving.]
HoloIRCUser has joined #litex
HoloIRCUser2 has quit [Ping timeout: 246 seconds]
tcal has quit [Ping timeout: 256 seconds]
tcal has joined #litex
miek has quit [Ping timeout: 246 seconds]
miek has joined #litex
kgugala_ has joined #litex
kgugala has quit [Ping timeout: 260 seconds]
tcal has quit [Remote host closed the connection]
<ronyrus> hi, is there a standard way to implement a sticky bit, clear on read, clear after write, these king of bits/registers in Litex.
<ronyrus> I searched a little but didn't find it.
<futarisIRCcloud> benh: great post on linux-litex mailing list. Hopefully it'll get some discussion going,
<_florent_> Hi, i can understand the concerns about the difficulties to use LiteX for people with a hardware background
<_florent_> Migen and LiteX have been created by people with hardware background (and not the opposite) and some architecture choices were made to improve productivity to create full systems and still allow efficient resource usage.
<_florent_> but' it's indeed possible these choices are making things harder if the hardware designer want to implement things with a different approach, and we still have to improve documentation
<_florent_> But both flows (traditional Verilog/VHDL vs Migen/LiteX) have advantages/drawbacks and Migen/LiteX has been used to create complex systems/cores that we still maintain and have allowed to create cores/systems that would not have been possible with Verilog/VHDL or would have a nightmare to do with traditional tools.
<_florent_> But for hardware people with a clear view/understanding of how they want things to be implemented, if LiteX approach is not close enough, i would recommend using LiteX only for the integration and/or for reusing core it can provide.
<_florent_> I'm personnaly using LiteX for different use cases: create full systems with it (fully in Migen/LiteX), create full systems with part on it full Migen/LiteX and others parts in traditionnal VHDL/Verilog/Vendor IP, create full systems with only VHDL/Verilog cores and where LiteX is only used for integration, or just generate standalone cores (LiteDRAM, LiteEth, LitePCIe) in verilog that will be integrated in a
<_florent_> traditional flow, etc...
<benh> futarisIRCcloud: hopefully .. I haven't heard back yet :-)
<_florent_> So we provide one approach to create SoCs (and we indeed have to improve documentation) but we don't force others to use exact same approach :)
<benh> I'd like to help get Linux upstream support asap :)
<benh> _florent_: it's been super handy to plug in IP blocks into microwatt standalone and I can see the appear for building SoCs, it's great once you get your head around it
<benh> _florent_: I personally find it a bit harder for low level hw design but then I'm not a hw designer so .. :-)
<benh> _florent_: ie, if I want to put together a module with a rather convoluted mix of state machines, combo processes, etc... I think it's just a matter of getting used to it
<_florent_> ronyrus: the CSR don't have sticky bit support, but you have we/re signals indicating the CSR has been accessed so can implement the behaviour in your logic
<benh> _florent_: it would make sense to add write-1-to-clear support
<benh> it's very useful for a number of things where you want atomicity ... for example clearing event bits or interrupt status bits
<ronyrus> _florent_ : thanks :) is there an example of logic that does that so I can take a look?
<benh> mind you, arguably anything requiring performance should be normal MMIOs :-)
<benh> also very useful for error reporting bits
<benh> it avoids the races of doing read-modify-write where you can end up losing a newly set bit
<benh> with W1C (or RC but I prefer W1C) you now you only clear what you've seen and it's race free even in multi-processor environments
<benh> where 2 CPUs might try to collect the same event
<zyp> isn't W1C already fairly trivial to implement?
<_florent_> ronyrus: i will need to write a bit of code, i could do that a bit later
<benh> zyp: it is in verilog/vhdl ... I suppose it's in migen too ;-)
<benh> I was just pointing out that it would be a useful feature to have in the base CSR implementation
<benh> as an option when creating them
<benh> it needs to be careful though that the write-clear by host and update by the logic itself are properly atomic
<zyp> true
<zyp> and I totally agree on the W1C
<ronyrus> _florent_ only if you want to. I just thought that maybe in some project or module there is such a code already, so you would point me there. No need to do it especially for me. :-)
<zyp> ronyrus, something like this? https://paste.jvnv.net/view/Xx8xE
<tpb> Title: JVnV Pastebin View paste – Untitled (at paste.jvnv.net)
<benh> _florent_: LiteEthPhyModel ... it seems to be using source/sink pads.. what does it connect to ?
<benh> ah found it
<benh> litex/build/sim/core/modules/ethernet/ethernet.c
kgugala_ has quit [Read error: Connection reset by peer]
kgugala has joined #litex
<ronyrus> zyp I'm confused, isn't 'we' is strobed when there is a read from the bus?
<zyp> hmm, I might have r and w the wrong way around
<zyp> but the rest should still make sense, right?
<tpb> Title: JVnV Pastebin View paste – Untitled (at paste.jvnv.net)
<ronyrus> I think so
<ronyrus> but I'm fairly new to the FPGA development, so ...
<tpb> Title: LiteDIP: Creating Open-Source IP Blocks For Generic Linux Drivers On FPGAs - Phoronix (at www.phoronix.com)
<tpb> Title: FPGA: Why so few open source drivers for open hardware? - mupuf.org (at mupuf.org)
<futarisIRCcloud> MuPuF: I hope to make good progress on this over my summer vacation, with the target of having a minimal DRM driver working over PCie!
<ronyrus> so, I wrote something that I thought would work, but it doesn't.
<tpb> Title: Context share whatever you see with others in seconds (at ctxt.io)
<ronyrus> Added it to a module that inherits from AutoCSR. The 'status' signal is going up, but 'w' stays 0.
<ronyrus> and 'r' is going up at some point for some reason ... ¯\_(ツ)_/¯
<ronyrus> I'm using liteScope to sample the signals.
<ius> how are offsets supposed to be handled when using litex_server with the crossover uart over pcie?
<ius> litex_server.py maps my PCIe BAR (where 0x0 actually translates to 0x82000000 on the fpga side) but seems to have no builtin way to specify this offset? the latter makes me think i'm not using it right
<ius> all reads (eg. by litex_crossover_uart.py) rely on the physical address obtained from csr.csv, so one would expect the server to be responsible for address translation?
<zyp> ius, doesn't look like either of those have any offset arguments
<zyp> you could alternatively use wishbone-tool, it expects a --register-offset argument
kgugala has quit [Quit: -a- Connection Timed Out]
<_florent_> ius: litex_server is not indeed not doing address translation, we could add it or you would also use wishbone-tool as zyp suggests
kgugala has joined #litex
<ius> right, thanks for confirming - wishbone-tool works indeed (i tried it before, was just confused about the python utils)
<mithro> awordnot: Yes, there is isn't much difference when you make CSR data-width 32bit -- and actually it is somewhat less about resources and more about route-ability of the resources
<mithro> _florent_: I disagree with the premise if LiteDIP -- but I'm open to being proved wrong
<mithro> _florent_: My belief is more about the number of users
<mithro> futarisIRCcloud: did you see the netv2 PCIe driver?
<tpb> Title: HowTo HDMI2PCIe on NeTV2 · timvideos/litex-buildenv Wiki · GitHub (at github.com)
CarlFK has joined #litex
<mithro> _florent_: I moved the LiteX for hardware engineers page to the LiteX wiki - https://github.com/enjoy-digital/litex/wiki/LiteX-for-Hardware-Engineers
<tpb> Title: LiteX for Hardware Engineers · enjoy-digital/litex Wiki · GitHub (at github.com)
<_florent_> mithro: i've not yet been able to read the full article from mupuf.org, i'll do it soon, i was just sharing it since saw it. I think the work we are currently doing with Antmicro/gsomlo/benh is going in the right direction and we just need to continue discussing things.
<_florent_> mithro: thanks for the LiteX for hardware engineers move, some parts will probably need to be re-phrased/partially rewritten and i will look at this. If you want to keep an original version of the document, you should probably also keep it in LiteX-Buildenv.
tpearson-mobile has joined #litex
<tpearson-mobile> anyone know what the license is intended to be on the fpga_101 files?
<tpearson-mobile> Since lab004 seems to contain the canonical non-Linux firmware example, it'd be important to know if it has to be rewritten to be used (irritating) or if the lack of license was an attempt to indicate public domain / CC0
<_florent_> tpearson-mobile: i just added a BSD 2-Clause License with https://github.com/litex-hub/fpga_101/commit/9e48d00cd93d933e6fb6e4d5a0ff144254d08dae
<tpb> Title: add LICENSE. · litex-hub/fpga_101@9e48d00 · GitHub (at github.com)
<tpearson-mobile> thanks!
<tpearson-mobile> much appreciated
<_florent_> mithro: i had a closer look at LiteX-for-Hardware-Engineers, i already read it some time ago but wanted to re-read it. I find it very useful for someone wanting to have a quick overview of LiteX and the tips for a someone with a hardware background, but for me this is more a blog post of bunnie's understanding of LiteX when discovering it in 2018.
Skip has joined #litex
<_florent_> mithro: but there are some issues: it's a bit outdated, some things are inexacts or biased by bunnie's background/dislike of Python, some things are covered by others wiki pages and explained a bit differently, etc...
<tpearson-mobile> yeah, agreed
<_florent_> mithro: i'm also not sure i want to modify it because it would denaturate it and remove the original content
<_florent_> mithro: so i'm probably going to move it in https://github.com/enjoy-digital/litex/wiki/Tutorials-Resources
<tpb> Title: Tutorials Resources · enjoy-digital/litex Wiki · GitHub (at github.com)
<tpearson-mobile> to be honest, the intersection of people that are skilled with Python and are also skilled hardware engineers is very small.
<tpearson-mobile> whether that changes now, we'll have to see
<tpearson-mobile> most hardware folks are used to being very close to the metal in software terms
<tpearson-mobile> Python is about as far away as you can get...
<tpearson-mobile> it's an interesting dicotomy
<tpearson-mobile> *dichotomy
<_florent_> and add a disclaimer that it was a written from Bunnie in 2018 while discovering LiteX, that it can be useful for others people with hardware background, but i would still recommend the others Wiki pages to really learn LiteX and the original reasoning for the concepts.
<tpearson-mobile> _florent_: quick question, for basic tutorial / quick start files is there any reason BSD is used instead of something that wouldn't require special notices in binaries and documentation?
<tpearson-mobile> I ask mainly because it's a bit onerous to require that for the life of a project just to get some Makefile templates. If the idea is making LiteX easy to use, basic templates like that should be under a public domain / CC0 type license IMO
<tpearson-mobile> there's a natural boundary between the gateware and the software already, and it'd be entirely possible to have the gateware under one license and the firmware under another
<_florent_> tpearson-mobile: yes i was also thinking of that while adding the license
<_florent_> tpearson-mobile: but in fpga_101, there are also some content i'd like to be with this license (or that is some reused stuff with this license)
<tpearson-mobile> right, makes sense....it's just that fpga_101 is also a de-facto quick start for firmware (basic templates to get things running)
<_florent_> tpearson-mobile: so the idea is just to make it use the same license used by LiteX and the cores
<tpearson-mobile> any way to split those out? Real world example: as you may know we mostly write GPL code publicly, so we'd probably end up rewriting the Makefile just to make licensing less complex
<tpearson-mobile> that makes using LiteX harder than it needs to be
<mithro> tpearson-mobile: BSD licenses are compatible with GPL code?
<tpearson-mobile> they're compatible, yes, but then you have to get into "this file is this license, that file is that license, this file is a chimera of both licenses, see the Git logs..."
<tpearson-mobile> and for a hour to rewrite a Makefile that's not something we like to do
<tpearson-mobile> yet....it's an hour of making LiteX harder to use
<tpearson-mobile> (hour because the docs are quite bad, and if you can't refer to the example Makefile because it's BSD licensed and you're writing a GPL version...)
<tpearson-mobile> all I'm saying is that adding licenses, even compatible ones, on basic use templates like this is going to make it harder to use LiteX than it needs to be for very little actual gain I can see
<mithro> tpearson-mobile: You can take a permissively licensed file and convert it to GPL licensed by making modifications and only releasing the modifications under a GPL license
<mithro> As long as you continue to have the attribution
<tpearson-mobile> but with two clause BSD you still have to comply with the BSD requirements -- BSD notices in binary and documentation, specifically
<tpearson-mobile> so it becomes a chimera
<mithro> @tpearson-mobile Doesn't GPL have the same notice requirements or am I misremebering? People seem to treat it like it does
<mithro> The GPL has a "Appropriate Legal Notices" section?
<tpearson-mobile> I'd need to double check, but I do seem to remember BSD being a bit more stringent on it to the point of having banners in command line programs
<mithro> tpearson-mobile: Are you GPLv2 or GPLv3
<tpearson-mobile> we tend to do GPLv3/AGPL
<mithro> tpearson-mobile: Releasing under GPL means it will probably never be usable in ASICs
<tpearson-mobile> Right, we had talked about that before, but this is for the *firmware*, which is on the software side :)
<tpb> Title: License compatibility - Wikipedia (at en.wikipedia.org)
<tpearson-mobile> not the gateware
<mithro> I'm only partially paying attention -- working on some other stuff
<tpearson-mobile> sure, no problem
<tpearson-mobile> mithro: I think the type of license we're looking for in regards to HDL simply doesn't exist -- basically, one that if you modify the HDL itself you have to contribute those changes back, but you can create internal functionally-identical derivative works in the process of making an ASIC
<tpearson-mobile> without contributing them back (since then you get into NDA protected stuff at foundries etc.)
<tpearson-mobile> Outside of certain strategic areas (e.g. OpenPOWER / FSI) where it is in our direct interest to allow proprietary implementations of our work, we tend to want people that want to make a proprietary / internal / locked down version of our stuff, instead of contributing back to the open version, to pay for that
<tpearson-mobile> but...probably a bit OT here :)
<tpearson-mobile> _florent_: I'm not entirely sure that the lab004 example is actually BSD compliant -- nowhere in the binary does it actually contain the BSD copyright notice :)
<mithro> tpearson-mobile: My general thinking is that trying to force people to do things doesn't really work -- it's better to create positive incentives so people *want* to contribute back
<mithro> _florent_: Lots of people like that LiteX for Hardware Engineers page -- many hardware engineers feel uncomfortable Python and understanding that people like Bunnie also struggle with it helps them understand
<tpearson-mobile> mithro: I agree on short timescales (years), but I disagree on timescales that are the length of copyright (decades to centuries)
<tpearson-mobile> the "carrot" only works on the shorter timescales in my experience
<mithro> @tpearson-mobile: Plus permissive can always be converted to repocical if needed in the future
<zyp> I prefer BSD licensing my embedded stuff, you don't get any contributions back from the people you turn away by GPL-licensing a project anyway
st-gourichon-fid has quit [Ping timeout: 260 seconds]
<tpearson-mobile> zyp: It's a bit more nuanced I think than that....at least for larger / more valuable works. For little stuff yes, absolutely, we've rewritten small stuff from scratch without even looking at it to avoid license restrictions. For larger projects though where you're starting to talk man-years or more of development, that GPL requirement absolutely
<tpearson-mobile> can make people start to think twice about just copying and using in proprietary stuff vs. contributing at least something back.
<tpearson-mobile> sometimes I've seen it change a new design from 100% proprietary to having a clear boundary inside the design of proprietary vs. GPL, just because it's cheaper to do that than to rewrite the entire thing using internal resources
<tpearson-mobile> anyway, I think without a license-free Makefile example, we need better documentation on key files like software/include/generated/variables.mak
<mithro> tpearson-mobile: I'm guessing you spend lots of time talking to Bradley Kuhn :-P
<_florent_> tpearson-mobile: i don't want to make your life harder, but also don't want to want to make mine harder, BSD-2 is probably a the best fit for most of the work in fpga_101, but please consider there is no restriction on basic things like Makefile, simple firmware, etc...
<tpearson-mobile> mithro: Nah :D
<zyp> tpearson-mobile, also, the BSD license does not require the binary itself to contain the license notice, it's sufficient to put it in the accompanying documentation
<tpearson-mobile> mithro: we've seen both the best in people (/corps) and the worst in people (/corps)
<tpearson-mobile> zyp: yes, though for embedded firmware it's not like there's normally a software help package that goes with it, oftentimes it ends up embedded in some Flash chip on a board and that's it
<tpearson-mobile> granted, we always publish something with those types of products that says "get the source here" but I don't know if that satisfies the BSD requirement.
<tpearson-mobile> _florent_: thanks, that does make it easier :)
<tpearson-mobile> just because there's a lot of "magic variables" in the Makefiles that will send people on a wild goose chase for no good reason if they had to assemble it all on their own
<tpearson-mobile> LiteX-specific magic variables, that is
<mithro> tpearson-mobile / _florent_: Are these the generated files? We could just put a CC0 license at the top of the generated file output? (Generated files are in a strange position in copyright law)?
<tpearson-mobile> mithro: one axiom we've taken away from our experience is that without the ability to enforce a stick against someone, they will eventually turn on you, it's just a matter of time. At some point the carrot you're offering simply won't keep their interest, and if you don't have enforcement ability you're in a bad spot. Note this is mostly just due
<tpearson-mobile> to the (IMO insane) copyright durations in the US -- they're long enough that you could have multiple generations own the copyright to any given work.
<tpearson-mobile> and the last chain in that generational link could easily be an IP holding company that will apply lawyers as needed to get maximum profit for themselves no matter the cost to anyone or anything else ;)
<_florent_> mithro: i agree LiteX for Hardware Engineers page has really interesting value as i was saying, but it does not mean that's the way i would recommend learning LiteX. I also don't want to denaturate it by modifying it, so i just moved it to https://github.com/enjoy-digital/litex/wiki/Tutorials-Resources#litex-for-hardware-engineers with a description/disclaimer and haven't touched the contents
<tpb> Title: Tutorials Resources · enjoy-digital/litex Wiki · GitHub (at github.com)
<tpearson-mobile> mithro: I don't think the main file in question (the Makefile) is autogenerated
<tpearson-mobile> but it was generated by someone that was familiar with the LiteX way of doing thing
<tpearson-mobile> *thinks
<tpearson-mobile> *things
tcal has joined #litex
<tpearson-mobile> there's also a little bit of code in main.c that, while useful, isn't worth dealing with licensing over -- there's tons of public domain examples of how to do things like string scans
<_florent_> mithro: no sure the generated files should be CC0: i still like to have a BSD-2 license on a LiteDRAM/LitePCIe standalone generated core
<mithro> _florent_: I hope the wiki will have more contributors than just you?
<tpearson-mobile> _florent_: You could always mark the couple of little files that we're talking about here as public domain / CC0 in the headers --that would remove any question :)
<mithro> Can use SPDX identifiers -- https://spdx.org/licenses/
<tpb> Title: SPDX License List | Software Package Data Exchange (SPDX) (at spdx.org)
<tpearson-mobile> yeah
<tpearson-mobile> that same relicense then allows those to be used in other works (Wikis, etc.) more easily
<tpearson-mobile> e.g. if we were to put out some documentation on how to use LiteX for things
<somlo> _florent_: this: https://pastebin.com/txWRww0U fixes it for me on rocket+litex
<tpb> Title: [Diff] diff --git a/litex/soc/software/liblitesdcard/spisdcard.c b/litex/soc/software/l - Pastebin.com (at pastebin.com)
<tpearson-mobile> I completely agree on keeping the more complex stuff under a proper license, it's just these building blocks that are really only useful to accelerate someone else's brand new design that I'm having a bit of a license quibble over
<somlo> not asking to apply it yet :)
<somlo> but apparently .data and .rodata end up being classified as .rodata (and writes to it are ignored)
<somlo> making it all go in .bss apparently leaves global variables still writable
<tpearson-mobile> (and where by nature there's no boundary to clearly mark where one project starts and another ends -- Makefiles have to be part of the resultant firmware sources, for instance)
<somlo> still investigating (we should be able to use initialized globals in .data and have them stay r/w, anything else is insanity)
<somlo> but at least I'm likely to be barking up the right tree, so to speak
<awordnot> somlo: wow that's a very weird bug
<somlo> tell me about it, it's been driving me up the wall for the better part of last week :)
<_florent_> mithro: there are already others direct contribution than mine in the wiki (from somlo for example), but i'd just like to get my change to describe how i see the project, it's taking time because i'm busy with others thins but it's slowly getting there. Once we have this base it will be easier to have others contributors.
<somlo> _florent_: I wonder if somehow soc/software/bios/linker.ld holds the answer -- my intuition says that's where I need to look next...
<somlo> hmmm... `INCLUDE generated/output_format.ld`, `INCLUDE generated/regions.ld` ...
<somlo> the latter (regions.ld) looks fine...
<somlo> oooh... in linker.ld, we have both .rodata and .data go in `> rom`, only .bss goes in `> sram`
<somlo> that might explain a thing or two
<mithro> _florent_: You mean s/change/chance/ right?
<somlo> let me try and rebuild with a small edit to linker.ld, see what happens
<somlo> _florent_: what are the implications of explicitly mapping .data into sram (instead of rom)? I'm no ld ninja, so I have to ask if it's likely the memtest might stomp all over initialized .data values in sram during self-test :)
<somlo> but really, .data *belongs* in sram, as it's supposed to be modifiable by the program!
<somlo> nvm, I'm being dumb -- memtest stomps all over DRAM, not sram ! :D
<zyp> somlo, does .data have different LMA and VMA?
<tpearson-mobile> does that work for you?
<tpb> Title: Relicense FSI master/slave as BSD 3-clause in addition to AGPL v3 (7b0ac449) · Commits · Raptor Engineering Public Development / lpc-spi-bridge-fpga · GitLab (at gitlab.raptorengineering.com)
<somlo> zyp: we're talking about the litex bios here, so it's all physical addresses at this point
<zyp> that's not relevant to my question
<somlo> ok, then I misunderstood your acronyms
<zyp> on a MCU with flash, it's typical to put .data's LMA in flash and VMA in ram, since the initial contents will be located in flash and copied to ram during startup
<mithro> tpearson-mobile: Should do
<tpearson-mobile> great!
<zyp> when you have .data going into rom, it sounds like you have a linker script written for such a platform
<tpb> Title: litex/linker.ld at master · enjoy-digital/litex · GitHub (at github.com)
<tpb> Title: litex/linker.ld at master · enjoy-digital/litex · GitHub (at github.com)
<somlo> that's wrong, IMHO
<zyp> yeah, that's wrong
<tpearson-mobile> mithro: there's a few other strategic OpenPOWER-related areas where I can probably get things relicensed if you need, so if you're interested in other files in that repo let me know
<somlo> should be "> sram", just like bss
<zyp> agreed
<somlo> building now to test, will send PR shortly :)
<somlo> presuming it works, which I think it should
<daveshah> I think just putting it in SRAM will break XIP platforms?
<daveshah> that would need some explicit copy-to-RAM step
<daveshah> unless they use a different linker script
<zyp> daveshah, which are you thinking of?
<somlo> daveshah: not familiar with XIP, but having .data that is really .rodata is a recipe for people wasting north of a week thinking they're losing their damn mind :D
<daveshah> I think some people are using LiteX with the BIOS executing from SPI flash
<daveshah> e.g. icebreaker
<daveshah> oh yeah it definitely needs to be fixed
<zyp> as long as we're talking about code that gets embedded in the bitstream to initialize the ram blocks, you can place it straight into ram unless you need reset capability
<zyp> if you need to be able to reset, you need a copy of the initial data as well
<somlo> but if you're executing from SPI flash, you should make sure there is no .data section
<zyp> https://cgit.jvnv.net/laks/tree/ld_scripts/arm_flash_ram.ld#n72 <- which in a linker script would look something like this
<tpb> Title: arm_flash_ram.ld\ld_scripts - laks - Microcontroller support library. (at cgit.jvnv.net)
<somlo> s/no .data section/nothing in the .data section/
<zyp> somlo, the .data section exists for a reason
<zyp> you'll want to handle it properly, not pretend it doesn't exist :)
<somlo> zyp: right, but if you know you're running stuff from rom, you also know you can't use it
<zyp> like I said, on a normal mcu with XIP flash, you put an initial copy in flash, and copy it to ram during startup
<somlo> and like I said, I'm no ld ninja, so if "running from rom" really means implicitly copying stuff into some memory that becomes available later on, then I'm out of my depth
<somlo> so anyway, I'll send in my PR, and y'all feel free to make me do revisions if it's wrong :)
<zyp> I don't have time right now, but I can take a look tomorrow
<zyp> I assume the startup code already has a part that zero-fills .bss?
<zyp> copying .data from flash to ram goes right next to that
tpearson-mobile has quit [Remote host closed the connection]
<somlo> ok, so then that would be an *additional* patch for XIP platforms, orthogonal to placing .data in sram in linker.ld
<zyp> I wouldn't call it orthogonal
<zyp> you'll want something like «> sram AT > rom» in the linker script, along with enough symbols for the startup code to know where to find the data and where to put it
<zyp> instead of a plain «> sram»
<somlo> now that I think about it, plain "> sram" probably won't even work, since the startup code won't be there to populate it anyway
<zyp> unless it's prepopulated in the initial blockram contents
<zyp> but either way it won't be after a soft reset
<zyp> which cpu are you working on?
<somlo> rocket (64-bit)
<zyp> hmm, I'm getting lost in the repos, where did crt0.S go?
<somlo> litex/soc/cores/cpu/rocket/crt0.S
<somlo> there's a bss_init loop
<somlo> there isn't a "populate data" code block :)
<zyp> right
<somlo> so I am starting to comprehend what you're saying, it will be there after pushing the bitstream, but won't get reset to the proper initial values on a soft reset
<zyp> yes
<somlo> so really I need two versions of .data, one in rom (to use as a source for memcpy-ing to the second one, in ram)
<zyp> so you should probably treat everything like a mcu with xip flash, both for .data and .bss initialization
<zyp> https://cgit.jvnv.net/laks/tree/startup/entry.cpp#n20 <- here's how I do it (along with the linker script I linked earlier)
<tpb> Title: entry.cpp\startup - laks - Microcontroller support library. (at cgit.jvnv.net)
<somlo> and somehow expressing this stuff with the appropriate magic incantation in the .ld file, and adding the block of code to do the memcpy on reset
<somlo> and probably on all CPUs, not just rocket, because it's wrong everywhere right now, even if on some targets it might happen to work by "accident" :)
<mithro> somlo: The XIP verse copy to ram options should be cleaned up
<somlo> I'll file an RFC PR and start the conversation, but I'm not equipped to handle a cross-ISA overhaul of everything :)
<zyp> https://paste.jvnv.net/view/M8Sow <- here's a newer version of that linker script, LOADADDR() makes everything clearer
<tpb> Title: JVnV Pastebin View paste – Untitled (at paste.jvnv.net)
<zyp> personally I prefer doing as little as possible in assembly to keep it portable, but that relies on the compiler not attempting to access .data or .bss
<zyp> before it has initialized them
<zyp> I wrote this for cortex-m, but I've ran it on vexriscv as well :)
<somlo> anyway, my dirty-hack attempt at `s/> rom/> sram/` didn't work, the bios hangs after printing the LiteX logo; so I filed issue https://github.com/enjoy-digital/litex/issues/566
<tpb> Title: bios: `.data` section placed in rom, wrongly ends up acting like `.rodata` · Issue #566 · enjoy-digital/litex · GitHub (at github.com)
<zyp> somlo, can you try this? https://paste.jvnv.net/view/tQGMs
<tpb> Title: JVnV Pastebin View paste – Untitled (at paste.jvnv.net)
<mithro> At some point I would like to write up my theories about how you should use the CSR objects
<mithro> daveshah: Yes, on the ice40 boards and the spartan 6 lx9 boards the BIOS is stored on SPI flash and XIP rather than inside a ROM
<zyp> hmm
<mithro> somlo / zyp: See above too
<zyp> mithro, just looked at #145
<mithro> They don't have enough block RAM to waste it on the ROM
<zyp> the picorv32/crt0 looks wrong too
<mithro> zyp: I think we definitely need to add testing for this
<zyp> it assumes .data is located right after .rodata, which the current linker script doesn't guarantee in any form
<zyp> and either way, it doesn't really matter whether the BIOS is using XIP SPI flash or block ram configured as a rom, .data can't be located in either since it needs to be writable
<zyp> the only case in which .data doesn't need to be copied by crt0 is when it's already loaded to ram prior to execution, which would be the case if there's either a loader before this, or if it's using block ram that's initialized by the fpga bitstream itself
<zyp> but in the latter case, the block ram contents would be modified the first time it runs and therefore potentially invalid after a cpu reset without reloading the fpga
<somlo> zyp: building now with your suggested patch, let's see what happens...
<zyp> I also haven't looked at the code that is initializing the block ram, but I'd bet that it currently only initializes the rom block, which is why simply changing to «> sram» didn't work at all
<zyp> in other words, I'd argue that the #ifdef EXECUTE_IN_PLACE conditional is unnecessary, and that .data should _always_ be copied
HoloIRCUser has quit [Quit: HoloIRCUser]
<zyp> because there's only the special case of a cpu that doesn't need to support reset that doesn't need it to be copied, and that case is currently not supported either way
<zyp> I guess the only reason it haven't been a bigger problem before is simply because there isn't a lot of code in the BIOS and most of it doesn't write to .data at all
<somlo> not too many globals, and if any, they're probably .bss not .data
<zyp> yeah, or they might be in .data but only read
<somlo> which is why this was such a WTF... whaddaya mean, I'm writing to the damn thing, and it stays unchanged :)
<zyp> fixing and testing every crt0 sounds fun :p
<somlo> CPUs (ISAs) should each have a maintainer :)
<somlo> zyp: that still hangs after the LiteX ascii-art logo and "BIOS built on <timestamp>"
<zyp> oh, hmm
<zyp> can I have a copy of the elf and the csr.csv?
<futarisIRCcloud> mithro: Yep. I've seen the HDMI2PCIe driver.
<zyp> hmm, at a glance the elf seems to have sane section headers
<zyp> do you have debugger access to it when it's running? you could set a breakpoint on main and check whether there's matching content at 0x10008600 and 0x11000000
<somlo> zyp: no debugger, but I could add some print statements right around where the logo is being printed, presumably before .data is ever accessed...
<mithro> somlo: Does Rocket have JTAG at all?
<mithro> somlo: It would be pretty easy to do something like wishbone-tool does for VexRSICV
<somlo> it probably does, but I'd have to invest a few hours in getting to the bottom of all that :)
<zyp> this could probably be tested just as well on vexriscv
<mithro> somlo: Recommend putting it on the todo list near the top
<zyp> except the copying loop would have to be 32-bit instead :)
<zyp> somlo, how big is your bios.bin?
<futarisIRCcloud> https://groupgets.com/manufacturers/getlab/products/kimchi-micro - OSHW i.MX8M based board with a mPCIe slot.
<tpb> Title: kimχ micro by GetLab | GroupGets (at groupgets.com)
<somlo> 35k according to `ls`
<zyp> 35080?
<somlo> nvm, that was bios.bin; bios.elf is 381920 bytes
<zyp> I asked about bios.bin :)
<somlo> oh
<somlo> 35084
<zyp> okay, that sounds sane
<zyp> judging by the elf, there's 35080 bytes of stuff to go in the .bin, the last 4 is probably just for alignment or something
<somlo> weird, 35080 divides evenly by 8, 35084 doesn't :)
<somlo> unless the .bin has 4 bytes worth of some kind of magic file header or something
<zyp> shouldn't
<somlo> interesting, right after the last line that prints, there's a call to `crcbios();`...
<somlo> hmmm...
<zyp> ah
<zyp> we probably broke something it assumes :)
<somlo> that, or crcbios actually uses one or more global variables :)
<somlo> looking...
<tpb> Title: litex/helpers.c at master · enjoy-digital/litex · GitHub (at github.com)
<zyp> yeah, already found it
<zyp> and yes, we did
<zyp> it's trying to do a crc over everything from _ftext to _edata and _edata is now in a different memory region :)
<zyp> maybe it's not hanging, just busy calculating the crc
<somlo> well, I could just comment out the call to crcbios for now
<somlo> rather than worry about fixing it for the purpose of this test
<zyp> hmm, it's only 16 megabytes between the regions, more likely it's stuck than slow
<zyp> probably faults once it runs past the end of the rom region
<somlo> I'm rebuilding with it commented out, should have a verdict in 20-ish minutes or so
<mithro> somlo: We should get bios patching working -- https://github.com/SymbiFlow/prjxray-bram-patch
<tpb> Title: GitHub - SymbiFlow/prjxray-bram-patch: Tool for updating the contents of BlockRAMs found in Xilinx 7 series bitstreams. (at github.com)
<somlo> if it works, it's worth figuring out how to fix it
<zyp> yeah
<zyp> I can look more at this tomorrow, should have been in bed an hour ago :)
<somlo> _florent_ showed me a way to have lxterm push just the bios.bin to a board without rebuilding the whole gateware
<somlo> didn't work for me right off the bat, so I'd have to invest another hour or two getting to the bottom of *that* :)
<zyp> anyway, I guess crcbios() is easy to fix
<zyp> currently it's going off _edata, which is end of .data VMA
<zyp> changing that to LMA is probably all there's to it
<zyp> could add a new symbol or do (_rdata + _edata - _fdata)
<zyp> oh, and the extra four bytes you've got is the CRC checksum :)
<somlo> heh
<somlo> zyp: looking at linker.ld, there's an `_erodata` symbol, but then there's a `.commmands` section which I'm unfamiliar with, inbetween .rodata and .data
<zyp> I assume the .commands is some magic to build an array of commands for the bios shell
<zyp> you can consider it another .rodata section
<somlo> so add an `_ecmds = .;` and s/_edata/_ecmds/ in the expected_crc value?
<zyp> no
<somlo> figures :)
<zyp> you want end of .data LMA
<zyp> which IIRC is easiest to get by doing LOADADDR() + LENGTH()
<zyp> or maybe it was SIZE()
<zyp> something like that :)
<somlo> LENGTH() of what?
<zyp> anyway, I'll go to bed now and then I'll check the backlog tomorrow to see how your test went, and then I'll update my patch to also fix the crcbios()
<somlo> ok, sounds good
<zyp> night :)
<somlo> back at you, and thanks!
Skip has quit [Remote host closed the connection]