44from pycde .signals import BitsSignal
55from 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+
2329class 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-
3746class 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
101112if __name__ == '__main__' :
102113 mod = System ([AHBRam ], name = "ahb_to_ram" , output_directory = "build/ahb_to_ram" )
0 commit comments