Stratix II GX. Проблема с целыми в Quartus II
Stratix II GX. Проблема с целыми в Quartus II
Граждане, помогите пожалуйста разобраться, почему программа на верилоге криво работает. Уже два дня пытаюсь найти причину... Я в этом деле новичок, строго не ругайте если что..... Вот часть кода:
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. Помогите пж-та.
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
- Контактная информация:
видимо косяк какой-то...
попробуйте вместо этого
написать вот так
а assign i_out = i; это удалить...
попробуйте вместо этого
Код: Выделить всё
output [31:0] i_out; написать вот так
Код: Выделить всё
output reg [31:0] i_out; а assign i_out = i; это удалить...
Последний раз редактировалось Mozart Ср дек 24, 2008 11:13:43, всего редактировалось 2 раза.
если после прочитанной книги что-то в голове осталось, радуйся. Голова работает на тебя!!!
Re: Stratix II GX. Проблема с целыми в Quartus II
10ff писал(а):Граждане, помогите пожалуйста разобраться, почему программа на верилоге криво работает. Уже два дня пытаюсь найти причину... Я в этом деле новичок, строго не ругайте если что..... Вот часть кода:
Оформите код тегами Code , а то в посте каша получается , и покажите на симуляции сигналы этого модуля , похоже на то что по сигналу RX у вас чтото происходит
навскидку чему равен flag ?
зачем нужен case ?
назначение этой строчки непонятно
Код: Выделить всё
parameter parity_var = (parity)?1:0;
Последний раз редактировалось igor_tgru Ср дек 24, 2008 11:35:01, всего редактировалось 2 раза.
Код: Выделить всё
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]- Mozart
- Мучитель микросхем
- Сообщения: 413
- Зарегистрирован: Пт мар 10, 2006 12:23:05
- Откуда: Moscow
- Контактная информация:
честно говоря я не понимаю как второй блок 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
если после прочитанной книги что-то в голове осталось, радуйся. Голова работает на тебя!!!
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
- Контактная информация:
в общем я написал так
и у меня всё работает график симуляции привожу, у меня нет платы для того чтобы посмотреть в железе... завтра может быть я доеду до работы и возьму железку, но заниматься мне этим просто некогда...
да ещё я считаю и уверен что один ваш модуль никак не влияет на другой!!!... по одной просто причине что вы можете записыват в один и тот же регистр только водном блоке always!!!...
совет вам, попробуйте отладить один кусок always'a а потом приступать у другому...
Код: Выделить всё
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 скачиваний
если после прочитанной книги что-то в голове осталось, радуйся. Голова работает на тебя!!!
Код: Выделить всё
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.