des00 25 5 сентября, 2014 Опубликовано 5 сентября, 2014 · Жалоба По сути вопроса я наверное плохо объясняю. Во всяком случае ISE 14.4 часто ругается когда меняется порядок индексов, то есть если объявляли регистр как 3:0, то попытки в каких то действиях запихать в него обратный порядок вызывает ошибку. Тут надо специалиста который поймет о чем я несу и нормально сформулирует :)... я что-то не могу сразу примера вспомнить.... ISE 14.7 ест и не давиться wire [4*32-1 : 0] iram_rdata; ...... wire [63 : 0] L__ordata_rslt; ...... assign iram_rdata[0*32 +: 32] = oram_addr[0] ? N__ordata_rslt[32 +: 32] : N__ordata_rslt[0 +: 32]; // 64 bit assign iram_rdata[1*32 +: 32] = oram_addr[0] ? T__ordata_rslt[32 +: 32] : T__ordata_rslt[0 +: 32]; assign iram_rdata[2*32 +: 32] = oram_addr[0] ? L__ordata_rslt[32 +: 32] : L__ordata_rslt[0 +: 32]; assign iram_rdata[3*32 +: 32] = dec__ordata_rslt; // 32 bit в атаче скрин стандарта Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ilkz 0 5 сентября, 2014 Опубликовано 5 сентября, 2014 (изменено) · Жалоба судя по коду port_map и port_sizes связаны однозначно (позиционно через generate), тогда какой смысл вводить 2 переменных, рискуя ошибиться (port_map постоянно увеличивается, в зависимости от port_size) если это можно рассчитать по месту ? а у вас нет произвольного числа параметров, у вас есть вектор port_sizes, длинна которого определенна в момент передачи параметра и nports который тоже определен при передаче параметра до создания параметра port_list. Если будут проблемы с синтезом или пониманием синтезатора, то сделайте красивый финт. А именно, old-style Verilog 95 объявление, позволяет использовать в качестве разрядностей векторов localparam. Т.е. по сути, задавать через параметр нужно только nports и port_sizes. Остальное будут вычисляемые параметры. Если задать только два параметра (nports и port_sizes), то при итерировании в цикле да - мы сможем достать из вектора нужный размер для нужного порта. Но как посчитать смещение для этого порта, ведь нужно держать где-то сумму всех предыдущих размеров? Основная проблема-то именно в этом. А так ваше предложение было бы почти идеальным решением. А совсем идеальным оно станет, имхо, если удастся обойтись только одним параметром - port_sizes, а все остальное - будет вычисляемым. P.S.: Т.е., в идеале нужно получить что-то такое: parameter nports = 8, parameter port_sizes = { 8'd6, 8'd1, 8'd8, 8'd4, 8'd2, 8'd3, 8'd2, 8'd1}, ... localparam current_port_pos = 0; generate for(i = 0; i < nports; i = i + 1) begin: port localparam current_port_pos = current_port_pos + port_sizes[i*8 +: 8] * 8; localparam current_port_size = port_sizes[i*8 +: 8] * 8; // и тогда доступ к порту i будет таким: // datain[current_port_pos +: current_port_size] end endgenerate , но верилог так не разрешает, т.к. получается переопределение константного параметра, что недопустимо. ________________________________________________________________________________ _______________________________ ISE 14.7 ест и не давиться Квартус очень даже давится: output [15:0] trx_data_out, input [15:0] data_from_trx ... assign trx_data_out[15:0] = data_from_trx[0:15]; выхлоп: Error (10198): Verilog HDL error at pcm_test_hw.v(59): part-select direction is opposite from prefix index direction Error (10784): HDL error at pcm_test_hw.v(16): see declaration for object "data_from_trx" Error (12153): Can't elaborate top-level user hierarchy Но если вручную расписать побитово через assign, то все будет работать. Изменено 5 сентября, 2014 пользователем ilkz Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
des00 25 5 сентября, 2014 Опубликовано 5 сентября, 2014 · Жалоба Если задать только два параметра (nports и port_sizes), то при итерировании в цикле да - мы сможем достать из вектора нужный размер для нужного порта. Но как посчитать смещение для этого порта, ведь нужно держать где-то сумму всех предыдущих размеров? Основная проблема-то именно в этом. module data_packer #( parameter nports = 8, parameter port_sizes = { 8'd6, 8'd1, 8'd8, 8'd4, 8'd2, 8'd3, 8'd2, 8'd1}, parameter max_port_size = 128 // max port size, bytes ) ( datain, port_ready, reset, clk, mode, byte, byte_ready, data_packed ); //------------------------------------------------------------------------------------------------------ // oops //------------------------------------------------------------------------------------------------------ localparam port_map = get_port_map(nports); localparam total_bits_len = get_ports_list(nports) * 8; function [max_port_size*8-1 : 0] get_port_map (input integer nports); integer i, pipa; begin pipa = 0; get_port_map = 1'b0; // unsigned extend for (i = 0; i < nports; i = i + 1) begin get_port_map[i*8 +: 8] = pipa; pipa = pipa + port_sizes[i*8 +: 8]; end end endfunction function integer get_ports_list (input integer nports); integer i; begin get_ports_list = 0; for (i = 0; i < nports; i = i + 1) begin get_ports_list = get_ports_list + port_sizes[i*8 +: 8]; end end endfunction //------------------------------------------------------------------------------------------------------ // //------------------------------------------------------------------------------------------------------ input [total_bits_len - 1 : 0] datain; input [nports - 1 : 0] port_ready; input reset; input clk; input mode; // 0 - forced mode (any port_ready[*] signal raise serialization), // 1 - wait mode (packer will be wait for all port_ready[*] signals before serialization, // port_ready[*] signals can come in any order and time) output reg [7:0] byte; output reg byte_ready; output reg data_packed; bla-bla-bla Какая проблема ? :) Квартус очень даже давится: правильно давиться, а спор с уважаемым Golikov A. о другом: использование +: и -: может применяться к векторам определенным в любом порядке. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ilkz 0 5 сентября, 2014 Опубликовано 5 сентября, 2014 · Жалоба Какая проблема ? :) Ух е-мое как изящно олд-стайл нагнул нью-стайл :twak: . Проверил на моделяторе и на железе - все синтезируется и работает как задумано. Класс. Век живи, век учись. B) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
des00 25 5 сентября, 2014 Опубликовано 5 сентября, 2014 · Жалоба Век живи, век учись. B) :) до кучи, при использовании такого стиля описания, возможно красивое решение файла параметров по умолчанию. Т.е.:создаете файл например parameters.vh, описываете в нем ваши параметры (в том числе с функциями преобразования), подключаете его в теле модуля сразу после секции портов(секцию параметров не трогаете). И так например во всем проекте. В итоге у вас есть файл параметров со значениями по умолчанию для всего проекта, при этому в любом инстансе модуля параметр может быть изменен индивидуально для модуля, не трогая все остальные инстансы. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Golikov 0 5 сентября, 2014 Опубликовано 5 сентября, 2014 · Жалоба assign iram_rdata[0*32 +: 32] = oram_addr[0] ? N__ordata_rslt[32 +: 32] : N__ordata_rslt[0 +: 32]; а так? assign iram_rdata[31 : 0] = oram_addr[0] ? N__ordata_rslt[32 +: 32] : N__ordata_rslt[0 +: 32]; и как следствие reg [31:0] Data; .... Data <= oram_addr[0] ? N__ordata_rslt[32 +: 32] : N__ordata_rslt[0 +: 32]; И я не в коем случае не спорю%) я просто помню что где-то я воткнулся в эту не удобность, а вот где не помню... до кучи, при использовании такого стиля описания, возможно красивое решение файла параметров по умолчанию. Т.е.:создаете файл например parameters.vh, описываете в нем ваши параметры (в том числе с функциями преобразования), Во-во, у меня так знакомый так в проекте сделал, теперь нельзя просто выдрать модуль из проекта, надо еще параметры переносить или этот файл с собой тащить. Палка о 2 концах... Ух е-мое как изящно олд-стайл нагнул нью-стайл Век живи, век учись. Недавно кто-то спрашивал про generate и там SM говорил что основное отличие генерейта в том что он реально генерит текст, и потому у него не может быть накапливающегося параметра в цикле от итерации к итерации, это как раз очень хороший пример различия простого for и generate. в функция можно использовать for без генерайта, и следовательно get_ports_list = 0; for (i = 0; i < nports; i = i + 1) begin get_ports_list = get_ports_list + port_sizes[i*8 +: 8]; end get_ports_list от итерации к итерации сохраняет свое "вычисленное" значение. А в генерайте он лишь текст, и параметр, и потому цикл развернулся в кучу строчек вида localparam current_port_pos = current_port_pos + port_sizes[i*8 +: 8] * 8; то есть в определение константы от константы которой еще нет... интересно попробовать так integer current_port_pos = 0; generate for(i = 0; i < nports; i = i + 1) begin: port current_port_pos = current_port_pos + port_sizes[i*8 +: 8] * 8; .... по идее тоже должно сработать... правильно давиться, а спор с уважаемым Golikov A. о другом: использование +: и -: может применяться к векторам определенным в любом порядке. еще раз все перечитал. Правильно ли я понимаю: если мы берем reg [15:0] Data; то мы не можем делать Data[0:15] , Data[7:10] и так далее... но можем Data[0 +: 16], Data [7 +: 4]? почему то мне казалось что во втором случае тоже ругань была... И да я понял главная моя ошибка, не в моменте присвоения, а в выборе куска вектора в другом порядке нежели при объявлении... вот где я всех запутал Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
des00 25 5 сентября, 2014 Опубликовано 5 сентября, 2014 · Жалоба а так? и как следствие assign iram_rdata[31 : 0] = oram_addr[0] ? N__ordata_rslt[31 -: 32] : N__ordata_rslt[0 +: 32]; ISE 14.7 собирает без проблем Во-во, у меня так знакомый так в проекте сделал, теперь нельзя просто выдрать модуль из проекта, надо еще параметры переносить или этот файл с собой тащить. Палка о 2 концах... если вырвали из SVN, от какая разница один или 2 файла. если взяли себе в проект, то потратить 5 минут на копипаст не вижу сложностей. еще раз все перечитал. Правильно ли я понимаю: если мы берем reg [15:0] Data; то мы не можем делать Data[0:15] , Data[7:10] и так далее... но можем Data[0 +: 16], Data [7 +: 4]? Да Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Golikov 0 5 сентября, 2014 Опубликовано 5 сентября, 2014 · Жалоба все понятно, это приятно... А порядок бит какой останется, как в объявлении? то есть в случае reg [31 : 0] Data1 reg [0 : 31] Data2 Data1[3 +: 2] == Data1 [4:3] Data2[3 +: 2] == Data2 [3:4] это опасно для понимания, может стать причиной ошибок... Или же порядок бит будет как указан? если вырвали из SVN, от какая разница один или 2 файла. если взяли себе в проект, то потратить 5 минут на копипаст не вижу сложностей. взять себе в проект, улучшить и вернуть, или когда там улучшиться взять себе опять вот где были сложности. Файл тащить там какие то варнинги сыпались, да и проект по идиологии был что все параметры были в модулях, а этот модуль выбивается. А если дописать параметры внутрь, то любой перенос надо не забывать их вставлять - убирать. В общем проблемы как всегда не в технологии, а в идиологии, если все проекты делать с внешним файлом констант - то вопросов нет. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
des00 25 5 сентября, 2014 Опубликовано 5 сентября, 2014 · Жалоба reg [31 : 0] Data1 reg [0 : 31] Data2 Data1[3 +: 2] == Data1 [4:3] Data2[3 +: 2] == Data2 [3:4] да, будет именно так. потому что порядок вектора оговорен стандартом vector[msb : lsb], а вот индексация вектора, с точки зрения направления может быть любой. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Golikov 0 5 сентября, 2014 Опубликовано 5 сентября, 2014 · Жалоба ок спасибо. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ilkz 0 16 сентября, 2014 Опубликовано 16 сентября, 2014 · Жалоба !!! Hotfix !!! В модуле обнаружилась веселая ошибка, приводящая к тому, что при использовании нескольких портов Квартус ругался. Ну и еще по мелочи пара исправлений. Выкладываю обновленный код.`include "timescale.v" module data_packer #( parameter nports = 8, parameter port_sizes = {8'd6, 8'd1, 8'd8, 8'd4, 8'd2, 8'd3, 8'd2, 8'd1}, parameter max_port_size = 8 // max port size, bytes ) ( datain, port_ready, reset, clk, mode, // 0 - forced mode (any port_ready[*] signal raise serialization), // 1 - wait mode (packer will be wait for all port_ready[*] signals before serialization, // port_ready[*] signals can come in any order and time) byte, byte_ready, data_packed ); function [max_port_size*nports*8-1 : 0] get_port_map (input integer nports); integer i, tmp; begin tmp = 0; get_port_map = 1'b0; // unsigned extend for (i = 0; i < nports; i = i + 1) begin get_port_map[i*8 +: 8] = tmp; tmp = tmp + port_sizes[i*8 +: 8]; end end endfunction function integer get_ports_list (input integer nports); integer i; begin get_ports_list = 0; for (i = 0; i < nports; i = i + 1) get_ports_list = get_ports_list + port_sizes[i*8 +: 8]; end endfunction localparam port_map = get_port_map(nports); localparam total_bits_len = get_ports_list(nports) * 8; input [total_bits_len - 1 : 0] datain; input [nports - 1 : 0] port_ready; input reset; input clk; input mode; output reg [7:0] byte; output reg byte_ready; output reg data_packed; reg [total_bits_len - 1 : 0] buffer; reg [nports - 1 : 0] ports_stored; reg [$clog2(max_port_size * nports) : 0] byte_cnt, offset; wire all_ports_stored = &ports_stored; wire serialize_en = byte_cnt > 0; wire serialization_done = {byte_ready, serialize_en} == 2'b10; integer n; genvar i, j; generate for(i = 0; i < nports; i = i + 1) begin: port localparam port_pos = port_map[i*8 +: 8] * 8; localparam port_size = port_sizes[i*8 +: 8] * 8; always @(posedge clk, posedge reset) begin if(reset) begin buffer[port_pos +: port_size] <= 0; ports_stored[i] <= 0; end else begin if(port_ready[i]) begin buffer[port_pos +: port_size] <= datain[port_pos +: port_size]; ports_stored[i] <= 1; end if(byte_ready) ports_stored[i] <= 0; if(serialization_done) buffer[port_pos +: port_size] <= 0; end end end endgenerate always @(posedge clk, posedge reset) begin if(reset) begin byte <= 0; byte_ready <= 0; data_packed <= 0; byte_cnt <= 0; offset <= 0; end else begin for(n = 0; n < nports; n = n + 1) begin if(port_ready[n] & !mode) begin byte_cnt <= port_sizes[n*8 +: 8]; offset <= port_map[n*8 +: 8]; end end if(mode & all_ports_stored) begin byte_cnt <= (total_bits_len >> 3); offset <= 0; end if(byte_cnt > 0) byte_cnt <= byte_cnt - 1; byte <= serialize_en ? buffer[((byte_cnt + offset - 1) * 8) +: 8] : byte; byte_ready <= serialize_en; data_packed <= serialization_done; end end endmodule Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
GAYVER 2 8 октября, 2015 Опубликовано 8 октября, 2015 · Жалоба а кто может объяснить смысл жтой записи? `define register_port(n) port_sizes[n * 8 +: 8] мы определили глобальный параметр register_port с произвольной размерностью. а что потом делает порт_сайз? он вроде как еще не определен... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Golikov 0 8 октября, 2015 Опубликовано 8 октября, 2015 · Жалоба register_port(n) заменить на port_sizes[n * 8 +: 8] Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
gotcha 0 8 октября, 2015 Опубликовано 8 октября, 2015 · Жалоба Макрофункция, которую обрабатывает препроцессор. Препроцессор всегда просто заменяет один текст на другой, из-за этого можно получить сюрпрайз-сюрпрайз (наприм. если n - арифметическое выражение). Хороший документ на эту тему http://www.veripool.org/papers/Preproc_Goo...Bos10_paper.pdf Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ilkz 0 12 октября, 2015 Опубликовано 12 октября, 2015 (изменено) · Жалоба GAYVER, это макрос, который позволяет упростить определение параметра port_list (см. пример использования в самом первом посте). Без этого макроса было бы localparam port_list = port_sizes[0 +: 8] + port_sizes[8 +: 8] + port_sizes[16 +: 8]; соответственно, надо помнить про индексы, высчитывать их. Это муторно. Макрос позволяет это действо скрыть: localparam port_list = `register_port(0) + `register_port(1) + `register_port(2); Кроме того, в последней версии кода этот параметр вообще ушел и никаких дополнительных макросов не требуется. Там использование гораздо проще: data_packer dp ( .reset (reset), .clk (sys_clk), .mode (mode), .datain ({port2, port1, port0}), .port_ready (rdy_port), .byte (), .byte_ready (), .data_packed () ) dp.nports = 3, // задаем количество используемых портов dp.port_sizes = {8'd3, 8'd8, 8'd6}, // задаем разрядности каждого порта dp.max_port_size = 8; // разрядность самого толстого используемого порта (в нашем случае 8, но можно задать с запасом) gotcha, сюрпрайз можно словить, если писать не аккуратно и использовать не так как задумано разработчиками. Но в целом Вы правы, с вычисляемыми макросами надо быть очень осторожным, особенно при их разработке. Изменено 12 октября, 2015 пользователем ilkz Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться