From Python to silicon
 

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

projects:sdx1000 [2006/11/14 11:28]
themaxx
projects:sdx1000 [2006/11/15 01:36] (current)
themaxx
Line 1: Line 1:
-<code python> +moved to dsx1000
-"""                                                                             +
- dac_sdx1000_hd.py +
- First-order Sigma Delta DAC with variable bit-width +
- +
- MyHDL implementation by George Pantazopoulos http://www.gammaburst.net    +
- Nov 2006 +
-""" +
-from myhdl import * +
-from math import log, ceil +
- +
-# ---------------------------------------------------------------------------- +
- +
-def dac_sdx1000(clk_i, rst_i, pcm_i, pdm_o): +
-    """ +
-    GJP Enterprises SDX1000  +
-    Multiplatform First-order Sigma Delta DAC core with variable bit width. +
-     +
-    Tested successfully on a Xilinx Spartan3 FPGA. +
-         +
-    Inputs: +
-    clk_i   clock (The faster, the better!) +
-    rst_i   active high reset +
-    pcm_i   digital PCM value to convert to PDM stream (adjustable width) +
-     +
-    Outputs: +
-    pdm_o   Pulse-density modulated bitstream. Range [0,1] +
-     +
-    To complete the DAC, an external RC analog low-pass filter at the output  +
-    is usually needed. +
-    See XAPP154 for more information. +
-     +
-    Sources: +
-    http://www.beis.de/Elektronik/DeltaSigma/DeltaSigma.html +
-    Xilinx Application Note XAPP154. +
-    """ +
-     +
-    __author__    = "George Pantazopoulos http://www.gammaburst.net" +
-    __version__   = "1.0.1" +
-    __revision__  = "" +
-    __date__      = "13 Nov 2006"     +
-     +
-    RES = len(pcm_i) +
- +
-    DREF_NEG =  0 +
-    DREF_POS =  (2**RES)-1 +
-     +
-    MIN = -2**(RES-1) +
-    MAX = +2**(RES-1) +
-     +
-    diff_o  = Signal(intbv(0, min=4*MIN, max=4*MAX)) +
-    adder_o = Signal(intbv(0, min=4*MIN, max=4*MAX)) +
-    reg_o   = Signal(intbv(0, min=4*MIN, max=4*MAX)) +
-    comp_o  = Signal(bool(0)) +
-    ddc_o   = Signal(intbv(0, min=4*MIN, max=4*MAX)) +
-         +
-    # Difference block ("Delta") +
-    @always_comb +
-    def Difference(): +
-        diff_o.next = pcm_i - ddc_o +
-         +
-    # The adder and register blocks comprise the integrator ("Sigma") +
-    # Adder block +
-    @always_comb +
-    def Adder(): +
-        adder_o.next = diff_o + reg_o +
-     +
-    # Register block +
-    @always(clk_i.posedge) +
-    def Reg(): +
-        if rst_i: +
-            reg_o.next = 0 +
-        else: +
-            reg_o.next = adder_o +
-     +
-    # Comparator block +
-    @always_comb +
-    def Comparator(): +
-        if reg_o > 0:  +
-            comp_o.next = 1 +
-        else: +
-            comp_o.next = 0 +
-         +
-    # 1-bit Digital-digital conveter +
-    # Creates a signed value from the comparator output +
-    @always_comb +
-    def DDC(): +
-         +
-        if comp_o: +
-            ddc_o.next = DREF_POS +
-        else: +
-            ddc_o.next = DREF_NEG +
-         +
-    # Bitstream output +
-    @always(clk_i.posedge) +
-    def BitStreamOut(): +
-        if rst_i: +
-            pdm_o.next = 0 +
-        else: +
-            pdm_o.next = comp_o +
-     +
-    return instances() +
- +
-# ---------------------------------------------------------------------------- +
- +
-def ToneOsc(clk_i, rst_i, freq_i, pcm_o, ACCUM_WIDTH=24): +
-    """ +
-    Phase-Accumulating tone oscillator +
-    """ +
-    OUTPUT_WIDTH = len(pcm_o) +
-     +
-    # Phase Accumulator +
-    accum = Signal(intbv(0)[ACCUM_WIDTH:]) +
- +
-    # At each clock, increment the accumulator by the value of freq_i +
-    @always(clk_i.posedge) +
-    def accumDrive(): +
-        if rst_i: +
-            accum.next = 0 +
-        else: +
-            accum.next = (accum + freq_i) % 2**ACCUM_WIDTH +
- +
-    # Take the top N significant bits of the accumulator as the PCM output +
-    @always_comb +
-    def pcmOut(): +
-        pcm_o.next = accum[ACCUM_WIDTH:ACCUM_WIDTH-OUTPUT_WIDTH] +
- +
-    return instances() +
- +
-# ---------------------------------------------------------------------------- +
- +
-def top(clk, pdm_o, CLK_HZ): +
-    """ +
-    Test Harness for Sigma-Delta DAC +
-    """ +
-     +
-    OUTPUT_FREQ_HZ = 440 +
-    ACCUM_WIDTH = 24 +
-     +
-    # Compute some constants +
-    ONE_HZ_FVAL = CLK_HZ / float(2**ACCUM_WIDTH) +
-    FVAL = int(ceil(440 * ONE_HZ_FVAL)) +
-     +
-    print "CLK_HZ = ", CLK_HZ +
-    print "OUTPUT_FREQ_HZ = ", OUTPUT_FREQ_HZ +
-    print "FVAL = ", FVAL +
- +
-    pcm_audio = Signal(intbv(0)[8:]) +
-     +
-    OSC = ToneOsc(clk_i=clk, +
-                  rst_i=False, +
-                  freq_i=FVAL, +
-                  pcm_o = pcm_audio, +
-                  ACCUM_WIDTH=24) +
-     +
-    DAC = dac_sdx1000(clk_i=clk, rst_i=False, pcm_i=pcm_audio, pdm_o=pdm_o) +
-     +
-    return instances() +
- +
-# ---------------------------------------------------------------------------- +
- +
-CLK_HZ = 16000000 +
- +
-clk   = Signal(bool(0)) +
-pdm_o = Signal(bool(0)) +
- +
-toVerilog.name = "dac_sigma_delta" +
-toVerilog(top, clk, pdm_o, CLK_HZ) +
- +
-# ---------------------------------------------------------------------------- +
-def bench_static(): +
-    """ +
-    Static value test +
-    """ +
-     +
-    DAC_RES = 8 +
-     +
-    clk   = Signal(bool(0)) +
-    dat_i = Signal(intbv(0, min=0, max=2**DAC_RES)) +
-    pdm_o = Signal(bool(0)) +
-     +
-    @always(delay(10)) +
-    def clkgen(): +
-        clk.next = not clk +
- +
-    dac_inst = dac_sdx1000(clk_i=clk,  +
-                           rst_i=False,  +
-                           pcm_i=dat_i,  +
-                           pdm_o=pdm_o) +
-     +
-    RUN_STEPS = 64 +
-     +
-    # dac input values (relative to full scale) +
-     +
-    relv = [0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0] +
-    dac_values = list() +
- +
-    for v in relv: +
-         +
-        dac_code = int(v * 2**DAC_RES) +
-      +
-        if dac_code == 2**DAC_RES: +
-            dac_code = 2**DAC_RES-1 +
-        elif dac_code > 2**DAC_RES: +
-            raise Exception +
-         +
-        dac_values.append(dac_code) +
-         +
-    @instance +
-    def stimulus(): +
-         +
-        for dac_value in dac_values: +
-            for i in range(RUN_STEPS): +
-                 +
-                yield clk.negedge +
-                dat_i.next = dac_value +
-                yield clk.posedge +
-         +
-        raise StopSimulation +
-             +
-    @instance +
-    def monitor(): +
-        print "DAC_RES   = ", DAC_RES +
-        print "RUN_STEPS = ", RUN_STEPS +
-         +
-        for dac_value in dac_values: +
-             +
-            pdm_accum = 0 +
-            pdm_avg   = 0.0 +
-             +
-            for i in range(RUN_STEPS): +
-                yield clk.posedge +
-                pdm_accum += pdm_o +
-                #print pdm_o +
-                 +
-            pdm_avg = float(pdm_accum) / float(RUN_STEPS) +
-            print "dac_value = %s, pdm_avg = %s" % (dac_value, pdm_avg) +
-     +
-    return clkgen, dac_inst, stimulus, monitor +
- +
-# ---------------------------------------------------------------------------- +
- +
-def test_static(): +
-    sim = Simulation(bench_static()) +
-    sim.run() +
- +
-if __name__ == '__main__': +
-    test_static() +
-     +
-</code>+
projects/sdx1000.txt · Last modified: 2006/11/15 01:36 by themaxx
 
Except where otherwise noted, content on this wiki is licensed under the following license: CC Attribution-Share Alike 3.0 Unported
Recent changes RSS feed Donate Powered by PHP Valid XHTML 1.0 Valid CSS Driven by DokuWiki