import re import os from configparser import ConfigParser class ModelGeneration: def __init__(self, file): # Script starts from here print("Arguement is : ", file) self.fname = os.path.basename(file) print("VHDL filename is : ", self.fname) if os.name == 'nt': self.home = os.path.join('library', 'config') else: self.home = os.path.expanduser('~') self.parser = ConfigParser() self.parser.read(os.path.join( self.home, os.path.join('.nghdl', 'config.ini'))) self.nghdl_home = self.parser.get('NGHDL', 'NGHDL_HOME') self.release_dir = self.parser.get('NGHDL', 'RELEASE') self.src_home = self.parser.get('SRC', 'SRC_HOME') self.licensefile = self.parser.get('SRC', 'LICENSE') # #### Creating connection_info.txt file from vhdl file #### # read_vhdl = open(file, 'r') vhdl_data = read_vhdl.readlines() read_vhdl.close() start_flag = -1 # Used for scaning part of data scan_data = [] # p=re.search('port(.*?)end',read_vhdl,re.M|re.I|re.DOTALL).group() for item in vhdl_data: if re.search('port', item, re.I): start_flag = 1 elif re.search("end", item, re.I): start_flag = 0 if start_flag == 1: item = re.sub("port", " ", item, flags=re.I) item = re.sub("\(", " ", item, flags=re.I) # noqa item = re.sub("\)", " ", item, flags=re.I) # noqa item = re.sub(";", " ", item, flags=re.I) if item.find(','): temp1 = item.split(",") item = "" + temp1[-1] temp2 = temp1[-1].split(":") for i in range(len(temp1) - 1): temp3 = temp1[i] + ":" + temp2[-1] scan_data.append(temp3.rstrip()) scan_data.append(item.rstrip()) scan_data = [_f for _f in scan_data if _f] elif start_flag == 0: break port_info = [] self.port_vector_info = [] for item in scan_data: print("Scan Data :", item) if re.search("in", item, flags=re.I): if re.search("std_logic_vector", item, flags=re.I): temp = re.compile(r"\s*std_logic_vector\s*", flags=re.I) elif re.search("std_logic", item, flags=re.I): temp = re.compile(r"\s*std_logic\s*", flags=re.I) else: raise ValueError("Please check your vhdl " + "code for datatype of input port") elif re.search("out", item, flags=re.I): if re.search("std_logic_vector", item, flags=re.I): temp = re.compile(r"\s*std_logic_vector\s*", flags=re.I) elif re.search("std_logic", item, flags=re.I): temp = re.compile(r"\s*std_logic\s*", flags=re.I) else: raise ValueError("Please check your vhdl " + "code for datatype of output port") else: raise ValueError( "Please check the in/out direction of your port" ) lhs = temp.split(item)[0] rhs = temp.split(item)[1] bit_info = re.compile(r"\s*downto\s*", flags=re.I).split(rhs)[0] if bit_info: port_info.append(lhs + ":" + str(int(bit_info) + int(1))) self.port_vector_info.append(1) else: port_info.append(lhs + ":" + str(int(1))) self.port_vector_info.append(0) print("Port Info :", port_info) # Open connection_info.txt file con_ifo = open('connection_info.txt', 'w') for item in port_info: word = item.split(':') con_ifo.write( word[0].strip() + ' ' + word[1].strip() + ' ' + word[2].strip() ) con_ifo.write("\n") con_ifo.close() def readPortInfo(self): # ############## Reading connection/port information ############## # # Declaring input and output list input_list = [] output_list = [] # Reading connection_info.txt file for port infomation read_file = open('connection_info.txt', 'r') data = read_file.readlines() read_file.close() # Extracting input and output port list from data print("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx") for line in data: print(line) if re.match(r'^\s*$', line): pass else: in_items = re.findall( "IN", line, re.MULTILINE | re.IGNORECASE ) out_items = re.findall( "OUT", line, re.MULTILINE | re.IGNORECASE ) if in_items: input_list.append(line.split()) if out_items: output_list.append(line.split()) print("Input List :", input_list) print("Output list :", output_list) self.input_port = [] self.output_port = [] # creating list of input and output port with its weight for input in input_list: self.input_port.append(input[0] + ":" + input[2]) for output in output_list: self.output_port.append(output[0] + ":" + output[2]) print("Output Port List : ", self.output_port) print("Input Port List : ", self.input_port) def createCfuncModFile(self): # ############## Creating content for cfunc.mod file ############## # print("Starting With cfunc.mod file") cfunc = open('cfunc.mod', 'w') print("Building content for cfunc.mod file") comment = '''/* This is cfunc.mod file auto generated by \ model_generation.py \nDeveloped by Fahim, Rahul at IIT Bombay */\n ''' header = ''' #include #include #include #include #include #include #include #include ''' if os.name == 'nt': header += ''' #undef BOOLEAN #include ''' else: header += ''' #include #include #include ''' function_open = ( '''void cm_''' + self.fname.split('.')[0] + '''(ARGS) \n{''') digital_state_output = [] for item in self.output_port: digital_state_output.append( "Digital_State_t *_op_" + item.split(':')[0] + ", *_op_" + item.split(':')[0] + "_old;" ) var_section = ''' // Declaring components of Client FILE *log_client = NULL; log_client=fopen("client.log","a"); int bytes_recieved; char send_data[1024]; char recv_data[1024]; char *key_iter; struct hostent *host; struct sockaddr_in server_addr; int sock_port = 5000+PARAM(instance_id); ''' if os.name != 'nt': var_section += ''' int socket_fd; ''' temp_input_var = [] for item in self.input_port: temp_input_var.append( "char temp_" + item.split(':')[0] + "[1024];" ) # Start of INIT function init_start_function = ''' if(INIT) { /* Allocate storage for output ports ''' \ '''and set the load for input ports */ ''' cm_event_alloc = [] cm_count_output = 0 for item in self.output_port: cm_event_alloc.append( "cm_event_alloc(" + str(cm_count_output) + "," + item.split(':')[1] + "*sizeof(Digital_State_t));" ) cm_count_output = cm_count_output + 1 load_in_port = [] for item in self.input_port: load_in_port.append( "for(Ii=0;Iih_addr); bzero(&(server_addr.sin_zero),8); ''' connect_server = ''' fprintf(log_client,"Client-Connecting to server \\n"); //Connecting to server int try_limit=10; while(try_limit>0) { if (connect(socket_fd, (struct sockaddr*)&server_addr,''' \ '''sizeof(struct sockaddr)) == -1) { sleep(1); try_limit--; if(try_limit==0) { fprintf(stderr,"Connect- Error:Tried to connect server on port,''' \ '''failed...giving up \\n"); fprintf(log_client,"Connect- Error:Tried to connect server on ''' \ '''port, failed...giving up \\n"); exit(1); } } else { printf("Client-Connected to server \\n"); fprintf(log_client,"Client-Connected to server \\n"); break; } } ''' # Assign bit value to every input assign_data_to_input = [] for item in self.input_port: assign_data_to_input.append("\tfor(Ii=0;Ii " + item.split(':')[0] + ",\n") for item in self.output_port: if self.output_port.index(item) == len(self.output_port) - 1: map.append("\t\t\t\t" + item.split(':')[0] + " => " + item.split(':')[0] + "\n") else: map.append("\t\t\t\t" + item.split(':')[0] + " => " + item.split(':')[0] + ",\n") map.append("\t\t\t);") # Testbench Clock tb_clk = "clk_s <= not clk_s after 5 us;\n\n" # Adding Process block for Vhpi process_Vhpi = [] process_Vhpi.append( "process\n\t\tvariable sock_port : integer;" + "\n\t\ttype string_ptr is access string;" + "\n\t\tvariable sock_ip : string_ptr;" + "\n\t\tbegin\n\t\tsock_port := sock_port_fun;" + "\n\t\tsock_ip := new string'(sock_ip_fun);" + "\n\t\tVhpi_Initialize(sock_port," + "Pack_String_To_Vhpi_String(sock_ip.all));" + "\n\t\twait until clk_s = '1';" + "\n\t\twhile true loop\n\t\t\twait until clk_s = '0';" + "\n\t\t\tVhpi_Listen;\n\t\t\twait for 1 us;\n\t\t\t" + "Vhpi_Send;" + "\n\t\tend loop;\n\t\twait;\n\tend process;\n\n" ) # Adding process block process = [] process.append("\tprocess\n") process.append("\t\tvariable count : integer:=0;\n") for item in self.input_port: process.append( "\t\tvariable " + item.split(':')[0] + "_v : VhpiString;\n" ) for item in self.output_port: process.append( "\t\tvariable " + item.split(':')[0] + "_v : VhpiString;\n" ) process.append("\t\tvariable obj_ref : VhpiString;\n") process.append("\tbegin\n") process.append("\t\twhile true loop\n") process.append("\t\t\twait until clk_s = '0';\n\n") port_vector_count = 0 for item in self.input_port: process.append( '\t\t\tobj_ref := Pack_String_To_Vhpi_String("' + item.split(':')[0] + '");\n' ) process.append( '\t\t\tVhpi_Get_Port_Value(obj_ref,' + item.split(':')[0] + '_v,' + item.split(':')[1] + ');\n' ) if self.port_vector_info[port_vector_count]: process.append( '\t\t\t' + item.split(':')[0] + ' <= Unpack_String(' + item.split(':')[0] + '_v,' + item.split(':')[1] + ');\n' ) else: process.append( '\t\t\t' + item.split(':')[0] + ' <= To_Std_Logic(' + item.split(':')[0] + '_v' + ');\n' ) port_vector_count += 1 process.append("\n") process.append('\t\t\twait for 1 us;\n') for item in self.output_port: if self.port_vector_info[port_vector_count]: process.append( '\t\t\t' + item.split(':')[0] + '_v := Pack_String_To_Vhpi_String' + '(Convert_SLV_To_String(' + item.split(':')[0] + '));\n' ) else: process.append( '\t\t\t' + item.split(':')[0] + '_v := Pack_String_To_Vhpi_String(To_String(' + item.split(':')[0] + '));\n' ) port_vector_count += 1 process.append( '\t\t\tobj_ref := Pack_String_To_Vhpi_String("' + item.split(':')[0] + '");\n' ) process.append( '\t\t\tVhpi_Set_Port_Value(obj_ref,' + item.split(':')[0] + '_v,' + item.split(':')[1] + ');\n' ) process.append("\n") process.append( '\t\t\treport "Iteration - "' + "& integer'image(count) severity note;\n" ) process.append('\t\t\tcount := count + 1;\n') process.append("\t\tend loop;\n") process.append("\tend process;\n\n") process.append("end architecture;") # Writing all the components to testbench file testbench.write(comment_vhdl) testbench.write(tb_header) testbench.write(tb_entity) testbench.write(arch) for item in components: testbench.write(item) for item in signals: testbench.write(item) testbench.write("\n\n") testbench.write("begin\n\n") for item in map: testbench.write(item) testbench.write("\n\t" + tb_clk) for item in process_Vhpi: testbench.write(item) for item in process: testbench.write(item) testbench.close() def createServerScript(self): # ####### Creating and writing components in start_server.sh ####### # self.digital_home = self.parser.get('NGHDL', 'DIGITAL_MODEL') self.digital_home = os.path.join(self.digital_home, "ghdl") start_server = open('start_server.sh', 'w') start_server.write("#!/bin/bash\n\n") start_server.write( "###This server run ghdl testbench for infinite time till " + "Ngspice sends kill signal to stop it\n\n" ) if os.name == 'nt': pathstr = self.digital_home + "/" + \ self.fname.split('.')[0] + "/DUTghdl/" pathstr = pathstr.replace("\\", "/") start_server.write("cd " + pathstr + "\n") else: start_server.write("cd " + self.digital_home + "/" + self.fname.split('.')[0] + "/DUTghdl/\n") start_server.write("chmod 775 sock_pkg_create.sh &&\n") start_server.write("./sock_pkg_create.sh $1 $2 &&\n") start_server.write("ghdl -i *.vhdl &&\n") start_server.write("ghdl -a *.vhdl &&\n") start_server.write("ghdl -a " + self.fname + " &&\n") start_server.write( "ghdl -a " + self.fname.split('.')[0] + "_tb.vhdl &&\n" ) if os.name == 'nt': start_server.write("ghdl -e -Wl,ghdlserver.o " + "-Wl,libws2_32.a " + self.fname.split('.')[0] + "_tb &&\n") start_server.write("./" + self.fname.split('.')[0] + "_tb.exe") else: start_server.write("ghdl -e -Wl,ghdlserver.o " + self.fname.split('.')[0] + "_tb &&\n") start_server.write( "./" + self.fname.split('.')[0] + "_tb --vcd=" + self.fname.split('.')[0] + "_tb.vcd\n") start_server.write( "gtkwave " + self.fname.split('.')[0] + "_tb.vcd 2>/dev/null") start_server.close() def createSockScript(self): # ########### Creating and writing in sock_pkg_create.sh ########### # sock_pkg_create = open('sock_pkg_create.sh', 'w') sock_pkg_create.write("#!/bin/bash\n\n") sock_pkg_create.write( "##This file creates sock_pkg.vhdl file and sets the port " + "and ip from parameters passed to it\n\n" ) sock_pkg_create.write("echo \"library ieee;\n") sock_pkg_create.write("package sock_pkg is\n") sock_pkg_create.write("\tfunction sock_port_fun return integer;\n") sock_pkg_create.write("\tfunction sock_ip_fun return string;\n") sock_pkg_create.write("end;\n\n") sock_pkg_create.write("package body sock_pkg is\n") sock_pkg_create.write("\tfunction sock_port_fun return integer is\n") sock_pkg_create.write("\t\tvariable sock_port : integer;\n") sock_pkg_create.write("\t\t\tbegin\n") sock_pkg_create.write("\t\t\t\tsock_port := $1;\n") sock_pkg_create.write("\t\t\t\treturn sock_port;\n") sock_pkg_create.write("\t\t\tend function;\n\n") sock_pkg_create.write("\tfunction sock_ip_fun return string is\n") sock_pkg_create.write("\t\ttype string_ptr is access string;\n") sock_pkg_create.write("\t\tvariable sock_ip : string_ptr;\n") sock_pkg_create.write("\t\t\tbegin\n") sock_pkg_create.write('\t\t\t\tsock_ip := new string\'(\\"$2\\");\n') sock_pkg_create.write("\t\t\t\treturn sock_ip.all;\n") sock_pkg_create.write("\t\t\tend function;\n\n") sock_pkg_create.write("\t\tend package body;\" > sock_pkg.vhdl")