diff --git a/Makefile b/Makefile index c03c774b2..cc9832778 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,8 @@ CORE := iob_soc SIMULATOR ?= icarus +DISABLE_LINT:=1 + include submodules/LIB/setup.mk INIT_MEM ?= 1 diff --git a/hardware/src/ext_mem.v b/hardware/src/ext_mem.v index 8abc9bf36..1423da78a 100644 --- a/hardware/src/ext_mem.v +++ b/hardware/src/ext_mem.v @@ -31,25 +31,6 @@ module ext_mem #( // INSTRUCTION CACHE // - // IOb ready and rvalid signals - wire i_ack; - reg i_wr_e; // Instruction write enable register - reg i_ready; - iob_reg_e #( - .DATA_W (1), - .RST_VAL(0) - ) i_wr_e_reg ( - .clk_i (clk_i), - .arst_i(arst_i), - .cke_i (cke_i), - .en_i (i_req[1+FIRM_ADDR_W-2+`WRITE_W-1]), - .data_i({|i_req[`WSTRB(0)]}), - .data_o(i_wr_e) - ); - //iob_reg_e #(1,1) i_ready_reg (clk_i, arst_i, cke_i, i_ack | i_req[1+FIRM_ADDR_W-2+`WRITE_W-1], i_ack, i_ready); - assign i_resp[`RVALID(0)] = i_wr_e ? 1'b0 : i_ack; - assign i_resp[`READY(0)] = i_ack; - // Back-end bus wire [1+MEM_ADDR_W+`WRITE_W-1:0] icache_be_req; wire [ `RESP_W-1:0] icache_be_resp; @@ -66,28 +47,31 @@ module ext_mem #( .USE_CTRL (0), //Cache-Control can't be accessed .USE_CTRL_CNT (0) //Remove counters ) icache ( - .clk_i(clk_i), - .rst_i(arst_i), + .clk_i (clk_i), + .cke_i (cke_i), + .arst_i(arst_i), // Front-end interface - .req (i_req[1+FIRM_ADDR_W-2+`WRITE_W-1]), + .avalid (i_req[1+FIRM_ADDR_W-2+`WRITE_W-1]), .addr (i_req[`ADDRESS(0, FIRM_ADDR_W-2)]), .wdata (i_req[`WDATA(0)]), .wstrb (i_req[`WSTRB(0)]), .rdata (i_resp[`RDATA(0)]), - .ack (i_ack), + .rvalid (i_resp[`RVALID(0)]), + .ready (i_resp[`READY(0)]), //Control IO .invalidate_in (1'b0), .invalidate_out(), .wtb_empty_in (1'b1), .wtb_empty_out (), // Back-end interface - .be_req (icache_be_req[1+MEM_ADDR_W+`WRITE_W-1]), + .be_avalid (icache_be_req[1+MEM_ADDR_W+`WRITE_W-1]), .be_addr (icache_be_req[`ADDRESS(0, MEM_ADDR_W)]), .be_wdata (icache_be_req[`WDATA(0)]), .be_wstrb (icache_be_req[`WSTRB(0)]), .be_rdata (icache_be_resp[`RDATA(0)]), - .be_ack (icache_be_resp[`READY(0)]) + .be_rvalid (icache_be_resp[`RVALID(0)]), + .be_ready (icache_be_resp[`READY(0)]) ); //l2 cache interface signals @@ -111,23 +95,6 @@ module ext_mem #( // // IOb ready and rvalid signals - wire d_ack; - reg d_wr_e; // Instruction write enable register - reg d_ready; - iob_reg_e #( - .DATA_W (1), - .RST_VAL(0) - ) d_wr_e_reg ( - .clk_i (clk_i), - .arst_i(arst_i), - .cke_i (cke_i), - .en_i (d_req[1+FIRM_ADDR_W-2+`WRITE_W-1]), - .data_i({|d_req[`WSTRB(0)]}), - .data_o(d_wr_e) - ); - //iob_reg_e #(1,0) d_ready_reg (clk_i, arst_i, cke_i, d_ack | d_req[1+FIRM_ADDR_W-2+`WRITE_W-1], ~d_req[1+FIRM_ADDR_W-2+`WRITE_W-1], d_ready); - assign d_resp[`RVALID(0)] = i_wr_e ? 1'b0 : d_ack; - assign d_resp[`READY(0)] = d_ack; // Back-end bus wire [1+MEM_ADDR_W+`WRITE_W-1:0] dcache_be_req; @@ -144,28 +111,31 @@ module ext_mem #( .USE_CTRL (1), //Either 1 to enable cache-control or 0 to disable .USE_CTRL_CNT (1) //do not change (it's implementation depends on the previous) ) dcache ( - .clk_i(clk_i), - .rst_i(arst_i), + .clk_i (clk_i), + .cke_i (cke_i), + .arst_i(arst_i), // Front-end interface - .req (d_req[2+MEM_ADDR_W-2+`WRITE_W-1]), + .avalid (d_req[2+MEM_ADDR_W-2+`WRITE_W-1]), .addr (d_req[`ADDRESS(0, 1+MEM_ADDR_W-2)]), .wdata (d_req[`WDATA(0)]), .wstrb (d_req[`WSTRB(0)]), .rdata (d_resp[`RDATA(0)]), - .ack (d_ack), + .rvalid (d_resp[`RVALID(0)]), + .ready (d_resp[`READY(0)]), //Control IO .invalidate_in (1'b0), .invalidate_out(invalidate), .wtb_empty_in (l2_wtb_empty), .wtb_empty_out (), // Back-end interface - .be_req (dcache_be_req[1+MEM_ADDR_W+`WRITE_W-1]), + .be_avalid (dcache_be_req[1+MEM_ADDR_W+`WRITE_W-1]), .be_addr (dcache_be_req[`ADDRESS(0, MEM_ADDR_W)]), .be_wdata (dcache_be_req[`WDATA(0)]), .be_wstrb (dcache_be_req[`WSTRB(0)]), .be_rdata (dcache_be_resp[`RDATA(0)]), - .be_ack (dcache_be_resp[`READY(0)]) + .be_rvalid (dcache_be_resp[`RVALID(0)]), + .be_ready (dcache_be_resp[`READY(0)]) ); // Merge cache back-ends @@ -188,14 +158,16 @@ module ext_mem #( wire [ DATA_W-1:0] l2cache_wdata; wire [ DATA_W/8-1:0] l2cache_wstrb; wire [ DATA_W-1:0] l2cache_rdata; - wire l2cache_ack; + wire l2cache_rvalid; + wire l2cache_ready; - assign l2cache_valid = l2cache_req[1+MEM_ADDR_W+`WRITE_W-1]; - assign l2cache_addr = l2cache_req[`ADDRESS(0, MEM_ADDR_W)-2]; - assign l2cache_wdata = l2cache_req[`WDATA(0)]; - assign l2cache_wstrb = l2cache_req[`WSTRB(0)]; - assign l2cache_resp[`RDATA(0)] = l2cache_rdata; - assign l2cache_resp[`READY(0)] = l2cache_ack; + assign l2cache_valid = l2cache_req[1+MEM_ADDR_W+`WRITE_W-1]; + assign l2cache_addr = l2cache_req[`ADDRESS(0, MEM_ADDR_W)-2]; + assign l2cache_wdata = l2cache_req[`WDATA(0)]; + assign l2cache_wstrb = l2cache_req[`WSTRB(0)]; + assign l2cache_resp[`RDATA(0)] = l2cache_rdata; + assign l2cache_resp[`RVALID(0)] = l2cache_rvalid; + assign l2cache_resp[`READY(0)] = l2cache_ready; // L2 cache instance iob_cache_axi #( @@ -212,12 +184,13 @@ module ext_mem #( .USE_CTRL_CNT (0) //Remove counters ) l2cache ( // Native interface - .req (l2cache_valid), + .avalid (l2cache_valid), .addr (l2cache_addr), .wdata (l2cache_wdata), .wstrb (l2cache_wstrb), .rdata (l2cache_rdata), - .ack (l2cache_ack), + .rvalid (l2cache_rvalid), + .ready (l2cache_ready), //Control IO .invalidate_in (invalidate_reg & ~l2_avalid), .invalidate_out(), @@ -226,7 +199,8 @@ module ext_mem #( // AXI interface `include "iob_axi_m_m_portmap.vs" .clk_i (clk_i), - .rst_i (arst_i) + .cke_i (cke_i), + .arst_i (arst_i) ); endmodule diff --git a/scripts/iob_soc_create_periphs_tmp.py b/scripts/iob_soc_create_periphs_tmp.py index 3a883dd06..341312976 100755 --- a/scripts/iob_soc_create_periphs_tmp.py +++ b/scripts/iob_soc_create_periphs_tmp.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -#Creates periphs_tmp.h +# Creates periphs_tmp.h import sys, os @@ -11,15 +11,19 @@ # peripherals_list: list with amount of instances of each peripheral (returned by get_peripherals()) def create_periphs_tmp(addr_w, peripherals_list, out_file): # Don't override output file - if os.path.isfile(out_file): return + if os.path.isfile(out_file): + return template_contents = [] for instance in peripherals_list: - template_contents.extend("#define {}_BASE ({}<<({}-1-N_SLAVES_W))\n".format(instance.name,instance.name,addr_w)) + template_contents.extend( + "#define {}_BASE ({}<<({}-1-N_SLAVES_W))\n".format( + instance.name, instance.name, addr_w + ) + ) # Write system.v os.makedirs(os.path.dirname(out_file), exist_ok=True) periphs_tmp_file = open(out_file, "w") periphs_tmp_file.writelines(template_contents) periphs_tmp_file.close() - diff --git a/scripts/iob_soc_create_system.py b/scripts/iob_soc_create_system.py index bf955129a..bd2d94b99 100755 --- a/scripts/iob_soc_create_system.py +++ b/scripts/iob_soc_create_system.py @@ -3,7 +3,12 @@ import re import iob_colors -from submodule_utils import get_pio_signals, get_peripherals_ports_params_top, get_reserved_signals, get_reserved_signal_connection +from submodule_utils import ( + get_pio_signals, + get_peripherals_ports_params_top, + get_reserved_signals, + get_reserved_signal_connection, +) from ios import get_peripheral_port_mapping # Automatically include _swreg_def.vh verilog headers after IOB_PRAGMA_PHEADERS comment @@ -16,36 +21,38 @@ def insert_header_files(dest_dir, name, peripherals_list): if module.name not in included_peripherals: included_peripherals.append(module.name) # Only insert swreg file if module has regiters - if hasattr(module,'regs') and module.regs: + if hasattr(module, "regs") and module.regs: top = module.name fd_out.write(f'`include "{top}_swreg_def.vh"\n') fd_out.close() -# Creates the Verilog Snippet (.vs) files required by {top}.v +# Creates the Verilog Snippet (.vs) files required by {top}.v # build_dir: build directory # top: top name of the system # peripherals_list: list of dictionaries each of them describes a peripheral instance # internal_wires: Optional argument. List of extra wires to create inside module def create_systemv(build_dir, top, peripherals_list, internal_wires=None): - num_extmem_connections = 1 # By default, one connection for iob-soc's cache + num_extmem_connections = 1 # By default, one connection for iob-soc's cache latest_extmem_bus_size = -1 - peripherals_with_trap = [] # List of peripherals with trap output + peripherals_with_trap = [] # List of peripherals with trap output - out_dir = os.path.join(build_dir,f'hardware/src/') + out_dir = os.path.join(build_dir, f"hardware/src/") insert_header_files(out_dir, top, peripherals_list) # Get port list, parameter list and top module name for each type of peripheral used - port_list, params_list, top_list = get_peripherals_ports_params_top(peripherals_list) + port_list, params_list, top_list = get_peripherals_ports_params_top( + peripherals_list + ) # Insert internal module wires (if any) periphs_wires_str = "" if internal_wires: - #Insert internal wires + # Insert internal wires for wire in internal_wires: periphs_wires_str += f" wire [{wire['n_bits']}-1:0] {wire['name']};\n" - + periphs_inst_str = "" # Insert IOs and Instances for this type of peripheral for instance in peripherals_list: @@ -61,55 +68,74 @@ def create_systemv(build_dir, top, peripherals_list, internal_wires=None): periphs_inst_str += " #(\n" # Insert parameters for param in params_list[instance.module.name]: - periphs_inst_str += ' .{}({}){}\n'.format(param['name'],instance.name+"_"+param['name'],",") + periphs_inst_str += " .{}({}){}\n".format( + param["name"], instance.name + "_" + param["name"], "," + ) # Remove comma at the end of last parameter - periphs_inst_str=periphs_inst_str[::-1].replace(",","",1)[::-1] + periphs_inst_str = periphs_inst_str[::-1].replace(",", "", 1)[::-1] periphs_inst_str += " )\n" # Insert peripheral instance name periphs_inst_str += " {} (\n".format(instance.name) # Insert io signals for signal in get_pio_signals(port_list[instance.module.name]): - if 'if_defined' in signal.keys(): periphs_inst_str += f"`ifdef {top.upper()}_{signal['if_defined']}\n" - periphs_inst_str += ' .{}({}),\n'.format(signal['name'],get_peripheral_port_mapping(instance,signal['name_without_prefix'])) - if 'if_defined' in signal.keys(): periphs_inst_str += "`endif\n" + if "if_defined" in signal.keys(): + periphs_inst_str += f"`ifdef {top.upper()}_{signal['if_defined']}\n" + periphs_inst_str += " .{}({}),\n".format( + signal["name"], + get_peripheral_port_mapping(instance, signal["name_without_prefix"]), + ) + if "if_defined" in signal.keys(): + periphs_inst_str += "`endif\n" # Insert reserved signals for signal in get_reserved_signals(port_list[instance.module.name]): # Check if should append this peripheral to the list of peripherals with extmem interfaces # Note: This implementation assumes that the axi_awid_o will be the first signal of the ext_mem interface - if signal['name']=="axi_awid_o": + if signal["name"] == "axi_awid_o": # Get extmem bus size of this peripheral - latest_extmem_bus_size=get_extmem_bus_size(signal['n_bits']) - num_extmem_connections+=latest_extmem_bus_size - - if 'if_defined' in signal.keys(): periphs_inst_str += f"`ifdef {top.upper()}_{signal['if_defined']}\n" - periphs_inst_str += " "+(get_reserved_signal_connection(signal['name'], - top.upper()+"_"+instance.name, - top_list[instance.module.name].upper()+"_SWREG")+",\n").replace( - "/**/", - str(num_extmem_connections-latest_extmem_bus_size)).replace( - "/**/", - str(latest_extmem_bus_size)) - if 'if_defined' in signal.keys(): periphs_inst_str += "`endif\n" - - if signal['name']=="trap_o": + latest_extmem_bus_size = get_extmem_bus_size(signal["n_bits"]) + num_extmem_connections += latest_extmem_bus_size + + if "if_defined" in signal.keys(): + periphs_inst_str += f"`ifdef {top.upper()}_{signal['if_defined']}\n" + periphs_inst_str += " " + ( + get_reserved_signal_connection( + signal["name"], + top.upper() + "_" + instance.name, + top_list[instance.module.name].upper() + "_SWREG", + ) + + ",\n" + ).replace( + "/**/", + str(num_extmem_connections - latest_extmem_bus_size), + ).replace( + "/**/", str(latest_extmem_bus_size) + ) + if "if_defined" in signal.keys(): + periphs_inst_str += "`endif\n" + + if signal["name"] == "trap_o": peripherals_with_trap.append(instance) - # Remove comma at the end of last signal - periphs_inst_str=periphs_inst_str[::-1].replace(",","",1)[::-1] - + periphs_inst_str = periphs_inst_str[::-1].replace(",", "", 1)[::-1] + periphs_inst_str += " );\n" # Create internal wires to connect to the cache and the peripheral's external memory address buses - periphs_wires_str += "\n // Internal wires for shared access to the external memory address bus\n" - periphs_wires_str += f" wire [{num_extmem_connections}*AXI_ADDR_W-1:0] internal_axi_awaddr_o;\n" - periphs_wires_str += f" wire [{num_extmem_connections}*AXI_ADDR_W-1:0] internal_axi_araddr_o;\n" - + periphs_wires_str += ( + "\n // Internal wires for shared access to the external memory address bus\n" + ) + periphs_wires_str += ( + f" wire [{num_extmem_connections}*AXI_ADDR_W-1:0] internal_axi_awaddr_o;\n" + ) + periphs_wires_str += ( + f" wire [{num_extmem_connections}*AXI_ADDR_W-1:0] internal_axi_araddr_o;\n" + ) # Create internal wires to connect the peripherals trap signals periphs_wires_str += "\n // Internal wires for trap signals\n" periphs_wires_str += " wire cpu_trap_o;\n" - trap_or_str = " assign trap_o = cpu_trap_o" + trap_or_str = " assign trap_o = cpu_trap_o" for peripheral in peripherals_with_trap: periphs_wires_str += f" wire {peripheral.name}_trap_o;\n" trap_or_str += f"| {peripheral.name}_trap_o" @@ -125,18 +151,21 @@ def create_systemv(build_dir, top, peripherals_list, internal_wires=None): # Instantiate `iob_addr_zone_selector` modules to connect periphs_inst_str += "\n // Address zone selector instances to share external memory address space between peripherals\n" periphs_inst_str += generate_iob_address_zone_selectors(top, num_extmem_connections) - + fd_periphs = open(f"{out_dir}/{top}_periphs_inst.vs", "w") fd_periphs.write(periphs_inst_str) fd_periphs.close() + # This function will return the size of the axi_m bus based on the width of the axi_awid signal # axi_awid_width: String representing the width of the axi_awid signal. def get_extmem_bus_size(axi_awid_width: str): # Parse the size of the ext_mem bus, it should be something like "N*AXI_ID_W", where N is the size of the bus - bus_size=re.findall("^(?:(\d+)\*)?AXI_ID_W$",axi_awid_width) + bus_size = re.findall("^(?:(\d+)\*)?AXI_ID_W$", axi_awid_width) # Make sure parse of with was successful - assert bus_size!=[], f"{iob_colors.FAIL} Could not parse bus size of 'axi_awid' signal with width \"{axi_awid_width}\".{iob_colors.ENDC}" + assert ( + bus_size != [] + ), f"{iob_colors.FAIL} Could not parse bus size of 'axi_awid' signal with width \"{axi_awid_width}\".{iob_colors.ENDC}" # Convert to integer return 1 if bus_size[0] == "" else int(bus_size[0]) diff --git a/scripts/iob_soc_create_wrapper_files.py b/scripts/iob_soc_create_wrapper_files.py index 470857f95..6a203f952 100755 --- a/scripts/iob_soc_create_wrapper_files.py +++ b/scripts/iob_soc_create_wrapper_files.py @@ -4,33 +4,43 @@ from submodule_utils import get_pio_signals, add_prefix_to_parameters_in_string -#Creates the Verilog Snippet (.vs) files required by wrappers +# Creates the Verilog Snippet (.vs) files required by wrappers def create_wrapper_files(build_dir, name, ios, confs, num_extmem_connections): - out_dir = os.path.join(build_dir,f'hardware/simulation/src/') + out_dir = os.path.join(build_dir, f"hardware/simulation/src/") pwires_str = "" pportmaps_str = "" - # Insert wires and connect them to system + # Insert wires and connect them to system for table in ios: # If table has 'doc_only' attribute set to True, skip it if "doc_only" in table.keys() and table["doc_only"]: continue - pio_signals = get_pio_signals(table['ports']) + pio_signals = get_pio_signals(table["ports"]) # Insert system IOs for peripheral - if pio_signals and 'if_defined' in table.keys(): pwires_str += f"`ifdef {table['if_defined']}\n" + if pio_signals and "if_defined" in table.keys(): + pwires_str += f"`ifdef {table['if_defined']}\n" for signal in pio_signals: - pwires_str += ' wire [{}-1:0] {}_{};\n'.format(add_prefix_to_parameters_in_string(signal['n_bits'],confs,"`"+name.upper()+"_"), - table['name'], - signal['name']) - if pio_signals and 'if_defined' in table.keys(): pwires_str += "`endif\n" + pwires_str += " wire [{}-1:0] {}_{};\n".format( + add_prefix_to_parameters_in_string( + signal["n_bits"], confs, "`" + name.upper() + "_" + ), + table["name"], + signal["name"], + ) + if pio_signals and "if_defined" in table.keys(): + pwires_str += "`endif\n" # Connect wires to soc port - if pio_signals and 'if_defined' in table.keys(): pportmaps_str += f"`ifdef {table['if_defined']}\n" + if pio_signals and "if_defined" in table.keys(): + pportmaps_str += f"`ifdef {table['if_defined']}\n" for signal in pio_signals: - pportmaps_str += ' .{signal}({signal}),\n'.format(signal=table['name']+"_"+signal['name']) - if pio_signals and 'if_defined' in table.keys(): pportmaps_str += "`endif\n" + pportmaps_str += " .{signal}({signal}),\n".format( + signal=table["name"] + "_" + signal["name"] + ) + if pio_signals and "if_defined" in table.keys(): + pportmaps_str += "`endif\n" # Add extmem wires for system pwires_str += f""" @@ -42,13 +52,13 @@ def create_wrapper_files(build_dir, name, ios, confs, num_extmem_connections): `include "iob_memory_axi_wire.vs" `endif """ - + fd_periphs = open(f"{out_dir}/{name}_wrapper_pwires.vs", "w") fd_periphs.write(pwires_str) fd_periphs.close() # Add extmem portmap for system - pportmaps_str +=f""" + pportmaps_str += f""" `ifdef {name.upper()}_USE_EXTMEM `include "iob_bus_0_{num_extmem_connections}_axi_m_portmap.vs" `endif @@ -62,16 +72,16 @@ def create_wrapper_files(build_dir, name, ios, confs, num_extmem_connections): create_ku040_interconnect_s_portmap(out_dir, name, num_extmem_connections) create_ku040_rstn(out_dir, name, num_extmem_connections) + def create_interconnect_instance(out_dir, name, num_extmem_connections): # Create strings for awlock and arlock - awlock_str = arlock_str = ' }' + awlock_str = arlock_str = " }" for i in range(num_extmem_connections): - awlock_str = f', axi_awlock[{i*2}]' + awlock_str - arlock_str = f', axi_arlock[{i*2}]' + arlock_str + awlock_str = f", axi_awlock[{i*2}]" + awlock_str + arlock_str = f", axi_arlock[{i*2}]" + arlock_str awlock_str = "{" + awlock_str[1:] arlock_str = "{" + arlock_str[1:] - interconnect_str = f""" `ifdef {name.upper()}_USE_EXTMEM //instantiate axi interconnect @@ -192,6 +202,7 @@ def create_ku040_rstn(out_dir, name, num_extmem_connections): fp_rstn.write(file_str) fp_rstn.close() + def create_ku040_interconnect_s_portmap(out_dir, name, num_extmem_connections): interconnect_str = "" for i in range(num_extmem_connections): @@ -254,5 +265,3 @@ def create_ku040_interconnect_s_portmap(out_dir, name, num_extmem_connections): fp_interconnect = open(f"{out_dir}/{name}_ku040_interconnect_s_portmap.vs", "w") fp_interconnect.write(interconnect_str) fp_interconnect.close() - - diff --git a/scripts/iob_soc_utils.py b/scripts/iob_soc_utils.py index c82d238b4..7df1a5039 100755 --- a/scripts/iob_soc_utils.py +++ b/scripts/iob_soc_utils.py @@ -5,7 +5,14 @@ from iob_soc_create_periphs_tmp import create_periphs_tmp from iob_soc_create_system import create_systemv, get_extmem_bus_size from iob_soc_create_wrapper_files import create_wrapper_files -from submodule_utils import get_table_ports, add_prefix_to_parameters_in_port, eval_param_expression_from_config, iob_soc_peripheral_setup, reserved_signals, if_gen_interface +from submodule_utils import ( + get_table_ports, + add_prefix_to_parameters_in_port, + eval_param_expression_from_config, + iob_soc_peripheral_setup, + reserved_signals, + if_gen_interface, +) from ios import get_interface_mapping import setup import iob_colors @@ -21,6 +28,7 @@ # Specialized IOb-SoC setup functions. ###################################### + def iob_soc_sw_setup(python_module, exclude_files=[]): peripherals_list = python_module.peripherals confs = python_module.confs @@ -28,8 +36,13 @@ def iob_soc_sw_setup(python_module, exclude_files=[]): name = python_module.name # Build periphs_tmp.h - if peripherals_list: create_periphs_tmp(next(i['val'] for i in confs if i['name'] == 'ADDR_W'), - peripherals_list, f"{build_dir}/software/{name}_periphs.h") + if peripherals_list: + create_periphs_tmp( + next(i["val"] for i in confs if i["name"] == "ADDR_W"), + peripherals_list, + f"{build_dir}/software/{name}_periphs.h", + ) + def iob_soc_wrapper_setup(python_module, num_extmem_connections, exclude_files=[]): peripherals_list = python_module.peripherals @@ -37,8 +50,10 @@ def iob_soc_wrapper_setup(python_module, num_extmem_connections, exclude_files=[ build_dir = python_module.build_dir name = python_module.name # Try to build wrapper files - #if not fnmatch.filter(exclude_files,'iob_soc_sim_wrapper.v'): - create_wrapper_files(build_dir, name, python_module.ios, confs, num_extmem_connections) + # if not fnmatch.filter(exclude_files,'iob_soc_sim_wrapper.v'): + create_wrapper_files( + build_dir, name, python_module.ios, confs, num_extmem_connections + ) # Check if USE_EXTMEM is set for conf in python_module.confs: @@ -90,11 +105,18 @@ def iob_soc_wrapper_setup(python_module, num_extmem_connections, exclude_files=[ } ) + def iob_soc_doc_setup(python_module, exclude_files=[]): # Copy .odg figures without processing - shutil.copytree(os.path.join(os.path.dirname(__file__),'..', "document/"), - os.path.join(python_module.build_dir,"document/"), dirs_exist_ok=True, - ignore=lambda directory, contents: [f for f in contents if os.path.splitext(f)[1] not in ['.odg', '']]) + shutil.copytree( + os.path.join(os.path.dirname(__file__), "..", "document/"), + os.path.join(python_module.build_dir, "document/"), + dirs_exist_ok=True, + ignore=lambda directory, contents: [ + f for f in contents if os.path.splitext(f)[1] not in [".odg", ""] + ], + ) + def iob_soc_hw_setup(python_module, exclude_files=[]): peripherals_list = python_module.peripherals @@ -103,34 +125,42 @@ def iob_soc_hw_setup(python_module, exclude_files=[]): # Try to build .v if template .v is available and iob_soc.v not in exclude list # Note, it checks for iob_soc.v in exclude files, instead of .v to be consistent with the copy_common_files() function. - #[If a user does not want to build .v from the template, then he also does not want to copy the template from the iob-soc] - if not fnmatch.filter(exclude_files,'iob_soc.v'): - create_systemv(build_dir, name, peripherals_list, internal_wires=python_module.internal_wires) + # [If a user does not want to build .v from the template, then he also does not want to copy the template from the iob-soc] + if not fnmatch.filter(exclude_files, "iob_soc.v"): + create_systemv( + build_dir, + name, + peripherals_list, + internal_wires=python_module.internal_wires, + ) + def update_ios_with_extmem_connections(python_module): ios = python_module.ios peripherals_list = python_module.peripherals - num_extmem_connections = 1 # By default, one connection for iob-soc's cache + num_extmem_connections = 1 # By default, one connection for iob-soc's cache # Count numer of external memory connections for peripheral in peripherals_list: - module = peripheral.module - for interface in module.ios: - for port in interface['ports']: - if port['name'] == 'axi_awid_o': - num_extmem_connections+=get_extmem_bus_size(port['n_bits']) - # Break the inner loop... - break - else: - # Continue if the inner loop wasn't broken. - continue - # Inner loop was broken, break the outer. + module = peripheral.module + for interface in module.ios: + for port in interface["ports"]: + if port["name"] == "axi_awid_o": + num_extmem_connections += get_extmem_bus_size(port["n_bits"]) + # Break the inner loop... break + else: + # Continue if the inner loop wasn't broken. + continue + # Inner loop was broken, break the outer. + break for interface in ios: - if interface['name'] == 'extmem': + if interface["name"] == "extmem": # Create bus of axi_m_port with size `num_extmem_connections` - interface['ports'] = if_gen_interface("axi_m_port", "", bus_size=num_extmem_connections) + interface["ports"] = if_gen_interface( + "axi_m_port", "", bus_size=num_extmem_connections + ) return num_extmem_connections @@ -145,8 +175,10 @@ def setup_iob_soc(python_module): # Replace IOb-SoC name in values of confs for conf in confs: - if type(conf['val']) == str: - conf['val'] = conf['val'].replace('iob_soc',name).replace('IOB_SOC',name.upper()) + if type(conf["val"]) == str: + conf["val"] = ( + conf["val"].replace("iob_soc", name).replace("IOB_SOC", name.upper()) + ) # Setup peripherals iob_soc_peripheral_setup(python_module) @@ -170,58 +202,80 @@ def setup_iob_soc(python_module): verilog_tools.replace_includes(python_module.setup_dir, build_dir) # Check if was setup with INIT_MEM and USE_EXTMEM (check if macro exists) - extmem_macro = bool(next((i['val'] for i in confs if i['name']=='USE_EXTMEM'), False)) - initmem_macro = bool(next((i['val'] for i in confs if i['name']=='INIT_MEM'), False)) + extmem_macro = bool( + next((i["val"] for i in confs if i["name"] == "USE_EXTMEM"), False) + ) + initmem_macro = bool( + next((i["val"] for i in confs if i["name"] == "INIT_MEM"), False) + ) # Set variables in fpga_build.mk - with open(python_module.build_dir+"/hardware/fpga/fpga_build.mk",'r') as file: contents = file.readlines() - contents.insert(0,"\n") + with open(python_module.build_dir + "/hardware/fpga/fpga_build.mk", "r") as file: + contents = file.readlines() + contents.insert(0, "\n") # Set N_INTERCONNECT_SLAVES variable - contents.insert(0,f"N_INTERCONNECT_SLAVES:={num_extmem_connections}\n") + contents.insert(0, f"N_INTERCONNECT_SLAVES:={num_extmem_connections}\n") # Set USE_EXTMEM variable - contents.insert(0,f"USE_EXTMEM:={int(extmem_macro)}\n") + contents.insert(0, f"USE_EXTMEM:={int(extmem_macro)}\n") # Set INIT_MEM variable - contents.insert(0,f"INIT_MEM:={int(initmem_macro)}\n") - contents.insert(0,"#Lines below were auto generated by iob_soc_utils.py\n") - with open(python_module.build_dir+"/hardware/fpga/fpga_build.mk",'w') as file: file.writelines(contents) + contents.insert(0, f"INIT_MEM:={int(initmem_macro)}\n") + contents.insert(0, "#Lines below were auto generated by iob_soc_utils.py\n") + with open(python_module.build_dir + "/hardware/fpga/fpga_build.mk", "w") as file: + file.writelines(contents) - mem_add_w_parameter = next((i for i in confs if i['name']=='MEM_ADDR_W'), False) + mem_add_w_parameter = next((i for i in confs if i["name"] == "MEM_ADDR_W"), False) if extmem_macro and initmem_macro: # Append init_ddr_contents.hex target to sw_build.mk - with open(f"{build_dir}/software/sw_build.mk", 'a') as file: + with open(f"{build_dir}/software/sw_build.mk", "a") as file: file.write("\n#Auto-generated target to create init_ddr_contents.hex\n") file.write("HEX+=init_ddr_contents.hex\n") file.write("# init file for external mem with firmware of both systems\n") file.write(f"init_ddr_contents.hex: {name}_firmware.hex\n") - sut_firmware_name = python_module.sut_fw_name.replace('.c','.hex') if 'sut_fw_name' in python_module.__dict__.keys() else '-' - file.write(f" ../../scripts/joinHexFiles.py $^ {sut_firmware_name} {mem_add_w_parameter['val']} > $@\n") + sut_firmware_name = ( + python_module.sut_fw_name.replace(".c", ".hex") + if "sut_fw_name" in python_module.__dict__.keys() + else "-" + ) + file.write( + f" ../../scripts/joinHexFiles.py $^ {sut_firmware_name} {mem_add_w_parameter['val']} > $@\n" + ) # Copy joinHexFiles.py from LIB - build_srcs.copy_files( "submodules/LIB", f"{build_dir}/scripts", [ "joinHexFiles.py" ], '*.py' ) + build_srcs.copy_files( + "submodules/LIB", f"{build_dir}/scripts", ["joinHexFiles.py"], "*.py" + ) -#Given the io dictionary of ports, the port name (and size, and optional bit list) and a wire, it will map the selected bits of the port to the given wire. -#io_dict: dictionary where keys represent port names, values are the mappings -#port_name: name of the port to map -#port_size: size the port (if port_bits are not specified, this value is not used) -#port_bits: list of bits of the port that are being mapped to the wire. If list is empty it will map all the bits. +# Given the io dictionary of ports, the port name (and size, and optional bit list) and a wire, it will map the selected bits of the port to the given wire. +# io_dict: dictionary where keys represent port names, values are the mappings +# port_name: name of the port to map +# port_size: size the port (if port_bits are not specified, this value is not used) +# port_bits: list of bits of the port that are being mapped to the wire. If list is empty it will map all the bits. # The order of bits in this list is important. The bits of the wire will always be filled in incremental order and will match the corresponding bit of the port given on this list following the list order. Example: The list [5,3] will map the port bit 5 to wire bit 0 and port bit 3 to wire bit 1. -#wire_name: name of the wire to connect the bits of the port to. +# wire_name: name of the wire to connect the bits of the port to. def map_IO_to_wire(io_dict, port_name, port_size, port_bits, wire_name): if not port_bits: - assert port_name not in io_dict, f"{iob_colors.FAIL}Peripheral port {port_name} has already been previously mapped!{iob_colors.ENDC}" + assert ( + port_name not in io_dict + ), f"{iob_colors.FAIL}Peripheral port {port_name} has already been previously mapped!{iob_colors.ENDC}" # Did not specify bits, connect all the entire port (all the bits) io_dict[port_name] = wire_name else: # Initialize array with port_size, all bits with 'None' value (not mapped) - if port_name not in io_dict: io_dict[port_name] = [None for n in range(int(port_size))] + if port_name not in io_dict: + io_dict[port_name] = [None for n in range(int(port_size))] # Map the selected bits to the corresponding wire bits # Each element in the bit list of this port will be a tuple containign the name of the wire to connect to and the bit of that wire. for wire_bit, bit in enumerate(port_bits): - assert bit < len(io_dict[port_name]), f"{iob_colors.FAIL}Peripheral port {port_name} does not have bit {bit}!{iob_colors.ENDC}" - assert not io_dict[port_name][bit], f"{iob_colors.FAIL}Peripheral port {port_name} bit {bit} has already been previously mapped!{iob_colors.ENDC}" + assert bit < len( + io_dict[port_name] + ), f"{iob_colors.FAIL}Peripheral port {port_name} does not have bit {bit}!{iob_colors.ENDC}" + assert not io_dict[port_name][ + bit + ], f"{iob_colors.FAIL}Peripheral port {port_name} bit {bit} has already been previously mapped!{iob_colors.ENDC}" io_dict[port_name][bit] = (wire_name, wire_bit) + # Function to handle portmap connections between: peripherals, internal, and external system interfaces. def peripheral_portmap(python_module): peripherals_list = python_module.peripherals @@ -230,7 +284,9 @@ def peripheral_portmap(python_module): # Add default portmap for peripherals not configured in peripheral_portmap for peripheral in peripherals_list: - if peripheral.name not in [i[0]['corename'] for i in peripheral_portmap or []]+[i[1]['corename'] for i in peripheral_portmap or []]: + if peripheral.name not in [ + i[0]["corename"] for i in peripheral_portmap or [] + ] + [i[1]["corename"] for i in peripheral_portmap or []]: # Import module of one of the given core types (to access its IO) module = peripheral.module # Map all ports of all interfaces @@ -239,45 +295,90 @@ def peripheral_portmap(python_module): if "doc_only" in interface.keys() and interface["doc_only"]: continue - if interface['ports']: - for port in interface['ports']: - if port['name'] not in reserved_signals: + if interface["ports"]: + for port in interface["ports"]: + if port["name"] not in reserved_signals: # Map port to the external system interface - peripheral_portmap.append(({'corename':peripheral.name, 'if_name':interface['name'], 'port':port['name'], 'bits':[]}, {'corename':'external', 'if_name':peripheral.name, 'port':'', 'bits':[]})) - else: + peripheral_portmap.append( + ( + { + "corename": peripheral.name, + "if_name": interface["name"], + "port": port["name"], + "bits": [], + }, + { + "corename": "external", + "if_name": peripheral.name, + "port": "", + "bits": [], + }, + ) + ) + else: # Auto-map if_gen interfaces, except for the ones that have reserved signals. - if interface['name'] in if_gen.interfaces and interface['name'] not in ['iob_s_port','axi_m_port']: + if interface["name"] in if_gen.interfaces and interface[ + "name" + ] not in ["iob_s_port", "axi_m_port"]: # Map entire interface to the external system interface - peripheral_portmap.append(({'corename':peripheral.name, 'if_name':interface['name'], 'port':'', 'bits':[]}, {'corename':'external', 'if_name':peripheral.name, 'port':'', 'bits':[]})) + peripheral_portmap.append( + ( + { + "corename": peripheral.name, + "if_name": interface["name"], + "port": "", + "bits": [], + }, + { + "corename": "external", + "if_name": peripheral.name, + "port": "", + "bits": [], + }, + ) + ) # Add 'IO" attribute to every peripheral for peripheral in peripherals_list: - peripheral.io={} + peripheral.io = {} # List of peripheral interconnection wires peripheral_wires = [] - #Handle peripheral portmap + # Handle peripheral portmap for map_idx, mapping in enumerate(peripheral_portmap): # List to store both items in this mamping mapping_items = [None, None] - assert mapping[0]['corename'] and mapping[1]['corename'], f"{iob_colors.FAIL}Mapping 'corename' can not be empty on portmap index {map_idx}!{iob_colors.ENDC}" + assert ( + mapping[0]["corename"] and mapping[1]["corename"] + ), f"{iob_colors.FAIL}Mapping 'corename' can not be empty on portmap index {map_idx}!{iob_colors.ENDC}" # The 'external' keyword in corename is reserved to map signals to the external interface, causing it to create a system IO port # The 'internal' keyword in corename is reserved to map signals to the internal interface, causing it to create an internal system wire # Get system block of peripheral in mapping[0] - if mapping[0]['corename'] not in ['external','internal']: - assert any(i for i in peripherals_list if i.name == mapping[0]['corename']), f"{iob_colors.FAIL}{map_idx} Peripheral instance named '{mapping[0]['corename']}' not found!{iob_colors.ENDC}" - mapping_items[0]=next(i for i in peripherals_list if i.name == mapping[0]['corename']) + if mapping[0]["corename"] not in ["external", "internal"]: + assert any( + i for i in peripherals_list if i.name == mapping[0]["corename"] + ), f"{iob_colors.FAIL}{map_idx} Peripheral instance named '{mapping[0]['corename']}' not found!{iob_colors.ENDC}" + mapping_items[0] = next( + i for i in peripherals_list if i.name == mapping[0]["corename"] + ) # Get system block of peripheral in mapping[1] - if mapping[1]['corename'] not in ['external','internal']: - assert any(i for i in peripherals_list if i.name == mapping[1]['corename']), f"{iob_colors.FAIL}{map_idx} Peripheral instance named '{mapping[1]['corename']}' not found!{iob_colors.ENDC}" - mapping_items[1]=next(i for i in peripherals_list if i.name == mapping[1]['corename']) + if mapping[1]["corename"] not in ["external", "internal"]: + assert any( + i for i in peripherals_list if i.name == mapping[1]["corename"] + ), f"{iob_colors.FAIL}{map_idx} Peripheral instance named '{mapping[1]['corename']}' not found!{iob_colors.ENDC}" + mapping_items[1] = next( + i for i in peripherals_list if i.name == mapping[1]["corename"] + ) - #Make sure we are not mapping two external or internal interfaces - assert mapping_items != [None, None], f"{iob_colors.FAIL}{map_idx} Cannot map between two internal/external interfaces!{iob_colors.ENDC}" + # Make sure we are not mapping two external or internal interfaces + assert mapping_items != [ + None, + None, + ], f"{iob_colors.FAIL}{map_idx} Cannot map between two internal/external interfaces!{iob_colors.ENDC}" # By default, store -1 if we are not mapping to external/internal interface mapping_external_interface = -1 @@ -285,170 +386,279 @@ def peripheral_portmap(python_module): # Store index if any of the entries is the external/internal interface if None in mapping_items: - if mapping[mapping_items.index(None)]['corename'] == 'external': + if mapping[mapping_items.index(None)]["corename"] == "external": mapping_external_interface = mapping_items.index(None) else: mapping_internal_interface = mapping_items.index(None) # Create interface for this portmap if it is connected to external interface - if mapping_external_interface>-1: + if mapping_external_interface > -1: # List of system IOs from ports of this mapping - mapping_ios=[] + mapping_ios = [] # Add peripherals table to ios of system - assert mapping[mapping_external_interface]['if_name'], f"{iob_colors.FAIL}Portmap index {map_idx} needs an interface name for the 'external' corename!{iob_colors.ENDC}" - ios.append({'name': mapping[mapping_external_interface]['if_name'], 'descr':f"IOs for peripherals based on portmap index {map_idx}", 'ports': mapping_ios, - # Only set `ios_table_prefix` if user has not specified a value in the portmap entry - 'ios_table_prefix':True if 'ios_table_prefix' not in mapping[mapping_external_interface] else mapping[mapping_external_interface]['ios_table_prefix']}) + assert mapping[mapping_external_interface][ + "if_name" + ], f"{iob_colors.FAIL}Portmap index {map_idx} needs an interface name for the 'external' corename!{iob_colors.ENDC}" + ios.append( + { + "name": mapping[mapping_external_interface]["if_name"], + "descr": f"IOs for peripherals based on portmap index {map_idx}", + "ports": mapping_ios, + # Only set `ios_table_prefix` if user has not specified a value in the portmap entry + "ios_table_prefix": True + if "ios_table_prefix" not in mapping[mapping_external_interface] + else mapping[mapping_external_interface]["ios_table_prefix"], + } + ) # Import module of one of the given core types (to access its IO) module = mapping_items[0].module - #print(f"DEBUG: {module.name} {module.ios}", file=sys.stderr) - - #Get ports of configured interface - interface_table = next((i for i in module.ios if i['name'] == mapping[0]['if_name']), None) - assert interface_table, f"{iob_colors.FAIL}Interface {mapping[0]['if_name']} of {mapping[0]['corename']} not found!{iob_colors.ENDC}" - interface_ports=get_table_ports(interface_table) - - #If mapping_items[1] is not internal/external interface - if mapping_internal_interface!=1 and mapping_external_interface!=1: + # print(f"DEBUG: {module.name} {module.ios}", file=sys.stderr) + + # Get ports of configured interface + interface_table = next( + (i for i in module.ios if i["name"] == mapping[0]["if_name"]), None + ) + assert ( + interface_table + ), f"{iob_colors.FAIL}Interface {mapping[0]['if_name']} of {mapping[0]['corename']} not found!{iob_colors.ENDC}" + interface_ports = get_table_ports(interface_table) + + # If mapping_items[1] is not internal/external interface + if mapping_internal_interface != 1 and mapping_external_interface != 1: # Import module of one of the given core types (to access its IO) module2 = mapping_items[1].module - #Get ports of configured interface - interface_table = next((i for i in module2.ios if i['name'] == mapping[1]['if_name']), None) - assert interface_table, f"{iob_colors.FAIL}Interface {mapping[1]['if_name']} of {mapping[1]['corename']} not found!{iob_colors.ENDC}" - interface_ports2=get_table_ports(interface_table) + # Get ports of configured interface + interface_table = next( + (i for i in module2.ios if i["name"] == mapping[1]["if_name"]), None + ) + assert ( + interface_table + ), f"{iob_colors.FAIL}Interface {mapping[1]['if_name']} of {mapping[1]['corename']} not found!{iob_colors.ENDC}" + interface_ports2 = get_table_ports(interface_table) # Check if should insert one port or every port in the interface - if not mapping[0]['port']: + if not mapping[0]["port"]: # Mapping configuration did not specify a port, therefore insert all signals from interface and auto-connect them - #NOTE: currently mapping[1]['if_name'] is always assumed to be equal to mapping[0]['if_name'] + # NOTE: currently mapping[1]['if_name'] is always assumed to be equal to mapping[0]['if_name'] # Get mapping for this interface - if_mapping = get_interface_mapping(mapping[0]['if_name']) + if_mapping = get_interface_mapping(mapping[0]["if_name"]) # For every port: create wires and connect IO for port in interface_ports: - if mapping_internal_interface<0 and mapping_external_interface<0: + if mapping_internal_interface < 0 and mapping_external_interface < 0: # Not mapped to internal/external interface # Create peripheral wire name based on mapping. wire_name = f"connect_{mapping[0]['corename']}_{mapping[0]['if_name']}_{port['name']}_to_{mapping[1]['corename']}_{mapping[1]['if_name']}_{if_mapping[port['name']]}" - peripheral_wires.append({'name':wire_name, 'n_bits':add_prefix_to_parameters_in_port(port,module.confs,mapping[0]['corename']+"_")['n_bits']}) - elif mapping_internal_interface>-1: - #Mapped to internal interface - #Wire name generated the same way as ios inserted in verilog - if mapping_internal_interface==0: + peripheral_wires.append( + { + "name": wire_name, + "n_bits": add_prefix_to_parameters_in_port( + port, module.confs, mapping[0]["corename"] + "_" + )["n_bits"], + } + ) + elif mapping_internal_interface > -1: + # Mapped to internal interface + # Wire name generated the same way as ios inserted in verilog + if mapping_internal_interface == 0: wire_name = f"{mapping[0]['if_name']+'_'}{port['name']}" else: wire_name = f"{mapping[1]['if_name']+'_'}{port['name']}" - #Add internal system wire for this port - peripheral_wires.append({'name':wire_name, 'n_bits':add_prefix_to_parameters_in_port(port,module.confs,mapping[0]['corename']+"_")['n_bits']}) + # Add internal system wire for this port + peripheral_wires.append( + { + "name": wire_name, + "n_bits": add_prefix_to_parameters_in_port( + port, module.confs, mapping[0]["corename"] + "_" + )["n_bits"], + } + ) else: - #Mapped to external interface - #Add system IO for this port - mapping_ios.append(add_prefix_to_parameters_in_port(port,module.confs,mapping[0]['corename']+"_")) + # Mapped to external interface + # Add system IO for this port + mapping_ios.append( + add_prefix_to_parameters_in_port( + port, module.confs, mapping[0]["corename"] + "_" + ) + ) # Dont add `if_name` prefix if `iob_table_prefix` is set to False - if 'ios_table_prefix' in mapping[mapping_external_interface] and not mapping[mapping_external_interface]['ios_table_prefix']: + if ( + "ios_table_prefix" in mapping[mapping_external_interface] + and not mapping[mapping_external_interface]["ios_table_prefix"] + ): signal_prefix = "" else: - signal_prefix = mapping[mapping_external_interface]['if_name']+'_' - - if 'remove_string_from_port_names' in mapping[mapping_external_interface]: - signal_name = port['name'].replace(mapping[mapping_external_interface]['remove_string_from_port_names'],"") + signal_prefix = ( + mapping[mapping_external_interface]["if_name"] + "_" + ) + + if ( + "remove_string_from_port_names" + in mapping[mapping_external_interface] + ): + signal_name = port["name"].replace( + mapping[mapping_external_interface][ + "remove_string_from_port_names" + ], + "", + ) # Update port name previsously inserted in mapping_ios - mapping_ios[-1]['name'] = signal_name + mapping_ios[-1]["name"] = signal_name else: - signal_name = port['name'] - #Wire name generated the same way as ios inserted in verilog + signal_name = port["name"] + # Wire name generated the same way as ios inserted in verilog wire_name = f"{signal_prefix}{signal_name}" - #Insert mapping between IO and wire for mapping[0] (if its not internal/external interface) - if mapping_internal_interface!=0 and mapping_external_interface!=0: - map_IO_to_wire(mapping_items[0].io, port['name'], 0, [], wire_name) + # Insert mapping between IO and wire for mapping[0] (if its not internal/external interface) + if mapping_internal_interface != 0 and mapping_external_interface != 0: + map_IO_to_wire(mapping_items[0].io, port["name"], 0, [], wire_name) - #Insert mapping between IO and wire for mapping[1] (if its not internal/external interface) - if mapping_internal_interface!=1 and mapping_external_interface!=1: - map_IO_to_wire(mapping_items[1].io, if_mapping[port['name']], 0, [], wire_name) + # Insert mapping between IO and wire for mapping[1] (if its not internal/external interface) + if mapping_internal_interface != 1 and mapping_external_interface != 1: + map_IO_to_wire( + mapping_items[1].io, if_mapping[port["name"]], 0, [], wire_name + ) else: # Mapping configuration specified a port, therefore only insert singal for that port - port = next((i for i in interface_ports if i['name'] == mapping[0]['port']),None) - assert port, f"{iob_colors.FAIL}Port {mapping[0]['port']} of {mapping[0]['if_name']} for {mapping[0]['corename']} not found!{iob_colors.ENDC}" - - if mapping_internal_interface!=1 and mapping_external_interface!=1: - port2 = next((i for i in interface_ports2 if i['name'] == mapping[1]['port']), None) - assert port2, f"{iob_colors.FAIL}Port {mapping[1]['port']} of {mapping[1]['if_name']} for {mapping[1]['corename']} not found!{iob_colors.ENDC}" - - #Get number of bits for this wire. If 'bits' was not specified, use the same size as the port of the peripheral - if not mapping[0]['bits']: + port = next( + (i for i in interface_ports if i["name"] == mapping[0]["port"]), None + ) + assert ( + port + ), f"{iob_colors.FAIL}Port {mapping[0]['port']} of {mapping[0]['if_name']} for {mapping[0]['corename']} not found!{iob_colors.ENDC}" + + if mapping_internal_interface != 1 and mapping_external_interface != 1: + port2 = next( + (i for i in interface_ports2 if i["name"] == mapping[1]["port"]), + None, + ) + assert ( + port2 + ), f"{iob_colors.FAIL}Port {mapping[1]['port']} of {mapping[1]['if_name']} for {mapping[1]['corename']} not found!{iob_colors.ENDC}" + + # Get number of bits for this wire. If 'bits' was not specified, use the same size as the port of the peripheral + if not mapping[0]["bits"]: # Mapping did not specify bits, use the same size as the port (will map all bits of the port) - n_bits = port['n_bits'] + n_bits = port["n_bits"] else: # Mapping specified bits, the width will be the total amount of bits specified - n_bits = len(mapping[0]['bits']) + n_bits = len(mapping[0]["bits"]) # Insert wire of the ports into the peripherals_wires list of the system - if mapping_internal_interface<0 and mapping_external_interface<0: + if mapping_internal_interface < 0 and mapping_external_interface < 0: # Not mapped to external interface # Create wire name based on mapping wire_name = f"connect_{mapping[0]['corename']}_{mapping[0]['if_name']}_{mapping[0]['port']}_to_{mapping[1]['corename']}_{mapping[1]['if_name']}_{mapping[1]['port']}" - peripheral_wires.append({'name':wire_name, 'n_bits':add_prefix_to_parameters_in_port(port,module.confs,mapping[0]['corename']+"_")['n_bits']}) - elif mapping_internal_interface>-1: - #Mapped to internal interface - #Wire name generated the same way as ios inserted in verilog - if mapping_internal_interface==0: + peripheral_wires.append( + { + "name": wire_name, + "n_bits": add_prefix_to_parameters_in_port( + port, module.confs, mapping[0]["corename"] + "_" + )["n_bits"], + } + ) + elif mapping_internal_interface > -1: + # Mapped to internal interface + # Wire name generated the same way as ios inserted in verilog + if mapping_internal_interface == 0: wire_name = f"{mapping[0]['if_name']+'_'}{port['name']}" else: wire_name = f"{mapping[1]['if_name']+'_'}{port['name']}" - #Add internal system wire for this port - peripheral_wires.append({'name':wire_name, 'n_bits':add_prefix_to_parameters_in_port(port,module.confs,mapping[0]['corename']+"_")['n_bits']}) + # Add internal system wire for this port + peripheral_wires.append( + { + "name": wire_name, + "n_bits": add_prefix_to_parameters_in_port( + port, module.confs, mapping[0]["corename"] + "_" + )["n_bits"], + } + ) else: - #Mapped to external interface - #Add system IO for this port - mapping_ios.append(add_prefix_to_parameters_in_port({'name':port['name'], 'type':port['type'], 'n_bits':n_bits, 'descr':port['descr']}, - module.confs,mapping[0]['corename']+"_")) + # Mapped to external interface + # Add system IO for this port + mapping_ios.append( + add_prefix_to_parameters_in_port( + { + "name": port["name"], + "type": port["type"], + "n_bits": n_bits, + "descr": port["descr"], + }, + module.confs, + mapping[0]["corename"] + "_", + ) + ) # Dont add `if_name` prefix if `iob_table_prefix` is set to False - if 'ios_table_prefix' in mapping[mapping_external_interface] and not mapping[mapping_external_interface]['ios_table_prefix']: + if ( + "ios_table_prefix" in mapping[mapping_external_interface] + and not mapping[mapping_external_interface]["ios_table_prefix"] + ): signal_prefix = "" else: - signal_prefix = mapping[mapping_external_interface]['if_name']+'_' - - if 'remove_string_from_port_names' in mapping[mapping_external_interface]: - signal_name = port['name'].replace(mapping[mapping_external_interface]['remove_string_from_port_names'],"") + signal_prefix = mapping[mapping_external_interface]["if_name"] + "_" + + if ( + "remove_string_from_port_names" + in mapping[mapping_external_interface] + ): + signal_name = port["name"].replace( + mapping[mapping_external_interface][ + "remove_string_from_port_names" + ], + "", + ) # Update port name previsously inserted in mapping_ios - mapping_ios[-1]['name'] = signal_name + mapping_ios[-1]["name"] = signal_name else: - signal_name = port['name'] - #Wire name generated the same way as ios inserted in verilog + signal_name = port["name"] + # Wire name generated the same way as ios inserted in verilog wire_name = f"{signal_prefix}{signal_name}" - #Insert mapping between IO and wire for mapping[0] (if its not internal/external interface) - if mapping_internal_interface!=0 and mapping_external_interface!=0: - map_IO_to_wire(mapping_items[0].io, mapping[0]['port'], eval_param_expression_from_config(port['n_bits'],module.confs,'max'), mapping[0]['bits'], wire_name) - - #Insert mapping between IO and wire for mapping[1] (if its not internal/external interface) - if mapping_internal_interface!=1 and mapping_external_interface!=1: - map_IO_to_wire(mapping_items[1].io, mapping[1]['port'], eval_param_expression_from_config(port2['n_bits'],module2.confs,'max'), mapping[1]['bits'], wire_name) + # Insert mapping between IO and wire for mapping[0] (if its not internal/external interface) + if mapping_internal_interface != 0 and mapping_external_interface != 0: + map_IO_to_wire( + mapping_items[0].io, + mapping[0]["port"], + eval_param_expression_from_config( + port["n_bits"], module.confs, "max" + ), + mapping[0]["bits"], + wire_name, + ) + + # Insert mapping between IO and wire for mapping[1] (if its not internal/external interface) + if mapping_internal_interface != 1 and mapping_external_interface != 1: + map_IO_to_wire( + mapping_items[1].io, + mapping[1]["port"], + eval_param_expression_from_config( + port2["n_bits"], module2.confs, "max" + ), + mapping[1]["bits"], + wire_name, + ) # Merge interfaces with the same name into a single interface interface_names = [] for interface in ios: - if interface['name'] not in interface_names: - interface_names.append(interface['name']) + if interface["name"] not in interface_names: + interface_names.append(interface["name"]) new_ios = [] for interface_name in interface_names: first_interface_instance = None for interface in ios: - if interface['name'] == interface_name: + if interface["name"] == interface_name: if not first_interface_instance: first_interface_instance = interface new_ios.append(interface) else: - first_interface_instance['ports']+=interface['ports'] - python_module.ios=new_ios - #print(f"### Debug python_module.ios: {python_module.ios}", file=sys.stderr) + first_interface_instance["ports"] += interface["ports"] + python_module.ios = new_ios + # print(f"### Debug python_module.ios: {python_module.ios}", file=sys.stderr) return peripheral_wires - - diff --git a/submodules/CACHE b/submodules/CACHE index bd6927a1c..a98d2b45a 160000 --- a/submodules/CACHE +++ b/submodules/CACHE @@ -1 +1 @@ -Subproject commit bd6927a1c6d01adc70327a24165f30f5adbfee41 +Subproject commit a98d2b45adea3277f983441872e6991e0e320f4c diff --git a/submodules/LIB b/submodules/LIB index a3d2c27a2..381ff7b03 160000 --- a/submodules/LIB +++ b/submodules/LIB @@ -1 +1 @@ -Subproject commit a3d2c27a287e58f7145cb1f018bfe3cdf2cf1f9f +Subproject commit 381ff7b0301ea4c607c08653db31097e81ceb182