Skip to content

Commit 04f0166

Browse files
committed
Add alwaysff example
1 parent 0e7111c commit 04f0166

File tree

1 file changed

+83
-0
lines changed

1 file changed

+83
-0
lines changed

pycde_example/alwaysff_example.py

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
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

Comments
 (0)