Skip to content

Commit 3f3ed2a

Browse files
committed
Modify to io class
1 parent e656a19 commit 3f3ed2a

File tree

2 files changed

+61
-49
lines changed

2 files changed

+61
-49
lines changed

pycde_example/ahb_to_ram.py

Lines changed: 55 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -4,41 +4,52 @@
44
from pycde.signals import BitsSignal
55
from pycde.module import ModuleBuilder
66

7-
class AHBModuleBuilder(ModuleBuilder):
8-
def scan_cls(self):
9-
self.cls_dct.update({
10-
"hsel": Input(Bits(1)),
11-
"hready_in": Input(Bits(1)),
12-
"htrans": Input(Bits(2)),
13-
"hsize": Input(Bits(3)),
14-
"hwrite": Input(Bits(1)),
15-
"haddr": Input(UInt(32)),
16-
"hwdata": Input(Bits(32)),
17-
"hready": Output(Bits(1)),
18-
"hresp": Output(Bits(1)),
19-
"hrdata": Output(Bits(32)),
20-
})
21-
return super().scan_cls()
22-
7+
class IOBase:
8+
pass
9+
10+
class AHBIO(IOBase):
11+
hsel = Input(Bits(1))
12+
hready_in = Input(Bits(1))
13+
htrans = Input(Bits(2))
14+
hsize = Input(Bits(3))
15+
hwrite = Input(Bits(1))
16+
haddr = Input(UInt(32))
17+
hwdata = Input(Bits(32))
18+
hready = Output(Bits(1))
19+
hresp = Output(Bits(1))
20+
hrdata = Output(Bits(32))
21+
22+
class SRAMIO(IOBase):
23+
SRAMRDATA = Input(Bits(32))
24+
SRAMADDR = Output(UInt(14))
25+
SRAMWEN = Output(Bits(4))
26+
SRAMWDATA = Output(Bits(32))
27+
SRAMCS = Output(Bits(1))
28+
2329
class SRAMModuleBuilder(ModuleBuilder):
2430
def scan_cls(self):
25-
self.cls_dct.update({
26-
"SRAMRDATA": Input(Bits(32)),
27-
"SRAMADDR": Output(UInt(14)),
28-
"SRAMWEN": Output(Bits(4)),
29-
"SRAMWDATA": Output(Bits(32)),
30-
"SRAMCS": Output(Bits(1)),
31-
})
31+
io_dct = {}
32+
for attr_name, attr_t in self.cls_dct.items():
33+
if isinstance(attr_t, IOBase):
34+
for io, attr in type(attr_t).__dict__.items():
35+
if isinstance(attr, Input):
36+
io_dct[f"{attr_name}_{io}"] = Input(attr.type)
37+
elif isinstance(attr, Output):
38+
io_dct[f"{attr_name}_{io}"] = Output(attr.type)
39+
elif isinstance(attr, tuple) and len(attr) == 1 and isinstance(attr[0], Input):
40+
io_dct[f"{attr_name}_{io}"] = Input(attr[0].type)
41+
elif isinstance(attr, tuple) and len(attr) == 1 and isinstance(attr[0], Output):
42+
io_dct[f"{attr_name}_{io}"] = Output(attr[0].type)
43+
self.cls_dct.update(io_dct)
3244
return super().scan_cls()
3345

34-
class AHBSRAMModuleBuilder(AHBModuleBuilder, SRAMModuleBuilder):
35-
pass
36-
3746
class AHBRam(Module):
38-
BuilderType = AHBSRAMModuleBuilder
47+
BuilderType = SRAMModuleBuilder
3948
# 时钟和复位
4049
hclk = Clock()
4150
hresetn = Reset()
51+
a = AHBIO()
52+
B = SRAMIO()
4253
@generator
4354
def construct(io):
4455
# # 内部状态变量
@@ -49,10 +60,10 @@ def construct(io):
4960
buf_pend = Reg(Bits(1), io.hclk, io.hresetn, name="pend") # 缓冲数据有效标志
5061

5162
# 控制逻辑
52-
ahb_access = io.htrans[1] & io.hsel & io.hready_in
53-
ahb_write = ahb_access & io.hwrite
63+
ahb_access = io.a_htrans[1] & io.a_hsel & io.a_hready_in
64+
ahb_write = ahb_access & io.a_hwrite
5465
ahb_write.name = "ahb_write"
55-
ahb_read = ahb_access & ~io.hwrite
66+
ahb_read = ahb_access & ~io.a_hwrite
5667
ahb_read.name = "ahb_read"
5768

5869
# 缓冲区pending状态
@@ -64,39 +75,39 @@ def construct(io):
6475
ram_write.name = "ram_write"
6576

6677
# 连接输出信号
67-
io.SRAMWEN = BitsSignal.concat(4*[ram_write]) & buf_we
68-
io.SRAMADDR = Mux(ahb_read, buf_addr, io.haddr.as_bits()[2:16].as_uint())
69-
io.SRAMCS = ahb_read | ram_write
70-
io.hready = Bits(1)(1)
71-
io.hresp = Bits(1)(0)
72-
io.SRAMWDATA = Mux(buf_pend, BitsSignal.concat(buf_data[::-1]), io.hwdata)
78+
io.B_SRAMWEN = BitsSignal.concat(4*[ram_write]) & buf_we
79+
io.B_SRAMADDR = Mux(ahb_read, buf_addr, io.a_haddr.as_bits()[2:16].as_uint())
80+
io.B_SRAMCS = ahb_read | ram_write
81+
io.a_hready = Bits(1)(1)
82+
io.a_hresp = Bits(1)(0)
83+
io.B_SRAMWDATA = Mux(buf_pend, BitsSignal.concat(buf_data[::-1]), io.a_hwdata)
7384

7485
# 字节选择逻辑 ----- 0: Byte, 1: Half-word, 2: Word
75-
tx_byte_num = [io.hsize == Bits(3)(i) for i in range(3)]
76-
byte_pos = [tx_byte_num[0] & (io.haddr.as_bits()[0:2] == Bits(2)(i)) for i in range(4)]
77-
half_pos = [tx_byte_num[1] & ~io.haddr.as_bits()[1], tx_byte_num[1] & io.haddr.as_bits()[1]]
86+
tx_byte_num = [io.a_hsize == Bits(3)(i) for i in range(3)]
87+
byte_pos = [tx_byte_num[0] & (io.a_haddr.as_bits()[0:2] == Bits(2)(i)) for i in range(4)]
88+
half_pos = [tx_byte_num[1] & ~io.a_haddr.as_bits()[1], tx_byte_num[1] & io.a_haddr.as_bits()[1]]
7889

7990
# 地址阶段字节选通信号
8091
byte_sel = [tx_byte_num[2] | half_pos[i//2] | byte_pos[i] for i in range(4)]
8192
buf_we_nxt = BitsSignal.concat([byte_sel[i] & ahb_write for i in range(4)])
8293

8394
# 更新缓冲区写使能
8495
buf_we.assign(Mux(ahb_write, buf_we_nxt, buf_we))
85-
buf_addr.assign(Mux(ahb_write, io.haddr.as_bits()[2:16].as_uint(), buf_addr))
86-
buf_hit.assign(Mux(ahb_read, (io.haddr.as_bits()[2:16].as_uint() == buf_addr), buf_hit))
96+
buf_addr.assign(Mux(ahb_write, io.a_haddr.as_bits()[2:16].as_uint(), buf_addr))
97+
buf_hit.assign(Mux(ahb_read, (io.a_haddr.as_bits()[2:16].as_uint() == buf_addr), buf_hit))
8798
buf_pend.assign(buf_pend_nxt)
8899

89100
# 数据缓冲区更新
90101
for i in range(4):
91-
buf_data[i].assign(Mux(buf_we[i] & reg_data_en, buf_data[i], io.hwdata[8*i:8*(i+1)]))
102+
buf_data[i].assign(Mux(buf_we[i] & reg_data_en, buf_data[i], io.a_hwdata[8*i:8*(i+1)]))
92103

93104
# 读数据合并逻辑
94105
buf_hit_reg = BitsSignal.concat(4*[buf_hit])
95106
merge1 = buf_hit_reg & buf_we
96107

97108
# 合并读数据
98-
hrdata_values = [Mux(merge1[i], io.SRAMRDATA[8*i:8*(i+1)], buf_data[i]) for i in range(4)]
99-
io.hrdata = BitsSignal.concat(hrdata_values[::-1])
109+
hrdata_values = [Mux(merge1[i], io.B_SRAMRDATA[8*i:8*(i+1)], buf_data[i]) for i in range(4)]
110+
io.a_hrdata = BitsSignal.concat(hrdata_values[::-1])
100111

101112
if __name__ == '__main__':
102113
mod = System([AHBRam], name="ahb_to_ram", output_directory="build/ahb_to_ram")

pycde_example/test_ahb_to_ram.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@
99
async def monitor(dut):
1010
while True:
1111
await RisingEdge(dut.hclk)
12-
cocotb.log.info(dut.hready.value)
13-
cocotb.log.info(dut.hresp.value)
14-
cocotb.log.info(dut.hrdata.value)
12+
cocotb.log.info(dut.a_hready.value)
13+
cocotb.log.info(dut.a_hresp.value)
14+
cocotb.log.info(dut.a_hrdata.value)
1515

1616
@cocotb.test()
1717
async def random_test(dut):
@@ -24,10 +24,11 @@ async def random_test(dut):
2424
dut.hresetn.value = 1
2525
await RisingEdge(dut.hclk)
2626
dut.hresetn.value = 0
27-
dut.SRAMRDATA.value = 0xdeadbeef
27+
dut.B_SRAMRDATA.value = 0xdeadbeef
2828

2929
ahb_lite_master = AHBLiteMaster(
30-
AHBBus.from_entity(dut), dut.hclk, dut.hresetn, def_val="0"
30+
# AHBBus.from_entity(dut), dut.hclk, dut.hresetn, def_val="0"
31+
AHBBus.from_prefix(dut, "a"), dut.hclk, dut.hresetn, def_val="0"
3132
)
3233

3334
# Perform the writes and reads

0 commit comments

Comments
 (0)