UPGRADE YOUR BROWSER

We have detected your current browser version is not the latest one. Xilinx.com uses the latest web technologies to bring you the best online experience possible. Please upgrade to a Xilinx.com supported browser:Chrome, Firefox, Internet Explorer 11, Safari. Thank you!

cancel
Showing results for 
Search instead for 
Did you mean: 
Highlighted
Participant e2g
Participant
11,530 Views
Registered: ‎06-10-2011

Microblaze Event Counters

Hi,

 

I am trying to learn how to use the Event Counters now offered in the Microblaze (as of last year). Here is my understanding:

 

Configuration:

 

Access to these registers are only permitted through the MDM. Therefore, in addition to enabling extended debugging on your MicroBlazes (C_DEBUG_ENABLED = 2) and setting how many counters you like, you also need to enabled register access for the MDM (C_DBG_REG_ACCESS = 1).

 

Question 1: Is there a way not to go through MDM / Assembly instructions to start, stop, clear these counters? My use case scenario is to read these counters while the application is running and not after it has ran.

 

 

Software Access Proceedure:

 

I followed the proceedure in both the MDM document (Link -page 32) and the MicroBlaze document (Link -page 90).  Here is what I have understood from it.

 

Question 2: The MDM document outlines two ways for accessessing the debug registers, with different lock types. One for single atomic access and another proceedure (that is similar to the first) for a sequence of accessess. It is still not clear of the difference as they appear to behave in the same way.

 

Test setup:

  • 6 processors (MicroBlaze)
    • 1 Host connected to Port 0 on MDM
    • 5 Slaves; slave 0 connected to port 1, Slave 1 connected to port 2, etc.
  • Slaves have 2 Event Counters enabled, 0 Latency event counters
  • Host has the default configuration (I am not interested in the host currently).

 

Proceedure:

  1. Write the magic value (0xEBAB) to the lock register in the MDM. Enabling Write/Read access
  2. For each slave processor
    1. Specify which port/Microblaze to the MDM:
      1. Write the value '0x61A07' to MDM's control register, and wait until the MDM status register reads '1' letting you know you have the lock/access.
      2. Write the value 0b10 (for slave 0) or value 0b100 (for slave 1), etc.
    2. Reset event counter access to the first counter for this Microblaze:
      1. Write the value '0x4A404' to MDM's control register, and wait........
      2. Write 0x1 (i.e. assert the Reset bit).
    3. Specify Event Counters for this MicroBlaze:
        1. Write the value '0x4A207' to MDM's control register, and wait........
        2. Write to the MDM's Data register, the event number
        3. Repeat step 1-2 for the number of event and latency counters you have
    4. Clear and start all counters for this MicroBlaze:
      1. Write the value '0x4A404' to MDM's control register, and wait........
      2. Write 0x18 (i.e. assert both the clear and start). Setting them indidivually didn't seem to matter.
    5. Run application
    6. Sample and Stop all counters for this MicroBlaze:
      1. Write the value '0x4A404' to MDM's control register, and wait........
      2. Write 0x6 (i.e. assert sample and stop bits). Setting them indidivually didn't seem to matter.
    7. Reset event counter access to the first counter for this Microblaze:
        1. Write the value '0x4A404' to MDM's control register, and wait........
        2. Write 0x1 (i.e. assert the Reset bit).
    8. Read Event (and Latency) counters for this MicroBlaze:
      1. Write the value '0x4AC1F' to MDM's control register, and wait........
      2. Read the data for the event counter currently selected.
      3. Repeat steps 1-2 for the remaining counters.
  3. Unlock access to MDM by writing any value other than 0xebab to its Lock register

 

What I am experiencing:

 

 

Instead of clearing and starting the timers, what I am doing in replacement of that is setting an initial value of '65 + i (where i = 0 --> 5) for all counters for slave i. Therefore, when I sample and stop, I should read back from those counters the same values I specify for each MicroBlaze.  Here are my results:

 

  1. Select Slave 0: Write to Which MicroBlaze register --> 0b10 (2)
    Specified the value: 65
    Sampled and read the value: 65
  2. Select Slave 1: Write to Which MicroBlaze register --> 0b100 (4)
    Specified the value: 66
    Sampled and read the value: 49
  3. Select Slave 2: Write to Which MicroBlaze register --> 0b1000 (8)
    Specified the value: 67
    Sampled and read the value: 67
  4. Select Slave 3: Write to Which MicroBlaze register --> 0b10000 (16)
    Specified the value: 68
    Sampled and read the value: 17
  5. Select Slave 4: Write to Which MicroBlaze register --> 0b100000 (32)
    Specified the value: 69
    Sampled and read the value: 17

Actual output:

 

--------------------------------
--- Performance Counter Test ---
--------------------------------
Reading Slave 0 Counter configuration
Specifying processor with this argument = 0x00000002
Event #00 = 65
Event #28 = 65
Reading Slave 1 Counter configuration
Specifying processor with this argument = 0x00000004
Event #00 = 49
Event #28 = 49
Reading Slave 2 Counter configuration
Specifying processor with this argument = 0x00000008
Event #00 = 67
Event #28 = 67
Reading Slave 3 Counter configuration
Specifying processor with this argument = 0x00000010
Event #00 = 17
Event #28 = 17
Reading Slave 4 Counter configuration
Specifying processor with this argument = 0x00000020
Event #00 = 17
Event #28 = 17
Locking access to MDM
--- Done ---

 

 

Help!

 

Eugene
0 Kudos
23 Replies
Participant e2g
Participant
11,375 Views
Registered: ‎06-10-2011

Re: Microblaze Event Counters

By the way, I found my answer for question 2. It keeps the lock such that after issuing the first command to the MDM with lock type of "0b10", and checking the status (whether I got the lock yet or not), I don't need to continually check the lock status on subsequent commands until I either explicitly tell it to unlock itself "0b00" or I issue a command with the lock type "0b01".

 

 

Eugene
0 Kudos
Xilinx Employee
Xilinx Employee
11,353 Views
Registered: ‎07-30-2007

Re: Microblaze Event Counters

It sounds like you're trying to write a value to the performance counter values via the PCDWR register, and then read the counter back via PCDRR, expecting to see the same values written, but they don't match. Is that the main question?

 

The only think I can think of is that since each counter has a different number of items, but that wouldn't explain the specific values you are seeing.

 

 

 

0 Kudos
Participant e2g
Participant
11,338 Views
Registered: ‎06-10-2011

Re: Microblaze Event Counters

Yes, correct (Resetting back to the first counter and asserting the sampling bit in the PCCMDR register in between).

 

Each Microblaze has two counters except the Host, the first, which I am not using. I am about change that to two as well just for the sake of consistency.

 

 

I am attaching 3 images/scenarios to describe the behaviour a little more visually for me and anyone else viewing this thread. The images show the written/specified values and the read back values. Again, interfacing with these registers (from my understanding) all goes through the MDM instead of directly accessing them from the Microblaze via a mfsr intruction or the like. I am not sure why it is this way... The full proceedure is outlined in first post.

 

Thanks for your help.

 

All processors hooked up:

 

Performance_Counters.jpg

 

 

 

A single slave processor hooked up:

 

Compared to first image, I removed the connections between MDM and some of the Microblazes.

Performance_Counters_single_hookup.jpg

 

 

Two Slave processors Hooked up:

 

Compared to first image, I removed the connections between MDM and some of the Microblazes.

 

Performance_Counters_dual_hookup.jpg

 

Eugene
0 Kudos
Participant e2g
Participant
11,298 Views
Registered: ‎06-10-2011

