#!/usr/bin/ruby # Create: 2014/04/10 16:30 kawasan # UpDate: 2014/04/10 16:30 kawasan # # Hex-fileをVHDL-fileに変換 (XilinxのBlockRAM割り当てされる形式) require 'date' # 取り合えず64KWord迄で設計してみる DATA_SIZE = ( 1024 * 64 * 2 ) # データ値をBIN-code文字列に変換 def i2strbin( dat, dsize ) if dsize > 16 puts( "Error : i2strbin : Non support dsize!" ) end hoge = sprintf( "000000000000000%s", dat.to_s(2) ) return hoge[hoge.size - dsize, dsize] end if ARGV.size < 4 puts( "Usage : hex2vhdl.rb filename modulename asize dsize" ) puts( "Hex-file to VHDL-file converter (ver 0.1)" ) puts( "ex.") puts( " Hex-file = test.hex" ) puts( " Module-name = PROM" ) puts( " Address-Bus Width = 13bit" ) puts( " Data-Bus Width = 16bit" ) puts( " hex2vhdl.rb test.hex PROM 13 16" ) exit end fname_source = ARGV[0] fname_dest = ARGV[1] asize = ARGV[2].to_i dsize = ARGV[3].to_i # Clear buffer bin = [0] for cnt in 0..DATA_SIZE-1 bin[cnt] = 0xff end source = open( fname_source ) segment = 0 add_end = 0 lcnt = 0 while line = source.gets cnt = 0; # 検査 レコード・マーク if line[cnt] != ':' printf( "%d:Code error!\n", lcnt ) exit end # Get レコード長 cnt += 1 ln = line[cnt,2].hex # Get ロード・アドレス cnt += 2 add = line[cnt,4].hex # Get レコード・タイプ cnt += 4 type = line[cnt,2].hex # Get データ列 dat = [0] cnt2 = 0; while ln > cnt2 cnt += 2; dat[ cnt2 ] = line[cnt,2].hex cnt2 += 1 end case type when 0x00 cnt2 = 0 while ln > cnt2 add_tmp = ( segment << 16 ) + add bin[ add_tmp ] = dat[ cnt2 ] cnt2 += 1 add += 1 if add_end < add_tmp add_end = add_tmp end end when 0x01 break when 0x02 # Get 拡張アドレス segment = dat[0,2].hex when 0x03 # Get スタート・アドレス segment = dat[0,2].hex # 今のところはスタート処理はしません else printf( "Type error!\n" ) end lcnt += 1 end source.close # --- Write ------------------------- dest = open( fname_dest + ".vhd", "wb" ) day = Time.now dest.printf( "-- hex2vhdl (kawasan) %s --\n\n", day.strftime("%Y/%m/%d") ) dest.puts( "library IEEE;" ) dest.puts( "use IEEE.std_logic_1164.all;" ) dest.puts( "use IEEE.std_logic_unsigned.all;" ) dest.puts( "use IEEE.std_logic_arith.all;\n\n" ) dest.puts( "entity PROM is" ) dest.puts( "\tport(" ) dest.puts( "\t\tCLK\t: in std_logic;" ) dest.printf( "\t\tADD\t: in std_logic_vector(%d downto 0);\n", asize - 1 ) dest.printf( "\t\tDO\t: out std_logic_vector(%d downto 0)\n", dsize - 1 ) dest.puts( "\t);" ) dest.puts( "end PROM;\n\n" ) dest.puts( "architecture rtl of PROM is" ) dest.puts( "\tsignal WR\t: std_logic := '0';" ) dest.printf( "\tsignal DI\t: std_logic_vector(%d downto 0) := \"%s\";\n", dsize - 1, i2strbin( 0, dsize ) ) dest.printf( "\tsignal ADDR_REG : std_logic_vector(%d downto 0);\n", asize - 1 ) dest.printf( "\ttype rom_type is array (0 to %d) of std_logic_vector (%d downto 0);\n", add_end >> 1, dsize - 1 ) dest.puts( "\tsignal ROM : rom_type := (" ); if dsize <= 8 add_end = add_end - 1 elsif dsize <= 16 add_end = add_end >> 1 else puts( "Error : Non support dsize!" ) exit end delm = "," for add in 0..add_end if dsize <= 8 dat = bin[add] else dat = bin[add * 2] + 0x100 * bin[add * 2 + 1] end if add >= add_end delm = ""; end dest.printf( "\t\"%s\"%s\t-- %04x\n", i2strbin( dat, dsize ), delm, add ) end dest.puts( "\t);" ) dest.puts( "begin" ) dest.puts( "\tprocess (CLK)" ) dest.puts( "\tbegin" ) dest.puts( "\t\tif (CLK'event and CLK = '1') then" ) dest.puts( "\t\t\tif (WR = '1') then" ) dest.puts( "\t\t\t\tROM(CONV_INTEGER(ADD)) <= DI;" ) dest.puts( "\t\t\tend if;" ) dest.puts( "\t\t\tADDR_REG <= ADD;" ) dest.puts( "\t\tend if;" ) dest.puts( "\tend process;" ) dest.puts( "\tDO <= ROM(CONV_INTEGER(ADDR_REG));" ) dest.puts( "end;" ) dest.close
$ hex2vhdl.rb top.hex PROM 13 16 $ head top.hex :100000000C9481000C94A3000C94A3000C94A30006 :100010000C94A3000C94A3000C94A3000C94A300D4 :100020000C94A3000C94A3000C94A3000C94A300C4 :100030000C94A3000C94A3000C94A3000C94A300B4 :100040000C94A3000C94A3000C94A3000C94A300A4 :100050000C94A3000C94A3000C94A3000C94A30094 :100060002D465047412D00547565204A756C20205F :10007000362030383A33303A3031203230313000A7 :10008000352E32366130322000456D63732D524D6E :10009000495820202020202020002D4669726D77AD $ head -40 PROM.vhd -- hex2vhdl (kawasan) 2014/07/19 -- library IEEE; use IEEE.std_logic_1164.all; use IEEE.std_logic_unsigned.all; use IEEE.std_logic_arith.all; entity PROM is port( CLK: in std_logic; ADD: in std_logic_vector(12 downto 0); DO: out std_logic_vector(15 downto 0) ); end PROM; architecture rtl of PROM is signal WR: std_logic := '0'; signal DI: std_logic_vector(15 downto 0) := "0000000000000000"; signal ADDR_REG : std_logic_vector(12 downto 0); type rom_type is array (0 to 3959) of std_logic_vector (15 downto 0); signal ROM : rom_type := ( "1001010000001100",-- 0000 "0000000010000001",-- 0001 "1001010000001100",-- 0002 "0000000010100011",-- 0003 "1001010000001100",-- 0004 "0000000010100011",-- 0005 "1001010000001100",-- 0006 "0000000010100011",-- 0007 "1001010000001100",-- 0008 "0000000010100011",-- 0009 "1001010000001100",-- 000a "0000000010100011",-- 000b "1001010000001100",-- 000c "0000000010100011",-- 000d "1001010000001100",-- 000e "0000000010100011",-- 000f "1001010000001100",-- 0010 "0000000010100011",-- 0011 "1001010000001100",-- 0012 $ tail top.hex :101E60000A0F163111F0812FF7CF87E06091EE0352 :101E700040E126E00E94D20E0E94AA0E90E01F913F :101E80000F9108950F931F93882311F400E001C070 :101E900003E080E1182F1F5F602F0E940A0F1631A8 :101EA00011F0812FF7CF87E06091EF0340E126E04A :101EB0000E94D20E0E94AA0E90E01F910F910895E9 :101EC000E62FF72FA82FB92F03C0C89531960D9292 :101ED00041505040D0F70895E62FF72FA82FB92F83 :101EE000C89531960D920020D9F70895F894FFCF48 :00000001FF $ tail -20 PROM.vhd "1001011000110001",-- 0f71 "1001001000001101",-- 0f72 "0010000000000000",-- 0f73 "1111011111011001",-- 0f74 "1001010100001000",-- 0f75 "1001010011111000",-- 0f76 "1100111111111111"-- 0f77 ); begin process (CLK) begin if (CLK'event and CLK = '1') then if (WR = '1') then ROM(CONV_INTEGER(ADD)) <= DI; end if; ADDR_REG <= ADD; end if; end process; DO <= ROM(CONV_INTEGER(ADDR_REG)); end;