system_id: added axi_sysid ip core and tcl
parent
ab3d43be71
commit
4fe5f007cb
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -0,0 +1,5 @@
|
|||
=============
|
||||
AXI System ID
|
||||
=============
|
||||
|
||||
System Identification IP core
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue