Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision

Target

Select target project
  • soclabs/nanosoc_tech
1 result
Select Git revision
Show changes
Commits on Source (65)
Showing
with 57 additions and 9292 deletions
# Exclude Simulation Files
# Exclude Compiled Binaries
/software/*/*.elf
/software/*/*.ELF
/software/*/*.hex
/software/*/*.lst
/software/*/*.o
# Compile Test Code Removal
system/testcodes/*/*.elf
system/testcodes/*/*.ELF
system/testcodes/*/*.hex
system/testcodes/*/*.lst
system/testcodes/*/*.o
# Bootrom removal
system/src/bootrom/
# Simulation Removal (If running at Tech Level)
sim
\ No newline at end of file
......@@ -34,24 +34,27 @@ build-job-Z2: # This job runs in the build stage, which runs first.
- cd ../DMA-230_MicroDMA_Controller/
- tar -xf PL230-r0p0-02rel2-1.tar.gz
# move to fpga_imp directory and run the fpga build script for pynq z2
- cd ../../nanosoc/Cortex-M0/nanosoc/systems/mcu/fpga_imp/
- if source ./build_fpga_pynq_z2.scr; then
- FILE = ./pynq_export/pz2/pynq/overlays/soclabs/design_1.bit
- if test -f "$FILE"; then
- echo "Build successful"
- else
- echo "Build failed"
- fi
- cd ../../nanosoc/system/fpga_imp/
- source ../../set_env.sh
- mkdir -p $NANOSOC_TECH_DIR/system/src/bootrom
- make -C $NANOSOC_TECH_DIR/system bootrom SIM_TOP_DIR=$NANOSOC_TECH_DIR/sim BOOTROM_BUILD_DIR=$NANOSOC_TECH_DIR/system/src/bootrom TOOL_CHAIN=ds6
- if source ./build_fpga_pynq_z2.scr; then echo "Vivado Finished"; fi
- FILE=./pynq_export/pz2/pynq/overlays/soclabs/design_1.bit
- if test -f "$FILE"; then
- echo "Build successful"
- else
- echo "Build failed"
- exit 1
- fi
# cleanup arm-AAA-ip directory
- cd ../../../../../../
- cd ../../../
- rm -r arm-AAA-ip
artifacts:
paths:
# Keep the generated bit and hwh file from fpga build script
- ./Cortex-M0/nanosoc/systems/mcu/fpga_imp/pynq_export/pz2/pynq/overlays/soclabs/design_1.bit
- ./Cortex-M0/nanosoc/systems/mcu/fpga_imp/pynq_export/pz2/pynq/overlays/soclabs/design_1.hwh
- ./Cortex-M0/nanosoc/systems/mcu/fpga_imp/CI_verification/load_bitfile.py
- ./system/fpga_imp/pynq_export/pz2/pynq/overlays/soclabs/design_1.bit
- ./system/fpga_imp/pynq_export/pz2/pynq/overlays/soclabs/design_1.hwh
- ./system/fpga_imp/CI_verification/load_bitfile.py
tags:
- Vivado2021.1
......@@ -67,24 +70,27 @@ build-job-ZCU104: # This job runs in the build stage, which runs first.
- cd ../DMA-230_MicroDMA_Controller/
- tar -xf PL230-r0p0-02rel2-1.tar.gz
# move to fpga_imp directory and run the fpga build script for pynq z2
- cd ../../nanosoc/Cortex-M0/nanosoc/systems/mcu/fpga_imp/
- if source ./build_fpga_pynq_zcu104.scr; then
- FILE = ./pynq_export/pz104/pynq/overlays/soclabs/design_1.bit
- if test -f "$FILE"; then
- echo "Build successful"
- else
- echo "Build failed"
- fi
- cd ../../nanosoc/system/fpga_imp/
- source ../../set_env.sh
- mkdir -p $NANOSOC_TECH_DIR/system/src/bootrom
- make -C $NANOSOC_TECH_DIR/system bootrom SIM_TOP_DIR=$NANOSOC_TECH_DIR/sim BOOTROM_BUILD_DIR=$NANOSOC_TECH_DIR/system/src/bootrom TOOL_CHAIN=ds5
- if source ./build_fpga_pynq_zcu104.scr; then echo "Vivado Finished"; fi
- FILE=./pynq_export/pz104/pynq/overlays/soclabs/design_1.bit
- if test -f "$FILE"; then
- echo "Build successful"
- else
- echo "Build failed"
- exit 1
- fi
# cleanup arm-AAA-ip directory
- cd ../../../../../../
- cd ../../../
- rm -r arm-AAA-ip
artifacts:
paths:
# Keep the generated bit and hwh file from fpga build script
- ./Cortex-M0/nanosoc/systems/mcu/fpga_imp/pynq_export/pz104/pynq/overlays/soclabs/design_1.bit
- ./Cortex-M0/nanosoc/systems/mcu/fpga_imp/pynq_export/pz104/pynq/overlays/soclabs/design_1.hwh
- ./Cortex-M0/nanosoc/systems/mcu/fpga_imp/CI_verification/load_bitfile.py
- ./system/fpga_imp/pynq_export/pz104/pynq/overlays/soclabs/design_1.bit
- ./system/fpga_imp/pynq_export/pz104/pynq/overlays/soclabs/design_1.hwh
- ./system/fpga_imp/CI_verification/load_bitfile.py
tags:
- VLAB-ZCU
......@@ -95,9 +101,9 @@ deploy-job-Z2: # This job runs in the deploy stage.
- echo "Deploying application to Z2"
# use smbclient to transfer accross the bit, hwh and python script files to the z2 xilinx board
# could probably set this up as scp with RSA keys in future
- smbclient //192.168.2.99/xilinx -m SMB3 -U xilinx%xilinx -c 'cd ./pynq/overlays/soclabs/ ; put ./Cortex-M0/nanosoc/systems/mcu/fpga_imp/pynq_export/pz2/pynq/overlays/soclabs/design_1.bit ./design_1.bit'
- smbclient //192.168.2.99/xilinx -m SMB3 -U xilinx%xilinx -c 'cd ./pynq/overlays/soclabs/ ; put ./Cortex-M0/nanosoc/systems/mcu/fpga_imp/pynq_export/pz2/pynq/overlays/soclabs/design_1.hwh ./design_1.hwh'
- cd ./Cortex-M0/nanosoc/systems/mcu/fpga_imp/CI_verification
- smbclient //192.168.2.99/xilinx -m SMB3 -U xilinx%xilinx -c 'cd ./pynq/overlays/soclabs/ ; put ./system/fpga_imp/pynq_export/pz2/pynq/overlays/soclabs/design_1.bit ./design_1.bit'
- smbclient //192.168.2.99/xilinx -m SMB3 -U xilinx%xilinx -c 'cd ./pynq/overlays/soclabs/ ; put ./system/fpga_imp/pynq_export/pz2/pynq/overlays/soclabs/design_1.hwh ./design_1.hwh'
- cd ./system/fpga_imp/CI_verification
- smbclient //192.168.2.99/xilinx -m SMB3 -U xilinx%xilinx -c 'put ./load_bitfile.py ./load_bitfile.py'
# get root access on host machine, this was found to be needed because other screen would not work
# however a more elegant solution would be better
......@@ -148,11 +154,11 @@ deploy-job-ZCU104: # This job runs in the deploy stage.
- screen -r zynq -X stuff "./ZCU104_connect.sh \n"
- sleep 10
# use scp to copy over bit files and python script
- screen -r zynq -X stuff "scp -i ~/.ssh/id_rsa dwn1c21@soclabs.soton.ac.uk:~/builds/wzndG1mA/0/soclabs/nanosoc/Cortex-M0/nanosoc/systems/mcu/fpga_imp/CI_verification/load_bitfile.py ./ \n"
- screen -r zynq -X stuff "scp -i ~/.ssh/id_rsa dwn1c21@soclabs.soton.ac.uk:~/builds/wzndG1mA/0/soclabs/nanosoc/system/fpga_imp/CI_verification/load_bitfile.py ./ \n"
- sleep 2
- screen -r zynq -X stuff "scp -i ~/.ssh/id_rsa dwn1c21@soclabs.soton.ac.uk:~/builds/wzndG1mA/0/soclabs/nanosoc/Cortex-M0/nanosoc/systems/mcu/fpga_imp/pynq_export/pz104/pynq/overlays/soclabs/design_1.bit ./pynq/overlays/soclabs/design_1.bit \n"
- screen -r zynq -X stuff "scp -i ~/.ssh/id_rsa dwn1c21@soclabs.soton.ac.uk:~/builds/wzndG1mA/0/soclabs/nanosoc/system/fpga_imp/pynq_export/pz104/pynq/overlays/soclabs/design_1.bit ./pynq/overlays/soclabs/design_1.bit \n"
- sleep 2
- screen -r zynq -X stuff "scp -i ~/.ssh/id_rsa dwn1c21@soclabs.soton.ac.uk:~/builds/wzndG1mA/0/soclabs/nanosoc/Cortex-M0/nanosoc/systems/mcu/fpga_imp/pynq_export/pz104/pynq/overlays/soclabs/design_1.hwh ./pynq/overlays/soclabs/design_1.hwh \n"
- screen -r zynq -X stuff "scp -i ~/.ssh/id_rsa dwn1c21@soclabs.soton.ac.uk:~/builds/wzndG1mA/0/soclabs/nanosoc/system/fpga_imp/pynq_export/pz104/pynq/overlays/soclabs/design_1.hwh ./pynq/overlays/soclabs/design_1.hwh \n"
- sleep 2
# Need root access to load the overlay onto the FPGA
- screen -r zynq -X stuff "sudo su\n"
......
# rtl_source_soclabs_ip.tcl
#
set iplib_vlog ../../../../../IPLIB
read_verilog $iplib_vlog/FT1248_streamio_v1_0/ft1248_streamio_v1_0.v
read_verilog $iplib_vlog/ADPcontrol_v1_0/ADPcontrol_v1_0.v
read_verilog $iplib_vlog/ADPcontrol_v1_0/ADPmanager.v
export ARM_PRODUCT_PATH=/apps/arm/developmentstudio-2021.0/sw/mappings
export ARM_TOOL_VARIANT=gold
export PATH=$PATH:/apps/arm/developmentstudio-2021.0/sw/ARMCompiler5.06u7/bin/
export ARM_PRODUCT_PATH=/apps/arm/developmentstudio-2021.0/sw/mappings
export ARM_TOOL_VARIANT=gold
export PATH=$PATH:/apps/arm/developmentstudio-2021.0/sw/ARMCompiler5.06u7/bin/
File deleted
//------------------------------------------------------------------------------------
// customised auto-generated synthesizable ROM module abstraction
// A joint work commissioned on behalf of SoC Labs, under Arm Academic Access license.
//
// Contributors
//
// David Flynn (d.w.flynn@soton.ac.uk)
// Date: 2302101100
// Copyright (c) 2021-2, SoC Labs (www.soclabs.org)
//------------------------------------------------------------------------------------
module bootrom (
input wire CLK,
input wire EN,
input wire [9:2] ADDR,
output reg [31:0] RDATA );
reg [9:2] addr_r;
always @(posedge CLK) if (EN) addr_r <= ADDR;
always @(addr_r) case(addr_r[9:2])
8'h00 : RDATA <= 32'h30000368; // 0x0000
8'h01 : RDATA <= 32'h10000335; // 0x0004
8'h02 : RDATA <= 32'h1000033d; // 0x0008
8'h03 : RDATA <= 32'h1000033f; // 0x000c
8'h04 : RDATA <= 32'h00000000; // 0x0010
8'h05 : RDATA <= 32'h00000000; // 0x0014
8'h06 : RDATA <= 32'h00000000; // 0x0018
8'h07 : RDATA <= 32'h00000000; // 0x001c
8'h08 : RDATA <= 32'h00000000; // 0x0020
8'h09 : RDATA <= 32'h00000000; // 0x0024
8'h0a : RDATA <= 32'h00000000; // 0x0028
8'h0b : RDATA <= 32'h10000341; // 0x002c
8'h0c : RDATA <= 32'h00000000; // 0x0030
8'h0d : RDATA <= 32'h00000000; // 0x0034
8'h0e : RDATA <= 32'h10000343; // 0x0038
8'h0f : RDATA <= 32'h10000345; // 0x003c
8'h10 : RDATA <= 32'h10000347; // 0x0040
8'h11 : RDATA <= 32'h10000347; // 0x0044
8'h12 : RDATA <= 32'h10000347; // 0x0048
8'h13 : RDATA <= 32'h10000347; // 0x004c
8'h14 : RDATA <= 32'h10000347; // 0x0050
8'h15 : RDATA <= 32'h10000347; // 0x0054
8'h16 : RDATA <= 32'h10000347; // 0x0058
8'h17 : RDATA <= 32'h10000347; // 0x005c
8'h18 : RDATA <= 32'h10000347; // 0x0060
8'h19 : RDATA <= 32'h10000347; // 0x0064
8'h1a : RDATA <= 32'h10000347; // 0x0068
8'h1b : RDATA <= 32'h00000000; // 0x006c
8'h1c : RDATA <= 32'h10000347; // 0x0070
8'h1d : RDATA <= 32'h10000347; // 0x0074
8'h1e : RDATA <= 32'h10000347; // 0x0078
8'h1f : RDATA <= 32'h10000347; // 0x007c
8'h20 : RDATA <= 32'h10000347; // 0x0080
8'h21 : RDATA <= 32'h10000347; // 0x0084
8'h22 : RDATA <= 32'h10000347; // 0x0088
8'h23 : RDATA <= 32'h10000347; // 0x008c
8'h24 : RDATA <= 32'h10000347; // 0x0090
8'h25 : RDATA <= 32'h10000347; // 0x0094
8'h26 : RDATA <= 32'h10000347; // 0x0098
8'h27 : RDATA <= 32'h10000347; // 0x009c
8'h28 : RDATA <= 32'h10000347; // 0x00a0
8'h29 : RDATA <= 32'h10000347; // 0x00a4
8'h2a : RDATA <= 32'h10000347; // 0x00a8
8'h2b : RDATA <= 32'h10000347; // 0x00ac
8'h2c : RDATA <= 32'h10000347; // 0x00b0
8'h2d : RDATA <= 32'h10000347; // 0x00b4
8'h2e : RDATA <= 32'h10000347; // 0x00b8
8'h2f : RDATA <= 32'h10000347; // 0x00bc
8'h30 : RDATA <= 32'hf802f000; // 0x00c0
8'h31 : RDATA <= 32'hf83ef000; // 0x00c4
8'h32 : RDATA <= 32'hc830a00c; // 0x00c8
8'h33 : RDATA <= 32'h18243808; // 0x00cc
8'h34 : RDATA <= 32'h46a2182d; // 0x00d0
8'h35 : RDATA <= 32'h46ab1e67; // 0x00d4
8'h36 : RDATA <= 32'h465d4654; // 0x00d8
8'h37 : RDATA <= 32'hd10142ac; // 0x00dc
8'h38 : RDATA <= 32'hf830f000; // 0x00e0
8'h39 : RDATA <= 32'h3e0f467e; // 0x00e4
8'h3a : RDATA <= 32'h46b6cc0f; // 0x00e8
8'h3b : RDATA <= 32'h42332601; // 0x00ec
8'h3c : RDATA <= 32'h1afbd000; // 0x00f0
8'h3d : RDATA <= 32'h46ab46a2; // 0x00f4
8'h3e : RDATA <= 32'h47184333; // 0x00f8
8'h3f : RDATA <= 32'h000002dc; // 0x00fc
8'h40 : RDATA <= 32'h000002fc; // 0x0100
8'h41 : RDATA <= 32'hd3023a10; // 0x0104
8'h42 : RDATA <= 32'hc178c878; // 0x0108
8'h43 : RDATA <= 32'h0752d8fa; // 0x010c
8'h44 : RDATA <= 32'hc830d301; // 0x0110
8'h45 : RDATA <= 32'hd501c130; // 0x0114
8'h46 : RDATA <= 32'h600c6804; // 0x0118
8'h47 : RDATA <= 32'h00004770; // 0x011c
8'h48 : RDATA <= 32'h24002300; // 0x0120
8'h49 : RDATA <= 32'h26002500; // 0x0124
8'h4a : RDATA <= 32'hd3013a10; // 0x0128
8'h4b : RDATA <= 32'hd8fbc178; // 0x012c
8'h4c : RDATA <= 32'hd3000752; // 0x0130
8'h4d : RDATA <= 32'hd500c130; // 0x0134
8'h4e : RDATA <= 32'h4770600b; // 0x0138
8'h4f : RDATA <= 32'hbd1fb51f; // 0x013c
8'h50 : RDATA <= 32'hbd10b510; // 0x0140
8'h51 : RDATA <= 32'hf915f000; // 0x0144
8'h52 : RDATA <= 32'hf7ff4611; // 0x0148
8'h53 : RDATA <= 32'hf000fff7; // 0x014c
8'h54 : RDATA <= 32'hf000f868; // 0x0150
8'h55 : RDATA <= 32'hb403f92d; // 0x0154
8'h56 : RDATA <= 32'hfff2f7ff; // 0x0158
8'h57 : RDATA <= 32'hf000bc03; // 0x015c
8'h58 : RDATA <= 32'h0000f933; // 0x0160
8'h59 : RDATA <= 32'h68012000; // 0x0164
8'h5a : RDATA <= 32'h6841468d; // 0x0168
8'h5b : RDATA <= 32'h00004708; // 0x016c
8'h5c : RDATA <= 32'h48532141; // 0x0170
8'h5d : RDATA <= 32'h61010149; // 0x0174
8'h5e : RDATA <= 32'h60812101; // 0x0178
8'h5f : RDATA <= 32'h60814851; // 0x017c
8'h60 : RDATA <= 32'h20204951; // 0x0180
8'h61 : RDATA <= 32'h47706188; // 0x0184
8'h62 : RDATA <= 32'h684a494e; // 0x0188
8'h63 : RDATA <= 32'hd1fc07d2; // 0x018c
8'h64 : RDATA <= 32'h07d2684a; // 0x0190
8'h65 : RDATA <= 32'h6008d100; // 0x0194
8'h66 : RDATA <= 32'h494a4770; // 0x0198
8'h67 : RDATA <= 32'h2b007803; // 0x019c
8'h68 : RDATA <= 32'h684ad009; // 0x01a0
8'h69 : RDATA <= 32'hd1fc07d2; // 0x01a4
8'h6a : RDATA <= 32'h07d2684a; // 0x01a8
8'h6b : RDATA <= 32'h600bd100; // 0x01ac
8'h6c : RDATA <= 32'h2b001c40; // 0x01b0
8'h6d : RDATA <= 32'h4770d1f2; // 0x01b4
8'h6e : RDATA <= 32'h4c44b510; // 0x01b8
8'h6f : RDATA <= 32'h48416821; // 0x01bc
8'h70 : RDATA <= 32'hd00a2900; // 0x01c0
8'h71 : RDATA <= 32'h781aa342; // 0x01c4
8'h72 : RDATA <= 32'hd0212a00; // 0x01c8
8'h73 : RDATA <= 32'h07c96841; // 0x01cc
8'h74 : RDATA <= 32'h6841d1fc; // 0x01d0
8'h75 : RDATA <= 32'hd01707c9; // 0x01d4
8'h76 : RDATA <= 32'ha341e017; // 0x01d8
8'h77 : RDATA <= 32'h2a00781a; // 0x01dc
8'h78 : RDATA <= 32'h6841d009; // 0x01e0
8'h79 : RDATA <= 32'hd1fc07c9; // 0x01e4
8'h7a : RDATA <= 32'h07c96841; // 0x01e8
8'h7b : RDATA <= 32'h6002d100; // 0x01ec
8'h7c : RDATA <= 32'h2a001c5b; // 0x01f0
8'h7d : RDATA <= 32'h2204d1f2; // 0x01f4
8'h7e : RDATA <= 32'h07c96841; // 0x01f8
8'h7f : RDATA <= 32'h6841d1fc; // 0x01fc
8'h80 : RDATA <= 32'hd10007c9; // 0x0200
8'h81 : RDATA <= 32'he7fe6002; // 0x0204
8'h82 : RDATA <= 32'h1c5b6002; // 0x0208
8'h83 : RDATA <= 32'hd1da2a00; // 0x020c
8'h84 : RDATA <= 32'h60202000; // 0x0210
8'h85 : RDATA <= 32'h8f4ff3bf; // 0x0214
8'h86 : RDATA <= 32'h8f6ff3bf; // 0x0218
8'h87 : RDATA <= 32'hffa2f7ff; // 0x021c
8'h88 : RDATA <= 32'hb510bd10; // 0x0220
8'h89 : RDATA <= 32'h48262141; // 0x0224
8'h8a : RDATA <= 32'h61010149; // 0x0228
8'h8b : RDATA <= 32'h60812101; // 0x022c
8'h8c : RDATA <= 32'h60814824; // 0x0230
8'h8d : RDATA <= 32'h21204a24; // 0x0234
8'h8e : RDATA <= 32'ha32f6191; // 0x0238
8'h8f : RDATA <= 32'h2a00781a; // 0x023c
8'h90 : RDATA <= 32'h6841d009; // 0x0240
8'h91 : RDATA <= 32'hd1fc07c9; // 0x0244
8'h92 : RDATA <= 32'h07c96841; // 0x0248
8'h93 : RDATA <= 32'h6002d100; // 0x024c
8'h94 : RDATA <= 32'h2a001c5b; // 0x0250
8'h95 : RDATA <= 32'h4c1dd1f2; // 0x0254
8'h96 : RDATA <= 32'h29006821; // 0x0258
8'h97 : RDATA <= 32'ha31cd00a; // 0x025c
8'h98 : RDATA <= 32'h2a00781a; // 0x0260
8'h99 : RDATA <= 32'h6841d021; // 0x0264
8'h9a : RDATA <= 32'hd1fc07c9; // 0x0268
8'h9b : RDATA <= 32'h07c96841; // 0x026c
8'h9c : RDATA <= 32'he017d017; // 0x0270
8'h9d : RDATA <= 32'h781aa31a; // 0x0274
8'h9e : RDATA <= 32'hd0092a00; // 0x0278
8'h9f : RDATA <= 32'h07c96841; // 0x027c
8'ha0 : RDATA <= 32'h6841d1fc; // 0x0280
8'ha1 : RDATA <= 32'hd10007c9; // 0x0284
8'ha2 : RDATA <= 32'h1c5b6002; // 0x0288
8'ha3 : RDATA <= 32'hd1f22a00; // 0x028c
8'ha4 : RDATA <= 32'h68412204; // 0x0290
8'ha5 : RDATA <= 32'hd1fc07c9; // 0x0294
8'ha6 : RDATA <= 32'h07c96841; // 0x0298
8'ha7 : RDATA <= 32'h6002d100; // 0x029c
8'ha8 : RDATA <= 32'h6002e7fe; // 0x02a0
8'ha9 : RDATA <= 32'h2a001c5b; // 0x02a4
8'haa : RDATA <= 32'h2000d1da; // 0x02a8
8'hab : RDATA <= 32'hf3bf6020; // 0x02ac
8'hac : RDATA <= 32'hf3bf8f4f; // 0x02b0
8'had : RDATA <= 32'hf7ff8f6f; // 0x02b4
8'hae : RDATA <= 32'h2000ff55; // 0x02b8
8'haf : RDATA <= 32'h0000bd10; // 0x02bc
8'hb0 : RDATA <= 32'h40006000; // 0x02c0
8'hb1 : RDATA <= 32'h4000e000; // 0x02c4
8'hb2 : RDATA <= 32'h40011000; // 0x02c8
8'hb3 : RDATA <= 32'h4001f000; // 0x02cc
8'hb4 : RDATA <= 32'h52202a2a; // 0x02d0
8'hb5 : RDATA <= 32'h70616d65; // 0x02d4
8'hb6 : RDATA <= 32'h41523e2d; // 0x02d8
8'hb7 : RDATA <= 32'h000a324d; // 0x02dc
8'hb8 : RDATA <= 32'h72724540; // 0x02e0
8'hb9 : RDATA <= 32'h203a726f; // 0x02e4
8'hba : RDATA <= 32'h414d4552; // 0x02e8
8'hbb : RDATA <= 32'h6c632050; // 0x02ec
8'hbc : RDATA <= 32'h65726165; // 0x02f0
8'hbd : RDATA <= 32'h00000a64; // 0x02f4
8'hbe : RDATA <= 32'h530a0a0a; // 0x02f8
8'hbf : RDATA <= 32'h414c434f; // 0x02fc
8'hc0 : RDATA <= 32'h203a5342; // 0x0300
8'hc1 : RDATA <= 32'h204d5241; // 0x0304
8'hc2 : RDATA <= 32'h74726f43; // 0x0308
8'hc3 : RDATA <= 32'h4d2d7865; // 0x030c
8'hc4 : RDATA <= 32'h616e2030; // 0x0310
8'hc5 : RDATA <= 32'h6f736f6e; // 0x0314
8'hc6 : RDATA <= 32'h00000a63; // 0x0318
8'hc7 : RDATA <= 32'h48034904; // 0x031c
8'hc8 : RDATA <= 32'h47706008; // 0x0320
8'hc9 : RDATA <= 32'h48014902; // 0x0324
8'hca : RDATA <= 32'h47706008; // 0x0328
8'hcb : RDATA <= 32'h05f5e100; // 0x032c
8'hcc : RDATA <= 32'h30000000; // 0x0330
8'hcd : RDATA <= 32'h47804807; // 0x0334
8'hce : RDATA <= 32'h47004807; // 0x0338
8'hcf : RDATA <= 32'he7fee7fe; // 0x033c
8'hd0 : RDATA <= 32'he7fee7fe; // 0x0340
8'hd1 : RDATA <= 32'he7fee7fe; // 0x0344
8'hd2 : RDATA <= 32'h49054804; // 0x0348
8'hd3 : RDATA <= 32'h4b064a05; // 0x034c
8'hd4 : RDATA <= 32'h00004770; // 0x0350
8'hd5 : RDATA <= 32'h10000325; // 0x0354
8'hd6 : RDATA <= 32'h100000c1; // 0x0358
8'hd7 : RDATA <= 32'h30000068; // 0x035c
8'hd8 : RDATA <= 32'h30000368; // 0x0360
8'hd9 : RDATA <= 32'h30000168; // 0x0364
8'hda : RDATA <= 32'h30000168; // 0x0368
8'hdb : RDATA <= 32'h47704770; // 0x036c
8'hdc : RDATA <= 32'h46754770; // 0x0370
8'hdd : RDATA <= 32'hf824f000; // 0x0374
8'hde : RDATA <= 32'h000546ae; // 0x0378
8'hdf : RDATA <= 32'h46534669; // 0x037c
8'he0 : RDATA <= 32'h00c008c0; // 0x0380
8'he1 : RDATA <= 32'hb0184685; // 0x0384
8'he2 : RDATA <= 32'hf7ffb520; // 0x0388
8'he3 : RDATA <= 32'hbc60ffdd; // 0x038c
8'he4 : RDATA <= 32'h08492700; // 0x0390
8'he5 : RDATA <= 32'h260046b6; // 0x0394
8'he6 : RDATA <= 32'hc5c0c5c0; // 0x0398
8'he7 : RDATA <= 32'hc5c0c5c0; // 0x039c
8'he8 : RDATA <= 32'hc5c0c5c0; // 0x03a0
8'he9 : RDATA <= 32'hc5c0c5c0; // 0x03a4
8'hea : RDATA <= 32'h00493d40; // 0x03a8
8'heb : RDATA <= 32'h4770468d; // 0x03ac
8'hec : RDATA <= 32'h4604b510; // 0x03b0
8'hed : RDATA <= 32'h46c046c0; // 0x03b4
8'hee : RDATA <= 32'hf7ff4620; // 0x03b8
8'hef : RDATA <= 32'hbd10fecc; // 0x03bc
8'hf0 : RDATA <= 32'h47704800; // 0x03c0
8'hf1 : RDATA <= 32'h30000004; // 0x03c4
8'hf2 : RDATA <= 32'h20184901; // 0x03c8
8'hf3 : RDATA <= 32'he7febeab; // 0x03cc
8'hf4 : RDATA <= 32'h00020026; // 0x03d0
8'hf5 : RDATA <= 32'h00004770; // 0x03d4
8'hf6 : RDATA <= 32'h100003f8; // 0x03d8
8'hf7 : RDATA <= 32'h30000000; // 0x03dc
8'hf8 : RDATA <= 32'h00000004; // 0x03e0
8'hf9 : RDATA <= 32'h10000104; // 0x03e4
8'hfa : RDATA <= 32'h100003fc; // 0x03e8
8'hfb : RDATA <= 32'h30000004; // 0x03ec
8'hfc : RDATA <= 32'h00000364; // 0x03f0
8'hfd : RDATA <= 32'h10000120; // 0x03f4
8'hfe : RDATA <= 32'h05f5e100; // 0x03f8
8'hff : RDATA <= 32'h00000000; // 0x03fc
default : RDATA <=32'h0;
endcase
endmodule
//-----------------------------------------------------------------------------
// The confidential and proprietary information contained in this file may
// only be used by a person authorised under and to the extent permitted
// by a subsisting licensing agreement from Arm Limited or its affiliates.
//
// (C) COPYRIGHT 2001-2013 Arm Limited or its affiliates.
// ALL RIGHTS RESERVED
//
// This entire notice must be reproduced on all copies of this file
// and copies of this file may only be made by a person if such person is
// permitted to do so under the terms of a subsisting license agreement
// from Arm Limited or its affiliates.
//
// SVN Information
//
// Checked In : $Date: 2017-10-10 15:55:38 +0100 (Tue, 10 Oct 2017) $
//
// Revision : $Revision: 371321 $
//
// Release Information : Cortex-M System Design Kit-r1p1-00rel0
//
//-----------------------------------------------------------------------------
//
//------------------------------------------------------------------------------
// Abstract : AHB BusMatrix top level README file
//------------------------------------------------------------------------------
Introduction
------------
This directory contains the AHB BusMatrix component.
cmsdk_ahb_busmatrix/bin/BuildBusMatrix.pl
The AHB BusMatrix is a configurable component. The configuration
process is handled by a Perl script, located in bin/BuildBusMatrix.pl
cmsdk_ahb_busmatrix/verilog/src
The source code of the configurable AHB Bus matrix is located in
verilog/src directory. Do not use the Verilog files in this directory
directly.
cmsdk_ahb_busmatrix/verilog/built
After configuration process, the Verilog files generated will be stored
in verilog/built directory.
cmsdk_ahb_busmatrix/xml/
During the configuration process, the configuration of the AHB BusMatrix
can be controlled by command line options or by an XML file.
Example XML files can be found in the xml directory.
cmsdk_mtx4x2/verilog/
A preconfigured version of AHB Bus matrix for the example Cortex-M3/M4
system is prepared in the cmsdk_mcu_mtx4x2 directory. The configuration
of this bus matrix can be found in cmsdk_mcu_mtx4x2/xml/
Several example AHB Bus Matrix configuration XML files are provided.
You can generate the AHB bus matrix RTL by running the following command:
> cd logical/cmsdk_ahb_busmatrix
> bin/BuildBusMatrix.pl -xmldir xml -cfg example2x3_full.xml -over -verbose
Please refer to the Cortex-M System Design Kit Technical Reference Manual for
further details on the use of this component.
======================== End of README.txt ===========================
eval "exec perl -w -S $0 $@" # -*- Perl -*-
if ($running_under_some_sh);
undef ($running_under_some_sh);
################################################################################
# The confidential and proprietary information contained in this file may
# only be used by a person authorised under and to the extent permitted
# by a subsisting licensing agreement from Arm Limited or its affiliates.
#
# (C) COPYRIGHT 2001-2013,2017 Arm Limited or its affiliates.
# ALL RIGHTS RESERVED
#
# This entire notice must be reproduced on all copies of this file
# and copies of this file may only be made by a person if such person is
# permitted to do so under the terms of a subsisting license agreement
# from Arm Limited or its affiliates.
#
################################################################################
# Version and Release Control Information:
#
# File Name : $RCSfile: BuildBusMatrix.pl,v $
#
# SVN Information
#
# Checked In : $Date: 2017-10-10 15:55:38 +0100 (Tue, 10 Oct 2017) $
#
# Revision : $Revision: 371321 $
#
# Release Information : Cortex-M System Design Kit-r1p1-00rel0
#
################################################################################
################################################################################
# Purpose : Builds particular configurations of the AHB BusMatrix
#
################################################################################
# Usage:
# Builds an AHB Bus Matrix component with a given number of input ports,
# a given number of output ports, a particular arbitration scheme and ARM
# processor interface.
#
# Notes: This version of the script uses an interface information hash with
# the following structure:
#
# my %InterfaceInfo = (
# SLAVES => {
# SI<n> => {
# NAME => '@name',
# CONNECTIONS => [ @MI<n> ... ],
# ADDRESS_MAP => {
# NORMAL => [ <address_info> ... ],
# REMAP => [ <remap_info> ... ]
# }
# }
# },
#
# MASTERS => {
# MI<n> => {
# NAME => '@name',
# CONNECTIONS => [ @SI<n> ... ]
# }
# }
# );
#
# Options: See the ShowHelp() function.
#
################################################################################
# ------------------------------------------------------------------------------
# Load PERL libraries
# ------------------------------------------------------------------------------
use strict;
use warnings;
use Getopt::Long;
use lib 'bin/lib'; # Collapse namespace 'lib::'
use xmlparser; # Load the XML parser module
use Data::Dumper;
use Storable 'dclone';
use File::Spec;
# ------------------------------------------------------------------------------
# Declare global variables
# ------------------------------------------------------------------------------
# General script variables
my $Debug = 0;
my $RenderDebug = 0;
my $Errors = 0;
my $HdlType = 'verilog';
my $HdlExt = '.v';
my $Connections = '';
my $Sparse = 0;
my $DefaultSlave = 'cmsdk_ahb_bm_default_slave';
# Parameter legal ranges
my $MinSlaveIF = 1;
my $MaxSlaveIF = 16;
my $MinMasterIF = 1;
my $MaxMasterIF = 16;
my $DataWidths = '32|64';
my $MinNameLength = 1;
my $MaxNameLength = 128;
my $MinUserWidth = 0;
my $MaxUserWidth = 32;
my $MinAddrWidth = 32;
my $MaxAddrWidth = 64;
# Interface ID tags (updated later)
my $IdWidthMI = 4;
my $IdWidthSI = 4;
# Interface information hash
my %InterfaceInfo = ();
# A processed version needed for the differences in IPXact
my %InterfaceInfoIPXact = ();
# Remap state information hash
my %RemapStates = ();
# Address space information hash
my %AddressSpace = ();
# Get the run date and correct offset
my ( $Sec, $Min, $Hour, $Mday, $Mon, $Year ) = localtime(time); $Year+=1900; $Mon++;
# Filename variables
my %FileList = ();
my ($Scriptname) = $0 =~ /([\w\.]+)$/;
# Hash for search and replacement of macros
my %Macro = ();
# Hash for processing text sections
my %Section = ();
# Arrays of instance names
my @MatrixDecodeNames = ();
my @OutputArbNames = ();
my @OutputStageNames = ();
# Hash for remapping information
my %RemapInfo = ();
# Hash array of name aliases
my %NameAliases = ();
# IP-XACT component name - default value is set later
my $ComponentName = '';
# ------------------------------------------------------------------------------
# Check for pre-requisites
# ------------------------------------------------------------------------------
# Check for the supported OS platform(s)
unless ( $^O =~ /(solaris|linux)\b/ ) {
die "Error: This script does not support the '$^0' OS!\n\n";
}
# Check for the required version of PERL
unless ( $] >= 5.005 ) {
die "Error: This script requires PERL version >= 5.005!\n\n";
}
# Check system clock for inappropriate roll-back - the date is used
# in the copyright field of file headers
unless ( $Year >= 2013 ) {
warn "Warning: The system clock is incorrectly set to '$Year'!\n";
$Year = 2013;
}
# ------------------------------------------------------------------------------
# Parse the command line
# ------------------------------------------------------------------------------
# Default values for command-line options
my $SlaveInterfaces = 1;
my $MasterInterfaces = 1;
my $Connectivity = 'full';
my $ArbiterType = 'fixed';
my $ArchitectureType = 'ahb2';
my $XmlConfigFile = '';
my $RoutingDataWidth = 32;
my $RoutingAddressWidth = 32;
my $UserSignalWidth = 0;
my $OutputArbName = 'cmsdk_ahb_bm_output_arb';
my $OutputStageName = 'cmsdk_ahb_bm_output_stage';
my $MatrixDecodeName = 'cmsdk_ahb_bm_decode';
my $InputStageName = 'cmsdk_ahb_bm_input_stage';
my $BusMatrixName = ''; # Default value is set later
my $Help = 0;
my $Verbose = 0;
my $SourceDir = "./$HdlType/src";
my $TargetDir = "./$HdlType/built";
my $IPXactSourceDir = "./ipxact/src";
my $IPXactTargetDir = "./ipxact/built";
my $XmlDir = './xml';
my $Overwrite = 0;
my $Timescales = 0;
my $NoTimescales = 0;
my $XmlTimescales = 0;
my $CheckMode = 0;
my $IPXact = 0;
# Display usage message if requested
if ( grep(/^-?-help$/, @ARGV) ) { ShowHelp(); }
# Get command line arguments
GetOptions( 'inports=i' => \$SlaveInterfaces,
'outports=i' => \$MasterInterfaces,
'connectivity=s' => \$Connectivity,
'arb=s' => \$ArbiterType,
'arch=s' => \$ArchitectureType,
'cfg=s' => \$XmlConfigFile,
'datawidth=i' => \$RoutingDataWidth,
'addrwidth=i' => \$RoutingAddressWidth,
'userwidth=i' => \$UserSignalWidth,
'outputarb=s' => \$OutputArbName,
'outputstage=s' => \$OutputStageName,
'matrixdecode=s' => \$MatrixDecodeName,
'inputstage=s' => \$InputStageName,
'busmatrix=s' => \$BusMatrixName,
'verbose' => \$Verbose,
'srcdir=s' => \$SourceDir,
'tgtdir=s' => \$TargetDir,
'ipxactsrcdir=s' => \$IPXactSourceDir,
'ipxacttgtdir=s' => \$IPXactTargetDir,
'xmldir=s' => \$XmlDir,
'overwrite' => \$Overwrite,
'timescales' => \$Timescales, 'notimescales' => \$NoTimescales,
'check' => \$CheckMode,
'ipxact' => \$IPXact,
'debug' => \$Debug,
'renderdebug' => \$RenderDebug,
);
if ( $Timescales and $NoTimescales ) {
die "Error: Can't use --timescales and --notimescales at the same time\n";
}
# Display script header when in verbose mode
if ( $Verbose ) {
printf "\n==============================================================\n" .
"= The confidential and proprietary information contained in this file may\n" .
"= only be used by a person authorised under and to the extent permitted\n" .
"= by a subsisting licensing agreement from Arm Limited or its affiliates.\n" .
"= \n" .
"= (C) COPYRIGHT 2001-2013,2017 Arm Limited or its affiliates.\n" .
"= ALL RIGHTS RESERVED\n" .
"= \n" .
"= This entire notice must be reproduced on all copies of this file\n" .
"= and copies of this file may only be made by a person if such person is\n" .
"= permitted to do so under the terms of a subsisting license agreement\n" .
"= from Arm Limited or its affiliates.\n" .
"=\n" .
"= $Scriptname\n" .
"=\n" .
"= Run Date : %02d/%02d/%04d %02d:%02d:%02d" .
"\n==============================================================\n\n",
$Mday, $Mon, $Year, $Hour, $Min, $Sec;
}
# ------------------------------------------------------------------------------
# Parse the configuration file if specified, or initialise by elaborating
# the '-connectivity' command-line argument and calculating an address map
# ------------------------------------------------------------------------------
if ( $XmlConfigFile ne '' ) {
# Conditionally prepend the XML directory path to the filename
if ( $XmlConfigFile !~ /^$XmlDir/ ) { $XmlConfigFile = "$XmlDir/$XmlConfigFile"; }
$XmlConfigFile = TidyPath($XmlConfigFile);
# Configure and run the XML parser
ProcessXmlConfigFile();
} else {
# Translate into internal form, the design specified on the command line
InitialiseInterfaceInfo();
}
# Do some preprocessing for IPXact generation
if ($IPXact) {
ProcessDataForIPXact();
}
# Set the default top-level name if required
if ( $BusMatrixName eq '' ) {
$BusMatrixName = sprintf( "cmsdk_ahb_busmatrix%dx%d%s%dd%da%du", $SlaveInterfaces,
$MasterInterfaces, substr($ArbiterType, 0, 1),
$RoutingDataWidth, $RoutingAddressWidth, $UserSignalWidth );
}
# Set the default IP-XACT component name if required
if ( $ComponentName eq '' ) { $ComponentName = $BusMatrixName . "_lite"; }
# ------------------------------------------------------------------------------
# Validate the parameters and abort if necessary
# ------------------------------------------------------------------------------
ValidateParameters();
if ( $Errors ) { die "\nBuild not started because of parameter errors!\n\n"; }
# ------------------------------------------------------------------------------
# Determine calculated parameters
# ------------------------------------------------------------------------------
SelectParameters();
# ------------------------------------------------------------------------------
# Display settings when in verbose mode
# ------------------------------------------------------------------------------
my $XmlTimescales_interpreted = ($XmlTimescales eq 'yes' || $XmlTimescales eq 'no') ? $XmlTimescales
: "no ($XmlTimescales)";
if ( $Verbose ) {
printf "Script accepted the following parameters:\n\n" .
"%s - Top-level name : '$BusMatrixName'\n" .
" - Slave interfaces : $SlaveInterfaces\n" .
" - Master interfaces : $MasterInterfaces\n" .
" - Architecture type : '$ArchitectureType'\n" .
" - Arbitration scheme : '$ArbiterType'\n" .
" - Address map : %s\n" .
" - Connectivity mapping : %s\n" .
" - Connectivity type : %s\n" .
" - Routing data width : $RoutingDataWidth\n" .
" - Routing address width : $RoutingAddressWidth\n" .
" - User signal width : $UserSignalWidth\n" .
" - Timescales : ". ($Timescales ? "yes" :
$NoTimescales ? "no" :
'') .
( $XmlTimescales ? $Timescales || $NoTimescales ? " - overriding $XmlTimescales_interpreted setting from XML"
: "$XmlTimescales_interpreted (from XML)"
: '' ) .
( ! ($XmlTimescales || $Timescales || $NoTimescales) ? 'yes (default)' : '') . "\n" .
" - Configuration directory : '$TargetDir'\n" .
" - Source directory : '$SourceDir'\n" .
($IPXact ?
" - IPXact target directory : '$IPXactTargetDir'\n" .
" - IPXact source directory : '$IPXactSourceDir'\n" : "") .
" - Overwrite mode : %s\n\n",
( $XmlConfigFile ne '' ) ? " - Configuration file : '$XmlConfigFile'\n" : '',
( $XmlConfigFile ne '' ) ? 'user defined' : 'calculated',
( $Connectivity ne 'full' ) ? $Connections : 'automatic',
( $Sparse ) ? 'sparse' : 'full',
( $Overwrite ) ? 'enabled' : 'disabled';
}
# ------------------------------------------------------------------------------
# Expand template macros if not in check mode
# ------------------------------------------------------------------------------
unless ( $CheckMode ) { CreateBusMatrix(); }
################################################################################
### Subroutines and Functions ##################################################
################################################################################
# ------------------------------------------------------------------------------
# SelectParameters - Selects the corresponding parameter set according to
# the fundamental specification
# ------------------------------------------------------------------------------
sub SelectParameters {
# Local variable(s)
my $Instance = '';
my $Index = 0;
my $Interface = '';
my %Arbiter = ( fixed => 'cmsdk_ahb_bm_fixed_arb', round => 'cmsdk_ahb_bm_round_arb', burst => 'cmsdk_ahb_bm_burst_arb' );
my $ArbType = '';
my $OutType = '';
my $BstrbWidth = $RoutingDataWidth / 8;
my $MakefileName = 'makefile';
my $MkfileName = 'cmsdk_ahb_busmatrix.mk';
my $IPXactFile_AHB2 = 'cmsdk_ahb_busmatrix_ipxact.xml';
my $IPXactFile_AHBLite = 'cmsdk_ahb_busmatrix_lite_ipxact.xml';
my $Mappings = $Connections;
my $Packing = ' ' x 14;
my $Unmapping = '';
my $RemapBit = 0;
my $OpenBr = '';
my $CloseBr = '';
my @RemapBits = ();
# Determine the connectivity type
$Sparse = IsSparse();
# Determine the slave interface ID width
$IdWidthSI = NumberOfDigits($SlaveInterfaces - 1, 2);
# Determine the master interface ID width, including an MSbit for
# selecting the default slave
$IdWidthMI = NumberOfDigits($MasterInterfaces - 1, 2) + 1;
# Format the mappings
$Mappings =~ s/\n/\n\/\//g;
# Determine single entity filenames
#$FileList{$MkfileName} = $MkfileName; # Note:Generation of ADK makefile is not required in BP210
#$FileList{$MakefileName} = $MakefileName; # Note:Generation of ADK makefile is not required in BP210
if ( $IPXact ) { $FileList{$ComponentName . '.xml'} = $IPXactFile_AHBLite; # Component already contains the -lite suffix or other name
$FileList{$BusMatrixName . '.xml'} = $IPXactFile_AHB2; }
$DefaultSlave = $BusMatrixName . '_default_slave';
$FileList{$BusMatrixName . $HdlExt} = 'cmsdk_ahb_busmatrix' . $HdlExt;
$FileList{$ComponentName . $HdlExt} = 'cmsdk_ahb_busmatrix_lite' . $HdlExt;
$FileList{$InputStageName . $HdlExt} = 'cmsdk_ahb_bm_input_stage' . $HdlExt;
$FileList{$DefaultSlave . $HdlExt} = 'cmsdk_ahb_bm_default_slave' . $HdlExt;
# Generate filenames and macro names for each instance of bm_decode
# and process any REMAP declarations accordingly
$Section{'remap_used'} = '0';
$Section{'no_remap_used'} = '1';
for ( $Index = 0; $Index < $SlaveInterfaces; $Index++ ) {
$Interface = 'SI' . $Index;
$Instance = $MatrixDecodeName . $InterfaceInfo{SLAVES}{$Interface}{NAME};
$FileList{$Instance . $HdlExt} = 'cmsdk_ahb_bm_decode' . $HdlExt;
push @MatrixDecodeNames, $Instance;
$RemapInfo{$Interface}{REMAP_BITS} = [];
$RemapInfo{$Interface}{REMAP_WIDTH} = 0;
$RemapInfo{$Interface}{REMAP_MAPPING} = {};
@RemapBits = ();
for ( $RemapBit = 0; $RemapBit < 4; $RemapBit++ ) {
if ( ( grep /:remap$RemapBit:/,
@{ $InterfaceInfo{SLAVES}{$Interface}{ADDRESS_MAP}{REMAP} } ) ||
( grep /:.*(del|_|,|\s)$RemapBit(_|,|\s|:|$)/,
@{ $InterfaceInfoIPXact{SLAVES}{$Interface}{ADDRESS_MAP}{NORMAL} } ) ) {
push @RemapBits, "REMAP[$RemapBit]";
push @{ $RemapInfo{$Interface}{REMAP_BITS} }, $RemapBit;
$RemapInfo{$Interface}{REMAP_MAPPING}{$RemapBit} = $RemapInfo{$Interface}{REMAP_WIDTH};
$RemapInfo{$Interface}{REMAP_WIDTH}++;
$Section{'remap_used'} = '1';
$Section{'no_remap_used'} = '0';
}
}
$OpenBr = ( $RemapInfo{$Interface}{REMAP_WIDTH} > 1 ) ? '{ ' : '';
$CloseBr = ( $RemapInfo{$Interface}{REMAP_WIDTH} > 1 ) ? ' }' : '';
$RemapInfo{$Interface}{REMAP_PORT} = $OpenBr . join( ', ', reverse @RemapBits ) . $CloseBr;
}
print "RemapInfo:\n" if $Debug;
print Dumper(\%RemapInfo) if $Debug;
# Determine names for the output_arb and output_stage instances
if ( $Sparse ) {
# Generate filenames and macro names for each instance of output_stage and
# output_arb modules
for ( $Index = 0; $Index < $MasterInterfaces; $Index++ ) {
$Interface = 'MI' . $Index;
# If the current output stage has only one connection, then override
# the template selection for the arbiter type and output stage
$ArbType = $Arbiter{$ArbiterType}; $OutType = 'cmsdk_ahb_bm_output_stage';
unless ( @{ $InterfaceInfo{MASTERS}{$Interface}{CONNECTIONS} } > 1 ) {
$ArbType = 'cmsdk_ahb_bm_single_arb'; $OutType = 'cmsdk_ahb_bm_single_output_stage';
}
$Instance = $OutputArbName . $InterfaceInfo{MASTERS}{$Interface}{NAME};
$FileList{$Instance . $HdlExt} = $ArbType . $HdlExt;
push @OutputArbNames, $Instance;
$Instance = $OutputStageName . $InterfaceInfo{MASTERS}{$Interface}{NAME};
$FileList{$Instance . $HdlExt} = $OutType . $HdlExt;
push @OutputStageNames, $Instance;
}
} else {
# The same output_stage and output_arb modules are used in a fully connected
# bus matrix
$FileList{$OutputArbName . $HdlExt} = $Arbiter{$ArbiterType} . ${HdlExt};
push @OutputArbNames, $OutputArbName;
$FileList{$OutputStageName . $HdlExt} = 'cmsdk_ahb_bm_output_stage' . ${HdlExt};
push @OutputStageNames, $OutputStageName;
# Initialise particular static instance names
$Macro{'output_arb_name'} = $OutputArbName;
$Macro{'output_stage_name'} = $OutputStageName;
$Macro{'output_stage_name_lc'} = lc($Macro{'output_stage_name'});
}
# Conditionally initialise the macro and section control hashes
# Determine architecture options
if ( $ArchitectureType =~ /^(v6|excl)$/ ){
$Section{'excl'} = 1;
$Macro{'prot'} = 5;
$Macro{'prot_v'} = 6;
$Macro{'resp'} = 2;
$Macro{'resp_v'} = 3;
$Macro{'bin_resp_xfail'} = '100';
} else {
$Section{'excl'} = 0;
$Macro{'prot'} = 3;
$Macro{'prot_v'} = 4;
$Macro{'resp'} = 1;
$Macro{'resp_v'} = 2;
$Macro{'bin_resp_xfail'} = 'xx';
}
# Determine response encoding
$Macro{'bin_resp_okay'} = substr( '000', -$Macro{'resp_v'}, $Macro{'resp_v'} );
$Macro{'bin_resp_error'} = substr( '001', -$Macro{'resp_v'}, $Macro{'resp_v'} );
$Macro{'bin_resp_retry'} = substr( '010', -$Macro{'resp_v'}, $Macro{'resp_v'} );
$Macro{'bin_resp_split'} = substr( '011', -$Macro{'resp_v'}, $Macro{'resp_v'} );
# Determine HUNALIGN support and xUSER width
$Section{'unalign'} = ( $ArchitectureType =~ /^(v6|unalign)$/ ) ? 1 : 0;
$Section{'user'} = ( $UserSignalWidth > 0 ) ? 1 : 0;
# Bus width fields
$Macro{'data'} = $RoutingDataWidth - 1;
$Macro{'data_v'} = $RoutingDataWidth;
$Macro{'addr'} = $RoutingAddressWidth - 1;
$Macro{'addr_v'} = $RoutingAddressWidth;
$Macro{'user'} = $UserSignalWidth - 1;
$Macro{'user_v'} = $UserSignalWidth;
$Macro{'bstrb'} = $BstrbWidth - 1;
$Macro{'bstrb_v'} = $BstrbWidth;
$Macro{'address_space_range'} = $RoutingAddressWidth >= 40 ? (2**($RoutingAddressWidth-40) )."T" :
$RoutingAddressWidth >= 30 ? (2**($RoutingAddressWidth-30) )."G" :
$RoutingAddressWidth >= 20 ? (2**($RoutingAddressWidth-20) )."M" :
$RoutingAddressWidth >= 10 ? (2**($RoutingAddressWidth-10) )."K" :
2**$RoutingAddressWidth ; # P and E not supported by IP-XACT standard
$Macro{'verilog_to_ipxact_path'} = File::Spec->abs2rel("$TargetDir/$BusMatrixName","$IPXactTargetDir/$BusMatrixName");
# Interface ID-width fields
$Macro{'idw_si'} = $IdWidthSI - 1;
$Macro{'idw_si_v'} = $IdWidthSI;
$Macro{'idw_mi'} = $IdWidthMI - 1;
$Macro{'idw_mi_v'} = $IdWidthMI;
# Determine default slave selection encoding (can be up to 5 bits)
$Macro{'dsid_bin'} = substr('10000', 0, $IdWidthMI);
# Determine a list of sub-module names
$Macro{'other_module_names'} = $DefaultSlave . " \\\n$Packing" .
$InputStageName . " \\\n$Packing" .
join( " \\\n$Packing", @MatrixDecodeNames ) .
" \\\n$Packing" .
join( " \\\n$Packing", @OutputArbNames ) .
" \\\n$Packing" .
join( " \\\n$Packing", @OutputStageNames );
# Initialise the static instance names
$Macro{'bus_matrix_name'} = $BusMatrixName;
$Macro{'input_stage_name'} = $InputStageName;
$Macro{'output_arb_stemname'} = $OutputArbName;
$Macro{'output_stage_stemname'} = $OutputStageName;
$Macro{'matrix_decode_stemname'} = $MatrixDecodeName;
$Macro{'component_name'} = $ComponentName;
# Miscellaneous fields
$Macro{'copyright_year'} = $Year;
$Macro{'timescale_directive'} = ( $NoTimescales || ( ($XmlTimescales eq 'no') && !$Timescales )) ? '' : "\n`timescale 1ns/1ps\n"; # On by default on CMSDK
$Macro{'arbiter_type'} = $ArbiterType;
$Macro{'architecture_type'} = $ArchitectureType;
$Macro{'total_si'} = $SlaveInterfaces;
$Macro{'total_mi'} = $MasterInterfaces;
$Macro{'connectivity'} = ( $Sparse ) ? 'sparse' : 'full';
$Macro{'mappings'} = ( $Sparse ) ? $Mappings :
sprintf("S<0..%d> -> M<0..%d>", $SlaveInterfaces - 1, $MasterInterfaces - 1);
}
# ------------------------------------------------------------------------------
# CreateBusMatrix - Creates a version of the Bus Matrix using the currently
# selected parameter set
# ------------------------------------------------------------------------------
sub CreateBusMatrix {
# Local variable(s)
my $VariantDir = "$TargetDir/$BusMatrixName";
my $IPXactVariantDir = "$IPXactTargetDir/$BusMatrixName";
my @ExistingFiles = glob( "$VariantDir/*" );
my @NewFiles = keys( %FileList );
my $File = '';
# Determine target preparation
if ( -e $VariantDir ) {
# Delete files when in overwrite mode, otherwise display an error
if ( $Overwrite ) {
foreach $File ( @ExistingFiles ) {
print "Deleting the '$File' file...\n" if ( $Verbose );
unlink $File or die "Error: Could not delete the file!\n\n";
}
print "\n" if ( @ExistingFiles and $Verbose );
} else {
die "Error: This variant of the bus matrix already exists!\n\n";
}
} else {
# Create the output directory for this Bus Matrix variant
mkdir $VariantDir or
die "Error: Could not create the output directory '$VariantDir'!\n\n";
}
if ($IPXact) {
@ExistingFiles = glob( "$IPXactVariantDir/*" );
# Determine ipxact target preparation
if ( -e $IPXactVariantDir ) {
# Delete files when in overwrite mode, otherwise display an error
if ( $Overwrite ) {
foreach $File ( @ExistingFiles ) {
print "Deleting the '$File' file...\n" if ( $Verbose );
unlink $File or die "Error: Could not delete the file!\n\n";
}
print "\n" if ( @ExistingFiles and $Verbose );
} else {
die "Error: IPXact directory for this variant of the bus matrix already exists!\n\n";
}
} else {
# Create the output directory for this Bus Matrix variant
mkdir $IPXactVariantDir or
die "Error: Could not create the output directory '$IPXactVariantDir'!\n\n";
}
}
# Process all required files
print "Creating the bus matrix variant...\n\n" if ( $Verbose );
foreach $File ( @NewFiles ) {
print " - Rendering '$File'\n" if ( $Verbose );
if ($FileList{$File} =~ /.*ipxact\.xml$/) {
RenderFile( "$IPXactSourceDir/$FileList{$File}", "$IPXactVariantDir/$File" );
} else{
RenderFile( "$SourceDir/$FileList{$File}", "$VariantDir/$File" );
}
}
print "\nDone!\n\n" if ( $Verbose );
}
# ------------------------------------------------------------------------------
# RenderFile - Processes nested sections embedded hierarchically within the
# specified template file, and expands macros accordingly. The
# variables '$SlaveIF' and '$MasterIF' have a reserved use
# depending upon the template being rendered. The variables may
# be assigned values from 'in' or 'out' sections, or assigned
# to a value extracted from a port-specific target filename. In
# all other cases, these variables just retain their values
# ------------------------------------------------------------------------------
sub RenderFile {
# Passed parameter 1 is the template filename
my $TemplateFile = shift;
# Passed parameter 2 is the rendered output filename
my $RenderedFile = shift;
# Local variable(s)
my $TextLine = '';
my $Field = '';
my $Type = '';
my $Level = 0;
my $LineNum = 0;
my $StartName = '';
my $EndName = '';
my @Section = ( { LINE => 0, PTR => 0, NAME => '', COPIES => 0, COUNT => 0, EN => 1 } );
my ($SourceFile) = $TemplateFile =~ /([\w\.]+)$/;
my $RefId = 0;
my $Interface = '';
my $SlaveIF = '';
my $MasterIF = '';
my @MIRegions = ();
my @FoundRegions = ();
my $Decodings = 0;
my $Region = 0;
my $AddrLo = '';
my $AddrHi = '';
my $Remapping = '';
my $Unmapping = '';
my $RemapBit = 0;
my $Bit = 0;
my $RemapState = 0;
my @ActiveRemap = ();
my $GotFirst = 0;
my $Arbiters = 'cmsdk_ahb_bm_burst_arb|cmsdk_ahb_bm_fixed_arb|cmsdk_ahb_bm_round_arb|cmsdk_ahb_bm_single_arb';
my @PortIds = ();
my $TotalIds = 0;
my @IPXactFiles = ( $ComponentName, $BusMatrixName, $DefaultSlave, $InputStageName,
@MatrixDecodeNames, @OutputArbNames, @OutputStageNames );
my %RemapTypes = ( none => 'Static', alias => 'Alias', move => 'Unmoved' );
my $Debug = $RenderDebug;
my @i_remapstate = ();
# Open the template file for reading
open( IN, "<$TemplateFile")
or die "Cannot open input file '$TemplateFile'!\n\n";
# Open the output file for writing the rendered text
open( OUT, ">$RenderedFile" )
or die "Cannot open output file '$RenderedFile'!\n\n";
# For the bm_decode template only, initialise specific macros and variables
if ( $TemplateFile =~ /cmsdk_ahb_bm_decode$HdlExt$/ ) {
# Set the current instance name for search and replacement, and also extract
# the slave interface number for reference use
if ( ($SlaveIF) = $RenderedFile =~ /$MatrixDecodeName(\w+)$HdlExt$/ ) {
$Macro{'matrix_decode_name'} = $MatrixDecodeName . $SlaveIF;
$Macro{'matrix_decode_name_lc'} = lc($Macro{'matrix_decode_name'});
$SlaveIF = $NameAliases{$SlaveIF} if ( $XmlConfigFile ne '' );
}
# Initialise macros for search and replace, then determine if the map or
# remap section is to be processed
$Section{'remap'} = 0;
$Macro{'idw_remap'} = '';
$Macro{'idw_remap_v'} = '';
$Macro{'bin_remapstate'} = '';
$Macro{'remapping_vector'} = '';
$Macro{'region_type'} = '';
if ( $RemapInfo{$SlaveIF}{REMAP_WIDTH} > 0 ) {
$Section{'remap'} = 1;
$Macro{'idw_remap'} = $RemapInfo{$SlaveIF}{REMAP_WIDTH} - 1;
$Macro{'address_map'} = '';
$Macro{'mdelse'} = '';
$Macro{'mem_lo'} = '';
$Macro{'mem_hi'} = '';
$Macro{'remapping_vector'} = $RemapInfo{$SlaveIF}{REMAP_PORT};
}
$Section{'map'} = ( $Section{'remap'} ) ? 0 : 1;
}
$Macro{'remap_name'} = '';
$Macro{'top_remap_bit'} = '';
$Macro{'top_remap_bitvalue'} = '';
# For a sparse bus matrix only, and concerning the output_arb or output_stage
# only, set the current instance names for search and replacement. Also
# extract the master interface number for reference use
if ( $Sparse ) {
if ( $TemplateFile =~ /($Arbiters)$HdlExt$/ ) {
if ( ($MasterIF) = $RenderedFile =~ /$OutputArbName(\w+)$HdlExt$/ ) {
$Macro{'output_arb_name'} = $OutputArbName . $MasterIF;
$MasterIF = $NameAliases{$MasterIF} if ( $XmlConfigFile ne '' );
}
} elsif ( $TemplateFile =~ /cmsdk_ahb_bm(_single)?_output_stage$HdlExt$/ ) {
if ( ($MasterIF) = $RenderedFile =~ /$OutputStageName(\w+)$HdlExt$/ ) {
$Macro{'output_stage_name'} = $OutputStageName . $MasterIF;
$Macro{'output_stage_name_lc'} = lc($Macro{'output_stage_name'});
$MasterIF = $NameAliases{$MasterIF} if ( $XmlConfigFile ne '' );
$MasterIF =~ /([0-9]+)$/;
$Macro{'output_arb_name'} = $OutputArbNames[$1];
}
}
}
# Convert default slave name
$Macro{'default_slave_name'} = $DefaultSlave;
# Process each line of the template file
while ( $TextLine = <IN> ) {
# Increment the source file line number
$LineNum++;
# Display each line of the template when in debug mode
print "$LineNum:" . $TextLine if ( $Debug );
# Expand any macro found in the line
unless ( $TextLine !~ /<<[^<>]+>>/ ) {
# Search for all replaceable macros within the line
while ( ($Field, $Type) = $TextLine =~ /(<<(\w+)>>)/gc ) {
if ( exists $Macro{$Type} ) {
$TextLine =~ s/$Field/$Macro{$Type}/;
# Display replacement token name when in debug mode
print "Replaced '$Field' on line $LineNum of '$SourceFile' with '$Macro{$Type}'...\n" if ( $Debug );
} else {
warn "Warning: Unidentified field '$Field' on line $LineNum of '$SourceFile'...\n";
}
}
# Extract sections and store the current file pointer position
if ( ($StartName) = $TextLine =~ /<<\s+start\s+(.+)\s+>>/ ) {
# Store the information onto the section stack
$Section[++$Level] = {
LINE => $LineNum,
PTR => tell(IN),
NAME => $StartName,
COPIES => 0,
COUNT => 0,
EN => 1
};
# Display section start name when in debug mode
print "Found start section $Level '$StartName'\n" if ( $Debug );
# Exclude child sections if the parent section was excluded, otherwise
# conditionally process specificaly named sections of the template
if ( $Section[$Level - 1]{EN} == 0 ) {
$Section[$Level]{EN} = 0;
} elsif ( $StartName eq 'unalign' ) { # Optional section
$Section[$Level]{EN} = ( $Section{'unalign'} ) ? -1 : 0;
} elsif ( $StartName eq 'excl' ) { # Optional section
$Section[$Level]{EN} = ( $Section{'excl'} ) ? -1 : 0;
} elsif ( $StartName eq 'user' ) { # Optional section
$Section[$Level]{EN} = ( $Section{'user'} ) ? -1 : 0;
} elsif ( $StartName eq 'map' ) { # Optional section
$Section[$Level]{EN} = ( $Section{'map'} ) ? -1 : 0;
} elsif ( $StartName eq 'remap' ) { # Optional section
$Section[$Level]{EN} = ( $Section{'remap'} ) ? -1 : 0;
} elsif ( $StartName eq 'vendor_extension' ) { # Optional section
# This is a dummy section to reset NoMoreIPXactInSections
$Section[$Level]{EN} = 0;
} elsif ( $StartName eq 'topfile' ) {
if ($TemplateFile =~ /.*lite_ipxact\.xml$/) { # Lite has the component/wrapper as top, the other has the AHB2 main top
$Section[$Level]{EN} = ( $Macro{'filename'} eq $ComponentName ) ? -1 : 0;
} else {
$Section[$Level]{EN} = ( $Macro{'filename'} eq $BusMatrixName ) ? -1 : 0;
}
} elsif ( $StartName eq 'connection' ) { # Optional section
# Determine template specific settings
if ( ($TemplateFile =~ /(cmsdk_ahb_busmatrix|$Arbiters|cmsdk_ahb_bm(_single)?_output_stage)$HdlExt$/) or
($TemplateFile =~ /.*ipxact\.xml$/) ){
$SlaveIF = 'SI' . $Macro{'in'};
}
$Interface = ( $TemplateFile =~ /($Arbiters|cmsdk_ahb_bm(_single)?_output_stage)$HdlExt$/ ) ?
$MasterIF : 'MI' . $Macro{'out'};
# For sparse bus matrix only, check for at least one connection
$Section[$Level]{EN} = ( grep /^$Interface$/,
@{ $InterfaceInfo{SLAVES}{$SlaveIF}{CONNECTIONS} } or !$Sparse ) ? -1 : 0;
# Indicate the first connection for the round_arb template
if ( $TemplateFile =~ /cmsdk_ahb_bm_round_arb$HdlExt$/ and $Section[$Level]{EN} ) {
$GotFirst = 1;
}
} elsif ( $StartName eq 'in' ) { # Common macro
# Set the number of times this section will be repeated
$Section[$Level]{COPIES} = $SlaveInterfaces - 1;
$Section[$Level]{EN} = -1;
# Set the current slave interface number and macros
$Macro{'in'} = $Section[$Level]{COUNT};
$Interface = 'SI' . $Section[$Level]{COUNT};
$Macro{'si_name'} = $InterfaceInfo{SLAVES}{$Interface}{NAME};
$SlaveIF = $Interface;
# Determine template specific settings
if ( $TemplateFile =~ /($Arbiters|cmsdk_ahb_bm(_single)?_output_stage)$HdlExt$/ ) {
$Macro{'bin_in'} = ToBinary($Section[$Level]{COUNT}, $IdWidthSI);
$Macro{'rrelse'} = ''; # Used in round_arb only
$GotFirst = 0;
} elsif ( $TemplateFile =~ /cmsdk_ahb_busmatrix$HdlExt$/ ) {
# Determine if the remap section should be processed
$Section{'remap'} = 0;
$Macro{'remapping_vector'} = '';
if ( $RemapInfo{$Interface}{REMAP_WIDTH} > 0 ) {
$Section{'remap'} = 1;
$Macro{'remapping_vector'} = $RemapInfo{$Interface}{REMAP_PORT};
}
$Macro{'matrix_decode_name'} = $MatrixDecodeNames[$Section[$Level]{COUNT}];
$Macro{'matrix_decode_name_lc'} = lc($Macro{'matrix_decode_name'});
}
} elsif ( $StartName eq 'out' ) { # Common macro
# Set the number of times this section will be repeated
$Section[$Level]{COPIES} = $MasterInterfaces - 1;
$Section[$Level]{EN} = -1;
# Set the current master interface number and macros
$Macro{'out'} = $Section[$Level]{COUNT};
$Interface = 'MI' . $Section[$Level]{COUNT};
$Macro{'mi_name'} = $InterfaceInfo{MASTERS}{$Interface}{NAME};
$Macro{'mi_name_lc'} = lc($Macro{'mi_name'});
# Determine template specific settings
if ( $TemplateFile =~ /cmsdk_ahb_bm_decode$HdlExt$/ ) {
$Macro{'bin_out'} = ToBinary($Section[$Level]{COUNT}, $IdWidthMI - 1);
} elsif ( $TemplateFile =~ /cmsdk_ahb_busmatrix$HdlExt$/ and $Sparse ) {
$Macro{'output_stage_name'} = $OutputStageNames[$Section[$Level]{COUNT}];
$Macro{'output_stage_name_lc'} = lc($Macro{'output_stage_name'});
}
} elsif ( $StartName eq 'rrin' ) { # Used in round_arb and output_stage
# Determine the port ID enumeration and the total number
if ( $Sparse ) {
@PortIds = @{ $InterfaceInfo{MASTERS}{$MasterIF}{CONNECTIONS} };
@PortIds = grep s/^SI//, @PortIds; # Remove all 'SI' prefixes
} else {
@PortIds = ( 0..$SlaveInterfaces-1 );
}
$TotalIds = scalar @PortIds;
# Set the number of times this section will be repeated, and determine
# the slave interface ID macros for the round_arb template
$Section[$Level]{COPIES} = $TotalIds - 1;
$Section[$Level]{EN} = -1;
$Macro{'rrin'} = $PortIds[$Section[$Level]{COUNT}];
$Macro{'bin_rrin'} = ToBinary($PortIds[$Section[$Level]{COUNT}], $IdWidthSI);
} elsif ( $StartName eq 'rridx' ) { # Used in round_arb only
# Set the number of times this section will be repeated, and determine
# the slave interface ID macros for the round_arb template
$Section[$Level]{COPIES} = $TotalIds - 2;
$Section[$Level]{EN} = -1;
$Macro{'rrelse'} = '';
$RefId = ($Section[$Level - 1]{COUNT} + 1) % $TotalIds;
$Macro{'rridx'} = $PortIds[$RefId];
$Macro{'bin_rridx'} = ToBinary($PortIds[$RefId], $IdWidthSI);
} elsif ( $StartName eq 'addr_map' ) { # Used in bm_decode only
# For the current remapping state and master interface, determine which
# address regions are visible
@MIRegions = grep /^$Interface:/,
@{ $InterfaceInfo{SLAVES}{$SlaveIF}{ADDRESS_MAP}{NORMAL} };
if ( $RemapState > 0 ) { # Only when remapping is asserted non-zero
# Translate the active remapping bits into a regexp filter
@ActiveRemap = ();
for ($Bit = 0; $Bit < $RemapInfo{$SlaveIF}{REMAP_WIDTH}; $Bit++) {
if ( ($RemapState >> $Bit) & 0x01 ) {
push @ActiveRemap, @{ $RemapInfo{$SlaveIF}{REMAP_BITS} }[$Bit];
}
}
$RemapBit = join( '|', @ActiveRemap );
# Determine if there are activated remap regions, and if so, delete
# normal but movable address map regions
if ( grep /^$Interface:remap($RemapBit):/,
@{ $InterfaceInfo{SLAVES}{$SlaveIF}{ADDRESS_MAP}{REMAP} } ) {
@MIRegions = grep !/^.*:move:/,
@MIRegions;
}
}
$Region = 0;
# Initialise macros in preparation for search and replace
$Macro{'mdelse'} = '';
$Macro{'address_map'} = '';
$Macro{'mem_lo'} = '';
$Macro{'mem_hi'} = '';
# Include this section if a mapping exists
$Section[$Level]{EN} = ( @MIRegions > 0 ) ? -1 : 0;
} elsif ( $StartName eq 'addr_map_ipxact' ) {
# All normal (non-remap) regions
@MIRegions = @{ $InterfaceInfoIPXact{SLAVES}{$SlaveIF}{ADDRESS_MAP}{NORMAL} };
# Initialise macros in preparation for search and replace
$Macro{'address_map'} = '';
$Macro{'mem_lo'} = '';
$Macro{'mem_hi'} = '';
# Include this section if a mapping exists
$Section[$Level]{EN} = ( @MIRegions > 0 ) ? -1 : 0;
} elsif ( $StartName eq 'segments' ) {
$Section[$Level]{COPIES} = scalar @{$AddressSpace{$Interface}} - 1;
$Section[$Level]{EN} = -1;
$Macro{'segment_name'} = '0x'.$AddressSpace{$Interface}[$Section[$Level]{COUNT}][0]."_".'0x'.$AddressSpace{$Interface}[$Section[$Level]{COUNT}][1];
$Macro{'segment_offset'} = '0x'.$AddressSpace{$Interface}[$Section[$Level]{COUNT}][0];
$Macro{'segment_range'} = '0x' . HexAdd( '0'. HexSubstract($AddressSpace{$Interface}[$Section[$Level]{COUNT}][1],
$AddressSpace{$Interface}[$Section[$Level]{COUNT}][0]) , 1 );
} elsif ( $StartName eq 'addr_remap_and_normal_all_this_remap' ) {
@MIRegions = ();
# All remap regions
my @allRegions = @{ $InterfaceInfoIPXact{SLAVES}{$SlaveIF}{ADDRESS_MAP}{REMAP} };
push (@allRegions, @{ $InterfaceInfoIPXact{SLAVES}{$SlaveIF}{ADDRESS_MAP}{NORMAL} });
foreach my $address_region ( @allRegions ) {
($MasterIF, $Remapping, $AddrLo, $AddrHi, $Unmapping) = split(/:/,$address_region);
# get canonical name for remap state
my @bits = GetRemapBits ($Remapping, $Unmapping);
my $i_remap_name = join( '_' , @bits );
# Change ! to n
$i_remap_name =~ s/!/n/g ;
if ($Macro{'remap_name'} eq "remap_".$i_remap_name) {
push (@MIRegions,$address_region);
}
}
# Initialise macros in preparation for search and replace
$Macro{'address_map'} = '';
$Macro{'mem_lo'} = '';
$Macro{'mem_hi'} = '';
# Include this section if a mapping exists
$Section[$Level]{EN} = ( @MIRegions > 0 ) ? -1 : 0;
} elsif ( $StartName =~ /^(addr|remap)_region$/ ) { # Used bm_decode and Spirit file only
# Do not add an else if it is the first address/remap region
$Macro{'mdelse'} = ( $Decodings > 0 ) ? 'else ' : '';
# Conditionally reference the first address/remap region and extract its info
if ( @MIRegions > 0 ) {
# Set the number of copies
$Section[$Level]{COPIES} = scalar @MIRegions - 1;
($MasterIF, $Remapping, $AddrLo, $AddrHi) = split(/:/, $MIRegions[$Region]);
$Macro{'address_block_name'} = 'Default';
$Macro{'address_block_remap'} = ($Remapping eq "move") ? 'TRUE' : 'FALSE';
$Macro{'base_address'} = "0x$AddrLo";
$Macro{'address_range'} = '0x' . HexSubstract($AddrHi, $AddrLo);
$Macro{'address_map'} = "0x$AddrLo-0x$AddrHi";
$Macro{'mem_lo'} = ToDecodeAddr($AddrLo);
$Macro{'mem_hi'} = ToDecodeAddr($AddrHi);
# Determine template specific settings
if ( $TemplateFile =~ /cmsdk_ahb_bm_decode$HdlExt$/ ) {
$Macro{'remapping_bit'} = '';
if ( $StartName eq 'remap_region' ) {
$Macro{'remapping_bit'} = substr($Remapping, 5, 1);
$Macro{'out'} = substr($MasterIF, 2);
$Macro{'bin_out'} = ToBinary( substr($MasterIF, 2), $IdWidthMI - 1);
} else {
$Macro{'region_type'} = $RemapTypes{$Remapping};
}
}
$Decodings++;
}
$Section[$Level]{EN} = -1;
} elsif ( $StartName =~ /^(addr|remap)_region_ipxact$/ ) { # Used bm_decode and IPXACT file only
# Conditionally reference the first address/remap region and extract its info
if ( @MIRegions > 0 ) {
# Set the number of copies
$Section[$Level]{COPIES} = scalar @MIRegions - 1;
$Section[$Level]{EN} = -1;
($MasterIF, $Remapping, $AddrLo, $AddrHi, $Unmapping) = split(/:/, $MIRegions[$Section[$Level]{COUNT}]);
$Macro{'address_block_name'} = 'Default';
$Macro{'address_block_remap'} = ($Remapping eq "move") ? 'TRUE' : 'FALSE';
$Macro{'base_address'} = "0x$AddrLo";
$Macro{'end_address'} = "0x$AddrHi";
$Macro{'address_range'} = '0x' . HexSubstract($AddrHi, HexSubstract($AddrLo,1));
$Macro{'address_map'} = "0x$AddrLo-0x$AddrHi";
$Macro{'mem_lo'} = ToDecodeAddr($AddrLo);
$Macro{'mem_hi'} = ToDecodeAddr($AddrHi);
$Macro{'out'} = substr($MasterIF, 2);
$Macro{'bin_out'} = ToBinary( substr($MasterIF, 2), $IdWidthMI - 1);
$Macro{'mi_name'} = $InterfaceInfo{MASTERS}{$MasterIF}{NAME};
$Macro{'mi_name_lc'} = lc($Macro{'mi_name'});
my @bits = GetRemapBits ($Remapping, $Unmapping);
my $remap_name = join( '_' , @bits );
# Change ! to n
$remap_name =~ s/!/n/g ;
$Macro{'remap_name'} = "remap_".$remap_name;
my $bit;
$Macro{'active_cond'} = '';
foreach $bit (@bits) {
if (substr($bit,0,1) eq '!') {
$Macro{'active_cond'} .= "\n" . ' 'x25 . ' & !remapping_dec['.$RemapInfo{$SlaveIF}{REMAP_MAPPING}{substr($bit,1)} .']';
} else {
$Macro{'active_cond'} .= "\n" . ' 'x25 . ' & remapping_dec['.$RemapInfo{$SlaveIF}{REMAP_MAPPING}{$bit} .']';
}
}
$Macro{'remapping_bit'} = $remap_name;
$Section{'remap_static'} = @bits ? 0 : 1;
$Section{'remap_conditional'} = @bits ? 1 : 0;
if (@bits) {
if ( substr($Remapping,0,5) eq 'remap' ) {
$Macro{'region_type'} = "Remapped region, active when REMAP bitcombination is " . $remap_name;
$Macro{'region_type_sanitized'} = "Remapped_" . $remap_name;
} else {
$Macro{'region_type'} = "Removable region, active only when REMAP bitcombination is " . $remap_name;
$Macro{'region_type_sanitized'} = "Removable_" . $remap_name;
}
} else {
$Macro{'region_type'} = "Static";
$Macro{'region_type_sanitized'} = $Macro{'region_type'};
}
}
} elsif ( $StartName eq 'ipxact_remap_region' ) { # Used in IPXact file only
# Get the remap regions for the current master interface
@MIRegions = grep /^$MasterIF:/,
@{ $InterfaceInfo{SLAVES}{$SlaveIF}{ADDRESS_MAP}{REMAP} };
if ( @MIRegions > 0 ) {
$Section[$Level]{COPIES} = scalar @MIRegions - 1;
($MasterIF, $Remapping, $AddrLo, $AddrHi) = split(/:/, $MIRegions[$Region]);
$Remapping =~ /([0-9])$/; $Remapping = $1;
$Macro{'address_block_name'} = 'Remap-Pin' . $Remapping;
$Macro{'base_address'} = "0x$AddrLo";
$Macro{'address_range'} = '0x' . HexSubstract($AddrHi, $AddrLo);
$Macro{'mem_lo'} = ToDecodeAddr($AddrLo);
$Macro{'mem_hi'} = ToDecodeAddr($AddrHi);
}
$Section[$Level]{EN} = ( $Macro{'base_address'} eq '' ) ? 0 : -1;
} elsif ( $StartName eq 'remap_state' ) { # Used in bm_decode only
# Initialise macros in preparation for search and replace
$Macro{'address_map'} = '';
$Macro{'mem_lo'} = '';
$Macro{'mem_hi'} = '';
$Macro{'remapping_bit'} = '';
$Macro{'idw_remap_v'} = $RemapInfo{$SlaveIF}{REMAP_WIDTH};
$Macro{'bin_remapstate'} = ToBinary(0, $RemapInfo{$SlaveIF}{REMAP_WIDTH});
# Initialise variables used in remap processing and calculate the required
# number of section copies
$RemapState = 0;
$Decodings = 0;
$Section[$Level]{COPIES} = (2 ** $RemapInfo{$SlaveIF}{REMAP_WIDTH}) - 1;
$Section[$Level]{EN} = -1;
} elsif ( $StartName eq 'remap_state_ipxact' ) { # Used in ipxact only
@i_remapstate = keys( %RemapStates );
#$Macro{'remapping_bit'} = '';
#$Macro{'idw_remap_v'} = $RemapInfo{$SlaveIF}{REMAP_WIDTH};
# Initialise variables used in remap processing and calculate the required
# number of section copies
$Section[$Level]{COPIES} = scalar @i_remapstate -1;
$Section[$Level]{EN} = ($Section{'remap_used'} > 0) ? -1 : 0;
$RemapState = $Section[$Level]{COUNT};
$Macro{'remap_name'} = $i_remapstate[$RemapState];
print "Processing remap state: $Macro{'remap_name'}\n" if ( $Debug );
} elsif ( $StartName eq 'remap_bit' ) { # Used in bm_decode only
# Set the number of copies
$Section[$Level]{COPIES} = $RemapInfo{$SlaveIF}{REMAP_WIDTH} - 1;
$Section[$Level]{EN} = -1;
$Bit = 0;
} elsif ( $StartName eq 'remap_bit_ipxact' ) { # Used in bm_decode only
# Set the number of copies
$Section[$Level]{COPIES} = scalar @{$RemapStates{$i_remapstate[$RemapState]}} -1;
$Section[$Level]{EN} = -1;
$Bit = 0;
my $r_bit = @{$RemapStates{$i_remapstate[$RemapState]}}[$Section[$Level]{COUNT}];
if (substr($r_bit,0,1) eq '!') {
$Macro{'top_remap_bit'} = substr($r_bit,1);
$Macro{'top_remap_bitvalue'} = 0;
} else {
$Macro{'top_remap_bit'} = $r_bit;
$Macro{'top_remap_bitvalue'} = 1;
}
} elsif ( $StartName eq 'addr_remap' ) { # Used in bm_decode only
# For the current remapping state, determine which remap regions are
# active per master interface
@MIRegions = ();
$Region = 0;
if ( ($RemapState >> $Bit) & 0x01 ) {
$RemapBit = @{ $RemapInfo{$SlaveIF}{REMAP_BITS} }[$Bit];
@MIRegions = grep /:remap$RemapBit:/,
@{ $InterfaceInfo{SLAVES}{$SlaveIF}{ADDRESS_MAP}{REMAP} };
}
# Initialise macros in preparation for search and replace
$Macro{'mdelse'} = '';
$Macro{'address_map'} = '';
$Macro{'mem_lo'} = '';
$Macro{'mem_hi'} = '';
# Include this section if a mapping exists
$Section[$Level]{EN} = ( @MIRegions > 0 ) ? -1 : 0;
} elsif ( $StartName eq 'file' ) { # Used in ipxact file only
$Macro{'filename'} = $IPXactFiles[0];
$Section[$Level]{COPIES} = scalar @IPXactFiles - 1;
$Section[$Level]{EN} = -1;
if ($TemplateFile =~ /.*lite_ipxact\.xml$/) {# Remove the wrapper from non-lite
#
} else {
# Don't include the lite wrapper in the AHB2 ipxact
if ( $Macro{'filename'} eq $ComponentName ) {
$Macro{'filename'} = $IPXactFiles[1];
++$Section[$Level]{COUNT};
}
}
} elsif ( exists $Section{$StartName} ) { # Optional section
$Section[$Level]{EN} = ( $Section{$StartName} ) ? -1 : 0;
}
# Display the number of section copies when in debug mode
print "Section copies: $Section[$Level]{COPIES}\n" if ( $Debug );
} elsif ( ($EndName) = $TextLine =~ /<<\s+end\s+(.+)\s+>>/ ) {
# Display section end name when in debug mode
print "Found end section $Level '$EndName'\n" if ( $Debug );
# Check for matching section markers
unless ( $EndName eq $Section[$Level]{NAME} ) {
die "Error: Unexpected section end on line $LineNum of '$SourceFile'...\n\n";
}
# Determine if the section is to be repeated
if ( $Section[$Level]{COUNT} < $Section[$Level]{COPIES} ) {
# Adjust input file pointer and line number
seek( IN, $Section[$Level]{PTR}, 0 );
$LineNum = $Section[$Level]{LINE};
# Update macro settings as necessary
if ( $EndName eq 'in' ) {
$Macro{'in'} = ++$Section[$Level]{COUNT};
$Interface = 'SI' . $Section[$Level]{COUNT};
$Macro{'si_name'} = $InterfaceInfo{SLAVES}{$Interface}{NAME};
$SlaveIF = $Interface;
# Determine template specific settings
if ( $TemplateFile =~ /($Arbiters|cmsdk_ahb_bm(_single)?_output_stage)$HdlExt$/ ) {
$Macro{'bin_in'} = ToBinary($Section[$Level]{COUNT}, $IdWidthSI);
if ( $GotFirst ) { $Macro{'rrelse'} = 'else '; }
} elsif ( $TemplateFile =~ /cmsdk_ahb_busmatrix$HdlExt$/ ) {
# Determine if the remap section should be processed
$Section{'remap'} = 0;
$Macro{'remapping_vector'} = '';
if ( $RemapInfo{$Interface}{REMAP_WIDTH} > 0 ) {
$Section{'remap'} = 1;
$Macro{'remapping_vector'} = $RemapInfo{$Interface}{REMAP_PORT};
}
$Macro{'matrix_decode_name'} = $MatrixDecodeNames[$Section[$Level]{COUNT}];
$Macro{'matrix_decode_name_lc'} = lc($Macro{'matrix_decode_name'});
}
} elsif ( $EndName eq 'out' ) {
$Macro{'out'} = ++$Section[$Level]{COUNT};
$Interface = 'MI' . $Section[$Level]{COUNT};
$Macro{'mi_name'} = $InterfaceInfo{MASTERS}{$Interface}{NAME};
$Macro{'mi_name_lc'} = lc($Macro{'mi_name'});
# Determine template specific settings
if ( $TemplateFile =~ /cmsdk_ahb_bm_decode$HdlExt$/ ) {
$Macro{'bin_out'} = ToBinary($Section[$Level]{COUNT}, $IdWidthMI - 1);
} elsif ( $TemplateFile =~ /cmsdk_ahb_busmatrix$HdlExt$/ and $Sparse ) {
$Macro{'output_stage_name'} = $OutputStageNames[$Section[$Level]{COUNT}];
$Macro{'output_stage_name_lc'} = lc($Macro{'output_stage_name'});
}
} elsif ( $EndName eq 'rrin' ) {
$Macro{'rrin'} = $PortIds[ ++$Section[$Level]{COUNT} ];
$Macro{'bin_rrin'} = ToBinary($PortIds[$Section[$Level]{COUNT}], $IdWidthSI);
} elsif ( $EndName eq 'rridx' ) {
$Section[$Level]{COUNT}++;
$Macro{'rrelse'} = 'else ';
# Determine next round robin port
$RefId = ++$RefId % $TotalIds;
$Macro{'rridx'} = $PortIds[$RefId];
$Macro{'bin_rridx'} = ToBinary($PortIds[$RefId], $IdWidthSI);
} elsif ( $EndName eq 'remap_state' ) {
$Macro{'bin_remapstate'} = ToBinary(++$Section[$Level]{COUNT},
$RemapInfo{$SlaveIF}{REMAP_WIDTH});
$Decodings = 0;
$RemapState++;
} elsif ( $EndName eq 'remap_state_ipxact' ) {
$Section[$Level]{COUNT}++;
$RemapState = $Section[$Level]{COUNT};
$Macro{'remap_name'} = $i_remapstate[$RemapState];
print "Processing remap state: $Macro{'remap_name'}\n" if ( $Debug );
} elsif ( $EndName eq 'remap_bit' ) {
$Section[$Level]{COUNT}++;
$Bit++;
} elsif ( $EndName eq 'remap_bit_ipxact' ) {
$Bit++;
$Section[$Level]{COUNT}++;
my $r_bit = @{$RemapStates{$i_remapstate[$RemapState]}}[$Section[$Level]{COUNT}];
if (substr($r_bit,0,1) eq '!') {
$Macro{'top_remap_bit'} = substr($r_bit,1);
$Macro{'top_remap_bitvalue'} = 0;
} else {
$Macro{'top_remap_bit'} = $r_bit;
$Macro{'top_remap_bitvalue'} = 1;
}
} elsif ( $EndName eq 'segments' ) {
$Section[$Level]{COUNT}++;
$Macro{'segment_name'} = '0x'.$AddressSpace{$Interface}[$Section[$Level]{COUNT}][0]."_".'0x'.$AddressSpace{$Interface}[$Section[$Level]{COUNT}][1];
$Macro{'segment_offset'} = '0x'.$AddressSpace{$Interface}[$Section[$Level]{COUNT}][0];
$Macro{'segment_range'} = '0x' . HexAdd( '0'. HexSubstract($AddressSpace{$Interface}[$Section[$Level]{COUNT}][1],
$AddressSpace{$Interface}[$Section[$Level]{COUNT}][0]) , 1 );
} elsif ( $EndName eq 'addr_remap_and_normal_all_this_remap' ) {
# Empty
} elsif ( $EndName =~ /^(addr|remap)_region$/ ) {
$Section[$Level]{COUNT}++;
# Conditionally reference the subsequent address/remap region
if ( @MIRegions > 0 ) {
$Macro{'mdelse'} = ( $Decodings > 0 ) ? 'else ' : '';
($MasterIF, $Remapping, $AddrLo, $AddrHi) = split(/:/, $MIRegions[++$Region]);
$Macro{'address_block_name'} = 'Default';
$Macro{'address_block_remap'} = ($Remapping eq "move") ? 'TRUE' : 'FALSE';
$Macro{'base_address'} = "0x$AddrLo";
$Macro{'address_range'} = '0x' . HexSubstract($AddrHi, $AddrLo);
$Macro{'address_map'} = "0x$AddrLo-0x$AddrHi";
$Macro{'mem_lo'} = ToDecodeAddr($AddrLo);
$Macro{'mem_hi'} = ToDecodeAddr($AddrHi);
# Determine template specific settings
if ( $TemplateFile =~ /cmsdk_ahb_bm_decode$HdlExt$/ ) {
$Macro{'remapping_bit'} = '';
if ( $EndName eq 'remap_region' ) {
$Macro{'remapping_bit'} = substr($Remapping, 5, 1);
$Macro{'out'} = substr($MasterIF, 2);
$Macro{'bin_out'} = ToBinary( substr($MasterIF, 2), $IdWidthMI - 1);
} else {
$Macro{'region_type'} = $RemapTypes{$Remapping};
}
}
$Decodings++;
}
} elsif ( $EndName =~ /^(addr|remap)_region_ipxact$/ ) { # Used bm_decode and IPXACT file only
$Section[$Level]{COUNT}++;
# Conditionally reference the first address/remap region and extract its info
if ( @MIRegions > 0 ) {
($MasterIF, $Remapping, $AddrLo, $AddrHi, $Unmapping) = split(/:/, $MIRegions[$Section[$Level]{COUNT}]);
$Macro{'address_block_name'} = 'Default';
$Macro{'address_block_remap'} = ($Remapping eq "move") ? 'TRUE' : 'FALSE';
$Macro{'base_address'} = "0x$AddrLo";
$Macro{'end_address'} = "0x$AddrHi";
$Macro{'address_range'} = '0x' . HexSubstract($AddrHi, HexSubstract($AddrLo,1));
$Macro{'address_map'} = "0x$AddrLo-0x$AddrHi";
$Macro{'mem_lo'} = ToDecodeAddr($AddrLo);
$Macro{'mem_hi'} = ToDecodeAddr($AddrHi);
$Macro{'out'} = substr($MasterIF, 2);
$Macro{'bin_out'} = ToBinary( substr($MasterIF, 2), $IdWidthMI - 1);
$Macro{'mi_name'} = $InterfaceInfo{MASTERS}{$MasterIF}{NAME};
$Macro{'mi_name_lc'} = lc($Macro{'mi_name'});
$Section{'remapped'} = ($Remapping =~ /^(move|remap).*/) ? 1 : 0;
$Section{'not_remapped'} = !$Section{'remapped'};
my @bits = GetRemapBits ($Remapping, $Unmapping);
my $remap_name = join( '_' , @bits );
# Change ! to n
$remap_name =~ s/!/n/g ;
$Macro{'remap_name'} = "remap_".$remap_name;
my $bit;
$Macro{'active_cond'} = '';
foreach $bit (@bits) {
if (substr($bit,0,1) eq '!') {
$Macro{'active_cond'} .= "\n" . ' 'x25 . ' & !remapping_dec['.$RemapInfo{$SlaveIF}{REMAP_MAPPING}{substr($bit,1)} .']';
} else {
$Macro{'active_cond'} .= "\n" . ' 'x25 . ' & remapping_dec['.$RemapInfo{$SlaveIF}{REMAP_MAPPING}{$bit} .']';
}
}
$Macro{'remapping_bit'} = $remap_name;
$Section{'remap_static'} = @bits ? 0 : 1;
$Section{'remap_conditional'} = @bits ? 1 : 0;
if (@bits) {
if ( substr($Remapping,0,5) eq 'remap' ) {
$Macro{'region_type'} = "Remapped region, active when REMAP bitcombination is " . $remap_name;
$Macro{'region_type_sanitized'} = "Remapped_" . $remap_name;
} else {
$Macro{'region_type'} = "Removable region, active only when REMAP bitcombination is " . $remap_name;
$Macro{'region_type_sanitized'} = "Removable_" . $remap_name;
}
} else {
$Macro{'region_type'} = "Static";
$Macro{'region_type_sanitized'} = $Macro{'region_type'};
}
}
} elsif ( $EndName eq 'ipxact_remap_region' ) {
$Section[$Level]{COUNT}++;
if ( @MIRegions > 0 ) {
($MasterIF, $Remapping, $AddrLo, $AddrHi) = split(/:/, $MIRegions[++$Region]);
$Remapping =~ /([0-9])$/; $Remapping = $1;
$Macro{'address_block_name'} = 'Remap-Pin' . $Remapping;
$Macro{'base_address'} = "0x$AddrLo";
$Macro{'address_range'} = '0x' . HexSubstract($AddrHi, $AddrLo);
$Macro{'mem_lo'} = ToDecodeAddr($AddrLo);
$Macro{'mem_hi'} = ToDecodeAddr($AddrHi);
}
} elsif ( $EndName eq 'file' ) { # Used in ipxact file only
if ($TemplateFile =~ /.*lite_ipxact\.xml$/) { # Remove the wrapper from non-lite
#
} else {
if ( $Macro{'filename'} eq $ComponentName ) {
++$Section[$Level]{COUNT};
}
}
$Macro{'filename'} = $IPXactFiles[++$Section[$Level]{COUNT}];
}
# Display pointer adjustment when in debug mode
printf ("Reversing back to line %d...\n", $LineNum + 1) if ( $Debug );
} elsif ( $Level > 0 ) {
$Level--;
}
# Do not include this line in the output
unless ($Section[$Level]{EN} == 0) { $Section[$Level]{EN} = -1; }
}
}
# Write the line(s) to the rendered output file when (delay) enabled
if ( $Section[$Level]{EN} ) {
print OUT $TextLine if ( $Section[$Level]{EN} > 0 );
$Section[$Level]{EN} = 1;
}
}
# Close the template file and rendered output file
close(IN);
close(OUT);
# If still inside a nested section, there were too few end macros
unless ( $Level == 0 ) {
die "Error: Section '$Section[$Level]{NAME}' expected in '$SourceFile'!\n\n";
}
}
# ------------------------------------------------------------------------------
# IsSparse - Determines the connectivity completeness
# ------------------------------------------------------------------------------
sub IsSparse {
# Local variable(s)
my $SlaveIF = '';
my @SlaveIFs = keys( %{ $InterfaceInfo{SLAVES} } );
my @MasterIFs = keys( %{ $InterfaceInfo{MASTERS} } );
my $Mappings = '';
my $Result = 0;
# Check each mapping
foreach $SlaveIF ( @SlaveIFs ) {
$Mappings = join( '|', @{ $InterfaceInfo{SLAVES}{$SlaveIF}{CONNECTIONS} } );
if ( grep $_ !~ /^($Mappings)$/, @MasterIFs ) { $Result = 1; last; }
}
return ($Result);
}
# ------------------------------------------------------------------------------
# HexSubstract - Does argument1 - argument2 substraction in hex.
# Assumes argument1 >= argument2
# ------------------------------------------------------------------------------
sub HexSubstract {
# Passed parameter 1 is the LHS hexadecimal operand value
my $Value1 = shift;
# Passed parameter 2 is the RHS hexadecimal operand value
my $Value2 = shift;
# Local variable(s)
my $Len1 = length($Value1);
my $Len2 = length($Value2);
my $Index = 0;
my $Char1 = '';
my $Char2 = '';
my $Borrow = 0;
my $Result = '';
# Append zeros to the 2nd operand
if ( $Len1 > $Len2 ) { $Value2 = '0' x ($Len1 - $Len2) . $Value2; }
# Substract using strings instead of conversion to decimal to support 64 bit numbers
for ( $Index = 1; $Index <= $Len1; $Index++ ) {
$Char1 = hex substr($Value1, $Len1 - $Index, 1);
$Char2 = hex substr($Value2, $Len1 - $Index, 1);
if ( $Char1 < ($Char2 + $Borrow) ) {
$Char1 = $Char1 + 16;
$Result = sprintf("%1x", $Char1 - $Char2 - $Borrow) . $Result;
$Borrow = 1;
} else {
$Result = sprintf("%1x", $Char1 - $Char2 - $Borrow) . $Result;
$Borrow = 0;
}
}
return ($Result);
}
# ------------------------------------------------------------------------------
# HexAdd - Does argument1 + argument2 substraction in hex.
# ------------------------------------------------------------------------------
sub HexAdd {
# Passed parameter 1 is the LHS hexadecimal operand value
my $Value1 = shift;
# Passed parameter 2 is the RHS hexadecimal operand value
my $Value2 = shift;
# Local variable(s)
my $Len1 = length($Value1);
my $Len2 = length($Value2);
my $Index = 0;
my $Char1 = '';
my $Char2 = '';
my $Carry = 0;
my $Result = '';
# Append zeros to the 2nd operand
if ( $Len1 > $Len2 ) { $Value2 = '0' x ($Len1 - $Len2) . $Value2; }
# Substract using strings instead of conversion to decimal to support 64 bit numbers
for ( $Index = 1; $Index <= $Len1; $Index++ ) {
$Char1 = hex substr($Value1, $Len1 - $Index, 1);
$Char2 = hex substr($Value2, $Len1 - $Index, 1);
if ( $Char1 +$Char2 + $Carry > 15) {
$Result = sprintf("%1x", $Char1 + $Char2 + $Carry - 16) . $Result;
$Carry = 1;
} else {
$Result = sprintf("%1x", $Char1 + $Char2 + $Carry) . $Result;
$Carry = 0;
}
}
return ($Result);
}
# ------------------------------------------------------------------------------
# RoundPowerOfTwo - Finds the minimum binary quantum for the specified
# integer value
# ------------------------------------------------------------------------------
sub RoundPowerOfTwo {
# Passed parameter 1 is the integer value
my $Value = shift;
# Local variable(s)
my $Result = 0;
my $ShiftCount = 0;
# Determine the number of available regions
while ( $Value > $Result ) { $Result = 1 << $ShiftCount++; }
return ($Result);
}
# ------------------------------------------------------------------------------
# NumberOfDigits - Calculates the number of digits required to describe
# the specified integer value in the specified base
# ------------------------------------------------------------------------------
sub NumberOfDigits {
# Passed parameter 1 is the integer value
my $Value = shift;
# Passed parameter 2 is the base
my $Base = shift;
# Local variable(s)
my $Result = 1;
my $XToTheY = 0;
# Determine the number of digits for values greater than the radix
unless ( $Base < 2 or $Value < $Base ) {
while ( $Value > $XToTheY ) { $XToTheY = $Base ** $Result++; }
if ( $Value != $XToTheY ) { $Result--; }
}
return ( $Result );
}
# ------------------------------------------------------------------------------
# NumberOfHexChars - Calculates the number of hexadecimal characters
# required to describe the specified number of bits
# ------------------------------------------------------------------------------
sub NumberOfHexChars {
# Passed parameter 1 is the integer value
my $Value = shift;
# Local variable(s)
my $Result = $Value / 4.0;
my $Integer = int($Result);
my $Fraction = $Result - $Integer;
# Determine the number of digits
$Result = ($Fraction > 0) ? $Integer + 1 : $Integer;
return ( $Result );
}
# ------------------------------------------------------------------------------
# ToBinary - Converts the specified integer into an n-bit binary string
# ------------------------------------------------------------------------------
sub ToBinary {
# Passed parameter 1 is the integer value
my $Value = shift;
# Passed parameter 2 is the binary string length
my $Length = shift;
# Local variable(s)
my $Format = "%0${Length}b";
my $Result = ( $Value =~ /^\d+$/ ) ? sprintf($Format, $Value) : '';
return ( substr($Result, -$Length, $Length) );
}
# ------------------------------------------------------------------------------
# ToDecodeAddr - Shifts the specified n-bit address to the correct alignment
# for the Matrix Decoder because HADDR[9:0] is not decoded
# ------------------------------------------------------------------------------
sub ToDecodeAddr {
# Passed parameter 1 is the address value
my $FullAddr = shift;
# Local variable(s)
my $AddrBits = $RoutingAddressWidth - 10;
my $HexChars = NumberOfHexChars($AddrBits);
my $Length = length($FullAddr);
my $BinAddr = sprintf( "%032b%032b", hex substr($FullAddr, 0, $Length - 8),
hex substr($FullAddr, $Length - 8) );
my $Result = '';
# Right-shift the binary string to remove the non-decoded bits, and repack
# it into 32-bit chunks for reformatting into a hexadecimal representation
$BinAddr = '0' x 10 . substr($BinAddr, 0, -10);
$Result = sprintf( "%08lx%08lx",
unpack( 'N', pack('B32', substr($BinAddr, 0, 32)) ),
unpack( 'N', pack('B32', substr($BinAddr, 32)) ) );
return ( sprintf("%d'h%s", $AddrBits, substr($Result, 16 - $HexChars)) );
}
# ------------------------------------------------------------------------------
# UnsignedFloatToHex - Converts the specified float value into a hex string
# ------------------------------------------------------------------------------
sub UnsignedFloatToHex {
# Passed parameter 1 is the float value
my $Value = shift;
# Local variable(s)
my $HexDigits = NumberOfDigits($Value, 16);
my $Divisor = 16 ** ($HexDigits - 1);
my $Dividend = 0;
my $Result = '';
# Determine number sequence
while ( length($Result) < $HexDigits ) {
$Dividend = int( $Value / $Divisor );
if ( $Dividend > 0 ) {
$Result = $Result . substr('0123456789abcdef', $Dividend, 1);
$Value -= ($Divisor * $Dividend);
} else {
$Result = $Result . '0';
}
$Divisor /= 16;
}
return ($Result);
}
# ------------------------------------------------------------------------------
# IsGtOrEq - Operator '>=' test for up to 64-bit hexadecimal numbers
# ------------------------------------------------------------------------------
sub IsGtOrEq {
# Passed parameter 1 is the LHS value
my $OperandLHS = shift;
# Passed parameter 2 is the RHS value
my $OperandRHS = shift;
# Local variable(s)
my $LengthLHS = length($OperandLHS);
my @LHS = ( hex substr($OperandLHS, 0, $LengthLHS - 8),
hex substr($OperandLHS, $LengthLHS - 8) );
my $LengthRHS = length($OperandRHS);
my @RHS = ( hex substr($OperandRHS, 0, $LengthRHS - 8),
hex substr($OperandRHS, $LengthRHS - 8) );
my $Result = ( $LHS[0] > $RHS[0] or
($LHS[0] == $RHS[0] and $LHS[1] >= $RHS[1]) ) ? 1 : 0;
return ($Result);
}
# ------------------------------------------------------------------------------
# IsLtOrEq - Operator '<=' test for up to 64-bit hexadecimal numbers
# ------------------------------------------------------------------------------
sub IsLtOrEq {
# Passed parameter 1 is the LHS value
my $OperandLHS = shift;
# Passed parameter 2 is the RHS value
my $OperandRHS = shift;
# Local variable(s)
my $LengthLHS = length($OperandLHS);
my @LHS = ( hex substr($OperandLHS, 0, $LengthLHS - 8),
hex substr($OperandLHS, $LengthLHS - 8) );
my $LengthRHS = length($OperandRHS);
my @RHS = ( hex substr($OperandRHS, 0, $LengthRHS - 8),
hex substr($OperandRHS, $LengthRHS - 8) );
my $Result = ( $LHS[0] < $RHS[0] or
($LHS[0] == $RHS[0] and $LHS[1] <= $RHS[1]) ) ? 1 : 0;
return ($Result);
}
# ------------------------------------------------------------------------------
# IsGt - Operator '>' test for up to 64-bit hexadecimal numbers
# ------------------------------------------------------------------------------
sub IsGt {
# Passed parameter 1 is the LHS value
my $OperandLHS = shift;
# Passed parameter 2 is the RHS value
my $OperandRHS = shift;
# Local variable(s)
my $LengthLHS = length($OperandLHS);
my @LHS = ( hex substr($OperandLHS, 0, $LengthLHS - 8),
hex substr($OperandLHS, $LengthLHS - 8) );
my $LengthRHS = length($OperandRHS);
my @RHS = ( hex substr($OperandRHS, 0, $LengthRHS - 8),
hex substr($OperandRHS, $LengthRHS - 8) );
my $Result = ( $LHS[0] > $RHS[0] or
($LHS[0] == $RHS[0] and $LHS[1] > $RHS[1]) ) ? 1 : 0;
return ($Result);
}
# ------------------------------------------------------------------------------
# IsLt - Operator '<' test for up to 64-bit hexadecimal numbers
# ------------------------------------------------------------------------------
sub IsLt {
# Passed parameter 1 is the LHS value
my $OperandLHS = shift;
# Passed parameter 2 is the RHS value
my $OperandRHS = shift;
# Local variable(s)
my $LengthLHS = length($OperandLHS);
my @LHS = ( hex substr($OperandLHS, 0, $LengthLHS - 8),
hex substr($OperandLHS, $LengthLHS - 8) );
my $LengthRHS = length($OperandRHS);
my @RHS = ( hex substr($OperandRHS, 0, $LengthRHS - 8),
hex substr($OperandRHS, $LengthRHS - 8) );
my $Result = ( $LHS[0] < $RHS[0] or
($LHS[0] == $RHS[0] and $LHS[1] < $RHS[1]) ) ? 1 : 0;
return ($Result);
}
# ------------------------------------------------------------------------------
# IsEq - Operator '=' test for up to 64-bit hexadecimal numbers
# ------------------------------------------------------------------------------
sub IsEq {
# Passed parameter 1 is the LHS value
my $OperandLHS = shift;
# Passed parameter 2 is the RHS value
my $OperandRHS = shift;
# Local variable(s)
my $LengthLHS = length($OperandLHS);
my @LHS = ( hex substr($OperandLHS, 0, $LengthLHS - 8),
hex substr($OperandLHS, $LengthLHS - 8) );
my $LengthRHS = length($OperandRHS);
my @RHS = ( hex substr($OperandRHS, 0, $LengthRHS - 8),
hex substr($OperandRHS, $LengthRHS - 8) );
my $Result = ($LHS[0] == $RHS[0] and $LHS[1] == $RHS[1]) ? 1 : 0;
return ($Result);
}
# ------------------------------------------------------------------------------
# TidyPath - Removes double and trailing slash characters from filename paths
# ------------------------------------------------------------------------------
sub TidyPath {
# Passed parameter 1 is the filepath string
my $Filepath = shift;
$Filepath =~ s/(\/\/|\\)/\//g; $Filepath =~ s/\/$//;
return ($Filepath);
}
# ------------------------------------------------------------------------------
# GetRemapBits - Takes the Remapping and Unmapping (if exists) of an
# address_region or remap_region and returns a sorted list of the bits
# when the region is enabled. Returns an empty list if the region is always
# enabled. Negative bits are marked with an exclamation mark
# example:
# a remap region that is activated by bit 3
# but is eclipsed when bit 1 is active will return:
# [
# '!1',
# '3'
# ],
# ------------------------------------------------------------------------------
sub GetRemapBits {
my $Remapping = shift;
my $Unmapping = shift;
my @bits = ();
my @c_bits = ();
my $r_bit;
if (substr($Remapping,0,3) eq "del") {
@c_bits = split ( /,| |_/,substr($Remapping,3)) ;
foreach $r_bit (@c_bits) {
if (!($r_bit eq '')) { # need to ignore leading empty characters generated by a leading separator
push @bits, '!'.$r_bit;
}
}
}
if (substr($Remapping,0,5) eq "remap") {
@c_bits = split ( /,| |_/,substr($Remapping,5)) ;
foreach $r_bit (@c_bits) {
if (!($r_bit eq '')) { # need to ignore leading empty characters generated by a leading separator
push @bits, $r_bit;
}
}
}
if ($Unmapping) {
@c_bits = split ( /,| |_/,substr($Unmapping,5)) ;
foreach $r_bit (@c_bits) {
if (!($r_bit eq '')) { # need to ignore leading empty characters generated by a leading separator
push @bits, '!'.$r_bit;
}
}
}
# Sort bits in order, so they are easier to match
@bits = sort {
my $c = $a;
my $d = $b;
if ( substr($a,0,1) eq '!') {
$c = substr($a,1)
}
if ( substr($b,0,1) eq '!') {
$d = substr($b,1)
}
$c <=> $d
} @bits;
return (@bits);
}
# ------------------------------------------------------------------------------
# ValidateParameters - Checks the value of user configurable script parameters
# ------------------------------------------------------------------------------
sub ValidateParameters {
# Local variable(s)
my %Names = (
bus_matrix_name => \$BusMatrixName,
input_stage_name => \$InputStageName,
matrix_decode_name => \$MatrixDecodeName,
output_arbiter_name => \$OutputArbName,
output_stage_name => \$OutputStageName
);
my @NameKeys = keys( %Names );
my $Name = '';
my $NameLength = 0;
my $ShowName = '';
my @OtherNameKeys = ();
my $OtherName = '';
my $Type = '';
my @Interfaces = ();
my $Interface = '';
# Validate permitted values for the total slave interfaces
unless ( $SlaveInterfaces >= $MinSlaveIF and $SlaveInterfaces <= $MaxSlaveIF ) {
warn "Error: The number of slave ports must be in the range from $MinSlaveIF to $MaxSlaveIF \n";
$Errors++;
}
# Validate permitted values for the total master interfaces
unless ( $MasterInterfaces >= $MinMasterIF and $MasterInterfaces <= $MaxMasterIF ) {
warn "Error: The number of master ports must be in the range from $MinMasterIF to $MaxMasterIF \n";
$Errors++;
}
# Raise a warning about the '1 x n' bus matrix configuration
if ( $SlaveInterfaces == 1 ) {
warn "Warning: This configuration has one slave port and will use 'single' output\n" .
" and arbiter stage(s) only.\n";
}
# Validate permitted values of arbitration scheme
unless ( $ArbiterType =~ /^(fixed|round|burst)$/ ) {
warn "Error: Invalid type of arbitration-scheme '$ArbiterType'!\n";
$Errors++;
}
# Validate permitted values of architecture version
unless ( $ArchitectureType =~ /^(ahb2|v6|excl|unalign)$/ ) {
warn "Error: Invalid type of architecture '$ArchitectureType'!\n";
$Errors++;
}
# Validate permitted values of routing-data width
unless ( $RoutingDataWidth =~ /^($DataWidths)$/ ) {
warn "Error: Invalid routing-data width '$RoutingDataWidth'!\n";
$Errors++;
}
# Validate permitted values of user-signal width
if ( $RoutingAddressWidth =~ /[^0-9]/ ) {
warn "Error: Invalid routing-address width '$RoutingAddressWidth'!\n";
$Errors++;
} elsif ( $RoutingAddressWidth < $MinAddrWidth or $RoutingAddressWidth > $MaxAddrWidth ) {
warn "Error: Routing-address width must be in the range $MinAddrWidth..$MaxAddrWidth!\n";
$Errors++;
}
# Validate permitted values of user-signal width
if ( $UserSignalWidth =~ /[^0-9]/ ) {
warn "Error: Invalid user-signal width '$UserSignalWidth'!\n";
$Errors++;
} elsif ( $UserSignalWidth < $MinUserWidth or $UserSignalWidth > $MaxUserWidth ) {
warn "Error: User-signal width must be in the range $MinUserWidth..$MaxUserWidth!\n";
$Errors++;
}
# Validate permitted values of module names
foreach $Name ( @NameKeys ) {
$ShowName = $Name; $ShowName =~ s/_/ /g;
$NameLength = length( ${ $Names{$Name} } );
# Check for illegal characters and then check the string length
if ( ${ $Names{$Name} } =~ /[^\w]/ ) {
warn "Error: The $ShowName contains illegal characters!\n";
$Errors++;
} elsif ( $NameLength < $MinNameLength or $NameLength > $MaxNameLength ) {
warn "Error: The $ShowName is incorrect length ($MinNameLength..$MaxNameLength characters)!\n";
$Errors++;
}
# Check for unique name
@OtherNameKeys = grep $_ ne $Name , @NameKeys;
foreach $OtherName ( @OtherNameKeys ) {
if ( ${ $Names{$OtherName} } eq ${ $Names{$Name} } ) {
warn "Error: The $ShowName is not assigned a unique value!\n";
$Errors++;
}
}
}
# Check interface information
foreach $Type ( ('SLAVES', 'MASTERS') ) {
@Interfaces = keys( %{ $InterfaceInfo{$Type} } );
foreach $Interface ( @Interfaces ) {
# Inspect interface names
$Name = $InterfaceInfo{$Type}{$Interface}{NAME};
if ( $Name =~ /[^\w]/ ) {
warn "Error: Interface $Interface name '$Name' contains illegal characters!\n";
$Errors++;
}
if ( length($Name) > $MaxNameLength ) {
warn "Error: Interface $Interface name '$Name' is too long ($MaxNameLength" .
" characters max)!\n";
$Errors++;
}
# Inspect connectivity for isolated nodes resulting from an
# incomplete sparse mapping
if ( @{ $InterfaceInfo{$Type}{$Interface}{CONNECTIONS} } == 0 ) {
warn "Error: Interface $Interface has no connectivity mapping and is isolated!\n";
$Errors++;
}
# If this is a slave, then check its address map
if ( $Type eq 'SLAVES' ) { CheckAddressMap($Interface); }
}
}
}
# ------------------------------------------------------------------------------
# CheckAddressMap - Checks the address map of the specified slave interface
# for tags and overlapping regions
# ------------------------------------------------------------------------------
sub CheckAddressMap {
# Passed parameter 1 is the integer value
my $SlaveIF = shift;
# Local variable(s)
my $Class = '';
my $Index = 0;
my $MasterIF = '';
my @MIRegions = ();
my $Region = '';
my $MI = '';
my $Tag = '';
my $RegionHi = '';
my $RegionLo = '';
my $RegionHiLSW = 0;
my $RegionLoLSW = 0;
my $CheckBound = '';
my $OtherRegion = '';
my $OtherMI = '';
my $OtherHi = '';
my $OtherLo = '';
my $OtherTag = 0;
my $Exclusions = '';
my $HexChars = NumberOfHexChars($RoutingAddressWidth);
my %Tags = ( NORMAL => 'none|move|alias', REMAP => 'remap[0-3]' );
my %TagMessages = ( NORMAL => 'remapping action', REMAP => 'REMAP bit' );
my %WarnType = ( NORMAL => 'address', REMAP => 'remap' );
# Process each mapping type
foreach $Class ( ('REMAP', 'NORMAL') ) {
# Check the address map for each master interface
for ( $Index = 0; $Index < $MasterInterfaces; $Index++ ) {
$MasterIF = 'MI' . $Index;
# Find regions matching the master interface under inspection
@MIRegions = grep /^$MasterIF:/, @{ $InterfaceInfo{SLAVES}{$SlaveIF}{ADDRESS_MAP}{$Class} };
# Determine if this slave interface has connectivity with the master interface
if ( grep $_ eq $MasterIF, @{ $InterfaceInfo{SLAVES}{$SlaveIF}{CONNECTIONS} } ) {
# Check for expected address regions
unless ( $Class eq 'REMAP' or @MIRegions > 0 ) {
warn "Error: Interface $SlaveIF has no address regions defined for the $MasterIF interface!\n";
$Errors++;
}
# Inspect each region mapped to the master interface
foreach $Region ( @MIRegions ) {
# Split the region into its constituent parts
($MI, $Tag, $RegionLo, $RegionHi) = split(/:/, $Region);
# Extract and remove the expected prefix, then check its type
unless ( $Tag =~ /^($Tags{$Class})$/ ) {
warn "Error: Interface $SlaveIF address region '$MI: $RegionLo-$RegionHi'" .
" declares\n unsupported $TagMessages{$Class}!\n";
$Errors++;
}
# Check that each bound only consists of hexadecimal characters
# and is the expected number of hexadecimal digits
foreach $CheckBound ( $RegionLo, $RegionHi ) {
if ( length($CheckBound) != $HexChars ) {
warn "Error: Interface $SlaveIF address bound '$MI: $CheckBound' is incorrect length should be $HexChars characters!\n";
$Errors++;
}
if ( $CheckBound =~ /[^a-f0-9]+/i ) {
warn "Error: Interface $SlaveIF address bound '$MI: $CheckBound' contains illegal characters!\n";
$Errors++;
}
}
# Check the region syntax
if ( IsGtOrEq($RegionLo, $RegionHi) ) {
warn "Error: Interface $SlaveIF address region '$MI: $RegionLo-$RegionHi' is invalid!\n";
$Errors++;
}
# Check the region size - minimum is 1kBytes
$RegionHiLSW = hex substr($RegionHi, length($RegionHi) - 8);
$RegionLoLSW = hex substr($RegionLo, length($RegionLo) - 8);
if ( abs( $RegionHiLSW - $RegionLoLSW ) < 1023 ) {
warn "Error: Interface $SlaveIF address region '$MI: $RegionLo-$RegionHi' is < 1kBytes!\n";
$Errors++;
}
# Check alignment of lower address bound
if ( ( hex(substr($RegionLo, -3, 3)) & 0x3ff ) != 0x000 ) {
warn "Warning: Interface $SlaveIF address bound '$MI: $RegionLo' is misaligned!\n";
}
# Check alignment of upper address bound
if ( ( hex(substr($RegionHi, -3, 3)) & 0x3ff ) != 0x3ff ) {
warn "Warning: Interface $SlaveIF address bound '$MI: $RegionHi' is misaligned!\n";
}
# Check the current region against all others for illegal overlap
foreach $OtherRegion ( @{ $InterfaceInfo{SLAVES}{$SlaveIF}{ADDRESS_MAP}{$Class} } ) {
# Split the other region into its constituent parts
($OtherMI, $OtherTag, $OtherLo, $OtherHi) = split(/:/, $OtherRegion);
# Exclude remap regions with different remap bits
if ( $Class eq 'REMAP' and $Tag ne $OtherTag ) { next; }
# Filter out the current region and any previously reported ones
unless ( $OtherRegion =~ /^($Region$Exclusions)$/ ) {
# Check bounds for overlap
if ( (IsGtOrEq($OtherLo, $RegionLo) and IsLtOrEq($OtherLo, $RegionHi)) or
(IsGtOrEq($OtherHi, $RegionLo) and IsLtOrEq($OtherHi, $RegionHi)) ) {
warn "Error: Interface $SlaveIF $WarnType{$Class} region '$OtherMI: $OtherLo-$OtherHi'" .
" overlaps\n with another $WarnType{$Class} region '$MI: $RegionLo-$RegionHi'!\n";
$Errors++;
# Suppress multiple messages that show the same error
$Exclusions = $Exclusions . "|$MI:[^:]+:$RegionLo:$RegionHi";
}
}
}
}
} elsif ( @MIRegions > 0 ) {
# This slave interface is not connected to the master interface and
# therefore should not have any address map information
warn "Error: Interface $SlaveIF has an address map for $MasterIF interface,\n" .
" while not connected!\n";
$Errors++;
}
}
# Clear the exclusions for checking the next class
$Exclusions = '';
}
}
# ------------------------------------------------------------------------------
# InitialiseInterfaceInfo - Determines the connectivity mapping and address
# map, assigning values to the global interface
# information hash
# ------------------------------------------------------------------------------
sub InitialiseInterfaceInfo {
# Local variable(s)
my $SlaveIF = '';
my $MasterIF = '';
my $Index1 = 0;
my $Index2 = 0;
my $Regions = RoundPowerOfTwo($MasterInterfaces);
my $RegionSize = (2 ** $RoutingAddressWidth) / $Regions;
my $BaseAddress = 0;
my $TopAddress = 0;
my @Mappings = split(/:\s*/, $Connectivity);
my $Mapping = '';
my @Interfaces = ();
my $HexChars = NumberOfHexChars($RoutingAddressWidth);
my $Format = "%0${HexChars}s";
# Initialise master interface parameter(s) first to simplify the sequence
for ( $Index1 = 0; $Index1 < $MasterInterfaces; $Index1++ ) {
$MasterIF = 'MI' . $Index1;
$InterfaceInfo{MASTERS}{$MasterIF}{NAME} = $MasterIF;
$InterfaceInfo{MASTERS}{$MasterIF}{CONNECTIONS} = [];
}
# Initialise slave interface parameter(s)
for ( $Index1 = 0; $Index1 < $SlaveInterfaces; $Index1++ ) {
# Initialise slave information container
$SlaveIF = 'SI' . $Index1;
$InterfaceInfo{SLAVES}{$SlaveIF}{NAME} = $SlaveIF;
$InterfaceInfo{SLAVES}{$SlaveIF}{CONNECTIONS} = [];
$InterfaceInfo{SLAVES}{$SlaveIF}{ADDRESS_MAP}{NORMAL} = [];
$InterfaceInfo{SLAVES}{$SlaveIF}{ADDRESS_MAP}{REMAP} = [];
# Establish the connectivity
if ( $Connectivity ne 'full' ) {
# Initialise or concatenate the connection description string
$Connectivity = 'sparse';
$Connections = $Connections . sprintf("%s%s -> ", ($Connections eq '') ?
'' : "\n" . ' ' x 29, $InterfaceInfo{SLAVES}{$SlaveIF}{NAME});
# Search the connectivity string for a mapping from this slave interface
foreach $Mapping ( @Mappings ) {
if ( $Mapping =~ /^$SlaveIF=MI\{([0-9,]+)\}/) {
# Process each master interface in turn, checking for its existence
@Interfaces = split(/,\s*/, $1);
foreach $MasterIF ( @Interfaces ) {
$MasterIF = 'MI' . $MasterIF;
if ( exists( $InterfaceInfo{MASTERS}{$MasterIF} ) ) {
# Append the details of this sparse connection
push @{ $InterfaceInfo{SLAVES}{$SlaveIF}{CONNECTIONS} }, $MasterIF;
$Connections = $Connections . "$MasterIF, ";
} else {
warn "Error: Interface $SlaveIF has an unresolved sparse connection '$MasterIF'!\n";
$Errors++;
}
}
}
}
} else {
# Full connectivity is default
for ( $Index2 = 0; $Index2 < $MasterInterfaces; $Index2++ ) {
push @{ $InterfaceInfo{SLAVES}{$SlaveIF}{CONNECTIONS} }, 'MI' . $Index2;
}
}
# Determine address map (assume no remap regions)
for ( $Index2 = 0; $Index2 < $MasterInterfaces; $Index2++ ) {
$MasterIF = 'MI' . $Index2;
$BaseAddress = $RegionSize * $Index2;
$TopAddress = $BaseAddress + $RegionSize - 1;
if ( grep $_ eq $MasterIF, @{ $InterfaceInfo{SLAVES}{$SlaveIF}{CONNECTIONS} } ) {
push @{ $InterfaceInfo{SLAVES}{$SlaveIF}{ADDRESS_MAP}{NORMAL} },
sprintf("%s:none:$Format:$Format", $MasterIF, UnsignedFloatToHex($BaseAddress),
UnsignedFloatToHex($TopAddress));
}
}
}
# Remove leading whitespace from the connections detail
$Connections =~ s/,\s+$//;
# Determine connectivity information from master interface perspective
for ( $Index1 = 0; $Index1 < $MasterInterfaces; $Index1++ ) {
$MasterIF = 'MI' . $Index1;
for ( $Index2 = 0; $Index2 < $SlaveInterfaces; $Index2++ ) {
$SlaveIF = 'SI' . $Index2;
if ( grep $_ eq $MasterIF, @{ $InterfaceInfo{SLAVES}{$SlaveIF}{CONNECTIONS} } ) {
push @{ $InterfaceInfo{MASTERS}{$MasterIF}{CONNECTIONS} }, $SlaveIF;
}
}
}
}
# ------------------------------------------------------------------------------
# ProcessXmlConfigFile - Reads the specified XML configuration file and
# assigns values to the global variables including
# the interface information hash
# ------------------------------------------------------------------------------
sub ProcessXmlConfigFile {
# Local variable(s)
my @Elements = ();
my $XmlItem = '';
my $XmlElement = '';
my @SlavePorts = ();
my @MasterPorts = ();
my $Index1 = 1;
my $Index2 = 0;
my $SlaveIF = '';
my $MasterIF = '';
my $Name = '';
my $Region = '';
# Configure the XML parser
ConfigureXmlParser( show_ids => 0, verbose => 0, show_warnings => 0 );
# Read the specified configuration file
RunXmlParser($XmlConfigFile);
# Display the XML structure when in debug mode
if ( $Debug ) { ListXmlHash('ROOT'); }
# Access mandatory items of information (bus matrix dimensions)
@SlavePorts = GetXmlNodeList('//cfgfile/slave_interface');
$SlaveInterfaces = scalar @SlavePorts;
@MasterPorts = GetXmlNodeList('//cfgfile/master_interface');
$MasterInterfaces = scalar @MasterPorts;
# Access optional items of information
@Elements = GetXmlNodeList('/cfgfile');
foreach $XmlElement ( @Elements ) {
# Assign the extracted value to the appropriate parameter name
$XmlItem = GetXmlValue("/cfgfile/$XmlElement");
if ( $XmlElement =~ /arbitration_scheme\[1\]$/ ) {
$ArbiterType = $XmlItem;
} elsif ( $XmlElement =~ /architecture_version\[1\]$/ ) {
$ArchitectureType = $XmlItem;
} elsif ( $XmlElement =~ /routing_data_width\[1\]$/ ) {
$RoutingDataWidth = $XmlItem;
} elsif ( $XmlElement =~ /routing_address_width\[1\]$/ ) {
$RoutingAddressWidth = $XmlItem;
} elsif ( $XmlElement =~ /user_signal_width\[1\]$/ ) {
$UserSignalWidth = $XmlItem;
} elsif ( $XmlElement =~ /timescales\[1\]$/ ) {
$XmlTimescales = $XmlItem;
} elsif ( $XmlElement =~ /bus_matrix_name\[1\]$/ ) {
$BusMatrixName = $XmlItem;
} elsif ( $XmlElement =~ /input_stage_name\[1\]$/ ) {
$InputStageName = $XmlItem;
} elsif ( $XmlElement =~ /matrix_decode_name\[1\]$/ ) {
$MatrixDecodeName = $XmlItem;
} elsif ( $XmlElement =~ /output_arbiter_name\[1\]$/ ) {
$OutputArbName = $XmlItem;
} elsif ( $XmlElement =~ /output_stage_name\[1\]$/ ) {
$OutputStageName = $XmlItem;
} elsif ( $XmlElement =~ /product_version_info\[1\]$/ ) {
$ComponentName = GetXmlValue("/cfgfile/$XmlElement" . '@component_name');
} elsif ( $XmlElement !~ /(slave|master)_interface\[\d+\]/ ) {
warn "Error: Unknown XML option '$XmlElement'!\n";
$Errors++;
}
}
# Extract master interface parameter(s) first to simplify the sequence
foreach $XmlElement ( @MasterPorts ) {
# Initialise information container and increment the count
$MasterIF = sprintf("MI%d", $Index2++);
$Name = GetXmlValue($XmlElement . '@name');
$InterfaceInfo{MASTERS}{$MasterIF}{NAME} = $Name;
$InterfaceInfo{MASTERS}{$MasterIF}{CONNECTIONS} = [];
# Add the name to the master alias lookup hash
if ( ! exists( $NameAliases{$Name} ) ) {
$NameAliases{$Name} = $MasterIF;
} else {
warn "Error: Interface $MasterIF name '$Name' is not unique!\n";
$Errors++;
}
}
# Extract slave interface parameter(s)
foreach $XmlElement ( @SlavePorts ) {
# Initialise information container
$SlaveIF = sprintf("SI%d", $Index1 - 1);
$Name = GetXmlValue($XmlElement . '@name');
$InterfaceInfo{SLAVES}{$SlaveIF}{NAME} = $Name;
$InterfaceInfo{SLAVES}{$SlaveIF}{CONNECTIONS} = [];
$InterfaceInfo{SLAVES}{$SlaveIF}{ADDRESS_MAP}{NORMAL} = [];
$InterfaceInfo{SLAVES}{$SlaveIF}{ADDRESS_MAP}{REMAP} = [];
# Add the name to the slave alias lookup hash
if ( ! exists( $NameAliases{$Name} ) ) {
$NameAliases{$Name} = $SlaveIF;
} else {
warn "Error: Interface $SlaveIF name '$Name' is not unique!\n";
$Errors++;
}
# Extract connectivity information or assign full connectivity as default
@Elements = GetXmlNodeList("//cfgfile/slave_interface[$Index1]/sparse_connect");
if ( @Elements > 0 ) {
# Initialise or concatenate the connection description string
$Connectivity = 'sparse';
$Connections = $Connections . sprintf("%s%s -> ", ($Connections eq '') ?
'' : "\n" . ' ' x 29, $InterfaceInfo{SLAVES}{$SlaveIF}{NAME});
# Convert the symbolic interface names to the MI<n> notation
foreach $XmlItem ( @Elements ) {
# Extract sparse connection attribute and check for existence of the
# named interface
$MasterIF = GetXmlValue($XmlItem . '@interface');
if ( exists( $NameAliases{$MasterIF} ) ) {
push @{ $InterfaceInfo{SLAVES}{$SlaveIF}{CONNECTIONS} }, $NameAliases{$MasterIF};
} else {
warn "Error: Interface '$Name' has an unresolved sparse connection '$MasterIF'!\n";
$Errors++;
}
# Append this sparse connection detail
$Connections = $Connections . "$MasterIF, ";
}
} else {
# Full connectivity is default
for ( $Index2 = 0; $Index2 < $MasterInterfaces; $Index2++ ) {
push @{ $InterfaceInfo{SLAVES}{$SlaveIF}{CONNECTIONS} }, 'MI' . $Index2;
}
}
# Extract address mapping information
@Elements = GetXmlNodeList("//cfgfile/slave_interface[$Index1]/address_region");
if ( @Elements > 0 ) {
foreach $XmlItem ( @Elements ) {
# Determine which master interface this address region is for, and
# check that it exists
$MasterIF = GetXmlValue($XmlItem . '@interface');
if ( exists( $NameAliases{$MasterIF} ) ) {
$Region = sprintf("%s:%s:%s:%s", $NameAliases{$MasterIF},
GetXmlValue($XmlItem . '@remapping'),
GetXmlValue($XmlItem . '@mem_lo'),
GetXmlValue($XmlItem . '@mem_hi'));
# Check for duplicated definitions
if ( grep $_ eq $Region, @{ $InterfaceInfo{SLAVES}{$SlaveIF}{ADDRESS_MAP}{NORMAL} } ) {
warn "Error: Interface '$Name' has duplicated address region for master interface '$MasterIF'\n";
$Errors++;
} else {
push @{ $InterfaceInfo{SLAVES}{$SlaveIF}{ADDRESS_MAP}{NORMAL} }, $Region;
}
} else {
warn "Error: Address region maps to unknown master interface '$MasterIF'\n";
$Errors++;
}
}
} else {
warn "Error: Expecting an address region for interface '$SlaveIF'\n";
$Errors++;
}
# Extract the optional remapped address information
@Elements = GetXmlNodeList("//cfgfile/slave_interface[$Index1]/remap_region");
foreach $XmlItem ( @Elements ) {
# Determine which master interface this remap region is for, and
# check that it exists
$MasterIF = GetXmlValue($XmlItem . '@interface');
if ( exists( $NameAliases{$MasterIF} ) ) {
$Region = sprintf("%s:remap%s:%s:%s", $NameAliases{$MasterIF},
GetXmlValue($XmlItem . '@bit'),
GetXmlValue($XmlItem . '@mem_lo'),
GetXmlValue($XmlItem . '@mem_hi'));
# Check for duplicated definitions
if ( grep $_ eq $Region, @{ $InterfaceInfo{SLAVES}{$SlaveIF}{ADDRESS_MAP}{REMAP} } ) {
warn "Error: Interface '$Name' has duplicated remap region for master interface '$MasterIF'\n";
$Errors++;
} else {
push @{ $InterfaceInfo{SLAVES}{$SlaveIF}{ADDRESS_MAP}{REMAP} }, $Region;
}
} else {
warn "Error: Remap region maps to unknown master interface '$MasterIF'\n";
$Errors++;
}
}
# Increment index
$Index1++;
}
# Remove leading whitespace from the connections detail
$Connections =~ s/,\s+$//;
# Determine connectivity information from master interface perspective
for ( $Index1 = 0; $Index1 < $MasterInterfaces; $Index1++ ) {
$MasterIF = 'MI' . $Index1;
for ( $Index2 = 0; $Index2 < $SlaveInterfaces; $Index2++ ) {
$SlaveIF = 'SI' . $Index2;
if ( grep $_ eq $MasterIF, @{ $InterfaceInfo{SLAVES}{$SlaveIF}{CONNECTIONS} } ) {
push @{ $InterfaceInfo{MASTERS}{$MasterIF}{CONNECTIONS} }, $SlaveIF;
}
}
}
}
sub ProcessDataForIPXact {
# Work on a copy for IPXact
%InterfaceInfoIPXact = %{ dclone \%InterfaceInfo };
my $SlaveIF = '';
my $MasterIF = '';
my @address_regions = ();
my $address_region;
my $remap_region;
my $AddrLo = '';
my $AddrHi = '';
my $Remapping = '';
my $r_MasterIF = '';
my $r_AddrLo = '';
my $r_AddrHi = '';
my $r_Remapping = '';
my $new_Remapping= '';
my $split_done = '';
my $r_bit = '';
my $r2_bit = '';
my $Unmapping = '';
my $new_Unmapping= '';
# Convert move to del
foreach $SlaveIF (keys %{$InterfaceInfoIPXact{SLAVES}} ) {
@address_regions = @{ $InterfaceInfoIPXact{SLAVES}{$SlaveIF}{ADDRESS_MAP}{NORMAL} };
foreach $address_region (@address_regions) {
($MasterIF, $Remapping, $AddrLo, $AddrHi) = split(/:/, $address_region);
$new_Remapping = $Remapping;
if ($Remapping eq 'move') {
foreach $remap_region (@{ $InterfaceInfoIPXact{SLAVES}{$SlaveIF}{ADDRESS_MAP}{REMAP} }) {
($r_MasterIF, $r_Remapping, $r_AddrLo, $r_AddrHi) = split(/:/, $remap_region);
$r_bit = substr($r_Remapping, 5);
if ($r_MasterIF eq $MasterIF) {
if (substr($new_Remapping,0,3) eq "del") {
# Check if it's already in the _del_
if ($new_Remapping =~ m/.*(del|_|,|\s)$r_bit(_|,|\s|$)/ ) {
$new_Remapping = $new_Remapping;
} else {
$new_Remapping = $new_Remapping . "," . $r_bit;
}
} else {
$new_Remapping = "del" . $r_bit;
}
}
}
if ( !($new_Remapping eq $Remapping) ) {
$address_region = $MasterIF .":". $new_Remapping .":". $AddrLo .":". $AddrHi;
print "Converted " . $MasterIF .":". $Remapping .":". $AddrLo .":". $AddrHi . " to " . $new_Remapping . "\n" if $Debug;
}
}
}
@{ $InterfaceInfoIPXact{SLAVES}{$SlaveIF}{ADDRESS_MAP}{NORMAL} } = @address_regions;
}
############################ ADDRESS REGION ############################
# Cut address_regions if remap_regions overlap
foreach $SlaveIF (keys %{$InterfaceInfoIPXact{SLAVES}} ) {
# Cut address_regions
@address_regions = @{ $InterfaceInfoIPXact{SLAVES}{$SlaveIF}{ADDRESS_MAP}{NORMAL} };
foreach $remap_region (@{ $InterfaceInfoIPXact{SLAVES}{$SlaveIF}{ADDRESS_MAP}{REMAP} }) {
($r_MasterIF, $r_Remapping, $r_AddrLo, $r_AddrHi) = split(/:/, $remap_region);
$r_bit = substr($r_Remapping, 5);
foreach $address_region (@address_regions) {
($MasterIF, $Remapping, $AddrLo, $AddrHi) = split(/:/, $address_region);
# Make new address region remapping type
if (substr($Remapping,0,3) eq "del") {
# Check if it's already in the _del_
if ($Remapping =~ m/.*(del|_|,|\s)$r_bit(_|,|\s|$)/ ) {
$new_Remapping = $Remapping;
} else {
$new_Remapping = $Remapping . "," . $r_bit;
}
} else {
$new_Remapping = "del" . $r_bit;
}
# Split the address region that is covered by a remap region
if ( IsLt( $AddrLo , $r_AddrLo) && IsLt( $r_AddrHi, $AddrHi) ) {
$address_region = $MasterIF .":". $new_Remapping .":". $r_AddrLo .":". $r_AddrHi;
push (@address_regions, $MasterIF .":". $Remapping .":". $AddrLo .":". HexSubstract($r_AddrLo,1));
push (@address_regions, $MasterIF .":". $Remapping .":". HexAdd($r_AddrHi,1) .":". $AddrHi);
if ($Debug) {
print "Splitting for encapsulated " . $MasterIF .":". $Remapping .":". $AddrLo .":". $AddrHi . "\n";
print " Into " . $MasterIF .":". $Remapping .":". $AddrLo .":". HexSubstract($r_AddrLo,1) . "\n";
print " Add " . $MasterIF .":". $new_Remapping .":". $r_AddrLo .":". $r_AddrHi . "\n";
print " And " . $MasterIF .":". $Remapping .":". HexAdd($r_AddrHi,1) .":". $AddrHi . "\n";
if (substr($Remapping,0,3) eq "del") {
print "^ (Double Del)\n";
}
print "---------------------------------------------------------------------\n";
}
redo;
} elsif ( IsLt( $AddrLo , $r_AddrLo) && IsLt( $r_AddrLo , $AddrHi) ) {
$address_region = $MasterIF .":". $Remapping .":". $AddrLo .":". HexSubstract($r_AddrLo,1);
push (@address_regions, $MasterIF .":". $new_Remapping .":". $r_AddrLo .":". $AddrHi);
if ($Debug) {
print "Splitting low region " . $MasterIF .":". $Remapping .":". $AddrLo .":". $AddrHi . "\n";
print " Into " . $MasterIF .":". $Remapping .":". $AddrLo .":". HexSubstract($r_AddrLo,1) . "\n";
print " And " . $MasterIF .":". $new_Remapping .":". $r_AddrLo .":". $AddrHi . "\n";
if (substr($Remapping,0,3) eq "del") {
print "^ (Double Del)\n";
}
print "---------------------------------------------------------------------\n";
}
redo;
} elsif ( IsLt( $AddrLo , $r_AddrHi) && IsLt( $r_AddrHi , $AddrHi) ) {
$address_region = $MasterIF .":". $new_Remapping .":". $AddrLo .":". $r_AddrHi;
push (@address_regions, $MasterIF .":". $Remapping .":". HexAdd($r_AddrHi,1) .":". $AddrHi);
if ($Debug) {
print "Splitting high region " . $MasterIF .":". $Remapping .":". $AddrLo .":". $AddrHi . "\n";
print " Into " . $MasterIF .":". $new_Remapping .":". $AddrLo .":". $r_AddrHi . "\n";
print " And " . $MasterIF .":". $Remapping .":". HexAdd($r_AddrHi,1) .":". $AddrHi . "\n";
if (substr($Remapping,0,3) eq "del") {
print "^ (Double Del)\n";
}
print "---------------------------------------------------------------------\n";
}
redo;
} elsif ( IsGtOrEq( $AddrLo , $r_AddrLo) && IsGtOrEq( $r_AddrHi , $AddrHi) && !($new_Remapping eq $Remapping) ) {
$address_region = $MasterIF .":". $new_Remapping .":". $AddrLo .":". $AddrHi;
if ($Debug) {
print "Changed region to deletable " . $MasterIF .":". $Remapping .":". $AddrLo .":". $AddrHi . "\n";
print " Into " . $MasterIF .":". $new_Remapping .":". $AddrLo .":". $AddrHi . "\n";
if (substr($Remapping,0,3) eq "del") {
print "^ (Double Del)\n";
}
print "---------------------------------------------------------------------\n";
}
}
}
}
@{ $InterfaceInfoIPXact{SLAVES}{$SlaveIF}{ADDRESS_MAP}{NORMAL} } =
sort {
my @split_a = split /:/, $a;
my @split_b = split /:/, $b;
my $c;
my $d;
if ( IsLt($split_a[2],$split_b[2]) ) {
$c = 1;
$d = 2;
} else {
$c = 2;
$d = 1;
}
$c <=> $d
# (hex $split_a[2]) <=> (hex $split_b[2] )
} @address_regions;
############################ REMAP ############################
# Cut remap_regions
@address_regions = @{ $InterfaceInfoIPXact{SLAVES}{$SlaveIF}{ADDRESS_MAP}{REMAP} }; # reusing address_region for remaps
foreach $remap_region (@{ $InterfaceInfoIPXact{SLAVES}{$SlaveIF}{ADDRESS_MAP}{REMAP} }) {
($r_MasterIF, $r_Remapping, $r_AddrLo, $r_AddrHi) = split(/:/, $remap_region);
$r_bit = substr($r_Remapping, 5);
foreach $address_region (@address_regions) {
($MasterIF, $Remapping, $AddrLo, $AddrHi, $Unmapping) = split(/:/, $address_region);
$r2_bit = substr($Remapping, 5);
if ($r_bit<$r2_bit) {
# If there is already an Unmapping defined
if ($Unmapping) {
# Check if it's already in the _del_
if ($Unmapping =~ m/.*(unmap|_|,|\s)$r_bit(_|,|\s|$)/ ) {
$new_Unmapping = $Unmapping;
} else {
$new_Unmapping = $r_bit < $r2_bit ? $Unmapping . "," . $r_bit : $Unmapping;
}
} else {
$new_Unmapping = "unmap " . $r_bit;
$Unmapping = '';
}
# Lower remap bit has higher priority
# Split the remap region that is covered by another remap region of higher priority
if ( IsLt( $AddrLo , $r_AddrLo) && IsLt( $r_AddrHi, $AddrHi) ) {
$address_region = $MasterIF .":". $Remapping .":". $r_AddrLo .":". $r_AddrHi.":".$new_Unmapping;
push (@address_regions, $MasterIF .":". $Remapping .":". $AddrLo .":". HexSubstract($r_AddrLo,1).":".$Unmapping);
push (@address_regions, $MasterIF .":". $Remapping .":". HexAdd($r_AddrHi,1) .":". $AddrHi.":".$Unmapping);
if ($Debug) {
print "Splitting remap for encapsulated " . $MasterIF .":". $Remapping .":". $AddrLo .":". $AddrHi .":".$Unmapping. "\n";
print " Into " . $MasterIF .":". $Remapping .":". $AddrLo .":". HexSubstract($r_AddrLo,1) .":".$Unmapping. "\n";
print " Add " . $MasterIF .":". $Remapping .":". $r_AddrLo .":". $r_AddrHi . ":".$new_Unmapping . "\n";
print " And " . $MasterIF .":". $Remapping .":". HexAdd($r_AddrHi,1) .":". $AddrHi .":".$Unmapping. "\n";
print "---------------------------------------------------------------------\n";
}
redo;
} elsif ( IsLt( $AddrLo , $r_AddrLo) && IsLt( $r_AddrLo , $AddrHi) ) {
$address_region = $MasterIF .":". $Remapping .":". $AddrLo .":". HexSubstract($r_AddrLo,1).":".$Unmapping;
push (@address_regions, $MasterIF .":". $Remapping .":". $r_AddrLo .":". $AddrHi.":".$new_Unmapping);
if ($Debug) {
print "Splitting low remap region " . $MasterIF .":". $Remapping .":". $AddrLo .":". $AddrHi .":".$Unmapping. "\n";
print " Into " . $MasterIF .":". $Remapping .":". $AddrLo .":". HexSubstract($r_AddrLo,1) .":".$Unmapping. "\n";
print " And " . $MasterIF .":". $Remapping .":". $r_AddrLo .":". $AddrHi .":".$new_Unmapping. "\n";
print "---------------------------------------------------------------------\n";
}
redo;
} elsif ( IsLt( $AddrLo , $r_AddrHi) && IsLt( $r_AddrHi , $AddrHi) ) {
$address_region = $MasterIF .":". $Remapping .":". $AddrLo .":". $r_AddrHi.":".$new_Unmapping;
push (@address_regions, $MasterIF .":". $Remapping .":". HexAdd($r_AddrHi,1) .":". $AddrHi.":".$Unmapping);
if ($Debug) {
print "Splitting high remap region " . $MasterIF .":". $Remapping .":". $AddrLo .":". $AddrHi .":".$Unmapping. "\n";
print " Into " . $MasterIF .":". $Remapping .":". $AddrLo .":". $r_AddrHi .":".$new_Unmapping. "\n";
print " And " . $MasterIF .":". $Remapping .":". HexAdd($r_AddrHi,1) .":". $AddrHi .":".$Unmapping. "\n";
print "---------------------------------------------------------------------\n";
}
redo;
} elsif ( IsGtOrEq( $AddrLo , $r_AddrLo) && IsGtOrEq( $r_AddrHi , $AddrHi) && !($new_Unmapping eq $Unmapping) ) {
$address_region = $MasterIF .":". $Remapping .":". $AddrLo .":". $AddrHi.":".$new_Unmapping;
if ($Debug) {
print "Changed remap region to unmappable " . $MasterIF .":". $Remapping .":". $AddrLo .":". $AddrHi .":".$Unmapping. "\n";
print " Into " . $MasterIF .":". $Remapping .":". $AddrLo .":". $AddrHi .":".$new_Unmapping. "\n";
print "---------------------------------------------------------------------\n";
}
}
}
}
}
@{ $InterfaceInfoIPXact{SLAVES}{$SlaveIF}{ADDRESS_MAP}{REMAP} } =
sort {
my @split_a = split /:/, $a;
my @split_b = split /:/, $b;
my $c;
my $d;
if ( IsLt($split_a[2],$split_b[2]) ) {
$c = 1;
$d = 2;
} else {
$c = 2;
$d = 1;
}
$c <=> $d
# (hex $split_a[2]) <=> (hex $split_b[2] )
} @address_regions;
# Sort remap in order of priority
@{ $InterfaceInfoIPXact{SLAVES}{$SlaveIF}{ADDRESS_MAP}{REMAP} } =
sort {
my @split_a = split /:/, $a;
my @split_b = split /:/, $b;
substr($split_a[1],5) <=> substr($split_b[1],5)
} @{ $InterfaceInfoIPXact{SLAVES}{$SlaveIF}{ADDRESS_MAP}{REMAP} };
}
# Generate Remapstates
my @bits;
my @c_bits;
my $remap_name;
foreach $SlaveIF (keys %{$InterfaceInfoIPXact{SLAVES}} ) {
@address_regions = @{ $InterfaceInfoIPXact{SLAVES}{$SlaveIF}{ADDRESS_MAP}{NORMAL} };
push (@address_regions, @{ $InterfaceInfoIPXact{SLAVES}{$SlaveIF}{ADDRESS_MAP}{REMAP} });
foreach $address_region (@address_regions) {
$Unmapping = '';
($MasterIF, $Remapping, $AddrLo, $AddrHi,$Unmapping) = split(/:/, $address_region);
@bits = GetRemapBits ($Remapping, $Unmapping);
$remap_name = "remap_".join( '_' , @bits );
# Change ! to n
$remap_name =~ s/!/n/g ;
# don't put in duplicates
if ( @bits && !$RemapStates{$remap_name}) {
@{ $RemapStates{$remap_name}} = @bits;
}
}
}
print "RemapStates:\n" if $Debug;
print Dumper(\%RemapStates) if $Debug;
# Generate AddressSpace regions
foreach $SlaveIF (keys %{$InterfaceInfoIPXact{SLAVES}} ) {
@address_regions = @{ $InterfaceInfoIPXact{SLAVES}{$SlaveIF}{ADDRESS_MAP}{NORMAL} };
push (@address_regions, @{ $InterfaceInfoIPXact{SLAVES}{$SlaveIF}{ADDRESS_MAP}{REMAP} });
foreach $address_region (@address_regions) {
($MasterIF, $Remapping, $AddrLo, $AddrHi) = split(/:/, $address_region);
if ( !( grep {(@{$_}[0] eq $AddrLo) && (@{$_}[1] eq $AddrHi)} @{ $AddressSpace{$MasterIF} } ) ) {
push @{ $AddressSpace{$MasterIF}}, [$AddrLo,$AddrHi];
}
}
}
# Sort the AddressSpace
foreach $MasterIF (keys %AddressSpace) {
@{ $AddressSpace{$MasterIF}} = sort {
my $c;
my $d;
if ( IsLt(@{$a}[0],@{$b}[0]) ) {
$c = 1;
$d = 2;
} else {
$c = 2;
$d = 1;
}
$c <=> $d
} @{ $AddressSpace{$MasterIF}};
}
print "AddressSpace:\n" if $Debug;
print Dumper(\%AddressSpace) if $Debug;
print "InterfaceInfo:\n" if $Debug;
print Dumper(\%InterfaceInfo) if $Debug;
print "InterfaceInfoIPXact:\n" if $Debug;
print Dumper(\%InterfaceInfoIPXact) if $Debug;
}
# ------------------------------------------------------------------------------
# ShowHelp - Displays help dialogue (developer's options are not advertised)
# ------------------------------------------------------------------------------
sub ShowHelp {
# Local variable(s)
my $ShowArchitectureOptions = 0;
printf "%sPurpose:\n" .
" Builds particular configurations of the AHB BusMatrix component.\n\n" .
"Usage:\n" .
" Builds an AHB BusMatrix component with a given number of input\n" .
" ports, a given number of output ports, a particular arbitration\n" .
" scheme and ARM processor interface.\n\n" .
"Options:\n" .
" --cfg=FILENAME Name of an XML configuration file that\n" .
" defines the bus matrix specification\n" .
" in place of most command line arguments.\n" .
" Note that this is the only method to\n" .
" specify customised address maps.\n".
"\n" .
" use these if not using the config file method:\n" .
" --inports=NUM Number of input (slave) ports ($MinSlaveIF..$MaxSlaveIF).\n" .
" --outports=NUM Number of output (master) ports ($MinMasterIF..$MaxMasterIF).\n\n" .
" --connectivity='SI0=MI\\{0,1,2}:SI1=MI{3,4,5}'\n\n" .
" Sparse interconnect declarations. The\n" .
" example above means inport 0 connects\n" .
" to outports 0, 1 and 2, and inport 1\n" .
" connects to outports 3, 4 and 5.\n\n" .
" --arb=SCHEME Arbitration scheme:\n" .
" burst - Fixed priority; Master 0 has\n" .
" highest priority, does not\n" .
" break defined length bursts.\n" .
" fixed - Fixed priority; Master 0 has\n" .
" highest priority.\n" .
" round - Round robin priority; priority\n" .
" goes to next available master.\n\n",
( $Verbose ) ? '' : "\n--- $Scriptname ---\n\n";
# Display option
if ( $ShowArchitectureOptions ) {
print " --arch=VER ARM Processor interface:\n" .
" ahb2 - AMBA2.0 interface.\n" .
" v6 - All ARM V6 extensions.\n" .
" excl - ARM V6 exclusive access\n" .
" extensions only.\n" .
" unalign - ARM V6 unaligned and byte-\n" .
" strobed access extensions\n" .
" only.\n";
}
print " --datawidth=WIDTH Width of data bus ($DataWidths).\n" .
" --addrwidth=WIDTH Width of address bus ($MinAddrWidth..$MaxAddrWidth).\n" .
" --userwidth=WIDTH Width of user signals ($MinUserWidth..$MaxUserWidth).\n\n" .
" --OutputArb=NAME Name of arbitration component\n" .
" (max $MaxNameLength characters).\n" .
" --OutputStage=NAME Name of output stage component\n" .
" (max $MaxNameLength characters).\n" .
" --MatrixDecode=NAME Name of address decoder component(s)\n" .
" (max $MaxNameLength characters).\n" .
" --InputStage=NAME Name of input stage component\n" .
" (max $MaxNameLength characters).\n" .
" --BusMatrix=NAME Name of top level entity\n" .
" (max $MaxNameLength characters).\n\n" .
" --ipxact Alos generates SPIRIT-2009 compatible IPXACT file.\n" .
" --verbose Prints run information.\n" .
" --help Prints this help.\n" .
" --srcdir=DIRNAME Directory name where source files are\n" .
" located (defaults to $SourceDir).\n" .
" --tgtdir=DIRNAME Directory name where RTL files will be\n" .
" generated (defaults to $TargetDir).\n" .
" --xmldir=DIRNAME Directory name where XML configuration\n" .
" files are located (defaults to $XmlDir).\n" .
" --ipxactsrcdir=DIRNAME Directory name where IPXact source files are\n" .
" located (defaults to $IPXactSourceDir).\n" .
" --ipxacttgtdir=DIRNAME Directory name where IPXact files will be\n" .
" generated (defaults to $IPXactTargetDir).\n" .
" --overwrite Overwrites existing bus matrix of the\n" .
" same name.\n" .
" --(no)timescales Adds or suppressed the '`timescale' directive in the rendered Verilog files.\n" .
" --check Disables file generation and just checks the\n" .
" XML configuration file.\n\n";
# Abort session with exit code = 0
exit (0);
}
# ------------------------------------------------------------------------------
# The confidential and proprietary information contained in this file may
# only be used by a person authorised under and to the extent permitted
# by a subsisting licensing agreement from Arm Limited or its affiliates.
#
# (C) COPYRIGHT 2006-2011,2017 Arm Limited or its affiliates.
# ALL RIGHTS RESERVED
#
# This entire notice must be reproduced on all copies of this file
# and copies of this file may only be made by a person if such person is
# permitted to do so under the terms of a subsisting license agreement
# from Arm Limited or its affiliates.
#
# ------------------------------------------------------------------------------
# Version and Release Control Information:
#
# File Name : $RCSfile: xmlparser.pm,v $
#
# SVN Information
#
# Checked In : $Date: 2011-02-21 17:53:53 +0000 (Mon, 21 Feb 2011) $
#
# Revision : $Revision: 162121 $
#
# Release Information : Cortex-M System Design Kit-r1p1-00rel0
#
# ------------------------------------------------------------------------------
# Purpose : Parse XML file input and produce equivalent structure
# hash array, which can be accessed via public methods.
#
# Requirements : Perl version 5.005 or later for thread safety
#
# Limitations : See the POD after the __END__ marker in this file. Try:
#
# pod2text xmlparser.pm | more
#
# ------------------------------------------------------------------------------
eval "exec perl -w -S $0 $@" # -*- Perl -*-
if ($running_under_some_sh);
undef ($running_under_some_sh);
# Declare module name
package xmlparser;
# Declare import modules and libraries
require Exporter;
use strict;
use vars qw( $VERSION @ISA @EXPORT @EXPORT_OK %XmlNodeTree %XmlNodeTotals );
# Declare public and private entities
@ISA = qw( Exporter );
@EXPORT = qw( ConfigureXmlParser
RunXmlParser
ListXmlHash
ChangeRelativePath
GetXmlNodeList
GetXmlValue
GetXmlName
%XmlNodeTotals
%XmlNodeTree );
@EXPORT_OK = qw( %XmlNodeTree );
$VERSION = 1.00;
# Dummy 'lock' routine for non-threaded versions of Perl
BEGIN {
if ( $] < 5.005 ) { eval "sub lock {}"; }
}
# ------------------------------------------------------------------------------
# Script variables
my $DebugMode = 0;
my $RecursionDepth = 0;
my $RecursionLimit = 25;
my $ShowIds = 0;
my $ShowWarnings = 1;
my $Verbose = 1;
my $Warnings = 0;
# Relative access path, serviced by ChangeRelativePath() function
my $RelativePath = '';
# Node stack
my @PathStack = ( 'ROOT' );
my $PathLevel = 0;
# Exportable global data structure and node counters (note that values and
# attributes will be added dynamically when the XML file is parsed)
%XmlNodeTree = ( ROOT => { ITEMS => {ELEMENTS => [], ATTRIBUTES => []} } );
%XmlNodeTotals = ( TOTAL => 0, ELEMENTS => 0, ATTRIBUTES => 0 );
# ------------------------------------------------------------------------------
# PUBLIC: RunXmlParser - Extracts the multi-line value and fields
# ------------------------------------------------------------------------------
sub RunXmlParser {
# Passed parameter 1 is the XML filename
my $XmlFilename = shift;
# Local variable(s)
my $TextLine = '';
my $LineCount = 0;
my $LeadingSpace = 0;
my $Delimeter = '';
my $Before = '';
my $After = '';
my $Field = '';
my $Residue = '';
my $InContainer = 0;
my $GotHeader = 0;
my $HeaderMisaligned = 0;
my $ContainerType = '';
my $Element = '';
my $EmptyElement = 0;
my $InstanceId = 1;
my $Increment = 1;
my $CurrentPath = 'ROOT';
my $ParentPath = 'ROOT';
my $AttributeCount = 0;
my $ParseEnable = 1;
my ($JustFilename) = $XmlFilename =~ /([^\/]+)$/;
# Open the input file
open (INPUT_FILE, "<$XmlFilename") or
ReportError('Cannot open the specified file for reading');
print "Parsing the '$JustFilename' file...\n" if ( $Verbose );
# Process each line of the file
while ( $TextLine = <INPUT_FILE> ) {
# Increment line count
$LineCount++;
# Parse the line(s), when enabled
while ( $ParseEnable ) {
# Remove single line comments, leading or end-of-line whitespace,
# carriage returns, newlines and tab characters. Leading whitespace
# is tracked for checking the <?xml ...?> processing instruction
$TextLine =~ s/<!--.*-->//g;
$LeadingSpace = ( $TextLine =~ s/^\s+// ) ? 1 : 0;
$TextLine =~ s/\s*(\r|\n|\t)$//g;
# Only process lines that are not blank
unless ( $TextLine eq '' ) {
# Display line when in debug mode
if ( $DebugMode ) { printf "Line %-03d: '$TextLine'\n", $LineCount; }
# Reconstruct fields of text (from multiple lines), which are delimited
# by the reserved characters '<' and '>'. Store the extracted tokens
# in the same order as they are processed. A path stack is used to
# determine the name of the current container. All nodes found within
# the scope of the current container are stored in a keyed list (the
# node structure hash array)
if ( ($Delimeter) = $TextLine =~ /([<>])/ ) {
# Store the patterns before and after the delimeter
$Before = $`;
$After = $';
# Determine appropriate action for the '<' delimeter
if ( $Delimeter eq '<' ) {
# Terminate reconstruction of a value field?
if ( ! $InContainer ) {
# Terminate the reconstructed value by concatenating the string
# preceding the '<' delimeter and extracting any residual text
$Field = $Field . $Before;
unless ( $Field eq '' ) {
# Display the value when in debug mode
if ( $DebugMode ) { print "Value of '$Element' = '$Field'\n"; }
# Check and store the extracted value
CheckValue($Field, $LineCount);
$XmlNodeTree{$CurrentPath}{VALUE} = $Field;
# Clear the field ready for a new reconstruction
$Field = '';
}
# Change to the 'in-container' state
$InContainer = 1;
}
# Initiate reconstruction of a container field?
if ( $InContainer ) {
# Initiate reconstruction of a new container by storing it and
# testing for the closing delimeter. If found, then trim the
# field accordingly and extract any residual text, else pad
# the field to support multi-line reconstruction
$Field = $After;
if ( $Field =~ s/>(.*)$// ) {
$After = $1;
$Before = '';
$Delimeter = '>';
} else {
$Field = $Field . ' ';
}
# If '<?xml' is found then check the alignment of the field
unless ( $GotHeader ) {
if ( $TextLine =~ /<\?xml/ ) {
$HeaderMisaligned = ($LineCount > 1 or $LeadingSpace);
}
}
}
}
# Determine appropriate action for the '>' delimeter
if ( $Delimeter eq '>' ) {
# Determine action for this delimeter
if ( ! $InContainer ) {
# Initiate reconstruction of a new value by storing it and
# testing for the opening delimeter. If found, then trim the
# field accordingly and extract any residual text
$Field = $After;
if ( $Field =~ s/<(.*)$// ) { $Residue = '<' . $1; }
} else {
# Terminate the reconstructed container by concatenating the
# remaining portion and smartly formatting the field to simplify
# pattern-matching. Selectively extract and residual text
$Field = TidyXmlContainer($Field . $Before, $LineCount);
$Residue = ( $After ne '' ) ? '>' . $After : '';
# Display the container name when in debug mode
if ( $DebugMode ) { print "Container: '$Field'\n"; }
# Ignore blank fields when produced by the removal of
# multi-line comments
unless ( $Field eq '' ) {
# Check the 'wellformedness' of the reconstructed container
CheckWellformedXml($Field, $LineCount);
# Re-initialise the node reference increment
$Increment = 1;
# Determine container type from beginning of the field, and
# apply appropriate syntax checks
$ContainerType = substr($Field, 0, 1);
if ( $ContainerType eq '?' ) {
# Check processing instructions
if ( $Field =~ /^\?xml/ ) {
unless ( $GotHeader ) {
CheckXmlHeader($Field, $HeaderMisaligned);
$GotHeader = 1;
}
} else {
# Anything else is not supported
ReportError("Unsupported XML processing instruction starting on line $LineCount");
}
} elsif ( $ContainerType eq '!' ) {
# Check declarations
CheckDeclaration($Field, $LineCount);
} elsif ( $ContainerType =~ /[a-z_.\-\/]/i ) {
# Check elements
CheckElement($Field, $LineCount);
# Determine element sub-type
if ( $ContainerType ne '/' ) {
# Extract and remove the element name
$Field =~ s/([a-z0-9_:\.\-]+)\s?//i;
$Element = $1;
# Check if this is an empty element
$EmptyElement = ( $Field =~ /\/$/ ) ? 1 : 0;
# Determine the parent path and then post-increment the path stack pointer
$ParentPath = DetermineStructPath($PathLevel++);
# For this new element, determine its unique current path. If the key is
# unique, then initialise the item lists in the current node record
$InstanceId = 1;
while ( 1 ) {
$PathStack[$PathLevel] = sprintf("%s[%d]", $Element, $InstanceId++);
$CurrentPath = DetermineStructPath($PathLevel);
unless ( exists($XmlNodeTree{$CurrentPath}) ) {
$XmlNodeTree{$CurrentPath}{ITEMS}{ELEMENTS} = [];
$XmlNodeTree{$CurrentPath}{ITEMS}{ATTRIBUTES} = [];
last;
}
}
# Display element name and path information when in debug mode
if ( $DebugMode ) {
printf "Element (%s): '%s'\nPUSH: Appending path: '%s', Parent path: '%s'\n",
$EmptyElement ? 'empty' : 'open', $PathStack[$PathLevel], $CurrentPath, $ParentPath;
}
# Update the item list of the parent node record
push ( @{ $XmlNodeTree{$ParentPath}{ITEMS}{ELEMENTS} }, $PathStack[$PathLevel] );
# Extract attributes and add the count to the node total
$AttributeCount = ExtractAttributes($Field, $CurrentPath);
$XmlNodeTotals{ATTRIBUTES} += $AttributeCount;
# Display number of extracted attributes when in debug mode
if ( $DebugMode ) {
unless ( $AttributeCount == 0 ) {
print "Extracted $AttributeCount attribute(s) from element '$PathStack[$PathLevel]'\n";
}
}
# Selectively decrement the path stack pointer and determine paths
if ( $EmptyElement ) {
$CurrentPath = DetermineStructPath(--$PathLevel);
$ParentPath = DetermineStructPath($PathLevel - 1);
# Display current and parent paths when in debug mode
if ( $DebugMode ) {
print "POP: Current path: '$CurrentPath', Parent path: '$ParentPath'\n";
}
}
} else {
# Decrement the node stack pointer and determine the paths
$CurrentPath = DetermineStructPath(--$PathLevel);
$ParentPath = DetermineStructPath($PathLevel - 1);
# Display paths when in debug mode
if ( $DebugMode ) {
print "POP: Current path: '$CurrentPath', Parent path: '$ParentPath'\n";
}
# Disable the node reference increment for closed elements
$Increment = 0;
}
} else {
# Any other type of field is not supported
ReportError("Unrecognised or illegal XML field starting on line $LineCount");
}
# Increment the node counts
$XmlNodeTotals{ELEMENTS} += $Increment;
$XmlNodeTotals{TOTAL}++;
# Clear the field ready for a new reconstruction and change to
# the 'in-value' state
$Field = '';
$InContainer = 0;
}
}
}
} else {
# Continue to build the field from multiple lines
$Field = $Field . $TextLine;
}
}
# If a second pass is required to process any residual text from the
# first attempt then remain in this loop, else exit the parsing loop
if ( $Residue ne '' ) {
# Display residual text when in debug mode
if ( $DebugMode ) { print "Residue: '$Residue'\n"; }
$TextLine = $Residue;
$Residue = '';
} else {
$ParseEnable = 0;
}
}
# Re-enable parsing for a fresh line of text
$ParseEnable = 1;
}
# Check that the root node is properly terminated upon the EOF
if ( $PathLevel != 0 ) {
ReportError('Unexpected end-of-file due to a syntax error');
}
# Close the XML file
close (INPUT_FILE);
# Display node totals when in verbose mode
if ( $Verbose ) {
printf "Processed %d line(s) with %d warning(s) - extracted %d XML node(s) [%d, @%d]...\n",
$LineCount, $Warnings, $XmlNodeTotals{TOTAL},
$XmlNodeTotals{ELEMENTS}, $XmlNodeTotals{ATTRIBUTES};
}
}
# ------------------------------------------------------------------------------
# TidyXmlContainer - Apply intelligent text formatting to the container
# ------------------------------------------------------------------------------
sub TidyXmlContainer {
# Passed parameter 1 is the container
my $Container = shift;
# Passed parameter 2 is the line number
my $LineNumber = shift;
# Local variable(s)
my $Field = '';
my $Quote = '';
my $Token = '';
my $InQuotes = 0;
# Check for illegal empty container
if ( $Container eq '' ) {
ReportError("Empty XML field starting on line $LineNumber");
}
# Remove multi-line comments and end-of-field or leading whitespace
$Container =~ s/^!--.*--$//;
$Container =~ s/^\s*//;
$Container =~ s/\s*$//g;
# If the container is an element with attributes, then process it with
# respect for embedded whitespace within quoted strings
$Field = $Container;
while ( ($Quote) = $Field =~ /[^=]+=\s*(['"]).*['"]/ ) {
# Selectively clear the container string for recomposition
if ( $InQuotes == 0 ) { $Container = ''; }
# Extract portions of the container between matching quote characters
# and process whitespace on alternate iterations
while ( $Field =~ s/([^$Quote]+)($Quote*)// ) {
$Token = $1 . $2;
unless ( $InQuotes % 1 ) {
$Token =~ s/\s+/ /g;
$Token =~ s/\s?=\s?/=/g;
}
$Container = $Container . $Token;
$InQuotes++;
}
}
return ($Container);
}
# ------------------------------------------------------------------------------
# CheckWellformedXml - Check the 'wellformedness' of the container
# ------------------------------------------------------------------------------
sub CheckWellformedXml {
# Passed parameter 1 is the container
my $Container = shift;
# Passed parameter 2 is the line number
my $LineNumber = shift;
# Local variable(s)
my $BadProcInstr = ( $Container =~ /^\?/ and
$Container !~ /\?$/ ) ? 1 : 0;
my $BadDecl = ( $Container =~ /^\!/ and
$Container =~ /[\!\?\/]$/ ) ? 1 : 0;
my $BadOpenElement = ( $Container =~ /^[a-z_.\-]/i and
$Container !~ /\/?$/ ) ? 1 : 0;
my $BadCloseElement = ( $Container =~ /^\// and
$Container =~ /(=|\/$)/ ) ? 1 : 0;
# Check and display an error if invalid
if ( $BadProcInstr or $BadDecl or $BadOpenElement or $BadCloseElement ) {
ReportError("XML field starting on line $LineNumber is not well-formed");
}
}
# ------------------------------------------------------------------------------
# CheckXmlHeader - Validate the <?xml ...?> header container
# ------------------------------------------------------------------------------
sub CheckXmlHeader {
# Passed parameter 1 is the header
my $Header = shift;
# Passed parameter 2 is the alignment error flag
my $Misaligned = shift;
# Local variable(s)
my $XMLVersion = '1.0 (default)';
my $XMLEncoding = 'iso-8859-1 (default)';
my $XMLMode = 'yes (default)';
# Announce the header check
print "Validating XML header...\n" if ( $Verbose );
# Check the mis-alignment flag
if ( $Misaligned ) {
ReportError("The '?xml' declaration must start on line 1, column 1");
}
# Check syntax of supported attributes
if ( ($Header !~ /^\?xml[\s\?]/) or
($Header !~ /((version|encoding|standalone)=("[^"]+"|'[^']+'))*/) ) {
ReportError("Invalid '<?xml ...?>' processing instruction");
}
# Check version, encoding and standalone (mode) attributes
if ( $Header =~ /version=("[^"]+"|'[^']+')/ ) {
$XMLVersion = $1; $XMLVersion =~ s/["']//g;
if ($XMLVersion ne '1.0') {
ReportError('Unsupported XML version');
}
}
if ( $Header =~ /encoding=("[^"]+"|'[^']+')/ ) {
$XMLEncoding = $1; $XMLEncoding =~ s/["']//g;
if ( $XMLEncoding !~ /^(iso\-8859\-1|UTF\-8)$/ ) {
ReportError('Unsupported XML encoding');
}
}
if ( $Header =~ /standalone=("[^"]+"|'[^']+')/ ) {
$XMLMode = $1; $XMLMode =~ s/["']//g;
if ( $XMLMode !~ /(yes|no)\b/ ) {
ReportError('Unsupported standalone declaration');
}
}
# Display header settings
print "XML version '$XMLVersion', encoding '$XMLEncoding', standalone" .
" '$XMLMode'...\n" if ( $Verbose );
}
# ------------------------------------------------------------------------------
# CheckDeclaration - Validate the <!... > declaration container
# NOTE: This procedure needs further work if required
# ------------------------------------------------------------------------------
sub CheckDeclaration {
# Passed parameter 1 is the container
my $Container = shift;
# Passed parameter 2 is the line number
my $LineNumber = shift;
# Local variable(s)
my $DeclarationType = '';
# Check and display an error if invalid
if ( ($DeclarationType) = $Container !~ /^\!(DOCTYPE|ENTITY)\b/ ) {
ReportError("Unrecognised XML declaration starting on line $LineNumber");
}
}
# ------------------------------------------------------------------------------
# CheckElement - Validate the element container
# ------------------------------------------------------------------------------
sub CheckElement {
# Passed parameter 1 is the container
my $Container = shift;
# Passed parameter 2 is the line number
my $LineNumber = shift;
# Local variable(s)
my $ElementName = '';
my $AttributeName = '';
my $AttributeValue = '';
my $StartQuote = '';
my $EndQuote = '';
my $ForbiddenQuote = '';
my %Names = ();
# Extract and remove the element name, then check it for illegal
# chacters
$Container =~ s/^\/?([^\s]+)\s?//;
$ElementName = $1;
if ( $ElementName =~ /[^a-z0-9_:\.\-]/i ) {
ReportError("XML element starting on line $LineNumber has an illegal name");
}
# If defined, check attributes of element fields. Extract, remove
# and test the LHS and RHS fields of '=' assignments in turn
while ( $Container =~ s/([^=]+)=(['"])// ) {
$AttributeName = $1; $StartQuote = $2;
$ForbiddenQuote = ($StartQuote eq '"') ? '"' : "'";
# Check the attribute name for illegal characters
if ( $AttributeName =~ /[^a-z0-9_:\.\-]/i ) {
ReportError("XML element starting on line $LineNumber has an illegal attribute name");
}
# Check the attribute name for duplicates and note unique ones
if ( exists($Names{$AttributeName}) ) {
ReportError("XML element starting on line $LineNumber has a duplicate attribute name");
}
$Names{$AttributeName} = ''; # Value unimportant for purpose
# Extract and remove the attribute value, restoring the container
# field appropriately for the next iteration
if ( $Container =~ s/([^=]+)// ) {
$AttributeValue = $1;
$AttributeValue =~ s/(['"])\s?([^'"]*)$//;
$EndQuote = $1; $Container = $2 . $Container;
# Check the attribute value for illegal characters
if ( $AttributeValue =~ /[<>$ForbiddenQuote]/ or
($AttributeValue =~ /&/ and
$AttributeValue !~ /&(amp|lt|gt|apos|quot|\#[0-9]{3}|\#x[A-Fa-f0-9]{2});/) ) {
ReportError("XML element starting on line $LineNumber has an illegal attribute value");
}
# Check for misquoted attribute value
unless ( $StartQuote eq $EndQuote ) {
ReportError("XML element starting on line $LineNumber has a misquoted attribute value");
}
}
}
}
# ------------------------------------------------------------------------------
# CheckValue - Check the XML value field for illegal characters
# ------------------------------------------------------------------------------
sub CheckValue {
# Passed parameter 1 is the value
my $Field = shift;
# Passed parameter 2 is the line number
my $LineNumber = shift;
# Local variable(s)
my $BadLTGT = ( $Field =~ /[<>]/ ) ? 1 : 0;
my $BadAmpersand = ( $Field =~ /&/ and
$Field !~ /&(amp|lt|gt|apos|quot|\#[0-9]{3}|\#x[A-Fa-f0-9]{2});/ ) ? 1 : 0;
# Check and display an error if invalid
if ( $BadLTGT or $BadAmpersand ) {
ReportError("XML value field starting on line $LineNumber contains illegal characters");
}
}
# ------------------------------------------------------------------------------
# ExtractAttributes - Inspect and extract the attributes from elements
# ------------------------------------------------------------------------------
sub ExtractAttributes {
# Passed parameter 1 is the container
my $Container = shift;
# Passed parameter 2 is the current path
my $Path = shift;
# Local variable(s)
my $Attributes = 0;
my $AttributeName = '';
my $AttributeValue = '';
# If defined, check attributes of element fields. Extract, remove
# and test the LHS and RHS fields of '=' assignments in turn
while ( $Container =~ s/([^=]+)=['"]// ) {
# Store the attribute name
$AttributeName = $1;
# Extract and remove the attribute value, restoring the container
# field appropriately for the next iteration
if ( $Container =~ s/([^=]+)// ) {
$AttributeValue = $1;
$AttributeValue =~ s/['"]\s?([^'"]*)$//;
$Container = $1 . $Container;
# Update the item list in the current node record and then save
# both the attribute name and its value
push ( @{ $XmlNodeTree{$Path}{ITEMS}{ATTRIBUTES} }, $AttributeName );
$XmlNodeTree{$Path}{ATTRIBUTES}{$AttributeName} = $AttributeValue;
$Attributes++;
}
}
return ($Attributes);
}
# ------------------------------------------------------------------------------
# PUBLIC: ListXmlHash - List contents of the structure, using safe recursion
# ------------------------------------------------------------------------------
sub ListXmlHash {
# Passed parameter 1 is the requested node start point
my $NodeKey = shift;
# Local variable(s)
my ($NodeName) = $NodeKey =~ /([^{]+)$/;;
my @NodeKeys = @{ $XmlNodeTree{$NodeKey}{ITEMS}{ELEMENTS} };
my $NodeValue = $XmlNodeTree{$NodeKey}{VALUE};
my $NodeItem = '';
my @Markup = ('', '@');
# Initially display the 'listing structure' message
if ( $RecursionDepth == 0 ) { print "Listing the data structure:\n\n"; }
# Remove the reference number from the node name
unless ( $ShowIds ) { $NodeName = GetXmlName($NodeName); }
# Display the element name and optional value
if ( not defined $NodeValue ) {
printf " %s- $NodeName\n", ' ' x ($RecursionDepth * 2);
} else {
printf " %s- $NodeName = '$NodeValue'\n", ' ' x ($RecursionDepth * 2);
}
# Selectively display attributes
foreach $NodeItem ( @{ $XmlNodeTree{$NodeKey}{ITEMS}{ATTRIBUTES} } ) {
printf " %s%s$NodeItem %s= '$XmlNodeTree{$NodeKey}{ATTRIBUTES}{$NodeItem}'\n",
' ' x ($RecursionDepth * 2), $Markup[1 - $ShowIds], $Markup[$ShowIds];
}
# List content of the current node by recursion within limits
foreach $NodeItem ( @NodeKeys ) {
if ( ++$RecursionDepth > $RecursionLimit ) {
ReportError("Recursion depth of $RecursionLimit exceeded");
} else {
# Interrogate the next level of the hierarchy
ListXmlHash("$NodeKey}{$NodeItem");
}
$RecursionDepth--;
}
}
# ------------------------------------------------------------------------------
# DetermineStructPath - Determine the structure path key
# ------------------------------------------------------------------------------
sub DetermineStructPath {
# Passed parameter 1 is the level
my $RequestedLevel = shift;
# Local variable(s)
my $LevelPointer = 0;
my $Result = 'ROOT';
# Build the path and remove the outermost pair of braces, else return
# the root node
if ( $RequestedLevel > 0 ) {
$Result = '';
while ( $LevelPointer <= $RequestedLevel ) {
$Result = $Result . '{' . $PathStack[$LevelPointer++] . '}';
}
$Result =~ s/(^{|}$)//g;
}
return ($Result);
}
# ------------------------------------------------------------------------------
# 'TranslateXPath' - Translates the specified XPath into the nearest match
# access key
# ------------------------------------------------------------------------------
sub TranslateXPath {
# Passed parameter 1 is the specified XPath
my $Path = shift;
# Local variable(s)
my @XPathTokens = [];
my $Token = '';
my $Key = '';
my $ResolvedPath = 'ROOT';
if ( $Path =~ s/^\/// ) {
# Determine the key lookup for absolute paths
@XPathTokens = split('/', $Path);
foreach $Token ( @XPathTokens ) {
foreach $Key ( @{ $XmlNodeTree{$ResolvedPath}{ITEMS}{ELEMENTS} } ) {
if ( $Key eq $Token or $Key =~ /$Token/ ) {
$ResolvedPath = $ResolvedPath . '}{' . $Key;
last;
}
}
}
$Path = $ResolvedPath;
} else {
ReportError('Unsupported or badly formed XPath');
}
# Display the translated access key when in debug mode
if ( $DebugMode ) { print "Key: '$Path'\n"; }
return ($Path);
}
# ------------------------------------------------------------------------------
# PUBLIC: 'GetXmlName' - Returns the XML node name without uniquifier(s)
# ------------------------------------------------------------------------------
sub GetXmlName {
# Passed parameter 1 is the specified XML node
my $XmlNode = shift;
$XmlNode =~ s/\[\d+\]//g;
return ($XmlNode);
}
# ------------------------------------------------------------------------------
# PUBLIC: 'ChangeRelativePath' - Sets and returns the relative path
# ------------------------------------------------------------------------------
sub ChangeRelativePath {
# Passed parameter 1 is the specified path stem
$RelativePath = shift;
return ($RelativePath);
}
# ------------------------------------------------------------------------------
# PUBLIC: 'GetXmlNodeList' - Return child node list for the specified parent
# node. Append '@' character to get attributes
# ------------------------------------------------------------------------------
sub GetXmlNodeList {
# Passed parameter 1 is the requested node
my $NodeKey = shift;
# Local variable(s)
my $NodeType = ( $NodeKey =~ s/@// ) ? 'ATTRIBUTES' : 'ELEMENTS';
my $ParentKey = '';
my $Key = '';
my $MatchNode = '';
my @Nodes = ();
# Determine nodename search or specific lookup
if ( $NodeKey =~ s/^\/\//\// ) {
# Translate the XPath, then split it into the parent key and search element
$ParentKey = TranslateXPath($NodeKey);
if ( $ParentKey =~ s/\}\{([a-z0-9\.\-\_]+)\[1\]$// ) { $MatchNode = $1; }
# Conditionally search for matching keys and store full paths of matches
unless ( $MatchNode eq '' or $NodeKey !~ /$MatchNode$/ ) {
foreach $Key ( @{ $XmlNodeTree{$ParentKey}{ITEMS}{$NodeType} } ) {
if ( $Key =~ /$MatchNode\[\d+\]/ ) { push @Nodes, "$ParentKey}{$Key"; }
}
}
} else { # Specific look-up
# Conditionally prepend the current relative path
unless ( $NodeKey =~ /^ROOT/ ) { $NodeKey = $RelativePath . $NodeKey; }
# Translate XPaths when specified
if ( $NodeKey =~ /\// ) { $NodeKey = TranslateXPath($NodeKey); }
# Lookup listing node if it exists
if ( exists($XmlNodeTree{$NodeKey}{ITEMS}{$NodeType}) ) {
@Nodes = @{ $XmlNodeTree{$NodeKey}{ITEMS}{$NodeType} };
} elsif ( $ShowWarnings ) {
ReportWarning('Unable to get node list due to non-existent access path');
}
}
# Display a list of nodes when in debug mode
if ( $DebugMode ) { foreach $Key ( @Nodes) { print "List node: '$Key'\n"; } }
return ( @Nodes );
}
# ------------------------------------------------------------------------------
# PUBLIC: 'GetXmlValue' - Extract the value of the specified element.
# Prepend '@' character before name to get attributes
# ------------------------------------------------------------------------------
sub GetXmlValue {
# Passed parameter 1 is the requested node start point
my $NodeKey = shift;
# Local variable(s)
my $Attribute = ( $NodeKey =~ s/@(.+)$// ) ? $1 : '';
my $Value = '';
my $NoValue = '';
# Conditionally prepend the current relative path
unless ( $NodeKey =~ /^ROOT/ ) { $NodeKey = $RelativePath . $NodeKey; }
# Translate XPaths when specified
if ( $NodeKey =~ /\// ) { $NodeKey = TranslateXPath($NodeKey); }
# Lookup the value or attribute node if it exists. It must be coded like this
# to avoid non-existent keys from being incorrectly added to the hash as a
# side effect of the 'exists()' function
if ( exists($XmlNodeTree{$NodeKey}) ) {
# Now check and extract the element or attribute value
if ( $Attribute ne '' ) {
if ( exists($XmlNodeTree{$NodeKey}{ATTRIBUTES}{$Attribute}) ) {
$Value = $XmlNodeTree{$NodeKey}{ATTRIBUTES}{$Attribute};
unless ( defined($Value) ) { $Value = $NoValue; }
} elsif ( $ShowWarnings ) {
ReportWarning('Access attempted to a non-existent attribute name');
}
} else {
$Value = exists( $XmlNodeTree{$NodeKey}{VALUE} ) ?
$XmlNodeTree{$NodeKey}{VALUE} : $NoValue;
}
} elsif ( $ShowWarnings ) {
ReportWarning("Access attempted to a non-existent element '$NodeKey'");
}
# Perform substitution of ampersand fields
if ( $Value =~ /&(quot|apos|lt|gt|amp|#x?[A-Fa-f0-9]+);/ ) {
$Value =~ s/&quot;/"/g;
$Value =~ s/&apos;/'/g;
$Value =~ s/&lt;/</g;
$Value =~ s/&gt;/>/g;
$Value =~ s/&amp;/&/g;
$Value =~ s/&#([A-Fa-f0-9]{3});/chr( scalar $1 )/ge; # Only UTF-8!
$Value =~ s/&#x([A-Fa-f0-9]{2});/chr( hex( scalar $1 ) )/ge; # Only UTF-8!
}
return ( $Value );
}
# ------------------------------------------------------------------------------
# PUBLIC: 'ConfigureXmlParser' - Configure aspects of module behaviour
# ------------------------------------------------------------------------------
sub ConfigureXmlParser {
# Passed parameter 1 is the hash array of options
my %XmlParserOptions = @_;
# Local variable(s)
my @Keys = keys( %XmlParserOptions );
my $Item = '';
my $Result = 0;
# Extract values and execute requested actions
foreach $Item ( @Keys ) {
if ($Item eq 'debug_mode' and $XmlParserOptions{$Item} ) {
$DebugMode = 1;
} elsif ( $Item eq 'recursion_limit' and $XmlParserOptions{$Item} > 0 ) {
$RecursionLimit = $XmlParserOptions{$Item};
} elsif ( $Item eq 'reset' and $XmlParserOptions{$Item} ) {
%XmlNodeTree = ( ROOT => { ITEMS => {ELEMENTS => [], ATTRIBUTES => []} } );
%XmlNodeTotals = ( TOTAL => 0, ELEMENTS => 0, ATTRIBUTES => 0 );
@PathStack = ( 'ROOT' );
$PathLevel = 0;
$RelativePath = '';
} elsif ( $Item eq 'show_ids' ) {
$ShowIds = ( $XmlParserOptions{$Item} ) ? 1 : 0;
} elsif ( $Item eq 'show_warnings' ) {
$ShowWarnings = ( ! $XmlParserOptions{$Item} ) ? 0 : 1;
} elsif ( $Item eq 'verbose' ) {
$Verbose = ( $XmlParserOptions{$Item} ) ? 1 : 0;
} else {
$Result = 1; # Flag a return code error
}
}
return ( $Result );
}
# ------------------------------------------------------------------------------
# ReportError - Reports an error message on STDOUT and forces exit(1)
# ------------------------------------------------------------------------------
sub ReportError {
# Passed parameter 1 is the error message
my $ErrorMessage = shift;
print "ERROR (xmlparser): $ErrorMessage - aborting!\n\n";
exit 1;
}
# ------------------------------------------------------------------------------
# ReportWarning - Reports a warning message on STDOUT
# ------------------------------------------------------------------------------
sub ReportWarning {
# Passed parameter 1 is the warning message
my $WarningMessage = shift;
print "WARNING (xmlparser): $WarningMessage!\n\n";
$Warnings++;
}
1;
__END__
# ------------------------------------------------------------------------------
# POD section (formatting is sensitive to blankline whitespace!)
# ------------------------------------------------------------------------------
=pod
=head1 NAME
xmlparser - Standalone XML parser with hash array output
=head1 SYNOPSIS
Example usage:
# Reference the module
use xmlparser;
# Configure parser options, parse the file and list its structure
ConfigureXmlParser( verbose => 0, reset => 1 );
RunXmlParser('my.xml');
ListXmlHash('ROOT');
# Access specific groups of elements
my @MyElements = GetXmlNodeList('/myxml/mynames');
my $Element = '';
my $Attribute = '';
foreach $Element ( @MyElements ) {
ChangeRelativePath('/myxml/mynames/');
printf "Element '%s'='%s'\n", GetXmlName($Element), GetXmlValue($Element);
foreach $Attribute ( GetXmlNodeList("\@$Element") ) {
ChangeRelativePath("/myxml/mynames/$Element/");
printf "Attribute '$Attribute'='%s'\n", GetXmlValue("\@$Attribute");
}
}
=head1 DESCRIPTION
In the absence of complete documentation, this section contains the
best source of information.
=head2 DOCUMENTATION
Documentation about this module does not yet exist for developers
within ARM Limited, but this section will provide essential clues
to the usage.
=head2 PRINCIPLES
This multi-line parser will extract elements and value text separated
by <tagged_delimeters>. XML directives and declarations are treated as
exceptions and these values will not be added to the hash array.
The parsing algorithm alternates between these two states:
=over 3
=item 1.
Accumulate value fields until detection of '<' character and
then change to the 'in-container' state.
=item 2.
Accumulate element fields until detection of '>' character and
then change to the 'in-value' state if an end of element is detected.
=back
Upon successfully identifying the closing brace of an element field,
a new item is added to the child element list at the current level of
hierarchy. A new hash key, bearing the element name, is added and
the new hierarchical path is pushed onto the stack. For hierarchical
reference, the current path and parent path are updated. Attributes
are extracted and placed into a separate key-value node, using the
same principles. The parser changes state to accumulate text fields.
Upon closure of the element container, i.e. the next opening brace,
the accumulated text is assigned as the value of the current element.
Also upon this event, the path stack is popped and hierarchical paths
are re-evaluated. Every extracted field is checked for legal composition.
Elements and attributes are checked for wellformedness.
The following example will show the relationship:
B<XML source:>
<cfgfile>
<my_element animal="dog"/>
<my_element>
cat
</my_element>
</cfgfile>
B<Storage structure:>
my %XmlNodeTree = (
ROOT => {
ITEMS => {
ELEMENTS => [ cfgfile[1] ],
ATTRIBUTES => []
}
}
ROOT}{cfgfile[1] => {
ITEMS => {
ELEMENTS => [ my_element[1], my_element[2] ],
ATTRIBUTES => []
}
}
ROOT}{cfgfile[1]}{my_element[1] => {
ITEMS => {
ELEMENTS => [],
ATTRIBUTES => [ animal ]
}
ATTRIBUTES => {
animal => 'dog'
}
}
ROOT}{cfgfile[1]}{my_element[2] => {
ITEMS => {
ELEMENTS => [],
ATTRIBUTES => []
}
VALUE => 'cat'
}
);
B<Extracted structure:>
- ROOT
- cfgfile
- my_element
@value = 'dog'
- my_element = 'cat'
Note that data is stored in the hash array using a pseudo hierarchical
method. This makes it very simple to use grep when needing to find
specifically named elements.
To interrogate the hash array, it is recommended to use the public
access functions GetXmlNodes() and GetXmlValue(). These functions will
translate a basic XPath notation into keys for hash access and perform
substitution of escaped character sequences.
=head1 FUNCTIONS
Currently, there are only a few public methods available. This section
describes each one.
=head2 ConfigureXmlParser(<key-value pairs>)
Use this procedure to modify the behaviour of the parser, e.g. to reset
the hash array. It accepts the following key-value pairs, also shown in
the above example:
=over 3
=item *
debug_mode => <integer: 0|1> - show debugging information.
=item *
recursion_limit => <integer: 1..n> - for the B<ListXmlHash()> fn.
=item *
reset => <integer: 0|1> - resets the hash and stack.
=item *
verbose => <integer: 0|1> - modifies verbosity, e.g. quiet mode.
=item *
show_ids => <integer: 0|1> - shows actual hash keynames.
=item *
show_warnings => <integer: 0|1> - control reports of warnings.
=back
Further options may be added over time.
=head2 RunXmlParser(<xml_filename>)
Use this procedure to read in the specified XML file. Ensure that
you reset the hash array before attempting to read another file - see
B<ConifigureXmlParser()>.
=head2 ListXmlHash(<starting_key>)
Use this procedure to verify the extraction process. All data is
contained under the B<'ROOT'> node, so this is often the only key
that you should specify.
=head2 ChangeRelativePath(<xpath or key>)
This function sets the relative path to be prepended to the specified
argument when calling the B<GetXmlNodeList()> and B<GetXmlValue()>
public access functions. Building XPaths and keys is more managable
this way.
=head2 GetXmlNodeList(<xpath or key>)
Use this function to obtain the list of child elements or a list of
attributes under the specified hierarchical level. By specifying the
'@' character in the XPath or at the end of the key, you can request
attributes instead of elements. Access to a non-existent xpath or key
will return a zero-item list.
=head2 GetXmlValue(<xpath or key>)
Use this function to obtain the value of the element or attribute
under the specified hierarchical level. By specifying the '@' character
at the start of the attribute name (i.e. the rightmost item in the
XPath or key), you can request attributes instead of elements. Access
to a non-existent xpath or key will return a zero-length string. Access
to elements or attributes without value will return a zero-length string.
The following 'escaped' characters will be substituted to their
true ASCII character:
=over 3
=item *
&quot; -> "
=item *
&apos; -> '
=item *
&lt; -> <
=item *
&gt; -> >
=item *
&amp; -> &
=item *
&#x<2_hex_chars>; -> equivalent hexadecimal character
=item *
&#<3_dec_chars>; -> equivalent decimal character
=back
=head2 GetXmlName(<item string>)
Removes the uniquifying index from the hash key item and returns the
originally named item.
=head2 Direct hash access
Knowing the format of key structure will allow you to perform access
to the hash array directly. You always need to know something about the
information structure in order to specify an XPath or key. This is
true even when letting XSLT do the work!
With reference to the example shown above, to access the 2nd element,
you would need to recreate this key:
# Direct access of an element
my $Value = $XmlNodeTree{'ROOT}{cfgfile[1]}{my_element[2]'}{VALUE};
# Direct access of an attribute
my $Attribute = $XmlNodeTree{'ROOT}{cfgfile[1]}{my_element[1]'}{ATTRIBUTES}{animal};
To access the desired positional element without hardcoding the node
keys, you could try resolving this through the appropriate ITEMS array
which records the ordering of all child items at the access level.
Examples of this are shown below:
# Set-up
use xmlparser; # Load the XML parser module
use xmlparser qw ( %XmlNodeTree ); # Request direct hash access
# Indirectly access the 2nd 'my_element' element
my $EI = $XmlNodeTree{'ROOT}{cfgfile[1]'}{ITEMS}{ELEMENTS}[1];
my $Value = $XmlNodeTree{"ROOT}{cfgfile[1]}{$EI"}{VALUE};
# Indirectly access the 1st attribute of the 1st element
my $EI = $XmlNodeTree{'ROOT}{cfgfile[1]'}{ITEMS}{ELEMENTS}[0];
my $AI = $XmlNodeTree{"ROOT}{cfgfile[1]}{$EI"}{ITEMS}{ATTRIBUTES}[0];
my $Value = $XmlNodeTree{"ROOT}{cfgfile[1]}{$EI"}{ATTRIBUTES}{$AI};
As will be appreciated, this is quite complicated! Therefore it is
better to use the public access functions for ease of use. Your choice.
=head1 SUPPORT
The following support issues are noted under this section.
=head2 Regarding XML
This is a lightweight parser, compliant to only a subset of the
XML 1.0 standard. Namespaces are supported at a basic level, that
is, the ':' character is permitted in element names. The following
support issues are defined below:
=over 3
=item 1.
The ENTITY declaration is not fully implemented and there is no
preprocessor for expanding macros instantiated by the '&MyFile;'
notation.
=item 2.
The DOCTYPE declaration is not fully implemented and there is no
support for DTD or XML-Schema. Checks can be performed efficiently
by writing a customised checking procedure within the PERL domain.
=item 4.
Only the '<?xml ?>' processing instruction is supported as far as
basic validation.
=item 5.
Only character sets 'iso-8859-1' and 'UTF-8' are accepted in the
header check.
=item 6.
Elements embedded in the <emphasis>middle</emphasis> of value fields,
like the 'emphasis' tag you have just read, are not supported. It will
truncate the text value and prepend the remainder to the value of the
next element.
=back
=head2 Regarding XPath and XPointer
The XPath facility of the public access functions is only a basic
provision. It only translates very simple XPaths into access-key
notation, and it does not support any of the XPath functions. The
XPointer notation allows indexed dereferencing of specific elements.
This is sufficient to get the values of elements and attributes.
Some examples of XPath and XPointer interpretations are shown below:
'/myxml' = 'ROOT}{myxml[1]' # Absolute
'/myxml[1]' = 'ROOT}{myxml[1]'
'myxml' = 'myxml[1]' # Relative
'myxml[2] = 'myxml[2]'
'//myxml' = [ 'ROOT}{myxml[1]' 'ROOT}{myxml[2]' ... ] # Search
Generally speaking, the relationship is to convert '/' characters into
'}{' brace-pairs, and to assume the first item when resolving non-indexed
references.
=head1 STATUS
This version (1.00) is the current initial version, dated 11th January 2007.
=head1 SEE ALSO
This is a customised standalone module. There are no references to other
modules from the developers community. Information for developers may be
obtained through internal ARM documentation.
=head1 COPYRIGHT
Copyright 2006 ARM Limited. All rights reserved <support@arm.com>
This library is free software; you can redistribute it and/or modify it
under the same terms as Perl itself. However, because this file is supplied
to support licenced IP from ARM Limited, please carefully check the terms
and conditions defined in your legal agreement with ARM Limited.
=cut
bin/BuildBusMatrix.pl -notimescales -xmldir xml -cfg soclabs_ahb32_4x7.xml -ipxact -ipxactsrcdir=ipxact/src -ipxacttgtdir=ipxact/built -over -verbose >& soclabs_ahb32_4x7.log
<?xml version="1.0" encoding="UTF-8"?>
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
<!-- The confidential and proprietary information contained in this file may -->
<!-- only be used by a person authorised under and to the extent permitted -->
<!-- by a subsisting licensing agreement from ARM Limited or its affiliates. -->
<!-- -->
<!-- (C) COPYRIGHT 2001-2017 ARM Limited or its affiliates. -->
<!-- ALL RIGHTS RESERVED -->
<!-- -->
<!-- This entire notice must be reproduced on all copies of this file -->
<!-- and copies of this file may only be made by a person if such person is -->
<!-- permitted to do so under the terms of a subsisting license agreement -->
<!-- from ARM Limited or its affiliates. -->
<!-- -->
<!-- SVN Information -->
<!-- -->
<!-- Checked In : $Date: 2017-10-10 15:55:38 +0100 (Tue, 10 Oct 2017) $ -->
<!-- -->
<!-- Revision : $Revision: 371321 $ -->
<!-- -->
<!-- Release Information : Cortex-M System Design Kit-r1p1-00rel0 -->
<!-- -->
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
<!-- Purpose : IP-XACT description for the main top of <<bus_matrix_name>> -->
<!-- -->
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
<spirit:component xmlns:spirit="http://www.spiritconsortium.org/XMLSchema/SPIRIT/1685-2009"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.spiritconsortium.org/XMLSchema/SPIRIT/1685-2009 http://www.spiritconsortium.org/XMLSchema/SPIRIT/1685-2009/index.xsd">
<spirit:vendor>arm.com</spirit:vendor>
<spirit:library>CoreLink</spirit:library>
<spirit:name><<bus_matrix_name>></spirit:name>
<spirit:version>r0p0_0</spirit:version>
<spirit:busInterfaces>
<!--Slave interfaces -->
//---------------------------------------- << start in >> ---------------------------------------
<spirit:busInterface>
<spirit:name>AHBLiteTarget_Slave_<<si_name>></spirit:name>
<spirit:description>Slave port <<si_name>></spirit:description>
<spirit:busType spirit:library="AMBA3" spirit:name="AHBLiteTarget" spirit:vendor="amba.com" spirit:version="r2p0_0"/>
<spirit:abstractionType spirit:library="AMBA3" spirit:name="AHBLiteTarget_rtl" spirit:vendor="amba.com" spirit:version="r2p0_0"/>
<spirit:slave>
<spirit:memoryMapRef spirit:memoryMapRef="AHBLiteTarget_Slave_<<si_name>>_MM"/>
//---------------------------------------- << start out >> --------------------------------------
//------------------------------------- << start connection >> ------------------------------------
<spirit:bridge spirit:masterRef="AHBLiteTarget_Master_<<mi_name>>" spirit:opaque="true"/>
//------------------------------------- << end connection >> --------------------------------------
//---------------------------------------- << end out >> ----------------------------------------
</spirit:slave>
<spirit:portMaps>
<!-- Clock/reset -->
<spirit:portMap>
<spirit:logicalPort>
<spirit:name>HCLK</spirit:name>
</spirit:logicalPort>
<spirit:physicalPort>
<spirit:name>HCLK</spirit:name>
</spirit:physicalPort>
</spirit:portMap>
<spirit:portMap>
<spirit:logicalPort>
<spirit:name>HRESETn</spirit:name>
</spirit:logicalPort>
<spirit:physicalPort>
<spirit:name>HRESETn</spirit:name>
</spirit:physicalPort>
</spirit:portMap>
<!-- Inputs -->
<spirit:portMap>
<spirit:logicalPort>
<spirit:name>HSELx</spirit:name>
</spirit:logicalPort>
<spirit:physicalPort>
<spirit:name>HSEL<<si_name>></spirit:name>
</spirit:physicalPort>
</spirit:portMap>
<spirit:portMap>
<spirit:logicalPort>
<spirit:name>HADDR</spirit:name>
</spirit:logicalPort>
<spirit:physicalPort>
<spirit:name>HADDR<<si_name>></spirit:name>
</spirit:physicalPort>
</spirit:portMap>
<spirit:portMap>
<spirit:logicalPort>
<spirit:name>HTRANS</spirit:name>
</spirit:logicalPort>
<spirit:physicalPort>
<spirit:name>HTRANS<<si_name>></spirit:name>
</spirit:physicalPort>
</spirit:portMap>
<spirit:portMap>
<spirit:logicalPort>
<spirit:name>HWRITE</spirit:name>
</spirit:logicalPort>
<spirit:physicalPort>
<spirit:name>HWRITE<<si_name>></spirit:name>
</spirit:physicalPort>
</spirit:portMap>
<spirit:portMap>
<spirit:logicalPort>
<spirit:name>HSIZE</spirit:name>
</spirit:logicalPort>
<spirit:physicalPort>
<spirit:name>HSIZE<<si_name>></spirit:name>
</spirit:physicalPort>
</spirit:portMap>
<spirit:portMap>
<spirit:logicalPort>
<spirit:name>HBURST</spirit:name>
</spirit:logicalPort>
<spirit:physicalPort>
<spirit:name>HBURST<<si_name>></spirit:name>
</spirit:physicalPort>
</spirit:portMap>
<spirit:portMap>
<spirit:logicalPort>
<spirit:name>HPROT</spirit:name>
//---------------------------------------- << start excl >> -------------------------------------
<spirit:vector>
<spirit:left>3</spirit:left>
<spirit:right>0</spirit:right>
</spirit:vector>
//---------------------------------------- << end excl >> -------------------------------------
</spirit:logicalPort>
<spirit:physicalPort>
<spirit:name>HPROT<<si_name>></spirit:name>
//---------------------------------------- << start excl >> -------------------------------------
<spirit:vector>
<spirit:left>3</spirit:left>
<spirit:right>0</spirit:right>
</spirit:vector>
//---------------------------------------- << end excl >> -------------------------------------
</spirit:physicalPort>
</spirit:portMap>
//---------------------------- << start unalign >> -----------------------------
<!-- HUNALIGN<<si_name>> unmapped -->
<!-- HBSTRB<<si_name>> unmapped -->
//----------------------------- << end unalign >> ------------------------------
<!-- HMASTER<<si_name>> unmapped -->
<spirit:portMap>
<spirit:logicalPort>
<spirit:name>HWDATA</spirit:name>
</spirit:logicalPort>
<spirit:physicalPort>
<spirit:name>HWDATA<<si_name>></spirit:name>
</spirit:physicalPort>
</spirit:portMap>
<spirit:portMap>
<spirit:logicalPort>
<spirit:name>HMASTLOCK</spirit:name>
</spirit:logicalPort>
<spirit:physicalPort>
<spirit:name>HMASTLOCK<<si_name>></spirit:name>
</spirit:physicalPort>
</spirit:portMap>
<spirit:portMap>
<spirit:logicalPort>
<spirit:name>HREADY</spirit:name>
</spirit:logicalPort>
<spirit:physicalPort>
<spirit:name>HREADY<<si_name>></spirit:name>
</spirit:physicalPort>
</spirit:portMap>
//---------------------------------------- << start user >> -------------------------------------
<spirit:portMap>
<spirit:logicalPort>
<spirit:name>HAUSER</spirit:name>
</spirit:logicalPort>
<spirit:physicalPort>
<spirit:name>HAUSER<<si_name>></spirit:name>
</spirit:physicalPort>
</spirit:portMap>
<spirit:portMap>
<spirit:logicalPort>
<spirit:name>HWUSER</spirit:name>
</spirit:logicalPort>
<spirit:physicalPort>
<spirit:name>HWUSER<<si_name>></spirit:name>
</spirit:physicalPort>
</spirit:portMap>
//---------------------------------------- << end user >> ---------------------------------------
<!-- Outputs -->
<spirit:portMap>
<spirit:logicalPort>
<spirit:name>HRDATA</spirit:name>
</spirit:logicalPort>
<spirit:physicalPort>
<spirit:name>HRDATA<<si_name>></spirit:name>
</spirit:physicalPort>
</spirit:portMap>
<spirit:portMap>
<spirit:logicalPort>
<spirit:name>HREADYOUT</spirit:name>
</spirit:logicalPort>
<spirit:physicalPort>
<spirit:name>HREADYOUT<<si_name>></spirit:name>
</spirit:physicalPort>
</spirit:portMap>
<spirit:portMap>
<spirit:logicalPort>
<spirit:name>HRESP</spirit:name>
</spirit:logicalPort>
<spirit:physicalPort>
<spirit:name>HRESP<<si_name>></spirit:name>
<spirit:vector>
<spirit:left>0</spirit:left>
<spirit:right>0</spirit:right>
</spirit:vector>
</spirit:physicalPort>
</spirit:portMap>
//---------------------------------------- << start user >> -------------------------------------
<spirit:portMap>
<spirit:logicalPort>
<spirit:name>HRUSER</spirit:name>
</spirit:logicalPort>
<spirit:physicalPort>
<spirit:name>HRUSER<<si_name>></spirit:name>
</spirit:physicalPort>
</spirit:portMap>
//---------------------------------------- << end user >> ---------------------------------------
</spirit:portMaps>
</spirit:busInterface>
//----------------------------------------- << end in >> ----------------------------------------
<!--Master interfaces -->
//---------------------------------------- << start out >> --------------------------------------
<spirit:busInterface>
<spirit:name>AHBLiteTarget_Master_<<mi_name>></spirit:name>
<spirit:description>Master port <<mi_name>></spirit:description>
<spirit:busType spirit:library="AMBA3" spirit:name="AHBLiteTarget" spirit:vendor="amba.com" spirit:version="r2p0_0"/>
<spirit:abstractionType spirit:library="AMBA3" spirit:name="AHBLiteTarget_rtl" spirit:vendor="amba.com" spirit:version="r2p0_0"/>
<spirit:master>
<spirit:addressSpaceRef spirit:addressSpaceRef="AHBLiteTarget_Master_<<mi_name>>_AS"/>
</spirit:master>
<spirit:portMaps>
<!-- Clock/reset -->
<spirit:portMap>
<spirit:logicalPort>
<spirit:name>HCLK</spirit:name>
</spirit:logicalPort>
<spirit:physicalPort>
<spirit:name>HCLK</spirit:name>
</spirit:physicalPort>
</spirit:portMap>
<spirit:portMap>
<spirit:logicalPort>
<spirit:name>HRESETn</spirit:name>
</spirit:logicalPort>
<spirit:physicalPort>
<spirit:name>HRESETn</spirit:name>
</spirit:physicalPort>
</spirit:portMap>
<!-- Outputs -->
<spirit:portMap>
<spirit:logicalPort>
<spirit:name>HSELx</spirit:name>
</spirit:logicalPort>
<spirit:physicalPort>
<spirit:name>HSEL<<mi_name>></spirit:name>
</spirit:physicalPort>
</spirit:portMap>
<spirit:portMap>
<spirit:logicalPort>
<spirit:name>HADDR</spirit:name>
</spirit:logicalPort>
<spirit:physicalPort>
<spirit:name>HADDR<<mi_name>></spirit:name>
</spirit:physicalPort>
</spirit:portMap>
<spirit:portMap>
<spirit:logicalPort>
<spirit:name>HTRANS</spirit:name>
</spirit:logicalPort>
<spirit:physicalPort>
<spirit:name>HTRANS<<mi_name>></spirit:name>
</spirit:physicalPort>
</spirit:portMap>
<spirit:portMap>
<spirit:logicalPort>
<spirit:name>HWRITE</spirit:name>
</spirit:logicalPort>
<spirit:physicalPort>
<spirit:name>HWRITE<<mi_name>></spirit:name>
</spirit:physicalPort>
</spirit:portMap>
<spirit:portMap>
<spirit:logicalPort>
<spirit:name>HSIZE</spirit:name>
</spirit:logicalPort>
<spirit:physicalPort>
<spirit:name>HSIZE<<mi_name>></spirit:name>
</spirit:physicalPort>
</spirit:portMap>
<spirit:portMap>
<spirit:logicalPort>
<spirit:name>HBURST</spirit:name>
</spirit:logicalPort>
<spirit:physicalPort>
<spirit:name>HBURST<<mi_name>></spirit:name>
</spirit:physicalPort>
</spirit:portMap>
<spirit:portMap>
<spirit:logicalPort>
<spirit:name>HPROT</spirit:name>
//---------------------------------------- << start excl >> -------------------------------------
<spirit:vector>
<spirit:left>3</spirit:left>
<spirit:right>0</spirit:right>
</spirit:vector>
//---------------------------------------- << end excl >> -------------------------------------
</spirit:logicalPort>
<spirit:physicalPort>
<spirit:name>HPROT<<mi_name>></spirit:name>
//---------------------------------------- << start excl >> -------------------------------------
<spirit:vector>
<spirit:left>3</spirit:left>
<spirit:right>0</spirit:right>
</spirit:vector>
//---------------------------------------- << end excl >> -------------------------------------
</spirit:physicalPort>
</spirit:portMap>
//---------------------------- << start unalign >> -----------------------------
<!-- HUNALIGN<<mi_name>> unmapped -->
<!-- HBSTRB<<mi_name>> unmapped -->
//----------------------------- << end unalign >> ------------------------------
<!-- HMASTER<<mi_name>> unmapped -->
<spirit:portMap>
<spirit:logicalPort>
<spirit:name>HWDATA</spirit:name>
</spirit:logicalPort>
<spirit:physicalPort>
<spirit:name>HWDATA<<mi_name>></spirit:name>
</spirit:physicalPort>
</spirit:portMap>
<spirit:portMap>
<spirit:logicalPort>
<spirit:name>HMASTLOCK</spirit:name>
</spirit:logicalPort>
<spirit:physicalPort>
<spirit:name>HMASTLOCK<<mi_name>></spirit:name>
</spirit:physicalPort>
</spirit:portMap>
<spirit:portMap>
<spirit:logicalPort>
<spirit:name>HREADY</spirit:name>
</spirit:logicalPort>
<spirit:physicalPort>
<spirit:name>HREADYMUX<<mi_name>></spirit:name>
</spirit:physicalPort>
</spirit:portMap>
//---------------------------------------- << start user >> -------------------------------------
<spirit:portMap>
<spirit:logicalPort>
<spirit:name>HAUSER</spirit:name>
</spirit:logicalPort>
<spirit:physicalPort>
<spirit:name>HAUSER<<mi_name>></spirit:name>
</spirit:physicalPort>
</spirit:portMap>
<spirit:portMap>
<spirit:logicalPort>
<spirit:name>HWUSER</spirit:name>
</spirit:logicalPort>
<spirit:physicalPort>
<spirit:name>HWUSER<<mi_name>></spirit:name>
</spirit:physicalPort>
</spirit:portMap>
//---------------------------------------- << end user >> ---------------------------------------
<!-- Inputs -->
<spirit:portMap>
<spirit:logicalPort>
<spirit:name>HRDATA</spirit:name>
</spirit:logicalPort>
<spirit:physicalPort>
<spirit:name>HRDATA<<mi_name>></spirit:name>
</spirit:physicalPort>
</spirit:portMap>
<spirit:portMap>
<spirit:logicalPort>
<spirit:name>HREADYOUT</spirit:name>
</spirit:logicalPort>
<spirit:physicalPort>
<spirit:name>HREADYOUT<<mi_name>></spirit:name>
</spirit:physicalPort>
</spirit:portMap>
<spirit:portMap>
<spirit:logicalPort>
<spirit:name>HRESP</spirit:name>
</spirit:logicalPort>
<spirit:physicalPort>
<spirit:name>HRESP<<mi_name>></spirit:name>
<spirit:vector>
<spirit:left>0</spirit:left>
<spirit:right>0</spirit:right>
</spirit:vector>
</spirit:physicalPort>
</spirit:portMap>
//---------------------------------------- << start user >> -------------------------------------
<spirit:portMap>
<spirit:logicalPort>
<spirit:name>HRUSER</spirit:name>
</spirit:logicalPort>
<spirit:physicalPort>
<spirit:name>HRUSER<<mi_name>></spirit:name>
</spirit:physicalPort>
</spirit:portMap>
//---------------------------------------- << end user >> ---------------------------------------
</spirit:portMaps>
</spirit:busInterface>
//---------------------------------------- << end out >> ----------------------------------------
<!--Scan test dummy signals -->
<spirit:busInterface>
<spirit:name>DFTInterface_Slave</spirit:name>
<spirit:description>Scan test dummy signals, not connected until scan insertion</spirit:description>
<spirit:busType spirit:library="generic" spirit:name="DFTInterface" spirit:vendor="arm.com" spirit:version="r0p0_1"/>
<spirit:abstractionType spirit:library="generic" spirit:name="DFTInterface_rtl" spirit:vendor="arm.com" spirit:version="r0p0_1"/>
<spirit:slave/>
<spirit:portMaps>
<!-- Clock/reset -->
<spirit:portMap>
<spirit:logicalPort>
<spirit:name>CLK</spirit:name>
</spirit:logicalPort>
<spirit:physicalPort>
<spirit:name>HCLK</spirit:name>
</spirit:physicalPort>
</spirit:portMap>
<spirit:portMap>
<spirit:logicalPort>
<spirit:name>RESETn</spirit:name>
</spirit:logicalPort>
<spirit:physicalPort>
<spirit:name>HRESETn</spirit:name>
</spirit:physicalPort>
</spirit:portMap>
<spirit:portMap>
<spirit:logicalPort>
<spirit:name>DFTSCANMODE</spirit:name>
</spirit:logicalPort>
<spirit:physicalPort>
<spirit:name>SCANENABLE</spirit:name>
</spirit:physicalPort>
</spirit:portMap>
<spirit:portMap>
<spirit:logicalPort>
<spirit:name>DFTSI</spirit:name>
</spirit:logicalPort>
<spirit:physicalPort>
<spirit:name>SCANINHCLK</spirit:name>
</spirit:physicalPort>
</spirit:portMap>
<spirit:portMap>
<spirit:logicalPort>
<spirit:name>DFTSO</spirit:name>
</spirit:logicalPort>
<spirit:physicalPort>
<spirit:name>SCANOUTHCLK</spirit:name>
</spirit:physicalPort>
</spirit:portMap>
</spirit:portMaps>
</spirit:busInterface>
</spirit:busInterfaces>
//--------------------------------- << start vendor_extension >> ---------------------------------
//---------------------------------- << end vendor_extension >> ----------------------------------
//---------------------------- << start remap_used >> -------------------------------
<spirit:remapStates>
//---------------------------- << start remap_state_ipxact >> -------------------------------
<spirit:remapState>
<spirit:name><<remap_name>></spirit:name>
<spirit:description>Remap state <<remap_name>></spirit:description>
<spirit:remapPorts>
//---------------------------- << start remap_bit_ipxact >> -------------------------------
<spirit:remapPort spirit:portNameRef="REMAP" spirit:portIndex="<<top_remap_bit>>"><<top_remap_bitvalue>></spirit:remapPort>
//---------------------------- << end remap_bit_ipxact >> -------------------------------
</spirit:remapPorts>
</spirit:remapState>
//------------------------------ << end remap_state_ipxact >> -------------------------
</spirit:remapStates>
//----------------------------- << end remap_used >> --------------------------------
<spirit:addressSpaces>
//---------------------------------------- << start out >> ----------------------------------------
<spirit:addressSpace>
<spirit:name>AHBLiteTarget_Master_<<mi_name>>_AS</spirit:name>
<spirit:description><<mi_name>> address space</spirit:description>
<spirit:range><<address_space_range>></spirit:range>
<spirit:width><<data_v>></spirit:width>
<spirit:segments>
//---------------------------------------- << start segments >> ----------------------------------------
<spirit:segment>
<spirit:name><<mi_name>>_<<segment_name>></spirit:name>
<spirit:addressOffset><<segment_offset>></spirit:addressOffset>
<spirit:range><<segment_range>></spirit:range>
</spirit:segment>
//---------------------------------------- << end segments >> ----------------------------------------
</spirit:segments>
<spirit:addressUnitBits>8</spirit:addressUnitBits>
</spirit:addressSpace>
//---------------------------------------- << end out >> ----------------------------------------
</spirit:addressSpaces>
<spirit:memoryMaps>
//---------------------------------------- << start in >> ----------------------------------------
<spirit:memoryMap>
<spirit:name>AHBLiteTarget_Slave_<<si_name>>_MM</spirit:name>
<spirit:description><<si_name>> memory map</spirit:description>
//----------------------------- << start addr_map_ipxact >> ---------------------------
//----------------------------- << start addr_region_ipxact >> ------------------------
//----------------------------- << start remap_static >> ------------------------
<spirit:subspaceMap spirit:masterRef="AHBLiteTarget_Master_<<mi_name>>"
spirit:segmentRef="<<mi_name>>_<<base_address>>_<<end_address>>">
<!-- Address_region <<address_map>> -->
//---------------------------- << start remap_used >> -------------------------------
<spirit:name>AHBLiteTarget_Master_<<mi_name>>_<<base_address>>_0_state_always_SM</spirit:name>
//---------------------------- << end remap_used >> -------------------------------
//---------------------------- << start no_remap_used >> -------------------------------
<spirit:name>AHBLiteTarget_Master_<<mi_name>>_<<base_address>>_0_state_default_SM</spirit:name>
//---------------------------- << end no_remap_used >> -------------------------------
<spirit:baseAddress><<base_address>></spirit:baseAddress>
</spirit:subspaceMap>
//----------------------------- << end remap_static >> ------------------------
//------------------------------ << end addr_region_ipxact >> -------------------------
//----------------------------- << end addr_map_ipxact >> -----------------------------
//---------------------------- << start remap_used >> -------------------------------
//----------------------------- << start remap_state_ipxact >> -------------------------
//----------------------------- << start addr_remap_and_normal_all_this_remap >> -------------------------
<spirit:memoryRemap spirit:state="<<remap_name>>">
<spirit:name>AHBLiteTarget_Slave_<<si_name>>_<<remap_name>>_remap_MM</spirit:name>
<spirit:description><<si_name>> <<remap_name>> remap</spirit:description>
//----------------------------- << start remap_region_ipxact >> -----------------------
<spirit:subspaceMap spirit:masterRef="AHBLiteTarget_Master_<<mi_name>>"
spirit:segmentRef="<<mi_name>>_<<base_address>>_<<end_address>>">
<!-- <<region_type>> address_region <<address_map>> -->
<spirit:name>AHBLiteTarget_Master_<<mi_name>>_<<base_address>>_0_state_<<remap_name>>_SM</spirit:name>
<spirit:baseAddress><<base_address>></spirit:baseAddress>
</spirit:subspaceMap>
//------------------------------ << end remap_region_ipxact >> -------------------------
</spirit:memoryRemap>
//----------------------------- << end addr_remap_and_normal_all_this_remap >> ---------------------------
//----------------------------- << end remap_state_ipxact >> -------------------------
//---------------------------- << end remap_used >> -------------------------------
</spirit:memoryMap>
//----------------------------------------- << end in >> ------------------------------------------
</spirit:memoryMaps>
<spirit:model>
<spirit:views>
<spirit:view>
<spirit:name>verilogsource</spirit:name>
<spirit:description><<bus_matrix_name>> bus matrix</spirit:description>
<spirit:envIdentifier>:*Simulation:</spirit:envIdentifier>
<spirit:envIdentifier>:*Synthesis:</spirit:envIdentifier>
<spirit:language>verilog</spirit:language>
<spirit:modelName><<bus_matrix_name>></spirit:modelName>
<spirit:fileSetRef>
<spirit:localName>fs-verilogsource</spirit:localName>
</spirit:fileSetRef>
</spirit:view>
</spirit:views>
<spirit:ports>
<!-- Common clock and reset -->
<spirit:port>
<spirit:name>HCLK</spirit:name>
<spirit:wire>
<spirit:direction>in</spirit:direction>
</spirit:wire>
</spirit:port>
<spirit:port>
<spirit:name>HRESETn</spirit:name>
<spirit:wire>
<spirit:direction>in</spirit:direction>
</spirit:wire>
</spirit:port>
<!-- Remap port -->
<spirit:port>
<spirit:name>REMAP</spirit:name>
<spirit:wire>
<spirit:direction>in</spirit:direction>
<spirit:vector>
<spirit:left>3</spirit:left>
<spirit:right>0</spirit:right>
</spirit:vector>
<spirit:driver>
<spirit:defaultValue>0</spirit:defaultValue>
</spirit:driver>
</spirit:wire>
</spirit:port>
<!-- Input signals of Slave interfaces -->
//----------------------------------------- << start in >> ------------------------------------------
<spirit:port>
<spirit:name>HSEL<<si_name>></spirit:name>
<spirit:wire>
<spirit:direction>in</spirit:direction>
</spirit:wire>
</spirit:port>
<spirit:port>
<spirit:name>HADDR<<si_name>></spirit:name>
<spirit:wire>
<spirit:direction>in</spirit:direction>
<spirit:vector>
<spirit:left><<addr>></spirit:left>
<spirit:right>0</spirit:right>
</spirit:vector>
</spirit:wire>
</spirit:port>
<spirit:port>
<spirit:name>HTRANS<<si_name>></spirit:name>
<spirit:wire>
<spirit:direction>in</spirit:direction>
<spirit:vector>
<spirit:left>1</spirit:left>
<spirit:right>0</spirit:right>
</spirit:vector>
</spirit:wire>
</spirit:port>
<spirit:port>
<spirit:name>HWRITE<<si_name>></spirit:name>
<spirit:wire>
<spirit:direction>in</spirit:direction>
</spirit:wire>
</spirit:port>
<spirit:port>
<spirit:name>HSIZE<<si_name>></spirit:name>
<spirit:wire>
<spirit:direction>in</spirit:direction>
<spirit:vector>
<spirit:left>2</spirit:left>
<spirit:right>0</spirit:right>
</spirit:vector>
</spirit:wire>
</spirit:port>
<spirit:port>
<spirit:name>HBURST<<si_name>></spirit:name>
<spirit:wire>
<spirit:direction>in</spirit:direction>
<spirit:vector>
<spirit:left>2</spirit:left>
<spirit:right>0</spirit:right>
</spirit:vector>
<spirit:driver>
<spirit:defaultValue>0</spirit:defaultValue>
</spirit:driver>
</spirit:wire>
</spirit:port>
<spirit:port>
<spirit:name>HPROT<<si_name>></spirit:name>
<spirit:wire>
<spirit:direction>in</spirit:direction>
<spirit:vector>
<spirit:left><<prot>></spirit:left>
<spirit:right>0</spirit:right>
</spirit:vector>
</spirit:wire>
</spirit:port>
//---------------------------- << start unalign >> -----------------------------
<spirit:port>
<spirit:name>HUNALIGN<<si_name>></spirit:name>
<spirit:wire>
<spirit:direction>in</spirit:direction>
<spirit:driver>
<spirit:defaultValue>0</spirit:defaultValue>
</spirit:driver>
</spirit:wire>
</spirit:port>
<spirit:port>
<spirit:name>HBSTRB<<si_name>></spirit:name>
<spirit:wire>
<spirit:direction>in</spirit:direction>
<spirit:vector>
<spirit:left><<bstrb>></spirit:left>
<spirit:right>0</spirit:right>
</spirit:vector>
<spirit:driver>
<spirit:defaultValue>0</spirit:defaultValue>
</spirit:driver>
</spirit:wire>
</spirit:port>
//----------------------------- << end unalign >> ------------------------------
<spirit:port>
<spirit:name>HMASTER<<si_name>></spirit:name>
<spirit:wire>
<spirit:direction>in</spirit:direction>
<spirit:vector>
<spirit:left>3</spirit:left>
<spirit:right>0</spirit:right>
</spirit:vector>
<spirit:driver>
<spirit:defaultValue><<in>></spirit:defaultValue>
</spirit:driver>
</spirit:wire>
</spirit:port>
<spirit:port>
<spirit:name>HWDATA<<si_name>></spirit:name>
<spirit:wire>
<spirit:direction>in</spirit:direction>
<spirit:vector>
<spirit:left><<data>></spirit:left>
<spirit:right>0</spirit:right>
</spirit:vector>
</spirit:wire>
</spirit:port>
<spirit:port>
<spirit:name>HMASTLOCK<<si_name>></spirit:name>
<spirit:wire>
<spirit:direction>in</spirit:direction>
</spirit:wire>
</spirit:port>
<spirit:port>
<spirit:name>HREADY<<si_name>></spirit:name>
<spirit:wire>
<spirit:direction>in</spirit:direction>
</spirit:wire>
</spirit:port>
//---------------------------------------- << start user >> -------------------------------------
<spirit:port>
<spirit:name>HAUSER<<si_name>></spirit:name>
<spirit:wire>
<spirit:direction>in</spirit:direction>
<spirit:vector>
<spirit:left><<user>></spirit:left>
<spirit:right>0</spirit:right>
</spirit:vector>
</spirit:wire>
</spirit:port>
<spirit:port>
<spirit:name>HWUSER<<si_name>></spirit:name>
<spirit:wire>
<spirit:direction>in</spirit:direction>
<spirit:vector>
<spirit:left><<user>></spirit:left>
<spirit:right>0</spirit:right>
</spirit:vector>
</spirit:wire>
</spirit:port>
//---------------------------------------- << end user >> ---------------------------------------
//----------------------------------------- << end in >> ----------------------------------------
<!-- Input signals of Master interfaces -->
//----------------------------------------- << start out >> ----------------------------------------
<spirit:port>
<spirit:name>HRDATA<<mi_name>></spirit:name>
<spirit:wire>
<spirit:direction>in</spirit:direction>
<spirit:vector>
<spirit:left><<data>></spirit:left>
<spirit:right>0</spirit:right>
</spirit:vector>
</spirit:wire>
</spirit:port>
<spirit:port>
<spirit:name>HREADYOUT<<mi_name>></spirit:name>
<spirit:wire>
<spirit:direction>in</spirit:direction>
</spirit:wire>
</spirit:port>
<spirit:port>
<spirit:name>HRESP<<mi_name>></spirit:name>
<spirit:wire>
<spirit:direction>in</spirit:direction>
<spirit:vector>
<spirit:left><<resp>></spirit:left>
<spirit:right>0</spirit:right>
</spirit:vector>
</spirit:wire>
</spirit:port>
//---------------------------------------- << start user >> -------------------------------------
<spirit:port>
<spirit:name>HRUSER<<mi_name>></spirit:name>
<spirit:wire>
<spirit:direction>in</spirit:direction>
<spirit:vector>
<spirit:left><<user>></spirit:left>
<spirit:right>0</spirit:right>
</spirit:vector>
</spirit:wire>
</spirit:port>
//---------------------------------------- << end user >> ---------------------------------------
//----------------------------------------- << end out >> ----------------------------------------
<!-- Scan test dummy signals; not connected until scan insertion -->
<spirit:port>
<spirit:name>SCANENABLE</spirit:name>
<spirit:wire>
<spirit:direction>in</spirit:direction>
</spirit:wire>
</spirit:port>
<spirit:port>
<spirit:name>SCANINHCLK</spirit:name>
<spirit:wire>
<spirit:direction>in</spirit:direction>
</spirit:wire>
</spirit:port>
<!-- Output signals of Master interfaces -->
//---------------------------------------- << start out >> --------------------------------------
<spirit:port>
<spirit:name>HSEL<<mi_name>></spirit:name>
<spirit:wire>
<spirit:direction>out</spirit:direction>
</spirit:wire>
</spirit:port>
<spirit:port>
<spirit:name>HADDR<<mi_name>></spirit:name>
<spirit:wire>
<spirit:direction>out</spirit:direction>
<spirit:vector>
<spirit:left><<addr>></spirit:left>
<spirit:right>0</spirit:right>
</spirit:vector>
</spirit:wire>
</spirit:port>
<spirit:port>
<spirit:name>HTRANS<<mi_name>></spirit:name>
<spirit:wire>
<spirit:direction>out</spirit:direction>
<spirit:vector>
<spirit:left>1</spirit:left>
<spirit:right>0</spirit:right>
</spirit:vector>
</spirit:wire>
</spirit:port>
<spirit:port>
<spirit:name>HWRITE<<mi_name>></spirit:name>
<spirit:wire>
<spirit:direction>out</spirit:direction>
</spirit:wire>
</spirit:port>
<spirit:port>
<spirit:name>HSIZE<<mi_name>></spirit:name>
<spirit:wire>
<spirit:direction>out</spirit:direction>
<spirit:vector>
<spirit:left>2</spirit:left>
<spirit:right>0</spirit:right>
</spirit:vector>
</spirit:wire>
</spirit:port>
<spirit:port>
<spirit:name>HBURST<<mi_name>></spirit:name>
<spirit:wire>
<spirit:direction>out</spirit:direction>
<spirit:vector>
<spirit:left>2</spirit:left>
<spirit:right>0</spirit:right>
</spirit:vector>
</spirit:wire>
</spirit:port>
<spirit:port>
<spirit:name>HPROT<<mi_name>></spirit:name>
<spirit:wire>
<spirit:direction>out</spirit:direction>
<spirit:vector>
<spirit:left><<prot>></spirit:left>
<spirit:right>0</spirit:right>
</spirit:vector>
</spirit:wire>
</spirit:port>
//---------------------------- << start unalign >> -----------------------------
<spirit:port>
<spirit:name>HUNALIGN<<mi_name>></spirit:name>
<spirit:wire>
<spirit:direction>out</spirit:direction>
</spirit:wire>
</spirit:port>
<spirit:port>
<spirit:name>HBSTRB<<mi_name>></spirit:name>
<spirit:wire>
<spirit:direction>out</spirit:direction>
<spirit:vector>
<spirit:left><<bstrb>></spirit:left>
<spirit:right>0</spirit:right>
</spirit:vector>
</spirit:wire>
</spirit:port>
//----------------------------- << end unalign >> ------------------------------
<spirit:port>
<spirit:name>HMASTER<<mi_name>></spirit:name>
<spirit:wire>
<spirit:direction>out</spirit:direction>
<spirit:vector>
<spirit:left>3</spirit:left>
<spirit:right>0</spirit:right>
</spirit:vector>
</spirit:wire>
</spirit:port>
<spirit:port>
<spirit:name>HWDATA<<mi_name>></spirit:name>
<spirit:wire>
<spirit:direction>out</spirit:direction>
<spirit:vector>
<spirit:left><<data>></spirit:left>
<spirit:right>0</spirit:right>
</spirit:vector>
</spirit:wire>
</spirit:port>
<spirit:port>
<spirit:name>HMASTLOCK<<mi_name>></spirit:name>
<spirit:wire>
<spirit:direction>out</spirit:direction>
</spirit:wire>
</spirit:port>
<spirit:port>
<spirit:name>HREADYMUX<<mi_name>></spirit:name>
<spirit:wire>
<spirit:direction>out</spirit:direction>
</spirit:wire>
</spirit:port>
//---------------------------------------- << start user >> -------------------------------------
<spirit:port>
<spirit:name>HAUSER<<mi_name>></spirit:name>
<spirit:wire>
<spirit:direction>out</spirit:direction>
<spirit:vector>
<spirit:left><<user>></spirit:left>
<spirit:right>0</spirit:right>
</spirit:vector>
</spirit:wire>
</spirit:port>
<spirit:port>
<spirit:name>HWUSER<<mi_name>></spirit:name>
<spirit:wire>
<spirit:direction>out</spirit:direction>
<spirit:vector>
<spirit:left><<user>></spirit:left>
<spirit:right>0</spirit:right>
</spirit:vector>
</spirit:wire>
</spirit:port>
//---------------------------------------- << end user >> ---------------------------------------
//---------------------------------------- << end out >> ----------------------------------------
<!-- Output signals of Slave interfaces -->
//---------------------------------------- << start in >> ----------------------------------------
<spirit:port>
<spirit:name>HRDATA<<si_name>></spirit:name>
<spirit:wire>
<spirit:direction>out</spirit:direction>
<spirit:vector>
<spirit:left><<data>></spirit:left>
<spirit:right>0</spirit:right>
</spirit:vector>
</spirit:wire>
</spirit:port>
<spirit:port>
<spirit:name>HREADYOUT<<si_name>></spirit:name>
<spirit:wire>
<spirit:direction>out</spirit:direction>
</spirit:wire>
</spirit:port>
<spirit:port>
<spirit:name>HRESP<<si_name>></spirit:name>
<spirit:wire>
<spirit:direction>out</spirit:direction>
<spirit:vector>
<spirit:left><<resp>></spirit:left>
<spirit:right>0</spirit:right>
</spirit:vector>
</spirit:wire>
</spirit:port>
//---------------------------------------- << start user >> -------------------------------------
<spirit:port>
<spirit:name>HRUSER<<si_name>></spirit:name>
<spirit:wire>
<spirit:direction>out</spirit:direction>
<spirit:vector>
<spirit:left><<user>></spirit:left>
<spirit:right>0</spirit:right>
</spirit:vector>
</spirit:wire>
</spirit:port>
//---------------------------------------- << end user >> ---------------------------------------
//---------------------------------------- << end in >> ----------------------------------------
<!-- Scan test dummy signals; not connected until scan insertion -->
<spirit:port>
<spirit:name>SCANOUTHCLK</spirit:name>
<spirit:wire>
<spirit:direction>out</spirit:direction>
</spirit:wire>
</spirit:port>
</spirit:ports>
</spirit:model>
<spirit:fileSets>
<spirit:fileSet>
<spirit:name>fs-verilogsource</spirit:name>
<spirit:displayName/>
<spirit:description>File list for <<bus_matrix_name>></spirit:description>
//-------------------------------------- << start file >> ---------------------------------------
<spirit:file>
<spirit:name><<verilog_to_ipxact_path>>/<<filename>>.v</spirit:name>
<spirit:fileType>verilogSource-2001</spirit:fileType>
//-------------------------------------- << start topfile >> ---------------------------------------
<spirit:isIncludeFile spirit:externalDeclarations="true">false</spirit:isIncludeFile>
//-------------------------------------- << end topfile >> ---------------------------------------
</spirit:file>
//--------------------------------------- << end file >> ----------------------------------------
</spirit:fileSet>
</spirit:fileSets>
<spirit:description><<bus_matrix_name>></spirit:description>
</spirit:component>
<?xml version="1.0" encoding="UTF-8"?>
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
<!-- The confidential and proprietary information contained in this file may -->
<!-- only be used by a person authorised under and to the extent permitted -->
<!-- by a subsisting licensing agreement from ARM Limited or its affiliates. -->
<!-- -->
<!-- (C) COPYRIGHT 2001-2017 ARM Limited or its affiliates. -->
<!-- ALL RIGHTS RESERVED -->
<!-- -->
<!-- This entire notice must be reproduced on all copies of this file -->
<!-- and copies of this file may only be made by a person if such person is -->
<!-- permitted to do so under the terms of a subsisting license agreement -->
<!-- from ARM Limited or its affiliates. -->
<!-- -->
<!-- SVN Information -->
<!-- -->
<!-- Checked In : $Date: 2017-10-10 15:55:38 +0100 (Tue, 10 Oct 2017) $ -->
<!-- -->
<!-- Revision : $Revision: 371321 $ -->
<!-- -->
<!-- Release Information : Cortex-M System Design Kit-r1p1-00rel0 -->
<!-- -->
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
<!-- Purpose : IP-XACT description for the AHB-Lite wrapper of <<component_name>> -->
<!-- -->
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
<spirit:component xmlns:spirit="http://www.spiritconsortium.org/XMLSchema/SPIRIT/1685-2009"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.spiritconsortium.org/XMLSchema/SPIRIT/1685-2009 http://www.spiritconsortium.org/XMLSchema/SPIRIT/1685-2009/index.xsd">
<spirit:vendor>arm.com</spirit:vendor>
<spirit:library>CoreLink</spirit:library>
<spirit:name><<component_name>></spirit:name>
<spirit:version>r0p0_0</spirit:version>
<spirit:busInterfaces>
<!--Slave interfaces -->
//---------------------------------------- << start in >> ---------------------------------------
<spirit:busInterface>
<spirit:name>AHBLiteInitiator_Slave_<<si_name>></spirit:name>
<spirit:description>Slave port <<si_name>></spirit:description>
<spirit:busType spirit:library="AMBA3" spirit:name="AHBLiteInitiator" spirit:vendor="amba.com" spirit:version="r2p0_0"/>
<spirit:abstractionType spirit:library="AMBA3" spirit:name="AHBLiteInitiator_rtl" spirit:vendor="amba.com" spirit:version="r2p0_0"/>
<spirit:slave>
<spirit:memoryMapRef spirit:memoryMapRef="AHBLiteInitiator_Slave_<<si_name>>_MM"/>
//---------------------------------------- << start out >> --------------------------------------
//------------------------------------- << start connection >> ------------------------------------
<spirit:bridge spirit:masterRef="AHBLiteTarget_Master_<<mi_name>>" spirit:opaque="true"/>
//------------------------------------- << end connection >> --------------------------------------
//---------------------------------------- << end out >> ----------------------------------------
</spirit:slave>
<spirit:portMaps>
<!-- Clock/reset -->
<spirit:portMap>
<spirit:logicalPort>
<spirit:name>HCLK</spirit:name>
</spirit:logicalPort>
<spirit:physicalPort>
<spirit:name>HCLK</spirit:name>
</spirit:physicalPort>
</spirit:portMap>
<spirit:portMap>
<spirit:logicalPort>
<spirit:name>HRESETn</spirit:name>
</spirit:logicalPort>
<spirit:physicalPort>
<spirit:name>HRESETn</spirit:name>
</spirit:physicalPort>
</spirit:portMap>
<!-- Inputs -->
<spirit:portMap>
<spirit:logicalPort>
<spirit:name>HADDR</spirit:name>
</spirit:logicalPort>
<spirit:physicalPort>
<spirit:name>HADDR<<si_name>></spirit:name>
</spirit:physicalPort>
</spirit:portMap>
<spirit:portMap>
<spirit:logicalPort>
<spirit:name>HTRANS</spirit:name>
</spirit:logicalPort>
<spirit:physicalPort>
<spirit:name>HTRANS<<si_name>></spirit:name>
</spirit:physicalPort>
</spirit:portMap>
<spirit:portMap>
<spirit:logicalPort>
<spirit:name>HWRITE</spirit:name>
</spirit:logicalPort>
<spirit:physicalPort>
<spirit:name>HWRITE<<si_name>></spirit:name>
</spirit:physicalPort>
</spirit:portMap>
<spirit:portMap>
<spirit:logicalPort>
<spirit:name>HSIZE</spirit:name>
</spirit:logicalPort>
<spirit:physicalPort>
<spirit:name>HSIZE<<si_name>></spirit:name>
</spirit:physicalPort>
</spirit:portMap>
<spirit:portMap>
<spirit:logicalPort>
<spirit:name>HBURST</spirit:name>
</spirit:logicalPort>
<spirit:physicalPort>
<spirit:name>HBURST<<si_name>></spirit:name>
</spirit:physicalPort>
</spirit:portMap>
<spirit:portMap>
<spirit:logicalPort>
<spirit:name>HPROT</spirit:name>
//---------------------------------------- << start excl >> -------------------------------------
<spirit:vector>
<spirit:left>3</spirit:left>
<spirit:right>0</spirit:right>
</spirit:vector>
//---------------------------------------- << end excl >> -------------------------------------
</spirit:logicalPort>
<spirit:physicalPort>
<spirit:name>HPROT<<si_name>></spirit:name>
//---------------------------------------- << start excl >> -------------------------------------
<spirit:vector>
<spirit:left>3</spirit:left>
<spirit:right>0</spirit:right>
</spirit:vector>
//---------------------------------------- << end excl >> -------------------------------------
</spirit:physicalPort>
</spirit:portMap>
<spirit:portMap>
<spirit:logicalPort>
<spirit:name>HWDATA</spirit:name>
</spirit:logicalPort>
<spirit:physicalPort>
<spirit:name>HWDATA<<si_name>></spirit:name>
</spirit:physicalPort>
</spirit:portMap>
<spirit:portMap>
<spirit:logicalPort>
<spirit:name>HMASTLOCK</spirit:name>
</spirit:logicalPort>
<spirit:physicalPort>
<spirit:name>HMASTLOCK<<si_name>></spirit:name>
</spirit:physicalPort>
</spirit:portMap>
//---------------------------------------- << start user >> -------------------------------------
<spirit:portMap>
<spirit:logicalPort>
<spirit:name>HAUSER</spirit:name>
</spirit:logicalPort>
<spirit:physicalPort>
<spirit:name>HAUSER<<si_name>></spirit:name>
</spirit:physicalPort>
</spirit:portMap>
<spirit:portMap>
<spirit:logicalPort>
<spirit:name>HWUSER</spirit:name>
</spirit:logicalPort>
<spirit:physicalPort>
<spirit:name>HWUSER<<si_name>></spirit:name>
</spirit:physicalPort>
</spirit:portMap>
//---------------------------------------- << end user >> ---------------------------------------
<!-- Outputs -->
<spirit:portMap>
<spirit:logicalPort>
<spirit:name>HRDATA</spirit:name>
</spirit:logicalPort>
<spirit:physicalPort>
<spirit:name>HRDATA<<si_name>></spirit:name>
</spirit:physicalPort>
</spirit:portMap>
<spirit:portMap>
<spirit:logicalPort>
<spirit:name>HREADY</spirit:name>
</spirit:logicalPort>
<spirit:physicalPort>
<spirit:name>HREADY<<si_name>></spirit:name>
</spirit:physicalPort>
</spirit:portMap>
<spirit:portMap>
<spirit:logicalPort>
<spirit:name>HRESP</spirit:name>
</spirit:logicalPort>
<spirit:physicalPort>
<spirit:name>HRESP<<si_name>></spirit:name>
</spirit:physicalPort>
</spirit:portMap>
//---------------------------------------- << start user >> -------------------------------------
<spirit:portMap>
<spirit:logicalPort>
<spirit:name>HRUSER</spirit:name>
</spirit:logicalPort>
<spirit:physicalPort>
<spirit:name>HRUSER<<si_name>></spirit:name>
</spirit:physicalPort>
</spirit:portMap>
//---------------------------------------- << end user >> ---------------------------------------
</spirit:portMaps>
</spirit:busInterface>
//----------------------------------------- << end in >> ----------------------------------------
<!--Master interfaces -->
//---------------------------------------- << start out >> --------------------------------------
<spirit:busInterface>
<spirit:name>AHBLiteTarget_Master_<<mi_name>></spirit:name>
<spirit:description>Master port <<mi_name>></spirit:description>
<spirit:busType spirit:library="AMBA3" spirit:name="AHBLiteTarget" spirit:vendor="amba.com" spirit:version="r2p0_0"/>
<spirit:abstractionType spirit:library="AMBA3" spirit:name="AHBLiteTarget_rtl" spirit:vendor="amba.com" spirit:version="r2p0_0"/>
<spirit:master>
<spirit:addressSpaceRef spirit:addressSpaceRef="AHBLiteTarget_Master_<<mi_name>>_AS"/>
</spirit:master>
<spirit:portMaps>
<!-- Clock/reset -->
<spirit:portMap>
<spirit:logicalPort>
<spirit:name>HCLK</spirit:name>
</spirit:logicalPort>
<spirit:physicalPort>
<spirit:name>HCLK</spirit:name>
</spirit:physicalPort>
</spirit:portMap>
<spirit:portMap>
<spirit:logicalPort>
<spirit:name>HRESETn</spirit:name>
</spirit:logicalPort>
<spirit:physicalPort>
<spirit:name>HRESETn</spirit:name>
</spirit:physicalPort>
</spirit:portMap>
<!-- Outputs -->
<spirit:portMap>
<spirit:logicalPort>
<spirit:name>HSELx</spirit:name>
</spirit:logicalPort>
<spirit:physicalPort>
<spirit:name>HSEL<<mi_name>></spirit:name>
</spirit:physicalPort>
</spirit:portMap>
<spirit:portMap>
<spirit:logicalPort>
<spirit:name>HADDR</spirit:name>
</spirit:logicalPort>
<spirit:physicalPort>
<spirit:name>HADDR<<mi_name>></spirit:name>
</spirit:physicalPort>
</spirit:portMap>
<spirit:portMap>
<spirit:logicalPort>
<spirit:name>HTRANS</spirit:name>
</spirit:logicalPort>
<spirit:physicalPort>
<spirit:name>HTRANS<<mi_name>></spirit:name>
</spirit:physicalPort>
</spirit:portMap>
<spirit:portMap>
<spirit:logicalPort>
<spirit:name>HWRITE</spirit:name>
</spirit:logicalPort>
<spirit:physicalPort>
<spirit:name>HWRITE<<mi_name>></spirit:name>
</spirit:physicalPort>
</spirit:portMap>
<spirit:portMap>
<spirit:logicalPort>
<spirit:name>HSIZE</spirit:name>
</spirit:logicalPort>
<spirit:physicalPort>
<spirit:name>HSIZE<<mi_name>></spirit:name>
</spirit:physicalPort>
</spirit:portMap>
<spirit:portMap>
<spirit:logicalPort>
<spirit:name>HBURST</spirit:name>
</spirit:logicalPort>
<spirit:physicalPort>
<spirit:name>HBURST<<mi_name>></spirit:name>
</spirit:physicalPort>
</spirit:portMap>
<spirit:portMap>
<spirit:logicalPort>
<spirit:name>HPROT</spirit:name>
//---------------------------------------- << start excl >> -------------------------------------
<spirit:vector>
<spirit:left>3</spirit:left>
<spirit:right>0</spirit:right>
</spirit:vector>
//---------------------------------------- << end excl >> -------------------------------------
</spirit:logicalPort>
<spirit:physicalPort>
<spirit:name>HPROT<<mi_name>></spirit:name>
//---------------------------------------- << start excl >> -------------------------------------
<spirit:vector>
<spirit:left>3</spirit:left>
<spirit:right>0</spirit:right>
</spirit:vector>
//---------------------------------------- << end excl >> -------------------------------------
</spirit:physicalPort>
</spirit:portMap>
<spirit:portMap>
<spirit:logicalPort>
<spirit:name>HWDATA</spirit:name>
</spirit:logicalPort>
<spirit:physicalPort>
<spirit:name>HWDATA<<mi_name>></spirit:name>
</spirit:physicalPort>
</spirit:portMap>
<spirit:portMap>
<spirit:logicalPort>
<spirit:name>HMASTLOCK</spirit:name>
</spirit:logicalPort>
<spirit:physicalPort>
<spirit:name>HMASTLOCK<<mi_name>></spirit:name>
</spirit:physicalPort>
</spirit:portMap>
<spirit:portMap>
<spirit:logicalPort>
<spirit:name>HREADY</spirit:name>
</spirit:logicalPort>
<spirit:physicalPort>
<spirit:name>HREADYMUX<<mi_name>></spirit:name>
</spirit:physicalPort>
</spirit:portMap>
//---------------------------------------- << start user >> -------------------------------------
<spirit:portMap>
<spirit:logicalPort>
<spirit:name>HAUSER</spirit:name>
</spirit:logicalPort>
<spirit:physicalPort>
<spirit:name>HAUSER<<mi_name>></spirit:name>
</spirit:physicalPort>
</spirit:portMap>
<spirit:portMap>
<spirit:logicalPort>
<spirit:name>HWUSER</spirit:name>
</spirit:logicalPort>
<spirit:physicalPort>
<spirit:name>HWUSER<<mi_name>></spirit:name>
</spirit:physicalPort>
</spirit:portMap>
//---------------------------------------- << end user >> ---------------------------------------
<!-- Inputs -->
<spirit:portMap>
<spirit:logicalPort>
<spirit:name>HRDATA</spirit:name>
</spirit:logicalPort>
<spirit:physicalPort>
<spirit:name>HRDATA<<mi_name>></spirit:name>
</spirit:physicalPort>
</spirit:portMap>
<spirit:portMap>
<spirit:logicalPort>
<spirit:name>HREADYOUT</spirit:name>
</spirit:logicalPort>
<spirit:physicalPort>
<spirit:name>HREADYOUT<<mi_name>></spirit:name>
</spirit:physicalPort>
</spirit:portMap>
<spirit:portMap>
<spirit:logicalPort>
<spirit:name>HRESP</spirit:name>
</spirit:logicalPort>
<spirit:physicalPort>
<spirit:name>HRESP<<mi_name>></spirit:name>
</spirit:physicalPort>
</spirit:portMap>
//---------------------------------------- << start user >> -------------------------------------
<spirit:portMap>
<spirit:logicalPort>
<spirit:name>HRUSER</spirit:name>
</spirit:logicalPort>
<spirit:physicalPort>
<spirit:name>HRUSER<<mi_name>></spirit:name>
</spirit:physicalPort>
</spirit:portMap>
//---------------------------------------- << end user >> ---------------------------------------
</spirit:portMaps>
</spirit:busInterface>
//---------------------------------------- << end out >> ----------------------------------------
<!--Scan test dummy signals -->
<spirit:busInterface>
<spirit:name>DFTInterface_Slave</spirit:name>
<spirit:description>Scan test dummy signals, not connected until scan insertion</spirit:description>
<spirit:busType spirit:library="generic" spirit:name="DFTInterface" spirit:vendor="arm.com" spirit:version="r0p0_1"/>
<spirit:abstractionType spirit:library="generic" spirit:name="DFTInterface_rtl" spirit:vendor="arm.com" spirit:version="r0p0_1"/>
<spirit:slave/>
<spirit:portMaps>
<!-- Clock/reset -->
<spirit:portMap>
<spirit:logicalPort>
<spirit:name>CLK</spirit:name>
</spirit:logicalPort>
<spirit:physicalPort>
<spirit:name>HCLK</spirit:name>
</spirit:physicalPort>
</spirit:portMap>
<spirit:portMap>
<spirit:logicalPort>
<spirit:name>RESETn</spirit:name>
</spirit:logicalPort>
<spirit:physicalPort>
<spirit:name>HRESETn</spirit:name>
</spirit:physicalPort>
</spirit:portMap>
<spirit:portMap>
<spirit:logicalPort>
<spirit:name>DFTSCANMODE</spirit:name>
</spirit:logicalPort>
<spirit:physicalPort>
<spirit:name>SCANENABLE</spirit:name>
</spirit:physicalPort>
</spirit:portMap>
<spirit:portMap>
<spirit:logicalPort>
<spirit:name>DFTSI</spirit:name>
</spirit:logicalPort>
<spirit:physicalPort>
<spirit:name>SCANINHCLK</spirit:name>
</spirit:physicalPort>
</spirit:portMap>
<spirit:portMap>
<spirit:logicalPort>
<spirit:name>DFTSO</spirit:name>
</spirit:logicalPort>
<spirit:physicalPort>
<spirit:name>SCANOUTHCLK</spirit:name>
</spirit:physicalPort>
</spirit:portMap>
</spirit:portMaps>
</spirit:busInterface>
</spirit:busInterfaces>
//--------------------------------- << start vendor_extension >> ---------------------------------
//---------------------------------- << end vendor_extension >> ----------------------------------
//---------------------------- << start remap_used >> -------------------------------
<spirit:remapStates>
//---------------------------- << start remap_state_ipxact >> -------------------------------
<spirit:remapState>
<spirit:name><<remap_name>></spirit:name>
<spirit:description>Remap state <<remap_name>></spirit:description>
<spirit:remapPorts>
//---------------------------- << start remap_bit_ipxact >> -------------------------------
<spirit:remapPort spirit:portNameRef="REMAP" spirit:portIndex="<<top_remap_bit>>"><<top_remap_bitvalue>></spirit:remapPort>
//---------------------------- << end remap_bit_ipxact >> -------------------------------
</spirit:remapPorts>
</spirit:remapState>
//------------------------------ << end remap_state_ipxact >> -------------------------
</spirit:remapStates>
//----------------------------- << end remap_used >> --------------------------------
<spirit:addressSpaces>
//---------------------------------------- << start out >> ----------------------------------------
<spirit:addressSpace>
<spirit:name>AHBLiteTarget_Master_<<mi_name>>_AS</spirit:name>
<spirit:description><<mi_name>> address space</spirit:description>
<spirit:range><<address_space_range>></spirit:range>
<spirit:width><<data_v>></spirit:width>
<spirit:segments>
//---------------------------------------- << start segments >> ----------------------------------------
<spirit:segment>
<spirit:name><<mi_name>>_<<segment_name>></spirit:name>
<spirit:addressOffset><<segment_offset>></spirit:addressOffset>
<spirit:range><<segment_range>></spirit:range>
</spirit:segment>
//---------------------------------------- << end segments >> ----------------------------------------
</spirit:segments>
<spirit:addressUnitBits>8</spirit:addressUnitBits>
</spirit:addressSpace>
//---------------------------------------- << end out >> ----------------------------------------
</spirit:addressSpaces>
<spirit:memoryMaps>
//---------------------------------------- << start in >> ----------------------------------------
<spirit:memoryMap>
<spirit:name>AHBLiteInitiator_Slave_<<si_name>>_MM</spirit:name>
<spirit:description><<si_name>> memory map</spirit:description>
//----------------------------- << start addr_map_ipxact >> ---------------------------
//----------------------------- << start addr_region_ipxact >> ------------------------
//----------------------------- << start remap_static >> ------------------------
<spirit:subspaceMap spirit:masterRef="AHBLiteTarget_Master_<<mi_name>>"
spirit:segmentRef="<<mi_name>>_<<base_address>>_<<end_address>>">
<!-- Address_region <<address_map>> -->
//---------------------------- << start remap_used >> -------------------------------
<spirit:name>AHBLiteTarget_Master_<<mi_name>>_<<base_address>>_0_state_always_SM</spirit:name>
//---------------------------- << end remap_used >> -------------------------------
//---------------------------- << start no_remap_used >> -------------------------------
<spirit:name>AHBLiteTarget_Master_<<mi_name>>_<<base_address>>_0_state_default_SM</spirit:name>
//---------------------------- << end no_remap_used >> -------------------------------
<spirit:baseAddress><<base_address>></spirit:baseAddress>
</spirit:subspaceMap>
//----------------------------- << end remap_static >> ------------------------
//------------------------------ << end addr_region_ipxact >> -------------------------
//----------------------------- << end addr_map_ipxact >> -----------------------------
//---------------------------- << start remap_used >> -------------------------------
//----------------------------- << start remap_state_ipxact >> -------------------------
//----------------------------- << start addr_remap_and_normal_all_this_remap >> -------------------------
<spirit:memoryRemap spirit:state="<<remap_name>>">
<spirit:name>AHBLiteInitiator_Slave_<<si_name>>_<<remap_name>>_remap_MM</spirit:name>
<spirit:description><<si_name>> <<remap_name>> remap</spirit:description>
//----------------------------- << start remap_region_ipxact >> -----------------------
<spirit:subspaceMap spirit:masterRef="AHBLiteTarget_Master_<<mi_name>>"
spirit:segmentRef="<<mi_name>>_<<base_address>>_<<end_address>>">
<!-- <<region_type>> address_region <<address_map>> -->
<spirit:name>AHBLiteTarget_Master_<<mi_name>>_<<base_address>>_0_state_<<remap_name>>_SM</spirit:name>
<spirit:baseAddress><<base_address>></spirit:baseAddress>
</spirit:subspaceMap>
//------------------------------ << end remap_region_ipxact >> -------------------------
</spirit:memoryRemap>
//----------------------------- << end addr_remap_and_normal_all_this_remap >> ---------------------------
//----------------------------- << end remap_state_ipxact >> -------------------------
//---------------------------- << end remap_used >> -------------------------------
</spirit:memoryMap>
//----------------------------------------- << end in >> ------------------------------------------
</spirit:memoryMaps>
<spirit:model>
<spirit:views>
<spirit:view>
<spirit:name>verilogsource</spirit:name>
<spirit:description><<component_name>> bus matrix</spirit:description>
<spirit:envIdentifier>:*Simulation:</spirit:envIdentifier>
<spirit:envIdentifier>:*Synthesis:</spirit:envIdentifier>
<spirit:language>verilog</spirit:language>
<spirit:modelName><<component_name>></spirit:modelName>
<spirit:fileSetRef>
<spirit:localName>fs-verilogsource</spirit:localName>
</spirit:fileSetRef>
</spirit:view>
</spirit:views>
<spirit:ports>
<!-- Common clock and reset -->
<spirit:port>
<spirit:name>HCLK</spirit:name>
<spirit:wire>
<spirit:direction>in</spirit:direction>
</spirit:wire>
</spirit:port>
<spirit:port>
<spirit:name>HRESETn</spirit:name>
<spirit:wire>
<spirit:direction>in</spirit:direction>
</spirit:wire>
</spirit:port>
<!-- Remap port -->
<spirit:port>
<spirit:name>REMAP</spirit:name>
<spirit:wire>
<spirit:direction>in</spirit:direction>
<spirit:vector>
<spirit:left>3</spirit:left>
<spirit:right>0</spirit:right>
</spirit:vector>
<spirit:driver>
<spirit:defaultValue>0</spirit:defaultValue>
</spirit:driver>
</spirit:wire>
</spirit:port>
<!-- Input signals of Slave interfaces -->
//----------------------------------------- << start in >> ------------------------------------------
<spirit:port>
<spirit:name>HADDR<<si_name>></spirit:name>
<spirit:wire>
<spirit:direction>in</spirit:direction>
<spirit:vector>
<spirit:left><<addr>></spirit:left>
<spirit:right>0</spirit:right>
</spirit:vector>
</spirit:wire>
</spirit:port>
<spirit:port>
<spirit:name>HTRANS<<si_name>></spirit:name>
<spirit:wire>
<spirit:direction>in</spirit:direction>
<spirit:vector>
<spirit:left>1</spirit:left>
<spirit:right>0</spirit:right>
</spirit:vector>
</spirit:wire>
</spirit:port>
<spirit:port>
<spirit:name>HWRITE<<si_name>></spirit:name>
<spirit:wire>
<spirit:direction>in</spirit:direction>
</spirit:wire>
</spirit:port>
<spirit:port>
<spirit:name>HSIZE<<si_name>></spirit:name>
<spirit:wire>
<spirit:direction>in</spirit:direction>
<spirit:vector>
<spirit:left>2</spirit:left>
<spirit:right>0</spirit:right>
</spirit:vector>
</spirit:wire>
</spirit:port>
<spirit:port>
<spirit:name>HBURST<<si_name>></spirit:name>
<spirit:wire>
<spirit:direction>in</spirit:direction>
<spirit:vector>
<spirit:left>2</spirit:left>
<spirit:right>0</spirit:right>
</spirit:vector>
<spirit:driver>
<spirit:defaultValue>0</spirit:defaultValue>
</spirit:driver>
</spirit:wire>
</spirit:port>
<spirit:port>
<spirit:name>HPROT<<si_name>></spirit:name>
<spirit:wire>
<spirit:direction>in</spirit:direction>
<spirit:vector>
<spirit:left><<prot>></spirit:left>
<spirit:right>0</spirit:right>
</spirit:vector>
</spirit:wire>
</spirit:port>
<spirit:port>
<spirit:name>HWDATA<<si_name>></spirit:name>
<spirit:wire>
<spirit:direction>in</spirit:direction>
<spirit:vector>
<spirit:left><<data>></spirit:left>
<spirit:right>0</spirit:right>
</spirit:vector>
</spirit:wire>
</spirit:port>
<spirit:port>
<spirit:name>HMASTLOCK<<si_name>></spirit:name>
<spirit:wire>
<spirit:direction>in</spirit:direction>
</spirit:wire>
</spirit:port>
//---------------------------------------- << start user >> -------------------------------------
<spirit:port>
<spirit:name>HAUSER<<si_name>></spirit:name>
<spirit:wire>
<spirit:direction>in</spirit:direction>
<spirit:vector>
<spirit:left><<user>></spirit:left>
<spirit:right>0</spirit:right>
</spirit:vector>
</spirit:wire>
</spirit:port>
<spirit:port>
<spirit:name>HWUSER<<si_name>></spirit:name>
<spirit:wire>
<spirit:direction>in</spirit:direction>
<spirit:vector>
<spirit:left><<user>></spirit:left>
<spirit:right>0</spirit:right>
</spirit:vector>
</spirit:wire>
</spirit:port>
//---------------------------------------- << end user >> ---------------------------------------
//----------------------------------------- << end in >> ----------------------------------------
<!-- Input signals of Master interfaces -->
//----------------------------------------- << start out >> ----------------------------------------
<spirit:port>
<spirit:name>HRDATA<<mi_name>></spirit:name>
<spirit:wire>
<spirit:direction>in</spirit:direction>
<spirit:vector>
<spirit:left><<data>></spirit:left>
<spirit:right>0</spirit:right>
</spirit:vector>
</spirit:wire>
</spirit:port>
<spirit:port>
<spirit:name>HREADYOUT<<mi_name>></spirit:name>
<spirit:wire>
<spirit:direction>in</spirit:direction>
</spirit:wire>
</spirit:port>
<spirit:port>
<spirit:name>HRESP<<mi_name>></spirit:name>
<spirit:wire>
<spirit:direction>in</spirit:direction>
</spirit:wire>
</spirit:port>
//---------------------------------------- << start user >> -------------------------------------
<spirit:port>
<spirit:name>HRUSER<<mi_name>></spirit:name>
<spirit:wire>
<spirit:direction>in</spirit:direction>
<spirit:vector>
<spirit:left><<user>></spirit:left>
<spirit:right>0</spirit:right>
</spirit:vector>
</spirit:wire>
</spirit:port>
//---------------------------------------- << end user >> ---------------------------------------
//----------------------------------------- << end out >> ----------------------------------------
<!-- Scan test dummy signals; not connected until scan insertion -->
<spirit:port>
<spirit:name>SCANENABLE</spirit:name>
<spirit:wire>
<spirit:direction>in</spirit:direction>
</spirit:wire>
</spirit:port>
<spirit:port>
<spirit:name>SCANINHCLK</spirit:name>
<spirit:wire>
<spirit:direction>in</spirit:direction>
</spirit:wire>
</spirit:port>
<!-- Output signals of Master interfaces -->
//---------------------------------------- << start out >> --------------------------------------
<spirit:port>
<spirit:name>HSEL<<mi_name>></spirit:name>
<spirit:wire>
<spirit:direction>out</spirit:direction>
</spirit:wire>
</spirit:port>
<spirit:port>
<spirit:name>HADDR<<mi_name>></spirit:name>
<spirit:wire>
<spirit:direction>out</spirit:direction>
<spirit:vector>
<spirit:left><<addr>></spirit:left>
<spirit:right>0</spirit:right>
</spirit:vector>
</spirit:wire>
</spirit:port>
<spirit:port>
<spirit:name>HTRANS<<mi_name>></spirit:name>
<spirit:wire>
<spirit:direction>out</spirit:direction>
<spirit:vector>
<spirit:left>1</spirit:left>
<spirit:right>0</spirit:right>
</spirit:vector>
</spirit:wire>
</spirit:port>
<spirit:port>
<spirit:name>HWRITE<<mi_name>></spirit:name>
<spirit:wire>
<spirit:direction>out</spirit:direction>
</spirit:wire>
</spirit:port>
<spirit:port>
<spirit:name>HSIZE<<mi_name>></spirit:name>
<spirit:wire>
<spirit:direction>out</spirit:direction>
<spirit:vector>
<spirit:left>2</spirit:left>
<spirit:right>0</spirit:right>
</spirit:vector>
</spirit:wire>
</spirit:port>
<spirit:port>
<spirit:name>HBURST<<mi_name>></spirit:name>
<spirit:wire>
<spirit:direction>out</spirit:direction>
<spirit:vector>
<spirit:left>2</spirit:left>
<spirit:right>0</spirit:right>
</spirit:vector>
</spirit:wire>
</spirit:port>
<spirit:port>
<spirit:name>HPROT<<mi_name>></spirit:name>
<spirit:wire>
<spirit:direction>out</spirit:direction>
<spirit:vector>
<spirit:left><<prot>></spirit:left>
<spirit:right>0</spirit:right>
</spirit:vector>
</spirit:wire>
</spirit:port>
<spirit:port>
<spirit:name>HWDATA<<mi_name>></spirit:name>
<spirit:wire>
<spirit:direction>out</spirit:direction>
<spirit:vector>
<spirit:left><<data>></spirit:left>
<spirit:right>0</spirit:right>
</spirit:vector>
</spirit:wire>
</spirit:port>
<spirit:port>
<spirit:name>HMASTLOCK<<mi_name>></spirit:name>
<spirit:wire>
<spirit:direction>out</spirit:direction>
</spirit:wire>
</spirit:port>
<spirit:port>
<spirit:name>HREADYMUX<<mi_name>></spirit:name>
<spirit:wire>
<spirit:direction>out</spirit:direction>
</spirit:wire>
</spirit:port>
//---------------------------------------- << start user >> -------------------------------------
<spirit:port>
<spirit:name>HAUSER<<mi_name>></spirit:name>
<spirit:wire>
<spirit:direction>out</spirit:direction>
<spirit:vector>
<spirit:left><<user>></spirit:left>
<spirit:right>0</spirit:right>
</spirit:vector>
</spirit:wire>
</spirit:port>
<spirit:port>
<spirit:name>HWUSER<<mi_name>></spirit:name>
<spirit:wire>
<spirit:direction>out</spirit:direction>
<spirit:vector>
<spirit:left><<user>></spirit:left>
<spirit:right>0</spirit:right>
</spirit:vector>
</spirit:wire>
</spirit:port>
//---------------------------------------- << end user >> ---------------------------------------
//---------------------------------------- << end out >> ----------------------------------------
<!-- Output signals of Slave interfaces -->
//---------------------------------------- << start in >> ----------------------------------------
<spirit:port>
<spirit:name>HRDATA<<si_name>></spirit:name>
<spirit:wire>
<spirit:direction>out</spirit:direction>
<spirit:vector>
<spirit:left><<data>></spirit:left>
<spirit:right>0</spirit:right>
</spirit:vector>
</spirit:wire>
</spirit:port>
<spirit:port>
<spirit:name>HREADY<<si_name>></spirit:name>
<spirit:wire>
<spirit:direction>out</spirit:direction>
</spirit:wire>
</spirit:port>
<spirit:port>
<spirit:name>HRESP<<si_name>></spirit:name>
<spirit:wire>
<spirit:direction>out</spirit:direction>
</spirit:wire>
</spirit:port>
//---------------------------------------- << start user >> -------------------------------------
<spirit:port>
<spirit:name>HRUSER<<si_name>></spirit:name>
<spirit:wire>
<spirit:direction>out</spirit:direction>
<spirit:vector>
<spirit:left><<user>></spirit:left>
<spirit:right>0</spirit:right>
</spirit:vector>
</spirit:wire>
</spirit:port>
//---------------------------------------- << end user >> ---------------------------------------
//---------------------------------------- << end in >> ----------------------------------------
<!-- Scan test dummy signals; not connected until scan insertion -->
<spirit:port>
<spirit:name>SCANOUTHCLK</spirit:name>
<spirit:wire>
<spirit:direction>out</spirit:direction>
</spirit:wire>
</spirit:port>
</spirit:ports>
</spirit:model>
<spirit:fileSets>
<spirit:fileSet>
<spirit:name>fs-verilogsource</spirit:name>
<spirit:displayName/>
<spirit:description>File list for <<component_name>></spirit:description>
//-------------------------------------- << start file >> ---------------------------------------
<spirit:file>
<spirit:name><<verilog_to_ipxact_path>>/<<filename>>.v</spirit:name>
<spirit:fileType>verilogSource-2001</spirit:fileType>
//-------------------------------------- << start topfile >> ---------------------------------------
<spirit:isIncludeFile spirit:externalDeclarations="true">false</spirit:isIncludeFile>
//-------------------------------------- << end topfile >> ---------------------------------------
</spirit:file>
//--------------------------------------- << end file >> ----------------------------------------
</spirit:fileSet>
</spirit:fileSets>
<spirit:description><<component_name>></spirit:description>
</spirit:component>
//-----------------------------------------------------------------------------
// The confidential and proprietary information contained in this file may
// only be used by a person authorised under and to the extent permitted
// by a subsisting licensing agreement from Arm Limited or its affiliates.
//
// (C) COPYRIGHT 2001-<<copyright_year>> Arm Limited or its affiliates.
// ALL RIGHTS RESERVED
//
// This entire notice must be reproduced on all copies of this file
// and copies of this file may only be made by a person if such person is
// permitted to do so under the terms of a subsisting license agreement
// from Arm Limited or its affiliates.
//
// SVN Information
//
// Checked In : $Date: 2017-10-10 15:55:38 +0100 (Tue, 10 Oct 2017) $
//
// Revision : $Revision: 371321 $
//
// Release Information : Cortex-M System Design Kit-r1p1-00rel0
//
//-----------------------------------------------------------------------------
//
//------------------------------------------------------------------------------
// Abstract : The Output Arbitration is used to determine which
// of the input stages will be given access to the
// shared slave.
//
// Notes : The bus matrix has <<connectivity>> connectivity.
//
//-----------------------------------------------------------------------------
<<timescale_directive>>
module <<output_arb_name>> (
// Common AHB signals
HCLK ,
HRESETn,
// Input port request signals
//------------------------------ << start in >> --------------------------------
//----------------------------- << start connection >> -------------------------
req_port<<in>>,
//------------------------------ << end connection >> --------------------------
//------------------------------- << end in >> ---------------------------------
HREADYM,
HSELM,
HTRANSM,
HBURSTM,
HMASTLOCKM,
// Arbiter outputs
addr_in_port,
no_port
);
// -----------------------------------------------------------------------------
// Input and Output declarations
// -----------------------------------------------------------------------------
// Common AHB signals
input HCLK; // AHB system clock
input HRESETn; // AHB system reset
//------------------------------ << start in >> --------------------------------
//----------------------------- << start connection >> -------------------------
input req_port<<in>>; // Port <<in>> request signal
//------------------------------ << end connection >> --------------------------
//------------------------------- << end in >> ---------------------------------
input HREADYM; // Transfer done
input HSELM; // Slave select line
input [1:0] HTRANSM; // Transfer type
input [2:0] HBURSTM; // Burst type
input HMASTLOCKM; // Locked transfer
output [<<idw_si>>:0] addr_in_port; // Port address input
output no_port; // No port selected signal
// -----------------------------------------------------------------------------
// Constant declarations
// -----------------------------------------------------------------------------
// HTRANS transfer type signal encoding
`define TRN_IDLE 2'b00 // Idle transfer
`define TRN_BUSY 2'b01 // Busy transfer
`define TRN_NONSEQ 2'b10 // NonSequential transfer
`define TRN_SEQ 2'b11 // Sequential transfer
// HBURST transfer type signal encoding
`define BUR_SINGLE 3'b000 // Single
`define BUR_INCR 3'b001 // Incremental
`define BUR_WRAP4 3'b010 // 4-beat wrap
`define BUR_INCR4 3'b011 // 4-beat Incr
`define BUR_WRAP8 3'b100 // 8-beat wrap
`define BUR_INCR8 3'b101 // 8-beat Incr
`define BUR_WRAP16 3'b110 // 16-beat Wrap
`define BUR_INCR16 3'b111 // 16-beat Incr
// -----------------------------------------------------------------------------
// Wire declarations
// -----------------------------------------------------------------------------
wire HCLK; // AHB system clock
wire HRESETn; // AHB system reset
//------------------------------ << start in >> --------------------------------
//----------------------------- << start connection >> -------------------------
wire req_port<<in>>; // Port <<in>> request signal
//------------------------------ << end connection >> --------------------------
//------------------------------- << end in >> ---------------------------------
wire HREADYM; // Transfer done
wire HSELM; // Slave select line
wire [1:0] HTRANSM; // Transfer type
wire [2:0] HBURSTM; // Burst type
wire HMASTLOCKM; // Locked transfer
wire [<<idw_si>>:0] addr_in_port; // Address input port
reg no_port; // No port selected signal
// -----------------------------------------------------------------------------
// Signal declarations
// -----------------------------------------------------------------------------
reg [<<idw_si>>:0] addr_in_port_next; // D-input of addr_in_port
reg [<<idw_si>>:0] i_addr_in_port; // Internal version of addr_in_port
reg no_port_next; // D-input of no_port
reg [3:0] next_burst_count; // D-input of reg_burst_count
reg [3:0] reg_burst_count; // Burst counter
reg next_burst_hold; // D-input of reg_burst_hold
reg reg_burst_hold; // Burst hold signal
// Early burst termination logic
reg [1:0] reg_early_term_count; // Counts number of early terminated bursts
wire [1:0] next_early_term_count; // D-input for reg_early_term_count
// -----------------------------------------------------------------------------
// Beginning of main code
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
// BURST TRANSFER COUNTER
// -----------------------------------------------------------------------------
//
// The Burst counter is used to count down from the number of transfers the
// master should perform and when the counter reaches zero the bus may be
// passed to another master.
//
// reg_burst_count indicates the number of transfers remaining in the
// current fixed length burst.
// reg_burst_hold is actually a decode of reg_burst_count=0 but is driven from a register
// to improve timing
always @ (HTRANSM or HSELM or HBURSTM or reg_burst_count or reg_burst_hold or reg_early_term_count)
begin : p_next_burst_count_comb
// Force the Burst logic to reset if this port is de-selected. This can
// happen for two reasons:
// 1. The master performs 2 fixed-length bursts back-to-back, but the
// second is to an alternate output port
// 2. The master is performing a fixed-length burst but is de-granted mid-
// way by a local AHB Arbiter
if (!HSELM)
begin
next_burst_count = 4'b0000;
next_burst_hold = 1'b0;
end
// Burst logic is initialised on a NONSEQ transfer (i.e. start of burst)
// IDLE transfers cause the logic to reset
// BUSY transfers pause the decrementer
// SEQ transfers decrement the counter
else
case (HTRANSM)
`TRN_NONSEQ : begin
case (HBURSTM)
`BUR_INCR16, `BUR_WRAP16 : begin
next_burst_count = 4'b1111;
next_burst_hold = 1'b1;
end // case: BUR_INCR16 | BUR_WRAP16
`BUR_INCR8, `BUR_WRAP8 : begin
next_burst_count = 4'b0111;
next_burst_hold = 1'b1;
end // case: BUR_INCR8 | BUR_WRAP8
`BUR_INCR4, `BUR_WRAP4 : begin
next_burst_count = 4'b0011;
next_burst_hold = 1'b1;
end // case: BUR_INCR4 | BUR_WRAP4
`BUR_SINGLE, `BUR_INCR : begin
next_burst_count = 4'b0000;
next_burst_hold = 1'b0;
end // case: BUR_SINGLE | BUR_INCR
default : begin
next_burst_count = 4'bxxxx;
next_burst_hold = 1'bx;
end // case: default
endcase // case(HBURSTM)
// Prevent early burst termination from keeping hold of the port
if (reg_early_term_count == 2'b10)
begin
next_burst_hold = 1'b0;
next_burst_count = 4'd0;
end
end // case: `TRN_NONSEQ
`TRN_SEQ : begin
next_burst_count = reg_burst_count - 4'b1;
if (reg_burst_count == 4'b0001)
next_burst_hold = 1'b0;
else
next_burst_hold = reg_burst_hold;
end // case: `TRN_SEQ
`TRN_BUSY : begin
next_burst_count = reg_burst_count;
next_burst_hold = reg_burst_hold;
end // case: `TRN_BUSY
`TRN_IDLE : begin
next_burst_count = 4'b0000;
next_burst_hold = 1'b0;
end // case: `TRN_IDLE
default : begin
next_burst_count = 4'bxxxx;
next_burst_hold = 1'bx;
end // case: default
endcase // case(HTRANSM)
end // block: p_next_burst_countComb
assign next_early_term_count = (!next_burst_hold) ? 2'b00 :
(reg_burst_hold & (HTRANSM == `TRN_NONSEQ)) ?
reg_early_term_count + 2'b1 :
reg_early_term_count;
// Sequential process
always @ (negedge HRESETn or posedge HCLK)
begin : p_burst_seq
if (!HRESETn)
begin
reg_burst_count <= 4'b0000;
reg_burst_hold <= 1'b0;
reg_early_term_count <= 2'b00;
end // if (HRESETn == 1'b0)
else
if (HREADYM)
begin
reg_burst_count <= next_burst_count;
reg_burst_hold <= next_burst_hold;
reg_early_term_count <= next_early_term_count;
end
end // block: p_burst_seq
// -----------------------------------------------------------------------------
// Port Selection
// -----------------------------------------------------------------------------
// The Output Arbitration function looks at all the requests to use the
// output port and determines which is the highest priority request. This
// version of the arbitration logic uses a fixed priority scheme that is
// gated by a tracking function of the burst boundary. Input port 0 is the
// highest priority, input port 1 is the second highest priority, etc.
// If none of the input ports are requesting then the current port will
// remain active if it is performing IDLE transfers to the selected slave. If
// this is not the case then the no_port signal will be asserted which
// indicates that no input port should be selected.
always @ (
//------------------------------ << start in >> --------------------------------
//----------------------------- << start connection >> -------------------------
req_port<<in>> or
//------------------------------ << end connection >> --------------------------
//------------------------------- << end in >> ---------------------------------
HSELM or HTRANSM or HMASTLOCKM or next_burst_hold or i_addr_in_port
)
begin : p_sel_port_comb
// Default values are used for addr_in_port_next and no_port_next
no_port_next = 1'b0;
addr_in_port_next = i_addr_in_port;
if ( HMASTLOCKM | next_burst_hold )
addr_in_port_next = i_addr_in_port;
//------------------------------ << start in >> --------------------------------
//----------------------------- << start connection >> -------------------------
else if ( req_port<<in>> | ( (i_addr_in_port == <<idw_si_v>>'b<<bin_in>>) & HSELM &
(HTRANSM != 2'b00) ) )
addr_in_port_next = <<idw_si_v>>'b<<bin_in>>;
//------------------------------ << end connection >> --------------------------
//------------------------------- << end in >> ---------------------------------
else if (HSELM)
addr_in_port_next = i_addr_in_port;
else
no_port_next = 1'b1;
end // block: p_sel_port_comb
// Sequential process
always @ (negedge HRESETn or posedge HCLK)
begin : p_addr_in_port_reg
if (!HRESETn)
begin
no_port <= 1'b1;
i_addr_in_port <= {<<idw_si_v>>{1'b0}};
end
else
if (HREADYM)
begin
no_port <= no_port_next;
i_addr_in_port <= addr_in_port_next;
end
end // block: p_addr_in_port_reg
// Drive output with internal version
assign addr_in_port = i_addr_in_port;
endmodule
// --================================= End ===================================--
//-----------------------------------------------------------------------------
// The confidential and proprietary information contained in this file may
// only be used by a person authorised under and to the extent permitted
// by a subsisting licensing agreement from Arm Limited or its affiliates.
//
// (C) COPYRIGHT 2001-<<copyright_year>> Arm Limited or its affiliates.
// ALL RIGHTS RESERVED
//
// This entire notice must be reproduced on all copies of this file
// and copies of this file may only be made by a person if such person is
// permitted to do so under the terms of a subsisting license agreement
// from Arm Limited or its affiliates.
//
// SVN Information
//
// Checked In : $Date: 2017-10-10 15:55:38 +0100 (Tue, 10 Oct 2017) $
//
// Revision : $Revision: 371321 $
//
// Release Information : Cortex-M System Design Kit-r1p1-00rel0
//
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
// Abstract : The MatrixDecode is used to determine which output
// stage is required for a particular access. Addresses
// that do not map to an Output port are diverted to
// the local default slave.
//
// Notes : The bus matrix has <<connectivity>> connectivity.
//
//-----------------------------------------------------------------------------
<<timescale_directive>>
module <<matrix_decode_name>> (
// Common AHB signals
HCLK,
HRESETn,
//---------------------------- << start remap >> -------------------------------
// Internal address remapping control
remapping_dec,
//----------------------------- << end remap >> --------------------------------
// Signals from the Input stage
HREADYS,
sel_dec,
decode_addr_dec,
trans_dec,
//----------------------------- << start out >> --------------------------------
//----------------------------- << start connection >> -------------------------
// Bus-switch output <<out>>
active_dec<<out>>,
readyout_dec<<out>>,
resp_dec<<out>>,
rdata_dec<<out>>,
//---------------------------- << start user >> --------------------------------
ruser_dec<<out>>,
//----------------------------- << end user >> ---------------------------------
//------------------------------ << end connection >> --------------------------
//------------------------------ << end out >> ---------------------------------
// Output port selection signals
//----------------------------- << start out >> --------------------------------
//----------------------------- << start connection >> -------------------------
sel_dec<<out>>,
//------------------------------ << end connection >> --------------------------
//------------------------------ << end out >> ---------------------------------
// Selected Output port data and control signals
active_dec,
HREADYOUTS,
HRESPS,
//---------------------------- << start user >> --------------------------------
HRUSERS,
//----------------------------- << end user >> ---------------------------------
HRDATAS
);
// -----------------------------------------------------------------------------
// Input and Output declarations
// -----------------------------------------------------------------------------
// Common AHB signals
input HCLK; // AHB System Clock
input HRESETn; // AHB System Reset
//---------------------------- << start remap >> -------------------------------
// Internal address remapping control
input [<<idw_remap>>:0] remapping_dec; // Internal remap signal
//----------------------------- << end remap >> --------------------------------
// Signals from the Input stage
input HREADYS; // Transfer done
input sel_dec; // HSEL input
input [<<addr>>:10] decode_addr_dec; // HADDR decoder input
input [1:0] trans_dec; // Input port HTRANS signal
//----------------------------- << start out >> --------------------------------
//----------------------------- << start connection >> -------------------------
// Bus-switch output MI<<out>>
input active_dec<<out>>; // Output stage MI<<out>> active_dec signal
input readyout_dec<<out>>; // HREADYOUT input
input [<<resp>>:0] resp_dec<<out>>; // HRESP input
input [<<data>>:0] rdata_dec<<out>>; // HRDATA input
//---------------------------- << start user >> --------------------------------
input [<<user>>:0] ruser_dec<<out>>; // HRUSER input
//----------------------------- << end user >> ---------------------------------
//------------------------------ << end connection >> --------------------------
//------------------------------ << end out >> ---------------------------------
// Output port selection signals
//----------------------------- << start out >> --------------------------------
//----------------------------- << start connection >> -------------------------
output sel_dec<<out>>; // HSEL output
//------------------------------ << end connection >> --------------------------
//------------------------------ << end out >> ---------------------------------
// Selected Output port data and control signals
output active_dec; // Combinatorial active_dec O/P
output HREADYOUTS; // HREADY feedback output
output [<<resp>>:0] HRESPS; // Transfer response
//---------------------------- << start user >> --------------------------------
output [<<user>>:0] HRUSERS; // User read Data
//----------------------------- << end user >> ---------------------------------
output [<<data>>:0] HRDATAS; // Read Data
// -----------------------------------------------------------------------------
// Wire declarations
// -----------------------------------------------------------------------------
// Common AHB signals
wire HCLK; // AHB System Clock
wire HRESETn; // AHB System Reset
//---------------------------- << start remap >> -------------------------------
// Internal address remapping control
wire [<<idw_remap>>:0] remapping_dec; // Internal remap signal
//----------------------------- << end remap >> --------------------------------
// Signals from the Input stage
wire HREADYS; // Transfer done
wire sel_dec; // HSEL input
wire [<<addr>>:10] decode_addr_dec; // HADDR input
wire [1:0] trans_dec; // Input port HTRANS signal
//----------------------------- << start out >> --------------------------------
//----------------------------- << start connection >> -------------------------
// Bus-switch output MI<<out>>
wire active_dec<<out>>; // active_dec signal
wire readyout_dec<<out>>; // HREADYOUT input
wire [<<resp>>:0] resp_dec<<out>>; // HRESP input
wire [<<data>>:0] rdata_dec<<out>>; // HRDATA input
//---------------------------- << start user >> --------------------------------
wire [<<user>>:0] ruser_dec<<out>>; // HRUSER input
//----------------------------- << end user >> ---------------------------------
reg sel_dec<<out>>; // HSEL output
//------------------------------ << end connection >> --------------------------
//------------------------------ << end out >> ---------------------------------
// -----------------------------------------------------------------------------
// Signal declarations
// -----------------------------------------------------------------------------
// Selected Output port data and control signals
reg active_dec; // Combinatorial active_dec O/P signal
reg HREADYOUTS; // Combinatorial HREADYOUT signal
reg [<<resp>>:0] HRESPS; // Combinatorial HRESPS signal
//---------------------------- << start user >> --------------------------------
reg [<<user>>:0] HRUSERS;
//----------------------------- << end user >> ---------------------------------
reg [<<data>>:0] HRDATAS; // Read data bus
reg [<<idw_mi>>:0] addr_out_port; // Address output ports
reg [<<idw_mi>>:0] data_out_port; // Data output ports
// Default slave signals
reg sel_dft_slv; // HSEL signal
wire readyout_dft_slv; // HREADYOUT signal
wire [<<resp>>:0] resp_dft_slv; // Combinatorial HRESPS signal
// -----------------------------------------------------------------------------
// Beginning of main code
// -----------------------------------------------------------------------------
//------------------------------------------------------------------------------
// Default slave (accessed when HADDR is unmapped)
//------------------------------------------------------------------------------
<<default_slave_name>> u_<<default_slave_name>> (
// Common AHB signals
.HCLK (HCLK),
.HRESETn (HRESETn),
// AHB Control signals
.HSEL (sel_dft_slv),
.HTRANS (trans_dec),
.HREADY (HREADYS),
.HREADYOUT (readyout_dft_slv),
.HRESP (resp_dft_slv)
);
//------------------------------------------------------------------------------
// Address phase signals
//------------------------------------------------------------------------------
// The address decode is done in two stages. This is so that the address
// decode occurs in only one process, p_addr_out_portComb, and then the select
// signal is factored in.
//
// Note that the hexadecimal address values are reformatted to align with the
// lower bound of decode_addr_dec[<<addr>>:10], which is not a hex character boundary
always @ (
//----------------------------- << start map >> --------------------------------
decode_addr_dec or data_out_port or trans_dec
//----------------------------- << end map >> ----------------------------------
//---------------------------- << start remap >> -------------------------------
decode_addr_dec or
remapping_dec or data_out_port or trans_dec
//----------------------------- << end remap >> --------------------------------
)
begin : p_addr_out_port_comb
// Only switch if there is an active transfer
if (trans_dec != 2'b00)
begin
//----------------------------- << start map >> --------------------------------
//----------------------------- << start out >> --------------------------------
//----------------------------- << start addr_map >> ---------------------------
//----------------------------- << start addr_region >> ------------------------
// Address region <<address_map>>
<<mdelse>>if ((decode_addr_dec >= <<mem_lo>>) & (decode_addr_dec <= <<mem_hi>>))
addr_out_port = <<idw_mi_v>>'b0<<bin_out>>; // Select Output port MI<<out>>
//------------------------------ << end addr_region >> -------------------------
//----------------------------- << end addr_map >> -----------------------------
//------------------------------ << end out >> ---------------------------------
else
addr_out_port = <<idw_mi_v>>'b<<dsid_bin>>; // Select the default slave
//----------------------------- << end map >> ----------------------------------
//---------------------------- << start remap >> -------------------------------
case (remapping_dec) // Composition: <<remapping_vector>>
//----------------------------- << start remap_state >> ------------------------
<<idw_remap_v>>'b<<bin_remapstate>> : begin
//----------------------------- << start remap_bit >> --------------------------
//----------------------------- << start addr_remap >> -------------------------
//----------------------------- << start remap_region >> -----------------------
// Remapped address region <<address_map>> due to REMAP[<<remapping_bit>>]
<<mdelse>>if ((decode_addr_dec >= <<mem_lo>>) & (decode_addr_dec <= <<mem_hi>>))
addr_out_port = <<idw_mi_v>>'b0<<bin_out>>; // Select Output port MI<<out>>
//------------------------------ << end remap_region >> -------------------------
//----------------------------- << end addr_remap >> ---------------------------
//------------------------------ << end remap_bit >> ---------------------------
//----------------------------- << start out >> --------------------------------
//----------------------------- << start addr_map >> ---------------------------
//----------------------------- << start addr_region >> ------------------------
// <<region_type>> address region <<address_map>>
<<mdelse>>if ((decode_addr_dec >= <<mem_lo>>) & (decode_addr_dec <= <<mem_hi>>))
addr_out_port = <<idw_mi_v>>'b0<<bin_out>>; // Select Output port MI<<out>>
//------------------------------ << end addr_region >> -------------------------
//----------------------------- << end addr_map >> -----------------------------
//------------------------------ << end out >> ---------------------------------
else
addr_out_port = <<idw_mi_v>>'b<<dsid_bin>>; // Select the default slave
end
//------------------------------ << end remap_state >> -------------------------
default : addr_out_port = {<<idw_mi_v>>{1'bx}};
endcase
//----------------------------- << end remap >> --------------------------------
end // if (trans_dec != 2'b00)
else
addr_out_port = data_out_port; // Stay on last port if no activity
end // block: p_addr_out_port_comb
// Select signal decode
always @ (sel_dec or addr_out_port)
begin : p_sel_comb
//----------------------------- << start out >> --------------------------------
//----------------------------- << start connection >> -------------------------
sel_dec<<out>> = 1'b0;
//------------------------------ << end connection >> --------------------------
//------------------------------ << end out >> ---------------------------------
sel_dft_slv = 1'b0;
if (sel_dec)
case (addr_out_port)
//----------------------------- << start out >> --------------------------------
//----------------------------- << start connection >> -------------------------
<<idw_mi_v>>'b0<<bin_out>> : sel_dec<<out>> = 1'b1;
//------------------------------ << end connection >> --------------------------
//------------------------------ << end out >> ---------------------------------
<<idw_mi_v>>'b<<dsid_bin>> : sel_dft_slv = 1'b1; // Select the default slave
default : begin
//----------------------------- << start out >> --------------------------------
//----------------------------- << start connection >> -------------------------
sel_dec<<out>> = 1'bx;
//------------------------------ << end connection >> --------------------------
//------------------------------ << end out >> ---------------------------------
sel_dft_slv = 1'bx;
end
endcase // case(addr_out_port)
end // block: p_sel_comb
// The decoder selects the appropriate active_dec signal depending on which
// output stage is required for the transfer.
always @ (
//----------------------------- << start out >> --------------------------------
//----------------------------- << start connection >> -------------------------
active_dec<<out>> or
//------------------------------ << end connection >> --------------------------
//------------------------------ << end out >> ---------------------------------
addr_out_port
)
begin : p_active_comb
case (addr_out_port)
//----------------------------- << start out >> --------------------------------
//----------------------------- << start connection >> -------------------------
<<idw_mi_v>>'b0<<bin_out>> : active_dec = active_dec<<out>>;
//------------------------------ << end connection >> --------------------------
//------------------------------ << end out >> ---------------------------------
<<idw_mi_v>>'b<<dsid_bin>> : active_dec = 1'b1; // Select the default slave
default : active_dec = 1'bx;
endcase // case(addr_out_port)
end // block: p_active_comb
//------------------------------------------------------------------------------
// Data phase signals
//------------------------------------------------------------------------------
// The data_out_port needs to be updated when HREADY from the input stage is high.
// Note: HREADY must be used, not HREADYOUT, because there are occaisions
// (namely when the holding register gets loaded) when HREADYOUT may be low
// but HREADY is high, and in this case it is important that the data_out_port
// gets updated.
// When the port is inactive, the default slave is selected to prevent toggling.
always @ (negedge HRESETn or posedge HCLK)
begin : p_data_out_port_seq
if (~HRESETn)
data_out_port <= <<idw_mi_v>>'b<<dsid_bin>>;
else
if (HREADYS)
if (sel_dec & trans_dec[1])
data_out_port <= addr_out_port;
else
data_out_port <= <<idw_mi_v>>'b<<dsid_bin>>;
end // block: p_data_out_port_seq
// HREADYOUTS output decode
always @ (
readyout_dft_slv or
//----------------------------- << start out >> --------------------------------
//----------------------------- << start connection >> -------------------------
readyout_dec<<out>> or
//------------------------------ << end connection >> --------------------------
//------------------------------ << end out >> ---------------------------------
data_out_port
)
begin : p_ready_comb
case (data_out_port)
//----------------------------- << start out >> --------------------------------
//----------------------------- << start connection >> -------------------------
<<idw_mi_v>>'b0<<bin_out>> : HREADYOUTS = readyout_dec<<out>>;
//------------------------------ << end connection >> --------------------------
//------------------------------ << end out >> ---------------------------------
<<idw_mi_v>>'b<<dsid_bin>> : HREADYOUTS = readyout_dft_slv; // Select the default slave
default : HREADYOUTS = 1'bx;
endcase // case(data_out_port)
end // block: p_ready_comb
// HRESPS output decode
always @ (
resp_dft_slv or
//----------------------------- << start out >> --------------------------------
//----------------------------- << start connection >> -------------------------
resp_dec<<out>> or
//------------------------------ << end connection >> --------------------------
//------------------------------ << end out >> ---------------------------------
data_out_port
)
begin : p_resp_comb
case (data_out_port)
//----------------------------- << start out >> --------------------------------
//----------------------------- << start connection >> -------------------------
<<idw_mi_v>>'b0<<bin_out>> : HRESPS = resp_dec<<out>>;
//------------------------------ << end connection >> --------------------------
//------------------------------ << end out >> ---------------------------------
<<idw_mi_v>>'b<<dsid_bin>> : HRESPS = resp_dft_slv; // Select the default slave
default : HRESPS = {<<resp_v>>{1'bx}};
endcase // case (data_out_port)
end // block: p_resp_comb
// HRDATAS output decode
always @ (
//----------------------------- << start out >> --------------------------------
//----------------------------- << start connection >> -------------------------
rdata_dec<<out>> or
//------------------------------ << end connection >> --------------------------
//------------------------------ << end out >> ---------------------------------
data_out_port
)
begin : p_rdata_comb
case (data_out_port)
//----------------------------- << start out >> --------------------------------
//----------------------------- << start connection >> -------------------------
<<idw_mi_v>>'b0<<bin_out>> : HRDATAS = rdata_dec<<out>>;
//------------------------------ << end connection >> --------------------------
//------------------------------ << end out >> ---------------------------------
<<idw_mi_v>>'b<<dsid_bin>> : HRDATAS = {<<data_v>>{1'b0}}; // Select the default slave
default : HRDATAS = {<<data_v>>{1'bx}};
endcase // case (data_out_port)
end // block: p_rdata_comb
//---------------------------- << start user >> --------------------------------
// HRUSERS output decode
always @ (
//----------------------------- << start out >> --------------------------------
//----------------------------- << start connection >> -------------------------
ruser_dec<<out>> or
//------------------------------ << end connection >> --------------------------
//------------------------------ << end out >> ---------------------------------
data_out_port
)
begin : p_ruser_comb
case (data_out_port)
//----------------------------- << start out >> --------------------------------
//----------------------------- << start connection >> -------------------------
<<idw_mi_v>>'b0<<bin_out>> : HRUSERS = ruser_dec<<out>>;
//------------------------------ << end connection >> --------------------------
//------------------------------ << end out >> ---------------------------------
<<idw_mi_v>>'b<<dsid_bin>> : HRUSERS = {<<user_v>>{1'b0}}; // Select the default slave
default : HRUSERS = {<<user_v>>{1'bx}};
endcase // case (data_out_port)
end // block: p_ruser_comb
//----------------------------- << end user >> ---------------------------------
endmodule
// --================================= End ===================================--
//-----------------------------------------------------------------------------
// The confidential and proprietary information contained in this file may
// only be used by a person authorised under and to the extent permitted
// by a subsisting licensing agreement from Arm Limited or its affiliates.
//
// (C) COPYRIGHT 2001-<<copyright_year>> Arm Limited or its affiliates.
// ALL RIGHTS RESERVED
//
// This entire notice must be reproduced on all copies of this file
// and copies of this file may only be made by a person if such person is
// permitted to do so under the terms of a subsisting license agreement
// from Arm Limited or its affiliates.
//
// SVN Information
//
// Checked In : $Date: 2017-10-10 15:55:38 +0100 (Tue, 10 Oct 2017) $
//
// Revision : $Revision: 371321 $
//
// Release Information : Cortex-M System Design Kit-r1p1-00rel0
//
//-----------------------------------------------------------------------------
//
// -----------------------------------------------------------------------------
// Abstract : Default slave used to drive the slave response signals
// when there are no other slaves selected.
//-----------------------------------------------------------------------------
<<timescale_directive>>
module <<default_slave_name>> (
// Common AHB signals
HCLK,
HRESETn,
// AHB control input signals
HSEL,
HTRANS,
HREADY,
// AHB control output signals
HREADYOUT,
HRESP
);
// -----------------------------------------------------------------------------
// Input and Output declarations
// -----------------------------------------------------------------------------
// Common AHB signals
input HCLK; // AHB System Clock
input HRESETn; // AHB System Reset
// AHB control input signals
input HSEL; // Slave Select
input [1:0] HTRANS; // Transfer type
input HREADY; // Transfer done
// AHB control output signals
output HREADYOUT; // HREADY feedback
output [<<resp>>:0] HRESP; // Transfer response
// -----------------------------------------------------------------------------
// Constant declarations
// -----------------------------------------------------------------------------
// HRESP transfer response signal encoding
`define RSP_OKAY <<resp_v>>'b<<bin_resp_okay>> // OKAY response
`define RSP_ERROR <<resp_v>>'b<<bin_resp_error>> // ERROR response
`define RSP_RETRY <<resp_v>>'b<<bin_resp_retry>> // RETRY response
`define RSP_SPLIT <<resp_v>>'b<<bin_resp_split>> // SPLIT response
//----------------------------- << start excl >> -------------------------------
`define RSP_XFAIL <<resp_v>>'b<<bin_resp_xfail>>; // XFAIL response
//------------------------------ << end excl >> --------------------------------
// -----------------------------------------------------------------------------
// Input and Output declarations
// -----------------------------------------------------------------------------
// Common AHB signals
wire HCLK; // AHB System Clock
wire HRESETn; // AHB System Reset
// AHB control input signals
wire HSEL; // Slave Select
wire [1:0] HTRANS; // Transfer type
wire HREADY; // Transfer done
// AHB control output signals
wire HREADYOUT; // HREADY feedback
wire [<<resp>>:0] HRESP; // Transfer response
// -----------------------------------------------------------------------------
// Signal declarations
// -----------------------------------------------------------------------------
wire invalid; // Set during invalid transfer
wire hready_next; // Controls generation of HREADYOUT output
reg i_hreadyout; // HREADYOUT register
wire [<<resp>>:0] hresp_next; // Generated response
reg [<<resp>>:0] i_hresp; // HRESP register
// -----------------------------------------------------------------------------
// Beginning of main code
// -----------------------------------------------------------------------------
assign invalid = ( HREADY & HSEL & HTRANS[1] );
assign hready_next = i_hreadyout ? ~invalid : 1'b1 ;
assign hresp_next = invalid ? `RSP_ERROR : `RSP_OKAY;
always @(negedge HRESETn or posedge HCLK)
begin : p_resp_seq
if (~HRESETn)
begin
i_hreadyout <= 1'b1;
i_hresp <= `RSP_OKAY;
end
else
begin
i_hreadyout <= hready_next;
if (i_hreadyout)
i_hresp <= hresp_next;
end
end
// Drive outputs with internal versions
assign HREADYOUT = i_hreadyout;
assign HRESP = i_hresp;
endmodule
// --================================= End ===================================--
//-----------------------------------------------------------------------------
// The confidential and proprietary information contained in this file may
// only be used by a person authorised under and to the extent permitted
// by a subsisting licensing agreement from Arm Limited or its affiliates.
//
// (C) COPYRIGHT 2001-<<copyright_year>> Arm Limited or its affiliates.
// ALL RIGHTS RESERVED
//
// This entire notice must be reproduced on all copies of this file
// and copies of this file may only be made by a person if such person is
// permitted to do so under the terms of a subsisting license agreement
// from Arm Limited or its affiliates.
//
// SVN Information
//
// Checked In : $Date: 2017-10-10 15:55:38 +0100 (Tue, 10 Oct 2017) $
//
// Revision : $Revision: 371321 $
//
// Release Information : Cortex-M System Design Kit-r1p1-00rel0
//
//-----------------------------------------------------------------------------
//
//------------------------------------------------------------------------------
// Abstract : The Output Arbitration is used to determine which
// of the input stages will be given access to the
// shared slave.
//
// Notes : The bus matrix has <<connectivity>> connectivity.
//
//-----------------------------------------------------------------------------
<<timescale_directive>>
module <<output_arb_name>> (
// Common AHB signals
HCLK ,
HRESETn,
// Input port request signals
//------------------------------ << start in >> --------------------------------
//----------------------------- << start connection >> -------------------------
req_port<<in>>,
//------------------------------ << end connection >> --------------------------
//------------------------------- << end in >> ---------------------------------
HREADYM,
HSELM,
HTRANSM,
HBURSTM,
HMASTLOCKM,
// Arbiter outputs
addr_in_port,
no_port
);
// -----------------------------------------------------------------------------
// Input and Output declarations
// -----------------------------------------------------------------------------
// Common AHB signals
input HCLK; // AHB system clock
input HRESETn; // AHB system reset
//------------------------------ << start in >> --------------------------------
//----------------------------- << start connection >> -------------------------
input req_port<<in>>; // Port <<in>> request signal
//------------------------------ << end connection >> --------------------------
//------------------------------- << end in >> ---------------------------------
input HREADYM; // Transfer done
input HSELM; // Slave select line
input [1:0] HTRANSM; // Transfer type
input [2:0] HBURSTM; // Burst type
input HMASTLOCKM; // Locked transfer
output [<<idw_si>>:0] addr_in_port; // Port address input
output no_port; // No port selected signal
// -----------------------------------------------------------------------------
// Wire declarations
// -----------------------------------------------------------------------------
wire HCLK; // AHB system clock
wire HRESETn; // AHB system reset
//------------------------------ << start in >> --------------------------------
//----------------------------- << start connection >> -------------------------
wire req_port<<in>>; // Port <<in>> request signal
//------------------------------ << end connection >> --------------------------
//------------------------------- << end in >> ---------------------------------
wire HREADYM; // Transfer done
wire HSELM; // Slave select line
wire [1:0] HTRANSM; // Transfer type
wire HMASTLOCKM; // Locked transfer
wire [<<idw_si>>:0] addr_in_port; // Port address input
reg no_port; // No port selected signal
// -----------------------------------------------------------------------------
// Signal declarations
// -----------------------------------------------------------------------------
reg [<<idw_si>>:0] addr_in_port_next; // D-input of addr_in_port
reg [<<idw_si>>:0] iaddr_in_port; // Internal version of addr_in_port
reg no_port_next; // D-input of no_port
// -----------------------------------------------------------------------------
// Beginning of main code
// -----------------------------------------------------------------------------
//------------------------------------------------------------------------------
// Port Selection
//------------------------------------------------------------------------------
// The Output Arbitration function looks at all the requests to use the
// output port and determines which is the highest priority request. This
// version of the arbitration logic uses a fixed priority scheme where input
// port 0 is the highest priority, input port 1 is the second highest
// priority, etc.
// If none of the input ports are requesting then the current port will
// remain active if it is performing IDLE transfers to the selected slave. If
// this is not the case then the no_port signal will be asserted which
// indicates that no input port should be selected.
always @ (
//------------------------------ << start in >> --------------------------------
//----------------------------- << start connection >> -------------------------
req_port<<in>> or
//------------------------------ << end connection >> --------------------------
//------------------------------- << end in >> ---------------------------------
HSELM or HTRANSM or HMASTLOCKM or iaddr_in_port
)
begin : p_sel_port_comb
// Default values are used for addr_in_port_next and no_port_next
no_port_next = 1'b0;
addr_in_port_next = iaddr_in_port;
if (HMASTLOCKM)
addr_in_port_next = iaddr_in_port;
//------------------------------ << start in >> --------------------------------
//----------------------------- << start connection >> -------------------------
else if ( req_port<<in>> | ( (iaddr_in_port == <<idw_si_v>>'b<<bin_in>>) & HSELM &
(HTRANSM != 2'b00) ) )
addr_in_port_next = <<idw_si_v>>'b<<bin_in>>;
//------------------------------ << end connection >> --------------------------
//------------------------------- << end in >> ---------------------------------
else if (HSELM)
addr_in_port_next = iaddr_in_port;
else
no_port_next = 1'b1;
end // block: p_sel_port_comb
// Sequential process
always @ (negedge HRESETn or posedge HCLK)
begin : p_addr_in_port_reg
if (~HRESETn)
begin
no_port <= 1'b1;
iaddr_in_port <= {<<idw_si_v>>{1'b0}};
end
else
if (HREADYM)
begin
no_port <= no_port_next;
iaddr_in_port <= addr_in_port_next;
end
end // block: p_addr_in_port_reg
// Drive output with internal version
assign addr_in_port = iaddr_in_port;
endmodule
// --================================= End ===================================--
//-----------------------------------------------------------------------------
// The confidential and proprietary information contained in this file may
// only be used by a person authorised under and to the extent permitted
// by a subsisting licensing agreement from Arm Limited or its affiliates.
//
// (C) COPYRIGHT 2001-<<copyright_year>> Arm Limited or its affiliates.
// ALL RIGHTS RESERVED
//
// This entire notice must be reproduced on all copies of this file
// and copies of this file may only be made by a person if such person is
// permitted to do so under the terms of a subsisting license agreement
// from Arm Limited or its affiliates.
//
// SVN Information
//
// Checked In : $Date: 2017-10-10 15:55:38 +0100 (Tue, 10 Oct 2017) $
//
// Revision : $Revision: 371321 $
//
// Release Information : Cortex-M System Design Kit-r1p1-00rel0
//
//-----------------------------------------------------------------------------
//
//------------------------------------------------------------------------------
// Abstract : The Input Stage is used to hold a pending transfer
// when the required output stage is not available.
//---------------------------- << start unalign >> -----------------------------
// Supports ARMv6 AMBA extensions for unaligned access.
//----------------------------- << end unalign >> ------------------------------
//----------------------------- << start excl >> -------------------------------
// Supports ARMv6 AMBA extensions for exclusive access.
//------------------------------ << end excl >> --------------------------------
//
//-----------------------------------------------------------------------------
<<timescale_directive>>
module <<input_stage_name>> (
// Common AHB signals
HCLK,
HRESETn,
// Input Port Address/Control Signals
HSELS,
HADDRS,
//---------------------------- << start user >> --------------------------------
HAUSERS,
//----------------------------- << end user >> ---------------------------------
HTRANSS,
HWRITES,
HSIZES,
HBURSTS,
HPROTS,
//---------------------------- << start unalign >> -----------------------------
HUNALIGNS,
HBSTRBS,
//----------------------------- << end unalign >> ------------------------------
HMASTERS,
HMASTLOCKS,
HREADYS,
// Internal Response
active_ip,
readyout_ip,
resp_ip,
// Input Port Response
HREADYOUTS,
HRESPS,
// Internal Address/Control Signals
sel_ip,
addr_ip,
//---------------------------- << start user >> --------------------------------
auser_ip,
//----------------------------- << end user >> ---------------------------------
trans_ip,
write_ip,
size_ip,
burst_ip,
prot_ip,
//---------------------------- << start unalign >> -----------------------------
unalign_ip,
bstrb_ip,
//----------------------------- << end unalign >> ------------------------------
master_ip,
mastlock_ip,
held_tran_ip
);
// -----------------------------------------------------------------------------
// Input and Output declarations
// -----------------------------------------------------------------------------
input HCLK; // AHB System Clock
input HRESETn; // AHB System Reset
input HSELS; // Slave Select from AHB
input [<<addr>>:0] HADDRS; // Address bus from AHB
//---------------------------- << start user >> --------------------------------
input [<<user>>:0] HAUSERS; // Additional user adress bus
//----------------------------- << end user >> ---------------------------------
input [1:0] HTRANSS; // Transfer type from AHB
input HWRITES; // Transfer direction from AHB
input [2:0] HSIZES; // Transfer size from AHB
input [2:0] HBURSTS; // Burst type from AHB
input [<<prot>>:0] HPROTS; // Protection control from AHB
//---------------------------- << start unalign >> -----------------------------
input HUNALIGNS; // Unalign signal from AHB
input [<<bstrb>>:0] HBSTRBS; // Active Byte Lane strobes
//----------------------------- << end unalign >> ------------------------------
input [3:0] HMASTERS; // Master number from AHB
input HMASTLOCKS; // Locked Sequence from AHB
input HREADYS; // Transfer done from AHB
input active_ip; // active_ip signal
input readyout_ip; // HREADYOUT input
input [<<resp>>:0] resp_ip; // HRESP input
output HREADYOUTS; // HREADY feedback to AHB
output [<<resp>>:0] HRESPS; // Transfer response to AHB
output sel_ip; // HSEL output
output [<<addr>>:0] addr_ip; // HADDR output
//---------------------------- << start user >> --------------------------------
output [<<user>>:0] auser_ip; // HAUSER output
//----------------------------- << end user >> ---------------------------------
output [1:0] trans_ip; // HTRANS output
output write_ip; // HWRITE output
output [2:0] size_ip; // HSIZE output
output [2:0] burst_ip; // HBURST output
output [<<prot>>:0] prot_ip; // HPROT output
//---------------------------- << start unalign >> -----------------------------
output unalign_ip; // HUNALIGN output
output [<<bstrb>>:0] bstrb_ip; // HBSTRB output
//----------------------------- << end unalign >> ------------------------------
output [3:0] master_ip; // HMASTER output
output mastlock_ip; // HMASTLOCK output
output held_tran_ip; // Holding register active flag
// -----------------------------------------------------------------------------
// Constant declarations
// -----------------------------------------------------------------------------
// HTRANS transfer type signal encoding
`define TRN_IDLE 2'b00 // Idle Transfer
`define TRN_BUSY 2'b01 // Busy Transfer
`define TRN_NONSEQ 2'b10 // Nonsequential transfer
`define TRN_SEQ 2'b11 // Sequential transfer
// HBURST transfer type signal encoding
`define BUR_SINGLE 3'b000 // Single BURST
`define BUR_INCR 3'b001 // Incremental BURSTS
`define BUR_WRAP4 3'b010 // 4-beat wrap
`define BUR_INCR4 3'b011 // 4-beat incr
`define BUR_WRAP8 3'b100 // 8-beat wrap
`define BUR_INCR8 3'b101 // 8-beat incr
`define BUR_WRAP16 3'b110 // 16-beat wrap
`define BUR_INCR16 3'b111 // 16-beat incr
// HRESP signal encoding
`define RSP_OKAY <<resp_v>>'b<<bin_resp_okay>> // OKAY response
`define RSP_ERROR <<resp_v>>'b<<bin_resp_error>> // ERROR response
`define RSP_RETRY <<resp_v>>'b<<bin_resp_retry>> // RETRY response
`define RSP_SPLIT <<resp_v>>'b<<bin_resp_split>> // SPLIT response
//----------------------------- << start excl >> -------------------------------
`define RSP_XFAIL <<resp_v>>'b<<bin_resp_xfail>>; // XFAIL response
//------------------------------ << end excl >> --------------------------------
// -----------------------------------------------------------------------------
// Wire declarations
// -----------------------------------------------------------------------------
wire HCLK; // AHB System Clock
wire HRESETn; // AHB System Reset
wire HSELS; // Slave Select from AHB
wire [<<addr>>:0] HADDRS; // Address bus from AHB
//---------------------------- << start user >> --------------------------------
wire [<<user>>:0] HAUSERS; // Additional user adress bus
//----------------------------- << end user >> ---------------------------------
wire [1:0] HTRANSS; // Transfer type from AHB
wire HWRITES; // Transfer direction from AHB
wire [2:0] HSIZES; // Transfer size from AHB
wire [2:0] HBURSTS; // Burst type from AHB
wire [<<prot>>:0] HPROTS; // Protection control from AHB
//---------------------------- << start unalign >> -----------------------------
wire HUNALIGNS; // Unalign signal from AHB
wire [<<bstrb>>:0] HBSTRBS; // Active Byte Lane strobes
//----------------------------- << end unalign >> ------------------------------
wire [3:0] HMASTERS; // Master number from AHB
wire HMASTLOCKS; // Locked Sequence from AHB
wire HREADYS; // Transfer done from AHB
reg HREADYOUTS; // HREADY feedback to AHB
reg [<<resp>>:0] HRESPS; // Transfer response to AHB
reg sel_ip; // HSEL output
reg [<<addr>>:0] addr_ip; // HADDR output
//---------------------------- << start user >> --------------------------------
reg [<<user>>:0] auser_ip; // HAUSER output
//----------------------------- << end user >> ---------------------------------
wire [1:0] trans_ip; // HTRANS output
reg write_ip; // HWRITE output
reg [2:0] size_ip; // HSIZE output
wire [2:0] burst_ip; // HBURST output
reg [<<prot>>:0] prot_ip; // HPROT output
//---------------------------- << start unalign >> -----------------------------
wire unalign_ip; // HUNALIGN output
wire [<<bstrb>>:0] bstrb_ip; // HBSTRB output
//----------------------------- << end unalign >> ------------------------------
reg [3:0] master_ip; // HMASTER output
reg mastlock_ip; // HMASTLOCK output
wire held_tran_ip; // Holding register active flag
wire active_ip; // active_ip signal
wire readyout_ip; // HREADYOUT input
wire [<<resp>>:0] resp_ip; // HRESP input
// -----------------------------------------------------------------------------
// Signal declarations
// -----------------------------------------------------------------------------
wire load_reg; // Holding register load flag
wire pend_tran; // An active transfer cannot complete
reg pend_tran_reg; // Registered version of pend_tran
wire addr_valid; // Indicates address phase of
// valid transfer
reg data_valid; // Indicates data phase of
// valid transfer
reg [1:0] reg_trans; // Registered HTRANSS
reg [<<addr>>:0] reg_addr; // Registered HADDRS
//---------------------------- << start user >> --------------------------------
reg [<<user>>:0] reg_auser;
//----------------------------- << end user >> ---------------------------------
reg reg_write; // Registered HWRITES
reg [2:0] reg_size; // Registered HSIZES
reg [2:0] reg_burst; // Registered HBURSTS
reg [<<prot>>:0] reg_prot; // Registered HPROTS
//---------------------------- << start unalign >> -----------------------------
reg reg_unalign; // Registered HUNALIGNS
reg [<<bstrb>>:0] reg_bstrb; // Registered HBSTRBS
//----------------------------- << end unalign >> ------------------------------
reg [3:0] reg_master; // Registerd HMASTERS
reg reg_mastlock; // Registered HMASTLOCKS
reg [1:0] transb; // HTRANS output used for burst information
reg [1:0] trans_int; // HTRANS output
reg [2:0] burst_int; // HBURST output
reg [3:0] offset_addr; // Address offset for boundary logic
reg [3:0] check_addr; // Address check for wrapped bursts
reg burst_override; // Registered burst_override_next
wire burst_override_next; // Indicates burst has been over-ridden
reg bound; // Registered version of bound_next
wire bound_next; // Indicates boundary wrapping
wire bound_en; // Clock-enable for bound register
// -----------------------------------------------------------------------------
// Beginning of main code
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
// Holding Registers
// -----------------------------------------------------------------------------
// Each input port has a holding register associated with it and a mux to
// select between the register and the direct input path. The control of
// the mux is done simply by selecting the holding register when it is loaded
// with a pending transfer, otherwise the straight through path is used.
always @ (negedge HRESETn or posedge HCLK)
begin : p_holding_reg_seq1
if (~HRESETn)
begin
reg_trans <= 2'b00;
reg_addr <= {<<addr_v>>{1'b0}};
//---------------------------- << start user >> --------------------------------
reg_auser <= {<<user_v>>{1'b0}};
//----------------------------- << end user >> ---------------------------------
reg_write <= 1'b0 ;
reg_size <= 3'b000;
reg_burst <= 3'b000;
reg_prot <= {<<prot_v>>{1'b0}};
//---------------------------- << start unalign >> -----------------------------
reg_unalign <= 1'b0;
reg_bstrb <= {<<bstrb_v>>{1'b0}};
//----------------------------- << end unalign >> ------------------------------
reg_master <= 4'b0000;
reg_mastlock <= 1'b0 ;
end
else
if (load_reg)
begin
reg_trans <= HTRANSS;
reg_addr <= HADDRS;
//---------------------------- << start user >> --------------------------------
reg_auser <= HAUSERS;
//----------------------------- << end user >> ---------------------------------
reg_write <= HWRITES;
reg_size <= HSIZES;
reg_burst <= HBURSTS;
reg_prot <= HPROTS;
//---------------------------- << start unalign >> -----------------------------
reg_unalign <= HUNALIGNS;
reg_bstrb <= HBSTRBS;
//----------------------------- << end unalign >> ------------------------------
reg_master <= HMASTERS;
reg_mastlock <= HMASTLOCKS;
end
end
// addr_valid indicates the address phase of an active (non-BUSY/IDLE)
// transfer to this slave port
assign addr_valid = ( HSELS & HTRANSS[1] );
// The holding register is loaded whenever there is a transfer on the input
// port which is validated by active HREADYS
assign load_reg = ( addr_valid & HREADYS );
// data_valid register
// addr_valid indicates the data phase of an active (non-BUSY/IDLE)
// transfer to this slave port. A valid response (HREADY, HRESP) must be
// generated
always @ (negedge HRESETn or posedge HCLK)
begin : p_data_valid
if (~HRESETn)
data_valid <= 1'b0;
else
if (HREADYS)
data_valid <= addr_valid;
end
// -----------------------------------------------------------------------------
// Generate HeldTran
// -----------------------------------------------------------------------------
// The HeldTran signal is used to indicate when there is an active transfer
// being presented to the output stage, either passing straight through or from
// the holding register.
// pend_tran indicates that an active transfer presented to this
// slave cannot complete immediately. It is always set after the
// load_reg signal has been active. When set, it is cleared when the
// transfer is being driven onto the selected slave (as indicated by
// active_ip being high) and HREADY from the selected slave is high.
assign pend_tran = (load_reg & (~active_ip)) ? 1'b1 :
(active_ip & readyout_ip) ? 1'b0 : pend_tran_reg;
// pend_tran_reg indicates that an active transfer was accepted by the input
// stage,but not by the output stage, and so the holding registers should be
// used
always @ (negedge HRESETn or posedge HCLK)
begin : p_pend_tran_reg
if (~HRESETn)
pend_tran_reg <= 1'b0;
else
pend_tran_reg <= pend_tran;
end
// held_tran_ip indicates an active transfer, and is held whilst that transfer is
// in the holding registers. It passes to the output stage where it acts as
// a request line to the arbitration scheme
assign held_tran_ip = (load_reg | pend_tran_reg);
// The output from this stage is selected from the holding register when
// there is a held transfer. Otherwise the direct path is used.
always @ ( pend_tran_reg or HSELS or HTRANSS or HADDRS or HWRITES or
HSIZES or HBURSTS or HPROTS or HMASTERS or HMASTLOCKS or
//---------------------------- << start user >> --------------------------------
HAUSERS or reg_auser or
//----------------------------- << end user >> ---------------------------------
reg_addr or reg_write or reg_size or reg_burst or reg_prot or
reg_master or reg_mastlock
)
begin : p_mux_comb
if (~pend_tran_reg)
begin
sel_ip = HSELS;
trans_int = HTRANSS;
addr_ip = HADDRS;
//---------------------------- << start user >> --------------------------------
auser_ip = HAUSERS;
//----------------------------- << end user >> ---------------------------------
write_ip = HWRITES;
size_ip = HSIZES;
burst_int = HBURSTS;
prot_ip = HPROTS;
master_ip = HMASTERS;
mastlock_ip = HMASTLOCKS;
end
else
begin
sel_ip = 1'b1;
trans_int = `TRN_NONSEQ;
addr_ip = reg_addr;
//---------------------------- << start user >> --------------------------------
auser_ip = reg_auser;
//----------------------------- << end user >> ---------------------------------
write_ip = reg_write;
size_ip = reg_size;
burst_int = reg_burst;
prot_ip = reg_prot;
master_ip = reg_master;
mastlock_ip = reg_mastlock;
end
end
// The transb output is used to select the correct Burst value when completing
// an interrupted defined-lenght burst.
always @ (pend_tran_reg or HTRANSS or reg_trans)
begin : p_transb_comb
if (~pend_tran_reg)
transb = HTRANSS;
else
transb = reg_trans;
end // block: p_transb_comb
//---------------------------- << start unalign >> -----------------------------
assign unalign_ip = (pend_tran_reg) ? reg_unalign : HUNALIGNS ;
assign bstrb_ip = (pend_tran_reg) ? reg_bstrb : HBSTRBS ;
//----------------------------- << end unalign >> ------------------------------
// Convert SEQ->NONSEQ and BUSY->IDLE when an address boundary is crossed
// whilst the burst type is being over-ridden, i.e. when completing an
// interrupted wrapping burst.
assign trans_ip = (burst_override & bound) ? {trans_int[1], 1'b0}
: trans_int;
assign burst_ip = (burst_override & (transb != `TRN_NONSEQ)) ? `BUR_INCR
: burst_int;
// -----------------------------------------------------------------------------
// HREADYOUT Generation
// -----------------------------------------------------------------------------
// There are three possible sources for the HREADYOUT signal.
// - It is driven LOW when there is a held transfer.
// - It is driven HIGH when not Selected or for Idle/Busy transfers.
// - At all other times it is driven from the appropriate shared
// slave.
always @ (data_valid or pend_tran_reg or readyout_ip or resp_ip)
begin : p_ready_comb
if (~data_valid)
begin
HREADYOUTS = 1'b1;
HRESPS = `RSP_OKAY;
end
else if (pend_tran_reg)
begin
HREADYOUTS = 1'b0;
HRESPS = `RSP_OKAY;
end
else
begin
HREADYOUTS = readyout_ip;
HRESPS = resp_ip;
end
end // block: p_ready_comb
// -----------------------------------------------------------------------------
// Early Burst Termination
// -----------------------------------------------------------------------------
// There are times when the output stage will switch to another input port
// without allowing the current burst to complete. In these cases the HTRANS
// and HBURST signals need to be overriden to ensure that the transfers
// reaching the output port meet the AHB specification.
assign burst_override_next = ( (HTRANSS == `TRN_NONSEQ) |
(HTRANSS == `TRN_IDLE) ) ? 1'b0
: ( (HTRANSS ==`TRN_SEQ) &
load_reg &
(~active_ip) ) ? 1'b1
: burst_override;
// burst_override register
always @ (negedge HRESETn or posedge HCLK)
begin : p_burst_overrideseq
if (~HRESETn)
burst_override <= 1'b0;
else
if (HREADYS)
burst_override <= burst_override_next;
end // block: p_burst_overrideseq
// -----------------------------------------------------------------------------
// Boundary Checking Logic
// -----------------------------------------------------------------------------
// offset_addr
always @ (HADDRS or HSIZES)
begin : p_offset_addr_comb
case (HSIZES)
3'b000 : offset_addr = HADDRS[3:0];
3'b001 : offset_addr = HADDRS[4:1];
3'b010 : offset_addr = HADDRS[5:2];
3'b011 : offset_addr = HADDRS[6:3];
3'b100, 3'b101, 3'b110, 3'b111 :
offset_addr = HADDRS[3:0]; // Sizes >= 128-bits are not supported
default : offset_addr = 4'bxxxx;
endcase
end
// check_addr
always @ (offset_addr or HBURSTS)
begin : p_check_addr_comb
case (HBURSTS)
`BUR_WRAP4 : begin
check_addr[1:0] = offset_addr[1:0];
check_addr[3:2] = 2'b11;
end
`BUR_WRAP8 : begin
check_addr[2:0] = offset_addr[2:0];
check_addr[3] = 1'b1;
end
`BUR_WRAP16 :
check_addr[3:0] = offset_addr[3:0];
`BUR_SINGLE, `BUR_INCR, `BUR_INCR4, `BUR_INCR8, `BUR_INCR16 :
check_addr[3:0] = 4'b0000;
default : check_addr[3:0] = 4'bxxxx;
endcase
end
assign bound_next = ( check_addr == 4'b1111 );
assign bound_en = ( HTRANSS[1] & HREADYS );
// bound register
always @ (negedge HRESETn or posedge HCLK)
begin : p_bound_seq
if (~HRESETn)
bound <= 1'b0;
else
if (bound_en)
bound <= bound_next;
end
endmodule
// --================================= End ===================================--
//-----------------------------------------------------------------------------
// The confidential and proprietary information contained in this file may
// only be used by a person authorised under and to the extent permitted
// by a subsisting licensing agreement from Arm Limited or its affiliates.
//
// (C) COPYRIGHT 2001-<<copyright_year>> Arm Limited or its affiliates.
// ALL RIGHTS RESERVED
//
// This entire notice must be reproduced on all copies of this file
// and copies of this file may only be made by a person if such person is
// permitted to do so under the terms of a subsisting license agreement
// from Arm Limited or its affiliates.
//
// SVN Information
//
// Checked In : $Date: 2017-10-10 15:55:38 +0100 (Tue, 10 Oct 2017) $
//
// Revision : $Revision: 371321 $
//
// Release Information : Cortex-M System Design Kit-r1p1-00rel0
//
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
// Abstract : The Output Stage is used to route the required input
// stage to the shared slave output.
//
// Notes : The bus matrix has <<connectivity>> connectivity,
// and has a <<arbiter_type>> arbiter scheme.
//
//-----------------------------------------------------------------------------
<<timescale_directive>>
module <<output_stage_name>> (
// Common AHB signals
HCLK,
HRESETn,
//------------------------------ << start in >> --------------------------------
//----------------------------- << start connection >> -------------------------
// Port <<in>> Signals
sel_op<<in>>,
addr_op<<in>>,
//---------------------------- << start user >> --------------------------------
auser_op<<in>>,
//----------------------------- << end user >> ---------------------------------
trans_op<<in>>,
write_op<<in>>,
size_op<<in>>,
burst_op<<in>>,
prot_op<<in>>,
//---------------------------- << start unalign >> -----------------------------
unalign_op<<in>>,
bstrb_op<<in>>,
//----------------------------- << end unalign >> ------------------------------
master_op<<in>>,
mastlock_op<<in>>,
wdata_op<<in>>,
//---------------------------- << start user >> --------------------------------
wuser_op<<in>>,
//----------------------------- << end user >> ---------------------------------
held_tran_op<<in>>,
//------------------------------ << end connection >> --------------------------
//------------------------------- << end in >> ---------------------------------
// Slave read data and response
HREADYOUTM,
//------------------------------ << start in >> --------------------------------
//----------------------------- << start connection >> -------------------------
active_op<<in>>,
//------------------------------ << end connection >> --------------------------
//------------------------------- << end in >> ---------------------------------
// Slave Address/Control Signals
HSELM,
HADDRM,
//---------------------------- << start user >> --------------------------------
HAUSERM,
//----------------------------- << end user >> ---------------------------------
HTRANSM,
HWRITEM,
HSIZEM,
HBURSTM,
HPROTM,
//---------------------------- << start unalign >> -----------------------------
HUNALIGNM,
HBSTRBM,
//----------------------------- << end unalign >> ------------------------------
HMASTERM,
HMASTLOCKM,
HREADYMUXM,
//---------------------------- << start user >> --------------------------------
HWUSERM,
//----------------------------- << end user >> ---------------------------------
HWDATAM
);
// -----------------------------------------------------------------------------
// Input and Output declarations
// -----------------------------------------------------------------------------
// Common AHB signals
input HCLK; // AHB system clock
input HRESETn; // AHB system reset
//------------------------------ << start in >> --------------------------------
//----------------------------- << start connection >> -------------------------
// Bus-switch input <<in>>
input sel_op<<in>>; // Port <<in>> HSEL signal
input [<<addr>>:0] addr_op<<in>>; // Port <<in>> HADDR signal
//---------------------------- << start user >> --------------------------------
input [<<user>>:0] auser_op<<in>>; // Port <<in>> HAUSER signal
//----------------------------- << end user >> ---------------------------------
input [1:0] trans_op<<in>>; // Port <<in>> HTRANS signal
input write_op<<in>>; // Port <<in>> HWRITE signal
input [2:0] size_op<<in>>; // Port <<in>> HSIZE signal
input [2:0] burst_op<<in>>; // Port <<in>> HBURST signal
input [<<prot>>:0] prot_op<<in>>; // Port <<in>> HPROT signal
//---------------------------- << start unalign >> -----------------------------
input unalign_op<<in>>; // Port <<in>> HUNALIGN signal
input [<<bstrb>>:0] bstrb_op<<in>>; // Port <<in>> HBSTRB signal
//----------------------------- << end unalign >> ------------------------------
input [3:0] master_op<<in>>; // Port <<in>> HMASTER signal
input mastlock_op<<in>>; // Port <<in>> HMASTLOCK signal
input [<<data>>:0] wdata_op<<in>>; // Port <<in>> HWDATA signal
//---------------------------- << start user >> --------------------------------
input [<<user>>:0] wuser_op<<in>>; // Port <<in>> HWUSER signal
//----------------------------- << end user >> ---------------------------------
input held_tran_op<<in>>; // Port <<in>> HeldTran signal
//------------------------------ << end connection >> --------------------------
//------------------------------- << end in >> ---------------------------------
input HREADYOUTM; // HREADY feedback
//------------------------------ << start in >> --------------------------------
//----------------------------- << start connection >> -------------------------
output active_op<<in>>; // Port <<in>> Active signal
//------------------------------ << end connection >> --------------------------
//------------------------------- << end in >> ---------------------------------
// Slave Address/Control Signals
output HSELM; // Slave select line
output [<<addr>>:0] HADDRM; // Address
//---------------------------- << start user >> --------------------------------
output [<<user>>:0] HAUSERM; // User Address bus
//----------------------------- << end user >> ---------------------------------
output [1:0] HTRANSM; // Transfer type
output HWRITEM; // Transfer direction
output [2:0] HSIZEM; // Transfer size
output [2:0] HBURSTM; // Burst type
output [<<prot>>:0] HPROTM; // Protection control
//---------------------------- << start unalign >> -----------------------------
output HUNALIGNM; // Unaligned transfer
output [<<bstrb>>:0] HBSTRBM; // Byte Lane strobe signal
//----------------------------- << end unalign >> ------------------------------
output [3:0] HMASTERM; // Master ID
output HMASTLOCKM; // Locked transfer
output HREADYMUXM; // Transfer done
//---------------------------- << start user >> --------------------------------
output [<<user>>:0] HWUSERM; // User data bus
//----------------------------- << end user >> ---------------------------------
output [<<data>>:0] HWDATAM; // Write data
// -----------------------------------------------------------------------------
// Wire declarations
// -----------------------------------------------------------------------------
wire HCLK; // AHB system clock
wire HRESETn; // AHB system reset
//------------------------------ << start in >> --------------------------------
//----------------------------- << start connection >> -------------------------
// Bus-switch input <<in>>
wire sel_op<<in>>; // Port <<in>> HSEL signal
wire [<<addr>>:0] addr_op<<in>>; // Port <<in>> HADDR signal
//---------------------------- << start user >> --------------------------------
wire [<<user>>:0] auser_op<<in>>; // Port <<in>> HAUSER signal
//----------------------------- << end user >> ---------------------------------
wire [1:0] trans_op<<in>>; // Port <<in>> HTRANS signal
wire write_op<<in>>; // Port <<in>> HWRITE signal
wire [2:0] size_op<<in>>; // Port <<in>> HSIZE signal
wire [2:0] burst_op<<in>>; // Port <<in>> HBURST signal
wire [<<prot>>:0] prot_op<<in>>; // Port <<in>> HPROT signal
//---------------------------- << start unalign >> -----------------------------
wire unalign_op<<in>>; // Port <<in>> HUNALIGN signal
wire [<<bstrb>>:0] bstrb_op<<in>>; // Port <<in>> HBSTRB signal
//----------------------------- << end unalign >> ------------------------------
wire [3:0] master_op<<in>>; // Port <<in>> HMASTER signal
wire mastlock_op<<in>>; // Port <<in>> HMASTLOCK signal
wire [<<data>>:0] wdata_op<<in>>; // Port <<in>> HWDATA signal
//---------------------------- << start user >> --------------------------------
wire [<<user>>:0] wuser_op<<in>>; // Port <<in>> HWUSER signal
//----------------------------- << end user >> ---------------------------------
wire held_tran_op<<in>>; // Port <<in>> HeldTran signal
reg active_op<<in>>; // Port <<in>> Active signal
//------------------------------ << end connection >> --------------------------
//------------------------------- << end in >> ---------------------------------
// Slave Address/Control Signals
wire HSELM; // Slave select line
reg [<<addr>>:0] HADDRM; // Address
//---------------------------- << start user >> --------------------------------
reg [<<user>>:0] HAUSERM; // User Address bus
//----------------------------- << end user >> ---------------------------------
wire [1:0] HTRANSM; // Transfer type
reg HWRITEM; // Transfer direction
reg [2:0] HSIZEM; // Transfer size
wire [2:0] HBURSTM; // Burst type
reg [<<prot>>:0] HPROTM; // Protection control
//---------------------------- << start unalign >> -----------------------------
reg HUNALIGNM; // Unaligned transfer
reg [<<bstrb>>:0] HBSTRBM; // Byte Lane strobe signal
//----------------------------- << end unalign >> ------------------------------
reg [3:0] HMASTERM; // Master ID
wire HMASTLOCKM; // Locked transfer
wire HREADYMUXM; // Transfer done
//---------------------------- << start user >> --------------------------------
reg [<<user>>:0] HWUSERM; // User data bus
//----------------------------- << end user >> ---------------------------------
reg [<<data>>:0] HWDATAM; // Write data
wire HREADYOUTM; // HREADY feedback
// -----------------------------------------------------------------------------
// Signal declarations
// -----------------------------------------------------------------------------
//------------------------------ << start in >> --------------------------------
//----------------------------- << start connection >> -------------------------
wire req_port<<in>>; // Port <<in>> request signal
//------------------------------ << end connection >> --------------------------
//------------------------------- << end in >> ---------------------------------
wire [<<idw_si>>:0] addr_in_port; // Address input port
reg [<<idw_si>>:0] data_in_port; // Data input port
wire no_port; // No port selected signal
reg slave_sel; // Slave select signal
reg wdata_phase; // Used to prevent unnecesary toggling
reg hsel_lock; // Held HSELS during locked sequence
wire next_hsel_lock; // Pre-registered hsel_lock
wire hlock_arb; // HMASTLOCK modified by HSEL for arbitration
reg i_hselm; // Internal HSELM
reg [1:0] i_htransm; // Internal HTRANSM
reg [2:0] i_hburstm; // Internal HBURSTM
wire i_hreadymuxm; // Internal HREADYMUXM
reg i_hmastlockm; // Internal HMASTLOCKM
// -----------------------------------------------------------------------------
// Beginning of main code
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
// Port Selection
// -----------------------------------------------------------------------------
//------------------------------ << start in >> --------------------------------
//----------------------------- << start connection >> -------------------------
assign req_port<<in>> = held_tran_op<<in>> & sel_op<<in>>;
//------------------------------ << end connection >> --------------------------
//------------------------------- << end in >> ---------------------------------
// Arbiter instance for resolving requests to this output stage
<<output_arb_name>> u_output_arb (
.HCLK (HCLK),
.HRESETn (HRESETn),
//------------------------------ << start in >> --------------------------------
//----------------------------- << start connection >> -------------------------
.req_port<<in>> (req_port<<in>>),
//------------------------------ << end connection >> --------------------------
//------------------------------- << end in >> ---------------------------------
.HREADYM (i_hreadymuxm),
.HSELM (i_hselm),
.HTRANSM (i_htransm),
.HBURSTM (i_hburstm),
.HMASTLOCKM (hlock_arb),
.addr_in_port (addr_in_port),
.no_port (no_port)
);
// Active signal combinatorial decode
always @ (addr_in_port or no_port)
begin : p_active_comb
// Default value(s)
//------------------------------ << start in >> --------------------------------
//----------------------------- << start connection >> -------------------------
active_op<<in>> = 1'b0;
//------------------------------ << end connection >> --------------------------
//------------------------------- << end in >> ---------------------------------
// Decode selection when enabled
if (~no_port)
case (addr_in_port)
//------------------------------ << start in >> --------------------------------
//----------------------------- << start connection >> -------------------------
<<idw_si_v>>'b<<bin_in>> : active_op<<in>> = 1'b1;
//------------------------------ << end connection >> --------------------------
//------------------------------- << end in >> ---------------------------------
default : begin
//------------------------------ << start in >> --------------------------------
//----------------------------- << start connection >> -------------------------
active_op<<in>> = 1'bx;
//------------------------------ << end connection >> --------------------------
//------------------------------- << end in >> ---------------------------------
end
endcase // case(addr_in_port)
end // block: p_active_comb
// Address/control output decode
always @ (
//------------------------------ << start in >> --------------------------------
//----------------------------- << start connection >> -------------------------
sel_op<<in>> or addr_op<<in>> or trans_op<<in>> or write_op<<in>> or
size_op<<in>> or burst_op<<in>> or prot_op<<in>> or
//---------------------------- << start unalign >> -----------------------------
unalign_op<<in>> or bstrb_op<<in>> or
//----------------------------- << end unalign >> ------------------------------
//---------------------------- << start user >> --------------------------------
auser_op<<in>> or
//----------------------------- << end user >> ---------------------------------
master_op<<in>> or mastlock_op<<in>> or
//------------------------------ << end connection >> --------------------------
//------------------------------- << end in >> ---------------------------------
addr_in_port or no_port
)
begin : p_addr_mux
// Default values
i_hselm = 1'b0;
HADDRM = {<<addr_v>>{1'b0}};
//---------------------------- << start user >> --------------------------------
HAUSERM = {<<user_v>>{1'b0}};
//----------------------------- << end user >> ---------------------------------
i_htransm = 2'b00;
HWRITEM = 1'b0;
HSIZEM = 3'b000;
i_hburstm = 3'b000;
HPROTM = {<<prot_v>>{1'b0}};
//---------------------------- << start unalign >> -----------------------------
HUNALIGNM = 1'b0;
HBSTRBM = {<<bstrb_v>>{1'b0}};
//----------------------------- << end unalign >> ------------------------------
HMASTERM = 4'b0000;
i_hmastlockm= 1'b0;
// Decode selection when enabled
if (~no_port)
case (addr_in_port)
//------------------------------ << start in >> --------------------------------
//----------------------------- << start connection >> -------------------------
// Bus-switch input <<in>>
<<idw_si_v>>'b<<bin_in>> :
begin
i_hselm = sel_op<<in>>;
HADDRM = addr_op<<in>>;
//---------------------------- << start user >> --------------------------------
HAUSERM = auser_op<<in>>;
//----------------------------- << end user >> ---------------------------------
i_htransm = trans_op<<in>>;
HWRITEM = write_op<<in>>;
HSIZEM = size_op<<in>>;
i_hburstm = burst_op<<in>>;
HPROTM = prot_op<<in>>;
//---------------------------- << start unalign >> -----------------------------
HUNALIGNM = unalign_op<<in>>;
HBSTRBM = bstrb_op<<in>>;
//----------------------------- << end unalign >> ------------------------------
HMASTERM = master_op<<in>>;
i_hmastlockm= mastlock_op<<in>>;
end // case: 4'b<<bin_in>>
//------------------------------ << end connection >> --------------------------
//------------------------------- << end in >> ---------------------------------
default :
begin
i_hselm = 1'bx;
HADDRM = {<<addr_v>>{1'bx}};
//---------------------------- << start user >> --------------------------------
HAUSERM = {<<user_v>>{1'bx}};
//----------------------------- << end user >> ---------------------------------
i_htransm = 2'bxx;
HWRITEM = 1'bx;
HSIZEM = 3'bxxx;
i_hburstm = 3'bxxx;
HPROTM = {<<prot_v>>{1'bx}};
//---------------------------- << start unalign >> -----------------------------
HUNALIGNM = 1'bx;
HBSTRBM = {<<bstrb_v>>{1'bx}};
//----------------------------- << end unalign >> ------------------------------
HMASTERM = 4'bxxxx;
i_hmastlockm= 1'bx;
end // case: default
endcase // case(addr_in_port)
end // block: p_addr_mux
// hsel_lock provides support for AHB masters that address other
// slave regions in the middle of a locked sequence (i.e. HSEL is
// de-asserted during the locked sequence). Unless HMASTLOCK is
// held during these intermediate cycles, the OutputArb scheme will
// lose track of the locked sequence and may allow another input
// port to access the output port which should be locked
assign next_hsel_lock = (i_hselm & i_htransm[1] & i_hmastlockm) ? 1'b1 :
(i_hmastlockm == 1'b0) ? 1'b0 :
hsel_lock;
// Register hsel_lock
always @ (negedge HRESETn or posedge HCLK)
begin : p_hsel_lock
if (~HRESETn)
hsel_lock <= 1'b0;
else
if (i_hreadymuxm)
hsel_lock <= next_hsel_lock;
end
// Version of HMASTLOCK which is masked when not selected, unless a
// locked sequence has already begun through this port
assign hlock_arb = i_hmastlockm & (hsel_lock | i_hselm);
assign HTRANSM = i_htransm;
assign HBURSTM = i_hburstm;
assign HSELM = i_hselm;
assign HMASTLOCKM = i_hmastlockm;
// Dataport register
always @ (negedge HRESETn or posedge HCLK)
begin : p_data_in_port_reg
if (~HRESETn)
//------------------------------ << start rrin >> ------------------------------
//------------------------------ << end rrin >> ------------------------------ used to get a valid port number for the reset of data_port
data_in_port <= <<idw_si_v>>'b<<bin_rrin>>;
else
if (i_hreadymuxm)
data_in_port <= addr_in_port;
end
// Dataphase register
always @ (negedge HRESETn or posedge HCLK)
begin : p_wdata_phase_reg
if (~HRESETn)
wdata_phase <= 1'b0;
else
if (i_hreadymuxm)
wdata_phase <= i_hselm & i_htransm[1];
end
// HWDATAM output decode
always @ (
//------------------------------ << start in >> --------------------------------
//----------------------------- << start connection >> -------------------------
wdata_op<<in>> or
//------------------------------ << end connection >> --------------------------
//------------------------------- << end in >> ---------------------------------
data_in_port or wdata_phase
)
begin : p_data_mux
// Default value
HWDATAM = {<<data_v>>{1'b0}};
// If interface active
if (wdata_phase)
// Decode selection
case (data_in_port)
//------------------------------ << start in >> --------------------------------
//----------------------------- << start connection >> -------------------------
<<idw_si_v>>'b<<bin_in>> : HWDATAM = wdata_op<<in>>;
//------------------------------ << end connection >> --------------------------
//------------------------------- << end in >> ---------------------------------
default : HWDATAM = {<<data_v>>{1'bx}};
endcase // case(data_in_port)
end // block: p_data_mux
//---------------------------- << start user >> --------------------------------
// HWUSERM output decode
always @ (
//------------------------------ << start in >> --------------------------------
//----------------------------- << start connection >> -------------------------
wuser_op<<in>> or
//------------------------------ << end connection >> --------------------------
//------------------------------- << end in >> ---------------------------------
data_in_port or wdata_phase
)
begin : p_wuser_mux
// Default value
HWUSERM = {<<user_v>>{1'b0}};
// If interface active
if (wdata_phase)
// Decode selection
case (data_in_port)
//------------------------------ << start in >> --------------------------------
//----------------------------- << start connection >> -------------------------
<<idw_si_v>>'b<<bin_in>> : HWUSERM = wuser_op<<in>>;
//------------------------------ << end connection >> --------------------------
//------------------------------- << end in >> ---------------------------------
default : HWUSERM = {<<user_v>>{1'bx}};
endcase // case(data_in_port)
end // block: p_wuser_mux
//----------------------------- << end user >> ---------------------------------
// ---------------------------------------------------------------------------
// HREADYMUXM generation
// ---------------------------------------------------------------------------
// The HREADY signal on the shared slave is generated directly from
// the shared slave HREADYOUTS if the slave is selected, otherwise
// it mirrors the HREADY signal of the appropriate input port
always @ (negedge HRESETn or posedge HCLK)
begin : p_slave_sel_reg
if (~HRESETn)
slave_sel <= 1'b0;
else
if (i_hreadymuxm)
slave_sel <= i_hselm;
end
// HREADYMUXM output selection
assign i_hreadymuxm = (slave_sel) ? HREADYOUTM : 1'b1;
// Drive output with internal version of the signal
assign HREADYMUXM = i_hreadymuxm;
endmodule
// --================================= End ===================================--
//-----------------------------------------------------------------------------
// The confidential and proprietary information contained in this file may
// only be used by a person authorised under and to the extent permitted
// by a subsisting licensing agreement from Arm Limited or its affiliates.
//
// (C) COPYRIGHT 2001-<<copyright_year>> Arm Limited or its affiliates.
// ALL RIGHTS RESERVED
//
// This entire notice must be reproduced on all copies of this file
// and copies of this file may only be made by a person if such person is
// permitted to do so under the terms of a subsisting license agreement
// from Arm Limited or its affiliates.
//
// SVN Information
//
// Checked In : $Date: 2017-10-10 15:55:38 +0100 (Tue, 10 Oct 2017) $
//
// Revision : $Revision: 371321 $
//
// Release Information : Cortex-M System Design Kit-r1p1-00rel0
//
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
// Abstract : The Output Arbitration is used to determine which
// of the input stages will be given access to the
// shared slave.
//
// Notes : The bus matrix has <<connectivity>> connectivity.
//
//-----------------------------------------------------------------------------
<<timescale_directive>>
module <<output_arb_name>> (
// Common AHB signals
HCLK ,
HRESETn,
// Input port request signals
//------------------------------ << start in >> --------------------------------
//----------------------------- << start connection >> -------------------------
req_port<<in>>,
//------------------------------ << end connection >> --------------------------
//------------------------------- << end in >> ---------------------------------
HREADYM,
HSELM,
HTRANSM,
HBURSTM,
HMASTLOCKM,
// Arbiter outputs
addr_in_port,
no_port
);
// -----------------------------------------------------------------------------
// Input and Output declarations
// -----------------------------------------------------------------------------
// Common AHB signals
input HCLK; // AHB system clock
input HRESETn; // AHB system reset
//------------------------------ << start in >> --------------------------------
//----------------------------- << start connection >> -------------------------
input req_port<<in>>; // Port <<in>> request signal
//------------------------------ << end connection >> --------------------------
//------------------------------- << end in >> ---------------------------------
input HREADYM; // Transfer done
input HSELM; // Slave select line
input [1:0] HTRANSM; // Transfer type
input [2:0] HBURSTM; // Burst type
input HMASTLOCKM; // Locked transfer
output [<<idw_si>>:0] addr_in_port; // Port address input
output no_port; // No port selected signal
// -----------------------------------------------------------------------------
// Constant declarations
// -----------------------------------------------------------------------------
// HTRANS transfer type signal encoding
`define TRN_IDLE 2'b00 // Idle transfer
`define TRN_BUSY 2'b01 // Busy transfer
`define TRN_NONSEQ 2'b10 // NonSequential transfer
`define TRN_SEQ 2'b11 // Sequential transfer
// HBURST transfer type signal encoding
`define BUR_SINGLE 3'b000 // Single
`define BUR_INCR 3'b001 // Incremental
`define BUR_WRAP4 3'b010 // 4-beat wrap
`define BUR_INCR4 3'b011 // 4-beat Incr
`define BUR_WRAP8 3'b100 // 8-beat wrap
`define BUR_INCR8 3'b101 // 8-beat Incr
`define BUR_WRAP16 3'b110 // 16-beat Wrap
`define BUR_INCR16 3'b111 // 16-beat Incr
// -----------------------------------------------------------------------------
// Wire declarations
// -----------------------------------------------------------------------------
wire HCLK; // AHB system clock
wire HRESETn; // AHB system reset
//------------------------------ << start in >> --------------------------------
//----------------------------- << start connection >> -------------------------
wire req_port<<in>>; // Port <<in>> request signal
//------------------------------ << end connection >> --------------------------
//------------------------------- << end in >> ---------------------------------
wire HREADYM; // Transfer done
wire HSELM; // Slave select line
wire [1:0] HTRANSM; // Transfer type
wire [2:0] HBURSTM; // Burst type
wire HMASTLOCKM; // Locked transfer
wire [<<idw_si>>:0] addr_in_port; // Address input port
wire no_port; // No port selected signal
// -----------------------------------------------------------------------------
// Signal declarations
// -----------------------------------------------------------------------------
reg [<<idw_si>>:0] next_addr_in_port; // D-input of addr_in_port
reg next_no_port; // D-input of no_port
reg [<<idw_si>>:0] i_addr_in_port; // Internal version of addr_in_port
reg i_no_port; // Internal version of no_port
// Burst counter logic
reg [3:0] next_burst_remain; // D-input of reg_burst_remain
reg [3:0] reg_burst_remain; // Burst counter
reg next_burst_hold; // D-input of reg_burst_hold
reg reg_burst_hold; // Burst hold signal
// INCR burst logic
reg [1:0] reg_early_term_count; // Counts number of INCR bursts terminated
// earlier than 4-beats or early terminated bursts
wire [1:0] next_early_term_count; // D-input for reg_early_term_count
// -----------------------------------------------------------------------------
// Beginning of main code
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
// BURST TRANSFER COUNTER
// -----------------------------------------------------------------------------
//
// The Burst counter is used to count down from the number of transfers the
// master should perform and when the counter reaches zero the bus may be
// passed to another master.
//
// reg_burst_remain indicates the number of transfers remaining in the
// current fixed length burst after the current transfer.
// reg_burst_hold is set when transfers remain in a burst and causes the arbitration
// to be held in the current cycle
always @ (HTRANSM or HSELM or HBURSTM or reg_burst_remain or reg_burst_hold or reg_early_term_count)
begin : p_next_burst_remain_comb
// Force the Burst logic to reset if this port is de-selected. This would
// otherwise cause problems in several situations, e.g.:
// 1. The master performs 2 fixed-length bursts back-to-back, but the
// second is to an alternate output port
// 2. The master is performing a fixed-length burst but is de-granted mid-
// way by a local AHB Arbiter
if (~HSELM)
begin
next_burst_remain = 4'b0000;
next_burst_hold = 1'b0;
end
// Burst logic is initialised on a NONSEQ transfer (i.e. start of burst)
// IDLE transfers cause the logic to reset
// BUSY transfers pause the decrementer
// SEQ transfers decrement the counter
else
case (HTRANSM)
`TRN_NONSEQ : begin
case (HBURSTM)
`BUR_INCR16, `BUR_WRAP16 : begin
next_burst_remain = 4'd15;
next_burst_hold = 1'b1;
end // case: BUR_INCR16 | BUR_WRAP16
`BUR_INCR8, `BUR_WRAP8 : begin
next_burst_remain = 4'd7;
next_burst_hold = 1'b1;
end // case: BUR_INCR8 | BUR_WRAP8
`BUR_INCR4, `BUR_WRAP4 : begin
next_burst_remain = 4'd3;
next_burst_hold = 1'b1;
end // case: BUR_INCR4 | BUR_WRAP4
`BUR_INCR : begin
next_burst_remain = 4'd3;
next_burst_hold = 1'b1;
end // case: BUR_INCR
`BUR_SINGLE : begin
next_burst_remain = 4'd0;
next_burst_hold = 1'b0;
end // case: BUR_SINGLE | BUR_INCR
default : begin
next_burst_remain = 4'bxxxx;
next_burst_hold = 1'bx;
end // case: default
endcase // case(HBURSTM)
// Prevent early burst termination from keeping hold of the port
if (reg_early_term_count == 2'b10)
begin
next_burst_hold = 1'b0;
next_burst_remain = 4'd0;
end
end // case: `TRN_NONSEQ
`TRN_SEQ : begin
if (reg_burst_remain == 4'd1) // this was last one remaining
begin
next_burst_hold = 1'b0;
next_burst_remain = 4'd0;
end
else
begin
next_burst_hold = reg_burst_hold;
if (reg_burst_remain != 4'd0)
next_burst_remain = reg_burst_remain - 4'b1;
else
next_burst_remain = 4'd0;
end
end // case: `TRN_SEQ
`TRN_BUSY : begin
next_burst_remain = reg_burst_remain;
next_burst_hold = reg_burst_hold;
end // case: `TRN_BUSY
`TRN_IDLE : begin
next_burst_remain = 4'd0;
next_burst_hold = 1'b0;
end // case: `TRN_IDLE
default : begin
next_burst_remain = 4'bxxxx;
next_burst_hold = 1'bx;
end // case: default
endcase // case(HTRANSM)
end // block: p_next_burst_remain_comb
// reg_early_term_count counts the number of bursts which have terminated
// earlier than the defined arbitration point: this is primarily
// intended to detect back-to-back INCR bursts which are less than 4
// beats long or early terminated bursts by another interconnect.
// If such bursts are not counted then theoretically a
// sequence of e.g. 3-beat INCR bursts from a master would lock the
// arbitration scheme indefinitely.
assign next_early_term_count = (!next_burst_hold) ? 2'b00 :
(reg_burst_hold & (HTRANSM == `TRN_NONSEQ)) ?
reg_early_term_count + 2'b1 :
reg_early_term_count;
// Sequential process
always @ (negedge HRESETn or posedge HCLK)
begin : p_burst_seq
if (~HRESETn)
begin
reg_burst_remain <= 4'b0000;
reg_burst_hold <= 1'b0;
reg_early_term_count <= 2'b00;
end // if (HRESETn == 1'b0)
else
if (HREADYM)
begin
reg_burst_remain <= next_burst_remain;
reg_burst_hold <= next_burst_hold;
reg_early_term_count <= next_early_term_count;
end
end // block: p_burst_seq
// -----------------------------------------------------------------------------
// Port Selection
// -----------------------------------------------------------------------------
// The Output Arbitration function looks at all the requests to use the
// output port and determines which is the highest priority request. This
// version of the arbitration logic uses a round-robin scheme.
// For example if port 1 is currently in use then the arbiter will first check
// if port 2 requires access, then it checks port 3, then port 4 etc. When
// port 2 is currently in use it will check port 3 first then port 4 and
// all remaining ports, before finally checking port 1.
// If none of the input ports are requesting then the current port will
// remain active if it is performing IDLE transfers to the selected slave. If
// this is not the case then the no_port signal will be asserted which
// indicates that no input port should be selected.
always @ (
//------------------------------ << start in >> --------------------------------
//----------------------------- << start connection >> -------------------------
req_port<<in>> or
//------------------------------ << end connection >> --------------------------
//------------------------------- << end in >> ---------------------------------
HMASTLOCKM or next_burst_hold or HSELM or i_no_port or i_addr_in_port
)
begin : p_sel_port_comb
// Default values are used for next_no_port and next_addr_in_port
next_no_port = 1'b0;
next_addr_in_port = i_addr_in_port;
if ( HMASTLOCKM | next_burst_hold )
next_addr_in_port = i_addr_in_port;
else if (i_no_port)
begin
//------------------------------ << start in >> --------------------------------
//----------------------------- << start connection >> -------------------------
<<rrelse>>if (req_port<<in>>)
next_addr_in_port = <<idw_si_v>>'b<<bin_in>>;
//------------------------------ << end connection >> --------------------------
//------------------------------ << end in >> ----------------------------------
else
next_no_port = 1'b1;
end
else
case (i_addr_in_port)
//------------------------------ << start rrin >> ------------------------------
<<idw_si_v>>'b<<bin_rrin>> : begin
//------------------------------ << start rridx >> -----------------------------
<<rrelse>>if (req_port<<rridx>>)
next_addr_in_port = <<idw_si_v>>'b<<bin_rridx>>;
//------------------------------ << end rridx >> -------------------------------
else if (HSELM)
next_addr_in_port = <<idw_si_v>>'b<<bin_rrin>>;
else
next_no_port = 1'b1;
end
//------------------------------ << end rrin >> --------------------------------
default : begin
next_addr_in_port = {<<idw_si_v>>{1'bx}};
next_no_port = 1'bx;
end
endcase
end
// Sequential process
always @ (negedge HRESETn or posedge HCLK)
begin : p_addr_in_port_reg
if (~HRESETn)
begin
i_no_port <= 1'b1;
i_addr_in_port <= {<<idw_si_v>>{1'b0}};
end
else
if (HREADYM)
begin
i_no_port <= next_no_port;
i_addr_in_port <= next_addr_in_port;
end
end
// Drive outputs with internal versions
assign addr_in_port = i_addr_in_port;
assign no_port = i_no_port;
endmodule
// --================================= End ===================================--