Commits

Christopher Felton  committed 47c00a8 Merge

merged

  • Participants
  • Parent commits 3c0fa12, f37afbf

Comments (0)

Files changed (8)

File mycores/aic23/__init__.py

+
+from aic23 import *

File mycores/aic23/aic23.py

+
+
+from myhdl import *
+
+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
+
+    # --[ Parameters ]--
+    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:])
+
+
+
+    @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
+
+        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)
+
+        
+    
+    return g_
+
+
+    
+
+
+    
+

File mycores/aic23/aic23_i2s.py

+
+
+from myhdl import *
+
+def aic23_i2s(
+    clk,
+    rst,
+
+    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
+    ):
+
+
+    shift_in  = Signal(intbv(0)[66:])
+    shift_out = Signal(intbv(0)[66:])
+
+    _bclk, bclk_n, bclk_p = (Signal(False) for ii in range(3))
+    _dout, dout_n, dout_p = (Signal(False) for ii in range(3))
+    _lout, lrcout_n, lrcout_p = (Signal(False) for ii in range(3))
+
+    _lin = Signal(False)
+    lrcin_n = Signal(False)
+    lrcin_p = Signal(False)
+
+    __lin  = Signal(False)
+    __lout = Signal(False)
+    __dout = Signal(False)
+    __bclk = Signal(False)
+    
+    cnt = Signal(intbv(0, max=36, min=0))
+    en_cnt = Signal(False)
+    
+    # State types
+    _s     = enum('LEFT_CH_START',   # Falling edge LRCOUT
+                  'LEFT_CH_AUDIO',   # Get data enable counter
+                  'RIGHT_CH_START',  # Rising edge LRCOUT
+                  'RIGHT_CH_AUDIO',  # Right channel audio data
+                  )
+    state  = Signal(_s.LEFT_CH_START)
+
+
+    @always(clk.negedge)
+    def rtl_syncdn():
+        __bclk.next = bclk
+        __dout.next = dout
+        __lin.next  = lrcin
+        __lout.next = lrcout
+
+    @always(clk.posedge)
+    def rtl_syncdu():        
+        _bclk.next = __bclk
+        _dout.next = __dout
+        _lin.next  = __lin
+        _lout.next = __lout
+
+
+    @always_comb
+    def rtl_syncor():
+        bclk_n.next = _bclk and not bclk
+        bclk_p.next = not _bclk and bclk
+
+        dout_n.next = _dout and not dout
+        dout_p.next = not _dout and dout
+
+        lrcin_n.next = _lin and not lrcin
+        lrcin_p.next = not _lin and lrcin
+
+        lrcout_n.next = _lout and not lrcout
+        lrcout_p.next = not _lout and lrcout
+
+
+    @always_comb
+    def rtl_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():
+        if bclk_p and en_cnt:
+            shift_in.next = concat(shift_in[65:0], _dout)
+
+        if Ts:
+            au_in_l.next = shift_in[65:33]  # bit 65 don't care
+            au_in_r.next = shift_in[32:0]   # bit 32 don't care
+
+
+    @always(clk.posedge)
+    def rtl_au_out():
+        if Ts:
+            shift_out.next = concat(au_out_l[31], au_out_l,
+                                    au_out_r[31], au_out_r)
+        elif bclk_n and en_cnt:
+            shift_out.next = concat(shift_out[65:0], intbv(0)[1:] )
+
+
+    @always(clk.posedge)
+    def rtl_sm():
+        if rst:
+            state.next = _s.LEFT_CH_START
+            cnt.next   = 0
+            en_cnt.next = False
+        else:
+            if state == _s.LEFT_CH_START:
+                if lrcin_n:
+                    state.next  = _s.LEFT_CH_AUDIO
+                    en_cnt.next = True
+                    
+            elif state == _s.LEFT_CH_AUDIO:
+                if cnt == 33:
+                    state.next  = _s.RIGHT_CH_START
+                    en_cnt.next = False
+                    
+            elif state == _s.RIGHT_CH_START:
+                if lrcin_p:
+                    state.next = _s.RIGHT_CH_AUDIO
+                    en_cnt.next = True
+                    
+            elif state == _s.RIGHT_CH_AUDIO:
+                if cnt == 33:
+                    state.next = _s.LEFT_CH_START
+                    en_cnt.next = False
+            else:
+                state.next = _s.LEFT_CH_START
+                #raise ValueError('Undefined State')
+
+
+            if en_cnt and bclk_p:
+                cnt.next = cnt + 1
+            else:
+                cnt.next = 0
+
+
+    @always_comb
+    def rtl_tst_pts():
+        tst_pts.next[0]   = bclk
+        tst_pts.next[1]   = lrcin
+        tst_pts.next[2]   = lrcout
+        tst_pts.next[3]   = din
+        tst_pts.next[4]   = dout
+
+
+    return instances()
+

