Closed francis2tm closed 2 years ago
Hi! I assume you're comparing the LiteX CircuitPython SoC, and the foboot bootloader.
Why is it necessary? In the bootloader this isn't the case, and is the fact that the USB is attached to a sperate CSR BUS why a new csr header file (usb_csr.h) is created?
The main reason is that ValentyUSB expects to operate entirely in a 12MHz clock domain. This is fine if you also want to run your main processor at 12MHz. This is how we operate in the Bootloader.
For the circuit python SoC we operate the CPU at 48MHz, we could probably also run it faster.
In order to run these two parts of the design at different speeds we need a point at which we can decouple them, and then use elements that handle passing data across clock domains. I chose to do this at the wishbone interface, so this is why we create a second CSR bank.
LiteX isn't really setup to automatically output register mapping for multiple CSR banks, hence the extra usb_csr.h
file.
Why does the USB need to be in a CSR bus that's decoupled from our CPU clock? Taking into consideration that in the bootloader SoC this does not happen If you're okay running the CPU clock at 12MHz then it's not required.
Why did you add this line and why isn't the platform.finalize() called in this example when the bootloader does?
The finalize
call in the bootloader really justs performs some final packaging that's different from the ice40, you can see the function here: https://github.com/gregdavill/foboot/blob/ab25c1542e7ccc5d70c4e7b17f7e9d1d565ae3ee/hw/rtl/platform/orangecrab.py#L137-L175
It's been a little while, but I actually don't think the bootloader uses a USB interrupt in it's firmware. So it was never connected up in gateware. It simply polls the USB core status in a while loop. This works because it's not really doing much else.
Thanks for the reply, Yes I'm comparing the LiteX CircuitPython SoC, and the foboot bootloader. It makes sense! And regarding the CPU interrupt connection, I did a mistake and I was actually referring to the function soc.finalize() and not platform.finalize(). In the bootloader, the soc.finalize() is called here: https://github.com/gregdavill/foboot/blob/ab25c1542e7ccc5d70c4e7b17f7e9d1d565ae3ee/hw/foboot-bitstream.py#L345 . According to litex source, soc.finalize() performs the cpu interrupt connection ( https://github.com/enjoy-digital/litex/blob/3c3884b1ea545905b9cf20cd2682400f95f1bcd3/litex/soc/integration/soc.py#L1102-L1120)
For this reason, my question is:
Why did you do an explicit self.comb += self.cpu.interrupt[self.interrupt_map['usb']].eq(self.usb0.irq)
in the CircuitPython SoC when (I think) this could've been achieved with the soc.finalize(), which is not called in the CircuitPython SoC?
I think I got it working, then just left it.
To get LiteX to auto connect the line you'd probably just need to create a Event Wrapper
shell. Since that's where it's expecting the IRQ line to be.
Ok, makes sense, thanks for the info!
Hey, I have some questions regarding the USB, specially because I saw the orange crab bootloader SoC (https://github.com/gregdavill/foboot/tree/OrangeCrab) and there the USB is added "differently" In these lines I see that you attach the USB into a seperate CSR Bus. 1) Why is it necessary? In the bootloader this isn't the case, and is the fact that the USB is attached to a sperate CSR BUS why a new csr header file (usb_csr.h) is created?
2) Why does the USB need to be in a CSR bus that's decoupled from our CPU clock? Taking into consideration that in the bootloader SoC this does not happen
In this line the USB interrupt is added (I think). In the bootloader, there is not an explicit USB interrupt addition like this, because I think this is done in the platform.finalize(). However, in the CircuitPython example, there is no platform.finalize().
3) Why did you add this line and why isn't the platform.finalize() called in this example when the bootloader does?