diff --git a/litedram/frontend/wishbone.py b/litedram/frontend/wishbone.py index df4930f..76cc57a 100644 --- a/litedram/frontend/wishbone.py +++ b/litedram/frontend/wishbone.py @@ -26,6 +26,8 @@ class LiteDRAMWishbone2Native(LiteXModule): port_data_width = 2**int(log2(len(port.wdata.data))) # Round to lowest power 2 ratio = wishbone_data_width/port_data_width + assert wishbone.addressing == "byte" + if wishbone_data_width != port_data_width: if wishbone_data_width > port_data_width: addr_shift = -log2_int(wishbone_data_width//port_data_width) @@ -79,3 +81,62 @@ class LiteDRAMWishbone2Native(LiteXModule): NextState("CMD") ) ) + +# LiteDRAMNative2Wishbone -------------------------------------------------------------------------- + +class LiteDRAMNative2Wishbone(LiteXModule): + def __init__(self, port, wishbone, base_address=0x00000000): + wishbone_data_width = len(wishbone.dat_w) + port_data_width = 2**int(log2(len(port.wdata.data))) # Round to lowest power 2 + ratio = wishbone_data_width/port_data_width + + assert ratio == 1 + + # # # + + # Signals. + adr = Signal(32) + + # FSM. + self.fsm = fsm = FSM(reset_state="CMD") + fsm.act("CMD", + If(port.cmd.valid, + port.cmd.ready.eq(1), + If(wishbone.addressing == "byte", + NextValue(adr, port.cmd.addr*int(port_data_width//8) + base_address), + ).Else( + NextValue(adr, port.cmd.addr + base_address//int(port_data_width//8)), + ), + If(port.cmd.we, + NextState("WRITE") + ).Else( + NextState("READ") + ) + ) + ) + fsm.act("WRITE", + If(port.wdata.valid, + wishbone.stb.eq(1), + wishbone.cyc.eq(1), + wishbone.we.eq(1), + wishbone.adr.eq(adr), + wishbone.sel.eq(port.wdata.we), + wishbone.dat_w.eq(port.wdata.data), + If(wishbone.ack, + port.wdata.ready.eq(1), + NextState("CMD") + ) + ) + ) + fsm.act("READ", + wishbone.stb.eq(1), + wishbone.cyc.eq(1), + wishbone.adr.eq(adr), + wishbone.sel.eq(2**len(wishbone.sel) - 1), + If(wishbone.ack, + # Assume port.rdata.ready always 1. + port.rdata.valid.eq(1), + port.rdata.data.eq(wishbone.dat_r), + NextState("CMD"), + ) + )