Difference between revisions of "Simple port modification"

From Verific Design Automation FAQ
Jump to: navigation, search
(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 top module with struct ports into flat ports  
+
# Convert instance of the module with struct ports into flat ports  
top_module_obj = get_modules("top").first
+
mod = get_modules("child").first
for p in get_ports(top_module_obj):
+
for i in get_instances(mod):
     #report_attributes(p) # for debugging purposes you can print the attributes and see what is going on
+
     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
    # Filter the user type ports
 
 
     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(m.base_name, p.direction, datatype_name=m.data_type_name, dimensions=dims);
+
             new_port = create_port(portname, p.direction, datatype_name=m.data_type_name, dimensions=dims);
             # Insert them into top module
+
             new_ports.append(new_port)
            insert_into(new_port, top_module_obj)
+
  
 
         # 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
  
// Convert the struct port into flat ports
 
 
module top #(WIDTH = 4)(
 
module top #(WIDTH = 4)(
   input bus_t in_bus, // this one
+
   input bus_t top_in_bus,
 +
  input [0:WIDTH-1] a,
 
   output [0:WIDTH-1] d,
 
   output [0:WIDTH-1] d,
   input [0:WIDTH-1] a
+
   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
  
// Convert the struct port into flat ports
 
 
module top #(WIDTH = 4)(
 
module top #(WIDTH = 4)(
   output [0:WIDTH-1] d,
+
   input bus_t top_in_bus,  
 
   input [0:WIDTH-1] a,
 
   input [0:WIDTH-1] a,
input logic clk,
+
  output [0:WIDTH-1] d,
input logic rst,
+
  output bus_t top_out_bus
input logic [1:0] addr,
+
input int data
+
 
) ;
 
) ;
 +
 +
  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