fpga: x400: Add netlist make flow
Original-commit: 789fa8f65727afabdeb4eea30a941015c6cd2ad5
This commit is contained in:
committed by
Joerg Hofrichter
parent
69e728dba0
commit
6d89320721
@@ -29,6 +29,7 @@ BUILD_VIVADO_DESIGN = \
|
|||||||
export VIV_DESIGN_SRCS=$(call RESOLVE_PATHS,$(call uniq,$(DESIGN_SRCS))); \
|
export VIV_DESIGN_SRCS=$(call RESOLVE_PATHS,$(call uniq,$(DESIGN_SRCS))); \
|
||||||
export VIV_VERILOG_DEFS="$(VERILOG_DEFS) UHD_FPGA_DIR=$(BASE_DIR)/../.."; \
|
export VIV_VERILOG_DEFS="$(VERILOG_DEFS) UHD_FPGA_DIR=$(BASE_DIR)/../.."; \
|
||||||
export VIV_INCR_BUILD=$(INCR_BUILD); \
|
export VIV_INCR_BUILD=$(INCR_BUILD); \
|
||||||
|
export VIV_SECURE_KEY=$(call RESOLVE_PATH,$(abspath $(SECURE_KEY))); \
|
||||||
cd $(BUILD_DIR); \
|
cd $(BUILD_DIR); \
|
||||||
$(TOOLS_DIR)/scripts/launch_vivado.py --parse-config $(MAKEFILE_DIR)/dev_config.json -mode $(VIVADO_MODE) -source $(call RESOLVE_PATH,$(1)) -log build.log -journal $(2).jou
|
$(TOOLS_DIR)/scripts/launch_vivado.py --parse-config $(MAKEFILE_DIR)/dev_config.json -mode $(VIVADO_MODE) -source $(call RESOLVE_PATH,$(1)) -log build.log -journal $(2).jou
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,19 @@
|
|||||||
|
#
|
||||||
|
# Copyright 2024 Ettus Research, a National Instruments Brand
|
||||||
|
#
|
||||||
|
|
||||||
|
source $::env(VIV_TOOLS_DIR)/scripts/viv_utils.tcl
|
||||||
|
source $::env(VIV_TOOLS_DIR)/scripts/viv_strategies.tcl
|
||||||
|
|
||||||
|
# STEP#1: Create project, add sources, refresh IP
|
||||||
|
vivado_utils::initialize_project
|
||||||
|
|
||||||
|
# STEP#2: Run synthesis
|
||||||
|
vivado_utils::synthesize_design -mode out_of_context
|
||||||
|
vivado_utils::generate_post_synth_reports
|
||||||
|
|
||||||
|
# STEP#3: Generate encrypted netlist
|
||||||
|
vivado_utils::export_encrypted_netlist
|
||||||
|
|
||||||
|
# Cleanup
|
||||||
|
vivado_utils::close_batch_project
|
||||||
+110
-8
@@ -10,6 +10,9 @@ namespace eval ::vivado_utils {
|
|||||||
namespace export \
|
namespace export \
|
||||||
initialize_project \
|
initialize_project \
|
||||||
synthesize_design \
|
synthesize_design \
|
||||||
|
export_synth_netlist \
|
||||||
|
separate_encrypted \
|
||||||
|
export_encrypted_netlist \
|
||||||
check_design \
|
check_design \
|
||||||
generate_post_synth_reports \
|
generate_post_synth_reports \
|
||||||
generate_post_place_reports \
|
generate_post_place_reports \
|
||||||
@@ -27,6 +30,7 @@ namespace eval ::vivado_utils {
|
|||||||
variable g_source_files $::env(VIV_DESIGN_SRCS)
|
variable g_source_files $::env(VIV_DESIGN_SRCS)
|
||||||
variable g_vivado_mode $::env(VIV_MODE)
|
variable g_vivado_mode $::env(VIV_MODE)
|
||||||
variable g_project_save $::env(VIV_PROJECT)
|
variable g_project_save $::env(VIV_PROJECT)
|
||||||
|
variable g_secure_key $::env(VIV_SECURE_KEY)
|
||||||
|
|
||||||
# Optional environment variables
|
# Optional environment variables
|
||||||
variable g_verilog_defs ""
|
variable g_verilog_defs ""
|
||||||
@@ -73,23 +77,29 @@ proc ::vivado_utils::initialize_project { {save_to_disk 0} } {
|
|||||||
foreach src_file $g_source_files {
|
foreach src_file $g_source_files {
|
||||||
set src_ext [file extension $src_file ]
|
set src_ext [file extension $src_file ]
|
||||||
if [expr [lsearch {.vhd .vhdl} $src_ext] >= 0] {
|
if [expr [lsearch {.vhd .vhdl} $src_ext] >= 0] {
|
||||||
puts "BUILDER: Adding VHDL : $src_file"
|
puts "BUILDER: Adding VHDL: $src_file"
|
||||||
read_vhdl -library work $src_file
|
read_vhdl -library work $src_file
|
||||||
} elseif [expr [lsearch {.v .vh .sv .svh} $src_ext] >= 0] {
|
} elseif [expr [lsearch {.v .vh} $src_ext] >= 0] {
|
||||||
puts "BUILDER: Adding Verilog : $src_file"
|
puts "BUILDER: Adding Verilog: $src_file"
|
||||||
read_verilog $src_file
|
read_verilog $src_file
|
||||||
|
} elseif [expr [lsearch {.vp} $src_ext] >= 0] {
|
||||||
|
puts "BUILDER: Adding encrypted Verilog: $src_file"
|
||||||
|
read_verilog $src_file
|
||||||
|
} elseif [expr [lsearch {.sv .svh} $src_ext] >= 0] {
|
||||||
|
puts "BUILDER: Adding SystemVerilog: $src_file"
|
||||||
|
read_verilog -sv $src_file
|
||||||
} elseif [expr [lsearch {.xdc} $src_ext] >= 0] {
|
} elseif [expr [lsearch {.xdc} $src_ext] >= 0] {
|
||||||
puts "BUILDER: Adding XDC : $src_file"
|
puts "BUILDER: Adding XDC: $src_file"
|
||||||
read_xdc $src_file
|
read_xdc $src_file
|
||||||
} elseif [expr [lsearch {.sdc} $src_ext] >= 0] {
|
} elseif [expr [lsearch {.sdc} $src_ext] >= 0] {
|
||||||
puts "BUILDER: Adding SDC : $src_file"
|
puts "BUILDER: Adding SDC: $src_file"
|
||||||
read_xdc $src_file
|
read_xdc $src_file
|
||||||
} elseif [expr [lsearch {.xci} $src_ext] >= 0] {
|
} elseif [expr [lsearch {.xci} $src_ext] >= 0] {
|
||||||
puts "BUILDER: Adding IP : $src_file"
|
puts "BUILDER: Adding IP: $src_file"
|
||||||
read_ip $src_file
|
read_ip $src_file
|
||||||
set_property generate_synth_checkpoint true [get_files $src_file]
|
set_property generate_synth_checkpoint true [get_files $src_file]
|
||||||
} elseif [expr [lsearch {.ngc .edif .edf} $src_ext] >= 0] {
|
} elseif [expr [lsearch {.ngc .edif .edf} $src_ext] >= 0] {
|
||||||
puts "BUILDER: Adding Netlist : $src_file"
|
puts "BUILDER: Adding Netlist: $src_file"
|
||||||
read_edif $src_file
|
read_edif $src_file
|
||||||
} elseif [expr [lsearch {.bd} $src_ext] >= 0] {
|
} elseif [expr [lsearch {.bd} $src_ext] >= 0] {
|
||||||
puts "BUILDER: Adding Block Design to list (added after IP regeneration): $src_file"
|
puts "BUILDER: Adding Block Design to list (added after IP regeneration): $src_file"
|
||||||
@@ -98,7 +108,7 @@ proc ::vivado_utils::initialize_project { {save_to_disk 0} } {
|
|||||||
puts "BUILDER: Adding Block Design XML to list (added after IP regeneration): $src_file"
|
puts "BUILDER: Adding Block Design XML to list (added after IP regeneration): $src_file"
|
||||||
append bd_files "$src_file "
|
append bd_files "$src_file "
|
||||||
} elseif [expr [lsearch {.dat} $src_ext] >= 0] {
|
} elseif [expr [lsearch {.dat} $src_ext] >= 0] {
|
||||||
puts "BUILDER: Adding Data File : $src_file"
|
puts "BUILDER: Adding Data File: $src_file"
|
||||||
add_files $src_file
|
add_files $src_file
|
||||||
} else {
|
} else {
|
||||||
puts "BUILDER: \[WARNING\] File ignored!!!: $src_file"
|
puts "BUILDER: \[WARNING\] File ignored!!!: $src_file"
|
||||||
@@ -148,6 +158,98 @@ proc ::vivado_utils::synthesize_design {args} {
|
|||||||
eval $synth_cmd
|
eval $synth_cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# ---------------------------------------------------
|
||||||
|
# Generate netlist from Synthesis
|
||||||
|
# ---------------------------------------------------
|
||||||
|
proc ::vivado_utils::export_synth_netlist { {suffix ""} } {
|
||||||
|
variable g_output_dir
|
||||||
|
variable g_top_module
|
||||||
|
|
||||||
|
puts "BUILDER: Writing EDIF netlist for $g_top_module"
|
||||||
|
set filename ${g_output_dir}/${g_top_module}
|
||||||
|
if { [expr [string length $suffix] > 0] } {
|
||||||
|
set filename ${filename}_${suffix}
|
||||||
|
}
|
||||||
|
write_edif -security_mode all -force ${filename}.edf
|
||||||
|
write_verilog -mode synth_stub -force -file ${filename}_stub.v
|
||||||
|
}
|
||||||
|
|
||||||
|
# ---------------------------------------------------
|
||||||
|
# Extract encrypted sections from a file
|
||||||
|
# ---------------------------------------------------
|
||||||
|
proc ::vivado_utils::separate_encrypted {input_filename unencrypted_filename encrypted_filename} {
|
||||||
|
set protected_sections ""
|
||||||
|
set unprotected_sections ""
|
||||||
|
set inside_protected_section 0
|
||||||
|
|
||||||
|
# Read each line from the input file and separate it into protected and
|
||||||
|
# unprotected sections.
|
||||||
|
set input_file [open $input_filename r]
|
||||||
|
while {[gets $input_file line] >= 0} {
|
||||||
|
# Check if we are inside a protected section
|
||||||
|
if {[string match "*`pragma protect begin_protected*" $line]} {
|
||||||
|
set inside_protected_section 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# Append the line to the appropriate section
|
||||||
|
if {$inside_protected_section} {
|
||||||
|
append protected_sections "$line\n"
|
||||||
|
} else {
|
||||||
|
append unprotected_sections "$line\n"
|
||||||
|
}
|
||||||
|
|
||||||
|
if {[string match "*`pragma protect end_protected*" $line]} {
|
||||||
|
set inside_protected_section 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
close $input_file
|
||||||
|
|
||||||
|
# Write the extracted portions to files
|
||||||
|
set encrypted_file [open $encrypted_filename w]
|
||||||
|
puts $encrypted_file $protected_sections
|
||||||
|
close $encrypted_file
|
||||||
|
set unencrypted_file [open $unencrypted_filename w]
|
||||||
|
puts $unencrypted_file $unprotected_sections
|
||||||
|
close $unencrypted_file
|
||||||
|
}
|
||||||
|
|
||||||
|
# ---------------------------------------------------------
|
||||||
|
# Generate an IEEE-1735 encrypted netlist in a single file
|
||||||
|
# ---------------------------------------------------------
|
||||||
|
proc ::vivado_utils::export_encrypted_netlist { {suffix ""} } {
|
||||||
|
variable g_output_dir
|
||||||
|
variable g_top_module
|
||||||
|
variable g_secure_key
|
||||||
|
|
||||||
|
puts "BUILDER: Writing encrypted netlist for $g_top_module"
|
||||||
|
set filename ${g_output_dir}/${g_top_module}
|
||||||
|
if { [expr [string length $suffix] > 0] } {
|
||||||
|
set filename ${filename}_${suffix}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Uniquify the module names to prevent collisions when the netlist is used
|
||||||
|
rename_ref -prefix_all $g_top_module
|
||||||
|
|
||||||
|
# Write the design to a Verilog netlist
|
||||||
|
write_verilog -force ${filename}_netlist.v
|
||||||
|
puts "BUILDER: Unencrypted netlist written to ${filename}_netlist.v"
|
||||||
|
write_xdc -force ${filename}.xdc
|
||||||
|
puts "BUILDER: Constraints written to ${filename}.xdc"
|
||||||
|
if {$g_secure_key ne ""} {
|
||||||
|
# The netlist may have parts that are already encrypted and Vivado doesn't
|
||||||
|
# let us encrypt stuff that's already encrypted, so we need to split it up.
|
||||||
|
vivado_utils::separate_encrypted ${filename}_netlist.v ${filename}_netlist_user.v ${filename}_netlist_other.vp
|
||||||
|
# Encrypt the parts that aren't already encrypted
|
||||||
|
encrypt -key ${g_secure_key} -lang verilog -ext .vp ${filename}_netlist_user.v
|
||||||
|
# Merge the two encrypted files
|
||||||
|
set combined_netlists [read [open ${filename}_netlist_user.vp r]][read [open ${filename}_netlist_other.vp r]]
|
||||||
|
set combined_netlists_file [open ${filename}.vp w]
|
||||||
|
puts $combined_netlists_file $combined_netlists
|
||||||
|
close $combined_netlists_file
|
||||||
|
puts "BUILDER: Encrypted netlist written to ${filename}.vp"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
# ---------------------------------------------------
|
# ---------------------------------------------------
|
||||||
# Check design (Shortcut for Vivado's synth_design -rtl)
|
# Check design (Shortcut for Vivado's synth_design -rtl)
|
||||||
# ---------------------------------------------------
|
# ---------------------------------------------------
|
||||||
|
|||||||
@@ -48,6 +48,9 @@ ifndef TARGET
|
|||||||
TARGET = synth
|
TARGET = synth
|
||||||
else ifeq ($(IP_ONLY), 1)
|
else ifeq ($(IP_ONLY), 1)
|
||||||
TARGET = viv_ip
|
TARGET = viv_ip
|
||||||
|
else ifeq ($(SECURE_CORE), 1)
|
||||||
|
TARGET = secure_core
|
||||||
|
TOP = secure_image_core
|
||||||
else
|
else
|
||||||
TARGET = bin
|
TARGET = bin
|
||||||
endif
|
endif
|
||||||
@@ -174,6 +177,7 @@ help: ##Show this help message.
|
|||||||
##CHECK=1 Launch the syntax checker instead of building a bitfile.
|
##CHECK=1 Launch the syntax checker instead of building a bitfile.
|
||||||
##IP_ONLY=1 Launch the build but stop after IP generation.
|
##IP_ONLY=1 Launch the build but stop after IP generation.
|
||||||
##SYNTH=1 Launch the build but stop after synthesis.
|
##SYNTH=1 Launch the build but stop after synthesis.
|
||||||
|
##SECURE_CORE=1 Launch a build of the secure image core only.
|
||||||
##BUILD_SEED=<N> Build seed to used to affect build results. (Default is 0)
|
##BUILD_SEED=<N> Build seed to used to affect build results. (Default is 0)
|
||||||
##TOP=<module> Specify a top module for syntax checking. (Default is the bitfile top)
|
##TOP=<module> Specify a top module for syntax checking. (Default is the bitfile top)
|
||||||
|
|
||||||
|
|||||||
@@ -187,4 +187,7 @@ rtl: .prereqs
|
|||||||
viv_ip: .prereqs $$(DESIGN_SRCS) ip
|
viv_ip: .prereqs $$(DESIGN_SRCS) ip
|
||||||
@echo "IP build for $(NAME) DONE . . ."
|
@echo "IP build for $(NAME) DONE . . ."
|
||||||
|
|
||||||
.PHONY: bin synth rtl viv_ip
|
secure_core: .prereqs
|
||||||
|
$(call BUILD_VIVADO_DESIGN,$(TOOLS_DIR)/scripts/viv_secure_synth.tcl,$(TOP_MODULE),$(ARCH),$(PART_ID))
|
||||||
|
|
||||||
|
.PHONY: bin synth rtl viv_ip secure_synth_netlist
|
||||||
|
|||||||
Reference in New Issue
Block a user