首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >这个语法是如何用凿子解释的?

这个语法是如何用凿子解释的?
EN

Stack Overflow用户
提问于 2019-12-17 13:26:35
回答 2查看 159关注 0票数 1

我在学凿子和火箭芯片。最近,我在火箭/ RocketCore.scala文件中发现了一个不可读的语法。

代码语言:javascript
复制
val perfEvents = new EventSets(Seq(
new EventSet((mask, hits) => Mux(mask(0), wb_xcpt, wb_valid && pipelineIDToWB((mask & hits).orR)), Seq(
  ("exception", () => false.B),
  ("load", () => id_ctrl.mem && id_ctrl.mem_cmd === M_XRD && !id_ctrl.fp),
  ("store", () => id_ctrl.mem && id_ctrl.mem_cmd === M_XWR && !id_ctrl.fp),
  ("amo", () => Bool(usingAtomics) && id_ctrl.mem && (isAMO(id_ctrl.mem_cmd) || id_ctrl.mem_cmd.isOneOf(M_XLR, M_XSC))),
  ("system", () => id_ctrl.csr =/= CSR.N),
  ("arith", () => id_ctrl.wxd && !(id_ctrl.jal || id_ctrl.jalr || id_ctrl.mem || id_ctrl.fp || id_ctrl.mul || id_ctrl.div || id_ctrl.csr =/= CSR.N)),
  ("branch", () => id_ctrl.branch),
  ("jal", () => id_ctrl.jal),
  ("jalr", () => id_ctrl.jalr))
  ++ (if (!usingMulDiv) Seq() else Seq(
    ("mul", () => if (pipelinedMul) id_ctrl.mul else id_ctrl.div && (id_ctrl.alu_fn & ALU.FN_DIV) =/= ALU.FN_DIV),
    ("div", () => if (pipelinedMul) id_ctrl.div else id_ctrl.div && (id_ctrl.alu_fn & ALU.FN_DIV) === ALU.FN_DIV)))
  ++ (if (!usingFPU) Seq() else Seq(
    ("fp load", () => id_ctrl.fp && io.fpu.dec.ldst && io.fpu.dec.wen),
    ("fp store", () => id_ctrl.fp && io.fpu.dec.ldst && !io.fpu.dec.wen),
    ("fp add", () => id_ctrl.fp && io.fpu.dec.fma && io.fpu.dec.swap23),
    ("fp mul", () => id_ctrl.fp && io.fpu.dec.fma && !io.fpu.dec.swap23 && !io.fpu.dec.ren3),
    ("fp mul-add", () => id_ctrl.fp && io.fpu.dec.fma && io.fpu.dec.ren3),
    ("fp div/sqrt", () => id_ctrl.fp && (io.fpu.dec.div || io.fpu.dec.sqrt)),
    ("fp other", () => id_ctrl.fp && !(io.fpu.dec.ldst || io.fpu.dec.fma || io.fpu.dec.div || io.fpu.dec.sqrt))))),
new EventSet((mask, hits) => (mask & hits).orR, Seq(
  ("load-use interlock", () => id_ex_hazard && ex_ctrl.mem || id_mem_hazard && mem_ctrl.mem || id_wb_hazard && wb_ctrl.mem),
  ("long-latency interlock", () => id_sboard_hazard),
  ("csr interlock", () => id_ex_hazard && ex_ctrl.csr =/= CSR.N || id_mem_hazard && mem_ctrl.csr =/= CSR.N || id_wb_hazard && wb_ctrl.csr =/= CSR.N),
  ("I$ blocked", () => icache_blocked),
  ("D$ blocked", () => id_ctrl.mem && dcache_blocked),
  ("branch misprediction", () => take_pc_mem && mem_direction_misprediction),
  ("control-flow target misprediction", () => take_pc_mem && mem_misprediction && mem_cfi && !mem_direction_misprediction && !icache_blocked),
  ("flush", () => wb_reg_flush_pipe),
  ("replay", () => replay_wb))
  ++ (if (!usingMulDiv) Seq() else Seq(
    ("mul/div interlock", () => id_ex_hazard && (ex_ctrl.mul || ex_ctrl.div) || id_mem_hazard && (mem_ctrl.mul || mem_ctrl.div) || id_wb_hazard && wb_ctrl.div)))
  ++ (if (!usingFPU) Seq() else Seq(
    ("fp interlock", () => id_ex_hazard && ex_ctrl.fp || id_mem_hazard && mem_ctrl.fp || id_wb_hazard && wb_ctrl.fp || id_ctrl.fp && id_stall_fpu)))),
new EventSet((mask, hits) => (mask & hits).orR, Seq(
  ("I$ miss", () => io.imem.perf.acquire),
  ("D$ miss", () => io.dmem.perf.acquire),
  ("D$ release", () => io.dmem.perf.release),
  ("ITLB miss", () => io.imem.perf.tlbMiss),
  ("DTLB miss", () => io.dmem.perf.tlbMiss),
  ("L2 TLB miss", () => io.ptw.perf.l2miss)))))

在使用EventSet类时,我没有找到掩码和命中的定义。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-12-17 17:34:40

这是一段相当吓人的代码。把它拆散

  • perfEvents被指定为EventSets
  • EventSets的一个实例,需要一个单一参数
    • class EventSets(val eventSets: Seq[EventSet])
    • So,您可以看到EventSet begin created.

Seq

  • EventSet需要两个参数
    • class EventSet(gate: (UInt, UInt) => Bool, events: Seq[(String, () => Bool)])
    • First:--两个UInts的函数,返回两个元组的Bool
    • Second: A Seq和没有返回Bool
    • So的参数的函数--您看到这些元组的长序列是defined.
    • NOTE:,(String, () => Bool())序列需要不同的配置参数,比如usingMulDiv
      • ,这样就可以看到构造++ (if (..,这是times.H242<的一对constucting.

--/code>

  • --它使用if有条件地向EventSet参数中添加不同的元组子序列。

我希望这能帮上忙。这是很多东西,可能是丑陋的,简短的,或更清晰的,真正的冗长和冗长。在格式化程序中执行此操作可能会有所帮助。这里有一点。

代码语言:javascript
复制
val perfEvents = new EventSets(
  Seq(
    new EventSet(
      (mask, hits) => Mux(wb_xcpt, mask(0), wb_valid && pipelineIDToWB((mask & hits).orR)),
      Seq(
        ("exception", () => false.B),
        ("load", () => id_ctrl.mem && id_ctrl.mem_cmd === M_XRD && !id_ctrl.fp),
        ("store", () => id_ctrl.mem && id_ctrl.mem_cmd === M_XWR && !id_ctrl.fp),
        ("amo",
         () =>
           Bool(usingAtomics) && id_ctrl.mem && (isAMO(id_ctrl.mem_cmd) || id_ctrl.mem_cmd.isOneOf(M_XLR, M_XSC))),
        ("system", () => id_ctrl.csr =/= CSR.N),
        ("arith",
         () =>
           id_ctrl.wxd && !(id_ctrl.jal || id_ctrl.jalr || id_ctrl.mem || id_ctrl.fp || id_ctrl.mul || id_ctrl.div || id_ctrl.csr =/= CSR.N)),
        ("branch", () => id_ctrl.branch),
        ("jal", () => id_ctrl.jal),
        ("jalr", () => id_ctrl.jalr)
      )
        ++ (if (!usingMulDiv) Seq()
            else
              Seq(
票数 2
EN

Stack Overflow用户

发布于 2019-12-17 17:23:39

maskhits只是传递给EventSet构造函数的lambda的参数,(mask, hits) => ...部分是它们的定义(或者声明,如果您愿意的话)。如果您查看EventSet source,可以看到lambda名为gate,只在此方法中使用:

代码语言:javascript
复制
def check(mask: UInt) = gate(mask, hits)

所以mask将是checkhits的论点

代码语言:javascript
复制
def hits = events.map(_._2()).asUInt

在本例中,对于第一个EventSet,您将得到以下内容

代码语言:javascript
复制
Seq(
  false.B,
  id_ctrl.mem && id_ctrl.mem_cmd === M_XRD && !id_ctrl.fp,
  ...
).asUInt
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59375267

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档