system_id: added axi_sysid ip core and tcl

main
Sergiu Arpadi 2019-05-08 15:02:33 +01:00 committed by sarpadi
parent ab3d43be71
commit 4fe5f007cb
11 changed files with 421 additions and 1 deletions

View File

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

135
library/axi_sysid/axi_sysid.v Executable file
View File

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

View File

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

View File

@ -0,0 +1,5 @@
=============
AXI System ID
=============
System Identification IP core

12
library/sysid_rom/Makefile Executable file
View File

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

22
library/sysid_rom/sysid_rom.v Executable file
View File

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

View File

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

2
projects/adv7511/zed/Makefile Normal file → Executable file
View File

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

View File

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

11
projects/common/zed/zed_system_bd.tcl Normal file → Executable file
View File

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

View File

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