Difference between revisions of "Simple port modification"
From Verific Design Automation FAQ
(Created page with "This example converts module with struct ports into flat ports. <nowiki> from invio import * set_preference("invio_insert_ports_with_newline", 1) add_sv_file("test.sv") ana...") |
|||
| Line 9: | Line 9: | ||
elaborate("top") | elaborate("top") | ||
| − | # Convert | + | # Convert instance of the module with struct ports into flat ports |
| − | + | mod = get_modules("child").first | |
| − | for | + | 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 | p_type = p.data_type | ||
| − | |||
if (p_type.is_named_user_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 | # Create new ports for each memeber and add them to the module | ||
for m in p_type.members: | for m in p_type.members: | ||
| + | portname = f"{p.base_name}_{m.base_name}" | ||
dims = [] | dims = [] | ||
for d in m.dimensions: | for d in m.dimensions: | ||
dims.append( (d.left_index, d.right_index) ) | dims.append( (d.left_index, d.right_index) ) | ||
# Create a port with the same attributes as struct memebers | # Create a port with the same attributes as struct memebers | ||
| − | new_port = create_port( | + | 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 the old struct port | ||
delete_object(p) | 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 out the modifications | ||
| Line 42: | Line 71: | ||
} bus_t; | } 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)( | module top #(WIDTH = 4)( | ||
| − | input bus_t | + | input bus_t top_in_bus, |
| + | input [0:WIDTH-1] a, | ||
output [0:WIDTH-1] d, | 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 | endmodule | ||
| Line 62: | Line 103: | ||
} bus_t; | } 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)( | module top #(WIDTH = 4)( | ||
| − | + | input bus_t top_in_bus, | |
input [0:WIDTH-1] a, | 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 | endmodule | ||
</nowiki> | </nowiki> | ||
Latest revision as of 15:39, 8 November 2024
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