Re: Microblaze Event Counters

I generated one of the example designs that is shipped with Vivado 2015.1, and modifed the mdm to have debug register access, modified the microblaze to contain 2 event counters,  and added a connection from the peripheral bus to the MDM for the Microblaze to address during runtime

 

This system only has one processor in it.

 

I have defaulted to the test of just writing a specific value, requesting the MDM to sample the current counter(s) which should be those specific values, and then read them back.

 

Problem: I am not reading the same values as I originally wrote in those counters.

 

Attached is the tcl script for the block design that I exported, and the helloworld.c application that I modified from the XSDK template.

 

helloworld.c

#include <stdio.h>
#include "platform.h"
#include "xparameters.h"

#define  MDM_BASEADDR         XPAR_MDM_1_BASEADDR
#define  DBG_STATUS           (MDM_BASEADDR + 0x10)
#define  DBG_CTRL             (MDM_BASEADDR + 0x10)
#define  DBG_DATA             (MDM_BASEADDR + 0x14)
#define  DBG_LOCK             (MDM_BASEADDR + 0x18)

#define NUM_TRIALS				1

/**
 * Function to write specified command to MDM CTRL register.
 */
void mdm_cmd(unsigned int  cmd) {
	volatile unsigned int * status  = (unsigned int *) DBG_STATUS;
	volatile unsigned int * control = (unsigned int *) DBG_CTRL;

	do {
		*control = cmd;
	} while( *status != 0x1);

	return;
}

void print(char *str);

int main()
{
    init_platform();
	disable_caches();

    print("Hello World\n\r");
    print("--------------------------------\n\r");
    print("--- Performance Counter Test ---\n\r");
    print("--------------------------------\n\r");
    volatile unsigned int * status  = (unsigned int *) DBG_STATUS;
    volatile unsigned int * control = (unsigned int *) DBG_CTRL;
    volatile unsigned int * data    = (unsigned int *) DBG_DATA;
    volatile unsigned int * lock    = (unsigned int *) DBG_LOCK;
    int i,j;

    unsigned int event_num[] = {30, 0};
    unsigned int event_num_size = sizeof(event_num) / sizeof(unsigned int);

    for (i = 0; i < NUM_TRIALS; i++)
    {
		print("Gaining access to MDM registers\n\r");
		// Gain access to DBG_CTRL and DBG_DATA
		// registers in MDM by writing magic num
		*lock = 0xebab;
		print("Done\n\r");

		/* C_MB_DBG_PORTS == 1; hence, no need to do this
		print("Specifying Port on MDM\n\r");
		mdm_cmd(0x61A07);
		*data = 0x1;
		print("Done\n\r");
		*/

		print("Resetting event counter selection back to the first\n\r");
		mdm_cmd(0x4A404);
		*data = 0x1;
		print("Done\n\r");

		print("Specifying event numbers\n\r");
		for( j = 0; j < event_num_size; j++) {
			mdm_cmd(0x4A207);
			*data = event_num[j];
		}
		print("Done\n\r");

		print("Resetting event counter selection back to the first\n\r");
		mdm_cmd(0x4A404);
		*data = 0x1;
		print("Done\n\r");

		print("Setting initial counter values\n\r");
		for( j = 0; j < event_num_size; j++) {
			mdm_cmd(0x4AE1F);
			*data = j*5 + 65;
		}

		print("Resetting event counter selection back to the first\n\r");
		mdm_cmd(0x4A404);
		*data = 0x1;
		print("Done\n\r");

	/*
		// Clear and start all counters for this processor
		mdm_cmd(0x4A404);
		*data = 0x18;   // Clear and start
	*/

		print("Setting sample bit\n\r");
		mdm_cmd(0x4A404);
		*data = 0x2;
		print("Done\n\r");

		print("Setting stop bit\n\r");
		mdm_cmd(0x4A404);
		*data = 0x4;
		print("Done\n\r");


	/*
		print("Resetting event counter selection back to the first\n\r");
		mdm_cmd(0x4A404);
		*data = 0x1;
		print("Done\n\r");

		// Check for Overflow and Full bits
		for( j = 0; j < event_num_size; j++) {
			mdm_cmd(0x4A601);
			xil_printf("Overflow-Full 0x%02x\n\r", *data);
		  }
	*/

		print("Resetting event counter selection back to the first\n\r");
		mdm_cmd(0x4A404);
		*data = 0x1;
		print("Done\n\r");

		print("Reading from Event Counters:\n\r");
		// Read events and latency counters
		for( j = 0; j < event_num_size; j++) {
			xil_printf("Event #%02d = ", event_num[j]);
			mdm_cmd(0x4AC1F);
			xil_printf("%d\n\r", *data);
		}
		print("Done\n\r");

		print("Locking the MDM registers\n\r");
		*lock = 0;
		print("Done\n\r");
    }

    cleanup_platform();
    return 0;
}

block_design.tcl

################################################################
# This is a generated script based on design: base_microblaze_design
#
# Though there are limitations about the generated script,
# the main purpose of this utility is to make learning
# IP Integrator Tcl commands easier.
################################################################

################################################################
# Check if script is running in correct Vivado version.
################################################################
set scripts_vivado_version 2015.1
set current_vivado_version [version -short]

if { [string first $scripts_vivado_version $current_vivado_version] == -1 } {
   puts ""
   puts "ERROR: This script was generated using Vivado <$scripts_vivado_version> and is being run in <$current_vivado_version> of Vivado. Please run the script in Vivado <$scripts_vivado_version> then open the design in Vivado <$current_vivado_version>. Upgrade the design by running \"Tools => Report => Report IP Status...\", then run write_bd_tcl to create an updated script."

   return 1
}

################################################################
# START
################################################################

# To test this script, run the following commands from Vivado Tcl console:
# source base_microblaze_design_script.tcl

# If you do not already have a project created,
# you can create a project using the following command:
#    create_project project_1 myproj -part xc7vx485tffg1761-2
#    set_property BOARD_PART xilinx.com:vc707:part0:1.2 [current_project]

# CHECKING IF PROJECT EXISTS
if { [get_projects -quiet] eq "" } {
   puts "ERROR: Please open or create a project!"
   return 1
}



# CHANGE DESIGN NAME HERE
set design_name base_microblaze_design

# If you do not already have an existing IP Integrator design open,
# you can create a design using the following command:
#    create_bd_design $design_name

# Creating design if needed
set errMsg ""
set nRet 0

set cur_design [current_bd_design -quiet]
set list_cells [get_bd_cells -quiet]

if { ${design_name} eq "" } {
   # USE CASES:
   #    1) Design_name not set

   set errMsg "ERROR: Please set the variable <design_name> to a non-empty value."
   set nRet 1

} elseif { ${cur_design} ne "" && ${list_cells} eq "" } {
   # USE CASES:
   #    2): Current design opened AND is empty AND names same.
   #    3): Current design opened AND is empty AND names diff; design_name NOT in project.
   #    4): Current design opened AND is empty AND names diff; design_name exists in project.

   if { $cur_design ne $design_name } {
      puts "INFO: Changing value of <design_name> from <$design_name> to <$cur_design> since current design is empty."
      set design_name [get_property NAME $cur_design]
   }
   puts "INFO: Constructing design in IPI design <$cur_design>..."

} elseif { ${cur_design} ne "" && $list_cells ne "" && $cur_design eq $design_name } {
   # USE CASES:
   #    5) Current design opened AND has components AND same names.

   set errMsg "ERROR: Design <$design_name> already exists in your project, please set the variable <design_name> to another value."
   set nRet 1
} elseif { [get_files -quiet ${design_name}.bd] ne "" } {
   # USE CASES: 
   #    6) Current opened design, has components, but diff names, design_name exists in project.
   #    7) No opened design, design_name exists in project.

   set errMsg "ERROR: Design <$design_name> already exists in your project, please set the variable <design_name> to another value."
   set nRet 2

} else {
   # USE CASES:
   #    8) No opened design, design_name not in project.
   #    9) Current opened design, has components, but diff names, design_name not in project.

   puts "INFO: Currently there is no design <$design_name> in project, so creating one..."

   create_bd_design $design_name

   puts "INFO: Making design <$design_name> as current_bd_design."
   current_bd_design $design_name

}

