[英]Yosys: How to correctly add states and transitions to fsm during fsm_recode pass?
我正在尝试通过向状态机添加冗余状态和转换来在Yosys中实现容错编码。
我首先尝试做的是在状态信号中添加额外的位,从而增加状态位的数量并将fsm_data.state_bits
设置为该新数字。 之后,我将当前状态信号编码为新信号。 为此,我使用了一种简单的汉明编码算法。
对状态进行编码后,我将更新过渡表,以使原始过渡现在使用新编码的状态。 最后,我尝试将冗余状态添加到状态机。 这些冗余状态是与父状态具有相同结尾的状态,但是具有翻转的一位。
所有这些似乎都可以在fsm_recode传递中使用。 我通过运行该工具的设计并打印fsm_info
了fsm_info
。 在打印fsm_info
之后,我使用了fsm_recode -encoding hamming
重新编码状态机并添加了冗余状态和转换。 最后,我再次打印了fsm_info
,并看到状态已正确编码,并且冗余状态和转换已添加到fsm中。
我使用的代码如下:
首先,我们计算新编码的状态信号将使用多少位。 encoder.allocateBits()
计算所需的奇偶校验位数,并返回编码信号应具有的位数。
if (encoding == "hamming") {
int nrOfStateBits = ceil_log2(fsm_data.state_table.size());
int new_num_state_bits = encoder.allocateBits();
fsm_data.state_bits = new_num_state_bits;
}
之后,我们遍历状态表并对状态进行编码并更新过渡表:
if (encoding == "hamming") {
new_code = encoder.encode(fsm_data.state_table[i]);
encoder.updateTransitionTableForState(fsm_data.state_table[i], new_code);
}
encoder.encode()
方法仅使用汉明编码对信号进行编码。 updateTransitionTableForState()
方法将更新转换表,如下所示:
void HammingEncoder::updateTransitionTableForState(RTLIL::Const old_state, RTLIL::Const new_state) {
for (int i = 0; i < fsmData.transition_table.size(); i++) {
if (fsmData.transition_table[i].state_in == old_state.as_int()) {
fsmData.transition_table[i].state_in = new_state.as_int();
}
if (fsmData.transition_table[i].state_out == old_state.as_int()) {
fsmData.transition_table[i].state_out = new_state.as_int();
}
}
}
最后,在对原始fsm进行编码并对其转换进行更新之后,我尝试添加所有冗余(子)状态:
void HammingEncoder::addLeafStates() {
std::vector<RTLIL::Const> new_states;
for (int i = 0; i < fsmData.state_table.size(); i++) {
std::vector<FsmData::transition_t> transitions = findOutgoingTransitionsForState(fsmData.state_table[i]);
for (int j = 0; j < fsmData.state_table[i].bits.size(); j++) {
RTLIL::Const new_signal = fsmData.state_table[i];
RTLIL::State s = (fsmData.state_table[i].bits[j] ^ 1) ? RTLIL::State::S1 : RTLIL::State::S0;
new_signal.bits[j] = s;
new_states.push_back(new_signal);
for (int k = 0; k < transitions.size(); k++) {
FsmData::transition_t new_transition = transitions[k];
new_transition.state_in = new_signal.as_int();
fsmData.transition_table.push_back(new_transition);
}
}
}
fsmData.state_table.insert(fsmData.state_table.end(), new_states.begin(), new_states.end());
}
此方法循环遍历已编码的fsmData.state_table
。 对于该表中的每个状态,它将在fsmData.transition_table
找到该状态的fsmData.transition_table
。 接下来,我们遍历该状态下的位数。 每次迭代时,我们当前查看的状态信号都经过1的XOR运算,每次迭代都会在状态位上进行移位。 这些信号中的每一个,然后将其父级的过渡添加到自身。
正如我提到的,当我在使用fsm_recode -encoding hamming
之后打印fsm_info
时,上述所有内容似乎都可以使用。 但是,当我随后进一步进行综合流程时。 我在fsm_map
传递中收到错误:
24. Executing FSM_MAP pass (mapping FSMs to basic logic).
Mapping FSM `$fsm$\state$145' from module `\m_hiftreg'.
ERROR: Assert `chunk.offset + chunk.width <= chunk.wire->width' failed in kernel/rtlil.cc:3455.
这似乎发生在fsm_map
传递的static void implement_pattern_cache()
方法内。 正是在此循环内,在RTLIL::SigSpec(state_onehot, in_state));
构造函数。
for (int in_state : it.second)
if (fullstate_cache.count(in_state) == 0)
or_sig.append(RTLIL::SigSpec(state_onehot, in_state));
在将状态和转换添加到fsm时,我到底做错了什么,这会导致此问题? 我不太熟悉fsm_map
传递,并且据我了解,当我打印fsm_info
时,fsm似乎处于良好状态。 提前致谢!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.