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