Skip to content

Instantly share code, notes, and snippets.

@mkatsimpris
Last active May 25, 2016 16:43
Show Gist options
  • Save mkatsimpris/6a9dc40fbe5bf79acd4a52ab76111392 to your computer and use it in GitHub Desktop.
Save mkatsimpris/6a9dc40fbe5bf79acd4a52ab76111392 to your computer and use it in GitHub Desktop.
#!/bin/python
from myhdl import *
ACTIVE_LOW, INACTIVE_HIGH = False, True
INACTIVE_LOW, ACTIVE_HIGH = False, True
def sintbv(value, nbits):
nbits -= 1
min_value = -1 << nbits
max_value = -min_value + 1
return intbv(value, min_value, max_value)
def round_signed(val, msb, lsb):
if val[lsb - 1]:
return val[msb:lsb].signed() + 1
return val[msb:lsb].signed()
def round_unsigned(val, msb, lsb):
temp=intbv(0)[msb:lsb]
if val[lsb - 1]:
temp[:]=val[msb:lsb] + 1
return temp
temp[:]=val[msb:lsb]
return temp
Traceback (most recent call last):
File "test_rgb2ycbcr.py", line 96, in <module>
testbench()
File "test_rgb2ycbcr.py", line 93, in testbench
assert instance.verify_convert() == 0
File "/usr/local/lib/python2.7/dist-packages/myhdl-1.0.dev0-py2.7.egg/myhdl/_block.py", line 218, in verify_convert
return myhdl.conversion.verify(self)
File "/usr/local/lib/python2.7/dist-packages/myhdl-1.0.dev0-py2.7.egg/myhdl/conversion/_verify.py", line 144, in __call__
inst = func.convert(hdl='Verilog')
File "/usr/local/lib/python2.7/dist-packages/myhdl-1.0.dev0-py2.7.egg/myhdl/_block.py", line 256, in convert
return converter(self)
File "/usr/local/lib/python2.7/dist-packages/myhdl-1.0.dev0-py2.7.egg/myhdl/conversion/_toVerilog.py", line 175, in __call__
genlist = _analyzeGens(arglist, h.absnames)
File "/usr/local/lib/python2.7/dist-packages/myhdl-1.0.dev0-py2.7.egg/myhdl/conversion/_analyze.py", line 174, in _analyzeGens
tree.symdict = f.f_globals.copy()
AttributeError: 'NoneType' object has no attribute 'f_globals'
#!/bin/python
from myhdl import *
from commons import *
from math import *
#Fixed point representation with 1 sign bit and 14 fractional bits
fract_bits=14
nbits=8
Y_COEFF=[0.2999,0.587,0.114]
CB_COEFF=[-0.1687,-0.3313,0.5]
CR_COEFF=[0.5,-0.4187,-0.0813]
OFFSET=[0,128,128]
Y=[int(round(Y_COEFF[i]*(2**fract_bits )))for i in range(3)]
Cb=[int(round(CB_COEFF[i]*(2**fract_bits ))) for i in range(3)]
Cr=[int(round(CR_COEFF[i]*(2**fract_bits ))) for i in range(3)]
Offset=[int(round(OFFSET[i]*(2**fract_bits ))) for i in range(3)]
class RGB(object):
def __init__(self, nbits=8):
self.nbits=nbits
self.red = Signal(intbv(0)[nbits:])
self.green = Signal(intbv(0)[nbits:])
self.blue = Signal(intbv(0)[nbits:])
def next(self, r, g, b):
self.red.next = r
self.green.next = g
self.blue.next = b
def bitLength(self): return self.nbits
class YCbCr(object):
def __init__(self, nbits=8):
self.nbits = nbits
self.y = Signal(intbv(0)[nbits:])
self.cb = Signal(intbv(0)[nbits:])
self.cr = Signal(intbv(0)[nbits:])
def bitLength(self): return self.nbits
@block
def rgb2ycbcr(ycbcr, enable_out, rgb, enable_in, clk, reset):
#Ranges for multiplication and addition signals
#to find the bit width required for a multiplication: 2*fract_bits + 2*sign_bits + 2*sign_bits
mult_max_range=2**(nbits+fract_bits+1)
rgb_range=2**nbits
coeff_range=2**fract_bits
#signals for y,cb,cr registers
Y_reg,Cb_reg,Cr_reg=[[Signal(intbv(0,min=-mult_max_range,max=mult_max_range)) for _ in range(3)] for _ in range(3)]
Y_sum,Cb_sum,Cr_sum=[Signal(intbv(0,min=-mult_max_range,max=mult_max_range)) for _ in range(3)]
#signals for signed input RGB
R_s,G_s,B_s=[Signal(intbv(0,min=-rgb_range,max=rgb_range)) for i in range(3)]
#signals for coefficient signed conversion
Y1_s,Y2_s,Y3_s=[Signal(intbv(Y[i],min=-coeff_range,max=coeff_range)) for i in range(3)]
Cb1_s,Cb2_s,Cb3_s=[Signal(intbv(Cb[i],min=-coeff_range,max=coeff_range)) for i in range(3)]
Cr1_s,Cr2_s,Cr3_s=[Signal(intbv(Cr[i],min=-coeff_range,max=coeff_range)) for i in range(3)]
offset_y,offset_cb,offset_cr=[Signal(intbv(Offset[i],min=-mult_max_range,max=mult_max_range)) for i in range(3)]
enable_out_reg=[Signal(bool(0)) for _ in range(2)]
@always_comb
def logic2():
#input RGB signed conversion
R_s.next=rgb.red
G_s.next=rgb.green
B_s.next=rgb.blue
@always_seq(clk.posedge, reset=reset)
def logic():
if enable_in == ACTIVE_HIGH:
Y_reg[0].next=R_s*Y1_s
Y_reg[1].next=G_s*Y2_s
Y_reg[2].next=B_s*Y3_s
Cb_reg[0].next=R_s*Cb1_s
Cb_reg[1].next=G_s*Cb2_s
Cb_reg[2].next=B_s*Cb3_s
Cr_reg[0].next=R_s*Cr1_s
Cr_reg[1].next=G_s*Cr2_s
Cr_reg[2].next=B_s*Cr3_s
Y_sum.next=Y_reg[0]+Y_reg[1]+Y_reg[2]+offset_y
Cb_sum.next=Cb_reg[0]+Cb_reg[1]+Cb_reg[2]+offset_cb
Cr_sum.next=Cr_reg[0]+Cr_reg[1]+Cr_reg[2]+offset_cr
#rounding
"""
the part which must be checked for rounding is the partm from signal[fract_bits + nbits:fract_bits]
"""
a=fract_bits + nbits
b=fract_bits
if(Y_sum[b - 1]==1 and Y_sum[a:b]!=(2**nbits)):
ycbcr.y.next=Y_sum[a:b]+1
else:
ycbcr.y.next=Y_sum[a:b]
if(Cb_sum[b- 1]==1 and Cb_sum[a:b]!=(2**nbits)):
ycbcr.cb.next=Cb_sum[a:b]+1
else:
ycbcr.cb.next=Cb_sum[a:b]
if(Cr_sum[b- 1]==1 and Cr_sum[a:b]!=(2**nbits)):
ycbcr.cr.next=Cr_sum[a:b]+1
else:
ycbcr.cr.next=Cr_sum[a:b]
#enable_out delayed
enable_out_reg[0].next=enable_in
enable_out_reg[1].next=enable_out_reg[0]
enable_out.next = enable_out_reg[1]
else:
enable_out.next=INACTIVE_LOW
return logic,logic2
def convert():
ycbcr = YCbCr()
rgb = RGB()
clk, enable_in, enable_out = [Signal(INACTIVE_LOW) for _ in range(3)]
reset = ResetSignal(1, active=ACTIVE_LOW, async=True)
instance=rgb2ycbcr(ycbcr, enable_out, rgb, enable_in, clk, reset)
instance.convert(hdl='VHDL')
if __name__ == '__main__':
convert()
#!/bin/python
from myhdl import *
from random import randrange
from commons import *
from rgb2ycbcr import *
from myhdl.conversion import *
def rgb_to_ycbcr(r,g,b):
ycbcr=[None for _ in range(3)]
ycbcr[0]=int(round(Y_COEFF[0]*float(r)+Y_COEFF[1]*float(g)+Y_COEFF[2]*float(b)+OFFSET[0]))
ycbcr[1]=int(round(CB_COEFF[0]*float(r)+CB_COEFF[1]*float(g)+CB_COEFF[2]*float(b)+OFFSET[1]))
ycbcr[2]=int(round(CR_COEFF[0]*float(r)+CR_COEFF[1]*float(g)+CR_COEFF[2]*float(b)+OFFSET[2]))
return tuple(ycbcr)
@block
def test():
ycbcr = YCbCr()
rgb = RGB()
clk, enable_in, enable_out = [Signal(INACTIVE_LOW) for _ in range(3)]
reset = ResetSignal(1, active=ACTIVE_LOW, async=True)
rgb2ycbcr_inst = rgb2ycbcr(ycbcr, enable_out, rgb, enable_in, clk, reset)
#create the test input values and the output values
input_list=[]
output_list=[]
samples=50
for i in range(samples):
r,g,b=[randrange(256) for _ in range(3)]
input_list.append((r,g,b))
out=rgb_to_ycbcr(r,g,b)
output_list.append(out)
input_list=tuple(input_list)
output_list=tuple(output_list)
@instance
def clkgen():
clk.next=0
while True:
yield delay(10)
clk.next = not clk
@instance
def resetOnStart():
reset.next = ACTIVE_LOW
yield clk.negedge
reset.next = INACTIVE_HIGH
@instance
def stimulus():
yield clk.negedge
rgb.next(input_list[0][0], input_list[0][1], input_list[0][2])
enable_in.next = ACTIVE_HIGH
#enable_in.next = INACTIVE_LOW if randrange(6) == 0 else ACTIVE_HIGH
for i in range(1,samples):
yield clk.negedge
yield clk.negedge
rgb.next(input_list[i][0], input_list[i][1], input_list[i][2])
yield clk.negedge
print "Output should be: %s %s %s---Real output is: %d %d %d"%(output_list[i-1][0],output_list[i-1][1],output_list[i-1][2],
ycbcr.y,ycbcr.cb,ycbcr.cr)
assert output_list[i-1][0] == ycbcr.y
assert output_list[i-1][1] == ycbcr.cb
assert output_list[i-1][2] == ycbcr.cr
raise StopSimulation
return stimulus,resetOnStart,clkgen,rgb2ycbcr_inst
def testbench():
instance=test()
instance.config_sim(trace=False)
instance.run_sim()
#instance.convert(hdl='VHDL')
verify.simulator='iverilog'
assert instance.verify_convert() == 0
if __name__ == '__main__':
testbench()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment