You can find the complete code at https://github.com/msvisser/glasgow/blob/sd-spi-applet/software/glasgow/applet/memory/sd_spi/__init__.py . It might be a bit messy, but running `glasgow -v run memory-sd-spi -V A=3.3 test` should trigger the issue. Even without anything connected you should see... Okay I've figured out the issue in your `Command-Wait-For-Ready` state. When the clock frequency isn't close to the bus frequency, the handshake for `ctrl.o_stream` finishes before the `ctrl.i_stream` handshake. This results in `should_tx` getting stuck at zero. The simulation clk freq is 1 MHz, and the Glasgow's (Rev C) clock freq is 48 MHz, which explains the difference between simulation/hardware. You can change the bus freq in setup to 100kHz to see this in simulation. Something like this should work: ```python with m.State("Command-Wait-For-Ready"): m.d.comb += [ ctrl.i_stream.p.chip.eq(chip), ctrl.i_stream.p.mode.eq(spi.Mode.Swap), ctrl.i_stream.p.data.eq(0xFF), ] with m.If(should_tx): m.d.sync += [ tx_pending.eq(1), rx_pending.eq(1), should_tx.eq(0) ] with m.Elif(~tx_pending & ~rx_pending): with m.If(i_count == 0): m.d.sync += o_count.eq(6) m.next = "Command-Transmit" with m.Else(): m.d.sync += should_tx.eq(1) with m.If(tx_pending): m.d.comb += ctrl.i_stream.valid.eq(1) with m.If(ctrl.i_stream.ready): m.d.sync += tx_pending.eq(0) with m.If(rx_pending): m.d.comb += ctrl.o_stream.ready.eq(1) with m.If(ctrl.o_stream.valid): m.d.sync += rx_pending.eq(0) m.d.sync += i_count.eq(i_count - 1) with m.If(ctrl.o_stream.p.data == 0xFF): m.d.sync += i_count.eq(0) ```