Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
7 years ago

Cyclone V: connecting multiple slaves via Avalon MM interface to HPS

Hello all,

I am using the DE0-Nano-SoC kit, where the Cyclone V FPGA is located and Quartus Prime Version 17.1.0 software. I have a problem with the PLL reprogrammable configuration using the Avalon MM interface. I'm guessing that the problem is with the Avalon MM interface configuration. Can I connect several slaves directly to 'h2f_lw_axi_master' port of 'Cyclone V Hard Processor System' or should I use some intermediate IPcore for this? Below I attach screenshots from my platform designer's system, configuration of PLL block, content of registers, where should be PLL configuration, but I have strange things and my C-driver. I will be very grateful for any suggestions.

P.S. I checked the signals and my program does not stand in the reset or interrupt, and the 'locked' signal from the Altera PLL block is still in a high state. My input clock is 50MHz.

My C-driver for configuration of PLL:

#include <stdio.h># include <unistd.h># include <fcntl.h># include <sys/mman.h># include <sys/stat.h># include "hwlib.h"# include "soc_cv_av/socal/socal.h"# include "soc_cv_av/socal/hps.h"# include "soc_cv_av/socal/alt_gpio.h"# include "hps_0.h"
/* Registers for PLL Reconfig*/
# define MODE              0x00# define STATUS            0x01# define START             0x02# define N_COUNTER         0x03# define M_COUNTER         0x04# define C_COUNTER         0x05# define DPS_COUNTER        0x06# define FRAC_COUNTER     0x07# define BS_COUNTER        0x08# define CPS_COUNTER        0x09# define C0_COUNTER         0x0A# define C1_COUNTER         0x0B
# define MAPPED_SIZE (RECONFIG_SLOW_CLK_SPAN+IPCORE_GPIO_0_SPAN)
static void write_reg(unsigned int base, unsigned int offset, unsigned int val){
        volatile unsigned int* reg;
        reg = (unsigned int*)(base + offset);
        *reg = val;
}
static unsigned int read_reg(unsigned int base, unsigned int offset){
        volatile unsigned int* reg;        
        reg = (unsigned int*)(base + offset);
        return *reg;
}
int main() {
    
    printf("\nDate: %s ; Time: %s\n\n", __DATE__, __TIME__);
    void *virtual_base;
    int fd, i; 
    int counter = 0xFFFF0000;
    unsigned int reg;
    if( ( fd = open( "/dev/mem", ( O_RDWR | O_SYNC ) ) ) == -1 ) {
        printf( "ERROR: could not open \"/dev/mem\"...\n" );
        return( 1 );
    }
    
    virtual_base = mmap(NULL, MAPPED_SIZE, ( PROT_READ | PROT_WRITE ), MAP_SHARED, fd, 0x0);
    if(virtual_base == MAP_FAILED) {
        printf( "ERROR: mmap() failed!\n" );
        close( fd );
        return( 1 );
    }
    
    unsigned int base_addr_gpio = (unsigned int) (virtual_base + IPCORE_GPIO_0_BASE);
    unsigned int base_addr_clk = (unsigned int) (virtual_base + RECONFIG_SLOW_CLK_BASE);
    
    printf("Simulation of GPIO:\n\n");
    //simulate GPIO
    for(i = 0; i < 64; i++ ){
        write_reg(base_addr_gpio, 0x0, counter);
        reg = read_reg(base_addr_gpio, 0x0);
        printf("Memory content: 0x%x\t Number loop: %d\n", reg, i);
        counter=counter+1;
    }
    
    printf("\nConfiguration of PLL:\n\n");
    
    //configuration PLL to 1 MHz
    // f_ref = (f_in/n) = 50MHz / 1 = 50 MHz => (f_ref range: 50-800 MHz!)
    // f_out = ((f_ref * M)/C)
    // 1MHz = ( 50 MHz *1)/50 )
    write_reg(base_addr_clk, MODE, 0b1); // polling mode
    reg = read_reg(base_addr_clk, MODE);
    printf("MODE of PLL: 0x%x\n", reg);
    
    write_reg(base_addr_clk, M_COUNTER, 0x0001); // M = 1 
    reg = read_reg(base_addr_clk, M_COUNTER);
    printf("M_COUNTER of PLL: 0x%x\n", reg);
    
    write_reg(base_addr_clk, FRAC_COUNTER, 0x000000); 
    
    write_reg(base_addr_clk, N_COUNTER, 0x0001); // N = 1
    //write_reg(base_addr_clk, N_COUNTER, 0x10000); // N -> bypass enable (f_ref = f_in)
    reg = read_reg(base_addr_clk, N_COUNTER);
    printf("N_COUNTER of PLL: 0x%x\n", reg);
    
    write_reg(base_addr_clk, C_COUNTER, 0x00A06); // C = 50 (0x19+0x19) -> set C0
    
    reg = read_reg(base_addr_clk, C_COUNTER);
    printf("C_COUNTER of PLL: 0x%x\n", reg);
    
    write_reg(base_addr_clk, C_COUNTER, 0x4060E); // C = 50 (0x19+0x19) -> set C1
    
    reg = read_reg(base_addr_clk, C_COUNTER);
    printf("C_COUNTER of PLL: 0x%x\n", reg);
    
    write_reg(base_addr_clk, BS_COUNTER, 0x6); // medium bandwidth
    reg = read_reg(base_addr_clk, BS_COUNTER);
    printf("BS_COUNTER of PLL: 0x%x\n", reg);
    
    write_reg(base_addr_clk, CPS_COUNTER, 0x2);
    reg = read_reg(base_addr_clk, CPS_COUNTER);
    printf("CPS_COUNTER of PLL: 0x%x\n", reg);
    
    write_reg(base_addr_clk, START, 0b1);
    
    sleep(1);
    reg = read_reg(base_addr_clk, M_COUNTER);
    printf("\nM_COUNTER of PLL: 0x%x\n", reg);
    reg = read_reg(base_addr_clk, N_COUNTER);
    printf("N_COUNTER of PLL: 0x%x\n", reg);
    reg = read_reg(base_addr_clk, C_COUNTER);
    printf("C_COUNTER of PLL: 0x%x\n", reg);
    reg = read_reg(base_addr_clk, C0_COUNTER);
    printf("C0_COUNTER of PLL: 0x%x\n", reg);
    reg = read_reg(base_addr_clk, C1_COUNTER);
    printf("C1_COUNTER of PLL: 0x%x\n", reg);
    reg = read_reg(base_addr_clk, STATUS);
    printf("Status of PLL: 0x%x\n", reg);
    
    if(reg != 0x01)
        printf("Unfortunately PLL is not correctly configured\n\n");
    else
        printf("Successful: PLL is correctly configured\n\n");
                
    if(munmap(virtual_base, MAPPED_SIZE) != 0){
        printf( "ERROR: munmap() failed...\n" );
        close( fd );
        return( 1 );
    }
    close( fd );
    return( 0 );
}

https://alteraforum.com/forum/attachment.php?attachmentid=15302&stc=1
No RepliesBe the first to reply