Last active
May 25, 2016 16:43
-
-
Save mkatsimpris/6a9dc40fbe5bf79acd4a52ab76111392 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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() | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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