MaratZuev 0 10 мая, 2018 Опубликовано 10 мая, 2018 · Жалоба Проект Во вложении. entity - test3.qpf Собирал в Quartus II 9.1, использовал для теста встроенный симулятор (файл test3.vwf) Ну, функциональное моделирование у Вас проходит безошибочно? Если так, то ломающееся временное свидетельствует об асинхронщине (а она есть у Вас в модуле spi_slave), либо.. Не хотите для начала именно с асинхронщиной побороться, чтобы на примере этого проекта навсегда забыть о ней? На всякий случай рекомендую и на метастабильность обратить внимание... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Jackov 1 10 мая, 2018 Опубликовано 10 мая, 2018 (изменено) · Жалоба to Sprite Посмотрел я на времянку и мозг отказал минут на 5 - как машина может находиться одновременно в нескольких состояниях? Там вообще мусор должен быть на моделировании - начальное состояние не определено - либо сброс добавьте, либо начальное условие при инициализации. Или это картинка не моделирования, а сигнал тап? Квартусовский симулятор сам инициализирует все триггеры нулями, ибо разработчики ПЛИС гарантируют, что по концу конфигурирования все триггеры в ПЛИС будут сброшены. Я всё ищу такую опцию для ModelSim-а, а то запарился каждый раз сброс прописывать. Изменено 10 мая, 2018 пользователем Jackov Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
MaratZuev 0 10 мая, 2018 Опубликовано 10 мая, 2018 (изменено) · Жалоба Квартусовский симулятор сам инициализирует все триггеры нулями, ибо разработчики ПЛИС гарантируют, что по концу конфигурирования все триггеры в ПЛИС будут сброшены. Привязка в таких вопросах к одному производителю и его ПО не есть достойное решение. Я всё ищу такую опцию для ModelSim-а, а то запарился каждый раз сброс прописывать. Может, signal_force вас спасёт? Но, по-хорошему, все триггеры, включая FSM в проекте рекомендуется заводить со сбросами (вот какой лучше: синхронизированный асинхронный или синхронный - каждый выбирает по себе ))) Изменено 10 мая, 2018 пользователем Marat Zuev Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Jackov 1 10 мая, 2018 Опубликовано 10 мая, 2018 · Жалоба Может, signal_force вас спасёт? Примерно так и делаю. Но всё равно ведь ручками приходится. Хотелось бы чтобы он сам по умолчанке делал. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
MaratZuev 0 10 мая, 2018 Опубликовано 10 мая, 2018 · Жалоба Примерно так и делаю. Но всё равно ведь ручками приходится. Хотелось бы чтобы он сам по умолчанке делал. Вот вы снова привязываетесь к инструменту. Комильфо проект (включая testbench) - инструментонезависимый. Пишите так, чтобы и реализация и моделирование проходили бы одинаково и в Modelsime и в Active-HDL-е и где бы то ни было.... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
alex1985 0 11 мая, 2018 Опубликовано 11 мая, 2018 · Жалоба Ну, функциональное моделирование у Вас проходит безошибочно? Если так, то ломающееся временное свидетельствует об асинхронщине (а она есть у Вас в модуле spi_slave), либо.. Не хотите для начала именно с асинхронщиной побороться, чтобы на примере этого проекта навсегда забыть о ней? На всякий случай рекомендую и на метастабильность обратить внимание... Спасибо за дельный совет! Действительно, данные (регистр data_in[15:0]) поступавшие в модуль были несинхронизированы, поправил. По совету iosifk поставил ветку default в state-машину. Но ошибка в модуле по прежнему имеется, в железе data_out после 10-15 раза выдает неверные данные, разбираюсь дальше. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
MaratZuev 0 11 мая, 2018 Опубликовано 11 мая, 2018 · Жалоба Но ошибка в модуле по прежнему имеется, в железе data_out после 10-15 раза выдает неверные данные, разбираюсь дальше. Пришлите "синхронизированный" модуль посмотреть. Ошибка на временном моделировании так и осталась? Кстати, а Вы умеете SignalTap-ом пользоваться? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Flip-fl0p 4 11 мая, 2018 Опубликовано 11 мая, 2018 · Жалоба Зачем вообще проводить временную симуляцию ? Это потраченное впустую уйма времени ! Проводите в Modelsim функциональное моделирование. Когда HDL описание работает как задумано, то описываете временные ограничения. И практически наверняка проект заработает сразу. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
alex1985 0 11 мая, 2018 Опубликовано 11 мая, 2018 (изменено) · Жалоба Пришлите "синхронизированный" модуль посмотреть. Ошибка на временном моделировании так и осталась? Кстати, а Вы умеете SignalTap-ом пользоваться? Моделировал в стандартном квартусовском симуляторе - ошибок нет, но при работе с железом ошибка присутствует: для этого специально поставил 2 компаратора на вход data_in и 2 компаратора на выход data_out, а сигналы с компараторов вывел на светодиоды платы. На входе данные всегда правильные, а выход после N передач выдает либо фиксированные данные, либо 0. SignalTap-ом пользоваться не умею. module spi_slave ( input CLK, input CS, input MOSI, input SCK, input [15:0] DATA_IN, output reg MISO, output reg [15:0] DATA_OUT ); reg [15:0] data_receive_reg; reg [15:0] data_send_reg; reg [3:0] bit_counter; reg miso_reg; //============================ // По спаду CS заносим данные в // data_send_reg //============================ always @(negedge CS) begin data_send_reg <= DATA_IN; end //============================ // Если CS=1 - обнуляем bitcounter // По фронту SCK заносим данные // в регистр data_receive_reg //============================ always @(negedge SCK, posedge CS) if (CS) bit_counter <= 4'b0000; else begin data_receive_reg[15-bit_counter] <= MOSI; bit_counter <= bit_counter + 4'b0001; end //============================ // Если CS=1 - обнуляем MISO // По фронту SCK выводим данные //============================ always @(posedge SCK, posedge CS) if (CS) miso_reg <= 1'b0; else miso_reg <= data_send_reg[15-bit_counter]; //============================ // Синхронизация данных //============================ always @(posedge CLK) begin DATA_OUT = data_receive_reg; MISO = miso_reg; end //============================ endmodule Изменено 11 мая, 2018 пользователем Sprite Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Flip-fl0p 4 11 мая, 2018 Опубликовано 11 мая, 2018 · Жалоба Жуть ! 1. Фильтруйте входные внешние асинхронные сигналы от пологих фронтов, и возможного дребезга около фронтов. 2. Работайте только про одному фронту синхросигнала. Хотите выделить фронт сигнала - применяйте схемы детектора фронтов(гуглится легко). Так как сделано у Вас - в FPGA не делается. 3. always @(negedge SCK, posedge CS) if (CS) bit_counter <= 4'b0000; else begin data_receive_reg[15-bit_counter] <= MOSI; bit_counter <= bit_counter + 4'b0001; end Так конечно можно. Но правильнее и красивее в сдвиговый регистр данные записывать. Записали и сдвинули. Приняли все биты - отдали данные в модуль, обрабатывающий слова. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
MaratZuev 0 11 мая, 2018 Опубликовано 11 мая, 2018 · Жалоба Моделировал в стандартном квартусовском симуляторе - ошибок нет, но при работе с железом ошибка присутствует: для этого специально поставил 2 компаратора на вход data_in и 2 компаратора на выход data_out, а сигналы с компараторов вывел на светодиоды платы. На входе данные всегда правильные, а выход после N передач выдает либо фиксированные данные, либо 0. Значит, модель Ваша не совпадает с действительностью. И уж если взялись, то возьмите осциллограф. Раз интерфейс отлаживаете - смотрите его на экране осциллоскопа, а не на мигании светодиодов. SignalTap-ом пользоваться не умею. А вот это освойте: и сейчас пригодится, и в будущем. Начинать, например, можно отсюда. И скрипт Вы, конечно, "синхронизировали" сильно. Сделайте так, как сказал Flip-fl0p. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
alex1985 0 12 мая, 2018 Опубликовано 12 мая, 2018 · Жалоба Жуть ! 1. Фильтруйте входные внешние асинхронные сигналы от пологих фронтов, и возможного дребезга около фронтов. 2. Работайте только про одному фронту синхросигнала. Хотите выделить фронт сигнала - применяйте схемы детектора фронтов(гуглится легко). Так как сделано у Вас - в FPGA не делается. 3. Но правильнее и красивее в сдвиговый регистр данные записывать. Записали и сдвинули. Приняли все биты - отдали данные в модуль, обрабатывающий слова. Ошибку исправил, засинхронизировал сигнал CS, переписал модуль SPI как советовал Flip-fl0p. В железе все работает, но при компиляции куча варнингов, типа: Warning: Presettable and clearable registers converted to equivalent circuits with latches. Registers power-up to an undefined state, and DEVCLRn places the registers in an undefined state. Warning (13310): Register "SPIslave:inst16|data_in_reg[15]" is converted into an equivalent circuit using register "SPIslave:inst16|data_in_reg[15]~_emulated" and latch "SPIslave:inst16|data_in_reg[15]~latch" Warning (13310): Register "SPIslave:inst16|data_in_reg[14]" is converted into an equivalent circuit using register "SPIslave:inst16|data_in_reg[14]~_emulated" and latch "SPIslave:inst16|data_in_reg[14]~latch" Warning (13310): Register "SPIslave:inst16|data_in_reg[13]" is converted into an equivalent circuit using register "SPIslave:inst16|data_in_reg[13]~_emulated" and latch "SPIslave:inst16|data_in_reg[13]~latch" Warning (13310): Register "SPIslave:inst16|data_in_reg[12]" is converted into an equivalent circuit using register "SPIslave:inst16|data_in_reg[12]~_emulated" and latch "SPIslave:inst16|data_in_reg[12]~latch" Warning (13310): Register "SPIslave:inst16|data_in_reg[11]" is converted into an equivalent circuit using register "SPIslave:inst16|data_in_reg[11]~_emulated" and latch "SPIslave:inst16|data_in_reg[11]~latch" Warning (13310): Register "SPIslave:inst16|data_in_reg[10]" is converted into an equivalent circuit using register "SPIslave:inst16|data_in_reg[10]~_emulated" and latch "SPIslave:inst16|data_in_reg[10]~latch" Warning (13310): Register "SPIslave:inst16|data_in_reg[9]" is converted into an equivalent circuit using register "SPIslave:inst16|data_in_reg[9]~_emulated" and latch "SPIslave:inst16|data_in_reg[9]~latch" Warning (13310): Register "SPIslave:inst16|data_in_reg[8]" is converted into an equivalent circuit using register "SPIslave:inst16|data_in_reg[8]~_emulated" and latch "SPIslave:inst16|data_in_reg[8]~latch" Warning (13310): Register "SPIslave:inst16|data_in_reg[7]" is converted into an equivalent circuit using register "SPIslave:inst16|data_in_reg[7]~_emulated" and latch "SPIslave:inst16|data_in_reg[7]~latch" Warning (13310): Register "SPIslave:inst16|data_in_reg[6]" is converted into an equivalent circuit using register "SPIslave:inst16|data_in_reg[6]~_emulated" and latch "SPIslave:inst16|data_in_reg[6]~latch" Warning (13310): Register "SPIslave:inst16|data_in_reg[5]" is converted into an equivalent circuit using register "SPIslave:inst16|data_in_reg[5]~_emulated" and latch "SPIslave:inst16|data_in_reg[5]~latch" Warning (13310): Register "SPIslave:inst16|data_in_reg[4]" is converted into an equivalent circuit using register "SPIslave:inst16|data_in_reg[4]~_emulated" and latch "SPIslave:inst16|data_in_reg[4]~latch" Warning (13310): Register "SPIslave:inst16|data_in_reg[3]" is converted into an equivalent circuit using register "SPIslave:inst16|data_in_reg[3]~_emulated" and latch "SPIslave:inst16|data_in_reg[3]~latch" Warning (13310): Register "SPIslave:inst16|data_in_reg[2]" is converted into an equivalent circuit using register "SPIslave:inst16|data_in_reg[2]~_emulated" and latch "SPIslave:inst16|data_in_reg[2]~latch" Warning (13310): Register "SPIslave:inst16|data_in_reg[1]" is converted into an equivalent circuit using register "SPIslave:inst16|data_in_reg[1]~_emulated" and latch "SPIslave:inst16|data_in_reg[1]~latch" Warning (13310): Register "SPIslave:inst16|data_in_reg[0]" is converted into an equivalent circuit using register "SPIslave:inst16|data_in_reg[0]~_emulated" and latch "SPIslave:inst16|data_in_reg[0]~latch" Warning: Timing Analysis is analyzing one or more combinational loops as latches Warning: Node "inst16|data_in_reg[15]~latch|combout" is a latch Warning: Node "inst16|data_in_reg[14]~latch|combout" is a latch Warning: Node "inst16|data_in_reg[13]~latch|combout" is a latch Warning: Node "inst16|data_in_reg[12]~latch|combout" is a latch Warning: Node "inst16|data_in_reg[11]~latch|combout" is a latch Warning: Node "inst16|data_in_reg[10]~latch|combout" is a latch Warning: Node "inst16|data_in_reg[9]~latch|combout" is a latch Warning: Node "inst16|data_in_reg[8]~latch|combout" is a latch Warning: Node "inst16|data_in_reg[7]~latch|combout" is a latch Warning: Node "inst16|data_in_reg[6]~latch|combout" is a latch Warning: Node "inst16|data_in_reg[5]~latch|combout" is a latch Warning: Node "inst16|data_in_reg[4]~latch|combout" is a latch Warning: Node "inst16|data_in_reg[3]~latch|combout" is a latch Warning: Node "inst16|data_in_reg[2]~latch|combout" is a latch Warning: Node "inst16|data_in_reg[1]~latch|combout" is a latch Warning: Node "inst16|data_in_reg[0]~latch|combout" is a latch Новый код ниже, не судите строго - только учусь) module SPIslave( input clk, input CS, input MOSI, input SCK, input [15:0] data_in, output reg MISO, output reg [15:0] data_out, output reg data_ready ); reg [15:0] data_receive; reg [15:0] data_in_reg; reg [4:0] bit_counter; reg fall_CS_reg; wire fall_CS; //---------------------------------------- // По спаду SCK принимаем данные //---------------------------------------- always @ (negedge SCK, posedge CS) if (CS) bit_counter <= 5'b00000; else begin data_receive <= { data_receive[14:0], MOSI }; bit_counter <= bit_counter + 5'b00001; end //---------------------------------------- // Выделяем спад CS //---------------------------------------- always @(posedge clk) fall_CS_reg <= CS; assign fall_CS = fall_CS_reg & ~CS; //---------------------------------------- // По фронту CS заносим данные в data_in_reg // По фронту SCK сдвигаем данные //---------------------------------------- always @ (posedge SCK, posedge fall_CS) begin if (fall_CS) data_in_reg <= data_in; else begin MISO <= data_in_reg[15]; data_in_reg <= (data_in_reg << 1); end end //---------------------------------------- // По переполнению счетчика выводим данные и сигнал готовности //---------------------------------------- always @ (posedge clk) begin if (bit_counter[4]) begin data_out <= data_receive; data_ready <= 1'b1; end else begin data_out <= data_out; data_ready <= 1'b0; end end endmodule Кстати, RTL-схема получилась довольно интересная: Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
andrew_b 17 12 мая, 2018 Опубликовано 12 мая, 2018 · Жалоба У вас тут большие проблемы с CDC (clock domain crossing). Точнее, его просто нет. Вы формируете fall_CS_reg по clk, а используете для SCK. Так делать нельзя. Что там с латчами, сказать не берусь. Вроде криминала не вижу, но я Верилог воспринимаю плохо. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AnatolySh 0 12 мая, 2018 Опубликовано 12 мая, 2018 · Жалоба переписал модуль SPI как советовал Flip-fl0p. Flip-fl0p советовал работать только от одного клока: у Вас это, как понимаю, clk. И в списке чувствительности, помимо него, имеет право быть (для проекта комильфо) только, если, конечно, он Вам нужен, ещё асинхронный глобальный сброс. А у Вас в этих списках зоопарк. Кстати, боюсь предложить Вам ещё включить (если я правильно помню называние) Design Assistant ))) И пока перестаньте нас радовать Вашим RTL: давайте сначала код вылизывать. Лучше выкладывайте экран функционального моделирования для этого модуля. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
iosifk 3 12 мая, 2018 Опубликовано 12 мая, 2018 · Жалоба Ошибку исправил, засинхронизировал сигнал CS, переписал модуль SPI как советовал Flip-fl0p. В железе все работает, но при компиляции куча варнингов, типа: Кстати, RTL-схема получилась довольно интересная: Давайте с конца начнем... Какой может быть интерес к "RTL-схема", если она потом оптимизируется и от нее мало что останется? Ваш стиль кодирования "все в одном" приведет к мало-отлаженному проекту. Который будет трудно сопровождать... На самом деле, все это гораздо проще ложится в набор автоматов: нижний, который умеет только работать с битом, средний, который умеет только передать-принять кадр, управляя при этом нижним, верхний, который работает с сигналами типа CS и запускает средний на выполнение. При этом, нижний может еще и фильтровать клоки и данные, если они приходят из SPI, а верхний может синхронизировать и фильтровать сигналы типа CS... И когда к этому придете, то станет понятно, что "есть только один клок в проекте и сигнал разрешения - пророк его"... А попутно сделаете привязку асинхронных сигналов.. Потом сделайте еще параметры, в которых бы задавалось число клоков на один бит SPI отдельно для симуляции и отдельно для железа...Скажем, если для железа надо 100 клоков на бит, то дляя симуляции и 4-х хватит... Тогда симуляция будет делаться быстро.. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться