Skip to content

Commit e656a19

Browse files
committed
add ahb to ram test
1 parent 5948988 commit e656a19

File tree

5 files changed

+96
-39
lines changed

5 files changed

+96
-39
lines changed

.github/workflows/python-package.yml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,10 @@ jobs:
4747
python pycde_example/*.py
4848
python -m pycde_example.mini_riscv
4949
50-
- name: Test with tox
51-
run: tox
50+
- name: Test with pytest
51+
run: |
52+
python pycde_example/ahb_to_ram.py
53+
pytest pycde_example/test_ahb_to_ram.py
5254
5355
- name: Upload coverage to codecov
5456
run: |

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,11 @@ Operating systems:
1010
- Windows
1111
- Linux
1212

13-
Python: 3.8 ~ 3.11 (64-bit only)
13+
Python: 3.8 ~ 3.13 (64-bit only)
1414

1515
- Use Python's package installer pip to install pycde example dependencies:
1616
```bash
17-
pip install -r requirements.txt
17+
pip install .
1818
```
1919

2020
- Build from source

pycde_example/ahb_to_ram.py

Lines changed: 32 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,16 @@
77
class AHBModuleBuilder(ModuleBuilder):
88
def scan_cls(self):
99
self.cls_dct.update({
10-
"HSEL": Input(Bits(1)),
11-
"HREADY": 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-
"HREADYOUT": Output(Bits(1)),
18-
"HRESP": Output(Bits(1)),
19-
"HRDATA": Output(Bits(32)),
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)),
2020
})
2121
return super().scan_cls()
2222

@@ -37,26 +37,26 @@ class AHBSRAMModuleBuilder(AHBModuleBuilder, SRAMModuleBuilder):
3737
class AHBRam(Module):
3838
BuilderType = AHBSRAMModuleBuilder
3939
# 时钟和复位
40-
HCLK = Clock()
41-
HRESETn = Reset()
40+
hclk = Clock()
41+
hresetn = Reset()
4242
@generator
4343
def construct(io):
4444
# # 内部状态变量
45-
buf_addr = Reg(UInt(14), io.HCLK, io.HRESETn, name="addr") # 地址缓冲 [AW-3:0]
46-
buf_we = Reg(Bits(4), io.HCLK, io.HRESETn, name="we") # 写使能缓冲
47-
buf_hit = Reg(Bits(1), io.HCLK, io.HRESETn, name="hit") # 地址匹配标志
48-
buf_data = [Reg(Bits(8), io.HCLK, name=f"data_{i}") for i in range(4)]
49-
buf_pend = Reg(Bits(1), io.HCLK, io.HRESETn, name="pend") # 缓冲数据有效标志
45+
buf_addr = Reg(UInt(14), io.hclk, io.hresetn, name="addr") # 地址缓冲 [AW-3:0]
46+
buf_we = Reg(Bits(4), io.hclk, io.hresetn, name="we") # 写使能缓冲
47+
buf_hit = Reg(Bits(1), io.hclk, io.hresetn, name="hit") # 地址匹配标志
48+
buf_data = [Reg(Bits(8), io.hclk, name=f"data_{i}") for i in range(4)]
49+
buf_pend = Reg(Bits(1), io.hclk, io.hresetn, name="pend") # 缓冲数据有效标志
5050

5151
# 控制逻辑
52-
ahb_access = io.HTRANS[1] & io.HSEL & io.HREADY
53-
ahb_write = ahb_access & io.HWRITE
52+
ahb_access = io.htrans[1] & io.hsel & io.hready_in
53+
ahb_write = ahb_access & io.hwrite
5454
ahb_write.name = "ahb_write"
55-
ahb_read = ahb_access & ~io.HWRITE
55+
ahb_read = ahb_access & ~io.hwrite
5656
ahb_read.name = "ahb_read"
5757

5858
# 缓冲区pending状态
59-
reg_data_en = ahb_write.reg(io.HCLK, io.HRESETn)
59+
reg_data_en = ahb_write.reg(io.hclk, io.hresetn)
6060
buf_pend_nxt = (buf_pend | reg_data_en) & ahb_read
6161

6262
# RAM写使能
@@ -65,38 +65,38 @@ def construct(io):
6565

6666
# 连接输出信号
6767
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())
68+
io.SRAMADDR = Mux(ahb_read, buf_addr, io.haddr.as_bits()[2:16].as_uint())
6969
io.SRAMCS = ahb_read | ram_write
70-
io.HREADYOUT = Bits(1)(1)
71-
io.HRESP = Bits(1)(0)
72-
io.SRAMWDATA = Mux(buf_pend, BitsSignal.concat(buf_data[::-1]), io.HWDATA)
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)
7373

7474
# 字节选择逻辑 ----- 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]]
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]]
7878

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

8383
# 更新缓冲区写使能
8484
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))
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))
8787
buf_pend.assign(buf_pend_nxt)
8888

8989
# 数据缓冲区更新
9090
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)]))
91+
buf_data[i].assign(Mux(buf_we[i] & reg_data_en, buf_data[i], io.hwdata[8*i:8*(i+1)]))
9292

9393
# 读数据合并逻辑
9494
buf_hit_reg = BitsSignal.concat(4*[buf_hit])
9595
merge1 = buf_hit_reg & buf_we
9696

9797
# 合并读数据
9898
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])
99+
io.hrdata = BitsSignal.concat(hrdata_values[::-1])
100100

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

pycde_example/test_ahb_to_ram.py

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
import cocotb
2+
import cocotb.clock
3+
from cocotb.triggers import RisingEdge
4+
from cocotb.runner import get_runner
5+
from cocotbext.ahb import AHBBus, AHBLiteMaster
6+
import sys
7+
8+
9+
async def monitor(dut):
10+
while True:
11+
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)
15+
16+
@cocotb.test()
17+
async def random_test(dut):
18+
19+
# Create a 10us period clock on port clk
20+
clock = cocotb.clock.Clock(dut.hclk, 10, units="us")
21+
cocotb.start_soon(clock.start()) # Start the clock
22+
cocotb.start_soon(monitor(dut))
23+
# Reset the DUT
24+
dut.hresetn.value = 1
25+
await RisingEdge(dut.hclk)
26+
dut.hresetn.value = 0
27+
dut.SRAMRDATA.value = 0xdeadbeef
28+
29+
ahb_lite_master = AHBLiteMaster(
30+
AHBBus.from_entity(dut), dut.hclk, dut.hresetn, def_val="0"
31+
)
32+
33+
# Perform the writes and reads
34+
resp = await ahb_lite_master.write(0, 1, 4, pip=False, verbose=True)
35+
resp = await ahb_lite_master.read(0, 1, pip=False, verbose=True)
36+
cocotb.log.info(f"Write response: {resp}")
37+
assert resp[0]["data"] == "0xdeadbeef", "Read data does not match expected value"
38+
39+
def test_ahb_sram_runner():
40+
41+
sys.path.append(__file__.replace("test_ahb_to_ram.py", ""))
42+
runner = get_runner("verilator")
43+
runner.build(
44+
sources=[__file__.replace("pycde_example/test_ahb_to_ram.py", "build/ahb_to_ram/hw/AHBRam.sv")],
45+
hdl_toplevel="AHBRam",
46+
always=True,
47+
build_args=[],
48+
)
49+
runner.test(
50+
hdl_toplevel="AHBRam", test_module="test_ahb_to_ram", test_args=[]
51+
)
52+
53+
54+
if __name__ == "__main__":
55+
test_ahb_sram_runner()

pyproject.toml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ dependencies = [
1616
[project.optional-dependencies]
1717
lint = ['ruff']
1818
doc = ['sphinx']
19-
test = ['pytest', 'tox']
19+
test = ['pytest', 'tox', "cocotbext-ahb"]
2020
dev = ['pycde_example[lint, doc, test]']
2121

2222
[project.urls]
@@ -27,6 +27,6 @@ dev = ['pycde_example[lint, doc, test]']
2727
[tool.ruff]
2828
line-length = 120
2929

30-
[tool.ruff.pydocstyle]
30+
[tool.ruff.lint.pydocstyle]
3131
convention = "google"
32-
32+

0 commit comments

Comments
 (0)