ChanServ changed the topic of #nmigen to: nMigen hardware description language · code at https://github.com/nmigen · logs at https://freenode.irclog.whitequark.org/nmigen · IRC meetings each Monday at 1800 UTC · next meeting TBD
lf has quit [Ping timeout: 260 seconds]
lf has joined #nmigen
emeb_mac has joined #nmigen
zeroing has quit [K-Lined]
<_whitenotifier> [YoWASP/yosys] whitequark pushed 1 commit to develop [+0/-0/±1] https://git.io/JtBJ5
<_whitenotifier> [YoWASP/yosys] whitequark 2d10832 - Update dependencies.
<pftbest> whitequark: hi, is there some way to force nmigen to emit error when connecting signals of different width? so it doesn't silently truncate data?
richbridger has joined #nmigen
<vup> pftbest: this is the current state of that afaik: https://github.com/nmigen/nmigen/issues/360
<pftbest> doesn't look like much. i think this behavior is causing real bugs, so it would be good to lint against
<pftbest> for example chisel and spinal check for this
<vup> well there are arguments for and against such a check, which is why it will become a lint
<vup> its just that the custom linter framework / api needs to be worked out first
esden has quit [Ping timeout: 260 seconds]
esden has joined #nmigen
pftbest has quit [Remote host closed the connection]
pftbest has joined #nmigen
pftbest has quit [Ping timeout: 240 seconds]
<d1b2> <DX-MON> oh, sorry nickoe, only just saw you ping.. I was writing a softcore CPU for an old project of mine called OPLSniffer (I have a need to sniff stuff from between the OPL and its DAC as I want to write a C++ impl of the OPL capable of being used in tracked music rendering such as needed for correctly playing back S3M files, which can't be figured out with VGM replays as that's not how it works in S3M unfortunately)
revolve has quit [Read error: Connection reset by peer]
<d1b2> <DX-MON> target is the Xilinx Spartan 6 XC6SLX9 and so I was writing a very low resource using CPU (PIC16) softcore to target my needs to get FIFO buffered packets out from the OPL to my network where I can then capture them on my desktop to analyse based on poking the OPL and also having Scream Tracker run on my W95/DOS box and analysing what it does with the OPL "samples" of a song
revolve has joined #nmigen
Degi_ has joined #nmigen
proteusguy has quit [Ping timeout: 264 seconds]
Degi has quit [Ping timeout: 264 seconds]
Degi_ is now known as Degi
electronic_eel_ has joined #nmigen
electronic_eel has quit [Ping timeout: 240 seconds]
proteusguy has joined #nmigen
sakirious0 has quit [Read error: Connection reset by peer]
sakirious02 has joined #nmigen
electronic_eel_ has quit [Ping timeout: 240 seconds]
electronic_eel has joined #nmigen
PyroPeter_ has joined #nmigen
PyroPeter has quit [Ping timeout: 264 seconds]
PyroPeter_ is now known as PyroPeter
electronic_eel has quit [Ping timeout: 264 seconds]
electronic_eel has joined #nmigen
Bertl is now known as Bertl_zZ
emeb_mac has quit [Quit: Leaving.]
bvernoux has joined #nmigen
revolve has quit [Read error: Connection reset by peer]
revolve has joined #nmigen
bvernoux has quit [Ping timeout: 265 seconds]
pftbest has joined #nmigen
jjeanthom has joined #nmigen
chipmuenk has joined #nmigen
pftbest has quit [Remote host closed the connection]
pftbest has joined #nmigen
jjeanthom has quit [Ping timeout: 256 seconds]
jjeanthom has joined #nmigen
revolve has quit [Read error: Connection reset by peer]
revolve has joined #nmigen
<nickoe> DX-MON Ok, so you are implementing all the PIC instructions such that you can use the same fw?
chipmuenk1 has joined #nmigen
chipmuenk has quit [Ping timeout: 260 seconds]
chipmuenk1 is now known as chipmuenk
jjeanthom has quit [Remote host closed the connection]
jjeanthom has joined #nmigen
jjeanthom has quit [Ping timeout: 240 seconds]
jeanthom has joined #nmigen
chipmuenk has quit [Ping timeout: 240 seconds]
chipmuenk has joined #nmigen
carlomaragno has quit [Ping timeout: 272 seconds]
miek has quit [Ping timeout: 272 seconds]
carlomaragno has joined #nmigen
miek has joined #nmigen
bvernoux has joined #nmigen
chipmuenk1 has joined #nmigen
chipmuenk has quit [Ping timeout: 258 seconds]
chipmuenk1 is now known as chipmuenk
<_whitenotifier> [nmigen-boards] whitequark commented on pull request #138: ecpix-5: ddr3: Add missing address pin. - https://git.io/JtBwH
Bertl_zZ is now known as Bertl
<_whitenotifier> [nmigen-boards] pftbest synchronize pull request #138: ecpix-5: ddr3: Add missing address pin. - https://git.io/Jt4gD
<_whitenotifier> [nmigen-boards] pftbest opened pull request #139: ecpix-5: ddr3: Add missing SLEWRATE="FAST" attribute - https://git.io/JtBKi
<_whitenotifier> [nmigen-boards] pftbest opened pull request #140: ecpix-5: ddr3: Adjust IO_TYPE attribute to match VCCIO which is 1.5v … - https://git.io/JtBKS
<_whitenotifier> [nmigen-boards] whitequark closed pull request #139: ecpix-5: ddr3: Add missing SLEWRATE="FAST" attribute - https://git.io/JtBKi
<_whitenotifier> [nmigen/nmigen-boards] whitequark pushed 1 commit to master [+0/-0/±1] https://git.io/JtB6e
<_whitenotifier> [nmigen/nmigen-boards] pftbest 30c6d0c - ecpix-5: ddr3: Add missing SLEWRATE="FAST" attribute
<_whitenotifier> [nmigen-boards] whitequark closed pull request #138: ecpix-5: ddr3: Add missing address pin. - https://git.io/Jt4gD
<_whitenotifier> [nmigen/nmigen-boards] whitequark pushed 1 commit to master [+0/-0/±1] https://git.io/JtB6v
<_whitenotifier> [nmigen/nmigen-boards] pftbest 4d860fb - ecpix-5: ddr3: Add missing address pin.
<_whitenotifier> [nmigen-boards] whitequark commented on pull request #140: ecpix-5: ddr3: Adjust IO_TYPE attribute to match VCCIO which is 1.5v … - https://git.io/JtB6L
<_whitenotifier> [nmigen-boards] pftbest synchronize pull request #140: ecpix-5: ddr3: Adjust IO_TYPE attribute to match VCCIO which is 1.5v … - https://git.io/JtBKS
<_whitenotifier> [nmigen-boards] pftbest commented on pull request #140: ecpix-5: ddr3: Adjust IO_TYPE attribute to match VCCIO which is 1.5v … - https://git.io/JtB6Y
<_whitenotifier> [nmigen-boards] whitequark closed pull request #140: ecpix-5: ddr3: Adjust IO_TYPE attribute to match VCCIO which is 1.5v … - https://git.io/JtBKS
<_whitenotifier> [nmigen/nmigen-boards] whitequark pushed 1 commit to master [+0/-0/±1] https://git.io/JtB64
<_whitenotifier> [nmigen/nmigen-boards] pftbest a35d870 - ecpix-5: ddr3: Adjust IO_TYPE attribute to match VCCIO which is 1.5v for this board.
<_whitenotifier> [nmigen-boards] whitequark commented on pull request #140: ecpix-5: ddr3: Adjust IO_TYPE attribute to match VCCIO which is 1.5v … - https://git.io/JtB6B
emeb_mac has joined #nmigen
pftbest has quit [Remote host closed the connection]
pftbest has joined #nmigen
revolve has quit [Read error: Connection reset by peer]
revolve has joined #nmigen
<DX-MON> nickoe: I am implementing a PIC so I have a smol firmware-able element I can then use to move data from the sniffer core to my network and deal with networky things
<DX-MON> only way I could think of not to utterly break the BRAM budget
pftbest_ has joined #nmigen
Raito_Bezarius has joined #nmigen
pftbest has quit [Ping timeout: 272 seconds]
<nickoe> DX-MON: Ok, I am not exactly sure I understand your setup exactly, but that is jus fine, I probably have nothing valuable to contribute about it anyways :D
<DX-MON> you say that and yet I keep stumbling in nMigen and simulation details so :P
<DX-MON> I'm designing for the XC6SLX9 in TQFP144 package.. it's a very smol FPGA
<DX-MON> otherwise I'd have done something like use a RISC-V core
<DX-MON> but I'm using the need to do very small and very efficient as a way to force me to really learn nMigen
<nickoe> DX-MON: yeah, well, I am just trying to learn nmigen, and have no previous experince with migen soo
<DX-MON> ah, you might find my stream from yesterday interesting then
<DX-MON> b/c I go from a blank file to most of a semi-functional processor in ~6h
<nickoe> But I had to patch symbiflow-arch-defs and nmigen to be able to use the symbiflow toolchaing for the artix7 with nmigen.
<nickoe> DX-MON: I was sorta watching it a bit, but meh, I think it is better I just try to get my own stuff to work. Right now trying to figure out how to do a little soc with litex, but I guess I need to use the migen compatability "layer" when using nmigen.
<nickoe> But I wonder why I can't see to find a simple example of this -- maybe I just get distrated whenever I open the correct doc :S
<nickoe> I have a bays3 board.
<nickoe> But I am still trying to lears the tools
<whitequark> this is kinda why i made boneless
<whitequark> i really need to get into a state where it's ready for downstream use
<nickoe> whitequark: What is boneless? I guess something without wishbone?
<whitequark> no
<whitequark> CPU architecture for control plane
<nickoe> whitequark: I know I poked you before, but did you see my pull request to update the symbiflow support? https://github.com/nmigen/nmigen/pull/584
pftbest_ has quit [Remote host closed the connection]
pftbest has joined #nmigen
<_whitenotifier> [nmigen] whitequark closed pull request #584: Fixup symbiflow toolchain for xilinx 7series - https://git.io/JtWqJ
<_whitenotifier> [nmigen/nmigen] whitequark pushed 1 commit to master [+0/-0/±1] https://git.io/JtByI
<_whitenotifier> [nmigen/nmigen] nickoe 746886c - vendor.xilinx_7series: fix tool names for symbiflow.
<_whitenotifier> [nmigen] whitequark commented on pull request #584: Fixup symbiflow toolchain for xilinx 7series - https://git.io/JtByL
<_whitenotifier> [nmigen/nmigen] github-actions[bot] pushed 1 commit to gh-pages [+0/-0/±13] https://git.io/JtByY
<_whitenotifier> [nmigen/nmigen] whitequark 8ffe7cc - Deploying to gh-pages from @ 746886ca8ac3b9a8941b540a347452805acbbcf2 🚀
<nickoe> thanks
<nickoe> whitequark: Why does boneless-cpu have to license files, it is dual licensed or?
pftbest has quit [Ping timeout: 240 seconds]
<whitequark> it is dual-licensed because of a historical artifact
<whitequark> Apache 2 includes a patent grant
<whitequark> probably doesn't matter for boneless
<nickoe> ok
<nickoe> Is there an example with nmigen to pop any cpu and a firmware on project and hook up some register to some IO pins?
ronyrus_ has quit [Quit: %me%]
ronyrus has joined #nmigen
pftbest has joined #nmigen
pftbest has quit [Remote host closed the connection]
pftbest has joined #nmigen
pftbest_ has joined #nmigen
pftbest has quit [Ping timeout: 240 seconds]
<awygle> i kind of want to use boneless as a control plane cpu but i am also drawn by the plug-and-play nature of a riscv cpu, can just write c (or maybe rust soon?)
chipmuenk has quit [Quit: chipmuenk]
<nickoe> there is also the picosoc
<nickoe> at least it had a demo on symbiflow-examples that did run on my board.
<d1b2> <DX-MON> well, my almost fully working ~9h to write PIC16 runs at 100MHz on this poor FPGA and uses 4 16-bit BRAM's for the program ROM, and consumes just 170 DFF's and 244 lUTs
<d1b2> <DX-MON> I'm pretty darn happy with that
<d1b2> <DX-MON> (it's actually a touch smaller than that.. I need to re-synth with the sniffer core disabled)
<d1b2> <DX-MON> *LUTs
Bertl is now known as Bertl_oO
<whitequark> DX-MON: 4-LUT?
<d1b2> <DX-MON> mix of 4- and 6-
<d1b2> <DX-MON> seeing the FPGA has both and I'm not specifying any constraints
<whitequark> yeah that's actually better than boneless
<whitequark> i think (for a fair comparison you'd need to restrict it to 4-luts)
<whitequark> but... then you have to program a PIC
<d1b2> <DX-MON> nod I will have to re-run with just the PIC (once I finish it completely) and restrict to 4-luts
<d1b2> <DX-MON> to be fair, for what I'm wanting to do.. programming a PIC (as I have XC8) isn't that terrible
<d1b2> <DX-MON> I might even go so far as "screw it, I'll write an assembler in Python and do the programming in asm so I can integrate it with nMigen building the gateware"
<whitequark> that's uh, exactly how boneless works
<d1b2> <DX-MON> I only learned about boneless' existence yesterday while I started writing this gateware a couple of days ago.. I figured it was good practice to forge ahead anyway so I could learn nMigen
<whitequark> oh sure, i didn't convey the tone right
<whitequark> i found it fun that we arrived at the same kinda solution
<d1b2> <DX-MON> 🙂
<whitequark> boneless made some unorthodox architecture choices (ok, less unorthodox compared to PICs) so it's not for everyone, anyways
<d1b2> <DX-MON> hahaha, fair
<whitequark> like having 16 bits as minimal addressable unit, and the... thing... with register windows
<whitequark> the base ISA is very regular though
<DX-MON> In my case, because I'm after a particular data rate minimum from the sniffer core and dealing with Ethernet (EMAC only thankfully), I decided I most probably want to run the CPU and all of that stuff at at least 50MHz (so that 100MHz I can run it at is rather handy), and make the EMAC core rather smart to offload as much as I can into gateware
<DX-MON> but I also know that the EMAC is going to cost between 2 and 4 BRAM, so I'd face significant firmware challenges with the remaining available BRAM
<whitequark> once i pipeline boneless it should be limited to 2, maybe 3 4-LUTs between FFs, and could be used with as little as 1 single port BRAM
<DX-MON> *drools*
<DX-MON> I think this PIC core could be pipelined but it'd need some rearchitecting and careful thought in where the stages are inserted
<tpw_rules> i made a kinda CPU extremely optimized for event handling and data shuffling which is 2 CPI and 2 BRAM
<whitequark> DX-MON: hmmm if you're interested in boneless that gives me even more motivation to work on it
<whitequark> someone else i know, too
<tpw_rules> it's me
<DX-MON> that does sound interesting, aye
<whitequark> i was just about to mention you as well, tpw_rules, but i meant someone i know in person who doens't have much online presence
<tpw_rules> ah okay
<DX-MON> once I'm more comfortable with the legality of posting source for a PIC16 core.. I'm thinking I'll push this one out BSD-3-Clause
<whitequark> i find that being able to observe someone working with your tools basically over their shoulder makes it a lot easier for me to believe that what i'm doing is actually helpful, which is something that i often struggle with
<tpw_rules> DX-MON: can i pm you? i'm actually kind of curious if my extremely wacky architecture has any other use. but i don't have any docs so i need to just describe it to you :P
<tpw_rules> but high speed sniffing event processing is what it was designed to do
<DX-MON> I /think/ I'm fine as I've done a fully cleanroom impl from the datasheet
<DX-MON> you're welcome to pm me yes
* whitequark is curious about the arch too
<tpw_rules> mine? i can share here
<whitequark> sure
<tpw_rules> okay. so it's got 32 bit data words, 18 bit instruction words, 4 instructions, and no-latency interrupt handling, although they aren't actually interrupts. the only memory is 256 general purpose registers (i.e. "main RAM") and 128 special purpose registers (i.e. all the "MMIO"). all instructions are always 2 cycles and one of the goals is no visible pipelining.
<tpw_rules> there's POKE to write a 9 bit sign extended immediate to a special register. COPY to move a general register to a special register, or vice versa. MODIFY to do a read-modify-write operation on a general register. and BRANCH to branch to an absolute target based on a flag condition
<tpw_rules> it's intended to have an event FIFO in front of it, so BRANCH to address 0 is rewritten to a BRANCH to the vector for the next event (if it's taken), and some special registers are updated based on data from the FIFO that pertains to the current event.
<tpw_rules> so it's designed for twiddling hardware and keeping flags about current state and stuff. there's also an output event FIFO (in this application linked to some PC software) that you can put stuff in through a special register and that automatically stalls execution if it's full. there's a full ALU (lifted from boneless actually) and register and branch target indirection and stuff exposed through special registers and the MODIFY
<tpw_rules> instruction
<tpw_rules> and that's it really
<tpw_rules> one fun property is you can operate it as a three operand RISC machine. you just have one instruction per operand. you can also do 2 operands in 2 instructions
<DX-MON> intruiging
<tpw_rules> also because it's relevant to the current application, there are "event-locked" timers which pass time based on the time each event occurs, completely decoupled from execution time or FIFO delays. if you start a timer during processing of one event and read the elapsed count during processing of the next event, you'll get exactly the number of cycles that occurred between the two events
nickoe has quit [Ping timeout: 240 seconds]
<awygle> is ariane the only risc-v written in nmigen (as opposed to migen)?
<whitequark> minerva too
<awygle> er, minerva, not ariane
bvernoux has quit [Quit: Leaving]
<awygle> (i think ariane's in vanilla verilog)
<DX-MON> interesting you should bring this up (I wasn't aware minerva is nMigen), but I was complaining on my stream yesterday that nMigen is cronically underutilised
<awygle> well i feel like get-out-the-vote advocacy has never been a project priority
<DX-MON> that's fair.. I mean more.. for how long it's been around, looking for things written using it is really hard work which is a shame as that provides very limited resources for learning it
<DX-MON> however once you learn it, well.. 6h to write the larger part of a PIC16 core vs the typical month or two of banging ones head on VHDL/Verilog
<DX-MON> favourite thing so far for me has to have been "oh, oops.. I didn't mean to make that decoder synchronous, oh.. I can just rename all instances of sync to comb in this file and we're good"
<awygle> my version of that was "wow i'm failing timing by a _lot_. s/FIFO/FIFOBuffered/g"
* awygle wonders if DomainRenamer('comb') works....
<whitequark> does not, that would be always unsound, i think
<awygle> it seems obviously a bad idea
<awygle> i was just curious whether it was explicitly prohibited or not
<DX-MON> for me it was more "uhhh.. why is such and such not happening in this cycle of my sim"
<tpw_rules> my favorite part is python sim/test.py *wait 10 seconds* OK
<whitequark> awygle: yeah, i recall explicitly prohibiting it, and it is
<DX-MON> followed by the pained groan of realising that I was being stupid with domains and that stupidity had caused my sim results to be just.. wrong.. entirely
<whitequark> tpw_rules: yeah it's pretty slow :/
<tpw_rules> i'm not sure if that was intended to be partially sarcastic but from my perspective holy crap it's so fast and easy
nickoe has joined #nmigen
<whitequark> oh
<whitequark> oh.
<whitequark> i... just have higher standards than that
<DX-MON> once I figured out how to ask it to synth my design and all that jazz.. agreed, stupidly quick and easyy
<tpw_rules> if it makes you feel better i think it's actually more like 6 seconds across 35 tests for the CPU core i described
<whitequark> like, i genuinely tried to make pysim faster than it is, and i think i explored two or three strategies where i reimplemented most of it as an experiment and had to throw it away cuz it was too slow
<DX-MON> uh.. I definitely feel like I want to contrib some docs on getting started with nMigen once I'm a touch more comfy with it
<DX-MON> (as in, standing up a fresh project)
<tpw_rules> and i think the biggest slowdown is the memory implementation. but it's really quite fast to me, at least compared to trying to fire up modelsim in uni classes.
<whitequark> yes, *that* i will actually fix soon-ish, hopefully
<whitequark> cxxsim requires me to
<whitequark> DX-MON: so i was going to put a lot of effort into first-party docs, and i kinda did, except then the whole pandemic thing kept escalating
<d1b2> <esden> what is there is very good: https://nmigen.info/nmigen/latest/index.html
<DX-MON> that's hugely understandable as yeah.. this.. entirely last year has been one slow-moving giant epic dumpster-fire in one way or another
<nickoe> whitequark: What is the plan about some basic tests or linting for the nmigen-boards repo?
<DX-MON> esden: it is.. however, I was struggling with basically how to write a small driver for the project and how to connect the platform and the design together
<DX-MON> I'd gone down the nmigen.cli route
<whitequark> nickoe: the plan is to add that at some point, but it is not trivial because of all the proprietary tools and for other reasons
<nickoe> whitequark: symbifow can be used for some of them
<DX-MON> which has been handy because being able to make RTLIL directly from my driver.. but figuring out the (trivial!) incantation of platform.build(toplevel).. uhhh
<nickoe> if ou want to run synth
<whitequark> DX-MON: there's a platform example but it's not really discoverable
<nickoe> whitequark: But do we need to synth, if we can just make sure it can export some verilog?
<DX-MON> yeah, that was what I stumbled on
<whitequark> nickoe: does that really test anything useful?
<DX-MON> I'm glad I persisted trying to figure it out
<whitequark> you might as well just check that it imports
<awygle> whitequark: re: docs, is there a way to spread the load of them away from being Just Whitequark?
<nickoe> whitequark: I am not sure, but I guess it is better than nothing and can catch some typos?
<whitequark> awygle: no, because a lot of the doc writing is actually defining the language specification as opposed to just documenting what the current impl does
<nickoe> whitequark: yes
<awygle> like, you're the only one who can reasonably do cxxsim, but i feel like other people could work on docs (with review and support)
<awygle> hm, ok that's fair
<whitequark> awygle: what i wrote so far turned up quite a few issues, some of which are already fixed, some are waiting on RFCs or on filing a proper bug
<nickoe> whitequark: TBH I don't have any better idea on how to do it, but the current setup.py test does not work anyways.
<awygle> whitequark: zero surprise there, i always find bugs/edge cases when i try to document stuff
<nickoe> awygle: it is the same story, when you start doing automated tests for things, you find real bugs :D
<DX-MON> oh.. talking of issues found.. I need to submit an issue because `m.d.comb += platform.request('gpioB').eq(processor.pData)` blew up with a very obtuse stack trace rather than saying "need to .eq to one of .i, .o or .oe y'dummy"
<awygle> idk i feel bad that all the pressure of maintainership is on you, but also i know how easy it is for "help" to actually be "more work in disguise" :/
<DX-MON> I feel like if I stared at the source for long enough I might be able to advance a PR too, but
<awygle> DX-MON: was it `assert defs[sig]` or something like that? cuz we have a bug for that
<DX-MON> lemmie recreate to check
<DX-MON> File "/data/Programming/nmigen/nmigen/hdl/ir.py", line 396, in add_defs
<DX-MON> assert defs[sig] is self
<awygle> https://github.com/nmigen/nmigen/issues/191 huh actually this could probably do with being renamed, or else a few more-specific versions filed
<awygle> i thought we had one explicitly for "assign to Instance output", which is the one i know of that hits that assert
<awygle> but i can't find it
<miek> 398?
<awygle> ah yeah
<awygle> although that's specifically the io one
<awygle> i think i was thinking of https://github.com/nmigen/nmigen/issues/405
<nickoe> mmm, can I use nmigen platform (boards) in a migen.compat import? I am trying to use an uart with litex, but it errors with: "nmigen.build.res.ResourceError: Resource serial#0 does not exist" which is true since no serial opbject like https://github.com/m-labs/migen/blob/master/migen/build/platforms/arty_a7.py#L58-L62 is available, but in nmigen we have UARTResource instead, https://github.com/nmigen/nmigen-boards/blob/master/nmigen_boards/
<nickoe> arty_a7.py#L33-L36
<nickoe> it may very well be that what I am trying to do is stupid... but, can it be done in any sensible way?+
<nickoe> with nmigen
<nickoe> and litex
pftbest has joined #nmigen
pftbest_ has quit [Ping timeout: 256 seconds]
<vup> nickoe: UARTResource uses uart as a name instead of serial
<vup> can you make it request that instead?
<vup> also as far as I know the way people usually use litex and nmigen together is by using nmigen to generate verilog and then use that using `Instance` in a normal litex project
revolve has quit [Read error: Connection reset by peer]
revolve has joined #nmigen
jeanthom has quit [Ping timeout: 264 seconds]
pftbest has quit [Quit: Leaving...]
<nickoe> vup: mmm, ok, I guess it would be more productive for me to just use migen :/
<nickoe> vup: I mean, the backtrace looks like this, https://dpaste.com/CWPFAS37W which is inside some litex stuff?
<vup> nickoe: passing `uart_name="uart"` in the soccore arguments should atleast make it use the right resource