Commits

Christopher Felton committed 1c79669

test aic23

Comments (0)

Files changed (8)

mycores/aic23/aic23.py

 from aic23_setup import *
 from aic23_i2s import *
 
-# Pin out for different FPGA boards with AIC23
-# [Comment]-------------------------+
-# [FPGA Pin]-------------------+    |
-# [AIC23 Pin]--------------+   |    |
-# [Port Dir]-------+       |   |    |
-# [Signal Name]    |       |   |    |
-#                  |       |   |    |
-# DSPtronics USB FPGA board|   |    |
-#------------------+-------+---+----+---------------------------
-#AUDIO_CLK,        Output: 25  63   This is driven by top-level DCM->DDR flop 
-#AUDIO_BCLK,       Input:  3   85   I2S Serial-bit clock
-#AUDIO_DIN,        Output: 4   62   I2S data out of CODEC
-#AUDIO_DOUT,       Input:  6   66   I2S data in to CODEC
-#AUDIO_LRCIN,      Input:  5   65   I2S DAC-word clock signal
-#AUDIO_LRCOUT,     Input:  7   68   I2S ADC-word clock signal
-#AUDIO_MODE,       Output: 22  69   0 - 2 wire, 1 - SPI
-#AUDIO_CSN,        Output: 21  84   Control Mode chip select
-#AUDIO_SCLK,       Output: 24  78   Control port serial clock
-#AUDIO_SDIN,       Output: 23  79   Control port serial data
-#                  |       |   |    |
-# Altera Cyclone II/III DSP board   |
-#------------------+-------+---+----+---------------------------
-#AUDIO_CLK,        Output: 25  AB3  This is driven by top-level DCM->DDR flop 
-#AUDIO_BCLK,       Input:  3   F3   I2S Serial-bit clock
-#AUDIO_DIN,        Output: 4   J21  I2S data out of CODEC
-#AUDIO_DOUT,       Input:  6   B13  I2S data in to CODEC
-#AUDIO_LRCIN,      Input:  5   W4   I2S DAC-word clock signal
-#AUDIO_LRCOUT,     Input:  7   AB2  I2S ADC-word clock signal
-#AUDIO_MODE,       Output: 22  AA2  0 - 2 wire, 1 - SPI
-#AUDIO_CSN,        Output: 21  AC25 Control Mode chip select
-#AUDIO_SCLK,       Output: 24  R4   Control port serial clock
-#AUDIO_SDIN,       Output: 23  AD2  Control port serial data
-
-
 def aic23(
     # --[System Signals]--
-    clock,   # also known as fclk
-    reset,   # system reset
-        
-    # --[ CODEC interface to FPGA logic (audio stream) ]--
-    au_bus,
-    #au_in_r,     # Output: audio in stream to FPGA logic right channel
-    #au_in_l,     # Output: audio in stream to FPGA logic left channel
-    #au_out_r,    # Input:  audio out stream from FPGA logic right channel
-    #au_out_l,    # Input:  audio out stream from FPGA logic left channel
-    #mic_in,      # Input:  Mic audio stream
-    #hp_out,      # Output: Speaker audio stream
-    #Ts,          # Output: Sample rate pulse
-    
-    # --[ External CODEC interface to AIC23, see pinout above comments ]--
-    aic23_bus,
-    #AUDIO_CLK,      # Output:   This is driven by top-level DCM->DDR flop 
-    #AUDIO_BCLK,      # Input:    I2S Serial-bit clock
-    #AUDIO_DIN,       # Output:   I2S data out of CODEC
-    #AUDIO_DOUT,      # Input:    I2S data in to CODEC
-    #AUDIO_LRCIN,     # Input:    I2S DAC-word clock signal
-    #AUDIO_LRCOUT,    # Input:    I2S ADC-word clock signal
-    #AUDIO_MODE,      # Output:   0 - 2 wire, 1 - SPI
-    #AUDIO_CSN,       # Output:   Control Mode chip select
-    #AUDIO_SCLK,      # Output:   Control port serial clock
-    #AUDIO_SDIN,      # Output:   Control port serial data
-
-    # --[ Test Points ]--
-    tst_pts,         # Output:   test points
+    clock,     # also known as fclk
+    reset,     # system reset        
+    au_bus,    # audio stream   
+    aic23_bus, # external codec interface
+    tst_pts,   # Output:   test points
 
     # --[ Parameters ]--
-    ConfigOpt=None
+    ConfigOpt = None
     ):
     """AIC23 interface
     This module contains the logic to configure the AIC23 in a default mode
     and transfer audio to and fro.  This module will configure the AIC23 
     """
 
-    rst      = Signal(False)   #
-    spi_mode = Signal(False)   # Map to status register
     i2s_tst_pts = Signal(intbv(0)[5:])
+        
+    # Static Signal
+    spi_mode = Signal(True) if aic23_bus.mode else Signal(False)
 
