Add constrain_pin_location command in openfpga; add full flow test.
This commit is contained in:
parent
9dca626a3d
commit
cfc0d08060
|
@ -8,3 +8,4 @@ add_subdirectory(librepackdc)
|
|||
add_subdirectory(libfpgabitstream)
|
||||
add_subdirectory(libpcf)
|
||||
add_subdirectory(libbusgroup)
|
||||
add_subdirectory(libpinconstrain)
|
||||
|
|
|
@ -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})
|
|
@ -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],,,
|
|
|
@ -0,0 +1,28 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
XML file specification is primarily to define the mapping of the interface cell ports defined
|
||||
in vpr_arch xml, to the EFPGA IO interface port names. This mapping is required by Symbiflow
|
||||
alongwith architecture definition file i.e. vpr_arch xml file. Symbiflow will process this
|
||||
file and use this information for IO placement and then later on use this to map it with the
|
||||
user-defined pin-mapping file.
|
||||
-->
|
||||
<DEVICE name= "qlf_k6n10_tsmc22" family="qlf_k6n10" width="6" height="6" z="20">
|
||||
<IO>
|
||||
<TOP_IO y="5">
|
||||
<CELL port_name="f2a_i" mapped_name="gfpga_pad_IO_F2A[0:79]" startx="1" endx="4"/>
|
||||
<CELL port_name="a2f_o" mapped_name="gfpga_pad_IO_A2F[0:79]" startx="1" endx="4"/>
|
||||
</TOP_IO>
|
||||
<RIGHT_IO x="5">
|
||||
<CELL port_name="f2a_i" mapped_name="gfpga_pad_IO_F2A[80:159]" starty="4" endy="1"/>
|
||||
<CELL port_name="a2f_o" mapped_name="gfpga_pad_IO_A2F[80:159]" starty="4" endy="1"/>
|
||||
</RIGHT_IO>
|
||||
<BOTTOM_IO y="0">
|
||||
<CELL port_name="f2a_i" mapped_name="gfpga_pad_IO_F2A[160:239]" startx="4" endx="1"/>
|
||||
<CELL port_name="a2f_o" mapped_name="gfpga_pad_IO_A2F[160:239]" startx="4" endx="1"/>
|
||||
</BOTTOM_IO>
|
||||
<LEFT_IO x="0">
|
||||
<CELL port_name="f2a_i" mapped_name="gfpga_pad_IO_F2A[240:319]" starty="1" endy="4"/>
|
||||
<CELL port_name="a2f_o" mapped_name="gfpga_pad_IO_A2F[240:319]" starty="1" endy="4"/>
|
||||
</LEFT_IO>
|
||||
</IO>
|
||||
</DEVICE>
|
|
@ -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
|
|
@ -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]
|
|
@ -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<std::string> input_ports) override {
|
||||
for (auto input_port : input_ports) {
|
||||
inputs_.push_back(input_port);
|
||||
}
|
||||
}
|
||||
void outputs(std::vector<std::string> output_ports) override {
|
||||
for (auto output_port : output_ports) {
|
||||
outputs_.push_back(output_port);
|
||||
}
|
||||
}
|
||||
|
||||
void names(std::vector<std::string> /*nets*/, std::vector<std:: vector<LogicValue>> /*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<std::string> /*ports*/, std:: vector<std::string> /*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<std::string> get_inputs() { return inputs_;}
|
||||
std::vector<std::string> get_outputs() { return outputs_;}
|
||||
private:
|
||||
bool had_error_ = false;
|
||||
std::vector<std::string> inputs_;
|
||||
std::vector<std::string> 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;
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
#ifndef BLIF_READER_H
|
||||
#define BLIF_READER_H
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <fstream>
|
||||
#include <vector>
|
||||
#include <unordered_map>
|
||||
#include <map>
|
||||
|
||||
/*
|
||||
Supported PCF commands:
|
||||
|
||||
* set_io <net> <pad> - constrain a given <net> to a given physical <pad> in eFPGA pinout.
|
||||
* set_clk <pin> <net> - constrain a given global clock <pin> to a given <net>
|
||||
|
||||
Every tile where <net> is present will be constrained to use a given global clock.
|
||||
*/
|
||||
using namespace std;
|
||||
class BlifReader
|
||||
{
|
||||
vector<string> inputs;
|
||||
vector<string> outputs;
|
||||
|
||||
public:
|
||||
BlifReader() {}
|
||||
BlifReader(const std::string &f)
|
||||
{
|
||||
read_blif(f);
|
||||
}
|
||||
bool read_blif(const std::string &f);
|
||||
const vector<string>& get_inputs()const { return inputs;}
|
||||
const vector<string>& get_outputs()const { return outputs;}
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,52 @@
|
|||
#include "csv_reader.h"
|
||||
#include <algorithm>
|
||||
|
||||
|
||||
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<string>());
|
||||
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<string> first_v = entries[0];
|
||||
auto result1 = std::find(first_v.begin(), first_v.end(), "port_name");
|
||||
vector<string>::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<std::string, string>(mapped_pin, port_name));
|
||||
//for (auto &s : v)
|
||||
//{
|
||||
// cout << s << " - ";
|
||||
//}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
#ifndef CVS_READER_H
|
||||
#define CVS_READER_H
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <fstream>
|
||||
#include <vector>
|
||||
#include <unordered_map>
|
||||
#include <ctype.h>
|
||||
#include <map>
|
||||
|
||||
using namespace std;
|
||||
|
||||
class CvsReader
|
||||
{
|
||||
vector<vector<string>> entries;
|
||||
map<string, string> port_map;
|
||||
public:
|
||||
CvsReader() {}
|
||||
bool read_cvs(const std::string &f);
|
||||
const vector<vector<string>>& get_entries()const { return entries;}
|
||||
const map<string, string>& get_port_map()const { return port_map;}
|
||||
};
|
||||
|
||||
#endif
|
|
@ -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<string>());
|
||||
commands.back().push_back(a);
|
||||
commands.back().push_back(b);
|
||||
commands.back().push_back(c);
|
||||
//pcf_pin_map.insert(std::pair<std::string, string>(b, c));
|
||||
}
|
||||
return true;
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
#ifndef PCF_READER_H
|
||||
#define PCF_READER_H
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <fstream>
|
||||
#include <vector>
|
||||
#include <unordered_map>
|
||||
#include <map>
|
||||
|
||||
/*
|
||||
Supported PCF commands:
|
||||
|
||||
* set_io <net> <pad> - constrain a given <net> to a given physical <pad> in eFPGA pinout.
|
||||
* set_clk <pin> <net> - constrain a given global clock <pin> to a given <net>
|
||||
|
||||
Every tile where <net> is present will be constrained to use a given global clock.
|
||||
*/
|
||||
using namespace std;
|
||||
class PcfReader
|
||||
{
|
||||
vector<vector<string>> commands;
|
||||
//std::map<string, string> pcf_pin_map;
|
||||
|
||||
public:
|
||||
PcfReader() {}
|
||||
PcfReader(const std::string &f)
|
||||
{
|
||||
read_pcf(f);
|
||||
}
|
||||
bool read_pcf(const std::string &f);
|
||||
const vector<vector<string>>& get_commands()const { return commands;}
|
||||
//const unordered_map<string, string>& get_pcf_pin_map()const { return pcf_pin_map;}
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,243 @@
|
|||
#include "xml_reader.h"
|
||||
#include <vector>
|
||||
#include <fstream>
|
||||
|
||||
//======================================================================
|
||||
std::vector<std::string> 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<std::string> 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<std::string, PinMappingData> *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<std::string> 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<std::string, PinMappingData>(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<std::string, PinMappingData>(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<std::string, PinMappingData>(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<std::string, PinMappingData>(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<std::string, PinMappingData> *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;
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
#ifndef XML_READER_H
|
||||
#define XML_READER_H
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
#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<std::string, PinMappingData> port_map_;
|
||||
public:
|
||||
XmlReader() {}
|
||||
bool read_xml(const std::string &f);
|
||||
const std::map<std::string, PinMappingData>& get_port_map()const { return port_map_;}
|
||||
std::vector<std::string> 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<std::string, PinMappingData> *port_map);
|
||||
bool parse_io (const pugi::xml_node xml_io, const int width, const int height, const int io_per_cell, std::map<std::string, PinMappingData> *port_map);
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,23 @@
|
|||
#include <iostream>
|
||||
#include <string>
|
||||
#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);
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
#include "pin_location.h"
|
||||
#include "cmd_line.h"
|
||||
#include "pin_constrain_loc.h"
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
// wraper function to do the real job, it is used by openfpga shell as well
|
||||
// this gurantees same behavior
|
||||
int pin_constrain_location (vector<string> 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<char*> (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;
|
||||
}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
#include "pin_location.h"
|
||||
#include "cmd_line.h"
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
// 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<std::string> args);
|
||||
|
||||
// base function for both openfpga wrapper and pin_c executable
|
||||
int pin_constrain_location_cmd_line (cmd_line& cmd);
|
||||
|
|
@ -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 <algorithm>
|
||||
#include <set>
|
||||
|
||||
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<std::string, PinMappingData> 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<string, string> 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<std::string> inputs = rd_blif.get_inputs();
|
||||
std::vector<std::string> 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<vector<string>> pcf_pin_cstr = rd_pcf.get_commands();
|
||||
std::set<std::string> 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;
|
||||
}
|
|
@ -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
|
|
@ -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;
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
#ifndef CMD_LINE
|
||||
#define CMD_LINE
|
||||
#include <iostream>
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
using namespace std;
|
||||
class cmd_line
|
||||
{
|
||||
unordered_map<string, string> params;
|
||||
unordered_set<string> flags;
|
||||
|
||||
public:
|
||||
cmd_line(int argc, const char *argv[]);
|
||||
const unordered_set<string> &get_flag_set() const { return flags; }
|
||||
const unordered_map<string, string> 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
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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]
|
|
@ -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
|
|
@ -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]
|
|
@ -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
|
|
@ -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]
|
|
@ -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
|
|
@ -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
|
|
@ -29,7 +29,8 @@ target_link_libraries(libopenfpga
|
|||
libpcf
|
||||
libvtrutil
|
||||
libbusgroup
|
||||
libvpr)
|
||||
libvpr
|
||||
libpinconstrain)
|
||||
|
||||
#Create the test executable
|
||||
add_executable(openfpga ${EXEC_SOURCE})
|
||||
|
|
|
@ -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<std::string> 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<std::string> 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 */
|
|
@ -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
|
|
@ -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<OpenfpgaContext>& 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 */
|
|
@ -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<OpenfpgaContext>& shell);
|
||||
|
||||
} /* end namespace openfpga */
|
||||
|
||||
#endif
|
|
@ -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!
|
||||
|
|
|
@ -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
|
|
@ -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 $@
|
||||
|
|
|
@ -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]
|
|
@ -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],,,
|
|
|
@ -0,0 +1,28 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
XML file specification is primarily to define the mapping of the interface cell ports defined
|
||||
in vpr_arch xml, to the EFPGA IO interface port names. This mapping is required by OpenFPGA
|
||||
alongwith architecture definition file i.e. vpr_arch xml file. OpenFPGA will process this
|
||||
file and use this information for IO placement and then later on use this to map it with the
|
||||
user-defined pin-mapping file.
|
||||
-->
|
||||
<DEVICE name= "k4_N4_tileable_40nm" family="k4n4" width="6" height="6" z="8">
|
||||
<IO>
|
||||
<TOP_IO y="5">
|
||||
<CELL port_name="output" mapped_name="gfpga_pad_IO_F2A[0:31]" startx="1" endx="4"/>
|
||||
<CELL port_name="input" mapped_name="gfpga_pad_IO_A2F[0:31]" startx="1" endx="4"/>
|
||||
</TOP_IO>
|
||||
<RIGHT_IO x="5">
|
||||
<CELL port_name="output" mapped_name="gfpga_pad_IO_F2A[32:63]" starty="4" endy="1"/>
|
||||
<CELL port_name="input" mapped_name="gfpga_pad_IO_A2F[32:63]" starty="4" endy="1"/>
|
||||
</RIGHT_IO>
|
||||
<BOTTOM_IO y="0">
|
||||
<CELL port_name="output" mapped_name="gfpga_pad_IO_F2A[64:95]" startx="4" endx="1"/>
|
||||
<CELL port_name="input" mapped_name="gfpga_pad_IO_A2F[64:95]" startx="4" endx="1"/>
|
||||
</BOTTOM_IO>
|
||||
<LEFT_IO x="0">
|
||||
<CELL port_name="output" mapped_name="gfpga_pad_IO_F2A[96:127]" starty="1" endy="4"/>
|
||||
<CELL port_name="input" mapped_name="gfpga_pad_IO_A2F[96:127]" starty="1" endy="4"/>
|
||||
</LEFT_IO>
|
||||
</IO>
|
||||
</DEVICE>
|
|
@ -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=
|
Loading…
Reference in New Issue