Jul'etta 0 13 ноября, 2017 Опубликовано 13 ноября, 2017 · Жалоба Уважаемые плисоводы! Не могу найти информацию и/или доступные примеры, помогите, пожалуйста со следующей задачей. Имеется модуль, в котором объявлены 32-разрядные регистры некоторого устройства, например, 2 регистра: reg_control и reg_status. Кроме модуля, в котором эти регистры объявлены, имеется второй модуль, в котором они используются. И вот чего я не могу понять: как объявить конкретные поля под конкретные значения в одном модуле и потом передать эти поля как часть регистра в другой модуль? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Mad_kvmg 0 13 ноября, 2017 Опубликовано 13 ноября, 2017 · Жалоба Уважаемые плисоводы! Не могу найти информацию и/или доступные примеры, помогите, пожалуйста со следующей задачей. Имеется модуль, в котором объявлены 32-разрядные регистры некоторого устройства, например, 2 регистра: reg_control и reg_status. Кроме модуля, в котором эти регистры объявлены, имеется второй модуль, в котором они используются. И вот чего я не могу понять: как объявить конкретные поля под конкретные значения в одном модуле и потом передать эти поля как часть регистра в другой модуль? На SV можно было бы объявить регистры как структуры с нужными полями, далее структуры передавать через порты модулей. Или даже структуру поместить в интерфейс, тогда и поля регистров и другие сигналы можно было бы передавать через порты модулей одной строкой (удобно и красиво). На проcто V можно подразумевать такой же подход, но реализовывать через reg и в явном виде передавать через порты модулей. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Jul'etta 0 13 ноября, 2017 Опубликовано 13 ноября, 2017 · Жалоба На SV можно было бы объявить регистры как структуры с нужными полями, далее структуры передавать через порты модулей. Или даже структуру поместить в интерфейс, тогда и поля регистров и другие сигналы можно было бы передавать через порты модулей одной строкой (удобно и красиво). На проcто V можно подразумевать такой же подход, но реализовывать через reg и в явном виде передавать через порты модулей. у меня просто Verilog. Вот как я объявила поля регистров в первом модуле (на примере регистра status): // Reg Status assign stts_overflow_fifo = Reg_Status_r[31:25]; assign stts_op_code = Reg_Status_r[24:17]; assign stts_status = Reg_Status_r[16:9]; assign stts_add_inf = Reg_Status_r[8:0]; Я не поняла Ваше объяснение про передачу в другой модуль. Синтаксис как ".port_name(signal)" ? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Mad_kvmg 0 13 ноября, 2017 Опубликовано 13 ноября, 2017 · Жалоба у меня просто Verilog. Вот как я объявила поля регистров в первом модуле (на примере регистра status): // Reg Status assign stts_overflow_fifo = Reg_Status_r[31:25]; assign stts_op_code = Reg_Status_r[24:17]; assign stts_status = Reg_Status_r[16:9]; assign stts_add_inf = Reg_Status_r[8:0]; Я не поняла Ваше объяснение про передачу в другой модуль. Синтаксис как ".port_name(signal)" ? Ну вот ваши stts_overflow_fifo, stts_op_code и т.д. делаете выходными портами первого модуля и подаете на входные порты второго модуля. Продумайте только имена портов, где вход где выход, что бы не запутаться. По другому никак. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Shivers 0 13 ноября, 2017 Опубликовано 13 ноября, 2017 · Жалоба На SV можно было бы объявить регистры как структуры с нужными полями, далее структуры передавать через порты модулей. Или даже структуру поместить в интерфейс, тогда и поля регистров и другие сигналы можно было бы передавать через порты модулей одной строкой (удобно и красиво). Очень интересный вопрос кстати, по использованию SV и интерфейсов - исключительно удобно для дизайна! Если бы не одно НО. Когда проектируется эсик, то уже после закачки RTL в тул синтеза (DC/Genus), на дженерик уровне все эти интерфейсы флатуются, преобразовывая имена во что то неудобоваримое. Результирующий нетлист (verilog де-факто) так же содержит только расфлатованные интерфейсы, в которых тяжело найти исходные сигналы. Получается, кодить то на SV - красивее и проще, а вот писать констрейнты и, главное, дебажить потом - боль жуткая. Агитирую коллег поменьше увлекаться SV, особенно на верхнем уровне иерархии. Ситуация изменится только когда пост-синтез/пост-лейаут нетлист можно будет сохранять в формате SV. Подозреваю, будет это не скоро. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Jul'etta 0 13 ноября, 2017 Опубликовано 13 ноября, 2017 · Жалоба Ну вот ваши stts_overflow_fifo, stts_op_code и т.д. делаете выходными портами первого модуля и подаете на входные порты второго модуля. Продумайте только имена портов, где вход где выход, что бы не запутаться. По другому никак. Ааа, вот кажется теперь поняла. Посмотрите, пожалуйста, верно ли // first module `include "Corr_Header.v" module sm_registers (clk, rst, stts_overflow_fifo_o, stts_op_code_o, stts_status_o, stts_add_inf_o ); input clk, rst; output stts_overflow_fifo_o; output stts_op_code_o; output stts_status_o; output stts_add_inf_o; assign stts_overflow_fifo = Reg_Status_r[31:25]; assign stts_op_code = Reg_Status_r[24:17]; assign stts_status = Reg_Status_r[16:9]; assign stts_add_inf = Reg_Status_r[8:0]; // second module `include "Corr_Header.v" module SM_Read (clk, rst, stts_overflow_fifo_i, stts_op_code_i, stts_status_i, stts_add_inf_i ); input clk, rst; input stts_overflow_fifo_i; input stts_op_code_i; input stts_status_i; input stts_add_inf_i; Очень интересный вопрос кстати, по использованию SV и интерфейсов - исключительно удобно для дизайна! Если бы не одно НО. Когда проектируется эсик, то уже после закачки RTL в тул синтеза (DC/Genus), на дженерик уровне все эти интерфейсы флатуются, преобразовывая имена во что то неудобоваримое. Результирующий нетлист (verilog де-факто) так же содержит только расфлатованные интерфейсы, в которых тяжело найти исходные сигналы. Получается, кодить то на SV - красивее и проще, а вот писать констрейнты и, главное, дебажить потом - боль жуткая. Агитирую коллег поменьше увлекаться SV, особенно на верхнем уровне иерархии. Ситуация изменится только когда пост-синтез/пост-лейаут нетлист можно будет сохранять в формате SV. Подозреваю, будет это не скоро. с ума сойти. Не использую пока ни SV, ни интерфейсов - не доросла. А кстати, обязательно ли имена полей должны совпадать с именами портов? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
one_eight_seven 6 13 ноября, 2017 Опубликовано 13 ноября, 2017 (изменено) · Жалоба Кроме модуля, в котором эти регистры объявлены, имеется второй модуль, в котором они используются. И вот чего я не могу понять: как объявить конкретные поля под конкретные значения в одном модуле и потом передать эти поля как часть регистра в другой модуль? Я обычно сохраняю регистры, но не пользуюсь численными значениями в объявлении полей. Вместо хард литералов я использую макро. С помощью макро разбиваю регистры на рабочие вектора. assign stts_overflow_fifo = Reg_Status_r[31:25]; assign stts_op_code = Reg_Status_r[24:17]; assign stts_status = Reg_Status_r[16:9]; assign stts_add_inf = Reg_Status_r[8:0] Превращается в: assign stts_overflow_fifo = Reg_Status_r[`OVERFLOW_FIFO_HI:`OVERFLOW_FIFO_LO]; assign stts_op_code = Reg_Status_r[`OPCODE_HI:`OPCODE_LO]; assign stts_status = Reg_Status_r[`STATUS_HI:`STATUS_LO]; assign stts_add_inf = Reg_Status_r[`ADD_INTF_HI:`ADD_INTF_LO] Естественно, данная операция осуществляется во всех модулях, где регистр (Reg_Status_r) используется данным образом. Как вариант можно использовать "опорный" бит и ширину поля. Ну или второй вариант, уже предложенный здесь - в модуле, куда нужно передать сигналы, в качестве входов/выходов задать сразу нужные наименования и ширины векторов. Агитирую коллег поменьше увлекаться SV Поддерживаю. По этой же причине я предпочитаю писать Gate-Level везде, где это возможно, поскольку так Netlist остаётся похожим на RTL-код, в отличие от бихевиорального описания. Посмотрите, пожалуйста, верно ли Ширину векторов забыли указать при определении. А кстати, обязательно ли имена полей должны совпадать с именами портов? Нет. Компилятору нужно лишь точно заданное соответствие подключений. Имена переменных - это для вас и для тех, кто будет с вашим кодом работать. Изменено 13 ноября, 2017 пользователем one_eight_seven Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Mad_kvmg 0 13 ноября, 2017 Опубликовано 13 ноября, 2017 · Жалоба Очень интересный вопрос кстати, по использованию SV и интерфейсов - исключительно удобно для дизайна! Если бы не одно НО. Когда проектируется эсик, то уже после закачки RTL в тул синтеза (DC/Genus), на дженерик уровне все эти интерфейсы флатуются, преобразовывая имена во что то неудобоваримое. Результирующий нетлист (verilog де-факто) так же содержит только расфлатованные интерфейсы, в которых тяжело найти исходные сигналы. Получается, кодить то на SV - красивее и проще, а вот писать констрейнты и, главное, дебажить потом - боль жуткая. Агитирую коллег поменьше увлекаться SV, особенно на верхнем уровне иерархии. Ситуация изменится только когда пост-синтез/пост-лейаут нетлист можно будет сохранять в формате SV. Подозреваю, будет это не скоро. Для FPGA маршрута (синтезаторов) тоже самое. В целом ни чего сложного, простое правило - в файле верхнего уровня использовать "плоский" список портов. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Jul'etta 0 13 ноября, 2017 Опубликовано 13 ноября, 2017 · Жалоба Я обычно сохраняю регистры, но не пользуюсь численными значениями в объявлении полей. Вместо хард литералов я использую макро. С помощью макро разбиваю регистры на рабочие вектора. assign stts_overflow_fifo = Reg_Status_r[31:25]; assign stts_op_code = Reg_Status_r[24:17]; assign stts_status = Reg_Status_r[16:9]; assign stts_add_inf = Reg_Status_r[8:0] Превращается в: assign stts_overflow_fifo = Reg_Status_r[`OVERFLOW_FIFO_HI:`OVERFLOW_FIFO_LO]; assign stts_op_code = Reg_Status_r[`OPCODE_HI:`OPCODE_LO]; assign stts_status = Reg_Status_r[`STATUS_HI:`STATUS_LO]; assign stts_add_inf = Reg_Status_r[`ADD_INTF_HI:`ADD_INTF_LO] Естественно, данная операция осуществляется во всех модулях, где регистр (Reg_Status_r) используется данным образом. Как вариант можно использовать "опорный" бит и ширину поля. Ну или второй вариант, уже предложенный здесь - в модуле, куда нужно передать сигналы, в качестве входов/выходов задать сразу нужные наименования и ширины векторов. Поддерживаю. По этой же причине я предпочитаю писать Gate-Level везде, где это возможно, поскольку так Netlist остаётся похожим на RTL-код, в отличие от бихевиорального описания. Ширину векторов забыли указать при определении. Нет. Компилятору нужно лишь точно заданное соответствие подключений. Имена переменных - это для вас и для тех, кто будет с вашим кодом работать. Ага, а уже в заголовке объявляете через 'define ? просто я так сделала с самими названиями регистров: 'define reg_control 14'h000 'define reg_status 14'h004 .... а оказывается, можно в заголовке и поля так задавать, здорово, только я пока не уверена, за что какие поля у меня будут отвечать. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
_Sam_ 0 13 ноября, 2017 Опубликовано 13 ноября, 2017 · Жалоба reg_control и reg_status wire control; wire status; module first_module( output wire control, output wire status ); assign control = 1'b1; assign status = 1'b0; endmodule module second_module( input wire control, input wire status ); endmodule first_module FIRST(.control, .status); second_module SECOND(.control, .status); `include "Corr_Header.v" module sm_registers (clk, rst, stts_overflow_fifo_o, stts_op_code_o, stts_status_o, stts_add_inf_o ); input clk, rst; output stts_overflow_fifo_o; output stts_op_code_o; output stts_status_o; output stts_add_inf_o; Не надо пожалуйста писать так. Пишите так: module sm_registers ( input wire clk, input wire rst, output wire stts_overflow_fifo_o, output wire stts_op_code_o, output wire stts_status_o, output wire stts_add_inf_o ); output stts_overflow_fifo_o; assign stts_overflow_fifo = Reg_Status_r[31:25]; Как уже писали выше надо stts_overflow_fifo_o привести к виду wire [5:0]stts_overflow_fifo и определить RegStatus_r Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
one_eight_seven 6 13 ноября, 2017 Опубликовано 13 ноября, 2017 · Жалоба а оказывается, можно в заголовке и поля так задавать, здорово Почему нет? Макроопределение - это просто текстовая замена. т.е.: `define MACRO (EXPRESSION) приведёт к тому, что все вхождения `MACRO будут заменены на (EXPRESSION). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Jul'etta 0 13 ноября, 2017 Опубликовано 13 ноября, 2017 · Жалоба Пишите так: module sm_registers ( input wire clk, input wire rst, output wire stts_overflow_fifo_o, output wire stts_op_code_o, output wire stts_status_o, output wire stts_add_inf_o ); Как уже писали выше надо stts_overflow_fifo_o привести к виду wire [5:0]stts_overflow_fifo и определить RegStatus_r да, видела такой стиль (когда читала книгу В.В. Соловьева по основам проектирования на верилог). Так лаконичней, согласна, но мне милей все отдельно обозначать. Почему нет? Макроопределение - это просто текстовая замена. т.е.: `define MACRO (EXPRESSION) приведёт к тому, что все вхождения `MACRO будут заменены на (EXPRESSION). Спасибо, не додумалась :) буду иметь ввиду. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dvladim 0 13 ноября, 2017 Опубликовано 13 ноября, 2017 · Жалоба Так лаконичней, согласна, но мне милей все отдельно обозначать. Двойная работа - бессмысленная. И wire писать необязательно. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться