cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
ankmax
Visitor
Visitor
947 Views
Registered: ‎02-18-2017

Clocking wizard 5.2 dynamic reconfiguration via AXI4-Lite in linux

Hi,

 

I am trying to check if Dynamic reconfiguration of clock works. Problem is whenever I check the value of status register (0x04), it is always '1'. When I check the default value of say clock configuration register 2, it does come out

0x0004000a

as mentioned in the clocking wizard guide. So, it means communication with the AXI Lite clocking wizard registers is happening. I do not understand what I am doing wrong. I tried to check this design with a slave AXI lite peripheral to see if the clocks where changing but it was not.

 

Do I need some special drivers in Linux for clocking wizard? Or if there is problem with the hardware design and the code?

Your input will be appreciated. Thank you!

Below is the code and hardware design used for testing.

 

//VCO Frequency = (Input Clock Frequency) * (CLKFBOUT_MULT)/DIVCLK_DIVIDE
#define CLK_REG0	0x200		//set 0x00000A01 (DIVCLK_DIVIDE[7:0] - 1, CLKFBOUT_MULT[15:8] - 10 (Default - 0x01010A00))
#define CLK_REG2	0x208		//set 0x00000005 (CLKOUT0_DIVIDE[7:0] - 5 (clkout1 = VCO/CLKOUT0_DIVIDE, status reg - 0x1) (Default - 0x0004000a))
#define CLK_REG23	0x25C		//set 0x00000003 (BIT2 - SEN, BIT1 - SADDR, BIT0 - LOAD)
#define STATUS		0x04		//Status register, BIT[0] - LOCKED

void clock_reconfig()
{
    int dh = open("/dev/mem", O_RDWR | O_SYNC);
    unsigned int* address = mmap(NULL, 65535, PROT_READ | PROT_WRITE, MAP_SHARED, dh, 0x43C00000);

	address[CLK_REG0>>2] 		= 0x00000A01;
	address[CLK_REG2>>2] 		= 0x00000005;
	while(address[STATUS>>2] != 1);
        //Start dynamic reconfiguration state m/c	
        address[CLK_REG23>>2]		= 0x00000007;	
	address[CLK_REG23>>2]		= 0x00000002;
	//Wait for locked signal
	sleep(1);
}

hardwaredesign.png

0 Kudos
Reply
1 Reply
johnmcd
Xilinx Employee
Xilinx Employee
915 Views
Registered: ‎02-01-2008

I had it working with baremetal and started with the example app for the driver. There was a bug in the example app but it was with respect to calculating the fractional divide.

 

So comparing my stuff to yours (and I'm not looking at the docs) I see:

  • You write to offset 0x200 and 0x208 for clk mult/divide values. I write to 0x208 and write phase value 0 to 0x20C
  • next, I do not check for not locked.
  • next, same as you, write 7 to 0x25c
  • now I check for clk not locked
  • same as you write 0x2 to 0x25c
  • same as you, wait for lock

Below is a snippet of my code, after calculating the mult/div values. In this snippet you will see a led out macro called every once in a while. That's because I used microblaze and this src (without prints) in hardware simulation.

    /* Configuring Multiply and Divide values */
    *(u32 *)(CfgPtr_Dynamic->BaseAddr + 0x208) =
	    Frac_en | (Frac_divide << 8) | (Divide);
    *(u32 *)(CfgPtr_Dynamic->BaseAddr + 0x20C) = 0x00;  //Phase
    LED_OUT(0xa);

    /* Load Clock Configuration Register values */
    *(u32 *)(CfgPtr_Dynamic->BaseAddr + 0x25C) = 0x07;
    LED_OUT(0xb);

    if(*(u32 *)(CfgPtr_Dynamic->BaseAddr + 0x04) & CLK_LOCK) {
        LED_OUT(0x83);
        Error++;
        xil_printf("\n ERROR: Clock is locked : 0x%x \t expected "
	    "0x00\n\r", *(u32 *)(CfgPtr_Dynamic->BaseAddr + 0x04) & CLK_LOCK);
     }
    LED_OUT(0xc);

     /* Clock Configuration Registers are used for dynamic reconfiguration */
     *(u32 *)(CfgPtr_Dynamic->BaseAddr + 0x25C) = 0x02;
     LED_OUT(0xd);

    Fail = Wait_For_Lock(CfgPtr_Dynamic);
    LED_OUT(0xe);
    if(Fail) {
	    LED_OUT(0x84);
	    Error++;
	    xil_printf("\n ERROR: Clock is not locked : 0x%x \t Expected "\
        		": 0x1\n\r", *(u32 *)(CfgPtr_Dynamic->BaseAddr + 0x04) & CLK_LOCK);
    }
0 Kudos
Reply