Source code for coffe.mux_subcircuits

def _generate_ptran_driver(spice_file, mux_name, implemented_mux_size):
	""" Generate mux driver for pass-transistor based MUX (it has a level restorer) """
	
	# Create the MUX output driver circuit
	spice_file.write("******************************************************************************************\n")
	spice_file.write("* " + mux_name + " driver subcircuit (" + str(implemented_mux_size) + ":1)\n")
	spice_file.write("******************************************************************************************\n")
	spice_file.write(".SUBCKT " + mux_name + "_driver n_in n_out n_vdd n_gnd\n")
	spice_file.write("Xrest_" + mux_name + " n_in n_1_1 n_vdd n_gnd rest Wp=rest_" + mux_name + "_pmos\n")
	spice_file.write("Xinv_" + mux_name + "_1 n_in n_1_1 n_vdd n_gnd inv Wn=inv_" + mux_name + "_1_nmos Wp=inv_" + mux_name + "_1_pmos\n")
	spice_file.write("Xwire_" + mux_name + "_driver n_1_1 n_1_2 wire Rw=wire_" + mux_name + "_driver_res Cw=wire_" + mux_name + "_driver_cap\n")
	spice_file.write("Xinv_" + mux_name + "_2 n_1_2 n_out n_vdd n_gnd inv Wn=inv_" + mux_name + "_2_nmos Wp=inv_" + mux_name + "_2_pmos\n")
	spice_file.write(".ENDS\n\n\n")
	
	
def _generate_ptran_sense_only(spice_file, mux_name, implemented_mux_size):
	""" Generate mux driver for pass-transistor based MUX (it has a level restorer) """
	
	# Create the MUX output sense inverter only circuit
	spice_file.write("******************************************************************************************\n")
	spice_file.write("* " + mux_name + " sense inverter subcircuit (" + str(implemented_mux_size) + ":1)\n")
	spice_file.write("******************************************************************************************\n")
	spice_file.write(".SUBCKT " + mux_name + "_sense n_in n_out n_vdd n_gnd\n")
	spice_file.write("Xrest_" + mux_name + " n_in n_out n_vdd n_gnd rest Wp=rest_" + mux_name + "_pmos\n")
	spice_file.write("Xinv_" + mux_name + "_1 n_in n_out n_vdd n_gnd inv Wn=inv_" + mux_name + "_1_nmos Wp=inv_" + mux_name + "_1_pmos\n")
	spice_file.write(".ENDS\n\n\n")
	
	
def _generate_ptran_2lvl_mux_off(spice_file, mux_name, implemented_mux_size):
	""" Generate off pass-transistor 2-level mux """
	
	# Create the off MUX circuit
	spice_file.write("******************************************************************************************\n")
	spice_file.write("* " + mux_name + " subcircuit (" + str(implemented_mux_size) + ":1), turned off \n")
	spice_file.write("******************************************************************************************\n")
	spice_file.write(".SUBCKT " + mux_name + "_off n_in n_gate n_gate_n n_vdd n_gnd\n")
	spice_file.write("Xptran_" + mux_name + "_L1 n_in n_gnd n_gnd n_gnd ptran Wn=ptran_" + mux_name + "_L1_nmos\n")
	spice_file.write(".ENDS\n\n\n")
	

def _generate_ptran_2lvl_mux_partial(spice_file, mux_name, implemented_mux_size, level1_size):
	""" Generate partially on pass-transistor 2-level mux """

	# Create the partially-on MUX circuit
	spice_file.write("******************************************************************************************\n")
	spice_file.write("* " + mux_name + " subcircuit (" + str(implemented_mux_size) + ":1), partially turned on\n")
	spice_file.write("******************************************************************************************\n")
	spice_file.write(".SUBCKT " + mux_name + "_partial n_in n_gate n_gate_n n_vdd n_gnd\n")
	# Write level 1 netlist
	spice_file.write("Xptran_" + mux_name + "_L1 n_in n_1 n_gate n_gnd ptran Wn=ptran_" + mux_name + "_L1_nmos\n")
	current_node = "n_1"
	for i in range(1, level1_size):
		new_node = "n_1_" + str(i)
		spice_file.write("Xwire_" + mux_name + "_L1_" + str(i) + " " + current_node + " " + new_node + 
							" wire Rw='wire_" + mux_name + "_L1_res/" + str(level1_size) + "' Cw='wire_" +
							mux_name + "_L1_cap/" + str(level1_size) + "'\n")
		spice_file.write("Xptran_" + mux_name + "_L1_" + str(i) + "h n_gnd " + new_node + " n_gnd n_gnd ptran Wn=ptran_" + mux_name + "_L1_nmos\n")
		current_node = new_node
	new_node = "n_1_" + str(level1_size)
	spice_file.write("Xwire_" + mux_name + "_L1_" + str(level1_size) + " " + current_node + " " + new_node + 
							" wire Rw='wire_" + mux_name + "_L1_res/" + str(level1_size) + "' Cw='wire_" +
							mux_name + "_L1_cap/" + str(level1_size) + "'\n")
	current_node = new_node
	# Write level 2 netlist
	spice_file.write("Xptran_" + mux_name + "_L2 " + current_node + " n_gnd n_gnd n_gnd ptran Wn=ptran_" + mux_name + "_L2_nmos\n")
	spice_file.write(".ENDS\n\n\n") 


def _generate_ptran_2lvl_mux_on(spice_file, mux_name, implemented_mux_size, level1_size, level2_size):
	""" Generate on pass-transistor 2-level mux, never call this outside this file """

	# Create the fully-on MUX circuit
	spice_file.write("******************************************************************************************\n")
	spice_file.write("* " + mux_name + " subcircuit (" + str(implemented_mux_size) + ":1), fully turned on (mux only)\n")
	spice_file.write("******************************************************************************************\n")
	spice_file.write(".SUBCKT " + mux_name + "_on_mux_only n_in n_out n_gate n_gate_n n_vdd n_gnd\n")
	# Write level 1 netlist
	spice_file.write("Xptran_" + mux_name + "_L1 n_in n_1 n_gate n_gnd ptran Wn=ptran_" + mux_name + "_L1_nmos\n")
	current_node = "n_1"
	for i in range(1, level1_size):
		new_node = "n_1_" + str(i)
		spice_file.write("Xwire_" + mux_name + "_L1_" + str(i) + " " + current_node + " " + new_node + 
							" wire Rw='wire_" + mux_name + "_L1_res/" + str(level1_size) + "' Cw='wire_" +
							mux_name + "_L1_cap/" + str(level1_size) + "'\n")
		spice_file.write("Xptran_" + mux_name + "_L1_" + str(i) + "h n_gnd " + new_node + " n_gnd n_gnd ptran Wn=ptran_" + mux_name + "_L1_nmos\n")
		current_node = new_node
	new_node = "n_1_" + str(level1_size)
	spice_file.write("Xwire_" + mux_name + "_L1_" + str(level1_size) + " " + current_node + " " + new_node + 
							" wire Rw='wire_" + mux_name + "_L1_res/" + str(level1_size) + "' Cw='wire_" +
							mux_name + "_L1_cap/" + str(level1_size) + "'\n")
	current_node = new_node
	# Write level 2 netlist
	spice_file.write("Xptran_" + mux_name + "_L2 " + current_node + " n_2 n_gate n_gnd ptran Wn=ptran_" + mux_name + "_L2_nmos\n")
	current_node = "n_2"
	wire_counter = 1
	tran_counter = 1
	# These are the switches below driver connection
	for i in range(1, int(level2_size/2)):
		new_node = "n_2_" + str(i)
		spice_file.write("Xwire_" + mux_name + "_L2_" + str(wire_counter) + " " + current_node + " " + new_node + 
							" wire Rw='wire_" + mux_name + "_L2_res/" + str(level2_size-1) + "' Cw='wire_" +
							mux_name + "_L2_cap/" + str(level2_size-1) + "'\n")
		spice_file.write("Xptran_" + mux_name + "_L2_" + str(tran_counter) + "h n_gnd " + new_node + " n_gnd n_gnd ptran Wn=ptran_" + mux_name + "_L2_nmos\n")
		wire_counter = wire_counter + 1
		tran_counter = tran_counter + 1
		current_node = new_node
	# These are the middle wires
	# If level size is odd, we put a full size wire, if even, wire is only half size (wire is in middle of two switches) 
	if level2_size%2==0:
		spice_file.write("Xwire_" + mux_name + "_L2_" + str(wire_counter) + " " + current_node + " n_out" + 
							" wire Rw='wire_" + mux_name + "_L2_res/" + str(2*(level2_size-1)) + "' Cw='wire_" +
							mux_name + "_L2_cap/" + str(2*(level2_size-1)) + "'\n")
		wire_counter = wire_counter + 1
		new_node = "n_2_" + str(int(level2_size/2))
		spice_file.write("Xwire_" + mux_name + "_L2_" + str(wire_counter) + " " + " n_out " + new_node + 
							" wire Rw='wire_" + mux_name + "_L2_res/" + str(2*(level2_size-1)) + "' Cw='wire_" +
							mux_name + "_L2_cap/" + str(2*(level2_size-1)) + "'\n")
		spice_file.write("Xptran_" + mux_name + "_L2_" + str(tran_counter) + "h n_gnd " + new_node + " n_gnd n_gnd ptran Wn=ptran_" + mux_name + "_L2_nmos\n")
		wire_counter = wire_counter + 1
		tran_counter = tran_counter + 1
		current_node = new_node
	else:
		spice_file.write("Xwire_" + mux_name + "_L2_" + str(wire_counter) + " " + current_node + " n_out" + 
							" wire Rw='wire_" + mux_name + "_L2_res/" + str(level2_size-1) + "' Cw='wire_" +
							mux_name + "_L2_cap/" + str(level2_size-1) + "'\n")
		spice_file.write("Xptran_" + mux_name + "_L2_" + str(tran_counter) + "h n_gnd n_out n_gnd n_gnd ptran Wn=ptran_" + mux_name + "_L2_nmos\n")
		wire_counter = wire_counter + 1
		tran_counter = tran_counter + 1
		new_node = "n_2_" + str(int(level2_size/2))
		spice_file.write("Xwire_" + mux_name + "_L2_" + str(wire_counter) + " " + " n_out " + new_node + 
							" wire Rw='wire_" + mux_name + "_L2_res/" + str(level2_size-1) + "' Cw='wire_" +
							mux_name + "_L2_cap/" + str(level2_size-1) + "'\n")
		spice_file.write("Xptran_" + mux_name + "_L2_" + str(tran_counter) + "h n_gnd " + new_node + " n_gnd n_gnd ptran Wn=ptran_" + mux_name + "_L2_nmos\n")
		wire_counter = wire_counter + 1
		tran_counter = tran_counter + 1
		current_node = new_node
	# These are the switches above driver connection
	for i in range(1, int(level2_size/2)):
		new_node = "n_2_" + str(i+int(level2_size/2))
		spice_file.write("Xwire_" + mux_name + "_L2_" + str(wire_counter) + " " + current_node + " " + new_node + 
							" wire Rw='wire_" + mux_name + "_L2_res/" + str(level2_size-1) + "' Cw='wire_" +
							mux_name + "_L2_cap/" + str(level2_size-1) + "'\n")
		spice_file.write("Xptran_" + mux_name + "_L2_" + str(tran_counter) + "h n_gnd " + new_node + " n_gnd n_gnd ptran Wn=ptran_" + mux_name + "_L2_nmos\n")
		wire_counter = wire_counter + 1
		tran_counter = tran_counter + 1
		current_node = new_node  
	spice_file.write(".ENDS\n\n\n")


[docs] def generate_ptran_2lvl_mux(spice_filename, mux_name, implemented_mux_size, level1_size, level2_size): """ Creates two-level MUX circuits There are 3 different types of MUX that are generated depending on how 'on' the mux is 1. Fully on (both levels are on) circuit name: mux_name + "_on" 2. Partially on (only level 1 is on) circuit name: mux_name + "_partial" 3. Off (both levels are off) circuit name: mux_name + "_off" """ # Open SPICE file for appending spice_file = open(spice_filename, 'a') # Generate SPICE subcircuits _generate_ptran_driver(spice_file, mux_name, implemented_mux_size) _generate_ptran_2lvl_mux_off(spice_file, mux_name, implemented_mux_size) _generate_ptran_2lvl_mux_partial(spice_file, mux_name, implemented_mux_size, level1_size) _generate_ptran_2lvl_mux_on(spice_file, mux_name, implemented_mux_size, level1_size, level2_size) # Create the fully-on MUX circuit spice_file.write("******************************************************************************************\n") spice_file.write("* " + mux_name + " subcircuit (" + str(implemented_mux_size) + ":1), fully turned on \n") spice_file.write("******************************************************************************************\n") spice_file.write(".SUBCKT " + mux_name + "_on n_in n_out n_gate n_gate_n n_vdd n_gnd\n") spice_file.write("X" + mux_name + "_on_mux_only n_in n_1_1 n_gate n_gate_n n_vdd n_gnd " + mux_name + "_on_mux_only\n") spice_file.write("X" + mux_name + "_driver n_1_1 n_out n_vdd n_gnd " + mux_name + "_driver\n") spice_file.write(".ENDS\n\n\n") # Close SPICE file spice_file.close() # Create a list of all transistors used in this subcircuit tran_names_list = [] tran_names_list.append("ptran_" + mux_name + "_L1_nmos") tran_names_list.append("ptran_" + mux_name + "_L2_nmos") tran_names_list.append("rest_" + mux_name + "_pmos") tran_names_list.append("inv_" + mux_name + "_1_nmos") tran_names_list.append("inv_" + mux_name + "_1_pmos") tran_names_list.append("inv_" + mux_name + "_2_nmos") tran_names_list.append("inv_" + mux_name + "_2_pmos") # Create a list of all wires used in this subcircuit wire_names_list = [] wire_names_list.append("wire_" + mux_name + "_driver") wire_names_list.append("wire_" + mux_name + "_L1") wire_names_list.append("wire_" + mux_name + "_L2") return tran_names_list, wire_names_list
[docs] def generate_ptran_2lvl_mux_no_driver(spice_filename, mux_name, implemented_mux_size, level1_size, level2_size): """ Creates two-level MUX files There are 3 different types of MUX that are generated depending on how 'on' the mux is 1. Fully on (both levels are on) circuit name: mux_name + "_on" 2. Partially on (only level 1 is on) circuit name: mux_name + "_partial" 3. Off (both levels are off) circuit name: mux_name + "_off" No driver is attached to the on mux (we need this for the local routing mux) """ # Open SPICE file for appending spice_file = open(spice_filename, 'a') # Generate SPICE subcircuits _generate_ptran_sense_only(spice_file, mux_name, implemented_mux_size) _generate_ptran_2lvl_mux_off(spice_file, mux_name, implemented_mux_size) _generate_ptran_2lvl_mux_partial(spice_file, mux_name, implemented_mux_size, level1_size) _generate_ptran_2lvl_mux_on(spice_file, mux_name, implemented_mux_size, level1_size, level2_size) # Create the fully-on MUX circuit spice_file.write("******************************************************************************************\n") spice_file.write("* " + mux_name + " subcircuit (" + str(implemented_mux_size) + ":1), fully turned on \n") spice_file.write("******************************************************************************************\n") spice_file.write(".SUBCKT " + mux_name + "_on n_in n_out n_gate n_gate_n n_vdd n_gnd\n") spice_file.write("X" + mux_name + "_on_mux_only n_in n_1_1 n_gate n_gate_n n_vdd n_gnd " + mux_name + "_on_mux_only\n") spice_file.write("X" + mux_name + "_sense n_1_1 n_out n_vdd n_gnd " + mux_name + "_sense\n") spice_file.write(".ENDS\n\n\n") # Close SPICE file spice_file.close() # Create a list of all transistors used in this subcircuit tran_names_list = [] tran_names_list.append("ptran_" + mux_name + "_L1_nmos") tran_names_list.append("ptran_" + mux_name + "_L2_nmos") tran_names_list.append("rest_" + mux_name + "_pmos") tran_names_list.append("inv_" + mux_name + "_1_nmos") tran_names_list.append("inv_" + mux_name + "_1_pmos") # Create a list of all wires used in this subcircuit wire_names_list = [] wire_names_list.append("wire_" + mux_name + "_L1") wire_names_list.append("wire_" + mux_name + "_L2") return tran_names_list, wire_names_list
[docs] def generate_ptran_2_to_1_mux(spice_filename, mux_name): """ Generate a 2:1 pass-transistor MUX with shared SRAM """ # Open SPICE file for appending spice_file = open(spice_filename, 'a') # Create the 2:1 MUX circuit spice_file.write("******************************************************************************************\n") spice_file.write("* " + mux_name + " subcircuit (2:1)\n") spice_file.write("******************************************************************************************\n") spice_file.write(".SUBCKT " + mux_name + " n_in n_out n_gate n_gate_n n_vdd n_gnd\n") spice_file.write("Xptran_" + mux_name + " n_in n_1_1 n_gate n_gnd ptran Wn=ptran_" + mux_name + "_nmos\n") spice_file.write("Xwire_" + mux_name + " n_1_1 n_1_2 wire Rw='wire_" + mux_name + "_res/2' Cw='wire_" + mux_name + "_cap/2'\n") spice_file.write("Xwire_" + mux_name + "_h n_1_2 n_1_3 wire Rw='wire_" + mux_name + "_res/2' Cw='wire_" + mux_name + "_cap/2'\n") spice_file.write("Xptran_" + mux_name + "_h n_gnd n_1_3 n_gnd n_gnd ptran Wn=ptran_" + mux_name + "_nmos\n") spice_file.write("Xrest_" + mux_name + " n_1_2 n_2_1 n_vdd n_gnd rest Wp=rest_" + mux_name + "_pmos\n") spice_file.write("Xinv_" + mux_name + "_1 n_1_2 n_2_1 n_vdd n_gnd inv Wn=inv_" + mux_name + "_1_nmos Wp=inv_" + mux_name + "_1_pmos\n") spice_file.write("Xwire_" + mux_name + "_driver n_2_1 n_2_2 wire Rw=wire_" + mux_name + "_driver_res Cw=wire_" + mux_name + "_driver_cap\n") spice_file.write("Xinv_" + mux_name + "_2 n_2_2 n_out n_vdd n_gnd inv Wn=inv_" + mux_name + "_2_nmos Wp=inv_" + mux_name + "_2_pmos\n") spice_file.write(".ENDS\n\n\n") spice_file.close() # Create a list of all transistors used in this subcircuit tran_names_list = [] tran_names_list.append("ptran_" + mux_name + "_nmos") tran_names_list.append("rest_" + mux_name + "_pmos") tran_names_list.append("inv_" + mux_name + "_1_nmos") tran_names_list.append("inv_" + mux_name + "_1_pmos") tran_names_list.append("inv_" + mux_name + "_2_nmos") tran_names_list.append("inv_" + mux_name + "_2_pmos") # Create a list of all wires used in this subcircuit wire_names_list = [] wire_names_list.append("wire_" + mux_name) wire_names_list.append("wire_" + mux_name + "_driver") return tran_names_list, wire_names_list
def _generate_tgate_driver(spice_file, mux_name, implemented_mux_size): """ Generate mux driver for pass-transistor based MUX (it has a level restorer) """ # Create the MUX output driver circuit spice_file.write("******************************************************************************************\n") spice_file.write("* " + mux_name + " driver subcircuit (" + str(implemented_mux_size) + ":1)\n") spice_file.write("******************************************************************************************\n") spice_file.write(".SUBCKT " + mux_name + "_driver n_in n_out n_vdd n_gnd\n") # spice_file.write("Xrest_" + mux_name + " n_in n_1_1 n_vdd n_gnd rest Wp=rest_" + mux_name + "_pmos\n") spice_file.write("Xinv_" + mux_name + "_1 n_in n_1_1 n_vdd n_gnd inv Wn=inv_" + mux_name + "_1_nmos Wp=inv_" + mux_name + "_1_pmos\n") spice_file.write("Xwire_" + mux_name + "_driver n_1_1 n_1_2 wire Rw=wire_" + mux_name + "_driver_res Cw=wire_" + mux_name + "_driver_cap\n") spice_file.write("Xinv_" + mux_name + "_2 n_1_2 n_out n_vdd n_gnd inv Wn=inv_" + mux_name + "_2_nmos Wp=inv_" + mux_name + "_2_pmos\n") spice_file.write(".ENDS\n\n\n") def _generate_tgate_sense_only(spice_file, mux_name, implemented_mux_size): """ Generate mux driver for pass-transistor based MUX (it has a level restorer) """ # Create the MUX output sense inverter only circuit spice_file.write("******************************************************************************************\n") spice_file.write("* " + mux_name + " sense inverter subcircuit (" + str(implemented_mux_size) + ":1)\n") spice_file.write("******************************************************************************************\n") spice_file.write(".SUBCKT " + mux_name + "_sense n_in n_out n_vdd n_gnd\n") # spice_file.write("Xrest_" + mux_name + " n_in n_out n_vdd n_gnd rest Wp=rest_" + mux_name + "_pmos\n") spice_file.write("Xinv_" + mux_name + "_1 n_in n_out n_vdd n_gnd inv Wn=inv_" + mux_name + "_1_nmos Wp=inv_" + mux_name + "_1_pmos\n") spice_file.write(".ENDS\n\n\n") def _generate_tgate_2lvl_mux_off(spice_file, mux_name, implemented_mux_size): """ Generate off pass-transistor 2-level mux """ # Create the off MUX circuit spice_file.write("******************************************************************************************\n") spice_file.write("* " + mux_name + " subcircuit (" + str(implemented_mux_size) + ":1), turned off \n") spice_file.write("******************************************************************************************\n") spice_file.write(".SUBCKT " + mux_name + "_off n_in n_gate n_gate_n n_vdd n_gnd\n") spice_file.write("Xtgate_" + mux_name + "_L1 n_in n_gnd n_gnd n_vdd n_vdd n_gnd tgate Wn=tgate_" + mux_name + "_L1_nmos Wp=tgate_" + mux_name + "_L1_pmos\n") spice_file.write(".ENDS\n\n\n") def _generate_tgate_2lvl_mux_partial(spice_file, mux_name, implemented_mux_size, level1_size): """ Generate partially on pass-transistor 2-level mux """ # Create the partially-on MUX circuit spice_file.write("******************************************************************************************\n") spice_file.write("* " + mux_name + " subcircuit (" + str(implemented_mux_size) + ":1), partially turned on\n") spice_file.write("******************************************************************************************\n") spice_file.write(".SUBCKT " + mux_name + "_partial n_in n_gate n_gate_n n_vdd n_gnd\n") # Write level 1 netlist spice_file.write("Xtgate_" + mux_name + "_L1 n_in n_1 n_gate n_gate_n n_vdd n_gnd tgate Wn=tgate_" + mux_name + "_L1_nmos Wp=tgate_" + mux_name + "_L1_pmos\n") current_node = "n_1" for i in range(1, level1_size): new_node = "n_1_" + str(i) spice_file.write("Xwire_" + mux_name + "_L1_" + str(i) + " " + current_node + " " + new_node + " wire Rw='wire_" + mux_name + "_L1_res/" + str(level1_size) + "' Cw='wire_" + mux_name + "_L1_cap/" + str(level1_size) + "'\n") spice_file.write("Xtgate_" + mux_name + "_L1_" + str(i) + "h n_gnd " + new_node + " n_gnd n_vdd n_vdd n_gnd tgate Wn=tgate_" + mux_name + "_L1_nmos Wp=tgate_" + mux_name + "_L1_pmos\n") current_node = new_node new_node = "n_1_" + str(level1_size) spice_file.write("Xwire_" + mux_name + "_L1_" + str(level1_size) + " " + current_node + " " + new_node + " wire Rw='wire_" + mux_name + "_L1_res/" + str(level1_size) + "' Cw='wire_" + mux_name + "_L1_cap/" + str(level1_size) + "'\n") current_node = new_node # Write level 2 netlist spice_file.write("Xtgate_" + mux_name + "_L2 " + current_node + " n_gnd n_gnd n_vdd n_vdd n_gnd tgate Wn=tgate_" + mux_name + "_L2_nmos Wp=tgate_" + mux_name + "_L2_pmos\n") spice_file.write(".ENDS\n\n\n") def _generate_tgate_2lvl_mux_on(spice_file, mux_name, implemented_mux_size, level1_size, level2_size): """ Generate on pass-transistor 2-level mux, never call this outside this file """ # Create the fully-on MUX circuit spice_file.write("******************************************************************************************\n") spice_file.write("* " + mux_name + " subcircuit (" + str(implemented_mux_size) + ":1), fully turned on (mux only)\n") spice_file.write("******************************************************************************************\n") spice_file.write(".SUBCKT " + mux_name + "_on_mux_only n_in n_out n_gate n_gate_n n_vdd n_gnd\n") # Write level 1 netlist spice_file.write("Xtgate_" + mux_name + "_L1 n_in n_1 n_gate n_gate_n n_vdd n_gnd tgate Wn=tgate_" + mux_name + "_L1_nmos Wp=tgate_" + mux_name + "_L1_pmos\n") current_node = "n_1" for i in range(1, level1_size): new_node = "n_1_" + str(i) spice_file.write("Xwire_" + mux_name + "_L1_" + str(i) + " " + current_node + " " + new_node + " wire Rw='wire_" + mux_name + "_L1_res/" + str(level1_size) + "' Cw='wire_" + mux_name + "_L1_cap/" + str(level1_size) + "'\n") spice_file.write("Xtgate_" + mux_name + "_L1_" + str(i) + "h n_gnd " + new_node + " n_gnd n_vdd n_vdd n_gnd tgate Wn=tgate_" + mux_name + "_L1_nmos Wp=tgate_" + mux_name + "_L1_pmos\n") current_node = new_node new_node = "n_1_" + str(level1_size) spice_file.write("Xwire_" + mux_name + "_L1_" + str(level1_size) + " " + current_node + " " + new_node + " wire Rw='wire_" + mux_name + "_L1_res/" + str(level1_size) + "' Cw='wire_" + mux_name + "_L1_cap/" + str(level1_size) + "'\n") current_node = new_node # Write level 2 netlist spice_file.write("Xtgate_" + mux_name + "_L2 " + current_node + " n_2 n_gate n_gate_n n_vdd n_gnd tgate Wn=tgate_" + mux_name + "_L2_nmos Wp=tgate_" + mux_name + "_L2_pmos\n") current_node = "n_2" wire_counter = 1 tran_counter = 1 # These are the switches below driver connection for i in range(1, int(level2_size/2)): new_node = "n_2_" + str(i) spice_file.write("Xwire_" + mux_name + "_L2_" + str(wire_counter) + " " + current_node + " " + new_node + " wire Rw='wire_" + mux_name + "_L2_res/" + str(level2_size-1) + "' Cw='wire_" + mux_name + "_L2_cap/" + str(level2_size-1) + "'\n") spice_file.write("Xtagte_" + mux_name + "_L2_" + str(tran_counter) + "h n_gnd " + new_node + " n_gnd n_vdd n_vdd n_gnd tgate Wn=tgate_" + mux_name + "_L2_nmos Wp=tgate_" + mux_name + "_L2_pmos\n") wire_counter = wire_counter + 1 tran_counter = tran_counter + 1 current_node = new_node # These are the middle wires # If level size is odd, we put a full size wire, if even, wire is only half size (wire is in middle of two switches) if level2_size%2==0: spice_file.write("Xwire_" + mux_name + "_L2_" + str(wire_counter) + " " + current_node + " n_out" + " wire Rw='wire_" + mux_name + "_L2_res/" + str(2*(level2_size-1)) + "' Cw='wire_" + mux_name + "_L2_cap/" + str(2*(level2_size-1)) + "'\n") wire_counter = wire_counter + 1 new_node = "n_2_" + str(int(level2_size/2)) spice_file.write("Xwire_" + mux_name + "_L2_" + str(wire_counter) + " " + " n_out " + new_node + " wire Rw='wire_" + mux_name + "_L2_res/" + str(2*(level2_size-1)) + "' Cw='wire_" + mux_name + "_L2_cap/" + str(2*(level2_size-1)) + "'\n") spice_file.write("Xtgate_" + mux_name + "_L2_" + str(tran_counter) + "h n_gnd " + new_node + " n_gnd n_vdd n_vdd n_gnd tgate Wn=tgate_" + mux_name + "_L2_nmos Wp=tgate_" + mux_name + "_L2_pmos\n") wire_counter = wire_counter + 1 tran_counter = tran_counter + 1 current_node = new_node else: spice_file.write("Xwire_" + mux_name + "_L2_" + str(wire_counter) + " " + current_node + " n_out" + " wire Rw='wire_" + mux_name + "_L2_res/" + str(level2_size-1) + "' Cw='wire_" + mux_name + "_L2_cap/" + str(level2_size-1) + "'\n") spice_file.write("Xtgate_" + mux_name + "_L2_" + str(tran_counter) + "h n_gnd n_out n_gnd n_vdd n_vdd n_gnd tgate Wn=tgate_" + mux_name + "_L2_nmos Wp=tgate_" + mux_name + "_L2_pmos\n") wire_counter = wire_counter + 1 tran_counter = tran_counter + 1 new_node = "n_2_" + str(int(level2_size/2)) spice_file.write("Xwire_" + mux_name + "_L2_" + str(wire_counter) + " " + " n_out " + new_node + " wire Rw='wire_" + mux_name + "_L2_res/" + str(level2_size-1) + "' Cw='wire_" + mux_name + "_L2_cap/" + str(level2_size-1) + "'\n") spice_file.write("Xtgate_" + mux_name + "_L2_" + str(tran_counter) + "h n_gnd " + new_node + " n_gnd n_vdd n_vdd n_gnd tgate Wn=tgate_" + mux_name + "_L2_nmos Wp=tgate_" + mux_name + "_L2_pmos\n") wire_counter = wire_counter + 1 tran_counter = tran_counter + 1 current_node = new_node # These are the switches above driver connection for i in range(1, int(level2_size/2)): new_node = "n_2_" + str(i+int(level2_size/2)) spice_file.write("Xwire_" + mux_name + "_L2_" + str(wire_counter) + " " + current_node + " " + new_node + " wire Rw='wire_" + mux_name + "_L2_res/" + str(level2_size-1) + "' Cw='wire_" + mux_name + "_L2_cap/" + str(level2_size-1) + "'\n") spice_file.write("Xtgate_" + mux_name + "_L2_" + str(tran_counter) + "h n_gnd " + new_node + " n_gnd n_vdd n_vdd n_gnd tgate Wn=tgate_" + mux_name + "_L2_nmos Wp=tgate_" + mux_name + "_L2_pmos\n") wire_counter = wire_counter + 1 tran_counter = tran_counter + 1 current_node = new_node spice_file.write(".ENDS\n\n\n")
[docs] def generate_tgate_2lvl_mux(spice_filename, mux_name, implemented_mux_size, level1_size, level2_size): """ Creates two-level MUX circuits There are 3 different types of MUX that are generated depending on how 'on' the mux is 1. Fully on (both levels are on) circuit name: mux_name + "_on" 2. Partially on (only level 1 is on) circuit name: mux_name + "_partial" 3. Off (both levels are off) circuit name: mux_name + "_off" """ # Open SPICE file for appending spice_file = open(spice_filename, 'a') # Generate SPICE subcircuits _generate_tgate_driver(spice_file, mux_name, implemented_mux_size) _generate_tgate_2lvl_mux_off(spice_file, mux_name, implemented_mux_size) _generate_tgate_2lvl_mux_partial(spice_file, mux_name, implemented_mux_size, level1_size) _generate_tgate_2lvl_mux_on(spice_file, mux_name, implemented_mux_size, level1_size, level2_size) # Create the fully-on MUX circuit spice_file.write("******************************************************************************************\n") spice_file.write("* " + mux_name + " subcircuit (" + str(implemented_mux_size) + ":1), fully turned on \n") spice_file.write("******************************************************************************************\n") spice_file.write(".SUBCKT " + mux_name + "_on n_in n_out n_gate n_gate_n n_vdd n_gnd\n") spice_file.write("X" + mux_name + "_on_mux_only n_in n_1_1 n_gate n_gate_n n_vdd n_gnd " + mux_name + "_on_mux_only\n") spice_file.write("X" + mux_name + "_driver n_1_1 n_out n_vdd n_gnd " + mux_name + "_driver\n") spice_file.write(".ENDS\n\n\n") # Close SPICE file spice_file.close() # Create a list of all transistors used in this subcircuit tran_names_list = [] tran_names_list.append("tgate_" + mux_name + "_L1_nmos") tran_names_list.append("tgate_" + mux_name + "_L1_pmos") tran_names_list.append("tgate_" + mux_name + "_L2_nmos") tran_names_list.append("tgate_" + mux_name + "_L2_pmos") # tran_names_list.append("rest_" + mux_name + "_pmos") tran_names_list.append("inv_" + mux_name + "_1_nmos") tran_names_list.append("inv_" + mux_name + "_1_pmos") tran_names_list.append("inv_" + mux_name + "_2_nmos") tran_names_list.append("inv_" + mux_name + "_2_pmos") # Create a list of all wires used in this subcircuit wire_names_list = [] wire_names_list.append("wire_" + mux_name + "_driver") wire_names_list.append("wire_" + mux_name + "_L1") wire_names_list.append("wire_" + mux_name + "_L2") return tran_names_list, wire_names_list
[docs] def generate_tgate_2lvl_mux_no_driver(spice_filename, mux_name, implemented_mux_size, level1_size, level2_size): """ Creates two-level MUX files There are 3 different types of MUX that are generated depending on how 'on' the mux is 1. Fully on (both levels are on) circuit name: mux_name + "_on" 2. Partially on (only level 1 is on) circuit name: mux_name + "_partial" 3. Off (both levels are off) circuit name: mux_name + "_off" No driver is attached to the on mux (we need this for the local routing mux) """ # Open SPICE file for appending spice_file = open(spice_filename, 'a') # Generate SPICE subcircuits _generate_tgate_sense_only(spice_file, mux_name, implemented_mux_size) _generate_tgate_2lvl_mux_off(spice_file, mux_name, implemented_mux_size) _generate_tgate_2lvl_mux_partial(spice_file, mux_name, implemented_mux_size, level1_size) _generate_tgate_2lvl_mux_on(spice_file, mux_name, implemented_mux_size, level1_size, level2_size) # Create the fully-on MUX circuit spice_file.write("******************************************************************************************\n") spice_file.write("* " + mux_name + " subcircuit (" + str(implemented_mux_size) + ":1), fully turned on \n") spice_file.write("******************************************************************************************\n") spice_file.write(".SUBCKT " + mux_name + "_on n_in n_out n_gate n_gate_n n_vdd n_gnd\n") spice_file.write("X" + mux_name + "_on_mux_only n_in n_1_1 n_gate n_gate_n n_vdd n_gnd " + mux_name + "_on_mux_only\n") spice_file.write("X" + mux_name + "_sense n_1_1 n_out n_vdd n_gnd " + mux_name + "_sense\n") spice_file.write(".ENDS\n\n\n") # Close SPICE file spice_file.close() # Create a list of all transistors used in this subcircuit tran_names_list = [] tran_names_list.append("tgate_" + mux_name + "_L1_nmos") tran_names_list.append("tgate_" + mux_name + "_L1_pmos") tran_names_list.append("tgate_" + mux_name + "_L2_nmos") tran_names_list.append("tgate_" + mux_name + "_L2_pmos") # tran_names_list.append("rest_" + mux_name + "_pmos") tran_names_list.append("inv_" + mux_name + "_1_nmos") tran_names_list.append("inv_" + mux_name + "_1_pmos") # Create a list of all wires used in this subcircuit wire_names_list = [] wire_names_list.append("wire_" + mux_name + "_L1") wire_names_list.append("wire_" + mux_name + "_L2") return tran_names_list, wire_names_list
[docs] def generate_tgate_2_to_1_mux(spice_filename, mux_name): """ Generate a 2:1 pass-transistor MUX with shared SRAM """ # Open SPICE file for appending spice_file = open(spice_filename, 'a') # Create the 2:1 MUX circuit spice_file.write("******************************************************************************************\n") spice_file.write("* " + mux_name + " subcircuit (2:1)\n") spice_file.write("******************************************************************************************\n") spice_file.write(".SUBCKT " + mux_name + " n_in n_out n_gate n_gate_n n_vdd n_gnd\n") spice_file.write("Xtgate_" + mux_name + " n_in n_1_1 n_gate n_gate_n n_vdd n_gnd tgate Wn=tgate_" + mux_name + "_nmos Wp=tgate_" + mux_name + "_pmos\n") spice_file.write("Xwire_" + mux_name + " n_1_1 n_1_2 wire Rw='wire_" + mux_name + "_res/2' Cw='wire_" + mux_name + "_cap/2'\n") spice_file.write("Xwire_" + mux_name + "_h n_1_2 n_1_3 wire Rw='wire_" + mux_name + "_res/2' Cw='wire_" + mux_name + "_cap/2'\n") spice_file.write("Xtgate_" + mux_name + "_h n_gnd n_1_3 n_gnd n_vdd n_vdd n_gnd tgate Wn=tgate_" + mux_name + "_nmos Wp=tgate_" + mux_name + "_pmos\n") # spice_file.write("Xrest_" + mux_name + " n_1_2 n_2_1 n_vdd n_gnd rest Wp=rest_" + mux_name + "_pmos\n") spice_file.write("Xinv_" + mux_name + "_1 n_1_2 n_2_1 n_vdd n_gnd inv Wn=inv_" + mux_name + "_1_nmos Wp=inv_" + mux_name + "_1_pmos\n") spice_file.write("Xwire_" + mux_name + "_driver n_2_1 n_2_2 wire Rw=wire_" + mux_name + "_driver_res Cw=wire_" + mux_name + "_driver_cap\n") spice_file.write("Xinv_" + mux_name + "_2 n_2_2 n_out n_vdd n_gnd inv Wn=inv_" + mux_name + "_2_nmos Wp=inv_" + mux_name + "_2_pmos\n") spice_file.write(".ENDS\n\n\n") spice_file.close() # Create a list of all transistors used in this subcircuit tran_names_list = [] tran_names_list.append("tgate_" + mux_name + "_nmos") tran_names_list.append("tgate_" + mux_name + "_pmos") # tran_names_list.append("rest_" + mux_name + "_pmos") tran_names_list.append("inv_" + mux_name + "_1_nmos") tran_names_list.append("inv_" + mux_name + "_1_pmos") tran_names_list.append("inv_" + mux_name + "_2_nmos") tran_names_list.append("inv_" + mux_name + "_2_pmos") # Create a list of all wires used in this subcircuit wire_names_list = [] wire_names_list.append("wire_" + mux_name) wire_names_list.append("wire_" + mux_name + "_driver") return tran_names_list, wire_names_list
[docs] def generate_dedicated_driver(spice_filename, driver_name, num_bufs, top_name): """ Generate a driver for the dedicated routing links """ # Open SPICE file for appending spice_file = open(spice_filename, 'a') # Create the driver spice_file.write("******************************************************************************************\n") spice_file.write("* " + driver_name + " subcircuit (2:1)\n") spice_file.write("******************************************************************************************\n") spice_file.write(".SUBCKT " + driver_name + " n_in n_out n_vdd n_gnd\n") count = 1 spice_file.write("Xinv_" + driver_name + "_"+str(count)+" n_in n_1_"+str(count)+" n_vdd n_gnd inv Wn=inv_" + driver_name + "_"+str(1)+"_nmos Wp=inv_" + driver_name + "_"+str(1)+"_pmos\n") spice_file.write("Xwirer_edi_"+str(count)+" n_1_"+str(count)+" n_1_"+str(count+1)+" wire Rw=wire_"+top_name+"_2_res/"+str(num_bufs*2)+" Cw=wire_"+top_name+"_2_cap/"+str(num_bufs*2)+" \n") count += 1 for i in range(2, num_bufs * 2): spice_file.write("Xinv_" + driver_name + "_"+str(i)+" n_1_"+str(count)+" n_1_"+str(count + 1)+" n_vdd n_gnd inv Wn=inv_" + driver_name + "_"+str(i)+"_nmos Wp=inv_" + driver_name + "_"+str(i)+"_pmos\n") spice_file.write("Xwirer_edi_"+str(i)+" n_1_"+str(count + 1)+" n_1_"+str(count + 2)+" wire Rw=wire_"+top_name+"_2_res/"+str(num_bufs*2)+" Cw=wire_"+top_name+"_2_cap/"+str(num_bufs*2)+" \n") count += 2 spice_file.write("Xinv_" + driver_name + "_"+str(num_bufs * 2)+" n_1_"+str(count)+" n_1_"+str(count + 1)+" n_vdd n_gnd inv Wn=inv_" + driver_name + "_"+str(num_bufs * 2)+"_nmos Wp=inv_" + driver_name + "_"+str(num_bufs * 2)+"_pmos\n") spice_file.write("Xwirer_edi_"+str(num_bufs * 2 + 1)+" n_1_"+str(count + 1)+" n_out wire Rw=wire_"+top_name+"_2_res/"+str(num_bufs*2)+" Cw=wire_"+top_name+"_2_cap/"+str(num_bufs*2)+" \n") spice_file.write(".ENDS\n\n\n") spice_file.close() # Create a list of all transistors used in this subcircuit tran_names_list = [] for i in range(1, num_bufs * 2 + 1): tran_names_list.append("inv_" + driver_name + "_"+str(i)+"_nmos") tran_names_list.append("inv_" + driver_name + "_"+str(i)+"_pmos") # Create a list of all wires used in this subcircuit wire_names_list = [] return tran_names_list, wire_names_list