Thread: [myhdl-list] More thoughts and code towards dynamic code generation
Brought to you by:
jandecaluwe
From: Samuele D. <sm...@gm...> - 2016-05-01 21:22:33
|
Hello, Finally I have some contributions to the project: After seeing some questions about VHDL "generate" like capabilities for MyHDL I started thinking about a solution. It is only a proof of concept, let me know your thoughts! The following code uses RedBaron to inspect and refactor itself in order to generate an elif statement list. A decorator is used for targeting the function to analyze: from myhdl import * from functools import wraps import inspect from redbaron import RedBaron i_redbaron = [i for i in range(2,6)] def redBaronGenerate(i_redbaron): def real_redBaronGenerate(func): with open(inspect.getsourcefile(func), "r") as source_file: red = RedBaron(source_file.read()) #find the decoratornode and the definition node (parent of the former) node = red.find("decorator", lambda x: x.value.value.name.value == "redBaronGenerate") defnode = node.parent #delete the decorator del defnode.decorators[node.index_on_parent] #search elif elifnode = defnode.find("elif") #iterate for elif insertions as desired start =elifnode.index_on_parent for i,elifindex in zip(i_redbaron , range(start,start+len(i_redbaron))): # prepare the elif template elifnodetemplate = elifnode.copy() for node in elifnodetemplate.findAll("name","i_redbaron"): node.replace(str(i)) #insert the node elifnode.parent.value.insert(elifindex,elifnodetemplate) #delete the template del elifnode.parent.value[elifnode.index_on_parent] #we dump the result to a file as a demonstration purpose #we could try also to substitute the function with the newer at runtime with open("address_gens_redbaron.py", "w") as source_file: source_file.write(red.dumps()) @wraps(func) def wrapper(*args, **kwds): return func(*args, **kwds) return wrapper return real_redBaronGenerate @block def address_gens(clk,count,datain_address,feedback_address): n = len(count) @always(clk.posedge) def address_counter(): count.next = count +1 @always(clk.posedge) def datain_address_generator(): datain_address.next = concat(count[n-2:0],count[n-2],count[n-1]) @always(clk.posedge) @redBaronGenerate(i_redbaron) def feedback_address_generator(): #REDBARON for i_redbaron in range(1,5) if count[n-1] == 0: feedback_address.next = concat(count[n:n-1],count[n-2:1],count[n-2],count[0]) elif count[n-i_redbaron] == 0: feedback_address.next = concat(count[n:n-i_redbaron],count[n-i_redbaron-1:1], count[n-i_redbaron-1],count[0]) else: feedback_address.next = count #and last 2 values are not important (actually one could be used to do half of the last butterfly) return address_counter,datain_address_generator,feedback_address_generator if __name__ == "__main__": @block def ClkDriver(clk,halfperiod): @always(delay(halfperiod)) def driveClk(): clk.next = not clk return driveClk @block def tb(clk,count,dina,fa): clk_driver = ClkDriver(clk,5) a_gen = address_gens(clk,count,dina,fa) return clk_driver,a_gen clk = Signal(False) count = Signal(modbv(0,_nrbits=8)) dina = Signal(intbv(0,_nrbits=8)) fa = Signal(intbv(0,_nrbits=8)) #address_gens(clk,count,fa).convert(hdl='Verilog') tb1 = tb(clk,count,dina,fa) tb1.config_sim(trace=True) |
From: Jan D. <ja...@ja...> - 2016-05-02 10:04:49
|
On 01/05/16 23:22, Samuele Disegna wrote: > Hello, > > Finally I have some contributions to the project: > After seeing some questions about VHDL "generate" like capabilities for MyHDL I started thinking about a solution. I am not following. MyHDL "generate" is much more powerful than VHDL can offer, including for conversion because you can use the Python interpreter to elaborate your code you first. > It is only a proof of concept, let me know your thoughts! > The following code uses RedBaron to inspect and refactor itself in order to generate an elif statement list. > A decorator is used for targeting the function to analyze: > > from myhdl import * > from functools import wraps > import inspect > from redbaron import RedBaron > > i_redbaron = [i for i in range(2,6)] > def redBaronGenerate(i_redbaron): > def real_redBaronGenerate(func): > with open(inspect.getsourcefile(func), "r") as source_file: > red = RedBaron(source_file.read()) > #find the decoratornode and the definition node (parent of the former) > node = red.find("decorator", lambda x: x.value.value.name.value == "redBaronGenerate") > defnode = node.parent > #delete the decorator > del defnode.decorators[node.index_on_parent] > #search elif > elifnode = defnode.find("elif") > #iterate for elif insertions as desired > start =elifnode.index_on_parent > for i,elifindex in zip(i_redbaron , range(start,start+len(i_redbaron))): > # prepare the elif template > elifnodetemplate = elifnode.copy() > for node in elifnodetemplate.findAll("name","i_redbaron"): > node.replace(str(i)) > #insert the node > elifnode.parent.value.insert(elifindex,elifnodetemplate) > #delete the template > del elifnode.parent.value[elifnode.index_on_parent] > #we dump the result to a file as a demonstration purpose > #we could try also to substitute the function with the newer at runtime > with open("address_gens_redbaron.py", "w") as source_file: > source_file.write(red.dumps()) > @wraps(func) > def wrapper(*args, **kwds): > return func(*args, **kwds) > return wrapper > return real_redBaronGenerate > > @block > def address_gens(clk,count,datain_address,feedback_address): > n = len(count) > > @always(clk.posedge) > def address_counter(): > count.next = count +1 > > @always(clk.posedge) > def datain_address_generator(): > datain_address.next = concat(count[n-2:0],count[n-2],count[n-1]) > > @always(clk.posedge) > @redBaronGenerate(i_redbaron) > def feedback_address_generator(): > #REDBARON for i_redbaron in range(1,5) > if count[n-1] == 0: > feedback_address.next = concat(count[n:n-1],count[n-2:1],count[n-2],count[0]) > elif count[n-i_redbaron] == 0: > feedback_address.next = concat(count[n:n-i_redbaron],count[n-i_redbaron-1:1], > count[n-i_redbaron-1],count[0]) > else: > feedback_address.next = count #and last 2 values are not important (actually one could be used to do half of the last butterfly) > > return address_counter,datain_address_generator,feedback_address_generator > > > if __name__ == "__main__": > @block > def ClkDriver(clk,halfperiod): > @always(delay(halfperiod)) > def driveClk(): > clk.next = not clk > return driveClk > @block > def tb(clk,count,dina,fa): > clk_driver = ClkDriver(clk,5) > a_gen = address_gens(clk,count,dina,fa) > return clk_driver,a_gen > > clk = Signal(False) > count = Signal(modbv(0,_nrbits=8)) > dina = Signal(intbv(0,_nrbits=8)) > fa = Signal(intbv(0,_nrbits=8)) > > #address_gens(clk,count,fa).convert(hdl='Verilog') > > tb1 = tb(clk,count,dina,fa) > tb1.config_sim(trace=True) > > > > ------------------------------------------------------------------------------ > Find and fix application performance issues faster with Applications Manager > Applications Manager provides deep performance insights into multiple tiers of > your business applications. It resolves application problems quickly and > reduces your MTTR. Get your free trial! > https://ad.doubleclick.net/ddm/clk/302982198;130105516;z > > > > _______________________________________________ > myhdl-list mailing list > myh...@li... > https://lists.sourceforge.net/lists/listinfo/myhdl-list > -- Jan Decaluwe - Resources bvba - http://www.jandecaluwe.com Python as a HDL: http://www.myhdl.org VHDL development, the modern way: http://www.sigasi.com Urubu, a static website CMS: http://urubu.jandecaluwe.com |
From: Samuele D. <sm...@gm...> - 2016-05-02 11:11:02
|
How would you use current MyHDL features to produce something like this that is convertible? I am dynamically replicating the elif template inside this always block: bi_redbaron = [i for i in range(2,6)] @always(clk.posedge) @redBaronGenerate(i_redbaron) def feedback_address_generator(): if count[n-1] == 0: feedback_address.next = concat(count[n:n-1],count[n-2:1],count[n-2],count[0]) elif count[n-i_redbaron] == 0: feedback_address.next = concat(count[n:n-i_redbaron],count[n-i_redbaron-1:1], count[n-i_redbaron-1],count[0]) else: feedback_address.next = count Generated code is: @always(clk.posedge) def feedback_address_generator(): if count[n-1] == 0: feedback_address.next = concat(count[n:n-1],count[n-2:1],count[n-2],count[0]) elif count[n-2] == 0: feedback_address.next = concat(count[n:n-2],count[n-2-1:1], count[n-2-1],count[0]) elif count[n-3] == 0: feedback_address.next = concat(count[n:n-3],count[n-3-1:1], count[n-3-1],count[0]) elif count[n-4] == 0: feedback_address.next = concat(count[n:n-4],count[n-4-1:1], count[n-4-1],count[0]) elif count[n-5] == 0: feedback_address.next = concat(count[n:n-5],count[n-5-1:1], count[n-5-1],count[0]) else: feedback_address.next = count On Mon, May 2, 2016 at 12:04 PM, Jan Decaluwe <ja...@ja...> wrote: > On 01/05/16 23:22, Samuele Disegna wrote: > > Hello, > > > > Finally I have some contributions to the project: > > After seeing some questions about VHDL "generate" like capabilities for > MyHDL I started thinking about a solution. > > I am not following. MyHDL "generate" is much more > powerful than VHDL can offer, including for conversion > because you can use the Python interpreter to elaborate > your code you first. > > > > It is only a proof of concept, let me know your thoughts! > > The following code uses RedBaron to inspect and refactor itself in order > to generate an elif statement list. > > A decorator is used for targeting the function to analyze: > > > > from myhdl import * > > from functools import wraps > > import inspect > > from redbaron import RedBaron > > > > i_redbaron = [i for i in range(2,6)] > > def redBaronGenerate(i_redbaron): > > def real_redBaronGenerate(func): > > with open(inspect.getsourcefile(func), "r") as source_file: > > red = RedBaron(source_file.read()) > > #find the decoratornode and the definition node (parent of > the former) > > node = red.find("decorator", lambda x: > x.value.value.name.value == "redBaronGenerate") > > defnode = node.parent > > #delete the decorator > > del defnode.decorators[node.index_on_parent] > > #search elif > > elifnode = defnode.find("elif") > > #iterate for elif insertions as desired > > start =elifnode.index_on_parent > > for i,elifindex in zip(i_redbaron , > range(start,start+len(i_redbaron))): > > # prepare the elif template > > elifnodetemplate = elifnode.copy() > > for node in > elifnodetemplate.findAll("name","i_redbaron"): > > node.replace(str(i)) > > #insert the node > > elifnode.parent.value.insert(elifindex,elifnodetemplate) > > #delete the template > > del elifnode.parent.value[elifnode.index_on_parent] > > #we dump the result to a file as a demonstration purpose > > #we could try also to substitute the function with the > newer at runtime > > with open("address_gens_redbaron.py", "w") as source_file: > > source_file.write(red.dumps()) > > @wraps(func) > > def wrapper(*args, **kwds): > > return func(*args, **kwds) > > return wrapper > > return real_redBaronGenerate > > > > @block > > def address_gens(clk,count,datain_address,feedback_address): > > n = len(count) > > > > @always(clk.posedge) > > def address_counter(): > > count.next = count +1 > > > > @always(clk.posedge) > > def datain_address_generator(): > > datain_address.next = concat(count[n-2:0],count[n-2],count[n-1]) > > > > @always(clk.posedge) > > @redBaronGenerate(i_redbaron) > > def feedback_address_generator(): > > #REDBARON for i_redbaron in range(1,5) > > if count[n-1] == 0: > > feedback_address.next = > concat(count[n:n-1],count[n-2:1],count[n-2],count[0]) > > elif count[n-i_redbaron] == 0: > > feedback_address.next = > concat(count[n:n-i_redbaron],count[n-i_redbaron-1:1], > > > count[n-i_redbaron-1],count[0]) > > else: > > feedback_address.next = count #and last 2 values are not > important (actually one could be used to do half of the last butterfly) > > > > return > address_counter,datain_address_generator,feedback_address_generator > > > > > > if __name__ == "__main__": > > @block > > def ClkDriver(clk,halfperiod): > > @always(delay(halfperiod)) > > def driveClk(): > > clk.next = not clk > > return driveClk > > @block > > def tb(clk,count,dina,fa): > > clk_driver = ClkDriver(clk,5) > > a_gen = address_gens(clk,count,dina,fa) > > return clk_driver,a_gen > > > > clk = Signal(False) > > count = Signal(modbv(0,_nrbits=8)) > > dina = Signal(intbv(0,_nrbits=8)) > > fa = Signal(intbv(0,_nrbits=8)) > > > > #address_gens(clk,count,fa).convert(hdl='Verilog') > > > > tb1 = tb(clk,count,dina,fa) > > tb1.config_sim(trace=True) > > > > > > > > > ------------------------------------------------------------------------------ > > Find and fix application performance issues faster with Applications > Manager > > Applications Manager provides deep performance insights into multiple > tiers of > > your business applications. It resolves application problems quickly and > > reduces your MTTR. Get your free trial! > > https://ad.doubleclick.net/ddm/clk/302982198;130105516;z > > > > > > > > _______________________________________________ > > myhdl-list mailing list > > myh...@li... > > https://lists.sourceforge.net/lists/listinfo/myhdl-list > > > > > -- > Jan Decaluwe - Resources bvba - http://www.jandecaluwe.com > Python as a HDL: http://www.myhdl.org > VHDL development, the modern way: http://www.sigasi.com > Urubu, a static website CMS: http://urubu.jandecaluwe.com > > > > ------------------------------------------------------------------------------ > Find and fix application performance issues faster with Applications > Manager > Applications Manager provides deep performance insights into multiple > tiers of > your business applications. It resolves application problems quickly and > reduces your MTTR. Get your free trial! > https://ad.doubleclick.net/ddm/clk/302982198;130105516;z > _______________________________________________ > myhdl-list mailing list > myh...@li... > https://lists.sourceforge.net/lists/listinfo/myhdl-list > |
From: Jan D. <ja...@ja...> - 2016-05-02 11:50:34
|
Is the generated code convertible? Then we have an automated path from initial code to silicon, and the problem is solved as far as I am concerned. On 02/05/16 13:10, Samuele Disegna wrote: > > How would you use current MyHDL features to produce something like this that is convertible? I am dynamically replicating the elif template inside this always block: > > bi_redbaron = [i for i in range(2,6)] > @always(clk.posedge) > @redBaronGenerate(i_redbaron) > def feedback_address_generator(): > if count[n-1] == 0: > feedback_address.next = concat(count[n:n-1],count[n-2:1],count[n-2],count[0]) > elif count[n-i_redbaron] == 0: > feedback_address.next = concat(count[n:n-i_redbaron],count[n-i_redbaron-1:1], > count[n-i_redbaron-1],count[0]) > else: > feedback_address.next = count > > > Generated code is: > > @always(clk.posedge) > def feedback_address_generator(): > if count[n-1] == 0: > feedback_address.next = concat(count[n:n-1],count[n-2:1],count[n-2],count[0]) > elif count[n-2] == 0: > feedback_address.next = concat(count[n:n-2],count[n-2-1:1], count[n-2-1],count[0]) > elif count[n-3] == 0: > feedback_address.next = concat(count[n:n-3],count[n-3-1:1],count[n-3-1],count[0]) > elif count[n-4] == 0: > feedback_address.next = concat(count[n:n-4],count[n-4-1:1],count[n-4-1],count[0]) > elif count[n-5] == 0: > feedback_address.next = concat(count[n:n-5],count[n-5-1:1],count[n-5-1],count[0]) > else: > feedback_address.next = count > > On Mon, May 2, 2016 at 12:04 PM, Jan Decaluwe <ja...@ja... <mailto:ja...@ja...>> wrote: > > On 01/05/16 23:22, Samuele Disegna wrote: > > Hello, > > > > Finally I have some contributions to the project: > > After seeing some questions about VHDL "generate" like capabilities for MyHDL I started thinking about a solution. > > I am not following. MyHDL "generate" is much more > powerful than VHDL can offer, including for conversion > because you can use the Python interpreter to elaborate > your code you first. > > > > It is only a proof of concept, let me know your thoughts! > > The following code uses RedBaron to inspect and refactor itself in order to generate an elif statement list. > > A decorator is used for targeting the function to analyze: > > > > from myhdl import * > > from functools import wraps > > import inspect > > from redbaron import RedBaron > > > > i_redbaron = [i for i in range(2,6)] > > def redBaronGenerate(i_redbaron): > > def real_redBaronGenerate(func): > > with open(inspect.getsourcefile(func), "r") as source_file: > > red = RedBaron(source_file.read()) > > #find the decoratornode and the definition node (parent of the former) > > node = red.find("decorator", lambda x: x.value.value.name.value == "redBaronGenerate") > > defnode = node.parent > > #delete the decorator > > del defnode.decorators[node.index_on_parent] > > #search elif > > elifnode = defnode.find("elif") > > #iterate for elif insertions as desired > > start =elifnode.index_on_parent > > for i,elifindex in zip(i_redbaron , range(start,start+len(i_redbaron))): > > # prepare the elif template > > elifnodetemplate = elifnode.copy() > > for node in elifnodetemplate.findAll("name","i_redbaron"): > > node.replace(str(i)) > > #insert the node > > elifnode.parent.value.insert(elifindex,elifnodetemplate) > > #delete the template > > del elifnode.parent.value[elifnode.index_on_parent] > > #we dump the result to a file as a demonstration purpose > > #we could try also to substitute the function with the newer at runtime > > with open("address_gens_redbaron.py", "w") as source_file: > > source_file.write(red.dumps()) > > @wraps(func) > > def wrapper(*args, **kwds): > > return func(*args, **kwds) > > return wrapper > > return real_redBaronGenerate > > > > @block > > def address_gens(clk,count,datain_address,feedback_address): > > n = len(count) > > > > @always(clk.posedge) > > def address_counter(): > > count.next = count +1 > > > > @always(clk.posedge) > > def datain_address_generator(): > > datain_address.next = concat(count[n-2:0],count[n-2],count[n-1]) > > > > @always(clk.posedge) > > @redBaronGenerate(i_redbaron) > > def feedback_address_generator(): > > #REDBARON for i_redbaron in range(1,5) > > if count[n-1] == 0: > > feedback_address.next = concat(count[n:n-1],count[n-2:1],count[n-2],count[0]) > > elif count[n-i_redbaron] == 0: > > feedback_address.next = concat(count[n:n-i_redbaron],count[n-i_redbaron-1:1], > > count[n-i_redbaron-1],count[0]) > > else: > > feedback_address.next = count #and last 2 values are not important (actually one could be used to do half of the last butterfly) > > > > return address_counter,datain_address_generator,feedback_address_generator > > > > > > if __name__ == "__main__": > > @block > > def ClkDriver(clk,halfperiod): > > @always(delay(halfperiod)) > > def driveClk(): > > clk.next = not clk > > return driveClk > > @block > > def tb(clk,count,dina,fa): > > clk_driver = ClkDriver(clk,5) > > a_gen = address_gens(clk,count,dina,fa) > > return clk_driver,a_gen > > > > clk = Signal(False) > > count = Signal(modbv(0,_nrbits=8)) > > dina = Signal(intbv(0,_nrbits=8)) > > fa = Signal(intbv(0,_nrbits=8)) > > > > #address_gens(clk,count,fa).convert(hdl='Verilog') > > > > tb1 = tb(clk,count,dina,fa) > > tb1.config_sim(trace=True) > > > > > > > > ------------------------------------------------------------------------------ > > Find and fix application performance issues faster with Applications Manager > > Applications Manager provides deep performance insights into multiple tiers of > > your business applications. It resolves application problems quickly and > > reduces your MTTR. Get your free trial! > > https://ad.doubleclick.net/ddm/clk/302982198;130105516;z > > > > > > > > _______________________________________________ > > myhdl-list mailing list > > myh...@li... <mailto:myh...@li...> > > https://lists.sourceforge.net/lists/listinfo/myhdl-list > > > > > -- > Jan Decaluwe - Resources bvba - http://www.jandecaluwe.com > Python as a HDL: http://www.myhdl.org > VHDL development, the modern way: http://www.sigasi.com > Urubu, a static website CMS: http://urubu.jandecaluwe.com > > > ------------------------------------------------------------------------------ > Find and fix application performance issues faster with Applications Manager > Applications Manager provides deep performance insights into multiple tiers of > your business applications. It resolves application problems quickly and > reduces your MTTR. Get your free trial! > https://ad.doubleclick.net/ddm/clk/302982198;130105516;z > _______________________________________________ > myhdl-list mailing list > myh...@li... <mailto:myh...@li...> > https://lists.sourceforge.net/lists/listinfo/myhdl-list > > > > > ------------------------------------------------------------------------------ > Find and fix application performance issues faster with Applications Manager > Applications Manager provides deep performance insights into multiple tiers of > your business applications. It resolves application problems quickly and > reduces your MTTR. Get your free trial! > https://ad.doubleclick.net/ddm/clk/302982198;130105516;z > > > > _______________________________________________ > myhdl-list mailing list > myh...@li... > https://lists.sourceforge.net/lists/listinfo/myhdl-list > -- Jan Decaluwe - Resources bvba - http://www.jandecaluwe.com Python as a HDL: http://www.myhdl.org VHDL development, the modern way: http://www.sigasi.com Urubu, a static website CMS: http://urubu.jandecaluwe.com |
From: Samuele D. <sm...@gm...> - 2016-05-02 12:19:55
|
Yes it is! it is a fairly simple approach but we might need some clever thoughts about what the user expect to get from it and how we want to get resulting generated code: -should it generate a new parsed file (as my example)? -should it replace the function instance at runtime while simulating? The nice thing of this approach is that it is orthogonal to MyHDL development because it aims to refactor the source code to a MyHDL compatible one. If someone has some code that needs this I can look at it and start to investigate all the different approaches. Or I can look at VHDL and other modern languages and try to reach feature parity with them (first case is better because as you said we have much many capabilities in MyHDL, and therefore we can do better) Henry G., let me know how we can interact if you are interested! :), Samuele On Mon, May 2, 2016 at 1:50 PM, Jan Decaluwe <ja...@ja...> wrote: > Is the generated code convertible? Then we have an automated path > from initial code to silicon, and the problem is solved as > far as I am concerned. > > On 02/05/16 13:10, Samuele Disegna wrote: > > > > How would you use current MyHDL features to produce something like this > that is convertible? I am dynamically replicating the elif template inside > this always block: > > > > bi_redbaron = [i for i in range(2,6)] > > @always(clk.posedge) > > @redBaronGenerate(i_redbaron) > > def feedback_address_generator(): > > if count[n-1] == 0: > > feedback_address.next = > concat(count[n:n-1],count[n-2:1],count[n-2],count[0]) > > elif count[n-i_redbaron] == 0: > > feedback_address.next = > concat(count[n:n-i_redbaron],count[n-i_redbaron-1:1], > > > count[n-i_redbaron-1],count[0]) > > else: > > feedback_address.next = count > > > > > > Generated code is: > > > > @always(clk.posedge) > > def feedback_address_generator(): > > if count[n-1] == 0: > > feedback_address.next = > concat(count[n:n-1],count[n-2:1],count[n-2],count[0]) > > elif count[n-2] == 0: > > feedback_address.next = concat(count[n:n-2],count[n-2-1:1], > count[n-2-1],count[0]) > > elif count[n-3] == 0: > > feedback_address.next = > concat(count[n:n-3],count[n-3-1:1],count[n-3-1],count[0]) > > elif count[n-4] == 0: > > feedback_address.next = > concat(count[n:n-4],count[n-4-1:1],count[n-4-1],count[0]) > > elif count[n-5] == 0: > > feedback_address.next = > concat(count[n:n-5],count[n-5-1:1],count[n-5-1],count[0]) > > else: > > feedback_address.next = count > > > > On Mon, May 2, 2016 at 12:04 PM, Jan Decaluwe <ja...@ja... > <mailto:ja...@ja...>> wrote: > > > > On 01/05/16 23:22, Samuele Disegna wrote: > > > Hello, > > > > > > Finally I have some contributions to the project: > > > After seeing some questions about VHDL "generate" like > capabilities for MyHDL I started thinking about a solution. > > > > I am not following. MyHDL "generate" is much more > > powerful than VHDL can offer, including for conversion > > because you can use the Python interpreter to elaborate > > your code you first. > > > > > > > It is only a proof of concept, let me know your thoughts! > > > The following code uses RedBaron to inspect and refactor itself > in order to generate an elif statement list. > > > A decorator is used for targeting the function to analyze: > > > > > > from myhdl import * > > > from functools import wraps > > > import inspect > > > from redbaron import RedBaron > > > > > > i_redbaron = [i for i in range(2,6)] > > > def redBaronGenerate(i_redbaron): > > > def real_redBaronGenerate(func): > > > with open(inspect.getsourcefile(func), "r") as > source_file: > > > red = RedBaron(source_file.read()) > > > #find the decoratornode and the definition node > (parent of the former) > > > node = red.find("decorator", lambda x: > x.value.value.name.value == "redBaronGenerate") > > > defnode = node.parent > > > #delete the decorator > > > del defnode.decorators[node.index_on_parent] > > > #search elif > > > elifnode = defnode.find("elif") > > > #iterate for elif insertions as desired > > > start =elifnode.index_on_parent > > > for i,elifindex in zip(i_redbaron , > range(start,start+len(i_redbaron))): > > > # prepare the elif template > > > elifnodetemplate = elifnode.copy() > > > for node in > elifnodetemplate.findAll("name","i_redbaron"): > > > node.replace(str(i)) > > > #insert the node > > > > elifnode.parent.value.insert(elifindex,elifnodetemplate) > > > #delete the template > > > del elifnode.parent.value[elifnode.index_on_parent] > > > #we dump the result to a file as a demonstration > purpose > > > #we could try also to substitute the function with > the newer at runtime > > > with open("address_gens_redbaron.py", "w") as > source_file: > > > source_file.write(red.dumps()) > > > @wraps(func) > > > def wrapper(*args, **kwds): > > > return func(*args, **kwds) > > > return wrapper > > > return real_redBaronGenerate > > > > > > @block > > > def address_gens(clk,count,datain_address,feedback_address): > > > n = len(count) > > > > > > @always(clk.posedge) > > > def address_counter(): > > > count.next = count +1 > > > > > > @always(clk.posedge) > > > def datain_address_generator(): > > > datain_address.next = > concat(count[n-2:0],count[n-2],count[n-1]) > > > > > > @always(clk.posedge) > > > @redBaronGenerate(i_redbaron) > > > def feedback_address_generator(): > > > #REDBARON for i_redbaron in range(1,5) > > > if count[n-1] == 0: > > > feedback_address.next = > concat(count[n:n-1],count[n-2:1],count[n-2],count[0]) > > > elif count[n-i_redbaron] == 0: > > > feedback_address.next = > concat(count[n:n-i_redbaron],count[n-i_redbaron-1:1], > > > > count[n-i_redbaron-1],count[0]) > > > else: > > > feedback_address.next = count #and last 2 values are > not important (actually one could be used to do half of the last butterfly) > > > > > > return > address_counter,datain_address_generator,feedback_address_generator > > > > > > > > > if __name__ == "__main__": > > > @block > > > def ClkDriver(clk,halfperiod): > > > @always(delay(halfperiod)) > > > def driveClk(): > > > clk.next = not clk > > > return driveClk > > > @block > > > def tb(clk,count,dina,fa): > > > clk_driver = ClkDriver(clk,5) > > > a_gen = address_gens(clk,count,dina,fa) > > > return clk_driver,a_gen > > > > > > clk = Signal(False) > > > count = Signal(modbv(0,_nrbits=8)) > > > dina = Signal(intbv(0,_nrbits=8)) > > > fa = Signal(intbv(0,_nrbits=8)) > > > > > > #address_gens(clk,count,fa).convert(hdl='Verilog') > > > > > > tb1 = tb(clk,count,dina,fa) > > > tb1.config_sim(trace=True) > > > > > > > > > > > > > ------------------------------------------------------------------------------ > > > Find and fix application performance issues faster with > Applications Manager > > > Applications Manager provides deep performance insights into > multiple tiers of > > > your business applications. It resolves application problems > quickly and > > > reduces your MTTR. Get your free trial! > > > https://ad.doubleclick.net/ddm/clk/302982198;130105516;z > > > > > > > > > > > > _______________________________________________ > > > myhdl-list mailing list > > > myh...@li... <mailto: > myh...@li...> > > > https://lists.sourceforge.net/lists/listinfo/myhdl-list > > > > > > > > > -- > > Jan Decaluwe - Resources bvba - http://www.jandecaluwe.com > > Python as a HDL: http://www.myhdl.org > > VHDL development, the modern way: http://www.sigasi.com > > Urubu, a static website CMS: http://urubu.jandecaluwe.com > > > > > > > ------------------------------------------------------------------------------ > > Find and fix application performance issues faster with Applications > Manager > > Applications Manager provides deep performance insights into > multiple tiers of > > your business applications. It resolves application problems quickly > and > > reduces your MTTR. Get your free trial! > > https://ad.doubleclick.net/ddm/clk/302982198;130105516;z > > _______________________________________________ > > myhdl-list mailing list > > myh...@li... <mailto: > myh...@li...> > > https://lists.sourceforge.net/lists/listinfo/myhdl-list > > > > > > > > > > > ------------------------------------------------------------------------------ > > Find and fix application performance issues faster with Applications > Manager > > Applications Manager provides deep performance insights into multiple > tiers of > > your business applications. It resolves application problems quickly and > > reduces your MTTR. Get your free trial! > > https://ad.doubleclick.net/ddm/clk/302982198;130105516;z > > > > > > > > _______________________________________________ > > myhdl-list mailing list > > myh...@li... > > https://lists.sourceforge.net/lists/listinfo/myhdl-list > > > > > -- > Jan Decaluwe - Resources bvba - http://www.jandecaluwe.com > Python as a HDL: http://www.myhdl.org > VHDL development, the modern way: http://www.sigasi.com > Urubu, a static website CMS: http://urubu.jandecaluwe.com > > > > ------------------------------------------------------------------------------ > Find and fix application performance issues faster with Applications > Manager > Applications Manager provides deep performance insights into multiple > tiers of > your business applications. It resolves application problems quickly and > reduces your MTTR. Get your free trial! > https://ad.doubleclick.net/ddm/clk/302982198;130105516;z > _______________________________________________ > myhdl-list mailing list > myh...@li... > https://lists.sourceforge.net/lists/listinfo/myhdl-list > |
From: Henry G. <he...@ma...> - 2016-05-02 12:12:24
|
On 02/05/16 12:50, Jan Decaluwe wrote: > Is the generated code convertible? Then we have an automated path > from initial code to silicon, and the problem is solved as > far as I am concerned. :) I think this could a be a really powerful technique. I'm going to have a play with it now - looking at e.g. auto loop unrolling. There is potentially a really neat tool flow here: Python -> High level translation library -> convertible code -> V* Currently, the convertible code has to be hand crafted, but it would be really cool if we could have an interim library that takes a MyHDL hierarchy and translates the functions into convertible code. It means complex cases can be handled through the translation library without it making the converter code unwieldy. I looked at PyPy for this a little while ago, but it was hard to penetrate (not least because of the rather dismissive response from the pypy developers) - Redbaron looks like it might be better suited to the problem (largely because it looks like it doesn't require any backend changes to the MyHDL converter code). Henry |
From: Henry G. <he...@ma...> - 2016-05-02 21:00:32
|
On 02/05/16 13:12, Henry Gomersall wrote: > On 02/05/16 12:50, Jan Decaluwe wrote: >> > Is the generated code convertible? Then we have an automated path >> > from initial code to silicon, and the problem is solved as >> > far as I am concerned. > :) > > I think this could a be a really powerful technique. I'm going to have a > play with it now - looking at e.g. auto loop unrolling. Whoa! This is really powerful. I've not yet done anything to show it off (more than Samuele has done anyway), but it looks like it fits really neatly with the block operator - inspecting and dynamically twiddling the code therein. Essentially it seems like a fairly easy operation to have an extra layer of elaboration to expand python stuff into convertible stuff. Bear with me, I'll have something soonish to talk about. Samuele, I'm keen to interact on this, but I need to have a play by myself a bit I think first (to thoroughly understand it). Henry |
From: Henry G. <he...@ma...> - 2016-05-02 21:02:19
|
On 02/05/16 22:00, Henry Gomersall wrote: > Essentially it seems like a fairly easy operation to have an extra layer > of elaboration to expand python stuff into convertible stuff. Sorry, *more arbitrary* python stuff into convertible *python* stuff. Henry |