如何理解SonicBoom中CtrlSigs类的`sigs zip decoder map`代码含义?
Chisel译码代码中zip与map操作逻辑讲解
首先需要纠正一个常见误解:zip和map不是Chisel Vec的内置方法,是Scala标准库针对集合类型的通用操作,这也是你查Chisel API找不到相关说明的原因——Chisel是基于Scala实现的硬件描述领域特定语言,写Chisel代码时会同时用到Scala原生语法特性和Chisel提供的硬件描述接口。
你提到的这行代码本质是用Scala的集合操作简化了大量重复的信号赋值操作,完全等价于手写24行逐个赋值的代码,可以拆分三步理解:
1. 确认两个输入序列的对应关系
sigs:是手动构造的Scala序列,里面按顺序存放了CtrlSigsBundle中除了rocc之外的24个控制信号字段,顺序完全和代码中列出的顺序一致:legal、fp_val、fp_single……直到最后的csr_cmd,每个元素都是可赋值的硬件信号节点。decoder:是RocketChip的DecodeLogic工具返回的译码结果,它是一个长度和sigs完全相等的序列,每个元素对应一个控制信号的译码值,顺序和sigs的顺序严格一一对应。
2. zip操作的作用
zip是Scala集合的通用方法,作用是把两个等长的序列按位置两两配对,生成一个新的二元组序列。
比如对于两个序列Seq(a,b,c)和Seq(1,2,3),zip之后得到的结果是Seq( (a,1), (b,2), (c,3) )。
对应到你的代码里,sigs zip decoder得到的序列就是:
Seq( (legal, decoder(0)), (fp_val, decoder(1)), ... , (csr_cmd, decoder(23)) )
3. map操作的作用
map也是Scala集合的通用方法,作用是遍历序列中的每个元素,执行自定义的逻辑,返回处理后的新序列。
你代码里map {case(s,d) => s := d}的逻辑就是:遍历zip得到的每个二元组,用模式匹配把二元组的第一个元素(待赋值的控制信号)赋值给变量s,第二个元素(译码得到的信号值)赋值给变量d,然后执行硬件赋值操作s := d,把译码结果连接到对应的控制信号上。
等价手写代码
如果不使用zip和map,你需要手写24行完全重复的赋值逻辑,和这行代码的效果完全一致,没有任何硬件层面的差异:
legal := decoder(0) fp_val := decoder(1) fp_single := decoder(2) uopc := decoder(3) iq_type := decoder(4) fu_code := decoder(5) dst_type := decoder(6) rs1_type := decoder(7) rs2_type := decoder(8) frs3_en := decoder(9) imm_sel := decoder(10) uses_ldq := decoder(11) uses_stq := decoder(12) is_amo := decoder(13) is_fence := decoder(14) is_fencei := decoder(15) mem_cmd := decoder(16) wakeup_delay := decoder(17) bypassable := decoder(18) is_br := decoder(19) is_sys_pc2epc := decoder(20) inst_unique := decoder(21) flush_on_commit := decoder(22) csr_cmd := decoder(23)
用zip+map的写法只是利用Scala的语法特性简化了重复代码,没有引入任何额外的硬件逻辑。
内容的提问来源于stack exchange,提问作者Gerrie
相关产品推荐
相关产品推荐

