Merge pull request #109 from sebastien-riou/arty

missing tcl files for Murax on Arty
This commit is contained in:
Dolu1990 2020-01-17 12:07:54 +01:00 committed by GitHub
commit ac79cc6fe6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 330 additions and 1 deletions

View File

@ -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"
}

View File

@ -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"
}

View File

@ -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"

View File

@ -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

View File

@ -0,0 +1,4 @@
source [file join [file dirname [file normalize [info script]]] vivado_params.tcl]
open_project -read_only $outputdir/$projectName
start_gui

View File

@ -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

View File

@ -0,0 +1,5 @@
set outputdir ./vivado_project
set part "xc7a35ticsg324-1L"
set base ".."
set projectName "fpga"
set topv "$base/../../../Murax.v"

View File

@ -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

View File

@ -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

View File

@ -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