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

Всем привет! Хочу поделиться (и заодно получить ревью кода) самописным SPI slave модулем.

 

Гитхаб

 

Тестбенч там же, в репозитории. Вот небольшая вырезка из тестов)

 

SPI.png

post-81523-1467156677_thumb.png

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


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

Всем привет! Хочу поделиться (и заодно получить ревью кода) самописным SPI slave модулем.

 

Тестбенч там же, в репозитории. Вот небольшая вырезка из тестов)

Из плюсов :

Код красивый, структурированный, педантичный (использование логической арифметики условий вместо бинарной)

 

Из минусов по RTL :

По коду :

1. Код логически сложно читать. Сложные условия, лучше собрать отдельно, введя промежуточные сигналы вида wire sck_posedge = CPOL ? (SCK & !SCK_sync) : (!SCK & SCK_sync);

2. Правила хорошего тона, предписывают придерживаться единой нотации сигналов/параметров/констант. Смешивание имен сигналов в верхнем/нижнем регистрах ИМХО режет взгляд.

3. Тоже самое относиться к нотации портов. Либо вы все делаете с квалификаторами направления, либо не делаете вообще.

По логике :

Работать будет, но может глючить:

1. В виду недостаточности одного регистра для устранения метастабильных состояний.

2. Не увидел в коде выхода из аварийных ситуаций приемника, а именно выключение CS до достижения передачи 8 го бита. Битовый счетчик синхронизируется сам по себе, либо по сигналу сброса.

 

Из минусов по tb:

1. Это так называемый ad-hoc tb, демонстрирующий включение корки. Использовать его для отладки затруднительно, т.к. проверка только глазами.

2. Нет автоматического тестирования.

3. Нет моделирования аварийных ситуаций.

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


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

1. В виду недостаточности одного регистра для устранения метастабильных состояний.

Вы про этот регистр "SCK_sync" ?

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


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

Спасибо, уже работаю над ошибками по коду и стилю) Получается, MOSI тоже надо засинхронизировать? Тогда выходит, что у меня основная частота должна быть хотя бы в 3 раза выше, чем частота sck.

 

Что касается автоматических тестов, можете привести пример, как это вообще делается? Я пока ещё не совсем въехал)

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

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


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

Тогда выходит, что у меня основная частота должна быть хотя бы в 3 раза выше, чем частота sck.

Никто не мешает вам работать на частоте самого SPI(sck), а потом уже кидать информацию в основной клоковый домен, скажем, через FIFO.

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


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

Никто не мешает вам работать на частоте самого SPI(sck), а потом уже кидать информацию в основной клоковый домен, скажем, через FIFO.

С этим есть некоторые проблемы: при CPHA = 0 данные выставляются на шине не по sck, а по фронту/спаду (в зависимости от того, какой выбран активный уровень) cs. Клока sck в этот момент ещё нет, поэтому нужно либо ставить отдельный триггер, тактирующийся от cs, либо кидать внешний клок, следящий за изменением cs. Я не хочу плодить клоки

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


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

С этим есть некоторые проблемы: при CPHA = 0 данные выставляются на шине не по sck, а по фронту/спаду (в зависимости от того, какой выбран активный уровень) cs. Клока sck в этот момент ещё нет, поэтому нужно либо ставить отдельный триггер, тактирующийся от cs, либо кидать внешний клок, следящий за изменением cs. Я не хочу плодить клоки

так вроде как должно быть

MISO = !CS ? shiftReg[7] : 1'bz;

то есть при взводе CS данные сразу появляются на шине без каких-либо дополнительных триггеров/клоков.

 

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


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

так вроде как должно быть

MISO = !CS ? shiftReg[7] : 1'bz;

то есть при взводе CS данные сразу появляются на шине без каких-либо дополнительных триггеров/клоков.

Тут опять же зависит от CPHA, если этот бит установлен в 1, то первый бит выставляется на шину только по первому изменению sck, не раньше. Ну и в сам shiftReg данные откуда-то закидываются же) по другому клоку, системному. Опять же получается плодим клоки

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


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

Тут опять же зависит от CPHA, если этот бит установлен в 1, то первый бит выставляется на шину только по первому изменению sck, не раньше. Ну и в сам shiftReg данные откуда-то закидываются же) по другому клоку, системному. Опять же получается плодим клоки

и что же тогда должно быть на шине между CS и первым SCLK?

даже не так, какая разница что там будет на шине между CS и первым фронтом клока?

а если без разницы, то почему бы там не оказаться первому биту

 

и клоков в любом случае два и в каком месте переходить от одного к другому не принципиально.

но имхо удобнее когда сдвиговый регистр незасимо от системных клоков, сам по себе от SCLK работает, а синхронизация при выгрузке/загрузке сдвигового регистра. а не когда sclk синхронизируется под системный клок.

у MSP430 USCI так сделан, как-то раз оказалось довольно удобно, что как SPI слэйву, данные снаружи могут задвинуть на любой скорости, не зависимо от системных клоков и вообще их наличия.

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


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

и что же тогда должно быть на шине между CS и первым SCLK?

даже не так, какая разница что там будет на шине между CS и первым фронтом клока?

а если без разницы, то почему бы там не оказаться первому биту

Вообще здравая мысль) сейчас попробую сделать именно так

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


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

Что-то я в ступоре, как мне сделать всё-таки тактирование напрямую от SCK, если в зависимости от CPOL и CPHA задвигать данные нужно по разным фронтам. Получается у меня multiple driver

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


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

посмотрел код, как-то очень уж многословно для описания сдвигового регистра.

ограничивать впихуемое размером регистра имхо не надо, пусть дальше наружу лезет.

а то потом получается что много-много простых spi устройств в daisy chain не включить и вместо одной цепочки надо городить кучу чипселектов.

 

и для слэйва режимов пожалуй всё-таки не 4, а 2. какая там будет полярность у клоков до и после передачи ему одинаково.

 

assign miso = (!cs) ? (msb ? shiftReg[DATAWIDTH - 1] : shiftReg[0]) : 1'bz;
always (@ clk) 
  if (!cs) begin
    if ((cpha ^ cpol) ^ clk) sample <= mosi;
    else shiftReg <= msb ? {shiftReg[DATA_WIDTH-1 : 1], sample} : {sample, shiftReg[DATA_WIDTH-2 : 0]};    
  end

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


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

Получается, MOSI тоже надо засинхронизировать? Тогда выходит, что у меня основная частота должна быть хотя бы в 3 раза выше, чем частота sck.

MOSI не обязательно, т.к. мастер должен выдерживать tsu/th для этого сигнала относительно SCK. А насчет в 3 раза выше, так это в любом случае надо, т.к. иначе вы можете корректно не поймать переходы SCK. В этом и есть недостаток всех SPI в пересадкой сигнала на чистую высокую тактовую.

Что касается автоматических тестов, можете привести пример, как это вообще делается? Я пока ещё не совсем въехал)

Тест должен проверять работу модуля без участия человека. Самый простой вариант для SPI - запись - чтение - проверка состояния модуля. Тут лучше почить книги что-то вроде SV for verification.

 

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


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

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

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

Гость
Ответить в этой теме...

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

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

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

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

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

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