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

Вопросы настройки, программирования, прошивки микроконтроллеров и микросхем программируемой логики
Закрыто
Первый раз сказал Мяу!
Аватара пользователя
Сообщения: 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;
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 КБ) 555 скачиваний
Реклама
Мучитель микросхем
Аватара пользователя
Сообщения: 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 раза.
если после прочитанной книги что-то в голове осталось, радуйся. Голова работает на тебя!!!
Контактная информация:
Реклама
Первый раз сказал Мяу!
Сообщения: 20
Зарегистрирован: Пн окт 27, 2008 22:11:28

Сообщение igor_tgru »

10ff писал(а):Граждане, помогите пожалуйста разобраться, почему программа на верилоге криво работает. Уже два дня пытаюсь найти причину... Я в этом деле новичок, строго не ругайте если что..... Вот часть кода:
Оформите код тегами Code , а то в посте каша получается , и покажите на симуляции сигналы этого модуля , похоже на то что по сигналу RX у вас чтото происходит
навскидку чему равен flag ?
зачем нужен case ?
назначение этой строчки непонятно

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

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

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

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

Сообщение igor_tgru »

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

Сообщение igor_tgru »

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

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

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

Сообщение igor_tgru »

10ff писал(а):В том то и дело что если все параметры и переменные свести к 32-м разрядам то ничо не работает.
и если half_of_per будет 32 разряда тоже неработает ?
хотя тут может срабатывать оптимизатор , а посему имхо half_of_per нужно выводить из разряда константы.
Мучитель микросхем
Аватара пользователя
Сообщения: 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
если после прочитанной книги что-то в голове осталось, радуйся. Голова работает на тебя!!!
Контактная информация:
Первый раз сказал Мяу!
Аватара пользователя
Сообщения: 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 разрядов и изменение части других параметров дает эффект...а так уже всё пробывал :(
Мучитель микросхем
Аватара пользователя
Сообщения: 413
Зарегистрирован: Пт мар 10, 2006 12:23:05
Откуда: Moscow

Сообщение Mozart »

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

Сообщение Mozart »

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

Сообщение igor_tgru »

2 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.
Закрыто

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