Доброго дня !
По воле случая, начал терзать FPGA, пытаюсь писать на Verilog-е. Язык для меня новый и не совсем понятный, посему возникли некоторые нубские вопросы. Прошу сообщество помочь
Пытаюсь наваять контроллер SDRAM (плата Марсоход-2).
Правильно ли я понимаю, что то что описано в блоке always/initial выполняется последовательно (т.е. сверху вниз) ? Правомерен ли такой код (ниже)? В нем действия будут выполняются последовательно, так ?
//Начальные установки сразу после включения питания, по первому позитивному фронту тактового сигнала
initial @(posedge clock_in)
begin
sdram_ready <= 1'b0;
sdram_CKE <= 1'b0; //П. 3
sdram_address <= 16'h0000;
sdram_data_out <= 16'h0000;
sdram_comand <= COMMAND_INHIBIT; //Подаем команду NOP на время инициализации
sdram_IOmask <= WRITEOUTPUT_DIS;
//sdram_initial_s0 = 1'b1; //Начинаем первый этам инициализации
AUC_Reset <= 1'b1; //Запрещаем работу счетчика периода подачи ком. AUTO_REFRESH
->ePOWERON_INIT;
end
//Выдерживаем паузу перед подачей тактовых импульсов на SDRAM
initial @ePOWERON_INIT
begin
//repeat ((INITIAL_TIME * FREQUENCY) / 2) //Задержка перед разрешением тактирования
repeat (INITIAL_TIME / 2)
@(posedge clock_in); //
begin
sdram_CKE = 1'b1; //Разрешаем тактирование SDRAM (п. 5)
end
repeat (INITIAL_TIME / 2) //Выдерживаем оставшееся время
@(posedge clock_in);
begin
->eINIT_PRECHARGE; //Выполняем ком. PRECHARGE для всех банков
end
end
//Выполняем ком. PRECHARGE для всех банков
initial @eINIT_PRECHARGE
begin
@(negedge clock_in) begin
sdram_bankaddress = 2'b00;
sdram_address[10] = 1'b1; //Деактивировать все банки
sdram_comand = PRECHARGE; //Команда дективации
end
@(negedge clock_in) begin
sdram_comand = NO_OPERATION; //Применяем ком. NO_OPERATION и ждем время tRP
end
repeat ((TIME_RP / 10)) //Пауза на время tRP
@(posedge clock_in);
begin
->eINIT_AUTOREFRESH; //Выполнение ком. AUTO_REFRESH
end
end
Нет. initial может синтезироваться, а может - нет. Это зависит от конкретного производителя. Темболее конструкцию initial @ я в первые вижу И все присваивания выполняются одновременно, а не последовательно.
initial@ -- встречал в какой-то книжке... Хотя, подозреваю, это может относится только к симуляции...
Тогда встречный вопрос Каким образом можно реализовать действие, которое выполняется по условию и единожды ? Юзать флаги выполнения ? С initial все выглядит как-то изящней
По поводу присваивания -- я думал, это относится только к неблокирующим присваиваниям: test <= 1'b0
И ещё Вот этот участок кода будет выполнятся последовательно ?
@(negedge clock_in) begin
sdram_bankaddress = 2'b00;
sdram_address[10] = 1'b1; //Деактивировать все банки
sdram_comand = PRECHARGE; //Команда дективации
end
@(negedge clock_in) begin
sdram_comand = NO_OPERATION; //Применяем ком. NO_OPERATION и ждем время tRP
end
repeat ((TIME_RP / 10)) //Пауза на время tRP
@(posedge clock_in);
То бишь, по первому заднему фронту делаем присваивания, ждем второго заднего фронта, делаем следующее присваивание и дальше ждем N передних фронтов (формирование задержки).
К примеру, у xilinx initial синтезируется. Но срабатывает не по условию а только по ресету.
Вот этот участок кода будет выполнятся последовательно ?
Последовательно будет выполняться, но только в симуляции. Такое не синтезируется. Для того, чтобы заставить в железе что-то выполняться последовательно, нужно делать машину состояний.
+1 к машине состояний. Забудьте все алгоритмические методы, когда начинаете работать с ПЛИС. Все решения в результате должны иметь схемный аналог, выполненный из логических элементов. Как вариант использовать ядро микоконтроллера и на нем использовать уже алгоритмические языки.