-
-
-    @always_comb
-    def hdl_bit_assignments():
-        # Status bits
-        AISR.next[0] = AUDIO_MODE
-        AISR.next[1] = spi_mode
-
-        
-    @always(clock.posedge)       # always_comb doesn't work with 1 static signal
-    def hdl_assignments():
-                                 # coded active high
-        if AUDIO_MODE:
-            spi_mode.next = True
-        else:
-            spi_mode.next = False
-
+    AUDIO_CSN = aic23_bus.csn
+    AUDIO_SCLK = aic23_bus.sclk
+    AUDIO_SDIN = aic23_bus.sdin
+    @always(clock.posedge) 
+    def hdl_test_points():
         tst_pts.next[5:] = i2s_tst_pts
         tst_pts.next[5]  = AUDIO_CSN
         tst_pts.next[6]  = AUDIO_SCLK
         tst_pts.next[7]  = AUDIO_SDIN
 
-
-    g_setup = aic23_setup(clock, reset,
-                          AUDIO_CSN, AUDIO_SCLK, AUDIO_SDIN,
-                          LVC, RVC, LHC, RHC, AAC, DAC, PDC, DAF, SRC,
-                          DIA, RST, PGM)
-    
-    g_i2s  = aic23_i2s(clock, reset,
-                       AUDIO_BCLK, AUDIO_DIN, AUDIO_DOUT, AUDIO_LRCIN, AUDIO_LRCOUT,
-                       au_in_l, au_in_r, au_out_l, au_out_r, mic_in, hp_out,
-                       Ts, i2s_tst_pts)
+    pgm = Signal(False)
+    g_setup = aic23_setup(clock, reset, pgm, aic23_bus)    
+    g_i2s  = aic23_i2s(clock, reset, aic23_bus, au_bus, i2s_tst_pts)
 
         
     
-    return g_
+    return hdl_test_points, g_setup, g_i2s
 
 
     

mycores/aic23/aic23_config.py

+
+import argparse
+from myhdl import intbv
+
+class Aic23Config(argparse.Namespace):
+    """
+    This object is used to set the configuration for the AIC23.
+
+    List of configuration options:
+       * sample_rate : Set the sample rate, 8,32,44.1,48,96kHz
+       * iwl : input word length.  Audio sample size in bits, 16,20,24,32
+       * left and right : channel settings, each left and right contains
+         the following
+          * mute : mute line in
+          * lock : left and right updated at the same time
+          * volume : line in volume
+          * hp_lock : headphone, left and right updated at the same time
+          * hp_zero_cross : headphone, check for zero-crossing
+          * hp_volume : headphone volume
+    """
+    def __init__(self, parser=None):
+        argparse.Namespace.__init__(
+            self,
+            sample_rate=32,  # sample rate in kHz
+            iwl=16           # input word length
+            )
+        self.left = argparse.Namespace(mute=False, lock=False, volume=23,
+                                       hp_lock=False, hp_zero_cross=True,
+                                       hp_volume=121)
+        self.right = argparse.Namespace(mute=False, lock=False, volume=23,
+                                       hp_lock=False, hp_zero_cross=True,
+                                       hp_volume=121)
+   
+    def __str__(self):
+        return "TBC summary of the configuration"
+
+    def BuildRom(self):
+        """
+        Given the configuration options build the "ROM".  The "ROM"
+        is the values the registers in the AIC23 will be programmed 
+        as.
+        The following are the registers that are programmed
+          LVC :00: Left line input channel volume control
+          RVC :01: Right line input channel volume control
+          LHC :02: Left channel headphone volume control
+          RHC :03: Right channel headphone volume control
+          AAC :04: Analog audio path control
+          DAC :05: Digital audio path control
+          PDC :06: Power down control
+          DAF :07: Digital audio interface format
+          SRC :08: Sample rate control
+          DIA :09: Digital interface activation
+          RST :0F: Reset register
+
+          Reference : http://www.ti.com/lit/ds/symlink/tlv320aic23b.pdf
+          
+          The following will convert the instance attributes to the 
+          register settings.  The following is fairly dense because it 
+          includes majority of the documentation for the registers.
+        """
+        # Each register is 9 bits and a 7 bit address.  Each control transfer
+        # is 16bits over SPI (this core uses the SPI as the control interface).
+        
+        # Channel volume control registers
+        #             D8    D7    D6    D5    D4    D3    D2    D1    D0
+        # Function   LRS   LIM    x     x    LIV4  LIV3  LIV2  LIV1  LIV0
+        # Default     0     1     0     0     1     0     1     1     1
+        #    LRS : Left/right line simultaneous volume/mute update (lock)
+        #          Simultaneous update 0 = Disabled   1 = Enabled
+        #    LIM : Line inmput mute
+        #          Line input mute     0 = Normal     1 = Muted
+        #    LIV : Line input volume
+        #          
+        LVC = intbv('0_0001_0111') # left line unmute, volume = 10111, Default 0_1001_0111
+        RVC = intbv('0_0001_0111') # right line unmute, volume = 10111, Default 0_1001_0111
+        LVC[8] = 1 if self.left.lock else 0
+        LVC[7] = 1 if self.left.mute else 0
+        LVC[5:] = self.left.volume
+        RVC[8] = 1 if self.right.lock else 0
+        RVC[7] = 1 if self.right.mute else 0
+        RVC[5:] = self.right.volume
+                
+        # Headphone volume control registers
+        #             D8    D7    D6    D5    D4    D3    D2    D1    D0
+        # Function  
+        # Default
+        LHC = intbv('0_0000_0000') # all disable, Default 0_1111_1001
+        RHC = intbv('0_0000_0000') # all disable, Default 0_1111_1001    
+        # @todo : headphone controls
+
+        #             D8    D7    D6    D5    D4    D3    D2    D1    D0
+        # Function  
+        # Default
+        AAC = intbv('0_0001_1010') # Side tone disable, DAC select, Default 0_0000_1010
+        # @todo : 
+
+        #             D8    D7    D6    D5    D4    D3    D2     D1     D0
+        # Function    x     x     x     x     x    DACM  DEEMP1 DEEMP0 ADCHP
+        # Default     0     0     0     0     0     1     0      0      0
+        #    DACM DAC soft mute        0 = Disabled   1 = Enabled
+        #    DEEMP deemphasis         00 = Disabled   01 = 32kHz
+        #           
+        DAC = intbv('0_0000_0000') # disable all, Default 0_0000_1000
+
+        # Power Down Control
+        #             D8    D7    D6    D5    D4    D3    D2    D1    D0
+        # Function  
+        # Default        
+        PDC = intbv('0_0000_0010') # power down mic, Default 0_0000_0111
+        
+        # Digital Audio Interface Format
+        #             D8    D7    D6    D5     D4    D3    D2    D1    D0
+        # Function    x     x    MS    LRSWAP LRP   IWL1  IWL0  FOR1  FOR0
+        # Default     0     0     0     0      0     0     0     0     1
+        #  MS     Master/slave mode    0 = Slave      1 = Master
+        #
+        #  LRSWAP DAC left/right swap  0 = Disable    1 = Enable
+        #
+        #  LRP    DAC left/right phase 0 = right channel on, LRCIN high
+        #                              1 = right channel on, LRCIN low, DSP mode
+        # 
+        #  IWL    Input bit length    00 = 16  01=20  10=24  11=32
+        # 
+        #  FOR    Data format         00 = I2S MSB first, right aligned
+        #                             01 = I2S MSB first left aligned
+        #                             10 = I2S MSB first left-1 alighed
+        #                             11 = DSP format, frame sync followed by two data words
+        DAF = intbv('0_0100_1110') # Master mode, 32 bit word, I2S format
+        iwl_t = {16:0, 20:1, 24:2, 32:3}
+        DAF[4:2] = iwl_t[self.iwl]
+
+        # Sample Rate Control
+        #             D8    D7     D6    D5    D4    D3    D2    D1    D0
+        # Function    x    CLKOUT CLKIN SR3   SR2   SR1   SR0   BOSR  USB/Normal
+        # Default     0     0      0     1     0     0     0     0     0
+        #  
+        SRC = intbv('0_1001_1101') # clkout/2, SR= 0111 96kHz, USB mode
+        self.sample_rate = int(self.sample_rate)
+        sr_t = {8:(3,0), 32:(8,0), 44:(8,1), 48:(0,0), 96:(3,0)}
+        SRC[6:2] = sr_t[self.sample_rate][0]
+        SRC[1] = sr_t[self.sample_rate][1]
+        
+
+        DIA = intbv('0_0000_0001') # activate interface, Default 0_0000_0000
+        RST = intbv('0_0000_0000') # no reset, Default 0_0000_0000
+
+        # create two tuple of ints(intbv) first for the values the secod
+        # for the address.
+        config_rom = tuple(map(int, (LVC, RVC, LHC, RHC, AAC, DAC, PDC, DAF, SRC, DIA, RST)))
+        config_addr = (0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09 ,0x0F)
+        assert len(config_rom) == len(config_addr)
+
+        return config_rom, config_addr
+
+
+        

mycores/aic23/aic23_i2s.py

 from myhdl import *
 
 def aic23_i2s(
-    clk,
-    rst,
+    clock,
+    reset,
+    aic23_bus,
+    au_bus,
 
-    bclk,        # CODEC interface clock (12 MHz)
-    din,         # Audio to CODEC
-    dout,        # Audio from CODEC
-    lrcin,       # left/right for audio to CODEC
-    lrcout,      # left/right for audio from CODEC
-
-    au_in_l,     # to FPGA audio
-    au_in_r,     # to FPGA audio 
-    au_out_l,    # from FPGA audio
-    au_out_r,    # from FPGA audio
-    au_mic,      # mic
-    au_hp,       # au
-     
-    Ts,          # Sample pulse
     tst_pts      # testpoints
     ):
 
+    # local aliases
+    bclk = aic23_bus.bclk      # CODEC interface clock (12 MHz)
+    din = aic23_bus.din        # Audio to CODEC
+    dout = aic23_bus.dout      # Audio from CODEC
+    lrcin = aic23_bus.lrcin    # left/right for audio to CODEC
+    lrcout = aic23_bus.lrcout  # left/right for audio from CODEC
 
+    au_in_l = au_bus.in_l     # to FPGA audio
+    au_in_r = au_bus.in_r     # to FPGA audio 
+    au_out_l = au_bus.out_l   # from FPGA audio
+    au_out_r = au_bus.out_r   # from FPGA audio
+    au_mic = au_bus.mic_in    # mic
+    au_hp = au_bus.hp_out     # au     
+    Ts = au_bus.Ts            # Sample pulse
+
+    # local signals
     shift_in  = Signal(intbv(0)[66:])
     shift_out = Signal(intbv(0)[66:])
 
     state  = Signal(_s.LEFT_CH_START)
 
 