File mycores/aic23/aic23_register_def.py

+
+from myhdl import *
+import open_cores.register_file as RF
+
+
+RegDef = RF.regdict()
+
+
+#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# AIC23 Control Register
+RegDef["AICR"] = {"addr" : 0x00, "width" : 8, "type" : "rw",
+                  "bits" : {},
+                  "default" : 0x80,  # wb_sel = 1
+                  "comment" : "AIC23 Control register"
+                  }
+RegDef["AICR"]["bits"] = RF.odict(); bits = RegDef["AICR"]["bits"]
+bits["WB_SEL"] = {"b" : 7, "width" : 1, "comment" : "1 = Wishbone bus feeds the TX/RX FIFO.\n"  + 
+                                                    "0 = Streaming iterface supplies the FIFOs"}
+bits["LOOP"]   = {"b" : 1, "width" : 1, "comment" : "Internal loopback"} 
+bits["EN"]     = {"b" : 0, "width" : 1, "comment" : "Enable AIC23 interface"}
+
+#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# AIC23 Status Register
+RegDef["AISR"] = {"addr" : 0x04, "width" : 8, "type" : "ro",
+                  "bits" : {"mode"   : {"b" : 0, "width" : 1, "comment" : "AIC23 interface mode"} ,
+                            },
+                  "default" : 0x00,  
+                  "comment" : "AIC23 Status register"
+                  }
+
+# These are shadows of the AIC23 configuration registers, the top 7 msb
+# are the address and the bottom 9 lsb bits are the configuraiton bits
+# Registers (X no initialize, I init == value)
+#
+# 0000000 -- Left line input channel volume control   X == 
+# 0000001 -- Right line input channel volumen control X == 
+# 0000010 -- Left channel headphone volume control    X == 
+# 0000011 -- Right channel headphone volume control   X == 
+# 0000100 -- Analog audio path control                X ==
+# 0000101 -- Digital Audio path control               X ==
+# 0000110 -- Power Down Control                       X ==
+# 0000111 -- Digital Audio Interface Format           X ==
+# 0001000 -- Sample Rate Control                      I == 00 01110 1
+# 0001001 -- Digtial Interface Activation             X ==
+# 0001111 -- Reset Register                           X ==
+
+#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# Left Volume Control
+RegDef["LVC"]  = {"addr" : 0x20, "width" : 8, "type" : "rw",
+                  "bits" : {},  # Bit definition follow register definition                  
+                  "default" : "000_0000" + "0_0001_0111",  
+                  "comment" : "Left line input channel volume control"
+                  }
+# Bit defitions, it is convinient to use an order dict for the bit defitions as well
+RegDef["LVC"]["bits"] = RF.odict(); bits = RegDef["LVC"]["bits"]
+bits["LRS"] = {"b" : 8, "width" : 1,
+               "comment" : "Left/right line simultaneous volume/mute update \n" +
+               "0=Disable  1=Enable"}
+bits["LIM"] = {"b" : 7, "width" : 1,
+               "comment" : "Left line input mute  0=Normal  1=Muted"}
+bits["LIV"] = {"b" : range(5), "width" : 5,
+               "comment" : "Left line input volume control (10111 = 0dB default\n" +
+               "11111=+12dB down to 00000=-34dB in 1.5dB steps"} 
+
+#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# Right Volume Control
+RegDef["RVC"]  = {"addr" : 0x22, "width" : 8, "type" : "rw",
+                  "bits" : {},
+                  "default" : "_0001_0111",  #"000_0001" + "0
+                  "comment" : "Right line input channel volume control"
+                  }
+RegDef["RVC"]["bits"] = RF.odict(); bits = RegDef["RVC"]["bits"]
+bits["RLS"] = {"b" : 8, "width" : 1,
+               "comment" : "Right/left line simultaneous volume/mute update \n" +
+               "0=Disable  1=Enable"}
+bits["RIM"] = {"b" : 7, "width" : 1,
+               "comment" : "Right line input mute\n  0=Normal  1=Muted"}
+bits["RIV"] = {"b" : range(5), "width" : 5,
+               "comment" : "Left line input volume control (10111 = 0dB default\n" +
+               "11111=+12dB down to 00000=-34dB in 1.5dB steps"} 
+
+#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# Left Headphone Control
+RegDef["LHC"]  = {"addr" : 0x24, "width" : 8, "type" : "rw",
+                  "bits" : {},
+                  "default" : "_0000_0000",  #"000_0010" + "0
+                  "comment" : "Left channel headphone volume control"
+                  }
+RegDef["LHC"]["bits"] = RF.odict(); bits = RegDef["LHC"]["bits"]
+bits["LRS"] = {"b" : 8, "width" : 1,
+               "comment" : "Left/right headphone channel simultaneious volume/mute udpate\n" +
+                           "0 = Disable  1 = Enable"}
+bits["LZC"] = {"b" : 7, "width" : 1,
+               "comment" : "Left-channel zero-cross detect\n"
+                           "0 = Off  1 = On"}
+bits["LHV"] = {"b" : range(7), "width" : 6,
+               "comment" : "Left headphone volume control (1111001 = 0db default)\n" +
+                           "1111111 = +6 db, 79 steps between +6 dB and -73 db (mute), 0110000 = -73 db (mute)\n" +
+                           "anything below 0110000 does nothing, still muted"}
+
+#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# Right Headphone Control
+RegDef["RHC"]  = {"addr" : 0x26, "width" : 8, "type" : "rw",
+                  "bits" : {},
+                  "default" : "_0000_0000",  #"000_0011" + "0
+                  "comment" : "Right channel headphone volume control"
+                  }
+RegDef["RHC"]["bits"] = RF.odict(); bits = RegDef["RHC"]["bits"]
+bits["RLS"] = {"b" : 8, "width" : 1,
+               "comment" : "Right/left headphone channel simultaneious volume/mute udpate\n" +
+                           "0 = Disable  1 = Enable"}
+bits["RZC"] = {"b" : 7, "width" : 1,
+               "comment" : "Right-channel zero-cross detect\n"
+                           "0 = Off  1 = On"}
+bits["RHV"] = {"b" : range(7), "width" : 6,
+               "comment" : "Right headphone volume control (1111001 = 0db default)\n" +
+                           "1111111 = +6 db, 79 steps between +6 dB and -73 db (mute), 0110000 = -73 db (mute)\n" +
+                           "anything below 0110000 does nothing, still muted"}
+
+
+#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# Analog audio control
+RegDef["AAC"]  = {"addr" : 0x28, "width" : 8, "type" : "rw",
+                  "bits" : {},
+                  "default" : "_0001_1010",  #"000_0100" + "0
+                  "comment" : "Analog audio path control"
+                  }
+RegDef["AAC"]["bits"] = RF.odict(); bits = RegDef["AAC"]["bits"]
+bits["STA"]   = {"b" : range(6,9), "width" : 3, "comment" : "Side-tone attenuation"}
+bits["STE"]   = {"b" : 5, "width" : 1, "comment" : "Side-tone enable"}
+bits["DAC"]   = {"b" : 4, "width" : 1, "comment" : "DAC Select 0 = DAC off  1 = DAC selected"}
+bits["BYP"]   = {"b" : 3, "width" : 1, "comment" : "Bypass 0 = Disabled  1 = Enabled"}
+bits["INSEL"] = {"b" : 2, "width" : 1, "comment" : "Input select for ADC 0 = line  1 = Microphone"}
+bits["MICM"]  = {"b" : 1, "width" : 1, "comment" : "Microphone mute 0 = Normal  1 = Muted"}
+bits["MICB"]  = {"b" : 0, "width" : 1, "comment" : "Microphone boost 0 = db  1 = 20dB"}
+
+
+#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# Digital audio control
+RegDef["DAC"]  = {"addr" : 0x2A, "width" : 8, "type" : "rw",
+                  "bits" : {},
+                  "default" : "_0000_0000",  #"000_0101" + "0
+                  "comment" : "Digital audio path control"
+                  }
+RegDef["DAC"]["bits"] = RF.odict(); bits = RegDef["DAC"]["bits"]
+bits["DACM"]  = {"b" : 3, "width" : 1, "comment" : "DAC soft mute 0 = Disalbe  1 = Enable"}
+bits["DEEMP"] = {"b" : range(1,3), "width" : 2,
+                 "comment" : "De-emphasis control\n" +
+                             "0 = Disable  1 = 32kHz  2 = 44.1kHz  3 = 48kHz"}
+bits["ADCHP"] = {"b" : 0, "width" : 1, "comment" : "ADC high-pass filter"}
+
+#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# Power Down Control
+RegDef["PDC"]  = {"addr" : 0x2C, "width" : 8, "type" : "rw",
+                  "bits" : {},
+                  "default" : "_0000_0010",  #"000_0110" + "0
+                  "comment" : "Power down control"
+                  }
+RegDef["PDC"]["bits"] = RF.odict(); bits = RegDef["PDC"]["bits"]
+bits["OFF"]  = {"b" : 7, "width" : 1, "comment" : "Device power"}
+bits["CLK"]  = {"b" : 6, "width" : 1, "comment" : "Clock"}
+bits["OSC"]  = {"b" : 5, "width" : 1, "comment" : "Oscillator"}
+bits["OUT"]  = {"b" : 4, "width" : 1, "comment" : "Outputs"}
+bits["DAC"]  = {"b" : 3, "width" : 1, "comment" : "DAC"}
+bits["ADC"]  = {"b" : 2, "width" : 1, "comment" : "ADC"}
+bits["MIC"]  = {"b" : 1, "width" : 1, "comment" : "Microphone input"}
+bits["LINE"] = {"b" : 0, "width" : 1, "comment" : "Line input"}
+
+
+#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# Digital Audio Interface Format
+RegDef["DAF"]  = {"addr" : 0x2E, "width" : 8, "type" : "rw",
+                  "bits" : {},
+                  "default" : "_0100_1110",  #"000_0111" + "0
+                  "comment" : "Digital audio interface format"
+                  }
+RegDef["DAF"]["bits"] = RF.odict(); bits = RegDef["DAF"]["bits"]
+bits["MS"]     = {"b" : 6, "width" : 1, "comment" : "Master/slave mode"}
+bits["LRSWAP"] = {"b" : 5, "width" : 1, "comment" : "DAC lef/right swap"}
+bits["LRP"]    = {"b" : 4, "width" : 1, "comment" : "DAC left/right phase"}
+bits["IWL"]    = {"b" : range(2,4), "width" : 2,
+                  "comment" : "Input bit length\n" +
+                  " 00 = 16  01 = 20  10=24  11 = 32"}
+bits["FOR"]    = {"b" : range(2), "width" : 2,
+                  "comment" : "Data format\n" +
+                  "3 = DSP format, frame sync followed by two data words\n"+
+                  "2 = I2S format, MSB first, left-1 aligned\n"+
+                  "1 = MSB first, left aligned\n"+
+                  "0 = MSB first, right aligned"}
+
+#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# Sample Rate Control
+RegDef["SRC"]  = {"addr" : 0x30, "width" : 8, "type" : "rw",
+                  "bits" : {},
+                  "default" : "_1001_1101",  #"000_1000" + "0
+                  "comment" : "Sample rate control"
+                  }
+RegDef["SRC"]["bits"] = RF.odict(); bits = RegDef["SRC"]["bits"]
+
+bits["CLKOUT"] = {"b" : 7, "width" : 1, "comment" : "clock output divider, 1 = MCLK/2"}
+bits["CLKIN"]  = {"b" : 6, "width" : 1, "comment" : "clock input divider, 1 = MCLK/2"}
+bits["SR"]     = {"b" : range(2,6), "width" : 4, "comment" : "Sampling rate control, see datasheet"}
+bits["BOSR"]   = {"b" : 1, "width" : 1, "comment" : "Base oversample rate, see datasheet"}
+bits["USB"]    = {"b" : 0, "width" : 1, "comment" : "Clock mode select"}
+
+
+#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# Digital Interface Activation
+RegDef["DIA"]  = {"addr" : 0x32, "width" : 8, "type" : "rw",
+                  "bits" : {},
+                  "default" : "_0000_0001",  #"000_1001" + "0
+                  "comment" : "Digital interface activation"
+                  }
+RegDef["DIA"]["bits"] = RF.odict(); bits = RegDef["DIA"]["bits"]
+bits["ACT"] = {"b" : 0, "width" : 1, "comment" : "Activate interface 1 = Active"}
+
+
+#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# Reset Regester
+RegDef["RST"]  = {"addr" : 0x34, "width" : 8, "type" : "rw",
+                  "bits" : {},
+                  "default" : "_0000_0000",  #"000_1111" + "0
+                  "comment" : "Reset register, write 0 to this register to trigger a reset"
+                  }
+RegDef["RST"]["bits"] = RF.odict(); bits = RegDef["RST"]["bits"]
+
+#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# Program Configuration Register
+RegDef["PGM"]  = {"addr" : 0x36, "width" : 8, "type" : "rw",
+                  "bits" : {},
+                  "default" : "_0000_0000",  #"000_0000" + "0
+                  "comment" : "Program the configuration"
+                  }
+RegDef["PGM"]["bits"] = RF.odict(); bits = RegDef["PGM"]["bits"]
+bits["go"] = {"b" : 0, "width" : 1, "comment" : "1 = Program the configuration\n" +
+                                              "0 = No action"}
+
+
+
+
+unused = RF.GetRegisterFileSignals(RegDef)
+
+# List of Signals (Register File) index for each register
+aicr_i = RegDef['AICR']['index']
+aisr_i = RegDef['AICR']['index']
+lvc_i  = RegDef['LVC']['index']
+rvc_i  = RegDef['RVC']['index']
+lhc_i  = RegDef['LHC']['index']
+rhc_i  = RegDef['RHC']['index']
+aac_i  = RegDef['AAC']['index']
+dac_i  = RegDef['DAC']['index']
+pdc_i  = RegDef['PDC']['index']
+daf_i  = RegDef['DAF']['index']
+src_i  = RegDef['SRC']['index']
+dia_i  = RegDef['DIA']['index']
+rrst_i = RegDef['RST']['index']
+pgm_i  = RegDef['PGM']['index']
+
+
+
+
+
+
+

