KWIer 0 20 декабря, 2011 Опубликовано 20 декабря, 2011 · Жалоба Ну парни, всем спасибо, я устал возится с этим простейшим куском.... Чувствую себя неудавшимся кодером, потому как в графике нарисовал все за 5 минут и все работает.. Выложу, может пригодится или хоть настроение поднимет кому :) module shift_reg ( input enable, input clr, input cpu_data_in, cpu_clk_in, output reg [263:0] sr = 0, output wire [8:0] bytenums ); reg [8:0] cntr; assign bytenums = cntr; always @ (posedge cpu_clk_in or posedge clr) begin if (clr == 1'b1) begin cntr <= 9'd0; end else begin if (enable==1'b1) begin sr[263:1] <= sr[262:0]; sr[0] <= cpu_data_in; cntr <= cntr + 1'b1; end end end endmodule module cntr264 ( input enable, input clr, cpu_clk_in, output reg rec_ready ); reg [8:0] cntr; always @ (posedge cpu_clk_in or posedge clr) begin if (clr==1'b1) cntr <= 9'd0; else begin if (enable == 1'b1) begin cntr <= cntr + 1'b1; if (cntr == 9'd263) begin cntr <= 9'd0; rec_ready <= 1'b1; end else rec_ready <= 1'b0; end end end endmodule Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
M@kar 0 20 декабря, 2011 Опубликовано 20 декабря, 2011 · Жалоба Попробуйте вот так: module cpu_in ( input enable, input cpu_data_in, cpu_clk_in, output reg [263:0] cpu_mess, output wire [8:0] bytenums ); reg [263:0] sr = 0; reg [8:0] cntr; assign bytenums = cntr; always @(enable) begin always @ (posedge cpu_clk_in) begin sr[263:1] <= sr[262:0]; sr[0] <= cpu_data_in; cntr <= cntr +1; end end always @(negedge enable) begin if (cntr==9'd264) cpu_mess <= sr; cntr <= 0; end endmodule Не знаю, скомпилируется ли. Нет под рукой компилятора. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
KWIer 0 20 декабря, 2011 Опубликовано 20 декабря, 2011 · Жалоба Попробуйте вот так: module cpu_in ( input enable, input cpu_data_in, cpu_clk_in, output reg [263:0] cpu_mess, output wire [8:0] bytenums ); reg [263:0] sr = 0; reg [8:0] cntr; assign bytenums = cntr; always @(enable) begin always @ (posedge cpu_clk_in) begin sr[263:1] <= sr[262:0]; sr[0] <= cpu_data_in; cntr <= cntr +1; end end always @(negedge enable) begin if (cntr==9'd264) cpu_mess <= sr; cntr <= 0; end endmodule Не знаю, скомпилируется ли. Нет под рукой компилятора. Нее, не удается :( Во-первых похоже не понравилось что always внутри другого always, затем Error (10028): Can't resolve multiple constant drivers for net "cntr[8]" at cpu_in.v(20) и еще кажется нельзя в одном модуле событие обрабатывать по enable и negedge enable Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
M@kar 0 20 декабря, 2011 Опубликовано 20 декабря, 2011 (изменено) · Жалоба Во-первых похоже не понравилось что always внутри другого always, затем Error (10028): Can't resolve multiple constant drivers for net "cntr[8]" at cpu_in.v(20) и еще кажется нельзя в одном модуле событие обрабатывать по enable и negedge enable Похоже на правду. Главное, что у вас все заработало уже :cheers: Так наверно тоже ругаться будет на latch? always @(negedge enable) begin if (cntr==9'd264) cpu_mess <= sr; cntr <= 0; end always @ (posedge cpu_clk_in) begin if (enable) begin sr[263:1] <= sr[262:0]; sr[0] <= cpu_data_in; cntr <= cntr +1; end end Изменено 20 декабря, 2011 пользователем M@kar Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
KWIer 0 20 декабря, 2011 Опубликовано 20 декабря, 2011 · Жалоба Похоже на правду. Главное, что у вас все заработало уже :cheers: Так наверно тоже ругаться будет на latch? always @(negedge enable) begin if (cntr==9'd264) cpu_mess <= sr; cntr <= 0; end always @ (posedge cpu_clk_in) begin if (enable) begin sr[263:1] <= sr[262:0]; sr[0] <= cpu_data_in; cntr <= cntr +1; end end Ругается, но не на латч... А на несколько драйdеров cntr Error (10028): Can't resolve multiple constant drivers for net "cntr[3]" at cpu_in.v(17) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
M@kar 0 20 декабря, 2011 Опубликовано 20 декабря, 2011 (изменено) · Жалоба Тогда так: always @(negedge enable) begin if (cntr==9'd264) cpu_mess <= sr; end always @ (posedge cpu_clk_in) begin if (enable) begin sr[263:1] <= sr[262:0]; sr[0] <= cpu_data_in; cntr <= cntr +1; end else cntr <= 0; end Хотя не, так он else cntr <= 0; не обнулит никогда. Тогда у меня только вариант с латчем уживаться: always @ (posedge cpu_clk_in or negedge enable) begin if (enable) begin sr[263:1] <= sr[262:0]; sr[0] <= cpu_data_in; cntr <= cntr +1; end else begin // if (!enable) begin if (cntr==9'd264) cpu_mess <= sr; cntr <= 0; end end Его можно попробовать так убрать: module cpu_in ( input enable, input cpu_data_in, cpu_clk_in, output reg [263:0] cpu_mess, output wire [8:0] bytenums ); reg [263:0] sr = 0; reg [263:0] temp = 0; reg [8:0] cntr; assign bytenums = cntr; always @ (posedge cpu_clk_in or negedge enable) begin if (enable) begin sr[263:1] <= sr[262:0]; sr[0] <= cpu_data_in; cntr <= cntr +1; end else begin // if (!enable) begin if (cntr==9'd264) begin cpu_mess <= sr; temp <= sr; cntr <= 0; end else begin cntr <= 0; cpu_mess <= temp; end end endmodule Хотя так жаловаться на temp будет :rolleyes: Изменено 20 декабря, 2011 пользователем M@kar Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Timmy 1 20 декабря, 2011 Опубликовано 20 декабря, 2011 · Жалоба Предполагаю, что вначале поднимается enable, потом 264 раза бьёт клок, потом enable опускается. Именно так типично управляется spi с микроконтроллера. module cpu_in ( input enable, input cpu_data_in, cpu_clk_in, output reg [263:0] cpu_mess, output wire [8:0] bytenums ); reg [263:0] sr; reg [8:0] cntr; reg reset_count; assign bytenums = cntr; always @ (posedge cpu_clk_in) begin if (enable) begin sr[263:1] <= sr[262:0]; sr[0] <= cpu_data_in; if(reset_count) cntr <= 9'b0; else cntr <= cntr+1; end end always @(negedge enable) begin if(cntr = 9'd264)cpu_mess < sr; end always @(posedge cpu_clk_in or negedge enable) if enable = 1'b0 reset_count <= 1'b1; else reset_count <= 1'b0; endmodule Отдельно определяем регистр для cpu_mess, который защёлкивается по фронту enable, и ещё специальный триггер для управления сбросом счётчика бит, который асинхронно устанавливается по уровню enable и сбрасывается после первого клока(который одновременно сбрасывает счётчик). И не забывайте о синхронизации всего этого с системным клок доменом. Ещё надо проверить конечное значение счётчика, которое может получится на 1 меньше, чем ожидалось. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
yume 0 22 декабря, 2011 Опубликовано 22 декабря, 2011 · Жалоба Я могу быть не права, но обратите внимание вот на что: 1) У всех авторов в их кодах считается не 264 бита, а 265, поскольку счетчик cntr начинает считать с 0, а значение снимается по счету 264, т.е. всего 265 тактов. Это же явно видно по схеме в аттачах автора KWIer. 2) У автора KWIer был запрос был такой, перефразирую - когда enable будет держаться 264 тактов подряд - только тогда считать информацию на шине правильной, т.е. защититься от внезапных всплесков enable, так? Если так, то никто из авторов не позаботился о том, чтобы "неправильные данные" во время случайного всплеска не попали в регистр sr, а ведь он потом перейдет в cpu_mess. Может стоит обнулять sr, когда enable не находится в единичном состоянии 264 такта подряд? 3) Автор KWIer скажите мне, КАК вы умудрились на схематике подключить ШИНУ на однобитный вход триггера (DFF кажется) и не получить ошибок? 4) Автор Timmy кажется приблизил этот код к работоспособности, но (без компилятора, на глаз) вижу такое несоответствие задумке: поясню ЕСЛИ (enable = 0) ТО (reset_count = 1) - указано явно ЕСЛИ (enable = 1) ТО (reset_count = 0) - указано неявно через else в другом же процессе происходит проверка ЕСЛИ ((enable = 1) И (reset_count = 1)) ТО (cntr = 0) - сгруппировано мной для наглядности. Так вот, cntr похоже никогда так 0 не станет. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Timmy 1 22 декабря, 2011 Опубликовано 22 декабря, 2011 · Жалоба Я могу быть не права, но обратите внимание вот на что: 1) У всех авторов в их кодах считается не 264 бита, а 265, поскольку счетчик cntr начинает считать с 0, а значение снимается по счету 264, т.е. всего 265 тактов. Это же явно видно по схеме в аттачах автора KWIer. 2) У автора KWIer был запрос был такой, перефразирую - когда enable будет держаться 264 тактов подряд - только тогда считать информацию на шине правильной, т.е. защититься от внезапных всплесков enable, так? Если так, то никто из авторов не позаботился о том, чтобы "неправильные данные" во время случайного всплеска не попали в регистр sr, а ведь он потом перейдет в cpu_mess. Может стоит обнулять sr, когда enable не находится в единичном состоянии 264 такта подряд? 4) Автор Timmy кажется приблизил этот код к работоспособности, но (без компилятора, на глаз) вижу такое несоответствие задумке: поясню ЕСЛИ (enable = 0) ТО (reset_count = 1) - указано явно ЕСЛИ (enable = 1) ТО (reset_count = 0) - указано неявно через else в другом же процессе происходит проверка ЕСЛИ ((enable = 1) И (reset_count = 1)) ТО (cntr = 0) - сгруппировано мной для наглядности. Так вот, cntr похоже никогда так 0 не станет. по 1)Я тоже обратил внимание в предыдущем посте, что 264 надо проверить и исправить:). по 2)Случайные данные могут сколько угодно задвигаться в sr, в cpu_mess они не попадут, если enable держался не 264 клока. А потом полностью перезапишутся правильным пакетом в 264 клока. по 4)Обращайте также внимание на условия выполнения процессов. В соответствии с ними reset_count безусловно и асинхронно устанавливается по низкому уровню enable, а сбрасывается по фронту clk при высоком уровне enable. Одновременно по тому же фронту clk сбросится и cntr, это не зря называется flip-flop. Надеюсь, код типа reset_count <= 1'b0; if(reset_count==1'b1)cntr <= 9'b0; не вызывает у Вас когнитивного диссонанса?:) Ещё заметил, что я по VHDL-ной привычке иногда пишу "if" без скобок и = вместо ==. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
M@kar 0 22 декабря, 2011 Опубликовано 22 декабря, 2011 (изменено) · Жалоба по 1)Я тоже обратил внимание в предыдущем посте, что 264 надо проверить и исправитьsm.Обращал внимание автора на это, он говорит так и надо. Спасибо вам за пример, а то я так и не сообразил. Изменено 22 декабря, 2011 пользователем M@kar Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
yume 0 23 декабря, 2011 Опубликовано 23 декабря, 2011 · Жалоба Надеюсь, код типаreset_count <= 1'b0; if(reset_count==1'b1)cntr <= 9'b0; не вызывает у Вас когнитивного диссонанса?:) Возможно, ввиду того, что редко использую latch в реализации, считаю что код вырван из контекста, хотя часто использую такой способ и неприятных ощущений он у меня не вызывает: if(reset_count==1'b1) begin cntr <= 9'b0; reset_count <= 1'b0; end Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sazh 8 23 декабря, 2011 Опубликовано 23 декабря, 2011 · Жалоба считаю что код вырван из контекста И Ваш тоже. Ибо все что Выше , предлагалось ввиде наброска без использования внутренней системной частоты. Что наложило свой отпечаток на реализацию в виде двух процессов always @(posedge cpu_clk_in) и always @(posedge cpu_clk_in or negedge enable), поэтому и разнесены по процессам reset_count и cntr. Если и настаивать на чем либо, тестбенч желательно прилагать. Что касается Вашего вопроса по графическому редактору, то как известно параметризированные lpm функции занимают много места на листе ватмана, поэтому и используют одиночные примитивы, ибо если к одиночному примитиву подвести шину, квартус размножает этот примитив до разрядности этой шины. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
KWIer 0 23 декабря, 2011 Опубликовано 23 декабря, 2011 (изменено) · Жалоба Timmy, Спасибо за рабочий код... прогнал в симуляторе и в железе, все работает как часы... На всякий случай выкладываю финальную редакцию твоего кода. Я могу быть не права, но обратите внимание вот на что: 1) У всех авторов в их кодах считается не 264 бита, а 265, поскольку счетчик cntr начинает считать с 0, а значение снимается по счету 264, т.е. всего 265 тактов. Это же явно видно по схеме в аттачах автора KWIer. ... 3) Автор KWIer скажите мне, КАК вы умудрились на схематике подключить ШИНУ на однобитный вход триггера (DFF кажется) и не получить ошибок? ... 1) в реализации у Timmy, условие действительно должно быть if(cntr == 9'd263), чтобы считать ровно 264 клока (симуляция во вложении), так как счетчик увеличивается лишь по второму импульсу клока. А вот в моей первой реализации по первому переднему фронту клока сдвигался 1 бит и счетчик становился равным 1, соответственно счетчик = 264 когда сдвинуто 264 бита, а не 265. Можете провести сравнение двух симуляций в посках различий в поведении счетчиков :) 3) Quartus такие действия разрешает, если на входе и выходе DFF шина одинаковой ширины, он создает массив триггеров. Еще раз всем спасибо! :santa2: Вопрос можно считать решенным, а тему - завершенной cpu_in.v Изменено 23 декабря, 2011 пользователем KWIer Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
yume 0 23 декабря, 2011 Опубликовано 23 декабря, 2011 · Жалоба Что касается Вашего вопроса по графическому редактору, то как известно параметризированные lpm функции занимают много места на листе ватмана, поэтому и используют одиночные примитивы, ибо если к одиночному примитиву подвести шину, квартус размножает этот примитив до разрядности этой шины. 3) Quartus такие действия разрешает, если на входе и выходе DFF шина одинаковой ширины, он создает массив триггеров. Ух ты! Забавно, что Квартус так умеет, не знала, спасибо) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться