Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: объявление и передача в другой модуль полей регистра на Verilog
Форум разработчиков электроники ELECTRONIX.ru > Программируемая логика ПЛИС (FPGA,CPLD, PLD) > Языки проектирования на ПЛИС (FPGA)
Jul'etta
Уважаемые плисоводы! Не могу найти информацию и/или доступные примеры, помогите, пожалуйста со следующей задачей.
Имеется модуль, в котором объявлены 32-разрядные регистры некоторого устройства, например, 2 регистра: reg_control и reg_status. Кроме модуля, в котором эти регистры объявлены, имеется второй модуль, в котором они используются. И вот чего я не могу понять: как объявить конкретные поля под конкретные значения в одном модуле и потом передать эти поля как часть регистра в другой модуль?
Mad_max
Цитата(Jul'etta @ Nov 13 2017, 11:33) *
Уважаемые плисоводы! Не могу найти информацию и/или доступные примеры, помогите, пожалуйста со следующей задачей.
Имеется модуль, в котором объявлены 32-разрядные регистры некоторого устройства, например, 2 регистра: reg_control и reg_status. Кроме модуля, в котором эти регистры объявлены, имеется второй модуль, в котором они используются. И вот чего я не могу понять: как объявить конкретные поля под конкретные значения в одном модуле и потом передать эти поля как часть регистра в другой модуль?


На SV можно было бы объявить регистры как структуры с нужными полями, далее структуры передавать через порты модулей.
Или даже структуру поместить в интерфейс, тогда и поля регистров и другие сигналы можно было бы передавать через порты модулей одной строкой (удобно и красиво).

На проcто V можно подразумевать такой же подход, но реализовывать через reg и в явном виде передавать через порты модулей.
Jul'etta
Цитата(Mad_max @ Nov 13 2017, 08:52) *
На 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_max
Цитата(Jul'etta @ Nov 13 2017, 12:07) *
у меня просто 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
Цитата(Mad_max @ Nov 13 2017, 11:52) *
На SV можно было бы объявить регистры как структуры с нужными полями, далее структуры передавать через порты модулей.
Или даже структуру поместить в интерфейс, тогда и поля регистров и другие сигналы можно было бы передавать через порты модулей одной строкой (удобно и красиво).

Очень интересный вопрос кстати, по использованию SV и интерфейсов - исключительно удобно для дизайна! Если бы не одно НО. Когда проектируется эсик, то уже после закачки RTL в тул синтеза (DC/Genus), на дженерик уровне все эти интерфейсы флатуются, преобразовывая имена во что то неудобоваримое. Результирующий нетлист (verilog де-факто) так же содержит только расфлатованные интерфейсы, в которых тяжело найти исходные сигналы. Получается, кодить то на SV - красивее и проще, а вот писать констрейнты и, главное, дебажить потом - боль жуткая. Агитирую коллег поменьше увлекаться SV, особенно на верхнем уровне иерархии. Ситуация изменится только когда пост-синтез/пост-лейаут нетлист можно будет сохранять в формате SV. Подозреваю, будет это не скоро.
Jul'etta
Цитата(Mad_max @ Nov 13 2017, 09:13) *
Ну вот ваши 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;

Цитата(Shivers @ Nov 13 2017, 09:29) *
Очень интересный вопрос кстати, по использованию SV и интерфейсов - исключительно удобно для дизайна! Если бы не одно НО. Когда проектируется эсик, то уже после закачки RTL в тул синтеза (DC/Genus), на дженерик уровне все эти интерфейсы флатуются, преобразовывая имена во что то неудобоваримое. Результирующий нетлист (verilog де-факто) так же содержит только расфлатованные интерфейсы, в которых тяжело найти исходные сигналы. Получается, кодить то на SV - красивее и проще, а вот писать констрейнты и, главное, дебажить потом - боль жуткая. Агитирую коллег поменьше увлекаться SV, особенно на верхнем уровне иерархии. Ситуация изменится только когда пост-синтез/пост-лейаут нетлист можно будет сохранять в формате SV. Подозреваю, будет это не скоро.



wacko.gif с ума сойти. Не использую пока ни SV, ни интерфейсов - не доросла.

А кстати, обязательно ли имена полей должны совпадать с именами портов?
one_eight_seven
Цитата
Кроме модуля, в котором эти регистры объявлены, имеется второй модуль, в котором они используются. И вот чего я не могу понять: как объявить конкретные поля под конкретные значения в одном модуле и потом передать эти поля как часть регистра в другой модуль?

Я обычно сохраняю регистры, но не пользуюсь численными значениями в объявлении полей. Вместо хард литералов я использую макро. С помощью макро разбиваю регистры на рабочие вектора.
Код
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-код, в отличие от бихевиорального описания.

Цитата
Посмотрите, пожалуйста, верно ли

Ширину векторов забыли указать при определении.

Цитата
А кстати, обязательно ли имена полей должны совпадать с именами портов?

Нет. Компилятору нужно лишь точно заданное соответствие подключений. Имена переменных - это для вас и для тех, кто будет с вашим кодом работать.
Mad_max
Цитата(Shivers @ Nov 13 2017, 12:29) *
Очень интересный вопрос кстати, по использованию SV и интерфейсов - исключительно удобно для дизайна! Если бы не одно НО. Когда проектируется эсик, то уже после закачки RTL в тул синтеза (DC/Genus), на дженерик уровне все эти интерфейсы флатуются, преобразовывая имена во что то неудобоваримое. Результирующий нетлист (verilog де-факто) так же содержит только расфлатованные интерфейсы, в которых тяжело найти исходные сигналы. Получается, кодить то на SV - красивее и проще, а вот писать констрейнты и, главное, дебажить потом - боль жуткая. Агитирую коллег поменьше увлекаться SV, особенно на верхнем уровне иерархии. Ситуация изменится только когда пост-синтез/пост-лейаут нетлист можно будет сохранять в формате SV. Подозреваю, будет это не скоро.

Для FPGA маршрута (синтезаторов) тоже самое.
В целом ни чего сложного, простое правило - в файле верхнего уровня использовать "плоский" список портов.
Jul'etta
Цитата(one_eight_seven @ Nov 13 2017, 09:57) *
Я обычно сохраняю регистры, но не пользуюсь численными значениями в объявлении полей. Вместо хард литералов я использую макро. С помощью макро разбиваю регистры на рабочие вектора.
Код
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_
Цитата
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
Цитата
а оказывается, можно в заголовке и поля так задавать, здорово

Почему нет? Макроопределение - это просто текстовая замена. т.е.:
`define MACRO (EXPRESSION)

приведёт к тому, что все вхождения `MACRO будут заменены на (EXPRESSION).
Jul'etta

Пишите так:

Код
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
[/quote]

да, видела такой стиль (когда читала книгу В.В. Соловьева по основам проектирования на верилог). Так лаконичней, согласна, но мне милей все отдельно обозначать.

Цитата(one_eight_seven @ Nov 13 2017, 11:41) *
Почему нет? Макроопределение - это просто текстовая замена. т.е.:
`define MACRO (EXPRESSION)

приведёт к тому, что все вхождения `MACRO будут заменены на (EXPRESSION).


Спасибо, не додумалась sm.gif буду иметь ввиду.
dvladim
Цитата(Jul'etta @ Nov 13 2017, 14:02) *
Так лаконичней, согласна, но мне милей все отдельно обозначать.

Двойная работа - бессмысленная. И wire писать необязательно.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2024 Invision Power Services, Inc.