dxp 34 13 июня, 2007 Опубликовано 13 июня, 2007 · Жалоба Вот, скажем, мультиплексор: module MBusMux4 #(parameter P_Width = 1) ( input [P_Width-1:0] in0, input [P_Width-1:0] in1, input [P_Width-1:0] in2, input [P_Width-1:0] in3, output reg [P_Width-1:0] out, input [1:0] sel ); always @* begin case(sel) 0: out = in0; 1: out = in1; 2: out = in2; 3: out = in3; endcase end endmodule переключает 4 шины, размерность шины задается параметром. Но иногда надо не только ширину шины задавать, но и их количество (в данном случае их 4, но нужно сделать так, чтоб можно было задавать параметром). Вопрос: как сделать такой мультиплекор? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Doka 1 13 июня, 2007 Опубликовано 13 июня, 2007 · Жалоба сдается мне сделать такое, в классическом верилоге, не поддерживающим передачи в интерфейсе модуля двухмерных массивов, крайне затруднительно.. но если уж так хочется "параметризации", то написать автогенерилку модулей mux_02..mux_nn (статически находящихся в бибилиотеке проекта), а в верхнем модуле иерархии через `define custom_mux mux_N задавать нужный примитив. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
MurrVK 0 13 июня, 2007 Опубликовано 13 июня, 2007 · Жалоба Вот, скажем, мультиплексор: module MBusMux4 #(parameter P_Width = 1) ( input [P_Width-1:0] in0, input [P_Width-1:0] in1, input [P_Width-1:0] in2, input [P_Width-1:0] in3, output reg [P_Width-1:0] out, input [1:0] sel ); always @* begin case(sel) 0: out = in0; 1: out = in1; 2: out = in2; 3: out = in3; endcase end endmodule переключает 4 шины, размерность шины задается параметром. Но иногда надо не только ширину шины задавать, но и их количество (в данном случае их 4, но нужно сделать так, чтоб можно было задавать параметром). Вопрос: как сделать такой мультиплекор? А почему бы не так: module MBusMux4 #(parameter P_Width = 1, B_Count = 4, Sel_Bus_Width = 2) ( input [P_Width-1:0] in[B_Count - 1: 0], output [P_Width-1:0] out, input [Sel_Bus_Width - 1:0] sel ); assign out = in[sel]; endmodule Я примерно такое в Квартусе делал - кушало даже без предупреждений. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
CaPpuCcino 0 13 июня, 2007 Опубликовано 13 июня, 2007 · Жалоба А почему бы не так: module MBusMux4 #(parameter P_Width = 1, B_Count = 4, Sel_Bus_Width = 2) ( input [P_Width-1:0] in[B_Count - 1: 0], output [P_Width-1:0] out, input [Sel_Bus_Width - 1:0] sel ); assign out = in[sel]; endmodule Я примерно такое в Квартусе делал - кушало даже без предупреждений. +1 и предупреждений никаких не должно быть - индексирование в массиве операция синтезируемая Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
RobFPGA 27 13 июня, 2007 Опубликовано 13 июня, 2007 · Жалоба Приветствую! Была у меня такая проблема при построении дерева сумматоров на verilog. Пришлось делать один широкий вход и разбирать его на шины уже внутри модуля. ... parameter WidthIn=8; parameter NumIn=4; input [WidthIn*NumIn-1:0]; .. Успехов Rob! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sazh 3 13 июня, 2007 Опубликовано 13 июня, 2007 · Жалоба Все так и есть Rob. А все что выше, так это или графический редактор поддерживает. Ну и наверно sverilog module mux_generate #(parameter P_Width = 4, parameter P_Size = 4) ( input [sel_width-1:0] sel, input [P_Width*P_Size-1:0] data, output [P_Width-1:0] out ); localparam sel_width = clog2(P_Size); wire [P_Width-1:0] r [P_Size-1:0]; /////////////////////////////////////////////////////////////////////////////////////////// function integer clog2 (input integer num); // this function calculates ceil(log2(num)) integer j; begin num = num - 1; for (j = 0; num > 0; j = j + 1) num = num >> 1; clog2 = j; end endfunction ////////////////////////////////////////////////////////////////////////////////// genvar j; generate for(j=0; j<P_Size; j=j+1 ) begin : block_a assign r[j] = data[(j+1)*P_Width-1:j*P_Width]; end endgenerate assign out = r[sel]; endmodule Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Doka 1 13 июня, 2007 Опубликовано 13 июня, 2007 · Жалоба module MBusMux4 #(parameter P_Width = 1, B_Count = 4, Sel_Bus_Width = 2) ( input [P_Width-1:0] in[B_Count - 1: 0], output [P_Width-1:0] out, input [Sel_Bus_Width - 1:0] sel ); assign out = in[sel]; endmodule в XST жалуется на строчку >>> input [P_Width-1:0] in[b_Count - 1: 0], ERROR:HDLCompilers:26 - "mux_param.v" line 5 expecting ')', found '[' Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
CaPpuCcino 0 13 июня, 2007 Опубликовано 13 июня, 2007 · Жалоба в XST жалуется на строчку >>> input [P_Width-1:0] in[b_Count - 1: 0], ERROR:HDLCompilers:26 - "mux_param.v" line 5 expecting ')', found '[' попробуйте пакованный массив input [b_Count - 1: 0] [P_Width-1:0] in, хотя кажись Ксайлинковский компиллер вообще не поддерживает СВ, а вот альтера должна поддерживать один из вариантов (ток не помню какой -- пакованный или непакованный) (раньше тоже пользовался жирной шиной даже для коммутаторов Н*М, но немного запарно распихивать всё по генерэйтам - всё-таки СВ намного удобнее) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
MurrVK 0 13 июня, 2007 Опубликовано 13 июня, 2007 · Жалоба Да, я погарячился, в моей записи действительно какие-то проблемы. Попробую разобраться. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dxp 34 13 июня, 2007 Опубликовано 13 июня, 2007 · Жалоба Была у меня такая проблема при построении дерева сумматоров на verilog. Пришлось делать один широкий вход и разбирать его на шины уже внутри модуля. Вот и я пошел по тому же пути. Главное неудобство, имхо, в использовании - надо правильно конкатенацию входных шин делать (чаще всего порядок следования путал). По имени оно и нагляднее и безопаснее. попробуйте пакованный массив input [b_Count - 1: 0] [P_Width-1:0] in, хотя кажись Ксайлинковский компиллер вообще не поддерживает СВ, а вот альтера должна поддерживать один из вариантов (ток не помню какой -- пакованный или непакованный) Квартус в настоящее время поддерживает только одномерные пакованные массивы. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dxp 34 14 июня, 2007 Опубликовано 14 июня, 2007 · Жалоба Разовью тему. Дело в том, что обсуждаемый параметризованный мультиплексор это только часть проблемы. Худо-бедно решаемая. Основная задача состоит в разработке параметризованного контроллера памяти. Собсно, с самим контроллером памяти проблем нет, вопросы возникают насчет того, как его сделать на произвольное количество клиентов. В настоящее время приходится прописывать порты руками - например, три клиента, три порта, каждый из которых включает в себя шину адреса, шину данных на запись, шину данных на чтение, сигнал запроса (rqst) - занятия контроллера клиентом, сигнал разрешения (grant) - предоставление контроллера клиенту, занятость/готовность контроллера памяти на текущей операции (контроллер памяти SDRAM, там есть остановки на авторефреш и на смену страницы) и т.д. Прописывать руками неудобно- нужно порты добавлять/убавлять, арбитр править, в общем, это крайне неудобно и чревато ошибками. Хоцца наконец слепить модуль, для которого указал количество клиентов и цепляй эти клиенты единообразным способом. Тут и повторное использование упрощается, и коллегам гораздо проще и безошибочнее такую вещь юзать. Думал было обойтись с помощью SV интерфейсов - канал доступа оформить в виде интерфейса и задавать массив интерфейсов. Но, похоже, оказалось, что массив интерфейсов есть весчь нелегальная. Даже не знаю, что и думать. Есть идеи? Кто как такие вещи делает? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
iosifk 3 14 июня, 2007 Опубликовано 14 июня, 2007 · Жалоба Разовью тему. ... Хоцца наконец слепить модуль, для которого указал количество клиентов и цепляй эти клиенты единообразным способом. Тут и повторное использование упрощается, и коллегам гораздо проще и безошибочнее такую вещь юзать. Думал было обойтись с помощью SV интерфейсов - канал доступа оформить в виде интерфейса и задавать массив интерфейсов. Но, похоже, оказалось, что массив интерфейсов есть весчь нелегальная. Даже не знаю, что и думать. Есть идеи? Кто как такие вещи делает? Я такого типа вещи обхожу таким образом. В вериложном файле пишу ключевой комментарий: "коммутатор начинается отсюда" и до "заканчивается здесь"... Далее в BCB пишу софт, который читает файл, ищет "от" и "до", стирает старое содержимое и вставляет новое. А в ВСВ я делаю все, что хочу. Ну и таким же способом добавляю номер версии, даты прошивок и прочее. Еще очень удобно по названиям пинов из верхнего проекта автоматически генерить все начала вериложного файла - от портов до буферов и проводов. И uсf к ним в придачу. Просто мне так проще... Удачи! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
CaPpuCcino 0 14 июня, 2007 Опубликовано 14 июня, 2007 · Жалоба Но, похоже, оказалось, что массив интерфейсов есть весчь нелегальная. по этому поводу у меня есть для вас хорошая и плохая новость. начну с хорошей: interface FIFO_interface #(parameter number_of_subbuses=1, parameter addr_bus_width=30, parameter bank_selector_width=2, parameter burst_length=4, parameter data_width=128); logic [number_of_subbuses-1:0][addr_bus_width+bank_selector_width-1:0] ADDR_data_write_bundle; logic [number_of_subbuses-1:0][(burst_length+1)-1:0] CMD_data_write_bundle; logic [number_of_subbuses-1:0]ADDR_write_op_req_bundle; logic [number_of_subbuses-1:0]ADDR_write_op_gnt_bundle; logic [number_of_subbuses-1:0][data_width-1:0] DATA_OUT_data_write_bundle; logic [number_of_subbuses-1:0]DATA_OUT_write_op_req_bundle; logic [number_of_subbuses-1:0]DATA_OUT_write_op_gnt_bundle; logic [number_of_subbuses-1:0]DATA_OUT_write_op_forward_gnt_bundle; logic [number_of_subbuses-1:0][data_width-1:0] DATA_IN_data_read_bundle; logic [number_of_subbuses-1:0]DATA_IN_read_op_req_bundle; logic [number_of_subbuses-1:0]DATA_IN_read_op_gnt_bundle; logic [number_of_subbuses-1:0]DATA_IN_read_op_forward_gnt_bundle; modport switch_slave ( input ADDR_data_write_bundle, input CMD_data_write_bundle, input ADDR_write_op_req_bundle, output ADDR_write_op_gnt_bundle, input DATA_OUT_data_write_bundle, input DATA_OUT_write_op_req_bundle, output DATA_OUT_write_op_gnt_bundle, output DATA_OUT_write_op_forward_gnt_bundle, output DATA_IN_data_read_bundle, input DATA_IN_read_op_req_bundle, output DATA_IN_read_op_gnt_bundle, output DATA_IN_read_op_forward_gnt_bundle ); ///////////////////////////!!!!!!!!!!!!! ATTENTION HERE !!!!!!!!!!!!!////////////////////////////////////////////////////////////////////////// genvar i; generate for (i=1; i<number_of_subbuses; i++) begin:subbus modport master ( output .ADDR_data_write(ADDR_data_write_bundle[i-1]), output .CMD_data_write(CMD_data_write_bundle[i-1]), output .ADDR_write_op_req(ADDR_write_op_req_bundle[i-1]), input .ADDR_write_op_gnt(ADDR_write_op_gnt_bundle[i-1]), output .DATA_OUT_data_write(DATA_OUT_data_write_bundle[i-1]), output .DATA_OUT_write_op_req(DATA_OUT_write_op_req_bundle[i-1]), input .DATA_OUT_write_op_gnt(DATA_OUT_write_op_gnt_bundle[i-1]), input .DATA_OUT_write_op_forward_gnt(DATA_OUT_write_op_forward_gnt_bundle[i-1]), input .DATA_IN_data_read(DATA_IN_data_read_bundle[i-1]), output .DATA_IN_read_op_req(DATA_IN_read_op_req_bundle[i-1]), input .DATA_IN_read_op_gnt(DATA_IN_read_op_gnt_bundle[i-1]), input .DATA_IN_read_op_forward_gnt(DATA_IN_read_op_forward_gnt_bundle[i-1]) ); modport slave ( input .ADDR_data_write(ADDR_data_write_bundle[i-1]), input .CMD_data_write(CMD_data_write_bundle[i-1]), input .ADDR_write_op_req(ADDR_write_op_req_bundle[i-1]), output .ADDR_write_op_gnt(ADDR_write_op_gnt_bundle[i-1]), input .DATA_OUT_data_write(DATA_OUT_data_write_bundle[i-1]), input .DATA_OUT_write_op_req(DATA_OUT_write_op_req_bundle[i-1]), output .DATA_OUT_write_op_gnt(DATA_OUT_write_op_gnt_bundle[i-1]), output .DATA_OUT_write_op_forward_gnt(DATA_OUT_write_op_forward_gnt_bundle[i-1]), output .DATA_IN_data_read(DATA_IN_data_read_bundle[i-1]), input .DATA_IN_read_op_req(DATA_IN_read_op_req_bundle[i-1]), output .DATA_IN_read_op_gnt(DATA_IN_read_op_gnt_bundle[i-1]), output .DATA_IN_read_op_forward_gnt(DATA_IN_read_op_forward_gnt_bundle[i-1]) ); end endgenerate endinterface если не разберётесь что тут происходит то матчасть: IEEE Std 1800-2005 стр. 359-360 20.4.4 Modeport expressions плохая новость: для того чтобы делать такое вам нужен компилятор действительно поддерживающий СистемВерилог - Альтера с таким не справиться касаемо того как я обходил подобные проблемы на V2К1. там как наверное помните многомерные массивы уже появились - а вот как порты их почему-то всё ещё нельзя было пользовать. делал плоский массив для каждой шины. все шины собирал в двухмерный массив. потом делал из двухмерного снова плоский - и вот этот плоский уже пускал в порт. с другой стороны эту жирную шину так же разбирал (в обратном порядке) generate-ом. немного уродливо - но работает без вопросов и автоматически (за счёт генерэйта) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dxp 34 15 июня, 2007 Опубликовано 15 июня, 2007 · Жалоба Я такого типа вещи обхожу таким образом. В вериложном файле пишу ключевой комментарий: "коммутатор начинается отсюда" и до "заканчивается здесь"... Далее в BCB пишу софт, который читает файл, ищет "от" и "до", стирает старое содержимое и вставляет новое. А в ВСВ я делаю все, что хочу. Ну и таким же способом добавляю номер версии, даты прошивок и прочее. Еще очень удобно по названиям пинов из верхнего проекта автоматически генерить все начала вериложного файла - от портов до буферов и проводов. И uсf к ним в придачу. Просто мне так проще... Т.е. типа мегавизарда своего написать. Что ж, может и вариант. :a14: по этому поводу у меня есть для вас хорошая и плохая новость. начну с хорошей: [...] если не разберётесь что тут происходит то матчасть: IEEE Std 1800-2005 стр. 359-360 20.4.4 Modeport expressions плохая новость: для того чтобы делать такое вам нужен компилятор действительно поддерживающий СистемВерилог - Альтера с таким не справиться Что можно сделать на СВ, не сомневался ни секунды. То, что Квартус не поддерживает генерацию в модпортах, в курсе. Из доступних синтезеров, умеющих СВ в полной мере, насколько понимаю, есть только Прецижн. К сожалению, тут есть сомнения насчет того, что он выдает адекватную по скорости генерацию (по сравнению с Квартусом) - как-то пробовал простой дизайн, что-то Прецижн там подотстал от Квартсуса и Синплифая. Может, конечно, я там что-то в настройках не прочухал, но это вряд ли - не особенно там опций много. Вторая плохая новость для меня тут в том, что и используемый мною симулятор (Актив-ХДЛ) тоже не далеко не до конца поддерживает СВ (те же структуры, например, не держит), поэтому с таким инструментарием лезть в дебри СВ, имхо, глупо. А менять весь тулчейн с ходу тоже не улыбается - времени на это просто нет. Придецца лепить костыли. Хм, простая, в общем-то, вещь - задать по параметру количество портов у модуля, а до сих пор в широкораспространенном языке (Верилог) не решена. Как же они с такими вещами-то до сих пор жили? Неужто руками все разруливали? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
CaPpuCcino 0 15 июня, 2007 Опубликовано 15 июня, 2007 · Жалоба Хм, простая, в общем-то, вещь - задать по параметру количество портов у модуля, а до сих пор в широкораспространенном языке (Верилог) не решена. Как же они с такими вещами-то до сих пор жили? Неужто руками все разруливали? да нет -- посмотрите концовку моего поста - запихивайте хоть все сигналы в одну плоскую мега-шину, а дальше генерэйтиком - регулярность то есть -- значит генерэйтовский цикл отлично подойдёт - в принципе могу даж какой-нить исходничек для примера заслать в личку (если нужно конечно) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться