How to implement a pipeline...??? Please help

R

Ritchy lelis

Hi guys

In the development of my ADC project i have a new new challenge.

First i need to implement a 10 Bit pipelineADC that will be the
basis to later implement any kind of pipeline arquitecture (i mean,
with 10 Bit, 16 Bit or any other configuration i want) i wish to...

What's a 10 Bit pipiline ADC?

This link with a draw will help have a perfect view of what is it:
http://t3.gstatic.com/images?q=tbn:...MdTOa4&t=1&usg=__-TsH7dnNdJm4GZTuWCxjvajZhfk=

To have a 10 Bit pipiline ADC we need 9 stages, where 8 of them are a
1.5 bit configuration and the last one have a 2 Bit configuration.

How it works?

When we inject a input voltage (at the first block), it will be
computed in the first 1.5 Bit stage and when finished the compute it
will generate a output voltage who served of input voltage for the
second 1.5 Bit stage which in his turn generate also a output voltage
who served of input voltage in the third stage ... and successively
continuing until the ninth stage. The ninth stage it's a 2 Bit stage
and it will receive the last output voltage from the eighth stage and
in his turn it will compute a final output signal.

I already implemented the 1.5 Bit/stage and the 2 Bit/stage functions
with good results (i already watch their plot's and they are cool to
me) but my Pipeline function try don't seems that good.

After the 2 Bit compute i expect a output signal like the drawing on
the link below but more stretched.
http://t3.gstatic.com/images?q=tbn:...fu9RQA&t=1&usg=__-yHJFMatnCPcf9jWQv3kaxM0brE=

Instead of have a lot of steps one after the another, it will have
something like a single step only. Why? That it's because when we have
a pipeline with a lot of stage's the final output voltage until the 2
Bit stage it's very "dense" and long and that nearly saturating the
last block ( the 2 Bit stage).

Next i will leave the code that I have done so far for my Pipeline
function:

-------------------------------------------------------------------------------------------------------------------------------------------------------------------
-------------------------------------------------------------------------------------------------------------------------------------------------------------------

from flash1b5 import flash1b5
from flash1b5 import *
from flash2b import flash2b
from flash2b import *
import matplotlib.pyplot as plt
import numpy as np
from pylab import *

if __name__ == "__main__":

Inc = raw_input("Valor do Incrimento = ")

Vref = np.linspace(1,1, Inc)
Vi = np.linspace(-1,1, Inc)

Cs = np.linspace(3e-12, 3e-12, Inc)
Cf = np.linspace(3e-12, 3e-12, Inc)

f1 = flash1b5(Vi, Vref, Cs, Cf)

Vin1 = f1[0]
Vt1 = f1[1]
Vd1 = f1[2]


f2b = flash2b(Vt1, Vref)

Vin2 = f2b[0]
Vd2 = f2b[1]


hold(True)

fig2 = figure(1,figsize=(8,5))
ax2 = fig2.add_subplot(111, autoscale_on=False, xlim=(-1,1),
ylim=(-0.5,2.5))
ax2.plot(Vin2, Vd2, lw=2, color='blue')
grid (True); xlabel('V_ent');ylabel('Vout_Digital')


plt.show()
-------------------------------------------------------------------------------------------------------------------------------------------------------------------

The 1.5 Bit function:

import numpy as np
from pylab import *


def flash1b5(Vi, Vref, Cs, Cf):

Vin = np.zeros(Vi.shape, dtype=np.float)
Vt = np.zeros(Vi.shape, dtype=np.float)
Vd = np.zeros(Vi.shape, dtype=np.float)

if any(Vi > Vref/4):
mask1 = (Vi > Vref/4)
np.putmask(Vin, mask1, Vi)
Vs= (1+Cs/Cf)*Vin - (Cs/Cf)*Vref
np.putmask(Vd, mask1, [2])
np.putmask(Vt, mask1, Vs)

##
if any(-Vref/4 <= Vi) and any( Vi<= Vref/4):
mask2 = (-Vref/4 <= Vi) & (Vi <= Vref/4)
np.putmask(Vin, mask2, Vi)
Vs = (1+(Cs/Cf))*Vin
np.putmask(Vd, mask2, [1])
np.putmask(Vt, mask2, Vs)

##
if any(Vi < -Vref/4):
mask3 = (Vi < -Vref/4)
np.putmask(Vin, mask3, Vi)
Vs= (1+Cs/Cf)*Vin + (Cs/Cf)*Vref
np.putmask(Vd, mask3, [0])
np.putmask(Vt, mask3, Vs)

##
out = [Vin, Vt, Vd]
return out
-------------------------------------------------------------------------------------------------------------------------------------------------------------------

The 2 Bit function:

import numpy as np
from pylab import *


def flash2b(Vi, Vref):

Vin = np.zeros(Vi.shape, dtype=np.float)
Vt = np.zeros(Vi.shape, dtype=np.float)
Vd = np.zeros(Vi.shape, dtype=np.float)

if any(Vi > Vref/2):
mask1 = (Vi > Vref/2)
np.putmask(Vin, mask1, Vi)
np.putmask(Vd, mask1, [3])

if any(Vi > 0) and any(Vref/2 >= Vi):
mask2 = (Vref/2 >= Vi) & (Vi > 0)
np.putmask(Vin, mask2, Vi)
np.putmask(Vd, mask2, [2])

if any(Vi <= 0) and any(-Vref/2 < Vi):
mask3 = (-Vref/2 < Vi) & (Vi <= 0)
np.putmask(Vin, mask3, Vi)
np.putmask(Vd, mask3, [1])

if any(Vi <= -Vref/2):
mask4 = (Vi < -Vref/2)
np.putmask(Vin, mask4, Vi)
np.putmask(Vd, mask4, [0])

S_Out = [Vin, Vd]

return S_Out
---------------------------------------------------------------------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------------------------------------------------------------------------

Guys i'm asking if it's possible for a generic function for a
pipeline, all the suggestions ideas are welcome.

Also if you have a specific solution for my problem I will be grateful
for it here.

Thanks for reading my post.

Cheers
 
D

Dennis Lee Bieber

Guys i'm asking if it's possible for a generic function for a
pipeline, all the suggestions ideas are welcome.
I've not done metaclasses, so don't know if a metaclass would be of
use... Since it appears one would have to have something that generates
functions on the fly based upon inputs...

