fix(plc): 修复RS/SR触发器dst_pin全部为-1的问题

第二遍XML解析时Comb→Gate、Inputs→Gate、R/S属性→Input
链接创建全部未设置dst_pin,导致collect_input_signals
无法区分S/R引脚,SR/RS运算结果错误。

修复内容:
- has_comb路径: Comb→链级Gate根据R/S属性匹配Comb#N设置dst_pin
- has_comb路径: 链级Inputs→Gate根据R/S属性匹配Input#N设置dst_pin
- R/S属性→Input链接改为!ins_el条件下创建,避免与Inputs→Gate重复
- 简单链路径: Inputs→Gate根据R/S属性设置dst_pin
This commit is contained in:
ypc 2026-07-08 19:14:10 +08:00
parent 323dc1ced0
commit 392fcfb255
1 changed files with 78 additions and 24 deletions

View File

@ -485,6 +485,20 @@ int parse_reclose_logic_xml(const char *file_path, LogicGraph graphs[], int *gra
if(has_comb) if(has_comb)
{ {
// 收集链级 Gate 的 R/S 属性RS/SR 用)
const char *gateS = NULL, *gateR = NULL;
int isChainSRRS = 0;
if(gate_el)
{
int cgtTmp = gate_type_from_xml_str(gate_el->Attribute("type"));
if(cgtTmp == NODE_TYPE_SR_LATCH || cgtTmp == NODE_TYPE_RS_LATCH)
{
isChainSRRS = cgtTmp;
gateS = gate_el->Attribute("S");
gateR = gate_el->Attribute("R");
}
}
// 收集所有 Comb 的 Gate 索引(第一遍已解析) // 收集所有 Comb 的 Gate 索引(第一遍已解析)
// Comb Gate → 链级 Gate (一个Comb一根线) // Comb Gate → 链级 Gate (一个Comb一根线)
if(gate_el) if(gate_el)
@ -508,6 +522,18 @@ int parse_reclose_logic_xml(const char *file_path, LogicGraph graphs[], int *gra
l.src_id = cur->nodes[ci].id; l.src_id = cur->nodes[ci].id;
l.dest_type = cur->nodes[cgi].type; l.dest_type = cur->nodes[cgi].type;
l.dest_id = cur->nodes[cgi].id; l.dest_id = cur->nodes[cgi].id;
// RS/SR: 根据 R/S 属性设置 dst_pin
if(isChainSRRS)
{
int combId = c->IntAttribute("id");
char combRef[16];
snprintf(combRef, sizeof(combRef), "Comb#%d", combId);
if(gateR && strcmp(gateR, combRef) == 0)
l.dst_pin = (isChainSRRS == NODE_TYPE_SR_LATCH) ? 1 : 0;
else if(gateS && strcmp(gateS, combRef) == 0)
l.dst_pin = (isChainSRRS == NODE_TYPE_SR_LATCH) ? 0 : 1;
}
} }
} }
} }
@ -535,28 +561,40 @@ int parse_reclose_logic_xml(const char *file_path, LogicGraph graphs[], int *gra
} }
// 链级 Inputs → 链级 Gate如 RS/SR 直接连 Input 信号) // 链级 Inputs → 链级 Gate如 RS/SR 直接连 Input 信号)
if(gate_el && ins_el) if(gate_el && ins_el)
{ {
int cgt = gate_type_from_xml_str(gate_el->Attribute("type")); int cgt = gate_type_from_xml_str(gate_el->Attribute("type"));
int cgi = find_node_index(cur, cgt, gate_el->IntAttribute("id")); int cgi = find_node_index(cur, cgt, gate_el->IntAttribute("id"));
if(cgi >= 0) if(cgi >= 0)
{ {
for(tinyxml2::XMLElement *sig = ins_el->FirstChildElement("Signal"); sig; for(tinyxml2::XMLElement *sig = ins_el->FirstChildElement("Signal"); sig;
sig = sig->NextSiblingElement("Signal")) sig = sig->NextSiblingElement("Signal"))
{ {
if(cur->link_count >= MAX_LINKS_PER_GRAPH) break; if(cur->link_count >= MAX_LINKS_PER_GRAPH) break;
int si = find_node_index(cur, NODE_TYPE_HW_INPUT, sig->IntAttribute("no")); int si = find_node_index(cur, NODE_TYPE_HW_INPUT, sig->IntAttribute("no"));
if(si >= 0) if(si >= 0)
{ LogicLink &l = cur->links[cur->link_count++]; { LogicLink &l = cur->links[cur->link_count++];
memset(&l, 0, sizeof(l)); l.dst_pin = -1; memset(&l, 0, sizeof(l)); l.dst_pin = -1;
l.src_type=NODE_TYPE_HW_INPUT; l.src_id=cur->nodes[si].id; l.src_type=NODE_TYPE_HW_INPUT; l.src_id=cur->nodes[si].id;
l.dest_type=cur->nodes[cgi].type; l.dest_id=cur->nodes[cgi].id; } l.dest_type=cur->nodes[cgi].type; l.dest_id=cur->nodes[cgi].id;
}
}
}
// RS/SR 的 R/S 属性引用的 Input 信号(无 <Inputs> 块时也需创建链接) // RS/SR: 根据 R/S 属性设置 dst_pin
if(gate_el) if(isChainSRRS)
{
char inRef[16];
snprintf(inRef, sizeof(inRef), "Input#%d", sig->IntAttribute("no"));
if(gateR && strcmp(gateR, inRef) == 0)
l.dst_pin = (isChainSRRS == NODE_TYPE_SR_LATCH) ? 1 : 0;
else if(gateS && strcmp(gateS, inRef) == 0)
l.dst_pin = (isChainSRRS == NODE_TYPE_SR_LATCH) ? 0 : 1;
}
}
}
}
}
// RS/SR 的 R/S 属性引用的 Input 信号(仅当无 <Inputs> 块时创建链接,避免重复)
if(gate_el && !ins_el)
{ {
int cgt = gate_type_from_xml_str(gate_el->Attribute("type")); int cgt = gate_type_from_xml_str(gate_el->Attribute("type"));
if(cgt == NODE_TYPE_SR_LATCH || cgt == NODE_TYPE_RS_LATCH) if(cgt == NODE_TYPE_SR_LATCH || cgt == NODE_TYPE_RS_LATCH)
@ -574,7 +612,8 @@ int parse_reclose_logic_xml(const char *file_path, LogicGraph graphs[], int *gra
{ LogicLink &l = cur->links[cur->link_count++]; { LogicLink &l = cur->links[cur->link_count++];
memset(&l, 0, sizeof(l)); l.dst_pin = -1; memset(&l, 0, sizeof(l)); l.dst_pin = -1;
l.src_type=NODE_TYPE_HW_INPUT; l.src_id=cur->nodes[si].id; l.src_type=NODE_TYPE_HW_INPUT; l.src_id=cur->nodes[si].id;
l.dest_type=cur->nodes[cgi2].type; l.dest_id=cur->nodes[cgi2].id; } l.dest_type=cur->nodes[cgi2].type; l.dest_id=cur->nodes[cgi2].id;
l.dst_pin = (cgt == NODE_TYPE_SR_LATCH) ? 0 : 1; }
} }
if(r_attr2 && strncmp(r_attr2, "Input#", 6) == 0) if(r_attr2 && strncmp(r_attr2, "Input#", 6) == 0)
{ {
@ -584,7 +623,8 @@ int parse_reclose_logic_xml(const char *file_path, LogicGraph graphs[], int *gra
{ LogicLink &l = cur->links[cur->link_count++]; { LogicLink &l = cur->links[cur->link_count++];
memset(&l, 0, sizeof(l)); l.dst_pin = -1; memset(&l, 0, sizeof(l)); l.dst_pin = -1;
l.src_type=NODE_TYPE_HW_INPUT; l.src_id=cur->nodes[si].id; l.src_type=NODE_TYPE_HW_INPUT; l.src_id=cur->nodes[si].id;
l.dest_type=cur->nodes[cgi2].type; l.dest_id=cur->nodes[cgi2].id; } l.dest_type=cur->nodes[cgi2].type; l.dest_id=cur->nodes[cgi2].id;
l.dst_pin = (cgt == NODE_TYPE_SR_LATCH) ? 1 : 0; }
} }
} }
} }
@ -608,7 +648,21 @@ int parse_reclose_logic_xml(const char *file_path, LogicGraph graphs[], int *gra
{ LogicLink &l = cur->links[cur->link_count++]; { LogicLink &l = cur->links[cur->link_count++];
memset(&l, 0, sizeof(l)); l.dst_pin = -1; memset(&l, 0, sizeof(l)); l.dst_pin = -1;
l.src_type=NODE_TYPE_HW_INPUT; l.src_id=cur->nodes[si].id; l.src_type=NODE_TYPE_HW_INPUT; l.src_id=cur->nodes[si].id;
l.dest_type=cur->nodes[gi].type; l.dest_id=cur->nodes[gi].id; } l.dest_type=cur->nodes[gi].type; l.dest_id=cur->nodes[gi].id;
// SR/RS: 根据 R/S 属性设置 dst_pin
if(gt == NODE_TYPE_SR_LATCH || gt == NODE_TYPE_RS_LATCH)
{
const char *sA = gate_el->Attribute("S");
const char *rA = gate_el->Attribute("R");
char inRef[16];
snprintf(inRef, sizeof(inRef), "Input#%d", sig->IntAttribute("no"));
if(rA && strcmp(rA, inRef) == 0)
l.dst_pin = (gt == NODE_TYPE_SR_LATCH) ? 1 : 0;
else if(sA && strcmp(sA, inRef) == 0)
l.dst_pin = (gt == NODE_TYPE_SR_LATCH) ? 0 : 1;
}
}
} }
if(ous_el) if(ous_el)