File mycores/aic23/aic23_setup.py

+#
+#
+
+from myhdl import *
+from aic23_spi import *
+
+def aic23_setup(
+    clock,
+    reset,
+    
+    AUDIO_CSN,
+    AUDIO_SCLK,
+    AUDIO_SDIN,
+
+    # Configuration Parameters
+    ConfigOpt
+    ):
+    """ Static setup / configuration for the AIC23 CODEC
+
+    This module will generate the correct register settings based
+    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 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
+
+
+    # State types
+    _s     = enum('IDLE', 'RGO', 'BDLY', 'WAIT', 'INC', 'END')
+    state  = Signal(_s.IDLE)
+
+    aic_c      = Signal(intbv(0)[16:])  # control data
+    aic_c_go   = Signal(False)          # send control data
+    aic_c_busy = Signal(False)          # sending data
+    
+    _go        = Signal(False)
+    reg_cnt    = Signal(intbv(0)[4:])
+
+    pgm        = Signal(False)
+    pgm_trans  = Signal(False)
+    pgm_rst    = Signal(False)
+
+    @always(clk.posedge)
+    def rtl_pgm():
+        if rst:
+            pgm.next = PGM[0]
+            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
+        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
+
+            elif state == _s.BDLY:
+                aic_c_go.next = False
+                state.next = _s.WAIT
+
+            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,
+                    AUDIO_CSN, AUDIO_SCLK, AUDIO_SDIN)
+
+
+    return instances()

File 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()

File mycores/aic23/aic23_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
+
+
+    

File mycores/aic23/test_aic23.py

+
+from myhdl import *
+from aic23 import *
+
+
+
+if __name__ == '__main__':
+    clk             = Signal(False)
+    rst             = Signal(False)
+    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)[6:])
+
+    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)