-    @always(clk.negedge)
-    def rtl_syncdn():
+    @always(clock.negedge)
+    def hdl_syncdn():
         __bclk.next = bclk
         __dout.next = dout
         __lin.next  = lrcin
         __lout.next = lrcout
 
-    @always(clk.posedge)
-    def rtl_syncdu():        
+    @always(clock.posedge)
+    def hdl_syncdu():        
         _bclk.next = __bclk
         _dout.next = __dout
         _lin.next  = __lin
 
 
     @always_comb
-    def rtl_syncor():
+    def hdl_syncor():
         bclk_n.next = _bclk and not bclk
         bclk_p.next = not _bclk and bclk
 
 
 
     @always_comb
-    def rtl_assignments():
+    def hdl_assignments():
         Ts.next  = lrcin_n
         din.next = shift_out[65]
         # Use the following for simple test
         #din.next = dout  # Simple Loopback
     
-    @always(clk.posedge)
-    def rtl_au_in():
+    @always(clock.posedge)
+    def hdl_au_in():
         if bclk_p and en_cnt:
             shift_in.next = concat(shift_in[65:0], _dout)
 
             au_in_r.next = shift_in[32:0]   # bit 32 don't care
 
 
-    @always(clk.posedge)
-    def rtl_au_out():
+    @always(clock.posedge)
+    def hdl_au_out():
         if Ts:
             shift_out.next = concat(au_out_l[31], au_out_l,
                                     au_out_r[31], au_out_r)
             shift_out.next = concat(shift_out[65:0], intbv(0)[1:] )
 
 
-    @always(clk.posedge)
-    def rtl_sm():
-        if rst:
+    @always(clock.posedge)
+    def hdl_sm():
+        if reset == True:
             state.next = _s.LEFT_CH_START
             cnt.next   = 0
             en_cnt.next = False

mycores/aic23/aic23_setup.py

 
 from myhdl import *
 from aic23_spi import *
+from aic23_config import Aic23Config
 
 def aic23_setup(
     clock,
     reset,
-    
-    AUDIO_CSN,
-    AUDIO_SCLK,
-    AUDIO_SDIN,
-
+    pgm,
+    aic23_bus,
     # Configuration Parameters
-    ConfigOpt
+    Config=None
     ):
     """ Static setup / configuration for the AIC23 CODEC
 
     on the configure in ConfigOpt.  This module will drive the
     AIC23 configuration bus (
     """
-    # Read in the configuration file, from the configuration file generate
-    # the correct register configuration.
-    
-    # values assigned below, see note on current msb of data being included
-    R_LVC = Signal(intbv('0000_0000'))    # Left volume control
-    R_RVC = Signal(intbv('0000_0000'))    # Right volume control
-    R_LHC = Signal(intbv('0000_0000'))    # Left headphone volume control
-    R_RHC = Signal(intbv('0000_0000'))    # Right headphone volume control
-    R_AAC = Signal(intbv('0000_0000'))    # Analog audio path control
-    R_DAC = Signal(intbv('0000_0000'))    # Digital audio path control
-    R_PDC = Signal(intbv('0000_0000'))    # Power down control
-    R_DAF = Signal(intbv('0000_0000'))    # Digital audio interface format
-    R_SRC = Signal(intbv('0000_0000'))    # Sample rate control
-    R_DIA = Signal(intbv('0000_0000'))    # Digital interface activation
-    R_RST = Signal(intbv('0000_0000'))    # Reset register
+    # @todo: Read in the configuration file, from the configuration file 
+    # generate the correct register configuration.
+    if Config is None or not isinstance(Config, Aic23Config):
+        if not isinstance(Config, Aic23Config):
+            print("WARNING: Invalid AIC23 config type %s, results might not be as expected" % (type(Config)))
+        Config = Aic23Config()
+    config_rom,config_addr = Config.BuildRom()
 
-    # -- TODO REMOVE --#
-    I_LVC = Signal(intbv('0001_0111')) # left line unmute, volume = 10111, Default 0_1001_0111
-    I_RVC = Signal(intbv('0001_0111')) # right line unmute, volume = 10111, Default 0_1001_0111
-    I_LHC = Signal(intbv('0000_0000')) # all disable, Default 0_1111_1001
-    I_RHC = Signal(intbv('0000_0000')) # all disable, Default 0_1111_1001    
-    I_AAC = Signal(intbv('0001_1010')) # Side tone disable, DAC select, Default 0_0000_1010
-    I_DAC = Signal(intbv('0000_0000')) # disable all, Default 0_0000_1000
-    I_PDC = Signal(intbv('0000_0010')) # power down mic, Default 0_0000_0111
-    I_DAF = Signal(intbv('0100_1110')) # Master mode, 32 bit word, I2S format, Default 0_0000_0001
-    I_SRC = Signal(intbv('1001_1101')) # clkout/2, SR= 0111 96kHz, USB mode, Default 0_0010_0000
-    I_DIA = Signal(intbv('0000_0001')) # activate interface, Default 0_0000_0000
-    I_RST = Signal(intbv('0000_0000')) # no reset, Default 0_0000_0000
-
+    # Local aliases
+    AUDIO_CSN = aic23_bus.csn
+    AUDIO_SCLK = aic23_bus.sclk
+    AUDIO_SDIN = aic23_bus.sdin
 
     # State types
