Merge pull request #109 from sebastien-riou/arty
missing tcl files for Murax on Arty
This commit is contained in:
commit
ac79cc6fe6
|
@ -0,0 +1,50 @@
|
|||
|
||||
# Input files
|
||||
set mmi_file "./soc.mmi"
|
||||
set elf_file "./soc.elf"
|
||||
set source_bit_file "./soc.bit"
|
||||
|
||||
# Output files
|
||||
set output_bit_file "./soc_latest_sw.bit"
|
||||
|
||||
# Enable to turn on debug
|
||||
set updatemem_debug 0
|
||||
|
||||
# Assemble bit file that can be downloaded to device directly
|
||||
# Combine the original bit file, mmi file, and software elf to create the full bitstream
|
||||
|
||||
# Delete target file
|
||||
file delete -force $output_bit_file
|
||||
|
||||
# Determine if the user has built the project and has the target source file
|
||||
# If not, then use the reference bit file shipped with the project
|
||||
if { ![file exists $source_bit_file] } {
|
||||
puts "\n********************************************"
|
||||
puts "INFO - File $source_bit_file doesn't exist as project has not been built"
|
||||
puts " Using $reference_bit_file instead\n"
|
||||
puts "********************************************/n"
|
||||
set source_bit_file $reference_bit_file
|
||||
}
|
||||
|
||||
# Banner message to console as there is no output for a few seconds
|
||||
puts " Running updatemem ..."
|
||||
|
||||
if { $updatemem_debug } {
|
||||
set error [catch {exec updatemem --debug --force --meminfo $mmi_file --data $elf_file --bit $source_bit_file --proc dummy --out $output_bit_file} result]
|
||||
} else {
|
||||
set error [catch {exec updatemem --force --meminfo $mmi_file --data $elf_file --bit $source_bit_file --proc dummy --out $output_bit_file} result]
|
||||
}
|
||||
|
||||
# Print the stdout from updatemem
|
||||
puts $result
|
||||
|
||||
# Updatemem returns 0 even when there is an error, so cannot trap on error. Having deleted output file to start, then
|
||||
# detect if it now exists, else exit.
|
||||
if { ![file exists $output_bit_file] } {
|
||||
puts "ERROR - $output_bit_file not made"
|
||||
return -1
|
||||
} else {
|
||||
puts "\n********************************************"
|
||||
puts " $output_bit_file correctly generated"
|
||||
puts "********************************************\n"
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
|
||||
# Input file
|
||||
set source_bit_file "./latest.bit"
|
||||
|
||||
# Output file
|
||||
set output_mcs_file "./latest.mcs"
|
||||
|
||||
# Delete target file
|
||||
file delete -force $output_mcs_file
|
||||
|
||||
# Determine if the user has built the project and has the target source file
|
||||
# If not, then use the reference bit file shipped with the project
|
||||
if { ![file exists $source_bit_file] } {
|
||||
puts "\n********************************************"
|
||||
puts "INFO - File $source_bit_file doesn't exist as project has not been built\n"
|
||||
puts "********************************************/n"
|
||||
error
|
||||
}
|
||||
|
||||
# Create MCS file for base board QSPI flash memory
|
||||
write_cfgmem -force -format MCS -size 16 -interface SPIx4 -loadbit " up 0 $source_bit_file" $output_mcs_file
|
||||
|
||||
# Check MCS was correctly made
|
||||
if { ![file exists $output_mcs_file] } {
|
||||
puts "ERROR - $output_bit_file not made"
|
||||
return -1
|
||||
} else {
|
||||
puts "\n********************************************"
|
||||
puts " $output_mcs_file correctly generated"
|
||||
puts "********************************************\n"
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
source [file join [file dirname [file normalize [info script]]] vivado_params.tcl]
|
||||
|
||||
open_project -read_only $outputdir/$projectName
|
||||
open_run impl_1
|
||||
source $base/soc_mmi.tcl
|
||||
puts "mmi files generated"
|
|
@ -0,0 +1,46 @@
|
|||
#Create output directory and clear contents
|
||||
source [file join [file dirname [file normalize [info script]]] vivado_params.tcl]
|
||||
|
||||
file mkdir $outputdir
|
||||
set files [glob -nocomplain "$outputdir/*"]
|
||||
if {[llength $files] != 0} {
|
||||
puts "deleting contents of $outputdir"
|
||||
file delete -force {*}[glob -directory $outputdir *]; # clear folder contents
|
||||
} else {
|
||||
puts "$outputdir is empty"
|
||||
}
|
||||
|
||||
#Create project
|
||||
create_project -part $part $projectName $outputdir
|
||||
|
||||
#add source files to Vivado project
|
||||
#add_files -fileset sim_1 ./path/to/testbench.vhd
|
||||
#add_files [glob ./path/to/sources/*.vhd]
|
||||
#add_files -fileset constrs_1 ./path/to/constraint/constraint.xdc
|
||||
#add_files [glob ./path/to/library/sources/*.vhd]
|
||||
#set_property -library userDefined [glob ./path/to/library/sources/*.vhd]
|
||||
add_files [glob $base/*.v]
|
||||
add_files [glob $topv]
|
||||
add_files -fileset constrs_1 $base/arty_a7.xdc
|
||||
|
||||
#set top level module and update compile order
|
||||
set_property top toplevel [current_fileset]
|
||||
update_compile_order -fileset sources_1
|
||||
#update_compile_order -fileset sim_1
|
||||
|
||||
#launch synthesis
|
||||
launch_runs synth_1
|
||||
wait_on_run synth_1
|
||||
|
||||
#Run implementation and generate bitstream
|
||||
set_property STEPS.PHYS_OPT_DESIGN.IS_ENABLED true [get_runs impl_1]
|
||||
launch_runs impl_1 -to_step write_bitstream
|
||||
wait_on_run impl_1
|
||||
puts "Implementation done!"
|
||||
|
||||
#reports generated by default
|
||||
#open_run impl_1
|
||||
#report_timing_summary -check_timing_verbose -report_unconstrained -file report_timing_summary.rpt
|
||||
#report_utilization -hierarchical -file report_utilization.rpt
|
||||
|
||||
#TODO: add checks about timing, DRC, CDC such that the script give clear indication if design is OK or not
|
|
@ -0,0 +1,4 @@
|
|||
source [file join [file dirname [file normalize [info script]]] vivado_params.tcl]
|
||||
|
||||
open_project -read_only $outputdir/$projectName
|
||||
start_gui
|
|
@ -0,0 +1,151 @@
|
|||
#script to update the init values of RAM without re-synthesis
|
||||
|
||||
if {![info exists mmi_file]} {
|
||||
# Set MMI output file name
|
||||
set mmi_file "soc.mmi"
|
||||
}
|
||||
if {![info exists part]} {
|
||||
set part "xc7a35ticsg324-1L"
|
||||
}
|
||||
|
||||
# Function to swap bits
|
||||
proc swap_bits { bit } {
|
||||
|
||||
if { $bit > 23 } {return [expr {24 + (31 - $bit)}]}
|
||||
if { $bit > 15 } {return [expr {16 + (23 - $bit)}]}
|
||||
if { $bit > 7 } {return [expr {8 + (15 - $bit)}]}
|
||||
return [expr {7 - $bit}]
|
||||
}
|
||||
|
||||
# If run from batch file, will need to open project, then open the run
|
||||
# open_run impl_1
|
||||
|
||||
# Find all the RAMs, place in a list
|
||||
set rams [get_cells -hier -regexp {.*core/system_ram/.*} -filter {REF_NAME =~ RAMB36E1}]
|
||||
|
||||
puts "[llength $rams] RAMs in total"
|
||||
foreach m $rams {puts $m}
|
||||
|
||||
set mems [dict create]
|
||||
foreach m $rams {
|
||||
set numbers [regexp -all -inline -- {[0-9]+} $m]
|
||||
dict set mems $numbers $m
|
||||
}
|
||||
set keys [dict keys $mems]
|
||||
#set keys [lsort -integer $keys]
|
||||
set rams []
|
||||
foreach key $keys {
|
||||
set m [dict get $mems $key]
|
||||
puts "$key -> $m"
|
||||
lappend rams $m
|
||||
}
|
||||
|
||||
puts "after sort:"
|
||||
foreach m $rams {puts $m}
|
||||
puts $rams
|
||||
|
||||
if { [llength $rams] == 0 } {
|
||||
puts "Error - no memories found"
|
||||
return -1
|
||||
}
|
||||
|
||||
if { [expr {[llength $rams] % 4}] != 0 } {
|
||||
puts "Error - Number of memories not divisible by 4"
|
||||
return -1
|
||||
}
|
||||
|
||||
set size_bytes [expr {4096*[llength $rams]}]
|
||||
puts "Instruction memory size $size_bytes"
|
||||
|
||||
# Currently only support memory sizes between 16kB, (one byte per mem), and 128kB, (one bit per mem)
|
||||
if { ($size_bytes < (4*4096)) || ($size_bytes > (32*4096)) } {
|
||||
puts "Error - Memory size of $size_bytes out of range"
|
||||
puts " Script only supports memory sizes between 16kB and 128kB"
|
||||
return -1
|
||||
}
|
||||
|
||||
# Create and open target mmi file
|
||||
set fp [open $mmi_file {WRONLY CREAT TRUNC}]
|
||||
if { $fp == 0 } {
|
||||
puts "Error - Unable to open $mmi_file for writing"
|
||||
return -1
|
||||
}
|
||||
|
||||
# Write the file header
|
||||
puts $fp "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
|
||||
puts $fp "<MemInfo Version=\"1\" Minor=\"15\">"
|
||||
puts $fp " <Processor Endianness=\"ignored\" InstPath=\"dummy\">"
|
||||
puts $fp " <AddressSpace Name=\"soc_side\" Begin=\"[expr {0x80000000}]\" End=\"[expr {0x80000000 + $size_bytes-1}]\">"
|
||||
puts $fp " <BusBlock>"
|
||||
|
||||
# Calculate the expected number of bits per memory
|
||||
set mem_bits [expr {32/[llength $rams]}]
|
||||
|
||||
puts "mem_bits = $mem_bits"
|
||||
|
||||
set mem_info [dict create]
|
||||
|
||||
set i 0
|
||||
foreach ram $rams {
|
||||
# Get the RAM location
|
||||
set loc_val [get_property LOC [get_cells $ram]]
|
||||
regexp -- {(RAMB36_)([0-9XY]+)} $loc_val full ram_name loc_xy
|
||||
|
||||
set memi [dict create ram $ram loc $loc_xy]
|
||||
|
||||
set numbers [regexp -all -inline -- {[0-9]+} $ram]
|
||||
if { [llength $numbers] == 2 } {
|
||||
dict lappend mem_info [lindex $numbers 0] $memi
|
||||
} else {
|
||||
dict lappend mem_info [expr $i/4] $memi
|
||||
}
|
||||
incr i
|
||||
}
|
||||
|
||||
set sorted_mem_info [dict create]
|
||||
foreach {idx mems} $mem_info {
|
||||
foreach mem [lreverse $mems] {
|
||||
dict lappend sorted_mem_info $idx $mem
|
||||
}
|
||||
}
|
||||
foreach mems $sorted_mem_info {
|
||||
foreach mem $mems {
|
||||
puts $mem
|
||||
}
|
||||
}
|
||||
|
||||
set lsb 0
|
||||
set memlen [ expr 4096*8 / $mem_bits ]
|
||||
foreach {idx mems} $sorted_mem_info {
|
||||
puts "idx=$idx"
|
||||
foreach mem $mems {
|
||||
puts "mem=$mem"
|
||||
set ram [dict get $mem ram]
|
||||
set loc [dict get $mem loc]
|
||||
set msb [expr $lsb+$mem_bits-1]
|
||||
set addr_start 0
|
||||
set addr_end [expr $memlen-1]
|
||||
puts "ram=$ram loc=$loc lsb=$lsb msb=$msb addr_start=$addr_start addr_end=$addr_end"
|
||||
puts $fp " <!-- $ram -->"
|
||||
puts $fp " <BitLane MemType=\"RAMB36\" Placement=\"$loc\">"
|
||||
puts $fp " <DataWidth MSB=\"$msb\" LSB=\"$lsb\"/>"
|
||||
puts $fp " <!--not used!--><AddressRange Begin=\"$addr_start\" End=\"$addr_end\"/>"
|
||||
puts $fp " <Parity ON=\"false\" NumBits=\"0\"/>"
|
||||
puts $fp " </BitLane>"
|
||||
|
||||
set lsb [expr ($msb+1)%32]
|
||||
}
|
||||
}
|
||||
|
||||
puts $fp " </BusBlock>"
|
||||
puts $fp " </AddressSpace>"
|
||||
puts $fp " </Processor>"
|
||||
puts $fp " <Config>"
|
||||
puts $fp " <Option Name=\"Part\" Val=\"$part\"/>"
|
||||
puts $fp " </Config>"
|
||||
puts $fp " <DRC>"
|
||||
puts $fp " <Rule Name=\"RDADDRCHANGE\" Val=\"false\"/>"
|
||||
puts $fp " </DRC>"
|
||||
puts $fp "</MemInfo>"
|
||||
|
||||
close $fp
|
|
@ -0,0 +1,5 @@
|
|||
set outputdir ./vivado_project
|
||||
set part "xc7a35ticsg324-1L"
|
||||
set base ".."
|
||||
set projectName "fpga"
|
||||
set topv "$base/../../../Murax.v"
|
|
@ -0,0 +1,26 @@
|
|||
|
||||
open_hw
|
||||
connect_hw_server
|
||||
open_hw_target
|
||||
current_hw_device [get_hw_devices xc7a35t_0]
|
||||
refresh_hw_device -update_hw_probes false [lindex [get_hw_devices xc7a35t_0] 0]
|
||||
|
||||
create_hw_cfgmem -hw_device [lindex [get_hw_devices] 0] -mem_dev [lindex [get_cfgmem_parts {s25fl128sxxxxxx0-spi-x1_x2_x4}] 0]
|
||||
set_property PROBES.FILE {} [get_hw_devices xc7a35t_0]
|
||||
set_property FULL_PROBES.FILE {} [get_hw_devices xc7a35t_0]
|
||||
refresh_hw_device [lindex [get_hw_devices xc7a35t_0] 0]
|
||||
set_property PROGRAM.ADDRESS_RANGE {use_file} [ get_property PROGRAM.HW_CFGMEM [lindex [get_hw_devices xc7a35t_0] 0]]
|
||||
set_property PROGRAM.FILES [list "latest.mcs" ] [ get_property PROGRAM.HW_CFGMEM [lindex [get_hw_devices xc7a35t_0] 0]]
|
||||
set_property PROGRAM.PRM_FILE {} [ get_property PROGRAM.HW_CFGMEM [lindex [get_hw_devices xc7a35t_0] 0]]
|
||||
set_property PROGRAM.UNUSED_PIN_TERMINATION {pull-none} [ get_property PROGRAM.HW_CFGMEM [lindex [get_hw_devices xc7a35t_0] 0]]
|
||||
set_property PROGRAM.BLANK_CHECK 0 [ get_property PROGRAM.HW_CFGMEM [lindex [get_hw_devices xc7a35t_0] 0]]
|
||||
set_property PROGRAM.ERASE 1 [ get_property PROGRAM.HW_CFGMEM [lindex [get_hw_devices xc7a35t_0] 0]]
|
||||
set_property PROGRAM.CFG_PROGRAM 1 [ get_property PROGRAM.HW_CFGMEM [lindex [get_hw_devices xc7a35t_0] 0]]
|
||||
set_property PROGRAM.VERIFY 1 [ get_property PROGRAM.HW_CFGMEM [lindex [get_hw_devices xc7a35t_0] 0]]
|
||||
set_property PROGRAM.CHECKSUM 0 [ get_property PROGRAM.HW_CFGMEM [lindex [get_hw_devices xc7a35t_0] 0]]
|
||||
|
||||
if {![string equal [get_property PROGRAM.HW_CFGMEM_TYPE [lindex [get_hw_devices xc7a35t_0] 0]] [get_property MEM_TYPE [get_property CFGMEM_PART [ get_property PROGRAM.HW_CFGMEM [lindex [get_hw_devices xc7a35t_0] 0]]]]] } { create_hw_bitstream -hw_device [lindex [get_hw_devices xc7a35t_0] 0] [get_property PROGRAM.HW_CFGMEM_BITFILE [ lindex [get_hw_devices xc7a35t_0] 0]]; program_hw_devices [lindex [get_hw_devices xc7a35t_0] 0]; };
|
||||
program_hw_cfgmem -hw_cfgmem [ get_property PROGRAM.HW_CFGMEM [lindex [get_hw_devices xc7a35t_0] 0]]
|
||||
|
||||
close_hw_target
|
||||
close_hw
|
|
@ -0,0 +1,10 @@
|
|||
open_hw
|
||||
connect_hw_server
|
||||
open_hw_target
|
||||
current_hw_device [get_hw_devices xc7a35t_0]
|
||||
refresh_hw_device -update_hw_probes false [lindex [get_hw_devices xc7a35t_0] 0]
|
||||
set_property PROBES.FILE {} [get_hw_devices xc7a35t_0]
|
||||
set_property FULL_PROBES.FILE {} [get_hw_devices xc7a35t_0]
|
||||
set_property PROGRAM.FILE {latest.bit} [get_hw_devices xc7a35t_0]
|
||||
program_hw_devices [get_hw_devices xc7a35t_0]
|
||||
disconnect_hw_server
|
|
@ -33,5 +33,5 @@ clean-for-commit:
|
|||
rm -f *.d
|
||||
rm demo_rom.bin demo.bin crt_ram.bin
|
||||
|
||||
clean: clean-tmp
|
||||
clean: clean-for-commit
|
||||
rm -f *.bin
|
||||
|
|
Loading…
Reference in New Issue