Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: AvalonBus и Modelsim
Форум разработчиков электроники ELECTRONIX.ru > Программируемая логика ПЛИС (FPGA,CPLD, PLD) > Системы на ПЛИС - System on a Programmable Chip (SoPC)
Dima_G
Добрый день!
Изучаю шину авалон, написал тестовый проект из трех мастеров, одновременно доступающихся к одному подчиненному устройству. При помощи вкладки "Generate" в qsys сгенерил тестбенч для модельсима. Прогнал 2 случая:
1. Все мастера имеют одинаковый приоритет доступа к подчиненному устройству (==1). Получил картинку eq.jpeg.
По ней видно, что по событию sec_pulse три мастера начинают одновременно доступаться к шине, арбитр разруливает это путем удерживания сигнала waitrequest.
вопрос: Почему для нулевого мастера тоже получается задержка за счет waitrequest? Если на шине оставить только одного мастера, то waitrequest падает в момент выставления сигнала write_data, если несколько мастеров - то через цикл. В этот цикл разрешается арбитраж на шине?

2. ПРи помощи qsys поставл мастеру_1 приоритет 9 (остальные два имеют приоритет 1). Ожидал, что арбитраж выиграет мастер_1. Однако симуляция показала, что по прежнему первая транзакция идет от мастера_0 (файл neq.jpeg)
вопрос: почему мастер_1 не начинает первым транзакцию?
вопрос: на диаграмме видно, что сигнал waitrequest для мастер_2 продлился еще на один такт (те между окончанием передачи мастер_1 и началом передачи мастер_2 вставился холостой цикл, чего не было на eq.jpeg. С чем это связано?

Если это важно: квартус версии 13.0 (Linux), модельсим 10.1d
Спасибо!

Приложения:
1. Код мастера шины

Код
module mmbus_master
#(
    parameter REVERSE = 0,
    parameter DIGIT_NUM = 0
)
(
    input bit clk, reset_n, waitrequest,
    output bit write,
    output bit[31:0] write_data,
    output bit[3:0] byte_select,
    output bit[31:0] address
);

// pulse every 1 sec
bit[31:0] divider;
bit sec_pulse;
always_ff @(posedge clk) begin
    if (!reset_n)
        divider <= '0;
    else if (divider < 50)
        divider <= divider + 1'b1;
    else
        divider <= '0;
end
assign sec_pulse = divider == 50;

// Increment digit
bit[3:0] digit;
always_ff @(posedge clk) begin
    if (!reset_n)
        digit <= '0;
    else if (sec_pulse) begin
        if (REVERSE) begin
            if (digit == 0) digit <= 9;
            else digit <= digit - 1'b1;
        end
        else begin
            if (digit == 9) digit <= '0;
            else digit <= digit + 1'b1;
        end
    end
end

// Write digit to bus
typedef enum
{
    IDLE,
    WAIT
} EState;

EState eWriteState;
always_ff @(posedge clk) begin
    if (!reset_n)
        eWriteState <= IDLE;
    else begin
        unique case (eWriteState)
            IDLE:    if (sec_pulse) begin
                            address         <= 32'h5044;
                            write_data    <= digit << 8*DIGIT_NUM;
                            write            <= '1;
                            byte_select <= 1'b1 << DIGIT_NUM;
                            eWriteState    <= WAIT;
                    end
            WAIT:    if (!waitrequest) begin
                            address         <= '0;
                            write_data    <= '0;
                            write            <= '0;
                            byte_select <= '0;
                            eWriteState    <= IDLE;
                    end
        endcase
    end
end

endmodule


2. Код подчиненного устройства


Код
function [6:0]bin2seg(input bit [3:0] digit);
    unique case (digit)
        0:    bin2seg = 7'b1000000;
        1:    bin2seg = 7'b1111001;
        2:    bin2seg = 7'b0100100;
        3:    bin2seg = 7'b0110000;
        4:    bin2seg = 7'b0011001;
        5:    bin2seg = 7'b0010010;
        6:    bin2seg = 7'b0000010;
        7:    bin2seg = 7'b1111000;
        8:    bin2seg = 7'b0000000;
        9:    bin2seg = 7'b0010000;
        default: bin2seg = 7'b1111111;
    endcase
endfunction


module seg_driver
(
    input bit clk, reset_n, write, chipselect,
    input bit [3:0] byteselect,
    input bit[31:0] write_data,
    output bit[6:0] seg0, seg1, seg2, seg3
);

bit[31:0] value;

always_ff@(posedge clk) begin
    if (!reset_n)
        value <= '0;
    else if (chipselect && write)
        //value <= write_data;
        if (byteselect[0]) value[7:0] <= write_data[7:0];
        if (byteselect[1]) value[15:8] <= write_data[15:8];
        if (byteselect[2]) value[23:16] <= write_data[23:16];
        if (byteselect[3]) value[31:24] <= write_data[31:24];
end

assign seg0 = bin2seg(value[3:0]);
assign seg1 = bin2seg(value[11:8]);
assign seg2 = bin2seg(value[19:16]);
assign seg3 = bin2seg(value[27:24]);

endmodule
vadimuzzz
В QSys задается не приоритет, а arbitration shares. Т.е. мастер, которому вы дали 9, имеет право на 9 последовательных транзакций. Остальные мастеры ждут своей очереди. Т.е. потенциально в системе 9-1-1 первый мастер может претендовать та 9/11 пропускной способности шины. На очередность этот параметр не влияет никак.
Dima_G
Цитата(vadimuzzz @ Aug 24 2015, 15:38) *
В QSys задается не приоритет, а arbitration shares. Т.е. мастер, которому вы дали 9, имеет право на 9 последовательных транзакций. Остальные мастеры ждут своей очереди. Т.е. потенциально в системе 9-1-1 первый мастер может претендовать та 9/11 пропускной способности шины. На очередность этот параметр не влияет никак.


Согласно документу AN 184: Simultaneous Multi-Mastering with the Avalon Bus (стр. 8)

In a fairness-based arbitration scheme, each master-slave pair has an
integer value of “shares” for bus transfers. If conflicting requests to access
a particular slave occur, the master that has the highest fairness setting is
granted access to the slave.
After the master-slave pair exhausts its share
assignment, control of the slave is granted to the master-slave pairs with
lower share assignments.

Те как я понимаю, в случае если приоритетный мастер не исчерпал лимит транзакций, то право на передачу будет предоставлено именно ему.
vadimuzzz
Цитата(Dima_G @ Aug 24 2015, 15:46) *
Те как я понимаю, в случае если приоритетный мастер не исчерпал лимит транзакций, то право на передачу будет предоставлено именно ему.

только на ваших картинках этого не видно. сделайте не одиночные, а множественные обращения, тогда и должна стать заметной разница

https://www.altera.com/content/dam/altera-w...nterconnect.pdf

стр. 8-14
Dima_G
Цитата(vadimuzzz @ Aug 24 2015, 15:53) *
только на ваших картинках этого не видно.

1. Абсолютно аналогичная картина наблюдается при первой транзакции после сброса.
2. Если я сделаю пачку транзакций, то таким образом я же проверю arb. shares (какой процент пропускной способности будет выделяться каждому мастеру)? А меня вопрос с арбитражем зацепил biggrin.gif , когда шина практически не нагружена, но присутствуют одновременные обращения

vadimuzzz
Цитата
А меня вопрос с арбитражем зацепил biggrin.gif , когда шина практически не нагружена, но присутствуют одновременные обращения

ну, я не вижу смысла упирать именно на очередность. какая разница, пятый мастер или десятый ломится - для шины претендующей на высокую пропускную способность нет трагедии подождать пару тактов.
Dima_G
Цитата(vadimuzzz @ Aug 24 2015, 16:52) *
какая разница, пятый мастер или десятый ломится

Просто заметил расхождение с документацией, подозреваю, что сам где-то совершил ошибку (либо недопонимание шины)


В любом случае, спасибо за участие!
Буду дальше искать проблему
Dima_G
На всякий случай посмотрел работу в реальной системе при помощи SignalTap, картина совпадает с Modelsim
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.