Stratix II GX. Проблема с целыми в Quartus II

Вопросы настройки, программирования, прошивки микроконтроллеров и микросхем программируемой логики
Закрыто
Аватара пользователя
10ff
Первый раз сказал Мяу!
Сообщения: 36
Зарегистрирован: Вт дек 23, 2008 21:44:13
Откуда: Россия

Stratix II GX. Проблема с целыми в Quartus II

Сообщение 10ff »

Граждане, помогите пожалуйста разобраться, почему программа на верилоге криво работает. Уже два дня пытаюсь найти причину... Я в этом деле новичок, строго не ругайте если что..... Вот часть кода:

module deser(data_out, CLK_COUNT, par_out, inp, reset, start, clock, i_out);

parameter data_bit = 8;
parameter parity = 1;
parameter stop_bit = 2;
parameter [31:0] baudrate = 921600;
parameter [31:0] frequency = 50000000;

parameter parity_var = (parity)?1:0;
parameter argument = (stop_bit + 1'd1 + parity_var);
parameter clk_number = data_bit + argument;
parameter [31:0] half_of_per = ((frequency)/(2*(baudrate)));

output reg [data_bit - 1:0] data_out;
output reset;
output reg par_out;
output reg CLK_COUNT;
output [31:0] i_out;
input start, inp, clock;
reg [3:0] l, k;
reg [clk_number - 1:0] IN;
reg stop2, par, flag;
reg [31:0] i;

assign i_out = i;

always @(posedge clock)
begin
if (flag)
stop2 <= 1'b1;
case (start)
1'b1:
begin
i = i + 1;
if ((i == half_of_per) && (CLK_COUNT == 1'b0))
begin
i = 0;
CLK_COUNT = 1'b1;
end
if ((i == half_of_per) && (CLK_COUNT == 1'b1))
begin
i = 0;
CLK_COUNT = 1'b0;
stop2 <= 1'b0;
end
end
1'b0:
begin
i = 0;
CLK_COUNT = 1'b0;
end
endcase
end
Вопрос в следующем: при отладке программы в SignalTap значение i в какой-то момент может стать произвольным, вследствие чего вся остальная часть програмины перестает работать. Это ошибка Квартуса? Или же програмина криво написана? В прикрепленном файле снимок диаграммы в SignalTap. Помогите пж-та.
Вложения
signaltap.jpg
(98.29 КБ) 551 скачивание
Аватара пользователя
Mozart
Мучитель микросхем
Сообщения: 413
Зарегистрирован: Пт мар 10, 2006 12:23:05
Откуда: Moscow
Контактная информация:

Сообщение Mozart »

видимо косяк какой-то...
попробуйте вместо этого

Код: Выделить всё

output [31:0] i_out; 

написать вот так

Код: Выделить всё

output reg [31:0] i_out; 

а assign i_out = i; это удалить...
Последний раз редактировалось Mozart Ср дек 24, 2008 11:13:43, всего редактировалось 2 раза.
если после прочитанной книги что-то в голове осталось, радуйся. Голова работает на тебя!!!
igor_tgru
Первый раз сказал Мяу!
Сообщения: 20
Зарегистрирован: Пн окт 27, 2008 22:11:28

Re: Stratix II GX. Проблема с целыми в Quartus II

Сообщение igor_tgru »

10ff писал(а):Граждане, помогите пожалуйста разобраться, почему программа на верилоге криво работает. Уже два дня пытаюсь найти причину... Я в этом деле новичок, строго не ругайте если что..... Вот часть кода:

Оформите код тегами Code , а то в посте каша получается , и покажите на симуляции сигналы этого модуля , похоже на то что по сигналу RX у вас чтото происходит
навскидку чему равен flag ?
зачем нужен case ?
назначение этой строчки непонятно

Код: Выделить всё

parameter parity_var = (parity)?1:0; 
Последний раз редактировалось igor_tgru Ср дек 24, 2008 11:35:01, всего редактировалось 2 раза.
Аватара пользователя
10ff
Первый раз сказал Мяу!
Сообщения: 36
Зарегистрирован: Вт дек 23, 2008 21:44:13
Откуда: Россия

Сообщение 10ff »

Код: Выделить всё

module deser(data_out, CLK_COUNT, par_out, inp, reset, start, clock, i_out);
 
parameter data_bit = 8;
parameter parity = 1;        //parity can be : 1)none, parity = 0 2)even, parity = 1 3)odd, parity = 2
parameter stop_bit = 2;     //4)mark, parity = 3 5)space, parity = 4
parameter [31:0] baudrate = 921600;   
parameter [31:0] frequency = 200000000;                     

parameter parity_var = (parity)?1:0;
parameter argument = (stop_bit + 1'd1 + parity_var);
parameter clk_number = data_bit + argument;
parameter [6:0] half_of_per = ((frequency)/(2*(baudrate)));

output reg [data_bit - 1:0] data_out;
output reset;
output reg par_out;
output reg CLK_COUNT;
output [6:0] i_out;
input start, inp, clock;
reg [3:0] l, k;
reg [clk_number - 1:0] IN;
reg stop2, par, flag;
reg [6:0] i;

assign i_out = i;
 
always @(posedge clock)
  begin
  if (flag)
    stop2 <= 1'b1;
  case (start)
  1'b1:
       begin
       i = i + 1;
      if ((i == half_of_per) && (CLK_COUNT == 1'b0))
        begin
        i = 0;
        CLK_COUNT = 1'b1;           
        end
      if ((i == half_of_per) && (CLK_COUNT == 1'b1))   
        begin
        i = 0;
        CLK_COUNT = 1'b0;
        stop2 <= 1'b0;       
        end
      end
  1'b0:
       begin
       i = 0;
       CLK_COUNT = 1'b0;
       end
  /*default:
       begin
       i = 0;
       CLK_COUNT = 1'b0;
       end   */ 
  endcase       
  end

always @(posedge CLK_COUNT)
  begin
  flag = 1'b0;   
  l = l + 1'b1;
  IN[l-1] = inp;
  if (l == clk_number)
    begin                 
           case(parity)
             0:
               begin
               par_out = 1'b0;
               end
             1:
               begin
               par = 1'b0;
               for (k = 4'b0001 ; k <= data_bit ; k = k + 4'b0001)
               par = par^IN[k];
               par_out = (par == IN[data_bit + 1])?(1'b0):(1'b1);               
               end
             2:             
               begin
               par = 1'b0;
               for (k = 4'b0001 ; k <= data_bit ; k = k + 4'b0001)
               par = par^IN[k];
               par = ~(par);
               par_out = (par == IN[data_bit + 1])?(1'b0):(1'b1);               
               end
             3:
               begin
               par_out = (IN[data_bit + 1] == 1'b1)?(1'b0):(1'b1);
               end
             4:
               begin
               par_out = (IN[data_bit + 1] == 1'b0)?(1'b0):(1'b1);
               end   
             endcase   
        data_out[data_bit - 1:0] = IN[data_bit:1];
        l = 1'b0;
        flag = 1'b1;     
    end   
  end
assign reset = flag & (~stop2); 
endmodule    [code]

Дело в том, что output [31:0] i_out; служит лишь для отладки...чтобы посмотреть что творится в регистре i, поэтому смысла его менять нету. Сегодня обнаружил что если регистр i уменьшить, скажем так
reg [6:0] i;
то все замечательно работает. Но если раздуваешь его до [31:0] то квартус начинает косячить....одни лаги...[/code]
Аватара пользователя
10ff
Первый раз сказал Мяу!
Сообщения: 36
Зарегистрирован: Вт дек 23, 2008 21:44:13
Откуда: Россия

Сообщение 10ff »

flag равен 1 в данном случае. можно конечно и без case, на if, но результат все равно тот же
igor_tgru
Первый раз сказал Мяу!
Сообщения: 20
Зарегистрирован: Пн окт 27, 2008 22:11:28

Сообщение igor_tgru »

10ff писал(а):flag равен 1 в данном случае. можно конечно и без case, на if, но результат все равно тот же

в первом посте флаг нигде неопределялся посему непонятно было , а кейс всетаки имхо наглядней заменить на иф.
igor_tgru
Первый раз сказал Мяу!
Сообщения: 20
Зарегистрирован: Пн окт 27, 2008 22:11:28

Сообщение igor_tgru »

10ff писал(а): Сегодня обнаружил что если регистр i уменьшить, скажем так
reg [6:0] i;
то все замечательно работает. Но если раздуваешь его до [31:0] то квартус начинает косячить....одни лаги...

дак етить ты пытаешся сравнивать значения с раными разрядностями , это не есть гут
Аватара пользователя
10ff
Первый раз сказал Мяу!
Сообщения: 36
Зарегистрирован: Вт дек 23, 2008 21:44:13
Откуда: Россия

Сообщение 10ff »

В том то и дело что если все параметры и переменные свести к 32-м разрядам то ничо не работает.
igor_tgru
Первый раз сказал Мяу!
Сообщения: 20
Зарегистрирован: Пн окт 27, 2008 22:11:28

Сообщение igor_tgru »

10ff писал(а):В том то и дело что если все параметры и переменные свести к 32-м разрядам то ничо не работает.

и если half_of_per будет 32 разряда тоже неработает ?
хотя тут может срабатывать оптимизатор , а посему имхо half_of_per нужно выводить из разряда константы.
Аватара пользователя
Mozart
Мучитель микросхем
Сообщения: 413
Зарегистрирован: Пт мар 10, 2006 12:23:05
Откуда: Moscow
Контактная информация:

Сообщение Mozart »

честно говоря я не понимаю как второй блок always может влиять на первый... попробуйте так...

Код: Выделить всё

reg [31:0] i; 
output [31:0] xz;

always @(posedge clock or posedge reset)
begin
   if (reset)
   begin
      i = 0;
      xz = 0;
   end
   if (flag)
      stop2 <= 1'b1;
      
   case (start)
      1'b1:
      begin
         i = i + 1;
         xz = i;
         if ((i == half_of_per))
         begin
            if ((CLK_COUNT == 1'b0))
            begin
               i = 0;
               CLK_COUNT = 1'b1;
            end
            else if (CLK_COUNT == 1'b1))
            begin
               i = 0;
               CLK_COUNT = 1'b0;
               stop2 <= 1'b0;
            end
         end
      end

      1'b0:
      begin
         i = 0;
         CLK_COUNT = 1'b0;
      end
   endcase
   
end
если после прочитанной книги что-то в голове осталось, радуйся. Голова работает на тебя!!!
Аватара пользователя
10ff
Первый раз сказал Мяу!
Сообщения: 36
Зарегистрирован: Вт дек 23, 2008 21:44:13
Откуда: Россия

Сообщение 10ff »

Mozart писал(а):честно говоря я не понимаю как второй блок always может влиять на первый... попробуйте так...

Код: Выделить всё

reg [31:0] i; 
output [31:0] xz;

always @(posedge clock or posedge reset)
......
end


Попробывал, ситуация абсолютна та же. Лишь уменьшение регистра i до 10 разрядов и изменение части других параметров дает эффект...а так уже всё пробывал :(
Аватара пользователя
Mozart
Мучитель микросхем
Сообщения: 413
Зарегистрирован: Пт мар 10, 2006 12:23:05
Откуда: Moscow
Контактная информация:

Сообщение Mozart »

значит надо смотреть errata на верилог или рекомендации... а вообще какая у вас версия Quartus'a??
если после прочитанной книги что-то в голове осталось, радуйся. Голова работает на тебя!!!
Аватара пользователя
Mozart
Мучитель микросхем
Сообщения: 413
Зарегистрирован: Пт мар 10, 2006 12:23:05
Откуда: Moscow
Контактная информация:

Сообщение Mozart »

в общем я написал так

Код: Выделить всё

module main(
   CLK_COUNT,
   reset,
   start,
   clock,
   i_out
);
 
input reset;
output reg CLK_COUNT;
//output [31:0] i_out;
input start, clock;
output reg [31:0] i_out;
 
always @(posedge clock)
begin
   if (start == 1'b0)
   begin
      i_out = 0;
      CLK_COUNT = 1'b0;
   end
   else if (start == 1'b1)
   begin
      i_out = i_out + 1;
      if (i_out == 10) //от балды задал
      begin
         if (CLK_COUNT == 1'b0)
         begin
            i_out = 0;
            CLK_COUNT = 1'b1;           
         end
         else if (CLK_COUNT == 1'b1)
         begin
            i_out = 0;
            CLK_COUNT = 1'b0;
         end
      end
   end
end


endmodule

и у меня всё работает график симуляции привожу, у меня нет платы для того чтобы посмотреть в железе... завтра может быть я доеду до работы и возьму железку, но заниматься мне этим просто некогда...
да ещё я считаю и уверен что один ваш модуль никак не влияет на другой!!!... по одной просто причине что вы можете записыват в один и тот же регистр только водном блоке always!!!...

совет вам, попробуйте отладить один кусок always'a а потом приступать у другому...
Вложения
results_.gif
результы
(32.83 КБ) 550 скачиваний
если после прочитанной книги что-то в голове осталось, радуйся. Голова работает на тебя!!!
Аватара пользователя
Mozart
Мучитель микросхем
Сообщения: 413
Зарегистрирован: Пт мар 10, 2006 12:23:05
Откуда: Moscow
Контактная информация:

Сообщение Mozart »

так что-то получилось толковое??
если после прочитанной книги что-то в голове осталось, радуйся. Голова работает на тебя!!!
igor_tgru
Первый раз сказал Мяу!
Сообщения: 20
Зарегистрирован: Пн окт 27, 2008 22:11:28

Сообщение igor_tgru »

2 10ff

А опиши что должен делать этот модуль .
Аватара пользователя
10ff
Первый раз сказал Мяу!
Сообщения: 36
Зарегистрирован: Вт дек 23, 2008 21:44:13
Откуда: Россия

Сообщение 10ff »

Код: Выделить всё

module ct_case1
#(
parameter frequency = 50_000_000,
           baudrate = 921_600
)
(
input  clock,
output CLK_COUNT
);

localparam div = frequency / (2*baudrate),
      ct_width = clogb2(div);

//
function integer clogb2 (input [31:0] value);
if (value <2> 0; clogb2 = clogb2 + 1)
value = value >> 1;
                     end
endfunction
//

reg [ct_width-1:0] ct_period_half;
reg                div_2;

assign CLK_COUNT = div_2;
     
always @(posedge clock)
begin
if (ct_period_half == div-1)       ct_period_half <= {ct_width{1'b0}};
else                               ct_period_half <= ct_period_half + 1'b1;

case (1'b1)
(ct_period_half == div-1) : div_2 <= ~div_2;
                  default : div_2 <= div_2;
                //  default : div_2 <= 1'b0;
endcase
end

endmodule



Всем большое спасибо за помощь. Модуль заработал после того как я вставил следующий код в свою програмину. Это функция для вычисления ширины регистра счетчика(а не как я писал [31:0]), а также делитель частоты. Код подсказал человек с форума electronix.
Закрыто

Вернуться в «Микроконтроллеры и ПЛИС»