|
| 1 | +import pycde |
| 2 | + |
| 3 | +from pycde import Module, Input, Output, generator, ir |
| 4 | +from pycde.types import Bits |
| 5 | +from pycde.circt.dialects import sv, hw, comb |
| 6 | +from pycde.circt import ir as circt_ir |
| 7 | +from pycde import support |
| 8 | +from pycde.signals import _FromCirctValue |
| 9 | + |
| 10 | +def unknown_location(): |
| 11 | + return ir.Location.unknown() |
| 12 | +support.get_user_loc.__code__ = unknown_location.__code__ |
| 13 | + |
| 14 | + |
| 15 | +class AsyncLowResetSyncReleaseCounter(Module): |
| 16 | + """异步低电平复位同步释放计数器示例。 |
| 17 | + |
| 18 | + 这个模块展示了如何使用sv.AlwaysFFOp创建带异步低电平复位的计数器, |
| 19 | + 并实现复位的同步释放。这是数字电路设计中常用的复位策略。 |
| 20 | + """ |
| 21 | + |
| 22 | + module_name = "async_low_reset_sync_release_counter" |
| 23 | + clk = Input(Bits(1)) |
| 24 | + # 异步复位输入,低电平有效 |
| 25 | + rst_n = Input(Bits(1)) |
| 26 | + |
| 27 | + # 控制计数器是否计数的输入信号 |
| 28 | + enable = Input(Bits(1)) |
| 29 | + # 计数器输出 |
| 30 | + count = Output(Bits(8)) |
| 31 | + |
| 32 | + @generator |
| 33 | + def construct(ports): |
| 34 | + # 创建一个8位寄存器来存储计数值 |
| 35 | + i8_type = circt_ir.IntegerType.get_signless(8) |
| 36 | + count_reg = sv.RegOp(hw.InOutType.get(i8_type), name="count_reg") |
| 37 | + |
| 38 | + clock_edge = circt_ir.IntegerAttr.get(circt_ir.IntegerType.get_signless(32), 0) # 0:AtPosEdge, 1:AtNegEdge, 2:AtBothEdges |
| 39 | + reset_style = circt_ir.IntegerAttr.get(circt_ir.IntegerType.get_signless(32), 2) # 0:NoReset, 1:SyncReset, 2:AsyncReset |
| 40 | + reset_edge = circt_ir.IntegerAttr.get(circt_ir.IntegerType.get_signless(32), 1) # 0:AtPosEdge, 1:AtNegEdge, 2:AtBothEdges |
| 41 | + |
| 42 | + # 这对应于SystemVerilog中的always_ff @(posedge clk, negedge rst_n) |
| 43 | + # 使用AlwaysFFOp创建带异步复位的时序逻辑块 |
| 44 | + always_blk = sv.AlwaysFFOp( |
| 45 | + clockEdge=clock_edge, |
| 46 | + clock=ports.clk.value, |
| 47 | + resetStyle=reset_style, |
| 48 | + resetEdge=reset_edge, |
| 49 | + reset=ports.rst_n.value, |
| 50 | + ) |
| 51 | + always_blk.bodyBlk.blocks.append() |
| 52 | + always_blk.resetBlk.blocks.append() |
| 53 | + # 复位逻辑:异步低电平复位,同步释放 |
| 54 | + with circt_ir.InsertionPoint(always_blk.resetBlk.blocks[0]): |
| 55 | + sv.PAssignOp(count_reg, hw.ConstantOp.create(i8_type, 1)) |
| 56 | + |
| 57 | + with circt_ir.InsertionPoint(always_blk.bodyBlk.blocks[0]): |
| 58 | + |
| 59 | + # 读取计数寄存器的当前值 |
| 60 | + current_count = sv.ReadInOutOp(count_reg) |
| 61 | + |
| 62 | + with_cond = sv.IfOp(ports.enable.value) |
| 63 | + with_cond.thenRegion.blocks.append() |
| 64 | + |
| 65 | + with circt_ir.InsertionPoint(with_cond.thenRegion.blocks[0]): |
| 66 | + # 计算下一个计数值 (current_count + 1) |
| 67 | + next_count = hw.ConstantOp.create(i8_type, 1) |
| 68 | + add_op = comb.AddOp.create(current_count, next_count) |
| 69 | + # 将新值赋给寄存器 |
| 70 | + sv.PAssignOp(count_reg, add_op) |
| 71 | + |
| 72 | + # 将计数寄存器值连接到输出端口 |
| 73 | + ports.count = _FromCirctValue(sv.ReadInOutOp(count_reg).result) |
| 74 | + |
| 75 | + |
| 76 | +if __name__ == "__main__": |
| 77 | + # 创建系统并编译模块 |
| 78 | + s = pycde.System( |
| 79 | + [AsyncLowResetSyncReleaseCounter], |
| 80 | + name="alwaysff_example", |
| 81 | + output_directory="build/alwaysff_example" |
| 82 | + ) |
| 83 | + s.compile() |
0 commit comments