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

    

Не получается синтезировать мультиплексор шин

Понадобилось создать мультиплексор шин 4 в 1.

Тут взял пример:

http://www.dsol.ru/stud/STESHENKO/glava3/34.htm

module multiplexor4_1 (out, in1, in2, in3, in4, cntrl1, cntrl2);

output out;

input in1, in2, in3, in4, cntrl1, cntrl2;

 

assign out = cntrl1 ? (cntrl2 ? in4 : in3) : (cntrl2 ? in2 : in1);

 

endmodule

 

Gо примеру написал свой:

input [7:0] external_porog,

input [DATA_WIDTH-1:0] porog_simple,

input [DATA_WIDTH-1:0] porog_range,

output [DATA_WIDTH-1:0] selected_porog,

 

// мультиплексор порога

always @(mode_simple or mode_manual or mode_range)

begin

assign selected_porog = mode_simple ? porog_simple : mode_manual ? {1'b0,external_porog,1'b0}: mode_range?porog_range:{DATA_WIDTH{1'b1}};

end

 

Получил ошибку при симуляции ModelSim

# ** Error: delay_17_string.v(104): LHS in procedural continuous assignment may not be a net: selected_porog.

 

И при синтезе

ERROR:HDLCompiler:1660 - "E:\Halt\maisb_s6\hdl\low_level\threshold\delay_17_string.v" Line 104: Procedural assignment to a non-register selected_porog is not permitted, left-hand side should be reg/integer/time/genvar

 

Никаких препятствий синтезировать мультиплексор без регистров не вижу :-(

 

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


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

Приветствую!

 

Поработаю капитаном ...

 

Если хотите assign то зачем оборачиваете это в always ? :cranky:

 

Удачи! Rob.

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


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

 

Поработаю капитаном ...

 

Если хотите assign то зачем оборачиваете это в always ? :cranky:

 

Удачи! Rob.

 

Без always работает.

6 лет пишу в основнов синхронные проекты, совсем азбуку забыл ;-)

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


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

6 лет пишу в основнов синхронные проекты, совсем азбуку забыл ;-)

 

При использовании assign проект не становится асинхронным.

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


Ссылка на сообщение
Поделиться на другие сайты
Понадобилось создать мультиплексор шин 4 в 1.

Тут взял пример:

http://www.dsol.ru/stud/STESHENKO/glava3/34.htm

 

 

Gо примеру написал свой:

 

 

Получил ошибку при симуляции ModelSim

# ** Error: delay_17_string.v(104): LHS in procedural continuous assignment may not be a net: selected_porog.

 

И при синтезе

ERROR:HDLCompiler:1660 - "E:\Halt\maisb_s6\hdl\low_level\threshold\delay_17_string.v" Line 104: Procedural assignment to a non-register selected_porog is not permitted, left-hand side should be reg/integer/time/genvar

 

Никаких препятствий синтезировать мультиплексор без регистров не вижу :-(

 

День добрый! Сверху все верно написали) Либо assign, либо always - одно с другим не смешивается.

 

Хотелось вставить пять копеек по поводу написания. Вообще не понимаю такие "однострочные" конструкции. Конечно, дело привычки, но

 

assign selected_porog = mode_simple ? porog_simple : mode_manual ? {1'b0,external_porog,1'b0}: mode_range?porog_range:{DATA_WIDTH{1'b1}};

 

строка такого вида заставляет капать кровь из глаз...

 

Я бы сделал подобным образом:

 

always_comb begin
  if (mode_simple)           selected_porog = porog_simple;
  else if (mode_manual)      selected_porog = {1'b0,external_porog,1'b0};
     else if (mode_range)    selected_porog = porog_range;
        else                 selected_porog = '1;
end

 

Ну или как-то разложил на несколько строк вашу строку. Или добавил бы кучу скобочек, как минимум B)

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


Ссылка на сообщение
Поделиться на другие сайты
always_comb begin
  if (mode_simple)           selected_porog = porog_simple;
  else if (mode_manual)      selected_porog = {1'b0,external_porog,1'b0};
     else if (mode_range)    selected_porog = porog_range;
        else                 selected_porog = '1;
end

Позанудствую немного.

В ряде стандартов и рекомендаций говориться, что для описания комбинаторики не стоит использовать if else конструкцию,

либо case, либо через ?. Аргумент такой, что можно получить различный результат моделирования RTL описания и netlist.

Сам, ей Богу, ни разу с таким не сталкивался, но не просто также это рекомендуют...

 

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


Ссылка на сообщение
Поделиться на другие сайты
но не просто также это рекомендуют...

рекомендация связана с опасностью генерации latch при некорректном описании сложной структуры в if, т.к. очень просто "потерять" где-то деблокирующий else.

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


Ссылка на сообщение
Поделиться на другие сайты
рекомендация связана с опасностью генерации latch при некорректном описании сложной структуры в if, т.к. очень просто "потерять" где-то деблокирующий else.

Да. И это легко обходится путём присвоения значения по умолчанию до if. Поэтому, имхо, if...else или case ... - скорее дело вкуса и удобочитаемости.

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


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

Напомню что конструкцию case можно синтезнуть как full parallel и тогда это уже становиться не делом вкуса. Ровно также можно не написать дефолт в кейзе и прийти к тому же лачу.

Просто вопрос читаемости...

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


Ссылка на сообщение
Поделиться на другие сайты
Да. И это легко обходится путём присвоения значения по умолчанию до if. Поэтому, имхо, if...else или case ... - скорее дело вкуса и удобочитаемости.

В формате языка Verilog 1364_2001 тоже? ;)

 

Ровно также можно не написать дефолт в кейзе и прийти к тому же лачу.

Был вопрос с чем связаны рекомендации, ответ для стандартов языка 1995 && 2001 очевиден.

 

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


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

Вот пример, где неправильное использование if else может добавить

головной боли не только по причине синтезирования latch'ей.

 

Имеем кода №1.

module test (
    input  wire i1,
    input  wire i2,
    output reg  o1,
    output wire o2);

always @ (i1 or i2) 
  case ({i1, i2}) 
    2'b10:       o1 = 1'b0; 
    2'b11:       o1 = 1'b1; 
    default:     o1 = 1'b0; 
  endcase 

assign o2 = (i2 || o1) ? 1'b0 : i2;

endmodule

Имеем кода №2.

module test (
    input  wire i1,
    input  wire i2,
    output reg  o1,
    output reg o2);

always @ (i1 or i2) 
  case ({i1, i2}) 
    2'b10:       o1 = 1'b0; 
    2'b11:       o1 = 1'b1; 
    default:     o1 = 1'b0;
  endcase 

always @ (i2 or o1) 
   if (o1) o2 = 1'b0; 
   else    o2 = i2; 

endmodule

Ну и тест к нему простой

module tb_top;

    reg i1,i2;
    wire o1,o2;

    //-----------------------------------------------------------------------------------
    // DUT
    //-----------------------------------------------------------------------------------
  
    test 
    u_test ( 
                    .i1    ( i1 ), 
                    .i2    ( i2 ),
                    .o1    ( o1 ),
                    .o2    ( o2 )
                );

    //-----------------------------------------------------------------------------------
    // Run test
    //-----------------------------------------------------------------------------------
  
    initial begin
        #10ns;
        i1 = 0;
        i2 = 0;
        #10ns;
        i1 = 0;
        i2 = 1;
        #10ns;
        i1 = 1;
        i2 = 0;
        #10ns;
        i1 = 1;
        i2 = 1;
        #10ns;
    end

endmodule

 

Если промоделировать два варианта, а потом сравнить с результатом моделирования netlist (он в обоих случаях одинаковый).

Мы увидим, что для кода №2 результат моделирования RTL и netlist отличается, при i1 = 0; i2 = 1; выход о2 ошибочно в лог.1.

 

 

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


Ссылка на сообщение
Поделиться на другие сайты
Был вопрос с чем связаны рекомендации, ответ для стандартов языка 1995 && 2001 очевиден.

Не понял что в контексте обсуждения с этими стандартами не так?

 

 

Вот пример, где неправильное использование if else может добавить

головной боли не только по причине синтезирования latch'ей.

 

не ну это не честно: в первом случае if(i2 || o1), а во втором if(o1).

тут больше проблем из-за ошибки в списке чувствительности может быть, но и это обходиться через always @(*)

 

 

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

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


Ссылка на сообщение
Поделиться на другие сайты
не ну это не честно: в первом случае if(i2 || o1), а во втором if(o1).

тут больше проблем из-за ошибки в списке чувствительности может быть, но и это обходиться через always @(*)

Что интересно, обе схемы синтезировались то корректно, проблема возникает только при моделировании.

Ну и типа не пишите через if else, а через ? или case, во всяких умных рекомендациях вещают.

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

Да да все эти гадские X'и.

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


Ссылка на сообщение
Поделиться на другие сайты
Если промоделировать два варианта, а потом сравнить с результатом моделирования netlist (он в обоих случаях одинаковый).

 

На сколько Вы в этом уверены?

 

Что интересно, обе схемы синтезировались то корректно, проблема возникает только при моделировании.

 

То есть у Вас оба варианта при синтезе дают одинаковый результат?

А чем синтезируете?

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


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

мне тоже кажется что схемы разные. Просто мы видим разные условия формирования выхода о2, по таблице истинности они различны, как может быть одна схема?

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


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

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

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

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

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

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

Войти

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

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