package.py 4.84 KB
Newer Older
1
2
3
4
5
#!/usr/bin/python

import json
import argparse
from subprocess import Popen, STDOUT, PIPE
6
import axi4
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

script = '''
create_project -force "{0}" /tmp
ipx::infer_core -name "{0}" -vendor "{1}" -library "{2}" -version "{3}" "{4}"
set_property supported_families {{virtex7 Production qvirtex7 Production kintex7 Production kintex7l Production qkintex7 Production qkintex7l Production artix7 Production artix7l Production aartix7 Production qartix7 Production zynq Production qzynq Production azynq Production}} [ipx::current_core]
set_property core_revision 1 [ipx::current_core]
set_property display_name "{0}" [ipx::current_core]
set_property description "{0}" [ipx::current_core]
set_property taxonomy "{2}" [ipx::current_core]
ipx::add_bus_parameter POLARITY [ipx::get_bus_interfaces reset -of_objects [ipx::current_core]]
set_property value ACTIVE_HIGH [ipx::get_bus_parameters POLARITY -of_objects [ipx::get_bus_interfaces reset -of_objects [ipx::current_core]]]
ipx::update_checksums [ipx::current_core]
ipx::save_core [ipx::current_core]
close_project -delete
'''

23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
__interface_script = '''
set name    "{0}"
set vendor  "{1}"
set library "{2}"
set version "{3}"
set root    "{4}"
set mainmod "{5}"

cd $root

create_project -in_memory $root
update_ip_catalog
ipx::create_core $vendor $library $name $version

set core [ipx::current_core]

set_property supported_families {{virtex7 Production qvirtex7 Production kintex7 Production kintex7l Production qkintex7 Production qkintex7l Production artix7 Production artix7l Production aartix7 Production qartix7 Production zynq Production qzynq Production azynq Production}} $core

#set_property core_revision 1 $core
set_property display_name $name $core
set_property description $name $core
set_property taxonomy $library $core

set fg [ipx::add_file_group -type synthesis "sources" $core]
set_property -dict [list model_name $name language Verilog] $fg
ipx::import_top_level_hdl -top_level_hdl_file $mainmod -verbose $core

set clk [ipx::add_bus_interface clock $core]
set_property type_name std_logic [ipx::add_port "clock" $core]
set_property -dict [list \
  abstraction_type_vlnv {{xilinx.com:signal:clock_rtl:1.0}} \
  bus_type_vlnv {{xilinx.com:signal:clock:1.0}}] $clk
set_property physical_name "clock" [ipx::add_port_map "CLK" $clk]

set rst [ipx::add_bus_interface reset $core]
set_property type_name std_logic [ipx::add_port "reset" $core]
set_property -dict [list \
  abstraction_type_vlnv {{xilinx.com:signal:reset_rtl:1.0}} \
  bus_type_vlnv {{xilinx.com:signal:reset:1.0}}] $rst
set_property value ACTIVE_HIGH [ipx::add_bus_parameter POLARITY $rst]
set_property physical_name "reset" [ipx::add_port_map "RST" $rst]

{6}

ipx::create_default_gui_files $core
ipx::update_checksums $core
ipx::save_core $core
ipx::archive_core "$root/$name.zip" $core
#close_project -delete
'''

__axi4Tcl = '''
set if [ipx::add_bus_interface "{0}" $core]
set_property -dict [list \
  abstraction_type_vlnv {{xilinx.com:interface:axi4mm_rtl:1.0}} \
  bus_type_vlnv {{xilinx.com:interface:axi4mm:1.0}} \
  interface_mode {1}] $if
ipx::associate_bus_interfaces -busif "{0}" -clock clock -reset reset $core
foreach {{bport port}} {2} {{
  puts "$bport $port"
  set_property physical_name "$port" [ipx::add_port_map $bport $if]
}}
'''

def map_interface(name, kind):
	if kind == 'axi4master':
		script = __axi4Tcl.format(name, 'master', make_tcl_port_list(axi4.get_port_dict(name)))
		return script
	elif kind == 'axi4slave':
		script = __axi4Tcl.format(name, 'slave', make_tcl_port_list(axi4.get_port_dict(name)))
		return script
	else:
		print 'unknown interface: ' + kind
		return ''

def make_tcl_port_list(d, f=lambda x: x):
        return "[list " + ' '.join([k + ' ' + f(d[k]) for k in sorted(d.keys())]) + "]"

101
102
103
104
105
106
107
def read_json(jsonfile):
	with open(jsonfile, 'r') as jf:
		contents = jf.read()
		return json.loads(contents)

def make_vivado_script(jsonfile):
	cd = read_json(jsonfile)
108
109
110
111
112
113
114
	if ('interfaces' not in cd) or (len(cd['interfaces']) is 0):
		#print 'found no interfaces, or empty interface list, using auto-inference'
		return script.format(cd['name'], cd['vendor'], cd['library'], cd['version'], cd['root'])
	else:
		#print 'found interfaces: ', cd['interfaces']
		ifs = '\n'.join([map_interface(i['name'], i['kind']) for i in cd['interfaces']])
		return __interface_script.format(cd['name'], cd['vendor'], cd['library'], cd['version'], cd['root'], cd['root'] + '/' + cd['name'] + '.v', ifs)
115
116
117
118
119
120

def run_vivado(script):
	p = Popen(['vivado', '-mode', 'tcl', '-nolog', '-nojournal'], stdin=PIPE, stdout=PIPE, stderr=STDOUT)
	output = p.communicate(input = script)[0]
	print output.decode() 

Jens Korinth's avatar
Bugfix    
Jens Korinth committed
121
def parse_args():
122
123
124
125
	parser = argparse.ArgumentParser(description = 'Package a hardware module specified by JSON as IP-XACT.')
	parser.add_argument('json', help = 'path to JSON file')
	return parser.parse_args()

Jens Korinth's avatar
Bugfix    
Jens Korinth committed
126
args = parse_args()
127
run_vivado(make_vivado_script(args.json))
128
#print make_vivado_script(args.json)