diff --git a/library/axi_sysid/Makefile b/library/axi_sysid/Makefile new file mode 100644 index 000000000..203bfa344 --- /dev/null +++ b/library/axi_sysid/Makefile @@ -0,0 +1,13 @@ +#################################################################################### +## Copyright 2018(c) Analog Devices, Inc. +## Auto-generated, do not modify! +#################################################################################### + +LIBRARY_NAME := axi_sysid + +GENERIC_DEPS += ../common/up_axi.v +GENERIC_DEPS += axi_sysid.v + +XILINX_DEPS += axi_sysid_ip.tcl + +include ../scripts/library.mk diff --git a/library/axi_sysid/axi_sysid.v b/library/axi_sysid/axi_sysid.v new file mode 100755 index 000000000..60e3df8c1 --- /dev/null +++ b/library/axi_sysid/axi_sysid.v @@ -0,0 +1,135 @@ +`timescale 1ns / 1ps + +module sys_id #( + parameter ROM_WIDTH = 32, + parameter ROM_ADDR_BITS = 9)( + + //axi interface + input s_axi_aclk, + input s_axi_aresetn, + input s_axi_awvalid, + input [15:0] s_axi_awaddr, + input [2:0] s_axi_awprot, + output s_axi_awready, + input s_axi_wvalid, + input [31:0] s_axi_wdata, + input [3:0] s_axi_wstrb, + output s_axi_wready, + output s_axi_bvalid, + output [1:0] s_axi_bresp, + input s_axi_bready, + input s_axi_arvalid, + input [15:0] s_axi_araddr, + input [2:0] s_axi_arprot, + output s_axi_arready, + output s_axi_rvalid, + output [1:0] s_axi_rresp, + output [31:0] s_axi_rdata, + input s_axi_rready, + + input [ROM_WIDTH-1:0] sys_rom_data, + input [ROM_WIDTH-1:0] pr_rom_data, + output [ROM_ADDR_BITS-1:0] rom_addr); + +localparam AXI_ADDRESS_WIDTH = 12; +localparam [31:0] CORE_VERSION = {16'h0001, /* MAJOR */ + 8'h00, /* MINOR */ + 8'h00}; /* PATCH */ +localparam [31:0] CORE_MAGIC = 32'h53594944; // SYID + +reg up_wack = 'd0; +reg [31:0] up_rdata_s = 'd0; +reg up_rack_s = 'd0; +reg up_rreq_s_d = 'd0; +reg [31:0] up_scratch = 'd0; + +wire up_clk; +wire up_rstn; +wire up_rreq_s; +wire [(ROM_ADDR_BITS+1):0] up_raddr_s; +wire up_wreq_s; +wire [(ROM_ADDR_BITS+1):0] up_waddr_s; +wire [31:0] up_wdata_s; +wire [31:0] rom_data_s; + +assign up_clk = s_axi_aclk; +assign up_rstn = s_axi_aresetn; + +assign rom_addr = up_raddr_s [ROM_ADDR_BITS-1:0]; +assign rom_data_s = (up_raddr_s [ROM_ADDR_BITS + 1'h1: ROM_ADDR_BITS] == 2'h1) ? sys_rom_data : + (up_raddr_s [ROM_ADDR_BITS + 1'h1: ROM_ADDR_BITS] == 2'h2) ? pr_rom_data : 'h0; + +up_axi #( + .AXI_ADDRESS_WIDTH(ROM_ADDR_BITS+4)) +i_up_axi ( + .up_rstn (up_rstn), + .up_clk (up_clk), + .up_axi_awvalid (s_axi_awvalid), + .up_axi_awaddr (s_axi_awaddr[ROM_ADDR_BITS+3:0]), + .up_axi_awready (s_axi_awready), + .up_axi_wvalid (s_axi_wvalid), + .up_axi_wdata (s_axi_wdata), + .up_axi_wstrb (s_axi_wstrb), + .up_axi_wready (s_axi_wready), + .up_axi_bvalid (s_axi_bvalid), + .up_axi_bresp (s_axi_bresp), + .up_axi_bready (s_axi_bready), + .up_axi_arvalid (s_axi_arvalid), + .up_axi_araddr (s_axi_araddr[ROM_ADDR_BITS+3:0]), + .up_axi_arready (s_axi_arready), + .up_axi_rvalid (s_axi_rvalid), + .up_axi_rresp (s_axi_rresp), + .up_axi_rdata (s_axi_rdata), + .up_axi_rready (s_axi_rready), + .up_wreq (up_wreq_s), + .up_waddr (up_waddr_s), + .up_wdata (up_wdata_s), + .up_wack (up_wack), + .up_rreq (up_rreq_s), + .up_raddr (up_raddr_s), + .up_rdata (up_rdata_s), + .up_rack (up_rack_s)); + +//delaying data read with 1 tck to compensate for the ROM latency +always @(posedge up_clk) begin + up_rreq_s_d <= up_rreq_s; +end + +//axi registers read +always @(posedge up_clk) begin + if (up_rstn == 1'b0) begin + up_rack_s <= 'd0; + up_rdata_s <= 'd0; + end else begin + up_rack_s <= up_rreq_s_d; + if (up_rreq_s_d == 1'b1) begin + case (up_raddr_s) + 8'h00: up_rdata_s <= CORE_VERSION; + 8'h01: up_rdata_s <= 0; + 8'h02: up_rdata_s <= up_scratch; + 8'h03: up_rdata_s <= CORE_MAGIC; + 8'h10: up_rdata_s <= ROM_ADDR_BITS; + default: begin + up_rdata_s <= rom_data_s; + end + endcase + end else begin + up_rdata_s <= 32'd0; + end + end +end + +//axi registers write +always @(posedge up_clk) begin + if (up_rstn == 1'b0) begin + up_wack <= 'd0; + up_scratch <= 'd0; + end else begin + up_wack <= up_wreq_s; + if ((up_wreq_s == 1'b1) && (up_waddr_s == 8'h02)) begin + up_scratch <= up_wdata_s; + end + end +end + +endmodule diff --git a/library/axi_sysid/axi_sysid_ip.tcl b/library/axi_sysid/axi_sysid_ip.tcl new file mode 100644 index 000000000..4562fb312 --- /dev/null +++ b/library/axi_sysid/axi_sysid_ip.tcl @@ -0,0 +1,14 @@ +# ip + +source ../scripts/adi_env.tcl +source $ad_hdl_dir/library/scripts/adi_ip_xilinx.tcl + +adi_ip_create axi_sysid +adi_ip_files axi_sysid [list \ + "$ad_hdl_dir/library/common/up_axi.v" \ + "axi_sysid.v"] + +adi_ip_properties axi_sysid +set cc [ipx::current_core] + +ipx::save_core $cc diff --git a/library/axi_sysid/readme.rst b/library/axi_sysid/readme.rst new file mode 100644 index 000000000..ba5086ff3 --- /dev/null +++ b/library/axi_sysid/readme.rst @@ -0,0 +1,5 @@ +============= +AXI System ID +============= + +System Identification IP core diff --git a/library/sysid_rom/Makefile b/library/sysid_rom/Makefile new file mode 100755 index 000000000..db27ad917 --- /dev/null +++ b/library/sysid_rom/Makefile @@ -0,0 +1,12 @@ +#################################################################################### +## Copyright 2018(c) Analog Devices, Inc. +## Auto-generated, do not modify! +#################################################################################### + +LIBRARY_NAME := sysid_rom + +GENERIC_DEPS += sysid_rom.v + +XILINX_DEPS += sysid_rom_ip.tcl + +include ../scripts/library.mk diff --git a/library/sysid_rom/sysid_rom.v b/library/sysid_rom/sysid_rom.v new file mode 100755 index 000000000..e49b3a6b2 --- /dev/null +++ b/library/sysid_rom/sysid_rom.v @@ -0,0 +1,22 @@ +`timescale 1ns / 1ps + +module sysid_rom#( + parameter ROM_WIDTH = 32, + parameter ROM_ADDR_BITS = 6, + parameter PATH_TO_FILE = "path_to_mem_init_file" )( + + input clk, + input [ROM_ADDR_BITS-1:0] rom_addr, + output reg [ROM_WIDTH-1:0] rom_data); + +reg [ROM_WIDTH-1:0] lut_rom [(2**ROM_ADDR_BITS)-1:0]; + +initial begin + $readmemh(PATH_TO_FILE, lut_rom, 0, (2**ROM_ADDR_BITS)-1); +end + +always @(posedge clk) begin + rom_data = lut_rom[rom_addr]; +end + +endmodule diff --git a/library/sysid_rom/sysid_rom_ip.tcl b/library/sysid_rom/sysid_rom_ip.tcl new file mode 100755 index 000000000..174c3c885 --- /dev/null +++ b/library/sysid_rom/sysid_rom_ip.tcl @@ -0,0 +1,13 @@ +# ip + +source ../scripts/adi_env.tcl +source $ad_hdl_dir/library/scripts/adi_ip_xilinx.tcl + +adi_ip_create sysid_rom +adi_ip_files sysid_rom [list \ + "sysid_rom.v"] + +adi_ip_properties_lite sysid_rom +set cc [ipx::current_core] + +ipx::save_core $cc diff --git a/projects/adv7511/zed/Makefile b/projects/adv7511/zed/Makefile old mode 100644 new mode 100755 index 984681f54..edbc516c0 --- a/projects/adv7511/zed/Makefile +++ b/projects/adv7511/zed/Makefile @@ -14,6 +14,8 @@ LIB_DEPS += axi_dmac LIB_DEPS += axi_hdmi_tx LIB_DEPS += axi_i2s_adi LIB_DEPS += axi_spdif_tx +LIB_DEPS += axi_sysid +LIB_DEPS += sysid_rom LIB_DEPS += util_i2c_mixer include ../../scripts/project-xilinx.mk diff --git a/projects/adv7511/zed/system_bd.tcl b/projects/adv7511/zed/system_bd.tcl index 253f4f30e..68163bd5d 100644 --- a/projects/adv7511/zed/system_bd.tcl +++ b/projects/adv7511/zed/system_bd.tcl @@ -1,3 +1,10 @@ source $ad_hdl_dir/projects/common/zed/zed_system_bd.tcl +#system ID +ad_ip_parameter axi_sysid_0 CONFIG.ROM_ADDR_BITS 9 +ad_ip_parameter rom_sys_0 CONFIG.PATH_TO_FILE "[pwd]/mem_init_sys.txt" +ad_ip_parameter rom_sys_0 CONFIG.ROM_ADDR_BITS 9 +set sys_cstring "sys rom custom string placeholder" +sysid_gen_sys_init_file $sys_cstring + diff --git a/projects/common/zed/zed_system_bd.tcl b/projects/common/zed/zed_system_bd.tcl old mode 100644 new mode 100755 index 233a55b14..c00e099d8 --- a/projects/common/zed/zed_system_bd.tcl +++ b/projects/common/zed/zed_system_bd.tcl @@ -257,6 +257,14 @@ ad_connect sys_ps7/DMA2_REQ axi_i2s_adi/DMA_REQ_RX ad_connect sys_ps7/DMA2_ACK axi_i2s_adi/DMA_ACK_RX ad_connect sys_cpu_resetn axi_i2s_adi/DMA_REQ_RX_RSTN +# system id + +ad_ip_instance axi_sysid axi_sysid_0 +ad_ip_instance sysid_rom rom_sys_0 + +ad_connect axi_sysid_0/rom_addr rom_sys_0/rom_addr +ad_connect axi_sysid_0/sys_rom_data rom_sys_0/rom_data + # interrupts ad_connect sys_concat_intc/dout sys_ps7/IRQ_F2P @@ -280,12 +288,13 @@ ad_connect sys_concat_intc/In0 GND # interconnects and address mapping ad_cpu_interconnect 0x41600000 axi_iic_main +ad_cpu_interconnect 0x45000000 axi_sysid_0 ad_cpu_interconnect 0x79000000 axi_hdmi_clkgen ad_cpu_interconnect 0x43000000 axi_hdmi_dma ad_cpu_interconnect 0x70e00000 axi_hdmi_core ad_cpu_interconnect 0x75c00000 axi_spdif_tx_core ad_cpu_interconnect 0x77600000 axi_i2s_adi ad_cpu_interconnect 0x41620000 axi_iic_fmc + ad_mem_hp0_interconnect sys_cpu_clk sys_ps7/S_AXI_HP0 ad_mem_hp0_interconnect sys_cpu_clk axi_hdmi_dma/m_src_axi - diff --git a/projects/scripts/adi_board.tcl b/projects/scripts/adi_board.tcl index 2c541bc3c..842b47f5d 100644 --- a/projects/scripts/adi_board.tcl +++ b/projects/scripts/adi_board.tcl @@ -786,3 +786,191 @@ proc ad_cpu_interrupt {p_ps_index p_mb_index p_name} { } } +## Converts a string input to hex and adds whitespace as padding to obtain the size defined by +# the blocksize parameter. +# +# \param[str] - string input +# \param[blocksize] - size of hex output in bytes +# +# \return - hex +# + +proc stringtohex {str blocksize} { + binary scan $str H* hex + return [format %0-[expr $blocksize * 2]s $hex] +} + +## Generates the 8 bit checksum for the input hex string +# +# \param[hex] - string input +# +# \return - 8 bit checksum +# + +proc checksum8bit {hex} { + + set chks 0 + for {set i 0} {$i < [string length $hex]} {incr i} { + if { ($i+1) % 2 == 0} { + set chks [expr $chks + "0x[string range $hex $i-1 $i]"] + } + } + return [format %0.2x [expr 255 - [expr "0x[string range [format %0.2x $chks] [expr [string length [format %0.2x $chks]] -2] [expr [string length [format %0.2x $chks]] -1]]"] +1]] +} + +## Flips the characters of a string, four at a time. Used to fix endianness. +# +# \param[str] - string input +# +# \return - string +# + +proc hexstr_flip {str} { + + set fstr {} + for {set i 0} {$i < [string length $str]} {incr i} { + if { ($i+1) % 8 == 0} { + set line [string range $str [expr $i - 7] $i] + set fline {} + for {set j 0} {$j < [string length $line]} {incr j} { + if { ($j+1) % 2 == 0} { + append fline [string reverse [append byte [string index $line $j]]] + } else { + set byte [string index $line $j] + } + } + append fstr [string reverse $fline] + } + } + return $fstr +} + +## Generates a file used for initializing the system ROM. +# +# \param[custom_string] - string input +# + +proc sysid_gen_sys_init_file {custom_string} { + + # git sha + set no_git_err "fatal: not a git repository" + if {[catch {exec git rev-parse HEAD} gitsha_string]} { + if [expr [string match *$no_git_err* $gitsha_string] == 1] { + set gitsha_string 0 + } + } + set gitsha_hex [hexstr_flip [stringtohex $gitsha_string 44]] + + #git clean + set git_clean_string "f" + if {$gitsha_string != 0} { + set git_status [exec git status .] + if [expr [string match *modified* $git_status] == 0] { + set git_clean_string "t" + } + } + set git_clean_hex [hexstr_flip [stringtohex $git_clean_string 4]] + + # vadj check + set vadj_check_string "vadj" + set vadj_check_hex [hexstr_flip [stringtohex $vadj_check_string 4]] + + # time and date + set thetime [clock seconds] + set timedate_hex [hexstr_flip [stringtohex $thetime 12]] + + # merge components + set verh_hex {} + set verh_size 448 + + append verh_hex $gitsha_hex $git_clean_hex $vadj_check_hex $timedate_hex + append verh_hex "00000000" [checksum8bit $verh_hex] "000000" + set verh_hex [format %0-[expr [expr $verh_size] * 8]s $verh_hex] + + # common header + # size in lines + set table_size 16 + set comh_size [expr 8 * $table_size] + + # set version + set comh_ver_hex "00000001" + + # project name + set projname_hex [hexstr_flip [stringtohex [lindex [split [current_project] _] 0] 32]] + + # board name + set boardname_hex [hexstr_flip [stringtohex [lindex [split [current_project] _] 1] 32]] + + # custom string + set custom_hex [hexstr_flip [stringtohex $custom_string 64]] + + # pr offset + # not used + set pr_offset "00000000" + + # init - generate header + set comh_hex {} + append comh_hex $comh_ver_hex + + # offset for internal use area + set offset $table_size + append comh_hex [format %08s [format %0.2x $offset]] + + # offset for projname_hex + set offset [expr $table_size + $verh_size] + append comh_hex [format %08s [format %0.2x $offset]] + + # offset for boardname_hex + set offset [expr $offset + [expr [string length $projname_hex] / 8]] + append comh_hex [format %08s [format %0.2x $offset]] + + # offset for custom_hex + set offset [expr $offset + [expr [string length $boardname_hex] / 8]] + append comh_hex [format %08s [format %0.2x $offset]] + + # offset for pr custom string + set offset $pr_offset + append comh_hex [format %08s $offset] + + # pad header to match size and add checksum + set comh_hex [format %0-[expr [expr $table_size - 2] * 8]s $comh_hex] + append comh_hex "00000000" [checksum8bit $comh_hex] "000000" + + # creating file + set sys_mem_hex [format %0-[expr 512 * 8]s [concat $comh_hex$verh_hex$projname_hex$boardname_hex$custom_hex]] + + set sys_mem_file [open "mem_init_sys.txt" "w"] + + # writting 32 bits to each line + for {set i 0} {$i < [string length $sys_mem_hex]} {incr i} { + if { ($i+1) % 8 == 0} { + puts $sys_mem_file [string index $sys_mem_hex $i] + } else { + puts -nonewline $sys_mem_file [string index $sys_mem_hex $i] + } + } + close $sys_mem_file +} + +## Generates a file used for initializing the PR ROM. +# +# \param[custom_string] - string input +# + +proc sysid_gen_pr_init_file {custom_string} { + + set custom_hex [stringtohex $custom_string 64] + + # creating file + set pr_mem_file [open "mem_init_pr.txt" "w"] + + # writting 32 bits to each line + for {set i 0} {$i < [string length $custom_hex]} {incr i} { + if { ($i+1) % 8 == 0} { + puts $pr_mem_file [string index $custom_hex $i] + } else { + puts -nonewline $pr_mem_file [string index $custom_hex $i] + } + } + close $pr_mem_file +}