-    _s     = enum('IDLE', 'RGO', 'BDLY', 'WAIT', 'INC', 'END')
-    state  = Signal(_s.IDLE)
+    States = enum('IDLE', 'RGO', 'BDLY', 'WAIT', 'INC', 'END')
+    state  = Signal(States.IDLE)
 
     aic_c      = Signal(intbv(0)[16:])  # control data
     aic_c_go   = Signal(False)          # send control data
     _go        = Signal(False)
     reg_cnt    = Signal(intbv(0)[4:])
 
-    pgm        = Signal(False)
+    _pgm       = Signal(False)
     pgm_trans  = Signal(False)
     pgm_rst    = Signal(False)
 
-    @always(clk.posedge)
-    def rtl_pgm():
-        if rst:
-            pgm.next = PGM[0]
+    @always_seq(clock.posedge, reset=reset)
+    def hdl_pgm():
+        _pgm.next = pgm        
+        if pgm and not _pgm or not pgm_rst:
+            pgm_trans.next = True
+        else:
             pgm_trans.next = False
-        else:
-            pgm.next = PGM[0]
-
-            if PGM[0] and not pgm:
-                pgm_trans.next = True
-            else:
-                pgm_trans.next = False
 
     
-    @always(clk.posedge)
-    def rtl_sm():
-        if rst:
-            state.next     = _s.IDLE
-            aic_c_go.next  = False
-            reg_cnt.next   = 0
-            pgm_rst.next   = True
+    @always_seq(clock.posedge, reset=reset)
+    def hdl_sm():
+        if state == States.IDLE:
+            if pgm_trans:
+                state.next = States.RGO
+            reg_cnt.next = 0
+                
+        elif state == States.RGO:
+            if not aic_c_busy:
+                state.next = States.BDLY
+                aic_c_go.next = True
+
+        elif state == States.BDLY:
+            aic_c_go.next = False
+            state.next = States.WAIT
+
+        elif state == States.WAIT:
+            aic_c_go.next = False
+            if not aic_c_busy:
+                if reg_cnt == 9:
+                    state.next = States.END
+                else:
+                    state.next = States.INC
+
+        elif state == States.INC:
+            aic_c_go.next = False
+            state.next = States.RGO
+            reg_cnt.next = reg_cnt + 1
+
+        elif state == States.END:
+            pgm_rst.next  = True   # at least one pgm has been completed
+            aic_c_go.next = False
+            if pgm_trans:
+                state.next = States.IDLE
+            else:
+                state.next = States.END  
+
         else:
-            
-            if state == _s.IDLE:
-                state.next = _s.RGO
-                reg_cnt.next = 0
-                
-            elif state == _s.RGO:
-                if not aic_c_busy:
-                    state.next = _s.BDLY
-                    aic_c_go.next = True
+            assert False, "Unhandled state %s" % (state)
+            aic_c_go.next = False
+            state.next = States.END
 
-            elif state == _s.BDLY:
-                aic_c_go.next = False
-                state.next = _s.WAIT
+    @always(clock.posedge)
+    def hdl_rom_addr_val():
+        aic_c.next[9:0] = config_rom[reg_cnt]
+        aic_c.next[16:9] = config_addr[reg_cnt]
 
-            elif state == _s.WAIT:
-                aic_c_go.next = False
-                if not aic_c_busy:
-                    if reg_cnt == 9:
-                        state.next = _s.END
-                    else:
-                        state.next = _s.INC
-
-            elif state == _s.INC:
-                aic_c_go.next = False
-                state.next = _s.RGO
-                reg_cnt.next = reg_cnt + 1
-
-
-            elif state == _s.END:
-                #pgm_rst.next  = False
-                aic_c_go.next = False
-                if pgm_trans:
-                    state.next = _s.IDLE
-                else:
-                    state.next = _s.END  # stop here, one shot
-
-            else:
-                aic_c_go.next = False
-                state.next = _s.END
-
-    ConfigValuesI = [Signal(intbv(0)[16:]) for ii in range(11)]    
-    ConfigValuesR = [Signal(intbv(0)[16:]) for ii in range(11)]    
-    # The following prevents the overriding of the register address
-    @always(clk.posedge)
-    def rtl_init_regs():
-        # @todo msb of the data config currently in the address rom
-        #       need to move to the RegDef.  Was lazy, can't decide to
-        #       fix the RegDef to support 16-bit or add second set of 8bit
-        #       registers by hand.
-        R_LVC.next = intbv('000_0000_0')  # Left volume control
-        R_RVC.next = intbv('000_0001_0')  # Right volume control
-        R_LHC.next = intbv('000_0010_0')  # Left headphone volume control
-        R_RHC.next = intbv('000_0011_0')  # Right headphone volume control
-        R_AAC.next = intbv('000_0100_0')  # Analog audio path control
-        R_DAC.next = intbv('000_0101_0')  # Digital audio path control
-        R_PDC.next = intbv('000_0110_0')  # Power down control
-        R_DAF.next = intbv('000_0111_0')  # Digital audio interface format
-        R_SRC.next = intbv('000_1000_0')  # Sample rate control
-        R_DIA.next = intbv('000_1001_0')  # Digital interface activation
-        R_RST.next = intbv('000_1111_0')  # Reset register
-
-        I_LVC.next = intbv('0001_0111')
-        I_RVC.next = intbv('0001_0111')
-        I_LHC.next = intbv('0000_0000')
-        I_RHC.next = intbv('0000_0000')
-        I_AAC.next = intbv('0001_1010')   # bypass == bit 3
-        I_DAC.next = intbv('0000_0000')
-        I_PDC.next = intbv('0000_0010')
-        I_DAF.next = intbv('0100_1110')
-        I_SRC.next = intbv('1001_1101')
-        I_DIA.next = intbv('0000_0001')
-        I_RST.next = intbv('0000_0000')
-
-    # @todo this should be a always_comb don't need the extra
-    #       set of registers.
-    @always(clk.posedge)
-    def rtl_addr_rom():
-        ConfigValuesI[0].next  = concat(R_LVC, I_LVC)
-        ConfigValuesI[1].next  = concat(R_RVC, I_RVC)
-        ConfigValuesI[2].next  = concat(R_LHC, I_LHC)
-        ConfigValuesI[3].next  = concat(R_RHC, I_RHC)
-        ConfigValuesI[4].next  = concat(R_AAC, I_AAC)
-        ConfigValuesI[5].next  = concat(R_DAC, I_DAC)
-        ConfigValuesI[6].next  = concat(R_PDC, I_PDC)
-        ConfigValuesI[7].next  = concat(R_DAF, I_DAF)
-        ConfigValuesI[8].next  = concat(R_SRC, I_SRC)
-        ConfigValuesI[9].next  = concat(R_DIA, I_DIA)
-
-        ConfigValuesR[0].next  = concat(R_LVC, LVC[8:])
-        ConfigValuesR[1].next  = concat(R_RVC, RVC[8:])
-        ConfigValuesR[2].next  = concat(R_LHC, LHC[8:])
-        ConfigValuesR[3].next  = concat(R_RHC, RHC[8:])
-        ConfigValuesR[4].next  = concat(R_AAC, AAC[8:])
-        ConfigValuesR[5].next  = concat(R_DAC, DAC[8:])
-        ConfigValuesR[6].next  = concat(R_PDC, PDC[8:])
-        ConfigValuesR[7].next  = concat(R_DAF, DAF[8:])
-        ConfigValuesR[8].next  = concat(R_SRC, SRC[8:])
-        ConfigValuesR[9].next  = concat(R_DIA, DIA[8:])
-        #ConfigValues[10].next = concat(R_RST, RST[10:])
-    
-    @always_comb
-    def rtl_data_sel():
-        if pgm_rst:
-            aic_c.next = ConfigValuesI[int(reg_cnt)]
-        else:
-            aic_c.next = ConfigValuesR[int(reg_cnt)]
-            
-        
-
-    SPI = aic23_spi(clk, rst, aic_c, aic_c_go, aic_c_busy,
+    SPI = aic23_spi(clock, reset, aic_c, aic_c_go, aic_c_busy,
                     AUDIO_CSN, AUDIO_SCLK, AUDIO_SDIN)
 
 

mycores/aic23/aic23_spi.py

 
     @always(clk.posedge)
     def rtl_simple_sm():
-        if rst:
+        if rst == False:
             state.next = _s.IDLE
             busy.next  = False
         else:
                 if bit_cnt == 17:
                     state.next = _s.END
             elif state == _s.END:
-                #busy.next = False
-                if sclk_negedge:
+                busy.next = False
+                if not data_go: #sclk_negedge and 
                     state.next = _s.IDLE
 
             else:
 
     @always(clk.posedge)
     def rtl_sync_outs():
-        if rst:
+        if rst == False:
             csn.next  = True
             bit_cnt.next = 0
             shift_out.next = data_in
         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]

mycores/aic23/aic23_top.py

+
+from argparse import Namespace
 from myhdl import *
+from aic23 import aic23
+from aic23_config import Aic23Config
 
-from aic23 import aic23
 
 # Pin out for different FPGA boards with AIC23
 # [Comment]-------------------------+
 #AUDIO_SCLK,       Output: 24  R4   Control port serial clock
 #AUDIO_SDIN,       Output: 23  AD2  Control port serial data
 
+class Container(object) : pass
 
 def aic23_top(
     # --[System Signals]--
     clock,   # also known as fclk
     reset,   # system reset
-    
-    # --[ Wishbone Bus ]--
-    clk_i,          # wishbone clock
-    rst_i,          # wishbone reset 
-    cyc_i,          # cycle
-    stb_i,          # strobe
-    adr_i,          # address
-    we_i,           # write enable
-    sel_i,          # byte select
-    dat_i,          # data input
-    dat_o,          # data output
-    ack_o,          # acknowledge
-
-    
+        
     # --[ CODEC interface to FPGA logic (audio stream) ]--
     au_in_r,     # Output: audio in stream to FPGA logic right channel
     au_in_l,     # Output: audio in stream to FPGA logic left channel
     tst_pts,         # Output:   test points
 
     # --[ Parameters ]--
-    C_WB_ADDR = 0x1000
+    ConfigOpt = None
     ):
     """AIC23 interface
     This module contains the logic to configure the AIC23 in a default mode
     and transfer audio to and fro.
     """
 
-    fclk = clock
+    aic23_bus = Namespace(bclk=AUDIO_BCLK, din=AUDIO_DIN, dout=AUDIO_DOUT,
+                          lrcin=AUDIO_LRCIN, lrcout=AUDIO_LRCOUT, mode=AUDIO_MODE,
+                          csn=AUDIO_CSN, sclk=AUDIO_SCLK, sdin=AUDIO_SDIN)
+    au_bus = Namespace(in_r=au_in_r, in_l=au_in_l, out_r=au_out_r, out_l=au_out_l,
+                       mic_in=mic_in, hp_out=hp_out, Ts=Ts)
 
+    g_aic23 = aic23(clock, reset, au_bus, aic23_bus, tst_pts, ConfigOpt)
+
+    return g_aic23
+
+
+def _convert(ConfigOpt):
+    clock           = Signal(False)
+    reset           = ResetSignal(False, active=0, async=True)
+    au_in_r         = Signal(intbv(0)[32:])     
+    au_in_l         = Signal(intbv(0)[32:])  
+    au_out_r        = Signal(intbv(0)[32:])
+    au_out_l        = Signal(intbv(0)[32:])
+    mic_in          = Signal(intbv(0)[32:])      
+    hp_out          = Signal(intbv(0)[32:])
+    Ts              = Signal(False)
+    AUDIO_BCLK      = Signal(False)
+    AUDIO_DIN       = Signal(False)       
+    AUDIO_DOUT      = Signal(False)      
+    AUDIO_LRCIN     = Signal(False)     
+    AUDIO_LRCOUT    = Signal(False)    
+    AUDIO_MODE      = Signal(False)      
+    AUDIO_CSN       = Signal(False)       
+    AUDIO_SCLK      = Signal(False)       
+    AUDIO_SDIN      = Signal(False)
+    tst_pts         = Signal(intbv(0)[8:])
+
+    toVerilog(aic23_top, clock, reset, au_in_r, au_in_l, au_out_r, au_out_l,
+              mic_in, hp_out, Ts, AUDIO_BCLK, AUDIO_DIN, AUDIO_DOUT,
+              AUDIO_LRCIN, AUDIO_LRCOUT, AUDIO_MODE, AUDIO_CSN,
+              AUDIO_SCLK, AUDIO_SDIN, tst_pts)
+
+    toVHDL(aic23_top, clock, reset, au_in_r, au_in_l, au_out_r, au_out_l,
+           mic_in, hp_out, Ts, AUDIO_BCLK, AUDIO_DIN, AUDIO_DOUT,
+           AUDIO_LRCIN, AUDIO_LRCOUT, AUDIO_MODE, AUDIO_CSN,
+           AUDIO_SCLK, AUDIO_SDIN, tst_pts)
+
+
+def _create_parser():
+    parser = None
+    return parser
+
+if __name__ == '__main__':
+    _convert(Aic23Config(_create_parser()))
 
     

mycores/aic23/aic23_wb_top.py

