#!/usr/bin/ruby -Ks # # vhd2tbtmpl.rb # v0.0.9 # 20121126 # akinobu nishi # require 'kconv' win_flag = 0 if(win_flag == 1) require 'Win32API' # 20120619 add end print("input vhdl file ex)test.vhd\n") vhdl_name = STDIN.gets.chomp p((File::dirname(vhdl_name))) vhdl_name_buf = vhdl_name.sub(File::dirname(vhdl_name),"").sub("\\","") # 20121108 add if linux then "/"?,if windows then "\\" if(File::dirname(vhdl_name) == ".") # current directory out_vhdl_name = "tb_" + vhdl_name # 20121108 del else # 絶対パス out_vhdl_name = File::dirname(vhdl_name) + "\\" + "tb_" + vhdl_name_buf # 20121108 add if linux then "/"?,if windows then "\\" end csv_name = vhdl_name.sub(".vhdl",".csv").sub(".vhd",".csv") # 20121119 add vhdlをcsvで吐き出す。 ########## # 初期化 file_out = File.open(out_vhdl_name,"w") file_out.close file_entity_out = File.open("entity_out.vhd","w") file_entity_out.close file_csv_out = File.open(csv_name,"w") # 20121119 add file_csv_out.close # 20121119 add ########## generic_flag = 0 def vhdl_name(f_name_ref) @f_name_ref = f_name_ref.chomp end def comment_check(din) if((din2 = din.lstrip) =~ /\A--/) data = nil else data = din end return data end def library_use_check(din) if(((din_lstrip = din.lstrip.downcase) =~ /\Alibrary/) || ((din_lstrip = din.lstrip.downcase) =~ /\Ause/)) data = din else data = nil end return data end def entity_check(din) if((din_lstrip = din.lstrip.downcase) =~ /\Aentity/) din2 = din_lstrip.downcase.sub("entity","") din3 = din2.sub("is","") # data = din3 data = 1 else data = 0 end return data end def generic_check(din) # if(din != nil) # din.each_byte {|c| sum = sum + c} # end if((din_lstrip = din.lstrip.downcase) =~ /\Ageneric/) din2 = din_lstrip.downcase.sub("generic","") din3 = din2.sub("is","") # data = din3 data = 1 else data = 0 end return data end def port_check(din) # if(din != nil) # din.each_byte {|c| sum = sum + c} # end if((din_lstrip = din.lstrip.downcase) =~ /\Aport/) din2 = din_lstrip.downcase.sub("port","") din3 = din2.sub("is","") # data = din3 data = 1 else data = 0 end return data end def file_out(name,type,data) file_out = File.open(name,type) file_out.write(data) file_out.close end ## init st = 1 st_entity = 1 entity_data = [] cnt = 0 ## in_file = File.open(vhdl_name, "r") while din = in_file.gets # 1行ずつデータ読み込み nilまで if(check = din.downcase.include?("entity")) st = 2 end case st when 1 dout = library_use_check(din) when 2 case st_entity when 1 dout = "" file_out("entity_out.vhd","a",din) cnt += 1 if(check = din.downcase.include?("end")) st_entity = 2 end when 2 # if(check = din.include?("generic")) # dout = "" # st_entity = 3 # print("i") # end # if(check = din.include?("port")) # dout = "" # st_entity = 4 # print("j") # end # when 3 # gen_data = generic_check # if(gen_data == "end") # st_entity = 4 # end # when 4 # port_data = port_check # if(port_data == "end") # st_entity = 5 # end else end else end file_out(out_vhdl_name,"a",dout) end st = 1 din_buf = [] comment_flag = 0 # data_gen_buf = [] # data_port_buf = [] data_gen_buf = Array.new(100000) # 20120927 change 10 to 100000 data_gen_buf.each_index{ |y| data_gen_buf[y] = Array.new(3, "") # ""で初期化 } data_port_buf = Array.new(100000) # 20120927 change 10 to 100000 data_port_buf.each_index{ |y| data_port_buf[y] = Array.new(3, "") # ""で初期化 } entity_name = "" check_str = "" i = 0 j = 0 flag = 0 data = [] din3_buf = [] din3 = "" in_file = File.open("entity_out.vhd", "r") while din = in_file.getc # 1文字ずつデータ読み込み nilまで din = din.chr din_buf = [din_buf,din] din2 = din_buf.to_s if(check = din2.include?("--")) comment_flag = 1 else end if(comment_flag == 1) ## 20121126 din_buf = din_buf - din.to_a din2 = din_buf.to_s.sub("-","") if(din == "\n") din_buf = [] comment_flag = 0 end end if(comment_flag == 0) case st when 1 check_str = "entity" if(check = din2.downcase.include?(check_str)) st = 2 din_buf = [] end when 2 check_str = " " if(din == check_str) # entity_name = din2.strip din_buf = [] st = 3 end when 3 check_str = "is" if(check = din2.downcase.include?(check_str)) din2 = din2.downcase # 20121108 add din2.sub!(check_str,"") entity_name = din2.strip st = 4 din_buf = [] p(entity_name) end when 4 i = 0 j = 0 check_str = "generic" if((check = generic_check(din2)) == 1) # if(check = din2.downcase.include?(check_str)) st = 5 din_buf = [] generic_flag = 1 # 20120916 add end check_str = "port" if((check = port_check(din2)) == 1) # if(check = din2.downcase.include?(check_str)) st = 6 din_buf = [] end when 5 check_str = "(" if(din == check_str) data1 = din2.strip din_buf = [] st = 51 end when 51 check_str = ":" if(din == check_str) din2.sub!(check_str,"") data_gen_buf[i][j] = din2.strip j += 1 din_buf = [] st = 52 end check_str = ");" if(check = din2.downcase.include?(check_str)) st = 4 din_buf = [] end when 52 check_str = ":=" if(check = din2.downcase.include?(check_str)) din2.sub!(check_str,"") data_gen_buf[i][j] = din2.strip j += 1 din_buf = [] st = 53 end check_str = "\n" if(din == check_str) din2.sub!(check_str,"") data_gen_buf[i][j] = din2.strip j += 1 din_buf = [] st = 4 end when 53 check_str = "\n" if(din == check_str) din2.sub!(check_str,"") data_gen_buf[i][j] = din2.strip i_gen_buf = i j = 0 din_buf = [] st = 54 end check_str = ";" if(din == check_str) din2.sub!(check_str,"") data_gen_buf[i][j] = din2.strip i += 1 j = 0 din_buf = [] st = 51 end when 54 i = 0 j = 0 check_str = ");" if(check = din2.include?(check_str)) din_buf = [] st = 4 end when 6 check_str = "(" if(din == check_str) data1 = din2.strip din_buf = [] st = 61 end when 61 check_str = ":" if(din == check_str) din2.sub!(check_str,"") data_port_buf[i][j] = din2.strip # j = 0 j += 1 din_buf = [] st = 62 end check_str = ");" if(check = din2.downcase.include?(check_str)) st = 7 din_buf = [] end when 62 check_str = "in out inout" if((check = din2.downcase.include?("in ")) || (check = din2.downcase.include?("out ")) || (check = din2.downcase.include?("inout"))) # 20121122 add space for inout bug data_port_buf[i][j] = din2.strip # j = 1 j += 1 din_buf = [] st = 63 end when 63 check_str = "\n" if(din == check_str) din2.sub!(check_str,"") data_port_buf[i][j] = din2.strip i_port_buf = i j = 0 din_buf = [] st = 64 # st = 64 end check_str = ";" if(din == check_str) din2.sub!(check_str,"") data_port_buf[i][j] = din2.strip # j = 2 p(data_port_buf[i][j]) i += 1 j = 0 din_buf = [] st = 61 end when 64 check_str = ");" if(check = din2.include?(check_str)) din_buf = [] st = 7 end when 7 else end end end print("\n") data = "entity tb_" + entity_name +" is end tb_" + entity_name + "; architecture tb_" + entity_name + "_arch of tb_" + entity_name + " is\n\n" file_out(out_vhdl_name,"a",data) for i in 0..i_port_buf data = "signal " + data_port_buf[i][0] + " : " + data_port_buf[i][2] + ";\n" file_out(out_vhdl_name,"a",data) end data = "COMPONENT " + entity_name + "\n" file_out(out_vhdl_name,"a",data) if(generic_flag == 1) # 20120916 add data = " generic( " file_out(out_vhdl_name,"a",data) if(data_gen_buf[0][0] != "") # 20120619 add for i in 0..i_gen_buf if(i == i_gen_buf) data = " " + data_gen_buf[i][0] + " : " + data_gen_buf[i][1] + " := " + data_gen_buf[i][2] + " " else data = " " + data_gen_buf[i][0] + " : " + data_gen_buf[i][1] + " := " + data_gen_buf[i][2] + "; " end file_out(out_vhdl_name,"a",data) end end data = " );" file_out(out_vhdl_name,"a",data) end data = " PORT ( " file_out(out_vhdl_name,"a",data) for i in 0..i_port_buf if(i == i_port_buf) data = " " + data_port_buf[i][0] + " : " + data_port_buf[i][1] + " " + data_port_buf[i][2] + "\n" else data = " " + data_port_buf[i][0] + " : " + data_port_buf[i][1] + " " + data_port_buf[i][2] + ";\n" end file_out(out_vhdl_name,"a",data) end data = " ); END COMPONENT; BEGIN " file_out(out_vhdl_name,"a",data) data = "i1 : " + entity_name + "\n" file_out(out_vhdl_name,"a",data) if(generic_flag == 1) # 20120916 add data = " generic map( " file_out(out_vhdl_name,"a",data) if(data_gen_buf[0][0] != "") # 20120619 add for i in 0..i_gen_buf if(i == i_gen_buf) data = " " + data_gen_buf[i][0] + " => " + data_gen_buf[i][2] + " " else data = " " + data_gen_buf[i][0] + " => " + data_gen_buf[i][2] + ", " end file_out(out_vhdl_name,"a",data) end end data = " )" file_out(out_vhdl_name,"a",data) end data = " PORT MAP ( " file_out(out_vhdl_name,"a",data) for i in 0..i_port_buf if(i == i_port_buf) data = " " + data_port_buf[i][0] + " => " + data_port_buf[i][0] + "\n" else data = " " + data_port_buf[i][0] + " => " + data_port_buf[i][0] + ",\n" end file_out(out_vhdl_name,"a",data) end data = " ); init1 : process begin rst_n <= '0'; wait for 3000 ns; rst_n <= '1'; wait; END process init1; init2 : process -- 10MHz = 100us/1cycle begin loop clk <= '0'; wait for 50 ns; clk <= '1'; wait for 50 ns; end loop; end process init2; " file_out(out_vhdl_name,"a",data) # 20121119 add data = " process(clk,rst_n) begin if(rst_n = '0')then -- if this parameter is included clk and rst_n(reset), please delete it. " file_out(out_vhdl_name,"a",data) for i in 0..i_port_buf if(data_port_buf[i][0].downcase != "clk" && data_port_buf[i][0].downcase != "rst_n" ) if(data_port_buf[i][1].downcase == "in") if(data_port_buf[i][2].downcase == "std_logic") data = " " + data_port_buf[i][0] + " <= " + "'0';" + "\n" elsif(check = data_port_buf[i][2].downcase.include?("std_logic_vector")) data = " " + data_port_buf[i][0] + " <= " + "(others => '0');" + "\n" elsif(check = data_port_buf[i][2].downcase.include?("signed")) data = " " + data_port_buf[i][0] + " <= " + "(others => '0');" + "\n" else data = " " + data_port_buf[i][0] + " <= " + "(others => '0');" + "\n" end file_out(out_vhdl_name,"a",data) elsif(data_port_buf[i][1].downcase == "inout") if(data_port_buf[i][2].downcase == "std_logic") data = " " + data_port_buf[i][0] + " <= " + "'Z';" + "\n" else data = " " + data_port_buf[i][0] + " <= " + "(others => 'Z');" + "\n" end file_out(out_vhdl_name,"a",data) else end end end data = " elsif(clk'event and clk = '1')then -- please write your code in this area. end if; end process; " file_out(out_vhdl_name,"a",data) data = " END tb_" + entity_name + "_arch; " file_out(out_vhdl_name,"a",data) ########## # 20121119 add for csv ########## buf = [] bus_buf = "" data = '"Name"' + ',"入出力"'+ ',"備考"' + "\n" file_out(csv_name,"a",data) for i in 0..i_port_buf if(data_port_buf[i][2].downcase != "std_logic") buf = data_port_buf[i][2].downcase.sub("(",",").sub("downto",",").sub(" to ",",").sub(")",",").split(/\s*,\s*/) p(buf) if(buf[1] != nil && buf[2] != nil) bus_buf = '[' + buf[1] + '..' + buf[2] + ']' # ex) [11..0] else bus_buf = '' end else bus_buf = '' end data = '"'+ data_port_buf[i][0] + bus_buf + '"' + ',"'+ data_port_buf[i][1].downcase + '"'+ ',"' + '"' + "\n" # 20121120 add downcase # data = '"'+ data_port_buf[i][0] + '"' + ',"'+ data_port_buf[i][1] + '"'+ ',"'+ data_port_buf[i][2] + '"' + "\n" file_out(csv_name,"a",data) end ########## p("vhd2tbtmpl end") # 20121119 # 20120619 add if(win_flag == 1) print("テストベンチ作成完了。" + out_vhdl_name + "が出力されました。\n") print("終了するには何かキーを押してください。\n") kbhit = Win32API.new('msvcrt','_kbhit',[],'l') while true if kbhit.call != 0 break end end puts "\nキーが押されました" else print("testbench template was genarated. " + out_vhdl_name + ".\n") end