Перейти к содержанию
    

Реальное время доступа к DDRAM

Имеем в наличие TMS320C6455. На входе второго клока - 40MHz. Т.е. тактовая частота DDR контроллера = 40*20/2 = 400МГц.

Тактовая частота процессора = 1ГГц.

Кроме того имеем 2 штуки MT47H32M16HR-25E c Tck=2.5nS и CL=5.

 

Далее - пишется программа на С (без оптимизации), которая в цикле читает 200 раз косвенно по адресу читает из внутреннего ОЗУ в регистр некоторое значение. Потом дергается GPIO пин, подключенный к осциллографу, потом абсолютно идентичный цикл, в котором в качестве косвенного адреса выступает адрес DDRAM. И - снова дергает пин GPIO.

 

Итог - время для 200 чтений внутренней памяти - 6.2uS, время для 200 чтений DDRAM - 22.6uS. Вычитаем, делим на 200 и получаем, что одно чтение (а читаю я словами по 32 бита - потому как две микросхемы по 16) из DDRAM занимает примерно 80nS.

 

Вот и вопрос - не многовато ли? Настройки контроллера делались исключительно по формулам, приведенным в соответствующем PDF-е. Если что - иогу тут их выложить.

 

Объясните - где тут фокус зарыт, почему так медленно?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вы меряете не время чтения памяти, а время выполнения GPIO. Не удивлюсь, если один вывод в GPIO дольше чем все 200 чтений внутренней RAM. :)

Неверная методика измерений.

Надо делать примерно так: дёргаете ногой 1раз, делаете N чтений из DDR, дёргаете ногой 2раз, делаете N+M чтений из DDR, дёргаете ногой 3раз. Вычитаете время (2раз-1раз) из (3раз-2раз), делите на M.

Да и программу лучше компилить с полной оптимизацией, объявив указатель чтения как: volatile u32 *p

Изменено пользователем jcxz

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вы меряете не время чтения памяти, а время выполнения GPIO. Не удивлюсь, если один вывод в GPIO дольше чем все 200 чтений внутренней RAM. :)

Увы - если бы в этом было дело.. Но суть в том, что с ног GPIO я начинал. И четко знаю, что состояние ног GPIO меняется с частотой 133 МГц. Т.е максимальная погрешность, вносимая обменом по GPIO составляет 8 нс. Т.е. ей можно пренебречь.

 

На всякий случай - привожу текст программы:

    register volatile Uint32 *gpset, *gpclr;
    volatile Uint32 *pram, ram, *vram = &ram;
    Uint32 eram;
    unsigned short xxx;
    int i;
    gpset = &(((CSL_GpioRegs*)CSL_GPIO_0_REGS)->SET_DATA);
    gpclr = &(((CSL_GpioRegs*)CSL_GPIO_0_REGS)->CLR_DATA);
    ram - 0x12345678;
    for (;;) {
        *gpclr = CSL_FMK(GPIO_SET_DATA_SET4, CSL_GPIO_SET_DATA_SET_SET);
        for (i = 0, pram = (volatile Uint32 *) DDR2_BASE_ADDR; i < 200; i++, pram++)
            eram = *vram;
        *gpset = CSL_FMK(GPIO_SET_DATA_SET4, CSL_GPIO_SET_DATA_SET_SET);
        for (i = 0, pram = (volatile Uint32 *) DDR2_BASE_ADDR; i < 200; i++, pram++)
            eram = *pram;
    }

А вот инициализация контроллера DDRAM:

    register Uint32 mask, mask2;
    /*PERCFG1 - enable DDRAM interface*/
    CSL_FINST(((CSL_DevRegs*)CSL_DEV_REGS)->PERCFG1, DEV_PERCFG1_DDR2CTL, ENABLE);

    /*DMCCTL*/
    CSL_FINST (((CSL_Ddr2Regs *) CSL_DDR2_0_REGS)->DMCCTL, DDR2_DMCCTL_IFRESET, ASSERT);

    mask = ((CSL_Ddr2Regs *) CSL_DDR2_0_REGS)->SDCFG;
    ((CSL_Ddr2Regs *) CSL_DDR2_0_REGS)->SDCFG = mask | CSL_DDR2_SDCFG_BOOT_UNLOCK_MASK;
    ((CSL_Ddr2Regs *) CSL_DDR2_0_REGS)->SDCFG = mask & ~(CSL_DDR2_SDCFG_BOOT_UNLOCK_MASK | CSL_DDR2_SDCFG_DDR_DRIVE_MASK);

    mask = ((CSL_Ddr2Regs *) CSL_DDR2_0_REGS)->SDCFG;
    ((CSL_Ddr2Regs *) CSL_DDR2_0_REGS)->SDCFG = mask | CSL_DDR2_SDCFG_TIMUNLOCK_MASK;

    /*SDTIM1*/
    mask2 = CSL_FMK(DDR2_SDTIM1_T_RFC, 41) 
        | CSL_FMK(DDR2_SDTIM1_T_RP, 4)
        | CSL_FMK(DDR2_SDTIM1_T_RCD, 4)
        | CSL_FMK(DDR2_SDTIM1_T_WR, 5)
        | CSL_FMK(DDR2_SDTIM1_T_RAS, 16)
        | CSL_FMK(DDR2_SDTIM1_T_RC, 22)
        | CSL_FMK(DDR2_SDTIM1_T_RRD, 4)
        | CSL_FMK(DDR2_SDTIM1_T_WTR, 2);
    ((CSL_Ddr2Regs *) CSL_DDR2_0_REGS)->SDTIM1 = mask2;

    /*SDTIM2*/
    mask2 = CSL_FMK(DDR2_SDTIM2_T_ODT, 2) 
        | CSL_FMK(DDR2_SDTIM2_T_SXNR, 46)
        | CSL_FMK(DDR2_SDTIM2_T_SXRD, 199)
        | CSL_FMK(DDR2_SDTIM2_T_RTP, 2)
        | CSL_FMK(DDR2_SDTIM2_T_CKE, 2);
    ((CSL_Ddr2Regs *) CSL_DDR2_0_REGS)->SDTIM2 = mask2;

    /* SDRFC*/
    ((CSL_Ddr2Regs *) CSL_DDR2_0_REGS)->SDRFC = CSL_FMK( DDR2_SDRFC_REFRESH_RATE, 1560 );

    mask &= ~CSL_DDR2_SDCFG_TIMUNLOCK_MASK;
    ((CSL_Ddr2Regs *) CSL_DDR2_0_REGS)->SDCFG = mask;

    /*DMCCTL*/
    CSL_FINS (((CSL_Ddr2Regs *) CSL_DDR2_0_REGS)->DMCCTL, DDR2_DMCCTL_RL, 6);

    mask &= ~(CSL_DDR2_SDCFG_NM_MASK|CSL_DDR2_SDCFG_CL_MASK|CSL_DDR2_SDCFG_IBANK_MASK|CSL_
DDR2_SDCFG_PAGESIZE_MASK);
    mask |= CSL_FMK(DDR2_SDCFG_NM, CSL_DDR2_SDCFG_NM_32BIT) 
        | CSL_FMK(DDR2_SDCFG_CL, CSL_DDR2_SDCFG_CL_FIVE)
        | CSL_FMK(DDR2_SDCFG_IBANK, CSL_DDR2_SDCFG_IBANK_FOUR)
        | CSL_FMK(DDR2_SDCFG_PAGESIZE, CSL_DDR2_SDCFG_PAGESIZE_1024W_PAGE);
    ((CSL_Ddr2Regs *) CSL_DDR2_0_REGS)->SDCFG = mask;

    /*DMCCTL*/
    CSL_FINST (((CSL_Ddr2Regs *) CSL_DDR2_0_REGS)->DMCCTL, DDR2_DMCCTL_IFRESET, RELEASE);

Могу привести расчет значений, устанавливаемых в регистры.. Вроде - все делал аккуратно.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...