+from myhdl import *
+
+from aic23 import aic23
+
+# Pin out for different FPGA boards with AIC23
+# [Comment]-------------------------+
+# [FPGA Pin]-------------------+    |
+# [AIC23 Pin]--------------+   |    |
+# [Port Dir]-------+       |   |    |
+# [Signal Name]    |       |   |    |
+#                  |       |   |    |
+# DSPtronics USB FPGA board|   |    |
+#------------------+-------+---+----+---------------------------
+#AUDIO_CLK,        Output: 25  63   This is driven by top-level DCM->DDR flop 
+#AUDIO_BCLK,       Input:  3   85   I2S Serial-bit clock
+#AUDIO_DIN,        Output: 4   62   I2S data out of CODEC
+#AUDIO_DOUT,       Input:  6   66   I2S data in to CODEC
+#AUDIO_LRCIN,      Input:  5   65   I2S DAC-word clock signal
+#AUDIO_LRCOUT,     Input:  7   68   I2S ADC-word clock signal
+#AUDIO_MODE,       Output: 22  69   0 - 2 wire, 1 - SPI
+#AUDIO_CSN,        Output: 21  84   Control Mode chip select
+#AUDIO_SCLK,       Output: 24  78   Control port serial clock
+#AUDIO_SDIN,       Output: 23  79   Control port serial data
+#                  |       |   |    |
+# Altera Cyclone II/III DSP board   |
+#------------------+-------+---+----+---------------------------
+#AUDIO_CLK,        Output: 25  AB3  This is driven by top-level DCM->DDR flop 
+#AUDIO_BCLK,       Input:  3   F3   I2S Serial-bit clock
+#AUDIO_DIN,        Output: 4   J21  I2S data out of CODEC
+#AUDIO_DOUT,       Input:  6   B13  I2S data in to CODEC
+#AUDIO_LRCIN,      Input:  5   W4   I2S DAC-word clock signal
+#AUDIO_LRCOUT,     Input:  7   AB2  I2S ADC-word clock signal
+#AUDIO_MODE,       Output: 22  AA2  0 - 2 wire, 1 - SPI
+#AUDIO_CSN,        Output: 21  AC25 Control Mode chip select
+#AUDIO_SCLK,       Output: 24  R4   Control port serial clock
+#AUDIO_SDIN,       Output: 23  AD2  Control port serial data
+
+
+def aic23_top(
+    # --[System Signals]--
+    clock,   # also known as fclk
+    reset,   # system reset
+    
+    # --[ Wishbone Bus ]--
+    clk_i,          # wishbone clock
+    rst_i,          # wishbone reset 
+    cyc_i,          # cycle
+    stb_i,          # strobe
+    adr_i,          # address
+    we_i,           # write enable
+    sel_i,          # byte select
+    dat_i,          # data input
+    dat_o,          # data output
+    ack_o,          # acknowledge
+
+    
+    # --[ CODEC interface to FPGA logic (audio stream) ]--
+    au_in_r,     # Output: audio in stream to FPGA logic right channel
+    au_in_l,     # Output: audio in stream to FPGA logic left channel
+    au_out_r,    # Input:  audio out stream from FPGA logic right channel
+    au_out_l,    # Input:  audio out stream from FPGA logic left channel
+    mic_in,      # Input:  Mic audio stream
+    hp_out,      # Output: Speaker audio stream
+    Ts,          # Output: Sample rate pulse
+    
+    # --[ External CODEC interface to AIC23, see pinout above comments ]--
+    #AUDIO_CLK,      # Output:   This is driven by top-level DCM->DDR flop 
+    AUDIO_BCLK,      # Input:    I2S Serial-bit clock
+    AUDIO_DIN,       # Output:   I2S data out of CODEC
+    AUDIO_DOUT,      # Input:    I2S data in to CODEC
+    AUDIO_LRCIN,     # Input:    I2S DAC-word clock signal
+    AUDIO_LRCOUT,    # Input:    I2S ADC-word clock signal
+    AUDIO_MODE,      # Output:   0 - 2 wire, 1 - SPI
+    AUDIO_CSN,       # Output:   Control Mode chip select
+    AUDIO_SCLK,      # Output:   Control port serial clock
+    AUDIO_SDIN,      # Output:   Control port serial data
+    tst_pts,         # Output:   test points
+
+    # --[ Parameters ]--
+    C_WB_ADDR = 0x1000
+    ):
+    """AIC23 interface
+    This module contains the logic to configure the AIC23 in a default mode
+    and transfer audio to and fro.
+    """
+
+    fclk = clock
+
+
+    

mycores/aic23/test_aic23.py

 
 from myhdl import *
-from aic23 import *
+from aic23_top import aic23_top
+from i2s_model import i2s_model
 
 
-
-if __name__ == '__main__':
-    clk             = Signal(False)
-    rst             = Signal(False)
+def test_aic23():
+    
+    clock           = Signal(False)
+    reset           = ResetSignal(True, active=0, async=True)
     au_in_r         = Signal(intbv(0)[32:])     
     au_in_l         = Signal(intbv(0)[32:])  
     au_out_r        = Signal(intbv(0)[32:])
     AUDIO_CSN       = Signal(False)       
     AUDIO_SCLK      = Signal(False)       
     AUDIO_SDIN      = Signal(False)
-    tst_pts         = Signal(intbv(0)[6:])
+    tst_pts         = Signal(intbv(0)[8:])
 
-    toVerilog(aic23, clk, rst, au_in_r, au_in_l, au_out_r, au_out_l,
-              mic_in, hp_out, Ts, AUDIO_BCLK, AUDIO_DIN, AUDIO_DOUT,
-              AUDIO_LRCIN, AUDIO_LRCOUT, AUDIO_MODE, AUDIO_CSN,
-              AUDIO_SCLK, AUDIO_SDIN, tst_pts)
+    auir, auil = [Signal(intbv(0)[32:]) for ii in (0,1)]
+    auor, auol = [Signal(intbv(0)[32:]) for ii in (0,1)]
+
+    def _test_aic():
+        
+        tb_i2s = i2s_model(AUDIO_LRCIN, AUDIO_LRCOUT, AUDIO_BCLK,
+                           AUDIO_DIN, AUDIO_DOUT,
+                           auir, auil, auor, auol)
+        tb_dut = aic23_top(clock, reset, au_in_r, au_in_l, 
+                       au_out_r, au_out_l, mic_in, hp_out, Ts,
+                       AUDIO_BCLK, AUDIO_DIN, AUDIO_DOUT, 
+                       AUDIO_LRCIN, AUDIO_LRCOUT, AUDIO_MODE,
+                       AUDIO_CSN, AUDIO_SCLK, AUDIO_SDIN, tst_pts)
+
+        @always(delay(2))
+        def tb_clkgen():
+            clock.next = not clock
+
+        @always(delay(200))
+        def tb_bclkgen():
+            AUDIO_BLCK.next = not AUDIO_BCLK
+
+        @instance
+        def tb_stimulus():
+            reset.next = False
+            yield delay(100)
+            reset.next = True
+            yield clock.posedge
+
+            for ii in range(333):
+                yield delay(2000)
+
+            raise StopSimulation
+            
+        return tb_stimulus, tb_clkgen, tb_i2s, tb_dut
+
+    Simulation(traceSignals(_test_aic)).run()
+
+
+if __name__ == '__main__':
+    test_aic23()