I look at details on what you are trying to create and see a
series-parallel circuit architecture with clocked stages and delay lines
for the summing of the outputs. That is, when the clock ticks, every
stage in the unit does its processing and provides and output... On the
next tick, those outputs become inputs to the subsequent stage and the
process repeats
Also if you have a specific solution for my problem I will be grateful
for it here.
I'm still blinking at the thought of doing analog to digital
conversion in Python! I sure wouldn't hold out much hope of real-time
signal processing. There is a reason ADC and DAC are done in hardware,
even if the intermediate processing is with general purpose processors.


I'm also not sure I understand the

np.linspace(1,1, Inc)...

Looking up documentation implies you are trying to create a vector
of "inc" length, evenly populated by values between 1 and 1... which
means a vector of all 1s... Might it not be faster to just

v = [1] * inc

and pass v to some numpy method for conversion from Python list to numpy
vector?

(the -1 to 1 at least makes sense)


Me? I'd probably create a class in which the __init__() takes a
value specifying the number of stages. It would than create suitable
lists to track values, some sort of counter (c), a Semaphore (s)
[initialized at 0 -- ie, already acquired/block], a thread for EACH
stage, and an Event (e) object

Each stage thread, initialized with its position in the pipeline.
The threads perform an e.wait() call. They also, after the wait is
released, perform an e.clear() call. As their processing, they each grab
from the pipeline "input" list the current value for their position.
After processing they update their position in the "output" list(s),
they decrement the counter c (maybe put a lock around access to c). The
thread that decrements c to 0 is responsible for "releasing" the
semaphore.

The main code of the class instance is responsible for a loop that
does: set up the "input" list based on current value of stage outputs,
initialize c to the count of stages (minus 1?), e.set() to signal all
stage threads to process the current conditions, s.acquire() to block
until the last processed thread (by c hitting 0) does s.release(). It
then collects the output lists, does whatever shifting is needed to
prepare for the next cycle...

Actually, that "loop" may not be a loop so much as a method off the
class like

digitalOutput = adcInstance.step(analogInput)

which is, itself, in a loop.

That is, something like...

myADC = ADC(stages=10)
while True:
voltage = getNextAnalogInput()
digital = myADC.step(voltage)
outputDigitalValue()


Obviously I've not taken the time to actually lay out all the
instance lists needed for inputs and outputs, nor the code of threads
(while one can create the first "stages-1" threads with a loop, the
final stage needs a discrete creation)


When one finds that the threading solution is really slow (though
understandable in terms of the hardware circuit -- one thread per stage
makes the stages easy to code), THEN one might try to figure out how to
implement an iterative version... I suspect using numpy would be the
third optimization -- removing iteration by using parallel vector
operations.
 
R

Ritchy lelis

Guys i'm asking if it's possible for a generic function for a
pipeline, all the suggestions ideas are welcome.

        I've not done metaclasses, so don't know if a metaclass would be of
use... Since it appears one would have to have something that generates
functions on the fly based upon inputs...

        I look at details on what you are trying to create and see a
series-parallel circuit architecture with clocked stages and delay lines
for the summing of the outputs. That is, when the clock ticks, every
stage in the unit does its processing and provides and output... On the
next tick, those outputs become inputs to the subsequent stage and the
process repeats
Also if you have a specific solution for my problem I will be grateful
for it here.

        I'm still blinking at the thought of doing analog to digital
conversion in Python! I sure wouldn't hold out much hope of real-time
signal processing. There is a reason ADC and DAC are done in hardware,
even if the intermediate processing is with general purpose processors.

        I'm also not sure I understand the

np.linspace(1,1, Inc)...

        Looking up documentation implies you are trying to create a vector
of "inc" length, evenly populated by values between 1 and 1... which
means a vector of all 1s... Might it not be faster to just

        v = [1] * inc

and pass v to some numpy method for conversion from Python list to numpy
vector?

(the -1 to 1 at least makes sense)

        Me? I'd probably create a class in which the __init__() takes a
value specifying the number of stages. It would than create suitable
lists to track values, some sort of counter (c), a Semaphore (s)
[initialized at 0 -- ie, already acquired/block],  a thread for EACH
stage, and an Event (e) object

        Each stage thread, initialized with its position in the pipeline.
The threads perform an e.wait() call. They also, after the wait is
released, perform an e.clear() call. As their processing, they each grab
from the pipeline "input" list the current value for their position.
After processing they update their position in the "output" list(s),
they decrement the counter c (maybe put a lock around access to c). The
thread that decrements c to 0 is responsible for "releasing" the
semaphore.

        The main code of the class instance is responsible for a loop that
does: set up the "input" list based on current value of stage outputs,
initialize c to the count of stages (minus 1?), e.set() to signal all
stage threads to process the current conditions, s.acquire() to block
until the last processed thread (by c hitting 0) does s.release(). It
then collects the output lists, does whatever shifting is needed to
prepare for the next cycle...

        Actually, that "loop" may not be a loop so much as a method off the
class like

        digitalOutput = adcInstance.step(analogInput)

which is, itself, in a loop.

That is, something like...

myADC = ADC(stages=10)
while True:
        voltage = getNextAnalogInput()
        digital = myADC.step(voltage)
        outputDigitalValue()

        Obviously I've not taken the time to actually lay out all the
instance lists needed for inputs and outputs, nor the code of threads
(while one can create the first "stages-1" threads with a loop, the
final stage needs a discrete creation)

        When one finds that the threading solution is really slow (though
understandable in terms of the hardware circuit -- one thread per stage
makes the stages easy to code), THEN one might try to figure out how to
implement an iterative version... I suspect using numpy would be the
third optimization -- removing iteration by using parallel vector
operations.


Hi

First of all i would like to thank you for your time and help.

I appreciate your suggestions and they seems very good to me... The
only problem it's that i'm newbie at python programming, but still
interested to learn more and more...

I already got a solution through harsh but it worked. at least I got
the wave form i wanted.

Next i'm going to let you'll my solution here. It's rudimentary but it
work's.

Seems very perceptible that's why i will not explain it right now but
if in case of doubt I will:

Pipeline Function:

from flash1b5 import flash1b5
from flash1b5 import *
from flash2b import flash2b
from flash2b import *
import matplotlib.pyplot as plt
import numpy as np
from pylab import *

if __name__ == "__main__":

Inc = raw_input("Valor do Incrimento = ")

Vref = np.linspace(1,1, Inc)
Vi = np.linspace(-1,1, Inc)
# x = np.linspace(-1,1, Inc)
# Vi = 1*sin(2*pi*(x-1/4))
Cs = np.linspace(3e-12, 3e-12, Inc)
Cf = np.linspace(3e-12, 3e-12, Inc)

f1 = flash1b5(Vi, Vref, Cs, Cf)

Vin1 = f1[0]
Vt1 = f1[1]
Vd1 = f1[2]*256

f2 = flash1b5(Vt1, Vref, Cs, Cf)

Vin2 = f2[0]
Vt2 = f2[1]
Vd2 = f2[2]*128

f3 = flash1b5(Vt2, Vref, Cs, Cf)

Vin3 = f3[0]
Vt3 = f3[1]
Vd3 = f3[2]*64

f4 = flash1b5(Vt3, Vref, Cs, Cf)

Vin4 = f4[0]
Vt4 = f4[1]
Vd4 = f4[2]*32

f5 = flash1b5(Vt4, Vref, Cs, Cf)

Vin5 = f5[0]
Vt5 = f5[1]
Vd5 = f5[2]*16

f6 = flash1b5(Vt5, Vref, Cs, Cf)

Vin6 = f6[0]
Vt6 = f6[1]
Vd6 = f6[2]*8

f7 = flash1b5(Vt6, Vref, Cs, Cf)

Vin7 = f7[0]
Vt7 = f7[1]
Vd7 = f7[2]*4

f8 = flash1b5(Vt7, Vref, Cs, Cf)

Vin8 = f8[0]
Vt8 = f8[1]
Vd8 = f8[2]*2

f2b = flash2b(Vt8, Vref)

Vin2b = f2b[0]
Vd2b = f2b[1]*1

Vd = Vd1+Vd2+Vd3+Vd4+Vd5+Vd6+Vd7+Vd8+Vd2b

## print 'Vin = ',Vin
## print 'Vt = ',Vt
## print 'Vd = ',Vd
##
# fig1 = figure(1,figsize=(8,5))
# ax1 = fig1.add_subplot(211, autoscale_on=False, xlim=(-1,1),
ylim=(-1,1))
# ax1.plot(Vin1, Vt4, lw=2, color='blue')
# grid (True); title('FLASH 1.5 BIT',fontsize =
16);ylabel('Vout_Residuo')
##
## ax1.annotate('00', xy=(-0.5, 0.5))
## ax1.annotate('01', xy=(0.0, 0.5))
## ax1.annotate('11', xy=(0.5, 0.5))
#
## hold(True)
#
fig2 = figure(1,figsize=(8,5))
ax2 = fig2.add_subplot(111, autoscale_on=True)
ax2.plot(Vin1, Vd, lw=2, color='red')
grid (True); xlabel('Vin');ylabel('Vout_Digital')
#
## ax2.annotate('00 --> 0', xy=(-0.5, 0.1))
## ax2.annotate('01 --> 1', xy=(0.0, 1.1))
## ax2.annotate('11 --> 2', xy=(0.5, 2.1))
##
#
plt.show()
--------------------------------------------------------------------------

About the answer i got for my last post:

1 -
v = [1] * inc
and pass v to some numpy method for conversion from Python list to numpy
vector?

Yes i agree with you, but at the time i made it i found that function
(Linspace) that could do what i was loking for and i didn't worry
about search for a better solution. but even if wanted to, i'm new at
the programming language and i don't know how to convert a list to a
vector in numpy. but still open for tips/tricks that could help me.

2 -
Me? I'd probably create a class in which the __init__() takes a
value specifying the number of stages. It would than create suitable
lists to track values, some sort of counter (c), a Semaphore (s)
[initialized at 0 -- ie, already acquired/block], a thread for EACH
stage, and an Event (e) object
Each stage thread, initialized with its position in the pipeline.
The threads perform an e.wait() call. They also, after the wait is
released, perform an e.clear() call. As their processing, they each grab
from the pipeline "input" list the current value for their position.
After processing they update their position in the "output" list(s),
they decrement the counter c (maybe put a lock around access to c). The
thread that decrements c to 0 is responsible for "releasing" the
semaphore

I did understand your algorithm/idea and that's what i want to
implement here (you couldn't be more right). but i don't now how to
implement the funcs e.wait() call and e.clear() call. they already
exists? i have to create them?

if I may, i would like to ask more help on this one please. I hope not
to be bothering you :(
 
D

Dennis Lee Bieber

First of all i would like to thank you for your time and help.

I appreciate your suggestions and they seems very good to me... The
only problem it's that i'm newbie at python programming, but still
interested to learn more and more...
Forgive but trying something as complex as ADC while not being
familiar with either the implementation language nor the real task is a
bit of a hill to climb...

Based on reading of Wikipedia, flash and pipeline are totally
different methods of conversion. Flash being a parallel comparator mode
in which each there are comparators for practically every output value.
Pipeline feeds signals in stages.


Using numpy vector operations should be the fastest implementation,
though I'm not experienced with numpy... Nor have I found a good
description of the algorithm for a 2-bit stage -- if I read your code,
it just uses different thresholds.

The following is NOT TESTED -- All I've done is try to interpret
numpy documentation and a paper (Maxim application note 1023) which gave
equations for a 1.5bit stage. I'm not happy with the shift
register/delay table code (which may be quite incorrect).

-=-=-=-=-=-=-
# Python 2.5 in use

import numpy as np

class A2DPipe(object):
def __init__(self, stages, V_ref):
# save the number of stages and the reference Voltage
self.stages = stages
self.V_ref = V_ref

# compute the comparator threshold voltages
self.V_H = self.V_ref * 0.25
self.V_L = -self.V_H

# initialize the input voltage stage data to 0.0;
# along with (stages-1) array of one, and zeroes
self.V_in = np.zeros(self.stages, dtype=np.float)
self.ones = np.float([+1] * (self.stages - 1))
self.zeros = np.zeros(self.stages - 1, dtype=np.float)

#initialize 2-D array of stage outputs for shifting
self.registers = array([[0] * self.stages
for i in range(self.stages)])

def step(self, V_in):
# computes values for next cycle of the ADC
# input is current instantaneous voltage
# update input voltage stage data by shifting values
# and inserting newest value
self.V_in = [V_in] + self.V_in[:self.stages-1]

# compute "digital" outputs [+1, 0, -1], and
# residual voltages for the first (stages - 1) stages
# using 1.5bit stage
dout1, res = self.f1b5(self.V_in[:-1])

# compute "digital" outputs for the final 2bit stage
dout2 = self.f2b(self.V_in[-1])

# update shift register values; move older values
# [need to work on this]
self.registers[:-1] = self.registers[1:]
self.registers[-1][:-1] = dout1
self.registers[-1][-1] = np.float(0.0)

# update the stage input voltages with the
# residuals (they get shifted on the next entry
self.V_in = res

# return the "sum" of the "digital" outputs
return ((self.sum() ** 2) + dout2[0]) ** 2 + dout2[1]

def sum(self):
s = 0.0
for d in self.registers:
s = s ** 2 + d[0]
return s

def f1b5(self, v_in):
# compute the positions where input voltage exceeds high
threshold
highBits = np.where(v_in > self.V_H,
self.ones,
self.zeros)

# compute the positions where the input voltage is less than low
limit
lowBits = np.where(v_in < self.V_L,
self.ones,
self.zeros)

# "digital" output is sum of high bits, and negated low bits
digital_out = highBits + -lowBits

# compute residuals
residuals = ((2 * v_in - self.V_ref) * highBits +
(2 * v_in * np.where(highBits + lowBits == 0,
self.ones, self.zeros)) +
(2 * v_in + self.V_ref) * lowBits)

# return "digital" output and residuals
return (digital_out, residuals)

def f2b(self, v_in):
# the 2bit stage is the final stage in the system, so
# v_in is a single element
# compute the positions where input voltage exceeds high
threshold
# (2X the threshold of the 1.5B stages)
highBits = np.where(v_in > (2 * self.V_H),
1.0,
0.0)

# compute the positions where the input voltage is less than low
limit
lowBits = np.where(v_in < (2 * self.V_L),
1.0,
0.0)

# "digital" output is sum of high bits, and negated low bits
digital_out = highBits + -lowBits

# compute residuals
residuals = ((4 * v_in - self.V_ref) * highBits +
(4 * v_in * np.where(highBits + lowBits == 0,
self.ones, self.zeros)) +
(4 * v_in + self.V_ref) * lowBits)

# return "digital" output and residuals
return (digital_out, residuals)
# "digital" output is sum of high bits, and negated low bits
digital_out = highBits + -lowBits

# compute residuals
residuals = ((2 * v_in - self.V_ref) * highBits +
(2 * v_in * np.where(highBits + lowBits == 0,
self.ones, self.zeros)) +
(2 * v_in + self.V_ref) * lowBits)

# return "digital" output and residuals
return (digital_out, residuals)



adc8_1V = A2DPipe(8, 1.0)

for v in range(-32, 32):
print adc8_1V.step(v * 0.25)
-=-=-=-=-=-
 
R

Ritchy lelis

@hotmail.com> declaimed the following in
gmane.comp.python.general:
        I've not done metaclasses, so don't know if a metaclass would be of
use... Since it appears one would have to have something that generates
functions on the fly based upon inputs...
        I look at details on what you are trying to create and see a
series-parallel circuit architecture with clocked stages and delay lines
for the summing of the outputs. That is, when the clock ticks, every
stage in the unit does its processing and provides and output... On the
next tick, those outputs become inputs to the subsequent stage and the
process repeats
        I'm still blinking at the thought of doing analog to digital
conversion in Python! I sure wouldn't hold out much hope of real-time
signal processing. There is a reason ADC and DAC are done in hardware,
even if the intermediate processing is with general purpose processors.
        I'm also not sure I understand the
np.linspace(1,1, Inc)...
        Looking up documentation implies you are trying to create a vector
of "inc" length, evenly populated by values between 1 and 1... which
means a vector of all 1s... Might it not be faster to just
        v = [1] * inc
and pass v to some numpy method for conversion from Python list to numpy
vector?
(the -1 to 1 at least makes sense)
        Me? I'd probably create a class in which the __init__() takes a
value specifying the number of stages. It would than create suitable
lists to track values, some sort of counter (c), a Semaphore (s)
[initialized at 0 -- ie, already acquired/block],  a thread for EACH
stage, and an Event (e) object
        Each stage thread, initialized with its position in thepipeline.
The threads perform an e.wait() call. They also, after the wait is
released, perform an e.clear() call. As their processing, they each grab
from thepipeline"input" list the current value for their position.
After processing they update their position in the "output" list(s),
they decrement the counter c (maybe put a lock around access to c). The
thread that decrements c to 0 is responsible for "releasing" the
semaphore.
        The main code of the class instance is responsible for a loop that
does: set up the "input" list based on current value of stage outputs,
initialize c to the count of stages (minus 1?), e.set() to signal all
stage threads to process the current conditions, s.acquire() to block
until the last processed thread (by c hitting 0) does s.release(). It
then collects the output lists, does whatever shifting is needed to
prepare for the next cycle...
        Actually, that "loop" may not be a loop so much as a method off the
class like
        digitalOutput = adcInstance.step(analogInput)
which is, itself, in a loop.
That is, something like...
myADC = ADC(stages=10)
while True:
        voltage = getNextAnalogInput()
        digital = myADC.step(voltage)
        outputDigitalValue()
        Obviously I've not taken the time to actually lay out all the
instance lists needed for inputs and outputs, nor the code of threads
(while one can create the first "stages-1" threads with a loop, the
final stage needs a discrete creation)
        When one finds that the threading solution is really slow (though
understandable in terms of the hardware circuit -- one thread per stage
makes the stages easy to code), THEN one might try to figure out how to
implement an iterative version... I suspect using numpy would be the
third optimization -- removing iteration by using parallel vector
operations.

Hi

First of all i would like to thank you for your time and help.

I appreciate your suggestions and they seems very good to me... The
only problem it's that i'm newbie at python programming, but still
interested to learn more and more...

I already got a solution through harsh but it worked. at least I got
the wave form i wanted.

Next i'm going to let you'll my solution here. It's rudimentary but it
work's.

Seems very perceptible that's why i will not explain it right now but
if in case of doubt I will:

PipelineFunction:

from flash1b5 import flash1b5
from flash1b5 import *
from flash2b import flash2b
from flash2b import *
import matplotlib.pyplot as plt
import numpy as np
from pylab import *

if __name__ == "__main__":

    Inc = raw_input("Valor do Incrimento = ")

    Vref = np.linspace(1,1, Inc)
    Vi = np.linspace(-1,1, Inc)
#    x = np.linspace(-1,1, Inc)
#    Vi = 1*sin(2*pi*(x-1/4))
    Cs = np.linspace(3e-12, 3e-12, Inc)
    Cf = np.linspace(3e-12, 3e-12, Inc)

    f1 = flash1b5(Vi, Vref, Cs, Cf)

    Vin1 = f1[0]
    Vt1 = f1[1]
    Vd1 = f1[2]*256

    f2 = flash1b5(Vt1, Vref, Cs, Cf)

    Vin2 = f2[0]
    Vt2 = f2[1]
    Vd2 = f2[2]*128

    f3 = flash1b5(Vt2, Vref, Cs, Cf)

    Vin3 = f3[0]
    Vt3 = f3[1]
    Vd3 = f3[2]*64

    f4 = flash1b5(Vt3, Vref, Cs, Cf)

    Vin4 = f4[0]
    Vt4 = f4[1]
    Vd4 = f4[2]*32

    f5 = flash1b5(Vt4, Vref, Cs, Cf)

    Vin5 = f5[0]
    Vt5 = f5[1]
    Vd5 = f5[2]*16

    f6 = flash1b5(Vt5, Vref, Cs, Cf)

    Vin6 = f6[0]
    Vt6 = f6[1]
    Vd6 = f6[2]*8

    f7 = flash1b5(Vt6, Vref, Cs, Cf)

    Vin7 = f7[0]
    Vt7 = f7[1]
    Vd7 = f7[2]*4

    f8 = flash1b5(Vt7, Vref, Cs, Cf)

    Vin8 = f8[0]
    Vt8 = f8[1]
    Vd8 = f8[2]*2

    f2b = flash2b(Vt8, Vref)

    Vin2b = f2b[0]
    Vd2b = f2b[1]*1

    Vd = Vd1+Vd2+Vd3+Vd4+Vd5+Vd6+Vd7+Vd8+Vd2b

##    print 'Vin = ',Vin
##    print 'Vt = ',Vt
##    print 'Vd = ',Vd
##
#    fig1 = figure(1,figsize=(8,5))
#    ax1 = fig1.add_subplot(211, autoscale_on=False, xlim=(-1,1),
ylim=(-1,1))
#    ax1.plot(Vin1, Vt4, lw=2, color='blue')
#    grid (True); title('FLASH 1.5 BIT',fontsize =
16);ylabel('Vout_Residuo')
##
##    ax1.annotate('00', xy=(-0.5, 0.5))
##    ax1.annotate('01', xy=(0.0, 0.5))
##    ax1.annotate('11', xy=(0.5, 0.5))
#
##    hold(True)
#
    fig2 = figure(1,figsize=(8,5))
    ax2 = fig2.add_subplot(111, autoscale_on=True)
    ax2.plot(Vin1, Vd, lw=2, color='red')
    grid (True); xlabel('Vin');ylabel('Vout_Digital')
#
##    ax2.annotate('00 --> 0', xy=(-0.5, 0.1))
##    ax2.annotate('01 --> 1', xy=(0.0, 1.1))
##    ax2.annotate('11 --> 2', xy=(0.5, 2.1))
##
#
    plt.show()
--------------------------------------------------------------------------

About the answer i got for my last post:

 1 -
    v = [1] * inc


and pass v to some numpy method for conversion from Python list to numpy
vector?

Yes i agree with you, but at the time i made it i found that function
(Linspace) that could do what i was loking for and i didn't worry
about search for a better solution. but even if wanted to, i'm new at
the programming language and i don't know how to convert a list to a
vector in numpy. but still open for tips/tricks that could help me.

2 -
        Me? I'd probably create a class in which the __init__() takes a
value specifying the number of stages. It would than create suitable
lists to track values, some sort of counter (c), a Semaphore (s)
[initialized at 0 -- ie, already acquired/block],  a thread for EACH
stage, and an Event (e) object
        Each stage thread, initialized with its position in thepipeline.
The threads perform an e.wait() call. They also, after the wait is
released, perform an e.clear() call. As their processing, they each grab
from thepipeline"input" list the current value for their position.
After processing they update their position in the "output" list(s),
they decrement the counter c (maybe put a lock around access to c). The
thread that decrements c to 0 is responsible for "releasing" the
semaphore

I did understand your algorithm/idea and that's what i want to
implement here (you couldn't be more right). but i don't now how to
implement the funcs e.wait() call and e.clear() call. they already
exists? i have to create them?

if I may, i would like to ask more help on this one please. I hope not
to be bothering you :(

hi friend Dennis Lee Bieber

I have watching your code sujestion and now i can understand more of
what you have there..

I have made some chances into it, for my better understanding of your
point of view and adapted for it to fits my needs...

i would like to show you them but i need to now if you still
interested in the challenge it self and also in helping me with your
extraordinary tips.

Can i count on your help? I hope so gratefully.

I'll be waiting for a message so we can proceed.

Cheers.
 
D

Dennis Lee Bieber

hi friend Dennis Lee Bieber

I have watching your code sujestion and now i can understand more of
what you have there..
Take warning -- I think I had a major flaw in the summation part of
the logic... It's probably easier just to use a list of lists (one list
per stage, and each list as long as the number of stages) and sum the
diagonal

result = sum([list_of_lists for i in range(number_of_stages)])
i would like to show you them but i need to now if you still
interested in the challenge it self and also in helping me with your
extraordinary tips.

Can i count on your help? I hope so gratefully.
My apologies... much more help and I'll have done the work for you
(though I'm still perplexed at simulating a hardware A/D converter when
the input is already a floating point digital, and the output is integer
digital)
 
R

Ritchy lelis

hi friend Dennis Lee Bieber
I have watching your code sujestion and now i can understand more of
what you have there..

        Take warning -- I think I had a major flaw in the summation part of
the logic... It's probably easier just to use a list of lists (one list
per stage, and each list as long as the number of stages) and sum the
diagonal

        result = sum([list_of_lists for i in range(number_of_stages)])
