def unblock_channel(address_id, directory_id, num_caches): name = 'unblock_channel_{}_{}'.format(address_id, directory_id) inputs = [] outputs = [] transitions = [] locations = ['empty'] for cache_id in range(num_caches): suffix = '_{}_{}_{}'.format(cache_id, directory_id, address_id) for port in ['UnblockEMsg', 'UnblockSMsg']: input_channel_name = port + suffix input_channel = util.new_variable(input_channel_name, 'unit') inputs.append(input_channel) output_channel = util.new_variable(port + 'P' + suffix, 'unit') outputs.append(output_channel) full_state = 'full_{}'.format(input_channel_name) locations.append(full_state) transitions.append((None, 'empty', input_channel, TRUE, [], full_state)) transitions.append((None, full_state, output_channel, [ZERO], TRUE, [], 'empty')) return automaton.SymbolicAutomaton('{}_channel'.format(name), locations, 'empty', transitions, variables=[], initial_values=[], input_channels=inputs, output_channels=outputs)
def unblock_channel(address_id, directory_id, num_caches): name = "unblock_channel_{}_{}".format(address_id, directory_id) inputs = [] outputs = [] transitions = [] locations = ["empty"] for cache_id in range(num_caches): suffix = "_{}_{}_{}".format(cache_id, directory_id, address_id) for port in ["UnblockEMsg", "UnblockSMsg"]: input_channel_name = port + suffix input_channel = util.new_variable(input_channel_name, "unit") inputs.append(input_channel) output_channel = util.new_variable(port + "P" + suffix, "unit") outputs.append(output_channel) full_state = "full_{}".format(input_channel_name) locations.append(full_state) transitions.append((None, "empty", input_channel, TRUE, [], full_state)) transitions.append((None, full_state, output_channel, [ZERO], TRUE, [], "empty")) return automaton.SymbolicAutomaton( "{}_channel".format(name), locations, "empty", transitions, variables=[], initial_values=[], input_channels=inputs, output_channels=outputs, )
def request_channel(address_id, cache_id, directory_id, num_values): name = "request_channel_{}_{}_{}".format(address_id, cache_id, directory_id) inputs = [] outputs = [] suffix = "_{}_{}_{}".format(cache_id, directory_id, address_id) for port in ["GetXMsg", "GetSMsg"]: inputs.append(util.new_variable(port + suffix, "unit")) outputs.append(util.new_variable(port + "P" + suffix, "unit")) inputs.append(z3p.Int("WBMsg" + suffix)) outputs.append(z3p.Int("WBMsgP" + suffix)) data_ranges = {z3p.Int("WBMsg" + suffix): (0, num_values - 1)} return lossless_non_duplicating_blocking_capacity_one_channel(name, inputs, outputs, data_ranges, {})
def request_channel(address_id, cache_id, directory_id, num_values): name = 'request_channel_{}_{}_{}'.format(address_id, cache_id, directory_id) inputs = [] outputs = [] suffix = '_{}_{}_{}'.format(cache_id, directory_id, address_id) for port in ['GetXMsg', 'GetSMsg']: inputs.append(util.new_variable(port + suffix, 'unit')) outputs.append(util.new_variable(port + 'P' + suffix, 'unit')) inputs.append(z3p.Int('WBMsg' + suffix)) outputs.append(z3p.Int('WBMsgP' + suffix)) data_ranges = {z3p.Int('WBMsg' + suffix): (0, num_values - 1)} return lossless_non_duplicating_blocking_capacity_one_channel(name, inputs, outputs, data_ranges, {})
def timer(): timeout = util.new_variable('timeout', 'unit') transitions = [('t0', 'initial', timeout, [z3p.IntVal(0)], z3p.BoolVal(True), [], 'initial')] return automaton.SymbolicAutomaton('timer', ['initial'], 'initial', transitions, output_channels=[timeout])
def sender(): transitions = [] input_message = z3p.Int('sender_input_message') sender_tag = z3p.Int('sender_tag') ack_tag = z3p.Int('ack_tag') forward_input_channel = z3p.Array('forward_input_channel', z3p.IntSort(), z3p.IntSort()) backward_output_channel = z3p.Int('backward_output_channel') send = z3p.Int('send') timeout = util.new_variable('timeout', 'unit') transitions.append(('t0', 'initial', send, z3p.BoolVal(True), [(input_message, send)], 'q0')) transitions.append( ('t1', 'q0', forward_input_channel, [sender_tag, input_message], z3p.BoolVal(True), [], 'q1')) transitions.append(('t2', 'q1', timeout, z3p.BoolVal(True), [], 'q0')) transitions.append(('t3', 'q1', backward_output_channel, z3p.BoolVal(True), [(ack_tag, backward_output_channel)], 'q2')) transitions.append(('t4', 'q2', z3p.Eq(ack_tag, sender_tag), [ (sender_tag, z3p.If(z3p.Eq(sender_tag, 0), z3p.IntVal(1), z3p.IntVal(0))) ], 'initial')) transitions.append(('t5', 'q2', z3p.Neq(ack_tag, sender_tag), [], 'q0')) return automaton.SymbolicAutomaton( 'sender', ['initial', 'q0', 'q1', 'q2'], 'initial', transitions, variables=[input_message, sender_tag, ack_tag], initial_values=[z3p.IntVal(0), z3p.IntVal(0), z3p.IntVal(0)], input_channels=[send, timeout, backward_output_channel], output_channels=[forward_input_channel], variable_ranges={ input_message: (min_value_message, max_value_message), sender_tag: (0, 1), ack_tag: (0, 1) }, output_channel_ranges={ forward_input_channel[1]: (min_value_message, max_value_message), forward_input_channel[0]: (0, 1) })
def environment(cache_id, directory_id, address_id, num_values): transitions = [] variables = [] variable_ranges = {} PendingStore = z3p.Int("pending_store_environment_{}_{}_{}".format(cache_id, directory_id, address_id)) StoreResult = z3p.Int("store_result_{}_{}_{}".format(cache_id, directory_id, address_id)) variable_ranges[PendingStore] = (0, num_values - 1) variable_ranges[StoreResult] = (0, num_values - 1) variables = [PendingStore, StoreResult] initial_values = [ZERO, ZERO] locations = [ "Env{}_Initial".format(cache_id), "Env{}_PendingLD".format(cache_id), "Env{}_PendingST".format(cache_id), "Env{}_PendingEV".format(cache_id), "Env{}_Error".format(cache_id), ] # input messages suffix = "_{}_{}_{}".format(cache_id, directory_id, address_id) LDAckMsg = z3p.Int("LDAckMsg" + suffix) STAckMsg = z3p.Int("STAckMsg" + suffix) EVAckMsg = util.new_variable("EVAckMsg" + suffix, "unit") input_channels = [LDAckMsg, STAckMsg, EVAckMsg] # input_channels = [LDAckMsg] LDMsg = util.new_variable("LDMsg" + suffix, "unit") STMsg = z3p.Int("STMsg" + suffix) EVMsg = util.new_variable("EVMsg" + suffix, "unit") output_channels = [LDMsg, STMsg, EVMsg] # output_channels = [LDMsg] transitions = [] # // Load flow # Env_Initial send LDMsg[c][d][a] {} -> Env_PendingLD; # Env_PendingLD on LDAckMsg[c][d][a] (v) {} -> Env_Initial; transitions.append( (None, "Env{}_Initial".format(cache_id), LDMsg, [ZERO], TRUE, [], "Env{}_PendingLD".format(cache_id)) ) transitions.append( ( None, "Env{}_PendingLD".format(cache_id), LDAckMsg, TRUE, [(PendingStore, LDAckMsg)], "Env{}_Initial".format(cache_id), ) ) # // Store flow # foreach v in ValueType # Env_Initial send STMsg[c][d][a] (v) { PendingStore := v; } -> Env_PendingST; # Env_PendingST on STAckMsg[c][d][a] # if (v = PendingStore) {} -> Env_Initial; # if (v != PendingStore) {} -> Env_Error; for v in range(num_values): transitions.append( ( None, "Env{}_Initial".format(cache_id), STMsg, [z3p.IntVal(v)], TRUE, [(PendingStore, z3p.IntVal(v))], "Env{}_PendingST".format(cache_id), ) ) transitions.append( ( None, "Env{}_PendingST".format(cache_id), STAckMsg, TRUE, [(StoreResult, STAckMsg)], "Env{}_PendingST2".format(cache_id), ) ) transitions.append( ( None, "Env{}_PendingST2".format(cache_id), z3p.Eq(StoreResult, PendingStore), [(StoreResult, ZERO), (PendingStore, ZERO)], "Env{}_Initial".format(cache_id), ) ) transitions.append( ( None, "Env{}_PendingST2".format(cache_id), z3p.Neq(StoreResult, PendingStore), [(StoreResult, ZERO), (PendingStore, ZERO)], "Env{}_Error".format(cache_id), ) ) # // Evict flow # Env_Initial send EVMsg[c][d][a] {} -> Env_PendingEV; # Env_PendingEV on EVAckMsg[c][d][a] {} -> Env_Initial; transitions.append( (None, "Env{}_Initial".format(cache_id), EVMsg, [ZERO], TRUE, [], "Env{}_PendingEV".format(cache_id)) ) transitions.append((None, "Env{}_PendingEV".format(cache_id), EVAckMsg, TRUE, [], "Env{}_Initial".format(cache_id))) locations.extend(["Env{}_PendingST2".format(cache_id)]) return automaton.SymbolicAutomaton( "enviroment_{}_{}_{}".format(cache_id, directory_id, address_id), locations, "Env{}_Initial".format(cache_id), transitions, variables=variables, initial_values=initial_values, input_channels=input_channels, output_channels=output_channels, variable_ranges=variable_ranges, )
def response_channel(address_id, cache_id, directory_id, num_values, num_caches): name = "response_channel_{}_{}_{}".format(cache_id, address_id, directory_id) inputs = [] outputs = [] data_ranges = {} number_of_fields = {} suffix = "_{}_{}_{}".format(cache_id, directory_id, address_id) wbackmsg = "WBAckMsg" wbackmsg_input = util.new_variable(wbackmsg + suffix, "unit") wbackmsg_output = util.new_variable(wbackmsg + "P" + suffix, "unit") inputs.append(wbackmsg_input) outputs.append(wbackmsg_output) locations = ["empty"] transitions = [] full_state = "WBAckMsg_full" locations.append(full_state) transitions.append((None, "empty", wbackmsg_input, TRUE, [], full_state)) transitions.append((None, full_state, wbackmsg_output, [ZERO], TRUE, [], "empty")) variable_ranges = {} variable_data = z3p.Int("data_{}".format(name)) variable_num_caches = z3p.Int("num_caches_{}".format(name)) variable_ranges[variable_data] = (0, num_values - 1) variable_ranges[variable_num_caches] = (0, num_caches) datamsgd2c = "DataMsgD2C" datamsgd2c_input = z3p.Array(datamsgd2c + suffix, z3p.IntSort(), z3p.IntSort()) datamsgd2c_output = z3p.Array(datamsgd2c + "P" + suffix, z3p.IntSort(), z3p.IntSort()) inputs.append(datamsgd2c_input) outputs.append(datamsgd2c_output) full_state = "DataMsgD2C_full" locations.append(full_state) transitions.append( ( None, "empty", datamsgd2c_input, TRUE, [(variable_data, datamsgd2c_input[0]), (variable_num_caches, datamsgd2c_input[1])], full_state, ) ) transitions.append( ( None, full_state, datamsgd2c_output, [variable_data, variable_num_caches], TRUE, [(variable_data, ZERO), (variable_num_caches, ZERO)], "empty", ) ) datamsgc2c = "DataMsgC2C" invackmsg = "InvAckMsg" for other_cache_id in range(num_caches): if other_cache_id != cache_id: suffix2 = "_{}{}".format(other_cache_id, suffix) datamsgc2c_input = z3p.Int(datamsgc2c + suffix2) datamsgc2c_output = z3p.Int(datamsgc2c + "P" + suffix2) inputs.append(datamsgc2c_input) outputs.append(datamsgc2c_output) full_state = "DataMsgC2C_full_{}".format(other_cache_id) locations.append(full_state) transitions.append((None, "empty", datamsgc2c_input, TRUE, [(variable_data, datamsgc2c_input)], full_state)) transitions.append( (None, full_state, datamsgc2c_output, [variable_data], TRUE, [(variable_data, ZERO)], "empty") ) invackmsg_input = util.new_variable(invackmsg + suffix2, "unit") invackmsg_output = util.new_variable(invackmsg + "P" + suffix2, "unit") inputs.append(invackmsg_input) outputs.append(invackmsg_output) full_state = "InvAckMsg_full_{}".format(other_cache_id) locations.append(full_state) transitions.append((None, "empty", invackmsg_input, TRUE, [], full_state)) transitions.append((None, full_state, invackmsg_output, [ZERO], TRUE, [], "empty")) return automaton.SymbolicAutomaton( name, locations, "empty", transitions, variables=[variable_data, variable_num_caches], initial_values=[ZERO, ZERO], input_channels=inputs, output_channels=outputs, variable_ranges=variable_ranges, )
def environment(cache_id, directory_id, address_id, num_values): transitions = [] variables = [] variable_ranges = {} PendingStore = z3p.Int('pending_store_environment_{}_{}_{}'.format(cache_id, directory_id, address_id)) StoreResult = z3p.Int('store_result_{}_{}_{}'.format(cache_id, directory_id, address_id)) variable_ranges[PendingStore] = (0, num_values - 1) variable_ranges[StoreResult] = (0, num_values - 1) variables = [PendingStore, StoreResult] initial_values = [ZERO, ZERO] locations = ['Env{}_Initial'.format(cache_id), 'Env{}_PendingLD'.format(cache_id), 'Env{}_PendingST'.format(cache_id), 'Env{}_PendingEV'.format(cache_id), 'Env{}_Error'.format(cache_id)] # input messages suffix = '_{}_{}_{}'.format(cache_id, directory_id, address_id) LDAckMsg = z3p.Int('LDAckMsg' + suffix) STAckMsg = z3p.Int('STAckMsg' + suffix) EVAckMsg = util.new_variable('EVAckMsg' + suffix, 'unit') input_channels = [LDAckMsg, STAckMsg, EVAckMsg] # input_channels = [LDAckMsg] LDMsg = util.new_variable('LDMsg' + suffix, 'unit') STMsg = z3p.Int('STMsg' + suffix) EVMsg = util.new_variable('EVMsg' + suffix, 'unit') output_channels = [LDMsg, STMsg, EVMsg] # output_channels = [LDMsg] transitions = [] # // Load flow # Env_Initial send LDMsg[c][d][a] {} -> Env_PendingLD; # Env_PendingLD on LDAckMsg[c][d][a] (v) {} -> Env_Initial; transitions.append((None, 'Env{}_Initial'.format(cache_id), LDMsg, [ZERO], TRUE, [], 'Env{}_PendingLD'.format(cache_id))) transitions.append((None, 'Env{}_PendingLD'.format(cache_id), LDAckMsg, TRUE, [(PendingStore, LDAckMsg)], 'Env{}_Initial'.format(cache_id))) # // Store flow # foreach v in ValueType # Env_Initial send STMsg[c][d][a] (v) { PendingStore := v; } -> Env_PendingST; # Env_PendingST on STAckMsg[c][d][a] # if (v = PendingStore) {} -> Env_Initial; # if (v != PendingStore) {} -> Env_Error; for v in range(num_values): transitions.append((None, 'Env{}_Initial'.format(cache_id), STMsg, [z3p.IntVal(v)], TRUE, [(PendingStore, z3p.IntVal(v))], 'Env{}_PendingST'.format(cache_id))) transitions.append((None, 'Env{}_PendingST'.format(cache_id), STAckMsg, TRUE, [(StoreResult, STAckMsg)], 'Env{}_PendingST2'.format(cache_id))) transitions.append((None, 'Env{}_PendingST2'.format(cache_id), z3p.Eq(StoreResult, PendingStore), [(StoreResult, ZERO), (PendingStore, ZERO)], 'Env{}_Initial'.format(cache_id))) transitions.append((None, 'Env{}_PendingST2'.format(cache_id), z3p.Neq(StoreResult, PendingStore), [(StoreResult, ZERO), (PendingStore, ZERO)], 'Env{}_Error'.format(cache_id))) # // Evict flow # Env_Initial send EVMsg[c][d][a] {} -> Env_PendingEV; # Env_PendingEV on EVAckMsg[c][d][a] {} -> Env_Initial; transitions.append((None, 'Env{}_Initial'.format(cache_id), EVMsg, [ZERO], TRUE, [], 'Env{}_PendingEV'.format(cache_id))) transitions.append((None, 'Env{}_PendingEV'.format(cache_id), EVAckMsg, TRUE, [], 'Env{}_Initial'.format(cache_id))) locations.extend(['Env{}_PendingST2'.format(cache_id)]) return automaton.SymbolicAutomaton('enviroment_{}_{}_{}'.format(cache_id, directory_id, address_id), locations, 'Env{}_Initial'.format(cache_id), transitions, variables=variables, initial_values=initial_values, input_channels=input_channels, output_channels=output_channels, variable_ranges=variable_ranges)
def response_channel(address_id, cache_id, directory_id, num_values, num_caches): name = 'response_channel_{}_{}_{}'.format(cache_id, address_id, directory_id) inputs = [] outputs = [] data_ranges = {} number_of_fields = {} suffix = '_{}_{}_{}'.format(cache_id, directory_id, address_id) wbackmsg = 'WBAckMsg' wbackmsg_input = util.new_variable(wbackmsg + suffix, 'unit') wbackmsg_output = util.new_variable(wbackmsg + 'P' + suffix, 'unit') inputs.append(wbackmsg_input) outputs.append(wbackmsg_output) locations = ['empty'] transitions = [] full_state = 'WBAckMsg_full' locations.append(full_state) transitions.append((None, 'empty', wbackmsg_input, TRUE, [], full_state)) transitions.append((None, full_state, wbackmsg_output, [ZERO], TRUE, [], 'empty')) variable_ranges = {} variable_data = z3p.Int('data_{}'.format(name)) variable_num_caches = z3p.Int('num_caches_{}'.format(name)) variable_ranges[variable_data] = (0, num_values - 1) variable_ranges[variable_num_caches] = (0, num_caches) datamsgd2c = 'DataMsgD2C' datamsgd2c_input = z3p.Array(datamsgd2c + suffix, z3p.IntSort(), z3p.IntSort()) datamsgd2c_output = z3p.Array(datamsgd2c + 'P' + suffix, z3p.IntSort(), z3p.IntSort()) inputs.append(datamsgd2c_input) outputs.append(datamsgd2c_output) full_state = 'DataMsgD2C_full' locations.append(full_state) transitions.append((None, 'empty', datamsgd2c_input, TRUE, [(variable_data, datamsgd2c_input[0]), (variable_num_caches, datamsgd2c_input[1])], full_state)) transitions.append((None, full_state, datamsgd2c_output, [variable_data, variable_num_caches], TRUE, [(variable_data, ZERO), (variable_num_caches, ZERO)], 'empty')) datamsgc2c = 'DataMsgC2C' invackmsg = 'InvAckMsg' for other_cache_id in range(num_caches): if other_cache_id != cache_id: suffix2 = '_{}{}'.format(other_cache_id, suffix) datamsgc2c_input = z3p.Int(datamsgc2c + suffix2) datamsgc2c_output = z3p.Int(datamsgc2c + 'P' + suffix2) inputs.append(datamsgc2c_input) outputs.append(datamsgc2c_output) full_state = 'DataMsgC2C_full_{}'.format(other_cache_id) locations.append(full_state) transitions.append((None, 'empty', datamsgc2c_input, TRUE, [(variable_data, datamsgc2c_input)], full_state)) transitions.append((None, full_state, datamsgc2c_output, [variable_data], TRUE, [(variable_data, ZERO)], 'empty')) invackmsg_input = util.new_variable(invackmsg + suffix2, 'unit') invackmsg_output = util.new_variable(invackmsg + 'P' + suffix2, 'unit') inputs.append(invackmsg_input) outputs.append(invackmsg_output) full_state = 'InvAckMsg_full_{}'.format(other_cache_id) locations.append(full_state) transitions.append((None, 'empty', invackmsg_input, TRUE, [], full_state)) transitions.append((None, full_state, invackmsg_output, [ZERO], TRUE, [], 'empty')) return automaton.SymbolicAutomaton(name, locations, 'empty', transitions, variables=[variable_data, variable_num_caches], initial_values=[ZERO, ZERO], input_channels=inputs, output_channels=outputs, variable_ranges=variable_ranges)
GetXMsgP[c][d] = {} GetSMsgP[c][d] = {} WBMsgP[c][d] = {} UnblockSMsgP[c][d] = {} UnblockEMsgP[c][d] = {} FwdGetXMsg[c][d] = {} FwdGetSMsg[c][d] = {} DataMsgD2C[c][d] = {} WBAckMsg[c][d] = {} for a in range(NUM_ADDRESSES): suffix = '_{}_{}_{}'.format(c, d, a) LDMsg[c][d][a] = util.new_variable('LDMsg' + suffix, 'unit') STMsg[c][d][a] = z3p.Int('STMsg' + suffix) EVMsg[c][d][a] = util.new_variable('EVMsg' + suffix, 'unit') FwdGetXMsgP[c][d][a] = z3p.Int('FwdGetXMsgP' + suffix) FwdGetSMsgP[c][d][a] = z3p.Int('FwdGetSMsgP' + suffix) DataMsgD2CP[c][d][a] = z3p.Array('DataMsgD2CP' + suffix, z3p.IntSort(), z3p.IntSort()) WBAckMsgP[c][d][a] = util.new_variable('WBAckMsgP' + suffix, 'unit') LDAckMsg[c][d][a] = z3p.Int('LDAckMsg' + suffix) STAckMsg[c][d][a] = z3p.Int('STAckMsg' + suffix) EVAckMsg[c][d][a] = util.new_variable('EVAckMsg' + suffix, 'unit') UnblockSMsg[c][d][a] = util.new_variable('UnblockSMsg' + suffix, 'unit') UnblockEMsg[c][d][a] = util.new_variable('UnblockEMsg' + suffix, 'unit') GetXMsg[c][d][a] = util.new_variable('GetXMsg' + suffix, 'unit') GetSMsg[c][d][a] = util.new_variable('GetSMsg' + suffix, 'unit') WBMsg[c][d][a] = z3p.Int('WBMsg' + suffix)
WBMsg[c][d] = {} GetXMsgP[c][d] = {} GetSMsgP[c][d] = {} WBMsgP[c][d] = {} UnblockSMsgP[c][d] = {} UnblockEMsgP[c][d] = {} FwdGetXMsg[c][d] = {} FwdGetSMsg[c][d] = {} DataMsgD2C[c][d] = {} WBAckMsg[c][d] = {} for a in range(NUM_ADDRESSES): suffix = '_{}_{}_{}'.format(c, d, a) LDMsg[c][d][a] = util.new_variable('LDMsg' + suffix, 'unit') STMsg[c][d][a] = z3p.Int('STMsg' + suffix) EVMsg[c][d][a] = util.new_variable('EVMsg' + suffix, 'unit') FwdGetXMsgP[c][d][a] = z3p.Int('FwdGetXMsgP' + suffix) FwdGetSMsgP[c][d][a] = z3p.Int('FwdGetSMsgP' + suffix) DataMsgD2CP[c][d][a] = z3p.Array('DataMsgD2CP' + suffix, z3p.IntSort(), z3p.IntSort()) WBAckMsgP[c][d][a] = util.new_variable('WBAckMsgP' + suffix, 'unit') LDAckMsg[c][d][a] = z3p.Int('LDAckMsg' + suffix) STAckMsg[c][d][a] = z3p.Int('STAckMsg' + suffix) EVAckMsg[c][d][a] = util.new_variable('EVAckMsg' + suffix, 'unit') UnblockSMsg[c][d][a] = util.new_variable('UnblockSMsg' + suffix, 'unit') UnblockEMsg[c][d][a] = util.new_variable('UnblockEMsg' + suffix, 'unit')