puts "INFO: Currently the variable <design_name> is equal to \"$design_name\"."

if { $nRet != 0 } {
   puts $errMsg
   return $nRet
}

##################################################################
# DESIGN PROCs
##################################################################


# Hierarchical cell: microblaze_0_local_memory
proc create_hier_cell_microblaze_0_local_memory { parentCell nameHier } {

  if { $parentCell eq "" || $nameHier eq "" } {
     puts "ERROR: create_hier_cell_microblaze_0_local_memory() - Empty argument(s)!"
     return
  }

  # Get object for parentCell
  set parentObj [get_bd_cells $parentCell]
  if { $parentObj == "" } {
     puts "ERROR: Unable to find parent cell <$parentCell>!"
     return
  }

  # Make sure parentObj is hier blk
  set parentType [get_property TYPE $parentObj]
  if { $parentType ne "hier" } {
     puts "ERROR: Parent <$parentObj> has TYPE = <$parentType>. Expected to be <hier>."
     return
  }

  # Save current instance; Restore later
  set oldCurInst [current_bd_instance .]

  # Set parent object as current
  current_bd_instance $parentObj

  # Create cell and set as current instance
  set hier_obj [create_bd_cell -type hier $nameHier]
  current_bd_instance $hier_obj

  # Create interface pins
  create_bd_intf_pin -mode MirroredMaster -vlnv xilinx.com:interface:lmb_rtl:1.0 DLMB
  create_bd_intf_pin -mode MirroredMaster -vlnv xilinx.com:interface:lmb_rtl:1.0 ILMB

  # Create pins
  create_bd_pin -dir I -type clk LMB_Clk
  create_bd_pin -dir I -from 0 -to 0 -type rst SYS_Rst

  # Create instance: dlmb_bram_if_cntlr, and set properties
  set dlmb_bram_if_cntlr [ create_bd_cell -type ip -vlnv xilinx.com:ip:lmb_bram_if_cntlr:4.0 dlmb_bram_if_cntlr ]
  set_property -dict [ list CONFIG.C_ECC {0}  ] $dlmb_bram_if_cntlr

  # Create instance: dlmb_v10, and set properties
  set dlmb_v10 [ create_bd_cell -type ip -vlnv xilinx.com:ip:lmb_v10:3.0 dlmb_v10 ]

  # Create instance: ilmb_bram_if_cntlr, and set properties
  set ilmb_bram_if_cntlr [ create_bd_cell -type ip -vlnv xilinx.com:ip:lmb_bram_if_cntlr:4.0 ilmb_bram_if_cntlr ]
  set_property -dict [ list CONFIG.C_ECC {0}  ] $ilmb_bram_if_cntlr

  # Create instance: ilmb_v10, and set properties
  set ilmb_v10 [ create_bd_cell -type ip -vlnv xilinx.com:ip:lmb_v10:3.0 ilmb_v10 ]

  # Create instance: lmb_bram, and set properties
  set lmb_bram [ create_bd_cell -type ip -vlnv xilinx.com:ip:blk_mem_gen:8.2 lmb_bram ]
  set_property -dict [ list CONFIG.Memory_Type {True_Dual_Port_RAM} CONFIG.use_bram_block {BRAM_Controller}  ] $lmb_bram

  # Create interface connections
  connect_bd_intf_net -intf_net microblaze_0_dlmb [get_bd_intf_pins DLMB] [get_bd_intf_pins dlmb_v10/LMB_M]
  connect_bd_intf_net -intf_net microblaze_0_dlmb_bus [get_bd_intf_pins dlmb_bram_if_cntlr/SLMB] [get_bd_intf_pins dlmb_v10/LMB_Sl_0]
  connect_bd_intf_net -intf_net microblaze_0_dlmb_cntlr [get_bd_intf_pins dlmb_bram_if_cntlr/BRAM_PORT] [get_bd_intf_pins lmb_bram/BRAM_PORTA]
  connect_bd_intf_net -intf_net microblaze_0_ilmb [get_bd_intf_pins ILMB] [get_bd_intf_pins ilmb_v10/LMB_M]
  connect_bd_intf_net -intf_net microblaze_0_ilmb_bus [get_bd_intf_pins ilmb_bram_if_cntlr/SLMB] [get_bd_intf_pins ilmb_v10/LMB_Sl_0]
  connect_bd_intf_net -intf_net microblaze_0_ilmb_cntlr [get_bd_intf_pins ilmb_bram_if_cntlr/BRAM_PORT] [get_bd_intf_pins lmb_bram/BRAM_PORTB]

  # Create port connections
  connect_bd_net -net SYS_Rst_1 [get_bd_pins SYS_Rst] [get_bd_pins dlmb_bram_if_cntlr/LMB_Rst] [get_bd_pins dlmb_v10/SYS_Rst] [get_bd_pins ilmb_bram_if_cntlr/LMB_Rst] [get_bd_pins ilmb_v10/SYS_Rst]
  connect_bd_net -net microblaze_0_Clk [get_bd_pins LMB_Clk] [get_bd_pins dlmb_bram_if_cntlr/LMB_Clk] [get_bd_pins dlmb_v10/LMB_Clk] [get_bd_pins ilmb_bram_if_cntlr/LMB_Clk] [get_bd_pins ilmb_v10/LMB_Clk]
  
  # Restore current instance
  current_bd_instance $oldCurInst
}


