Funcion basica de PBox y NBox
This commit is contained in:
parent
4bf7619cc1
commit
d6125f9433
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,130 @@
|
|||
// Block Name (Original): BlenderRun_ProdTime
|
||||
// Block Number: 2040
|
||||
// Original Language: LAD
|
||||
|
||||
FUNCTION_BLOCK "BlenderRun_ProdTime"
|
||||
{ S7_Optimized_Access := 'TRUE' }
|
||||
VERSION : 0.1
|
||||
|
||||
VAR_INPUT
|
||||
END_VAR
|
||||
|
||||
VAR_OUTPUT
|
||||
END_VAR
|
||||
|
||||
VAR_IN_OUT
|
||||
END_VAR
|
||||
|
||||
VAR_TEMP
|
||||
m1MinONS : Bool;
|
||||
m1HourONS : Bool;
|
||||
Buffer : Bool;
|
||||
mRunMin : Bool;
|
||||
mRunHr : Bool;
|
||||
I_DIRunning_sec : DInt;
|
||||
I_DIRunning_min : DInt;
|
||||
MOD60 : DInt;
|
||||
END_VAR
|
||||
|
||||
BEGIN
|
||||
|
||||
// Network 1: Seconds
|
||||
|
||||
// RLO: "Procedure_Variables"."Blender_Run"."Running"
|
||||
// RLO: "Procedure_Variables"."Blender_Run"."Running" AND "CLK_1.0S"
|
||||
IF "Procedure_Variables"."Blender_Run"."Running" AND "CLK_1.0S" THEN
|
||||
"Blender_Variables_Pers"."gSLIM_Sec" := "Blender_Variables_Pers"."gSLIM_Sec" + 1;
|
||||
END_IF;
|
||||
|
||||
// Network 2: Reset Hours
|
||||
|
||||
// RLO: "SLIM_Variables"."ResetHour"
|
||||
IF "SLIM_Variables"."ResetHour" THEN
|
||||
"Blender_Variables_Pers"."gSLIM_Sec" := 0;
|
||||
END_IF;
|
||||
|
||||
// Network 3: Seconds Counter
|
||||
|
||||
// RLO: "gBlenderBlending"
|
||||
// RLO: "gBlenderBlending" AND "CLK_1.0S"
|
||||
IF "gBlenderBlending" AND "CLK_1.0S" THEN
|
||||
"Blender_Variables_Pers"."gProdSec" := "Blender_Variables_Pers"."gProdSec" + 1;
|
||||
END_IF;
|
||||
|
||||
// Network 4: Minute
|
||||
|
||||
"m1MinONS" := "Blender_Variables_Pers"."gProdSec" = 60;
|
||||
|
||||
// Network 5: Minute Counter
|
||||
|
||||
IF "m1MinONS" THEN
|
||||
"Blender_Variables_Pers"."gProdSec" := 0;
|
||||
"Blender_Variables_Pers"."gProdMin" := "Blender_Variables_Pers"."gProdMin" + 1;
|
||||
END_IF;
|
||||
// Logic included in grouped IF (by UID 27)
|
||||
// Logic included in grouped IF (by UID 27)
|
||||
|
||||
// Network 6: Hour
|
||||
|
||||
"m1HourONS" := "Blender_Variables_Pers"."gProdMin" = 60;
|
||||
|
||||
// Network 7: Hour Counter
|
||||
|
||||
IF "m1HourONS" THEN
|
||||
"Blender_Variables_Pers"."gProdMin" := 0;
|
||||
"Blender_Variables_Pers"."gProdHour" := "Blender_Variables_Pers"."gProdHour" + 1;
|
||||
"Blender_Variables_Pers"."gBlendingMaintHour" := "Blender_Variables_Pers"."gBlendingMaintHour" + 1;
|
||||
END_IF;
|
||||
// Logic included in grouped IF (by UID 30)
|
||||
// Logic included in grouped IF (by UID 30)
|
||||
// Logic included in grouped IF (by UID 30)
|
||||
|
||||
// Network 8: Counter reset
|
||||
|
||||
// RLO: "gBlenderCIPMode"
|
||||
// RLO: "gBlenderRinseMode"
|
||||
IF "gBlenderCIPMode" OR "gBlenderRinseMode" THEN
|
||||
"Blender_Variables_Pers"."gProdSec" := 0;
|
||||
"Blender_Variables_Pers"."gProdMin" := 0;
|
||||
"Blender_Variables_Pers"."gProdHour" := 0;
|
||||
END_IF;
|
||||
// Logic included in grouped IF (by UID 31)
|
||||
// Logic included in grouped IF (by UID 31)
|
||||
// Logic included in grouped IF (by UID 31)
|
||||
|
||||
// Network 9: Running Seconds
|
||||
|
||||
// RLO: "Procedure_Variables"."Blender_Run"."Running"
|
||||
// RLO: "Procedure_Variables"."Blender_Run"."Running" AND "CLK_1.0S"
|
||||
IF "Procedure_Variables"."Blender_Run"."Running" AND "CLK_1.0S" THEN
|
||||
"Blender_Variables_Pers"."gRunningSeconds" := "Blender_Variables_Pers"."gRunningSeconds" + 1;
|
||||
END_IF;
|
||||
|
||||
// Network 10: Running Minutes
|
||||
|
||||
"I_DIRunning_sec" := "Blender_Variables_Pers"."gRunningSeconds";
|
||||
"MOD60" := "I_DIRunning_sec" MOD DINT#60;
|
||||
// RLO: "MOD60" = DINT#0 AND "Procedure_Variables"."Blender_Run"."Running"
|
||||
// RLO: ("MOD60" = DINT#0 AND "Procedure_Variables"."Blender_Run"."Running") AND "CLK_1.0S"
|
||||
IF ("MOD60" = DINT#0 AND "Procedure_Variables"."Blender_Run"."Running") AND "CLK_1.0S" THEN
|
||||
"Blender_Variables_Pers"."gRunningMinutes" := "Blender_Variables_Pers"."gRunningMinutes" + 1;
|
||||
END_IF;
|
||||
|
||||
// Network 11: Running Hours for Maintenance
|
||||
|
||||
// RLO: "mRunMin"
|
||||
IF "mRunMin" THEN
|
||||
"I_DIRunning_min" := "Blender_Variables_Pers"."gRunningMinutes";
|
||||
END_IF;
|
||||
IF "mRunMin" THEN
|
||||
"MOD60" := "I_DIRunning_min" MOD DINT#60;
|
||||
END_IF;
|
||||
IF "MOD60" = DINT#0 THEN
|
||||
"Blender_Variables_Pers"."gRunningMaintHour" := "Blender_Variables_Pers"."gRunningMaintHour" + 1;
|
||||
END_IF;
|
||||
|
||||
// Network 12: Running Hours for Maintenance
|
||||
|
||||
"HMI_Variables_Status"."System"."BlendingMaintHour" := "Blender_Variables_Pers"."gRunningMaintHour";
|
||||
|
||||
END_FUNCTION_BLOCK
|
|
@ -233,9 +233,7 @@
|
|||
<Component Name="Clock_5Hz" />
|
||||
</Symbol>
|
||||
</Access>
|
||||
<Part Name="Contact" UId="24">
|
||||
<Negated Name="operand" />
|
||||
</Part>
|
||||
<Part Name="Contact" UId="24" />
|
||||
<Part Name="NBox" UId="25" />
|
||||
<Part Name="Coil" UId="26" />
|
||||
</Parts>
|
||||
|
|
|
@ -43,17 +43,17 @@
|
|||
"template_values": {},
|
||||
"negated_pins": {},
|
||||
"inputs": {
|
||||
"bit": {
|
||||
"uid": "22",
|
||||
"scope": "GlobalVariable",
|
||||
"type": "variable",
|
||||
"name": "\"M19001\""
|
||||
},
|
||||
"in": {
|
||||
"type": "connection",
|
||||
"source_instruction_type": "Contact",
|
||||
"source_instruction_uid": "24",
|
||||
"source_pin": "out"
|
||||
},
|
||||
"bit": {
|
||||
"uid": "22",
|
||||
"scope": "GlobalVariable",
|
||||
"type": "variable",
|
||||
"name": "\"M19001\""
|
||||
}
|
||||
},
|
||||
"outputs": {}
|
||||
|
@ -92,9 +92,7 @@
|
|||
"uid": "24",
|
||||
"type": "Contact",
|
||||
"template_values": {},
|
||||
"negated_pins": {
|
||||
"operand": true
|
||||
},
|
||||
"negated_pins": {},
|
||||
"inputs": {
|
||||
"operand": {
|
||||
"uid": "21",
|
||||
|
@ -115,17 +113,17 @@
|
|||
"template_values": {},
|
||||
"negated_pins": {},
|
||||
"inputs": {
|
||||
"bit": {
|
||||
"uid": "22",
|
||||
"scope": "GlobalVariable",
|
||||
"type": "variable",
|
||||
"name": "\"M19001\""
|
||||
},
|
||||
"in": {
|
||||
"type": "connection",
|
||||
"source_instruction_type": "Contact",
|
||||
"source_instruction_uid": "24",
|
||||
"source_pin": "out"
|
||||
},
|
||||
"bit": {
|
||||
"uid": "22",
|
||||
"scope": "GlobalVariable",
|
||||
"type": "variable",
|
||||
"name": "\"M19001\""
|
||||
}
|
||||
},
|
||||
"outputs": {}
|
||||
|
|
|
@ -44,21 +44,22 @@
|
|||
"template_values": {},
|
||||
"negated_pins": {},
|
||||
"inputs": {
|
||||
"bit": {
|
||||
"uid": "22",
|
||||
"scope": "GlobalVariable",
|
||||
"type": "variable",
|
||||
"name": "\"M19001\""
|
||||
},
|
||||
"in": {
|
||||
"type": "connection",
|
||||
"source_instruction_type": "Contact",
|
||||
"source_instruction_uid": "24",
|
||||
"source_pin": "out"
|
||||
},
|
||||
"bit": {
|
||||
"uid": "22",
|
||||
"scope": "GlobalVariable",
|
||||
"type": "variable",
|
||||
"name": "\"M19001\""
|
||||
}
|
||||
},
|
||||
"outputs": {},
|
||||
"scl": "\"stat_M19001\" := \"Clock_10Hz\"; // P_TRIG: \"Clock_10Hz\" AND NOT \"stat_M19001\""
|
||||
"_edge_mem_update_scl": "\"M19001\" := \"Clock_10Hz\";",
|
||||
"scl": "// Logic moved to Coil 26"
|
||||
},
|
||||
{
|
||||
"instruction_uid": "26",
|
||||
|
@ -81,7 +82,7 @@
|
|||
}
|
||||
},
|
||||
"outputs": {},
|
||||
"scl": "\"Clock_5Hz\" := \"Clock_10Hz\" AND NOT \"stat_M19001\";"
|
||||
"scl": "\"Clock_5Hz\" := \"Clock_10Hz\" AND NOT \"M19001\";\\n\"M19001\" := \"Clock_10Hz\"; // P_TRIG(\"Clock_10Hz\") (Mem update handled by consumer)"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
@ -95,9 +96,7 @@
|
|||
"uid": "24",
|
||||
"type": "Contact_scl",
|
||||
"template_values": {},
|
||||
"negated_pins": {
|
||||
"operand": true
|
||||
},
|
||||
"negated_pins": {},
|
||||
"inputs": {
|
||||
"operand": {
|
||||
"uid": "21",
|
||||
|
@ -110,7 +109,7 @@
|
|||
}
|
||||
},
|
||||
"outputs": {},
|
||||
"scl": "// RLO: (NOT \"Clock_10Hz\")"
|
||||
"scl": "// RLO: \"Clock_10Hz\""
|
||||
},
|
||||
{
|
||||
"instruction_uid": "25",
|
||||
|
@ -119,21 +118,22 @@
|
|||
"template_values": {},
|
||||
"negated_pins": {},
|
||||
"inputs": {
|
||||
"bit": {
|
||||
"uid": "22",
|
||||
"scope": "GlobalVariable",
|
||||
"type": "variable",
|
||||
"name": "\"M19001\""
|
||||
},
|
||||
"in": {
|
||||
"type": "connection",
|
||||
"source_instruction_type": "Contact",
|
||||
"source_instruction_uid": "24",
|
||||
"source_pin": "out"
|
||||
},
|
||||
"bit": {
|
||||
"uid": "22",
|
||||
"scope": "GlobalVariable",
|
||||
"type": "variable",
|
||||
"name": "\"M19001\""
|
||||
}
|
||||
},
|
||||
"outputs": {},
|
||||
"scl": "\"stat_M19001\" := (NOT \"Clock_10Hz\"); // N_TRIG: NOT (NOT \"Clock_10Hz\") AND \"stat_M19001\""
|
||||
"_edge_mem_update_scl": "\"M19001\" := \"Clock_10Hz\";",
|
||||
"scl": "// Logic moved to Coil 26"
|
||||
},
|
||||
{
|
||||
"instruction_uid": "26",
|
||||
|
@ -156,7 +156,7 @@
|
|||
}
|
||||
},
|
||||
"outputs": {},
|
||||
"scl": "\"Clock_5Hz\" := NOT (NOT \"Clock_10Hz\") AND \"stat_M19001\";"
|
||||
"scl": "\"Clock_5Hz\" := NOT \"Clock_10Hz\" AND \"M19001\";\\n\"M19001\" := \"Clock_10Hz\"; // N_TRIG(\"Clock_10Hz\") (Mem update handled by consumer)"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
@ -15,10 +15,6 @@ END_VAR
|
|||
VAR_IN_OUT
|
||||
END_VAR
|
||||
|
||||
VAR_STAT
|
||||
"stat_M19001" : Bool; // Memory for edge detection
|
||||
END_VAR
|
||||
|
||||
VAR_TEMP
|
||||
END_VAR
|
||||
|
||||
|
@ -27,13 +23,13 @@ BEGIN
|
|||
// Network 1: Clock Bit
|
||||
|
||||
// RLO: "Clock_10Hz"
|
||||
"stat_M19001" := "Clock_10Hz"; // P_TRIG: "Clock_10Hz" AND NOT "stat_M19001"
|
||||
"Clock_5Hz" := "Clock_10Hz" AND NOT "stat_M19001";
|
||||
// Logic moved to Coil 26
|
||||
"Clock_5Hz" := "Clock_10Hz" AND NOT "M19001";\n"M19001" := "Clock_10Hz"; // P_TRIG("Clock_10Hz") (Mem update handled by consumer)
|
||||
|
||||
// Network 2: Clock Bit
|
||||
|
||||
// RLO: (NOT "Clock_10Hz")
|
||||
"stat_M19001" := (NOT "Clock_10Hz"); // N_TRIG: NOT (NOT "Clock_10Hz") AND "stat_M19001"
|
||||
"Clock_5Hz" := NOT (NOT "Clock_10Hz") AND "stat_M19001";
|
||||
// RLO: "Clock_10Hz"
|
||||
// Logic moved to Coil 26
|
||||
"Clock_5Hz" := NOT "Clock_10Hz" AND "M19001";\n"M19001" := "Clock_10Hz"; // N_TRIG("Clock_10Hz") (Mem update handled by consumer)
|
||||
|
||||
END_FUNCTION_BLOCK
|
||||
|
|
|
@ -357,7 +357,7 @@ def convert_xml_to_json(xml_filepath, json_filepath):
|
|||
|
||||
# --- Punto de Entrada Principal ---
|
||||
if __name__ == "__main__":
|
||||
xml_filename_base = "TestLAD"
|
||||
xml_filename_base = "BlenderRun_ProdTime"
|
||||
xml_file = f"{xml_filename_base}.xml"
|
||||
json_file = f"{xml_filename_base}_simplified.json"
|
||||
convert_xml_to_json(xml_file, json_file)
|
250
x2_process.py
250
x2_process.py
|
@ -258,7 +258,6 @@ def process_contact(instruction, network_id, scl_map, access_map):
|
|||
instruction["type"] = instr_type + SCL_SUFFIX
|
||||
return True
|
||||
|
||||
|
||||
def process_eq(instruction, network_id, scl_map, access_map):
|
||||
instr_uid = instruction["instruction_uid"]
|
||||
instr_type = instruction["type"]
|
||||
|
@ -315,52 +314,127 @@ def process_eq(instruction, network_id, scl_map, access_map):
|
|||
instruction["type"] = instr_type + SCL_SUFFIX
|
||||
return True
|
||||
|
||||
# --- process_edge_detector MODIFICADA ---
|
||||
def process_edge_detector(instruction, network_id, scl_map, access_map):
|
||||
"""Genera SCL para PBox (P_TRIG) o NBox (N_TRIG).
|
||||
Guarda la expresión del pulso en scl_map['out'] y la actualización
|
||||
de memoria en un campo temporal '_edge_mem_update_scl'.
|
||||
El campo 'scl' principal se deja casi vacío.
|
||||
"""
|
||||
instr_uid = instruction["instruction_uid"]
|
||||
instr_type_original = instruction["type"] # PBox o NBox
|
||||
|
||||
if instr_type_original.endswith(SCL_SUFFIX) or "_error" in instr_type_original:
|
||||
return False
|
||||
|
||||
# 1. Obtener CLK y MemBit original
|
||||
clk_input = instruction["inputs"].get("in")
|
||||
mem_bit_input = instruction["inputs"].get("bit")
|
||||
clk_scl = get_scl_representation(clk_input, network_id, scl_map, access_map)
|
||||
mem_bit_scl_original = get_scl_representation(mem_bit_input, network_id, scl_map, access_map)
|
||||
|
||||
# 2. Verificar dependencias y tipo de MemBit
|
||||
if clk_scl is None or mem_bit_scl_original is None: return False
|
||||
if not (mem_bit_input and mem_bit_input.get("type") == "variable"):
|
||||
instruction["scl"] = f"// ERROR: {instr_type_original} {instr_uid} 'bit' no es variable."
|
||||
instruction["type"] = instr_type_original + "_error"
|
||||
return True
|
||||
|
||||
# 3. Formatear CLK
|
||||
clk_scl_formatted = clk_scl
|
||||
if clk_scl not in ["TRUE", "FALSE"] and \
|
||||
(' ' in clk_scl or 'AND' in clk_scl or 'OR' in clk_scl or ':=' in clk_scl) and \
|
||||
not (clk_scl.startswith('(') and clk_scl.endswith(')')):
|
||||
clk_scl_formatted = f"({clk_scl})"
|
||||
|
||||
# 4. Generar Lógica SCL del *pulso*
|
||||
result_pulse_expression = "FALSE"
|
||||
scl_comment = ""
|
||||
if instr_type_original == "PBox": # P_TRIG
|
||||
result_pulse_expression = f"{clk_scl_formatted} AND NOT {mem_bit_scl_original}"
|
||||
scl_comment = f"// P_TRIG({clk_scl_formatted})"
|
||||
elif instr_type_original == "NBox": # N_TRIG
|
||||
result_pulse_expression = f"NOT {clk_scl_formatted} AND {mem_bit_scl_original}"
|
||||
scl_comment = f"// N_TRIG({clk_scl_formatted})"
|
||||
else: # Error
|
||||
instruction["scl"] = f"// ERROR: Tipo de flanco inesperado {instr_type_original}"
|
||||
instruction["type"] = instr_type_original + "_error"
|
||||
return True
|
||||
|
||||
# 5. Generar la actualización del bit de memoria
|
||||
scl_mem_update = f"{mem_bit_scl_original} := {clk_scl_formatted};"
|
||||
|
||||
# 6. Almacenar Resultados
|
||||
map_key_out = (network_id, instr_uid, "out")
|
||||
scl_map[map_key_out] = result_pulse_expression # Guardar EXPRESIÓN del pulso
|
||||
|
||||
instruction['_edge_mem_update_scl'] = scl_mem_update # Guardar UPDATE en campo temporal
|
||||
instruction['scl'] = f"{scl_comment} (Mem update handled by consumer)" # Dejar SCL principal vacío/comentario
|
||||
instruction["type"] = instr_type_original + SCL_SUFFIX
|
||||
|
||||
# 7. Propagar ENO
|
||||
map_key_eno = (network_id, instr_uid, "eno")
|
||||
scl_map[map_key_eno] = clk_scl
|
||||
|
||||
return True
|
||||
|
||||
# --- process_coil MODIFICADA ---
|
||||
def process_coil(instruction, network_id, scl_map, access_map):
|
||||
"""Genera la asignación para Coil. Si la entrada viene de PBox/NBox,
|
||||
añade la actualización de memoria del flanco DESPUÉS de la asignación."""
|
||||
instr_uid = instruction["instruction_uid"]
|
||||
instr_type = instruction["type"]
|
||||
if instr_type.endswith(SCL_SUFFIX) or "_error" in instr_type:
|
||||
return False
|
||||
|
||||
in_rlo_scl = get_scl_representation(
|
||||
instruction["inputs"].get("in"), network_id, scl_map, access_map
|
||||
)
|
||||
coil_input_info = instruction["inputs"].get("in")
|
||||
operand_info = instruction["inputs"].get("operand")
|
||||
|
||||
in_rlo_scl = get_scl_representation(coil_input_info, network_id, scl_map, access_map)
|
||||
operand_scl = get_scl_representation(operand_info, network_id, scl_map, access_map)
|
||||
|
||||
if in_rlo_scl is None or operand_scl is None:
|
||||
return False # Dependencias no listas
|
||||
if in_rlo_scl is None or operand_scl is None: return False
|
||||
|
||||
# Validar y formatear operando
|
||||
if not (operand_info and operand_info.get("type") == "variable"):
|
||||
print(f"Error: Operando COIL {instr_uid} no es variable o falta información.")
|
||||
instruction["scl"] = (
|
||||
f"// ERROR: Coil {instr_uid} operando no es variable o falta info"
|
||||
)
|
||||
instruction["scl"] = f"// ERROR: Coil {instr_uid} operando no es variable o falta info"
|
||||
instruction["type"] = instr_type + "_error"
|
||||
return True # Marcar como procesado (con error)
|
||||
return True
|
||||
|
||||
operand_scl_formatted = format_variable_name(operand_scl)
|
||||
if in_rlo_scl == "(TRUE)": in_rlo_scl = "TRUE"
|
||||
elif in_rlo_scl == "(FALSE)": in_rlo_scl = "FALSE"
|
||||
|
||||
# Simplificar RLO si es posible
|
||||
if in_rlo_scl == "(TRUE)":
|
||||
in_rlo_scl = "TRUE"
|
||||
elif in_rlo_scl == "(FALSE)":
|
||||
in_rlo_scl = "FALSE"
|
||||
# Generar la asignación SCL principal
|
||||
scl_assignment = f"{operand_scl_formatted} := {in_rlo_scl};"
|
||||
scl_final = scl_assignment # Inicializar SCL final
|
||||
|
||||
# --- Lógica para añadir actualización de memoria de flancos ---
|
||||
mem_update_scl = None
|
||||
if isinstance(coil_input_info, dict) and coil_input_info.get("type") == "connection":
|
||||
source_uid = coil_input_info.get("source_instruction_uid")
|
||||
source_pin = coil_input_info.get("source_pin")
|
||||
# Buscar la instrucción fuente en la lógica de la red actual
|
||||
source_instruction = None
|
||||
network_logic = next((net["logic"] for net in data["networks"] if net["id"] == network_id), [])
|
||||
for instr in network_logic:
|
||||
if instr.get("instruction_uid") == source_uid:
|
||||
source_instruction = instr
|
||||
break
|
||||
|
||||
if source_instruction:
|
||||
source_type = source_instruction.get("type","").replace('_scl','').replace('_error','')
|
||||
# Si la fuente es PBox o NBox y tiene el campo temporal con la actualización
|
||||
if source_type in ["PBox", "NBox"] and '_edge_mem_update_scl' in source_instruction:
|
||||
mem_update_scl = source_instruction['_edge_mem_update_scl']
|
||||
# Añadir la actualización DESPUÉS de la asignación de la bobina
|
||||
scl_final = f"{scl_assignment}\\n{mem_update_scl} {source_instruction.get('scl', '')}" # Añadir también comentario original del PBox/NBox
|
||||
# Marcar la instrucción PBox/NBox para que x3 no escriba su SCL (que ahora está vacío/comentario)
|
||||
source_instruction['scl'] = f"// Logic moved to Coil {instr_uid}"
|
||||
|
||||
# Generar la asignación SCL
|
||||
scl_final = f"{operand_scl_formatted} := {in_rlo_scl};"
|
||||
instruction["scl"] = scl_final
|
||||
instruction["type"] = instr_type + SCL_SUFFIX
|
||||
|
||||
# Las bobinas no suelen tener salida ENO explícita en este contexto,
|
||||
# pero podríamos propagar el RLO de entrada si fuera necesario para alguna lógica posterior.
|
||||
# map_key_eno = (network_id, instr_uid, "eno")
|
||||
# scl_map[map_key_eno] = in_rlo_scl
|
||||
|
||||
return True
|
||||
|
||||
|
||||
def process_convert(instruction, network_id, scl_map, access_map):
|
||||
instr_uid = instruction["instruction_uid"]
|
||||
instr_type = instruction["type"]
|
||||
|
@ -424,7 +498,6 @@ def process_convert(instruction, network_id, scl_map, access_map):
|
|||
scl_map[map_key_eno] = en_scl # ENO sigue a EN
|
||||
return True
|
||||
|
||||
|
||||
def process_mod(instruction, network_id, scl_map, access_map):
|
||||
instr_uid = instruction["instruction_uid"]
|
||||
instr_type = instruction["type"]
|
||||
|
@ -483,7 +556,6 @@ def process_mod(instruction, network_id, scl_map, access_map):
|
|||
scl_map[map_key_eno] = en_scl
|
||||
return True
|
||||
|
||||
|
||||
def process_add(instruction, network_id, scl_map, access_map):
|
||||
instr_uid = instruction["instruction_uid"]
|
||||
instr_type = instruction["type"]
|
||||
|
@ -542,7 +614,6 @@ def process_add(instruction, network_id, scl_map, access_map):
|
|||
scl_map[map_key_eno] = en_scl
|
||||
return True
|
||||
|
||||
|
||||
def process_move(instruction, network_id, scl_map, access_map):
|
||||
instr_uid = instruction["instruction_uid"]
|
||||
instr_type = instruction["type"]
|
||||
|
@ -608,95 +679,90 @@ def process_move(instruction, network_id, scl_map, access_map):
|
|||
return True
|
||||
|
||||
|
||||
def process_edge_detector(instruction, network_id, scl_map, access_map):
|
||||
# --- FUNCIÓN UNIFICADA CORREGIDA para PBox y NBox ---
|
||||
|
||||
"""Genera SCL para PBox (P_TRIG) o NBox (N_TRIG)."""
|
||||
instr_uid = instruction["instruction_uid"]
|
||||
instr_type_original = instruction["type"] # PBox o NBox
|
||||
if instr_type_original.endswith(SCL_SUFFIX) or "_error" in instr_type_original:
|
||||
return False
|
||||
instr_type_original = instruction["type"] # PBox o NBox
|
||||
# print(f"DEBUG Edge: Intentando procesar {instr_type_original} UID {instr_uid} en Red {network_id}") # Debug
|
||||
|
||||
# Obtener CLK (señal de entrada) y MemBit (bit de memoria)
|
||||
if instr_type_original.endswith(SCL_SUFFIX) or "_error" in instr_type_original:
|
||||
return False # Ya procesado o error
|
||||
|
||||
# 1. Obtener representaciones SCL de las entradas CLK y MemBit
|
||||
clk_input = instruction["inputs"].get("in")
|
||||
mem_bit_input = instruction["inputs"].get("bit")
|
||||
|
||||
clk_scl = get_scl_representation(clk_input, network_id, scl_map, access_map)
|
||||
mem_bit_scl_original = get_scl_representation(
|
||||
mem_bit_input, network_id, scl_map, access_map
|
||||
)
|
||||
mem_bit_scl_original = get_scl_representation(mem_bit_input, network_id, scl_map, access_map)
|
||||
|
||||
if clk_scl is None or mem_bit_scl_original is None:
|
||||
# print(f"DEBUG Edge: Esperando dependencias para {instr_type_original} UID {instr_uid}")
|
||||
return False # Dependencias no listas
|
||||
|
||||
# Validar que el bit de memoria sea una variable
|
||||
if not (mem_bit_input and mem_bit_input.get("type") == "variable"):
|
||||
print(
|
||||
f"Error: {instr_type_original} {instr_uid} 'bit' no es variable o falta información."
|
||||
)
|
||||
instruction["scl"] = (
|
||||
f"// ERROR: {instr_type_original} {instr_uid} 'bit' no es variable."
|
||||
)
|
||||
# 2. Verificar si las dependencias están listas
|
||||
if clk_scl is None:
|
||||
# print(f"DEBUG Edge: CLK no resuelto para {instr_type_original} UID {instr_uid}. Esperando.")
|
||||
return False # Dependencia CLK no lista
|
||||
if mem_bit_scl_original is None:
|
||||
# Esto es menos probable, pero por seguridad
|
||||
print(f"Error: No se pudo resolver MemBit para {instr_type_original} UID {instr_uid}.")
|
||||
instruction["scl"] = f"// ERROR: {instr_type_original} {instr_uid} MemBit no resuelto."
|
||||
instruction["type"] = instr_type_original + "_error"
|
||||
return True # Procesado con error
|
||||
return True # Marcar como error
|
||||
|
||||
# --- Renombrar bit de memoria para VAR_STAT ---
|
||||
# Quitar comillas existentes, añadir prefijo "stat_" y volver a añadir comillas
|
||||
# 3. Validar que el bit de memoria sea una variable
|
||||
if not (mem_bit_input and mem_bit_input.get("type") == "variable"):
|
||||
print(f"Error: {instr_type_original} {instr_uid} 'bit' no es variable o falta información.")
|
||||
instruction["scl"] = f"// ERROR: {instr_type_original} {instr_uid} 'bit' no es variable."
|
||||
instruction["type"] = instr_type_original + "_error"
|
||||
return True # Procesado con error
|
||||
|
||||
# 4. Renombrar bit de memoria para VAR_STAT y formatear CLK
|
||||
mem_bit_name_clean = mem_bit_scl_original.strip('"')
|
||||
stat_mem_bit_scl = (
|
||||
f'"stat_{mem_bit_name_clean}"' # Nombre SCL para la variable estática
|
||||
)
|
||||
stat_mem_bit_scl = f'"stat_{mem_bit_name_clean}"' if not mem_bit_name_clean.startswith("stat_") else mem_bit_scl_original
|
||||
|
||||
# Asegurar paréntesis alrededor de CLK si es complejo
|
||||
# Formatear CLK
|
||||
clk_scl_formatted = clk_scl
|
||||
# Añadir paréntesis si es necesario (expresión compleja o asignación previa)
|
||||
# No añadir paréntesis a TRUE/FALSE literales
|
||||
if (
|
||||
clk_scl not in ["TRUE", "FALSE"]
|
||||
and (" " in clk_scl or "AND" in clk_scl or "OR" in clk_scl or ":=" in clk_scl)
|
||||
and not (clk_scl.startswith("(") and clk_scl.endswith(")"))
|
||||
):
|
||||
# Añadir paréntesis si es necesario (expresión compleja) - No a TRUE/FALSE
|
||||
if clk_scl not in ["TRUE", "FALSE"] and \
|
||||
(' ' in clk_scl or 'AND' in clk_scl or 'OR' in clk_scl or ':=' in clk_scl) and \
|
||||
not (clk_scl.startswith('(') and clk_scl.endswith(')')):
|
||||
clk_scl_formatted = f"({clk_scl})"
|
||||
|
||||
# --- Generar Lógica SCL ---
|
||||
result_scl = "FALSE" # SCL para la salida del flanco (pin 'out')
|
||||
scl_comment = "" # Comentario informativo
|
||||
# 5. Generar Lógica SCL específica para PBox o NBox
|
||||
result_pulse_scl = "FALSE" # SCL para la salida del flanco (pin 'out')
|
||||
scl_comment = ""
|
||||
|
||||
if instr_type_original == "PBox": # Flanco Positivo (P_TRIG)
|
||||
result_scl = f"{clk_scl_formatted} AND NOT {stat_mem_bit_scl}"
|
||||
scl_comment = f"// P_TRIG: {result_scl}"
|
||||
elif instr_type_original == "NBox": # Flanco Negativo (N_TRIG)
|
||||
result_scl = f"NOT {clk_scl_formatted} AND {stat_mem_bit_scl}"
|
||||
scl_comment = f"// N_TRIG: {result_scl}"
|
||||
if instr_type_original == "PBox": # Flanco Positivo (P_TRIG)
|
||||
# Pulso = CLK actual Y NO Memoria anterior
|
||||
result_pulse_scl = f"{clk_scl_formatted} AND NOT {stat_mem_bit_scl}"
|
||||
scl_comment = f"// P_TRIG({clk_scl_formatted})"
|
||||
elif instr_type_original == "NBox": # Flanco Negativo (N_TRIG)
|
||||
# Pulso = NO CLK actual Y Memoria anterior
|
||||
result_pulse_scl = f"NOT {clk_scl_formatted} AND {stat_mem_bit_scl}"
|
||||
scl_comment = f"// N_TRIG({clk_scl_formatted})"
|
||||
else:
|
||||
# No debería ocurrir si el mapeo de procesadores es correcto
|
||||
print(
|
||||
f"Error interno: process_edge_detector llamado para tipo inesperado {instr_type_original}"
|
||||
)
|
||||
instruction["scl"] = (
|
||||
f"// ERROR: Tipo de flanco inesperado {instr_type_original}"
|
||||
)
|
||||
print(f"Error interno: process_edge_detector llamado para tipo inesperado {instr_type_original}")
|
||||
instruction["scl"] = f"// ERROR: Tipo de flanco inesperado {instr_type_original}"
|
||||
instruction["type"] = instr_type_original + "_error"
|
||||
return True
|
||||
|
||||
# La actualización del bit de memoria es igual para P_TRIG y N_TRIG estándar
|
||||
# 6. Generar la actualización del bit de memoria (siempre se actualiza con el estado actual de CLK)
|
||||
scl_mem_update = f"{stat_mem_bit_scl} := {clk_scl_formatted};"
|
||||
|
||||
# --- Almacenar Resultados ---
|
||||
# El pulso resultante va al mapa SCL para que lo usen las instrucciones siguientes
|
||||
# 7. Almacenar Resultados
|
||||
# - El *pulso* resultante se almacena en el mapa para la salida 'out'.
|
||||
# - La *actualización de memoria* se almacena en el campo 'scl' de la instrucción.
|
||||
map_key_out = (network_id, instr_uid, "out")
|
||||
scl_map[map_key_out] = result_scl
|
||||
scl_map[map_key_out] = result_pulse_scl
|
||||
# print(f"DEBUG Edge: {instr_type_original} UID {instr_uid} -> map['out'] = {result_pulse_scl}") # Debug
|
||||
|
||||
# La actualización de memoria es la acción principal de esta instrucción en SCL
|
||||
instruction["scl"] = f"{scl_mem_update} {scl_comment}"
|
||||
instruction["scl"] = f"{scl_mem_update} {scl_comment}" # Incluye la acción principal y un comentario
|
||||
instruction["type"] = instr_type_original + SCL_SUFFIX
|
||||
# print(f"DEBUG Edge: {instr_type_original} UID {instr_uid} -> instruction['scl'] = {instruction['scl']}") # Debug
|
||||
|
||||
# El pin ENO normalmente sigue al CLK en los bloques de flanco estándar
|
||||
# 8. Propagar ENO (generalmente sigue al CLK)
|
||||
map_key_eno = (network_id, instr_uid, "eno")
|
||||
scl_map[map_key_eno] = clk_scl # Usar clk_scl original sin formateo extra
|
||||
|
||||
return True
|
||||
scl_map[map_key_eno] = clk_scl # Usar el clk_scl original sin formato extra
|
||||
|
||||
# print(f"DEBUG Edge: {instr_type_original} UID {instr_uid} procesado exitosamente.") # Debug
|
||||
return True # Indicar que se procesó
|
||||
|
||||
def process_o(instruction, network_id, scl_map, access_map):
|
||||
instr_uid = instruction["instruction_uid"]
|
||||
|
@ -760,7 +826,6 @@ def process_o(instruction, network_id, scl_map, access_map):
|
|||
# La instrucción 'O' no tiene ENO propio, propaga el resultado por 'out'
|
||||
return True
|
||||
|
||||
|
||||
def process_call(instruction, network_id, scl_map, access_map):
|
||||
instr_uid = instruction["instruction_uid"]
|
||||
instr_type = instruction.get("type", "") # Usar get con default
|
||||
|
@ -878,7 +943,6 @@ def process_call(instruction, network_id, scl_map, access_map):
|
|||
|
||||
return True
|
||||
|
||||
|
||||
# --- NUEVO: Procesador de Agrupación (Refinado) ---
|
||||
def process_group_ifs(instruction, network_id, scl_map, access_map):
|
||||
"""
|
||||
|
@ -1308,7 +1372,7 @@ def process_json_to_scl(json_filepath):
|
|||
# --- Ejecución ---
|
||||
if __name__ == "__main__":
|
||||
# Asegúrate de que el nombre base del archivo XML sea correcto
|
||||
xml_filename_base = "TestLAD" # Cambia esto si tu XML se llama diferente
|
||||
xml_filename_base = "BlenderRun_ProdTime" # Cambia esto si tu XML se llama diferente
|
||||
input_json_file = f"{xml_filename_base}_simplified.json"
|
||||
|
||||
if not os.path.exists(input_json_file):
|
||||
|
|
|
@ -197,7 +197,7 @@ def generate_scl(processed_json_filepath, output_scl_filepath):
|
|||
# --- Ejecución ---
|
||||
if __name__ == "__main__":
|
||||
|
||||
xml_file = "TestLAD.xml" # CAMBIAR AL NUEVO ARCHIVO XML
|
||||
xml_file = "BlenderRun_ProdTime.xml" # CAMBIAR AL NUEVO ARCHIVO XML
|
||||
input_json_file = xml_file.replace(
|
||||
".xml", "_simplified_processed.json"
|
||||
) # Nombre de salida dinámico
|
||||
|
|
Loading…
Reference in New Issue