Simple port modification
From Verific Design Automation FAQ
This example converts module with struct ports into flat ports.
from invio import *
set_preference("invio_insert_ports_with_newline", 1)
add_sv_file("test.sv")
analyze()
elaborate("top")
# Convert instance of the module with struct ports into flat ports
mod = get_modules("child").first
for i in get_instances(mod):
for p in i.portmaps:
pin = p.pin
if pin and pin.data_type.is_named_user_type:
print(f'... Replacing portmap: {p.full_name}')
portmap = ''
for m in pin.data_type.members:
portmap = portmap + f'.{pin.base_name}_{m.base_name} ({p.connected.first.base_name}.{m.base_name})' + ', \n'
rt = create_raw_text_object(ref=p)
replace_orig_text_of_object(rt, portmap[:len(portmap)-3]) # trim off the last ', '
# You will need to write out the modification and relaod to see the effect of text replacement in the parse tree.
# Replace the assignment with raw text
a = get_assigns(mod).first
new_assign = """assign out_bus_clk = in_bus_clk;
assign out_bus_rst = in_bus_rst;
assign out_bus_addr = in_bus_addr;
assign out_bus_data = in_bus_data;
"""
print(f'... Replacing assignment: {a.full_name}')
replace_orig_text_of_object(a, new_assign)
# flatten the ports
new_ports = []
for p in get_ports(mod):
p_type = p.data_type
if (p_type.is_named_user_type):
print(f'... Replacing port: {p.full_name}')
# Create new ports for each memeber and add them to the module
for m in p_type.members:
portname = f"{p.base_name}_{m.base_name}"
dims = []
for d in m.dimensions:
dims.append( (d.left_index, d.right_index) )
# Create a port with the same attributes as struct memebers
new_port = create_port(portname, p.direction, datatype_name=m.data_type_name, dimensions=dims);
new_ports.append(new_port)
# Delete the old struct port
delete_object(p)
# Insert them into top module after removing the old ports
for p in new_ports:
insert_into(p, mod)
# Write out the modifications
write_modified_file("test.sv", "test_mod.sv")
"test.sv"
typedef struct {
logic clk;
logic rst;
logic [1:0] addr;
int data;
} bus_t;
module child (
input bus_t in_bus,
output bus_t out_bus
);
assign out_bus = in_bus;
endmodule // child
module top #(WIDTH = 4)(
input bus_t top_in_bus,
input [0:WIDTH-1] a,
output [0:WIDTH-1] d,
output bus_t top_out_bus
) ;
child u_child (
.in_bus (top_in_bus),
.out_bus (top_out_bus)
);
endmodule
Testcase after modification, "test_mod.sv":
typedef struct {
logic clk;
logic rst;
logic [1:0] addr;
int data;
} bus_t;
module child (
input logic in_bus_clk,
input logic in_bus_rst,
input logic [1:0] in_bus_addr,
input int in_bus_data,
output logic out_bus_clk,
output logic out_bus_rst,
output logic [1:0] out_bus_addr,
output int out_bus_data
);
assign out_bus_clk = in_bus_clk;
assign out_bus_rst = in_bus_rst;
assign out_bus_addr = in_bus_addr;
assign out_bus_data = in_bus_data;
endmodule // child
module top #(WIDTH = 4)(
input bus_t top_in_bus,
input [0:WIDTH-1] a,
output [0:WIDTH-1] d,
output bus_t top_out_bus
) ;
child u_child (
.in_bus_clk (top_in_bus.clk),
.in_bus_rst (top_in_bus.rst),
.in_bus_addr (top_in_bus.addr),
.in_bus_data (top_in_bus.data),
.out_bus_clk (top_out_bus.clk),
.out_bus_rst (top_out_bus.rst),
.out_bus_addr (top_out_bus.addr),
.out_bus_data (top_out_bus.data)
);
endmodule