# Procedure to create entire design; Provide argument to make
# procedure reusable. If parentCell is "", will use root.
proc create_root_design { parentCell } {

  if { $parentCell eq "" } {
     set parentCell [get_bd_cells /]
  }

  # Get object for parentCell
  set parentObj [get_bd_cells $parentCell]
  if { $parentObj == "" } {
     puts "ERROR: Unable to find parent cell <$parentCell>!"
     return
  }

  # Make sure parentObj is hier blk
  set parentType [get_property TYPE $parentObj]
  if { $parentType ne "hier" } {
     puts "ERROR: Parent <$parentObj> has TYPE = <$parentType>. Expected to be <hier>."
     return
  }

  # Save current instance; Restore later
  set oldCurInst [current_bd_instance .]

  # Set parent object as current
  current_bd_instance $parentObj


  # Create interface ports
  set led_8bits [ create_bd_intf_port -mode Master -vlnv xilinx.com:interface:gpio_rtl:1.0 led_8bits ]
  set rs232_uart [ create_bd_intf_port -mode Master -vlnv xilinx.com:interface:uart_rtl:1.0 rs232_uart ]
  set sys_diff_clock [ create_bd_intf_port -mode Slave -vlnv xilinx.com:interface:diff_clock_rtl:1.0 sys_diff_clock ]
  set_property -dict [ list CONFIG.FREQ_HZ {200000000}  ] $sys_diff_clock

  # Create ports
  set reset [ create_bd_port -dir I -type rst reset ]
  set_property -dict [ list CONFIG.POLARITY {ACTIVE_HIGH}  ] $reset

  # Create instance: axi_gpio_0, and set properties
  set axi_gpio_0 [ create_bd_cell -type ip -vlnv xilinx.com:ip:axi_gpio:2.0 axi_gpio_0 ]
  set_property -dict [ list CONFIG.GPIO_BOARD_INTERFACE {led_8bits} CONFIG.USE_BOARD_FLOW {true}  ] $axi_gpio_0

  # Create instance: axi_uartlite_0, and set properties
  set axi_uartlite_0 [ create_bd_cell -type ip -vlnv xilinx.com:ip:axi_uartlite:2.0 axi_uartlite_0 ]
  set_property -dict [ list CONFIG.C_BAUDRATE {9600} CONFIG.UARTLITE_BOARD_INTERFACE {rs232_uart} CONFIG.USE_BOARD_FLOW {true}  ] $axi_uartlite_0

  # Create instance: clk_wiz_1, and set properties
  set clk_wiz_1 [ create_bd_cell -type ip -vlnv xilinx.com:ip:clk_wiz:5.1 clk_wiz_1 ]
  set_property -dict [ list CONFIG.CLK_IN1_BOARD_INTERFACE {sys_diff_clock} CONFIG.PRIM_SOURCE {Differential_clock_capable_pin} CONFIG.RESET_BOARD_INTERFACE {reset} CONFIG.USE_BOARD_FLOW {true}  ] $clk_wiz_1

  # Create instance: mdm_1, and set properties
  set mdm_1 [ create_bd_cell -type ip -vlnv xilinx.com:ip:mdm:3.2 mdm_1 ]
  set_property -dict [ list CONFIG.C_DBG_REG_ACCESS {1}  ] $mdm_1

  # Create instance: microblaze_0, and set properties
  set microblaze_0 [ create_bd_cell -type ip -vlnv xilinx.com:ip:microblaze:9.5 microblaze_0 ]
  set_property -dict [ list CONFIG.C_DEBUG_ENABLED {2} CONFIG.C_DEBUG_EVENT_COUNTERS {2} CONFIG.C_DEBUG_LATENCY_COUNTERS {0} CONFIG.C_D_AXI {1} CONFIG.C_D_LMB {1} CONFIG.C_I_LMB {1}  ] $microblaze_0

  # Create instance: microblaze_0_axi_periph, and set properties
  set microblaze_0_axi_periph [ create_bd_cell -type ip -vlnv xilinx.com:ip:axi_interconnect:2.1 microblaze_0_axi_periph ]
  set_property -dict [ list CONFIG.NUM_MI {3}  ] $microblaze_0_axi_periph

  # Create instance: microblaze_0_local_memory
  create_hier_cell_microblaze_0_local_memory [current_bd_instance .] microblaze_0_local_memory

  # Create instance: rst_clk_wiz_1_100M, and set properties
  set rst_clk_wiz_1_100M [ create_bd_cell -type ip -vlnv xilinx.com:ip:proc_sys_reset:5.0 rst_clk_wiz_1_100M ]
  set_property -dict [ list CONFIG.RESET_BOARD_INTERFACE {reset} CONFIG.USE_BOARD_FLOW {true}  ] $rst_clk_wiz_1_100M

  # Create interface connections
  connect_bd_intf_net -intf_net axi_gpio_0_GPIO [get_bd_intf_ports led_8bits] [get_bd_intf_pins axi_gpio_0/GPIO]
  connect_bd_intf_net -intf_net axi_uartlite_0_UART [get_bd_intf_ports rs232_uart] [get_bd_intf_pins axi_uartlite_0/UART]
  connect_bd_intf_net -intf_net microblaze_0_M_AXI_DP [get_bd_intf_pins microblaze_0/M_AXI_DP] [get_bd_intf_pins microblaze_0_axi_periph/S00_AXI]
  connect_bd_intf_net -intf_net microblaze_0_axi_periph_M00_AXI [get_bd_intf_pins axi_uartlite_0/S_AXI] [get_bd_intf_pins microblaze_0_axi_periph/M00_AXI]
  connect_bd_intf_net -intf_net microblaze_0_axi_periph_M01_AXI [get_bd_intf_pins axi_gpio_0/S_AXI] [get_bd_intf_pins microblaze_0_axi_periph/M01_AXI]
  connect_bd_intf_net -intf_net microblaze_0_axi_periph_M02_AXI [get_bd_intf_pins mdm_1/S_AXI] [get_bd_intf_pins microblaze_0_axi_periph/M02_AXI]
  connect_bd_intf_net -intf_net microblaze_0_debug [get_bd_intf_pins mdm_1/MBDEBUG_0] [get_bd_intf_pins microblaze_0/DEBUG]
  connect_bd_intf_net -intf_net microblaze_0_dlmb_1 [get_bd_intf_pins microblaze_0/DLMB] [get_bd_intf_pins microblaze_0_local_memory/DLMB]
  connect_bd_intf_net -intf_net microblaze_0_ilmb_1 [get_bd_intf_pins microblaze_0/ILMB] [get_bd_intf_pins microblaze_0_local_memory/ILMB]
  connect_bd_intf_net -intf_net sys_diff_clock_1 [get_bd_intf_ports sys_diff_clock] [get_bd_intf_pins clk_wiz_1/CLK_IN1_D]

  # Create port connections
  connect_bd_net -net clk_wiz_1_locked [get_bd_pins clk_wiz_1/locked] [get_bd_pins rst_clk_wiz_1_100M/dcm_locked]
  connect_bd_net -net mdm_1_debug_sys_rst [get_bd_pins mdm_1/Debug_SYS_Rst] [get_bd_pins rst_clk_wiz_1_100M/mb_debug_sys_rst]
  connect_bd_net -net microblaze_0_Clk [get_bd_pins axi_gpio_0/s_axi_aclk] [get_bd_pins axi_uartlite_0/s_axi_aclk] [get_bd_pins clk_wiz_1/clk_out1] [get_bd_pins mdm_1/S_AXI_ACLK] [get_bd_pins microblaze_0/Clk] [get_bd_pins microblaze_0_axi_periph/ACLK] [get_bd_pins microblaze_0_axi_periph/M00_ACLK] [get_bd_pins microblaze_0_axi_periph/M01_ACLK] [get_bd_pins microblaze_0_axi_periph/M02_ACLK] [get_bd_pins microblaze_0_axi_periph/S00_ACLK] [get_bd_pins microblaze_0_local_memory/LMB_Clk] [get_bd_pins rst_clk_wiz_1_100M/slowest_sync_clk]
  connect_bd_net -net reset_1 [get_bd_ports reset] [get_bd_pins clk_wiz_1/reset] [get_bd_pins rst_clk_wiz_1_100M/ext_reset_in]
  connect_bd_net -net rst_clk_wiz_1_100M_bus_struct_reset [get_bd_pins microblaze_0_local_memory/SYS_Rst] [get_bd_pins rst_clk_wiz_1_100M/bus_struct_reset]
  connect_bd_net -net rst_clk_wiz_1_100M_interconnect_aresetn [get_bd_pins microblaze_0_axi_periph/ARESETN] [get_bd_pins rst_clk_wiz_1_100M/interconnect_aresetn]
  connect_bd_net -net rst_clk_wiz_1_100M_mb_reset [get_bd_pins microblaze_0/Reset] [get_bd_pins rst_clk_wiz_1_100M/mb_reset]
  connect_bd_net -net rst_clk_wiz_1_100M_peripheral_aresetn [get_bd_pins axi_gpio_0/s_axi_aresetn] [get_bd_pins axi_uartlite_0/s_axi_aresetn] [get_bd_pins mdm_1/S_AXI_ARESETN] [get_bd_pins microblaze_0_axi_periph/M00_ARESETN] [get_bd_pins microblaze_0_axi_periph/M01_ARESETN] [get_bd_pins microblaze_0_axi_periph/M02_ARESETN] [get_bd_pins microblaze_0_axi_periph/S00_ARESETN] [get_bd_pins rst_clk_wiz_1_100M/peripheral_aresetn]

  # Create address segments
  create_bd_addr_seg -range 0x10000 -offset 0x40000000 [get_bd_addr_spaces microblaze_0/Data] [get_bd_addr_segs axi_gpio_0/S_AXI/Reg] SEG_axi_gpio_0_Reg
  create_bd_addr_seg -range 0x10000 -offset 0x40600000 [get_bd_addr_spaces microblaze_0/Data] [get_bd_addr_segs axi_uartlite_0/S_AXI/Reg] SEG_axi_uartlite_0_Reg
  create_bd_addr_seg -range 0x8000 -offset 0x0 [get_bd_addr_spaces microblaze_0/Data] [get_bd_addr_segs microblaze_0_local_memory/dlmb_bram_if_cntlr/SLMB/Mem] SEG_dlmb_bram_if_cntlr_Mem
  create_bd_addr_seg -range 0x8000 -offset 0x0 [get_bd_addr_spaces microblaze_0/Instruction] [get_bd_addr_segs microblaze_0_local_memory/ilmb_bram_if_cntlr/SLMB/Mem] SEG_ilmb_bram_if_cntlr_Mem
  create_bd_addr_seg -range 0x1000 -offset 0x41400000 [get_bd_addr_spaces microblaze_0/Data] [get_bd_addr_segs mdm_1/S_AXI/Reg] SEG_mdm_1_Reg
  

  # Restore current instance
  current_bd_instance $oldCurInst

  save_bd_design
}
# End of create_root_design()


##################################################################
# MAIN FLOW
##################################################################

create_root_design ""

 

Eugene
0 Kudos
Participant e2g
Participant
11,254 Views
Registered: ‎06-10-2011

Re: Microblaze Event Counters

I had a friend try out the simple project in the last post and he was getting correct numbers (65-70) when reading those registers back. I switched out my V7 evaluation board for another and was getting the same results. I will try a few more things. 

 

I also hooked up a Kintex 7 board and I am not getting the correct results (Appears to only read the last event counter, no matter how many times I reset).

 

 

Eugene
0 Kudos
Participant e2g
Participant
11,163 Views
Registered: ‎06-10-2011

Re: Microblaze Event Counters

bump. I installed Ubuntu 1404 LTS on my machie  and I am not getting correct  and consistent results

Eugene
0 Kudos
Xilinx Employee
Xilinx Employee
11,132 Views
Registered: ‎10-08-2010

Re: Microblaze Event Counters

I have implemented your design in block_design.tcl on a KC705 board with Vivado 2015.1, and used your software in helloworld.c (which looks fine), and I get the following output:

 

Reading from Event Counters:
Event #30 = 65
Event #00 = 70

 

This seems correct to me. You write 65 and 70 in the loop on lines 80-83, and that is also what you read in the loop on lines 127.131. Do you get a different output when you run it, or do you think the correct output is something else?

 

I will continue to look at your multiprocessor configuration, but I would first like to understand better what the problem is.

 

0 Kudos
Participant e2g
Participant
11,080 Views
Registered: ‎06-10-2011

Re: Microblaze Event Counters

I get different output. I read back 32, 35. Which is half (shift by one) of 65, 70. From my earlier posts, I was getting different numbers. 

 

Can you let me know if you built this platform on Windows?

 

I would also go back and modify the original post but I don't a EDIT option in the drop-down menu.

Eugene
0 Kudos
Xilinx Employee
Xilinx Employee
11,044 Views
Registered: ‎10-08-2010

Re: Microblaze Event Counters

I used Linux, but now I have also tested on Windows with the same correct result.

 

Let us try to figure out what the difference could be. I have:

  • Vivado version: 2015.1
  • Vivado Synthesis Strategy: "Viovado Synthesis Defaults (Vivado Synthesis 2015)"
  • Vivado Implementation Strategy: "Vuvado Implementation Defaults (Vivado Implementation 2015)"
  • OS: Linux (Red Hat Enterprise Linux 5.9) or Windows (Windows 7 Enterprise SP1)
  • Board: KC705 REV 1.1

Can you also list the Vivado version, operating system, and board you are using?

 

Do you get any critical warnings, or warnings that seem suspicious when generating, synthesizing and Implementing? You can ignore warnings Synth 8-3919,115,350,312,3332,3295, Opt 31-6, DRC 23-20, and Place 30-12.

Are all IP cores up-to-date in Vivado (Tools > Report > Report IP Status)?

 

0 Kudos
Participant e2g
Participant
10,768 Views
Registered: ‎06-10-2011

Re: Microblaze Event Counters

I have:

  • Vivado version 2015.1
  • Vivado Synthesis Strategy: "Viovado Synthesis Defaults (Vivado Synthesis 2015)"
  • Vivado Implementation Strategy: "Vuvado Implementation Defaults (Vivado Implementation 2015)"
  • OS: Linux (Ubuntu 14.04.1 or Ubuntu 14.04.3)
  • Board: VC707 REV 1.0 (I also have a KC705 REV 1.0)

 

I don't get any critical warnings. Nothing seems suspicious to me. There are some warnings behind the encrypted sources of the MicroBlaze. There is also a null assignment in the mdm (that is supposedly ignored). All warnings attached below

 

I have also noticed that when choosing the board in the base system builder in Vivado, it lists both the KC705 and VC707..but they are both REV 1.1. It doesn't explain why it works for my colleague who has the same REV1.0 board on his Ubuntu system.

 

Synthesis Command: synth_design -top base_microblaze_design_wrapper -part xc7vx485tffg1761-2
[Synth 8-3919] null assignment ignored ["/home/eugene/event_counters/event_counters.srcs/sources_1/ipshared/xilinx.com/mdm_v3_2/a1222098/hdl/vhdl/mdm.vhd":3800]
[Synth 8-115] binding instance 'i_0' in module 'PC_Module_gti' to reference 'keep__22' which has no pins
[Synth 8-312] ignoring unsynthesizable construct: assertion statement ["/home/eugene/event_counters/event_counters.srcs/sources_1/ipshared/xilinx.com/microblaze_v9_5/89e574e2/hdl/microblaze_v9_5_vh_rfs.vhd":55016]
[Synth 8-3332] Sequential element (\MDM_Core_I1/Config_Reg_reg[31] ) is unused and will be removed from module MDM.
[Synth 8-3295] tying undriven pin \MicroBlaze_Core_I/Performance.Core/Data_Flow_I/Shift_Logic_Module_I/mask_0_15_inferred :in0 to constant 0
Implementation
Design InitializationOpt Design Command: opt_design
[Opt 31-6] Deleting driverless net: base_microblaze_design_i/microblaze_0/U0/MicroBlaze_Core_I/Performance.Core/Data_Flow_I/EX_Op1_Zero.
Place Design
Route Design
Write Bitstream Command: open_checkpoint base_microblaze_design_wrapper_routed.dcp
[DRC 23-20] Rule violation (CFGBVS-1) Missing CFGBVS and CONFIG_VOLTAGE Design Properties - Neither the CFGBVS nor CONFIG_VOLTAGE voltage property is set in the current_design. Configuration bank voltage select (CFGBVS) must be set to VCCO or GND, and CONFIG_VOLTAGE must be set to the correct configuration voltage, in order to determine the I/O voltage support for the pins in bank 0. It is suggested to specify these either using the 'Edit Device Properties' function in the GUI or directly in the XDC file using the following syntax:

set_property CFGBVS value1 [current_design]
#where value1 is either VCCO or GND

set_property CONFIG_VOLTAGE value2 [current_design]
#where value2 is the voltage provided to configuration bank 0

Refer to the device configuration user guide for more information.

 

 

Eugene
0 Kudos
Participant e2g
Participant
10,766 Views
Registered: ‎06-10-2011

Re: Microblaze Event Counters

All cores are up to date.
Eugene
0 Kudos
Participant e2g
Participant
10,736 Views
Registered: ‎06-10-2011

Re: Microblaze Event Counters

Marking the nets for Debug between the MDM and microblaze and, Microblaze and the peripheral bus causes the system to show the correct results.

Eugene
0 Kudos
Xilinx Employee
Xilinx Employee
10,669 Views
Registered: ‎10-08-2010

Re: Microblaze Event Counters

Interesting! That would suggest that the issue is related to synthesis or implementation.

 

To narrow it down further, could you try removing MARK_DEBUG, disable opt_design (uncheck Implementation Settings - Opt Design (opt_design) - is_enabled), and then run synthesis and implementation again? If that works, the culprit is optimize design.

 

Would you also be able to submit the issue to Xilinx support?

 

0 Kudos
Participant e2g
Participant
10,637 Views
Registered: ‎06-10-2011

Re: Microblaze Event Counters

I build the system with your suggestions and this is what I noticed:

  1. Downloading and running the application on the first try resulted in the correct solution
  2. Changing the starting number for the counters and downloading/running the application subsequent times, it stopped working.
  3. Downloading the bit file again, and downloaded the application. Display correct results.
  4. I downloaded the application again (each time changing the stored result between software compilations) and it worked. 
  5. About the 5th time, it was displaying incorrect results.

 

Here are the shared libraries for my install of vivado:

ldd /opt/Xilinx/Vivado/2015.1/bin/unwrapped/lnx64.o/vivado

	linux-vdso.so.1 =>  (0x00007fff7c7e3000)
	libtcmalloc.so.4 => /opt/Xilinx/Vivado/2015.1/lib/lnx64.o/libtcmalloc.so.4 (0x00007fb76752c000)
	libboost_signals.so => /opt/Xilinx/Vivado/2015.1/lib/lnx64.o/libboost_signals.so (0x00007fb767315000)
	librdi_common.so => /opt/Xilinx/Vivado/2015.1/lib/lnx64.o/librdi_common.so (0x00007fb766762000)
	librdi_commonmain.so => /opt/Xilinx/Vivado/2015.1/lib/lnx64.o/librdi_commonmain.so (0x00007fb766556000)
	libstdc++.so.6 => /opt/Xilinx/Vivado/2015.1/lib/lnx64.o/libstdc++.so.6 (0x00007fb766253000)
	libgcc_s.so.1 => /opt/Xilinx/Vivado/2015.1/lib/lnx64.o/libgcc_s.so.1 (0x00007fb76603d000)
	libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fb765c5f000)
	libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fb765958000)
	libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007fb76573a000)
	libCOIN-all.so => /opt/Xilinx/Vivado/2015.1/lib/lnx64.o/libCOIN-all.so (0x00007fb765069000)
	libXil_lmgr11.so => /opt/Xilinx/Vivado/2015.1/lib/lnx64.o/libXil_lmgr11.so (0x00007fb764d03000)
	libboost_date_time.so => /opt/Xilinx/Vivado/2015.1/lib/lnx64.o/libboost_date_time.so (0x00007fb764af3000)
	libboost_filesystem.so => /opt/Xilinx/Vivado/2015.1/lib/lnx64.o/libboost_filesystem.so (0x00007fb7648dc000)
	libboost_program_options.so => /opt/Xilinx/Vivado/2015.1/lib/lnx64.o/libboost_program_options.so (0x00007fb76466d000)
	libboost_regex.so => /opt/Xilinx/Vivado/2015.1/lib/lnx64.o/libboost_regex.so (0x00007fb764387000)
	libboost_system.so => /opt/Xilinx/Vivado/2015.1/lib/lnx64.o/libboost_system.so (0x00007fb764183000)
	libboost_thread.so => /opt/Xilinx/Vivado/2015.1/lib/lnx64.o/libboost_thread.so (0x00007fb763f64000)
	libhdlpsolve.so => /opt/Xilinx/Vivado/2015.1/lib/lnx64.o/libhdlpsolve.so (0x00007fb763cc1000)
	libhdxml.so => /opt/Xilinx/Vivado/2015.1/lib/lnx64.o/libhdxml.so (0x00007fb763a16000)
	libisl_iostreams.so => /opt/Xilinx/Vivado/2015.1/lib/lnx64.o/libisl_iostreams.so (0x00007fb7631de000)
	libisl_iosutils.so => /opt/Xilinx/Vivado/2015.1/lib/lnx64.o/libisl_iosutils.so (0x00007fb762fc5000)
	libisl_sysinfo.so => /opt/Xilinx/Vivado/2015.1/lib/lnx64.o/libisl_sysinfo.so (0x00007fb762d91000)
	libprotobuf.so.7 => /opt/Xilinx/Vivado/2015.1/lib/lnx64.o/libprotobuf.so.7 (0x00007fb762aa0000)
	librdi_commonxillic.so => /opt/Xilinx/Vivado/2015.1/lib/lnx64.o/librdi_commonxillic.so (0x00007fb76283d000)
	librdi_curl.so => /opt/Xilinx/Vivado/2015.1/lib/lnx64.o/librdi_curl.so (0x00007fb76242d000)
	librdiconfig.so => /opt/Xilinx/Vivado/2015.1/lib/lnx64.o/librdiconfig.so (0x00007fb762215000)
	librdizlib.so => /opt/Xilinx/Vivado/2015.1/lib/lnx64.o/librdizlib.so (0x00007fb761fef000)
	libtcl8.5.so => /opt/Xilinx/Vivado/2015.1/lib/lnx64.o/libtcl8.5.so (0x00007fb761ccc000)
	libxerces-c-3.1.so => /opt/Xilinx/Vivado/2015.1/lib/lnx64.o/libxerces-c-3.1.so (0x00007fb761722000)
	libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007fb76151e000)
	libgomp.so.1 => /opt/Xilinx/Vivado/2015.1/lib/lnx64.o/libgomp.so.1 (0x00007fb76130f000)
	librdi_commonversion.so => /opt/Xilinx/Vivado/2015.1/lib/lnx64.o/librdi_commonversion.so (0x00007fb76110c000)
	/lib64/ld-linux-x86-64.so.2 (0x00007fb7677a0000)
	librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x00007fb760f03000)
	libboost_iostreams.so => /opt/Xilinx/Vivado/2015.1/lib/lnx64.o/libboost_iostreams.so (0x00007fb760cf0000)
Eugene
0 Kudos
Participant e2g
Participant
10,636 Views
Registered: ‎06-10-2011

Re: Microblaze Event Counters

Where exactly do I submit a webcase? Is this something still reserved for my professor and not a usual student XUP account. I just get the options, self-service, forums (here) and refer to the dealer you bought the hardware from.

Eugene
0 Kudos
Participant e2g
Participant
10,491 Views
Registered: ‎06-10-2011

Re: Microblaze Event Counters

bump

 

@stefana and @goran

Eugene
0 Kudos
Xilinx Employee
Xilinx Employee
10,462 Views
Registered: ‎10-08-2010

Re: Microblaze Event Counters

Sorry for the delay in replying to your post.

 

I will try to repeat what you are seeing, but I think I need some more details In step 2, you say "Changing the starting number for the counters.", and in step 4 "changing the stored result between software compilations". How did you do those two things? Were all steps done with a design inplemented with optimization disabled?

 

The availabel support for Xilinx University Program is described at XUP support. Unfortunately it doesn't seem  to include submitting support cases, so I think we have to continue here in the forum.

0 Kudos
Participant e2g
Participant
10,447 Views
Registered: ‎06-10-2011

Re: Microblaze Event Counters

Both of those mean the same thing: Changing the value I set initially in the counters. This is done on line 129

 

Screenshot from 2015-08-27 18:10:05.png

 

I wasn't sure if the previous value was cleared or not in the MDM/Microblaze registers in between software runs. Therefore, between clicking on "Run As" in SDK, I changed the 65 number you see above to something else each time.

 

 

 

UPDATE: I unchecked is_opt as per your suggestion again, and rebuilt the design. I ran the code I provided earlier and I am still puzzled what is going on. Keep in mind, I never run XSDK as we just download the ELF via xsdb.

 

Within XSDK, if I click "Run As" --> "Launch on Hardware (System Debugger)" It works consistenly. That is, it reads back the values I set in the initial event counter registers every time.

 

When I click on "Run As" --> "Launch on Hardware (GDB)", the results are not that consistent.

 

Here are the results for Launching on Hardware (GDB). I removed extra information from the screen and have it setting and reading back the event registers 20 times. It now just prints, "Setting initial values" and prints the values it reads  back. As you can see, I get wrong results (0 in 2 cases) in one or two cases.

 

--------------------------------
--- Performance Counter Test ---
--------------------------------
Setting initial counter values
Event #30 = 65
Event #00 = 70
Setting initial counter values
Event #30 = 70
Event #00 = 75
Setting initial counter values
Event #30 = 75
Event #00 = 80
Setting initial counter values
Event #30 = 80
Event #00 = 85
Setting initial counter values
Event #30 = 85
Event #00 = 90
Setting initial counter values
Event #30 = 90
Event #00 = 95
Setting initial counter values
Event #30 = 95
Event #00 = 0
Setting initial counter values
Event #30 = 100
Event #00 = 105
Setting initial counter values
Event #30 = 0
Event #00 =105
Settininitial counter values
Event #30 = 110
Event #00 = 115
Setting initial counter values
Event #30 = 115
Event #00 = 120
Setting initial counter values
Event #30 = 120
Event #00 = 125
Setting initial counter values
Event #30 = 125
Event #00 = 130
Setting initial counter values
Event #30 = 130
Event #00 = 135
Setting initial counter values
Event #30 = 135
Event #00 = 140
Setting initial counter values
Event #30 = 140
Event #00 = 145
Setting initial counter values
Event #30 = 145
Event #00 = 150
Setting initial counter values
Event #30 = 150
Event #00 = 155
Setting initial counter values
Event #30 = 155
Event #00 = 160
Setting initial counter values
Event #30 = 160
Event #00 = 165

but here are the results for Launching on Hardware (System Debugger). All correct by the way, for reference.

 

--------------------------------
--- Performance Counter Test ---
--------------------------------
Setting initial counter values
Event #30 = 65
Event #00 = 70
Setting initial counter values
Event #30 = 70
Event #00 = 75
Setting initial counter values
Event #30 = 75
Event #00 = 80
Setting initial counter values
Event #30 = 80
Event #00 = 85
Setting initial counter values
Event #30 = 85
Event #00 = 90
Setting initial counter values
Event #30 = 90
Event #00 = 95
Setting initial counter values
Event #30 = 95
Event #00 = 100
Setting initial counter values
Event #30 = 100
Event #00 = 105
Setting initial counter values
Event #30 = 105
Event #00 = 110
Setting initial counter values
Event #30 = 110
Event #00 = 115
Setting initial counter values
Event #30 = 115
Event #00 = 120
Setting initial counter values
Event #30 = 120
Event #00 = 125
Setting initial counter values
Event #30 = 125
Event #00 = 130
Setting initial counter values
Event #30 = 130
Event #00 = 135
Setting initial counter values
Event #30 = 135
Event #00 = 140
Setting initial counter values
Event #30 = 140
Event #00 = 145
Setting initial counter values
Event #30 = 145
Event #00 = 150
Setting initial counter values
Event #30 = 150
Event #00 = 155
Setting initial counter values
Event #30 = 155
Event #00 = 160
Setting initial counter values
Event #30 = 160
Event #00 = 165

Regardless of if that has any effect or not, turning is_opt off helped alot but as you can see in one of the run configurations, it reads bad data every once in awhile.

Eugene
0 Kudos
Participant e2g
Participant
10,289 Views
Registered: ‎06-10-2011

Re: Microblaze Event Counters

bump...

Eugene
0 Kudos
Participant e2g
Participant
9,071 Views
Registered: ‎06-10-2011

Re: Microblaze Event Counters

I reverted back to the system I am trying to use which is composed of 6 Microblaze processors. I am unfamiliar with the JTAG protocol (if it's even called that) between the processor and the MDM, but it seems the MicroBlaze is sending incorrect data to the MDM, which is in turn giving me an incorrect number.

 

Long story short, I am trying to read back an event counter that I initially specified to contain the number 70. I am reading back a number 17. From the waveform, it seems 17 is being sent to the MDM which means the MicroBlaze is the culprit.

 

 

Screenshot from 2015-09-22 13:10:44.png

Eugene
0 Kudos
Participant e2g
Participant
9,067 Views
Registered: ‎06-10-2011

Re: Microblaze Event Counters

 

Brackground:

I have a 6 processor system, of which there exists a host processor on the first MDM port and 5 slave processors on the rest. Processors are the MicroBlaze. The host and the first slave reads out incorrect numbers (16,17) instead of (65,70,  the values that I actually specify in each of the event counters). The 3rd processor (2nd slave processor) reads back the value 65, 70 correctly. 

 

Update:

I have verified that the numbers 16, and 17 are being sent by the MicroBlaze/MDM ports that are not working correctly. Before I assumed that it is the MicroBlaze and not the MDM, I also verified that when specifying/writing the values of 65, 70, that the MDM is actually sending those numbers to the Microblaze and not these strange values 16,17.

 

Yes, the MDM does indeed send the proper values 65, and 70

 

Writing 65 into First slave processor that reads back 16 instead

 

 

 

Writing 65 into 2nd slave processor that reads back correct value (65)

 

Eugene
0 Kudos
Xilinx Employee
Xilinx Employee
9,054 Views
Registered: ‎07-30-2007

Re: Microblaze Event Counters

The strange part is that the failure seems to be run or build dependent. Can you characterize when the failure occurs?

Is it build dependent? Board dependent? Does it never fail on the first run, but fail on all subsequent?

 

With random hardware failures like this, the first thing I check is timing constraints. I've analyzed your design and it is correctly constrained to expect a 200MHz input clock.

 

Next we have to tease out if it is an RTL bug or an synthesis/implementation issue.

0 Kudos
Participant e2g
Participant
9,047 Views
Registered: ‎06-10-2011

Re: Microblaze Event Counters

I have  tried the system I sent you sometime ago on both virtex7 and kintex7 with wrong results that occur on the first and subsequent runs (I just rebuilt that design, and ran it three times and on the fourth time, it should both numbers read back as correct. It appears to be random.) Some time ago, I tried stefano's suggestion, I turned off implementation optimization (is_opt) and that produced more consistent results but fails at least once (see post #19).

 

I would be interested to know if the simple design I sent you works for multiple runs.

 

Code:

#include <stdio.h>
#include "platform.h"
#include "xparameters.h"

#define  MDM_BASEADDR         XPAR_MDM_1_BASEADDR
#define  DBG_STATUS           (MDM_BASEADDR + 0x10)
#define  DBG_CTRL             (MDM_BASEADDR + 0x10)
#define  DBG_DATA             (MDM_BASEADDR + 0x14)
#define  DBG_LOCK             (MDM_BASEADDR + 0x18)

#define NUM_TRIALS				20

/**
 * Function to write specified command to MDM CTRL register.
 */
void mdm_cmd(unsigned int  cmd) {
	volatile unsigned int * status  = (unsigned int *) DBG_STATUS;
	volatile unsigned int * control = (unsigned int *) DBG_CTRL;

	do {
		*control = cmd;
	} while( *status != 0x1);

	return;
}

void print(char *str);

int main()
{
    init_platform();
	disable_caches();

    print("Hello World\n\r");
    print("--------------------------------\n\r");
    print("--- Performance Counter Test ---\n\r");
    print("--------------------------------\n\r");
    volatile unsigned int * status  = (unsigned int *) DBG_STATUS;
    volatile unsigned int * control = (unsigned int *) DBG_CTRL;
    volatile unsigned int * data    = (unsigned int *) DBG_DATA;
    volatile unsigned int * lock    = (unsigned int *) DBG_LOCK;
    int i,j;

    unsigned int event_num[] = {30, 0};
    unsigned int event_num_size = sizeof(event_num) / sizeof(unsigned int);

    for (i = 0; i < NUM_TRIALS; i++)
    {
		//print("Gaining access to MDM registers\n\r");
		// Gain access to DBG_CTRL and DBG_DATA
		// registers in MDM by writing magic num
		*lock = 0xebab;
		//print("Done\n\r");

		/* C_MB_DBG_PORTS == 1; hence, no need to do this
		print("Specifying Port on MDM\n\r");
		mdm_cmd(0x61A07);
		*data = 0x1;
		print("Done\n\r");
		*/

		//print("Resetting event counter selection back to the first\n\r");
		mdm_cmd(0x4A404); 
		*data = 0x1;
		//print("Done\n\r");

		//print("Specifying event numbers\n\r");
		for( j = 0; j < event_num_size; j++) {
			mdm_cmd(0x4A207);
			*data = event_num[j];
		}
		//print("Done\n\r");

		//print("Resetting event counter selection back to the first\n\r");
		mdm_cmd(0x4A404);
		*data = 0x1;
		//print("Done\n\r");

		print("Setting initial counter values\n\r");
		for( j = 0; j < event_num_size; j++) {
			mdm_cmd(0x4AE1F);
			int k = j*5 + 65;
			xil_printf("\tSetting %d\n\r", k );
			*data = k;
		}

		//print("Resetting event counter selection back to the first\n\r");
		mdm_cmd(0x4A404);
		*data = 0x1;
		//print("Done\n\r");

	/*
		// Clear and start all counters for this processor
		mdm_cmd(0x4A404);
		*data = 0x18;   // Clear and start
	*/

		//print("Setting sample bit\n\r");
		mdm_cmd(0x4A404);
		*data = 0x2;
		//print("Done\n\r");

		//print("Setting stop bit\n\r");
		mdm_cmd(0x4A404);
		*data = 0x4;
		//print("Done\n\r");


		//print("Resetting event counter selection back to the first\n\r");
		mdm_cmd(0x4A404);
		*data = 0x1;
		//print("Done\n\r");

		// Check for Overflow and Full bits
		/*ifor( j = 0; j < event_num_size; j++) {
			mdm_cmd(0x4A601);
			xil_printf("Overflow-Full 0x%02x\n\r", *data);
		}*/

		//print("Resetting event counter selection back to the first\n\r");
		mdm_cmd(0x4A404);
		*data = 0x1;
		//print("Done\n\r");

		print("Reading from Event Counters:\n\r");
		// Read events and latency counters
		for( j = 0; j < event_num_size; j++) {
			xil_printf("Event #%02d = ", event_num[j]);
			mdm_cmd(0x4AC1F);
			xil_printf("%d\n\r", *data);
		}
		print("Done\n\r");

		//print("Locking the MDM registers\n\r");
		*lock = 0;
		//print("Done\n\r");
    }

    cleanup_platform();
    return 0;
}

 

Output:

 

 

--------------------------------
--- Performance Counter Test ---
--------------------------------
Setting initial counter values
        Setting 65
        Setting 70
Reading from Event Counters:
Event #30 = 65
Event #00 = 0
Done
Setting initial counter values
        Setting 65
        Setting 70
Reading from Event Counters:
Event #30 = 0
Event #00 = 65
Done
Setting initial counter values
        Setting 65
        Setting 70
Reading from Event Counters:
Event #30 = 65
Event #00 = 0
Done
Setting initial counter values
        Setting 65
        Setting 70
Reading from Event Counters:
Event #30 = 65
Event #00 = 70
Done
Setting initial counter values
        Setting 65
        Setting 70
Reading from Event Counters:
Event #30 = 65
Event #00 = 70
Done
Setting initial counter values
        Setting 65
        Setting 70
Reading from Event Counters:
Event #30 = 65
Event #00 = 70
Done
Setting initial counter values
        Setting 65
        Setting 70
Reading from Event Counters:
Event #30 = 70
Event #00 = 70
Done
Setting initial counter values
        Setting 65
        Setting 70
Reading from Event Counters:
Event #30 = 65
Event #00 = 70
Done
Setting initial counter values
        Setting 65
        Setting 70
Reading from Event Counters:
Event #30 = 0
Event #00 =65
Done
    Setting initial counter values
        Setting 65
        Setting 70
Reading from Event Counters:
Event #30 = 70
Event #00 = 70
Done
Setting initial counter values
        Setting 65
        Setting 70
Reading from Event Counters:
Event #30 = 65
Event #00 = 0
Done
Setting initial counter values
        Setting 65
        Setting 70
Reading from Event Counters:
Event #30 = 65
Event #00 = 0
Done
Setting initial counter values
        Setting 65
        Setting 70
Reading from Event Counters:
Event #30 = 65
Event #00 = 70
Done
Setting initial counter values
        Setting 65
        Setting 70
Reading from Event Counters:
Event #30 = 65
Event #00 = 70
Done
Setting initial counter values
        Setting 65
        Setting 70
Reading from Event Counters:
Event #30 = 65
Event #00 = 70
Done
Setting initial counter values
        Setting 65
        Setting 70
Reading from Event Counters:
Event #30 = 65
Event #00 = 70
Done
Setting initial counter values
        Setting 65
        Setting 70
Reading from Event Counters:
Event #30 = 65
Event #00 = 70
Done
Setting initial counter values
        Setting 65
        Setting 70
Reading from Event Counters:
Event #30 = 65
Event #00 = 70
Done
Setting initial counter values
        Setting 65
        Setting 70
Reading from Event Counters:
Event #30 = 65
Event #00 = 70
Done
Setting initial counter values
        Setting 65
        Setting 70
Reading from Event Counters:
Event #30 = 65
Event #00 = 70
Done
Eugene
0 Kudos