diff --git a/libopenfpga/CMakeLists.txt b/libopenfpga/CMakeLists.txt index 36bce10b6..f6f812f89 100644 --- a/libopenfpga/CMakeLists.txt +++ b/libopenfpga/CMakeLists.txt @@ -8,3 +8,4 @@ add_subdirectory(librepackdc) add_subdirectory(libfpgabitstream) add_subdirectory(libpcf) add_subdirectory(libbusgroup) +add_subdirectory(libpinconstrain) diff --git a/libopenfpga/libpinconstrain/CMakeLists.txt b/libopenfpga/libpinconstrain/CMakeLists.txt new file mode 100644 index 000000000..9ee340d87 --- /dev/null +++ b/libopenfpga/libpinconstrain/CMakeLists.txt @@ -0,0 +1,40 @@ +cmake_minimum_required(VERSION 3.9) + +project("libpinconstrain") + +file(GLOB_RECURSE EXEC_SOURCES test/*.cpp) +file(GLOB_RECURSE LIB_SOURCES src/*.cpp) +file(GLOB_RECURSE LIB_HEADERS src/*.h) +files_to_dirs(LIB_HEADERS LIB_INCLUDE_DIRS) + +file(GLOB_RECURSE BLIF_READ_HEADERS ../../vpr/src/base/*.h) +files_to_dirs(BLIF_READ_HEADERS BLIF_READ_INCLUDE_DIRS) + +file(GLOB_RECURSE VTR_UTIL_HEADERS ../../libs/libvtrutil/src/*.h) +files_to_dirs(VTR_UTIL_HEADERS VTR_UTIL_INCLUDE_DIRS) + +#Remove test executable from library +list(REMOVE_ITEM LIB_SOURCES ${EXEC_SOURCES}) + +#Create the library +add_library(libpinconstrain STATIC + ${LIB_HEADERS} + ${LIB_SOURCES}) +target_include_directories(libpinconstrain PUBLIC ${LIB_INCLUDE_DIRS} ${BLIF_READ_INCLUDE_DIRS} ${VTR_UTIL_INCLUDE_DIRS}) +set_target_properties(libpinconstrain PROPERTIES PREFIX "") #Avoid extra 'lib' prefix + +#Specify link-time dependancies +target_link_libraries(libpinconstrain + libvpr + libvtrutil + libpugixml) + +#Create the test executable +foreach(testsourcefile ${EXEC_SOURCES}) + # Use a simple string replace, to cut off .cpp. + get_filename_component(testname ${testsourcefile} NAME_WE) + add_executable(${testname} ${testsourcefile}) + target_include_directories(${testname} PUBLIC ${LIB_INCLUDE_DIRS} ${BLIF_READ_INCLUDE_DIRS} ${VTR_UTIL_INCLUDE_DIRS}) + # Make sure the library is linked to each test executable + target_link_libraries(${testname} libpinconstrain) +endforeach(testsourcefile ${EXEC_SOURCES}) diff --git a/libopenfpga/libpinconstrain/data/pinmap_qlf_k6n10_tsmc22.csv b/libopenfpga/libpinconstrain/data/pinmap_qlf_k6n10_tsmc22.csv new file mode 100755 index 000000000..ce9e78890 --- /dev/null +++ b/libopenfpga/libpinconstrain/data/pinmap_qlf_k6n10_tsmc22.csv @@ -0,0 +1,161 @@ +orientation,row,col,pin_num_in_cell,port_name,mapped_pin,GPIO_type,Associated Clock,Clock Edge +TOP,,,,gfpga_pad_IO_A2F[0],pad_fpga_io[18],,, +TOP,,,,gfpga_pad_IO_F2A[0],pad_fpga_io[18],,, +TOP,,,,gfpga_pad_IO_A2F[6],pad_fpga_io[19],,, +TOP,,,,gfpga_pad_IO_F2A[6],pad_fpga_io[19],,, +TOP,,,,gfpga_pad_IO_A2F[8],pad_fpga_io[20],,, +TOP,,,,gfpga_pad_IO_F2A[8],pad_fpga_io[20],,, +TOP,,,,gfpga_pad_IO_A2F[12],pad_fpga_io[21],,, +TOP,,,,gfpga_pad_IO_F2A[12],pad_fpga_io[21],,, +TOP,,,,gfpga_pad_IO_A2F[16],pad_fpga_io[22],,, +TOP,,,,gfpga_pad_IO_F2A[16],pad_fpga_io[22],,, +TOP,,,,gfpga_pad_IO_A2F[20],pad_fpga_io[23],,, +TOP,,,,gfpga_pad_IO_F2A[20],pad_fpga_io[23],,, +TOP,,,,gfpga_pad_IO_A2F[24],pad_fpga_io[24],,, +TOP,,,,gfpga_pad_IO_F2A[24],pad_fpga_io[24],,, +TOP,,,,gfpga_pad_IO_F2A[28],pad_fpga_io[25],,, +TOP,,,,gfpga_pad_IO_A2F[28],pad_fpga_io[25],,, +TOP,,,,gfpga_pad_IO_F2A[32],pad_fpga_io[26],,, +TOP,,,,gfpga_pad_IO_A2F[32],pad_fpga_io[26],,, +TOP,,,,gfpga_pad_IO_F2A[36],pad_fpga_io[27],,, +TOP,,,,gfpga_pad_IO_A2F[36],pad_fpga_io[27],,, +TOP,,,,gfpga_pad_IO_F2A[40],pad_fpga_io[28],,, +TOP,,,,gfpga_pad_IO_A2F[40],pad_fpga_io[28],,, +TOP,,,,gfpga_pad_IO_F2A[44],pad_fpga_io[29],,, +TOP,,,,gfpga_pad_IO_A2F[44],pad_fpga_io[29],,, +TOP,,,,gfpga_pad_IO_F2A[48],pad_fpga_io[30],,, +TOP,,,,gfpga_pad_IO_A2F[48],pad_fpga_io[30],,, +TOP,,,,gfpga_pad_IO_A2F[52],pad_fpga_io[31],,, +TOP,,,,gfpga_pad_IO_F2A[52],pad_fpga_io[31],,, +TOP,,,,gfpga_pad_IO_A2F[56],pad_fpga_io[32],,, +TOP,,,,gfpga_pad_IO_F2A[56],pad_fpga_io[32],,, +TOP,,,,gfpga_pad_IO_A2F[60],pad_fpga_io[33],,, +TOP,,,,gfpga_pad_IO_F2A[60],pad_fpga_io[33],,, +TOP,,,,gfpga_pad_IO_A2F[64],pad_fpga_io[34],,, +TOP,,,,gfpga_pad_IO_F2A[64],pad_fpga_io[34],,, +TOP,,,,gfpga_pad_IO_A2F[68],pad_fpga_io[35],,, +TOP,,,,gfpga_pad_IO_F2A[68],pad_fpga_io[35],,, +TOP,,,,gfpga_pad_IO_A2F[72],pad_fpga_io[36],,, +TOP,,,,gfpga_pad_IO_F2A[72],pad_fpga_io[36],,, +TOP,,,,gfpga_pad_IO_A2F[76],pad_fpga_io[37],,, +TOP,,,,gfpga_pad_IO_F2A[76],pad_fpga_io[37],,, +RIGHT,,,,gfpga_pad_IO_A2F[80],pad_fpga_io[38],,, +RIGHT,,,,gfpga_pad_IO_F2A[80],pad_fpga_io[38],,, +RIGHT,,,,gfpga_pad_IO_A2F[84],pad_fpga_io[39],,, +RIGHT,,,,gfpga_pad_IO_F2A[84],pad_fpga_io[39],,, +RIGHT,,,,gfpga_pad_IO_A2F[88],pad_fpga_io[40],,, +RIGHT,,,,gfpga_pad_IO_F2A[88],pad_fpga_io[40],,, +RIGHT,,,,gfpga_pad_IO_A2F[92],pad_fpga_io[41],,, +RIGHT,,,,gfpga_pad_IO_F2A[92],pad_fpga_io[41],,, +RIGHT,,,,gfpga_pad_IO_A2F[96],pad_fpga_io[42],,, +RIGHT,,,,gfpga_pad_IO_F2A[96],pad_fpga_io[42],,, +RIGHT,,,,gfpga_pad_IO_A2F[100],pad_fpga_io[43],,, +RIGHT,,,,gfpga_pad_IO_F2A[100],pad_fpga_io[43],,, +RIGHT,,,,gfpga_pad_IO_A2F[104],pad_fpga_io[44],,, +RIGHT,,,,gfpga_pad_IO_F2A[104],pad_fpga_io[44],,, +RIGHT,,,,gfpga_pad_IO_F2A[108],pad_fpga_io[45],,, +RIGHT,,,,gfpga_pad_IO_A2F[108],pad_fpga_io[45],,, +RIGHT,,,,gfpga_pad_IO_F2A[112],pad_fpga_io[46],,, +RIGHT,,,,gfpga_pad_IO_A2F[112],pad_fpga_io[46],,, +RIGHT,,,,gfpga_pad_IO_F2A[116],pad_fpga_io[47],,, +RIGHT,,,,gfpga_pad_IO_A2F[116],pad_fpga_io[47],,, +RIGHT,,,,gfpga_pad_IO_F2A[120],pad_fpga_io[48],,, +RIGHT,,,,gfpga_pad_IO_A2F[120],pad_fpga_io[48],,, +RIGHT,,,,gfpga_pad_IO_F2A[124],pad_fpga_io[49],,, +RIGHT,,,,gfpga_pad_IO_A2F[124],pad_fpga_io[49],,, +RIGHT,,,,gfpga_pad_IO_F2A[128],pad_fpga_io[50],,, +RIGHT,,,,gfpga_pad_IO_A2F[128],pad_fpga_io[50],,, +RIGHT,,,,gfpga_pad_IO_F2A[132],pad_fpga_io[51],,, +RIGHT,,,,gfpga_pad_IO_A2F[132],pad_fpga_io[51],,, +RIGHT,,,,gfpga_pad_IO_F2A[136],pad_fpga_io[52],,, +RIGHT,,,,gfpga_pad_IO_A2F[136],pad_fpga_io[52],,, +RIGHT,,,,gfpga_pad_IO_F2A[140],pad_fpga_io[53],,, +RIGHT,,,,gfpga_pad_IO_A2F[140],pad_fpga_io[53],,, +RIGHT,,,,gfpga_pad_IO_F2A[144],pad_fpga_io[54],,, +RIGHT,,,,gfpga_pad_IO_A2F[144],pad_fpga_io[54],,, +RIGHT,,,,gfpga_pad_IO_F2A[148],pad_fpga_io[55],,, +RIGHT,,,,gfpga_pad_IO_A2F[148],pad_fpga_io[55],,, +RIGHT,,,,gfpga_pad_IO_F2A[152],pad_fpga_io[56],,, +RIGHT,,,,gfpga_pad_IO_A2F[152],pad_fpga_io[56],,, +RIGHT,,,,gfpga_pad_IO_A2F[156],pad_fpga_io[57],,, +RIGHT,,,,gfpga_pad_IO_F2A[156],pad_fpga_io[57],,, +BOTTOM,,,,gfpga_pad_IO_A2F[160],pad_fpga_io[58],,, +BOTTOM,,,,gfpga_pad_IO_F2A[160],pad_fpga_io[58],,, +BOTTOM,,,,gfpga_pad_IO_A2F[164],pad_fpga_io[59],,, +BOTTOM,,,,gfpga_pad_IO_F2A[164],pad_fpga_io[59],,, +BOTTOM,,,,gfpga_pad_IO_A2F[168],pad_fpga_io[60],,, +BOTTOM,,,,gfpga_pad_IO_F2A[168],pad_fpga_io[60],,, +BOTTOM,,,,gfpga_pad_IO_A2F[172],pad_fpga_io[61],,, +BOTTOM,,,,gfpga_pad_IO_F2A[172],pad_fpga_io[61],,, +BOTTOM,,,,gfpga_pad_IO_A2F[176],pad_fpga_io[62],,, +BOTTOM,,,,gfpga_pad_IO_F2A[176],pad_fpga_io[62],,, +BOTTOM,,,,gfpga_pad_IO_A2F[180],pad_fpga_io[63],,, +BOTTOM,,,,gfpga_pad_IO_F2A[180],pad_fpga_io[63],,, +BOTTOM,,,,gfpga_pad_IO_A2F[184],pad_fpga_io[64],,, +BOTTOM,,,,gfpga_pad_IO_F2A[184],pad_fpga_io[64],,, +BOTTOM,,,,gfpga_pad_IO_A2F[188],pad_fpga_io[65],,, +BOTTOM,,,,gfpga_pad_IO_F2A[188],pad_fpga_io[65],,, +BOTTOM,,,,gfpga_pad_IO_A2F[192],pad_fpga_io[66],,, +BOTTOM,,,,gfpga_pad_IO_F2A[192],pad_fpga_io[66],,, +BOTTOM,,,,gfpga_pad_IO_A2F[196],pad_fpga_io[67],,, +BOTTOM,,,,gfpga_pad_IO_F2A[196],pad_fpga_io[67],,, +BOTTOM,,,,gfpga_pad_IO_A2F[200],pad_fpga_io[68],,, +BOTTOM,,,,gfpga_pad_IO_F2A[200],pad_fpga_io[68],,, +BOTTOM,,,,gfpga_pad_IO_A2F[204],pad_fpga_io[69],,, +BOTTOM,,,,gfpga_pad_IO_F2A[204],pad_fpga_io[69],,, +BOTTOM,,,,gfpga_pad_IO_F2A[208],pad_fpga_io[70],,, +BOTTOM,,,,gfpga_pad_IO_A2F[208],pad_fpga_io[70],,, +BOTTOM,,,,gfpga_pad_IO_F2A[212],pad_fpga_io[71],,, +BOTTOM,,,,gfpga_pad_IO_A2F[212],pad_fpga_io[71],,, +BOTTOM,,,,gfpga_pad_IO_F2A[216],pad_fpga_io[72],,, +BOTTOM,,,,gfpga_pad_IO_A2F[216],pad_fpga_io[72],,, +BOTTOM,,,,gfpga_pad_IO_F2A[220],pad_fpga_io[73],,, +BOTTOM,,,,gfpga_pad_IO_A2F[220],pad_fpga_io[73],,, +BOTTOM,,,,gfpga_pad_IO_F2A[224],pad_fpga_io[74],,, +BOTTOM,,,,gfpga_pad_IO_A2F[224],pad_fpga_io[74],,, +BOTTOM,,,,gfpga_pad_IO_F2A[228],pad_fpga_io[75],,, +BOTTOM,,,,gfpga_pad_IO_A2F[228],pad_fpga_io[75],,, +BOTTOM,,,,gfpga_pad_IO_F2A[232],pad_fpga_io[76],,, +BOTTOM,,,,gfpga_pad_IO_A2F[232],pad_fpga_io[76],,, +BOTTOM,,,,gfpga_pad_IO_F2A[236],pad_fpga_io[77],,, +BOTTOM,,,,gfpga_pad_IO_A2F[236],pad_fpga_io[77],,, +LEFT,,,,gfpga_pad_IO_F2A[240],pad_fpga_io[78],,, +LEFT,,,,gfpga_pad_IO_A2F[240],pad_fpga_io[78],,, +LEFT,,,,gfpga_pad_IO_F2A[244],pad_fpga_io[79],,, +LEFT,,,,gfpga_pad_IO_A2F[244],pad_fpga_io[79],,, +LEFT,,,,gfpga_pad_IO_F2A[248],pad_fpga_io[0],,, +LEFT,,,,gfpga_pad_IO_A2F[248],pad_fpga_io[0],,, +LEFT,,,,gfpga_pad_IO_A2F[252],pad_fpga_io[1],,, +LEFT,,,,gfpga_pad_IO_F2A[252],pad_fpga_io[1],,, +LEFT,,,,gfpga_pad_IO_A2F[256],pad_fpga_io[2],,, +LEFT,,,,gfpga_pad_IO_F2A[256],pad_fpga_io[2],,, +LEFT,,,,gfpga_pad_IO_A2F[260],pad_fpga_io[3],,, +LEFT,,,,gfpga_pad_IO_F2A[260],pad_fpga_io[3],,, +LEFT,,,,gfpga_pad_IO_A2F[264],pad_fpga_io[4],,, +LEFT,,,,gfpga_pad_IO_F2A[264],pad_fpga_io[4],,, +LEFT,,,,gfpga_pad_IO_A2F[268],pad_fpga_io[5],,, +LEFT,,,,gfpga_pad_IO_F2A[268],pad_fpga_io[5],,, +LEFT,,,,gfpga_pad_IO_A2F[272],pad_fpga_io[6],,, +LEFT,,,,gfpga_pad_IO_F2A[272],pad_fpga_io[6],,, +LEFT,,,,gfpga_pad_IO_A2F[276],pad_fpga_io[7],,, +LEFT,,,,gfpga_pad_IO_F2A[276],pad_fpga_io[7],,, +LEFT,,,,gfpga_pad_IO_A2F[280],pad_fpga_io[8],,, +LEFT,,,,gfpga_pad_IO_F2A[280],pad_fpga_io[8],,, +LEFT,,,,gfpga_pad_IO_A2F[284],pad_fpga_io[9],,, +LEFT,,,,gfpga_pad_IO_F2A[284],pad_fpga_io[9],,, +LEFT,,,,gfpga_pad_IO_A2F[288],pad_fpga_io[10],,, +LEFT,,,,gfpga_pad_IO_F2A[288],pad_fpga_io[10],,, +LEFT,,,,gfpga_pad_IO_A2F[292],pad_fpga_io[11],,, +LEFT,,,,gfpga_pad_IO_F2A[292],pad_fpga_io[11],,, +LEFT,,,,gfpga_pad_IO_A2F[296],pad_fpga_io[12],,, +LEFT,,,,gfpga_pad_IO_F2A[296],pad_fpga_io[12],,, +LEFT,,,,gfpga_pad_IO_A2F[300],pad_fpga_io[13],,, +LEFT,,,,gfpga_pad_IO_F2A[300],pad_fpga_io[13],,, +LEFT,,,,gfpga_pad_IO_A2F[304],pad_fpga_io[14],,, +LEFT,,,,gfpga_pad_IO_F2A[304],pad_fpga_io[14],,, +LEFT,,,,gfpga_pad_IO_F2A[308],pad_fpga_io[15],,, +LEFT,,,,gfpga_pad_IO_A2F[308],pad_fpga_io[15],,, +LEFT,,,,gfpga_pad_IO_F2A[312],pad_fpga_io[16],,, +LEFT,,,,gfpga_pad_IO_A2F[312],pad_fpga_io[16],,, +LEFT,,,,gfpga_pad_IO_F2A[316],pad_fpga_io[17],,, +LEFT,,,,gfpga_pad_IO_A2F[316],pad_fpga_io[17],,, diff --git a/libopenfpga/libpinconstrain/data/pinmap_qlf_k6n10_tsmc22.xml b/libopenfpga/libpinconstrain/data/pinmap_qlf_k6n10_tsmc22.xml new file mode 100755 index 000000000..b919edfa8 --- /dev/null +++ b/libopenfpga/libpinconstrain/data/pinmap_qlf_k6n10_tsmc22.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/libopenfpga/libpinconstrain/data/simple_pic.blif b/libopenfpga/libpinconstrain/data/simple_pic.blif new file mode 100644 index 000000000..cc29c34f6 --- /dev/null +++ b/libopenfpga/libpinconstrain/data/simple_pic.blif @@ -0,0 +1,580 @@ +# Generated by Yosys 0.10.0 (git sha1 dca8fb54a, gcc 7.5.0-3ubuntu1~18.04 -fPIC -Os) + +.model simple_pic +.inputs clk_i rst_i cyc_i stb_i adr_i[1] adr_i[2] we_i dat_i[0] dat_i[1] dat_i[2] dat_i[3] dat_i[4] dat_i[5] dat_i[6] dat_i[7] irq[1] irq[2] irq[3] irq[4] irq[5] irq[6] irq[7] irq[8] +.outputs dat_o[0] dat_o[1] dat_o[2] dat_o[3] dat_o[4] dat_o[5] dat_o[6] dat_o[7] ack_o int_o +.names $false +.names $true +1 +.names $undef +.names stb_i cyc_i ack_o ack_o_dffsre_Q_D +110 1 +.subckt dffsre C=clk_i D=ack_o_dffsre_Q_D E=$true Q=ack_o R=$true S=$true +.subckt dffsre C=clk_i D=dat_o_dffsre_Q_D[7] E=$true Q=dat_o[7] R=$true S=$true +.subckt dffsre C=clk_i D=dat_o_dffsre_Q_D[6] E=$true Q=dat_o[6] R=$true S=$true +.subckt dffsre C=clk_i D=dat_o_dffsre_Q_D[5] E=$true Q=dat_o[5] R=$true S=$true +.subckt dffsre C=clk_i D=dat_o_dffsre_Q_D[4] E=$true Q=dat_o[4] R=$true S=$true +.subckt dffsre C=clk_i D=dat_o_dffsre_Q_D[3] E=$true Q=dat_o[3] R=$true S=$true +.subckt dffsre C=clk_i D=dat_o_dffsre_Q_D[2] E=$true Q=dat_o[2] R=$true S=$true +.subckt dffsre C=clk_i D=dat_o_dffsre_Q_D[1] E=$true Q=dat_o[1] R=$true S=$true +.subckt dffsre C=clk_i D=dat_o_dffsre_Q_D[0] E=$true Q=dat_o[0] R=$true S=$true +.names adr_i[1] adr_i[2] pending[8] mask[8] pol[8] edgen[8] dat_o_dffsre_Q_D[7] +000001 1 +000011 1 +000101 1 +000111 1 +001001 1 +001011 1 +001101 1 +001111 1 +010100 1 +010101 1 +010110 1 +010111 1 +011100 1 +011101 1 +011110 1 +011111 1 +100010 1 +100011 1 +100110 1 +100111 1 +101010 1 +101011 1 +101110 1 +101111 1 +111000 1 +111001 1 +111010 1 +111011 1 +111100 1 +111101 1 +111110 1 +111111 1 +.names adr_i[1] adr_i[2] pending[7] mask[7] pol[7] edgen[7] dat_o_dffsre_Q_D[6] +000001 1 +000011 1 +000101 1 +000111 1 +001001 1 +001011 1 +001101 1 +001111 1 +010100 1 +010101 1 +010110 1 +010111 1 +011100 1 +011101 1 +011110 1 +011111 1 +100010 1 +100011 1 +100110 1 +100111 1 +101010 1 +101011 1 +101110 1 +101111 1 +111000 1 +111001 1 +111010 1 +111011 1 +111100 1 +111101 1 +111110 1 +111111 1 +.names adr_i[1] adr_i[2] pending[6] mask[6] pol[6] edgen[6] dat_o_dffsre_Q_D[5] +000001 1 +000011 1 +000101 1 +000111 1 +001001 1 +001011 1 +001101 1 +001111 1 +010100 1 +010101 1 +010110 1 +010111 1 +011100 1 +011101 1 +011110 1 +011111 1 +100010 1 +100011 1 +100110 1 +100111 1 +101010 1 +101011 1 +101110 1 +101111 1 +111000 1 +111001 1 +111010 1 +111011 1 +111100 1 +111101 1 +111110 1 +111111 1 +.names adr_i[1] adr_i[2] pending[5] mask[5] pol[5] edgen[5] dat_o_dffsre_Q_D[4] +000001 1 +000011 1 +000101 1 +000111 1 +001001 1 +001011 1 +001101 1 +001111 1 +010100 1 +010101 1 +010110 1 +010111 1 +011100 1 +011101 1 +011110 1 +011111 1 +100010 1 +100011 1 +100110 1 +100111 1 +101010 1 +101011 1 +101110 1 +101111 1 +111000 1 +111001 1 +111010 1 +111011 1 +111100 1 +111101 1 +111110 1 +111111 1 +.names adr_i[1] adr_i[2] pending[4] mask[4] pol[4] edgen[4] dat_o_dffsre_Q_D[3] +000001 1 +000011 1 +000101 1 +000111 1 +001001 1 +001011 1 +001101 1 +001111 1 +010100 1 +010101 1 +010110 1 +010111 1 +011100 1 +011101 1 +011110 1 +011111 1 +100010 1 +100011 1 +100110 1 +100111 1 +101010 1 +101011 1 +101110 1 +101111 1 +111000 1 +111001 1 +111010 1 +111011 1 +111100 1 +111101 1 +111110 1 +111111 1 +.names adr_i[1] adr_i[2] pending[3] mask[3] pol[3] edgen[3] dat_o_dffsre_Q_D[2] +000001 1 +000011 1 +000101 1 +000111 1 +001001 1 +001011 1 +001101 1 +001111 1 +010100 1 +010101 1 +010110 1 +010111 1 +011100 1 +011101 1 +011110 1 +011111 1 +100010 1 +100011 1 +100110 1 +100111 1 +101010 1 +101011 1 +101110 1 +101111 1 +111000 1 +111001 1 +111010 1 +111011 1 +111100 1 +111101 1 +111110 1 +111111 1 +.names adr_i[1] adr_i[2] pending[2] mask[2] pol[2] edgen[2] dat_o_dffsre_Q_D[1] +000001 1 +000011 1 +000101 1 +000111 1 +001001 1 +001011 1 +001101 1 +001111 1 +010100 1 +010101 1 +010110 1 +010111 1 +011100 1 +011101 1 +011110 1 +011111 1 +100010 1 +100011 1 +100110 1 +100111 1 +101010 1 +101011 1 +101110 1 +101111 1 +111000 1 +111001 1 +111010 1 +111011 1 +111100 1 +111101 1 +111110 1 +111111 1 +.names adr_i[1] adr_i[2] pending[1] mask[1] pol[1] edgen[1] dat_o_dffsre_Q_D[0] +000001 1 +000011 1 +000101 1 +000111 1 +001001 1 +001011 1 +001101 1 +001111 1 +010100 1 +010101 1 +010110 1 +010111 1 +011100 1 +011101 1 +011110 1 +011111 1 +100010 1 +100011 1 +100110 1 +100111 1 +101010 1 +101011 1 +101110 1 +101111 1 +111000 1 +111001 1 +111010 1 +111011 1 +111100 1 +111101 1 +111110 1 +111111 1 +.names lirq[8] pol[8] dirq[8] edgen[8] irq_event_dffsre_Q_D[7] +0000 1 +0010 1 +0011 1 +1100 1 +1101 1 +1110 1 +.names lirq[7] pol[7] dirq[7] edgen[7] irq_event_dffsre_Q_D[6] +0000 1 +0010 1 +0011 1 +1100 1 +1101 1 +1110 1 +.names lirq[6] pol[6] dirq[6] edgen[6] irq_event_dffsre_Q_D[5] +0000 1 +0010 1 +0011 1 +1100 1 +1101 1 +1110 1 +.names lirq[5] pol[5] dirq[5] edgen[5] irq_event_dffsre_Q_D[4] +0000 1 +0010 1 +0011 1 +1100 1 +1101 1 +1110 1 +.names lirq[4] pol[4] dirq[4] edgen[4] irq_event_dffsre_Q_D[3] +0000 1 +0010 1 +0011 1 +1100 1 +1101 1 +1110 1 +.names lirq[3] pol[3] dirq[3] edgen[3] irq_event_dffsre_Q_D[2] +0000 1 +0010 1 +0011 1 +1100 1 +1101 1 +1110 1 +.names lirq[2] pol[2] dirq[2] edgen[2] irq_event_dffsre_Q_D[1] +0000 1 +0010 1 +0011 1 +1100 1 +1101 1 +1110 1 +.names lirq[1] pol[1] dirq[1] edgen[1] irq_event_dffsre_Q_D[0] +0000 1 +0010 1 +0011 1 +1100 1 +1101 1 +1110 1 +.subckt dffsre C=clk_i D=lirq[8] E=$true Q=dirq[8] R=$true S=$true +.subckt dffsre C=clk_i D=lirq[7] E=$true Q=dirq[7] R=$true S=$true +.subckt dffsre C=clk_i D=lirq[6] E=$true Q=dirq[6] R=$true S=$true +.subckt dffsre C=clk_i D=lirq[5] E=$true Q=dirq[5] R=$true S=$true +.subckt dffsre C=clk_i D=lirq[4] E=$true Q=dirq[4] R=$true S=$true +.subckt dffsre C=clk_i D=lirq[3] E=$true Q=dirq[3] R=$true S=$true +.subckt dffsre C=clk_i D=lirq[2] E=$true Q=dirq[2] R=$true S=$true +.subckt dffsre C=clk_i D=lirq[1] E=$true Q=dirq[1] R=$true S=$true +.subckt dffsre C=clk_i D=dat_i[7] E=we_i_$lut_A_2_Y Q=edgen[8] R=rst_i S=$true +.subckt dffsre C=clk_i D=dat_i[6] E=we_i_$lut_A_2_Y Q=edgen[7] R=rst_i S=$true +.subckt dffsre C=clk_i D=dat_i[5] E=we_i_$lut_A_2_Y Q=edgen[6] R=rst_i S=$true +.subckt dffsre C=clk_i D=dat_i[4] E=we_i_$lut_A_2_Y Q=edgen[5] R=rst_i S=$true +.subckt dffsre C=clk_i D=dat_i[3] E=we_i_$lut_A_2_Y Q=edgen[4] R=rst_i S=$true +.subckt dffsre C=clk_i D=dat_i[2] E=we_i_$lut_A_2_Y Q=edgen[3] R=rst_i S=$true +.subckt dffsre C=clk_i D=dat_i[1] E=we_i_$lut_A_2_Y Q=edgen[2] R=rst_i S=$true +.subckt dffsre C=clk_i D=dat_i[0] E=we_i_$lut_A_2_Y Q=edgen[1] R=rst_i S=$true +.subckt dffsre C=clk_i D=int_o_dffsre_Q_D E=$true Q=int_o R=$true S=$true +.names int_o_dffsre_Q_D_$lut_Y_A int_o_dffsre_Q_D_$lut_Y_A_1 int_o_dffsre_Q_D_$lut_Y_A_2 pending[6] mask[6] int_o_dffsre_Q_D +00000 1 +00001 1 +00010 1 +00011 1 +00100 1 +00101 1 +00110 1 +00111 1 +01000 1 +01001 1 +01010 1 +01011 1 +01100 1 +01101 1 +01110 1 +01111 1 +10000 1 +10001 1 +10010 1 +10011 1 +10100 1 +10101 1 +10110 1 +10111 1 +11000 1 +11001 1 +11010 1 +11011 1 +11110 1 +.names pending[7] mask[7] pending[8] mask[8] int_o_dffsre_Q_D_$lut_Y_A +0000 1 +0001 1 +0011 1 +0100 1 +0101 1 +0111 1 +1100 1 +1101 1 +1111 1 +.names pending[2] mask[2] pending[3] mask[3] int_o_dffsre_Q_D_$lut_Y_A_1 +0000 1 +0001 1 +0011 1 +0100 1 +0101 1 +0111 1 +1100 1 +1101 1 +1111 1 +.names pending[1] mask[1] pending[4] mask[4] pending[5] mask[5] int_o_dffsre_Q_D_$lut_Y_A_2 +000000 1 +000001 1 +000011 1 +000100 1 +000101 1 +000111 1 +001100 1 +001101 1 +001111 1 +010000 1 +010001 1 +010011 1 +010100 1 +010101 1 +010111 1 +011100 1 +011101 1 +011111 1 +110000 1 +110001 1 +110011 1 +110100 1 +110101 1 +110111 1 +111100 1 +111101 1 +111111 1 +.subckt dffsre C=clk_i D=irq_event_dffsre_Q_D[7] E=$true Q=irq_event[8] R=$true S=$true +.subckt dffsre C=clk_i D=irq_event_dffsre_Q_D[6] E=$true Q=irq_event[7] R=$true S=$true +.subckt dffsre C=clk_i D=irq_event_dffsre_Q_D[5] E=$true Q=irq_event[6] R=$true S=$true +.subckt dffsre C=clk_i D=irq_event_dffsre_Q_D[4] E=$true Q=irq_event[5] R=$true S=$true +.subckt dffsre C=clk_i D=irq_event_dffsre_Q_D[3] E=$true Q=irq_event[4] R=$true S=$true +.subckt dffsre C=clk_i D=irq_event_dffsre_Q_D[2] E=$true Q=irq_event[3] R=$true S=$true +.subckt dffsre C=clk_i D=irq_event_dffsre_Q_D[1] E=$true Q=irq_event[2] R=$true S=$true +.subckt dffsre C=clk_i D=irq_event_dffsre_Q_D[0] E=$true Q=irq_event[1] R=$true S=$true +.subckt dffsre C=clk_i D=irq[8] E=$true Q=lirq[8] R=$true S=$true +.subckt dffsre C=clk_i D=irq[7] E=$true Q=lirq[7] R=$true S=$true +.subckt dffsre C=clk_i D=irq[6] E=$true Q=lirq[6] R=$true S=$true +.subckt dffsre C=clk_i D=irq[5] E=$true Q=lirq[5] R=$true S=$true +.subckt dffsre C=clk_i D=irq[4] E=$true Q=lirq[4] R=$true S=$true +.subckt dffsre C=clk_i D=irq[3] E=$true Q=lirq[3] R=$true S=$true +.subckt dffsre C=clk_i D=irq[2] E=$true Q=lirq[2] R=$true S=$true +.subckt dffsre C=clk_i D=irq[1] E=$true Q=lirq[1] R=$true S=$true +.subckt dffsre C=clk_i D=dat_i[7] E=we_i_$lut_A_3_Y Q=mask[8] R=$true S=rst_i +.subckt dffsre C=clk_i D=dat_i[6] E=we_i_$lut_A_3_Y Q=mask[7] R=$true S=rst_i +.subckt dffsre C=clk_i D=dat_i[5] E=we_i_$lut_A_3_Y Q=mask[6] R=$true S=rst_i +.subckt dffsre C=clk_i D=dat_i[4] E=we_i_$lut_A_3_Y Q=mask[5] R=$true S=rst_i +.subckt dffsre C=clk_i D=dat_i[3] E=we_i_$lut_A_3_Y Q=mask[4] R=$true S=rst_i +.subckt dffsre C=clk_i D=dat_i[2] E=we_i_$lut_A_3_Y Q=mask[3] R=$true S=rst_i +.subckt dffsre C=clk_i D=dat_i[1] E=we_i_$lut_A_3_Y Q=mask[2] R=$true S=rst_i +.subckt dffsre C=clk_i D=dat_i[0] E=we_i_$lut_A_3_Y Q=mask[1] R=$true S=rst_i +.subckt dffsre C=clk_i D=pending_dffsre_Q_D[7] E=$true Q=pending[8] R=rst_i S=$true +.subckt dffsre C=clk_i D=pending_dffsre_Q_D[6] E=$true Q=pending[7] R=rst_i S=$true +.subckt dffsre C=clk_i D=pending_dffsre_Q_D[5] E=$true Q=pending[6] R=rst_i S=$true +.subckt dffsre C=clk_i D=pending_dffsre_Q_D[4] E=$true Q=pending[5] R=rst_i S=$true +.subckt dffsre C=clk_i D=pending_dffsre_Q_D[3] E=$true Q=pending[4] R=rst_i S=$true +.subckt dffsre C=clk_i D=pending_dffsre_Q_D[2] E=$true Q=pending[3] R=rst_i S=$true +.subckt dffsre C=clk_i D=pending_dffsre_Q_D[1] E=$true Q=pending[2] R=rst_i S=$true +.subckt dffsre C=clk_i D=pending_dffsre_Q_D[0] E=$true Q=pending[1] R=rst_i S=$true +.subckt dffsre C=clk_i D=dat_i[7] E=we_i_$lut_A_Y Q=pol[8] R=rst_i S=$true +.subckt dffsre C=clk_i D=dat_i[6] E=we_i_$lut_A_Y Q=pol[7] R=rst_i S=$true +.subckt dffsre C=clk_i D=dat_i[5] E=we_i_$lut_A_Y Q=pol[6] R=rst_i S=$true +.subckt dffsre C=clk_i D=dat_i[4] E=we_i_$lut_A_Y Q=pol[5] R=rst_i S=$true +.subckt dffsre C=clk_i D=dat_i[3] E=we_i_$lut_A_Y Q=pol[4] R=rst_i S=$true +.subckt dffsre C=clk_i D=dat_i[2] E=we_i_$lut_A_Y Q=pol[3] R=rst_i S=$true +.subckt dffsre C=clk_i D=dat_i[1] E=we_i_$lut_A_Y Q=pol[2] R=rst_i S=$true +.subckt dffsre C=clk_i D=dat_i[0] E=we_i_$lut_A_Y Q=pol[1] R=rst_i S=$true +.names we_i stb_i cyc_i adr_i[1] adr_i[2] we_i_$lut_A_Y +11110 1 +.names we_i stb_i cyc_i adr_i[1] adr_i[2] we_i_$lut_A_1_Y +11111 1 +.names irq_event[8] pending[8] dat_i[7] we_i_$lut_A_1_Y pending_dffsre_Q_D[7] +0100 1 +0101 1 +0110 1 +1000 1 +1001 1 +1010 1 +1011 1 +1100 1 +1101 1 +1110 1 +1111 1 +.names irq_event[7] pending[7] dat_i[6] we_i_$lut_A_1_Y pending_dffsre_Q_D[6] +0100 1 +0101 1 +0110 1 +1000 1 +1001 1 +1010 1 +1011 1 +1100 1 +1101 1 +1110 1 +1111 1 +.names irq_event[6] pending[6] dat_i[5] we_i_$lut_A_1_Y pending_dffsre_Q_D[5] +0100 1 +0101 1 +0110 1 +1000 1 +1001 1 +1010 1 +1011 1 +1100 1 +1101 1 +1110 1 +1111 1 +.names irq_event[5] pending[5] dat_i[4] we_i_$lut_A_1_Y pending_dffsre_Q_D[4] +0100 1 +0101 1 +0110 1 +1000 1 +1001 1 +1010 1 +1011 1 +1100 1 +1101 1 +1110 1 +1111 1 +.names irq_event[4] pending[4] dat_i[3] we_i_$lut_A_1_Y pending_dffsre_Q_D[3] +0100 1 +0101 1 +0110 1 +1000 1 +1001 1 +1010 1 +1011 1 +1100 1 +1101 1 +1110 1 +1111 1 +.names irq_event[3] pending[3] dat_i[2] we_i_$lut_A_1_Y pending_dffsre_Q_D[2] +0100 1 +0101 1 +0110 1 +1000 1 +1001 1 +1010 1 +1011 1 +1100 1 +1101 1 +1110 1 +1111 1 +.names irq_event[2] pending[2] dat_i[1] we_i_$lut_A_1_Y pending_dffsre_Q_D[1] +0100 1 +0101 1 +0110 1 +1000 1 +1001 1 +1010 1 +1011 1 +1100 1 +1101 1 +1110 1 +1111 1 +.names irq_event[1] pending[1] dat_i[0] we_i_$lut_A_1_Y pending_dffsre_Q_D[0] +0100 1 +0101 1 +0110 1 +1000 1 +1001 1 +1010 1 +1011 1 +1100 1 +1101 1 +1110 1 +1111 1 +.names we_i stb_i cyc_i adr_i[1] adr_i[2] we_i_$lut_A_2_Y +11100 1 +.names we_i stb_i cyc_i adr_i[2] adr_i[1] we_i_$lut_A_3_Y +11110 1 +.end diff --git a/libopenfpga/libpinconstrain/data/simple_pic_cstr_pin.pcf b/libopenfpga/libpinconstrain/data/simple_pic_cstr_pin.pcf new file mode 100644 index 000000000..a875201c8 --- /dev/null +++ b/libopenfpga/libpinconstrain/data/simple_pic_cstr_pin.pcf @@ -0,0 +1,20 @@ +set_io dat_o[0] pad_fpga_io[18] +set_io dat_o[1] pad_fpga_io[19] +set_io dat_o[2] pad_fpga_io[20] +set_io dat_o[3] pad_fpga_io[21] +set_io dat_o[4] pad_fpga_io[22] +set_io dat_o[5] pad_fpga_io[23] +set_io dat_o[6] pad_fpga_io[24] +set_io dat_o[7] pad_fpga_io[25] +set_io ack_o pad_fpga_io[26] +set_io int_o pad_fpga_io[27] +set_io clk_i pad_fpga_io[28] +set_io rst_i pad_fpga_io[29] +set_io cyc_i pad_fpga_io[30] +set_io stb_i pad_fpga_io[31] +set_io adr_i[1] pad_fpga_io[32] +set_io adr_i[2] pad_fpga_io[33] +set_io we_i pad_fpga_io[60] +set_io dat_i[0] pad_fpga_io[35] +set_io dat_i[1] pad_fpga_io[36] +set_io dat_i[2] pad_fpga_io[37] diff --git a/libopenfpga/libpinconstrain/src/file_readers/blif_reader.cpp b/libopenfpga/libpinconstrain/src/file_readers/blif_reader.cpp new file mode 100644 index 000000000..46f6bf68f --- /dev/null +++ b/libopenfpga/libpinconstrain/src/file_readers/blif_reader.cpp @@ -0,0 +1,70 @@ +#include "vtr_path.h" +#include "read_blif.h" +#include "blifparse.hpp" +#include "blif_reader.h" + +// blif parser callback + using namespace blifparse; + class BlifParserCallback : public Callback { + public: + void start_parse() override {} + + void filename(std::string /*fname*/) override {} + void lineno(int /*line_num*/) override {} + + void begin_model(std::string /*model_name*/) override {} + void inputs(std::vector input_ports) override { + for (auto input_port : input_ports) { + inputs_.push_back(input_port); + } + } + void outputs(std::vector output_ports) override { + for (auto output_port : output_ports) { + outputs_.push_back(output_port); + } + } + + void names(std::vector /*nets*/, std::vector> /*so_cover*/) override {} + void latch(std::string /*input*/, std::string /*output*/, LatchType /* type*/, std::string /*control*/, LogicValue /*init*/) override {} + void subckt(std::string /*model*/, std::vector /*ports*/, std:: vector /*nets*/) override {} + void blackbox() override {} + + void end_model() override {} + + void finish_parse() override {} + + void parse_error(const int curr_lineno, const std::string& near_text, const std::string& msg) override { + fprintf(stderr, "Custom Error at line %d near '%s': %s\n", curr_lineno, near_text.c_str(), msg.c_str()); + had_error_ = true; + } + + bool had_error() { return had_error_ == true; } + std::vector get_inputs() { return inputs_;} + std::vector get_outputs() { return outputs_;} + private: + bool had_error_ = false; + std::vector inputs_; + std::vector outputs_; +}; + +// read port info from blif file +bool BlifReader::read_blif(const std::string &blif_file_name) +{ + e_circuit_format circuit_format; + auto name_ext = vtr::split_ext(blif_file_name); + if (name_ext[1] == ".blif") { + circuit_format = e_circuit_format::BLIF; + } else if (name_ext[1] == ".eblif") { + circuit_format = e_circuit_format::EBLIF; + } else { + return false; + } + BlifParserCallback callback; + blif_parse_filename(blif_file_name, callback); + if (callback.had_error()) { + return false; + } + inputs = callback.get_inputs(); + outputs = callback.get_outputs(); + return true; +} diff --git a/libopenfpga/libpinconstrain/src/file_readers/blif_reader.h b/libopenfpga/libpinconstrain/src/file_readers/blif_reader.h new file mode 100644 index 000000000..ab5829a4f --- /dev/null +++ b/libopenfpga/libpinconstrain/src/file_readers/blif_reader.h @@ -0,0 +1,37 @@ +#ifndef BLIF_READER_H +#define BLIF_READER_H + +#include +#include +#include +#include +#include +#include +#include + +/* +Supported PCF commands: + +* set_io - constrain a given to a given physical in eFPGA pinout. +* set_clk - constrain a given global clock to a given + + Every tile where is present will be constrained to use a given global clock. +*/ +using namespace std; +class BlifReader +{ + vector inputs; + vector outputs; + +public: + BlifReader() {} + BlifReader(const std::string &f) + { + read_blif(f); + } + bool read_blif(const std::string &f); + const vector& get_inputs()const { return inputs;} + const vector& get_outputs()const { return outputs;} +}; + +#endif diff --git a/libopenfpga/libpinconstrain/src/file_readers/csv_reader.cpp b/libopenfpga/libpinconstrain/src/file_readers/csv_reader.cpp new file mode 100644 index 000000000..fe14b78e7 --- /dev/null +++ b/libopenfpga/libpinconstrain/src/file_readers/csv_reader.cpp @@ -0,0 +1,52 @@ +#include "csv_reader.h" +#include + + +bool CvsReader::read_cvs(const std::string &f) +{ + std::ifstream infile(f); + if (!infile.is_open()) + { + cout << "ERROR: cound not open the file " << f << endl; + return false; + } + + std::string line; + while (std::getline(infile, line)) + { + // cout << line << " - " << endl; + if (!line.size()) + continue; + entries.push_back(vector()); + entries.back().push_back(string("")); + for (auto c : line) + { + if (isspace(c)) + continue; + if (c == ',') + { + entries.back().push_back(string("")); + } + else + entries.back().back().push_back(c); + } + } + std::vector first_v = entries[0]; + auto result1 = std::find(first_v.begin(), first_v.end(), "port_name"); + vector::iterator result2 = find(first_v.begin(), first_v.end(), "mapped_pin"); + int port_name_index = distance(first_v.begin(), result1); + int mapped_pin_index = distance(first_v.begin(), result2); + + for (auto &v : entries) + { + string port_name = v[port_name_index]; + string mapped_pin = v[mapped_pin_index]; + port_map.insert(std::pair(mapped_pin, port_name)); + //for (auto &s : v) + //{ + // cout << s << " - "; + //} + } + + return true; +} diff --git a/libopenfpga/libpinconstrain/src/file_readers/csv_reader.h b/libopenfpga/libpinconstrain/src/file_readers/csv_reader.h new file mode 100644 index 000000000..db3c8feb8 --- /dev/null +++ b/libopenfpga/libpinconstrain/src/file_readers/csv_reader.h @@ -0,0 +1,26 @@ +#ifndef CVS_READER_H +#define CVS_READER_H + +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace std; + +class CvsReader +{ + vector> entries; + map port_map; +public: + CvsReader() {} + bool read_cvs(const std::string &f); + const vector>& get_entries()const { return entries;} + const map& get_port_map()const { return port_map;} +}; + +#endif diff --git a/libopenfpga/libpinconstrain/src/file_readers/pcf_reader.cpp b/libopenfpga/libpinconstrain/src/file_readers/pcf_reader.cpp new file mode 100644 index 000000000..e4adad10f --- /dev/null +++ b/libopenfpga/libpinconstrain/src/file_readers/pcf_reader.cpp @@ -0,0 +1,27 @@ +#include "pcf_reader.h" + +bool PcfReader::read_pcf(const std::string &f) +{ + std::ifstream infile(f); + if (!infile.is_open()) + { + cout << "ERROR: cound not open the file " << f << endl; + return false; + } + std::string line; + while (std::getline(infile, line)) + { + std::istringstream iss(line); + string a, b, c; + if (!(iss >> a >> b >> c)) + { + break; + } // error + commands.push_back(vector()); + commands.back().push_back(a); + commands.back().push_back(b); + commands.back().push_back(c); + //pcf_pin_map.insert(std::pair(b, c)); + } + return true; +} diff --git a/libopenfpga/libpinconstrain/src/file_readers/pcf_reader.h b/libopenfpga/libpinconstrain/src/file_readers/pcf_reader.h new file mode 100644 index 000000000..550986ee5 --- /dev/null +++ b/libopenfpga/libpinconstrain/src/file_readers/pcf_reader.h @@ -0,0 +1,37 @@ +#ifndef PCF_READER_H +#define PCF_READER_H + +#include +#include +#include +#include +#include +#include +#include + +/* +Supported PCF commands: + +* set_io - constrain a given to a given physical in eFPGA pinout. +* set_clk - constrain a given global clock to a given + + Every tile where is present will be constrained to use a given global clock. +*/ +using namespace std; +class PcfReader +{ + vector> commands; + //std::map pcf_pin_map; + +public: + PcfReader() {} + PcfReader(const std::string &f) + { + read_pcf(f); + } + bool read_pcf(const std::string &f); + const vector>& get_commands()const { return commands;} + //const unordered_map& get_pcf_pin_map()const { return pcf_pin_map;} +}; + +#endif diff --git a/libopenfpga/libpinconstrain/src/file_readers/xml_reader.cpp b/libopenfpga/libpinconstrain/src/file_readers/xml_reader.cpp new file mode 100644 index 000000000..f26fa0982 --- /dev/null +++ b/libopenfpga/libpinconstrain/src/file_readers/xml_reader.cpp @@ -0,0 +1,243 @@ +#include "xml_reader.h" +#include +#include + +//====================================================================== +std::vector XmlReader::vec_to_scalar(std::string str) +{ + auto open_bracket_pos = str.find("["); + auto close_bracket_pos = str.find("]"); + auto colon_pos = str.find(":"); + std::vector scalar_ports; + + //Parse checks + if (open_bracket_pos == std::string::npos && close_bracket_pos != std::string::npos) { + //Close brace only + std::string msg = "near '" + str + "', missing '['"; + std::cerr << " ERROR: " << msg << std::endl; + } + + if (open_bracket_pos != std::string::npos && close_bracket_pos == std::string::npos) { + //Open brace only + std::string msg = "near '" + str + "', missing ']'"; + std::cerr << " ERROR: " << msg << std::endl; + } + + if (open_bracket_pos != std::string::npos && close_bracket_pos != std::string::npos) { + //Have open and close braces, close must be after open + if (open_bracket_pos > close_bracket_pos) { + std::string msg = "near '" + str + "', '[' after ']'"; + std::cerr << " ERROR: " << msg << std::endl; + } + } + + if (colon_pos != std::string::npos) { + //Have a colon, it must be between open/close braces + if (colon_pos > close_bracket_pos || colon_pos < open_bracket_pos) { + std::string msg = "near '" + str + "', found ':' but not between '[' and ']'"; + std::cerr << " ERROR: " << msg << std::endl; + } + } + + std::string name = str.substr(0, open_bracket_pos); + std::string first_idx_str; + std::string second_idx_str; + + if (colon_pos == std::string::npos && open_bracket_pos == std::string::npos && close_bracket_pos == std::string::npos) { + } else if (colon_pos == std::string::npos) { + first_idx_str = str.substr(open_bracket_pos + 1, close_bracket_pos); + second_idx_str = first_idx_str; + } else { + first_idx_str = str.substr(open_bracket_pos + 1, colon_pos); + second_idx_str = str.substr(colon_pos + 1, close_bracket_pos); + } + + int first_idx = std::stoi(first_idx_str); + int second_idx = std::stoi(second_idx_str); + + if (first_idx < second_idx) + { + for(int i=first_idx; i < second_idx+1; i++) + { + std::string curr_port_name = name + '[' + std::to_string(i) + ']'; + scalar_ports.push_back(curr_port_name); + } + } + else + { + for(int i=first_idx; i >= second_idx ; i--) + { + std::string curr_port_name = name + '[' + std::to_string(i) + ']'; + scalar_ports.push_back(curr_port_name); + } + } + return scalar_ports; +} +//====================================================================== +bool XmlReader::parse_io_cell (const pugi::xml_node xml_orient_io, const int row_or_col, const int io_per_cell, std::map *port_map) +{ + pugi::xpath_node_set cells = xml_orient_io.select_nodes("CELL"); + for (pugi::xpath_node_set::const_iterator it = cells.begin(); it != cells.end(); ++it) + { + pugi::xpath_node node = *it; + int startx, starty, endx, endy, i, j, x, y; + std::string port_name = node.node().attribute("port_name").as_string(); + std::string mapped_name = node.node().attribute("mapped_name").as_string(); + std::vector scalar_mapped_pins = vec_to_scalar(mapped_name); + i = 0; + + if (node.node().attribute("startx") && node.node().attribute("endx")) + { + startx = node.node().attribute("startx").as_int(); + endx = node.node().attribute("endx").as_int(); + y = row_or_col; + if (startx < endx) + { + for (x=startx; x < endx+1; x++) + { + for (j=0; j < io_per_cell; j++) + { + std::string mapped_pin = scalar_mapped_pins[i]; + PinMappingData pinMapData = PinMappingData(port_name, mapped_pin, x, y, j); + port_map->insert(std::pair(mapped_pin, pinMapData)); + i++; + } + } + } + else + { + for (x=startx; x >= endx; x--) + { + for (j=0; j < io_per_cell; j++) + { + std::string mapped_pin = scalar_mapped_pins[i]; + PinMappingData pinMapData = PinMappingData(port_name, mapped_pin, x, y, j); + port_map->insert(std::pair(mapped_pin, pinMapData)); + i++; + } + } + } + } + if (node.node().attribute("starty") && node.node().attribute("endy").value()) + { + starty = node.node().attribute("starty").as_int(); + endy = node.node().attribute("endy").as_int(); + x = row_or_col; + if (starty < endy) + { + for (y=starty; y < endy+1; y++) + { + for (j=0; j < io_per_cell; j++) + { + std::string mapped_pin = scalar_mapped_pins[i]; + PinMappingData pinMapData = PinMappingData(port_name, mapped_pin, x, y, j); + port_map->insert(std::pair(mapped_pin, pinMapData)); + i++; + } + } + } + else + { + for (y=starty; y >= endy; y--) + { + for (j=0; j < io_per_cell; j++) + { + std::string mapped_pin = scalar_mapped_pins[i]; + PinMappingData pinMapData = PinMappingData(port_name, mapped_pin, x, y, j); + port_map->insert(std::pair(mapped_pin, pinMapData)); + i++; + } + } + } + } + + } + return true; +} + +//====================================================================== +bool XmlReader::parse_io (const pugi::xml_node xml_io, const int width, const int height, const int io_per_cell, std::map *port_map) +{ + pugi::xml_node xml_top_io = xml_io.child("TOP_IO"); + if (!xml_top_io) + { + return false; + } + int io_row_top = height - 1; + if (xml_top_io.attribute("y")) + io_row_top = xml_top_io.attribute("y").as_int(); + + pugi::xml_node xml_bottom_io = xml_io.child("BOTTOM_IO"); + if (!xml_bottom_io) + { + return false; + } + int io_row_bottom = 0; + if (xml_bottom_io.attribute("y")) + io_row_bottom = xml_bottom_io.attribute("y").as_int(); + + pugi::xml_node xml_left_io = xml_io.child("LEFT_IO"); + if (!xml_left_io) + { + return false; + } + int io_col_left = 0; + if (xml_left_io.attribute("x")) + io_col_left = xml_left_io.attribute("x").as_int(); + pugi::xml_node xml_right_io = xml_io.child("RIGHT_IO"); + if (!xml_right_io) + { + return false; + } + int io_col_right = width - 1; + if (xml_right_io.attribute("x")) + io_col_right = xml_right_io.attribute("x").as_int(); + + + if (!parse_io_cell (xml_top_io, io_row_top, io_per_cell, port_map)) + return false; + if (!parse_io_cell (xml_bottom_io, io_row_bottom, io_per_cell, port_map)) + return false; + if (!parse_io_cell (xml_right_io, io_col_right, io_per_cell, port_map)) + return false; + if (!parse_io_cell (xml_left_io, io_col_left, io_per_cell, port_map)) + return false; + + return true; +} +//====================================================================== + +bool XmlReader::read_xml(const std::string &f) +{ + pugi::xml_document doc; + std::ifstream infile(f); + if (!infile.is_open()) + { + std::cerr << "ERROR: cound not open the file " << f << std::endl; + return false; + } + + pugi::xml_parse_result result = doc.load_file(f.c_str()); + + if (!result) + return false; + + pugi::xml_node device = doc.child("DEVICE"); + if (!device) + return false; + + int width = device.attribute("width").as_int(); + int height = device.attribute("height").as_int(); + int z = device.attribute("z").as_int(); + if (z <= 0) + return false; + + pugi::xml_node xml_io = device.child("IO"); + if (!xml_io) + return false; + + if (!parse_io (xml_io, width, height, z, &port_map_)) + return false; + + return true; +} diff --git a/libopenfpga/libpinconstrain/src/file_readers/xml_reader.h b/libopenfpga/libpinconstrain/src/file_readers/xml_reader.h new file mode 100644 index 000000000..253a32543 --- /dev/null +++ b/libopenfpga/libpinconstrain/src/file_readers/xml_reader.h @@ -0,0 +1,41 @@ +#ifndef XML_READER_H +#define XML_READER_H + +#include +#include +#include +#include + +#include "pugixml.hpp" + +class PinMappingData +{ + public: + PinMappingData(std::string p_name, std::string map_pin, int x, int y, int z):port_name_(p_name), mapped_pin_(map_pin), x_(x), y_(y), z_(z){} + std::string get_port_name () { return port_name_; } + std::string get_mapped_pin () { return mapped_pin_; } + int get_x () { return x_; } + int get_y () { return y_; } + int get_z () { return z_; } + private: + std::string port_name_; + std::string mapped_pin_; + int x_; + int y_; + int z_; + +}; + +class XmlReader +{ + std::map port_map_; +public: + XmlReader() {} + bool read_xml(const std::string &f); + const std::map& get_port_map()const { return port_map_;} + std::vector vec_to_scalar(std::string str); + bool parse_io_cell (const pugi::xml_node xml_orient_io, const int row_or_col, const int io_per_cell, std::map *port_map); + bool parse_io (const pugi::xml_node xml_io, const int width, const int height, const int io_per_cell, std::map *port_map); +}; + +#endif diff --git a/libopenfpga/libpinconstrain/src/main.cpp b/libopenfpga/libpinconstrain/src/main.cpp new file mode 100644 index 000000000..8e9e76b76 --- /dev/null +++ b/libopenfpga/libpinconstrain/src/main.cpp @@ -0,0 +1,23 @@ +#include +#include +#include "csv_reader.h" +#include "pcf_reader.h" +#include "xml_reader.h" +#include "cmd_line.h" +// #include "pin_location.h" +#include "pin_constrain_loc.h" + +// Convert a PCF file into a VPR io.place file. +// This requires : XML file where we can get (x, y, z) of internal port +// CSV file where we have the maching list (external, internal) ports +// PCF file: constraint file. a design pin can be assigned to an external port +// BLIF file: user design. We need to check the input and output. Special handling for outputs +// The output is a file constraint in VPR format. +// Usage options: --xml PINMAP_XML --pcf PCF --blif BLIF --output OUTPUT --xml PINMAP_XML --csv CSV_FILE + +int main(int argc, const char* argv[]) +{ + cmd_line cmd(argc, argv); + + return pin_constrain_location_cmd_line(cmd); +} diff --git a/libopenfpga/libpinconstrain/src/pin_loc/pin_constrain_loc.cpp b/libopenfpga/libpinconstrain/src/pin_loc/pin_constrain_loc.cpp new file mode 100644 index 000000000..f41d3fcfb --- /dev/null +++ b/libopenfpga/libpinconstrain/src/pin_loc/pin_constrain_loc.cpp @@ -0,0 +1,30 @@ +#include "pin_location.h" +#include "cmd_line.h" +#include "pin_constrain_loc.h" +#include +#include + +// wraper function to do the real job, it is used by openfpga shell as well +// this gurantees same behavior +int pin_constrain_location (vector args) { + if (args.size() != PIN_C_ARGUMENT_NUMBER ) { + return 1; + } + const char* pin_c_args [PIN_C_ARGUMENT_NUMBER]; + for (int i = 0; i < PIN_C_ARGUMENT_NUMBER; i++) { + pin_c_args[i] = const_cast (args[i].c_str()); + } + cmd_line pin_c_cmd (PIN_C_ARGUMENT_NUMBER, pin_c_args); + return pin_constrain_location_cmd_line(pin_c_cmd); +} + +// base function for both openfpga wrapper and pin_c executable +int pin_constrain_location_cmd_line (cmd_line& cmd) { + pin_location pl (cmd); + //pl.get_cmd().print_options(); + if (!pl.reader_and_writer()) { + return 1; + } + return 0; +} + diff --git a/libopenfpga/libpinconstrain/src/pin_loc/pin_constrain_loc.h b/libopenfpga/libpinconstrain/src/pin_loc/pin_constrain_loc.h new file mode 100644 index 000000000..6ab52a649 --- /dev/null +++ b/libopenfpga/libpinconstrain/src/pin_loc/pin_constrain_loc.h @@ -0,0 +1,12 @@ +#include "pin_location.h" +#include "cmd_line.h" +#include +#include + +// wraper function to do the real job, it is used by openfpga shell as well +// this gurantees same behavior +int pin_constrain_location (std::vector args); + +// base function for both openfpga wrapper and pin_c executable +int pin_constrain_location_cmd_line (cmd_line& cmd); + diff --git a/libopenfpga/libpinconstrain/src/pin_loc/pin_location.cpp b/libopenfpga/libpinconstrain/src/pin_loc/pin_location.cpp new file mode 100644 index 000000000..b06f26d6e --- /dev/null +++ b/libopenfpga/libpinconstrain/src/pin_loc/pin_location.cpp @@ -0,0 +1,140 @@ + +#include "csv_reader.h" +#include "pcf_reader.h" +#include "xml_reader.h" +#include "blif_reader.h" +#include "cmd_line.h" +#include "pin_location.h" +#include +#include + +const string USAGE_MSG = "usage options: --xml PINMAP_XML --pcf PCF --blif BLIF --csv CSV_FILE --output OUTPUT"; +const cmd_line & pin_location::get_cmd() const +{ + return cl_; +} + +bool pin_location::reader_and_writer() +{ + cmd_line cmd = cl_; + string xml_name = cmd.get_param("--xml"); + string csv_name = cmd.get_param("--csv"); + string pcf_name = cmd.get_param("--pcf"); + string blif_name = cmd.get_param("--blif"); + string output_name = cmd.get_param("--output"); + if ((xml_name == "") || (csv_name == "") || (pcf_name == "") || (blif_name == "")|| (output_name == "") ) + { + CERROR << error_messages[MISSING_IN_OUT_FILES] << std::endl << USAGE_MSG << endl; + return false; + } + + XmlReader rd_xml; + if (!rd_xml.read_xml(xml_name)) + { + CERROR << error_messages[PIN_LOC_XML_PARSE_ERROR] << std::endl; + return false; + } + std::map xml_port_map = rd_xml.get_port_map(); + + CvsReader rd_csv; + if (!rd_csv.read_cvs(csv_name)) + { + CERROR << error_messages[PIN_MAP_CSV_PARSE_ERROR] << std::endl; + return false; + } + map csv_port_map = rd_csv.get_port_map(); + + PcfReader rd_pcf; + if (!rd_pcf.read_pcf(pcf_name)) + { + CERROR << error_messages[PIN_CONSTRAINT_PARSE_ERROR] << std::endl; + return false; + } + + // read port info from blif file + BlifReader rd_blif; + if (!rd_blif.read_blif(blif_name)) { + CERROR << error_messages[INPUT_DESIGN_PARSE_ERROR] << std::endl; + return false; + } + std::vector inputs = rd_blif.get_inputs(); + std::vector outputs = rd_blif.get_outputs(); + + std::ofstream out_file; + out_file.open(output_name); + out_file << "#Block Name x y z\n"; + out_file << "#------------ -- -- -\n"; + + vector> pcf_pin_cstr = rd_pcf.get_commands(); + std::set constrained_ports, constrained_pins; + for (auto pin_cstr_v : pcf_pin_cstr) + { + if ((pin_cstr_v[0] != "set_io") && (pin_cstr_v[0] != "set_clk")) + continue; + + string pin_name = pin_cstr_v[1]; + string cstr_name = pin_cstr_v[2]; + auto found_in = std::find(inputs.begin(), inputs.end(), pin_name); + bool valid = false, is_out = false; + + if (found_in != inputs.end()) + valid = true; + else + { + auto found_out = std::find(outputs.begin(), outputs.end(), pin_name); + if (found_out != outputs.end()) + { + valid = true; + is_out = true; + } + else + { + CERROR << error_messages[CONSTRAINED_PORT_NOT_FOUND] << ": <" << pin_name << ">" << std::endl; + out_file.close(); + return false; + } + } + if (constrained_ports.find(pin_name) == constrained_ports.end()) { + constrained_ports.insert(pin_name); + } else { + CERROR << error_messages[RE_CONSTRAINED_PORT] << ": <" << pin_name << ">" << std::endl; + out_file.close(); + return false; + } + if (!valid) + continue; + + std::string content_to_write; + + // Get the the intternal port from the CSV file + auto element_cstr = csv_port_map.find(cstr_name); + if (element_cstr != csv_port_map.end()) + { + + if (constrained_pins.find(cstr_name) == constrained_pins.end()) { + constrained_pins.insert(cstr_name); + } else { + CERROR << error_messages[OVERLAP_PIN_IN_CONSTRAINT] << ": <" << cstr_name << ">" << std::endl; + out_file.close(); + return false; + } + + // Get the (x, y, z) from the XML reader + PinMappingData pinMapData = xml_port_map.at(element_cstr->second); + if (is_out) + { + content_to_write += "out:"; + } + content_to_write += pin_name + " " + std::to_string(pinMapData.get_x()) + " " + std::to_string(pinMapData.get_y()) + " " + std::to_string(pinMapData.get_z()) + "\n"; + } else { + CERROR << error_messages[CONSTRAINED_PIN_NOT_FOUND] << ": <" << cstr_name << ">" << std::endl; + out_file.close(); + return false; + } + + out_file << content_to_write; + } + out_file.close(); + + return true; +} diff --git a/libopenfpga/libpinconstrain/src/pin_loc/pin_location.h b/libopenfpga/libpinconstrain/src/pin_loc/pin_location.h new file mode 100644 index 000000000..40728b9a6 --- /dev/null +++ b/libopenfpga/libpinconstrain/src/pin_loc/pin_location.h @@ -0,0 +1,47 @@ +#ifndef PIN_LOCATION +#define PIN_LOCATION +#include "cmd_line.h" + +// number of arguments for "pin_c", inlcuding the "pin_c" command itself +#define PIN_C_ARGUMENT_NUMBER 11 +class pin_location { +private: + // error messages to be printed out with std::cerr + enum { + MISSING_IN_OUT_FILES = 0, + PIN_LOC_XML_PARSE_ERROR, + PIN_MAP_CSV_PARSE_ERROR, + PIN_CONSTRAINT_PARSE_ERROR, + INPUT_DESIGN_PARSE_ERROR, + CONSTRAINED_PORT_NOT_FOUND, + CONSTRAINED_PIN_NOT_FOUND, + RE_CONSTRAINED_PORT, + OVERLAP_PIN_IN_CONSTRAINT, + MAX_MESSAGE_ID + }; + std::string error_messages[MAX_MESSAGE_ID] = { + "Missing input or output file arguments", // MISSING_IN_OUT_FILES + "Pin location file parse error", // PIN_LOC_XML_PARSE_ERROR + "Pin map file parse error", // PIN_MAP_CSV_PARSE_ERROR + "Pin constraint file parse error", // PIN_CONSTRAINT_PARSE_ERROR + "Input design parse error", // INPUT_DESIGN_PARSE_ERROR + "Constrained port not found in design", // CONSTRAINED_PORT_NOT_FOUND + "Constrained pin not found in device", // CONSTRAINED_PIN_NOT_FOUND + "Re-constrained port", // RE_CONSTRAINED_PORT + "Overlap pin found in constraint" // OVERLAP_PIN_IN_CONSTRAINT + }; + #define CERROR std::cerr << "[Error] " + + cmd_line cl_; + +public: + pin_location(cmd_line& cl): cl_(cl){ + + } + const cmd_line& get_cmd()const; + bool reader_and_writer(); + +}; + + +#endif diff --git a/libopenfpga/libpinconstrain/src/util/cmd_line.cpp b/libopenfpga/libpinconstrain/src/util/cmd_line.cpp new file mode 100644 index 000000000..635129424 --- /dev/null +++ b/libopenfpga/libpinconstrain/src/util/cmd_line.cpp @@ -0,0 +1,77 @@ +#include "cmd_line.h" + +cmd_line::cmd_line(int argc, const char *argv[]) +{ + bool needVal = false; + string key; + for (int i = 1; i < argc; ++i) + { + string s(argv[i]); + if (s.size() < 2) + { + cout << "Warning: Not a valid flag \"" << s << "\" discarding" << endl; + continue; + } + if ('-' == s[0]) + { + if ('-' == s[1]) + { // param key + if (needVal) + cout << "Warning: Key " << key << " did not get a value" << endl; + needVal = true; + key = s; + } + else + { // flag + flags.insert(s); + if (needVal) + cout << "Warning: Key " << key << " did not get a value" << endl; + needVal = false; + } + } + else + { // param value + if (needVal) + { + params[key] = s; + needVal = false; + } + else + { + cout << "Warning: No key for value " << s << endl; + } + } + } +} + +bool cmd_line::is_flag_set(string &fl) +{ + return (flags.find(fl) != end(flags)); +} + +string cmd_line::get_param(const string &key) +{ + if (params.find(key) != end(params)) + return params[key]; + return ""; +} + +void cmd_line::set_flag(string &fl) +{ + flags.insert(fl); +} + +void cmd_line::set_param_value(string &key, string &val) +{ + params[key] = val; +} + +void cmd_line::print_options() const +{ + cout << "Flags :\n"; + for (auto &f : flags) + cout << "\t" << f << endl; + cout << "Params :\n"; + for (auto &p : params) + cout << "\t" << p.first << "\t" << p.second << endl; +} diff --git a/libopenfpga/libpinconstrain/src/util/cmd_line.h b/libopenfpga/libpinconstrain/src/util/cmd_line.h new file mode 100644 index 000000000..f4c532edf --- /dev/null +++ b/libopenfpga/libpinconstrain/src/util/cmd_line.h @@ -0,0 +1,23 @@ +#ifndef CMD_LINE +#define CMD_LINE +#include +#include +#include +using namespace std; +class cmd_line +{ + unordered_map params; + unordered_set flags; + +public: + cmd_line(int argc, const char *argv[]); + const unordered_set &get_flag_set() const { return flags; } + const unordered_map get_param_map() const { return params; } + bool is_flag_set(string &fl); + string get_param(const string &key); + void set_flag(string &fl); + void set_param_value(string &key, string &val); + void print_options() const; +}; + +#endif diff --git a/libopenfpga/libpinconstrain/test/main.cpp b/libopenfpga/libpinconstrain/test/main.cpp new file mode 100644 index 000000000..95ea3bf8c --- /dev/null +++ b/libopenfpga/libpinconstrain/test/main.cpp @@ -0,0 +1,30 @@ + +/******************************************************************** + * Unit test functions to validate the correctness of + * 1. parser of data structures + * 2. writer of data structures + *******************************************************************/ +/* Headers from vtrutils */ +#include "vtr_assert.h" +#include "vtr_log.h" +#include "cmd_line.h" +#include "pin_location.h" +#include "pin_constrain_loc.h" + +int main(int argc, const char** argv) { + VTR_ASSERT(argc == PIN_C_ARGUMENT_NUMBER); + string command_line; + for (int i = 0; i < argc; i++) { + if (i > 0) { + command_line += " "; + } + command_line += argv[i]; + } + VTR_LOG("Created command line <%s> for test.\n", command_line); + cmd_line pin_c_cmd (argc, argv); + VTR_LOG("Testing reader and writer.\n"); + int status = pin_constrain_location_cmd_line(pin_c_cmd); + VTR_LOG("Test result: %s.\n", status == 0 ? "PASS" : "FAIL"); + return status; +} + diff --git a/libopenfpga/libpinconstrain/test/test0/simple_pic_cstr_pin.pcf b/libopenfpga/libpinconstrain/test/test0/simple_pic_cstr_pin.pcf new file mode 100644 index 000000000..b6a221157 --- /dev/null +++ b/libopenfpga/libpinconstrain/test/test0/simple_pic_cstr_pin.pcf @@ -0,0 +1,20 @@ +set_io dat_o[0] pad_fpga_io[18] +set_io dat_o[1] pad_fpga_io[18] +set_io dat_o[2] pad_fpga_io[20] +set_io dat_o[3] pad_fpga_io[21] +set_io dat_o[4] pad_fpga_io[22] +set_io dat_o[5] pad_fpga_io[23] +set_io dat_o[6] pad_fpga_io[24] +set_io dat_o[7] pad_fpga_io[25] +set_io ack_o pad_fpga_io[26] +set_io int_o pad_fpga_io[27] +set_io clk_i pad_fpga_io[28] +set_io rst_i pad_fpga_io[29] +set_io cyc_i pad_fpga_io[30] +set_io stb_i pad_fpga_io[31] +set_io adr_i[1] pad_fpga_io[32] +set_io adr_i[2] pad_fpga_io[33] +set_io we_i pad_fpga_io[60] +set_io dat_i[0] pad_fpga_io[35] +set_io dat_i[1] pad_fpga_io[36] +set_io dat_i[2] pad_fpga_io[37] diff --git a/libopenfpga/libpinconstrain/test/test0/simple_pic_run.openfpga b/libopenfpga/libpinconstrain/test/test0/simple_pic_run.openfpga new file mode 100644 index 000000000..3076e9275 --- /dev/null +++ b/libopenfpga/libpinconstrain/test/test0/simple_pic_run.openfpga @@ -0,0 +1,9 @@ +# Run VPR for the 'and' design +#--write_rr_graph example_rr_graph.xml +# + +# constraint pin +# same to script usage (no "-net" yet): +# python3 create_ioplace.py --pcf “pcf_file” --blif “blif_file” --net “net_file” --pinmap_xml “pinmap_xml_file” --csv_file “csv_file” --output “outputplace_file” +constrain_pin_location --pcf ./simple_pic_cstr_pin.pcf --blif simple_pic.blif --net NOT_YET_SUPPORT --pinmap_xml pinmap_qlf_k6n10_tsmc22.xml --csv_file pinmap_qlf_k6n10_tsmc22.csv --output simple_pic_pin_constained.place +exit diff --git a/libopenfpga/libpinconstrain/test/test1/simple_pic_cstr_pin.pcf b/libopenfpga/libpinconstrain/test/test1/simple_pic_cstr_pin.pcf new file mode 100644 index 000000000..fc228228f --- /dev/null +++ b/libopenfpga/libpinconstrain/test/test1/simple_pic_cstr_pin.pcf @@ -0,0 +1,20 @@ +set_io dat_o[0] blahblah +set_io dat_o[1] pad_fpga_io[19] +set_io dat_o[2] pad_fpga_io[20] +set_io dat_o[3] pad_fpga_io[21] +set_io dat_o[4] pad_fpga_io[22] +set_io dat_o[5] pad_fpga_io[23] +set_io dat_o[6] pad_fpga_io[24] +set_io dat_o[7] pad_fpga_io[25] +set_io ack_o pad_fpga_io[26] +set_io int_o pad_fpga_io[27] +set_io clk_i pad_fpga_io[28] +set_io rst_i pad_fpga_io[29] +set_io cyc_i pad_fpga_io[30] +set_io stb_i pad_fpga_io[31] +set_io adr_i[1] pad_fpga_io[32] +set_io adr_i[2] pad_fpga_io[33] +set_io we_i pad_fpga_io[60] +set_io dat_i[0] pad_fpga_io[35] +set_io dat_i[1] pad_fpga_io[36] +set_io dat_i[2] pad_fpga_io[37] diff --git a/libopenfpga/libpinconstrain/test/test1/simple_pic_run.openfpga b/libopenfpga/libpinconstrain/test/test1/simple_pic_run.openfpga new file mode 100644 index 000000000..3076e9275 --- /dev/null +++ b/libopenfpga/libpinconstrain/test/test1/simple_pic_run.openfpga @@ -0,0 +1,9 @@ +# Run VPR for the 'and' design +#--write_rr_graph example_rr_graph.xml +# + +# constraint pin +# same to script usage (no "-net" yet): +# python3 create_ioplace.py --pcf “pcf_file” --blif “blif_file” --net “net_file” --pinmap_xml “pinmap_xml_file” --csv_file “csv_file” --output “outputplace_file” +constrain_pin_location --pcf ./simple_pic_cstr_pin.pcf --blif simple_pic.blif --net NOT_YET_SUPPORT --pinmap_xml pinmap_qlf_k6n10_tsmc22.xml --csv_file pinmap_qlf_k6n10_tsmc22.csv --output simple_pic_pin_constained.place +exit diff --git a/libopenfpga/libpinconstrain/test/test2/simple_pic_cstr_pin.pcf b/libopenfpga/libpinconstrain/test/test2/simple_pic_cstr_pin.pcf new file mode 100644 index 000000000..8eea133df --- /dev/null +++ b/libopenfpga/libpinconstrain/test/test2/simple_pic_cstr_pin.pcf @@ -0,0 +1,21 @@ +set_io dat_o[0] pad_fpga_io[17] +set_io dat_o[0] pad_fpga_io[18] +set_io dat_o[1] pad_fpga_io[19] +set_io dat_o[2] pad_fpga_io[20] +set_io dat_o[3] pad_fpga_io[21] +set_io dat_o[4] pad_fpga_io[22] +set_io dat_o[5] pad_fpga_io[23] +set_io dat_o[6] pad_fpga_io[24] +set_io dat_o[7] pad_fpga_io[25] +set_io ack_o pad_fpga_io[26] +set_io int_o pad_fpga_io[27] +set_io clk_i pad_fpga_io[28] +set_io rst_i pad_fpga_io[29] +set_io cyc_i pad_fpga_io[30] +set_io stb_i pad_fpga_io[31] +set_io adr_i[1] pad_fpga_io[32] +set_io adr_i[2] pad_fpga_io[33] +set_io we_i pad_fpga_io[60] +set_io dat_i[0] pad_fpga_io[35] +set_io dat_i[1] pad_fpga_io[36] +set_io dat_i[2] pad_fpga_io[37] diff --git a/libopenfpga/libpinconstrain/test/test2/simple_pic_run.openfpga b/libopenfpga/libpinconstrain/test/test2/simple_pic_run.openfpga new file mode 100644 index 000000000..3076e9275 --- /dev/null +++ b/libopenfpga/libpinconstrain/test/test2/simple_pic_run.openfpga @@ -0,0 +1,9 @@ +# Run VPR for the 'and' design +#--write_rr_graph example_rr_graph.xml +# + +# constraint pin +# same to script usage (no "-net" yet): +# python3 create_ioplace.py --pcf “pcf_file” --blif “blif_file” --net “net_file” --pinmap_xml “pinmap_xml_file” --csv_file “csv_file” --output “outputplace_file” +constrain_pin_location --pcf ./simple_pic_cstr_pin.pcf --blif simple_pic.blif --net NOT_YET_SUPPORT --pinmap_xml pinmap_qlf_k6n10_tsmc22.xml --csv_file pinmap_qlf_k6n10_tsmc22.csv --output simple_pic_pin_constained.place +exit diff --git a/libopenfpga/libpinconstrain/test/test3/simple_pic_run.openfpga b/libopenfpga/libpinconstrain/test/test3/simple_pic_run.openfpga new file mode 100644 index 000000000..ee73f42f2 --- /dev/null +++ b/libopenfpga/libpinconstrain/test/test3/simple_pic_run.openfpga @@ -0,0 +1,9 @@ +# Run VPR for the 'and' design +#--write_rr_graph example_rr_graph.xml +# + +# constraint pin +# same to script usage (no "-net" yet): +# python3 create_ioplace.py --pcf “pcf_file” --blif “blif_file” --net “net_file” --pinmap_xml “pinmap_xml_file” --csv_file “csv_file” --output “outputplace_file” +constrain_pin_location --pcf simple_pic_cstr_pin.pcf --blif simple_pic.blif --net NOT_YET_SUPPORT --pinmap_xml pinmap_qlf_k6n10_tsmc22.xml --csv_file pinmap_qlf_k6n10_tsmc22.csv --output simple_pic_pin_constained.place +exit diff --git a/openfpga/CMakeLists.txt b/openfpga/CMakeLists.txt index 70b00fa7b..a9720896c 100644 --- a/openfpga/CMakeLists.txt +++ b/openfpga/CMakeLists.txt @@ -29,7 +29,8 @@ target_link_libraries(libopenfpga libpcf libvtrutil libbusgroup - libvpr) + libvpr + libpinconstrain) #Create the test executable add_executable(openfpga ${EXEC_SOURCE}) diff --git a/openfpga/src/base/openfpga_constrain_pin_location.cpp b/openfpga/src/base/openfpga_constrain_pin_location.cpp new file mode 100644 index 000000000..d2e972312 --- /dev/null +++ b/openfpga/src/base/openfpga_constrain_pin_location.cpp @@ -0,0 +1,96 @@ +/******************************************************************** + * This file includes functions to build bitstream database + *******************************************************************/ +/* Headers from vtrutil library */ +#include "vtr_time.h" +#include "vtr_log.h" + +/* Headers from openfpgashell library */ +#include "command_exit_codes.h" + +/* Headers from openfpgautil library */ +#include "openfpga_digest.h" +#include "openfpga_reserved_words.h" + +#include "openfpga_naming.h" +#include "openfpga_constrain_pin_location.h" + +/* Include global variables of VPR */ +#include "globals.h" + +/* begin namespace openfpga */ +extern int pin_constrain_location (std::vector args); +namespace openfpga { + /******************************************************************** + * Top-level function to read an OpenFPGA architecture file + * we use the APIs from the libarchopenfpga library + * + * The command will accept an option '--file' which is the architecture + * file provided by users + *******************************************************************/ +int constrain_pin_location(OpenfpgaContext& openfpga_context, const Command& cmd, const CommandContext& cmd_context) { + + /* initialize arguments with sanity check*/ + std::vector pin_constrain_args; + pin_constrain_args.push_back("pin_c"); + + /* todo: create a factory to produce this in the future*/ + std::string pcf_option_name = "pcf"; + CommandOptionId opt_pcf_file = cmd.option(pcf_option_name); + VTR_ASSERT(true == cmd_context.option_enable(cmd, opt_pcf_file)); + VTR_ASSERT(false == cmd_context.option_value(cmd, opt_pcf_file).empty()); + std::string pcf_file_name = cmd_context.option_value(cmd, opt_pcf_file); + pin_constrain_args.push_back(std::string("--") + pcf_option_name); + pin_constrain_args.push_back(pcf_file_name.c_str()); + + std::string blif_option_name = "blif"; + CommandOptionId opt_blif_file = cmd.option(blif_option_name); + VTR_ASSERT(true == cmd_context.option_enable(cmd, opt_blif_file)); + VTR_ASSERT(false == cmd_context.option_value(cmd, opt_blif_file).empty()); + std::string blif_file_name = cmd_context.option_value(cmd, opt_blif_file); + pin_constrain_args.push_back(std::string("--") + blif_option_name); + pin_constrain_args.push_back(blif_file_name); + +#if 0 + // --net is not supported by pin_c yet + std::string net_option_name = "net"; + CommandOptionId opt_net_file = cmd.option(net_option_name); + VTR_ASSERT(true == cmd_context.option_enable(cmd, opt_net_file)); + VTR_ASSERT(false == cmd_context.option_value(cmd, opt_net_file).empty()); + std::string net_file_name = cmd_context.option_value(cmd, opt_net_file); + pin_constrain_args.push_back(std::string("--") + net_option_name); + pin_constrain_args.push_back(net_file_name); +#endif + + std::string pinmap_xml_option_name = "pinmap_xml"; + CommandOptionId opt_pinmap_xml_file = cmd.option(pinmap_xml_option_name); + VTR_ASSERT(true == cmd_context.option_enable(cmd, opt_pinmap_xml_file)); + VTR_ASSERT(false == cmd_context.option_value(cmd, opt_pinmap_xml_file).empty()); + std::string pinmap_xml_file_name = cmd_context.option_value(cmd, opt_pinmap_xml_file); + pin_constrain_args.push_back(std::string("--xml")); + pin_constrain_args.push_back(pinmap_xml_file_name); + + std::string csv_file_option_name = "csv_file"; + CommandOptionId opt_csv_file = cmd.option(csv_file_option_name); + VTR_ASSERT(true == cmd_context.option_enable(cmd, opt_csv_file)); + VTR_ASSERT(false == cmd_context.option_value(cmd, opt_csv_file).empty()); + std::string csv_file_name = cmd_context.option_value(cmd, opt_csv_file); + pin_constrain_args.push_back(std::string("--csv")); + pin_constrain_args.push_back(csv_file_name); + + std::string output_option_name = "output"; + CommandOptionId opt_output_file = cmd.option(output_option_name); + VTR_ASSERT(true == cmd_context.option_enable(cmd, opt_output_file)); + VTR_ASSERT(false == cmd_context.option_value(cmd, opt_output_file).empty()); + std::string output_file_name = cmd_context.option_value(cmd, opt_output_file); + pin_constrain_args.push_back(std::string("--") + output_option_name); + pin_constrain_args.push_back(output_file_name); + + if (pin_constrain_location(pin_constrain_args)) { + return CMD_EXEC_FATAL_ERROR; + } + + return CMD_EXEC_SUCCESS; +} + +} /* end namespace openfpga */ diff --git a/openfpga/src/base/openfpga_constrain_pin_location.h b/openfpga/src/base/openfpga_constrain_pin_location.h new file mode 100644 index 000000000..ce7f46389 --- /dev/null +++ b/openfpga/src/base/openfpga_constrain_pin_location.h @@ -0,0 +1,20 @@ +#ifndef OPENFPGA_BITSTREAM_H +#define OPENFPGA_BITSTREAM_H + +/******************************************************************** + * Include header files that are required by function declaration + *******************************************************************/ +#include "command.h" +#include "command_context.h" +#include "openfpga_context.h" + +/******************************************************************** + * Function declaration + *******************************************************************/ + +/* begin namespace openfpga */ +namespace openfpga { + int constrain_pin_location(OpenfpgaContext& openfpga_context, const Command& cmd, const CommandContext& cmd_context); +} /* end namespace openfpga */ + +#endif diff --git a/openfpga/src/base/openfpga_constrain_pin_location_command.cpp b/openfpga/src/base/openfpga_constrain_pin_location_command.cpp new file mode 100644 index 000000000..0e0ae27a0 --- /dev/null +++ b/openfpga/src/base/openfpga_constrain_pin_location_command.cpp @@ -0,0 +1,56 @@ +/******************************************************************** + * Add commands to the OpenFPGA shell interface, + * in purpose of setting up OpenFPGA core engine, including: + * - read_openfpga_arch : read OpenFPGA architecture file + *******************************************************************/ +#include "openfpga_constrain_pin_location_command.h" +#include "openfpga_constrain_pin_location.h" + +/* begin namespace openfpga */ +namespace openfpga { + +/******************************************************************** + * - Add a command to Shell environment: constrain_pin_location + * - Add associated options + * - Add command dependency + *******************************************************************/ +void add_openfpga_constrain_pin_location_command(openfpga::Shell& shell) { + Command shell_cmd("constrain_pin_location"); + + /* Options are created by following the python script crafted by QL, since that has been used for a while: + python3 create_ioplace.py --pcf “pcf_file” --blif “blif_file” --net “net_file” --pinmap_xml “pinmap_xml_file” --csv_file “csv_file” --output “outputplace_file” + */ + /* Add an option '--pcf'*/ + CommandOptionId opt_pcf_file = shell_cmd.add_option("pcf", true, "file path to the user pin constraint"); + shell_cmd.set_option_require_value(opt_pcf_file, openfpga::OPT_STRING); + + /* Add an option '--blif'*/ + CommandOptionId opt_blif_file = shell_cmd.add_option("blif", true, "file path to the synthesized blif"); + shell_cmd.set_option_require_value(opt_blif_file, openfpga::OPT_STRING); + +#if 0 + /* Add an option '--net'*/ + /* Note: This is not implemented in "pin_c" c code yet */ + CommandOptionId opt_net_file = shell_cmd.add_option("net", true, "file path to the packed net"); + shell_cmd.set_option_require_value(opt_net_file, openfpga::OPT_STRING); +#endif + + /* Add an option '--pinmap_xml'*/ + CommandOptionId opt_pinmap_file = shell_cmd.add_option("pinmap_xml", true, "file path to the pin location XML"); + shell_cmd.set_option_require_value(opt_pinmap_file, openfpga::OPT_STRING); + + /* Add an option '--csv_file'*/ + CommandOptionId opt_csv_file = shell_cmd.add_option("csv_file", true, "file path to the pin map csv"); + shell_cmd.set_option_require_value(opt_csv_file, openfpga::OPT_STRING); + + /* Add an option '--output'*/ + CommandOptionId opt_output_file = shell_cmd.add_option("output", true, "file path to the output"); + shell_cmd.set_option_require_value(opt_output_file, openfpga::OPT_STRING); + + /* Add command 'constrain_pin_location' to the Shell */ + ShellCommandId shell_cmd_id = shell.add_command(shell_cmd, "constrain pin location by generating a place file"); + shell.set_command_execute_function(shell_cmd_id, constrain_pin_location); + +} + +} /* end namespace openfpga */ diff --git a/openfpga/src/base/openfpga_constrain_pin_location_command.h b/openfpga/src/base/openfpga_constrain_pin_location_command.h new file mode 100644 index 000000000..2206c0f90 --- /dev/null +++ b/openfpga/src/base/openfpga_constrain_pin_location_command.h @@ -0,0 +1,21 @@ +#ifndef OPENFPGA_CONSTRAIN_PIN_LOCATION_COMMAND_H +#define OPENFPGA_CONSTRAIN_PIN_LOCATION_COMMAND_H + +/******************************************************************** + * Include header files that are required by function declaration + *******************************************************************/ +#include "shell.h" +#include "openfpga_context.h" + +/******************************************************************** + * Function declaration + *******************************************************************/ + +/* begin namespace openfpga */ +namespace openfpga { + +void add_openfpga_constrain_pin_location_command(openfpga::Shell& shell); + +} /* end namespace openfpga */ + +#endif diff --git a/openfpga/src/main.cpp b/openfpga/src/main.cpp index 8b4404c84..4fbe09ffb 100644 --- a/openfpga/src/main.cpp +++ b/openfpga/src/main.cpp @@ -17,6 +17,7 @@ #include "openfpga_bitstream_command.h" #include "openfpga_spice_command.h" #include "openfpga_sdc_command.h" +#include "openfpga_constrain_pin_location_command.h" #include "basic_command.h" #include "openfpga_title.h" @@ -80,6 +81,9 @@ int main(int argc, char** argv) { /* Add openfpga sdc commands */ openfpga::add_openfpga_sdc_commands(shell); + /* Add constrain pin location command */ + openfpga::add_openfpga_constrain_pin_location_command(shell); + /* Add basic commands: exit, help, etc. * Note: * This MUST be the last command group to be added! diff --git a/openfpga_flow/openfpga_shell_scripts/pin_constrain_example_script.openfpga b/openfpga_flow/openfpga_shell_scripts/pin_constrain_example_script.openfpga new file mode 100644 index 000000000..92c71f136 --- /dev/null +++ b/openfpga_flow/openfpga_shell_scripts/pin_constrain_example_script.openfpga @@ -0,0 +1,79 @@ +# Ru constrain_pin_location +constrain_pin_location --pcf ${AND2_PIN_CONSTRAIN_FILE} --blif ${VPR_TESTBENCH_BLIF} --pinmap_xml ${AND2_PIN_MAP_XML_FILE} --csv_file ${AND2_PIN_MAP_CSV_FILE} --output ${OPENFPGA_VPR_FIX_PINS_FILE} + +# Run VPR for the 'and' design +#--write_rr_graph example_rr_graph.xml +vpr ${VPR_ARCH_FILE} ${VPR_TESTBENCH_BLIF} --clock_modeling ideal --device ${OPENFPGA_VPR_DEVICE_LAYOUT} --route_chan_width ${OPENFPGA_VPR_ROUTE_CHAN_WIDTH} --fix_pins ${OPENFPGA_VPR_FIX_PINS_FILE} + +# Read OpenFPGA architecture definition +read_openfpga_arch -f ${OPENFPGA_ARCH_FILE} + +# Read OpenFPGA simulation settings +read_openfpga_simulation_setting -f ${OPENFPGA_SIM_SETTING_FILE} + +# Annotate the OpenFPGA architecture to VPR data base +# to debug use --verbose options +link_openfpga_arch --activity_file ${ACTIVITY_FILE} --sort_gsb_chan_node_in_edges + +# Check and correct any naming conflicts in the BLIF netlist +check_netlist_naming_conflict --fix --report ./netlist_renaming.xml + +# Apply fix-up to clustering nets based on routing results +pb_pin_fixup --verbose + +# Apply fix-up to Look-Up Table truth tables based on packing results +lut_truth_table_fixup + +# Build the module graph +# - Enabled compression on routing architecture modules +# - Enable pin duplication on grid modules +build_fabric --compress_routing #--verbose + +# Write the fabric hierarchy of module graph to a file +# This is used by hierarchical PnR flows +write_fabric_hierarchy --file ./fabric_hierarchy.txt + +# Repack the netlist to physical pbs +# This must be done before bitstream generator and testbench generation +# Strongly recommend it is done after all the fix-up have been applied +repack #--verbose + +# Build the bitstream +# - Output the fabric-independent bitstream to a file +build_architecture_bitstream --verbose --write_file fabric_independent_bitstream.xml + +# Build fabric-dependent bitstream +build_fabric_bitstream --verbose + +# Write fabric-dependent bitstream +write_fabric_bitstream --file fabric_bitstream.bit --format plain_text + +# Write the Verilog netlist for FPGA fabric +# - Enable the use of explicit port mapping in Verilog netlist +write_fabric_verilog --file ./SRC --explicit_port_mapping --include_timing --print_user_defined_template --verbose + +# Write the Verilog testbench for FPGA fabric +# - We suggest the use of same output directory as fabric Verilog netlists +# - Must specify the reference benchmark file if you want to output any testbenches +# - Enable top-level testbench which is a full verification including programming circuit and core logic of FPGA +# - Enable pre-configured top-level testbench which is a fast verification skipping programming phase +# - Simulation ini file is optional and is needed only when you need to interface different HDL simulators using openfpga flow-run scripts +write_full_testbench --file ./SRC --reference_benchmark_file_path ${REFERENCE_VERILOG_TESTBENCH} --explicit_port_mapping --include_signal_init --bitstream fabric_bitstream.bit +write_preconfigured_fabric_wrapper --embed_bitstream iverilog --file ./SRC --explicit_port_mapping +write_preconfigured_testbench --file ./SRC --reference_benchmark_file_path ${REFERENCE_VERILOG_TESTBENCH} --explicit_port_mapping + +# Write the SDC files for PnR backend +# - Turn on every options here +write_pnr_sdc --file ./SDC + +# Write SDC to disable timing for configure ports +write_sdc_disable_timing_configure_ports --file ./SDC/disable_configure_ports.sdc + +# Write the SDC to run timing analysis for a mapped FPGA fabric +write_analysis_sdc --file ./SDC_analysis + +# Finish and exit OpenFPGA +exit + +# Note : +# To run verification at the end of the flow maintain source in ./SRC directory diff --git a/openfpga_flow/regression_test_scripts/basic_reg_test.sh b/openfpga_flow/regression_test_scripts/basic_reg_test.sh index 9572da2d5..36bd62342 100755 --- a/openfpga_flow/regression_test_scripts/basic_reg_test.sh +++ b/openfpga_flow/regression_test_scripts/basic_reg_test.sh @@ -166,6 +166,7 @@ run-task basic_tests/bus_group/full_testbench_implicit_mapping $@ echo -e "Testing fix pins features"; run-task basic_tests/fix_pins $@ +run-task basic_tests/pin_constrain $@ echo -e "Testing project templates"; run-task template_tasks/vpr_blif_template $@ diff --git a/openfpga_flow/tasks/basic_tests/constrain_pin_location/config/and2.pcf b/openfpga_flow/tasks/basic_tests/constrain_pin_location/config/and2.pcf new file mode 100644 index 000000000..839f8a857 --- /dev/null +++ b/openfpga_flow/tasks/basic_tests/constrain_pin_location/config/and2.pcf @@ -0,0 +1,3 @@ +set_io a pad_fpga_io[0] +set_io b pad_fpga_io[4] +set_io c pad_fpga_io[6] diff --git a/openfpga_flow/tasks/basic_tests/constrain_pin_location/config/pinmap_k4_N4_tileable_40nm.csv b/openfpga_flow/tasks/basic_tests/constrain_pin_location/config/pinmap_k4_N4_tileable_40nm.csv new file mode 100644 index 000000000..2d9fcb6c3 --- /dev/null +++ b/openfpga_flow/tasks/basic_tests/constrain_pin_location/config/pinmap_k4_N4_tileable_40nm.csv @@ -0,0 +1,17 @@ +orientation,row,col,pin_num_in_cell,port_name,mapped_pin,GPIO_type,Associated Clock,Clock Edge +TOP,,,,gfpga_pad_IO_A2F[0],pad_fpga_io[0],,, +TOP,,,,gfpga_pad_IO_F2A[0],pad_fpga_io[0],,, +TOP,,,,gfpga_pad_IO_A2F[4],pad_fpga_io[1],,, +TOP,,,,gfpga_pad_IO_F2A[4],pad_fpga_io[1],,, +TOP,,,,gfpga_pad_IO_A2F[8],pad_fpga_io[2],,, +TOP,,,,gfpga_pad_IO_F2A[8],pad_fpga_io[2],,, +TOP,,,,gfpga_pad_IO_A2F[31],pad_fpga_io[3],,, +TOP,,,,gfpga_pad_IO_F2A[31],pad_fpga_io[3],,, +RIGHT,,,,gfpga_pad_IO_A2F[32],pad_fpga_io[4],,, +RIGHT,,,,gfpga_pad_IO_F2A[32],pad_fpga_io[4],,, +RIGHT,,,,gfpga_pad_IO_A2F[40],pad_fpga_io[5],,, +RIGHT,,,,gfpga_pad_IO_F2A[40],pad_fpga_io[5],,, +BOTTOM,,,,gfpga_pad_IO_A2F[64],pad_fpga_io[6],,, +BOTTOM,,,,gfpga_pad_IO_F2A[64],pad_fpga_io[6],,, +LEFT,,,,gfpga_pad_IO_F2A[127],pad_fpga_io[7],,, +LEFT,,,,gfpga_pad_IO_A2F[127],pad_fpga_io[7],,, \ No newline at end of file diff --git a/openfpga_flow/tasks/basic_tests/constrain_pin_location/config/pinmap_k4_N4_tileable_40nm.xml b/openfpga_flow/tasks/basic_tests/constrain_pin_location/config/pinmap_k4_N4_tileable_40nm.xml new file mode 100644 index 000000000..e6502dc59 --- /dev/null +++ b/openfpga_flow/tasks/basic_tests/constrain_pin_location/config/pinmap_k4_N4_tileable_40nm.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/openfpga_flow/tasks/basic_tests/constrain_pin_location/config/task.conf b/openfpga_flow/tasks/basic_tests/constrain_pin_location/config/task.conf new file mode 100644 index 000000000..089ae46fb --- /dev/null +++ b/openfpga_flow/tasks/basic_tests/constrain_pin_location/config/task.conf @@ -0,0 +1,41 @@ +# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = +# Configuration file for running experiments +# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = +# timeout_each_job : FPGA Task script splits fpga flow into multiple jobs +# Each job execute fpga_flow script on combination of architecture & benchmark +# timeout_each_job is timeout for each job +# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + +[GENERAL] +run_engine=openfpga_shell +power_tech_file = ${PATH:OPENFPGA_PATH}/openfpga_flow/tech/PTM_45nm/45nm.xml +power_analysis = true +spice_output=false +verilog_output=true +timeout_each_job = 20*60 +fpga_flow=yosys_vpr + +[OpenFPGA_SHELL] +openfpga_shell_template=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_shell_scripts/pin_constrain_example_script.openfpga +openfpga_arch_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_arch/k4_N4_40nm_cc_openfpga.xml +openfpga_sim_setting_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_simulation_settings/auto_sim_openfpga.xml +openfpga_vpr_device_layout=4x4 +openfpga_vpr_route_chan_width=20 +and2_pin_constrain_file=${PATH:OPENFPGA_PATH}/openfpga_flow/tasks/basic_tests/constrain_pin_location/config/and2.pcf +and2_pin_map_xml_file=${PATH:OPENFPGA_PATH}/openfpga_flow/tasks/basic_tests/constrain_pin_location/config/pinmap_k4_N4_tileable_40nm.xml +and2_pin_map_csv_file=${PATH:OPENFPGA_PATH}/openfpga_flow/tasks/basic_tests/constrain_pin_location/config/pinmap_k4_N4_tileable_40nm.csv +openfpga_vpr_fix_pins_file=./and2_constrain_pin.place + +[ARCHITECTURES] +arch0=${PATH:OPENFPGA_PATH}/openfpga_flow/vpr_arch/k4_N4_tileable_40nm.xml + +[BENCHMARKS] +bench0=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and2/and2.v + +[SYNTHESIS_PARAM] +bench_read_verilog_options_common = -nolatches +bench0_top = and2 + +[SCRIPT_PARAM_MIN_ROUTE_CHAN_WIDTH] +end_flow_with_test= +vpr_fpga_verilog_formal_verification_top_netlist=