Darti 0 29 января, 2015 Опубликовано 29 января, 2015 · Жалоба Пытаюсь совокупить Atmega8 и EPM240, конечная цель генератор DDS, авр задает, плис молотит. Делаю исключительно just for fun, чтобы получить немного опыта. В общем все завелось и фурычит, но через одно место. Проблема очевидно в SPI модуле, суть такова что аврка пересчитывает частоту в переменную размерностью 32 бита, толкает их по spi, плисина должна принять стартовый бит '*', а затем 4 байта и использовать их. После Си верилог для меня в целом понятен, но читать чужие куски просто нереально, поэтому я решил написать свой модуль spi. ///---------------------------------------///// /// SPI RECEIVE DATA ///---------------------------------------///// //если чип селект не равен 0, т.е. данные не передаются if(ss) begin nBit <= 0; //обнуляем счетчик принятых битов end //если данные передаются else begin //нужно поймать восходящий фронт, тактовых импульсов spi //при этом смотрим читали ли мы уже на этом импульсе if((s_clk == 1) && (bit_readed == 0)) begin //читаем данные spi_data[7:0] <= {spi_data[6:0],mosi}; //увеличиваем счетчик nBit <= nBit + 1'b1; //выставляем флаг что на этом импульсе данные уже прочитаны bit_readed <= 1; end //по спадающему фронту, сбрасываем флаг того что данные прочитаны if(s_clk == 0) begin bit_readed <= 0; end //если прочитали 8 бит if(nBit == 8) begin //выставляем флаг что байт готов к обработке byte_readed <= 1; //обнуляем биты nBit <= 0; end end Дальше идет разбор байтов //если байт прочитан if(byte_readed == 1) begin //выставляем флаг byte_readed <= 0; //смотрим номер прочитанного байта case(n_Byte) 1: begin temp_resByte[7:0] <= spi_data[7:0]; n_Byte <= 2; end 2: begin temp_resByte[15:8] <= spi_data[7:0]; n_Byte <= 3; end 3: begin temp_resByte[23:16]<= spi_data[7:0]; n_Byte <= 4; end 4: begin temp_resByte[31:24]<= spi_data[7:0]; n_Byte <= 0; add_Counter[31:0] <= temp_resByte[31:0]; end 0: begin n_Byte <= 0; // do nothing end endcase //если прочитанный байт '*', то читаем остальные байты if(spi_data[7:0] == 8'b00101010) begin n_Byte <= 1; end end Проблема в том, что данные читаются через раз, через два, бывает и больше, самое главное на мк я бы посмотрел отладчиком, что приходит, здесь же не знаю как и подступиться к проблеме. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Golikov 0 29 января, 2015 Опубликовано 29 января, 2015 · Жалоба Жестко. Вам надо работать по фронтам клока. Либо спи либо отдельного. А так это слишком все шатко. Ключевое слово Always @(posedge clk) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Darti 0 29 января, 2015 Опубликовано 29 января, 2015 · Жалоба Жестко. Вам надо работать по фронтам клока. Либо спи либо отдельного. А так это слишком все шатко. Ключевое слово Always @(posedge clk) нене весь этот код засунут в Always @(posedge clk), просто там есть еще логика, которая не относится к делу, т.е. я проверяю каждый такт генератора, установленного на плисине 100мгц. К клокам spi никак не могу привязаться, ибо если я выставляю какие то флаги в допустим Always @(posedge s_clk), то их нельзя сбрасывать в так назовем основном цикле Always @(posedge clk). Думаю есть способы обойти это, но гугль ничего не выдает толкового. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Golikov 0 29 января, 2015 Опубликовано 29 января, 2015 · Жалоба Ага. А вы уверены что во всех частях схемы событие s_clk = 0 наступает одновременно? Ответ в общем случае нет. И так може получится что у вас срабатываю оба if Ловите фронт клока Sclk2 <= sclk1 Sclk1 <= sclk If(( sclk2 = 0)&&(sclk1 = 1)) Это будет фронт и будет он 1 раз по нему и сохраняйте данные. А чтобы защититься от метастабильности хорошо бы еще sclk3 <= sclk2 добавить и if делать по 3 и 2 П.с. Простите пишу с планшета и он сам буквы заглавные ставит, бороться сил нет:) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Darti 0 31 января, 2015 Опубликовано 31 января, 2015 · Жалоба Ага. А вы уверены что во всех частях схемы событие s_clk = 0 наступает одновременно? Ответ в общем случае нет. И так може получится что у вас срабатываю оба if Ловите фронт клока Sclk2 <= sclk1 Sclk1 <= sclk If(( sclk2 = 0)&&(sclk1 = 1)) Это будет фронт и будет он 1 раз по нему и сохраняйте данные. А чтобы защититься от метастабильности хорошо бы еще sclk3 <= sclk2 добавить и if делать по 3 и 2 П.с. Простите пишу с планшета и он сам буквы заглавные ставит, бороться сил нет:) Спасибо огромное, сделал по Вашему, с sclk3. Если раньше данные принимались 1 раз из 5 попыток, то сейчас наоборот за 5 раз, 1 не уходят. Попробую еще поковырять Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Golikov 0 31 января, 2015 Опубликовано 31 января, 2015 · Жалоба ну теперь вы можете обобщить полученный опыт на другие сигналы%) У вас же не один клок асинхронный основному клоку Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться