vasta 0 23 апреля, 2012 Опубликовано 23 апреля, 2012 · Жалоба Не могу разобраться, несколько строк прозрачного кода - а симулятор какую-то фигню выдает always @(posedge sample ) begin if (!sample_cnt) begin sample_cnt<= 1'b1; dout<=dout<<1; if(0) begin dout<=dout+1; end end else begin sample_cnt<= 1'b0; end end Все логично, если dout в начале был 0х01, то генерируется последовательно 0х02, 0х04, 0х08 .... Как только заходим в условие, т.е. always @(posedge sample ) begin if (!sample_cnt) begin sample_cnt<= 1'b1; dout<=dout<<1; if(1) begin dout<=dout+1; end end else begin sample_cnt<= 1'b0; end end почему-то пропускается строка dout<=dout<<1, т.е генерится 0х01, 0х02,0х03,0х04, хотя должно быть 0х01,0х03,0х07,0х0F Где я заблудился??? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
topor_topor 0 23 апреля, 2012 Опубликовано 23 апреля, 2012 · Жалоба Не могу разобраться, несколько строк прозрачного кода - а симулятор какую-то фигню выдает почему-то пропускается строка dout<=dout<<1, т.е генерится 0х01, 0х02,0х03,0х04, хотя должно быть 0х01,0х03,0х07,0х0F Где я заблудился??? A что это должно быть по смыслу? Либо счётчик, либо сдвиговый регистр? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
troiden 0 23 апреля, 2012 Опубликовано 23 апреля, 2012 (изменено) · Жалоба Всё работает по коду, у вас одновременно должны произойти два события: dout<=dout<<1; dout<=dout+1; Симулятор выполняет только последнее, а не одно за другим. Изменено 23 апреля, 2012 пользователем troiden Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
vasta 0 23 апреля, 2012 Опубликовано 23 апреля, 2012 · Жалоба A что это должно быть по смыслу? Либо счётчик, либо сдвиговый регистр? Вообще сдвиговый регистр, вставляющий единицы по условию. Т.е выполнено условие - сдвигаем , и вставляем "1" , не выполнено - просто сдвигаем Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
masics 0 23 апреля, 2012 Опубликовано 23 апреля, 2012 · Жалоба Потому что "if(1)" означает "выполнять всегда". Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
vasta 0 23 апреля, 2012 Опубликовано 23 апреля, 2012 · Жалоба Всё работает по коду, у вас одновременно должны произойти два события: dout<=dout<<1; dout<=dout+1; Симулятор выполняет только последнее, а не одно за другим. Да, вы правы, подводит Сишный образ мышления. Т.е эти операции должны выполняться в разных always-блоках, и иначе никак? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
troiden 0 23 апреля, 2012 Опубликовано 23 апреля, 2012 · Жалоба Да, вы правы, подводит Сишный образ мышления. Т.е эти операции должны выполняться в разных always-блоках, и иначе никак? Разные always-блоки не помогут, напоритесь на те же грабли. К тому же такой код синтез не пройдет. Нужно написать что-то подобное: dout[width:0] <= {dout[width-1, 0], 1}; Тут вам и сдвиг, и добавление единицы в младший разряд. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
topor_topor 0 23 апреля, 2012 Опубликовано 23 апреля, 2012 · Жалоба Вообще сдвиговый регистр, вставляющий единицы по условию. Т.е выполнено условие - сдвигаем , и вставляем "1" , не выполнено - просто сдвигаем Ну если это для синтеза, то надо шдето так (схемой надо думать, а не C++): wire SEL = 1; wire [N:0] D_OUT, dout; // Сдвигаем всё время.... always @(posedge sample ) begin if (!sample_cnt) begin sample_cnt<= 1'b1; dout<=dout<<1; end end // Вставляем когда надо.... assign D_OUT[N:0] = (SEL) ? {dout[N:1], 1} : dout[N:0]; Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
masics 0 23 апреля, 2012 Опубликовано 23 апреля, 2012 · Жалоба always @(posedge sample ) begin if (!sample_cnt) begin sample_cnt<= 1'b1; if(dout == 0) dout <= 1; else dout<=dout<<1; end else begin sample_cnt<= 1'b0; end end Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
troiden 0 23 апреля, 2012 Опубликовано 23 апреля, 2012 (изменено) · Жалоба Если уж пошли полные коды, то вот вариантик :) wire sel; reg [n:0] dout = 0; always @(posedge sample ) begin if (!sample_cnt) begin sample_cnt <= 1'b1; dout[n:0] <= {dout[n-1:0], sel}; end else begin sample_cnt<= 1'b0; end end n меняете на нужную вам разрядность sel - сигнал на добавление единицы Изменено 23 апреля, 2012 пользователем troiden Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Leka 1 23 апреля, 2012 Опубликовано 23 апреля, 2012 · Жалоба Да, вы правы, подводит Сишный образ мышления. Чтобы не подводил - можно использовать временные переменные с блокирующим присваиванием: tmp=dout<<1; if(...)tmp=tmp+1; dout<=tmp; Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sisuprun 0 4 мая, 2012 Опубликовано 4 мая, 2012 · Жалоба Чтобы не подводил - можно использовать временные переменные с блокирующим присваиванием: tmp=dout<<1; if(...)tmp=tmp+1; dout<=tmp; ИМХО не самый лучший вариант. Ведь выливается это в комбинационную схему, которая может привести к неоднозначным результатам работы. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Leka 1 4 мая, 2012 Опубликовано 4 мая, 2012 · Жалоба ИМХО не самый лучший вариант. Ведь выливается это в комбинационную схему, которая может привести к неоднозначным результатам работы. Внутри always@(posedge clk) - dout будет триггером. А чтобы не было неоднозначностей, tmp должен использоваться только внутри данного always блока. Синтезируется в сдвигвый регистр без использования ЛУТ: module tst( output reg [7:0] dout, input din, clk ); integer tmp; always@(posedge clk)begin tmp=dout<<1; if(din)tmp=tmp+1; dout<=tmp; end endmodule Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sisuprun 0 4 мая, 2012 Опубликовано 4 мая, 2012 · Жалоба Синтезируется в сдвигвый регистр без использования ЛУТ: module tst( output reg [7:0] dout, input din, clk ); integer tmp; always@(posedge clk)begin tmp=dout<<1; if(din)tmp=tmp+1; dout<=tmp; end endmodule Ну ежели уж строго говорить то Ваше описание синтезируется в почти тригерную схему : RTL в приложении. Система для синтеза ИСЕ 12.2. Так вот Ваше утверждение что сдвиговый регистр без ЛУТ считаю не совсем верным. Ибо в схеме есть элемент SRL16Е представляющий собой ЛУТ (согласно сюда): The SRL16E was introduced in the Virtex® FPGA architecture and is included in all variants of the Spartan® -3 family. It is an alternate operating mode of a Look-Up Table in which it becomes a 16-bit shift register. The added capability this configuration provides can lead to dramatic improvements in performance and cost savings to your design. А на счет однозначности схемы при использовании блокирующего/неблокирующего присвоения внутри always блока то рекомендую заглянуть вот сюда там об этом достаточно подробно расписано :laughing: Удачи!!! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Leka 1 4 мая, 2012 Опубликовано 4 мая, 2012 · Жалоба Ну ежели уж строго говорить то ... результат синтеза зависит от настроек, у меня синтезируется без SRLxxx А на счет однозначности... не там ее ищете, и похоже, и не так ее понимаете, судя по приведенной ссылке. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться