Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Осваиваю Verilog, простейший модуль
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > Программирование
sergeeff
Коллеги!

Пришлось осваивать азы Verilog'a. Простейший модуль. К ARM9 подсоединен FPGA Spartan3. Он должен вырабатывать два положительных импульса чтения/записи в контроллер дисплея. На fpga поступают cs3 от ARM (0x20000000), 16 младших разрядов адреса, системные wr и rd. Модуль сгенерировал, в fpga - записал. Запустил простенький тест: в цикле записываю информацию по адресу 0x20009001 байт данных). Смотрю осциллографом - в fpga проскакивают импульсы на выходе disp_rd, хотя никакого чтения по адресам 0х2000900х не производится. Что неправильно написано в veriloge?

Код
module decoder(adr, n_cs3, n_wr, n_rd, disp_wr, disp_rd);
   input adr[15:0];
   input n_wr;
   input n_rd;

   output disp_wr;
   output disp_rd;

   assign disp_wr = (adr[15:4] == 12b'1001_0000_0000) & ~n_cs3 & ~n_wr;
   assign disp_rd = (adr[15:4] == 12b'1001_0000_0000) & ~n_cs3 & ~n_rd;
endmodule
Джеймс
Так это наверное всё-таки не импульсы, а наносекундные "иголки".
По-хорошему вам нужно "пересаживать" сигналы disp_wr и disp_rd на какую-то частоту, которая есть в FPGA.
sergeeff
Цитата(Джеймс @ May 1 2010, 15:46) *
Так это наверное всё-таки не импульсы, а наносекундные "иголки".
По-хорошему вам нужно "пересаживать" сигналы disp_wr и disp_rd на какую-то частоту, которая есть в FPGA.


В том и дело, что сигналы disp_rd имеют нормальную длительность, определяемую длительностью wr/rd для cs3. То есть ясно, что адресный декодер, таким образом написанный в модуле не работает правильно (не так, как хочется или представляется), но не могу понять в чем эта неправильность.
dxp
Цитата(sergeeff @ May 1 2010, 19:35) *
Смотрю осциллографом - в fpga проскакивают импульсы на выходе disp_rd, хотя никакого чтения по адресам 0х2000900х не производится. Что неправильно написано в veriloge?

Код
module decoder(adr, n_cs3, n_wr, n_rd, disp_wr, disp_rd);
   <...>
   assign disp_wr = (adr[15:4] == 12b'1001_0000_0000) & ~n_cs3 & ~n_wr;
   assign disp_rd = (adr[15:4] == 12b'1001_0000_0000) & ~n_cs3 & ~n_rd;
endmodule

Ваш модуль описывает чисто комбинационную логику. По этой причине сигналы disp_wr и disp_rd содержат "иголки", возникающие из-за гонок при прохождении сигналов через логику. Основным способом борьбы с этим является использование регистров и синхронного дизайна. Ваш модуль должен быть похож на это:
Код
module decoder(clk, reset, adr, n_cs3, n_wr, n_rd, disp_wr, disp_rd);
   <...>
    reg disp_wr;
    reg disp_rd;

    always @(posedge clk) begin
        if(reset) begin
            disp_wr <= 0;
            disp_rd <= 0;
        end
        else begin
            disp_wr <= (adr[15:4] == 12b'1001_0000_0000) & ~n_cs3 & ~n_wr;
            disp_rd <= (adr[15:4] == 12b'1001_0000_0000) & ~n_cs3 & ~n_rd;
        end
    end
endmodule


Т.е. вам нужно еще завести два глобальных системных сигнала - клок и сброс.

В вышеописанном примере правые части выражения будут так же давать на выходе "иголки" при переключении логики, но важно, чтобы "иголок" не было в момент прихода фронта клока. Если по времянкам все укладывается в требования, то все процессы переключения в логике успеют завершиться при приходе клока.

Нужно помнить и учитывать, что такое решение дает задержку. Но еще важнее то, что это далеко не полное решение. Входящие сигналы от процессора (шина и сигналы управления) являются асинхронными по отношению к внутреннему клоку ПЛИС, поэтому прямо вот так это использовать нельзя - будут глюки из-за метастабильности. Все эти сигналы (сигналы управления в обязательном порядке) необходимо пропустить через синхронизаторы. Это еще даст задержку, что тоже нужно учитвать. smile.gif Простейшая реализация синхронизатора - цепочка из двух последовательно соединенных триггеров.
Джеймс
Цитата(sergeeff @ May 1 2010, 16:35) *
Смотрю осциллографом - в fpga проскакивают импульсы на выходе disp_rd, хотя никакого чтения по адресам 0х2000900х не производится.


Хорошо, тогда смотрите осциллографом стык ARM -> FPGA. Конкретно, n_cs3 и n_rd (двумя лучами). Есть чтение или нет? Может бага в софте. Или чтение идет в другой ветке алгоритма (опять же софт..)
sergeeff
Цитата(dxp @ May 1 2010, 16:16) *
Входящие сигналы от процессора (шина и сигналы управления) являются асинхронными по отношению к внутреннему клоку ПЛИС, поэтому прямо вот так это использовать нельзя - будут глюки из-за метастабильности.


Мы это предполагали и в качестве clk fpga используем сlock процессора деленный на 4. Или это все равно не есть хорошо?
dxp
Цитата(sergeeff @ May 1 2010, 20:56) *
Мы это предполагали и в качестве clk fpga используем сlock процессора деленный на 4. Или это все равно не есть хорошо?

Системный клок ПЛИС должен быть по частоте больше (в несколько раз, минимум вдвое), чем сигналы, которые он тактирует. В современных ПЛИС есть средства для генерации внутренних клоков на основе опорных внешних - например, в ПЛИС Altera это PLL. У Xilinx я не очень в курсе в нюансах, но тоже есть специальные аппаратные средства - DCM, DLL. Нужно подать снаружи клок (хоть от проца) и внутри умножить/поделить его до нужной величины. И все внешние асинхронные сигналы пропустить через синхронизаторы:
Код
...
reg [1:0] nCS;

always @(posedge clk) begin
    if(reset) nCS <= 2'b11;
    else begin
        nCS[0] <= n_cs3;
        nCS[1] <= nCS[0];
    end
end

Сигнал nCS[1] и является "правильным", засинхронизированным, который можно безопасно использовать.
sergeeff
Спасибо за советы, в понедельник попробую.

Всех с праздником и хорошей погоды.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.