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" />
|
<Component Name="Clock_5Hz" />
|
||||||
</Symbol>
|
</Symbol>
|
||||||
</Access>
|
</Access>
|
||||||
<Part Name="Contact" UId="24">
|
<Part Name="Contact" UId="24" />
|
||||||
<Negated Name="operand" />
|
|
||||||
</Part>
|
|
||||||
<Part Name="NBox" UId="25" />
|
<Part Name="NBox" UId="25" />
|
||||||
<Part Name="Coil" UId="26" />
|
<Part Name="Coil" UId="26" />
|
||||||
</Parts>
|
</Parts>
|
||||||
|
|
|
@ -43,17 +43,17 @@
|
||||||
"template_values": {},
|
"template_values": {},
|
||||||
"negated_pins": {},
|
"negated_pins": {},
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"bit": {
|
|
||||||
"uid": "22",
|
|
||||||
"scope": "GlobalVariable",
|
|
||||||
"type": "variable",
|
|
||||||
"name": "\"M19001\""
|
|
||||||
},
|
|
||||||
"in": {
|
"in": {
|
||||||
"type": "connection",
|
"type": "connection",
|
||||||
"source_instruction_type": "Contact",
|
"source_instruction_type": "Contact",
|
||||||
"source_instruction_uid": "24",
|
"source_instruction_uid": "24",
|
||||||
"source_pin": "out"
|
"source_pin": "out"
|
||||||
|
},
|
||||||
|
"bit": {
|
||||||
|
"uid": "22",
|
||||||
|
"scope": "GlobalVariable",
|
||||||
|
"type": "variable",
|
||||||
|
"name": "\"M19001\""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"outputs": {}
|
"outputs": {}
|
||||||
|
@ -92,9 +92,7 @@
|
||||||
"uid": "24",
|
"uid": "24",
|
||||||
"type": "Contact",
|
"type": "Contact",
|
||||||
"template_values": {},
|
"template_values": {},
|
||||||
"negated_pins": {
|
"negated_pins": {},
|
||||||
"operand": true
|
|
||||||
},
|
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"operand": {
|
"operand": {
|
||||||
"uid": "21",
|
"uid": "21",
|
||||||
|
@ -115,17 +113,17 @@
|
||||||
"template_values": {},
|
"template_values": {},
|
||||||
"negated_pins": {},
|
"negated_pins": {},
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"bit": {
|
|
||||||
"uid": "22",
|
|
||||||
"scope": "GlobalVariable",
|
|
||||||
"type": "variable",
|
|
||||||
"name": "\"M19001\""
|
|
||||||
},
|
|
||||||
"in": {
|
"in": {
|
||||||
"type": "connection",
|
"type": "connection",
|
||||||
"source_instruction_type": "Contact",
|
"source_instruction_type": "Contact",
|
||||||
"source_instruction_uid": "24",
|
"source_instruction_uid": "24",
|
||||||
"source_pin": "out"
|
"source_pin": "out"
|
||||||
|
},
|
||||||
|
"bit": {
|
||||||
|
"uid": "22",
|
||||||
|
"scope": "GlobalVariable",
|
||||||
|
"type": "variable",
|
||||||
|
"name": "\"M19001\""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"outputs": {}
|
"outputs": {}
|
||||||
|
|
|
@ -44,21 +44,22 @@
|
||||||
"template_values": {},
|
"template_values": {},
|
||||||
"negated_pins": {},
|
"negated_pins": {},
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"bit": {
|
|
||||||
"uid": "22",
|
|
||||||
"scope": "GlobalVariable",
|
|
||||||
"type": "variable",
|
|
||||||
"name": "\"M19001\""
|
|
||||||
},
|
|
||||||
"in": {
|
"in": {
|
||||||
"type": "connection",
|
"type": "connection",
|
||||||
"source_instruction_type": "Contact",
|
"source_instruction_type": "Contact",
|
||||||
"source_instruction_uid": "24",
|
"source_instruction_uid": "24",
|
||||||
"source_pin": "out"
|
"source_pin": "out"
|
||||||
|
},
|
||||||
|
"bit": {
|
||||||
|
"uid": "22",
|
||||||
|
"scope": "GlobalVariable",
|
||||||
|
"type": "variable",
|
||||||
|
"name": "\"M19001\""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"outputs": {},
|
"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",
|
"instruction_uid": "26",
|
||||||
|
@ -81,7 +82,7 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"outputs": {},
|
"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",
|
"uid": "24",
|
||||||
"type": "Contact_scl",
|
"type": "Contact_scl",
|
||||||
"template_values": {},
|
"template_values": {},
|
||||||
"negated_pins": {
|
"negated_pins": {},
|
||||||
"operand": true
|
|
||||||
},
|
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"operand": {
|
"operand": {
|
||||||
"uid": "21",
|
"uid": "21",
|
||||||
|
@ -110,7 +109,7 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"outputs": {},
|
"outputs": {},
|
||||||
"scl": "// RLO: (NOT \"Clock_10Hz\")"
|
"scl": "// RLO: \"Clock_10Hz\""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"instruction_uid": "25",
|
"instruction_uid": "25",
|
||||||
|
@ -119,21 +118,22 @@
|
||||||
"template_values": {},
|
"template_values": {},
|
||||||
"negated_pins": {},
|
"negated_pins": {},
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"bit": {
|
|
||||||
"uid": "22",
|
|
||||||
"scope": "GlobalVariable",
|
|
||||||
"type": "variable",
|
|
||||||
"name": "\"M19001\""
|
|
||||||
},
|
|
||||||
"in": {
|
"in": {
|
||||||
"type": "connection",
|
"type": "connection",
|
||||||
"source_instruction_type": "Contact",
|
"source_instruction_type": "Contact",
|
||||||
"source_instruction_uid": "24",
|
"source_instruction_uid": "24",
|
||||||
"source_pin": "out"
|
"source_pin": "out"
|
||||||
|
},
|
||||||
|
"bit": {
|
||||||
|
"uid": "22",
|
||||||
|
"scope": "GlobalVariable",
|
||||||
|
"type": "variable",
|
||||||
|
"name": "\"M19001\""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"outputs": {},
|
"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",
|
"instruction_uid": "26",
|
||||||
|
@ -156,7 +156,7 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"outputs": {},
|
"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
|
VAR_IN_OUT
|
||||||
END_VAR
|
END_VAR
|
||||||
|
|
||||||
VAR_STAT
|
|
||||||
"stat_M19001" : Bool; // Memory for edge detection
|
|
||||||
END_VAR
|
|
||||||
|
|
||||||
VAR_TEMP
|
VAR_TEMP
|
||||||
END_VAR
|
END_VAR
|
||||||
|
|
||||||
|
@ -27,13 +23,13 @@ BEGIN
|
||||||
// Network 1: Clock Bit
|
// Network 1: Clock Bit
|
||||||
|
|
||||||
// RLO: "Clock_10Hz"
|
// RLO: "Clock_10Hz"
|
||||||
"stat_M19001" := "Clock_10Hz"; // P_TRIG: "Clock_10Hz" AND NOT "stat_M19001"
|
// Logic moved to Coil 26
|
||||||
"Clock_5Hz" := "Clock_10Hz" AND NOT "stat_M19001";
|
"Clock_5Hz" := "Clock_10Hz" AND NOT "M19001";\n"M19001" := "Clock_10Hz"; // P_TRIG("Clock_10Hz") (Mem update handled by consumer)
|
||||||
|
|
||||||
// Network 2: Clock Bit
|
// Network 2: Clock Bit
|
||||||
|
|
||||||
// RLO: (NOT "Clock_10Hz")
|
// RLO: "Clock_10Hz"
|
||||||
"stat_M19001" := (NOT "Clock_10Hz"); // N_TRIG: NOT (NOT "Clock_10Hz") AND "stat_M19001"
|
// Logic moved to Coil 26
|
||||||
"Clock_5Hz" := NOT (NOT "Clock_10Hz") AND "stat_M19001";
|
"Clock_5Hz" := NOT "Clock_10Hz" AND "M19001";\n"M19001" := "Clock_10Hz"; // N_TRIG("Clock_10Hz") (Mem update handled by consumer)
|
||||||
|
|
||||||
END_FUNCTION_BLOCK
|
END_FUNCTION_BLOCK
|
||||||
|
|
|
@ -357,7 +357,7 @@ def convert_xml_to_json(xml_filepath, json_filepath):
|
||||||
|
|
||||||
# --- Punto de Entrada Principal ---
|
# --- Punto de Entrada Principal ---
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
xml_filename_base = "TestLAD"
|
xml_filename_base = "BlenderRun_ProdTime"
|
||||||
xml_file = f"{xml_filename_base}.xml"
|
xml_file = f"{xml_filename_base}.xml"
|
||||||
json_file = f"{xml_filename_base}_simplified.json"
|
json_file = f"{xml_filename_base}_simplified.json"
|
||||||
convert_xml_to_json(xml_file, json_file)
|
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
|
instruction["type"] = instr_type + SCL_SUFFIX
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
def process_eq(instruction, network_id, scl_map, access_map):
|
def process_eq(instruction, network_id, scl_map, access_map):
|
||||||
instr_uid = instruction["instruction_uid"]
|
instr_uid = instruction["instruction_uid"]
|
||||||
instr_type = instruction["type"]
|
instr_type = instruction["type"]
|
||||||
|
@ -315,52 +314,127 @@ def process_eq(instruction, network_id, scl_map, access_map):
|
||||||
instruction["type"] = instr_type + SCL_SUFFIX
|
instruction["type"] = instr_type + SCL_SUFFIX
|
||||||
return True
|
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):
|
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_uid = instruction["instruction_uid"]
|
||||||
instr_type = instruction["type"]
|
instr_type = instruction["type"]
|
||||||
if instr_type.endswith(SCL_SUFFIX) or "_error" in instr_type:
|
if instr_type.endswith(SCL_SUFFIX) or "_error" in instr_type:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
in_rlo_scl = get_scl_representation(
|
coil_input_info = instruction["inputs"].get("in")
|
||||||
instruction["inputs"].get("in"), network_id, scl_map, access_map
|
|
||||||
)
|
|
||||||
operand_info = instruction["inputs"].get("operand")
|
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)
|
operand_scl = get_scl_representation(operand_info, network_id, scl_map, access_map)
|
||||||
|
|
||||||
if in_rlo_scl is None or operand_scl is None:
|
if in_rlo_scl is None or operand_scl is None: return False
|
||||||
return False # Dependencias no listas
|
|
||||||
|
|
||||||
# Validar y formatear operando
|
|
||||||
if not (operand_info and operand_info.get("type") == "variable"):
|
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"
|
instruction["type"] = instr_type + "_error"
|
||||||
return True # Marcar como procesado (con error)
|
return True
|
||||||
|
|
||||||
operand_scl_formatted = format_variable_name(operand_scl)
|
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
|
# Generar la asignación SCL principal
|
||||||
if in_rlo_scl == "(TRUE)":
|
scl_assignment = f"{operand_scl_formatted} := {in_rlo_scl};"
|
||||||
in_rlo_scl = "TRUE"
|
scl_final = scl_assignment # Inicializar SCL final
|
||||||
elif in_rlo_scl == "(FALSE)":
|
|
||||||
in_rlo_scl = "FALSE"
|
# --- 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["scl"] = scl_final
|
||||||
instruction["type"] = instr_type + SCL_SUFFIX
|
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
|
return True
|
||||||
|
|
||||||
|
|
||||||
def process_convert(instruction, network_id, scl_map, access_map):
|
def process_convert(instruction, network_id, scl_map, access_map):
|
||||||
instr_uid = instruction["instruction_uid"]
|
instr_uid = instruction["instruction_uid"]
|
||||||
instr_type = instruction["type"]
|
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
|
scl_map[map_key_eno] = en_scl # ENO sigue a EN
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
def process_mod(instruction, network_id, scl_map, access_map):
|
def process_mod(instruction, network_id, scl_map, access_map):
|
||||||
instr_uid = instruction["instruction_uid"]
|
instr_uid = instruction["instruction_uid"]
|
||||||
instr_type = instruction["type"]
|
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
|
scl_map[map_key_eno] = en_scl
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
def process_add(instruction, network_id, scl_map, access_map):
|
def process_add(instruction, network_id, scl_map, access_map):
|
||||||
instr_uid = instruction["instruction_uid"]
|
instr_uid = instruction["instruction_uid"]
|
||||||
instr_type = instruction["type"]
|
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
|
scl_map[map_key_eno] = en_scl
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
def process_move(instruction, network_id, scl_map, access_map):
|
def process_move(instruction, network_id, scl_map, access_map):
|
||||||
instr_uid = instruction["instruction_uid"]
|
instr_uid = instruction["instruction_uid"]
|
||||||
instr_type = instruction["type"]
|
instr_type = instruction["type"]
|
||||||
|
@ -608,95 +679,90 @@ def process_move(instruction, network_id, scl_map, access_map):
|
||||||
return True
|
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)."""
|
"""Genera SCL para PBox (P_TRIG) o NBox (N_TRIG)."""
|
||||||
instr_uid = instruction["instruction_uid"]
|
instr_uid = instruction["instruction_uid"]
|
||||||
instr_type_original = instruction["type"] # PBox o NBox
|
instr_type_original = instruction["type"] # PBox o NBox
|
||||||
if instr_type_original.endswith(SCL_SUFFIX) or "_error" in instr_type_original:
|
# print(f"DEBUG Edge: Intentando procesar {instr_type_original} UID {instr_uid} en Red {network_id}") # Debug
|
||||||
return False
|
|
||||||
|
|
||||||
# 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")
|
clk_input = instruction["inputs"].get("in")
|
||||||
mem_bit_input = instruction["inputs"].get("bit")
|
mem_bit_input = instruction["inputs"].get("bit")
|
||||||
|
|
||||||
clk_scl = get_scl_representation(clk_input, network_id, scl_map, access_map)
|
clk_scl = get_scl_representation(clk_input, network_id, scl_map, access_map)
|
||||||
mem_bit_scl_original = get_scl_representation(
|
mem_bit_scl_original = get_scl_representation(mem_bit_input, network_id, scl_map, access_map)
|
||||||
mem_bit_input, network_id, scl_map, access_map
|
|
||||||
)
|
|
||||||
|
|
||||||
if clk_scl is None or mem_bit_scl_original is None:
|
# 2. Verificar si las dependencias están listas
|
||||||
# print(f"DEBUG Edge: Esperando dependencias para {instr_type_original} UID {instr_uid}")
|
if clk_scl is None:
|
||||||
return False # Dependencias no listas
|
# print(f"DEBUG Edge: CLK no resuelto para {instr_type_original} UID {instr_uid}. Esperando.")
|
||||||
|
return False # Dependencia CLK no lista
|
||||||
# Validar que el bit de memoria sea una variable
|
if mem_bit_scl_original is None:
|
||||||
if not (mem_bit_input and mem_bit_input.get("type") == "variable"):
|
# Esto es menos probable, pero por seguridad
|
||||||
print(
|
print(f"Error: No se pudo resolver MemBit para {instr_type_original} UID {instr_uid}.")
|
||||||
f"Error: {instr_type_original} {instr_uid} 'bit' no es variable o falta información."
|
instruction["scl"] = f"// ERROR: {instr_type_original} {instr_uid} MemBit no resuelto."
|
||||||
)
|
|
||||||
instruction["scl"] = (
|
|
||||||
f"// ERROR: {instr_type_original} {instr_uid} 'bit' no es variable."
|
|
||||||
)
|
|
||||||
instruction["type"] = instr_type_original + "_error"
|
instruction["type"] = instr_type_original + "_error"
|
||||||
return True # Procesado con error
|
return True # Marcar como error
|
||||||
|
|
||||||
# --- Renombrar bit de memoria para VAR_STAT ---
|
# 3. Validar que el bit de memoria sea una variable
|
||||||
# Quitar comillas existentes, añadir prefijo "stat_" y volver a añadir comillas
|
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('"')
|
mem_bit_name_clean = mem_bit_scl_original.strip('"')
|
||||||
stat_mem_bit_scl = (
|
stat_mem_bit_scl = f'"stat_{mem_bit_name_clean}"' if not mem_bit_name_clean.startswith("stat_") else mem_bit_scl_original
|
||||||
f'"stat_{mem_bit_name_clean}"' # Nombre SCL para la variable estática
|
|
||||||
)
|
|
||||||
|
|
||||||
# Asegurar paréntesis alrededor de CLK si es complejo
|
|
||||||
# Formatear CLK
|
|
||||||
clk_scl_formatted = clk_scl
|
clk_scl_formatted = clk_scl
|
||||||
# Añadir paréntesis si es necesario (expresión compleja o asignación previa)
|
# Añadir paréntesis si es necesario (expresión compleja) - No a TRUE/FALSE
|
||||||
# No añadir paréntesis a TRUE/FALSE literales
|
if clk_scl not in ["TRUE", "FALSE"] and \
|
||||||
if (
|
(' ' in clk_scl or 'AND' in clk_scl or 'OR' in clk_scl or ':=' in clk_scl) and \
|
||||||
clk_scl not in ["TRUE", "FALSE"]
|
not (clk_scl.startswith('(') and clk_scl.endswith(')')):
|
||||||
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})"
|
clk_scl_formatted = f"({clk_scl})"
|
||||||
|
|
||||||
# --- Generar Lógica SCL ---
|
# 5. Generar Lógica SCL específica para PBox o NBox
|
||||||
result_scl = "FALSE" # SCL para la salida del flanco (pin 'out')
|
result_pulse_scl = "FALSE" # SCL para la salida del flanco (pin 'out')
|
||||||
scl_comment = "" # Comentario informativo
|
scl_comment = ""
|
||||||
|
|
||||||
if instr_type_original == "PBox": # Flanco Positivo (P_TRIG)
|
if instr_type_original == "PBox": # Flanco Positivo (P_TRIG)
|
||||||
result_scl = f"{clk_scl_formatted} AND NOT {stat_mem_bit_scl}"
|
# Pulso = CLK actual Y NO Memoria anterior
|
||||||
scl_comment = f"// P_TRIG: {result_scl}"
|
result_pulse_scl = f"{clk_scl_formatted} AND NOT {stat_mem_bit_scl}"
|
||||||
elif instr_type_original == "NBox": # Flanco Negativo (N_TRIG)
|
scl_comment = f"// P_TRIG({clk_scl_formatted})"
|
||||||
result_scl = f"NOT {clk_scl_formatted} AND {stat_mem_bit_scl}"
|
elif instr_type_original == "NBox": # Flanco Negativo (N_TRIG)
|
||||||
scl_comment = f"// N_TRIG: {result_scl}"
|
# 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:
|
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}")
|
||||||
print(
|
instruction["scl"] = f"// ERROR: Tipo de flanco inesperado {instr_type_original}"
|
||||||
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"
|
instruction["type"] = instr_type_original + "_error"
|
||||||
return True
|
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};"
|
scl_mem_update = f"{stat_mem_bit_scl} := {clk_scl_formatted};"
|
||||||
|
|
||||||
# --- Almacenar Resultados ---
|
# 7. Almacenar Resultados
|
||||||
# El pulso resultante va al mapa SCL para que lo usen las instrucciones siguientes
|
# - 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")
|
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}" # Incluye la acción principal y un comentario
|
||||||
instruction["scl"] = f"{scl_mem_update} {scl_comment}"
|
|
||||||
instruction["type"] = instr_type_original + SCL_SUFFIX
|
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")
|
map_key_eno = (network_id, instr_uid, "eno")
|
||||||
scl_map[map_key_eno] = clk_scl # Usar clk_scl original sin formateo extra
|
scl_map[map_key_eno] = clk_scl # Usar el clk_scl original sin formato extra
|
||||||
|
|
||||||
return True
|
|
||||||
|
|
||||||
|
# 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):
|
def process_o(instruction, network_id, scl_map, access_map):
|
||||||
instr_uid = instruction["instruction_uid"]
|
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'
|
# La instrucción 'O' no tiene ENO propio, propaga el resultado por 'out'
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
def process_call(instruction, network_id, scl_map, access_map):
|
def process_call(instruction, network_id, scl_map, access_map):
|
||||||
instr_uid = instruction["instruction_uid"]
|
instr_uid = instruction["instruction_uid"]
|
||||||
instr_type = instruction.get("type", "") # Usar get con default
|
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
|
return True
|
||||||
|
|
||||||
|
|
||||||
# --- NUEVO: Procesador de Agrupación (Refinado) ---
|
# --- NUEVO: Procesador de Agrupación (Refinado) ---
|
||||||
def process_group_ifs(instruction, network_id, scl_map, access_map):
|
def process_group_ifs(instruction, network_id, scl_map, access_map):
|
||||||
"""
|
"""
|
||||||
|
@ -1308,7 +1372,7 @@ def process_json_to_scl(json_filepath):
|
||||||
# --- Ejecución ---
|
# --- Ejecución ---
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
# Asegúrate de que el nombre base del archivo XML sea correcto
|
# 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"
|
input_json_file = f"{xml_filename_base}_simplified.json"
|
||||||
|
|
||||||
if not os.path.exists(input_json_file):
|
if not os.path.exists(input_json_file):
|
||||||
|
|
|
@ -197,7 +197,7 @@ def generate_scl(processed_json_filepath, output_scl_filepath):
|
||||||
# --- Ejecución ---
|
# --- Ejecución ---
|
||||||
if __name__ == "__main__":
|
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(
|
input_json_file = xml_file.replace(
|
||||||
".xml", "_simplified_processed.json"
|
".xml", "_simplified_processed.json"
|
||||||
) # Nombre de salida dinámico
|
) # Nombre de salida dinámico
|
||||||
|
|
Loading…
Reference in New Issue