i would like to show you them but i need to now if you still
interested in the challenge it self and also in helping me with your
extraordinary tips.
Can i count on your help? I hope so gratefully.

        My apologies... much more help and I'll have done the work for you
(though I'm still perplexed at simulating a hardware A/D converter when
the input is already a floating point digital, and the output is integer
digital)



My apologies... much more help and I'll have done the work for you

Until now you were the only person who helped me so far...
your help has served a lot.
Already learned a lot with you so please do not stop
helping me.

To show you that you have not done it alone, i'll show you that i have
made some arrangements.

About the pipeline Class still have some errors and i'm working on it.
Hope this link help.

http://www.eetimes.com/design/autom...ash-and-Pipeline-Converter-Operation-Explored

though I'm still perplexed at simulating a hardware A/D converter when
the input is already a floating point digital, and the output is integer
digital

I believe that de residuals that we're getting at the output,
already are the wave forms that we should get if we had a Oscilloscope
and analyzing the behavior of a A/D hardware and the digital parts is
to quantify the analog input ie first we analyze and translate the
analog input to a known residue and then quantifies to the digital
output.

I already initialized the "non linear" issues with the Class
Calculate, and after this we will start to see how A/D converter
really works.
I would love you to help me at this one to

Class Calculate:

1 - http://www.national.com/appinfo/adc/files/ABCs_of_ADCs.pdf

2 - http://www.atmel.com/dyn/resources/prod_documents/doc2559.pdf

And now my new arrangements:

# -*- coding: cp1252 -*-
#######################################ADC#####################################

##>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>Incluir as
Bibliotecas>>>>>>>>>>>>>>>>>>>>>>>>
import matplotlib.pyplot as plt
import numpy as np
from numpy.random import *
from numpy.fft import *
from pylab import *
##>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>CLASS
ADC>>>>>>>>>>>>>>>>>>>>>>>>>>>>
class ADC(object):

def __init__(self, Inc, V_in, V_ref, Cs, Cf):

##Guarda o número de estágio e a tensão de
referência
## Stores the number of stage and reference
voltage
self.Inc = Inc
self.V_ref = V_ref
self.Cs = Cs
self.Cf = Cs

##calcula os limiares da tensão do comparador
##calculates the threshold voltage of the
comparator
self.V_H = self.V_ref * 0.25
self.V_L = -self.V_H
self.V_in = V_in

#define dois array de "Inc" elementos todos a
uns e zeros respectivamente
##sets two array "Inc" elements all the ones and
zeros respectively
self.ones = np.ones(Inc, dtype=np.float)
self.zeros = np.zeros(Inc, dtype=np.float)

##função flash 1.5 bit
##1.5 bit flash function
def flash1b5(self):

# calcula as posições onde a tensão de entrada
excede o limiar alto
## calculates the positions where the input
voltage exceeds the high threshold
highBits = np.where(self.V_in > self.V_H,
self.ones, self.zeros)

# calcula as posições onde a tensão de entrada é
menor que o limiar baixo
## calculates the positions where the input
voltage is less than the low threshold
lowBits = np.where(self.V_in < self.V_L,
self.ones, self.zeros)

# calcula as posições onde a tensão de entrada é
maior que o limiar baixo e não excede o limiar alto
## calculates the positions where the input
voltage is greater than the low threshold and does not exceed the high
threshold
midleBits = np.where(highBits + lowBits == 0,
self.ones, self.zeros)

# "digital" output pode ser obtido somando 1 e o
highBits e subtraindo lowBits
## "Digital" output can be obtained by adding
and subtracting 1 and highBits lowBits
self.digital_out = 1 + highBits + -lowBits


# calcular residuo
## Calculate residue
self.residuals = (((1+self.Cs/self.Cf)*
self.V_in) -((self.Cs/self.Cf) * self.V_ref)) * highBits + ((1+self.Cs/
self.Cf)* self.V_in )* midleBits + (((1+self.Cs/self.Cf)* self.V_in) +
((self.Cs/
self.Cf)* self.V_ref)) * lowBits

# retorno da saida digital e do residuo
## return of the digital output and the residue
out = [self.digital_out, self.residuals]
return out

##função flash 2 bit
## 2 bit flash function
def flash2b(self):


# calcula as posições onde a tensão de entrada
excede o limiar alto
## calculates the positions where the input
voltage exceeds the high threshold
# (2X the threshold of the 1.5B stages)
highBits1 = np.where(self.V_in > 2*self.V_H,
[3], self.zeros)

# calcula as posições onde a tensão de entrada
está entre zero e o limiar alto
## calculates the positions where the input
voltage is between zero and the high threshold
if any(self.V_in <= 2*self.V_H) and
any(self.V_in > 0.0):
highBits2 = np.where((self.V_in <=
2*self.V_H) & (self.V_in > 0.0), [2], self.zeros)

# calcula as posições onde a tensão de entrada
está entre zero e o limiar baixo
## calculates the positions where the input
voltage is between zero and low threshold
if any(self.V_in <= 0.0) and any(self.V_in >
2*self.V_L):
lowBits1 = np.where((self.V_in <= 0.0) &
(self.V_in > 2*self.V_L), self.ones,self.zeros)

# calcula as posições onde a tensão de entrada é
menor que o limiar baixo
## calculates the positions where the input
voltage is less than the low threshold
lowBits2 = np.where(self.V_in <= 2*self.V_L,
self.zeros, self.zeros)

# "digital" output pode ser obtido somando todas
as posiçoes desta forma.
## "Digital" output can be obtained by adding
all the positions in this way
self.digital_out = lowBits2 + lowBits1 +
highBits2+ highBits1

# retorno da saida digital
## Digital output return
out = [self.digital_out]
return out

##função flash 2.5 bit
## 2.5 bit flash function
def flash2b5(self):

## calculates the positions where the input
voltage exceeds the high threshold
highBits1 = np.where(self.V_in > (self.V_H*5/2),
self.ones, self.zeros)

