examples / mycores / aic23 / aic23_spi.py

from myhdl import *
  
def aic23_spi(
    clk,         # system clock
    rst,         # system reset
    data_in,     # parallel data to sent
    data_go,     # command to send data
    busy,        # busy sending data
    AUDIO_CSN,   # Serial config select
    AUDIO_SCLK,  # Serial config clock
    AUDIO_SDIN   # Serial data to AIC23
    ):
    """ SPI interface to configure the AIC23
    """

    clk_cnt   = Signal(intbv(0)[8:])
    bit_cnt   = Signal(intbv(0, max=18, min=0))
    shift_out = Signal(intbv(0)[16:])
    
    csn       = Signal(False)
    sclk      = Signal(False)

    # State types
    _s     = enum('IDLE', 'SHIFT', 'END')
    state  = Signal(_s.IDLE)

    sclk_negedge = Signal(False)

    @always_comb
    def rtl_assignments():
        AUDIO_CSN.next  = csn
        AUDIO_SDIN.next = shift_out[15]

        if not busy or csn:
            AUDIO_SCLK.next  = True
        else:
            AUDIO_SCLK.next = sclk       


    @always(clk.posedge)
    def rtl_simple_sm():
        if rst:
            state.next = _s.IDLE
            busy.next  = False
        else:
            if state == _s.IDLE:
                if data_go:
                    state.next = _s.SHIFT
                    busy.next  = True
                else:
                    busy.next  = False
            elif state == _s.SHIFT:
                if bit_cnt == 17:
                    state.next = _s.END
            elif state == _s.END:
                #busy.next = False
                if sclk_negedge:
                    state.next = _s.IDLE

            else:
                assert False, "Invalid State"
                state.next = _s.IDLE

    @always(clk.posedge)
    def rtl_sync_outs():
        if rst:
            csn.next  = True
            bit_cnt.next = 0
            shift_out.next = data_in
        else:
            if busy and bit_cnt < 18-1:
                if sclk_negedge:
                    csn.next = False
                    bit_cnt.next = bit_cnt + 1
                    if not csn:
                        shift_out.next = (shift_out << 1) & 0xFFFF
            else:
                bit_cnt.next = 0
                shift_out.next = data_in
                csn.next = True
            
    # counter for slower clock, desire a clock that is much slower
    # than the system clock
    CLK_MOD = int(2**8)  # <-- cver issue with verilog power op
    @always(clk.posedge)
    def rtl_slow_clk():
        clk_cnt.next = (clk_cnt + 1) % CLK_MOD
        sclk.next    = clk_cnt[7]


    @always_comb
    def rtl_edges():
        sclk_negedge.next = sclk and not clk_cnt[7]
        
    return instances()
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.