peepsalot has quit [Remote host closed the connection]
peepsalot has joined #nmigen
Naib has quit [Ping timeout: 260 seconds]
whitequark has quit [Ping timeout: 260 seconds]
jn has quit [Ping timeout: 260 seconds]
bob_twinkles has quit [Ping timeout: 260 seconds]
Naib has joined #nmigen
Naib has joined #nmigen
Naib has quit [Changing host]
whitequark has joined #nmigen
urja has quit [Read error: Connection reset by peer]
urja has joined #nmigen
kaucasus has joined #nmigen
jn_ is now known as jn
<kaucasus>
Is there an easy way to memory-map IO for a board with the built-in Memory() module?
<Sarayan>
memory-mapped i/o is not memory
<DX-MON>
though you can map Memory() to addresses in your processor as SRAM by comparing high address bits and feeding the read_port() and write_port() address signals the low bits
DX-MON is now known as dragonmux
<dragonmux>
MMIO is acomplished using CSRs though
<kaucasus>
In the future we would indeed like to use CSRs, but it's just a proof of concept rn. We basically wanted to act like if buttons/leds of our board is just the same as a lw/sw instruction for any data
<kaucasus>
(Making a risc-v processor, but I think you folks already assumed that one :P)
<dragonmux>
that is literally the CSR process, yes - you compare a memory address vs what's on the bus, and if it matches, then the data on the bus is routed to your register (or the reigster routed to the data lines of the bus) based on the bus protocol. The bits of that register then drive and are driven by your buttons/LEDs
<dragonmux>
CSR here doesn't refer to RISC-V CSRs which are their own.. other.. thing
<kaucasus>
ohhh okay! So in memory mapped io the memory/register made with Memory() and the register actually driving your leds/buttons are two different registers who always have the same value
<kaucasus>
I feel like I'm misunderstanding something right, is nmigen/yosys then smart enough to not actually generate/synthesize the redundant register?
<kaucasus>
Currently in our elaborate we just do `m.submodules.led_port = led_port = self.memory.read_port()` and later `m.d.comb += [led_port.addr.eq(MEM_MAPPED_IO_LOC), self.o_leds.eq(led_port.data)]` But I don't think that's what you mean?
<Sarayan>
you want a register with backing storage in your address map?
<Sarayan>
the trick is, if your register is part of a memory block, you can't have a direct access to it, you have to read the memory to get the value, and that's usually not what you want
<Sarayan>
the point of registers usually being fast, parallel, direct access
<kaucasus>
Yeah we don't really *want* a register with backing storage in the address map and yeah that's the problem we kinda wanted to solve of it being part of the memory block
<kaucasus>
Though I guess it doesn't matter that our leds and buttons don't have fast access since they're only used in the core itself and it's not like it needs it's own clock or any weird stuff like that
<kaucasus>
(but later for a UART that might be a problem)
<Sarayan>
the address *map* is not the memory
<Sarayan>
the memory includes an address decoding, but if you have an address map you have to have some kind of chip select too
<Sarayan>
and the matches() you do for your register decoding is not going to be signigicantly slower than your chip select decode
<dragonmux>
yeah, what we're saying is that Memory() is only good for SRAM blocks mapped into your processor, for what you're doing you want to use the Wishbone CSR pattern
<dragonmux>
in this pattern you define a Signal(8) or w/e the width of the bus is, you decode the address on the processor's bus, resulting in a "matches" signal and when it matches you either assert your signal onto the bus, or assert the bus contents onto the signal in the sync domain
<dragonmux>
you then have bits you can drive the LEDs with (`m.d.comb += self.o_leds.eq(ledReg)`) and that's all there is to it
<dragonmux>
trying to involve Memory as opposed to a nmigen-soc MemoryMap is over-complicating things
<dragonmux>
(in that particular project it happens that every periphal is also a controller able to make requests on the bus, which is why each peripheral has a self.ctl_bus that is added to the arbiter as well as a self.bus that is added to the decoder)
FL4SHK has quit [Ping timeout: 258 seconds]
FL4SHK has joined #nmigen
<FL4SHK>
How do I use a platform's `connectors`?
<FL4SHK>
Such as the PMODs on the Arty A7
<miek>
you add a Resource to the platform (that references pins on the connector), then request & use that resource