## calculates the positions where the input
voltage is between zero and the high threshold

if any(self.V_in <= (self.V_H*5/2)) and
any(self.V_in >=(self.V_H*3/2)):
highBits2 = np.where((self.V_in <=
(self.V_H*5/2)) &
(self.V_in
=(self.V_H*3/2)), self.ones, self.zeros)

if any(self.V_in <= (self.V_H*3/2)) and
any(self.V_in >=(self.V_H*1/2)):
highBits3 = np.where((self.V_in <=
(self.V_H*3/2)) &
(self.V_in
=(self.V_H*1/2)), self.ones, self.zeros)

if any(self.V_in <= (self.V_H*1/2)) and
any(self.V_in >=(self.V_L*1/2)):
midleBits = np.where((self.V_in <=
(self.V_H*1/2)) &
(self.V_in
=(self.V_L*1/2)), self.ones, self.zeros)

if any(self.V_in <= (self.V_L*1/2)) and
any(self.V_in >=(self.V_L*3/2)):
lowBits1 = np.where((self.V_in <=
(self.V_L*1/2)) &
(self.V_in
=(self.V_L*3/2)), self.ones, self.zeros)

if any(self.V_in <= (self.V_L*3/2)) and
any(self.V_in >=(self.V_L*5/2)):
lowBits2 = np.where((self.V_in <=
(self.V_L*3/2)) &
(self.V_in
=(self.V_L*5/2)), self.ones, self.zeros)

## calculates the positions where the input
voltage is less than the low threshold
lowBits3 = np.where(self.V_in < (self.V_L*5/2),
self.ones, self.zeros)

## Calculate residue 2.5 Bit
self.residuals = ((4*self.V_in -
3*self.V_ref)*highBits1 + (4*self.V_in - 2*self.V_ref) * highBits2 +
(4*self.V_in - self.V_ref) *
highBits3 + (4 * self.V_in) * midleBits + (4*self.V_in + self.V_ref) *
lowBits1 +
(4*self.V_in + 2*self.V_ref) *
lowBits2 + (4*self.V_in + 3*self.V_ref) * lowBits3)

## Residue output return
out = [self.residuals]
return out

##
##
##função flash 3 Bit
## 3 Bit flash function
def flash3b(self):

## calculates the positions where the input
voltage exceeds the high threshold
highBits1 = np.where(self.V_in > (self.V_H*3),
[7], self.zeros)

## calculates the positions where the input
voltage is between zero and the high threshold
if any(self.V_in <= (self.V_H*3)) and
any(self.V_in >=self.V_H*2):
highBits2 = np.where((self.V_in <=
(self.V_H*3)) &
(self.V_in
=(self.V_H*2)), [6], self.zeros)

if any(self.V_in <= (self.V_H*2)) and
any(self.V_in >=(self.V_H)):
highBits3 = np.where((self.V_in <=
(self.V_H*2)) &
(self.V_in
=(self.V_H)), [5], self.zeros)

if any(self.V_in <= (self.V_H)) and
any(self.V_in >=0.0):
highBits4 = np.where((self.V_in <=
(self.V_H)) &
(self.V_in
=0.0), [4], self.zeros)

if any(self.V_in <= 0.0) and any(self.V_in >=
(self.V_L)):
lowBits1 = np.where((self.V_in <=
0.0) &
(self.V_in >=
(self.V_L)), [3], self.zeros)

if any(self.V_in <= (self.V_L)) and
any(self.V_in >=(self.V_L*2)):
lowBits2 = np.where((self.V_in <=
(self.V_L)) &
(self.V_in
=(self.V_L*2)), [2], self.zeros)

if any(self.V_in <= (self.V_L*2)) and
any(self.V_in >=(self.V_L*3)):
lowBits3 = np.where((self.V_in <=
(self.V_L*2)) &
(self.V_in
=(self.V_L*3)), [1], self.zeros)

## calculates the positions where the input
voltage is less than the low threshold
lowBits4 = np.where(self.V_in < (self.V_L*3),
self.zeros, self.zeros)

## "Digital" output can be obtained by adding
all the positions in this way
self.digital_out = lowBits4 + lowBits3 +
lowBits2 + lowBits1 + highBits4 + highBits3 + highBits2 +highBits1

# retorno da saida digital
## Digital output return
out = [self.digital_out]
return out
##
##
##função flash 3.5 bit
## 3.5 Bit flash function
def flash3b5(self):

## calculates the positions where the input
voltage exceeds the high threshold
highBits1 = np.where(self.V_in >
(self.V_H*13/4), self.ones, self.zeros)

## calculates the positions where the input
voltage is between zero and the high threshold
if any(self.V_in <= (self.V_H*13/4)) and
any(self.V_in >=(self.V_H*11/4)):
highBits2 = np.where((self.V_in <=
(self.V_H*13/4)) &
(self.V_in
=(self.V_H*11/4)), self.ones, self.zeros)

if any(self.V_in <= (self.V_H*11/4)) and
any(self.V_in >=(self.V_H*9/4)):
highBits3 = np.where((self.V_in <=
(self.V_H*11/4)) &
(self.V_in
=(self.V_H*9/4)), self.ones, self.zeros)

if any(self.V_in <= (self.V_H*9/4)) and
any(self.V_in >=(self.V_H*7/4)):
highBits4 = np.where((self.V_in <=
(self.V_H*9/4)) &
(self.V_in
=(self.V_H*7/4)), self.ones, self.zeros)

if any(self.V_in <= (self.V_H*7/4)) and
any(self.V_in >=(self.V_H*5/4)):
highBits5 = np.where((self.V_in <=
(self.V_H*7/4)) &
(self.V_in
=(self.V_H*5/4)), self.ones, self.zeros)

if any(self.V_in <= (self.V_H*5/4)) and
any(self.V_in >=(self.V_H*3/4)):
highBits6 = np.where((self.V_in <=
(self.V_H*5/4)) &
(self.V_in
=(self.V_H*3/4)), self.ones, self.zeros)

if any(self.V_in <= (self.V_H*3/4)) and
any(self.V_in >=(self.V_H*1/4)):
highBits7 = np.where((self.V_in <=
(self.V_H*3/4)) &
(self.V_in
=(self.V_H*1/4)), self.ones, self.zeros)

if any(self.V_in <= (self.V_H*1/4)) and
any(self.V_in >=(self.V_L*1/4)):
midleBits = np.where((self.V_in <=
(self.V_H*1/4)) &
(self.V_in
=(self.V_L*1/4)), self.ones, self.zeros)

if any(self.V_in <= (self.V_L*1/4)) and
any(self.V_in >=(self.V_L*3/4)):
lowBits1 = np.where((self.V_in <=
(self.V_L*1/4)) &
(self.V_in
=(self.V_L*3/4)), self.ones, self.zeros)

if any(self.V_in <= (self.V_L*3/4)) and
any(self.V_in >=(self.V_L*5/4)):
lowBits2 = np.where((self.V_in <=
(self.V_L*3/4)) &
(self.V_in
=(self.V_L*5/4)), self.ones, self.zeros)

if any(self.V_in <= (self.V_L*5/4)) and
any(self.V_in >=(self.V_L*7/4)):
lowBits3 = np.where((self.V_in <=
(self.V_L*5/4)) &
(self.V_in
=(self.V_L*7/4)), self.ones, self.zeros)

if any(self.V_in <= (self.V_L*7/4)) and
any(self.V_in >=(self.V_L*9/4)):
lowBits4 = np.where((self.V_in <=
(self.V_L*7/4)) &
(self.V_in
=(self.V_L*9/4)), self.ones, self.zeros)

if any(self.V_in <= (self.V_L*9/4)) and
any(self.V_in >=(self.V_L*11/4)):
lowBits5 = np.where((self.V_in <=
(self.V_L*9/4)) &
(self.V_in
=(self.V_L*11/4)), self.ones, self.zeros)

if any(self.V_in <= (self.V_L*11/4)) and
any(self.V_in >=(self.V_L*13/4)):
lowBits6 = np.where((self.V_in <=
(self.V_L*11/4)) &
(self.V_in
=(self.V_L*13/4)), self.ones, self.zeros)

## calculates the positions where the input
voltage is less than the low threshold
lowBits7 = np.where(self.V_in < (self.V_L*13/4),
self.ones, self.zeros)

## Calculate residue 3.5 Bit
self.residuals = ((8*self.V_in - 7*self.V_ref)
*highBits1 + (8*self.V_in - 6*self.V_ref)* highBits2 +
(8*self.V_in -
5*self.V_ref)*highBits3 + (8*self.V_in - 4*self.V_ref) * highBits4 +
(8*self.V_in - 3*self.V_ref) *
highBits5 + (8*self.V_in - 2*self.V_ref) * highBits6 +
(8*self.V_in - self.V_ref) *
highBits7 + (8 * self.V_in) * midleBits +
(8*self.V_in + self.V_ref) *
lowBits1 + (8*self.V_in + 2*self.V_ref) * lowBits2 +
(8*self.V_in + 3*self.V_ref) *
lowBits3 + (8*self.V_in + 4*self.V_ref) * lowBits4 +
(8*self.V_in + 5*self.V_ref) *
lowBits5 + (8*self.V_in + 6*self.V_ref) * lowBits6 +
(8*self.V_in + 7*self.V_ref) *
lowBits7 )

## Residue output return
out = [self.residuals]
return out
##
##
## ##função Pipeline
## def pipeline(self):

##>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>CLASS
CALCULATE>>>>>>>>>>>>>>>>>>>>>>>>>>>>
##class calculate(ADC):
##
## def __init__ (self):
##
##
## def AC_Errors(self):
##
##
## def Offset_Errors(self):
##
##
## def plot_fft(self):
##
##
## def DNL_INL(self):



##>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>SIMULAÇÃO>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
##
if __name__=='__main__':

V_in = np.linspace(-1, 1, 10000)

F1B5 = ADC(10000, V_in, 1, 2, 2).flash1b5()
F2B = ADC(10000, V_in, 1, 2, 2).flash2b()
F2B5 = ADC(10000, V_in, 1, 2, 2).flash2b5()
F3B5 = ADC(10000, V_in, 1, 2, 2).flash3b5()
F3B = ADC(10000, V_in, 1, 2, 2).flash3b()

fig1 = figure(1,figsize=(8,5))
ax1 = fig1.add_subplot(111, autoscale_on=True)
ax1.plot(V_in, F1B5[1], lw = 1, color='b')
grid(True); xlabel('IN'); ylabel('OUT'); title('RESIDUALS
1B5')

fig2 = figure(2,figsize=(8,5))
ax2 = fig2.add_subplot(111, autoscale_on=False,xlim=(-1,1),
ylim=(-1,3))
ax2.plot(V_in, F1B5[0], lw=1, color='r')
grid(True); xlabel('IN'); ylabel('OUT'); title('DIGITAL OUT
1B5')

fig3 = figure(3,figsize=(8,5))
ax3 = fig3.add_subplot(111, autoscale_on=False,xlim=(-1,1),
ylim=(-1,4))
ax3.plot(V_in, F2B[0], lw=1, color='g')
grid(True); xlabel('IN'); ylabel('OUT'); title('DIGITAL OUT
2B')

fig4 = figure(4,figsize=(8,5))
ax4 = fig4.add_subplot(111, autoscale_on=True)
ax4.plot(V_in, F2B5[0], lw=1, color='y')
grid(True); xlabel('IN'); ylabel('OUT'); title('RESIDUALS
2B5')

fig5 = figure(5,figsize=(8,5))
ax5 = fig5.add_subplot(111, autoscale_on=False,xlim=(-1,1),
ylim=(-1,8))
ax5.plot(V_in, F3B[0], lw=1, color='brown')
grid(True); xlabel('IN'); ylabel('OUT'); title('DIGITAL OUT
3B')

fig6 = figure(6,figsize=(8,5))
ax6 = fig6.add_subplot(111, autoscale_on=False,
xlim=(-1,1), ylim=(-1,1))
ax6.plot(V_in, F3B5[0], lw=1, color='purple')
grid(True); xlabel('IN'); ylabel('OUT'); title('RESIDUALS
3B5')

plt.show()

Ps: How can i put my messages just for you to read it like you always
do?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,067
Latest member
HunterTere

Latest Threads

Top