LMT 0 30 августа, 2008 Опубликовано 30 августа, 2008 · Жалоба Здравствуйте. Есть такой тестовый скрипт: `timescale 1ns/1ps module test; //////////////////////////////////////////////////////////////////////////// // Часы parameter CLOCK = 10; reg C; initial begin C = 1'b0; #CLOCK; forever #( CLOCK / 2 ) C = ~ C; end //////////////////////////////////////////////////////////////////////////// // Тестовый массив reg [7 : 0] Array[3 : 0]; //////////////////////////////////////////////////////////////////////////// // Тестовый task task automatic Post; input integer idx; input integer cnt; integer i; begin for(i = 0; i < cnt; i = i + 1) begin repeat(2) @( posedge C ); Array[ idx ] = #1 { i[3 : 0], idx[3 : 0] }; end repeat(2) @( posedge C ); end endtask //////////////////////////////////////////////////////////////////////////// // Основной поток initial begin #(3 * CLOCK); fork Post(0, 5); Post(1, 5); Post(2, 5); Post(3, 5); join #(4 * CLOCK) $stop; end endmodule Почему при исполнении под modelsim'ом присваивание элементу массива значения в отдельном task'е перекрывает присваивания другим элементам во всех остальных task'ах (см. рис.) ? Допускается ли в verilog'е такое обращение с массивами в принципе ? Или я чего-то не знаю ... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dvladim 0 30 августа, 2008 Опубликовано 30 августа, 2008 · Жалоба Ух. Поехали. Нет такого понятия: "массив". Есть понятие память. Доступ только по словам. Доступа к битам слова нет. В task чаще передают "провод". Т.е. "input [7 : 0] iii;" task у вас выполняется не мгновенно. Это нормально работает только для поведенческого описания. Не для синтеза. (вот тут меня наверное поправят.) Выполнение одного таска несколько раз одновременно ведет к непредсказуемым результатам. Из-за того, что переменные не копируются. У вас fork ... join и таски все выполняются одновременно. Так что ... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
LMT 0 31 августа, 2008 Опубликовано 31 августа, 2008 · Жалоба Не, понятие массива в языке есть. Просто при синтезе масив инстанциируется в память. Речь идёт только о функциональном тестбенче, синтезируемость не преследуется. Приведённый выше пример есть иллюстрация проблемы в тестбенче для функциональной верификации параметризованного модуля. Чтобы не плодить для передачи модулю n аргументов (n = 4 :) ) в n потоков initial, был применён такой подход, но что-то он не сработал. Я, конечно, выкрутился, но получилось некузяво. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
des00 25 31 августа, 2008 Опубликовано 31 августа, 2008 · Жалоба Приведённый выше пример есть иллюстрация проблемы в тестбенче для функциональной верификации параметризованного модуля. Чтобы не плодить для передачи модулю n аргументов (n = 4 :) ) в n потоков initial, был применён такой подход, но что-то он не сработал. Я, конечно, выкрутился, но получилось некузяво. Проблем никаких нет. Все работает правильно, Что вы написали, то вы и получили. Вы же сами описываете ОДИН массив, к которому ОДНОВРЕМЕННО лезут, по ПЕРЕКРЫВАЮЩИМСЯ адресам 4 треда (в тасках). или вы вставили порождение программных тредов fork/join для "красного словца", совершенно не осознавая к чему это приведет ?? %)) Удачи!!! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
LMT 0 31 августа, 2008 Опубликовано 31 августа, 2008 · Жалоба des00 fork/join обеспечивают параллельное выполнение statements, заключённых между ними, и применены осознанно. Посмотрите внимательно сорс: запись в массив происходит по разным индексам (но при этом запись в один элемент приводит к записи во все одного и того же значения). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dvladim 0 31 августа, 2008 Опубликовано 31 августа, 2008 · Жалоба Кстати только сейчас заметил, что в Array[ idx ] = #1 { i[3 : 0], idx[3 : 0] }; idx слева правильный, а справа всегда = 3. Может из-за этого: "#1"? А вообще правильно говорят, что нечего вызывать таск из разных мест одновременно. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
id_gene 0 1 сентября, 2008 Опубликовано 1 сентября, 2008 · Жалоба А вот попробуйте перенести задержку вот так: begin repeat(2) @( posedge C ); #idx Array[ idx ] = { i[3 : 0], idx[3 : 0] }; end Похоже, что доступ к массиву (даже по разным адресам) блокирующим присвоением из разных тасков в одно и то же время заканчивается вашим случаем. В моделсиме можно пошагово пройти, с просмотром каждой переменной в каждом треде. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
LMT 0 1 сентября, 2008 Опубликовано 1 сентября, 2008 · Жалоба Да, в таком виде всё отработало как надо. Похоже, всё дело в типе задержки. Спасибо за подсказку. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
des00 25 2 сентября, 2008 Опубликовано 2 сентября, 2008 · Жалоба des00 fork/join обеспечивают параллельное выполнение statements, заключённых между ними, и применены осознанно. Посмотрите внимательно сорс: запись в массив происходит по разным индексам (но при этом запись в один элемент приводит к записи во все одного и того же значения). да вы правы, не туда посмотрел. если дело в задержке, то это бага. напишите в ментор, с примером. хотя я добавил вот такой код к вашему примеру always_ff @(posedge C) begin string str; $timeformat(-9, 1, " ns", 10); str = $psprintf("%0t :", $time); foreach (Array[i]) str = {str, $psprintf("%0d ", Array[i])}; $display (str); end вот результат # 15.0 ns :x x x x # 25.0 ns :x x x x # 35.0 ns :x x x x # 45.0 ns :x x x x # 55.0 ns :3 2 1 0 # 65.0 ns :3 2 1 0 # 75.0 ns :19 18 17 16 # 85.0 ns :19 18 17 16 # 95.0 ns :35 34 33 32 # 105.0 ns :35 34 33 32 # 115.0 ns :51 50 49 48 # 125.0 ns :51 50 49 48 # 135.0 ns :67 66 65 64 # 145.0 ns :67 66 65 64 # 155.0 ns :67 66 65 64 # 165.0 ns :67 66 65 64 # 175.0 ns :67 66 65 64 отмеченной вами баги не видно. проверялось на 6.3g Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
LMT 0 2 сентября, 2008 Опубликовано 2 сентября, 2008 · Жалоба В ментор писать не буду, поскольку работаю с 6.2g. Кроме того, у меня вообще права писать туда нет ;) :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dvladim 0 2 сентября, 2008 Опубликовано 2 сентября, 2008 · Жалоба хотя я добавил вот такой код к вашему примеру вот результат Не информативно. Было бы интереснее следующее: always @(array[0]) $display($time, array[0]); 2All Если таск написан с использованием временных задержек как то: #, @(), wait то вызов таска когда он же выполняется может приводить к произвольным результатам. Рекомендуется в таске вставлять проверку двойного вызова. task reg in_use; begin if (in_use === 1'b1) $stop; in_use = 1'b1; .......... in_use = 1'b0; end endtask Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
des00 25 3 сентября, 2008 Опубликовано 3 сентября, 2008 · Жалоба Не информативно. автору значения, хранящиеся в массиве, интересны как синхронные воздействия, поэтому нет никакого смысла привязываться к изменению значений массива. Т.к. команда $time не чувствительна к дельта-циклам, а привязка к моменту вывода сообщения в лог тоже не имеет смысла, т.к. выполнение команды $display в вашем случае будет не недетерменированно. И раз пошла такая пьянка, то ИМХО лучше сделать так :) initial $monitor($time, Array[0], Array[1], Array[2], Array[3]); 2All Если таск написан с использованием временных задержек как то: #, @(), wait то вызов таска когда он же выполняется может приводить к произвольным результатам. Рекомендуется в таске вставлять проверку двойного вызова. task reg in_use; begin if (in_use === 1'b1) $stop; in_use = 1'b1; .......... in_use = 1'b0; end endtask ну это действительно только для тредов которые обращаются к разделяемым ресурсам (что в данном случае не верно) и лучше уж тогда воспользоваться семафором. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
LMT 0 3 сентября, 2008 Опубликовано 3 сентября, 2008 · Жалоба dvladim Если таск написан с использованием временных задержек как то: #, @(), wait то вызов таска когда он же выполняется может приводить к произвольным результатам. Атрибут automatic делает task реентрантным. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dvladim 0 3 сентября, 2008 Опубликовано 3 сентября, 2008 · Жалоба автору значения, хранящиеся в массиве, интересны как синхронные воздействия, поэтому нет никакого смысла привязываться к изменению значений массива. Т.к. команда $time не чувствительна к дельта-циклам, а привязка к моменту вывода сообщения в лог тоже не имеет смысла, т.к. выполнение команды $display в вашем случае будет не недетерменированно. И раз пошла такая пьянка, то ИМХО лучше сделать так :) initial $monitor($time, Array[0], Array[1], Array[2], Array[3]); Если значение, скажем, Array[0] изменится несколько раз в одной временной точке, то $monitor покажет только последнее значение, always @() $display покажет все. Просто в данном случае есть подозрение, что элементы массива меняются по несколько раз. Атрибут automatic делает task реентрантным. Это начиная с 2001. Раньше не было. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
des00 25 4 сентября, 2008 Опубликовано 4 сентября, 2008 · Жалоба Если значение, скажем, Array[0] изменится несколько раз в одной временной точке, то $monitor покажет только последнее значение, always @() $display покажет все. да вы правы, век живи век учись %) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться