Перейти к содержанию

мультиплексор шины в SV

Здравствуйте,
Прошу помочь:
Правильно ли утверждение: если создать одну шину данных,направленную в сторону мастера, и адресную шину, далее соединить шину данных слейвов с мастером напрямую (без применения явного описания мультиплексора по адресам), то компилятор сам формирует мультиплексор?

допустим:
создаем модуль мастера, перебирающий адреса,создаем слейв, комбинационной логикой мультиплексируем по адресу выходную шину, но если реализовывать слейв следующими способами результаты получаются разными:

реализация слейва через интерфейс:
1.мультиплексирование данных по адресу:
modelsim - ошибка
Цитата
driven in a combinatorial block, may not be driven by any other process.

quartus - полная компиляция выполненяется
2.с отдельным процессом мультиплексирования шины по адресу внутри слейва:
modelsim - ошибка
Цитата
driven in a combinatorial block, may not be driven by any other process.

quartus - полная компиляция выполненяется


реализация слева без интерфейса - портами:
1.мультиплексирование данных по адресу:
modelsim - моделирование выполняется с ошибкой передачи шины по одному адресу из четырех
[attachment=110207:without_...rect_mux.png]
quartus - полная компиляция выполненяется
2.с отдельным процессом мультиплексирования шины по адресу внутри слейва:
modelsim - моделирование выполняется без ошибок
quartus - полная компиляция выполненяется



С чем связаны различные варианты результатов?
Как правильно реализовать чтение из множества ведомых модулей по адресу?
Код
`timescale 1ns / 1ps

`define COMB;//COMB or REG

module tb();
    //===========================================/
    //GEN
    //===========================================/
    logic clk = 'b0;
    logic [31:0] data;
    always #10 clk <= ~clk;
    multi_slave multi_slave_inst(
        .*
        );
endmodule


module multi_slave
        (
        input logic clk,
        output logic [31:0] data
        );
    logic [31:0] readdata;
    logic [7:0] addr;
    
            
    master master_inst(
        .*
        );

    slave_1 slave_1_inst(
        .*
        );
    slave_2 slave_2_inst(
        .*
        );
    


endmodule

module master
        (
        input logic [31:0] readdata,
        input logic clk,
        output logic [7:0] addr,
        output logic [31:0] data
        );
    enum int unsigned {
        ONE,
        TWO,
        THREE,
        FOUR
        } st;
    logic delay = 'b0;
    always_ff@(posedge clk)
        begin
        case (st)
            ONE:
                begin
                addr <= 1;
                st <= TWO;
                end
            TWO:
                begin
                addr <= 2;
                st <= THREE;
                end
            THREE:
                begin
                addr <= 3;
                st <= FOUR;
                end
            FOUR:
                begin
                addr <= 4;
                st <= ONE;
                end                
            default:
                begin
                st <= ONE;
                delay <= 1'b0;
                addr <= 1;
                end
            endcase
        end
        
    logic [64:0] sreg = 'b0;
    
    always_ff@(posedge clk) sreg <= {sreg[31:0],readdata};
    assign data[31:0] = sreg[63:32];
endmodule
/*****************COMB*******************/
`ifdef COMB
module slave_1
        (
        input logic clk,
        input logic [7:0] addr,
        output logic [31:0] readdata
        );
    logic [31:0] readdata_s1;
    always_comb
        begin
        case(addr)
            8'd1: readdata = readdata_s1;
            8'd2: readdata = readdata_s1;
            default: readdata = 'bZ;
            endcase
        end
    always_comb
        begin
        case(addr)
            8'd1: readdata_s1 = "S1_1";
            8'd2: readdata_s1 = "S1_2";
             default: readdata_s1 = 'bZ;
            endcase
        end
endmodule

module slave_2
        (
        input logic clk,
        input logic [7:0] addr,
        output logic [31:0] readdata
        );
    logic [31:0] readdata_s2;
    always_comb
        begin
        case(addr)
            8'd3: readdata = readdata_s2;
            8'd4: readdata = readdata_s2;
             default: readdata = 'bZ;
            endcase
        end
    always_comb
        begin
        case(addr)
            8'd3: readdata_s2 = "S2_3";
            8'd4: readdata_s2 = "S2_4";
             default: readdata_s2 = 'bZ;
            endcase
        end
endmodule


Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
'z'-состояние везде настоятельно рекомендуют использовать только для внешних ног, к которым подключены двунаправленные буферы. Внутри же самой ПЛИС никаких z-состояний быть не может.
Если совсем не заморачиваться, то можно вместо 'z' выставить все '0', а на вход мастера подавать результат ОРа всех шин. Другой вариант - описать мультиплексор самому.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
Моделсим более строго, чем компиляторы, соблюдает стандарт Верилога.
Поэтому некорректные, но понятные сердцем конструкции могут нормально компилироваться и работать в железе, но симулироваться неправильно.

В Вашем случае, да и во всех других, нужно не лениться описать поведение блоков подробно, не оставляя детали на откуп понимания симулятора/компилятора.
Убережете себя от многих внезапных открытий.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Для публикации сообщений создайте учётную запись или авторизуйтесь

Вы должны быть пользователем, чтобы оставить комментарий

Создать учетную запись

Зарегистрируйте новую учётную запись в нашем сообществе. Это очень просто!

Регистрация нового пользователя

Войти

Уже есть аккаунт? Войти в систему.

Войти
Авторизация