Problem
I'm writing a verilog program that does the trapezoidal integration method (where a review is also welcome, wink wink). But turns out you need input for these kind of things, so in the overly complicated setup I'm doing, I'm writing a python program on a Raspberry Pi to output inputs for the FPGA which then outputs to a d to a which outputs to an oscilloscope which is where you all go, "Thank goodness I'm not that programmer" and I go half mad.
The main requirements for the code is that it output each bit of the input for the FPGA at a separate pin, as serial data is slower, and that the output be two's complement (i.e., the signals are signed integers, so the bits given to the FPGA must also be signed).
Approach
My code can be broken up into three phases: signal generation, signal conversion, and signal output.
Signal generation
Right now, I'm just using a simple square wave. This is done using
x = 0
signal = 1
while x <= 25:
if x % 2 == 0:
signal*=-1
signals.append(signal)
x+=1
Signal conversion
This iterates over signals
and applies twos_comp()
to each. twos_comp()
converts the integer to its binary representation (carefully slicing off all the unneeded nonsense) and then if the original value was greater than zero, just returns that. Otherwise, the number is inverted using the invert()
function, and then has one added to it, and is returned. Type conversions are rife, and this whole thing is rather hack-y.
This assumes 8 bit numbers.
Signal output
Using RPi.GPIO, a clock pin (which is mapped to the FPGA's clock) is setup and a set of 8 pins is setup for the signal. Again, parallel not serial. For each item in the new list generated by twos_comp()
, the program waits for the clock's rising edge (I know this is somewhat frowned upon, but the output needs to be synced to the clock and the clock is also pretty fast, so it's not like it's going to be waiting for a while (50 mega hertz, can be faster). Then, for each item in the 8-bit number, it's outputted to the appropriate pin.
Concerns/reviewing
Any and all comments are welcome in this review, with speed comments (especially in the latter part of the program) extra welcome as I want it to be able to keep up with the FPGA clock. (Speed in the first part obviously isn't as necessary as it all can be done before the FPGA starts up. I also don't know if RPi.GPIO will be able to output the bits fast enough.) As I mentioned earlier, the invert()
and twos_comp()
functions are...kinda hacky.
Thanks!
Code
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BCM)
x = 21
while x <= 28: #signal pins
GPIO.setup(x, GPIO.OUT)
x+=1
GPIO.setup(5, GPIO.IN) #clock
signals = []
bit_signals = []
def invert(bit_val):
new_val = []
for i in bit_val:
new_val.append(str(int(not(int(i)))))
return ''.join(new_val)
def twos_comp(val):
bin_val = format(val, '09b')[-8:]
if val < 0:
return format(int(invert(bin_val),2) + int('1', 2), '08b')
else:
return bin_val
x = 0
signal = 1
while x <= 25:
if x % 2 == 0:
signal*=-1
signals.append(signal)
x+=1
for i in signals:
bit_signals.append(twos_comp(i))
for i in bit_signals:
GPIO.wait_for_edge(5, GPIO.RISING)
counter = 21
for k in str(i):
GPIO.output(counter, k) #k will be 0 or 1 which is accepted input
counter += 1
GPIO.cleanup()
1 Answer 1
You should start by organising your code better. Try to avoid global variables and group together code in functions.
In addition, you should learn about list comprehensions. They make initializing your signals way easier.
import RPi.GPIO as GPIO
def twos_comp(i):
...
def gpio_setup(inputs, outputs):
GPIO.setmode(GPIO.BCM)
for pin in inputs:
GPIO.setup(pin, GPIO.IN)
for pin in outputs:
GPIO.setup(pin, GPIO.OUT)
def main(input_pin, output_pins):
signals = [1 if i % 2 else -1 for i in range(26)]
bit_signals = [twos_comp(i) for i in signals]
for i in bit_signals:
GPIO.wait_for_edge(input_pin, GPIO.RISING)
for pin, k in zip(output_pins, str(i)):
GPIO.output(pin, k) #k will be 0 or 1 which is accepted input
if __name__ == "__main__":
in, out = [5], range(21, 29)
gpio_setup(in, out)
main(in[0], out)
GPIO.cleanup()
And finally, there are better ways to do twos complement. A nice one is for example here.
-
2\$\begingroup\$ This is a lot cleaner than my code. Thank you very much. Do you have any thoughts on how fast RPi.GPIO can be updating the pins at the end, and if it can keep up with the FPGA clock? \$\endgroup\$auden– auden2018年08月07日 16:06:12 +00:00Commented Aug 7, 2018 at 16:06
-
1\$\begingroup\$ @heather You're welcome. I have no idea, since I never tried to use them, sorry. \$\endgroup\$Graipher– Graipher2018年08月07日 16:07:56 +00:00Commented Aug 7, 2018 at 16:07
-
2\$\begingroup\$ Okay, cool, thanks. Probably a question more appropriate for Raspberry Pi.SE anyway =) \$\endgroup\$auden– auden2018年08月07日 16:10:16 +00:00Commented Aug 7, 2018 at 16:10
Explore related questions
See similar questions with these tags.
ExternalError: TypeError: pin is undefined on line 6
. Is your code broken? \$\endgroup\$